@assistant-ui/ai-sdk 0.0.5 → 0.0.7

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 (92) hide show
  1. package/dist/adapters/aiSDKFormatAdapter.d.ts +2 -8
  2. package/dist/adapters/aiSDKFormatAdapter.js +1 -25
  3. package/dist/adapters/vercelAttachmentAdapter.d.ts +1 -2
  4. package/dist/adapters/vercelAttachmentAdapter.d.ts.map +1 -1
  5. package/dist/aiSDKExtras.d.ts +2 -3
  6. package/dist/aiSDKExtras.d.ts.map +1 -1
  7. package/dist/converters/convertMessage.d.ts +5 -4
  8. package/dist/converters/convertMessage.d.ts.map +1 -1
  9. package/dist/converters/convertMessage.js +40 -3
  10. package/dist/converters/convertMessage.js.map +1 -1
  11. package/dist/converters/modelContentEnvelope.d.ts +4 -5
  12. package/dist/converters/modelContentEnvelope.d.ts.map +1 -1
  13. package/dist/converters/toCreateMessage.d.ts +1 -2
  14. package/dist/converters/toCreateMessage.d.ts.map +1 -1
  15. package/dist/converters/toolOutputConversion.d.ts +2 -3
  16. package/dist/converters/toolOutputConversion.d.ts.map +1 -1
  17. package/dist/hooks.d.ts +2 -3
  18. package/dist/hooks.d.ts.map +1 -1
  19. package/dist/model-context/injectInteractableContext.d.ts +1 -2
  20. package/dist/model-context/injectInteractableContext.d.ts.map +1 -1
  21. package/dist/model-context/injectQuoteContext.d.ts +1 -2
  22. package/dist/model-context/injectQuoteContext.d.ts.map +1 -1
  23. package/dist/runtime/AISDKChat.d.ts +2 -3
  24. package/dist/runtime/AISDKChat.d.ts.map +1 -1
  25. package/dist/runtime/AISDKThreads.d.ts +2 -3
  26. package/dist/runtime/AISDKThreads.d.ts.map +1 -1
  27. package/dist/runtime/AISDKThreads.js +87 -68
  28. package/dist/runtime/AISDKThreads.js.map +1 -1
  29. package/dist/runtime/sdkIdentity.d.ts +5 -0
  30. package/dist/runtime/sdkIdentity.d.ts.map +1 -0
  31. package/dist/runtime/sdkIdentity.js +9 -0
  32. package/dist/runtime/sdkIdentity.js.map +1 -0
  33. package/dist/runtime/useAISDKRuntime.d.ts +17 -5
  34. package/dist/runtime/useAISDKRuntime.d.ts.map +1 -1
  35. package/dist/runtime/useAISDKRuntime.js +103 -38
  36. package/dist/runtime/useAISDKRuntime.js.map +1 -1
  37. package/dist/runtime/useChatRuntime.d.ts +2 -3
  38. package/dist/runtime/useChatRuntime.d.ts.map +1 -1
  39. package/dist/runtime/useChatRuntime.js +5 -1
  40. package/dist/runtime/useChatRuntime.js.map +1 -1
  41. package/dist/runtime/useChatThread.d.ts +19 -5
  42. package/dist/runtime/useChatThread.d.ts.map +1 -1
  43. package/dist/runtime/useChatThread.js +31 -10
  44. package/dist/runtime/useChatThread.js.map +1 -1
  45. package/dist/runtime/useExternalHistory.d.ts +2 -3
  46. package/dist/runtime/useExternalHistory.d.ts.map +1 -1
  47. package/dist/runtime/useExternalHistory.js +31 -20
  48. package/dist/runtime/useExternalHistory.js.map +1 -1
  49. package/dist/runtime/useResourceCleanup.d.ts +1 -2
  50. package/dist/runtime/useResourceCleanup.d.ts.map +1 -1
  51. package/dist/runtime/useStreamingTiming.d.ts +2 -3
  52. package/dist/runtime/useStreamingTiming.d.ts.map +1 -1
  53. package/dist/tools/frontendTools.d.ts +3 -4
  54. package/dist/tools/frontendTools.d.ts.map +1 -1
  55. package/dist/tools/generativeTools.d.ts +5 -6
  56. package/dist/tools/generativeTools.d.ts.map +1 -1
  57. package/dist/tools/mcp-stdio.unsupported.d.ts +1 -2
  58. package/dist/tools/mcp-stdio.unsupported.d.ts.map +1 -1
  59. package/dist/transport/AssistantChatTransport.d.ts +3 -4
  60. package/dist/transport/AssistantChatTransport.d.ts.map +1 -1
  61. package/dist/transport/resumable.d.ts +4 -5
  62. package/dist/transport/resumable.d.ts.map +1 -1
  63. package/dist/usage.d.ts +4 -5
  64. package/dist/usage.d.ts.map +1 -1
  65. package/dist/utils/getVercelAIMessages.d.ts +1 -2
  66. package/dist/utils/getVercelAIMessages.d.ts.map +1 -1
  67. package/dist/utils/sliceMessagesUntil.d.ts +1 -2
  68. package/dist/utils/sliceMessagesUntil.d.ts.map +1 -1
  69. package/package.json +15 -14
  70. package/src/adapters/aiSDKFormatAdapter.ts +4 -41
  71. package/src/converters/convertMessage.test.ts +152 -0
  72. package/src/converters/convertMessage.ts +95 -5
  73. package/src/runtime/AISDKChat.test.ts +4 -5
  74. package/src/runtime/AISDKThreads.cloud.test.ts +12 -3
  75. package/src/runtime/AISDKThreads.test.ts +140 -13
  76. package/src/runtime/AISDKThreads.ts +23 -4
  77. package/src/runtime/sdkIdentity.ts +9 -0
  78. package/src/runtime/useAISDKRuntime.approval.integration.test.tsx +287 -0
  79. package/src/runtime/useAISDKRuntime.approval.test.tsx +257 -1
  80. package/src/runtime/useAISDKRuntime.test.ts +46 -4
  81. package/src/runtime/useAISDKRuntime.ts +164 -24
  82. package/src/runtime/useAISDKRuntime.voice.test.tsx +270 -0
  83. package/src/runtime/useChatRuntime.test.ts +72 -5
  84. package/src/runtime/useChatRuntime.ts +2 -1
  85. package/src/runtime/useChatThread.test.ts +74 -0
  86. package/src/runtime/useChatThread.ts +45 -6
  87. package/src/runtime/useExternalHistory.test.ts +75 -0
  88. package/src/runtime/useExternalHistory.ts +28 -11
  89. package/src/tools/generativeTools.test.ts +7 -1
  90. package/src/transport/AssistantChatTransport.test.ts +1 -9
  91. package/dist/adapters/aiSDKFormatAdapter.d.ts.map +0 -1
  92. package/dist/adapters/aiSDKFormatAdapter.js.map +0 -1
@@ -25,6 +25,7 @@ const toExportedMessageRepository = (toThreadMessages, messages) => {
25
25
  };
26
26
  };
27
27
  const isAwaitingToolApproval = (message) => message.status?.type === "requires-action" && message.status.reason === "tool-calls";
28
+ const isTerminalMessage = (message) => message.status === void 0 || message.status.type === "complete" || message.status.type === "incomplete";
28
29
  const encodeContent = (storageFormatAdapter, item) => JSON.stringify(storageFormatAdapter.encode(item));
