@assistant-ui/mcp-docs-server 0.1.13 → 0.1.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.docs/organized/code-examples/with-ag-ui.md +1089 -0
- package/.docs/organized/code-examples/with-ai-sdk-v5.md +12 -12
- package/.docs/organized/code-examples/with-assistant-transport.md +10 -10
- package/.docs/organized/code-examples/with-cloud.md +7 -7
- package/.docs/organized/code-examples/with-external-store.md +6 -6
- package/.docs/organized/code-examples/with-ffmpeg.md +10 -10
- package/.docs/organized/code-examples/with-langgraph.md +5 -5
- package/.docs/organized/code-examples/with-parent-id-grouping.md +6 -6
- package/.docs/organized/code-examples/with-react-hook-form.md +10 -10
- package/.docs/raw/docs/cloud/authorization.mdx +2 -2
- package/.docs/raw/docs/guides/context-api.mdx +5 -5
- package/.docs/raw/docs/migrations/v0-12.mdx +2 -2
- package/.docs/raw/docs/runtimes/custom/custom-thread-list.mdx +9 -0
- package/.docs/raw/docs/runtimes/custom/local.mdx +77 -4
- package/.docs/raw/docs/runtimes/langgraph/index.mdx +7 -4
- package/.docs/raw/docs/runtimes/mastra/full-stack-integration.mdx +12 -10
- package/.docs/raw/docs/runtimes/mastra/separate-server-integration.mdx +50 -31
- package/.docs/raw/docs/ui/Reasoning.mdx +174 -0
- package/dist/chunk-M2RKUM66.js +3 -3
- package/dist/chunk-NVNFQ5ZO.js +2 -2
- package/package.json +5 -5
|
@@ -1035,32 +1035,32 @@ export default nextConfig;
|
|
|
1035
1035
|
"version": "0.0.0",
|
|
1036
1036
|
"type": "module",
|
|
1037
1037
|
"dependencies": {
|
|
1038
|
-
"@ai-sdk/openai": "^2.0.
|
|
1039
|
-
"@ai-sdk/react": "^2.0.
|
|
1038
|
+
"@ai-sdk/openai": "^2.0.68",
|
|
1039
|
+
"@ai-sdk/react": "^2.0.93",
|
|
1040
1040
|
"@assistant-ui/react": "workspace:^",
|
|
1041
1041
|
"@assistant-ui/react-ai-sdk": "workspace:*",
|
|
1042
1042
|
"@assistant-ui/react-markdown": "workspace:^",
|
|
1043
|
-
"@radix-ui/react-slot": "^1.2.
|
|
1043
|
+
"@radix-ui/react-slot": "^1.2.4",
|
|
1044
1044
|
"@radix-ui/react-tooltip": "^1.2.8",
|
|
1045
|
-
"@tailwindcss/postcss": "^4.1.
|
|
1046
|
-
"ai": "^5.0.
|
|
1045
|
+
"@tailwindcss/postcss": "^4.1.17",
|
|
1046
|
+
"ai": "^5.0.93",
|
|
1047
1047
|
"class-variance-authority": "^0.7.1",
|
|
1048
1048
|
"clsx": "^2.1.1",
|
|
1049
|
-
"lucide-react": "^0.
|
|
1050
|
-
"next": "16.0.
|
|
1049
|
+
"lucide-react": "^0.554.0",
|
|
1050
|
+
"next": "16.0.3",
|
|
1051
1051
|
"postcss": "^8.5.6",
|
|
1052
1052
|
"react": "19.2.0",
|
|
1053
1053
|
"react-dom": "19.2.0",
|
|
1054
1054
|
"remark-gfm": "^4.0.1",
|
|
1055
|
-
"tailwind-merge": "^3.
|
|
1056
|
-
"tailwindcss": "^4.1.
|
|
1055
|
+
"tailwind-merge": "^3.4.0",
|
|
1056
|
+
"tailwindcss": "^4.1.17",
|
|
1057
1057
|
"zod": "^4.1.12"
|
|
1058
1058
|
},
|
|
1059
1059
|
"devDependencies": {
|
|
1060
1060
|
"@assistant-ui/x-buildutils": "workspace:*",
|
|
1061
|
-
"@types/node": "^24.10.
|
|
1062
|
-
"@types/react": "^19.2.
|
|
1063
|
-
"@types/react-dom": "^19.2.
|
|
1061
|
+
"@types/node": "^24.10.1",
|
|
1062
|
+
"@types/react": "^19.2.5",
|
|
1063
|
+
"@types/react-dom": "^19.2.3",
|
|
1064
1064
|
"tw-animate-css": "^1.4.0",
|
|
1065
1065
|
"typescript": "^5.9.3"
|
|
1066
1066
|
},
|
|
@@ -1261,29 +1261,29 @@ export default nextConfig;
|
|
|
1261
1261
|
"@assistant-ui/react": "workspace:^",
|
|
1262
1262
|
"@assistant-ui/react-langgraph": "workspace:^",
|
|
1263
1263
|
"@assistant-ui/react-markdown": "workspace:^",
|
|
1264
|
-
"@radix-ui/react-slot": "^1.2.
|
|
1264
|
+
"@radix-ui/react-slot": "^1.2.4",
|
|
1265
1265
|
"@radix-ui/react-tooltip": "^1.2.8",
|
|
1266
|
-
"@tailwindcss/postcss": "^4.1.
|
|
1267
|
-
"assistant-stream": "^0.2.
|
|
1266
|
+
"@tailwindcss/postcss": "^4.1.17",
|
|
1267
|
+
"assistant-stream": "^0.2.41",
|
|
1268
1268
|
"class-variance-authority": "^0.7.1",
|
|
1269
1269
|
"clsx": "^2.1.1",
|
|
1270
1270
|
"framer-motion": "^12.23.24",
|
|
1271
|
-
"lucide-react": "^0.
|
|
1272
|
-
"next": "16.0.
|
|
1271
|
+
"lucide-react": "^0.554.0",
|
|
1272
|
+
"next": "16.0.3",
|
|
1273
1273
|
"postcss": "^8.5.6",
|
|
1274
1274
|
"react": "19.2.0",
|
|
1275
1275
|
"react-dom": "19.2.0",
|
|
1276
1276
|
"remark-gfm": "^4.0.1",
|
|
1277
|
-
"tailwind-merge": "^3.
|
|
1278
|
-
"tailwindcss": "^4.1.
|
|
1277
|
+
"tailwind-merge": "^3.4.0",
|
|
1278
|
+
"tailwindcss": "^4.1.17",
|
|
1279
1279
|
"tailwindcss-animate": "^1.0.7",
|
|
1280
1280
|
"zod": "^4.1.12"
|
|
1281
1281
|
},
|
|
1282
1282
|
"devDependencies": {
|
|
1283
1283
|
"@assistant-ui/x-buildutils": "workspace:*",
|
|
1284
|
-
"@types/node": "^24.10.
|
|
1285
|
-
"@types/react": "^19.2.
|
|
1286
|
-
"@types/react-dom": "^19.2.
|
|
1284
|
+
"@types/node": "^24.10.1",
|
|
1285
|
+
"@types/react": "^19.2.5",
|
|
1286
|
+
"@types/react-dom": "^19.2.3",
|
|
1287
1287
|
"tw-animate-css": "^1.4.0",
|
|
1288
1288
|
"typescript": "^5.9.3"
|
|
1289
1289
|
},
|
|
@@ -1083,23 +1083,23 @@ export default nextConfig;
|
|
|
1083
1083
|
"lint": "eslint ."
|
|
1084
1084
|
},
|
|
1085
1085
|
"dependencies": {
|
|
1086
|
-
"@ai-sdk/openai": "^2.0.
|
|
1086
|
+
"@ai-sdk/openai": "^2.0.68",
|
|
1087
1087
|
"@assistant-ui/react": "workspace:*",
|
|
1088
1088
|
"@assistant-ui/react-ai-sdk": "workspace:*",
|
|
1089
1089
|
"@assistant-ui/react-markdown": "workspace:*",
|
|
1090
|
-
"@radix-ui/react-slot": "^1.2.
|
|
1090
|
+
"@radix-ui/react-slot": "^1.2.4",
|
|
1091
1091
|
"@radix-ui/react-tooltip": "^1.2.8",
|
|
1092
|
-
"ai": "^5.0.
|
|
1092
|
+
"ai": "^5.0.93",
|
|
1093
1093
|
"class-variance-authority": "^0.7.1",
|
|
1094
1094
|
"clsx": "^2.1.1",
|
|
1095
1095
|
"jsonwebtoken": "^9.0.2",
|
|
1096
|
-
"lucide-react": "^0.
|
|
1096
|
+
"lucide-react": "^0.554.0",
|
|
1097
1097
|
"nanoid": "5.1.6",
|
|
1098
|
-
"next": "16.0.
|
|
1098
|
+
"next": "16.0.3",
|
|
1099
1099
|
"react": "19.2.0",
|
|
1100
1100
|
"react-dom": "19.2.0",
|
|
1101
1101
|
"remark-gfm": "^4.0.1",
|
|
1102
|
-
"tailwind-merge": "^3.
|
|
1102
|
+
"tailwind-merge": "^3.4.0",
|
|
1103
1103
|
"tw-animate-css": "^1.4.0"
|
|
1104
1104
|
},
|
|
1105
1105
|
"devDependencies": {
|
|
@@ -1109,7 +1109,7 @@ export default nextConfig;
|
|
|
1109
1109
|
"@types/react": "^19",
|
|
1110
1110
|
"@types/react-dom": "^19",
|
|
1111
1111
|
"postcss": "^8",
|
|
1112
|
-
"tailwindcss": "^4.1.
|
|
1112
|
+
"tailwindcss": "^4.1.17",
|
|
1113
1113
|
"typescript": "^5"
|
|
1114
1114
|
}
|
|
1115
1115
|
}
|
|
@@ -995,19 +995,19 @@ export default nextConfig;
|
|
|
995
995
|
"lint": "eslint ."
|
|
996
996
|
},
|
|
997
997
|
"dependencies": {
|
|
998
|
-
"@ai-sdk/openai": "^2.0.
|
|
998
|
+
"@ai-sdk/openai": "^2.0.68",
|
|
999
999
|
"@assistant-ui/react": "workspace:*",
|
|
1000
1000
|
"@assistant-ui/react-markdown": "workspace:*",
|
|
1001
|
-
"@radix-ui/react-slot": "^1.2.
|
|
1001
|
+
"@radix-ui/react-slot": "^1.2.4",
|
|
1002
1002
|
"@radix-ui/react-tooltip": "^1.2.8",
|
|
1003
1003
|
"class-variance-authority": "^0.7.1",
|
|
1004
1004
|
"clsx": "^2.1.1",
|
|
1005
|
-
"lucide-react": "^0.
|
|
1006
|
-
"next": "16.0.
|
|
1005
|
+
"lucide-react": "^0.554.0",
|
|
1006
|
+
"next": "16.0.3",
|
|
1007
1007
|
"react": "19.2.0",
|
|
1008
1008
|
"react-dom": "19.2.0",
|
|
1009
1009
|
"remark-gfm": "^4.0.1",
|
|
1010
|
-
"tailwind-merge": "^3.
|
|
1010
|
+
"tailwind-merge": "^3.4.0",
|
|
1011
1011
|
"tw-animate-css": "^1.4.0"
|
|
1012
1012
|
},
|
|
1013
1013
|
"devDependencies": {
|
|
@@ -1016,7 +1016,7 @@ export default nextConfig;
|
|
|
1016
1016
|
"@types/react": "^19",
|
|
1017
1017
|
"@types/react-dom": "^19",
|
|
1018
1018
|
"postcss": "^8",
|
|
1019
|
-
"tailwindcss": "^4.1.
|
|
1019
|
+
"tailwindcss": "^4.1.17",
|
|
1020
1020
|
"typescript": "^5"
|
|
1021
1021
|
}
|
|
1022
1022
|
}
|
|
@@ -1220,7 +1220,7 @@ export default nextConfig;
|
|
|
1220
1220
|
"lint": "eslint ."
|
|
1221
1221
|
},
|
|
1222
1222
|
"dependencies": {
|
|
1223
|
-
"@ai-sdk/openai": "^2.0.
|
|
1223
|
+
"@ai-sdk/openai": "^2.0.68",
|
|
1224
1224
|
"@assistant-ui/react": "workspace:*",
|
|
1225
1225
|
"@assistant-ui/react-ai-sdk": "workspace:*",
|
|
1226
1226
|
"@assistant-ui/react-hook-form": "workspace:*",
|
|
@@ -1228,25 +1228,25 @@ export default nextConfig;
|
|
|
1228
1228
|
"@ffmpeg/ffmpeg": "^0.12.15",
|
|
1229
1229
|
"@ffmpeg/util": "^0.12.2",
|
|
1230
1230
|
"@hookform/resolvers": "^5.2.2",
|
|
1231
|
-
"@radix-ui/react-avatar": "^1.1.
|
|
1231
|
+
"@radix-ui/react-avatar": "^1.1.11",
|
|
1232
1232
|
"@radix-ui/react-icons": "^1.3.2",
|
|
1233
|
-
"@radix-ui/react-label": "^2.1.
|
|
1234
|
-
"@radix-ui/react-slot": "^1.2.
|
|
1233
|
+
"@radix-ui/react-label": "^2.1.8",
|
|
1234
|
+
"@radix-ui/react-slot": "^1.2.4",
|
|
1235
1235
|
"@radix-ui/react-tabs": "^1.1.13",
|
|
1236
1236
|
"@radix-ui/react-tooltip": "^1.2.8",
|
|
1237
1237
|
"@react-hook/media-query": "^1.1.1",
|
|
1238
|
-
"ai": "^5.0.
|
|
1238
|
+
"ai": "^5.0.93",
|
|
1239
1239
|
"class-variance-authority": "^0.7.1",
|
|
1240
1240
|
"clsx": "^2.1.1",
|
|
1241
1241
|
"json-schema-to-zod": "^2.6.1",
|
|
1242
|
-
"lucide-react": "^0.
|
|
1243
|
-
"next": "16.0.
|
|
1242
|
+
"lucide-react": "^0.554.0",
|
|
1243
|
+
"next": "16.0.3",
|
|
1244
1244
|
"react": "19.2.0",
|
|
1245
1245
|
"react-dom": "19.2.0",
|
|
1246
|
-
"react-hook-form": "^7.66.
|
|
1246
|
+
"react-hook-form": "^7.66.1",
|
|
1247
1247
|
"react-resizable-panels": "^3.0.6",
|
|
1248
1248
|
"remark-gfm": "^4.0.1",
|
|
1249
|
-
"tailwind-merge": "^3.
|
|
1249
|
+
"tailwind-merge": "^3.4.0",
|
|
1250
1250
|
"tw-animate-css": "^1.4.0",
|
|
1251
1251
|
"zod": "^4.1.12",
|
|
1252
1252
|
"zustand": "^5.0.8"
|
|
@@ -1257,7 +1257,7 @@ export default nextConfig;
|
|
|
1257
1257
|
"@types/react": "^19",
|
|
1258
1258
|
"@types/react-dom": "^19",
|
|
1259
1259
|
"postcss": "^8",
|
|
1260
|
-
"tailwindcss": "^4.1.
|
|
1260
|
+
"tailwindcss": "^4.1.17",
|
|
1261
1261
|
"typescript": "^5.9.3"
|
|
1262
1262
|
}
|
|
1263
1263
|
}
|
|
@@ -1669,19 +1669,19 @@ export default nextConfig;
|
|
|
1669
1669
|
"@assistant-ui/react-langgraph": "workspace:*",
|
|
1670
1670
|
"@assistant-ui/react-markdown": "workspace:*",
|
|
1671
1671
|
"@langchain/langgraph-sdk": "^1.0.0",
|
|
1672
|
-
"@radix-ui/react-slot": "^1.2.
|
|
1672
|
+
"@radix-ui/react-slot": "^1.2.4",
|
|
1673
1673
|
"@radix-ui/react-tooltip": "^1.2.8",
|
|
1674
1674
|
"class-variance-authority": "^0.7.1",
|
|
1675
1675
|
"clsx": "^2.1.1",
|
|
1676
1676
|
"js-cookie": "^3.0.5",
|
|
1677
1677
|
"jsonwebtoken": "^9.0.2",
|
|
1678
|
-
"lucide-react": "^0.
|
|
1678
|
+
"lucide-react": "^0.554.0",
|
|
1679
1679
|
"nanoid": "5.1.6",
|
|
1680
|
-
"next": "16.0.
|
|
1680
|
+
"next": "16.0.3",
|
|
1681
1681
|
"react": "19.2.0",
|
|
1682
1682
|
"react-dom": "19.2.0",
|
|
1683
1683
|
"remark-gfm": "^4.0.1",
|
|
1684
|
-
"tailwind-merge": "^3.
|
|
1684
|
+
"tailwind-merge": "^3.4.0",
|
|
1685
1685
|
"tw-animate-css": "^1.4.0"
|
|
1686
1686
|
},
|
|
1687
1687
|
"devDependencies": {
|
|
@@ -1692,7 +1692,7 @@ export default nextConfig;
|
|
|
1692
1692
|
"@types/react": "^19",
|
|
1693
1693
|
"@types/react-dom": "^19",
|
|
1694
1694
|
"postcss": "^8",
|
|
1695
|
-
"tailwindcss": "^4.1.
|
|
1695
|
+
"tailwindcss": "^4.1.17",
|
|
1696
1696
|
"typescript": "^5.9.3"
|
|
1697
1697
|
}
|
|
1698
1698
|
}
|
|
@@ -1241,19 +1241,19 @@ export default nextConfig;
|
|
|
1241
1241
|
"lint": "eslint ."
|
|
1242
1242
|
},
|
|
1243
1243
|
"dependencies": {
|
|
1244
|
-
"@ai-sdk/openai": "^2.0.
|
|
1244
|
+
"@ai-sdk/openai": "^2.0.68",
|
|
1245
1245
|
"@assistant-ui/react": "workspace:*",
|
|
1246
1246
|
"@assistant-ui/react-markdown": "workspace:*",
|
|
1247
|
-
"@radix-ui/react-slot": "^1.2.
|
|
1247
|
+
"@radix-ui/react-slot": "^1.2.4",
|
|
1248
1248
|
"@radix-ui/react-tooltip": "^1.2.8",
|
|
1249
1249
|
"class-variance-authority": "^0.7.1",
|
|
1250
1250
|
"clsx": "^2.1.1",
|
|
1251
|
-
"lucide-react": "^0.
|
|
1252
|
-
"next": "16.0.
|
|
1251
|
+
"lucide-react": "^0.554.0",
|
|
1252
|
+
"next": "16.0.3",
|
|
1253
1253
|
"react": "19.2.0",
|
|
1254
1254
|
"react-dom": "19.2.0",
|
|
1255
1255
|
"remark-gfm": "^4.0.1",
|
|
1256
|
-
"tailwind-merge": "^3.
|
|
1256
|
+
"tailwind-merge": "^3.4.0",
|
|
1257
1257
|
"tw-animate-css": "^1.4.0"
|
|
1258
1258
|
},
|
|
1259
1259
|
"devDependencies": {
|
|
@@ -1262,7 +1262,7 @@ export default nextConfig;
|
|
|
1262
1262
|
"@types/react": "^19",
|
|
1263
1263
|
"@types/react-dom": "^19",
|
|
1264
1264
|
"postcss": "^8",
|
|
1265
|
-
"tailwindcss": "^4.1.
|
|
1265
|
+
"tailwindcss": "^4.1.17",
|
|
1266
1266
|
"typescript": "^5"
|
|
1267
1267
|
}
|
|
1268
1268
|
}
|
|
@@ -1640,31 +1640,31 @@ export default nextConfig;
|
|
|
1640
1640
|
"lint": "eslint ."
|
|
1641
1641
|
},
|
|
1642
1642
|
"dependencies": {
|
|
1643
|
-
"@ai-sdk/openai": "^2.0.
|
|
1643
|
+
"@ai-sdk/openai": "^2.0.68",
|
|
1644
1644
|
"@assistant-ui/react": "workspace:*",
|
|
1645
1645
|
"@assistant-ui/react-ai-sdk": "workspace:*",
|
|
1646
1646
|
"@assistant-ui/react-hook-form": "workspace:*",
|
|
1647
1647
|
"@assistant-ui/react-markdown": "workspace:*",
|
|
1648
1648
|
"@hookform/resolvers": "^5.2.2",
|
|
1649
|
-
"@radix-ui/react-avatar": "^1.1.
|
|
1649
|
+
"@radix-ui/react-avatar": "^1.1.11",
|
|
1650
1650
|
"@radix-ui/react-icons": "^1.3.2",
|
|
1651
|
-
"@radix-ui/react-label": "^2.1.
|
|
1652
|
-
"@radix-ui/react-slot": "^1.2.
|
|
1651
|
+
"@radix-ui/react-label": "^2.1.8",
|
|
1652
|
+
"@radix-ui/react-slot": "^1.2.4",
|
|
1653
1653
|
"@radix-ui/react-tabs": "^1.1.13",
|
|
1654
1654
|
"@radix-ui/react-tooltip": "^1.2.8",
|
|
1655
1655
|
"@react-hook/media-query": "^1.1.1",
|
|
1656
|
-
"ai": "^5.0.
|
|
1656
|
+
"ai": "^5.0.93",
|
|
1657
1657
|
"class-variance-authority": "^0.7.1",
|
|
1658
1658
|
"clsx": "^2.1.1",
|
|
1659
1659
|
"json-schema-to-zod": "^2.6.1",
|
|
1660
|
-
"lucide-react": "^0.
|
|
1661
|
-
"next": "16.0.
|
|
1660
|
+
"lucide-react": "^0.554.0",
|
|
1661
|
+
"next": "16.0.3",
|
|
1662
1662
|
"react": "19.2.0",
|
|
1663
1663
|
"react-dom": "19.2.0",
|
|
1664
|
-
"react-hook-form": "^7.66.
|
|
1664
|
+
"react-hook-form": "^7.66.1",
|
|
1665
1665
|
"react-resizable-panels": "^3.0.6",
|
|
1666
1666
|
"remark-gfm": "^4.0.1",
|
|
1667
|
-
"tailwind-merge": "^3.
|
|
1667
|
+
"tailwind-merge": "^3.4.0",
|
|
1668
1668
|
"tw-animate-css": "^1.4.0",
|
|
1669
1669
|
"zod": "^4.1.12",
|
|
1670
1670
|
"zustand": "^5.0.8"
|
|
@@ -1675,7 +1675,7 @@ export default nextConfig;
|
|
|
1675
1675
|
"@types/react": "^19",
|
|
1676
1676
|
"@types/react-dom": "^19",
|
|
1677
1677
|
"postcss": "^8",
|
|
1678
|
-
"tailwindcss": "^4.1.
|
|
1678
|
+
"tailwindcss": "^4.1.17",
|
|
1679
1679
|
"typescript": "^5.9.3"
|
|
1680
1680
|
}
|
|
1681
1681
|
}
|
|
@@ -70,7 +70,7 @@ export const POST = async (req: Request) => {
|
|
|
70
70
|
|
|
71
71
|
if (!userId) throw new Error("User not authenticated");
|
|
72
72
|
|
|
73
|
-
const workspaceId = orgId ? `${orgId}
|
|
73
|
+
const workspaceId = orgId ? `${orgId}_${userId}` : userId;
|
|
74
74
|
const assistantCloud = new AssistantCloud({
|
|
75
75
|
apiKey: process.env["ASSISTANT_API_KEY"]!,
|
|
76
76
|
userId,
|
|
@@ -91,7 +91,7 @@ const cloud = new AssistantCloud({
|
|
|
91
91
|
baseUrl: process.env["NEXT_PUBLIC_ASSISTANT_BASE_URL"]!,
|
|
92
92
|
authToken: () =>
|
|
93
93
|
fetch("/api/assistant-ui-token", { method: "POST" }).then((r) =>
|
|
94
|
-
r.
|
|
94
|
+
r.text(),
|
|
95
95
|
),
|
|
96
96
|
});
|
|
97
97
|
|
|
@@ -35,7 +35,7 @@ assistant-ui organizes state into **scopes** - logical boundaries that provide a
|
|
|
35
35
|
└── ✏️ Composer (composer) - New message input
|
|
36
36
|
└── 📎 Attachment (attachment) - Files being added
|
|
37
37
|
|
|
38
|
-
🔧
|
|
38
|
+
🔧 Tools (tools) - Custom UI components for tool calls
|
|
39
39
|
```
|
|
40
40
|
|
|
41
41
|
**How scopes work:**
|
|
@@ -212,9 +212,9 @@ api.threadListItem().unarchive();
|
|
|
212
212
|
api.threadListItem().delete();
|
|
213
213
|
api.threads().getState();
|
|
214
214
|
|
|
215
|
-
//
|
|
216
|
-
api.
|
|
217
|
-
api.
|
|
215
|
+
// Tools actions
|
|
216
|
+
api.tools().setToolUI(toolName, render);
|
|
217
|
+
api.tools().getState();
|
|
218
218
|
```
|
|
219
219
|
|
|
220
220
|
### useAssistantEvent
|
|
@@ -272,7 +272,7 @@ Each scope provides access to specific state and actions:
|
|
|
272
272
|
- **Part** (`part`): Content part within a message (text, tool calls, etc.)
|
|
273
273
|
- **Composer** (`composer`): Text input for sending or editing messages
|
|
274
274
|
- **Attachment** (`attachment`): File or media attached to a message or composer
|
|
275
|
-
- **
|
|
275
|
+
- **Tools** (`tools`): Tool UI components
|
|
276
276
|
|
|
277
277
|
### Scope Resolution
|
|
278
278
|
|
|
@@ -20,8 +20,8 @@ The following hooks have been removed:
|
|
|
20
20
|
|
|
21
21
|
- `useMessageUtils` → Use `useAssistantState(({ message }) => message.isHovering)` / `useAssistantState(({ message }) => message.isCopied)`
|
|
22
22
|
- `useMessageUtilsStore` → Use `useAssistantApi()` with `api.message().setIsHovering()` / `api.message().setIsCopied()`
|
|
23
|
-
- `useToolUIs` → Use `useAssistantState(({
|
|
24
|
-
- `useToolUIsStore` → Use `useAssistantApi()` with `api.
|
|
23
|
+
- `useToolUIs` → Use `useAssistantState(({ tools }) => tools)` and `useAssistantApi()` with `api.tools()`
|
|
24
|
+
- `useToolUIsStore` → Use `useAssistantApi()` with `api.tools()`
|
|
25
25
|
|
|
26
26
|
**Deprecated Hooks:**
|
|
27
27
|
|
|
@@ -109,6 +109,15 @@ When the hook mounts it calls `list()` on your adapter, hydrates existing thread
|
|
|
109
109
|
async delete(remoteId) {
|
|
110
110
|
await fetch(`/api/threads/${remoteId}`, { method: "DELETE" });
|
|
111
111
|
},
|
|
112
|
+
async fetch(remoteId) {
|
|
113
|
+
const response = await fetch(`/api/threads/${remoteId}`);
|
|
114
|
+
const thread = await response.json();
|
|
115
|
+
return {
|
|
116
|
+
status: thread.is_archived ? "archived" : "regular",
|
|
117
|
+
remoteId: thread.id,
|
|
118
|
+
title: thread.title,
|
|
119
|
+
};
|
|
120
|
+
},
|
|
112
121
|
async generateTitle(remoteId, messages) {
|
|
113
122
|
return createAssistantStream(async (controller) => {
|
|
114
123
|
const response = await fetch(`/api/threads/${remoteId}/title`, {
|
|
@@ -538,7 +538,12 @@ export function MyRuntimeProvider({ children }) {
|
|
|
538
538
|
```
|
|
539
539
|
|
|
540
540
|
<Callout type="info" title="Returning a title from generateTitle">
|
|
541
|
-
The `generateTitle` method must return an <code>AssistantStream</code>
|
|
541
|
+
The `generateTitle` method must return an <code>AssistantStream</code>{" "}
|
|
542
|
+
containing the title text. The easiest, type-safe way is to use{" "}
|
|
543
|
+
<code>createAssistantStream</code> and call{" "}
|
|
544
|
+
<code>controller.appendText(newTitle)</code> followed by{" "}
|
|
545
|
+
<code>controller.close()</code>. Returning a raw <code>ReadableStream</code>{" "}
|
|
546
|
+
won't update the thread list UI.
|
|
542
547
|
</Callout>
|
|
543
548
|
|
|
544
549
|
#### Understanding the Architecture
|
|
@@ -854,9 +859,9 @@ function MyCustomRuntimeProvider({ children }) {
|
|
|
854
859
|
</Callout>
|
|
855
860
|
|
|
856
861
|
<Callout type="warning">
|
|
857
|
-
**`useThreadRuntime` vs `useLocalThreadRuntime`:**
|
|
858
|
-
|
|
859
|
-
|
|
862
|
+
**`useThreadRuntime` vs `useLocalThreadRuntime`:** - `useThreadRuntime` -
|
|
863
|
+
Access the current thread's runtime from within components -
|
|
864
|
+
`useLocalThreadRuntime` - Create a new single-thread runtime instance
|
|
860
865
|
</Callout>
|
|
861
866
|
|
|
862
867
|
## Integration Examples
|
|
@@ -999,6 +1004,74 @@ async run({ messages }) { // ❌ Wrong for streaming
|
|
|
999
1004
|
```
|
|
1000
1005
|
</Callout>
|
|
1001
1006
|
|
|
1007
|
+
### Tool UI Flickers or Disappears During Streaming
|
|
1008
|
+
|
|
1009
|
+
A common issue when implementing a streaming `ChatModelAdapter` is seeing a tool's UI appear for a moment and then disappear. This is caused by failing to accumulate the `tool_calls` correctly across multiple stream chunks. State must be stored **outside** the streaming loop to persist.
|
|
1010
|
+
|
|
1011
|
+
**❌ Incorrect: Forgetting Previous Tool Calls**
|
|
1012
|
+
|
|
1013
|
+
This implementation incorrectly re-creates the `content` array for every chunk. If a later chunk contains only text, tool calls from previous chunks are lost, causing the UI to disappear.
|
|
1014
|
+
|
|
1015
|
+
```tsx
|
|
1016
|
+
// This implementation incorrectly re-creates the `content` array for every chunk.
|
|
1017
|
+
// If a later chunk contains only text, tool calls from previous chunks are lost.
|
|
1018
|
+
async *run({ messages, abortSignal, context }) {
|
|
1019
|
+
const stream = await backendApi({ messages, abortSignal, context });
|
|
1020
|
+
let text = "";
|
|
1021
|
+
|
|
1022
|
+
for await (const chunk of stream) {
|
|
1023
|
+
// ❌ DON'T: This overwrites toolCalls with only the current chunk's data
|
|
1024
|
+
const toolCalls = chunk.tool_calls || [];
|
|
1025
|
+
const content = [{ type: "text", text }];
|
|
1026
|
+
for (const toolCall of toolCalls) {
|
|
1027
|
+
content.push({
|
|
1028
|
+
type: "tool-call",
|
|
1029
|
+
toolName: toolCall.name,
|
|
1030
|
+
toolCallId: toolCall.id,
|
|
1031
|
+
args: toolCall.args,
|
|
1032
|
+
});
|
|
1033
|
+
}
|
|
1034
|
+
yield { content }; // This yield might not contain the tool call anymore
|
|
1035
|
+
}
|
|
1036
|
+
}
|
|
1037
|
+
```
|
|
1038
|
+
|
|
1039
|
+
**✅ Correct: Accumulating State**
|
|
1040
|
+
|
|
1041
|
+
This implementation uses a `Map` outside the loop to remember all tool calls.
|
|
1042
|
+
|
|
1043
|
+
```tsx
|
|
1044
|
+
// This implementation uses a Map outside the loop to remember all tool calls.
|
|
1045
|
+
async *run({ messages, abortSignal, context }) {
|
|
1046
|
+
const stream = await backendApi({ messages, abortSignal, context });
|
|
1047
|
+
let text = "";
|
|
1048
|
+
// ✅ DO: Declare state outside the loop
|
|
1049
|
+
const toolCallsMap = new Map();
|
|
1050
|
+
|
|
1051
|
+
for await (const chunk of stream) {
|
|
1052
|
+
text += chunk.content || "";
|
|
1053
|
+
|
|
1054
|
+
// ✅ DO: Add/update tool calls in the persistent map
|
|
1055
|
+
for (const toolCall of chunk.tool_calls || []) {
|
|
1056
|
+
toolCallsMap.set(toolCall.toolCallId, {
|
|
1057
|
+
type: "tool-call",
|
|
1058
|
+
toolName: toolCall.name,
|
|
1059
|
+
toolCallId: toolCall.toolCallId,
|
|
1060
|
+
args: toolCall.args,
|
|
1061
|
+
});
|
|
1062
|
+
}
|
|
1063
|
+
|
|
1064
|
+
// ✅ DO: Build content from accumulated state
|
|
1065
|
+
const content = [
|
|
1066
|
+
...(text ? [{ type: "text", text }] : []),
|
|
1067
|
+
...Array.from(toolCallsMap.values()),
|
|
1068
|
+
];
|
|
1069
|
+
|
|
1070
|
+
yield { content }; // Yield the complete, correct state every time
|
|
1071
|
+
}
|
|
1072
|
+
}
|
|
1073
|
+
```
|
|
1074
|
+
|
|
1002
1075
|
### Debug Tips
|
|
1003
1076
|
|
|
1004
1077
|
1. **Log adapter calls** to trace execution:
|
|
@@ -136,7 +136,7 @@ export const OPTIONS = () => {
|
|
|
136
136
|
|
|
137
137
|
// ---cut---
|
|
138
138
|
import { Client } from "@langchain/langgraph-sdk";
|
|
139
|
-
import { LangChainMessage } from "@assistant-ui/react-langgraph";
|
|
139
|
+
import { LangChainMessage, LangGraphSendMessageConfig } from "@assistant-ui/react-langgraph";
|
|
140
140
|
|
|
141
141
|
const createClient = () => {
|
|
142
142
|
const apiUrl = process.env["NEXT_PUBLIC_LANGGRAPH_API_URL"] || "/api";
|
|
@@ -160,6 +160,7 @@ export const getThreadState = async (
|
|
|
160
160
|
export const sendMessage = async (params: {
|
|
161
161
|
threadId: string;
|
|
162
162
|
messages: LangChainMessage;
|
|
163
|
+
config?: LangGraphSendMessageConfig;
|
|
163
164
|
}) => {
|
|
164
165
|
const client = createClient();
|
|
165
166
|
return client.runs.stream(
|
|
@@ -170,6 +171,7 @@ export const sendMessage = async (params: {
|
|
|
170
171
|
messages: params.messages,
|
|
171
172
|
},
|
|
172
173
|
streamMode: "messages",
|
|
174
|
+
...params.config
|
|
173
175
|
},
|
|
174
176
|
);
|
|
175
177
|
};
|
|
@@ -195,12 +197,13 @@ import { createThread, getThreadState, sendMessage } from "@/lib/chatApi";
|
|
|
195
197
|
|
|
196
198
|
export function MyAssistant() {
|
|
197
199
|
const runtime = useLangGraphRuntime({
|
|
198
|
-
stream: async (messages, { initialize }) => {
|
|
200
|
+
stream: async (messages, { initialize, config }) => {
|
|
199
201
|
const { externalId } = await initialize();
|
|
200
202
|
if (!externalId) throw new Error("Thread not found");
|
|
201
203
|
return sendMessage({
|
|
202
204
|
threadId: externalId,
|
|
203
205
|
messages,
|
|
206
|
+
config
|
|
204
207
|
});
|
|
205
208
|
},
|
|
206
209
|
create: async () => {
|
|
@@ -306,11 +309,11 @@ The `useLangGraphRuntime` hook now includes built-in thread management capabilit
|
|
|
306
309
|
|
|
307
310
|
```typescript
|
|
308
311
|
const runtime = useLangGraphRuntime({
|
|
309
|
-
stream: async (messages, { initialize }) => {
|
|
312
|
+
stream: async (messages, { initialize, config }) => {
|
|
310
313
|
// initialize() creates or loads a thread and returns its IDs
|
|
311
314
|
const { remoteId, externalId } = await initialize();
|
|
312
315
|
// Use externalId (your backend's thread ID) for API calls
|
|
313
|
-
return sendMessage({ threadId: externalId, messages });
|
|
316
|
+
return sendMessage({ threadId: externalId, messages, config });
|
|
314
317
|
},
|
|
315
318
|
create: async () => {
|
|
316
319
|
// Called when creating a new thread
|
|
@@ -63,10 +63,10 @@ This default route uses the Vercel AI SDK directly with OpenAI. In the following
|
|
|
63
63
|
|
|
64
64
|
### Install Mastra Packages
|
|
65
65
|
|
|
66
|
-
Add the
|
|
66
|
+
Add the `@mastra/core` package and its peer dependency `zod` (which you can use later inside tools for example). Also add `@mastra/ai-sdk` to convert Mastra's stream to an AI SDK-compatible format:
|
|
67
67
|
|
|
68
68
|
```bash npm2yarn
|
|
69
|
-
npm install @mastra/core@latest @mastra/
|
|
69
|
+
npm install @mastra/core@latest @mastra/ai-sdk@latest zod@latest
|
|
70
70
|
```
|
|
71
71
|
|
|
72
72
|
</Step>
|
|
@@ -123,7 +123,6 @@ These files will be used in the next steps to define your Mastra agent and confi
|
|
|
123
123
|
Now, let's define the behavior of our AI agent. Open the `mastra/agents/chefAgent.ts` file and add the following code:
|
|
124
124
|
|
|
125
125
|
```typescript title="mastra/agents/chefAgent.ts"
|
|
126
|
-
import { openai } from "@ai-sdk/openai";
|
|
127
126
|
import { Agent } from "@mastra/core/agent";
|
|
128
127
|
|
|
129
128
|
export const chefAgent = new Agent({
|
|
@@ -131,14 +130,14 @@ export const chefAgent = new Agent({
|
|
|
131
130
|
instructions:
|
|
132
131
|
"You are Michel, a practical and experienced home chef. " +
|
|
133
132
|
"You help people cook with whatever ingredients they have available.",
|
|
134
|
-
model: openai
|
|
133
|
+
model: "openai/gpt-4o-mini",
|
|
135
134
|
});
|
|
136
135
|
```
|
|
137
136
|
|
|
138
137
|
This code creates a new Mastra `Agent` named `chef-agent`.
|
|
139
138
|
|
|
140
139
|
- `instructions`: Defines the agent's persona and primary goal.
|
|
141
|
-
- `model`: Specifies the language model the agent will use (in this case, OpenAI's GPT-4o Mini via
|
|
140
|
+
- `model`: Specifies the language model the agent will use (in this case, OpenAI's GPT-4o Mini via Mastra's model router).
|
|
142
141
|
|
|
143
142
|
Make sure you have set up your OpenAI API key as described in the [Getting Started guide](/docs/getting-started).
|
|
144
143
|
|
|
@@ -151,7 +150,6 @@ Next, register the agent with your Mastra instance. Open the `mastra/index.ts` f
|
|
|
151
150
|
|
|
152
151
|
```typescript title="mastra/index.ts"
|
|
153
152
|
import { Mastra } from "@mastra/core";
|
|
154
|
-
|
|
155
153
|
import { chefAgent } from "./agents/chefAgent";
|
|
156
154
|
|
|
157
155
|
export const mastra = new Mastra({
|
|
@@ -169,6 +167,8 @@ This code initializes Mastra and makes the `chefAgent` available for use in your
|
|
|
169
167
|
Now, update your API route (`app/api/chat/route.ts`) to use the Mastra agent you just configured. Replace the existing content with the following:
|
|
170
168
|
|
|
171
169
|
```typescript title="app/api/chat/route.ts"
|
|
170
|
+
import { createUIMessageStreamResponse } from "ai";
|
|
171
|
+
import { toAISdkFormat } from "@mastra/ai-sdk";
|
|
172
172
|
import { mastra } from "@/mastra"; // Adjust the import path if necessary
|
|
173
173
|
|
|
174
174
|
// Allow streaming responses up to 30 seconds
|
|
@@ -182,10 +182,12 @@ export async function POST(req: Request) {
|
|
|
182
182
|
const agent = mastra.getAgent("chefAgent");
|
|
183
183
|
|
|
184
184
|
// Stream the response using the agent
|
|
185
|
-
const
|
|
185
|
+
const stream = await agent.stream(messages);
|
|
186
186
|
|
|
187
|
-
//
|
|
188
|
-
return
|
|
187
|
+
// Create a Response that streams the UI message stream to the client
|
|
188
|
+
return createUIMessageStreamResponse({
|
|
189
|
+
stream: toAISdkFormat(stream, { from: "agent" }),
|
|
190
|
+
});
|
|
189
191
|
}
|
|
190
192
|
```
|
|
191
193
|
|
|
@@ -194,7 +196,7 @@ Key changes:
|
|
|
194
196
|
- We import the `mastra` instance created in `mastra/index.ts`. Make sure the import path (`@/mastra`) is correct for your project setup (you might need `~/mastra`, `../../../mastra`, etc., depending on your path aliases and project structure).
|
|
195
197
|
- We retrieve the `chefAgent` using `mastra.getAgent("chefAgent")`.
|
|
196
198
|
- Instead of calling the AI SDK's `streamText` directly, we call `agent.stream(messages)` to process the chat messages using the agent's configuration and model.
|
|
197
|
-
- The result is still returned in a format compatible with assistant-ui using `
|
|
199
|
+
- The result is still returned in a format compatible with assistant-ui using `createUIMessageStreamResponse()` and `toAISdkFormat()`.
|
|
198
200
|
|
|
199
201
|
Your API route is now powered by Mastra!
|
|
200
202
|
|