@assistant-ui/core 0.3.20 → 0.3.21

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 (905) hide show
  1. package/dist/adapters/attachment.d.ts +42 -34
  2. package/dist/adapters/attachment.d.ts.map +1 -1
  3. package/dist/adapters/attachment.js +51 -21
  4. package/dist/adapters/attachment.js.map +1 -1
  5. package/dist/adapters/directive-formatter.d.ts +1 -3
  6. package/dist/adapters/directive-formatter.d.ts.map +1 -1
  7. package/dist/adapters/feedback.d.ts +6 -7
  8. package/dist/adapters/feedback.d.ts.map +1 -1
  9. package/dist/adapters/index.d.ts +14 -9
  10. package/dist/adapters/index.d.ts.map +1 -0
  11. package/dist/adapters/index.js +1 -1
  12. package/dist/adapters/speech.d.ts +57 -58
  13. package/dist/adapters/speech.d.ts.map +1 -1
  14. package/dist/adapters/speech.js +16 -2
  15. package/dist/adapters/speech.js.map +1 -1
  16. package/dist/adapters/suggestion.d.ts +14 -16
  17. package/dist/adapters/suggestion.d.ts.map +1 -1
  18. package/dist/adapters/thread-history.d.ts +54 -51
  19. package/dist/adapters/thread-history.d.ts.map +1 -1
  20. package/dist/adapters/trigger.d.ts +7 -9
  21. package/dist/adapters/trigger.d.ts.map +1 -1
  22. package/dist/adapters/voice.d.ts +46 -40
  23. package/dist/adapters/voice.d.ts.map +1 -1
  24. package/dist/adapters/voice.js +17 -3
  25. package/dist/adapters/voice.js.map +1 -1
  26. package/dist/index.d.ts +70 -56
  27. package/dist/index.d.ts.map +1 -0
  28. package/dist/index.js +6 -6
  29. package/dist/index.js.map +1 -1
  30. package/dist/internal/duplicate-detection.d.ts +0 -2
  31. package/dist/internal/duplicate-detection.d.ts.map +1 -1
  32. package/dist/internal.d.ts +27 -58
  33. package/dist/internal.d.ts.map +1 -0
  34. package/dist/internal.js +8 -6
  35. package/dist/model-context/frame/host.d.ts +19 -21
  36. package/dist/model-context/frame/host.d.ts.map +1 -1
  37. package/dist/model-context/frame/host.js +3 -1
  38. package/dist/model-context/frame/host.js.map +1 -1
  39. package/dist/model-context/frame/provider.d.ts +27 -28
  40. package/dist/model-context/frame/provider.d.ts.map +1 -1
  41. package/dist/model-context/frame/provider.js +6 -0
  42. package/dist/model-context/frame/provider.js.map +1 -1
  43. package/dist/model-context/frame/types.d.ts +19 -21
  44. package/dist/model-context/frame/types.d.ts.map +1 -1
  45. package/dist/model-context/frame/validate.d.ts +3 -0
  46. package/dist/model-context/frame/validate.d.ts.map +1 -0
  47. package/dist/model-context/frame/validate.js +26 -0
  48. package/dist/model-context/frame/validate.js.map +1 -0
  49. package/dist/model-context/interactable-composer-metadata.d.ts +42 -29
  50. package/dist/model-context/interactable-composer-metadata.d.ts.map +1 -1
  51. package/dist/model-context/interactable-composer-metadata.js +30 -6
  52. package/dist/model-context/interactable-composer-metadata.js.map +1 -1
  53. package/dist/model-context/registry-handles.d.ts +6 -8
  54. package/dist/model-context/registry-handles.d.ts.map +1 -1
  55. package/dist/model-context/registry.d.ts +14 -16
  56. package/dist/model-context/registry.d.ts.map +1 -1
  57. package/dist/model-context/tool-call-text.d.ts +13 -14
  58. package/dist/model-context/tool-call-text.d.ts.map +1 -1
  59. package/dist/model-context/tool.d.ts +10 -11
  60. package/dist/model-context/tool.d.ts.map +1 -1
  61. package/dist/model-context/types.d.ts +32 -34
  62. package/dist/model-context/types.d.ts.map +1 -1
  63. package/dist/react/AssistantProvider.d.ts +6 -8
  64. package/dist/react/AssistantProvider.d.ts.map +1 -1
  65. package/dist/react/AssistantRuntimeProvider.d.ts +23 -25
  66. package/dist/react/AssistantRuntimeProvider.d.ts.map +1 -1
  67. package/dist/react/RuntimeAdapter.d.ts +2 -5
  68. package/dist/react/RuntimeAdapter.d.ts.map +1 -1
  69. package/dist/react/adapters/LocalStorageThreadListAdapter.d.ts +24 -18
  70. package/dist/react/adapters/LocalStorageThreadListAdapter.d.ts.map +1 -1
  71. package/dist/react/adapters/LocalStorageThreadListAdapter.js +58 -25
  72. package/dist/react/adapters/LocalStorageThreadListAdapter.js.map +1 -1
  73. package/dist/react/adapters/TitleGenerationAdapter.d.ts +2 -4
  74. package/dist/react/adapters/TitleGenerationAdapter.d.ts.map +1 -1
  75. package/dist/react/client/AdaptedRemoteThread.d.ts +5 -7
  76. package/dist/react/client/AdaptedRemoteThread.d.ts.map +1 -1
  77. package/dist/react/client/DataRenderers.d.ts +1 -3
  78. package/dist/react/client/DataRenderers.d.ts.map +1 -1
  79. package/dist/react/client/InMemoryThreadList.d.ts +6 -8
  80. package/dist/react/client/InMemoryThreadList.d.ts.map +1 -1
  81. package/dist/react/client/Interactables.d.ts +2 -4
  82. package/dist/react/client/Interactables.d.ts.map +1 -1
  83. package/dist/react/client/Interactables.js +306 -101
  84. package/dist/react/client/Interactables.js.map +1 -1
  85. package/dist/react/client/RemoteThreadList.d.ts +32 -34
  86. package/dist/react/client/RemoteThreadList.d.ts.map +1 -1
  87. package/dist/react/client/RemoteThreadList.js +2 -1
  88. package/dist/react/client/RemoteThreadList.js.map +1 -1
  89. package/dist/react/client/Tools.d.ts +9 -11
  90. package/dist/react/client/Tools.d.ts.map +1 -1
  91. package/dist/react/client/Tools.js +4 -8
  92. package/dist/react/client/Tools.js.map +1 -1
  93. package/dist/react/client/interactable-model-context.d.ts +9 -10
  94. package/dist/react/client/interactable-model-context.d.ts.map +1 -1
  95. package/dist/react/client/interactable-model-context.js +32 -22
  96. package/dist/react/client/interactable-model-context.js.map +1 -1
  97. package/dist/react/index.d.ts +160 -122
  98. package/dist/react/index.d.ts.map +1 -0
  99. package/dist/react/index.js +5 -5
  100. package/dist/react/interactables-legacy/Interactables.d.ts +1 -3
  101. package/dist/react/interactables-legacy/Interactables.d.ts.map +1 -1
  102. package/dist/react/interactables-legacy/Interactables.js +15 -8
  103. package/dist/react/interactables-legacy/Interactables.js.map +1 -1
  104. package/dist/react/interactables-legacy/interactable-model-context.d.ts +6 -8
  105. package/dist/react/interactables-legacy/interactable-model-context.d.ts.map +1 -1
  106. package/dist/react/interactables-legacy/interactable-model-context.js +13 -14
  107. package/dist/react/interactables-legacy/interactable-model-context.js.map +1 -1
  108. package/dist/react/interactables-legacy/scopes.d.ts +33 -36
  109. package/dist/react/interactables-legacy/scopes.d.ts.map +1 -1
  110. package/dist/react/interactables-legacy/useAssistantInteractable.d.ts +6 -8
  111. package/dist/react/interactables-legacy/useAssistantInteractable.d.ts.map +1 -1
  112. package/dist/react/interactables-legacy/useInteractableState.d.ts +6 -7
  113. package/dist/react/interactables-legacy/useInteractableState.d.ts.map +1 -1
  114. package/dist/react/interactables-shared/useInteractablePersistenceQueue.d.ts +23 -13
  115. package/dist/react/interactables-shared/useInteractablePersistenceQueue.d.ts.map +1 -1
  116. package/dist/react/interactables-shared/useInteractablePersistenceQueue.js +54 -25
  117. package/dist/react/interactables-shared/useInteractablePersistenceQueue.js.map +1 -1
  118. package/dist/react/model-context/define-mcp-toolkit.d.ts +11 -13
  119. package/dist/react/model-context/define-mcp-toolkit.d.ts.map +1 -1
  120. package/dist/react/model-context/define-toolkit.d.ts +12 -4
  121. package/dist/react/model-context/define-toolkit.d.ts.map +1 -1
  122. package/dist/react/model-context/external-tool.d.ts +0 -2
  123. package/dist/react/model-context/external-tool.d.ts.map +1 -1
  124. package/dist/react/model-context/human-tool.d.ts +0 -2
  125. package/dist/react/model-context/human-tool.d.ts.map +1 -1
  126. package/dist/react/model-context/interactableTool.d.ts +23 -25
  127. package/dist/react/model-context/interactableTool.d.ts.map +1 -1
  128. package/dist/react/model-context/makeAssistantDataUI.d.ts +4 -6
  129. package/dist/react/model-context/makeAssistantDataUI.d.ts.map +1 -1
  130. package/dist/react/model-context/makeAssistantTool.d.ts +4 -6
  131. package/dist/react/model-context/makeAssistantTool.d.ts.map +1 -1
  132. package/dist/react/model-context/makeAssistantToolUI.d.ts +4 -6
  133. package/dist/react/model-context/makeAssistantToolUI.d.ts.map +1 -1
  134. package/dist/react/model-context/provider-tool.d.ts +3 -4
  135. package/dist/react/model-context/provider-tool.d.ts.map +1 -1
  136. package/dist/react/model-context/stub-tool.d.ts +0 -2
  137. package/dist/react/model-context/stub-tool.d.ts.map +1 -1
  138. package/dist/react/model-context/toolbox.d.ts +37 -24
  139. package/dist/react/model-context/toolbox.d.ts.map +1 -1
  140. package/dist/react/model-context/useAssistantContext.d.ts +2 -5
  141. package/dist/react/model-context/useAssistantContext.d.ts.map +1 -1
  142. package/dist/react/model-context/useAssistantDataUI.d.ts +5 -7
  143. package/dist/react/model-context/useAssistantDataUI.d.ts.map +1 -1
  144. package/dist/react/model-context/useAssistantInstructions.d.ts +2 -5
  145. package/dist/react/model-context/useAssistantInstructions.d.ts.map +1 -1
  146. package/dist/react/model-context/useAssistantTool.d.ts +8 -11
  147. package/dist/react/model-context/useAssistantTool.d.ts.map +1 -1
  148. package/dist/react/model-context/useAssistantToolUI.d.ts +11 -13
  149. package/dist/react/model-context/useAssistantToolUI.d.ts.map +1 -1
  150. package/dist/react/model-context/useAuiToolOverrides.d.ts +2 -3
  151. package/dist/react/model-context/useAuiToolOverrides.d.ts.map +1 -1
  152. package/dist/react/model-context/useInlineRender.d.ts +2 -4
  153. package/dist/react/model-context/useInlineRender.d.ts.map +1 -1
  154. package/dist/react/model-context/useInteractable.d.ts +37 -36
  155. package/dist/react/model-context/useInteractable.d.ts.map +1 -1
  156. package/dist/react/model-context/useInteractableState.d.ts +10 -8
  157. package/dist/react/model-context/useInteractableState.d.ts.map +1 -1
  158. package/dist/react/model-context/useInteractableVersions.d.ts +3 -5
  159. package/dist/react/model-context/useInteractableVersions.d.ts.map +1 -1
  160. package/dist/react/model-context/useToolArgsStatus.d.ts +5 -6
  161. package/dist/react/model-context/useToolArgsStatus.d.ts.map +1 -1
  162. package/dist/react/primitive-hooks/useActionBarCopy.d.ts +6 -8
  163. package/dist/react/primitive-hooks/useActionBarCopy.d.ts.map +1 -1
  164. package/dist/react/primitive-hooks/useActionBarEdit.d.ts +2 -4
  165. package/dist/react/primitive-hooks/useActionBarEdit.d.ts.map +1 -1
  166. package/dist/react/primitive-hooks/useActionBarFeedback.d.ts +4 -6
  167. package/dist/react/primitive-hooks/useActionBarFeedback.d.ts.map +1 -1
  168. package/dist/react/primitive-hooks/useActionBarReload.d.ts +2 -4
  169. package/dist/react/primitive-hooks/useActionBarReload.d.ts.map +1 -1
  170. package/dist/react/primitive-hooks/useActionBarSpeak.d.ts +2 -4
  171. package/dist/react/primitive-hooks/useActionBarSpeak.d.ts.map +1 -1
  172. package/dist/react/primitive-hooks/useActionBarStopSpeaking.d.ts +2 -4
  173. package/dist/react/primitive-hooks/useActionBarStopSpeaking.d.ts.map +1 -1
  174. package/dist/react/primitive-hooks/useBranchPickerNext.d.ts +2 -4
  175. package/dist/react/primitive-hooks/useBranchPickerNext.d.ts.map +1 -1
  176. package/dist/react/primitive-hooks/useBranchPickerPrevious.d.ts +2 -4
  177. package/dist/react/primitive-hooks/useBranchPickerPrevious.d.ts.map +1 -1
  178. package/dist/react/primitive-hooks/useComposerAddAttachment.d.ts +3 -5
  179. package/dist/react/primitive-hooks/useComposerAddAttachment.d.ts.map +1 -1
  180. package/dist/react/primitive-hooks/useComposerCancel.d.ts +2 -4
  181. package/dist/react/primitive-hooks/useComposerCancel.d.ts.map +1 -1
  182. package/dist/react/primitive-hooks/useComposerDictate.d.ts +2 -4
  183. package/dist/react/primitive-hooks/useComposerDictate.d.ts.map +1 -1
  184. package/dist/react/primitive-hooks/useComposerSend.d.ts +3 -5
  185. package/dist/react/primitive-hooks/useComposerSend.d.ts.map +1 -1
  186. package/dist/react/primitive-hooks/useEditComposerCancel.d.ts +1 -3
  187. package/dist/react/primitive-hooks/useEditComposerCancel.d.ts.map +1 -1
  188. package/dist/react/primitive-hooks/useEditComposerSend.d.ts +2 -4
  189. package/dist/react/primitive-hooks/useEditComposerSend.d.ts.map +1 -1
  190. package/dist/react/primitive-hooks/useMessageBranching.d.ts +4 -6
  191. package/dist/react/primitive-hooks/useMessageBranching.d.ts.map +1 -1
  192. package/dist/react/primitive-hooks/useMessageError.d.ts +0 -2
  193. package/dist/react/primitive-hooks/useMessageError.d.ts.map +1 -1
  194. package/dist/react/primitive-hooks/useMessageReload.d.ts +2 -4
  195. package/dist/react/primitive-hooks/useMessageReload.d.ts.map +1 -1
  196. package/dist/react/primitive-hooks/useSuggestionTrigger.d.ts +6 -8
  197. package/dist/react/primitive-hooks/useSuggestionTrigger.d.ts.map +1 -1
  198. package/dist/react/primitive-hooks/useSuggestionTrigger.js +4 -4
  199. package/dist/react/primitive-hooks/useSuggestionTrigger.js.map +1 -1
  200. package/dist/react/primitive-hooks/useThreadIsEmpty.d.ts +0 -2
  201. package/dist/react/primitive-hooks/useThreadIsEmpty.d.ts.map +1 -1
  202. package/dist/react/primitive-hooks/useThreadIsRunning.d.ts +0 -2
  203. package/dist/react/primitive-hooks/useThreadIsRunning.d.ts.map +1 -1
  204. package/dist/react/primitive-hooks/useThreadListItemArchive.d.ts +1 -3
  205. package/dist/react/primitive-hooks/useThreadListItemArchive.d.ts.map +1 -1
  206. package/dist/react/primitive-hooks/useThreadListItemDelete.d.ts +1 -3
  207. package/dist/react/primitive-hooks/useThreadListItemDelete.d.ts.map +1 -1
  208. package/dist/react/primitive-hooks/useThreadListItemTrigger.d.ts +1 -3
  209. package/dist/react/primitive-hooks/useThreadListItemTrigger.d.ts.map +1 -1
  210. package/dist/react/primitive-hooks/useThreadListItemUnarchive.d.ts +1 -3
  211. package/dist/react/primitive-hooks/useThreadListItemUnarchive.d.ts.map +1 -1
  212. package/dist/react/primitive-hooks/useThreadListLoadMore.d.ts +2 -4
  213. package/dist/react/primitive-hooks/useThreadListLoadMore.d.ts.map +1 -1
  214. package/dist/react/primitive-hooks/useThreadListNew.d.ts +1 -3
  215. package/dist/react/primitive-hooks/useThreadListNew.d.ts.map +1 -1
  216. package/dist/react/primitive-hooks/useThreadMessageIds.d.ts +0 -2
  217. package/dist/react/primitive-hooks/useThreadMessageIds.d.ts.map +1 -1
  218. package/dist/react/primitive-hooks/useThreadMessages.d.ts +1 -3
  219. package/dist/react/primitive-hooks/useThreadMessages.d.ts.map +1 -1
  220. package/dist/react/primitive-hooks/useVoice.d.ts +5 -7
  221. package/dist/react/primitive-hooks/useVoice.d.ts.map +1 -1
  222. package/dist/react/primitives/chainOfThought/ChainOfThoughtParts.d.ts +25 -26
  223. package/dist/react/primitives/chainOfThought/ChainOfThoughtParts.d.ts.map +1 -1
  224. package/dist/react/primitives/composer/ComposerAttachments.d.ts +22 -23
  225. package/dist/react/primitives/composer/ComposerAttachments.d.ts.map +1 -1
  226. package/dist/react/primitives/composer/ComposerIf.d.ts +10 -9
  227. package/dist/react/primitives/composer/ComposerIf.d.ts.map +1 -1
  228. package/dist/react/primitives/composer/ComposerQueue.d.ts +11 -14
  229. package/dist/react/primitives/composer/ComposerQueue.d.ts.map +1 -1
  230. package/dist/react/primitives/generativeUI/GenerativeUI.d.ts +26 -28
  231. package/dist/react/primitives/generativeUI/GenerativeUI.d.ts.map +1 -1
  232. package/dist/react/primitives/generativeUI/GenerativeUI.js +16 -6
  233. package/dist/react/primitives/generativeUI/GenerativeUI.js.map +1 -1
  234. package/dist/react/primitives/message/MessageAttachments.d.ts +26 -23
  235. package/dist/react/primitives/message/MessageAttachments.d.ts.map +1 -1
  236. package/dist/react/primitives/message/MessageAttachments.js +14 -15
  237. package/dist/react/primitives/message/MessageAttachments.js.map +1 -1
  238. package/dist/react/primitives/message/MessageGroupedParts.d.ts +120 -117
  239. package/dist/react/primitives/message/MessageGroupedParts.d.ts.map +1 -1
  240. package/dist/react/primitives/message/MessageGroupedParts.js +3 -3
  241. package/dist/react/primitives/message/MessageGroupedParts.js.map +1 -1
  242. package/dist/react/primitives/message/MessageParts.d.ts +199 -185
  243. package/dist/react/primitives/message/MessageParts.d.ts.map +1 -1
  244. package/dist/react/primitives/message/MessageParts.js +124 -82
  245. package/dist/react/primitives/message/MessageParts.js.map +1 -1
  246. package/dist/react/primitives/message/MessageQuote.d.ts +6 -8
  247. package/dist/react/primitives/message/MessageQuote.d.ts.map +1 -1
  248. package/dist/react/primitives/messagePart/MessagePartInProgress.d.ts +2 -4
  249. package/dist/react/primitives/messagePart/MessagePartInProgress.d.ts.map +1 -1
  250. package/dist/react/primitives/part/PartMessages.d.ts +13 -15
  251. package/dist/react/primitives/part/PartMessages.d.ts.map +1 -1
  252. package/dist/react/primitives/thread/ThreadMessages.d.ts +54 -56
  253. package/dist/react/primitives/thread/ThreadMessages.d.ts.map +1 -1
  254. package/dist/react/primitives/thread/ThreadSuggestions.d.ts +20 -21
  255. package/dist/react/primitives/thread/ThreadSuggestions.d.ts.map +1 -1
  256. package/dist/react/primitives/thread/ThreadSuggestions.js +24 -5
  257. package/dist/react/primitives/thread/ThreadSuggestions.js.map +1 -1
  258. package/dist/react/primitives/threadList/ThreadListItems.d.ts +22 -23
  259. package/dist/react/primitives/threadList/ThreadListItems.d.ts.map +1 -1
  260. package/dist/react/primitives/threadListItem/ThreadListItemTitle.d.ts +4 -6
  261. package/dist/react/primitives/threadListItem/ThreadListItemTitle.d.ts.map +1 -1
  262. package/dist/react/providers/AttachmentByIndexProvider.d.ts +3 -5
  263. package/dist/react/providers/AttachmentByIndexProvider.d.ts.map +1 -1
  264. package/dist/react/providers/ChainOfThoughtByIndicesProvider.d.ts +3 -5
  265. package/dist/react/providers/ChainOfThoughtByIndicesProvider.d.ts.map +1 -1
  266. package/dist/react/providers/ChainOfThoughtPartByIndexProvider.d.ts +2 -4
  267. package/dist/react/providers/ChainOfThoughtPartByIndexProvider.d.ts.map +1 -1
  268. package/dist/react/providers/MessageByIdProvider.d.ts +2 -4
  269. package/dist/react/providers/MessageByIdProvider.d.ts.map +1 -1
  270. package/dist/react/providers/MessageByIndexProvider.d.ts +2 -4
  271. package/dist/react/providers/MessageByIndexProvider.d.ts.map +1 -1
  272. package/dist/react/providers/PartByIndexProvider.d.ts +2 -4
  273. package/dist/react/providers/PartByIndexProvider.d.ts.map +1 -1
  274. package/dist/react/providers/QueueItemByIndexProvider.d.ts +2 -4
  275. package/dist/react/providers/QueueItemByIndexProvider.d.ts.map +1 -1
  276. package/dist/react/providers/ReadonlyThreadProvider.d.ts +5 -7
  277. package/dist/react/providers/ReadonlyThreadProvider.d.ts.map +1 -1
  278. package/dist/react/providers/ReadonlyThreadProvider.js.map +1 -1
  279. package/dist/react/providers/SuggestionByIndexProvider.d.ts +2 -4
  280. package/dist/react/providers/SuggestionByIndexProvider.d.ts.map +1 -1
  281. package/dist/react/providers/TextMessagePartProvider.d.ts +3 -5
  282. package/dist/react/providers/TextMessagePartProvider.d.ts.map +1 -1
  283. package/dist/react/providers/TextMessagePartProvider.js +5 -1
  284. package/dist/react/providers/TextMessagePartProvider.js.map +1 -1
  285. package/dist/react/providers/ThreadListItemByIndexProvider.d.ts +3 -5
  286. package/dist/react/providers/ThreadListItemByIndexProvider.d.ts.map +1 -1
  287. package/dist/react/providers/ThreadListItemRuntimeProvider.d.ts +3 -6
  288. package/dist/react/providers/ThreadListItemRuntimeProvider.d.ts.map +1 -1
  289. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.d.ts +209 -219
  290. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.d.ts.map +1 -1
  291. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js +53 -39
  292. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js.map +1 -1
  293. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts +185 -196
  294. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts.map +1 -1
  295. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js +13 -4
  296. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js.map +1 -1
  297. package/dist/react/runtimes/RemoteThreadResource.d.ts +14 -19
  298. package/dist/react/runtimes/RemoteThreadResource.d.ts.map +1 -1
  299. package/dist/react/runtimes/RemoteThreadResource.js +3 -1
  300. package/dist/react/runtimes/RemoteThreadResource.js.map +1 -1
  301. package/dist/react/runtimes/RuntimeAdapterProvider.d.ts +8 -9
  302. package/dist/react/runtimes/RuntimeAdapterProvider.d.ts.map +1 -1
  303. package/dist/react/runtimes/assistant-transport/commandQueue.d.ts +9 -11
  304. package/dist/react/runtimes/assistant-transport/commandQueue.d.ts.map +1 -1
  305. package/dist/react/runtimes/assistant-transport/replayBoundaryStream.d.ts +4 -5
  306. package/dist/react/runtimes/assistant-transport/replayBoundaryStream.d.ts.map +1 -1
  307. package/dist/react/runtimes/assistant-transport/replayBoundaryStream.js +9 -2
  308. package/dist/react/runtimes/assistant-transport/replayBoundaryStream.js.map +1 -1
  309. package/dist/react/runtimes/assistant-transport/runManager.d.ts +7 -9
  310. package/dist/react/runtimes/assistant-transport/runManager.d.ts.map +1 -1
  311. package/dist/react/runtimes/assistant-transport/runManager.js +4 -1
  312. package/dist/react/runtimes/assistant-transport/runManager.js.map +1 -1
  313. package/dist/react/runtimes/assistant-transport/types.d.ts +106 -100
  314. package/dist/react/runtimes/assistant-transport/types.d.ts.map +1 -1
  315. package/dist/react/runtimes/assistant-transport/useAssistantTransportRuntime.d.ts +3 -5
  316. package/dist/react/runtimes/assistant-transport/useAssistantTransportRuntime.d.ts.map +1 -1
  317. package/dist/react/runtimes/assistant-transport/useAssistantTransportRuntime.js +17 -6
  318. package/dist/react/runtimes/assistant-transport/useAssistantTransportRuntime.js.map +1 -1
  319. package/dist/react/runtimes/assistant-transport/useConvertedState.d.ts +2 -4
  320. package/dist/react/runtimes/assistant-transport/useConvertedState.d.ts.map +1 -1
  321. package/dist/react/runtimes/assistant-transport/useLatestRef.d.ts +1 -3
  322. package/dist/react/runtimes/assistant-transport/useLatestRef.d.ts.map +1 -1
  323. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.d.ts +5 -7
  324. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.d.ts.map +1 -1
  325. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.js +410 -213
  326. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.js.map +1 -1
  327. package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.d.ts +14 -16
  328. package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.d.ts.map +1 -1
  329. package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.js +8 -4
  330. package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.js.map +1 -1
  331. package/dist/react/runtimes/cloud/auiV0.d.ts +136 -123
  332. package/dist/react/runtimes/cloud/auiV0.d.ts.map +1 -1
  333. package/dist/react/runtimes/cloud/auiV0.js +60 -9
  334. package/dist/react/runtimes/cloud/auiV0.js.map +1 -1
  335. package/dist/react/runtimes/cloud/createCloudThreadListAdapter.d.ts +9 -10
  336. package/dist/react/runtimes/cloud/createCloudThreadListAdapter.d.ts.map +1 -1
  337. package/dist/react/runtimes/cloud/createCloudThreadListAdapterCreateFallback.d.ts +4 -5
  338. package/dist/react/runtimes/cloud/createCloudThreadListAdapterCreateFallback.d.ts.map +1 -1
  339. package/dist/react/runtimes/cloud/sdkIdentity.d.ts +1 -3
  340. package/dist/react/runtimes/cloud/sdkIdentity.d.ts.map +1 -1
  341. package/dist/react/runtimes/cloud/sdkIdentity.js +1 -1
  342. package/dist/react/runtimes/cloud/useCloudThreadListAdapter.d.ts +2 -4
  343. package/dist/react/runtimes/cloud/useCloudThreadListAdapter.d.ts.map +1 -1
  344. package/dist/react/runtimes/cloud/useCloudThreadListRuntime.d.ts +8 -9
  345. package/dist/react/runtimes/cloud/useCloudThreadListRuntime.d.ts.map +1 -1
  346. package/dist/react/runtimes/createMessageConverter.d.ts +14 -17
  347. package/dist/react/runtimes/createMessageConverter.d.ts.map +1 -1
  348. package/dist/react/runtimes/createMessageConverter.js.map +1 -1
  349. package/dist/react/runtimes/createRuntimeExtras.d.ts +11 -13
  350. package/dist/react/runtimes/createRuntimeExtras.d.ts.map +1 -1
  351. package/dist/react/runtimes/external-message-converter.d.ts +14 -18
  352. package/dist/react/runtimes/external-message-converter.d.ts.map +1 -1
  353. package/dist/react/runtimes/external-store-history-copy.d.ts +25 -0
  354. package/dist/react/runtimes/external-store-history-copy.d.ts.map +1 -0
  355. package/dist/react/runtimes/external-store-history-copy.js +148 -0
  356. package/dist/react/runtimes/external-store-history-copy.js.map +1 -0
  357. package/dist/react/runtimes/useExternalStoreRuntime.d.ts +2 -4
  358. package/dist/react/runtimes/useExternalStoreRuntime.d.ts.map +1 -1
  359. package/dist/react/runtimes/useExternalStoreRuntime.js +72 -35
  360. package/dist/react/runtimes/useExternalStoreRuntime.js.map +1 -1
  361. package/dist/react/runtimes/useExternalStoreSharedOptions.d.ts +1 -3
  362. package/dist/react/runtimes/useExternalStoreSharedOptions.d.ts.map +1 -1
  363. package/dist/react/runtimes/useLocalRuntime.d.ts +26 -37
  364. package/dist/react/runtimes/useLocalRuntime.d.ts.map +1 -1
  365. package/dist/react/runtimes/useLocalRuntime.js +142 -34
  366. package/dist/react/runtimes/useLocalRuntime.js.map +1 -1
  367. package/dist/react/runtimes/useRemoteThreadListRuntime.d.ts +2 -4
  368. package/dist/react/runtimes/useRemoteThreadListRuntime.d.ts.map +1 -1
  369. package/dist/react/runtimes/useRuntimeAdapters.d.ts +1 -3
  370. package/dist/react/runtimes/useRuntimeAdapters.d.ts.map +1 -1
  371. package/dist/react/runtimes/useStreamingTiming.d.ts +3 -5
  372. package/dist/react/runtimes/useStreamingTiming.d.ts.map +1 -1
  373. package/dist/react/types/MessagePartComponentTypes.d.ts +46 -43
  374. package/dist/react/types/MessagePartComponentTypes.d.ts.map +1 -1
  375. package/dist/react/types/scopes/dataRenderers.d.ts +8 -11
  376. package/dist/react/types/scopes/dataRenderers.d.ts.map +1 -1
  377. package/dist/react/types/scopes/interactables.d.ts +50 -49
  378. package/dist/react/types/scopes/interactables.d.ts.map +1 -1
  379. package/dist/react/types/scopes/tools.d.ts +17 -19
  380. package/dist/react/types/scopes/tools.d.ts.map +1 -1
  381. package/dist/react/types/store-augmentation.d.ts +10 -11
  382. package/dist/react/types/store-augmentation.d.ts.map +1 -1
  383. package/dist/react/utils/getMessageQuote.d.ts +5 -6
  384. package/dist/react/utils/getMessageQuote.d.ts.map +1 -1
  385. package/dist/react/utils/groupParts.d.ts +28 -29
  386. package/dist/react/utils/groupParts.d.ts.map +1 -1
  387. package/dist/react/utils/useJSONEqual.d.ts +1 -3
  388. package/dist/react/utils/useJSONEqual.d.ts.map +1 -1
  389. package/dist/react/utils/useJSONSchemaDependency.d.ts +2 -4
  390. package/dist/react/utils/useJSONSchemaDependency.d.ts.map +1 -1
  391. package/dist/runtime/api/assistant-runtime.d.ts +26 -28
  392. package/dist/runtime/api/assistant-runtime.d.ts.map +1 -1
  393. package/dist/runtime/api/attachment-runtime.d.ts +46 -43
  394. package/dist/runtime/api/attachment-runtime.d.ts.map +1 -1
  395. package/dist/runtime/api/attachment-runtime.js.map +1 -1
  396. package/dist/runtime/api/bindings.d.ts +31 -30
  397. package/dist/runtime/api/bindings.d.ts.map +1 -1
  398. package/dist/runtime/api/composer-runtime.d.ts +207 -193
  399. package/dist/runtime/api/composer-runtime.d.ts.map +1 -1
  400. package/dist/runtime/api/composer-runtime.js +4 -0
  401. package/dist/runtime/api/composer-runtime.js.map +1 -1
  402. package/dist/runtime/api/message-part-runtime.d.ts +28 -26
  403. package/dist/runtime/api/message-part-runtime.d.ts.map +1 -1
  404. package/dist/runtime/api/message-part-runtime.js +22 -0
  405. package/dist/runtime/api/message-part-runtime.js.map +1 -1
  406. package/dist/runtime/api/message-runtime.d.ts +87 -84
  407. package/dist/runtime/api/message-runtime.d.ts.map +1 -1
  408. package/dist/runtime/api/message-runtime.js +1 -1
  409. package/dist/runtime/api/message-runtime.js.map +1 -1
  410. package/dist/runtime/api/paths.d.ts +48 -50
  411. package/dist/runtime/api/paths.d.ts.map +1 -1
  412. package/dist/runtime/api/thread-list-item-runtime.d.ts +64 -66
  413. package/dist/runtime/api/thread-list-item-runtime.d.ts.map +1 -1
  414. package/dist/runtime/api/thread-list-item-runtime.js.map +1 -1
  415. package/dist/runtime/api/thread-list-runtime.d.ts +73 -76
  416. package/dist/runtime/api/thread-list-runtime.d.ts.map +1 -1
  417. package/dist/runtime/api/thread-list-runtime.js.map +1 -1
  418. package/dist/runtime/api/thread-runtime.d.ts +299 -300
  419. package/dist/runtime/api/thread-runtime.d.ts.map +1 -1
  420. package/dist/runtime/api/thread-runtime.js +2 -1
  421. package/dist/runtime/api/thread-runtime.js.map +1 -1
  422. package/dist/runtime/base/base-assistant-runtime-core.d.ts +8 -10
  423. package/dist/runtime/base/base-assistant-runtime-core.d.ts.map +1 -1
  424. package/dist/runtime/base/base-composer-runtime-core.d.ts +149 -99
  425. package/dist/runtime/base/base-composer-runtime-core.d.ts.map +1 -1
  426. package/dist/runtime/base/base-composer-runtime-core.js +400 -122
  427. package/dist/runtime/base/base-composer-runtime-core.js.map +1 -1
  428. package/dist/runtime/base/base-thread-runtime-core.d.ts +120 -108
  429. package/dist/runtime/base/base-thread-runtime-core.d.ts.map +1 -1
  430. package/dist/runtime/base/base-thread-runtime-core.js +109 -41
  431. package/dist/runtime/base/base-thread-runtime-core.js.map +1 -1
  432. package/dist/runtime/base/default-edit-composer-runtime-core.d.ts +29 -29
  433. package/dist/runtime/base/default-edit-composer-runtime-core.d.ts.map +1 -1
  434. package/dist/runtime/base/default-edit-composer-runtime-core.js +10 -1
  435. package/dist/runtime/base/default-edit-composer-runtime-core.js.map +1 -1
  436. package/dist/runtime/base/default-thread-composer-runtime-core.d.ts +27 -29
  437. package/dist/runtime/base/default-thread-composer-runtime-core.d.ts.map +1 -1
  438. package/dist/runtime/base/default-thread-composer-runtime-core.js +21 -6
  439. package/dist/runtime/base/default-thread-composer-runtime-core.js.map +1 -1
  440. package/dist/runtime/branch/external-thread-branch-adapter.d.ts +14 -16
  441. package/dist/runtime/branch/external-thread-branch-adapter.d.ts.map +1 -1
  442. package/dist/runtime/interfaces/assistant-runtime-core.d.ts +7 -9
  443. package/dist/runtime/interfaces/assistant-runtime-core.d.ts.map +1 -1
  444. package/dist/runtime/interfaces/composer-runtime-core.d.ts +88 -72
  445. package/dist/runtime/interfaces/composer-runtime-core.d.ts.map +1 -1
  446. package/dist/runtime/interfaces/thread-list-runtime-core.d.ts +63 -65
  447. package/dist/runtime/interfaces/thread-list-runtime-core.d.ts.map +1 -1
  448. package/dist/runtime/interfaces/thread-runtime-core.d.ts +210 -197
  449. package/dist/runtime/interfaces/thread-runtime-core.d.ts.map +1 -1
  450. package/dist/runtime/internal.d.ts +25 -20
  451. package/dist/runtime/internal.d.ts.map +1 -0
  452. package/dist/runtime/queue/external-thread-queue-adapter.d.ts +35 -37
  453. package/dist/runtime/queue/external-thread-queue-adapter.d.ts.map +1 -1
  454. package/dist/runtime/queue/message-queue.d.ts +29 -31
  455. package/dist/runtime/queue/message-queue.d.ts.map +1 -1
  456. package/dist/runtime/queue/message-queue.js +1 -1
  457. package/dist/runtime/queue/queue-item.d.ts +5 -7
  458. package/dist/runtime/queue/queue-item.d.ts.map +1 -1
  459. package/dist/runtime/utils/abortable-thread-load.d.ts +7 -8
  460. package/dist/runtime/utils/abortable-thread-load.d.ts.map +1 -1
  461. package/dist/runtime/utils/attachment-add-operations.d.ts +13 -11
  462. package/dist/runtime/utils/attachment-add-operations.d.ts.map +1 -1
  463. package/dist/runtime/utils/attachment-add-operations.js +24 -2
  464. package/dist/runtime/utils/attachment-add-operations.js.map +1 -1
  465. package/dist/runtime/utils/attachment-send-operations.d.ts +12 -0
  466. package/dist/runtime/utils/attachment-send-operations.d.ts.map +1 -0
  467. package/dist/runtime/utils/attachment-send-operations.js +34 -0
  468. package/dist/runtime/utils/attachment-send-operations.js.map +1 -0
  469. package/dist/runtime/utils/auto-status.d.ts +4 -5
  470. package/dist/runtime/utils/auto-status.d.ts.map +1 -1
  471. package/dist/runtime/utils/auto-status.js +3 -5
  472. package/dist/runtime/utils/auto-status.js.map +1 -1
  473. package/dist/runtime/utils/chat-model-adapter.d.ts +26 -27
  474. package/dist/runtime/utils/chat-model-adapter.d.ts.map +1 -1
  475. package/dist/runtime/utils/external-message-conversion.d.ts +32 -32
  476. package/dist/runtime/utils/external-message-conversion.d.ts.map +1 -1
  477. package/dist/runtime/utils/external-message-conversion.js +3 -3
  478. package/dist/runtime/utils/external-message-conversion.js.map +1 -1
  479. package/dist/runtime/utils/external-store-message.d.ts +2 -4
  480. package/dist/runtime/utils/external-store-message.d.ts.map +1 -1
  481. package/dist/runtime/utils/message-repository-session.d.ts +21 -23
  482. package/dist/runtime/utils/message-repository-session.d.ts.map +1 -1
  483. package/dist/runtime/utils/message-repository.d.ts +50 -51
  484. package/dist/runtime/utils/message-repository.d.ts.map +1 -1
  485. package/dist/runtime/utils/message-repository.js +8 -7
  486. package/dist/runtime/utils/message-repository.js.map +1 -1
  487. package/dist/runtime/utils/pending-tool-calls.d.ts +10 -11
  488. package/dist/runtime/utils/pending-tool-calls.d.ts.map +1 -1
  489. package/dist/runtime/utils/resolveToolApprovalResponse.d.ts +6 -8
  490. package/dist/runtime/utils/resolveToolApprovalResponse.d.ts.map +1 -1
  491. package/dist/runtime/utils/runtime-extras-brand.d.ts +4 -6
  492. package/dist/runtime/utils/runtime-extras-brand.d.ts.map +1 -1
  493. package/dist/runtime/utils/stored-message-parts.d.ts +5 -5
  494. package/dist/runtime/utils/stored-message-parts.d.ts.map +1 -1
  495. package/dist/runtime/utils/stored-message-parts.js +22 -2
  496. package/dist/runtime/utils/stored-message-parts.js.map +1 -1
  497. package/dist/runtime/utils/streaming-timing.d.ts +19 -21
  498. package/dist/runtime/utils/streaming-timing.d.ts.map +1 -1
  499. package/dist/runtime/utils/thread-message-like.d.ts +36 -32
  500. package/dist/runtime/utils/thread-message-like.d.ts.map +1 -1
  501. package/dist/runtime/utils/thread-message-like.js +16 -6
  502. package/dist/runtime/utils/thread-message-like.js.map +1 -1
  503. package/dist/runtime/utils/thread-runtime-lifecycle.d.ts +4 -5
  504. package/dist/runtime/utils/thread-runtime-lifecycle.d.ts.map +1 -1
  505. package/dist/runtime/utils/thread-runtime-lifecycle.js +31 -4
  506. package/dist/runtime/utils/thread-runtime-lifecycle.js.map +1 -1
  507. package/dist/runtime/utils/tool-call-tree.d.ts +6 -8
  508. package/dist/runtime/utils/tool-call-tree.d.ts.map +1 -1
  509. package/dist/runtime/utils/tool-interactions.d.ts +10 -0
  510. package/dist/runtime/utils/tool-interactions.d.ts.map +1 -0
  511. package/dist/runtime/utils/tool-interactions.js +92 -0
  512. package/dist/runtime/utils/tool-interactions.js.map +1 -0
  513. package/dist/runtimes/assistant-transport/utils.d.ts +0 -2
  514. package/dist/runtimes/assistant-transport/utils.d.ts.map +1 -1
  515. package/dist/runtimes/external-store/external-store-adapter.d.ts +215 -198
  516. package/dist/runtimes/external-store/external-store-adapter.d.ts.map +1 -1
  517. package/dist/runtimes/external-store/external-store-runtime-core.d.ts +5 -6
  518. package/dist/runtimes/external-store/external-store-runtime-core.d.ts.map +1 -1
  519. package/dist/runtimes/external-store/external-store-runtime-core.js +4 -1
  520. package/dist/runtimes/external-store/external-store-runtime-core.js.map +1 -1
  521. package/dist/runtimes/external-store/external-store-shared-options.d.ts +1 -3
  522. package/dist/runtimes/external-store/external-store-shared-options.d.ts.map +1 -1
  523. package/dist/runtimes/external-store/external-store-thread-list-runtime-core.d.ts +38 -40
  524. package/dist/runtimes/external-store/external-store-thread-list-runtime-core.d.ts.map +1 -1
  525. package/dist/runtimes/external-store/external-store-thread-list-runtime-core.js +2 -2
  526. package/dist/runtimes/external-store/external-store-thread-list-runtime-core.js.map +1 -1
  527. package/dist/runtimes/external-store/external-store-thread-runtime-core.d.ts +117 -124
  528. package/dist/runtimes/external-store/external-store-thread-runtime-core.d.ts.map +1 -1
  529. package/dist/runtimes/external-store/external-store-thread-runtime-core.js +44 -14
  530. package/dist/runtimes/external-store/external-store-thread-runtime-core.js.map +1 -1
  531. package/dist/runtimes/external-store/thread-message-converter.d.ts +3 -5
  532. package/dist/runtimes/external-store/thread-message-converter.d.ts.map +1 -1
  533. package/dist/runtimes/inert/InertThreadRuntimeCore.d.ts +94 -95
  534. package/dist/runtimes/inert/InertThreadRuntimeCore.d.ts.map +1 -1
  535. package/dist/runtimes/inert/InertThreadRuntimeCore.js +3 -0
  536. package/dist/runtimes/inert/InertThreadRuntimeCore.js.map +1 -1
  537. package/dist/runtimes/internal.d.ts +20 -16
  538. package/dist/runtimes/internal.d.ts.map +1 -0
  539. package/dist/runtimes/local/local-runtime-core.d.ts +6 -8
  540. package/dist/runtimes/local/local-runtime-core.d.ts.map +1 -1
  541. package/dist/runtimes/local/local-runtime-options.d.ts +40 -42
  542. package/dist/runtimes/local/local-runtime-options.d.ts.map +1 -1
  543. package/dist/runtimes/local/local-thread-list-runtime-core.d.ts +40 -42
  544. package/dist/runtimes/local/local-thread-list-runtime-core.d.ts.map +1 -1
  545. package/dist/runtimes/local/local-thread-runtime-core.d.ts +93 -97
  546. package/dist/runtimes/local/local-thread-runtime-core.d.ts.map +1 -1
  547. package/dist/runtimes/local/local-thread-runtime-core.js +178 -31
  548. package/dist/runtimes/local/local-thread-runtime-core.js.map +1 -1
  549. package/dist/runtimes/local/should-continue.d.ts +1 -3
  550. package/dist/runtimes/local/should-continue.d.ts.map +1 -1
  551. package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.d.ts +76 -53
  552. package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.d.ts.map +1 -1
  553. package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.js +28 -1
  554. package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.js.map +1 -1
  555. package/dist/runtimes/remote-thread-list/adapter/in-memory.d.ts +11 -13
  556. package/dist/runtimes/remote-thread-list/adapter/in-memory.d.ts.map +1 -1
  557. package/dist/runtimes/remote-thread-list/adapter-changed.d.ts +2 -4
  558. package/dist/runtimes/remote-thread-list/adapter-changed.d.ts.map +1 -1
  559. package/dist/runtimes/remote-thread-list/empty-thread-core.d.ts +1 -3
  560. package/dist/runtimes/remote-thread-list/empty-thread-core.d.ts.map +1 -1
  561. package/dist/runtimes/remote-thread-list/optimistic-state.d.ts +33 -29
  562. package/dist/runtimes/remote-thread-list/optimistic-state.d.ts.map +1 -1
  563. package/dist/runtimes/remote-thread-list/optimistic-state.js +8 -3
  564. package/dist/runtimes/remote-thread-list/optimistic-state.js.map +1 -1
  565. package/dist/runtimes/remote-thread-list/remote-thread-state.d.ts +44 -46
  566. package/dist/runtimes/remote-thread-list/remote-thread-state.d.ts.map +1 -1
  567. package/dist/runtimes/remote-thread-list/remote-thread-state.js +1 -1
  568. package/dist/runtimes/remote-thread-list/title-generation.d.ts +25 -26
  569. package/dist/runtimes/remote-thread-list/title-generation.d.ts.map +1 -1
  570. package/dist/runtimes/remote-thread-list/title.d.ts +3 -5
  571. package/dist/runtimes/remote-thread-list/title.d.ts.map +1 -1
  572. package/dist/runtimes/remote-thread-list/types.d.ts +111 -112
  573. package/dist/runtimes/remote-thread-list/types.d.ts.map +1 -1
  574. package/dist/runtimes/tool-invocations/ToolInvocationTracker.d.ts +144 -145
  575. package/dist/runtimes/tool-invocations/ToolInvocationTracker.d.ts.map +1 -1
  576. package/dist/runtimes/tool-invocations/ToolInvocationTracker.js +22 -7
  577. package/dist/runtimes/tool-invocations/ToolInvocationTracker.js.map +1 -1
  578. package/dist/store/clients/chain-of-thought-client.d.ts +7 -9
  579. package/dist/store/clients/chain-of-thought-client.d.ts.map +1 -1
  580. package/dist/store/clients/external-thread.d.ts +53 -54
  581. package/dist/store/clients/external-thread.d.ts.map +1 -1
  582. package/dist/store/clients/external-thread.js +1256 -731
  583. package/dist/store/clients/external-thread.js.map +1 -1
  584. package/dist/store/clients/model-context-client.d.ts +1 -3
  585. package/dist/store/clients/model-context-client.d.ts.map +1 -1
  586. package/dist/store/clients/no-op-composer-client.d.ts +2 -4
  587. package/dist/store/clients/no-op-composer-client.d.ts.map +1 -1
  588. package/dist/store/clients/no-op-composer-client.js +3 -1
  589. package/dist/store/clients/no-op-composer-client.js.map +1 -1
  590. package/dist/store/clients/runtime-adapter.d.ts +1 -3
  591. package/dist/store/clients/runtime-adapter.d.ts.map +1 -1
  592. package/dist/store/clients/single-thread-list.d.ts +3 -4
  593. package/dist/store/clients/single-thread-list.d.ts.map +1 -1
  594. package/dist/store/clients/submission-message.d.ts +8 -0
  595. package/dist/store/clients/submission-message.d.ts.map +1 -0
  596. package/dist/store/clients/submission-message.js +22 -0
  597. package/dist/store/clients/submission-message.js.map +1 -0
  598. package/dist/store/clients/suggestions.d.ts +5 -7
  599. package/dist/store/clients/suggestions.d.ts.map +1 -1
  600. package/dist/store/clients/thread-message-client.d.ts +10 -9
  601. package/dist/store/clients/thread-message-client.d.ts.map +1 -1
  602. package/dist/store/clients/thread-message-client.js +81 -82
  603. package/dist/store/clients/thread-message-client.js.map +1 -1
  604. package/dist/store/clients/thread-selection-events.d.ts +0 -2
  605. package/dist/store/clients/thread-selection-events.d.ts.map +1 -1
  606. package/dist/store/clients/thread-tasks.d.ts +4 -6
  607. package/dist/store/clients/thread-tasks.d.ts.map +1 -1
  608. package/dist/store/env.d.ts +0 -2
  609. package/dist/store/env.d.ts.map +1 -1
  610. package/dist/store/index.d.ts +33 -36
  611. package/dist/store/index.d.ts.map +1 -0
  612. package/dist/store/index.js +5 -5
  613. package/dist/store/internal.d.ts +12 -12
  614. package/dist/store/internal.d.ts.map +1 -0
  615. package/dist/store/internal.js +2 -2
  616. package/dist/store/primitive-predicates.d.ts +3 -4
  617. package/dist/store/primitive-predicates.d.ts.map +1 -1
  618. package/dist/store/primitive-predicates.js +9 -4
  619. package/dist/store/primitive-predicates.js.map +1 -1
  620. package/dist/store/runtime-clients/attachment-runtime-client.d.ts +3 -5
  621. package/dist/store/runtime-clients/attachment-runtime-client.d.ts.map +1 -1
  622. package/dist/store/runtime-clients/composer-runtime-client.d.ts +10 -12
  623. package/dist/store/runtime-clients/composer-runtime-client.d.ts.map +1 -1
  624. package/dist/store/runtime-clients/composer-runtime-client.js +65 -62
  625. package/dist/store/runtime-clients/composer-runtime-client.js.map +1 -1
  626. package/dist/store/runtime-clients/handle-runtime-action.d.ts +0 -2
  627. package/dist/store/runtime-clients/handle-runtime-action.d.ts.map +1 -1
  628. package/dist/store/runtime-clients/handle-thread-list-action.d.ts +0 -2
  629. package/dist/store/runtime-clients/handle-thread-list-action.d.ts.map +1 -1
  630. package/dist/store/runtime-clients/liveRef.d.ts +1 -3
  631. package/dist/store/runtime-clients/liveRef.d.ts.map +1 -1
  632. package/dist/store/runtime-clients/message-part-runtime-client.d.ts +3 -5
  633. package/dist/store/runtime-clients/message-part-runtime-client.d.ts.map +1 -1
  634. package/dist/store/runtime-clients/message-part-runtime-client.js +26 -16
  635. package/dist/store/runtime-clients/message-part-runtime-client.js.map +1 -1
  636. package/dist/store/runtime-clients/message-runtime-client.d.ts +9 -9
  637. package/dist/store/runtime-clients/message-runtime-client.d.ts.map +1 -1
  638. package/dist/store/runtime-clients/message-runtime-client.js +121 -113
  639. package/dist/store/runtime-clients/message-runtime-client.js.map +1 -1
  640. package/dist/store/runtime-clients/thread-list-item-runtime-client.d.ts +4 -6
  641. package/dist/store/runtime-clients/thread-list-item-runtime-client.d.ts.map +1 -1
  642. package/dist/store/runtime-clients/thread-list-runtime-client.d.ts +5 -7
  643. package/dist/store/runtime-clients/thread-list-runtime-client.d.ts.map +1 -1
  644. package/dist/store/runtime-clients/thread-runtime-client.d.ts +3 -5
  645. package/dist/store/runtime-clients/thread-runtime-client.d.ts.map +1 -1
  646. package/dist/store/runtime-clients/thread-runtime-client.js +221 -158
  647. package/dist/store/runtime-clients/thread-runtime-client.js.map +1 -1
  648. package/dist/store/runtime-clients/useSubscribable.d.ts +2 -4
  649. package/dist/store/runtime-clients/useSubscribable.d.ts.map +1 -1
  650. package/dist/store/scope-registration.d.ts +28 -29
  651. package/dist/store/scope-registration.d.ts.map +1 -1
  652. package/dist/store/scopes/attachment.d.ts +15 -17
  653. package/dist/store/scopes/attachment.d.ts.map +1 -1
  654. package/dist/store/scopes/chain-of-thought.d.ts +28 -29
  655. package/dist/store/scopes/chain-of-thought.d.ts.map +1 -1
  656. package/dist/store/scopes/composer.d.ts +141 -128
  657. package/dist/store/scopes/composer.d.ts.map +1 -1
  658. package/dist/store/scopes/message.d.ts +114 -107
  659. package/dist/store/scopes/message.d.ts.map +1 -1
  660. package/dist/store/scopes/model-context.d.ts +7 -9
  661. package/dist/store/scopes/model-context.d.ts.map +1 -1
  662. package/dist/store/scopes/part.d.ts +49 -45
  663. package/dist/store/scopes/part.d.ts.map +1 -1
  664. package/dist/store/scopes/queue-item.d.ts +18 -20
  665. package/dist/store/scopes/queue-item.d.ts.map +1 -1
  666. package/dist/store/scopes/suggestion.d.ts +10 -12
  667. package/dist/store/scopes/suggestion.d.ts.map +1 -1
  668. package/dist/store/scopes/suggestions.d.ts +13 -15
  669. package/dist/store/scopes/suggestions.d.ts.map +1 -1
  670. package/dist/store/scopes/task.d.ts +23 -25
  671. package/dist/store/scopes/task.d.ts.map +1 -1
  672. package/dist/store/scopes/thread-list-item.d.ts +63 -65
  673. package/dist/store/scopes/thread-list-item.d.ts.map +1 -1
  674. package/dist/store/scopes/thread.d.ts +192 -194
  675. package/dist/store/scopes/thread.d.ts.map +1 -1
  676. package/dist/store/scopes/threads.d.ts +45 -47
  677. package/dist/store/scopes/threads.d.ts.map +1 -1
  678. package/dist/subscribable/subscribable.d.ts +58 -53
  679. package/dist/subscribable/subscribable.d.ts.map +1 -1
  680. package/dist/subscribable/subscribable.js +35 -7
  681. package/dist/subscribable/subscribable.js.map +1 -1
  682. package/dist/types/attachment.d.ts +26 -27
  683. package/dist/types/attachment.d.ts.map +1 -1
  684. package/dist/types/augmentations.d.ts +4 -4
  685. package/dist/types/augmentations.d.ts.map +1 -1
  686. package/dist/types/directive.d.ts +11 -13
  687. package/dist/types/directive.d.ts.map +1 -1
  688. package/dist/types/error.d.ts +7 -8
  689. package/dist/types/error.d.ts.map +1 -1
  690. package/dist/types/index.d.ts +7 -7
  691. package/dist/types/index.d.ts.map +1 -0
  692. package/dist/types/message.d.ts +322 -284
  693. package/dist/types/message.d.ts.map +1 -1
  694. package/dist/types/message.js.map +1 -1
  695. package/dist/types/quote.d.ts +2 -4
  696. package/dist/types/quote.d.ts.map +1 -1
  697. package/dist/types/trigger.d.ts +8 -10
  698. package/dist/types/trigger.d.ts.map +1 -1
  699. package/dist/types/unsubscribe.d.ts +0 -2
  700. package/dist/types/unsubscribe.d.ts.map +1 -1
  701. package/dist/utils/abortable-iterable.d.ts +0 -2
  702. package/dist/utils/abortable-iterable.d.ts.map +1 -1
  703. package/dist/utils/composite-context-provider.d.ts +8 -11
  704. package/dist/utils/composite-context-provider.d.ts.map +1 -1
  705. package/dist/utils/data-url.d.ts +10 -12
  706. package/dist/utils/data-url.d.ts.map +1 -1
  707. package/dist/utils/getGroupStatus.d.ts +17 -18
  708. package/dist/utils/getGroupStatus.d.ts.map +1 -1
  709. package/dist/utils/id.d.ts +0 -2
  710. package/dist/utils/id.d.ts.map +1 -1
  711. package/dist/utils/image-media-type.d.ts +0 -2
  712. package/dist/utils/image-media-type.d.ts.map +1 -1
  713. package/dist/utils/invoke-user-callback.d.ts +0 -2
  714. package/dist/utils/invoke-user-callback.d.ts.map +1 -1
  715. package/dist/utils/json/is-json-equal.d.ts +0 -2
  716. package/dist/utils/json/is-json-equal.d.ts.map +1 -1
  717. package/dist/utils/json/is-json.d.ts +1 -3
  718. package/dist/utils/json/is-json.d.ts.map +1 -1
  719. package/dist/utils/json/stable-stringify-tool-args.d.ts +1 -3
  720. package/dist/utils/json/stable-stringify-tool-args.d.ts.map +1 -1
  721. package/dist/utils/normalizePartStatus.d.ts +2 -3
  722. package/dist/utils/normalizePartStatus.d.ts.map +1 -1
  723. package/dist/utils/normalizePartStatus.js +3 -2
  724. package/dist/utils/normalizePartStatus.js.map +1 -1
  725. package/dist/utils/notify-event-listeners.d.ts +1 -2
  726. package/dist/utils/notify-event-listeners.d.ts.map +1 -1
  727. package/dist/utils/record.d.ts +0 -2
  728. package/dist/utils/record.d.ts.map +1 -1
  729. package/dist/utils/silent-runtime-action.d.ts +0 -2
  730. package/dist/utils/silent-runtime-action.d.ts.map +1 -1
  731. package/dist/utils/text.d.ts +1 -3
  732. package/dist/utils/text.d.ts.map +1 -1
  733. package/dist/utils/wire-media.d.ts +0 -2
  734. package/dist/utils/wire-media.d.ts.map +1 -1
  735. package/package.json +11 -10
  736. package/src/adapters/attachment.test.ts +98 -1
  737. package/src/adapters/attachment.ts +70 -20
  738. package/src/adapters/speech.test.ts +94 -0
  739. package/src/adapters/speech.ts +16 -2
  740. package/src/adapters/thread-history.ts +16 -5
  741. package/src/adapters/voice.test.ts +169 -0
  742. package/src/adapters/voice.ts +25 -4
  743. package/src/index.ts +14 -2
  744. package/src/internal.ts +7 -0
  745. package/src/model-context/frame/host.test.ts +51 -1
  746. package/src/model-context/frame/host.ts +3 -1
  747. package/src/model-context/frame/provider.test.ts +61 -0
  748. package/src/model-context/frame/provider.ts +8 -1
  749. package/src/model-context/frame/validate.ts +57 -0
  750. package/src/model-context/interactable-composer-metadata.test.ts +82 -0
  751. package/src/model-context/interactable-composer-metadata.ts +45 -2
  752. package/src/react/adapters/LocalStorageThreadListAdapter.test.ts +594 -0
  753. package/src/react/adapters/LocalStorageThreadListAdapter.tsx +98 -35
  754. package/src/react/client/Interactables.test.ts +853 -1
  755. package/src/react/client/Interactables.ts +325 -45
  756. package/src/react/client/RemoteThreadList.initialize-failure.test.ts +124 -0
  757. package/src/react/client/RemoteThreadList.ts +6 -0
  758. package/src/react/client/Tools.ts +2 -3
  759. package/src/react/client/interactable-model-context.test.ts +56 -13
  760. package/src/react/client/interactable-model-context.ts +48 -23
  761. package/src/react/index.ts +2 -2
  762. package/src/react/interactables-legacy/Interactables.test.ts +212 -1
  763. package/src/react/interactables-legacy/Interactables.ts +25 -14
  764. package/src/react/interactables-legacy/interactable-model-context.ts +26 -24
  765. package/src/react/interactables-shared/useInteractablePersistenceQueue.test.tsx +22 -2
  766. package/src/react/interactables-shared/useInteractablePersistenceQueue.ts +63 -11
  767. package/src/react/primitive-hooks/useSuggestionTrigger.test.ts +33 -0
  768. package/src/react/primitive-hooks/useSuggestionTrigger.ts +7 -4
  769. package/src/react/primitives/generativeUI/GenerativeUI.test.tsx +124 -8
  770. package/src/react/primitives/generativeUI/GenerativeUI.tsx +35 -15
  771. package/src/react/primitives/message/MessageAttachments.test.tsx +2 -6
  772. package/src/react/primitives/message/MessageAttachments.tsx +14 -8
  773. package/src/react/primitives/message/MessageGroupedParts.test.tsx +151 -7
  774. package/src/react/primitives/message/MessageGroupedParts.tsx +19 -6
  775. package/src/react/primitives/message/MessageParts.test.tsx +84 -0
  776. package/src/react/primitives/message/MessageParts.tool-interaction.test.tsx +69 -0
  777. package/src/react/primitives/message/MessageParts.tsx +29 -8
  778. package/src/react/primitives/thread/ThreadSuggestions.test.tsx +97 -0
  779. package/src/react/primitives/thread/ThreadSuggestions.tsx +29 -6
  780. package/src/react/providers/ReadonlyThreadProvider.tsx +2 -2
  781. package/src/react/providers/TextMessagePartProvider.tsx +3 -0
  782. package/src/react/runtimes/RemoteThreadListHookInstanceManager.running.test.tsx +93 -0
  783. package/src/react/runtimes/RemoteThreadListHookInstanceManager.test.tsx +160 -3
  784. package/src/react/runtimes/RemoteThreadListHookInstanceManager.title.test.tsx +38 -0
  785. package/src/react/runtimes/RemoteThreadListHookInstanceManager.tsx +73 -53
  786. package/src/react/runtimes/RemoteThreadListThreadListRuntimeCore.tsx +19 -3
  787. package/src/react/runtimes/RemoteThreadResource.ts +5 -2
  788. package/src/react/runtimes/assistant-transport/replayBoundaryStream.test.ts +3 -1
  789. package/src/react/runtimes/assistant-transport/replayBoundaryStream.ts +10 -2
  790. package/src/react/runtimes/assistant-transport/runManager.ts +3 -0
  791. package/src/react/runtimes/assistant-transport/transport-parentid.test.tsx +57 -0
  792. package/src/react/runtimes/assistant-transport/transport-thread-id.test.tsx +571 -0
  793. package/src/react/runtimes/assistant-transport/types.ts +9 -1
  794. package/src/react/runtimes/assistant-transport/useAssistantTransport.spec.md +10 -0
  795. package/src/react/runtimes/assistant-transport/useAssistantTransportRuntime.test.tsx +42 -0
  796. package/src/react/runtimes/assistant-transport/useAssistantTransportRuntime.ts +33 -9
  797. package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.copy.integration.test.tsx +289 -0
  798. package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.copy.test.tsx +471 -0
  799. package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.engagement.test.tsx +330 -0
  800. package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.test.ts +78 -2
  801. package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.test.tsx +361 -2
  802. package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.ts +571 -216
  803. package/src/react/runtimes/cloud/CloudFileAttachmentAdapter.test.ts +25 -0
  804. package/src/react/runtimes/cloud/CloudFileAttachmentAdapter.ts +7 -3
  805. package/src/react/runtimes/cloud/auiV0.ts +158 -9
  806. package/src/react/runtimes/cloud/auiV0DecodeSafely.test.ts +352 -1
  807. package/src/react/runtimes/createMessageConverter.ts +9 -3
  808. package/src/react/runtimes/external-store-history-copy.ts +223 -0
  809. package/src/react/runtimes/useExternalStoreRuntime.history-copy.test.tsx +483 -0
  810. package/src/react/runtimes/useExternalStoreRuntime.lifecycle.test.tsx +76 -1
  811. package/src/react/runtimes/useExternalStoreRuntime.ts +25 -5
  812. package/src/react/runtimes/useLocalRuntime.test.tsx +145 -1
  813. package/src/react/runtimes/useLocalRuntime.ts +8 -5
  814. package/src/react/types/MessagePartComponentTypes.ts +10 -0
  815. package/src/react/types/scopes/interactables.ts +3 -0
  816. package/src/runtime/api/attachment-runtime.ts +10 -5
  817. package/src/runtime/api/bindings.ts +6 -1
  818. package/src/runtime/api/composer-runtime.ts +29 -6
  819. package/src/runtime/api/message-part-runtime.test.ts +215 -0
  820. package/src/runtime/api/message-part-runtime.ts +40 -0
  821. package/src/runtime/api/message-runtime.test.ts +112 -2
  822. package/src/runtime/api/message-runtime.ts +10 -5
  823. package/src/runtime/api/thread-list-item-runtime.ts +5 -5
  824. package/src/runtime/api/thread-list-runtime.ts +3 -3
  825. package/src/runtime/api/thread-runtime.test.ts +59 -0
  826. package/src/runtime/api/thread-runtime.ts +21 -11
  827. package/src/runtime/base/base-composer-runtime-core.ts +548 -153
  828. package/src/runtime/base/base-thread-runtime-core.test.ts +744 -9
  829. package/src/runtime/base/base-thread-runtime-core.ts +154 -27
  830. package/src/runtime/base/default-edit-composer-runtime-core.ts +13 -1
  831. package/src/runtime/base/default-thread-composer-runtime-core.ts +29 -10
  832. package/src/runtime/interfaces/composer-runtime-core.ts +19 -0
  833. package/src/runtime/interfaces/thread-runtime-core.ts +22 -1
  834. package/src/runtime/utils/attachment-add-operations.ts +45 -2
  835. package/src/runtime/utils/attachment-send-operations.ts +54 -0
  836. package/src/runtime/utils/auto-status.test.ts +54 -0
  837. package/src/runtime/utils/auto-status.ts +3 -10
  838. package/src/runtime/utils/external-message-conversion.test.ts +48 -0
  839. package/src/runtime/utils/external-message-conversion.ts +3 -4
  840. package/src/runtime/utils/message-repository.test.ts +69 -1
  841. package/src/runtime/utils/message-repository.ts +14 -7
  842. package/src/runtime/utils/stored-message-parts.ts +43 -1
  843. package/src/runtime/utils/thread-message-like.test.ts +58 -0
  844. package/src/runtime/utils/thread-message-like.ts +72 -46
  845. package/src/runtime/utils/thread-runtime-lifecycle.test.ts +67 -0
  846. package/src/runtime/utils/thread-runtime-lifecycle.ts +42 -8
  847. package/src/runtime/utils/tool-interactions.test.ts +193 -0
  848. package/src/runtime/utils/tool-interactions.ts +147 -0
  849. package/src/runtimes/external-store/external-store-adapter.ts +22 -1
  850. package/src/runtimes/external-store/external-store-runtime-core.ts +10 -2
  851. package/src/runtimes/external-store/external-store-thread-list-runtime-core.ts +2 -2
  852. package/src/runtimes/external-store/external-store-thread-runtime-core.test.ts +49 -0
  853. package/src/runtimes/external-store/external-store-thread-runtime-core.ts +76 -29
  854. package/src/runtimes/inert/InertThreadRuntimeCore.test.ts +127 -56
  855. package/src/runtimes/inert/InertThreadRuntimeCore.ts +10 -1
  856. package/src/runtimes/local/local-thread-runtime-core.edit-cancellation.test.ts +70 -0
  857. package/src/runtimes/local/local-thread-runtime-core.test.ts +1649 -108
  858. package/src/runtimes/local/local-thread-runtime-core.ts +301 -47
  859. package/src/runtimes/readonly/ReadonlyThreadRuntimeCore.ts +53 -1
  860. package/src/runtimes/remote-thread-list/optimistic-state.ts +8 -3
  861. package/src/runtimes/tool-invocations/EDGE_CASES.md +19 -4
  862. package/src/runtimes/tool-invocations/ToolInvocationTracker.test.ts +392 -39
  863. package/src/runtimes/tool-invocations/ToolInvocationTracker.ts +31 -8
  864. package/src/store/clients/external-thread.test.ts +145 -0
  865. package/src/store/clients/external-thread.ts +635 -131
  866. package/src/store/clients/model-context-client.test.ts +8 -8
  867. package/src/store/clients/no-op-composer-client.ts +2 -0
  868. package/src/store/clients/submission-message.ts +27 -0
  869. package/src/store/clients/thread-message-client.test.ts +39 -0
  870. package/src/store/clients/thread-message-client.ts +13 -6
  871. package/src/store/index.ts +2 -2
  872. package/src/store/internal.ts +1 -0
  873. package/src/store/primitive-predicates.test.ts +103 -0
  874. package/src/store/primitive-predicates.ts +15 -3
  875. package/src/store/runtime-clients/composer-runtime-client.ts +4 -3
  876. package/src/store/runtime-clients/message-part-runtime-client.test.ts +42 -0
  877. package/src/store/runtime-clients/message-part-runtime-client.ts +4 -0
  878. package/src/store/runtime-clients/message-runtime-client.ts +5 -0
  879. package/src/store/runtime-clients/thread-runtime-client.test.tsx +138 -5
  880. package/src/store/runtime-clients/thread-runtime-client.ts +46 -9
  881. package/src/store/scopes/composer.ts +22 -4
  882. package/src/store/scopes/message.ts +8 -0
  883. package/src/store/scopes/part.ts +8 -0
  884. package/src/subscribable/subscribable.test.ts +198 -1
  885. package/src/subscribable/subscribable.ts +49 -7
  886. package/src/tests/RemoteThreadListThreadListRuntimeCore-errors.test.ts +95 -1
  887. package/src/tests/auiV0Encode.test.ts +408 -1
  888. package/src/tests/base-composer-runtime-core-send.test.ts +722 -29
  889. package/src/tests/base-composer-runtime-core.test.ts +196 -0
  890. package/src/tests/composer-can-send.test.ts +98 -1
  891. package/src/tests/composer-submission.test.tsx +796 -0
  892. package/src/tests/default-edit-composer-runtime-core.test.ts +102 -2
  893. package/src/tests/external-store-thread-list-runtime-core.test.ts +111 -0
  894. package/src/tests/external-store-thread-runtime-core-adapter.test.ts +581 -1
  895. package/src/tests/external-store-thread-runtime-core.test.ts +186 -0
  896. package/src/tests/external-thread-attachments.test.tsx +741 -3
  897. package/src/tests/external-thread-isLast.test.tsx +69 -0
  898. package/src/tests/get-thread-state-isRunning.test.ts +2 -2
  899. package/src/tests/remote-thread-list-adapter-switch.test.ts +45 -1
  900. package/src/types/message.ts +49 -2
  901. package/src/utils/normalizePartStatus.ts +14 -1
  902. package/dist/tests/remote-thread-list-test-helpers.d.ts +0 -15
  903. package/dist/tests/remote-thread-list-test-helpers.d.ts.map +0 -1
  904. package/dist/tests/remote-thread-list-test-helpers.js +0 -59
  905. package/dist/tests/remote-thread-list-test-helpers.js.map +0 -1
