@assistant-ui/core 0.3.13 → 0.3.14

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 (396) hide show
  1. package/dist/adapters/speech.d.ts.map +1 -1
  2. package/dist/adapters/speech.js +9 -15
  3. package/dist/adapters/speech.js.map +1 -1
  4. package/dist/adapters/thread-history.d.ts +2 -0
  5. package/dist/adapters/thread-history.d.ts.map +1 -1
  6. package/dist/adapters/voice.d.ts.map +1 -1
  7. package/dist/adapters/voice.js +27 -15
  8. package/dist/adapters/voice.js.map +1 -1
  9. package/dist/index.d.ts +2 -2
  10. package/dist/index.js.map +1 -1
  11. package/dist/internal.d.ts +1 -1
  12. package/dist/internal.js +6 -6
  13. package/dist/model-context/frame/host.d.ts.map +1 -1
  14. package/dist/model-context/frame/host.js +2 -1
  15. package/dist/model-context/frame/host.js.map +1 -1
  16. package/dist/model-context/registry.d.ts.map +1 -1
  17. package/dist/model-context/registry.js +16 -4
  18. package/dist/model-context/registry.js.map +1 -1
  19. package/dist/react/RuntimeAdapter.d.ts +8 -1
  20. package/dist/react/RuntimeAdapter.d.ts.map +1 -1
  21. package/dist/react/RuntimeAdapter.js +23 -18
  22. package/dist/react/RuntimeAdapter.js.map +1 -1
  23. package/dist/react/adapters/LocalStorageThreadListAdapter.d.ts.map +1 -1
  24. package/dist/react/adapters/LocalStorageThreadListAdapter.js +28 -12
  25. package/dist/react/adapters/LocalStorageThreadListAdapter.js.map +1 -1
  26. package/dist/react/client/AdaptedRemoteThread.d.ts +11 -0
  27. package/dist/react/client/AdaptedRemoteThread.d.ts.map +1 -0
  28. package/dist/react/client/AdaptedRemoteThread.js +27 -0
  29. package/dist/react/client/AdaptedRemoteThread.js.map +1 -0
  30. package/dist/react/client/InMemoryThreadList.d.ts +19 -0
  31. package/dist/react/client/InMemoryThreadList.d.ts.map +1 -0
  32. package/dist/react/client/InMemoryThreadList.js +418 -0
  33. package/dist/react/client/InMemoryThreadList.js.map +1 -0
  34. package/dist/react/client/Interactables.d.ts.map +1 -1
  35. package/dist/react/client/Interactables.js +159 -102
  36. package/dist/react/client/Interactables.js.map +1 -1
  37. package/dist/react/client/RemoteThreadList.d.ts +34 -0
  38. package/dist/react/client/RemoteThreadList.d.ts.map +1 -0
  39. package/dist/react/client/RemoteThreadList.js +826 -0
  40. package/dist/react/client/RemoteThreadList.js.map +1 -0
  41. package/dist/react/client/Tools.d.ts.map +1 -1
  42. package/dist/react/client/Tools.js +38 -27
  43. package/dist/react/client/Tools.js.map +1 -1
  44. package/dist/react/index.d.ts +7 -2
  45. package/dist/react/index.js +5 -2
  46. package/dist/react/interactables-legacy/Interactables.d.ts.map +1 -1
  47. package/dist/react/interactables-legacy/Interactables.js +145 -110
  48. package/dist/react/interactables-legacy/Interactables.js.map +1 -1
  49. package/dist/react/primitive-hooks/useActionBarCopy.d.ts.map +1 -1
  50. package/dist/react/primitive-hooks/useActionBarCopy.js +13 -18
  51. package/dist/react/primitive-hooks/useActionBarCopy.js.map +1 -1
  52. package/dist/react/primitive-hooks/useActionBarEdit.d.ts.map +1 -1
  53. package/dist/react/primitive-hooks/useActionBarEdit.js +2 -4
  54. package/dist/react/primitive-hooks/useActionBarEdit.js.map +1 -1
  55. package/dist/react/primitive-hooks/useActionBarReload.d.ts.map +1 -1
  56. package/dist/react/primitive-hooks/useActionBarReload.js +2 -4
  57. package/dist/react/primitive-hooks/useActionBarReload.js.map +1 -1
  58. package/dist/react/primitive-hooks/useBranchPickerNext.d.ts.map +1 -1
  59. package/dist/react/primitive-hooks/useBranchPickerNext.js +2 -6
  60. package/dist/react/primitive-hooks/useBranchPickerNext.js.map +1 -1
  61. package/dist/react/primitive-hooks/useBranchPickerPrevious.d.ts.map +1 -1
  62. package/dist/react/primitive-hooks/useBranchPickerPrevious.js +2 -6
  63. package/dist/react/primitive-hooks/useBranchPickerPrevious.js.map +1 -1
  64. package/dist/react/primitive-hooks/useComposerCancel.d.ts.map +1 -1
  65. package/dist/react/primitive-hooks/useComposerCancel.js +2 -4
  66. package/dist/react/primitive-hooks/useComposerCancel.js.map +1 -1
  67. package/dist/react/primitive-hooks/useComposerSend.d.ts.map +1 -1
  68. package/dist/react/primitive-hooks/useComposerSend.js +2 -4
  69. package/dist/react/primitive-hooks/useComposerSend.js.map +1 -1
  70. package/dist/react/primitive-hooks/useSuggestionTrigger.d.ts.map +1 -1
  71. package/dist/react/primitive-hooks/useSuggestionTrigger.js +6 -2
  72. package/dist/react/primitive-hooks/useSuggestionTrigger.js.map +1 -1
  73. package/dist/react/primitives/message/MessageParts.d.ts +13 -0
  74. package/dist/react/primitives/message/MessageParts.d.ts.map +1 -1
  75. package/dist/react/primitives/message/MessageParts.js.map +1 -1
  76. package/dist/react/primitives/thread/ThreadMessages.d.ts.map +1 -1
  77. package/dist/react/primitives/thread/ThreadMessages.js +1 -1
  78. package/dist/react/primitives/thread/ThreadMessages.js.map +1 -1
  79. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.d.ts +22 -10
  80. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.d.ts.map +1 -1
  81. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js +109 -71
  82. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js.map +1 -1
  83. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts +8 -2
  84. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts.map +1 -1
  85. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js +40 -13
  86. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js.map +1 -1
  87. package/dist/react/runtimes/RemoteThreadResource.d.ts +30 -0
  88. package/dist/react/runtimes/RemoteThreadResource.d.ts.map +1 -0
  89. package/dist/react/runtimes/RemoteThreadResource.js +134 -0
  90. package/dist/react/runtimes/RemoteThreadResource.js.map +1 -0
  91. package/dist/react/runtimes/RuntimeAdapterProvider.d.ts +3 -10
  92. package/dist/react/runtimes/RuntimeAdapterProvider.d.ts.map +1 -1
  93. package/dist/react/runtimes/RuntimeAdapterProvider.js +3 -6
  94. package/dist/react/runtimes/RuntimeAdapterProvider.js.map +1 -1
  95. package/dist/react/runtimes/assistant-transport/commandQueue.d.ts +17 -0
  96. package/dist/react/runtimes/assistant-transport/commandQueue.d.ts.map +1 -0
  97. package/dist/react/runtimes/assistant-transport/commandQueue.js +55 -0
  98. package/dist/react/runtimes/assistant-transport/commandQueue.js.map +1 -0
  99. package/dist/react/runtimes/assistant-transport/replayBoundaryStream.d.ts +11 -0
  100. package/dist/react/runtimes/assistant-transport/replayBoundaryStream.d.ts.map +1 -0
  101. package/dist/react/runtimes/assistant-transport/replayBoundaryStream.js +165 -0
  102. package/dist/react/runtimes/assistant-transport/replayBoundaryStream.js.map +1 -0
  103. package/dist/react/runtimes/assistant-transport/runManager.d.ts +15 -0
  104. package/dist/react/runtimes/assistant-transport/runManager.d.ts.map +1 -0
  105. package/dist/react/runtimes/assistant-transport/runManager.js +86 -0
  106. package/dist/react/runtimes/assistant-transport/runManager.js.map +1 -0
  107. package/dist/react/runtimes/assistant-transport/types.d.ts +130 -0
  108. package/dist/react/runtimes/assistant-transport/types.d.ts.map +1 -0
  109. package/dist/react/runtimes/assistant-transport/types.js +0 -0
  110. package/dist/react/runtimes/assistant-transport/useAssistantTransportRuntime.d.ts +14 -0
  111. package/dist/react/runtimes/assistant-transport/useAssistantTransportRuntime.d.ts.map +1 -0
  112. package/dist/react/runtimes/assistant-transport/useAssistantTransportRuntime.js +296 -0
  113. package/dist/react/runtimes/assistant-transport/useAssistantTransportRuntime.js.map +1 -0
  114. package/dist/react/runtimes/assistant-transport/useConvertedState.d.ts +7 -0
  115. package/dist/react/runtimes/assistant-transport/useConvertedState.d.ts.map +1 -0
  116. package/dist/react/runtimes/assistant-transport/useConvertedState.js +25 -0
  117. package/dist/react/runtimes/assistant-transport/useConvertedState.js.map +1 -0
  118. package/dist/react/runtimes/assistant-transport/useLatestRef.d.ts +7 -0
  119. package/dist/react/runtimes/assistant-transport/useLatestRef.d.ts.map +1 -0
  120. package/dist/react/runtimes/assistant-transport/useLatestRef.js +27 -0
  121. package/dist/react/runtimes/assistant-transport/useLatestRef.js.map +1 -0
  122. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.d.ts.map +1 -1
  123. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.js +39 -13
  124. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.js.map +1 -1
  125. package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.d.ts +2 -1
  126. package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.d.ts.map +1 -1
  127. package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.js +3 -3
  128. package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.js.map +1 -1
  129. package/dist/react/runtimes/cloud/auiV0.d.ts +4 -0
  130. package/dist/react/runtimes/cloud/auiV0.d.ts.map +1 -1
  131. package/dist/react/runtimes/cloud/auiV0.js +7 -0
  132. package/dist/react/runtimes/cloud/auiV0.js.map +1 -1
  133. package/dist/react/runtimes/cloud/useCloudThreadListAdapter.d.ts.map +1 -1
  134. package/dist/react/runtimes/cloud/useCloudThreadListAdapter.js +22 -12
  135. package/dist/react/runtimes/cloud/useCloudThreadListAdapter.js.map +1 -1
  136. package/dist/react/runtimes/cloud/useCloudThreadListRuntime.d.ts +16 -0
  137. package/dist/react/runtimes/cloud/useCloudThreadListRuntime.d.ts.map +1 -0
  138. package/dist/react/runtimes/cloud/useCloudThreadListRuntime.js +36 -0
  139. package/dist/react/runtimes/cloud/useCloudThreadListRuntime.js.map +1 -0
  140. package/dist/react/runtimes/external-message-converter.js +14 -14
  141. package/dist/react/runtimes/external-message-converter.js.map +1 -1
  142. package/dist/react/runtimes/useExternalStoreRuntime.d.ts.map +1 -1
  143. package/dist/react/runtimes/useExternalStoreRuntime.js +44 -28
  144. package/dist/react/runtimes/useExternalStoreRuntime.js.map +1 -1
  145. package/dist/react/runtimes/useExternalStoreSharedOptions.js.map +1 -1
  146. package/dist/react/runtimes/useLocalRuntime.js +1 -1
  147. package/dist/react/runtimes/useRuntimeAdapters.d.ts +9 -0
  148. package/dist/react/runtimes/useRuntimeAdapters.d.ts.map +1 -0
  149. package/dist/react/runtimes/useRuntimeAdapters.js +20 -0
  150. package/dist/react/runtimes/useRuntimeAdapters.js.map +1 -0
  151. package/dist/runtime/api/composer-runtime.d.ts +5 -0
  152. package/dist/runtime/api/composer-runtime.d.ts.map +1 -1
  153. package/dist/runtime/api/composer-runtime.js.map +1 -1
  154. package/dist/runtime/api/message-runtime.js +1 -1
  155. package/dist/runtime/api/thread-list-runtime.d.ts +1 -0
  156. package/dist/runtime/api/thread-list-runtime.d.ts.map +1 -1
  157. package/dist/runtime/api/thread-list-runtime.js +4 -2
  158. package/dist/runtime/api/thread-list-runtime.js.map +1 -1
  159. package/dist/runtime/api/thread-runtime.d.ts +12 -2
  160. package/dist/runtime/api/thread-runtime.d.ts.map +1 -1
  161. package/dist/runtime/api/thread-runtime.js +8 -2
  162. package/dist/runtime/api/thread-runtime.js.map +1 -1
  163. package/dist/runtime/base/base-composer-runtime-core.d.ts.map +1 -1
  164. package/dist/runtime/base/base-composer-runtime-core.js +8 -7
  165. package/dist/runtime/base/base-composer-runtime-core.js.map +1 -1
  166. package/dist/runtime/base/base-thread-runtime-core.d.ts +1 -0
  167. package/dist/runtime/base/base-thread-runtime-core.d.ts.map +1 -1
  168. package/dist/runtime/base/base-thread-runtime-core.js +3 -3
  169. package/dist/runtime/base/base-thread-runtime-core.js.map +1 -1
  170. package/dist/runtime/base/default-thread-composer-runtime-core.d.ts +0 -1
  171. package/dist/runtime/base/default-thread-composer-runtime-core.d.ts.map +1 -1
  172. package/dist/runtime/base/default-thread-composer-runtime-core.js +10 -4
  173. package/dist/runtime/base/default-thread-composer-runtime-core.js.map +1 -1
  174. package/dist/runtime/interfaces/thread-runtime-core.d.ts +6 -0
  175. package/dist/runtime/interfaces/thread-runtime-core.d.ts.map +1 -1
  176. package/dist/runtime/internal.js +5 -5
  177. package/dist/runtime/queue/message-queue.d.ts.map +1 -1
  178. package/dist/runtime/queue/message-queue.js +2 -1
  179. package/dist/runtime/queue/message-queue.js.map +1 -1
  180. package/dist/runtime/utils/thread-runtime-lifecycle.d.ts +8 -0
  181. package/dist/runtime/utils/thread-runtime-lifecycle.d.ts.map +1 -0
  182. package/dist/runtime/utils/thread-runtime-lifecycle.js +11 -0
  183. package/dist/runtime/utils/thread-runtime-lifecycle.js.map +1 -0
  184. package/dist/runtimes/external-store/external-store-shared-options.js.map +1 -1
  185. package/dist/runtimes/external-store/external-store-thread-list-runtime-core.d.ts.map +1 -1
  186. package/dist/runtimes/external-store/external-store-thread-list-runtime-core.js +4 -1
  187. package/dist/runtimes/external-store/external-store-thread-list-runtime-core.js.map +1 -1
  188. package/dist/runtimes/external-store/external-store-thread-runtime-core.d.ts +8 -0
  189. package/dist/runtimes/external-store/external-store-thread-runtime-core.d.ts.map +1 -1
  190. package/dist/runtimes/external-store/external-store-thread-runtime-core.js +35 -13
  191. package/dist/runtimes/external-store/external-store-thread-runtime-core.js.map +1 -1
  192. package/dist/runtimes/internal.d.ts +1 -1
  193. package/dist/runtimes/local/local-thread-runtime-core.d.ts +3 -0
  194. package/dist/runtimes/local/local-thread-runtime-core.d.ts.map +1 -1
  195. package/dist/runtimes/local/local-thread-runtime-core.js +53 -13
  196. package/dist/runtimes/local/local-thread-runtime-core.js.map +1 -1
  197. package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.d.ts +1 -0
  198. package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.d.ts.map +1 -1
  199. package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.js +3 -0
  200. package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.js.map +1 -1
  201. package/dist/runtimes/remote-thread-list/empty-thread-core.js +3 -0
  202. package/dist/runtimes/remote-thread-list/empty-thread-core.js.map +1 -1
  203. package/dist/runtimes/remote-thread-list/types.d.ts +29 -1
  204. package/dist/runtimes/remote-thread-list/types.d.ts.map +1 -1
  205. package/dist/runtimes/tool-invocations/ToolInvocationTracker.d.ts +1 -12
  206. package/dist/runtimes/tool-invocations/ToolInvocationTracker.d.ts.map +1 -1
  207. package/dist/runtimes/tool-invocations/ToolInvocationTracker.js +67 -38
  208. package/dist/runtimes/tool-invocations/ToolInvocationTracker.js.map +1 -1
  209. package/dist/store/clients/suggestions.js +2 -2
  210. package/dist/store/clients/suggestions.js.map +1 -1
  211. package/dist/store/clients/thread-selection-events.d.ts +10 -0
  212. package/dist/store/clients/thread-selection-events.d.ts.map +1 -0
  213. package/dist/store/clients/thread-selection-events.js +40 -0
  214. package/dist/store/clients/thread-selection-events.js.map +1 -0
  215. package/dist/store/env.d.ts +5 -0
  216. package/dist/store/env.d.ts.map +1 -0
  217. package/dist/store/env.js +12 -0
  218. package/dist/store/env.js.map +1 -0
  219. package/dist/store/index.d.ts +5 -3
  220. package/dist/store/index.js +4 -2
  221. package/dist/store/internal.d.ts +4 -1
  222. package/dist/store/internal.js +4 -1
  223. package/dist/store/primitive-predicates.d.ts +19 -0
  224. package/dist/store/primitive-predicates.d.ts.map +1 -0
  225. package/dist/store/primitive-predicates.js +19 -0
  226. package/dist/store/primitive-predicates.js.map +1 -0
  227. package/dist/store/runtime-clients/attachment-runtime-client.d.ts.map +1 -1
  228. package/dist/store/runtime-clients/attachment-runtime-client.js +18 -11
  229. package/dist/store/runtime-clients/attachment-runtime-client.js.map +1 -1
  230. package/dist/store/runtime-clients/handle-runtime-action.d.ts +5 -0
  231. package/dist/store/runtime-clients/handle-runtime-action.d.ts.map +1 -0
  232. package/dist/store/runtime-clients/handle-runtime-action.js +12 -0
  233. package/dist/store/runtime-clients/handle-runtime-action.js.map +1 -0
  234. package/dist/store/runtime-clients/handle-thread-list-action.d.ts +5 -0
  235. package/dist/store/runtime-clients/handle-thread-list-action.d.ts.map +1 -0
  236. package/dist/store/runtime-clients/handle-thread-list-action.js +7 -0
  237. package/dist/store/runtime-clients/handle-thread-list-action.js.map +1 -0
  238. package/dist/store/runtime-clients/thread-list-item-runtime-client.d.ts.map +1 -1
  239. package/dist/store/runtime-clients/thread-list-item-runtime-client.js +62 -29
  240. package/dist/store/runtime-clients/thread-list-item-runtime-client.js.map +1 -1
  241. package/dist/store/runtime-clients/thread-list-runtime-client.d.ts.map +1 -1
  242. package/dist/store/runtime-clients/thread-list-runtime-client.js +5 -6
  243. package/dist/store/runtime-clients/thread-list-runtime-client.js.map +1 -1
  244. package/dist/store/scopes/composer.d.ts +9 -4
  245. package/dist/store/scopes/composer.d.ts.map +1 -1
  246. package/dist/store/scopes/thread-list-item.d.ts +7 -6
  247. package/dist/store/scopes/thread-list-item.d.ts.map +1 -1
  248. package/dist/store/scopes/thread.d.ts +8 -7
  249. package/dist/store/scopes/thread.d.ts.map +1 -1
  250. package/dist/store/scopes/threads.d.ts +17 -1
  251. package/dist/store/scopes/threads.d.ts.map +1 -1
  252. package/dist/subscribable/subscribable.d.ts +2 -1
  253. package/dist/subscribable/subscribable.d.ts.map +1 -1
  254. package/dist/subscribable/subscribable.js +23 -18
  255. package/dist/subscribable/subscribable.js.map +1 -1
  256. package/dist/utils/composite-context-provider.d.ts +1 -0
  257. package/dist/utils/composite-context-provider.d.ts.map +1 -1
  258. package/dist/utils/composite-context-provider.js +25 -9
  259. package/dist/utils/composite-context-provider.js.map +1 -1
  260. package/dist/utils/notify-event-listeners.d.ts +2 -2
  261. package/dist/utils/notify-event-listeners.d.ts.map +1 -1
  262. package/dist/utils/notify-event-listeners.js +2 -2
  263. package/dist/utils/notify-event-listeners.js.map +1 -1
  264. package/package.json +7 -7
  265. package/src/adapters/speech.test.ts +118 -1
  266. package/src/adapters/speech.ts +21 -22
  267. package/src/adapters/thread-history.ts +2 -0
  268. package/src/adapters/voice.test.ts +69 -0
  269. package/src/adapters/voice.ts +27 -27
  270. package/src/index.ts +1 -0
  271. package/src/model-context/frame/host.test.ts +23 -0
  272. package/src/model-context/frame/host.ts +2 -1
  273. package/src/model-context/registry.test.ts +131 -0
  274. package/src/model-context/registry.ts +16 -6
  275. package/src/react/RuntimeAdapter.test.ts +2 -0
  276. package/src/react/RuntimeAdapter.ts +20 -8
  277. package/src/react/adapters/LocalStorageThreadListAdapter.tsx +34 -17
  278. package/src/react/client/AdaptedRemoteThread.ts +41 -0
  279. package/src/react/client/InMemoryThreadList.test.tsx +148 -0
  280. package/src/react/client/InMemoryThreadList.ts +290 -0
  281. package/src/react/client/Interactables.test.ts +326 -2
  282. package/src/react/client/Interactables.ts +227 -110
  283. package/src/react/client/RemoteThreadList.test.ts +1026 -0
  284. package/src/react/client/RemoteThreadList.ts +1067 -0
  285. package/src/react/client/Tools.ts +36 -29
  286. package/src/react/index.ts +13 -0
  287. package/src/react/interactables-legacy/Interactables.test.ts +317 -0
  288. package/src/react/interactables-legacy/Interactables.ts +204 -128
  289. package/src/react/primitive-hooks/useActionBarCopy.ts +2 -7
  290. package/src/react/primitive-hooks/useActionBarEdit.ts +2 -1
  291. package/src/react/primitive-hooks/useActionBarReload.ts +2 -6
  292. package/src/react/primitive-hooks/useBranchPickerNext.ts +2 -7
  293. package/src/react/primitive-hooks/useBranchPickerPrevious.ts +2 -7
  294. package/src/react/primitive-hooks/useComposerCancel.ts +2 -1
  295. package/src/react/primitive-hooks/useComposerSend.ts +2 -5
  296. package/src/react/primitive-hooks/useSuggestionTrigger.test.ts +11 -0
  297. package/src/react/primitive-hooks/useSuggestionTrigger.ts +4 -5
  298. package/src/react/primitives/message/MessageParts.tsx +0 -1
  299. package/src/react/primitives/thread/ThreadMessages.tsx +2 -1
  300. package/src/react/runtimes/RemoteThreadListHookInstanceManager.retry.test.tsx +116 -0
  301. package/src/react/runtimes/RemoteThreadListHookInstanceManager.running.test.tsx +1 -1
  302. package/src/react/runtimes/RemoteThreadListHookInstanceManager.test.tsx +57 -6
  303. package/src/react/runtimes/RemoteThreadListHookInstanceManager.title.test.tsx +272 -0
  304. package/src/react/runtimes/RemoteThreadListHookInstanceManager.tsx +159 -124
  305. package/src/react/runtimes/RemoteThreadListThreadListRuntimeCore.tsx +59 -20
  306. package/src/react/runtimes/RemoteThreadResource.test.ts +141 -0
  307. package/src/react/runtimes/RemoteThreadResource.ts +231 -0
  308. package/src/react/runtimes/RuntimeAdapterProvider.tsx +8 -20
  309. package/src/react/runtimes/assistant-transport/commandQueue.ts +68 -0
  310. package/src/react/runtimes/assistant-transport/replayBoundaryStream.test.ts +455 -0
  311. package/src/react/runtimes/assistant-transport/replayBoundaryStream.ts +172 -0
  312. package/src/react/runtimes/assistant-transport/runManager.ts +124 -0
  313. package/src/react/runtimes/assistant-transport/transport-delivery.test.tsx +79 -0
  314. package/src/react/runtimes/assistant-transport/transport-parentid.test.tsx +97 -0
  315. package/src/react/runtimes/assistant-transport/transport-scheduling.test.ts +414 -0
  316. package/src/react/runtimes/assistant-transport/types.ts +170 -0
  317. package/src/react/runtimes/assistant-transport/useAssistantTransport.spec.md +141 -0
  318. package/src/react/runtimes/assistant-transport/useAssistantTransportRuntime.test.tsx +625 -0
  319. package/src/react/runtimes/assistant-transport/useAssistantTransportRuntime.ts +481 -0
  320. package/src/react/runtimes/assistant-transport/useConvertedState.ts +20 -0
  321. package/src/react/runtimes/assistant-transport/useLatestRef.ts +9 -0
  322. package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.test.tsx +131 -6
  323. package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.ts +61 -15
  324. package/src/react/runtimes/cloud/CloudFileAttachmentAdapter.ts +6 -4
  325. package/src/react/runtimes/cloud/auiV0.ts +17 -1
  326. package/src/react/runtimes/cloud/useCloudThreadListAdapter.tsx +36 -21
  327. package/src/react/runtimes/cloud/useCloudThreadListRuntime.test.tsx +56 -0
  328. package/src/react/runtimes/cloud/useCloudThreadListRuntime.ts +31 -0
  329. package/src/react/runtimes/external-message-converter.test.ts +143 -0
  330. package/src/react/runtimes/external-message-converter.ts +41 -41
  331. package/src/react/runtimes/remote-thread-hook-on-tap.test.ts +58 -0
  332. package/src/react/runtimes/useExternalStoreRuntime.lifecycle.test.tsx +83 -0
  333. package/src/react/runtimes/useExternalStoreRuntime.suggestions.test.tsx +13 -3
  334. package/src/react/runtimes/useExternalStoreRuntime.ts +7 -0
  335. package/src/react/runtimes/useExternalStoreSharedOptions.ts +3 -1
  336. package/src/react/runtimes/useLocalRuntime.test.tsx +130 -4
  337. package/src/react/runtimes/useRuntimeAdapters.test.tsx +62 -0
  338. package/src/react/runtimes/useRuntimeAdapters.ts +28 -0
  339. package/src/runtime/api/composer-runtime.ts +5 -0
  340. package/src/runtime/api/thread-list-runtime.ts +3 -1
  341. package/src/runtime/api/thread-runtime.ts +20 -2
  342. package/src/runtime/base/base-composer-runtime-core.ts +6 -5
  343. package/src/runtime/base/base-thread-runtime-core.test.ts +191 -0
  344. package/src/runtime/base/base-thread-runtime-core.ts +11 -2
  345. package/src/runtime/base/default-thread-composer-runtime-core.ts +12 -4
  346. package/src/runtime/interfaces/thread-runtime-core.ts +6 -0
  347. package/src/runtime/queue/message-queue.ts +2 -1
  348. package/src/runtime/utils/thread-runtime-lifecycle.ts +18 -0
  349. package/src/runtimes/external-store/external-store-shared-options.ts +3 -1
  350. package/src/runtimes/external-store/external-store-thread-list-runtime-core.ts +4 -1
  351. package/src/runtimes/external-store/external-store-thread-runtime-core.ts +99 -34
  352. package/src/runtimes/local/local-thread-runtime-core.test.ts +373 -4
  353. package/src/runtimes/local/local-thread-runtime-core.ts +79 -14
  354. package/src/runtimes/readonly/ReadonlyThreadRuntimeCore.ts +4 -0
  355. package/src/runtimes/remote-thread-list/empty-thread-core.ts +4 -0
  356. package/src/runtimes/remote-thread-list/types.ts +30 -0
  357. package/src/runtimes/tool-invocations/EDGE_CASES.md +17 -6
  358. package/src/runtimes/tool-invocations/ToolInvocationTracker.test.ts +243 -0
  359. package/src/runtimes/tool-invocations/ToolInvocationTracker.ts +127 -61
  360. package/src/store/clients/model-context-client.test.ts +16 -8
  361. package/src/store/clients/suggestions.ts +2 -2
  362. package/src/store/clients/thread-selection-events.ts +21 -0
  363. package/src/store/env.ts +11 -0
  364. package/src/store/index.ts +14 -1
  365. package/src/store/internal.ts +13 -0
  366. package/src/store/primitive-predicates.test.ts +184 -0
  367. package/src/store/primitive-predicates.ts +43 -0
  368. package/src/store/runtime-clients/attachment-runtime-client.test.ts +41 -0
  369. package/src/store/runtime-clients/attachment-runtime-client.ts +2 -1
  370. package/src/store/runtime-clients/handle-runtime-action.ts +11 -0
  371. package/src/store/runtime-clients/handle-thread-list-action.test.ts +69 -0
  372. package/src/store/runtime-clients/handle-thread-list-action.ts +6 -0
  373. package/src/store/runtime-clients/thread-list-item-runtime-client.ts +15 -7
  374. package/src/store/runtime-clients/thread-list-runtime-client.ts +9 -6
  375. package/src/store/scopes/composer.ts +9 -4
  376. package/src/store/scopes/thread-list-item.ts +7 -6
  377. package/src/store/scopes/thread.ts +8 -7
  378. package/src/store/scopes/threads.ts +14 -0
  379. package/src/subscribable/subscribable.test.ts +77 -1
  380. package/src/subscribable/subscribable.ts +38 -23
  381. package/src/tests/RemoteThreadListThreadListRuntimeCore-switchToThread-unarchive.test.ts +25 -0
  382. package/src/tests/auiV0Encode.test.ts +66 -0
  383. package/src/tests/base-composer-runtime-core-send.test.ts +30 -0
  384. package/src/tests/base-composer-runtime-core.test.ts +28 -0
  385. package/src/tests/composer-can-cancel.test.ts +101 -0
  386. package/src/tests/external-store-thread-list-runtime-core.test.ts +101 -0
  387. package/src/tests/external-store-thread-runtime-core-adapter.test.ts +191 -1
  388. package/src/tests/external-store-thread-runtime-core.test.ts +124 -0
  389. package/src/tests/interactables-toolui-migration.test.tsx +66 -0
  390. package/src/tests/message-queue.test.ts +28 -0
  391. package/src/tests/session-reset-notification.test.ts +145 -0
  392. package/src/tests/thread-switch-events.test.tsx +99 -1
  393. package/src/tests/tools-scope-migration.test.tsx +58 -0
  394. package/src/utils/composite-context-provider.test.ts +139 -0
  395. package/src/utils/composite-context-provider.ts +26 -8
  396. package/src/utils/notify-event-listeners.ts +10 -5
