@assistant-ui/core 0.3.16 → 0.3.17

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 (305) hide show
  1. package/dist/index.d.ts +2 -2
  2. package/dist/index.js +2 -2
  3. package/dist/index.js.map +1 -1
  4. package/dist/internal.d.ts +2 -1
  5. package/dist/internal.js +2 -1
  6. package/dist/model-context/frame/provider.d.ts +3 -0
  7. package/dist/model-context/frame/provider.d.ts.map +1 -1
  8. package/dist/model-context/frame/provider.js +71 -21
  9. package/dist/model-context/frame/provider.js.map +1 -1
  10. package/dist/model-context/tool-call-text.d.ts +26 -0
  11. package/dist/model-context/tool-call-text.d.ts.map +1 -0
  12. package/dist/model-context/tool-call-text.js +18 -0
  13. package/dist/model-context/tool-call-text.js.map +1 -0
  14. package/dist/react/RuntimeAdapter.js +1 -1
  15. package/dist/react/adapters/LocalStorageThreadListAdapter.d.ts.map +1 -1
  16. package/dist/react/adapters/LocalStorageThreadListAdapter.js +1 -1
  17. package/dist/react/adapters/LocalStorageThreadListAdapter.js.map +1 -1
  18. package/dist/react/client/AdaptedRemoteThread.js +1 -1
  19. package/dist/react/client/InMemoryThreadList.js +1 -1
  20. package/dist/react/client/Interactables.js +1 -1
  21. package/dist/react/client/RemoteThreadList.d.ts +15 -0
  22. package/dist/react/client/RemoteThreadList.d.ts.map +1 -1
  23. package/dist/react/client/RemoteThreadList.js +240 -138
  24. package/dist/react/client/RemoteThreadList.js.map +1 -1
  25. package/dist/react/client/Tools.d.ts.map +1 -1
  26. package/dist/react/client/Tools.js +6 -2
  27. package/dist/react/client/Tools.js.map +1 -1
  28. package/dist/react/index.d.ts +2 -1
  29. package/dist/react/index.js +2 -1
  30. package/dist/react/interactables-legacy/Interactables.js +4 -4
  31. package/dist/react/interactables-legacy/Interactables.js.map +1 -1
  32. package/dist/react/model-context/toolbox.d.ts +2 -14
  33. package/dist/react/model-context/toolbox.d.ts.map +1 -1
  34. package/dist/react/model-context/toolbox.js +1 -13
  35. package/dist/react/model-context/toolbox.js.map +1 -1
  36. package/dist/react/model-context/useAssistantContext.js +37 -7
  37. package/dist/react/model-context/useAssistantContext.js.map +1 -1
  38. package/dist/react/model-context/useAuiToolOverrides.js +31 -5
  39. package/dist/react/model-context/useAuiToolOverrides.js.map +1 -1
  40. package/dist/react/model-context/useInlineRender.d.ts.map +1 -1
  41. package/dist/react/model-context/useInlineRender.js +10 -36
  42. package/dist/react/model-context/useInlineRender.js.map +1 -1
  43. package/dist/react/primitive-hooks/useMessageError.d.ts.map +1 -1
  44. package/dist/react/primitive-hooks/useMessageError.js +2 -8
  45. package/dist/react/primitive-hooks/useMessageError.js.map +1 -1
  46. package/dist/react/primitive-hooks/useThreadListLoadMore.d.ts.map +1 -1
  47. package/dist/react/primitive-hooks/useThreadListLoadMore.js +2 -4
  48. package/dist/react/primitive-hooks/useThreadListLoadMore.js.map +1 -1
  49. package/dist/react/primitives/composer/ComposerAttachments.d.ts.map +1 -1
  50. package/dist/react/primitives/composer/ComposerAttachments.js +4 -3
  51. package/dist/react/primitives/composer/ComposerAttachments.js.map +1 -1
  52. package/dist/react/primitives/composer/ComposerQueue.d.ts.map +1 -1
  53. package/dist/react/primitives/composer/ComposerQueue.js +4 -3
  54. package/dist/react/primitives/composer/ComposerQueue.js.map +1 -1
  55. package/dist/react/primitives/message/MessageAttachments.d.ts.map +1 -1
  56. package/dist/react/primitives/message/MessageAttachments.js +7 -6
  57. package/dist/react/primitives/message/MessageAttachments.js.map +1 -1
  58. package/dist/react/primitives/message/MessageGroupedParts.js +2 -2
  59. package/dist/react/primitives/message/MessageGroupedParts.js.map +1 -1
  60. package/dist/react/primitives/message/MessageParts.js +3 -3
  61. package/dist/react/primitives/message/MessageParts.js.map +1 -1
  62. package/dist/react/primitives/threadList/ThreadListItems.d.ts.map +1 -1
  63. package/dist/react/primitives/threadList/ThreadListItems.js +5 -4
  64. package/dist/react/primitives/threadList/ThreadListItems.js.map +1 -1
  65. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.d.ts +6 -4
  66. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.d.ts.map +1 -1
  67. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js +44 -22
  68. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js.map +1 -1
  69. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts +6 -5
  70. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts.map +1 -1
  71. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js +79 -62
  72. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js.map +1 -1
  73. package/dist/react/runtimes/RemoteThreadResource.d.ts +1 -6
  74. package/dist/react/runtimes/RemoteThreadResource.d.ts.map +1 -1
  75. package/dist/react/runtimes/RemoteThreadResource.js +3 -3
  76. package/dist/react/runtimes/RemoteThreadResource.js.map +1 -1
  77. package/dist/react/runtimes/assistant-transport/useLatestRef.js +2 -2
  78. package/dist/react/runtimes/assistant-transport/useLatestRef.js.map +1 -1
  79. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.d.ts.map +1 -1
  80. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.js +23 -18
  81. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.js.map +1 -1
  82. package/dist/react/runtimes/cloud/auiV0.d.ts +5 -1
  83. package/dist/react/runtimes/cloud/auiV0.d.ts.map +1 -1
  84. package/dist/react/runtimes/cloud/auiV0.js.map +1 -1
  85. package/dist/react/runtimes/cloud/createCloudThreadListAdapter.d.ts +29 -0
  86. package/dist/react/runtimes/cloud/createCloudThreadListAdapter.d.ts.map +1 -0
  87. package/dist/react/runtimes/cloud/createCloudThreadListAdapter.js +159 -0
  88. package/dist/react/runtimes/cloud/createCloudThreadListAdapter.js.map +1 -0
  89. package/dist/react/runtimes/cloud/useCloudThreadListAdapter.d.ts +1 -9
  90. package/dist/react/runtimes/cloud/useCloudThreadListAdapter.d.ts.map +1 -1
  91. package/dist/react/runtimes/cloud/useCloudThreadListAdapter.js +16 -153
  92. package/dist/react/runtimes/cloud/useCloudThreadListAdapter.js.map +1 -1
  93. package/dist/react/runtimes/external-message-converter.js +1 -1
  94. package/dist/react/runtimes/external-message-converter.js.map +1 -1
  95. package/dist/react/runtimes/useRemoteThreadListRuntime.d.ts.map +1 -1
  96. package/dist/react/runtimes/useRemoteThreadListRuntime.js +14 -6
  97. package/dist/react/runtimes/useRemoteThreadListRuntime.js.map +1 -1
  98. package/dist/react/types/MessagePartComponentTypes.d.ts +7 -3
  99. package/dist/react/types/MessagePartComponentTypes.d.ts.map +1 -1
  100. package/dist/react/types/scopes/tools.d.ts +2 -0
  101. package/dist/react/types/scopes/tools.d.ts.map +1 -1
  102. package/dist/runtime/api/message-part-runtime.d.ts +2 -2
  103. package/dist/runtime/api/message-part-runtime.d.ts.map +1 -1
  104. package/dist/runtime/api/message-part-runtime.js +1 -1
  105. package/dist/runtime/api/message-part-runtime.js.map +1 -1
  106. package/dist/runtime/api/thread-list-runtime.d.ts +9 -1
  107. package/dist/runtime/api/thread-list-runtime.d.ts.map +1 -1
  108. package/dist/runtime/api/thread-list-runtime.js +5 -0
  109. package/dist/runtime/api/thread-list-runtime.js.map +1 -1
  110. package/dist/runtime/api/thread-runtime.d.ts +1 -1
  111. package/dist/runtime/base/base-thread-runtime-core.d.ts +2 -2
  112. package/dist/runtime/base/base-thread-runtime-core.d.ts.map +1 -1
  113. package/dist/runtime/base/base-thread-runtime-core.js +2 -2
  114. package/dist/runtime/base/base-thread-runtime-core.js.map +1 -1
  115. package/dist/runtime/interfaces/thread-list-runtime-core.d.ts +14 -2
  116. package/dist/runtime/interfaces/thread-list-runtime-core.d.ts.map +1 -1
  117. package/dist/runtime/interfaces/thread-runtime-core.d.ts +15 -1
  118. package/dist/runtime/interfaces/thread-runtime-core.d.ts.map +1 -1
  119. package/dist/runtime/utils/auto-status.d.ts +1 -1
  120. package/dist/runtime/utils/auto-status.d.ts.map +1 -1
  121. package/dist/runtime/utils/auto-status.js +6 -2
  122. package/dist/runtime/utils/auto-status.js.map +1 -1
  123. package/dist/runtime/utils/external-message-conversion.d.ts +3 -2
  124. package/dist/runtime/utils/external-message-conversion.d.ts.map +1 -1
  125. package/dist/runtime/utils/external-message-conversion.js +4 -3
  126. package/dist/runtime/utils/external-message-conversion.js.map +1 -1
  127. package/dist/runtime/utils/resolveToolApprovalResponse.d.ts +6 -3
  128. package/dist/runtime/utils/resolveToolApprovalResponse.d.ts.map +1 -1
  129. package/dist/runtime/utils/resolveToolApprovalResponse.js +12 -3
  130. package/dist/runtime/utils/resolveToolApprovalResponse.js.map +1 -1
  131. package/dist/runtime/utils/thread-message-like.d.ts +2 -10
  132. package/dist/runtime/utils/thread-message-like.d.ts.map +1 -1
  133. package/dist/runtime/utils/thread-message-like.js.map +1 -1
  134. package/dist/runtime/utils/tool-call-tree.d.ts +39 -0
  135. package/dist/runtime/utils/tool-call-tree.d.ts.map +1 -0
  136. package/dist/runtime/utils/tool-call-tree.js +85 -0
  137. package/dist/runtime/utils/tool-call-tree.js.map +1 -0
  138. package/dist/runtimes/external-store/external-store-adapter.d.ts +29 -2
  139. package/dist/runtimes/external-store/external-store-adapter.d.ts.map +1 -1
  140. package/dist/runtimes/external-store/external-store-thread-runtime-core.d.ts +2 -1
  141. package/dist/runtimes/external-store/external-store-thread-runtime-core.d.ts.map +1 -1
  142. package/dist/runtimes/external-store/external-store-thread-runtime-core.js +34 -28
  143. package/dist/runtimes/external-store/external-store-thread-runtime-core.js.map +1 -1
  144. package/dist/runtimes/inert/InertThreadRuntimeCore.d.ts +1 -1
  145. package/dist/runtimes/inert/InertThreadRuntimeCore.d.ts.map +1 -1
  146. package/dist/runtimes/inert/InertThreadRuntimeCore.js.map +1 -1
  147. package/dist/runtimes/local/local-thread-runtime-core.d.ts +1 -1
  148. package/dist/runtimes/local/local-thread-runtime-core.d.ts.map +1 -1
  149. package/dist/runtimes/local/local-thread-runtime-core.js +3 -1
  150. package/dist/runtimes/local/local-thread-runtime-core.js.map +1 -1
  151. package/dist/runtimes/remote-thread-list/remote-thread-state.d.ts +1 -1
  152. package/dist/runtimes/remote-thread-list/remote-thread-state.d.ts.map +1 -1
  153. package/dist/runtimes/remote-thread-list/remote-thread-state.js +30 -13
  154. package/dist/runtimes/remote-thread-list/remote-thread-state.js.map +1 -1
  155. package/dist/runtimes/remote-thread-list/title.d.ts +9 -0
  156. package/dist/runtimes/remote-thread-list/title.d.ts.map +1 -0
  157. package/dist/runtimes/remote-thread-list/title.js +6 -0
  158. package/dist/runtimes/remote-thread-list/title.js.map +1 -0
  159. package/dist/runtimes/remote-thread-list/types.d.ts +6 -5
  160. package/dist/runtimes/remote-thread-list/types.d.ts.map +1 -1
  161. package/dist/runtimes/tool-invocations/ToolInvocationTracker.d.ts +31 -8
  162. package/dist/runtimes/tool-invocations/ToolInvocationTracker.d.ts.map +1 -1
  163. package/dist/runtimes/tool-invocations/ToolInvocationTracker.js +97 -60
  164. package/dist/runtimes/tool-invocations/ToolInvocationTracker.js.map +1 -1
  165. package/dist/store/clients/external-thread.d.ts +1 -1
  166. package/dist/store/clients/external-thread.d.ts.map +1 -1
  167. package/dist/store/clients/external-thread.js +11 -4
  168. package/dist/store/clients/external-thread.js.map +1 -1
  169. package/dist/store/clients/single-thread-list.js +1 -1
  170. package/dist/store/clients/suggestions.d.ts.map +1 -1
  171. package/dist/store/clients/suggestions.js +18 -6
  172. package/dist/store/clients/suggestions.js.map +1 -1
  173. package/dist/store/clients/thread-message-client.js +1 -1
  174. package/dist/store/clients/thread-selection-events.js +1 -1
  175. package/dist/store/index.d.ts +2 -1
  176. package/dist/store/index.js +2 -1
  177. package/dist/store/internal.d.ts +2 -2
  178. package/dist/store/internal.js +2 -2
  179. package/dist/store/primitive-predicates.d.ts +4 -1
  180. package/dist/store/primitive-predicates.d.ts.map +1 -1
  181. package/dist/store/primitive-predicates.js +9 -1
  182. package/dist/store/primitive-predicates.js.map +1 -1
  183. package/dist/store/runtime-clients/composer-runtime-client.js +1 -1
  184. package/dist/store/runtime-clients/message-runtime-client.js +1 -1
  185. package/dist/store/runtime-clients/thread-list-item-runtime-client.js +1 -1
  186. package/dist/store/runtime-clients/thread-list-runtime-client.d.ts.map +1 -1
  187. package/dist/store/runtime-clients/thread-list-runtime-client.js +124 -105
  188. package/dist/store/runtime-clients/thread-list-runtime-client.js.map +1 -1
  189. package/dist/store/runtime-clients/thread-runtime-client.js +1 -1
  190. package/dist/store/runtime-clients/useSubscribable.d.ts +3 -1
  191. package/dist/store/runtime-clients/useSubscribable.d.ts.map +1 -1
  192. package/dist/store/runtime-clients/useSubscribable.js +1 -1
  193. package/dist/store/runtime-clients/useSubscribable.js.map +1 -1
  194. package/dist/store/scopes/part.d.ts +6 -3
  195. package/dist/store/scopes/part.d.ts.map +1 -1
  196. package/dist/subscribable/subscribable.d.ts +8 -1
  197. package/dist/subscribable/subscribable.d.ts.map +1 -1
  198. package/dist/subscribable/subscribable.js +24 -16
  199. package/dist/subscribable/subscribable.js.map +1 -1
  200. package/dist/types/message.d.ts +40 -1
  201. package/dist/types/message.d.ts.map +1 -1
  202. package/dist/types/message.js +7 -1
  203. package/dist/types/message.js.map +1 -1
  204. package/package.json +12 -17
  205. package/src/index.ts +6 -1
  206. package/src/internal.ts +8 -0
  207. package/src/model-context/frame/provider.test.ts +217 -1
  208. package/src/model-context/frame/provider.ts +111 -23
  209. package/src/model-context/tool-call-text.test.ts +67 -0
  210. package/src/model-context/tool-call-text.ts +67 -0
  211. package/src/react/AssistantRuntimeProvider.test.tsx +66 -2
  212. package/src/react/adapters/LocalStorageThreadListAdapter.tsx +1 -3
  213. package/src/react/client/RemoteThreadList.background.test.ts +384 -0
  214. package/src/react/client/RemoteThreadList.concurrent.test.tsx +274 -0
  215. package/src/react/client/RemoteThreadList.test.ts +273 -1
  216. package/src/react/client/RemoteThreadList.ts +293 -83
  217. package/src/react/client/Tools.ts +7 -1
  218. package/src/react/index.ts +4 -0
  219. package/src/react/model-context/modelContextHooks.test.tsx +131 -0
  220. package/src/react/model-context/toolbox.test.ts +9 -9
  221. package/src/react/model-context/toolbox.ts +9 -36
  222. package/src/react/model-context/useAssistantContext.ts +4 -2
  223. package/src/react/model-context/useAuiToolOverrides.ts +4 -2
  224. package/src/react/model-context/useInlineRender.test.tsx +48 -0
  225. package/src/react/model-context/useInlineRender.ts +14 -10
  226. package/src/react/primitive-hooks/useMessageError.ts +2 -19
  227. package/src/react/primitive-hooks/useThreadListLoadMore.ts +2 -3
  228. package/src/react/primitives/composer/ComposerAttachments.test.tsx +76 -0
  229. package/src/react/primitives/composer/ComposerAttachments.tsx +9 -4
  230. package/src/react/primitives/composer/ComposerQueue.test.tsx +72 -0
  231. package/src/react/primitives/composer/ComposerQueue.tsx +7 -4
  232. package/src/react/primitives/message/MessageAttachments.test.tsx +107 -37
  233. package/src/react/primitives/message/MessageAttachments.tsx +10 -7
  234. package/src/react/primitives/message/MessageGroupedParts.tsx +2 -2
  235. package/src/react/primitives/message/MessageParts.tsx +3 -3
  236. package/src/react/primitives/threadList/ThreadListItems.test.tsx +99 -0
  237. package/src/react/primitives/threadList/ThreadListItems.tsx +8 -5
  238. package/src/react/runtimes/RemoteThreadListHookInstanceManager.running.test.tsx +94 -1
  239. package/src/react/runtimes/RemoteThreadListHookInstanceManager.tsx +72 -31
  240. package/src/react/runtimes/RemoteThreadListThreadListRuntimeCore.switch-delete.test.ts +169 -0
  241. package/src/react/runtimes/RemoteThreadListThreadListRuntimeCore.tsx +114 -68
  242. package/src/react/runtimes/RemoteThreadResource.ts +1 -4
  243. package/src/react/runtimes/assistant-transport/transport-scheduling.test.ts +51 -2
  244. package/src/react/runtimes/assistant-transport/useLatestRef.ts +2 -2
  245. package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.test.ts +45 -0
  246. package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.test.tsx +65 -1
  247. package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.ts +42 -35
  248. package/src/react/runtimes/cloud/auiV0.ts +5 -0
  249. package/src/react/runtimes/cloud/createCloudThreadListAdapter.test.ts +88 -0
  250. package/src/react/runtimes/cloud/createCloudThreadListAdapter.ts +236 -0
  251. package/src/react/runtimes/cloud/useCloudThreadListAdapter.test.tsx +90 -1
  252. package/src/react/runtimes/cloud/useCloudThreadListAdapter.tsx +33 -238
  253. package/src/react/runtimes/external-message-converter.ts +1 -0
  254. package/src/react/runtimes/useRemoteThreadListRuntime.concurrent.test.tsx +216 -0
  255. package/src/react/runtimes/useRemoteThreadListRuntime.ts +24 -6
  256. package/src/react/types/MessagePartComponentTypes.ts +7 -3
  257. package/src/react/types/scopes/tools.ts +2 -0
  258. package/src/runtime/api/message-part-runtime.ts +3 -3
  259. package/src/runtime/api/thread-list-runtime.ts +25 -1
  260. package/src/runtime/base/base-thread-runtime-core.test.ts +94 -3
  261. package/src/runtime/base/base-thread-runtime-core.ts +10 -4
  262. package/src/runtime/interfaces/thread-list-runtime-core.ts +20 -1
  263. package/src/runtime/interfaces/thread-runtime-core.ts +17 -1
  264. package/src/runtime/utils/auto-status.test.ts +57 -0
  265. package/src/runtime/utils/auto-status.ts +13 -1
  266. package/src/runtime/utils/external-message-conversion.test.ts +97 -0
  267. package/src/runtime/utils/external-message-conversion.ts +17 -1
  268. package/src/runtime/utils/resolveToolApprovalResponse.test.ts +73 -0
  269. package/src/runtime/utils/resolveToolApprovalResponse.ts +27 -6
  270. package/src/runtime/utils/thread-message-like.ts +2 -10
  271. package/src/runtime/utils/tool-call-tree.test.ts +191 -0
  272. package/src/runtime/utils/tool-call-tree.ts +97 -0
  273. package/src/runtimes/external-store/external-store-adapter.ts +38 -2
  274. package/src/runtimes/external-store/external-store-thread-runtime-core.ts +56 -33
  275. package/src/runtimes/inert/InertThreadRuntimeCore.ts +1 -1
  276. package/src/runtimes/local/local-thread-runtime-core.test.ts +29 -3
  277. package/src/runtimes/local/local-thread-runtime-core.ts +5 -1
  278. package/src/runtimes/remote-thread-list/remote-thread-state.test.ts +112 -0
  279. package/src/runtimes/remote-thread-list/remote-thread-state.ts +55 -16
  280. package/src/runtimes/remote-thread-list/title.ts +3 -0
  281. package/src/runtimes/remote-thread-list/types.ts +6 -5
  282. package/src/runtimes/tool-invocations/EDGE_CASES.md +110 -5
  283. package/src/runtimes/tool-invocations/ToolInvocationTracker.test.ts +750 -136
  284. package/src/runtimes/tool-invocations/ToolInvocationTracker.ts +144 -91
  285. package/src/store/clients/external-thread.ts +14 -8
  286. package/src/store/clients/suggestions.test.ts +155 -1
  287. package/src/store/clients/suggestions.ts +42 -34
  288. package/src/store/index.ts +4 -0
  289. package/src/store/internal.ts +2 -0
  290. package/src/store/primitive-predicates.ts +35 -0
  291. package/src/store/runtime-clients/thread-list-runtime-client.ts +16 -2
  292. package/src/store/runtime-clients/useSubscribable.ts +8 -2
  293. package/src/store/scopes/part.ts +6 -3
  294. package/src/subscribable/subscribable.test.ts +50 -0
  295. package/src/subscribable/subscribable.ts +33 -21
  296. package/src/tests/RemoteThreadListThreadListRuntimeCore-load-race.test.ts +111 -0
  297. package/src/tests/RemoteThreadListThreadListRuntimeCore-loadMore.test.ts +78 -0
  298. package/src/tests/RemoteThreadListThreadListRuntimeCore-reload.test.ts +52 -0
  299. package/src/tests/external-store-optimistic-id.test.ts +79 -0
  300. package/src/tests/external-store-repository-instance.test.ts +166 -0
  301. package/src/tests/external-store-thread-runtime-core-adapter.test.ts +22 -16
  302. package/src/tests/external-thread-attachments.test.tsx +85 -1
  303. package/src/tests/remote-thread-list-adapter-switch.test.ts +66 -1
  304. package/src/tests/thread-switch-events.test.tsx +397 -2
  305. package/src/types/message.ts +50 -2
