@assistant-ui/core 0.3.14 → 0.3.16

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 (341) hide show
  1. package/dist/adapters/voice.js +11 -0
  2. package/dist/adapters/voice.js.map +1 -1
  3. package/dist/index.js +1 -1
  4. package/dist/internal.d.ts +8 -2
  5. package/dist/internal.js +9 -3
  6. package/dist/model-context/frame/host.d.ts +1 -1
  7. package/dist/model-context/frame/host.d.ts.map +1 -1
  8. package/dist/model-context/frame/host.js +20 -5
  9. package/dist/model-context/frame/host.js.map +1 -1
  10. package/dist/model-context/frame/provider.d.ts +6 -0
  11. package/dist/model-context/frame/provider.d.ts.map +1 -1
  12. package/dist/model-context/frame/provider.js +126 -16
  13. package/dist/model-context/frame/provider.js.map +1 -1
  14. package/dist/model-context/frame/types.d.ts +4 -1
  15. package/dist/model-context/frame/types.d.ts.map +1 -1
  16. package/dist/model-context/frame/types.js.map +1 -1
  17. package/dist/model-context/interactable-composer-metadata.d.ts +1 -1
  18. package/dist/model-context/interactable-composer-metadata.js +1 -1
  19. package/dist/model-context/interactable-composer-metadata.js.map +1 -1
  20. package/dist/model-context/registry.d.ts +2 -2
  21. package/dist/model-context/registry.d.ts.map +1 -1
  22. package/dist/model-context/registry.js +9 -28
  23. package/dist/model-context/registry.js.map +1 -1
  24. package/dist/react/client/InMemoryThreadList.d.ts.map +1 -1
  25. package/dist/react/client/InMemoryThreadList.js +24 -20
  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 +59 -177
  29. package/dist/react/client/Interactables.js.map +1 -1
  30. package/dist/react/client/RemoteThreadList.d.ts +1 -1
  31. package/dist/react/client/RemoteThreadList.d.ts.map +1 -1
  32. package/dist/react/client/RemoteThreadList.js +117 -78
  33. package/dist/react/client/RemoteThreadList.js.map +1 -1
  34. package/dist/react/index.d.ts +2 -1
  35. package/dist/react/interactables-legacy/Interactables.d.ts.map +1 -1
  36. package/dist/react/interactables-legacy/Interactables.js +56 -174
  37. package/dist/react/interactables-legacy/Interactables.js.map +1 -1
  38. package/dist/react/interactables-shared/useInteractablePersistenceQueue.d.ts +24 -0
  39. package/dist/react/interactables-shared/useInteractablePersistenceQueue.d.ts.map +1 -0
  40. package/dist/react/interactables-shared/useInteractablePersistenceQueue.js +138 -0
  41. package/dist/react/interactables-shared/useInteractablePersistenceQueue.js.map +1 -0
  42. package/dist/react/primitive-hooks/useActionBarCopy.js +7 -1
  43. package/dist/react/primitive-hooks/useActionBarCopy.js.map +1 -1
  44. package/dist/react/primitive-hooks/useThreadIsEmpty.d.ts +3 -0
  45. package/dist/react/primitive-hooks/useThreadIsEmpty.d.ts.map +1 -1
  46. package/dist/react/primitive-hooks/useThreadIsEmpty.js +3 -0
  47. package/dist/react/primitive-hooks/useThreadIsEmpty.js.map +1 -1
  48. package/dist/react/primitive-hooks/useThreadIsRunning.d.ts +3 -0
  49. package/dist/react/primitive-hooks/useThreadIsRunning.d.ts.map +1 -1
  50. package/dist/react/primitive-hooks/useThreadIsRunning.js +3 -0
  51. package/dist/react/primitive-hooks/useThreadIsRunning.js.map +1 -1
  52. package/dist/react/primitives/composer/ComposerIf.js.map +1 -1
  53. package/dist/react/primitives/composer/ComposerQueue.d.ts +2 -1
  54. package/dist/react/primitives/composer/ComposerQueue.d.ts.map +1 -1
  55. package/dist/react/primitives/message/MessageParts.js.map +1 -1
  56. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.d.ts +3 -1
  57. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.d.ts.map +1 -1
  58. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js +6 -0
  59. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js.map +1 -1
  60. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts +7 -1
  61. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts.map +1 -1
  62. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js +174 -64
  63. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js.map +1 -1
  64. package/dist/react/runtimes/RemoteThreadResource.d.ts.map +1 -1
  65. package/dist/react/runtimes/RemoteThreadResource.js +2 -0
  66. package/dist/react/runtimes/RemoteThreadResource.js.map +1 -1
  67. package/dist/react/runtimes/assistant-transport/runManager.d.ts.map +1 -1
  68. package/dist/react/runtimes/assistant-transport/runManager.js +2 -12
  69. package/dist/react/runtimes/assistant-transport/runManager.js.map +1 -1
  70. package/dist/react/runtimes/assistant-transport/useAssistantTransportRuntime.d.ts.map +1 -1
  71. package/dist/react/runtimes/assistant-transport/useAssistantTransportRuntime.js +1 -1
  72. package/dist/react/runtimes/assistant-transport/useAssistantTransportRuntime.js.map +1 -1
  73. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.d.ts +3 -10
  74. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.d.ts.map +1 -1
  75. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.js +20 -67
  76. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.js.map +1 -1
  77. package/dist/react/runtimes/cloud/createCloudThreadListAdapterCreateFallback.d.ts +12 -0
  78. package/dist/react/runtimes/cloud/createCloudThreadListAdapterCreateFallback.d.ts.map +1 -0
  79. package/dist/react/runtimes/cloud/createCloudThreadListAdapterCreateFallback.js +10 -0
  80. package/dist/react/runtimes/cloud/createCloudThreadListAdapterCreateFallback.js.map +1 -0
  81. package/dist/react/runtimes/cloud/useCloudThreadListAdapter.d.ts.map +1 -1
  82. package/dist/react/runtimes/cloud/useCloudThreadListAdapter.js +38 -5
  83. package/dist/react/runtimes/cloud/useCloudThreadListAdapter.js.map +1 -1
  84. package/dist/react/runtimes/cloud/useCloudThreadListRuntime.js.map +1 -1
  85. package/dist/react/runtimes/createMessageConverter.d.ts +2 -1
  86. package/dist/react/runtimes/createMessageConverter.d.ts.map +1 -1
  87. package/dist/react/runtimes/external-message-converter.d.ts +6 -25
  88. package/dist/react/runtimes/external-message-converter.d.ts.map +1 -1
  89. package/dist/react/runtimes/external-message-converter.js +33 -233
  90. package/dist/react/runtimes/external-message-converter.js.map +1 -1
  91. package/dist/runtime/api/composer-runtime.d.ts +1 -1
  92. package/dist/runtime/api/composer-runtime.js.map +1 -1
  93. package/dist/runtime/api/thread-runtime.d.ts +1 -2
  94. package/dist/runtime/api/thread-runtime.d.ts.map +1 -1
  95. package/dist/runtime/base/base-composer-runtime-core.d.ts +1 -1
  96. package/dist/runtime/base/base-composer-runtime-core.d.ts.map +1 -1
  97. package/dist/runtime/base/base-composer-runtime-core.js +14 -29
  98. package/dist/runtime/base/base-composer-runtime-core.js.map +1 -1
  99. package/dist/runtime/base/base-thread-runtime-core.d.ts +2 -4
  100. package/dist/runtime/base/base-thread-runtime-core.d.ts.map +1 -1
  101. package/dist/runtime/base/base-thread-runtime-core.js +3 -9
  102. package/dist/runtime/base/base-thread-runtime-core.js.map +1 -1
  103. package/dist/runtime/base/default-thread-composer-runtime-core.d.ts +1 -1
  104. package/dist/runtime/base/default-thread-composer-runtime-core.d.ts.map +1 -1
  105. package/dist/runtime/base/default-thread-composer-runtime-core.js +1 -1
  106. package/dist/runtime/base/default-thread-composer-runtime-core.js.map +1 -1
  107. package/dist/runtime/interfaces/composer-runtime-core.d.ts +1 -1
  108. package/dist/runtime/interfaces/thread-runtime-core.d.ts +1 -1
  109. package/dist/runtime/internal.d.ts +2 -1
  110. package/dist/runtime/internal.js +2 -1
  111. package/dist/runtime/queue/external-thread-queue-adapter.d.ts +1 -1
  112. package/dist/runtime/queue/message-queue.d.ts.map +1 -1
  113. package/dist/runtime/queue/message-queue.js +1 -1
  114. package/dist/runtime/queue/message-queue.js.map +1 -1
  115. package/dist/runtime/queue/queue-item.d.ts +12 -0
  116. package/dist/runtime/queue/queue-item.d.ts.map +1 -0
  117. package/dist/runtime/queue/queue-item.js +6 -0
  118. package/dist/runtime/queue/queue-item.js.map +1 -0
  119. package/dist/runtime/utils/abortable-thread-load.d.ts +15 -0
  120. package/dist/runtime/utils/abortable-thread-load.d.ts.map +1 -0
  121. package/dist/runtime/utils/abortable-thread-load.js +35 -0
  122. package/dist/runtime/utils/abortable-thread-load.js.map +1 -0
  123. package/dist/runtime/utils/attachment-add-operations.d.ts +18 -0
  124. package/dist/runtime/utils/attachment-add-operations.d.ts.map +1 -0
  125. package/dist/runtime/utils/attachment-add-operations.js +43 -0
  126. package/dist/runtime/utils/attachment-add-operations.js.map +1 -0
  127. package/dist/runtime/utils/auto-status.d.ts +6 -1
  128. package/dist/runtime/utils/auto-status.d.ts.map +1 -1
  129. package/dist/runtime/utils/auto-status.js +7 -1
  130. package/dist/runtime/utils/auto-status.js.map +1 -1
  131. package/dist/runtime/utils/external-message-conversion.d.ts +47 -0
  132. package/dist/runtime/utils/external-message-conversion.d.ts.map +1 -0
  133. package/dist/runtime/utils/external-message-conversion.js +221 -0
  134. package/dist/runtime/utils/external-message-conversion.js.map +1 -0
  135. package/dist/runtime/utils/external-store-message.d.ts +2 -1
  136. package/dist/runtime/utils/external-store-message.d.ts.map +1 -1
  137. package/dist/runtime/utils/external-store-message.js +2 -1
  138. package/dist/runtime/utils/external-store-message.js.map +1 -1
  139. package/dist/runtime/utils/message-repository-session.d.ts +30 -0
  140. package/dist/runtime/utils/message-repository-session.d.ts.map +1 -0
  141. package/dist/runtime/utils/message-repository-session.js +130 -0
  142. package/dist/runtime/utils/message-repository-session.js.map +1 -0
  143. package/dist/runtime/utils/message-repository.d.ts.map +1 -1
  144. package/dist/runtime/utils/message-repository.js +30 -22
  145. package/dist/runtime/utils/message-repository.js.map +1 -1
  146. package/dist/runtime/utils/pending-tool-calls.d.ts +20 -0
  147. package/dist/runtime/utils/pending-tool-calls.d.ts.map +1 -0
  148. package/dist/runtime/utils/pending-tool-calls.js +22 -0
  149. package/dist/runtime/utils/pending-tool-calls.js.map +1 -0
  150. package/dist/runtime/utils/thread-message-like.d.ts +2 -1
  151. package/dist/runtime/utils/thread-message-like.d.ts.map +1 -1
  152. package/dist/runtime/utils/thread-message-like.js.map +1 -1
  153. package/dist/runtimes/external-store/external-store-thread-list-runtime-core.d.ts +2 -5
  154. package/dist/runtimes/external-store/external-store-thread-list-runtime-core.d.ts.map +1 -1
  155. package/dist/runtimes/external-store/external-store-thread-list-runtime-core.js +3 -10
  156. package/dist/runtimes/external-store/external-store-thread-list-runtime-core.js.map +1 -1
  157. package/dist/runtimes/external-store/external-store-thread-runtime-core.d.ts +19 -1
  158. package/dist/runtimes/external-store/external-store-thread-runtime-core.d.ts.map +1 -1
  159. package/dist/runtimes/external-store/external-store-thread-runtime-core.js +124 -20
  160. package/dist/runtimes/external-store/external-store-thread-runtime-core.js.map +1 -1
  161. package/dist/runtimes/inert/InertThreadRuntimeCore.d.ts +102 -0
  162. package/dist/runtimes/inert/InertThreadRuntimeCore.d.ts.map +1 -0
  163. package/dist/runtimes/inert/InertThreadRuntimeCore.js +156 -0
  164. package/dist/runtimes/inert/InertThreadRuntimeCore.js.map +1 -0
  165. package/dist/runtimes/local/local-thread-runtime-core.d.ts +3 -1
  166. package/dist/runtimes/local/local-thread-runtime-core.d.ts.map +1 -1
  167. package/dist/runtimes/local/local-thread-runtime-core.js +45 -8
  168. package/dist/runtimes/local/local-thread-runtime-core.js.map +1 -1
  169. package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.d.ts +12 -60
  170. package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.d.ts.map +1 -1
  171. package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.js +10 -145
  172. package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.js.map +1 -1
  173. package/dist/runtimes/remote-thread-list/adapter-changed.d.ts +9 -0
  174. package/dist/runtimes/remote-thread-list/adapter-changed.d.ts.map +1 -0
  175. package/dist/runtimes/remote-thread-list/adapter-changed.js +13 -0
  176. package/dist/runtimes/remote-thread-list/adapter-changed.js.map +1 -0
  177. package/dist/runtimes/remote-thread-list/empty-thread-core.d.ts.map +1 -1
  178. package/dist/runtimes/remote-thread-list/empty-thread-core.js +16 -155
  179. package/dist/runtimes/remote-thread-list/empty-thread-core.js.map +1 -1
  180. package/dist/runtimes/remote-thread-list/optimistic-state.d.ts +2 -0
  181. package/dist/runtimes/remote-thread-list/optimistic-state.d.ts.map +1 -1
  182. package/dist/runtimes/remote-thread-list/optimistic-state.js +11 -0
  183. package/dist/runtimes/remote-thread-list/optimistic-state.js.map +1 -1
  184. package/dist/runtimes/remote-thread-list/remote-thread-state.d.ts +12 -1
  185. package/dist/runtimes/remote-thread-list/remote-thread-state.d.ts.map +1 -1
  186. package/dist/runtimes/remote-thread-list/remote-thread-state.js +77 -1
  187. package/dist/runtimes/remote-thread-list/remote-thread-state.js.map +1 -1
  188. package/dist/runtimes/remote-thread-list/types.d.ts +3 -0
  189. package/dist/runtimes/remote-thread-list/types.d.ts.map +1 -1
  190. package/dist/runtimes/tool-invocations/ToolInvocationTracker.d.ts.map +1 -1
  191. package/dist/runtimes/tool-invocations/ToolInvocationTracker.js +2 -0
  192. package/dist/runtimes/tool-invocations/ToolInvocationTracker.js.map +1 -1
  193. package/dist/store/clients/external-thread.d.ts.map +1 -1
  194. package/dist/store/clients/external-thread.js +75 -100
  195. package/dist/store/clients/external-thread.js.map +1 -1
  196. package/dist/store/clients/single-thread-list.d.ts.map +1 -1
  197. package/dist/store/clients/single-thread-list.js +1 -1
  198. package/dist/store/clients/single-thread-list.js.map +1 -1
  199. package/dist/store/clients/suggestions.d.ts.map +1 -1
  200. package/dist/store/clients/suggestions.js +16 -7
  201. package/dist/store/clients/suggestions.js.map +1 -1
  202. package/dist/store/index.d.ts +4 -2
  203. package/dist/store/runtime-clients/handle-runtime-action.d.ts.map +1 -1
  204. package/dist/store/runtime-clients/handle-runtime-action.js +2 -0
  205. package/dist/store/runtime-clients/handle-runtime-action.js.map +1 -1
  206. package/dist/store/scope-registration.d.ts +1 -1
  207. package/dist/store/scopes/composer.d.ts +2 -1
  208. package/dist/store/scopes/composer.d.ts.map +1 -1
  209. package/dist/store/scopes/message.d.ts +1 -1
  210. package/dist/store/scopes/queue-item.d.ts +2 -9
  211. package/dist/store/scopes/queue-item.d.ts.map +1 -1
  212. package/dist/store/scopes/queue-item.js +0 -6
  213. package/dist/types/message.d.ts +8 -4
  214. package/dist/types/message.d.ts.map +1 -1
  215. package/dist/types/message.js.map +1 -1
  216. package/dist/utils/data-url.d.ts +14 -1
  217. package/dist/utils/data-url.d.ts.map +1 -1
  218. package/dist/utils/data-url.js +13 -1
  219. package/dist/utils/data-url.js.map +1 -1
  220. package/dist/utils/invoke-user-callback.d.ts +5 -0
  221. package/dist/utils/invoke-user-callback.d.ts.map +1 -0
  222. package/dist/utils/invoke-user-callback.js +19 -0
  223. package/dist/utils/invoke-user-callback.js.map +1 -0
  224. package/dist/utils/normalizePartStatus.js.map +1 -1
  225. package/dist/utils/silent-runtime-action.d.ts +6 -0
  226. package/dist/utils/silent-runtime-action.d.ts.map +1 -0
  227. package/dist/utils/silent-runtime-action.js +7 -0
  228. package/dist/utils/silent-runtime-action.js.map +1 -0
  229. package/package.json +10 -10
  230. package/src/adapters/voice.test.ts +66 -1
  231. package/src/adapters/voice.ts +8 -0
  232. package/src/internal.ts +13 -0
  233. package/src/model-context/frame/host.test.ts +152 -9
  234. package/src/model-context/frame/host.ts +23 -5
  235. package/src/model-context/frame/provider.test.ts +601 -19
  236. package/src/model-context/frame/provider.ts +158 -20
  237. package/src/model-context/frame/types.ts +5 -0
  238. package/src/model-context/interactable-composer-metadata.ts +1 -1
  239. package/src/model-context/registry.test.ts +44 -0
  240. package/src/model-context/registry.ts +13 -35
  241. package/src/react/client/InMemoryThreadList.test.tsx +49 -0
  242. package/src/react/client/InMemoryThreadList.ts +7 -1
  243. package/src/react/client/Interactables.ts +19 -178
  244. package/src/react/client/RemoteThreadList.test.ts +292 -0
  245. package/src/react/client/RemoteThreadList.ts +119 -82
  246. package/src/react/interactables-legacy/Interactables.ts +20 -177
  247. package/src/react/interactables-shared/useInteractablePersistenceQueue.test.tsx +161 -0
  248. package/src/react/interactables-shared/useInteractablePersistenceQueue.ts +206 -0
  249. package/src/react/primitive-hooks/useActionBarCopy.test.ts +15 -0
  250. package/src/react/primitive-hooks/useActionBarCopy.ts +13 -3
  251. package/src/react/primitive-hooks/useThreadIsEmpty.ts +3 -0
  252. package/src/react/primitive-hooks/useThreadIsRunning.ts +3 -0
  253. package/src/react/runtimes/RemoteThreadListHookInstanceManager.tsx +12 -0
  254. package/src/react/runtimes/RemoteThreadListThreadListRuntimeCore.republish.test.ts +87 -0
  255. package/src/react/runtimes/RemoteThreadListThreadListRuntimeCore.tsx +251 -76
  256. package/src/react/runtimes/RemoteThreadResource.ts +2 -0
  257. package/src/react/runtimes/assistant-transport/runManager.ts +4 -17
  258. package/src/react/runtimes/assistant-transport/useAssistantTransportRuntime.test.tsx +58 -0
  259. package/src/react/runtimes/assistant-transport/useAssistantTransportRuntime.ts +3 -1
  260. package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.test.tsx +92 -0
  261. package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.ts +40 -141
  262. package/src/react/runtimes/cloud/createCloudThreadListAdapterCreateFallback.test.ts +37 -0
  263. package/src/react/runtimes/cloud/createCloudThreadListAdapterCreateFallback.ts +18 -0
  264. package/src/react/runtimes/cloud/useCloudThreadListAdapter.test.tsx +98 -3
  265. package/src/react/runtimes/cloud/useCloudThreadListAdapter.tsx +68 -6
  266. package/src/react/runtimes/external-message-converter.test.ts +0 -14
  267. package/src/react/runtimes/external-message-converter.test.tsx +77 -0
  268. package/src/react/runtimes/external-message-converter.ts +58 -481
  269. package/src/react/runtimes/useLocalRuntime.test.tsx +5 -5
  270. package/src/runtime/api/composer-runtime.ts +1 -1
  271. package/src/runtime/api/message-runtime.test.ts +28 -1
  272. package/src/runtime/base/base-composer-runtime-core.ts +20 -40
  273. package/src/runtime/base/base-thread-runtime-core.test.ts +16 -0
  274. package/src/runtime/base/base-thread-runtime-core.ts +6 -11
  275. package/src/runtime/base/default-thread-composer-runtime-core.ts +1 -4
  276. package/src/runtime/interfaces/composer-runtime-core.ts +1 -1
  277. package/src/runtime/interfaces/thread-runtime-core.ts +1 -1
  278. package/src/runtime/internal.ts +5 -0
  279. package/src/runtime/queue/external-thread-queue-adapter.ts +1 -1
  280. package/src/runtime/queue/message-queue.ts +1 -4
  281. package/src/runtime/queue/queue-item.ts +10 -0
  282. package/src/runtime/utils/abortable-thread-load.test.ts +87 -0
  283. package/src/runtime/utils/abortable-thread-load.ts +53 -0
  284. package/src/runtime/utils/attachment-add-operations.ts +59 -0
  285. package/src/runtime/utils/auto-status.ts +33 -0
  286. package/src/runtime/utils/external-message-conversion.test.ts +113 -0
  287. package/src/runtime/utils/external-message-conversion.ts +494 -0
  288. package/src/runtime/utils/external-store-message.ts +2 -0
  289. package/src/runtime/utils/message-repository-session.test.ts +195 -0
  290. package/src/runtime/utils/message-repository-session.ts +176 -0
  291. package/src/runtime/utils/message-repository.ts +33 -22
  292. package/src/runtime/utils/pending-tool-calls.test.ts +57 -0
  293. package/src/runtime/utils/pending-tool-calls.ts +35 -0
  294. package/src/runtime/utils/thread-message-like.ts +2 -0
  295. package/src/runtimes/external-store/external-store-thread-list-runtime-core.ts +6 -14
  296. package/src/runtimes/external-store/external-store-thread-runtime-core.ts +179 -28
  297. package/src/runtimes/inert/InertThreadRuntimeCore.test.ts +253 -0
  298. package/src/runtimes/inert/InertThreadRuntimeCore.ts +232 -0
  299. package/src/runtimes/local/local-thread-runtime-core.test.ts +491 -1
  300. package/src/runtimes/local/local-thread-runtime-core.ts +86 -11
  301. package/src/runtimes/readonly/ReadonlyThreadRuntimeCore.ts +17 -209
  302. package/src/runtimes/remote-thread-list/adapter-changed.ts +10 -0
  303. package/src/runtimes/remote-thread-list/empty-thread-core.ts +28 -221
  304. package/src/runtimes/remote-thread-list/optimistic-state.test.ts +18 -0
  305. package/src/runtimes/remote-thread-list/optimistic-state.ts +13 -0
  306. package/src/runtimes/remote-thread-list/remote-thread-state.test.ts +37 -0
  307. package/src/runtimes/remote-thread-list/remote-thread-state.ts +123 -0
  308. package/src/runtimes/remote-thread-list/types.ts +4 -0
  309. package/src/runtimes/tool-invocations/EDGE_CASES.md +17 -0
  310. package/src/runtimes/tool-invocations/ToolInvocationTracker.test.ts +140 -0
  311. package/src/runtimes/tool-invocations/ToolInvocationTracker.ts +3 -0
  312. package/src/store/clients/external-thread.ts +17 -62
  313. package/src/store/clients/single-thread-list.ts +4 -1
  314. package/src/store/clients/suggestions.test.ts +31 -0
  315. package/src/store/clients/suggestions.ts +18 -19
  316. package/src/store/runtime-clients/handle-runtime-action.test.ts +40 -0
  317. package/src/store/runtime-clients/handle-runtime-action.ts +3 -0
  318. package/src/store/scopes/message.ts +1 -1
  319. package/src/store/scopes/queue-item.ts +2 -9
  320. package/src/tests/MessageRepository.test.ts +125 -0
  321. package/src/tests/RemoteThreadListThreadListRuntimeCore-errors.test.ts +2 -2
  322. package/src/tests/RemoteThreadListThreadListRuntimeCore-load-race.test.ts +194 -0
  323. package/src/tests/RemoteThreadListThreadListRuntimeCore-loadMore.test.ts +8 -6
  324. package/src/tests/RemoteThreadListThreadListRuntimeCore-title-race.test.ts +158 -0
  325. package/src/tests/empty-thread-core.test.ts +6 -0
  326. package/src/tests/external-store-thread-runtime-core-adapter.test.ts +184 -0
  327. package/src/tests/external-store-thread-runtime-core.test.ts +642 -0
  328. package/src/tests/external-thread-attachments.test.tsx +173 -0
  329. package/src/tests/external-thread-isEmpty.test.tsx +100 -0
  330. package/src/tests/remote-thread-list-adapter-switch.test.ts +383 -0
  331. package/src/tests/single-thread-list-item.test.tsx +47 -0
  332. package/src/tests/thread-message-like.test.ts +39 -1
  333. package/src/tests/useRemoteThreadListRuntime-controlled.test.tsx +67 -0
  334. package/src/types/message.ts +9 -4
  335. package/src/utils/data-url.test.ts +52 -1
  336. package/src/utils/data-url.ts +21 -0
  337. package/src/utils/invoke-user-callback.test.ts +82 -0
  338. package/src/utils/invoke-user-callback.ts +31 -0
  339. package/src/utils/normalizePartStatus.ts +1 -1
  340. package/src/utils/silent-runtime-action.ts +6 -0
  341. package/dist/store/scopes/queue-item.js.map +0 -1
