@assistant-ui/react-ai-sdk 0.6.8 → 0.6.10
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.mts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +23 -20
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +16 -15
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -2
package/dist/index.d.mts
CHANGED
|
@@ -36,13 +36,13 @@ type VercelRSCAdapterBase<T> = {
|
|
|
36
36
|
};
|
|
37
37
|
type VercelRSCAdapter<T = VercelRSCMessage> = VercelRSCAdapterBase<T> & (T extends VercelRSCMessage ? object : RSCMessageConverter<T>);
|
|
38
38
|
|
|
39
|
-
declare const useVercelRSCRuntime: <T extends WeakKey>(adapter: VercelRSCAdapter<T>) => _assistant_ui_react.
|
|
39
|
+
declare const useVercelRSCRuntime: <T extends WeakKey>(adapter: VercelRSCAdapter<T>) => _assistant_ui_react.AssistantRuntime<_assistant_ui_react.ThreadRuntime>;
|
|
40
40
|
|
|
41
41
|
declare const getVercelRSCMessage: (message: ThreadMessage) => unknown;
|
|
42
42
|
|
|
43
|
-
declare const useVercelUseChatRuntime: (chatHelpers: ReturnType<typeof useChat>) => _assistant_ui_react.
|
|
43
|
+
declare const useVercelUseChatRuntime: (chatHelpers: ReturnType<typeof useChat>) => _assistant_ui_react.AssistantRuntime<_assistant_ui_react.ThreadRuntime>;
|
|
44
44
|
|
|
45
|
-
declare const useVercelUseAssistantRuntime: (assistantHelpers: ReturnType<typeof useAssistant>) => _assistant_ui_react.
|
|
45
|
+
declare const useVercelUseAssistantRuntime: (assistantHelpers: ReturnType<typeof useAssistant>) => _assistant_ui_react.AssistantRuntime<_assistant_ui_react.ThreadRuntime>;
|
|
46
46
|
|
|
47
47
|
declare const getVercelAIMessages: (message: ThreadMessage) => Message[];
|
|
48
48
|
|
package/dist/index.d.ts
CHANGED
|
@@ -36,13 +36,13 @@ type VercelRSCAdapterBase<T> = {
|
|
|
36
36
|
};
|
|
37
37
|
type VercelRSCAdapter<T = VercelRSCMessage> = VercelRSCAdapterBase<T> & (T extends VercelRSCMessage ? object : RSCMessageConverter<T>);
|
|
38
38
|
|
|
39
|
-
declare const useVercelRSCRuntime: <T extends WeakKey>(adapter: VercelRSCAdapter<T>) => _assistant_ui_react.
|
|
39
|
+
declare const useVercelRSCRuntime: <T extends WeakKey>(adapter: VercelRSCAdapter<T>) => _assistant_ui_react.AssistantRuntime<_assistant_ui_react.ThreadRuntime>;
|
|
40
40
|
|
|
41
41
|
declare const getVercelRSCMessage: (message: ThreadMessage) => unknown;
|
|
42
42
|
|
|
43
|
-
declare const useVercelUseChatRuntime: (chatHelpers: ReturnType<typeof useChat>) => _assistant_ui_react.
|
|
43
|
+
declare const useVercelUseChatRuntime: (chatHelpers: ReturnType<typeof useChat>) => _assistant_ui_react.AssistantRuntime<_assistant_ui_react.ThreadRuntime>;
|
|
44
44
|
|
|
45
|
-
declare const useVercelUseAssistantRuntime: (assistantHelpers: ReturnType<typeof useAssistant>) => _assistant_ui_react.
|
|
45
|
+
declare const useVercelUseAssistantRuntime: (assistantHelpers: ReturnType<typeof useAssistant>) => _assistant_ui_react.AssistantRuntime<_assistant_ui_react.ThreadRuntime>;
|
|
46
46
|
|
|
47
47
|
declare const getVercelAIMessages: (message: ThreadMessage) => Message[];
|
|
48
48
|
|
package/dist/index.js
CHANGED
|
@@ -83,7 +83,8 @@ var convertMessage = (message) => {
|
|
|
83
83
|
id: idx.toString(),
|
|
84
84
|
type: "file",
|
|
85
85
|
name: attachment.name ?? attachment.url,
|
|
86
|
-
content: []
|
|
86
|
+
content: [],
|
|
87
|
+
status: { type: "complete" }
|
|
87
88
|
})
|
|
88
89
|
)
|
|
89
90
|
};
|
|
@@ -147,26 +148,25 @@ var convertMessage = (message) => {
|
|
|
147
148
|
};
|
|
148
149
|
|
|
149
150
|
// src/ui/use-chat/useVercelUseChatRuntime.tsx
|
|
150
|
-
var
|
|
151
|
+
var import_react5 = require("@assistant-ui/react");
|
|
151
152
|
|
|
152
153
|
// src/ui/utils/useInputSync.tsx
|
|
153
154
|
var import_react3 = require("react");
|
|
154
|
-
var
|
|
155
|
+
var import_react_use_callback_ref = require("@radix-ui/react-use-callback-ref");
|
|
155
156
|
var useInputSync = (helpers, runtime) => {
|
|
156
|
-
const helpersRef = (0, import_react3.useRef)(helpers);
|
|
157
157
|
(0, import_react3.useEffect)(() => {
|
|
158
|
-
|
|
159
|
-
if (runtime.thread.composer.text !== helpers.input) {
|
|
158
|
+
if (runtime.thread.composer.getState().text !== helpers.input) {
|
|
160
159
|
runtime.thread.composer.setText(helpers.input);
|
|
161
160
|
}
|
|
162
161
|
}, [helpers, runtime]);
|
|
162
|
+
const handleThreadUpdate = (0, import_react_use_callback_ref.useCallbackRef)(() => {
|
|
163
|
+
if (runtime.thread.composer.getState().text !== helpers.input) {
|
|
164
|
+
helpers.setInput(runtime.thread.composer.getState().text);
|
|
165
|
+
}
|
|
166
|
+
});
|
|
163
167
|
(0, import_react3.useEffect)(() => {
|
|
164
|
-
return
|
|
165
|
-
|
|
166
|
-
helpersRef.current.setInput(runtime.thread.composer.text);
|
|
167
|
-
}
|
|
168
|
-
});
|
|
169
|
-
}, [runtime]);
|
|
168
|
+
return runtime.thread.subscribe(handleThreadUpdate);
|
|
169
|
+
}, [runtime, handleThreadUpdate]);
|
|
170
170
|
};
|
|
171
171
|
|
|
172
172
|
// src/ui/utils/sliceMessagesUntil.tsx
|
|
@@ -223,12 +223,15 @@ var vercelAttachmentAdapter = {
|
|
|
223
223
|
type: "file",
|
|
224
224
|
name: file.name,
|
|
225
225
|
file,
|
|
226
|
-
|
|
226
|
+
contentType: file.type,
|
|
227
|
+
content: [],
|
|
228
|
+
status: { type: "requires-action", reason: "composer-send" }
|
|
227
229
|
};
|
|
228
230
|
},
|
|
229
231
|
async send(attachment) {
|
|
230
232
|
return {
|
|
231
233
|
...attachment,
|
|
234
|
+
status: { type: "complete" },
|
|
232
235
|
content: []
|
|
233
236
|
};
|
|
234
237
|
},
|
|
@@ -237,19 +240,19 @@ var vercelAttachmentAdapter = {
|
|
|
237
240
|
};
|
|
238
241
|
|
|
239
242
|
// src/ui/getVercelAIMessages.tsx
|
|
240
|
-
var
|
|
243
|
+
var import_react4 = require("@assistant-ui/react");
|
|
241
244
|
var getVercelAIMessages = (message) => {
|
|
242
|
-
return (0,
|
|
245
|
+
return (0, import_react4.getExternalStoreMessage)(message);
|
|
243
246
|
};
|
|
244
247
|
|
|
245
248
|
// src/ui/use-chat/useVercelUseChatRuntime.tsx
|
|
246
249
|
var useVercelUseChatRuntime = (chatHelpers) => {
|
|
247
|
-
const messages = (0,
|
|
250
|
+
const messages = (0, import_react5.useExternalMessageConverter)({
|
|
248
251
|
callback: convertMessage,
|
|
249
252
|
isRunning: chatHelpers.isLoading,
|
|
250
253
|
messages: chatHelpers.messages
|
|
251
254
|
});
|
|
252
|
-
const runtime = (0,
|
|
255
|
+
const runtime = (0, import_react5.useExternalStoreRuntime)({
|
|
253
256
|
isRunning: chatHelpers.isLoading,
|
|
254
257
|
messages,
|
|
255
258
|
setMessages: (messages2) => chatHelpers.setMessages(messages2.map(getVercelAIMessages).flat()),
|
|
@@ -288,14 +291,14 @@ var useVercelUseChatRuntime = (chatHelpers) => {
|
|
|
288
291
|
};
|
|
289
292
|
|
|
290
293
|
// src/ui/use-assistant/useVercelUseAssistantRuntime.tsx
|
|
291
|
-
var
|
|
294
|
+
var import_react6 = require("@assistant-ui/react");
|
|
292
295
|
var useVercelUseAssistantRuntime = (assistantHelpers) => {
|
|
293
|
-
const messages = (0,
|
|
296
|
+
const messages = (0, import_react6.useExternalMessageConverter)({
|
|
294
297
|
callback: convertMessage,
|
|
295
298
|
isRunning: assistantHelpers.status === "in_progress",
|
|
296
299
|
messages: assistantHelpers.messages
|
|
297
300
|
});
|
|
298
|
-
const runtime = (0,
|
|
301
|
+
const runtime = (0, import_react6.useExternalStoreRuntime)({
|
|
299
302
|
isRunning: assistantHelpers.status === "in_progress",
|
|
300
303
|
messages,
|
|
301
304
|
onCancel: async () => assistantHelpers.stop(),
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/rsc/useVercelRSCRuntime.tsx","../src/rsc/getVercelRSCMessage.tsx","../src/ui/utils/convertMessage.ts","../src/ui/use-chat/useVercelUseChatRuntime.tsx","../src/ui/utils/useInputSync.tsx","../src/ui/utils/sliceMessagesUntil.tsx","../src/ui/utils/toCreateMessage.ts","../src/ui/utils/vercelAttachmentAdapter.ts","../src/ui/getVercelAIMessages.tsx","../src/ui/use-assistant/useVercelUseAssistantRuntime.tsx"],"sourcesContent":["export * from \"./rsc\";\nexport * from \"./ui\";\n","\"use client\";\n\nimport type { VercelRSCAdapter } from \"./VercelRSCAdapter\";\nimport {\n ExternalStoreAdapter,\n ThreadMessageLike,\n useExternalStoreRuntime,\n} from \"@assistant-ui/react\";\nimport { VercelRSCMessage } from \"./VercelRSCMessage\";\n\nconst vercelToThreadMessage = <T,>(\n converter: (message: T) => VercelRSCMessage,\n rawMessage: T,\n): ThreadMessageLike => {\n const message = converter(rawMessage);\n\n return {\n id: message.id,\n role: message.role,\n content: [{ type: \"ui\", display: message.display }],\n createdAt: message.createdAt,\n };\n};\n\nexport const useVercelRSCRuntime = <T extends WeakKey>(\n adapter: VercelRSCAdapter<T>,\n) => {\n const onNew = adapter.onNew ?? adapter.append;\n if (!onNew)\n throw new Error(\"You must pass a onNew function to useVercelRSCRuntime\");\n const eAdapter: ExternalStoreAdapter<any> = {\n isRunning: adapter.isRunning,\n messages: adapter.messages,\n onNew,\n onEdit: adapter.onEdit ?? adapter.edit,\n onReload: adapter.onReload ?? adapter.reload,\n convertMessage: (m: T) =>\n vercelToThreadMessage(\n adapter.convertMessage ?? ((m) => m as VercelRSCMessage),\n m,\n ),\n unstable_capabilities: {\n copy: false,\n },\n };\n\n const runtime = useExternalStoreRuntime(eAdapter);\n return runtime;\n};\n","import {\n getExternalStoreMessage,\n type ThreadMessage,\n} from \"@assistant-ui/react\";\n\nexport const symbolInnerRSCMessage = Symbol(\"innerVercelRSCMessage\");\n\nexport const getVercelRSCMessage = (message: ThreadMessage) => {\n return getExternalStoreMessage(message);\n};\n","import { Message } from \"ai\";\nimport { useExternalMessageConverter } from \"@assistant-ui/react\";\nimport { ToolCallContentPart } from \"@assistant-ui/react\";\nimport { TextContentPart } from \"@assistant-ui/react\";\nimport { MessageAttachment } from \"../../../../react/src/context/stores/Attachment\";\n\nexport const convertMessage: useExternalMessageConverter.Callback<Message> = (\n message,\n) => {\n switch (message.role) {\n case \"user\":\n return {\n role: \"user\",\n id: message.id,\n createdAt: message.createdAt,\n content: message.content,\n\n attachments: message.experimental_attachments?.map(\n (attachment, idx) =>\n ({\n id: idx.toString(),\n type: \"file\",\n name: attachment.name ?? attachment.url,\n content: [],\n }) satisfies MessageAttachment,\n ),\n };\n\n case \"system\":\n return {\n role: \"system\",\n id: message.id,\n createdAt: message.createdAt,\n content: message.content,\n };\n\n case \"assistant\":\n return {\n role: \"assistant\",\n id: message.id,\n createdAt: message.createdAt,\n content: [\n ...(message.content\n ? [\n {\n type: \"text\",\n text: message.content,\n } satisfies TextContentPart,\n ]\n : []),\n ...(message.toolInvocations?.map(\n (t) =>\n ({\n type: \"tool-call\",\n toolName: t.toolName,\n toolCallId: t.toolCallId,\n argsText: JSON.stringify(t.args),\n args: t.args,\n result: \"result\" in t ? t.result : undefined,\n }) satisfies ToolCallContentPart,\n ) ?? []),\n ],\n };\n\n case \"data\": {\n type MaybeSupportedDataMessage =\n | { type?: \"unsafe_other\" }\n | ToolCallContentPart\n | {\n type: \"tool-result\";\n toolCallId: string;\n result: any;\n };\n\n if (\n !message.data ||\n !(typeof message.data === \"object\") ||\n Array.isArray(message.data)\n )\n return [];\n\n const data = message.data as MaybeSupportedDataMessage;\n\n if (data.type === \"tool-call\") {\n return {\n role: \"assistant\",\n id: message.id,\n createdAt: message.createdAt,\n content: [data],\n };\n } else if (data.type === \"tool-result\") {\n return {\n role: \"tool\",\n toolCallId: data.toolCallId,\n result: data.result,\n };\n }\n return [];\n }\n\n default:\n // TODO handle tool and function messages\n const _unsupported: \"function\" | \"tool\" = message.role;\n throw new Error(\n `You have a message with an unsupported role. The role ${_unsupported} is not supported.`,\n );\n }\n};\n","import type { useChat } from \"ai/react\";\nimport { convertMessage } from \"../utils/convertMessage\";\nimport {\n useExternalMessageConverter,\n useExternalStoreRuntime,\n} from \"@assistant-ui/react\";\nimport { useInputSync } from \"../utils/useInputSync\";\nimport { sliceMessagesUntil } from \"../utils/sliceMessagesUntil\";\nimport { toCreateMessage } from \"../utils/toCreateMessage\";\nimport { vercelAttachmentAdapter } from \"../utils/vercelAttachmentAdapter\";\nimport { getVercelAIMessages } from \"../getVercelAIMessages\";\n\nexport const useVercelUseChatRuntime = (\n chatHelpers: ReturnType<typeof useChat>,\n) => {\n const messages = useExternalMessageConverter({\n callback: convertMessage,\n isRunning: chatHelpers.isLoading,\n messages: chatHelpers.messages,\n });\n\n const runtime = useExternalStoreRuntime({\n isRunning: chatHelpers.isLoading,\n messages,\n setMessages: (messages) =>\n chatHelpers.setMessages(messages.map(getVercelAIMessages).flat()),\n onCancel: async () => chatHelpers.stop(),\n onNew: async (message) => {\n await chatHelpers.append(await toCreateMessage(message));\n },\n onEdit: async (message) => {\n const newMessages = sliceMessagesUntil(\n chatHelpers.messages,\n message.parentId,\n );\n chatHelpers.setMessages(newMessages);\n\n await chatHelpers.append(await toCreateMessage(message));\n },\n onReload: async (parentId: string | null) => {\n const newMessages = sliceMessagesUntil(chatHelpers.messages, parentId);\n chatHelpers.setMessages(newMessages);\n\n await chatHelpers.reload();\n },\n onAddToolResult: ({ toolCallId, result }) => {\n chatHelpers.addToolResult({ toolCallId, result });\n },\n onSwitchToNewThread: () => {\n chatHelpers.messages = [];\n chatHelpers.input = \"\";\n chatHelpers.setMessages([]);\n chatHelpers.setInput(\"\");\n },\n adapters: {\n attachments: vercelAttachmentAdapter,\n },\n });\n\n useInputSync(chatHelpers, runtime);\n\n return runtime;\n};\n","import { useRef, useEffect } from \"react\";\nimport {\n ExternalStoreRuntime,\n subscribeToMainThread,\n} from \"@assistant-ui/react\";\nimport { useAssistant, useChat } from \"ai/react\";\n\ntype VercelHelpers =\n | ReturnType<typeof useChat>\n | ReturnType<typeof useAssistant>;\n\nexport const useInputSync = (\n helpers: VercelHelpers,\n runtime: ExternalStoreRuntime,\n) => {\n // sync input from vercel to assistant-ui\n const helpersRef = useRef(helpers);\n useEffect(() => {\n helpersRef.current = helpers;\n if (runtime.thread.composer.text !== helpers.input) {\n runtime.thread.composer.setText(helpers.input);\n }\n }, [helpers, runtime]);\n\n // sync input from assistant-ui to vercel\n useEffect(() => {\n return subscribeToMainThread(runtime, () => {\n if (runtime.thread.composer.text !== helpersRef.current.input) {\n helpersRef.current.setInput(runtime.thread.composer.text);\n }\n });\n }, [runtime]);\n};\n","import type { Message } from \"ai\";\n\nexport const sliceMessagesUntil = (\n messages: 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 liekly 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","import { AppendMessage } from \"@assistant-ui/react\";\nimport { CreateMessage } from \"ai\";\n\nexport const toCreateMessage = async (\n message: AppendMessage,\n): Promise<CreateMessage> => {\n const content = message.content\n .filter((part) => part.type === \"text\")\n .map((t) => t.text)\n .join(\"\\n\\n\");\n\n const images = message.content\n .filter((part) => part.type === \"image\")\n .map((part) => ({ url: part.image }));\n\n return {\n role: message.role,\n content,\n experimental_attachments: [\n ...images,\n ...(await Promise.all(\n (message.attachments ?? []).map(async (m) => {\n if (m.file == null)\n throw new Error(\"Attachment did not contain a file\");\n return {\n contentType: m.file.type,\n name: m.file.name,\n url: await getFileDataURL(m.file),\n };\n }),\n )),\n ],\n };\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","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 content: [],\n };\n },\n async send(attachment) {\n // noop\n return {\n ...attachment,\n content: [],\n };\n },\n async remove() {\n // noop\n },\n};\n","import {\n getExternalStoreMessage,\n type ThreadMessage,\n} from \"@assistant-ui/react\";\nimport type { Message } from \"ai\";\n\nexport const getVercelAIMessages = (message: ThreadMessage) => {\n return getExternalStoreMessage(message) as Message[];\n};\n","import type { useAssistant } from \"ai/react\";\nimport {\n useExternalMessageConverter,\n useExternalStoreRuntime,\n} from \"@assistant-ui/react\";\nimport { convertMessage } from \"../utils/convertMessage\";\nimport { useInputSync } from \"../utils/useInputSync\";\nimport { toCreateMessage } from \"../utils/toCreateMessage\";\nimport { vercelAttachmentAdapter } from \"../utils/vercelAttachmentAdapter\";\n\nexport const useVercelUseAssistantRuntime = (\n assistantHelpers: ReturnType<typeof useAssistant>,\n) => {\n const messages = useExternalMessageConverter({\n callback: convertMessage,\n isRunning: assistantHelpers.status === \"in_progress\",\n messages: assistantHelpers.messages,\n });\n const runtime = useExternalStoreRuntime({\n isRunning: assistantHelpers.status === \"in_progress\",\n messages,\n onCancel: async () => assistantHelpers.stop(),\n onNew: async (message) => {\n await assistantHelpers.append(await toCreateMessage(message));\n },\n onSwitchToNewThread: () => {\n assistantHelpers.messages = [];\n assistantHelpers.input = \"\";\n assistantHelpers.setMessages([]);\n assistantHelpers.setInput(\"\");\n },\n adapters: {\n attachments: vercelAttachmentAdapter,\n },\n });\n\n useInputSync(assistantHelpers, runtime);\n\n return runtime;\n};\n"],"mappings":"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","names":["m","import_react","import_react","import_react","import_react","messages","import_react"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/rsc/useVercelRSCRuntime.tsx","../src/rsc/getVercelRSCMessage.tsx","../src/ui/utils/convertMessage.ts","../src/ui/use-chat/useVercelUseChatRuntime.tsx","../src/ui/utils/useInputSync.tsx","../src/ui/utils/sliceMessagesUntil.tsx","../src/ui/utils/toCreateMessage.ts","../src/ui/utils/vercelAttachmentAdapter.ts","../src/ui/getVercelAIMessages.tsx","../src/ui/use-assistant/useVercelUseAssistantRuntime.tsx"],"sourcesContent":["export * from \"./rsc\";\nexport * from \"./ui\";\n","\"use client\";\n\nimport type { VercelRSCAdapter } from \"./VercelRSCAdapter\";\nimport {\n ExternalStoreAdapter,\n ThreadMessageLike,\n useExternalStoreRuntime,\n} from \"@assistant-ui/react\";\nimport { VercelRSCMessage } from \"./VercelRSCMessage\";\n\nconst vercelToThreadMessage = <T,>(\n converter: (message: T) => VercelRSCMessage,\n rawMessage: T,\n): ThreadMessageLike => {\n const message = converter(rawMessage);\n\n return {\n id: message.id,\n role: message.role,\n content: [{ type: \"ui\", display: message.display }],\n createdAt: message.createdAt,\n };\n};\n\nexport const useVercelRSCRuntime = <T extends WeakKey>(\n adapter: VercelRSCAdapter<T>,\n) => {\n const onNew = adapter.onNew ?? adapter.append;\n if (!onNew)\n throw new Error(\"You must pass a onNew function to useVercelRSCRuntime\");\n const eAdapter: ExternalStoreAdapter<any> = {\n isRunning: adapter.isRunning,\n messages: adapter.messages,\n onNew,\n onEdit: adapter.onEdit ?? adapter.edit,\n onReload: adapter.onReload ?? adapter.reload,\n convertMessage: (m: T) =>\n vercelToThreadMessage(\n adapter.convertMessage ?? ((m) => m as VercelRSCMessage),\n m,\n ),\n unstable_capabilities: {\n copy: false,\n },\n };\n\n const runtime = useExternalStoreRuntime(eAdapter);\n return runtime;\n};\n","import {\n getExternalStoreMessage,\n type ThreadMessage,\n} from \"@assistant-ui/react\";\n\nexport const symbolInnerRSCMessage = Symbol(\"innerVercelRSCMessage\");\n\nexport const getVercelRSCMessage = (message: ThreadMessage) => {\n return getExternalStoreMessage(message);\n};\n","import { Message } from \"ai\";\nimport { useExternalMessageConverter } from \"@assistant-ui/react\";\nimport { ToolCallContentPart } from \"@assistant-ui/react\";\nimport { TextContentPart } from \"@assistant-ui/react\";\nimport { CompleteAttachment } from \"@assistant-ui/react\";\n\nexport const convertMessage: useExternalMessageConverter.Callback<Message> = (\n message,\n) => {\n switch (message.role) {\n case \"user\":\n return {\n role: \"user\",\n id: message.id,\n createdAt: message.createdAt,\n content: message.content,\n\n attachments: message.experimental_attachments?.map(\n (attachment, idx) =>\n ({\n id: idx.toString(),\n type: \"file\",\n name: attachment.name ?? attachment.url,\n content: [],\n status: { type: \"complete\" },\n }) satisfies CompleteAttachment,\n ),\n };\n\n case \"system\":\n return {\n role: \"system\",\n id: message.id,\n createdAt: message.createdAt,\n content: message.content,\n };\n\n case \"assistant\":\n return {\n role: \"assistant\",\n id: message.id,\n createdAt: message.createdAt,\n content: [\n ...(message.content\n ? [\n {\n type: \"text\",\n text: message.content,\n } satisfies TextContentPart,\n ]\n : []),\n ...(message.toolInvocations?.map(\n (t) =>\n ({\n type: \"tool-call\",\n toolName: t.toolName,\n toolCallId: t.toolCallId,\n argsText: JSON.stringify(t.args),\n args: t.args,\n result: \"result\" in t ? t.result : undefined,\n }) satisfies ToolCallContentPart,\n ) ?? []),\n ],\n };\n\n case \"data\": {\n type MaybeSupportedDataMessage =\n | { type?: \"unsafe_other\" }\n | ToolCallContentPart\n | {\n type: \"tool-result\";\n toolCallId: string;\n result: any;\n };\n\n if (\n !message.data ||\n !(typeof message.data === \"object\") ||\n Array.isArray(message.data)\n )\n return [];\n\n const data = message.data as MaybeSupportedDataMessage;\n\n if (data.type === \"tool-call\") {\n return {\n role: \"assistant\",\n id: message.id,\n createdAt: message.createdAt,\n content: [data],\n };\n } else if (data.type === \"tool-result\") {\n return {\n role: \"tool\",\n toolCallId: data.toolCallId,\n result: data.result,\n };\n }\n return [];\n }\n\n default:\n // TODO handle tool and function messages\n const _unsupported: \"function\" | \"tool\" = message.role;\n throw new Error(\n `You have a message with an unsupported role. The role ${_unsupported} is not supported.`,\n );\n }\n};\n","import type { useChat } from \"ai/react\";\nimport { convertMessage } from \"../utils/convertMessage\";\nimport {\n useExternalMessageConverter,\n useExternalStoreRuntime,\n} from \"@assistant-ui/react\";\nimport { useInputSync } from \"../utils/useInputSync\";\nimport { sliceMessagesUntil } from \"../utils/sliceMessagesUntil\";\nimport { toCreateMessage } from \"../utils/toCreateMessage\";\nimport { vercelAttachmentAdapter } from \"../utils/vercelAttachmentAdapter\";\nimport { getVercelAIMessages } from \"../getVercelAIMessages\";\n\nexport const useVercelUseChatRuntime = (\n chatHelpers: ReturnType<typeof useChat>,\n) => {\n const messages = useExternalMessageConverter({\n callback: convertMessage,\n isRunning: chatHelpers.isLoading,\n messages: chatHelpers.messages,\n });\n\n const runtime = useExternalStoreRuntime({\n isRunning: chatHelpers.isLoading,\n messages,\n setMessages: (messages) =>\n chatHelpers.setMessages(messages.map(getVercelAIMessages).flat()),\n onCancel: async () => chatHelpers.stop(),\n onNew: async (message) => {\n await chatHelpers.append(await toCreateMessage(message));\n },\n onEdit: async (message) => {\n const newMessages = sliceMessagesUntil(\n chatHelpers.messages,\n message.parentId,\n );\n chatHelpers.setMessages(newMessages);\n\n await chatHelpers.append(await toCreateMessage(message));\n },\n onReload: async (parentId: string | null) => {\n const newMessages = sliceMessagesUntil(chatHelpers.messages, parentId);\n chatHelpers.setMessages(newMessages);\n\n await chatHelpers.reload();\n },\n onAddToolResult: ({ toolCallId, result }) => {\n chatHelpers.addToolResult({ toolCallId, result });\n },\n onSwitchToNewThread: () => {\n chatHelpers.messages = [];\n chatHelpers.input = \"\";\n chatHelpers.setMessages([]);\n chatHelpers.setInput(\"\");\n },\n adapters: {\n attachments: vercelAttachmentAdapter,\n },\n });\n\n useInputSync(chatHelpers, runtime);\n\n return runtime;\n};\n","import { useEffect } from \"react\";\nimport { useAssistant, useChat } from \"ai/react\";\nimport { AssistantRuntime } from \"@assistant-ui/react\";\nimport { useCallbackRef } from \"@radix-ui/react-use-callback-ref\";\n\ntype VercelHelpers =\n | ReturnType<typeof useChat>\n | ReturnType<typeof useAssistant>;\n\nexport const useInputSync = (\n helpers: VercelHelpers,\n runtime: AssistantRuntime,\n) => {\n // sync input from vercel to assistant-ui\n useEffect(() => {\n if (runtime.thread.composer.getState().text !== helpers.input) {\n runtime.thread.composer.setText(helpers.input);\n }\n }, [helpers, runtime]);\n\n // sync input from assistant-ui to vercel\n const handleThreadUpdate = useCallbackRef(() => {\n if (runtime.thread.composer.getState().text !== helpers.input) {\n helpers.setInput(runtime.thread.composer.getState().text);\n }\n });\n\n useEffect(() => {\n return runtime.thread.subscribe(handleThreadUpdate);\n }, [runtime, handleThreadUpdate]);\n};\n","import type { Message } from \"ai\";\n\nexport const sliceMessagesUntil = (\n messages: 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 liekly 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","import { AppendMessage } from \"@assistant-ui/react\";\nimport { CreateMessage } from \"ai\";\n\nexport const toCreateMessage = async (\n message: AppendMessage,\n): Promise<CreateMessage> => {\n const content = message.content\n .filter((part) => part.type === \"text\")\n .map((t) => t.text)\n .join(\"\\n\\n\");\n\n const images = message.content\n .filter((part) => part.type === \"image\")\n .map((part) => ({ url: part.image }));\n\n return {\n role: message.role,\n content,\n experimental_attachments: [\n ...images,\n ...(await Promise.all(\n (message.attachments ?? []).map(async (m) => {\n if (m.file == null)\n throw new Error(\"Attachment did not contain a file\");\n return {\n contentType: m.file.type,\n name: m.file.name,\n url: await getFileDataURL(m.file),\n };\n }),\n )),\n ],\n };\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","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","import {\n getExternalStoreMessage,\n type ThreadMessage,\n} from \"@assistant-ui/react\";\nimport type { Message } from \"ai\";\n\nexport const getVercelAIMessages = (message: ThreadMessage) => {\n return getExternalStoreMessage(message) as Message[];\n};\n","import type { useAssistant } from \"ai/react\";\nimport {\n useExternalMessageConverter,\n useExternalStoreRuntime,\n} from \"@assistant-ui/react\";\nimport { convertMessage } from \"../utils/convertMessage\";\nimport { useInputSync } from \"../utils/useInputSync\";\nimport { toCreateMessage } from \"../utils/toCreateMessage\";\nimport { vercelAttachmentAdapter } from \"../utils/vercelAttachmentAdapter\";\n\nexport const useVercelUseAssistantRuntime = (\n assistantHelpers: ReturnType<typeof useAssistant>,\n) => {\n const messages = useExternalMessageConverter({\n callback: convertMessage,\n isRunning: assistantHelpers.status === \"in_progress\",\n messages: assistantHelpers.messages,\n });\n const runtime = useExternalStoreRuntime({\n isRunning: assistantHelpers.status === \"in_progress\",\n messages,\n onCancel: async () => assistantHelpers.stop(),\n onNew: async (message) => {\n await assistantHelpers.append(await toCreateMessage(message));\n },\n onSwitchToNewThread: () => {\n assistantHelpers.messages = [];\n assistantHelpers.input = \"\";\n assistantHelpers.setMessages([]);\n assistantHelpers.setInput(\"\");\n },\n adapters: {\n attachments: vercelAttachmentAdapter,\n },\n });\n\n useInputSync(assistantHelpers, runtime);\n\n return runtime;\n};\n"],"mappings":"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","names":["m","import_react","import_react","import_react","import_react","messages","import_react"]}
|
package/dist/index.mjs
CHANGED
|
@@ -56,7 +56,8 @@ var convertMessage = (message) => {
|
|
|
56
56
|
id: idx.toString(),
|
|
57
57
|
type: "file",
|
|
58
58
|
name: attachment.name ?? attachment.url,
|
|
59
|
-
content: []
|
|
59
|
+
content: [],
|
|
60
|
+
status: { type: "complete" }
|
|
60
61
|
})
|
|
61
62
|
)
|
|
62
63
|
};
|
|
@@ -126,25 +127,22 @@ import {
|
|
|
126
127
|
} from "@assistant-ui/react";
|
|
127
128
|
|
|
128
129
|
// src/ui/utils/useInputSync.tsx
|
|
129
|
-
import {
|
|
130
|
-
import {
|
|
131
|
-
subscribeToMainThread
|
|
132
|
-
} from "@assistant-ui/react";
|
|
130
|
+
import { useEffect } from "react";
|
|
131
|
+
import { useCallbackRef } from "@radix-ui/react-use-callback-ref";
|
|
133
132
|
var useInputSync = (helpers, runtime) => {
|
|
134
|
-
const helpersRef = useRef(helpers);
|
|
135
133
|
useEffect(() => {
|
|
136
|
-
|
|
137
|
-
if (runtime.thread.composer.text !== helpers.input) {
|
|
134
|
+
if (runtime.thread.composer.getState().text !== helpers.input) {
|
|
138
135
|
runtime.thread.composer.setText(helpers.input);
|
|
139
136
|
}
|
|
140
137
|
}, [helpers, runtime]);
|
|
138
|
+
const handleThreadUpdate = useCallbackRef(() => {
|
|
139
|
+
if (runtime.thread.composer.getState().text !== helpers.input) {
|
|
140
|
+
helpers.setInput(runtime.thread.composer.getState().text);
|
|
141
|
+
}
|
|
142
|
+
});
|
|
141
143
|
useEffect(() => {
|
|
142
|
-
return
|
|
143
|
-
|
|
144
|
-
helpersRef.current.setInput(runtime.thread.composer.text);
|
|
145
|
-
}
|
|
146
|
-
});
|
|
147
|
-
}, [runtime]);
|
|
144
|
+
return runtime.thread.subscribe(handleThreadUpdate);
|
|
145
|
+
}, [runtime, handleThreadUpdate]);
|
|
148
146
|
};
|
|
149
147
|
|
|
150
148
|
// src/ui/utils/sliceMessagesUntil.tsx
|
|
@@ -201,12 +199,15 @@ var vercelAttachmentAdapter = {
|
|
|
201
199
|
type: "file",
|
|
202
200
|
name: file.name,
|
|
203
201
|
file,
|
|
204
|
-
|
|
202
|
+
contentType: file.type,
|
|
203
|
+
content: [],
|
|
204
|
+
status: { type: "requires-action", reason: "composer-send" }
|
|
205
205
|
};
|
|
206
206
|
},
|
|
207
207
|
async send(attachment) {
|
|
208
208
|
return {
|
|
209
209
|
...attachment,
|
|
210
|
+
status: { type: "complete" },
|
|
210
211
|
content: []
|
|
211
212
|
};
|
|
212
213
|
},
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/rsc/useVercelRSCRuntime.tsx","../src/rsc/getVercelRSCMessage.tsx","../src/ui/utils/convertMessage.ts","../src/ui/use-chat/useVercelUseChatRuntime.tsx","../src/ui/utils/useInputSync.tsx","../src/ui/utils/sliceMessagesUntil.tsx","../src/ui/utils/toCreateMessage.ts","../src/ui/utils/vercelAttachmentAdapter.ts","../src/ui/getVercelAIMessages.tsx","../src/ui/use-assistant/useVercelUseAssistantRuntime.tsx"],"sourcesContent":["\"use client\";\n\nimport type { VercelRSCAdapter } from \"./VercelRSCAdapter\";\nimport {\n ExternalStoreAdapter,\n ThreadMessageLike,\n useExternalStoreRuntime,\n} from \"@assistant-ui/react\";\nimport { VercelRSCMessage } from \"./VercelRSCMessage\";\n\nconst vercelToThreadMessage = <T,>(\n converter: (message: T) => VercelRSCMessage,\n rawMessage: T,\n): ThreadMessageLike => {\n const message = converter(rawMessage);\n\n return {\n id: message.id,\n role: message.role,\n content: [{ type: \"ui\", display: message.display }],\n createdAt: message.createdAt,\n };\n};\n\nexport const useVercelRSCRuntime = <T extends WeakKey>(\n adapter: VercelRSCAdapter<T>,\n) => {\n const onNew = adapter.onNew ?? adapter.append;\n if (!onNew)\n throw new Error(\"You must pass a onNew function to useVercelRSCRuntime\");\n const eAdapter: ExternalStoreAdapter<any> = {\n isRunning: adapter.isRunning,\n messages: adapter.messages,\n onNew,\n onEdit: adapter.onEdit ?? adapter.edit,\n onReload: adapter.onReload ?? adapter.reload,\n convertMessage: (m: T) =>\n vercelToThreadMessage(\n adapter.convertMessage ?? ((m) => m as VercelRSCMessage),\n m,\n ),\n unstable_capabilities: {\n copy: false,\n },\n };\n\n const runtime = useExternalStoreRuntime(eAdapter);\n return runtime;\n};\n","import {\n getExternalStoreMessage,\n type ThreadMessage,\n} from \"@assistant-ui/react\";\n\nexport const symbolInnerRSCMessage = Symbol(\"innerVercelRSCMessage\");\n\nexport const getVercelRSCMessage = (message: ThreadMessage) => {\n return getExternalStoreMessage(message);\n};\n","import { Message } from \"ai\";\nimport { useExternalMessageConverter } from \"@assistant-ui/react\";\nimport { ToolCallContentPart } from \"@assistant-ui/react\";\nimport { TextContentPart } from \"@assistant-ui/react\";\nimport { MessageAttachment } from \"../../../../react/src/context/stores/Attachment\";\n\nexport const convertMessage: useExternalMessageConverter.Callback<Message> = (\n message,\n) => {\n switch (message.role) {\n case \"user\":\n return {\n role: \"user\",\n id: message.id,\n createdAt: message.createdAt,\n content: message.content,\n\n attachments: message.experimental_attachments?.map(\n (attachment, idx) =>\n ({\n id: idx.toString(),\n type: \"file\",\n name: attachment.name ?? attachment.url,\n content: [],\n }) satisfies MessageAttachment,\n ),\n };\n\n case \"system\":\n return {\n role: \"system\",\n id: message.id,\n createdAt: message.createdAt,\n content: message.content,\n };\n\n case \"assistant\":\n return {\n role: \"assistant\",\n id: message.id,\n createdAt: message.createdAt,\n content: [\n ...(message.content\n ? [\n {\n type: \"text\",\n text: message.content,\n } satisfies TextContentPart,\n ]\n : []),\n ...(message.toolInvocations?.map(\n (t) =>\n ({\n type: \"tool-call\",\n toolName: t.toolName,\n toolCallId: t.toolCallId,\n argsText: JSON.stringify(t.args),\n args: t.args,\n result: \"result\" in t ? t.result : undefined,\n }) satisfies ToolCallContentPart,\n ) ?? []),\n ],\n };\n\n case \"data\": {\n type MaybeSupportedDataMessage =\n | { type?: \"unsafe_other\" }\n | ToolCallContentPart\n | {\n type: \"tool-result\";\n toolCallId: string;\n result: any;\n };\n\n if (\n !message.data ||\n !(typeof message.data === \"object\") ||\n Array.isArray(message.data)\n )\n return [];\n\n const data = message.data as MaybeSupportedDataMessage;\n\n if (data.type === \"tool-call\") {\n return {\n role: \"assistant\",\n id: message.id,\n createdAt: message.createdAt,\n content: [data],\n };\n } else if (data.type === \"tool-result\") {\n return {\n role: \"tool\",\n toolCallId: data.toolCallId,\n result: data.result,\n };\n }\n return [];\n }\n\n default:\n // TODO handle tool and function messages\n const _unsupported: \"function\" | \"tool\" = message.role;\n throw new Error(\n `You have a message with an unsupported role. The role ${_unsupported} is not supported.`,\n );\n }\n};\n","import type { useChat } from \"ai/react\";\nimport { convertMessage } from \"../utils/convertMessage\";\nimport {\n useExternalMessageConverter,\n useExternalStoreRuntime,\n} from \"@assistant-ui/react\";\nimport { useInputSync } from \"../utils/useInputSync\";\nimport { sliceMessagesUntil } from \"../utils/sliceMessagesUntil\";\nimport { toCreateMessage } from \"../utils/toCreateMessage\";\nimport { vercelAttachmentAdapter } from \"../utils/vercelAttachmentAdapter\";\nimport { getVercelAIMessages } from \"../getVercelAIMessages\";\n\nexport const useVercelUseChatRuntime = (\n chatHelpers: ReturnType<typeof useChat>,\n) => {\n const messages = useExternalMessageConverter({\n callback: convertMessage,\n isRunning: chatHelpers.isLoading,\n messages: chatHelpers.messages,\n });\n\n const runtime = useExternalStoreRuntime({\n isRunning: chatHelpers.isLoading,\n messages,\n setMessages: (messages) =>\n chatHelpers.setMessages(messages.map(getVercelAIMessages).flat()),\n onCancel: async () => chatHelpers.stop(),\n onNew: async (message) => {\n await chatHelpers.append(await toCreateMessage(message));\n },\n onEdit: async (message) => {\n const newMessages = sliceMessagesUntil(\n chatHelpers.messages,\n message.parentId,\n );\n chatHelpers.setMessages(newMessages);\n\n await chatHelpers.append(await toCreateMessage(message));\n },\n onReload: async (parentId: string | null) => {\n const newMessages = sliceMessagesUntil(chatHelpers.messages, parentId);\n chatHelpers.setMessages(newMessages);\n\n await chatHelpers.reload();\n },\n onAddToolResult: ({ toolCallId, result }) => {\n chatHelpers.addToolResult({ toolCallId, result });\n },\n onSwitchToNewThread: () => {\n chatHelpers.messages = [];\n chatHelpers.input = \"\";\n chatHelpers.setMessages([]);\n chatHelpers.setInput(\"\");\n },\n adapters: {\n attachments: vercelAttachmentAdapter,\n },\n });\n\n useInputSync(chatHelpers, runtime);\n\n return runtime;\n};\n","import { useRef, useEffect } from \"react\";\nimport {\n ExternalStoreRuntime,\n subscribeToMainThread,\n} from \"@assistant-ui/react\";\nimport { useAssistant, useChat } from \"ai/react\";\n\ntype VercelHelpers =\n | ReturnType<typeof useChat>\n | ReturnType<typeof useAssistant>;\n\nexport const useInputSync = (\n helpers: VercelHelpers,\n runtime: ExternalStoreRuntime,\n) => {\n // sync input from vercel to assistant-ui\n const helpersRef = useRef(helpers);\n useEffect(() => {\n helpersRef.current = helpers;\n if (runtime.thread.composer.text !== helpers.input) {\n runtime.thread.composer.setText(helpers.input);\n }\n }, [helpers, runtime]);\n\n // sync input from assistant-ui to vercel\n useEffect(() => {\n return subscribeToMainThread(runtime, () => {\n if (runtime.thread.composer.text !== helpersRef.current.input) {\n helpersRef.current.setInput(runtime.thread.composer.text);\n }\n });\n }, [runtime]);\n};\n","import type { Message } from \"ai\";\n\nexport const sliceMessagesUntil = (\n messages: 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 liekly 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","import { AppendMessage } from \"@assistant-ui/react\";\nimport { CreateMessage } from \"ai\";\n\nexport const toCreateMessage = async (\n message: AppendMessage,\n): Promise<CreateMessage> => {\n const content = message.content\n .filter((part) => part.type === \"text\")\n .map((t) => t.text)\n .join(\"\\n\\n\");\n\n const images = message.content\n .filter((part) => part.type === \"image\")\n .map((part) => ({ url: part.image }));\n\n return {\n role: message.role,\n content,\n experimental_attachments: [\n ...images,\n ...(await Promise.all(\n (message.attachments ?? []).map(async (m) => {\n if (m.file == null)\n throw new Error(\"Attachment did not contain a file\");\n return {\n contentType: m.file.type,\n name: m.file.name,\n url: await getFileDataURL(m.file),\n };\n }),\n )),\n ],\n };\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","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 content: [],\n };\n },\n async send(attachment) {\n // noop\n return {\n ...attachment,\n content: [],\n };\n },\n async remove() {\n // noop\n },\n};\n","import {\n getExternalStoreMessage,\n type ThreadMessage,\n} from \"@assistant-ui/react\";\nimport type { Message } from \"ai\";\n\nexport const getVercelAIMessages = (message: ThreadMessage) => {\n return getExternalStoreMessage(message) as Message[];\n};\n","import type { useAssistant } from \"ai/react\";\nimport {\n useExternalMessageConverter,\n useExternalStoreRuntime,\n} from \"@assistant-ui/react\";\nimport { convertMessage } from \"../utils/convertMessage\";\nimport { useInputSync } from \"../utils/useInputSync\";\nimport { toCreateMessage } from \"../utils/toCreateMessage\";\nimport { vercelAttachmentAdapter } from \"../utils/vercelAttachmentAdapter\";\n\nexport const useVercelUseAssistantRuntime = (\n assistantHelpers: ReturnType<typeof useAssistant>,\n) => {\n const messages = useExternalMessageConverter({\n callback: convertMessage,\n isRunning: assistantHelpers.status === \"in_progress\",\n messages: assistantHelpers.messages,\n });\n const runtime = useExternalStoreRuntime({\n isRunning: assistantHelpers.status === \"in_progress\",\n messages,\n onCancel: async () => assistantHelpers.stop(),\n onNew: async (message) => {\n await assistantHelpers.append(await toCreateMessage(message));\n },\n onSwitchToNewThread: () => {\n assistantHelpers.messages = [];\n assistantHelpers.input = \"\";\n assistantHelpers.setMessages([]);\n assistantHelpers.setInput(\"\");\n },\n adapters: {\n attachments: vercelAttachmentAdapter,\n },\n });\n\n useInputSync(assistantHelpers, runtime);\n\n return runtime;\n};\n"],"mappings":"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","names":["m","useExternalStoreRuntime","getExternalStoreMessage","useExternalStoreRuntime","messages","useExternalMessageConverter","useExternalStoreRuntime","useExternalMessageConverter","useExternalStoreRuntime"]}
|
|
1
|
+
{"version":3,"sources":["../src/rsc/useVercelRSCRuntime.tsx","../src/rsc/getVercelRSCMessage.tsx","../src/ui/utils/convertMessage.ts","../src/ui/use-chat/useVercelUseChatRuntime.tsx","../src/ui/utils/useInputSync.tsx","../src/ui/utils/sliceMessagesUntil.tsx","../src/ui/utils/toCreateMessage.ts","../src/ui/utils/vercelAttachmentAdapter.ts","../src/ui/getVercelAIMessages.tsx","../src/ui/use-assistant/useVercelUseAssistantRuntime.tsx"],"sourcesContent":["\"use client\";\n\nimport type { VercelRSCAdapter } from \"./VercelRSCAdapter\";\nimport {\n ExternalStoreAdapter,\n ThreadMessageLike,\n useExternalStoreRuntime,\n} from \"@assistant-ui/react\";\nimport { VercelRSCMessage } from \"./VercelRSCMessage\";\n\nconst vercelToThreadMessage = <T,>(\n converter: (message: T) => VercelRSCMessage,\n rawMessage: T,\n): ThreadMessageLike => {\n const message = converter(rawMessage);\n\n return {\n id: message.id,\n role: message.role,\n content: [{ type: \"ui\", display: message.display }],\n createdAt: message.createdAt,\n };\n};\n\nexport const useVercelRSCRuntime = <T extends WeakKey>(\n adapter: VercelRSCAdapter<T>,\n) => {\n const onNew = adapter.onNew ?? adapter.append;\n if (!onNew)\n throw new Error(\"You must pass a onNew function to useVercelRSCRuntime\");\n const eAdapter: ExternalStoreAdapter<any> = {\n isRunning: adapter.isRunning,\n messages: adapter.messages,\n onNew,\n onEdit: adapter.onEdit ?? adapter.edit,\n onReload: adapter.onReload ?? adapter.reload,\n convertMessage: (m: T) =>\n vercelToThreadMessage(\n adapter.convertMessage ?? ((m) => m as VercelRSCMessage),\n m,\n ),\n unstable_capabilities: {\n copy: false,\n },\n };\n\n const runtime = useExternalStoreRuntime(eAdapter);\n return runtime;\n};\n","import {\n getExternalStoreMessage,\n type ThreadMessage,\n} from \"@assistant-ui/react\";\n\nexport const symbolInnerRSCMessage = Symbol(\"innerVercelRSCMessage\");\n\nexport const getVercelRSCMessage = (message: ThreadMessage) => {\n return getExternalStoreMessage(message);\n};\n","import { Message } from \"ai\";\nimport { useExternalMessageConverter } from \"@assistant-ui/react\";\nimport { ToolCallContentPart } from \"@assistant-ui/react\";\nimport { TextContentPart } from \"@assistant-ui/react\";\nimport { CompleteAttachment } from \"@assistant-ui/react\";\n\nexport const convertMessage: useExternalMessageConverter.Callback<Message> = (\n message,\n) => {\n switch (message.role) {\n case \"user\":\n return {\n role: \"user\",\n id: message.id,\n createdAt: message.createdAt,\n content: message.content,\n\n attachments: message.experimental_attachments?.map(\n (attachment, idx) =>\n ({\n id: idx.toString(),\n type: \"file\",\n name: attachment.name ?? attachment.url,\n content: [],\n status: { type: \"complete\" },\n }) satisfies CompleteAttachment,\n ),\n };\n\n case \"system\":\n return {\n role: \"system\",\n id: message.id,\n createdAt: message.createdAt,\n content: message.content,\n };\n\n case \"assistant\":\n return {\n role: \"assistant\",\n id: message.id,\n createdAt: message.createdAt,\n content: [\n ...(message.content\n ? [\n {\n type: \"text\",\n text: message.content,\n } satisfies TextContentPart,\n ]\n : []),\n ...(message.toolInvocations?.map(\n (t) =>\n ({\n type: \"tool-call\",\n toolName: t.toolName,\n toolCallId: t.toolCallId,\n argsText: JSON.stringify(t.args),\n args: t.args,\n result: \"result\" in t ? t.result : undefined,\n }) satisfies ToolCallContentPart,\n ) ?? []),\n ],\n };\n\n case \"data\": {\n type MaybeSupportedDataMessage =\n | { type?: \"unsafe_other\" }\n | ToolCallContentPart\n | {\n type: \"tool-result\";\n toolCallId: string;\n result: any;\n };\n\n if (\n !message.data ||\n !(typeof message.data === \"object\") ||\n Array.isArray(message.data)\n )\n return [];\n\n const data = message.data as MaybeSupportedDataMessage;\n\n if (data.type === \"tool-call\") {\n return {\n role: \"assistant\",\n id: message.id,\n createdAt: message.createdAt,\n content: [data],\n };\n } else if (data.type === \"tool-result\") {\n return {\n role: \"tool\",\n toolCallId: data.toolCallId,\n result: data.result,\n };\n }\n return [];\n }\n\n default:\n // TODO handle tool and function messages\n const _unsupported: \"function\" | \"tool\" = message.role;\n throw new Error(\n `You have a message with an unsupported role. The role ${_unsupported} is not supported.`,\n );\n }\n};\n","import type { useChat } from \"ai/react\";\nimport { convertMessage } from \"../utils/convertMessage\";\nimport {\n useExternalMessageConverter,\n useExternalStoreRuntime,\n} from \"@assistant-ui/react\";\nimport { useInputSync } from \"../utils/useInputSync\";\nimport { sliceMessagesUntil } from \"../utils/sliceMessagesUntil\";\nimport { toCreateMessage } from \"../utils/toCreateMessage\";\nimport { vercelAttachmentAdapter } from \"../utils/vercelAttachmentAdapter\";\nimport { getVercelAIMessages } from \"../getVercelAIMessages\";\n\nexport const useVercelUseChatRuntime = (\n chatHelpers: ReturnType<typeof useChat>,\n) => {\n const messages = useExternalMessageConverter({\n callback: convertMessage,\n isRunning: chatHelpers.isLoading,\n messages: chatHelpers.messages,\n });\n\n const runtime = useExternalStoreRuntime({\n isRunning: chatHelpers.isLoading,\n messages,\n setMessages: (messages) =>\n chatHelpers.setMessages(messages.map(getVercelAIMessages).flat()),\n onCancel: async () => chatHelpers.stop(),\n onNew: async (message) => {\n await chatHelpers.append(await toCreateMessage(message));\n },\n onEdit: async (message) => {\n const newMessages = sliceMessagesUntil(\n chatHelpers.messages,\n message.parentId,\n );\n chatHelpers.setMessages(newMessages);\n\n await chatHelpers.append(await toCreateMessage(message));\n },\n onReload: async (parentId: string | null) => {\n const newMessages = sliceMessagesUntil(chatHelpers.messages, parentId);\n chatHelpers.setMessages(newMessages);\n\n await chatHelpers.reload();\n },\n onAddToolResult: ({ toolCallId, result }) => {\n chatHelpers.addToolResult({ toolCallId, result });\n },\n onSwitchToNewThread: () => {\n chatHelpers.messages = [];\n chatHelpers.input = \"\";\n chatHelpers.setMessages([]);\n chatHelpers.setInput(\"\");\n },\n adapters: {\n attachments: vercelAttachmentAdapter,\n },\n });\n\n useInputSync(chatHelpers, runtime);\n\n return runtime;\n};\n","import { useEffect } from \"react\";\nimport { useAssistant, useChat } from \"ai/react\";\nimport { AssistantRuntime } from \"@assistant-ui/react\";\nimport { useCallbackRef } from \"@radix-ui/react-use-callback-ref\";\n\ntype VercelHelpers =\n | ReturnType<typeof useChat>\n | ReturnType<typeof useAssistant>;\n\nexport const useInputSync = (\n helpers: VercelHelpers,\n runtime: AssistantRuntime,\n) => {\n // sync input from vercel to assistant-ui\n useEffect(() => {\n if (runtime.thread.composer.getState().text !== helpers.input) {\n runtime.thread.composer.setText(helpers.input);\n }\n }, [helpers, runtime]);\n\n // sync input from assistant-ui to vercel\n const handleThreadUpdate = useCallbackRef(() => {\n if (runtime.thread.composer.getState().text !== helpers.input) {\n helpers.setInput(runtime.thread.composer.getState().text);\n }\n });\n\n useEffect(() => {\n return runtime.thread.subscribe(handleThreadUpdate);\n }, [runtime, handleThreadUpdate]);\n};\n","import type { Message } from \"ai\";\n\nexport const sliceMessagesUntil = (\n messages: 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 liekly 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","import { AppendMessage } from \"@assistant-ui/react\";\nimport { CreateMessage } from \"ai\";\n\nexport const toCreateMessage = async (\n message: AppendMessage,\n): Promise<CreateMessage> => {\n const content = message.content\n .filter((part) => part.type === \"text\")\n .map((t) => t.text)\n .join(\"\\n\\n\");\n\n const images = message.content\n .filter((part) => part.type === \"image\")\n .map((part) => ({ url: part.image }));\n\n return {\n role: message.role,\n content,\n experimental_attachments: [\n ...images,\n ...(await Promise.all(\n (message.attachments ?? []).map(async (m) => {\n if (m.file == null)\n throw new Error(\"Attachment did not contain a file\");\n return {\n contentType: m.file.type,\n name: m.file.name,\n url: await getFileDataURL(m.file),\n };\n }),\n )),\n ],\n };\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","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","import {\n getExternalStoreMessage,\n type ThreadMessage,\n} from \"@assistant-ui/react\";\nimport type { Message } from \"ai\";\n\nexport const getVercelAIMessages = (message: ThreadMessage) => {\n return getExternalStoreMessage(message) as Message[];\n};\n","import type { useAssistant } from \"ai/react\";\nimport {\n useExternalMessageConverter,\n useExternalStoreRuntime,\n} from \"@assistant-ui/react\";\nimport { convertMessage } from \"../utils/convertMessage\";\nimport { useInputSync } from \"../utils/useInputSync\";\nimport { toCreateMessage } from \"../utils/toCreateMessage\";\nimport { vercelAttachmentAdapter } from \"../utils/vercelAttachmentAdapter\";\n\nexport const useVercelUseAssistantRuntime = (\n assistantHelpers: ReturnType<typeof useAssistant>,\n) => {\n const messages = useExternalMessageConverter({\n callback: convertMessage,\n isRunning: assistantHelpers.status === \"in_progress\",\n messages: assistantHelpers.messages,\n });\n const runtime = useExternalStoreRuntime({\n isRunning: assistantHelpers.status === \"in_progress\",\n messages,\n onCancel: async () => assistantHelpers.stop(),\n onNew: async (message) => {\n await assistantHelpers.append(await toCreateMessage(message));\n },\n onSwitchToNewThread: () => {\n assistantHelpers.messages = [];\n assistantHelpers.input = \"\";\n assistantHelpers.setMessages([]);\n assistantHelpers.setInput(\"\");\n },\n adapters: {\n attachments: vercelAttachmentAdapter,\n },\n });\n\n useInputSync(assistantHelpers, runtime);\n\n return runtime;\n};\n"],"mappings":";AAGA;AAAA,EAGE;AAAA,OACK;AAGP,IAAM,wBAAwB,CAC5B,WACA,eACsB;AACtB,QAAM,UAAU,UAAU,UAAU;AAEpC,SAAO;AAAA,IACL,IAAI,QAAQ;AAAA,IACZ,MAAM,QAAQ;AAAA,IACd,SAAS,CAAC,EAAE,MAAM,MAAM,SAAS,QAAQ,QAAQ,CAAC;AAAA,IAClD,WAAW,QAAQ;AAAA,EACrB;AACF;AAEO,IAAM,sBAAsB,CACjC,YACG;AACH,QAAM,QAAQ,QAAQ,SAAS,QAAQ;AACvC,MAAI,CAAC;AACH,UAAM,IAAI,MAAM,uDAAuD;AACzE,QAAM,WAAsC;AAAA,IAC1C,WAAW,QAAQ;AAAA,IACnB,UAAU,QAAQ;AAAA,IAClB;AAAA,IACA,QAAQ,QAAQ,UAAU,QAAQ;AAAA,IAClC,UAAU,QAAQ,YAAY,QAAQ;AAAA,IACtC,gBAAgB,CAAC,MACf;AAAA,MACE,QAAQ,mBAAmB,CAACA,OAAMA;AAAA,MAClC;AAAA,IACF;AAAA,IACF,uBAAuB;AAAA,MACrB,MAAM;AAAA,IACR;AAAA,EACF;AAEA,QAAM,UAAU,wBAAwB,QAAQ;AAChD,SAAO;AACT;;;AChDA;AAAA,EACE;AAAA,OAEK;AAEA,IAAM,wBAAwB,OAAO,uBAAuB;AAE5D,IAAM,sBAAsB,CAAC,YAA2B;AAC7D,SAAO,wBAAwB,OAAO;AACxC;;;ACHO,IAAM,iBAAgE,CAC3E,YACG;AACH,UAAQ,QAAQ,MAAM;AAAA,IACpB,KAAK;AACH,aAAO;AAAA,QACL,MAAM;AAAA,QACN,IAAI,QAAQ;AAAA,QACZ,WAAW,QAAQ;AAAA,QACnB,SAAS,QAAQ;AAAA,QAEjB,aAAa,QAAQ,0BAA0B;AAAA,UAC7C,CAAC,YAAY,SACV;AAAA,YACC,IAAI,IAAI,SAAS;AAAA,YACjB,MAAM;AAAA,YACN,MAAM,WAAW,QAAQ,WAAW;AAAA,YACpC,SAAS,CAAC;AAAA,YACV,QAAQ,EAAE,MAAM,WAAW;AAAA,UAC7B;AAAA,QACJ;AAAA,MACF;AAAA,IAEF,KAAK;AACH,aAAO;AAAA,QACL,MAAM;AAAA,QACN,IAAI,QAAQ;AAAA,QACZ,WAAW,QAAQ;AAAA,QACnB,SAAS,QAAQ;AAAA,MACnB;AAAA,IAEF,KAAK;AACH,aAAO;AAAA,QACL,MAAM;AAAA,QACN,IAAI,QAAQ;AAAA,QACZ,WAAW,QAAQ;AAAA,QACnB,SAAS;AAAA,UACP,GAAI,QAAQ,UACR;AAAA,YACE;AAAA,cACE,MAAM;AAAA,cACN,MAAM,QAAQ;AAAA,YAChB;AAAA,UACF,IACA,CAAC;AAAA,UACL,GAAI,QAAQ,iBAAiB;AAAA,YAC3B,CAAC,OACE;AAAA,cACC,MAAM;AAAA,cACN,UAAU,EAAE;AAAA,cACZ,YAAY,EAAE;AAAA,cACd,UAAU,KAAK,UAAU,EAAE,IAAI;AAAA,cAC/B,MAAM,EAAE;AAAA,cACR,QAAQ,YAAY,IAAI,EAAE,SAAS;AAAA,YACrC;AAAA,UACJ,KAAK,CAAC;AAAA,QACR;AAAA,MACF;AAAA,IAEF,KAAK,QAAQ;AAUX,UACE,CAAC,QAAQ,QACT,EAAE,OAAO,QAAQ,SAAS,aAC1B,MAAM,QAAQ,QAAQ,IAAI;AAE1B,eAAO,CAAC;AAEV,YAAM,OAAO,QAAQ;AAErB,UAAI,KAAK,SAAS,aAAa;AAC7B,eAAO;AAAA,UACL,MAAM;AAAA,UACN,IAAI,QAAQ;AAAA,UACZ,WAAW,QAAQ;AAAA,UACnB,SAAS,CAAC,IAAI;AAAA,QAChB;AAAA,MACF,WAAW,KAAK,SAAS,eAAe;AACtC,eAAO;AAAA,UACL,MAAM;AAAA,UACN,YAAY,KAAK;AAAA,UACjB,QAAQ,KAAK;AAAA,QACf;AAAA,MACF;AACA,aAAO,CAAC;AAAA,IACV;AAAA,IAEA;AAEE,YAAM,eAAoC,QAAQ;AAClD,YAAM,IAAI;AAAA,QACR,yDAAyD,YAAY;AAAA,MACvE;AAAA,EACJ;AACF;;;AC1GA;AAAA,EACE;AAAA,EACA,2BAAAC;AAAA,OACK;;;ACLP,SAAS,iBAAiB;AAG1B,SAAS,sBAAsB;AAMxB,IAAM,eAAe,CAC1B,SACA,YACG;AAEH,YAAU,MAAM;AACd,QAAI,QAAQ,OAAO,SAAS,SAAS,EAAE,SAAS,QAAQ,OAAO;AAC7D,cAAQ,OAAO,SAAS,QAAQ,QAAQ,KAAK;AAAA,IAC/C;AAAA,EACF,GAAG,CAAC,SAAS,OAAO,CAAC;AAGrB,QAAM,qBAAqB,eAAe,MAAM;AAC9C,QAAI,QAAQ,OAAO,SAAS,SAAS,EAAE,SAAS,QAAQ,OAAO;AAC7D,cAAQ,SAAS,QAAQ,OAAO,SAAS,SAAS,EAAE,IAAI;AAAA,IAC1D;AAAA,EACF,CAAC;AAED,YAAU,MAAM;AACd,WAAO,QAAQ,OAAO,UAAU,kBAAkB;AAAA,EACpD,GAAG,CAAC,SAAS,kBAAkB,CAAC;AAClC;;;AC5BO,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;;;AChBO,IAAM,kBAAkB,OAC7B,YAC2B;AAC3B,QAAM,UAAU,QAAQ,QACrB,OAAO,CAAC,SAAS,KAAK,SAAS,MAAM,EACrC,IAAI,CAAC,MAAM,EAAE,IAAI,EACjB,KAAK,MAAM;AAEd,QAAM,SAAS,QAAQ,QACpB,OAAO,CAAC,SAAS,KAAK,SAAS,OAAO,EACtC,IAAI,CAAC,UAAU,EAAE,KAAK,KAAK,MAAM,EAAE;AAEtC,SAAO;AAAA,IACL,MAAM,QAAQ;AAAA,IACd;AAAA,IACA,0BAA0B;AAAA,MACxB,GAAG;AAAA,MACH,GAAI,MAAM,QAAQ;AAAA,SACf,QAAQ,eAAe,CAAC,GAAG,IAAI,OAAO,MAAM;AAC3C,cAAI,EAAE,QAAQ;AACZ,kBAAM,IAAI,MAAM,mCAAmC;AACrD,iBAAO;AAAA,YACL,aAAa,EAAE,KAAK;AAAA,YACpB,MAAM,EAAE,KAAK;AAAA,YACb,KAAK,MAAM,eAAe,EAAE,IAAI;AAAA,UAClC;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF;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;;;AC1CH,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;;;AC5BA;AAAA,EACE,2BAAAC;AAAA,OAEK;AAGA,IAAM,sBAAsB,CAAC,YAA2B;AAC7D,SAAOA,yBAAwB,OAAO;AACxC;;;ALIO,IAAM,0BAA0B,CACrC,gBACG;AACH,QAAM,WAAW,4BAA4B;AAAA,IAC3C,UAAU;AAAA,IACV,WAAW,YAAY;AAAA,IACvB,UAAU,YAAY;AAAA,EACxB,CAAC;AAED,QAAM,UAAUC,yBAAwB;AAAA,IACtC,WAAW,YAAY;AAAA,IACvB;AAAA,IACA,aAAa,CAACC,cACZ,YAAY,YAAYA,UAAS,IAAI,mBAAmB,EAAE,KAAK,CAAC;AAAA,IAClE,UAAU,YAAY,YAAY,KAAK;AAAA,IACvC,OAAO,OAAO,YAAY;AACxB,YAAM,YAAY,OAAO,MAAM,gBAAgB,OAAO,CAAC;AAAA,IACzD;AAAA,IACA,QAAQ,OAAO,YAAY;AACzB,YAAM,cAAc;AAAA,QAClB,YAAY;AAAA,QACZ,QAAQ;AAAA,MACV;AACA,kBAAY,YAAY,WAAW;AAEnC,YAAM,YAAY,OAAO,MAAM,gBAAgB,OAAO,CAAC;AAAA,IACzD;AAAA,IACA,UAAU,OAAO,aAA4B;AAC3C,YAAM,cAAc,mBAAmB,YAAY,UAAU,QAAQ;AACrE,kBAAY,YAAY,WAAW;AAEnC,YAAM,YAAY,OAAO;AAAA,IAC3B;AAAA,IACA,iBAAiB,CAAC,EAAE,YAAY,OAAO,MAAM;AAC3C,kBAAY,cAAc,EAAE,YAAY,OAAO,CAAC;AAAA,IAClD;AAAA,IACA,qBAAqB,MAAM;AACzB,kBAAY,WAAW,CAAC;AACxB,kBAAY,QAAQ;AACpB,kBAAY,YAAY,CAAC,CAAC;AAC1B,kBAAY,SAAS,EAAE;AAAA,IACzB;AAAA,IACA,UAAU;AAAA,MACR,aAAa;AAAA,IACf;AAAA,EACF,CAAC;AAED,eAAa,aAAa,OAAO;AAEjC,SAAO;AACT;;;AM7DA;AAAA,EACE,+BAAAC;AAAA,EACA,2BAAAC;AAAA,OACK;AAMA,IAAM,+BAA+B,CAC1C,qBACG;AACH,QAAM,WAAWC,6BAA4B;AAAA,IAC3C,UAAU;AAAA,IACV,WAAW,iBAAiB,WAAW;AAAA,IACvC,UAAU,iBAAiB;AAAA,EAC7B,CAAC;AACD,QAAM,UAAUC,yBAAwB;AAAA,IACtC,WAAW,iBAAiB,WAAW;AAAA,IACvC;AAAA,IACA,UAAU,YAAY,iBAAiB,KAAK;AAAA,IAC5C,OAAO,OAAO,YAAY;AACxB,YAAM,iBAAiB,OAAO,MAAM,gBAAgB,OAAO,CAAC;AAAA,IAC9D;AAAA,IACA,qBAAqB,MAAM;AACzB,uBAAiB,WAAW,CAAC;AAC7B,uBAAiB,QAAQ;AACzB,uBAAiB,YAAY,CAAC,CAAC;AAC/B,uBAAiB,SAAS,EAAE;AAAA,IAC9B;AAAA,IACA,UAAU;AAAA,MACR,aAAa;AAAA,IACf;AAAA,EACF,CAAC;AAED,eAAa,kBAAkB,OAAO;AAEtC,SAAO;AACT;","names":["m","useExternalStoreRuntime","getExternalStoreMessage","useExternalStoreRuntime","messages","useExternalMessageConverter","useExternalStoreRuntime","useExternalMessageConverter","useExternalStoreRuntime"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@assistant-ui/react-ai-sdk",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.10",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
@@ -24,11 +24,12 @@
|
|
|
24
24
|
],
|
|
25
25
|
"sideEffects": false,
|
|
26
26
|
"dependencies": {
|
|
27
|
+
"@radix-ui/react-use-callback-ref": "^1.1.0",
|
|
27
28
|
"zod": "^3.23.8",
|
|
28
29
|
"zustand": "^4.5.5"
|
|
29
30
|
},
|
|
30
31
|
"peerDependencies": {
|
|
31
|
-
"@assistant-ui/react": "^0.5.
|
|
32
|
+
"@assistant-ui/react": "^0.5.68",
|
|
32
33
|
"@types/react": "*",
|
|
33
34
|
"ai": "^3.2.x",
|
|
34
35
|
"react": "^18"
|