@@ -1 +1 @@
1
- {"version":3,"file":"thread-list-runtime.js","names":["Unsubscribe","LazyMemoizeSubject","NestedSubscriptionSubject","SKIP_UPDATE","ShallowMemoizeSubject","ThreadListRuntimeCore","ThreadListItemRuntime","ThreadListItemRuntimeImpl","ThreadListItemState","ThreadListItemRuntimeBinding","ThreadRuntime","ThreadRuntimeCoreBinding","ThreadRuntimeImpl","RESOLVED_PROMISE","Promise","resolve","ThreadListState","mainThreadId","newThreadId","threadIds","archivedThreadIds","isLoading","isLoadingMore","hasMore","threadItems","Readonly","Record","Omit","ThreadListRuntime","getState","subscribe","callback","main","getById","threadId","mainItem","getItemById","getItemByIndex","idx","getArchivedItemByIndex","switchToThread","options","unarchive","switchToNewThread","getLoadThreadsPromise","reload","reloadMainThread","loadMore","getThreadListState","threadList","getThreadListItemState","undefined","threadData","id","remoteId","externalId","title","status","lastMessageAt","custom","isMain","isRunning","unstable_isThreadRunning","ThreadListRuntimeCoreBinding","ThreadListRuntimeImpl","_getState","_stateBinding","_core","_runtimeFactory","binding","threadListItemBinding","constructor","stateBinding","path","bind","_mainThreadListItemRuntime","ref","threadSelector","type","getMainThreadRuntimeCore","__internal_bindMethods","JSON","stringify","getThreadRuntimeCore","index"],"sources":["../../../src/runtime/api/thread-list-runtime.ts"],"sourcesContent":["import type { Unsubscribe } from \"../../types/unsubscribe\";\nimport {\n LazyMemoizeSubject,\n NestedSubscriptionSubject,\n} from \"../../subscribable/subscribable\";\nimport {\n SKIP_UPDATE,\n ShallowMemoizeSubject,\n} from \"../../subscribable/subscribable\";\nimport type { ThreadListRuntimeCore } from \"../interfaces/thread-list-runtime-core\";\nimport {\n type ThreadListItemRuntime,\n ThreadListItemRuntimeImpl,\n type ThreadListItemState,\n} from \"./thread-list-item-runtime\";\nimport {\n type ThreadListItemRuntimeBinding,\n type ThreadRuntime,\n type ThreadRuntimeCoreBinding,\n ThreadRuntimeImpl,\n} from \"./thread-runtime\";\n\nconst RESOLVED_PROMISE = Promise.resolve();\n\nexport type ThreadListState = {\n readonly mainThreadId: string;\n readonly newThreadId: string | undefined;\n readonly threadIds: readonly string[];\n readonly archivedThreadIds: readonly string[];\n readonly isLoading: boolean;\n readonly isLoadingMore: boolean;\n readonly hasMore: boolean;\n readonly threadItems: Readonly<\n Record<\n string,\n Omit<ThreadListItemState, \"isMain\" | \"threadId\" | \"isRunning\">\n >\n >;\n};\n\nexport type ThreadListRuntime = {\n getState(): ThreadListState;\n\n subscribe(callback: () => void): Unsubscribe;\n\n readonly main: ThreadRuntime;\n getById(threadId: string): ThreadRuntime;\n\n readonly mainItem: ThreadListItemRuntime;\n getItemById(threadId: string): ThreadListItemRuntime;\n getItemByIndex(idx: number): ThreadListItemRuntime;\n getArchivedItemByIndex(idx: number): ThreadListItemRuntime;\n\n switchToThread(\n threadId: string,\n options?: { unarchive?: boolean },\n ): Promise<void>;\n switchToNewThread(): Promise<void>;\n\n getLoadThreadsPromise(): Promise<void>;\n reload(): Promise<void>;\n /**\n * Refetches the open thread's remote state, for state that changed out of\n * band and so never reached the stream. When the runtime declares the\n * in-place capability (`unstable_refetchThread`), composer drafts survive,\n * existing messages stay rendered during the refetch, and the promise\n * settles with the refetch, rejecting if it fails; that runtime also owns\n * what happens to a run in progress, since this does not stop one. Runtimes\n * without the capability have their hook remounted instead, which discards\n * unsent composer input and ends any run, and the promise resolves once the\n * new runtime attaches. A thread that has not been sent yet is left alone.\n */\n reloadMainThread(): Promise<void>;\n loadMore(): Promise<void>;\n};\n\nconst getThreadListState = (\n threadList: ThreadListRuntimeCore,\n): ThreadListState => {\n return {\n mainThreadId: threadList.mainThreadId,\n newThreadId: threadList.newThreadId,\n threadIds: threadList.threadIds,\n archivedThreadIds: threadList.archivedThreadIds,\n isLoading: threadList.isLoading,\n isLoadingMore: threadList.isLoadingMore ?? false,\n hasMore: threadList.hasMore ?? false,\n threadItems: threadList.threadItems,\n };\n};\n\nconst getThreadListItemState = (\n threadList: ThreadListRuntimeCore,\n threadId: string | undefined,\n): ThreadListItemState | SKIP_UPDATE => {\n if (threadId === undefined) return SKIP_UPDATE;\n\n const threadData = threadList.getItemById(threadId);\n if (!threadData) return SKIP_UPDATE;\n return {\n id: threadData.id,\n remoteId: threadData.remoteId,\n externalId: threadData.externalId,\n title: threadData.title,\n status: threadData.status,\n lastMessageAt: threadData.lastMessageAt,\n custom: threadData.custom,\n isMain: threadData.id === threadList.mainThreadId,\n isRunning: threadList.unstable_isThreadRunning?.(threadData.id) ?? false,\n };\n};\n\nexport type ThreadListRuntimeCoreBinding = ThreadListRuntimeCore;\n\nexport class ThreadListRuntimeImpl implements ThreadListRuntime {\n private _getState;\n private _stateBinding: LazyMemoizeSubject<ThreadListState, object>;\n private _core: ThreadListRuntimeCoreBinding;\n private _runtimeFactory: new (\n binding: ThreadRuntimeCoreBinding,\n threadListItemBinding: ThreadListItemRuntimeBinding,\n ) => ThreadRuntime;\n\n constructor(\n _core: ThreadListRuntimeCoreBinding,\n _runtimeFactory: new (\n binding: ThreadRuntimeCoreBinding,\n threadListItemBinding: ThreadListItemRuntimeBinding,\n ) => ThreadRuntime = ThreadRuntimeImpl,\n ) {\n this._core = _core;\n this._runtimeFactory = _runtimeFactory;\n const stateBinding = new LazyMemoizeSubject({\n path: {},\n getState: () => getThreadListState(_core),\n subscribe: (callback) => _core.subscribe(callback),\n });\n\n this._getState = stateBinding.getState.bind(stateBinding);\n this._stateBinding = stateBinding;\n\n this._mainThreadListItemRuntime = new ThreadListItemRuntimeImpl(\n new ShallowMemoizeSubject({\n path: {\n ref: `threadItems[main]`,\n threadSelector: { type: \"main\" },\n },\n getState: () => {\n return getThreadListItemState(this._core, this._core.mainThreadId);\n },\n subscribe: (callback) => this._core.subscribe(callback),\n }),\n this._core,\n );\n\n this.main = new _runtimeFactory(\n new NestedSubscriptionSubject({\n path: {\n ref: \"threads.main\",\n threadSelector: { type: \"main\" },\n },\n getState: () => _core.getMainThreadRuntimeCore(),\n subscribe: (callback) => _core.subscribe(callback),\n }),\n this._mainThreadListItemRuntime,\n );\n\n this.__internal_bindMethods();\n }\n\n protected __internal_bindMethods() {\n this.switchToThread = this.switchToThread.bind(this);\n this.switchToNewThread = this.switchToNewThread.bind(this);\n this.getLoadThreadsPromise = this.getLoadThreadsPromise.bind(this);\n this.reload = this.reload.bind(this);\n this.reloadMainThread = this.reloadMainThread.bind(this);\n this.loadMore = this.loadMore.bind(this);\n this.getState = this.getState.bind(this);\n this.subscribe = this.subscribe.bind(this);\n this.getById = this.getById.bind(this);\n this.getItemById = this.getItemById.bind(this);\n this.getItemByIndex = this.getItemByIndex.bind(this);\n this.getArchivedItemByIndex = this.getArchivedItemByIndex.bind(this);\n }\n\n public switchToThread(\n threadId: string,\n options?: { unarchive?: boolean },\n ): Promise<void> {\n return this._core.switchToThread(threadId, options);\n }\n\n public switchToNewThread(): Promise<void> {\n return this._core.switchToNewThread();\n }\n\n public getLoadThreadsPromise(): Promise<void> {\n return this._core.getLoadThreadsPromise();\n }\n\n public reload(): Promise<void> {\n return this._core.reload?.() ?? RESOLVED_PROMISE;\n }\n\n public reloadMainThread(): Promise<void> {\n return this._core.reloadMainThread?.() ?? RESOLVED_PROMISE;\n }\n\n public loadMore(): Promise<void> {\n return this._core.loadMore?.() ?? RESOLVED_PROMISE;\n }\n\n public getState(): ThreadListState {\n return this._getState();\n }\n\n public subscribe(callback: () => void): Unsubscribe {\n return this._stateBinding.subscribe(callback);\n }\n\n private _mainThreadListItemRuntime;\n\n public readonly main: ThreadRuntime;\n\n public get mainItem() {\n return this._mainThreadListItemRuntime;\n }\n\n public getById(threadId: string) {\n return new this._runtimeFactory(\n new NestedSubscriptionSubject({\n path: {\n ref: `threads[threadId=${JSON.stringify(threadId)}]`,\n threadSelector: { type: \"threadId\", threadId },\n },\n getState: () => this._core.getThreadRuntimeCore(threadId),\n subscribe: (callback) => this._core.subscribe(callback),\n }),\n this.mainItem,\n );\n }\n\n public getItemByIndex(idx: number) {\n return new ThreadListItemRuntimeImpl(\n new ShallowMemoizeSubject({\n path: {\n ref: `threadItems[${idx}]`,\n threadSelector: { type: \"index\", index: idx },\n },\n getState: () => {\n return getThreadListItemState(this._core, this._core.threadIds[idx]);\n },\n subscribe: (callback) => this._core.subscribe(callback),\n }),\n this._core,\n );\n }\n\n public getArchivedItemByIndex(idx: number) {\n return new ThreadListItemRuntimeImpl(\n new ShallowMemoizeSubject({\n path: {\n ref: `archivedThreadItems[${idx}]`,\n threadSelector: { type: \"archiveIndex\", index: idx },\n },\n getState: () => {\n return getThreadListItemState(\n this._core,\n this._core.archivedThreadIds[idx],\n );\n },\n subscribe: (callback) => this._core.subscribe(callback),\n }),\n this._core,\n );\n }\n\n public getItemById(threadId: string) {\n return new ThreadListItemRuntimeImpl(\n new ShallowMemoizeSubject({\n path: {\n ref: `threadItems[threadId=${threadId}]`,\n threadSelector: { type: \"threadId\", threadId },\n },\n getState: () => {\n return getThreadListItemState(this._core, threadId);\n },\n subscribe: (callback) => this._core.subscribe(callback),\n }),\n this._core,\n );\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"thread-list-runtime.js","names":["Unsubscribe","LazyMemoizeSubject","NestedSubscriptionSubject","SKIP_UPDATE","ShallowMemoizeSubject","ThreadListRuntimeCore","ThreadListRuntimeEvent","ThreadListItemRuntime","ThreadListItemRuntimeImpl","ThreadListItemState","ThreadListItemRuntimeBinding","ThreadRuntime","ThreadRuntimeCoreBinding","ThreadRuntimeImpl","RESOLVED_PROMISE","Promise","resolve","NOOP_UNSUBSCRIBE","ThreadListState","mainThreadId","newThreadId","threadIds","archivedThreadIds","isLoading","isLoadingMore","hasMore","threadItems","Readonly","Record","Omit","ThreadListRuntime","getState","subscribe","callback","main","getById","threadId","mainItem","getItemById","getItemByIndex","idx","getArchivedItemByIndex","switchToThread","options","unarchive","switchToNewThread","unstable_subscribeThreadEvents","event","getLoadThreadsPromise","reload","reloadMainThread","loadMore","getThreadListState","threadList","getThreadListItemState","undefined","threadData","id","remoteId","externalId","title","status","lastMessageAt","custom","isMain","isRunning","unstable_isThreadRunning","ThreadListRuntimeCoreBinding","ThreadListRuntimeImpl","_getState","_stateBinding","_core","_runtimeFactory","binding","threadListItemBinding","constructor","stateBinding","path","bind","_mainThreadListItemRuntime","ref","threadSelector","type","getMainThreadRuntimeCore","__internal_bindMethods","JSON","stringify","getThreadRuntimeCore","index"],"sources":["../../../src/runtime/api/thread-list-runtime.ts"],"sourcesContent":["import type { Unsubscribe } from \"../../types/unsubscribe\";\nimport {\n LazyMemoizeSubject,\n NestedSubscriptionSubject,\n} from \"../../subscribable/subscribable\";\nimport {\n SKIP_UPDATE,\n ShallowMemoizeSubject,\n} from \"../../subscribable/subscribable\";\nimport type {\n ThreadListRuntimeCore,\n ThreadListRuntimeEvent,\n} from \"../interfaces/thread-list-runtime-core\";\nimport {\n type ThreadListItemRuntime,\n ThreadListItemRuntimeImpl,\n type ThreadListItemState,\n} from \"./thread-list-item-runtime\";\nimport {\n type ThreadListItemRuntimeBinding,\n type ThreadRuntime,\n type ThreadRuntimeCoreBinding,\n ThreadRuntimeImpl,\n} from \"./thread-runtime\";\n\nconst RESOLVED_PROMISE = Promise.resolve();\nconst NOOP_UNSUBSCRIBE = () => {};\n\nexport type ThreadListState = {\n readonly mainThreadId: string;\n readonly newThreadId: string | undefined;\n readonly threadIds: readonly string[];\n readonly archivedThreadIds: readonly string[];\n readonly isLoading: boolean;\n readonly isLoadingMore: boolean;\n readonly hasMore: boolean;\n readonly threadItems: Readonly<\n Record<\n string,\n Omit<ThreadListItemState, \"isMain\" | \"threadId\" | \"isRunning\">\n >\n >;\n};\n\nexport type ThreadListRuntime = {\n getState(): ThreadListState;\n\n subscribe(callback: () => void): Unsubscribe;\n\n readonly main: ThreadRuntime;\n getById(threadId: string): ThreadRuntime;\n\n readonly mainItem: ThreadListItemRuntime;\n getItemById(threadId: string): ThreadListItemRuntime;\n getItemByIndex(idx: number): ThreadListItemRuntime;\n getArchivedItemByIndex(idx: number): ThreadListItemRuntime;\n\n switchToThread(\n threadId: string,\n options?: { unarchive?: boolean },\n ): Promise<void>;\n switchToNewThread(): Promise<void>;\n\n /**\n * Observes lifecycle events on every thread this list keeps alive, so an\n * event that fires while its thread is not selected stays observable. Thread\n * lists that mount only the main thread never emit; their main thread's\n * runtime is observed directly.\n */\n unstable_subscribeThreadEvents(\n callback: (event: ThreadListRuntimeEvent) => void,\n ): Unsubscribe;\n\n getLoadThreadsPromise(): Promise<void>;\n reload(): Promise<void>;\n /**\n * Refetches the open thread's remote state, for state that changed out of\n * band and so never reached the stream. When the runtime declares the\n * in-place capability (`unstable_refetchThread`), composer drafts survive,\n * existing messages stay rendered during the refetch, and the promise\n * settles with the refetch, rejecting if it fails; that runtime also owns\n * what happens to a run in progress, since this does not stop one. Runtimes\n * without the capability have their hook remounted instead, which discards\n * unsent composer input and ends any run, and the promise resolves once the\n * new runtime attaches. A thread that has not been sent yet is left alone.\n */\n reloadMainThread(): Promise<void>;\n loadMore(): Promise<void>;\n};\n\nconst getThreadListState = (\n threadList: ThreadListRuntimeCore,\n): ThreadListState => {\n return {\n mainThreadId: threadList.mainThreadId,\n newThreadId: threadList.newThreadId,\n threadIds: threadList.threadIds,\n archivedThreadIds: threadList.archivedThreadIds,\n isLoading: threadList.isLoading,\n isLoadingMore: threadList.isLoadingMore ?? false,\n hasMore: threadList.hasMore ?? false,\n threadItems: threadList.threadItems,\n };\n};\n\nconst getThreadListItemState = (\n threadList: ThreadListRuntimeCore,\n threadId: string | undefined,\n): ThreadListItemState | SKIP_UPDATE => {\n if (threadId === undefined) return SKIP_UPDATE;\n\n const threadData = threadList.getItemById(threadId);\n if (!threadData) return SKIP_UPDATE;\n return {\n id: threadData.id,\n remoteId: threadData.remoteId,\n externalId: threadData.externalId,\n title: threadData.title,\n status: threadData.status,\n lastMessageAt: threadData.lastMessageAt,\n custom: threadData.custom,\n isMain: threadData.id === threadList.mainThreadId,\n isRunning: threadList.unstable_isThreadRunning?.(threadData.id) ?? false,\n };\n};\n\nexport type ThreadListRuntimeCoreBinding = ThreadListRuntimeCore;\n\nexport class ThreadListRuntimeImpl implements ThreadListRuntime {\n private _getState;\n private _stateBinding: LazyMemoizeSubject<ThreadListState, object>;\n private _core: ThreadListRuntimeCoreBinding;\n private _runtimeFactory: new (\n binding: ThreadRuntimeCoreBinding,\n threadListItemBinding: ThreadListItemRuntimeBinding,\n ) => ThreadRuntime;\n\n constructor(\n _core: ThreadListRuntimeCoreBinding,\n _runtimeFactory: new (\n binding: ThreadRuntimeCoreBinding,\n threadListItemBinding: ThreadListItemRuntimeBinding,\n ) => ThreadRuntime = ThreadRuntimeImpl,\n ) {\n this._core = _core;\n this._runtimeFactory = _runtimeFactory;\n const stateBinding = new LazyMemoizeSubject({\n path: {},\n getState: () => getThreadListState(_core),\n subscribe: (callback) => _core.subscribe(callback),\n });\n\n this._getState = stateBinding.getState.bind(stateBinding);\n this._stateBinding = stateBinding;\n\n this._mainThreadListItemRuntime = new ThreadListItemRuntimeImpl(\n new ShallowMemoizeSubject({\n path: {\n ref: `threadItems[main]`,\n threadSelector: { type: \"main\" },\n },\n getState: () => {\n return getThreadListItemState(this._core, this._core.mainThreadId);\n },\n subscribe: (callback) => this._core.subscribe(callback),\n }),\n this._core,\n );\n\n this.main = new _runtimeFactory(\n new NestedSubscriptionSubject({\n path: {\n ref: \"threads.main\",\n threadSelector: { type: \"main\" },\n },\n getState: () => _core.getMainThreadRuntimeCore(),\n subscribe: (callback) => _core.subscribe(callback),\n }),\n this._mainThreadListItemRuntime,\n );\n\n this.__internal_bindMethods();\n }\n\n protected __internal_bindMethods() {\n this.switchToThread = this.switchToThread.bind(this);\n this.switchToNewThread = this.switchToNewThread.bind(this);\n this.unstable_subscribeThreadEvents =\n this.unstable_subscribeThreadEvents.bind(this);\n this.getLoadThreadsPromise = this.getLoadThreadsPromise.bind(this);\n this.reload = this.reload.bind(this);\n this.reloadMainThread = this.reloadMainThread.bind(this);\n this.loadMore = this.loadMore.bind(this);\n this.getState = this.getState.bind(this);\n this.subscribe = this.subscribe.bind(this);\n this.getById = this.getById.bind(this);\n this.getItemById = this.getItemById.bind(this);\n this.getItemByIndex = this.getItemByIndex.bind(this);\n this.getArchivedItemByIndex = this.getArchivedItemByIndex.bind(this);\n }\n\n public switchToThread(\n threadId: string,\n options?: { unarchive?: boolean },\n ): Promise<void> {\n return this._core.switchToThread(threadId, options);\n }\n\n public switchToNewThread(): Promise<void> {\n return this._core.switchToNewThread();\n }\n\n public unstable_subscribeThreadEvents(\n callback: (event: ThreadListRuntimeEvent) => void,\n ): Unsubscribe {\n return (\n this._core.unstable_subscribeThreadEvents?.(callback) ?? NOOP_UNSUBSCRIBE\n );\n }\n\n public getLoadThreadsPromise(): Promise<void> {\n return this._core.getLoadThreadsPromise();\n }\n\n public reload(): Promise<void> {\n return this._core.reload?.() ?? RESOLVED_PROMISE;\n }\n\n public reloadMainThread(): Promise<void> {\n return this._core.reloadMainThread?.() ?? RESOLVED_PROMISE;\n }\n\n public loadMore(): Promise<void> {\n return this._core.loadMore?.() ?? RESOLVED_PROMISE;\n }\n\n public getState(): ThreadListState {\n return this._getState();\n }\n\n public subscribe(callback: () => void): Unsubscribe {\n return this._stateBinding.subscribe(callback);\n }\n\n private _mainThreadListItemRuntime;\n\n public readonly main: ThreadRuntime;\n\n public get mainItem() {\n return this._mainThreadListItemRuntime;\n }\n\n public getById(threadId: string) {\n return new this._runtimeFactory(\n new NestedSubscriptionSubject({\n path: {\n ref: `threads[threadId=${JSON.stringify(threadId)}]`,\n threadSelector: { type: \"threadId\", threadId },\n },\n getState: () => this._core.getThreadRuntimeCore(threadId),\n subscribe: (callback) => this._core.subscribe(callback),\n }),\n this.mainItem,\n );\n }\n\n public getItemByIndex(idx: number) {\n return new ThreadListItemRuntimeImpl(\n new ShallowMemoizeSubject({\n path: {\n ref: `threadItems[${idx}]`,\n threadSelector: { type: \"index\", index: idx },\n },\n getState: () => {\n return getThreadListItemState(this._core, this._core.threadIds[idx]);\n },\n subscribe: (callback) => this._core.subscribe(callback),\n }),\n this._core,\n );\n }\n\n public getArchivedItemByIndex(idx: number) {\n return new ThreadListItemRuntimeImpl(\n new ShallowMemoizeSubject({\n path: {\n ref: `archivedThreadItems[${idx}]`,\n threadSelector: { type: \"archiveIndex\", index: idx },\n },\n getState: () => {\n return getThreadListItemState(\n this._core,\n this._core.archivedThreadIds[idx],\n );\n },\n subscribe: (callback) => this._core.subscribe(callback),\n }),\n this._core,\n );\n }\n\n public getItemById(threadId: string) {\n return new ThreadListItemRuntimeImpl(\n new ShallowMemoizeSubject({\n path: {\n ref: `threadItems[threadId=${threadId}]`,\n threadSelector: { type: \"threadId\", threadId },\n },\n getState: () => {\n return getThreadListItemState(this._core, threadId);\n },\n subscribe: (callback) => this._core.subscribe(callback),\n }),\n this._core,\n );\n }\n}\n"],"mappings":";;;;AAyBA,MAAMc,mBAAmBC,QAAQC,QAAQ;AACzC,MAAMC,yBAAyB,CAAC;AAgEhC,MAAMmC,sBACJC,eACoB;CACpB,OAAO;EACLlC,cAAckC,WAAWlC;EACzBC,aAAaiC,WAAWjC;EACxBC,WAAWgC,WAAWhC;EACtBC,mBAAmB+B,WAAW/B;EAC9BC,WAAW8B,WAAW9B;EACtBC,eAAe6B,WAAW7B,iBAAiB;EAC3CC,SAAS4B,WAAW5B,WAAW;EAC/BC,aAAa2B,WAAW3B;CAC1B;AACF;AAEA,MAAM4B,0BACJD,YACAjB,aACsC;CACtC,IAAIA,aAAamB,KAAAA,GAAW,OAAOpD;CAEnC,MAAMqD,aAAaH,WAAWf,YAAYF,QAAQ;CAClD,IAAI,CAACoB,YAAY,OAAOrD;CACxB,OAAO;EACLsD,IAAID,WAAWC;EACfC,UAAUF,WAAWE;EACrBC,YAAYH,WAAWG;EACvBC,OAAOJ,WAAWI;EAClBC,QAAQL,WAAWK;EACnBC,eAAeN,WAAWM;EAC1BC,QAAQP,WAAWO;EACnBC,QAAQR,WAAWC,OAAOJ,WAAWlC;EACrC8C,WAAWZ,WAAWa,2BAA2BV,WAAWC,EAAE,KAAK;CACrE;AACF;AAIA,IAAaW,wBAAb,MAAgE;CAC9D;CACA;CACA;CACA;CAKAO,YACEJ,OACAC,kBAGqB3D,mBACrB;EACA,KAAK0D,QAAQA;EACb,KAAKC,kBAAkBA;EACvB,MAAMI,eAAe,IAAI3E,mBAAmB;GAC1C4E,MAAM,CAAC;GACP9C,gBAAgBqB,mBAAmBmB,KAAK;GACxCvC,YAAYC,aAAasC,MAAMvC,UAAUC,QAAQ;EACnD,CAAC;EAED,KAAKoC,YAAYO,aAAa7C,SAAS+C,KAAKF,YAAY;EACxD,KAAKN,gBAAgBM;EAErB,KAAKG,6BAA6B,IAAIvE,0BACpC,IAAIJ,sBAAsB;GACxByE,MAAM;IACJG,KAAK;IACLC,gBAAgB,EAAEC,MAAM,OAAO;GACjC;GACAnD,gBAAgB;IACd,OAAOuB,uBAAuB,KAAKiB,OAAO,KAAKA,MAAMpD,YAAY;GACnE;GACAa,YAAYC,aAAa,KAAKsC,MAAMvC,UAAUC,QAAQ;EACxD,CAAC,GACD,KAAKsC,KACP;EAEA,KAAKrC,OAAO,IAAIsC,gBACd,IAAItE,0BAA0B;GAC5B2E,MAAM;IACJG,KAAK;IACLC,gBAAgB,EAAEC,MAAM,OAAO;GACjC;GACAnD,gBAAgBwC,MAAMY,yBAAyB;GAC/CnD,YAAYC,aAAasC,MAAMvC,UAAUC,QAAQ;EACnD,CAAC,GACD,KAAK8C,0BACP;EAEA,KAAKK,uBAAuB;CAC9B;CAEA,yBAAmC;EACjC,KAAK1C,iBAAiB,KAAKA,eAAeoC,KAAK,IAAI;EACnD,KAAKjC,oBAAoB,KAAKA,kBAAkBiC,KAAK,IAAI;EACzD,KAAKhC,iCACH,KAAKA,+BAA+BgC,KAAK,IAAI;EAC/C,KAAK9B,wBAAwB,KAAKA,sBAAsB8B,KAAK,IAAI;EACjE,KAAK7B,SAAS,KAAKA,OAAO6B,KAAK,IAAI;EACnC,KAAK5B,mBAAmB,KAAKA,iBAAiB4B,KAAK,IAAI;EACvD,KAAK3B,WAAW,KAAKA,SAAS2B,KAAK,IAAI;EACvC,KAAK/C,WAAW,KAAKA,SAAS+C,KAAK,IAAI;EACvC,KAAK9C,YAAY,KAAKA,UAAU8C,KAAK,IAAI;EACzC,KAAK3C,UAAU,KAAKA,QAAQ2C,KAAK,IAAI;EACrC,KAAKxC,cAAc,KAAKA,YAAYwC,KAAK,IAAI;EAC7C,KAAKvC,iBAAiB,KAAKA,eAAeuC,KAAK,IAAI;EACnD,KAAKrC,yBAAyB,KAAKA,uBAAuBqC,KAAK,IAAI;CACrE;CAEA,eACE1C,UACAO,SACe;EACf,OAAO,KAAK4B,MAAM7B,eAAeN,UAAUO,OAAO;CACpD;CAEA,oBAA0C;EACxC,OAAO,KAAK4B,MAAM1B,kBAAkB;CACtC;CAEA,+BACEZ,UACa;EACb,OACE,KAAKsC,MAAMzB,iCAAiCb,QAAQ,KAAKhB;CAE7D;CAEA,wBAA8C;EAC5C,OAAO,KAAKsD,MAAMvB,sBAAsB;CAC1C;CAEA,SAA+B;EAC7B,OAAO,KAAKuB,MAAMtB,SAAS,KAAKnC;CAClC;CAEA,mBAAyC;EACvC,OAAO,KAAKyD,MAAMrB,mBAAmB,KAAKpC;CAC5C;CAEA,WAAiC;EAC/B,OAAO,KAAKyD,MAAMpB,WAAW,KAAKrC;CACpC;CAEA,WAAmC;EACjC,OAAO,KAAKuD,UAAU;CACxB;CAEA,UAAiBpC,UAAmC;EAClD,OAAO,KAAKqC,cAActC,UAAUC,QAAQ;CAC9C;CAEA;CAEA;CAEA,IAAWI,WAAW;EACpB,OAAO,KAAK0C;CACd;CAEA,QAAe3C,UAAkB;EAC/B,OAAO,IAAI,KAAKoC,gBACd,IAAItE,0BAA0B;GAC5B2E,MAAM;IACJG,KAAK,oBAAoBK,KAAKC,UAAUlD,QAAQ,EAAC;IACjD6C,gBAAgB;KAAEC,MAAM;KAAY9C;IAAS;GAC/C;GACAL,gBAAgB,KAAKwC,MAAMgB,qBAAqBnD,QAAQ;GACxDJ,YAAYC,aAAa,KAAKsC,MAAMvC,UAAUC,QAAQ;EACxD,CAAC,GACD,KAAKI,QACP;CACF;CAEA,eAAsBG,KAAa;EACjC,OAAO,IAAIhC,0BACT,IAAIJ,sBAAsB;GACxByE,MAAM;IACJG,KAAK,eAAexC,IAAG;IACvByC,gBAAgB;KAAEC,MAAM;KAASM,OAAOhD;IAAI;GAC9C;GACAT,gBAAgB;IACd,OAAOuB,uBAAuB,KAAKiB,OAAO,KAAKA,MAAMlD,UAAUmB,IAAI;GACrE;GACAR,YAAYC,aAAa,KAAKsC,MAAMvC,UAAUC,QAAQ;EACxD,CAAC,GACD,KAAKsC,KACP;CACF;CAEA,uBAA8B/B,KAAa;EACzC,OAAO,IAAIhC,0BACT,IAAIJ,sBAAsB;GACxByE,MAAM;IACJG,KAAK,uBAAuBxC,IAAG;IAC/ByC,gBAAgB;KAAEC,MAAM;KAAgBM,OAAOhD;IAAI;GACrD;GACAT,gBAAgB;IACd,OAAOuB,uBACL,KAAKiB,OACL,KAAKA,MAAMjD,kBAAkBkB,IAC/B;GACF;GACAR,YAAYC,aAAa,KAAKsC,MAAMvC,UAAUC,QAAQ;EACxD,CAAC,GACD,KAAKsC,KACP;CACF;CAEA,YAAmBnC,UAAkB;EACnC,OAAO,IAAI5B,0BACT,IAAIJ,sBAAsB;GACxByE,MAAM;IACJG,KAAK,wBAAwB5C,SAAQ;IACrC6C,gBAAgB;KAAEC,MAAM;KAAY9C;IAAS;GAC/C;GACAL,gBAAgB;IACd,OAAOuB,uBAAuB,KAAKiB,OAAOnC,QAAQ;GACpD;GACAJ,YAAYC,aAAa,KAAKsC,MAAMvC,UAAUC,QAAQ;EACxD,CAAC,GACD,KAAKsC,KACP;CACF;AACF"}
@@ -207,7 +207,7 @@ declare class ThreadRuntimeImpl implements ThreadRuntime {
207
207
  unstable_notifySessionReset: () => void;
208
208
  addToolResult: (options: AddToolResultOptions) => void;
209
209
  resumeToolCall: (options: ResumeToolCallOptions) => void;
210
- respondToToolApproval: (options: RespondToToolApprovalOptions) => void;
210
+ respondToToolApproval: (options: RespondToToolApprovalOptions) => Promise<void>;
211
211
  speak: (messageId: string) => void;
212
212
  stopSpeaking: () => void;
213
213
  connectVoice: () => void;
@@ -21,7 +21,7 @@ type BaseThreadAdapters = {
21
21
  };
22
22
  declare abstract class BaseThreadRuntimeCore extends BaseSubscribable implements ThreadRuntimeCore {
23
23
  private _isInitialized;
24
- protected readonly repository: MessageRepository;
24
+ protected repository: MessageRepository;
25
25
  abstract get adapters(): BaseThreadAdapters | undefined;
26
26
  abstract get isDisabled(): boolean;
27
27
  abstract get isSendDisabled(): boolean;
@@ -35,7 +35,7 @@ declare abstract class BaseThreadRuntimeCore extends BaseSubscribable implements
35
35
  abstract resumeRun(config: ResumeRunConfig): void;
36
36
  abstract addToolResult(options: AddToolResultOptions): void;
37
37
  abstract resumeToolCall(options: ResumeToolCallOptions): void;
38
- abstract respondToToolApproval(options: RespondToToolApprovalOptions): void;
38
+ abstract respondToToolApproval(options: RespondToToolApprovalOptions): Promise<void>;
39
39
  abstract cancelRun(): void;
40
40
  abstract exportExternalState(): any;
41
41
  abstract importExternalState(state: any): void;
@@ -1 +1 @@
1
- {"version":3,"file":"base-thread-runtime-core.d.ts","names":[],"sources":["../../../src/runtime/base/base-thread-runtime-core.ts"],"mappings":";;;;;;;;;;;;;;;KAwCK;EACH,SAAS;EACT,WAAW;EACX,cAAc;EACd,QAAQ;;uBAGY,8BACZ,4BACG;UAEH;qBAEW,YAAU;eACT,YAAY;eACZ;eACA;eACA;eACA,wBAAwB;eACxB;eAEA,gBAAgB;WACpB,OAAO,SAAS;WAChB,cAAc,2BAA2B;WACzC,SAAS,QAAQ;WACjB,UAAU,QAAQ;WAClB,cAAc,SAAS;WACvB,eAAe,SAAS;WACxB,sBACd,SAAS;WAEK;WACA;WACA,oBAAoB;WACpB;YAEN,gBAAgB;YAChB;UACF;UACA;UACA;YAEE;YAKA,6BAA6B;MAI5B,qBAAqB;MAgBrB,sEAAK,sDAAA;WAWA,UAAQ;mBAEP;EAEL,YAAA,kBAAkB;EAKvB,mBALuB;;;;;;;;;;;;;;YAsBpB,qBACR,SAAS,eACT,2BACC;UAmBK;EACD,gBAAgB,oBAAiB;EAGjC,UAAU;EAeV,eAAe;;;;;EAsBf,YAAY;EAOZ,eAAe;EAKf,wBAAwB,UAAU,wBACvC,OAAO,GACP,SAAS,0BAA0B;EAQ9B,iBAAiB,WAAW,QAAQ;UAqBnC;EACD,QAAQ;EAER,MAAM;EA8BN;UAMC;UACA;EACD,OAAO;UAEN;UACA;EAED;EAEA,uBAAwB,yBAAuB;EAK/C;UAmEC;UAEA;UA8DA;EAaD;EAmBA;EAUA;YAUG;EAOH,UAAM;EAIN,OAAO,MAAM;EAOb,MAAM,2BAA2B;UAIhC;EAKD,YAAY,UAAU,wBAC3B,OAAO,GACP,UAAU,2BAA2B,KAAE"}
1
+ {"version":3,"file":"base-thread-runtime-core.d.ts","names":[],"sources":["../../../src/runtime/base/base-thread-runtime-core.ts"],"mappings":";;;;;;;;;;;;;;;KAwCK;EACH,SAAS;EACT,WAAW;EACX,cAAc;EACd,QAAQ;;uBAGY,8BACZ,4BACG;UAEH;YAEE,YAAU;eACA,YAAY;eACZ;eACA;eACA;eACA,wBAAwB;eACxB;eAEA,gBAAgB;WACpB,OAAO,SAAS;WAChB,cAAc,2BAA2B;WACzC,SAAS,QAAQ;WACjB,UAAU,QAAQ;WAClB,cAAc,SAAS;WACvB,eAAe,SAAS;WACxB,sBACd,SAAS,+BACR;WACa;WACA;WACA,oBAAoB;WACpB;YAEN,gBAAgB;YAChB;UACF;UACA;UACA;YAEE;YAKA,6BAA6B;MAI5B,qBAAqB;MAgBrB,sEAAK,sDAAA;WAWA,UAAQ;mBAEP;EAEL,YAAA,kBAAkB;EAKvB,mBALuB;;;;;;;;;;;;;;YAsBpB,qBACR,SAAS,eACT,2BACC;UAmBK;EACD,gBAAgB,oBAAiB;EAGjC,UAAU;EAeV,eAAe;;;;;EAsBf,YAAY;EAOZ,eAAe;EAKf,wBAAwB,UAAU,wBACvC,OAAO,GACP,SAAS,0BAA0B;EAQ9B,iBAAiB,WAAW,QAAQ;UAqBnC;EACD,QAAQ;EAER,MAAM;EA8BN;UAMC;UACA;EACD,OAAO;UAEN;UACA;EAED;EAEA,uBAAwB,yBAAuB;EAK/C;UAmEC;UAEA;UA8DA;EAaD;EAmBA;EAUA;YAUG;EAOH,UAAM;EAIN,OAAO,MAAM;EAOb,MAAM,2BAA2B;UAIhC;EAKD,YAAY,UAAU,wBAC3B,OAAO,GACP,UAAU,2BAA2B,KAAE"}
@@ -358,7 +358,7 @@ var BaseThreadRuntimeCore = class extends BaseSubscribable {
358
358
  _eventSubscribers = /* @__PURE__ */ new Map();
359
359
  unstable_on(event, callback) {
360
360
  const wrapped = callback;
361
- if (event === "modelContextUpdate") return this._contextProvider.subscribe?.(() => wrapped({})) ?? (() => {});
361
+ if (event === "modelContextUpdate") return this._contextProvider.subscribe?.(() => notifyEventListeners([wrapped], {}, `Thread runtime "${event}"`)) ?? (() => {});
362
362
  let subscribers = this._eventSubscribers.get(event);
363
363
  if (!subscribers) {
364
364
  subscribers = /* @__PURE__ */ new Set();
@@ -366,7 +366,7 @@ var BaseThreadRuntimeCore = class extends BaseSubscribable {
366
366
  }
367
367
  subscribers.add(wrapped);
368
368
  if (event === "initialize" && this._isInitialized) queueMicrotask(() => {
369
- if (subscribers.has(wrapped)) wrapped({});
369
+ if (subscribers.has(wrapped)) notifyEventListeners([wrapped], {}, `Thread runtime "${event}"`);
370
370
  });
371
371
  return () => {
372
372
  this._eventSubscribers.get(event)?.delete(wrapped);
@@ -1 +1 @@
1
- {"version":3,"file":"base-thread-runtime-core.js","names":["AppendMessage","ThreadAssistantMessage","ThreadMessage","Unsubscribe","ModelContextProvider","getThreadMessageText","generateId","ExportedMessageRepository","MessageRepository","DefaultThreadComposerRuntimeCore","AddToolResultOptions","ResumeToolCallOptions","RespondToToolApprovalOptions","ThreadSuggestion","SubmitFeedbackOptions","ThreadRuntimeCore","SpeechState","VoiceSessionState","RuntimeCapabilities","ThreadRuntimeEventCallback","ThreadRuntimeEventPayload","ThreadRuntimeEventType","StartRunConfig","ResumeRunConfig","DefaultEditComposerRuntimeCore","SpeechSynthesisAdapter","FeedbackAdapter","AttachmentAdapter","RealtimeVoiceAdapter","ThreadMessageLike","notifyEventListeners","gateInteractableComposerMetadata","BaseSubscribable","BaseThreadAdapters","speech","feedback","attachments","voice","BaseThreadRuntimeCore","_isInitialized","repository","adapters","isDisabled","isSendDisabled","isLoading","suggestions","extras","capabilities","append","message","deleteMessage","messageId","Promise","startRun","config","resumeRun","addToolResult","options","resumeToolCall","respondToToolApproval","cancelRun","exportExternalState","importExternalState","state","unstable_notifySessionReset","_voiceMessages","_voiceGeneration","_cachedMergedMessages","_cachedVoiceGeneration","_cachedMergedBase","_markVoiceMessagesDirty","_getBaseMessages","getMessages","messages","length","base","mostRecentAssistantMessage","this","role","metadata","unstable_state","composer","_contextProvider","constructor","getModelContext","enrichAppendMetadata","anchorId","parentId","parentIndex","findIndex","m","id","composerMetadata","unstable_composerMetadata","slice","custom","_editComposers","Map","getEditComposer","get","beginEdit","has","Error","set","delete","getMessage","_notifySubscribers","getMessageById","baseMessages","voiceIdx","at","index","undefined","getBranches","some","switchToBranch","branchId","_notifyEventSubscribers","event","E","payload","subscribers","_eventSubscribers","submitFeedback","type","adapter","submit","updatedMessage","submittedFeedback","addOrUpdateMessage","_stopSpeaking","speak","utterance","unsub","subscribe","status","cancel","stopSpeaking","_voiceSession","Session","_voiceUnsubs","Array","_voiceVolume","_voiceVolumeSubscribers","Set","getVoiceVolume","subscribeVoiceVolume","callback","add","connectVoice","disconnectVoice","session","connect","unsubs","currentMode","Mode","isMuted","mode","push","onStatusChange","_finishVoiceAssistantMessage","onModeChange","onVolumeChange","volume","onTranscript","transcript","_handleVoiceTranscript","_currentAssistantMsg","TranscriptItem","ensureInitialized","isFinal","content","text","createdAt","Date","reason","unstable_annotations","unstable_data","steps","idx","indexOf","updated","last","disconnect","muteVoice","mute","unmuteVoice","unmute","export","import","data","clear","reset","initialMessages","fromArray","unstable_on","wrapped","queueMicrotask"],"sources":["../../../src/runtime/base/base-thread-runtime-core.ts"],"sourcesContent":["import type {\n AppendMessage,\n ThreadAssistantMessage,\n ThreadMessage,\n} from \"../../types/message\";\nimport type { Unsubscribe } from \"../../types/unsubscribe\";\nimport type { ModelContextProvider } from \"../../model-context/types\";\nimport { getThreadMessageText } from \"../../utils/text\";\nimport { generateId } from \"../../utils/id\";\nimport {\n ExportedMessageRepository,\n MessageRepository,\n} from \"../utils/message-repository\";\nimport { DefaultThreadComposerRuntimeCore } from \"./default-thread-composer-runtime-core\";\nimport type {\n AddToolResultOptions,\n ResumeToolCallOptions,\n RespondToToolApprovalOptions,\n ThreadSuggestion,\n SubmitFeedbackOptions,\n ThreadRuntimeCore,\n SpeechState,\n VoiceSessionState,\n RuntimeCapabilities,\n ThreadRuntimeEventCallback,\n ThreadRuntimeEventPayload,\n ThreadRuntimeEventType,\n StartRunConfig,\n ResumeRunConfig,\n} from \"../interfaces/thread-runtime-core\";\nimport { DefaultEditComposerRuntimeCore } from \"./default-edit-composer-runtime-core\";\nimport type { SpeechSynthesisAdapter } from \"../../adapters/speech\";\nimport type { FeedbackAdapter } from \"../../adapters/feedback\";\nimport type { AttachmentAdapter } from \"../../adapters/attachment\";\nimport type { RealtimeVoiceAdapter } from \"../../adapters/voice\";\nimport type { ThreadMessageLike } from \"../utils/thread-message-like\";\nimport { notifyEventListeners } from \"../../utils/notify-event-listeners\";\nimport { gateInteractableComposerMetadata } from \"../../model-context/interactable-composer-metadata\";\nimport { BaseSubscribable } from \"../../subscribable/subscribable\";\n\ntype BaseThreadAdapters = {\n speech?: SpeechSynthesisAdapter | undefined;\n feedback?: FeedbackAdapter | undefined;\n attachments?: AttachmentAdapter | undefined;\n voice?: RealtimeVoiceAdapter | undefined;\n};\n\nexport abstract class BaseThreadRuntimeCore\n extends BaseSubscribable\n implements ThreadRuntimeCore\n{\n private _isInitialized = false;\n\n protected readonly repository = new MessageRepository();\n public abstract get adapters(): BaseThreadAdapters | undefined;\n public abstract get isDisabled(): boolean;\n public abstract get isSendDisabled(): boolean;\n public abstract get isLoading(): boolean;\n public abstract get suggestions(): readonly ThreadSuggestion[];\n public abstract get extras(): unknown;\n\n public abstract get capabilities(): RuntimeCapabilities;\n public abstract append(message: AppendMessage): void;\n public abstract deleteMessage(messageId: string): void | Promise<void>;\n public abstract startRun(config: StartRunConfig): void;\n public abstract resumeRun(config: ResumeRunConfig): void;\n public abstract addToolResult(options: AddToolResultOptions): void;\n public abstract resumeToolCall(options: ResumeToolCallOptions): void;\n public abstract respondToToolApproval(\n options: RespondToToolApprovalOptions,\n ): void;\n public abstract cancelRun(): void;\n public abstract exportExternalState(): any;\n public abstract importExternalState(state: any): void;\n public abstract unstable_notifySessionReset(): void;\n\n protected _voiceMessages: ThreadMessage[] = [];\n protected _voiceGeneration = 0;\n private _cachedMergedMessages: readonly ThreadMessage[] | null = null;\n private _cachedVoiceGeneration = -1;\n private _cachedMergedBase: readonly ThreadMessage[] | null = null;\n\n protected _markVoiceMessagesDirty() {\n this._voiceGeneration++;\n this._cachedMergedMessages = null;\n }\n\n protected _getBaseMessages(): readonly ThreadMessage[] {\n return this.repository.getMessages();\n }\n\n public get messages(): readonly ThreadMessage[] {\n if (this._voiceMessages.length === 0) {\n return this._getBaseMessages();\n }\n const base = this._getBaseMessages();\n if (\n this._cachedVoiceGeneration !== this._voiceGeneration ||\n this._cachedMergedBase !== base\n ) {\n this._cachedMergedMessages = [...base, ...this._voiceMessages];\n this._cachedVoiceGeneration = this._voiceGeneration;\n this._cachedMergedBase = base;\n }\n return this._cachedMergedMessages!;\n }\n\n public get state() {\n let mostRecentAssistantMessage: (typeof this.messages)[number] | undefined;\n for (const message of this.messages) {\n if (message.role === \"assistant\") {\n mostRecentAssistantMessage = message;\n }\n }\n\n return mostRecentAssistantMessage?.metadata.unstable_state ?? null;\n }\n\n public readonly composer = new DefaultThreadComposerRuntimeCore(this);\n\n private readonly _contextProvider: ModelContextProvider;\n\n constructor(_contextProvider: ModelContextProvider) {\n super();\n this._contextProvider = _contextProvider;\n }\n\n public getModelContext() {\n return this._contextProvider.getModelContext();\n }\n\n /**\n * Stamps provider-contributed composer metadata onto an outgoing message.\n * Called at dispatch rather than in the composer, so programmatic sends are\n * covered too, and exactly once per message: a queued send is stamped when\n * it leaves the lane, never when it enters.\n *\n * Only user messages are stamped, matching the readers: both the version\n * fold and the model injection skip every other role.\n *\n * @param anchorId Message the gated branch prefix ends at. A queued send\n * passes the current tail, having waited through a run that grew the prefix\n * past the parent it was created with.\n */\n protected enrichAppendMetadata(\n message: AppendMessage,\n anchorId: string | null = message.parentId,\n ): AppendMessage {\n if (message.role !== \"user\") return message;\n const messages = this.messages;\n const parentIndex =\n anchorId === null ? -1 : messages.findIndex((m) => m.id === anchorId);\n const composerMetadata = gateInteractableComposerMetadata(\n this.getModelContext().unstable_composerMetadata,\n messages.slice(0, parentIndex + 1),\n );\n if (!composerMetadata) return message;\n return {\n ...message,\n metadata: {\n ...message.metadata,\n custom: { ...message.metadata?.custom, ...composerMetadata },\n },\n };\n }\n\n private _editComposers = new Map<string, DefaultEditComposerRuntimeCore>();\n public getEditComposer(messageId: string) {\n return this._editComposers.get(messageId);\n }\n public beginEdit(messageId: string) {\n if (this._editComposers.has(messageId))\n throw new Error(\"Edit already in progress\");\n\n this._editComposers.set(\n messageId,\n new DefaultEditComposerRuntimeCore(\n this,\n () => this._editComposers.delete(messageId),\n this.repository.getMessage(messageId),\n ),\n );\n this._notifySubscribers();\n }\n\n public getMessageById(messageId: string) {\n try {\n return this.repository.getMessage(messageId);\n } catch {\n // Check voice messages\n const baseMessages = this.repository.getMessages();\n const voiceIdx = this._voiceMessages.findIndex((m) => m.id === messageId);\n if (voiceIdx !== -1) {\n const parentId =\n voiceIdx > 0\n ? this._voiceMessages[voiceIdx - 1]!.id\n : (baseMessages.at(-1)?.id ?? null);\n return {\n parentId,\n message: this._voiceMessages[voiceIdx]!,\n index: baseMessages.length + voiceIdx,\n };\n }\n return undefined;\n }\n }\n\n public getBranches(messageId: string): string[] {\n if (this._voiceMessages.some((m) => m.id === messageId)) {\n return [];\n }\n return this.repository.getBranches(messageId);\n }\n\n public switchToBranch(branchId: string): void {\n this.repository.switchToBranch(branchId);\n this._notifySubscribers();\n }\n\n public _notifyEventSubscribers<E extends ThreadRuntimeEventType>(\n event: E,\n payload: ThreadRuntimeEventPayload[E],\n ) {\n const subscribers = this._eventSubscribers.get(event);\n if (!subscribers) return;\n\n notifyEventListeners(subscribers, payload, `Thread runtime \"${event}\"`);\n }\n\n public submitFeedback({ messageId, type }: SubmitFeedbackOptions) {\n const adapter = this.adapters?.feedback;\n if (!adapter) throw new Error(\"Feedback adapter not configured\");\n\n const { message, parentId } = this.repository.getMessage(messageId);\n adapter.submit({ message, type });\n\n if (message.role === \"assistant\") {\n const updatedMessage: ThreadMessage = {\n ...message,\n metadata: {\n ...message.metadata,\n submittedFeedback: { type },\n },\n };\n this.repository.addOrUpdateMessage(parentId, updatedMessage);\n }\n\n this._notifySubscribers();\n }\n\n private _stopSpeaking: Unsubscribe | undefined;\n public speech: SpeechState | undefined;\n\n public speak(messageId: string) {\n const adapter = this.adapters?.speech;\n if (!adapter) throw new Error(\"Speech adapter not configured\");\n\n const { message } = this.repository.getMessage(messageId);\n\n this._stopSpeaking?.();\n\n const utterance = adapter.speak(getThreadMessageText(message));\n const unsub = utterance.subscribe(() => {\n if (utterance.status.type === \"ended\") {\n this._stopSpeaking = undefined;\n this.speech = undefined;\n } else {\n this.speech = { messageId, status: utterance.status };\n }\n this._notifySubscribers();\n });\n\n this.speech = { messageId, status: utterance.status };\n this._notifySubscribers();\n\n this._stopSpeaking = () => {\n utterance.cancel();\n unsub();\n this.speech = undefined;\n this._stopSpeaking = undefined;\n };\n }\n\n public stopSpeaking() {\n if (!this._stopSpeaking) throw new Error(\"No message is being spoken\");\n this._stopSpeaking();\n this._notifySubscribers();\n }\n\n private _voiceSession: RealtimeVoiceAdapter.Session | undefined;\n private _voiceUnsubs: Array<() => void> = [];\n public voice: VoiceSessionState | undefined;\n\n private _voiceVolume = 0;\n private _voiceVolumeSubscribers = new Set<() => void>();\n\n public getVoiceVolume = () => this._voiceVolume;\n\n public subscribeVoiceVolume = (callback: () => void): Unsubscribe => {\n this._voiceVolumeSubscribers.add(callback);\n return () => this._voiceVolumeSubscribers.delete(callback);\n };\n\n public connectVoice() {\n const adapter = this.adapters?.voice;\n if (!adapter) throw new Error(\"Voice adapter not configured\");\n\n this.disconnectVoice();\n\n const session = adapter.connect({});\n this._voiceSession = session;\n const unsubs: Array<() => void> = [];\n\n let currentMode: RealtimeVoiceAdapter.Mode = \"listening\";\n\n this.voice = {\n status: session.status,\n isMuted: session.isMuted,\n mode: currentMode,\n };\n this._voiceVolume = 0;\n this._notifySubscribers();\n\n unsubs.push(\n session.onStatusChange((status) => {\n if (status.type === \"ended\") {\n this._finishVoiceAssistantMessage();\n this._voiceSession = undefined;\n this.voice = undefined;\n } else {\n this.voice = {\n status,\n isMuted: session.isMuted,\n mode: currentMode,\n };\n }\n this._notifySubscribers();\n }),\n );\n\n unsubs.push(\n session.onModeChange((mode) => {\n currentMode = mode;\n if (this.voice) {\n this.voice = { ...this.voice, mode };\n this._notifySubscribers();\n }\n }),\n );\n\n unsubs.push(\n session.onVolumeChange((volume) => {\n this._voiceVolume = volume;\n notifyEventListeners(\n this._voiceVolumeSubscribers,\n undefined,\n \"Voice volume\",\n );\n }),\n );\n\n unsubs.push(\n session.onTranscript((transcript) => {\n this._handleVoiceTranscript(transcript);\n }),\n );\n\n this._voiceUnsubs = unsubs;\n }\n\n private _currentAssistantMsg: ThreadAssistantMessage | null = null;\n\n private _handleVoiceTranscript(\n transcript: RealtimeVoiceAdapter.TranscriptItem,\n ) {\n this.ensureInitialized();\n\n if (transcript.role === \"user\") {\n this._finishVoiceAssistantMessage();\n this._currentAssistantMsg = null;\n\n if (transcript.isFinal) {\n this._voiceMessages.push({\n id: generateId(),\n role: \"user\",\n content: [{ type: \"text\", text: transcript.text }],\n metadata: { custom: {} },\n createdAt: new Date(),\n status: { type: \"complete\", reason: \"unknown\" },\n attachments: [],\n });\n this._markVoiceMessagesDirty();\n this._notifySubscribers();\n }\n } else {\n if (!this._currentAssistantMsg) {\n this._currentAssistantMsg = {\n id: generateId(),\n role: \"assistant\",\n content: [{ type: \"text\", text: transcript.text }],\n metadata: {\n unstable_state: this.state,\n unstable_annotations: [],\n unstable_data: [],\n steps: [],\n custom: {},\n },\n status: { type: \"running\" },\n createdAt: new Date(),\n };\n this._voiceMessages.push(this._currentAssistantMsg);\n } else {\n const idx = this._voiceMessages.indexOf(this._currentAssistantMsg);\n if (idx === -1) return;\n const updated: ThreadAssistantMessage = {\n ...this._currentAssistantMsg,\n content: [{ type: \"text\", text: transcript.text }],\n ...(transcript.isFinal\n ? { status: { type: \"complete\", reason: \"stop\" } }\n : {}),\n };\n this._voiceMessages[idx] = updated;\n this._currentAssistantMsg = updated;\n }\n\n if (transcript.isFinal) {\n this._currentAssistantMsg = null;\n }\n\n this._markVoiceMessagesDirty();\n this._notifySubscribers();\n }\n }\n\n private _finishVoiceAssistantMessage() {\n const last = this._voiceMessages.at(-1);\n if (last?.role === \"assistant\" && last.status.type === \"running\") {\n const idx = this._voiceMessages.length - 1;\n this._voiceMessages[idx] = {\n ...(last as ThreadAssistantMessage),\n status: { type: \"complete\", reason: \"stop\" },\n };\n this._markVoiceMessagesDirty();\n this._notifySubscribers();\n }\n }\n\n public disconnectVoice() {\n this._finishVoiceAssistantMessage();\n this._currentAssistantMsg = null;\n for (const unsub of this._voiceUnsubs) unsub();\n this._voiceUnsubs = [];\n this._voiceSession?.disconnect();\n this._voiceSession = undefined;\n this.voice = undefined;\n this._voiceVolume = 0;\n notifyEventListeners(\n this._voiceVolumeSubscribers,\n undefined,\n \"Voice volume\",\n );\n this._voiceMessages = [];\n this._markVoiceMessagesDirty();\n this._notifySubscribers();\n }\n\n public muteVoice() {\n if (!this._voiceSession) throw new Error(\"No active voice session\");\n this._voiceSession.mute();\n this.voice = {\n ...this.voice!,\n isMuted: true,\n };\n this._notifySubscribers();\n }\n\n public unmuteVoice() {\n if (!this._voiceSession) throw new Error(\"No active voice session\");\n this._voiceSession.unmute();\n this.voice = {\n ...this.voice!,\n isMuted: false,\n };\n this._notifySubscribers();\n }\n\n protected ensureInitialized() {\n if (!this._isInitialized) {\n this._isInitialized = true;\n this._notifyEventSubscribers(\"initialize\", {});\n }\n }\n\n public export() {\n return this.repository.export();\n }\n\n public import(data: ExportedMessageRepository) {\n this.ensureInitialized();\n this.repository.clear();\n this.repository.import(data);\n this._notifySubscribers();\n }\n\n public reset(initialMessages?: readonly ThreadMessageLike[]) {\n this.import(ExportedMessageRepository.fromArray(initialMessages ?? []));\n }\n\n private _eventSubscribers = new Map<\n ThreadRuntimeEventType,\n Set<(payload?: unknown) => void>\n >();\n\n public unstable_on<E extends ThreadRuntimeEventType>(\n event: E,\n callback: ThreadRuntimeEventCallback<E>,\n ) {\n const wrapped = callback as (payload?: unknown) => void;\n if (event === \"modelContextUpdate\") {\n // provider.subscribe is `() => void`; pump the typed empty payload to the user callback.\n return this._contextProvider.subscribe?.(() => wrapped({})) ?? (() => {});\n }\n\n let subscribers = this._eventSubscribers.get(event);\n if (!subscribers) {\n subscribers = new Set();\n this._eventSubscribers.set(event, subscribers);\n }\n subscribers.add(wrapped);\n\n // `initialize` latches: replay it (deferred) to subscribers that attach\n // after the thread already initialized, mirroring a BehaviorSubject.\n if (event === \"initialize\" && this._isInitialized) {\n queueMicrotask(() => {\n if (subscribers.has(wrapped)) wrapped({});\n });\n }\n\n return () => {\n this._eventSubscribers.get(event)?.delete(wrapped);\n };\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"base-thread-runtime-core.js","names":["AppendMessage","ThreadAssistantMessage","ThreadMessage","Unsubscribe","ModelContextProvider","getThreadMessageText","generateId","ExportedMessageRepository","MessageRepository","DefaultThreadComposerRuntimeCore","AddToolResultOptions","ResumeToolCallOptions","RespondToToolApprovalOptions","ThreadSuggestion","SubmitFeedbackOptions","ThreadRuntimeCore","SpeechState","VoiceSessionState","RuntimeCapabilities","ThreadRuntimeEventCallback","ThreadRuntimeEventPayload","ThreadRuntimeEventType","StartRunConfig","ResumeRunConfig","DefaultEditComposerRuntimeCore","SpeechSynthesisAdapter","FeedbackAdapter","AttachmentAdapter","RealtimeVoiceAdapter","ThreadMessageLike","notifyEventListeners","gateInteractableComposerMetadata","BaseSubscribable","BaseThreadAdapters","speech","feedback","attachments","voice","BaseThreadRuntimeCore","_isInitialized","repository","adapters","isDisabled","isSendDisabled","isLoading","suggestions","extras","capabilities","append","message","deleteMessage","messageId","Promise","startRun","config","resumeRun","addToolResult","options","resumeToolCall","respondToToolApproval","cancelRun","exportExternalState","importExternalState","state","unstable_notifySessionReset","_voiceMessages","_voiceGeneration","_cachedMergedMessages","_cachedVoiceGeneration","_cachedMergedBase","_markVoiceMessagesDirty","_getBaseMessages","getMessages","messages","length","base","mostRecentAssistantMessage","this","role","metadata","unstable_state","composer","_contextProvider","constructor","getModelContext","enrichAppendMetadata","anchorId","parentId","parentIndex","findIndex","m","id","composerMetadata","unstable_composerMetadata","slice","custom","_editComposers","Map","getEditComposer","get","beginEdit","has","Error","set","delete","getMessage","_notifySubscribers","getMessageById","baseMessages","voiceIdx","at","index","undefined","getBranches","some","switchToBranch","branchId","_notifyEventSubscribers","event","E","payload","subscribers","_eventSubscribers","submitFeedback","type","adapter","submit","updatedMessage","submittedFeedback","addOrUpdateMessage","_stopSpeaking","speak","utterance","unsub","subscribe","status","cancel","stopSpeaking","_voiceSession","Session","_voiceUnsubs","Array","_voiceVolume","_voiceVolumeSubscribers","Set","getVoiceVolume","subscribeVoiceVolume","callback","add","connectVoice","disconnectVoice","session","connect","unsubs","currentMode","Mode","isMuted","mode","push","onStatusChange","_finishVoiceAssistantMessage","onModeChange","onVolumeChange","volume","onTranscript","transcript","_handleVoiceTranscript","_currentAssistantMsg","TranscriptItem","ensureInitialized","isFinal","content","text","createdAt","Date","reason","unstable_annotations","unstable_data","steps","idx","indexOf","updated","last","disconnect","muteVoice","mute","unmuteVoice","unmute","export","import","data","clear","reset","initialMessages","fromArray","unstable_on","wrapped","queueMicrotask"],"sources":["../../../src/runtime/base/base-thread-runtime-core.ts"],"sourcesContent":["import type {\n AppendMessage,\n ThreadAssistantMessage,\n ThreadMessage,\n} from \"../../types/message\";\nimport type { Unsubscribe } from \"../../types/unsubscribe\";\nimport type { ModelContextProvider } from \"../../model-context/types\";\nimport { getThreadMessageText } from \"../../utils/text\";\nimport { generateId } from \"../../utils/id\";\nimport {\n ExportedMessageRepository,\n MessageRepository,\n} from \"../utils/message-repository\";\nimport { DefaultThreadComposerRuntimeCore } from \"./default-thread-composer-runtime-core\";\nimport type {\n AddToolResultOptions,\n ResumeToolCallOptions,\n RespondToToolApprovalOptions,\n ThreadSuggestion,\n SubmitFeedbackOptions,\n ThreadRuntimeCore,\n SpeechState,\n VoiceSessionState,\n RuntimeCapabilities,\n ThreadRuntimeEventCallback,\n ThreadRuntimeEventPayload,\n ThreadRuntimeEventType,\n StartRunConfig,\n ResumeRunConfig,\n} from \"../interfaces/thread-runtime-core\";\nimport { DefaultEditComposerRuntimeCore } from \"./default-edit-composer-runtime-core\";\nimport type { SpeechSynthesisAdapter } from \"../../adapters/speech\";\nimport type { FeedbackAdapter } from \"../../adapters/feedback\";\nimport type { AttachmentAdapter } from \"../../adapters/attachment\";\nimport type { RealtimeVoiceAdapter } from \"../../adapters/voice\";\nimport type { ThreadMessageLike } from \"../utils/thread-message-like\";\nimport { notifyEventListeners } from \"../../utils/notify-event-listeners\";\nimport { gateInteractableComposerMetadata } from \"../../model-context/interactable-composer-metadata\";\nimport { BaseSubscribable } from \"../../subscribable/subscribable\";\n\ntype BaseThreadAdapters = {\n speech?: SpeechSynthesisAdapter | undefined;\n feedback?: FeedbackAdapter | undefined;\n attachments?: AttachmentAdapter | undefined;\n voice?: RealtimeVoiceAdapter | undefined;\n};\n\nexport abstract class BaseThreadRuntimeCore\n extends BaseSubscribable\n implements ThreadRuntimeCore\n{\n private _isInitialized = false;\n\n protected repository = new MessageRepository();\n public abstract get adapters(): BaseThreadAdapters | undefined;\n public abstract get isDisabled(): boolean;\n public abstract get isSendDisabled(): boolean;\n public abstract get isLoading(): boolean;\n public abstract get suggestions(): readonly ThreadSuggestion[];\n public abstract get extras(): unknown;\n\n public abstract get capabilities(): RuntimeCapabilities;\n public abstract append(message: AppendMessage): void;\n public abstract deleteMessage(messageId: string): void | Promise<void>;\n public abstract startRun(config: StartRunConfig): void;\n public abstract resumeRun(config: ResumeRunConfig): void;\n public abstract addToolResult(options: AddToolResultOptions): void;\n public abstract resumeToolCall(options: ResumeToolCallOptions): void;\n public abstract respondToToolApproval(\n options: RespondToToolApprovalOptions,\n ): Promise<void>;\n public abstract cancelRun(): void;\n public abstract exportExternalState(): any;\n public abstract importExternalState(state: any): void;\n public abstract unstable_notifySessionReset(): void;\n\n protected _voiceMessages: ThreadMessage[] = [];\n protected _voiceGeneration = 0;\n private _cachedMergedMessages: readonly ThreadMessage[] | null = null;\n private _cachedVoiceGeneration = -1;\n private _cachedMergedBase: readonly ThreadMessage[] | null = null;\n\n protected _markVoiceMessagesDirty() {\n this._voiceGeneration++;\n this._cachedMergedMessages = null;\n }\n\n protected _getBaseMessages(): readonly ThreadMessage[] {\n return this.repository.getMessages();\n }\n\n public get messages(): readonly ThreadMessage[] {\n if (this._voiceMessages.length === 0) {\n return this._getBaseMessages();\n }\n const base = this._getBaseMessages();\n if (\n this._cachedVoiceGeneration !== this._voiceGeneration ||\n this._cachedMergedBase !== base\n ) {\n this._cachedMergedMessages = [...base, ...this._voiceMessages];\n this._cachedVoiceGeneration = this._voiceGeneration;\n this._cachedMergedBase = base;\n }\n return this._cachedMergedMessages!;\n }\n\n public get state() {\n let mostRecentAssistantMessage: (typeof this.messages)[number] | undefined;\n for (const message of this.messages) {\n if (message.role === \"assistant\") {\n mostRecentAssistantMessage = message;\n }\n }\n\n return mostRecentAssistantMessage?.metadata.unstable_state ?? null;\n }\n\n public readonly composer = new DefaultThreadComposerRuntimeCore(this);\n\n private readonly _contextProvider: ModelContextProvider;\n\n constructor(_contextProvider: ModelContextProvider) {\n super();\n this._contextProvider = _contextProvider;\n }\n\n public getModelContext() {\n return this._contextProvider.getModelContext();\n }\n\n /**\n * Stamps provider-contributed composer metadata onto an outgoing message.\n * Called at dispatch rather than in the composer, so programmatic sends are\n * covered too, and exactly once per message: a queued send is stamped when\n * it leaves the lane, never when it enters.\n *\n * Only user messages are stamped, matching the readers: both the version\n * fold and the model injection skip every other role.\n *\n * @param anchorId Message the gated branch prefix ends at. A queued send\n * passes the current tail, having waited through a run that grew the prefix\n * past the parent it was created with.\n */\n protected enrichAppendMetadata(\n message: AppendMessage,\n anchorId: string | null = message.parentId,\n ): AppendMessage {\n if (message.role !== \"user\") return message;\n const messages = this.messages;\n const parentIndex =\n anchorId === null ? -1 : messages.findIndex((m) => m.id === anchorId);\n const composerMetadata = gateInteractableComposerMetadata(\n this.getModelContext().unstable_composerMetadata,\n messages.slice(0, parentIndex + 1),\n );\n if (!composerMetadata) return message;\n return {\n ...message,\n metadata: {\n ...message.metadata,\n custom: { ...message.metadata?.custom, ...composerMetadata },\n },\n };\n }\n\n private _editComposers = new Map<string, DefaultEditComposerRuntimeCore>();\n public getEditComposer(messageId: string) {\n return this._editComposers.get(messageId);\n }\n public beginEdit(messageId: string) {\n if (this._editComposers.has(messageId))\n throw new Error(\"Edit already in progress\");\n\n this._editComposers.set(\n messageId,\n new DefaultEditComposerRuntimeCore(\n this,\n () => this._editComposers.delete(messageId),\n this.repository.getMessage(messageId),\n ),\n );\n this._notifySubscribers();\n }\n\n public getMessageById(messageId: string) {\n try {\n return this.repository.getMessage(messageId);\n } catch {\n // Check voice messages\n const baseMessages = this.repository.getMessages();\n const voiceIdx = this._voiceMessages.findIndex((m) => m.id === messageId);\n if (voiceIdx !== -1) {\n const parentId =\n voiceIdx > 0\n ? this._voiceMessages[voiceIdx - 1]!.id\n : (baseMessages.at(-1)?.id ?? null);\n return {\n parentId,\n message: this._voiceMessages[voiceIdx]!,\n index: baseMessages.length + voiceIdx,\n };\n }\n return undefined;\n }\n }\n\n public getBranches(messageId: string): string[] {\n if (this._voiceMessages.some((m) => m.id === messageId)) {\n return [];\n }\n return this.repository.getBranches(messageId);\n }\n\n public switchToBranch(branchId: string): void {\n this.repository.switchToBranch(branchId);\n this._notifySubscribers();\n }\n\n public _notifyEventSubscribers<E extends ThreadRuntimeEventType>(\n event: E,\n payload: ThreadRuntimeEventPayload[E],\n ) {\n const subscribers = this._eventSubscribers.get(event);\n if (!subscribers) return;\n\n notifyEventListeners(subscribers, payload, `Thread runtime \"${event}\"`);\n }\n\n public submitFeedback({ messageId, type }: SubmitFeedbackOptions) {\n const adapter = this.adapters?.feedback;\n if (!adapter) throw new Error(\"Feedback adapter not configured\");\n\n const { message, parentId } = this.repository.getMessage(messageId);\n adapter.submit({ message, type });\n\n if (message.role === \"assistant\") {\n const updatedMessage: ThreadMessage = {\n ...message,\n metadata: {\n ...message.metadata,\n submittedFeedback: { type },\n },\n };\n this.repository.addOrUpdateMessage(parentId, updatedMessage);\n }\n\n this._notifySubscribers();\n }\n\n private _stopSpeaking: Unsubscribe | undefined;\n public speech: SpeechState | undefined;\n\n public speak(messageId: string) {\n const adapter = this.adapters?.speech;\n if (!adapter) throw new Error(\"Speech adapter not configured\");\n\n const { message } = this.repository.getMessage(messageId);\n\n this._stopSpeaking?.();\n\n const utterance = adapter.speak(getThreadMessageText(message));\n const unsub = utterance.subscribe(() => {\n if (utterance.status.type === \"ended\") {\n this._stopSpeaking = undefined;\n this.speech = undefined;\n } else {\n this.speech = { messageId, status: utterance.status };\n }\n this._notifySubscribers();\n });\n\n this.speech = { messageId, status: utterance.status };\n this._notifySubscribers();\n\n this._stopSpeaking = () => {\n utterance.cancel();\n unsub();\n this.speech = undefined;\n this._stopSpeaking = undefined;\n };\n }\n\n public stopSpeaking() {\n if (!this._stopSpeaking) throw new Error(\"No message is being spoken\");\n this._stopSpeaking();\n this._notifySubscribers();\n }\n\n private _voiceSession: RealtimeVoiceAdapter.Session | undefined;\n private _voiceUnsubs: Array<() => void> = [];\n public voice: VoiceSessionState | undefined;\n\n private _voiceVolume = 0;\n private _voiceVolumeSubscribers = new Set<() => void>();\n\n public getVoiceVolume = () => this._voiceVolume;\n\n public subscribeVoiceVolume = (callback: () => void): Unsubscribe => {\n this._voiceVolumeSubscribers.add(callback);\n return () => this._voiceVolumeSubscribers.delete(callback);\n };\n\n public connectVoice() {\n const adapter = this.adapters?.voice;\n if (!adapter) throw new Error(\"Voice adapter not configured\");\n\n this.disconnectVoice();\n\n const session = adapter.connect({});\n this._voiceSession = session;\n const unsubs: Array<() => void> = [];\n\n let currentMode: RealtimeVoiceAdapter.Mode = \"listening\";\n\n this.voice = {\n status: session.status,\n isMuted: session.isMuted,\n mode: currentMode,\n };\n this._voiceVolume = 0;\n this._notifySubscribers();\n\n unsubs.push(\n session.onStatusChange((status) => {\n if (status.type === \"ended\") {\n this._finishVoiceAssistantMessage();\n this._voiceSession = undefined;\n this.voice = undefined;\n } else {\n this.voice = {\n status,\n isMuted: session.isMuted,\n mode: currentMode,\n };\n }\n this._notifySubscribers();\n }),\n );\n\n unsubs.push(\n session.onModeChange((mode) => {\n currentMode = mode;\n if (this.voice) {\n this.voice = { ...this.voice, mode };\n this._notifySubscribers();\n }\n }),\n );\n\n unsubs.push(\n session.onVolumeChange((volume) => {\n this._voiceVolume = volume;\n notifyEventListeners(\n this._voiceVolumeSubscribers,\n undefined,\n \"Voice volume\",\n );\n }),\n );\n\n unsubs.push(\n session.onTranscript((transcript) => {\n this._handleVoiceTranscript(transcript);\n }),\n );\n\n this._voiceUnsubs = unsubs;\n }\n\n private _currentAssistantMsg: ThreadAssistantMessage | null = null;\n\n private _handleVoiceTranscript(\n transcript: RealtimeVoiceAdapter.TranscriptItem,\n ) {\n this.ensureInitialized();\n\n if (transcript.role === \"user\") {\n this._finishVoiceAssistantMessage();\n this._currentAssistantMsg = null;\n\n if (transcript.isFinal) {\n this._voiceMessages.push({\n id: generateId(),\n role: \"user\",\n content: [{ type: \"text\", text: transcript.text }],\n metadata: { custom: {} },\n createdAt: new Date(),\n status: { type: \"complete\", reason: \"unknown\" },\n attachments: [],\n });\n this._markVoiceMessagesDirty();\n this._notifySubscribers();\n }\n } else {\n if (!this._currentAssistantMsg) {\n this._currentAssistantMsg = {\n id: generateId(),\n role: \"assistant\",\n content: [{ type: \"text\", text: transcript.text }],\n metadata: {\n unstable_state: this.state,\n unstable_annotations: [],\n unstable_data: [],\n steps: [],\n custom: {},\n },\n status: { type: \"running\" },\n createdAt: new Date(),\n };\n this._voiceMessages.push(this._currentAssistantMsg);\n } else {\n const idx = this._voiceMessages.indexOf(this._currentAssistantMsg);\n if (idx === -1) return;\n const updated: ThreadAssistantMessage = {\n ...this._currentAssistantMsg,\n content: [{ type: \"text\", text: transcript.text }],\n ...(transcript.isFinal\n ? { status: { type: \"complete\", reason: \"stop\" } }\n : {}),\n };\n this._voiceMessages[idx] = updated;\n this._currentAssistantMsg = updated;\n }\n\n if (transcript.isFinal) {\n this._currentAssistantMsg = null;\n }\n\n this._markVoiceMessagesDirty();\n this._notifySubscribers();\n }\n }\n\n private _finishVoiceAssistantMessage() {\n const last = this._voiceMessages.at(-1);\n if (last?.role === \"assistant\" && last.status.type === \"running\") {\n const idx = this._voiceMessages.length - 1;\n this._voiceMessages[idx] = {\n ...(last as ThreadAssistantMessage),\n status: { type: \"complete\", reason: \"stop\" },\n };\n this._markVoiceMessagesDirty();\n this._notifySubscribers();\n }\n }\n\n public disconnectVoice() {\n this._finishVoiceAssistantMessage();\n this._currentAssistantMsg = null;\n for (const unsub of this._voiceUnsubs) unsub();\n this._voiceUnsubs = [];\n this._voiceSession?.disconnect();\n this._voiceSession = undefined;\n this.voice = undefined;\n this._voiceVolume = 0;\n notifyEventListeners(\n this._voiceVolumeSubscribers,\n undefined,\n \"Voice volume\",\n );\n this._voiceMessages = [];\n this._markVoiceMessagesDirty();\n this._notifySubscribers();\n }\n\n public muteVoice() {\n if (!this._voiceSession) throw new Error(\"No active voice session\");\n this._voiceSession.mute();\n this.voice = {\n ...this.voice!,\n isMuted: true,\n };\n this._notifySubscribers();\n }\n\n public unmuteVoice() {\n if (!this._voiceSession) throw new Error(\"No active voice session\");\n this._voiceSession.unmute();\n this.voice = {\n ...this.voice!,\n isMuted: false,\n };\n this._notifySubscribers();\n }\n\n protected ensureInitialized() {\n if (!this._isInitialized) {\n this._isInitialized = true;\n this._notifyEventSubscribers(\"initialize\", {});\n }\n }\n\n public export() {\n return this.repository.export();\n }\n\n public import(data: ExportedMessageRepository) {\n this.ensureInitialized();\n this.repository.clear();\n this.repository.import(data);\n this._notifySubscribers();\n }\n\n public reset(initialMessages?: readonly ThreadMessageLike[]) {\n this.import(ExportedMessageRepository.fromArray(initialMessages ?? []));\n }\n\n private _eventSubscribers = new Map<\n ThreadRuntimeEventType,\n Set<(payload?: unknown) => void>\n >();\n\n public unstable_on<E extends ThreadRuntimeEventType>(\n event: E,\n callback: ThreadRuntimeEventCallback<E>,\n ) {\n const wrapped = callback as (payload?: unknown) => void;\n if (event === \"modelContextUpdate\") {\n // provider.subscribe is `() => void`; pump the typed empty payload to the user callback.\n return (\n this._contextProvider.subscribe?.(() =>\n notifyEventListeners([wrapped], {}, `Thread runtime \"${event}\"`),\n ) ?? (() => {})\n );\n }\n\n let subscribers = this._eventSubscribers.get(event);\n if (!subscribers) {\n subscribers = new Set();\n this._eventSubscribers.set(event, subscribers);\n }\n subscribers.add(wrapped);\n\n // `initialize` latches: replay it (deferred) to subscribers that attach\n // after the thread already initialized, mirroring a BehaviorSubject.\n if (event === \"initialize\" && this._isInitialized) {\n queueMicrotask(() => {\n if (subscribers.has(wrapped)) {\n notifyEventListeners([wrapped], {}, `Thread runtime \"${event}\"`);\n }\n });\n }\n\n return () => {\n this._eventSubscribers.get(event)?.delete(wrapped);\n };\n }\n}\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { Unsubscribe } from "../../types/unsubscribe.js";
2
- import { ThreadRuntimeCore } from "./thread-runtime-core.js";
2
+ import { ThreadRuntimeCore, ThreadRuntimeEventType } from "./thread-runtime-core.js";
3
3
  //#region src/runtime/interfaces/thread-list-runtime-core.d.ts
4
4
  type ThreadListItemStatus = "archived" | "regular" | "new" | "deleted";
5
5
  type ThreadListItemCoreState = {
@@ -12,6 +12,10 @@ type ThreadListItemCoreState = {
12
12
  readonly custom?: Record<string, unknown> | undefined;
13
13
  readonly runtime?: ThreadRuntimeCore | undefined;
14
14
  };
15
+ type ThreadListRuntimeEvent = {
16
+ readonly threadId: string;
17
+ readonly type: ThreadRuntimeEventType;
18
+ };
15
19
  type ThreadListRuntimeCore = {
16
20
  readonly isLoading: boolean;
17
21
  readonly isLoadingMore?: boolean;
@@ -32,6 +36,14 @@ type ThreadListRuntimeCore = {
32
36
  * running, and the main thread's run state is read from its runtime directly.
33
37
  */
34
38
  unstable_isThreadRunning?(threadId: string): boolean;
39
+ /**
40
+ * Lifecycle events from every thread this list keeps alive, including
41
+ * threads that are not the main one. Implemented by thread lists that keep
42
+ * runtimes alive for non-main threads. A thread list that mounts only the
43
+ * main thread leaves this undefined: its other threads have no runtime and so
44
+ * emit nothing, and the main thread's runtime is observed directly.
45
+ */
46
+ unstable_subscribeThreadEvents?(callback: (event: ThreadListRuntimeEvent) => void): Unsubscribe;
35
47
  getItemById(threadId: string): ThreadListItemCoreState | undefined;
36
48
  switchToThread(threadId: string, options?: {
37
49
  unarchive?: boolean;
@@ -55,5 +67,5 @@ type ThreadListRuntimeCore = {
55
67
  subscribe(callback: () => void): Unsubscribe;
56
68
  };
57
69
  //#endregion
58
- export { ThreadListItemCoreState, ThreadListItemStatus, ThreadListRuntimeCore };
70
+ export { ThreadListItemCoreState, ThreadListItemStatus, ThreadListRuntimeCore, ThreadListRuntimeEvent };
59
71
  //# sourceMappingURL=thread-list-runtime-core.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"thread-list-runtime-core.d.ts","names":[],"sources":["../../../src/runtime/interfaces/thread-list-runtime-core.ts"],"mappings":";;;KAGY;KAEA;WACD;WACA;WACA;WAEA,QAAQ;WACR;WACA,gBAAgB;WAChB,SAAS;WAET,UAAU;;KAGT;WACD;WACA;WACA;EACT;EACA;EAEA;EACA;WAES,aAAa,SAAS,eAAe;EAE9C,4BAA4B;EAC5B,qBAAqB,mBAAmB;;;;;;;;;EAUxC,0BAA0B;EAE1B,YAAY,mBAAmB;EAE/B,eACE,kBACA;IAAY;MACX;EACH,qBAAqB;EAErB,yBAAyB;EACzB,WAAW;EACX,qBAAqB;EACrB,aAAa;EAEb,OAAO,mBAAmB;EAC1B,OAAO,kBAAkB,mBAAmB;EAC5C,cACE,kBACA,QAAQ,sCACP;EACH,QAAQ,mBAAmB;EAC3B,UAAU,mBAAmB;EAC7B,OAAO,mBAAmB;EAE1B,WACE,mBACC;IAAU;IAAkB;;EAC/B,cAAc,mBAAmB;EAEjC,UAAU,uBAAuB"}
1
+ {"version":3,"file":"thread-list-runtime-core.d.ts","names":[],"sources":["../../../src/runtime/interfaces/thread-list-runtime-core.ts"],"mappings":";;;KAMY;KAEA;WACD;WACA;WACA;WAEA,QAAQ;WACR;WACA,gBAAgB;WAChB,SAAS;WAET,UAAU;;KAGT;WACD;WACA,MAAM;;KAGL;WACD;WACA;WACA;EACT;EACA;EAEA;EACA;WAES,aAAa,SAAS,eAAe;EAE9C,4BAA4B;EAC5B,qBAAqB,mBAAmB;;;;;;;;;EAUxC,0BAA0B;;;;;;;;EAS1B,gCACE,WAAW,OAAO,kCACjB;EAEH,YAAY,mBAAmB;EAE/B,eACE,kBACA;IAAY;MACX;EACH,qBAAqB;EAErB,yBAAyB;EACzB,WAAW;EACX,qBAAqB;EACrB,aAAa;EAEb,OAAO,mBAAmB;EAC1B,OAAO,kBAAkB,mBAAmB;EAC5C,cACE,kBACA,QAAQ,sCACP;EACH,QAAQ,mBAAmB;EAC3B,UAAU,mBAAmB;EAC7B,OAAO,mBAAmB;EAE1B,WACE,mBACC;IAAU;IAAkB;;EAC/B,cAAc,mBAAmB;EAEjC,UAAU,uBAAuB"}
@@ -53,6 +53,8 @@ type RespondToToolApprovalOptions = {
53
53
  approved: boolean;
54
54
  /** The approval option that produced this decision, when the request carried options. */
55
55
  optionId?: string;
56
+ /** The free-form answer, when the request asked for one. */
57
+ text?: string;
56
58
  reason?: string;
57
59
  };
58
60
  type SubmitFeedbackOptions = {
@@ -135,7 +137,19 @@ type ThreadRuntimeCore = Readonly<{
135
137
  unstable_notifySessionReset: () => void;
136
138
  addToolResult: (options: AddToolResultOptions) => void;
137
139
  resumeToolCall: (options: ResumeToolCallOptions) => void;
138
- respondToToolApproval: (options: RespondToToolApprovalOptions) => void;
140
+ /**
141
+ * Records a decision on a tool approval gate. Resolves once the runtime has
142
+ * accepted the response and rejects when it could not be recorded, so a
143
+ * caller can leave the gate retryable rather than spending it. A capability
144
+ * or state precondition still throws synchronously; a failure to record
145
+ * arrives as a rejection, including one an adapter raises synchronously.
146
+ *
147
+ * Acceptance is as far as the runtime can see the response: one that records
148
+ * the decision locally settles on the record, while one that answers by
149
+ * resuming a run settles on the resume. A failure of the work the decision
150
+ * unblocks is reported through the runtime's own error channel, not here.
151
+ */
152
+ respondToToolApproval: (options: RespondToToolApprovalOptions) => Promise<void>;
139
153
  speak: (messageId: string) => void;
140
154
  stopSpeaking: () => void;
141
155
  connectVoice: () => void;
@@ -1 +1 @@
1
- {"version":3,"file":"thread-runtime-core.d.ts","names":[],"sources":["../../../src/runtime/interfaces/thread-runtime-core.ts"],"mappings":";;;;;;;;;;;;;;KAqBY;WACD;WACA;WACA;WACA;;WAEA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;;KAGC;EACV;EACA;EACA;EACA,QAAQ;EACR;EACA,WAAW;;;;;;;EAOX,wBAAwB;;KAGd;EACV;EACA;;KAGU;EACV;EACA;;EAEA;EACA;;KAGU;EACV;EACA;;KAGU;;EAEV;;EAEA;;EAEA;;KAGU;WACD;WACA,QAAQ,uBAAuB;;KAG9B;WACD,QAAQ,qBAAqB;WAC7B;WACA,MAAM,qBAAqB;;KAG1B;WACD;;KAGC;;;;;;;EAOV,UAAU;;;;;;;EAOV,QAAQ;;;;;;;;;EASR,YAAY;;;;;EAKZ,oBAAoB;;KAGV,+BAA+B;KAE/B,2BAA2B,UAAU,2BAC/C,SAAS,0BAA0B;KAGzB;EACV;EACA;EACA,WAAW;;KAGD,kBAAkB;EAC5B,UACE,SAAS,wBACN,eAAe;;KAGV,oBAAoB;EAC9B,iBAAiB;IAEX;IACA,SAAS;IACT;;EAIN,cAAc;EACd,iBAAiB;EAEjB,SAAS,SAAS;EAClB,gBAAgB,6BAA6B;EAC7C,WAAW,QAAQ;EACnB,YAAY,QAAQ;EACpB;EACA;EAEA,gBAAgB,SAAS;EACzB,iBAAiB,SAAS;EAC1B,wBAAwB,SAAS;EAEjC,QAAQ;EACR;EAEA;EACA;EACA;EACA;EAEA,iBAAiB,UAAU;EAE3B,uBAAuB;EAEvB,UAAU;EACV,kBAAkB,sBAAsB;EACxC,YAAY;EAEZ,+BAA+B;EAC/B,oCAAoC;EACpC,iBAAiB,qBAAqB,WAAW;EACjD,mBAAmB;EAEnB,QAAQ;EACR,OAAO;EAEP,cAAc,SAAS;EACvB;;;;;;EAMA;EACA;;;;;;;EAOA;EACA,mBAAmB;EACnB,OAAO;EACP,sBAAsB;EAEtB;EAEA,YAAY,yBAAyB;EAErC;EACA,uBAAuB,yBAAyB;EAEhD,OAAO,YAAY;EACnB,UAAU;EAEV;EACA,oBAAoB;EAEpB,MAAM,2BAA2B;;;;;;;;;;;;EAajC,gCAAgC;;;;;;EAOhC,YAAY,UAAU,wBACpB,OAAO,GACP,UAAU,2BAA2B,KACpC"}
1
+ {"version":3,"file":"thread-runtime-core.d.ts","names":[],"sources":["../../../src/runtime/interfaces/thread-runtime-core.ts"],"mappings":";;;;;;;;;;;;;;KAqBY;WACD;WACA;WACA;WACA;;WAEA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;;KAGC;EACV;EACA;EACA;EACA,QAAQ;EACR;EACA,WAAW;;;;;;;EAOX,wBAAwB;;KAGd;EACV;EACA;;KAGU;EACV;EACA;;EAEA;;EAEA;EACA;;KAGU;EACV;EACA;;KAGU;;EAEV;;EAEA;;EAEA;;KAGU;WACD;WACA,QAAQ,uBAAuB;;KAG9B;WACD,QAAQ,qBAAqB;WAC7B;WACA,MAAM,qBAAqB;;KAG1B;WACD;;KAGC;;;;;;;EAOV,UAAU;;;;;;;EAOV,QAAQ;;;;;;;;;EASR,YAAY;;;;;EAKZ,oBAAoB;;KAGV,+BAA+B;KAE/B,2BAA2B,UAAU,2BAC/C,SAAS,0BAA0B;KAGzB;EACV;EACA;EACA,WAAW;;KAGD,kBAAkB;EAC5B,UACE,SAAS,wBACN,eAAe;;KAGV,oBAAoB;EAC9B,iBAAiB;IAEX;IACA,SAAS;IACT;;EAIN,cAAc;EACd,iBAAiB;EAEjB,SAAS,SAAS;EAClB,gBAAgB,6BAA6B;EAC7C,WAAW,QAAQ;EACnB,YAAY,QAAQ;EACpB;EACA;EAEA,gBAAgB,SAAS;EACzB,iBAAiB,SAAS;;;;;;;;;;;;;EAa1B,wBACE,SAAS,iCACN;EAEL,QAAQ;EACR;EAEA;EACA;EACA;EACA;EAEA,iBAAiB,UAAU;EAE3B,uBAAuB;EAEvB,UAAU;EACV,kBAAkB,sBAAsB;EACxC,YAAY;EAEZ,+BAA+B;EAC/B,oCAAoC;EACpC,iBAAiB,qBAAqB,WAAW;EACjD,mBAAmB;EAEnB,QAAQ;EACR,OAAO;EAEP,cAAc,SAAS;EACvB;;;;;;EAMA;EACA;;;;;;;EAOA;EACA,mBAAmB;EACnB,OAAO;EACP,sBAAsB;EAEtB;EAEA,YAAY,yBAAyB;EAErC;EACA,uBAAuB,yBAAyB;EAEhD,OAAO,YAAY;EACnB,UAAU;EAEV;EACA,oBAAoB;EAEpB,MAAM,2BAA2B;;;;;;;;;;;;EAajC,gCAAgC;;;;;;EAOhC,YAAY,UAAU,wBACpB,OAAO,GACP,UAAU,2BAA2B,KACpC"}
@@ -6,7 +6,7 @@ type ThreadMessageLikeContentItem = Exclude<ThreadMessageLike["content"], string
6
6
  declare const isPendingToolCall: (c: ThreadMessageLikeContentItem) => boolean;
7
7
  declare const isInterruptedToolCall: (c: ThreadMessageLikeContentItem) => boolean;
8
8
  declare const isAutoStatus: (status: MessageStatus) => boolean;
9
- declare const getAutoStatus: (isLast: boolean, isRunning: boolean, hasInterruptedToolCalls: boolean, hasPendingToolCalls: boolean, error?: ReadonlyJSONValue) => MessageStatus;
9
+ declare const getAutoStatus: (isLast: boolean, isRunning: boolean, hasInterruptedToolCalls: boolean, hasPendingToolCalls: boolean, error?: ReadonlyJSONValue, isCancelled?: boolean) => MessageStatus;
10
10
  declare const getContentAutoStatus: (content: ThreadMessageLike["content"], isLast: boolean, isRunning: boolean) => MessageStatus;
11
11
  //#endregion
12
12
  export { getAutoStatus, getContentAutoStatus, isAutoStatus, isInterruptedToolCall, isPendingToolCall };
@@ -1 +1 @@
1
- {"version":3,"file":"auto-status.d.ts","names":[],"sources":["../../../src/runtime/utils/auto-status.ts"],"mappings":";;;;KAIK,+BAA+B,QAClC;cAIW,oBAAqB,GAAG;cAGxB,wBACX,GAAG;cA8CQ,eAAgB,QAAQ;cAGxB,gBACX,iBACA,oBACA,kCACA,8BACA,QAAQ,sBACP;cAqBU,uBACX,SAAS,8BACT,iBACA,uBACC"}
1
+ {"version":3,"file":"auto-status.d.ts","names":[],"sources":["../../../src/runtime/utils/auto-status.ts"],"mappings":";;;;KAIK,+BAA+B,QAClC;cAIW,oBAAqB,GAAG;cAGxB,wBACX,GAAG;cAuDQ,eAAgB,QAAQ;cAGxB,gBACX,iBACA,oBACA,kCACA,8BACA,QAAQ,mBACR,0BACC;cAuBU,uBACX,SAAS,8BACT,iBACA,uBACC"}
@@ -10,6 +10,10 @@ const AUTO_STATUS_COMPLETE = Object.freeze(Object.assign({
10
10
  type: "complete",
11
11
  reason: "unknown"
12
12
  }, { [symbolAutoStatus]: true }));
13
+ const AUTO_STATUS_CANCELLED = Object.freeze(Object.assign({
14
+ type: "incomplete",
15
+ reason: "cancelled"
16
+ }, { [symbolAutoStatus]: true }));
13
17
  const AUTO_STATUS_PENDING = Object.freeze(Object.assign({
14
18
  type: "requires-action",
15
19
  reason: "tool-calls"
@@ -19,13 +23,13 @@ const AUTO_STATUS_INTERRUPT = Object.freeze(Object.assign({
19
23
  reason: "interrupt"
20
24
  }, { [symbolAutoStatus]: true }));
21
25
  const isAutoStatus = (status) => status[symbolAutoStatus] === true;
22
- const getAutoStatus = (isLast, isRunning, hasInterruptedToolCalls, hasPendingToolCalls, error) => {
26
+ const getAutoStatus = (isLast, isRunning, hasInterruptedToolCalls, hasPendingToolCalls, error, isCancelled) => {
23
27
  if (isLast && error) return Object.assign({
24
28
  type: "incomplete",
25
29
  reason: "error",
26
30
  error
27
31
  }, { [symbolAutoStatus]: true });
28
- return isLast && isRunning ? AUTO_STATUS_RUNNING : hasInterruptedToolCalls ? AUTO_STATUS_INTERRUPT : hasPendingToolCalls ? AUTO_STATUS_PENDING : AUTO_STATUS_COMPLETE;
32
+ return isLast && isRunning ? AUTO_STATUS_RUNNING : hasInterruptedToolCalls ? AUTO_STATUS_INTERRUPT : hasPendingToolCalls ? AUTO_STATUS_PENDING : isCancelled ? AUTO_STATUS_CANCELLED : AUTO_STATUS_COMPLETE;
29
33
  };
30
34
  const getContentAutoStatus = (content, isLast, isRunning) => getAutoStatus(isLast, isRunning, typeof content !== "string" && content.some(isInterruptedToolCall), typeof content !== "string" && content.some(isPendingToolCall));
31
35
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"auto-status.js","names":["MessageStatus","ReadonlyJSONValue","ThreadMessageLike","ThreadMessageLikeContentItem","Exclude","isPendingToolCall","c","type","result","undefined","isInterruptedToolCall","interrupt","approval","approved","resolution","symbolAutoStatus","Symbol","AUTO_STATUS_RUNNING","Object","freeze","assign","const","AUTO_STATUS_COMPLETE","reason","AUTO_STATUS_PENDING","AUTO_STATUS_INTERRUPT","isAutoStatus","status","getAutoStatus","isLast","isRunning","hasInterruptedToolCalls","hasPendingToolCalls","error","getContentAutoStatus","content","some"],"sources":["../../../src/runtime/utils/auto-status.ts"],"sourcesContent":["import type { MessageStatus } from \"../../types/message\";\nimport type { ReadonlyJSONValue } from \"assistant-stream/utils\";\nimport type { ThreadMessageLike } from \"./thread-message-like\";\n\ntype ThreadMessageLikeContentItem = Exclude<\n ThreadMessageLike[\"content\"],\n string\n>[number];\n\nexport const isPendingToolCall = (c: ThreadMessageLikeContentItem): boolean =>\n c.type === \"tool-call\" && c.result === undefined;\n\nexport const isInterruptedToolCall = (\n c: ThreadMessageLikeContentItem,\n): boolean => {\n if (c.type !== \"tool-call\" || c.result !== undefined) return false;\n return (\n c.interrupt != null ||\n (c.approval != null &&\n c.approval.approved === undefined &&\n c.approval.resolution === undefined)\n );\n};\n\nconst symbolAutoStatus = Symbol(\"autoStatus\");\n\nconst AUTO_STATUS_RUNNING = Object.freeze(\n Object.assign({ type: \"running\" as const }, { [symbolAutoStatus]: true }),\n);\nconst AUTO_STATUS_COMPLETE = Object.freeze(\n Object.assign(\n {\n type: \"complete\" as const,\n reason: \"unknown\" as const,\n },\n { [symbolAutoStatus]: true },\n ),\n);\n\nconst AUTO_STATUS_PENDING = Object.freeze(\n Object.assign(\n {\n type: \"requires-action\" as const,\n reason: \"tool-calls\" as const,\n },\n { [symbolAutoStatus]: true },\n ),\n);\n\nconst AUTO_STATUS_INTERRUPT = Object.freeze(\n Object.assign(\n {\n type: \"requires-action\" as const,\n reason: \"interrupt\" as const,\n },\n { [symbolAutoStatus]: true },\n ),\n);\n\nexport const isAutoStatus = (status: MessageStatus) =>\n (status as any)[symbolAutoStatus] === true;\n\nexport const getAutoStatus = (\n isLast: boolean,\n isRunning: boolean,\n hasInterruptedToolCalls: boolean,\n hasPendingToolCalls: boolean,\n error?: ReadonlyJSONValue,\n): MessageStatus => {\n if (isLast && error) {\n return Object.assign(\n {\n type: \"incomplete\" as const,\n reason: \"error\" as const,\n error: error,\n },\n { [symbolAutoStatus]: true },\n );\n }\n\n return isLast && isRunning\n ? AUTO_STATUS_RUNNING\n : hasInterruptedToolCalls\n ? AUTO_STATUS_INTERRUPT\n : hasPendingToolCalls\n ? AUTO_STATUS_PENDING\n : AUTO_STATUS_COMPLETE;\n};\n\nexport const getContentAutoStatus = (\n content: ThreadMessageLike[\"content\"],\n isLast: boolean,\n isRunning: boolean,\n): MessageStatus =>\n getAutoStatus(\n isLast,\n isRunning,\n typeof content !== \"string\" && content.some(isInterruptedToolCall),\n typeof content !== \"string\" && content.some(isPendingToolCall),\n );\n"],"mappings":";AASA,MAAaK,qBAAqBC,MAChCA,EAAEC,SAAS,eAAeD,EAAEE,WAAWC,KAAAA;AAEzC,MAAaC,yBACXJ,MACY;CACZ,IAAIA,EAAEC,SAAS,eAAeD,EAAEE,WAAWC,KAAAA,GAAW,OAAO;CAC7D,OACEH,EAAEK,aAAa,QACdL,EAAEM,YAAY,QACbN,EAAEM,SAASC,aAAaJ,KAAAA,KACxBH,EAAEM,SAASE,eAAeL,KAAAA;AAEhC;AAEA,MAAMM,mBAAmBC,OAAO,YAAY;AAE5C,MAAMC,sBAAsBC,OAAOC,OACjCD,OAAOE,OAAO,EAAEb,MAAM,UAAmB,GAAG,GAAGQ,mBAAmB,KAAK,CAAC,CAC1E;AACA,MAAMO,uBAAuBJ,OAAOC,OAClCD,OAAOE,OACL;CACEb,MAAM;CACNgB,QAAQ;AACV,GACA,GAAGR,mBAAmB,KAAK,CAC7B,CACF;AAEA,MAAMS,sBAAsBN,OAAOC,OACjCD,OAAOE,OACL;CACEb,MAAM;CACNgB,QAAQ;AACV,GACA,GAAGR,mBAAmB,KAAK,CAC7B,CACF;AAEA,MAAMU,wBAAwBP,OAAOC,OACnCD,OAAOE,OACL;CACEb,MAAM;CACNgB,QAAQ;AACV,GACA,GAAGR,mBAAmB,KAAK,CAC7B,CACF;AAEA,MAAaW,gBAAgBC,WAC1BA,OAAeZ,sBAAsB;AAExC,MAAaa,iBACXC,QACAC,WACAC,yBACAC,qBACAC,UACkB;CAClB,IAAIJ,UAAUI,OACZ,OAAOf,OAAOE,OACZ;EACEb,MAAM;EACNgB,QAAQ;EACDU;CACT,GACA,GAAGlB,mBAAmB,KAAK,CAC7B;CAGF,OAAOc,UAAUC,YACbb,sBACAc,0BACEN,wBACAO,sBACER,sBACAF;AACV;AAEA,MAAaY,wBACXC,SACAN,QACAC,cAEAF,cACEC,QACAC,WACA,OAAOK,YAAY,YAAYA,QAAQC,KAAK1B,qBAAqB,GACjE,OAAOyB,YAAY,YAAYA,QAAQC,KAAK/B,iBAAiB,CAC/D"}
1
+ {"version":3,"file":"auto-status.js","names":["MessageStatus","ReadonlyJSONValue","ThreadMessageLike","ThreadMessageLikeContentItem","Exclude","isPendingToolCall","c","type","result","undefined","isInterruptedToolCall","interrupt","approval","approved","resolution","symbolAutoStatus","Symbol","AUTO_STATUS_RUNNING","Object","freeze","assign","const","AUTO_STATUS_COMPLETE","reason","AUTO_STATUS_CANCELLED","AUTO_STATUS_PENDING","AUTO_STATUS_INTERRUPT","isAutoStatus","status","getAutoStatus","isLast","isRunning","hasInterruptedToolCalls","hasPendingToolCalls","error","isCancelled","getContentAutoStatus","content","some"],"sources":["../../../src/runtime/utils/auto-status.ts"],"sourcesContent":["import type { MessageStatus } from \"../../types/message\";\nimport type { ReadonlyJSONValue } from \"assistant-stream/utils\";\nimport type { ThreadMessageLike } from \"./thread-message-like\";\n\ntype ThreadMessageLikeContentItem = Exclude<\n ThreadMessageLike[\"content\"],\n string\n>[number];\n\nexport const isPendingToolCall = (c: ThreadMessageLikeContentItem): boolean =>\n c.type === \"tool-call\" && c.result === undefined;\n\nexport const isInterruptedToolCall = (\n c: ThreadMessageLikeContentItem,\n): boolean => {\n if (c.type !== \"tool-call\" || c.result !== undefined) return false;\n return (\n c.interrupt != null ||\n (c.approval != null &&\n c.approval.approved === undefined &&\n c.approval.resolution === undefined)\n );\n};\n\nconst symbolAutoStatus = Symbol(\"autoStatus\");\n\nconst AUTO_STATUS_RUNNING = Object.freeze(\n Object.assign({ type: \"running\" as const }, { [symbolAutoStatus]: true }),\n);\nconst AUTO_STATUS_COMPLETE = Object.freeze(\n Object.assign(\n {\n type: \"complete\" as const,\n reason: \"unknown\" as const,\n },\n { [symbolAutoStatus]: true },\n ),\n);\nconst AUTO_STATUS_CANCELLED = Object.freeze(\n Object.assign(\n {\n type: \"incomplete\" as const,\n reason: \"cancelled\" as const,\n },\n { [symbolAutoStatus]: true },\n ),\n);\n\nconst AUTO_STATUS_PENDING = Object.freeze(\n Object.assign(\n {\n type: \"requires-action\" as const,\n reason: \"tool-calls\" as const,\n },\n { [symbolAutoStatus]: true },\n ),\n);\n\nconst AUTO_STATUS_INTERRUPT = Object.freeze(\n Object.assign(\n {\n type: \"requires-action\" as const,\n reason: \"interrupt\" as const,\n },\n { [symbolAutoStatus]: true },\n ),\n);\n\nexport const isAutoStatus = (status: MessageStatus) =>\n (status as any)[symbolAutoStatus] === true;\n\nexport const getAutoStatus = (\n isLast: boolean,\n isRunning: boolean,\n hasInterruptedToolCalls: boolean,\n hasPendingToolCalls: boolean,\n error?: ReadonlyJSONValue,\n isCancelled?: boolean,\n): MessageStatus => {\n if (isLast && error) {\n return Object.assign(\n {\n type: \"incomplete\" as const,\n reason: \"error\" as const,\n error: error,\n },\n { [symbolAutoStatus]: true },\n );\n }\n\n return isLast && isRunning\n ? AUTO_STATUS_RUNNING\n : hasInterruptedToolCalls\n ? AUTO_STATUS_INTERRUPT\n : hasPendingToolCalls\n ? AUTO_STATUS_PENDING\n : isCancelled\n ? AUTO_STATUS_CANCELLED\n : AUTO_STATUS_COMPLETE;\n};\n\nexport const getContentAutoStatus = (\n content: ThreadMessageLike[\"content\"],\n isLast: boolean,\n isRunning: boolean,\n): MessageStatus =>\n getAutoStatus(\n isLast,\n isRunning,\n typeof content !== \"string\" && content.some(isInterruptedToolCall),\n typeof content !== \"string\" && content.some(isPendingToolCall),\n );\n"],"mappings":";AASA,MAAaK,qBAAqBC,MAChCA,EAAEC,SAAS,eAAeD,EAAEE,WAAWC,KAAAA;AAEzC,MAAaC,yBACXJ,MACY;CACZ,IAAIA,EAAEC,SAAS,eAAeD,EAAEE,WAAWC,KAAAA,GAAW,OAAO;CAC7D,OACEH,EAAEK,aAAa,QACdL,EAAEM,YAAY,QACbN,EAAEM,SAASC,aAAaJ,KAAAA,KACxBH,EAAEM,SAASE,eAAeL,KAAAA;AAEhC;AAEA,MAAMM,mBAAmBC,OAAO,YAAY;AAE5C,MAAMC,sBAAsBC,OAAOC,OACjCD,OAAOE,OAAO,EAAEb,MAAM,UAAmB,GAAG,GAAGQ,mBAAmB,KAAK,CAAC,CAC1E;AACA,MAAMO,uBAAuBJ,OAAOC,OAClCD,OAAOE,OACL;CACEb,MAAM;CACNgB,QAAQ;AACV,GACA,GAAGR,mBAAmB,KAAK,CAC7B,CACF;AACA,MAAMS,wBAAwBN,OAAOC,OACnCD,OAAOE,OACL;CACEb,MAAM;CACNgB,QAAQ;AACV,GACA,GAAGR,mBAAmB,KAAK,CAC7B,CACF;AAEA,MAAMU,sBAAsBP,OAAOC,OACjCD,OAAOE,OACL;CACEb,MAAM;CACNgB,QAAQ;AACV,GACA,GAAGR,mBAAmB,KAAK,CAC7B,CACF;AAEA,MAAMW,wBAAwBR,OAAOC,OACnCD,OAAOE,OACL;CACEb,MAAM;CACNgB,QAAQ;AACV,GACA,GAAGR,mBAAmB,KAAK,CAC7B,CACF;AAEA,MAAaY,gBAAgBC,WAC1BA,OAAeb,sBAAsB;AAExC,MAAac,iBACXC,QACAC,WACAC,yBACAC,qBACAC,OACAC,gBACkB;CAClB,IAAIL,UAAUI,OACZ,OAAOhB,OAAOE,OACZ;EACEb,MAAM;EACNgB,QAAQ;EACDW;CACT,GACA,GAAGnB,mBAAmB,KAAK,CAC7B;CAGF,OAAOe,UAAUC,YACbd,sBACAe,0BACEN,wBACAO,sBACER,sBACAU,cACEX,wBACAF;AACZ;AAEA,MAAac,wBACXC,SACAP,QACAC,cAEAF,cACEC,QACAC,WACA,OAAOM,YAAY,YAAYA,QAAQC,KAAK5B,qBAAqB,GACjE,OAAO2B,YAAY,YAAYA,QAAQC,KAAKjC,iBAAiB,CAC/D"}
@@ -20,6 +20,7 @@ type ExternalMessageConverterMessage = (ThreadMessageLike & {
20
20
  type ExternalMessageConverterMetadata = {
21
21
  readonly toolStatuses?: Record<string, ToolExecutionStatus>;
22
22
  readonly error?: ReadonlyJSONValue;
23
+ readonly cancelledMessageIds?: ReadonlySet<string>;
23
24
  readonly messageTiming?: Record<string, MessageTiming>;
24
25
  };
25
26
  type ExternalMessageConverterCallback<T> = (message: T, metadata: ExternalMessageConverterMetadata) => ExternalMessageConverterMessage | ExternalMessageConverterMessage[];
@@ -34,12 +35,12 @@ type ExternalMessageConverterChunk<T> = {
34
35
  declare const convertExternalMessageCallback: <T>(input: T, callback: ExternalMessageConverterCallback<T>, metadata: ExternalMessageConverterMetadata) => ExternalMessageConverterCallbackResult<T>;
35
36
  declare const joinExternalMessages: (messages: readonly ExternalMessageConverterMessage[]) => ThreadMessageLike;
36
37
  declare const chunkExternalMessages: <T>(callbackResults: ExternalMessageConverterCallbackResult<T>[], joinStrategy?: JoinStrategy) => ExternalMessageConverterChunk<T>[];
37
- declare const shallowArrayEqual: (a: unknown[], b: unknown[]) => boolean;
38
+ declare const shallowArrayEqual: (a: readonly unknown[], b: readonly unknown[]) => boolean;
38
39
  type ExternalMessageConversionCache = {
39
40
  message: ThreadMessage | undefined;
40
41
  generatedFallbackMessages: WeakSet<object>;
41
42
  };
42
- declare const convertExternalMessageChunk: <T>(message: ExternalMessageConverterChunk<T>, idx: number, chunkCount: number, isRunning: boolean, error: ReadonlyJSONValue | undefined, cache?: ExternalMessageConversionCache) => ThreadMessage;
43
+ declare const convertExternalMessageChunk: <T>(message: ExternalMessageConverterChunk<T>, idx: number, chunkCount: number, isRunning: boolean, error: ReadonlyJSONValue | undefined, cache?: ExternalMessageConversionCache, cancelledMessageIds?: ReadonlySet<string>) => ThreadMessage;
43
44
  declare const completeExternalMessageConversion: (messages: ThreadMessage[], error: ReadonlyJSONValue | undefined) => ThreadMessage[];
44
45
  declare const convertExternalMessages: <T extends WeakKey>(messages: T[], callback: ExternalMessageConverterCallback<T>, isRunning: boolean, metadata: ExternalMessageConverterMetadata) => ThreadMessage[];
45
46
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"external-message-conversion.d.ts","names":[],"sources":["../../../src/runtime/utils/external-message-conversion.ts"],"mappings":";;;;;KA2BY;KAEA,mCACP;WACU;aACE,eAAe;;;EAI1B;EACA;EACA;EACA;EACA;EACA;EACA,oBAAoB;;KAGd;WACD,eAAe,eAAe;WAC9B,QAAQ;WACR,gBAAgB,eAAe;;KAG9B,iCAAiC,MAC3C,SAAS,GACT,UAAU,qCACP,kCAAkC;KAE3B,uCAAuC;EACjD,OAAO;EACP,SAAS;;KAGC,8BAA8B;EACxC,QAAQ;EACR,SAAS;;cAsDE,iCAAkC,GAC7C,OAAO,GACP,UAAU,iCAAiC,IAC3C,UAAU,qCACT,uCAAuC;cAY7B,uBACX,mBAAmB,sCAClB;cA4KU,wBAAyB,GACpC,iBAAiB,uCAAuC,MACxD,eAAe,iBAAY,8BAAA;cAmDhB,oBAAqB,cAAc;KAQ3C;EACH,SAAS;EACT,2BAA2B;;cAGhB,8BAA+B,GAC1C,SAAS,8BAA8B,IACvC,aACA,oBACA,oBACA,OAAO,+BACP,QAAQ,mCAA8B;cAiF3B,oCACX,UAAU,iBACV,OAAO,kCAA6B;cAWzB,0BAA2B,UAAU,SAChD,UAAU,KACV,UAAU,iCAAiC,IAC3C,oBACA,UAAU,qCAAgC"}
1
+ {"version":3,"file":"external-message-conversion.d.ts","names":[],"sources":["../../../src/runtime/utils/external-message-conversion.ts"],"mappings":";;;;;KA2BY;KAEA,mCACP;WACU;aACE,eAAe;;;EAI1B;EACA;EACA;EACA;EACA;EACA;EACA,oBAAoB;;KAGd;WACD,eAAe,eAAe;WAC9B,QAAQ;WACR,sBAAsB;WACtB,gBAAgB,eAAe;;KAG9B,iCAAiC,MAC3C,SAAS,GACT,UAAU,qCACP,kCAAkC;KAE3B,uCAAuC;EACjD,OAAO;EACP,SAAS;;KAGC,8BAA8B;EACxC,QAAQ;EACR,SAAS;;cAsDE,iCAAkC,GAC7C,OAAO,GACP,UAAU,iCAAiC,IAC3C,UAAU,qCACT,uCAAuC;cAY7B,uBACX,mBAAmB,sCAClB;cA4KU,wBAAyB,GACpC,iBAAiB,uCAAuC,MACxD,eAAe,iBAAY,8BAAA;cAmDhB,oBACX,uBACA;KASG;EACH,SAAS;EACT,2BAA2B;;cAGhB,8BAA+B,GAC1C,SAAS,8BAA8B,IACvC,aACA,oBACA,oBACA,OAAO,+BACP,QAAQ,gCACR,sBAAsB,wBAAmB;cA0F9B,oCACX,UAAU,iBACV,OAAO,kCAA6B;cAWzB,0BAA2B,UAAU,SAChD,UAAU,KACV,UAAU,iCAAiC,IAC3C,oBACA,UAAU,qCAAgC"}
@@ -152,12 +152,13 @@ const shallowArrayEqual = (a, b) => {
152
152
  for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false;
153
153
  return true;
154
154
  };
155
- const convertExternalMessageChunk = (message, idx, chunkCount, isRunning, error, cache) => {
155
+ const convertExternalMessageChunk = (message, idx, chunkCount, isRunning, error, cache, cancelledMessageIds) => {
156
156
  const isLast = idx === chunkCount - 1;
157
157
  const joined = joinExternalMessages(message.outputs);
158
+ const isCancelled = cancelledMessageIds !== void 0 && message.outputs.some((output) => output.role !== "tool" && output.id != null && cancelledMessageIds.has(output.id));
158
159
  const hasInterruptedToolCalls = typeof joined.content === "object" && joined.content.some(isInterruptedToolCall);
159
160
  const hasPendingToolCalls = typeof joined.content === "object" && joined.content.some(isPendingToolCall);
160
- const autoStatus = getAutoStatus(isLast, isRunning, hasInterruptedToolCalls, hasPendingToolCalls, isLast ? error : void 0);
161
+ const autoStatus = getAutoStatus(isLast, isRunning, hasInterruptedToolCalls, hasPendingToolCalls, isLast ? error : void 0, isCancelled);
161
162
  const fallbackId = `${FALLBACK_ID_PREFIX}${idx}`;
162
163
  const cachedMessage = cache?.message;
163
164
  if (cachedMessage && (cachedMessage.role !== "assistant" || !isAutoStatus(cachedMessage.status) || cachedMessage.status === autoStatus || cachedMessage.status.type === "incomplete" && cachedMessage.status.reason === "error" && cachedMessage.status.error !== void 0 && autoStatus.type === "incomplete" && autoStatus.reason === "error" && autoStatus.error !== void 0 && (cachedMessage.status.error === autoStatus.error || isJSONValueEqual(cachedMessage.status.error, autoStatus.error)))) {
@@ -212,7 +213,7 @@ const completeExternalMessageConversion = (messages, error) => {
212
213
  const convertExternalMessages = (messages, callback, isRunning, metadata) => {
213
214
  const callbackResults = messages.map((message) => convertExternalMessageCallback(message, callback, metadata));
214
215
  const chunks = chunkExternalMessages(callbackResults);
215
- const result = chunks.map((message, idx) => convertExternalMessageChunk(message, idx, chunks.length, isRunning, metadata.error));
216
+ const result = chunks.map((message, idx) => convertExternalMessageChunk(message, idx, chunks.length, isRunning, metadata.error, void 0, metadata.cancelledMessageIds));
216
217
  return completeExternalMessageConversion(result, metadata.error);
217
218
  };
218
219
  //#endregion