@assistant-ui/core 0.3.13 → 0.3.15

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 (463) 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 +38 -15
  8. package/dist/adapters/voice.js.map +1 -1
  9. package/dist/index.d.ts +2 -2
  10. package/dist/index.js +1 -1
  11. package/dist/index.js.map +1 -1
  12. package/dist/internal.d.ts +3 -2
  13. package/dist/internal.js +8 -7
  14. package/dist/model-context/frame/host.d.ts +1 -1
  15. package/dist/model-context/frame/host.d.ts.map +1 -1
  16. package/dist/model-context/frame/host.js +19 -4
  17. package/dist/model-context/frame/host.js.map +1 -1
  18. package/dist/model-context/frame/provider.d.ts +4 -0
  19. package/dist/model-context/frame/provider.d.ts.map +1 -1
  20. package/dist/model-context/frame/provider.js +50 -3
  21. package/dist/model-context/frame/provider.js.map +1 -1
  22. package/dist/model-context/frame/types.d.ts +4 -1
  23. package/dist/model-context/frame/types.d.ts.map +1 -1
  24. package/dist/model-context/frame/types.js.map +1 -1
  25. package/dist/model-context/registry.d.ts.map +1 -1
  26. package/dist/model-context/registry.js +16 -4
  27. package/dist/model-context/registry.js.map +1 -1
  28. package/dist/react/RuntimeAdapter.d.ts +8 -1
  29. package/dist/react/RuntimeAdapter.d.ts.map +1 -1
  30. package/dist/react/RuntimeAdapter.js +23 -18
  31. package/dist/react/RuntimeAdapter.js.map +1 -1
  32. package/dist/react/adapters/LocalStorageThreadListAdapter.d.ts.map +1 -1
  33. package/dist/react/adapters/LocalStorageThreadListAdapter.js +28 -12
  34. package/dist/react/adapters/LocalStorageThreadListAdapter.js.map +1 -1
  35. package/dist/react/client/AdaptedRemoteThread.d.ts +11 -0
  36. package/dist/react/client/AdaptedRemoteThread.d.ts.map +1 -0
  37. package/dist/react/client/AdaptedRemoteThread.js +27 -0
  38. package/dist/react/client/AdaptedRemoteThread.js.map +1 -0
  39. package/dist/react/client/InMemoryThreadList.d.ts +19 -0
  40. package/dist/react/client/InMemoryThreadList.d.ts.map +1 -0
  41. package/dist/react/client/InMemoryThreadList.js +418 -0
  42. package/dist/react/client/InMemoryThreadList.js.map +1 -0
  43. package/dist/react/client/Interactables.d.ts.map +1 -1
  44. package/dist/react/client/Interactables.js +159 -102
  45. package/dist/react/client/Interactables.js.map +1 -1
  46. package/dist/react/client/RemoteThreadList.d.ts +34 -0
  47. package/dist/react/client/RemoteThreadList.d.ts.map +1 -0
  48. package/dist/react/client/RemoteThreadList.js +898 -0
  49. package/dist/react/client/RemoteThreadList.js.map +1 -0
  50. package/dist/react/client/Tools.d.ts.map +1 -1
  51. package/dist/react/client/Tools.js +38 -27
  52. package/dist/react/client/Tools.js.map +1 -1
  53. package/dist/react/index.d.ts +7 -2
  54. package/dist/react/index.js +5 -2
  55. package/dist/react/interactables-legacy/Interactables.d.ts.map +1 -1
  56. package/dist/react/interactables-legacy/Interactables.js +145 -110
  57. package/dist/react/interactables-legacy/Interactables.js.map +1 -1
  58. package/dist/react/primitive-hooks/useActionBarCopy.d.ts.map +1 -1
  59. package/dist/react/primitive-hooks/useActionBarCopy.js +20 -19
  60. package/dist/react/primitive-hooks/useActionBarCopy.js.map +1 -1
  61. package/dist/react/primitive-hooks/useActionBarEdit.d.ts.map +1 -1
  62. package/dist/react/primitive-hooks/useActionBarEdit.js +2 -4
  63. package/dist/react/primitive-hooks/useActionBarEdit.js.map +1 -1
  64. package/dist/react/primitive-hooks/useActionBarReload.d.ts.map +1 -1
  65. package/dist/react/primitive-hooks/useActionBarReload.js +2 -4
  66. package/dist/react/primitive-hooks/useActionBarReload.js.map +1 -1
  67. package/dist/react/primitive-hooks/useBranchPickerNext.d.ts.map +1 -1
  68. package/dist/react/primitive-hooks/useBranchPickerNext.js +2 -6
  69. package/dist/react/primitive-hooks/useBranchPickerNext.js.map +1 -1
  70. package/dist/react/primitive-hooks/useBranchPickerPrevious.d.ts.map +1 -1
  71. package/dist/react/primitive-hooks/useBranchPickerPrevious.js +2 -6
  72. package/dist/react/primitive-hooks/useBranchPickerPrevious.js.map +1 -1
  73. package/dist/react/primitive-hooks/useComposerCancel.d.ts.map +1 -1
  74. package/dist/react/primitive-hooks/useComposerCancel.js +2 -4
  75. package/dist/react/primitive-hooks/useComposerCancel.js.map +1 -1
  76. package/dist/react/primitive-hooks/useComposerSend.d.ts.map +1 -1
  77. package/dist/react/primitive-hooks/useComposerSend.js +2 -4
  78. package/dist/react/primitive-hooks/useComposerSend.js.map +1 -1
  79. package/dist/react/primitive-hooks/useSuggestionTrigger.d.ts.map +1 -1
  80. package/dist/react/primitive-hooks/useSuggestionTrigger.js +6 -2
  81. package/dist/react/primitive-hooks/useSuggestionTrigger.js.map +1 -1
  82. package/dist/react/primitive-hooks/useThreadIsEmpty.d.ts +3 -0
  83. package/dist/react/primitive-hooks/useThreadIsEmpty.d.ts.map +1 -1
  84. package/dist/react/primitive-hooks/useThreadIsEmpty.js +3 -0
  85. package/dist/react/primitive-hooks/useThreadIsEmpty.js.map +1 -1
  86. package/dist/react/primitive-hooks/useThreadIsRunning.d.ts +3 -0
  87. package/dist/react/primitive-hooks/useThreadIsRunning.d.ts.map +1 -1
  88. package/dist/react/primitive-hooks/useThreadIsRunning.js +3 -0
  89. package/dist/react/primitive-hooks/useThreadIsRunning.js.map +1 -1
  90. package/dist/react/primitives/message/MessageParts.d.ts +13 -0
  91. package/dist/react/primitives/message/MessageParts.d.ts.map +1 -1
  92. package/dist/react/primitives/message/MessageParts.js.map +1 -1
  93. package/dist/react/primitives/thread/ThreadMessages.d.ts.map +1 -1
  94. package/dist/react/primitives/thread/ThreadMessages.js +1 -1
  95. package/dist/react/primitives/thread/ThreadMessages.js.map +1 -1
  96. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.d.ts +24 -10
  97. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.d.ts.map +1 -1
  98. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js +115 -71
  99. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js.map +1 -1
  100. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts +14 -2
  101. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts.map +1 -1
  102. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js +232 -63
  103. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js.map +1 -1
  104. package/dist/react/runtimes/RemoteThreadResource.d.ts +30 -0
  105. package/dist/react/runtimes/RemoteThreadResource.d.ts.map +1 -0
  106. package/dist/react/runtimes/RemoteThreadResource.js +136 -0
  107. package/dist/react/runtimes/RemoteThreadResource.js.map +1 -0
  108. package/dist/react/runtimes/RuntimeAdapterProvider.d.ts +3 -10
  109. package/dist/react/runtimes/RuntimeAdapterProvider.d.ts.map +1 -1
  110. package/dist/react/runtimes/RuntimeAdapterProvider.js +3 -6
  111. package/dist/react/runtimes/RuntimeAdapterProvider.js.map +1 -1
  112. package/dist/react/runtimes/assistant-transport/commandQueue.d.ts +17 -0
  113. package/dist/react/runtimes/assistant-transport/commandQueue.d.ts.map +1 -0
  114. package/dist/react/runtimes/assistant-transport/commandQueue.js +55 -0
  115. package/dist/react/runtimes/assistant-transport/commandQueue.js.map +1 -0
  116. package/dist/react/runtimes/assistant-transport/replayBoundaryStream.d.ts +11 -0
  117. package/dist/react/runtimes/assistant-transport/replayBoundaryStream.d.ts.map +1 -0
  118. package/dist/react/runtimes/assistant-transport/replayBoundaryStream.js +165 -0
  119. package/dist/react/runtimes/assistant-transport/replayBoundaryStream.js.map +1 -0
  120. package/dist/react/runtimes/assistant-transport/runManager.d.ts +15 -0
  121. package/dist/react/runtimes/assistant-transport/runManager.d.ts.map +1 -0
  122. package/dist/react/runtimes/assistant-transport/runManager.js +86 -0
  123. package/dist/react/runtimes/assistant-transport/runManager.js.map +1 -0
  124. package/dist/react/runtimes/assistant-transport/types.d.ts +130 -0
  125. package/dist/react/runtimes/assistant-transport/types.d.ts.map +1 -0
  126. package/dist/react/runtimes/assistant-transport/types.js +0 -0
  127. package/dist/react/runtimes/assistant-transport/useAssistantTransportRuntime.d.ts +14 -0
  128. package/dist/react/runtimes/assistant-transport/useAssistantTransportRuntime.d.ts.map +1 -0
  129. package/dist/react/runtimes/assistant-transport/useAssistantTransportRuntime.js +296 -0
  130. package/dist/react/runtimes/assistant-transport/useAssistantTransportRuntime.js.map +1 -0
  131. package/dist/react/runtimes/assistant-transport/useConvertedState.d.ts +7 -0
  132. package/dist/react/runtimes/assistant-transport/useConvertedState.d.ts.map +1 -0
  133. package/dist/react/runtimes/assistant-transport/useConvertedState.js +25 -0
  134. package/dist/react/runtimes/assistant-transport/useConvertedState.js.map +1 -0
  135. package/dist/react/runtimes/assistant-transport/useLatestRef.d.ts +7 -0
  136. package/dist/react/runtimes/assistant-transport/useLatestRef.d.ts.map +1 -0
  137. package/dist/react/runtimes/assistant-transport/useLatestRef.js +27 -0
  138. package/dist/react/runtimes/assistant-transport/useLatestRef.js.map +1 -0
  139. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.d.ts.map +1 -1
  140. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.js +39 -13
  141. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.js.map +1 -1
  142. package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.d.ts +2 -1
  143. package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.d.ts.map +1 -1
  144. package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.js +3 -3
  145. package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.js.map +1 -1
  146. package/dist/react/runtimes/cloud/auiV0.d.ts +4 -0
  147. package/dist/react/runtimes/cloud/auiV0.d.ts.map +1 -1
  148. package/dist/react/runtimes/cloud/auiV0.js +7 -0
  149. package/dist/react/runtimes/cloud/auiV0.js.map +1 -1
  150. package/dist/react/runtimes/cloud/useCloudThreadListAdapter.d.ts.map +1 -1
  151. package/dist/react/runtimes/cloud/useCloudThreadListAdapter.js +60 -17
  152. package/dist/react/runtimes/cloud/useCloudThreadListAdapter.js.map +1 -1
  153. package/dist/react/runtimes/cloud/useCloudThreadListRuntime.d.ts +16 -0
  154. package/dist/react/runtimes/cloud/useCloudThreadListRuntime.d.ts.map +1 -0
  155. package/dist/react/runtimes/cloud/useCloudThreadListRuntime.js +36 -0
  156. package/dist/react/runtimes/cloud/useCloudThreadListRuntime.js.map +1 -0
  157. package/dist/react/runtimes/external-message-converter.js +14 -14
  158. package/dist/react/runtimes/external-message-converter.js.map +1 -1
  159. package/dist/react/runtimes/useExternalStoreRuntime.d.ts.map +1 -1
  160. package/dist/react/runtimes/useExternalStoreRuntime.js +44 -28
  161. package/dist/react/runtimes/useExternalStoreRuntime.js.map +1 -1
  162. package/dist/react/runtimes/useExternalStoreSharedOptions.js.map +1 -1
  163. package/dist/react/runtimes/useLocalRuntime.js +1 -1
  164. package/dist/react/runtimes/useRuntimeAdapters.d.ts +9 -0
  165. package/dist/react/runtimes/useRuntimeAdapters.d.ts.map +1 -0
  166. package/dist/react/runtimes/useRuntimeAdapters.js +20 -0
  167. package/dist/react/runtimes/useRuntimeAdapters.js.map +1 -0
  168. package/dist/runtime/api/composer-runtime.d.ts +5 -0
  169. package/dist/runtime/api/composer-runtime.d.ts.map +1 -1
  170. package/dist/runtime/api/composer-runtime.js.map +1 -1
  171. package/dist/runtime/api/message-runtime.js +1 -1
  172. package/dist/runtime/api/thread-list-runtime.d.ts +1 -0
  173. package/dist/runtime/api/thread-list-runtime.d.ts.map +1 -1
  174. package/dist/runtime/api/thread-list-runtime.js +4 -2
  175. package/dist/runtime/api/thread-list-runtime.js.map +1 -1
  176. package/dist/runtime/api/thread-runtime.d.ts +12 -2
  177. package/dist/runtime/api/thread-runtime.d.ts.map +1 -1
  178. package/dist/runtime/api/thread-runtime.js +8 -2
  179. package/dist/runtime/api/thread-runtime.js.map +1 -1
  180. package/dist/runtime/base/base-composer-runtime-core.d.ts.map +1 -1
  181. package/dist/runtime/base/base-composer-runtime-core.js +8 -7
  182. package/dist/runtime/base/base-composer-runtime-core.js.map +1 -1
  183. package/dist/runtime/base/base-thread-runtime-core.d.ts +1 -0
  184. package/dist/runtime/base/base-thread-runtime-core.d.ts.map +1 -1
  185. package/dist/runtime/base/base-thread-runtime-core.js +3 -3
  186. package/dist/runtime/base/base-thread-runtime-core.js.map +1 -1
  187. package/dist/runtime/base/default-thread-composer-runtime-core.d.ts +0 -1
  188. package/dist/runtime/base/default-thread-composer-runtime-core.d.ts.map +1 -1
  189. package/dist/runtime/base/default-thread-composer-runtime-core.js +10 -4
  190. package/dist/runtime/base/default-thread-composer-runtime-core.js.map +1 -1
  191. package/dist/runtime/interfaces/thread-runtime-core.d.ts +6 -0
  192. package/dist/runtime/interfaces/thread-runtime-core.d.ts.map +1 -1
  193. package/dist/runtime/internal.js +5 -5
  194. package/dist/runtime/queue/message-queue.d.ts.map +1 -1
  195. package/dist/runtime/queue/message-queue.js +2 -1
  196. package/dist/runtime/queue/message-queue.js.map +1 -1
  197. package/dist/runtime/utils/message-repository.d.ts.map +1 -1
  198. package/dist/runtime/utils/message-repository.js +27 -18
  199. package/dist/runtime/utils/message-repository.js.map +1 -1
  200. package/dist/runtime/utils/thread-runtime-lifecycle.d.ts +8 -0
  201. package/dist/runtime/utils/thread-runtime-lifecycle.d.ts.map +1 -0
  202. package/dist/runtime/utils/thread-runtime-lifecycle.js +11 -0
  203. package/dist/runtime/utils/thread-runtime-lifecycle.js.map +1 -0
  204. package/dist/runtimes/external-store/external-store-shared-options.js.map +1 -1
  205. package/dist/runtimes/external-store/external-store-thread-list-runtime-core.d.ts.map +1 -1
  206. package/dist/runtimes/external-store/external-store-thread-list-runtime-core.js +4 -1
  207. package/dist/runtimes/external-store/external-store-thread-list-runtime-core.js.map +1 -1
  208. package/dist/runtimes/external-store/external-store-thread-runtime-core.d.ts +8 -0
  209. package/dist/runtimes/external-store/external-store-thread-runtime-core.d.ts.map +1 -1
  210. package/dist/runtimes/external-store/external-store-thread-runtime-core.js +37 -13
  211. package/dist/runtimes/external-store/external-store-thread-runtime-core.js.map +1 -1
  212. package/dist/runtimes/inert/InertThreadRuntimeCore.d.ts +102 -0
  213. package/dist/runtimes/inert/InertThreadRuntimeCore.d.ts.map +1 -0
  214. package/dist/runtimes/inert/InertThreadRuntimeCore.js +156 -0
  215. package/dist/runtimes/inert/InertThreadRuntimeCore.js.map +1 -0
  216. package/dist/runtimes/internal.d.ts +1 -1
  217. package/dist/runtimes/local/local-thread-runtime-core.d.ts +3 -0
  218. package/dist/runtimes/local/local-thread-runtime-core.d.ts.map +1 -1
  219. package/dist/runtimes/local/local-thread-runtime-core.js +78 -19
  220. package/dist/runtimes/local/local-thread-runtime-core.js.map +1 -1
  221. package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.d.ts +12 -59
  222. package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.d.ts.map +1 -1
  223. package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.js +10 -142
  224. package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.js.map +1 -1
  225. package/dist/runtimes/remote-thread-list/adapter-changed.d.ts +9 -0
  226. package/dist/runtimes/remote-thread-list/adapter-changed.d.ts.map +1 -0
  227. package/dist/runtimes/remote-thread-list/adapter-changed.js +13 -0
  228. package/dist/runtimes/remote-thread-list/adapter-changed.js.map +1 -0
  229. package/dist/runtimes/remote-thread-list/empty-thread-core.d.ts.map +1 -1
  230. package/dist/runtimes/remote-thread-list/empty-thread-core.js +16 -152
  231. package/dist/runtimes/remote-thread-list/empty-thread-core.js.map +1 -1
  232. package/dist/runtimes/remote-thread-list/optimistic-state.d.ts +2 -0
  233. package/dist/runtimes/remote-thread-list/optimistic-state.d.ts.map +1 -1
  234. package/dist/runtimes/remote-thread-list/optimistic-state.js +11 -0
  235. package/dist/runtimes/remote-thread-list/optimistic-state.js.map +1 -1
  236. package/dist/runtimes/remote-thread-list/types.d.ts +32 -1
  237. package/dist/runtimes/remote-thread-list/types.d.ts.map +1 -1
  238. package/dist/runtimes/tool-invocations/ToolInvocationTracker.d.ts +1 -12
  239. package/dist/runtimes/tool-invocations/ToolInvocationTracker.d.ts.map +1 -1
  240. package/dist/runtimes/tool-invocations/ToolInvocationTracker.js +67 -38
  241. package/dist/runtimes/tool-invocations/ToolInvocationTracker.js.map +1 -1
  242. package/dist/store/clients/external-thread.js +1 -1
  243. package/dist/store/clients/external-thread.js.map +1 -1
  244. package/dist/store/clients/suggestions.js +2 -2
  245. package/dist/store/clients/suggestions.js.map +1 -1
  246. package/dist/store/clients/thread-selection-events.d.ts +10 -0
  247. package/dist/store/clients/thread-selection-events.d.ts.map +1 -0
  248. package/dist/store/clients/thread-selection-events.js +40 -0
  249. package/dist/store/clients/thread-selection-events.js.map +1 -0
  250. package/dist/store/env.d.ts +5 -0
  251. package/dist/store/env.d.ts.map +1 -0
  252. package/dist/store/env.js +12 -0
  253. package/dist/store/env.js.map +1 -0
  254. package/dist/store/index.d.ts +5 -3
  255. package/dist/store/index.js +4 -2
  256. package/dist/store/internal.d.ts +4 -1
  257. package/dist/store/internal.js +4 -1
  258. package/dist/store/primitive-predicates.d.ts +19 -0
  259. package/dist/store/primitive-predicates.d.ts.map +1 -0
  260. package/dist/store/primitive-predicates.js +19 -0
  261. package/dist/store/primitive-predicates.js.map +1 -0
  262. package/dist/store/runtime-clients/attachment-runtime-client.d.ts.map +1 -1
  263. package/dist/store/runtime-clients/attachment-runtime-client.js +18 -11
  264. package/dist/store/runtime-clients/attachment-runtime-client.js.map +1 -1
  265. package/dist/store/runtime-clients/handle-runtime-action.d.ts +5 -0
  266. package/dist/store/runtime-clients/handle-runtime-action.d.ts.map +1 -0
  267. package/dist/store/runtime-clients/handle-runtime-action.js +14 -0
  268. package/dist/store/runtime-clients/handle-runtime-action.js.map +1 -0
  269. package/dist/store/runtime-clients/handle-thread-list-action.d.ts +5 -0
  270. package/dist/store/runtime-clients/handle-thread-list-action.d.ts.map +1 -0
  271. package/dist/store/runtime-clients/handle-thread-list-action.js +7 -0
  272. package/dist/store/runtime-clients/handle-thread-list-action.js.map +1 -0
  273. package/dist/store/runtime-clients/thread-list-item-runtime-client.d.ts.map +1 -1
  274. package/dist/store/runtime-clients/thread-list-item-runtime-client.js +62 -29
  275. package/dist/store/runtime-clients/thread-list-item-runtime-client.js.map +1 -1
  276. package/dist/store/runtime-clients/thread-list-runtime-client.d.ts.map +1 -1
  277. package/dist/store/runtime-clients/thread-list-runtime-client.js +5 -6
  278. package/dist/store/runtime-clients/thread-list-runtime-client.js.map +1 -1
  279. package/dist/store/scopes/composer.d.ts +9 -4
  280. package/dist/store/scopes/composer.d.ts.map +1 -1
  281. package/dist/store/scopes/thread-list-item.d.ts +7 -6
  282. package/dist/store/scopes/thread-list-item.d.ts.map +1 -1
  283. package/dist/store/scopes/thread.d.ts +8 -7
  284. package/dist/store/scopes/thread.d.ts.map +1 -1
  285. package/dist/store/scopes/threads.d.ts +17 -1
  286. package/dist/store/scopes/threads.d.ts.map +1 -1
  287. package/dist/subscribable/subscribable.d.ts +2 -1
  288. package/dist/subscribable/subscribable.d.ts.map +1 -1
  289. package/dist/subscribable/subscribable.js +23 -18
  290. package/dist/subscribable/subscribable.js.map +1 -1
  291. package/dist/types/message.d.ts +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/dist/utils/silent-runtime-action.d.ts +6 -0
  302. package/dist/utils/silent-runtime-action.d.ts.map +1 -0
  303. package/dist/utils/silent-runtime-action.js +7 -0
  304. package/dist/utils/silent-runtime-action.js.map +1 -0
  305. package/package.json +8 -8
  306. package/src/adapters/speech.test.ts +118 -1
  307. package/src/adapters/speech.ts +21 -22
  308. package/src/adapters/thread-history.ts +2 -0
  309. package/src/adapters/voice.test.ts +134 -0
  310. package/src/adapters/voice.ts +35 -27
  311. package/src/index.ts +1 -0
  312. package/src/internal.ts +1 -0
  313. package/src/model-context/frame/host.test.ts +87 -5
  314. package/src/model-context/frame/host.ts +18 -4
  315. package/src/model-context/frame/provider.test.ts +347 -20
  316. package/src/model-context/frame/provider.ts +58 -2
  317. package/src/model-context/frame/types.ts +5 -0
  318. package/src/model-context/registry.test.ts +131 -0
  319. package/src/model-context/registry.ts +16 -6
  320. package/src/react/RuntimeAdapter.test.ts +2 -0
  321. package/src/react/RuntimeAdapter.ts +20 -8
  322. package/src/react/adapters/LocalStorageThreadListAdapter.tsx +34 -17
  323. package/src/react/client/AdaptedRemoteThread.ts +41 -0
  324. package/src/react/client/InMemoryThreadList.test.tsx +148 -0
  325. package/src/react/client/InMemoryThreadList.ts +290 -0
  326. package/src/react/client/Interactables.test.ts +326 -2
  327. package/src/react/client/Interactables.ts +227 -110
  328. package/src/react/client/RemoteThreadList.test.ts +1222 -0
  329. package/src/react/client/RemoteThreadList.ts +1136 -0
  330. package/src/react/client/Tools.ts +36 -29
  331. package/src/react/index.ts +13 -0
  332. package/src/react/interactables-legacy/Interactables.test.ts +317 -0
  333. package/src/react/interactables-legacy/Interactables.ts +204 -128
  334. package/src/react/primitive-hooks/useActionBarCopy.test.ts +15 -0
  335. package/src/react/primitive-hooks/useActionBarCopy.ts +15 -10
  336. package/src/react/primitive-hooks/useActionBarEdit.ts +2 -1
  337. package/src/react/primitive-hooks/useActionBarReload.ts +2 -6
  338. package/src/react/primitive-hooks/useBranchPickerNext.ts +2 -7
  339. package/src/react/primitive-hooks/useBranchPickerPrevious.ts +2 -7
  340. package/src/react/primitive-hooks/useComposerCancel.ts +2 -1
  341. package/src/react/primitive-hooks/useComposerSend.ts +2 -5
  342. package/src/react/primitive-hooks/useSuggestionTrigger.test.ts +11 -0
  343. package/src/react/primitive-hooks/useSuggestionTrigger.ts +4 -5
  344. package/src/react/primitive-hooks/useThreadIsEmpty.ts +3 -0
  345. package/src/react/primitive-hooks/useThreadIsRunning.ts +3 -0
  346. package/src/react/primitives/message/MessageParts.tsx +0 -1
  347. package/src/react/primitives/thread/ThreadMessages.tsx +2 -1
  348. package/src/react/runtimes/RemoteThreadListHookInstanceManager.retry.test.tsx +116 -0
  349. package/src/react/runtimes/RemoteThreadListHookInstanceManager.running.test.tsx +1 -1
  350. package/src/react/runtimes/RemoteThreadListHookInstanceManager.test.tsx +57 -6
  351. package/src/react/runtimes/RemoteThreadListHookInstanceManager.title.test.tsx +272 -0
  352. package/src/react/runtimes/RemoteThreadListHookInstanceManager.tsx +171 -124
  353. package/src/react/runtimes/RemoteThreadListThreadListRuntimeCore.republish.test.ts +87 -0
  354. package/src/react/runtimes/RemoteThreadListThreadListRuntimeCore.tsx +327 -83
  355. package/src/react/runtimes/RemoteThreadResource.test.ts +141 -0
  356. package/src/react/runtimes/RemoteThreadResource.ts +233 -0
  357. package/src/react/runtimes/RuntimeAdapterProvider.tsx +8 -20
  358. package/src/react/runtimes/assistant-transport/commandQueue.ts +68 -0
  359. package/src/react/runtimes/assistant-transport/replayBoundaryStream.test.ts +455 -0
  360. package/src/react/runtimes/assistant-transport/replayBoundaryStream.ts +172 -0
  361. package/src/react/runtimes/assistant-transport/runManager.ts +124 -0
  362. package/src/react/runtimes/assistant-transport/transport-delivery.test.tsx +79 -0
  363. package/src/react/runtimes/assistant-transport/transport-parentid.test.tsx +97 -0
  364. package/src/react/runtimes/assistant-transport/transport-scheduling.test.ts +414 -0
  365. package/src/react/runtimes/assistant-transport/types.ts +170 -0
  366. package/src/react/runtimes/assistant-transport/useAssistantTransport.spec.md +141 -0
  367. package/src/react/runtimes/assistant-transport/useAssistantTransportRuntime.test.tsx +683 -0
  368. package/src/react/runtimes/assistant-transport/useAssistantTransportRuntime.ts +483 -0
  369. package/src/react/runtimes/assistant-transport/useConvertedState.ts +20 -0
  370. package/src/react/runtimes/assistant-transport/useLatestRef.ts +9 -0
  371. package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.test.tsx +131 -6
  372. package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.ts +61 -15
  373. package/src/react/runtimes/cloud/CloudFileAttachmentAdapter.ts +6 -4
  374. package/src/react/runtimes/cloud/auiV0.ts +17 -1
  375. package/src/react/runtimes/cloud/useCloudThreadListAdapter.test.tsx +98 -3
  376. package/src/react/runtimes/cloud/useCloudThreadListAdapter.tsx +104 -27
  377. package/src/react/runtimes/cloud/useCloudThreadListRuntime.test.tsx +56 -0
  378. package/src/react/runtimes/cloud/useCloudThreadListRuntime.ts +31 -0
  379. package/src/react/runtimes/external-message-converter.test.ts +143 -0
  380. package/src/react/runtimes/external-message-converter.ts +41 -41
  381. package/src/react/runtimes/remote-thread-hook-on-tap.test.ts +58 -0
  382. package/src/react/runtimes/useExternalStoreRuntime.lifecycle.test.tsx +83 -0
  383. package/src/react/runtimes/useExternalStoreRuntime.suggestions.test.tsx +13 -3
  384. package/src/react/runtimes/useExternalStoreRuntime.ts +7 -0
  385. package/src/react/runtimes/useExternalStoreSharedOptions.ts +3 -1
  386. package/src/react/runtimes/useLocalRuntime.test.tsx +134 -8
  387. package/src/react/runtimes/useRuntimeAdapters.test.tsx +62 -0
  388. package/src/react/runtimes/useRuntimeAdapters.ts +28 -0
  389. package/src/runtime/api/composer-runtime.ts +5 -0
  390. package/src/runtime/api/thread-list-runtime.ts +3 -1
  391. package/src/runtime/api/thread-runtime.ts +20 -2
  392. package/src/runtime/base/base-composer-runtime-core.ts +6 -5
  393. package/src/runtime/base/base-thread-runtime-core.test.ts +191 -0
  394. package/src/runtime/base/base-thread-runtime-core.ts +11 -2
  395. package/src/runtime/base/default-thread-composer-runtime-core.ts +12 -4
  396. package/src/runtime/interfaces/thread-runtime-core.ts +6 -0
  397. package/src/runtime/queue/message-queue.ts +2 -1
  398. package/src/runtime/utils/message-repository.ts +26 -18
  399. package/src/runtime/utils/thread-runtime-lifecycle.ts +18 -0
  400. package/src/runtimes/external-store/external-store-shared-options.ts +3 -1
  401. package/src/runtimes/external-store/external-store-thread-list-runtime-core.ts +4 -1
  402. package/src/runtimes/external-store/external-store-thread-runtime-core.ts +103 -34
  403. package/src/runtimes/inert/InertThreadRuntimeCore.test.ts +253 -0
  404. package/src/runtimes/inert/InertThreadRuntimeCore.ts +232 -0
  405. package/src/runtimes/local/local-thread-runtime-core.test.ts +692 -4
  406. package/src/runtimes/local/local-thread-runtime-core.ts +117 -22
  407. package/src/runtimes/readonly/ReadonlyThreadRuntimeCore.ts +17 -205
  408. package/src/runtimes/remote-thread-list/adapter-changed.ts +10 -0
  409. package/src/runtimes/remote-thread-list/empty-thread-core.ts +28 -217
  410. package/src/runtimes/remote-thread-list/optimistic-state.test.ts +18 -0
  411. package/src/runtimes/remote-thread-list/optimistic-state.ts +13 -0
  412. package/src/runtimes/remote-thread-list/types.ts +34 -0
  413. package/src/runtimes/tool-invocations/EDGE_CASES.md +17 -6
  414. package/src/runtimes/tool-invocations/ToolInvocationTracker.test.ts +243 -0
  415. package/src/runtimes/tool-invocations/ToolInvocationTracker.ts +127 -61
  416. package/src/store/clients/external-thread.ts +1 -1
  417. package/src/store/clients/model-context-client.test.ts +16 -8
  418. package/src/store/clients/suggestions.ts +2 -2
  419. package/src/store/clients/thread-selection-events.ts +21 -0
  420. package/src/store/env.ts +11 -0
  421. package/src/store/index.ts +14 -1
  422. package/src/store/internal.ts +13 -0
  423. package/src/store/primitive-predicates.test.ts +184 -0
  424. package/src/store/primitive-predicates.ts +43 -0
  425. package/src/store/runtime-clients/attachment-runtime-client.test.ts +41 -0
  426. package/src/store/runtime-clients/attachment-runtime-client.ts +2 -1
  427. package/src/store/runtime-clients/handle-runtime-action.test.ts +40 -0
  428. package/src/store/runtime-clients/handle-runtime-action.ts +14 -0
  429. package/src/store/runtime-clients/handle-thread-list-action.test.ts +69 -0
  430. package/src/store/runtime-clients/handle-thread-list-action.ts +6 -0
  431. package/src/store/runtime-clients/thread-list-item-runtime-client.ts +15 -7
  432. package/src/store/runtime-clients/thread-list-runtime-client.ts +9 -6
  433. package/src/store/scopes/composer.ts +9 -4
  434. package/src/store/scopes/thread-list-item.ts +7 -6
  435. package/src/store/scopes/thread.ts +8 -7
  436. package/src/store/scopes/threads.ts +14 -0
  437. package/src/subscribable/subscribable.test.ts +77 -1
  438. package/src/subscribable/subscribable.ts +38 -23
  439. package/src/tests/MessageRepository.test.ts +48 -0
  440. package/src/tests/RemoteThreadListThreadListRuntimeCore-errors.test.ts +2 -2
  441. package/src/tests/RemoteThreadListThreadListRuntimeCore-loadMore.test.ts +8 -6
  442. package/src/tests/RemoteThreadListThreadListRuntimeCore-switchToThread-unarchive.test.ts +25 -0
  443. package/src/tests/auiV0Encode.test.ts +66 -0
  444. package/src/tests/base-composer-runtime-core-send.test.ts +30 -0
  445. package/src/tests/base-composer-runtime-core.test.ts +28 -0
  446. package/src/tests/composer-can-cancel.test.ts +101 -0
  447. package/src/tests/empty-thread-core.test.ts +6 -0
  448. package/src/tests/external-store-thread-list-runtime-core.test.ts +101 -0
  449. package/src/tests/external-store-thread-runtime-core-adapter.test.ts +211 -1
  450. package/src/tests/external-store-thread-runtime-core.test.ts +124 -0
  451. package/src/tests/external-thread-isEmpty.test.tsx +100 -0
  452. package/src/tests/interactables-toolui-migration.test.tsx +66 -0
  453. package/src/tests/message-queue.test.ts +28 -0
  454. package/src/tests/remote-thread-list-adapter-switch.test.ts +383 -0
  455. package/src/tests/session-reset-notification.test.ts +145 -0
  456. package/src/tests/thread-switch-events.test.tsx +99 -1
  457. package/src/tests/tools-scope-migration.test.tsx +58 -0
  458. package/src/tests/useRemoteThreadListRuntime-controlled.test.tsx +67 -0
  459. package/src/types/message.ts +1 -1
  460. package/src/utils/composite-context-provider.test.ts +139 -0
  461. package/src/utils/composite-context-provider.ts +26 -8
  462. package/src/utils/notify-event-listeners.ts +10 -5
  463. package/src/utils/silent-runtime-action.ts +6 -0
