@assistant-ui/core 0.3.12 → 0.3.14

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 (452) hide show
  1. package/dist/adapters/speech.d.ts.map +1 -1
  2. package/dist/adapters/speech.js +9 -15
  3. package/dist/adapters/speech.js.map +1 -1
  4. package/dist/adapters/thread-history.d.ts +2 -0
  5. package/dist/adapters/thread-history.d.ts.map +1 -1
  6. package/dist/adapters/voice.d.ts.map +1 -1
  7. package/dist/adapters/voice.js +27 -15
  8. package/dist/adapters/voice.js.map +1 -1
  9. package/dist/index.d.ts +3 -3
  10. package/dist/index.js +2 -2
  11. package/dist/index.js.map +1 -1
  12. package/dist/internal.d.ts +1 -1
  13. package/dist/internal.js +6 -6
  14. package/dist/model-context/frame/host.d.ts.map +1 -1
  15. package/dist/model-context/frame/host.js +2 -1
  16. package/dist/model-context/frame/host.js.map +1 -1
  17. package/dist/model-context/registry.d.ts.map +1 -1
  18. package/dist/model-context/registry.js +16 -4
  19. package/dist/model-context/registry.js.map +1 -1
  20. package/dist/react/RuntimeAdapter.d.ts +8 -1
  21. package/dist/react/RuntimeAdapter.d.ts.map +1 -1
  22. package/dist/react/RuntimeAdapter.js +23 -18
  23. package/dist/react/RuntimeAdapter.js.map +1 -1
  24. package/dist/react/adapters/LocalStorageThreadListAdapter.d.ts.map +1 -1
  25. package/dist/react/adapters/LocalStorageThreadListAdapter.js +28 -12
  26. package/dist/react/adapters/LocalStorageThreadListAdapter.js.map +1 -1
  27. package/dist/react/client/AdaptedRemoteThread.d.ts +11 -0
  28. package/dist/react/client/AdaptedRemoteThread.d.ts.map +1 -0
  29. package/dist/react/client/AdaptedRemoteThread.js +27 -0
  30. package/dist/react/client/AdaptedRemoteThread.js.map +1 -0
  31. package/dist/react/client/InMemoryThreadList.d.ts +19 -0
  32. package/dist/react/client/InMemoryThreadList.d.ts.map +1 -0
  33. package/dist/react/client/InMemoryThreadList.js +418 -0
  34. package/dist/react/client/InMemoryThreadList.js.map +1 -0
  35. package/dist/react/client/Interactables.d.ts.map +1 -1
  36. package/dist/react/client/Interactables.js +159 -102
  37. package/dist/react/client/Interactables.js.map +1 -1
  38. package/dist/react/client/RemoteThreadList.d.ts +34 -0
  39. package/dist/react/client/RemoteThreadList.d.ts.map +1 -0
  40. package/dist/react/client/RemoteThreadList.js +826 -0
  41. package/dist/react/client/RemoteThreadList.js.map +1 -0
  42. package/dist/react/client/Tools.d.ts.map +1 -1
  43. package/dist/react/client/Tools.js +38 -27
  44. package/dist/react/client/Tools.js.map +1 -1
  45. package/dist/react/client/interactable-model-context.d.ts.map +1 -1
  46. package/dist/react/client/interactable-model-context.js +5 -1
  47. package/dist/react/client/interactable-model-context.js.map +1 -1
  48. package/dist/react/index.d.ts +7 -2
  49. package/dist/react/index.js +5 -2
  50. package/dist/react/interactables-legacy/Interactables.d.ts.map +1 -1
  51. package/dist/react/interactables-legacy/Interactables.js +145 -110
  52. package/dist/react/interactables-legacy/Interactables.js.map +1 -1
  53. package/dist/react/primitive-hooks/useActionBarCopy.d.ts.map +1 -1
  54. package/dist/react/primitive-hooks/useActionBarCopy.js +13 -18
  55. package/dist/react/primitive-hooks/useActionBarCopy.js.map +1 -1
  56. package/dist/react/primitive-hooks/useActionBarEdit.d.ts.map +1 -1
  57. package/dist/react/primitive-hooks/useActionBarEdit.js +2 -4
  58. package/dist/react/primitive-hooks/useActionBarEdit.js.map +1 -1
  59. package/dist/react/primitive-hooks/useActionBarReload.d.ts.map +1 -1
  60. package/dist/react/primitive-hooks/useActionBarReload.js +2 -4
  61. package/dist/react/primitive-hooks/useActionBarReload.js.map +1 -1
  62. package/dist/react/primitive-hooks/useBranchPickerNext.d.ts.map +1 -1
  63. package/dist/react/primitive-hooks/useBranchPickerNext.js +2 -6
  64. package/dist/react/primitive-hooks/useBranchPickerNext.js.map +1 -1
  65. package/dist/react/primitive-hooks/useBranchPickerPrevious.d.ts.map +1 -1
  66. package/dist/react/primitive-hooks/useBranchPickerPrevious.js +2 -6
  67. package/dist/react/primitive-hooks/useBranchPickerPrevious.js.map +1 -1
  68. package/dist/react/primitive-hooks/useComposerCancel.d.ts.map +1 -1
  69. package/dist/react/primitive-hooks/useComposerCancel.js +2 -4
  70. package/dist/react/primitive-hooks/useComposerCancel.js.map +1 -1
  71. package/dist/react/primitive-hooks/useComposerSend.d.ts.map +1 -1
  72. package/dist/react/primitive-hooks/useComposerSend.js +2 -4
  73. package/dist/react/primitive-hooks/useComposerSend.js.map +1 -1
  74. package/dist/react/primitive-hooks/useSuggestionTrigger.d.ts.map +1 -1
  75. package/dist/react/primitive-hooks/useSuggestionTrigger.js +6 -2
  76. package/dist/react/primitive-hooks/useSuggestionTrigger.js.map +1 -1
  77. package/dist/react/primitives/message/MessageParts.d.ts +13 -0
  78. package/dist/react/primitives/message/MessageParts.d.ts.map +1 -1
  79. package/dist/react/primitives/message/MessageParts.js.map +1 -1
  80. package/dist/react/primitives/thread/ThreadMessages.d.ts.map +1 -1
  81. package/dist/react/primitives/thread/ThreadMessages.js +1 -1
  82. package/dist/react/primitives/thread/ThreadMessages.js.map +1 -1
  83. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.d.ts +22 -10
  84. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.d.ts.map +1 -1
  85. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js +109 -71
  86. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js.map +1 -1
  87. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts +8 -2
  88. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts.map +1 -1
  89. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js +40 -13
  90. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js.map +1 -1
  91. package/dist/react/runtimes/RemoteThreadResource.d.ts +30 -0
  92. package/dist/react/runtimes/RemoteThreadResource.d.ts.map +1 -0
  93. package/dist/react/runtimes/RemoteThreadResource.js +134 -0
  94. package/dist/react/runtimes/RemoteThreadResource.js.map +1 -0
  95. package/dist/react/runtimes/RuntimeAdapterProvider.d.ts +3 -10
  96. package/dist/react/runtimes/RuntimeAdapterProvider.d.ts.map +1 -1
  97. package/dist/react/runtimes/RuntimeAdapterProvider.js +3 -6
  98. package/dist/react/runtimes/RuntimeAdapterProvider.js.map +1 -1
  99. package/dist/react/runtimes/assistant-transport/commandQueue.d.ts +17 -0
  100. package/dist/react/runtimes/assistant-transport/commandQueue.d.ts.map +1 -0
  101. package/dist/react/runtimes/assistant-transport/commandQueue.js +55 -0
  102. package/dist/react/runtimes/assistant-transport/commandQueue.js.map +1 -0
  103. package/dist/react/runtimes/assistant-transport/replayBoundaryStream.d.ts +11 -0
  104. package/dist/react/runtimes/assistant-transport/replayBoundaryStream.d.ts.map +1 -0
  105. package/dist/react/runtimes/assistant-transport/replayBoundaryStream.js +165 -0
  106. package/dist/react/runtimes/assistant-transport/replayBoundaryStream.js.map +1 -0
  107. package/dist/react/runtimes/assistant-transport/runManager.d.ts +15 -0
  108. package/dist/react/runtimes/assistant-transport/runManager.d.ts.map +1 -0
  109. package/dist/react/runtimes/assistant-transport/runManager.js +86 -0
  110. package/dist/react/runtimes/assistant-transport/runManager.js.map +1 -0
  111. package/dist/react/runtimes/assistant-transport/types.d.ts +130 -0
  112. package/dist/react/runtimes/assistant-transport/types.d.ts.map +1 -0
  113. package/dist/react/runtimes/assistant-transport/types.js +0 -0
  114. package/dist/react/runtimes/assistant-transport/useAssistantTransportRuntime.d.ts +14 -0
  115. package/dist/react/runtimes/assistant-transport/useAssistantTransportRuntime.d.ts.map +1 -0
  116. package/dist/react/runtimes/assistant-transport/useAssistantTransportRuntime.js +296 -0
  117. package/dist/react/runtimes/assistant-transport/useAssistantTransportRuntime.js.map +1 -0
  118. package/dist/react/runtimes/assistant-transport/useConvertedState.d.ts +7 -0
  119. package/dist/react/runtimes/assistant-transport/useConvertedState.d.ts.map +1 -0
  120. package/dist/react/runtimes/assistant-transport/useConvertedState.js +25 -0
  121. package/dist/react/runtimes/assistant-transport/useConvertedState.js.map +1 -0
  122. package/dist/react/runtimes/assistant-transport/useLatestRef.d.ts +7 -0
  123. package/dist/react/runtimes/assistant-transport/useLatestRef.d.ts.map +1 -0
  124. package/dist/react/runtimes/assistant-transport/useLatestRef.js +27 -0
  125. package/dist/react/runtimes/assistant-transport/useLatestRef.js.map +1 -0
  126. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.d.ts.map +1 -1
  127. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.js +39 -13
  128. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.js.map +1 -1
  129. package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.d.ts +2 -1
  130. package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.d.ts.map +1 -1
  131. package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.js +3 -3
  132. package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.js.map +1 -1
  133. package/dist/react/runtimes/cloud/auiV0.d.ts +4 -0
  134. package/dist/react/runtimes/cloud/auiV0.d.ts.map +1 -1
  135. package/dist/react/runtimes/cloud/auiV0.js +7 -0
  136. package/dist/react/runtimes/cloud/auiV0.js.map +1 -1
  137. package/dist/react/runtimes/cloud/useCloudThreadListAdapter.d.ts.map +1 -1
  138. package/dist/react/runtimes/cloud/useCloudThreadListAdapter.js +22 -12
  139. package/dist/react/runtimes/cloud/useCloudThreadListAdapter.js.map +1 -1
  140. package/dist/react/runtimes/cloud/useCloudThreadListRuntime.d.ts +16 -0
  141. package/dist/react/runtimes/cloud/useCloudThreadListRuntime.d.ts.map +1 -0
  142. package/dist/react/runtimes/cloud/useCloudThreadListRuntime.js +36 -0
  143. package/dist/react/runtimes/cloud/useCloudThreadListRuntime.js.map +1 -0
  144. package/dist/react/runtimes/external-message-converter.js +14 -14
  145. package/dist/react/runtimes/external-message-converter.js.map +1 -1
  146. package/dist/react/runtimes/useExternalStoreRuntime.d.ts.map +1 -1
  147. package/dist/react/runtimes/useExternalStoreRuntime.js +44 -28
  148. package/dist/react/runtimes/useExternalStoreRuntime.js.map +1 -1
  149. package/dist/react/runtimes/useExternalStoreSharedOptions.js.map +1 -1
  150. package/dist/react/runtimes/useLocalRuntime.js +1 -1
  151. package/dist/react/runtimes/useRuntimeAdapters.d.ts +9 -0
  152. package/dist/react/runtimes/useRuntimeAdapters.d.ts.map +1 -0
  153. package/dist/react/runtimes/useRuntimeAdapters.js +20 -0
  154. package/dist/react/runtimes/useRuntimeAdapters.js.map +1 -0
  155. package/dist/runtime/api/composer-runtime.d.ts +5 -0
  156. package/dist/runtime/api/composer-runtime.d.ts.map +1 -1
  157. package/dist/runtime/api/composer-runtime.js.map +1 -1
  158. package/dist/runtime/api/message-runtime.js +1 -1
  159. package/dist/runtime/api/thread-list-runtime.d.ts +1 -0
  160. package/dist/runtime/api/thread-list-runtime.d.ts.map +1 -1
  161. package/dist/runtime/api/thread-list-runtime.js +4 -2
  162. package/dist/runtime/api/thread-list-runtime.js.map +1 -1
  163. package/dist/runtime/api/thread-runtime.d.ts +12 -2
  164. package/dist/runtime/api/thread-runtime.d.ts.map +1 -1
  165. package/dist/runtime/api/thread-runtime.js +13 -3
  166. package/dist/runtime/api/thread-runtime.js.map +1 -1
  167. package/dist/runtime/base/base-composer-runtime-core.d.ts +25 -0
  168. package/dist/runtime/base/base-composer-runtime-core.d.ts.map +1 -1
  169. package/dist/runtime/base/base-composer-runtime-core.js +72 -18
  170. package/dist/runtime/base/base-composer-runtime-core.js.map +1 -1
  171. package/dist/runtime/base/base-thread-runtime-core.d.ts +15 -0
  172. package/dist/runtime/base/base-thread-runtime-core.d.ts.map +1 -1
  173. package/dist/runtime/base/base-thread-runtime-core.js +34 -3
  174. package/dist/runtime/base/base-thread-runtime-core.js.map +1 -1
  175. package/dist/runtime/base/default-edit-composer-runtime-core.d.ts.map +1 -1
  176. package/dist/runtime/base/default-edit-composer-runtime-core.js +1 -6
  177. package/dist/runtime/base/default-edit-composer-runtime-core.js.map +1 -1
  178. package/dist/runtime/base/default-thread-composer-runtime-core.d.ts +0 -1
  179. package/dist/runtime/base/default-thread-composer-runtime-core.d.ts.map +1 -1
  180. package/dist/runtime/base/default-thread-composer-runtime-core.js +11 -8
  181. package/dist/runtime/base/default-thread-composer-runtime-core.js.map +1 -1
  182. package/dist/runtime/interfaces/thread-runtime-core.d.ts +6 -0
  183. package/dist/runtime/interfaces/thread-runtime-core.d.ts.map +1 -1
  184. package/dist/runtime/internal.js +5 -5
  185. package/dist/runtime/queue/external-thread-queue-adapter.d.ts +15 -0
  186. package/dist/runtime/queue/external-thread-queue-adapter.d.ts.map +1 -1
  187. package/dist/runtime/queue/message-queue.d.ts.map +1 -1
  188. package/dist/runtime/queue/message-queue.js +25 -11
  189. package/dist/runtime/queue/message-queue.js.map +1 -1
  190. package/dist/runtime/utils/thread-runtime-lifecycle.d.ts +8 -0
  191. package/dist/runtime/utils/thread-runtime-lifecycle.d.ts.map +1 -0
  192. package/dist/runtime/utils/thread-runtime-lifecycle.js +11 -0
  193. package/dist/runtime/utils/thread-runtime-lifecycle.js.map +1 -0
  194. package/dist/runtimes/external-store/external-store-adapter.d.ts +7 -0
  195. package/dist/runtimes/external-store/external-store-adapter.d.ts.map +1 -1
  196. package/dist/runtimes/external-store/external-store-shared-options.js.map +1 -1
  197. package/dist/runtimes/external-store/external-store-thread-list-runtime-core.d.ts.map +1 -1
  198. package/dist/runtimes/external-store/external-store-thread-list-runtime-core.js +4 -1
  199. package/dist/runtimes/external-store/external-store-thread-list-runtime-core.js.map +1 -1
  200. package/dist/runtimes/external-store/external-store-thread-runtime-core.d.ts +11 -1
  201. package/dist/runtimes/external-store/external-store-thread-runtime-core.d.ts.map +1 -1
  202. package/dist/runtimes/external-store/external-store-thread-runtime-core.js +78 -20
  203. package/dist/runtimes/external-store/external-store-thread-runtime-core.js.map +1 -1
  204. package/dist/runtimes/internal.d.ts +1 -1
  205. package/dist/runtimes/local/local-thread-runtime-core.d.ts +3 -0
  206. package/dist/runtimes/local/local-thread-runtime-core.d.ts.map +1 -1
  207. package/dist/runtimes/local/local-thread-runtime-core.js +55 -14
  208. package/dist/runtimes/local/local-thread-runtime-core.js.map +1 -1
  209. package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.d.ts +1 -0
  210. package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.d.ts.map +1 -1
  211. package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.js +3 -0
  212. package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.js.map +1 -1
  213. package/dist/runtimes/remote-thread-list/empty-thread-core.js +3 -0
  214. package/dist/runtimes/remote-thread-list/empty-thread-core.js.map +1 -1
  215. package/dist/runtimes/remote-thread-list/types.d.ts +29 -1
  216. package/dist/runtimes/remote-thread-list/types.d.ts.map +1 -1
  217. package/dist/runtimes/tool-invocations/ToolInvocationTracker.d.ts +1 -12
  218. package/dist/runtimes/tool-invocations/ToolInvocationTracker.d.ts.map +1 -1
  219. package/dist/runtimes/tool-invocations/ToolInvocationTracker.js +67 -38
  220. package/dist/runtimes/tool-invocations/ToolInvocationTracker.js.map +1 -1
  221. package/dist/store/clients/external-thread.d.ts +7 -0
  222. package/dist/store/clients/external-thread.d.ts.map +1 -1
  223. package/dist/store/clients/external-thread.js +460 -369
  224. package/dist/store/clients/external-thread.js.map +1 -1
  225. package/dist/store/clients/runtime-adapter.d.ts.map +1 -1
  226. package/dist/store/clients/runtime-adapter.js +5 -2
  227. package/dist/store/clients/runtime-adapter.js.map +1 -1
  228. package/dist/store/clients/single-thread-list.d.ts.map +1 -1
  229. package/dist/store/clients/single-thread-list.js +31 -27
  230. package/dist/store/clients/single-thread-list.js.map +1 -1
  231. package/dist/store/clients/suggestions.d.ts +3 -1
  232. package/dist/store/clients/suggestions.d.ts.map +1 -1
  233. package/dist/store/clients/suggestions.js +65 -37
  234. package/dist/store/clients/suggestions.js.map +1 -1
  235. package/dist/store/clients/thread-selection-events.d.ts +10 -0
  236. package/dist/store/clients/thread-selection-events.d.ts.map +1 -0
  237. package/dist/store/clients/thread-selection-events.js +40 -0
  238. package/dist/store/clients/thread-selection-events.js.map +1 -0
  239. package/dist/store/env.d.ts +5 -0
  240. package/dist/store/env.d.ts.map +1 -0
  241. package/dist/store/env.js +12 -0
  242. package/dist/store/env.js.map +1 -0
  243. package/dist/store/index.d.ts +6 -4
  244. package/dist/store/index.js +5 -3
  245. package/dist/store/internal.d.ts +4 -1
  246. package/dist/store/internal.js +4 -1
  247. package/dist/store/primitive-predicates.d.ts +19 -0
  248. package/dist/store/primitive-predicates.d.ts.map +1 -0
  249. package/dist/store/primitive-predicates.js +19 -0
  250. package/dist/store/primitive-predicates.js.map +1 -0
  251. package/dist/store/runtime-clients/attachment-runtime-client.d.ts.map +1 -1
  252. package/dist/store/runtime-clients/attachment-runtime-client.js +18 -11
  253. package/dist/store/runtime-clients/attachment-runtime-client.js.map +1 -1
  254. package/dist/store/runtime-clients/handle-runtime-action.d.ts +5 -0
  255. package/dist/store/runtime-clients/handle-runtime-action.d.ts.map +1 -0
  256. package/dist/store/runtime-clients/handle-runtime-action.js +12 -0
  257. package/dist/store/runtime-clients/handle-runtime-action.js.map +1 -0
  258. package/dist/store/runtime-clients/handle-thread-list-action.d.ts +5 -0
  259. package/dist/store/runtime-clients/handle-thread-list-action.d.ts.map +1 -0
  260. package/dist/store/runtime-clients/handle-thread-list-action.js +7 -0
  261. package/dist/store/runtime-clients/handle-thread-list-action.js.map +1 -0
  262. package/dist/store/runtime-clients/thread-list-item-runtime-client.d.ts.map +1 -1
  263. package/dist/store/runtime-clients/thread-list-item-runtime-client.js +104 -57
  264. package/dist/store/runtime-clients/thread-list-item-runtime-client.js.map +1 -1
  265. package/dist/store/runtime-clients/thread-list-runtime-client.d.ts.map +1 -1
  266. package/dist/store/runtime-clients/thread-list-runtime-client.js +5 -6
  267. package/dist/store/runtime-clients/thread-list-runtime-client.js.map +1 -1
  268. package/dist/store/runtime-clients/thread-runtime-client.d.ts.map +1 -1
  269. package/dist/store/runtime-clients/thread-runtime-client.js +98 -82
  270. package/dist/store/runtime-clients/thread-runtime-client.js.map +1 -1
  271. package/dist/store/scope-registration.d.ts +2 -2
  272. package/dist/store/scopes/composer.d.ts +9 -4
  273. package/dist/store/scopes/composer.d.ts.map +1 -1
  274. package/dist/store/scopes/suggestions.d.ts +6 -1
  275. package/dist/store/scopes/suggestions.d.ts.map +1 -1
  276. package/dist/store/scopes/thread-list-item.d.ts +7 -6
  277. package/dist/store/scopes/thread-list-item.d.ts.map +1 -1
  278. package/dist/store/scopes/thread.d.ts +25 -7
  279. package/dist/store/scopes/thread.d.ts.map +1 -1
  280. package/dist/store/scopes/threads.d.ts +17 -1
  281. package/dist/store/scopes/threads.d.ts.map +1 -1
  282. package/dist/subscribable/subscribable.d.ts +2 -1
  283. package/dist/subscribable/subscribable.d.ts.map +1 -1
  284. package/dist/subscribable/subscribable.js +23 -18
  285. package/dist/subscribable/subscribable.js.map +1 -1
  286. package/dist/types/error.d.ts +15 -1
  287. package/dist/types/error.d.ts.map +1 -1
  288. package/dist/types/error.js +18 -1
  289. package/dist/types/error.js.map +1 -1
  290. package/dist/types/message.d.ts +2 -0
  291. package/dist/types/message.d.ts.map +1 -1
  292. package/dist/types/message.js.map +1 -1
  293. package/dist/utils/composite-context-provider.d.ts +1 -0
  294. package/dist/utils/composite-context-provider.d.ts.map +1 -1
  295. package/dist/utils/composite-context-provider.js +25 -9
  296. package/dist/utils/composite-context-provider.js.map +1 -1
  297. package/dist/utils/notify-event-listeners.d.ts +2 -2
  298. package/dist/utils/notify-event-listeners.d.ts.map +1 -1
  299. package/dist/utils/notify-event-listeners.js +2 -2
  300. package/dist/utils/notify-event-listeners.js.map +1 -1
  301. package/package.json +7 -7
  302. package/src/adapters/speech.test.ts +118 -1
  303. package/src/adapters/speech.ts +21 -22
  304. package/src/adapters/thread-history.ts +2 -0
  305. package/src/adapters/voice.test.ts +69 -0
  306. package/src/adapters/voice.ts +27 -27
  307. package/src/index.ts +2 -0
  308. package/src/model-context/frame/host.test.ts +23 -0
  309. package/src/model-context/frame/host.ts +2 -1
  310. package/src/model-context/registry.test.ts +131 -0
  311. package/src/model-context/registry.ts +16 -6
  312. package/src/react/RuntimeAdapter.test.ts +2 -0
  313. package/src/react/RuntimeAdapter.ts +20 -8
  314. package/src/react/adapters/LocalStorageThreadListAdapter.tsx +34 -17
  315. package/src/react/client/AdaptedRemoteThread.ts +41 -0
  316. package/src/react/client/InMemoryThreadList.test.tsx +148 -0
  317. package/src/react/client/InMemoryThreadList.ts +290 -0
  318. package/src/react/client/Interactables.test.ts +326 -2
  319. package/src/react/client/Interactables.ts +227 -110
  320. package/src/react/client/RemoteThreadList.test.ts +1026 -0
  321. package/src/react/client/RemoteThreadList.ts +1067 -0
  322. package/src/react/client/Tools.ts +36 -29
  323. package/src/react/client/interactable-model-context.ts +6 -1
  324. package/src/react/index.ts +13 -0
  325. package/src/react/interactables-legacy/Interactables.test.ts +317 -0
  326. package/src/react/interactables-legacy/Interactables.ts +204 -128
  327. package/src/react/primitive-hooks/useActionBarCopy.ts +2 -7
  328. package/src/react/primitive-hooks/useActionBarEdit.ts +2 -1
  329. package/src/react/primitive-hooks/useActionBarReload.ts +2 -6
  330. package/src/react/primitive-hooks/useBranchPickerNext.ts +2 -7
  331. package/src/react/primitive-hooks/useBranchPickerPrevious.ts +2 -7
  332. package/src/react/primitive-hooks/useComposerCancel.ts +2 -1
  333. package/src/react/primitive-hooks/useComposerSend.ts +2 -5
  334. package/src/react/primitive-hooks/useSuggestionTrigger.test.ts +11 -0
  335. package/src/react/primitive-hooks/useSuggestionTrigger.ts +4 -5
  336. package/src/react/primitives/message/MessageParts.tsx +0 -1
  337. package/src/react/primitives/thread/ThreadMessages.tsx +2 -1
  338. package/src/react/runtimes/RemoteThreadListHookInstanceManager.retry.test.tsx +116 -0
  339. package/src/react/runtimes/RemoteThreadListHookInstanceManager.running.test.tsx +1 -1
  340. package/src/react/runtimes/RemoteThreadListHookInstanceManager.test.tsx +57 -6
  341. package/src/react/runtimes/RemoteThreadListHookInstanceManager.title.test.tsx +272 -0
  342. package/src/react/runtimes/RemoteThreadListHookInstanceManager.tsx +159 -124
  343. package/src/react/runtimes/RemoteThreadListThreadListRuntimeCore.tsx +59 -20
  344. package/src/react/runtimes/RemoteThreadResource.test.ts +141 -0
  345. package/src/react/runtimes/RemoteThreadResource.ts +231 -0
  346. package/src/react/runtimes/RuntimeAdapterProvider.tsx +8 -20
  347. package/src/react/runtimes/assistant-transport/commandQueue.ts +68 -0
  348. package/src/react/runtimes/assistant-transport/replayBoundaryStream.test.ts +455 -0
  349. package/src/react/runtimes/assistant-transport/replayBoundaryStream.ts +172 -0
  350. package/src/react/runtimes/assistant-transport/runManager.ts +124 -0
  351. package/src/react/runtimes/assistant-transport/transport-delivery.test.tsx +79 -0
  352. package/src/react/runtimes/assistant-transport/transport-parentid.test.tsx +97 -0
  353. package/src/react/runtimes/assistant-transport/transport-scheduling.test.ts +414 -0
  354. package/src/react/runtimes/assistant-transport/types.ts +170 -0
  355. package/src/react/runtimes/assistant-transport/useAssistantTransport.spec.md +141 -0
  356. package/src/react/runtimes/assistant-transport/useAssistantTransportRuntime.test.tsx +625 -0
  357. package/src/react/runtimes/assistant-transport/useAssistantTransportRuntime.ts +481 -0
  358. package/src/react/runtimes/assistant-transport/useConvertedState.ts +20 -0
  359. package/src/react/runtimes/assistant-transport/useLatestRef.ts +9 -0
  360. package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.test.tsx +131 -6
  361. package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.ts +61 -15
  362. package/src/react/runtimes/cloud/CloudFileAttachmentAdapter.ts +6 -4
  363. package/src/react/runtimes/cloud/auiV0.ts +17 -1
  364. package/src/react/runtimes/cloud/useCloudThreadListAdapter.tsx +36 -21
  365. package/src/react/runtimes/cloud/useCloudThreadListRuntime.test.tsx +56 -0
  366. package/src/react/runtimes/cloud/useCloudThreadListRuntime.ts +31 -0
  367. package/src/react/runtimes/external-message-converter.test.ts +143 -0
  368. package/src/react/runtimes/external-message-converter.ts +41 -41
  369. package/src/react/runtimes/remote-thread-hook-on-tap.test.ts +58 -0
  370. package/src/react/runtimes/useExternalStoreRuntime.lifecycle.test.tsx +83 -0
  371. package/src/react/runtimes/useExternalStoreRuntime.suggestions.test.tsx +124 -0
  372. package/src/react/runtimes/useExternalStoreRuntime.ts +7 -0
  373. package/src/react/runtimes/useExternalStoreSharedOptions.ts +3 -1
  374. package/src/react/runtimes/useLocalRuntime.test.tsx +130 -4
  375. package/src/react/runtimes/useRuntimeAdapters.test.tsx +62 -0
  376. package/src/react/runtimes/useRuntimeAdapters.ts +28 -0
  377. package/src/runtime/api/composer-runtime.ts +5 -0
  378. package/src/runtime/api/thread-list-runtime.ts +3 -1
  379. package/src/runtime/api/thread-runtime.ts +28 -3
  380. package/src/runtime/base/base-composer-runtime-core.ts +106 -13
  381. package/src/runtime/base/base-thread-runtime-core.test.ts +191 -0
  382. package/src/runtime/base/base-thread-runtime-core.ts +47 -2
  383. package/src/runtime/base/default-edit-composer-runtime-core.ts +1 -15
  384. package/src/runtime/base/default-thread-composer-runtime-core.ts +13 -15
  385. package/src/runtime/interfaces/thread-runtime-core.ts +6 -0
  386. package/src/runtime/queue/external-thread-queue-adapter.ts +17 -0
  387. package/src/runtime/queue/message-queue.ts +28 -10
  388. package/src/runtime/utils/thread-runtime-lifecycle.ts +18 -0
  389. package/src/runtimes/external-store/external-store-adapter.ts +7 -0
  390. package/src/runtimes/external-store/external-store-shared-options.ts +3 -1
  391. package/src/runtimes/external-store/external-store-thread-list-runtime-core.ts +4 -1
  392. package/src/runtimes/external-store/external-store-thread-runtime-core.ts +187 -48
  393. package/src/runtimes/local/local-thread-runtime-core.test.ts +373 -4
  394. package/src/runtimes/local/local-thread-runtime-core.ts +83 -15
  395. package/src/runtimes/readonly/ReadonlyThreadRuntimeCore.ts +4 -0
  396. package/src/runtimes/remote-thread-list/empty-thread-core.ts +4 -0
  397. package/src/runtimes/remote-thread-list/types.ts +30 -0
  398. package/src/runtimes/tool-invocations/EDGE_CASES.md +17 -6
  399. package/src/runtimes/tool-invocations/ToolInvocationTracker.test.ts +243 -0
  400. package/src/runtimes/tool-invocations/ToolInvocationTracker.ts +127 -61
  401. package/src/store/clients/external-thread.ts +119 -16
  402. package/src/store/clients/model-context-client.test.ts +16 -8
  403. package/src/store/clients/runtime-adapter.ts +5 -2
  404. package/src/store/clients/single-thread-list.ts +2 -1
  405. package/src/store/clients/suggestions.ts +39 -13
  406. package/src/store/clients/thread-selection-events.ts +21 -0
  407. package/src/store/env.ts +11 -0
  408. package/src/store/index.ts +14 -1
  409. package/src/store/internal.ts +13 -0
  410. package/src/store/primitive-predicates.test.ts +184 -0
  411. package/src/store/primitive-predicates.ts +43 -0
  412. package/src/store/runtime-clients/attachment-runtime-client.test.ts +41 -0
  413. package/src/store/runtime-clients/attachment-runtime-client.ts +2 -1
  414. package/src/store/runtime-clients/handle-runtime-action.ts +11 -0
  415. package/src/store/runtime-clients/handle-thread-list-action.test.ts +69 -0
  416. package/src/store/runtime-clients/handle-thread-list-action.ts +6 -0
  417. package/src/store/runtime-clients/thread-list-item-runtime-client.ts +28 -35
  418. package/src/store/runtime-clients/thread-list-runtime-client.ts +9 -6
  419. package/src/store/runtime-clients/thread-runtime-client.ts +5 -0
  420. package/src/store/scopes/composer.ts +9 -4
  421. package/src/store/scopes/suggestions.ts +6 -0
  422. package/src/store/scopes/thread-list-item.ts +7 -6
  423. package/src/store/scopes/thread.ts +25 -7
  424. package/src/store/scopes/threads.ts +14 -0
  425. package/src/subscribable/subscribable.test.ts +77 -1
  426. package/src/subscribable/subscribable.ts +38 -23
  427. package/src/tests/RemoteThreadListThreadListRuntimeCore-switchToThread-unarchive.test.ts +25 -0
  428. package/src/tests/append-interactable-snapshots.test.ts +350 -0
  429. package/src/tests/auiV0Encode.test.ts +66 -0
  430. package/src/tests/base-composer-runtime-core-send.test.ts +156 -0
  431. package/src/tests/base-composer-runtime-core.test.ts +136 -1
  432. package/src/tests/composer-can-cancel.test.ts +101 -0
  433. package/src/tests/default-edit-composer-runtime-core.test.ts +0 -68
  434. package/src/tests/external-store-thread-list-runtime-core.test.ts +101 -0
  435. package/src/tests/external-store-thread-runtime-core-adapter.test.ts +491 -1
  436. package/src/tests/external-store-thread-runtime-core.test.ts +124 -0
  437. package/src/tests/external-thread-attachments.test.tsx +214 -0
  438. package/src/tests/external-thread-parity.test.tsx +54 -0
  439. package/src/tests/external-thread-refetch.test.tsx +117 -0
  440. package/src/tests/external-thread-suggestions.test.tsx +59 -0
  441. package/src/tests/interactables-toolui-migration.test.tsx +66 -0
  442. package/src/tests/message-queue.test.ts +54 -0
  443. package/src/tests/session-reset-notification.test.ts +145 -0
  444. package/src/tests/thread-message-like.test.ts +39 -0
  445. package/src/tests/thread-switch-events.test.tsx +234 -0
  446. package/src/tests/tools-scope-migration.test.tsx +58 -0
  447. package/src/types/error.ts +24 -0
  448. package/src/types/message.ts +2 -0
  449. package/src/utils/composite-context-provider.test.ts +139 -0
  450. package/src/utils/composite-context-provider.ts +26 -8
  451. package/src/utils/notify-event-listeners.ts +10 -5
  452. package/src/tests/default-thread-composer-runtime-core.test.ts +0 -82
