@assistant-ui/core 0.3.17 → 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 (470) 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/adapters/speech.d.ts.map +1 -1
  5. package/dist/adapters/speech.js +13 -3
  6. package/dist/adapters/speech.js.map +1 -1
  7. package/dist/adapters/thread-history.d.ts +4 -0
  8. package/dist/adapters/thread-history.d.ts.map +1 -1
  9. package/dist/index.d.ts +3 -3
  10. package/dist/index.js.map +1 -1
  11. package/dist/internal.d.ts +4 -3
  12. package/dist/internal.js +3 -2
  13. package/dist/model-context/frame/host.d.ts.map +1 -1
  14. package/dist/model-context/frame/host.js +35 -14
  15. package/dist/model-context/frame/host.js.map +1 -1
  16. package/dist/model-context/frame/provider.d.ts +2 -0
  17. package/dist/model-context/frame/provider.d.ts.map +1 -1
  18. package/dist/model-context/frame/provider.js +30 -7
  19. package/dist/model-context/frame/provider.js.map +1 -1
  20. package/dist/model-context/interactable-composer-metadata.d.ts.map +1 -1
  21. package/dist/model-context/interactable-composer-metadata.js +27 -18
  22. package/dist/model-context/interactable-composer-metadata.js.map +1 -1
  23. package/dist/model-context/registry.d.ts.map +1 -1
  24. package/dist/model-context/registry.js +3 -5
  25. package/dist/model-context/registry.js.map +1 -1
  26. package/dist/model-context/types.d.ts.map +1 -1
  27. package/dist/model-context/types.js +5 -4
  28. package/dist/model-context/types.js.map +1 -1
  29. package/dist/react/adapters/LocalStorageThreadListAdapter.d.ts.map +1 -1
  30. package/dist/react/adapters/LocalStorageThreadListAdapter.js +45 -7
  31. package/dist/react/adapters/LocalStorageThreadListAdapter.js.map +1 -1
  32. package/dist/react/client/DataRenderers.d.ts.map +1 -1
  33. package/dist/react/client/DataRenderers.js +20 -15
  34. package/dist/react/client/DataRenderers.js.map +1 -1
  35. package/dist/react/client/InMemoryThreadList.d.ts.map +1 -1
  36. package/dist/react/client/InMemoryThreadList.js +62 -56
  37. package/dist/react/client/InMemoryThreadList.js.map +1 -1
  38. package/dist/react/client/Interactables.d.ts.map +1 -1
  39. package/dist/react/client/Interactables.js +35 -32
  40. package/dist/react/client/Interactables.js.map +1 -1
  41. package/dist/react/client/RemoteThreadList.d.ts +1 -0
  42. package/dist/react/client/RemoteThreadList.d.ts.map +1 -1
  43. package/dist/react/client/RemoteThreadList.js +154 -143
  44. package/dist/react/client/RemoteThreadList.js.map +1 -1
  45. package/dist/react/client/Tools.d.ts.map +1 -1
  46. package/dist/react/client/Tools.js +18 -16
  47. package/dist/react/client/Tools.js.map +1 -1
  48. package/dist/react/client/interactable-model-context.d.ts.map +1 -1
  49. package/dist/react/client/interactable-model-context.js +3 -2
  50. package/dist/react/client/interactable-model-context.js.map +1 -1
  51. package/dist/react/index.d.ts +2 -2
  52. package/dist/react/index.js +2 -2
  53. package/dist/react/interactables-legacy/Interactables.js +242 -121
  54. package/dist/react/interactables-legacy/Interactables.js.map +1 -1
  55. package/dist/react/interactables-legacy/useAssistantInteractable.d.ts.map +1 -1
  56. package/dist/react/interactables-legacy/useAssistantInteractable.js +3 -0
  57. package/dist/react/interactables-legacy/useAssistantInteractable.js.map +1 -1
  58. package/dist/react/interactables-shared/useInteractablePersistenceQueue.d.ts.map +1 -1
  59. package/dist/react/interactables-shared/useInteractablePersistenceQueue.js +11 -9
  60. package/dist/react/interactables-shared/useInteractablePersistenceQueue.js.map +1 -1
  61. package/dist/react/model-context/makeAssistantTool.d.ts +2 -2
  62. package/dist/react/model-context/makeAssistantTool.js +1 -1
  63. package/dist/react/model-context/makeAssistantTool.js.map +1 -1
  64. package/dist/react/model-context/useAssistantTool.d.ts +2 -2
  65. package/dist/react/model-context/useAssistantTool.js +1 -1
  66. package/dist/react/model-context/useAssistantTool.js.map +1 -1
  67. package/dist/react/model-context/useInteractable.d.ts.map +1 -1
  68. package/dist/react/model-context/useInteractable.js +4 -1
  69. package/dist/react/model-context/useInteractable.js.map +1 -1
  70. package/dist/react/model-context/useInteractableVersions.js +1 -1
  71. package/dist/react/model-context/useToolArgsStatus.d.ts.map +1 -1
  72. package/dist/react/model-context/useToolArgsStatus.js +2 -1
  73. package/dist/react/model-context/useToolArgsStatus.js.map +1 -1
  74. package/dist/react/primitives/message/MessageGroupedParts.d.ts +11 -2
  75. package/dist/react/primitives/message/MessageGroupedParts.d.ts.map +1 -1
  76. package/dist/react/primitives/message/MessageGroupedParts.js +3 -2
  77. package/dist/react/primitives/message/MessageGroupedParts.js.map +1 -1
  78. package/dist/react/primitives/part/PartMessages.d.ts +1 -0
  79. package/dist/react/primitives/part/PartMessages.d.ts.map +1 -1
  80. package/dist/react/primitives/part/PartMessages.js +1 -0
  81. package/dist/react/primitives/part/PartMessages.js.map +1 -1
  82. package/dist/react/primitives/thread/ThreadMessages.d.ts.map +1 -1
  83. package/dist/react/primitives/thread/ThreadMessages.js +6 -5
  84. package/dist/react/primitives/thread/ThreadMessages.js.map +1 -1
  85. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.d.ts.map +1 -1
  86. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js +16 -8
  87. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js.map +1 -1
  88. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts +5 -1
  89. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts.map +1 -1
  90. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js +105 -104
  91. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js.map +1 -1
  92. package/dist/react/runtimes/RemoteThreadResource.d.ts +1 -0
  93. package/dist/react/runtimes/RemoteThreadResource.d.ts.map +1 -1
  94. package/dist/react/runtimes/RemoteThreadResource.js +13 -11
  95. package/dist/react/runtimes/RemoteThreadResource.js.map +1 -1
  96. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.d.ts +5 -24
  97. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.d.ts.map +1 -1
  98. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.js +354 -226
  99. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.js.map +1 -1
  100. package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.d.ts +1 -0
  101. package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.d.ts.map +1 -1
  102. package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.js +22 -2
  103. package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.js.map +1 -1
  104. package/dist/react/runtimes/cloud/auiV0.d.ts +40 -15
  105. package/dist/react/runtimes/cloud/auiV0.d.ts.map +1 -1
  106. package/dist/react/runtimes/cloud/auiV0.js +62 -15
  107. package/dist/react/runtimes/cloud/auiV0.js.map +1 -1
  108. package/dist/react/runtimes/cloud/createCloudThreadListAdapter.d.ts +2 -1
  109. package/dist/react/runtimes/cloud/createCloudThreadListAdapter.d.ts.map +1 -1
  110. package/dist/react/runtimes/cloud/createCloudThreadListAdapter.js +6 -1
  111. package/dist/react/runtimes/cloud/createCloudThreadListAdapter.js.map +1 -1
  112. package/dist/react/runtimes/cloud/sdkIdentity.d.ts +6 -0
  113. package/dist/react/runtimes/cloud/sdkIdentity.d.ts.map +1 -0
  114. package/dist/react/runtimes/cloud/sdkIdentity.js +9 -0
  115. package/dist/react/runtimes/cloud/sdkIdentity.js.map +1 -0
  116. package/dist/react/runtimes/external-message-converter.d.ts +12 -2
  117. package/dist/react/runtimes/external-message-converter.d.ts.map +1 -1
  118. package/dist/react/runtimes/external-message-converter.js +26 -61
  119. package/dist/react/runtimes/external-message-converter.js.map +1 -1
  120. package/dist/react/runtimes/useExternalStoreRuntime.js +75 -46
  121. package/dist/react/runtimes/useExternalStoreRuntime.js.map +1 -1
  122. package/dist/react/runtimes/useRemoteThreadListRuntime.d.ts.map +1 -1
  123. package/dist/react/runtimes/useRemoteThreadListRuntime.js +64 -24
  124. package/dist/react/runtimes/useRemoteThreadListRuntime.js.map +1 -1
  125. package/dist/react/utils/groupParts.d.ts +6 -1
  126. package/dist/react/utils/groupParts.d.ts.map +1 -1
  127. package/dist/react/utils/groupParts.js +6 -0
  128. package/dist/react/utils/groupParts.js.map +1 -1
  129. package/dist/react/utils/useJSONEqual.d.ts +3 -1
  130. package/dist/react/utils/useJSONEqual.d.ts.map +1 -1
  131. package/dist/react/utils/useJSONEqual.js +6 -1
  132. package/dist/react/utils/useJSONEqual.js.map +1 -1
  133. package/dist/react/utils/useJSONSchemaDependency.d.ts +7 -0
  134. package/dist/react/utils/useJSONSchemaDependency.d.ts.map +1 -0
  135. package/dist/react/utils/useJSONSchemaDependency.js +20 -0
  136. package/dist/react/utils/useJSONSchemaDependency.js.map +1 -0
  137. package/dist/runtime/api/thread-list-item-runtime.d.ts +7 -3
  138. package/dist/runtime/api/thread-list-item-runtime.d.ts.map +1 -1
  139. package/dist/runtime/api/thread-list-item-runtime.js +2 -2
  140. package/dist/runtime/api/thread-list-item-runtime.js.map +1 -1
  141. package/dist/runtime/api/thread-list-runtime.d.ts +3 -0
  142. package/dist/runtime/api/thread-list-runtime.d.ts.map +1 -1
  143. package/dist/runtime/api/thread-list-runtime.js +18 -14
  144. package/dist/runtime/api/thread-list-runtime.js.map +1 -1
  145. package/dist/runtime/api/thread-runtime.d.ts +4 -0
  146. package/dist/runtime/api/thread-runtime.d.ts.map +1 -1
  147. package/dist/runtime/api/thread-runtime.js +3 -6
  148. package/dist/runtime/api/thread-runtime.js.map +1 -1
  149. package/dist/runtime/base/base-composer-runtime-core.d.ts +1 -0
  150. package/dist/runtime/base/base-composer-runtime-core.d.ts.map +1 -1
  151. package/dist/runtime/base/base-composer-runtime-core.js +62 -22
  152. package/dist/runtime/base/base-composer-runtime-core.js.map +1 -1
  153. package/dist/runtime/base/base-thread-runtime-core.d.ts +2 -0
  154. package/dist/runtime/base/base-thread-runtime-core.d.ts.map +1 -1
  155. package/dist/runtime/base/base-thread-runtime-core.js +161 -69
  156. package/dist/runtime/base/base-thread-runtime-core.js.map +1 -1
  157. package/dist/runtime/interfaces/composer-runtime-core.d.ts +12 -5
  158. package/dist/runtime/interfaces/composer-runtime-core.d.ts.map +1 -1
  159. package/dist/runtime/interfaces/thread-list-runtime-core.d.ts +4 -1
  160. package/dist/runtime/interfaces/thread-list-runtime-core.d.ts.map +1 -1
  161. package/dist/runtime/interfaces/thread-runtime-core.d.ts +6 -0
  162. package/dist/runtime/interfaces/thread-runtime-core.d.ts.map +1 -1
  163. package/dist/runtime/queue/message-queue.d.ts +5 -0
  164. package/dist/runtime/queue/message-queue.d.ts.map +1 -1
  165. package/dist/runtime/queue/message-queue.js +61 -6
  166. package/dist/runtime/queue/message-queue.js.map +1 -1
  167. package/dist/runtime/utils/auto-status.d.ts +6 -2
  168. package/dist/runtime/utils/auto-status.d.ts.map +1 -1
  169. package/dist/runtime/utils/auto-status.js +12 -4
  170. package/dist/runtime/utils/auto-status.js.map +1 -1
  171. package/dist/runtime/utils/external-message-conversion.d.ts +16 -4
  172. package/dist/runtime/utils/external-message-conversion.d.ts.map +1 -1
  173. package/dist/runtime/utils/external-message-conversion.js +49 -13
  174. package/dist/runtime/utils/external-message-conversion.js.map +1 -1
  175. package/dist/runtime/utils/message-repository.d.ts +1 -0
  176. package/dist/runtime/utils/message-repository.d.ts.map +1 -1
  177. package/dist/runtime/utils/message-repository.js +18 -9
  178. package/dist/runtime/utils/message-repository.js.map +1 -1
  179. package/dist/runtime/utils/thread-message-like.d.ts +2 -1
  180. package/dist/runtime/utils/thread-message-like.d.ts.map +1 -1
  181. package/dist/runtime/utils/thread-message-like.js +5 -3
  182. package/dist/runtime/utils/thread-message-like.js.map +1 -1
  183. package/dist/runtimes/external-store/external-store-thread-list-runtime-core.d.ts.map +1 -1
  184. package/dist/runtimes/external-store/external-store-thread-list-runtime-core.js +21 -27
  185. package/dist/runtimes/external-store/external-store-thread-list-runtime-core.js.map +1 -1
  186. package/dist/runtimes/external-store/external-store-thread-runtime-core.d.ts.map +1 -1
  187. package/dist/runtimes/external-store/external-store-thread-runtime-core.js +8 -1
  188. package/dist/runtimes/external-store/external-store-thread-runtime-core.js.map +1 -1
  189. package/dist/runtimes/internal.d.ts +3 -3
  190. package/dist/runtimes/internal.js +2 -2
  191. package/dist/runtimes/local/local-thread-runtime-core.d.ts +1 -1
  192. package/dist/runtimes/local/local-thread-runtime-core.d.ts.map +1 -1
  193. package/dist/runtimes/local/local-thread-runtime-core.js +4 -1
  194. package/dist/runtimes/local/local-thread-runtime-core.js.map +1 -1
  195. package/dist/runtimes/remote-thread-list/remote-thread-state.d.ts +18 -1
  196. package/dist/runtimes/remote-thread-list/remote-thread-state.d.ts.map +1 -1
  197. package/dist/runtimes/remote-thread-list/remote-thread-state.js +130 -42
  198. package/dist/runtimes/remote-thread-list/remote-thread-state.js.map +1 -1
  199. package/dist/runtimes/remote-thread-list/title-generation.d.ts +49 -0
  200. package/dist/runtimes/remote-thread-list/title-generation.d.ts.map +1 -0
  201. package/dist/runtimes/remote-thread-list/title-generation.js +197 -0
  202. package/dist/runtimes/remote-thread-list/title-generation.js.map +1 -0
  203. package/dist/runtimes/remote-thread-list/title.d.ts +3 -1
  204. package/dist/runtimes/remote-thread-list/title.d.ts.map +1 -1
  205. package/dist/runtimes/remote-thread-list/title.js +9 -1
  206. package/dist/runtimes/remote-thread-list/title.js.map +1 -1
  207. package/dist/runtimes/remote-thread-list/types.d.ts +10 -0
  208. package/dist/runtimes/remote-thread-list/types.d.ts.map +1 -1
  209. package/dist/runtimes/tool-invocations/ToolInvocationTracker.d.ts.map +1 -1
  210. package/dist/runtimes/tool-invocations/ToolInvocationTracker.js +2 -1
  211. package/dist/runtimes/tool-invocations/ToolInvocationTracker.js.map +1 -1
  212. package/dist/store/clients/external-thread.d.ts.map +1 -1
  213. package/dist/store/clients/external-thread.js +260 -203
  214. package/dist/store/clients/external-thread.js.map +1 -1
  215. package/dist/store/clients/model-context-client.d.ts.map +1 -1
  216. package/dist/store/clients/model-context-client.js +2 -1
  217. package/dist/store/clients/model-context-client.js.map +1 -1
  218. package/dist/store/clients/single-thread-list.d.ts.map +1 -1
  219. package/dist/store/clients/single-thread-list.js +1 -0
  220. package/dist/store/clients/single-thread-list.js.map +1 -1
  221. package/dist/store/clients/suggestions.d.ts.map +1 -1
  222. package/dist/store/clients/suggestions.js +5 -4
  223. package/dist/store/clients/suggestions.js.map +1 -1
  224. package/dist/store/clients/thread-tasks.d.ts +13 -0
  225. package/dist/store/clients/thread-tasks.d.ts.map +1 -0
  226. package/dist/store/clients/thread-tasks.js +69 -0
  227. package/dist/store/clients/thread-tasks.js.map +1 -0
  228. package/dist/store/index.d.ts +3 -2
  229. package/dist/store/index.js +3 -3
  230. package/dist/store/primitive-predicates.d.ts.map +1 -1
  231. package/dist/store/primitive-predicates.js +4 -4
  232. package/dist/store/primitive-predicates.js.map +1 -1
  233. package/dist/store/runtime-clients/composer-runtime-client.d.ts +1 -0
  234. package/dist/store/runtime-clients/composer-runtime-client.d.ts.map +1 -1
  235. package/dist/store/runtime-clients/composer-runtime-client.js +97 -61
  236. package/dist/store/runtime-clients/composer-runtime-client.js.map +1 -1
  237. package/dist/store/runtime-clients/message-runtime-client.d.ts +1 -0
  238. package/dist/store/runtime-clients/message-runtime-client.d.ts.map +1 -1
  239. package/dist/store/runtime-clients/message-runtime-client.js +221 -144
  240. package/dist/store/runtime-clients/message-runtime-client.js.map +1 -1
  241. package/dist/store/runtime-clients/thread-list-item-runtime-client.d.ts.map +1 -1
  242. package/dist/store/runtime-clients/thread-list-item-runtime-client.js +1 -1
  243. package/dist/store/runtime-clients/thread-list-item-runtime-client.js.map +1 -1
  244. package/dist/store/runtime-clients/thread-list-runtime-client.d.ts.map +1 -1
  245. package/dist/store/runtime-clients/thread-list-runtime-client.js +54 -52
  246. package/dist/store/runtime-clients/thread-list-runtime-client.js.map +1 -1
  247. package/dist/store/runtime-clients/thread-runtime-client.d.ts.map +1 -1
  248. package/dist/store/runtime-clients/thread-runtime-client.js +246 -126
  249. package/dist/store/runtime-clients/thread-runtime-client.js.map +1 -1
  250. package/dist/store/scope-registration.d.ts +2 -0
  251. package/dist/store/scope-registration.d.ts.map +1 -1
  252. package/dist/store/scopes/composer.d.ts +10 -2
  253. package/dist/store/scopes/composer.d.ts.map +1 -1
  254. package/dist/store/scopes/message.d.ts +30 -1
  255. package/dist/store/scopes/message.d.ts.map +1 -1
  256. package/dist/store/scopes/task.d.ts +36 -0
  257. package/dist/store/scopes/task.d.ts.map +1 -0
  258. package/dist/store/scopes/task.js +0 -0
  259. package/dist/store/scopes/thread-list-item.d.ts +2 -2
  260. package/dist/store/scopes/thread-list-item.d.ts.map +1 -1
  261. package/dist/store/scopes/thread.d.ts +28 -0
  262. package/dist/store/scopes/thread.d.ts.map +1 -1
  263. package/dist/store/scopes/threads.d.ts +1 -0
  264. package/dist/store/scopes/threads.d.ts.map +1 -1
  265. package/dist/subscribable/subscribable.d.ts +2 -1
  266. package/dist/subscribable/subscribable.d.ts.map +1 -1
  267. package/dist/subscribable/subscribable.js +23 -15
  268. package/dist/subscribable/subscribable.js.map +1 -1
  269. package/dist/types/attachment.d.ts +2 -1
  270. package/dist/types/attachment.d.ts.map +1 -1
  271. package/dist/types/attachment.js +2 -1
  272. package/dist/types/attachment.js.map +1 -1
  273. package/dist/types/index.d.ts +2 -2
  274. package/dist/types/message.d.ts +8 -1
  275. package/dist/types/message.d.ts.map +1 -1
  276. package/dist/types/message.js.map +1 -1
  277. package/dist/utils/abortable-iterable.d.ts +19 -0
  278. package/dist/utils/abortable-iterable.d.ts.map +1 -0
  279. package/dist/utils/abortable-iterable.js +88 -0
  280. package/dist/utils/abortable-iterable.js.map +1 -0
  281. package/dist/utils/composite-context-provider.d.ts.map +1 -1
  282. package/dist/utils/composite-context-provider.js +20 -2
  283. package/dist/utils/composite-context-provider.js.map +1 -1
  284. package/dist/utils/getGroupStatus.d.ts +18 -2
  285. package/dist/utils/getGroupStatus.d.ts.map +1 -1
  286. package/dist/utils/getGroupStatus.js +32 -7
  287. package/dist/utils/getGroupStatus.js.map +1 -1
  288. package/dist/utils/record.d.ts +11 -0
  289. package/dist/utils/record.d.ts.map +1 -0
  290. package/dist/utils/record.js +12 -0
  291. package/dist/utils/record.js.map +1 -0
  292. package/dist/utils/wire-media.d.ts.map +1 -1
  293. package/dist/utils/wire-media.js +2 -2
  294. package/dist/utils/wire-media.js.map +1 -1
  295. package/package.json +11 -11
  296. package/src/adapters/attachment.test.ts +50 -1
  297. package/src/adapters/attachment.ts +7 -4
  298. package/src/adapters/speech.test.ts +236 -0
  299. package/src/adapters/speech.ts +17 -10
  300. package/src/adapters/thread-history.ts +3 -0
  301. package/src/index.ts +2 -0
  302. package/src/internal.ts +4 -0
  303. package/src/model-context/frame/host.test.ts +137 -1
  304. package/src/model-context/frame/host.ts +49 -16
  305. package/src/model-context/frame/provider.test.ts +71 -0
  306. package/src/model-context/frame/provider.ts +37 -7
  307. package/src/model-context/interactable-composer-metadata.test.ts +58 -0
  308. package/src/model-context/interactable-composer-metadata.ts +19 -13
  309. package/src/model-context/registry.test.ts +12 -0
  310. package/src/model-context/registry.ts +3 -2
  311. package/src/model-context/types.test.ts +25 -0
  312. package/src/model-context/types.ts +9 -4
  313. package/src/react/RuntimeAdapter.test.ts +34 -0
  314. package/src/react/adapters/LocalStorageThreadListAdapter.test.ts +244 -0
  315. package/src/react/adapters/LocalStorageThreadListAdapter.tsx +104 -7
  316. package/src/react/client/DataRenderers.test.tsx +45 -0
  317. package/src/react/client/DataRenderers.ts +13 -9
  318. package/src/react/client/InMemoryThreadList.ts +1 -0
  319. package/src/react/client/Interactables.test.ts +72 -1
  320. package/src/react/client/Interactables.ts +22 -14
  321. package/src/react/client/RemoteThreadList.background.test.ts +148 -6
  322. package/src/react/client/RemoteThreadList.concurrent.test.tsx +42 -1
  323. package/src/react/client/RemoteThreadList.test.ts +386 -4
  324. package/src/react/client/RemoteThreadList.ts +181 -112
  325. package/src/react/client/Tools.ts +22 -11
  326. package/src/react/client/interactable-model-context.test.ts +44 -0
  327. package/src/react/client/interactable-model-context.ts +3 -2
  328. package/src/react/index.ts +5 -1
  329. package/src/react/interactables-legacy/Interactables.ts +16 -16
  330. package/src/react/interactables-legacy/useAssistantInteractable.test.tsx +132 -0
  331. package/src/react/interactables-legacy/useAssistantInteractable.ts +10 -1
  332. package/src/react/interactables-shared/useInteractablePersistenceQueue.ts +9 -10
  333. package/src/react/model-context/makeAssistantTool.ts +2 -2
  334. package/src/react/model-context/useAssistantTool.ts +2 -2
  335. package/src/react/model-context/useInteractable.test.tsx +177 -0
  336. package/src/react/model-context/useInteractable.ts +3 -0
  337. package/src/react/model-context/useToolArgsStatus.test.tsx +30 -0
  338. package/src/react/model-context/useToolArgsStatus.ts +2 -1
  339. package/src/react/primitive-hooks/useActionBarCopy.test.ts +0 -1
  340. package/src/react/primitive-hooks/useSuggestionTrigger.test.ts +0 -1
  341. package/src/react/primitives/message/MessageGroupedParts.test.tsx +96 -0
  342. package/src/react/primitives/message/MessageGroupedParts.tsx +15 -4
  343. package/src/react/primitives/part/PartMessages.test.tsx +104 -1
  344. package/src/react/primitives/part/PartMessages.tsx +1 -0
  345. package/src/react/primitives/thread/ThreadMessages.test.tsx +142 -0
  346. package/src/react/primitives/thread/ThreadMessages.tsx +8 -5
  347. package/src/react/providers/ReadonlyThreadProvider.test.tsx +56 -0
  348. package/src/react/runtimes/RemoteThreadListHookInstanceManager.destroy.test.tsx +172 -0
  349. package/src/react/runtimes/RemoteThreadListHookInstanceManager.running.test.tsx +33 -0
  350. package/src/react/runtimes/RemoteThreadListHookInstanceManager.test.tsx +7 -1
  351. package/src/react/runtimes/RemoteThreadListHookInstanceManager.tsx +28 -5
  352. package/src/react/runtimes/RemoteThreadListThreadListRuntimeCore.load-error.test.ts +132 -0
  353. package/src/react/runtimes/RemoteThreadListThreadListRuntimeCore.switch-delete.test.ts +105 -0
  354. package/src/react/runtimes/RemoteThreadListThreadListRuntimeCore.tsx +143 -112
  355. package/src/react/runtimes/RemoteThreadResource.test.ts +9 -0
  356. package/src/react/runtimes/RemoteThreadResource.ts +19 -12
  357. package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.test.ts +20 -14
  358. package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.test.tsx +703 -6
  359. package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.ts +492 -402
  360. package/src/react/runtimes/cloud/CloudFileAttachmentAdapter.test.ts +77 -0
  361. package/src/react/runtimes/cloud/CloudFileAttachmentAdapter.ts +27 -1
  362. package/src/react/runtimes/cloud/auiV0.ts +160 -25
  363. package/src/react/runtimes/cloud/createCloudThreadListAdapter.test.ts +36 -0
  364. package/src/react/runtimes/cloud/createCloudThreadListAdapter.ts +8 -1
  365. package/src/react/runtimes/cloud/sdkIdentity.ts +9 -0
  366. package/src/react/runtimes/cloud/useCloudThreadListAdapter.test.tsx +18 -4
  367. package/src/react/runtimes/external-message-converter.test.ts +136 -1
  368. package/src/react/runtimes/external-message-converter.ts +39 -93
  369. package/src/react/runtimes/useExternalStoreRuntime.lifecycle.test.tsx +41 -0
  370. package/src/react/runtimes/useExternalStoreRuntime.ts +10 -4
  371. package/src/react/runtimes/useLocalRuntime.test.tsx +20 -0
  372. package/src/react/runtimes/useRemoteThreadListRuntime.load-error.test.tsx +108 -0
  373. package/src/react/runtimes/useRemoteThreadListRuntime.ts +34 -1
  374. package/src/react/utils/groupParts.ts +12 -1
  375. package/src/react/utils/useJSONEqual.ts +9 -0
  376. package/src/react/utils/useJSONSchemaDependency.ts +22 -0
  377. package/src/runtime/api/message-runtime.test.ts +75 -0
  378. package/src/runtime/api/thread-list-item-runtime.ts +10 -3
  379. package/src/runtime/api/thread-list-runtime.ts +21 -11
  380. package/src/runtime/api/thread-runtime.test.ts +136 -0
  381. package/src/runtime/api/thread-runtime.ts +10 -5
  382. package/src/runtime/base/base-composer-runtime-core.ts +105 -24
  383. package/src/runtime/base/base-thread-runtime-core.test.ts +1063 -2
  384. package/src/runtime/base/base-thread-runtime-core.ts +228 -87
  385. package/src/runtime/interfaces/composer-runtime-core.ts +10 -5
  386. package/src/runtime/interfaces/thread-list-runtime-core.ts +5 -1
  387. package/src/runtime/interfaces/thread-runtime-core.ts +6 -0
  388. package/src/runtime/queue/message-queue.ts +68 -6
  389. package/src/runtime/utils/auto-status.test.ts +112 -1
  390. package/src/runtime/utils/auto-status.ts +31 -5
  391. package/src/runtime/utils/external-message-conversion.test.ts +202 -0
  392. package/src/runtime/utils/external-message-conversion.ts +123 -32
  393. package/src/runtime/utils/message-repository.test.ts +49 -0
  394. package/src/runtime/utils/message-repository.ts +32 -20
  395. package/src/runtime/utils/thread-message-like.test.ts +52 -0
  396. package/src/runtime/utils/thread-message-like.ts +5 -1
  397. package/src/runtimes/external-store/external-store-thread-list-runtime-core.ts +18 -13
  398. package/src/runtimes/external-store/external-store-thread-runtime-core.ts +31 -1
  399. package/src/runtimes/internal.ts +1 -0
  400. package/src/runtimes/local/local-thread-runtime-core.test.ts +21 -0
  401. package/src/runtimes/local/local-thread-runtime-core.ts +11 -1
  402. package/src/runtimes/remote-thread-list/remote-thread-state.test.ts +128 -2
  403. package/src/runtimes/remote-thread-list/remote-thread-state.ts +182 -42
  404. package/src/runtimes/remote-thread-list/title-generation.test.ts +602 -0
  405. package/src/runtimes/remote-thread-list/title-generation.ts +329 -0
  406. package/src/runtimes/remote-thread-list/title.test.ts +62 -0
  407. package/src/runtimes/remote-thread-list/title.ts +13 -0
  408. package/src/runtimes/remote-thread-list/types.ts +10 -0
  409. package/src/runtimes/tool-invocations/EDGE_CASES.md +2 -6
  410. package/src/runtimes/tool-invocations/ToolInvocationTracker.test.ts +133 -0
  411. package/src/runtimes/tool-invocations/ToolInvocationTracker.ts +10 -6
  412. package/src/store/clients/external-thread.ts +67 -4
  413. package/src/store/clients/model-context-client.ts +5 -1
  414. package/src/store/clients/single-thread-list.ts +1 -0
  415. package/src/store/clients/suggestions.test.ts +40 -0
  416. package/src/store/clients/suggestions.ts +13 -10
  417. package/src/store/clients/thread-tasks.test.ts +274 -0
  418. package/src/store/clients/thread-tasks.ts +138 -0
  419. package/src/store/index.ts +8 -0
  420. package/src/store/primitive-predicates.test.ts +48 -5
  421. package/src/store/primitive-predicates.ts +7 -2
  422. package/src/store/runtime-clients/composer-runtime-client.ts +42 -9
  423. package/src/store/runtime-clients/message-runtime-client.ts +54 -6
  424. package/src/store/runtime-clients/thread-list-item-runtime-client.ts +4 -2
  425. package/src/store/runtime-clients/thread-list-runtime-client.ts +1 -0
  426. package/src/store/runtime-clients/thread-runtime-client.ts +89 -11
  427. package/src/store/scope-registration.ts +2 -0
  428. package/src/store/scopes/composer.ts +16 -4
  429. package/src/store/scopes/message.ts +14 -0
  430. package/src/store/scopes/task.ts +34 -0
  431. package/src/store/scopes/thread-list-item.ts +5 -2
  432. package/src/store/scopes/thread.ts +20 -0
  433. package/src/store/scopes/threads.ts +1 -0
  434. package/src/store/thread-tasks.test.tsx +209 -0
  435. package/src/subscribable/subscribable.test.ts +156 -1
  436. package/src/subscribable/subscribable.ts +25 -15
  437. package/src/tests/MessageRepository.test.ts +117 -5
  438. package/src/tests/OptimisticState-list-race.test.ts +1 -0
  439. package/src/tests/RemoteThreadListThreadListRuntimeCore-initialize-adapter-change.test.ts +38 -0
  440. package/src/tests/RemoteThreadListThreadListRuntimeCore-load-race.test.ts +47 -0
  441. package/src/tests/RemoteThreadListThreadListRuntimeCore-title-race.test.ts +89 -0
  442. package/src/tests/attachment-adapters.test.ts +14 -0
  443. package/src/tests/auiV0Encode.test.ts +300 -0
  444. package/src/tests/base-composer-runtime-core-send.test.ts +51 -0
  445. package/src/tests/base-composer-runtime-core.test.ts +353 -2
  446. package/src/tests/external-store-thread-list-runtime-core.test.ts +83 -0
  447. package/src/tests/external-store-thread-runtime-core-adapter.test.ts +178 -18
  448. package/src/tests/external-thread-attachments.test.tsx +208 -0
  449. package/src/tests/external-thread-parity.test.tsx +57 -0
  450. package/src/tests/groupParts.test.ts +71 -0
  451. package/src/tests/message-queue.test.ts +253 -0
  452. package/src/tests/remote-thread-list-isLoading.test.ts +1 -0
  453. package/src/tests/remote-thread-list-reactive-threadId.test.ts +51 -0
  454. package/src/tests/thread-list-runtime-getLoadThreadsPromise.test.ts +1 -0
  455. package/src/tests/thread-switch-events.test.tsx +78 -0
  456. package/src/tests/tools-scope-migration.test.tsx +28 -0
  457. package/src/tests/useRemoteThreadListRuntime-controlled.test.tsx +43 -0
  458. package/src/types/attachment.ts +4 -0
  459. package/src/types/index.ts +1 -0
  460. package/src/types/message.ts +8 -0
  461. package/src/utils/abortable-iterable.test.ts +328 -0
  462. package/src/utils/abortable-iterable.ts +104 -0
  463. package/src/utils/composite-context-provider.test.ts +25 -0
  464. package/src/utils/composite-context-provider.ts +23 -2
  465. package/src/utils/getGroupStatus.test.ts +70 -4
  466. package/src/utils/getGroupStatus.ts +35 -12
  467. package/src/utils/record.test.ts +48 -0
  468. package/src/utils/record.ts +11 -0
  469. package/src/utils/wire-media.test.ts +10 -0
  470. package/src/utils/wire-media.ts +6 -2
