@assistant-ui/react-ai-sdk 1.3.26 → 1.3.28

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.
Files changed (105) hide show
  1. package/dist/frontendTools.d.ts +9 -5
  2. package/dist/frontendTools.d.ts.map +1 -1
  3. package/dist/frontendTools.js +36 -35
  4. package/dist/frontendTools.js.map +1 -1
  5. package/dist/index.d.ts +9 -11
  6. package/dist/index.js +9 -10
  7. package/dist/injectQuoteContext.d.ts +6 -2
  8. package/dist/injectQuoteContext.d.ts.map +1 -1
  9. package/dist/injectQuoteContext.js +46 -53
  10. package/dist/injectQuoteContext.js.map +1 -1
  11. package/dist/modelContentEnvelope.d.ts +12 -10
  12. package/dist/modelContentEnvelope.d.ts.map +1 -1
  13. package/dist/modelContentEnvelope.js +17 -15
  14. package/dist/modelContentEnvelope.js.map +1 -1
  15. package/dist/node_modules/.pnpm/@types_json-schema@7.0.15/node_modules/@types/json-schema/index.d.ts +141 -0
  16. package/dist/node_modules/.pnpm/@types_json-schema@7.0.15/node_modules/@types/json-schema/index.d.ts.map +1 -0
  17. package/dist/packages/assistant-stream/dist/core/AssistantStream.d.ts +1 -0
  18. package/dist/packages/assistant-stream/dist/core/AssistantStreamChunk.d.ts +1 -0
  19. package/dist/packages/assistant-stream/dist/core/accumulators/AssistantMessageStream.d.ts +1 -0
  20. package/dist/packages/assistant-stream/dist/core/accumulators/assistant-message-accumulator.d.ts +1 -0
  21. package/dist/packages/assistant-stream/dist/core/modules/assistant-stream.d.ts +1 -0
  22. package/dist/packages/assistant-stream/dist/core/modules/text.d.ts +1 -0
  23. package/dist/packages/assistant-stream/dist/core/modules/tool-call.d.ts +1 -0
  24. package/dist/packages/assistant-stream/dist/core/serialization/PlainText.d.ts +1 -0
  25. package/dist/packages/assistant-stream/dist/core/serialization/assistant-transport/AssistantTransport.d.ts +1 -0
  26. package/dist/packages/assistant-stream/dist/core/serialization/data-stream/DataStream.d.ts +1 -0
  27. package/dist/packages/assistant-stream/dist/core/serialization/ui-message-stream/UIMessageStream.d.ts +1 -0
  28. package/dist/packages/assistant-stream/dist/core/tool/ToolExecutionStream.d.ts +1 -0
  29. package/dist/packages/assistant-stream/dist/core/tool/schema-utils.d.ts +1 -0
  30. package/dist/packages/assistant-stream/dist/core/tool/schema-utils.js +50 -0
  31. package/dist/packages/assistant-stream/dist/core/tool/schema-utils.js.map +1 -0
  32. package/dist/packages/assistant-stream/dist/core/tool/tool-types.d.ts +43 -0
  33. package/dist/packages/assistant-stream/dist/core/tool/tool-types.d.ts.map +1 -0
  34. package/dist/packages/assistant-stream/dist/core/tool/toolResultStream.d.ts +1 -0
  35. package/dist/packages/assistant-stream/dist/core/utils/stream/AssistantMetaTransformStream.d.ts +1 -0
  36. package/dist/packages/assistant-stream/dist/core/utils/stream/AssistantTransformStream.d.ts +1 -0
  37. package/dist/packages/assistant-stream/dist/core/utils/types.d.ts +1 -0
  38. package/dist/packages/assistant-stream/dist/index.d.ts +1 -0
  39. package/dist/packages/assistant-stream/dist/resumable/createResumableAssistantStreamResponse.d.ts +6 -0
  40. package/dist/packages/assistant-stream/dist/resumable/createResumableAssistantStreamResponse.d.ts.map +1 -0
  41. package/dist/packages/assistant-stream/dist/resumable/createResumableAssistantStreamResponse.js +6 -0
  42. package/dist/packages/assistant-stream/dist/resumable/createResumableAssistantStreamResponse.js.map +1 -0
  43. package/dist/packages/assistant-stream/dist/resumable/index.d.ts +1 -0
  44. package/dist/packages/assistant-stream/dist/utils/json/json-value.d.ts +10 -0
  45. package/dist/packages/assistant-stream/dist/utils/json/json-value.d.ts.map +1 -0
  46. package/dist/packages/assistant-stream/dist/utils.d.ts +1 -0
  47. package/dist/ui/adapters/aiSDKFormatAdapter.d.ts +8 -4
  48. package/dist/ui/adapters/aiSDKFormatAdapter.d.ts.map +1 -1
  49. package/dist/ui/adapters/aiSDKFormatAdapter.js +24 -20
  50. package/dist/ui/adapters/aiSDKFormatAdapter.js.map +1 -1
  51. package/dist/ui/getVercelAIMessages.d.ts +7 -3
  52. package/dist/ui/getVercelAIMessages.d.ts.map +1 -1
  53. package/dist/ui/getVercelAIMessages.js +7 -3
  54. package/dist/ui/getVercelAIMessages.js.map +1 -1
  55. package/dist/ui/resumable.d.ts +18 -15
  56. package/dist/ui/resumable.d.ts.map +1 -1
  57. package/dist/ui/resumable.js +21 -20
  58. package/dist/ui/resumable.js.map +1 -1
  59. package/dist/ui/use-chat/AssistantChatTransport.d.ts +17 -14
  60. package/dist/ui/use-chat/AssistantChatTransport.d.ts.map +1 -1
  61. package/dist/ui/use-chat/AssistantChatTransport.js +98 -108
  62. package/dist/ui/use-chat/AssistantChatTransport.js.map +1 -1
  63. package/dist/ui/use-chat/useAISDKRuntime.d.ts +43 -33
  64. package/dist/ui/use-chat/useAISDKRuntime.d.ts.map +1 -1
  65. package/dist/ui/use-chat/useAISDKRuntime.js +184 -204
  66. package/dist/ui/use-chat/useAISDKRuntime.js.map +1 -1
  67. package/dist/ui/use-chat/useChatRuntime.d.ts +19 -12
  68. package/dist/ui/use-chat/useChatRuntime.d.ts.map +1 -1
  69. package/dist/ui/use-chat/useChatRuntime.js +60 -81
  70. package/dist/ui/use-chat/useChatRuntime.js.map +1 -1
  71. package/dist/ui/use-chat/useExternalHistory.d.ts +8 -4
  72. package/dist/ui/use-chat/useExternalHistory.d.ts.map +1 -1
  73. package/dist/ui/use-chat/useExternalHistory.js +178 -200
  74. package/dist/ui/use-chat/useExternalHistory.js.map +1 -1
  75. package/dist/ui/use-chat/useStreamingTiming.d.ts +7 -3
  76. package/dist/ui/use-chat/useStreamingTiming.d.ts.map +1 -1
  77. package/dist/ui/use-chat/useStreamingTiming.js +60 -75
  78. package/dist/ui/use-chat/useStreamingTiming.js.map +1 -1
  79. package/dist/ui/utils/convertMessage.d.ts +29 -20
  80. package/dist/ui/utils/convertMessage.d.ts.map +1 -1
  81. package/dist/ui/utils/convertMessage.js +207 -301
  82. package/dist/ui/utils/convertMessage.js.map +1 -1
  83. package/dist/ui/utils/sliceMessagesUntil.d.ts +6 -2
  84. package/dist/ui/utils/sliceMessagesUntil.d.ts.map +1 -1
  85. package/dist/ui/utils/sliceMessagesUntil.js +10 -10
  86. package/dist/ui/utils/sliceMessagesUntil.js.map +1 -1
  87. package/dist/ui/utils/toCreateMessage.d.ts +7 -3
  88. package/dist/ui/utils/toCreateMessage.d.ts.map +1 -1
  89. package/dist/ui/utils/toCreateMessage.js +34 -38
  90. package/dist/ui/utils/toCreateMessage.js.map +1 -1
  91. package/dist/ui/utils/vercelAttachmentAdapter.d.ts +6 -2
  92. package/dist/ui/utils/vercelAttachmentAdapter.d.ts.map +1 -1
  93. package/dist/ui/utils/vercelAttachmentAdapter.js +37 -35
  94. package/dist/ui/utils/vercelAttachmentAdapter.js.map +1 -1
  95. package/dist/usage.d.ts +15 -12
  96. package/dist/usage.d.ts.map +1 -1
  97. package/dist/usage.js +80 -99
  98. package/dist/usage.js.map +1 -1
  99. package/package.json +11 -11
  100. package/src/ui/use-chat/useAISDKRuntime.test.ts +2 -2
  101. package/src/ui/use-chat/useAISDKRuntime.ts +8 -0
  102. package/src/ui/utils/convertMessage.test.ts +71 -6
  103. package/src/ui/utils/convertMessage.ts +27 -25
  104. package/dist/index.d.ts.map +0 -1
  105. package/dist/index.js.map +0 -1