@@ -0,0 +1,43 @@
1
+ import type { AssistantState } from "@assistant-ui/store";
2
+
3
+ /**
4
+ * Disabled predicates shared by every binding's primitive layer. Each binding
5
+ * consumes these as state selectors so the disabled semantics of a primitive
6
+ * cannot drift between frameworks.
7
+ */
8
+
9
+ export const composerSendDisabled = (s: AssistantState): boolean =>
10
+ !s.composer.canSend || (s.thread.isRunning && !s.thread.capabilities.queue);
11
+
12
+ export const composerCancelDisabled = (s: AssistantState): boolean =>
13
+ !s.composer.canCancel;
14
+
15
+ export const composerInputDisabled = (s: AssistantState): boolean =>
16
+ s.thread.isDisabled || s.composer.dictation?.inputDisabled === true;
17
+
18
+ export const actionBarEditDisabled = (s: AssistantState): boolean =>
19
+ s.composer.isEditing;
20
+
21
+ export const actionBarReloadDisabled = (s: AssistantState): boolean =>
22
+ s.thread.isRunning || s.thread.isDisabled || s.message.role !== "assistant";
23
+
24
+ export const actionBarCopyDisabled = (s: AssistantState): boolean =>
25
+ !(
26
+ (s.message.role !== "assistant" || s.message.status?.type !== "running") &&
27
+ s.message.parts.some((part) => part.type === "text" && part.text.length > 0)
28
+ );
29
+
30
+ export const branchPickerPreviousDisabled = (s: AssistantState): boolean =>
31
+ s.message.branchNumber <= 1 ||
32
+ (s.thread.isRunning && !s.thread.capabilities.switchBranchDuringRun);
33
+
34
+ export const branchPickerNextDisabled = (s: AssistantState): boolean =>
35
+ s.message.branchNumber >= s.message.branchCount ||
36
+ (s.thread.isRunning && !s.thread.capabilities.switchBranchDuringRun);
37
+
38
+ export const suggestionTriggerDisabled = (
39
+ s: AssistantState,
40
+ send: boolean,
41
+ ): boolean =>
42
+ s.thread.isDisabled ||
43
+ (send && s.thread.isRunning && !s.thread.capabilities.queue);
@@ -0,0 +1,41 @@
1
+ import { createTapRoot, useResource } from "@assistant-ui/tap";
2
+ import { afterEach, describe, expect, it, vi } from "vitest";
3
+ import type { AttachmentRuntime } from "../../runtime/api/attachment-runtime";
4
+ import { AttachmentRuntimeClient } from "./attachment-runtime-client";
5
+
6
+ describe("AttachmentRuntimeClient", () => {
7
+ afterEach(() => {
8
+ vi.restoreAllMocks();
9
+ });
10
+
11
+ it("reports attachment removal failures", async () => {
12
+ const error = new Error("storage unavailable");
13
+ const consoleError = vi
14
+ .spyOn(console, "error")
15
+ .mockImplementation(() => {});
16
+ const state = {
17
+ id: "attachment-1",
18
+ type: "file",
19
+ name: "notes.txt",
20
+ status: { type: "complete" },
21
+ content: [],
22
+ source: "thread-composer",
23
+ };
24
+ const runtime = {
25
+ getState: () => state,
26
+ subscribe: () => () => {},
27
+ remove: () => Promise.reject(error),
28
+ } as unknown as AttachmentRuntime;
29
+ const root = createTapRoot(function AttachmentClientRoot() {
30
+ return useResource(AttachmentRuntimeClient({ runtime }));
31
+ });
32
+
33
+ await expect(root.getValue().remove()).rejects.toBe(error);
34
+
35
+ expect(consoleError).toHaveBeenCalledWith(
36
+ "[assistant-ui] attachment remove failed:",
37
+ error,
38
+ );
39
+ root.unmount();
40
+ });
41
+ });
@@ -1,6 +1,7 @@
1
1
  import { resource } from "@assistant-ui/tap";