@@ -3,6 +3,14 @@ import type { AssistantCloud } from "assistant-cloud";
3
3
  import type { PendingAttachment } from "../../../types/attachment";
4
4
  import { CloudFileAttachmentAdapter } from "./CloudFileAttachmentAdapter";
5
5
 
6
+ const deferred = <T>() => {
7
+ let resolve!: (value: T) => void;
8
+ const promise = new Promise<T>((res) => {
9
+ resolve = res;
10
+ });
11
+ return { promise, resolve };
12
+ };
13
+
6
14
  const makeCloud = () =>
7
15
  ({
8
16
  files: {
@@ -124,4 +132,73 @@ describe("CloudFileAttachmentAdapter", () => {
124
132
  "Attachment not uploaded",
125
133
  );
126
134
  });
135
+
136
+ it("does not finish an upload removed while requesting its URL", async () => {
137
+ const presigned = deferred<{
138
+ signedUrl: string;
139
+ publicUrl: string;
140
+ }>();
141
+ const cloud = makeCloud();
142
+ vi.mocked(cloud.files.generatePresignedUploadUrl).mockReturnValue(
143
+ presigned.promise,
144
+ );
145
+ const fetchMock = vi.fn().mockResolvedValue({ ok: true });
146
+ vi.stubGlobal("fetch", fetchMock);
147
+ const adapter = new CloudFileAttachmentAdapter(cloud);
148
+ const generator = adapter.add({ file: makeFile() });
149
+
150
+ const running = await generator.next();
151
+ const completion = generator.next();
152
+ await vi.waitFor(() => {
153
+ expect(cloud.files.generatePresignedUploadUrl).toHaveBeenCalledOnce();
154
+ });
155
+
156
+ await adapter.remove(running.value!);
157
+ presigned.resolve({
158
+ signedUrl: "https://storage.example/upload",
159
+ publicUrl: "https://cdn.example/file.png",
160
+ });
161
+
162
+ await expect(completion).resolves.toEqual({ done: true, value: undefined });
163
+ expect(fetchMock).not.toHaveBeenCalled();
164
+ await expect(adapter.send(running.value!)).rejects.toThrow(
165
+ "Attachment not uploaded",
166
+ );
167
+ });
168
+
169
+ it("does not finish an upload removed during the file request", async () => {
170
+ const fetchMock = vi.fn((_url: string, init: RequestInit) => {
171
+ return new Promise((_resolve, reject) => {
172
+ init.signal!.addEventListener(
173
+ "abort",
174
+ () =>
175
+ reject(new DOMException("The operation was aborted", "AbortError")),
176
+ { once: true },
177
+ );
178
+ });
179
+ });
180
+ vi.stubGlobal("fetch", fetchMock);
181
+ const errorSpy = vi.spyOn(console, "error").mockImplementation(() => {});
182
+ const adapter = new CloudFileAttachmentAdapter(makeCloud());
183
+ const generator = adapter.add({ file: makeFile() });
184
+
185
+ const running = await generator.next();
186
+ const completion = generator.next();
187
+ await vi.waitFor(() => {
188
+ expect(fetchMock).toHaveBeenCalledOnce();
189
+ });
190
+
191
+ await adapter.remove(running.value!);
192
+ expect(fetchMock).toHaveBeenCalledWith(
193
+ "https://storage.example/upload",
194
+ expect.objectContaining({ signal: expect.any(AbortSignal) }),
195
+ );
196
+ expect(vi.mocked(fetchMock).mock.calls[0]?.[1]?.signal?.aborted).toBe(true);
197
+
198
+ await expect(completion).resolves.toEqual({ done: true, value: undefined });
199
+ expect(errorSpy).not.toHaveBeenCalled();
200
+ await expect(adapter.send(running.value!)).rejects.toThrow(
201
+ "Attachment not uploaded",
202
+ );
203
+ });
127
204
  });
