@assistant-ui/core 0.3.18 → 0.3.19

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 (274) hide show
  1. package/dist/adapters/speech.d.ts.map +1 -1
  2. package/dist/adapters/speech.js +13 -3
  3. package/dist/adapters/speech.js.map +1 -1
  4. package/dist/adapters/thread-history.d.ts +4 -0
  5. package/dist/adapters/thread-history.d.ts.map +1 -1
  6. package/dist/index.d.ts +2 -2
  7. package/dist/index.js.map +1 -1
  8. package/dist/internal.d.ts +1 -1
  9. package/dist/model-context/frame/host.d.ts.map +1 -1
  10. package/dist/model-context/frame/host.js +26 -11
  11. package/dist/model-context/frame/host.js.map +1 -1
  12. package/dist/model-context/interactable-composer-metadata.js +11 -9
  13. package/dist/model-context/interactable-composer-metadata.js.map +1 -1
  14. package/dist/react/adapters/LocalStorageThreadListAdapter.d.ts.map +1 -1
  15. package/dist/react/adapters/LocalStorageThreadListAdapter.js +45 -7
  16. package/dist/react/adapters/LocalStorageThreadListAdapter.js.map +1 -1
  17. package/dist/react/client/DataRenderers.d.ts.map +1 -1
  18. package/dist/react/client/DataRenderers.js +20 -15
  19. package/dist/react/client/DataRenderers.js.map +1 -1
  20. package/dist/react/client/Interactables.d.ts.map +1 -1
  21. package/dist/react/client/Interactables.js +11 -5
  22. package/dist/react/client/Interactables.js.map +1 -1
  23. package/dist/react/client/RemoteThreadList.d.ts.map +1 -1
  24. package/dist/react/client/RemoteThreadList.js +3 -2
  25. package/dist/react/client/RemoteThreadList.js.map +1 -1
  26. package/dist/react/client/interactable-model-context.d.ts.map +1 -1
  27. package/dist/react/client/interactable-model-context.js +3 -2
  28. package/dist/react/client/interactable-model-context.js.map +1 -1
  29. package/dist/react/index.d.ts +2 -2
  30. package/dist/react/index.js +2 -2
  31. package/dist/react/interactables-legacy/useAssistantInteractable.d.ts.map +1 -1
  32. package/dist/react/interactables-legacy/useAssistantInteractable.js +3 -0
  33. package/dist/react/interactables-legacy/useAssistantInteractable.js.map +1 -1
  34. package/dist/react/model-context/useInteractable.d.ts.map +1 -1
  35. package/dist/react/model-context/useInteractable.js +4 -1
  36. package/dist/react/model-context/useInteractable.js.map +1 -1
  37. package/dist/react/model-context/useInteractableVersions.js +1 -1
  38. package/dist/react/primitives/message/MessageGroupedParts.d.ts +11 -2
  39. package/dist/react/primitives/message/MessageGroupedParts.d.ts.map +1 -1
  40. package/dist/react/primitives/message/MessageGroupedParts.js +3 -2
  41. package/dist/react/primitives/message/MessageGroupedParts.js.map +1 -1
  42. package/dist/react/primitives/part/PartMessages.d.ts +1 -0
  43. package/dist/react/primitives/part/PartMessages.d.ts.map +1 -1
  44. package/dist/react/primitives/part/PartMessages.js +1 -0
  45. package/dist/react/primitives/part/PartMessages.js.map +1 -1
  46. package/dist/react/primitives/thread/ThreadMessages.d.ts.map +1 -1
  47. package/dist/react/primitives/thread/ThreadMessages.js +6 -5
  48. package/dist/react/primitives/thread/ThreadMessages.js.map +1 -1
  49. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts.map +1 -1
  50. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js +2 -1
  51. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js.map +1 -1
  52. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.d.ts +2 -24
  53. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.d.ts.map +1 -1
  54. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.js +135 -374
  55. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.js.map +1 -1
  56. package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.d.ts +1 -0
  57. package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.d.ts.map +1 -1
  58. package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.js +22 -2
  59. package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.js.map +1 -1
  60. package/dist/react/runtimes/cloud/auiV0.d.ts +40 -15
  61. package/dist/react/runtimes/cloud/auiV0.d.ts.map +1 -1
  62. package/dist/react/runtimes/cloud/auiV0.js +62 -15
  63. package/dist/react/runtimes/cloud/auiV0.js.map +1 -1
  64. package/dist/react/runtimes/cloud/createCloudThreadListAdapter.d.ts +2 -1
  65. package/dist/react/runtimes/cloud/createCloudThreadListAdapter.d.ts.map +1 -1
  66. package/dist/react/runtimes/cloud/createCloudThreadListAdapter.js +4 -0
  67. package/dist/react/runtimes/cloud/createCloudThreadListAdapter.js.map +1 -1
  68. package/dist/react/runtimes/cloud/sdkIdentity.d.ts +6 -0
  69. package/dist/react/runtimes/cloud/sdkIdentity.d.ts.map +1 -0
  70. package/dist/react/runtimes/cloud/sdkIdentity.js +9 -0
  71. package/dist/react/runtimes/cloud/sdkIdentity.js.map +1 -0
  72. package/dist/react/runtimes/external-message-converter.d.ts +12 -2
  73. package/dist/react/runtimes/external-message-converter.d.ts.map +1 -1
  74. package/dist/react/runtimes/external-message-converter.js +26 -61
  75. package/dist/react/runtimes/external-message-converter.js.map +1 -1
  76. package/dist/react/runtimes/useRemoteThreadListRuntime.js +1 -1
  77. package/dist/react/runtimes/useRemoteThreadListRuntime.js.map +1 -1
  78. package/dist/react/utils/groupParts.d.ts +6 -1
  79. package/dist/react/utils/groupParts.d.ts.map +1 -1
  80. package/dist/react/utils/groupParts.js +6 -0
  81. package/dist/react/utils/groupParts.js.map +1 -1
  82. package/dist/react/utils/useJSONEqual.d.ts +3 -1
  83. package/dist/react/utils/useJSONEqual.d.ts.map +1 -1
  84. package/dist/react/utils/useJSONEqual.js +6 -1
  85. package/dist/react/utils/useJSONEqual.js.map +1 -1
  86. package/dist/react/utils/useJSONSchemaDependency.d.ts +7 -0
  87. package/dist/react/utils/useJSONSchemaDependency.d.ts.map +1 -0
  88. package/dist/react/utils/useJSONSchemaDependency.js +20 -0
  89. package/dist/react/utils/useJSONSchemaDependency.js.map +1 -0
  90. package/dist/runtime/api/thread-runtime.d.ts.map +1 -1
  91. package/dist/runtime/api/thread-runtime.js +2 -5
  92. package/dist/runtime/api/thread-runtime.js.map +1 -1
  93. package/dist/runtime/base/base-composer-runtime-core.d.ts +1 -0
  94. package/dist/runtime/base/base-composer-runtime-core.d.ts.map +1 -1
  95. package/dist/runtime/base/base-composer-runtime-core.js +46 -10
  96. package/dist/runtime/base/base-composer-runtime-core.js.map +1 -1
  97. package/dist/runtime/base/base-thread-runtime-core.d.ts +2 -0
  98. package/dist/runtime/base/base-thread-runtime-core.d.ts.map +1 -1
  99. package/dist/runtime/base/base-thread-runtime-core.js +155 -64
  100. package/dist/runtime/base/base-thread-runtime-core.js.map +1 -1
  101. package/dist/runtime/interfaces/thread-runtime-core.d.ts +6 -0
  102. package/dist/runtime/interfaces/thread-runtime-core.d.ts.map +1 -1
  103. package/dist/runtime/queue/message-queue.d.ts +5 -0
  104. package/dist/runtime/queue/message-queue.d.ts.map +1 -1
  105. package/dist/runtime/queue/message-queue.js +61 -6
  106. package/dist/runtime/queue/message-queue.js.map +1 -1
  107. package/dist/runtime/utils/auto-status.d.ts +6 -2
  108. package/dist/runtime/utils/auto-status.d.ts.map +1 -1
  109. package/dist/runtime/utils/auto-status.js +12 -4
  110. package/dist/runtime/utils/auto-status.js.map +1 -1
  111. package/dist/runtime/utils/external-message-conversion.d.ts +16 -4
  112. package/dist/runtime/utils/external-message-conversion.d.ts.map +1 -1
  113. package/dist/runtime/utils/external-message-conversion.js +48 -12
  114. package/dist/runtime/utils/external-message-conversion.js.map +1 -1
  115. package/dist/runtime/utils/message-repository.js +3 -3
  116. package/dist/runtime/utils/message-repository.js.map +1 -1
  117. package/dist/runtime/utils/thread-message-like.d.ts +2 -1
  118. package/dist/runtime/utils/thread-message-like.d.ts.map +1 -1
  119. package/dist/runtime/utils/thread-message-like.js +4 -2
  120. package/dist/runtime/utils/thread-message-like.js.map +1 -1
  121. package/dist/runtimes/external-store/external-store-thread-runtime-core.d.ts.map +1 -1
  122. package/dist/runtimes/external-store/external-store-thread-runtime-core.js +8 -1
  123. package/dist/runtimes/external-store/external-store-thread-runtime-core.js.map +1 -1
  124. package/dist/runtimes/internal.d.ts +1 -1
  125. package/dist/runtimes/local/local-thread-runtime-core.d.ts +1 -1
  126. package/dist/runtimes/local/local-thread-runtime-core.d.ts.map +1 -1
  127. package/dist/runtimes/local/local-thread-runtime-core.js +4 -1
  128. package/dist/runtimes/local/local-thread-runtime-core.js.map +1 -1
  129. package/dist/runtimes/tool-invocations/ToolInvocationTracker.d.ts.map +1 -1
  130. package/dist/runtimes/tool-invocations/ToolInvocationTracker.js +2 -1
  131. package/dist/runtimes/tool-invocations/ToolInvocationTracker.js.map +1 -1
  132. package/dist/store/clients/external-thread.d.ts.map +1 -1
  133. package/dist/store/clients/external-thread.js +241 -200
  134. package/dist/store/clients/external-thread.js.map +1 -1
  135. package/dist/store/clients/thread-tasks.d.ts +13 -0
  136. package/dist/store/clients/thread-tasks.d.ts.map +1 -0
  137. package/dist/store/clients/thread-tasks.js +69 -0
  138. package/dist/store/clients/thread-tasks.js.map +1 -0
  139. package/dist/store/index.d.ts +3 -2
  140. package/dist/store/index.js +3 -3
  141. package/dist/store/primitive-predicates.d.ts.map +1 -1
  142. package/dist/store/primitive-predicates.js +4 -4
  143. package/dist/store/primitive-predicates.js.map +1 -1
  144. package/dist/store/runtime-clients/thread-runtime-client.d.ts.map +1 -1
  145. package/dist/store/runtime-clients/thread-runtime-client.js +176 -128
  146. package/dist/store/runtime-clients/thread-runtime-client.js.map +1 -1
  147. package/dist/store/scope-registration.d.ts +2 -0
  148. package/dist/store/scope-registration.d.ts.map +1 -1
  149. package/dist/store/scopes/task.d.ts +36 -0
  150. package/dist/store/scopes/task.d.ts.map +1 -0
  151. package/dist/store/scopes/task.js +0 -0
  152. package/dist/store/scopes/thread.d.ts +20 -0
  153. package/dist/store/scopes/thread.d.ts.map +1 -1
  154. package/dist/subscribable/subscribable.d.ts +2 -1
  155. package/dist/subscribable/subscribable.d.ts.map +1 -1
  156. package/dist/subscribable/subscribable.js +23 -15
  157. package/dist/subscribable/subscribable.js.map +1 -1
  158. package/dist/types/index.d.ts +2 -2
  159. package/dist/types/message.d.ts +8 -1
  160. package/dist/types/message.d.ts.map +1 -1
  161. package/dist/types/message.js.map +1 -1
  162. package/dist/utils/abortable-iterable.d.ts.map +1 -1
  163. package/dist/utils/abortable-iterable.js +30 -14
  164. package/dist/utils/abortable-iterable.js.map +1 -1
  165. package/dist/utils/getGroupStatus.d.ts +18 -2
  166. package/dist/utils/getGroupStatus.d.ts.map +1 -1
  167. package/dist/utils/getGroupStatus.js +32 -7
  168. package/dist/utils/getGroupStatus.js.map +1 -1
  169. package/dist/utils/wire-media.d.ts.map +1 -1
  170. package/dist/utils/wire-media.js +2 -2
  171. package/dist/utils/wire-media.js.map +1 -1
  172. package/package.json +6 -6
  173. package/src/adapters/speech.test.ts +236 -0
  174. package/src/adapters/speech.ts +17 -10
  175. package/src/adapters/thread-history.ts +3 -0
  176. package/src/index.ts +1 -0
  177. package/src/model-context/frame/host.test.ts +113 -1
  178. package/src/model-context/frame/host.ts +39 -12
  179. package/src/model-context/interactable-composer-metadata.test.ts +30 -0
  180. package/src/model-context/interactable-composer-metadata.ts +10 -10
  181. package/src/react/adapters/LocalStorageThreadListAdapter.test.ts +244 -0
  182. package/src/react/adapters/LocalStorageThreadListAdapter.tsx +104 -7
  183. package/src/react/client/DataRenderers.test.tsx +45 -0
  184. package/src/react/client/DataRenderers.ts +13 -9
  185. package/src/react/client/Interactables.test.ts +44 -1
  186. package/src/react/client/Interactables.ts +7 -1
  187. package/src/react/client/RemoteThreadList.test.ts +41 -1
  188. package/src/react/client/RemoteThreadList.ts +15 -2
  189. package/src/react/client/interactable-model-context.test.ts +44 -0
  190. package/src/react/client/interactable-model-context.ts +3 -2
  191. package/src/react/index.ts +5 -1
  192. package/src/react/interactables-legacy/useAssistantInteractable.test.tsx +132 -0
  193. package/src/react/interactables-legacy/useAssistantInteractable.ts +10 -1
  194. package/src/react/model-context/useInteractable.test.tsx +177 -0
  195. package/src/react/model-context/useInteractable.ts +3 -0
  196. package/src/react/primitive-hooks/useActionBarCopy.test.ts +0 -1
  197. package/src/react/primitive-hooks/useSuggestionTrigger.test.ts +0 -1
  198. package/src/react/primitives/message/MessageGroupedParts.test.tsx +96 -0
  199. package/src/react/primitives/message/MessageGroupedParts.tsx +15 -4
  200. package/src/react/primitives/part/PartMessages.test.tsx +104 -1
  201. package/src/react/primitives/part/PartMessages.tsx +1 -0
  202. package/src/react/primitives/thread/ThreadMessages.test.tsx +142 -0
  203. package/src/react/primitives/thread/ThreadMessages.tsx +8 -5
  204. package/src/react/providers/ReadonlyThreadProvider.test.tsx +56 -0
  205. package/src/react/runtimes/RemoteThreadListThreadListRuntimeCore.tsx +7 -1
  206. package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.test.ts +20 -14
  207. package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.test.tsx +221 -1
  208. package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.ts +166 -512
  209. package/src/react/runtimes/cloud/CloudFileAttachmentAdapter.test.ts +77 -0
  210. package/src/react/runtimes/cloud/CloudFileAttachmentAdapter.ts +27 -1
  211. package/src/react/runtimes/cloud/auiV0.ts +160 -25
  212. package/src/react/runtimes/cloud/createCloudThreadListAdapter.test.ts +21 -0
  213. package/src/react/runtimes/cloud/createCloudThreadListAdapter.ts +7 -1
  214. package/src/react/runtimes/cloud/sdkIdentity.ts +9 -0
  215. package/src/react/runtimes/cloud/useCloudThreadListAdapter.test.tsx +18 -4
  216. package/src/react/runtimes/external-message-converter.test.ts +136 -1
  217. package/src/react/runtimes/external-message-converter.ts +39 -93
  218. package/src/react/runtimes/useRemoteThreadListRuntime.ts +1 -1
  219. package/src/react/utils/groupParts.ts +12 -1
  220. package/src/react/utils/useJSONEqual.ts +9 -0
  221. package/src/react/utils/useJSONSchemaDependency.ts +22 -0
  222. package/src/runtime/api/thread-runtime.test.ts +58 -0
  223. package/src/runtime/api/thread-runtime.ts +2 -4
  224. package/src/runtime/base/base-composer-runtime-core.ts +69 -16
  225. package/src/runtime/base/base-thread-runtime-core.test.ts +1008 -1
  226. package/src/runtime/base/base-thread-runtime-core.ts +222 -83
  227. package/src/runtime/interfaces/thread-runtime-core.ts +6 -0
  228. package/src/runtime/queue/message-queue.ts +68 -6
  229. package/src/runtime/utils/auto-status.test.ts +112 -1
  230. package/src/runtime/utils/auto-status.ts +31 -5
  231. package/src/runtime/utils/external-message-conversion.test.ts +134 -0
  232. package/src/runtime/utils/external-message-conversion.ts +122 -31
  233. package/src/runtime/utils/message-repository.test.ts +49 -0
  234. package/src/runtime/utils/message-repository.ts +3 -3
  235. package/src/runtime/utils/thread-message-like.test.ts +52 -0
  236. package/src/runtime/utils/thread-message-like.ts +4 -0
  237. package/src/runtimes/external-store/external-store-thread-runtime-core.ts +31 -1
  238. package/src/runtimes/local/local-thread-runtime-core.test.ts +21 -0
  239. package/src/runtimes/local/local-thread-runtime-core.ts +11 -1
  240. package/src/runtimes/tool-invocations/EDGE_CASES.md +2 -6
  241. package/src/runtimes/tool-invocations/ToolInvocationTracker.test.ts +133 -0
  242. package/src/runtimes/tool-invocations/ToolInvocationTracker.ts +10 -6
  243. package/src/store/clients/external-thread.ts +19 -1
  244. package/src/store/clients/thread-tasks.test.ts +274 -0
  245. package/src/store/clients/thread-tasks.ts +138 -0
  246. package/src/store/index.ts +8 -0
  247. package/src/store/primitive-predicates.test.ts +48 -5
  248. package/src/store/primitive-predicates.ts +7 -2
  249. package/src/store/runtime-clients/thread-runtime-client.ts +31 -1
  250. package/src/store/scope-registration.ts +2 -0
  251. package/src/store/scopes/task.ts +34 -0
  252. package/src/store/scopes/thread.ts +16 -0
  253. package/src/store/thread-tasks.test.tsx +209 -0
  254. package/src/subscribable/subscribable.test.ts +156 -1
  255. package/src/subscribable/subscribable.ts +25 -15
  256. package/src/tests/MessageRepository.test.ts +1 -5
  257. package/src/tests/auiV0Encode.test.ts +300 -0
  258. package/src/tests/base-composer-runtime-core-send.test.ts +51 -0
  259. package/src/tests/base-composer-runtime-core.test.ts +314 -2
  260. package/src/tests/external-store-thread-runtime-core-adapter.test.ts +151 -0
  261. package/src/tests/external-thread-attachments.test.tsx +69 -0
  262. package/src/tests/external-thread-parity.test.tsx +34 -0
  263. package/src/tests/groupParts.test.ts +71 -0
  264. package/src/tests/message-queue.test.ts +253 -0
  265. package/src/tests/remote-thread-list-reactive-threadId.test.ts +51 -0
  266. package/src/tests/useRemoteThreadListRuntime-controlled.test.tsx +43 -0
  267. package/src/types/index.ts +1 -0
  268. package/src/types/message.ts +8 -0
  269. package/src/utils/abortable-iterable.test.ts +115 -0
  270. package/src/utils/abortable-iterable.ts +34 -23
  271. package/src/utils/getGroupStatus.test.ts +70 -4
  272. package/src/utils/getGroupStatus.ts +35 -12
  273. package/src/utils/wire-media.test.ts +10 -0
  274. package/src/utils/wire-media.ts +6 -2
