@assistant-ui/core 0.2.14 → 0.2.16

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 (323) 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.d.ts +3 -3
  45. package/dist/react/model-context/toolbox.d.ts.map +1 -1
  46. package/dist/react/model-context/toolbox.js.map +1 -1
  47. package/dist/react/model-context/useAssistantContext.js.map +1 -1
  48. package/dist/react/model-context/useAssistantDataUI.js +27 -8
  49. package/dist/react/model-context/useAssistantDataUI.js.map +1 -1
  50. package/dist/react/model-context/useAssistantInstructions.js +33 -10
  51. package/dist/react/model-context/useAssistantInstructions.js.map +1 -1
  52. package/dist/react/model-context/useAssistantInteractable.js.map +1 -1
  53. package/dist/react/model-context/useAssistantTool.js +59 -17
  54. package/dist/react/model-context/useAssistantTool.js.map +1 -1
  55. package/dist/react/model-context/useAssistantToolUI.js +30 -9
  56. package/dist/react/model-context/useAssistantToolUI.js.map +1 -1
  57. package/dist/react/model-context/useAuiToolOverrides.js.map +1 -1
  58. package/dist/react/model-context/useInlineRender.js +35 -8
  59. package/dist/react/model-context/useInlineRender.js.map +1 -1
  60. package/dist/react/model-context/useInteractableState.js +65 -19
  61. package/dist/react/model-context/useInteractableState.js.map +1 -1
  62. package/dist/react/model-context/useToolArgsStatus.js +42 -14
  63. package/dist/react/model-context/useToolArgsStatus.js.map +1 -1
  64. package/dist/react/primitive-hooks/useActionBarCopy.js +59 -22
  65. package/dist/react/primitive-hooks/useActionBarCopy.js.map +1 -1
  66. package/dist/react/primitive-hooks/useActionBarEdit.js +25 -7
  67. package/dist/react/primitive-hooks/useActionBarEdit.js.map +1 -1
  68. package/dist/react/primitive-hooks/useActionBarFeedback.js +49 -13
  69. package/dist/react/primitive-hooks/useActionBarFeedback.js.map +1 -1
  70. package/dist/react/primitive-hooks/useActionBarReload.js +25 -7
  71. package/dist/react/primitive-hooks/useActionBarReload.js.map +1 -1
  72. package/dist/react/primitive-hooks/useActionBarSpeak.js +28 -9
  73. package/dist/react/primitive-hooks/useActionBarSpeak.js.map +1 -1
  74. package/dist/react/primitive-hooks/useActionBarStopSpeaking.js +25 -7
  75. package/dist/react/primitive-hooks/useActionBarStopSpeaking.js.map +1 -1
  76. package/dist/react/primitive-hooks/useBranchPickerNext.js +27 -11
  77. package/dist/react/primitive-hooks/useBranchPickerNext.js.map +1 -1
  78. package/dist/react/primitive-hooks/useBranchPickerPrevious.js +27 -11
  79. package/dist/react/primitive-hooks/useBranchPickerPrevious.js.map +1 -1
  80. package/dist/react/primitive-hooks/useComposerAddAttachment.js +24 -8
  81. package/dist/react/primitive-hooks/useComposerAddAttachment.js.map +1 -1
  82. package/dist/react/primitive-hooks/useComposerCancel.js +25 -7
  83. package/dist/react/primitive-hooks/useComposerCancel.js.map +1 -1
  84. package/dist/react/primitive-hooks/useComposerDictate.js +25 -7
  85. package/dist/react/primitive-hooks/useComposerDictate.js.map +1 -1
  86. package/dist/react/primitive-hooks/useComposerSend.js +25 -7
  87. package/dist/react/primitive-hooks/useComposerSend.js.map +1 -1
  88. package/dist/react/primitive-hooks/useEditComposerCancel.js +18 -4
  89. package/dist/react/primitive-hooks/useEditComposerCancel.js.map +1 -1
  90. package/dist/react/primitive-hooks/useEditComposerSend.js +25 -7
  91. package/dist/react/primitive-hooks/useEditComposerSend.js.map +1 -1
  92. package/dist/react/primitive-hooks/useMessageBranching.js +41 -9
  93. package/dist/react/primitive-hooks/useMessageBranching.js.map +1 -1
  94. package/dist/react/primitive-hooks/useMessageError.js +4 -1
  95. package/dist/react/primitive-hooks/useMessageError.js.map +1 -1
  96. package/dist/react/primitive-hooks/useMessageReload.js +25 -7
  97. package/dist/react/primitive-hooks/useMessageReload.js.map +1 -1
  98. package/dist/react/primitive-hooks/useSuggestionTrigger.js +31 -13
  99. package/dist/react/primitive-hooks/useSuggestionTrigger.js.map +1 -1
  100. package/dist/react/primitive-hooks/useThreadIsEmpty.js +4 -1
  101. package/dist/react/primitive-hooks/useThreadIsEmpty.js.map +1 -1
  102. package/dist/react/primitive-hooks/useThreadIsRunning.js +4 -1
  103. package/dist/react/primitive-hooks/useThreadIsRunning.js.map +1 -1
  104. package/dist/react/primitive-hooks/useThreadListItemArchive.js +18 -4
  105. package/dist/react/primitive-hooks/useThreadListItemArchive.js.map +1 -1
  106. package/dist/react/primitive-hooks/useThreadListItemDelete.js +18 -4
  107. package/dist/react/primitive-hooks/useThreadListItemDelete.js.map +1 -1
  108. package/dist/react/primitive-hooks/useThreadListItemTrigger.js +18 -4
  109. package/dist/react/primitive-hooks/useThreadListItemTrigger.js.map +1 -1
  110. package/dist/react/primitive-hooks/useThreadListItemUnarchive.js +18 -4
  111. package/dist/react/primitive-hooks/useThreadListItemUnarchive.js.map +1 -1
  112. package/dist/react/primitive-hooks/useThreadListLoadMore.js +25 -7
  113. package/dist/react/primitive-hooks/useThreadListLoadMore.js.map +1 -1
  114. package/dist/react/primitive-hooks/useThreadListNew.js +18 -4
  115. package/dist/react/primitive-hooks/useThreadListNew.js.map +1 -1
  116. package/dist/react/primitive-hooks/useThreadMessages.js +4 -1
  117. package/dist/react/primitive-hooks/useThreadMessages.js.map +1 -1
  118. package/dist/react/primitive-hooks/useVoice.js +63 -13
  119. package/dist/react/primitive-hooks/useVoice.js.map +1 -1
  120. package/dist/react/primitives/chainOfThought/ChainOfThoughtParts.js +42 -7
  121. package/dist/react/primitives/chainOfThought/ChainOfThoughtParts.js.map +1 -1
  122. package/dist/react/primitives/composer/ComposerAttachments.js +67 -16
  123. package/dist/react/primitives/composer/ComposerAttachments.js.map +1 -1
  124. package/dist/react/primitives/composer/ComposerIf.js +30 -9
  125. package/dist/react/primitives/composer/ComposerIf.js.map +1 -1
  126. package/dist/react/primitives/composer/ComposerQueue.js.map +1 -1
  127. package/dist/react/primitives/generativeUI/GenerativeUI.js +55 -13
  128. package/dist/react/primitives/generativeUI/GenerativeUI.js.map +1 -1
  129. package/dist/react/primitives/message/MessageAttachments.js +68 -16
  130. package/dist/react/primitives/message/MessageAttachments.js.map +1 -1
  131. package/dist/react/primitives/message/MessageGroupedParts.js +3 -3
  132. package/dist/react/primitives/message/MessageGroupedParts.js.map +1 -1
  133. package/dist/react/primitives/message/MessageParts.js +649 -181
  134. package/dist/react/primitives/message/MessageParts.js.map +1 -1
  135. package/dist/react/primitives/message/MessageQuote.js +18 -2
  136. package/dist/react/primitives/message/MessageQuote.js.map +1 -1
  137. package/dist/react/primitives/messagePart/MessagePartInProgress.js +6 -2
  138. package/dist/react/primitives/messagePart/MessagePartInProgress.js.map +1 -1
  139. package/dist/react/primitives/part/PartMessages.js +46 -14
  140. package/dist/react/primitives/part/PartMessages.js.map +1 -1
  141. package/dist/react/primitives/thread/ThreadMessages.js +67 -10
  142. package/dist/react/primitives/thread/ThreadMessages.js.map +1 -1
  143. package/dist/react/primitives/thread/ThreadSuggestions.js +50 -10
  144. package/dist/react/primitives/thread/ThreadSuggestions.js.map +1 -1
  145. package/dist/react/primitives/threadList/ThreadListItems.js +55 -14
  146. package/dist/react/primitives/threadList/ThreadListItems.js.map +1 -1
  147. package/dist/react/primitives/threadListItem/ThreadListItemTitle.js +15 -2
  148. package/dist/react/primitives/threadListItem/ThreadListItemTitle.js.map +1 -1
  149. package/dist/react/providers/AttachmentByIndexProvider.js +57 -12
  150. package/dist/react/providers/AttachmentByIndexProvider.js.map +1 -1
  151. package/dist/react/providers/ChainOfThoughtByIndicesProvider.js +33 -11
  152. package/dist/react/providers/ChainOfThoughtByIndicesProvider.js.map +1 -1
  153. package/dist/react/providers/ChainOfThoughtPartByIndexProvider.js +29 -6
  154. package/dist/react/providers/ChainOfThoughtPartByIndexProvider.js.map +1 -1
  155. package/dist/react/providers/MessageByIndexProvider.js +49 -19
  156. package/dist/react/providers/MessageByIndexProvider.js.map +1 -1
  157. package/dist/react/providers/PartByIndexProvider.js +29 -6
  158. package/dist/react/providers/PartByIndexProvider.js.map +1 -1
  159. package/dist/react/providers/QueueItemByIndexProvider.js +29 -6
  160. package/dist/react/providers/QueueItemByIndexProvider.js.map +1 -1
  161. package/dist/react/providers/ReadonlyThreadProvider.js +83 -28
  162. package/dist/react/providers/ReadonlyThreadProvider.js.map +1 -1
  163. package/dist/react/providers/SuggestionByIndexProvider.js +29 -6
  164. package/dist/react/providers/SuggestionByIndexProvider.js.map +1 -1
  165. package/dist/react/providers/TextMessagePartProvider.js +73 -25
  166. package/dist/react/providers/TextMessagePartProvider.js.map +1 -1
  167. package/dist/react/providers/ThreadListItemByIndexProvider.js +30 -6
  168. package/dist/react/providers/ThreadListItemByIndexProvider.js.map +1 -1
  169. package/dist/react/providers/ThreadListItemRuntimeProvider.js +28 -5
  170. package/dist/react/providers/ThreadListItemRuntimeProvider.js.map +1 -1
  171. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js +19 -4
  172. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js.map +1 -1
  173. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js.map +1 -1
  174. package/dist/react/runtimes/RuntimeAdapterProvider.js +27 -10
  175. package/dist/react/runtimes/RuntimeAdapterProvider.js.map +1 -1
  176. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.js +10 -1
  177. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.js.map +1 -1
  178. package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.js.map +1 -1
  179. package/dist/react/runtimes/cloud/auiV0.js.map +1 -1
  180. package/dist/react/runtimes/cloud/useCloudThreadListAdapter.js +17 -17
  181. package/dist/react/runtimes/cloud/useCloudThreadListAdapter.js.map +1 -1
  182. package/dist/react/runtimes/createMessageConverter.js.map +1 -1
  183. package/dist/react/runtimes/external-message-converter.d.ts.map +1 -1
  184. package/dist/react/runtimes/external-message-converter.js +67 -30
  185. package/dist/react/runtimes/external-message-converter.js.map +1 -1
  186. package/dist/react/runtimes/useExternalStoreRuntime.js +44 -10
  187. package/dist/react/runtimes/useExternalStoreRuntime.js.map +1 -1
  188. package/dist/react/runtimes/useExternalStoreSharedOptions.js +17 -12
  189. package/dist/react/runtimes/useExternalStoreSharedOptions.js.map +1 -1
  190. package/dist/react/runtimes/useLocalRuntime.js.map +1 -1
  191. package/dist/react/runtimes/useRemoteThreadListRuntime.js +34 -6
  192. package/dist/react/runtimes/useRemoteThreadListRuntime.js.map +1 -1
  193. package/dist/react/types/MessagePartComponentTypes.d.ts +5 -6
  194. package/dist/react/types/MessagePartComponentTypes.d.ts.map +1 -1
  195. package/dist/react/utils/getMessageQuote.js.map +1 -1
  196. package/dist/react/utils/groupParts.js.map +1 -1
  197. package/dist/runtime/api/assistant-runtime.js.map +1 -1
  198. package/dist/runtime/api/attachment-runtime.js.map +1 -1
  199. package/dist/runtime/api/composer-runtime.js.map +1 -1
  200. package/dist/runtime/api/message-part-runtime.d.ts +3 -9
  201. package/dist/runtime/api/message-part-runtime.d.ts.map +1 -1
  202. package/dist/runtime/api/message-part-runtime.js +3 -6
  203. package/dist/runtime/api/message-part-runtime.js.map +1 -1
  204. package/dist/runtime/api/message-runtime.js.map +1 -1
  205. package/dist/runtime/api/thread-list-item-runtime.js.map +1 -1
  206. package/dist/runtime/api/thread-list-runtime.js.map +1 -1
  207. package/dist/runtime/api/thread-runtime.js.map +1 -1
  208. package/dist/runtime/base/base-assistant-runtime-core.js.map +1 -1
  209. package/dist/runtime/base/base-composer-runtime-core.js.map +1 -1
  210. package/dist/runtime/base/base-thread-runtime-core.js.map +1 -1
  211. package/dist/runtime/base/default-edit-composer-runtime-core.js.map +1 -1
  212. package/dist/runtime/base/default-thread-composer-runtime-core.js.map +1 -1
  213. package/dist/runtime/interfaces/thread-runtime-core.d.ts +2 -1
  214. package/dist/runtime/interfaces/thread-runtime-core.d.ts.map +1 -1
  215. package/dist/runtime/queue/message-queue.js.map +1 -1
  216. package/dist/runtime/utils/auto-status.js.map +1 -1
  217. package/dist/runtime/utils/external-store-message.js.map +1 -1
  218. package/dist/runtime/utils/message-repository.js.map +1 -1
  219. package/dist/runtime/utils/resolveToolApprovalResponse.d.ts +15 -0
  220. package/dist/runtime/utils/resolveToolApprovalResponse.d.ts.map +1 -0
  221. package/dist/runtime/utils/resolveToolApprovalResponse.js +35 -0
  222. package/dist/runtime/utils/resolveToolApprovalResponse.js.map +1 -0
  223. package/dist/runtime/utils/thread-message-like.d.ts +5 -1
  224. package/dist/runtime/utils/thread-message-like.d.ts.map +1 -1
  225. package/dist/runtime/utils/thread-message-like.js.map +1 -1
  226. package/dist/runtimes/assistant-transport/utils.js.map +1 -1
  227. package/dist/runtimes/external-store/external-store-runtime-core.js.map +1 -1
  228. package/dist/runtimes/external-store/external-store-shared-options.js.map +1 -1
  229. package/dist/runtimes/external-store/external-store-thread-list-runtime-core.js.map +1 -1
  230. package/dist/runtimes/external-store/external-store-thread-runtime-core.js.map +1 -1
  231. package/dist/runtimes/external-store/thread-message-converter.js.map +1 -1
  232. package/dist/runtimes/local/local-runtime-core.js.map +1 -1
  233. package/dist/runtimes/local/local-thread-list-runtime-core.js.map +1 -1
  234. package/dist/runtimes/local/local-thread-runtime-core.d.ts +1 -0
  235. package/dist/runtimes/local/local-thread-runtime-core.d.ts.map +1 -1
  236. package/dist/runtimes/local/local-thread-runtime-core.js +9 -7
  237. package/dist/runtimes/local/local-thread-runtime-core.js.map +1 -1
  238. package/dist/runtimes/local/should-continue.js +1 -1
  239. package/dist/runtimes/local/should-continue.js.map +1 -1
  240. package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.js.map +1 -1
  241. package/dist/runtimes/remote-thread-list/adapter/in-memory.js.map +1 -1
  242. package/dist/runtimes/remote-thread-list/empty-thread-core.js.map +1 -1
  243. package/dist/runtimes/remote-thread-list/optimistic-state.js.map +1 -1
  244. package/dist/runtimes/remote-thread-list/remote-thread-state.js.map +1 -1
  245. package/dist/runtimes/tool-invocations/ToolInvocationTracker.js.map +1 -1
  246. package/dist/store/clients/chain-of-thought-client.js +37 -19
  247. package/dist/store/clients/chain-of-thought-client.js.map +1 -1
  248. package/dist/store/clients/model-context-client.js +64 -14
  249. package/dist/store/clients/model-context-client.js.map +1 -1
  250. package/dist/store/clients/no-op-composer-client.js +94 -53
  251. package/dist/store/clients/no-op-composer-client.js.map +1 -1
  252. package/dist/store/clients/runtime-adapter.js.map +1 -1
  253. package/dist/store/clients/suggestions.d.ts.map +1 -1
  254. package/dist/store/clients/suggestions.js +59 -21
  255. package/dist/store/clients/suggestions.js.map +1 -1
  256. package/dist/store/clients/thread-message-client.d.ts.map +1 -1
  257. package/dist/store/clients/thread-message-client.js +176 -69
  258. package/dist/store/clients/thread-message-client.js.map +1 -1
  259. package/dist/store/runtime-clients/attachment-runtime-client.js +29 -6
  260. package/dist/store/runtime-clients/attachment-runtime-client.js.map +1 -1
  261. package/dist/store/runtime-clients/composer-runtime-client.d.ts.map +1 -1
  262. package/dist/store/runtime-clients/composer-runtime-client.js +188 -68
  263. package/dist/store/runtime-clients/composer-runtime-client.js.map +1 -1
  264. package/dist/store/runtime-clients/liveRef.d.ts +7 -0
  265. package/dist/store/runtime-clients/liveRef.d.ts.map +1 -0
  266. package/dist/store/runtime-clients/liveRef.js +8 -0
  267. package/dist/store/runtime-clients/liveRef.js.map +1 -0
  268. package/dist/store/runtime-clients/message-part-runtime-client.js +47 -8
  269. package/dist/store/runtime-clients/message-part-runtime-client.js.map +1 -1
  270. package/dist/store/runtime-clients/message-runtime-client.d.ts.map +1 -1
  271. package/dist/store/runtime-clients/message-runtime-client.js +214 -52
  272. package/dist/store/runtime-clients/message-runtime-client.js.map +1 -1
  273. package/dist/store/runtime-clients/thread-list-item-runtime-client.js +69 -25
  274. package/dist/store/runtime-clients/thread-list-item-runtime-client.js.map +1 -1
  275. package/dist/store/runtime-clients/thread-list-runtime-client.d.ts.map +1 -1
  276. package/dist/store/runtime-clients/thread-list-runtime-client.js +137 -34
  277. package/dist/store/runtime-clients/thread-list-runtime-client.js.map +1 -1
  278. package/dist/store/runtime-clients/thread-runtime-client.d.ts.map +1 -1
  279. package/dist/store/runtime-clients/thread-runtime-client.js +192 -71
  280. package/dist/store/runtime-clients/thread-runtime-client.js.map +1 -1
  281. package/dist/store/runtime-clients/useSubscribable.js +2 -9
  282. package/dist/store/runtime-clients/useSubscribable.js.map +1 -1
  283. package/dist/store/scopes/part.d.ts +5 -6
  284. package/dist/store/scopes/part.d.ts.map +1 -1
  285. package/dist/store/scopes/queue-item.js.map +1 -1
  286. package/dist/subscribable/subscribable.js.map +1 -1
  287. package/dist/tests/remote-thread-list-test-helpers.js.map +1 -1
  288. package/dist/types/message.d.ts +38 -5
  289. package/dist/types/message.d.ts.map +1 -1
  290. package/dist/types/message.js.map +1 -1
  291. package/dist/utils/composite-context-provider.js.map +1 -1
  292. package/dist/utils/id.js.map +1 -1
  293. package/dist/utils/json/is-json-equal.js.map +1 -1
  294. package/dist/utils/json/is-json.js.map +1 -1
  295. package/dist/utils/text.js.map +1 -1
  296. package/package.json +8 -8
  297. package/src/index.ts +4 -0
  298. package/src/internal.ts +1 -0
  299. package/src/model-context/types.ts +1 -0
  300. package/src/react/AssistantProvider.tsx +7 -0
  301. package/src/react/client/Tools.ts +3 -5
  302. package/src/react/model-context/toolbox.test.ts +2 -1
  303. package/src/react/model-context/toolbox.ts +2 -6
  304. package/src/react/runtimes/external-message-converter.ts +3 -1
  305. package/src/react/types/MessagePartComponentTypes.ts +5 -5
  306. package/src/runtime/api/message-part-runtime.ts +14 -11
  307. package/src/runtime/interfaces/thread-runtime-core.ts +2 -0
  308. package/src/runtime/utils/resolveToolApprovalResponse.test.ts +91 -0
  309. package/src/runtime/utils/resolveToolApprovalResponse.ts +55 -0
  310. package/src/runtime/utils/thread-message-like.ts +10 -1
  311. package/src/runtimes/local/local-thread-runtime-core.test.ts +61 -2
  312. package/src/runtimes/local/local-thread-runtime-core.ts +17 -8
  313. package/src/runtimes/local/should-continue.ts +2 -1
  314. package/src/store/clients/suggestions.ts +3 -5
  315. package/src/store/clients/thread-message-client.ts +13 -14
  316. package/src/store/runtime-clients/composer-runtime-client.ts +18 -21
  317. package/src/store/runtime-clients/liveRef.ts +5 -0
  318. package/src/store/runtime-clients/message-runtime-client.ts +16 -21
  319. package/src/store/runtime-clients/thread-list-runtime-client.ts +3 -5
  320. package/src/store/runtime-clients/thread-runtime-client.ts +9 -10
  321. package/src/store/runtime-clients/useSubscribable.ts +2 -10
  322. package/src/store/scopes/part.ts +5 -2
  323. package/src/types/message.ts +45 -3
