@assistant-ui/core 0.2.22 → 0.3.0

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 (349) hide show
  1. package/dist/adapters/thread-history.d.ts +8 -0
  2. package/dist/adapters/thread-history.d.ts.map +1 -1
  3. package/dist/internal.d.ts +3 -2
  4. package/dist/internal.js +3 -2
  5. package/dist/model-context/frame/host.d.ts.map +1 -1
  6. package/dist/model-context/frame/host.js +36 -21
  7. package/dist/model-context/frame/host.js.map +1 -1
  8. package/dist/model-context/types.d.ts.map +1 -1
  9. package/dist/model-context/types.js +13 -4
  10. package/dist/model-context/types.js.map +1 -1
  11. package/dist/react/adapters/LocalStorageThreadListAdapter.d.ts.map +1 -1
  12. package/dist/react/adapters/LocalStorageThreadListAdapter.js +3 -2
  13. package/dist/react/adapters/LocalStorageThreadListAdapter.js.map +1 -1
  14. package/dist/react/client/Tools.d.ts.map +1 -1
  15. package/dist/react/client/Tools.js +40 -55
  16. package/dist/react/client/Tools.js.map +1 -1
  17. package/dist/react/client/interactable-model-context.js +1 -0
  18. package/dist/react/client/interactable-model-context.js.map +1 -1
  19. package/dist/react/interactables-legacy/useAssistantInteractable.js +1 -1
  20. package/dist/react/interactables-legacy/useAssistantInteractable.js.map +1 -1
  21. package/dist/react/interactables-legacy/useInteractableState.js +4 -3
  22. package/dist/react/interactables-legacy/useInteractableState.js.map +1 -1
  23. package/dist/react/model-context/useAssistantContext.js +1 -1
  24. package/dist/react/model-context/useAssistantContext.js.map +1 -1
  25. package/dist/react/model-context/useAssistantDataUI.js +1 -1
  26. package/dist/react/model-context/useAssistantDataUI.js.map +1 -1
  27. package/dist/react/model-context/useAssistantInstructions.js +1 -1
  28. package/dist/react/model-context/useAssistantInstructions.js.map +1 -1
  29. package/dist/react/model-context/useAssistantTool.js +29 -25
  30. package/dist/react/model-context/useAssistantTool.js.map +1 -1
  31. package/dist/react/model-context/useAssistantToolUI.js +1 -1
  32. package/dist/react/model-context/useAssistantToolUI.js.map +1 -1
  33. package/dist/react/model-context/useAuiToolOverrides.js +1 -1
  34. package/dist/react/model-context/useAuiToolOverrides.js.map +1 -1
  35. package/dist/react/model-context/useInteractable.js +1 -1
  36. package/dist/react/model-context/useInteractable.js.map +1 -1
  37. package/dist/react/model-context/useInteractableState.js +3 -2
  38. package/dist/react/model-context/useInteractableState.js.map +1 -1
  39. package/dist/react/model-context/useInteractableVersions.js +1 -0
  40. package/dist/react/model-context/useInteractableVersions.js.map +1 -1
  41. package/dist/react/model-context/useToolArgsStatus.js +1 -0
  42. package/dist/react/model-context/useToolArgsStatus.js.map +1 -1
  43. package/dist/react/primitive-hooks/useActionBarCopy.js +4 -3
  44. package/dist/react/primitive-hooks/useActionBarCopy.js.map +1 -1
  45. package/dist/react/primitive-hooks/useActionBarEdit.js +2 -1
  46. package/dist/react/primitive-hooks/useActionBarEdit.js.map +1 -1
  47. package/dist/react/primitive-hooks/useActionBarFeedback.js +3 -2
  48. package/dist/react/primitive-hooks/useActionBarFeedback.js.map +1 -1
  49. package/dist/react/primitive-hooks/useActionBarReload.js +2 -1
  50. package/dist/react/primitive-hooks/useActionBarReload.js.map +1 -1
  51. package/dist/react/primitive-hooks/useActionBarSpeak.js +2 -1
  52. package/dist/react/primitive-hooks/useActionBarSpeak.js.map +1 -1
  53. package/dist/react/primitive-hooks/useActionBarStopSpeaking.js +2 -1
  54. package/dist/react/primitive-hooks/useActionBarStopSpeaking.js.map +1 -1
  55. package/dist/react/primitive-hooks/useBranchPickerNext.js +2 -1
  56. package/dist/react/primitive-hooks/useBranchPickerNext.js.map +1 -1
  57. package/dist/react/primitive-hooks/useBranchPickerPrevious.js +2 -1
  58. package/dist/react/primitive-hooks/useBranchPickerPrevious.js.map +1 -1
  59. package/dist/react/primitive-hooks/useComposerAddAttachment.js +2 -1
  60. package/dist/react/primitive-hooks/useComposerAddAttachment.js.map +1 -1
  61. package/dist/react/primitive-hooks/useComposerCancel.js +2 -1
  62. package/dist/react/primitive-hooks/useComposerCancel.js.map +1 -1
  63. package/dist/react/primitive-hooks/useComposerDictate.js +2 -1
  64. package/dist/react/primitive-hooks/useComposerDictate.js.map +1 -1
  65. package/dist/react/primitive-hooks/useComposerSend.js +2 -1
  66. package/dist/react/primitive-hooks/useComposerSend.js.map +1 -1
  67. package/dist/react/primitive-hooks/useEditComposerCancel.js +2 -1
  68. package/dist/react/primitive-hooks/useEditComposerCancel.js.map +1 -1
  69. package/dist/react/primitive-hooks/useEditComposerSend.js +2 -1
  70. package/dist/react/primitive-hooks/useEditComposerSend.js.map +1 -1
  71. package/dist/react/primitive-hooks/useMessageBranching.js +3 -2
  72. package/dist/react/primitive-hooks/useMessageBranching.js.map +1 -1
  73. package/dist/react/primitive-hooks/useMessageReload.js +2 -1
  74. package/dist/react/primitive-hooks/useMessageReload.js.map +1 -1
  75. package/dist/react/primitive-hooks/useSuggestionTrigger.js +8 -7
  76. package/dist/react/primitive-hooks/useSuggestionTrigger.js.map +1 -1
  77. package/dist/react/primitive-hooks/useThreadListItemArchive.js +2 -1
  78. package/dist/react/primitive-hooks/useThreadListItemArchive.js.map +1 -1
  79. package/dist/react/primitive-hooks/useThreadListItemDelete.js +2 -1
  80. package/dist/react/primitive-hooks/useThreadListItemDelete.js.map +1 -1
  81. package/dist/react/primitive-hooks/useThreadListItemTrigger.js +2 -1
  82. package/dist/react/primitive-hooks/useThreadListItemTrigger.js.map +1 -1
  83. package/dist/react/primitive-hooks/useThreadListItemUnarchive.js +2 -1
  84. package/dist/react/primitive-hooks/useThreadListItemUnarchive.js.map +1 -1
  85. package/dist/react/primitive-hooks/useThreadListLoadMore.js +2 -1
  86. package/dist/react/primitive-hooks/useThreadListLoadMore.js.map +1 -1
  87. package/dist/react/primitive-hooks/useThreadListNew.js +2 -1
  88. package/dist/react/primitive-hooks/useThreadListNew.js.map +1 -1
  89. package/dist/react/primitive-hooks/useVoice.js +5 -13
  90. package/dist/react/primitive-hooks/useVoice.js.map +1 -1
  91. package/dist/react/primitives/chainOfThought/ChainOfThoughtParts.js +1 -1
  92. package/dist/react/primitives/chainOfThought/ChainOfThoughtParts.js.map +1 -1
  93. package/dist/react/primitives/composer/ComposerAttachments.js +1 -1
  94. package/dist/react/primitives/composer/ComposerAttachments.js.map +1 -1
  95. package/dist/react/primitives/composer/ComposerQueue.d.ts.map +1 -1
  96. package/dist/react/primitives/composer/ComposerQueue.js +1 -1
  97. package/dist/react/primitives/composer/ComposerQueue.js.map +1 -1
  98. package/dist/react/primitives/message/MessageAttachments.d.ts.map +1 -1
  99. package/dist/react/primitives/message/MessageAttachments.js +1 -1
  100. package/dist/react/primitives/message/MessageAttachments.js.map +1 -1
  101. package/dist/react/primitives/message/MessageParts.js +84 -122
  102. package/dist/react/primitives/message/MessageParts.js.map +1 -1
  103. package/dist/react/primitives/thread/ThreadMessages.js +1 -1
  104. package/dist/react/primitives/thread/ThreadMessages.js.map +1 -1
  105. package/dist/react/primitives/thread/ThreadSuggestions.js +1 -1
  106. package/dist/react/primitives/thread/ThreadSuggestions.js.map +1 -1
  107. package/dist/react/primitives/threadList/ThreadListItems.js +1 -1
  108. package/dist/react/primitives/threadList/ThreadListItems.js.map +1 -1
  109. package/dist/react/providers/AttachmentByIndexProvider.js +2 -2
  110. package/dist/react/providers/AttachmentByIndexProvider.js.map +1 -1
  111. package/dist/react/providers/ChainOfThoughtByIndicesProvider.js +1 -1
  112. package/dist/react/providers/ChainOfThoughtByIndicesProvider.js.map +1 -1
  113. package/dist/react/providers/ChainOfThoughtPartByIndexProvider.d.ts.map +1 -1
  114. package/dist/react/providers/ChainOfThoughtPartByIndexProvider.js +30 -18
  115. package/dist/react/providers/ChainOfThoughtPartByIndexProvider.js.map +1 -1
  116. package/dist/react/providers/MessageByIdProvider.js +2 -2
  117. package/dist/react/providers/MessageByIdProvider.js.map +1 -1
  118. package/dist/react/providers/MessageByIndexProvider.js +2 -2
  119. package/dist/react/providers/MessageByIndexProvider.js.map +1 -1
  120. package/dist/react/providers/PartByIndexProvider.d.ts.map +1 -1
  121. package/dist/react/providers/PartByIndexProvider.js +30 -18
  122. package/dist/react/providers/PartByIndexProvider.js.map +1 -1
  123. package/dist/react/providers/QueueItemByIndexProvider.js +1 -1
  124. package/dist/react/providers/QueueItemByIndexProvider.js.map +1 -1
  125. package/dist/react/providers/ReadonlyThreadProvider.js +1 -1
  126. package/dist/react/providers/ReadonlyThreadProvider.js.map +1 -1
  127. package/dist/react/providers/SuggestionByIndexProvider.js +1 -1
  128. package/dist/react/providers/SuggestionByIndexProvider.js.map +1 -1
  129. package/dist/react/providers/TextMessagePartProvider.js +1 -0
  130. package/dist/react/providers/TextMessagePartProvider.js.map +1 -1
  131. package/dist/react/providers/ThreadListItemByIndexProvider.js +1 -1
  132. package/dist/react/providers/ThreadListItemByIndexProvider.js.map +1 -1
  133. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js +3 -3
  134. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js.map +1 -1
  135. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts.map +1 -1
  136. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js +6 -4
  137. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js.map +1 -1
  138. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.d.ts +31 -1
  139. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.d.ts.map +1 -1
  140. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.js +42 -20
  141. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.js.map +1 -1
  142. package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.d.ts +1 -1
  143. package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.d.ts.map +1 -1
  144. package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.js +1 -1
  145. package/dist/react/runtimes/cloud/CloudFileAttachmentAdapter.js.map +1 -1
  146. package/dist/react/runtimes/cloud/auiV0.d.ts +12 -1
  147. package/dist/react/runtimes/cloud/auiV0.d.ts.map +1 -1
  148. package/dist/react/runtimes/cloud/auiV0.js +2 -1
  149. package/dist/react/runtimes/cloud/auiV0.js.map +1 -1
  150. package/dist/react/runtimes/cloud/useCloudThreadListAdapter.js +75 -73
  151. package/dist/react/runtimes/cloud/useCloudThreadListAdapter.js.map +1 -1
  152. package/dist/react/runtimes/createRuntimeExtras.js +1 -1
  153. package/dist/react/runtimes/createRuntimeExtras.js.map +1 -1
  154. package/dist/react/runtimes/external-message-converter.js +1 -1
  155. package/dist/react/runtimes/external-message-converter.js.map +1 -1
  156. package/dist/react/runtimes/useExternalStoreSharedOptions.js +1 -0
  157. package/dist/react/runtimes/useExternalStoreSharedOptions.js.map +1 -1
  158. package/dist/react/runtimes/useLocalRuntime.d.ts +0 -1
  159. package/dist/react/runtimes/useLocalRuntime.d.ts.map +1 -1
  160. package/dist/react/types/scopes/tools.d.ts +0 -6
  161. package/dist/react/types/scopes/tools.d.ts.map +1 -1
  162. package/dist/react/utils/groupParts.d.ts +1 -3
  163. package/dist/react/utils/groupParts.d.ts.map +1 -1
  164. package/dist/react/utils/groupParts.js +1 -3
  165. package/dist/react/utils/groupParts.js.map +1 -1
  166. package/dist/runtime/api/assistant-runtime.d.ts +1 -1
  167. package/dist/runtime/api/assistant-runtime.d.ts.map +1 -1
  168. package/dist/runtime/api/assistant-runtime.js +1 -1
  169. package/dist/runtime/api/assistant-runtime.js.map +1 -1
  170. package/dist/runtime/api/attachment-runtime.d.ts +1 -1
  171. package/dist/runtime/api/attachment-runtime.d.ts.map +1 -1
  172. package/dist/runtime/api/attachment-runtime.js +1 -1
  173. package/dist/runtime/api/attachment-runtime.js.map +1 -1
  174. package/dist/runtime/api/composer-runtime.d.ts +2 -2
  175. package/dist/runtime/api/composer-runtime.d.ts.map +1 -1
  176. package/dist/runtime/api/composer-runtime.js +2 -2
  177. package/dist/runtime/api/composer-runtime.js.map +1 -1
  178. package/dist/runtime/api/message-part-runtime.d.ts +4 -4
  179. package/dist/runtime/api/message-part-runtime.d.ts.map +1 -1
  180. package/dist/runtime/api/message-part-runtime.js +3 -3
  181. package/dist/runtime/api/message-part-runtime.js.map +1 -1
  182. package/dist/runtime/api/message-runtime.d.ts +1 -1
  183. package/dist/runtime/api/message-runtime.d.ts.map +1 -1
  184. package/dist/runtime/api/message-runtime.js +2 -2
  185. package/dist/runtime/api/message-runtime.js.map +1 -1
  186. package/dist/runtime/api/thread-list-item-runtime.d.ts +1 -1
  187. package/dist/runtime/api/thread-list-item-runtime.d.ts.map +1 -1
  188. package/dist/runtime/api/thread-list-item-runtime.js +2 -2
  189. package/dist/runtime/api/thread-list-item-runtime.js.map +1 -1
  190. package/dist/runtime/api/thread-list-runtime.d.ts +1 -1
  191. package/dist/runtime/api/thread-list-runtime.d.ts.map +1 -1
  192. package/dist/runtime/api/thread-list-runtime.js +1 -1
  193. package/dist/runtime/api/thread-list-runtime.js.map +1 -1
  194. package/dist/runtime/base/base-thread-runtime-core.d.ts +1 -1
  195. package/dist/runtime/base/base-thread-runtime-core.d.ts.map +1 -1
  196. package/dist/runtime/base/base-thread-runtime-core.js +1 -1
  197. package/dist/runtime/base/base-thread-runtime-core.js.map +1 -1
  198. package/dist/runtime/base/default-edit-composer-runtime-core.d.ts +2 -2
  199. package/dist/runtime/base/default-edit-composer-runtime-core.d.ts.map +1 -1
  200. package/dist/runtime/base/default-edit-composer-runtime-core.js +2 -2
  201. package/dist/runtime/base/default-edit-composer-runtime-core.js.map +1 -1
  202. package/dist/runtime/base/default-thread-composer-runtime-core.d.ts +1 -1
  203. package/dist/runtime/base/default-thread-composer-runtime-core.d.ts.map +1 -1
  204. package/dist/runtime/base/default-thread-composer-runtime-core.js +1 -1
  205. package/dist/runtime/base/default-thread-composer-runtime-core.js.map +1 -1
  206. package/dist/runtime/utils/message-repository.d.ts.map +1 -1
  207. package/dist/runtime/utils/message-repository.js +4 -2
  208. package/dist/runtime/utils/message-repository.js.map +1 -1
  209. package/dist/runtimes/external-store/external-store-thread-list-runtime-core.d.ts +1 -1
  210. package/dist/runtimes/external-store/external-store-thread-list-runtime-core.d.ts.map +1 -1
  211. package/dist/runtimes/external-store/external-store-thread-list-runtime-core.js +1 -1
  212. package/dist/runtimes/external-store/external-store-thread-list-runtime-core.js.map +1 -1
  213. package/dist/runtimes/external-store/external-store-thread-runtime-core.d.ts.map +1 -1
  214. package/dist/runtimes/external-store/external-store-thread-runtime-core.js +12 -0
  215. package/dist/runtimes/external-store/external-store-thread-runtime-core.js.map +1 -1
  216. package/dist/runtimes/internal.d.ts +2 -1
  217. package/dist/runtimes/internal.js +2 -1
  218. package/dist/runtimes/local/local-thread-runtime-core.d.ts +3 -0
  219. package/dist/runtimes/local/local-thread-runtime-core.d.ts.map +1 -1
  220. package/dist/runtimes/local/local-thread-runtime-core.js +44 -13
  221. package/dist/runtimes/local/local-thread-runtime-core.js.map +1 -1
  222. package/dist/runtimes/tool-invocations/ToolInvocationTracker.d.ts +32 -27
  223. package/dist/runtimes/tool-invocations/ToolInvocationTracker.d.ts.map +1 -1
  224. package/dist/runtimes/tool-invocations/ToolInvocationTracker.js +2 -0
  225. package/dist/runtimes/tool-invocations/ToolInvocationTracker.js.map +1 -1
  226. package/dist/store/clients/no-op-composer-client.js +1 -0
  227. package/dist/store/clients/no-op-composer-client.js.map +1 -1
  228. package/dist/store/clients/runtime-adapter.js +3 -3
  229. package/dist/store/clients/runtime-adapter.js.map +1 -1
  230. package/dist/store/runtime-clients/thread-list-runtime-client.js +1 -0
  231. package/dist/store/runtime-clients/thread-list-runtime-client.js.map +1 -1
  232. package/dist/store/runtime-clients/thread-runtime-client.d.ts.map +1 -1
  233. package/dist/store/runtime-clients/thread-runtime-client.js +17 -15
  234. package/dist/store/runtime-clients/thread-runtime-client.js.map +1 -1
  235. package/dist/store/scopes/thread.d.ts +1 -0
  236. package/dist/store/scopes/thread.d.ts.map +1 -1
  237. package/dist/subscribable/subscribable.d.ts +3 -3
  238. package/dist/subscribable/subscribable.d.ts.map +1 -1
  239. package/dist/subscribable/subscribable.js +3 -3
  240. package/dist/subscribable/subscribable.js.map +1 -1
  241. package/package.json +8 -8
  242. package/src/adapters/thread-history.ts +8 -0
  243. package/src/internal.ts +1 -1
  244. package/src/model-context/frame/host.test.ts +47 -0
  245. package/src/model-context/frame/host.ts +46 -19
  246. package/src/model-context/types.ts +16 -6
  247. package/src/react/adapters/LocalStorageThreadListAdapter.tsx +17 -7
  248. package/src/react/client/Tools.ts +0 -7
  249. package/src/react/interactables-legacy/useAssistantInteractable.ts +1 -1
  250. package/src/react/interactables-legacy/useInteractableState.ts +3 -3
  251. package/src/react/model-context/useAssistantContext.ts +1 -1
  252. package/src/react/model-context/useAssistantDataUI.ts +1 -1
  253. package/src/react/model-context/useAssistantInstructions.ts +1 -1
  254. package/src/react/model-context/useAssistantTool.ts +2 -2
  255. package/src/react/model-context/useAssistantToolUI.ts +1 -1
  256. package/src/react/model-context/useAuiToolOverrides.ts +1 -1
  257. package/src/react/model-context/useInteractable.ts +1 -1
  258. package/src/react/model-context/useInteractableState.ts +2 -2
  259. package/src/react/primitive-hooks/useActionBarCopy.test.ts +2 -2
  260. package/src/react/primitive-hooks/useActionBarCopy.ts +3 -3
  261. package/src/react/primitive-hooks/useActionBarEdit.ts +1 -1
  262. package/src/react/primitive-hooks/useActionBarFeedback.ts +2 -2
  263. package/src/react/primitive-hooks/useActionBarReload.ts +1 -1
  264. package/src/react/primitive-hooks/useActionBarSpeak.ts +1 -1
  265. package/src/react/primitive-hooks/useActionBarStopSpeaking.ts +1 -1
  266. package/src/react/primitive-hooks/useBranchPickerNext.ts +1 -1
  267. package/src/react/primitive-hooks/useBranchPickerPrevious.ts +1 -1
  268. package/src/react/primitive-hooks/useComposerAddAttachment.ts +1 -1
  269. package/src/react/primitive-hooks/useComposerCancel.ts +1 -1
  270. package/src/react/primitive-hooks/useComposerDictate.ts +1 -1
  271. package/src/react/primitive-hooks/useComposerSend.ts +1 -1
  272. package/src/react/primitive-hooks/useEditComposerCancel.ts +1 -1
  273. package/src/react/primitive-hooks/useEditComposerSend.ts +1 -1
  274. package/src/react/primitive-hooks/useMessageBranching.ts +2 -2
  275. package/src/react/primitive-hooks/useMessageReload.ts +1 -1
  276. package/src/react/primitive-hooks/useSuggestionTrigger.ts +9 -9
  277. package/src/react/primitive-hooks/useThreadListItemArchive.ts +1 -1
  278. package/src/react/primitive-hooks/useThreadListItemDelete.ts +1 -1
  279. package/src/react/primitive-hooks/useThreadListItemTrigger.ts +1 -1
  280. package/src/react/primitive-hooks/useThreadListItemUnarchive.ts +1 -1
  281. package/src/react/primitive-hooks/useThreadListLoadMore.ts +1 -1
  282. package/src/react/primitive-hooks/useThreadListNew.ts +1 -1
  283. package/src/react/primitive-hooks/useVoice.ts +5 -5
  284. package/src/react/primitives/chainOfThought/ChainOfThoughtParts.tsx +1 -1
  285. package/src/react/primitives/composer/ComposerAttachments.tsx +1 -1
  286. package/src/react/primitives/composer/ComposerQueue.tsx +1 -3
  287. package/src/react/primitives/message/MessageAttachments.tsx +1 -3
  288. package/src/react/primitives/message/MessageParts.tsx +9 -9
  289. package/src/react/primitives/thread/ThreadMessages.tsx +1 -1
  290. package/src/react/primitives/thread/ThreadSuggestions.tsx +1 -1
  291. package/src/react/primitives/threadList/ThreadListItems.tsx +1 -1
  292. package/src/react/providers/AttachmentByIndexProvider.tsx +2 -2
  293. package/src/react/providers/ChainOfThoughtByIndicesProvider.tsx +1 -1
  294. package/src/react/providers/ChainOfThoughtPartByIndexProvider.tsx +2 -19
  295. package/src/react/providers/MessageByIdProvider.tsx +2 -2
  296. package/src/react/providers/MessageByIndexProvider.tsx +2 -2
  297. package/src/react/providers/PartByIndexProvider.tsx +2 -16
  298. package/src/react/providers/QueueItemByIndexProvider.tsx +1 -1
  299. package/src/react/providers/ReadonlyThreadProvider.tsx +1 -1
  300. package/src/react/providers/SuggestionByIndexProvider.tsx +1 -1
  301. package/src/react/providers/ThreadListItemByIndexProvider.tsx +1 -1
  302. package/src/react/runtimes/RemoteThreadListHookInstanceManager.tsx +3 -3
  303. package/src/react/runtimes/RemoteThreadListThreadListRuntimeCore.tsx +20 -6
  304. package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.test.ts +34 -0
  305. package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.test.tsx +32 -7
  306. package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.ts +47 -16
  307. package/src/react/runtimes/cloud/CloudFileAttachmentAdapter.ts +5 -1
  308. package/src/react/runtimes/cloud/auiV0.ts +14 -0
  309. package/src/react/runtimes/cloud/useCloudThreadListAdapter.tsx +90 -88
  310. package/src/react/runtimes/createRuntimeExtras.test.ts +1 -1
  311. package/src/react/runtimes/createRuntimeExtras.ts +1 -1
  312. package/src/react/runtimes/external-message-converter.test.ts +346 -0
  313. package/src/react/runtimes/external-message-converter.ts +1 -1
  314. package/src/react/runtimes/useLocalRuntime.test.tsx +43 -0
  315. package/src/react/types/scopes/tools.ts +0 -6
  316. package/src/react/utils/groupParts.ts +1 -7
  317. package/src/runtime/api/assistant-runtime.ts +4 -1
  318. package/src/runtime/api/attachment-runtime.ts +8 -2
  319. package/src/runtime/api/composer-runtime.ts +9 -5
  320. package/src/runtime/api/message-part-runtime.ts +10 -3
  321. package/src/runtime/api/message-runtime.ts +7 -2
  322. package/src/runtime/api/thread-list-item-runtime.ts +7 -2
  323. package/src/runtime/api/thread-list-runtime.ts +10 -2
  324. package/src/runtime/base/base-thread-runtime-core.ts +5 -1
  325. package/src/runtime/base/default-edit-composer-runtime-core.ts +14 -2
  326. package/src/runtime/base/default-thread-composer-runtime-core.ts +11 -1
  327. package/src/runtime/utils/message-repository.ts +19 -13
  328. package/src/runtimes/external-store/external-store-thread-list-runtime-core.ts +4 -1
  329. package/src/runtimes/external-store/external-store-thread-runtime-core.ts +15 -0
  330. package/src/runtimes/internal.ts +3 -0
  331. package/src/runtimes/local/local-thread-runtime-core.test.ts +596 -0
  332. package/src/runtimes/local/local-thread-runtime-core.ts +85 -21
  333. package/src/runtimes/local/should-continue.test.ts +122 -0
  334. package/src/runtimes/tool-invocations/ToolInvocationTracker.test.ts +9 -10
  335. package/src/runtimes/tool-invocations/ToolInvocationTracker.ts +38 -32
  336. package/src/store/clients/model-context-client.test.ts +21 -1
  337. package/src/store/clients/runtime-adapter.ts +3 -3
  338. package/src/store/runtime-clients/thread-runtime-client.ts +2 -1
  339. package/src/store/scopes/thread.ts +1 -0
  340. package/src/subscribable/subscribable.ts +16 -8
  341. package/src/tests/MessageRepository.test.ts +12 -0
  342. package/src/tests/RemoteThreadListThreadListRuntimeCore-switchToThread-position.test.ts +121 -0
  343. package/src/tests/auiV0Encode.test.ts +74 -0
  344. package/src/tests/base-composer-runtime-core.test.ts +422 -0
  345. package/src/tests/external-store-thread-list-runtime-core.test.ts +6 -6
  346. package/src/tests/external-store-thread-runtime-core-adapter.test.ts +575 -0
  347. package/src/tests/external-store-thread-runtime-core.test.ts +55 -1
  348. package/src/tests/groupParts.test.ts +3 -48
  349. package/src/tests/OptimisticState-delete-crash.test.ts +0 -208
