@assistant-ui/core 0.3.17 → 0.3.18

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 (284) hide show
  1. package/dist/adapters/attachment.d.ts.map +1 -1
  2. package/dist/adapters/attachment.js +5 -4
  3. package/dist/adapters/attachment.js.map +1 -1
  4. package/dist/index.d.ts +2 -2
  5. package/dist/index.js.map +1 -1
  6. package/dist/internal.d.ts +3 -2
  7. package/dist/internal.js +3 -2
  8. package/dist/model-context/frame/host.d.ts.map +1 -1
  9. package/dist/model-context/frame/host.js +10 -4
  10. package/dist/model-context/frame/host.js.map +1 -1
  11. package/dist/model-context/frame/provider.d.ts +2 -0
  12. package/dist/model-context/frame/provider.d.ts.map +1 -1
  13. package/dist/model-context/frame/provider.js +30 -7
  14. package/dist/model-context/frame/provider.js.map +1 -1
  15. package/dist/model-context/interactable-composer-metadata.d.ts.map +1 -1
  16. package/dist/model-context/interactable-composer-metadata.js +16 -9
  17. package/dist/model-context/interactable-composer-metadata.js.map +1 -1
  18. package/dist/model-context/registry.d.ts.map +1 -1
  19. package/dist/model-context/registry.js +3 -5
  20. package/dist/model-context/registry.js.map +1 -1
  21. package/dist/model-context/types.d.ts.map +1 -1
  22. package/dist/model-context/types.js +5 -4
  23. package/dist/model-context/types.js.map +1 -1
  24. package/dist/react/client/InMemoryThreadList.d.ts.map +1 -1
  25. package/dist/react/client/InMemoryThreadList.js +62 -56
  26. package/dist/react/client/InMemoryThreadList.js.map +1 -1
  27. package/dist/react/client/Interactables.d.ts.map +1 -1
  28. package/dist/react/client/Interactables.js +24 -27
  29. package/dist/react/client/Interactables.js.map +1 -1
  30. package/dist/react/client/RemoteThreadList.d.ts +1 -0
  31. package/dist/react/client/RemoteThreadList.d.ts.map +1 -1
  32. package/dist/react/client/RemoteThreadList.js +151 -141
  33. package/dist/react/client/RemoteThreadList.js.map +1 -1
  34. package/dist/react/client/Tools.d.ts.map +1 -1
  35. package/dist/react/client/Tools.js +18 -16
  36. package/dist/react/client/Tools.js.map +1 -1
  37. package/dist/react/interactables-legacy/Interactables.js +242 -121
  38. package/dist/react/interactables-legacy/Interactables.js.map +1 -1
  39. package/dist/react/interactables-shared/useInteractablePersistenceQueue.d.ts.map +1 -1
  40. package/dist/react/interactables-shared/useInteractablePersistenceQueue.js +11 -9
  41. package/dist/react/interactables-shared/useInteractablePersistenceQueue.js.map +1 -1
  42. package/dist/react/model-context/makeAssistantTool.d.ts +2 -2
  43. package/dist/react/model-context/makeAssistantTool.js +1 -1
  44. package/dist/react/model-context/makeAssistantTool.js.map +1 -1
  45. package/dist/react/model-context/useAssistantTool.d.ts +2 -2
  46. package/dist/react/model-context/useAssistantTool.js +1 -1
  47. package/dist/react/model-context/useAssistantTool.js.map +1 -1
  48. package/dist/react/model-context/useToolArgsStatus.d.ts.map +1 -1
  49. package/dist/react/model-context/useToolArgsStatus.js +2 -1
  50. package/dist/react/model-context/useToolArgsStatus.js.map +1 -1
  51. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.d.ts.map +1 -1
  52. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js +16 -8
  53. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js.map +1 -1
  54. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts +5 -1
  55. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts.map +1 -1
  56. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js +103 -103
  57. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js.map +1 -1
  58. package/dist/react/runtimes/RemoteThreadResource.d.ts +1 -0
  59. package/dist/react/runtimes/RemoteThreadResource.d.ts.map +1 -1
  60. package/dist/react/runtimes/RemoteThreadResource.js +13 -11
  61. package/dist/react/runtimes/RemoteThreadResource.js.map +1 -1
  62. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.d.ts +4 -1
  63. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.d.ts.map +1 -1
  64. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.js +401 -34
  65. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.js.map +1 -1
  66. package/dist/react/runtimes/cloud/createCloudThreadListAdapter.d.ts.map +1 -1
  67. package/dist/react/runtimes/cloud/createCloudThreadListAdapter.js +2 -1
  68. package/dist/react/runtimes/cloud/createCloudThreadListAdapter.js.map +1 -1
  69. package/dist/react/runtimes/useExternalStoreRuntime.js +75 -46
  70. package/dist/react/runtimes/useExternalStoreRuntime.js.map +1 -1
  71. package/dist/react/runtimes/useRemoteThreadListRuntime.d.ts.map +1 -1
  72. package/dist/react/runtimes/useRemoteThreadListRuntime.js +63 -23
  73. package/dist/react/runtimes/useRemoteThreadListRuntime.js.map +1 -1
  74. package/dist/runtime/api/thread-list-item-runtime.d.ts +7 -3
  75. package/dist/runtime/api/thread-list-item-runtime.d.ts.map +1 -1
  76. package/dist/runtime/api/thread-list-item-runtime.js +2 -2
  77. package/dist/runtime/api/thread-list-item-runtime.js.map +1 -1
  78. package/dist/runtime/api/thread-list-runtime.d.ts +3 -0
  79. package/dist/runtime/api/thread-list-runtime.d.ts.map +1 -1
  80. package/dist/runtime/api/thread-list-runtime.js +18 -14
  81. package/dist/runtime/api/thread-list-runtime.js.map +1 -1
  82. package/dist/runtime/api/thread-runtime.d.ts +4 -0
  83. package/dist/runtime/api/thread-runtime.d.ts.map +1 -1
  84. package/dist/runtime/api/thread-runtime.js +1 -1
  85. package/dist/runtime/api/thread-runtime.js.map +1 -1
  86. package/dist/runtime/base/base-composer-runtime-core.d.ts.map +1 -1
  87. package/dist/runtime/base/base-composer-runtime-core.js +16 -12
  88. package/dist/runtime/base/base-composer-runtime-core.js.map +1 -1
  89. package/dist/runtime/base/base-thread-runtime-core.d.ts.map +1 -1
  90. package/dist/runtime/base/base-thread-runtime-core.js +6 -5
  91. package/dist/runtime/base/base-thread-runtime-core.js.map +1 -1
  92. package/dist/runtime/interfaces/composer-runtime-core.d.ts +12 -5
  93. package/dist/runtime/interfaces/composer-runtime-core.d.ts.map +1 -1
  94. package/dist/runtime/interfaces/thread-list-runtime-core.d.ts +4 -1
  95. package/dist/runtime/interfaces/thread-list-runtime-core.d.ts.map +1 -1
  96. package/dist/runtime/utils/external-message-conversion.js +1 -1
  97. package/dist/runtime/utils/external-message-conversion.js.map +1 -1
  98. package/dist/runtime/utils/message-repository.d.ts +1 -0
  99. package/dist/runtime/utils/message-repository.d.ts.map +1 -1
  100. package/dist/runtime/utils/message-repository.js +15 -6
  101. package/dist/runtime/utils/message-repository.js.map +1 -1
  102. package/dist/runtime/utils/thread-message-like.js +1 -1
  103. package/dist/runtime/utils/thread-message-like.js.map +1 -1
  104. package/dist/runtimes/external-store/external-store-thread-list-runtime-core.d.ts.map +1 -1
  105. package/dist/runtimes/external-store/external-store-thread-list-runtime-core.js +21 -27
  106. package/dist/runtimes/external-store/external-store-thread-list-runtime-core.js.map +1 -1
  107. package/dist/runtimes/internal.d.ts +2 -2
  108. package/dist/runtimes/internal.js +2 -2
  109. package/dist/runtimes/remote-thread-list/remote-thread-state.d.ts +18 -1
  110. package/dist/runtimes/remote-thread-list/remote-thread-state.d.ts.map +1 -1
  111. package/dist/runtimes/remote-thread-list/remote-thread-state.js +130 -42
  112. package/dist/runtimes/remote-thread-list/remote-thread-state.js.map +1 -1
  113. package/dist/runtimes/remote-thread-list/title-generation.d.ts +49 -0
  114. package/dist/runtimes/remote-thread-list/title-generation.d.ts.map +1 -0
  115. package/dist/runtimes/remote-thread-list/title-generation.js +197 -0
  116. package/dist/runtimes/remote-thread-list/title-generation.js.map +1 -0
  117. package/dist/runtimes/remote-thread-list/title.d.ts +3 -1
  118. package/dist/runtimes/remote-thread-list/title.d.ts.map +1 -1
  119. package/dist/runtimes/remote-thread-list/title.js +9 -1
  120. package/dist/runtimes/remote-thread-list/title.js.map +1 -1
  121. package/dist/runtimes/remote-thread-list/types.d.ts +10 -0
  122. package/dist/runtimes/remote-thread-list/types.d.ts.map +1 -1
  123. package/dist/store/clients/external-thread.d.ts.map +1 -1
  124. package/dist/store/clients/external-thread.js +19 -3
  125. package/dist/store/clients/external-thread.js.map +1 -1
  126. package/dist/store/clients/model-context-client.d.ts.map +1 -1
  127. package/dist/store/clients/model-context-client.js +2 -1
  128. package/dist/store/clients/model-context-client.js.map +1 -1
  129. package/dist/store/clients/single-thread-list.d.ts.map +1 -1
  130. package/dist/store/clients/single-thread-list.js +1 -0
  131. package/dist/store/clients/single-thread-list.js.map +1 -1
  132. package/dist/store/clients/suggestions.d.ts.map +1 -1
  133. package/dist/store/clients/suggestions.js +5 -4
  134. package/dist/store/clients/suggestions.js.map +1 -1
  135. package/dist/store/runtime-clients/composer-runtime-client.d.ts +1 -0
  136. package/dist/store/runtime-clients/composer-runtime-client.d.ts.map +1 -1
  137. package/dist/store/runtime-clients/composer-runtime-client.js +97 -61
  138. package/dist/store/runtime-clients/composer-runtime-client.js.map +1 -1
  139. package/dist/store/runtime-clients/message-runtime-client.d.ts +1 -0
  140. package/dist/store/runtime-clients/message-runtime-client.d.ts.map +1 -1
  141. package/dist/store/runtime-clients/message-runtime-client.js +221 -144
  142. package/dist/store/runtime-clients/message-runtime-client.js.map +1 -1
  143. package/dist/store/runtime-clients/thread-list-item-runtime-client.d.ts.map +1 -1
  144. package/dist/store/runtime-clients/thread-list-item-runtime-client.js +1 -1
  145. package/dist/store/runtime-clients/thread-list-item-runtime-client.js.map +1 -1
  146. package/dist/store/runtime-clients/thread-list-runtime-client.d.ts.map +1 -1
  147. package/dist/store/runtime-clients/thread-list-runtime-client.js +54 -52
  148. package/dist/store/runtime-clients/thread-list-runtime-client.js.map +1 -1
  149. package/dist/store/runtime-clients/thread-runtime-client.d.ts.map +1 -1
  150. package/dist/store/runtime-clients/thread-runtime-client.js +193 -121
  151. package/dist/store/runtime-clients/thread-runtime-client.js.map +1 -1
  152. package/dist/store/scopes/composer.d.ts +10 -2
  153. package/dist/store/scopes/composer.d.ts.map +1 -1
  154. package/dist/store/scopes/message.d.ts +30 -1
  155. package/dist/store/scopes/message.d.ts.map +1 -1
  156. package/dist/store/scopes/thread-list-item.d.ts +2 -2
  157. package/dist/store/scopes/thread-list-item.d.ts.map +1 -1
  158. package/dist/store/scopes/thread.d.ts +8 -0
  159. package/dist/store/scopes/thread.d.ts.map +1 -1
  160. package/dist/store/scopes/threads.d.ts +1 -0
  161. package/dist/store/scopes/threads.d.ts.map +1 -1
  162. package/dist/types/attachment.d.ts +2 -1
  163. package/dist/types/attachment.d.ts.map +1 -1
  164. package/dist/types/attachment.js +2 -1
  165. package/dist/types/attachment.js.map +1 -1
  166. package/dist/utils/abortable-iterable.d.ts +19 -0
  167. package/dist/utils/abortable-iterable.d.ts.map +1 -0
  168. package/dist/utils/abortable-iterable.js +72 -0
  169. package/dist/utils/abortable-iterable.js.map +1 -0
  170. package/dist/utils/composite-context-provider.d.ts.map +1 -1
  171. package/dist/utils/composite-context-provider.js +20 -2
  172. package/dist/utils/composite-context-provider.js.map +1 -1
  173. package/dist/utils/record.d.ts +11 -0
  174. package/dist/utils/record.d.ts.map +1 -0
  175. package/dist/utils/record.js +12 -0
  176. package/dist/utils/record.js.map +1 -0
  177. package/package.json +10 -10
  178. package/src/adapters/attachment.test.ts +50 -1
  179. package/src/adapters/attachment.ts +7 -4
  180. package/src/index.ts +1 -0
  181. package/src/internal.ts +4 -0
  182. package/src/model-context/frame/host.test.ts +24 -0
  183. package/src/model-context/frame/host.ts +10 -4
  184. package/src/model-context/frame/provider.test.ts +71 -0
  185. package/src/model-context/frame/provider.ts +37 -7
  186. package/src/model-context/interactable-composer-metadata.test.ts +28 -0
  187. package/src/model-context/interactable-composer-metadata.ts +9 -3
  188. package/src/model-context/registry.test.ts +12 -0
  189. package/src/model-context/registry.ts +3 -2
  190. package/src/model-context/types.test.ts +25 -0
  191. package/src/model-context/types.ts +9 -4
  192. package/src/react/RuntimeAdapter.test.ts +34 -0
  193. package/src/react/client/InMemoryThreadList.ts +1 -0
  194. package/src/react/client/Interactables.test.ts +28 -0
  195. package/src/react/client/Interactables.ts +15 -13
  196. package/src/react/client/RemoteThreadList.background.test.ts +148 -6
  197. package/src/react/client/RemoteThreadList.concurrent.test.tsx +42 -1
  198. package/src/react/client/RemoteThreadList.test.ts +345 -3
  199. package/src/react/client/RemoteThreadList.ts +166 -110
  200. package/src/react/client/Tools.ts +22 -11
  201. package/src/react/interactables-legacy/Interactables.ts +16 -16
  202. package/src/react/interactables-shared/useInteractablePersistenceQueue.ts +9 -10
  203. package/src/react/model-context/makeAssistantTool.ts +2 -2
  204. package/src/react/model-context/useAssistantTool.ts +2 -2
  205. package/src/react/model-context/useToolArgsStatus.test.tsx +30 -0
  206. package/src/react/model-context/useToolArgsStatus.ts +2 -1
  207. package/src/react/runtimes/RemoteThreadListHookInstanceManager.destroy.test.tsx +172 -0
  208. package/src/react/runtimes/RemoteThreadListHookInstanceManager.running.test.tsx +33 -0
  209. package/src/react/runtimes/RemoteThreadListHookInstanceManager.test.tsx +7 -1
  210. package/src/react/runtimes/RemoteThreadListHookInstanceManager.tsx +28 -5
  211. package/src/react/runtimes/RemoteThreadListThreadListRuntimeCore.load-error.test.ts +132 -0
  212. package/src/react/runtimes/RemoteThreadListThreadListRuntimeCore.switch-delete.test.ts +105 -0
  213. package/src/react/runtimes/RemoteThreadListThreadListRuntimeCore.tsx +136 -111
  214. package/src/react/runtimes/RemoteThreadResource.test.ts +9 -0
  215. package/src/react/runtimes/RemoteThreadResource.ts +19 -12
  216. package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.test.tsx +483 -6
  217. package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.ts +504 -68
  218. package/src/react/runtimes/cloud/createCloudThreadListAdapter.test.ts +15 -0
  219. package/src/react/runtimes/cloud/createCloudThreadListAdapter.ts +1 -0
  220. package/src/react/runtimes/useExternalStoreRuntime.lifecycle.test.tsx +41 -0
  221. package/src/react/runtimes/useExternalStoreRuntime.ts +10 -4
  222. package/src/react/runtimes/useLocalRuntime.test.tsx +20 -0
  223. package/src/react/runtimes/useRemoteThreadListRuntime.load-error.test.tsx +108 -0
  224. package/src/react/runtimes/useRemoteThreadListRuntime.ts +33 -0
  225. package/src/runtime/api/message-runtime.test.ts +75 -0
  226. package/src/runtime/api/thread-list-item-runtime.ts +10 -3
  227. package/src/runtime/api/thread-list-runtime.ts +21 -11
  228. package/src/runtime/api/thread-runtime.test.ts +78 -0
  229. package/src/runtime/api/thread-runtime.ts +8 -1
  230. package/src/runtime/base/base-composer-runtime-core.ts +36 -8
  231. package/src/runtime/base/base-thread-runtime-core.test.ts +55 -1
  232. package/src/runtime/base/base-thread-runtime-core.ts +6 -4
  233. package/src/runtime/interfaces/composer-runtime-core.ts +10 -5
  234. package/src/runtime/interfaces/thread-list-runtime-core.ts +5 -1
  235. package/src/runtime/utils/external-message-conversion.test.ts +68 -0
  236. package/src/runtime/utils/external-message-conversion.ts +1 -1
  237. package/src/runtime/utils/message-repository.ts +29 -17
  238. package/src/runtime/utils/thread-message-like.ts +1 -1
  239. package/src/runtimes/external-store/external-store-thread-list-runtime-core.ts +18 -13
  240. package/src/runtimes/internal.ts +1 -0
  241. package/src/runtimes/remote-thread-list/remote-thread-state.test.ts +128 -2
  242. package/src/runtimes/remote-thread-list/remote-thread-state.ts +182 -42
  243. package/src/runtimes/remote-thread-list/title-generation.test.ts +602 -0
  244. package/src/runtimes/remote-thread-list/title-generation.ts +329 -0
  245. package/src/runtimes/remote-thread-list/title.test.ts +62 -0
  246. package/src/runtimes/remote-thread-list/title.ts +13 -0
  247. package/src/runtimes/remote-thread-list/types.ts +10 -0
  248. package/src/store/clients/external-thread.ts +48 -3
  249. package/src/store/clients/model-context-client.ts +5 -1
  250. package/src/store/clients/single-thread-list.ts +1 -0
  251. package/src/store/clients/suggestions.test.ts +40 -0
  252. package/src/store/clients/suggestions.ts +13 -10
  253. package/src/store/runtime-clients/composer-runtime-client.ts +42 -9
  254. package/src/store/runtime-clients/message-runtime-client.ts +54 -6
  255. package/src/store/runtime-clients/thread-list-item-runtime-client.ts +4 -2
  256. package/src/store/runtime-clients/thread-list-runtime-client.ts +1 -0
  257. package/src/store/runtime-clients/thread-runtime-client.ts +58 -10
  258. package/src/store/scopes/composer.ts +16 -4
  259. package/src/store/scopes/message.ts +14 -0
  260. package/src/store/scopes/thread-list-item.ts +5 -2
  261. package/src/store/scopes/thread.ts +4 -0
  262. package/src/store/scopes/threads.ts +1 -0
  263. package/src/tests/MessageRepository.test.ts +116 -0
  264. package/src/tests/OptimisticState-list-race.test.ts +1 -0
  265. package/src/tests/RemoteThreadListThreadListRuntimeCore-initialize-adapter-change.test.ts +38 -0
  266. package/src/tests/RemoteThreadListThreadListRuntimeCore-load-race.test.ts +47 -0
  267. package/src/tests/RemoteThreadListThreadListRuntimeCore-title-race.test.ts +89 -0
  268. package/src/tests/attachment-adapters.test.ts +14 -0
  269. package/src/tests/base-composer-runtime-core.test.ts +39 -0
  270. package/src/tests/external-store-thread-list-runtime-core.test.ts +83 -0
  271. package/src/tests/external-store-thread-runtime-core-adapter.test.ts +27 -18
  272. package/src/tests/external-thread-attachments.test.tsx +139 -0
  273. package/src/tests/external-thread-parity.test.tsx +23 -0
  274. package/src/tests/remote-thread-list-isLoading.test.ts +1 -0
  275. package/src/tests/thread-list-runtime-getLoadThreadsPromise.test.ts +1 -0
  276. package/src/tests/thread-switch-events.test.tsx +78 -0
  277. package/src/tests/tools-scope-migration.test.tsx +28 -0
  278. package/src/types/attachment.ts +4 -0
  279. package/src/utils/abortable-iterable.test.ts +213 -0
  280. package/src/utils/abortable-iterable.ts +93 -0
  281. package/src/utils/composite-context-provider.test.ts +25 -0
  282. package/src/utils/composite-context-provider.ts +23 -2
  283. package/src/utils/record.test.ts +48 -0
  284. package/src/utils/record.ts +11 -0
