@assistant-ui/core 0.2.14 → 0.2.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (319) hide show
  1. package/dist/adapters/attachment.js.map +1 -1
  2. package/dist/adapters/directive-formatter.js.map +1 -1
  3. package/dist/adapters/speech.js.map +1 -1
  4. package/dist/adapters/voice.js.map +1 -1
  5. package/dist/index.d.ts +2 -2
  6. package/dist/index.js.map +1 -1
  7. package/dist/internal/duplicate-detection.js.map +1 -1
  8. package/dist/internal.d.ts +2 -1
  9. package/dist/internal.js +2 -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/frame/types.js.map +1 -1
  13. package/dist/model-context/registry.js.map +1 -1
  14. package/dist/model-context/tool.js.map +1 -1
  15. package/dist/model-context/types.d.ts +1 -0
  16. package/dist/model-context/types.d.ts.map +1 -1
  17. package/dist/model-context/types.js.map +1 -1
  18. package/dist/react/AssistantProvider.js +1 -0
  19. package/dist/react/AssistantProvider.js.map +1 -1
  20. package/dist/react/AssistantRuntimeProvider.js +18 -6
  21. package/dist/react/AssistantRuntimeProvider.js.map +1 -1
  22. package/dist/react/RuntimeAdapter.js +26 -7
  23. package/dist/react/RuntimeAdapter.js.map +1 -1
  24. package/dist/react/adapters/LocalStorageThreadListAdapter.js +29 -7
  25. package/dist/react/adapters/LocalStorageThreadListAdapter.js.map +1 -1
  26. package/dist/react/adapters/TitleGenerationAdapter.js.map +1 -1
  27. package/dist/react/client/DataRenderers.js +54 -35
  28. package/dist/react/client/DataRenderers.js.map +1 -1
  29. package/dist/react/client/Interactables.js +67 -67
  30. package/dist/react/client/Interactables.js.map +1 -1
  31. package/dist/react/client/Tools.d.ts.map +1 -1
  32. package/dist/react/client/Tools.js +118 -55
  33. package/dist/react/client/Tools.js.map +1 -1
  34. package/dist/react/client/interactable-model-context.js.map +1 -1
  35. package/dist/react/model-context/define-mcp-toolkit.js.map +1 -1
  36. package/dist/react/model-context/define-toolkit.js.map +1 -1
  37. package/dist/react/model-context/external-tool.js.map +1 -1
  38. package/dist/react/model-context/human-tool.js.map +1 -1
  39. package/dist/react/model-context/makeAssistantDataUI.js.map +1 -1
  40. package/dist/react/model-context/makeAssistantTool.js.map +1 -1
  41. package/dist/react/model-context/makeAssistantToolUI.js.map +1 -1
  42. package/dist/react/model-context/provider-tool.js.map +1 -1
  43. package/dist/react/model-context/stub-tool.js.map +1 -1
  44. package/dist/react/model-context/toolbox.js.map +1 -1
  45. package/dist/react/model-context/useAssistantContext.js.map +1 -1
  46. package/dist/react/model-context/useAssistantDataUI.js +27 -8
  47. package/dist/react/model-context/useAssistantDataUI.js.map +1 -1
  48. package/dist/react/model-context/useAssistantInstructions.js +33 -10
  49. package/dist/react/model-context/useAssistantInstructions.js.map +1 -1
  50. package/dist/react/model-context/useAssistantInteractable.js.map +1 -1
  51. package/dist/react/model-context/useAssistantTool.js +59 -17
  52. package/dist/react/model-context/useAssistantTool.js.map +1 -1
  53. package/dist/react/model-context/useAssistantToolUI.js +30 -9
  54. package/dist/react/model-context/useAssistantToolUI.js.map +1 -1
  55. package/dist/react/model-context/useAuiToolOverrides.js.map +1 -1
  56. package/dist/react/model-context/useInlineRender.js +35 -8
  57. package/dist/react/model-context/useInlineRender.js.map +1 -1
  58. package/dist/react/model-context/useInteractableState.js +65 -19
  59. package/dist/react/model-context/useInteractableState.js.map +1 -1
  60. package/dist/react/model-context/useToolArgsStatus.js +42 -14
  61. package/dist/react/model-context/useToolArgsStatus.js.map +1 -1
  62. package/dist/react/primitive-hooks/useActionBarCopy.js +59 -22
  63. package/dist/react/primitive-hooks/useActionBarCopy.js.map +1 -1
  64. package/dist/react/primitive-hooks/useActionBarEdit.js +25 -7
  65. package/dist/react/primitive-hooks/useActionBarEdit.js.map +1 -1
  66. package/dist/react/primitive-hooks/useActionBarFeedback.js +49 -13
  67. package/dist/react/primitive-hooks/useActionBarFeedback.js.map +1 -1
  68. package/dist/react/primitive-hooks/useActionBarReload.js +25 -7
  69. package/dist/react/primitive-hooks/useActionBarReload.js.map +1 -1
  70. package/dist/react/primitive-hooks/useActionBarSpeak.js +28 -9
  71. package/dist/react/primitive-hooks/useActionBarSpeak.js.map +1 -1
  72. package/dist/react/primitive-hooks/useActionBarStopSpeaking.js +25 -7
  73. package/dist/react/primitive-hooks/useActionBarStopSpeaking.js.map +1 -1
  74. package/dist/react/primitive-hooks/useBranchPickerNext.js +27 -11
  75. package/dist/react/primitive-hooks/useBranchPickerNext.js.map +1 -1
  76. package/dist/react/primitive-hooks/useBranchPickerPrevious.js +27 -11
  77. package/dist/react/primitive-hooks/useBranchPickerPrevious.js.map +1 -1
  78. package/dist/react/primitive-hooks/useComposerAddAttachment.js +24 -8
  79. package/dist/react/primitive-hooks/useComposerAddAttachment.js.map +1 -1
  80. package/dist/react/primitive-hooks/useComposerCancel.js +25 -7
  81. package/dist/react/primitive-hooks/useComposerCancel.js.map +1 -1
  82. package/dist/react/primitive-hooks/useComposerDictate.js +25 -7
  83. package/dist/react/primitive-hooks/useComposerDictate.js.map +1 -1
  84. package/dist/react/primitive-hooks/useComposerSend.js +25 -7
  85. package/dist/react/primitive-hooks/useComposerSend.js.map +1 -1
  86. package/dist/react/primitive-hooks/useEditComposerCancel.js +18 -4
  87. package/dist/react/primitive-hooks/useEditComposerCancel.js.map +1 -1
  88. package/dist/react/primitive-hooks/useEditComposerSend.js +25 -7
  89. package/dist/react/primitive-hooks/useEditComposerSend.js.map +1 -1
  90. package/dist/react/primitive-hooks/useMessageBranching.js +41 -9
  91. package/dist/react/primitive-hooks/useMessageBranching.js.map +1 -1
  92. package/dist/react/primitive-hooks/useMessageError.js +4 -1
  93. package/dist/react/primitive-hooks/useMessageError.js.map +1 -1
  94. package/dist/react/primitive-hooks/useMessageReload.js +25 -7
  95. package/dist/react/primitive-hooks/useMessageReload.js.map +1 -1
  96. package/dist/react/primitive-hooks/useSuggestionTrigger.js +31 -13
  97. package/dist/react/primitive-hooks/useSuggestionTrigger.js.map +1 -1
  98. package/dist/react/primitive-hooks/useThreadIsEmpty.js +4 -1
  99. package/dist/react/primitive-hooks/useThreadIsEmpty.js.map +1 -1
  100. package/dist/react/primitive-hooks/useThreadIsRunning.js +4 -1
  101. package/dist/react/primitive-hooks/useThreadIsRunning.js.map +1 -1
  102. package/dist/react/primitive-hooks/useThreadListItemArchive.js +18 -4
  103. package/dist/react/primitive-hooks/useThreadListItemArchive.js.map +1 -1
  104. package/dist/react/primitive-hooks/useThreadListItemDelete.js +18 -4
  105. package/dist/react/primitive-hooks/useThreadListItemDelete.js.map +1 -1
  106. package/dist/react/primitive-hooks/useThreadListItemTrigger.js +18 -4
  107. package/dist/react/primitive-hooks/useThreadListItemTrigger.js.map +1 -1
  108. package/dist/react/primitive-hooks/useThreadListItemUnarchive.js +18 -4
  109. package/dist/react/primitive-hooks/useThreadListItemUnarchive.js.map +1 -1
  110. package/dist/react/primitive-hooks/useThreadListLoadMore.js +25 -7
  111. package/dist/react/primitive-hooks/useThreadListLoadMore.js.map +1 -1
  112. package/dist/react/primitive-hooks/useThreadListNew.js +18 -4
  113. package/dist/react/primitive-hooks/useThreadListNew.js.map +1 -1
  114. package/dist/react/primitive-hooks/useThreadMessages.js +4 -1
  115. package/dist/react/primitive-hooks/useThreadMessages.js.map +1 -1
  116. package/dist/react/primitive-hooks/useVoice.js +63 -13
  117. package/dist/react/primitive-hooks/useVoice.js.map +1 -1
  118. package/dist/react/primitives/chainOfThought/ChainOfThoughtParts.js +42 -7
  119. package/dist/react/primitives/chainOfThought/ChainOfThoughtParts.js.map +1 -1
  120. package/dist/react/primitives/composer/ComposerAttachments.js +67 -16
  121. package/dist/react/primitives/composer/ComposerAttachments.js.map +1 -1
  122. package/dist/react/primitives/composer/ComposerIf.js +30 -9
  123. package/dist/react/primitives/composer/ComposerIf.js.map +1 -1
  124. package/dist/react/primitives/composer/ComposerQueue.js.map +1 -1
  125. package/dist/react/primitives/generativeUI/GenerativeUI.js +55 -13
  126. package/dist/react/primitives/generativeUI/GenerativeUI.js.map +1 -1
  127. package/dist/react/primitives/message/MessageAttachments.js +68 -16
  128. package/dist/react/primitives/message/MessageAttachments.js.map +1 -1
  129. package/dist/react/primitives/message/MessageGroupedParts.js +3 -3
  130. package/dist/react/primitives/message/MessageGroupedParts.js.map +1 -1
  131. package/dist/react/primitives/message/MessageParts.js +649 -181
  132. package/dist/react/primitives/message/MessageParts.js.map +1 -1
  133. package/dist/react/primitives/message/MessageQuote.js +18 -2
  134. package/dist/react/primitives/message/MessageQuote.js.map +1 -1
  135. package/dist/react/primitives/messagePart/MessagePartInProgress.js +6 -2
  136. package/dist/react/primitives/messagePart/MessagePartInProgress.js.map +1 -1
  137. package/dist/react/primitives/part/PartMessages.js +46 -14
  138. package/dist/react/primitives/part/PartMessages.js.map +1 -1
  139. package/dist/react/primitives/thread/ThreadMessages.js +67 -10
  140. package/dist/react/primitives/thread/ThreadMessages.js.map +1 -1
  141. package/dist/react/primitives/thread/ThreadSuggestions.js +50 -10
  142. package/dist/react/primitives/thread/ThreadSuggestions.js.map +1 -1
  143. package/dist/react/primitives/threadList/ThreadListItems.js +55 -14
  144. package/dist/react/primitives/threadList/ThreadListItems.js.map +1 -1
  145. package/dist/react/primitives/threadListItem/ThreadListItemTitle.js +15 -2
  146. package/dist/react/primitives/threadListItem/ThreadListItemTitle.js.map +1 -1
  147. package/dist/react/providers/AttachmentByIndexProvider.js +57 -12
  148. package/dist/react/providers/AttachmentByIndexProvider.js.map +1 -1
  149. package/dist/react/providers/ChainOfThoughtByIndicesProvider.js +33 -11
  150. package/dist/react/providers/ChainOfThoughtByIndicesProvider.js.map +1 -1
  151. package/dist/react/providers/ChainOfThoughtPartByIndexProvider.js +29 -6
  152. package/dist/react/providers/ChainOfThoughtPartByIndexProvider.js.map +1 -1
  153. package/dist/react/providers/MessageByIndexProvider.js +49 -19
  154. package/dist/react/providers/MessageByIndexProvider.js.map +1 -1
  155. package/dist/react/providers/PartByIndexProvider.js +29 -6
  156. package/dist/react/providers/PartByIndexProvider.js.map +1 -1
  157. package/dist/react/providers/QueueItemByIndexProvider.js +29 -6
  158. package/dist/react/providers/QueueItemByIndexProvider.js.map +1 -1
  159. package/dist/react/providers/ReadonlyThreadProvider.js +83 -28
  160. package/dist/react/providers/ReadonlyThreadProvider.js.map +1 -1
  161. package/dist/react/providers/SuggestionByIndexProvider.js +29 -6
  162. package/dist/react/providers/SuggestionByIndexProvider.js.map +1 -1
  163. package/dist/react/providers/TextMessagePartProvider.js +73 -25
  164. package/dist/react/providers/TextMessagePartProvider.js.map +1 -1
  165. package/dist/react/providers/ThreadListItemByIndexProvider.js +30 -6
  166. package/dist/react/providers/ThreadListItemByIndexProvider.js.map +1 -1
  167. package/dist/react/providers/ThreadListItemRuntimeProvider.js +28 -5
  168. package/dist/react/providers/ThreadListItemRuntimeProvider.js.map +1 -1
  169. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js +19 -4
  170. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js.map +1 -1
  171. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js.map +1 -1
  172. package/dist/react/runtimes/RuntimeAdapterProvider.js +27 -10
  173. package/dist/react/runtimes/RuntimeAdapterProvider.js.map +1 -1
  174. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.js +10 -1
  175. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.js.map +1 -1
  176. package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.js.map +1 -1
  177. package/dist/react/runtimes/cloud/auiV0.js.map +1 -1
  178. package/dist/react/runtimes/cloud/useCloudThreadListAdapter.js +17 -17
  179. package/dist/react/runtimes/cloud/useCloudThreadListAdapter.js.map +1 -1
  180. package/dist/react/runtimes/createMessageConverter.js.map +1 -1
  181. package/dist/react/runtimes/external-message-converter.d.ts.map +1 -1
  182. package/dist/react/runtimes/external-message-converter.js +67 -30
  183. package/dist/react/runtimes/external-message-converter.js.map +1 -1
  184. package/dist/react/runtimes/useExternalStoreRuntime.js +44 -10
  185. package/dist/react/runtimes/useExternalStoreRuntime.js.map +1 -1
  186. package/dist/react/runtimes/useExternalStoreSharedOptions.js +17 -12
  187. package/dist/react/runtimes/useExternalStoreSharedOptions.js.map +1 -1
  188. package/dist/react/runtimes/useLocalRuntime.js.map +1 -1
  189. package/dist/react/runtimes/useRemoteThreadListRuntime.js +34 -6
  190. package/dist/react/runtimes/useRemoteThreadListRuntime.js.map +1 -1
  191. package/dist/react/types/MessagePartComponentTypes.d.ts +5 -6
  192. package/dist/react/types/MessagePartComponentTypes.d.ts.map +1 -1
  193. package/dist/react/utils/getMessageQuote.js.map +1 -1
  194. package/dist/react/utils/groupParts.js.map +1 -1
  195. package/dist/runtime/api/assistant-runtime.js.map +1 -1
  196. package/dist/runtime/api/attachment-runtime.js.map +1 -1
  197. package/dist/runtime/api/composer-runtime.js.map +1 -1
  198. package/dist/runtime/api/message-part-runtime.d.ts +3 -9
  199. package/dist/runtime/api/message-part-runtime.d.ts.map +1 -1
  200. package/dist/runtime/api/message-part-runtime.js +3 -6
  201. package/dist/runtime/api/message-part-runtime.js.map +1 -1
  202. package/dist/runtime/api/message-runtime.js.map +1 -1
  203. package/dist/runtime/api/thread-list-item-runtime.js.map +1 -1
  204. package/dist/runtime/api/thread-list-runtime.js.map +1 -1
  205. package/dist/runtime/api/thread-runtime.js.map +1 -1
  206. package/dist/runtime/base/base-assistant-runtime-core.js.map +1 -1
  207. package/dist/runtime/base/base-composer-runtime-core.js.map +1 -1
  208. package/dist/runtime/base/base-thread-runtime-core.js.map +1 -1
  209. package/dist/runtime/base/default-edit-composer-runtime-core.js.map +1 -1
  210. package/dist/runtime/base/default-thread-composer-runtime-core.js.map +1 -1
  211. package/dist/runtime/interfaces/thread-runtime-core.d.ts +2 -1
  212. package/dist/runtime/interfaces/thread-runtime-core.d.ts.map +1 -1
  213. package/dist/runtime/queue/message-queue.js.map +1 -1
  214. package/dist/runtime/utils/auto-status.js.map +1 -1
  215. package/dist/runtime/utils/external-store-message.js.map +1 -1
  216. package/dist/runtime/utils/message-repository.js.map +1 -1
  217. package/dist/runtime/utils/resolveToolApprovalResponse.d.ts +15 -0
  218. package/dist/runtime/utils/resolveToolApprovalResponse.d.ts.map +1 -0
  219. package/dist/runtime/utils/resolveToolApprovalResponse.js +35 -0
  220. package/dist/runtime/utils/resolveToolApprovalResponse.js.map +1 -0
  221. package/dist/runtime/utils/thread-message-like.d.ts +5 -1
  222. package/dist/runtime/utils/thread-message-like.d.ts.map +1 -1
  223. package/dist/runtime/utils/thread-message-like.js.map +1 -1
  224. package/dist/runtimes/assistant-transport/utils.js.map +1 -1
  225. package/dist/runtimes/external-store/external-store-runtime-core.js.map +1 -1
  226. package/dist/runtimes/external-store/external-store-shared-options.js.map +1 -1
  227. package/dist/runtimes/external-store/external-store-thread-list-runtime-core.js.map +1 -1
  228. package/dist/runtimes/external-store/external-store-thread-runtime-core.js.map +1 -1
  229. package/dist/runtimes/external-store/thread-message-converter.js.map +1 -1
  230. package/dist/runtimes/local/local-runtime-core.js.map +1 -1
  231. package/dist/runtimes/local/local-thread-list-runtime-core.js.map +1 -1
  232. package/dist/runtimes/local/local-thread-runtime-core.d.ts +1 -0
  233. package/dist/runtimes/local/local-thread-runtime-core.d.ts.map +1 -1
  234. package/dist/runtimes/local/local-thread-runtime-core.js +9 -7
  235. package/dist/runtimes/local/local-thread-runtime-core.js.map +1 -1
  236. package/dist/runtimes/local/should-continue.js +1 -1
  237. package/dist/runtimes/local/should-continue.js.map +1 -1
  238. package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.js.map +1 -1
  239. package/dist/runtimes/remote-thread-list/adapter/in-memory.js.map +1 -1
  240. package/dist/runtimes/remote-thread-list/empty-thread-core.js.map +1 -1
  241. package/dist/runtimes/remote-thread-list/optimistic-state.js.map +1 -1
  242. package/dist/runtimes/remote-thread-list/remote-thread-state.js.map +1 -1
  243. package/dist/runtimes/tool-invocations/ToolInvocationTracker.js.map +1 -1
  244. package/dist/store/clients/chain-of-thought-client.js +37 -19
  245. package/dist/store/clients/chain-of-thought-client.js.map +1 -1
  246. package/dist/store/clients/model-context-client.js +64 -14
  247. package/dist/store/clients/model-context-client.js.map +1 -1
  248. package/dist/store/clients/no-op-composer-client.js +94 -53
  249. package/dist/store/clients/no-op-composer-client.js.map +1 -1
  250. package/dist/store/clients/runtime-adapter.js.map +1 -1
  251. package/dist/store/clients/suggestions.d.ts.map +1 -1
  252. package/dist/store/clients/suggestions.js +59 -21
  253. package/dist/store/clients/suggestions.js.map +1 -1
  254. package/dist/store/clients/thread-message-client.d.ts.map +1 -1
  255. package/dist/store/clients/thread-message-client.js +176 -69
  256. package/dist/store/clients/thread-message-client.js.map +1 -1
  257. package/dist/store/runtime-clients/attachment-runtime-client.js +29 -6
  258. package/dist/store/runtime-clients/attachment-runtime-client.js.map +1 -1
  259. package/dist/store/runtime-clients/composer-runtime-client.d.ts.map +1 -1
  260. package/dist/store/runtime-clients/composer-runtime-client.js +188 -68
  261. package/dist/store/runtime-clients/composer-runtime-client.js.map +1 -1
  262. package/dist/store/runtime-clients/liveRef.d.ts +7 -0
  263. package/dist/store/runtime-clients/liveRef.d.ts.map +1 -0
  264. package/dist/store/runtime-clients/liveRef.js +8 -0
  265. package/dist/store/runtime-clients/liveRef.js.map +1 -0
  266. package/dist/store/runtime-clients/message-part-runtime-client.js +47 -8
  267. package/dist/store/runtime-clients/message-part-runtime-client.js.map +1 -1
  268. package/dist/store/runtime-clients/message-runtime-client.d.ts.map +1 -1
  269. package/dist/store/runtime-clients/message-runtime-client.js +214 -52
  270. package/dist/store/runtime-clients/message-runtime-client.js.map +1 -1
  271. package/dist/store/runtime-clients/thread-list-item-runtime-client.js +69 -25
  272. package/dist/store/runtime-clients/thread-list-item-runtime-client.js.map +1 -1
  273. package/dist/store/runtime-clients/thread-list-runtime-client.d.ts.map +1 -1
  274. package/dist/store/runtime-clients/thread-list-runtime-client.js +137 -34
  275. package/dist/store/runtime-clients/thread-list-runtime-client.js.map +1 -1
  276. package/dist/store/runtime-clients/thread-runtime-client.d.ts.map +1 -1
  277. package/dist/store/runtime-clients/thread-runtime-client.js +192 -71
  278. package/dist/store/runtime-clients/thread-runtime-client.js.map +1 -1
  279. package/dist/store/runtime-clients/useSubscribable.js +2 -9
  280. package/dist/store/runtime-clients/useSubscribable.js.map +1 -1
  281. package/dist/store/scopes/part.d.ts +5 -6
  282. package/dist/store/scopes/part.d.ts.map +1 -1
  283. package/dist/store/scopes/queue-item.js.map +1 -1
  284. package/dist/subscribable/subscribable.js.map +1 -1
  285. package/dist/tests/remote-thread-list-test-helpers.js.map +1 -1
  286. package/dist/types/message.d.ts +38 -5
  287. package/dist/types/message.d.ts.map +1 -1
  288. package/dist/types/message.js.map +1 -1
  289. package/dist/utils/composite-context-provider.js.map +1 -1
  290. package/dist/utils/id.js.map +1 -1
  291. package/dist/utils/json/is-json-equal.js.map +1 -1
  292. package/dist/utils/json/is-json.js.map +1 -1
  293. package/dist/utils/text.js.map +1 -1
  294. package/package.json +6 -6
  295. package/src/index.ts +4 -0
  296. package/src/internal.ts +1 -0
  297. package/src/model-context/types.ts +1 -0
  298. package/src/react/AssistantProvider.tsx +7 -0
  299. package/src/react/client/Tools.ts +3 -5
  300. package/src/react/runtimes/external-message-converter.ts +3 -1
  301. package/src/react/types/MessagePartComponentTypes.ts +5 -5
  302. package/src/runtime/api/message-part-runtime.ts +14 -11
  303. package/src/runtime/interfaces/thread-runtime-core.ts +2 -0
  304. package/src/runtime/utils/resolveToolApprovalResponse.test.ts +91 -0
  305. package/src/runtime/utils/resolveToolApprovalResponse.ts +55 -0
  306. package/src/runtime/utils/thread-message-like.ts +10 -1
  307. package/src/runtimes/local/local-thread-runtime-core.test.ts +61 -2
  308. package/src/runtimes/local/local-thread-runtime-core.ts +17 -8
  309. package/src/runtimes/local/should-continue.ts +2 -1
  310. package/src/store/clients/suggestions.ts +3 -5
  311. package/src/store/clients/thread-message-client.ts +13 -14
  312. package/src/store/runtime-clients/composer-runtime-client.ts +18 -21
  313. package/src/store/runtime-clients/liveRef.ts +5 -0
  314. package/src/store/runtime-clients/message-runtime-client.ts +16 -21
  315. package/src/store/runtime-clients/thread-list-runtime-client.ts +3 -5
  316. package/src/store/runtime-clients/thread-runtime-client.ts +9 -10
  317. package/src/store/runtime-clients/useSubscribable.ts +2 -10
  318. package/src/store/scopes/part.ts +5 -2
  319. package/src/types/message.ts +45 -3