@@ -1,8 +1,8 @@
1
1
  import { gateInteractableComposerMetadata } from "../../model-context/interactable-composer-metadata.js";
2
+ import { notifyEventListeners } from "../../utils/notify-event-listeners.js";
2
3
  import { generateId } from "../../utils/id.js";
3
4
  import { getThreadMessageText } from "../../utils/text.js";
4
5
  import { ExportedMessageRepository, MessageRepository } from "../utils/message-repository.js";
5
- import { notifyEventListeners } from "../../utils/notify-event-listeners.js";
6
6
  import { DefaultThreadComposerRuntimeCore } from "./default-thread-composer-runtime-core.js";
7
7
  import { DefaultEditComposerRuntimeCore } from "./default-edit-composer-runtime-core.js";
8
8
  //#region src/runtime/base/base-thread-runtime-core.ts
@@ -222,7 +222,7 @@ var BaseThreadRuntimeCore = class {
222
222
  }));
223
223
  unsubs.push(session.onVolumeChange((volume) => {
224
224
  this._voiceVolume = volume;
225
- for (const cb of this._voiceVolumeSubscribers) cb();
225
+ notifyEventListeners(this._voiceVolumeSubscribers, void 0, "Voice volume");
226
226
  }));
227
227
  unsubs.push(session.onTranscript((transcript) => {
228
228
  this._handleVoiceTranscript(transcript);
@@ -320,7 +320,7 @@ var BaseThreadRuntimeCore = class {
320
320
  this._voiceSession = void 0;
321
321
  this.voice = void 0;
322
322
  this._voiceVolume = 0;
323
- for (const cb of this._voiceVolumeSubscribers) cb();
323
+ notifyEventListeners(this._voiceVolumeSubscribers, void 0, "Voice volume");
324
324
  this._voiceMessages = [];
325
325
  this._markVoiceMessagesDirty();
326
326
  this._notifySubscribers();
@@ -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","BaseThreadAdapters","speech","feedback","attachments","voice","BaseThreadRuntimeCore","_subscriptions","Set","_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","_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","callback","_notifyEventSubscribers","event","E","payload","subscribers","_eventSubscribers","subscribe","add","submitFeedback","type","adapter","submit","updatedMessage","submittedFeedback","addOrUpdateMessage","_stopSpeaking","speak","utterance","unsub","status","cancel","stopSpeaking","_voiceSession","Session","_voiceUnsubs","Array","_voiceVolume","_voiceVolumeSubscribers","getVoiceVolume","subscribeVoiceVolume","connectVoice","disconnectVoice","session","connect","unsubs","currentMode","Mode","isMuted","mode","push","onStatusChange","_finishVoiceAssistantMessage","onModeChange","onVolumeChange","volume","cb","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\";\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 implements ThreadRuntimeCore {\n private _subscriptions = new Set<() => void>();\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\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 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 protected _notifySubscribers() {\n for (const callback of this._subscriptions) callback();\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 subscribe(callback: () => void): Unsubscribe {\n this._subscriptions.add(callback);\n return () => this._subscriptions.delete(callback);\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 for (const cb of this._voiceVolumeSubscribers) cb();\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 for (const cb of this._voiceVolumeSubscribers) cb();\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","BaseThreadAdapters","speech","feedback","attachments","voice","BaseThreadRuntimeCore","_subscriptions","Set","_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","callback","_notifyEventSubscribers","event","E","payload","subscribers","_eventSubscribers","subscribe","add","submitFeedback","type","adapter","submit","updatedMessage","submittedFeedback","addOrUpdateMessage","_stopSpeaking","speak","utterance","unsub","status","cancel","stopSpeaking","_voiceSession","Session","_voiceUnsubs","Array","_voiceVolume","_voiceVolumeSubscribers","getVoiceVolume","subscribeVoiceVolume","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\";\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 implements ThreadRuntimeCore {\n private _subscriptions = new Set<() => void>();\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 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 protected _notifySubscribers() {\n for (const callback of this._subscriptions) callback();\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 subscribe(callback: () => void): Unsubscribe {\n this._subscriptions.add(callback);\n return () => this._subscriptions.delete(callback);\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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"}
@@ -10,7 +10,6 @@ import { BaseComposerRuntimeCore } from "./base-composer-runtime-core.js";
10
10
  import "../../index.js";
11
11
  //#region src/runtime/base/default-thread-composer-runtime-core.d.ts
12
12
  declare class DefaultThreadComposerRuntimeCore extends BaseComposerRuntimeCore implements ThreadComposerRuntimeCore {
13
- private _canCancel;
14
13
  get canCancel(): boolean;
15
14
  get canSend(): boolean;
16
15
  private _queueCache;
@@ -1 +1 @@
1
- {"version":3,"file":"default-thread-composer-runtime-core.d.ts","names":[],"sources":["../../../src/runtime/base/default-thread-composer-runtime-core.ts"],"mappings":";;;;;;;;;;;cAea,yCACH,mCACG;UAEH;MACG;MAIA;UAIH;MAQY,kBAAkB;EAgBtB,cACd,qBACA,WAAW;EAKG,gBAAgB;YAItB,wBAAoB;YAIpB,uBAAmB;UAIrB;EAUN,YAAA,SAAS,KAAK;IACZ;MAEM,cAAc;MACd,YAAY;;;EAUf,WAVe;EA+BT,WACX,SAAS,KAAK,yCACd,UAAU,cAAW;EAWV,gBAAY"}
1
+ {"version":3,"file":"default-thread-composer-runtime-core.d.ts","names":[],"sources":["../../../src/runtime/base/default-thread-composer-runtime-core.ts"],"mappings":";;;;;;;;;;;cAsBa,yCACH,mCACG;MAEA;MAIA;UAIH;MAQY,kBAAkB;EAgBtB,cACd,qBACA,WAAW;EAKG,gBAAgB;YAItB,wBAAoB;YAIpB,uBAAmB;UAIrB;EAUN,YAAA,SAAS,KAAK;IACZ;MAEM,cAAc;MACd,YAAY;;;EAUf,WAVe;EAiCT,WACX,SAAS,KAAK,yCACd,UAAU,cAAW;EAWV,gBAAY"}
@@ -1,10 +1,14 @@
1
1
  import { EMPTY_QUEUE_ITEMS } from "../../store/scopes/queue-item.js";
2
+ import { getThreadRuntimeCoreIsRunning } from "../api/thread-runtime.js";
2
3
  import { BaseComposerRuntimeCore } from "./base-composer-runtime-core.js";
3
4
  //#region src/runtime/base/default-thread-composer-runtime-core.ts
5
+ const isCancelable = (runtime) => {
6
+ if (!runtime.capabilities?.cancel) return false;
7
+ return getThreadRuntimeCoreIsRunning(runtime);
8
+ };
4
9
  var DefaultThreadComposerRuntimeCore = class extends BaseComposerRuntimeCore {
5
- _canCancel = false;
6
10
  get canCancel() {
7
- return this._canCancel;
11
+ return isCancelable(this.runtime);
8
12
  }
9
13
  get canSend() {
10
14
  return !this.isEmpty && !this.runtime.isSendDisabled && !this._isSending;
@@ -42,12 +46,14 @@ var DefaultThreadComposerRuntimeCore = class extends BaseComposerRuntimeCore {
42
46
  this.connect();
43
47
  }
44
48
  connect() {
49
+ let lastCanCancel = false;
45
50
  let lastIsSendDisabled = this.runtime.isSendDisabled;
46
51
  let lastQueue = this.queue;
47
52
  return this.runtime.subscribe(() => {
48
53
  let changed = false;
49
- if (this.canCancel !== this.runtime.capabilities.cancel) {
50
- this._canCancel = this.runtime.capabilities.cancel;
54
+ const nextCanCancel = this.canCancel;
55
+ if (lastCanCancel !== nextCanCancel) {
56
+ lastCanCancel = nextCanCancel;
51
57
  changed = true;
52
58
  }
53
59
  if (lastIsSendDisabled !== this.runtime.isSendDisabled) {
@@ -1 +1 @@
1
- {"version":3,"file":"default-thread-composer-runtime-core.js","names":["AppendMessage","AttachmentAdapter","DictationAdapter","SendOptions","ThreadComposerRuntimeCore","ThreadRuntimeCore","QueuePlacement","EMPTY_QUEUE_ITEMS","QueueItemState","BaseComposerRuntimeCore","DefaultThreadComposerRuntimeCore","_canCancel","canCancel","canSend","isEmpty","runtime","isSendDisabled","_isSending","_queueCache","steer","queue","flat","getSteerQueueItems","getQueueItems","cache","length","moveQueueItem","queueItemId","placement","removeQueueItem","getAttachmentAdapter","adapters","attachments","getDictationAdapter","dictation","Omit","constructor","connect","lastIsSendDisabled","lastQueue","subscribe","changed","capabilities","cancel","_notifySubscribers","handleSend","message","options","append","parentId","messages","at","id","sourceId","startRun","handleCancel","cancelRun"],"sources":["../../../src/runtime/base/default-thread-composer-runtime-core.ts"],"sourcesContent":["import type { AppendMessage } from \"../../types/message\";\nimport type { AttachmentAdapter } from \"../../adapters/attachment\";\nimport type { DictationAdapter } from \"../../adapters/speech\";\nimport type {\n SendOptions,\n ThreadComposerRuntimeCore,\n} from \"../interfaces/composer-runtime-core\";\nimport type { ThreadRuntimeCore } from \"../interfaces/thread-runtime-core\";\nimport type { QueuePlacement } from \"../queue/external-thread-queue-adapter\";\nimport {\n EMPTY_QUEUE_ITEMS,\n type QueueItemState,\n} from \"../../store/scopes/queue-item\";\nimport { BaseComposerRuntimeCore } from \"./base-composer-runtime-core\";\n\nexport class DefaultThreadComposerRuntimeCore\n extends BaseComposerRuntimeCore\n implements ThreadComposerRuntimeCore\n{\n private _canCancel = false;\n public get canCancel() {\n return this._canCancel;\n }\n\n public get canSend() {\n return !this.isEmpty && !this.runtime.isSendDisabled && !this._isSending;\n }\n\n private _queueCache:\n | {\n steer: readonly QueueItemState[];\n queue: readonly QueueItemState[];\n flat: readonly QueueItemState[];\n }\n | undefined;\n\n public override get queue(): readonly QueueItemState[] {\n const steer = this.runtime.getSteerQueueItems?.() ?? EMPTY_QUEUE_ITEMS;\n const queue = this.runtime.getQueueItems?.() ?? EMPTY_QUEUE_ITEMS;\n const cache = this._queueCache;\n if (cache && cache.steer === steer && cache.queue === queue)\n return cache.flat;\n const flat =\n steer.length === 0\n ? queue\n : queue.length === 0\n ? steer\n : [...steer, ...queue];\n this._queueCache = { steer, queue, flat };\n return flat;\n }\n\n public override moveQueueItem(\n queueItemId: string,\n placement: QueuePlacement,\n ): void {\n this.runtime.moveQueueItem?.(queueItemId, placement);\n }\n\n public override removeQueueItem(queueItemId: string): void {\n this.runtime.removeQueueItem?.(queueItemId);\n }\n\n protected getAttachmentAdapter() {\n return this.runtime.adapters?.attachments;\n }\n\n protected getDictationAdapter() {\n return this.runtime.adapters?.dictation;\n }\n\n private runtime: Omit<ThreadRuntimeCore, \"composer\"> & {\n adapters?:\n | {\n attachments?: AttachmentAdapter | undefined;\n dictation?: DictationAdapter | undefined;\n }\n | undefined;\n };\n\n constructor(\n runtime: Omit<ThreadRuntimeCore, \"composer\"> & {\n adapters?:\n | {\n attachments?: AttachmentAdapter | undefined;\n dictation?: DictationAdapter | undefined;\n }\n | undefined;\n },\n ) {\n super();\n this.runtime = runtime;\n this.connect();\n }\n\n public connect() {\n let lastIsSendDisabled = this.runtime.isSendDisabled;\n let lastQueue = this.queue;\n return this.runtime.subscribe(() => {\n let changed = false;\n if (this.canCancel !== this.runtime.capabilities.cancel) {\n this._canCancel = this.runtime.capabilities.cancel;\n changed = true;\n }\n if (lastIsSendDisabled !== this.runtime.isSendDisabled) {\n lastIsSendDisabled = this.runtime.isSendDisabled;\n changed = true;\n }\n if (lastQueue !== this.queue) {\n lastQueue = this.queue;\n changed = true;\n }\n if (changed) this._notifySubscribers();\n });\n }\n\n public async handleSend(\n message: Omit<AppendMessage, \"parentId\" | \"sourceId\">,\n options?: SendOptions,\n ) {\n return this.runtime.append({\n ...(message as AppendMessage),\n parentId: this.runtime.messages.at(-1)?.id ?? null,\n sourceId: null,\n startRun: options?.startRun,\n steer: options?.steer,\n });\n }\n\n public async handleCancel() {\n this.runtime.cancelRun();\n }\n}\n"],"mappings":";;;AAeA,IAAaU,mCAAb,cACUD,wBAEV;CACE,aAAqB;CACrB,IAAWG,YAAY;EACrB,OAAO,KAAKD;CACd;CAEA,IAAWE,UAAU;EACnB,OAAO,CAAC,KAAKC,WAAW,CAAC,KAAKC,QAAQC,kBAAkB,CAAC,KAAKC;CAChE;CAEA;CAQA,IAAoBG,QAAmC;EACrD,MAAMD,QAAQ,KAAKJ,QAAQO,qBAAqB,KAAKf;EACrD,MAAMa,QAAQ,KAAKL,QAAQQ,gBAAgB,KAAKhB;EAChD,MAAMiB,QAAQ,KAAKN;EACnB,IAAIM,SAASA,MAAML,UAAUA,SAASK,MAAMJ,UAAUA,OACpD,OAAOI,MAAMH;EACf,MAAMA,OACJF,MAAMM,WAAW,IACbL,QACAA,MAAMK,WAAW,IACfN,QACA,CAAC,GAAGA,OAAO,GAAGC,KAAK;EAC3B,KAAKF,cAAc;GAAEC;GAAOC;GAAOC;EAAK;EACxC,OAAOA;CACT;CAEA,cACEM,aACAC,WACM;EACN,KAAKb,QAAQW,gBAAgBC,aAAaC,SAAS;CACrD;CAEA,gBAAgCD,aAA2B;EACzD,KAAKZ,QAAQc,kBAAkBF,WAAW;CAC5C;CAEA,uBAAiC;EAC/B,OAAO,KAAKZ,QAAQgB,UAAUC;CAChC;CAEA,sBAAgC;EAC9B,OAAO,KAAKjB,QAAQgB,UAAUG;CAChC;CAEA;CASAE,YACErB,SAQA;EACA,MAAM;EACN,KAAKA,UAAUA;EACf,KAAKsB,QAAQ;CACf;CAEA,UAAiB;EACf,IAAIC,qBAAqB,KAAKvB,QAAQC;EACtC,IAAIuB,YAAY,KAAKnB;EACrB,OAAO,KAAKL,QAAQyB,gBAAgB;GAClC,IAAIC,UAAU;GACd,IAAI,KAAK7B,cAAc,KAAKG,QAAQ2B,aAAaC,QAAQ;IACvD,KAAKhC,aAAa,KAAKI,QAAQ2B,aAAaC;IAC5CF,UAAU;GACZ;GACA,IAAIH,uBAAuB,KAAKvB,QAAQC,gBAAgB;IACtDsB,qBAAqB,KAAKvB,QAAQC;IAClCyB,UAAU;GACZ;GACA,IAAIF,cAAc,KAAKnB,OAAO;IAC5BmB,YAAY,KAAKnB;IACjBqB,UAAU;GACZ;GACA,IAAIA,SAAS,KAAKG,mBAAmB;EACvC,CAAC;CACH;CAEA,MAAaC,WACXC,SACAC,SACA;EACA,OAAO,KAAKhC,QAAQiC,OAAO;GACzB,GAAIF;GACJG,UAAU,KAAKlC,QAAQmC,SAASC,GAAG,EAAE,CAAC,EAAEC,MAAM;GAC9CC,UAAU;GACVC,UAAUP,SAASO;GACnBnC,OAAO4B,SAAS5B;EAClB,CAAC;CACH;CAEA,MAAaoC,eAAe;EAC1B,KAAKxC,QAAQyC,UAAU;CACzB;AACF"}
1
+ {"version":3,"file":"default-thread-composer-runtime-core.js","names":["AppendMessage","AttachmentAdapter","DictationAdapter","SendOptions","ThreadComposerRuntimeCore","ThreadRuntimeCore","getThreadRuntimeCoreIsRunning","QueuePlacement","EMPTY_QUEUE_ITEMS","QueueItemState","BaseComposerRuntimeCore","isCancelable","runtime","Omit","capabilities","cancel","DefaultThreadComposerRuntimeCore","canCancel","canSend","isEmpty","isSendDisabled","_isSending","_queueCache","steer","queue","flat","getSteerQueueItems","getQueueItems","cache","length","moveQueueItem","queueItemId","placement","removeQueueItem","getAttachmentAdapter","adapters","attachments","getDictationAdapter","dictation","constructor","connect","lastCanCancel","lastIsSendDisabled","lastQueue","subscribe","changed","nextCanCancel","_notifySubscribers","handleSend","message","options","append","parentId","messages","at","id","sourceId","startRun","handleCancel","cancelRun"],"sources":["../../../src/runtime/base/default-thread-composer-runtime-core.ts"],"sourcesContent":["import type { AppendMessage } from \"../../types/message\";\nimport type { AttachmentAdapter } from \"../../adapters/attachment\";\nimport type { DictationAdapter } from \"../../adapters/speech\";\nimport type {\n SendOptions,\n ThreadComposerRuntimeCore,\n} from \"../interfaces/composer-runtime-core\";\nimport type { ThreadRuntimeCore } from \"../interfaces/thread-runtime-core\";\nimport { getThreadRuntimeCoreIsRunning } from \"../api/thread-runtime\";\nimport type { QueuePlacement } from \"../queue/external-thread-queue-adapter\";\nimport {\n EMPTY_QUEUE_ITEMS,\n type QueueItemState,\n} from \"../../store/scopes/queue-item\";\nimport { BaseComposerRuntimeCore } from \"./base-composer-runtime-core\";\n\nconst isCancelable = (runtime: Omit<ThreadRuntimeCore, \"composer\">) => {\n // capabilities is a subclass field assigned after this composer is constructed\n if (!runtime.capabilities?.cancel) return false;\n return getThreadRuntimeCoreIsRunning(runtime);\n};\n\nexport class DefaultThreadComposerRuntimeCore\n extends BaseComposerRuntimeCore\n implements ThreadComposerRuntimeCore\n{\n public get canCancel() {\n return isCancelable(this.runtime);\n }\n\n public get canSend() {\n return !this.isEmpty && !this.runtime.isSendDisabled && !this._isSending;\n }\n\n private _queueCache:\n | {\n steer: readonly QueueItemState[];\n queue: readonly QueueItemState[];\n flat: readonly QueueItemState[];\n }\n | undefined;\n\n public override get queue(): readonly QueueItemState[] {\n const steer = this.runtime.getSteerQueueItems?.() ?? EMPTY_QUEUE_ITEMS;\n const queue = this.runtime.getQueueItems?.() ?? EMPTY_QUEUE_ITEMS;\n const cache = this._queueCache;\n if (cache && cache.steer === steer && cache.queue === queue)\n return cache.flat;\n const flat =\n steer.length === 0\n ? queue\n : queue.length === 0\n ? steer\n : [...steer, ...queue];\n this._queueCache = { steer, queue, flat };\n return flat;\n }\n\n public override moveQueueItem(\n queueItemId: string,\n placement: QueuePlacement,\n ): void {\n this.runtime.moveQueueItem?.(queueItemId, placement);\n }\n\n public override removeQueueItem(queueItemId: string): void {\n this.runtime.removeQueueItem?.(queueItemId);\n }\n\n protected getAttachmentAdapter() {\n return this.runtime.adapters?.attachments;\n }\n\n protected getDictationAdapter() {\n return this.runtime.adapters?.dictation;\n }\n\n private runtime: Omit<ThreadRuntimeCore, \"composer\"> & {\n adapters?:\n | {\n attachments?: AttachmentAdapter | undefined;\n dictation?: DictationAdapter | undefined;\n }\n | undefined;\n };\n\n constructor(\n runtime: Omit<ThreadRuntimeCore, \"composer\"> & {\n adapters?:\n | {\n attachments?: AttachmentAdapter | undefined;\n dictation?: DictationAdapter | undefined;\n }\n | undefined;\n },\n ) {\n super();\n this.runtime = runtime;\n this.connect();\n }\n\n public connect() {\n let lastCanCancel = false;\n let lastIsSendDisabled = this.runtime.isSendDisabled;\n let lastQueue = this.queue;\n return this.runtime.subscribe(() => {\n let changed = false;\n const nextCanCancel = this.canCancel;\n if (lastCanCancel !== nextCanCancel) {\n lastCanCancel = nextCanCancel;\n changed = true;\n }\n if (lastIsSendDisabled !== this.runtime.isSendDisabled) {\n lastIsSendDisabled = this.runtime.isSendDisabled;\n changed = true;\n }\n if (lastQueue !== this.queue) {\n lastQueue = this.queue;\n changed = true;\n }\n if (changed) this._notifySubscribers();\n });\n }\n\n public async handleSend(\n message: Omit<AppendMessage, \"parentId\" | \"sourceId\">,\n options?: SendOptions,\n ) {\n return this.runtime.append({\n ...(message as AppendMessage),\n parentId: this.runtime.messages.at(-1)?.id ?? null,\n sourceId: null,\n startRun: options?.startRun,\n steer: options?.steer,\n });\n }\n\n public async handleCancel() {\n this.runtime.cancelRun();\n }\n}\n"],"mappings":";;;;AAgBA,MAAMW,gBAAgBC,YAAiD;CAErE,IAAI,CAACA,QAAQE,cAAcC,QAAQ,OAAO;CAC1C,OAAOT,8BAA8BM,OAAO;AAC9C;AAEA,IAAaI,mCAAb,cACUN,wBAEV;CACE,IAAWO,YAAY;EACrB,OAAON,aAAa,KAAKC,OAAO;CAClC;CAEA,IAAWM,UAAU;EACnB,OAAO,CAAC,KAAKC,WAAW,CAAC,KAAKP,QAAQQ,kBAAkB,CAAC,KAAKC;CAChE;CAEA;CAQA,IAAoBG,QAAmC;EACrD,MAAMD,QAAQ,KAAKX,QAAQc,qBAAqB,KAAKlB;EACrD,MAAMgB,QAAQ,KAAKZ,QAAQe,gBAAgB,KAAKnB;EAChD,MAAMoB,QAAQ,KAAKN;EACnB,IAAIM,SAASA,MAAML,UAAUA,SAASK,MAAMJ,UAAUA,OACpD,OAAOI,MAAMH;EACf,MAAMA,OACJF,MAAMM,WAAW,IACbL,QACAA,MAAMK,WAAW,IACfN,QACA,CAAC,GAAGA,OAAO,GAAGC,KAAK;EAC3B,KAAKF,cAAc;GAAEC;GAAOC;GAAOC;EAAK;EACxC,OAAOA;CACT;CAEA,cACEM,aACAC,WACM;EACN,KAAKpB,QAAQkB,gBAAgBC,aAAaC,SAAS;CACrD;CAEA,gBAAgCD,aAA2B;EACzD,KAAKnB,QAAQqB,kBAAkBF,WAAW;CAC5C;CAEA,uBAAiC;EAC/B,OAAO,KAAKnB,QAAQuB,UAAUC;CAChC;CAEA,sBAAgC;EAC9B,OAAO,KAAKxB,QAAQuB,UAAUG;CAChC;CAEA;CASAC,YACE3B,SAQA;EACA,MAAM;EACN,KAAKA,UAAUA;EACf,KAAK4B,QAAQ;CACf;CAEA,UAAiB;EACf,IAAIC,gBAAgB;EACpB,IAAIC,qBAAqB,KAAK9B,QAAQQ;EACtC,IAAIuB,YAAY,KAAKnB;EACrB,OAAO,KAAKZ,QAAQgC,gBAAgB;GAClC,IAAIC,UAAU;GACd,MAAMC,gBAAgB,KAAK7B;GAC3B,IAAIwB,kBAAkBK,eAAe;IACnCL,gBAAgBK;IAChBD,UAAU;GACZ;GACA,IAAIH,uBAAuB,KAAK9B,QAAQQ,gBAAgB;IACtDsB,qBAAqB,KAAK9B,QAAQQ;IAClCyB,UAAU;GACZ;GACA,IAAIF,cAAc,KAAKnB,OAAO;IAC5BmB,YAAY,KAAKnB;IACjBqB,UAAU;GACZ;GACA,IAAIA,SAAS,KAAKE,mBAAmB;EACvC,CAAC;CACH;CAEA,MAAaC,WACXC,SACAC,SACA;EACA,OAAO,KAAKtC,QAAQuC,OAAO;GACzB,GAAIF;GACJG,UAAU,KAAKxC,QAAQyC,SAASC,GAAG,EAAE,CAAC,EAAEC,MAAM;GAC9CC,UAAU;GACVC,UAAUP,SAASO;GACnBlC,OAAO2B,SAAS3B;EAClB,CAAC;CACH;CAEA,MAAamC,eAAe;EAC1B,KAAK9C,QAAQ+C,UAAU;CACzB;AACF"}
@@ -60,6 +60,11 @@ type SubmitFeedbackOptions = {
60
60
  type: "negative" | "positive";
61
61
  };
62
62
  type ThreadSuggestion = {
63
+ /** Display heading for the suggestion. Falls back to the prompt when absent. */
64
+ title?: string;
65
+ /** Secondary display text shown alongside the title. */
66
+ label?: string;
67
+ /** The message text sent when the suggestion is selected. */
63
68
  prompt: string;
64
69
  };
65
70
  type SpeechState = {
@@ -127,6 +132,7 @@ type ThreadRuntimeCore = Readonly<{
127
132
  startRun: (config: StartRunConfig) => void;
128
133
  resumeRun: (config: ResumeRunConfig) => void;
129
134
  cancelRun: () => void;
135
+ unstable_notifySessionReset: () => void;
130
136
  addToolResult: (options: AddToolResultOptions) => void;
131
137
  resumeToolCall: (options: ResumeToolCallOptions) => void;
132
138
  respondToToolApproval: (options: RespondToToolApprovalOptions) => 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;EACV;;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;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;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"}
@@ -3,16 +3,16 @@ import { symbolInnerMessage } from "./utils/external-store-message.js";
3
3
  import { getAutoStatus, isAutoStatus } from "./utils/auto-status.js";
4
4
  import { ExportedMessageRepository, MessageRepository } from "./utils/message-repository.js";
5
5
  import { BaseAssistantRuntimeCore } from "./base/base-assistant-runtime-core.js";
6
- import { BaseComposerRuntimeCore } from "./base/base-composer-runtime-core.js";
7
- import { DefaultThreadComposerRuntimeCore } from "./base/default-thread-composer-runtime-core.js";
8
- import { DefaultEditComposerRuntimeCore } from "./base/default-edit-composer-runtime-core.js";
9
- import { BaseThreadRuntimeCore } from "./base/base-thread-runtime-core.js";
10
- import { ThreadListItemRuntimeImpl } from "./api/thread-list-item-runtime.js";
11
6
  import { AttachmentRuntimeImpl, EditComposerAttachmentRuntimeImpl, MessageAttachmentRuntimeImpl, ThreadComposerAttachmentRuntimeImpl } from "./api/attachment-runtime.js";
12
7
  import { ComposerRuntimeImpl, EditComposerRuntimeImpl, ThreadComposerRuntimeImpl } from "./api/composer-runtime.js";
13
8
  import { MessagePartRuntimeImpl } from "./api/message-part-runtime.js";
14
9
  import { MessageRuntimeImpl } from "./api/message-runtime.js";
15
10
  import { ThreadRuntimeImpl, getThreadState } from "./api/thread-runtime.js";
11
+ import { BaseComposerRuntimeCore } from "./base/base-composer-runtime-core.js";
12
+ import { DefaultThreadComposerRuntimeCore } from "./base/default-thread-composer-runtime-core.js";
13
+ import { DefaultEditComposerRuntimeCore } from "./base/default-edit-composer-runtime-core.js";
14
+ import { BaseThreadRuntimeCore } from "./base/base-thread-runtime-core.js";
15
+ import { ThreadListItemRuntimeImpl } from "./api/thread-list-item-runtime.js";
16
16
  import { ThreadListRuntimeImpl } from "./api/thread-list-runtime.js";
17
17
  import { AssistantRuntimeImpl } from "./api/assistant-runtime.js";
18
18
  export { AssistantRuntimeImpl, AttachmentRuntimeImpl, BaseAssistantRuntimeCore, BaseComposerRuntimeCore, BaseThreadRuntimeCore, ComposerRuntimeImpl, DefaultEditComposerRuntimeCore, DefaultThreadComposerRuntimeCore, EditComposerAttachmentRuntimeImpl, EditComposerRuntimeImpl, ExportedMessageRepository, MessageAttachmentRuntimeImpl, MessagePartRuntimeImpl, MessageRepository, MessageRuntimeImpl, ThreadComposerAttachmentRuntimeImpl, ThreadComposerRuntimeImpl, ThreadListItemRuntimeImpl, ThreadListRuntimeImpl, ThreadRuntimeImpl, fromThreadMessageLike, getAutoStatus, getThreadState, isAutoStatus, symbolInnerMessage };
@@ -1 +1 @@
1
- {"version":3,"file":"message-queue.d.ts","names":[],"sources":["../../../src/runtime/queue/message-queue.ts"],"mappings":";;;KAgBY;EACV,MAAM,SAAS,eAAe;IAAW;;;EAEzC;;KAGU;WACD,SAAS;;EAElB;;EAEA;;;;;;;EAOA;;EAEA;EACA,YAAY;;cAgCD,qBACX,QAAQ,uBACP"}
1
+ {"version":3,"file":"message-queue.d.ts","names":[],"sources":["../../../src/runtime/queue/message-queue.ts"],"mappings":";;;KAiBY;EACV,MAAM,SAAS,eAAe;IAAW;;;EAEzC;;KAGU;WACD,SAAS;;EAElB;;EAEA;;;;;;;EAOA;;EAEA;EACA,YAAY;;cAgCD,qBACX,QAAQ,uBACP"}
@@ -1,3 +1,4 @@
1
+ import { notifyEventListeners } from "../../utils/notify-event-listeners.js";
1
2
  import { generateId } from "../../utils/id.js";
2
3
  import { getThreadMessageText } from "../../utils/text.js";
3
4
  import { EMPTY_QUEUE_ITEMS } from "../../store/scopes/queue-item.js";
@@ -28,7 +29,7 @@ const createMessageQueue = (driver) => {
28
29
  let cancelSettles = 0;
29
30
  let interrupting = false;
30
31
  const notify = () => {
31
- for (const callback of subscribers) callback();
32
+ notifyEventListeners(subscribers, void 0, "Message queue");
32
33
  };
33
34
  const setLanes = (next) => {
34
35
  lanes = next;
@@ -1 +1 @@
1
- {"version":3,"file":"message-queue.js","names":["AppendMessage","FileMessagePart","TextMessagePart","EMPTY_QUEUE_ITEMS","QueueItemState","generateId","getThreadMessageText","ExternalThreadQueueAdapter","QueuePlacement","MessageQueueDriver","run","message","options","steer","cancel","MessageQueueController","adapter","notifyBusy","notifyIdle","notifyCancelled","clear","subscribe","callback","Lane","getQueueItemParts","source","content","attachments","flatMap","attachment","filter","part","type","parts","push","data","image","mimeType","filename","undefined","createMessageQueue","driver","lanes","Record","queue","messages","Map","subscribers","Set","running","paused","dispatchTransform","m","suppressIdle","cancelSettles","interrupting","notify","setLanes","next","items","steerItems","toItem","id","prompt","laneOf","queueItemId","some","item","advance","lane","length","head","get","delete","slice","interrupt","Math","max","set","enqueue","move","placement","fromLane","Error","toLane","find","i","dest","anchorIndex","anchor","index","findIndex","insertAfter","insertBefore","after","before","nextDest","edit","map","remove","__internal_setDispatchTransform","transform","__internal_notifyCancelled","add"],"sources":["../../../src/runtime/queue/message-queue.ts"],"sourcesContent":["import type {\n AppendMessage,\n FileMessagePart,\n TextMessagePart,\n} from \"../../types/message\";\nimport {\n EMPTY_QUEUE_ITEMS,\n type QueueItemState,\n} from \"../../store/scopes/queue-item\";\nimport { generateId } from \"../../utils/id\";\nimport { getThreadMessageText } from \"../../utils/text\";\nimport type {\n ExternalThreadQueueAdapter,\n QueuePlacement,\n} from \"./external-thread-queue-adapter\";\n\nexport type MessageQueueDriver = {\n run: (message: AppendMessage, options: { steer: boolean }) => void;\n /** When omitted, steering degrades to \"process next\" instead of interrupting. */\n cancel?: (() => void) | undefined;\n};\n\nexport type MessageQueueController = {\n readonly adapter: ExternalThreadQueueAdapter;\n /** Mark a run as in flight so concurrent sends buffer; call on the rising edge. */\n notifyBusy: () => void;\n /** Advances to the next pending message; call on the run's falling edge. */\n notifyIdle: () => void;\n /**\n * Pauses queue advance for a user-initiated cancel, so the cancelled run's\n * settle keeps the pending items instead of dispatching the next one; the\n * next explicit send or run start re-arms draining. Call before aborting\n * the run.\n */\n notifyCancelled: () => void;\n /** Empties both lanes without dispatching. */\n clear: () => void;\n subscribe: (callback: () => void) => () => void;\n};\n\ntype Lane = \"queue\" | \"steer\";\n\nconst getQueueItemParts = (\n message: AppendMessage,\n): readonly (FileMessagePart | TextMessagePart)[] => {\n // attachment-derived text is the file body, not user-authored prose;\n // project only the file/image content of attachments\n const source = [\n ...message.content,\n ...(message.attachments ?? []).flatMap((attachment) =>\n (attachment.content ?? []).filter((part) => part.type !== \"text\"),\n ),\n ];\n const parts: (FileMessagePart | TextMessagePart)[] = [];\n for (const part of source) {\n if (part.type === \"file\" || part.type === \"text\") {\n parts.push(part);\n } else if (part.type === \"image\") {\n parts.push({\n type: \"file\",\n data: part.image,\n mimeType: \"image/*\",\n ...(part.filename !== undefined && { filename: part.filename }),\n });\n }\n }\n return parts;\n};\n\nexport const createMessageQueue = (\n driver: MessageQueueDriver,\n): MessageQueueController => {\n let lanes: Record<Lane, readonly QueueItemState[]> = {\n queue: EMPTY_QUEUE_ITEMS,\n steer: EMPTY_QUEUE_ITEMS,\n };\n const messages = new Map<string, AppendMessage>();\n const subscribers = new Set<() => void>();\n\n let running = false;\n let paused = false;\n let dispatchTransform: (message: AppendMessage) => AppendMessage = (m) => m;\n // swallow the cancelled run's settle when steering so it does not double-advance\n let suppressIdle = 0;\n // settles from cancelled runs that must drop `running` without advancing\n let cancelSettles = 0;\n let interrupting = false;\n\n const notify = () => {\n for (const callback of subscribers) callback();\n };\n\n const setLanes = (next: Record<Lane, readonly QueueItemState[]>) => {\n lanes = next;\n adapter.items = next.queue;\n adapter.steerItems = next.steer;\n notify();\n };\n\n const toItem = (id: string, message: AppendMessage): QueueItemState => ({\n id,\n prompt: getThreadMessageText(message),\n parts: getQueueItemParts(message),\n });\n\n const laneOf = (queueItemId: string): Lane | undefined => {\n if (lanes.steer.some((item) => item.id === queueItemId)) return \"steer\";\n if (lanes.queue.some((item) => item.id === queueItemId)) return \"queue\";\n return undefined;\n };\n\n const advance = () => {\n if (running || paused) return;\n const lane: Lane = lanes.steer.length > 0 ? \"steer\" : \"queue\";\n const head = lanes[lane][0];\n if (!head) return;\n const message = messages.get(head.id);\n messages.delete(head.id);\n setLanes({ ...lanes, [lane]: lanes[lane].slice(1) });\n if (!message) return;\n running = true;\n driver.run(dispatchTransform(message), { steer: false });\n };\n\n const interrupt = (message: AppendMessage) => {\n paused = false;\n // the interrupted run settles exactly once, whether or not it was\n // already cancel-notified\n suppressIdle += Math.max(cancelSettles, 1);\n cancelSettles = 0;\n // a driver whose cancel routes through the runtime notifies this queue\n // back; the interrupt already accounted for that settle and is dispatching\n // in its place\n interrupting = true;\n try {\n driver.cancel!();\n } finally {\n interrupting = false;\n }\n running = true;\n driver.run(dispatchTransform(message), { steer: true });\n };\n\n const push = (lane: Lane, message: AppendMessage) => {\n paused = false;\n const id = generateId();\n messages.set(id, message);\n setLanes({ ...lanes, [lane]: [...lanes[lane], toItem(id, message)] });\n advance();\n };\n\n const enqueue = (message: AppendMessage) => {\n push(\"queue\", message);\n };\n\n const steer = (message: AppendMessage) => {\n if (running && driver.cancel) {\n interrupt(message);\n return;\n }\n push(\"steer\", message);\n };\n\n const move = (queueItemId: string, placement: QueuePlacement) => {\n const fromLane = laneOf(queueItemId);\n if (!fromLane) throw new Error(`Unknown queue item \"${queueItemId}\".`);\n const toLane = placement.lane ?? fromLane;\n\n const item = lanes[fromLane].find((i) => i.id === queueItemId)!;\n const dest = (toLane === fromLane ? lanes[fromLane] : lanes[toLane]).filter(\n (i) => i.id !== queueItemId,\n );\n\n const anchorIndex = (anchor: string) => {\n if (anchor === queueItemId)\n throw new Error(`Queue item \"${queueItemId}\" cannot anchor itself.`);\n const index = dest.findIndex((i) => i.id === anchor);\n if (index === -1)\n throw new Error(`Unknown anchor \"${anchor}\" in lane \"${toLane}\".`);\n return index;\n };\n\n const { insertAfter, insertBefore } = placement;\n let index: number;\n if (insertAfter === undefined && insertBefore === undefined) {\n index =\n toLane === fromLane\n ? lanes[fromLane].findIndex((i) => i.id === queueItemId)\n : dest.length;\n } else if (insertAfter !== undefined && insertBefore !== undefined) {\n const after = insertAfter === null ? -1 : anchorIndex(insertAfter);\n const before =\n insertBefore === null ? dest.length : anchorIndex(insertBefore);\n if (before !== after + 1)\n throw new Error(\n `insertAfter \"${insertAfter}\" and insertBefore \"${insertBefore}\" are not adjacent in lane \"${toLane}\".`,\n );\n index = after + 1;\n } else if (insertAfter !== undefined) {\n index = insertAfter === null ? 0 : anchorIndex(insertAfter) + 1;\n } else {\n index = insertBefore === null ? dest.length : anchorIndex(insertBefore!);\n }\n\n // placement and immediate dispatch cannot coexist: an anchored move into\n // the steer lane places without interrupting; only an unanchored one\n // cancels the live run and dispatches\n if (\n insertAfter === undefined &&\n insertBefore === undefined &&\n toLane === \"steer\" &&\n fromLane !== \"steer\" &&\n running &&\n driver.cancel\n ) {\n const message = messages.get(queueItemId)!;\n messages.delete(queueItemId);\n setLanes({\n queue: lanes.queue.filter((i) => i.id !== queueItemId),\n steer: lanes.steer,\n });\n interrupt(message);\n return;\n }\n\n const nextDest = [...dest.slice(0, index), item, ...dest.slice(index)];\n const next = { ...lanes, [toLane]: nextDest };\n if (toLane !== fromLane)\n next[fromLane] = lanes[fromLane].filter((i) => i.id !== queueItemId);\n setLanes(next);\n advance();\n };\n\n const edit = (queueItemId: string, message: AppendMessage) => {\n const lane = laneOf(queueItemId);\n if (!lane) throw new Error(`Unknown queue item \"${queueItemId}\".`);\n messages.set(queueItemId, message);\n setLanes({\n ...lanes,\n [lane]: lanes[lane].map((item) =>\n item.id === queueItemId ? toItem(queueItemId, message) : item,\n ),\n });\n };\n\n const remove = (queueItemId: string) => {\n if (!messages.delete(queueItemId)) return;\n setLanes({\n queue: lanes.queue.filter((item) => item.id !== queueItemId),\n steer: lanes.steer.filter((item) => item.id !== queueItemId),\n });\n };\n\n const notifyCancelled = () => {\n if (interrupting) return;\n if (running && cancelSettles === 0) {\n paused = true;\n cancelSettles = 1;\n }\n };\n\n const adapter: ExternalThreadQueueAdapter = {\n items: lanes.queue,\n steerItems: lanes.steer,\n enqueue,\n steer,\n move,\n edit,\n remove,\n __internal_setDispatchTransform: (transform) => {\n dispatchTransform = transform;\n },\n __internal_notifyCancelled: notifyCancelled,\n };\n\n return {\n adapter,\n notifyBusy: () => {\n paused = false;\n // a cancelled run's settle that is still outstanding belongs to a run\n // this new one replaces; swallow it entirely\n suppressIdle += cancelSettles;\n cancelSettles = 0;\n running = true;\n },\n notifyIdle: () => {\n if (suppressIdle > 0) {\n suppressIdle--;\n return;\n }\n if (cancelSettles > 0) cancelSettles--;\n running = false;\n advance();\n },\n notifyCancelled,\n clear: () => {\n messages.clear();\n setLanes({ queue: EMPTY_QUEUE_ITEMS, steer: EMPTY_QUEUE_ITEMS });\n },\n subscribe: (callback) => {\n subscribers.add(callback);\n return () => {\n subscribers.delete(callback);\n };\n },\n };\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"message-queue.js","names":["AppendMessage","FileMessagePart","TextMessagePart","EMPTY_QUEUE_ITEMS","QueueItemState","generateId","notifyEventListeners","getThreadMessageText","ExternalThreadQueueAdapter","QueuePlacement","MessageQueueDriver","run","message","options","steer","cancel","MessageQueueController","adapter","notifyBusy","notifyIdle","notifyCancelled","clear","subscribe","callback","Lane","getQueueItemParts","source","content","attachments","flatMap","attachment","filter","part","type","parts","push","data","image","mimeType","filename","undefined","createMessageQueue","driver","lanes","Record","queue","messages","Map","subscribers","Set","running","paused","dispatchTransform","m","suppressIdle","cancelSettles","interrupting","notify","setLanes","next","items","steerItems","toItem","id","prompt","laneOf","queueItemId","some","item","advance","lane","length","head","get","delete","slice","interrupt","Math","max","set","enqueue","move","placement","fromLane","Error","toLane","find","i","dest","anchorIndex","anchor","index","findIndex","insertAfter","insertBefore","after","before","nextDest","edit","map","remove","__internal_setDispatchTransform","transform","__internal_notifyCancelled","add"],"sources":["../../../src/runtime/queue/message-queue.ts"],"sourcesContent":["import type {\n AppendMessage,\n FileMessagePart,\n TextMessagePart,\n} from \"../../types/message\";\nimport {\n EMPTY_QUEUE_ITEMS,\n type QueueItemState,\n} from \"../../store/scopes/queue-item\";\nimport { generateId } from \"../../utils/id\";\nimport { notifyEventListeners } from \"../../utils/notify-event-listeners\";\nimport { getThreadMessageText } from \"../../utils/text\";\nimport type {\n ExternalThreadQueueAdapter,\n QueuePlacement,\n} from \"./external-thread-queue-adapter\";\n\nexport type MessageQueueDriver = {\n run: (message: AppendMessage, options: { steer: boolean }) => void;\n /** When omitted, steering degrades to \"process next\" instead of interrupting. */\n cancel?: (() => void) | undefined;\n};\n\nexport type MessageQueueController = {\n readonly adapter: ExternalThreadQueueAdapter;\n /** Mark a run as in flight so concurrent sends buffer; call on the rising edge. */\n notifyBusy: () => void;\n /** Advances to the next pending message; call on the run's falling edge. */\n notifyIdle: () => void;\n /**\n * Pauses queue advance for a user-initiated cancel, so the cancelled run's\n * settle keeps the pending items instead of dispatching the next one; the\n * next explicit send or run start re-arms draining. Call before aborting\n * the run.\n */\n notifyCancelled: () => void;\n /** Empties both lanes without dispatching. */\n clear: () => void;\n subscribe: (callback: () => void) => () => void;\n};\n\ntype Lane = \"queue\" | \"steer\";\n\nconst getQueueItemParts = (\n message: AppendMessage,\n): readonly (FileMessagePart | TextMessagePart)[] => {\n // attachment-derived text is the file body, not user-authored prose;\n // project only the file/image content of attachments\n const source = [\n ...message.content,\n ...(message.attachments ?? []).flatMap((attachment) =>\n (attachment.content ?? []).filter((part) => part.type !== \"text\"),\n ),\n ];\n const parts: (FileMessagePart | TextMessagePart)[] = [];\n for (const part of source) {\n if (part.type === \"file\" || part.type === \"text\") {\n parts.push(part);\n } else if (part.type === \"image\") {\n parts.push({\n type: \"file\",\n data: part.image,\n mimeType: \"image/*\",\n ...(part.filename !== undefined && { filename: part.filename }),\n });\n }\n }\n return parts;\n};\n\nexport const createMessageQueue = (\n driver: MessageQueueDriver,\n): MessageQueueController => {\n let lanes: Record<Lane, readonly QueueItemState[]> = {\n queue: EMPTY_QUEUE_ITEMS,\n steer: EMPTY_QUEUE_ITEMS,\n };\n const messages = new Map<string, AppendMessage>();\n const subscribers = new Set<() => void>();\n\n let running = false;\n let paused = false;\n let dispatchTransform: (message: AppendMessage) => AppendMessage = (m) => m;\n // swallow the cancelled run's settle when steering so it does not double-advance\n let suppressIdle = 0;\n // settles from cancelled runs that must drop `running` without advancing\n let cancelSettles = 0;\n let interrupting = false;\n\n const notify = () => {\n notifyEventListeners(subscribers, undefined, \"Message queue\");\n };\n\n const setLanes = (next: Record<Lane, readonly QueueItemState[]>) => {\n lanes = next;\n adapter.items = next.queue;\n adapter.steerItems = next.steer;\n notify();\n };\n\n const toItem = (id: string, message: AppendMessage): QueueItemState => ({\n id,\n prompt: getThreadMessageText(message),\n parts: getQueueItemParts(message),\n });\n\n const laneOf = (queueItemId: string): Lane | undefined => {\n if (lanes.steer.some((item) => item.id === queueItemId)) return \"steer\";\n if (lanes.queue.some((item) => item.id === queueItemId)) return \"queue\";\n return undefined;\n };\n\n const advance = () => {\n if (running || paused) return;\n const lane: Lane = lanes.steer.length > 0 ? \"steer\" : \"queue\";\n const head = lanes[lane][0];\n if (!head) return;\n const message = messages.get(head.id);\n messages.delete(head.id);\n setLanes({ ...lanes, [lane]: lanes[lane].slice(1) });\n if (!message) return;\n running = true;\n driver.run(dispatchTransform(message), { steer: false });\n };\n\n const interrupt = (message: AppendMessage) => {\n paused = false;\n // the interrupted run settles exactly once, whether or not it was\n // already cancel-notified\n suppressIdle += Math.max(cancelSettles, 1);\n cancelSettles = 0;\n // a driver whose cancel routes through the runtime notifies this queue\n // back; the interrupt already accounted for that settle and is dispatching\n // in its place\n interrupting = true;\n try {\n driver.cancel!();\n } finally {\n interrupting = false;\n }\n running = true;\n driver.run(dispatchTransform(message), { steer: true });\n };\n\n const push = (lane: Lane, message: AppendMessage) => {\n paused = false;\n const id = generateId();\n messages.set(id, message);\n setLanes({ ...lanes, [lane]: [...lanes[lane], toItem(id, message)] });\n advance();\n };\n\n const enqueue = (message: AppendMessage) => {\n push(\"queue\", message);\n };\n\n const steer = (message: AppendMessage) => {\n if (running && driver.cancel) {\n interrupt(message);\n return;\n }\n push(\"steer\", message);\n };\n\n const move = (queueItemId: string, placement: QueuePlacement) => {\n const fromLane = laneOf(queueItemId);\n if (!fromLane) throw new Error(`Unknown queue item \"${queueItemId}\".`);\n const toLane = placement.lane ?? fromLane;\n\n const item = lanes[fromLane].find((i) => i.id === queueItemId)!;\n const dest = (toLane === fromLane ? lanes[fromLane] : lanes[toLane]).filter(\n (i) => i.id !== queueItemId,\n );\n\n const anchorIndex = (anchor: string) => {\n if (anchor === queueItemId)\n throw new Error(`Queue item \"${queueItemId}\" cannot anchor itself.`);\n const index = dest.findIndex((i) => i.id === anchor);\n if (index === -1)\n throw new Error(`Unknown anchor \"${anchor}\" in lane \"${toLane}\".`);\n return index;\n };\n\n const { insertAfter, insertBefore } = placement;\n let index: number;\n if (insertAfter === undefined && insertBefore === undefined) {\n index =\n toLane === fromLane\n ? lanes[fromLane].findIndex((i) => i.id === queueItemId)\n : dest.length;\n } else if (insertAfter !== undefined && insertBefore !== undefined) {\n const after = insertAfter === null ? -1 : anchorIndex(insertAfter);\n const before =\n insertBefore === null ? dest.length : anchorIndex(insertBefore);\n if (before !== after + 1)\n throw new Error(\n `insertAfter \"${insertAfter}\" and insertBefore \"${insertBefore}\" are not adjacent in lane \"${toLane}\".`,\n );\n index = after + 1;\n } else if (insertAfter !== undefined) {\n index = insertAfter === null ? 0 : anchorIndex(insertAfter) + 1;\n } else {\n index = insertBefore === null ? dest.length : anchorIndex(insertBefore!);\n }\n\n // placement and immediate dispatch cannot coexist: an anchored move into\n // the steer lane places without interrupting; only an unanchored one\n // cancels the live run and dispatches\n if (\n insertAfter === undefined &&\n insertBefore === undefined &&\n toLane === \"steer\" &&\n fromLane !== \"steer\" &&\n running &&\n driver.cancel\n ) {\n const message = messages.get(queueItemId)!;\n messages.delete(queueItemId);\n setLanes({\n queue: lanes.queue.filter((i) => i.id !== queueItemId),\n steer: lanes.steer,\n });\n interrupt(message);\n return;\n }\n\n const nextDest = [...dest.slice(0, index), item, ...dest.slice(index)];\n const next = { ...lanes, [toLane]: nextDest };\n if (toLane !== fromLane)\n next[fromLane] = lanes[fromLane].filter((i) => i.id !== queueItemId);\n setLanes(next);\n advance();\n };\n\n const edit = (queueItemId: string, message: AppendMessage) => {\n const lane = laneOf(queueItemId);\n if (!lane) throw new Error(`Unknown queue item \"${queueItemId}\".`);\n messages.set(queueItemId, message);\n setLanes({\n ...lanes,\n [lane]: lanes[lane].map((item) =>\n item.id === queueItemId ? toItem(queueItemId, message) : item,\n ),\n });\n };\n\n const remove = (queueItemId: string) => {\n if (!messages.delete(queueItemId)) return;\n setLanes({\n queue: lanes.queue.filter((item) => item.id !== queueItemId),\n steer: lanes.steer.filter((item) => item.id !== queueItemId),\n });\n };\n\n const notifyCancelled = () => {\n if (interrupting) return;\n if (running && cancelSettles === 0) {\n paused = true;\n cancelSettles = 1;\n }\n };\n\n const adapter: ExternalThreadQueueAdapter = {\n items: lanes.queue,\n steerItems: lanes.steer,\n enqueue,\n steer,\n move,\n edit,\n remove,\n __internal_setDispatchTransform: (transform) => {\n dispatchTransform = transform;\n },\n __internal_notifyCancelled: notifyCancelled,\n };\n\n return {\n adapter,\n notifyBusy: () => {\n paused = false;\n // a cancelled run's settle that is still outstanding belongs to a run\n // this new one replaces; swallow it entirely\n suppressIdle += cancelSettles;\n cancelSettles = 0;\n running = true;\n },\n notifyIdle: () => {\n if (suppressIdle > 0) {\n suppressIdle--;\n return;\n }\n if (cancelSettles > 0) cancelSettles--;\n running = false;\n advance();\n },\n notifyCancelled,\n clear: () => {\n messages.clear();\n setLanes({ queue: EMPTY_QUEUE_ITEMS, steer: EMPTY_QUEUE_ITEMS });\n },\n subscribe: (callback) => {\n subscribers.add(callback);\n return () => {\n subscribers.delete(callback);\n };\n },\n };\n};\n"],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import { ThreadRuntimeCore } from "../interfaces/thread-runtime-core.js";
2
+ //#region src/runtime/utils/thread-runtime-lifecycle.d.ts
3
+ declare const captureThreadRuntimeGeneration: (runtime: ThreadRuntimeCore) => number;
4
+ declare const isThreadRuntimeGenerationCurrent: (runtime: ThreadRuntimeCore, generation: number) => boolean;
5
+ declare const invalidateThreadRuntime: (runtime: ThreadRuntimeCore) => void;
6
+ //#endregion
7
+ export { captureThreadRuntimeGeneration, invalidateThreadRuntime, isThreadRuntimeGenerationCurrent };
8
+ //# sourceMappingURL=thread-runtime-lifecycle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"thread-runtime-lifecycle.d.ts","names":[],"sources":["../../../src/runtime/utils/thread-runtime-lifecycle.ts"],"mappings":";;cAOa,iCAAkC,SAAS;cAG3C,mCACX,SAAS,mBACT;cAGW,0BAA2B,SAAS"}
@@ -0,0 +1,11 @@
1
+ //#region src/runtime/utils/thread-runtime-lifecycle.ts
2
+ const generations = /* @__PURE__ */ new WeakMap();
3
+ const captureThreadRuntimeGeneration = (runtime) => generations.get(runtime) ?? 0;
4
+ const isThreadRuntimeGenerationCurrent = (runtime, generation) => captureThreadRuntimeGeneration(runtime) === generation;
5
+ const invalidateThreadRuntime = (runtime) => {
6
+ generations.set(runtime, captureThreadRuntimeGeneration(runtime) + 1);
7
+ };
8
+ //#endregion
9
+ export { captureThreadRuntimeGeneration, invalidateThreadRuntime, isThreadRuntimeGenerationCurrent };
10
+
11
+ //# sourceMappingURL=thread-runtime-lifecycle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"thread-runtime-lifecycle.js","names":["ThreadRuntimeCore","generations","WeakMap","captureThreadRuntimeGeneration","runtime","get","isThreadRuntimeGenerationCurrent","generation","invalidateThreadRuntime","set"],"sources":["../../../src/runtime/utils/thread-runtime-lifecycle.ts"],"sourcesContent":["import type { ThreadRuntimeCore } from \"../interfaces/thread-runtime-core\";\n\n// Invalidation must stay re-entrant: StrictMode's simulated unmount runs the\n// effect cleanup while the runtime object survives into the next mount, so a\n// permanent disposed mark would swallow every later append.\nconst generations = new WeakMap<ThreadRuntimeCore, number>();\n\nexport const captureThreadRuntimeGeneration = (runtime: ThreadRuntimeCore) =>\n generations.get(runtime) ?? 0;\n\nexport const isThreadRuntimeGenerationCurrent = (\n runtime: ThreadRuntimeCore,\n generation: number,\n) => captureThreadRuntimeGeneration(runtime) === generation;\n\nexport const invalidateThreadRuntime = (runtime: ThreadRuntimeCore) => {\n generations.set(runtime, captureThreadRuntimeGeneration(runtime) + 1);\n};\n"],"mappings":";AAKA,MAAMC,8BAAc,IAAIC,QAAmC;AAE3D,MAAaC,kCAAkCC,YAC7CH,YAAYI,IAAID,OAAO,KAAK;AAE9B,MAAaE,oCACXF,SACAG,eACGJ,+BAA+BC,OAAO,MAAMG;AAEjD,MAAaC,2BAA2BJ,YAA+B;CACrEH,YAAYQ,IAAIL,SAASD,+BAA+BC,OAAO,IAAI,CAAC;AACtE"}
@@ -1 +1 @@
1
- {"version":3,"file":"external-store-shared-options.js","names":["ExternalStoreAdapter","ExternalStoreSharedOptions","Pick","pickExternalStoreSharedOptions","options","isDisabled","isSendDisabled","unstable_capabilities","suggestions","Required","K"],"sources":["../../../src/runtimes/external-store/external-store-shared-options.ts"],"sourcesContent":["import type { ExternalStoreAdapter } from \"./external-store-adapter\";\n\nexport type ExternalStoreSharedOptions = Pick<\n ExternalStoreAdapter,\n \"isDisabled\" | \"isSendDisabled\" | \"unstable_capabilities\" | \"suggestions\"\n>;\n\nexport const pickExternalStoreSharedOptions = (\n options: ExternalStoreSharedOptions,\n): ExternalStoreSharedOptions =>\n ({\n isDisabled: options.isDisabled,\n isSendDisabled: options.isSendDisabled,\n unstable_capabilities: options.unstable_capabilities,\n suggestions: options.suggestions,\n }) satisfies {\n [K in keyof Required<ExternalStoreSharedOptions>]: ExternalStoreSharedOptions[K];\n };\n"],"mappings":";AAOA,MAAaG,kCACXC,aAEC;CACCC,YAAYD,QAAQC;CACpBC,gBAAgBF,QAAQE;CACxBC,uBAAuBH,QAAQG;CAC/BC,aAAaJ,QAAQI;AACvB"}
1
+ {"version":3,"file":"external-store-shared-options.js","names":["ExternalStoreAdapter","ExternalStoreSharedOptions","Pick","pickExternalStoreSharedOptions","options","isDisabled","isSendDisabled","unstable_capabilities","suggestions","Required","K"],"sources":["../../../src/runtimes/external-store/external-store-shared-options.ts"],"sourcesContent":["import type { ExternalStoreAdapter } from \"./external-store-adapter\";\n\nexport type ExternalStoreSharedOptions = Pick<\n ExternalStoreAdapter,\n \"isDisabled\" | \"isSendDisabled\" | \"unstable_capabilities\" | \"suggestions\"\n>;\n\nexport const pickExternalStoreSharedOptions = (\n options: ExternalStoreSharedOptions,\n): ExternalStoreSharedOptions =>\n ({\n isDisabled: options.isDisabled,\n isSendDisabled: options.isSendDisabled,\n unstable_capabilities: options.unstable_capabilities,\n suggestions: options.suggestions,\n }) satisfies {\n [\n K in keyof Required<ExternalStoreSharedOptions>\n ]: ExternalStoreSharedOptions[K];\n };\n"],"mappings":";AAOA,MAAaG,kCACXC,aAEC;CACCC,YAAYD,QAAQC;CACpBC,gBAAgBF,QAAQE;CACxBC,uBAAuBH,QAAQG;CAC/BC,aAAaJ,QAAQI;AACvB"}
@@ -1 +1 @@
1
- {"version":3,"file":"external-store-thread-list-runtime-core.d.ts","names":[],"sources":["../../../src/runtimes/external-store/external-store-thread-list-runtime-core.ts"],"mappings":";;;;;KAQY,mCAAmC;cAgBlC,8CAA8C;UACjD;UACA;UACA;UACA;UAEA;MAEG;MAIA;MAIA;MAIA;MAIA,eAAW,SAAA,eAAA;EAIf,yBAAqB;UAIpB;MAEG;UAIH;EAGN,YAAA,SAAS,4CACT,eAAe;EAMV,4BAAwB;EAIxB;EAIA,YAAY,mBAAgB;EAI5B,sBACL,SAAS,gCACT;EAqFW,oBAAoB;EASpB,eACX,kBACA;IAAa;MACZ;EAUU,qBAAqB;EAUrB,OAAO,kBAAkB,mBAAmB;EAQ5C,aACX,kBACA,QAAQ,sCACP;EAUU,UAAU;EAIV,QAAQ,mBAAmB;EAQ3B,UAAU,mBAAmB;EAQ7B,OAAO,mBAAmB;EAQhC,WACL,mBACC;IAAU;IAAkB;;EAIxB;UAIC;EAED,UAAU,uBAAuB;UAKhC"}
1
+ {"version":3,"file":"external-store-thread-list-runtime-core.d.ts","names":[],"sources":["../../../src/runtimes/external-store/external-store-thread-list-runtime-core.ts"],"mappings":";;;;;KAUY,mCAAmC;cAgBlC,8CAA8C;UACjD;UACA;UACA;UACA;UAEA;MAEG;MAIA;MAIA;MAIA;MAIA,eAAW,SAAA,eAAA;EAIf,yBAAqB;UAIpB;MAEG;UAIH;EAGN,YAAA,SAAS,4CACT,eAAe;EAMV,4BAAwB;EAIxB;EAIA,YAAY,mBAAgB;EAI5B,sBACL,SAAS,gCACT;EAsFW,oBAAoB;EASpB,eACX,kBACA;IAAa;MACZ;EAUU,qBAAqB;EAUrB,OAAO,kBAAkB,mBAAmB;EAQ5C,aACX,kBACA,QAAQ,sCACP;EAUU,UAAU;EAIV,QAAQ,mBAAmB;EAQ3B,UAAU,mBAAmB;EAQ7B,OAAO,mBAAmB;EAQhC,WACL,mBACC;IAAU;IAAkB;;EAIxB;UAIC;EAED,UAAU,uBAAuB;UAKhC"}
@@ -1,3 +1,5 @@
1
+ import { notifySubscribers } from "../../subscribable/subscribable.js";
2
+ import { invalidateThreadRuntime } from "../../runtime/utils/thread-runtime-lifecycle.js";
1
3
  //#region src/runtimes/external-store/external-store-thread-list-runtime-core.ts
2
4
  const EMPTY_ARRAY = Object.freeze([]);
3
5
  const DEFAULT_THREAD_ID = "DEFAULT_THREAD_ID";
@@ -78,6 +80,7 @@ var ExternalStoreThreadListRuntimeCore = class {
78
80
  if (previousThreads !== newThreads) this._threads = this.adapter.threads?.map((t) => t.id) ?? EMPTY_ARRAY;
79
81
  if (previousArchivedThreads !== newArchivedThreads) this._archivedThreads = this.adapter.archivedThreads?.map((t) => t.id) ?? EMPTY_ARRAY;
80
82
  if (initialLoad || previousThreadId !== newThreadId) {
83
+ if (!initialLoad) invalidateThreadRuntime(this._mainThread);
81
84
  this._mainThreadId = newThreadId;
82
85
  this._mainThread = this.threadFactory();
83
86
  }
@@ -148,7 +151,7 @@ var ExternalStoreThreadListRuntimeCore = class {
148
151
  return () => this._subscriptions.delete(callback);
149
152
  }
150
153
  _notifySubscribers() {
151
- for (const callback of this._subscriptions) callback();
154
+ notifySubscribers(this._subscriptions);
152
155
  }
153
156
  };
154
157
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"external-store-thread-list-runtime-core.js","names":["Unsubscribe","ExternalStoreThreadRuntimeCore","ThreadListItemCoreState","ThreadListRuntimeCore","ExternalStoreThreadListAdapter","ExternalStoreThreadFactory","EMPTY_ARRAY","Object","freeze","DEFAULT_THREAD_ID","DEFAULT_THREADS","DEFAULT_THREAD","id","remoteId","undefined","externalId","status","RESOLVED_PROMISE","Promise","resolve","DEFAULT_THREAD_DATA","ExternalStoreThreadListRuntimeCore","_mainThreadId","_threads","_archivedThreads","_threadData","Readonly","Record","adapter","isLoading","newThreadId","threadIds","archivedThreadIds","threadItems","getLoadThreadsPromise","_mainThread","mainThreadId","threadFactory","constructor","__internal_setAdapter","getMainThreadRuntimeCore","getThreadRuntimeCore","Error","getItemById","threadId","initialLoad","previousAdapter","newThreads","threads","newArchivedThreads","archivedThreads","previousThreadId","previousThreads","previousArchivedThreads","fromEntries","map","t","_notifySubscribers","reloadMainThread","unstable_refetchThread","switchToThread","_options","unarchive","onSwitchToThread","switchToNewThread","onSwitchToNewThread","rename","newTitle","onRename","updateCustom","custom","onUpdateCustom","detach","archive","onArchive","onUnarchive","delete","onDelete","initialize","generateTitle","_subscriptions","Set","subscribe","callback","add"],"sources":["../../../src/runtimes/external-store/external-store-thread-list-runtime-core.ts"],"sourcesContent":["import type { Unsubscribe } from \"../../types/unsubscribe\";\nimport type { ExternalStoreThreadRuntimeCore } from \"./external-store-thread-runtime-core\";\nimport type {\n ThreadListItemCoreState,\n ThreadListRuntimeCore,\n} from \"../../runtime/interfaces/thread-list-runtime-core\";\nimport type { ExternalStoreThreadListAdapter } from \"./external-store-adapter\";\n\nexport type ExternalStoreThreadFactory = () => ExternalStoreThreadRuntimeCore;\n\nconst EMPTY_ARRAY = Object.freeze([]);\nconst DEFAULT_THREAD_ID = \"DEFAULT_THREAD_ID\";\nconst DEFAULT_THREADS = Object.freeze([DEFAULT_THREAD_ID]);\nconst DEFAULT_THREAD = Object.freeze({\n id: DEFAULT_THREAD_ID,\n remoteId: undefined,\n externalId: undefined,\n status: \"regular\",\n});\nconst RESOLVED_PROMISE = Promise.resolve();\nconst DEFAULT_THREAD_DATA = Object.freeze({\n [DEFAULT_THREAD_ID]: DEFAULT_THREAD,\n});\n\nexport class ExternalStoreThreadListRuntimeCore implements ThreadListRuntimeCore {\n private _mainThreadId: string = DEFAULT_THREAD_ID;\n private _threads: readonly string[] = DEFAULT_THREADS;\n private _archivedThreads: readonly string[] = EMPTY_ARRAY;\n private _threadData: Readonly<Record<string, ThreadListItemCoreState>> =\n DEFAULT_THREAD_DATA;\n private adapter: ExternalStoreThreadListAdapter = {};\n\n public get isLoading() {\n return this.adapter.isLoading ?? false;\n }\n\n public get newThreadId() {\n return undefined;\n }\n\n public get threadIds() {\n return this._threads;\n }\n\n public get archivedThreadIds() {\n return this._archivedThreads;\n }\n\n public get threadItems() {\n return this._threadData;\n }\n\n public getLoadThreadsPromise() {\n return RESOLVED_PROMISE;\n }\n\n private _mainThread!: ExternalStoreThreadRuntimeCore;\n\n public get mainThreadId() {\n return this._mainThreadId;\n }\n\n private threadFactory: ExternalStoreThreadFactory;\n\n constructor(\n adapter: ExternalStoreThreadListAdapter = {},\n threadFactory: ExternalStoreThreadFactory,\n ) {\n this.threadFactory = threadFactory;\n this.__internal_setAdapter(adapter, true);\n }\n\n public getMainThreadRuntimeCore() {\n return this._mainThread;\n }\n\n public getThreadRuntimeCore(): never {\n throw new Error(\"Method not implemented.\");\n }\n\n public getItemById(threadId: string) {\n return this._threadData[threadId];\n }\n\n public __internal_setAdapter(\n adapter: ExternalStoreThreadListAdapter,\n initialLoad = false,\n ) {\n const previousAdapter = this.adapter;\n this.adapter = adapter;\n\n const newThreadId = adapter.threadId ?? DEFAULT_THREAD_ID;\n const newThreads = adapter.threads ?? EMPTY_ARRAY;\n const newArchivedThreads = adapter.archivedThreads ?? EMPTY_ARRAY;\n\n const previousThreadId = previousAdapter.threadId ?? DEFAULT_THREAD_ID;\n const previousThreads = previousAdapter.threads ?? EMPTY_ARRAY;\n const previousArchivedThreads =\n previousAdapter.archivedThreads ?? EMPTY_ARRAY;\n\n if (\n !initialLoad &&\n previousThreadId === newThreadId &&\n previousThreads === newThreads &&\n previousArchivedThreads === newArchivedThreads\n ) {\n return;\n }\n\n if (\n previousThreads !== newThreads ||\n previousArchivedThreads !== newArchivedThreads ||\n previousThreadId !== newThreadId\n ) {\n this._threadData = {\n ...DEFAULT_THREAD_DATA,\n ...Object.fromEntries(\n adapter.threads?.map((t) => [\n t.id,\n {\n ...t,\n remoteId: t.remoteId,\n externalId: t.externalId,\n status: \"regular\",\n },\n ]) ?? [],\n ),\n ...Object.fromEntries(\n adapter.archivedThreads?.map((t) => [\n t.id,\n {\n ...t,\n remoteId: t.remoteId,\n externalId: t.externalId,\n status: \"archived\",\n },\n ]) ?? [],\n ),\n };\n }\n\n if (previousThreads !== newThreads) {\n this._threads = this.adapter.threads?.map((t) => t.id) ?? EMPTY_ARRAY;\n }\n\n if (previousArchivedThreads !== newArchivedThreads) {\n this._archivedThreads =\n this.adapter.archivedThreads?.map((t) => t.id) ?? EMPTY_ARRAY;\n }\n\n // `initialLoad ||`: `_mainThread!` must be assigned on construction.\n if (initialLoad || previousThreadId !== newThreadId) {\n this._mainThreadId = newThreadId;\n this._mainThread = this.threadFactory();\n }\n\n if (!this._threadData[this._mainThreadId]) {\n this._threadData = {\n ...this._threadData,\n [this._mainThreadId]: {\n id: this._mainThreadId,\n remoteId: undefined,\n externalId: undefined,\n status: \"regular\",\n },\n };\n }\n\n this._notifySubscribers();\n }\n\n public async reloadMainThread(): Promise<void> {\n // There is no runtime hook to remount here, so the capability is the only\n // path and an adapter without it has nothing to refetch with.\n if (!this._mainThread.unstable_refetchThread) return;\n // No unsent-thread guard: every entry here is regular or archived, so the\n // \"new\" status the remote thread list has to exclude cannot occur.\n await this._mainThread.unstable_refetchThread();\n }\n\n public async switchToThread(\n threadId: string,\n _options?: { unarchive?: boolean },\n ): Promise<void> {\n if (this._mainThreadId === threadId) return;\n const onSwitchToThread = this.adapter.onSwitchToThread;\n if (!onSwitchToThread)\n throw new Error(\n \"External store adapter does not support switching to thread\",\n );\n await onSwitchToThread(threadId);\n }\n\n public async switchToNewThread(): Promise<void> {\n const onSwitchToNewThread = this.adapter.onSwitchToNewThread;\n if (!onSwitchToNewThread)\n throw new Error(\n \"External store adapter does not support switching to new thread\",\n );\n\n await onSwitchToNewThread();\n }\n\n public async rename(threadId: string, newTitle: string): Promise<void> {\n const onRename = this.adapter.onRename;\n if (!onRename)\n throw new Error(\"External store adapter does not support renaming\");\n\n await onRename(threadId, newTitle);\n }\n\n public async updateCustom(\n threadId: string,\n custom: Record<string, unknown> | undefined,\n ): Promise<void> {\n const onUpdateCustom = this.adapter.onUpdateCustom;\n if (!onUpdateCustom)\n throw new Error(\n \"External store adapter does not support updating custom metadata\",\n );\n\n await onUpdateCustom(threadId, custom);\n }\n\n public async detach(): Promise<void> {\n // no-op\n }\n\n public async archive(threadId: string): Promise<void> {\n const onArchive = this.adapter.onArchive;\n if (!onArchive)\n throw new Error(\"External store adapter does not support archiving\");\n\n await onArchive(threadId);\n }\n\n public async unarchive(threadId: string): Promise<void> {\n const onUnarchive = this.adapter.onUnarchive;\n if (!onUnarchive)\n throw new Error(\"External store adapter does not support unarchiving\");\n\n await onUnarchive(threadId);\n }\n\n public async delete(threadId: string): Promise<void> {\n const onDelete = this.adapter.onDelete;\n if (!onDelete)\n throw new Error(\"External store adapter does not support deleting\");\n\n await onDelete(threadId);\n }\n\n public initialize(\n threadId: string,\n ): Promise<{ remoteId: string; externalId: string | undefined }> {\n return Promise.resolve({ remoteId: threadId, externalId: undefined });\n }\n\n public generateTitle(): never {\n throw new Error(\"Method not implemented.\");\n }\n\n private _subscriptions = new Set<() => void>();\n\n public subscribe(callback: () => void): Unsubscribe {\n this._subscriptions.add(callback);\n return () => this._subscriptions.delete(callback);\n }\n\n private _notifySubscribers() {\n for (const callback of this._subscriptions) callback();\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"external-store-thread-list-runtime-core.js","names":["Unsubscribe","ExternalStoreThreadRuntimeCore","ThreadListItemCoreState","ThreadListRuntimeCore","ExternalStoreThreadListAdapter","invalidateThreadRuntime","notifySubscribers","ExternalStoreThreadFactory","EMPTY_ARRAY","Object","freeze","DEFAULT_THREAD_ID","DEFAULT_THREADS","DEFAULT_THREAD","id","remoteId","undefined","externalId","status","RESOLVED_PROMISE","Promise","resolve","DEFAULT_THREAD_DATA","ExternalStoreThreadListRuntimeCore","_mainThreadId","_threads","_archivedThreads","_threadData","Readonly","Record","adapter","isLoading","newThreadId","threadIds","archivedThreadIds","threadItems","getLoadThreadsPromise","_mainThread","mainThreadId","threadFactory","constructor","__internal_setAdapter","getMainThreadRuntimeCore","getThreadRuntimeCore","Error","getItemById","threadId","initialLoad","previousAdapter","newThreads","threads","newArchivedThreads","archivedThreads","previousThreadId","previousThreads","previousArchivedThreads","fromEntries","map","t","_notifySubscribers","reloadMainThread","unstable_refetchThread","switchToThread","_options","unarchive","onSwitchToThread","switchToNewThread","onSwitchToNewThread","rename","newTitle","onRename","updateCustom","custom","onUpdateCustom","detach","archive","onArchive","onUnarchive","delete","onDelete","initialize","generateTitle","_subscriptions","Set","subscribe","callback","add"],"sources":["../../../src/runtimes/external-store/external-store-thread-list-runtime-core.ts"],"sourcesContent":["import type { Unsubscribe } from \"../../types/unsubscribe\";\nimport type { ExternalStoreThreadRuntimeCore } from \"./external-store-thread-runtime-core\";\nimport type {\n ThreadListItemCoreState,\n ThreadListRuntimeCore,\n} from \"../../runtime/interfaces/thread-list-runtime-core\";\nimport type { ExternalStoreThreadListAdapter } from \"./external-store-adapter\";\nimport { invalidateThreadRuntime } from \"../../runtime/utils/thread-runtime-lifecycle\";\nimport { notifySubscribers } from \"../../subscribable/subscribable\";\n\nexport type ExternalStoreThreadFactory = () => ExternalStoreThreadRuntimeCore;\n\nconst EMPTY_ARRAY = Object.freeze([]);\nconst DEFAULT_THREAD_ID = \"DEFAULT_THREAD_ID\";\nconst DEFAULT_THREADS = Object.freeze([DEFAULT_THREAD_ID]);\nconst DEFAULT_THREAD = Object.freeze({\n id: DEFAULT_THREAD_ID,\n remoteId: undefined,\n externalId: undefined,\n status: \"regular\",\n});\nconst RESOLVED_PROMISE = Promise.resolve();\nconst DEFAULT_THREAD_DATA = Object.freeze({\n [DEFAULT_THREAD_ID]: DEFAULT_THREAD,\n});\n\nexport class ExternalStoreThreadListRuntimeCore implements ThreadListRuntimeCore {\n private _mainThreadId: string = DEFAULT_THREAD_ID;\n private _threads: readonly string[] = DEFAULT_THREADS;\n private _archivedThreads: readonly string[] = EMPTY_ARRAY;\n private _threadData: Readonly<Record<string, ThreadListItemCoreState>> =\n DEFAULT_THREAD_DATA;\n private adapter: ExternalStoreThreadListAdapter = {};\n\n public get isLoading() {\n return this.adapter.isLoading ?? false;\n }\n\n public get newThreadId() {\n return undefined;\n }\n\n public get threadIds() {\n return this._threads;\n }\n\n public get archivedThreadIds() {\n return this._archivedThreads;\n }\n\n public get threadItems() {\n return this._threadData;\n }\n\n public getLoadThreadsPromise() {\n return RESOLVED_PROMISE;\n }\n\n private _mainThread!: ExternalStoreThreadRuntimeCore;\n\n public get mainThreadId() {\n return this._mainThreadId;\n }\n\n private threadFactory: ExternalStoreThreadFactory;\n\n constructor(\n adapter: ExternalStoreThreadListAdapter = {},\n threadFactory: ExternalStoreThreadFactory,\n ) {\n this.threadFactory = threadFactory;\n this.__internal_setAdapter(adapter, true);\n }\n\n public getMainThreadRuntimeCore() {\n return this._mainThread;\n }\n\n public getThreadRuntimeCore(): never {\n throw new Error(\"Method not implemented.\");\n }\n\n public getItemById(threadId: string) {\n return this._threadData[threadId];\n }\n\n public __internal_setAdapter(\n adapter: ExternalStoreThreadListAdapter,\n initialLoad = false,\n ) {\n const previousAdapter = this.adapter;\n this.adapter = adapter;\n\n const newThreadId = adapter.threadId ?? DEFAULT_THREAD_ID;\n const newThreads = adapter.threads ?? EMPTY_ARRAY;\n const newArchivedThreads = adapter.archivedThreads ?? EMPTY_ARRAY;\n\n const previousThreadId = previousAdapter.threadId ?? DEFAULT_THREAD_ID;\n const previousThreads = previousAdapter.threads ?? EMPTY_ARRAY;\n const previousArchivedThreads =\n previousAdapter.archivedThreads ?? EMPTY_ARRAY;\n\n if (\n !initialLoad &&\n previousThreadId === newThreadId &&\n previousThreads === newThreads &&\n previousArchivedThreads === newArchivedThreads\n ) {\n return;\n }\n\n if (\n previousThreads !== newThreads ||\n previousArchivedThreads !== newArchivedThreads ||\n previousThreadId !== newThreadId\n ) {\n this._threadData = {\n ...DEFAULT_THREAD_DATA,\n ...Object.fromEntries(\n adapter.threads?.map((t) => [\n t.id,\n {\n ...t,\n remoteId: t.remoteId,\n externalId: t.externalId,\n status: \"regular\",\n },\n ]) ?? [],\n ),\n ...Object.fromEntries(\n adapter.archivedThreads?.map((t) => [\n t.id,\n {\n ...t,\n remoteId: t.remoteId,\n externalId: t.externalId,\n status: \"archived\",\n },\n ]) ?? [],\n ),\n };\n }\n\n if (previousThreads !== newThreads) {\n this._threads = this.adapter.threads?.map((t) => t.id) ?? EMPTY_ARRAY;\n }\n\n if (previousArchivedThreads !== newArchivedThreads) {\n this._archivedThreads =\n this.adapter.archivedThreads?.map((t) => t.id) ?? EMPTY_ARRAY;\n }\n\n // `initialLoad ||`: `_mainThread!` must be assigned on construction.\n if (initialLoad || previousThreadId !== newThreadId) {\n if (!initialLoad) invalidateThreadRuntime(this._mainThread);\n this._mainThreadId = newThreadId;\n this._mainThread = this.threadFactory();\n }\n\n if (!this._threadData[this._mainThreadId]) {\n this._threadData = {\n ...this._threadData,\n [this._mainThreadId]: {\n id: this._mainThreadId,\n remoteId: undefined,\n externalId: undefined,\n status: \"regular\",\n },\n };\n }\n\n this._notifySubscribers();\n }\n\n public async reloadMainThread(): Promise<void> {\n // There is no runtime hook to remount here, so the capability is the only\n // path and an adapter without it has nothing to refetch with.\n if (!this._mainThread.unstable_refetchThread) return;\n // No unsent-thread guard: every entry here is regular or archived, so the\n // \"new\" status the remote thread list has to exclude cannot occur.\n await this._mainThread.unstable_refetchThread();\n }\n\n public async switchToThread(\n threadId: string,\n _options?: { unarchive?: boolean },\n ): Promise<void> {\n if (this._mainThreadId === threadId) return;\n const onSwitchToThread = this.adapter.onSwitchToThread;\n if (!onSwitchToThread)\n throw new Error(\n \"External store adapter does not support switching to thread\",\n );\n await onSwitchToThread(threadId);\n }\n\n public async switchToNewThread(): Promise<void> {\n const onSwitchToNewThread = this.adapter.onSwitchToNewThread;\n if (!onSwitchToNewThread)\n throw new Error(\n \"External store adapter does not support switching to new thread\",\n );\n\n await onSwitchToNewThread();\n }\n\n public async rename(threadId: string, newTitle: string): Promise<void> {\n const onRename = this.adapter.onRename;\n if (!onRename)\n throw new Error(\"External store adapter does not support renaming\");\n\n await onRename(threadId, newTitle);\n }\n\n public async updateCustom(\n threadId: string,\n custom: Record<string, unknown> | undefined,\n ): Promise<void> {\n const onUpdateCustom = this.adapter.onUpdateCustom;\n if (!onUpdateCustom)\n throw new Error(\n \"External store adapter does not support updating custom metadata\",\n );\n\n await onUpdateCustom(threadId, custom);\n }\n\n public async detach(): Promise<void> {\n // no-op\n }\n\n public async archive(threadId: string): Promise<void> {\n const onArchive = this.adapter.onArchive;\n if (!onArchive)\n throw new Error(\"External store adapter does not support archiving\");\n\n await onArchive(threadId);\n }\n\n public async unarchive(threadId: string): Promise<void> {\n const onUnarchive = this.adapter.onUnarchive;\n if (!onUnarchive)\n throw new Error(\"External store adapter does not support unarchiving\");\n\n await onUnarchive(threadId);\n }\n\n public async delete(threadId: string): Promise<void> {\n const onDelete = this.adapter.onDelete;\n if (!onDelete)\n throw new Error(\"External store adapter does not support deleting\");\n\n await onDelete(threadId);\n }\n\n public initialize(\n threadId: string,\n ): Promise<{ remoteId: string; externalId: string | undefined }> {\n return Promise.resolve({ remoteId: threadId, externalId: undefined });\n }\n\n public generateTitle(): never {\n throw new Error(\"Method not implemented.\");\n }\n\n private _subscriptions = new Set<() => void>();\n\n public subscribe(callback: () => void): Unsubscribe {\n this._subscriptions.add(callback);\n return () => this._subscriptions.delete(callback);\n }\n\n private _notifySubscribers() {\n notifySubscribers(this._subscriptions);\n }\n}\n"],"mappings":";;;AAYA,MAAMQ,cAAcC,OAAOC,OAAO,CAAA,CAAE;AACpC,MAAMC,oBAAoB;AAC1B,MAAMC,kBAAkBH,OAAOC,OAAO,CAACC,iBAAiB,CAAC;AACzD,MAAME,iBAAiBJ,OAAOC,OAAO;CACnCI,IAAIH;CACJI,UAAUC,KAAAA;CACVC,YAAYD,KAAAA;CACZE,QAAQ;AACV,CAAC;AACD,MAAMC,mBAAmBC,QAAQC,QAAQ;AACzC,MAAMC,sBAAsBb,OAAOC,OAAO,GACvCC,oBAAoBE,eACvB,CAAC;AAED,IAAaU,qCAAb,MAAiF;CAC/E,gBAAgCZ;CAChC,WAAsCC;CACtC,mBAA8CJ;CAC9C,cACEc;CACF,UAAkD,CAAC;CAEnD,IAAWS,YAAY;EACrB,OAAO,KAAKD,QAAQC,aAAa;CACnC;CAEA,IAAWC,cAAc,CAEzB;CAEA,IAAWC,YAAY;EACrB,OAAO,KAAKR;CACd;CAEA,IAAWS,oBAAoB;EAC7B,OAAO,KAAKR;CACd;CAEA,IAAWS,cAAc;EACvB,OAAO,KAAKR;CACd;CAEA,wBAA+B;EAC7B,OAAOR;CACT;CAEA;CAEA,IAAWmB,eAAe;EACxB,OAAO,KAAKd;CACd;CAEA;CAEAgB,YACEV,UAA0C,CAAC,GAC3CS,eACA;EACA,KAAKA,gBAAgBA;EACrB,KAAKE,sBAAsBX,SAAS,IAAI;CAC1C;CAEA,2BAAkC;EAChC,OAAO,KAAKO;CACd;CAEA,uBAAqC;EACnC,MAAM,IAAIO,MAAM,yBAAyB;CAC3C;CAEA,YAAmBE,UAAkB;EACnC,OAAO,KAAKnB,YAAYmB;CAC1B;CAEA,sBACEhB,SACAiB,cAAc,OACd;EACA,MAAMC,kBAAkB,KAAKlB;EAC7B,KAAKA,UAAUA;EAEf,MAAME,cAAcF,QAAQgB,YAAYnC;EACxC,MAAMsC,aAAanB,QAAQoB,WAAW1C;EACtC,MAAM2C,qBAAqBrB,QAAQsB,mBAAmB5C;EAEtD,MAAM6C,mBAAmBL,gBAAgBF,YAAYnC;EACrD,MAAM2C,kBAAkBN,gBAAgBE,WAAW1C;EACnD,MAAM+C,0BACJP,gBAAgBI,mBAAmB5C;EAErC,IACE,CAACuC,eACDM,qBAAqBrB,eACrBsB,oBAAoBL,cACpBM,4BAA4BJ,oBAE5B;EAGF,IACEG,oBAAoBL,cACpBM,4BAA4BJ,sBAC5BE,qBAAqBrB,aAErB,KAAKL,cAAc;GACjB,GAAGL;GACH,GAAGb,OAAO+C,YACR1B,QAAQoB,SAASO,KAAKC,MAAM,CAC1BA,EAAE5C,IACF;IACE,GAAG4C;IACH3C,UAAU2C,EAAE3C;IACZE,YAAYyC,EAAEzC;IACdC,QAAQ;GACV,CAAC,CACF,KAAK,CAAA,CACR;GACA,GAAGT,OAAO+C,YACR1B,QAAQsB,iBAAiBK,KAAKC,MAAM,CAClCA,EAAE5C,IACF;IACE,GAAG4C;IACH3C,UAAU2C,EAAE3C;IACZE,YAAYyC,EAAEzC;IACdC,QAAQ;GACV,CAAC,CACF,KAAK,CAAA,CACR;EACF;EAGF,IAAIoC,oBAAoBL,YACtB,KAAKxB,WAAW,KAAKK,QAAQoB,SAASO,KAAKC,MAAMA,EAAE5C,EAAE,KAAKN;EAG5D,IAAI+C,4BAA4BJ,oBAC9B,KAAKzB,mBACH,KAAKI,QAAQsB,iBAAiBK,KAAKC,MAAMA,EAAE5C,EAAE,KAAKN;EAItD,IAAIuC,eAAeM,qBAAqBrB,aAAa;GACnD,IAAI,CAACe,aAAa1C,wBAAwB,KAAKgC,WAAW;GAC1D,KAAKb,gBAAgBQ;GACrB,KAAKK,cAAc,KAAKE,cAAc;EACxC;EAEA,IAAI,CAAC,KAAKZ,YAAY,KAAKH,gBACzB,KAAKG,cAAc;GACjB,GAAG,KAAKA;IACP,KAAKH,gBAAgB;IACpBV,IAAI,KAAKU;IACTT,UAAUC,KAAAA;IACVC,YAAYD,KAAAA;IACZE,QAAQ;GACV;EACF;EAGF,KAAKyC,mBAAmB;CAC1B;CAEA,MAAaC,mBAAkC;EAG7C,IAAI,CAAC,KAAKvB,YAAYwB,wBAAwB;EAG9C,MAAM,KAAKxB,YAAYwB,uBAAuB;CAChD;CAEA,MAAaC,eACXhB,UACAiB,UACe;EACf,IAAI,KAAKvC,kBAAkBsB,UAAU;EACrC,MAAMmB,mBAAmB,KAAKnC,QAAQmC;EACtC,IAAI,CAACA,kBACH,MAAM,IAAIrB,MACR,6DACF;EACF,MAAMqB,iBAAiBnB,QAAQ;CACjC;CAEA,MAAaoB,oBAAmC;EAC9C,MAAMC,sBAAsB,KAAKrC,QAAQqC;EACzC,IAAI,CAACA,qBACH,MAAM,IAAIvB,MACR,iEACF;EAEF,MAAMuB,oBAAoB;CAC5B;CAEA,MAAaC,OAAOtB,UAAkBuB,UAAiC;EACrE,MAAMC,WAAW,KAAKxC,QAAQwC;EAC9B,IAAI,CAACA,UACH,MAAM,IAAI1B,MAAM,kDAAkD;EAEpE,MAAM0B,SAASxB,UAAUuB,QAAQ;CACnC;CAEA,MAAaE,aACXzB,UACA0B,QACe;EACf,MAAMC,iBAAiB,KAAK3C,QAAQ2C;EACpC,IAAI,CAACA,gBACH,MAAM,IAAI7B,MACR,kEACF;EAEF,MAAM6B,eAAe3B,UAAU0B,MAAM;CACvC;CAEA,MAAaE,SAAwB,CACnC;CAGF,MAAaC,QAAQ7B,UAAiC;EACpD,MAAM8B,YAAY,KAAK9C,QAAQ8C;EAC/B,IAAI,CAACA,WACH,MAAM,IAAIhC,MAAM,mDAAmD;EAErE,MAAMgC,UAAU9B,QAAQ;CAC1B;CAEA,MAAakB,UAAUlB,UAAiC;EACtD,MAAM+B,cAAc,KAAK/C,QAAQ+C;EACjC,IAAI,CAACA,aACH,MAAM,IAAIjC,MAAM,qDAAqD;EAEvE,MAAMiC,YAAY/B,QAAQ;CAC5B;CAEA,MAAagC,OAAOhC,UAAiC;EACnD,MAAMiC,WAAW,KAAKjD,QAAQiD;EAC9B,IAAI,CAACA,UACH,MAAM,IAAInC,MAAM,kDAAkD;EAEpE,MAAMmC,SAASjC,QAAQ;CACzB;CAEA,WACEA,UAC+D;EAC/D,OAAO1B,QAAQC,QAAQ;GAAEN,UAAU+B;GAAU7B,YAAYD,KAAAA;EAAU,CAAC;CACtE;CAEA,gBAA8B;EAC5B,MAAM,IAAI4B,MAAM,yBAAyB;CAC3C;CAEA,iCAAyB,IAAIuC,IAAgB;CAE7C,UAAiBE,UAAmC;EAClD,KAAKH,eAAeI,IAAID,QAAQ;EAChC,aAAa,KAAKH,eAAeJ,OAAOO,QAAQ;CAClD;CAEA,qBAA6B;EAC3B/E,kBAAkB,KAAK4E,cAAc;CACvC;AACF"}
@@ -38,6 +38,8 @@ declare class ExternalStoreThreadRuntimeCore extends BaseThreadRuntimeCore imple
38
38
  extras: unknown;
39
39
  private _converter;
40
40
  private _store;
41
+ private _getInitializePromise?;
42
+ __internal_setGetInitializePromise(getPromise: () => Promise<unknown> | undefined): void;
41
43
  private _transformedQueue;
42
44
  /**
43
45
  * Client-side tool-invocations pipeline. Constructed lazily on first
@@ -87,6 +89,12 @@ declare class ExternalStoreThreadRuntimeCore extends BaseThreadRuntimeCore imple
87
89
  resumeRun(config: ResumeRunConfig): Promise<void>;
88
90
  exportExternalState(): any;
89
91
  importExternalState(state: any): void;
92
+ /**
93
+ * Adapter-facing notification that the backing session was discarded.
94
+ * Clears session-scoped tool-invocation state and parks queued work,
95
+ * without run-cancel semantics (`onCancel`, composer draft restoration).
96
+ */
97
+ unstable_notifySessionReset(): void;
90
98
  cancelRun(): void;
91
99
  private dropEmptyOptimisticHead;
92
100
  addToolResult(options: AddToolResultOptions): void;