@assistant-ui/core 0.2.9 → 0.2.11

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 (437) hide show
  1. package/dist/adapters/attachment.d.ts.map +1 -1
  2. package/dist/adapters/attachment.js +22 -12
  3. package/dist/adapters/attachment.js.map +1 -1
  4. package/dist/adapters/directive-formatter.js.map +1 -1
  5. package/dist/adapters/speech.js.map +1 -1
  6. package/dist/index.d.ts +3 -1
  7. package/dist/index.js +2 -1
  8. package/dist/index.js.map +1 -1
  9. package/dist/internal.js +1 -1
  10. package/dist/model-context/frame/host.js.map +1 -1
  11. package/dist/model-context/frame/provider.js.map +1 -1
  12. package/dist/model-context/registry.js.map +1 -1
  13. package/dist/model-context/tool.d.ts +1 -1
  14. package/dist/model-context/tool.js +1 -1
  15. package/dist/model-context/tool.js.map +1 -1
  16. package/dist/model-context/types.js +17 -2
  17. package/dist/model-context/types.js.map +1 -1
  18. package/dist/react/AssistantProvider.js +1 -1
  19. package/dist/react/AssistantRuntimeProvider.d.ts +1 -1
  20. package/dist/react/AssistantRuntimeProvider.d.ts.map +1 -1
  21. package/dist/react/AssistantRuntimeProvider.js +1 -1
  22. package/dist/react/RuntimeAdapter.js +4 -2
  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 +13 -3
  26. package/dist/react/adapters/LocalStorageThreadListAdapter.js.map +1 -1
  27. package/dist/react/client/DataRenderers.d.ts.map +1 -1
  28. package/dist/react/client/DataRenderers.js +6 -5
  29. package/dist/react/client/DataRenderers.js.map +1 -1
  30. package/dist/react/client/Interactables.d.ts.map +1 -1
  31. package/dist/react/client/Interactables.js +30 -29
  32. package/dist/react/client/Interactables.js.map +1 -1
  33. package/dist/react/client/Tools.d.ts.map +1 -1
  34. package/dist/react/client/Tools.js +19 -12
  35. package/dist/react/client/Tools.js.map +1 -1
  36. package/dist/react/index.d.ts +10 -5
  37. package/dist/react/index.js +7 -2
  38. package/dist/react/model-context/define-mcp-toolkit.d.ts +12 -0
  39. package/dist/react/model-context/define-mcp-toolkit.d.ts.map +1 -0
  40. package/dist/react/model-context/define-mcp-toolkit.js +14 -0
  41. package/dist/react/model-context/define-mcp-toolkit.js.map +1 -0
  42. package/dist/react/model-context/define-toolkit.d.ts +10 -12
  43. package/dist/react/model-context/define-toolkit.d.ts.map +1 -1
  44. package/dist/react/model-context/define-toolkit.js +2 -15
  45. package/dist/react/model-context/define-toolkit.js.map +1 -1
  46. package/dist/react/model-context/external-tool.d.ts +14 -0
  47. package/dist/react/model-context/external-tool.d.ts.map +1 -0
  48. package/dist/react/model-context/external-tool.js +17 -0
  49. package/dist/react/model-context/external-tool.js.map +1 -0
  50. package/dist/react/model-context/human-tool.d.ts +27 -0
  51. package/dist/react/model-context/human-tool.d.ts.map +1 -0
  52. package/dist/react/model-context/human-tool.js +30 -0
  53. package/dist/react/model-context/human-tool.js.map +1 -0
  54. package/dist/react/model-context/makeAssistantTool.d.ts +8 -0
  55. package/dist/react/model-context/makeAssistantTool.d.ts.map +1 -1
  56. package/dist/react/model-context/makeAssistantTool.js +4 -0
  57. package/dist/react/model-context/makeAssistantTool.js.map +1 -1
  58. package/dist/react/model-context/makeAssistantToolUI.d.ts +8 -0
  59. package/dist/react/model-context/makeAssistantToolUI.d.ts.map +1 -1
  60. package/dist/react/model-context/makeAssistantToolUI.js +4 -0
  61. package/dist/react/model-context/makeAssistantToolUI.js.map +1 -1
  62. package/dist/react/model-context/provider-tool.d.ts +15 -0
  63. package/dist/react/model-context/provider-tool.d.ts.map +1 -0
  64. package/dist/react/model-context/provider-tool.js +12 -0
  65. package/dist/react/model-context/provider-tool.js.map +1 -0
  66. package/dist/react/model-context/stub-tool.d.ts +12 -0
  67. package/dist/react/model-context/stub-tool.d.ts.map +1 -0
  68. package/dist/react/model-context/stub-tool.js +15 -0
  69. package/dist/react/model-context/stub-tool.js.map +1 -0
  70. package/dist/react/model-context/toolbox.d.ts +64 -17
  71. package/dist/react/model-context/toolbox.d.ts.map +1 -1
  72. package/dist/react/model-context/toolbox.js +19 -1
  73. package/dist/react/model-context/toolbox.js.map +1 -1
  74. package/dist/react/model-context/useAssistantContext.js +1 -1
  75. package/dist/react/model-context/useAssistantContext.js.map +1 -1
  76. package/dist/react/model-context/useAssistantDataUI.js +1 -1
  77. package/dist/react/model-context/useAssistantDataUI.js.map +1 -1
  78. package/dist/react/model-context/useAssistantInstructions.js +1 -1
  79. package/dist/react/model-context/useAssistantInstructions.js.map +1 -1
  80. package/dist/react/model-context/useAssistantInteractable.js +1 -1
  81. package/dist/react/model-context/useAssistantInteractable.js.map +1 -1
  82. package/dist/react/model-context/useAssistantTool.d.ts +11 -1
  83. package/dist/react/model-context/useAssistantTool.d.ts.map +1 -1
  84. package/dist/react/model-context/useAssistantTool.js +12 -6
  85. package/dist/react/model-context/useAssistantTool.js.map +1 -1
  86. package/dist/react/model-context/useAssistantToolUI.d.ts +13 -4
  87. package/dist/react/model-context/useAssistantToolUI.d.ts.map +1 -1
  88. package/dist/react/model-context/useAssistantToolUI.js +7 -4
  89. package/dist/react/model-context/useAssistantToolUI.js.map +1 -1
  90. package/dist/react/model-context/useAuiToolOverrides.d.ts +22 -0
  91. package/dist/react/model-context/useAuiToolOverrides.d.ts.map +1 -0
  92. package/dist/react/model-context/useAuiToolOverrides.js +31 -0
  93. package/dist/react/model-context/useAuiToolOverrides.js.map +1 -0
  94. package/dist/react/model-context/useInlineRender.js +1 -1
  95. package/dist/react/model-context/useInlineRender.js.map +1 -1
  96. package/dist/react/model-context/useInteractableState.js +1 -1
  97. package/dist/react/model-context/useInteractableState.js.map +1 -1
  98. package/dist/react/model-context/useToolArgsStatus.js +1 -1
  99. package/dist/react/primitive-hooks/useActionBarCopy.js +1 -1
  100. package/dist/react/primitive-hooks/useActionBarCopy.js.map +1 -1
  101. package/dist/react/primitive-hooks/useActionBarEdit.js +1 -1
  102. package/dist/react/primitive-hooks/useActionBarEdit.js.map +1 -1
  103. package/dist/react/primitive-hooks/useActionBarFeedback.js +1 -1
  104. package/dist/react/primitive-hooks/useActionBarFeedback.js.map +1 -1
  105. package/dist/react/primitive-hooks/useActionBarReload.js +1 -1
  106. package/dist/react/primitive-hooks/useActionBarReload.js.map +1 -1
  107. package/dist/react/primitive-hooks/useActionBarSpeak.js +1 -1
  108. package/dist/react/primitive-hooks/useActionBarSpeak.js.map +1 -1
  109. package/dist/react/primitive-hooks/useActionBarStopSpeaking.js +1 -1
  110. package/dist/react/primitive-hooks/useActionBarStopSpeaking.js.map +1 -1
  111. package/dist/react/primitive-hooks/useBranchPickerNext.js +1 -1
  112. package/dist/react/primitive-hooks/useBranchPickerNext.js.map +1 -1
  113. package/dist/react/primitive-hooks/useBranchPickerPrevious.js +1 -1
  114. package/dist/react/primitive-hooks/useBranchPickerPrevious.js.map +1 -1
  115. package/dist/react/primitive-hooks/useComposerAddAttachment.js +1 -1
  116. package/dist/react/primitive-hooks/useComposerAddAttachment.js.map +1 -1
  117. package/dist/react/primitive-hooks/useComposerCancel.js +1 -1
  118. package/dist/react/primitive-hooks/useComposerCancel.js.map +1 -1
  119. package/dist/react/primitive-hooks/useComposerDictate.js +1 -1
  120. package/dist/react/primitive-hooks/useComposerDictate.js.map +1 -1
  121. package/dist/react/primitive-hooks/useComposerSend.js +1 -1
  122. package/dist/react/primitive-hooks/useComposerSend.js.map +1 -1
  123. package/dist/react/primitive-hooks/useEditComposerCancel.js +1 -1
  124. package/dist/react/primitive-hooks/useEditComposerCancel.js.map +1 -1
  125. package/dist/react/primitive-hooks/useEditComposerSend.js +1 -1
  126. package/dist/react/primitive-hooks/useEditComposerSend.js.map +1 -1
  127. package/dist/react/primitive-hooks/useMessageBranching.js +1 -1
  128. package/dist/react/primitive-hooks/useMessageBranching.js.map +1 -1
  129. package/dist/react/primitive-hooks/useMessageReload.js +1 -1
  130. package/dist/react/primitive-hooks/useMessageReload.js.map +1 -1
  131. package/dist/react/primitive-hooks/useSuggestionTrigger.js +1 -1
  132. package/dist/react/primitive-hooks/useSuggestionTrigger.js.map +1 -1
  133. package/dist/react/primitive-hooks/useThreadListItemArchive.js +1 -1
  134. package/dist/react/primitive-hooks/useThreadListItemArchive.js.map +1 -1
  135. package/dist/react/primitive-hooks/useThreadListItemDelete.js +1 -1
  136. package/dist/react/primitive-hooks/useThreadListItemDelete.js.map +1 -1
  137. package/dist/react/primitive-hooks/useThreadListItemTrigger.js +1 -1
  138. package/dist/react/primitive-hooks/useThreadListItemTrigger.js.map +1 -1
  139. package/dist/react/primitive-hooks/useThreadListItemUnarchive.js +1 -1
  140. package/dist/react/primitive-hooks/useThreadListItemUnarchive.js.map +1 -1
  141. package/dist/react/primitive-hooks/useThreadListLoadMore.js +1 -1
  142. package/dist/react/primitive-hooks/useThreadListLoadMore.js.map +1 -1
  143. package/dist/react/primitive-hooks/useThreadListNew.js +1 -1
  144. package/dist/react/primitive-hooks/useThreadListNew.js.map +1 -1
  145. package/dist/react/primitive-hooks/useVoice.js +1 -1
  146. package/dist/react/primitive-hooks/useVoice.js.map +1 -1
  147. package/dist/react/primitives/chainOfThought/ChainOfThoughtParts.d.ts +1 -1
  148. package/dist/react/primitives/chainOfThought/ChainOfThoughtParts.js +1 -1
  149. package/dist/react/primitives/chainOfThought/ChainOfThoughtParts.js.map +1 -1
  150. package/dist/react/primitives/composer/ComposerAttachments.js +1 -1
  151. package/dist/react/primitives/composer/ComposerAttachments.js.map +1 -1
  152. package/dist/react/primitives/composer/ComposerQueue.js +1 -1
  153. package/dist/react/primitives/composer/ComposerQueue.js.map +1 -1
  154. package/dist/react/primitives/generativeUI/GenerativeUI.js +1 -1
  155. package/dist/react/primitives/generativeUI/GenerativeUI.js.map +1 -1
  156. package/dist/react/primitives/message/MessageAttachments.js +1 -1
  157. package/dist/react/primitives/message/MessageAttachments.js.map +1 -1
  158. package/dist/react/primitives/message/MessageGroupedParts.js +1 -1
  159. package/dist/react/primitives/message/MessageGroupedParts.js.map +1 -1
  160. package/dist/react/primitives/message/MessageParts.d.ts +1 -1
  161. package/dist/react/primitives/message/MessageParts.js +1 -1
  162. package/dist/react/primitives/message/MessageParts.js.map +1 -1
  163. package/dist/react/primitives/message/MessageQuote.js +1 -1
  164. package/dist/react/primitives/part/PartMessages.d.ts +12 -10
  165. package/dist/react/primitives/part/PartMessages.d.ts.map +1 -1
  166. package/dist/react/primitives/part/PartMessages.js +13 -11
  167. package/dist/react/primitives/part/PartMessages.js.map +1 -1
  168. package/dist/react/primitives/thread/ThreadMessages.js +1 -1
  169. package/dist/react/primitives/thread/ThreadMessages.js.map +1 -1
  170. package/dist/react/primitives/thread/ThreadSuggestions.js +1 -1
  171. package/dist/react/primitives/thread/ThreadSuggestions.js.map +1 -1
  172. package/dist/react/primitives/threadList/ThreadListItems.js +1 -1
  173. package/dist/react/primitives/threadList/ThreadListItems.js.map +1 -1
  174. package/dist/react/providers/AttachmentByIndexProvider.js.map +1 -1
  175. package/dist/react/providers/ChainOfThoughtByIndicesProvider.js.map +1 -1
  176. package/dist/react/providers/ChainOfThoughtPartByIndexProvider.js.map +1 -1
  177. package/dist/react/providers/MessageByIndexProvider.js.map +1 -1
  178. package/dist/react/providers/PartByIndexProvider.js.map +1 -1
  179. package/dist/react/providers/QueueItemByIndexProvider.js.map +1 -1
  180. package/dist/react/providers/ReadonlyThreadProvider.js +1 -1
  181. package/dist/react/providers/ReadonlyThreadProvider.js.map +1 -1
  182. package/dist/react/providers/SuggestionByIndexProvider.js.map +1 -1
  183. package/dist/react/providers/TextMessagePartProvider.d.ts.map +1 -1
  184. package/dist/react/providers/TextMessagePartProvider.js +4 -3
  185. package/dist/react/providers/TextMessagePartProvider.js.map +1 -1
  186. package/dist/react/providers/ThreadListItemByIndexProvider.js.map +1 -1
  187. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.d.ts +7 -0
  188. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.d.ts.map +1 -1
  189. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js +1 -1
  190. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js.map +1 -1
  191. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts +8 -0
  192. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts.map +1 -1
  193. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js +29 -1
  194. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js.map +1 -1
  195. package/dist/react/runtimes/RuntimeAdapterProvider.js +1 -1
  196. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.js +1 -1
  197. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.js.map +1 -1
  198. package/dist/react/runtimes/cloud/useCloudThreadListAdapter.d.ts.map +1 -1
  199. package/dist/react/runtimes/cloud/useCloudThreadListAdapter.js +10 -3
  200. package/dist/react/runtimes/cloud/useCloudThreadListAdapter.js.map +1 -1
  201. package/dist/react/runtimes/createMessageConverter.d.ts +2 -2
  202. package/dist/react/runtimes/createMessageConverter.d.ts.map +1 -1
  203. package/dist/react/runtimes/createMessageConverter.js.map +1 -1
  204. package/dist/react/runtimes/external-message-converter.d.ts +4 -3
  205. package/dist/react/runtimes/external-message-converter.d.ts.map +1 -1
  206. package/dist/react/runtimes/external-message-converter.js +1 -1
  207. package/dist/react/runtimes/external-message-converter.js.map +1 -1
  208. package/dist/react/runtimes/useExternalStoreRuntime.js +1 -1
  209. package/dist/react/runtimes/useExternalStoreSharedOptions.js +1 -1
  210. package/dist/react/runtimes/useLocalRuntime.d.ts +2 -1
  211. package/dist/react/runtimes/useLocalRuntime.d.ts.map +1 -1
  212. package/dist/react/runtimes/useLocalRuntime.js +4 -3
  213. package/dist/react/runtimes/useLocalRuntime.js.map +1 -1
  214. package/dist/react/runtimes/useRemoteThreadListRuntime.js +1 -1
  215. package/dist/react/runtimes/useRemoteThreadListRuntime.js.map +1 -1
  216. package/dist/react/utils/groupParts.d.ts +1 -1
  217. package/dist/react/utils/groupParts.js.map +1 -1
  218. package/dist/runtime/api/attachment-runtime.js.map +1 -1
  219. package/dist/runtime/api/composer-runtime.d.ts +8 -2
  220. package/dist/runtime/api/composer-runtime.d.ts.map +1 -1
  221. package/dist/runtime/api/composer-runtime.js +14 -0
  222. package/dist/runtime/api/composer-runtime.js.map +1 -1
  223. package/dist/runtime/api/message-part-runtime.js.map +1 -1
  224. package/dist/runtime/api/message-runtime.js +1 -1
  225. package/dist/runtime/api/message-runtime.js.map +1 -1
  226. package/dist/runtime/api/thread-list-item-runtime.d.ts +2 -0
  227. package/dist/runtime/api/thread-list-item-runtime.d.ts.map +1 -1
  228. package/dist/runtime/api/thread-list-item-runtime.js +6 -0
  229. package/dist/runtime/api/thread-list-item-runtime.js.map +1 -1
  230. package/dist/runtime/api/thread-runtime.d.ts +7 -0
  231. package/dist/runtime/api/thread-runtime.d.ts.map +1 -1
  232. package/dist/runtime/api/thread-runtime.js.map +1 -1
  233. package/dist/runtime/base/base-composer-runtime-core.d.ts +4 -0
  234. package/dist/runtime/base/base-composer-runtime-core.d.ts.map +1 -1
  235. package/dist/runtime/base/base-composer-runtime-core.js +7 -1
  236. package/dist/runtime/base/base-composer-runtime-core.js.map +1 -1
  237. package/dist/runtime/base/base-thread-runtime-core.js.map +1 -1
  238. package/dist/runtime/base/default-thread-composer-runtime-core.d.ts +4 -0
  239. package/dist/runtime/base/default-thread-composer-runtime-core.d.ts.map +1 -1
  240. package/dist/runtime/base/default-thread-composer-runtime-core.js +17 -1
  241. package/dist/runtime/base/default-thread-composer-runtime-core.js.map +1 -1
  242. package/dist/runtime/interfaces/composer-runtime-core.d.ts +6 -1
  243. package/dist/runtime/interfaces/composer-runtime-core.d.ts.map +1 -1
  244. package/dist/runtime/interfaces/thread-list-runtime-core.d.ts +1 -0
  245. package/dist/runtime/interfaces/thread-list-runtime-core.d.ts.map +1 -1
  246. package/dist/runtime/interfaces/thread-runtime-core.d.ts +4 -0
  247. package/dist/runtime/interfaces/thread-runtime-core.d.ts.map +1 -1
  248. package/dist/runtime/queue/external-thread-queue-adapter.d.ts +20 -0
  249. package/dist/runtime/queue/external-thread-queue-adapter.d.ts.map +1 -0
  250. package/dist/runtime/queue/external-thread-queue-adapter.js +0 -0
  251. package/dist/runtime/queue/message-queue.d.ts +20 -0
  252. package/dist/runtime/queue/message-queue.d.ts.map +1 -0
  253. package/dist/runtime/queue/message-queue.js +97 -0
  254. package/dist/runtime/queue/message-queue.js.map +1 -0
  255. package/dist/runtime/utils/message-repository.js.map +1 -1
  256. package/dist/runtime/utils/thread-message-like.js.map +1 -1
  257. package/dist/runtimes/external-store/external-store-adapter.d.ts +5 -1
  258. package/dist/runtimes/external-store/external-store-adapter.d.ts.map +1 -1
  259. package/dist/runtimes/external-store/external-store-runtime-core.js.map +1 -1
  260. package/dist/runtimes/external-store/external-store-thread-list-runtime-core.d.ts +1 -0
  261. package/dist/runtimes/external-store/external-store-thread-list-runtime-core.d.ts.map +1 -1
  262. package/dist/runtimes/external-store/external-store-thread-list-runtime-core.js +5 -0
  263. package/dist/runtimes/external-store/external-store-thread-list-runtime-core.js.map +1 -1
  264. package/dist/runtimes/external-store/external-store-thread-runtime-core.d.ts +4 -0
  265. package/dist/runtimes/external-store/external-store-thread-runtime-core.d.ts.map +1 -1
  266. package/dist/runtimes/external-store/external-store-thread-runtime-core.js +20 -2
  267. package/dist/runtimes/external-store/external-store-thread-runtime-core.js.map +1 -1
  268. package/dist/runtimes/local/local-runtime-core.js.map +1 -1
  269. package/dist/runtimes/local/local-runtime-options.d.ts +5 -0
  270. package/dist/runtimes/local/local-runtime-options.d.ts.map +1 -1
  271. package/dist/runtimes/local/local-thread-runtime-core.d.ts +7 -0
  272. package/dist/runtimes/local/local-thread-runtime-core.d.ts.map +1 -1
  273. package/dist/runtimes/local/local-thread-runtime-core.js +45 -0
  274. package/dist/runtimes/local/local-thread-runtime-core.js.map +1 -1
  275. package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.d.ts +3 -0
  276. package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.d.ts.map +1 -1
  277. package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.js +3 -0
  278. package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.js.map +1 -1
  279. package/dist/runtimes/remote-thread-list/adapter/in-memory.d.ts +1 -0
  280. package/dist/runtimes/remote-thread-list/adapter/in-memory.d.ts.map +1 -1
  281. package/dist/runtimes/remote-thread-list/adapter/in-memory.js +3 -0
  282. package/dist/runtimes/remote-thread-list/adapter/in-memory.js.map +1 -1
  283. package/dist/runtimes/remote-thread-list/empty-thread-core.d.ts.map +1 -1
  284. package/dist/runtimes/remote-thread-list/empty-thread-core.js +3 -0
  285. package/dist/runtimes/remote-thread-list/empty-thread-core.js.map +1 -1
  286. package/dist/runtimes/remote-thread-list/remote-thread-state.js.map +1 -1
  287. package/dist/runtimes/remote-thread-list/types.d.ts +1 -0
  288. package/dist/runtimes/remote-thread-list/types.d.ts.map +1 -1
  289. package/dist/runtimes/tool-invocations/ToolInvocationTracker.js.map +1 -1
  290. package/dist/store/clients/chain-of-thought-client.d.ts.map +1 -1
  291. package/dist/store/clients/chain-of-thought-client.js +6 -5
  292. package/dist/store/clients/chain-of-thought-client.js.map +1 -1
  293. package/dist/store/clients/model-context-client.d.ts.map +1 -1
  294. package/dist/store/clients/model-context-client.js +6 -5
  295. package/dist/store/clients/model-context-client.js.map +1 -1
  296. package/dist/store/clients/no-op-composer-client.d.ts.map +1 -1
  297. package/dist/store/clients/no-op-composer-client.js +4 -3
  298. package/dist/store/clients/no-op-composer-client.js.map +1 -1
  299. package/dist/store/clients/runtime-adapter.d.ts.map +1 -1
  300. package/dist/store/clients/runtime-adapter.js +7 -6
  301. package/dist/store/clients/runtime-adapter.js.map +1 -1
  302. package/dist/store/clients/suggestions.d.ts.map +1 -1
  303. package/dist/store/clients/suggestions.js +7 -6
  304. package/dist/store/clients/suggestions.js.map +1 -1
  305. package/dist/store/clients/thread-message-client.d.ts.map +1 -1
  306. package/dist/store/clients/thread-message-client.js +13 -12
  307. package/dist/store/clients/thread-message-client.js.map +1 -1
  308. package/dist/store/index.d.ts +1 -1
  309. package/dist/store/runtime-clients/attachment-runtime-client.d.ts.map +1 -1
  310. package/dist/store/runtime-clients/attachment-runtime-client.js +3 -3
  311. package/dist/store/runtime-clients/attachment-runtime-client.js.map +1 -1
  312. package/dist/store/runtime-clients/composer-runtime-client.d.ts +12 -5
  313. package/dist/store/runtime-clients/composer-runtime-client.d.ts.map +1 -1
  314. package/dist/store/runtime-clients/composer-runtime-client.js +32 -16
  315. package/dist/store/runtime-clients/composer-runtime-client.js.map +1 -1
  316. package/dist/store/runtime-clients/message-part-runtime-client.d.ts.map +1 -1
  317. package/dist/store/runtime-clients/message-part-runtime-client.js +3 -3
  318. package/dist/store/runtime-clients/message-part-runtime-client.js.map +1 -1
  319. package/dist/store/runtime-clients/message-runtime-client.d.ts +6 -3
  320. package/dist/store/runtime-clients/message-runtime-client.d.ts.map +1 -1
  321. package/dist/store/runtime-clients/message-runtime-client.js +17 -16
  322. package/dist/store/runtime-clients/message-runtime-client.js.map +1 -1
  323. package/dist/store/runtime-clients/thread-list-item-runtime-client.d.ts.map +1 -1
  324. package/dist/store/runtime-clients/thread-list-item-runtime-client.js +9 -7
  325. package/dist/store/runtime-clients/thread-list-item-runtime-client.js.map +1 -1
  326. package/dist/store/runtime-clients/thread-list-runtime-client.d.ts.map +1 -1
  327. package/dist/store/runtime-clients/thread-list-runtime-client.js +11 -10
  328. package/dist/store/runtime-clients/thread-list-runtime-client.js.map +1 -1
  329. package/dist/store/runtime-clients/thread-runtime-client.d.ts.map +1 -1
  330. package/dist/store/runtime-clients/thread-runtime-client.js +15 -14
  331. package/dist/store/runtime-clients/thread-runtime-client.js.map +1 -1
  332. package/dist/store/runtime-clients/useSubscribable.d.ts +7 -0
  333. package/dist/store/runtime-clients/useSubscribable.d.ts.map +1 -0
  334. package/dist/store/runtime-clients/useSubscribable.js +16 -0
  335. package/dist/store/runtime-clients/useSubscribable.js.map +1 -0
  336. package/dist/store/scope-registration.d.ts +1 -1
  337. package/dist/store/scopes/composer.d.ts +1 -1
  338. package/dist/store/scopes/queue-item.d.ts +2 -1
  339. package/dist/store/scopes/queue-item.d.ts.map +1 -1
  340. package/dist/store/scopes/queue-item.js +6 -0
  341. package/dist/store/scopes/queue-item.js.map +1 -0
  342. package/dist/store/scopes/thread-list-item.d.ts +1 -0
  343. package/dist/store/scopes/thread-list-item.d.ts.map +1 -1
  344. package/dist/store/scopes/thread.d.ts +1 -1
  345. package/dist/store/scopes/threads.d.ts +1 -1
  346. package/dist/types/message.d.ts +2 -1
  347. package/dist/types/message.d.ts.map +1 -1
  348. package/dist/types/message.js.map +1 -1
  349. package/dist/utils/composite-context-provider.d.ts +1 -1
  350. package/dist/utils/composite-context-provider.js +3 -1
  351. package/dist/utils/composite-context-provider.js.map +1 -1
  352. package/dist/utils/json/is-json.js.map +1 -1
  353. package/dist/utils/text.js.map +1 -1
  354. package/package.json +15 -11
  355. package/src/adapters/attachment.ts +24 -4
  356. package/src/index.ts +8 -0
  357. package/src/model-context/tool.ts +1 -1
  358. package/src/model-context/types.ts +21 -3
  359. package/src/react/RuntimeAdapter.ts +6 -4
  360. package/src/react/adapters/LocalStorageThreadListAdapter.tsx +15 -2
  361. package/src/react/client/DataRenderers.ts +48 -42
  362. package/src/react/client/Interactables.ts +263 -267
  363. package/src/react/client/Tools.ts +123 -115
  364. package/src/react/index.ts +16 -3
  365. package/src/react/model-context/define-mcp-toolkit.ts +16 -0
  366. package/src/react/model-context/define-toolkit.test.ts +101 -6
  367. package/src/react/model-context/define-toolkit.ts +35 -18
  368. package/src/react/model-context/external-tool.ts +16 -0
  369. package/src/react/model-context/human-tool.ts +32 -0
  370. package/src/react/model-context/makeAssistantTool.ts +8 -0
  371. package/src/react/model-context/makeAssistantToolUI.ts +8 -0
  372. package/src/react/model-context/provider-tool.ts +30 -0
  373. package/src/react/model-context/stub-tool.ts +14 -0
  374. package/src/react/model-context/toolbox.test.ts +182 -0
  375. package/src/react/model-context/toolbox.ts +191 -23
  376. package/src/react/model-context/useAssistantTool.ts +28 -8
  377. package/src/react/model-context/useAssistantToolUI.ts +13 -4
  378. package/src/react/model-context/useAuiToolOverrides.ts +38 -0
  379. package/src/react/primitives/message/MessageGroupedParts.tsx +1 -1
  380. package/src/react/primitives/part/PartMessages.tsx +12 -10
  381. package/src/react/providers/TextMessagePartProvider.tsx +31 -32
  382. package/src/react/runtimes/RemoteThreadListThreadListRuntimeCore.tsx +43 -0
  383. package/src/react/runtimes/cloud/useCloudThreadListAdapter.tsx +9 -0
  384. package/src/react/runtimes/createMessageConverter.ts +2 -1
  385. package/src/react/runtimes/external-message-converter.ts +5 -3
  386. package/src/react/runtimes/useLocalRuntime.ts +2 -0
  387. package/src/runtime/api/composer-runtime.ts +26 -0
  388. package/src/runtime/api/thread-list-item-runtime.ts +15 -0
  389. package/src/runtime/base/base-composer-runtime-core.ts +11 -0
  390. package/src/runtime/base/default-thread-composer-runtime-core.ts +22 -0
  391. package/src/runtime/interfaces/composer-runtime-core.ts +7 -0
  392. package/src/runtime/interfaces/thread-list-runtime-core.ts +4 -0
  393. package/src/runtime/interfaces/thread-runtime-core.ts +5 -0
  394. package/src/runtime/queue/external-thread-queue-adapter.ts +14 -0
  395. package/src/runtime/queue/message-queue.ts +128 -0
  396. package/src/runtimes/external-store/external-store-adapter.ts +10 -0
  397. package/src/runtimes/external-store/external-store-thread-list-runtime-core.ts +13 -0
  398. package/src/runtimes/external-store/external-store-thread-runtime-core.ts +31 -2
  399. package/src/runtimes/local/local-runtime-options.ts +6 -0
  400. package/src/runtimes/local/local-thread-runtime-core.ts +70 -0
  401. package/src/runtimes/readonly/ReadonlyThreadRuntimeCore.ts +4 -0
  402. package/src/runtimes/remote-thread-list/adapter/in-memory.ts +4 -0
  403. package/src/runtimes/remote-thread-list/empty-thread-core.ts +4 -0
  404. package/src/runtimes/remote-thread-list/types.ts +4 -0
  405. package/src/store/clients/chain-of-thought-client.ts +24 -25
  406. package/src/store/clients/model-context-client.test.ts +87 -2
  407. package/src/store/clients/model-context-client.ts +22 -19
  408. package/src/store/clients/no-op-composer-client.ts +69 -66
  409. package/src/store/clients/runtime-adapter.ts +9 -6
  410. package/src/store/clients/suggestions.ts +41 -40
  411. package/src/store/clients/thread-message-client.ts +127 -132
  412. package/src/store/runtime-clients/attachment-runtime-client.ts +7 -3
  413. package/src/store/runtime-clients/composer-runtime-client.ts +142 -113
  414. package/src/store/runtime-clients/message-part-runtime-client.ts +16 -14
  415. package/src/store/runtime-clients/message-runtime-client.ts +124 -122
  416. package/src/store/runtime-clients/thread-list-item-runtime-client.ts +44 -44
  417. package/src/store/runtime-clients/thread-list-runtime-client.ts +83 -80
  418. package/src/store/runtime-clients/thread-runtime-client.ts +113 -119
  419. package/src/store/runtime-clients/{tap-subscribable.ts → useSubscribable.ts} +4 -4
  420. package/src/store/scopes/queue-item.ts +2 -0
  421. package/src/store/scopes/thread-list-item.ts +1 -0
  422. package/src/tests/RemoteThreadListThreadListRuntimeCore-custom-metadata.test.ts +69 -1
  423. package/src/tests/attachment-adapters.test.ts +86 -0
  424. package/src/tests/external-store-thread-runtime-core.test.ts +125 -0
  425. package/src/tests/message-queue.test.ts +168 -0
  426. package/src/tests/thread-list-runtime-getLoadThreadsPromise.test.ts +1 -0
  427. package/src/types/message.ts +2 -0
  428. package/src/utils/composite-context-provider.ts +3 -1
  429. package/dist/react/model-context/hitl.d.ts +0 -19
  430. package/dist/react/model-context/hitl.d.ts.map +0 -1
  431. package/dist/react/model-context/hitl.js +0 -22
  432. package/dist/react/model-context/hitl.js.map +0 -1
  433. package/dist/store/runtime-clients/tap-subscribable.d.ts +0 -7
  434. package/dist/store/runtime-clients/tap-subscribable.d.ts.map +0 -1
  435. package/dist/store/runtime-clients/tap-subscribable.js +0 -16
  436. package/dist/store/runtime-clients/tap-subscribable.js.map +0 -1
  437. package/src/react/model-context/hitl.ts +0 -22
