@assistant-ui/core 0.3.19 → 0.3.20

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 (664) hide show
  1. package/dist/adapters/attachment.d.ts +9 -10
  2. package/dist/adapters/attachment.d.ts.map +1 -1
  3. package/dist/adapters/attachment.js +2 -1
  4. package/dist/adapters/attachment.js.map +1 -1
  5. package/dist/adapters/directive-formatter.d.ts +1 -2
  6. package/dist/adapters/directive-formatter.d.ts.map +1 -1
  7. package/dist/adapters/feedback.d.ts +2 -2
  8. package/dist/adapters/feedback.d.ts.map +1 -1
  9. package/dist/adapters/speech.d.ts +6 -7
  10. package/dist/adapters/speech.d.ts.map +1 -1
  11. package/dist/adapters/suggestion.d.ts +5 -6
  12. package/dist/adapters/suggestion.d.ts.map +1 -1
  13. package/dist/adapters/thread-history.d.ts +6 -7
  14. package/dist/adapters/thread-history.d.ts.map +1 -1
  15. package/dist/adapters/trigger.d.ts +1 -2
  16. package/dist/adapters/trigger.d.ts.map +1 -1
  17. package/dist/adapters/voice.d.ts +5 -6
  18. package/dist/adapters/voice.d.ts.map +1 -1
  19. package/dist/internal/duplicate-detection.d.ts +1 -2
  20. package/dist/internal/duplicate-detection.d.ts.map +1 -1
  21. package/dist/model-context/frame/host.d.ts +1 -2
  22. package/dist/model-context/frame/host.d.ts.map +1 -1
  23. package/dist/model-context/frame/provider.d.ts +1 -2
  24. package/dist/model-context/frame/provider.d.ts.map +1 -1
  25. package/dist/model-context/frame/types.d.ts +5 -6
  26. package/dist/model-context/frame/types.d.ts.map +1 -1
  27. package/dist/model-context/interactable-composer-metadata.d.ts +9 -10
  28. package/dist/model-context/interactable-composer-metadata.d.ts.map +1 -1
  29. package/dist/model-context/registry-handles.d.ts +3 -4
  30. package/dist/model-context/registry-handles.d.ts.map +1 -1
  31. package/dist/model-context/registry.d.ts +1 -2
  32. package/dist/model-context/registry.d.ts.map +1 -1
  33. package/dist/model-context/tool-call-text.d.ts +2 -3
  34. package/dist/model-context/tool-call-text.d.ts.map +1 -1
  35. package/dist/model-context/tool.d.ts +2 -3
  36. package/dist/model-context/tool.d.ts.map +1 -1
  37. package/dist/model-context/types.d.ts +8 -9
  38. package/dist/model-context/types.d.ts.map +1 -1
  39. package/dist/react/AssistantProvider.d.ts +3 -4
  40. package/dist/react/AssistantProvider.d.ts.map +1 -1
  41. package/dist/react/AssistantRuntimeProvider.d.ts +1 -2
  42. package/dist/react/AssistantRuntimeProvider.d.ts.map +1 -1
  43. package/dist/react/RuntimeAdapter.d.ts +2 -3
  44. package/dist/react/RuntimeAdapter.d.ts.map +1 -1
  45. package/dist/react/adapters/LocalStorageThreadListAdapter.d.ts +4 -5
  46. package/dist/react/adapters/LocalStorageThreadListAdapter.d.ts.map +1 -1
  47. package/dist/react/adapters/LocalStorageThreadListAdapter.js +20 -34
  48. package/dist/react/adapters/LocalStorageThreadListAdapter.js.map +1 -1
  49. package/dist/react/adapters/TitleGenerationAdapter.d.ts +2 -3
  50. package/dist/react/adapters/TitleGenerationAdapter.d.ts.map +1 -1
  51. package/dist/react/client/AdaptedRemoteThread.d.ts +1 -2
  52. package/dist/react/client/AdaptedRemoteThread.d.ts.map +1 -1
  53. package/dist/react/client/DataRenderers.d.ts +1 -2
  54. package/dist/react/client/DataRenderers.d.ts.map +1 -1
  55. package/dist/react/client/InMemoryThreadList.d.ts +3 -4
  56. package/dist/react/client/InMemoryThreadList.d.ts.map +1 -1
  57. package/dist/react/client/Interactables.d.ts +1 -2
  58. package/dist/react/client/Interactables.d.ts.map +1 -1
  59. package/dist/react/client/RemoteThreadList.d.ts +2 -3
  60. package/dist/react/client/RemoteThreadList.d.ts.map +1 -1
  61. package/dist/react/client/Tools.d.ts +2 -2
  62. package/dist/react/client/Tools.d.ts.map +1 -1
  63. package/dist/react/client/interactable-model-context.d.ts +2 -3
  64. package/dist/react/client/interactable-model-context.d.ts.map +1 -1
  65. package/dist/react/interactables-legacy/Interactables.d.ts +1 -2
  66. package/dist/react/interactables-legacy/Interactables.d.ts.map +1 -1
  67. package/dist/react/interactables-legacy/interactable-model-context.d.ts +2 -3
  68. package/dist/react/interactables-legacy/interactable-model-context.d.ts.map +1 -1
  69. package/dist/react/interactables-legacy/scopes.d.ts +9 -10
  70. package/dist/react/interactables-legacy/scopes.d.ts.map +1 -1
  71. package/dist/react/interactables-legacy/useAssistantInteractable.d.ts +2 -3
  72. package/dist/react/interactables-legacy/useAssistantInteractable.d.ts.map +1 -1
  73. package/dist/react/interactables-legacy/useInteractableState.d.ts +1 -2
  74. package/dist/react/interactables-legacy/useInteractableState.d.ts.map +1 -1
  75. package/dist/react/interactables-shared/useInteractablePersistenceQueue.d.ts +1 -2
  76. package/dist/react/interactables-shared/useInteractablePersistenceQueue.d.ts.map +1 -1
  77. package/dist/react/model-context/define-mcp-toolkit.d.ts +4 -5
  78. package/dist/react/model-context/define-mcp-toolkit.d.ts.map +1 -1
  79. package/dist/react/model-context/define-toolkit.d.ts +2 -3
  80. package/dist/react/model-context/define-toolkit.d.ts.map +1 -1
  81. package/dist/react/model-context/external-tool.d.ts +1 -2
  82. package/dist/react/model-context/external-tool.d.ts.map +1 -1
  83. package/dist/react/model-context/human-tool.d.ts +3 -4
  84. package/dist/react/model-context/human-tool.d.ts.map +1 -1
  85. package/dist/react/model-context/interactableTool.d.ts +3 -4
  86. package/dist/react/model-context/interactableTool.d.ts.map +1 -1
  87. package/dist/react/model-context/makeAssistantDataUI.d.ts +2 -3
  88. package/dist/react/model-context/makeAssistantDataUI.d.ts.map +1 -1
  89. package/dist/react/model-context/makeAssistantTool.d.ts +2 -3
  90. package/dist/react/model-context/makeAssistantTool.d.ts.map +1 -1
  91. package/dist/react/model-context/makeAssistantToolUI.d.ts +2 -3
  92. package/dist/react/model-context/makeAssistantToolUI.d.ts.map +1 -1
  93. package/dist/react/model-context/provider-tool.d.ts +2 -3
  94. package/dist/react/model-context/provider-tool.d.ts.map +1 -1
  95. package/dist/react/model-context/stub-tool.d.ts +1 -2
  96. package/dist/react/model-context/stub-tool.d.ts.map +1 -1
  97. package/dist/react/model-context/toolbox.d.ts +9 -10
  98. package/dist/react/model-context/toolbox.d.ts.map +1 -1
  99. package/dist/react/model-context/useAssistantContext.d.ts +2 -2
  100. package/dist/react/model-context/useAssistantContext.d.ts.map +1 -1
  101. package/dist/react/model-context/useAssistantDataUI.d.ts +2 -3
  102. package/dist/react/model-context/useAssistantDataUI.d.ts.map +1 -1
  103. package/dist/react/model-context/useAssistantInstructions.d.ts +2 -2
  104. package/dist/react/model-context/useAssistantInstructions.d.ts.map +1 -1
  105. package/dist/react/model-context/useAssistantTool.d.ts +2 -3
  106. package/dist/react/model-context/useAssistantTool.d.ts.map +1 -1
  107. package/dist/react/model-context/useAssistantToolUI.d.ts +2 -3
  108. package/dist/react/model-context/useAssistantToolUI.d.ts.map +1 -1
  109. package/dist/react/model-context/useAuiToolOverrides.d.ts +1 -2
  110. package/dist/react/model-context/useAuiToolOverrides.d.ts.map +1 -1
  111. package/dist/react/model-context/useInlineRender.d.ts +1 -2
  112. package/dist/react/model-context/useInlineRender.d.ts.map +1 -1
  113. package/dist/react/model-context/useInteractable.d.ts +4 -5
  114. package/dist/react/model-context/useInteractable.d.ts.map +1 -1
  115. package/dist/react/model-context/useInteractableState.d.ts +1 -2
  116. package/dist/react/model-context/useInteractableState.d.ts.map +1 -1
  117. package/dist/react/model-context/useInteractableVersions.d.ts +1 -2
  118. package/dist/react/model-context/useInteractableVersions.d.ts.map +1 -1
  119. package/dist/react/model-context/useToolArgsStatus.d.ts +2 -3
  120. package/dist/react/model-context/useToolArgsStatus.d.ts.map +1 -1
  121. package/dist/react/primitive-hooks/useActionBarCopy.d.ts +2 -3
  122. package/dist/react/primitive-hooks/useActionBarCopy.d.ts.map +1 -1
  123. package/dist/react/primitive-hooks/useActionBarEdit.d.ts +1 -2
  124. package/dist/react/primitive-hooks/useActionBarEdit.d.ts.map +1 -1
  125. package/dist/react/primitive-hooks/useActionBarFeedback.d.ts +2 -3
  126. package/dist/react/primitive-hooks/useActionBarFeedback.d.ts.map +1 -1
  127. package/dist/react/primitive-hooks/useActionBarReload.d.ts +1 -2
  128. package/dist/react/primitive-hooks/useActionBarReload.d.ts.map +1 -1
  129. package/dist/react/primitive-hooks/useActionBarSpeak.d.ts +1 -2
  130. package/dist/react/primitive-hooks/useActionBarSpeak.d.ts.map +1 -1
  131. package/dist/react/primitive-hooks/useActionBarStopSpeaking.d.ts +1 -2
  132. package/dist/react/primitive-hooks/useActionBarStopSpeaking.d.ts.map +1 -1
  133. package/dist/react/primitive-hooks/useBranchPickerNext.d.ts +1 -2
  134. package/dist/react/primitive-hooks/useBranchPickerNext.d.ts.map +1 -1
  135. package/dist/react/primitive-hooks/useBranchPickerPrevious.d.ts +1 -2
  136. package/dist/react/primitive-hooks/useBranchPickerPrevious.d.ts.map +1 -1
  137. package/dist/react/primitive-hooks/useComposerAddAttachment.d.ts +1 -2
  138. package/dist/react/primitive-hooks/useComposerAddAttachment.d.ts.map +1 -1
  139. package/dist/react/primitive-hooks/useComposerCancel.d.ts +1 -2
  140. package/dist/react/primitive-hooks/useComposerCancel.d.ts.map +1 -1
  141. package/dist/react/primitive-hooks/useComposerDictate.d.ts +1 -2
  142. package/dist/react/primitive-hooks/useComposerDictate.d.ts.map +1 -1
  143. package/dist/react/primitive-hooks/useComposerSend.d.ts +1 -2
  144. package/dist/react/primitive-hooks/useComposerSend.d.ts.map +1 -1
  145. package/dist/react/primitive-hooks/useEditComposerCancel.d.ts +1 -2
  146. package/dist/react/primitive-hooks/useEditComposerCancel.d.ts.map +1 -1
  147. package/dist/react/primitive-hooks/useEditComposerSend.d.ts +1 -2
  148. package/dist/react/primitive-hooks/useEditComposerSend.d.ts.map +1 -1
  149. package/dist/react/primitive-hooks/useMessageBranching.d.ts +1 -2
  150. package/dist/react/primitive-hooks/useMessageBranching.d.ts.map +1 -1
  151. package/dist/react/primitive-hooks/useMessageError.d.ts +1 -2
  152. package/dist/react/primitive-hooks/useMessageError.d.ts.map +1 -1
  153. package/dist/react/primitive-hooks/useMessageReload.d.ts +1 -2
  154. package/dist/react/primitive-hooks/useMessageReload.d.ts.map +1 -1
  155. package/dist/react/primitive-hooks/useSuggestionTrigger.d.ts +2 -3
  156. package/dist/react/primitive-hooks/useSuggestionTrigger.d.ts.map +1 -1
  157. package/dist/react/primitive-hooks/useThreadIsEmpty.d.ts +1 -2
  158. package/dist/react/primitive-hooks/useThreadIsEmpty.d.ts.map +1 -1
  159. package/dist/react/primitive-hooks/useThreadIsRunning.d.ts +1 -2
  160. package/dist/react/primitive-hooks/useThreadIsRunning.d.ts.map +1 -1
  161. package/dist/react/primitive-hooks/useThreadListItemArchive.d.ts +1 -2
  162. package/dist/react/primitive-hooks/useThreadListItemArchive.d.ts.map +1 -1
  163. package/dist/react/primitive-hooks/useThreadListItemDelete.d.ts +1 -2
  164. package/dist/react/primitive-hooks/useThreadListItemDelete.d.ts.map +1 -1
  165. package/dist/react/primitive-hooks/useThreadListItemTrigger.d.ts +1 -2
  166. package/dist/react/primitive-hooks/useThreadListItemTrigger.d.ts.map +1 -1
  167. package/dist/react/primitive-hooks/useThreadListItemUnarchive.d.ts +1 -2
  168. package/dist/react/primitive-hooks/useThreadListItemUnarchive.d.ts.map +1 -1
  169. package/dist/react/primitive-hooks/useThreadListLoadMore.d.ts +1 -2
  170. package/dist/react/primitive-hooks/useThreadListLoadMore.d.ts.map +1 -1
  171. package/dist/react/primitive-hooks/useThreadListNew.d.ts +1 -2
  172. package/dist/react/primitive-hooks/useThreadListNew.d.ts.map +1 -1
  173. package/dist/react/primitive-hooks/useThreadMessageIds.d.ts +1 -2
  174. package/dist/react/primitive-hooks/useThreadMessageIds.d.ts.map +1 -1
  175. package/dist/react/primitive-hooks/useThreadMessages.d.ts +1 -2
  176. package/dist/react/primitive-hooks/useThreadMessages.d.ts.map +1 -1
  177. package/dist/react/primitive-hooks/useVoice.d.ts +3 -4
  178. package/dist/react/primitive-hooks/useVoice.d.ts.map +1 -1
  179. package/dist/react/primitives/chainOfThought/ChainOfThoughtParts.d.ts +2 -3
  180. package/dist/react/primitives/chainOfThought/ChainOfThoughtParts.d.ts.map +1 -1
  181. package/dist/react/primitives/composer/ComposerAttachments.d.ts +4 -5
  182. package/dist/react/primitives/composer/ComposerAttachments.d.ts.map +1 -1
  183. package/dist/react/primitives/composer/ComposerIf.d.ts +4 -5
  184. package/dist/react/primitives/composer/ComposerIf.d.ts.map +1 -1
  185. package/dist/react/primitives/composer/ComposerQueue.d.ts +2 -3
  186. package/dist/react/primitives/composer/ComposerQueue.d.ts.map +1 -1
  187. package/dist/react/primitives/generativeUI/GenerativeUI.d.ts +4 -5
  188. package/dist/react/primitives/generativeUI/GenerativeUI.d.ts.map +1 -1
  189. package/dist/react/primitives/generativeUI/GenerativeUI.js +27 -28
  190. package/dist/react/primitives/generativeUI/GenerativeUI.js.map +1 -1
  191. package/dist/react/primitives/message/MessageAttachments.d.ts +4 -5
  192. package/dist/react/primitives/message/MessageAttachments.d.ts.map +1 -1
  193. package/dist/react/primitives/message/MessageGroupedParts.d.ts +2 -3
  194. package/dist/react/primitives/message/MessageGroupedParts.d.ts.map +1 -1
  195. package/dist/react/primitives/message/MessageParts.d.ts +10 -10
  196. package/dist/react/primitives/message/MessageParts.d.ts.map +1 -1
  197. package/dist/react/primitives/message/MessageQuote.d.ts +2 -3
  198. package/dist/react/primitives/message/MessageQuote.d.ts.map +1 -1
  199. package/dist/react/primitives/messagePart/MessagePartInProgress.d.ts +2 -3
  200. package/dist/react/primitives/messagePart/MessagePartInProgress.d.ts.map +1 -1
  201. package/dist/react/primitives/part/PartMessages.d.ts +3 -4
  202. package/dist/react/primitives/part/PartMessages.d.ts.map +1 -1
  203. package/dist/react/primitives/thread/ThreadMessages.d.ts +7 -8
  204. package/dist/react/primitives/thread/ThreadMessages.d.ts.map +1 -1
  205. package/dist/react/primitives/thread/ThreadSuggestions.d.ts +5 -6
  206. package/dist/react/primitives/thread/ThreadSuggestions.d.ts.map +1 -1
  207. package/dist/react/primitives/threadList/ThreadListItems.d.ts +4 -5
  208. package/dist/react/primitives/threadList/ThreadListItems.d.ts.map +1 -1
  209. package/dist/react/primitives/threadListItem/ThreadListItemTitle.d.ts +2 -3
  210. package/dist/react/primitives/threadListItem/ThreadListItemTitle.d.ts.map +1 -1
  211. package/dist/react/providers/AttachmentByIndexProvider.d.ts +2 -3
  212. package/dist/react/providers/AttachmentByIndexProvider.d.ts.map +1 -1
  213. package/dist/react/providers/ChainOfThoughtByIndicesProvider.d.ts +1 -2
  214. package/dist/react/providers/ChainOfThoughtByIndicesProvider.d.ts.map +1 -1
  215. package/dist/react/providers/ChainOfThoughtPartByIndexProvider.d.ts +1 -2
  216. package/dist/react/providers/ChainOfThoughtPartByIndexProvider.d.ts.map +1 -1
  217. package/dist/react/providers/MessageByIdProvider.d.ts +1 -2
  218. package/dist/react/providers/MessageByIdProvider.d.ts.map +1 -1
  219. package/dist/react/providers/MessageByIndexProvider.d.ts +1 -2
  220. package/dist/react/providers/MessageByIndexProvider.d.ts.map +1 -1
  221. package/dist/react/providers/PartByIndexProvider.d.ts +1 -2
  222. package/dist/react/providers/PartByIndexProvider.d.ts.map +1 -1
  223. package/dist/react/providers/QueueItemByIndexProvider.d.ts +2 -3
  224. package/dist/react/providers/QueueItemByIndexProvider.d.ts.map +1 -1
  225. package/dist/react/providers/ReadonlyThreadProvider.d.ts +2 -3
  226. package/dist/react/providers/ReadonlyThreadProvider.d.ts.map +1 -1
  227. package/dist/react/providers/SuggestionByIndexProvider.d.ts +2 -3
  228. package/dist/react/providers/SuggestionByIndexProvider.d.ts.map +1 -1
  229. package/dist/react/providers/TextMessagePartProvider.d.ts +1 -2
  230. package/dist/react/providers/TextMessagePartProvider.d.ts.map +1 -1
  231. package/dist/react/providers/ThreadListItemByIndexProvider.d.ts +1 -2
  232. package/dist/react/providers/ThreadListItemByIndexProvider.d.ts.map +1 -1
  233. package/dist/react/providers/ThreadListItemRuntimeProvider.d.ts +1 -2
  234. package/dist/react/providers/ThreadListItemRuntimeProvider.d.ts.map +1 -1
  235. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.d.ts +3 -2
  236. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.d.ts.map +1 -1
  237. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js +17 -7
  238. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js.map +1 -1
  239. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts +1 -2
  240. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts.map +1 -1
  241. package/dist/react/runtimes/RemoteThreadResource.d.ts +4 -5
  242. package/dist/react/runtimes/RemoteThreadResource.d.ts.map +1 -1
  243. package/dist/react/runtimes/RuntimeAdapterProvider.d.ts +3 -3
  244. package/dist/react/runtimes/RuntimeAdapterProvider.d.ts.map +1 -1
  245. package/dist/react/runtimes/assistant-transport/commandQueue.d.ts +2 -3
  246. package/dist/react/runtimes/assistant-transport/commandQueue.d.ts.map +1 -1
  247. package/dist/react/runtimes/assistant-transport/replayBoundaryStream.d.ts +3 -4
  248. package/dist/react/runtimes/assistant-transport/replayBoundaryStream.d.ts.map +1 -1
  249. package/dist/react/runtimes/assistant-transport/runManager.d.ts +2 -3
  250. package/dist/react/runtimes/assistant-transport/runManager.d.ts.map +1 -1
  251. package/dist/react/runtimes/assistant-transport/types.d.ts +17 -18
  252. package/dist/react/runtimes/assistant-transport/types.d.ts.map +1 -1
  253. package/dist/react/runtimes/assistant-transport/useAssistantTransportRuntime.d.ts +4 -5
  254. package/dist/react/runtimes/assistant-transport/useAssistantTransportRuntime.d.ts.map +1 -1
  255. package/dist/react/runtimes/assistant-transport/useConvertedState.d.ts +1 -2
  256. package/dist/react/runtimes/assistant-transport/useConvertedState.d.ts.map +1 -1
  257. package/dist/react/runtimes/assistant-transport/useLatestRef.d.ts +1 -2
  258. package/dist/react/runtimes/assistant-transport/useLatestRef.d.ts.map +1 -1
  259. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.d.ts +2 -3
  260. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.d.ts.map +1 -1
  261. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.js +17 -4
  262. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.js.map +1 -1
  263. package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.d.ts +1 -2
  264. package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.d.ts.map +1 -1
  265. package/dist/react/runtimes/cloud/auiV0.d.ts +11 -3
  266. package/dist/react/runtimes/cloud/auiV0.d.ts.map +1 -1
  267. package/dist/react/runtimes/cloud/auiV0.js +63 -2
  268. package/dist/react/runtimes/cloud/auiV0.js.map +1 -1
  269. package/dist/react/runtimes/cloud/createCloudThreadListAdapter.d.ts +4 -5
  270. package/dist/react/runtimes/cloud/createCloudThreadListAdapter.d.ts.map +1 -1
  271. package/dist/react/runtimes/cloud/createCloudThreadListAdapterCreateFallback.d.ts +1 -2
  272. package/dist/react/runtimes/cloud/createCloudThreadListAdapterCreateFallback.d.ts.map +1 -1
  273. package/dist/react/runtimes/cloud/sdkIdentity.d.ts +1 -2
  274. package/dist/react/runtimes/cloud/sdkIdentity.d.ts.map +1 -1
  275. package/dist/react/runtimes/cloud/sdkIdentity.js +1 -1
  276. package/dist/react/runtimes/cloud/useCloudThreadListAdapter.d.ts +1 -2
  277. package/dist/react/runtimes/cloud/useCloudThreadListAdapter.d.ts.map +1 -1
  278. package/dist/react/runtimes/cloud/useCloudThreadListRuntime.d.ts +1 -2
  279. package/dist/react/runtimes/cloud/useCloudThreadListRuntime.d.ts.map +1 -1
  280. package/dist/react/runtimes/createMessageConverter.d.ts +1 -2
  281. package/dist/react/runtimes/createMessageConverter.d.ts.map +1 -1
  282. package/dist/react/runtimes/createRuntimeExtras.d.ts +3 -4
  283. package/dist/react/runtimes/createRuntimeExtras.d.ts.map +1 -1
  284. package/dist/react/runtimes/external-message-converter.d.ts +6 -6
  285. package/dist/react/runtimes/external-message-converter.d.ts.map +1 -1
  286. package/dist/react/runtimes/useExternalStoreRuntime.d.ts +1 -2
  287. package/dist/react/runtimes/useExternalStoreRuntime.d.ts.map +1 -1
  288. package/dist/react/runtimes/useExternalStoreSharedOptions.d.ts +1 -2
  289. package/dist/react/runtimes/useExternalStoreSharedOptions.d.ts.map +1 -1
  290. package/dist/react/runtimes/useLocalRuntime.d.ts +3 -4
  291. package/dist/react/runtimes/useLocalRuntime.d.ts.map +1 -1
  292. package/dist/react/runtimes/useRemoteThreadListRuntime.d.ts +1 -2
  293. package/dist/react/runtimes/useRemoteThreadListRuntime.d.ts.map +1 -1
  294. package/dist/react/runtimes/useRemoteThreadListRuntime.js +2 -2
  295. package/dist/react/runtimes/useRemoteThreadListRuntime.js.map +1 -1
  296. package/dist/react/runtimes/useRuntimeAdapters.d.ts +4 -4
  297. package/dist/react/runtimes/useRuntimeAdapters.d.ts.map +1 -1
  298. package/dist/react/runtimes/useStreamingTiming.d.ts +2 -2
  299. package/dist/react/runtimes/useStreamingTiming.d.ts.map +1 -1
  300. package/dist/react/types/MessagePartComponentTypes.d.ts +26 -27
  301. package/dist/react/types/MessagePartComponentTypes.d.ts.map +1 -1
  302. package/dist/react/types/scopes/dataRenderers.d.ts +3 -4
  303. package/dist/react/types/scopes/dataRenderers.d.ts.map +1 -1
  304. package/dist/react/types/scopes/interactables.d.ts +10 -11
  305. package/dist/react/types/scopes/interactables.d.ts.map +1 -1
  306. package/dist/react/types/scopes/tools.d.ts +4 -5
  307. package/dist/react/types/scopes/tools.d.ts.map +1 -1
  308. package/dist/react/utils/getMessageQuote.d.ts +1 -2
  309. package/dist/react/utils/getMessageQuote.d.ts.map +1 -1
  310. package/dist/react/utils/groupParts.d.ts +7 -8
  311. package/dist/react/utils/groupParts.d.ts.map +1 -1
  312. package/dist/react/utils/useJSONEqual.d.ts +2 -3
  313. package/dist/react/utils/useJSONEqual.d.ts.map +1 -1
  314. package/dist/react/utils/useJSONSchemaDependency.d.ts +1 -2
  315. package/dist/react/utils/useJSONSchemaDependency.d.ts.map +1 -1
  316. package/dist/runtime/api/assistant-runtime.d.ts +2 -3
  317. package/dist/runtime/api/assistant-runtime.d.ts.map +1 -1
  318. package/dist/runtime/api/attachment-runtime.d.ts +6 -7
  319. package/dist/runtime/api/attachment-runtime.d.ts.map +1 -1
  320. package/dist/runtime/api/bindings.d.ts +5 -6
  321. package/dist/runtime/api/bindings.d.ts.map +1 -1
  322. package/dist/runtime/api/composer-runtime.d.ts +10 -10
  323. package/dist/runtime/api/composer-runtime.d.ts.map +1 -1
  324. package/dist/runtime/api/message-part-runtime.d.ts +3 -4
  325. package/dist/runtime/api/message-part-runtime.d.ts.map +1 -1
  326. package/dist/runtime/api/message-part-runtime.js +3 -2
  327. package/dist/runtime/api/message-part-runtime.js.map +1 -1
  328. package/dist/runtime/api/message-runtime.d.ts +8 -6
  329. package/dist/runtime/api/message-runtime.d.ts.map +1 -1
  330. package/dist/runtime/api/message-runtime.js +3 -2
  331. package/dist/runtime/api/message-runtime.js.map +1 -1
  332. package/dist/runtime/api/paths.d.ts +6 -7
  333. package/dist/runtime/api/paths.d.ts.map +1 -1
  334. package/dist/runtime/api/thread-list-item-runtime.d.ts +8 -8
  335. package/dist/runtime/api/thread-list-item-runtime.d.ts.map +1 -1
  336. package/dist/runtime/api/thread-list-runtime.d.ts +4 -5
  337. package/dist/runtime/api/thread-list-runtime.d.ts.map +1 -1
  338. package/dist/runtime/api/thread-runtime.d.ts +10 -11
  339. package/dist/runtime/api/thread-runtime.d.ts.map +1 -1
  340. package/dist/runtime/base/base-assistant-runtime-core.d.ts +1 -2
  341. package/dist/runtime/base/base-assistant-runtime-core.d.ts.map +1 -1
  342. package/dist/runtime/base/base-composer-runtime-core.d.ts +1 -2
  343. package/dist/runtime/base/base-composer-runtime-core.d.ts.map +1 -1
  344. package/dist/runtime/base/base-thread-runtime-core.d.ts +8 -3
  345. package/dist/runtime/base/base-thread-runtime-core.d.ts.map +1 -1
  346. package/dist/runtime/base/base-thread-runtime-core.js +71 -27
  347. package/dist/runtime/base/base-thread-runtime-core.js.map +1 -1
  348. package/dist/runtime/base/default-edit-composer-runtime-core.d.ts +1 -2
  349. package/dist/runtime/base/default-edit-composer-runtime-core.d.ts.map +1 -1
  350. package/dist/runtime/base/default-edit-composer-runtime-core.js +12 -2
  351. package/dist/runtime/base/default-edit-composer-runtime-core.js.map +1 -1
  352. package/dist/runtime/base/default-thread-composer-runtime-core.d.ts +1 -2
  353. package/dist/runtime/base/default-thread-composer-runtime-core.d.ts.map +1 -1
  354. package/dist/runtime/base/default-thread-composer-runtime-core.js +7 -1
  355. package/dist/runtime/base/default-thread-composer-runtime-core.js.map +1 -1
  356. package/dist/runtime/branch/external-thread-branch-adapter.d.ts +1 -2
  357. package/dist/runtime/branch/external-thread-branch-adapter.d.ts.map +1 -1
  358. package/dist/runtime/interfaces/assistant-runtime-core.d.ts +1 -2
  359. package/dist/runtime/interfaces/assistant-runtime-core.d.ts.map +1 -1
  360. package/dist/runtime/interfaces/composer-runtime-core.d.ts +10 -11
  361. package/dist/runtime/interfaces/composer-runtime-core.d.ts.map +1 -1
  362. package/dist/runtime/interfaces/thread-list-runtime-core.d.ts +4 -5
  363. package/dist/runtime/interfaces/thread-list-runtime-core.d.ts.map +1 -1
  364. package/dist/runtime/interfaces/thread-runtime-core.d.ts +17 -16
  365. package/dist/runtime/interfaces/thread-runtime-core.d.ts.map +1 -1
  366. package/dist/runtime/queue/external-thread-queue-adapter.d.ts +2 -3
  367. package/dist/runtime/queue/external-thread-queue-adapter.d.ts.map +1 -1
  368. package/dist/runtime/queue/message-queue.d.ts +5 -4
  369. package/dist/runtime/queue/message-queue.d.ts.map +1 -1
  370. package/dist/runtime/queue/message-queue.js +9 -1
  371. package/dist/runtime/queue/message-queue.js.map +1 -1
  372. package/dist/runtime/queue/queue-item.d.ts +2 -3
  373. package/dist/runtime/queue/queue-item.d.ts.map +1 -1
  374. package/dist/runtime/utils/abortable-thread-load.d.ts +2 -3
  375. package/dist/runtime/utils/abortable-thread-load.d.ts.map +1 -1
  376. package/dist/runtime/utils/attachment-add-operations.d.ts +3 -4
  377. package/dist/runtime/utils/attachment-add-operations.d.ts.map +1 -1
  378. package/dist/runtime/utils/auto-status.d.ts +7 -8
  379. package/dist/runtime/utils/auto-status.d.ts.map +1 -1
  380. package/dist/runtime/utils/chat-model-adapter.d.ts +5 -6
  381. package/dist/runtime/utils/chat-model-adapter.d.ts.map +1 -1
  382. package/dist/runtime/utils/external-message-conversion.d.ts +15 -16
  383. package/dist/runtime/utils/external-message-conversion.d.ts.map +1 -1
  384. package/dist/runtime/utils/external-message-conversion.js +3 -2
  385. package/dist/runtime/utils/external-message-conversion.js.map +1 -1
  386. package/dist/runtime/utils/external-store-message.d.ts +4 -5
  387. package/dist/runtime/utils/external-store-message.d.ts.map +1 -1
  388. package/dist/runtime/utils/message-repository-session.d.ts +3 -4
  389. package/dist/runtime/utils/message-repository-session.d.ts.map +1 -1
  390. package/dist/runtime/utils/message-repository.d.ts +4 -5
  391. package/dist/runtime/utils/message-repository.d.ts.map +1 -1
  392. package/dist/runtime/utils/pending-tool-calls.d.ts +2 -3
  393. package/dist/runtime/utils/pending-tool-calls.d.ts.map +1 -1
  394. package/dist/runtime/utils/resolveToolApprovalResponse.d.ts +1 -2
  395. package/dist/runtime/utils/resolveToolApprovalResponse.d.ts.map +1 -1
  396. package/dist/runtime/utils/runtime-extras-brand.d.ts +2 -3
  397. package/dist/runtime/utils/runtime-extras-brand.d.ts.map +1 -1
  398. package/dist/runtime/utils/stored-message-parts.d.ts +21 -0
  399. package/dist/runtime/utils/stored-message-parts.d.ts.map +1 -0
  400. package/dist/runtime/utils/stored-message-parts.js +83 -0
  401. package/dist/runtime/utils/stored-message-parts.js.map +1 -0
  402. package/dist/runtime/utils/streaming-timing.d.ts +4 -5
  403. package/dist/runtime/utils/streaming-timing.d.ts.map +1 -1
  404. package/dist/runtime/utils/thread-message-like.d.ts +5 -5
  405. package/dist/runtime/utils/thread-message-like.d.ts.map +1 -1
  406. package/dist/runtime/utils/thread-message-like.js.map +1 -1
  407. package/dist/runtime/utils/thread-runtime-lifecycle.d.ts +3 -4
  408. package/dist/runtime/utils/thread-runtime-lifecycle.d.ts.map +1 -1
  409. package/dist/runtime/utils/tool-call-tree.d.ts +4 -5
  410. package/dist/runtime/utils/tool-call-tree.d.ts.map +1 -1
  411. package/dist/runtimes/assistant-transport/utils.d.ts +1 -2
  412. package/dist/runtimes/assistant-transport/utils.d.ts.map +1 -1
  413. package/dist/runtimes/external-store/external-store-adapter.d.ts +9 -6
  414. package/dist/runtimes/external-store/external-store-adapter.d.ts.map +1 -1
  415. package/dist/runtimes/external-store/external-store-runtime-core.d.ts +1 -2
  416. package/dist/runtimes/external-store/external-store-runtime-core.d.ts.map +1 -1
  417. package/dist/runtimes/external-store/external-store-shared-options.d.ts +2 -3
  418. package/dist/runtimes/external-store/external-store-shared-options.d.ts.map +1 -1
  419. package/dist/runtimes/external-store/external-store-thread-list-runtime-core.d.ts +2 -3
  420. package/dist/runtimes/external-store/external-store-thread-list-runtime-core.d.ts.map +1 -1
  421. package/dist/runtimes/external-store/external-store-thread-runtime-core.d.ts +4 -3
  422. package/dist/runtimes/external-store/external-store-thread-runtime-core.d.ts.map +1 -1
  423. package/dist/runtimes/external-store/external-store-thread-runtime-core.js +29 -6
  424. package/dist/runtimes/external-store/external-store-thread-runtime-core.js.map +1 -1
  425. package/dist/runtimes/external-store/thread-message-converter.d.ts +2 -3
  426. package/dist/runtimes/external-store/thread-message-converter.d.ts.map +1 -1
  427. package/dist/runtimes/inert/InertThreadRuntimeCore.d.ts +2 -3
  428. package/dist/runtimes/inert/InertThreadRuntimeCore.d.ts.map +1 -1
  429. package/dist/runtimes/local/local-runtime-core.d.ts +1 -2
  430. package/dist/runtimes/local/local-runtime-core.d.ts.map +1 -1
  431. package/dist/runtimes/local/local-runtime-options.d.ts +1 -2
  432. package/dist/runtimes/local/local-runtime-options.d.ts.map +1 -1
  433. package/dist/runtimes/local/local-thread-list-runtime-core.d.ts +2 -3
  434. package/dist/runtimes/local/local-thread-list-runtime-core.d.ts.map +1 -1
  435. package/dist/runtimes/local/local-thread-runtime-core.d.ts +9 -4
  436. package/dist/runtimes/local/local-thread-runtime-core.d.ts.map +1 -1
  437. package/dist/runtimes/local/local-thread-runtime-core.js +53 -9
  438. package/dist/runtimes/local/local-thread-runtime-core.js.map +1 -1
  439. package/dist/runtimes/local/should-continue.d.ts +1 -2
  440. package/dist/runtimes/local/should-continue.d.ts.map +1 -1
  441. package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.d.ts +1 -2
  442. package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.d.ts.map +1 -1
  443. package/dist/runtimes/remote-thread-list/adapter/in-memory.d.ts +1 -2
  444. package/dist/runtimes/remote-thread-list/adapter/in-memory.d.ts.map +1 -1
  445. package/dist/runtimes/remote-thread-list/adapter-changed.d.ts +1 -2
  446. package/dist/runtimes/remote-thread-list/adapter-changed.d.ts.map +1 -1
  447. package/dist/runtimes/remote-thread-list/empty-thread-core.d.ts +1 -2
  448. package/dist/runtimes/remote-thread-list/empty-thread-core.d.ts.map +1 -1
  449. package/dist/runtimes/remote-thread-list/optimistic-state.d.ts +1 -2
  450. package/dist/runtimes/remote-thread-list/optimistic-state.d.ts.map +1 -1
  451. package/dist/runtimes/remote-thread-list/remote-thread-state.d.ts +16 -17
  452. package/dist/runtimes/remote-thread-list/remote-thread-state.d.ts.map +1 -1
  453. package/dist/runtimes/remote-thread-list/title-generation.d.ts +7 -8
  454. package/dist/runtimes/remote-thread-list/title-generation.d.ts.map +1 -1
  455. package/dist/runtimes/remote-thread-list/title.d.ts +2 -3
  456. package/dist/runtimes/remote-thread-list/title.d.ts.map +1 -1
  457. package/dist/runtimes/remote-thread-list/types.d.ts +8 -9
  458. package/dist/runtimes/remote-thread-list/types.d.ts.map +1 -1
  459. package/dist/runtimes/tool-invocations/ToolInvocationTracker.d.ts +4 -5
  460. package/dist/runtimes/tool-invocations/ToolInvocationTracker.d.ts.map +1 -1
  461. package/dist/store/clients/chain-of-thought-client.d.ts +1 -2
  462. package/dist/store/clients/chain-of-thought-client.d.ts.map +1 -1
  463. package/dist/store/clients/external-thread.d.ts +3 -4
  464. package/dist/store/clients/external-thread.d.ts.map +1 -1
  465. package/dist/store/clients/external-thread.js +15 -11
  466. package/dist/store/clients/external-thread.js.map +1 -1
  467. package/dist/store/clients/model-context-client.d.ts +1 -2
  468. package/dist/store/clients/model-context-client.d.ts.map +1 -1
  469. package/dist/store/clients/no-op-composer-client.d.ts +1 -2
  470. package/dist/store/clients/no-op-composer-client.d.ts.map +1 -1
  471. package/dist/store/clients/runtime-adapter.d.ts +1 -2
  472. package/dist/store/clients/runtime-adapter.d.ts.map +1 -1
  473. package/dist/store/clients/single-thread-list.d.ts +1 -2
  474. package/dist/store/clients/single-thread-list.d.ts.map +1 -1
  475. package/dist/store/clients/suggestions.d.ts +3 -4
  476. package/dist/store/clients/suggestions.d.ts.map +1 -1
  477. package/dist/store/clients/thread-message-client.d.ts +2 -3
  478. package/dist/store/clients/thread-message-client.d.ts.map +1 -1
  479. package/dist/store/clients/thread-selection-events.d.ts +1 -2
  480. package/dist/store/clients/thread-selection-events.d.ts.map +1 -1
  481. package/dist/store/clients/thread-tasks.d.ts +3 -4
  482. package/dist/store/clients/thread-tasks.d.ts.map +1 -1
  483. package/dist/store/env.d.ts +1 -2
  484. package/dist/store/env.d.ts.map +1 -1
  485. package/dist/store/primitive-predicates.d.ts +11 -12
  486. package/dist/store/primitive-predicates.d.ts.map +1 -1
  487. package/dist/store/primitive-predicates.js +2 -2
  488. package/dist/store/primitive-predicates.js.map +1 -1
  489. package/dist/store/runtime-clients/attachment-runtime-client.d.ts +1 -2
  490. package/dist/store/runtime-clients/attachment-runtime-client.d.ts.map +1 -1
  491. package/dist/store/runtime-clients/composer-runtime-client.d.ts +1 -2
  492. package/dist/store/runtime-clients/composer-runtime-client.d.ts.map +1 -1
  493. package/dist/store/runtime-clients/handle-runtime-action.d.ts +1 -2
  494. package/dist/store/runtime-clients/handle-runtime-action.d.ts.map +1 -1
  495. package/dist/store/runtime-clients/handle-thread-list-action.d.ts +1 -2
  496. package/dist/store/runtime-clients/handle-thread-list-action.d.ts.map +1 -1
  497. package/dist/store/runtime-clients/liveRef.d.ts +1 -2
  498. package/dist/store/runtime-clients/liveRef.d.ts.map +1 -1
  499. package/dist/store/runtime-clients/message-part-runtime-client.d.ts +1 -2
  500. package/dist/store/runtime-clients/message-part-runtime-client.d.ts.map +1 -1
  501. package/dist/store/runtime-clients/message-runtime-client.d.ts +1 -2
  502. package/dist/store/runtime-clients/message-runtime-client.d.ts.map +1 -1
  503. package/dist/store/runtime-clients/thread-list-item-runtime-client.d.ts +1 -2
  504. package/dist/store/runtime-clients/thread-list-item-runtime-client.d.ts.map +1 -1
  505. package/dist/store/runtime-clients/thread-list-runtime-client.d.ts +1 -2
  506. package/dist/store/runtime-clients/thread-list-runtime-client.d.ts.map +1 -1
  507. package/dist/store/runtime-clients/thread-runtime-client.d.ts +1 -2
  508. package/dist/store/runtime-clients/thread-runtime-client.d.ts.map +1 -1
  509. package/dist/store/runtime-clients/useSubscribable.d.ts +1 -2
  510. package/dist/store/runtime-clients/useSubscribable.d.ts.map +1 -1
  511. package/dist/store/scopes/attachment.d.ts +4 -5
  512. package/dist/store/scopes/attachment.d.ts.map +1 -1
  513. package/dist/store/scopes/chain-of-thought.d.ts +5 -6
  514. package/dist/store/scopes/chain-of-thought.d.ts.map +1 -1
  515. package/dist/store/scopes/composer.d.ts +6 -7
  516. package/dist/store/scopes/composer.d.ts.map +1 -1
  517. package/dist/store/scopes/message.d.ts +6 -6
  518. package/dist/store/scopes/message.d.ts.map +1 -1
  519. package/dist/store/scopes/model-context.d.ts +3 -4
  520. package/dist/store/scopes/model-context.d.ts.map +1 -1
  521. package/dist/store/scopes/part.d.ts +4 -5
  522. package/dist/store/scopes/part.d.ts.map +1 -1
  523. package/dist/store/scopes/queue-item.d.ts +4 -4
  524. package/dist/store/scopes/queue-item.d.ts.map +1 -1
  525. package/dist/store/scopes/suggestion.d.ts +4 -5
  526. package/dist/store/scopes/suggestion.d.ts.map +1 -1
  527. package/dist/store/scopes/suggestions.d.ts +5 -6
  528. package/dist/store/scopes/suggestions.d.ts.map +1 -1
  529. package/dist/store/scopes/task.d.ts +4 -5
  530. package/dist/store/scopes/task.d.ts.map +1 -1
  531. package/dist/store/scopes/thread-list-item.d.ts +5 -6
  532. package/dist/store/scopes/thread-list-item.d.ts.map +1 -1
  533. package/dist/store/scopes/thread.d.ts +5 -6
  534. package/dist/store/scopes/thread.d.ts.map +1 -1
  535. package/dist/store/scopes/threads.d.ts +4 -5
  536. package/dist/store/scopes/threads.d.ts.map +1 -1
  537. package/dist/subscribable/subscribable.d.ts +15 -16
  538. package/dist/subscribable/subscribable.d.ts.map +1 -1
  539. package/dist/tests/remote-thread-list-test-helpers.d.ts +5 -6
  540. package/dist/tests/remote-thread-list-test-helpers.d.ts.map +1 -1
  541. package/dist/types/attachment.d.ts +9 -10
  542. package/dist/types/attachment.d.ts.map +1 -1
  543. package/dist/types/augmentations.d.ts +3 -4
  544. package/dist/types/augmentations.d.ts.map +1 -1
  545. package/dist/types/directive.d.ts +2 -3
  546. package/dist/types/directive.d.ts.map +1 -1
  547. package/dist/types/error.d.ts +8 -9
  548. package/dist/types/error.d.ts.map +1 -1
  549. package/dist/types/message.d.ts +48 -46
  550. package/dist/types/message.d.ts.map +1 -1
  551. package/dist/types/message.js.map +1 -1
  552. package/dist/types/quote.d.ts +1 -2
  553. package/dist/types/quote.d.ts.map +1 -1
  554. package/dist/types/trigger.d.ts +2 -3
  555. package/dist/types/trigger.d.ts.map +1 -1
  556. package/dist/types/unsubscribe.d.ts +1 -2
  557. package/dist/types/unsubscribe.d.ts.map +1 -1
  558. package/dist/utils/abortable-iterable.d.ts +2 -3
  559. package/dist/utils/abortable-iterable.d.ts.map +1 -1
  560. package/dist/utils/composite-context-provider.d.ts +1 -2
  561. package/dist/utils/composite-context-provider.d.ts.map +1 -1
  562. package/dist/utils/data-url.d.ts +6 -7
  563. package/dist/utils/data-url.d.ts.map +1 -1
  564. package/dist/utils/getGroupStatus.d.ts +2 -3
  565. package/dist/utils/getGroupStatus.d.ts.map +1 -1
  566. package/dist/utils/id.d.ts +3 -4
  567. package/dist/utils/id.d.ts.map +1 -1
  568. package/dist/utils/image-media-type.d.ts +1 -2
  569. package/dist/utils/image-media-type.d.ts.map +1 -1
  570. package/dist/utils/invoke-user-callback.d.ts +1 -2
  571. package/dist/utils/invoke-user-callback.d.ts.map +1 -1
  572. package/dist/utils/json/is-json-equal.d.ts +1 -2
  573. package/dist/utils/json/is-json-equal.d.ts.map +1 -1
  574. package/dist/utils/json/is-json.d.ts +4 -5
  575. package/dist/utils/json/is-json.d.ts.map +1 -1
  576. package/dist/utils/json/stable-stringify-tool-args.d.ts +2 -3
  577. package/dist/utils/json/stable-stringify-tool-args.d.ts.map +1 -1
  578. package/dist/utils/normalizePartStatus.d.ts +4 -5
  579. package/dist/utils/normalizePartStatus.d.ts.map +1 -1
  580. package/dist/utils/notify-event-listeners.d.ts +1 -2
  581. package/dist/utils/notify-event-listeners.d.ts.map +1 -1
  582. package/dist/utils/record.d.ts +1 -2
  583. package/dist/utils/record.d.ts.map +1 -1
  584. package/dist/utils/silent-runtime-action.d.ts +2 -3
  585. package/dist/utils/silent-runtime-action.d.ts.map +1 -1
  586. package/dist/utils/text.d.ts +1 -2
  587. package/dist/utils/text.d.ts.map +1 -1
  588. package/dist/utils/wire-media.d.ts +3 -4
  589. package/dist/utils/wire-media.d.ts.map +1 -1
  590. package/package.json +14 -13
  591. package/src/adapters/attachment.ts +8 -1
  592. package/src/adapters/feedback.ts +1 -0
  593. package/src/model-context/frame/provider.test.ts +45 -20
  594. package/src/react/RuntimeAdapter.test.ts +4 -1
  595. package/src/react/adapters/LocalStorageThreadListAdapter.test.ts +117 -0
  596. package/src/react/adapters/LocalStorageThreadListAdapter.tsx +27 -74
  597. package/src/react/client/Interactables.test.ts +12 -7
  598. package/src/react/client/RemoteThreadList.concurrent.test.tsx +9 -3
  599. package/src/react/client/RemoteThreadList.test.ts +5 -6
  600. package/src/react/interactables-legacy/Interactables.test.ts +9 -3
  601. package/src/react/interactables-legacy/useAssistantInteractable.test.tsx +40 -22
  602. package/src/react/model-context/useInteractable.test.tsx +56 -29
  603. package/src/react/primitive-hooks/useActionBarCopy.test.ts +5 -5
  604. package/src/react/primitives/generativeUI/GenerativeUI.test.tsx +54 -0
  605. package/src/react/primitives/generativeUI/GenerativeUI.tsx +13 -18
  606. package/src/react/primitives/message/MessageGroupedParts.test.tsx +4 -1
  607. package/src/react/primitives/thread/ThreadMessages.test.tsx +25 -7
  608. package/src/react/runtimes/RemoteThreadListHookInstanceManager.layout.test.tsx +62 -0
  609. package/src/react/runtimes/RemoteThreadListHookInstanceManager.retry.test.tsx +2 -2
  610. package/src/react/runtimes/RemoteThreadListHookInstanceManager.test.tsx +23 -20
  611. package/src/react/runtimes/RemoteThreadListHookInstanceManager.title.test.tsx +24 -17
  612. package/src/react/runtimes/RemoteThreadListHookInstanceManager.tsx +39 -24
  613. package/src/react/runtimes/assistant-transport/transport-scheduling.test.ts +73 -46
  614. package/src/react/runtimes/assistant-transport/useAssistantTransportRuntime.test.tsx +66 -1
  615. package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.test.tsx +102 -0
  616. package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.ts +24 -11
  617. package/src/react/runtimes/cloud/CloudFileAttachmentAdapter.test.ts +8 -4
  618. package/src/react/runtimes/cloud/auiV0.ts +121 -1
  619. package/src/react/runtimes/cloud/auiV0DecodeSafely.test.ts +522 -0
  620. package/src/react/runtimes/external-message-converter.test.ts +7 -3
  621. package/src/react/runtimes/remote-thread-hook-on-tap.test.ts +2 -1
  622. package/src/react/runtimes/useExternalStoreRuntime.lifecycle.test.tsx +8 -2
  623. package/src/react/runtimes/useExternalStoreRuntime.suggestions.test.tsx +6 -2
  624. package/src/react/runtimes/useRemoteThreadListRuntime.concurrent.test.tsx +84 -4
  625. package/src/react/runtimes/useRemoteThreadListRuntime.ts +5 -1
  626. package/src/runtime/api/message-part-runtime.ts +4 -1
  627. package/src/runtime/api/message-runtime.ts +15 -2
  628. package/src/runtime/base/base-thread-runtime-core.test.ts +761 -18
  629. package/src/runtime/base/base-thread-runtime-core.ts +89 -26
  630. package/src/runtime/base/default-edit-composer-runtime-core.ts +12 -2
  631. package/src/runtime/base/default-thread-composer-runtime-core.ts +12 -1
  632. package/src/runtime/interfaces/thread-runtime-core.ts +2 -0
  633. package/src/runtime/queue/message-queue.ts +11 -1
  634. package/src/runtime/utils/external-message-conversion.test.ts +43 -0
  635. package/src/runtime/utils/external-message-conversion.ts +6 -2
  636. package/src/runtime/utils/stored-message-parts.ts +174 -0
  637. package/src/runtime/utils/thread-message-like.ts +7 -2
  638. package/src/runtimes/external-store/external-store-adapter.ts +4 -0
  639. package/src/runtimes/external-store/external-store-thread-runtime-core.ts +44 -9
  640. package/src/runtimes/local/local-thread-runtime-core.test.ts +168 -12
  641. package/src/runtimes/local/local-thread-runtime-core.ts +80 -9
  642. package/src/store/clients/external-thread.ts +34 -13
  643. package/src/store/primitive-predicates.test.ts +16 -0
  644. package/src/store/primitive-predicates.ts +4 -1
  645. package/src/store/runtime-clients/thread-runtime-client.test.tsx +110 -0
  646. package/src/store/scopes/message.ts +4 -1
  647. package/src/subscribable/subscribable.test.ts +7 -2
  648. package/src/tests/attachment-adapters.test.ts +16 -1
  649. package/src/tests/auiV0Encode.test.ts +4 -0
  650. package/src/tests/base-composer-runtime-core-addAttachment.test.ts +6 -6
  651. package/src/tests/base-composer-runtime-core.test.ts +16 -5
  652. package/src/tests/composer-can-cancel.test.ts +35 -6
  653. package/src/tests/composer-can-send.test.ts +22 -0
  654. package/src/tests/default-edit-composer-runtime-core.test.ts +47 -0
  655. package/src/tests/external-store-thread-runtime-core-adapter.test.ts +229 -27
  656. package/src/tests/external-store-thread-runtime-core.test.ts +31 -0
  657. package/src/tests/external-thread-attachments.test.tsx +22 -23
  658. package/src/tests/external-thread-feedback.test.tsx +20 -7
  659. package/src/tests/external-thread-parity.test.tsx +1 -1
  660. package/src/tests/message-queue.test.ts +45 -10
  661. package/src/tests/thread-switch-events.test.tsx +11 -7
  662. package/src/tests/useRemoteThreadListRuntime-controlled.test.tsx +2 -1
  663. package/src/types/message.test.ts +19 -0
  664. package/src/types/message.ts +16 -8
