@assistant-ui/core 0.3.19 → 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 (934) hide show
  1. package/dist/adapters/attachment.d.ts +50 -43
  2. package/dist/adapters/attachment.d.ts.map +1 -1
  3. package/dist/adapters/attachment.js +52 -21
  4. package/dist/adapters/attachment.js.map +1 -1
  5. package/dist/adapters/directive-formatter.d.ts +2 -5
  6. package/dist/adapters/directive-formatter.d.ts.map +1 -1
  7. package/dist/adapters/feedback.d.ts +7 -8
  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 +63 -65
  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 +19 -22
  17. package/dist/adapters/suggestion.d.ts.map +1 -1
  18. package/dist/adapters/thread-history.d.ts +60 -58
  19. package/dist/adapters/thread-history.d.ts.map +1 -1
  20. package/dist/adapters/trigger.d.ts +8 -11
  21. package/dist/adapters/trigger.d.ts.map +1 -1
  22. package/dist/adapters/voice.d.ts +50 -45
  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 +1 -4
  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 +20 -23
  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 +28 -30
  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 +24 -27
  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 +51 -39
  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 +9 -12
  54. package/dist/model-context/registry-handles.d.ts.map +1 -1
  55. package/dist/model-context/registry.d.ts +15 -18
  56. package/dist/model-context/registry.d.ts.map +1 -1
  57. package/dist/model-context/tool-call-text.d.ts +15 -17
  58. package/dist/model-context/tool-call-text.d.ts.map +1 -1
  59. package/dist/model-context/tool.d.ts +12 -14
  60. package/dist/model-context/tool.d.ts.map +1 -1
  61. package/dist/model-context/types.d.ts +40 -43
  62. package/dist/model-context/types.d.ts.map +1 -1
  63. package/dist/react/AssistantProvider.d.ts +9 -12
  64. package/dist/react/AssistantProvider.d.ts.map +1 -1
  65. package/dist/react/AssistantRuntimeProvider.d.ts +23 -26
  66. package/dist/react/AssistantRuntimeProvider.d.ts.map +1 -1
  67. package/dist/react/RuntimeAdapter.d.ts +4 -8
  68. package/dist/react/RuntimeAdapter.d.ts.map +1 -1
  69. package/dist/react/adapters/LocalStorageThreadListAdapter.d.ts +28 -23
  70. package/dist/react/adapters/LocalStorageThreadListAdapter.d.ts.map +1 -1
  71. package/dist/react/adapters/LocalStorageThreadListAdapter.js +77 -58
  72. package/dist/react/adapters/LocalStorageThreadListAdapter.js.map +1 -1
  73. package/dist/react/adapters/TitleGenerationAdapter.d.ts +4 -7
  74. package/dist/react/adapters/TitleGenerationAdapter.d.ts.map +1 -1
  75. package/dist/react/client/AdaptedRemoteThread.d.ts +6 -9
  76. package/dist/react/client/AdaptedRemoteThread.d.ts.map +1 -1
  77. package/dist/react/client/DataRenderers.d.ts +2 -5
  78. package/dist/react/client/DataRenderers.d.ts.map +1 -1
  79. package/dist/react/client/InMemoryThreadList.d.ts +9 -12
  80. package/dist/react/client/InMemoryThreadList.d.ts.map +1 -1
  81. package/dist/react/client/Interactables.d.ts +3 -6
  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 +34 -37
  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 +10 -12
  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 -11
  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 +2 -5
  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 -9
  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 +42 -46
  109. package/dist/react/interactables-legacy/scopes.d.ts.map +1 -1
  110. package/dist/react/interactables-legacy/useAssistantInteractable.d.ts +8 -11
  111. package/dist/react/interactables-legacy/useAssistantInteractable.d.ts.map +1 -1
  112. package/dist/react/interactables-legacy/useInteractableState.d.ts +7 -9
  113. package/dist/react/interactables-legacy/useInteractableState.d.ts.map +1 -1
  114. package/dist/react/interactables-shared/useInteractablePersistenceQueue.d.ts +23 -14
  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 +15 -18
  119. package/dist/react/model-context/define-mcp-toolkit.d.ts.map +1 -1
  120. package/dist/react/model-context/define-toolkit.d.ts +13 -6
  121. package/dist/react/model-context/define-toolkit.d.ts.map +1 -1
  122. package/dist/react/model-context/external-tool.d.ts +1 -4
  123. package/dist/react/model-context/external-tool.d.ts.map +1 -1
  124. package/dist/react/model-context/human-tool.d.ts +3 -6
  125. package/dist/react/model-context/human-tool.d.ts.map +1 -1
  126. package/dist/react/model-context/interactableTool.d.ts +26 -29
  127. package/dist/react/model-context/interactableTool.d.ts.map +1 -1
  128. package/dist/react/model-context/makeAssistantDataUI.d.ts +6 -9
  129. package/dist/react/model-context/makeAssistantDataUI.d.ts.map +1 -1
  130. package/dist/react/model-context/makeAssistantTool.d.ts +6 -9
  131. package/dist/react/model-context/makeAssistantTool.d.ts.map +1 -1
  132. package/dist/react/model-context/makeAssistantToolUI.d.ts +6 -9
  133. package/dist/react/model-context/makeAssistantToolUI.d.ts.map +1 -1
  134. package/dist/react/model-context/provider-tool.d.ts +5 -7
  135. package/dist/react/model-context/provider-tool.d.ts.map +1 -1
  136. package/dist/react/model-context/stub-tool.d.ts +1 -4
  137. package/dist/react/model-context/stub-tool.d.ts.map +1 -1
  138. package/dist/react/model-context/toolbox.d.ts +44 -32
  139. package/dist/react/model-context/toolbox.d.ts.map +1 -1
  140. package/dist/react/model-context/useAssistantContext.d.ts +3 -6
  141. package/dist/react/model-context/useAssistantContext.d.ts.map +1 -1
  142. package/dist/react/model-context/useAssistantDataUI.d.ts +7 -10
  143. package/dist/react/model-context/useAssistantDataUI.d.ts.map +1 -1
  144. package/dist/react/model-context/useAssistantInstructions.d.ts +3 -6
  145. package/dist/react/model-context/useAssistantInstructions.d.ts.map +1 -1
  146. package/dist/react/model-context/useAssistantTool.d.ts +9 -13
  147. package/dist/react/model-context/useAssistantTool.d.ts.map +1 -1
  148. package/dist/react/model-context/useAssistantToolUI.d.ts +13 -16
  149. package/dist/react/model-context/useAssistantToolUI.d.ts.map +1 -1
  150. package/dist/react/model-context/useAuiToolOverrides.d.ts +3 -5
  151. package/dist/react/model-context/useAuiToolOverrides.d.ts.map +1 -1
  152. package/dist/react/model-context/useInlineRender.d.ts +3 -6
  153. package/dist/react/model-context/useInlineRender.d.ts.map +1 -1
  154. package/dist/react/model-context/useInteractable.d.ts +40 -40
  155. package/dist/react/model-context/useInteractable.d.ts.map +1 -1
  156. package/dist/react/model-context/useInteractableState.d.ts +10 -9
  157. package/dist/react/model-context/useInteractableState.d.ts.map +1 -1
  158. package/dist/react/model-context/useInteractableVersions.d.ts +4 -7
  159. package/dist/react/model-context/useInteractableVersions.d.ts.map +1 -1
  160. package/dist/react/model-context/useToolArgsStatus.d.ts +7 -9
  161. package/dist/react/model-context/useToolArgsStatus.d.ts.map +1 -1
  162. package/dist/react/primitive-hooks/useActionBarCopy.d.ts +7 -10
  163. package/dist/react/primitive-hooks/useActionBarCopy.d.ts.map +1 -1
  164. package/dist/react/primitive-hooks/useActionBarEdit.d.ts +3 -6
  165. package/dist/react/primitive-hooks/useActionBarEdit.d.ts.map +1 -1
  166. package/dist/react/primitive-hooks/useActionBarFeedback.d.ts +6 -9
  167. package/dist/react/primitive-hooks/useActionBarFeedback.d.ts.map +1 -1
  168. package/dist/react/primitive-hooks/useActionBarReload.d.ts +3 -6
  169. package/dist/react/primitive-hooks/useActionBarReload.d.ts.map +1 -1
  170. package/dist/react/primitive-hooks/useActionBarSpeak.d.ts +3 -6
  171. package/dist/react/primitive-hooks/useActionBarSpeak.d.ts.map +1 -1
  172. package/dist/react/primitive-hooks/useActionBarStopSpeaking.d.ts +3 -6
  173. package/dist/react/primitive-hooks/useActionBarStopSpeaking.d.ts.map +1 -1
  174. package/dist/react/primitive-hooks/useBranchPickerNext.d.ts +3 -6
  175. package/dist/react/primitive-hooks/useBranchPickerNext.d.ts.map +1 -1
  176. package/dist/react/primitive-hooks/useBranchPickerPrevious.d.ts +3 -6
  177. package/dist/react/primitive-hooks/useBranchPickerPrevious.d.ts.map +1 -1
  178. package/dist/react/primitive-hooks/useComposerAddAttachment.d.ts +4 -7
  179. package/dist/react/primitive-hooks/useComposerAddAttachment.d.ts.map +1 -1
  180. package/dist/react/primitive-hooks/useComposerCancel.d.ts +3 -6
  181. package/dist/react/primitive-hooks/useComposerCancel.d.ts.map +1 -1
  182. package/dist/react/primitive-hooks/useComposerDictate.d.ts +3 -6
  183. package/dist/react/primitive-hooks/useComposerDictate.d.ts.map +1 -1
  184. package/dist/react/primitive-hooks/useComposerSend.d.ts +4 -7
  185. package/dist/react/primitive-hooks/useComposerSend.d.ts.map +1 -1
  186. package/dist/react/primitive-hooks/useEditComposerCancel.d.ts +2 -5
  187. package/dist/react/primitive-hooks/useEditComposerCancel.d.ts.map +1 -1
  188. package/dist/react/primitive-hooks/useEditComposerSend.d.ts +3 -6
  189. package/dist/react/primitive-hooks/useEditComposerSend.d.ts.map +1 -1
  190. package/dist/react/primitive-hooks/useMessageBranching.d.ts +5 -8
  191. package/dist/react/primitive-hooks/useMessageBranching.d.ts.map +1 -1
  192. package/dist/react/primitive-hooks/useMessageError.d.ts +1 -4
  193. package/dist/react/primitive-hooks/useMessageError.d.ts.map +1 -1
  194. package/dist/react/primitive-hooks/useMessageReload.d.ts +3 -6
  195. package/dist/react/primitive-hooks/useMessageReload.d.ts.map +1 -1
  196. package/dist/react/primitive-hooks/useSuggestionTrigger.d.ts +7 -10
  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 +1 -4
  201. package/dist/react/primitive-hooks/useThreadIsEmpty.d.ts.map +1 -1
  202. package/dist/react/primitive-hooks/useThreadIsRunning.d.ts +1 -4
  203. package/dist/react/primitive-hooks/useThreadIsRunning.d.ts.map +1 -1
  204. package/dist/react/primitive-hooks/useThreadListItemArchive.d.ts +2 -5
  205. package/dist/react/primitive-hooks/useThreadListItemArchive.d.ts.map +1 -1
  206. package/dist/react/primitive-hooks/useThreadListItemDelete.d.ts +2 -5
  207. package/dist/react/primitive-hooks/useThreadListItemDelete.d.ts.map +1 -1
  208. package/dist/react/primitive-hooks/useThreadListItemTrigger.d.ts +2 -5
  209. package/dist/react/primitive-hooks/useThreadListItemTrigger.d.ts.map +1 -1
  210. package/dist/react/primitive-hooks/useThreadListItemUnarchive.d.ts +2 -5
  211. package/dist/react/primitive-hooks/useThreadListItemUnarchive.d.ts.map +1 -1
  212. package/dist/react/primitive-hooks/useThreadListLoadMore.d.ts +3 -6
  213. package/dist/react/primitive-hooks/useThreadListLoadMore.d.ts.map +1 -1
  214. package/dist/react/primitive-hooks/useThreadListNew.d.ts +2 -5
  215. package/dist/react/primitive-hooks/useThreadListNew.d.ts.map +1 -1
  216. package/dist/react/primitive-hooks/useThreadMessageIds.d.ts +1 -4
  217. package/dist/react/primitive-hooks/useThreadMessageIds.d.ts.map +1 -1
  218. package/dist/react/primitive-hooks/useThreadMessages.d.ts +2 -5
  219. package/dist/react/primitive-hooks/useThreadMessages.d.ts.map +1 -1
  220. package/dist/react/primitive-hooks/useVoice.d.ts +8 -11
  221. package/dist/react/primitive-hooks/useVoice.d.ts.map +1 -1
  222. package/dist/react/primitives/chainOfThought/ChainOfThoughtParts.d.ts +27 -29
  223. package/dist/react/primitives/chainOfThought/ChainOfThoughtParts.d.ts.map +1 -1
  224. package/dist/react/primitives/composer/ComposerAttachments.d.ts +26 -28
  225. package/dist/react/primitives/composer/ComposerAttachments.d.ts.map +1 -1
  226. package/dist/react/primitives/composer/ComposerIf.d.ts +13 -13
  227. package/dist/react/primitives/composer/ComposerIf.d.ts.map +1 -1
  228. package/dist/react/primitives/composer/ComposerQueue.d.ts +13 -17
  229. package/dist/react/primitives/composer/ComposerQueue.d.ts.map +1 -1
  230. package/dist/react/primitives/generativeUI/GenerativeUI.d.ts +30 -33
  231. package/dist/react/primitives/generativeUI/GenerativeUI.d.ts.map +1 -1
  232. package/dist/react/primitives/generativeUI/GenerativeUI.js +42 -33
  233. package/dist/react/primitives/generativeUI/GenerativeUI.js.map +1 -1
  234. package/dist/react/primitives/message/MessageAttachments.d.ts +30 -28
  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 +122 -120
  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 +208 -194
  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 +8 -11
  247. package/dist/react/primitives/message/MessageQuote.d.ts.map +1 -1
  248. package/dist/react/primitives/messagePart/MessagePartInProgress.d.ts +4 -7
  249. package/dist/react/primitives/messagePart/MessagePartInProgress.d.ts.map +1 -1
  250. package/dist/react/primitives/part/PartMessages.d.ts +16 -19
  251. package/dist/react/primitives/part/PartMessages.d.ts.map +1 -1
  252. package/dist/react/primitives/thread/ThreadMessages.d.ts +61 -64
  253. package/dist/react/primitives/thread/ThreadMessages.d.ts.map +1 -1
  254. package/dist/react/primitives/thread/ThreadSuggestions.d.ts +25 -27
  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 +26 -28
  259. package/dist/react/primitives/threadList/ThreadListItems.d.ts.map +1 -1
  260. package/dist/react/primitives/threadListItem/ThreadListItemTitle.d.ts +6 -9
  261. package/dist/react/primitives/threadListItem/ThreadListItemTitle.d.ts.map +1 -1
  262. package/dist/react/providers/AttachmentByIndexProvider.d.ts +5 -8
  263. package/dist/react/providers/AttachmentByIndexProvider.d.ts.map +1 -1
  264. package/dist/react/providers/ChainOfThoughtByIndicesProvider.d.ts +4 -7
  265. package/dist/react/providers/ChainOfThoughtByIndicesProvider.d.ts.map +1 -1
  266. package/dist/react/providers/ChainOfThoughtPartByIndexProvider.d.ts +3 -6
  267. package/dist/react/providers/ChainOfThoughtPartByIndexProvider.d.ts.map +1 -1
  268. package/dist/react/providers/MessageByIdProvider.d.ts +3 -6
  269. package/dist/react/providers/MessageByIdProvider.d.ts.map +1 -1
  270. package/dist/react/providers/MessageByIndexProvider.d.ts +3 -6
  271. package/dist/react/providers/MessageByIndexProvider.d.ts.map +1 -1
  272. package/dist/react/providers/PartByIndexProvider.d.ts +3 -6
  273. package/dist/react/providers/PartByIndexProvider.d.ts.map +1 -1
  274. package/dist/react/providers/QueueItemByIndexProvider.d.ts +4 -7
  275. package/dist/react/providers/QueueItemByIndexProvider.d.ts.map +1 -1
  276. package/dist/react/providers/ReadonlyThreadProvider.d.ts +7 -10
  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 +4 -7
  280. package/dist/react/providers/SuggestionByIndexProvider.d.ts.map +1 -1
  281. package/dist/react/providers/TextMessagePartProvider.d.ts +4 -7
  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 +4 -7
  286. package/dist/react/providers/ThreadListItemByIndexProvider.d.ts.map +1 -1
  287. package/dist/react/providers/ThreadListItemRuntimeProvider.d.ts +4 -8
  288. package/dist/react/providers/ThreadListItemRuntimeProvider.d.ts.map +1 -1
  289. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.d.ts +210 -219
  290. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.d.ts.map +1 -1
  291. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js +70 -46
  292. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js.map +1 -1
  293. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts +186 -198
  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 +17 -23
  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 +10 -11
  302. package/dist/react/runtimes/RuntimeAdapterProvider.d.ts.map +1 -1
  303. package/dist/react/runtimes/assistant-transport/commandQueue.d.ts +11 -14
  304. package/dist/react/runtimes/assistant-transport/commandQueue.d.ts.map +1 -1
  305. package/dist/react/runtimes/assistant-transport/replayBoundaryStream.d.ts +6 -8
  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 +9 -12
  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 +123 -118
  314. package/dist/react/runtimes/assistant-transport/types.d.ts.map +1 -1
  315. package/dist/react/runtimes/assistant-transport/useAssistantTransportRuntime.d.ts +7 -10
  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 +3 -6
  320. package/dist/react/runtimes/assistant-transport/useConvertedState.d.ts.map +1 -1
  321. package/dist/react/runtimes/assistant-transport/useLatestRef.d.ts +2 -5
  322. package/dist/react/runtimes/assistant-transport/useLatestRef.d.ts.map +1 -1
  323. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.d.ts +7 -10
  324. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.d.ts.map +1 -1
  325. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.js +426 -216
  326. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.js.map +1 -1
  327. package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.d.ts +15 -18
  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 +146 -125
  332. package/dist/react/runtimes/cloud/auiV0.d.ts.map +1 -1
  333. package/dist/react/runtimes/cloud/auiV0.js +120 -8
  334. package/dist/react/runtimes/cloud/auiV0.js.map +1 -1
  335. package/dist/react/runtimes/cloud/createCloudThreadListAdapter.d.ts +13 -15
  336. package/dist/react/runtimes/cloud/createCloudThreadListAdapter.d.ts.map +1 -1
  337. package/dist/react/runtimes/cloud/createCloudThreadListAdapterCreateFallback.d.ts +5 -7
  338. package/dist/react/runtimes/cloud/createCloudThreadListAdapterCreateFallback.d.ts.map +1 -1
  339. package/dist/react/runtimes/cloud/sdkIdentity.d.ts +2 -5
  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 +3 -6
  343. package/dist/react/runtimes/cloud/useCloudThreadListAdapter.d.ts.map +1 -1
  344. package/dist/react/runtimes/cloud/useCloudThreadListRuntime.d.ts +9 -11
  345. package/dist/react/runtimes/cloud/useCloudThreadListRuntime.d.ts.map +1 -1
  346. package/dist/react/runtimes/createMessageConverter.d.ts +15 -19
  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 +14 -17
  350. package/dist/react/runtimes/createRuntimeExtras.d.ts.map +1 -1
  351. package/dist/react/runtimes/external-message-converter.d.ts +17 -21
  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 +3 -6
  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 +2 -5
  362. package/dist/react/runtimes/useExternalStoreSharedOptions.d.ts.map +1 -1
  363. package/dist/react/runtimes/useLocalRuntime.d.ts +29 -41
  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 +3 -6
  368. package/dist/react/runtimes/useRemoteThreadListRuntime.d.ts.map +1 -1
  369. package/dist/react/runtimes/useRemoteThreadListRuntime.js +2 -2
  370. package/dist/react/runtimes/useRemoteThreadListRuntime.js.map +1 -1
  371. package/dist/react/runtimes/useRuntimeAdapters.d.ts +5 -7
  372. package/dist/react/runtimes/useRuntimeAdapters.d.ts.map +1 -1
  373. package/dist/react/runtimes/useStreamingTiming.d.ts +4 -6
  374. package/dist/react/runtimes/useStreamingTiming.d.ts.map +1 -1
  375. package/dist/react/types/MessagePartComponentTypes.d.ts +72 -70
  376. package/dist/react/types/MessagePartComponentTypes.d.ts.map +1 -1
  377. package/dist/react/types/scopes/dataRenderers.d.ts +11 -15
  378. package/dist/react/types/scopes/dataRenderers.d.ts.map +1 -1
  379. package/dist/react/types/scopes/interactables.d.ts +60 -60
  380. package/dist/react/types/scopes/interactables.d.ts.map +1 -1
  381. package/dist/react/types/scopes/tools.d.ts +21 -24
  382. package/dist/react/types/scopes/tools.d.ts.map +1 -1
  383. package/dist/react/types/store-augmentation.d.ts +10 -11
  384. package/dist/react/types/store-augmentation.d.ts.map +1 -1
  385. package/dist/react/utils/getMessageQuote.d.ts +6 -8
  386. package/dist/react/utils/getMessageQuote.d.ts.map +1 -1
  387. package/dist/react/utils/groupParts.d.ts +35 -37
  388. package/dist/react/utils/groupParts.d.ts.map +1 -1
  389. package/dist/react/utils/useJSONEqual.d.ts +3 -6
  390. package/dist/react/utils/useJSONEqual.d.ts.map +1 -1
  391. package/dist/react/utils/useJSONSchemaDependency.d.ts +3 -6
  392. package/dist/react/utils/useJSONSchemaDependency.d.ts.map +1 -1
  393. package/dist/runtime/api/assistant-runtime.d.ts +28 -31
  394. package/dist/runtime/api/assistant-runtime.d.ts.map +1 -1
  395. package/dist/runtime/api/attachment-runtime.d.ts +51 -49
  396. package/dist/runtime/api/attachment-runtime.d.ts.map +1 -1
  397. package/dist/runtime/api/attachment-runtime.js.map +1 -1
  398. package/dist/runtime/api/bindings.d.ts +35 -35
  399. package/dist/runtime/api/bindings.d.ts.map +1 -1
  400. package/dist/runtime/api/composer-runtime.d.ts +215 -201
  401. package/dist/runtime/api/composer-runtime.d.ts.map +1 -1
  402. package/dist/runtime/api/composer-runtime.js +4 -0
  403. package/dist/runtime/api/composer-runtime.js.map +1 -1
  404. package/dist/runtime/api/message-part-runtime.d.ts +31 -30
  405. package/dist/runtime/api/message-part-runtime.d.ts.map +1 -1
  406. package/dist/runtime/api/message-part-runtime.js +25 -2
  407. package/dist/runtime/api/message-part-runtime.js.map +1 -1
  408. package/dist/runtime/api/message-runtime.d.ts +87 -82
  409. package/dist/runtime/api/message-runtime.d.ts.map +1 -1
  410. package/dist/runtime/api/message-runtime.js +4 -3
  411. package/dist/runtime/api/message-runtime.js.map +1 -1
  412. package/dist/runtime/api/paths.d.ts +54 -57
  413. package/dist/runtime/api/paths.d.ts.map +1 -1
  414. package/dist/runtime/api/thread-list-item-runtime.d.ts +70 -72
  415. package/dist/runtime/api/thread-list-item-runtime.d.ts.map +1 -1
  416. package/dist/runtime/api/thread-list-item-runtime.js.map +1 -1
  417. package/dist/runtime/api/thread-list-runtime.d.ts +77 -81
  418. package/dist/runtime/api/thread-list-runtime.d.ts.map +1 -1
  419. package/dist/runtime/api/thread-list-runtime.js.map +1 -1
  420. package/dist/runtime/api/thread-runtime.d.ts +306 -308
  421. package/dist/runtime/api/thread-runtime.d.ts.map +1 -1
  422. package/dist/runtime/api/thread-runtime.js +2 -1
  423. package/dist/runtime/api/thread-runtime.js.map +1 -1
  424. package/dist/runtime/base/base-assistant-runtime-core.d.ts +9 -12
  425. package/dist/runtime/base/base-assistant-runtime-core.d.ts.map +1 -1
  426. package/dist/runtime/base/base-composer-runtime-core.d.ts +150 -101
  427. package/dist/runtime/base/base-composer-runtime-core.d.ts.map +1 -1
  428. package/dist/runtime/base/base-composer-runtime-core.js +400 -122
  429. package/dist/runtime/base/base-composer-runtime-core.js.map +1 -1
  430. package/dist/runtime/base/base-thread-runtime-core.d.ts +121 -104
  431. package/dist/runtime/base/base-thread-runtime-core.d.ts.map +1 -1
  432. package/dist/runtime/base/base-thread-runtime-core.js +174 -62
  433. package/dist/runtime/base/base-thread-runtime-core.js.map +1 -1
  434. package/dist/runtime/base/default-edit-composer-runtime-core.d.ts +30 -31
  435. package/dist/runtime/base/default-edit-composer-runtime-core.d.ts.map +1 -1
  436. package/dist/runtime/base/default-edit-composer-runtime-core.js +21 -2
  437. package/dist/runtime/base/default-edit-composer-runtime-core.js.map +1 -1
  438. package/dist/runtime/base/default-thread-composer-runtime-core.d.ts +28 -31
  439. package/dist/runtime/base/default-thread-composer-runtime-core.d.ts.map +1 -1
  440. package/dist/runtime/base/default-thread-composer-runtime-core.js +23 -2
  441. package/dist/runtime/base/default-thread-composer-runtime-core.js.map +1 -1
  442. package/dist/runtime/branch/external-thread-branch-adapter.d.ts +15 -18
  443. package/dist/runtime/branch/external-thread-branch-adapter.d.ts.map +1 -1
  444. package/dist/runtime/interfaces/assistant-runtime-core.d.ts +8 -11
  445. package/dist/runtime/interfaces/assistant-runtime-core.d.ts.map +1 -1
  446. package/dist/runtime/interfaces/composer-runtime-core.d.ts +98 -83
  447. package/dist/runtime/interfaces/composer-runtime-core.d.ts.map +1 -1
  448. package/dist/runtime/interfaces/thread-list-runtime-core.d.ts +67 -70
  449. package/dist/runtime/interfaces/thread-list-runtime-core.d.ts.map +1 -1
  450. package/dist/runtime/interfaces/thread-runtime-core.d.ts +225 -211
  451. package/dist/runtime/interfaces/thread-runtime-core.d.ts.map +1 -1
  452. package/dist/runtime/internal.d.ts +25 -20
  453. package/dist/runtime/internal.d.ts.map +1 -0
  454. package/dist/runtime/queue/external-thread-queue-adapter.d.ts +37 -40
  455. package/dist/runtime/queue/external-thread-queue-adapter.d.ts.map +1 -1
  456. package/dist/runtime/queue/message-queue.d.ts +32 -33
  457. package/dist/runtime/queue/message-queue.d.ts.map +1 -1
  458. package/dist/runtime/queue/message-queue.js +10 -2
  459. package/dist/runtime/queue/message-queue.js.map +1 -1
  460. package/dist/runtime/queue/queue-item.d.ts +7 -10
  461. package/dist/runtime/queue/queue-item.d.ts.map +1 -1
  462. package/dist/runtime/utils/abortable-thread-load.d.ts +9 -11
  463. package/dist/runtime/utils/abortable-thread-load.d.ts.map +1 -1
  464. package/dist/runtime/utils/attachment-add-operations.d.ts +16 -15
  465. package/dist/runtime/utils/attachment-add-operations.d.ts.map +1 -1
  466. package/dist/runtime/utils/attachment-add-operations.js +24 -2
  467. package/dist/runtime/utils/attachment-add-operations.js.map +1 -1
  468. package/dist/runtime/utils/attachment-send-operations.d.ts +12 -0
  469. package/dist/runtime/utils/attachment-send-operations.d.ts.map +1 -0
  470. package/dist/runtime/utils/attachment-send-operations.js +34 -0
  471. package/dist/runtime/utils/attachment-send-operations.js.map +1 -0
  472. package/dist/runtime/utils/auto-status.d.ts +11 -13
  473. package/dist/runtime/utils/auto-status.d.ts.map +1 -1
  474. package/dist/runtime/utils/auto-status.js +3 -5
  475. package/dist/runtime/utils/auto-status.js.map +1 -1
  476. package/dist/runtime/utils/chat-model-adapter.d.ts +31 -33
  477. package/dist/runtime/utils/chat-model-adapter.d.ts.map +1 -1
  478. package/dist/runtime/utils/external-message-conversion.d.ts +47 -48
  479. package/dist/runtime/utils/external-message-conversion.d.ts.map +1 -1
  480. package/dist/runtime/utils/external-message-conversion.js +6 -5
  481. package/dist/runtime/utils/external-message-conversion.js.map +1 -1
  482. package/dist/runtime/utils/external-store-message.d.ts +6 -9
  483. package/dist/runtime/utils/external-store-message.d.ts.map +1 -1
  484. package/dist/runtime/utils/message-repository-session.d.ts +24 -27
  485. package/dist/runtime/utils/message-repository-session.d.ts.map +1 -1
  486. package/dist/runtime/utils/message-repository.d.ts +52 -54
  487. package/dist/runtime/utils/message-repository.d.ts.map +1 -1
  488. package/dist/runtime/utils/message-repository.js +8 -7
  489. package/dist/runtime/utils/message-repository.js.map +1 -1
  490. package/dist/runtime/utils/pending-tool-calls.d.ts +12 -14
  491. package/dist/runtime/utils/pending-tool-calls.d.ts.map +1 -1
  492. package/dist/runtime/utils/resolveToolApprovalResponse.d.ts +7 -10
  493. package/dist/runtime/utils/resolveToolApprovalResponse.d.ts.map +1 -1
  494. package/dist/runtime/utils/runtime-extras-brand.d.ts +6 -9
  495. package/dist/runtime/utils/runtime-extras-brand.d.ts.map +1 -1
  496. package/dist/runtime/utils/stored-message-parts.d.ts +21 -0
  497. package/dist/runtime/utils/stored-message-parts.d.ts.map +1 -0
  498. package/dist/runtime/utils/stored-message-parts.js +103 -0
  499. package/dist/runtime/utils/stored-message-parts.js.map +1 -0
  500. package/dist/runtime/utils/streaming-timing.d.ts +23 -26
  501. package/dist/runtime/utils/streaming-timing.d.ts.map +1 -1
  502. package/dist/runtime/utils/thread-message-like.d.ts +38 -34
  503. package/dist/runtime/utils/thread-message-like.d.ts.map +1 -1
  504. package/dist/runtime/utils/thread-message-like.js +16 -6
  505. package/dist/runtime/utils/thread-message-like.js.map +1 -1
  506. package/dist/runtime/utils/thread-runtime-lifecycle.d.ts +5 -7
  507. package/dist/runtime/utils/thread-runtime-lifecycle.d.ts.map +1 -1
  508. package/dist/runtime/utils/thread-runtime-lifecycle.js +31 -4
  509. package/dist/runtime/utils/thread-runtime-lifecycle.js.map +1 -1
  510. package/dist/runtime/utils/tool-call-tree.d.ts +10 -13
  511. package/dist/runtime/utils/tool-call-tree.d.ts.map +1 -1
  512. package/dist/runtime/utils/tool-interactions.d.ts +10 -0
  513. package/dist/runtime/utils/tool-interactions.d.ts.map +1 -0
  514. package/dist/runtime/utils/tool-interactions.js +92 -0
  515. package/dist/runtime/utils/tool-interactions.js.map +1 -0
  516. package/dist/runtimes/assistant-transport/utils.d.ts +1 -4
  517. package/dist/runtimes/assistant-transport/utils.d.ts.map +1 -1
  518. package/dist/runtimes/external-store/external-store-adapter.d.ts +220 -200
  519. package/dist/runtimes/external-store/external-store-adapter.d.ts.map +1 -1
  520. package/dist/runtimes/external-store/external-store-runtime-core.d.ts +6 -8
  521. package/dist/runtimes/external-store/external-store-runtime-core.d.ts.map +1 -1
  522. package/dist/runtimes/external-store/external-store-runtime-core.js +4 -1
  523. package/dist/runtimes/external-store/external-store-runtime-core.js.map +1 -1
  524. package/dist/runtimes/external-store/external-store-shared-options.d.ts +3 -6
  525. package/dist/runtimes/external-store/external-store-shared-options.d.ts.map +1 -1
  526. package/dist/runtimes/external-store/external-store-thread-list-runtime-core.d.ts +40 -43
  527. package/dist/runtimes/external-store/external-store-thread-list-runtime-core.d.ts.map +1 -1
  528. package/dist/runtimes/external-store/external-store-thread-list-runtime-core.js +2 -2
  529. package/dist/runtimes/external-store/external-store-thread-list-runtime-core.js.map +1 -1
  530. package/dist/runtimes/external-store/external-store-thread-runtime-core.d.ts +119 -125
  531. package/dist/runtimes/external-store/external-store-thread-runtime-core.d.ts.map +1 -1
  532. package/dist/runtimes/external-store/external-store-thread-runtime-core.js +71 -18
  533. package/dist/runtimes/external-store/external-store-thread-runtime-core.js.map +1 -1
  534. package/dist/runtimes/external-store/thread-message-converter.d.ts +5 -8
  535. package/dist/runtimes/external-store/thread-message-converter.d.ts.map +1 -1
  536. package/dist/runtimes/inert/InertThreadRuntimeCore.d.ts +96 -98
  537. package/dist/runtimes/inert/InertThreadRuntimeCore.d.ts.map +1 -1
  538. package/dist/runtimes/inert/InertThreadRuntimeCore.js +3 -0
  539. package/dist/runtimes/inert/InertThreadRuntimeCore.js.map +1 -1
  540. package/dist/runtimes/internal.d.ts +20 -16
  541. package/dist/runtimes/internal.d.ts.map +1 -0
  542. package/dist/runtimes/local/local-runtime-core.d.ts +7 -10
  543. package/dist/runtimes/local/local-runtime-core.d.ts.map +1 -1
  544. package/dist/runtimes/local/local-runtime-options.d.ts +41 -44
  545. package/dist/runtimes/local/local-runtime-options.d.ts.map +1 -1
  546. package/dist/runtimes/local/local-thread-list-runtime-core.d.ts +42 -45
  547. package/dist/runtimes/local/local-thread-list-runtime-core.d.ts.map +1 -1
  548. package/dist/runtimes/local/local-thread-runtime-core.d.ts +94 -93
  549. package/dist/runtimes/local/local-thread-runtime-core.d.ts.map +1 -1
  550. package/dist/runtimes/local/local-thread-runtime-core.js +220 -29
  551. package/dist/runtimes/local/local-thread-runtime-core.js.map +1 -1
  552. package/dist/runtimes/local/should-continue.d.ts +2 -5
  553. package/dist/runtimes/local/should-continue.d.ts.map +1 -1
  554. package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.d.ts +77 -55
  555. package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.d.ts.map +1 -1
  556. package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.js +28 -1
  557. package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.js.map +1 -1
  558. package/dist/runtimes/remote-thread-list/adapter/in-memory.d.ts +12 -15
  559. package/dist/runtimes/remote-thread-list/adapter/in-memory.d.ts.map +1 -1
  560. package/dist/runtimes/remote-thread-list/adapter-changed.d.ts +3 -6
  561. package/dist/runtimes/remote-thread-list/adapter-changed.d.ts.map +1 -1
  562. package/dist/runtimes/remote-thread-list/empty-thread-core.d.ts +2 -5
  563. package/dist/runtimes/remote-thread-list/empty-thread-core.d.ts.map +1 -1
  564. package/dist/runtimes/remote-thread-list/optimistic-state.d.ts +34 -31
  565. package/dist/runtimes/remote-thread-list/optimistic-state.d.ts.map +1 -1
  566. package/dist/runtimes/remote-thread-list/optimistic-state.js +8 -3
  567. package/dist/runtimes/remote-thread-list/optimistic-state.js.map +1 -1
  568. package/dist/runtimes/remote-thread-list/remote-thread-state.d.ts +60 -63
  569. package/dist/runtimes/remote-thread-list/remote-thread-state.d.ts.map +1 -1
  570. package/dist/runtimes/remote-thread-list/remote-thread-state.js +1 -1
  571. package/dist/runtimes/remote-thread-list/title-generation.d.ts +31 -33
  572. package/dist/runtimes/remote-thread-list/title-generation.d.ts.map +1 -1
  573. package/dist/runtimes/remote-thread-list/title.d.ts +5 -8
  574. package/dist/runtimes/remote-thread-list/title.d.ts.map +1 -1
  575. package/dist/runtimes/remote-thread-list/types.d.ts +119 -121
  576. package/dist/runtimes/remote-thread-list/types.d.ts.map +1 -1
  577. package/dist/runtimes/tool-invocations/ToolInvocationTracker.d.ts +147 -149
  578. package/dist/runtimes/tool-invocations/ToolInvocationTracker.d.ts.map +1 -1
  579. package/dist/runtimes/tool-invocations/ToolInvocationTracker.js +22 -7
  580. package/dist/runtimes/tool-invocations/ToolInvocationTracker.js.map +1 -1
  581. package/dist/store/clients/chain-of-thought-client.d.ts +8 -11
  582. package/dist/store/clients/chain-of-thought-client.d.ts.map +1 -1
  583. package/dist/store/clients/external-thread.d.ts +56 -58
  584. package/dist/store/clients/external-thread.d.ts.map +1 -1
  585. package/dist/store/clients/external-thread.js +1270 -741
  586. package/dist/store/clients/external-thread.js.map +1 -1
  587. package/dist/store/clients/model-context-client.d.ts +2 -5
  588. package/dist/store/clients/model-context-client.d.ts.map +1 -1
  589. package/dist/store/clients/no-op-composer-client.d.ts +3 -6
  590. package/dist/store/clients/no-op-composer-client.d.ts.map +1 -1
  591. package/dist/store/clients/no-op-composer-client.js +3 -1
  592. package/dist/store/clients/no-op-composer-client.js.map +1 -1
  593. package/dist/store/clients/runtime-adapter.d.ts +2 -5
  594. package/dist/store/clients/runtime-adapter.d.ts.map +1 -1
  595. package/dist/store/clients/single-thread-list.d.ts +4 -6
  596. package/dist/store/clients/single-thread-list.d.ts.map +1 -1
  597. package/dist/store/clients/submission-message.d.ts +8 -0
  598. package/dist/store/clients/submission-message.d.ts.map +1 -0
  599. package/dist/store/clients/submission-message.js +22 -0
  600. package/dist/store/clients/submission-message.js.map +1 -0
  601. package/dist/store/clients/suggestions.d.ts +8 -11
  602. package/dist/store/clients/suggestions.d.ts.map +1 -1
  603. package/dist/store/clients/thread-message-client.d.ts +12 -12
  604. package/dist/store/clients/thread-message-client.d.ts.map +1 -1
  605. package/dist/store/clients/thread-message-client.js +81 -82
  606. package/dist/store/clients/thread-message-client.js.map +1 -1
  607. package/dist/store/clients/thread-selection-events.d.ts +1 -4
  608. package/dist/store/clients/thread-selection-events.d.ts.map +1 -1
  609. package/dist/store/clients/thread-tasks.d.ts +7 -10
  610. package/dist/store/clients/thread-tasks.d.ts.map +1 -1
  611. package/dist/store/env.d.ts +1 -4
  612. package/dist/store/env.d.ts.map +1 -1
  613. package/dist/store/index.d.ts +33 -36
  614. package/dist/store/index.d.ts.map +1 -0
  615. package/dist/store/index.js +5 -5
  616. package/dist/store/internal.d.ts +12 -12
  617. package/dist/store/internal.d.ts.map +1 -0
  618. package/dist/store/internal.js +2 -2
  619. package/dist/store/primitive-predicates.d.ts +14 -16
  620. package/dist/store/primitive-predicates.d.ts.map +1 -1
  621. package/dist/store/primitive-predicates.js +10 -5
  622. package/dist/store/primitive-predicates.js.map +1 -1
  623. package/dist/store/runtime-clients/attachment-runtime-client.d.ts +4 -7
  624. package/dist/store/runtime-clients/attachment-runtime-client.d.ts.map +1 -1
  625. package/dist/store/runtime-clients/composer-runtime-client.d.ts +11 -14
  626. package/dist/store/runtime-clients/composer-runtime-client.d.ts.map +1 -1
  627. package/dist/store/runtime-clients/composer-runtime-client.js +65 -62
  628. package/dist/store/runtime-clients/composer-runtime-client.js.map +1 -1
  629. package/dist/store/runtime-clients/handle-runtime-action.d.ts +1 -4
  630. package/dist/store/runtime-clients/handle-runtime-action.d.ts.map +1 -1
  631. package/dist/store/runtime-clients/handle-thread-list-action.d.ts +1 -4
  632. package/dist/store/runtime-clients/handle-thread-list-action.d.ts.map +1 -1
  633. package/dist/store/runtime-clients/liveRef.d.ts +2 -5
  634. package/dist/store/runtime-clients/liveRef.d.ts.map +1 -1
  635. package/dist/store/runtime-clients/message-part-runtime-client.d.ts +4 -7
  636. package/dist/store/runtime-clients/message-part-runtime-client.d.ts.map +1 -1
  637. package/dist/store/runtime-clients/message-part-runtime-client.js +26 -16
  638. package/dist/store/runtime-clients/message-part-runtime-client.js.map +1 -1
  639. package/dist/store/runtime-clients/message-runtime-client.d.ts +10 -11
  640. package/dist/store/runtime-clients/message-runtime-client.d.ts.map +1 -1
  641. package/dist/store/runtime-clients/message-runtime-client.js +121 -113
  642. package/dist/store/runtime-clients/message-runtime-client.js.map +1 -1
  643. package/dist/store/runtime-clients/thread-list-item-runtime-client.d.ts +5 -8
  644. package/dist/store/runtime-clients/thread-list-item-runtime-client.d.ts.map +1 -1
  645. package/dist/store/runtime-clients/thread-list-runtime-client.d.ts +6 -9
  646. package/dist/store/runtime-clients/thread-list-runtime-client.d.ts.map +1 -1
  647. package/dist/store/runtime-clients/thread-runtime-client.d.ts +4 -7
  648. package/dist/store/runtime-clients/thread-runtime-client.d.ts.map +1 -1
  649. package/dist/store/runtime-clients/thread-runtime-client.js +221 -158
  650. package/dist/store/runtime-clients/thread-runtime-client.js.map +1 -1
  651. package/dist/store/runtime-clients/useSubscribable.d.ts +3 -6
  652. package/dist/store/runtime-clients/useSubscribable.d.ts.map +1 -1
  653. package/dist/store/scope-registration.d.ts +28 -29
  654. package/dist/store/scope-registration.d.ts.map +1 -1
  655. package/dist/store/scopes/attachment.d.ts +19 -22
  656. package/dist/store/scopes/attachment.d.ts.map +1 -1
  657. package/dist/store/scopes/chain-of-thought.d.ts +33 -35
  658. package/dist/store/scopes/chain-of-thought.d.ts.map +1 -1
  659. package/dist/store/scopes/composer.d.ts +147 -135
  660. package/dist/store/scopes/composer.d.ts.map +1 -1
  661. package/dist/store/scopes/message.d.ts +119 -112
  662. package/dist/store/scopes/message.d.ts.map +1 -1
  663. package/dist/store/scopes/model-context.d.ts +10 -13
  664. package/dist/store/scopes/model-context.d.ts.map +1 -1
  665. package/dist/store/scopes/part.d.ts +53 -50
  666. package/dist/store/scopes/part.d.ts.map +1 -1
  667. package/dist/store/scopes/queue-item.d.ts +21 -23
  668. package/dist/store/scopes/queue-item.d.ts.map +1 -1
  669. package/dist/store/scopes/suggestion.d.ts +14 -17
  670. package/dist/store/scopes/suggestion.d.ts.map +1 -1
  671. package/dist/store/scopes/suggestions.d.ts +18 -21
  672. package/dist/store/scopes/suggestions.d.ts.map +1 -1
  673. package/dist/store/scopes/task.d.ts +27 -30
  674. package/dist/store/scopes/task.d.ts.map +1 -1
  675. package/dist/store/scopes/thread-list-item.d.ts +68 -71
  676. package/dist/store/scopes/thread-list-item.d.ts.map +1 -1
  677. package/dist/store/scopes/thread.d.ts +197 -200
  678. package/dist/store/scopes/thread.d.ts.map +1 -1
  679. package/dist/store/scopes/threads.d.ts +49 -52
  680. package/dist/store/scopes/threads.d.ts.map +1 -1
  681. package/dist/subscribable/subscribable.d.ts +73 -69
  682. package/dist/subscribable/subscribable.d.ts.map +1 -1
  683. package/dist/subscribable/subscribable.js +35 -7
  684. package/dist/subscribable/subscribable.js.map +1 -1
  685. package/dist/types/attachment.d.ts +35 -37
  686. package/dist/types/attachment.d.ts.map +1 -1
  687. package/dist/types/augmentations.d.ts +7 -8
  688. package/dist/types/augmentations.d.ts.map +1 -1
  689. package/dist/types/directive.d.ts +13 -16
  690. package/dist/types/directive.d.ts.map +1 -1
  691. package/dist/types/error.d.ts +15 -17
  692. package/dist/types/error.d.ts.map +1 -1
  693. package/dist/types/index.d.ts +7 -7
  694. package/dist/types/index.d.ts.map +1 -0
  695. package/dist/types/message.d.ts +358 -318
  696. package/dist/types/message.d.ts.map +1 -1
  697. package/dist/types/message.js.map +1 -1
  698. package/dist/types/quote.d.ts +3 -6
  699. package/dist/types/quote.d.ts.map +1 -1
  700. package/dist/types/trigger.d.ts +10 -13
  701. package/dist/types/trigger.d.ts.map +1 -1
  702. package/dist/types/unsubscribe.d.ts +1 -4
  703. package/dist/types/unsubscribe.d.ts.map +1 -1
  704. package/dist/utils/abortable-iterable.d.ts +2 -5
  705. package/dist/utils/abortable-iterable.d.ts.map +1 -1
  706. package/dist/utils/composite-context-provider.d.ts +9 -13
  707. package/dist/utils/composite-context-provider.d.ts.map +1 -1
  708. package/dist/utils/data-url.d.ts +16 -19
  709. package/dist/utils/data-url.d.ts.map +1 -1
  710. package/dist/utils/getGroupStatus.d.ts +19 -21
  711. package/dist/utils/getGroupStatus.d.ts.map +1 -1
  712. package/dist/utils/id.d.ts +3 -6
  713. package/dist/utils/id.d.ts.map +1 -1
  714. package/dist/utils/image-media-type.d.ts +1 -4
  715. package/dist/utils/image-media-type.d.ts.map +1 -1
  716. package/dist/utils/invoke-user-callback.d.ts +1 -4
  717. package/dist/utils/invoke-user-callback.d.ts.map +1 -1
  718. package/dist/utils/json/is-json-equal.d.ts +1 -4
  719. package/dist/utils/json/is-json-equal.d.ts.map +1 -1
  720. package/dist/utils/json/is-json.d.ts +5 -8
  721. package/dist/utils/json/is-json.d.ts.map +1 -1
  722. package/dist/utils/json/stable-stringify-tool-args.d.ts +3 -6
  723. package/dist/utils/json/stable-stringify-tool-args.d.ts.map +1 -1
  724. package/dist/utils/normalizePartStatus.d.ts +6 -8
  725. package/dist/utils/normalizePartStatus.d.ts.map +1 -1
  726. package/dist/utils/normalizePartStatus.js +3 -2
  727. package/dist/utils/normalizePartStatus.js.map +1 -1
  728. package/dist/utils/notify-event-listeners.d.ts +2 -4
  729. package/dist/utils/notify-event-listeners.d.ts.map +1 -1
  730. package/dist/utils/record.d.ts +1 -4
  731. package/dist/utils/record.d.ts.map +1 -1
  732. package/dist/utils/silent-runtime-action.d.ts +2 -5
  733. package/dist/utils/silent-runtime-action.d.ts.map +1 -1
  734. package/dist/utils/text.d.ts +2 -5
  735. package/dist/utils/text.d.ts.map +1 -1
  736. package/dist/utils/wire-media.d.ts +3 -6
  737. package/dist/utils/wire-media.d.ts.map +1 -1
  738. package/package.json +15 -13
  739. package/src/adapters/attachment.test.ts +98 -1
  740. package/src/adapters/attachment.ts +77 -20
  741. package/src/adapters/feedback.ts +1 -0
  742. package/src/adapters/speech.test.ts +94 -0
  743. package/src/adapters/speech.ts +16 -2
  744. package/src/adapters/thread-history.ts +16 -5
  745. package/src/adapters/voice.test.ts +169 -0
  746. package/src/adapters/voice.ts +25 -4
  747. package/src/index.ts +14 -2
  748. package/src/internal.ts +7 -0
  749. package/src/model-context/frame/host.test.ts +51 -1
  750. package/src/model-context/frame/host.ts +3 -1
  751. package/src/model-context/frame/provider.test.ts +106 -20
  752. package/src/model-context/frame/provider.ts +8 -1
  753. package/src/model-context/frame/validate.ts +57 -0
  754. package/src/model-context/interactable-composer-metadata.test.ts +82 -0
  755. package/src/model-context/interactable-composer-metadata.ts +45 -2
  756. package/src/react/RuntimeAdapter.test.ts +4 -1
  757. package/src/react/adapters/LocalStorageThreadListAdapter.test.ts +711 -0
  758. package/src/react/adapters/LocalStorageThreadListAdapter.tsx +125 -109
  759. package/src/react/client/Interactables.test.ts +865 -8
  760. package/src/react/client/Interactables.ts +325 -45
  761. package/src/react/client/RemoteThreadList.concurrent.test.tsx +9 -3
  762. package/src/react/client/RemoteThreadList.initialize-failure.test.ts +124 -0
  763. package/src/react/client/RemoteThreadList.test.ts +5 -6
  764. package/src/react/client/RemoteThreadList.ts +6 -0
  765. package/src/react/client/Tools.ts +2 -3
  766. package/src/react/client/interactable-model-context.test.ts +56 -13
  767. package/src/react/client/interactable-model-context.ts +48 -23
  768. package/src/react/index.ts +2 -2
  769. package/src/react/interactables-legacy/Interactables.test.ts +221 -4
  770. package/src/react/interactables-legacy/Interactables.ts +25 -14
  771. package/src/react/interactables-legacy/interactable-model-context.ts +26 -24
  772. package/src/react/interactables-legacy/useAssistantInteractable.test.tsx +40 -22
  773. package/src/react/interactables-shared/useInteractablePersistenceQueue.test.tsx +22 -2
  774. package/src/react/interactables-shared/useInteractablePersistenceQueue.ts +63 -11
  775. package/src/react/model-context/useInteractable.test.tsx +56 -29
  776. package/src/react/primitive-hooks/useActionBarCopy.test.ts +5 -5
  777. package/src/react/primitive-hooks/useSuggestionTrigger.test.ts +33 -0
  778. package/src/react/primitive-hooks/useSuggestionTrigger.ts +7 -4
  779. package/src/react/primitives/generativeUI/GenerativeUI.test.tsx +170 -0
  780. package/src/react/primitives/generativeUI/GenerativeUI.tsx +43 -28
  781. package/src/react/primitives/message/MessageAttachments.test.tsx +2 -6
  782. package/src/react/primitives/message/MessageAttachments.tsx +14 -8
  783. package/src/react/primitives/message/MessageGroupedParts.test.tsx +155 -8
  784. package/src/react/primitives/message/MessageGroupedParts.tsx +19 -6
  785. package/src/react/primitives/message/MessageParts.test.tsx +84 -0
  786. package/src/react/primitives/message/MessageParts.tool-interaction.test.tsx +69 -0
  787. package/src/react/primitives/message/MessageParts.tsx +29 -8
  788. package/src/react/primitives/thread/ThreadMessages.test.tsx +25 -7
  789. package/src/react/primitives/thread/ThreadSuggestions.test.tsx +97 -0
  790. package/src/react/primitives/thread/ThreadSuggestions.tsx +29 -6
  791. package/src/react/providers/ReadonlyThreadProvider.tsx +2 -2
  792. package/src/react/providers/TextMessagePartProvider.tsx +3 -0
  793. package/src/react/runtimes/RemoteThreadListHookInstanceManager.layout.test.tsx +62 -0
  794. package/src/react/runtimes/RemoteThreadListHookInstanceManager.retry.test.tsx +2 -2
  795. package/src/react/runtimes/RemoteThreadListHookInstanceManager.running.test.tsx +93 -0
  796. package/src/react/runtimes/RemoteThreadListHookInstanceManager.test.tsx +181 -21
  797. package/src/react/runtimes/RemoteThreadListHookInstanceManager.title.test.tsx +62 -17
  798. package/src/react/runtimes/RemoteThreadListHookInstanceManager.tsx +112 -77
  799. package/src/react/runtimes/RemoteThreadListThreadListRuntimeCore.tsx +19 -3
  800. package/src/react/runtimes/RemoteThreadResource.ts +5 -2
  801. package/src/react/runtimes/assistant-transport/replayBoundaryStream.test.ts +3 -1
  802. package/src/react/runtimes/assistant-transport/replayBoundaryStream.ts +10 -2
  803. package/src/react/runtimes/assistant-transport/runManager.ts +3 -0
  804. package/src/react/runtimes/assistant-transport/transport-parentid.test.tsx +57 -0
  805. package/src/react/runtimes/assistant-transport/transport-scheduling.test.ts +73 -46
  806. package/src/react/runtimes/assistant-transport/transport-thread-id.test.tsx +571 -0
  807. package/src/react/runtimes/assistant-transport/types.ts +9 -1
  808. package/src/react/runtimes/assistant-transport/useAssistantTransport.spec.md +10 -0
  809. package/src/react/runtimes/assistant-transport/useAssistantTransportRuntime.test.tsx +108 -1
  810. package/src/react/runtimes/assistant-transport/useAssistantTransportRuntime.ts +33 -9
  811. package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.copy.integration.test.tsx +289 -0
  812. package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.copy.test.tsx +471 -0
  813. package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.engagement.test.tsx +330 -0
  814. package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.test.ts +78 -2
  815. package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.test.tsx +463 -2
  816. package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.ts +595 -227
  817. package/src/react/runtimes/cloud/CloudFileAttachmentAdapter.test.ts +33 -4
  818. package/src/react/runtimes/cloud/CloudFileAttachmentAdapter.ts +7 -3
  819. package/src/react/runtimes/cloud/auiV0.ts +275 -6
  820. package/src/react/runtimes/cloud/auiV0DecodeSafely.test.ts +873 -0
  821. package/src/react/runtimes/createMessageConverter.ts +9 -3
  822. package/src/react/runtimes/external-message-converter.test.ts +7 -3
  823. package/src/react/runtimes/external-store-history-copy.ts +223 -0
  824. package/src/react/runtimes/remote-thread-hook-on-tap.test.ts +2 -1
  825. package/src/react/runtimes/useExternalStoreRuntime.history-copy.test.tsx +483 -0
  826. package/src/react/runtimes/useExternalStoreRuntime.lifecycle.test.tsx +84 -3
  827. package/src/react/runtimes/useExternalStoreRuntime.suggestions.test.tsx +6 -2
  828. package/src/react/runtimes/useExternalStoreRuntime.ts +25 -5
  829. package/src/react/runtimes/useLocalRuntime.test.tsx +145 -1
  830. package/src/react/runtimes/useLocalRuntime.ts +8 -5
  831. package/src/react/runtimes/useRemoteThreadListRuntime.concurrent.test.tsx +84 -4
  832. package/src/react/runtimes/useRemoteThreadListRuntime.ts +5 -1
  833. package/src/react/types/MessagePartComponentTypes.ts +10 -0
  834. package/src/react/types/scopes/interactables.ts +3 -0
  835. package/src/runtime/api/attachment-runtime.ts +10 -5
  836. package/src/runtime/api/bindings.ts +6 -1
  837. package/src/runtime/api/composer-runtime.ts +29 -6
  838. package/src/runtime/api/message-part-runtime.test.ts +215 -0
  839. package/src/runtime/api/message-part-runtime.ts +44 -1
  840. package/src/runtime/api/message-runtime.test.ts +112 -2
  841. package/src/runtime/api/message-runtime.ts +25 -7
  842. package/src/runtime/api/thread-list-item-runtime.ts +5 -5
  843. package/src/runtime/api/thread-list-runtime.ts +3 -3
  844. package/src/runtime/api/thread-runtime.test.ts +59 -0
  845. package/src/runtime/api/thread-runtime.ts +21 -11
  846. package/src/runtime/base/base-composer-runtime-core.ts +548 -153
  847. package/src/runtime/base/base-thread-runtime-core.test.ts +1614 -136
  848. package/src/runtime/base/base-thread-runtime-core.ts +236 -46
  849. package/src/runtime/base/default-edit-composer-runtime-core.ts +24 -2
  850. package/src/runtime/base/default-thread-composer-runtime-core.ts +33 -3
  851. package/src/runtime/interfaces/composer-runtime-core.ts +19 -0
  852. package/src/runtime/interfaces/thread-runtime-core.ts +24 -1
  853. package/src/runtime/queue/message-queue.ts +11 -1
  854. package/src/runtime/utils/attachment-add-operations.ts +45 -2
  855. package/src/runtime/utils/attachment-send-operations.ts +54 -0
  856. package/src/runtime/utils/auto-status.test.ts +54 -0
  857. package/src/runtime/utils/auto-status.ts +3 -10
  858. package/src/runtime/utils/external-message-conversion.test.ts +91 -0
  859. package/src/runtime/utils/external-message-conversion.ts +9 -6
  860. package/src/runtime/utils/message-repository.test.ts +69 -1
  861. package/src/runtime/utils/message-repository.ts +14 -7
  862. package/src/runtime/utils/stored-message-parts.ts +216 -0
  863. package/src/runtime/utils/thread-message-like.test.ts +58 -0
  864. package/src/runtime/utils/thread-message-like.ts +79 -48
  865. package/src/runtime/utils/thread-runtime-lifecycle.test.ts +67 -0
  866. package/src/runtime/utils/thread-runtime-lifecycle.ts +42 -8
  867. package/src/runtime/utils/tool-interactions.test.ts +193 -0
  868. package/src/runtime/utils/tool-interactions.ts +147 -0
  869. package/src/runtimes/external-store/external-store-adapter.ts +25 -0
  870. package/src/runtimes/external-store/external-store-runtime-core.ts +10 -2
  871. package/src/runtimes/external-store/external-store-thread-list-runtime-core.ts +2 -2
  872. package/src/runtimes/external-store/external-store-thread-runtime-core.test.ts +49 -0
  873. package/src/runtimes/external-store/external-store-thread-runtime-core.ts +114 -32
  874. package/src/runtimes/inert/InertThreadRuntimeCore.test.ts +127 -56
  875. package/src/runtimes/inert/InertThreadRuntimeCore.ts +10 -1
  876. package/src/runtimes/local/local-thread-runtime-core.edit-cancellation.test.ts +70 -0
  877. package/src/runtimes/local/local-thread-runtime-core.test.ts +1866 -169
  878. package/src/runtimes/local/local-thread-runtime-core.ts +365 -40
  879. package/src/runtimes/readonly/ReadonlyThreadRuntimeCore.ts +53 -1
  880. package/src/runtimes/remote-thread-list/optimistic-state.ts +8 -3
  881. package/src/runtimes/tool-invocations/EDGE_CASES.md +19 -4
  882. package/src/runtimes/tool-invocations/ToolInvocationTracker.test.ts +392 -39
  883. package/src/runtimes/tool-invocations/ToolInvocationTracker.ts +31 -8
  884. package/src/store/clients/external-thread.test.ts +145 -0
  885. package/src/store/clients/external-thread.ts +669 -144
  886. package/src/store/clients/model-context-client.test.ts +8 -8
  887. package/src/store/clients/no-op-composer-client.ts +2 -0
  888. package/src/store/clients/submission-message.ts +27 -0
  889. package/src/store/clients/thread-message-client.test.ts +39 -0
  890. package/src/store/clients/thread-message-client.ts +13 -6
  891. package/src/store/index.ts +2 -2
  892. package/src/store/internal.ts +1 -0
  893. package/src/store/primitive-predicates.test.ts +119 -0
  894. package/src/store/primitive-predicates.ts +19 -4
  895. package/src/store/runtime-clients/composer-runtime-client.ts +4 -3
  896. package/src/store/runtime-clients/message-part-runtime-client.test.ts +42 -0
  897. package/src/store/runtime-clients/message-part-runtime-client.ts +4 -0
  898. package/src/store/runtime-clients/message-runtime-client.ts +5 -0
  899. package/src/store/runtime-clients/thread-runtime-client.test.tsx +243 -0
  900. package/src/store/runtime-clients/thread-runtime-client.ts +46 -9
  901. package/src/store/scopes/composer.ts +22 -4
  902. package/src/store/scopes/message.ts +12 -1
  903. package/src/store/scopes/part.ts +8 -0
  904. package/src/subscribable/subscribable.test.ts +205 -3
  905. package/src/subscribable/subscribable.ts +49 -7
  906. package/src/tests/RemoteThreadListThreadListRuntimeCore-errors.test.ts +95 -1
  907. package/src/tests/attachment-adapters.test.ts +16 -1
  908. package/src/tests/auiV0Encode.test.ts +412 -1
  909. package/src/tests/base-composer-runtime-core-addAttachment.test.ts +6 -6
  910. package/src/tests/base-composer-runtime-core-send.test.ts +722 -29
  911. package/src/tests/base-composer-runtime-core.test.ts +212 -5
  912. package/src/tests/composer-can-cancel.test.ts +35 -6
  913. package/src/tests/composer-can-send.test.ts +120 -1
  914. package/src/tests/composer-submission.test.tsx +796 -0
  915. package/src/tests/default-edit-composer-runtime-core.test.ts +149 -2
  916. package/src/tests/external-store-thread-list-runtime-core.test.ts +111 -0
  917. package/src/tests/external-store-thread-runtime-core-adapter.test.ts +810 -28
  918. package/src/tests/external-store-thread-runtime-core.test.ts +217 -0
  919. package/src/tests/external-thread-attachments.test.tsx +763 -26
  920. package/src/tests/external-thread-feedback.test.tsx +20 -7
  921. package/src/tests/external-thread-isLast.test.tsx +69 -0
  922. package/src/tests/external-thread-parity.test.tsx +1 -1
  923. package/src/tests/get-thread-state-isRunning.test.ts +2 -2
  924. package/src/tests/message-queue.test.ts +45 -10
  925. package/src/tests/remote-thread-list-adapter-switch.test.ts +45 -1
  926. package/src/tests/thread-switch-events.test.tsx +11 -7
  927. package/src/tests/useRemoteThreadListRuntime-controlled.test.tsx +2 -1
  928. package/src/types/message.test.ts +19 -0
  929. package/src/types/message.ts +65 -10
  930. package/src/utils/normalizePartStatus.ts +14 -1
  931. package/dist/tests/remote-thread-list-test-helpers.d.ts +0 -16
  932. package/dist/tests/remote-thread-list-test-helpers.d.ts.map +0 -1
  933. package/dist/tests/remote-thread-list-test-helpers.js +0 -59
  934. 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,11 +151,19 @@ 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;