@@ -1,39 +1,38 @@
1
- import type { FC, PropsWithChildren } from "react";
1
+ import { type FC, type PropsWithChildren, useMemo } from "react";
2
2
  import { useAui, AuiProvider, type ClientOutput } from "@assistant-ui/store";
3
3
  import type { PartState } from "../../store/scopes/part";
4
- import { resource, tapMemo } from "@assistant-ui/tap";
5
4
 
6
- const TextMessagePartClient = resource(
7
- ({
8
- text,
9
- isRunning,
10
- }: {
11
- text: string;
12
- isRunning: boolean;
13
- }): ClientOutput<"part"> => {
14
- const state = tapMemo<PartState>(
15
- () => ({
16
- type: "text",
17
- text,
18
- status: isRunning ? { type: "running" } : { type: "complete" },
19
- }),
20
- [text, isRunning],
21
- );
5
+ import { resource } from "@assistant-ui/tap";
6
+
7
+ const TextMessagePartClient = resource(function TextMessagePartClient({
8
+ text,
9
+ isRunning,
10
+ }: {
11
+ text: string;
12
+ isRunning: boolean;
13
+ }): ClientOutput<"part"> {
14
+ const state = useMemo<PartState>(
15
+ () => ({
16
+ type: "text",
17
+ text,
18
+ status: isRunning ? { type: "running" } : { type: "complete" },
19
+ }),
20
+ [text, isRunning],
21
+ );
22
22
 
23
- return {
24
- getState: () => state,
25
- addToolResult: () => {
26
- throw new Error("Not supported");
27
- },
28
- resumeToolCall: () => {
29
- throw new Error("Not supported");
30
- },
31
- respondToToolApproval: () => {
32
- throw new Error("Not supported");
33
- },
34
- };
35
- },
36
- );
23
+ return {
24
+ getState: () => state,
25
+ addToolResult: () => {
26
+ throw new Error("Not supported");
27
+ },
28
+ resumeToolCall: () => {
29
+ throw new Error("Not supported");
30
+ },
31
+ respondToToolApproval: () => {
32
+ throw new Error("Not supported");
33
+ },
34
+ };
35
+ });
37
36
 