@@ -3,7 +3,8 @@ import type { FeedbackAdapter } from "../../adapters/feedback";
3
3
  import type { SpeechSynthesisAdapter } from "../../adapters/speech";
4
4
  import type { RealtimeVoiceAdapter } from "../../adapters/voice";
5
5
  import type { ModelContextProvider } from "../../model-context/types";
6
- import type { AppendMessage } from "../../types/message";
6
+ import type { AppendMessage, ThreadMessage } from "../../types/message";
7
+ import type { ChatModelRunResult } from "../../runtime/utils/chat-model-adapter";
7
8
  import { CompositeContextProvider } from "../../utils/composite-context-provider";
8
9
  import type {
9
10
  AddToolResultOptions,
@@ -19,6 +20,9 @@ import { LocalRuntimeCore } from "../../runtimes/local/local-runtime-core";
19
20
 
20
21
  const createVoiceAdapter = () => {
21
22
  let volumeCallback: ((volume: number) => void) | undefined;
23
+ let statusCallback:
24
+ | ((status: RealtimeVoiceAdapter.Status) => void)
25
+ | undefined;
22
26
  let transcriptCallback:
23
27
  | ((transcript: RealtimeVoiceAdapter.TranscriptItem) => void)
24
28
  | undefined;
@@ -28,7 +32,12 @@ const createVoiceAdapter = () => {
28
32
  disconnect: vi.fn(),
29
33
  mute: vi.fn(),
30
34
  unmute: vi.fn(),
31
- onStatusChange: () => () => {},
35
+ onStatusChange: (callback) => {
36
+ statusCallback = callback;
37
+ return () => {
38
+ statusCallback = undefined;
39
+ };
40
+ },
32
41
  onTranscript: (callback) => {
33
42
  transcriptCallback = callback;
34
43
  return () => {
@@ -47,12 +56,15 @@ const createVoiceAdapter = () => {
47
56
  return {
48
57
  adapter: { connect: () => session },
49
58
  emitVolume: (volume: number) => volumeCallback?.(volume),
59
+ emitStatus: (status: RealtimeVoiceAdapter.Status) =>
60
+ statusCallback?.(status),
50
61
  emitTranscript: (transcript: RealtimeVoiceAdapter.TranscriptItem) =>
51
62
  transcriptCallback?.(transcript),
52
63
  session,
53
64
  } satisfies {
54
65
  adapter: RealtimeVoiceAdapter;
55
66
  emitVolume: (volume: number) => void;
67
+ emitStatus: (status: RealtimeVoiceAdapter.Status) => void;
56
68
  emitTranscript: (transcript: RealtimeVoiceAdapter.TranscriptItem) => void;
57
69
  session: RealtimeVoiceAdapter.Session;
58
70
  };
@@ -1077,6 +1089,571 @@ describe("BaseThreadRuntimeCore voice volume subscriptions", () => {
1077
1089
  });
1078
1090
 
1079
1091
  describe("BaseThreadRuntimeCore voice transcripts", () => {
1092
+ const createLocalVoiceThread = async () => {
1093
+ const voiceAdapter = createVoiceAdapter();
1094
+ const history = {
1095
+ load: vi.fn(async () => ({ messages: [] })),
1096
+ append: vi.fn(async () => {}),
1097
+ };
1098
+ const runtime = new LocalRuntimeCore(
1099
+ {
1100
+ adapters: {
1101
+ chatModel: {
1102
+ async run() {
1103
+ return {};
1104
+ },
1105
+ },
1106
+ history,
1107
+ voice: voiceAdapter.adapter,
1108
+ },
1109
+ },
1110
+ undefined,
1111
+ );
1112
+ const thread = runtime.threads.getMainThreadRuntimeCore();
1113
+ await thread.__internal_load();
1114
+ thread.connectVoice();
1115
+ return { history, thread, voiceAdapter };
1116
+ };
1117
+
1118
+ it("holds a queued send that becomes dispatchable while a voice session is connected", async () => {
1119
+ let resolveFirst!: (result: ChatModelRunResult) => void;
1120
+ const firstRun = new Promise<ChatModelRunResult>((resolve) => {
1121
+ resolveFirst = resolve;
1122
+ });
1123
+ let runCount = 0;
1124
+ const run = vi.fn(() =>
1125
+ ++runCount === 1 ? firstRun : Promise.resolve({}),
1126
+ );
1127
+ const voiceAdapter = createVoiceAdapter();
1128
+ const runtime = new LocalRuntimeCore(
1129
+ {
1130
+ unstable_enableMessageQueue: true,
1131
+ adapters: { chatModel: { run }, voice: voiceAdapter.adapter },
1132
+ },
1133
+ undefined,
1134
+ );
1135
+ const thread = runtime.threads.getMainThreadRuntimeCore();
1136
+ const firstMessage: AppendMessage = {
1137
+ parentId: null,
1138
+ sourceId: null,
1139
+ runConfig: {},
1140
+ role: "user",
1141
+ content: [{ type: "text", text: "first" }],
1142
+ attachments: [],
1143
+ metadata: { custom: {} },
1144
+ createdAt: new Date(),
1145
+ };
1146
+
1147
+ await thread.append(firstMessage);
1148
+ expect(run).toHaveBeenCalledOnce();
1149
+ await thread.append({
1150
+ ...firstMessage,
1151
+ parentId: thread.messages.at(-1)?.id ?? null,
1152
+ content: [{ type: "text", text: "second" }],
1153
+ steer: false,
1154
+ });
1155
+
1156
+ const deferred: Array<() => void> = [];
1157
+ const originalQueueMicrotask = globalThis.queueMicrotask;
1158
+ globalThis.queueMicrotask = (callback: () => void) => {
1159
+ deferred.push(callback);
1160
+ };
1161
+ try {
1162
+ resolveFirst({});
1163
+ await new Promise((resolve) => setTimeout(resolve, 0));
1164
+ } finally {
1165
+ globalThis.queueMicrotask = originalQueueMicrotask;
1166
+ }
1167
+ expect(thread.messages.at(-1)?.status?.type).toBe("complete");
1168
+
1169
+ thread.connectVoice();
1170
+ try {
1171
+ for (const callback of deferred) callback();
1172
+ await Promise.resolve();
1173
+ expect(run).toHaveBeenCalledOnce();
1174
+ expect(thread.getQueueItems()).toHaveLength(1);
1175
+ } finally {
1176
+ thread.disconnectVoice();
1177
+ }
1178
+ await Promise.resolve();
1179
+
1180
+ expect(run).toHaveBeenCalledTimes(2);
1181
+ expect(thread.getQueueItems()).toHaveLength(0);
1182
+ });
1183
+
1184
+ it("commits a final user transcript to the repository and history", async () => {
1185
+ const { history, thread, voiceAdapter } = await createLocalVoiceThread();
1186
+
1187
+ try {
1188
+ voiceAdapter.emitTranscript({
1189
+ role: "user",
1190
+ text: "Hello",
1191
+ isFinal: true,
1192
+ });
1193
+ const message = thread.messages[0]!;
1194
+
1195
+ expect(message.metadata.modality).toBe("voice");
1196
+ expect(history.append).toHaveBeenCalledExactlyOnceWith({
1197
+ parentId: null,
1198
+ message,
1199
+ });
1200
+ expect(thread.export().messages).toContainEqual({
1201
+ parentId: null,
1202
+ message,
1203
+ });
1204
+ } finally {
1205
+ thread.disconnectVoice();
1206
+ }
1207
+ });
1208
+
1209
+ it("commits an assistant transcript when it finalizes", async () => {
1210
+ const { history, thread, voiceAdapter } = await createLocalVoiceThread();
1211
+
1212
+ try {
1213
+ voiceAdapter.emitTranscript({ role: "assistant", text: "Partial" });
1214
+
1215
+ expect(thread.messages[0]?.status).toEqual({ type: "running" });
1216
+ expect(history.append).not.toHaveBeenCalled();
1217
+
1218
+ voiceAdapter.emitTranscript({
1219
+ role: "assistant",
1220
+ text: "Complete",
1221
+ isFinal: true,
1222
+ });
1223
+ const message = thread.messages[0]!;
1224
+
1225
+ expect(message.status).toEqual({ type: "complete", reason: "stop" });
1226
+ expect(history.append).toHaveBeenCalledExactlyOnceWith({
1227
+ parentId: null,
1228
+ message,
1229
+ });
1230
+ } finally {
1231
+ thread.disconnectVoice();
1232
+ }
1233
+ });
1234
+
1235
+ it("commits an in-flight assistant transcript when disconnecting", async () => {
1236
+ const { history, thread, voiceAdapter } = await createLocalVoiceThread();
1237
+
1238
+ voiceAdapter.emitTranscript({ role: "assistant", text: "Partial" });
1239
+ thread.disconnectVoice();
1240
+ const message = thread.messages[0]!;
1241
+
1242
+ expect(message.status).toEqual({ type: "complete", reason: "stop" });
1243
+ expect(history.append).toHaveBeenCalledExactlyOnceWith({
1244
+ parentId: null,
1245
+ message,
1246
+ });
1247
+ });
1248
+
1249
+ it("keeps committed transcripts after disconnect", async () => {
1250
+ const { thread, voiceAdapter } = await createLocalVoiceThread();
1251
+
1252
+ voiceAdapter.emitTranscript({
1253
+ role: "user",
1254
+ text: "Hello",
1255
+ isFinal: true,
1256
+ });
1257
+ const message = thread.messages[0]!;
1258
+
1259
+ thread.disconnectVoice();
1260
+
1261
+ expect(thread.messages).toEqual([message]);
1262
+ });
1263
+
1264
+ it("links the second transcript to the first", async () => {
1265
+ const { thread, voiceAdapter } = await createLocalVoiceThread();
1266
+
1267
+ try {
1268
+ voiceAdapter.emitTranscript({
1269
+ role: "user",
1270
+ text: "First",
1271
+ isFinal: true,
1272
+ });
1273
+ const first = thread.messages[0]!;
1274
+ voiceAdapter.emitTranscript({
1275
+ role: "user",
1276
+ text: "Second",
1277
+ isFinal: true,
1278
+ });
1279
+ const second = thread.messages[1]!;
1280
+
1281
+ expect(thread.export().messages).toContainEqual({
1282
+ parentId: first.id,
1283
+ message: second,
1284
+ });
1285
+ } finally {
1286
+ thread.disconnectVoice();
1287
+ }
1288
+ });
1289
+
1290
+ it("rejects a text send while a session is connected", async () => {
1291
+ const { thread, voiceAdapter } = await createLocalVoiceThread();
1292
+
1293
+ voiceAdapter.emitTranscript({
1294
+ role: "user",
1295
+ text: "Voice message",
1296
+ isFinal: true,
1297
+ });
1298
+ const transcript = thread.messages[0]!;
1299
+ const message: AppendMessage = {
1300
+ parentId: transcript.id,
1301
+ sourceId: null,
1302
+ role: "user",
1303
+ content: [{ type: "text", text: "Text message" }],
1304
+ attachments: [],
1305
+ metadata: { custom: {} },
1306
+ createdAt: new Date(),
1307
+ runConfig: {},
1308
+ startRun: false,
1309
+ };
1310
+
1311
+ await expect(thread.append(message)).rejects.toThrow(
1312
+ "Cannot send a text message while a voice session is connected",
1313
+ );
1314
+ expect(thread.export().messages).toHaveLength(1);
1315
+
1316
+ thread.disconnectVoice();
1317
+
1318
+ await expect(thread.append(message)).resolves.toBeUndefined();
1319
+ expect(thread.export().messages).toContainEqual({
1320
+ parentId: transcript.id,
1321
+ message: expect.objectContaining({ role: "user" }),
1322
+ });
1323
+ });
1324
+
1325
+ it("keeps the replacement session's hooks when a subscriber reconnects during disconnect", () => {
1326
+ class HookRuntime extends TestRuntime {
1327
+ connected = 0;
1328
+ disconnected = 0;
1329
+ protected override _onVoiceConnected() {
1330
+ this.connected += 1;
1331
+ }
1332
+ protected override _onVoiceDisconnected() {
1333
+ this.disconnected += 1;
1334
+ }
1335
+ }
1336
+ const runtime = new HookRuntime(createVoiceAdapter());
1337
+ runtime.connectVoice();
1338
+ expect(runtime.connected).toBe(1);
1339
+
1340
+ let reconnected = false;
1341
+ const unsubscribe = runtime.subscribe(() => {
1342
+ if (reconnected || runtime.voice !== undefined) return;
1343
+ reconnected = true;
1344
+ runtime.connectVoice();
1345
+ });
1346
+
1347
+ try {
1348
+ runtime.disconnectVoice();
1349
+ expect(runtime.voice).toBeDefined();
1350
+ expect(runtime.connected).toBe(2);
1351
+ expect(runtime.disconnected).toBe(0);
1352
+ } finally {
1353
+ unsubscribe();
1354
+ runtime.disconnectVoice();
1355
+ }
1356
+ expect(runtime.disconnected).toBe(1);
1357
+ });
1358
+
1359
+ it("keeps voice hooks held while replacing a session", () => {
1360
+ class HookRuntime extends TestRuntime {
1361
+ connected = 0;
1362
+ disconnected = 0;
1363
+ protected override _onVoiceConnected() {
1364
+ this.connected += 1;
1365
+ }
1366
+ protected override _onVoiceDisconnected() {
1367
+ this.disconnected += 1;
1368
+ }
1369
+ }
1370
+ const runtime = new HookRuntime(createVoiceAdapter());
1371
+
1372
+ runtime.connectVoice();
1373
+ runtime.connectVoice();
1374
+
1375
+ expect(runtime.connected).toBe(2);
1376
+ expect(runtime.disconnected).toBe(0);
1377
+
1378
+ runtime.disconnectVoice();
1379
+
1380
+ expect(runtime.disconnected).toBe(1);
1381
+ });
1382
+
1383
+ it("ignores an ended status from a replaced session", () => {
1384
+ class HookRuntime extends TestRuntime {
1385
+ disconnected = 0;
1386
+ protected override _onVoiceDisconnected() {
1387
+ this.disconnected += 1;
1388
+ }
1389
+ }
1390
+ const statusCallbacks: Array<
1391
+ (status: RealtimeVoiceAdapter.Status) => void
1392
+ > = [];
1393
+ const createSession = (): RealtimeVoiceAdapter.Session => ({
1394
+ status: { type: "running" },
1395
+ isMuted: false,
1396
+ disconnect: vi.fn(),
1397
+ mute: vi.fn(),
1398
+ unmute: vi.fn(),
1399
+ onStatusChange: (callback) => {
1400
+ statusCallbacks.push(callback);
1401
+ return () => {};
1402
+ },
1403
+ onTranscript: () => () => {},
1404
+ onModeChange: () => () => {},
1405
+ onVolumeChange: () => () => {},
1406
+ });
1407
+ const runtime = new HookRuntime({
1408
+ adapter: { connect: () => createSession() },
1409
+ emitVolume: () => {},
1410
+ emitStatus: () => {},
1411
+ emitTranscript: () => {},
1412
+ session: createSession(),
1413
+ });
1414
+
1415
+ runtime.connectVoice();
1416
+ runtime.connectVoice();
1417
+ statusCallbacks[0]!({ type: "ended", reason: "finished" });
1418
+
1419
+ try {
1420
+ expect(runtime.voice).toBeDefined();
1421
+ expect(runtime.disconnected).toBe(0);
1422
+ } finally {
1423
+ runtime.disconnectVoice();
1424
+ }
1425
+ expect(runtime.disconnected).toBe(1);
1426
+ });
1427
+
1428
+ it("releases voice hooks when a replacement cannot connect", () => {
1429
+ class HookRuntime extends TestRuntime {
1430
+ connected = 0;
1431
+ disconnected = 0;
1432
+ protected override _onVoiceConnected() {
1433
+ this.connected += 1;
1434
+ }
1435
+ protected override _onVoiceDisconnected() {
1436
+ this.disconnected += 1;
1437
+ }
1438
+ }
1439
+ const voice = createVoiceAdapter();
1440
+ const error = new Error("connection failed");
1441
+ voice.adapter.connect = vi
1442
+ .fn()
1443
+ .mockReturnValueOnce(voice.session)
1444
+ .mockImplementationOnce(() => {
1445
+ throw error;
1446
+ });
1447
+ const runtime = new HookRuntime(voice);
1448
+ runtime.connectVoice();
1449
+
1450
+ expect(() => runtime.connectVoice()).toThrow(error);
1451
+ expect(runtime.connected).toBe(1);
1452
+ expect(runtime.disconnected).toBe(1);
1453
+ });
1454
+
1455
+ it("rejects starting a voice session while a run is in progress", async () => {
1456
+ const voiceAdapter = createVoiceAdapter();
1457
+ let resolveRun!: (result: ChatModelRunResult) => void;
1458
+ const firstRun = new Promise<ChatModelRunResult>((resolve) => {
1459
+ resolveRun = resolve;
1460
+ });
1461
+ const run = vi.fn(() => firstRun);
1462
+ const runtime = new LocalRuntimeCore(
1463
+ { adapters: { chatModel: { run }, voice: voiceAdapter.adapter } },
1464
+ undefined,
1465
+ );
1466
+ const thread = runtime.threads.getMainThreadRuntimeCore();
1467
+ const pending = thread.append({
1468
+ parentId: null,
1469
+ sourceId: null,
1470
+ role: "user",
1471
+ content: [{ type: "text", text: "hello" }],
1472
+ attachments: [],
1473
+ metadata: { custom: {} },
1474
+ createdAt: new Date(),
1475
+ runConfig: {},
1476
+ });
1477
+ await new Promise((resolve) => setTimeout(resolve, 0));
1478
+ expect(run).toHaveBeenCalledOnce();
1479
+
1480
+ expect(() => thread.connectVoice()).toThrow(
1481
+ "Cannot start a voice session while a run is in progress or paused on a pending tool action",
1482
+ );
1483
+ expect(thread.voice).toBeUndefined();
1484
+
1485
+ resolveRun({});
1486
+ await pending;
1487
+
1488
+ thread.connectVoice();
1489
+ try {
1490
+ expect(thread.voice).toBeDefined();
1491
+ } finally {
1492
+ thread.disconnectVoice();
1493
+ }
1494
+ });
1495
+
1496
+ it("rejects starting a voice session while a run is paused on a tool action", () => {
1497
+ const voiceAdapter = createVoiceAdapter();
1498
+ const runtime = new LocalRuntimeCore(
1499
+ {
1500
+ adapters: {
1501
+ chatModel: {
1502
+ async run() {
1503
+ return {};
1504
+ },
1505
+ },
1506
+ voice: voiceAdapter.adapter,
1507
+ },
1508
+ },
1509
+ undefined,
1510
+ );
1511
+ const thread = runtime.threads.getMainThreadRuntimeCore();
1512
+ thread.reset([
1513
+ {
1514
+ id: "user",
1515
+ role: "user",
1516
+ content: [{ type: "text", text: "Use the tool" }],
1517
+ },
1518
+ {
1519
+ id: "assistant",
1520
+ role: "assistant",
1521
+ content: [
1522
+ {
1523
+ type: "tool-call",
1524
+ toolCallId: "tool-call",
1525
+ toolName: "tool",
1526
+ args: {},
1527
+ argsText: "{}",
1528
+ },
1529
+ ],
1530
+ status: { type: "requires-action", reason: "tool-calls" },
1531
+ },
1532
+ ]);
1533
+
1534
+ expect(() => thread.connectVoice()).toThrow(
1535
+ "Cannot start a voice session while a run is in progress or paused on a pending tool action",
1536
+ );
1537
+ expect(thread.voice).toBeUndefined();
1538
+ });
1539
+
1540
+ it("reloads committed transcripts from history into a fresh runtime", async () => {
1541
+ const items: Array<{ parentId: string | null; message: ThreadMessage }> =
1542
+ [];
1543
+ const history = {
1544
+ load: async () => ({
1545
+ messages: items,
1546
+ headId: items.at(-1)?.message.id ?? null,
1547
+ }),
1548
+ append: async (item: {
1549
+ parentId: string | null;
1550
+ message: ThreadMessage;
1551
+ }) => {
1552
+ items.push(item);
1553
+ },
1554
+ };
1555
+ const chatModel = {
1556
+ async run() {
1557
+ return {};
1558
+ },
1559
+ };
1560
+ const voiceAdapter = createVoiceAdapter();
1561
+ const first = new LocalRuntimeCore(
1562
+ { adapters: { chatModel, history, voice: voiceAdapter.adapter } },
1563
+ undefined,
1564
+ );
1565
+ const thread = first.threads.getMainThreadRuntimeCore();
1566
+ await new Promise((resolve) => setTimeout(resolve, 0));
1567
+ thread.connectVoice();
1568
+ voiceAdapter.emitTranscript({ role: "user", text: "Hi", isFinal: true });
1569
+ voiceAdapter.emitTranscript({
1570
+ role: "assistant",
1571
+ text: "Hello",
1572
+ isFinal: true,
1573
+ });
1574
+ thread.disconnectVoice();
1575
+ await new Promise((resolve) => setTimeout(resolve, 0));
1576
+ expect(items).toHaveLength(2);
1577
+
1578
+ const second = new LocalRuntimeCore(
1579
+ { adapters: { chatModel, history } },
1580
+ undefined,
1581
+ );
1582
+ const reloaded = second.threads.getMainThreadRuntimeCore();
1583
+ await reloaded.__internal_load();
1584
+
1585
+ expect(reloaded.messages.map((message) => message.role)).toEqual([
1586
+ "user",
1587
+ "assistant",
1588
+ ]);
1589
+ expect(reloaded.messages[1]?.metadata.modality).toBe("voice");
1590
+ });
1591
+
1592
+ it("rejects starting a voice session while a send awaits initialization", async () => {
1593
+ const voiceAdapter = createVoiceAdapter();
1594
+ const run = vi.fn(async () => ({}));
1595
+ const runtime = new LocalRuntimeCore(
1596
+ { adapters: { chatModel: { run }, voice: voiceAdapter.adapter } },
1597
+ undefined,
1598
+ );
1599
+ const thread = runtime.threads.getMainThreadRuntimeCore();
1600
+ let release!: () => void;
1601
+ const barrier = new Promise<void>((resolve) => {
1602
+ release = resolve;
1603
+ });
1604
+ thread.__internal_setGetInitializePromise(() => barrier);
1605
+ const pending = thread.append({
1606
+ parentId: null,
1607
+ sourceId: null,
1608
+ role: "user",
1609
+ content: [{ type: "text", text: "hello" }],
1610
+ attachments: [],
1611
+ metadata: { custom: {} },
1612
+ createdAt: new Date(),
1613
+ runConfig: {},
1614
+ });
1615
+ await new Promise((resolve) => setTimeout(resolve, 0));
1616
+ expect(run).not.toHaveBeenCalled();
1617
+
1618
+ expect(() => thread.connectVoice()).toThrow(
1619
+ "Cannot start a voice session while a run is in progress or paused on a pending tool action",
1620
+ );
1621
+
1622
+ release();
1623
+ await pending;
1624
+ expect(run).toHaveBeenCalledOnce();
1625
+
1626
+ thread.connectVoice();
1627
+ try {
1628
+ expect(thread.voice).toBeDefined();
1629
+ } finally {
1630
+ thread.disconnectVoice();
1631
+ }
1632
+ });
1633
+
1634
+ it("rejects opening an edit while connected", async () => {
1635
+ const { thread, voiceAdapter } = await createLocalVoiceThread();
1636
+
1637
+ try {
1638
+ voiceAdapter.emitTranscript({
1639
+ role: "user",
1640
+ text: "Hello",
1641
+ isFinal: true,
1642
+ });
1643
+ const transcript = thread.messages[0]!;
1644
+
1645
+ expect(() => thread.beginEdit(transcript.id)).toThrow(
1646
+ "Cannot edit a message while a voice session is connected",
1647
+ );
1648
+
1649
+ thread.disconnectVoice();
1650
+
1651
+ expect(() => thread.beginEdit(transcript.id)).not.toThrow();
1652
+ } finally {
1653
+ thread.disconnectVoice();
1654
+ }
1655
+ });
1656
+
1080
1657
  it("speaks an assistant transcript", () => {
1081
1658
  const voiceAdapter = createVoiceAdapter();
1082
1659
  const speech = {
@@ -1176,11 +1753,41 @@ describe("BaseThreadRuntimeCore voice transcripts", () => {
1176
1753
  const message = runtime.messages[0]!;
1177
1754
 
1178
1755
  expect(() =>
1179
- runtime.submitFeedback({ messageId: message.id, type: "positive" }),
1756
+ runtime.submitFeedback({
1757
+ messageId: message.id,
1758
+ type: "positive",
1759
+ comment: "Helpful summary",
1760
+ }),
1180
1761
  ).not.toThrow();
1181
1762
  expect(feedback.submit).toHaveBeenCalledExactlyOnceWith({
1182
1763
  message,
1183
1764
  type: "positive",
1765
+ comment: "Helpful summary",
1766
+ });
1767
+ expect(runtime.messages[0]?.metadata.submittedFeedback).toEqual({
1768
+ type: "positive",
1769
+ comment: "Helpful summary",
1770
+ });
1771
+
1772
+ const rated = runtime.messages[0]!;
1773
+ runtime.submitFeedback({
1774
+ messageId: message.id,
1775
+ type: "negative",
1776
+ comment: " ",
1777
+ });
1778
+ expect(feedback.submit).toHaveBeenLastCalledWith({
1779
+ message: rated,
1780
+ type: "negative",
1781
+ });
1782
+ expect(runtime.messages[0]?.metadata.submittedFeedback).toEqual({
1783
+ type: "negative",
1784
+ });
1785
+
1786
+ const rerated = runtime.messages[0]!;
1787
+ runtime.submitFeedback({ messageId: message.id, type: "positive" });
1788
+ expect(feedback.submit).toHaveBeenLastCalledWith({
1789
+ message: rerated,
1790
+ type: "positive",
1184
1791
  });
1185
1792
  expect(runtime.messages[0]?.metadata.submittedFeedback).toEqual({
1186
1793
  type: "positive",
@@ -1190,7 +1797,31 @@ describe("BaseThreadRuntimeCore voice transcripts", () => {
1190
1797
  }
1191
1798
  });
1192
1799
 
1193
- it("rejects an edit resubmission of a transcript before any side effect", async () => {
1800
+ it("marks transcript feedback locally without an adapter", () => {
1801
+ const voiceAdapter = createVoiceAdapter();
1802
+ const runtime = new TestRuntime(voiceAdapter);
1803
+ runtime.connectVoice();
1804
+
1805
+ try {
1806
+ voiceAdapter.emitTranscript({
1807
+ role: "assistant",
1808
+ text: "Hello",
1809
+ isFinal: true,
1810
+ });
1811
+ const message = runtime.messages[0]!;
1812
+
1813
+ expect(() =>
1814
+ runtime.submitFeedback({ messageId: message.id, type: "negative" }),
1815
+ ).not.toThrow();
1816
+ expect(runtime.messages[0]?.metadata.submittedFeedback).toEqual({
1817
+ type: "negative",
1818
+ });
1819
+ } finally {
1820
+ runtime.disconnectVoice();
1821
+ }
1822
+ });
1823
+
1824
+ it("blocks an edit while connected and accepts it once the session ends", async () => {
1194
1825
  const voiceAdapter = createVoiceAdapter();
1195
1826
  const run = vi.fn(async () => ({}));
1196
1827
  const runtime = new LocalRuntimeCore(
@@ -1218,31 +1849,28 @@ describe("BaseThreadRuntimeCore voice transcripts", () => {
1218
1849
  };
1219
1850
 
1220
1851
  await expect(thread.append(edit)).rejects.toThrow(
1221
- "Voice transcript messages cannot be edited",
1852
+ "Cannot send a text message while a voice session is connected",
1222
1853
  );
1223
1854
  await expect(thread.append({ ...edit, startRun: false })).rejects.toThrow(
1224
- "Voice transcript messages cannot be edited",
1855
+ "Cannot send a text message while a voice session is connected",
1225
1856
  );
1226
1857
  expect(run).not.toHaveBeenCalled();
1227
1858
  expect(thread.messages).toHaveLength(1);
1859
+
1860
+ thread.disconnectVoice();
1861
+
1862
+ await thread.append(edit);
1863
+ expect(run).toHaveBeenCalledOnce();
1228
1864
  } finally {
1229
1865
  thread.disconnectVoice();
1230
1866
  }
1231
1867
  });
1232
1868
 
1233
- it("rejects reloading a transcript", async () => {
1869
+ it("blocks a reload while connected and allows it once the session ends", async () => {
1234
1870
  const voiceAdapter = createVoiceAdapter();
1871
+ const run = vi.fn(async () => ({}));
1235
1872
  const runtime = new LocalRuntimeCore(
1236
- {
1237
- adapters: {
1238
- chatModel: {
1239
- async run() {
1240
- return {};
1241
- },
1242
- },
1243
- voice: voiceAdapter.adapter,
1244
- },
1245
- },
1873
+ { adapters: { chatModel: { run }, voice: voiceAdapter.adapter } },
1246
1874
  undefined,
1247
1875
  );
1248
1876
  const thread = runtime.threads.getMainThreadRuntimeCore();
@@ -1262,7 +1890,121 @@ describe("BaseThreadRuntimeCore voice transcripts", () => {
1262
1890
  sourceId: message.id,
1263
1891
  runConfig: {},
1264
1892
  }),
1265
- ).rejects.toThrow("Voice transcript messages cannot be reloaded");
1893
+ ).rejects.toThrow(
1894
+ "Cannot start a run while a voice session is connected",
1895
+ );
1896
+ expect(run).not.toHaveBeenCalled();
1897
+
1898
+ thread.disconnectVoice();
1899
+
1900
+ await thread.startRun({
1901
+ parentId: null,
1902
+ sourceId: message.id,
1903
+ runConfig: {},
1904
+ });
1905
+ expect(run).toHaveBeenCalledOnce();
1906
+ } finally {
1907
+ thread.disconnectVoice();
1908
+ }
1909
+ });
1910
+
1911
+ it("blocks an approval response while connected before deciding it", () => {
1912
+ const voiceAdapter = createVoiceAdapter();
1913
+ const run = vi.fn(async () => ({}));
1914
+ const runtime = new LocalRuntimeCore(
1915
+ { adapters: { chatModel: { run }, voice: voiceAdapter.adapter } },
1916
+ undefined,
1917
+ );
1918
+ const thread = runtime.threads.getMainThreadRuntimeCore();
1919
+ thread.connectVoice();
1920
+ thread.reset([
1921
+ {
1922
+ id: "user",
1923
+ role: "user",
1924
+ content: [{ type: "text", text: "Use the tool" }],
1925
+ },
1926
+ {
1927
+ id: "assistant",
1928
+ role: "assistant",
1929
+ content: [
1930
+ {
1931
+ type: "tool-call",
1932
+ toolCallId: "tool-call",
1933
+ toolName: "tool",
1934
+ args: {},
1935
+ argsText: "{}",
1936
+ approval: { id: "approval-1" },
1937
+ },
1938
+ ],
1939
+ status: { type: "requires-action", reason: "interrupt" },
1940
+ },
1941
+ ]);
1942
+
1943
+ try {
1944
+ expect(() =>
1945
+ thread.respondToToolApproval({
1946
+ approvalId: "approval-1",
1947
+ approved: true,
1948
+ }),
1949
+ ).toThrow(
1950
+ "Cannot respond to a tool approval while a voice session is connected",
1951
+ );
1952
+ const part = thread.messages[1]!.content[0]!;
1953
+ expect(
1954
+ part.type === "tool-call" && part.approval?.approved,
1955
+ ).toBeUndefined();
1956
+ expect(run).not.toHaveBeenCalled();
1957
+ } finally {
1958
+ thread.disconnectVoice();
1959
+ }
1960
+ });
1961
+
1962
+ it("blocks a tool result continuation while connected", () => {
1963
+ const voiceAdapter = createVoiceAdapter();
1964
+ const run = vi.fn(async () => ({}));
1965
+ const runtime = new LocalRuntimeCore(
1966
+ { adapters: { chatModel: { run }, voice: voiceAdapter.adapter } },
1967
+ undefined,
1968
+ );
1969
+ const thread = runtime.threads.getMainThreadRuntimeCore();
1970
+ const messageId = "assistant";
1971
+ const toolCallId = "tool-call";
1972
+ thread.connectVoice();
1973
+ thread.reset([
1974
+ {
1975
+ id: "user",
1976
+ role: "user",
1977
+ content: [{ type: "text", text: "Use the tool" }],
1978
+ },
1979
+ {
1980
+ id: messageId,
1981
+ role: "assistant",
1982
+ content: [
1983
+ {
1984
+ type: "tool-call",
1985
+ toolCallId,
1986
+ toolName: "tool",
1987
+ args: {},
1988
+ argsText: "{}",
1989
+ },
1990
+ ],
1991
+ status: { type: "requires-action", reason: "tool-calls" },
1992
+ },
1993
+ ]);
1994
+
1995
+ try {
1996
+ expect(() =>
1997
+ thread.addToolResult({
1998
+ messageId,
1999
+ toolCallId,
2000
+ toolName: "tool",
2001
+ result: "done",
2002
+ isError: false,
2003
+ }),
2004
+ ).toThrow("Cannot add a tool result while a voice session is connected");
2005
+ expect(run).not.toHaveBeenCalled();
2006
+ const part = thread.messages[1]!.content[0]!;
2007
+ expect(part).not.toHaveProperty("result");
1266
2008
  } finally {
1267
2009
  thread.disconnectVoice();
1268
2010
  }
@@ -1279,6 +2021,7 @@ describe("BaseThreadRuntimeCore voice transcripts", () => {
1279
2021
  text: "Hello",
1280
2022
  isFinal: true,
1281
2023
  });
2024
+ voiceAdapter.emitStatus({ type: "ended", reason: "finished" });
1282
2025
 
1283
2026
  expect(() => runtime.beginEdit(runtime.messages[0]!.id)).toThrow(
1284
2027
  "Voice transcript messages cannot be edited",