145
- submittedFeedback: "positive" | "negative" | undefined;
146
- onSubmitFeedback: (feedback: { type: "positive" | "negative" }) => void;
160
+ submittedFeedback:
161
+ | { type: "positive" | "negative"; comment?: string }
162
+ | undefined;
163
+ onSubmitFeedback: (feedback: {
164
+ type: "positive" | "negative";
165
+ comment?: string;
166
+ }) => void;
147
167
  speech: SpeechState | undefined;
148
168
  onSpeak: () => void;
149
169
  onStopSpeaking: () => void;
@@ -153,12 +173,14 @@ type MessageClientProps = {
153
173
  const useMessageClient = ({
154
174
  message,
155
175
  index,
176
+ isLast,
156
177
  parentId,
157
178
  onEdit,
158
179
  onReload,
159
180
  queue,
160
181
  branches,
161
182
  onRespondToToolApproval,
183
+ unstable_onRecordToolInteraction,
162
184
  onAddToolResult,
163
185
  onResumeToolCall,
164
186
  attachmentAdapter,
@@ -180,6 +202,7 @@ const useMessageClient = ({
180
202
  status: derivePartStatus(message, idx, part),
181
203
  messageId: message.id,
182
204
  onRespondToToolApproval,
205
+ unstable_onRecordToolInteraction,
183
206
  onAddToolResult,
184
207
  onResumeToolCall,
185
208
  }),
@@ -236,7 +259,7 @@ const useMessageClient = ({
236
259
  ...message,
237
260
  metadata: {
238
261
  ...message.metadata,
239
- submittedFeedback: { type: submittedFeedback },
262
+ submittedFeedback,
240
263
  },
241
264
  }
242
265
  : message;
@@ -244,7 +267,7 @@ const useMessageClient = ({
244
267
  ...messageWithFeedback,
245
268
  attachments: message.attachments ?? [],
246
269
  parentId,
247
- isLast: false, // Will be set by thread
270
+ isLast,
248
271
  branchNumber,
249
272
  branchCount,
250
273
  speech,
@@ -256,6 +279,7 @@ const useMessageClient = ({
256
279
  };
257
280
  }, [
258
281
  message,
282
+ isLast,
259
283
  parentId,
260
284
  isCopied,
261
285
  isHovering,
@@ -322,6 +346,9 @@ type PartResourceProps = {
322
346
  onRespondToToolApproval?:
323
347
  | ((options: RespondToToolApprovalOptions) => void | Promise<void>)
324
348
  | undefined;
349
+ unstable_onRecordToolInteraction?:
350
+ | ((options: Unstable_RecordToolInteractionOptions) => void | Promise<void>)
351
+ | undefined;
325
352
  onAddToolResult?: ((options: AddToolResultOptions) => void) | undefined;
326
353
  onResumeToolCall?: ((options: ResumeToolCallOptions) => void) | undefined;
327
354
  };
@@ -332,6 +359,7 @@ const usePartResource = ({
332
359
  status,
333
360
  messageId,
334
361
  onRespondToToolApproval,
362
+ unstable_onRecordToolInteraction,
335
363
  onAddToolResult,
336
364
  onResumeToolCall,
337
365
  }: PartResourceProps): ClientOutput<"part"> => {
@@ -372,6 +400,18 @@ const usePartResource = ({
372
400
  throw new Error("Tried to resume tool call on non-tool message part");
373
401
 
374
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(() => {});
375
415
  },
376
416
  respondToToolApproval: (response) => {
377
417
  if (!onRespondToToolApproval)
@@ -396,6 +436,22 @@ const usePartResource = ({
396
436
  return Promise.reject(error);
397
437
  }
398
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
+ },
399
455
  };
400
456
  };
401
457
 
@@ -421,6 +477,8 @@ const useAttachmentResource = ({
421
477
 
422
478
  const AttachmentResource = resource(useAttachmentResource);
423
479
 
480
+ const EMPTY_MESSAGE_KEYS: readonly string[] = Object.freeze([]);
481
+
424
482
  type ComposerClientResourceProps = {
425
483
  type: "thread" | "edit";
426
484
  canCancel: boolean;
@@ -432,6 +490,8 @@ type ComposerClientResourceProps = {
432
490
  message?: ExternalThreadMessage;
433
491
  queue?: ExternalThreadQueueAdapter | undefined;
434
492
  attachmentAdapter?: AttachmentAdapter | undefined;
493
+ /** `id|role` of each thread message, used to tell when a send has landed. */
494
+ messageKeys?: readonly string[] | undefined;
435
495
  };
436
496
 
437
497
  const useQueueItemClient = ({
@@ -468,34 +528,59 @@ const useLiveState = <T>(initial: T) => {
468
528
  };
469
529
 
470
530
  // A try/catch inside the resource makes the React Compiler bail out of the
471
- // 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.
472
532
  const removeAttachmentThroughAdapter = async (
473
533
  attachment: Attachment,
474
534
  attachmentAdapter: AttachmentAdapter | undefined,
475
- setAttachments: (
476
- next:
477
- | readonly Attachment[]
478
- | ((prev: readonly Attachment[]) => readonly Attachment[]),
479
- ) => void,
535
+ onError: (message: string) => void,
480
536
  ) => {
481
537
  try {
482
538
  await attachmentAdapter?.remove(attachment);
483
539
  } catch (error) {
484
- const message = error instanceof Error ? error.message : String(error);
485
- setAttachments((prev) =>
486
- prev.map((candidate) =>
487
- candidate.id === attachment.id && !isAttachmentComplete(candidate)
488
- ? {
489
- ...candidate,
490
- status: { type: "incomplete", reason: "error", message },
491
- }
492
- : candidate,
493
- ),
494
- );
540
+ onError(error instanceof Error ? error.message : String(error));
495
541
  throw error;
496
542
  }
497
543
  };
498
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
+
499
584
  // Composer Client - minimal implementation
500
585
  const useComposerClientResource = ({
501
586
  type,
@@ -508,6 +593,7 @@ const useComposerClientResource = ({
508
593
  message,
509
594
  queue,
510
595
  attachmentAdapter,
596
+ messageKeys = EMPTY_MESSAGE_KEYS,
511
597
  }: ComposerClientResourceProps): ClientOutput<"composer"> => {
512
598
  const [isEditing, setIsEditing, isEditingRef] = useLiveState(
513
599
  type === "thread",
@@ -529,6 +615,65 @@ const useComposerClientResource = ({
529
615
  () => new AttachmentAddOperations(),
530
616
  [],
531
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]);
532
677
 
533
678
  const updateFromMessage = () => {
534
679
  if (!message) return;
@@ -538,33 +683,130 @@ const useComposerClientResource = ({
538
683
  .join("\n\n");
539
684
  setText(messageText);
540
685
  setRole(message.role);
541
- 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);
542
692
  };
543
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
+
544
784
  const attachmentClients = useClientLookup(
545
785
  attachments.map((attachment) =>
546
786
  withKey(
547
787
  attachment.id,
548
788
  AttachmentResource({
549
789
  attachment,
550
- onRemove: async () => {
551
- attachmentAddOperations.cancel(attachment.id);
552
- if (!isAttachmentComplete(attachment)) {
553
- await removeAttachmentThroughAdapter(
554
- attachment,
555
- attachmentAdapter,
556
- setAttachments,
557
- );
558
- }
559
- setAttachments((prev) =>
560
- prev.filter((a) => a.id !== attachment.id),
561
- );
562
- },
790
+ onRemove: () => handleRemoveAttachment(attachment),
563
791
  }),
564
792
  ),
565
793
  ),
566
794
  );
567
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
+
568
810
  const removePendingAttachments = async (removed: readonly Attachment[]) => {
569
811
  if (!attachmentAdapter) return;
570
812
  await Promise.all(
@@ -575,6 +817,16 @@ const useComposerClientResource = ({
575
817
  };
576
818
 
577
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
+ }
578
830
  setAttachments((prev) => {
579
831
  const idx = prev.findIndex((a) => a.id === attachment.id);
580
832
  if (idx === -1) return [...prev, attachment];
@@ -616,14 +868,17 @@ const useComposerClientResource = ({
616
868
  attachments: attachmentClients.state,
617
869
  runConfig,
618
870
  isEditing,
619
- canCancel,
620
- canSend: isEditing && !isEmpty && !isSendDisabled,
871
+ canCancel: canCancel || submission !== undefined,
872
+ canSend:
873
+ isEditing && !isEmpty && !isSendDisabled && submission === undefined,
621
874
  attachmentAccept: attachmentAdapter?.accept ?? "*",
622
875
  isEmpty,
623
876
  type,
624
877
  dictation: undefined,
625
878
  quote,
626
879
  queue: queueItems,
880
+ submission,
881
+ inTransit: inTransitSubmissions,
627
882
  };
628
883
  }, [
629
884
  text,
@@ -633,6 +888,8 @@ const useComposerClientResource = ({
633
888
  isEditing,
634
889
  canCancel,
635
890
  isSendDisabled,
891
+ submission,
892
+ inTransitSubmissions,
636
893
  type,
637
894
  attachments.length,
638
895
  quote,
@@ -640,6 +897,211 @@ const useComposerClientResource = ({
640
897
  attachmentAdapter?.accept,
641
898
  ]);
642
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
+
643
1105
  return {
644
1106
  getState: () => state,
645
1107
  setText,
@@ -664,7 +1126,7 @@ const useComposerClientResource = ({
664
1126
  await drainAttachmentAdd(
665
1127
  attachmentAdapter.add({ file: fileOrAttachment }),
666
1128
  (attachment) => {
667
- if (!attachmentAddOperations.accept(operation, attachment.id))
1129
+ if (!attachmentAddOperations.accept(operation, attachment))
668
1130
  return false;
669
1131
  upsertAttachment(attachment);
670
1132
  return true;
@@ -701,94 +1163,98 @@ const useComposerClientResource = ({
701
1163
  clearAttachments: async () => {
702
1164
  attachmentAddOperations.cancelAll();
703
1165
  const removed = attachmentsRef.current;
1166
+ if (submissionRef.current) {
1167
+ for (const attachment of removed)
1168
+ attachmentSends.markRemoved(attachment);
1169
+ }
704
1170
  setAttachments([]);
705
1171
  await removePendingAttachments(removed);
706
1172
  },
707
1173
  attachment: (selector) => {
708
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 });
709
1183
  return attachmentClients.get({ key: selector.id });
710
1184
  }
711
1185
  return attachmentClients.get(selector);
712
1186
  },
713
1187
  reset: async () => {
714
1188
  attachmentAddOperations.cancelAll();
1189
+ sendGeneration.current++;
1190
+ const discarded = discardSubmission();
715
1191
  const removed = attachmentsRef.current;
716
1192
  setText("");
717
1193
  setRole("user");
718
1194
  setRunConfig({});
719
1195
  setAttachments([]);
720
1196
  setQuote(undefined);
721
- await removePendingAttachments(removed);
1197
+ await Promise.all([removePendingAttachments(removed), discarded]);
722
1198
  },
723
1199
  send: (opts?: ComposerSendOptions) => {
724
- const currentQuote = quoteRef.current;
725
- const currentText = textRef.current;
726
- const currentRole = roleRef.current;
727
- const currentRunConfig = runConfigRef.current;
728
- const currentAttachments = attachmentsRef.current;
729
- 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;
730
1206
  if (!isEditingRef.current) throw new Error("Composer is not available");
731
- if (isEmpty || isSendDisabled) return;
732
-
733
- attachmentAddOperations.cancelAll();
734
- setText("");
735
- setAttachments([]);
736
- setQuote(undefined);
737
-
738
- const dispatch = (sendAttachments: readonly Attachment[]) => {
739
- const composedMessage: AppendMessage = {
740
- role: currentRole,
741
- content: currentText
742
- ? [{ type: "text" as const, text: currentText }]
743
- : [],
744
- attachments: sendAttachments as any,
745
- createdAt: new Date(),
746
- parentId: null,
747
- sourceId: null,
748
- runConfig: currentRunConfig,
749
- startRun: opts?.startRun,
750
- metadata: {
751
- custom: { ...(currentQuote ? { quote: currentQuote } : {}) },
752
- },
753
- };
754
- // edit sends carry a sourceId contract; only thread sends queue
755
- if (queue && type === "thread") {
756
- if (opts?.steer ?? isRunning) queue.steer(composedMessage);
757
- else queue.enqueue(composedMessage);
758
- } else {
759
- onSend?.(composedMessage);
760
- }
761
- 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,
762
1215
  };
763
-
764
- if (attachmentAdapter && currentAttachments.length > 0) {
765
- void Promise.all(
766
- currentAttachments.map((attachment) =>
767
- attachment.status.type === "complete"
768
- ? attachment
769
- : attachmentAdapter.send(attachment as PendingAttachment),
770
- ),
771
- ).then(dispatch, (error) => {
772
- // Upload failed: merge the failed send back into the draft.
773
- setText((prev) =>
774
- currentText && prev
775
- ? currentText + "\n" + prev
776
- : currentText || prev,
777
- );
778
- setQuote((prev) => prev ?? currentQuote);
779
- setAttachments((prev) => [...currentAttachments, ...prev]);
780
- console.error("Failed to send attachments", error);
781
- });
782
- } else {
783
- 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);
784
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);
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);
785
1242
  },
786
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
+ }
787
1251
  // An edit session ends here, so its in-flight adapter adds must not
788
1252
  // land in a later session; the thread composer's cancel stops the run
789
1253
  // and leaves the draft (and its pending adds) alone.
790
1254
  if (type === "edit") {
791
1255
  attachmentAddOperations.cancelAll();
1256
+ sendGeneration.current++;
1257
+ void discardSubmission();
792
1258
  const removed = attachmentsRef.current;
793
1259
  setAttachments([]);
794
1260
  removePendingAttachments(removed).catch((error) => {
@@ -912,6 +1378,7 @@ const useExternalThread = ({
912
1378
  onRefetchThread,
913
1379
  onAddToolResult,
914
1380
  onResumeToolCall,
1381
+ unstable_onRecordToolInteraction,
915
1382
  onLoadExternalState,
916
1383
  attachmentAdapter,
917
1384
  feedbackAdapter,
@@ -931,16 +1398,24 @@ const useExternalThread = ({
931
1398
  Record<
932
1399
  string,
933
1400
  {
934
- type: "positive" | "negative";
935
- external: "positive" | "negative" | undefined;
1401
+ feedback: { type: "positive" | "negative"; comment?: string };
1402
+ external:
1403
+ | {
1404
+ readonly type: "positive" | "negative";
1405
+ readonly comment?: string;
1406
+ }
1407
+ | undefined;
936
1408
  }
937
1409
  >
938
1410
  >({});
939
1411
 
940
1412
  const feedbackFor = (msg: ExternalThreadMessage) => {
941
1413
  const entry = submittedFeedback[msg.id];
942
- return entry && msg.metadata.submittedFeedback?.type === entry.external
943
- ? entry.type
1414
+ const external = msg.metadata.submittedFeedback;
1415
+ return entry &&
1416
+ external?.type === entry.external?.type &&
1417
+ external?.comment === entry.external?.comment
1418
+ ? entry.feedback
944
1419
  : undefined;
945
1420
  };
946
1421
 
@@ -952,7 +1427,11 @@ const useExternalThread = ({
952
1427
  setSubmittedFeedback((prev) => {
953
1428
  const live = Object.entries(prev).filter(([id, entry]) => {
954
1429
  const msg = messages.find((m) => m.id === id);
955
- return !!msg && msg.metadata.submittedFeedback?.type === entry.external;
1430
+ return (
1431
+ !!msg &&
1432
+ msg.metadata.submittedFeedback?.type === entry.external?.type &&
1433
+ msg.metadata.submittedFeedback?.comment === entry.external?.comment
1434
+ );
956
1435
  });
957
1436
  return live.length === Object.keys(prev).length
958
1437
  ? prev
@@ -962,17 +1441,21 @@ const useExternalThread = ({
962
1441
 
963
1442
  const handleSubmitFeedback = (
964
1443
  message: ExternalThreadMessage,
965
- { type }: { type: "positive" | "negative" },
1444
+ feedback: { type: "positive" | "negative"; comment?: string },
966
1445
  ) => {
967
- if (!feedbackAdapter) throw new Error("Feedback adapter not configured");
968
- feedbackAdapter.submit({ message, type });
1446
+ const comment = feedback.comment?.trim();
1447
+ const submittedFeedback = {
1448
+ type: feedback.type,
1449
+ ...(comment ? { comment } : undefined),
1450
+ };
1451
+ feedbackAdapter?.submit({ message, ...submittedFeedback });
969
1452
 
970
1453
  if (message.role === "assistant") {
971
1454
  setSubmittedFeedback((prev) => ({
972
1455
  ...prev,
973
1456
  [message.id]: {
974
- type,
975
- external: message.metadata.submittedFeedback?.type,
1457
+ feedback: submittedFeedback,
1458
+ external: message.metadata.submittedFeedback,
976
1459
  },
977
1460
  }));
978
1461
  }
@@ -1002,36 +1485,9 @@ const useExternalThread = ({
1002
1485
  onReload?.(parentId);
1003
1486
  };
1004
1487
 
1005
- const messageClients = useClientLookup(
1006
- messages.map((msg, index) => {
1007
- const props: MessageClientProps = {
1008
- message: msg,
1009
- index,
1010
- parentId: index > 0 ? messages[index - 1]!.id : null,
1011
- onReload: () => handleReload(msg.id),
1012
- queue,
1013
- branches,
1014
- onRespondToToolApproval,
1015
- onAddToolResult,
1016
- onResumeToolCall,
1017
- attachmentAdapter,
1018
- submittedFeedback: feedbackFor(msg),
1019
- onSubmitFeedback: (feedback) => handleSubmitFeedback(msg, feedback),
1020
- speech: speech?.messageId === msg.id ? speech : undefined,
1021
- onSpeak: () => handleSpeak(msg),
1022
- onStopSpeaking: () => speechController.stopMessage(msg.id),
1023
- };
1024
- if (onEdit) props.onEdit = onEdit;
1025
- return withKey(msg.id, MessageClient(props));
1026
- }),
1027
- );
1028
-
1029
- const taskDeriver = useMemo(() => createTaskDeriver(), []);
1030
- const tasks = useMemo(() => taskDeriver(messages), [taskDeriver, messages]);
1031
- const taskClients = useClientLookup(
1032
- tasks.map((task) =>
1033
- withKey(getTaskKey(task), TaskClient({ task }), [task]),
1034
- ),
1488
+ const messageKeys = useMemo(
1489
+ () => messages.map((message) => `${message.id}|${message.role}`),
1490
+ [messages],
1035
1491
  );
1036
1492
 
1037
1493
  const handleCancelRun = () => {
@@ -1077,8 +1533,71 @@ const useExternalThread = ({
1077
1533
  onSend: handleSendNew,
1078
1534
  queue: composerQueue,
1079
1535
  attachmentAdapter,
1536
+ messageKeys,
1080
1537
  }),
1081
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));
1571
+ }),
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
+
1082
1601
  const suggestionsClient = useClientResource(
1083
1602
  ThreadSuggestions(EMPTY_SUGGESTIONS),
1084
1603
  );
@@ -1091,13 +1610,13 @@ const useExternalThread = ({
1091
1610
  const hasFeedback = !!feedbackAdapter;
1092
1611
  const hasSpeech = !!speechAdapter;
1093
1612
  const state = useMemo(() => {
1094
- const messageStates = messageClients.state.map((s, idx, arr) => ({
1095
- ...s,
1096
- isLast: idx === arr.length - 1,
1097
- }));
1613
+ const messageStates =
1614
+ pendingClients.state.length === 0
1615
+ ? messageClients.state
1616
+ : [...messageClients.state, ...pendingClients.state];
1098
1617
 
1099
1618
  return {
1100
- isEmpty: messages.length === 0 && !isLoading,
1619
+ isEmpty: messageStates.length === 0 && !isLoading,
1101
1620
  isDisabled: false,
1102
1621
  isLoading,
1103
1622
  isRunning,
@@ -1127,7 +1646,6 @@ const useExternalThread = ({
1127
1646
  composer: composerClient.state,
1128
1647
  };
1129
1648
  }, [
1130
- messages,
1131
1649
  isRunning,
1132
1650
  isLoading,
1133
1651
  threadState,
@@ -1143,6 +1661,7 @@ const useExternalThread = ({
1143
1661
  hasSpeech,
1144
1662
  speech,
1145
1663
  messageClients.state,
1664
+ pendingClients.state,
1146
1665
  composerClient.state,
1147
1666
  tasks,
1148
1667
  ]);
@@ -1217,8 +1736,14 @@ const useExternalThread = ({
1217
1736
  reset: () => {},
1218
1737
  message: (selector) => {
1219
1738
  if ("id" in selector) {
1739
+ if (pending.some((row) => row.id === selector.id))
1740
+ return pendingClients.get({ key: selector.id });
1220
1741
  return messageClients.get({ key: selector.id });
1221
1742
  }
1743
+ if (selector.index >= messageClients.state.length)
1744
+ return pendingClients.get({
1745
+ index: selector.index - messageClients.state.length,
1746
+ });
1222
1747
  return messageClients.get(selector);
1223
1748
  },
1224
1749
  stopSpeaking: speechController.stop,