29
30
  const useExternalHistory = (runtimeRef, historyAdapter, toThreadMessages, storageFormatAdapter, onSetMessages) => {
30
31
  const loadedRef = useRef(false);
@@ -106,6 +107,8 @@ const useExternalHistory = (runtimeRef, historyAdapter, toThreadMessages, storag
106
107
  useEffect(() => {
107
108
  if (!formatAdapter) return;
108
109
  const adapter = formatAdapter;
110
+ const idleScheduledInnerIds = /* @__PURE__ */ new Set();
111
+ const unpersistedInnerIds = (message) => isTerminalMessage(message) ? getExternalStoreMessages(message).map((innerMessage) => storageFormatAdapter.getId(innerMessage)).filter((innerId) => !persistedInnerMessages.current.has(innerId)) : [];
109
112
  const unsubscribe = runtimeRef.current.thread.subscribe(() => {
110
113
  const threadState_0 = runtimeRef.current.thread.getState();
111
114
  const { isRunning } = threadState_0;
@@ -134,8 +137,13 @@ const useExternalHistory = (runtimeRef, historyAdapter, toThreadMessages, storag
134
137
  }
135
138
  return;
136
139
  }
137
- if (!wasRunning) return;
138
- if (runStartRef.current != null) stepBoundariesRef.current.push(Date.now() - runStartRef.current);
140
+ if (wasRunning) {
141
+ if (runStartRef.current != null) stepBoundariesRef.current.push(Date.now() - runStartRef.current);
142
+ } else {
143
+ const pending = threadState_0.messages.flatMap(unpersistedInnerIds);
144
+ if (pending.every((innerId_0) => idleScheduledInnerIds.has(innerId_0))) return;
145
+ for (const innerId_1 of pending) idleScheduledInnerIds.add(innerId_1);
146
+ }
139
147
  if (persistTimerRef.current) clearTimeout(persistTimerRef.current);
140
148
  persistTimerRef.current = setTimeout(() => {
141
149
  persistSettled(false);
@@ -187,25 +195,25 @@ const useExternalHistory = (runtimeRef, historyAdapter, toThreadMessages, storag
187
195
  parentId: idx === 0 ? lastInnerMessageId : storageFormatAdapter.getId(msgs_0[idx - 1]),
188
196
  message: msg
189
197
  }));
190
- for (const message of messages_0) {
191
- const innerMessages = getExternalStoreMessages(message);
192
- const isTerminal = message.status === void 0 || message.status.type === "complete" || message.status.type === "incomplete";
193
- const isAwaitingToolCalls = isAwaitingToolApproval(message);
198
+ for (const message_0 of messages_0) {
199
+ const innerMessages = getExternalStoreMessages(message_0);
200
+ const isTerminal = isTerminalMessage(message_0);
201
+ const isAwaitingToolCalls = isAwaitingToolApproval(message_0);
194
202
  if (!(isTerminal || isAwaitingToolCalls && adapter.update !== void 0)) {
195
203
  lastInnerMessageId = getLastInnerId(innerMessages) ?? lastInnerMessageId;
196
204
  continue;
197
205
  }
198
- if (!historyIds.current.has(message.id)) {
199
- historyIds.current.add(message.id);
200
- deferredTelemetryIds.current.add(message.id);
206
+ if (!historyIds.current.has(message_0.id)) {
207
+ historyIds.current.add(message_0.id);
208
+ deferredTelemetryIds.current.add(message_0.id);
201
209
  }
202
210
  const batchItems = toBatchItems(innerMessages);
203
211
  for (const item of batchItems) {
204
- const innerId = storageFormatAdapter.getId(item.message);
205
- const persisted = persistedInnerMessages.current.get(innerId);
212
+ const innerId_2 = storageFormatAdapter.getId(item.message);
213
+ const persisted = persistedInnerMessages.current.get(innerId_2);
206
214
  if (!persisted) {
207
215
  await adapter.append(item);
208
- persistedInnerMessages.current.set(innerId, {
216
+ persistedInnerMessages.current.set(innerId_2, {
209
217
  source: item.message,
210
218
  content: encodeContent(storageFormatAdapter, item)
211
219
  });
@@ -213,8 +221,8 @@ const useExternalHistory = (runtimeRef, historyAdapter, toThreadMessages, storag
213
221
  const content = encodeContent(storageFormatAdapter, item);
214
222
  if (content === persisted.content) persisted.source = item.message;
215
223
  else try {
216
- await adapter.update(item, innerId);
217
- persistedInnerMessages.current.set(innerId, {
224
+ await adapter.update(item, innerId_2);
225
+ persistedInnerMessages.current.set(innerId_2, {
218
226
  source: item.message,
219
227
  content
220
228
  });
@@ -222,9 +230,12 @@ const useExternalHistory = (runtimeRef, historyAdapter, toThreadMessages, storag
222
230
  }
223
231
  }
224
232
  lastInnerMessageId = getLastInnerId(innerMessages) ?? lastInnerMessageId;
225
- if (deferredTelemetryIds.current.has(message.id) && isTerminal) {
226
- deferredTelemetryIds.current.delete(message.id);
227
- adapter.reportTelemetry?.(batchItems, telemetryOptions);
233
+ if (deferredTelemetryIds.current.has(message_0.id) && isTerminal) {
234
+ deferredTelemetryIds.current.delete(message_0.id);
235
+ adapter.reportTelemetry?.(batchItems, {
236
+ ...telemetryOptions,
237
+ message: message_0
238
+ });
228
239
  }
229
240
  }
230
241
  }).catch((error_0) => {
@@ -254,12 +265,12 @@ const useExternalHistory = (runtimeRef, historyAdapter, toThreadMessages, storag
254
265
  if (messageIndex === -1) return;
255
266
  const previousInnerMessages = messages_1.slice(0, messageIndex).flatMap(getExternalStoreMessages);
256
267
  let parentId = previousInnerMessages.at(-1) ? storageFormatAdapter.getId(previousInnerMessages.at(-1)) : null;
257
- const itemsToDelete = getExternalStoreMessages(messages_1[messageIndex]).map((message_0) => {
268
+ const itemsToDelete = getExternalStoreMessages(messages_1[messageIndex]).map((message_1) => {
258
269
  const item_0 = {
259
270
  parentId,
260
- message: message_0
271
+ message: message_1
261
272
  };
262
- parentId = storageFormatAdapter.getId(message_0);
273
+ parentId = storageFormatAdapter.getId(message_1);
263
274
  return item_0;
264
275
  });
265
276
  const deletion = persistInFlightRef.current.then(async () => {
@@ -1 +1 @@
1
- {"version":3,"file":"useExternalHistory.js","names":["AssistantRuntime","ThreadHistoryAdapter","ThreadMessage","MessageFormatAdapter","MessageFormatItem","MessageFormatRepository","ExportedMessageRepository","getExternalStoreMessages","MessageRepository","useAui","useRef","useEffect","useState","RefObject","useCallback","useMemo","toExportedMessageRepository","toThreadMessages","messages","TMessage","survivingIds","Set","survivors","flatMap","m","message","console","warn","parentId","has","add","id","headId","isAwaitingToolApproval","status","type","reason","encodeContent","storageFormatAdapter","item","JSON","stringify","encode","useExternalHistory","runtimeRef","historyAdapter","onSetMessages","loadedRef","itemEpoch","setItemEpoch","aui","optionalThreadListItem","threadListItem","source","hasLoaded","setHasLoaded","historyIds","deferredTelemetryIds","persistedInnerMessages","Map","content","onSetMessagesRef","current","formatAdapter","undefined","withFormat","Error","isLoading","loadHistory","repo","load","length","set","getId","converted","thread","import","tempRepo","getMessages","error","pin","remoteId","getState","subscribe","n","threadState","isRunning","runStartRef","persistTimerRef","ReturnType","setTimeout","persistInFlightRef","Promise","resolve","stepBoundariesRef","wasRunningRef","toolCallCountRef","adapter","unsubscribe","wasRunning","lastMsg","at","role","currentToolCallCount","filter","p","push","Date","now","clearTimeout","persistSettled","initialThreadState","ignoreRunning","latest","boundaries","durationMs","lastAssistant","findLast","tcCount","totalSteps","stepDur","i","Math","round","stepTimestamps","map","endMs","start_ms","end_ms","telemetryOptions","then","lastInnerMessageId","getLastInnerId","msgs","toBatchItems","msg","idx","innerMessages","isTerminal","isAwaitingToolCalls","isReady","update","batchItems","innerId","persisted","get","append","delete","reportTelemetry","catch","deleteMessage","messageId","deleteMessages","bind","messageIndex","findIndex","previousInnerMessages","slice","itemsToDelete","deletion"],"sources":["../../src/runtime/useExternalHistory.ts"],"sourcesContent":["\"use client\";\n\nimport type {\n AssistantRuntime,\n ThreadHistoryAdapter,\n ThreadMessage,\n MessageFormatAdapter,\n MessageFormatItem,\n MessageFormatRepository,\n ExportedMessageRepository,\n} from \"@assistant-ui/core\";\nimport { getExternalStoreMessages } from \"@assistant-ui/core\";\nimport { MessageRepository } from \"@assistant-ui/core/internal\";\nimport { useAui } from \"@assistant-ui/store\";\nimport {\n useRef,\n useEffect,\n useState,\n type RefObject,\n useCallback,\n useMemo,\n} from \"react\";\n\nexport const toExportedMessageRepository = <TMessage>(\n toThreadMessages: (messages: TMessage[]) => ThreadMessage[],\n messages: MessageFormatRepository<TMessage>,\n): ExportedMessageRepository => {\n const survivingIds = new Set<string>();\n const survivors = messages.messages.flatMap((m) => {\n const message = toThreadMessages([m.message])[0];\n if (!message) {\n console.warn(\"Skipping a stored message that could not be loaded.\");\n return [];\n }\n if (m.parentId && !survivingIds.has(m.parentId)) return [];\n survivingIds.add(message.id);\n return [{ ...m, message }];\n });\n\n return {\n headId:\n messages.headId && survivingIds.has(messages.headId)\n ? messages.headId\n : null,\n messages: survivors,\n };\n};\n\nconst isAwaitingToolApproval = (message: ThreadMessage) =>\n message.status?.type === \"requires-action\" &&\n message.status.reason === \"tool-calls\";\n\nconst encodeContent = <TMessage>(\n storageFormatAdapter: MessageFormatAdapter<TMessage, any>,\n item: MessageFormatItem<TMessage>,\n) => JSON.stringify(storageFormatAdapter.encode(item));\n\nexport const useExternalHistory = <TMessage>(\n runtimeRef: RefObject<AssistantRuntime>,\n historyAdapter: ThreadHistoryAdapter | undefined,\n toThreadMessages: (messages: TMessage[]) => ThreadMessage[],\n storageFormatAdapter: MessageFormatAdapter<TMessage, any>,\n onSetMessages: (messages: TMessage[]) => void,\n) => {\n const loadedRef = useRef(false);\n const [itemEpoch, setItemEpoch] = useState(0);\n\n const aui = useAui();\n const optionalThreadListItem = useCallback(\n () => (aui.threadListItem.source ? aui.threadListItem : null),\n [aui],\n );\n\n const [hasLoaded, setHasLoaded] = useState(false);\n\n const historyIds = useRef(new Set<string>());\n const deferredTelemetryIds = useRef(new Set<string>());\n // `content` is a snapshot taken at write time rather than a re-encode of `source`, because a retained message object can be mutated in place by the runtime that produced it.\n const persistedInnerMessages = useRef(\n new Map<string, { source: TMessage; content: string }>(),\n );\n\n const onSetMessagesRef = useRef(onSetMessages);\n useEffect(() => {\n onSetMessagesRef.current = onSetMessages;\n });\n\n const formatAdapter = useMemo(() => {\n if (!historyAdapter) return undefined;\n if (!historyAdapter.withFormat) {\n throw new Error(\n \"useAISDKRuntime: ThreadHistoryAdapter is missing the required `withFormat` method.\",\n );\n }\n return historyAdapter.withFormat<TMessage, any>(storageFormatAdapter);\n }, [historyAdapter, storageFormatAdapter]);\n\n const isLoading = formatAdapter != null && !hasLoaded;\n\n useEffect(() => {\n if (!formatAdapter || loadedRef.current) return undefined;\n\n const loadHistory = async () => {\n try {\n const repo = await formatAdapter.load();\n if (repo && repo.messages.length > 0) {\n for (const m of repo.messages) {\n persistedInnerMessages.current.set(\n storageFormatAdapter.getId(m.message),\n {\n source: m.message,\n content: encodeContent(storageFormatAdapter, m),\n },\n );\n }\n const converted = toExportedMessageRepository(toThreadMessages, repo);\n runtimeRef.current.thread.import(converted);\n\n const tempRepo = new MessageRepository();\n tempRepo.import(converted);\n const messages = tempRepo.getMessages();\n\n onSetMessagesRef.current(\n messages.flatMap(getExternalStoreMessages<TMessage>),\n );\n\n historyIds.current = new Set();\n for (const m of converted.messages) {\n historyIds.current.add(m.message.id);\n if (isAwaitingToolApproval(m.message)) {\n deferredTelemetryIds.current.add(m.message.id);\n }\n }\n }\n } catch (error) {\n console.error(\"Failed to load message history:\", error);\n } finally {\n setHasLoaded(true);\n }\n };\n\n formatAdapter.pin?.();\n\n const remoteId = optionalThreadListItem()?.getState().remoteId;\n if (!remoteId) {\n // History loads asynchronously against the thread list item; without a\n // remote id there is nothing to await, so the flag settles here.\n // eslint-disable-next-line react-hooks/set-state-in-effect\n setHasLoaded(true);\n return aui.subscribe(() => {\n if (optionalThreadListItem()?.getState().remoteId) {\n setItemEpoch((n) => n + 1);\n }\n });\n }\n\n const threadState = runtimeRef.current.thread.getState();\n if (threadState.isRunning || threadState.messages.length > 0) {\n loadedRef.current = true;\n setHasLoaded(true);\n return undefined;\n }\n\n loadedRef.current = true;\n void loadHistory();\n return undefined;\n }, [\n formatAdapter,\n toThreadMessages,\n runtimeRef,\n optionalThreadListItem,\n aui,\n itemEpoch,\n storageFormatAdapter,\n ]);\n\n const runStartRef = useRef<number | null>(null);\n const persistTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const persistInFlightRef = useRef<Promise<void>>(Promise.resolve());\n const stepBoundariesRef = useRef<number[]>([]);\n const wasRunningRef = useRef(false);\n const toolCallCountRef = useRef(0);\n\n useEffect(() => {\n if (!formatAdapter) return;\n const adapter = formatAdapter;\n\n const unsubscribe = runtimeRef.current.thread.subscribe(() => {\n const threadState = runtimeRef.current.thread.getState();\n const { isRunning } = threadState;\n const wasRunning = wasRunningRef.current;\n wasRunningRef.current = isRunning;\n\n // Track step boundaries by content changes (more reliable than isRunning)\n if (runStartRef.current != null) {\n const lastMsg = threadState.messages.at(-1);\n if (lastMsg?.role === \"assistant\") {\n const currentToolCallCount = lastMsg.content.filter(\n (p) => p.type === \"tool-call\",\n ).length;\n while (toolCallCountRef.current < currentToolCallCount) {\n stepBoundariesRef.current.push(Date.now() - runStartRef.current);\n toolCallCountRef.current++;\n }\n }\n }\n\n if (isRunning) {\n if (runStartRef.current == null) {\n runStartRef.current = Date.now();\n stepBoundariesRef.current = [];\n toolCallCountRef.current = 0;\n adapter.pin?.();\n }\n // Cancel any pending persist — isRunning went back to true\n if (persistTimerRef.current) {\n clearTimeout(persistTimerRef.current);\n persistTimerRef.current = null;\n }\n return;\n }\n\n // Only act on the true→false transition\n if (!wasRunning) return;\n\n // Record step boundary offset (synchronous for accuracy)\n if (runStartRef.current != null) {\n stepBoundariesRef.current.push(Date.now() - runStartRef.current);\n }\n\n // Debounce: wait one macrotask so agentic step flickers are absorbed\n if (persistTimerRef.current) clearTimeout(persistTimerRef.current);\n persistTimerRef.current = setTimeout(() => {\n persistSettled(false);\n }, 0);\n });\n\n const initialThreadState = runtimeRef.current.thread.getState();\n wasRunningRef.current = initialThreadState.isRunning;\n if (initialThreadState.isRunning) {\n if (runStartRef.current == null) {\n runStartRef.current = Date.now();\n stepBoundariesRef.current = [];\n toolCallCountRef.current = 0;\n adapter.pin?.();\n }\n } else if (initialThreadState.messages.length > 0) {\n persistSettled(true);\n }\n\n function persistSettled(ignoreRunning: boolean) {\n persistTimerRef.current = null;\n const latest = runtimeRef.current.thread.getState();\n if (!ignoreRunning && latest.isRunning) return;\n\n const boundaries = stepBoundariesRef.current;\n const durationMs = boundaries.length > 0 ? boundaries.at(-1) : undefined;\n\n // Fallback: if only 1 boundary but message has multiple steps, distribute evenly\n if (boundaries.length === 1 && durationMs != null) {\n const lastAssistant = latest.messages.findLast(\n (m) => m.role === \"assistant\",\n );\n if (lastAssistant) {\n const tcCount = lastAssistant.content.filter(\n (p) => p.type === \"tool-call\",\n ).length;\n if (tcCount > 0) {\n const totalSteps = tcCount + 1;\n const stepDur = durationMs / totalSteps;\n boundaries.length = 0;\n for (let i = 0; i < totalSteps; i++) {\n boundaries.push(Math.round((i + 1) * stepDur));\n }\n }\n }\n }\n\n // Build per-step timestamps when there are multiple steps\n const stepTimestamps =\n boundaries.length > 1\n ? boundaries.map((endMs, i) => ({\n start_ms: i === 0 ? 0 : boundaries[i - 1]!,\n end_ms: endMs,\n }))\n : undefined;\n\n runStartRef.current = null;\n stepBoundariesRef.current = [];\n\n const telemetryOptions = {\n ...(durationMs != null ? { durationMs } : undefined),\n ...(stepTimestamps != null ? { stepTimestamps } : undefined),\n };\n\n persistInFlightRef.current = persistInFlightRef.current\n .then(async () => {\n const { messages } = latest;\n let lastInnerMessageId: string | null = null;\n\n const getLastInnerId = (msgs: TMessage[]): string | null =>\n msgs.length > 0 ? storageFormatAdapter.getId(msgs.at(-1)!) : null;\n\n const toBatchItems = (msgs: TMessage[]) =>\n msgs.map((msg, idx) => ({\n parentId:\n idx === 0\n ? lastInnerMessageId\n : storageFormatAdapter.getId(msgs[idx - 1]!),\n message: msg,\n }));\n\n for (const message of messages) {\n const innerMessages = getExternalStoreMessages<TMessage>(message);\n\n const isTerminal =\n message.status === undefined ||\n message.status.type === \"complete\" ||\n message.status.type === \"incomplete\";\n const isAwaitingToolCalls = isAwaitingToolApproval(message);\n // A paused message's later content can only reach storage via update, so it is persisted early only when the adapter supports update.\n const isReady =\n isTerminal ||\n (isAwaitingToolCalls && adapter.update !== undefined);\n\n if (!isReady) {\n lastInnerMessageId =\n getLastInnerId(innerMessages) ?? lastInnerMessageId;\n continue;\n }\n\n if (!historyIds.current.has(message.id)) {\n historyIds.current.add(message.id);\n deferredTelemetryIds.current.add(message.id);\n }\n\n const batchItems = toBatchItems(innerMessages);\n for (const item of batchItems) {\n const innerId = storageFormatAdapter.getId(item.message);\n const persisted = persistedInnerMessages.current.get(innerId);\n if (!persisted) {\n await adapter.append(item);\n persistedInnerMessages.current.set(innerId, {\n source: item.message,\n content: encodeContent(storageFormatAdapter, item),\n });\n } else if (\n persisted.source !== item.message &&\n durationMs !== undefined &&\n adapter.update\n ) {\n const content = encodeContent(storageFormatAdapter, item);\n if (content === persisted.content) {\n persisted.source = item.message;\n } else {\n try {\n await adapter.update(item, innerId);\n persistedInnerMessages.current.set(innerId, {\n source: item.message,\n content,\n });\n } catch {\n // A failed update leaves the stale baseline behind so the next run stop retries it.\n }\n }\n }\n }\n\n lastInnerMessageId =\n getLastInnerId(innerMessages) ?? lastInnerMessageId;\n\n if (deferredTelemetryIds.current.has(message.id) && isTerminal) {\n deferredTelemetryIds.current.delete(message.id);\n adapter.reportTelemetry?.(batchItems, telemetryOptions);\n }\n }\n })\n .catch((error) => {\n console.error(\"Failed to persist message history:\", error);\n });\n }\n\n return () => {\n unsubscribe();\n if (persistTimerRef.current) {\n clearTimeout(persistTimerRef.current);\n persistTimerRef.current = null;\n persistSettled(false);\n }\n };\n }, [formatAdapter, storageFormatAdapter, runtimeRef]);\n\n const deleteMessage = useCallback(\n async (messageId: string) => {\n const deleteMessages = formatAdapter?.delete?.bind(formatAdapter);\n if (!deleteMessages) return;\n\n const messages = runtimeRef.current.thread.getState().messages;\n const messageIndex = messages.findIndex((m) => m.id === messageId);\n if (messageIndex === -1) return;\n\n const previousInnerMessages = messages\n .slice(0, messageIndex)\n .flatMap(getExternalStoreMessages<TMessage>);\n let parentId = previousInnerMessages.at(-1)\n ? storageFormatAdapter.getId(previousInnerMessages.at(-1)!)\n : null;\n const itemsToDelete = getExternalStoreMessages<TMessage>(\n messages[messageIndex]!,\n ).map((message) => {\n const item = { parentId, message };\n parentId = storageFormatAdapter.getId(message);\n return item;\n });\n\n const deletion = persistInFlightRef.current.then(async () => {\n await deleteMessages(itemsToDelete);\n\n historyIds.current.delete(messageId);\n deferredTelemetryIds.current.delete(messageId);\n for (const item of itemsToDelete) {\n persistedInnerMessages.current.delete(\n storageFormatAdapter.getId(item.message),\n );\n }\n });\n\n persistInFlightRef.current = deletion.catch(() => {});\n await deletion;\n },\n [formatAdapter, runtimeRef, storageFormatAdapter],\n );\n\n return { isLoading, deleteMessage };\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"useExternalHistory.js","names":["AssistantRuntime","ThreadHistoryAdapter","ThreadMessage","MessageFormatAdapter","MessageFormatItem","MessageFormatRepository","ExportedMessageRepository","getExternalStoreMessages","MessageRepository","useAui","useRef","useEffect","useState","RefObject","useCallback","useMemo","toExportedMessageRepository","toThreadMessages","messages","TMessage","survivingIds","Set","survivors","flatMap","m","message","console","warn","parentId","has","add","id","headId","isAwaitingToolApproval","status","type","reason","isTerminalMessage","undefined","encodeContent","storageFormatAdapter","item","JSON","stringify","encode","useExternalHistory","runtimeRef","historyAdapter","onSetMessages","loadedRef","itemEpoch","setItemEpoch","aui","optionalThreadListItem","threadListItem","source","hasLoaded","setHasLoaded","historyIds","deferredTelemetryIds","persistedInnerMessages","Map","content","onSetMessagesRef","current","formatAdapter","withFormat","Error","isLoading","loadHistory","repo","load","length","set","getId","converted","thread","import","tempRepo","getMessages","error","pin","remoteId","getState","subscribe","n","threadState","isRunning","runStartRef","persistTimerRef","ReturnType","setTimeout","persistInFlightRef","Promise","resolve","stepBoundariesRef","wasRunningRef","toolCallCountRef","adapter","idleScheduledInnerIds","unpersistedInnerIds","map","innerMessage","filter","innerId","unsubscribe","wasRunning","lastMsg","at","role","currentToolCallCount","p","push","Date","now","clearTimeout","pending","every","persistSettled","initialThreadState","ignoreRunning","latest","boundaries","durationMs","lastAssistant","findLast","tcCount","totalSteps","stepDur","i","Math","round","stepTimestamps","endMs","start_ms","end_ms","telemetryOptions","then","lastInnerMessageId","getLastInnerId","msgs","toBatchItems","msg","idx","innerMessages","isTerminal","isAwaitingToolCalls","isReady","update","batchItems","persisted","get","append","delete","reportTelemetry","catch","deleteMessage","messageId","deleteMessages","bind","messageIndex","findIndex","previousInnerMessages","slice","itemsToDelete","deletion"],"sources":["../../src/runtime/useExternalHistory.ts"],"sourcesContent":["\"use client\";\n\nimport type {\n AssistantRuntime,\n ThreadHistoryAdapter,\n ThreadMessage,\n MessageFormatAdapter,\n MessageFormatItem,\n MessageFormatRepository,\n ExportedMessageRepository,\n} from \"@assistant-ui/core\";\nimport { getExternalStoreMessages } from \"@assistant-ui/core\";\nimport { MessageRepository } from \"@assistant-ui/core/internal\";\nimport { useAui } from \"@assistant-ui/store\";\nimport {\n useRef,\n useEffect,\n useState,\n type RefObject,\n useCallback,\n useMemo,\n} from \"react\";\n\nexport const toExportedMessageRepository = <TMessage>(\n toThreadMessages: (messages: TMessage[]) => ThreadMessage[],\n messages: MessageFormatRepository<TMessage>,\n): ExportedMessageRepository => {\n const survivingIds = new Set<string>();\n const survivors = messages.messages.flatMap((m) => {\n const message = toThreadMessages([m.message])[0];\n if (!message) {\n console.warn(\"Skipping a stored message that could not be loaded.\");\n return [];\n }\n if (m.parentId && !survivingIds.has(m.parentId)) return [];\n survivingIds.add(message.id);\n return [{ ...m, message }];\n });\n\n return {\n headId:\n messages.headId && survivingIds.has(messages.headId)\n ? messages.headId\n : null,\n messages: survivors,\n };\n};\n\nconst isAwaitingToolApproval = (message: ThreadMessage) =>\n message.status?.type === \"requires-action\" &&\n message.status.reason === \"tool-calls\";\n\nconst isTerminalMessage = (message: ThreadMessage) =>\n message.status === undefined ||\n message.status.type === \"complete\" ||\n message.status.type === \"incomplete\";\n\nconst encodeContent = <TMessage>(\n storageFormatAdapter: MessageFormatAdapter<TMessage, any>,\n item: MessageFormatItem<TMessage>,\n) => JSON.stringify(storageFormatAdapter.encode(item));\n\nexport const useExternalHistory = <TMessage>(\n runtimeRef: RefObject<AssistantRuntime>,\n historyAdapter: ThreadHistoryAdapter | undefined,\n toThreadMessages: (messages: TMessage[]) => ThreadMessage[],\n storageFormatAdapter: MessageFormatAdapter<TMessage, any>,\n onSetMessages: (messages: TMessage[]) => void,\n) => {\n const loadedRef = useRef(false);\n const [itemEpoch, setItemEpoch] = useState(0);\n\n const aui = useAui();\n const optionalThreadListItem = useCallback(\n () => (aui.threadListItem.source ? aui.threadListItem : null),\n [aui],\n );\n\n const [hasLoaded, setHasLoaded] = useState(false);\n\n const historyIds = useRef(new Set<string>());\n const deferredTelemetryIds = useRef(new Set<string>());\n // `content` is a snapshot taken at write time rather than a re-encode of `source`, because a retained message object can be mutated in place by the runtime that produced it.\n const persistedInnerMessages = useRef(\n new Map<string, { source: TMessage; content: string }>(),\n );\n\n const onSetMessagesRef = useRef(onSetMessages);\n useEffect(() => {\n onSetMessagesRef.current = onSetMessages;\n });\n\n const formatAdapter = useMemo(() => {\n if (!historyAdapter) return undefined;\n if (!historyAdapter.withFormat) {\n throw new Error(\n \"useAISDKRuntime: ThreadHistoryAdapter is missing the required `withFormat` method.\",\n );\n }\n return historyAdapter.withFormat<TMessage, any>(storageFormatAdapter);\n }, [historyAdapter, storageFormatAdapter]);\n\n const isLoading = formatAdapter != null && !hasLoaded;\n\n useEffect(() => {\n if (!formatAdapter || loadedRef.current) return undefined;\n\n const loadHistory = async () => {\n try {\n const repo = await formatAdapter.load();\n if (repo && repo.messages.length > 0) {\n for (const m of repo.messages) {\n persistedInnerMessages.current.set(\n storageFormatAdapter.getId(m.message),\n {\n source: m.message,\n content: encodeContent(storageFormatAdapter, m),\n },\n );\n }\n const converted = toExportedMessageRepository(toThreadMessages, repo);\n runtimeRef.current.thread.import(converted);\n\n const tempRepo = new MessageRepository();\n tempRepo.import(converted);\n const messages = tempRepo.getMessages();\n\n onSetMessagesRef.current(\n messages.flatMap(getExternalStoreMessages<TMessage>),\n );\n\n historyIds.current = new Set();\n for (const m of converted.messages) {\n historyIds.current.add(m.message.id);\n if (isAwaitingToolApproval(m.message)) {\n deferredTelemetryIds.current.add(m.message.id);\n }\n }\n }\n } catch (error) {\n console.error(\"Failed to load message history:\", error);\n } finally {\n setHasLoaded(true);\n }\n };\n\n formatAdapter.pin?.();\n\n const remoteId = optionalThreadListItem()?.getState().remoteId;\n if (!remoteId) {\n // History loads asynchronously against the thread list item; without a\n // remote id there is nothing to await, so the flag settles here.\n // eslint-disable-next-line react-hooks/set-state-in-effect\n setHasLoaded(true);\n return aui.subscribe(() => {\n if (optionalThreadListItem()?.getState().remoteId) {\n setItemEpoch((n) => n + 1);\n }\n });\n }\n\n const threadState = runtimeRef.current.thread.getState();\n if (threadState.isRunning || threadState.messages.length > 0) {\n loadedRef.current = true;\n setHasLoaded(true);\n return undefined;\n }\n\n loadedRef.current = true;\n void loadHistory();\n return undefined;\n }, [\n formatAdapter,\n toThreadMessages,\n runtimeRef,\n optionalThreadListItem,\n aui,\n itemEpoch,\n storageFormatAdapter,\n ]);\n\n const runStartRef = useRef<number | null>(null);\n const persistTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const persistInFlightRef = useRef<Promise<void>>(Promise.resolve());\n const stepBoundariesRef = useRef<number[]>([]);\n const wasRunningRef = useRef(false);\n const toolCallCountRef = useRef(0);\n\n useEffect(() => {\n if (!formatAdapter) return;\n const adapter = formatAdapter;\n\n const idleScheduledInnerIds = new Set<string>();\n const unpersistedInnerIds = (message: ThreadMessage) =>\n isTerminalMessage(message)\n ? getExternalStoreMessages<TMessage>(message)\n .map((innerMessage) => storageFormatAdapter.getId(innerMessage))\n .filter((innerId) => !persistedInnerMessages.current.has(innerId))\n : [];\n\n const unsubscribe = runtimeRef.current.thread.subscribe(() => {\n const threadState = runtimeRef.current.thread.getState();\n const { isRunning } = threadState;\n const wasRunning = wasRunningRef.current;\n wasRunningRef.current = isRunning;\n\n // Track step boundaries by content changes (more reliable than isRunning)\n if (runStartRef.current != null) {\n const lastMsg = threadState.messages.at(-1);\n if (lastMsg?.role === \"assistant\") {\n const currentToolCallCount = lastMsg.content.filter(\n (p) => p.type === \"tool-call\",\n ).length;\n while (toolCallCountRef.current < currentToolCallCount) {\n stepBoundariesRef.current.push(Date.now() - runStartRef.current);\n toolCallCountRef.current++;\n }\n }\n }\n\n if (isRunning) {\n if (runStartRef.current == null) {\n runStartRef.current = Date.now();\n stepBoundariesRef.current = [];\n toolCallCountRef.current = 0;\n adapter.pin?.();\n }\n // Cancel any pending persist — isRunning went back to true\n if (persistTimerRef.current) {\n clearTimeout(persistTimerRef.current);\n persistTimerRef.current = null;\n }\n return;\n }\n\n if (wasRunning) {\n // Record step boundary offset (synchronous for accuracy)\n if (runStartRef.current != null) {\n stepBoundariesRef.current.push(Date.now() - runStartRef.current);\n }\n } else {\n const pending = threadState.messages.flatMap(unpersistedInnerIds);\n if (pending.every((innerId) => idleScheduledInnerIds.has(innerId)))\n return;\n for (const innerId of pending) idleScheduledInnerIds.add(innerId);\n }\n\n // Debounce: wait one macrotask so agentic step flickers are absorbed\n if (persistTimerRef.current) clearTimeout(persistTimerRef.current);\n persistTimerRef.current = setTimeout(() => {\n persistSettled(false);\n }, 0);\n });\n\n const initialThreadState = runtimeRef.current.thread.getState();\n wasRunningRef.current = initialThreadState.isRunning;\n if (initialThreadState.isRunning) {\n if (runStartRef.current == null) {\n runStartRef.current = Date.now();\n stepBoundariesRef.current = [];\n toolCallCountRef.current = 0;\n adapter.pin?.();\n }\n } else if (initialThreadState.messages.length > 0) {\n persistSettled(true);\n }\n\n function persistSettled(ignoreRunning: boolean) {\n persistTimerRef.current = null;\n const latest = runtimeRef.current.thread.getState();\n if (!ignoreRunning && latest.isRunning) return;\n\n const boundaries = stepBoundariesRef.current;\n const durationMs = boundaries.length > 0 ? boundaries.at(-1) : undefined;\n\n // Fallback: if only 1 boundary but message has multiple steps, distribute evenly\n if (boundaries.length === 1 && durationMs != null) {\n const lastAssistant = latest.messages.findLast(\n (m) => m.role === \"assistant\",\n );\n if (lastAssistant) {\n const tcCount = lastAssistant.content.filter(\n (p) => p.type === \"tool-call\",\n ).length;\n if (tcCount > 0) {\n const totalSteps = tcCount + 1;\n const stepDur = durationMs / totalSteps;\n boundaries.length = 0;\n for (let i = 0; i < totalSteps; i++) {\n boundaries.push(Math.round((i + 1) * stepDur));\n }\n }\n }\n }\n\n // Build per-step timestamps when there are multiple steps\n const stepTimestamps =\n boundaries.length > 1\n ? boundaries.map((endMs, i) => ({\n start_ms: i === 0 ? 0 : boundaries[i - 1]!,\n end_ms: endMs,\n }))\n : undefined;\n\n runStartRef.current = null;\n stepBoundariesRef.current = [];\n\n const telemetryOptions = {\n ...(durationMs != null ? { durationMs } : undefined),\n ...(stepTimestamps != null ? { stepTimestamps } : undefined),\n };\n\n persistInFlightRef.current = persistInFlightRef.current\n .then(async () => {\n const { messages } = latest;\n let lastInnerMessageId: string | null = null;\n\n const getLastInnerId = (msgs: TMessage[]): string | null =>\n msgs.length > 0 ? storageFormatAdapter.getId(msgs.at(-1)!) : null;\n\n const toBatchItems = (msgs: TMessage[]) =>\n msgs.map((msg, idx) => ({\n parentId:\n idx === 0\n ? lastInnerMessageId\n : storageFormatAdapter.getId(msgs[idx - 1]!),\n message: msg,\n }));\n\n for (const message of messages) {\n const innerMessages = getExternalStoreMessages<TMessage>(message);\n\n const isTerminal = isTerminalMessage(message);\n const isAwaitingToolCalls = isAwaitingToolApproval(message);\n // A paused message's later content can only reach storage via update, so it is persisted early only when the adapter supports update.\n const isReady =\n isTerminal ||\n (isAwaitingToolCalls && adapter.update !== undefined);\n\n if (!isReady) {\n lastInnerMessageId =\n getLastInnerId(innerMessages) ?? lastInnerMessageId;\n continue;\n }\n\n if (!historyIds.current.has(message.id)) {\n historyIds.current.add(message.id);\n deferredTelemetryIds.current.add(message.id);\n }\n\n const batchItems = toBatchItems(innerMessages);\n for (const item of batchItems) {\n const innerId = storageFormatAdapter.getId(item.message);\n const persisted = persistedInnerMessages.current.get(innerId);\n if (!persisted) {\n await adapter.append(item);\n persistedInnerMessages.current.set(innerId, {\n source: item.message,\n content: encodeContent(storageFormatAdapter, item),\n });\n } else if (\n persisted.source !== item.message &&\n durationMs !== undefined &&\n adapter.update\n ) {\n const content = encodeContent(storageFormatAdapter, item);\n if (content === persisted.content) {\n persisted.source = item.message;\n } else {\n try {\n await adapter.update(item, innerId);\n persistedInnerMessages.current.set(innerId, {\n source: item.message,\n content,\n });\n } catch {\n // A failed update leaves the stale baseline behind so the next run stop retries it.\n }\n }\n }\n }\n\n lastInnerMessageId =\n getLastInnerId(innerMessages) ?? lastInnerMessageId;\n\n if (deferredTelemetryIds.current.has(message.id) && isTerminal) {\n deferredTelemetryIds.current.delete(message.id);\n adapter.reportTelemetry?.(batchItems, {\n ...telemetryOptions,\n message,\n });\n }\n }\n })\n .catch((error) => {\n console.error(\"Failed to persist message history:\", error);\n });\n }\n\n return () => {\n unsubscribe();\n if (persistTimerRef.current) {\n clearTimeout(persistTimerRef.current);\n persistTimerRef.current = null;\n persistSettled(false);\n }\n };\n }, [formatAdapter, storageFormatAdapter, runtimeRef]);\n\n const deleteMessage = useCallback(\n async (messageId: string) => {\n const deleteMessages = formatAdapter?.delete?.bind(formatAdapter);\n if (!deleteMessages) return;\n\n const messages = runtimeRef.current.thread.getState().messages;\n const messageIndex = messages.findIndex((m) => m.id === messageId);\n if (messageIndex === -1) return;\n\n const previousInnerMessages = messages\n .slice(0, messageIndex)\n .flatMap(getExternalStoreMessages<TMessage>);\n let parentId = previousInnerMessages.at(-1)\n ? storageFormatAdapter.getId(previousInnerMessages.at(-1)!)\n : null;\n const itemsToDelete = getExternalStoreMessages<TMessage>(\n messages[messageIndex]!,\n ).map((message) => {\n const item = { parentId, message };\n parentId = storageFormatAdapter.getId(message);\n return item;\n });\n\n const deletion = persistInFlightRef.current.then(async () => {\n await deleteMessages(itemsToDelete);\n\n historyIds.current.delete(messageId);\n deferredTelemetryIds.current.delete(messageId);\n for (const item of itemsToDelete) {\n persistedInnerMessages.current.delete(\n storageFormatAdapter.getId(item.message),\n );\n }\n });\n\n persistInFlightRef.current = deletion.catch(() => {});\n await deletion;\n },\n [formatAdapter, runtimeRef, storageFormatAdapter],\n );\n\n return { isLoading, deleteMessage };\n};\n"],"mappings":"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"}
@@ -1,5 +1,4 @@
1
1
  //#region src/runtime/useResourceCleanup.d.ts
2
- declare const useResourceCleanup: (enabled: boolean, cleanup: () => void) => void;
2
+ export declare const useResourceCleanup: (enabled: boolean, cleanup: () => void) => void;
3
3
  //#endregion
4
- export { useResourceCleanup };
5
4
  //# sourceMappingURL=useResourceCleanup.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useResourceCleanup.d.ts","names":[],"sources":["../../src/runtime/useResourceCleanup.ts"],"mappings":";cAGa,qBAAsB,kBAAkB"}
1
+ {"version":3,"file":"useResourceCleanup.d.ts","names":[],"sources":["../../src/runtime/useResourceCleanup.ts"],"mappings":";qBAGa,qBAAsB,kBAAkB"}
@@ -2,14 +2,13 @@ import { StreamingTimingAccessors } from "@assistant-ui/core/react";
2
2
  import { MessageTiming } from "@assistant-ui/core";
3
3
  import { UIMessage } from "@ai-sdk/react";
4
4
  //#region src/runtime/useStreamingTiming.d.ts
5
- declare const aiSdkStreamingTimingAccessors: StreamingTimingAccessors<UIMessage>;
5
+ export declare const aiSdkStreamingTimingAccessors: StreamingTimingAccessors<UIMessage>;
6
6
  /**
7
7
  * Tracks streaming timing for AI SDK messages client-side. Delegates to the
8
8
  * shared `useStreamingTiming` primitive in `@assistant-ui/core/react`,
9
9
  * adapted to the `UIMessage` shape. Timing is finalized when streaming ends
10
10
  * and stored per message id.
11
11
  */
12
- declare const useStreamingTiming: (messages: UIMessage[], isRunning: boolean) => Record<string, MessageTiming>;
12
+ export declare const useStreamingTiming: (messages: UIMessage[], isRunning: boolean) => Record<string, MessageTiming>;
13
13
  //#endregion
14
- export { aiSdkStreamingTimingAccessors, useStreamingTiming };
15
14
  //# sourceMappingURL=useStreamingTiming.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useStreamingTiming.d.ts","names":[],"sources":["../../src/runtime/useStreamingTiming.ts"],"mappings":";;;;cA8Ca,+BAA+B,yBAAyB;;;;;;;cAaxD,qBACX,UAAU,aACV,uBACC,eAAe"}
1
+ {"version":3,"file":"useStreamingTiming.d.ts","names":[],"sources":["../../src/runtime/useStreamingTiming.ts"],"mappings":";;;;qBA8Ca,+BAA+B,yBAAyB;;;;;;;qBAaxD,qBACX,UAAU,aACV,uBACC,eAAe"}
@@ -2,8 +2,8 @@ import { ToolSet } from "ai";
2
2
  import { ToolJSONSchema } from "assistant-stream";
3
3
  //#region src/tools/frontendTools.d.ts
4
4
  /** Frontend tool definitions uploaded by AssistantChatTransport. */
5
- type FrontendTools = Record<string, ToolJSONSchema>;
6
- declare const defaultToModelOutput: ({ output }: {
5
+ export type FrontendTools = Record<string, ToolJSONSchema>;
6
+ export declare const defaultToModelOutput: ({ output }: {
7
7
  output: unknown;
8
8
  }) => {
9
9
  type: "content";
@@ -27,7 +27,6 @@ declare const defaultToModelOutput: ({ output }: {
27
27
  type: "json";
28
28
  value: import("ai").JSONValue;
29
29
  };
30
- declare const frontendTools: (tools: FrontendTools) => ToolSet;
30
+ export declare const frontendTools: (tools: FrontendTools) => ToolSet;
31
31
  //#endregion
32
- export { FrontendTools, defaultToModelOutput, frontendTools };
33
32
  //# sourceMappingURL=frontendTools.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"frontendTools.d.ts","names":[],"sources":["../../src/tools/frontendTools.ts"],"mappings":";;;;KASY,gBAAgB,eAAe;cAE9B,yBAAwB;EAAc;;;;;;;;;;;;;;;;;;;;;;;cAuDtC,gBAAiB,OAAO,kBAAgB"}
1
+ {"version":3,"file":"frontendTools.d.ts","names":[],"sources":["../../src/tools/frontendTools.ts"],"mappings":";;;;YASY,gBAAgB,eAAe;qBAE9B,yBAAwB;EAAc;;;;;;;;;;;;;;;;;;;;;;;qBAuDtC,gBAAiB,OAAO,kBAAgB"}
@@ -7,7 +7,7 @@ import { ToolSet } from "ai";
7
7
  * {@link AISDKToolkit} with {@link AISDKToolkitOptions} /
8
8
  * {@link AISDKToolkitToolsOptions} instead.
9
9
  */
10
- interface GenerativeToolsOptions {
10
+ export interface GenerativeToolsOptions {
11
11
  /**
12
12
  * The server build of a generative toolkit (schema + server `execute`). Typed
13
13
  * as the canonical {@link Toolkit} so callers don't need to cast; the server
@@ -21,10 +21,10 @@ interface GenerativeToolsOptions {
21
21
  */
22
22
  frontendTools?: FrontendTools;
23
23
  }
24
- type AISDKToolkitOptions = {
24
+ export type AISDKToolkitOptions = {
25
25
  toolkit: Toolkit;
26
26
  };
27
- type AISDKToolkitToolsOptions = {
27
+ export type AISDKToolkitToolsOptions = {
28
28
  /**
29
29
  * Tools uploaded by the frontend request body.
30
30
  */
@@ -61,13 +61,12 @@ type AISDKToolkitToolsOptions = {
61
61
  * });
62
62
  * ```
63
63
  */
64
- declare const generativeTools: (options: GenerativeToolsOptions) => ToolSet;
65
- declare class AISDKToolkit {
64
+ export declare const generativeTools: (options: GenerativeToolsOptions) => ToolSet;
65
+ export declare class AISDKToolkit {
66
66
  #private;
67
67
  constructor(options: AISDKToolkitOptions);
68
68
  tools(options?: AISDKToolkitToolsOptions): Promise<ToolSet>;
69
69
  close(): Promise<void>;
70
70
  }
71
71
  //#endregion
72
- export { AISDKToolkit, AISDKToolkitOptions, AISDKToolkitToolsOptions, GenerativeToolsOptions, generativeTools };
73
72
  //# sourceMappingURL=generativeTools.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"generativeTools.d.ts","names":[],"sources":["../../src/tools/generativeTools.ts"],"mappings":";;;;;;;;;UAsFiB;;;;;;EAMf,SAAS;;;;;;EAMT,gBAAgB;;KAGN;EACV,SAAS;;KAGC;;;;EAIV,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAkCA,kBAAmB,SAAS,2BAAyB;cAYrD;;EAIC,YAAA,SAAS;EAIf,MAAM,UAAS,2BAAgC,QAAQ;EAsBvD,SAAS"}
1
+ {"version":3,"file":"generativeTools.d.ts","names":[],"sources":["../../src/tools/generativeTools.ts"],"mappings":";;;;;;;;;iBAsFiB;;;;;;EAMf,SAAS;;;;;;EAMT,gBAAgB;;YAGN;EACV,SAAS;;YAGC;;;;EAIV,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qBAkCA,kBAAmB,SAAS,2BAAyB;qBAYrD;;EAIC,YAAA,SAAS;EAIf,MAAM,UAAS,2BAAgC,QAAQ;EAsBvD,SAAS"}
@@ -1,6 +1,5 @@
1
1
  import { Experimental_StdioMCPTransport as Experimental_StdioMCPTransport$1 } from "@ai-sdk/mcp/mcp-stdio";
2
2
  //#region src/tools/mcp-stdio.unsupported.d.ts
3
- declare const Experimental_StdioMCPTransport: typeof Experimental_StdioMCPTransport$1;
3
+ export declare const Experimental_StdioMCPTransport: typeof Experimental_StdioMCPTransport$1;
4
4
  //#endregion
5
- export { Experimental_StdioMCPTransport };
6
5
  //# sourceMappingURL=mcp-stdio.unsupported.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-stdio.unsupported.d.ts","names":[],"sources":["../../src/tools/mcp-stdio.unsupported.ts"],"mappings":";;cAUa,uCACuC"}
1
+ {"version":3,"file":"mcp-stdio.unsupported.d.ts","names":[],"sources":["../../src/tools/mcp-stdio.unsupported.ts"],"mappings":";;qBAUa,uCACuC"}
@@ -2,11 +2,11 @@ import { AssistantChatResumableOptions } from "./resumable.js";
2
2
  import { DefaultChatTransport, HttpChatTransportInitOptions, UIMessage } from "ai";
3
3
  import { AssistantRuntime, ThreadListItemRuntime } from "@assistant-ui/core";
4
4
  //#region src/transport/AssistantChatTransport.d.ts
5
- type InitializableThreadListItem = Pick<ThreadListItemRuntime, "initialize">;
6
- type AssistantChatTransportInitOptions<UI_MESSAGE extends UIMessage> = HttpChatTransportInitOptions<UI_MESSAGE> & {
5
+ export type InitializableThreadListItem = Pick<ThreadListItemRuntime, "initialize">;
6
+ export type AssistantChatTransportInitOptions<UI_MESSAGE extends UIMessage> = HttpChatTransportInitOptions<UI_MESSAGE> & {
7
7
  resumable?: AssistantChatResumableOptions;
8
8
  };
9
- declare class AssistantChatTransport<UI_MESSAGE extends UIMessage> extends DefaultChatTransport<UI_MESSAGE> {
9
+ export declare class AssistantChatTransport<UI_MESSAGE extends UIMessage> extends DefaultChatTransport<UI_MESSAGE> {
10
10
  private runtime;
11
11
  private getThreadListItem;
12
12
  private readonly resumable;
@@ -19,5 +19,4 @@ declare class AssistantChatTransport<UI_MESSAGE extends UIMessage> extends Defau
19
19
  __internal_setGetThreadListItem(getter: () => InitializableThreadListItem | undefined): void;
20
20
  }
21
21
  //#endregion
22
- export { AssistantChatTransport, AssistantChatTransportInitOptions, InitializableThreadListItem };
23
22
  //# sourceMappingURL=AssistantChatTransport.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"AssistantChatTransport.d.ts","names":[],"sources":["../../src/transport/AssistantChatTransport.ts"],"mappings":";;;;KAeY,8BAA8B,KACxC;KAaU,kCAAkC,mBAAmB,aAC/D,6BAA6B;EAC3B,YAAY;;cAGH,uBACX,mBAAmB,mBACX,qBAAqB;UACrB;UACA;mBAGS;mBAEA;;EAKV,oBAAoB,uBAAuB;EAOtC,YAAA,cAAc,kCAAkC;EA0D5D,WAAW,SAAS;EAIpB,uBAAuB;EAIvB,gCACE,cAAc"}
1
+ {"version":3,"file":"AssistantChatTransport.d.ts","names":[],"sources":["../../src/transport/AssistantChatTransport.ts"],"mappings":";;;;YAeY,8BAA8B,KACxC;YAaU,kCAAkC,mBAAmB,aAC/D,6BAA6B;EAC3B,YAAY;;qBAGH,uBACX,mBAAmB,mBACX,qBAAqB;UACrB;UACA;mBAGS;mBAEA;;EAKV,oBAAoB,uBAAuB;EAOtC,YAAA,cAAc,kCAAkC;EA0D5D,WAAW,SAAS;EAIpB,uBAAuB;EAIvB,gCACE,cAAc"}
@@ -1,7 +1,7 @@
1
1
  //#region src/transport/resumable.d.ts
2
2
  /** Response header used by the [Resumable Streams](/docs/guides/resumable-streams) server and client wiring. */
3
- declare const RESUMABLE_STREAM_ID_HEADER = "x-resumable-stream-id";
4
- type ResumableClientStorage = {
3
+ export declare const RESUMABLE_STREAM_ID_HEADER = "x-resumable-stream-id";
4
+ export type ResumableClientStorage = {
5
5
  getStreamId(threadId?: string): string | null;
6
6
  setStreamId(id: string, threadId?: string): void;
7
7
  clear(threadId?: string): void;
@@ -9,7 +9,7 @@ type ResumableClientStorage = {
9
9
  subscribe?(listener: () => void, threadId?: string): () => void;
10
10
  };
11
11
  /** `sessionStorage`-backed storage for the pending resumable stream id. See the [Resumable Streams](/docs/guides/resumable-streams) guide for end-to-end wiring. */
12
- declare function createResumableSessionStorage(options?: {
12
+ export declare function createResumableSessionStorage(options?: {
13
13
  /**
14
14
  * Storage key for the pending stream id. A static string namespaces per route
15
15
  * or chat surface. A getter is read lazily on every access, so the key can be
@@ -24,7 +24,7 @@ declare function createResumableSessionStorage(options?: {
24
24
  */
25
25
  key?: string | (() => string | undefined);
26
26
  }): ResumableClientStorage;
27
- type AssistantChatResumableOptions = {
27
+ export type AssistantChatResumableOptions = {
28
28
  storage: ResumableClientStorage;
29
29
  resumeApi: string | ((streamId: string) => string);
30
30
  /**
@@ -34,5 +34,4 @@ type AssistantChatResumableOptions = {
34
34
  isFinishEvent?: (chunk: Uint8Array, accumulator: string) => boolean;
35
35
  };
36
36
  //#endregion
37
- export { AssistantChatResumableOptions, RESUMABLE_STREAM_ID_HEADER, ResumableClientStorage, createResumableSessionStorage };
38
37
  //# sourceMappingURL=resumable.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"resumable.d.ts","names":[],"sources":["../../src/transport/resumable.ts"],"mappings":";;cAKa;KAID;EACV,YAAY;EACZ,YAAY,YAAY;EACxB,MAAM;;EAEN,WAAW,sBAAsB;;;iBAkBnB,8BAA8B;;;;;;;;;;;;;EAa5C;IACE;KA0GQ;EACV,SAAS;EACT,sBAAsB;;;;;EAKtB,iBAAiB,OAAO,YAAY"}
1
+ {"version":3,"file":"resumable.d.ts","names":[],"sources":["../../src/transport/resumable.ts"],"mappings":";;qBAKa;YAID;EACV,YAAY;EACZ,YAAY,YAAY;EACxB,MAAM;;EAEN,WAAW,sBAAsB;;;wBAkBnB,8BAA8B;;;;;;;;;;;;;EAa5C;IACE;YA0GQ;EACV,SAAS;EACT,sBAAsB;;;;;EAKtB,iBAAiB,OAAO,YAAY"}
package/dist/usage.d.ts CHANGED
@@ -1,17 +1,17 @@
1
1
  /// <reference types="@assistant-ui/core/react" />
2
2
  //#region src/usage.d.ts
3
- type ThreadTokenUsage = {
3
+ export type ThreadTokenUsage = {
4
4
  totalTokens?: number;
5
5
  inputTokens?: number;
6
6
  outputTokens?: number;
7
7
  reasoningTokens?: number;
8
8
  cachedInputTokens?: number;
9
9
  };
10
- interface TokenUsageExtractableMessage {
10
+ export interface TokenUsageExtractableMessage {
11
11
  role?: string;
12
12
  metadata?: unknown;
13
13
  }
14
- declare function getThreadMessageTokenUsage(message: TokenUsageExtractableMessage | undefined): ThreadTokenUsage | undefined;
14
+ export declare function getThreadMessageTokenUsage(message: TokenUsageExtractableMessage | undefined): ThreadTokenUsage | undefined;
15
15
  /**
16
16
  * Reads token usage from the newest assistant message that reports any.
17
17
  *
@@ -20,7 +20,6 @@ declare function getThreadMessageTokenUsage(message: TokenUsageExtractableMessag
20
20
  * other key the route returns into `metadata.custom`, which is where this hook
21
21
  * looks.
22
22
  */
23
- declare function useThreadTokenUsage(): ThreadTokenUsage | undefined;
23
+ export declare function useThreadTokenUsage(): ThreadTokenUsage | undefined;
24
24
  //#endregion
25
- export { ThreadTokenUsage, TokenUsageExtractableMessage, getThreadMessageTokenUsage, useThreadTokenUsage };
26
25
  //# sourceMappingURL=usage.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"usage.d.ts","names":[],"sources":["../src/usage.ts"],"mappings":";KAIY;EACV;EACA;EACA;EACA;EACA;;UAGe;EACf;EACA;;iBAuHc,2BACd,SAAS,2CACR;;;;;;;;;iBAsCa,uBAAuB"}
1
+ {"version":3,"file":"usage.d.ts","names":[],"sources":["../src/usage.ts"],"mappings":";YAIY;EACV;EACA;EACA;EACA;EACA;;iBAGe;EACf;EACA;;wBAuHc,2BACd,SAAS,2CACR;;;;;;;;;wBAsCa,uBAAuB"}
@@ -1,7 +1,6 @@
1
1
  import { UIMessage } from "ai";
2
2
  import { ThreadMessage } from "@assistant-ui/core";
3
3
  //#region src/utils/getVercelAIMessages.d.ts
4
- declare const getVercelAIMessages: <UI_MESSAGE extends UIMessage = UIMessage>(message: ThreadMessage) => UI_MESSAGE[];
4
+ export declare const getVercelAIMessages: <UI_MESSAGE extends UIMessage = UIMessage>(message: ThreadMessage) => UI_MESSAGE[];
5
5
  //#endregion
6
- export { getVercelAIMessages };
7
6
  //# sourceMappingURL=getVercelAIMessages.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"getVercelAIMessages.d.ts","names":[],"sources":["../../src/utils/getVercelAIMessages.ts"],"mappings":";;;cAMa,sBAAuB,mBAAmB,YAAY,WACjE,SAAS,kBAEmC"}
1
+ {"version":3,"file":"getVercelAIMessages.d.ts","names":[],"sources":["../../src/utils/getVercelAIMessages.ts"],"mappings":";;;qBAMa,sBAAuB,mBAAmB,YAAY,WACjE,SAAS,kBAEmC"}
@@ -1,6 +1,5 @@
1
1
  import { UIMessage } from "ai";
2
2
  //#region src/utils/sliceMessagesUntil.d.ts
3
- declare const sliceMessagesUntil: <UI_MESSAGE extends UIMessage = UIMessage>(messages: UI_MESSAGE[], messageId: string | null) => UI_MESSAGE[];
3
+ export declare const sliceMessagesUntil: <UI_MESSAGE extends UIMessage = UIMessage>(messages: UI_MESSAGE[], messageId: string | null) => UI_MESSAGE[];
4
4
  //#endregion
5
- export { sliceMessagesUntil };
6
5
  //# sourceMappingURL=sliceMessagesUntil.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"sliceMessagesUntil.d.ts","names":[],"sources":["../../src/utils/sliceMessagesUntil.ts"],"mappings":";;cAEa,qBAAsB,mBAAmB,YAAY,WAChE,UAAU,cACV,6BAAwB"}
1
+ {"version":3,"file":"sliceMessagesUntil.d.ts","names":[],"sources":["../../src/utils/sliceMessagesUntil.ts"],"mappings":";;qBAEa,qBAAsB,mBAAmB,YAAY,WAChE,UAAU,cACV,6BAAwB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@assistant-ui/ai-sdk",
3
- "version": "0.0.5",
3
+ "version": "0.0.7",
4
4
  "description": "Vercel AI SDK adapter for assistant-ui",
5
5
  "keywords": [
6
6
  "ai-sdk",
@@ -46,14 +46,14 @@
46
46
  ],
47
47
  "sideEffects": false,
48
48
  "dependencies": {
49
- "@ai-sdk/mcp": "^2.0.45",
50
- "@ai-sdk/react": "^4.0.96",
51
- "@assistant-ui/core": "^0.3.18",
52
- "@assistant-ui/store": "^0.3.13",
53
- "@assistant-ui/tap": "^0.9.17",
54
- "ai": "^7.0.93",
55
- "assistant-cloud": "*",
56
- "assistant-stream": "^0.3.42"
49
+ "@ai-sdk/mcp": "^2.0.49",
50
+ "@ai-sdk/react": "^4.0.104",
51
+ "@assistant-ui/core": "^0.3.20",
52
+ "@assistant-ui/store": "^0.3.14",
53
+ "@assistant-ui/tap": "^0.9.18",
54
+ "ai": "^7.0.101",
55
+ "assistant-cloud": "^0.2.2",
56
+ "assistant-stream": "^0.3.44"
57
57
  },
58
58
  "peerDependencies": {
59
59
  "@types/react": "*",
@@ -68,14 +68,14 @@
68
68
  }
69
69
  },
70
70
  "devDependencies": {
71
- "@assistant-ui/x-buildutils": "0.0.26",
71
+ "@assistant-ui/x-buildutils": "0.0.28",
72
72
  "@testing-library/react": "^16.3.3",
73
73
  "@types/json-schema": "^7.0.15",
74
- "@types/react": "^19.2.18",
75
- "@types/react-dom": "^19.2.7",
74
+ "@types/react": "^19.3.0",
75
+ "@types/react-dom": "^19.3.0",
76
76
  "jsdom": "^30.0.1",
77
- "react": "^19.2.8",
78
- "vitest": "^4.1.11"
77
+ "react": "^19.3.0",
78
+ "vitest": "^5.0.1"
79
79
  },
80
80
  "publishConfig": {
81
81
  "access": "public",
@@ -93,6 +93,7 @@
93
93
  "scripts": {
94
94
  "build": "aui-build",
95
95
  "test": "vitest run",
96
+ "typecheck": "tsc --noEmit && tsc --noEmit -p tsconfig.test.json",
96
97
  "test:react-compiler": "vitest run --config vitest.react-compiler.config.ts",
97
98
  "test:standalone": "vitest run --project standalone",
98
99
  "test:watch": "vitest"
@@ -1,41 +1,4 @@
1
- import type { UIMessage } from "ai";
2
- import type {
3
- MessageFormatAdapter,
4
- MessageFormatItem,
5
- MessageStorageEntry,
6
- } from "@assistant-ui/core";
7
-
8
- // Storage format for AI SDK messages - just the UIMessage
9
- export type AISDKStorageFormat = Omit<UIMessage, "id">;
10
-
11
- export const aiSDKV6FormatAdapter: MessageFormatAdapter<
12
- UIMessage,
13
- AISDKStorageFormat
14
- > = {
15
- format: "ai-sdk/v6",
16
-
17
- encode({
18
- message: { id, parts, ...message },
19
- }: MessageFormatItem<UIMessage>): AISDKStorageFormat {
20
- return {
21
- ...message,
22
- parts,
23
- };
24
- },
25
-
26
- decode(
27
- stored: MessageStorageEntry<AISDKStorageFormat>,
28
- ): MessageFormatItem<UIMessage> {
29
- return {
30
- parentId: stored.parent_id,
31
- message: {
32
- id: stored.id,
33
- ...stored.content,
34
- },
35
- };
36
- },
37
-
38
- getId(message: UIMessage): string {
39
- return message.id;
40
- },
41
- };
1
+ export {
2
+ aiSDKV6FormatAdapter,
3
+ type AISDKStorageFormat,
4
+ } from "assistant-cloud/ai-sdk";