@assistant-ui/core 0.2.20 → 0.2.22

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 (610) hide show
  1. package/dist/adapters/attachment.d.ts +2 -2
  2. package/dist/adapters/attachment.d.ts.map +1 -1
  3. package/dist/adapters/attachment.js +14 -7
  4. package/dist/adapters/attachment.js.map +1 -1
  5. package/dist/adapters/directive-formatter.d.ts +0 -1
  6. package/dist/adapters/directive-formatter.d.ts.map +1 -1
  7. package/dist/adapters/feedback.d.ts +0 -1
  8. package/dist/adapters/feedback.d.ts.map +1 -1
  9. package/dist/adapters/index.d.ts +2 -2
  10. package/dist/adapters/index.js +2 -1
  11. package/dist/adapters/speech.d.ts +0 -1
  12. package/dist/adapters/speech.d.ts.map +1 -1
  13. package/dist/adapters/speech.js +9 -2
  14. package/dist/adapters/speech.js.map +1 -1
  15. package/dist/adapters/suggestion.d.ts +16 -2
  16. package/dist/adapters/suggestion.d.ts.map +1 -1
  17. package/dist/adapters/suggestion.js +36 -0
  18. package/dist/adapters/suggestion.js.map +1 -0
  19. package/dist/adapters/thread-history.d.ts +2 -2
  20. package/dist/adapters/thread-history.d.ts.map +1 -1
  21. package/dist/adapters/trigger.d.ts +5 -3
  22. package/dist/adapters/trigger.d.ts.map +1 -1
  23. package/dist/adapters/voice.d.ts +0 -1
  24. package/dist/adapters/voice.d.ts.map +1 -1
  25. package/dist/adapters/voice.js +13 -5
  26. package/dist/adapters/voice.js.map +1 -1
  27. package/dist/index.d.ts +4 -3
  28. package/dist/index.js +3 -1
  29. package/dist/index.js.map +1 -1
  30. package/dist/internal/duplicate-detection.d.ts.map +1 -1
  31. package/dist/internal.d.ts +9 -1
  32. package/dist/internal.js +8 -2
  33. package/dist/model-context/frame/host.d.ts +1 -1
  34. package/dist/model-context/frame/host.d.ts.map +1 -1
  35. package/dist/model-context/frame/host.js +5 -0
  36. package/dist/model-context/frame/host.js.map +1 -1
  37. package/dist/model-context/frame/provider.d.ts +0 -1
  38. package/dist/model-context/frame/provider.d.ts.map +1 -1
  39. package/dist/model-context/frame/provider.js +1 -0
  40. package/dist/model-context/frame/provider.js.map +1 -1
  41. package/dist/model-context/frame/types.d.ts.map +1 -1
  42. package/dist/model-context/interactable-composer-metadata.d.ts +4 -2
  43. package/dist/model-context/interactable-composer-metadata.d.ts.map +1 -1
  44. package/dist/model-context/interactable-composer-metadata.js.map +1 -1
  45. package/dist/model-context/registry-handles.d.ts +0 -1
  46. package/dist/model-context/registry-handles.d.ts.map +1 -1
  47. package/dist/model-context/registry.d.ts +0 -1
  48. package/dist/model-context/registry.d.ts.map +1 -1
  49. package/dist/model-context/tool.d.ts +23 -9
  50. package/dist/model-context/tool.d.ts.map +1 -1
  51. package/dist/model-context/tool.js +0 -25
  52. package/dist/model-context/tool.js.map +1 -1
  53. package/dist/model-context/types.d.ts +0 -1
  54. package/dist/model-context/types.d.ts.map +1 -1
  55. package/dist/react/AssistantProvider.d.ts +0 -1
  56. package/dist/react/AssistantProvider.d.ts.map +1 -1
  57. package/dist/react/AssistantProvider.js.map +1 -1
  58. package/dist/react/AssistantRuntimeProvider.d.ts +1 -6
  59. package/dist/react/AssistantRuntimeProvider.d.ts.map +1 -1
  60. package/dist/react/RuntimeAdapter.d.ts +1 -0
  61. package/dist/react/RuntimeAdapter.d.ts.map +1 -1
  62. package/dist/react/adapters/LocalStorageThreadListAdapter.d.ts +13 -2
  63. package/dist/react/adapters/LocalStorageThreadListAdapter.d.ts.map +1 -1
  64. package/dist/react/adapters/LocalStorageThreadListAdapter.js +196 -54
  65. package/dist/react/adapters/LocalStorageThreadListAdapter.js.map +1 -1
  66. package/dist/react/adapters/TitleGenerationAdapter.d.ts +0 -1
  67. package/dist/react/adapters/TitleGenerationAdapter.d.ts.map +1 -1
  68. package/dist/react/client/DataRenderers.d.ts +0 -1
  69. package/dist/react/client/DataRenderers.d.ts.map +1 -1
  70. package/dist/react/client/Interactables.d.ts +0 -1
  71. package/dist/react/client/Interactables.d.ts.map +1 -1
  72. package/dist/react/client/Interactables.js.map +1 -1
  73. package/dist/react/client/Tools.d.ts +3 -2
  74. package/dist/react/client/Tools.d.ts.map +1 -1
  75. package/dist/react/client/interactable-model-context.d.ts +0 -1
  76. package/dist/react/client/interactable-model-context.d.ts.map +1 -1
  77. package/dist/react/index.d.ts +2 -2
  78. package/dist/react/interactables-legacy/Interactables.d.ts +0 -1
  79. package/dist/react/interactables-legacy/Interactables.d.ts.map +1 -1
  80. package/dist/react/interactables-legacy/interactable-model-context.d.ts +0 -1
  81. package/dist/react/interactables-legacy/interactable-model-context.d.ts.map +1 -1
  82. package/dist/react/interactables-legacy/scopes.d.ts +4 -2
  83. package/dist/react/interactables-legacy/scopes.d.ts.map +1 -1
  84. package/dist/react/interactables-legacy/useAssistantInteractable.d.ts +0 -1
  85. package/dist/react/interactables-legacy/useAssistantInteractable.d.ts.map +1 -1
  86. package/dist/react/interactables-legacy/useInteractableState.d.ts.map +1 -1
  87. package/dist/react/model-context/define-mcp-toolkit.d.ts +19 -4
  88. package/dist/react/model-context/define-mcp-toolkit.d.ts.map +1 -1
  89. package/dist/react/model-context/define-mcp-toolkit.js +17 -5
  90. package/dist/react/model-context/define-mcp-toolkit.js.map +1 -1
  91. package/dist/react/model-context/define-toolkit.d.ts +1 -2
  92. package/dist/react/model-context/define-toolkit.d.ts.map +1 -1
  93. package/dist/react/model-context/external-tool.d.ts.map +1 -1
  94. package/dist/react/model-context/human-tool.d.ts.map +1 -1
  95. package/dist/react/model-context/interactableTool.d.ts +2 -2
  96. package/dist/react/model-context/interactableTool.d.ts.map +1 -1
  97. package/dist/react/model-context/makeAssistantDataUI.d.ts +2 -2
  98. package/dist/react/model-context/makeAssistantDataUI.d.ts.map +1 -1
  99. package/dist/react/model-context/makeAssistantTool.d.ts +2 -2
  100. package/dist/react/model-context/makeAssistantTool.d.ts.map +1 -1
  101. package/dist/react/model-context/makeAssistantToolUI.d.ts +2 -2
  102. package/dist/react/model-context/makeAssistantToolUI.d.ts.map +1 -1
  103. package/dist/react/model-context/provider-tool.d.ts +0 -1
  104. package/dist/react/model-context/provider-tool.d.ts.map +1 -1
  105. package/dist/react/model-context/stub-tool.d.ts.map +1 -1
  106. package/dist/react/model-context/toolbox.d.ts +5 -5
  107. package/dist/react/model-context/toolbox.d.ts.map +1 -1
  108. package/dist/react/model-context/useAssistantContext.d.ts +1 -0
  109. package/dist/react/model-context/useAssistantContext.d.ts.map +1 -1
  110. package/dist/react/model-context/useAssistantDataUI.d.ts +3 -2
  111. package/dist/react/model-context/useAssistantDataUI.d.ts.map +1 -1
  112. package/dist/react/model-context/useAssistantInstructions.d.ts +1 -0
  113. package/dist/react/model-context/useAssistantInstructions.d.ts.map +1 -1
  114. package/dist/react/model-context/useAssistantTool.d.ts +4 -2
  115. package/dist/react/model-context/useAssistantTool.d.ts.map +1 -1
  116. package/dist/react/model-context/useAssistantToolUI.d.ts +3 -2
  117. package/dist/react/model-context/useAssistantToolUI.d.ts.map +1 -1
  118. package/dist/react/model-context/useAuiToolOverrides.d.ts +0 -1
  119. package/dist/react/model-context/useAuiToolOverrides.d.ts.map +1 -1
  120. package/dist/react/model-context/useInlineRender.d.ts +0 -1
  121. package/dist/react/model-context/useInlineRender.d.ts.map +1 -1
  122. package/dist/react/model-context/useInteractable.d.ts +7 -4
  123. package/dist/react/model-context/useInteractable.d.ts.map +1 -1
  124. package/dist/react/model-context/useInteractable.js.map +1 -1
  125. package/dist/react/model-context/useInteractableState.d.ts.map +1 -1
  126. package/dist/react/model-context/useInteractableVersions.d.ts +0 -1
  127. package/dist/react/model-context/useInteractableVersions.d.ts.map +1 -1
  128. package/dist/react/model-context/useToolArgsStatus.d.ts +3 -1
  129. package/dist/react/model-context/useToolArgsStatus.d.ts.map +1 -1
  130. package/dist/react/primitive-hooks/useActionBarCopy.d.ts +1 -4
  131. package/dist/react/primitive-hooks/useActionBarCopy.d.ts.map +1 -1
  132. package/dist/react/primitive-hooks/useActionBarCopy.js +13 -13
  133. package/dist/react/primitive-hooks/useActionBarCopy.js.map +1 -1
  134. package/dist/react/primitive-hooks/useActionBarEdit.d.ts.map +1 -1
  135. package/dist/react/primitive-hooks/useActionBarFeedback.d.ts.map +1 -1
  136. package/dist/react/primitive-hooks/useActionBarReload.d.ts.map +1 -1
  137. package/dist/react/primitive-hooks/useActionBarSpeak.d.ts.map +1 -1
  138. package/dist/react/primitive-hooks/useActionBarStopSpeaking.d.ts.map +1 -1
  139. package/dist/react/primitive-hooks/useBranchPickerNext.d.ts.map +1 -1
  140. package/dist/react/primitive-hooks/useBranchPickerPrevious.d.ts.map +1 -1
  141. package/dist/react/primitive-hooks/useComposerAddAttachment.d.ts +0 -1
  142. package/dist/react/primitive-hooks/useComposerAddAttachment.d.ts.map +1 -1
  143. package/dist/react/primitive-hooks/useComposerCancel.d.ts.map +1 -1
  144. package/dist/react/primitive-hooks/useComposerDictate.d.ts.map +1 -1
  145. package/dist/react/primitive-hooks/useComposerSend.d.ts +0 -1
  146. package/dist/react/primitive-hooks/useComposerSend.d.ts.map +1 -1
  147. package/dist/react/primitive-hooks/useEditComposerCancel.d.ts.map +1 -1
  148. package/dist/react/primitive-hooks/useEditComposerSend.d.ts.map +1 -1
  149. package/dist/react/primitive-hooks/useMessageBranching.d.ts.map +1 -1
  150. package/dist/react/primitive-hooks/useMessageError.d.ts.map +1 -1
  151. package/dist/react/primitive-hooks/useMessageError.js +5 -1
  152. package/dist/react/primitive-hooks/useMessageError.js.map +1 -1
  153. package/dist/react/primitive-hooks/useMessageReload.d.ts.map +1 -1
  154. package/dist/react/primitive-hooks/useSuggestionTrigger.d.ts +1 -5
  155. package/dist/react/primitive-hooks/useSuggestionTrigger.d.ts.map +1 -1
  156. package/dist/react/primitive-hooks/useThreadIsEmpty.d.ts.map +1 -1
  157. package/dist/react/primitive-hooks/useThreadIsRunning.d.ts.map +1 -1
  158. package/dist/react/primitive-hooks/useThreadListItemArchive.d.ts.map +1 -1
  159. package/dist/react/primitive-hooks/useThreadListItemDelete.d.ts.map +1 -1
  160. package/dist/react/primitive-hooks/useThreadListItemTrigger.d.ts.map +1 -1
  161. package/dist/react/primitive-hooks/useThreadListItemUnarchive.d.ts.map +1 -1
  162. package/dist/react/primitive-hooks/useThreadListLoadMore.d.ts.map +1 -1
  163. package/dist/react/primitive-hooks/useThreadListNew.d.ts.map +1 -1
  164. package/dist/react/primitive-hooks/useThreadMessageIds.d.ts.map +1 -1
  165. package/dist/react/primitive-hooks/useThreadMessages.d.ts +0 -1
  166. package/dist/react/primitive-hooks/useThreadMessages.d.ts.map +1 -1
  167. package/dist/react/primitive-hooks/useVoice.d.ts +0 -1
  168. package/dist/react/primitive-hooks/useVoice.d.ts.map +1 -1
  169. package/dist/react/primitives/chainOfThought/ChainOfThoughtParts.d.ts +7 -4
  170. package/dist/react/primitives/chainOfThought/ChainOfThoughtParts.d.ts.map +1 -1
  171. package/dist/react/primitives/chainOfThought/ChainOfThoughtParts.js +1 -1
  172. package/dist/react/primitives/chainOfThought/ChainOfThoughtParts.js.map +1 -1
  173. package/dist/react/primitives/composer/ComposerAttachments.d.ts +4 -3
  174. package/dist/react/primitives/composer/ComposerAttachments.d.ts.map +1 -1
  175. package/dist/react/primitives/composer/ComposerAttachments.js.map +1 -1
  176. package/dist/react/primitives/composer/ComposerIf.d.ts +4 -3
  177. package/dist/react/primitives/composer/ComposerIf.d.ts.map +1 -1
  178. package/dist/react/primitives/composer/ComposerQueue.d.ts +2 -2
  179. package/dist/react/primitives/composer/ComposerQueue.d.ts.map +1 -1
  180. package/dist/react/primitives/composer/ComposerQueue.js.map +1 -1
  181. package/dist/react/primitives/generativeUI/GenerativeUI.d.ts +2 -2
  182. package/dist/react/primitives/generativeUI/GenerativeUI.d.ts.map +1 -1
  183. package/dist/react/primitives/message/MessageAttachments.d.ts +4 -3
  184. package/dist/react/primitives/message/MessageAttachments.d.ts.map +1 -1
  185. package/dist/react/primitives/message/MessageAttachments.js.map +1 -1
  186. package/dist/react/primitives/message/MessageGroupedParts.d.ts +1 -6
  187. package/dist/react/primitives/message/MessageGroupedParts.d.ts.map +1 -1
  188. package/dist/react/primitives/message/MessageGroupedParts.js.map +1 -1
  189. package/dist/react/primitives/message/MessageParts.d.ts +44 -25
  190. package/dist/react/primitives/message/MessageParts.d.ts.map +1 -1
  191. package/dist/react/primitives/message/MessageParts.js +48 -37
  192. package/dist/react/primitives/message/MessageParts.js.map +1 -1
  193. package/dist/react/primitives/message/MessageQuote.d.ts +2 -2
  194. package/dist/react/primitives/message/MessageQuote.d.ts.map +1 -1
  195. package/dist/react/primitives/messagePart/MessagePartInProgress.d.ts +0 -1
  196. package/dist/react/primitives/messagePart/MessagePartInProgress.d.ts.map +1 -1
  197. package/dist/react/primitives/part/PartMessages.d.ts +2 -2
  198. package/dist/react/primitives/part/PartMessages.d.ts.map +1 -1
  199. package/dist/react/primitives/part/PartMessages.js.map +1 -1
  200. package/dist/react/primitives/thread/ThreadMessages.d.ts +35 -17
  201. package/dist/react/primitives/thread/ThreadMessages.d.ts.map +1 -1
  202. package/dist/react/primitives/thread/ThreadMessages.js.map +1 -1
  203. package/dist/react/primitives/thread/ThreadSuggestions.d.ts +6 -4
  204. package/dist/react/primitives/thread/ThreadSuggestions.d.ts.map +1 -1
  205. package/dist/react/primitives/thread/ThreadSuggestions.js.map +1 -1
  206. package/dist/react/primitives/threadList/ThreadListItems.d.ts +4 -3
  207. package/dist/react/primitives/threadList/ThreadListItems.d.ts.map +1 -1
  208. package/dist/react/primitives/threadList/ThreadListItems.js.map +1 -1
  209. package/dist/react/primitives/threadListItem/ThreadListItemTitle.d.ts +0 -1
  210. package/dist/react/primitives/threadListItem/ThreadListItemTitle.d.ts.map +1 -1
  211. package/dist/react/providers/AttachmentByIndexProvider.d.ts +0 -1
  212. package/dist/react/providers/AttachmentByIndexProvider.d.ts.map +1 -1
  213. package/dist/react/providers/ChainOfThoughtByIndicesProvider.d.ts +0 -1
  214. package/dist/react/providers/ChainOfThoughtByIndicesProvider.d.ts.map +1 -1
  215. package/dist/react/providers/ChainOfThoughtPartByIndexProvider.d.ts +0 -1
  216. package/dist/react/providers/ChainOfThoughtPartByIndexProvider.d.ts.map +1 -1
  217. package/dist/react/providers/ChainOfThoughtPartByIndexProvider.js +18 -30
  218. package/dist/react/providers/ChainOfThoughtPartByIndexProvider.js.map +1 -1
  219. package/dist/react/providers/MessageByIdProvider.d.ts +0 -1
  220. package/dist/react/providers/MessageByIdProvider.d.ts.map +1 -1
  221. package/dist/react/providers/MessageByIndexProvider.d.ts +0 -1
  222. package/dist/react/providers/MessageByIndexProvider.d.ts.map +1 -1
  223. package/dist/react/providers/PartByIndexProvider.d.ts +0 -1
  224. package/dist/react/providers/PartByIndexProvider.d.ts.map +1 -1
  225. package/dist/react/providers/PartByIndexProvider.js +18 -30
  226. package/dist/react/providers/PartByIndexProvider.js.map +1 -1
  227. package/dist/react/providers/QueueItemByIndexProvider.d.ts +0 -1
  228. package/dist/react/providers/QueueItemByIndexProvider.d.ts.map +1 -1
  229. package/dist/react/providers/ReadonlyThreadProvider.d.ts +0 -1
  230. package/dist/react/providers/ReadonlyThreadProvider.d.ts.map +1 -1
  231. package/dist/react/providers/SuggestionByIndexProvider.d.ts +0 -1
  232. package/dist/react/providers/SuggestionByIndexProvider.d.ts.map +1 -1
  233. package/dist/react/providers/TextMessagePartProvider.d.ts +0 -1
  234. package/dist/react/providers/TextMessagePartProvider.d.ts.map +1 -1
  235. package/dist/react/providers/ThreadListItemByIndexProvider.d.ts +0 -1
  236. package/dist/react/providers/ThreadListItemByIndexProvider.d.ts.map +1 -1
  237. package/dist/react/providers/ThreadListItemRuntimeProvider.d.ts +1 -1
  238. package/dist/react/providers/ThreadListItemRuntimeProvider.d.ts.map +1 -1
  239. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.d.ts +2 -1
  240. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.d.ts.map +1 -1
  241. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js +2 -1
  242. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js.map +1 -1
  243. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts +12 -3
  244. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts.map +1 -1
  245. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js +70 -27
  246. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js.map +1 -1
  247. package/dist/react/runtimes/RuntimeAdapterProvider.d.ts +0 -1
  248. package/dist/react/runtimes/RuntimeAdapterProvider.d.ts.map +1 -1
  249. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.d.ts +0 -1
  250. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.d.ts.map +1 -1
  251. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.js +1 -1
  252. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.js.map +1 -1
  253. package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.d.ts +1 -4
  254. package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.d.ts.map +1 -1
  255. package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.js +8 -4
  256. package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.js.map +1 -1
  257. package/dist/react/runtimes/cloud/auiV0.d.ts +12 -2
  258. package/dist/react/runtimes/cloud/auiV0.d.ts.map +1 -1
  259. package/dist/react/runtimes/cloud/auiV0.js +30 -1
  260. package/dist/react/runtimes/cloud/auiV0.js.map +1 -1
  261. package/dist/react/runtimes/cloud/useCloudThreadListAdapter.d.ts +0 -1
  262. package/dist/react/runtimes/cloud/useCloudThreadListAdapter.d.ts.map +1 -1
  263. package/dist/react/runtimes/createMessageConverter.d.ts +1 -7
  264. package/dist/react/runtimes/createMessageConverter.d.ts.map +1 -1
  265. package/dist/react/runtimes/createRuntimeExtras.d.ts +0 -1
  266. package/dist/react/runtimes/createRuntimeExtras.d.ts.map +1 -1
  267. package/dist/react/runtimes/external-message-converter.d.ts +1 -8
  268. package/dist/react/runtimes/external-message-converter.d.ts.map +1 -1
  269. package/dist/react/runtimes/external-message-converter.js +43 -45
  270. package/dist/react/runtimes/external-message-converter.js.map +1 -1
  271. package/dist/react/runtimes/useExternalStoreRuntime.d.ts +0 -1
  272. package/dist/react/runtimes/useExternalStoreRuntime.d.ts.map +1 -1
  273. package/dist/react/runtimes/useExternalStoreSharedOptions.d.ts +0 -1
  274. package/dist/react/runtimes/useExternalStoreSharedOptions.d.ts.map +1 -1
  275. package/dist/react/runtimes/useLocalRuntime.d.ts +3 -5
  276. package/dist/react/runtimes/useLocalRuntime.d.ts.map +1 -1
  277. package/dist/react/runtimes/useLocalRuntime.js +9 -1
  278. package/dist/react/runtimes/useLocalRuntime.js.map +1 -1
  279. package/dist/react/runtimes/useRemoteThreadListRuntime.d.ts +0 -1
  280. package/dist/react/runtimes/useRemoteThreadListRuntime.d.ts.map +1 -1
  281. package/dist/react/runtimes/useStreamingTiming.d.ts +0 -1
  282. package/dist/react/runtimes/useStreamingTiming.d.ts.map +1 -1
  283. package/dist/react/types/MessagePartComponentTypes.d.ts +6 -3
  284. package/dist/react/types/MessagePartComponentTypes.d.ts.map +1 -1
  285. package/dist/react/types/scopes/dataRenderers.d.ts +1 -1
  286. package/dist/react/types/scopes/dataRenderers.d.ts.map +1 -1
  287. package/dist/react/types/scopes/interactables.d.ts +4 -2
  288. package/dist/react/types/scopes/interactables.d.ts.map +1 -1
  289. package/dist/react/types/scopes/tools.d.ts +5 -3
  290. package/dist/react/types/scopes/tools.d.ts.map +1 -1
  291. package/dist/react/types/store-augmentation.d.ts +1 -2
  292. package/dist/react/types/store-augmentation.d.ts.map +1 -1
  293. package/dist/react/utils/getMessageQuote.d.ts +0 -1
  294. package/dist/react/utils/getMessageQuote.d.ts.map +1 -1
  295. package/dist/react/utils/groupParts.d.ts +2 -2
  296. package/dist/react/utils/groupParts.d.ts.map +1 -1
  297. package/dist/react/utils/useJSONEqual.d.ts.map +1 -1
  298. package/dist/runtime/api/assistant-runtime.d.ts +0 -1
  299. package/dist/runtime/api/assistant-runtime.d.ts.map +1 -1
  300. package/dist/runtime/api/attachment-runtime.d.ts +0 -1
  301. package/dist/runtime/api/attachment-runtime.d.ts.map +1 -1
  302. package/dist/runtime/api/bindings.d.ts +0 -1
  303. package/dist/runtime/api/bindings.d.ts.map +1 -1
  304. package/dist/runtime/api/composer-runtime.d.ts +6 -4
  305. package/dist/runtime/api/composer-runtime.d.ts.map +1 -1
  306. package/dist/runtime/api/message-part-runtime.d.ts +0 -1
  307. package/dist/runtime/api/message-part-runtime.d.ts.map +1 -1
  308. package/dist/runtime/api/message-runtime.d.ts +6 -16
  309. package/dist/runtime/api/message-runtime.d.ts.map +1 -1
  310. package/dist/runtime/api/message-runtime.js +5 -5
  311. package/dist/runtime/api/message-runtime.js.map +1 -1
  312. package/dist/runtime/api/paths.d.ts.map +1 -1
  313. package/dist/runtime/api/thread-list-item-runtime.d.ts +0 -1
  314. package/dist/runtime/api/thread-list-item-runtime.d.ts.map +1 -1
  315. package/dist/runtime/api/thread-list-item-runtime.js +2 -1
  316. package/dist/runtime/api/thread-list-item-runtime.js.map +1 -1
  317. package/dist/runtime/api/thread-list-runtime.d.ts +0 -1
  318. package/dist/runtime/api/thread-list-runtime.d.ts.map +1 -1
  319. package/dist/runtime/api/thread-runtime.d.ts +3 -1
  320. package/dist/runtime/api/thread-runtime.d.ts.map +1 -1
  321. package/dist/runtime/base/base-assistant-runtime-core.d.ts +0 -1
  322. package/dist/runtime/base/base-assistant-runtime-core.d.ts.map +1 -1
  323. package/dist/runtime/base/base-composer-runtime-core.d.ts +4 -2
  324. package/dist/runtime/base/base-composer-runtime-core.d.ts.map +1 -1
  325. package/dist/runtime/base/base-composer-runtime-core.js +51 -10
  326. package/dist/runtime/base/base-composer-runtime-core.js.map +1 -1
  327. package/dist/runtime/base/base-thread-runtime-core.d.ts +2 -4
  328. package/dist/runtime/base/base-thread-runtime-core.d.ts.map +1 -1
  329. package/dist/runtime/base/base-thread-runtime-core.js +3 -2
  330. package/dist/runtime/base/base-thread-runtime-core.js.map +1 -1
  331. package/dist/runtime/base/default-edit-composer-runtime-core.d.ts +1 -5
  332. package/dist/runtime/base/default-edit-composer-runtime-core.d.ts.map +1 -1
  333. package/dist/runtime/base/default-edit-composer-runtime-core.js +4 -2
  334. package/dist/runtime/base/default-edit-composer-runtime-core.js.map +1 -1
  335. package/dist/runtime/base/default-thread-composer-runtime-core.d.ts +1 -0
  336. package/dist/runtime/base/default-thread-composer-runtime-core.d.ts.map +1 -1
  337. package/dist/runtime/base/default-thread-composer-runtime-core.js +2 -2
  338. package/dist/runtime/base/default-thread-composer-runtime-core.js.map +1 -1
  339. package/dist/runtime/branch/external-thread-branch-adapter.d.ts.map +1 -1
  340. package/dist/runtime/interfaces/assistant-runtime-core.d.ts +0 -1
  341. package/dist/runtime/interfaces/assistant-runtime-core.d.ts.map +1 -1
  342. package/dist/runtime/interfaces/composer-runtime-core.d.ts +2 -2
  343. package/dist/runtime/interfaces/composer-runtime-core.d.ts.map +1 -1
  344. package/dist/runtime/interfaces/thread-list-runtime-core.d.ts +0 -1
  345. package/dist/runtime/interfaces/thread-list-runtime-core.d.ts.map +1 -1
  346. package/dist/runtime/interfaces/thread-runtime-core.d.ts +2 -2
  347. package/dist/runtime/interfaces/thread-runtime-core.d.ts.map +1 -1
  348. package/dist/runtime/queue/external-thread-queue-adapter.d.ts +0 -1
  349. package/dist/runtime/queue/external-thread-queue-adapter.d.ts.map +1 -1
  350. package/dist/runtime/queue/message-queue.d.ts +6 -4
  351. package/dist/runtime/queue/message-queue.d.ts.map +1 -1
  352. package/dist/runtime/queue/message-queue.js +1 -1
  353. package/dist/runtime/utils/auto-status.d.ts +0 -1
  354. package/dist/runtime/utils/auto-status.d.ts.map +1 -1
  355. package/dist/runtime/utils/chat-model-adapter.d.ts +0 -1
  356. package/dist/runtime/utils/chat-model-adapter.d.ts.map +1 -1
  357. package/dist/runtime/utils/external-store-message.d.ts +0 -1
  358. package/dist/runtime/utils/external-store-message.d.ts.map +1 -1
  359. package/dist/runtime/utils/message-repository.d.ts +1 -5
  360. package/dist/runtime/utils/message-repository.d.ts.map +1 -1
  361. package/dist/runtime/utils/message-repository.js +3 -1
  362. package/dist/runtime/utils/message-repository.js.map +1 -1
  363. package/dist/runtime/utils/resolveToolApprovalResponse.d.ts +0 -1
  364. package/dist/runtime/utils/resolveToolApprovalResponse.d.ts.map +1 -1
  365. package/dist/runtime/utils/streaming-timing.d.ts +5 -3
  366. package/dist/runtime/utils/streaming-timing.d.ts.map +1 -1
  367. package/dist/runtime/utils/thread-message-like.d.ts +2 -2
  368. package/dist/runtime/utils/thread-message-like.d.ts.map +1 -1
  369. package/dist/runtime/utils/thread-message-like.js +4 -1
  370. package/dist/runtime/utils/thread-message-like.js.map +1 -1
  371. package/dist/runtimes/assistant-transport/utils.d.ts.map +1 -1
  372. package/dist/runtimes/external-store/external-store-adapter.d.ts +2 -2
  373. package/dist/runtimes/external-store/external-store-adapter.d.ts.map +1 -1
  374. package/dist/runtimes/external-store/external-store-runtime-core.d.ts +0 -1
  375. package/dist/runtimes/external-store/external-store-runtime-core.d.ts.map +1 -1
  376. package/dist/runtimes/external-store/external-store-shared-options.d.ts +0 -1
  377. package/dist/runtimes/external-store/external-store-shared-options.d.ts.map +1 -1
  378. package/dist/runtimes/external-store/external-store-thread-list-runtime-core.d.ts +0 -1
  379. package/dist/runtimes/external-store/external-store-thread-list-runtime-core.d.ts.map +1 -1
  380. package/dist/runtimes/external-store/external-store-thread-runtime-core.d.ts +2 -0
  381. package/dist/runtimes/external-store/external-store-thread-runtime-core.d.ts.map +1 -1
  382. package/dist/runtimes/external-store/external-store-thread-runtime-core.js +1 -1
  383. package/dist/runtimes/external-store/external-store-thread-runtime-core.js.map +1 -1
  384. package/dist/runtimes/external-store/thread-message-converter.d.ts +0 -1
  385. package/dist/runtimes/external-store/thread-message-converter.d.ts.map +1 -1
  386. package/dist/runtimes/local/local-runtime-core.d.ts +0 -1
  387. package/dist/runtimes/local/local-runtime-core.d.ts.map +1 -1
  388. package/dist/runtimes/local/local-runtime-options.d.ts +0 -1
  389. package/dist/runtimes/local/local-runtime-options.d.ts.map +1 -1
  390. package/dist/runtimes/local/local-thread-list-runtime-core.d.ts +0 -1
  391. package/dist/runtimes/local/local-thread-list-runtime-core.d.ts.map +1 -1
  392. package/dist/runtimes/local/local-thread-runtime-core.d.ts +5 -21
  393. package/dist/runtimes/local/local-thread-runtime-core.d.ts.map +1 -1
  394. package/dist/runtimes/local/local-thread-runtime-core.js +29 -17
  395. package/dist/runtimes/local/local-thread-runtime-core.js.map +1 -1
  396. package/dist/runtimes/local/should-continue.d.ts +0 -1
  397. package/dist/runtimes/local/should-continue.d.ts.map +1 -1
  398. package/dist/runtimes/local/should-continue.js +2 -2
  399. package/dist/runtimes/local/should-continue.js.map +1 -1
  400. package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.d.ts +0 -1
  401. package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.d.ts.map +1 -1
  402. package/dist/runtimes/remote-thread-list/adapter/in-memory.d.ts +1 -2
  403. package/dist/runtimes/remote-thread-list/adapter/in-memory.d.ts.map +1 -1
  404. package/dist/runtimes/remote-thread-list/adapter/in-memory.js +5 -3
  405. package/dist/runtimes/remote-thread-list/adapter/in-memory.js.map +1 -1
  406. package/dist/runtimes/remote-thread-list/empty-thread-core.d.ts +0 -1
  407. package/dist/runtimes/remote-thread-list/empty-thread-core.d.ts.map +1 -1
  408. package/dist/runtimes/remote-thread-list/optimistic-state.d.ts +10 -8
  409. package/dist/runtimes/remote-thread-list/optimistic-state.d.ts.map +1 -1
  410. package/dist/runtimes/remote-thread-list/optimistic-state.js +22 -9
  411. package/dist/runtimes/remote-thread-list/optimistic-state.js.map +1 -1
  412. package/dist/runtimes/remote-thread-list/remote-thread-state.d.ts +0 -1
  413. package/dist/runtimes/remote-thread-list/remote-thread-state.d.ts.map +1 -1
  414. package/dist/runtimes/remote-thread-list/types.d.ts +1 -2
  415. package/dist/runtimes/remote-thread-list/types.d.ts.map +1 -1
  416. package/dist/runtimes/tool-invocations/ToolInvocationTracker.d.ts +2 -2
  417. package/dist/runtimes/tool-invocations/ToolInvocationTracker.d.ts.map +1 -1
  418. package/dist/runtimes/tool-invocations/ToolInvocationTracker.js +1 -2
  419. package/dist/runtimes/tool-invocations/ToolInvocationTracker.js.map +1 -1
  420. package/dist/store/clients/chain-of-thought-client.d.ts +0 -1
  421. package/dist/store/clients/chain-of-thought-client.d.ts.map +1 -1
  422. package/dist/store/clients/model-context-client.d.ts +0 -1
  423. package/dist/store/clients/model-context-client.d.ts.map +1 -1
  424. package/dist/store/clients/no-op-composer-client.d.ts +0 -1
  425. package/dist/store/clients/no-op-composer-client.d.ts.map +1 -1
  426. package/dist/store/clients/runtime-adapter.d.ts +0 -1
  427. package/dist/store/clients/runtime-adapter.d.ts.map +1 -1
  428. package/dist/store/clients/suggestions.d.ts +0 -1
  429. package/dist/store/clients/suggestions.d.ts.map +1 -1
  430. package/dist/store/clients/thread-message-client.d.ts +0 -1
  431. package/dist/store/clients/thread-message-client.d.ts.map +1 -1
  432. package/dist/store/runtime-clients/attachment-runtime-client.d.ts +0 -1
  433. package/dist/store/runtime-clients/attachment-runtime-client.d.ts.map +1 -1
  434. package/dist/store/runtime-clients/composer-runtime-client.d.ts +0 -1
  435. package/dist/store/runtime-clients/composer-runtime-client.d.ts.map +1 -1
  436. package/dist/store/runtime-clients/liveRef.d.ts.map +1 -1
  437. package/dist/store/runtime-clients/message-part-runtime-client.d.ts +0 -1
  438. package/dist/store/runtime-clients/message-part-runtime-client.d.ts.map +1 -1
  439. package/dist/store/runtime-clients/message-runtime-client.d.ts +0 -1
  440. package/dist/store/runtime-clients/message-runtime-client.d.ts.map +1 -1
  441. package/dist/store/runtime-clients/thread-list-item-runtime-client.d.ts +0 -1
  442. package/dist/store/runtime-clients/thread-list-item-runtime-client.d.ts.map +1 -1
  443. package/dist/store/runtime-clients/thread-list-runtime-client.d.ts +0 -1
  444. package/dist/store/runtime-clients/thread-list-runtime-client.d.ts.map +1 -1
  445. package/dist/store/runtime-clients/thread-runtime-client.d.ts +0 -1
  446. package/dist/store/runtime-clients/thread-runtime-client.d.ts.map +1 -1
  447. package/dist/store/runtime-clients/useSubscribable.d.ts +0 -1
  448. package/dist/store/runtime-clients/useSubscribable.d.ts.map +1 -1
  449. package/dist/store/scope-registration.d.ts +1 -2
  450. package/dist/store/scope-registration.d.ts.map +1 -1
  451. package/dist/store/scopes/attachment.d.ts +0 -1
  452. package/dist/store/scopes/attachment.d.ts.map +1 -1
  453. package/dist/store/scopes/chain-of-thought.d.ts +0 -1
  454. package/dist/store/scopes/chain-of-thought.d.ts.map +1 -1
  455. package/dist/store/scopes/composer.d.ts +0 -1
  456. package/dist/store/scopes/composer.d.ts.map +1 -1
  457. package/dist/store/scopes/message.d.ts +6 -4
  458. package/dist/store/scopes/message.d.ts.map +1 -1
  459. package/dist/store/scopes/model-context.d.ts +0 -1
  460. package/dist/store/scopes/model-context.d.ts.map +1 -1
  461. package/dist/store/scopes/part.d.ts +0 -1
  462. package/dist/store/scopes/part.d.ts.map +1 -1
  463. package/dist/store/scopes/queue-item.d.ts.map +1 -1
  464. package/dist/store/scopes/suggestion.d.ts.map +1 -1
  465. package/dist/store/scopes/suggestions.d.ts +0 -1
  466. package/dist/store/scopes/suggestions.d.ts.map +1 -1
  467. package/dist/store/scopes/thread-list-item.d.ts +0 -1
  468. package/dist/store/scopes/thread-list-item.d.ts.map +1 -1
  469. package/dist/store/scopes/thread.d.ts +4 -3
  470. package/dist/store/scopes/thread.d.ts.map +1 -1
  471. package/dist/store/scopes/threads.d.ts +0 -1
  472. package/dist/store/scopes/threads.d.ts.map +1 -1
  473. package/dist/subscribable/subscribable.d.ts +1 -2
  474. package/dist/subscribable/subscribable.d.ts.map +1 -1
  475. package/dist/subscribable/subscribable.js +11 -3
  476. package/dist/subscribable/subscribable.js.map +1 -1
  477. package/dist/tests/remote-thread-list-test-helpers.d.ts +2 -2
  478. package/dist/tests/remote-thread-list-test-helpers.d.ts.map +1 -1
  479. package/dist/tests/remote-thread-list-test-helpers.js +5 -2
  480. package/dist/tests/remote-thread-list-test-helpers.js.map +1 -1
  481. package/dist/types/attachment.d.ts +3 -2
  482. package/dist/types/attachment.d.ts.map +1 -1
  483. package/dist/types/attachment.js +6 -0
  484. package/dist/types/attachment.js.map +1 -0
  485. package/dist/types/directive.d.ts +3 -2
  486. package/dist/types/directive.d.ts.map +1 -1
  487. package/dist/types/error.d.ts +15 -0
  488. package/dist/types/error.d.ts.map +1 -0
  489. package/dist/types/error.js +46 -0
  490. package/dist/types/error.js.map +1 -0
  491. package/dist/types/index.d.ts +2 -2
  492. package/dist/types/message.d.ts +71 -33
  493. package/dist/types/message.d.ts.map +1 -1
  494. package/dist/types/message.js.map +1 -1
  495. package/dist/types/quote.d.ts.map +1 -1
  496. package/dist/types/trigger.d.ts +0 -1
  497. package/dist/types/trigger.d.ts.map +1 -1
  498. package/dist/types/unsubscribe.d.ts.map +1 -1
  499. package/dist/utils/composite-context-provider.d.ts +1 -0
  500. package/dist/utils/composite-context-provider.d.ts.map +1 -1
  501. package/dist/utils/data-url.d.ts +9 -0
  502. package/dist/utils/data-url.d.ts.map +1 -0
  503. package/dist/utils/data-url.js +14 -0
  504. package/dist/utils/data-url.js.map +1 -0
  505. package/dist/utils/id.d.ts.map +1 -1
  506. package/dist/utils/json/is-json-equal.d.ts.map +1 -1
  507. package/dist/utils/json/is-json.d.ts +0 -1
  508. package/dist/utils/json/is-json.d.ts.map +1 -1
  509. package/dist/utils/json/is-json.js +1 -1
  510. package/dist/utils/json/is-json.js.map +1 -1
  511. package/dist/utils/json/stable-stringify-tool-args.d.ts +7 -0
  512. package/dist/utils/json/stable-stringify-tool-args.d.ts.map +1 -0
  513. package/dist/utils/json/stable-stringify-tool-args.js +32 -0
  514. package/dist/utils/json/stable-stringify-tool-args.js.map +1 -0
  515. package/dist/utils/notify-event-listeners.d.ts +6 -0
  516. package/dist/utils/notify-event-listeners.d.ts.map +1 -0
  517. package/dist/utils/notify-event-listeners.js +16 -0
  518. package/dist/utils/notify-event-listeners.js.map +1 -0
  519. package/dist/utils/text.d.ts +0 -1
  520. package/dist/utils/text.d.ts.map +1 -1
  521. package/package.json +14 -10
  522. package/src/adapters/attachment.test.ts +107 -0
  523. package/src/adapters/attachment.ts +20 -10
  524. package/src/adapters/index.ts +6 -1
  525. package/src/adapters/speech.test.ts +88 -0
  526. package/src/adapters/speech.ts +17 -2
  527. package/src/adapters/suggestion.test.ts +187 -0
  528. package/src/adapters/suggestion.ts +75 -1
  529. package/src/adapters/voice.test.ts +130 -0
  530. package/src/adapters/voice.ts +26 -6
  531. package/src/index.ts +15 -1
  532. package/src/internal.ts +21 -0
  533. package/src/model-context/frame/host.test.ts +100 -0
  534. package/src/model-context/frame/host.ts +10 -0
  535. package/src/model-context/frame/provider.test.ts +83 -0
  536. package/src/model-context/frame/provider.ts +1 -0
  537. package/src/model-context/tool.test.ts +110 -0
  538. package/src/model-context/tool.ts +31 -9
  539. package/src/react/adapters/LocalStorageThreadListAdapter.test.ts +304 -0
  540. package/src/react/adapters/LocalStorageThreadListAdapter.tsx +307 -60
  541. package/src/react/index.ts +2 -0
  542. package/src/react/model-context/define-mcp-toolkit.ts +39 -6
  543. package/src/react/model-context/define-toolkit.test.ts +107 -0
  544. package/src/react/primitive-hooks/useActionBarCopy.test.ts +79 -0
  545. package/src/react/primitive-hooks/useActionBarCopy.ts +4 -3
  546. package/src/react/primitive-hooks/useMessageError.test.ts +64 -0
  547. package/src/react/primitive-hooks/useMessageError.ts +19 -6
  548. package/src/react/primitives/chainOfThought/ChainOfThoughtParts.tsx +1 -3
  549. package/src/react/primitives/message/MessageParts.tsx +48 -35
  550. package/src/react/providers/ChainOfThoughtPartByIndexProvider.tsx +19 -2
  551. package/src/react/providers/PartByIndexProvider.tsx +16 -2
  552. package/src/react/runtimes/RemoteThreadListHookInstanceManager.test.tsx +18 -0
  553. package/src/react/runtimes/RemoteThreadListHookInstanceManager.tsx +4 -1
  554. package/src/react/runtimes/RemoteThreadListThreadListRuntimeCore.tsx +96 -26
  555. package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.test.tsx +69 -0
  556. package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.ts +1 -1
  557. package/src/react/runtimes/cloud/CloudFileAttachmentAdapter.test.ts +127 -0
  558. package/src/react/runtimes/cloud/CloudFileAttachmentAdapter.ts +15 -4
  559. package/src/react/runtimes/cloud/auiV0.ts +71 -2
  560. package/src/react/runtimes/external-message-converter.test.tsx +123 -0
  561. package/src/react/runtimes/external-message-converter.ts +36 -11
  562. package/src/react/runtimes/useLocalRuntime.test.tsx +56 -0
  563. package/src/react/runtimes/useLocalRuntime.ts +13 -1
  564. package/src/runtime/api/message-runtime.test.ts +81 -0
  565. package/src/runtime/api/message-runtime.ts +4 -6
  566. package/src/runtime/api/thread-list-item-runtime.ts +6 -1
  567. package/src/runtime/base/base-composer-runtime-core.ts +95 -30
  568. package/src/runtime/base/base-thread-runtime-core.ts +2 -1
  569. package/src/runtime/base/default-edit-composer-runtime-core.ts +4 -2
  570. package/src/runtime/base/default-thread-composer-runtime-core.ts +2 -2
  571. package/src/runtime/utils/message-repository.ts +8 -3
  572. package/src/runtime/utils/thread-message-like.ts +3 -0
  573. package/src/runtimes/local/local-thread-runtime-core.test.ts +276 -3
  574. package/src/runtimes/local/local-thread-runtime-core.ts +29 -25
  575. package/src/runtimes/local/should-continue.ts +5 -2
  576. package/src/runtimes/remote-thread-list/adapter/in-memory.test.ts +14 -0
  577. package/src/runtimes/remote-thread-list/adapter/in-memory.ts +13 -5
  578. package/src/runtimes/remote-thread-list/optimistic-state.test.ts +63 -0
  579. package/src/runtimes/remote-thread-list/optimistic-state.ts +49 -17
  580. package/src/runtimes/remote-thread-list/types.ts +1 -1
  581. package/src/runtimes/tool-invocations/EDGE_CASES.md +13 -19
  582. package/src/runtimes/tool-invocations/ToolInvocationTracker.test.ts +127 -6
  583. package/src/runtimes/tool-invocations/ToolInvocationTracker.ts +4 -2
  584. package/src/subscribable/subscribable.test.ts +58 -0
  585. package/src/subscribable/subscribable.ts +13 -3
  586. package/src/tests/MessageRepository.test.ts +26 -0
  587. package/src/tests/OptimisticState-list-race.test.ts +33 -0
  588. package/src/tests/RemoteThreadListThreadListRuntimeCore-errors.test.ts +42 -0
  589. package/src/tests/RemoteThreadListThreadListRuntimeCore-switchToThread-order.test.ts +223 -0
  590. package/src/tests/attachment-adapters.test.ts +14 -2
  591. package/src/tests/auiV0Encode.test.ts +134 -1
  592. package/src/tests/base-composer-runtime-core-addAttachment.test.ts +123 -5
  593. package/src/tests/base-composer-runtime-core-send.test.ts +573 -0
  594. package/src/tests/default-edit-composer-runtime-core.test.ts +43 -5
  595. package/src/tests/event-subscription-listener-errors.test.ts +205 -0
  596. package/src/tests/remote-thread-list-test-helpers.ts +14 -7
  597. package/src/tests/thread-message-like.test.ts +97 -0
  598. package/src/types/attachment.ts +6 -0
  599. package/src/types/error.test.ts +122 -0
  600. package/src/types/error.ts +74 -0
  601. package/src/types/index.ts +1 -0
  602. package/src/types/message.ts +12 -3
  603. package/src/utils/data-url.test.ts +50 -0
  604. package/src/utils/data-url.ts +9 -0
  605. package/src/utils/json/is-json-equal.test.ts +84 -0
  606. package/src/utils/json/is-json.test.ts +123 -0
  607. package/src/utils/json/is-json.ts +1 -1
  608. package/src/utils/json/stable-stringify-tool-args.test.ts +105 -0
  609. package/src/utils/json/stable-stringify-tool-args.ts +70 -0
  610. package/src/utils/notify-event-listeners.ts +30 -0