@@ -648,6 +648,7 @@ export class LocalThreadRuntimeCore
648
648
  public respondToToolApproval({
649
649
  approvalId,
650
650
  approved,
651
+ optionId,
651
652
  reason,
652
653
  }: RespondToToolApprovalOptions) {
653
654
  let message = this.repository
@@ -673,14 +674,25 @@ export class LocalThreadRuntimeCore
673
674
  "Tried to respond to a tool approval on a message whose status is not requires-action",
674
675
  );
675
676
 
676
- let recorded = false;
677
+ const target = message.content.find(
678
+ (c) => c.type === "tool-call" && c.approval?.id === approvalId,
679
+ );
680
+ if (target?.type !== "tool-call" || !target.approval)
681
+ throw new Error("Tried to respond to a non-existing tool approval");
682
+ if (target.approval.resolution !== undefined)
683
+ throw new Error(
684
+ "Tried to respond to a tool approval that was cancelled or expired",
685
+ );
686
+ if (target.approval.approved !== undefined)
687
+ throw new Error("Tried to respond to an already decided tool approval");
688
+
689
+ const targetApproval = target.approval;
677
690
  const newContent = message.content.map((c) => {
678
- if (c.type !== "tool-call" || c.approval?.id !== approvalId) return c;
679
- if (c.approval.approved !== undefined) return c;
680
- recorded = true;
691
+ if (c !== target) return c;
681
692
  const approval = {
682
- ...c.approval,
693
+ ...targetApproval,
683
694
  approved,
695
+ ...(optionId != null && { optionId }),
684
696
  ...(reason != null && { reason }),
685
697
  };
686
698
  if (approved) return { ...c, approval };
@@ -692,9 +704,6 @@ export class LocalThreadRuntimeCore
692
704
  };
693
705
  });