@@ -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","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","constructor","_contextProvider","getModelContext","_editComposers","Map","getEditComposer","get","beginEdit","has","Error","set","delete","getMessage","_notifySubscribers","getMessageById","baseMessages","voiceIdx","findIndex","m","id","parentId","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","custom","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\";\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 constructor(private readonly _contextProvider: ModelContextProvider) {}\n\n public getModelContext() {\n return this._contextProvider.getModelContext();\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","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","_editComposers","Map","getEditComposer","get","beginEdit","has","Error","set","delete","getMessage","_notifySubscribers","getMessageById","baseMessages","voiceIdx","findIndex","m","id","parentId","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","custom","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\";\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 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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"}
@@ -6,8 +6,6 @@ import { ThreadRuntimeCore } from "../interfaces/thread-runtime-core.js";
6
6
  import { BaseComposerRuntimeCore } from "./base-composer-runtime-core.js";
7
7
  //#region src/runtime/base/default-edit-composer-runtime-core.d.ts
8
8
  declare class DefaultEditComposerRuntimeCore extends BaseComposerRuntimeCore {
9
- private runtime;
10
- private endEditCallback;
11
9
  get canCancel(): boolean;
12
10
  get canSend(): boolean;
13
11
  protected getAttachmentAdapter(): AttachmentAdapter | undefined;
@@ -17,6 +15,8 @@ declare class DefaultEditComposerRuntimeCore extends BaseComposerRuntimeCore {
17
15
  private _nonTextPassthrough;
18
16
  private _parentId;
19
17
  private _sourceId;
18
+ private runtime;
19
+ private endEditCallback;
20
20
  constructor(runtime: ThreadRuntimeCore & {
21
21
  adapters?: {
22
22
  attachments?: AttachmentAdapter | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"default-edit-composer-runtime-core.d.ts","names":[],"sources":["../../../src/runtime/base/default-edit-composer-runtime-core.ts"],"mappings":";;;;;;;cAWa,uCAAuC;UAuBxC;UAQA;MA9BC;MAIA;YAID,wBAAoB;YAIpB,uBAAmB;UAIrB;UACA;UACA;UACA;UACA;EAEE,YAAA,SAAS;IACf;MAEM,cAAc;MACd,YAAY;;KAIZ,+BACN,UAAU;IAAa;IAAyB,SAAS;;MA2BlD;MAIA;EAIE,WACX,SAAS,KAAK,yCACd,UAAU,cAAW;EAkDhB"}
1
+ {"version":3,"file":"default-edit-composer-runtime-core.d.ts","names":[],"sources":["../../../src/runtime/base/default-edit-composer-runtime-core.ts"],"mappings":";;;;;;;cAWa,uCAAuC;MACvC;MAIA;YAID,wBAAoB;YAIpB,uBAAmB;UAIrB;UACA;UACA;UACA;UACA;UACA;UAQA;EAGN,YAAA,SAAS;IACP;MAEM,cAAc;MACd,YAAY;;KAIpB,+BACE,UAAU;IAAa;IAAyB,SAAS;;MA6BlD;MAIA;EAIE,WACX,SAAS,KAAK,yCACd,UAAU,cAAW;EAkDhB"}
@@ -4,8 +4,6 @@ import { getThreadMessageText } from "../../utils/text.js";
4
4
  import { BaseComposerRuntimeCore } from "./base-composer-runtime-core.js";
5
5
  //#region src/runtime/base/default-edit-composer-runtime-core.ts
6
6
  var DefaultEditComposerRuntimeCore = class extends BaseComposerRuntimeCore {
7
- runtime;
8
- endEditCallback;
9
7
  get canCancel() {
10
8
  return true;
11
9
  }
@@ -23,6 +21,8 @@ var DefaultEditComposerRuntimeCore = class extends BaseComposerRuntimeCore {
23
21
  _nonTextPassthrough;
24
22
  _parentId;
25
23
  _sourceId;
24
+ runtime;
25
+ endEditCallback;
26
26
  constructor(runtime, endEditCallback, { parentId, message }) {
27
27
  super();
28
28
  this.runtime = runtime;
@@ -1 +1 @@
1
- {"version":3,"file":"default-edit-composer-runtime-core.js","names":["AppendMessage","ThreadMessage","CompleteAttachment","getThreadMessageText","attachmentsEqual","liftNonTextParts","AttachmentAdapter","DictationAdapter","SendOptions","ThreadRuntimeCore","BaseComposerRuntimeCore","gateInteractableComposerMetadata","DefaultEditComposerRuntimeCore","canCancel","canSend","isEmpty","_isSending","getAttachmentAdapter","runtime","adapters","attachments","getDictationAdapter","dictation","_previousText","_previousAttachments","_nonTextPassthrough","_parentId","_sourceId","constructor","endEditCallback","parentId","message","id","setText","setRole","role","content","filter","p","type","setAttachments","setRunConfig","composer","runConfig","sourceId","handleSend","Omit","options","appendTask","Promise","undefined","text","attachmentsChanged","startRun","length","messages","parentIndex","findIndex","m","composerMetadata","getModelContext","unstable_composerMetadata","slice","enriched","enrichWithComposerMetadata","append","handleCancel","_notifySubscribers"],"sources":["../../../src/runtime/base/default-edit-composer-runtime-core.ts"],"sourcesContent":["import type { AppendMessage, ThreadMessage } from \"../../types/message\";\nimport type { CompleteAttachment } from \"../../types/attachment\";\nimport { getThreadMessageText } from \"../../utils/text\";\nimport { attachmentsEqual, liftNonTextParts } from \"../../adapters/attachment\";\nimport type { AttachmentAdapter } from \"../../adapters/attachment\";\nimport type { DictationAdapter } from \"../../adapters/speech\";\nimport type { SendOptions } from \"../interfaces/composer-runtime-core\";\nimport type { ThreadRuntimeCore } from \"../interfaces/thread-runtime-core\";\nimport { BaseComposerRuntimeCore } from \"./base-composer-runtime-core\";\nimport { gateInteractableComposerMetadata } from \"../../model-context/interactable-composer-metadata\";\n\nexport class DefaultEditComposerRuntimeCore extends BaseComposerRuntimeCore {\n public get canCancel() {\n return true;\n }\n\n public get canSend() {\n return !this.isEmpty && !this._isSending;\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 _previousText;\n private _previousAttachments: readonly CompleteAttachment[];\n private _nonTextPassthrough: readonly ThreadMessage[\"content\"][number][];\n private _parentId: string | null;\n private _sourceId: string | null;\n constructor(\n private runtime: ThreadRuntimeCore & {\n adapters?:\n | {\n attachments?: AttachmentAdapter | undefined;\n dictation?: DictationAdapter | undefined;\n }\n | undefined;\n },\n private endEditCallback: () => void,\n { parentId, message }: { parentId: string | null; message: ThreadMessage },\n ) {\n super();\n this._parentId = parentId;\n this._sourceId = message.id;\n this._previousText = getThreadMessageText(message);\n this.setText(this._previousText);\n\n this.setRole(message.role);\n\n if (message.role === \"user\") {\n this._previousAttachments = [\n ...(message.attachments ?? []),\n ...liftNonTextParts(message.content),\n ];\n this._nonTextPassthrough = [];\n } else {\n this._previousAttachments = message.attachments ?? [];\n this._nonTextPassthrough = message.content.filter(\n (p) => p.type !== \"text\",\n );\n }\n this.setAttachments(this._previousAttachments);\n\n this.setRunConfig({ ...runtime.composer.runConfig });\n }\n\n public get parentId() {\n return this._parentId;\n }\n\n public get sourceId() {\n return this._sourceId;\n }\n\n public async handleSend(\n message: Omit<AppendMessage, \"parentId\" | \"sourceId\">,\n options?: SendOptions,\n ) {\n let appendTask: void | Promise<void> = undefined;\n const text = getThreadMessageText(message as AppendMessage);\n const attachmentsChanged = !attachmentsEqual(\n message.attachments ?? [],\n this._previousAttachments,\n );\n\n if (\n text !== this._previousText ||\n attachmentsChanged ||\n options?.startRun\n ) {\n const content =\n this._nonTextPassthrough.length > 0\n ? ([\n ...message.content,\n ...this._nonTextPassthrough,\n ] as AppendMessage[\"content\"])\n : message.content;\n // Gate live state against the new branch's prefix (messages up to the\n // parent): an unchanged interactable re-stamps the prior baseline, an\n // interactable edited since the original message stamps its newest state.\n const messages = this.runtime.messages;\n const parentIndex =\n this._parentId === null\n ? -1\n : messages.findIndex((m) => m.id === this._parentId);\n const composerMetadata = gateInteractableComposerMetadata(\n this.runtime.getModelContext().unstable_composerMetadata,\n messages.slice(0, parentIndex + 1),\n );\n const enriched = this.enrichWithComposerMetadata(\n message,\n composerMetadata,\n );\n appendTask = this.runtime.append({\n ...enriched,\n content,\n parentId: this._parentId,\n sourceId: this._sourceId,\n startRun: options?.startRun,\n });\n }\n\n this.handleCancel();\n return appendTask;\n }\n\n public handleCancel() {\n this.endEditCallback();\n this._notifySubscribers();\n }\n}\n"],"mappings":";;;;;AAWA,IAAaY,iCAAb,cAAoDF,wBAAwB;CAuBhEQ;CAQAW;CA9BV,IAAWhB,YAAY;EACrB,OAAO;CACT;CAEA,IAAWC,UAAU;EACnB,OAAO,CAAC,KAAKC,WAAW,CAAC,KAAKC;CAChC;CAEA,uBAAiC;EAC/B,OAAO,KAAKE,QAAQC,UAAUC;CAChC;CAEA,sBAAgC;EAC9B,OAAO,KAAKF,QAAQC,UAAUG;CAChC;CAEA;CACA;CACA;CACA;CACA;CACAM,YACE,SAQA,iBACA,EAAEE,UAAUC,WACZ;EACA,MAAM;EAXEb,KAAAA,UAAAA;EAQAW,KAAAA,kBAAAA;EAIR,KAAKH,YAAYI;EACjB,KAAKH,YAAYI,QAAQC;EACzB,KAAKT,gBAAgBpB,qBAAqB4B,OAAO;EACjD,KAAKE,QAAQ,KAAKV,aAAa;EAE/B,KAAKW,QAAQH,QAAQI,IAAI;EAEzB,IAAIJ,QAAQI,SAAS,QAAQ;GAC3B,KAAKX,uBAAuB,CAC1B,GAAIO,QAAQX,eAAe,CAAA,GAC3B,GAAGf,iBAAiB0B,QAAQK,OAAO,CAAC;GAEtC,KAAKX,sBAAsB,CAAA;EAC7B,OAAO;GACL,KAAKD,uBAAuBO,QAAQX,eAAe,CAAA;GACnD,KAAKK,sBAAsBM,QAAQK,QAAQC,QACxCC,MAAMA,EAAEC,SAAS,MACpB;EACF;EACA,KAAKC,eAAe,KAAKhB,oBAAoB;EAE7C,KAAKiB,aAAa,EAAE,GAAGvB,QAAQwB,SAASC,UAAU,CAAC;CACrD;CAEA,IAAWb,WAAW;EACpB,OAAO,KAAKJ;CACd;CAEA,IAAWkB,WAAW;EACpB,OAAO,KAAKjB;CACd;CAEA,MAAakB,WACXd,SACAgB,SACA;EACA,IAAIC,aAAmCE,KAAAA;EACvC,MAAMC,OAAOhD,qBAAqB4B,OAAwB;EAC1D,MAAMqB,qBAAqB,CAAChD,iBAC1B2B,QAAQX,eAAe,CAAA,GACvB,KAAKI,oBACP;EAEA,IACE2B,SAAS,KAAK5B,iBACd6B,sBACAL,SAASM,UACT;GACA,MAAMjB,UACJ,KAAKX,oBAAoB6B,SAAS,IAC7B,CACC,GAAGvB,QAAQK,SACX,GAAG,KAAKX,mBAAmB,IAE7BM,QAAQK;GAId,MAAMmB,WAAW,KAAKrC,QAAQqC;GAC9B,MAAMC,cACJ,KAAK9B,cAAc,OACf,KACA6B,SAASE,WAAWC,MAAMA,EAAE1B,OAAO,KAAKN,SAAS;GACvD,MAAMiC,mBAAmBhD,iCACvB,KAAKO,QAAQ0C,gBAAgB,CAAC,CAACC,2BAC/BN,SAASO,MAAM,GAAGN,cAAc,CAAC,CACnC;GACA,MAAMO,WAAW,KAAKC,2BACpBjC,SACA4B,gBACF;GACAX,aAAa,KAAK9B,QAAQ+C,OAAO;IAC/B,GAAGF;IACH3B;IACAN,UAAU,KAAKJ;IACfkB,UAAU,KAAKjB;IACf0B,UAAUN,SAASM;GACrB,CAAC;EACH;EAEA,KAAKa,aAAa;EAClB,OAAOlB;CACT;CAEA,eAAsB;EACpB,KAAKnB,gBAAgB;EACrB,KAAKsC,mBAAmB;CAC1B;AACF"}
1
+ {"version":3,"file":"default-edit-composer-runtime-core.js","names":["AppendMessage","ThreadMessage","CompleteAttachment","getThreadMessageText","attachmentsEqual","liftNonTextParts","AttachmentAdapter","DictationAdapter","SendOptions","ThreadRuntimeCore","BaseComposerRuntimeCore","gateInteractableComposerMetadata","DefaultEditComposerRuntimeCore","canCancel","canSend","isEmpty","_isSending","getAttachmentAdapter","runtime","adapters","attachments","getDictationAdapter","dictation","_previousText","_previousAttachments","_nonTextPassthrough","_parentId","_sourceId","endEditCallback","constructor","parentId","message","id","setText","setRole","role","content","filter","p","type","setAttachments","setRunConfig","composer","runConfig","sourceId","handleSend","Omit","options","appendTask","Promise","undefined","text","attachmentsChanged","startRun","length","messages","parentIndex","findIndex","m","composerMetadata","getModelContext","unstable_composerMetadata","slice","enriched","enrichWithComposerMetadata","append","handleCancel","_notifySubscribers"],"sources":["../../../src/runtime/base/default-edit-composer-runtime-core.ts"],"sourcesContent":["import type { AppendMessage, ThreadMessage } from \"../../types/message\";\nimport type { CompleteAttachment } from \"../../types/attachment\";\nimport { getThreadMessageText } from \"../../utils/text\";\nimport { attachmentsEqual, liftNonTextParts } from \"../../adapters/attachment\";\nimport type { AttachmentAdapter } from \"../../adapters/attachment\";\nimport type { DictationAdapter } from \"../../adapters/speech\";\nimport type { SendOptions } from \"../interfaces/composer-runtime-core\";\nimport type { ThreadRuntimeCore } from \"../interfaces/thread-runtime-core\";\nimport { BaseComposerRuntimeCore } from \"./base-composer-runtime-core\";\nimport { gateInteractableComposerMetadata } from \"../../model-context/interactable-composer-metadata\";\n\nexport class DefaultEditComposerRuntimeCore extends BaseComposerRuntimeCore {\n public get canCancel() {\n return true;\n }\n\n public get canSend() {\n return !this.isEmpty && !this._isSending;\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 _previousText;\n private _previousAttachments: readonly CompleteAttachment[];\n private _nonTextPassthrough: readonly ThreadMessage[\"content\"][number][];\n private _parentId: string | null;\n private _sourceId: string | null;\n private runtime: ThreadRuntimeCore & {\n adapters?:\n | {\n attachments?: AttachmentAdapter | undefined;\n dictation?: DictationAdapter | undefined;\n }\n | undefined;\n };\n private endEditCallback: () => void;\n\n constructor(\n runtime: ThreadRuntimeCore & {\n adapters?:\n | {\n attachments?: AttachmentAdapter | undefined;\n dictation?: DictationAdapter | undefined;\n }\n | undefined;\n },\n endEditCallback: () => void,\n { parentId, message }: { parentId: string | null; message: ThreadMessage },\n ) {\n super();\n this.runtime = runtime;\n this.endEditCallback = endEditCallback;\n this._parentId = parentId;\n this._sourceId = message.id;\n this._previousText = getThreadMessageText(message);\n this.setText(this._previousText);\n\n this.setRole(message.role);\n\n if (message.role === \"user\") {\n this._previousAttachments = [\n ...(message.attachments ?? []),\n ...liftNonTextParts(message.content),\n ];\n this._nonTextPassthrough = [];\n } else {\n this._previousAttachments = message.attachments ?? [];\n this._nonTextPassthrough = message.content.filter(\n (p) => p.type !== \"text\",\n );\n }\n this.setAttachments(this._previousAttachments);\n\n this.setRunConfig({ ...runtime.composer.runConfig });\n }\n\n public get parentId() {\n return this._parentId;\n }\n\n public get sourceId() {\n return this._sourceId;\n }\n\n public async handleSend(\n message: Omit<AppendMessage, \"parentId\" | \"sourceId\">,\n options?: SendOptions,\n ) {\n let appendTask: void | Promise<void> = undefined;\n const text = getThreadMessageText(message as AppendMessage);\n const attachmentsChanged = !attachmentsEqual(\n message.attachments ?? [],\n this._previousAttachments,\n );\n\n if (\n text !== this._previousText ||\n attachmentsChanged ||\n options?.startRun\n ) {\n const content =\n this._nonTextPassthrough.length > 0\n ? ([\n ...message.content,\n ...this._nonTextPassthrough,\n ] as AppendMessage[\"content\"])\n : message.content;\n // Gate live state against the new branch's prefix (messages up to the\n // parent): an unchanged interactable re-stamps the prior baseline, an\n // interactable edited since the original message stamps its newest state.\n const messages = this.runtime.messages;\n const parentIndex =\n this._parentId === null\n ? -1\n : messages.findIndex((m) => m.id === this._parentId);\n const composerMetadata = gateInteractableComposerMetadata(\n this.runtime.getModelContext().unstable_composerMetadata,\n messages.slice(0, parentIndex + 1),\n );\n const enriched = this.enrichWithComposerMetadata(\n message,\n composerMetadata,\n );\n appendTask = this.runtime.append({\n ...enriched,\n content,\n parentId: this._parentId,\n sourceId: this._sourceId,\n startRun: options?.startRun,\n });\n }\n\n this.handleCancel();\n return appendTask;\n }\n\n public handleCancel() {\n this.endEditCallback();\n this._notifySubscribers();\n }\n}\n"],"mappings":";;;;;AAWA,IAAaY,iCAAb,cAAoDF,wBAAwB;CAC1E,IAAWG,YAAY;EACrB,OAAO;CACT;CAEA,IAAWC,UAAU;EACnB,OAAO,CAAC,KAAKC,WAAW,CAAC,KAAKC;CAChC;CAEA,uBAAiC;EAC/B,OAAO,KAAKE,QAAQC,UAAUC;CAChC;CAEA,sBAAgC;EAC9B,OAAO,KAAKF,QAAQC,UAAUG;CAChC;CAEA;CACA;CACA;CACA;CACA;CACA;CAQA;CAEAO,YACEX,SAQAU,iBACA,EAAEE,UAAUC,WACZ;EACA,MAAM;EACN,KAAKb,UAAUA;EACf,KAAKU,kBAAkBA;EACvB,KAAKF,YAAYI;EACjB,KAAKH,YAAYI,QAAQC;EACzB,KAAKT,gBAAgBpB,qBAAqB4B,OAAO;EACjD,KAAKE,QAAQ,KAAKV,aAAa;EAE/B,KAAKW,QAAQH,QAAQI,IAAI;EAEzB,IAAIJ,QAAQI,SAAS,QAAQ;GAC3B,KAAKX,uBAAuB,CAC1B,GAAIO,QAAQX,eAAe,CAAA,GAC3B,GAAGf,iBAAiB0B,QAAQK,OAAO,CAAC;GAEtC,KAAKX,sBAAsB,CAAA;EAC7B,OAAO;GACL,KAAKD,uBAAuBO,QAAQX,eAAe,CAAA;GACnD,KAAKK,sBAAsBM,QAAQK,QAAQC,QACxCC,MAAMA,EAAEC,SAAS,MACpB;EACF;EACA,KAAKC,eAAe,KAAKhB,oBAAoB;EAE7C,KAAKiB,aAAa,EAAE,GAAGvB,QAAQwB,SAASC,UAAU,CAAC;CACrD;CAEA,IAAWb,WAAW;EACpB,OAAO,KAAKJ;CACd;CAEA,IAAWkB,WAAW;EACpB,OAAO,KAAKjB;CACd;CAEA,MAAakB,WACXd,SACAgB,SACA;EACA,IAAIC,aAAmCE,KAAAA;EACvC,MAAMC,OAAOhD,qBAAqB4B,OAAwB;EAC1D,MAAMqB,qBAAqB,CAAChD,iBAC1B2B,QAAQX,eAAe,CAAA,GACvB,KAAKI,oBACP;EAEA,IACE2B,SAAS,KAAK5B,iBACd6B,sBACAL,SAASM,UACT;GACA,MAAMjB,UACJ,KAAKX,oBAAoB6B,SAAS,IAC7B,CACC,GAAGvB,QAAQK,SACX,GAAG,KAAKX,mBAAmB,IAE7BM,QAAQK;GAId,MAAMmB,WAAW,KAAKrC,QAAQqC;GAC9B,MAAMC,cACJ,KAAK9B,cAAc,OACf,KACA6B,SAASE,WAAWC,MAAMA,EAAE1B,OAAO,KAAKN,SAAS;GACvD,MAAMiC,mBAAmBhD,iCACvB,KAAKO,QAAQ0C,gBAAgB,CAAC,CAACC,2BAC/BN,SAASO,MAAM,GAAGN,cAAc,CAAC,CACnC;GACA,MAAMO,WAAW,KAAKC,2BACpBjC,SACA4B,gBACF;GACAX,aAAa,KAAK9B,QAAQ+C,OAAO;IAC/B,GAAGF;IACH3B;IACAN,UAAU,KAAKJ;IACfkB,UAAU,KAAKjB;IACf0B,UAAUN,SAASM;GACrB,CAAC;EACH;EAEA,KAAKa,aAAa;EAClB,OAAOlB;CACT;CAEA,eAAsB;EACpB,KAAKpB,gBAAgB;EACrB,KAAKuC,mBAAmB;CAC1B;AACF"}
@@ -9,7 +9,6 @@ import { BaseComposerRuntimeCore } from "./base-composer-runtime-core.js";
9
9
  import "../../index.js";
10
10
  //#region src/runtime/base/default-thread-composer-runtime-core.d.ts
11
11
  declare class DefaultThreadComposerRuntimeCore extends BaseComposerRuntimeCore implements ThreadComposerRuntimeCore {
12
- private runtime;
13
12
  private _canCancel;
14
13
  get canCancel(): boolean;
15
14
  get canSend(): boolean;
@@ -18,6 +17,7 @@ declare class DefaultThreadComposerRuntimeCore extends BaseComposerRuntimeCore i
18
17
  removeQueueItem(queueItemId: string): void;
19
18
  protected getAttachmentAdapter(): AttachmentAdapter | undefined;
20
19
  protected getDictationAdapter(): DictationAdapter | undefined;
20
+ private runtime;
21
21
  constructor(runtime: Omit<ThreadRuntimeCore, "composer"> & {
22
22
  adapters?: {
23
23
  attachments?: AttachmentAdapter | undefined;
@@ -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;UAgCD;UA9BF;MACG;MAIA;MAIS,kBAAkB;EAItB,eAAe;EAIf,gBAAgB;YAItB,wBAAoB;YAIpB,uBAAmB;EAKnB,YAAA,SAAS,KAAK;IACpB;MAEM,cAAc;MACd,YAAY;;;EASf,WATe;EA8BT,WACX,SAAS,KAAK,yCACd,UAAU,cAAW;EAoBV,gBAAY"}
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;MAIS,kBAAkB;EAItB,eAAe;EAIf,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;EAoBV,gBAAY"}
@@ -3,7 +3,6 @@ import { EMPTY_QUEUE_ITEMS } from "../../store/scopes/queue-item.js";
3
3
  import { BaseComposerRuntimeCore } from "./base-composer-runtime-core.js";
4
4
  //#region src/runtime/base/default-thread-composer-runtime-core.ts
5
5
  var DefaultThreadComposerRuntimeCore = class extends BaseComposerRuntimeCore {
6
- runtime;
7
6
  _canCancel = false;
8
7
  get canCancel() {
9
8
  return this._canCancel;
@@ -26,6 +25,7 @@ var DefaultThreadComposerRuntimeCore = class extends BaseComposerRuntimeCore {
26
25
  getDictationAdapter() {
27
26
  return this.runtime.adapters?.dictation;
28
27
  }
28
+ runtime;
29
29
  constructor(runtime) {
30
30
  super();
31
31
  this.runtime = runtime;
@@ -1 +1 @@
1
- {"version":3,"file":"default-thread-composer-runtime-core.js","names":["AppendMessage","AttachmentAdapter","DictationAdapter","SendOptions","ThreadComposerRuntimeCore","ThreadRuntimeCore","EMPTY_QUEUE_ITEMS","QueueItemState","BaseComposerRuntimeCore","gateInteractableComposerMetadata","DefaultThreadComposerRuntimeCore","_canCancel","canCancel","canSend","isEmpty","runtime","isSendDisabled","_isSending","queue","getQueueItems","steerQueueItem","queueItemId","removeQueueItem","getAttachmentAdapter","adapters","attachments","getDictationAdapter","dictation","constructor","Omit","connect","lastIsSendDisabled","lastQueue","subscribe","changed","capabilities","cancel","_notifySubscribers","handleSend","message","options","composerMetadata","getModelContext","unstable_composerMetadata","messages","enriched","enrichWithComposerMetadata","append","parentId","at","id","sourceId","startRun","steer","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 {\n EMPTY_QUEUE_ITEMS,\n type QueueItemState,\n} from \"../../store/scopes/queue-item\";\nimport { BaseComposerRuntimeCore } from \"./base-composer-runtime-core\";\nimport { gateInteractableComposerMetadata } from \"../../model-context/interactable-composer-metadata\";\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 public override get queue(): readonly QueueItemState[] {\n return this.runtime.getQueueItems?.() ?? EMPTY_QUEUE_ITEMS;\n }\n\n public override steerQueueItem(queueItemId: string): void {\n this.runtime.steerQueueItem?.(queueItemId);\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 constructor(\n private runtime: Omit<ThreadRuntimeCore, \"composer\"> & {\n adapters?:\n | {\n attachments?: AttachmentAdapter | undefined;\n dictation?: DictationAdapter | undefined;\n }\n | undefined;\n },\n ) {\n super();\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 // Merge provider-contributed metadata onto the outgoing user message\n // (same metadata.custom append path quotes ride). The interactables gate\n // runs here because it needs thread history, unavailable to the provider.\n const composerMetadata = gateInteractableComposerMetadata(\n this.runtime.getModelContext().unstable_composerMetadata,\n this.runtime.messages,\n );\n const enriched = this.enrichWithComposerMetadata(message, composerMetadata);\n\n return this.runtime.append({\n ...(enriched 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,cACUF,wBAEV;CA+BYO;CA9BV,aAAqB;CACrB,IAAWH,YAAY;EACrB,OAAO,KAAKD;CACd;CAEA,IAAWE,UAAU;EACnB,OAAO,CAAC,KAAKC,WAAW,CAAC,KAAKC,QAAQC,kBAAkB,CAAC,KAAKC;CAChE;CAEA,IAAoBC,QAAmC;EACrD,OAAO,KAAKH,QAAQI,gBAAgB,KAAKb;CAC3C;CAEA,eAA+Be,aAA2B;EACxD,KAAKN,QAAQK,iBAAiBC,WAAW;CAC3C;CAEA,gBAAgCA,aAA2B;EACzD,KAAKN,QAAQO,kBAAkBD,WAAW;CAC5C;CAEA,uBAAiC;EAC/B,OAAO,KAAKN,QAAQS,UAAUC;CAChC;CAEA,sBAAgC;EAC9B,OAAO,KAAKV,QAAQS,UAAUG;CAChC;CAEAC,YACE,SAQA;EACA,MAAM;EATEb,KAAAA,UAAAA;EAUR,KAAKe,QAAQ;CACf;CAEA,UAAiB;EACf,IAAIC,qBAAqB,KAAKhB,QAAQC;EACtC,IAAIgB,YAAY,KAAKd;EACrB,OAAO,KAAKH,QAAQkB,gBAAgB;GAClC,IAAIC,UAAU;GACd,IAAI,KAAKtB,cAAc,KAAKG,QAAQoB,aAAaC,QAAQ;IACvD,KAAKzB,aAAa,KAAKI,QAAQoB,aAAaC;IAC5CF,UAAU;GACZ;GACA,IAAIH,uBAAuB,KAAKhB,QAAQC,gBAAgB;IACtDe,qBAAqB,KAAKhB,QAAQC;IAClCkB,UAAU;GACZ;GACA,IAAIF,cAAc,KAAKd,OAAO;IAC5Bc,YAAY,KAAKd;IACjBgB,UAAU;GACZ;GACA,IAAIA,SAAS,KAAKG,mBAAmB;EACvC,CAAC;CACH;CAEA,MAAaC,WACXC,SACAC,SACA;EAIA,MAAMC,mBAAmBhC,iCACvB,KAAKM,QAAQ2B,gBAAgB,CAAC,CAACC,2BAC/B,KAAK5B,QAAQ6B,QACf;EACA,MAAMC,WAAW,KAAKC,2BAA2BP,SAASE,gBAAgB;EAE1E,OAAO,KAAK1B,QAAQgC,OAAO;GACzB,GAAIF;GACJG,UAAU,KAAKjC,QAAQ6B,SAASK,GAAG,EAAE,CAAC,EAAEC,MAAM;GAC9CC,UAAU;GACVC,UAAUZ,SAASY;GACnBC,OAAOb,SAASa;EAClB,CAAC;CACH;CAEA,MAAaC,eAAe;EAC1B,KAAKvC,QAAQwC,UAAU;CACzB;AACF"}
1
+ {"version":3,"file":"default-thread-composer-runtime-core.js","names":["AppendMessage","AttachmentAdapter","DictationAdapter","SendOptions","ThreadComposerRuntimeCore","ThreadRuntimeCore","EMPTY_QUEUE_ITEMS","QueueItemState","BaseComposerRuntimeCore","gateInteractableComposerMetadata","DefaultThreadComposerRuntimeCore","_canCancel","canCancel","canSend","isEmpty","runtime","isSendDisabled","_isSending","queue","getQueueItems","steerQueueItem","queueItemId","removeQueueItem","getAttachmentAdapter","adapters","attachments","getDictationAdapter","dictation","Omit","constructor","connect","lastIsSendDisabled","lastQueue","subscribe","changed","capabilities","cancel","_notifySubscribers","handleSend","message","options","composerMetadata","getModelContext","unstable_composerMetadata","messages","enriched","enrichWithComposerMetadata","append","parentId","at","id","sourceId","startRun","steer","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 {\n EMPTY_QUEUE_ITEMS,\n type QueueItemState,\n} from \"../../store/scopes/queue-item\";\nimport { BaseComposerRuntimeCore } from \"./base-composer-runtime-core\";\nimport { gateInteractableComposerMetadata } from \"../../model-context/interactable-composer-metadata\";\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 public override get queue(): readonly QueueItemState[] {\n return this.runtime.getQueueItems?.() ?? EMPTY_QUEUE_ITEMS;\n }\n\n public override steerQueueItem(queueItemId: string): void {\n this.runtime.steerQueueItem?.(queueItemId);\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 // Merge provider-contributed metadata onto the outgoing user message\n // (same metadata.custom append path quotes ride). The interactables gate\n // runs here because it needs thread history, unavailable to the provider.\n const composerMetadata = gateInteractableComposerMetadata(\n this.runtime.getModelContext().unstable_composerMetadata,\n this.runtime.messages,\n );\n const enriched = this.enrichWithComposerMetadata(message, composerMetadata);\n\n return this.runtime.append({\n ...(enriched 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,cACUF,wBAEV;CACE,aAAqB;CACrB,IAAWI,YAAY;EACrB,OAAO,KAAKD;CACd;CAEA,IAAWE,UAAU;EACnB,OAAO,CAAC,KAAKC,WAAW,CAAC,KAAKC,QAAQC,kBAAkB,CAAC,KAAKC;CAChE;CAEA,IAAoBC,QAAmC;EACrD,OAAO,KAAKH,QAAQI,gBAAgB,KAAKb;CAC3C;CAEA,eAA+Be,aAA2B;EACxD,KAAKN,QAAQK,iBAAiBC,WAAW;CAC3C;CAEA,gBAAgCA,aAA2B;EACzD,KAAKN,QAAQO,kBAAkBD,WAAW;CAC5C;CAEA,uBAAiC;EAC/B,OAAO,KAAKN,QAAQS,UAAUC;CAChC;CAEA,sBAAgC;EAC9B,OAAO,KAAKV,QAAQS,UAAUG;CAChC;CAEA;CASAE,YACEd,SAQA;EACA,MAAM;EACN,KAAKA,UAAUA;EACf,KAAKe,QAAQ;CACf;CAEA,UAAiB;EACf,IAAIC,qBAAqB,KAAKhB,QAAQC;EACtC,IAAIgB,YAAY,KAAKd;EACrB,OAAO,KAAKH,QAAQkB,gBAAgB;GAClC,IAAIC,UAAU;GACd,IAAI,KAAKtB,cAAc,KAAKG,QAAQoB,aAAaC,QAAQ;IACvD,KAAKzB,aAAa,KAAKI,QAAQoB,aAAaC;IAC5CF,UAAU;GACZ;GACA,IAAIH,uBAAuB,KAAKhB,QAAQC,gBAAgB;IACtDe,qBAAqB,KAAKhB,QAAQC;IAClCkB,UAAU;GACZ;GACA,IAAIF,cAAc,KAAKd,OAAO;IAC5Bc,YAAY,KAAKd;IACjBgB,UAAU;GACZ;GACA,IAAIA,SAAS,KAAKG,mBAAmB;EACvC,CAAC;CACH;CAEA,MAAaC,WACXC,SACAC,SACA;EAIA,MAAMC,mBAAmBhC,iCACvB,KAAKM,QAAQ2B,gBAAgB,CAAC,CAACC,2BAC/B,KAAK5B,QAAQ6B,QACf;EACA,MAAMC,WAAW,KAAKC,2BAA2BP,SAASE,gBAAgB;EAE1E,OAAO,KAAK1B,QAAQgC,OAAO;GACzB,GAAIF;GACJG,UAAU,KAAKjC,QAAQ6B,SAASK,GAAG,EAAE,CAAC,EAAEC,MAAM;GAC9CC,UAAU;GACVC,UAAUZ,SAASY;GACnBC,OAAOb,SAASa;EAClB,CAAC;CACH;CAEA,MAAaC,eAAe;EAC1B,KAAKvC,QAAQwC,UAAU;CACzB;AACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"message-repository.d.ts","names":[],"sources":["../../../src/runtime/utils/message-repository.ts"],"mappings":";;;KAOY;EACV,SAAS;EACT;EACA,YAAY;;KAGF;EACV;EACA,UAAU;IACR,SAAS;IACT;IACA,YAAY;;;cAIH;EAEC,YAAA,mBAAS,wBAClB;EAkBM,sBAAA;IACL,SAAS;IACT;OACC;IACS;QACX;;cAyDQ;UACH;UACA;UACA;UAKA;UAUA;UAwDA;MAQJ;MAIA;EAUJ,YAAY,2BAAe;EAuB3B,mBAAmB,yBAAyB,SAAS;EAiCrD,WAAW;;;;;EAcX,cAAc,mBAAmB;EAsCjC,YAAY;;;;;;;;;UAmBJ;EA+BR,eAAe;EAkBf,UAAU;EAgDV;EAUA,UAAU;EAwBV,SAAS,QAAQ,YAAY"}
1
+ {"version":3,"file":"message-repository.d.ts","names":[],"sources":["../../../src/runtime/utils/message-repository.ts"],"mappings":";;;KAOY;EACV,SAAS;EACT;EACA,YAAY;;KAGF;EACV;EACA,UAAU;IACR,SAAS;IACT;IACA,YAAY;;;cAIH;EAEC,YAAA,mBAAS,wBAClB;EAkBM,sBAAA;IACL,SAAS;IACT;OACC;IACS;QACX;;cA6DQ;UACH;UACA;UACA;UAKA;UAUA;UA0DA;MAQJ;MAIA;EAUJ,YAAY,2BAAe;EAuB3B,mBAAmB,yBAAyB,SAAS;EAiCrD,WAAW;;;;;EAcX,cAAc,mBAAmB;EAsCjC,YAAY;;;;;;;;;UAmBJ;EA+BR,eAAe;EAkBf,UAAU;EAgDV;EAUA,UAAU;EAwBV,SAAS,QAAQ,YAAY"}
@@ -30,8 +30,8 @@ const findHead = (message) => {
30
30
  return null;
31
31
  };
32
32
  var CachedValue = class {
33
- func;
34
33
  _value = null;
34
+ func;
35
35
  constructor(func) {
36
36
  this.func = func;
37
37
  }
@@ -61,6 +61,9 @@ var MessageRepository = class {
61
61
  const parentOrRoot = child.prev ?? this.root;
62
62
  const newParentOrRoot = newParent ?? this.root;
63
63
  if (operation === "relink" && parentOrRoot === newParentOrRoot) return;
64
+ if (operation !== "cut") {
65
+ for (let current = newParent; current; current = current.prev) if (current.current.id === child.current.id) throw new Error("MessageRepository(performOp/link): A message with the same id already exists in the parent tree. This error occurs if the same message id is found multiple times. This is likely an internal bug in assistant-ui.");
66
+ }
64
67
  if (operation !== "link") {
65
68
  parentOrRoot.children = parentOrRoot.children.filter((m) => m !== child.current.id);
66
69
  if (parentOrRoot.next === child) {
@@ -71,7 +74,6 @@ var MessageRepository = class {
71
74
  }
72
75
  }
73
76
  if (operation !== "cut") {
74
- for (let current = newParent; current; current = current.prev) if (current.current.id === child.current.id) throw new Error("MessageRepository(performOp/link): A message with the same id already exists in the parent tree. This error occurs if the same message id is found multiple times. This is likely an internal bug in assistant-ui.");
75
77
  newParentOrRoot.children = [...newParentOrRoot.children, child.current.id];
76
78
  if (findHead(child) === this.head || newParentOrRoot.next === null) newParentOrRoot.next = child;
77
79
  child.prev = newParent;
@@ -1 +1 @@
1
- {"version":3,"file":"message-repository.js","names":["ThreadMessage","RunConfig","generateId","ThreadMessageLike","getAutoStatus","fromThreadMessageLike","ExportedMessageRepositoryItem","message","parentId","runConfig","ExportedMessageRepository","headId","messages","Array","fromArray","conv","map","m","undefined","idx","id","fromBranchableArray","items","options","fallbackStatus","Error","RepositoryParent","children","next","RepositoryMessage","prev","current","level","findHead","CachedValue","_value","T","constructor","func","value","dirty","MessageRepository","Map","head","root","updateLevels","newLevel","childId","childMessage","get","performOp","newParent","child","operation","parentOrRoot","newParentOrRoot","filter","fallbackId","at","fallback","_messages","canonicalHeadId","metadata","isOptimistic","getMessages","headMessage","addOrUpdateMessage","existingItem","newItem","set","getMessage","messageId","index","deleteMessage","replacementId","replacement","delete","getBranches","evictOffBranchOptimisticMessages","previousHead","currentHead","onHeadBranch","Set","add","stale","has","push","switchToBranch","prevOrRoot","resetHead","clear","length","deleteDescendants","msg","export","exportItems","import"],"sources":["../../../src/runtime/utils/message-repository.ts"],"sourcesContent":["import type { ThreadMessage } from \"../../types/message\";\nimport type { RunConfig } from \"../../types/message\";\nimport { generateId } from \"../../utils/id\";\nimport type { ThreadMessageLike } from \"./thread-message-like\";\nimport { getAutoStatus } from \"./auto-status\";\nimport { fromThreadMessageLike } from \"./thread-message-like\";\n\nexport type ExportedMessageRepositoryItem = {\n message: ThreadMessage;\n parentId: string | null;\n runConfig?: RunConfig;\n};\n\nexport type ExportedMessageRepository = {\n headId?: string | null;\n messages: Array<{\n message: ThreadMessage;\n parentId: string | null;\n runConfig?: RunConfig;\n }>;\n};\n\nexport const ExportedMessageRepository = {\n fromArray: (\n messages: readonly ThreadMessageLike[],\n ): ExportedMessageRepository => {\n const conv = messages.map((m) =>\n fromThreadMessageLike(\n m,\n generateId(),\n getAutoStatus(false, false, false, false, undefined),\n ),\n );\n\n return {\n messages: conv.map((m, idx) => ({\n parentId: idx > 0 ? conv[idx - 1]!.id : null,\n message: m,\n })),\n };\n },\n\n fromBranchableArray: (\n items: readonly {\n message: ThreadMessageLike;\n parentId: string | null;\n }[],\n options?: { headId?: string | null },\n ): ExportedMessageRepository => {\n const fallbackStatus = getAutoStatus(false, false, false, false, undefined);\n return {\n ...(options?.headId !== undefined\n ? { headId: options.headId }\n : undefined),\n messages: items.map(({ message, parentId }) => {\n if (!message.id) {\n throw new Error(\n \"ExportedMessageRepository.fromBranchableArray: Each message must have an 'id' field set.\",\n );\n }\n return {\n parentId,\n message: fromThreadMessageLike(message, message.id, fallbackStatus),\n };\n }),\n };\n },\n};\n\ntype RepositoryParent = {\n children: string[];\n next: RepositoryMessage | null;\n};\n\ntype RepositoryMessage = RepositoryParent & {\n prev: RepositoryMessage | null;\n current: ThreadMessage;\n level: number;\n};\n\nconst findHead = (\n message: RepositoryMessage | RepositoryParent,\n): RepositoryMessage | null => {\n if (message.next) return findHead(message.next);\n if (\"current\" in message) return message;\n return null;\n};\n\nclass CachedValue<T> {\n private _value: T | null = null;\n\n constructor(private func: () => T) {}\n\n get value() {\n if (this._value === null) {\n this._value = this.func();\n }\n return this._value;\n }\n\n dirty() {\n this._value = null;\n }\n}\n\nexport class MessageRepository {\n private messages = new Map<string, RepositoryMessage>();\n private head: RepositoryMessage | null = null;\n private root: RepositoryParent = {\n children: [],\n next: null,\n };\n\n private updateLevels(message: RepositoryMessage, newLevel: number) {\n message.level = newLevel;\n for (const childId of message.children) {\n const childMessage = this.messages.get(childId);\n if (childMessage) {\n this.updateLevels(childMessage, newLevel + 1);\n }\n }\n }\n\n private performOp(\n newParent: RepositoryMessage | null,\n child: RepositoryMessage,\n operation: \"cut\" | \"link\" | \"relink\",\n ) {\n const parentOrRoot = child.prev ?? this.root;\n const newParentOrRoot = newParent ?? this.root;\n\n if (operation === \"relink\" && parentOrRoot === newParentOrRoot) return;\n\n if (operation !== \"link\") {\n parentOrRoot.children = parentOrRoot.children.filter(\n (m) => m !== child.current.id,\n );\n\n if (parentOrRoot.next === child) {\n const fallbackId = parentOrRoot.children.at(-1);\n const fallback = fallbackId ? this.messages.get(fallbackId) : null;\n if (fallback === undefined) {\n throw new Error(\n \"MessageRepository(performOp/cut): Fallback sibling message not found. This is likely an internal bug in assistant-ui.\",\n );\n }\n parentOrRoot.next = fallback;\n }\n }\n\n if (operation !== \"cut\") {\n for (\n let current: RepositoryMessage | null = newParent;\n current;\n current = current.prev\n ) {\n if (current.current.id === child.current.id) {\n throw new Error(\n \"MessageRepository(performOp/link): A message with the same id already exists in the parent tree. This error occurs if the same message id is found multiple times. This is likely an internal bug in assistant-ui.\",\n );\n }\n }\n\n newParentOrRoot.children = [\n ...newParentOrRoot.children,\n child.current.id,\n ];\n\n if (findHead(child) === this.head || newParentOrRoot.next === null) {\n newParentOrRoot.next = child;\n }\n\n child.prev = newParent;\n\n const newLevel = newParent ? newParent.level + 1 : 0;\n this.updateLevels(child, newLevel);\n }\n }\n\n private _messages = new CachedValue<readonly ThreadMessage[]>(() => {\n const messages = new Array<ThreadMessage>((this.head?.level ?? -1) + 1);\n for (let current = this.head; current; current = current.prev) {\n messages[current.level] = current.current;\n }\n return messages;\n });\n\n get headId() {\n return this.head?.current.id ?? null;\n }\n\n get canonicalHeadId() {\n // Optimistic messages are ephemeral, so persisted callers need the nearest\n // non-optimistic ancestor rather than the raw head.\n let head = this.head;\n while (head?.current.metadata?.isOptimistic) {\n head = head.prev;\n }\n return head?.current.id ?? null;\n }\n\n getMessages(headId?: string) {\n if (headId === undefined || headId === this.head?.current.id) {\n return this._messages.value;\n }\n\n const headMessage = this.messages.get(headId);\n if (!headMessage) {\n throw new Error(\n \"MessageRepository(getMessages): Head message not found. This is likely an internal bug in assistant-ui.\",\n );\n }\n\n const messages = new Array<ThreadMessage>(headMessage.level + 1);\n for (\n let current: RepositoryMessage | null = headMessage;\n current;\n current = current.prev\n ) {\n messages[current.level] = current.current;\n }\n return messages;\n }\n\n addOrUpdateMessage(parentId: string | null, message: ThreadMessage) {\n const existingItem = this.messages.get(message.id);\n const prev = parentId ? this.messages.get(parentId) : null;\n if (prev === undefined)\n throw new Error(\n \"MessageRepository(addOrUpdateMessage): Parent message not found. This is likely an internal bug in assistant-ui.\",\n );\n\n if (existingItem) {\n existingItem.current = message;\n this.performOp(prev, existingItem, \"relink\");\n this._messages.dirty();\n return;\n }\n\n const newItem: RepositoryMessage = {\n prev,\n current: message,\n next: null,\n children: [],\n level: prev ? prev.level + 1 : 0,\n };\n\n this.messages.set(message.id, newItem);\n this.performOp(prev, newItem, \"link\");\n\n if (this.head === prev) {\n this.head = newItem;\n }\n\n this._messages.dirty();\n }\n\n getMessage(messageId: string) {\n const message = this.messages.get(messageId);\n if (!message)\n throw new Error(\n \"MessageRepository(updateMessage): Message not found. This is likely an internal bug in assistant-ui.\",\n );\n\n return {\n parentId: message.prev?.current.id ?? null,\n message: message.current,\n index: message.level,\n };\n }\n\n deleteMessage(messageId: string, replacementId?: string | null | undefined) {\n const message = this.messages.get(messageId);\n\n if (!message)\n throw new Error(\n \"MessageRepository(deleteMessage): Message not found. This is likely an internal bug in assistant-ui.\",\n );\n\n const replacement =\n replacementId === undefined\n ? message.prev\n : replacementId === null\n ? null\n : this.messages.get(replacementId);\n if (replacement === undefined)\n throw new Error(\n \"MessageRepository(deleteMessage): Replacement not found. This is likely an internal bug in assistant-ui.\",\n );\n\n for (const child of message.children) {\n const childMessage = this.messages.get(child);\n if (!childMessage)\n throw new Error(\n \"MessageRepository(deleteMessage): Child message not found. This is likely an internal bug in assistant-ui.\",\n );\n this.performOp(replacement, childMessage, \"relink\");\n }\n\n this.performOp(null, message, \"cut\");\n this.messages.delete(messageId);\n\n if (this.head === message) {\n this.head = findHead(replacement ?? this.root);\n }\n\n this._messages.dirty();\n }\n\n getBranches(messageId: string) {\n const message = this.messages.get(messageId);\n if (!message)\n throw new Error(\n \"MessageRepository(getBranches): Message not found. This is likely an internal bug in assistant-ui.\",\n );\n\n const { children } = message.prev ?? this.root;\n return children;\n }\n\n /**\n * Evicts optimistic messages (`metadata.isOptimistic`) the head just moved\n * away from. Since eviction runs on every head move, the only optimistic\n * messages in the repository live on the branch the head previously pointed\n * at — so we walk just that branch rather than the whole repository. Keeps a\n * client→server id swap from leaving a phantom sibling, and drops off-branch\n * placeholders.\n */\n private evictOffBranchOptimisticMessages(\n previousHead: RepositoryMessage | null,\n currentHead: RepositoryMessage | null,\n ) {\n if (!previousHead) return;\n\n const onHeadBranch = new Set<string>();\n for (let current = currentHead; current; current = current.prev) {\n onHeadBranch.add(current.current.id);\n }\n\n const stale: string[] = [];\n for (\n let current: RepositoryMessage | null = previousHead;\n current;\n current = current.prev\n ) {\n // Stop at the first node shared with the current head branch: every\n // ancestor above it is shared too, so nothing further can be off-branch.\n if (onHeadBranch.has(current.current.id)) break;\n if (current.current.metadata?.isOptimistic) {\n stale.push(current.current.id);\n }\n }\n\n for (const id of stale) {\n // A prior deletion may have already removed this node.\n if (this.messages.has(id)) this.deleteMessage(id);\n }\n }\n\n switchToBranch(messageId: string) {\n const message = this.messages.get(messageId);\n if (!message)\n throw new Error(\n \"MessageRepository(switchToBranch): Branch not found. This is likely an internal bug in assistant-ui.\",\n );\n\n const previousHead = this.head;\n const prevOrRoot = message.prev ?? this.root;\n prevOrRoot.next = message;\n\n this.head = findHead(message);\n\n this.evictOffBranchOptimisticMessages(previousHead, this.head);\n\n this._messages.dirty();\n }\n\n resetHead(messageId: string | null) {\n if (messageId === null) {\n this.clear();\n return;\n }\n\n const message = this.messages.get(messageId);\n if (!message)\n throw new Error(\n \"MessageRepository(resetHead): Branch not found. This is likely an internal bug in assistant-ui.\",\n );\n\n const previousHead = this.head;\n\n if (message.children.length > 0) {\n const deleteDescendants = (msg: RepositoryMessage) => {\n for (const childId of msg.children) {\n const childMessage = this.messages.get(childId);\n if (childMessage) {\n deleteDescendants(childMessage);\n this.messages.delete(childId);\n }\n }\n };\n deleteDescendants(message);\n\n message.children = [];\n message.next = null;\n }\n\n this.head = message;\n for (\n let current: RepositoryMessage | null = message;\n current;\n current = current.prev\n ) {\n if (current.prev) {\n current.prev.next = current;\n } else {\n this.root.next = current;\n }\n }\n\n this.evictOffBranchOptimisticMessages(previousHead, this.head);\n\n this._messages.dirty();\n }\n\n clear(): void {\n this.messages.clear();\n this.head = null;\n this.root = {\n children: [],\n next: null,\n };\n this._messages.dirty();\n }\n\n export(): ExportedMessageRepository {\n const exportItems: ExportedMessageRepository[\"messages\"] = [];\n\n // Optimistic messages are ephemeral and never persisted. A persisted child\n // of an optimistic node is re-parented onto its nearest persisted ancestor\n // so the exported tree never references a skipped id.\n for (const [, message] of this.messages) {\n if (message.current.metadata?.isOptimistic) continue;\n let prev = message.prev;\n while (prev && prev.current.metadata?.isOptimistic) {\n prev = prev.prev;\n }\n exportItems.push({\n message: message.current,\n parentId: prev?.current.id ?? null,\n });\n }\n\n return {\n headId: this.canonicalHeadId,\n messages: exportItems,\n };\n }\n\n import({ headId, messages }: ExportedMessageRepository) {\n for (const { message, parentId } of messages) {\n this.addOrUpdateMessage(parentId, message);\n }\n\n this.resetHead(headId ?? messages.at(-1)?.message.id ?? null);\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"message-repository.js","names":["ThreadMessage","RunConfig","generateId","ThreadMessageLike","getAutoStatus","fromThreadMessageLike","ExportedMessageRepositoryItem","message","parentId","runConfig","ExportedMessageRepository","headId","messages","Array","fromArray","conv","map","m","undefined","idx","id","fromBranchableArray","items","options","fallbackStatus","Error","RepositoryParent","children","next","RepositoryMessage","prev","current","level","findHead","CachedValue","_value","T","func","constructor","value","dirty","MessageRepository","Map","head","root","updateLevels","newLevel","childId","childMessage","get","performOp","newParent","child","operation","parentOrRoot","newParentOrRoot","filter","fallbackId","at","fallback","_messages","canonicalHeadId","metadata","isOptimistic","getMessages","headMessage","addOrUpdateMessage","existingItem","newItem","set","getMessage","messageId","index","deleteMessage","replacementId","replacement","delete","getBranches","evictOffBranchOptimisticMessages","previousHead","currentHead","onHeadBranch","Set","add","stale","has","push","switchToBranch","prevOrRoot","resetHead","clear","length","deleteDescendants","msg","export","exportItems","import"],"sources":["../../../src/runtime/utils/message-repository.ts"],"sourcesContent":["import type { ThreadMessage } from \"../../types/message\";\nimport type { RunConfig } from \"../../types/message\";\nimport { generateId } from \"../../utils/id\";\nimport type { ThreadMessageLike } from \"./thread-message-like\";\nimport { getAutoStatus } from \"./auto-status\";\nimport { fromThreadMessageLike } from \"./thread-message-like\";\n\nexport type ExportedMessageRepositoryItem = {\n message: ThreadMessage;\n parentId: string | null;\n runConfig?: RunConfig;\n};\n\nexport type ExportedMessageRepository = {\n headId?: string | null;\n messages: Array<{\n message: ThreadMessage;\n parentId: string | null;\n runConfig?: RunConfig;\n }>;\n};\n\nexport const ExportedMessageRepository = {\n fromArray: (\n messages: readonly ThreadMessageLike[],\n ): ExportedMessageRepository => {\n const conv = messages.map((m) =>\n fromThreadMessageLike(\n m,\n generateId(),\n getAutoStatus(false, false, false, false, undefined),\n ),\n );\n\n return {\n messages: conv.map((m, idx) => ({\n parentId: idx > 0 ? conv[idx - 1]!.id : null,\n message: m,\n })),\n };\n },\n\n fromBranchableArray: (\n items: readonly {\n message: ThreadMessageLike;\n parentId: string | null;\n }[],\n options?: { headId?: string | null },\n ): ExportedMessageRepository => {\n const fallbackStatus = getAutoStatus(false, false, false, false, undefined);\n return {\n ...(options?.headId !== undefined\n ? { headId: options.headId }\n : undefined),\n messages: items.map(({ message, parentId }) => {\n if (!message.id) {\n throw new Error(\n \"ExportedMessageRepository.fromBranchableArray: Each message must have an 'id' field set.\",\n );\n }\n return {\n parentId,\n message: fromThreadMessageLike(message, message.id, fallbackStatus),\n };\n }),\n };\n },\n};\n\ntype RepositoryParent = {\n children: string[];\n next: RepositoryMessage | null;\n};\n\ntype RepositoryMessage = RepositoryParent & {\n prev: RepositoryMessage | null;\n current: ThreadMessage;\n level: number;\n};\n\nconst findHead = (\n message: RepositoryMessage | RepositoryParent,\n): RepositoryMessage | null => {\n if (message.next) return findHead(message.next);\n if (\"current\" in message) return message;\n return null;\n};\n\nclass CachedValue<T> {\n private _value: T | null = null;\n\n private func: () => T;\n\n constructor(func: () => T) {\n this.func = func;\n }\n\n get value() {\n if (this._value === null) {\n this._value = this.func();\n }\n return this._value;\n }\n\n dirty() {\n this._value = null;\n }\n}\n\nexport class MessageRepository {\n private messages = new Map<string, RepositoryMessage>();\n private head: RepositoryMessage | null = null;\n private root: RepositoryParent = {\n children: [],\n next: null,\n };\n\n private updateLevels(message: RepositoryMessage, newLevel: number) {\n message.level = newLevel;\n for (const childId of message.children) {\n const childMessage = this.messages.get(childId);\n if (childMessage) {\n this.updateLevels(childMessage, newLevel + 1);\n }\n }\n }\n\n private performOp(\n newParent: RepositoryMessage | null,\n child: RepositoryMessage,\n operation: \"cut\" | \"link\" | \"relink\",\n ) {\n const parentOrRoot = child.prev ?? this.root;\n const newParentOrRoot = newParent ?? this.root;\n\n if (operation === \"relink\" && parentOrRoot === newParentOrRoot) return;\n\n if (operation !== \"cut\") {\n for (\n let current: RepositoryMessage | null = newParent;\n current;\n current = current.prev\n ) {\n if (current.current.id === child.current.id) {\n throw new Error(\n \"MessageRepository(performOp/link): A message with the same id already exists in the parent tree. This error occurs if the same message id is found multiple times. This is likely an internal bug in assistant-ui.\",\n );\n }\n }\n }\n\n if (operation !== \"link\") {\n parentOrRoot.children = parentOrRoot.children.filter(\n (m) => m !== child.current.id,\n );\n\n if (parentOrRoot.next === child) {\n const fallbackId = parentOrRoot.children.at(-1);\n const fallback = fallbackId ? this.messages.get(fallbackId) : null;\n if (fallback === undefined) {\n throw new Error(\n \"MessageRepository(performOp/cut): Fallback sibling message not found. This is likely an internal bug in assistant-ui.\",\n );\n }\n parentOrRoot.next = fallback;\n }\n }\n\n if (operation !== \"cut\") {\n newParentOrRoot.children = [\n ...newParentOrRoot.children,\n child.current.id,\n ];\n\n if (findHead(child) === this.head || newParentOrRoot.next === null) {\n newParentOrRoot.next = child;\n }\n\n child.prev = newParent;\n\n const newLevel = newParent ? newParent.level + 1 : 0;\n this.updateLevels(child, newLevel);\n }\n }\n\n private _messages = new CachedValue<readonly ThreadMessage[]>(() => {\n const messages = new Array<ThreadMessage>((this.head?.level ?? -1) + 1);\n for (let current = this.head; current; current = current.prev) {\n messages[current.level] = current.current;\n }\n return messages;\n });\n\n get headId() {\n return this.head?.current.id ?? null;\n }\n\n get canonicalHeadId() {\n // Optimistic messages are ephemeral, so persisted callers need the nearest\n // non-optimistic ancestor rather than the raw head.\n let head = this.head;\n while (head?.current.metadata?.isOptimistic) {\n head = head.prev;\n }\n return head?.current.id ?? null;\n }\n\n getMessages(headId?: string) {\n if (headId === undefined || headId === this.head?.current.id) {\n return this._messages.value;\n }\n\n const headMessage = this.messages.get(headId);\n if (!headMessage) {\n throw new Error(\n \"MessageRepository(getMessages): Head message not found. This is likely an internal bug in assistant-ui.\",\n );\n }\n\n const messages = new Array<ThreadMessage>(headMessage.level + 1);\n for (\n let current: RepositoryMessage | null = headMessage;\n current;\n current = current.prev\n ) {\n messages[current.level] = current.current;\n }\n return messages;\n }\n\n addOrUpdateMessage(parentId: string | null, message: ThreadMessage) {\n const existingItem = this.messages.get(message.id);\n const prev = parentId ? this.messages.get(parentId) : null;\n if (prev === undefined)\n throw new Error(\n \"MessageRepository(addOrUpdateMessage): Parent message not found. This is likely an internal bug in assistant-ui.\",\n );\n\n if (existingItem) {\n existingItem.current = message;\n this.performOp(prev, existingItem, \"relink\");\n this._messages.dirty();\n return;\n }\n\n const newItem: RepositoryMessage = {\n prev,\n current: message,\n next: null,\n children: [],\n level: prev ? prev.level + 1 : 0,\n };\n\n this.messages.set(message.id, newItem);\n this.performOp(prev, newItem, \"link\");\n\n if (this.head === prev) {\n this.head = newItem;\n }\n\n this._messages.dirty();\n }\n\n getMessage(messageId: string) {\n const message = this.messages.get(messageId);\n if (!message)\n throw new Error(\n \"MessageRepository(updateMessage): Message not found. This is likely an internal bug in assistant-ui.\",\n );\n\n return {\n parentId: message.prev?.current.id ?? null,\n message: message.current,\n index: message.level,\n };\n }\n\n deleteMessage(messageId: string, replacementId?: string | null | undefined) {\n const message = this.messages.get(messageId);\n\n if (!message)\n throw new Error(\n \"MessageRepository(deleteMessage): Message not found. This is likely an internal bug in assistant-ui.\",\n );\n\n const replacement =\n replacementId === undefined\n ? message.prev\n : replacementId === null\n ? null\n : this.messages.get(replacementId);\n if (replacement === undefined)\n throw new Error(\n \"MessageRepository(deleteMessage): Replacement not found. This is likely an internal bug in assistant-ui.\",\n );\n\n for (const child of message.children) {\n const childMessage = this.messages.get(child);\n if (!childMessage)\n throw new Error(\n \"MessageRepository(deleteMessage): Child message not found. This is likely an internal bug in assistant-ui.\",\n );\n this.performOp(replacement, childMessage, \"relink\");\n }\n\n this.performOp(null, message, \"cut\");\n this.messages.delete(messageId);\n\n if (this.head === message) {\n this.head = findHead(replacement ?? this.root);\n }\n\n this._messages.dirty();\n }\n\n getBranches(messageId: string) {\n const message = this.messages.get(messageId);\n if (!message)\n throw new Error(\n \"MessageRepository(getBranches): Message not found. This is likely an internal bug in assistant-ui.\",\n );\n\n const { children } = message.prev ?? this.root;\n return children;\n }\n\n /**\n * Evicts optimistic messages (`metadata.isOptimistic`) the head just moved\n * away from. Since eviction runs on every head move, the only optimistic\n * messages in the repository live on the branch the head previously pointed\n * at — so we walk just that branch rather than the whole repository. Keeps a\n * client→server id swap from leaving a phantom sibling, and drops off-branch\n * placeholders.\n */\n private evictOffBranchOptimisticMessages(\n previousHead: RepositoryMessage | null,\n currentHead: RepositoryMessage | null,\n ) {\n if (!previousHead) return;\n\n const onHeadBranch = new Set<string>();\n for (let current = currentHead; current; current = current.prev) {\n onHeadBranch.add(current.current.id);\n }\n\n const stale: string[] = [];\n for (\n let current: RepositoryMessage | null = previousHead;\n current;\n current = current.prev\n ) {\n // Stop at the first node shared with the current head branch: every\n // ancestor above it is shared too, so nothing further can be off-branch.\n if (onHeadBranch.has(current.current.id)) break;\n if (current.current.metadata?.isOptimistic) {\n stale.push(current.current.id);\n }\n }\n\n for (const id of stale) {\n // A prior deletion may have already removed this node.\n if (this.messages.has(id)) this.deleteMessage(id);\n }\n }\n\n switchToBranch(messageId: string) {\n const message = this.messages.get(messageId);\n if (!message)\n throw new Error(\n \"MessageRepository(switchToBranch): Branch not found. This is likely an internal bug in assistant-ui.\",\n );\n\n const previousHead = this.head;\n const prevOrRoot = message.prev ?? this.root;\n prevOrRoot.next = message;\n\n this.head = findHead(message);\n\n this.evictOffBranchOptimisticMessages(previousHead, this.head);\n\n this._messages.dirty();\n }\n\n resetHead(messageId: string | null) {\n if (messageId === null) {\n this.clear();\n return;\n }\n\n const message = this.messages.get(messageId);\n if (!message)\n throw new Error(\n \"MessageRepository(resetHead): Branch not found. This is likely an internal bug in assistant-ui.\",\n );\n\n const previousHead = this.head;\n\n if (message.children.length > 0) {\n const deleteDescendants = (msg: RepositoryMessage) => {\n for (const childId of msg.children) {\n const childMessage = this.messages.get(childId);\n if (childMessage) {\n deleteDescendants(childMessage);\n this.messages.delete(childId);\n }\n }\n };\n deleteDescendants(message);\n\n message.children = [];\n message.next = null;\n }\n\n this.head = message;\n for (\n let current: RepositoryMessage | null = message;\n current;\n current = current.prev\n ) {\n if (current.prev) {\n current.prev.next = current;\n } else {\n this.root.next = current;\n }\n }\n\n this.evictOffBranchOptimisticMessages(previousHead, this.head);\n\n this._messages.dirty();\n }\n\n clear(): void {\n this.messages.clear();\n this.head = null;\n this.root = {\n children: [],\n next: null,\n };\n this._messages.dirty();\n }\n\n export(): ExportedMessageRepository {\n const exportItems: ExportedMessageRepository[\"messages\"] = [];\n\n // Optimistic messages are ephemeral and never persisted. A persisted child\n // of an optimistic node is re-parented onto its nearest persisted ancestor\n // so the exported tree never references a skipped id.\n for (const [, message] of this.messages) {\n if (message.current.metadata?.isOptimistic) continue;\n let prev = message.prev;\n while (prev && prev.current.metadata?.isOptimistic) {\n prev = prev.prev;\n }\n exportItems.push({\n message: message.current,\n parentId: prev?.current.id ?? null,\n });\n }\n\n return {\n headId: this.canonicalHeadId,\n messages: exportItems,\n };\n }\n\n import({ headId, messages }: ExportedMessageRepository) {\n for (const { message, parentId } of messages) {\n this.addOrUpdateMessage(parentId, message);\n }\n\n this.resetHead(headId ?? messages.at(-1)?.message.id ?? null);\n }\n}\n"],"mappings":"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"}
@@ -5,7 +5,6 @@ import { ExternalStoreThreadRuntimeCore } from "./external-store-thread-runtime-
5
5
  //#region src/runtimes/external-store/external-store-thread-list-runtime-core.d.ts
6
6
  type ExternalStoreThreadFactory = () => ExternalStoreThreadRuntimeCore;
7
7
  declare class ExternalStoreThreadListRuntimeCore implements ThreadListRuntimeCore {
8
- private threadFactory;
9
8
  private _mainThreadId;
10
9
  private _threads;
11
10
  private _archivedThreads;
@@ -19,6 +18,7 @@ declare class ExternalStoreThreadListRuntimeCore implements ThreadListRuntimeCor
19
18
  getLoadThreadsPromise(): Promise<void>;
20
19
  private _mainThread;
21
20
  get mainThreadId(): string;
21
+ private threadFactory;
22
22
  constructor(adapter: ExternalStoreThreadListAdapter | undefined, threadFactory: ExternalStoreThreadFactory);
23
23
  getMainThreadRuntimeCore(): ExternalStoreThreadRuntimeCore;
24
24
  getThreadRuntimeCore(): never;
@@ -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;UAwC/C;UAvCF;UACA;UACA;UACA;UAEA;MAEG;MAIA;MAIA;MAIA;MAIA,eAAW,SAAA,eAAA;EAIf,yBAAqB;UAIpB;MAEG;EAKT,YAAA,SAAS,4CACD,eAAe;EAKlB,4BAAwB;EAIxB;EAIA,YAAY,mBAAgB;EAI5B,sBACL,SAAS,gCACT;EAqFW,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":";;;;;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,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"}
@@ -11,7 +11,6 @@ const DEFAULT_THREAD = Object.freeze({
11
11
  const RESOLVED_PROMISE = Promise.resolve();
12
12
  const DEFAULT_THREAD_DATA = Object.freeze({ [DEFAULT_THREAD_ID]: DEFAULT_THREAD });
13
13
  var ExternalStoreThreadListRuntimeCore = class {
14
- threadFactory;
15
14
  _mainThreadId = DEFAULT_THREAD_ID;
16
15
  _threads = DEFAULT_THREADS;
17
16
  _archivedThreads = EMPTY_ARRAY;
@@ -37,6 +36,7 @@ var ExternalStoreThreadListRuntimeCore = class {
37
36
  get mainThreadId() {
38
37
  return this._mainThreadId;
39
38
  }
39
+ threadFactory;
40
40
  constructor(adapter = {}, threadFactory) {
41
41
  this.threadFactory = threadFactory;
42
42
  this.__internal_setAdapter(adapter, true);
@@ -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","constructor","threadFactory","__internal_setAdapter","getMainThreadRuntimeCore","getThreadRuntimeCore","Error","getItemById","threadId","initialLoad","previousAdapter","newThreads","threads","newArchivedThreads","archivedThreads","previousThreadId","previousThreads","previousArchivedThreads","fromEntries","map","t","_notifySubscribers","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 constructor(\n adapter: ExternalStoreThreadListAdapter = {},\n private threadFactory: ExternalStoreThreadFactory,\n ) {\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 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","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","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 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 +1 @@
1
- {"version":3,"file":"external-store-thread-runtime-core.d.ts","names":[],"sources":["../../../src/runtimes/external-store/external-store-thread-runtime-core.ts"],"mappings":";;;;;;;;;;;;;;;cAkDa,qBACX,oBACA,mBAAmB;cAKR,uCACH,iCACG;UAEH;MAgBG,gBAAY;UAIf;EACD;EACA;MACI;MAIA;YAIQ,6BAA6B;MAI5B,sEAAK,sDAAA;MAId;kBARqC;;;;;;;EAYzC,sBAAsB;EACtB;UAEC;UAEA;;;;;UAMA;EAEQ,UAAU;EAQxB,YAAA,iBAAiB,sBACjB,OAAO;EAMF,sBAAsB,OAAO;;;;;;;UA8K5B;;;;;UAmEA;UACA;;;;;;;UAQA;EAmBQ,eAAe;;;;;;;;;UA6BvB;EAaK,OAAO,SAAS,gBAAgB;EA8BhC,cAAc,oBAAoB;EAoBxC,0BApBwC;EA0BxC,eAAe;EAIf,gBAAgB;EAIV,SAAS,QAAQ,iBAAiB;EAclC,UAAU,QAAQ,kBAAkB;EAO1C;EAOA,oBAAoB;EAmBpB;EA0CA,cAAc,SAAS;EAMvB,eAAe,SAAS;EAoBxB,sBAAsB,SAAS;EAMtB,MAAM,2BAA2B;EAMjC,OAAO,MAAM;UAQrB"}
1
+ {"version":3,"file":"external-store-thread-runtime-core.d.ts","names":[],"sources":["../../../src/runtimes/external-store/external-store-thread-runtime-core.ts"],"mappings":";;;;;;;;;;;;;;;cAkDa,qBACX,oBACA,mBAAmB;cAKR,uCACH,iCACG;UAEH;MAgBG,gBAAY;UAIf;EACD;EACA;MACI;MAIA;YAIQ,6BAA6B;MAI5B,sEAAK,sDAAA;MAId;kBARqC;;;;;;;EAYzC,sBAAsB;EACtB;UAEC;UAEA;;;;;UAMA;EAEQ,UAAU;EAQxB,YAAA,iBAAiB,sBACjB,OAAO;EAMF,sBAAsB,OAAO;;;;;;;UA6L5B;;;;;UAmEA;UACA;;;;;;;UAQA;EAmBQ,eAAe;;;;;;;;;UA6BvB;EAaK,OAAO,SAAS,gBAAgB;EA8BhC,cAAc,oBAAoB;EAoBxC,0BApBwC;EA0BxC,eAAe;EAIf,gBAAgB;EAIV,SAAS,QAAQ,iBAAiB;EAclC,UAAU,QAAQ,kBAAkB;EAO1C;EAOA,oBAAoB;EAmBpB;EA0CA,cAAc,SAAS;EAMvB,eAAe,SAAS;EAoBxB,sBAAsB,SAAS;EAMtB,MAAM,2BAA2B;EAMjC,OAAO,MAAM;UAQrB"}
@@ -133,6 +133,18 @@ var ExternalStoreThreadRuntimeCore = class extends BaseThreadRuntimeCore {
133
133
  bindExternalStoreMessage(newMessage, m);
134
134
  return newMessage;
135
135
  });
136
+ const seenIds = /* @__PURE__ */ new Set();
137
+ const deduped = [];
138
+ for (let i = messages.length - 1; i >= 0; i--) {
139
+ const message = messages[i];
140
+ if (seenIds.has(message.id)) {
141
+ console.warn(`ExternalStoreThreadRuntimeCore: duplicate message id "${message.id}" in the provided messages array; keeping the last occurrence.`);
142
+ continue;
143
+ }
144
+ seenIds.add(message.id);
145
+ deduped.push(message);
146
+ }
147
+ if (deduped.length !== messages.length) messages = deduped.reverse();
136
148
  for (let i = 0; i < messages.length; i++) {
137
149
  const message = messages[i];
138
150
  const parent = messages[i - 1];