@@ -1,6 +1,5 @@
1
1
  import { ThreadUserMessagePart } from "../types/message.js";
2
2
  import { Attachment, CompleteAttachment, PendingAttachment } from "../types/attachment.js";
3
-
4
3
  //#region src/adapters/attachment.d.ts
5
4
  type AttachmentAdapter = {
6
5
  accept: string;
@@ -18,6 +17,7 @@ declare class SimpleImageAttachmentAdapter implements AttachmentAdapter {
18
17
  send(attachment: PendingAttachment): Promise<CompleteAttachment>;
19
18
  remove(): Promise<void>;
20
19
  }
20
+ declare const getFileDataURL: (file: File) => Promise<string>;
21
21
  declare class SimpleTextAttachmentAdapter implements AttachmentAdapter {
22
22
  accept: string;
23
23
  add(state: {
@@ -46,5 +46,5 @@ declare class CompositeAttachmentAdapter implements AttachmentAdapter {
46
46
  remove(attachment: Attachment): Promise<void>;
47
47
  }
48
48
  //#endregion
49
- export { AttachmentAdapter, CompositeAttachmentAdapter, SimpleImageAttachmentAdapter, SimpleTextAttachmentAdapter, attachmentsEqual, fileMatchesAccept, liftNonTextParts, partToCompleteAttachment };
49
+ export { AttachmentAdapter, CompositeAttachmentAdapter, SimpleImageAttachmentAdapter, SimpleTextAttachmentAdapter, attachmentsEqual, fileMatchesAccept, getFileDataURL, liftNonTextParts, partToCompleteAttachment };
50
50
  //# sourceMappingURL=attachment.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"attachment.d.ts","names":[],"sources":["../../src/adapters/attachment.ts"],"mappings":";;;;KAQY,iBAAA;EACV,MAAA;EACA,GAAA,CAAI,KAAA;IACF,IAAA,EAAM,IAAA;EAAA,IACJ,OAAA,CAAQ,iBAAA,IAAqB,cAAA,CAAe,iBAAA;EAChD,MAAA,CAAO,UAAA,EAAY,UAAA,GAAa,OAAA;EAChC,IAAA,CAAK,UAAA,EAAY,iBAAA,GAAoB,OAAA,CAAQ,kBAAA;AAAA;AAAA,cAGlC,4BAAA,YAAwC,iBAAA;EAC5C,MAAA;EAEM,GAAA,CAAI,KAAA;IAAS,IAAA,EAAM,IAAA;EAAA,IAAS,OAAA,CAAQ,iBAAA;EAWpC,IAAA,CACX,UAAA,EAAY,iBAAA,GACX,OAAA,CAAQ,kBAAA;EAaE,MAAA,IAAM,OAAA;AAAA;AAAA,cA6BR,2BAAA,YAAuC,iBAAA;EAC3C,MAAA;EAGM,GAAA,CAAI,KAAA;IAAS,IAAA,EAAM,IAAA;EAAA,IAAS,OAAA,CAAQ,iBAAA;EAWpC,IAAA,CACX,UAAA,EAAY,iBAAA,GACX,OAAA,CAAQ,kBAAA;EAaE,MAAA,IAAM,OAAA;AAAA;AAAA,iBAiBL,iBAAA,CACd,IAAA;EAAQ,IAAA;EAAc,IAAA;AAAA,GACtB,YAAA;AAAA,iBAiCc,gBAAA,CACd,CAAA,WAAY,kBAAA,IACZ,CAAA,WAAY,kBAAkB;AAAA,iBAMhB,wBAAA,CACd,IAAA,EAAM,OAAA,CAAQ,qBAAA;EAAyB,IAAA;AAAA,KACtC,kBAAA;AAAA,iBA4Ca,gBAAA,CACd,OAAA,WAAkB,qBAAA,KACjB,kBAAkB;AAAA,cAUR,0BAAA,YAAsC,iBAAA;EAAA,QACzC,SAAA;EAED,MAAA;cAEK,QAAA,EAAU,iBAAA;EAgBf,GAAA,CAAI,KAAA;IAAS,IAAA,EAAM,IAAA;EAAA,IAAM,OAAA,CAAA,iBAAA,IAAA,cAAA,CAAA,iBAAA;EASnB,IAAA,CAAK,UAAA,EAAY,iBAAA,GAAiB,OAAA,CAAA,kBAAA;EAUlC,MAAA,CAAO,UAAA,EAAY,UAAA,GAAU,OAAA;AAAA"}
1
+ {"version":3,"file":"attachment.d.ts","names":[],"sources":["../../src/adapters/attachment.ts"],"mappings":";;;KAQY;EACV;EACA,IAAI;IACF,MAAM;MACJ,QAAQ,qBAAqB,eAAe;EAChD,OAAO,YAAY,aAAa;EAChC,KAAK,YAAY,oBAAoB,QAAQ;;cAGlC,wCAAwC;EAC5C;EAEM,IAAI;IAAS,MAAM;MAAS,QAAQ;EAWpC,KACX,YAAY,oBACX,QAAQ;EAaE,UAAM;;cA0BR,iBAAwB,MAAM,SAAO;cAarC,uCAAuC;EAC3C;EAGM,IAAI;IAAS,MAAM;MAAS,QAAQ;EAWpC,KACX,YAAY,oBACX,QAAQ;EAaE,UAAM;;iBAiBL,kBACd;EAAQ;EAAc;GACtB;iBAiCc,iBACd,YAAY,sBACZ,YAAY;iBAME,yBACd,MAAM,QAAQ;EAAyB;KACtC;iBA4Ca,iBACd,kBAAkB,0BACjB;cAUU,sCAAsC;UACzC;EAED;EAEK,YAAA,UAAU;EAgBf,IAAI;IAAS,MAAM;MAAM,QAAA,qBAAA,eAAA;EASnB,KAAK,YAAY,oBAAiB,QAAA;EAUlC,OAAO,YAAY,aAAU"}
@@ -4,7 +4,7 @@ var SimpleImageAttachmentAdapter = class {
4
4
  accept = "image/*";
5
5
  async add(state) {
6
6
  return {
7
- id: state.file.name,
7
+ id: generateId(),
8
8
  type: "image",
9
9
  name: state.file.name,
10
10
  contentType: state.file.type,
@@ -27,11 +27,18 @@ var SimpleImageAttachmentAdapter = class {
27
27
  }
28
28
  async remove() {}
29
29
  };
30
- const bytesToBase64 = (bytes) => globalThis.Buffer.from(bytes).toString("base64");
30
+ const bytesToBase64 = (bytes) => {
31
+ const nodeBuffer = globalThis.Buffer;
32
+ if (nodeBuffer) return nodeBuffer.from(bytes).toString("base64");
33
+ let binary = "";
34
+ const chunkSize = 32768;
35
+ for (let i = 0; i < bytes.length; i += chunkSize) binary += String.fromCharCode(...bytes.subarray(i, i + chunkSize));
36
+ return btoa(binary);
37
+ };
31
38
  const getFileDataURL = async (file) => {
32
39
  if (typeof FileReader === "undefined") {
33
40
  const buffer = await file.arrayBuffer();
34
- return `data:${file.type};base64,${bytesToBase64(new Uint8Array(buffer))}`;
41
+ return `data:${file.type || "application/octet-stream"};base64,${bytesToBase64(new Uint8Array(buffer))}`;
35
42
  }
36
43
  return new Promise((resolve, reject) => {
37
44
  const reader = new FileReader();
@@ -41,10 +48,10 @@ const getFileDataURL = async (file) => {
41
48
  });
42
49
  };
43
50
  var SimpleTextAttachmentAdapter = class {
44
- accept = "text/plain,text/html,text/markdown,text/csv,text/xml,text/json,text/css";
51
+ accept = "text/plain,text/html,text/markdown,text/csv,text/xml,text/json,application/json,text/css";
45
52
  async add(state) {
46
53
  return {
47
- id: state.file.name,
54
+ id: generateId(),
48
55
  type: "document",
49
56
  name: state.file.name,
50
57
  contentType: state.file.type,
@@ -80,7 +87,7 @@ function fileMatchesAccept(file, acceptString) {
80
87
  if (acceptString === "*") return true;
81
88
  const allowedTypes = acceptString.split(",").map((type) => type.trim().toLowerCase());
82
89
  const fileExtension = `.${file.name.split(".").pop().toLowerCase()}`;
83
- const fileMimeType = file.type.toLowerCase();
90
+ const fileMimeType = file.type.split(";", 1)[0].trim().toLowerCase();
84
91
  for (const type of allowedTypes) {
85
92
  if (type.startsWith(".") && type === fileExtension) return true;
86
93
  if (type.includes("/") && type === fileMimeType) return true;
@@ -163,6 +170,6 @@ var CompositeAttachmentAdapter = class {
163
170
  }
164
171
  };
165
172
  //#endregion
166
- export { CompositeAttachmentAdapter, SimpleImageAttachmentAdapter, SimpleTextAttachmentAdapter, attachmentsEqual, fileMatchesAccept, liftNonTextParts, partToCompleteAttachment };
173
+ export { CompositeAttachmentAdapter, SimpleImageAttachmentAdapter, SimpleTextAttachmentAdapter, attachmentsEqual, fileMatchesAccept, getFileDataURL, liftNonTextParts, partToCompleteAttachment };
167
174
 
168
175
  //# sourceMappingURL=attachment.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"attachment.js","names":["Attachment","PendingAttachment","CompleteAttachment","ThreadUserMessagePart","generateId","AttachmentAdapter","accept","add","state","file","File","Promise","AsyncGenerator","remove","attachment","send","SimpleImageAttachmentAdapter","id","name","type","contentType","status","reason","content","image","getFileDataURL","bytesToBase64","bytes","Uint8Array","globalThis","Buffer","from","toString","encoding","FileReader","buffer","arrayBuffer","resolve","reject","reader","onload","result","onerror","error","readAsDataURL","SimpleTextAttachmentAdapter","text","getFileText","readAsText","fileMatchesAccept","acceptString","allowedTypes","split","map","trim","toLowerCase","fileExtension","pop","fileMimeType","startsWith","includes","endsWith","generalType","attachmentsEqual","a","b","length","every","att","i","partToCompleteAttachment","part","Exclude","filename","mimeType","audio","format","liftNonTextParts","push","CompositeAttachmentAdapter","_adapters","constructor","adapters","wildcardIdx","findIndex","Error","join","adapter","slice"],"sources":["../../src/adapters/attachment.ts"],"sourcesContent":["import type {\n Attachment,\n PendingAttachment,\n CompleteAttachment,\n} from \"../types/attachment\";\nimport type { ThreadUserMessagePart } from \"../types/message\";\nimport { generateId } from \"../utils/id\";\n\nexport type AttachmentAdapter = {\n accept: string;\n add(state: {\n file: File;\n }): Promise<PendingAttachment> | AsyncGenerator<PendingAttachment, void>;\n remove(attachment: Attachment): Promise<void>;\n send(attachment: PendingAttachment): Promise<CompleteAttachment>;\n};\n\nexport class SimpleImageAttachmentAdapter implements AttachmentAdapter {\n public accept = \"image/*\";\n\n public async add(state: { file: File }): Promise<PendingAttachment> {\n return {\n id: state.file.name,\n type: \"image\",\n name: state.file.name,\n contentType: state.file.type,\n file: state.file,\n status: { type: \"requires-action\", reason: \"composer-send\" },\n };\n }\n\n public async send(\n attachment: PendingAttachment,\n ): Promise<CompleteAttachment> {\n return {\n ...attachment,\n status: { type: \"complete\" },\n content: [\n {\n type: \"image\",\n image: await getFileDataURL(attachment.file),\n },\n ],\n };\n }\n\n public async remove() {\n // noop\n }\n}\n\nconst bytesToBase64 = (bytes: Uint8Array): string =>\n (\n globalThis as {\n Buffer: {\n from(bytes: Uint8Array): { toString(encoding: string): string };\n };\n }\n ).Buffer.from(bytes).toString(\"base64\");\n\n// React Native's Blob polyfill has FileReader but not file.text()/arrayBuffer(); Node has\n// the reverse. Prefer FileReader when present, falling back to the Blob methods otherwise.\nconst getFileDataURL = async (file: File): Promise<string> => {\n if (typeof FileReader === \"undefined\") {\n const buffer = await file.arrayBuffer();\n return `data:${file.type};base64,${bytesToBase64(new Uint8Array(buffer))}`;\n }\n return new Promise<string>((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = () => resolve(reader.result as string);\n reader.onerror = (error) => reject(error);\n reader.readAsDataURL(file);\n });\n};\n\nexport class SimpleTextAttachmentAdapter implements AttachmentAdapter {\n public accept =\n \"text/plain,text/html,text/markdown,text/csv,text/xml,text/json,text/css\";\n\n public async add(state: { file: File }): Promise<PendingAttachment> {\n return {\n id: state.file.name,\n type: \"document\",\n name: state.file.name,\n contentType: state.file.type,\n file: state.file,\n status: { type: \"requires-action\", reason: \"composer-send\" },\n };\n }\n\n public async send(\n attachment: PendingAttachment,\n ): Promise<CompleteAttachment> {\n return {\n ...attachment,\n status: { type: \"complete\" },\n content: [\n {\n type: \"text\",\n text: `<attachment name=${attachment.name}>\\n${await getFileText(attachment.file)}\\n</attachment>`,\n },\n ],\n };\n }\n\n public async remove() {\n // noop\n }\n}\n\nconst getFileText = async (file: File): Promise<string> => {\n if (typeof FileReader === \"undefined\") {\n return file.text();\n }\n return new Promise<string>((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = () => resolve(reader.result as string);\n reader.onerror = (error) => reject(error);\n reader.readAsText(file);\n });\n};\n\nexport function fileMatchesAccept(\n file: { name: string; type: string },\n acceptString: string,\n) {\n if (acceptString === \"*\") {\n return true;\n }\n\n const allowedTypes = acceptString\n .split(\",\")\n .map((type) => type.trim().toLowerCase());\n\n const fileExtension = `.${file.name.split(\".\").pop()!.toLowerCase()}`;\n const fileMimeType = file.type.toLowerCase();\n\n for (const type of allowedTypes) {\n if (type.startsWith(\".\") && type === fileExtension) {\n return true;\n }\n\n if (type.includes(\"/\") && type === fileMimeType) {\n return true;\n }\n\n if (type.endsWith(\"/*\")) {\n const generalType = type.split(\"/\")[0]!;\n if (fileMimeType.startsWith(`${generalType}/`)) {\n return true;\n }\n }\n }\n\n return false;\n}\n\nexport function attachmentsEqual(\n a: readonly CompleteAttachment[],\n b: readonly CompleteAttachment[],\n): boolean {\n if (a.length !== b.length) return false;\n return a.every((att, i) => att.id === b[i]!.id);\n}\n\nexport function partToCompleteAttachment(\n part: Exclude<ThreadUserMessagePart, { type: \"text\" }>,\n): CompleteAttachment {\n const id = generateId();\n\n if (part.type === \"image\") {\n return {\n id,\n type: \"image\",\n name: part.filename ?? \"image\",\n content: [part],\n status: { type: \"complete\" },\n };\n }\n\n if (part.type === \"file\") {\n return {\n id,\n type: \"document\",\n name: part.filename ?? \"document\",\n contentType: part.mimeType,\n content: [part],\n status: { type: \"complete\" },\n };\n }\n\n if (part.type === \"audio\") {\n return {\n id,\n type: \"audio\",\n name: `audio.${part.audio.format}`,\n contentType: `audio/${part.audio.format}`,\n content: [part],\n status: { type: \"complete\" },\n };\n }\n\n return {\n id,\n type: \"data\",\n name: part.name,\n content: [part],\n status: { type: \"complete\" },\n };\n}\n\nexport function liftNonTextParts(\n content: readonly ThreadUserMessagePart[],\n): CompleteAttachment[] {\n const result: CompleteAttachment[] = [];\n for (const part of content) {\n if (part.type !== \"text\") {\n result.push(partToCompleteAttachment(part));\n }\n }\n return result;\n}\n\nexport class CompositeAttachmentAdapter implements AttachmentAdapter {\n private _adapters: AttachmentAdapter[];\n\n public accept: string;\n\n constructor(adapters: AttachmentAdapter[]) {\n this._adapters = adapters;\n\n const wildcardIdx = adapters.findIndex((a) => a.accept === \"*\");\n if (wildcardIdx !== -1) {\n if (wildcardIdx !== adapters.length - 1)\n throw new Error(\n \"A wildcard adapter (handling all files) can only be specified as the last adapter.\",\n );\n\n this.accept = \"*\";\n } else {\n this.accept = adapters.map((a) => a.accept).join(\",\");\n }\n }\n\n public add(state: { file: File }) {\n for (const adapter of this._adapters) {\n if (fileMatchesAccept(state.file, adapter.accept)) {\n return adapter.add(state);\n }\n }\n throw new Error(\"No matching adapter found for file\");\n }\n\n public async send(attachment: PendingAttachment) {\n const adapters = this._adapters.slice();\n for (const adapter of adapters) {\n if (fileMatchesAccept(attachment.file, adapter.accept)) {\n return adapter.send(attachment);\n }\n }\n throw new Error(\"No matching adapter found for attachment\");\n }\n\n public async remove(attachment: Attachment) {\n const adapters = this._adapters.slice();\n for (const adapter of adapters) {\n if (\n fileMatchesAccept(\n {\n name: attachment.name,\n type: attachment.contentType ?? \"\",\n },\n adapter.accept,\n )\n ) {\n return adapter.remove(attachment);\n }\n }\n throw new Error(\"No matching adapter found for attachment\");\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"attachment.js","names":["Attachment","PendingAttachment","CompleteAttachment","ThreadUserMessagePart","generateId","AttachmentAdapter","accept","add","state","file","File","Promise","AsyncGenerator","remove","attachment","send","SimpleImageAttachmentAdapter","id","type","name","contentType","status","reason","content","image","getFileDataURL","bytesToBase64","bytes","Uint8Array","nodeBuffer","globalThis","Buffer","from","toString","encoding","binary","chunkSize","i","length","String","fromCharCode","subarray","btoa","FileReader","buffer","arrayBuffer","resolve","reject","reader","onload","result","onerror","error","readAsDataURL","SimpleTextAttachmentAdapter","text","getFileText","readAsText","fileMatchesAccept","acceptString","allowedTypes","split","map","trim","toLowerCase","fileExtension","pop","fileMimeType","startsWith","includes","endsWith","generalType","attachmentsEqual","a","b","every","att","partToCompleteAttachment","part","Exclude","filename","mimeType","audio","format","liftNonTextParts","push","CompositeAttachmentAdapter","_adapters","constructor","adapters","wildcardIdx","findIndex","Error","join","adapter","slice"],"sources":["../../src/adapters/attachment.ts"],"sourcesContent":["import type {\n Attachment,\n PendingAttachment,\n CompleteAttachment,\n} from \"../types/attachment\";\nimport type { ThreadUserMessagePart } from \"../types/message\";\nimport { generateId } from \"../utils/id\";\n\nexport type AttachmentAdapter = {\n accept: string;\n add(state: {\n file: File;\n }): Promise<PendingAttachment> | AsyncGenerator<PendingAttachment, void>;\n remove(attachment: Attachment): Promise<void>;\n send(attachment: PendingAttachment): Promise<CompleteAttachment>;\n};\n\nexport class SimpleImageAttachmentAdapter implements AttachmentAdapter {\n public accept = \"image/*\";\n\n public async add(state: { file: File }): Promise<PendingAttachment> {\n return {\n id: generateId(),\n type: \"image\",\n name: state.file.name,\n contentType: state.file.type,\n file: state.file,\n status: { type: \"requires-action\", reason: \"composer-send\" },\n };\n }\n\n public async send(\n attachment: PendingAttachment,\n ): Promise<CompleteAttachment> {\n return {\n ...attachment,\n status: { type: \"complete\" },\n content: [\n {\n type: \"image\",\n image: await getFileDataURL(attachment.file),\n },\n ],\n };\n }\n\n public async remove() {\n // noop\n }\n}\n\nconst bytesToBase64 = (bytes: Uint8Array): string => {\n const nodeBuffer = (\n globalThis as {\n Buffer?: {\n from(bytes: Uint8Array): { toString(encoding: string): string };\n };\n }\n ).Buffer;\n if (nodeBuffer) {\n return nodeBuffer.from(bytes).toString(\"base64\");\n }\n let binary = \"\";\n const chunkSize = 0x8000;\n for (let i = 0; i < bytes.length; i += chunkSize) {\n binary += String.fromCharCode(...bytes.subarray(i, i + chunkSize));\n }\n return btoa(binary);\n};\n\n// React Native's Blob polyfill has FileReader but not file.text()/arrayBuffer(); Node has\n// the reverse. Prefer FileReader when present, falling back to the Blob methods otherwise.\nexport const getFileDataURL = async (file: File): Promise<string> => {\n if (typeof FileReader === \"undefined\") {\n const buffer = await file.arrayBuffer();\n return `data:${file.type || \"application/octet-stream\"};base64,${bytesToBase64(new Uint8Array(buffer))}`;\n }\n return new Promise<string>((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = () => resolve(reader.result as string);\n reader.onerror = (error) => reject(error);\n reader.readAsDataURL(file);\n });\n};\n\nexport class SimpleTextAttachmentAdapter implements AttachmentAdapter {\n public accept =\n \"text/plain,text/html,text/markdown,text/csv,text/xml,text/json,application/json,text/css\";\n\n public async add(state: { file: File }): Promise<PendingAttachment> {\n return {\n id: generateId(),\n type: \"document\",\n name: state.file.name,\n contentType: state.file.type,\n file: state.file,\n status: { type: \"requires-action\", reason: \"composer-send\" },\n };\n }\n\n public async send(\n attachment: PendingAttachment,\n ): Promise<CompleteAttachment> {\n return {\n ...attachment,\n status: { type: \"complete\" },\n content: [\n {\n type: \"text\",\n text: `<attachment name=${attachment.name}>\\n${await getFileText(attachment.file)}\\n</attachment>`,\n },\n ],\n };\n }\n\n public async remove() {\n // noop\n }\n}\n\nconst getFileText = async (file: File): Promise<string> => {\n if (typeof FileReader === \"undefined\") {\n return file.text();\n }\n return new Promise<string>((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = () => resolve(reader.result as string);\n reader.onerror = (error) => reject(error);\n reader.readAsText(file);\n });\n};\n\nexport function fileMatchesAccept(\n file: { name: string; type: string },\n acceptString: string,\n) {\n if (acceptString === \"*\") {\n return true;\n }\n\n const allowedTypes = acceptString\n .split(\",\")\n .map((type) => type.trim().toLowerCase());\n\n const fileExtension = `.${file.name.split(\".\").pop()!.toLowerCase()}`;\n const fileMimeType = file.type.split(\";\", 1)[0]!.trim().toLowerCase();\n\n for (const type of allowedTypes) {\n if (type.startsWith(\".\") && type === fileExtension) {\n return true;\n }\n\n if (type.includes(\"/\") && type === fileMimeType) {\n return true;\n }\n\n if (type.endsWith(\"/*\")) {\n const generalType = type.split(\"/\")[0]!;\n if (fileMimeType.startsWith(`${generalType}/`)) {\n return true;\n }\n }\n }\n\n return false;\n}\n\nexport function attachmentsEqual(\n a: readonly CompleteAttachment[],\n b: readonly CompleteAttachment[],\n): boolean {\n if (a.length !== b.length) return false;\n return a.every((att, i) => att.id === b[i]!.id);\n}\n\nexport function partToCompleteAttachment(\n part: Exclude<ThreadUserMessagePart, { type: \"text\" }>,\n): CompleteAttachment {\n const id = generateId();\n\n if (part.type === \"image\") {\n return {\n id,\n type: \"image\",\n name: part.filename ?? \"image\",\n content: [part],\n status: { type: \"complete\" },\n };\n }\n\n if (part.type === \"file\") {\n return {\n id,\n type: \"document\",\n name: part.filename ?? \"document\",\n contentType: part.mimeType,\n content: [part],\n status: { type: \"complete\" },\n };\n }\n\n if (part.type === \"audio\") {\n return {\n id,\n type: \"audio\",\n name: `audio.${part.audio.format}`,\n contentType: `audio/${part.audio.format}`,\n content: [part],\n status: { type: \"complete\" },\n };\n }\n\n return {\n id,\n type: \"data\",\n name: part.name,\n content: [part],\n status: { type: \"complete\" },\n };\n}\n\nexport function liftNonTextParts(\n content: readonly ThreadUserMessagePart[],\n): CompleteAttachment[] {\n const result: CompleteAttachment[] = [];\n for (const part of content) {\n if (part.type !== \"text\") {\n result.push(partToCompleteAttachment(part));\n }\n }\n return result;\n}\n\nexport class CompositeAttachmentAdapter implements AttachmentAdapter {\n private _adapters: AttachmentAdapter[];\n\n public accept: string;\n\n constructor(adapters: AttachmentAdapter[]) {\n this._adapters = adapters;\n\n const wildcardIdx = adapters.findIndex((a) => a.accept === \"*\");\n if (wildcardIdx !== -1) {\n if (wildcardIdx !== adapters.length - 1)\n throw new Error(\n \"A wildcard adapter (handling all files) can only be specified as the last adapter.\",\n );\n\n this.accept = \"*\";\n } else {\n this.accept = adapters.map((a) => a.accept).join(\",\");\n }\n }\n\n public add(state: { file: File }) {\n for (const adapter of this._adapters) {\n if (fileMatchesAccept(state.file, adapter.accept)) {\n return adapter.add(state);\n }\n }\n throw new Error(\"No matching adapter found for file\");\n }\n\n public async send(attachment: PendingAttachment) {\n const adapters = this._adapters.slice();\n for (const adapter of adapters) {\n if (fileMatchesAccept(attachment.file, adapter.accept)) {\n return adapter.send(attachment);\n }\n }\n throw new Error(\"No matching adapter found for attachment\");\n }\n\n public async remove(attachment: Attachment) {\n const adapters = this._adapters.slice();\n for (const adapter of adapters) {\n if (\n fileMatchesAccept(\n {\n name: attachment.name,\n type: attachment.contentType ?? \"\",\n },\n adapter.accept,\n )\n ) {\n return adapter.remove(attachment);\n }\n }\n throw new Error(\"No matching adapter found for attachment\");\n }\n}\n"],"mappings":"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"}
@@ -1,5 +1,4 @@
1
1
  import { Unstable_DirectiveFormatter } from "../types/directive.js";
2
-
3
2
  //#region src/adapters/directive-formatter.d.ts
4
3
  /**
5
4
  * Default directive formatter using the `:type[label]{name=id}` syntax.
@@ -1 +1 @@
1
- {"version":3,"file":"directive-formatter.d.ts","names":[],"sources":["../../src/adapters/directive-formatter.ts"],"mappings":";;;;;AAcA;;;cAAa,kCAAA,EAAoC,2BAiChD"}
1
+ {"version":3,"file":"directive-formatter.d.ts","names":[],"sources":["../../src/adapters/directive-formatter.ts"],"mappings":";;;;;;;cAca,oCAAoC"}
@@ -1,5 +1,4 @@
1
1
  import { ThreadMessage } from "../types/message.js";
2
-
3
2
  //#region src/adapters/feedback.d.ts
4
3
  type FeedbackAdapterFeedback = {
5
4
  message: ThreadMessage;
@@ -1 +1 @@
1
- {"version":3,"file":"feedback.d.ts","names":[],"sources":["../../src/adapters/feedback.ts"],"mappings":";;;KAEK,uBAAA;EACH,OAAA,EAAS,aAAa;EACtB,IAAA;AAAA;AAAA,KAGU,eAAA;EACV,MAAA,GAAS,QAAA,EAAU,uBAAuB;AAAA"}
1
+ {"version":3,"file":"feedback.d.ts","names":[],"sources":["../../src/adapters/feedback.ts"],"mappings":";;KAEK;EACH,SAAS;EACT;;KAGU;EACV,SAAS,UAAU"}
@@ -3,7 +3,7 @@ import { unstable_defaultDirectiveFormatter } from "./directive-formatter.js";
3
3
  import { FeedbackAdapter } from "./feedback.js";
4
4
  import { DictationAdapter, SpeechSynthesisAdapter, WebSpeechDictationAdapter, WebSpeechSynthesisAdapter } from "./speech.js";
5
5
  import { RealtimeVoiceAdapter, VoiceSessionControls, VoiceSessionHelpers, createVoiceSession } from "./voice.js";
6
- import { SuggestionAdapter } from "./suggestion.js";
6
+ import { CreateSuggestionAdapterOptions, SuggestionAdapter, SuggestionAdapterGenerateOptions, createSuggestionAdapter } from "./suggestion.js";
7
7
  import { Unstable_TriggerAdapter } from "./trigger.js";
8
8
  import { GenericThreadHistoryAdapter, MessageFormatAdapter, MessageFormatItem, MessageFormatRepository, MessageStorageEntry, ThreadHistoryAdapter } from "./thread-history.js";
9
- export { type AttachmentAdapter, CompositeAttachmentAdapter, type DictationAdapter, type FeedbackAdapter, type GenericThreadHistoryAdapter, type MessageFormatAdapter, type MessageFormatItem, type MessageFormatRepository, type MessageStorageEntry, type RealtimeVoiceAdapter, SimpleImageAttachmentAdapter, SimpleTextAttachmentAdapter, type SpeechSynthesisAdapter, type SuggestionAdapter, type ThreadHistoryAdapter, type Unstable_TriggerAdapter, type VoiceSessionControls, type VoiceSessionHelpers, WebSpeechDictationAdapter, WebSpeechSynthesisAdapter, createVoiceSession, unstable_defaultDirectiveFormatter };
9
+ export { type AttachmentAdapter, CompositeAttachmentAdapter, type CreateSuggestionAdapterOptions, type DictationAdapter, type FeedbackAdapter, type GenericThreadHistoryAdapter, type MessageFormatAdapter, type MessageFormatItem, type MessageFormatRepository, type MessageStorageEntry, type RealtimeVoiceAdapter, SimpleImageAttachmentAdapter, SimpleTextAttachmentAdapter, type SpeechSynthesisAdapter, type SuggestionAdapter, type SuggestionAdapterGenerateOptions, type ThreadHistoryAdapter, type Unstable_TriggerAdapter, type VoiceSessionControls, type VoiceSessionHelpers, WebSpeechDictationAdapter, WebSpeechSynthesisAdapter, createSuggestionAdapter, createVoiceSession, unstable_defaultDirectiveFormatter };
@@ -1,5 +1,6 @@
1
1
  import { CompositeAttachmentAdapter, SimpleImageAttachmentAdapter, SimpleTextAttachmentAdapter } from "./attachment.js";
2
2
  import { WebSpeechDictationAdapter, WebSpeechSynthesisAdapter } from "./speech.js";
3
3
  import { createVoiceSession } from "./voice.js";
4
+ import { createSuggestionAdapter } from "./suggestion.js";
4
5
  import { unstable_defaultDirectiveFormatter } from "./directive-formatter.js";
5
- export { CompositeAttachmentAdapter, SimpleImageAttachmentAdapter, SimpleTextAttachmentAdapter, WebSpeechDictationAdapter, WebSpeechSynthesisAdapter, createVoiceSession, unstable_defaultDirectiveFormatter };
6
+ export { CompositeAttachmentAdapter, SimpleImageAttachmentAdapter, SimpleTextAttachmentAdapter, WebSpeechDictationAdapter, WebSpeechSynthesisAdapter, createSuggestionAdapter, createVoiceSession, unstable_defaultDirectiveFormatter };
@@ -1,5 +1,4 @@
1
1
  import { Unsubscribe } from "../types/unsubscribe.js";
2
-
3
2
  //#region src/adapters/speech.d.ts
4
3
  declare namespace SpeechSynthesisAdapter {
5
4
  type Status = {
@@ -1 +1 @@
1
- {"version":3,"file":"speech.d.ts","names":[],"sources":["../../src/adapters/speech.ts"],"mappings":";;;kBAEiB,sBAAA;EAAA,KACH,MAAA;IAEN,IAAA;EAAA;IAGA,IAAA;IACA,MAAA;IACA,KAAA;EAAA;EAAA,KAGM,SAAA;IACV,MAAA,EAAQ,MAAA;IACR,MAAA;IACA,SAAA,GAAY,QAAA,iBAAyB,WAAW;EAAA;AAAA;AAAA,KAIxC,sBAAA;EACV,KAAA,GAAQ,IAAA,aAAiB,sBAAA,CAAuB,SAAS;AAAA;AAAA,kBAG1C,gBAAA;EAAA,KACH,MAAA;IAEN,IAAA;EAAA;IAGA,IAAA;IACA,MAAA;EAAA;EAAA,KAGM,MAAA;IACV,UAAA;IACA,OAAA;EAAA;EAAA,KAGU,OAAA;IACV,MAAA,EAAQ,MAAA;IACR,IAAA,QAAY,OAAA;IACZ,MAAA;IACA,aAAA,GAAgB,QAAA,iBAAyB,WAAA;IACzC,WAAA,GAAc,QAAA,GAAW,MAAA,EAAQ,MAAA,cAAoB,WAAA;IACrD,QAAA,GAAW,QAAA,GAAW,MAAA,EAAQ,MAAA,cAAoB,WAAA;EAAA;AAAA;AAAA,KAI1C,gBAAA;EACV,MAAA,QAAc,gBAAA,CAAiB,OAAO;EACtC,2BAAA;AAAA;AAAA,cAGW,yBAAA,YAAqC,sBAAsB;EACtE,KAAA,CAAM,IAAA,WAAe,sBAAA,CAAuB,SAAA;AAAA;AAAA,UA0EpC,yBAAA,SAAkC,WAAW;EACrD,IAAA;EACA,UAAA;EACA,cAAA;EACA,KAAA;EACA,IAAA;EACA,KAAA;AAAA;AAAA,UAGQ,4BAAA;EAAA,QACA,yBAAyB;AAAA;AAAA,QAG3B,MAAA;EAAA,UACI,MAAA;IACR,iBAAA,GAAoB,4BAAA;IACpB,uBAAA,GAA0B,4BAA4B;EAAA;AAAA;AAAA,cAW7C,yBAAA,YAAqC,gBAAgB;EAAA,QACxD,SAAA;EAAA,QACA,WAAA;EAAA,QACA,eAAA;cAGN,OAAA;IACE,QAAA;IACA,UAAA;IACA,cAAA;EAAA;EAAA,OAYG,WAAA;EAIP,MAAA,IAAU,gBAAA,CAAiB,OAAA;AAAA"}
1
+ {"version":3,"file":"speech.d.ts","names":[],"sources":["../../src/adapters/speech.ts"],"mappings":";;kBAEiB;OACH;IAEN;;IAGA;IACA;IACA;;OAGM;IACV,QAAQ;IACR;IACA,YAAY,yBAAyB;;;KAI7B;EACV,QAAQ,iBAAiB,uBAAuB;;kBAkBjC;OACH;IAEN;;IAGA;IACA;;OAGM;IACV;IACA;;OAGU;IACV,QAAQ;IACR,YAAY;IACZ;IACA,gBAAgB,yBAAyB;IACzC,cAAc,WAAW,QAAQ,oBAAoB;IACrD,WAAW,WAAW,QAAQ,oBAAoB;;;KAI1C;EACV,cAAc,iBAAiB;EAC/B;;cAGW,qCAAqC;EAChD,MAAM,eAAe,uBAAuB;;UA0EpC,kCAAkC;EAC1C;EACA;EACA;EACA;EACA;EACA;;UAGQ;UACA;;QAGF;YACI;IACR,oBAAoB;IACpB,0BAA0B;;;cAWjB,qCAAqC;UACxC;UACA;UACA;EAGN,YAAA;IACE;IACA;IACA;;SAYG;EAIP,UAAU,iBAAiB"}
@@ -1,4 +1,11 @@
1
1
  //#region src/adapters/speech.ts
2
+ const notifySpeechSynthesisListeners = (listeners) => {
3
+ for (const listener of listeners) try {
4
+ listener();
5
+ } catch (error) {
6
+ console.error("[assistant-ui] Speech synthesis listener threw an error", error);
7
+ }
8
+ };
2
9
  var WebSpeechSynthesisAdapter = class {
3
10
  speak(text) {
4
11
  const utterance = new SpeechSynthesisUtterance(text);
@@ -10,7 +17,7 @@ var WebSpeechSynthesisAdapter = class {
10
17
  reason,
11
18
  error
12
19
  };
13
- subscribers.forEach((handler) => handler());
20
+ notifySpeechSynthesisListeners(subscribers);
14
21
  };
15
22
  utterance.addEventListener("end", () => handleEnd("finished"));
16
23
  utterance.addEventListener("error", (e) => handleEnd("error", e.error));
@@ -25,7 +32,7 @@ var WebSpeechSynthesisAdapter = class {
25
32
  if (res.status.type === "ended") {
26
33
  let cancelled = false;
27
34
  queueMicrotask(() => {
28
- if (!cancelled) callback();
35
+ if (!cancelled) notifySpeechSynthesisListeners([callback]);
29
36
  });
30
37
  return () => {
31
38
  cancelled = true;
@@ -1 +1 @@
1
- {"version":3,"file":"speech.js","names":["Unsubscribe","SpeechSynthesisAdapter","Status","type","reason","error","Utterance","status","cancel","subscribe","callback","speak","text","DictationAdapter","Result","transcript","isFinal","Session","stop","Promise","onSpeechStart","onSpeechEnd","result","onSpeech","listen","disableInputDuringDictation","WebSpeechSynthesisAdapter","utterance","SpeechSynthesisUtterance","subscribers","Set","handleEnd","res","forEach","handler","addEventListener","e","window","speechSynthesis","cancelled","queueMicrotask","add","delete","SpeechRecognitionResultItem","confidence","SpeechRecognitionResult","length","item","index","SpeechRecognitionResultList","SpeechRecognitionEvent","Event","resultIndex","results","SpeechRecognitionErrorEvent","message","SpeechRecognitionInstance","EventTarget","lang","continuous","interimResults","start","abort","SpeechRecognitionConstructor","global","Window","SpeechRecognition","webkitSpeechRecognition","getSpeechRecognitionAPI","undefined","WebSpeechDictationAdapter","_language","_continuous","_interimResults","constructor","options","language","defaultLanguage","navigator","isSupported","SpeechRecognitionAPI","Error","recognition","speechStartCallbacks","speechEndCallbacks","speechCallbacks","finalTranscript","session","resolve","checkEnded","setTimeout","updateStatus","newStatus","cb","event","speechEvent","i","currentStatus","errorEvent","console"],"sources":["../../src/adapters/speech.ts"],"sourcesContent":["import type { Unsubscribe } from \"../types/unsubscribe\";\n\nexport namespace SpeechSynthesisAdapter {\n export type Status =\n | {\n type: \"starting\" | \"running\";\n }\n | {\n type: \"ended\";\n reason: \"finished\" | \"cancelled\" | \"error\";\n error?: unknown;\n };\n\n export type Utterance = {\n status: Status;\n cancel: () => void;\n subscribe: (callback: () => void) => Unsubscribe;\n };\n}\n\nexport type SpeechSynthesisAdapter = {\n speak: (text: string) => SpeechSynthesisAdapter.Utterance;\n};\n\nexport namespace DictationAdapter {\n export type Status =\n | {\n type: \"starting\" | \"running\";\n }\n | {\n type: \"ended\";\n reason: \"stopped\" | \"cancelled\" | \"error\";\n };\n\n export type Result = {\n transcript: string;\n isFinal?: boolean;\n };\n\n export type Session = {\n status: Status;\n stop: () => Promise<void>;\n cancel: () => void;\n onSpeechStart: (callback: () => void) => Unsubscribe;\n onSpeechEnd: (callback: (result: Result) => void) => Unsubscribe;\n onSpeech: (callback: (result: Result) => void) => Unsubscribe;\n };\n}\n\nexport type DictationAdapter = {\n listen: () => DictationAdapter.Session;\n disableInputDuringDictation?: boolean;\n};\n\nexport class WebSpeechSynthesisAdapter implements SpeechSynthesisAdapter {\n speak(text: string): SpeechSynthesisAdapter.Utterance {\n const utterance = new SpeechSynthesisUtterance(text);\n\n const subscribers = new Set<() => void>();\n const handleEnd = (\n reason: \"finished\" | \"error\" | \"cancelled\",\n error?: unknown,\n ) => {\n if (res.status.type === \"ended\") return;\n\n res.status = { type: \"ended\", reason, error };\n subscribers.forEach((handler) => handler());\n };\n\n utterance.addEventListener(\"end\", () => handleEnd(\"finished\"));\n utterance.addEventListener(\"error\", (e) => handleEnd(\"error\", e.error));\n\n window.speechSynthesis.speak(utterance);\n\n const res: SpeechSynthesisAdapter.Utterance = {\n status: { type: \"running\" },\n cancel: () => {\n window.speechSynthesis.cancel();\n handleEnd(\"cancelled\");\n },\n subscribe: (callback) => {\n if (res.status.type === \"ended\") {\n let cancelled = false;\n queueMicrotask(() => {\n if (!cancelled) callback();\n });\n return () => {\n cancelled = true;\n };\n } else {\n subscribers.add(callback);\n return () => {\n subscribers.delete(callback);\n };\n }\n },\n };\n return res;\n }\n}\n\ninterface SpeechRecognitionResultItem {\n transcript: string;\n confidence: number;\n}\n\ninterface SpeechRecognitionResult {\n readonly length: number;\n item(index: number): SpeechRecognitionResultItem;\n readonly isFinal: boolean;\n [index: number]: SpeechRecognitionResultItem;\n}\n\ninterface SpeechRecognitionResultList {\n readonly length: number;\n item(index: number): SpeechRecognitionResult;\n [index: number]: SpeechRecognitionResult;\n}\n\ninterface SpeechRecognitionEvent extends Event {\n readonly resultIndex: number;\n readonly results: SpeechRecognitionResultList;\n}\n\ninterface SpeechRecognitionErrorEvent extends Event {\n readonly error: string;\n readonly message: string;\n}\n\ninterface SpeechRecognitionInstance extends EventTarget {\n lang: string;\n continuous: boolean;\n interimResults: boolean;\n start(): void;\n stop(): void;\n abort(): void;\n}\n\ninterface SpeechRecognitionConstructor {\n new (): SpeechRecognitionInstance;\n}\n\ndeclare global {\n interface Window {\n SpeechRecognition?: SpeechRecognitionConstructor;\n webkitSpeechRecognition?: SpeechRecognitionConstructor;\n }\n}\n\nconst getSpeechRecognitionAPI = ():\n | SpeechRecognitionConstructor\n | undefined => {\n if (typeof window === \"undefined\") return undefined;\n return window.SpeechRecognition ?? window.webkitSpeechRecognition;\n};\n\nexport class WebSpeechDictationAdapter implements DictationAdapter {\n private _language: string;\n private _continuous: boolean;\n private _interimResults: boolean;\n\n constructor(\n options: {\n language?: string;\n continuous?: boolean;\n interimResults?: boolean;\n } = {},\n ) {\n const defaultLanguage =\n typeof navigator !== \"undefined\" && navigator.language\n ? navigator.language\n : \"en-US\";\n this._language = options.language ?? defaultLanguage;\n this._continuous = options.continuous ?? true;\n this._interimResults = options.interimResults ?? true;\n }\n\n static isSupported(): boolean {\n return getSpeechRecognitionAPI() !== undefined;\n }\n\n listen(): DictationAdapter.Session {\n const SpeechRecognitionAPI = getSpeechRecognitionAPI();\n if (!SpeechRecognitionAPI) {\n throw new Error(\n \"SpeechRecognition is not supported in this browser. \" +\n \"Try using Chrome, Edge, or Safari.\",\n );\n }\n\n const recognition = new SpeechRecognitionAPI();\n recognition.lang = this._language;\n recognition.continuous = this._continuous;\n recognition.interimResults = this._interimResults;\n\n const speechStartCallbacks = new Set<() => void>();\n const speechEndCallbacks = new Set<\n (result: DictationAdapter.Result) => void\n >();\n const speechCallbacks = new Set<\n (result: DictationAdapter.Result) => void\n >();\n\n let finalTranscript = \"\";\n\n const session: DictationAdapter.Session = {\n status: { type: \"starting\" },\n\n stop: async () => {\n recognition.stop();\n return new Promise<void>((resolve) => {\n const checkEnded = () => {\n if (session.status.type === \"ended\") {\n resolve();\n } else {\n setTimeout(checkEnded, 50);\n }\n };\n checkEnded();\n });\n },\n\n cancel: () => {\n recognition.abort();\n },\n\n onSpeechStart: (callback: () => void): Unsubscribe => {\n speechStartCallbacks.add(callback);\n return () => {\n speechStartCallbacks.delete(callback);\n };\n },\n\n onSpeechEnd: (\n callback: (result: DictationAdapter.Result) => void,\n ): Unsubscribe => {\n speechEndCallbacks.add(callback);\n return () => {\n speechEndCallbacks.delete(callback);\n };\n },\n\n onSpeech: (\n callback: (result: DictationAdapter.Result) => void,\n ): Unsubscribe => {\n speechCallbacks.add(callback);\n return () => {\n speechCallbacks.delete(callback);\n };\n },\n };\n\n const updateStatus = (newStatus: DictationAdapter.Status) => {\n session.status = newStatus;\n };\n\n recognition.addEventListener(\"speechstart\", () => {\n for (const cb of speechStartCallbacks) cb();\n });\n\n recognition.addEventListener(\"start\", () => {\n updateStatus({ type: \"running\" });\n });\n\n recognition.addEventListener(\"result\", (event) => {\n const speechEvent = event as unknown as SpeechRecognitionEvent;\n\n for (\n let i = speechEvent.resultIndex;\n i < speechEvent.results.length;\n i++\n ) {\n const result = speechEvent.results[i];\n if (!result) continue;\n\n const transcript = result[0]?.transcript ?? \"\";\n\n if (result.isFinal) {\n finalTranscript += transcript;\n for (const cb of speechCallbacks) cb({ transcript, isFinal: true });\n } else {\n for (const cb of speechCallbacks) cb({ transcript, isFinal: false });\n }\n }\n });\n\n recognition.addEventListener(\"speechend\", () => {\n // speechend fires when user stops speaking, but 'end' handles final cleanup\n });\n\n recognition.addEventListener(\"end\", () => {\n const currentStatus = session.status;\n if (currentStatus.type !== \"ended\") {\n updateStatus({ type: \"ended\", reason: \"stopped\" });\n }\n if (finalTranscript) {\n for (const cb of speechEndCallbacks)\n cb({ transcript: finalTranscript });\n finalTranscript = \"\";\n }\n });\n\n recognition.addEventListener(\"error\", (event) => {\n const errorEvent = event as unknown as SpeechRecognitionErrorEvent;\n if (errorEvent.error === \"aborted\") {\n updateStatus({ type: \"ended\", reason: \"cancelled\" });\n } else {\n updateStatus({ type: \"ended\", reason: \"error\" });\n console.error(\"Dictation error:\", errorEvent.error, errorEvent.message);\n }\n });\n\n try {\n recognition.start();\n } catch (error) {\n updateStatus({ type: \"ended\", reason: \"error\" });\n throw error;\n }\n\n return session;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"speech.js","names":["Unsubscribe","SpeechSynthesisAdapter","Status","type","reason","error","Utterance","status","cancel","subscribe","callback","speak","text","notifySpeechSynthesisListeners","listeners","Iterable","listener","console","DictationAdapter","Result","transcript","isFinal","Session","stop","Promise","onSpeechStart","onSpeechEnd","result","onSpeech","listen","disableInputDuringDictation","WebSpeechSynthesisAdapter","utterance","SpeechSynthesisUtterance","subscribers","Set","handleEnd","res","addEventListener","e","window","speechSynthesis","cancelled","queueMicrotask","add","delete","SpeechRecognitionResultItem","confidence","SpeechRecognitionResult","length","item","index","SpeechRecognitionResultList","SpeechRecognitionEvent","Event","resultIndex","results","SpeechRecognitionErrorEvent","message","SpeechRecognitionInstance","EventTarget","lang","continuous","interimResults","start","abort","SpeechRecognitionConstructor","global","Window","SpeechRecognition","webkitSpeechRecognition","getSpeechRecognitionAPI","undefined","WebSpeechDictationAdapter","_language","_continuous","_interimResults","constructor","options","language","defaultLanguage","navigator","isSupported","SpeechRecognitionAPI","Error","recognition","speechStartCallbacks","speechEndCallbacks","speechCallbacks","finalTranscript","session","resolve","checkEnded","setTimeout","updateStatus","newStatus","cb","event","speechEvent","i","currentStatus","errorEvent"],"sources":["../../src/adapters/speech.ts"],"sourcesContent":["import type { Unsubscribe } from \"../types/unsubscribe\";\n\nexport namespace SpeechSynthesisAdapter {\n export type Status =\n | {\n type: \"starting\" | \"running\";\n }\n | {\n type: \"ended\";\n reason: \"finished\" | \"cancelled\" | \"error\";\n error?: unknown;\n };\n\n export type Utterance = {\n status: Status;\n cancel: () => void;\n subscribe: (callback: () => void) => Unsubscribe;\n };\n}\n\nexport type SpeechSynthesisAdapter = {\n speak: (text: string) => SpeechSynthesisAdapter.Utterance;\n};\n\nconst notifySpeechSynthesisListeners = (\n listeners: Iterable<() => void>,\n): void => {\n for (const listener of listeners) {\n try {\n listener();\n } catch (error) {\n console.error(\n \"[assistant-ui] Speech synthesis listener threw an error\",\n error,\n );\n }\n }\n};\n\nexport namespace DictationAdapter {\n export type Status =\n | {\n type: \"starting\" | \"running\";\n }\n | {\n type: \"ended\";\n reason: \"stopped\" | \"cancelled\" | \"error\";\n };\n\n export type Result = {\n transcript: string;\n isFinal?: boolean;\n };\n\n export type Session = {\n status: Status;\n stop: () => Promise<void>;\n cancel: () => void;\n onSpeechStart: (callback: () => void) => Unsubscribe;\n onSpeechEnd: (callback: (result: Result) => void) => Unsubscribe;\n onSpeech: (callback: (result: Result) => void) => Unsubscribe;\n };\n}\n\nexport type DictationAdapter = {\n listen: () => DictationAdapter.Session;\n disableInputDuringDictation?: boolean;\n};\n\nexport class WebSpeechSynthesisAdapter implements SpeechSynthesisAdapter {\n speak(text: string): SpeechSynthesisAdapter.Utterance {\n const utterance = new SpeechSynthesisUtterance(text);\n\n const subscribers = new Set<() => void>();\n const handleEnd = (\n reason: \"finished\" | \"error\" | \"cancelled\",\n error?: unknown,\n ) => {\n if (res.status.type === \"ended\") return;\n\n res.status = { type: \"ended\", reason, error };\n notifySpeechSynthesisListeners(subscribers);\n };\n\n utterance.addEventListener(\"end\", () => handleEnd(\"finished\"));\n utterance.addEventListener(\"error\", (e) => handleEnd(\"error\", e.error));\n\n window.speechSynthesis.speak(utterance);\n\n const res: SpeechSynthesisAdapter.Utterance = {\n status: { type: \"running\" },\n cancel: () => {\n window.speechSynthesis.cancel();\n handleEnd(\"cancelled\");\n },\n subscribe: (callback) => {\n if (res.status.type === \"ended\") {\n let cancelled = false;\n queueMicrotask(() => {\n if (!cancelled) notifySpeechSynthesisListeners([callback]);\n });\n return () => {\n cancelled = true;\n };\n } else {\n subscribers.add(callback);\n return () => {\n subscribers.delete(callback);\n };\n }\n },\n };\n return res;\n }\n}\n\ninterface SpeechRecognitionResultItem {\n transcript: string;\n confidence: number;\n}\n\ninterface SpeechRecognitionResult {\n readonly length: number;\n item(index: number): SpeechRecognitionResultItem;\n readonly isFinal: boolean;\n [index: number]: SpeechRecognitionResultItem;\n}\n\ninterface SpeechRecognitionResultList {\n readonly length: number;\n item(index: number): SpeechRecognitionResult;\n [index: number]: SpeechRecognitionResult;\n}\n\ninterface SpeechRecognitionEvent extends Event {\n readonly resultIndex: number;\n readonly results: SpeechRecognitionResultList;\n}\n\ninterface SpeechRecognitionErrorEvent extends Event {\n readonly error: string;\n readonly message: string;\n}\n\ninterface SpeechRecognitionInstance extends EventTarget {\n lang: string;\n continuous: boolean;\n interimResults: boolean;\n start(): void;\n stop(): void;\n abort(): void;\n}\n\ninterface SpeechRecognitionConstructor {\n new (): SpeechRecognitionInstance;\n}\n\ndeclare global {\n interface Window {\n SpeechRecognition?: SpeechRecognitionConstructor;\n webkitSpeechRecognition?: SpeechRecognitionConstructor;\n }\n}\n\nconst getSpeechRecognitionAPI = ():\n | SpeechRecognitionConstructor\n | undefined => {\n if (typeof window === \"undefined\") return undefined;\n return window.SpeechRecognition ?? window.webkitSpeechRecognition;\n};\n\nexport class WebSpeechDictationAdapter implements DictationAdapter {\n private _language: string;\n private _continuous: boolean;\n private _interimResults: boolean;\n\n constructor(\n options: {\n language?: string;\n continuous?: boolean;\n interimResults?: boolean;\n } = {},\n ) {\n const defaultLanguage =\n typeof navigator !== \"undefined\" && navigator.language\n ? navigator.language\n : \"en-US\";\n this._language = options.language ?? defaultLanguage;\n this._continuous = options.continuous ?? true;\n this._interimResults = options.interimResults ?? true;\n }\n\n static isSupported(): boolean {\n return getSpeechRecognitionAPI() !== undefined;\n }\n\n listen(): DictationAdapter.Session {\n const SpeechRecognitionAPI = getSpeechRecognitionAPI();\n if (!SpeechRecognitionAPI) {\n throw new Error(\n \"SpeechRecognition is not supported in this browser. \" +\n \"Try using Chrome, Edge, or Safari.\",\n );\n }\n\n const recognition = new SpeechRecognitionAPI();\n recognition.lang = this._language;\n recognition.continuous = this._continuous;\n recognition.interimResults = this._interimResults;\n\n const speechStartCallbacks = new Set<() => void>();\n const speechEndCallbacks = new Set<\n (result: DictationAdapter.Result) => void\n >();\n const speechCallbacks = new Set<\n (result: DictationAdapter.Result) => void\n >();\n\n let finalTranscript = \"\";\n\n const session: DictationAdapter.Session = {\n status: { type: \"starting\" },\n\n stop: async () => {\n recognition.stop();\n return new Promise<void>((resolve) => {\n const checkEnded = () => {\n if (session.status.type === \"ended\") {\n resolve();\n } else {\n setTimeout(checkEnded, 50);\n }\n };\n checkEnded();\n });\n },\n\n cancel: () => {\n recognition.abort();\n },\n\n onSpeechStart: (callback: () => void): Unsubscribe => {\n speechStartCallbacks.add(callback);\n return () => {\n speechStartCallbacks.delete(callback);\n };\n },\n\n onSpeechEnd: (\n callback: (result: DictationAdapter.Result) => void,\n ): Unsubscribe => {\n speechEndCallbacks.add(callback);\n return () => {\n speechEndCallbacks.delete(callback);\n };\n },\n\n onSpeech: (\n callback: (result: DictationAdapter.Result) => void,\n ): Unsubscribe => {\n speechCallbacks.add(callback);\n return () => {\n speechCallbacks.delete(callback);\n };\n },\n };\n\n const updateStatus = (newStatus: DictationAdapter.Status) => {\n session.status = newStatus;\n };\n\n recognition.addEventListener(\"speechstart\", () => {\n for (const cb of speechStartCallbacks) cb();\n });\n\n recognition.addEventListener(\"start\", () => {\n updateStatus({ type: \"running\" });\n });\n\n recognition.addEventListener(\"result\", (event) => {\n const speechEvent = event as unknown as SpeechRecognitionEvent;\n\n for (\n let i = speechEvent.resultIndex;\n i < speechEvent.results.length;\n i++\n ) {\n const result = speechEvent.results[i];\n if (!result) continue;\n\n const transcript = result[0]?.transcript ?? \"\";\n\n if (result.isFinal) {\n finalTranscript += transcript;\n for (const cb of speechCallbacks) cb({ transcript, isFinal: true });\n } else {\n for (const cb of speechCallbacks) cb({ transcript, isFinal: false });\n }\n }\n });\n\n recognition.addEventListener(\"speechend\", () => {\n // speechend fires when user stops speaking, but 'end' handles final cleanup\n });\n\n recognition.addEventListener(\"end\", () => {\n const currentStatus = session.status;\n if (currentStatus.type !== \"ended\") {\n updateStatus({ type: \"ended\", reason: \"stopped\" });\n }\n if (finalTranscript) {\n for (const cb of speechEndCallbacks)\n cb({ transcript: finalTranscript });\n finalTranscript = \"\";\n }\n });\n\n recognition.addEventListener(\"error\", (event) => {\n const errorEvent = event as unknown as SpeechRecognitionErrorEvent;\n if (errorEvent.error === \"aborted\") {\n updateStatus({ type: \"ended\", reason: \"cancelled\" });\n } else {\n updateStatus({ type: \"ended\", reason: \"error\" });\n console.error(\"Dictation error:\", errorEvent.error, errorEvent.message);\n }\n });\n\n try {\n recognition.start();\n } catch (error) {\n updateStatus({ type: \"ended\", reason: \"error\" });\n throw error;\n }\n\n return session;\n }\n}\n"],"mappings":";AAwBA,MAAMa,kCACJC,cACS;CACT,KAAK,MAAME,YAAYF,WACrB,IAAI;EACFE,SAAS;CACX,SAASX,OAAO;EACdY,QAAQZ,MACN,2DACAA,KACF;CACF;AAEJ;AAgCA,IAAa0B,4BAAb,MAAyE;CACvEpB,MAAMC,MAAgD;EACpD,MAAMoB,YAAY,IAAIC,yBAAyBrB,IAAI;EAEnD,MAAMsB,8BAAc,IAAIC,IAAgB;EACxC,MAAMC,aACJhC,QACAC,UACG;GACH,IAAIgC,IAAI9B,OAAOJ,SAAS,SAAS;GAEjCkC,IAAI9B,SAAS;IAAEJ,MAAM;IAASC;IAAQC;GAAM;GAC5CQ,+BAA+BqB,WAAW;EAC5C;EAEAF,UAAUM,iBAAiB,aAAaF,UAAU,UAAU,CAAC;EAC7DJ,UAAUM,iBAAiB,UAAUC,MAAMH,UAAU,SAASG,EAAElC,KAAK,CAAC;EAEtEmC,OAAOC,gBAAgB9B,MAAMqB,SAAS;EAEtC,MAAMK,MAAwC;GAC5C9B,QAAQ,EAAEJ,MAAM,UAAU;GAC1BK,cAAc;IACZgC,OAAOC,gBAAgBjC,OAAO;IAC9B4B,UAAU,WAAW;GACvB;GACA3B,YAAYC,aAAa;IACvB,IAAI2B,IAAI9B,OAAOJ,SAAS,SAAS;KAC/B,IAAIuC,YAAY;KAChBC,qBAAqB;MACnB,IAAI,CAACD,WAAW7B,+BAA+B,CAACH,QAAQ,CAAC;KAC3D,CAAC;KACD,aAAa;MACXgC,YAAY;KACd;IACF,OAAO;KACLR,YAAYU,IAAIlC,QAAQ;KACxB,aAAa;MACXwB,YAAYW,OAAOnC,QAAQ;KAC7B;IACF;GACF;EACF;EACA,OAAO2B;CACT;AACF;AAkDA,MAAMkC,gCAEW;CACf,IAAI,OAAO/B,WAAW,aAAa,OAAOgC,KAAAA;CAC1C,OAAOhC,OAAO6B,qBAAqB7B,OAAO8B;AAC5C;AAEA,IAAaG,4BAAb,MAAmE;CACjE;CACA;CACA;CAEAI,YACEC,UAII,CAAC,GACL;EACA,MAAME,kBACJ,OAAOC,cAAc,eAAeA,UAAUF,WAC1CE,UAAUF,WACV;EACN,KAAKL,YAAYI,QAAQC,YAAYC;EACrC,KAAKL,cAAcG,QAAQhB,cAAc;EACzC,KAAKc,kBAAkBE,QAAQf,kBAAkB;CACnD;CAEA,OAAOmB,cAAuB;EAC5B,OAAOX,wBAAwB,MAAMC,KAAAA;CACvC;CAEA3C,SAAmC;EACjC,MAAMsD,uBAAuBZ,wBAAwB;EACrD,IAAI,CAACY,sBACH,MAAM,IAAIC,MACR,wFAEF;EAGF,MAAMC,cAAc,IAAIF,qBAAqB;EAC7CE,YAAYxB,OAAO,KAAKa;EACxBW,YAAYvB,aAAa,KAAKa;EAC9BU,YAAYtB,iBAAiB,KAAKa;EAElC,MAAMU,uCAAuB,IAAInD,IAAgB;EACjD,MAAMoD,qCAAqB,IAAIpD,IAE7B;EACF,MAAMqD,kCAAkB,IAAIrD,IAE1B;EAEF,IAAIsD,kBAAkB;EAEtB,MAAMC,UAAoC;GACxCnF,QAAQ,EAAEJ,MAAM,WAAW;GAE3BoB,MAAM,YAAY;IAChB8D,YAAY9D,KAAK;IACjB,OAAO,IAAIC,SAAemE,YAAY;KACpC,MAAMC,mBAAmB;MACvB,IAAIF,QAAQnF,OAAOJ,SAAS,SAC1BwF,QAAQ;WAERE,WAAWD,YAAY,EAAE;KAE7B;KACAA,WAAW;IACb,CAAC;GACH;GAEApF,cAAc;IACZ6E,YAAYpB,MAAM;GACpB;GAEAxC,gBAAgBf,aAAsC;IACpD4E,qBAAqB1C,IAAIlC,QAAQ;IACjC,aAAa;KACX4E,qBAAqBzC,OAAOnC,QAAQ;IACtC;GACF;GAEAgB,cACEhB,aACgB;IAChB6E,mBAAmB3C,IAAIlC,QAAQ;IAC/B,aAAa;KACX6E,mBAAmB1C,OAAOnC,QAAQ;IACpC;GACF;GAEAkB,WACElB,aACgB;IAChB8E,gBAAgB5C,IAAIlC,QAAQ;IAC5B,aAAa;KACX8E,gBAAgB3C,OAAOnC,QAAQ;IACjC;GACF;EACF;EAEA,MAAMoF,gBAAgBC,cAAuC;GAC3DL,QAAQnF,SAASwF;EACnB;EAEAV,YAAY/C,iBAAiB,qBAAqB;GAChD,KAAK,MAAM0D,MAAMV,sBAAsBU,GAAG;EAC5C,CAAC;EAEDX,YAAY/C,iBAAiB,eAAe;GAC1CwD,aAAa,EAAE3F,MAAM,UAAU,CAAC;EAClC,CAAC;EAEDkF,YAAY/C,iBAAiB,WAAW2D,UAAU;GAChD,MAAMC,cAAcD;GAEpB,KACE,IAAIE,IAAID,YAAY3C,aACpB4C,IAAID,YAAY1C,QAAQP,QACxBkD,KACA;IACA,MAAMxE,SAASuE,YAAY1C,QAAQ2C;IACnC,IAAI,CAACxE,QAAQ;IAEb,MAAMP,aAAaO,OAAO,EAAE,EAAEP,cAAc;IAE5C,IAAIO,OAAON,SAAS;KAClBoE,mBAAmBrE;KACnB,KAAK,MAAM4E,MAAMR,iBAAiBQ,GAAG;MAAE5E;MAAYC,SAAS;KAAK,CAAC;IACpE,OACE,KAAK,MAAM2E,MAAMR,iBAAiBQ,GAAG;KAAE5E;KAAYC,SAAS;IAAM,CAAC;GAEvE;EACF,CAAC;EAEDgE,YAAY/C,iBAAiB,mBAAmB,CAC9C,CACD;EAED+C,YAAY/C,iBAAiB,aAAa;GAExC,IADsBoD,QAAQnF,OACZJ,SAAS,SACzB2F,aAAa;IAAE3F,MAAM;IAASC,QAAQ;GAAU,CAAC;GAEnD,IAAIqF,iBAAiB;IACnB,KAAK,MAAMO,MAAMT,oBACfS,GAAG,EAAE5E,YAAYqE,gBAAgB,CAAC;IACpCA,kBAAkB;GACpB;EACF,CAAC;EAEDJ,YAAY/C,iBAAiB,UAAU2D,UAAU;GAC/C,MAAMI,aAAaJ;GACnB,IAAII,WAAWhG,UAAU,WACvByF,aAAa;IAAE3F,MAAM;IAASC,QAAQ;GAAY,CAAC;QAC9C;IACL0F,aAAa;KAAE3F,MAAM;KAASC,QAAQ;IAAQ,CAAC;IAC/Ca,QAAQZ,MAAM,oBAAoBgG,WAAWhG,OAAOgG,WAAW3C,OAAO;GACxE;EACF,CAAC;EAED,IAAI;GACF2B,YAAYrB,MAAM;EACpB,SAAS3D,OAAO;GACdyF,aAAa;IAAE3F,MAAM;IAASC,QAAQ;GAAQ,CAAC;GAC/C,MAAMC;EACR;EAEA,OAAOqF;CACT;AACF"}
@@ -1,13 +1,27 @@
1
1
  import { ThreadMessage } from "../types/message.js";
2
2
  import { ThreadSuggestion } from "../runtime/interfaces/thread-runtime-core.js";
3
-
4
3
  //#region src/adapters/suggestion.d.ts
5
4
  type SuggestionAdapterGenerateOptions = {
6
5
  messages: readonly ThreadMessage[];
6
+ signal?: AbortSignal;
7
7
  };
8
8
  type SuggestionAdapter = {
9
9
  generate: (options: SuggestionAdapterGenerateOptions) => Promise<readonly ThreadSuggestion[]> | AsyncGenerator<readonly ThreadSuggestion[], void>;
10
10
  };
11
+ declare const consumeSuggestionResult: (result: ReturnType<SuggestionAdapter["generate"]>, options: {
12
+ signal: AbortSignal;
13
+ onUpdate: (suggestions: readonly ThreadSuggestion[]) => void;
14
+ }) => Promise<void>;
15
+ type CreateSuggestionAdapterOptions = {
16
+ complete: (options: {
17
+ prompt: string;
18
+ signal?: AbortSignal;
19
+ }) => Promise<readonly string[]>;
20
+ count?: number | undefined;
21
+ instructions?: string | undefined;
22
+ maxMessages?: number | undefined;
23
+ };
24
+ declare const createSuggestionAdapter: (options: CreateSuggestionAdapterOptions) => SuggestionAdapter;
11
25
  //#endregion
12
- export { SuggestionAdapter };
26
+ export { CreateSuggestionAdapterOptions, SuggestionAdapter, SuggestionAdapterGenerateOptions, consumeSuggestionResult, createSuggestionAdapter };
13
27
  //# sourceMappingURL=suggestion.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"suggestion.d.ts","names":[],"sources":["../../src/adapters/suggestion.ts"],"mappings":";;;;KAGK,gCAAA;EACH,QAAA,WAAmB,aAAa;AAAA;AAAA,KAGtB,iBAAA;EACV,QAAA,GACE,OAAA,EAAS,gCAAA,KAEP,OAAA,UAAiB,gBAAA,MACjB,cAAA,UAAwB,gBAAA;AAAA"}
1
+ {"version":3,"file":"suggestion.d.ts","names":[],"sources":["../../src/adapters/suggestion.ts"],"mappings":";;;KAIY;EACV,mBAAmB;EACnB,SAAS;;KAGC;EACV,WACE,SAAS,qCAEP,iBAAiB,sBACjB,wBAAwB;;cAGjB,0BACX,QAAQ,WAAW,gCACnB;EACE,QAAQ;EACR,WAAW,sBAAsB;MAElC;KAcS;EACV,WAAW;IACT;IACA,SAAS;QACL;EACN;EACA;EACA;;cAGW,0BACX,SAAS,mCACR"}
@@ -0,0 +1,36 @@
1
+ import { getThreadMessageText } from "../utils/text.js";
2
+ //#region src/adapters/suggestion.ts
3
+ const consumeSuggestionResult = async (result, options) => {
4
+ const { signal, onUpdate } = options;
5
+ if (Symbol.asyncIterator in result) for await (const r of result) {
6
+ if (signal.aborted) break;
7
+ onUpdate(r);
8
+ }
9
+ else {
10
+ const suggestions = await result;
11
+ if (signal.aborted) return;
12
+ onUpdate(suggestions);
13
+ }
14
+ };
15
+ const createSuggestionAdapter = (options) => {
16
+ const count = options.count ?? 3;
17
+ const maxMessages = options.maxMessages ?? 10;
18
+ return { async generate({ messages, signal }) {
19
+ const limit = Math.max(0, Math.floor(maxMessages));
20
+ const transcript = (limit === 0 ? [] : messages.slice(-limit)).map((message) => {
21
+ const text = getThreadMessageText(message).trim();
22
+ if (!text) return null;
23
+ return `${message.role}: ${text}`;
24
+ }).filter((line) => line != null).join("\n");
25
+ let prompt = `Based on the following conversation, suggest exactly ${count} short follow-up prompts that the USER would plausibly send next. Write each prompt in the user's voice as something they would type. Return only the prompts, one per line, with no numbering or extra commentary.\n\nConversation:\n${transcript}`;
26
+ if (options.instructions) prompt += `\n\nAdditional instructions:\n${options.instructions}`;
27
+ return (await options.complete({
28
+ prompt,
29
+ ...signal !== void 0 && { signal }
30
+ })).map((s) => s.trim()).filter((s) => s.length > 0).slice(0, count).map((text) => ({ prompt: text }));
31
+ } };
32
+ };
33
+ //#endregion
34
+ export { consumeSuggestionResult, createSuggestionAdapter };
35
+
36
+ //# sourceMappingURL=suggestion.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"suggestion.js","names":["ThreadMessage","ThreadSuggestion","getThreadMessageText","SuggestionAdapterGenerateOptions","messages","signal","AbortSignal","SuggestionAdapter","generate","options","Promise","AsyncGenerator","consumeSuggestionResult","result","ReturnType","onUpdate","suggestions","Symbol","asyncIterator","r","aborted","CreateSuggestionAdapterOptions","complete","prompt","count","instructions","maxMessages","createSuggestionAdapter","limit","Math","max","floor","recent","slice","transcript","map","message","text","trim","role","filter","line","join","results","undefined","s","length"],"sources":["../../src/adapters/suggestion.ts"],"sourcesContent":["import type { ThreadMessage } from \"../types/message\";\nimport type { ThreadSuggestion } from \"../runtime/interfaces/thread-runtime-core\";\nimport { getThreadMessageText } from \"../utils/text\";\n\nexport type SuggestionAdapterGenerateOptions = {\n messages: readonly ThreadMessage[];\n signal?: AbortSignal;\n};\n\nexport type SuggestionAdapter = {\n generate: (\n options: SuggestionAdapterGenerateOptions,\n ) =>\n | Promise<readonly ThreadSuggestion[]>\n | AsyncGenerator<readonly ThreadSuggestion[], void>;\n};\n\nexport const consumeSuggestionResult = async (\n result: ReturnType<SuggestionAdapter[\"generate\"]>,\n options: {\n signal: AbortSignal;\n onUpdate: (suggestions: readonly ThreadSuggestion[]) => void;\n },\n): Promise<void> => {\n const { signal, onUpdate } = options;\n if (Symbol.asyncIterator in result) {\n for await (const r of result) {\n if (signal.aborted) break;\n onUpdate(r);\n }\n } else {\n const suggestions = await result;\n if (signal.aborted) return;\n onUpdate(suggestions);\n }\n};\n\nexport type CreateSuggestionAdapterOptions = {\n complete: (options: {\n prompt: string;\n signal?: AbortSignal;\n }) => Promise<readonly string[]>;\n count?: number | undefined;\n instructions?: string | undefined;\n maxMessages?: number | undefined;\n};\n\nexport const createSuggestionAdapter = (\n options: CreateSuggestionAdapterOptions,\n): SuggestionAdapter => {\n const count = options.count ?? 3;\n const maxMessages = options.maxMessages ?? 10;\n\n return {\n async generate({ messages, signal }) {\n const limit = Math.max(0, Math.floor(maxMessages));\n const recent = limit === 0 ? [] : messages.slice(-limit);\n const transcript = recent\n .map((message) => {\n const text = getThreadMessageText(message).trim();\n if (!text) return null;\n return `${message.role}: ${text}`;\n })\n .filter((line): line is string => line != null)\n .join(\"\\n\");\n\n let prompt =\n `Based on the following conversation, suggest exactly ${count} short follow-up prompts that the USER would plausibly send next. ` +\n `Write each prompt in the user's voice as something they would type. ` +\n `Return only the prompts, one per line, with no numbering or extra commentary.\\n\\n` +\n `Conversation:\\n${transcript}`;\n\n if (options.instructions) {\n prompt += `\\n\\nAdditional instructions:\\n${options.instructions}`;\n }\n\n const results = await options.complete({\n prompt,\n ...(signal !== undefined && { signal }),\n });\n return results\n .map((s) => s.trim())\n .filter((s) => s.length > 0)\n .slice(0, count)\n .map((text) => ({ prompt: text }));\n },\n };\n};\n"],"mappings":";;AAiBA,MAAaY,0BAA0B,OACrCC,QACAJ,YAIkB;CAClB,MAAM,EAAEJ,QAAQU,aAAaN;CAC7B,IAAIQ,OAAOC,iBAAiBL,QAC1B,WAAW,MAAMM,KAAKN,QAAQ;EAC5B,IAAIR,OAAOe,SAAS;EACpBL,SAASI,CAAC;CACZ;MACK;EACL,MAAMH,cAAc,MAAMH;EAC1B,IAAIR,OAAOe,SAAS;EACpBL,SAASC,WAAW;CACtB;AACF;AAYA,MAAaW,2BACXlB,YACsB;CACtB,MAAMe,QAAQf,QAAQe,SAAS;CAC/B,MAAME,cAAcjB,QAAQiB,eAAe;CAE3C,OAAO,EACL,MAAMlB,SAAS,EAAEJ,UAAUC,UAAU;EACnC,MAAMuB,QAAQC,KAAKC,IAAI,GAAGD,KAAKE,MAAML,WAAW,CAAC;EAEjD,MAAMQ,cADSN,UAAU,IAAI,CAAA,IAAKxB,SAAS6B,MAAM,CAACL,KAAK,EAAA,CAEpDO,KAAKC,YAAY;GAChB,MAAMC,OAAOnC,qBAAqBkC,OAAO,CAAC,CAACE,KAAK;GAChD,IAAI,CAACD,MAAM,OAAO;GAClB,OAAO,GAAGD,QAAQG,KAAI,IAAKF;EAC7B,CAAC,CAAC,CACDG,QAAQC,SAAyBA,QAAQ,IAAI,CAAC,CAC9CC,KAAK,IAAI;EAEZ,IAAInB,SACF,wDAAwDC,MAAK,wOAG3CU;EAEpB,IAAIzB,QAAQgB,cACVF,UAAU,iCAAiCd,QAAQgB;EAOrD,QAAOkB,MAJelC,QAAQa,SAAS;GACrCC;GACA,GAAIlB,WAAWuC,KAAAA,KAAa,EAAEvC,OAAO;EACvC,CAAC,EAAA,CAEE8B,KAAKU,MAAMA,EAAEP,KAAK,CAAC,CAAC,CACpBE,QAAQK,MAAMA,EAAEC,SAAS,CAAC,CAAC,CAC3Bb,MAAM,GAAGT,KAAK,CAAC,CACfW,KAAKE,UAAU,EAAEd,QAAQc,KAAK,EAAE;CACrC,EACF;AACF"}
@@ -1,7 +1,6 @@
1
1
  import { ChatModelRunOptions, ChatModelRunResult } from "../runtime/utils/chat-model-adapter.js";
2
2
  import { ExportedMessageRepository, ExportedMessageRepositoryItem } from "../runtime/utils/message-repository.js";
3
3
  import { ReadonlyJSONValue } from "assistant-stream/utils";
4
-
5
4
  //#region src/adapters/thread-history.d.ts
6
5
  interface MessageStorageEntry<TPayload> {
7
6
  id: string;
@@ -43,7 +42,8 @@ type ThreadHistoryAdapter = {
43
42
  }>;
44
43
  resume?(options: ChatModelRunOptions): AsyncGenerator<ChatModelRunResult, void, unknown>;
45
44
  append(item: ExportedMessageRepositoryItem): Promise<void>;
46
- delete?(items: ExportedMessageRepositoryItem[]): Promise<void>; /** Required when used with `useAISDKRuntime` / `useChatRuntime`. */
45
+ delete?(items: ExportedMessageRepositoryItem[]): Promise<void>;
46
+ /** Required when used with `useAISDKRuntime` / `useChatRuntime`. */
47
47
  withFormat?<TMessage, TStorageFormat extends Record<string, unknown>>(formatAdapter: MessageFormatAdapter<TMessage, TStorageFormat>): GenericThreadHistoryAdapter<TMessage>;
48
48
  };
49
49
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"thread-history.d.ts","names":[],"sources":["../../src/adapters/thread-history.ts"],"mappings":";;;;;UAUiB,mBAAA;EACf,EAAA;EACA,SAAA;EACA,MAAA;EACA,OAAA,EAAS,QAAQ;AAAA;AAAA,UAGF,iBAAA;EACf,QAAA;EACA,OAAA,EAAS,QAAQ;AAAA;AAAA,UAGF,uBAAA;EACf,MAAA;EACA,QAAA,EAAU,iBAAiB,CAAC,QAAA;AAAA;AAAA,UAGb,oBAAA,kCAEQ,MAAA;EAEvB,MAAA;EACA,MAAA,CAAO,IAAA,EAAM,iBAAA,CAAkB,QAAA,IAAY,cAAA;EAC3C,MAAA,CACE,MAAA,EAAQ,mBAAA,CAAoB,cAAA,IAC3B,iBAAA,CAAkB,QAAA;EACrB,KAAA,CAAM,OAAA,EAAS,QAAA;AAAA;AAAA,KAGL,2BAAA;EACV,IAAA,IAAQ,OAAA,CAAQ,uBAAA,CAAwB,QAAA;EACxC,MAAA,CAAO,IAAA,EAAM,iBAAA,CAAkB,QAAA,IAAY,OAAA;EAC3C,MAAA,EACE,IAAA,EAAM,iBAAA,CAAkB,QAAA,GACxB,cAAA,WACC,OAAA;EACH,MAAA,EAAQ,KAAA,EAAO,iBAAA,CAAkB,QAAA,MAAc,OAAA;EAC/C,eAAA,EACE,KAAA,EAAO,iBAAA,CAAkB,QAAA,KACzB,OAAA;IACE,UAAA;IACA,cAAA;MAAmB,QAAA;MAAkB,MAAA;IAAA;EAAA;AAAA;AAAA,KAK/B,oBAAA;EACV,IAAA,IAAQ,OAAA,CACN,yBAAA;IACE,KAAA,GAAQ,iBAAA;IACR,eAAA;EAAA;EAGJ,MAAA,EACE,OAAA,EAAS,mBAAA,GACR,cAAA,CAAe,kBAAA;EAClB,MAAA,CAAO,IAAA,EAAM,6BAAA,GAAgC,OAAA;EAC7C,MAAA,EAAQ,KAAA,EAAO,6BAAA,KAAkC,OAAA,QAnCN;EAqC3C,UAAA,mCAA6C,MAAA,mBAC3C,aAAA,EAAe,oBAAA,CAAqB,QAAA,EAAU,cAAA,IAC7C,2BAAA,CAA4B,QAAA;AAAA"}
1
+ {"version":3,"file":"thread-history.d.ts","names":[],"sources":["../../src/adapters/thread-history.ts"],"mappings":";;;;UAUiB,oBAAoB;EACnC;EACA;EACA;EACA,SAAS;;UAGM,kBAAkB;EACjC;EACA,SAAS;;UAGM,wBAAwB;EACvC;EACA,UAAU,kBAAkB;;UAGb,qBACf,UACA,uBAAuB;EAEvB;EACA,OAAO,MAAM,kBAAkB,YAAY;EAC3C,OACE,QAAQ,oBAAoB,kBAC3B,kBAAkB;EACrB,MAAM,SAAS;;KAGL,4BAA4B;EACtC,QAAQ,QAAQ,wBAAwB;EACxC,OAAO,MAAM,kBAAkB,YAAY;EAC3C,QACE,MAAM,kBAAkB,WACxB,yBACC;EACH,QAAQ,OAAO,kBAAkB,cAAc;EAC/C,iBACE,OAAO,kBAAkB,aACzB;IACE;IACA;MAAmB;MAAkB;;;;KAK/B;EACV,QAAQ,QACN;IACE,QAAQ;IACR;;EAGJ,QACE,SAAS,sBACR,eAAe;EAClB,OAAO,MAAM,gCAAgC;EAC7C,QAAQ,OAAO,kCAAkC;;EAEjD,YAAY,UAAU,uBAAuB,yBAC3C,eAAe,qBAAqB,UAAU,kBAC7C,4BAA4B"}
@@ -1,10 +1,12 @@
1
1
  import { Unstable_TriggerCategory, Unstable_TriggerItem } from "../types/trigger.js";
2
-
3
2
  //#region src/adapters/trigger.d.ts
4
3
  /** Adapter providing synchronous categories and items to a trigger popover. */
5
4
  type Unstable_TriggerAdapter = {
6
- /** Return the top-level categories for the trigger popover. */categories(): readonly Unstable_TriggerCategory[]; /** Return items within a category. */
7
- categoryItems(categoryId: string): readonly Unstable_TriggerItem[]; /** Global search across all categories (optional). */
5
+ /** Return the top-level categories for the trigger popover. */
6
+ categories(): readonly Unstable_TriggerCategory[];
7
+ /** Return items within a category. */
8
+ categoryItems(categoryId: string): readonly Unstable_TriggerItem[];
9
+ /** Global search across all categories (optional). */
8
10
  search?(query: string): readonly Unstable_TriggerItem[];
9
11
  };
10
12
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"trigger.d.ts","names":[],"sources":["../../src/adapters/trigger.ts"],"mappings":";;;;KAMY,uBAAA;EAAA,+DAEV,UAAA,aAAuB,wBAAA;EAGvB,aAAA,CAAc,UAAA,oBAA8B,oBAAA,IAAA;EAG5C,MAAA,EAAQ,KAAA,oBAAyB,oBAAA;AAAA"}
1
+ {"version":3,"file":"trigger.d.ts","names":[],"sources":["../../src/adapters/trigger.ts"],"mappings":";;;KAMY;;EAEV,uBAAuB;;EAGvB,cAAc,8BAA8B;;EAG5C,QAAQ,yBAAyB"}
@@ -1,5 +1,4 @@
1
1
  import { Unsubscribe } from "../types/unsubscribe.js";
2
-
3
2
  //#region src/adapters/voice.d.ts
4
3
  declare namespace RealtimeVoiceAdapter {
5
4
  type Status = {
@@ -1 +1 @@
1
- {"version":3,"file":"voice.d.ts","names":[],"sources":["../../src/adapters/voice.ts"],"mappings":";;;kBAEiB,oBAAA;EAAA,KACH,MAAA;IAEN,IAAA;EAAA;IAGA,IAAA;IACA,MAAA;IACA,KAAA;EAAA;EAAA,KAGM,IAAA;EAAA,KAEA,cAAA;IACV,IAAA;IACA,IAAA;IACA,OAAA;EAAA;EAAA,KAGU,OAAA;IACV,MAAA,EAAQ,MAAA;IACR,OAAA;IAEA,UAAA;IACA,IAAA;IACA,MAAA;IAEA,cAAA,GAAiB,QAAA,GAAW,MAAA,EAAQ,MAAA,cAAoB,WAAA;IACxD,YAAA,GACE,QAAA,GAAW,UAAA,EAAY,cAAA,cACpB,WAAA;IACL,YAAA,GAAe,QAAA,GAAW,IAAA,EAAM,IAAA,cAAkB,WAAA;IAClD,cAAA,GAAiB,QAAA,GAAW,MAAA,sBAA4B,WAAA;EAAA;AAAA;AAAA,KAIhD,oBAAA;EACV,OAAA,GAAU,OAAA;IACR,WAAA,GAAc,WAAA;EAAA,MACV,oBAAA,CAAqB,OAAO;AAAA;AAAA,KAGxB,oBAAA;EACV,UAAA;EACA,IAAA;EACA,MAAA;AAAA;AAAA,KAGU,mBAAA;EACV,SAAA,GAAY,MAAA,EAAQ,oBAAA,CAAqB,MAAA;EACzC,GAAA,GAAM,MAAA,sCAA4C,KAAA;EAClD,cAAA,GAAiB,IAAA,EAAM,oBAAA,CAAqB,cAAA;EAC5C,QAAA,GAAW,IAAA,EAAM,oBAAA,CAAqB,IAAA;EACtC,UAAA,GAAa,MAAA;EACb,UAAA;AAAA;AAAA,iBAGc,kBAAA,CACd,OAAA;EAAW,WAAA,GAAc,WAAA;AAAA,GACzB,KAAA,GAAQ,OAAA,EAAS,mBAAA,KAAwB,OAAA,CAAQ,oBAAA,IAChD,oBAAA,CAAqB,OAAA"}
1
+ {"version":3,"file":"voice.d.ts","names":[],"sources":["../../src/adapters/voice.ts"],"mappings":";;kBAEiB;OACH;IAEN;;IAGA;IACA;IACA;;OAGM;OAEA;IACV;IACA;IACA;;OAGU;IACV,QAAQ;IACR;IAEA;IACA;IACA;IAEA,iBAAiB,WAAW,QAAQ,oBAAoB;IACxD,eACE,WAAW,YAAY,4BACpB;IACL,eAAe,WAAW,MAAM,kBAAkB;IAClD,iBAAiB,WAAW,4BAA4B;;;KAIhD;EACV,UAAU;IACR,cAAc;QACV,qBAAqB;;KAGjB;EACV;EACA;EACA;;KAGU;EACV,YAAY,QAAQ,qBAAqB;EACzC,MAAM,4CAA4C;EAClD,iBAAiB,MAAM,qBAAqB;EAC5C,WAAW,MAAM,qBAAqB;EACtC,aAAa;EACb;;iBAmBc,mBACd;EAAW,cAAc;GACzB,QAAQ,SAAS,wBAAwB,QAAQ,wBAChD,qBAAqB"}
@@ -1,4 +1,11 @@
1
1
  //#region src/adapters/voice.ts
2
+ const notifyListeners = (listeners, value) => {
3
+ for (const listener of listeners) try {
4
+ listener(value);
5
+ } catch (error) {
6
+ console.error("[assistant-ui] Voice session listener threw an error", error);
7
+ }
8
+ };
2
9
  function createVoiceSession(options, setup) {
3
10
  const statusCbs = /* @__PURE__ */ new Set();
4
11
  const transcriptCbs = /* @__PURE__ */ new Set();
@@ -19,7 +26,7 @@ function createVoiceSession(options, setup) {
19
26
  setStatus: (status) => {
20
27
  if (disposed) return;
21
28
  currentStatus = status;
22
- for (const cb of statusCbs) cb(status);
29
+ notifyListeners(statusCbs, status);
23
30
  },
24
31
  end: (reason, error) => {
25
32
  if (disposed) return;
@@ -28,20 +35,20 @@ function createVoiceSession(options, setup) {
28
35
  reason,
29
36
  error
30
37
  };
31
- for (const cb of statusCbs) cb(currentStatus);
38
+ notifyListeners(statusCbs, currentStatus);
32
39
  cleanup();
33
40
  },
34
41
  emitTranscript: (item) => {
35
42
  if (disposed) return;
36
- for (const cb of transcriptCbs) cb(item);
43
+ notifyListeners(transcriptCbs, item);
37
44
  },
38
45
  emitMode: (mode) => {
39
46
  if (disposed) return;
40
- for (const cb of modeCbs) cb(mode);
47
+ notifyListeners(modeCbs, mode);
41
48
  },
42
49
  emitVolume: (volume) => {
43
50
  if (disposed) return;
44
- for (const cb of volumeCbs) cb(volume);
51
+ notifyListeners(volumeCbs, volume);
45
52
  },
46
53
  isDisposed: () => disposed
47
54
  };
@@ -87,6 +94,7 @@ function createVoiceSession(options, setup) {
87
94
  if (disposed) return;
88
95
  controls = await setup(helpers);
89
96
  if (disposed) controls.disconnect();
97
+ else if (isMuted) controls.mute();
90
98
  } catch (error) {
91
99
  helpers.end("error", error);
92
100
  }
@@ -1 +1 @@
1
- {"version":3,"file":"voice.js","names":["Unsubscribe","RealtimeVoiceAdapter","Status","type","reason","error","Mode","TranscriptItem","role","text","isFinal","Session","status","isMuted","disconnect","mute","unmute","onStatusChange","callback","onTranscript","transcript","onModeChange","mode","onVolumeChange","volume","connect","options","abortSignal","AbortSignal","VoiceSessionControls","VoiceSessionHelpers","setStatus","end","emitTranscript","item","emitMode","emitVolume","isDisposed","createVoiceSession","setup","helpers","Promise","statusCbs","Set","s","transcriptCbs","t","modeCbs","m","volumeCbs","v","currentStatus","disposed","controls","cleanup","clear","cb","session","add","delete","addEventListener","once","doSetup"],"sources":["../../src/adapters/voice.ts"],"sourcesContent":["import type { Unsubscribe } from \"../types/unsubscribe\";\n\nexport namespace RealtimeVoiceAdapter {\n export type Status =\n | {\n type: \"starting\" | \"running\";\n }\n | {\n type: \"ended\";\n reason: \"finished\" | \"cancelled\" | \"error\";\n error?: unknown;\n };\n\n export type Mode = \"listening\" | \"speaking\";\n\n export type TranscriptItem = {\n role: \"user\" | \"assistant\";\n text: string;\n isFinal?: boolean;\n };\n\n export type Session = {\n status: Status;\n isMuted: boolean;\n\n disconnect: () => void;\n mute: () => void;\n unmute: () => void;\n\n onStatusChange: (callback: (status: Status) => void) => Unsubscribe;\n onTranscript: (\n callback: (transcript: TranscriptItem) => void,\n ) => Unsubscribe;\n onModeChange: (callback: (mode: Mode) => void) => Unsubscribe;\n onVolumeChange: (callback: (volume: number) => void) => Unsubscribe;\n };\n}\n\nexport type RealtimeVoiceAdapter = {\n connect: (options: {\n abortSignal?: AbortSignal;\n }) => RealtimeVoiceAdapter.Session;\n};\n\nexport type VoiceSessionControls = {\n disconnect: () => void;\n mute: () => void;\n unmute: () => void;\n};\n\nexport type VoiceSessionHelpers = {\n setStatus: (status: RealtimeVoiceAdapter.Status) => void;\n end: (reason: \"finished\" | \"cancelled\" | \"error\", error?: unknown) => void;\n emitTranscript: (item: RealtimeVoiceAdapter.TranscriptItem) => void;\n emitMode: (mode: RealtimeVoiceAdapter.Mode) => void;\n emitVolume: (volume: number) => void;\n isDisposed: () => boolean;\n};\n\nexport function createVoiceSession(\n options: { abortSignal?: AbortSignal },\n setup: (helpers: VoiceSessionHelpers) => Promise<VoiceSessionControls>,\n): RealtimeVoiceAdapter.Session {\n const statusCbs = new Set<(s: RealtimeVoiceAdapter.Status) => void>();\n const transcriptCbs = new Set<\n (t: RealtimeVoiceAdapter.TranscriptItem) => void\n >();\n const modeCbs = new Set<(m: RealtimeVoiceAdapter.Mode) => void>();\n const volumeCbs = new Set<(v: number) => void>();\n\n let currentStatus: RealtimeVoiceAdapter.Status = { type: \"starting\" };\n let isMuted = false;\n let disposed = false;\n let controls: VoiceSessionControls | null = null;\n\n const cleanup = () => {\n disposed = true;\n statusCbs.clear();\n transcriptCbs.clear();\n modeCbs.clear();\n volumeCbs.clear();\n };\n\n const helpers: VoiceSessionHelpers = {\n setStatus: (status) => {\n if (disposed) return;\n currentStatus = status;\n for (const cb of statusCbs) cb(status);\n },\n end: (reason, error?) => {\n if (disposed) return;\n currentStatus = { type: \"ended\", reason, error };\n for (const cb of statusCbs) cb(currentStatus);\n cleanup();\n },\n emitTranscript: (item) => {\n if (disposed) return;\n for (const cb of transcriptCbs) cb(item);\n },\n emitMode: (mode) => {\n if (disposed) return;\n for (const cb of modeCbs) cb(mode);\n },\n emitVolume: (volume) => {\n if (disposed) return;\n for (const cb of volumeCbs) cb(volume);\n },\n isDisposed: () => disposed,\n };\n\n const session: RealtimeVoiceAdapter.Session = {\n get status() {\n return currentStatus;\n },\n get isMuted() {\n return isMuted;\n },\n disconnect: () => {\n controls?.disconnect();\n cleanup();\n },\n mute: () => {\n controls?.mute();\n isMuted = true;\n },\n unmute: () => {\n controls?.unmute();\n isMuted = false;\n },\n onStatusChange: (cb) => {\n statusCbs.add(cb);\n return () => statusCbs.delete(cb);\n },\n onTranscript: (cb) => {\n transcriptCbs.add(cb);\n return () => transcriptCbs.delete(cb);\n },\n onModeChange: (cb) => {\n modeCbs.add(cb);\n return () => modeCbs.delete(cb);\n },\n onVolumeChange: (cb) => {\n volumeCbs.add(cb);\n return () => volumeCbs.delete(cb);\n },\n };\n\n if (options.abortSignal) {\n options.abortSignal.addEventListener(\"abort\", () => session.disconnect(), {\n once: true,\n });\n }\n\n const doSetup = async () => {\n try {\n if (disposed) return;\n controls = await setup(helpers);\n if (disposed) controls.disconnect();\n } catch (error) {\n helpers.end(\"error\", error);\n }\n };\n\n doSetup();\n return session;\n}\n"],"mappings":";AA2DA,SAAgBsC,mBACdZ,SACAa,OAC8B;CAC9B,MAAMG,4BAAY,IAAIC,IAA8C;CACpE,MAAME,gCAAgB,IAAIF,IAExB;CACF,MAAMI,0BAAU,IAAIJ,IAA4C;CAChE,MAAMM,4BAAY,IAAIN,IAAyB;CAE/C,IAAIQ,gBAA6C,EAAEhD,MAAM,WAAW;CACpE,IAAIU,UAAU;CACd,IAAIuC,WAAW;CACf,IAAIC,WAAwC;CAE5C,MAAMC,gBAAgB;EACpBF,WAAW;EACXV,UAAUa,MAAM;EAChBV,cAAcU,MAAM;EACpBR,QAAQQ,MAAM;EACdN,UAAUM,MAAM;CAClB;CAEA,MAAMf,UAA+B;EACnCT,YAAYnB,WAAW;GACrB,IAAIwC,UAAU;GACdD,gBAAgBvC;GAChB,KAAK,MAAM4C,MAAMd,WAAWc,GAAG5C,MAAM;EACvC;EACAoB,MAAM5B,QAAQC,UAAW;GACvB,IAAI+C,UAAU;GACdD,gBAAgB;IAAEhD,MAAM;IAASC;IAAQC;GAAM;GAC/C,KAAK,MAAMmD,MAAMd,WAAWc,GAAGL,aAAa;GAC5CG,QAAQ;EACV;EACArB,iBAAiBC,SAAS;GACxB,IAAIkB,UAAU;GACd,KAAK,MAAMI,MAAMX,eAAeW,GAAGtB,IAAI;EACzC;EACAC,WAAWb,SAAS;GAClB,IAAI8B,UAAU;GACd,KAAK,MAAMI,MAAMT,SAASS,GAAGlC,IAAI;EACnC;EACAc,aAAaZ,WAAW;GACtB,IAAI4B,UAAU;GACd,KAAK,MAAMI,MAAMP,WAAWO,GAAGhC,MAAM;EACvC;EACAa,kBAAkBe;CACpB;CAEA,MAAMK,UAAwC;EAC5C,IAAI7C,SAAS;GACX,OAAOuC;EACT;EACA,IAAItC,UAAU;GACZ,OAAOA;EACT;EACAC,kBAAkB;GAChBuC,UAAUvC,WAAW;GACrBwC,QAAQ;EACV;EACAvC,YAAY;GACVsC,UAAUtC,KAAK;GACfF,UAAU;EACZ;EACAG,cAAc;GACZqC,UAAUrC,OAAO;GACjBH,UAAU;EACZ;EACAI,iBAAiBuC,OAAO;GACtBd,UAAUgB,IAAIF,EAAE;GAChB,aAAad,UAAUiB,OAAOH,EAAE;EAClC;EACArC,eAAeqC,OAAO;GACpBX,cAAca,IAAIF,EAAE;GACpB,aAAaX,cAAcc,OAAOH,EAAE;EACtC;EACAnC,eAAemC,OAAO;GACpBT,QAAQW,IAAIF,EAAE;GACd,aAAaT,QAAQY,OAAOH,EAAE;EAChC;EACAjC,iBAAiBiC,OAAO;GACtBP,UAAUS,IAAIF,EAAE;GAChB,aAAaP,UAAUU,OAAOH,EAAE;EAClC;CACF;CAEA,IAAI9B,QAAQC,aACVD,QAAQC,YAAYiC,iBAAiB,eAAeH,QAAQ3C,WAAW,GAAG,EACxE+C,MAAM,KACR,CAAC;CAGH,MAAMC,UAAU,YAAY;EAC1B,IAAI;GACF,IAAIV,UAAU;GACdC,WAAW,MAAMd,MAAMC,OAAO;GAC9B,IAAIY,UAAUC,SAASvC,WAAW;EACpC,SAAST,OAAO;GACdmC,QAAQR,IAAI,SAAS3B,KAAK;EAC5B;CACF;CAEAyD,QAAQ;CACR,OAAOL;AACT"}
1
+ {"version":3,"file":"voice.js","names":["Unsubscribe","RealtimeVoiceAdapter","Status","type","reason","error","Mode","TranscriptItem","role","text","isFinal","Session","status","isMuted","disconnect","mute","unmute","onStatusChange","callback","onTranscript","transcript","onModeChange","mode","onVolumeChange","volume","connect","options","abortSignal","AbortSignal","VoiceSessionControls","VoiceSessionHelpers","setStatus","end","emitTranscript","item","emitMode","emitVolume","isDisposed","notifyListeners","listeners","ReadonlySet","value","T","listener","console","createVoiceSession","setup","helpers","Promise","statusCbs","Set","s","transcriptCbs","t","modeCbs","m","volumeCbs","v","currentStatus","disposed","controls","cleanup","clear","session","cb","add","delete","addEventListener","once","doSetup"],"sources":["../../src/adapters/voice.ts"],"sourcesContent":["import type { Unsubscribe } from \"../types/unsubscribe\";\n\nexport namespace RealtimeVoiceAdapter {\n export type Status =\n | {\n type: \"starting\" | \"running\";\n }\n | {\n type: \"ended\";\n reason: \"finished\" | \"cancelled\" | \"error\";\n error?: unknown;\n };\n\n export type Mode = \"listening\" | \"speaking\";\n\n export type TranscriptItem = {\n role: \"user\" | \"assistant\";\n text: string;\n isFinal?: boolean;\n };\n\n export type Session = {\n status: Status;\n isMuted: boolean;\n\n disconnect: () => void;\n mute: () => void;\n unmute: () => void;\n\n onStatusChange: (callback: (status: Status) => void) => Unsubscribe;\n onTranscript: (\n callback: (transcript: TranscriptItem) => void,\n ) => Unsubscribe;\n onModeChange: (callback: (mode: Mode) => void) => Unsubscribe;\n onVolumeChange: (callback: (volume: number) => void) => Unsubscribe;\n };\n}\n\nexport type RealtimeVoiceAdapter = {\n connect: (options: {\n abortSignal?: AbortSignal;\n }) => RealtimeVoiceAdapter.Session;\n};\n\nexport type VoiceSessionControls = {\n disconnect: () => void;\n mute: () => void;\n unmute: () => void;\n};\n\nexport type VoiceSessionHelpers = {\n setStatus: (status: RealtimeVoiceAdapter.Status) => void;\n end: (reason: \"finished\" | \"cancelled\" | \"error\", error?: unknown) => void;\n emitTranscript: (item: RealtimeVoiceAdapter.TranscriptItem) => void;\n emitMode: (mode: RealtimeVoiceAdapter.Mode) => void;\n emitVolume: (volume: number) => void;\n isDisposed: () => boolean;\n};\n\nconst notifyListeners = <T>(\n listeners: ReadonlySet<(value: T) => void>,\n value: T,\n) => {\n for (const listener of listeners) {\n try {\n listener(value);\n } catch (error) {\n console.error(\n \"[assistant-ui] Voice session listener threw an error\",\n error,\n );\n }\n }\n};\n\nexport function createVoiceSession(\n options: { abortSignal?: AbortSignal },\n setup: (helpers: VoiceSessionHelpers) => Promise<VoiceSessionControls>,\n): RealtimeVoiceAdapter.Session {\n const statusCbs = new Set<(s: RealtimeVoiceAdapter.Status) => void>();\n const transcriptCbs = new Set<\n (t: RealtimeVoiceAdapter.TranscriptItem) => void\n >();\n const modeCbs = new Set<(m: RealtimeVoiceAdapter.Mode) => void>();\n const volumeCbs = new Set<(v: number) => void>();\n\n let currentStatus: RealtimeVoiceAdapter.Status = { type: \"starting\" };\n let isMuted = false;\n let disposed = false;\n let controls: VoiceSessionControls | null = null;\n\n const cleanup = () => {\n disposed = true;\n statusCbs.clear();\n transcriptCbs.clear();\n modeCbs.clear();\n volumeCbs.clear();\n };\n\n const helpers: VoiceSessionHelpers = {\n setStatus: (status) => {\n if (disposed) return;\n currentStatus = status;\n notifyListeners(statusCbs, status);\n },\n end: (reason, error?) => {\n if (disposed) return;\n currentStatus = { type: \"ended\", reason, error };\n notifyListeners(statusCbs, currentStatus);\n cleanup();\n },\n emitTranscript: (item) => {\n if (disposed) return;\n notifyListeners(transcriptCbs, item);\n },\n emitMode: (mode) => {\n if (disposed) return;\n notifyListeners(modeCbs, mode);\n },\n emitVolume: (volume) => {\n if (disposed) return;\n notifyListeners(volumeCbs, volume);\n },\n isDisposed: () => disposed,\n };\n\n const session: RealtimeVoiceAdapter.Session = {\n get status() {\n return currentStatus;\n },\n get isMuted() {\n return isMuted;\n },\n disconnect: () => {\n controls?.disconnect();\n cleanup();\n },\n mute: () => {\n controls?.mute();\n isMuted = true;\n },\n unmute: () => {\n controls?.unmute();\n isMuted = false;\n },\n onStatusChange: (cb) => {\n statusCbs.add(cb);\n return () => statusCbs.delete(cb);\n },\n onTranscript: (cb) => {\n transcriptCbs.add(cb);\n return () => transcriptCbs.delete(cb);\n },\n onModeChange: (cb) => {\n modeCbs.add(cb);\n return () => modeCbs.delete(cb);\n },\n onVolumeChange: (cb) => {\n volumeCbs.add(cb);\n return () => volumeCbs.delete(cb);\n },\n };\n\n if (options.abortSignal) {\n options.abortSignal.addEventListener(\"abort\", () => session.disconnect(), {\n once: true,\n });\n }\n\n const doSetup = async () => {\n try {\n if (disposed) return;\n controls = await setup(helpers);\n if (disposed) {\n controls.disconnect();\n } else if (isMuted) {\n controls.mute();\n }\n } catch (error) {\n helpers.end(\"error\", error);\n }\n };\n\n doSetup();\n return session;\n}\n"],"mappings":";AA2DA,MAAMsC,mBACJC,WACAE,UACG;CACH,KAAK,MAAME,YAAYJ,WACrB,IAAI;EACFI,SAASF,KAAK;CAChB,SAASpC,OAAO;EACduC,QAAQvC,MACN,wDACAA,KACF;CACF;AAEJ;AAEA,SAAgBwC,mBACdnB,SACAoB,OAC8B;CAC9B,MAAMG,4BAAY,IAAIC,IAA8C;CACpE,MAAME,gCAAgB,IAAIF,IAExB;CACF,MAAMI,0BAAU,IAAIJ,IAA4C;CAChE,MAAMM,4BAAY,IAAIN,IAAyB;CAE/C,IAAIQ,gBAA6C,EAAEvD,MAAM,WAAW;CACpE,IAAIU,UAAU;CACd,IAAI8C,WAAW;CACf,IAAIC,WAAwC;CAE5C,MAAMC,gBAAgB;EACpBF,WAAW;EACXV,UAAUa,MAAM;EAChBV,cAAcU,MAAM;EACpBR,QAAQQ,MAAM;EACdN,UAAUM,MAAM;CAClB;CAEA,MAAMf,UAA+B;EACnChB,YAAYnB,WAAW;GACrB,IAAI+C,UAAU;GACdD,gBAAgB9C;GAChB0B,gBAAgBW,WAAWrC,MAAM;EACnC;EACAoB,MAAM5B,QAAQC,UAAW;GACvB,IAAIsD,UAAU;GACdD,gBAAgB;IAAEvD,MAAM;IAASC;IAAQC;GAAM;GAC/CiC,gBAAgBW,WAAWS,aAAa;GACxCG,QAAQ;EACV;EACA5B,iBAAiBC,SAAS;GACxB,IAAIyB,UAAU;GACdrB,gBAAgBc,eAAelB,IAAI;EACrC;EACAC,WAAWb,SAAS;GAClB,IAAIqC,UAAU;GACdrB,gBAAgBgB,SAAShC,IAAI;EAC/B;EACAc,aAAaZ,WAAW;GACtB,IAAImC,UAAU;GACdrB,gBAAgBkB,WAAWhC,MAAM;EACnC;EACAa,kBAAkBsB;CACpB;CAEA,MAAMI,UAAwC;EAC5C,IAAInD,SAAS;GACX,OAAO8C;EACT;EACA,IAAI7C,UAAU;GACZ,OAAOA;EACT;EACAC,kBAAkB;GAChB8C,UAAU9C,WAAW;GACrB+C,QAAQ;EACV;EACA9C,YAAY;GACV6C,UAAU7C,KAAK;GACfF,UAAU;EACZ;EACAG,cAAc;GACZ4C,UAAU5C,OAAO;GACjBH,UAAU;EACZ;EACAI,iBAAiB+C,OAAO;GACtBf,UAAUgB,IAAID,EAAE;GAChB,aAAaf,UAAUiB,OAAOF,EAAE;EAClC;EACA7C,eAAe6C,OAAO;GACpBZ,cAAca,IAAID,EAAE;GACpB,aAAaZ,cAAcc,OAAOF,EAAE;EACtC;EACA3C,eAAe2C,OAAO;GACpBV,QAAQW,IAAID,EAAE;GACd,aAAaV,QAAQY,OAAOF,EAAE;EAChC;EACAzC,iBAAiByC,OAAO;GACtBR,UAAUS,IAAID,EAAE;GAChB,aAAaR,UAAUU,OAAOF,EAAE;EAClC;CACF;CAEA,IAAItC,QAAQC,aACVD,QAAQC,YAAYwC,iBAAiB,eAAeJ,QAAQjD,WAAW,GAAG,EACxEsD,MAAM,KACR,CAAC;CAGH,MAAMC,UAAU,YAAY;EAC1B,IAAI;GACF,IAAIV,UAAU;GACdC,WAAW,MAAMd,MAAMC,OAAO;GAC9B,IAAIY,UACFC,SAAS9C,WAAW;QACf,IAAID,SACT+C,SAAS7C,KAAK;EAElB,SAASV,OAAO;GACd0C,QAAQf,IAAI,SAAS3B,KAAK;EAC5B;CACF;CAEAgE,QAAQ;CACR,OAAON;AACT"}