@@ -28,6 +28,10 @@ export class CloudFileAttachmentAdapter implements AttachmentAdapter {
28
28
  }
29
29
 
30
30
  private uploadedUrls = new Map<string, string>();
31
+ private activeUploads = new Map<
32
+ string,
33
+ { cancelled: boolean; controller: AbortController }
34
+ >();
31
35
 
32
36
  public async *add({
33
37
  file,
@@ -44,13 +48,20 @@ export class CloudFileAttachmentAdapter implements AttachmentAdapter {
44
48
  file,
45
49
  status: { type: "running", reason: "uploading", progress: 0 },
46
50
  };
47
- yield attachment;
51
+ const controller = new AbortController();
52
+ const upload = { cancelled: false, controller };
53
+ this.activeUploads.set(id, upload);
48
54
 
49
55
  try {
56
+ yield attachment;
57
+ if (upload.cancelled) return;
58
+
50
59
  const { signedUrl, publicUrl } =
51
60
  await this.getCloud().files.generatePresignedUploadUrl({
52
61
  filename: file.name,
53
62
  });
63
+ if (upload.cancelled) return;
64
+
54
65
  const res = await fetch(signedUrl, {
55
66
  method: "PUT",
56
67
  body: file,
@@ -58,7 +69,10 @@ export class CloudFileAttachmentAdapter implements AttachmentAdapter {
58
69
  "Content-Type": file.type,
59
70
  },
60
71
  mode: "cors",
72
+ signal: controller.signal,
61
73
  });
74
+ if (upload.cancelled) return;
75
+
62
76
  if (!res.ok) {
63
77
  throw new Error(
64
78
  `Failed to upload file: ${res.status} ${res.statusText}`,
@@ -71,6 +85,8 @@ export class CloudFileAttachmentAdapter implements AttachmentAdapter {
71
85
  };
72
86
  yield attachment;
73
87
  } catch (error) {
88
+ if (upload.cancelled) return;
89
+
74
90
  console.error("[assistant-ui] Failed to upload attachment:", error);
75
91
  attachment = {
76
92
  ...attachment,
@@ -81,10 +97,20 @@ export class CloudFileAttachmentAdapter implements AttachmentAdapter {
81
97
  },
82
98
  };
83
99
  yield attachment;
100
+ } finally {
101
+ if (this.activeUploads.get(id) === upload) {
102
+ this.activeUploads.delete(id);
103
+ }
84
104
  }
85
105
  }
86
106
 
87
107
  public async remove(attachment: Attachment): Promise<void> {
108
+ const upload = this.activeUploads.get(attachment.id);
109
+ if (upload) {
110
+ upload.cancelled = true;
111
+ upload.controller.abort();
112
+ this.activeUploads.delete(attachment.id);
113
+ }
88
114
  this.uploadedUrls.delete(attachment.id);
89
115
  }
90
116
 
@@ -2,11 +2,17 @@ import type {
2
2
  MessageStatus,
3
3
  SourceProviderMetadata,
4
4
  ThreadMessage,
5
+ ToolCallMessagePartMcpMetadata,
6
+ ToolCallTiming,
5
7
  ToolApprovalDisplay,
6
8
  ToolApprovalOption,
9
+ ReasoningMessagePart,
7
10
  } from "../../../types/message";
8
11
  import type { CompleteAttachment } from "../../../types/attachment";
9
- import { fromThreadMessageLike } from "../../../runtime/utils/thread-message-like";
12
+ import {
13
+ fromThreadMessageLike,
14
+ type ThreadMessageLike,
15
+ } from "../../../runtime/utils/thread-message-like";
10
16
  import type { CloudMessage } from "assistant-cloud";
11
17
  import { isJSONValue } from "../../../utils/json/is-json";
12
18
  import type {
@@ -33,11 +39,16 @@ type AuiV0MessagePart =
33
39
  | {
34
40
  readonly type: "text";
35
41
  readonly text: string;
42
+ readonly parentId?: string;
36
43
  }
37
44
  | {
38
45
  readonly type: "reasoning";
39
46
  readonly text: string;
40
47
  readonly unstable_summary?: string;
48
+ readonly providerMetadata?: NonNullable<
49
+ ReasoningMessagePart["providerMetadata"]
50
+ >;
51
+ readonly parentId?: string;
41
52
  }
42
53
  | {
43
54
  readonly type: "source";
@@ -46,6 +57,7 @@ type AuiV0MessagePart =
46
57
  readonly url: string;
47
58
  readonly title?: string;
48
59
  readonly providerMetadata?: SourceProviderMetadata;
60
+ readonly parentId?: string;
49
61
  }
50
62
  | {
51
63
  readonly type: "source";
@@ -55,25 +67,10 @@ type AuiV0MessagePart =
55
67
  readonly mediaType: string;
56
68
  readonly filename?: string;
57
69
  readonly providerMetadata?: SourceProviderMetadata;
70
+ readonly parentId?: string;
58
71
  }
59
- | {
60
- readonly type: "tool-call";
61
- readonly toolCallId: string;
62
- readonly toolName: string;
63
- readonly args: ReadonlyJSONObject;
64
- readonly result?: ReadonlyJSONValue;
65
- readonly isError?: true;
66
- readonly approval?: AuiV0ToolApproval;
67
- }
68
- | {
69
- readonly type: "tool-call";
70
- readonly toolCallId: string;
71
- readonly toolName: string;
72
- readonly argsText: string;
73
- readonly result?: ReadonlyJSONValue;
74
- readonly isError?: true;
75
- readonly approval?: AuiV0ToolApproval;
76
- }
72
+ | (AuiV0ToolCallPart &
73
+ ({ readonly args: ReadonlyJSONObject } | { readonly argsText: string }))
77
74
  | {
78
75
  readonly type: "image";
79
76
  readonly image: string;
@@ -84,17 +81,49 @@ type AuiV0MessagePart =
84
81
  readonly mimeType: string;
85
82
  readonly filename?: string;
86
83
  readonly sourceType?: "url" | "id";
84
+ readonly parentId?: string;
87
85
  }
88
86
  | {
89
87
  readonly type: "data";
90
88
  readonly name: string;
91
89
  readonly data: ReadonlyJSONValue;
90
+ }
91
+ | {
92
+ readonly type: "audio";
93
+ readonly audio: {
94
+ readonly data: string;
95
+ readonly format: "mp3" | "wav";
96
+ };
97
+ }
98
+ | {
99
+ readonly type: "generative-ui";
100
+ readonly spec: ReadonlyJSONObject;
101
+ readonly id?: string;
102
+ readonly parentId?: string;
92
103
  };
93
104
 
105
+ type AuiV0ToolCallPart = {
106
+ readonly type: "tool-call";
107
+ readonly toolCallId: string;
108
+ readonly toolName: string;
109
+ readonly result?: ReadonlyJSONValue;
110
+ readonly isError?: true;
111
+ readonly interrupt?: {
112
+ readonly type: "human";
113
+ readonly payload: ReadonlyJSONValue;
114
+ };
115
+ readonly timing?: ToolCallTiming;
116
+ readonly mcp?: ToolCallMessagePartMcpMetadata;
117
+ readonly approval?: AuiV0ToolApproval;
118
+ readonly parentId?: string;
119
+ readonly messages?: readonly AuiV0Message[];
120
+ };
121
+
94
122
  type AuiV0AttachmentPart =
95
123
  | {
96
124
  readonly type: "text";
97
125
  readonly text: string;
126
+ readonly parentId?: string;
98
127
  }
99
128
  | {
100
129
  readonly type: "image";
@@ -107,6 +136,7 @@ type AuiV0AttachmentPart =
107
136
  readonly mimeType: string;
108
137
  readonly filename?: string;
109
138
  readonly sourceType?: "url" | "id";
139
+ readonly parentId?: string;
110
140
  }
111
141
  | {
112
142
  readonly type: "audio";
@@ -131,6 +161,8 @@ type AuiV0Attachment = {
131
161
  };
132
162
 
133
163
  type AuiV0Message = {
164
+ readonly id?: string;
165
+ readonly createdAt?: string;
134
166
  readonly role: "assistant" | "user" | "system";
135
167
  readonly status?: MessageStatus;
136
168
  readonly content: readonly AuiV0MessagePart[];
@@ -155,7 +187,13 @@ const encodeAttachmentPart = (
155
187
  const type = part.type;
156
188
  switch (type) {
157
189
  case "text":
158
- return { type: "text", text: part.text };
190
+ return {
191
+ type: "text",
192
+ text: part.text,
193
+ ...(part.parentId !== undefined
194
+ ? { parentId: part.parentId }
195
+ : undefined),
196
+ };
159
197
 
160
198
  case "image":
161
199
  return {
@@ -173,6 +211,9 @@ const encodeAttachmentPart = (
173
211
  ...(part.sourceType != null
174
212
  ? { sourceType: part.sourceType }
175
213
  : undefined),
214
+ ...(part.parentId !== undefined
215
+ ? { parentId: part.parentId }
216
+ : undefined),
176
217
  };
177
218
 
178
219
  case "audio":
@@ -234,7 +275,13 @@ export function auiV0Encode(message: ThreadMessage): AuiV0Message {
234
275
  const type = part.type;
235
276
  switch (type) {
236
277
  case "text":
237
- return { type: "text", text: part.text };
278
+ return {
279
+ type: "text",
280
+ text: part.text,
281
+ ...(part.parentId !== undefined
282
+ ? { parentId: part.parentId }
283
+ : undefined),
284
+ };
238
285
 
239
286
  case "reasoning":
240
287
  return {
@@ -243,6 +290,12 @@ export function auiV0Encode(message: ThreadMessage): AuiV0Message {
243
290
  ...(part.unstable_summary !== undefined
244
291
  ? { unstable_summary: part.unstable_summary }
245
292
  : undefined),
293
+ ...(part.providerMetadata !== undefined
294
+ ? { providerMetadata: part.providerMetadata }
295
+ : undefined),
296
+ ...(part.parentId !== undefined
297
+ ? { parentId: part.parentId }
298
+ : undefined),
246
299
  };
247
300
 
248
301
  case "source":
@@ -256,6 +309,9 @@ export function auiV0Encode(message: ThreadMessage): AuiV0Message {
256
309
  ...(part.providerMetadata != null
257
310
  ? { providerMetadata: part.providerMetadata }
258
311
  : undefined),
312
+ ...(part.parentId !== undefined
313
+ ? { parentId: part.parentId }
314
+ : undefined),
259
315
  };
260
316
  }
261
317
 
@@ -271,6 +327,9 @@ export function auiV0Encode(message: ThreadMessage): AuiV0Message {
271
327
  ...(part.providerMetadata != null
272
328
  ? { providerMetadata: part.providerMetadata }
273
329
  : undefined),
330
+ ...(part.parentId !== undefined
331
+ ? { parentId: part.parentId }
332
+ : undefined),
274
333
  };
275
334
 
276
335
  case "tool-call": {
@@ -290,7 +349,25 @@ export function auiV0Encode(message: ThreadMessage): AuiV0Message {
290
349
  ? { result: part.result as ReadonlyJSONValue }
291
350
  : undefined),
292
351
  ...(part.isError ? { isError: true } : undefined),
352
+ ...(part.interrupt !== undefined
353
+ ? {
354
+ interrupt: {
355
+ type: part.interrupt.type,
356
+ payload: part.interrupt.payload as ReadonlyJSONValue,
357
+ },
358
+ }
359
+ : undefined),
360
+ ...(part.timing !== undefined
361
+ ? { timing: part.timing }
362
+ : undefined),
363
+ ...(part.mcp !== undefined ? { mcp: part.mcp } : undefined),
293
364
  ...(part.approval ? { approval: part.approval } : undefined),
365
+ ...(part.parentId !== undefined
366
+ ? { parentId: part.parentId }
367
+ : undefined),
368
+ ...(part.messages !== undefined
369
+ ? { messages: part.messages.map(encodeNestedMessage) }
370
+ : undefined),
294
371
  };
295
372
  }
296
373
 
@@ -304,6 +381,9 @@ export function auiV0Encode(message: ThreadMessage): AuiV0Message {
304
381
  mimeType: part.mimeType,
305
382
  ...(part.filename ? { filename: part.filename } : undefined),
306
383
  ...(part.sourceType ? { sourceType: part.sourceType } : undefined),
384
+ ...(part.parentId !== undefined
385
+ ? { parentId: part.parentId }
386
+ : undefined),
307
387
  };
308
388
 
309
389
  case "data": {
@@ -317,8 +397,24 @@ export function auiV0Encode(message: ThreadMessage): AuiV0Message {
317
397
  };
318
398
  }
319
399
 
400
+ case "audio":
401
+ return {
402
+ type: "audio",
403
+ audio: { data: part.audio.data, format: part.audio.format },
404
+ };
405
+
406
+ case "generative-ui":
407
+ return {
408
+ type: "generative-ui",
409
+ spec: part.spec as unknown as ReadonlyJSONObject,
410
+ ...(part.id !== undefined ? { id: part.id } : undefined),
411
+ ...(part.parentId !== undefined
412
+ ? { parentId: part.parentId }
413
+ : undefined),
414
+ };
415
+
320
416
  default: {
321
- const unhandledType: "audio" | "generative-ui" = type;
417
+ const unhandledType: never = type;
322
418
  throw new Error(
323
419
  `Message part type not supported by aui/v0: ${unhandledType}`,
324
420
  );
@@ -335,14 +431,13 @@ export function auiV0Decode(
335
431
  cloudMessage: CloudMessage & { format: "aui/v0" },
336
432
  ): ExportedMessageRepositoryItem {
337
433
  const payload = cloudMessage.content as unknown as AuiV0Message;
338
- const message = fromThreadMessageLike(
434
+ const message = decodeAuiV0Message(
339
435
  {
436
+ ...payload,
340
437
  id: cloudMessage.id,
341
438
  createdAt: cloudMessage.created_at,
342
- ...payload,
343
439
  },
344
440
  cloudMessage.id,
345
- { type: "complete", reason: "unknown" },
346
441
  );
347
442
 
348
443
  return {
@@ -350,3 +445,43 @@ export function auiV0Decode(
350
445
  message,
351
446
  };
352
447
  }
448
+
449
+ const encodeNestedMessage = (message: ThreadMessage): AuiV0Message => ({
450
+ ...auiV0Encode(message),
451
+ id: message.id,
452
+ createdAt: message.createdAt.toISOString(),
453
+ });
454
+
455
+ const decodeAuiV0Message = (
456
+ payload: Omit<AuiV0Message, "createdAt"> & {
457
+ readonly createdAt?: Date | undefined;
458
+ },
459
+ fallbackId: string,
460
+ ): ThreadMessage =>
461
+ fromThreadMessageLike(
462
+ {
463
+ ...payload,
464
+ content: payload.content.map((part, index) => {
465
+ if (part.type !== "tool-call" || part.messages === undefined)
466
+ return part;
467
+ return {
468
+ ...part,
469
+ messages: part.messages.map((message, nestedIndex) =>
470
+ decodeAuiV0Message(
471
+ {
472
+ ...message,
473
+ createdAt:
474
+ message.createdAt !== undefined
475
+ ? new Date(message.createdAt)
476
+ : payload.createdAt,
477
+ },
478
+ message.id ??
479
+ `${fallbackId}-${part.toolCallId}-${index}-${nestedIndex}`,
480
+ ),
481
+ ),
482
+ };
483
+ }),
484
+ } as ThreadMessageLike,
485
+ fallbackId,
486
+ { type: "complete", reason: "unknown" },
487
+ );
@@ -4,6 +4,22 @@ import { describe, expect, it, vi } from "vitest";
4
4
  import { renderHook } from "@testing-library/react";
5
5
  import type { AssistantCloud } from "assistant-cloud";
6
6
  import { createCloudThreadListAdapter } from "./createCloudThreadListAdapter";
7
+ import { CORE_SDK } from "./sdkIdentity";
8
+
9
+ vi.mock("@assistant-ui/store", async (importOriginal) => ({
10
+ ...(await importOriginal<typeof import("@assistant-ui/store")>()),
11
+ useAui: () => ({
12
+ threads: {
13
+ getState: () => ({ mainThreadId: "local-1", threadItems: [] }),
14
+ },
15
+ thread: { getState: () => ({ isEmpty: true, suggestions: [] }) },
16
+ threadListItem: {
17
+ getState: () => ({ id: "local-1", remoteId: "remote-1" }),
18
+ },
19
+ on: () => () => {},
20
+ subscribe: () => () => {},
21
+ }),
22
+ }));
7
23
 
8
24
  const makeCloud = () =>
9
25
  ({
@@ -15,6 +31,7 @@ const makeCloud = () =>
15
31
  get: vi.fn(),
16
32
  },
17
33
  runs: { stream: vi.fn(async () => new ReadableStream()) },
34
+ registerSdk: vi.fn(),
18
35
  }) as unknown as AssistantCloud;
19
36
 
20
37
  describe("createCloudThreadListAdapter", () => {
@@ -68,6 +85,25 @@ describe("createCloudThreadListAdapter", () => {
68
85
  expect(adapter.unstable_Provider).toBeUndefined();
69
86
  });
70
87
 
88
+ it("registers core and the calling integration identities", () => {
89
+ const cloud = makeCloud();
90
+ const sdk = { name: "@assistant-ui/ai-sdk", version: "0.0.5" };
91
+
92
+ createCloudThreadListAdapter({ cloud, sdk });
93
+
94
+ expect(cloud.registerSdk).toHaveBeenNthCalledWith(1, CORE_SDK);
95
+ expect(cloud.registerSdk).toHaveBeenNthCalledWith(2, sdk);
96
+ });
97
+
98
+ it("registers only core without a calling integration identity", () => {
99
+ const cloud = makeCloud();
100
+
101
+ createCloudThreadListAdapter({ cloud });
102
+
103
+ expect(cloud.registerSdk).toHaveBeenCalledOnce();
104
+ expect(cloud.registerSdk).toHaveBeenCalledWith(CORE_SDK);
105
+ });
106
+
71
107
  it("constructs stable history and attachment adapters when the hook runs", () => {
72
108
  const cloud = makeCloud();
73
109
  const adapter = createCloudThreadListAdapter({ cloud });
@@ -1,7 +1,7 @@
1
1
  declare const process: { env: Record<string, string | undefined> };
2
2
 
3
3
  import { type RefObject, useMemo, useState } from "react";
4
- import { AssistantCloud } from "assistant-cloud";
4
+ import { AssistantCloud, type SdkIdentity } from "assistant-cloud";
5
5
  import type {
6
6
  RemoteThreadListAdapter,
7
7
  RuntimeAdapters,
@@ -10,6 +10,7 @@ import { InMemoryThreadListAdapter } from "../../../runtimes/remote-thread-list/
10
10
  import { useAssistantCloudThreadHistoryAdapter } from "./AssistantCloudThreadHistoryAdapter";
11
11
  import { CloudFileAttachmentAdapter } from "./CloudFileAttachmentAdapter";
12
12
  import { isRecord } from "../../../utils/json/is-json";
13
+ import { CORE_SDK } from "./sdkIdentity";
13
14
 
14
15
  type ThreadData = {
15
16
  externalId: string | undefined;
@@ -17,6 +18,7 @@ type ThreadData = {
17
18
 
18
19
  export type CloudThreadListAdapterOptions = {
19
20
  cloud?: AssistantCloud | undefined;
21
+ sdk?: SdkIdentity | undefined;
20
22
 
21
23
  create?: (() => Promise<ThreadData>) | undefined;
22
24
  delete?: ((threadId: string) => Promise<void>) | undefined;
@@ -43,6 +45,7 @@ export const useCloudRuntimeAdapters = (
43
45
  () => ({
44
46
  history,
45
47
  attachments,
48
+ feedback: history.feedback,
46
49
  }),
47
50
  [history, attachments],
48
51
  );
@@ -115,6 +118,10 @@ export const createCloudThreadListAdapter = (
115
118
  return inMemory;
116
119
  }
117
120
 
121
+ cloud.registerSdk?.(CORE_SDK);
122
+ const sdk = getOptions().sdk;
123
+ if (sdk) cloud.registerSdk?.(sdk);
124
+
118
125
  return {
119
126
  list: async ({ after } = {}) => {
120
127
  const {
@@ -0,0 +1,9 @@
1
+ import type { SdkIdentity } from "assistant-cloud";
2
+
3
+ export const CORE_SDK: SdkIdentity = {
4
+ name: "@assistant-ui/core",
5
+ version:
6
+ typeof __AUI_PACKAGE_VERSION__ === "string"
7
+ ? __AUI_PACKAGE_VERSION__
8
+ : "0.0.0",
9
+ };
@@ -36,9 +36,11 @@ describe("useCloudThreadListAdapter", () => {
36
36
  const cloudDeleteA = vi.fn(async () => {});
37
37
  const cloudDeleteB = vi.fn(async () => {});
38
38
  const cloudA = {
39
+ registerSdk: vi.fn(),
39
40
  threads: { delete: cloudDeleteA },
40
41
  } as unknown as AssistantCloud;
41
42
  const cloudB = {
43
+ registerSdk: vi.fn(),
42
44
  threads: { delete: cloudDeleteB },
43
45
  } as unknown as AssistantCloud;
44
46
  const committed: { current: RemoteThreadListAdapter | null } = {
@@ -117,7 +119,10 @@ describe("useCloudThreadListAdapter", () => {
117
119
  .fn()
118
120
  .mockResolvedValueOnce({ threads: activeThreads })
119
121
  .mockResolvedValueOnce({ threads: archivedThreads });
120
- const cloud = { threads: { list } } as unknown as AssistantCloud;
122
+ const cloud = {
123
+ registerSdk: vi.fn(),
124
+ threads: { list },
125
+ } as unknown as AssistantCloud;
121
126
  const { result } = renderHook(() => useCloudThreadListAdapter({ cloud }));
122
127
 
123
128
  const page = await result.current.list();
@@ -149,7 +154,10 @@ describe("useCloudThreadListAdapter", () => {
149
154
  .mockResolvedValueOnce({ threads: firstPage })
150
155
  .mockResolvedValueOnce({ threads: [] })
151
156
  .mockResolvedValueOnce({ threads: secondPage });
152
- const cloud = { threads: { list } } as unknown as AssistantCloud;
157
+ const cloud = {
158
+ registerSdk: vi.fn(),
159
+ threads: { list },
160
+ } as unknown as AssistantCloud;
153
161
  const { result } = renderHook(() => useCloudThreadListAdapter({ cloud }));
154
162
 
155
163
  const first = await result.current.list();
@@ -186,7 +194,10 @@ describe("useCloudThreadListAdapter", () => {
186
194
  .mockResolvedValueOnce({ threads: archivedPage1 })
187
195
  .mockResolvedValueOnce({ threads: activePage2 })
188
196
  .mockResolvedValueOnce({ threads: archivedPage2 });
189
- const cloud = { threads: { list } } as unknown as AssistantCloud;
197
+ const cloud = {
198
+ registerSdk: vi.fn(),
199
+ threads: { list },
200
+ } as unknown as AssistantCloud;
190
201
  const { result } = renderHook(() => useCloudThreadListAdapter({ cloud }));
191
202
 
192
203
  const page1 = await result.current.list();
@@ -213,7 +224,10 @@ describe("useCloudThreadListAdapter", () => {
213
224
  .fn()
214
225
  .mockResolvedValueOnce({ threads: activeThreads })
215
226
  .mockResolvedValueOnce({ threads: [] });
216
- const cloud = { threads: { list } } as unknown as AssistantCloud;
227
+ const cloud = {
228
+ registerSdk: vi.fn(),
229
+ threads: { list },
230
+ } as unknown as AssistantCloud;
217
231
  const { result } = renderHook(() => useCloudThreadListAdapter({ cloud }));
218
232
 
219
233
  const page = await result.current.list({ after: "thread-20" });