@@ -178,6 +178,20 @@ describe("useAssistantCloudThreadHistoryAdapter", () => {
178
178
  threadId: "thread-1",
179
179
  messageId: "local-message-1",
180
180
  });
181
+ listeners.get("thread.toolApprovalAnswered")!({
182
+ threadId: "thread-1",
183
+ messageId: "local-message-1",
184
+ toolCallId: "tool-approved",
185
+ toolName: "send_email",
186
+ approved: true,
187
+ });
188
+ listeners.get("thread.toolApprovalAnswered")!({
189
+ threadId: "thread-1",
190
+ messageId: "local-message-1",
191
+ toolCallId: "tool-rejected",
192
+ toolName: "delete_account",
193
+ approved: false,
194
+ });
181
195
  listeners.get("composer.attachmentAdd")!({
182
196
  threadId: "thread-1",
183
197
  contentType: "image/png",
@@ -202,6 +216,11 @@ describe("useAssistantCloudThreadHistoryAdapter", () => {
202
216
  messageId: "local-message-1",
203
217
  reason: "error",
204
218
  });
219
+ listeners.get("message.error")!({
220
+ threadId: "thread-1",
221
+ messageId: "local-message-2",
222
+ reason: "error",
223
+ });
205
224
  threadState.isEmpty = true;
206
225
  threadState.suggestions = [{ prompt: "one" }, { prompt: "two" }];
207
226
  notify!();
@@ -232,6 +251,16 @@ describe("useAssistantCloudThreadHistoryAdapter", () => {
232
251
  expect.objectContaining({ kind: "message_regenerated" }),
233
252
  expect.objectContaining({ kind: "branch_switched" }),
234
253
  expect.objectContaining({ kind: "message_copied" }),
254
+ expect.objectContaining({
255
+ kind: "tool_approved",
256
+ message_id: "remote-message-1",
257
+ props: { toolCallId: "tool-approved", toolName: "send_email" },
258
+ }),
259
+ expect.objectContaining({
260
+ kind: "tool_rejected",
261
+ message_id: "remote-message-1",
262
+ props: { toolCallId: "tool-rejected", toolName: "delete_account" },
263
+ }),
235
264
  expect.objectContaining({
236
265
  kind: "attachment_added",
237
266
  props: { type: "image/png" },
@@ -250,6 +279,12 @@ describe("useAssistantCloudThreadHistoryAdapter", () => {
250
279
  expect.objectContaining({ kind: "suggestions_shown", value: 2 }),
251
280
  ]),
252
281
  );
282
+ expect(
283
+ vi
284
+ .mocked(cloud.events.track)
285
+ .mock.calls.map(([event]) => event)
286
+ .filter((event) => event.kind === "error_shown"),
287
+ ).toHaveLength(1);
253
288
  });
254
289
 
255
290
  it("refreshes formatted persistence when the Cloud client changes", async () => {
@@ -501,7 +536,7 @@ describe("useAssistantCloudThreadHistoryAdapter", () => {
501
536
  },
502
537
  timing: {
503
538
  streamStartTime: 100,
504
- firstTokenTime: 155.6,
539
+ firstTokenTime: 55.6,
505
540
  totalChunks: 1,
506
541
  toolCallCount: 0,
507
542
  },
@@ -688,6 +723,7 @@ describe("useAssistantCloudThreadHistoryAdapter", () => {
688
723
  tool_source: "mcp",
689
724
  }),
690
725
  ],
726
+ finish_reason: "tool-calls",
691
727
  },
692
728
  {
693
729
  tool_calls: [
@@ -696,6 +732,7 @@ describe("useAssistantCloudThreadHistoryAdapter", () => {
696
732
  tool_source: "frontend",
697
733
  }),
698
734
  ],
735
+ finish_reason: "tool-calls",
699
736
  },
700
737
  ],
701
738
  trace_id: "00112233445566778899aabbccddeeff",
@@ -705,6 +742,189 @@ describe("useAssistantCloudThreadHistoryAdapter", () => {
705
742
  );
706
743
  });
707
744
 
745
+ it("reports a single ai-sdk/v6 step with its tool calls", () => {
746
+ mocks.aui = mocks.makeClient("thread-1");
747
+ const cloud = makeCloud();
748
+ const { result } = renderHook(() =>
749
+ useAssistantCloudThreadHistoryAdapter({ current: cloud }),
750
+ );
751
+ const formatted = result.current.withFormat({
752
+ format: "ai-sdk/v6",
753
+ encode: ({ message }) => message,
754
+ decode: ({ parent_id, content }) => ({
755
+ parentId: parent_id,
756
+ message: content as { id: string },
757
+ }),
758
+ getId: (message: { id: string }) => message.id,
759
+ });
760
+
761
+ formatted.reportTelemetry([
762
+ {
763
+ parentId: null,
764
+ message: {
765
+ id: "message-1",
766
+ role: "assistant",
767
+ parts: [
768
+ { type: "step-start" },
769
+ {
770
+ type: "tool-search",
771
+ toolCallId: "search-1",
772
+ input: { query: "test" },
773
+ output: { result: "ok" },
774
+ },
775
+ ],
776
+ },
777
+ },
778
+ ]);
779
+
780
+ expect(cloud.runs.report).toHaveBeenCalledWith(
781
+ expect.objectContaining({
782
+ total_steps: 1,
783
+ steps: [
784
+ {
785
+ tool_calls: [
786
+ expect.objectContaining({
787
+ tool_call_id: "search-1",
788
+ tool_source: "frontend",
789
+ }),
790
+ ],
791
+ finish_reason: "tool-calls",
792
+ },
793
+ ],
794
+ }),
795
+ );
796
+ });
797
+
798
+ it("reads the status of an ai-sdk/v6 run from its finish reason", () => {
799
+ mocks.aui = mocks.makeClient("thread-1");
800
+ const cloud = makeCloud();
801
+ const { result } = renderHook(() =>
802
+ useAssistantCloudThreadHistoryAdapter({ current: cloud }),
803
+ );
804
+ const formatted = result.current.withFormat({
805
+ format: "ai-sdk/v6",
806
+ encode: ({ message }) => message,
807
+ decode: ({ parent_id, content }) => ({
808
+ parentId: parent_id,
809
+ message: content as { id: string },
810
+ }),
811
+ getId: (message: { id: string }) => message.id,
812
+ });
813
+
814
+ formatted.reportTelemetry([
815
+ {
816
+ parentId: null,
817
+ message: {
818
+ id: "message-1",
819
+ role: "assistant",
820
+ parts: [{ type: "text", text: "cut" }],
821
+ metadata: { finishReason: "length" },
822
+ },
823
+ },
824
+ ]);
825
+
826
+ expect(cloud.runs.report).toHaveBeenCalledWith(
827
+ expect.objectContaining({ status: "incomplete", outcome_type: "length" }),
828
+ );
829
+ });
830
+
831
+ it("reads the error and timing of an ai-sdk/v6 run from the thread message", () => {
832
+ mocks.aui = mocks.makeClient("thread-1");
833
+ const cloud = makeCloud();
834
+ const { result } = renderHook(() =>
835
+ useAssistantCloudThreadHistoryAdapter({ current: cloud }),
836
+ );
837
+ const formatted = result.current.withFormat({
838
+ format: "ai-sdk/v6",
839
+ encode: ({ message }) => message,
840
+ decode: ({ parent_id, content }) => ({
841
+ parentId: parent_id,
842
+ message: content as { id: string },
843
+ }),
844
+ getId: (message: { id: string }) => message.id,
845
+ });
846
+ const base = makeAssistantMessage("assistant-1");
847
+ const message: ThreadAssistantMessage = {
848
+ ...base,
849
+ status: {
850
+ type: "incomplete",
851
+ reason: "error",
852
+ error: Object.assign(new Error("model unavailable"), {
853
+ code: "model_unavailable",
854
+ }),
855
+ },
856
+ metadata: {
857
+ ...base.metadata,
858
+ timing: {
859
+ streamStartTime: 100,
860
+ firstTokenTime: 240,
861
+ totalChunks: 3,
862
+ toolCallCount: 0,
863
+ },
864
+ },
865
+ };
866
+
867
+ formatted.reportTelemetry(
868
+ [
869
+ {
870
+ parentId: null,
871
+ message: {
872
+ id: "message-1",
873
+ role: "assistant",
874
+ parts: [{ type: "text", text: "partial" }],
875
+ },
876
+ },
877
+ ],
878
+ { message },
879
+ );
880
+
881
+ expect(cloud.runs.report).toHaveBeenCalledWith(
882
+ expect.objectContaining({
883
+ status: "error",
884
+ error: "model unavailable",
885
+ error_code: "model_unavailable",
886
+ first_token_ms: 240,
887
+ }),
888
+ );
889
+ });
890
+
891
+ it("reports a run that failed before any assistant message was stored", () => {
892
+ mocks.aui = mocks.makeClient("thread-1");
893
+ const cloud = makeCloud();
894
+ const { result } = renderHook(() =>
895
+ useAssistantCloudThreadHistoryAdapter({ current: cloud }),
896
+ );
897
+ const formatted = result.current.withFormat({
898
+ format: "ai-sdk/v6",
899
+ encode: ({ message }) => message,
900
+ decode: ({ parent_id, content }) => ({
901
+ parentId: parent_id,
902
+ message: content as { id: string },
903
+ }),
904
+ getId: (message: { id: string }) => message.id,
905
+ });
906
+ const message: ThreadAssistantMessage = {
907
+ ...makeAssistantMessage("assistant-1"),
908
+ content: [],
909
+ status: {
910
+ type: "incomplete",
911
+ reason: "error",
912
+ error: { code: "AI_APICallError", message: "upstream failed" },
913
+ },
914
+ };
915
+
916
+ formatted.reportTelemetry([], { message, durationMs: 120 });
917
+
918
+ expect(cloud.runs.report).toHaveBeenCalledWith(
919
+ expect.objectContaining({
920
+ status: "error",
921
+ error: "upstream failed",
922
+ error_code: "AI_APICallError",
923
+ duration_ms: 120,
924
+ }),
925
+ );
926
+ });
927
+
708
928
  it("reports the model ID carried by aui/v0 step metadata", () => {
709
929
  mocks.aui = mocks.makeClient("thread-1");
710
930
  const cloud = makeCloud();