@assistant-ui/react-ai-sdk 0.10.16 → 0.11.0-alpha.0-alpha
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/frontendTools.js +1 -1
- package/dist/frontendTools.js.map +1 -1
- package/dist/index.d.ts +0 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -5
- package/dist/index.js.map +1 -1
- package/dist/ui/getVercelAIMessages.d.ts +2 -2
- package/dist/ui/getVercelAIMessages.d.ts.map +1 -1
- package/dist/ui/getVercelAIMessages.js.map +1 -1
- package/dist/ui/index.d.ts +1 -4
- package/dist/ui/index.d.ts.map +1 -1
- package/dist/ui/index.js +2 -8
- package/dist/ui/index.js.map +1 -1
- package/dist/ui/use-chat/useAISDKRuntime.d.ts +7 -0
- package/dist/ui/use-chat/useAISDKRuntime.d.ts.map +1 -0
- package/dist/ui/use-chat/useAISDKRuntime.js +53 -0
- package/dist/ui/use-chat/useAISDKRuntime.js.map +1 -0
- package/dist/ui/utils/convertMessage.d.ts +5 -5
- package/dist/ui/utils/convertMessage.d.ts.map +1 -1
- package/dist/ui/utils/convertMessage.js +115 -86
- package/dist/ui/utils/convertMessage.js.map +1 -1
- package/dist/ui/utils/sliceMessagesUntil.d.ts +2 -2
- package/dist/ui/utils/sliceMessagesUntil.d.ts.map +1 -1
- package/dist/ui/utils/sliceMessagesUntil.js.map +1 -1
- package/dist/ui/utils/toCreateMessage.d.ts +2 -2
- package/dist/ui/utils/toCreateMessage.d.ts.map +1 -1
- package/dist/ui/utils/toCreateMessage.js +29 -17
- package/dist/ui/utils/toCreateMessage.js.map +1 -1
- package/dist/ui/utils/vercelAttachmentAdapter.js +1 -1
- package/dist/ui/utils/vercelAttachmentAdapter.js.map +1 -1
- package/package.json +14 -14
- package/src/frontendTools.ts +1 -1
- package/src/index.ts +0 -5
- package/src/ui/getVercelAIMessages.tsx +2 -2
- package/src/ui/index.ts +1 -4
- package/src/ui/use-chat/{useVercelUseChatRuntime.tsx → useAISDKRuntime.tsx} +13 -39
- package/src/ui/utils/convertMessage.ts +162 -117
- package/src/ui/utils/sliceMessagesUntil.tsx +2 -2
- package/src/ui/utils/toCreateMessage.ts +45 -20
- package/src/ui/utils/vercelAttachmentAdapter.ts +1 -1
- package/dist/converters/fromLanguageModelTools.d.ts +0 -7
- package/dist/converters/fromLanguageModelTools.d.ts.map +0 -1
- package/dist/converters/fromLanguageModelTools.js +0 -16
- package/dist/converters/fromLanguageModelTools.js.map +0 -1
- package/dist/converters/index.d.ts +0 -4
- package/dist/converters/index.d.ts.map +0 -1
- package/dist/converters/index.js +0 -10
- package/dist/converters/index.js.map +0 -1
- package/dist/converters/toLanguageModelMessages.d.ts +0 -9
- package/dist/converters/toLanguageModelMessages.d.ts.map +0 -1
- package/dist/converters/toLanguageModelMessages.js +0 -143
- package/dist/converters/toLanguageModelMessages.js.map +0 -1
- package/dist/converters/toLanguageModelTools.d.ts +0 -7
- package/dist/converters/toLanguageModelTools.d.ts.map +0 -1
- package/dist/converters/toLanguageModelTools.js +0 -15
- package/dist/converters/toLanguageModelTools.js.map +0 -1
- package/dist/dangerous-in-browser/DangerousInBrowserAdapter.d.ts +0 -9
- package/dist/dangerous-in-browser/DangerousInBrowserAdapter.d.ts.map +0 -1
- package/dist/dangerous-in-browser/DangerousInBrowserAdapter.js +0 -38
- package/dist/dangerous-in-browser/DangerousInBrowserAdapter.js.map +0 -1
- package/dist/dangerous-in-browser/createEdgeRuntimeAPI.d.ts +0 -56
- package/dist/dangerous-in-browser/createEdgeRuntimeAPI.d.ts.map +0 -1
- package/dist/dangerous-in-browser/createEdgeRuntimeAPI.js +0 -65
- package/dist/dangerous-in-browser/createEdgeRuntimeAPI.js.map +0 -1
- package/dist/dangerous-in-browser/index.d.ts +0 -2
- package/dist/dangerous-in-browser/index.d.ts.map +0 -1
- package/dist/dangerous-in-browser/index.js +0 -8
- package/dist/dangerous-in-browser/index.js.map +0 -1
- package/dist/dangerous-in-browser/useDangerousInBrowserRuntime.d.ts +0 -5
- package/dist/dangerous-in-browser/useDangerousInBrowserRuntime.d.ts.map +0 -1
- package/dist/dangerous-in-browser/useDangerousInBrowserRuntime.js +0 -21
- package/dist/dangerous-in-browser/useDangerousInBrowserRuntime.js.map +0 -1
- package/dist/rsc/RSCDisplay.d.ts +0 -3
- package/dist/rsc/RSCDisplay.d.ts.map +0 -1
- package/dist/rsc/RSCDisplay.js +0 -26
- package/dist/rsc/RSCDisplay.js.map +0 -1
- package/dist/rsc/VercelRSCAdapter.d.ts +0 -17
- package/dist/rsc/VercelRSCAdapter.d.ts.map +0 -1
- package/dist/rsc/VercelRSCAdapter.js +0 -1
- package/dist/rsc/VercelRSCAdapter.js.map +0 -1
- package/dist/rsc/VercelRSCMessage.d.ts +0 -8
- package/dist/rsc/VercelRSCMessage.d.ts.map +0 -1
- package/dist/rsc/VercelRSCMessage.js +0 -2
- package/dist/rsc/VercelRSCMessage.js.map +0 -1
- package/dist/rsc/index.d.ts +0 -5
- package/dist/rsc/index.d.ts.map +0 -1
- package/dist/rsc/index.js +0 -8
- package/dist/rsc/index.js.map +0 -1
- package/dist/rsc/useVercelRSCRuntime.d.ts +0 -3
- package/dist/rsc/useVercelRSCRuntime.d.ts.map +0 -1
- package/dist/rsc/useVercelRSCRuntime.js +0 -57
- package/dist/rsc/useVercelRSCRuntime.js.map +0 -1
- package/dist/rsc/utils/RSCThreadExtras.d.ts +0 -8
- package/dist/rsc/utils/RSCThreadExtras.d.ts.map +0 -1
- package/dist/rsc/utils/RSCThreadExtras.js +0 -8
- package/dist/rsc/utils/RSCThreadExtras.js.map +0 -1
- package/dist/ui/use-assistant/useVercelUseAssistantRuntime.d.ts +0 -7
- package/dist/ui/use-assistant/useVercelUseAssistantRuntime.d.ts.map +0 -1
- package/dist/ui/use-assistant/useVercelUseAssistantRuntime.js +0 -48
- package/dist/ui/use-assistant/useVercelUseAssistantRuntime.js.map +0 -1
- package/dist/ui/use-chat/useVercelUseChatRuntime.d.ts +0 -8
- package/dist/ui/use-chat/useVercelUseChatRuntime.d.ts.map +0 -1
- package/dist/ui/use-chat/useVercelUseChatRuntime.js +0 -75
- package/dist/ui/use-chat/useVercelUseChatRuntime.js.map +0 -1
- package/dist/ui/utils/useInputSync.d.ts +0 -6
- package/dist/ui/utils/useInputSync.d.ts.map +0 -1
- package/dist/ui/utils/useInputSync.js +0 -18
- package/dist/ui/utils/useInputSync.js.map +0 -1
- package/dist/useChatRuntime.d.ts +0 -16
- package/dist/useChatRuntime.d.ts.map +0 -1
- package/dist/useChatRuntime.js +0 -106
- package/dist/useChatRuntime.js.map +0 -1
- package/dist/useCloudRuntime.d.ts +0 -12
- package/dist/useCloudRuntime.d.ts.map +0 -1
- package/dist/useCloudRuntime.js +0 -15
- package/dist/useCloudRuntime.js.map +0 -1
- package/src/converters/fromLanguageModelTools.ts +0 -19
- package/src/converters/index.ts +0 -3
- package/src/converters/toLanguageModelMessages.ts +0 -185
- package/src/converters/toLanguageModelTools.ts +0 -21
- package/src/dangerous-in-browser/DangerousInBrowserAdapter.ts +0 -41
- package/src/dangerous-in-browser/createEdgeRuntimeAPI.ts +0 -145
- package/src/dangerous-in-browser/index.ts +0 -4
- package/src/dangerous-in-browser/useDangerousInBrowserRuntime.ts +0 -26
- package/src/rsc/RSCDisplay.tsx +0 -23
- package/src/rsc/VercelRSCAdapter.tsx +0 -21
- package/src/rsc/VercelRSCMessage.tsx +0 -9
- package/src/rsc/index.ts +0 -4
- package/src/rsc/useVercelRSCRuntime.tsx +0 -70
- package/src/rsc/utils/RSCThreadExtras.tsx +0 -11
- package/src/ui/use-assistant/useVercelUseAssistantRuntime.tsx +0 -60
- package/src/ui/utils/useInputSync.tsx +0 -26
- package/src/useChatRuntime.ts +0 -157
- package/src/useCloudRuntime.ts +0 -21
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/ui/utils/vercelAttachmentAdapter.ts"],"sourcesContent":["import { AttachmentAdapter } from \"@assistant-ui/react\";\nimport { generateId } from \"
|
|
1
|
+
{"version":3,"sources":["../../../src/ui/utils/vercelAttachmentAdapter.ts"],"sourcesContent":["import { AttachmentAdapter } from \"@assistant-ui/react\";\nimport { generateId } from \"ai\";\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,IAAM,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":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@assistant-ui/react-ai-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0-alpha.0-alpha",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -18,19 +18,19 @@
|
|
|
18
18
|
],
|
|
19
19
|
"sideEffects": false,
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@ai-sdk/provider": "^
|
|
22
|
-
"@ai-sdk/react": "
|
|
23
|
-
"
|
|
21
|
+
"@ai-sdk/provider": "^2.0.0",
|
|
22
|
+
"@ai-sdk/react": "^2.0.0",
|
|
23
|
+
"ai": "^5.0.0",
|
|
24
24
|
"@radix-ui/react-use-callback-ref": "^1.1.1",
|
|
25
25
|
"@types/json-schema": "^7.0.15",
|
|
26
|
-
"assistant-stream": "^0.2.
|
|
26
|
+
"assistant-stream": "^0.2.21",
|
|
27
27
|
"json-schema": "^0.4.0",
|
|
28
|
-
"zod": "^
|
|
28
|
+
"zod": "^4.0.14",
|
|
29
29
|
"zod-to-json-schema": "^3.24.6",
|
|
30
|
-
"zustand": "^5.0.
|
|
30
|
+
"zustand": "^5.0.7"
|
|
31
31
|
},
|
|
32
32
|
"peerDependencies": {
|
|
33
|
-
"@assistant-ui/react": "^0.10.
|
|
33
|
+
"@assistant-ui/react": "^0.10.33",
|
|
34
34
|
"@types/react": "*",
|
|
35
35
|
"react": "^18 || ^19 || ^19.0.0-rc"
|
|
36
36
|
},
|
|
@@ -40,13 +40,13 @@
|
|
|
40
40
|
}
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
|
-
"@types/node": "^24.0
|
|
44
|
-
"@types/react": "^19.1.
|
|
43
|
+
"@types/node": "^24.1.0",
|
|
44
|
+
"@types/react": "^19.1.9",
|
|
45
45
|
"eslint": "^9",
|
|
46
|
-
"eslint-config-next": "15.
|
|
47
|
-
"react": "
|
|
46
|
+
"eslint-config-next": "15.4.5",
|
|
47
|
+
"react": "19.1.0",
|
|
48
48
|
"tsx": "^4.20.3",
|
|
49
|
-
"@assistant-ui/react": "0.10.
|
|
49
|
+
"@assistant-ui/react": "0.10.33",
|
|
50
50
|
"@assistant-ui/x-buildutils": "0.0.1"
|
|
51
51
|
},
|
|
52
52
|
"publishConfig": {
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
},
|
|
56
56
|
"repository": {
|
|
57
57
|
"type": "git",
|
|
58
|
-
"url": "https://github.com/assistant-ui/assistant-ui/tree/main/packages/react-ai-sdk"
|
|
58
|
+
"url": "https://github.com/assistant-ui/assistant-ui/tree/main/packages/react-ai-sdk-v5"
|
|
59
59
|
},
|
|
60
60
|
"bugs": {
|
|
61
61
|
"url": "https://github.com/assistant-ui/assistant-ui/issues"
|
package/src/frontendTools.ts
CHANGED
package/src/index.ts
CHANGED
|
@@ -2,8 +2,8 @@ import {
|
|
|
2
2
|
getExternalStoreMessages,
|
|
3
3
|
type ThreadMessage,
|
|
4
4
|
} from "@assistant-ui/react";
|
|
5
|
-
import type {
|
|
5
|
+
import type { UIMessage } from "ai";
|
|
6
6
|
|
|
7
7
|
export const getVercelAIMessages = (message: ThreadMessage) => {
|
|
8
|
-
return getExternalStoreMessages(message) as
|
|
8
|
+
return getExternalStoreMessages(message) as UIMessage[];
|
|
9
9
|
};
|
package/src/ui/index.ts
CHANGED
|
@@ -1,4 +1 @@
|
|
|
1
|
-
export {
|
|
2
|
-
export { useVercelUseAssistantRuntime } from "./use-assistant/useVercelUseAssistantRuntime";
|
|
3
|
-
export { getVercelAIMessages } from "./getVercelAIMessages";
|
|
4
|
-
export { AISDKMessageConverter } from "./utils/convertMessage";
|
|
1
|
+
export { useAISDKRuntime } from "./use-chat/useAISDKRuntime";
|
|
@@ -2,44 +2,38 @@
|
|
|
2
2
|
|
|
3
3
|
import type { useChat } from "@ai-sdk/react";
|
|
4
4
|
import { useExternalStoreRuntime } from "@assistant-ui/react";
|
|
5
|
-
import { useInputSync } from "../utils/useInputSync";
|
|
6
5
|
import { sliceMessagesUntil } from "../utils/sliceMessagesUntil";
|
|
7
6
|
import { toCreateMessage } from "../utils/toCreateMessage";
|
|
8
7
|
import { vercelAttachmentAdapter } from "../utils/vercelAttachmentAdapter";
|
|
9
8
|
import { getVercelAIMessages } from "../getVercelAIMessages";
|
|
10
9
|
import { ExternalStoreAdapter } from "@assistant-ui/react";
|
|
11
|
-
import { useState } from "react";
|
|
12
|
-
import { generateId } from "@ai-sdk/ui-utils";
|
|
13
10
|
import { AISDKMessageConverter } from "../utils/convertMessage";
|
|
14
11
|
|
|
15
|
-
export type
|
|
12
|
+
export type AISDKRuntimeAdapter = {
|
|
16
13
|
adapters?:
|
|
17
14
|
| Omit<NonNullable<ExternalStoreAdapter["adapters"]>, "attachments">
|
|
18
15
|
| undefined;
|
|
19
|
-
unstable_joinStrategy?: "concat-content" | "none";
|
|
20
16
|
};
|
|
21
17
|
|
|
22
|
-
export const
|
|
18
|
+
export const useAISDKRuntime = (
|
|
23
19
|
chatHelpers: ReturnType<typeof useChat>,
|
|
24
|
-
adapter:
|
|
20
|
+
adapter: AISDKRuntimeAdapter = {},
|
|
25
21
|
) => {
|
|
26
22
|
const messages = AISDKMessageConverter.useThreadMessages({
|
|
27
23
|
isRunning:
|
|
28
24
|
chatHelpers.status === "submitted" || chatHelpers.status == "streaming",
|
|
29
25
|
messages: chatHelpers.messages,
|
|
30
|
-
joinStrategy: adapter.unstable_joinStrategy,
|
|
31
26
|
});
|
|
32
27
|
|
|
33
|
-
const [threadId, setThreadId] = useState<string>(generateId());
|
|
34
|
-
|
|
35
28
|
const runtime = useExternalStoreRuntime({
|
|
36
|
-
isRunning:
|
|
29
|
+
isRunning:
|
|
30
|
+
chatHelpers.status === "submitted" || chatHelpers.status === "streaming",
|
|
37
31
|
messages,
|
|
38
32
|
setMessages: (messages) =>
|
|
39
33
|
chatHelpers.setMessages(messages.map(getVercelAIMessages).flat()),
|
|
40
34
|
onCancel: async () => chatHelpers.stop(),
|
|
41
35
|
onNew: async (message) => {
|
|
42
|
-
await chatHelpers.
|
|
36
|
+
await chatHelpers.sendMessage(await toCreateMessage(message));
|
|
43
37
|
},
|
|
44
38
|
onEdit: async (message) => {
|
|
45
39
|
const newMessages = sliceMessagesUntil(
|
|
@@ -48,46 +42,26 @@ export const useVercelUseChatRuntime = (
|
|
|
48
42
|
);
|
|
49
43
|
chatHelpers.setMessages(newMessages);
|
|
50
44
|
|
|
51
|
-
await chatHelpers.
|
|
45
|
+
await chatHelpers.sendMessage(await toCreateMessage(message));
|
|
52
46
|
},
|
|
53
47
|
onReload: async (parentId: string | null) => {
|
|
54
48
|
const newMessages = sliceMessagesUntil(chatHelpers.messages, parentId);
|
|
55
49
|
chatHelpers.setMessages(newMessages);
|
|
56
50
|
|
|
57
|
-
await chatHelpers.
|
|
51
|
+
await chatHelpers.regenerate();
|
|
58
52
|
},
|
|
59
53
|
onAddToolResult: ({ toolCallId, result }) => {
|
|
60
|
-
chatHelpers.addToolResult({
|
|
54
|
+
chatHelpers.addToolResult({
|
|
55
|
+
tool: toolCallId,
|
|
56
|
+
toolCallId,
|
|
57
|
+
output: result,
|
|
58
|
+
});
|
|
61
59
|
},
|
|
62
60
|
adapters: {
|
|
63
61
|
attachments: vercelAttachmentAdapter,
|
|
64
62
|
...adapter.adapters,
|
|
65
|
-
threadList: new Proxy(adapter.adapters?.threadList ?? {}, {
|
|
66
|
-
get(target, prop, receiver) {
|
|
67
|
-
if (prop === "threadId") {
|
|
68
|
-
return target.threadId ?? threadId;
|
|
69
|
-
}
|
|
70
|
-
if (prop === "onSwitchToNewThread") {
|
|
71
|
-
return () => {
|
|
72
|
-
chatHelpers.messages = [];
|
|
73
|
-
chatHelpers.input = "";
|
|
74
|
-
chatHelpers.setMessages([]);
|
|
75
|
-
chatHelpers.setInput("");
|
|
76
|
-
setThreadId(generateId());
|
|
77
|
-
|
|
78
|
-
if (typeof target.onSwitchToNewThread === "function") {
|
|
79
|
-
return target.onSwitchToNewThread.call(target);
|
|
80
|
-
}
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
return Reflect.get(target, prop, receiver);
|
|
85
|
-
},
|
|
86
|
-
}),
|
|
87
63
|
},
|
|
88
64
|
});
|
|
89
65
|
|
|
90
|
-
useInputSync(chatHelpers, runtime);
|
|
91
|
-
|
|
92
66
|
return runtime;
|
|
93
67
|
};
|
|
@@ -1,100 +1,183 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { isToolUIPart, UIMessage } from "ai";
|
|
2
2
|
import {
|
|
3
3
|
unstable_createMessageConverter,
|
|
4
4
|
type ReasoningMessagePart,
|
|
5
5
|
type ToolCallMessagePart,
|
|
6
6
|
type TextMessagePart,
|
|
7
|
-
type CompleteAttachment,
|
|
8
7
|
type SourceMessagePart,
|
|
9
8
|
type FileMessagePart,
|
|
10
9
|
} from "@assistant-ui/react";
|
|
11
10
|
|
|
12
|
-
const convertParts = (message:
|
|
13
|
-
if (message.parts
|
|
14
|
-
return
|
|
15
|
-
.filter((p) => p.type !== "step-start")
|
|
16
|
-
.map((part) => {
|
|
17
|
-
const type = part.type;
|
|
18
|
-
switch (type) {
|
|
19
|
-
case "text":
|
|
20
|
-
return {
|
|
21
|
-
type: "text",
|
|
22
|
-
text: part.text,
|
|
23
|
-
} satisfies TextMessagePart;
|
|
24
|
-
case "tool-invocation":
|
|
25
|
-
return {
|
|
26
|
-
type: "tool-call",
|
|
27
|
-
toolName: part.toolInvocation.toolName,
|
|
28
|
-
toolCallId: part.toolInvocation.toolCallId,
|
|
29
|
-
argsText: JSON.stringify(part.toolInvocation.args),
|
|
30
|
-
args: part.toolInvocation.args,
|
|
31
|
-
result:
|
|
32
|
-
part.toolInvocation.state === "result" &&
|
|
33
|
-
part.toolInvocation.result,
|
|
34
|
-
} satisfies ToolCallMessagePart;
|
|
35
|
-
case "reasoning":
|
|
36
|
-
return {
|
|
37
|
-
type: "reasoning",
|
|
38
|
-
text: part.reasoning,
|
|
39
|
-
} satisfies ReasoningMessagePart;
|
|
40
|
-
case "source":
|
|
41
|
-
return {
|
|
42
|
-
type: "source",
|
|
43
|
-
...part.source,
|
|
44
|
-
} satisfies SourceMessagePart;
|
|
45
|
-
case "file":
|
|
46
|
-
return {
|
|
47
|
-
type: "file",
|
|
48
|
-
data: part.data,
|
|
49
|
-
mimeType: part.mimeType,
|
|
50
|
-
} satisfies FileMessagePart;
|
|
51
|
-
default: {
|
|
52
|
-
const _unsupported: never = type;
|
|
53
|
-
throw new Error(
|
|
54
|
-
`You have a message with an unsupported part type. The type ${_unsupported} is not supported.`,
|
|
55
|
-
);
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
});
|
|
11
|
+
const convertParts = (message: UIMessage) => {
|
|
12
|
+
if (!message.parts || message.parts.length === 0) {
|
|
13
|
+
return [];
|
|
59
14
|
}
|
|
60
15
|
|
|
61
|
-
return message.
|
|
62
|
-
|
|
63
|
-
|
|
16
|
+
return message.parts
|
|
17
|
+
.filter((p) => p.type !== "step-start")
|
|
18
|
+
.map((part) => {
|
|
19
|
+
const type = part.type;
|
|
20
|
+
|
|
21
|
+
// Handle text parts
|
|
22
|
+
if (type === "text") {
|
|
23
|
+
return {
|
|
64
24
|
type: "text",
|
|
65
|
-
text:
|
|
66
|
-
} satisfies TextMessagePart
|
|
67
|
-
|
|
68
|
-
|
|
25
|
+
text: part.text,
|
|
26
|
+
} satisfies TextMessagePart;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Handle reasoning parts
|
|
30
|
+
if (type === "reasoning") {
|
|
31
|
+
return {
|
|
32
|
+
type: "reasoning",
|
|
33
|
+
text: part.text,
|
|
34
|
+
} satisfies ReasoningMessagePart;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Handle tool-* parts (AI SDK v5 tool calls)
|
|
38
|
+
if (isToolUIPart(part)) {
|
|
39
|
+
const toolName = type.replace("tool-", "");
|
|
40
|
+
const toolCallId = part.toolCallId;
|
|
41
|
+
|
|
42
|
+
// Extract args and result based on state
|
|
43
|
+
let args: any = {};
|
|
44
|
+
let result: any = undefined;
|
|
45
|
+
let isError = false;
|
|
46
|
+
|
|
47
|
+
if (
|
|
48
|
+
part.state === "input-streaming" ||
|
|
49
|
+
part.state === "input-available"
|
|
50
|
+
) {
|
|
51
|
+
args = part.input || {};
|
|
52
|
+
} else if (part.state === "output-available") {
|
|
53
|
+
args = part.input || {};
|
|
54
|
+
result = part.output;
|
|
55
|
+
} else if (part.state === "output-error") {
|
|
56
|
+
args = part.input || {};
|
|
57
|
+
isError = true;
|
|
58
|
+
result = { error: part.errorText };
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return {
|
|
62
|
+
type: "tool-call",
|
|
63
|
+
toolName,
|
|
64
|
+
toolCallId,
|
|
65
|
+
argsText: JSON.stringify(args),
|
|
66
|
+
args,
|
|
67
|
+
result,
|
|
68
|
+
isError,
|
|
69
|
+
} satisfies ToolCallMessagePart;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Handle dynamic-tool parts
|
|
73
|
+
if (type === "dynamic-tool") {
|
|
74
|
+
const toolName = part.toolName;
|
|
75
|
+
const toolCallId = part.toolCallId;
|
|
76
|
+
|
|
77
|
+
// Extract args and result based on state
|
|
78
|
+
let args: any = {};
|
|
79
|
+
let result: any = undefined;
|
|
80
|
+
let isError = false;
|
|
81
|
+
|
|
82
|
+
if (
|
|
83
|
+
part.state === "input-streaming" ||
|
|
84
|
+
part.state === "input-available"
|
|
85
|
+
) {
|
|
86
|
+
args = part.input || {};
|
|
87
|
+
} else if (part.state === "output-available") {
|
|
88
|
+
args = part.input || {};
|
|
89
|
+
result = part.output;
|
|
90
|
+
} else if (part.state === "output-error") {
|
|
91
|
+
args = part.input || {};
|
|
92
|
+
isError = true;
|
|
93
|
+
result = { error: part.errorText };
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return {
|
|
97
|
+
type: "tool-call",
|
|
98
|
+
toolName,
|
|
99
|
+
toolCallId,
|
|
100
|
+
argsText: JSON.stringify(args),
|
|
101
|
+
args,
|
|
102
|
+
result,
|
|
103
|
+
isError,
|
|
104
|
+
} satisfies ToolCallMessagePart;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Handle source-url parts
|
|
108
|
+
if (type === "source-url") {
|
|
109
|
+
return {
|
|
110
|
+
type: "source",
|
|
111
|
+
sourceType: "url",
|
|
112
|
+
id: part.sourceId,
|
|
113
|
+
url: part.url,
|
|
114
|
+
title: part.title || "",
|
|
115
|
+
} satisfies SourceMessagePart;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Handle source-document parts
|
|
119
|
+
if (type === "source-document") {
|
|
120
|
+
console.warn(
|
|
121
|
+
`Source document part type ${type} is not yet supported in conversion`,
|
|
122
|
+
);
|
|
123
|
+
return null;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// Handle file parts
|
|
127
|
+
if (type === "file") {
|
|
128
|
+
return {
|
|
129
|
+
type: "file",
|
|
130
|
+
data: part.url,
|
|
131
|
+
mimeType: part.mediaType,
|
|
132
|
+
} satisfies FileMessagePart;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Handle data-* parts (AI SDK v5 data parts)
|
|
136
|
+
if (type.startsWith("data-")) {
|
|
137
|
+
// For now, we'll skip data parts as they don't have a direct equivalent
|
|
138
|
+
// in the assistant-ui types. They could be converted to a custom message part
|
|
139
|
+
// or handled differently based on the specific use case.
|
|
140
|
+
console.warn(
|
|
141
|
+
`Data part type ${type} is not yet supported in conversion`,
|
|
142
|
+
);
|
|
143
|
+
return null;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// For unsupported types, we'll skip them instead of throwing
|
|
147
|
+
console.warn(`Unsupported message part type: ${type}`);
|
|
148
|
+
return null;
|
|
149
|
+
})
|
|
150
|
+
.filter(Boolean) as any[];
|
|
69
151
|
};
|
|
70
152
|
|
|
71
153
|
export const AISDKMessageConverter = unstable_createMessageConverter(
|
|
72
|
-
(message:
|
|
154
|
+
(message: UIMessage) => {
|
|
155
|
+
// UIMessage doesn't have createdAt, so we'll use current date or undefined
|
|
156
|
+
const createdAt = new Date();
|
|
73
157
|
switch (message.role) {
|
|
74
158
|
case "user":
|
|
75
159
|
return {
|
|
76
160
|
role: "user",
|
|
77
161
|
id: message.id,
|
|
78
|
-
createdAt
|
|
162
|
+
createdAt,
|
|
79
163
|
content: convertParts(message),
|
|
80
|
-
attachments: message.
|
|
81
|
-
(
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
),
|
|
164
|
+
attachments: message.parts
|
|
165
|
+
?.filter((p: any) => p.type === "file")
|
|
166
|
+
.map((part: any, idx) => ({
|
|
167
|
+
id: idx.toString(),
|
|
168
|
+
type: "file" as const,
|
|
169
|
+
name: part.name ?? part.url ?? "file",
|
|
170
|
+
content: [],
|
|
171
|
+
contentType: part.mediaType ?? part.mimeType ?? "unknown/unknown",
|
|
172
|
+
status: { type: "complete" as const },
|
|
173
|
+
})),
|
|
91
174
|
};
|
|
92
175
|
|
|
93
176
|
case "system":
|
|
94
177
|
return {
|
|
95
178
|
role: "system",
|
|
96
179
|
id: message.id,
|
|
97
|
-
createdAt
|
|
180
|
+
createdAt,
|
|
98
181
|
content: convertParts(message),
|
|
99
182
|
};
|
|
100
183
|
|
|
@@ -102,60 +185,22 @@ export const AISDKMessageConverter = unstable_createMessageConverter(
|
|
|
102
185
|
return {
|
|
103
186
|
role: "assistant",
|
|
104
187
|
id: message.id,
|
|
105
|
-
createdAt
|
|
188
|
+
createdAt,
|
|
106
189
|
content: convertParts(message),
|
|
107
190
|
metadata: {
|
|
108
|
-
unstable_annotations: message.annotations,
|
|
109
|
-
unstable_data: Array.isArray(message.data)
|
|
110
|
-
? message.data
|
|
111
|
-
: message.data
|
|
112
|
-
? [message.data]
|
|
191
|
+
unstable_annotations: (message as any).annotations,
|
|
192
|
+
unstable_data: Array.isArray((message as any).data)
|
|
193
|
+
? (message as any).data
|
|
194
|
+
: (message as any).data
|
|
195
|
+
? [(message as any).data]
|
|
113
196
|
: undefined,
|
|
197
|
+
custom: {},
|
|
114
198
|
},
|
|
115
199
|
};
|
|
116
200
|
|
|
117
|
-
case "data": {
|
|
118
|
-
type MaybeSupportedDataMessage =
|
|
119
|
-
| { type?: "unsafe_other" }
|
|
120
|
-
| ToolCallMessagePart
|
|
121
|
-
| {
|
|
122
|
-
type: "tool-result";
|
|
123
|
-
toolCallId: string;
|
|
124
|
-
result: any;
|
|
125
|
-
};
|
|
126
|
-
|
|
127
|
-
if (
|
|
128
|
-
!message.data ||
|
|
129
|
-
!(typeof message.data === "object") ||
|
|
130
|
-
Array.isArray(message.data)
|
|
131
|
-
)
|
|
132
|
-
return [];
|
|
133
|
-
|
|
134
|
-
const data = message.data as MaybeSupportedDataMessage;
|
|
135
|
-
|
|
136
|
-
if (data.type === "tool-call") {
|
|
137
|
-
return {
|
|
138
|
-
role: "assistant",
|
|
139
|
-
id: message.id,
|
|
140
|
-
createdAt: message.createdAt,
|
|
141
|
-
content: [data],
|
|
142
|
-
};
|
|
143
|
-
} else if (data.type === "tool-result") {
|
|
144
|
-
return {
|
|
145
|
-
role: "tool",
|
|
146
|
-
id: message.id,
|
|
147
|
-
toolCallId: data.toolCallId,
|
|
148
|
-
result: data.result,
|
|
149
|
-
};
|
|
150
|
-
}
|
|
151
|
-
return [];
|
|
152
|
-
}
|
|
153
|
-
|
|
154
201
|
default:
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
`You have a message with an unsupported role. The role ${_unsupported} is not supported.`,
|
|
158
|
-
);
|
|
202
|
+
console.warn(`Unsupported message role: ${message.role}`);
|
|
203
|
+
return [];
|
|
159
204
|
}
|
|
160
205
|
},
|
|
161
206
|
);
|
|
@@ -1,35 +1,60 @@
|
|
|
1
1
|
import { AppendMessage } from "@assistant-ui/react";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
CreateUIMessage,
|
|
4
|
+
FileUIPart,
|
|
5
|
+
UIDataTypes,
|
|
6
|
+
UIMessage,
|
|
7
|
+
UIMessagePart,
|
|
8
|
+
UITools,
|
|
9
|
+
} from "ai";
|
|
3
10
|
|
|
4
11
|
export const toCreateMessage = async (
|
|
5
12
|
message: AppendMessage,
|
|
6
|
-
): Promise<
|
|
7
|
-
const
|
|
13
|
+
): Promise<CreateUIMessage<UIMessage>> => {
|
|
14
|
+
const textParts = message.content
|
|
8
15
|
.filter((part) => part.type === "text")
|
|
9
16
|
.map((t) => t.text)
|
|
10
17
|
.join("\n\n");
|
|
11
18
|
|
|
12
|
-
const
|
|
19
|
+
const parts: UIMessagePart<UIDataTypes, UITools>[] = [
|
|
20
|
+
{
|
|
21
|
+
type: "text",
|
|
22
|
+
text: textParts,
|
|
23
|
+
},
|
|
24
|
+
];
|
|
25
|
+
|
|
26
|
+
// Add image parts
|
|
27
|
+
const imageParts = message.content
|
|
13
28
|
.filter((part) => part.type === "image")
|
|
14
|
-
.map(
|
|
29
|
+
.map(
|
|
30
|
+
(part) =>
|
|
31
|
+
({
|
|
32
|
+
type: "file",
|
|
33
|
+
mediaType: "image/png", // Default to PNG, could be made more dynamic
|
|
34
|
+
url: part.image,
|
|
35
|
+
}) satisfies FileUIPart,
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
parts.push(...imageParts);
|
|
39
|
+
|
|
40
|
+
// Add attachment parts
|
|
41
|
+
const attachmentParts = await Promise.all(
|
|
42
|
+
(message.attachments ?? []).map(async (m) => {
|
|
43
|
+
if (m.file == null) throw new Error("Attachment did not contain a file");
|
|
44
|
+
return {
|
|
45
|
+
type: "file",
|
|
46
|
+
mediaType: m.file.type,
|
|
47
|
+
filename: m.file.name,
|
|
48
|
+
url: await getFileDataURL(m.file),
|
|
49
|
+
} satisfies FileUIPart;
|
|
50
|
+
}),
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
parts.push(...attachmentParts);
|
|
15
54
|
|
|
16
55
|
return {
|
|
17
56
|
role: message.role,
|
|
18
|
-
|
|
19
|
-
experimental_attachments: [
|
|
20
|
-
...images,
|
|
21
|
-
...(await Promise.all(
|
|
22
|
-
(message.attachments ?? []).map(async (m) => {
|
|
23
|
-
if (m.file == null)
|
|
24
|
-
throw new Error("Attachment did not contain a file");
|
|
25
|
-
return {
|
|
26
|
-
contentType: m.file.type,
|
|
27
|
-
name: m.file.name,
|
|
28
|
-
url: await getFileDataURL(m.file),
|
|
29
|
-
};
|
|
30
|
-
}),
|
|
31
|
-
)),
|
|
32
|
-
],
|
|
57
|
+
parts,
|
|
33
58
|
};
|
|
34
59
|
};
|
|
35
60
|
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { LanguageModelV1FunctionTool } from "@ai-sdk/provider";
|
|
2
|
-
import { Tool } from "@assistant-ui/react";
|
|
3
|
-
/**
|
|
4
|
-
* @deprecated This is an internal API and may change without notice.
|
|
5
|
-
*/
|
|
6
|
-
export declare const fromLanguageModelTools: (tools: LanguageModelV1FunctionTool[]) => Record<string, Tool<any, any>>;
|
|
7
|
-
//# sourceMappingURL=fromLanguageModelTools.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"fromLanguageModelTools.d.ts","sourceRoot":"","sources":["../../src/converters/fromLanguageModelTools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,2BAA2B,EAAE,MAAM,kBAAkB,CAAC;AAC/D,OAAO,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAE3C;;GAEG;AACH,eAAO,MAAM,sBAAsB,GACjC,OAAO,2BAA2B,EAAE,KACnC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,CAU/B,CAAC"}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
// src/converters/fromLanguageModelTools.ts
|
|
2
|
-
var fromLanguageModelTools = (tools) => {
|
|
3
|
-
return Object.fromEntries(
|
|
4
|
-
tools.map((tool) => [
|
|
5
|
-
tool.name,
|
|
6
|
-
{
|
|
7
|
-
description: tool.description,
|
|
8
|
-
parameters: tool.parameters
|
|
9
|
-
}
|
|
10
|
-
])
|
|
11
|
-
);
|
|
12
|
-
};
|
|
13
|
-
export {
|
|
14
|
-
fromLanguageModelTools
|
|
15
|
-
};
|
|
16
|
-
//# sourceMappingURL=fromLanguageModelTools.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/converters/fromLanguageModelTools.ts"],"sourcesContent":["import { LanguageModelV1FunctionTool } from \"@ai-sdk/provider\";\nimport { Tool } from \"@assistant-ui/react\";\n\n/**\n * @deprecated This is an internal API and may change without notice.\n */\nexport const fromLanguageModelTools = (\n tools: LanguageModelV1FunctionTool[],\n): Record<string, Tool<any, any>> => {\n return Object.fromEntries(\n tools.map((tool) => [\n tool.name,\n {\n description: tool.description,\n parameters: tool.parameters,\n },\n ]),\n );\n};\n"],"mappings":";AAMO,IAAM,yBAAyB,CACpC,UACmC;AACnC,SAAO,OAAO;AAAA,IACZ,MAAM,IAAI,CAAC,SAAS;AAAA,MAClB,KAAK;AAAA,MACL;AAAA,QACE,aAAa,KAAK;AAAA,QAClB,YAAY,KAAK;AAAA,MACnB;AAAA,IACF,CAAC;AAAA,EACH;AACF;","names":[]}
|