@assistant-ui/react-ai-sdk 1.0.0 → 1.0.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/frontendTools.d.ts +1 -1
- package/dist/frontendTools.js +1 -1
- package/dist/frontendTools.js.map +1 -1
- package/dist/ui/getVercelAIMessages.d.ts +1 -1
- package/dist/ui/getVercelAIMessages.d.ts.map +1 -1
- package/dist/ui/getVercelAIMessages.js.map +1 -1
- package/dist/ui/use-chat/useAISDKRuntime.d.ts +2 -2
- package/dist/ui/use-chat/useAISDKRuntime.d.ts.map +1 -1
- package/dist/ui/use-chat/useAISDKRuntime.js +6 -2
- package/dist/ui/use-chat/useAISDKRuntime.js.map +1 -1
- package/dist/ui/use-chat/useChatRuntime.d.ts.map +1 -1
- package/dist/ui/use-chat/useChatRuntime.js +28 -1
- package/dist/ui/use-chat/useChatRuntime.js.map +1 -1
- package/dist/ui/utils/sliceMessagesUntil.d.ts +1 -1
- 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 +1 -1
- package/dist/ui/utils/toCreateMessage.d.ts.map +1 -1
- package/dist/ui/utils/toCreateMessage.js.map +1 -1
- package/package.json +11 -11
- package/src/frontendTools.ts +1 -1
- package/src/ui/getVercelAIMessages.tsx +4 -2
- package/src/ui/use-chat/useAISDKRuntime.tsx +21 -9
- package/src/ui/use-chat/useChatRuntime.tsx +27 -0
- package/src/ui/utils/sliceMessagesUntil.tsx +2 -2
- package/src/ui/utils/toCreateMessage.ts +3 -3
package/dist/frontendTools.d.ts
CHANGED
package/dist/frontendTools.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/frontendTools.ts"],"sourcesContent":["import { jsonSchema } from \"ai\";\nimport type { JSONSchema7 } from \"json-schema\";\n\nexport const frontendTools = (\n tools: Record<string, { description?: string; parameters: JSONSchema7 }>,\n) =>\n Object.fromEntries(\n Object.entries(tools).map(([name, tool]) => [\n name,\n {\n ...(tool.description ? { description: tool.description } : undefined),\n
|
|
1
|
+
{"version":3,"sources":["../src/frontendTools.ts"],"sourcesContent":["import { jsonSchema } from \"ai\";\nimport type { JSONSchema7 } from \"json-schema\";\n\nexport const frontendTools = (\n tools: Record<string, { description?: string; parameters: JSONSchema7 }>,\n) =>\n Object.fromEntries(\n Object.entries(tools).map(([name, tool]) => [\n name,\n {\n ...(tool.description ? { description: tool.description } : undefined),\n inputSchema: jsonSchema(tool.parameters),\n },\n ]),\n );\n"],"mappings":";AAAA,SAAS,kBAAkB;AAGpB,IAAM,gBAAgB,CAC3B,UAEA,OAAO;AAAA,EACL,OAAO,QAAQ,KAAK,EAAE,IAAI,CAAC,CAAC,MAAM,IAAI,MAAM;AAAA,IAC1C;AAAA,IACA;AAAA,MACE,GAAI,KAAK,cAAc,EAAE,aAAa,KAAK,YAAY,IAAI;AAAA,MAC3D,aAAa,WAAW,KAAK,UAAU;AAAA,IACzC;AAAA,EACF,CAAC;AACH;","names":[]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { type ThreadMessage } from "@assistant-ui/react";
|
|
2
2
|
import type { UIMessage } from "ai";
|
|
3
|
-
export declare const getVercelAIMessages: (message: ThreadMessage) =>
|
|
3
|
+
export declare const getVercelAIMessages: <UI_MESSAGE extends UIMessage = UIMessage>(message: ThreadMessage) => UI_MESSAGE[];
|
|
4
4
|
//# sourceMappingURL=getVercelAIMessages.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getVercelAIMessages.d.ts","sourceRoot":"","sources":["../../src/ui/getVercelAIMessages.tsx"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,aAAa,EACnB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AAEpC,eAAO,MAAM,mBAAmB,GAAI,SAAS,
|
|
1
|
+
{"version":3,"file":"getVercelAIMessages.d.ts","sourceRoot":"","sources":["../../src/ui/getVercelAIMessages.tsx"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,aAAa,EACnB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AAEpC,eAAO,MAAM,mBAAmB,GAAI,UAAU,SAAS,SAAS,GAAG,SAAS,EAC1E,SAAS,aAAa,KAEsB,UAAU,EACvD,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/ui/getVercelAIMessages.tsx"],"sourcesContent":["import {\n getExternalStoreMessages,\n type ThreadMessage,\n} from \"@assistant-ui/react\";\nimport type { UIMessage } from \"ai\";\n\nexport const getVercelAIMessages = (message: ThreadMessage) => {\n return getExternalStoreMessages(message) as
|
|
1
|
+
{"version":3,"sources":["../../src/ui/getVercelAIMessages.tsx"],"sourcesContent":["import {\n getExternalStoreMessages,\n type ThreadMessage,\n} from \"@assistant-ui/react\";\nimport type { UIMessage } from \"ai\";\n\nexport const getVercelAIMessages = <UI_MESSAGE extends UIMessage = UIMessage>(\n message: ThreadMessage,\n) => {\n return getExternalStoreMessages(message) as UI_MESSAGE[];\n};\n"],"mappings":";AAAA;AAAA,EACE;AAAA,OAEK;AAGA,IAAM,sBAAsB,CACjC,YACG;AACH,SAAO,yBAAyB,OAAO;AACzC;","names":[]}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import type { useChat } from "@ai-sdk/react";
|
|
1
|
+
import type { UIMessage, useChat } from "@ai-sdk/react";
|
|
2
2
|
import { ExternalStoreAdapter, ThreadHistoryAdapter, AssistantRuntime } from "@assistant-ui/react";
|
|
3
3
|
export type AISDKRuntimeAdapter = {
|
|
4
4
|
adapters?: (NonNullable<ExternalStoreAdapter["adapters"]> & {
|
|
5
5
|
history?: ThreadHistoryAdapter | undefined;
|
|
6
6
|
}) | undefined;
|
|
7
7
|
};
|
|
8
|
-
export declare const useAISDKRuntime: (chatHelpers: ReturnType<typeof useChat
|
|
8
|
+
export declare const useAISDKRuntime: <UI_MESSAGE extends UIMessage = UIMessage>(chatHelpers: ReturnType<typeof useChat<UI_MESSAGE>>, adapter?: AISDKRuntimeAdapter) => AssistantRuntime;
|
|
9
9
|
//# sourceMappingURL=useAISDKRuntime.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useAISDKRuntime.d.ts","sourceRoot":"","sources":["../../../src/ui/use-chat/useAISDKRuntime.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"useAISDKRuntime.d.ts","sourceRoot":"","sources":["../../../src/ui/use-chat/useAISDKRuntime.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxD,OAAO,EAEL,oBAAoB,EACpB,oBAAoB,EACpB,gBAAgB,EAGjB,MAAM,qBAAqB,CAAC;AAa7B,MAAM,MAAM,mBAAmB,GAAG;IAChC,QAAQ,CAAC,EACL,CAAC,WAAW,CAAC,oBAAoB,CAAC,UAAU,CAAC,CAAC,GAAG;QAC/C,OAAO,CAAC,EAAE,oBAAoB,GAAG,SAAS,CAAC;KAC5C,CAAC,GACF,SAAS,CAAC;CACf,CAAC;AAEF,eAAO,MAAM,eAAe,GAAI,UAAU,SAAS,SAAS,GAAG,SAAS,EACtE,aAAa,UAAU,CAAC,OAAO,OAAO,CAAC,UAAU,CAAC,CAAC,EACnD,UAAS,mBAAwB,qBA2ElC,CAAC"}
|
|
@@ -9,7 +9,9 @@ import { toCreateMessage } from "../utils/toCreateMessage.js";
|
|
|
9
9
|
import { vercelAttachmentAdapter } from "../utils/vercelAttachmentAdapter.js";
|
|
10
10
|
import { getVercelAIMessages } from "../getVercelAIMessages.js";
|
|
11
11
|
import { AISDKMessageConverter } from "../utils/convertMessage.js";
|
|
12
|
-
import {
|
|
12
|
+
import {
|
|
13
|
+
aiSDKV5FormatAdapter
|
|
14
|
+
} from "../adapters/aiSDKFormatAdapter.js";
|
|
13
15
|
import { useExternalHistory } from "./useExternalHistory.js";
|
|
14
16
|
import { useMemo } from "react";
|
|
15
17
|
var useAISDKRuntime = (chatHelpers, adapter = {}) => {
|
|
@@ -37,7 +39,9 @@ var useAISDKRuntime = (chatHelpers, adapter = {}) => {
|
|
|
37
39
|
const runtime = useExternalStoreRuntime({
|
|
38
40
|
isRunning: chatHelpers.status === "submitted" || chatHelpers.status === "streaming",
|
|
39
41
|
messages,
|
|
40
|
-
setMessages: (messages2) => chatHelpers.setMessages(
|
|
42
|
+
setMessages: (messages2) => chatHelpers.setMessages(
|
|
43
|
+
messages2.map(getVercelAIMessages).flat()
|
|
44
|
+
),
|
|
41
45
|
onCancel: async () => chatHelpers.stop(),
|
|
42
46
|
onNew: async (message) => {
|
|
43
47
|
const createMessage = await toCreateMessage(message);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/ui/use-chat/useAISDKRuntime.tsx"],"sourcesContent":["\"use client\";\n\nimport type { useChat } from \"@ai-sdk/react\";\nimport {\n useExternalStoreRuntime,\n ExternalStoreAdapter,\n ThreadHistoryAdapter,\n AssistantRuntime,\n} from \"@assistant-ui/react\";\nimport { sliceMessagesUntil } from \"../utils/sliceMessagesUntil\";\nimport { toCreateMessage } from \"../utils/toCreateMessage\";\nimport { vercelAttachmentAdapter } from \"../utils/vercelAttachmentAdapter\";\nimport { getVercelAIMessages } from \"../getVercelAIMessages\";\nimport { AISDKMessageConverter } from \"../utils/convertMessage\";\nimport {
|
|
1
|
+
{"version":3,"sources":["../../../src/ui/use-chat/useAISDKRuntime.tsx"],"sourcesContent":["\"use client\";\n\nimport type { UIMessage, useChat } from \"@ai-sdk/react\";\nimport {\n useExternalStoreRuntime,\n ExternalStoreAdapter,\n ThreadHistoryAdapter,\n AssistantRuntime,\n ThreadMessage,\n MessageFormatAdapter,\n} from \"@assistant-ui/react\";\nimport { sliceMessagesUntil } from \"../utils/sliceMessagesUntil\";\nimport { toCreateMessage } from \"../utils/toCreateMessage\";\nimport { vercelAttachmentAdapter } from \"../utils/vercelAttachmentAdapter\";\nimport { getVercelAIMessages } from \"../getVercelAIMessages\";\nimport { AISDKMessageConverter } from \"../utils/convertMessage\";\nimport {\n AISDKStorageFormat,\n aiSDKV5FormatAdapter,\n} from \"../adapters/aiSDKFormatAdapter\";\nimport { useExternalHistory } from \"./useExternalHistory\";\nimport { useMemo } from \"react\";\n\nexport type AISDKRuntimeAdapter = {\n adapters?:\n | (NonNullable<ExternalStoreAdapter[\"adapters\"]> & {\n history?: ThreadHistoryAdapter | undefined;\n })\n | undefined;\n};\n\nexport const useAISDKRuntime = <UI_MESSAGE extends UIMessage = UIMessage>(\n chatHelpers: ReturnType<typeof useChat<UI_MESSAGE>>,\n adapter: AISDKRuntimeAdapter = {},\n) => {\n const messages = AISDKMessageConverter.useThreadMessages({\n isRunning:\n chatHelpers.status === \"submitted\" || chatHelpers.status == \"streaming\",\n messages: chatHelpers.messages,\n });\n\n const isLoading = useExternalHistory(\n useMemo(\n () => ({\n get current(): AssistantRuntime {\n return runtime;\n },\n }),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [],\n ),\n adapter.adapters?.history,\n AISDKMessageConverter.toThreadMessages as (\n messages: UI_MESSAGE[],\n ) => ThreadMessage[],\n aiSDKV5FormatAdapter as MessageFormatAdapter<\n UI_MESSAGE,\n AISDKStorageFormat\n >,\n (messages) => {\n chatHelpers.setMessages(messages);\n },\n );\n\n const runtime = useExternalStoreRuntime({\n isRunning:\n chatHelpers.status === \"submitted\" || chatHelpers.status === \"streaming\",\n messages,\n setMessages: (messages) =>\n chatHelpers.setMessages(\n messages.map(getVercelAIMessages<UI_MESSAGE>).flat(),\n ),\n onCancel: async () => chatHelpers.stop(),\n onNew: async (message) => {\n const createMessage = await toCreateMessage<UI_MESSAGE>(message);\n await chatHelpers.sendMessage(createMessage);\n },\n onEdit: async (message) => {\n const newMessages = sliceMessagesUntil(\n chatHelpers.messages,\n message.parentId,\n );\n chatHelpers.setMessages(newMessages);\n\n const createMessage = await toCreateMessage<UI_MESSAGE>(message);\n await chatHelpers.sendMessage(createMessage);\n },\n onReload: async (parentId: string | null) => {\n const newMessages = sliceMessagesUntil(chatHelpers.messages, parentId);\n chatHelpers.setMessages(newMessages);\n\n await chatHelpers.regenerate();\n },\n onAddToolResult: ({ toolCallId, result }) => {\n chatHelpers.addToolResult({\n tool: toolCallId,\n toolCallId,\n output: result,\n });\n },\n adapters: {\n attachments: vercelAttachmentAdapter,\n ...adapter.adapters,\n },\n isLoading,\n });\n\n return runtime;\n};\n"],"mappings":";;;AAGA;AAAA,EACE;AAAA,OAMK;AACP,SAAS,0BAA0B;AACnC,SAAS,uBAAuB;AAChC,SAAS,+BAA+B;AACxC,SAAS,2BAA2B;AACpC,SAAS,6BAA6B;AACtC;AAAA,EAEE;AAAA,OACK;AACP,SAAS,0BAA0B;AACnC,SAAS,eAAe;AAUjB,IAAM,kBAAkB,CAC7B,aACA,UAA+B,CAAC,MAC7B;AACH,QAAM,WAAW,sBAAsB,kBAAkB;AAAA,IACvD,WACE,YAAY,WAAW,eAAe,YAAY,UAAU;AAAA,IAC9D,UAAU,YAAY;AAAA,EACxB,CAAC;AAED,QAAM,YAAY;AAAA,IAChB;AAAA,MACE,OAAO;AAAA,QACL,IAAI,UAA4B;AAC9B,iBAAO;AAAA,QACT;AAAA,MACF;AAAA;AAAA,MAEA,CAAC;AAAA,IACH;AAAA,IACA,QAAQ,UAAU;AAAA,IAClB,sBAAsB;AAAA,IAGtB;AAAA,IAIA,CAACA,cAAa;AACZ,kBAAY,YAAYA,SAAQ;AAAA,IAClC;AAAA,EACF;AAEA,QAAM,UAAU,wBAAwB;AAAA,IACtC,WACE,YAAY,WAAW,eAAe,YAAY,WAAW;AAAA,IAC/D;AAAA,IACA,aAAa,CAACA,cACZ,YAAY;AAAA,MACVA,UAAS,IAAI,mBAA+B,EAAE,KAAK;AAAA,IACrD;AAAA,IACF,UAAU,YAAY,YAAY,KAAK;AAAA,IACvC,OAAO,OAAO,YAAY;AACxB,YAAM,gBAAgB,MAAM,gBAA4B,OAAO;AAC/D,YAAM,YAAY,YAAY,aAAa;AAAA,IAC7C;AAAA,IACA,QAAQ,OAAO,YAAY;AACzB,YAAM,cAAc;AAAA,QAClB,YAAY;AAAA,QACZ,QAAQ;AAAA,MACV;AACA,kBAAY,YAAY,WAAW;AAEnC,YAAM,gBAAgB,MAAM,gBAA4B,OAAO;AAC/D,YAAM,YAAY,YAAY,aAAa;AAAA,IAC7C;AAAA,IACA,UAAU,OAAO,aAA4B;AAC3C,YAAM,cAAc,mBAAmB,YAAY,UAAU,QAAQ;AACrE,kBAAY,YAAY,WAAW;AAEnC,YAAM,YAAY,WAAW;AAAA,IAC/B;AAAA,IACA,iBAAiB,CAAC,EAAE,YAAY,OAAO,MAAM;AAC3C,kBAAY,cAAc;AAAA,QACxB,MAAM;AAAA,QACN;AAAA,QACA,QAAQ;AAAA,MACV,CAAC;AAAA,IACH;AAAA,IACA,UAAU;AAAA,MACR,aAAa;AAAA,MACb,GAAG,QAAQ;AAAA,IACb;AAAA,IACA;AAAA,EACF,CAAC;AAED,SAAO;AACT;","names":["messages"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useChatRuntime.d.ts","sourceRoot":"","sources":["../../../src/ui/use-chat/useChatRuntime.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAW,KAAK,SAAS,EAAE,MAAM,eAAe,CAAC;AACxD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,EACL,gBAAgB,EAIjB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAmB,KAAK,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAC9E,OAAO,EAAE,QAAQ,EAAE,MAAM,IAAI,CAAC;AAG9B,MAAM,MAAM,qBAAqB,CAAC,UAAU,SAAS,SAAS,GAAG,SAAS,IACxE,QAAQ,CAAC,UAAU,CAAC,GAAG;IACrB,KAAK,CAAC,EAAE,cAAc,GAAG,SAAS,CAAC;IACnC,QAAQ,CAAC,EAAE,mBAAmB,CAAC,UAAU,CAAC,GAAG,SAAS,CAAC;CACxD,CAAC;AAEJ,eAAO,MAAM,oBAAoB,GAAI,UAAU,SAAS,SAAS,GAAG,SAAS,EAC3E,UAAU,qBAAqB,CAAC,UAAU,CAAC,KAC1C,
|
|
1
|
+
{"version":3,"file":"useChatRuntime.d.ts","sourceRoot":"","sources":["../../../src/ui/use-chat/useChatRuntime.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAW,KAAK,SAAS,EAAE,MAAM,eAAe,CAAC;AACxD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,EACL,gBAAgB,EAIjB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAmB,KAAK,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAC9E,OAAO,EAAE,QAAQ,EAAE,MAAM,IAAI,CAAC;AAG9B,MAAM,MAAM,qBAAqB,CAAC,UAAU,SAAS,SAAS,GAAG,SAAS,IACxE,QAAQ,CAAC,UAAU,CAAC,GAAG;IACrB,KAAK,CAAC,EAAE,cAAc,GAAG,SAAS,CAAC;IACnC,QAAQ,CAAC,EAAE,mBAAmB,CAAC,UAAU,CAAC,GAAG,SAAS,CAAC;CACxD,CAAC;AAEJ,eAAO,MAAM,oBAAoB,GAAI,UAAU,SAAS,SAAS,GAAG,SAAS,EAC3E,UAAU,qBAAqB,CAAC,UAAU,CAAC,KAC1C,gBAsDF,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,UAAU,SAAS,SAAS,GAAG,SAAS,EAAE,wBAGtE,qBAAqB,CAAC,UAAU,CAAM,KAAG,gBAQ3C,CAAC"}
|
|
@@ -19,7 +19,34 @@ var useChatThreadRuntime = (options) => {
|
|
|
19
19
|
const contextAdapters = useRuntimeAdapters();
|
|
20
20
|
const chat = useChat({
|
|
21
21
|
...chatOptions,
|
|
22
|
-
transport
|
|
22
|
+
transport,
|
|
23
|
+
onToolCall: async ({ toolCall }) => {
|
|
24
|
+
await chatOptions.onToolCall?.({ toolCall });
|
|
25
|
+
const tools = runtime.thread.getModelContext().tools;
|
|
26
|
+
const tool = tools?.[toolCall.toolName];
|
|
27
|
+
if (tool) {
|
|
28
|
+
try {
|
|
29
|
+
const result = await tool.execute?.(toolCall.input, {
|
|
30
|
+
toolCallId: toolCall.toolCallId,
|
|
31
|
+
abortSignal: new AbortController().signal
|
|
32
|
+
// dummy signal for now
|
|
33
|
+
});
|
|
34
|
+
chat.addToolResult({
|
|
35
|
+
tool: toolCall.toolName,
|
|
36
|
+
toolCallId: toolCall.toolCallId,
|
|
37
|
+
output: result
|
|
38
|
+
});
|
|
39
|
+
} catch (error) {
|
|
40
|
+
chat.addToolResult({
|
|
41
|
+
tool: toolCall.toolName,
|
|
42
|
+
toolCallId: toolCall.toolCallId,
|
|
43
|
+
output: {
|
|
44
|
+
error: error instanceof Error ? error.message : String(error)
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
23
50
|
});
|
|
24
51
|
const runtime = useAISDKRuntime(chat, {
|
|
25
52
|
adapters: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/ui/use-chat/useChatRuntime.tsx"],"sourcesContent":["\"use client\";\n\nimport { useChat, type UIMessage } from \"@ai-sdk/react\";\nimport type { AssistantCloud } from \"assistant-cloud\";\nimport {\n AssistantRuntime,\n unstable_useCloudThreadListAdapter,\n unstable_useRemoteThreadListRuntime,\n useRuntimeAdapters,\n} from \"@assistant-ui/react\";\nimport { useAISDKRuntime, type AISDKRuntimeAdapter } from \"./useAISDKRuntime\";\nimport { ChatInit } from \"ai\";\nimport { AssistantChatTransport } from \"./AssistantChatTransport\";\n\nexport type UseChatRuntimeOptions<UI_MESSAGE extends UIMessage = UIMessage> =\n ChatInit<UI_MESSAGE> & {\n cloud?: AssistantCloud | undefined;\n adapters?: AISDKRuntimeAdapter[\"adapters\"] | undefined;\n };\n\nexport const useChatThreadRuntime = <UI_MESSAGE extends UIMessage = UIMessage>(\n options?: UseChatRuntimeOptions<UI_MESSAGE>,\n): AssistantRuntime => {\n const {\n adapters,\n transport: transportOptions,\n ...chatOptions\n } = options ?? {};\n const transport = transportOptions ?? new AssistantChatTransport();\n\n // Get adapters from context (including history adapter from cloud)\n const contextAdapters = useRuntimeAdapters();\n\n const chat = useChat({\n ...chatOptions,\n transport,\n });\n\n const runtime = useAISDKRuntime(chat as any, {\n adapters: {\n ...contextAdapters,\n ...adapters,\n },\n });\n if (transport instanceof AssistantChatTransport) {\n transport.setRuntime(runtime);\n }\n\n return runtime;\n};\n\nexport const useChatRuntime = <UI_MESSAGE extends UIMessage = UIMessage>({\n cloud,\n ...options\n}: UseChatRuntimeOptions<UI_MESSAGE> = {}): AssistantRuntime => {\n const cloudAdapter = unstable_useCloudThreadListAdapter({ cloud });\n return unstable_useRemoteThreadListRuntime({\n runtimeHook: function RuntimeHook() {\n return useChatThreadRuntime(options);\n },\n adapter: cloudAdapter,\n });\n};\n"],"mappings":";;;AAEA,SAAS,eAA+B;AAExC;AAAA,EAEE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,uBAAiD;AAE1D,SAAS,8BAA8B;AAQhC,IAAM,uBAAuB,CAClC,YACqB;AACrB,QAAM;AAAA,IACJ;AAAA,IACA,WAAW;AAAA,IACX,GAAG;AAAA,EACL,IAAI,WAAW,CAAC;AAChB,QAAM,YAAY,oBAAoB,IAAI,uBAAuB;AAGjE,QAAM,kBAAkB,mBAAmB;AAE3C,QAAM,OAAO,QAAQ;AAAA,IACnB,GAAG;AAAA,IACH;AAAA,EACF,CAAC;AAED,QAAM,UAAU,gBAAgB,MAAa;AAAA,IAC3C,UAAU;AAAA,MACR,GAAG;AAAA,MACH,GAAG;AAAA,IACL;AAAA,EACF,CAAC;AACD,MAAI,qBAAqB,wBAAwB;AAC/C,cAAU,WAAW,OAAO;AAAA,EAC9B;AAEA,SAAO;AACT;AAEO,IAAM,iBAAiB,CAA2C;AAAA,EACvE;AAAA,EACA,GAAG;AACL,IAAuC,CAAC,MAAwB;AAC9D,QAAM,eAAe,mCAAmC,EAAE,MAAM,CAAC;AACjE,SAAO,oCAAoC;AAAA,IACzC,aAAa,SAAS,cAAc;AAClC,aAAO,qBAAqB,OAAO;AAAA,IACrC;AAAA,IACA,SAAS;AAAA,EACX,CAAC;AACH;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/ui/use-chat/useChatRuntime.tsx"],"sourcesContent":["\"use client\";\n\nimport { useChat, type UIMessage } from \"@ai-sdk/react\";\nimport type { AssistantCloud } from \"assistant-cloud\";\nimport {\n AssistantRuntime,\n unstable_useCloudThreadListAdapter,\n unstable_useRemoteThreadListRuntime,\n useRuntimeAdapters,\n} from \"@assistant-ui/react\";\nimport { useAISDKRuntime, type AISDKRuntimeAdapter } from \"./useAISDKRuntime\";\nimport { ChatInit } from \"ai\";\nimport { AssistantChatTransport } from \"./AssistantChatTransport\";\n\nexport type UseChatRuntimeOptions<UI_MESSAGE extends UIMessage = UIMessage> =\n ChatInit<UI_MESSAGE> & {\n cloud?: AssistantCloud | undefined;\n adapters?: AISDKRuntimeAdapter[\"adapters\"] | undefined;\n };\n\nexport const useChatThreadRuntime = <UI_MESSAGE extends UIMessage = UIMessage>(\n options?: UseChatRuntimeOptions<UI_MESSAGE>,\n): AssistantRuntime => {\n const {\n adapters,\n transport: transportOptions,\n ...chatOptions\n } = options ?? {};\n const transport = transportOptions ?? new AssistantChatTransport();\n\n // Get adapters from context (including history adapter from cloud)\n const contextAdapters = useRuntimeAdapters();\n\n const chat = useChat({\n ...chatOptions,\n transport,\n onToolCall: async ({ toolCall }) => {\n await chatOptions.onToolCall?.({ toolCall });\n\n const tools = runtime.thread.getModelContext().tools;\n const tool = tools?.[toolCall.toolName];\n if (tool) {\n try {\n const result = await tool.execute?.(toolCall.input, {\n toolCallId: toolCall.toolCallId,\n abortSignal: new AbortController().signal, // dummy signal for now\n });\n chat.addToolResult({\n tool: toolCall.toolName,\n toolCallId: toolCall.toolCallId,\n output: result,\n });\n } catch (error) {\n chat.addToolResult({\n tool: toolCall.toolName,\n toolCallId: toolCall.toolCallId,\n output: {\n error: error instanceof Error ? error.message : String(error),\n },\n });\n }\n }\n },\n });\n\n const runtime = useAISDKRuntime(chat as any, {\n adapters: {\n ...contextAdapters,\n ...adapters,\n },\n });\n if (transport instanceof AssistantChatTransport) {\n transport.setRuntime(runtime);\n }\n\n return runtime;\n};\n\nexport const useChatRuntime = <UI_MESSAGE extends UIMessage = UIMessage>({\n cloud,\n ...options\n}: UseChatRuntimeOptions<UI_MESSAGE> = {}): AssistantRuntime => {\n const cloudAdapter = unstable_useCloudThreadListAdapter({ cloud });\n return unstable_useRemoteThreadListRuntime({\n runtimeHook: function RuntimeHook() {\n return useChatThreadRuntime(options);\n },\n adapter: cloudAdapter,\n });\n};\n"],"mappings":";;;AAEA,SAAS,eAA+B;AAExC;AAAA,EAEE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,uBAAiD;AAE1D,SAAS,8BAA8B;AAQhC,IAAM,uBAAuB,CAClC,YACqB;AACrB,QAAM;AAAA,IACJ;AAAA,IACA,WAAW;AAAA,IACX,GAAG;AAAA,EACL,IAAI,WAAW,CAAC;AAChB,QAAM,YAAY,oBAAoB,IAAI,uBAAuB;AAGjE,QAAM,kBAAkB,mBAAmB;AAE3C,QAAM,OAAO,QAAQ;AAAA,IACnB,GAAG;AAAA,IACH;AAAA,IACA,YAAY,OAAO,EAAE,SAAS,MAAM;AAClC,YAAM,YAAY,aAAa,EAAE,SAAS,CAAC;AAE3C,YAAM,QAAQ,QAAQ,OAAO,gBAAgB,EAAE;AAC/C,YAAM,OAAO,QAAQ,SAAS,QAAQ;AACtC,UAAI,MAAM;AACR,YAAI;AACF,gBAAM,SAAS,MAAM,KAAK,UAAU,SAAS,OAAO;AAAA,YAClD,YAAY,SAAS;AAAA,YACrB,aAAa,IAAI,gBAAgB,EAAE;AAAA;AAAA,UACrC,CAAC;AACD,eAAK,cAAc;AAAA,YACjB,MAAM,SAAS;AAAA,YACf,YAAY,SAAS;AAAA,YACrB,QAAQ;AAAA,UACV,CAAC;AAAA,QACH,SAAS,OAAO;AACd,eAAK,cAAc;AAAA,YACjB,MAAM,SAAS;AAAA,YACf,YAAY,SAAS;AAAA,YACrB,QAAQ;AAAA,cACN,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,YAC9D;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,EACF,CAAC;AAED,QAAM,UAAU,gBAAgB,MAAa;AAAA,IAC3C,UAAU;AAAA,MACR,GAAG;AAAA,MACH,GAAG;AAAA,IACL;AAAA,EACF,CAAC;AACD,MAAI,qBAAqB,wBAAwB;AAC/C,cAAU,WAAW,OAAO;AAAA,EAC9B;AAEA,SAAO;AACT;AAEO,IAAM,iBAAiB,CAA2C;AAAA,EACvE;AAAA,EACA,GAAG;AACL,IAAuC,CAAC,MAAwB;AAC9D,QAAM,eAAe,mCAAmC,EAAE,MAAM,CAAC;AACjE,SAAO,oCAAoC;AAAA,IACzC,aAAa,SAAS,cAAc;AAClC,aAAO,qBAAqB,OAAO;AAAA,IACrC;AAAA,IACA,SAAS;AAAA,EACX,CAAC;AACH;","names":[]}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { UIMessage } from "ai";
|
|
2
|
-
export declare const sliceMessagesUntil: (messages:
|
|
2
|
+
export declare const sliceMessagesUntil: <UI_MESSAGE extends UIMessage = UIMessage>(messages: UI_MESSAGE[], messageId: string | null) => UI_MESSAGE[];
|
|
3
3
|
//# sourceMappingURL=sliceMessagesUntil.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sliceMessagesUntil.d.ts","sourceRoot":"","sources":["../../../src/ui/utils/sliceMessagesUntil.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AAEpC,eAAO,MAAM,kBAAkB,
|
|
1
|
+
{"version":3,"file":"sliceMessagesUntil.d.ts","sourceRoot":"","sources":["../../../src/ui/utils/sliceMessagesUntil.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AAEpC,eAAO,MAAM,kBAAkB,GAAI,UAAU,SAAS,SAAS,GAAG,SAAS,EACzE,UAAU,UAAU,EAAE,EACtB,WAAW,MAAM,GAAG,IAAI,iBAezB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/ui/utils/sliceMessagesUntil.tsx"],"sourcesContent":["import type { UIMessage } from \"ai\";\n\nexport const sliceMessagesUntil = (\n messages:
|
|
1
|
+
{"version":3,"sources":["../../../src/ui/utils/sliceMessagesUntil.tsx"],"sourcesContent":["import type { UIMessage } from \"ai\";\n\nexport const sliceMessagesUntil = <UI_MESSAGE extends UIMessage = UIMessage>(\n messages: UI_MESSAGE[],\n messageId: string | null,\n) => {\n if (messageId == null) return [];\n\n let messageIdx = messages.findIndex((m) => m.id === messageId);\n if (messageIdx === -1)\n throw new Error(\n \"useVercelAIThreadState: Message not found. This is likely an internal bug in assistant-ui.\",\n );\n\n while (messages[messageIdx + 1]?.role === \"assistant\") {\n messageIdx++;\n }\n\n return messages.slice(0, messageIdx + 1);\n};\n"],"mappings":";AAEO,IAAM,qBAAqB,CAChC,UACA,cACG;AACH,MAAI,aAAa,KAAM,QAAO,CAAC;AAE/B,MAAI,aAAa,SAAS,UAAU,CAAC,MAAM,EAAE,OAAO,SAAS;AAC7D,MAAI,eAAe;AACjB,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAEF,SAAO,SAAS,aAAa,CAAC,GAAG,SAAS,aAAa;AACrD;AAAA,EACF;AAEA,SAAO,SAAS,MAAM,GAAG,aAAa,CAAC;AACzC;","names":[]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { AppendMessage } from "@assistant-ui/react";
|
|
2
2
|
import { CreateUIMessage, UIMessage } from "ai";
|
|
3
|
-
export declare const toCreateMessage: (message: AppendMessage) => Promise<CreateUIMessage<
|
|
3
|
+
export declare const toCreateMessage: <UI_MESSAGE extends UIMessage = UIMessage>(message: AppendMessage) => Promise<CreateUIMessage<UI_MESSAGE>>;
|
|
4
4
|
//# sourceMappingURL=toCreateMessage.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toCreateMessage.d.ts","sourceRoot":"","sources":["../../../src/ui/utils/toCreateMessage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EACL,eAAe,EAIf,SAAS,EAGV,MAAM,IAAI,CAAC;AAEZ,eAAO,MAAM,eAAe,
|
|
1
|
+
{"version":3,"file":"toCreateMessage.d.ts","sourceRoot":"","sources":["../../../src/ui/utils/toCreateMessage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EACL,eAAe,EAIf,SAAS,EAGV,MAAM,IAAI,CAAC;AAEZ,eAAO,MAAM,eAAe,GAAU,UAAU,SAAS,SAAS,GAAG,SAAS,EAC5E,SAAS,aAAa,KACrB,OAAO,CAAC,eAAe,CAAC,UAAU,CAAC,CA+CrC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/ui/utils/toCreateMessage.ts"],"sourcesContent":["import { AppendMessage } from \"@assistant-ui/react\";\nimport {\n CreateUIMessage,\n FileUIPart,\n generateId,\n UIDataTypes,\n UIMessage,\n UIMessagePart,\n UITools,\n} from \"ai\";\n\nexport const toCreateMessage = async (\n message: AppendMessage,\n): Promise<CreateUIMessage<
|
|
1
|
+
{"version":3,"sources":["../../../src/ui/utils/toCreateMessage.ts"],"sourcesContent":["import { AppendMessage } from \"@assistant-ui/react\";\nimport {\n CreateUIMessage,\n FileUIPart,\n generateId,\n UIDataTypes,\n UIMessage,\n UIMessagePart,\n UITools,\n} from \"ai\";\n\nexport const toCreateMessage = async <UI_MESSAGE extends UIMessage = UIMessage>(\n message: AppendMessage,\n): Promise<CreateUIMessage<UI_MESSAGE>> => {\n const textParts = message.content\n .filter((part) => part.type === \"text\")\n .map((t) => t.text)\n .join(\"\\n\\n\");\n\n const parts: UIMessagePart<UIDataTypes, UITools>[] = [\n {\n type: \"text\",\n text: textParts,\n },\n ];\n\n // Add image parts\n const imageParts = message.content\n .filter((part) => part.type === \"image\")\n .map(\n (part) =>\n ({\n type: \"file\",\n mediaType: \"image/png\", // Default to PNG, could be made more dynamic\n url: part.image,\n }) satisfies FileUIPart,\n );\n\n parts.push(...imageParts);\n\n // Add attachment parts\n const attachmentParts = await Promise.all(\n (message.attachments ?? []).map(async (m) => {\n if (m.file == null) throw new Error(\"Attachment did not contain a file\");\n return {\n type: \"file\",\n mediaType: m.file.type,\n filename: m.file.name,\n url: await getFileDataURL(m.file),\n } satisfies FileUIPart;\n }),\n );\n\n parts.push(...attachmentParts);\n\n return {\n id: generateId(),\n role: message.role,\n parts,\n } satisfies CreateUIMessage<UIMessage> as CreateUIMessage<UI_MESSAGE>;\n};\n\nconst getFileDataURL = (file: File) =>\n new Promise<string>((resolve, reject) => {\n const reader = new FileReader();\n\n reader.onload = () => resolve(reader.result as string);\n reader.onerror = (error) => reject(error);\n\n reader.readAsDataURL(file);\n });\n"],"mappings":";AACA;AAAA,EAGE;AAAA,OAKK;AAEA,IAAM,kBAAkB,OAC7B,YACyC;AACzC,QAAM,YAAY,QAAQ,QACvB,OAAO,CAAC,SAAS,KAAK,SAAS,MAAM,EACrC,IAAI,CAAC,MAAM,EAAE,IAAI,EACjB,KAAK,MAAM;AAEd,QAAM,QAA+C;AAAA,IACnD;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,IACR;AAAA,EACF;AAGA,QAAM,aAAa,QAAQ,QACxB,OAAO,CAAC,SAAS,KAAK,SAAS,OAAO,EACtC;AAAA,IACC,CAAC,UACE;AAAA,MACC,MAAM;AAAA,MACN,WAAW;AAAA;AAAA,MACX,KAAK,KAAK;AAAA,IACZ;AAAA,EACJ;AAEF,QAAM,KAAK,GAAG,UAAU;AAGxB,QAAM,kBAAkB,MAAM,QAAQ;AAAA,KACnC,QAAQ,eAAe,CAAC,GAAG,IAAI,OAAO,MAAM;AAC3C,UAAI,EAAE,QAAQ,KAAM,OAAM,IAAI,MAAM,mCAAmC;AACvE,aAAO;AAAA,QACL,MAAM;AAAA,QACN,WAAW,EAAE,KAAK;AAAA,QAClB,UAAU,EAAE,KAAK;AAAA,QACjB,KAAK,MAAM,eAAe,EAAE,IAAI;AAAA,MAClC;AAAA,IACF,CAAC;AAAA,EACH;AAEA,QAAM,KAAK,GAAG,eAAe;AAE7B,SAAO;AAAA,IACL,IAAI,WAAW;AAAA,IACf,MAAM,QAAQ;AAAA,IACd;AAAA,EACF;AACF;AAEA,IAAM,iBAAiB,CAAC,SACtB,IAAI,QAAgB,CAAC,SAAS,WAAW;AACvC,QAAM,SAAS,IAAI,WAAW;AAE9B,SAAO,SAAS,MAAM,QAAQ,OAAO,MAAgB;AACrD,SAAO,UAAU,CAAC,UAAU,OAAO,KAAK;AAExC,SAAO,cAAc,IAAI;AAC3B,CAAC;","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@assistant-ui/react-ai-sdk",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -19,17 +19,17 @@
|
|
|
19
19
|
"sideEffects": false,
|
|
20
20
|
"dependencies": {
|
|
21
21
|
"@ai-sdk/provider": "^2.0.0",
|
|
22
|
-
"@ai-sdk/react": "^2.0.
|
|
23
|
-
"ai": "^5.0.
|
|
22
|
+
"@ai-sdk/react": "^2.0.15",
|
|
23
|
+
"ai": "^5.0.15",
|
|
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.23",
|
|
27
27
|
"json-schema": "^0.4.0",
|
|
28
|
-
"zod": "^4.0.
|
|
28
|
+
"zod": "^4.0.17",
|
|
29
29
|
"zustand": "^5.0.7"
|
|
30
30
|
},
|
|
31
31
|
"peerDependencies": {
|
|
32
|
-
"@assistant-ui/react": "^0.10.
|
|
32
|
+
"@assistant-ui/react": "^0.10.42",
|
|
33
33
|
"@types/react": "*",
|
|
34
34
|
"assistant-cloud": "*",
|
|
35
35
|
"react": "^18 || ^19 || ^19.0.0-rc"
|
|
@@ -43,13 +43,13 @@
|
|
|
43
43
|
}
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
|
-
"@types/node": "^24.
|
|
47
|
-
"@types/react": "^19.1.
|
|
46
|
+
"@types/node": "^24.3.0",
|
|
47
|
+
"@types/react": "^19.1.10",
|
|
48
48
|
"eslint": "^9",
|
|
49
|
-
"eslint-config-next": "15.4.
|
|
49
|
+
"eslint-config-next": "15.4.6",
|
|
50
50
|
"react": "19.1.1",
|
|
51
|
-
"tsx": "^4.20.
|
|
52
|
-
"@assistant-ui/react": "0.10.
|
|
51
|
+
"tsx": "^4.20.4",
|
|
52
|
+
"@assistant-ui/react": "0.10.42",
|
|
53
53
|
"@assistant-ui/x-buildutils": "0.0.1"
|
|
54
54
|
},
|
|
55
55
|
"publishConfig": {
|
package/src/frontendTools.ts
CHANGED
|
@@ -4,6 +4,8 @@ import {
|
|
|
4
4
|
} from "@assistant-ui/react";
|
|
5
5
|
import type { UIMessage } from "ai";
|
|
6
6
|
|
|
7
|
-
export const getVercelAIMessages =
|
|
8
|
-
|
|
7
|
+
export const getVercelAIMessages = <UI_MESSAGE extends UIMessage = UIMessage>(
|
|
8
|
+
message: ThreadMessage,
|
|
9
|
+
) => {
|
|
10
|
+
return getExternalStoreMessages(message) as UI_MESSAGE[];
|
|
9
11
|
};
|
|
@@ -1,18 +1,23 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
-
import type { useChat } from "@ai-sdk/react";
|
|
3
|
+
import type { UIMessage, useChat } from "@ai-sdk/react";
|
|
4
4
|
import {
|
|
5
5
|
useExternalStoreRuntime,
|
|
6
6
|
ExternalStoreAdapter,
|
|
7
7
|
ThreadHistoryAdapter,
|
|
8
8
|
AssistantRuntime,
|
|
9
|
+
ThreadMessage,
|
|
10
|
+
MessageFormatAdapter,
|
|
9
11
|
} from "@assistant-ui/react";
|
|
10
12
|
import { sliceMessagesUntil } from "../utils/sliceMessagesUntil";
|
|
11
13
|
import { toCreateMessage } from "../utils/toCreateMessage";
|
|
12
14
|
import { vercelAttachmentAdapter } from "../utils/vercelAttachmentAdapter";
|
|
13
15
|
import { getVercelAIMessages } from "../getVercelAIMessages";
|
|
14
16
|
import { AISDKMessageConverter } from "../utils/convertMessage";
|
|
15
|
-
import {
|
|
17
|
+
import {
|
|
18
|
+
AISDKStorageFormat,
|
|
19
|
+
aiSDKV5FormatAdapter,
|
|
20
|
+
} from "../adapters/aiSDKFormatAdapter";
|
|
16
21
|
import { useExternalHistory } from "./useExternalHistory";
|
|
17
22
|
import { useMemo } from "react";
|
|
18
23
|
|
|
@@ -24,8 +29,8 @@ export type AISDKRuntimeAdapter = {
|
|
|
24
29
|
| undefined;
|
|
25
30
|
};
|
|
26
31
|
|
|
27
|
-
export const useAISDKRuntime = (
|
|
28
|
-
chatHelpers: ReturnType<typeof useChat
|
|
32
|
+
export const useAISDKRuntime = <UI_MESSAGE extends UIMessage = UIMessage>(
|
|
33
|
+
chatHelpers: ReturnType<typeof useChat<UI_MESSAGE>>,
|
|
29
34
|
adapter: AISDKRuntimeAdapter = {},
|
|
30
35
|
) => {
|
|
31
36
|
const messages = AISDKMessageConverter.useThreadMessages({
|
|
@@ -45,8 +50,13 @@ export const useAISDKRuntime = (
|
|
|
45
50
|
[],
|
|
46
51
|
),
|
|
47
52
|
adapter.adapters?.history,
|
|
48
|
-
AISDKMessageConverter.toThreadMessages
|
|
49
|
-
|
|
53
|
+
AISDKMessageConverter.toThreadMessages as (
|
|
54
|
+
messages: UI_MESSAGE[],
|
|
55
|
+
) => ThreadMessage[],
|
|
56
|
+
aiSDKV5FormatAdapter as MessageFormatAdapter<
|
|
57
|
+
UI_MESSAGE,
|
|
58
|
+
AISDKStorageFormat
|
|
59
|
+
>,
|
|
50
60
|
(messages) => {
|
|
51
61
|
chatHelpers.setMessages(messages);
|
|
52
62
|
},
|
|
@@ -57,10 +67,12 @@ export const useAISDKRuntime = (
|
|
|
57
67
|
chatHelpers.status === "submitted" || chatHelpers.status === "streaming",
|
|
58
68
|
messages,
|
|
59
69
|
setMessages: (messages) =>
|
|
60
|
-
chatHelpers.setMessages(
|
|
70
|
+
chatHelpers.setMessages(
|
|
71
|
+
messages.map(getVercelAIMessages<UI_MESSAGE>).flat(),
|
|
72
|
+
),
|
|
61
73
|
onCancel: async () => chatHelpers.stop(),
|
|
62
74
|
onNew: async (message) => {
|
|
63
|
-
const createMessage = await toCreateMessage(message);
|
|
75
|
+
const createMessage = await toCreateMessage<UI_MESSAGE>(message);
|
|
64
76
|
await chatHelpers.sendMessage(createMessage);
|
|
65
77
|
},
|
|
66
78
|
onEdit: async (message) => {
|
|
@@ -70,7 +82,7 @@ export const useAISDKRuntime = (
|
|
|
70
82
|
);
|
|
71
83
|
chatHelpers.setMessages(newMessages);
|
|
72
84
|
|
|
73
|
-
const createMessage = await toCreateMessage(message);
|
|
85
|
+
const createMessage = await toCreateMessage<UI_MESSAGE>(message);
|
|
74
86
|
await chatHelpers.sendMessage(createMessage);
|
|
75
87
|
},
|
|
76
88
|
onReload: async (parentId: string | null) => {
|
|
@@ -34,6 +34,33 @@ export const useChatThreadRuntime = <UI_MESSAGE extends UIMessage = UIMessage>(
|
|
|
34
34
|
const chat = useChat({
|
|
35
35
|
...chatOptions,
|
|
36
36
|
transport,
|
|
37
|
+
onToolCall: async ({ toolCall }) => {
|
|
38
|
+
await chatOptions.onToolCall?.({ toolCall });
|
|
39
|
+
|
|
40
|
+
const tools = runtime.thread.getModelContext().tools;
|
|
41
|
+
const tool = tools?.[toolCall.toolName];
|
|
42
|
+
if (tool) {
|
|
43
|
+
try {
|
|
44
|
+
const result = await tool.execute?.(toolCall.input, {
|
|
45
|
+
toolCallId: toolCall.toolCallId,
|
|
46
|
+
abortSignal: new AbortController().signal, // dummy signal for now
|
|
47
|
+
});
|
|
48
|
+
chat.addToolResult({
|
|
49
|
+
tool: toolCall.toolName,
|
|
50
|
+
toolCallId: toolCall.toolCallId,
|
|
51
|
+
output: result,
|
|
52
|
+
});
|
|
53
|
+
} catch (error) {
|
|
54
|
+
chat.addToolResult({
|
|
55
|
+
tool: toolCall.toolName,
|
|
56
|
+
toolCallId: toolCall.toolCallId,
|
|
57
|
+
output: {
|
|
58
|
+
error: error instanceof Error ? error.message : String(error),
|
|
59
|
+
},
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
},
|
|
37
64
|
});
|
|
38
65
|
|
|
39
66
|
const runtime = useAISDKRuntime(chat as any, {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { UIMessage } from "ai";
|
|
2
2
|
|
|
3
|
-
export const sliceMessagesUntil = (
|
|
4
|
-
messages:
|
|
3
|
+
export const sliceMessagesUntil = <UI_MESSAGE extends UIMessage = UIMessage>(
|
|
4
|
+
messages: UI_MESSAGE[],
|
|
5
5
|
messageId: string | null,
|
|
6
6
|
) => {
|
|
7
7
|
if (messageId == null) return [];
|
|
@@ -9,9 +9,9 @@ import {
|
|
|
9
9
|
UITools,
|
|
10
10
|
} from "ai";
|
|
11
11
|
|
|
12
|
-
export const toCreateMessage = async (
|
|
12
|
+
export const toCreateMessage = async <UI_MESSAGE extends UIMessage = UIMessage>(
|
|
13
13
|
message: AppendMessage,
|
|
14
|
-
): Promise<CreateUIMessage<
|
|
14
|
+
): Promise<CreateUIMessage<UI_MESSAGE>> => {
|
|
15
15
|
const textParts = message.content
|
|
16
16
|
.filter((part) => part.type === "text")
|
|
17
17
|
.map((t) => t.text)
|
|
@@ -57,7 +57,7 @@ export const toCreateMessage = async (
|
|
|
57
57
|
id: generateId(),
|
|
58
58
|
role: message.role,
|
|
59
59
|
parts,
|
|
60
|
-
}
|
|
60
|
+
} satisfies CreateUIMessage<UIMessage> as CreateUIMessage<UI_MESSAGE>;
|
|
61
61
|
};
|
|
62
62
|
|
|
63
63
|
const getFileDataURL = (file: File) =>
|