@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
@@ -8,7 +8,9 @@ const executionContext = {
8
8
  human: async () => undefined,
9
9
  };
10
10
 
11
- const createHost = () => {
11
+ const DEFAULT_ORIGIN = "https://host.example";
12
+
13
+ const createHost = (targetOrigin?: string) => {
12
14
  let handleMessage: ((event: MessageEvent) => void) | undefined;
13
15
  const addEventListener = vi.fn(
14
16
  (_type: string, listener: EventListenerOrEventListenerObject) => {
@@ -16,15 +18,23 @@ const createHost = () => {
16
18
  },
17
19
  );
18
20
  const removeEventListener = vi.fn();
19
- vi.stubGlobal("window", { addEventListener, removeEventListener });
21
+ vi.stubGlobal("window", {
22
+ addEventListener,
23
+ removeEventListener,
24
+ location: { origin: DEFAULT_ORIGIN },
25
+ });
20
26
 
21
27
  const postMessage = vi.fn();
22
28
  const iframeWindow = { postMessage } as unknown as Window;
23
- const host = new AssistantFrameHost(iframeWindow);
29
+ const host = new AssistantFrameHost(iframeWindow, targetOrigin);
24
30
 
25
- const dispatchMessage = (message: FrameMessage) =>
31
+ const dispatchMessage = (
32
+ message: FrameMessage,
33
+ origin = targetOrigin ?? DEFAULT_ORIGIN,
34
+ ) =>
26
35
  handleMessage?.({
27
36
  source: iframeWindow,
37
+ origin,
28
38
  data: {
29
39
  channel: FRAME_MESSAGE_CHANNEL,
30
40
  message,
@@ -46,7 +56,15 @@ const createHost = () => {
46
56
  const execute = host.getModelContext().tools?.search?.execute;
47
57
  if (!execute) throw new Error("Expected the search tool to be available");
48
58
 
49
- return { dispatchMessage, execute, host, postMessage };
59
+ const getToolCallId = () => {
60
+ const call = postMessage.mock.calls.find(
61
+ ([data]) => data.message.type === "tool-call",
62
+ );
63
+ if (!call) throw new Error("Expected a tool call to be posted");
64
+ return call[0].message.id as string;
65
+ };
66
+
67
+ return { dispatchMessage, execute, getToolCallId, host, postMessage };
50
68
  };
51
69
 
52
70
  beforeEach(() => {
@@ -59,15 +77,54 @@ afterEach(() => {
59
77
  });
60
78
 
61
79
  describe("AssistantFrameHost", () => {
80
+ it("defaults to the current origin", () => {
81
+ const { host, postMessage } = createHost();
82
+
83
+ expect(postMessage).toHaveBeenCalledWith(expect.anything(), DEFAULT_ORIGIN);
84
+
85
+ host.dispose();
86
+ });
87
+
88
+ it("ignores context updates from another origin", () => {
89
+ const { dispatchMessage, host } = createHost();
90
+
91
+ dispatchMessage(
92
+ {
93
+ type: "model-context-update",
94
+ context: { system: "untrusted instructions" },
95
+ },
96
+ "https://untrusted.example",
97
+ );
98
+
99
+ expect(host.getModelContext().system).toBeUndefined();
100
+ host.dispose();
101
+ });
102
+
103
+ it("allows an explicit wildcard origin", () => {
104
+ const { dispatchMessage, host, postMessage } = createHost("*");
105
+
106
+ dispatchMessage(
107
+ {
108
+ type: "model-context-update",
109
+ context: { system: "cross-origin instructions" },
110
+ },
111
+ "https://iframe.example",
112
+ );
113
+
114
+ expect(postMessage).toHaveBeenCalledWith(expect.anything(), "*");
115
+ expect(host.getModelContext().system).toBe("cross-origin instructions");
116
+ host.dispose();
117
+ });
118
+
62
119
  it("resolves tool calls from frame results", async () => {
63
- const { dispatchMessage, execute, host } = createHost();
120
+ const { dispatchMessage, execute, getToolCallId, host } = createHost();
64
121
  const result = Promise.resolve(
65
122
  execute({ query: "weather" }, executionContext),
66
123
  );
67
124
 
68
125
  dispatchMessage({
69
126
  type: "tool-result",
70
- id: "tool-0",
127
+ id: getToolCallId(),
71
128
  result: "sunny",
72
129
  });
73
130
 
@@ -76,20 +133,63 @@ describe("AssistantFrameHost", () => {
76
133
  host.dispose();
77
134
  });
78
135
 
136
+ it("rejects tool results that carry an empty error message", async () => {
137
+ const { dispatchMessage, execute, getToolCallId, host } = createHost();
138
+ const result = Promise.resolve(
139
+ execute({ query: "weather" }, executionContext),
140
+ );
141
+
142
+ dispatchMessage({
143
+ type: "tool-result",
144
+ id: getToolCallId(),
145
+ error: "",
146
+ });
147
+
148
+ await expect(result).rejects.toThrow();
149
+ expect(vi.getTimerCount()).toBe(0);
150
+ host.dispose();
151
+ });
152
+
153
+ it("resolves results from guests that serialize an absent error as null", async () => {
154
+ const { dispatchMessage, execute, getToolCallId, host } = createHost();
155
+ const result = Promise.resolve(
156
+ execute({ query: "weather" }, executionContext),
157
+ );
158
+
159
+ dispatchMessage({
160
+ type: "tool-result",
161
+ id: getToolCallId(),
162
+ result: "sunny",
163
+ error: null,
164
+ } as unknown as FrameMessage);
165
+
166
+ await expect(result).resolves.toBe("sunny");
167
+ expect(vi.getTimerCount()).toBe(0);
168
+ host.dispose();
169
+ });
170
+
79
171
  it("rejects pending tool calls when disposed", async () => {
80
- const { execute, host } = createHost();
172
+ const { execute, getToolCallId, host, postMessage } = createHost();
81
173
  const result = Promise.resolve(execute({}, executionContext));
174
+ const toolCallId = getToolCallId();
82
175
 
83
176
  host.dispose();
84
177
 
85
178
  await expect(result).rejects.toThrow(
86
179
  "AssistantFrameHost has been disposed",
87
180
  );
181
+ expect(postMessage).toHaveBeenLastCalledWith(
182
+ {
183
+ channel: FRAME_MESSAGE_CHANNEL,
184
+ message: { type: "tool-cancel", id: toolCallId },
185
+ },
186
+ DEFAULT_ORIGIN,
187
+ );
88
188
  expect(vi.getTimerCount()).toBe(0);
89
189
  });
90
190
 
91
191
  it("rejects pending tool calls when execution is aborted", async () => {
92
- const { execute, host } = createHost();
192
+ const { execute, getToolCallId, host, postMessage } = createHost();
93
193
  const abortController = new AbortController();
94
194
  const abortError = new Error("Run cancelled");
95
195
  abortError.name = "AbortError";
@@ -104,15 +204,58 @@ describe("AssistantFrameHost", () => {
104
204
  );
105
205
  const onRejected = vi.fn();
106
206
  void result.catch(onRejected);
207
+ const toolCallId = getToolCallId();
107
208
 
108
209
  abortController.abort(abortError);
109
210
  await Promise.resolve();
110
211
 
111
212
  expect(onRejected).toHaveBeenCalledWith(abortError);
213
+ expect(postMessage).toHaveBeenLastCalledWith(
214
+ {
215
+ channel: FRAME_MESSAGE_CHANNEL,
216
+ message: { type: "tool-cancel", id: toolCallId },
217
+ },
218
+ DEFAULT_ORIGIN,
219
+ );
220
+ expect(vi.getTimerCount()).toBe(0);
221
+ host.dispose();
222
+ });
223
+
224
+ it("cancels tool calls when they time out", async () => {
225
+ const { execute, getToolCallId, host, postMessage } = createHost();
226
+ const result = Promise.resolve(execute({}, executionContext));
227
+ const toolCallId = getToolCallId();
228
+ const rejection = expect(result).rejects.toThrow(
229
+ 'Tool call "search" timed out',
230
+ );
231
+
232
+ await vi.advanceTimersByTimeAsync(30000);
233
+
234
+ await rejection;
235
+ expect(postMessage).toHaveBeenLastCalledWith(
236
+ {
237
+ channel: FRAME_MESSAGE_CHANNEL,
238
+ message: { type: "tool-cancel", id: toolCallId },
239
+ },
240
+ DEFAULT_ORIGIN,
241
+ );
112
242
  expect(vi.getTimerCount()).toBe(0);
113
243
  host.dispose();
114
244
  });
115
245
 
246
+ it("uses unique tool IDs across host instances", () => {
247
+ const first = createHost();
248
+ const second = createHost();
249
+
250
+ void first.execute({}, executionContext).catch(() => undefined);
251
+ void second.execute({}, executionContext).catch(() => undefined);
252
+
253
+ expect(first.getToolCallId()).not.toBe(second.getToolCallId());
254
+
255
+ first.host.dispose();
256
+ second.host.dispose();
257
+ });
258
+
116
259
  it("does not post tool calls when execution is already aborted", async () => {
117
260
  const { execute, host, postMessage } = createHost();
118
261
  const abortController = new AbortController();
@@ -2,6 +2,7 @@ import type { ModelContextProvider, ModelContext } from "../types";
2
2
  import type { Unsubscribe } from "../../types/unsubscribe";
3
3
  import type { Tool } from "assistant-stream";
4
4
  import { notifySubscribers as notifyStateSubscribers } from "../../subscribable/subscribable";
5
+ import { generateId } from "../../utils/id";
5
6
  import {
6
7
  type FrameMessage,
7
8
  FRAME_MESSAGE_CHANNEL,
@@ -9,6 +10,8 @@ import {
9
10
  type SerializedTool,
10
11
  } from "./types";
11
12
 
13
+ const getDefaultTargetOrigin = () => window.location.origin;
14
+
12
15
  /**
13
16
  * Deserializes tools from JSON Schema format back to Tool objects
14
17
  */
@@ -58,12 +61,14 @@ export class AssistantFrameHost implements ModelContextProvider {
58
61
  reject: (error: any) => void;
59
62
  }
60
63
  >();
61
- private _requestCounter = 0;
62
64
  private _iframeWindow: Window;
63
65
  private _targetOrigin: string;
64
66
  private _disposed = false;
65
67
 
66
- constructor(iframeWindow: Window, targetOrigin: string = "*") {
68
+ constructor(
69
+ iframeWindow: Window,
70
+ targetOrigin: string = getDefaultTargetOrigin(),
71
+ ) {
67
72
  this._iframeWindow = iframeWindow;
68
73
  this._targetOrigin = targetOrigin;
69
74
 
@@ -90,7 +95,7 @@ export class AssistantFrameHost implements ModelContextProvider {
90
95
  case "tool-result": {
91
96
  const pending = this._pendingRequests.get(message.id);
92
97
  if (pending) {
93
- if (message.error) {
98
+ if (typeof message.error === "string") {
94
99
  pending.reject(new Error(message.error));
95
100
  } else {
96
101
  pending.resolve(message.result);
@@ -130,7 +135,7 @@ export class AssistantFrameHost implements ModelContextProvider {
130
135
  return this.sendRequest(
131
136
  {
132
137
  type: "tool-call",
133
- id: `tool-${this._requestCounter++}`,
138
+ id: `tool-${generateId()}`,
134
139
  toolName,
135
140
  args,
136
141
  },
@@ -159,6 +164,7 @@ export class AssistantFrameHost implements ModelContextProvider {
159
164
  if (!abortSignal) return;
160
165
  const pending = this._pendingRequests.get(message.id);
161
166
  if (pending) {
167
+ this.cancelToolCall(message.id);
162
168
  pending.reject(getAbortReason(abortSignal));
163
169
  this._pendingRequests.delete(message.id);
164
170
  }
@@ -182,6 +188,7 @@ export class AssistantFrameHost implements ModelContextProvider {
182
188
  timeoutId = setTimeout(() => {
183
189
  const pending = this._pendingRequests.get(message.id);
184
190
  if (pending) {
191
+ this.cancelToolCall(message.id);
185
192
  pending.reject(new Error(timeoutMessage));
186
193
  this._pendingRequests.delete(message.id);
187
194
  }
@@ -195,6 +202,16 @@ export class AssistantFrameHost implements ModelContextProvider {
195
202
  });
196
203
  }
197
204
 
205
+ private cancelToolCall(id: string) {
206
+ this._iframeWindow.postMessage(
207
+ {
208
+ channel: FRAME_MESSAGE_CHANNEL,
209
+ message: { type: "tool-cancel", id } satisfies FrameMessage,
210
+ },
211
+ this._targetOrigin,
212
+ );
213
+ }
214
+
198
215
  private requestContext() {
199
216
  this._iframeWindow.postMessage(
200
217
  {
@@ -225,7 +242,8 @@ export class AssistantFrameHost implements ModelContextProvider {
225
242
  window.removeEventListener("message", this.handleMessage);
226
243
  this._subscribers.clear();
227
244
  const error = new Error("AssistantFrameHost has been disposed");
228
- for (const pending of this._pendingRequests.values()) {
245
+ for (const [id, pending] of this._pendingRequests) {
246
+ this.cancelToolCall(id);
229
247
  pending.reject(error);
230
248
  }
231
249
  this._pendingRequests.clear();