@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
@@ -27,6 +27,7 @@ import type {
27
27
  RespondToToolApprovalOptions,
28
28
  ResumeToolCallOptions,
29
29
  SpeechState,
30
+ ThreadSuggestion,
30
31
  } from "../../runtime/interfaces/thread-runtime-core";
31
32
  import type {
32
33
  ExternalThreadQueueAdapter,
@@ -45,13 +46,14 @@ import { getThreadMessageText } from "../../utils/text";
45
46
  import { resolveToolApprovalResponse } from "../../runtime/utils/resolveToolApprovalResponse";
46
47
  import { toMessagePartStatus } from "../../utils/normalizePartStatus";
47
48
  import { ModelContext } from "./model-context-client";
48
- import { Suggestions } from "./suggestions";
49
+ import { ThreadSuggestions } from "./suggestions";
49
50
  import { Tools } from "../../react/client/Tools";
50
51
  import { DataRenderers } from "../../react/client/DataRenderers";
51
52
  import { SingleThreadList } from "./single-thread-list";
52
53
 
53
54
  const EMPTY_QUEUE_ITEMS: readonly QueueItemState[] = [];
54
55
  const EMPTY_BRANCH_IDS: readonly string[] = [];
56
+ const EMPTY_SUGGESTIONS: readonly ThreadSuggestion[] = [];
55
57
 
56
58
  export type ExternalThreadMessage = ThreadMessage & {
57
59
  id: string;
@@ -93,6 +95,13 @@ export type ExternalThreadProps = {
93
95
  onStartRun?: () => void;
94
96
  onCancel?: () => void;
95
97
  onResume?: (() => void) | undefined;
98
+ /**
99
+ * Handler for re-fetching this thread's state in place, driving
100
+ * `threads.reloadMainThread()`. Unrelated to `onReload`, which re-generates
101
+ * an assistant message. Presence enables the `refetchThread` capability;
102
+ * rejections propagate to the caller.
103
+ */
104
+ onRefetchThread?: (() => Promise<void>) | undefined;
96
105
  onAddToolResult?: ((options: AddToolResultOptions) => void) | undefined;
97
106
  /** Callback for resuming a tool call that is waiting for human input. */
98
107
  onResumeToolCall?: ((options: ResumeToolCallOptions) => void) | undefined;
@@ -401,6 +410,7 @@ const AttachmentResource = resource(useAttachmentResource);
401
410
  type ComposerClientResourceProps = {
402
411
  type: "thread" | "edit";
403
412
  canCancel: boolean;
413
+ isRunning?: boolean;
404
414
  isSendDisabled?: boolean;
405
415
  onCancel?: () => void;
406
416
  onBeginEdit?: () => void;
@@ -410,6 +420,53 @@ type ComposerClientResourceProps = {
410
420
  attachmentAdapter?: AttachmentAdapter | undefined;
411
421
  };
412
422
 
423
+ type AttachmentAddOperation = {
424
+ cancelled: boolean;
425
+ attachmentIds: Set<string>;
426
+ };
427
+
428
+ class AttachmentAddOperations {
429
+ private readonly operations = new Set<AttachmentAddOperation>();
430
+
431
+ start() {
432
+ const operation: AttachmentAddOperation = {
433
+ cancelled: false,
434
+ attachmentIds: new Set(),
435
+ };
436
+ this.operations.add(operation);
437
+ return operation;
438
+ }
439
+
440
+ accept(operation: AttachmentAddOperation, attachmentId: string) {
441
+ if (operation.cancelled) return false;
442
+ operation.attachmentIds.add(attachmentId);
443
+ return true;
444
+ }
445
+
446
+ finish(operation: AttachmentAddOperation) {
447
+ this.operations.delete(operation);
448
+ }
449
+
450
+ isCancelled(operation: AttachmentAddOperation) {
451
+ return operation.cancelled;
452
+ }
453
+
454
+ cancel(attachmentId: string) {
455
+ for (const operation of [...this.operations]) {
456
+ if (!operation.attachmentIds.has(attachmentId)) continue;
457
+ operation.cancelled = true;
458
+ this.operations.delete(operation);
459
+ }
460
+ }
461
+
462
+ cancelAll() {
463
+ for (const operation of this.operations) {
464
+ operation.cancelled = true;
465
+ }
466
+ this.operations.clear();
467
+ }
468
+ }
469
+
413
470
  const useQueueItemClient = ({
414
471
  item,
415
472
  onMove,
@@ -431,11 +488,11 @@ const QueueItemClient = resource(useQueueItemClient);
431
488
 
432
489
  const drainAdapterAdd = async (
433
490
  result: ReturnType<AttachmentAdapter["add"]>,
434
- upsert: (attachment: Attachment) => void,
491
+ upsert: (attachment: Attachment) => boolean,
435
492
  ) => {
436
493
  if (Symbol.asyncIterator in result) {
437
494
  for await (const attachment of result) {
438
- upsert(attachment);
495
+ if (!upsert(attachment)) break;
439
496
  }
440
497
  } else {
441
498
  upsert(await result);
@@ -460,6 +517,7 @@ const useLiveState = <T>(initial: T) => {
460
517
  const useComposerClientResource = ({
461
518
  type,
462
519
  canCancel,
520
+ isRunning = false,
463
521
  isSendDisabled = false,
464
522
  onCancel,
465
523
  onBeginEdit,
@@ -484,6 +542,10 @@ const useComposerClientResource = ({
484
542
  const [quote, setQuote, quoteRef] = useLiveState<
485
543
  { readonly text: string; readonly messageId: string } | undefined
486
544
  >(undefined);
545
+ const attachmentAddOperations = useMemo(
546
+ () => new AttachmentAddOperations(),
547
+ [],
548
+ );
487
549
 
488
550
  const updateFromMessage = () => {
489
551
  if (!message) return;
@@ -503,6 +565,7 @@ const useComposerClientResource = ({
503
565
  AttachmentResource({
504
566
  attachment,
505
567
  onRemove: async () => {
568
+ attachmentAddOperations.cancel(attachment.id);
506
569
  await attachmentAdapter?.remove(attachment);
507
570
  setAttachments((prev) =>
508
571
  prev.filter((a) => a.id !== attachment.id),
@@ -607,10 +670,22 @@ const useComposerClientResource = ({
607
670
  );
608
671
  }
609
672
  if (!isCreateAttachment(fileOrAttachment) && attachmentAdapter) {
610
- await drainAdapterAdd(
611
- attachmentAdapter.add({ file: fileOrAttachment }),
612
- upsertAttachment,
613
- );
673
+ const operation = attachmentAddOperations.start();
674
+ try {
675
+ await drainAdapterAdd(
676
+ attachmentAdapter.add({ file: fileOrAttachment }),
677
+ (attachment) => {
678
+ if (!attachmentAddOperations.accept(operation, attachment.id))
679
+ return false;
680
+ upsertAttachment(attachment);
681
+ return true;
682
+ },
683
+ );
684
+ attachmentAddOperations.finish(operation);
685
+ } catch (error) {
686
+ attachmentAddOperations.finish(operation);
687
+ if (!attachmentAddOperations.isCancelled(operation)) throw error;
688
+ }
614
689
  } else if (!isCreateAttachment(fileOrAttachment)) {
615
690
  const newAttachment: Attachment = {
616
691
  id: Math.random().toString(36).substring(7),
@@ -635,6 +710,7 @@ const useComposerClientResource = ({
635
710
  }
636
711
  },
637
712
  clearAttachments: async () => {
713
+ attachmentAddOperations.cancelAll();
638
714
  const removed = attachmentsRef.current;
639
715
  setAttachments([]);
640
716
  await removePendingAttachments(removed);
@@ -646,6 +722,7 @@ const useComposerClientResource = ({
646
722
  return attachmentClients.get(selector);
647
723
  },
648
724
  reset: async () => {
725
+ attachmentAddOperations.cancelAll();
649
726
  const removed = attachmentsRef.current;
650
727
  setText("");
651
728
  setRole("user");
@@ -657,18 +734,21 @@ const useComposerClientResource = ({
657
734
  send: (opts?: ComposerSendOptions) => {
658
735
  const currentQuote = quoteRef.current;
659
736
  const currentText = textRef.current;
737
+ const currentRole = roleRef.current;
738
+ const currentRunConfig = runConfigRef.current;
660
739
  const currentAttachments = attachmentsRef.current;
661
740
  const isEmpty = !currentText.trim() && !currentAttachments.length;
662
741
  if (!isEditingRef.current) throw new Error("Composer is not available");
663
742
  if (isEmpty || isSendDisabled) return;
664
743
 
744
+ attachmentAddOperations.cancelAll();
665
745
  setText("");
666
746
  setAttachments([]);
667
747
  setQuote(undefined);
668
748
 
669
749
  const dispatch = (sendAttachments: readonly Attachment[]) => {
670
750
  const composedMessage: AppendMessage = {
671
- role: roleRef.current,
751
+ role: currentRole,
672
752
  content: currentText
673
753
  ? [{ type: "text" as const, text: currentText }]
674
754
  : [],
@@ -676,7 +756,7 @@ const useComposerClientResource = ({
676
756
  createdAt: new Date(),
677
757
  parentId: null,
678
758
  sourceId: null,
679
- runConfig: runConfigRef.current,
759
+ runConfig: currentRunConfig,
680
760
  startRun: opts?.startRun,
681
761
  metadata: {
682
762
  custom: { ...(currentQuote ? { quote: currentQuote } : {}) },
@@ -684,7 +764,7 @@ const useComposerClientResource = ({
684
764
  };
685
765
  // edit sends carry a sourceId contract; only thread sends queue
686
766
  if (queue && type === "thread") {
687
- if (opts?.steer ?? canCancel) queue.steer(composedMessage);
767
+ if (opts?.steer ?? isRunning) queue.steer(composedMessage);
688
768
  else queue.enqueue(composedMessage);
689
769
  } else {
690
770
  onSend?.(composedMessage);
@@ -829,6 +909,7 @@ const useExternalThread = ({
829
909
  onStartRun,
830
910
  onCancel,
831
911
  onResume,
912
+ onRefetchThread,
832
913
  onAddToolResult,
833
914
  onResumeToolCall,
834
915
  onLoadExternalState,
@@ -942,7 +1023,15 @@ const useExternalThread = ({
942
1023
  );
943
1024
 
944
1025
  const handleCancelRun = () => {
945
- onCancel?.();
1026
+ // Nothing is aborted without a handler, so pausing the queue would hold
1027
+ // the pending items against a run that keeps going.
1028
+ if (!onCancel) return;
1029
+
1030
+ // Before the run is aborted, so the settle it produces keeps the pending
1031
+ // items instead of dispatching the next one at the moment the user
1032
+ // stopped.
1033
+ queue?.__internal_notifyCancelled?.();
1034
+ onCancel();
946
1035
  };
947
1036
 
948
1037
  const handleSendNew = (message: AppendMessage) => {
@@ -952,6 +1041,8 @@ const useExternalThread = ({
952
1041
  };
953
1042
 
954
1043
  const headId = messages.at(-1)?.id ?? null;
1044
+ const hasCancel = !!onCancel;
1045
+ const hasRefetchThread = !!onRefetchThread;
955
1046
  const composerQueue = useMemo(
956
1047
  (): ExternalThreadQueueAdapter | undefined =>
957
1048
  queue && {
@@ -967,7 +1058,8 @@ const useExternalThread = ({
967
1058
  const composerClient = useClientResource(
968
1059
  ComposerClientResource({
969
1060
  type: "thread",
970
- canCancel: isRunning,
1061
+ canCancel: isRunning && hasCancel,
1062
+ isRunning,
971
1063
  isSendDisabled,
972
1064
  onCancel: handleCancelRun,
973
1065
  onSend: handleSendNew,
@@ -975,6 +1067,9 @@ const useExternalThread = ({
975
1067
  attachmentAdapter,
976
1068
  }),
977
1069
  );
1070
+ const suggestionsClient = useClientResource(
1071
+ ThreadSuggestions(EMPTY_SUGGESTIONS),
1072
+ );
978
1073
 
979
1074
  const hasQueue = !!queue;
980
1075
  const hasBranches = !!branches;
@@ -998,8 +1093,8 @@ const useExternalThread = ({
998
1093
  edit: hasEdit,
999
1094
  delete: false,
1000
1095
  reload: hasReload,
1001
- refetchThread: false,
1002
- cancel: isRunning,
1096
+ refetchThread: hasRefetchThread,
1097
+ cancel: hasCancel,
1003
1098
  speech: hasSpeech,
1004
1099
  attachments: hasAttachments,
1005
1100
  feedback: hasFeedback,
@@ -1012,7 +1107,7 @@ const useExternalThread = ({
1012
1107
  },
1013
1108
  messages: messageStates,
1014
1109
  state: threadState ?? {},
1015
- suggestions: [],
1110
+ suggestions: EMPTY_SUGGESTIONS,
1016
1111
  extras,
1017
1112
  speech,
1018
1113
  voice: undefined,
@@ -1028,6 +1123,8 @@ const useExternalThread = ({
1028
1123
  hasBranches,
1029
1124
  hasEdit,
1030
1125
  hasReload,
1126
+ hasCancel,
1127
+ hasRefetchThread,
1031
1128
  hasAttachments,
1032
1129
  hasFeedback,
1033
1130
  hasSpeech,
@@ -1039,6 +1136,7 @@ const useExternalThread = ({
1039
1136
  return {
1040
1137
  getState: () => state,
1041
1138
  composer: () => composerClient.methods,
1139
+ suggestions: () => suggestionsClient.methods,
1042
1140
  append: (message) => {
1043
1141
  const appendMessage: AppendMessage =
1044
1142
  typeof message === "string"
@@ -1081,6 +1179,7 @@ const useExternalThread = ({
1081
1179
  onResume();
1082
1180
  },
1083
1181
  cancelRun: handleCancelRun,
1182
+ ...(onRefetchThread && { unstable_refetchThread: onRefetchThread }),
1084
1183
  importExternalState: (state: unknown) => {
1085
1184
  if (!onLoadExternalState)
1086
1185
  throw new Error(
@@ -1147,6 +1246,10 @@ attachTransformScopes(useExternalThread, (scopes, parent) => {
1147
1246
  scopes.dataRenderers = DataRenderers();
1148
1247
  }
1149
1248
  if (!scopes.suggestions && parent.suggestions.source === null) {
1150
- scopes.suggestions = Suggestions();
1249
+ scopes.suggestions = Derived({
1250
+ source: "thread",
1251
+ query: {},
1252
+ get: (aui) => aui.thread.suggestions(),
1253
+ });
1151
1254
  }
1152
1255
  });
@@ -39,10 +39,12 @@ describe("ModelContext", () => {
39
39
  it("reflects modelName from a registered provider", async () => {
40
40
  const { sub, unmount } = render();
41
41
  try {
42
- sub.getValue().register(provider({ config: { modelName: "gpt-4" } }));
42
+ sub
43
+ .getValue()
44
+ .register(provider({ config: { modelName: "gpt-5.6-luna" } }));
43
45
  await tick();
44
46
 
45
- expect(sub.getValue().getState().modelName).toBe("gpt-4");
47
+ expect(sub.getValue().getState().modelName).toBe("gpt-5.6-luna");
46
48
  } finally {
47
49
  unmount();
48
50
  }
@@ -67,11 +69,15 @@ describe("ModelContext", () => {
67
69
  it("keeps the same state reference when an extra provider does not change the merged values", async () => {
68
70
  const { sub, unmount } = render();
69
71
  try {
70
- sub.getValue().register(provider({ config: { modelName: "gpt-4" } }));
72
+ sub
73
+ .getValue()
74
+ .register(provider({ config: { modelName: "gpt-5.6-luna" } }));
71
75
  await tick();
72
76
  const before = sub.getValue().getState();
73
77
 
74
- sub.getValue().register(provider({ config: { modelName: "gpt-4" } }));
78
+ sub
79
+ .getValue()
80
+ .register(provider({ config: { modelName: "gpt-5.6-luna" } }));
75
81
  await tick();
76
82
  const after = sub.getValue().getState();
77
83
 
@@ -86,9 +92,9 @@ describe("ModelContext", () => {
86
92
  try {
87
93
  const unsubscribe = sub
88
94
  .getValue()
89
- .register(provider({ config: { modelName: "gpt-4" } }));
95
+ .register(provider({ config: { modelName: "gpt-5.6-luna" } }));
90
96
  await tick();
91
- expect(sub.getValue().getState().modelName).toBe("gpt-4");
97
+ expect(sub.getValue().getState().modelName).toBe("gpt-5.6-luna");
92
98
 
93
99
  unsubscribe();
94
100
  await tick();
@@ -102,9 +108,11 @@ describe("ModelContext", () => {
102
108
  it("reflects modelName synchronously after register without awaiting", () => {
103
109
  const { sub, unmount } = render();
104
110
  try {
105
- sub.getValue().register(provider({ config: { modelName: "gpt-4" } }));
111
+ sub
112
+ .getValue()
113
+ .register(provider({ config: { modelName: "gpt-5.6-luna" } }));
106
114
 
107
- expect(sub.getValue().getState().modelName).toBe("gpt-4");
115
+ expect(sub.getValue().getState().modelName).toBe("gpt-5.6-luna");
108
116
  } finally {
109
117
  unmount();
110
118
  }
@@ -1,7 +1,6 @@
1
1
  import type { AssistantClient, ScopesConfig } from "@assistant-ui/store";
2
2
  import { Derived } from "@assistant-ui/store/client";
3
3
  import { ModelContext } from "./model-context-client";
4
- import { Suggestions } from "./suggestions";
5
4
 
6
5
  export const baseRuntimeAdapterTransformScopes = (
7
6
  scopes: ScopesConfig,
@@ -27,6 +26,10 @@ export const baseRuntimeAdapterTransformScopes = (
27
26
  scopes.modelContext = ModelContext();
28
27
  }
29
28
  if (!scopes.suggestions && parent.suggestions.source === null) {
30
- scopes.suggestions = Suggestions();
29
+ scopes.suggestions = Derived({
30
+ source: "thread",
31
+ query: {},
32
+ get: (aui) => aui.thread.suggestions(),
33
+ });
31
34
  }
32
35
  };
@@ -79,7 +79,8 @@ const useSingleThreadList = ({
79
79
  },
80
80
  getLoadThreadsPromise: () => RESOLVED_PROMISE,
81
81
  reload: () => RESOLVED_PROMISE,
82
- reloadMainThread: () => RESOLVED_PROMISE,
82
+ reloadMainThread: () =>
83
+ threadClient.methods.unstable_refetchThread?.() ?? RESOLVED_PROMISE,
83
84
  loadMore: () => RESOLVED_PROMISE,
84
85
  item: (selector) => {
85
86
  if (
@@ -1,9 +1,10 @@
1
- import { useState } from "react";
1
+ import { useMemo, useState } from "react";
2
2
  import { resource, withKey } from "@assistant-ui/tap";
3
3
  import type { ClientOutput } from "@assistant-ui/store";
4
4
  import { useClientLookup } from "@assistant-ui/store/client";
5
5
  import type { SuggestionsState } from "../scopes/suggestions";
6
6
  import type { SuggestionState } from "../scopes/suggestion";
7
+ import type { ThreadSuggestion } from "../../runtime/interfaces/thread-runtime-core";
7
8
 
8
9
  export type SuggestionConfig =
9
10
  | string
@@ -19,7 +20,24 @@ const useSuggestionClient = (
19
20
 
20
21
  const SuggestionClient = resource(useSuggestionClient);
21
22
 
22
- const useSuggestionsResource = (
23
+ const useSuggestionsClient = (
24
+ state: SuggestionsState,
25
+ ): ClientOutput<"suggestions"> => {
26
+ const suggestionClients = useClientLookup(
27
+ state.suggestions.map((suggestion, index) =>
28
+ withKey(index, SuggestionClient(suggestion), [suggestion]),
29
+ ),
30
+ );
31
+
32
+ return {
33
+ getState: () => state,
34
+ suggestion: ({ index }: { index: number }) => {
35
+ return suggestionClients.get({ index });
36
+ },
37
+ };
38
+ };
39
+
40
+ const useStaticSuggestions = (
23
41
  suggestions?: SuggestionConfig[],
24
42
  ): ClientOutput<"suggestions"> => {
25
43
  const [state] = useState<SuggestionsState>(() => {
@@ -43,18 +61,26 @@ const useSuggestionsResource = (
43
61
  };
44
62
  });
45
63
 
46
- const suggestionClients = useClientLookup(
47
- state.suggestions.map((suggestion, index) =>
48
- withKey(index, SuggestionClient(suggestion), [suggestion]),
49
- ),
64
+ return useSuggestionsClient(state);
65
+ };
66
+
67
+ export const Suggestions = resource(useStaticSuggestions);
68
+
69
+ const useThreadSuggestions = (
70
+ suggestions: readonly ThreadSuggestion[],
71
+ ): ClientOutput<"suggestions"> => {
72
+ const state = useMemo<SuggestionsState>(
73
+ () => ({
74
+ suggestions: suggestions.map((s) => ({
75
+ title: s.title ?? s.prompt,
76
+ label: s.label ?? "",
77
+ prompt: s.prompt,
78
+ })),
79
+ }),
80
+ [suggestions],
50
81
  );
51
82
 
52
- return {
53
- getState: () => state,
54
- suggestion: ({ index }: { index: number }) => {
55
- return suggestionClients.get({ index });
56
- },
57
- };
83
+ return useSuggestionsClient(state);
58
84
  };
59
85
 
60
- export const Suggestions = resource(useSuggestionsResource);
86
+ export const ThreadSuggestions = resource(useThreadSuggestions);
@@ -0,0 +1,21 @@
1
+ import { useEffect, useRef } from "react";
2
+ import { useAssistantEmit } from "@assistant-ui/store/client";
3
+
4
+ /**
5
+ * Emits `threads.selectionChanged` whenever the main thread selection changes.
6
+ * Does not emit for the initially selected thread on mount. Every `threads`
7
+ * client whose selection can change calls this with its current main thread id.
8
+ */
9
+ export const useThreadSelectionEvents = (mainThreadId: string) => {
10
+ const emit = useAssistantEmit();
11
+ const previousMainThreadIdRef = useRef(mainThreadId);
12
+ useEffect(() => {
13
+ const previousThreadId = previousMainThreadIdRef.current;
14
+ if (previousThreadId === mainThreadId) return;
15
+ previousMainThreadIdRef.current = mainThreadId;
16
+ emit("threads.selectionChanged", {
17
+ threadId: mainThreadId,
18
+ previousThreadId,
19
+ });
20
+ }, [mainThreadId, emit]);
21
+ };
@@ -0,0 +1,11 @@
1
+ // Bundlers replace the process.env.NODE_ENV literal statically (Vite, webpack,
2
+ // Metro); the try covers hosts where no process binding exists at runtime.
3
+ export const isDevelopment = (() => {
4
+ try {
5
+ return (
6
+ process.env.NODE_ENV === "development" || process.env.NODE_ENV === "test"
7
+ );
8
+ } catch {
9
+ return false;
10
+ }
11
+ })();
@@ -5,6 +5,7 @@
5
5
  export type {
6
6
  ThreadsState,
7
7
  ThreadsMethods,
8
+ ThreadsEvents,
8
9
  ThreadsClientSchema,
9
10
  } from "./scopes/threads";
10
11
  export type {
@@ -79,7 +80,19 @@ export type {
79
80
  } from "./scopes/chain-of-thought";
80
81
 
81
82
  // runtime wiring
82
- export { RuntimeAdapter } from "../react/RuntimeAdapter";
83
+ export {
84
+ RuntimeAdapter,
85
+ runtimeAdapterTransformScopes,
86
+ } from "../react/RuntimeAdapter";
87
+ export {
88
+ InMemoryThreadList,
89
+ inMemoryThreadListTransformScopes,
90
+ type InMemoryThreadListProps,
91
+ } from "../react/client/InMemoryThreadList";
92
+ export {
93
+ RemoteThreadList,
94
+ type RemoteThreadListProps,
95
+ } from "../react/client/RemoteThreadList";
83
96
  export {
84
97
  useExternalMessageConverter,
85
98
  convertExternalMessages,
@@ -6,3 +6,16 @@ export { ThreadClient } from "./runtime-clients/thread-runtime-client";
6
6
  export { ThreadListItemClient } from "./runtime-clients/thread-list-item-runtime-client";
7
7
  export { ThreadListClient } from "./runtime-clients/thread-list-runtime-client";
8
8
  export { baseRuntimeAdapterTransformScopes } from "./clients/runtime-adapter";
9
+ export {
10
+ actionBarCopyDisabled,
11
+ actionBarEditDisabled,
12
+ actionBarReloadDisabled,
13
+ branchPickerNextDisabled,
14
+ branchPickerPreviousDisabled,
15
+ composerCancelDisabled,
16
+ composerInputDisabled,
17
+ composerSendDisabled,
18
+ suggestionTriggerDisabled,
19
+ } from "./primitive-predicates";
20
+ export { isDevelopment } from "./env";
21
+ export { useThreadSelectionEvents } from "./clients/thread-selection-events";