2
2
  import type { ClientOutput } from "@assistant-ui/store";
3
3
  import type { AttachmentRuntime } from "../../runtime/api/attachment-runtime";
4
+ import { handleRuntimeAction } from "./handle-runtime-action";
4
5
  import { useSubscribable } from "./useSubscribable";
5
6
 
6
7
  const useAttachmentRuntimeClient = ({
@@ -12,7 +13,7 @@ const useAttachmentRuntimeClient = ({
12
13
 
13
14
  return {
14
15
  getState: () => state,
15
- remove: runtime.remove,
16
+ remove: () => handleRuntimeAction("attachment remove", runtime.remove),
16
17
  __internal_getRuntime: () => runtime,
17
18
  };
18
19
  };
@@ -0,0 +1,40 @@
1
+ import { describe, expect, it, vi } from "vitest";
2
+ import { ThreadListAdapterChangedError } from "../../runtimes/remote-thread-list/adapter-changed";
3
+ import { handleRuntimeAction } from "./handle-runtime-action";
4
+
5
+ describe("handleRuntimeAction", () => {
6
+ it("does not log a silent adapter-change cancellation", async () => {
7
+ const error = new ThreadListAdapterChangedError();
8
+ const consoleError = vi
9
+ .spyOn(console, "error")
10
+ .mockImplementation(() => {});
11
+
12
+ try {
13
+ await expect(
14
+ handleRuntimeAction("thread list archive", () => Promise.reject(error)),
15
+ ).rejects.toBe(error);
16
+ expect(consoleError).not.toHaveBeenCalled();
17
+ } finally {
18
+ consoleError.mockRestore();
19
+ }
20
+ });
21
+
22
+ it("logs an ordinary rejection", async () => {
23
+ const error = new Error("archive failed");
24
+ const consoleError = vi
25
+ .spyOn(console, "error")
26
+ .mockImplementation(() => {});
27
+
28
+ try {
29
+ await expect(
30
+ handleRuntimeAction("thread list archive", () => Promise.reject(error)),
31
+ ).rejects.toBe(error);
32
+ expect(consoleError).toHaveBeenCalledExactlyOnceWith(
33
+ "[assistant-ui] thread list archive failed:",
34
+ error,
35
+ );
36
+ } finally {
37
+ consoleError.mockRestore();
38
+ }
39
+ });
40
+ });
@@ -0,0 +1,14 @@
1
+ import { isSilentRuntimeAction } from "../../utils/silent-runtime-action";
2
+
3
+ export const handleRuntimeAction = (
4
+ label: string,
5
+ execute: () => Promise<void>,
6
+ ): Promise<void> => {
7
+ const task = execute();
8
+
9
+ void task.catch((error: unknown) => {
10
+ if (isSilentRuntimeAction(error)) return;
11
+ console.error(`[assistant-ui] ${label} failed:`, error);
12
+ });
13
+ return task;
14
+ };
@@ -0,0 +1,69 @@
1
+ import { afterEach, describe, expect, it, vi } from "vitest";
2
+ import { handleThreadListAction } from "./handle-thread-list-action";
3
+
4
+ describe("handleThreadListAction", () => {
5
+ afterEach(() => {
6
+ vi.restoreAllMocks();
7
+ });
8
+
9
+ it("reports a rejected task", async () => {
10
+ const error = new Error("unavailable");
11
+ const task = Promise.reject(error);
12
+ const consoleError = vi
13
+ .spyOn(console, "error")
14
+ .mockImplementation(() => {});
15
+
16
+ const result = handleThreadListAction("delete", () => task);
17
+
18
+ expect(result).toBe(task);
19
+ await expect(result).rejects.toBe(error);
20
+ expect(consoleError).toHaveBeenCalledWith(
21
+ "[assistant-ui] thread list delete failed:",
22
+ error,
23
+ );
24
+ });
25
+
26
+ it("preserves synchronous failures", () => {
27
+ const error = new Error("invalid thread");
28
+ const consoleError = vi
29
+ .spyOn(console, "error")
30
+ .mockImplementation(() => {});
31
+
32
+ expect(() =>
33
+ handleThreadListAction("switch", () => {
34
+ throw error;
35
+ }),
36
+ ).toThrow(error);
37
+ expect(consoleError).not.toHaveBeenCalled();
38
+ });
39
+
40
+ it("does not leak an ignored action as an unhandled rejection", async () => {
41
+ const error = new Error("delete failed");
42
+ const consoleError = vi
43
+ .spyOn(console, "error")
44
+ .mockImplementation(() => {});
45
+ const rejections: unknown[] = [];
46
+ const onUnhandledRejection = (reason: unknown) => {
47
+ rejections.push(reason);
48
+ };
49
+ const priorListeners = process.listeners("unhandledRejection");
50
+ process.removeAllListeners("unhandledRejection");
51
+ process.on("unhandledRejection", onUnhandledRejection);
52
+
53
+ try {
54
+ handleThreadListAction("delete", () => Promise.reject(error));
55
+ await new Promise((resolve) => setTimeout(resolve, 20));
56
+ } finally {
57
+ process.removeListener("unhandledRejection", onUnhandledRejection);
58
+ for (const listener of priorListeners) {
59
+ process.on("unhandledRejection", listener);
60
+ }
61
+ }
62
+
63
+ expect(rejections).toEqual([]);
64
+ expect(consoleError).toHaveBeenCalledWith(
65
+ "[assistant-ui] thread list delete failed:",
66
+ error,
67
+ );
68
+ });
69
+ });
@@ -0,0 +1,6 @@
1
+ import { handleRuntimeAction } from "./handle-runtime-action";
2
+
3
+ export const handleThreadListAction = (
4
+ action: string,
5
+ execute: () => Promise<void>,
6
+ ): Promise<void> => handleRuntimeAction(`thread list ${action}`, execute);
@@ -4,6 +4,7 @@ import type { ClientOutput } from "@assistant-ui/store";
4
4
  import { useAssistantEmit } from "@assistant-ui/store/client";
5
5
  import type { ThreadListItemRuntime } from "../../runtime/api/thread-list-item-runtime";
6
6
  import { useSubscribable } from "./useSubscribable";
7
+ import { handleThreadListAction } from "./handle-thread-list-action";
7
8
 
8
9
  const useThreadListItemClient = ({
9
10
  runtime,
@@ -39,13 +40,20 @@ const useThreadListItemClient = ({
39
40
 
40
41
  return {
41
42
  getState: () => state,
42
- switchTo: runtime.switchTo,
43
- rename: runtime.rename,
44
- updateCustom: runtime.updateCustom,
45
- archive: runtime.archive,
46
- unarchive: runtime.unarchive,
47
- delete: runtime.delete,
48
- generateTitle: runtime.generateTitle,
43
+ switchTo: (options) =>
44
+ handleThreadListAction("switch", () => runtime.switchTo(options)),
45
+ rename: (newTitle) =>
46
+ handleThreadListAction("rename", () => runtime.rename(newTitle)),
47
+ updateCustom: (custom) =>
48
+ handleThreadListAction("update custom metadata", () =>
49
+ runtime.updateCustom(custom),
50
+ ),
51
+ archive: () => handleThreadListAction("archive", () => runtime.archive()),
52
+ unarchive: () =>
53
+ handleThreadListAction("unarchive", () => runtime.unarchive()),
54
+ delete: () => handleThreadListAction("delete", () => runtime.delete()),
55
+ generateTitle: () =>
56
+ handleThreadListAction("generate title", () => runtime.generateTitle()),
49
57
  initialize: runtime.initialize,
50
58
  detach: runtime.detach,
51
59
  __internal_getRuntime: () => runtime,
@@ -2,12 +2,14 @@ import { useMemo } from "react";
2
2
  import { useResource, withKey, resource } from "@assistant-ui/tap";
3
3
  import type { ClientOutput } from "@assistant-ui/store";
4
4
  import { useClientLookup, useClientResource } from "@assistant-ui/store/client";
5
+ import { useThreadSelectionEvents } from "../clients/thread-selection-events";
5
6
  import type { ThreadListRuntime } from "../../runtime/api/thread-list-runtime";
6
7
  import type { AssistantRuntime } from "../../runtime/api/assistant-runtime";
7
8
  import { useSubscribable } from "./useSubscribable";
8
9
  import { ThreadListItemClient } from "./thread-list-item-runtime-client";
9
10
  import { ThreadClient } from "./thread-runtime-client";
10
11
  import type { ThreadsState } from "../scopes/threads";
12
+ import { handleThreadListAction } from "./handle-thread-list-action";
11
13
 
12
14
  const useThreadListItemClientById = ({
13
15
  runtime,
@@ -40,6 +42,7 @@ const useThreadListClient = ({
40
42
  __internal_assistantRuntime: AssistantRuntime;
41
43
  }): ClientOutput<"threads"> => {
42
44
  const runtimeState = useSubscribable(runtime);
45
+ useThreadSelectionEvents(runtimeState.mainThreadId);
43
46
 
44
47
  const main = useClientResource(
45
48
  ThreadClient({
@@ -93,12 +96,12 @@ const useThreadListClient = ({
93
96
  : state.threadIds[index]!;
94
97
  return threadItems.get({ key: id });
95
98
  },
96
- switchToThread: async (threadId, options) => {
97
- await runtime.switchToThread(threadId, options);
98
- },
99
- switchToNewThread: async () => {
100
- await runtime.switchToNewThread();
101
- },
99
+ switchToThread: (threadId, options) =>
100
+ handleThreadListAction("switch", () =>
101
+ runtime.switchToThread(threadId, options),
102
+ ),
103
+ switchToNewThread: () =>
104
+ handleThreadListAction("create", () => runtime.switchToNewThread()),
102
105
  getLoadThreadsPromise: () => runtime.getLoadThreadsPromise(),
103
106
  reload: () => runtime.reload(),
104
107
  reloadMainThread: () => runtime.reloadMainThread(),
@@ -27,6 +27,11 @@ export type ComposerState = {
27
27
  readonly attachments: readonly Attachment[];
28
28
  readonly runConfig: RunConfig;
29
29
  readonly isEditing: boolean;
30
+ /**
31
+ * Whether the composer can cancel the current run. `true` when the runtime
32
+ * supports cancel and a run is in flight, not merely when cancel is a
33
+ * capability.
34
+ */
30
35
  readonly canCancel: boolean;
31
36
  /**
32
37
  * Whether the composer is currently willing to send. `true` when the
@@ -104,13 +109,13 @@ export type ComposerMeta = {
104
109
 
105
110
  export type ComposerEvents = {
106
111
  /**
107
- * @deprecated State-derivable. Observe composer `text` clearing via
108
- * `useAuiState` instead. Kept for backward compatibility.
112
+ * The user sent the composer contents. `messageId` is set when the send
113
+ * came from an edit composer.
109
114
  */
110
115
  "composer.send": { threadId: string; messageId?: string };
111
116
  /**
112
- * @deprecated State-derivable. Observe composer `attachments` via
113
- * `useAuiState` instead. Kept for backward compatibility.
117
+ * An attachment was added to the composer. `messageId` is set when the
118
+ * attachment was added to an edit composer.
114
119
  */
115
120
  "composer.attachmentAdd": { threadId: string; messageId?: string };
116
121
  "composer.attachmentAddError": {
@@ -42,15 +42,16 @@ export type ThreadListItemMeta = {
42
42
 
43
43
  export type ThreadListItemEvents = {
44
44
  /**
45
- * @deprecated State-derivable. Compare `s.threads.mainThreadId` against the
46
- * item's `s.threadListItem.id` via `useAuiState` instead. Kept for backward
47
- * compatibility.
45
+ * @deprecated Use `threads.selectionChanged` instead; its `threadId` is the
46
+ * newly selected thread. Inside a per-item `threadListItem` scope, filter by
47
+ * `threadId === threadListItem.id` to reproduce the per-item delivery. Kept
48
+ * for backward compatibility.
48
49
  */
49
50
  "threadListItem.switchedTo": { threadId: string };
50
51
  /**
51
- * @deprecated State-derivable. Compare `s.threads.mainThreadId` against the
52
- * item's `s.threadListItem.id` via `useAuiState` instead. Kept for backward
53
- * compatibility.
52
+ * @deprecated Use `threads.selectionChanged` instead; its
53
+ * `previousThreadId` is the thread that was switched away from. Kept for
54
+ * backward compatibility.
54
55
  */
55
56
  "threadListItem.switchedAway": { threadId: string };
56
57
  };
@@ -145,19 +145,20 @@ export type ThreadMeta = {
145
145
 
146
146
  export type ThreadEvents = {
147
147
  /**
148
- * @deprecated State-derivable. Observe `isRunning` flipping to `true` via
149
- * `useAuiState` instead. Kept for backward compatibility.
148
+ * A run started on this thread. Also observable as `isRunning` flipping to
149
+ * `true` in thread state.
150
150
  */
151
151
  "thread.runStart": { threadId: string };
152
152
  /**
153
- * @deprecated State-derivable. Observe `isRunning` flipping to `false` via
154
- * `useAuiState` instead. Kept for backward compatibility.
153
+ * A run on this thread ended, whether it completed, errored, or was
154
+ * cancelled. Also observable as `isRunning` flipping to `false` in thread
155
+ * state.
155
156
  */
156
157
  "thread.runEnd": { threadId: string };
157
158
  /**
158
- * @deprecated State-derivable. This event fires before the first message is
159
- * added; observe `messages` becoming non-empty via `useAuiState` instead of
160
- * reading state inside this event handler. Kept for backward compatibility.
159
+ * The thread transitioned from new to initialized. Fires before the first
160
+ * message is added, so read thread state via `useAuiState` rather than
161
+ * inside this event handler.
161
162
  */
162
163
  "thread.initialize": { threadId: string };
163
164
  /**
@@ -35,6 +35,20 @@ export type ThreadsMethods = {
35
35
  __internal_getAssistantRuntime?(): AssistantRuntime;
36
36
  };
37
37
 
38
+ export type ThreadsEvents = {
39
+ /**
40
+ * The main thread selection changed. Fires once per switch with the newly
41
+ * selected thread and the thread that was selected before. Does not fire
42
+ * for the initially selected thread on mount. Runtimes that resolve a
43
+ * deep-linked `threadId`/`initialThreadId` after mount (such as
44
+ * `useRemoteThreadListRuntime`) start on a placeholder new thread, so the
45
+ * deep link's resolution fires this event with the placeholder as
46
+ * `previousThreadId`.
47
+ */
48
+ "threads.selectionChanged": { threadId: string; previousThreadId: string };
49
+ };
50
+
38
51
  export type ThreadsClientSchema = {
39
52
  methods: ThreadsMethods;
53
+ events: ThreadsEvents;
40
54
  };
@@ -1,6 +1,6 @@
1
1
  import { describe, expect, it, vi } from "vitest";
2
2
  import type { SubscribableWithState } from "./subscribable";
3
- import { ShallowMemoizeSubject } from "./subscribable";
3
+ import { LazyMemoizeSubject, ShallowMemoizeSubject } from "./subscribable";
4
4
 
5
5
  type TestState = {
6
6
  status: string;
@@ -26,6 +26,9 @@ const createBinding = (initialState: TestState) => {
26
26
  state = nextState;
27
27
  for (const callback of subscribers) callback();
28
28
  },
29
+ replace(nextState: TestState) {
30
+ state = nextState;
31
+ },
29
32
  };
30
33
  };
31
34
 
@@ -55,4 +58,77 @@ describe("ShallowMemoizeSubject", () => {
55
58
 
56
59
  expect(subscriber).not.toHaveBeenCalled();
57
60
  });
61
+
62
+ it("notifies later subscribers when one throws", () => {
63
+ const source = createBinding({ status: "empty" });
64
+ const subject = new ShallowMemoizeSubject(source.binding);
65
+ const error = new Error("subscriber failed");
66
+ const laterSubscriber = vi.fn();
67
+ subject.subscribe(() => {
68
+ throw error;
69
+ });
70
+ subject.subscribe(laterSubscriber);
71
+
72
+ expect(() => source.update({ status: "ready" })).toThrow(error);
73
+ expect(laterSubscriber).toHaveBeenCalledOnce();
74
+ expect(subject.getState()).toEqual({ status: "ready" });
75
+ });
76
+
77
+ it("reads a value that landed while nobody was subscribed", () => {
78
+ const source = createBinding({ status: "empty" });
79
+ const subject = new ShallowMemoizeSubject(source.binding);
80
+ expect(subject.getState()).toEqual({ status: "empty" });
81
+
82
+ source.update({ status: "ready" });
83
+ const subscriber = vi.fn();
84
+ subject.subscribe(subscriber);
85
+
86
+ expect(subject.getState()).toEqual({ status: "ready" });
87
+ expect(subscriber).not.toHaveBeenCalled();
88
+ });
89
+ });
90
+
91
+ describe("LazyMemoizeSubject", () => {
92
+ it("notifies later subscribers when one throws", () => {
93
+ const source = createBinding({ status: "empty" });
94
+ const subject = new LazyMemoizeSubject(source.binding);
95
+ const error = new Error("subscriber failed");
96
+ const laterSubscriber = vi.fn();
97
+ subject.subscribe(() => {
98
+ throw error;
99
+ });
100
+ subject.subscribe(laterSubscriber);
101
+
102
+ expect(() => source.update({ status: "ready" })).toThrow(error);
103
+ expect(laterSubscriber).toHaveBeenCalledOnce();
104
+ expect(subject.getState()).toEqual({ status: "ready" });
105
+ });
106
+
107
+ it("reads a value replaced before connecting", () => {
108
+ const source = createBinding({ status: "empty" });
109
+ const subject = new LazyMemoizeSubject(source.binding);
110
+ expect(subject.getState()).toEqual({ status: "empty" });
111
+
112
+ source.replace({ status: "ready" });
113
+ const subscriber = vi.fn();
114
+ const unsubscribe = subject.subscribe(subscriber);
115
+
116
+ expect(subject.getState()).toEqual({ status: "ready" });
117
+ expect(subscriber).not.toHaveBeenCalled();
118
+ unsubscribe();
119
+ });
120
+
121
+ it("resynchronizes after reconnecting", () => {
122
+ const source = createBinding({ status: "empty" });
123
+ const subject = new LazyMemoizeSubject(source.binding);
124
+ expect(subject.getState()).toEqual({ status: "empty" });
125
+
126
+ const unsubscribe = subject.subscribe(() => {});
127
+ unsubscribe();
128
+ source.replace({ status: "ready" });
129
+ const reconnect = subject.subscribe(() => {});
130
+
131
+ expect(subject.getState()).toEqual({ status: "ready" });
132
+ reconnect();
133
+ });
58
134
  });
@@ -32,6 +32,31 @@ export type EventSubscribable<TEvent extends string> = {
32
32
  >;
33
33
  };
34
34
 
35
+ export const notifySubscribers = <TArgs extends unknown[]>(
36
+ subscribers: Iterable<(...args: TArgs) => void>,
37
+ ...args: TArgs
38
+ ): void => {
39
+ const errors: unknown[] = [];
40
+ for (const callback of subscribers) {
41
+ try {
42
+ callback(...args);
43
+ } catch (error) {
44
+ errors.push(error);
45
+ }
46
+ }
47
+
48
+ if (errors.length === 1) {
49
+ throw errors[0];
50
+ }
51
+
52
+ if (errors.length > 1) {
53
+ for (const error of errors) {
54
+ console.error(error);
55
+ }
56
+ throw new AggregateError(errors);
57
+ }
58
+ };
59
+
35
60
  function shallowEqual<T extends object>(
36
61
  objA: T | undefined,
37
62
  objB: T | undefined,
@@ -70,25 +95,7 @@ export class BaseSubscribable {
70
95
  }
71
96
 
72
97
  protected _notifySubscribers() {
73
- const errors = [];
74
- for (const callback of this._subscribers) {
75
- try {
76
- callback();
77
- } catch (error) {
78
- errors.push(error);
79
- }
80
- }
81
-
82
- if (errors.length > 0) {
83
- if (errors.length === 1) {
84
- throw errors[0];
85
- } else {
86
- for (const error of errors) {
87
- console.error(error);
88
- }
89
- throw new AggregateError(errors);
90
- }
91
- }
98
+ notifySubscribers(this._subscribers);
92
99
  }
93
100
  }
94
101
 
@@ -109,7 +116,7 @@ export abstract class BaseSubject {
109
116
  return;
110
117
  }
111
118
 
112
- for (const callback of this._subscriptions) callback(payload);
119
+ notifySubscribers(this._subscriptions, payload);
113
120
  }
114
121
 
115
122
  private _updateConnection() {
@@ -173,7 +180,9 @@ export class ShallowMemoizeSubject<TState extends object, TPath>
173
180
  }
174
181
  };
175
182
 
176
- return this.binding.subscribe(callback);
183
+ const unsubscribe = this.binding.subscribe(callback);
184
+ this._syncState();
185
+ return unsubscribe;
177
186
  }
178
187
  }
179
188
 
@@ -197,7 +206,11 @@ export class LazyMemoizeSubject<TState extends object, TPath>
197
206
  public getState = () => {
198
207
  if (!this.isConnected || this._previousStateDirty) {
199
208
  const newState = this.binding.getState();
200
- if (newState !== SKIP_UPDATE) {
209
+ if (
210
+ newState !== SKIP_UPDATE &&
211
+ (this._previousState === undefined ||
212
+ !shallowEqual(newState, this._previousState))
213
+ ) {
201
214
  this._previousState = newState;
202
215
  }
203
216
  this._previousStateDirty = false;
@@ -213,7 +226,9 @@ export class LazyMemoizeSubject<TState extends object, TPath>
213
226
  this.notifySubscribers();
214
227
  };
215
228
 
216
- return this.binding.subscribe(callback);
229
+ const unsubscribe = this.binding.subscribe(callback);
230
+ this._previousStateDirty = true;
231
+ return unsubscribe;
217
232
  }
218
233
  }
219
234