From 04c5c029bd4b000a107664f3d55688a367004603 Mon Sep 17 00:00:00 2001 From: Deepu Date: Tue, 18 Feb 2025 20:39:09 +0100 Subject: [PATCH 1/3] update vercel AI SDK to v4 --- package.json | 12 +- yarn.lock | 313 +++++++++++++++++++++++---------------------------- 2 files changed, 146 insertions(+), 179 deletions(-) diff --git a/package.json b/package.json index e8b8b46..68ec858 100644 --- a/package.json +++ b/package.json @@ -15,18 +15,15 @@ }, "dependencies": { "@langchain/community": "^0.3.25", - "@langchain/core": "^0.3.31", + "@langchain/core": "^0.3.40", "@langchain/langgraph": "^0.2.41", - "@langchain/openai": "^0.3.17", + "@langchain/openai": "^0.4.4", "@radix-ui/react-checkbox": "^1.1.3", "@radix-ui/react-dialog": "^1.1.4", "@radix-ui/react-popover": "^1.1.4", "@radix-ui/react-slot": "^1.1.1", "@supabase/supabase-js": "^2.32.0", - "@types/node": "20.12.12", - "@types/react": "18.3.2", - "@types/react-dom": "18.3.0", - "ai": "^3.1.12", + "ai": "^4.1.41", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "langchain": "^0.3.11", @@ -46,6 +43,9 @@ }, "devDependencies": { "@next/bundle-analyzer": "^13.4.19", + "@types/node": "20.12.12", + "@types/react": "18.3.2", + "@types/react-dom": "18.3.0", "autoprefixer": "10.4.14", "eslint": "8.46.0", "eslint-config-next": "13.4.12", diff --git a/yarn.lock b/yarn.lock index 91860f3..58e44c8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5,113 +5,65 @@ __metadata: version: 6 cacheKey: 8 -"@ai-sdk/provider-utils@npm:1.0.17": - version: 1.0.17 - resolution: "@ai-sdk/provider-utils@npm:1.0.17" - dependencies: - "@ai-sdk/provider": 0.0.22 - eventsource-parser: 1.1.2 - nanoid: 3.3.6 - secure-json-parse: 2.7.0 +"@ai-sdk/provider-utils@npm:2.1.8": + version: 2.1.8 + resolution: "@ai-sdk/provider-utils@npm:2.1.8" + dependencies: + "@ai-sdk/provider": 1.0.7 + eventsource-parser: ^3.0.0 + nanoid: ^3.3.8 + secure-json-parse: ^2.7.0 peerDependencies: zod: ^3.0.0 peerDependenciesMeta: zod: optional: true - checksum: 355a2ec40902cde5abb518ff57bfeb213475c068c0d2d3798bafb02008131f3f7849feed66f54b651a9b1c791db41696c3dd4bebaea7cdbc034164eaec3ed238 + checksum: 3d4651ec95a320b8da1e61b506e7866582966eccb339e335b57bc20cce331d5364711af8d1dc94a3e2f82808b2bdef2f957460c2dfffd98a9fcc348567db2bf8 languageName: node linkType: hard -"@ai-sdk/provider@npm:0.0.22": - version: 0.0.22 - resolution: "@ai-sdk/provider@npm:0.0.22" +"@ai-sdk/provider@npm:1.0.7": + version: 1.0.7 + resolution: "@ai-sdk/provider@npm:1.0.7" dependencies: - json-schema: 0.4.0 - checksum: e0be5ddfa6c385af92e7e4b7f763a117a3fa014ba3b15709bbe677b5ab27fbfe747f9711247db81a8fd83a4a201730a7dae528e6146601da08257703c8fd2576 + json-schema: ^0.4.0 + checksum: 724be1a85cc8250ef67663e1f6df3c294aa5353e22780a2cd1f5b156b1ef602c18e7c6dbd2459cd5ae08578c80aaec35e80a8bcebef8ee57d413a9ffa6962abd languageName: node linkType: hard -"@ai-sdk/react@npm:0.0.54": - version: 0.0.54 - resolution: "@ai-sdk/react@npm:0.0.54" +"@ai-sdk/react@npm:1.1.16": + version: 1.1.16 + resolution: "@ai-sdk/react@npm:1.1.16" dependencies: - "@ai-sdk/provider-utils": 1.0.17 - "@ai-sdk/ui-utils": 0.0.40 - swr: 2.2.5 + "@ai-sdk/provider-utils": 2.1.8 + "@ai-sdk/ui-utils": 1.1.14 + swr: ^2.2.5 + throttleit: 2.1.0 peerDependencies: - react: ^18 || ^19 + react: ^18 || ^19 || ^19.0.0-rc zod: ^3.0.0 peerDependenciesMeta: react: optional: true zod: optional: true - checksum: c4a309fb889d2f1fd7cdc1cfc2a08f6f89b5f7b5f1b5ee1eae351a8b570a22a016f4d7ad7c6bca375216127833adf4fa747b7eaf88087c9fce82123ba39994b2 - languageName: node - linkType: hard - -"@ai-sdk/solid@npm:0.0.43": - version: 0.0.43 - resolution: "@ai-sdk/solid@npm:0.0.43" - dependencies: - "@ai-sdk/provider-utils": 1.0.17 - "@ai-sdk/ui-utils": 0.0.40 - peerDependencies: - solid-js: ^1.7.7 - peerDependenciesMeta: - solid-js: - optional: true - checksum: 8a8437e468e801dea0b4c0da740d51755bb1e71a953eee80483072af6aaca5f99ea2e4e9c8c2b77ec224ac671a005bc6e10b1a3c17acf70c70bc27d058581867 + checksum: e60c341d12d3d1fab39282f2e0e2565c2fb5adf005c834bf23d0c8a5bfacdead7438838d4a7e3c90e4423f028993b41dd2b71b97319f5f6bf43bd6f79029579e languageName: node linkType: hard -"@ai-sdk/svelte@npm:0.0.45": - version: 0.0.45 - resolution: "@ai-sdk/svelte@npm:0.0.45" +"@ai-sdk/ui-utils@npm:1.1.14": + version: 1.1.14 + resolution: "@ai-sdk/ui-utils@npm:1.1.14" dependencies: - "@ai-sdk/provider-utils": 1.0.17 - "@ai-sdk/ui-utils": 0.0.40 - sswr: 2.1.0 - peerDependencies: - svelte: ^3.0.0 || ^4.0.0 - peerDependenciesMeta: - svelte: - optional: true - checksum: 83a0e0dafccfe57fabc600fb85b9c97f413e10f08bea6e58ffa80d5734e1fb6296927d5fffcf4ba87c385ecc9356d1caed68f8e976551af5b1b0ae01346f0284 - languageName: node - linkType: hard - -"@ai-sdk/ui-utils@npm:0.0.40": - version: 0.0.40 - resolution: "@ai-sdk/ui-utils@npm:0.0.40" - dependencies: - "@ai-sdk/provider": 0.0.22 - "@ai-sdk/provider-utils": 1.0.17 - json-schema: 0.4.0 - secure-json-parse: 2.7.0 - zod-to-json-schema: 3.23.2 + "@ai-sdk/provider": 1.0.7 + "@ai-sdk/provider-utils": 2.1.8 + zod-to-json-schema: ^3.24.1 peerDependencies: zod: ^3.0.0 peerDependenciesMeta: zod: optional: true - checksum: 6d59dd7780d9f03126c70cefce0a0320080a66eda5cd2ccc609ba7d8c708a3ee683d10931dfddf07dd85923300f0851300fc860a453dcefeb1a0f4cc52d72a7f - languageName: node - linkType: hard - -"@ai-sdk/vue@npm:0.0.45": - version: 0.0.45 - resolution: "@ai-sdk/vue@npm:0.0.45" - dependencies: - "@ai-sdk/provider-utils": 1.0.17 - "@ai-sdk/ui-utils": 0.0.40 - swrv: 1.0.4 - peerDependencies: - vue: ^3.3.4 - peerDependenciesMeta: - vue: - optional: true - checksum: dd12299b90d52852c85499db1e20bb7c0f681c3d399324fedd1fdd4ec03005e2b600d9e480bdc0fcf49fdb0216a9cf6b24b71d00e1e8a84fcf3c1139581175f3 + checksum: 0ad59c91a71edceceb7eb6559aaa572a116a60e1ad84d027256f9825cf8826943b87844a277da51ed654894c7e1a3260bef759005faacbcf24b257c91afe1292 languageName: node linkType: hard @@ -862,23 +814,23 @@ __metadata: languageName: node linkType: hard -"@langchain/core@npm:^0.3.31": - version: 0.3.31 - resolution: "@langchain/core@npm:0.3.31" +"@langchain/core@npm:^0.3.40": + version: 0.3.40 + resolution: "@langchain/core@npm:0.3.40" dependencies: "@cfworker/json-schema": ^4.0.2 ansi-styles: ^5.0.0 camelcase: 6 decamelize: 1.2.0 js-tiktoken: ^1.0.12 - langsmith: ^0.2.8 + langsmith: ">=0.2.8 <0.4.0" mustache: ^4.2.0 p-queue: ^6.6.2 p-retry: 4 uuid: ^10.0.0 zod: ^3.22.4 zod-to-json-schema: ^3.22.3 - checksum: 74d12d111a33d9215831e47e89a8e357f91ea3147495dc5b94e8087f58d6b5695fd984783b4fadc07a7c83f36ea9cd8e69d31337ee01a2616594eff79b9583c2 + checksum: faa546111d492a4df3f867908571dc94218ed3c680f0a8ff9cca2192a8f9100a23998fedafe368ec9b6989dc45c3bbf027832fbc37cf61bdcf535813c9fa55ea languageName: node linkType: hard @@ -947,17 +899,17 @@ __metadata: languageName: node linkType: hard -"@langchain/openai@npm:^0.3.17": - version: 0.3.17 - resolution: "@langchain/openai@npm:0.3.17" +"@langchain/openai@npm:^0.4.4": + version: 0.4.4 + resolution: "@langchain/openai@npm:0.4.4" dependencies: js-tiktoken: ^1.0.12 openai: ^4.77.0 zod: ^3.22.4 zod-to-json-schema: ^3.22.3 peerDependencies: - "@langchain/core": ">=0.3.29 <0.4.0" - checksum: af88894dcfa8381c0b0df924e085796995f5d5ba2a2657ea72b4181b35c5d92b0040c5cf305378c1f48a8f1f04d4a3b0b29ba1d84f80cedf5dab8bc46d7d5c6c + "@langchain/core": ">=0.3.39 <0.4.0" + checksum: fb8fe03764637a790b47f4a0c7d7050c796b43a4c03590e77b00c3183c52581f52d4077cec7b57ad4eeb7710d3bbbf1d8286e225da5e844580592d4e3218b1f2 languageName: node linkType: hard @@ -1918,42 +1870,25 @@ __metadata: languageName: node linkType: hard -"ai@npm:^3.1.12": - version: 3.3.26 - resolution: "ai@npm:3.3.26" +"ai@npm:^4.1.41": + version: 4.1.41 + resolution: "ai@npm:4.1.41" dependencies: - "@ai-sdk/provider": 0.0.22 - "@ai-sdk/provider-utils": 1.0.17 - "@ai-sdk/react": 0.0.54 - "@ai-sdk/solid": 0.0.43 - "@ai-sdk/svelte": 0.0.45 - "@ai-sdk/ui-utils": 0.0.40 - "@ai-sdk/vue": 0.0.45 + "@ai-sdk/provider": 1.0.7 + "@ai-sdk/provider-utils": 2.1.8 + "@ai-sdk/react": 1.1.16 + "@ai-sdk/ui-utils": 1.1.14 "@opentelemetry/api": 1.9.0 - eventsource-parser: 1.1.2 - json-schema: 0.4.0 jsondiffpatch: 0.6.0 - nanoid: 3.3.6 - secure-json-parse: 2.7.0 - zod-to-json-schema: 3.23.2 peerDependencies: - openai: ^4.42.0 - react: ^18 || ^19 - sswr: ^2.1.0 - svelte: ^3.0.0 || ^4.0.0 + react: ^18 || ^19 || ^19.0.0-rc zod: ^3.0.0 peerDependenciesMeta: - openai: - optional: true react: optional: true - sswr: - optional: true - svelte: - optional: true zod: optional: true - checksum: fc5424b346f8d809685ba9346182c30fe075878a9eb3b61279a97036e23c03271b5059365760996a3e9cbc49197ca9836bfbdc5806a30111cc6834b3ecc12fb7 + checksum: 952c01274cbd86f9077391246ca53a7f3dd36c4cb2035033c08822e3279e72f467658e98fb750428850291f9e24f019e6816685033d37d0e7ca10c92aa6ddaf8 languageName: node linkType: hard @@ -2355,7 +2290,7 @@ __metadata: languageName: node linkType: hard -"chalk@npm:^4.0.0, chalk@npm:^4.1.0": +"chalk@npm:^4.0.0, chalk@npm:^4.1.0, chalk@npm:^4.1.2": version: 4.1.2 resolution: "chalk@npm:4.1.2" dependencies: @@ -2414,7 +2349,7 @@ __metadata: languageName: node linkType: hard -"client-only@npm:0.0.1, client-only@npm:^0.0.1": +"client-only@npm:0.0.1": version: 0.0.1 resolution: "client-only@npm:0.0.1" checksum: 0c16bf660dadb90610553c1d8946a7fdfb81d624adea073b8440b7d795d5b5b08beb3c950c6a2cf16279365a3265158a236876d92bce16423c485c322d7dfaf8 @@ -2508,6 +2443,15 @@ __metadata: languageName: node linkType: hard +"console-table-printer@npm:^2.12.1": + version: 2.12.1 + resolution: "console-table-printer@npm:2.12.1" + dependencies: + simple-wcswidth: ^1.0.1 + checksum: 4d58fd4f18d3a69f421c9b0ffd44e5b0542677423491199e92c3e5ca0c023a06304a94bcc60f0d2b480a06cdf0720d2f228807f2af127abc8c905e73fcf64363 + languageName: node + linkType: hard + "cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.2": version: 7.0.3 resolution: "cross-spawn@npm:7.0.3" @@ -2665,6 +2609,13 @@ __metadata: languageName: node linkType: hard +"dequal@npm:^2.0.3": + version: 2.0.3 + resolution: "dequal@npm:2.0.3" + checksum: 8679b850e1a3d0ebbc46ee780d5df7b478c23f335887464023a631d1b9af051ad4a6595a44220f9ff8ff95a8ddccf019b5ad778a976fd7bbf77383d36f412f90 + languageName: node + linkType: hard + "detect-libc@npm:^2.0.3": version: 2.0.3 resolution: "detect-libc@npm:2.0.3" @@ -3241,10 +3192,10 @@ __metadata: languageName: node linkType: hard -"eventsource-parser@npm:1.1.2": - version: 1.1.2 - resolution: "eventsource-parser@npm:1.1.2" - checksum: 01896eea7203e097e50f7554da6ca3c6d33593ff11e8e3c970461932c3643bed2aea8402bf7fd16a1b25117de4e6fed15fef80672964a7dbd42b1e6781bf6e7a +"eventsource-parser@npm:^3.0.0": + version: 3.0.0 + resolution: "eventsource-parser@npm:3.0.0" + checksum: af7df874537a65e996568e5fed12db6eb27b4e041a70f5cc3a12b8b5b6f2ce229ba260d76b01f70f45ae0bf263e644d8f3768d24242f9ad86a8305991f61c7c0 languageName: node linkType: hard @@ -4195,7 +4146,7 @@ __metadata: languageName: node linkType: hard -"json-schema@npm:0.4.0": +"json-schema@npm:^0.4.0": version: 0.4.0 resolution: "json-schema@npm:0.4.0" checksum: 66389434c3469e698da0df2e7ac5a3281bcff75e797a5c127db7c5b56270e01ae13d9afa3c03344f76e32e81678337a8c912bdbb75101c62e487dc3778461d72 @@ -4266,9 +4217,9 @@ __metadata: resolution: "langchain-nextjs-template@workspace:." dependencies: "@langchain/community": ^0.3.25 - "@langchain/core": ^0.3.31 + "@langchain/core": ^0.3.40 "@langchain/langgraph": ^0.2.41 - "@langchain/openai": ^0.3.17 + "@langchain/openai": ^0.4.4 "@next/bundle-analyzer": ^13.4.19 "@radix-ui/react-checkbox": ^1.1.3 "@radix-ui/react-dialog": ^1.1.4 @@ -4278,7 +4229,7 @@ __metadata: "@types/node": 20.12.12 "@types/react": 18.3.2 "@types/react-dom": 18.3.0 - ai: ^3.1.12 + ai: ^4.1.41 autoprefixer: 10.4.14 class-variance-authority: ^0.7.1 clsx: ^2.1.1 @@ -4435,6 +4386,26 @@ __metadata: languageName: node linkType: hard +"langsmith@npm:>=0.2.8 <0.4.0": + version: 0.3.9 + resolution: "langsmith@npm:0.3.9" + dependencies: + "@types/uuid": ^10.0.0 + chalk: ^4.1.2 + console-table-printer: ^2.12.1 + p-queue: ^6.6.2 + p-retry: 4 + semver: ^7.6.3 + uuid: ^10.0.0 + peerDependencies: + openai: "*" + peerDependenciesMeta: + openai: + optional: true + checksum: 0d23fbe8ce1fb83728aaef2f50c3b9faa18a9b605e5d5df715b606cea01d5f7d674eb0174df58cf9ec832af99354ca3d01d4383599ad927780cdd24c94541ff5 + languageName: node + linkType: hard + "langsmith@npm:^0.2.0": version: 0.2.2 resolution: "langsmith@npm:0.2.2" @@ -4782,21 +4753,21 @@ __metadata: languageName: node linkType: hard -"nanoid@npm:3.3.6": - version: 3.3.6 - resolution: "nanoid@npm:3.3.6" +"nanoid@npm:^3.3.6, nanoid@npm:^3.3.7": + version: 3.3.7 + resolution: "nanoid@npm:3.3.7" bin: nanoid: bin/nanoid.cjs - checksum: 7d0eda657002738aa5206107bd0580aead6c95c460ef1bdd0b1a87a9c7ae6277ac2e9b945306aaa5b32c6dcb7feaf462d0f552e7f8b5718abfc6ead5c94a71b3 + checksum: d36c427e530713e4ac6567d488b489a36582ef89da1d6d4e3b87eded11eb10d7042a877958c6f104929809b2ab0bafa17652b076cdf84324aa75b30b722204f2 languageName: node linkType: hard -"nanoid@npm:^3.3.6, nanoid@npm:^3.3.7": - version: 3.3.7 - resolution: "nanoid@npm:3.3.7" +"nanoid@npm:^3.3.8": + version: 3.3.8 + resolution: "nanoid@npm:3.3.8" bin: nanoid: bin/nanoid.cjs - checksum: d36c427e530713e4ac6567d488b489a36582ef89da1d6d4e3b87eded11eb10d7042a877958c6f104929809b2ab0bafa17652b076cdf84324aa75b30b722204f2 + checksum: dfe0adbc0c77e9655b550c333075f51bb28cfc7568afbf3237249904f9c86c9aaaed1f113f0fddddba75673ee31c758c30c43d4414f014a52a7a626efc5958c9 languageName: node linkType: hard @@ -5774,7 +5745,7 @@ __metadata: languageName: node linkType: hard -"secure-json-parse@npm:2.7.0": +"secure-json-parse@npm:^2.7.0": version: 2.7.0 resolution: "secure-json-parse@npm:2.7.0" checksum: d9d7d5a01fc6db6115744ba23cf9e67ecfe8c524d771537c062ee05ad5c11b64c730bc58c7f33f60bd6877f96b86f0ceb9ea29644e4040cb757f6912d4dd6737 @@ -5938,6 +5909,13 @@ __metadata: languageName: node linkType: hard +"simple-wcswidth@npm:^1.0.1": + version: 1.0.1 + resolution: "simple-wcswidth@npm:1.0.1" + checksum: dc5bf4cb131d9c386825d1355add2b1ecc408b37dc2c2334edd7a1a4c9f527e6b594dedcdbf6d949bce2740c3a332e39af1183072a2d068e40d9e9146067a37f + languageName: node + linkType: hard + "sirv@npm:^1.0.7": version: 1.0.19 resolution: "sirv@npm:1.0.19" @@ -6017,17 +5995,6 @@ __metadata: languageName: node linkType: hard -"sswr@npm:2.1.0": - version: 2.1.0 - resolution: "sswr@npm:2.1.0" - dependencies: - swrev: ^4.0.0 - peerDependencies: - svelte: ^4.0.0 || ^5.0.0-next.0 - checksum: ae5cb3635c389923929e284f6c42d0fca7cfa28a93956917a1e99d964e8b8a7ad2f9e5207dad733ec5475cd197d74c00153e5ad8b308eea1d2569d4f0a77782a - languageName: node - linkType: hard - "stop-iteration-iterator@npm:^1.0.0": version: 1.0.0 resolution: "stop-iteration-iterator@npm:1.0.0" @@ -6222,31 +6189,15 @@ __metadata: languageName: node linkType: hard -"swr@npm:2.2.5": - version: 2.2.5 - resolution: "swr@npm:2.2.5" +"swr@npm:^2.2.5": + version: 2.3.2 + resolution: "swr@npm:2.3.2" dependencies: - client-only: ^0.0.1 - use-sync-external-store: ^1.2.0 - peerDependencies: - react: ^16.11.0 || ^17.0.0 || ^18.0.0 - checksum: c6e6a5bd254951b22e5fd0930a95c7f79b5d0657f803c41ba1542cd6376623fb70b1895049d54ddde26da63b91951ae9d62a06772f82be28c1014d421e5b7aa9 - languageName: node - linkType: hard - -"swrev@npm:^4.0.0": - version: 4.0.0 - resolution: "swrev@npm:4.0.0" - checksum: 454aed0e0367ef8faabfbe46e83e088199874beaa24c6a0e3aa58e10ec4464e33514d559f0e7be5adcbadffd3323c1b096c0625aaa13f029cbcc03ad40590a2f - languageName: node - linkType: hard - -"swrv@npm:1.0.4": - version: 1.0.4 - resolution: "swrv@npm:1.0.4" + dequal: ^2.0.3 + use-sync-external-store: ^1.4.0 peerDependencies: - vue: ">=3.2.26 < 4" - checksum: 6de43116e19ea22a8b76bd54c5b18571b84a32b0d4d1bfe80e9e562bd67d4464c1da73b3f60e6bf2b2f88e6e4576e596408dfb22a5af13c8186254395c466e91 + react: ^16.11.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + checksum: 215e7940dcb9deffbbe4f4402ae100bc48be93e83f822e6e26a3547f6625310bc010cb23ecb2164e121ef7a100466900cec774d74d019698ddf606c2f79a4a64 languageName: node linkType: hard @@ -6345,6 +6296,13 @@ __metadata: languageName: node linkType: hard +"throttleit@npm:2.1.0": + version: 2.1.0 + resolution: "throttleit@npm:2.1.0" + checksum: a2003947aafc721c4a17e6f07db72dc88a64fa9bba0f9c659f7997d30f9590b3af22dadd6a41851e0e8497d539c33b2935c2c7919cf4255922509af6913c619b + languageName: node + linkType: hard + "to-regex-range@npm:^5.0.1": version: 5.0.1 resolution: "to-regex-range@npm:5.0.1" @@ -6614,12 +6572,12 @@ __metadata: languageName: node linkType: hard -"use-sync-external-store@npm:^1.2.0": - version: 1.2.2 - resolution: "use-sync-external-store@npm:1.2.2" +"use-sync-external-store@npm:^1.4.0": + version: 1.4.0 + resolution: "use-sync-external-store@npm:1.4.0" peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - checksum: fe07c071c4da3645f112c38c0e57beb479a8838616ff4e92598256ecce527f2888c08febc7f9b2f0ce2f0e18540ba3cde41eb2035e4fafcb4f52955037098a81 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + checksum: dc3843a1b59ac8bd01417bd79498d4c688d5df8bf4801be50008ef4bfaacb349058c0b1605b5b43c828e0a2d62722d7e861573b3f31cea77a7f23e8b0fc2f7e3 languageName: node linkType: hard @@ -6872,7 +6830,7 @@ __metadata: languageName: node linkType: hard -"zod-to-json-schema@npm:3.23.2, zod-to-json-schema@npm:^3.22.3, zod-to-json-schema@npm:^3.22.5, zod-to-json-schema@npm:^3.23.2": +"zod-to-json-schema@npm:^3.22.3, zod-to-json-schema@npm:^3.22.5, zod-to-json-schema@npm:^3.23.2": version: 3.23.2 resolution: "zod-to-json-schema@npm:3.23.2" peerDependencies: @@ -6881,6 +6839,15 @@ __metadata: languageName: node linkType: hard +"zod-to-json-schema@npm:^3.24.1": + version: 3.24.1 + resolution: "zod-to-json-schema@npm:3.24.1" + peerDependencies: + zod: ^3.24.1 + checksum: 7195563f611bc21ea7f44129b8e32780125a9bd98b2e6b8709ac98bd2645729fecd87b8aeeaa8789617ee3f38e6585bab23dd613e2a35c31c6c157908f7a1681 + languageName: node + linkType: hard + "zod@npm:^3.22.3, zod@npm:^3.22.4, zod@npm:^3.23.8": version: 3.23.8 resolution: "zod@npm:3.23.8" From 3a7da13c8b2e1fd913ecb9fa6adac785c915c4ab Mon Sep 17 00:00:00 2001 From: Deepu Date: Tue, 18 Feb 2025 20:40:25 +0100 Subject: [PATCH 2/3] use @ai-sdk/react and LangChainAdapter --- app/api/chat/agents/route.ts | 43 ++++++++------------------ app/api/chat/retrieval/route.ts | 13 ++++---- app/api/chat/retrieval_agents/route.ts | 28 +++-------------- app/api/chat/route.ts | 13 ++------ app/structured_output/page.tsx | 1 + components/ChatMessageBubble.tsx | 2 +- components/ChatWindow.tsx | 41 +++++++++++++++--------- components/IntermediateStep.tsx | 4 +-- 8 files changed, 58 insertions(+), 87 deletions(-) diff --git a/app/api/chat/agents/route.ts b/app/api/chat/agents/route.ts index f4ce831..1a2bd04 100644 --- a/app/api/chat/agents/route.ts +++ b/app/api/chat/agents/route.ts @@ -1,5 +1,5 @@ import { NextRequest, NextResponse } from "next/server"; -import { Message as VercelChatMessage, StreamingTextResponse } from "ai"; +import { Message as VercelChatMessage, LangChainAdapter } from "ai"; import { createReactAgent } from "@langchain/langgraph/prebuilt"; import { ChatOpenAI } from "@langchain/openai"; @@ -26,23 +26,28 @@ const convertVercelMessageToLangChainMessage = (message: VercelChatMessage) => { }; const convertLangChainMessageToVercelMessage = (message: BaseMessage) => { - if (message._getType() === "human") { + if (message.getType() === "human") { return { content: message.content, role: "user" }; - } else if (message._getType() === "ai") { + } else if (message.getType() === "ai") { return { content: message.content, role: "assistant", - tool_calls: (message as AIMessage).tool_calls, + parts: (message as AIMessage).tool_calls, + }; + } else if (message.getType() === "tool") { + return { + content: message.content, + role: "system", }; } else { - return { content: message.content, role: message._getType() }; + return { content: message.content, role: message.getType() }; } }; const AGENT_SYSTEM_TEMPLATE = `You are a talking parrot named Polly. All final responses must be how a talking parrot would respond. Squawk often!`; /** - * This handler initializes and calls an tool caling ReAct agent. + * This handler initializes and calls an tool calling ReAct agent. * See the docs for more information: * * https://langchain-ai.github.io/langgraphjs/tutorials/quickstart/ @@ -89,36 +94,14 @@ export async function POST(req: NextRequest) { /** * Stream back all generated tokens and steps from their runs. * - * We do some filtering of the generated events and only stream back - * the final response as a string. - * * For this specific type of tool calling ReAct agents with OpenAI, we can tell when * the agent is ready to stream back final output when it no longer calls * a tool and instead streams back content. * * See: https://langchain-ai.github.io/langgraphjs/how-tos/stream-tokens/ */ - const eventStream = await agent.streamEvents( - { messages }, - { version: "v2" }, - ); - - const textEncoder = new TextEncoder(); - const transformStream = new ReadableStream({ - async start(controller) { - for await (const { event, data } of eventStream) { - if (event === "on_chat_model_stream") { - // Intermediate chat model generations will contain tool calls and no content - if (!!data.chunk.content) { - controller.enqueue(textEncoder.encode(data.chunk.content)); - } - } - } - controller.close(); - }, - }); - - return new StreamingTextResponse(transformStream); + const eventStream = agent.streamEvents({ messages }, { version: "v2" }); + return LangChainAdapter.toDataStreamResponse(eventStream); } else { /** * We could also pick intermediate steps out from `streamEvents` chunks, but diff --git a/app/api/chat/retrieval/route.ts b/app/api/chat/retrieval/route.ts index 53a8078..2773f39 100644 --- a/app/api/chat/retrieval/route.ts +++ b/app/api/chat/retrieval/route.ts @@ -1,5 +1,5 @@ import { NextRequest, NextResponse } from "next/server"; -import { Message as VercelChatMessage, StreamingTextResponse } from "ai"; +import { LangChainAdapter, Message as VercelChatMessage } from "ai"; import { createClient } from "@supabase/supabase-js"; @@ -140,7 +140,6 @@ export async function POST(req: NextRequest) { chat_history: (input) => input.chat_history, }, answerChain, - new BytesOutputParser(), ]); const stream = await conversationalRetrievalQAChain.stream({ @@ -160,10 +159,12 @@ export async function POST(req: NextRequest) { ), ).toString("base64"); - return new StreamingTextResponse(stream, { - headers: { - "x-message-index": (previousMessages.length + 1).toString(), - "x-sources": serializedSources, + return LangChainAdapter.toDataStreamResponse(stream, { + init: { + headers: { + "x-message-index": (previousMessages.length + 1).toString(), + "x-sources": serializedSources, + }, }, }); } catch (e: any) { diff --git a/app/api/chat/retrieval_agents/route.ts b/app/api/chat/retrieval_agents/route.ts index 7b5e342..f1de0c6 100644 --- a/app/api/chat/retrieval_agents/route.ts +++ b/app/api/chat/retrieval_agents/route.ts @@ -1,5 +1,5 @@ import { NextRequest, NextResponse } from "next/server"; -import { Message as VercelChatMessage, StreamingTextResponse } from "ai"; +import { LangChainAdapter, Message as VercelChatMessage } from "ai"; import { createClient } from "@supabase/supabase-js"; @@ -46,7 +46,7 @@ const AGENT_SYSTEM_TEMPLATE = `You are a stereotypical robot named Robbie and mu If you don't know how to answer a question, use the available tools to look up relevant information. You should particularly do this for questions about LangChain.`; /** - * This handler initializes and calls an tool caling ReAct agent. + * This handler initializes and calls an tool calling ReAct agent. * See the docs for more information: * * https://langchain-ai.github.io/langgraphjs/tutorials/quickstart/ @@ -96,7 +96,7 @@ export async function POST(req: NextRequest) { /** * Use a prebuilt LangGraph agent. */ - const agent = await createReactAgent({ + const agent = createReactAgent({ llm: chatModel, tools: [tool], /** @@ -112,38 +112,20 @@ export async function POST(req: NextRequest) { /** * Stream back all generated tokens and steps from their runs. * - * We do some filtering of the generated events and only stream back - * the final response as a string. - * * For this specific type of tool calling ReAct agents with OpenAI, we can tell when * the agent is ready to stream back final output when it no longer calls * a tool and instead streams back content. * * See: https://langchain-ai.github.io/langgraphjs/how-tos/stream-tokens/ */ - const eventStream = await agent.streamEvents( + const eventStream = agent.streamEvents( { messages, }, { version: "v2" }, ); - const textEncoder = new TextEncoder(); - const transformStream = new ReadableStream({ - async start(controller) { - for await (const { event, data } of eventStream) { - if (event === "on_chat_model_stream") { - // Intermediate chat model generations will contain tool calls and no content - if (!!data.chunk.content) { - controller.enqueue(textEncoder.encode(data.chunk.content)); - } - } - } - controller.close(); - }, - }); - - return new StreamingTextResponse(transformStream); + return LangChainAdapter.toDataStreamResponse(eventStream); } else { /** * We could also pick intermediate steps out from `streamEvents` chunks, but diff --git a/app/api/chat/route.ts b/app/api/chat/route.ts index 093a17c..ad9f02e 100644 --- a/app/api/chat/route.ts +++ b/app/api/chat/route.ts @@ -1,9 +1,8 @@ import { NextRequest, NextResponse } from "next/server"; -import { Message as VercelChatMessage, StreamingTextResponse } from "ai"; +import { Message as VercelChatMessage, LangChainAdapter } from "ai"; import { ChatOpenAI } from "@langchain/openai"; import { PromptTemplate } from "@langchain/core/prompts"; -import { HttpResponseOutputParser } from "langchain/output_parsers"; export const runtime = "edge"; @@ -47,26 +46,20 @@ export async function POST(req: NextRequest) { model: "gpt-4o-mini", }); - /** - * Chat models stream message chunks rather than bytes, so this - * output parser handles serialization and byte-encoding. - */ - const outputParser = new HttpResponseOutputParser(); - /** * Can also initialize as: * * import { RunnableSequence } from "@langchain/core/runnables"; * const chain = RunnableSequence.from([prompt, model, outputParser]); */ - const chain = prompt.pipe(model).pipe(outputParser); + const chain = prompt.pipe(model); const stream = await chain.stream({ chat_history: formattedPreviousMessages.join("\n"), input: currentMessageContent, }); - return new StreamingTextResponse(stream); + return LangChainAdapter.toDataStreamResponse(stream); } catch (e: any) { return NextResponse.json({ error: e.message }, { status: e.status ?? 500 }); } diff --git a/app/structured_output/page.tsx b/app/structured_output/page.tsx index 1edd2ca..212f37f 100644 --- a/app/structured_output/page.tsx +++ b/app/structured_output/page.tsx @@ -80,6 +80,7 @@ export default function AgentsPage() { emptyStateComponent={InfoCard} placeholder={`No matter what you type here, I'll always return the same JSON object with the same structure!`} emoji="🧱" + streamProtocol="text" /> ); } diff --git a/components/ChatMessageBubble.tsx b/components/ChatMessageBubble.tsx index 9f6973c..3d839df 100644 --- a/components/ChatMessageBubble.tsx +++ b/components/ChatMessageBubble.tsx @@ -1,5 +1,5 @@ import { cn } from "@/utils/cn"; -import type { Message } from "ai/react"; +import type { Message } from "@ai-sdk/react"; export function ChatMessageBubble(props: { message: Message; diff --git a/components/ChatWindow.tsx b/components/ChatWindow.tsx index 1bffe09..379fb20 100644 --- a/components/ChatWindow.tsx +++ b/components/ChatWindow.tsx @@ -1,16 +1,16 @@ "use client"; -import { type Message } from "ai"; -import { useChat } from "ai/react"; +import { UIMessage, type Message } from "ai"; +import { useChat } from "@ai-sdk/react"; import { useState } from "react"; import type { FormEvent, ReactNode } from "react"; import { toast } from "sonner"; import { StickToBottom, useStickToBottomContext } from "use-stick-to-bottom"; +import { ArrowDown, LoaderCircle, Paperclip } from "lucide-react"; import { ChatMessageBubble } from "@/components/ChatMessageBubble"; import { IntermediateStep } from "./IntermediateStep"; import { Button } from "./ui/button"; -import { ArrowDown, LoaderCircle, Paperclip } from "lucide-react"; import { Checkbox } from "./ui/checkbox"; import { UploadDocumentsForm } from "./UploadDocumentsForm"; import { @@ -143,6 +143,7 @@ export function ChatWindow(props: { emoji?: string; showIngestForm?: boolean; showIntermediateStepsToggle?: boolean; + streamProtocol?: "text" | "data"; }) { const [showIntermediateSteps, setShowIntermediateSteps] = useState( !!props.showIntermediateStepsToggle, @@ -170,16 +171,22 @@ export function ChatWindow(props: { }); } }, - streamMode: "text", - onError: (e) => + streamProtocol: props.streamProtocol ?? undefined, + onError: (e) => { + console.log("Error:", e); toast.error(`Error while processing your request`, { description: e.message, - }), + }); + }, }); + function isChatLoading(): boolean { + return chat.status === "streaming"; + } + async function sendMessage(e: FormEvent) { e.preventDefault(); - if (chat.isLoading || intermediateStepsLoading) return; + if (isChatLoading() || intermediateStepsLoading) return; if (!showIntermediateSteps) { chat.handleSubmit(e); @@ -194,6 +201,7 @@ export function ChatWindow(props: { id: chat.messages.length.toString(), content: chat.input, role: "user", + parts: [{ type: "text", text: chat.input }], }); chat.setMessages(messagesWithUserReply); @@ -208,6 +216,7 @@ export function ChatWindow(props: { setIntermediateStepsLoading(false); if (!response.ok) { + console.log("Error:", json.error); toast.error(`Error while processing your request`, { description: json.error, }); @@ -222,23 +231,25 @@ export function ChatWindow(props: { (responseMessage: Message) => { return ( (responseMessage.role === "assistant" && - !!responseMessage.tool_calls?.length) || - responseMessage.role === "tool" + !!responseMessage.parts?.length) || + responseMessage.role === "system" ); }, ); - const intermediateStepMessages = []; + const intermediateStepMessages: UIMessage[] = []; for (let i = 0; i < toolCallMessages.length; i += 2) { const aiMessage = toolCallMessages[i]; const toolMessage = toolCallMessages[i + 1]; + const content = JSON.stringify({ + action: aiMessage.parts?.[0], + observation: toolMessage.content, + }); intermediateStepMessages.push({ id: (messagesWithUserReply.length + i / 2).toString(), role: "system" as const, - content: JSON.stringify({ - action: aiMessage.tool_calls?.[0], - observation: toolMessage.content, - }), + content, + parts: [{ type: "text", text: content }], }); } const newMessages = messagesWithUserReply; @@ -319,7 +330,7 @@ export function ChatWindow(props: { id="show_intermediate_steps" name="show_intermediate_steps" checked={showIntermediateSteps} - disabled={chat.isLoading || intermediateStepsLoading} + disabled={isChatLoading() || intermediateStepsLoading} onCheckedChange={(e) => setShowIntermediateSteps(!!e)} />