@assistant-ui/react-ai-sdk 0.9.7 → 0.10.2
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/dist/index.d.ts +5 -56
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -441
- package/dist/index.js.map +1 -1
- package/dist/rsc/RSCDisplay.d.ts +3 -0
- package/dist/rsc/RSCDisplay.d.ts.map +1 -0
- package/dist/rsc/RSCDisplay.js +24 -0
- package/dist/rsc/RSCDisplay.js.map +1 -0
- package/dist/rsc/VercelRSCAdapter.d.ts +18 -0
- package/dist/rsc/VercelRSCAdapter.d.ts.map +1 -0
- package/dist/rsc/VercelRSCAdapter.js +2 -0
- package/dist/rsc/VercelRSCAdapter.js.map +1 -0
- package/dist/rsc/VercelRSCMessage.d.ts +8 -0
- package/dist/rsc/VercelRSCMessage.d.ts.map +1 -0
- package/dist/rsc/VercelRSCMessage.js +2 -0
- package/dist/rsc/VercelRSCMessage.js.map +1 -0
- package/dist/rsc/getVercelRSCMessage.d.ts +7 -0
- package/dist/rsc/getVercelRSCMessage.d.ts.map +1 -0
- package/dist/rsc/getVercelRSCMessage.js +10 -0
- package/dist/rsc/getVercelRSCMessage.js.map +1 -0
- package/dist/rsc/index.d.ts +6 -0
- package/dist/rsc/index.d.ts.map +1 -0
- package/dist/rsc/index.js +9 -0
- package/dist/rsc/index.js.map +1 -0
- package/dist/rsc/useVercelRSCRuntime.d.ts +3 -0
- package/dist/rsc/useVercelRSCRuntime.d.ts.map +1 -0
- package/dist/rsc/useVercelRSCRuntime.js +55 -0
- package/dist/rsc/useVercelRSCRuntime.js.map +1 -0
- package/dist/rsc/utils/RSCThreadExtras.d.ts +8 -0
- package/dist/rsc/utils/RSCThreadExtras.d.ts.map +1 -0
- package/dist/rsc/utils/RSCThreadExtras.js +6 -0
- package/dist/rsc/utils/RSCThreadExtras.js.map +1 -0
- package/dist/ui/getVercelAIMessages.d.ts +4 -0
- package/dist/ui/getVercelAIMessages.d.ts.map +1 -0
- package/dist/ui/getVercelAIMessages.js +10 -0
- package/dist/ui/getVercelAIMessages.js.map +1 -0
- package/dist/ui/index.d.ts +5 -0
- package/dist/ui/index.d.ts.map +1 -0
- package/dist/ui/index.js +11 -0
- package/dist/ui/index.js.map +1 -0
- package/dist/ui/use-assistant/useVercelUseAssistantRuntime.d.ts +7 -0
- package/dist/ui/use-assistant/useVercelUseAssistantRuntime.d.ts.map +1 -0
- package/dist/ui/use-assistant/useVercelUseAssistantRuntime.js +45 -0
- package/dist/ui/use-assistant/useVercelUseAssistantRuntime.js.map +1 -0
- package/dist/ui/use-chat/useVercelUseChatRuntime.d.ts +8 -0
- package/dist/ui/use-chat/useVercelUseChatRuntime.d.ts.map +1 -0
- package/dist/ui/use-chat/useVercelUseChatRuntime.js +72 -0
- package/dist/ui/use-chat/useVercelUseChatRuntime.js.map +1 -0
- package/dist/ui/utils/convertMessage.d.ts +14 -0
- package/dist/ui/utils/convertMessage.d.ts.map +1 -0
- package/dist/ui/utils/convertMessage.js +117 -0
- package/dist/ui/utils/convertMessage.js.map +1 -0
- package/dist/ui/utils/sliceMessagesUntil.d.ts +3 -0
- package/dist/ui/utils/sliceMessagesUntil.d.ts.map +1 -0
- package/dist/ui/utils/sliceMessagesUntil.js +16 -0
- package/dist/ui/utils/sliceMessagesUntil.js.map +1 -0
- package/dist/ui/utils/toCreateMessage.d.ts +4 -0
- package/dist/ui/utils/toCreateMessage.d.ts.map +1 -0
- package/dist/ui/utils/toCreateMessage.js +32 -0
- package/dist/ui/utils/toCreateMessage.js.map +1 -0
- package/dist/ui/utils/useInputSync.d.ts +6 -0
- package/dist/ui/utils/useInputSync.d.ts.map +1 -0
- package/dist/ui/utils/useInputSync.js +15 -0
- package/dist/ui/utils/useInputSync.js.map +1 -0
- package/dist/ui/utils/vercelAttachmentAdapter.d.ts +3 -0
- package/dist/ui/utils/vercelAttachmentAdapter.d.ts.map +1 -0
- package/dist/ui/utils/vercelAttachmentAdapter.js +28 -0
- package/dist/ui/utils/vercelAttachmentAdapter.js.map +1 -0
- package/dist/useChatRuntime.d.ts +5 -0
- package/dist/useChatRuntime.d.ts.map +1 -0
- package/dist/useChatRuntime.js +11 -0
- package/dist/useChatRuntime.js.map +1 -0
- package/package.json +15 -18
- package/src/index.ts +11 -0
- package/src/rsc/RSCDisplay.tsx +23 -0
- package/src/rsc/VercelRSCAdapter.tsx +23 -0
- package/src/rsc/VercelRSCMessage.tsx +9 -0
- package/src/rsc/getVercelRSCMessage.tsx +12 -0
- package/src/rsc/index.ts +5 -0
- package/src/rsc/useVercelRSCRuntime.tsx +70 -0
- package/src/rsc/utils/RSCThreadExtras.tsx +11 -0
- package/src/ui/getVercelAIMessages.tsx +9 -0
- package/src/ui/index.ts +4 -0
- package/src/ui/use-assistant/useVercelUseAssistantRuntime.tsx +58 -0
- package/src/ui/use-chat/useVercelUseChatRuntime.tsx +91 -0
- package/src/ui/utils/convertMessage.ts +158 -0
- package/src/ui/utils/sliceMessagesUntil.tsx +20 -0
- package/src/ui/utils/toCreateMessage.ts +44 -0
- package/src/ui/utils/useInputSync.tsx +24 -0
- package/src/ui/utils/vercelAttachmentAdapter.ts +29 -0
- package/src/useChatRuntime.ts +10 -0
- package/dist/index.d.mts +0 -56
- package/dist/index.mjs +0 -431
- package/dist/index.mjs.map +0 -1
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { useAssistant, useChat } from "@ai-sdk/react";
|
|
2
|
+
import { AssistantRuntime } from "@assistant-ui/react";
|
|
3
|
+
type VercelHelpers = ReturnType<typeof useChat> | ReturnType<typeof useAssistant>;
|
|
4
|
+
export declare const useInputSync: ({ setInput, input }: VercelHelpers, runtime: AssistantRuntime) => void;
|
|
5
|
+
export {};
|
|
6
|
+
//# sourceMappingURL=useInputSync.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useInputSync.d.ts","sourceRoot":"","sources":["../../../src/ui/utils/useInputSync.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAEvD,KAAK,aAAa,GACd,UAAU,CAAC,OAAO,OAAO,CAAC,GAC1B,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC;AAEpC,eAAO,MAAM,YAAY,GACvB,qBAAqB,aAAa,EAClC,SAAS,gBAAgB,SAa1B,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { useEffect } from "react";
|
|
2
|
+
const useInputSync = ({ setInput, input }, runtime) => {
|
|
3
|
+
useEffect(() => {
|
|
4
|
+
runtime.thread.composer.setText(input);
|
|
5
|
+
}, [runtime, input]);
|
|
6
|
+
useEffect(() => {
|
|
7
|
+
return runtime.thread.composer.subscribe(() => {
|
|
8
|
+
setInput(runtime.thread.composer.getState().text);
|
|
9
|
+
});
|
|
10
|
+
}, [runtime, setInput]);
|
|
11
|
+
};
|
|
12
|
+
export {
|
|
13
|
+
useInputSync
|
|
14
|
+
};
|
|
15
|
+
//# sourceMappingURL=useInputSync.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/ui/utils/useInputSync.tsx"],"sourcesContent":["import { useEffect } from \"react\";\nimport { useAssistant, useChat } from \"@ai-sdk/react\";\nimport { AssistantRuntime } from \"@assistant-ui/react\";\n\ntype VercelHelpers =\n | ReturnType<typeof useChat>\n | ReturnType<typeof useAssistant>;\n\nexport const useInputSync = (\n { setInput, input }: VercelHelpers,\n runtime: AssistantRuntime,\n) => {\n // sync input from vercel to assistant-ui\n useEffect(() => {\n runtime.thread.composer.setText(input);\n }, [runtime, input]);\n\n // sync input from assistant-ui to vercel\n useEffect(() => {\n return runtime.thread.composer.subscribe(() => {\n setInput(runtime.thread.composer.getState().text);\n });\n }, [runtime, setInput]);\n};\n"],"mappings":"AAAA,SAAS,iBAAiB;AAQnB,MAAM,eAAe,CAC1B,EAAE,UAAU,MAAM,GAClB,YACG;AAEH,YAAU,MAAM;AACd,YAAQ,OAAO,SAAS,QAAQ,KAAK;AAAA,EACvC,GAAG,CAAC,SAAS,KAAK,CAAC;AAGnB,YAAU,MAAM;AACd,WAAO,QAAQ,OAAO,SAAS,UAAU,MAAM;AAC7C,eAAS,QAAQ,OAAO,SAAS,SAAS,EAAE,IAAI;AAAA,IAClD,CAAC;AAAA,EACH,GAAG,CAAC,SAAS,QAAQ,CAAC;AACxB;","names":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vercelAttachmentAdapter.d.ts","sourceRoot":"","sources":["../../../src/ui/utils/vercelAttachmentAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAGxD,eAAO,MAAM,uBAAuB,EAAE,iBAyBrC,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { generateId } from "@ai-sdk/ui-utils";
|
|
2
|
+
const vercelAttachmentAdapter = {
|
|
3
|
+
accept: "image/*, text/plain, text/html, text/markdown, text/csv, text/xml, text/json, text/css",
|
|
4
|
+
async add({ file }) {
|
|
5
|
+
return {
|
|
6
|
+
id: generateId(),
|
|
7
|
+
type: "file",
|
|
8
|
+
name: file.name,
|
|
9
|
+
file,
|
|
10
|
+
contentType: file.type,
|
|
11
|
+
content: [],
|
|
12
|
+
status: { type: "requires-action", reason: "composer-send" }
|
|
13
|
+
};
|
|
14
|
+
},
|
|
15
|
+
async send(attachment) {
|
|
16
|
+
return {
|
|
17
|
+
...attachment,
|
|
18
|
+
status: { type: "complete" },
|
|
19
|
+
content: []
|
|
20
|
+
};
|
|
21
|
+
},
|
|
22
|
+
async remove() {
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
export {
|
|
26
|
+
vercelAttachmentAdapter
|
|
27
|
+
};
|
|
28
|
+
//# sourceMappingURL=vercelAttachmentAdapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/ui/utils/vercelAttachmentAdapter.ts"],"sourcesContent":["import { AttachmentAdapter } from \"@assistant-ui/react\";\nimport { generateId } from \"@ai-sdk/ui-utils\";\n\nexport const vercelAttachmentAdapter: AttachmentAdapter = {\n accept:\n \"image/*, text/plain, text/html, text/markdown, text/csv, text/xml, text/json, text/css\",\n async add({ file }) {\n return {\n id: generateId(),\n type: \"file\",\n name: file.name,\n file,\n contentType: file.type,\n content: [],\n status: { type: \"requires-action\", reason: \"composer-send\" },\n };\n },\n async send(attachment) {\n // noop\n return {\n ...attachment,\n status: { type: \"complete\" },\n content: [],\n };\n },\n async remove() {\n // noop\n },\n};\n"],"mappings":"AACA,SAAS,kBAAkB;AAEpB,MAAM,0BAA6C;AAAA,EACxD,QACE;AAAA,EACF,MAAM,IAAI,EAAE,KAAK,GAAG;AAClB,WAAO;AAAA,MACL,IAAI,WAAW;AAAA,MACf,MAAM;AAAA,MACN,MAAM,KAAK;AAAA,MACX;AAAA,MACA,aAAa,KAAK;AAAA,MAClB,SAAS,CAAC;AAAA,MACV,QAAQ,EAAE,MAAM,mBAAmB,QAAQ,gBAAgB;AAAA,IAC7D;AAAA,EACF;AAAA,EACA,MAAM,KAAK,YAAY;AAErB,WAAO;AAAA,MACL,GAAG;AAAA,MACH,QAAQ,EAAE,MAAM,WAAW;AAAA,MAC3B,SAAS,CAAC;AAAA,IACZ;AAAA,EACF;AAAA,EACA,MAAM,SAAS;AAAA,EAEf;AACF;","names":[]}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { EdgeRuntimeOptions } from "@assistant-ui/react-edge";
|
|
2
|
+
type UseChatRuntimeOptions = Omit<EdgeRuntimeOptions, "unstable_AISDKInterop">;
|
|
3
|
+
export declare const useChatRuntime: (options: UseChatRuntimeOptions) => import("@assistant-ui/react").AssistantRuntime;
|
|
4
|
+
export {};
|
|
5
|
+
//# sourceMappingURL=useChatRuntime.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useChatRuntime.d.ts","sourceRoot":"","sources":["../src/useChatRuntime.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAkB,MAAM,0BAA0B,CAAC;AAE9E,KAAK,qBAAqB,GAAG,IAAI,CAAC,kBAAkB,EAAE,uBAAuB,CAAC,CAAC;AAE/E,eAAO,MAAM,cAAc,GAAI,SAAS,qBAAqB,mDAK5D,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { useEdgeRuntime } from "@assistant-ui/react-edge";
|
|
2
|
+
const useChatRuntime = (options) => {
|
|
3
|
+
return useEdgeRuntime({
|
|
4
|
+
...options,
|
|
5
|
+
unstable_AISDKInterop: "v2"
|
|
6
|
+
});
|
|
7
|
+
};
|
|
8
|
+
export {
|
|
9
|
+
useChatRuntime
|
|
10
|
+
};
|
|
11
|
+
//# sourceMappingURL=useChatRuntime.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/useChatRuntime.ts"],"sourcesContent":["import { EdgeRuntimeOptions, useEdgeRuntime } from \"@assistant-ui/react-edge\";\n\ntype UseChatRuntimeOptions = Omit<EdgeRuntimeOptions, \"unstable_AISDKInterop\">;\n\nexport const useChatRuntime = (options: UseChatRuntimeOptions) => {\n return useEdgeRuntime({\n ...options,\n unstable_AISDKInterop: \"v2\",\n });\n};\n"],"mappings":"AAAA,SAA6B,sBAAsB;AAI5C,MAAM,iBAAiB,CAAC,YAAmC;AAChE,SAAO,eAAe;AAAA,IACpB,GAAG;AAAA,IACH,uBAAuB;AAAA,EACzB,CAAC;AACH;","names":[]}
|
package/package.json
CHANGED
|
@@ -1,25 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@assistant-ui/react-ai-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.2",
|
|
4
4
|
"license": "MIT",
|
|
5
|
+
"type": "module",
|
|
5
6
|
"exports": {
|
|
6
7
|
".": {
|
|
7
|
-
"
|
|
8
|
-
|
|
9
|
-
"default": "./dist/index.mjs"
|
|
10
|
-
},
|
|
11
|
-
"require": {
|
|
12
|
-
"types": "./dist/index.d.ts",
|
|
13
|
-
"default": "./dist/index.js"
|
|
14
|
-
}
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"default": "./dist/index.js"
|
|
15
10
|
}
|
|
16
11
|
},
|
|
17
|
-
"source": "./src/index.ts",
|
|
18
12
|
"main": "./dist/index.js",
|
|
19
|
-
"module": "./dist/index.mjs",
|
|
20
13
|
"types": "./dist/index.d.ts",
|
|
21
14
|
"files": [
|
|
22
15
|
"dist",
|
|
16
|
+
"src",
|
|
23
17
|
"README.md"
|
|
24
18
|
],
|
|
25
19
|
"sideEffects": false,
|
|
@@ -29,10 +23,10 @@
|
|
|
29
23
|
"@radix-ui/react-use-callback-ref": "^1.1.1",
|
|
30
24
|
"zod": "^3.24.3",
|
|
31
25
|
"zustand": "^5.0.3",
|
|
32
|
-
"@assistant-ui/react-edge": "0.1
|
|
26
|
+
"@assistant-ui/react-edge": "0.2.1"
|
|
33
27
|
},
|
|
34
28
|
"peerDependencies": {
|
|
35
|
-
"@assistant-ui/react": "^0.
|
|
29
|
+
"@assistant-ui/react": "^0.10.1",
|
|
36
30
|
"@types/react": "*",
|
|
37
31
|
"react": "^18 || ^19 || ^19.0.0-rc"
|
|
38
32
|
},
|
|
@@ -42,24 +36,27 @@
|
|
|
42
36
|
}
|
|
43
37
|
},
|
|
44
38
|
"devDependencies": {
|
|
39
|
+
"@types/node": "^22.14.1",
|
|
40
|
+
"@types/react": "^19.1.2",
|
|
41
|
+
"eslint": "^9",
|
|
45
42
|
"eslint-config-next": "15.3.1",
|
|
46
|
-
"
|
|
47
|
-
"
|
|
43
|
+
"react": "^19.1.0",
|
|
44
|
+
"tsx": "^4.19.3",
|
|
45
|
+
"@assistant-ui/tsbuildutils": "0.0.1",
|
|
48
46
|
"@assistant-ui/tsconfig": "0.0.0"
|
|
49
47
|
},
|
|
50
48
|
"publishConfig": {
|
|
51
49
|
"access": "public",
|
|
52
50
|
"provenance": true
|
|
53
51
|
},
|
|
54
|
-
"homepage": "https://www.assistant-ui.com/",
|
|
55
52
|
"repository": {
|
|
56
53
|
"type": "git",
|
|
57
|
-
"url": "
|
|
54
|
+
"url": "https://github.com/assistant-ui/assistant-ui/tree/main/packages/react-ai-sdk"
|
|
58
55
|
},
|
|
59
56
|
"bugs": {
|
|
60
57
|
"url": "https://github.com/assistant-ui/assistant-ui/issues"
|
|
61
58
|
},
|
|
62
59
|
"scripts": {
|
|
63
|
-
"build": "
|
|
60
|
+
"build": "tsx scripts/build.mts"
|
|
64
61
|
}
|
|
65
62
|
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export * from "./rsc";
|
|
2
|
+
export * from "./ui";
|
|
3
|
+
export * from "./useChatRuntime";
|
|
4
|
+
|
|
5
|
+
export {
|
|
6
|
+
toLanguageModelMessages,
|
|
7
|
+
toLanguageModelTools,
|
|
8
|
+
fromLanguageModelMessages,
|
|
9
|
+
fromLanguageModelTools,
|
|
10
|
+
useDangerousInBrowserRuntime,
|
|
11
|
+
} from "@assistant-ui/react-edge";
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import {
|
|
3
|
+
useThread,
|
|
4
|
+
useMessage,
|
|
5
|
+
getExternalStoreMessage,
|
|
6
|
+
} from "@assistant-ui/react";
|
|
7
|
+
import {
|
|
8
|
+
RSCThreadExtras,
|
|
9
|
+
symbolInternalRSCExtras,
|
|
10
|
+
} from "./utils/RSCThreadExtras";
|
|
11
|
+
import { FC } from "react";
|
|
12
|
+
|
|
13
|
+
export const RSCDisplay: FC = () => {
|
|
14
|
+
const convertFn = useThread((t) => {
|
|
15
|
+
const extras = (t.extras as RSCThreadExtras)?.[symbolInternalRSCExtras];
|
|
16
|
+
if (!extras)
|
|
17
|
+
throw new Error(
|
|
18
|
+
"This function can only be used inside a Vercel RSC runtime.",
|
|
19
|
+
);
|
|
20
|
+
return extras.convertFn;
|
|
21
|
+
});
|
|
22
|
+
return useMessage((m) => convertFn(getExternalStoreMessage(m)).display);
|
|
23
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import type { AppendMessage } from "@assistant-ui/react";
|
|
3
|
+
import type { VercelRSCMessage } from "./VercelRSCMessage";
|
|
4
|
+
import { ExternalStoreAdapter } from "@assistant-ui/react";
|
|
5
|
+
|
|
6
|
+
type RSCMessageConverter<T> = {
|
|
7
|
+
convertMessage: (message: T) => VercelRSCMessage;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
type VercelRSCAdapterBase<T> = {
|
|
11
|
+
isRunning?: boolean | undefined;
|
|
12
|
+
messages: T[];
|
|
13
|
+
|
|
14
|
+
onNew?: (message: AppendMessage) => Promise<void>;
|
|
15
|
+
onEdit?: ((message: AppendMessage) => Promise<void>) | undefined;
|
|
16
|
+
onReload?: ((parentId: string | null) => Promise<void>) | undefined;
|
|
17
|
+
convertMessage?: ((message: T) => VercelRSCMessage) | undefined;
|
|
18
|
+
|
|
19
|
+
adapters?: ExternalStoreAdapter["adapters"] | undefined;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export type VercelRSCAdapter<T = VercelRSCMessage> = VercelRSCAdapterBase<T> &
|
|
23
|
+
(T extends VercelRSCMessage ? object : RSCMessageConverter<T>);
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getExternalStoreMessage,
|
|
3
|
+
type ThreadMessage,
|
|
4
|
+
} from "@assistant-ui/react";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @deprecated Use `getExternalStoreMessage` instead. This method was specific to Vercel RSC
|
|
8
|
+
* implementation and has been replaced by a more generic external store message handler.
|
|
9
|
+
*/
|
|
10
|
+
export const getVercelRSCMessage = (message: ThreadMessage) => {
|
|
11
|
+
return getExternalStoreMessage(message);
|
|
12
|
+
};
|
package/src/rsc/index.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { useVercelRSCRuntime } from "./useVercelRSCRuntime";
|
|
2
|
+
export { getVercelRSCMessage } from "./getVercelRSCMessage";
|
|
3
|
+
export type { VercelRSCAdapter } from "./VercelRSCAdapter";
|
|
4
|
+
export type { VercelRSCMessage } from "./VercelRSCMessage";
|
|
5
|
+
export { RSCDisplay } from "./RSCDisplay";
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import type { VercelRSCAdapter } from "./VercelRSCAdapter";
|
|
4
|
+
import {
|
|
5
|
+
ExternalStoreAdapter,
|
|
6
|
+
ThreadMessageLike,
|
|
7
|
+
useExternalMessageConverter,
|
|
8
|
+
useExternalStoreRuntime,
|
|
9
|
+
} from "@assistant-ui/react";
|
|
10
|
+
import { VercelRSCMessage } from "./VercelRSCMessage";
|
|
11
|
+
import { useCallback, useMemo } from "react";
|
|
12
|
+
import { symbolInternalRSCExtras } from "./utils/RSCThreadExtras";
|
|
13
|
+
|
|
14
|
+
const vercelToThreadMessage = <T,>(
|
|
15
|
+
converter: (message: T) => VercelRSCMessage,
|
|
16
|
+
rawMessage: T,
|
|
17
|
+
): ThreadMessageLike => {
|
|
18
|
+
const message = converter(rawMessage);
|
|
19
|
+
|
|
20
|
+
return {
|
|
21
|
+
id: message.id,
|
|
22
|
+
role: message.role,
|
|
23
|
+
content: [{ type: "text", text: "[Developer: Please set up RSCDisplay]" }],
|
|
24
|
+
createdAt: message.createdAt,
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export const useVercelRSCRuntime = <T extends WeakKey>(
|
|
29
|
+
adapter: VercelRSCAdapter<T>,
|
|
30
|
+
) => {
|
|
31
|
+
const onNew = adapter.onNew;
|
|
32
|
+
if (!onNew)
|
|
33
|
+
throw new Error("You must pass a onNew function to useVercelRSCRuntime");
|
|
34
|
+
|
|
35
|
+
const convertFn = useMemo(() => {
|
|
36
|
+
return (
|
|
37
|
+
adapter.convertMessage?.bind(adapter) ?? ((m: T) => m as VercelRSCMessage)
|
|
38
|
+
);
|
|
39
|
+
}, [adapter.convertMessage, adapter]);
|
|
40
|
+
const callback = useCallback(
|
|
41
|
+
(m: T) => {
|
|
42
|
+
return vercelToThreadMessage(convertFn, m);
|
|
43
|
+
},
|
|
44
|
+
[convertFn],
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
const messages = useExternalMessageConverter({
|
|
48
|
+
callback,
|
|
49
|
+
isRunning: adapter.isRunning ?? false,
|
|
50
|
+
messages: adapter.messages,
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
const eAdapter: ExternalStoreAdapter = {
|
|
54
|
+
isRunning: adapter.isRunning,
|
|
55
|
+
messages,
|
|
56
|
+
onNew,
|
|
57
|
+
onEdit: adapter.onEdit,
|
|
58
|
+
onReload: adapter.onReload,
|
|
59
|
+
adapters: adapter.adapters,
|
|
60
|
+
unstable_capabilities: {
|
|
61
|
+
copy: false,
|
|
62
|
+
},
|
|
63
|
+
extras: {
|
|
64
|
+
[symbolInternalRSCExtras]: { convertFn },
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
const runtime = useExternalStoreRuntime(eAdapter);
|
|
69
|
+
return runtime;
|
|
70
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { VercelRSCMessage } from "../VercelRSCMessage";
|
|
3
|
+
|
|
4
|
+
export const symbolInternalRSCExtras = Symbol("internal-rsc-extras");
|
|
5
|
+
export type RSCThreadExtras =
|
|
6
|
+
| {
|
|
7
|
+
[symbolInternalRSCExtras]?: {
|
|
8
|
+
convertFn: (message: any) => VercelRSCMessage;
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
| undefined;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getExternalStoreMessage,
|
|
3
|
+
type ThreadMessage,
|
|
4
|
+
} from "@assistant-ui/react";
|
|
5
|
+
import type { Message } from "@ai-sdk/ui-utils";
|
|
6
|
+
|
|
7
|
+
export const getVercelAIMessages = (message: ThreadMessage) => {
|
|
8
|
+
return getExternalStoreMessage(message) as Message[];
|
|
9
|
+
};
|
package/src/ui/index.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { useVercelUseChatRuntime } from "./use-chat/useVercelUseChatRuntime";
|
|
2
|
+
export { useVercelUseAssistantRuntime } from "./use-assistant/useVercelUseAssistantRuntime";
|
|
3
|
+
export { getVercelAIMessages } from "./getVercelAIMessages";
|
|
4
|
+
export { AISDKMessageConverter } from "./utils/convertMessage";
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { useAssistant } from "@ai-sdk/react";
|
|
2
|
+
import { useExternalStoreRuntime } from "@assistant-ui/react";
|
|
3
|
+
import { useInputSync } from "../utils/useInputSync";
|
|
4
|
+
import { toCreateMessage } from "../utils/toCreateMessage";
|
|
5
|
+
import { vercelAttachmentAdapter } from "../utils/vercelAttachmentAdapter";
|
|
6
|
+
import { ExternalStoreAdapter } from "@assistant-ui/react";
|
|
7
|
+
import { AISDKMessageConverter } from "../utils/convertMessage";
|
|
8
|
+
|
|
9
|
+
export type VercelUseChatAdapter = {
|
|
10
|
+
adapters?:
|
|
11
|
+
| Omit<NonNullable<ExternalStoreAdapter["adapters"]>, "attachments">
|
|
12
|
+
| undefined;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export const useVercelUseAssistantRuntime = (
|
|
16
|
+
assistantHelpers: ReturnType<typeof useAssistant>,
|
|
17
|
+
adapter: VercelUseChatAdapter = {},
|
|
18
|
+
) => {
|
|
19
|
+
const messages = AISDKMessageConverter.useThreadMessages({
|
|
20
|
+
messages: assistantHelpers.messages,
|
|
21
|
+
isRunning: assistantHelpers.status === "in_progress",
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
const runtime = useExternalStoreRuntime({
|
|
25
|
+
isRunning: assistantHelpers.status === "in_progress",
|
|
26
|
+
messages,
|
|
27
|
+
onCancel: async () => assistantHelpers.stop(),
|
|
28
|
+
onNew: async (message) => {
|
|
29
|
+
await assistantHelpers.append(await toCreateMessage(message));
|
|
30
|
+
},
|
|
31
|
+
adapters: {
|
|
32
|
+
attachments: vercelAttachmentAdapter,
|
|
33
|
+
...adapter.adapters,
|
|
34
|
+
threadList: new Proxy(adapter.adapters?.threadList ?? {}, {
|
|
35
|
+
get(target, prop, receiver) {
|
|
36
|
+
if (prop === "onSwitchToNewThread") {
|
|
37
|
+
return () => {
|
|
38
|
+
assistantHelpers.messages = [];
|
|
39
|
+
assistantHelpers.input = "";
|
|
40
|
+
assistantHelpers.setMessages([]);
|
|
41
|
+
assistantHelpers.setInput("");
|
|
42
|
+
|
|
43
|
+
if (typeof target.onSwitchToNewThread === "function") {
|
|
44
|
+
return target.onSwitchToNewThread.call(target);
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return Reflect.get(target, prop, receiver);
|
|
50
|
+
},
|
|
51
|
+
}),
|
|
52
|
+
},
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
useInputSync(assistantHelpers, runtime);
|
|
56
|
+
|
|
57
|
+
return runtime;
|
|
58
|
+
};
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import type { useChat } from "@ai-sdk/react";
|
|
2
|
+
import { useExternalStoreRuntime } from "@assistant-ui/react";
|
|
3
|
+
import { useInputSync } from "../utils/useInputSync";
|
|
4
|
+
import { sliceMessagesUntil } from "../utils/sliceMessagesUntil";
|
|
5
|
+
import { toCreateMessage } from "../utils/toCreateMessage";
|
|
6
|
+
import { vercelAttachmentAdapter } from "../utils/vercelAttachmentAdapter";
|
|
7
|
+
import { getVercelAIMessages } from "../getVercelAIMessages";
|
|
8
|
+
import { ExternalStoreAdapter } from "@assistant-ui/react";
|
|
9
|
+
import { useState } from "react";
|
|
10
|
+
import { generateId } from "@ai-sdk/ui-utils";
|
|
11
|
+
import { AISDKMessageConverter } from "../utils/convertMessage";
|
|
12
|
+
|
|
13
|
+
export type VercelUseChatAdapter = {
|
|
14
|
+
adapters?:
|
|
15
|
+
| Omit<NonNullable<ExternalStoreAdapter["adapters"]>, "attachments">
|
|
16
|
+
| undefined;
|
|
17
|
+
unstable_joinStrategy?: "concat-content" | "none";
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export const useVercelUseChatRuntime = (
|
|
21
|
+
chatHelpers: ReturnType<typeof useChat>,
|
|
22
|
+
adapter: VercelUseChatAdapter = {},
|
|
23
|
+
) => {
|
|
24
|
+
const messages = AISDKMessageConverter.useThreadMessages({
|
|
25
|
+
isRunning:
|
|
26
|
+
chatHelpers.status === "submitted" || chatHelpers.status == "streaming",
|
|
27
|
+
messages: chatHelpers.messages,
|
|
28
|
+
joinStrategy: adapter.unstable_joinStrategy,
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
const [threadId, setThreadId] = useState<string>(generateId());
|
|
32
|
+
|
|
33
|
+
const runtime = useExternalStoreRuntime({
|
|
34
|
+
isRunning: chatHelpers.isLoading,
|
|
35
|
+
messages,
|
|
36
|
+
setMessages: (messages) =>
|
|
37
|
+
chatHelpers.setMessages(messages.map(getVercelAIMessages).flat()),
|
|
38
|
+
onCancel: async () => chatHelpers.stop(),
|
|
39
|
+
onNew: async (message) => {
|
|
40
|
+
await chatHelpers.append(await toCreateMessage(message));
|
|
41
|
+
},
|
|
42
|
+
onEdit: async (message) => {
|
|
43
|
+
const newMessages = sliceMessagesUntil(
|
|
44
|
+
chatHelpers.messages,
|
|
45
|
+
message.parentId,
|
|
46
|
+
);
|
|
47
|
+
chatHelpers.setMessages(newMessages);
|
|
48
|
+
|
|
49
|
+
await chatHelpers.append(await toCreateMessage(message));
|
|
50
|
+
},
|
|
51
|
+
onReload: async (parentId: string | null) => {
|
|
52
|
+
const newMessages = sliceMessagesUntil(chatHelpers.messages, parentId);
|
|
53
|
+
chatHelpers.setMessages(newMessages);
|
|
54
|
+
|
|
55
|
+
await chatHelpers.reload();
|
|
56
|
+
},
|
|
57
|
+
onAddToolResult: ({ toolCallId, result }) => {
|
|
58
|
+
chatHelpers.addToolResult({ toolCallId, result });
|
|
59
|
+
},
|
|
60
|
+
adapters: {
|
|
61
|
+
attachments: vercelAttachmentAdapter,
|
|
62
|
+
...adapter.adapters,
|
|
63
|
+
threadList: new Proxy(adapter.adapters?.threadList ?? {}, {
|
|
64
|
+
get(target, prop, receiver) {
|
|
65
|
+
if (prop === "threadId") {
|
|
66
|
+
return target.threadId ?? threadId;
|
|
67
|
+
}
|
|
68
|
+
if (prop === "onSwitchToNewThread") {
|
|
69
|
+
return () => {
|
|
70
|
+
chatHelpers.messages = [];
|
|
71
|
+
chatHelpers.input = "";
|
|
72
|
+
chatHelpers.setMessages([]);
|
|
73
|
+
chatHelpers.setInput("");
|
|
74
|
+
setThreadId(generateId());
|
|
75
|
+
|
|
76
|
+
if (typeof target.onSwitchToNewThread === "function") {
|
|
77
|
+
return target.onSwitchToNewThread.call(target);
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return Reflect.get(target, prop, receiver);
|
|
83
|
+
},
|
|
84
|
+
}),
|
|
85
|
+
},
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
useInputSync(chatHelpers, runtime);
|
|
89
|
+
|
|
90
|
+
return runtime;
|
|
91
|
+
};
|