38
37
  export const TextMessagePartProvider: FC<
39
38
  PropsWithChildren<{
@@ -508,6 +508,49 @@ export class RemoteThreadListThreadListRuntimeCore
508
508
  });
509
509
  }
510
510
 
511
+ public updateCustom(
512
+ threadIdOrRemoteId: string,
513
+ custom: Record<string, unknown> | undefined,
514
+ ): Promise<void> {
515
+ const data = this.getItemById(threadIdOrRemoteId);
516
+ if (!data) throw new Error("Thread not found");
517
+ if (data.status === "new") throw new Error("Thread is not yet initialized");
518
+
519
+ if (!this._options.adapter.updateCustom) {
520
+ throw new Error(
521
+ "Remote thread list adapter does not support updating custom metadata",
522
+ );
523
+ }
524
+
525
+ return this._state.optimisticUpdate({
526
+ execute: async () => {
527
+ const { remoteId } = await data.initializeTask;
528
+ const adapter = this._options.adapter;
529
+ if (!adapter.updateCustom) {
530
+ throw new Error(
531
+ "Remote thread list adapter does not support updating custom metadata",
532
+ );
533
+ }
534
+ return adapter.updateCustom(remoteId, custom);
535
+ },
536
+ optimistic: (state) => {
537
+ const data = getThreadData(state, threadIdOrRemoteId);
538
+ if (!data) return state;
539
+
540
+ return {
541
+ ...state,
542
+ threadData: {
543
+ ...state.threadData,
544
+ [data.id]: {
545
+ ...data,
546
+ custom,
547
+ },
548
+ },
549
+ };
550
+ },
551
+ });
552
+ }
553
+
511
554
  private async _ensureThreadIsNotMain(threadId: string) {
512
555
  if (threadId === this.newThreadId)
513
556
  throw new Error("Cannot ensure new thread is not main");
@@ -14,6 +14,7 @@ import { InMemoryThreadListAdapter } from "../../../runtimes/remote-thread-list/
14
14
  import { useAssistantCloudThreadHistoryAdapter } from "./AssistantCloudThreadHistoryAdapter";
15
15
  import { RuntimeAdapterProvider } from "../RuntimeAdapterProvider";
16
16
  import { CloudFileAttachmentAdapter } from "./CloudFileAttachmentAdapter";
17
+ import { isRecord } from "../../../utils/json/is-json";
17
18
 
18
19
  type ThreadData = {
19
20
  externalId: string | undefined;
@@ -26,6 +27,9 @@ type CloudThreadListAdapterOptions = {
26
27
  delete?: ((threadId: string) => Promise<void>) | undefined;
27
28
  };
28
29
 
30
+ const toCustom = (value: unknown): Record<string, unknown> | undefined =>
31
+ isRecord(value) ? value : undefined;
32
+
29
33
  const baseUrl =
30
34
  typeof process !== "undefined" &&
31
35
  process?.env?.NEXT_PUBLIC_ASSISTANT_BASE_URL;
@@ -91,6 +95,7 @@ export const useCloudThreadListAdapter = (
91
95
  remoteId: t.id,
92
96
  title: t.title,
93
97
  externalId: t.external_id ?? undefined,
98
+ custom: toCustom(t.metadata),
94
99
  })),