694
706
 
695
- if (!recorded)
696
- throw new Error("Tried to respond to an already decided tool approval");
697
-
698
707
  message = { ...message, content: newContent };
699
708
  const { parentId } = this.repository.getMessage(message.id);
700
709
  this.repository.addOrUpdateMessage(parentId, message);
@@ -15,7 +15,8 @@ export const shouldContinue = (
15
15
  c.type === "tool-call" &&
16
16
  c.result === undefined &&
17
17
  c.approval !== undefined &&
18
- c.approval.approved === undefined,
18
+ c.approval.approved === undefined &&
19
+ c.approval.resolution === undefined,
19
20
  );
20
21
  if (hasPendingApproval) return false;
21
22
 
@@ -44,11 +44,9 @@ const useSuggestionsResource = (
44
44
  });
45
45
 
46
46
  const suggestionClients = useClientLookup(
47
- () =>
48
- state.suggestions.map((suggestion, index) =>
49
- withKey(index, SuggestionClient(suggestion)),
50
- ),
51
- [state.suggestions],
47
+ state.suggestions.map((suggestion, index) =>
48
+ withKey(index, SuggestionClient(suggestion), [suggestion]),
49
+ ),
52
50
  );
53
51
 
54
52
  return {
@@ -76,24 +76,23 @@ const useThreadMessageClient = ({
76
76
  const [isHoveringState, setIsHovering] = useState(false);
77
77
 
78
78
  const parts = useClientLookup(
79
- () =>
80
- message.content.map((part, idx) =>
81
- withKey(
82
- "toolCallId" in part && part.toolCallId != null
83
- ? `toolCallId-${part.toolCallId}`
84
- : `index-${idx}`,
85
- ThreadMessagePartClient({ part }),
86
- ),
79
+ message.content.map((part, idx) =>
80
+ withKey(
81
+ "toolCallId" in part && part.toolCallId != null
82
+ ? `toolCallId-${part.toolCallId}`
83
+ : `index-${idx}`,
84
+ ThreadMessagePartClient({ part }),
85
+ [part],
87
86
  ),
88
- [message.content],
87
+ ),
89
88
  );
90
89
 
91
90
  const attachments = useClientLookup(
92
- () =>
93
- (message.attachments ?? []).map((attachment) =>
94
- withKey(attachment.id, ThreadMessageAttachmentClient({ attachment })),
95
- ),
96
- [message.attachments],
91
+ (message.attachments ?? []).map((attachment) =>
92
+ withKey(attachment.id, ThreadMessageAttachmentClient({ attachment }), [
93
+ attachment,
94
+ ]),
95
+ ),
97
96
  );
98
97
 
99
98
  const composer = useResource(NoOpComposerClient({ type: "edit" }));
@@ -102,33 +102,30 @@ const useComposerClient = ({
102
102
  }, [runtime, emit, threadIdRef, messageIdRef]);
103
103
 
104
104
  const attachments = useClientLookup(
105
- () =>
106
- runtimeState.attachments.map((attachment, idx) =>
107
- withKey(
108
- attachment.id,
109
- ComposerAttachmentClientByIndex({
110
- runtime,
111
- index: idx,
112
- }),
113
- ),
105
+ runtimeState.attachments.map((attachment, idx) =>
106
+ withKey(
107
+ attachment.id,
108
+ ComposerAttachmentClientByIndex({
109
+ runtime,
110
+ index: idx,
111
+ }),
112
+ [runtime, idx],
114
113
  ),
115
- [runtimeState.attachments, runtime],
114
+ ),
116
115
  );
117
116
 
118
117
  const queue = runtimeState.queue;
119
118
  const queueItems = useClientLookup(
120
- () =>
121
- queue.map((item) =>
122
- withKey(
123
- item.id,
124
- QueueItemClient({
125
- item,
126
- onSteer: () => runtime.steerQueueItem(item.id),
127
- onRemove: () => runtime.removeQueueItem(item.id),
128
- }),
129
- ),
119
+ queue.map((item) =>
120
+ withKey(
121
+ item.id,
122
+ QueueItemClient({
123
+ item,
124
+ onSteer: () => runtime.steerQueueItem(item.id),
125
+ onRemove: () => runtime.removeQueueItem(item.id),
126
+ }),
130
127
  ),
131
- [queue, runtime],
128
+ ),
132
129
  );
133
130
 
134
131
  const state = useMemo<ComposerState>(() => {
@@ -0,0 +1,5 @@
1
+ export const liveRef = <T>(get: () => T): { readonly current: T } => ({
2
+ get current() {
3
+ return get();
4
+ },
5
+ });
@@ -7,6 +7,7 @@ import {
7
7
  } from "@assistant-ui/store";
8
8
  import type { MessageRuntime } from "../../runtime/api/message-runtime";
9
9
  import { useSubscribable } from "./useSubscribable";
10
+ import { liveRef } from "./liveRef";
10
11
  import { ComposerClient } from "./composer-runtime-client";
11
12
  import { MessagePartClient } from "./message-part-runtime-client";
12
13
  import type { MessageState } from "../scopes/message";
@@ -59,11 +60,7 @@ const useMessageClient = ({
59
60
  const [isHoveringState, setIsHovering] = useState(false);
60
61
 
61
62
  const messageIdRef = useMemo(
62
- () => ({
63
- get current() {
64
- return runtime.getState().id;
65
- },
66
- }),
63
+ () => liveRef(() => runtime.getState().id),
67
64
  [runtime],
68
65
  );
69
66
 
@@ -75,27 +72,25 @@ const useMessageClient = ({
75
72
  }),
76
73
  );
77
74
  const parts = useClientLookup(
78
- () =>
79
- runtimeState.content.map((part, idx) =>
80
- withKey(
81
- "toolCallId" in part && part.toolCallId != null
82
- ? `toolCallId-${part.toolCallId}`
83
- : `index-${idx}`,
84
- MessagePartByIndex({ runtime, index: idx }),
85
- ),
75
+ runtimeState.content.map((part, idx) =>
76
+ withKey(
77
+ "toolCallId" in part && part.toolCallId != null
78
+ ? `toolCallId-${part.toolCallId}`
79
+ : `index-${idx}`,
80
+ MessagePartByIndex({ runtime, index: idx }),
81
+ [runtime, idx],
86
82
  ),
87
- [runtimeState.content, runtime],
83
+ ),
88
84
  );
89
85
 
90
86
  const attachments = useClientLookup(
91
- () =>
92
- (runtimeState.attachments ?? []).map((attachment, idx) =>
93
- withKey(
94
- attachment.id,
95
- MessageAttachmentClientByIndex({ runtime, index: idx }),
96
- ),
87
+ (runtimeState.attachments ?? []).map((attachment, idx) =>
88
+ withKey(
89
+ attachment.id,
90
+ MessageAttachmentClientByIndex({ runtime, index: idx }),
91
+ [runtime, idx],
97
92
  ),
98
- [runtimeState.attachments, runtime],
93
+ ),
99
94
  );
100
95
 
101
96
  const state = useMemo<MessageState>(() => {
@@ -47,11 +47,9 @@ const useThreadListClient = ({
47
47
  }),
48
48
  );
49
49
  const threadItems = useClientLookup(
50
- () =>
51
- Object.keys(runtimeState.threadItems).map((id) =>
52
- withKey(id, ThreadListItemClientById({ runtime, id })),
53
- ),
54
- [runtimeState.threadItems, runtime],
50
+ Object.keys(runtimeState.threadItems).map((id) =>
51
+ withKey(id, ThreadListItemClientById({ runtime, id }), [runtime, id]),
52
+ ),
55
53
  );
56
54
 
57
55
  const state = useMemo<ThreadsState>(() => {
@@ -3,6 +3,7 @@ import type { ThreadRuntimeEventType } from "../../runtime/interfaces/thread-run
3
3
  import type { ThreadRuntime } from "../../runtime/api/thread-runtime";
4
4
  import { useMemo, useEffect, RefObject } from "react";
5
5
  import { useResource, resource, withKey } from "@assistant-ui/tap";
6
+ import { liveRef } from "./liveRef";
6
7
  import {
7
8
  type ClientOutput,
8
9
  useAssistantEmit,
@@ -67,11 +68,7 @@ const useThreadClient = ({
67
68
  }, [runtime, emit]);
68
69
 
69
70
  const threadIdRef = useMemo(
70
- () => ({
71
- get current() {
72
- return runtime.getState()!.threadId;
73
- },
74
- }),
71
+ () => liveRef(() => runtime.getState()!.threadId),
75
72
  [runtime],
76
73
  );
77
74
 
@@ -82,11 +79,13 @@ const useThreadClient = ({
82
79
  }),
83
80
  );
84
81
  const messages = useClientLookup(
85
- () =>
86
- runtimeState.messages.map((m) =>
87
- withKey(m.id, MessageClientById({ runtime, id: m.id, threadIdRef })),
88
- ),
89
- [runtimeState.messages, runtime, threadIdRef],
82
+ runtimeState.messages.map((m) =>
83
+ withKey(m.id, MessageClientById({ runtime, id: m.id, threadIdRef }), [
84
+ runtime,
85
+ m.id,
86
+ threadIdRef,
87
+ ]),
88
+ ),
90
89
  );
91
90
 
92
91
  const state = useMemo<ThreadState>(() => {
@@ -1,16 +1,8 @@
1
- import { useState, useEffect } from "react";
1
+ import { useSyncExternalStore } from "react";
2
2
  import type { SubscribableWithState } from "../../subscribable/subscribable";
3
3
 
4
4
  export const useSubscribable = <T>(
5
5
  subscribable: Omit<SubscribableWithState<T, any>, "path">,
6
6
  ) => {
7
- const [, setState] = useState(subscribable.getState);
8
- useEffect(() => {
9
- setState(subscribable.getState());
10
- return subscribable.subscribe(() => {
11
- setState(subscribable.getState());
12
- });
13
- }, [subscribable]);
14
-
15
- return subscribable.getState();
7
+ return useSyncExternalStore(subscribable.subscribe, subscribable.getState);
16
8
  };
@@ -2,6 +2,7 @@ import type { ToolResponse } from "assistant-stream";
2
2
  import type {
3
3
  ThreadUserMessagePart,
4
4
  ThreadAssistantMessagePart,
5
+ ToolApprovalResponse,
5
6
  ToolCallMessagePartStatus,
6
7
  } from "../../types/message";
7
8
  import type { MessagePartStatus } from "../../types/message";
@@ -27,9 +28,11 @@ export type PartMethods = {
27
28
  */
28
29
  resumeToolCall(payload: unknown): void;
29
30
  /**
30
- * Respond to a server-side tool approval gate. The approval id is read from the part.
31
+ * Respond to a server-side tool approval gate. The approval id is read from
32
+ * the part. Accepts a boolean decision or the id of one of the approval's
33
+ * options.
31
34
  */
32
- respondToToolApproval(response: { approved: boolean; reason?: string }): void;
35
+ respondToToolApproval(response: ToolApprovalResponse): void;
33
36
  __internal_getRuntime?(): MessagePartRuntime;
34
37
  };
35
38
 
@@ -2,10 +2,10 @@ import type {
2
2
  ReadonlyJSONObject,
3
3
  ReadonlyJSONValue,
4
4
  } from "assistant-stream/utils";
5
- import type { ToolModelContentPart } from "assistant-stream";
5
+ import type { ToolCallTiming, ToolModelContentPart } from "assistant-stream";
6
6
  import type { CompleteAttachment } from "./attachment";
7
7
 
8
- export type { ToolModelContentPart };
8
+ export type { ToolCallTiming, ToolModelContentPart };
9
9
 
10
10
  export type TextMessagePart = {
11
11
  readonly type: "text";
@@ -135,6 +135,40 @@ export type ToolCallMessagePartMcpMetadata = {
135
135
  readonly app?: McpAppMetadata;
136
136
  };
137
137
 
138
+ export type ToolApprovalOptionKind =
139
+ | "allow-once"
140
+ | "allow-always"
141
+ | "reject-once"
142
+ | "reject-always";
143
+
144
+ export type ToolApprovalOption = {
145
+ /** Opaque, host-defined identifier. Scope semantics (session vs project vs global) belong to the option supplier. */
146
+ readonly id: string;
147
+ /**
148
+ * Decision class. Drives approved-resolution and default rendering.
149
+ * Open union: `_`-prefixed custom kinds are never auto-resolved and the
150
+ * default kit skips them; they must be answered with an explicit
151
+ * `approved` value (optionally alongside the `optionId`).
152
+ */
153
+ readonly kind: ToolApprovalOptionKind | (string & {});
154
+ /** Human label. Renderers supply defaults per kind when omitted. */
155
+ readonly label?: string;
156
+ readonly description?: string;
157
+ /** Patterns or rules this option would persist, shown before the user commits. Supplied by the host; never derived by the library. */
158
+ readonly grants?: readonly string[];
159
+ /** Opt-in confirmation step before this option resolves. */
160
+ readonly confirm?: boolean | { title?: string; description?: string };
161
+ };
162
+
163
+ export type ToolApprovalResponse =
164
+ | { readonly approved: boolean; readonly reason?: string }
165
+ | { readonly optionId: string; readonly reason?: string }
166
+ | {
167
+ readonly approved: boolean;
168
+ readonly optionId: string;
169
+ readonly reason?: string;
170
+ };
171
+
138
172
  export type ToolCallMessagePart<
139
173
  TArgs = ReadonlyJSONObject,
140
174
  TResult = unknown,
@@ -159,18 +193,26 @@ export type ToolCallMessagePart<
159
193
  readonly argsText: string;
160
194
  /** UI-only artifact associated with the tool result. */
161
195
  readonly artifact?: unknown;
196
+ /** Wall-clock timing for this call, when the runtime or host tracks it. */
197
+ readonly timing?: ToolCallTiming;
162
198
  /** MCP app metadata associated with this tool call, when present. */
163
199
  readonly mcp?: ToolCallMessagePartMcpMetadata;
164
200
  /** Content returned to the model for this tool result. */
165
201
  readonly modelContent?: readonly ToolModelContentPart[] | undefined;
166
202
  /** Human-input request that must be resolved before the run can continue. */
167
203
  readonly interrupt?: { type: "human"; payload: unknown };
168
- /** Server-side approval gate. `approved === undefined` is the only state in which `respondToApproval` may be called. */
204
+ /** Server-side approval gate. `respondToApproval` may only be called while `approved` is undefined and no `resolution` is recorded. */
169
205
  readonly approval?: {
170
206
  readonly id: string;
171
207
  readonly approved?: boolean;
172
208
  readonly reason?: string;
173
209
  readonly isAutomatic?: boolean;
210
+ /** Available decisions for this call. Absent: a plain allow / deny pair. */
211
+ readonly options?: readonly ToolApprovalOption[];
212
+ /** The option chosen at resolution, when options were present. */
213
+ readonly optionId?: string;
214
+ /** Terminal non-decision state: the request was cancelled or expired without a user decision. Set by the host. */
215
+ readonly resolution?: "cancelled" | "expired";
174
216
  };
175
217
  /** Parent message-part ID when this part belongs to a nested structure. */
176
218
  readonly parentId?: string;