@@ -1,5 +1,9 @@
1
1
  import { describe, expect, it } from "vitest";
2
- import { fromThreadMessageLike } from "../runtime/utils/thread-message-like";
2
+ import {
3
+ fromThreadMessageLike,
4
+ type ThreadMessageLike,
5
+ } from "../runtime/utils/thread-message-like";
6
+ import type { ToolCallMessagePartMcpMetadata } from "../types/message";
3
7
 
4
8
  const fallbackId = "test-id";
5
9
  const fallbackStatus = {
@@ -421,3 +425,37 @@ describe("fromThreadMessageLike provider metadata", () => {
421
425
  ]);
422
426
  });
423
427
  });
428
+
429
+ describe("fromThreadMessageLike MCP app metadata", () => {
430
+ it("keeps mcp on tool-call parts", () => {
431
+ const mcp: ToolCallMessagePartMcpMetadata = {
432
+ app: { resourceUri: "ui://demo/card" },
433
+ };
434
+ const message: ThreadMessageLike = {
435
+ role: "assistant",
436
+ content: [
437
+ {
438
+ type: "tool-call",
439
+ toolCallId: "call-1",
440
+ toolName: "show_card",
441
+ args: {},
442
+ argsText: "{}",
443
+ mcp,
444
+ },
445
+ ],
446
+ };
447
+
448
+ const result = fromThreadMessageLike(message, fallbackId, fallbackStatus);
449
+
450
+ expect(result.content).toEqual([
451
+ {
452
+ type: "tool-call",
453
+ toolCallId: "call-1",
454
+ toolName: "show_card",
455
+ args: {},
456
+ argsText: "{}",
457
+ mcp,
458
+ },
459
+ ]);
460
+ });
461
+ });
@@ -173,6 +173,73 @@ describe("useRemoteThreadListRuntime controlled threadId", () => {
173
173
  expect(onThreadIdChange).not.toHaveBeenCalled();
174
174
  });