95
100
  };
96
101
  },
@@ -110,6 +115,9 @@ export const useCloudThreadListAdapter = (
110
115
  rename: async (threadId, newTitle) => {
111
116
  return cloud.threads.update(threadId, { title: newTitle });
112
117
  },
118
+ updateCustom: async (threadId, custom) => {
119
+ return cloud.threads.update(threadId, { metadata: custom ?? null });
120
+ },
113
121
  archive: async (threadId) => {
114
122
  return cloud.threads.update(threadId, { is_archived: true });
115
123
  },
@@ -146,6 +154,7 @@ export const useCloudThreadListAdapter = (
146
154
  remoteId: thread.id,
147
155
  title: thread.title,
148
156
  externalId: thread.external_id ?? undefined,
157
+ custom: toCustom(thread.metadata),
149
158
  };
150
159
  },
151
160
 
@@ -5,6 +5,7 @@ import { useAui, useAuiState } from "@assistant-ui/store";
5
5
  import {
6
6
  useExternalMessageConverter,
7
7
  convertExternalMessages,
8
+ type JoinStrategy,
8
9
  } from "./external-message-converter";
9
10
  import { getExternalStoreMessages } from "../../runtime/utils/external-store-message";
10
11
 
@@ -20,7 +21,7 @@ export const createMessageConverter = <T extends object>(
20
21
  }: {
21
22
  messages: T[];
22
23
  isRunning: boolean;
23
- joinStrategy?: "concat-content" | "none" | undefined;
24
+ joinStrategy?: JoinStrategy | undefined;
24
25
  metadata?: useExternalMessageConverter.Metadata;
25
26
  }) => {
26
27
  return useExternalMessageConverter<T>({
@@ -22,6 +22,8 @@ import type {
22
22
  } from "../../types/message";
23
23
  import type { MessageTiming } from "../../types/message";
24
24
 
25
+ export type JoinStrategy = "concat-content" | "none";
26
+
25
27
  type ThreadMessageLikeContentItem = Exclude<
26
28
  ThreadMessageLike["content"],
27
29
  string
@@ -42,7 +44,7 @@ export namespace useExternalMessageConverter {
42
44
  export type Message =
43
45
  | (ThreadMessageLike & {
44
46
  readonly convertConfig?: {
45
- readonly joinStrategy?: "concat-content" | "none";
47
+ readonly joinStrategy?: JoinStrategy;
46
48
  };
47
49
  })
48
50
  | {
@@ -264,7 +266,7 @@ const joinExternalMessages = (
264
266
 
265
267
  const chunkExternalMessages = <T>(
266
268
  callbackResults: CallbackResult<T>[],
267
- joinStrategy?: "concat-content" | "none",
269
+ joinStrategy?: JoinStrategy,
268
270
  ) => {
269
271
  const results: ChunkResult<T>[] = [];
270
272
  let isAssistant = false;
@@ -397,7 +399,7 @@ export const useExternalMessageConverter = <T extends WeakKey>({
397
399
  callback: useExternalMessageConverter.Callback<T>;
398
400
  messages: T[];
399
401
  isRunning: boolean;
400
- joinStrategy?: "concat-content" | "none" | undefined;
402
+ joinStrategy?: JoinStrategy | undefined;
401
403
  metadata?: useExternalMessageConverter.Metadata | undefined;
402
404
  }) => {
403
405
  const state = useMemo(
@@ -71,6 +71,7 @@ export const splitLocalRuntimeOptions = <T extends LocalRuntimeOptions>(
71
71
  maxSteps,
72
72
  adapters,
73
73
  unstable_humanToolNames,
74
+ unstable_enableMessageQueue,
74
75
  ...rest
75
76
  } = options;
76
77
 
@@ -81,6 +82,7 @@ export const splitLocalRuntimeOptions = <T extends LocalRuntimeOptions>(
81
82
  maxSteps,
82
83
  adapters,
83
84
  unstable_humanToolNames,
85
+ unstable_enableMessageQueue,
84
86
  },
85
87
  otherOptions: rest,
86
88
  };
@@ -3,6 +3,7 @@ import type { MessageRole } from "../../types/message";
3
3
  import type { QuoteInfo } from "../../types/quote";
4
4
  import type { Unsubscribe } from "../../types/unsubscribe";
5
5
  import type { RunConfig } from "../../types/message";
6
+ import type { QueueItemState } from "../../store/scopes/queue-item";
6
7
  import {
7
8
  LazyMemoizeSubject,
8
9
  EventSubscriptionSubject,
@@ -63,6 +64,9 @@ type BaseComposerState = {
63
64
  * Undefined when no quote is set.
64
65
  */
65
66
  readonly quote: QuoteInfo | undefined;
67
+
68
+ /** Messages waiting to be processed. Empty unless the `queue` capability is set. */
69
+ readonly queue: readonly QueueItemState[];
66
70
  };
67
71
 
68
72
  export type ThreadComposerState = BaseComposerState & {
@@ -97,6 +101,7 @@ const getThreadComposerState = (
97
101
  attachmentAccept: runtime?.attachmentAccept ?? "",
98
102
  dictation: runtime?.dictation,
99
103
  quote: runtime?.quote,
104
+ queue: runtime?.queue ?? EMPTY_ARRAY,
100
105
 
101
106
  value: runtime?.text ?? "",
102
107
  });
@@ -120,6 +125,7 @@ const getEditComposerState = (
120
125
  attachmentAccept: runtime?.attachmentAccept ?? "",
121
126
  dictation: runtime?.dictation,
122
127
  quote: runtime?.quote,
128
+ queue: runtime?.queue ?? EMPTY_ARRAY,
123
129
 
124
130
  parentId: runtime?.parentId ?? null,
125
131
  sourceId: runtime?.sourceId ?? null,
@@ -194,6 +200,12 @@ export type ComposerRuntime = {
194
200
  */
195
201
  cancel(): void;
196
202
 
203
+ /** Promote a queued message so it processes next. */
204
+ steerQueueItem(queueItemId: string): void;
205
+
206
+ /** Remove a queued message. */
207
+ removeQueueItem(queueItemId: string): void;
208
+
197
209
  /**
198
210
  * Listens for changes to the composer state.
199
211
  * @param callback The callback to call when the composer state changes.
@@ -251,6 +263,8 @@ export abstract class ComposerRuntimeImpl implements ComposerRuntime {
251
263
  this.clearAttachments = this.clearAttachments.bind(this);
252
264
  this.send = this.send.bind(this);
253
265
  this.cancel = this.cancel.bind(this);
266
+ this.steerQueueItem = this.steerQueueItem.bind(this);
267
+ this.removeQueueItem = this.removeQueueItem.bind(this);
254
268
  this.setRole = this.setRole.bind(this);
255
269
  this.getAttachmentByIndex = this.getAttachmentByIndex.bind(this);
256
270
  this.startDictation = this.startDictation.bind(this);
@@ -303,6 +317,18 @@ export abstract class ComposerRuntimeImpl implements ComposerRuntime {
303
317
  core.cancel();
304
318
  }
305
319
 
320
+ public steerQueueItem(queueItemId: string) {
321
+ const core = this._core.getState();
322
+ if (!core) throw new Error("Composer is not available");
323
+ core.steerQueueItem(queueItemId);
324
+ }
325
+
326
+ public removeQueueItem(queueItemId: string) {
327
+ const core = this._core.getState();
328
+ if (!core) throw new Error("Composer is not available");
329
+ core.removeQueueItem(queueItemId);
330
+ }
331
+
306
332
  public setRole(role: MessageRole) {
307
333
  const core = this._core.getState();
308
334
  if (!core) throw new Error("Composer is not available");
@@ -38,6 +38,7 @@ export type ThreadListItemRuntime = {
38
38
 
39
39
  switchTo(options?: { unarchive?: boolean }): Promise<void>;
40
40
  rename(newTitle: string): Promise<void>;
41
+ updateCustom(custom: Record<string, unknown> | undefined): Promise<void>;
41
42
  archive(): Promise<void>;
42
43
  unarchive(): Promise<void>;
43
44
  delete(): Promise<void>;
@@ -74,6 +75,7 @@ export class ThreadListItemRuntimeImpl implements ThreadListItemRuntime {
74
75
  protected __internal_bindMethods() {
75
76
  this.switchTo = this.switchTo.bind(this);
76
77
  this.rename = this.rename.bind(this);
78
+ this.updateCustom = this.updateCustom.bind(this);
77
79
  this.archive = this.archive.bind(this);
78
80
  this.unarchive = this.unarchive.bind(this);
79
81
  this.delete = this.delete.bind(this);
@@ -100,6 +102,19 @@ export class ThreadListItemRuntimeImpl implements ThreadListItemRuntime {
100
102
  return this._threadListBinding.rename(state.id, newTitle);
101
103
  }
102
104
 
105
+ public updateCustom(
106
+ custom: Record<string, unknown> | undefined,
107
+ ): Promise<void> {
108
+ const state = this._core.getState();
109
+ if (!this._threadListBinding.updateCustom) {
110
+ throw new Error(
111
+ "Thread list runtime does not support updating custom metadata",
112
+ );
113
+ }
114
+
115
+ return this._threadListBinding.updateCustom(state.id, custom);
116
+ }
117
+
103
118
  public archive(): Promise<void> {
104
119
  const state = this._core.getState();
105
120
 
@@ -23,6 +23,10 @@ import type {
23
23
  SendOptions,
24
24
  } from "../interfaces/composer-runtime-core";
25
25
  import type { DictationAdapter } from "../../adapters/speech";
26
+ import {
27
+ EMPTY_QUEUE_ITEMS,
28
+ type QueueItemState,
29
+ } from "../../store/scopes/queue-item";
26
30
  import { generateId } from "../../utils/id";
27
31
 
28
32
  const isAttachmentComplete = (a: Attachment): a is CompleteAttachment =>
@@ -200,6 +204,13 @@ export abstract class BaseComposerRuntimeCore
200
204
  this.handleCancel();
201
205
  }
202
206
 
207
+ public get queue(): readonly QueueItemState[] {
208
+ return EMPTY_QUEUE_ITEMS;
209
+ }
210
+
211
+ public steerQueueItem(_queueItemId: string): void {}
212
+ public removeQueueItem(_queueItemId: string): void {}
213
+
203
214
  protected abstract handleSend(
204
215
  message: Omit<AppendMessage, "parentId" | "sourceId">,
205
216
  options?: SendOptions,
@@ -6,6 +6,10 @@ import type {
6
6
  ThreadComposerRuntimeCore,
7
7
  } from "../interfaces/composer-runtime-core";
8
8
  import type { ThreadRuntimeCore } from "../interfaces/thread-runtime-core";
9
+ import {
10
+ EMPTY_QUEUE_ITEMS,
11
+ type QueueItemState,
12
+ } from "../../store/scopes/queue-item";
9
13
  import { BaseComposerRuntimeCore } from "./base-composer-runtime-core";
10
14
 
11
15
  export class DefaultThreadComposerRuntimeCore
@@ -21,6 +25,18 @@ export class DefaultThreadComposerRuntimeCore
21
25
  return !this.isEmpty && !this.runtime.isSendDisabled;
22
26
  }
23
27
 
28
+ public override get queue(): readonly QueueItemState[] {
29
+ return this.runtime.getQueueItems?.() ?? EMPTY_QUEUE_ITEMS;
30
+ }
31
+
32
+ public override steerQueueItem(queueItemId: string): void {
33
+ this.runtime.steerQueueItem?.(queueItemId);
34
+ }
35
+
36
+ public override removeQueueItem(queueItemId: string): void {
37
+ this.runtime.removeQueueItem?.(queueItemId);
38
+ }
39
+
24
40
  protected getAttachmentAdapter() {
25
41
  return this.runtime.adapters?.attachments;
26
42
  }
@@ -45,6 +61,7 @@ export class DefaultThreadComposerRuntimeCore
45
61
 
46
62
  public connect() {
47
63
  let lastIsSendDisabled = this.runtime.isSendDisabled;
64
+ let lastQueue = this.queue;
48
65
  return this.runtime.subscribe(() => {
49
66
  let changed = false;
50
67
  if (this.canCancel !== this.runtime.capabilities.cancel) {
@@ -55,6 +72,10 @@ export class DefaultThreadComposerRuntimeCore
55
72
  lastIsSendDisabled = this.runtime.isSendDisabled;
56
73
  changed = true;
57
74
  }
75
+ if (lastQueue !== this.queue) {
76
+ lastQueue = this.queue;
77
+ changed = true;
78
+ }
58
79
  if (changed) this._notifySubscribers();
59
80
  });
60
81
  }
@@ -68,6 +89,7 @@ export class DefaultThreadComposerRuntimeCore
68
89
  parentId: this.runtime.messages.at(-1)?.id ?? null,
69
90
  sourceId: null,
70
91
  startRun: options?.startRun,
92
+ steer: options?.steer,
71
93
  });
72
94
  }
73
95
 
@@ -4,6 +4,7 @@ import type { Attachment, CreateAttachment } from "../../types/attachment";
4
4
  import type { Unsubscribe } from "../../types/unsubscribe";
5
5
  import type { RunConfig } from "../../types/message";
6
6
  import type { DictationAdapter } from "../../adapters/speech";
7
+ import type { QueueItemState } from "../../store/scopes/queue-item";
7
8
 
8
9
  export type AttachmentAddErrorReason =
9
10
  | "no-adapter"
@@ -45,6 +46,8 @@ export type DictationState = {
45
46
 
46
47
  export type SendOptions = {
47
48
  startRun?: boolean;
49
+ /** Process this message next; only meaningful with the `queue` capability. */
50
+ steer?: boolean;
48
51
  };
49
52
 
50
53
  export type ComposerRuntimeCore = Readonly<{
@@ -78,6 +81,10 @@ export type ComposerRuntimeCore = Readonly<{
78
81
  send: (options?: SendOptions) => void;
79
82
  cancel: () => void;
80
83
 
84
+ queue: readonly QueueItemState[];
85
+ steerQueueItem: (queueItemId: string) => void;
86
+ removeQueueItem: (queueItemId: string) => void;
87
+
81
88
  dictation: DictationState | undefined;
82
89
  startDictation: () => void;
83
90
  stopDictation: () => void;
@@ -44,6 +44,10 @@ export type ThreadListRuntimeCore = {
44
44
 
45
45
  detach(threadId: string): Promise<void>;
46
46
  rename(threadId: string, newTitle: string): Promise<void>;
47
+ updateCustom?(
48
+ threadId: string,
49
+ custom: Record<string, unknown> | undefined,
50
+ ): Promise<void>;
47
51
  archive(threadId: string): Promise<void>;
48
52
  unarchive(threadId: string): Promise<void>;
49
53
  delete(threadId: string): Promise<void>;
@@ -16,6 +16,7 @@ import type {
16
16
  EditComposerRuntimeCore,
17
17
  ThreadComposerRuntimeCore,
18
18
  } from "./composer-runtime-core";
19
+ import type { QueueItemState } from "../../store/scopes/queue-item";
19
20
 
20
21
  export type RuntimeCapabilities = {
21
22
  readonly switchToBranch: boolean;
@@ -169,6 +170,10 @@ export type ThreadRuntimeCore = Readonly<{
169
170
  getEditComposer: (messageId: string) => EditComposerRuntimeCore | undefined;
170
171
  beginEdit: (messageId: string) => void;
171
172
 
173
+ getQueueItems?: () => readonly QueueItemState[];
174
+ steerQueueItem?: (queueItemId: string) => void;
175
+ removeQueueItem?: (queueItemId: string) => void;
176
+
172
177
  speech: SpeechState | undefined;
173
178
  voice: VoiceSessionState | undefined;
174
179
 
@@ -0,0 +1,14 @@
1
+ import type { AppendMessage } from "../../types/message";
2
+ import type { QueueItemState } from "../../store/scopes/queue-item";
3
+
4
+ /**
5
+ * The queue surface a runtime exposes so the composer can stay usable during a
6
+ * run and render the pending messages.
7
+ */
8
+ export type ExternalThreadQueueAdapter = {
9
+ items: readonly QueueItemState[];
10
+ enqueue: (message: AppendMessage, options: { steer: boolean }) => void;
11
+ steer: (queueItemId: string) => void;
12
+ remove: (queueItemId: string) => void;
13
+ clear: (reason: "edit" | "reload" | "cancel-run") => void;
14
+ };
@@ -0,0 +1,128 @@
1
+ import type { AppendMessage } from "../../types/message";
2
+ import {
3
+ EMPTY_QUEUE_ITEMS,
4
+ type QueueItemState,
5
+ } from "../../store/scopes/queue-item";
6
+ import { generateId } from "../../utils/id";
7
+ import { getThreadMessageText } from "../../utils/text";
8
+ import type { ExternalThreadQueueAdapter } from "./external-thread-queue-adapter";
9
+
10
+ export type MessageQueueDriver = {
11
+ run: (message: AppendMessage, options: { steer: boolean }) => void;
12
+ /** When omitted, `steer` degrades to "process next" instead of interrupting. */
13
+ cancel?: (() => void) | undefined;
14
+ };
15
+
16
+ export type MessageQueueController = {
17
+ readonly adapter: ExternalThreadQueueAdapter;
18
+ /** Mark a run as in flight so concurrent sends buffer; call on the rising edge. */
19
+ notifyBusy: () => void;
20
+ /** Advances to the next pending message; call on the run's falling edge. */
21
+ notifyIdle: () => void;
22
+ subscribe: (callback: () => void) => () => void;
23
+ };
24
+
25
+ export const createMessageQueue = (
26
+ driver: MessageQueueDriver,
27
+ ): MessageQueueController => {
28
+ let items: readonly QueueItemState[] = EMPTY_QUEUE_ITEMS;
29
+ const messages = new Map<string, AppendMessage>();
30
+ const subscribers = new Set<() => void>();
31
+
32
+ let running = false;
33
+ // swallow the cancelled run's settle when steering so it does not double-advance
34
+ let suppressIdle = 0;
35
+
36
+ const notify = () => {
37
+ for (const callback of subscribers) callback();
38
+ };
39
+
40
+ const setItems = (next: readonly QueueItemState[]) => {
41
+ items = next;
42
+ adapter.items = next;
43
+ notify();
44
+ };
45
+
46
+ const advance = () => {
47
+ if (running || items.length === 0) return;
48
+ const head = items[0]!;
49
+ const message = messages.get(head.id);
50
+ messages.delete(head.id);
51
+ setItems(items.slice(1));
52
+ if (!message) return;
53
+ running = true;
54
+ driver.run(message, { steer: false });
55
+ };
56
+
57
+ const enqueue = (message: AppendMessage, { steer }: { steer: boolean }) => {
58
+ const id = generateId();
59
+ const prompt = getThreadMessageText(message);
60
+ messages.set(id, message);
61
+ setItems([...items, { id, prompt }]);
62
+ if (steer) {
63
+ steerItem(id);
64
+ } else {
65
+ advance();
66
+ }
67
+ };
68
+
69
+ const steerItem = (queueItemId: string) => {
70
+ if (!messages.has(queueItemId)) return;
71
+
72
+ if (driver.cancel && running) {
73
+ const message = messages.get(queueItemId)!;
74
+ messages.delete(queueItemId);
75
+ setItems(items.filter((item) => item.id !== queueItemId));
76
+ suppressIdle++;
77
+ driver.cancel();
78
+ running = true;
79
+ driver.run(message, { steer: true });
80
+ return;
81
+ }
82
+
83
+ const target = items.find((item) => item.id === queueItemId);
84
+ if (!target) return;
85
+ setItems([target, ...items.filter((item) => item.id !== queueItemId)]);
86
+ advance();
87
+ };
88
+
89
+ const remove = (queueItemId: string) => {
90
+ if (!messages.delete(queueItemId)) return;
91
+ setItems(items.filter((item) => item.id !== queueItemId));
92
+ };
93
+
94
+ const clear = () => {
95
+ if (items.length === 0) return;
96
+ messages.clear();
97
+ setItems(EMPTY_QUEUE_ITEMS);
98
+ };
99
+
100
+ const adapter: ExternalThreadQueueAdapter = {
101
+ items,
102
+ enqueue,
103
+ steer: steerItem,
104
+ remove,
105
+ clear,
106
+ };
107
+
108
+ return {
109
+ adapter,
110
+ notifyBusy: () => {
111
+ running = true;
112
+ },
113
+ notifyIdle: () => {
114
+ if (suppressIdle > 0) {
115
+ suppressIdle--;
116
+ return;
117
+ }
118
+ running = false;
119
+ advance();
120
+ },
121
+ subscribe: (callback) => {
122
+ subscribers.add(callback);
123
+ return () => {
124
+ subscribers.delete(callback);
125
+ };
126
+ },
127
+ };
128
+ };
@@ -17,6 +17,7 @@ import type {
17
17
  import type { ExportedMessageRepository } from "../../runtime/utils/message-repository";
18
18
  import type { ReadonlyJSONValue } from "assistant-stream/utils";
19
19
  import type { ToolExecutionStatus } from "../tool-invocations/ToolInvocationTracker";
20
+ import type { ExternalThreadQueueAdapter } from "../../runtime/queue/external-thread-queue-adapter";
20
21
 
21
22
  export type ExternalStoreThreadData<TState extends "regular" | "archived"> = {
22
23
  status: TState;
@@ -24,6 +25,7 @@ export type ExternalStoreThreadData<TState extends "regular" | "archived"> = {
24
25
  remoteId?: string | undefined;
25
26
  externalId?: string | undefined;
26
27
  title?: string | undefined;
28
+ custom?: Record<string, unknown> | undefined;
27
29
  };
28
30
 
29
31
  export type ExternalStoreThreadListAdapter = {
@@ -46,6 +48,12 @@ export type ExternalStoreThreadListAdapter = {
46
48
  threadId: string,
47
49
  newTitle: string,
48
50
  ) => (Promise<void> | void) | undefined;
51
+ onUpdateCustom?:
52
+ | ((
53
+ threadId: string,
54
+ custom: Record<string, unknown> | undefined,
55
+ ) => Promise<void> | void)
56
+ | undefined;
49
57
  onArchive?: ((threadId: string) => Promise<void> | void) | undefined;
50
58
  onUnarchive?: ((threadId: string) => Promise<void> | void) | undefined;
51
59
  onDelete?: ((threadId: string) => Promise<void> | void) | undefined;
@@ -98,6 +106,8 @@ type ExternalStoreAdapterBase<T> = {
98
106
  onExportExternalState?: (() => any) | undefined;
99
107
  onLoadExternalState?: ((state: any) => void) | undefined;
100
108
  onNew: (message: AppendMessage) => Promise<void>;
109
+ /** Opt in to message queuing. Typically produced by `createMessageQueue`. */
110
+ queue?: ExternalThreadQueueAdapter | undefined;
101
111
  onEdit?: ((message: AppendMessage) => Promise<void>) | undefined;
102
112
  onReload?: // TODO: remove parentId in 0.12.0
103
113
  | ((parentId: string | null, config: StartRunConfig) => Promise<void>)