@@ -1,7 +1,8 @@
1
1
  import { auiV0Decode, auiV0Encode } from "./auiV0.js";
2
+ import { c } from "@assistant-ui/tap/react-shim/compiler-runtime";
2
3
  import { useEffect, useRef, useState } from "@assistant-ui/tap/react-shim";
3
4
  import { getClientId, useAui } from "@assistant-ui/store";
4
- import { CloudMessagePersistence, createFormattedPersistence, createRunTelemetryToolCall, normalizeRunTelemetryUsage, truncateRunTelemetryText } from "assistant-cloud";
5
+ import { CloudMessagePersistence, createFormattedPersistence, createRunReport, createRunTelemetryToolCall, deriveRunOutcome, describeRunError, extractRunTelemetryModelId, normalizeRunTelemetryUsage, truncateRunTelemetryText } from "assistant-cloud";
5
6
  //#region src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.ts
6
7
  const globalPersistence = /* @__PURE__ */ new WeakMap();
7
8
  var AssistantCloudThreadHistoryAdapter = class {
@@ -22,6 +23,41 @@ var AssistantCloudThreadHistoryAdapter = class {
22
23
  get _persistence() {
23
24
  return this.getPersistence();
24
25
  }
26
+ /**
27
+ * A send is the moment the runtime creates the remote thread, so that one
28
+ * event waits for the id; every other event reads the id that already
29
+ * exists, because initializing a thread nobody has written to would create
30
+ * an empty remote thread just to attribute an event.
31
+ */
32
+ async resolveEngagementEventIds(threadId, messageId, options) {
33
+ const threadListItem = this.getThreadListItem(threadId);
34
+ if (!threadListItem) return {};
35
+ let remoteThreadId = threadListItem.getState().remoteId;
36
+ if (!remoteThreadId && options?.awaitThread) remoteThreadId = await threadListItem.initialize().then((result) => result.remoteId).catch(() => void 0);
37
+ const remoteMessageId = messageId ? this.getPersistence(threadListItem).getResolvedRemoteId(messageId) : void 0;
38
+ return {
39
+ ...remoteThreadId ? { thread_id: remoteThreadId } : void 0,
40
+ ...remoteMessageId ? { message_id: remoteMessageId } : void 0
41
+ };
42
+ }
43
+ feedback = { submit: ({ message, type }) => {
44
+ (async () => {
45
+ const threadListItem = this.tryGetKeyedThreadListItem();
46
+ const remoteThreadId = threadListItem?.getState().remoteId;
47
+ if (!threadListItem || !remoteThreadId) {
48
+ console.warn(`[assistant-ui] Skipping feedback for message ${message.id}: the thread has no remote id.`);
49
+ return;
50
+ }
51
+ const cloudMessageId = await this.getPersistence(threadListItem).getRemoteId(message.id);
52
+ if (!cloudMessageId) {
53
+ console.warn(`[assistant-ui] Skipping feedback for message ${message.id}: no cloud message id is mapped.`);
54
+ return;
55
+ }
56
+ await this.cloudRef.current.threads.messages.feedback(remoteThreadId, cloudMessageId, { type });
57
+ })().catch((error) => {
58
+ console.error("[assistant-ui] Cloud feedback submission failed:", error);
59
+ });
60
+ } };
25
61
  tryGetKeyedThreadListItem() {
26
62
  const live = this.aui.threadListItem;
27
63
  if (!live.source) return void 0;
@@ -29,6 +65,13 @@ var AssistantCloudThreadHistoryAdapter = class {
29
65
  if (id === void 0) return void 0;
30
66
  return this.aui.threads.getState().threadItems.some((item) => item.id === id || item.remoteId === id) ? this.aui.threads.item({ id }) : live;
31
67
  }
68
+ getThreadListItem(threadId) {
69
+ const current = this.aui.threadListItem;
70
+ const currentState = current.getState();
71
+ if (currentState.id === threadId || currentState.remoteId === threadId) return current;
72
+ const listed = this.aui.threads.getState().threadItems.find((item) => item.id === threadId || item.remoteId === threadId);
73
+ return listed ? this.aui.threads.item({ id: listed.id }) : void 0;
74
+ }
32
75
  withFormat(formatAdapter) {
33
76
  const adapter = this;
34
77
  let threadListItem;
@@ -60,7 +103,7 @@ var AssistantCloudThreadHistoryAdapter = class {
60
103
  },
61
104
  reportTelemetry(items, options) {
62
105
  const encodedRunMessages = items.map((item) => formatAdapter.encode(item));
63
- adapter._reportRunTelemetry(formatAdapter.format, encodedRunMessages, options, resolvePinned());
106
+ adapter._reportRunTelemetry(formatAdapter.format, encodedRunMessages, options, resolvePinned(), extractLastRunMessageInfo(items, formatAdapter));
64
107
  },
65
108
  async load() {
66
109
  const pinned = pinCurrent();
@@ -75,7 +118,7 @@ var AssistantCloudThreadHistoryAdapter = class {
75
118
  const { remoteId } = await this.aui.threadListItem.initialize();
76
119
  const encoded = auiV0Encode(message);
77
120
  await this._persistence.append(remoteId, message.id, parentId, "aui/v0", encoded);
78
- if (this.cloudRef.current.telemetry.enabled) this._maybeReportRun(remoteId, "aui/v0", encoded);
121
+ if (this.cloudRef.current.telemetry.enabled) this._maybeReportRun(remoteId, "aui/v0", encoded, extractRunMessageInfo(message, "aui/v0"));
79
122
  }
80
123
  async update(item) {
81
124
  if (!this._persistence.isPersisted(item.message.id)) return this.append(item);
@@ -84,7 +127,7 @@ var AssistantCloudThreadHistoryAdapter = class {
84
127
  if (!remoteId) return;
85
128
  const encoded = auiV0Encode(message);
86
129
  await this._persistence.update(remoteId, message.id, "aui/v0", encoded);
87
- if (this.cloudRef.current.telemetry.enabled) this._maybeReportRun(remoteId, "aui/v0", encoded);
130
+ if (this.cloudRef.current.telemetry.enabled) this._maybeReportRun(remoteId, "aui/v0", encoded, extractRunMessageInfo(message, "aui/v0"));
88
131
  }
89
132
  async delete() {
90
133
  throw new Error("Assistant Cloud does not support deleting thread messages yet.");
@@ -94,42 +137,68 @@ var AssistantCloudThreadHistoryAdapter = class {
94
137
  if (!remoteId) return { messages: [] };
95
138
  return { messages: (await this._persistence.load(remoteId, "aui/v0")).filter((m) => m.format === "aui/v0").map(auiV0Decode).reverse() };
96
139
  }
97
- _reportRunTelemetry(format, runMessages, options, threadListItem) {
140
+ _reportRunTelemetry(format, runMessages, options, threadListItem, messageInfo) {
98
141
  if (!this.cloudRef.current.telemetry.enabled) return;
99
- const remoteId = (threadListItem ?? this.aui.threadListItem).getState().remoteId;
142
+ const item = threadListItem ?? this.aui.threadListItem;
143
+ const remoteId = item.getState().remoteId;
100
144
  if (!remoteId) return;
101
145
  const extracted = extractRunTelemetry(format, runMessages);
102
146
  if (!extracted) return;
103
- this._sendReport(remoteId, extracted, options?.durationMs, options?.stepTimestamps);
147
+ this._sendReport(remoteId, extracted, options?.durationMs, options?.stepTimestamps, messageInfo, this.getPersistence(item));
104
148
  }
105
- _maybeReportRun(remoteId, format, content) {
149
+ _maybeReportRun(remoteId, format, content, messageInfo) {
106
150
  const extracted = extractTelemetry(format, content);
107
151
  if (!extracted) return;
108
- this._sendReport(remoteId, extracted);
152
+ this._sendReport(remoteId, extracted, void 0, void 0, messageInfo);
109
153
  }
110
- _sendReport(remoteId, data, durationMs, stepTimestamps) {
154
+ _sendReport(remoteId, data, durationMs, stepTimestamps, messageInfo, persistence = this._persistence) {
111
155
  const mergedSteps = mergeStepTimestamps(data.steps, stepTimestamps);
112
- const initial = {
113
- thread_id: remoteId,
114
- status: data.status,
115
- ...data.totalSteps != null ? { total_steps: data.totalSteps } : void 0,
116
- ...data.toolCalls ? { tool_calls: data.toolCalls } : void 0,
117
- ...mergedSteps ? { steps: mergedSteps } : void 0,
118
- ...data.inputTokens != null ? { input_tokens: data.inputTokens } : void 0,
119
- ...data.outputTokens != null ? { output_tokens: data.outputTokens } : void 0,
120
- ...data.reasoningTokens != null ? { reasoning_tokens: data.reasoningTokens } : void 0,
121
- ...data.cachedInputTokens != null ? { cached_input_tokens: data.cachedInputTokens } : void 0,
122
- ...durationMs != null ? { duration_ms: durationMs } : void 0,
123
- ...data.outputText != null ? { output_text: data.outputText } : void 0,
124
- ...data.metadata ? { metadata: data.metadata } : void 0,
125
- ...data.modelId ? { model_id: data.modelId } : void 0
126
- };
156
+ const messageId = messageInfo?.localMessageId ? persistence.getResolvedRemoteId(messageInfo.localMessageId) : void 0;
157
+ const initial = createRunReport({
158
+ threadId: remoteId,
159
+ status: messageInfo?.status ?? data.status,
160
+ outcome: messageInfo?.outcomeType,
161
+ error: messageInfo?.error,
162
+ errorCode: messageInfo?.errorCode,
163
+ messageId,
164
+ traceId: messageInfo?.traceId,
165
+ modelId: data.modelId,
166
+ provider: messageInfo?.provider,
167
+ usage: {
168
+ inputTokens: data.inputTokens,
169
+ outputTokens: data.outputTokens,
170
+ reasoningTokens: data.reasoningTokens,
171
+ cachedInputTokens: data.cachedInputTokens
172
+ },
173
+ steps: toRunReportSteps(mergedSteps),
174
+ totalSteps: data.totalSteps,
175
+ toolCalls: data.toolCalls,
176
+ durationMs,
177
+ firstTokenMs: messageInfo?.firstTokenMs,
178
+ outputText: data.outputText,
179
+ metadata: data.metadata,
180
+ telemetry: this.cloudRef.current.telemetry
181
+ });
127
182
  const { beforeReport } = this.cloudRef.current.telemetry;
128
183
  const report = beforeReport ? beforeReport(initial) : initial;
129
184
  if (!report) return;
130
185
  this.cloudRef.current.runs.report(report).catch(() => {});
131
186
  }
132
187
  };
188
+ function toRunReportSteps(steps) {
189
+ if (!steps) return void 0;
190
+ return steps.map((step) => ({
191
+ usage: {
192
+ inputTokens: step.input_tokens,
193
+ outputTokens: step.output_tokens,
194
+ reasoningTokens: step.reasoning_tokens,
195
+ cachedInputTokens: step.cached_input_tokens
196
+ },
197
+ toolCalls: step.tool_calls,
198
+ startMs: step.start_ms,
199
+ endMs: step.end_ms
200
+ }));
201
+ }
133
202
  function mergeStepTimestamps(steps, timestamps) {
134
203
  if (!timestamps) return steps;
135
204
  if (!steps) return timestamps.map((t) => ({ ...t }));
@@ -139,6 +208,46 @@ function mergeStepTimestamps(steps, timestamps) {
139
208
  ...i < len ? timestamps[i] : void 0
140
209
  }));
141
210
  }
211
+ function extractLastRunMessageInfo(items, formatAdapter) {
212
+ for (let i = items.length - 1; i >= 0; i--) {
213
+ const item = items[i];
214
+ const info = extractRunMessageInfo(item.message, formatAdapter.format, formatAdapter.getId(item.message));
215
+ if (info) return info;
216
+ }
217
+ }
218
+ function extractRunMessageInfo(message, format, localMessageId) {
219
+ if (!isRecord(message) || message.role !== "assistant") return void 0;
220
+ const status = isRecord(message.status) ? message.status : void 0;
221
+ const metadata = isRecord(message.metadata) ? message.metadata : void 0;
222
+ const custom = isRecord(metadata?.custom) ? metadata.custom : void 0;
223
+ const timing = isRecord(metadata?.timing) ? metadata.timing : void 0;
224
+ const streamStartTime = timing?.streamStartTime;
225
+ const firstTokenTime = timing?.firstTokenTime;
226
+ const firstTokenMs = typeof streamStartTime === "number" && Number.isFinite(streamStartTime) && typeof firstTokenTime === "number" && Number.isFinite(firstTokenTime) ? Math.round(firstTokenTime - streamStartTime) : void 0;
227
+ const finishReason = status?.type === "incomplete" ? status.reason : typeof metadata?.finishReason === "string" ? metadata.finishReason : void 0;
228
+ const failed = status?.type === "incomplete" && status.reason === "error";
229
+ const outcome = deriveRunOutcome({
230
+ finishReason: typeof finishReason === "string" ? finishReason : void 0,
231
+ isError: failed
232
+ });
233
+ const outcomeType = outcome.outcome;
234
+ const failure = failed ? describeRunError(status.error) : {};
235
+ const messageId = localMessageId ?? (typeof message.id === "string" ? message.id : void 0);
236
+ const traceId = format === "aui/v0" ? custom?.traceId : format === "ai-sdk/v6" ? metadata?.traceId : void 0;
237
+ const provider = typeof custom?.provider === "string" ? custom.provider : typeof metadata?.provider === "string" ? metadata.provider : void 0;
238
+ return {
239
+ ...messageId ? { localMessageId: messageId } : void 0,
240
+ ...outcome.status === "error" ? { status: "error" } : void 0,
241
+ ...outcomeType ? { outcomeType } : void 0,
242
+ ...failure,
243
+ ...firstTokenMs != null && firstTokenMs >= 0 ? { firstTokenMs } : void 0,
244
+ ...typeof traceId === "string" ? { traceId } : void 0,
245
+ ...provider !== void 0 ? { provider } : void 0
246
+ };
247
+ }
248
+ function isRecord(value) {
249
+ return value !== null && typeof value === "object";
250
+ }
142
251
  function extractTelemetry(format, content) {
143
252
  switch (format) {
144
253
  case "aui/v0": return extractAuiV0(content);
@@ -212,9 +321,9 @@ function extractAuiV0(content) {
212
321
  cachedInputTokens = hasCachedInput ? totalCachedInput : void 0;
213
322
  }
214
323
  const statusType = msg.status?.type;
215
- const status = statusType && AUI_STATUS_MAP[statusType] || "completed";
324
+ const status = statusType === "incomplete" && msg.status?.reason === "error" ? "error" : statusType && AUI_STATUS_MAP[statusType] || "completed";
216
325
  const metadata = msg.metadata?.custom;
217
- const modelId = msg.metadata?.modelId ?? (typeof msg.metadata?.custom?.modelId === "string" ? msg.metadata.custom.modelId : void 0);
326
+ const modelId = extractRunTelemetryModelId(msg.metadata);
218
327
  const telemetrySteps = steps && steps.length > 1 ? steps.map((s) => {
219
328
  const usage = s.usage ? normalizeRunTelemetryUsage(s.usage) : void 0;
220
329
  return {
@@ -277,16 +386,10 @@ function collectAiSdkV6Parts(parts) {
277
386
  stepsData
278
387
  };
279
388
  }
280
- function extractModelId(metadata) {
281
- if (!metadata) return void 0;
282
- if (typeof metadata.modelId === "string") return metadata.modelId;
283
- const custom = metadata.custom;
284
- if (typeof custom?.modelId === "string") return custom.modelId;
285
- }
286
389
  function buildAiSdkV6Result(textParts, toolCalls, totalSteps, metadata, stepsData, usage) {
287
390
  const hasText = textParts.length > 0;
288
391
  const outputText = hasText ? truncateRunTelemetryText(textParts.join("")) : void 0;
289
- const modelId = extractModelId(metadata);
392
+ const modelId = extractRunTelemetryModelId(metadata);
290
393
  const steps = stepsData && stepsData.length > 1 ? stepsData.map((s) => ({ ...s.tool_calls.length > 0 ? { tool_calls: s.tool_calls } : void 0 })) : void 0;
291
394
  return {
292
395
  status: hasText ? "completed" : "incomplete",
@@ -414,8 +517,272 @@ function useAssistantCloudThreadHistoryAdapter(cloudRef) {
414
517
  auiRef.current = aui;
415
518
  });
416
519
  const [adapter] = useState(() => new AssistantCloudThreadHistoryAdapter(cloudRef, () => auiRef.current));
520
+ useAssistantCloudEngagementEvents(cloudRef, adapter, aui);
417
521
  return adapter;
418
522
  }
523
+ const rootEngagementTrackers = /* @__PURE__ */ new WeakMap();
524
+ /**
525
+ * Thread switches are a thread list event, so one subscription per assistant
526
+ * client reports them; every thread runtime mounted under it shares the
527
+ * subscription and the last one to unmount removes it.
528
+ */
529
+ const useRootEngagementEvents = (cloudRef, adapter, aui) => {
530
+ const $ = c(5);
531
+ let t0;
532
+ let t1;
533
+ if ($[0] !== adapter || $[1] !== aui || $[2] !== cloudRef) {
534
+ t0 = () => {
535
+ let tracker = rootEngagementTrackers.get(aui);
536
+ if (!tracker) {
537
+ const created = {
538
+ count: 0,
539
+ adapter,
540
+ cloudRef,
541
+ dispose: _temp
542
+ };
543
+ created.dispose = aui.on({
544
+ scope: "*",
545
+ event: "threads.selectionChanged"
546
+ }, (payload) => {
547
+ created.adapter.resolveEngagementEventIds(payload.threadId).then((ids) => {
548
+ if (!ids.thread_id) return;
549
+ created.cloudRef.current.events?.track({
550
+ kind: "thread_switched",
551
+ ...ids
552
+ });
553
+ }).catch(_temp2);
554
+ });
555
+ rootEngagementTrackers.set(aui, created);
556
+ tracker = created;
557
+ }
558
+ const active = tracker;
559
+ active.adapter = adapter;
560
+ active.cloudRef = cloudRef;
561
+ active.count = active.count + 1;
562
+ return () => {
563
+ active.count = active.count - 1;
564
+ if (active.count === 0) {
565
+ active.dispose();
566
+ rootEngagementTrackers.delete(aui);
567
+ }
568
+ };
569
+ };
570
+ t1 = [
571
+ adapter,
572
+ aui,
573
+ cloudRef
574
+ ];
575
+ $[0] = adapter;
576
+ $[1] = aui;
577
+ $[2] = cloudRef;
578
+ $[3] = t0;
579
+ $[4] = t1;
580
+ } else {
581
+ t0 = $[3];
582
+ t1 = $[4];
583
+ }
584
+ useEffect(t0, t1);
585
+ };
586
+ const useAssistantCloudEngagementEvents = (cloudRef, adapter, aui) => {
587
+ const $ = c(13);
588
+ useRootEngagementEvents(cloudRef, adapter, aui);
589
+ let t0;
590
+ if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
591
+ t0 = /* @__PURE__ */ new Map();
592
+ $[0] = t0;
593
+ } else t0 = $[0];
594
+ const runStartedAt = useRef(t0);
595
+ let t1;
596
+ if ($[1] === Symbol.for("react.memo_cache_sentinel")) {
597
+ t1 = /* @__PURE__ */ new Map();
598
+ $[1] = t1;
599
+ } else t1 = $[1];
600
+ const runEndedAt = useRef(t1);
601
+ let t2;
602
+ if ($[2] === Symbol.for("react.memo_cache_sentinel")) {
603
+ t2 = /* @__PURE__ */ new Set();
604
+ $[2] = t2;
605
+ } else t2 = $[2];
606
+ const shownSuggestions = useRef(t2);
607
+ let t3;
608
+ let t4;
609
+ if ($[3] !== adapter || $[4] !== aui || $[5] !== cloudRef) {
610
+ t3 = () => {
611
+ const track = (event, threadId, messageId, options) => {
612
+ adapter.resolveEngagementEventIds(threadId, messageId, options).then((ids) => {
613
+ cloudRef.current.events?.track({
614
+ ...event,
615
+ ...ids
616
+ });
617
+ }).catch(_temp3);
618
+ };
619
+ const trackRunStopped = (threadId_0) => {
620
+ const startedAt = runStartedAt.current.get(threadId_0);
621
+ if (startedAt === void 0) return;
622
+ runStartedAt.current.delete(threadId_0);
623
+ track({
624
+ kind: "run_stopped",
625
+ value: Math.max(0, Date.now() - startedAt)
626
+ }, threadId_0);
627
+ };
628
+ const unsubscribers = [
629
+ aui.on({
630
+ scope: "thread",
631
+ event: "composer.send"
632
+ }, (payload) => {
633
+ const previousRunEndedAt = runEndedAt.current.get(payload.threadId);
634
+ track({
635
+ kind: payload.messageId ? "message_edited" : "message_sent",
636
+ ...payload.messageId ? { props: { chars: payload.chars } } : { props: {
637
+ chars: payload.chars,
638
+ attachments: payload.attachments
639
+ } },
640
+ ...!payload.messageId && previousRunEndedAt !== void 0 ? { value: Math.max(0, Date.now() - previousRunEndedAt) } : void 0
641
+ }, payload.threadId, payload.messageId, { awaitThread: !payload.messageId });
642
+ if (payload.suggestion) track({ kind: "suggestion_clicked" }, payload.threadId);
643
+ }),
644
+ aui.on({
645
+ scope: "thread",
646
+ event: "composer.attachmentAdd"
647
+ }, (payload_0) => {
648
+ track({
649
+ kind: "attachment_added",
650
+ ...payload_0.contentType ? { props: { type: payload_0.contentType } } : void 0
651
+ }, payload_0.threadId, payload_0.messageId);
652
+ }),
653
+ aui.on({
654
+ scope: "thread",
655
+ event: "composer.attachmentAddError"
656
+ }, (payload_1) => {
657
+ track({
658
+ kind: "attachment_failed",
659
+ ...payload_1.contentType ? { props: { type: payload_1.contentType } } : void 0
660
+ }, payload_1.threadId, payload_1.messageId);
661
+ }),
662
+ aui.on({
663
+ scope: "thread",
664
+ event: "composer.cancel"
665
+ }, (payload_2) => {
666
+ trackRunStopped(payload_2.threadId);
667
+ }),
668
+ aui.on({
669
+ scope: "thread",
670
+ event: "thread.runStart"
671
+ }, (payload_3) => {
672
+ runStartedAt.current.set(payload_3.threadId, Date.now());
673
+ }),
674
+ aui.on({
675
+ scope: "thread",
676
+ event: "thread.runEnd"
677
+ }, (payload_4) => {
678
+ runStartedAt.current.delete(payload_4.threadId);
679
+ runEndedAt.current.set(payload_4.threadId, Date.now());
680
+ }),
681
+ aui.on({
682
+ scope: "thread",
683
+ event: "thread.cancelRun"
684
+ }, (payload_5) => {
685
+ trackRunStopped(payload_5.threadId);
686
+ }),
687
+ aui.on({
688
+ scope: "thread",
689
+ event: "thread.voiceStarted"
690
+ }, (payload_6) => {
691
+ track({ kind: "voice_started" }, payload_6.threadId);
692
+ }),
693
+ aui.on({
694
+ scope: "thread",
695
+ event: "message.reload"
696
+ }, (payload_7) => {
697
+ track({ kind: "message_regenerated" }, payload_7.threadId, payload_7.messageId);
698
+ }),
699
+ aui.on({
700
+ scope: "thread",
701
+ event: "message.branchSwitched"
702
+ }, (payload_8) => {
703
+ track({ kind: "branch_switched" }, payload_8.threadId, payload_8.messageId);
704
+ }),
705
+ aui.on({
706
+ scope: "thread",
707
+ event: "message.copied"
708
+ }, (payload_9) => {
709
+ track({ kind: "message_copied" }, payload_9.threadId, payload_9.messageId);
710
+ }),
711
+ aui.on({
712
+ scope: "thread",
713
+ event: "message.speak"
714
+ }, (payload_10) => {
715
+ track({ kind: "speech_started" }, payload_10.threadId, payload_10.messageId);
716
+ }),
717
+ aui.on({
718
+ scope: "thread",
719
+ event: "message.error"
720
+ }, (payload_11) => {
721
+ track({
722
+ kind: "error_shown",
723
+ props: { reason: payload_11.reason }
724
+ }, payload_11.threadId, payload_11.messageId);
725
+ })
726
+ ];
727
+ return () => {
728
+ for (const unsubscribe of unsubscribers) unsubscribe();
729
+ };
730
+ };
731
+ t4 = [
732
+ adapter,
733
+ aui,
734
+ cloudRef
735
+ ];
736
+ $[3] = adapter;
737
+ $[4] = aui;
738
+ $[5] = cloudRef;
739
+ $[6] = t3;
740
+ $[7] = t4;
741
+ } else {
742
+ t3 = $[6];
743
+ t4 = $[7];
744
+ }
745
+ useEffect(t3, t4);
746
+ let t5;
747
+ let t6;
748
+ if ($[8] !== adapter || $[9] !== aui || $[10] !== cloudRef) {
749
+ t5 = () => {
750
+ const reportSuggestions = () => {
751
+ const { mainThreadId } = aui.threads.getState();
752
+ if (aui.threadListItem.getState().id !== mainThreadId) return;
753
+ const { isEmpty, suggestions } = aui.thread.getState();
754
+ if (!isEmpty || suggestions.length === 0 || shownSuggestions.current.has(mainThreadId)) return;
755
+ shownSuggestions.current.add(mainThreadId);
756
+ adapter.resolveEngagementEventIds(mainThreadId).then((ids_0) => {
757
+ cloudRef.current.events?.track({
758
+ kind: "suggestions_shown",
759
+ value: suggestions.length,
760
+ ...ids_0
761
+ });
762
+ });
763
+ };
764
+ reportSuggestions();
765
+ return aui.subscribe(reportSuggestions);
766
+ };
767
+ t6 = [
768
+ adapter,
769
+ aui,
770
+ cloudRef
771
+ ];
772
+ $[8] = adapter;
773
+ $[9] = aui;
774
+ $[10] = cloudRef;
775
+ $[11] = t5;
776
+ $[12] = t6;
777
+ } else {
778
+ t5 = $[11];
779
+ t6 = $[12];
780
+ }
781
+ useEffect(t5, t6);
782
+ };
783
+ function _temp() {}
784
+ function _temp2() {}
785
+ function _temp3() {}
419
786
  //#endregion
420
787
  export { extractAuiV0, useAssistantCloudThreadHistoryAdapter };
421
788