@@ -1 +1 @@
1
- {"version":3,"file":"message.d.ts","names":[],"sources":["../../src/types/message.ts"],"mappings":"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"}
1
+ {"version":3,"file":"message.d.ts","names":[],"sources":["../../src/types/message.ts"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"message.js","names":[],"sources":["../../src/types/message.ts"],"sourcesContent":["import type {\n ReadonlyJSONObject,\n ReadonlyJSONValue,\n} from \"assistant-stream/utils\";\nimport type { ToolModelContentPart } from \"assistant-stream\";\nimport type { CompleteAttachment } from \"./attachment\";\n\nexport type { ToolModelContentPart };\n\nexport type TextMessagePart = {\n readonly type: \"text\";\n readonly text: string;\n readonly parentId?: string;\n};\n\nexport type ReasoningMessagePart = {\n readonly type: \"reasoning\";\n readonly text: string;\n readonly parentId?: string;\n};\n\nexport type SourceProviderMetadata = {\n readonly [providerName: string]: ReadonlyJSONObject;\n};\n\nexport type SourceMessagePart =\n | {\n readonly type: \"source\";\n readonly sourceType: \"url\";\n readonly id: string;\n readonly url: string;\n readonly title?: string;\n readonly providerMetadata?: SourceProviderMetadata;\n readonly parentId?: string;\n }\n | {\n readonly type: \"source\";\n readonly sourceType: \"document\";\n readonly id: string;\n readonly url?: undefined;\n readonly title: string;\n readonly mediaType: string;\n readonly filename?: string;\n readonly providerMetadata?: SourceProviderMetadata;\n readonly parentId?: string;\n };\n\nexport type ImageMessagePart = {\n readonly type: \"image\";\n readonly image: string;\n readonly filename?: string;\n};\n\nexport type FileMessagePart = {\n readonly type: \"file\";\n readonly filename?: string;\n readonly data: string;\n readonly mimeType: string;\n readonly parentId?: string;\n};\n\nexport type Unstable_AudioMessagePart = {\n readonly type: \"audio\";\n readonly audio: {\n readonly data: string;\n readonly format: \"mp3\" | \"wav\";\n };\n};\n\nexport type DataMessagePart<T = any> = {\n readonly type: \"data\";\n readonly name: string;\n readonly data: T;\n};\n\n/**\n * A JSON spec describing a tree of UI components to render.\n *\n * The agent emits a {@link GenerativeUIMessagePart} containing this spec, and\n * the consumer-provided component allowlist is used to resolve `component`\n * names. Any component referenced that is not present in the allowlist is\n * rejected with a typed error — the allowlist is the security boundary in the\n * default same-realm rendering path.\n */\nexport type GenerativeUINode =\n | string\n | {\n /** Allowlisted component name (resolved against the consumer registry). */\n readonly component: string;\n /** Props passed to the resolved component (must be JSON-serializable). */\n readonly props?: Record<string, unknown>;\n /** Optional children — strings render as text, objects recurse. */\n readonly children?: readonly GenerativeUINode[];\n /** Optional stable key for React reconciliation. */\n readonly key?: string;\n };\n\n/**\n * The root spec for a generative UI tree.\n */\nexport type GenerativeUISpec = {\n /** Root node(s) to render. */\n readonly root: GenerativeUINode | readonly GenerativeUINode[];\n};\n\n/**\n * A message part that carries a JSON spec describing UI to render.\n *\n * Render with `<MessagePrimitive.GenerativeUI components={...} />`. The\n * primitive resolves component names against the consumer-provided allowlist\n * — any unknown name throws a typed error rather than rendering. Stream-\n * friendly: a partially-streamed spec renders progressively.\n */\nexport type GenerativeUIMessagePart = {\n readonly type: \"generative-ui\";\n /** The JSON spec describing the UI tree. */\n readonly spec: GenerativeUISpec;\n /** Optional id (useful for replays / stable keys). */\n readonly id?: string;\n readonly parentId?: string;\n};\n\nexport type McpAppMetadata = {\n readonly resourceUri: string;\n readonly mimeType?: string;\n readonly visibility?: readonly (\"model\" | \"app\")[];\n};\n\nexport const MCP_APP_URI_SCHEME = \"ui://\";\n\nexport const isMcpAppUri = (uri: string | undefined): boolean =>\n !!uri?.startsWith(MCP_APP_URI_SCHEME);\n\nexport type ToolCallMessagePartMcpMetadata = {\n readonly app?: McpAppMetadata;\n};\n\nexport type ToolCallMessagePart<\n TArgs = ReadonlyJSONObject,\n TResult = unknown,\n> = {\n /** Identifies this part as a tool call. */\n readonly type: \"tool-call\";\n /** Stable identifier for this invocation of the tool. */\n readonly toolCallId: string;\n /** Name of the tool requested by the model. */\n readonly toolName: string;\n /**\n * Arguments supplied by the model. During streaming this is a partial parse:\n * fields may be missing or incomplete. From a tool-call renderer, use\n * `useToolArgsStatus` to detect which fields are still arriving.\n */\n readonly args: TArgs;\n /** Result returned by the tool, if it has completed. */\n readonly result?: TResult | undefined;\n /** Whether the result represents a tool execution error. */\n readonly isError?: boolean | undefined;\n /** Raw JSON argument text streamed by the model. */\n readonly argsText: string;\n /** UI-only artifact associated with the tool result. */\n readonly artifact?: unknown;\n /** MCP app metadata associated with this tool call, when present. */\n readonly mcp?: ToolCallMessagePartMcpMetadata;\n /** Content returned to the model for this tool result. */\n readonly modelContent?: readonly ToolModelContentPart[] | undefined;\n /** Human-input request that must be resolved before the run can continue. */\n readonly interrupt?: { type: \"human\"; payload: unknown };\n /** Server-side approval gate. `approved === undefined` is the only state in which `respondToApproval` may be called. */\n readonly approval?: {\n readonly id: string;\n readonly approved?: boolean;\n readonly reason?: string;\n readonly isAutomatic?: boolean;\n };\n /** Parent message-part ID when this part belongs to a nested structure. */\n readonly parentId?: string;\n /**\n * Nested thread messages produced by this tool call, for example a sub-agent\n * conversation.\n */\n readonly messages?: readonly ThreadMessage[];\n};\n\nexport type ThreadUserMessagePart =\n | TextMessagePart\n | ImageMessagePart\n | FileMessagePart\n | DataMessagePart\n | Unstable_AudioMessagePart;\n\nexport type ThreadAssistantMessagePart =\n | TextMessagePart\n | ReasoningMessagePart\n | ToolCallMessagePart\n | SourceMessagePart\n | FileMessagePart\n | ImageMessagePart\n | DataMessagePart\n | GenerativeUIMessagePart;\n\nexport type MessagePartStatus =\n | {\n readonly type: \"running\";\n }\n | {\n readonly type: \"complete\";\n }\n | {\n readonly type: \"incomplete\";\n readonly reason:\n | \"cancelled\"\n | \"length\"\n | \"content-filter\"\n | \"other\"\n | \"error\";\n readonly error?: unknown;\n };\n\nexport type ToolCallMessagePartStatus =\n | {\n /** The tool call is waiting for UI or human input before continuing. */\n readonly type: \"requires-action\";\n /** Reason the tool call requires action. */\n readonly reason: \"interrupt\";\n }\n | MessagePartStatus;\n\nexport type MessageStatus =\n | {\n readonly type: \"running\";\n }\n | {\n readonly type: \"requires-action\";\n readonly reason: \"tool-calls\" | \"interrupt\";\n }\n | {\n readonly type: \"complete\";\n readonly reason: \"stop\" | \"unknown\";\n }\n | {\n readonly type: \"incomplete\";\n readonly reason:\n | \"cancelled\"\n | \"tool-calls\"\n | \"length\"\n | \"content-filter\"\n | \"other\"\n | \"error\";\n readonly error?: ReadonlyJSONValue;\n };\n\nexport type MessageTiming = {\n readonly streamStartTime: number;\n readonly firstTokenTime?: number;\n readonly totalStreamTime?: number;\n readonly tokenCount?: number;\n readonly tokensPerSecond?: number;\n readonly totalChunks: number;\n readonly toolCallCount: number;\n};\n\nexport type ThreadStep = {\n readonly messageId?: string;\n readonly usage?:\n | {\n readonly inputTokens: number;\n readonly outputTokens: number;\n }\n | undefined;\n};\n\ntype MessageCommonProps = {\n readonly id: string;\n readonly createdAt: Date;\n};\n\nexport type ThreadSystemMessage = MessageCommonProps & {\n readonly role: \"system\";\n readonly content: readonly [TextMessagePart];\n readonly metadata: {\n readonly unstable_state?: undefined;\n readonly unstable_annotations?: undefined;\n readonly unstable_data?: undefined;\n readonly steps?: undefined;\n readonly submittedFeedback?: undefined;\n readonly timing?: undefined;\n readonly custom: Record<string, unknown>;\n };\n};\n\nexport type ThreadUserMessage = MessageCommonProps & {\n readonly role: \"user\";\n readonly content: readonly ThreadUserMessagePart[];\n readonly attachments: readonly CompleteAttachment[];\n readonly metadata: {\n readonly unstable_state?: undefined;\n readonly unstable_annotations?: undefined;\n readonly unstable_data?: undefined;\n readonly steps?: undefined;\n readonly submittedFeedback?: undefined;\n readonly timing?: undefined;\n readonly custom: Record<string, unknown>;\n };\n};\n\nexport type ThreadAssistantMessage = MessageCommonProps & {\n readonly role: \"assistant\";\n readonly content: readonly ThreadAssistantMessagePart[];\n readonly status: MessageStatus;\n readonly metadata: {\n readonly unstable_state: ReadonlyJSONValue;\n readonly unstable_annotations: readonly ReadonlyJSONValue[];\n readonly unstable_data: readonly ReadonlyJSONValue[];\n readonly steps: readonly ThreadStep[];\n readonly submittedFeedback?: { readonly type: \"positive\" | \"negative\" };\n readonly timing?: MessageTiming;\n /**\n * Marks a client-side optimistic placeholder. Such messages are evicted\n * once off the head branch and are never persisted.\n */\n readonly isOptimistic?: boolean;\n readonly custom: Record<string, unknown>;\n };\n};\n\ntype BaseThreadMessage = {\n readonly status?: ThreadAssistantMessage[\"status\"];\n readonly metadata: {\n readonly unstable_state?: ReadonlyJSONValue;\n readonly unstable_annotations?: readonly ReadonlyJSONValue[];\n readonly unstable_data?: readonly ReadonlyJSONValue[];\n readonly steps?: readonly ThreadStep[];\n readonly submittedFeedback?: { readonly type: \"positive\" | \"negative\" };\n readonly timing?: MessageTiming;\n readonly isOptimistic?: boolean;\n readonly custom: Record<string, unknown>;\n };\n readonly attachments?: ThreadUserMessage[\"attachments\"];\n};\n\nexport type ThreadMessage = BaseThreadMessage &\n (ThreadSystemMessage | ThreadUserMessage | ThreadAssistantMessage);\n\nexport type MessageRole = ThreadMessage[\"role\"];\n\nexport type RunConfig = {\n readonly custom?: Record<string, unknown>;\n};\n\nexport type AppendMessage = Omit<ThreadMessage, \"id\"> & {\n parentId: string | null;\n\n /** The ID of the message that was edited or undefined. */\n sourceId: string | null;\n runConfig: RunConfig | undefined;\n startRun?: boolean | undefined;\n /** Process this message next; only meaningful for queue-capable runtimes. */\n steer?: boolean | undefined;\n};\n"],"mappings":";AAgIA,MAAa,qBAAqB;AAElC,MAAa,eAAe,QAC1B,CAAC,CAAC,KAAK,WAAW,kBAAkB"}
1
+ {"version":3,"file":"message.js","names":["ReadonlyJSONObject","ReadonlyJSONValue","ToolCallTiming","ToolModelContentPart","CompleteAttachment","TextMessagePart","type","text","parentId","ReasoningMessagePart","SourceProviderMetadata","providerName","SourceMessagePart","sourceType","id","url","title","providerMetadata","mediaType","filename","ImageMessagePart","image","FileMessagePart","data","mimeType","Unstable_AudioMessagePart","audio","format","DataMessagePart","name","T","GenerativeUINode","component","props","Record","children","key","GenerativeUISpec","root","GenerativeUIMessagePart","spec","McpAppMetadata","resourceUri","visibility","MCP_APP_URI_SCHEME","isMcpAppUri","uri","startsWith","ToolCallMessagePartMcpMetadata","app","ToolApprovalOptionKind","ToolApprovalOption","kind","label","description","grants","confirm","ToolApprovalResponse","approved","reason","optionId","ToolCallMessagePart","toolCallId","toolName","args","TArgs","result","TResult","isError","argsText","artifact","timing","mcp","modelContent","interrupt","payload","approval","isAutomatic","options","resolution","messages","ThreadMessage","ThreadUserMessagePart","ThreadAssistantMessagePart","MessagePartStatus","error","ToolCallMessagePartStatus","MessageStatus","MessageTiming","streamStartTime","firstTokenTime","totalStreamTime","tokenCount","tokensPerSecond","totalChunks","toolCallCount","ThreadStep","messageId","usage","inputTokens","outputTokens","MessageCommonProps","createdAt","Date","ThreadSystemMessage","role","content","metadata","unstable_state","unstable_annotations","unstable_data","steps","submittedFeedback","custom","ThreadUserMessage","attachments","ThreadAssistantMessage","status","isOptimistic","BaseThreadMessage","MessageRole","RunConfig","AppendMessage","Omit","sourceId","runConfig","startRun","steer"],"sources":["../../src/types/message.ts"],"sourcesContent":["import type {\n ReadonlyJSONObject,\n ReadonlyJSONValue,\n} from \"assistant-stream/utils\";\nimport type { ToolCallTiming, ToolModelContentPart } from \"assistant-stream\";\nimport type { CompleteAttachment } from \"./attachment\";\n\nexport type { ToolCallTiming, ToolModelContentPart };\n\nexport type TextMessagePart = {\n readonly type: \"text\";\n readonly text: string;\n readonly parentId?: string;\n};\n\nexport type ReasoningMessagePart = {\n readonly type: \"reasoning\";\n readonly text: string;\n readonly parentId?: string;\n};\n\nexport type SourceProviderMetadata = {\n readonly [providerName: string]: ReadonlyJSONObject;\n};\n\nexport type SourceMessagePart =\n | {\n readonly type: \"source\";\n readonly sourceType: \"url\";\n readonly id: string;\n readonly url: string;\n readonly title?: string;\n readonly providerMetadata?: SourceProviderMetadata;\n readonly parentId?: string;\n }\n | {\n readonly type: \"source\";\n readonly sourceType: \"document\";\n readonly id: string;\n readonly url?: undefined;\n readonly title: string;\n readonly mediaType: string;\n readonly filename?: string;\n readonly providerMetadata?: SourceProviderMetadata;\n readonly parentId?: string;\n };\n\nexport type ImageMessagePart = {\n readonly type: \"image\";\n readonly image: string;\n readonly filename?: string;\n};\n\nexport type FileMessagePart = {\n readonly type: \"file\";\n readonly filename?: string;\n readonly data: string;\n readonly mimeType: string;\n readonly parentId?: string;\n};\n\nexport type Unstable_AudioMessagePart = {\n readonly type: \"audio\";\n readonly audio: {\n readonly data: string;\n readonly format: \"mp3\" | \"wav\";\n };\n};\n\nexport type DataMessagePart<T = any> = {\n readonly type: \"data\";\n readonly name: string;\n readonly data: T;\n};\n\n/**\n * A JSON spec describing a tree of UI components to render.\n *\n * The agent emits a {@link GenerativeUIMessagePart} containing this spec, and\n * the consumer-provided component allowlist is used to resolve `component`\n * names. Any component referenced that is not present in the allowlist is\n * rejected with a typed error — the allowlist is the security boundary in the\n * default same-realm rendering path.\n */\nexport type GenerativeUINode =\n | string\n | {\n /** Allowlisted component name (resolved against the consumer registry). */\n readonly component: string;\n /** Props passed to the resolved component (must be JSON-serializable). */\n readonly props?: Record<string, unknown>;\n /** Optional children — strings render as text, objects recurse. */\n readonly children?: readonly GenerativeUINode[];\n /** Optional stable key for React reconciliation. */\n readonly key?: string;\n };\n\n/**\n * The root spec for a generative UI tree.\n */\nexport type GenerativeUISpec = {\n /** Root node(s) to render. */\n readonly root: GenerativeUINode | readonly GenerativeUINode[];\n};\n\n/**\n * A message part that carries a JSON spec describing UI to render.\n *\n * Render with `<MessagePrimitive.GenerativeUI components={...} />`. The\n * primitive resolves component names against the consumer-provided allowlist\n * — any unknown name throws a typed error rather than rendering. Stream-\n * friendly: a partially-streamed spec renders progressively.\n */\nexport type GenerativeUIMessagePart = {\n readonly type: \"generative-ui\";\n /** The JSON spec describing the UI tree. */\n readonly spec: GenerativeUISpec;\n /** Optional id (useful for replays / stable keys). */\n readonly id?: string;\n readonly parentId?: string;\n};\n\nexport type McpAppMetadata = {\n readonly resourceUri: string;\n readonly mimeType?: string;\n readonly visibility?: readonly (\"model\" | \"app\")[];\n};\n\nexport const MCP_APP_URI_SCHEME = \"ui://\";\n\nexport const isMcpAppUri = (uri: string | undefined): boolean =>\n !!uri?.startsWith(MCP_APP_URI_SCHEME);\n\nexport type ToolCallMessagePartMcpMetadata = {\n readonly app?: McpAppMetadata;\n};\n\nexport type ToolApprovalOptionKind =\n | \"allow-once\"\n | \"allow-always\"\n | \"reject-once\"\n | \"reject-always\";\n\nexport type ToolApprovalOption = {\n /** Opaque, host-defined identifier. Scope semantics (session vs project vs global) belong to the option supplier. */\n readonly id: string;\n /**\n * Decision class. Drives approved-resolution and default rendering.\n * Open union: `_`-prefixed custom kinds are never auto-resolved and the\n * default kit skips them; they must be answered with an explicit\n * `approved` value (optionally alongside the `optionId`).\n */\n readonly kind: ToolApprovalOptionKind | (string & {});\n /** Human label. Renderers supply defaults per kind when omitted. */\n readonly label?: string;\n readonly description?: string;\n /** Patterns or rules this option would persist, shown before the user commits. Supplied by the host; never derived by the library. */\n readonly grants?: readonly string[];\n /** Opt-in confirmation step before this option resolves. */\n readonly confirm?: boolean | { title?: string; description?: string };\n};\n\nexport type ToolApprovalResponse =\n | { readonly approved: boolean; readonly reason?: string }\n | { readonly optionId: string; readonly reason?: string }\n | {\n readonly approved: boolean;\n readonly optionId: string;\n readonly reason?: string;\n };\n\nexport type ToolCallMessagePart<\n TArgs = ReadonlyJSONObject,\n TResult = unknown,\n> = {\n /** Identifies this part as a tool call. */\n readonly type: \"tool-call\";\n /** Stable identifier for this invocation of the tool. */\n readonly toolCallId: string;\n /** Name of the tool requested by the model. */\n readonly toolName: string;\n /**\n * Arguments supplied by the model. During streaming this is a partial parse:\n * fields may be missing or incomplete. From a tool-call renderer, use\n * `useToolArgsStatus` to detect which fields are still arriving.\n */\n readonly args: TArgs;\n /** Result returned by the tool, if it has completed. */\n readonly result?: TResult | undefined;\n /** Whether the result represents a tool execution error. */\n readonly isError?: boolean | undefined;\n /** Raw JSON argument text streamed by the model. */\n readonly argsText: string;\n /** UI-only artifact associated with the tool result. */\n readonly artifact?: unknown;\n /** Wall-clock timing for this call, when the runtime or host tracks it. */\n readonly timing?: ToolCallTiming;\n /** MCP app metadata associated with this tool call, when present. */\n readonly mcp?: ToolCallMessagePartMcpMetadata;\n /** Content returned to the model for this tool result. */\n readonly modelContent?: readonly ToolModelContentPart[] | undefined;\n /** Human-input request that must be resolved before the run can continue. */\n readonly interrupt?: { type: \"human\"; payload: unknown };\n /** Server-side approval gate. `respondToApproval` may only be called while `approved` is undefined and no `resolution` is recorded. */\n readonly approval?: {\n readonly id: string;\n readonly approved?: boolean;\n readonly reason?: string;\n readonly isAutomatic?: boolean;\n /** Available decisions for this call. Absent: a plain allow / deny pair. */\n readonly options?: readonly ToolApprovalOption[];\n /** The option chosen at resolution, when options were present. */\n readonly optionId?: string;\n /** Terminal non-decision state: the request was cancelled or expired without a user decision. Set by the host. */\n readonly resolution?: \"cancelled\" | \"expired\";\n };\n /** Parent message-part ID when this part belongs to a nested structure. */\n readonly parentId?: string;\n /**\n * Nested thread messages produced by this tool call, for example a sub-agent\n * conversation.\n */\n readonly messages?: readonly ThreadMessage[];\n};\n\nexport type ThreadUserMessagePart =\n | TextMessagePart\n | ImageMessagePart\n | FileMessagePart\n | DataMessagePart\n | Unstable_AudioMessagePart;\n\nexport type ThreadAssistantMessagePart =\n | TextMessagePart\n | ReasoningMessagePart\n | ToolCallMessagePart\n | SourceMessagePart\n | FileMessagePart\n | ImageMessagePart\n | DataMessagePart\n | GenerativeUIMessagePart;\n\nexport type MessagePartStatus =\n | {\n readonly type: \"running\";\n }\n | {\n readonly type: \"complete\";\n }\n | {\n readonly type: \"incomplete\";\n readonly reason:\n | \"cancelled\"\n | \"length\"\n | \"content-filter\"\n | \"other\"\n | \"error\";\n readonly error?: unknown;\n };\n\nexport type ToolCallMessagePartStatus =\n | {\n /** The tool call is waiting for UI or human input before continuing. */\n readonly type: \"requires-action\";\n /** Reason the tool call requires action. */\n readonly reason: \"interrupt\";\n }\n | MessagePartStatus;\n\nexport type MessageStatus =\n | {\n readonly type: \"running\";\n }\n | {\n readonly type: \"requires-action\";\n readonly reason: \"tool-calls\" | \"interrupt\";\n }\n | {\n readonly type: \"complete\";\n readonly reason: \"stop\" | \"unknown\";\n }\n | {\n readonly type: \"incomplete\";\n readonly reason:\n | \"cancelled\"\n | \"tool-calls\"\n | \"length\"\n | \"content-filter\"\n | \"other\"\n | \"error\";\n readonly error?: ReadonlyJSONValue;\n };\n\nexport type MessageTiming = {\n readonly streamStartTime: number;\n readonly firstTokenTime?: number;\n readonly totalStreamTime?: number;\n readonly tokenCount?: number;\n readonly tokensPerSecond?: number;\n readonly totalChunks: number;\n readonly toolCallCount: number;\n};\n\nexport type ThreadStep = {\n readonly messageId?: string;\n readonly usage?:\n | {\n readonly inputTokens: number;\n readonly outputTokens: number;\n }\n | undefined;\n};\n\ntype MessageCommonProps = {\n readonly id: string;\n readonly createdAt: Date;\n};\n\nexport type ThreadSystemMessage = MessageCommonProps & {\n readonly role: \"system\";\n readonly content: readonly [TextMessagePart];\n readonly metadata: {\n readonly unstable_state?: undefined;\n readonly unstable_annotations?: undefined;\n readonly unstable_data?: undefined;\n readonly steps?: undefined;\n readonly submittedFeedback?: undefined;\n readonly timing?: undefined;\n readonly custom: Record<string, unknown>;\n };\n};\n\nexport type ThreadUserMessage = MessageCommonProps & {\n readonly role: \"user\";\n readonly content: readonly ThreadUserMessagePart[];\n readonly attachments: readonly CompleteAttachment[];\n readonly metadata: {\n readonly unstable_state?: undefined;\n readonly unstable_annotations?: undefined;\n readonly unstable_data?: undefined;\n readonly steps?: undefined;\n readonly submittedFeedback?: undefined;\n readonly timing?: undefined;\n readonly custom: Record<string, unknown>;\n };\n};\n\nexport type ThreadAssistantMessage = MessageCommonProps & {\n readonly role: \"assistant\";\n readonly content: readonly ThreadAssistantMessagePart[];\n readonly status: MessageStatus;\n readonly metadata: {\n readonly unstable_state: ReadonlyJSONValue;\n readonly unstable_annotations: readonly ReadonlyJSONValue[];\n readonly unstable_data: readonly ReadonlyJSONValue[];\n readonly steps: readonly ThreadStep[];\n readonly submittedFeedback?: { readonly type: \"positive\" | \"negative\" };\n readonly timing?: MessageTiming;\n /**\n * Marks a client-side optimistic placeholder. Such messages are evicted\n * once off the head branch and are never persisted.\n */\n readonly isOptimistic?: boolean;\n readonly custom: Record<string, unknown>;\n };\n};\n\ntype BaseThreadMessage = {\n readonly status?: ThreadAssistantMessage[\"status\"];\n readonly metadata: {\n readonly unstable_state?: ReadonlyJSONValue;\n readonly unstable_annotations?: readonly ReadonlyJSONValue[];\n readonly unstable_data?: readonly ReadonlyJSONValue[];\n readonly steps?: readonly ThreadStep[];\n readonly submittedFeedback?: { readonly type: \"positive\" | \"negative\" };\n readonly timing?: MessageTiming;\n readonly isOptimistic?: boolean;\n readonly custom: Record<string, unknown>;\n };\n readonly attachments?: ThreadUserMessage[\"attachments\"];\n};\n\nexport type ThreadMessage = BaseThreadMessage &\n (ThreadSystemMessage | ThreadUserMessage | ThreadAssistantMessage);\n\nexport type MessageRole = ThreadMessage[\"role\"];\n\nexport type RunConfig = {\n readonly custom?: Record<string, unknown>;\n};\n\nexport type AppendMessage = Omit<ThreadMessage, \"id\"> & {\n parentId: string | null;\n\n /** The ID of the message that was edited or undefined. */\n sourceId: string | null;\n runConfig: RunConfig | undefined;\n startRun?: boolean | undefined;\n /** Process this message next; only meaningful for queue-capable runtimes. */\n steer?: boolean | undefined;\n};\n"],"mappings":";AAgIA,MAAa4C,qBAAqB;AAElC,MAAaC,eAAeC,QAC1B,CAAC,CAACA,KAAKC,WAAWH,kBAAkB"}
@@ -1 +1 @@
1
- {"version":3,"file":"composite-context-provider.js","names":[],"sources":["../../src/utils/composite-context-provider.ts"],"sourcesContent":["import {\n type ModelContextProvider,\n mergeModelContexts,\n} from \"../model-context/types\";\n\nexport class CompositeContextProvider implements ModelContextProvider {\n private _providers = new Set<ModelContextProvider>();\n\n getModelContext() {\n return mergeModelContexts(this._providers);\n }\n\n registerModelContextProvider(provider: ModelContextProvider) {\n this._providers.add(provider);\n const unsubscribe = provider.subscribe?.(() => {\n this.notifySubscribers();\n });\n this.notifySubscribers();\n return () => {\n this._providers.delete(provider);\n unsubscribe?.();\n this.notifySubscribers();\n };\n }\n\n private _subscribers = new Set<() => void>();\n\n notifySubscribers() {\n for (const callback of this._subscribers) callback();\n }\n\n subscribe(callback: () => void) {\n this._subscribers.add(callback);\n return () => {\n this._subscribers.delete(callback);\n };\n }\n}\n"],"mappings":";;AAKA,IAAa,2BAAb,MAAsE;CACpE,6BAAqB,IAAI,IAA0B;CAEnD,kBAAkB;EAChB,OAAO,mBAAmB,KAAK,UAAU;CAC3C;CAEA,6BAA6B,UAAgC;EAC3D,KAAK,WAAW,IAAI,QAAQ;EAC5B,MAAM,cAAc,SAAS,kBAAkB;GAC7C,KAAK,kBAAkB;EACzB,CAAC;EACD,KAAK,kBAAkB;EACvB,aAAa;GACX,KAAK,WAAW,OAAO,QAAQ;GAC/B,cAAc;GACd,KAAK,kBAAkB;EACzB;CACF;CAEA,+BAAuB,IAAI,IAAgB;CAE3C,oBAAoB;EAClB,KAAK,MAAM,YAAY,KAAK,cAAc,SAAS;CACrD;CAEA,UAAU,UAAsB;EAC9B,KAAK,aAAa,IAAI,QAAQ;EAC9B,aAAa;GACX,KAAK,aAAa,OAAO,QAAQ;EACnC;CACF;AACF"}
1
+ {"version":3,"file":"composite-context-provider.js","names":["ModelContextProvider","mergeModelContexts","CompositeContextProvider","_providers","Set","getModelContext","registerModelContextProvider","provider","add","unsubscribe","subscribe","notifySubscribers","delete","_subscribers","callback"],"sources":["../../src/utils/composite-context-provider.ts"],"sourcesContent":["import {\n type ModelContextProvider,\n mergeModelContexts,\n} from \"../model-context/types\";\n\nexport class CompositeContextProvider implements ModelContextProvider {\n private _providers = new Set<ModelContextProvider>();\n\n getModelContext() {\n return mergeModelContexts(this._providers);\n }\n\n registerModelContextProvider(provider: ModelContextProvider) {\n this._providers.add(provider);\n const unsubscribe = provider.subscribe?.(() => {\n this.notifySubscribers();\n });\n this.notifySubscribers();\n return () => {\n this._providers.delete(provider);\n unsubscribe?.();\n this.notifySubscribers();\n };\n }\n\n private _subscribers = new Set<() => void>();\n\n notifySubscribers() {\n for (const callback of this._subscribers) callback();\n }\n\n subscribe(callback: () => void) {\n this._subscribers.add(callback);\n return () => {\n this._subscribers.delete(callback);\n };\n }\n}\n"],"mappings":";;AAKA,IAAaE,2BAAb,MAAsE;CACpE,6BAAqB,IAAIE,IAA0B;CAEnDC,kBAAkB;EAChB,OAAOJ,mBAAmB,KAAKE,UAAU;CAC3C;CAEAG,6BAA6BC,UAAgC;EAC3D,KAAKJ,WAAWK,IAAID,QAAQ;EAC5B,MAAME,cAAcF,SAASG,kBAAkB;GAC7C,KAAKC,kBAAkB;EACzB,CAAC;EACD,KAAKA,kBAAkB;EACvB,aAAa;GACX,KAAKR,WAAWS,OAAOL,QAAQ;GAC/BE,cAAc;GACd,KAAKE,kBAAkB;EACzB;CACF;CAEA,+BAAuB,IAAIP,IAAgB;CAE3CO,oBAAoB;EAClB,KAAK,MAAMG,YAAY,KAAKD,cAAcC,SAAS;CACrD;CAEAJ,UAAUI,UAAsB;EAC9B,KAAKD,aAAaL,IAAIM,QAAQ;EAC9B,aAAa;GACX,KAAKD,aAAaD,OAAOE,QAAQ;EACnC;CACF;AACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"id.js","names":[],"sources":["../../src/utils/id.ts"],"sourcesContent":["import { customAlphabet } from \"nanoid/non-secure\";\n\nexport const generateId = customAlphabet(\n \"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\",\n 7,\n);\n\nconst errorPrefix = \"__error__\";\nexport const generateErrorMessageId = () => `${errorPrefix}${generateId()}`;\nexport const isErrorMessageId = (id: string) => id.startsWith(errorPrefix);\n"],"mappings":";;AAEA,MAAa,aAAa,eACxB,kEACA,CACF;AAEA,MAAM,cAAc;AACpB,MAAa,+BAA+B,GAAG,cAAc,WAAW;AACxE,MAAa,oBAAoB,OAAe,GAAG,WAAW,WAAW"}
1
+ {"version":3,"file":"id.js","names":["customAlphabet","generateId","errorPrefix","generateErrorMessageId","isErrorMessageId","id","startsWith"],"sources":["../../src/utils/id.ts"],"sourcesContent":["import { customAlphabet } from \"nanoid/non-secure\";\n\nexport const generateId = customAlphabet(\n \"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\",\n 7,\n);\n\nconst errorPrefix = \"__error__\";\nexport const generateErrorMessageId = () => `${errorPrefix}${generateId()}`;\nexport const isErrorMessageId = (id: string) => id.startsWith(errorPrefix);\n"],"mappings":";;AAEA,MAAaC,aAAaD,eACxB,kEACA,CACF;AAEA,MAAME,cAAc;AACpB,MAAaC,+BAA+B,GAAGD,cAAcD,WAAW;AACxE,MAAaG,oBAAoBC,OAAeA,GAAGC,WAAWJ,WAAW"}
@@ -1 +1 @@
1
- {"version":3,"file":"is-json-equal.js","names":[],"sources":["../../../src/utils/json/is-json-equal.ts"],"sourcesContent":["import type { ReadonlyJSONValue } from \"assistant-stream/utils\";\nimport { isJSONValue, isRecord } from \"./is-json\";\n\nconst MAX_JSON_DEPTH = 100;\n\nconst isJSONValueEqualAtDepth = (\n a: ReadonlyJSONValue,\n b: ReadonlyJSONValue,\n currentDepth: number,\n): boolean => {\n if (a === b) return true;\n if (currentDepth > MAX_JSON_DEPTH) return false;\n\n if (a == null || b == null) return false;\n\n if (Array.isArray(a)) {\n if (!Array.isArray(b) || a.length !== b.length) return false;\n return a.every((item, index) =>\n isJSONValueEqualAtDepth(\n item,\n b[index] as ReadonlyJSONValue,\n currentDepth + 1,\n ),\n );\n }\n\n if (Array.isArray(b)) return false;\n if (!isRecord(a) || !isRecord(b)) return false;\n\n const aKeys = Object.keys(a);\n const bKeys = Object.keys(b);\n if (aKeys.length !== bKeys.length) return false;\n\n return aKeys.every(\n (key) =>\n Object.hasOwn(b, key) &&\n isJSONValueEqualAtDepth(\n a[key] as ReadonlyJSONValue,\n b[key] as ReadonlyJSONValue,\n currentDepth + 1,\n ),\n );\n};\n\nexport const isJSONValueEqual = (a: unknown, b: unknown): boolean => {\n if (!isJSONValue(a) || !isJSONValue(b)) return false;\n return isJSONValueEqualAtDepth(a, b, 0);\n};\n"],"mappings":";;AAGA,MAAM,iBAAiB;AAEvB,MAAM,2BACJ,GACA,GACA,iBACY;CACZ,IAAI,MAAM,GAAG,OAAO;CACpB,IAAI,eAAe,gBAAgB,OAAO;CAE1C,IAAI,KAAK,QAAQ,KAAK,MAAM,OAAO;CAEnC,IAAI,MAAM,QAAQ,CAAC,GAAG;EACpB,IAAI,CAAC,MAAM,QAAQ,CAAC,KAAK,EAAE,WAAW,EAAE,QAAQ,OAAO;EACvD,OAAO,EAAE,OAAO,MAAM,UACpB,wBACE,MACA,EAAE,QACF,eAAe,CACjB,CACF;CACF;CAEA,IAAI,MAAM,QAAQ,CAAC,GAAG,OAAO;CAC7B,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,OAAO;CAEzC,MAAM,QAAQ,OAAO,KAAK,CAAC;CAC3B,MAAM,QAAQ,OAAO,KAAK,CAAC;CAC3B,IAAI,MAAM,WAAW,MAAM,QAAQ,OAAO;CAE1C,OAAO,MAAM,OACV,QACC,OAAO,OAAO,GAAG,GAAG,KACpB,wBACE,EAAE,MACF,EAAE,MACF,eAAe,CACjB,CACJ;AACF;AAEA,MAAa,oBAAoB,GAAY,MAAwB;CACnE,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,YAAY,CAAC,GAAG,OAAO;CAC/C,OAAO,wBAAwB,GAAG,GAAG,CAAC;AACxC"}
1
+ {"version":3,"file":"is-json-equal.js","names":["ReadonlyJSONValue","isJSONValue","isRecord","MAX_JSON_DEPTH","isJSONValueEqualAtDepth","a","b","currentDepth","Array","isArray","length","every","item","index","aKeys","Object","keys","bKeys","key","hasOwn","isJSONValueEqual"],"sources":["../../../src/utils/json/is-json-equal.ts"],"sourcesContent":["import type { ReadonlyJSONValue } from \"assistant-stream/utils\";\nimport { isJSONValue, isRecord } from \"./is-json\";\n\nconst MAX_JSON_DEPTH = 100;\n\nconst isJSONValueEqualAtDepth = (\n a: ReadonlyJSONValue,\n b: ReadonlyJSONValue,\n currentDepth: number,\n): boolean => {\n if (a === b) return true;\n if (currentDepth > MAX_JSON_DEPTH) return false;\n\n if (a == null || b == null) return false;\n\n if (Array.isArray(a)) {\n if (!Array.isArray(b) || a.length !== b.length) return false;\n return a.every((item, index) =>\n isJSONValueEqualAtDepth(\n item,\n b[index] as ReadonlyJSONValue,\n currentDepth + 1,\n ),\n );\n }\n\n if (Array.isArray(b)) return false;\n if (!isRecord(a) || !isRecord(b)) return false;\n\n const aKeys = Object.keys(a);\n const bKeys = Object.keys(b);\n if (aKeys.length !== bKeys.length) return false;\n\n return aKeys.every(\n (key) =>\n Object.hasOwn(b, key) &&\n isJSONValueEqualAtDepth(\n a[key] as ReadonlyJSONValue,\n b[key] as ReadonlyJSONValue,\n currentDepth + 1,\n ),\n );\n};\n\nexport const isJSONValueEqual = (a: unknown, b: unknown): boolean => {\n if (!isJSONValue(a) || !isJSONValue(b)) return false;\n return isJSONValueEqualAtDepth(a, b, 0);\n};\n"],"mappings":";;AAGA,MAAMG,iBAAiB;AAEvB,MAAMC,2BACJC,GACAC,GACAC,iBACY;CACZ,IAAIF,MAAMC,GAAG,OAAO;CACpB,IAAIC,eAAeJ,gBAAgB,OAAO;CAE1C,IAAIE,KAAK,QAAQC,KAAK,MAAM,OAAO;CAEnC,IAAIE,MAAMC,QAAQJ,CAAC,GAAG;EACpB,IAAI,CAACG,MAAMC,QAAQH,CAAC,KAAKD,EAAEK,WAAWJ,EAAEI,QAAQ,OAAO;EACvD,OAAOL,EAAEM,OAAOC,MAAMC,UACpBT,wBACEQ,MACAN,EAAEO,QACFN,eAAe,CACjB,CACF;CACF;CAEA,IAAIC,MAAMC,QAAQH,CAAC,GAAG,OAAO;CAC7B,IAAI,CAACJ,SAASG,CAAC,KAAK,CAACH,SAASI,CAAC,GAAG,OAAO;CAEzC,MAAMQ,QAAQC,OAAOC,KAAKX,CAAC;CAC3B,MAAMY,QAAQF,OAAOC,KAAKV,CAAC;CAC3B,IAAIQ,MAAMJ,WAAWO,MAAMP,QAAQ,OAAO;CAE1C,OAAOI,MAAMH,OACVO,QACCH,OAAOI,OAAOb,GAAGY,GAAG,KACpBd,wBACEC,EAAEa,MACFZ,EAAEY,MACFX,eAAe,CACjB,CACJ;AACF;AAEA,MAAaa,oBAAoBf,GAAYC,MAAwB;CACnE,IAAI,CAACL,YAAYI,CAAC,KAAK,CAACJ,YAAYK,CAAC,GAAG,OAAO;CAC/C,OAAOF,wBAAwBC,GAAGC,GAAG,CAAC;AACxC"}
@@ -1 +1 @@
1
- {"version":3,"file":"is-json.js","names":[],"sources":["../../../src/utils/json/is-json.ts"],"sourcesContent":["import type {\n ReadonlyJSONArray,\n ReadonlyJSONObject,\n ReadonlyJSONValue,\n} from \"assistant-stream/utils\";\n\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n return value != null && typeof value === \"object\" && !Array.isArray(value);\n}\n\nexport function isJSONValue(\n value: unknown,\n currentDepth: number = 0,\n): value is ReadonlyJSONValue {\n // Protect against too deep recursion\n if (currentDepth > 100) {\n return false;\n }\n\n if (\n value === null ||\n typeof value === \"string\" ||\n typeof value === \"boolean\"\n ) {\n return true;\n }\n\n // Handle special number cases\n if (typeof value === \"number\") {\n return !Number.isNaN(value) && Number.isFinite(value);\n }\n\n if (Array.isArray(value)) {\n return value.every((item) => isJSONValue(item, currentDepth + 1));\n }\n\n if (isRecord(value)) {\n return Object.entries(value).every(\n ([key, val]) =>\n typeof key === \"string\" && isJSONValue(val, currentDepth + 1),\n );\n }\n\n return false;\n}\n\nexport function isJSONArray(value: unknown): value is ReadonlyJSONArray {\n return Array.isArray(value) && value.every(isJSONValue);\n}\n\nexport function isJSONObject(value: unknown): value is ReadonlyJSONObject {\n return (\n isRecord(value) &&\n Object.entries(value).every(\n ([key, val]) => typeof key === \"string\" && isJSONValue(val),\n )\n );\n}\n"],"mappings":";AAMA,SAAgB,SAAS,OAAkD;CACzE,OAAO,SAAS,QAAQ,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK;AAC3E;AAEA,SAAgB,YACd,OACA,eAAuB,GACK;CAE5B,IAAI,eAAe,KACjB,OAAO;CAGT,IACE,UAAU,QACV,OAAO,UAAU,YACjB,OAAO,UAAU,WAEjB,OAAO;CAIT,IAAI,OAAO,UAAU,UACnB,OAAO,CAAC,OAAO,MAAM,KAAK,KAAK,OAAO,SAAS,KAAK;CAGtD,IAAI,MAAM,QAAQ,KAAK,GACrB,OAAO,MAAM,OAAO,SAAS,YAAY,MAAM,eAAe,CAAC,CAAC;CAGlE,IAAI,SAAS,KAAK,GAChB,OAAO,OAAO,QAAQ,KAAK,CAAC,CAAC,OAC1B,CAAC,KAAK,SACL,OAAO,QAAQ,YAAY,YAAY,KAAK,eAAe,CAAC,CAChE;CAGF,OAAO;AACT;AAEA,SAAgB,YAAY,OAA4C;CACtE,OAAO,MAAM,QAAQ,KAAK,KAAK,MAAM,MAAM,WAAW;AACxD;AAEA,SAAgB,aAAa,OAA6C;CACxE,OACE,SAAS,KAAK,KACd,OAAO,QAAQ,KAAK,CAAC,CAAC,OACnB,CAAC,KAAK,SAAS,OAAO,QAAQ,YAAY,YAAY,GAAG,CAC5D;AAEJ"}
1
+ {"version":3,"file":"is-json.js","names":["ReadonlyJSONArray","ReadonlyJSONObject","ReadonlyJSONValue","isRecord","value","Record","Array","isArray","isJSONValue","currentDepth","Number","isNaN","isFinite","every","item","Object","entries","key","val","isJSONArray","isJSONObject"],"sources":["../../../src/utils/json/is-json.ts"],"sourcesContent":["import type {\n ReadonlyJSONArray,\n ReadonlyJSONObject,\n ReadonlyJSONValue,\n} from \"assistant-stream/utils\";\n\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n return value != null && typeof value === \"object\" && !Array.isArray(value);\n}\n\nexport function isJSONValue(\n value: unknown,\n currentDepth: number = 0,\n): value is ReadonlyJSONValue {\n // Protect against too deep recursion\n if (currentDepth > 100) {\n return false;\n }\n\n if (\n value === null ||\n typeof value === \"string\" ||\n typeof value === \"boolean\"\n ) {\n return true;\n }\n\n // Handle special number cases\n if (typeof value === \"number\") {\n return !Number.isNaN(value) && Number.isFinite(value);\n }\n\n if (Array.isArray(value)) {\n return value.every((item) => isJSONValue(item, currentDepth + 1));\n }\n\n if (isRecord(value)) {\n return Object.entries(value).every(\n ([key, val]) =>\n typeof key === \"string\" && isJSONValue(val, currentDepth + 1),\n );\n }\n\n return false;\n}\n\nexport function isJSONArray(value: unknown): value is ReadonlyJSONArray {\n return Array.isArray(value) && value.every(isJSONValue);\n}\n\nexport function isJSONObject(value: unknown): value is ReadonlyJSONObject {\n return (\n isRecord(value) &&\n Object.entries(value).every(\n ([key, val]) => typeof key === \"string\" && isJSONValue(val),\n )\n );\n}\n"],"mappings":";AAMA,SAAgBG,SAASC,OAAkD;CACzE,OAAOA,SAAS,QAAQ,OAAOA,UAAU,YAAY,CAACE,MAAMC,QAAQH,KAAK;AAC3E;AAEA,SAAgBI,YACdJ,OACAK,eAAuB,GACK;CAE5B,IAAIA,eAAe,KACjB,OAAO;CAGT,IACEL,UAAU,QACV,OAAOA,UAAU,YACjB,OAAOA,UAAU,WAEjB,OAAO;CAIT,IAAI,OAAOA,UAAU,UACnB,OAAO,CAACM,OAAOC,MAAMP,KAAK,KAAKM,OAAOE,SAASR,KAAK;CAGtD,IAAIE,MAAMC,QAAQH,KAAK,GACrB,OAAOA,MAAMS,OAAOC,SAASN,YAAYM,MAAML,eAAe,CAAC,CAAC;CAGlE,IAAIN,SAASC,KAAK,GAChB,OAAOW,OAAOC,QAAQZ,KAAK,CAAC,CAACS,OAC1B,CAACI,KAAKC,SACL,OAAOD,QAAQ,YAAYT,YAAYU,KAAKT,eAAe,CAAC,CAChE;CAGF,OAAO;AACT;AAEA,SAAgBU,YAAYf,OAA4C;CACtE,OAAOE,MAAMC,QAAQH,KAAK,KAAKA,MAAMS,MAAML,WAAW;AACxD;AAEA,SAAgBY,aAAahB,OAA6C;CACxE,OACED,SAASC,KAAK,KACdW,OAAOC,QAAQZ,KAAK,CAAC,CAACS,OACnB,CAACI,KAAKC,SAAS,OAAOD,QAAQ,YAAYT,YAAYU,GAAG,CAC5D;AAEJ"}
@@ -1 +1 @@
1
- {"version":3,"file":"text.js","names":[],"sources":["../../src/utils/text.ts"],"sourcesContent":["import type { AppendMessage, ThreadMessage } from \"../types/message\";\nimport type { TextMessagePart } from \"../types/message\";\n\nexport const getThreadMessageText = (\n message: ThreadMessage | AppendMessage,\n) => {\n const textParts = message.content.filter(\n (part) => part.type === \"text\",\n ) as TextMessagePart[];\n\n return textParts.map((part) => part.text).join(\"\\n\\n\");\n};\n"],"mappings":";AAGA,MAAa,wBACX,YACG;CAKH,OAJkB,QAAQ,QAAQ,QAC/B,SAAS,KAAK,SAAS,MAGX,CAAC,CAAC,KAAK,SAAS,KAAK,IAAI,CAAC,CAAC,KAAK,MAAM;AACvD"}
1
+ {"version":3,"file":"text.js","names":["AppendMessage","ThreadMessage","TextMessagePart","getThreadMessageText","message","textParts","content","filter","part","type","map","text","join"],"sources":["../../src/utils/text.ts"],"sourcesContent":["import type { AppendMessage, ThreadMessage } from \"../types/message\";\nimport type { TextMessagePart } from \"../types/message\";\n\nexport const getThreadMessageText = (\n message: ThreadMessage | AppendMessage,\n) => {\n const textParts = message.content.filter(\n (part) => part.type === \"text\",\n ) as TextMessagePart[];\n\n return textParts.map((part) => part.text).join(\"\\n\\n\");\n};\n"],"mappings":";AAGA,MAAaG,wBACXC,YACG;CAKH,OAJkBA,QAAQE,QAAQC,QAC/BC,SAASA,KAAKC,SAAS,MAGnBJ,CAAS,CAACK,KAAKF,SAASA,KAAKG,IAAI,CAAC,CAACC,KAAK,MAAM;AACvD"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@assistant-ui/core",
3
- "version": "0.2.14",
3
+ "version": "0.2.16",
4
4
  "description": "Framework-agnostic core runtime for assistant-ui",
5
5
  "keywords": [
6
6
  "assistant",
@@ -59,7 +59,7 @@
59
59
  ],
60
60
  "sideEffects": false,
61
61
  "dependencies": {
62
- "assistant-stream": "^0.3.21",
62
+ "assistant-stream": "^0.3.23",
63
63
  "nanoid": "^5.1.11"
64
64
  },
65
65
  "optionalDevDependencies": {
@@ -67,7 +67,7 @@
67
67
  },
68
68
  "peerDependencies": {
69
69
  "@assistant-ui/store": "^0.2.13",
70
- "@assistant-ui/tap": "^0.7.0",
70
+ "@assistant-ui/tap": "^0.9.0",
71
71
  "@types/react": "*",
72
72
  "react": "^18 || ^19",
73
73
  "assistant-cloud": "^0.1.31",
@@ -92,11 +92,11 @@
92
92
  "react": "^19.2.7",
93
93
  "vitest": "^4.1.8",
94
94
  "zustand": "^5.0.14",
95
- "@assistant-ui/store": "0.2.16",
96
- "@assistant-ui/tap": "0.7.1",
97
- "@assistant-ui/vite": "0.0.4",
98
- "@assistant-ui/x-buildutils": "0.0.12",
99
- "assistant-cloud": "0.1.32"
95
+ "@assistant-ui/store": "0.2.18",
96
+ "@assistant-ui/tap": "0.9.1",
97
+ "@assistant-ui/vite": "0.0.5",
98
+ "@assistant-ui/x-buildutils": "0.0.14",
99
+ "assistant-cloud": "0.1.33"
100
100
  },
101
101
  "publishConfig": {
102
102
  "access": "public",
package/src/index.ts CHANGED
@@ -21,7 +21,11 @@ export type {
21
21
  GenerativeUINode,
22
22
  GenerativeUISpec,
23
23
  Unstable_AudioMessagePart,
24
+ ToolApprovalOption,
25
+ ToolApprovalOptionKind,
26
+ ToolApprovalResponse,
24
27
  ToolCallMessagePart,
28
+ ToolCallTiming,
25
29
  ToolCallMessagePartMcpMetadata,
26
30
  McpAppMetadata,
27
31
  ToolModelContentPart,
package/src/internal.ts CHANGED
@@ -32,6 +32,7 @@ export {
32
32
 
33
33
  // Message utilities
34
34
  export { getThreadMessageText } from "./utils/text";
35
+ export { resolveToolApprovalResponse } from "./runtime/utils/resolveToolApprovalResponse";
35
36
 
36
37
  // Composite context provider
37
38
  export { CompositeContextProvider } from "./utils/composite-context-provider";
@@ -15,6 +15,7 @@ export type LanguageModelConfig = {
15
15
  apiKey?: string;
16
16
  baseUrl?: string;
17
17
  modelName?: string;
18
+ reasoningEffort?: string;
18
19
  };
19
20
 
20
21
  export type ModelContext = {
@@ -21,6 +21,13 @@ export type AssistantProviderBaseProps = PropsWithChildren<{
21
21
 
22
22
  export const AssistantProviderBase: FC<AssistantProviderBaseProps> = memo(
23
23
  ({ runtime, aui: parent = null, children }) => {
24
+ // The runtime has a stable identity but mutates in place: its options are
25
+ // pushed in by an unconditional effect inside <RenderComponent />, so that
26
+ // element must be re-created every commit for React to re-render it and
27
+ // re-run the effect. React Compiler caches <RenderComponent /> on the
28
+ // stable RenderComponent type, which silences the effect and stops option
29
+ // changes (e.g. unstable_enableMessageQueue) from reaching the runtime.
30
+ "use no memo";
24
31
  const aui = useAui({ threads: RuntimeAdapter(runtime) }, { parent });
25
32
  const RenderComponent = getRenderComponent(runtime);
26
33
  const inner = (
@@ -39,10 +39,7 @@ const useTools = ({
39
39
  /** Optional MCP app resource whose tools should be merged into context. */
40
40
  mcpApp?: ResourceElement<McpAppResourceOutput> | undefined;
41
41
  }): ClientOutput<"tools"> => {
42
- const mcpAppOutputs = useResources(
43
- () => (mcpApp ? [withKey("mcpApp", mcpApp)] : []),
44
- [mcpApp],
45
- );
42
+ const mcpAppOutputs = useResources(mcpApp ? [withKey("mcpApp", mcpApp)] : []);
46
43
  const mcpAppOutput = mcpAppOutputs[0];
47
44
 
48
45
  const [toolUIs, setToolUIs] = useState<ToolsState["toolUIs"]>(() => ({}));
@@ -88,7 +85,8 @@ const useTools = ({
88
85
  if (next.length > 0) return { ...prev, [toolName]: next };
89
86
  // Drop the key entirely so repeatedly mounted/unmounted tools
90
87
  // don't leave empty arrays accumulating across a long session.
91
- const { [toolName]: _removed, ...rest } = prev;
88
+ const rest = { ...prev };
89
+ delete rest[toolName];
92
90
  return rest;
93
91
  });
94
92
  };
@@ -1,4 +1,5 @@
1
1
  import { describe, expect, it } from "vitest";
2
+ import type { ToolCallMessagePartProps } from "../types/MessagePartComponentTypes";
2
3
  import { makeToolCallTextComponent } from "./toolbox";
3
4
 
4
5
  describe("makeToolCallTextComponent", () => {
@@ -94,7 +95,7 @@ describe("makeToolCallTextComponent", () => {
94
95
  addResult: () => {},
95
96
  resume: () => {},
96
97
  respondToApproval: () => {},
97
- }),
98
+ } as unknown as ToolCallMessagePartProps),
98
99
  ).toBe("Complete");
99
100
  });
100
101
 
@@ -102,7 +102,7 @@ export const makeToolCallTextComponent = <
102
102
  TResult,
103
103
  >(
104
104
  text: ToolCallText<TArgs, TResult>,
105
- ): ToolCallMessagePartComponent<TArgs, TResult> => {
105
+ ): ((part: ToolCallMessagePartProps<TArgs, TResult>) => ReactNode) => {
106
106
  return function ToolCallTextComponent(part) {
107
107
  return resolveToolCallText(text, part);
108
108
  };
@@ -195,11 +195,7 @@ type OverrideToolDeclarationCallbacks<
195
195
  ) => NoInfer<TResult> | Promise<NoInfer<TResult>>
196
196
  >
197
197
  : {}) &
198
- OverrideOptionalField<
199
- T,
200
- "streamCall",
201
- ToolStreamCall<TArgs, NoInfer<TResult>>
202
- >;
198
+ OverrideOptionalField<T, "streamCall", ToolStreamCall<TArgs, unknown>>;
203
199
 
204
200
  // Keep the authored shape tied to ToolDeclaration's union variants while
205
201
  // overriding callback fields to avoid inference pollution.
@@ -36,7 +36,9 @@ const isInterruptedToolCall = (c: ThreadMessageLikeContentItem): boolean => {
36
36
  if (c.type !== "tool-call" || c.result !== undefined) return false;
37
37
  return (
38
38
  c.interrupt != null ||
39
- (c.approval != null && c.approval.approved === undefined)
39
+ (c.approval != null &&
40
+ c.approval.approved === undefined &&
41
+ c.approval.resolution === undefined)
40
42
  );
41
43
  };
42
44
 
@@ -9,6 +9,7 @@ import type {
9
9
  ReasoningMessagePart,
10
10
  SourceMessagePart,
11
11
  TextMessagePart,
12
+ ToolApprovalResponse,
12
13
  ToolCallMessagePart,
13
14
  Unstable_AudioMessagePart,
14
15
  QuoteInfo,
@@ -73,12 +74,11 @@ export type ToolCallMessagePartProps<
73
74
  resume: (payload: unknown) => void;
74
75
  /**
75
76
  * Responds to a server-side tool approval gate. Only valid while
76
- * `approval` is set on the part and `approval.approved === undefined`.
77
+ * `approval` is set on the part, `approval.approved === undefined`, and
78
+ * no `approval.resolution` is recorded. Accepts a boolean decision or the
79
+ * id of one of `approval.options`; option kinds resolve to the boolean.
77
80
  */
78
- respondToApproval: (response: {
79
- approved: boolean;
80
- reason?: string;
81
- }) => void;
81
+ respondToApproval: (response: ToolApprovalResponse) => void;
82
82
  };
83
83
 
84
84
  /** Component used to render a tool-call message part. */
@@ -1,8 +1,10 @@
1
1
  import type {
2
2
  ThreadAssistantMessagePart,
3
3
  ThreadUserMessagePart,
4
+ ToolApprovalResponse,
4
5
  ToolCallMessagePartStatus,
5
6
  } from "../../types/message";
7
+ import { resolveToolApprovalResponse } from "../utils/resolveToolApprovalResponse";
6
8
  import type { Unsubscribe } from "../../types/unsubscribe";
7
9
  import type { MessagePartStatus } from "../../types/message";
8
10
  import type { SubscribableWithState } from "../../subscribable/subscribable";
@@ -26,7 +28,7 @@ type MessagePartSnapshotBinding = SubscribableWithState<
26
28
  export type MessagePartRuntime = {
27
29
  addToolResult(result: any | ToolResponse<any>): void;
28
30
  resumeToolCall(payload: unknown): void;
29
- respondToToolApproval(response: { approved: boolean; reason?: string }): void;
31
+ respondToToolApproval(response: ToolApprovalResponse): void;
30
32
 
31
33
  readonly path: MessagePartRuntimePath;
32
34
  getState(): MessagePartState;
@@ -104,10 +106,7 @@ export class MessagePartRuntimeImpl implements MessagePartRuntime {
104
106
  });
105
107
  }
106
108
 
107
- public respondToToolApproval(response: {
108
- approved: boolean;
109
- reason?: string;
110
- }) {
109
+ public respondToToolApproval(response: ToolApprovalResponse) {
111
110
  const state = this.contentBinding.getState();
112
111
  if (!state) throw new Error("Message part is not available");
113
112
 
@@ -116,16 +115,20 @@ export class MessagePartRuntimeImpl implements MessagePartRuntime {
116
115
  "Tried to respond to tool approval on non-tool message part",
117
116
  );
118
117
 
119
- if (!state.approval || state.approval.approved !== undefined)
118
+ if (
119
+ !state.approval ||
120
+ state.approval.approved !== undefined ||
121
+ state.approval.resolution !== undefined
122
+ )
120
123
  throw new Error("Tool call has no pending approval");
121
124
 
122
125
  if (!this.threadApi) throw new Error("Thread API is not available");
123
126
 
124
- this.threadApi.getState().respondToToolApproval({
125
- approvalId: state.approval.id,
126
- approved: response.approved,
127
- ...(response.reason != null && { reason: response.reason }),
128
- });
127
+ this.threadApi
128
+ .getState()
129
+ .respondToToolApproval(
130
+ resolveToolApprovalResponse(state.approval, response),
131
+ );
129
132
  }
130
133
 
131
134
  public subscribe(callback: () => void) {
@@ -58,6 +58,8 @@ export type ResumeToolCallOptions = {
58
58
  export type RespondToToolApprovalOptions = {
59
59
  approvalId: string;
60
60
  approved: boolean;
61
+ /** The approval option that produced this decision, when the request carried options. */
62
+ optionId?: string;
61
63
  reason?: string;
62
64
  };
63
65
 
@@ -0,0 +1,91 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { resolveToolApprovalResponse } from "./resolveToolApprovalResponse";
3
+
4
+ const approval = {
5
+ id: "a1",
6
+ options: [
7
+ { id: "once", kind: "allow-once" as const },
8
+ { id: "always", kind: "allow-always" as const, grants: ["git *"] },
9
+ { id: "deny", kind: "reject-once" as const },
10
+ { id: "never", kind: "reject-always" as const },
11
+ { id: "edit", kind: "_modify" },
12
+ ],
13
+ };
14
+
15
+ describe("resolveToolApprovalResponse", () => {
16
+ it("passes through boolean responses", () => {
17
+ expect(resolveToolApprovalResponse(approval, { approved: true })).toEqual({
18
+ approvalId: "a1",
19
+ approved: true,
20
+ });
21
+ expect(
22
+ resolveToolApprovalResponse(approval, {
23
+ approved: false,
24
+ reason: "nope",
25
+ }),
26
+ ).toEqual({ approvalId: "a1", approved: false, reason: "nope" });
27
+ });
28
+
29
+ it("resolves allow kinds to approved: true", () => {
30
+ expect(resolveToolApprovalResponse(approval, { optionId: "once" })).toEqual(
31
+ { approvalId: "a1", approved: true, optionId: "once" },
32
+ );
33
+ expect(
34
+ resolveToolApprovalResponse(approval, { optionId: "always" }),
35
+ ).toEqual({ approvalId: "a1", approved: true, optionId: "always" });
36
+ });
37
+
38
+ it("resolves reject kinds to approved: false and keeps the reason", () => {
39
+ expect(
40
+ resolveToolApprovalResponse(approval, {
41
+ optionId: "deny",
42
+ reason: "not now",
43
+ }),
44
+ ).toEqual({
45
+ approvalId: "a1",
46
+ approved: false,
47
+ optionId: "deny",
48
+ reason: "not now",
49
+ });
50
+ expect(
51
+ resolveToolApprovalResponse(approval, { optionId: "never" }),
52
+ ).toEqual({ approvalId: "a1", approved: false, optionId: "never" });
53
+ });
54
+
55
+ it("throws for an unknown option id", () => {
56
+ expect(() =>
57
+ resolveToolApprovalResponse(approval, { optionId: "missing" }),
58
+ ).toThrow('no option with id "missing"');
59
+ });
60
+
61
+ it("throws for custom kinds instead of guessing a boolean", () => {
62
+ expect(() =>
63
+ resolveToolApprovalResponse(approval, { optionId: "edit" }),
64
+ ).toThrow('custom kind "_modify"');
65
+ });
66
+
67
+ it("accepts an explicit approved alongside the optionId for custom kinds", () => {
68
+ expect(
69
+ resolveToolApprovalResponse(approval, {
70
+ optionId: "edit",
71
+ approved: true,
72
+ }),
73
+ ).toEqual({ approvalId: "a1", approved: true, optionId: "edit" });
74
+ });
75
+
76
+ it("does not resolve kinds named after Object.prototype members", () => {
77
+ const trap = {
78
+ id: "a3",
79
+ options: [{ id: "x", kind: "constructor" }],
80
+ };
81
+ expect(() => resolveToolApprovalResponse(trap, { optionId: "x" })).toThrow(
82
+ 'custom kind "constructor"',
83
+ );
84
+ });
85
+
86
+ it("throws for option responses when the approval has no options", () => {
87
+ expect(() =>
88
+ resolveToolApprovalResponse({ id: "a2" }, { optionId: "once" }),
89
+ ).toThrow('no option with id "once"');
90
+ });
91
+ });
@@ -0,0 +1,55 @@
1
+ import type {
2
+ ToolApprovalOption,
3
+ ToolApprovalResponse,
4
+ } from "../../types/message";
5
+ import type { RespondToToolApprovalOptions } from "../interfaces/thread-runtime-core";
6
+
7
+ const APPROVED_BY_KIND: Record<string, boolean> = {
8
+ "allow-once": true,
9
+ "allow-always": true,
10
+ "reject-once": false,
11
+ "reject-always": false,
12
+ };
13
+
14
+ /**
15
+ * Resolves a renderer-facing approval response (boolean or optionId form)
16
+ * against the approval's option list into the runtime-facing decision shape.
17
+ */
18
+ export const resolveToolApprovalResponse = (
19
+ approval: {
20
+ readonly id: string;
21
+ readonly options?: readonly ToolApprovalOption[];
22
+ },
23
+ response: ToolApprovalResponse,
24
+ ): RespondToToolApprovalOptions => {
25
+ let approved: boolean;
26
+ let optionId: string | undefined;
27
+
28
+ if ("optionId" in response) {
29
+ const option = approval.options?.find((o) => o.id === response.optionId);
30
+ if (!option)
31
+ throw new Error(
32
+ `Tool approval has no option with id "${response.optionId}"`,
33
+ );
34
+
35
+ if ("approved" in response) {
36
+ approved = response.approved;
37
+ } else {
38
+ if (!Object.hasOwn(APPROVED_BY_KIND, option.kind))
39
+ throw new Error(
40
+ `Tool approval option "${option.id}" has a custom kind "${option.kind}"; respond with an explicit approved value instead`,
41
+ );
42
+ approved = APPROVED_BY_KIND[option.kind]!;
43
+ }
44
+ optionId = option.id;
45
+ } else {
46
+ approved = response.approved;
47
+ }
48
+
49
+ return {
50
+ approvalId: approval.id,
51
+ approved,
52
+ ...(optionId !== undefined && { optionId }),
53
+ ...(response.reason != null && { reason: response.reason }),
54
+ };
55
+ };
@@ -18,7 +18,12 @@ import type {
18
18
  Unstable_AudioMessagePart,
19
19
  } from "../../types/message";
20
20
  import type { CompleteAttachment } from "../../types/attachment";
21
- import type { MessageTiming, TextMessagePart } from "../../types/message";
21
+ import type {
22
+ MessageTiming,
23
+ TextMessagePart,
24
+ ToolApprovalOption,
25
+ ToolCallTiming,
26
+ } from "../../types/message";
22
27
  import type {
23
28
  ReadonlyJSONObject,
24
29
  ReadonlyJSONValue,
@@ -55,11 +60,15 @@ export type ThreadMessageLike = {
55
60
  readonly parentId?: string | undefined;
56
61
  readonly messages?: readonly ThreadMessage[] | undefined;
57
62
  readonly interrupt?: { type: "human"; payload: unknown };
63
+ readonly timing?: ToolCallTiming;
58
64
  readonly approval?: {
59
65
  readonly id: string;
60
66
  readonly approved?: boolean;
61
67
  readonly reason?: string;
62
68
  readonly isAutomatic?: boolean;
69
+ readonly options?: readonly ToolApprovalOption[];
70
+ readonly optionId?: string;
71
+ readonly resolution?: "cancelled" | "expired";
63
72
  };
64
73
  }
65
74
  )[];