@@ -1,25 +1,41 @@
1
1
  import { mergeModelContexts } from "../model-context/types.js";
2
+ import { notifySubscribers } from "../subscribable/subscribable.js";
2
3
  //#region src/utils/composite-context-provider.ts
3
4
  var CompositeContextProvider = class {
4
- _providers = /* @__PURE__ */ new Set();
5
+ _providers = /* @__PURE__ */ new Map();
6
+ _providerUnsubscribes = /* @__PURE__ */ new Map();
5
7
  getModelContext() {
6
- return mergeModelContexts(this._providers);
8
+ return mergeModelContexts(new Set(this._providers.values()));
7
9
  }
8
10
  registerModelContextProvider(provider) {
9
- this._providers.add(provider);
10
- const unsubscribe = provider.subscribe?.(() => {
11
- this.notifySubscribers();
12
- });
11
+ const id = Symbol();
12
+ this._providers.set(id, provider);
13
+ let unsubscribe;
14
+ try {
15
+ unsubscribe = provider.subscribe?.(() => {
16
+ this.notifySubscribers();
17
+ });
18
+ } catch (error) {
19
+ this._providers.delete(id);
20
+ try {
21
+ this.notifySubscribers();
22
+ } catch (notifyError) {
23
+ console.error(notifyError);
24
+ }
25
+ throw error;
26
+ }
27
+ this._providerUnsubscribes.set(id, unsubscribe);
13
28
  this.notifySubscribers();
14
29
  return () => {
15
- this._providers.delete(provider);
16
- unsubscribe?.();
30
+ this._providers.delete(id);
31
+ this._providerUnsubscribes.get(id)?.();
32
+ this._providerUnsubscribes.delete(id);
17
33
  this.notifySubscribers();
18
34
  };
19
35
  }
20
36
  _subscribers = /* @__PURE__ */ new Set();
21
37
  notifySubscribers() {
22
- for (const callback of this._subscribers) callback();
38
+ notifySubscribers(this._subscribers);
23
39
  }
24
40
  subscribe(callback) {
25
41
  this._subscribers.add(callback);
@@ -1 +1 @@
1
- {"version":3,"file":"composite-context-provider.js","names":["ModelContextProvider","mergeModelContexts","CompositeContextProvider","_providers","Set","getModelContext","registerModelContextProvider","provider","add","unsubscribe","subscribe","notifySubscribers","delete","_subscribers","callback"],"sources":["../../src/utils/composite-context-provider.ts"],"sourcesContent":["import {\n type ModelContextProvider,\n mergeModelContexts,\n} from \"../model-context/types\";\n\nexport class CompositeContextProvider implements ModelContextProvider {\n private _providers = new Set<ModelContextProvider>();\n\n getModelContext() {\n return mergeModelContexts(this._providers);\n }\n\n registerModelContextProvider(provider: ModelContextProvider) {\n this._providers.add(provider);\n const unsubscribe = provider.subscribe?.(() => {\n this.notifySubscribers();\n });\n this.notifySubscribers();\n return () => {\n this._providers.delete(provider);\n unsubscribe?.();\n this.notifySubscribers();\n };\n }\n\n private _subscribers = new Set<() => void>();\n\n notifySubscribers() {\n for (const callback of this._subscribers) callback();\n }\n\n subscribe(callback: () => void) {\n this._subscribers.add(callback);\n return () => {\n this._subscribers.delete(callback);\n };\n }\n}\n"],"mappings":";;AAKA,IAAaE,2BAAb,MAAsE;CACpE,6BAAqB,IAAIE,IAA0B;CAEnDC,kBAAkB;EAChB,OAAOJ,mBAAmB,KAAKE,UAAU;CAC3C;CAEAG,6BAA6BC,UAAgC;EAC3D,KAAKJ,WAAWK,IAAID,QAAQ;EAC5B,MAAME,cAAcF,SAASG,kBAAkB;GAC7C,KAAKC,kBAAkB;EACzB,CAAC;EACD,KAAKA,kBAAkB;EACvB,aAAa;GACX,KAAKR,WAAWS,OAAOL,QAAQ;GAC/BE,cAAc;GACd,KAAKE,kBAAkB;EACzB;CACF;CAEA,+BAAuB,IAAIP,IAAgB;CAE3CO,oBAAoB;EAClB,KAAK,MAAMG,YAAY,KAAKD,cAAcC,SAAS;CACrD;CAEAJ,UAAUI,UAAsB;EAC9B,KAAKD,aAAaL,IAAIM,QAAQ;EAC9B,aAAa;GACX,KAAKD,aAAaD,OAAOE,QAAQ;EACnC;CACF;AACF"}
1
+ {"version":3,"file":"composite-context-provider.js","names":["ModelContextProvider","mergeModelContexts","notifySubscribers","notifyStateSubscribers","Unsubscribe","CompositeContextProvider","_providers","Map","_providerUnsubscribes","getModelContext","Set","values","registerModelContextProvider","provider","id","Symbol","set","unsubscribe","subscribe","error","delete","notifyError","console","get","_subscribers","callback","add"],"sources":["../../src/utils/composite-context-provider.ts"],"sourcesContent":["import {\n type ModelContextProvider,\n mergeModelContexts,\n} from \"../model-context/types\";\nimport { notifySubscribers as notifyStateSubscribers } from \"../subscribable/subscribable\";\nimport type { Unsubscribe } from \"../types/unsubscribe\";\n\nexport class CompositeContextProvider implements ModelContextProvider {\n private _providers = new Map<symbol, ModelContextProvider>();\n private _providerUnsubscribes = new Map<symbol, Unsubscribe | undefined>();\n\n getModelContext() {\n return mergeModelContexts(new Set(this._providers.values()));\n }\n\n registerModelContextProvider(provider: ModelContextProvider) {\n const id = Symbol();\n this._providers.set(id, provider);\n let unsubscribe: Unsubscribe | undefined;\n try {\n unsubscribe = provider.subscribe?.(() => {\n this.notifySubscribers();\n });\n } catch (error) {\n this._providers.delete(id);\n try {\n this.notifySubscribers();\n } catch (notifyError) {\n console.error(notifyError);\n }\n throw error;\n }\n this._providerUnsubscribes.set(id, unsubscribe);\n this.notifySubscribers();\n return () => {\n this._providers.delete(id);\n const unsubscribe = this._providerUnsubscribes.get(id);\n unsubscribe?.();\n this._providerUnsubscribes.delete(id);\n this.notifySubscribers();\n };\n }\n\n private _subscribers = new Set<() => void>();\n\n notifySubscribers() {\n notifyStateSubscribers(this._subscribers);\n }\n\n subscribe(callback: () => void) {\n this._subscribers.add(callback);\n return () => {\n this._subscribers.delete(callback);\n };\n }\n}\n"],"mappings":";;;AAOA,IAAaK,2BAAb,MAAsE;CACpE,6BAAqB,IAAIE,IAAkC;CAC3D,wCAAgC,IAAIA,IAAqC;CAEzEE,kBAAkB;EAChB,OAAOR,mBAAmB,IAAIS,IAAI,KAAKJ,WAAWK,OAAO,CAAC,CAAC;CAC7D;CAEAC,6BAA6BC,UAAgC;EAC3D,MAAMC,KAAKC,OAAO;EAClB,KAAKT,WAAWU,IAAIF,IAAID,QAAQ;EAChC,IAAII;EACJ,IAAI;GACFA,cAAcJ,SAASK,kBAAkB;IACvC,KAAKhB,kBAAkB;GACzB,CAAC;EACH,SAASiB,OAAO;GACd,KAAKb,WAAWc,OAAON,EAAE;GACzB,IAAI;IACF,KAAKZ,kBAAkB;GACzB,SAASmB,aAAa;IACpBC,QAAQH,MAAME,WAAW;GAC3B;GACA,MAAMF;EACR;EACA,KAAKX,sBAAsBQ,IAAIF,IAAIG,WAAW;EAC9C,KAAKf,kBAAkB;EACvB,aAAa;GACX,KAAKI,WAAWc,OAAON,EAAE;GAEzBG,KADyBT,sBAAsBe,IAAIT,EACnDG,CAAW,GAAG;GACd,KAAKT,sBAAsBY,OAAON,EAAE;GACpC,KAAKZ,kBAAkB;EACzB;CACF;CAEA,+BAAuB,IAAIQ,IAAgB;CAE3CR,oBAAoB;EAClBC,kBAAuB,KAAKqB,YAAY;CAC1C;CAEAN,UAAUO,UAAsB;EAC9B,KAAKD,aAAaE,IAAID,QAAQ;EAC9B,aAAa;GACX,KAAKD,aAAaJ,OAAOK,QAAQ;EACnC;CACF;AACF"}
@@ -1,6 +1,6 @@
1
1
  //#region src/utils/notify-event-listeners.d.ts
2
- type EventListener = (payload?: unknown) => void;
3
- declare const notifyEventListeners: (listeners: Iterable<EventListener>, payload: unknown, errorContext: string) => void;
2
+ type EventListener<T> = (payload: T) => unknown;
3
+ declare const notifyEventListeners: <T>(listeners: Iterable<EventListener<T>>, payloadOrFactory: T | (() => T), errorContext: string) => void;
4
4
  //#endregion
5
5
  export { notifyEventListeners };
6
6
  //# sourceMappingURL=notify-event-listeners.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"notify-event-listeners.d.ts","names":[],"sources":["../../src/utils/notify-event-listeners.ts"],"mappings":";KAAK,iBAAiB;cAET,uBACX,WAAW,SAAS,gBACpB,kBACA"}
1
+ {"version":3,"file":"notify-event-listeners.d.ts","names":[],"sources":["../../src/utils/notify-event-listeners.ts"],"mappings":";KAAK,cAAc,MAAM,SAAS;cAGrB,uBAAwB,GACnC,WAAW,SAAS,cAAc,KAClC,kBAAkB,WAAW,IAC7B"}
@@ -1,10 +1,10 @@
1
1
  //#region src/utils/notify-event-listeners.ts
2
- const notifyEventListeners = (listeners, payload, errorContext) => {
2
+ const notifyEventListeners = (listeners, payloadOrFactory, errorContext) => {
3
3
  const reportError = (error) => {
4
4
  console.error(`[assistant-ui] ${errorContext} listener threw an error`, error);
5
5
  };
6
6
  for (const listener of listeners) try {
7
- const result = listener(payload);
7
+ const result = listener(typeof payloadOrFactory === "function" ? payloadOrFactory() : payloadOrFactory);
8
8
  if (result !== null && (typeof result === "object" || typeof result === "function") && "then" in result && typeof result.then === "function") Promise.resolve(result).catch(reportError);
9
9
  } catch (error) {
10
10
  reportError(error);
@@ -1 +1 @@
1
- {"version":3,"file":"notify-event-listeners.js","names":["EventListener","payload","notifyEventListeners","listeners","Iterable","errorContext","reportError","error","console","listener","result","then","Promise","resolve","catch"],"sources":["../../src/utils/notify-event-listeners.ts"],"sourcesContent":["type EventListener = (payload?: unknown) => void;\n\nexport const notifyEventListeners = (\n listeners: Iterable<EventListener>,\n payload: unknown,\n errorContext: string,\n) => {\n const reportError = (error: unknown) => {\n console.error(\n `[assistant-ui] ${errorContext} listener threw an error`,\n error,\n );\n };\n\n for (const listener of listeners) {\n try {\n const result = listener(payload) as unknown;\n if (\n result !== null &&\n (typeof result === \"object\" || typeof result === \"function\") &&\n \"then\" in result &&\n typeof result.then === \"function\"\n ) {\n void Promise.resolve(result).catch(reportError);\n }\n } catch (error) {\n reportError(error);\n }\n }\n};\n"],"mappings":";AAEA,MAAaE,wBACXC,WACAF,SACAI,iBACG;CACH,MAAMC,eAAeC,UAAmB;EACtCC,QAAQD,MACN,kBAAkBF,aAAY,2BAC9BE,KACF;CACF;CAEA,KAAK,MAAME,YAAYN,WACrB,IAAI;EACF,MAAMO,SAASD,SAASR,OAAO;EAC/B,IACES,WAAW,SACV,OAAOA,WAAW,YAAY,OAAOA,WAAW,eACjD,UAAUA,UACV,OAAOA,OAAOC,SAAS,YAEvB,QAAaE,QAAQH,MAAM,CAAC,CAACI,MAAMR,WAAW;CAElD,SAASC,OAAO;EACdD,YAAYC,KAAK;CACnB;AAEJ"}
1
+ {"version":3,"file":"notify-event-listeners.js","names":["EventListener","payload","T","notifyEventListeners","listeners","Iterable","payloadOrFactory","errorContext","reportError","error","console","listener","result","then","Promise","resolve","catch"],"sources":["../../src/utils/notify-event-listeners.ts"],"sourcesContent":["type EventListener<T> = (payload: T) => unknown;\n\n// A function payload is indistinguishable from a factory and gets invoked; wrap a function-typed payload in a factory.\nexport const notifyEventListeners = <T>(\n listeners: Iterable<EventListener<T>>,\n payloadOrFactory: T | (() => T),\n errorContext: string,\n) => {\n const reportError = (error: unknown) => {\n console.error(\n `[assistant-ui] ${errorContext} listener threw an error`,\n error,\n );\n };\n\n for (const listener of listeners) {\n try {\n const result = listener(\n typeof payloadOrFactory === \"function\"\n ? (payloadOrFactory as () => T)()\n : payloadOrFactory,\n );\n if (\n result !== null &&\n (typeof result === \"object\" || typeof result === \"function\") &&\n \"then\" in result &&\n typeof result.then === \"function\"\n ) {\n void Promise.resolve(result).catch(reportError);\n }\n } catch (error) {\n reportError(error);\n }\n }\n};\n"],"mappings":";AAGA,MAAaG,wBACXC,WACAE,kBACAC,iBACG;CACH,MAAMC,eAAeC,UAAmB;EACtCC,QAAQD,MACN,kBAAkBF,aAAY,2BAC9BE,KACF;CACF;CAEA,KAAK,MAAME,YAAYP,WACrB,IAAI;EACF,MAAMQ,SAASD,SACb,OAAOL,qBAAqB,aACvBA,iBAA6B,IAC9BA,gBACN;EACA,IACEM,WAAW,SACV,OAAOA,WAAW,YAAY,OAAOA,WAAW,eACjD,UAAUA,UACV,OAAOA,OAAOC,SAAS,YAEvB,QAAaE,QAAQH,MAAM,CAAC,CAACI,MAAMR,WAAW;CAElD,SAASC,OAAO;EACdD,YAAYC,KAAK;CACnB;AAEJ"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@assistant-ui/core",
3
- "version": "0.3.12",
3
+ "version": "0.3.14",
4
4
  "description": "Framework-agnostic core runtime for assistant-ui",
5
5
  "keywords": [
6
6
  "assistant",
@@ -59,7 +59,7 @@
59
59
  ],
60
60
  "sideEffects": false,
61
61
  "dependencies": {
62
- "assistant-stream": "^0.3.37",
62
+ "assistant-stream": "^0.3.38",
63
63
  "nanoid": "^6.0.1"
64
64
  },
65
65
  "optionalDevDependencies": {
@@ -95,11 +95,11 @@
95
95
  "react-dom": "^19.2.8",
96
96
  "vitest": "^4.1.10",
97
97
  "zustand": "^5.0.14",
98
- "@assistant-ui/store": "0.3.8",
99
- "@assistant-ui/tap": "0.9.11",
100
- "@assistant-ui/vite": "0.0.12",
101
- "@assistant-ui/x-buildutils": "0.0.22",
102
- "assistant-cloud": "0.1.39"
98
+ "@assistant-ui/store": "0.3.10",
99
+ "@assistant-ui/tap": "0.9.13",
100
+ "@assistant-ui/vite": "0.0.14",
101
+ "@assistant-ui/x-buildutils": "0.0.23",
102
+ "assistant-cloud": "0.1.41"
103
103
  },
104
104
  "publishConfig": {
105
105
  "access": "public",
@@ -1,5 +1,5 @@
1
1
  import { afterEach, describe, expect, it, vi } from "vitest";
2
- import { WebSpeechSynthesisAdapter } from "./speech";
2
+ import { WebSpeechDictationAdapter, WebSpeechSynthesisAdapter } from "./speech";
3
3
 
4
4
  afterEach(() => {
5
5
  vi.restoreAllMocks();
@@ -86,3 +86,120 @@ describe("WebSpeechSynthesisAdapter", () => {
86
86
  );
87
87
  });
88
88
  });
89
+
90
+ describe("WebSpeechDictationAdapter", () => {
91
+ const stubSpeechRecognition = () => {
92
+ const listeners = new Map<string, EventListener>();
93
+ class MockSpeechRecognition {
94
+ lang = "";
95
+ continuous = false;
96
+ interimResults = false;
97
+
98
+ addEventListener(type: string, listener: EventListener) {
99
+ listeners.set(type, listener);
100
+ }
101
+
102
+ start() {}
103
+ stop() {}
104
+ abort() {}
105
+ }
106
+ vi.stubGlobal("window", {
107
+ SpeechRecognition: MockSpeechRecognition,
108
+ });
109
+ return listeners;
110
+ };
111
+
112
+ it("continues notifying dictation listeners when one throws", () => {
113
+ const listeners = stubSpeechRecognition();
114
+ const listenerError = new Error("listener failed");
115
+ const consoleError = vi
116
+ .spyOn(console, "error")
117
+ .mockImplementation(() => {});
118
+ const session = new WebSpeechDictationAdapter().listen();
119
+ const laterStartListener = vi.fn();
120
+ const laterSpeechListener = vi.fn();
121
+ const laterEndListener = vi.fn();
122
+
123
+ session.onSpeechStart(() => {
124
+ throw listenerError;
125
+ });
126
+ session.onSpeechStart(laterStartListener);
127
+ session.onSpeech(() => {
128
+ throw listenerError;
129
+ });
130
+ session.onSpeech(laterSpeechListener);
131
+ session.onSpeechEnd(() => {
132
+ throw listenerError;
133
+ });
134
+ session.onSpeechEnd(laterEndListener);
135
+
136
+ const event = {
137
+ resultIndex: 0,
138
+ results: [
139
+ {
140
+ 0: { transcript: "Hello" },
141
+ isFinal: true,
142
+ },
143
+ ],
144
+ } as unknown as Event;
145
+
146
+ expect(() =>
147
+ listeners.get("speechstart")?.(new Event("speechstart")),
148
+ ).not.toThrow();
149
+ expect(() => listeners.get("result")?.(event)).not.toThrow();
150
+ expect(() => listeners.get("end")?.(new Event("end"))).not.toThrow();
151
+
152
+ expect(laterStartListener).toHaveBeenCalledOnce();
153
+ expect(laterSpeechListener).toHaveBeenCalledWith({
154
+ transcript: "Hello",
155
+ isFinal: true,
156
+ });
157
+ expect(laterEndListener).toHaveBeenCalledWith({
158
+ transcript: "Hello",
159
+ });
160
+ expect(consoleError).toHaveBeenCalledTimes(3);
161
+ expect(consoleError).toHaveBeenCalledWith(
162
+ "[assistant-ui] Dictation listener threw an error",
163
+ listenerError,
164
+ );
165
+ });
166
+
167
+ it("isolates async failures and payload mutations", async () => {
168
+ const listeners = stubSpeechRecognition();
169
+ const listenerError = new Error("async listener failed");
170
+ const consoleError = vi
171
+ .spyOn(console, "error")
172
+ .mockImplementation(() => {});
173
+ const session = new WebSpeechDictationAdapter().listen();
174
+ const laterListener = vi.fn();
175
+
176
+ session.onSpeech(async (result) => {
177
+ result.transcript = "Changed";
178
+ result.isFinal = false;
179
+ throw listenerError;
180
+ });
181
+ session.onSpeech(laterListener);
182
+
183
+ const event = {
184
+ resultIndex: 0,
185
+ results: [
186
+ {
187
+ 0: { transcript: "Hello" },
188
+ isFinal: true,
189
+ },
190
+ ],
191
+ } as unknown as Event;
192
+
193
+ expect(() => listeners.get("result")?.(event)).not.toThrow();
194
+ expect(laterListener).toHaveBeenCalledWith({
195
+ transcript: "Hello",
196
+ isFinal: true,
197
+ });
198
+ await vi.waitFor(() => {
199
+ expect(consoleError).toHaveBeenCalledWith(
200
+ "[assistant-ui] Dictation listener threw an error",
201
+ listenerError,
202
+ );
203
+ });
204
+ });
205
+ });
@@ -1,4 +1,5 @@
1
1
  import type { Unsubscribe } from "../types/unsubscribe";
2
+ import { notifyEventListeners } from "../utils/notify-event-listeners";
2
3
 
3
4
  export namespace SpeechSynthesisAdapter {
4
5
  export type Status =
@@ -22,21 +23,6 @@ export type SpeechSynthesisAdapter = {
22
23
  speak: (text: string) => SpeechSynthesisAdapter.Utterance;
23
24
  };
24
25
 
25
- const notifySpeechSynthesisListeners = (
26
- listeners: Iterable<() => void>,
27
- ): void => {
28
- for (const listener of listeners) {
29
- try {
30
- listener();
31
- } catch (error) {
32
- console.error(
33
- "[assistant-ui] Speech synthesis listener threw an error",
34
- error,
35
- );
36
- }
37
- }
38
- };
39
-
40
26
  export namespace DictationAdapter {
41
27
  export type Status =
42
28
  | {
@@ -79,7 +65,7 @@ export class WebSpeechSynthesisAdapter implements SpeechSynthesisAdapter {
79
65
  if (res.status.type === "ended") return;
80
66
 
81
67
  res.status = { type: "ended", reason, error };
82
- notifySpeechSynthesisListeners(subscribers);
68
+ notifyEventListeners(subscribers, undefined, "Speech synthesis");
83
69
  };
84
70
 
85
71
  utterance.addEventListener("end", () => handleEnd("finished"));
@@ -97,7 +83,9 @@ export class WebSpeechSynthesisAdapter implements SpeechSynthesisAdapter {
97
83
  if (res.status.type === "ended") {
98
84
  let cancelled = false;
99
85
  queueMicrotask(() => {
100
- if (!cancelled) notifySpeechSynthesisListeners([callback]);
86
+ if (!cancelled) {
87
+ notifyEventListeners([callback], undefined, "Speech synthesis");
88
+ }
101
89
  });
102
90
  return () => {
103
91
  cancelled = true;
@@ -270,7 +258,7 @@ export class WebSpeechDictationAdapter implements DictationAdapter {
270
258
  };
271
259
 
272
260
  recognition.addEventListener("speechstart", () => {
273
- for (const cb of speechStartCallbacks) cb();
261
+ notifyEventListeners(speechStartCallbacks, undefined, "Dictation");
274
262
  });
275
263
 
276
264
  recognition.addEventListener("start", () => {
@@ -292,9 +280,17 @@ export class WebSpeechDictationAdapter implements DictationAdapter {
292
280
 
293
281
  if (result.isFinal) {
294
282
  finalTranscript += transcript;
295
- for (const cb of speechCallbacks) cb({ transcript, isFinal: true });
283
+ notifyEventListeners(
284
+ speechCallbacks,
285
+ () => ({ transcript, isFinal: true }),
286
+ "Dictation",
287
+ );
296
288
  } else {
297
- for (const cb of speechCallbacks) cb({ transcript, isFinal: false });
289
+ notifyEventListeners(
290
+ speechCallbacks,
291
+ () => ({ transcript, isFinal: false }),
292
+ "Dictation",
293
+ );
298
294
  }
299
295
  }
300
296
  });
@@ -309,8 +305,11 @@ export class WebSpeechDictationAdapter implements DictationAdapter {
309
305
  updateStatus({ type: "ended", reason: "stopped" });
310
306
  }
311
307
  if (finalTranscript) {
312
- for (const cb of speechEndCallbacks)
313
- cb({ transcript: finalTranscript });
308
+ notifyEventListeners(
309
+ speechEndCallbacks,
310
+ () => ({ transcript: finalTranscript }),
311
+ "Dictation",
312
+ );
314
313
  finalTranscript = "";
315
314
  }
316
315
  });
@@ -39,6 +39,8 @@ export interface MessageFormatAdapter<
39
39
 
40
40
  export type GenericThreadHistoryAdapter<TMessage> = {
41
41
  load(): Promise<MessageFormatRepository<TMessage>>;
42
+ /** Snapshot the current thread so later writes survive a switch. */
43
+ pin?(): void;
42
44
  append(item: MessageFormatItem<TMessage>): Promise<void>;
43
45
  update?(
44
46
  item: MessageFormatItem<TMessage>,
@@ -73,6 +73,75 @@ describe("createVoiceSession", () => {
73
73
  expect(controls.mute).not.toHaveBeenCalled();
74
74
  });
75
75
 
76
+ it("removes the abort listener after disconnecting", async () => {
77
+ const abortController = new AbortController();
78
+ const controls = {
79
+ disconnect: vi.fn(),
80
+ mute: vi.fn(),
81
+ unmute: vi.fn(),
82
+ };
83
+ const session = createVoiceSession(
84
+ { abortSignal: abortController.signal },
85
+ async () => controls,
86
+ );
87
+ await Promise.resolve();
88
+
89
+ session.disconnect();
90
+ session.disconnect();
91
+ abortController.abort();
92
+
93
+ expect(controls.disconnect).toHaveBeenCalledOnce();
94
+ });
95
+
96
+ it("keeps abort teardown available after the session ends", async () => {
97
+ const abortController = new AbortController();
98
+ const controls = {
99
+ disconnect: vi.fn(),
100
+ mute: vi.fn(),
101
+ unmute: vi.fn(),
102
+ };
103
+ let helpers: VoiceSessionHelpers | undefined;
104
+ createVoiceSession(
105
+ { abortSignal: abortController.signal },
106
+ async (sessionHelpers) => {
107
+ helpers = sessionHelpers;
108
+ return controls;
109
+ },
110
+ );
111
+ await Promise.resolve();
112
+ if (!helpers) throw new Error("Voice session setup did not start");
113
+
114
+ helpers.end("error");
115
+ abortController.abort();
116
+
117
+ expect(controls.disconnect).toHaveBeenCalledOnce();
118
+ });
119
+
120
+ it("cleans up when the adapter disconnect throws", async () => {
121
+ const disconnectError = new Error("disconnect failed");
122
+ let helpers: VoiceSessionHelpers | undefined;
123
+ const session = createVoiceSession({}, async (sessionHelpers) => {
124
+ helpers = sessionHelpers;
125
+ return {
126
+ disconnect: () => {
127
+ throw disconnectError;
128
+ },
129
+ mute: vi.fn(),
130
+ unmute: vi.fn(),
131
+ };
132
+ });
133
+ await Promise.resolve();
134
+ if (!helpers) throw new Error("Voice session setup did not start");
135
+ const transcriptListener = vi.fn();
136
+ session.onTranscript(transcriptListener);
137
+
138
+ expect(() => session.disconnect()).toThrow(disconnectError);
139
+ expect(helpers.isDisposed()).toBe(true);
140
+
141
+ helpers.emitTranscript({ role: "assistant", text: "stale" });
142
+ expect(transcriptListener).not.toHaveBeenCalled();
143
+ });
144
+
76
145
  it("continues notifying listeners when one throws", () => {
77
146
  const listenerError = new Error("listener failed");
78
147
  const consoleError = vi
@@ -1,4 +1,5 @@
1
1
  import type { Unsubscribe } from "../types/unsubscribe";
2
+ import { notifyEventListeners } from "../utils/notify-event-listeners";
2
3
 
3
4
  export namespace RealtimeVoiceAdapter {
4
5
  export type Status =
@@ -57,22 +58,6 @@ export type VoiceSessionHelpers = {
57
58
  isDisposed: () => boolean;
58
59
  };
59
60
 
60
- const notifyListeners = <T>(
61
- listeners: ReadonlySet<(value: T) => void>,
62
- value: T,
63
- ) => {
64
- for (const listener of listeners) {
65
- try {
66
- listener(value);
67
- } catch (error) {
68
- console.error(
69
- "[assistant-ui] Voice session listener threw an error",
70
- error,
71
- );
72
- }
73
- }
74
- };
75
-
76
61
  export function createVoiceSession(
77
62
  options: { abortSignal?: AbortSignal },
78
63
  setup: (helpers: VoiceSessionHelpers) => Promise<VoiceSessionControls>,
@@ -87,7 +72,17 @@ export function createVoiceSession(
87
72
  let currentStatus: RealtimeVoiceAdapter.Status = { type: "starting" };
88
73
  let isMuted = false;
89
74
  let disposed = false;
75
+ let disconnected = false;
90
76
  let controls: VoiceSessionControls | null = null;
77
+ const abortSignal = options.abortSignal;
78
+ let abortHandler: (() => void) | undefined;
79
+
80
+ const detachAbortHandler = () => {
81
+ if (abortHandler) {
82
+ abortSignal?.removeEventListener("abort", abortHandler);
83
+ abortHandler = undefined;
84
+ }
85
+ };
91
86
 
92
87
  const cleanup = () => {
93
88
  disposed = true;
@@ -101,25 +96,25 @@ export function createVoiceSession(
101
96
  setStatus: (status) => {
102
97
  if (disposed) return;
103
98
  currentStatus = status;
104
- notifyListeners(statusCbs, status);
99
+ notifyEventListeners(statusCbs, status, "Voice session");
105
100
  },
106
101
  end: (reason, error?) => {
107
102
  if (disposed) return;
108
103
  currentStatus = { type: "ended", reason, error };
109
- notifyListeners(statusCbs, currentStatus);
104
+ notifyEventListeners(statusCbs, currentStatus, "Voice session");
110
105
  cleanup();
111
106
  },
112
107
  emitTranscript: (item) => {
113
108
  if (disposed) return;
114
- notifyListeners(transcriptCbs, item);
109
+ notifyEventListeners(transcriptCbs, item, "Voice session");
115
110
  },
116
111
  emitMode: (mode) => {
117
112
  if (disposed) return;
118
- notifyListeners(modeCbs, mode);
113
+ notifyEventListeners(modeCbs, mode, "Voice session");
119
114
  },
120
115
  emitVolume: (volume) => {
121
116
  if (disposed) return;
122
- notifyListeners(volumeCbs, volume);
117
+ notifyEventListeners(volumeCbs, volume, "Voice session");
123
118
  },
124
119
  isDisposed: () => disposed,
125
120
  };
@@ -132,8 +127,14 @@ export function createVoiceSession(
132
127
  return isMuted;
133
128
  },
134
129
  disconnect: () => {
135
- controls?.disconnect();
136
- cleanup();
130
+ if (disconnected) return;
131
+ disconnected = true;
132
+ detachAbortHandler();
133
+ try {
134
+ controls?.disconnect();
135
+ } finally {
136
+ cleanup();
137
+ }
137
138
  },
138
139
  mute: () => {
139
140
  controls?.mute();
@@ -161,10 +162,9 @@ export function createVoiceSession(
161
162
  },
162
163
  };
163
164
 
164
- if (options.abortSignal) {
165
- options.abortSignal.addEventListener("abort", () => session.disconnect(), {
166
- once: true,
167
- });
165
+ if (abortSignal) {
166
+ abortHandler = () => session.disconnect();
167
+ abortSignal.addEventListener("abort", abortHandler, { once: true });
168
168
  }
169
169
 
170
170
  const doSetup = async () => {
package/src/index.ts CHANGED
@@ -208,6 +208,7 @@ export type {
208
208
  AssistantError,
209
209
  } from "./types/error";
210
210
  export { toAssistantError, isAssistantError } from "./types/error";
211
+ export { MessageNotSentError, isMessageNotSentError } from "./types/error";
211
212
 
212
213
  export type {
213
214
  RuntimeCapabilities,
@@ -346,6 +347,7 @@ export {
346
347
  // Remote Thread List (user-facing)
347
348
  export type {
348
349
  RemoteThreadListAdapter,
350
+ RuntimeAdapters,
349
351
  RemoteThreadListOptions,
350
352
  RemoteThreadListProviderComponent,
351
353
  RemoteThreadInitializeResponse,
@@ -144,4 +144,27 @@ describe("AssistantFrameHost", () => {
144
144
  );
145
145
  expect(postMessage).toHaveBeenCalledOnce();
146
146
  });
147
+
148
+ it("isolates subscriber errors while applying context updates", () => {
149
+ const { dispatchMessage, host } = createHost();
150
+ const error = new Error("subscriber failed");
151
+ const laterSubscriber = vi.fn();
152
+
153
+ host.subscribe(() => {
154
+ throw error;
155
+ });
156
+ host.subscribe(laterSubscriber);
157
+
158
+ expect(() =>
159
+ dispatchMessage({
160
+ type: "model-context-update",
161
+ context: { system: "frame instructions" },
162
+ }),
163
+ ).toThrow(error);
164
+
165
+ expect(host.getModelContext().system).toBe("frame instructions");
166
+ expect(laterSubscriber).toHaveBeenCalledOnce();
167
+
168
+ host.dispose();
169
+ });
147
170
  });
@@ -1,6 +1,7 @@
1
1
  import type { ModelContextProvider, ModelContext } from "../types";
2
2
  import type { Unsubscribe } from "../../types/unsubscribe";
3
3
  import type { Tool } from "assistant-stream";
4
+ import { notifySubscribers as notifyStateSubscribers } from "../../subscribable/subscribable";
4
5
  import {
5
6
  type FrameMessage,
6
7
  FRAME_MESSAGE_CHANNEL,
@@ -207,7 +208,7 @@ export class AssistantFrameHost implements ModelContextProvider {
207
208
  }
208
209
 
209
210
  private notifySubscribers() {
210
- this._subscribers.forEach((callback) => callback());
211
+ notifyStateSubscribers(this._subscribers);
211
212
  }
212
213
 
213
214
  getModelContext(): ModelContext {