175
175
 
176
+ it("reports the reset when an adapter change makes the runtime uncontrolled", async () => {
177
+ const adapterA = makeAdapter();
178
+ const adapterB = makeAdapter();
179
+ const onThreadIdChange = vi.fn();
180
+ const runtimeRef: RuntimeRef = { current: null };
181
+
182
+ const { rerender } = render(
183
+ <ControlledRuntime
184
+ adapter={adapterA}
185
+ threadId="thread-a"
186
+ onThreadIdChange={onThreadIdChange}
187
+ runtimeRef={runtimeRef}
188
+ />,
189
+ );
190
+ await waitForRemoteThread(runtimeRef, "thread-a");
191
+ onThreadIdChange.mockClear();
192
+
193
+ rerender(
194
+ <ControlledRuntime
195
+ adapter={adapterB}
196
+ threadId={undefined}
197
+ onThreadIdChange={onThreadIdChange}
198
+ runtimeRef={runtimeRef}
199
+ />,
200
+ );
201
+
202
+ await waitFor(() => {
203
+ const state = runtimeRef.current!.threads.getState();
204
+ expect(state.mainThreadId).toBeDefined();
205
+ expect(runtimeRef.current!.threads.mainItem.getState().status).toBe(
206
+ "new",
207
+ );
208
+ });
209
+ expect(onThreadIdChange).not.toHaveBeenCalled();
210
+ });
211
+
212
+ it("does not echo a controlled target when the adapter changes", async () => {
213
+ const adapterA = makeAdapter();
214
+ const adapterB = makeAdapter();
215
+ const onThreadIdChange = vi.fn();
216
+ const runtimeRef: RuntimeRef = { current: null };
217
+
218
+ const { rerender } = render(
219
+ <ControlledRuntime
220
+ adapter={adapterA}
221
+ threadId="thread-a"
222
+ onThreadIdChange={onThreadIdChange}
223
+ runtimeRef={runtimeRef}
224
+ />,
225
+ );
226
+ await waitForRemoteThread(runtimeRef, "thread-a");
227
+ onThreadIdChange.mockClear();
228
+
229
+ rerender(
230
+ <ControlledRuntime
231
+ adapter={adapterB}
232
+ threadId="thread-b"
233
+ onThreadIdChange={onThreadIdChange}
234
+ runtimeRef={runtimeRef}
235
+ />,
236
+ );
237
+
238
+ await waitForRemoteThread(runtimeRef, "thread-b");
239
+ expect(adapterB.fetch).toHaveBeenCalledWith("thread-b");
240
+ expect(onThreadIdChange).not.toHaveBeenCalled();
241
+ });
242
+
176
243
  it("still emits runtime-initiated thread switches", async () => {
177
244
  const adapter = makeAdapter();
178
245
  const onThreadIdChange = vi.fn();
@@ -168,9 +168,9 @@ export type ToolApprovalOption = {
168
168
  readonly id: string;
169
169
  /**
170
170
  * Decision class. Drives approved-resolution and default rendering.
171
- * Open union: `_`-prefixed custom kinds are never auto-resolved and the
172
- * default kit skips them; they must be answered with an explicit
173
- * `approved` value (optionally alongside the `optionId`).
171
+ * Open union: `_`-prefixed custom kinds are never auto-resolved; they must
172
+ * be answered with an explicit `approved` value (optionally alongside the
173
+ * `optionId`), which is what the default kit sends when one is chosen.
174
174
  */
175
175
  readonly kind: ToolApprovalOptionKind | (string & {});
176
176
  /** Human label. Renderers supply defaults per kind when omitted. */
@@ -304,7 +304,12 @@ export type ToolCallMessagePartStatus =
304
304
  /** The tool call is waiting for UI or human input before continuing. */
305
305
  readonly type: "requires-action";
306
306
  /** Reason the tool call requires action. */
307
- readonly reason: "interrupt";
307
+ readonly reason: "tool-calls" | "interrupt";
308
+ }
309
+ | {
310
+ readonly type: "incomplete";
311
+ readonly reason: "tool-calls";
312
+ readonly error?: ReadonlyJSONValue;
308
313
  }
309
314
  | MessagePartStatus;
310
315
 
@@ -1,5 +1,9 @@
1
1
  import { describe, it, expect } from "vitest";
2
- import { httpUrlPattern, parseDataUrl } from "./data-url";
2
+ import {
3
+ httpUrlPattern,
4
+ parseDataUrl,
5
+ resolveFilePartSource,
6
+ } from "./data-url";
3
7
 
4
8
  describe("parseDataUrl", () => {
5
9
  it("parses a base64 data URL", () => {
@@ -72,3 +76,50 @@ describe("httpUrlPattern", () => {
72
76
  },
73
77
  );
74
78
  });
79
+
80
+ describe("resolveFilePartSource", () => {
81
+ it("uses an explicit url source type for opaque values", () => {
82
+ expect(
83
+ resolveFilePartSource({
84
+ data: "provider-file-id",
85
+ mimeType: "application/pdf",
86
+ sourceType: "url",
87
+ }),
88
+ ).toEqual({ kind: "url", url: "provider-file-id" });
89
+ });
90
+
91
+ it("uses http URLs as url sources", () => {
92
+ expect(
93
+ resolveFilePartSource({
94
+ data: "https://example.com/file.pdf",
95
+ mimeType: "application/pdf",
96
+ }),
97
+ ).toEqual({ kind: "url", url: "https://example.com/file.pdf" });
98
+ });
99
+
100
+ it("decodes data URLs and uses their media type", () => {
101
+ expect(
102
+ resolveFilePartSource({
103
+ data: "data:image/png;base64,aGVsbG8=",
104
+ mimeType: "application/octet-stream",
105
+ }),
106
+ ).toEqual({
107
+ kind: "data",
108
+ data: "aGVsbG8=",
109
+ mimeType: "image/png",
110
+ });
111
+ });
112
+
113
+ it("passes through opaque data with its declared media type", () => {
114
+ expect(
115
+ resolveFilePartSource({
116
+ data: "provider-file-id",
117
+ mimeType: "application/pdf",
118
+ }),
119
+ ).toEqual({
120
+ kind: "data",
121
+ data: "provider-file-id",
122
+ mimeType: "application/pdf",
123
+ });
124
+ });
125
+ });
@@ -1,5 +1,9 @@
1
1
  export const httpUrlPattern = /^https?:\/\//i;
2
2
 
3
+ export type FilePartSource =
4
+ | { kind: "url"; url: string }
5
+ | { kind: "data"; data: string; mimeType: string };
6
+
3
7
  export function parseDataUrl(
4
8
  value: string,
5
9
  ): { mimeType: string; data: string } | null {
@@ -8,6 +12,23 @@ export function parseDataUrl(
8
12
  return { mimeType: match[1]!.toLowerCase(), data: match[2]! };
9
13
  }
10
14
 
15
+ export const resolveFilePartSource = (part: {
16
+ data: string;
17
+ mimeType: string;
18
+ sourceType?: string | undefined;
19
+ }): FilePartSource => {
20
+ if (part.sourceType === "url" || httpUrlPattern.test(part.data)) {
21
+ return { kind: "url", url: part.data };
22
+ }
23
+
24
+ const parsed = parseDataUrl(part.data);
25
+ return {
26
+ kind: "data",
27
+ data: parsed?.data ?? part.data,
28
+ mimeType: parsed?.mimeType ?? part.mimeType,
29
+ };
30
+ };
31
+
11
32
  /**
12
33
  * Whether a payload is something `new URL()` accepts. Adapters that place a
13
34
  * `FileMessagePart` payload into a url-typed wire field use this to decide
@@ -0,0 +1,82 @@
1
+ import { afterEach, describe, expect, it, vi } from "vitest";
2
+ import { invokeUserCallback } from "./invoke-user-callback";
3
+
4
+ describe("invokeUserCallback", () => {
5
+ afterEach(() => {
6
+ vi.restoreAllMocks();
7
+ });
8
+
9
+ it("invokes a callback synchronously with its arguments", () => {
10
+ const callback = vi.fn((left: number, right: number) => left + right);
11
+
12
+ expect(invokeUserCallback("test", "onSuccess", callback, 2, 3)).toBe(
13
+ undefined,
14
+ );
15
+ expect(callback).toHaveBeenCalledOnce();
16
+ expect(callback).toHaveBeenCalledWith(2, 3);
17
+ });
18
+
19
+ it("reports and swallows a synchronous throw", () => {
20
+ const error = new Error("sync failure");
21
+ const consoleError = vi
22
+ .spyOn(console, "error")
23
+ .mockImplementation(() => {});
24
+
25
+ expect(() =>
26
+ invokeUserCallback("test", "onError", () => {
27
+ throw error;
28
+ }),
29
+ ).not.toThrow();
30
+ expect(consoleError).toHaveBeenCalledOnce();
31
+ expect(consoleError).toHaveBeenCalledWith(
32
+ "[test] onError callback threw an error",
33
+ error,
34
+ );
35
+ });
36
+
37
+ it("reports an asynchronous rejection and resolves", async () => {
38
+ const error = new Error("async failure");
39
+ const consoleError = vi
40
+ .spyOn(console, "error")
41
+ .mockImplementation(() => {});
42
+
43
+ await expect(
44
+ invokeUserCallback("test", "onError", async () => {
45
+ throw error;
46
+ }),
47
+ ).resolves.toBeUndefined();
48
+ expect(consoleError).toHaveBeenCalledOnce();
49
+ expect(consoleError).toHaveBeenCalledWith(
50
+ "[test] onError callback threw an error",
51
+ error,
52
+ );
53
+ });
54
+
55
+ it("resolves only after an asynchronous callback settles", async () => {
56
+ let settleCallback: (() => void) | undefined;
57
+ const callbackPromise = new Promise<void>((resolve) => {
58
+ settleCallback = resolve;
59
+ });
60
+ let settled = false;
61
+
62
+ const result = invokeUserCallback(
63
+ "test",
64
+ "onFinish",
65
+ () => callbackPromise,
66
+ );
67
+ void result?.then(() => {
68
+ settled = true;
69
+ });
70
+
71
+ await Promise.resolve();
72
+ expect(settled).toBe(false);
73
+
74
+ settleCallback?.();
75
+ await result;
76
+ expect(settled).toBe(true);
77
+ });
78
+
79
+ it("does nothing when the callback is undefined", () => {
80
+ expect(invokeUserCallback("test", "onMissing", undefined)).toBeUndefined();
81
+ });
82
+ });
@@ -0,0 +1,31 @@
1
+ export function invokeUserCallback<TArgs extends readonly unknown[]>(
2
+ tag: string,
3
+ name: string,
4
+ callback: ((...args: TArgs) => unknown) | undefined,
5
+ ...args: TArgs
6
+ ): void | Promise<void> {
7
+ if (!callback) return;
8
+
9
+ const reportError = (error: unknown) => {
10
+ try {
11
+ console.error(`[${tag}] ${name} callback threw an error`, error);
12
+ } catch {}
13
+ };
14
+
15
+ try {
16
+ const result = callback(...args);
17
+ if (
18
+ result !== null &&
19
+ (typeof result === "object" || typeof result === "function") &&
20
+ "then" in result &&
21
+ typeof result.then === "function"
22
+ ) {
23
+ return Promise.resolve(result).then(
24
+ () => undefined,
25
+ (error) => reportError(error),
26
+ );
27
+ }
28
+ } catch (error) {
29
+ reportError(error);
30
+ }
31
+ }
@@ -65,7 +65,7 @@ export const toMessagePartStatus = (
65
65
 
66
66
  if (part.type === "tool-call") {
67
67
  if (part.result === undefined) {
68
- return message.status as ToolCallMessagePartStatus;
68
+ return message.status;
69
69
  } else {
70
70
  return COMPLETE_STATUS;
71
71
  }
@@ -0,0 +1,6 @@
1
+ export const SILENT_RUNTIME_ACTION = Symbol.for(
2
+ "assistant-ui.silent-runtime-action",
3
+ );
4
+
5
+ export const isSilentRuntimeAction = (error: unknown): boolean =>
6
+ typeof error === "object" && error !== null && SILENT_RUNTIME_ACTION in error;
@@ -1 +0,0 @@
1
- {"version":3,"file":"queue-item.js","names":["FileMessagePart","TextMessagePart","QueuePlacement","QueueItemState","id","prompt","parts","EMPTY_QUEUE_ITEMS","Object","freeze","QueueItemMethods","getState","steer","move","placement","remove","QueueItemMeta","source","query","type","index","QueueItemClientSchema","methods","meta"],"sources":["../../../src/store/scopes/queue-item.ts"],"sourcesContent":["import type { FileMessagePart, TextMessagePart } from \"../../types/message\";\nimport type { QueuePlacement } from \"../../runtime/queue/external-thread-queue-adapter\";\n\nexport type QueueItemState = {\n readonly id: string;\n /** @deprecated Derive from the text parts of `parts` instead. Removal after 2026-11-05. */\n readonly prompt: string;\n readonly parts: readonly (FileMessagePart | TextMessagePart)[];\n};\n\nexport const EMPTY_QUEUE_ITEMS: readonly QueueItemState[] = Object.freeze([]);\n\nexport type QueueItemMethods = {\n getState(): QueueItemState;\n /** @deprecated Use `move({ lane: \"steer\", insertAfter: null })` instead. Removal after 2026-11-05. */\n steer(): void;\n move(placement: QueuePlacement): void;\n remove(): void;\n};\n\nexport type QueueItemMeta = {\n source: \"composer\";\n query: { type: \"index\"; index: number } | { type: \"id\"; id: string };\n};\n\nexport type QueueItemClientSchema = {\n methods: QueueItemMethods;\n meta: QueueItemMeta;\n};\n"],"mappings":";AAUA,MAAaO,oBAA+CC,OAAOC,OAAO,CAAA,CAAE"}