@@ -1,12 +1,12 @@
1
- export const sliceMessagesUntil = (messages, messageId) => {
2
- if (messageId == null)
3
- return [];
4
- let messageIdx = messages.findIndex((m) => m.id === messageId);
5
- if (messageIdx === -1)
6
- throw new Error("useVercelAIThreadState: Message not found. This is likely an internal bug in assistant-ui.");
7
- while (messages[messageIdx + 1]?.role === "assistant") {
8
- messageIdx++;
9
- }
10
- return messages.slice(0, messageIdx + 1);
1
+ //#region src/ui/utils/sliceMessagesUntil.ts
2
+ const sliceMessagesUntil = (messages, messageId) => {
3
+ if (messageId == null) return [];
4
+ let messageIdx = messages.findIndex((m) => m.id === messageId);
5
+ if (messageIdx === -1) throw new Error("useVercelAIThreadState: Message not found. This is likely an internal bug in assistant-ui.");
6
+ while (messages[messageIdx + 1]?.role === "assistant") messageIdx++;
7
+ return messages.slice(0, messageIdx + 1);
11
8
  };
9
+ //#endregion
10
+ export { sliceMessagesUntil };
11
+
12
12
  //# sourceMappingURL=sliceMessagesUntil.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"sliceMessagesUntil.js","sourceRoot":"","sources":["../../../src/ui/utils/sliceMessagesUntil.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAChC,QAAsB,EACtB,SAAwB,EACxB,EAAE;IACF,IAAI,SAAS,IAAI,IAAI;QAAE,OAAO,EAAE,CAAC;IAEjC,IAAI,UAAU,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,SAAS,CAAC,CAAC;IAC/D,IAAI,UAAU,KAAK,CAAC,CAAC;QACnB,MAAM,IAAI,KAAK,CACb,4FAA4F,CAC7F,CAAC;IAEJ,OAAO,QAAQ,CAAC,UAAU,GAAG,CAAC,CAAC,EAAE,IAAI,KAAK,WAAW,EAAE,CAAC;QACtD,UAAU,EAAE,CAAC;IACf,CAAC;IAED,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,GAAG,CAAC,CAAC,CAAC;AAC3C,CAAC,CAAC"}
1
+ {"version":3,"file":"sliceMessagesUntil.js","names":[],"sources":["../../../src/ui/utils/sliceMessagesUntil.ts"],"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":";AAEA,MAAa,sBACX,UACA,cACG;CACH,IAAI,aAAa,MAAM,OAAO,CAAC;CAE/B,IAAI,aAAa,SAAS,WAAW,MAAM,EAAE,OAAO,SAAS;CAC7D,IAAI,eAAe,IACjB,MAAM,IAAI,MACR,4FACF;CAEF,OAAO,SAAS,aAAa,IAAI,SAAS,aACxC;CAGF,OAAO,SAAS,MAAM,GAAG,aAAa,CAAC;AACzC"}
@@ -1,4 +1,8 @@
1
- import type { AppendMessage } from "@assistant-ui/core";
2
- import type { CreateUIMessage, UIMessage } from "ai";
3
- export declare const toCreateMessage: <UI_MESSAGE extends UIMessage = UIMessage>(message: AppendMessage) => CreateUIMessage<UI_MESSAGE>;
1
+ import { CreateUIMessage, UIMessage } from "ai";
2
+ import { AppendMessage } from "@assistant-ui/core";
3
+
4
+ //#region src/ui/utils/toCreateMessage.d.ts
5
+ declare const toCreateMessage: <UI_MESSAGE extends UIMessage = UIMessage>(message: AppendMessage) => CreateUIMessage<UI_MESSAGE>;
6
+ //#endregion
7
+ export { toCreateMessage };
4
8
  //# 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,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,KAAK,EACV,eAAe,EAEf,SAAS,EAGV,MAAM,IAAI,CAAC;AAEZ,eAAO,MAAM,eAAe,GAAI,UAAU,SAAS,SAAS,GAAG,SAAS,EACtE,SAAS,aAAa,KACrB,eAAe,CAAC,UAAU,CA0C5B,CAAC"}
1
+ {"version":3,"file":"toCreateMessage.d.ts","names":[],"sources":["../../../src/ui/utils/toCreateMessage.ts"],"mappings":";;;;cASa,eAAA,sBAAsC,SAAA,GAAY,SAAA,EAC7D,OAAA,EAAS,aAAA,KACR,eAAA,CAAgB,UAAA"}
@@ -1,40 +1,36 @@
1
- export const toCreateMessage = (message) => {
2
- const inputParts = [
3
- ...message.content.filter((c) => c.type !== "file"),
4
- ...(message.attachments?.flatMap((a) => a.content.map((c) => ({
5
- ...c,
6
- filename: a.name,
7
- }))) ?? []),
8
- ];
9
- const parts = inputParts.map((part) => {
10
- switch (part.type) {
11
- case "text":
12
- return {
13
- type: "text",
14
- text: part.text,
15
- };
16
- case "image":
17
- return {
18
- type: "file",
19
- url: part.image,
20
- ...(part.filename && { filename: part.filename }),
21
- mediaType: "image/png",
22
- };
23
- case "file":
24
- return {
25
- type: "file",
26
- url: part.data,
27
- mediaType: part.mimeType,
28
- ...(part.filename && { filename: part.filename }),
29
- };
30
- default:
31
- throw new Error(`Unsupported part type: ${part.type}`);
32
- }
33
- });
34
- return {
35
- role: message.role,
36
- parts,
37
- metadata: message.metadata,
38
- };
1
+ //#region src/ui/utils/toCreateMessage.ts
2
+ const toCreateMessage = (message) => {
3
+ const parts = [...message.content.filter((c) => c.type !== "file"), ...message.attachments?.flatMap((a) => a.content.map((c) => ({
4
+ ...c,
5
+ filename: a.name
6
+ }))) ?? []].map((part) => {
7
+ switch (part.type) {
8
+ case "text": return {
9
+ type: "text",
10
+ text: part.text
11
+ };
12
+ case "image": return {
13
+ type: "file",
14
+ url: part.image,
15
+ ...part.filename && { filename: part.filename },
16
+ mediaType: "image/png"
17
+ };
18
+ case "file": return {
19
+ type: "file",
20
+ url: part.data,
21
+ mediaType: part.mimeType,
22
+ ...part.filename && { filename: part.filename }
23
+ };
24
+ default: throw new Error(`Unsupported part type: ${part.type}`);
25
+ }
26
+ });
27
+ return {
28
+ role: message.role,
29
+ parts,
30
+ metadata: message.metadata
31
+ };
39
32
  };
33
+ //#endregion
34
+ export { toCreateMessage };
35
+
40
36
  //# sourceMappingURL=toCreateMessage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"toCreateMessage.js","sourceRoot":"","sources":["../../../src/ui/utils/toCreateMessage.ts"],"names":[],"mappings":"AASA,MAAM,CAAC,MAAM,eAAe,GAAG,CAC7B,OAAsB,EACO,EAAE;IAC/B,MAAM,UAAU,GAAG;QACjB,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC;QACnD,GAAG,CAAC,OAAO,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CACrC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACpB,GAAG,CAAC;YACJ,QAAQ,EAAE,CAAC,CAAC,IAAI;SACjB,CAAC,CAAC,CACJ,IAAI,EAAE,CAAC;KACT,CAAC;IAEF,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,IAAI,EAAuC,EAAE;QACzE,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;YAClB,KAAK,MAAM;gBACT,OAAO;oBACL,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,IAAI,CAAC,IAAI;iBAChB,CAAC;YACJ,KAAK,OAAO;gBACV,OAAO;oBACL,IAAI,EAAE,MAAM;oBACZ,GAAG,EAAE,IAAI,CAAC,KAAK;oBACf,GAAG,CAAC,IAAI,CAAC,QAAQ,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC;oBACjD,SAAS,EAAE,WAAW;iBACvB,CAAC;YACJ,KAAK,MAAM;gBACT,OAAO;oBACL,IAAI,EAAE,MAAM;oBACZ,GAAG,EAAE,IAAI,CAAC,IAAI;oBACd,SAAS,EAAE,IAAI,CAAC,QAAQ;oBACxB,GAAG,CAAC,IAAI,CAAC,QAAQ,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC;iBAClD,CAAC;YACJ;gBACE,MAAM,IAAI,KAAK,CAAC,0BAA0B,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QAC3D,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO;QACL,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,KAAK;QACL,QAAQ,EAAE,OAAO,CAAC,QAAQ;KACyC,CAAC;AACxE,CAAC,CAAC"}
1
+ {"version":3,"file":"toCreateMessage.js","names":[],"sources":["../../../src/ui/utils/toCreateMessage.ts"],"sourcesContent":["import type { AppendMessage } from \"@assistant-ui/core\";\nimport type {\n CreateUIMessage,\n UIDataTypes,\n UIMessage,\n UIMessagePart,\n UITools,\n} from \"ai\";\n\nexport const toCreateMessage = <UI_MESSAGE extends UIMessage = UIMessage>(\n message: AppendMessage,\n): CreateUIMessage<UI_MESSAGE> => {\n const inputParts = [\n ...message.content.filter((c) => c.type !== \"file\"),\n ...(message.attachments?.flatMap((a) =>\n a.content.map((c) => ({\n ...c,\n filename: a.name,\n })),\n ) ?? []),\n ];\n\n const parts = inputParts.map((part): UIMessagePart<UIDataTypes, UITools> => {\n switch (part.type) {\n case \"text\":\n return {\n type: \"text\",\n text: part.text,\n };\n case \"image\":\n return {\n type: \"file\",\n url: part.image,\n ...(part.filename && { filename: part.filename }),\n mediaType: \"image/png\",\n };\n case \"file\":\n return {\n type: \"file\",\n url: part.data,\n mediaType: part.mimeType,\n ...(part.filename && { filename: part.filename }),\n };\n default:\n throw new Error(`Unsupported part type: ${part.type}`);\n }\n });\n\n return {\n role: message.role,\n parts,\n metadata: message.metadata,\n } satisfies CreateUIMessage<UIMessage> as CreateUIMessage<UI_MESSAGE>;\n};\n"],"mappings":";AASA,MAAa,mBACX,YACgC;CAWhC,MAAM,QAAQ,CATZ,GAAG,QAAQ,QAAQ,QAAQ,MAAM,EAAE,SAAS,MAAM,GAClD,GAAI,QAAQ,aAAa,SAAS,MAChC,EAAE,QAAQ,KAAK,OAAO;EACpB,GAAG;EACH,UAAU,EAAE;CACd,EAAE,CACJ,KAAK,CAAC,CAGe,EAAE,KAAK,SAA8C;EAC1E,QAAQ,KAAK,MAAb;GACE,KAAK,QACH,OAAO;IACL,MAAM;IACN,MAAM,KAAK;GACb;GACF,KAAK,SACH,OAAO;IACL,MAAM;IACN,KAAK,KAAK;IACV,GAAI,KAAK,YAAY,EAAE,UAAU,KAAK,SAAS;IAC/C,WAAW;GACb;GACF,KAAK,QACH,OAAO;IACL,MAAM;IACN,KAAK,KAAK;IACV,WAAW,KAAK;IAChB,GAAI,KAAK,YAAY,EAAE,UAAU,KAAK,SAAS;GACjD;GACF,SACE,MAAM,IAAI,MAAM,0BAA0B,KAAK,MAAM;EACzD;CACF,CAAC;CAED,OAAO;EACL,MAAM,QAAQ;EACd;EACA,UAAU,QAAQ;CACpB;AACF"}
@@ -1,3 +1,7 @@
1
- import type { AttachmentAdapter } from "@assistant-ui/core";
2
- export declare const vercelAttachmentAdapter: AttachmentAdapter;
1
+ import { AttachmentAdapter } from "@assistant-ui/core";
2
+
3
+ //#region src/ui/utils/vercelAttachmentAdapter.d.ts
4
+ declare const vercelAttachmentAdapter: AttachmentAdapter;
5
+ //#endregion
6
+ export { vercelAttachmentAdapter };
3
7
  //# sourceMappingURL=vercelAttachmentAdapter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"vercelAttachmentAdapter.d.ts","sourceRoot":"","sources":["../../../src/ui/utils/vercelAttachmentAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAa5D,eAAO,MAAM,uBAAuB,EAAE,iBA+BrC,CAAC"}
1
+ {"version":3,"file":"vercelAttachmentAdapter.d.ts","names":[],"sources":["../../../src/ui/utils/vercelAttachmentAdapter.ts"],"mappings":";;;cAaa,uBAAA,EAAyB,iBA+BrC"}
@@ -1,40 +1,42 @@
1
1
  import { generateId } from "ai";
2
+ //#region src/ui/utils/vercelAttachmentAdapter.ts
2
3
  const getFileDataURL = (file) => new Promise((resolve, reject) => {
3
- const reader = new FileReader();
4
- reader.onload = () => resolve(reader.result);
5
- reader.onerror = (error) => reject(error);
6
- reader.readAsDataURL(file);
4
+ const reader = new FileReader();
5
+ reader.onload = () => resolve(reader.result);
6
+ reader.onerror = (error) => reject(error);
7
+ reader.readAsDataURL(file);
7
8
  });
8
- export const vercelAttachmentAdapter = {
9
- accept: "*",
10
- async add({ file }) {
11
- return {
12
- id: generateId(),
13
- type: file.type.startsWith("image/") ? "image" : "file",
14
- name: file.name,
15
- file,
16
- contentType: file.type,
17
- content: [],
18
- status: { type: "requires-action", reason: "composer-send" },
19
- };
20
- },
21
- async send(attachment) {
22
- // noop
23
- return {
24
- ...attachment,
25
- status: { type: "complete" },
26
- content: [
27
- {
28
- type: "file",
29
- mimeType: attachment.contentType ?? "",
30
- filename: attachment.name,
31
- data: await getFileDataURL(attachment.file),
32
- },
33
- ],
34
- };
35
- },
36
- async remove() {
37
- // noop
38
- },
9
+ const vercelAttachmentAdapter = {
10
+ accept: "*",
11
+ async add({ file }) {
12
+ return {
13
+ id: generateId(),
14
+ type: file.type.startsWith("image/") ? "image" : "file",
15
+ name: file.name,
16
+ file,
17
+ contentType: file.type,
18
+ content: [],
19
+ status: {
20
+ type: "requires-action",
21
+ reason: "composer-send"
22
+ }
23
+ };
24
+ },
25
+ async send(attachment) {
26
+ return {
27
+ ...attachment,
28
+ status: { type: "complete" },
29
+ content: [{
30
+ type: "file",
31
+ mimeType: attachment.contentType ?? "",
32
+ filename: attachment.name,
33
+ data: await getFileDataURL(attachment.file)
34
+ }]
35
+ };
36
+ },
37
+ async remove() {}
39
38
  };
39
+ //#endregion
40
+ export { vercelAttachmentAdapter };
41
+
40
42
  //# sourceMappingURL=vercelAttachmentAdapter.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"vercelAttachmentAdapter.js","sourceRoot":"","sources":["../../../src/ui/utils/vercelAttachmentAdapter.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAEhC,MAAM,cAAc,GAAG,CAAC,IAAU,EAAE,EAAE,CACpC,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;IACtC,MAAM,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;IAEhC,MAAM,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,MAAgB,CAAC,CAAC;IACvD,MAAM,CAAC,OAAO,GAAG,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAE1C,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;AAC7B,CAAC,CAAC,CAAC;AAEL,MAAM,CAAC,MAAM,uBAAuB,GAAsB;IACxD,MAAM,EAAE,GAAG;IACX,KAAK,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE;QAChB,OAAO;YACL,EAAE,EAAE,UAAU,EAAE;YAChB,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM;YACvD,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,IAAI;YACJ,WAAW,EAAE,IAAI,CAAC,IAAI;YACtB,OAAO,EAAE,EAAE;YACX,MAAM,EAAE,EAAE,IAAI,EAAE,iBAAiB,EAAE,MAAM,EAAE,eAAe,EAAE;SAC7D,CAAC;IACJ,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,UAAU;QACnB,OAAO;QACP,OAAO;YACL,GAAG,UAAU;YACb,MAAM,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE;YAC5B,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,QAAQ,EAAE,UAAU,CAAC,WAAW,IAAI,EAAE;oBACtC,QAAQ,EAAE,UAAU,CAAC,IAAI;oBACzB,IAAI,EAAE,MAAM,cAAc,CAAC,UAAU,CAAC,IAAI,CAAC;iBAC5C;aACF;SACF,CAAC;IACJ,CAAC;IACD,KAAK,CAAC,MAAM;QACV,OAAO;IACT,CAAC;CACF,CAAC"}
1
+ {"version":3,"file":"vercelAttachmentAdapter.js","names":[],"sources":["../../../src/ui/utils/vercelAttachmentAdapter.ts"],"sourcesContent":["import type { AttachmentAdapter } from \"@assistant-ui/core\";\nimport { generateId } from \"ai\";\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\nexport const vercelAttachmentAdapter: AttachmentAdapter = {\n accept: \"*\",\n async add({ file }) {\n return {\n id: generateId(),\n type: file.type.startsWith(\"image/\") ? \"image\" : \"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 type: \"file\",\n mimeType: attachment.contentType ?? \"\",\n filename: attachment.name,\n data: await getFileDataURL(attachment.file),\n },\n ],\n };\n },\n async remove() {\n // noop\n },\n};\n"],"mappings":";;AAGA,MAAM,kBAAkB,SACtB,IAAI,SAAiB,SAAS,WAAW;CACvC,MAAM,SAAS,IAAI,WAAW;CAE9B,OAAO,eAAe,QAAQ,OAAO,MAAgB;CACrD,OAAO,WAAW,UAAU,OAAO,KAAK;CAExC,OAAO,cAAc,IAAI;AAC3B,CAAC;AAEH,MAAa,0BAA6C;CACxD,QAAQ;CACR,MAAM,IAAI,EAAE,QAAQ;EAClB,OAAO;GACL,IAAI,WAAW;GACf,MAAM,KAAK,KAAK,WAAW,QAAQ,IAAI,UAAU;GACjD,MAAM,KAAK;GACX;GACA,aAAa,KAAK;GAClB,SAAS,CAAC;GACV,QAAQ;IAAE,MAAM;IAAmB,QAAQ;GAAgB;EAC7D;CACF;CACA,MAAM,KAAK,YAAY;EAErB,OAAO;GACL,GAAG;GACH,QAAQ,EAAE,MAAM,WAAW;GAC3B,SAAS,CACP;IACE,MAAM;IACN,UAAU,WAAW,eAAe;IACpC,UAAU,WAAW;IACrB,MAAM,MAAM,eAAe,WAAW,IAAI;GAC5C,CACF;EACF;CACF;CACA,MAAM,SAAS,CAEf;AACF"}
package/dist/usage.d.ts CHANGED
@@ -1,16 +1,19 @@
1
1
  /// <reference types="@assistant-ui/core/react" />
2
- export type ThreadTokenUsage = {
3
- totalTokens?: number;
4
- inputTokens?: number;
5
- outputTokens?: number;
6
- reasoningTokens?: number;
7
- cachedInputTokens?: number;
2
+ //#region src/usage.d.ts
3
+ type ThreadTokenUsage = {
4
+ totalTokens?: number;
5
+ inputTokens?: number;
6
+ outputTokens?: number;
7
+ reasoningTokens?: number;
8
+ cachedInputTokens?: number;
8
9
  };
9
- export interface TokenUsageExtractableMessage {
10
- role?: string;
11
- metadata?: unknown;
10
+ interface TokenUsageExtractableMessage {
11
+ role?: string;
12
+ metadata?: unknown;
12
13
  }
13
- export declare function getThreadMessageTokenUsage(message: TokenUsageExtractableMessage | undefined): ThreadTokenUsage | undefined;
14
- export declare function getLatestThreadTokenUsage(messages: readonly TokenUsageExtractableMessage[] | undefined): ThreadTokenUsage | undefined;
15
- export declare function useThreadTokenUsage(): ThreadTokenUsage | undefined;
14
+ declare function getThreadMessageTokenUsage(message: TokenUsageExtractableMessage | undefined): ThreadTokenUsage | undefined;
15
+ declare function getLatestThreadTokenUsage(messages: readonly TokenUsageExtractableMessage[] | undefined): ThreadTokenUsage | undefined;
16
+ declare function useThreadTokenUsage(): ThreadTokenUsage | undefined;
17
+ //#endregion
18
+ export { ThreadTokenUsage, TokenUsageExtractableMessage, getLatestThreadTokenUsage, getThreadMessageTokenUsage, useThreadTokenUsage };
16
19
  //# sourceMappingURL=usage.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"usage.d.ts","sourceRoot":"","sources":["../src/usage.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,gBAAgB,GAAG;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF,MAAM,WAAW,4BAA4B;IAC3C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAmGD,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,4BAA4B,GAAG,SAAS,GAChD,gBAAgB,GAAG,SAAS,CAa9B;AAED,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,SAAS,4BAA4B,EAAE,GAAG,SAAS,GAC5D,gBAAgB,GAAG,SAAS,CAE9B;AAiBD,wBAAgB,mBAAmB,IAAI,gBAAgB,GAAG,SAAS,CAGlE"}
1
+ {"version":3,"file":"usage.d.ts","names":[],"sources":["../src/usage.ts"],"mappings":";KAGY,gBAAA;EACV,WAAA;EACA,WAAA;EACA,YAAA;EACA,eAAA;EACA,iBAAA;AAAA;AAAA,UAGe,4BAAA;EACf,IAAA;EACA,QAAQ;AAAA;AAAA,iBAoGM,0BAAA,CACd,OAAA,EAAS,4BAAA,eACR,gBAAgB;AAAA,iBAeH,yBAAA,CACd,QAAA,WAAmB,4BAAA,iBAClB,gBAAgB;AAAA,iBAmBH,mBAAA,CAAA,GAAuB,gBAAgB"}
package/dist/usage.js CHANGED
@@ -1,120 +1,101 @@
1
- /// <reference types="@assistant-ui/core/react" />
2
1
  import { useAuiState } from "@assistant-ui/store";
2
+ //#region src/usage.ts
3
3
  const USAGE_KEYS = [
4
- "inputTokens",
5
- "outputTokens",
6
- "reasoningTokens",
7
- "cachedInputTokens",
8
- "totalTokens",
4
+ "inputTokens",
5
+ "outputTokens",
6
+ "reasoningTokens",
7
+ "cachedInputTokens",
8
+ "totalTokens"
9
9
  ];
10
10
  function asRecord(value) {
11
- if (!value || typeof value !== "object" || Array.isArray(value))
12
- return undefined;
13
- return value;
11
+ if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
12
+ return value;
14
13
  }
15
14
  function asPositiveTokenCount(value) {
16
- if (typeof value !== "number" || !Number.isFinite(value) || value < 0) {
17
- return undefined;
18
- }
19
- return value;
15
+ if (typeof value !== "number" || !Number.isFinite(value) || value < 0) return;
16
+ return value;
20
17
  }
21
18
  function computeTotalTokens(usage) {
22
- if (usage.totalTokens !== undefined)
23
- return usage.totalTokens;
24
- if (usage.inputTokens !== undefined && usage.outputTokens !== undefined) {
25
- return usage.inputTokens + usage.outputTokens;
26
- }
27
- return undefined;
19
+ if (usage.totalTokens !== void 0) return usage.totalTokens;
20
+ if (usage.inputTokens !== void 0 && usage.outputTokens !== void 0) return usage.inputTokens + usage.outputTokens;
28
21
  }
29
22
  function normalizeUsage(value) {
30
- const record = asRecord(value);
31
- if (!record)
32
- return undefined;
33
- const result = {};
34
- let hasFields = false;
35
- for (const key of USAGE_KEYS) {
36
- const count = asPositiveTokenCount(record[key]);
37
- if (count !== undefined) {
38
- result[key] = count;
39
- hasFields = true;
40
- }
41
- }
42
- return hasFields ? result : undefined;
23
+ const record = asRecord(value);
24
+ if (!record) return void 0;
25
+ const result = {};
26
+ let hasFields = false;
27
+ for (const key of USAGE_KEYS) {
28
+ const count = asPositiveTokenCount(record[key]);
29
+ if (count !== void 0) {
30
+ result[key] = count;
31
+ hasFields = true;
32
+ }
33
+ }
34
+ return hasFields ? result : void 0;
43
35
  }
44
36
  function withComputedTotal(usage) {
45
- const totalTokens = computeTotalTokens(usage);
46
- return { ...usage, ...(totalTokens !== undefined && { totalTokens }) };
37
+ const totalTokens = computeTotalTokens(usage);
38
+ return {
39
+ ...usage,
40
+ ...totalTokens !== void 0 && { totalTokens }
41
+ };
47
42
  }
48
43
  function usageFromSteps(value) {
49
- const steps = Array.isArray(value) ? value : [];
50
- const sums = {};
51
- const present = {};
52
- let stepsWithUsage = 0;
53
- let stepsWithComputableTotal = 0;
54
- for (const step of steps) {
55
- const usage = normalizeUsage(asRecord(step)?.usage);
56
- if (!usage)
57
- continue;
58
- stepsWithUsage++;
59
- const stepTotal = computeTotalTokens(usage);
60
- if (stepTotal !== undefined) {
61
- sums.totalTokens = (sums.totalTokens ?? 0) + stepTotal;
62
- stepsWithComputableTotal++;
63
- }
64
- for (const key of USAGE_KEYS) {
65
- if (key === "totalTokens")
66
- continue;
67
- if (usage[key] !== undefined) {
68
- sums[key] = (sums[key] ?? 0) + usage[key];
69
- present[key] = true;
70
- }
71
- }
72
- }
73
- if (stepsWithUsage === 0)
74
- return undefined;
75
- const result = {};
76
- if (stepsWithComputableTotal === stepsWithUsage) {
77
- result.totalTokens = sums.totalTokens;
78
- }
79
- for (const key of USAGE_KEYS) {
80
- if (key === "totalTokens")
81
- continue;
82
- if (present[key]) {
83
- result[key] = sums[key];
84
- }
85
- }
86
- return result;
44
+ const steps = Array.isArray(value) ? value : [];
45
+ const sums = {};
46
+ const present = {};
47
+ let stepsWithUsage = 0;
48
+ let stepsWithComputableTotal = 0;
49
+ for (const step of steps) {
50
+ const usage = normalizeUsage(asRecord(step)?.usage);
51
+ if (!usage) continue;
52
+ stepsWithUsage++;
53
+ const stepTotal = computeTotalTokens(usage);
54
+ if (stepTotal !== void 0) {
55
+ sums.totalTokens = (sums.totalTokens ?? 0) + stepTotal;
56
+ stepsWithComputableTotal++;
57
+ }
58
+ for (const key of USAGE_KEYS) {
59
+ if (key === "totalTokens") continue;
60
+ if (usage[key] !== void 0) {
61
+ sums[key] = (sums[key] ?? 0) + usage[key];
62
+ present[key] = true;
63
+ }
64
+ }
65
+ }
66
+ if (stepsWithUsage === 0) return void 0;
67
+ const result = {};
68
+ if (stepsWithComputableTotal === stepsWithUsage) result.totalTokens = sums.totalTokens;
69
+ for (const key of USAGE_KEYS) {
70
+ if (key === "totalTokens") continue;
71
+ if (present[key]) result[key] = sums[key];
72
+ }
73
+ return result;
87
74
  }
88
- export function getThreadMessageTokenUsage(message) {
89
- if (!message || message.role !== "assistant")
90
- return undefined;
91
- const metadata = asRecord(message.metadata);
92
- if (!metadata)
93
- return undefined;
94
- const topLevelUsage = normalizeUsage(metadata.usage);
95
- if (topLevelUsage)
96
- return withComputedTotal(topLevelUsage);
97
- const legacyUsage = normalizeUsage(asRecord(metadata.custom)?.usage);
98
- if (legacyUsage)
99
- return withComputedTotal(legacyUsage);
100
- return usageFromSteps(metadata.steps);
75
+ function getThreadMessageTokenUsage(message) {
76
+ if (!message || message.role !== "assistant") return void 0;
77
+ const metadata = asRecord(message.metadata);
78
+ if (!metadata) return void 0;
79
+ const topLevelUsage = normalizeUsage(metadata.usage);
80
+ if (topLevelUsage) return withComputedTotal(topLevelUsage);
81
+ const legacyUsage = normalizeUsage(asRecord(metadata.custom)?.usage);
82
+ if (legacyUsage) return withComputedTotal(legacyUsage);
83
+ return usageFromSteps(metadata.steps);
101
84
  }
102
- export function getLatestThreadTokenUsage(messages) {
103
- return getThreadMessageTokenUsage(findLatestMessageWithUsage(messages));
85
+ function getLatestThreadTokenUsage(messages) {
86
+ return getThreadMessageTokenUsage(findLatestMessageWithUsage(messages));
104
87
  }
105
88
  function findLatestMessageWithUsage(messages) {
106
- if (!messages)
107
- return undefined;
108
- for (let idx = messages.length - 1; idx >= 0; idx -= 1) {
109
- const message = messages[idx];
110
- if (getThreadMessageTokenUsage(message)) {
111
- return message;
112
- }
113
- }
114
- return undefined;
89
+ if (!messages) return void 0;
90
+ for (let idx = messages.length - 1; idx >= 0; idx -= 1) {
91
+ const message = messages[idx];
92
+ if (getThreadMessageTokenUsage(message)) return message;
93
+ }
115
94
  }
116
- export function useThreadTokenUsage() {
117
- const msg = useAuiState((s) => findLatestMessageWithUsage(s.thread.messages));
118
- return getThreadMessageTokenUsage(msg);
95
+ function useThreadTokenUsage() {
96
+ return getThreadMessageTokenUsage(useAuiState((s) => findLatestMessageWithUsage(s.thread.messages)));
119
97
  }
98
+ //#endregion
99
+ export { getLatestThreadTokenUsage, getThreadMessageTokenUsage, useThreadTokenUsage };
100
+
120
101
  //# sourceMappingURL=usage.js.map
package/dist/usage.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"usage.js","sourceRoot":"","sources":["../src/usage.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"usage.js","names":[],"sources":["../src/usage.ts"],"sourcesContent":["/// <reference types=\"@assistant-ui/core/react\" />\nimport { useAuiState } from \"@assistant-ui/store\";\n\nexport type ThreadTokenUsage = {\n totalTokens?: number;\n inputTokens?: number;\n outputTokens?: number;\n reasoningTokens?: number;\n cachedInputTokens?: number;\n};\n\nexport interface TokenUsageExtractableMessage {\n role?: string;\n metadata?: unknown;\n}\n\ntype UsageRecord = Record<string, unknown>;\n\nconst USAGE_KEYS = [\n \"inputTokens\",\n \"outputTokens\",\n \"reasoningTokens\",\n \"cachedInputTokens\",\n \"totalTokens\",\n] as const satisfies (keyof ThreadTokenUsage)[];\n\nfunction asRecord(value: unknown): UsageRecord | undefined {\n if (!value || typeof value !== \"object\" || Array.isArray(value))\n return undefined;\n return value as UsageRecord;\n}\n\nfunction asPositiveTokenCount(value: unknown): number | undefined {\n if (typeof value !== \"number\" || !Number.isFinite(value) || value < 0) {\n return undefined;\n }\n return value;\n}\n\nfunction computeTotalTokens(usage: ThreadTokenUsage): number | undefined {\n if (usage.totalTokens !== undefined) return usage.totalTokens;\n if (usage.inputTokens !== undefined && usage.outputTokens !== undefined) {\n return usage.inputTokens + usage.outputTokens;\n }\n return undefined;\n}\n\nfunction normalizeUsage(value: unknown): ThreadTokenUsage | undefined {\n const record = asRecord(value);\n if (!record) return undefined;\n\n const result: ThreadTokenUsage = {};\n let hasFields = false;\n for (const key of USAGE_KEYS) {\n const count = asPositiveTokenCount(record[key]);\n if (count !== undefined) {\n result[key] = count;\n hasFields = true;\n }\n }\n return hasFields ? result : undefined;\n}\n\nfunction withComputedTotal(\n usage: ThreadTokenUsage,\n): ThreadTokenUsage | undefined {\n const totalTokens = computeTotalTokens(usage);\n return { ...usage, ...(totalTokens !== undefined && { totalTokens }) };\n}\n\nfunction usageFromSteps(value: unknown): ThreadTokenUsage | undefined {\n const steps = Array.isArray(value) ? value : [];\n\n const sums: Record<string, number> = {};\n const present: Record<string, boolean> = {};\n let stepsWithUsage = 0;\n let stepsWithComputableTotal = 0;\n\n for (const step of steps) {\n const usage = normalizeUsage(asRecord(step)?.usage);\n if (!usage) continue;\n stepsWithUsage++;\n\n const stepTotal = computeTotalTokens(usage);\n if (stepTotal !== undefined) {\n sums.totalTokens = (sums.totalTokens ?? 0) + stepTotal;\n stepsWithComputableTotal++;\n }\n\n for (const key of USAGE_KEYS) {\n if (key === \"totalTokens\") continue;\n if (usage[key] !== undefined) {\n sums[key] = (sums[key] ?? 0) + usage[key];\n present[key] = true;\n }\n }\n }\n\n if (stepsWithUsage === 0) return undefined;\n\n const result: ThreadTokenUsage = {};\n if (stepsWithComputableTotal === stepsWithUsage) {\n result.totalTokens = sums.totalTokens!;\n }\n for (const key of USAGE_KEYS) {\n if (key === \"totalTokens\") continue;\n if (present[key]) {\n result[key] = sums[key]!;\n }\n }\n return result;\n}\n\nexport function getThreadMessageTokenUsage(\n message: TokenUsageExtractableMessage | undefined,\n): ThreadTokenUsage | undefined {\n if (!message || message.role !== \"assistant\") return undefined;\n\n const metadata = asRecord(message.metadata);\n if (!metadata) return undefined;\n\n const topLevelUsage = normalizeUsage(metadata.usage);\n if (topLevelUsage) return withComputedTotal(topLevelUsage);\n\n const legacyUsage = normalizeUsage(asRecord(metadata.custom)?.usage);\n if (legacyUsage) return withComputedTotal(legacyUsage);\n\n return usageFromSteps(metadata.steps);\n}\n\nexport function getLatestThreadTokenUsage(\n messages: readonly TokenUsageExtractableMessage[] | undefined,\n): ThreadTokenUsage | undefined {\n return getThreadMessageTokenUsage(findLatestMessageWithUsage(messages));\n}\n\nfunction findLatestMessageWithUsage(\n messages: readonly TokenUsageExtractableMessage[] | undefined,\n): TokenUsageExtractableMessage | undefined {\n if (!messages) return undefined;\n\n for (let idx = messages.length - 1; idx >= 0; idx -= 1) {\n const message = messages[idx];\n if (getThreadMessageTokenUsage(message)) {\n return message;\n }\n }\n\n return undefined;\n}\n\nexport function useThreadTokenUsage(): ThreadTokenUsage | undefined {\n const msg = useAuiState((s) => findLatestMessageWithUsage(s.thread.messages));\n return getThreadMessageTokenUsage(msg);\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@assistant-ui/react-ai-sdk",
3
- "version": "1.3.26",
3
+ "version": "1.3.28",
4
4
  "description": "Vercel AI SDK adapter for assistant-ui",
5
5
  "keywords": [
6
6
  "ai-sdk",
@@ -30,10 +30,10 @@
30
30
  ],
31
31
  "sideEffects": false,
32
32
  "dependencies": {
33
- "@ai-sdk/react": "^3.0.177",
34
- "@assistant-ui/core": "^0.2.2",
35
- "@assistant-ui/store": "^0.2.10",
36
- "ai": "^6.0.175",
33
+ "@ai-sdk/react": "^3.0.190",
34
+ "@assistant-ui/core": "^0.2.6",
35
+ "@assistant-ui/store": "^0.2.12",
36
+ "ai": "^6.0.188",
37
37
  "assistant-cloud": "*"
38
38
  },
39
39
  "peerDependencies": {
@@ -48,17 +48,17 @@
48
48
  "devDependencies": {
49
49
  "@testing-library/react": "^16.3.2",
50
50
  "@types/json-schema": "^7.0.15",
51
- "@types/react": "^19.2.14",
51
+ "@types/react": "^19.2.15",
52
52
  "@types/react-dom": "^19.2.3",
53
53
  "jsdom": "^29.1.1",
54
- "react": "^19.2.5",
55
- "vitest": "^4.1.5",
56
- "@assistant-ui/x-buildutils": "0.0.7",
57
- "assistant-stream": "0.3.14"
54
+ "react": "^19.2.6",
55
+ "vitest": "^4.1.7",
56
+ "@assistant-ui/x-buildutils": "0.0.9",
57
+ "assistant-stream": "0.3.17"
58
58
  },
59
59
  "publishConfig": {
60
60
  "access": "public",
61
- "provenance": false
61
+ "provenance": true
62
62
  },
63
63
  "homepage": "https://www.assistant-ui.com/",
64
64
  "repository": {
@@ -77,13 +77,13 @@ describe("useAISDKRuntime", () => {
77
77
  result.current.thread.append({
78
78
  role: "user",
79
79
  content: [{ type: "text", text: "hello" }],
80
- runConfig: { custom: { model: "gpt-4.1" } },
80
+ runConfig: { custom: { model: "gpt-5.4-nano" } },
81
81
  });
82
82
  });
83
83
 
84
84
  await waitFor(() => {
85
85
  expect(chat.sendMessage).toHaveBeenCalledWith(expect.anything(), {
86
- metadata: { custom: { model: "gpt-4.1" } },
86
+ metadata: { custom: { model: "gpt-5.4-nano" } },
87
87
  });
88
88
  });
89
89
  });
@@ -350,6 +350,14 @@ export const useAISDKRuntime = <UI_MESSAGE extends UIMessage = UIMessage>(
350
350
  },
351
351
  onResumeToolCall: (options) =>
352
352
  toolInvocations.resume(options.toolCallId, options.payload),
353
+ onRespondToToolApproval: ({ approvalId, approved, reason }) => {
354
+ void chatHelpers.addToolApprovalResponse({
355
+ id: approvalId,
356
+ approved,
357
+ ...(reason != null && { reason }),
358
+ options: { metadata: lastRunConfigRef.current },
359
+ });
360
+ },
353
361
  ...(onResume && { onResume }),
354
362
  ...(suggestions && { suggestions }),
355
363
  adapters: {