@@ -1,6 +1,7 @@
1
1
  import { useState, useMemo, useEffect, useCallback, useRef } from "react";
2
2
  import { resource, withKey } from "@assistant-ui/tap";
3
3
  import type { ClientElement, ClientOutput } from "@assistant-ui/store";
4
+ import { useAssistantClientDestroySignal } from "@assistant-ui/store/internal";
4
5
  import {
5
6
  useClientLookup,
6
7
  attachTransformScopes,
@@ -18,8 +19,8 @@ import type {
18
19
  } from "../../types/message";
19
20
  import type {
20
21
  Attachment,
22
+ CompleteAttachment,
21
23
  CreateAttachment,
22
- PendingAttachment,
23
24
  } from "../../types/attachment";
24
25
  import {
25
26
  isAttachmentComplete,
@@ -31,12 +32,15 @@ import type {
31
32
  ResumeToolCallOptions,
32
33
  SpeechState,
33
34
  ThreadSuggestion,
35
+ Unstable_RecordToolInteractionOptions,
34
36
  } from "../../runtime/interfaces/thread-runtime-core";
37
+ import type { Unstable_ToolInteractionInput } from "../../types/message";
35
38
  import type {
36
39
  ExternalThreadQueueAdapter,
37
40
  QueuePlacement,
38
41
  } from "../../runtime/queue/external-thread-queue-adapter";
39
42
  import type { ExternalThreadBranchAdapter } from "../../runtime/branch/external-thread-branch-adapter";
43
+ import type { ComposerSubmission } from "../../runtime/interfaces/composer-runtime-core";
40
44
  import type { AttachmentAdapter } from "../../adapters/attachment";
41
45
  import type { FeedbackAdapter } from "../../adapters/feedback";
42
46
  import type { SpeechSynthesisAdapter } from "../../adapters/speech";
@@ -47,10 +51,14 @@ import type { ComposerSendOptions } from "../scopes/composer";
47
51
  import { fileMatchesAccept } from "../../adapters/attachment";
48
52
  import { getThreadMessageText } from "../../utils/text";
49
53
  import { resolveToolApprovalResponse } from "../../runtime/utils/resolveToolApprovalResponse";
54
+ import { createToolInteraction } from "../../runtime/utils/tool-interactions";
50
55
  import {
51
56
  AttachmentAddOperations,
52
57
  drainAttachmentAdd,
53
58
  } from "../../runtime/utils/attachment-add-operations";
59
+ import { AttachmentSendOperations } from "../../runtime/utils/attachment-send-operations";
60
+ import { ThreadMessageClient } from "./thread-message-client";
61
+ import { submissionThreadMessage } from "./submission-message";
54
62
  import { toMessagePartStatus } from "../../utils/normalizePartStatus";
55
63
  import { generateId } from "../../utils/id";
56
64
  import { ModelContext } from "./model-context-client";
@@ -126,11 +134,15 @@ export type ExternalThreadProps = {
126
134
  onRespondToToolApproval?: (
127
135
  options: RespondToToolApprovalOptions,
128
136
  ) => void | Promise<void>;
137
+ unstable_onRecordToolInteraction?:
138
+ | ((options: Unstable_RecordToolInteractionOptions) => void | Promise<void>)
139
+ | undefined;
129
140
  };
130
141
 
131
142
  type MessageClientProps = {
132
143
  message: ExternalThreadMessage;
133
144
  index: number;
145
+ isLast: boolean;
134
146
  parentId: string | null;
135
147
  onEdit?: (message: AppendMessage) => void;
136
148
  onReload?: () => void;
@@ -139,6 +151,9 @@ type MessageClientProps = {
139
151
  onRespondToToolApproval?:
140
152
  | ((options: RespondToToolApprovalOptions) => void | Promise<void>)
141
153
  | undefined;
154
+ unstable_onRecordToolInteraction?:
155
+ | ((options: Unstable_RecordToolInteractionOptions) => void | Promise<void>)
156
+ | undefined;
142
157
  onAddToolResult?: ((options: AddToolResultOptions) => void) | undefined;
143
158
  onResumeToolCall?: ((options: ResumeToolCallOptions) => void) | undefined;
144
159
  attachmentAdapter?: AttachmentAdapter | undefined;
@@ -158,12 +173,14 @@ type MessageClientProps = {
158
173
  const useMessageClient = ({
159
174
  message,
160
175
  index,
176
+ isLast,
161
177
  parentId,
162
178
  onEdit,
163
179
  onReload,
164
180
  queue,
165
181
  branches,
166
182
  onRespondToToolApproval,
183
+ unstable_onRecordToolInteraction,
167
184
  onAddToolResult,
168
185
  onResumeToolCall,
169
186
  attachmentAdapter,
@@ -185,6 +202,7 @@ const useMessageClient = ({
185
202
  status: derivePartStatus(message, idx, part),
186
203
  messageId: message.id,
187
204
  onRespondToToolApproval,
205
+ unstable_onRecordToolInteraction,
188
206
  onAddToolResult,
189
207
  onResumeToolCall,
190
208
  }),
@@ -249,7 +267,7 @@ const useMessageClient = ({
249
267
  ...messageWithFeedback,
250
268
  attachments: message.attachments ?? [],
251
269
  parentId,
252
- isLast: false, // Will be set by thread
270
+ isLast,
253
271
  branchNumber,
254
272
  branchCount,
255
273
  speech,
@@ -261,6 +279,7 @@ const useMessageClient = ({
261
279
  };
262
280
  }, [
263
281
  message,
282
+ isLast,
264
283
  parentId,
265
284
  isCopied,
266
285
  isHovering,
@@ -327,6 +346,9 @@ type PartResourceProps = {
327
346
  onRespondToToolApproval?:
328
347
  | ((options: RespondToToolApprovalOptions) => void | Promise<void>)
329
348
  | undefined;
349
+ unstable_onRecordToolInteraction?:
350
+ | ((options: Unstable_RecordToolInteractionOptions) => void | Promise<void>)
351
+ | undefined;
330
352
  onAddToolResult?: ((options: AddToolResultOptions) => void) | undefined;
331
353
  onResumeToolCall?: ((options: ResumeToolCallOptions) => void) | undefined;
332
354
  };
@@ -337,6 +359,7 @@ const usePartResource = ({
337
359
  status,
338
360
  messageId,
339
361
  onRespondToToolApproval,
362
+ unstable_onRecordToolInteraction,
340
363
  onAddToolResult,
341
364
  onResumeToolCall,
342
365
  }: PartResourceProps): ClientOutput<"part"> => {
@@ -377,6 +400,18 @@ const usePartResource = ({
377
400
  throw new Error("Tried to resume tool call on non-tool message part");
378
401
 
379
402
  onResumeToolCall({ toolCallId: part.toolCallId, payload });
403
+ void Promise.resolve()
404
+ .then(() =>
405
+ unstable_onRecordToolInteraction?.({
406
+ messageId,
407
+ toolCallId: part.toolCallId,
408
+ interaction: createToolInteraction({
409
+ type: "human-response",
410
+ payload,
411
+ }),
412
+ }),
413
+ )
414
+ .catch(() => {});
380
415
  },
381
416
  respondToToolApproval: (response) => {
382
417
  if (!onRespondToToolApproval)
@@ -401,6 +436,22 @@ const usePartResource = ({
401
436
  return Promise.reject(error);
402
437
  }
403
438
  },
439
+ unstable_recordInteraction: async (
440
+ input: Unstable_ToolInteractionInput,
441
+ ) => {
442
+ if (!unstable_onRecordToolInteraction)
443
+ throw new Error(
444
+ "Runtime does not support recording tool interactions.",
445
+ );
446
+ if (part.type !== "tool-call")
447
+ throw new Error("Tried to record interaction on non-tool message part");
448
+
449
+ await unstable_onRecordToolInteraction({
450
+ messageId,
451
+ toolCallId: part.toolCallId,
452
+ interaction: createToolInteraction(input),
453
+ });
454
+ },
404
455
  };
405
456
  };
406
457
 
@@ -426,6 +477,8 @@ const useAttachmentResource = ({
426
477
 
427
478
  const AttachmentResource = resource(useAttachmentResource);
428
479
 
480
+ const EMPTY_MESSAGE_KEYS: readonly string[] = Object.freeze([]);
481
+
429
482
  type ComposerClientResourceProps = {
430
483
  type: "thread" | "edit";
431
484
  canCancel: boolean;
@@ -437,6 +490,8 @@ type ComposerClientResourceProps = {
437
490
  message?: ExternalThreadMessage;
438
491
  queue?: ExternalThreadQueueAdapter | undefined;
439
492
  attachmentAdapter?: AttachmentAdapter | undefined;
493
+ /** `id|role` of each thread message, used to tell when a send has landed. */
494
+ messageKeys?: readonly string[] | undefined;
440
495
  };
441
496
 
442
497
  const useQueueItemClient = ({
@@ -473,34 +528,59 @@ const useLiveState = <T>(initial: T) => {
473
528
  };
474
529
 
475
530
  // A try/catch inside the resource makes the React Compiler bail out of the
476
- // whole hook, so the adapter call and its failure status live at module scope.
531
+ // whole hook, so calls that can throw go through these module-scope helpers.
477
532
  const removeAttachmentThroughAdapter = async (
478
533
  attachment: Attachment,
479
534
  attachmentAdapter: AttachmentAdapter | undefined,
480
- setAttachments: (
481
- next:
482
- | readonly Attachment[]
483
- | ((prev: readonly Attachment[]) => readonly Attachment[]),
484
- ) => void,
535
+ onError: (message: string) => void,
485
536
  ) => {
486
537
  try {
487
538
  await attachmentAdapter?.remove(attachment);
488
539
  } catch (error) {
489
- const message = error instanceof Error ? error.message : String(error);
490
- setAttachments((prev) =>
491
- prev.map((candidate) =>
492
- candidate.id === attachment.id && !isAttachmentComplete(candidate)
493
- ? {
494
- ...candidate,
495
- status: { type: "incomplete", reason: "error", message },
496
- }
497
- : candidate,
498
- ),
499
- );
540
+ onError(error instanceof Error ? error.message : String(error));
500
541
  throw error;
501
542
  }
502
543
  };
503
544
 
545
+ const dispatchSafely = (dispatch: () => void) => {
546
+ try {
547
+ dispatch();
548
+ return undefined;
549
+ } catch (error) {
550
+ return { error };
551
+ }
552
+ };
553
+
554
+ // A hidden thread keeps preparing its send, so only the owner's permanent
555
+ // teardown aborts it, never an effect cleanup.
556
+ const abortOnDestroy = (
557
+ destroySignal: AbortSignal | undefined,
558
+ controller: AbortController,
559
+ ) => {
560
+ if (!destroySignal) return () => {};
561
+ const abort = () => controller.abort(destroySignal.reason);
562
+ if (destroySignal.aborted) {
563
+ abort();
564
+ return () => {};
565
+ }
566
+ // A cancelled send can stay unsettled forever, so its abort unlinks too.
567
+ const unlink = () => {
568
+ destroySignal.removeEventListener("abort", abort);
569
+ controller.signal.removeEventListener("abort", unlink);
570
+ };
571
+ destroySignal.addEventListener("abort", abort, { once: true });
572
+ controller.signal.addEventListener("abort", unlink, { once: true });
573
+ return unlink;
574
+ };
575
+
576
+ type InTransitEntry = {
577
+ readonly submission: ComposerSubmission;
578
+ /** `id|role` of each thread message when the submission was dispatched. */
579
+ readonly known: ReadonlySet<string>;
580
+ };
581
+
582
+ const EMPTY_IN_TRANSIT: readonly InTransitEntry[] = Object.freeze([]);
583
+
504
584
  // Composer Client - minimal implementation
505
585
  const useComposerClientResource = ({
506
586
  type,
@@ -513,6 +593,7 @@ const useComposerClientResource = ({
513
593
  message,
514
594
  queue,
515
595
  attachmentAdapter,
596
+ messageKeys = EMPTY_MESSAGE_KEYS,
516
597
  }: ComposerClientResourceProps): ClientOutput<"composer"> => {
517
598
  const [isEditing, setIsEditing, isEditingRef] = useLiveState(
518
599
  type === "thread",
@@ -534,6 +615,65 @@ const useComposerClientResource = ({
534
615
  () => new AttachmentAddOperations(),
535
616
  [],
536
617
  );
618
+ const attachmentSends = useMemo(() => new AttachmentSendOperations(), []);
619
+ const destroySignal = useAssistantClientDestroySignal();
620
+ const [submission, setSubmission, submissionRef] = useLiveState<
621
+ ComposerSubmission | undefined
622
+ >(undefined);
623
+ const submissionSend = useRef<
624
+ | {
625
+ readonly options: ComposerSendOptions | undefined;
626
+ readonly runConfig: Record<string, unknown>;
627
+ readonly controller: AbortController;
628
+ }
629
+ | undefined
630
+ >(undefined);
631
+ const [inTransit, setInTransit] =
632
+ useLiveState<readonly InTransitEntry[]>(EMPTY_IN_TRANSIT);
633
+ const messageKeysRef = useRef(messageKeys);
634
+ const sendGeneration = useRef(0);
635
+
636
+ // A dispatched message stays on screen until the host shows it, so the two
637
+ // never swap through an empty frame. Each new message of a send's role
638
+ // stands in for the oldest send still waiting for one, and a shown send
639
+ // leaves in the same render its message arrives in.
640
+ const shown = useMemo(() => {
641
+ const claimed = new Set<string>();
642
+ const landed = new Set<InTransitEntry>();
643
+ for (const entry of inTransit) {
644
+ const key = messageKeys.find(
645
+ (candidate) =>
646
+ !entry.known.has(candidate) &&
647
+ !claimed.has(candidate) &&
648
+ candidate.endsWith(`|${entry.submission.role}`),
649
+ );
650
+ if (key === undefined) continue;
651
+ claimed.add(key);
652
+ landed.add(entry);
653
+ }
654
+ return { landed, claimed };
655
+ }, [inTransit, messageKeys]);
656
+ const inTransitSubmissions = useMemo(
657
+ () =>
658
+ inTransit
659
+ .filter((entry) => !shown.landed.has(entry))
660
+ .map((entry) => entry.submission),
661
+ [inTransit, shown],
662
+ );
663
+ useEffect(() => {
664
+ messageKeysRef.current = messageKeys;
665
+ if (shown.landed.size === 0) return;
666
+ // A message stands in for one send only, so the sends still waiting stop
667
+ // counting it as new.
668
+ setInTransit((prev) =>
669
+ prev
670
+ .filter((entry) => !shown.landed.has(entry))
671
+ .map((entry) => ({
672
+ ...entry,
673
+ known: new Set([...entry.known, ...shown.claimed]),
674
+ })),
675
+ );
676
+ }, [messageKeys, shown, setInTransit]);
537
677
 
538
678
  const updateFromMessage = () => {
539
679
  if (!message) return;
@@ -543,33 +683,130 @@ const useComposerClientResource = ({
543
683
  .join("\n\n");
544
684
  setText(messageText);
545
685
  setRole(message.role);
546
- setAttachments(message.attachments ?? []);
686
+ // Re-seeding from the message abandons any removal begun in a previous
687
+ // edit session, so the restored objects must shed their removal marks.
688
+ const restored = message.attachments ?? [];
689
+ for (const attachment of restored)
690
+ attachmentSends.unmarkRemoved(attachment);
691
+ setAttachments(restored);
547
692
  };
548
693
 
694
+ const handleRemoveAttachment = useCallback(
695
+ async (attachment: Attachment) => {
696
+ attachmentAddOperations.cancel(attachment.id);
697
+ attachmentSends.markRemoved(attachment);
698
+ if (!isAttachmentComplete(attachment)) {
699
+ await removeAttachmentThroughAdapter(
700
+ attachment,
701
+ attachmentAdapter,
702
+ (message) =>
703
+ setAttachments((prev) =>
704
+ prev.map((candidate) =>
705
+ candidate.id === attachment.id &&
706
+ !isAttachmentComplete(candidate)
707
+ ? attachmentSends.transfer(candidate, {
708
+ ...candidate,
709
+ status: { type: "incomplete", reason: "error", message },
710
+ })
711
+ : candidate,
712
+ ),
713
+ ),
714
+ );
715
+ }
716
+ setAttachments((prev) => prev.filter((a) => a.id !== attachment.id));
717
+ },
718
+ [
719
+ attachmentAddOperations,
720
+ attachmentAdapter,
721
+ attachmentSends,
722
+ setAttachments,
723
+ ],
724
+ );
725
+
726
+ // A submission is not delivered yet, so its attachments stay reachable by id
727
+ // and can still be taken out of the message that is being sent.
728
+ const handleRemoveSubmittedAttachment = useCallback(
729
+ async (attachment: Attachment) => {
730
+ attachmentAddOperations.cancel(attachment.id);
731
+ attachmentSends.markRemoved(attachment);
732
+ if (!isAttachmentComplete(attachment)) {
733
+ // An attachment whose removal failed stays out of the message it was
734
+ // taken from and shows why, so the removal can be tried again.
735
+ await removeAttachmentThroughAdapter(
736
+ attachment,
737
+ attachmentAdapter,
738
+ (message) =>
739
+ setSubmission((prev) =>
740
+ prev
741
+ ? {
742
+ ...prev,
743
+ attachments: prev.attachments.map((candidate) => {
744
+ if (
745
+ candidate.id !== attachment.id ||
746
+ isAttachmentComplete(candidate)
747
+ )
748
+ return candidate;
749
+ const failed = attachmentSends.transfer(candidate, {
750
+ ...candidate,
751
+ status: {
752
+ type: "incomplete",
753
+ reason: "error",
754
+ message,
755
+ },
756
+ });
757
+ attachmentSends.markRemoved(failed);
758
+ return failed;
759
+ }),
760
+ }
761
+ : prev,
762
+ ),
763
+ );
764
+ }
765
+ setSubmission((prev) =>
766
+ prev
767
+ ? {
768
+ ...prev,
769
+ attachments: prev.attachments.filter(
770
+ (a) => a.id !== attachment.id,
771
+ ),
772
+ }
773
+ : prev,
774
+ );
775
+ },
776
+ [
777
+ attachmentAddOperations,
778
+ attachmentAdapter,
779
+ attachmentSends,
780
+ setSubmission,
781
+ ],
782
+ );
783
+
549
784
  const attachmentClients = useClientLookup(
550
785
  attachments.map((attachment) =>
551
786
  withKey(
552
787
  attachment.id,
553
788
  AttachmentResource({
554
789
  attachment,
555
- onRemove: async () => {
556
- attachmentAddOperations.cancel(attachment.id);
557
- if (!isAttachmentComplete(attachment)) {
558
- await removeAttachmentThroughAdapter(
559
- attachment,
560
- attachmentAdapter,
561
- setAttachments,
562
- );
563
- }
564
- setAttachments((prev) =>
565
- prev.filter((a) => a.id !== attachment.id),
566
- );
567
- },
790
+ onRemove: () => handleRemoveAttachment(attachment),
568
791
  }),
569
792
  ),
570
793
  ),
571
794
  );
572
795
 
796
+ const submittedAttachmentClients = useClientLookup(
797
+ (submission?.attachments ?? [])
798
+ .filter((attachment) => !attachments.some((a) => a.id === attachment.id))
799
+ .map((attachment) =>
800
+ withKey(
801
+ attachment.id,
802
+ AttachmentResource({
803
+ attachment,
804
+ onRemove: () => handleRemoveSubmittedAttachment(attachment),
805
+ }),
806
+ ),
807
+ ),
808
+ );
809
+
573
810
  const removePendingAttachments = async (removed: readonly Attachment[]) => {
574
811
  if (!attachmentAdapter) return;
575
812
  await Promise.all(
@@ -580,6 +817,16 @@ const useComposerClientResource = ({
580
817
  };
581
818
 
582
819
  const upsertAttachment = (attachment: Attachment) => {
820
+ const current = submissionRef.current;
821
+ if (current?.attachments.some((a) => a.id === attachment.id)) {
822
+ setSubmission({
823
+ ...current,
824
+ attachments: current.attachments.map((a) =>
825
+ a.id === attachment.id ? attachmentSends.transfer(a, attachment) : a,
826
+ ),
827
+ });
828
+ return;
829
+ }
583
830
  setAttachments((prev) => {
584
831
  const idx = prev.findIndex((a) => a.id === attachment.id);
585
832
  if (idx === -1) return [...prev, attachment];
@@ -621,14 +868,17 @@ const useComposerClientResource = ({
621
868
  attachments: attachmentClients.state,
622
869
  runConfig,
623
870
  isEditing,
624
- canCancel,
625
- canSend: isEditing && !isEmpty && !isSendDisabled,
871
+ canCancel: canCancel || submission !== undefined,
872
+ canSend:
873
+ isEditing && !isEmpty && !isSendDisabled && submission === undefined,
626
874
  attachmentAccept: attachmentAdapter?.accept ?? "*",
627
875
  isEmpty,
628
876
  type,
629
877
  dictation: undefined,
630
878
  quote,
631
879
  queue: queueItems,
880
+ submission,
881
+ inTransit: inTransitSubmissions,
632
882
  };
633
883
  }, [
634
884
  text,
@@ -638,6 +888,8 @@ const useComposerClientResource = ({
638
888
  isEditing,
639
889
  canCancel,
640
890
  isSendDisabled,
891
+ submission,
892
+ inTransitSubmissions,
641
893
  type,
642
894
  attachments.length,
643
895
  quote,
@@ -645,6 +897,211 @@ const useComposerClientResource = ({
645
897
  attachmentAdapter?.accept,
646
898
  ]);
647
899
 
900
+ /** Ends the send being prepared, so nothing it started can dispatch it. */
901
+ const endSubmission = () => {
902
+ sendGeneration.current++;
903
+ submissionSend.current = undefined;
904
+ setSubmission(undefined);
905
+ };
906
+
907
+ // Takes a send's content back into the draft, ahead of anything written
908
+ // since. An edit composer kept its draft, so it only takes back the state
909
+ // the attachments came back in, such as the reason one failed.
910
+ const returnToDraft = (content: ComposerSubmission) => {
911
+ if (type !== "thread") {
912
+ const returned = new Map(
913
+ content.attachments.map((attachment) => [attachment.id, attachment]),
914
+ );
915
+ setAttachments((prev) =>
916
+ prev.map((attachment) => returned.get(attachment.id) ?? attachment),
917
+ );
918
+ return;
919
+ }
920
+ const kept = content.attachments.filter(
921
+ (attachment) => !attachmentSends.isRemoved(attachment),
922
+ );
923
+ setAttachments((prev) => [...kept, ...prev]);
924
+ setText((prev) => [content.text, prev].filter(Boolean).join("\n"));
925
+ setQuote((prev) => prev ?? content.quote);
926
+ };
927
+
928
+ const cancelSubmission = () => {
929
+ const current = submissionRef.current;
930
+ if (!current) return;
931
+ submissionSend.current?.controller.abort();
932
+ endSubmission();
933
+ returnToDraft(current);
934
+ };
935
+
936
+ const discardSubmission = async () => {
937
+ const current = submissionRef.current;
938
+ if (!current) return;
939
+ submissionSend.current?.controller.abort();
940
+ endSubmission();
941
+ // An attachment the draft still holds is removed along with the draft.
942
+ const drafted = new Set(attachmentsRef.current.map((a) => a.id));
943
+ await removePendingAttachments(
944
+ current.attachments.filter((attachment) => !drafted.has(attachment.id)),
945
+ );
946
+ };
947
+
948
+ const returnSubmissionToDraft = (
949
+ sent: readonly Attachment[],
950
+ settled: readonly PromiseSettledResult<CompleteAttachment>[],
951
+ reason: unknown,
952
+ ) => {
953
+ const current = submissionRef.current;
954
+ if (!current) return;
955
+ const failures = new Map<string, unknown>();
956
+ settled.forEach((result, index) => {
957
+ if (result.status === "rejected")
958
+ failures.set(sent[index]!.id, result.reason);
959
+ });
960
+ // Each attachment that could not be prepared carries its own reason, so
961
+ // the draft it returns to shows which file needs another try.
962
+ const attachments = current.attachments.map((attachment) => {
963
+ if (!failures.has(attachment.id) || isAttachmentComplete(attachment))
964
+ return attachment;
965
+ const failure = failures.get(attachment.id);
966
+ return attachmentSends.transfer(attachment, {
967
+ ...attachment,
968
+ status: {
969
+ type: "incomplete",
970
+ reason: "error",
971
+ message: failure instanceof Error ? failure.message : String(failure),
972
+ },
973
+ });
974
+ });
975
+ endSubmission();
976
+ returnToDraft({ ...current, attachments });
977
+ console.error("Failed to send attachments", reason);
978
+ };
979
+
980
+ const dispatchMessage = (
981
+ current: ComposerSubmission,
982
+ attachments: readonly CompleteAttachment[],
983
+ context: {
984
+ readonly options: ComposerSendOptions | undefined;
985
+ readonly runConfig: Record<string, unknown>;
986
+ },
987
+ isSubmission: boolean,
988
+ ) => {
989
+ const composedMessage: AppendMessage = {
990
+ role: current.role,
991
+ content: current.text
992
+ ? [{ type: "text" as const, text: current.text }]
993
+ : [],
994
+ attachments,
995
+ createdAt: new Date(),
996
+ parentId: null,
997
+ sourceId: null,
998
+ runConfig: context.runConfig,
999
+ startRun: context.options?.startRun,
1000
+ metadata: {
1001
+ custom: { ...(current.quote ? { quote: current.quote } : {}) },
1002
+ },
1003
+ };
1004
+ const sent: ComposerSubmission = { ...current, attachments };
1005
+ // edit sends carry a sourceId contract; only thread sends queue
1006
+ const queued = queue && type === "thread";
1007
+ if (isSubmission) {
1008
+ submissionSend.current = undefined;
1009
+ setSubmission(undefined);
1010
+ }
1011
+ // An edit keeps its draft, whose copies of these attachments are the
1012
+ // delivered ones now, so clearing that draft must not remove their uploads.
1013
+ if (isSubmission && type !== "thread") {
1014
+ const delivered = new Map(
1015
+ attachments.map((attachment) => [attachment.id, attachment]),
1016
+ );
1017
+ setAttachments((prev) =>
1018
+ prev.map((attachment) => delivered.get(attachment.id) ?? attachment),
1019
+ );
1020
+ }
1021
+ // A queued message has its own place in the UI, so only a thread send
1022
+ // stays in transit until the host shows it.
1023
+ const entry: InTransitEntry | undefined =
1024
+ isSubmission && type === "thread" && !queued
1025
+ ? { submission: sent, known: new Set(messageKeysRef.current) }
1026
+ : undefined;
1027
+ if (entry) setInTransit((prev) => [...prev, entry]);
1028
+
1029
+ const failure = dispatchSafely(() => {
1030
+ if (queued) {
1031
+ if (context.options?.steer ?? isRunning) queue.steer(composedMessage);
1032
+ else queue.enqueue(composedMessage);
1033
+ } else {
1034
+ onSend?.(composedMessage);
1035
+ }
1036
+ });
1037
+ if (failure) {
1038
+ console.error("[assistant-ui] Failed to send the message", failure.error);
1039
+ if (entry)
1040
+ setInTransit((prev) => prev.filter((candidate) => candidate !== entry));
1041
+ returnToDraft(sent);
1042
+ return;
1043
+ }
1044
+ if (type === "edit") {
1045
+ attachmentAddOperations.cancelAll();
1046
+ setIsEditing(false);
1047
+ }
1048
+ };
1049
+
1050
+ const prepareSubmission = async (generation: number) => {
1051
+ const context = submissionSend.current;
1052
+ if (!context) return;
1053
+ const { signal } = context.controller;
1054
+ if (signal.aborted) return;
1055
+
1056
+ const uploads = (submissionRef.current?.attachments ?? []).flatMap(
1057
+ (attachment) => {
1058
+ const upload = attachmentAddOperations.whenSendable(attachment.id);
1059
+ return upload ? [upload] : [];
1060
+ },
1061
+ );
1062
+ if (uploads.length > 0) {
1063
+ // An attachment still uploading in `add()` cannot be finalized yet, so
1064
+ // the submission waits for its latest state.
1065
+ await Promise.all(uploads);
1066
+ if (generation !== sendGeneration.current || signal.aborted) return;
1067
+ }
1068
+
1069
+ const current = submissionRef.current;
1070
+ if (!current) return;
1071
+ const sent = current.attachments.filter(
1072
+ (attachment) => !attachmentSends.isRemoved(attachment),
1073
+ );
1074
+ for (const attachment of sent)
1075
+ attachmentAddOperations.cancel(attachment.id);
1076
+
1077
+ const settled = await Promise.allSettled(
1078
+ sent.map((attachment) =>
1079
+ attachmentSends.send(attachment, attachmentAdapter, signal),
1080
+ ),
1081
+ );
1082
+ if (generation !== sendGeneration.current || signal.aborted) return;
1083
+
1084
+ const rejection = settled.find((result) => result.status === "rejected");
1085
+ if (rejection) {
1086
+ returnSubmissionToDraft(sent, settled, rejection.reason);
1087
+ return;
1088
+ }
1089
+
1090
+ // An attachment removed mid-upload can't be cancelled, but it can still be
1091
+ // dropped from the outgoing message instead of silently being sent anyway.
1092
+ const finalAttachments = settled.flatMap((result, index) =>
1093
+ attachmentSends.isRemoved(sent[index]!) || result.status === "rejected"
1094
+ ? []
1095
+ : [result.value],
1096
+ );
1097
+ dispatchMessage(
1098
+ submissionRef.current ?? current,
1099
+ finalAttachments,
1100
+ context,
1101
+ true,
1102
+ );
1103
+ };
1104
+
648
1105
  return {
649
1106
  getState: () => state,
650
1107
  setText,
@@ -669,7 +1126,7 @@ const useComposerClientResource = ({
669
1126
  await drainAttachmentAdd(
670
1127
  attachmentAdapter.add({ file: fileOrAttachment }),
671
1128
  (attachment) => {
672
- if (!attachmentAddOperations.accept(operation, attachment.id))
1129
+ if (!attachmentAddOperations.accept(operation, attachment))
673
1130
  return false;
674
1131
  upsertAttachment(attachment);
675
1132
  return true;
@@ -706,94 +1163,98 @@ const useComposerClientResource = ({
706
1163
  clearAttachments: async () => {
707
1164
  attachmentAddOperations.cancelAll();
708
1165
  const removed = attachmentsRef.current;
1166
+ if (submissionRef.current) {
1167
+ for (const attachment of removed)
1168
+ attachmentSends.markRemoved(attachment);
1169
+ }
709
1170
  setAttachments([]);
710
1171
  await removePendingAttachments(removed);
711
1172
  },
712
1173
  attachment: (selector) => {
713
1174
  if ("id" in selector) {
1175
+ const submitted = submission?.attachments.some(
1176
+ (attachment) => attachment.id === selector.id,
1177
+ );
1178
+ const inDraft = attachments.some(
1179
+ (attachment) => attachment.id === selector.id,
1180
+ );
1181
+ if (submitted && !inDraft)
1182
+ return submittedAttachmentClients.get({ key: selector.id });
714
1183
  return attachmentClients.get({ key: selector.id });
715
1184
  }
716
1185
  return attachmentClients.get(selector);
717
1186
  },
718
1187
  reset: async () => {
719
1188
  attachmentAddOperations.cancelAll();
1189
+ sendGeneration.current++;
1190
+ const discarded = discardSubmission();
720
1191
  const removed = attachmentsRef.current;
721
1192
  setText("");
722
1193
  setRole("user");
723
1194
  setRunConfig({});
724
1195
  setAttachments([]);
725
1196
  setQuote(undefined);
726
- await removePendingAttachments(removed);
1197
+ await Promise.all([removePendingAttachments(removed), discarded]);
727
1198
  },
728
1199
  send: (opts?: ComposerSendOptions) => {
729
- const currentQuote = quoteRef.current;
730
- const currentText = textRef.current;
731
- const currentRole = roleRef.current;
732
- const currentRunConfig = runConfigRef.current;
733
- const currentAttachments = attachmentsRef.current;
734
- const isEmpty = !currentText.trim() && !currentAttachments.length;
1200
+ // An attachment whose removal is still awaiting the adapter is excluded
1201
+ // up front, or a send started mid-removal would upload and dispatch it.
1202
+ const currentAttachments = attachmentsRef.current.filter(
1203
+ (attachment) => !attachmentSends.isRemoved(attachment),
1204
+ );
1205
+ const isEmpty = !textRef.current.trim() && !currentAttachments.length;
735
1206
  if (!isEditingRef.current) throw new Error("Composer is not available");
736
- if (isEmpty || isSendDisabled) return;
737
-
738
- attachmentAddOperations.cancelAll();
739
- setText("");
740
- setAttachments([]);
741
- setQuote(undefined);
742
-
743
- const dispatch = (sendAttachments: readonly Attachment[]) => {
744
- const composedMessage: AppendMessage = {
745
- role: currentRole,
746
- content: currentText
747
- ? [{ type: "text" as const, text: currentText }]
748
- : [],
749
- attachments: sendAttachments as any,
750
- createdAt: new Date(),
751
- parentId: null,
752
- sourceId: null,
753
- runConfig: currentRunConfig,
754
- startRun: opts?.startRun,
755
- metadata: {
756
- custom: { ...(currentQuote ? { quote: currentQuote } : {}) },
757
- },
758
- };
759
- // edit sends carry a sourceId contract; only thread sends queue
760
- if (queue && type === "thread") {
761
- if (opts?.steer ?? isRunning) queue.steer(composedMessage);
762
- else queue.enqueue(composedMessage);
763
- } else {
764
- onSend?.(composedMessage);
765
- }
766
- if (type === "edit") setIsEditing(false);
1207
+ if (isEmpty || isSendDisabled || submissionRef.current) return;
1208
+
1209
+ const submitted: ComposerSubmission = {
1210
+ id: generateId(),
1211
+ role: roleRef.current,
1212
+ text: textRef.current,
1213
+ quote: quoteRef.current,
1214
+ attachments: currentAttachments,
767
1215
  };
768
-
769
- if (attachmentAdapter && currentAttachments.length > 0) {
770
- void Promise.all(
771
- currentAttachments.map((attachment) =>
772
- attachment.status.type === "complete"
773
- ? attachment
774
- : attachmentAdapter.send(attachment as PendingAttachment),
775
- ),
776
- ).then(dispatch, (error) => {
777
- // Upload failed: merge the failed send back into the draft.
778
- setText((prev) =>
779
- currentText && prev
780
- ? currentText + "\n" + prev
781
- : currentText || prev,
782
- );
783
- setQuote((prev) => prev ?? currentQuote);
784
- setAttachments((prev) => [...currentAttachments, ...prev]);
785
- console.error("Failed to send attachments", error);
786
- });
787
- } else {
788
- dispatch(currentAttachments);
1216
+ const context = { options: opts, runConfig: runConfigRef.current };
1217
+ // Only a send whose attachments still need the adapter becomes a
1218
+ // submission; one with nothing left to prepare goes out right away, as
1219
+ // it always has, and never shows up as a row of its own.
1220
+ const complete = currentAttachments.filter(isAttachmentComplete);
1221
+ const ready = complete.length === currentAttachments.length;
1222
+ const controller = ready ? undefined : new AbortController();
1223
+ if (controller) {
1224
+ submissionSend.current = { ...context, controller };
1225
+ setSubmission(submitted);
1226
+ }
1227
+ if (type === "thread") {
1228
+ const detached = new Set(currentAttachments);
1229
+ setAttachments((prev) =>
1230
+ prev.filter((attachment) => !detached.has(attachment)),
1231
+ );
1232
+ setText("");
1233
+ setQuote(undefined);
789
1234
  }
1235
+ const generation = ++sendGeneration.current;
1236
+ if (!controller) {
1237
+ dispatchMessage(submitted, complete, context, false);
1238
+ return;
1239
+ }
1240
+ const release = abortOnDestroy(destroySignal, controller);
1241
+ void prepareSubmission(generation).finally(release);
790
1242
  },
791
1243
  cancel: () => {
1244
+ // Stopping takes a send still being prepared back into the draft and
1245
+ // still stops a run that is going, so the one control never loses either.
1246
+ if (type === "thread" && submissionRef.current) {
1247
+ cancelSubmission();
1248
+ if (canCancel) onCancel?.();
1249
+ return;
1250
+ }
792
1251
  // An edit session ends here, so its in-flight adapter adds must not
793
1252
  // land in a later session; the thread composer's cancel stops the run
794
1253
  // and leaves the draft (and its pending adds) alone.
795
1254
  if (type === "edit") {
796
1255
  attachmentAddOperations.cancelAll();
1256
+ sendGeneration.current++;
1257
+ void discardSubmission();
797
1258
  const removed = attachmentsRef.current;
798
1259
  setAttachments([]);
799
1260
  removePendingAttachments(removed).catch((error) => {
@@ -917,6 +1378,7 @@ const useExternalThread = ({
917
1378
  onRefetchThread,
918
1379
  onAddToolResult,
919
1380
  onResumeToolCall,
1381
+ unstable_onRecordToolInteraction,
920
1382
  onLoadExternalState,
921
1383
  attachmentAdapter,
922
1384
  feedbackAdapter,
@@ -1023,36 +1485,9 @@ const useExternalThread = ({
1023
1485
  onReload?.(parentId);
1024
1486
  };
1025
1487
 
1026
- const messageClients = useClientLookup(
1027
- messages.map((msg, index) => {
1028
- const props: MessageClientProps = {
1029
- message: msg,
1030
- index,
1031
- parentId: index > 0 ? messages[index - 1]!.id : null,
1032
- onReload: () => handleReload(msg.id),
1033
- queue,
1034
- branches,
1035
- onRespondToToolApproval,
1036
- onAddToolResult,
1037
- onResumeToolCall,
1038
- attachmentAdapter,
1039
- submittedFeedback: feedbackFor(msg),
1040
- onSubmitFeedback: (feedback) => handleSubmitFeedback(msg, feedback),
1041
- speech: speech?.messageId === msg.id ? speech : undefined,
1042
- onSpeak: () => handleSpeak(msg),
1043
- onStopSpeaking: () => speechController.stopMessage(msg.id),
1044
- };
1045
- if (onEdit) props.onEdit = onEdit;
1046
- return withKey(msg.id, MessageClient(props));
1047
- }),
1048
- );
1049
-
1050
- const taskDeriver = useMemo(() => createTaskDeriver(), []);
1051
- const tasks = useMemo(() => taskDeriver(messages), [taskDeriver, messages]);
1052
- const taskClients = useClientLookup(
1053
- tasks.map((task) =>
1054
- withKey(getTaskKey(task), TaskClient({ task }), [task]),
1055
- ),
1488
+ const messageKeys = useMemo(
1489
+ () => messages.map((message) => `${message.id}|${message.role}`),
1490
+ [messages],
1056
1491
  );
1057
1492
 
1058
1493
  const handleCancelRun = () => {
@@ -1098,8 +1533,71 @@ const useExternalThread = ({
1098
1533
  onSend: handleSendNew,
1099
1534
  queue: composerQueue,
1100
1535
  attachmentAdapter,
1536
+ messageKeys,
1537
+ }),
1538
+ );
1539
+ const submission = composerClient.state.submission;
1540
+ const inTransit = composerClient.state.inTransit;
1541
+ // Messages the composer sent that the host does not show yet render after
1542
+ // the thread's own, oldest first, so a send never leaves the conversation.
1543
+ const pending = useMemo(
1544
+ () => [...(inTransit ?? []), ...(submission ? [submission] : [])],
1545
+ [inTransit, submission],
1546
+ );
1547
+ const hasPending = pending.length > 0;
1548
+ const messageClients = useClientLookup(
1549
+ messages.map((msg, index) => {
1550
+ const props: MessageClientProps = {
1551
+ message: msg,
1552
+ index,
1553
+ isLast: index === messages.length - 1 && !hasPending,
1554
+ parentId: index > 0 ? messages[index - 1]!.id : null,
1555
+ onReload: () => handleReload(msg.id),
1556
+ queue,
1557
+ branches,
1558
+ onRespondToToolApproval,
1559
+ unstable_onRecordToolInteraction,
1560
+ onAddToolResult,
1561
+ onResumeToolCall,
1562
+ attachmentAdapter,
1563
+ submittedFeedback: feedbackFor(msg),
1564
+ onSubmitFeedback: (feedback) => handleSubmitFeedback(msg, feedback),
1565
+ speech: speech?.messageId === msg.id ? speech : undefined,
1566
+ onSpeak: () => handleSpeak(msg),
1567
+ onStopSpeaking: () => speechController.stopMessage(msg.id),
1568
+ };
1569
+ if (onEdit) props.onEdit = onEdit;
1570
+ return withKey(msg.id, MessageClient(props));
1101
1571
  }),
1102
1572
  );
1573
+
1574
+ const pendingMessages = useMemo(
1575
+ () => pending.map(submissionThreadMessage),
1576
+ [pending],
1577
+ );
1578
+ const pendingClients = useClientLookup(
1579
+ pending.map((row, index) =>
1580
+ withKey(
1581
+ row.id,
1582
+ ThreadMessageClient({
1583
+ message: pendingMessages[index]!,
1584
+ submission: row,
1585
+ index: messages.length + index,
1586
+ isLast: index === pending.length - 1,
1587
+ }),
1588
+ [pendingMessages[index], row, messages.length, index, pending.length],
1589
+ ),
1590
+ ),
1591
+ );
1592
+
1593
+ const taskDeriver = useMemo(() => createTaskDeriver(), []);
1594
+ const tasks = useMemo(() => taskDeriver(messages), [taskDeriver, messages]);
1595
+ const taskClients = useClientLookup(
1596
+ tasks.map((task) =>
1597
+ withKey(getTaskKey(task), TaskClient({ task }), [task]),
1598
+ ),
1599
+ );
1600
+
1103
1601
  const suggestionsClient = useClientResource(
1104
1602
  ThreadSuggestions(EMPTY_SUGGESTIONS),
1105
1603
  );
@@ -1112,13 +1610,13 @@ const useExternalThread = ({
1112
1610
  const hasFeedback = !!feedbackAdapter;
1113
1611
  const hasSpeech = !!speechAdapter;
1114
1612
  const state = useMemo(() => {
1115
- const messageStates = messageClients.state.map((s, idx, arr) => ({
1116
- ...s,
1117
- isLast: idx === arr.length - 1,
1118
- }));
1613
+ const messageStates =
1614
+ pendingClients.state.length === 0
1615
+ ? messageClients.state
1616
+ : [...messageClients.state, ...pendingClients.state];
1119
1617
 
1120
1618
  return {
1121
- isEmpty: messages.length === 0 && !isLoading,
1619
+ isEmpty: messageStates.length === 0 && !isLoading,
1122
1620
  isDisabled: false,
1123
1621
  isLoading,
1124
1622
  isRunning,
@@ -1148,7 +1646,6 @@ const useExternalThread = ({
1148
1646
  composer: composerClient.state,
1149
1647
  };
1150
1648
  }, [
1151
- messages,
1152
1649
  isRunning,
1153
1650
  isLoading,
1154
1651
  threadState,
@@ -1164,6 +1661,7 @@ const useExternalThread = ({
1164
1661
  hasSpeech,
1165
1662
  speech,
1166
1663
  messageClients.state,
1664
+ pendingClients.state,
1167
1665
  composerClient.state,
1168
1666
  tasks,
1169
1667
  ]);
@@ -1238,8 +1736,14 @@ const useExternalThread = ({
1238
1736
  reset: () => {},
1239
1737
  message: (selector) => {
1240
1738
  if ("id" in selector) {
1739
+ if (pending.some((row) => row.id === selector.id))
1740
+ return pendingClients.get({ key: selector.id });
1241
1741
  return messageClients.get({ key: selector.id });
1242
1742
  }
1743
+ if (selector.index >= messageClients.state.length)
1744
+ return pendingClients.get({
1745
+ index: selector.index - messageClients.state.length,
1746
+ });
1243
1747
  return messageClients.get(selector);
1244
1748
  },
1245
1749
  stopSpeaking: speechController.stop,