@assistant-ui/core 0.3.14 → 0.3.16

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 (341) hide show
  1. package/dist/adapters/voice.js +11 -0
  2. package/dist/adapters/voice.js.map +1 -1
  3. package/dist/index.js +1 -1
  4. package/dist/internal.d.ts +8 -2
  5. package/dist/internal.js +9 -3
  6. package/dist/model-context/frame/host.d.ts +1 -1
  7. package/dist/model-context/frame/host.d.ts.map +1 -1
  8. package/dist/model-context/frame/host.js +20 -5
  9. package/dist/model-context/frame/host.js.map +1 -1
  10. package/dist/model-context/frame/provider.d.ts +6 -0
  11. package/dist/model-context/frame/provider.d.ts.map +1 -1
  12. package/dist/model-context/frame/provider.js +126 -16
  13. package/dist/model-context/frame/provider.js.map +1 -1
  14. package/dist/model-context/frame/types.d.ts +4 -1
  15. package/dist/model-context/frame/types.d.ts.map +1 -1
  16. package/dist/model-context/frame/types.js.map +1 -1
  17. package/dist/model-context/interactable-composer-metadata.d.ts +1 -1
  18. package/dist/model-context/interactable-composer-metadata.js +1 -1
  19. package/dist/model-context/interactable-composer-metadata.js.map +1 -1
  20. package/dist/model-context/registry.d.ts +2 -2
  21. package/dist/model-context/registry.d.ts.map +1 -1
  22. package/dist/model-context/registry.js +9 -28
  23. package/dist/model-context/registry.js.map +1 -1
  24. package/dist/react/client/InMemoryThreadList.d.ts.map +1 -1
  25. package/dist/react/client/InMemoryThreadList.js +24 -20
  26. package/dist/react/client/InMemoryThreadList.js.map +1 -1
  27. package/dist/react/client/Interactables.d.ts.map +1 -1
  28. package/dist/react/client/Interactables.js +59 -177
  29. package/dist/react/client/Interactables.js.map +1 -1
  30. package/dist/react/client/RemoteThreadList.d.ts +1 -1
  31. package/dist/react/client/RemoteThreadList.d.ts.map +1 -1
  32. package/dist/react/client/RemoteThreadList.js +117 -78
  33. package/dist/react/client/RemoteThreadList.js.map +1 -1
  34. package/dist/react/index.d.ts +2 -1
  35. package/dist/react/interactables-legacy/Interactables.d.ts.map +1 -1
  36. package/dist/react/interactables-legacy/Interactables.js +56 -174
  37. package/dist/react/interactables-legacy/Interactables.js.map +1 -1
  38. package/dist/react/interactables-shared/useInteractablePersistenceQueue.d.ts +24 -0
  39. package/dist/react/interactables-shared/useInteractablePersistenceQueue.d.ts.map +1 -0
  40. package/dist/react/interactables-shared/useInteractablePersistenceQueue.js +138 -0
  41. package/dist/react/interactables-shared/useInteractablePersistenceQueue.js.map +1 -0
  42. package/dist/react/primitive-hooks/useActionBarCopy.js +7 -1
  43. package/dist/react/primitive-hooks/useActionBarCopy.js.map +1 -1
  44. package/dist/react/primitive-hooks/useThreadIsEmpty.d.ts +3 -0
  45. package/dist/react/primitive-hooks/useThreadIsEmpty.d.ts.map +1 -1
  46. package/dist/react/primitive-hooks/useThreadIsEmpty.js +3 -0
  47. package/dist/react/primitive-hooks/useThreadIsEmpty.js.map +1 -1
  48. package/dist/react/primitive-hooks/useThreadIsRunning.d.ts +3 -0
  49. package/dist/react/primitive-hooks/useThreadIsRunning.d.ts.map +1 -1
  50. package/dist/react/primitive-hooks/useThreadIsRunning.js +3 -0
  51. package/dist/react/primitive-hooks/useThreadIsRunning.js.map +1 -1
  52. package/dist/react/primitives/composer/ComposerIf.js.map +1 -1
  53. package/dist/react/primitives/composer/ComposerQueue.d.ts +2 -1
  54. package/dist/react/primitives/composer/ComposerQueue.d.ts.map +1 -1
  55. package/dist/react/primitives/message/MessageParts.js.map +1 -1
  56. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.d.ts +3 -1
  57. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.d.ts.map +1 -1
  58. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js +6 -0
  59. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.js.map +1 -1
  60. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts +7 -1
  61. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts.map +1 -1
  62. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js +174 -64
  63. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js.map +1 -1
  64. package/dist/react/runtimes/RemoteThreadResource.d.ts.map +1 -1
  65. package/dist/react/runtimes/RemoteThreadResource.js +2 -0
  66. package/dist/react/runtimes/RemoteThreadResource.js.map +1 -1
  67. package/dist/react/runtimes/assistant-transport/runManager.d.ts.map +1 -1
  68. package/dist/react/runtimes/assistant-transport/runManager.js +2 -12
  69. package/dist/react/runtimes/assistant-transport/runManager.js.map +1 -1
  70. package/dist/react/runtimes/assistant-transport/useAssistantTransportRuntime.d.ts.map +1 -1
  71. package/dist/react/runtimes/assistant-transport/useAssistantTransportRuntime.js +1 -1
  72. package/dist/react/runtimes/assistant-transport/useAssistantTransportRuntime.js.map +1 -1
  73. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.d.ts +3 -10
  74. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.d.ts.map +1 -1
  75. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.js +20 -67
  76. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.js.map +1 -1
  77. package/dist/react/runtimes/cloud/createCloudThreadListAdapterCreateFallback.d.ts +12 -0
  78. package/dist/react/runtimes/cloud/createCloudThreadListAdapterCreateFallback.d.ts.map +1 -0
  79. package/dist/react/runtimes/cloud/createCloudThreadListAdapterCreateFallback.js +10 -0
  80. package/dist/react/runtimes/cloud/createCloudThreadListAdapterCreateFallback.js.map +1 -0
  81. package/dist/react/runtimes/cloud/useCloudThreadListAdapter.d.ts.map +1 -1
  82. package/dist/react/runtimes/cloud/useCloudThreadListAdapter.js +38 -5
  83. package/dist/react/runtimes/cloud/useCloudThreadListAdapter.js.map +1 -1
  84. package/dist/react/runtimes/cloud/useCloudThreadListRuntime.js.map +1 -1
  85. package/dist/react/runtimes/createMessageConverter.d.ts +2 -1
  86. package/dist/react/runtimes/createMessageConverter.d.ts.map +1 -1
  87. package/dist/react/runtimes/external-message-converter.d.ts +6 -25
  88. package/dist/react/runtimes/external-message-converter.d.ts.map +1 -1
  89. package/dist/react/runtimes/external-message-converter.js +33 -233
  90. package/dist/react/runtimes/external-message-converter.js.map +1 -1
  91. package/dist/runtime/api/composer-runtime.d.ts +1 -1
  92. package/dist/runtime/api/composer-runtime.js.map +1 -1
  93. package/dist/runtime/api/thread-runtime.d.ts +1 -2
  94. package/dist/runtime/api/thread-runtime.d.ts.map +1 -1
  95. package/dist/runtime/base/base-composer-runtime-core.d.ts +1 -1
  96. package/dist/runtime/base/base-composer-runtime-core.d.ts.map +1 -1
  97. package/dist/runtime/base/base-composer-runtime-core.js +14 -29
  98. package/dist/runtime/base/base-composer-runtime-core.js.map +1 -1
  99. package/dist/runtime/base/base-thread-runtime-core.d.ts +2 -4
  100. package/dist/runtime/base/base-thread-runtime-core.d.ts.map +1 -1
  101. package/dist/runtime/base/base-thread-runtime-core.js +3 -9
  102. package/dist/runtime/base/base-thread-runtime-core.js.map +1 -1
  103. package/dist/runtime/base/default-thread-composer-runtime-core.d.ts +1 -1
  104. package/dist/runtime/base/default-thread-composer-runtime-core.d.ts.map +1 -1
  105. package/dist/runtime/base/default-thread-composer-runtime-core.js +1 -1
  106. package/dist/runtime/base/default-thread-composer-runtime-core.js.map +1 -1
  107. package/dist/runtime/interfaces/composer-runtime-core.d.ts +1 -1
  108. package/dist/runtime/interfaces/thread-runtime-core.d.ts +1 -1
  109. package/dist/runtime/internal.d.ts +2 -1
  110. package/dist/runtime/internal.js +2 -1
  111. package/dist/runtime/queue/external-thread-queue-adapter.d.ts +1 -1
  112. package/dist/runtime/queue/message-queue.d.ts.map +1 -1
  113. package/dist/runtime/queue/message-queue.js +1 -1
  114. package/dist/runtime/queue/message-queue.js.map +1 -1
  115. package/dist/runtime/queue/queue-item.d.ts +12 -0
  116. package/dist/runtime/queue/queue-item.d.ts.map +1 -0
  117. package/dist/runtime/queue/queue-item.js +6 -0
  118. package/dist/runtime/queue/queue-item.js.map +1 -0
  119. package/dist/runtime/utils/abortable-thread-load.d.ts +15 -0
  120. package/dist/runtime/utils/abortable-thread-load.d.ts.map +1 -0
  121. package/dist/runtime/utils/abortable-thread-load.js +35 -0
  122. package/dist/runtime/utils/abortable-thread-load.js.map +1 -0
  123. package/dist/runtime/utils/attachment-add-operations.d.ts +18 -0
  124. package/dist/runtime/utils/attachment-add-operations.d.ts.map +1 -0
  125. package/dist/runtime/utils/attachment-add-operations.js +43 -0
  126. package/dist/runtime/utils/attachment-add-operations.js.map +1 -0
  127. package/dist/runtime/utils/auto-status.d.ts +6 -1
  128. package/dist/runtime/utils/auto-status.d.ts.map +1 -1
  129. package/dist/runtime/utils/auto-status.js +7 -1
  130. package/dist/runtime/utils/auto-status.js.map +1 -1
  131. package/dist/runtime/utils/external-message-conversion.d.ts +47 -0
  132. package/dist/runtime/utils/external-message-conversion.d.ts.map +1 -0
  133. package/dist/runtime/utils/external-message-conversion.js +221 -0
  134. package/dist/runtime/utils/external-message-conversion.js.map +1 -0
  135. package/dist/runtime/utils/external-store-message.d.ts +2 -1
  136. package/dist/runtime/utils/external-store-message.d.ts.map +1 -1
  137. package/dist/runtime/utils/external-store-message.js +2 -1
  138. package/dist/runtime/utils/external-store-message.js.map +1 -1
  139. package/dist/runtime/utils/message-repository-session.d.ts +30 -0
  140. package/dist/runtime/utils/message-repository-session.d.ts.map +1 -0
  141. package/dist/runtime/utils/message-repository-session.js +130 -0
  142. package/dist/runtime/utils/message-repository-session.js.map +1 -0
  143. package/dist/runtime/utils/message-repository.d.ts.map +1 -1
  144. package/dist/runtime/utils/message-repository.js +30 -22
  145. package/dist/runtime/utils/message-repository.js.map +1 -1
  146. package/dist/runtime/utils/pending-tool-calls.d.ts +20 -0
  147. package/dist/runtime/utils/pending-tool-calls.d.ts.map +1 -0
  148. package/dist/runtime/utils/pending-tool-calls.js +22 -0
  149. package/dist/runtime/utils/pending-tool-calls.js.map +1 -0
  150. package/dist/runtime/utils/thread-message-like.d.ts +2 -1
  151. package/dist/runtime/utils/thread-message-like.d.ts.map +1 -1
  152. package/dist/runtime/utils/thread-message-like.js.map +1 -1
  153. package/dist/runtimes/external-store/external-store-thread-list-runtime-core.d.ts +2 -5
  154. package/dist/runtimes/external-store/external-store-thread-list-runtime-core.d.ts.map +1 -1
  155. package/dist/runtimes/external-store/external-store-thread-list-runtime-core.js +3 -10
  156. package/dist/runtimes/external-store/external-store-thread-list-runtime-core.js.map +1 -1
  157. package/dist/runtimes/external-store/external-store-thread-runtime-core.d.ts +19 -1
  158. package/dist/runtimes/external-store/external-store-thread-runtime-core.d.ts.map +1 -1
  159. package/dist/runtimes/external-store/external-store-thread-runtime-core.js +124 -20
  160. package/dist/runtimes/external-store/external-store-thread-runtime-core.js.map +1 -1
  161. package/dist/runtimes/inert/InertThreadRuntimeCore.d.ts +102 -0
  162. package/dist/runtimes/inert/InertThreadRuntimeCore.d.ts.map +1 -0
  163. package/dist/runtimes/inert/InertThreadRuntimeCore.js +156 -0
  164. package/dist/runtimes/inert/InertThreadRuntimeCore.js.map +1 -0
  165. package/dist/runtimes/local/local-thread-runtime-core.d.ts +3 -1
  166. package/dist/runtimes/local/local-thread-runtime-core.d.ts.map +1 -1
  167. package/dist/runtimes/local/local-thread-runtime-core.js +45 -8
  168. package/dist/runtimes/local/local-thread-runtime-core.js.map +1 -1
  169. package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.d.ts +12 -60
  170. package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.d.ts.map +1 -1
  171. package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.js +10 -145
  172. package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.js.map +1 -1
  173. package/dist/runtimes/remote-thread-list/adapter-changed.d.ts +9 -0
  174. package/dist/runtimes/remote-thread-list/adapter-changed.d.ts.map +1 -0
  175. package/dist/runtimes/remote-thread-list/adapter-changed.js +13 -0
  176. package/dist/runtimes/remote-thread-list/adapter-changed.js.map +1 -0
  177. package/dist/runtimes/remote-thread-list/empty-thread-core.d.ts.map +1 -1
  178. package/dist/runtimes/remote-thread-list/empty-thread-core.js +16 -155
  179. package/dist/runtimes/remote-thread-list/empty-thread-core.js.map +1 -1
  180. package/dist/runtimes/remote-thread-list/optimistic-state.d.ts +2 -0
  181. package/dist/runtimes/remote-thread-list/optimistic-state.d.ts.map +1 -1
  182. package/dist/runtimes/remote-thread-list/optimistic-state.js +11 -0
  183. package/dist/runtimes/remote-thread-list/optimistic-state.js.map +1 -1
  184. package/dist/runtimes/remote-thread-list/remote-thread-state.d.ts +12 -1
  185. package/dist/runtimes/remote-thread-list/remote-thread-state.d.ts.map +1 -1
  186. package/dist/runtimes/remote-thread-list/remote-thread-state.js +77 -1
  187. package/dist/runtimes/remote-thread-list/remote-thread-state.js.map +1 -1
  188. package/dist/runtimes/remote-thread-list/types.d.ts +3 -0
  189. package/dist/runtimes/remote-thread-list/types.d.ts.map +1 -1
  190. package/dist/runtimes/tool-invocations/ToolInvocationTracker.d.ts.map +1 -1
  191. package/dist/runtimes/tool-invocations/ToolInvocationTracker.js +2 -0
  192. package/dist/runtimes/tool-invocations/ToolInvocationTracker.js.map +1 -1
  193. package/dist/store/clients/external-thread.d.ts.map +1 -1
  194. package/dist/store/clients/external-thread.js +75 -100
  195. package/dist/store/clients/external-thread.js.map +1 -1
  196. package/dist/store/clients/single-thread-list.d.ts.map +1 -1
  197. package/dist/store/clients/single-thread-list.js +1 -1
  198. package/dist/store/clients/single-thread-list.js.map +1 -1
  199. package/dist/store/clients/suggestions.d.ts.map +1 -1
  200. package/dist/store/clients/suggestions.js +16 -7
  201. package/dist/store/clients/suggestions.js.map +1 -1
  202. package/dist/store/index.d.ts +4 -2
  203. package/dist/store/runtime-clients/handle-runtime-action.d.ts.map +1 -1
  204. package/dist/store/runtime-clients/handle-runtime-action.js +2 -0
  205. package/dist/store/runtime-clients/handle-runtime-action.js.map +1 -1
  206. package/dist/store/scope-registration.d.ts +1 -1
  207. package/dist/store/scopes/composer.d.ts +2 -1
  208. package/dist/store/scopes/composer.d.ts.map +1 -1
  209. package/dist/store/scopes/message.d.ts +1 -1
  210. package/dist/store/scopes/queue-item.d.ts +2 -9
  211. package/dist/store/scopes/queue-item.d.ts.map +1 -1
  212. package/dist/store/scopes/queue-item.js +0 -6
  213. package/dist/types/message.d.ts +8 -4
  214. package/dist/types/message.d.ts.map +1 -1
  215. package/dist/types/message.js.map +1 -1
  216. package/dist/utils/data-url.d.ts +14 -1
  217. package/dist/utils/data-url.d.ts.map +1 -1
  218. package/dist/utils/data-url.js +13 -1
  219. package/dist/utils/data-url.js.map +1 -1
  220. package/dist/utils/invoke-user-callback.d.ts +5 -0
  221. package/dist/utils/invoke-user-callback.d.ts.map +1 -0
  222. package/dist/utils/invoke-user-callback.js +19 -0
  223. package/dist/utils/invoke-user-callback.js.map +1 -0
  224. package/dist/utils/normalizePartStatus.js.map +1 -1
  225. package/dist/utils/silent-runtime-action.d.ts +6 -0
  226. package/dist/utils/silent-runtime-action.d.ts.map +1 -0
  227. package/dist/utils/silent-runtime-action.js +7 -0
  228. package/dist/utils/silent-runtime-action.js.map +1 -0
  229. package/package.json +10 -10
  230. package/src/adapters/voice.test.ts +66 -1
  231. package/src/adapters/voice.ts +8 -0
  232. package/src/internal.ts +13 -0
  233. package/src/model-context/frame/host.test.ts +152 -9
  234. package/src/model-context/frame/host.ts +23 -5
  235. package/src/model-context/frame/provider.test.ts +601 -19
  236. package/src/model-context/frame/provider.ts +158 -20
  237. package/src/model-context/frame/types.ts +5 -0
  238. package/src/model-context/interactable-composer-metadata.ts +1 -1
  239. package/src/model-context/registry.test.ts +44 -0
  240. package/src/model-context/registry.ts +13 -35
  241. package/src/react/client/InMemoryThreadList.test.tsx +49 -0
  242. package/src/react/client/InMemoryThreadList.ts +7 -1
  243. package/src/react/client/Interactables.ts +19 -178
  244. package/src/react/client/RemoteThreadList.test.ts +292 -0
  245. package/src/react/client/RemoteThreadList.ts +119 -82
  246. package/src/react/interactables-legacy/Interactables.ts +20 -177
  247. package/src/react/interactables-shared/useInteractablePersistenceQueue.test.tsx +161 -0
  248. package/src/react/interactables-shared/useInteractablePersistenceQueue.ts +206 -0
  249. package/src/react/primitive-hooks/useActionBarCopy.test.ts +15 -0
  250. package/src/react/primitive-hooks/useActionBarCopy.ts +13 -3
  251. package/src/react/primitive-hooks/useThreadIsEmpty.ts +3 -0
  252. package/src/react/primitive-hooks/useThreadIsRunning.ts +3 -0
  253. package/src/react/runtimes/RemoteThreadListHookInstanceManager.tsx +12 -0
  254. package/src/react/runtimes/RemoteThreadListThreadListRuntimeCore.republish.test.ts +87 -0
  255. package/src/react/runtimes/RemoteThreadListThreadListRuntimeCore.tsx +251 -76
  256. package/src/react/runtimes/RemoteThreadResource.ts +2 -0
  257. package/src/react/runtimes/assistant-transport/runManager.ts +4 -17
  258. package/src/react/runtimes/assistant-transport/useAssistantTransportRuntime.test.tsx +58 -0
  259. package/src/react/runtimes/assistant-transport/useAssistantTransportRuntime.ts +3 -1
  260. package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.test.tsx +92 -0
  261. package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.ts +40 -141
  262. package/src/react/runtimes/cloud/createCloudThreadListAdapterCreateFallback.test.ts +37 -0
  263. package/src/react/runtimes/cloud/createCloudThreadListAdapterCreateFallback.ts +18 -0
  264. package/src/react/runtimes/cloud/useCloudThreadListAdapter.test.tsx +98 -3
  265. package/src/react/runtimes/cloud/useCloudThreadListAdapter.tsx +68 -6
  266. package/src/react/runtimes/external-message-converter.test.ts +0 -14
  267. package/src/react/runtimes/external-message-converter.test.tsx +77 -0
  268. package/src/react/runtimes/external-message-converter.ts +58 -481
  269. package/src/react/runtimes/useLocalRuntime.test.tsx +5 -5
  270. package/src/runtime/api/composer-runtime.ts +1 -1
  271. package/src/runtime/api/message-runtime.test.ts +28 -1
  272. package/src/runtime/base/base-composer-runtime-core.ts +20 -40
  273. package/src/runtime/base/base-thread-runtime-core.test.ts +16 -0
  274. package/src/runtime/base/base-thread-runtime-core.ts +6 -11
  275. package/src/runtime/base/default-thread-composer-runtime-core.ts +1 -4
  276. package/src/runtime/interfaces/composer-runtime-core.ts +1 -1
  277. package/src/runtime/interfaces/thread-runtime-core.ts +1 -1
  278. package/src/runtime/internal.ts +5 -0
  279. package/src/runtime/queue/external-thread-queue-adapter.ts +1 -1
  280. package/src/runtime/queue/message-queue.ts +1 -4
  281. package/src/runtime/queue/queue-item.ts +10 -0
  282. package/src/runtime/utils/abortable-thread-load.test.ts +87 -0
  283. package/src/runtime/utils/abortable-thread-load.ts +53 -0
  284. package/src/runtime/utils/attachment-add-operations.ts +59 -0
  285. package/src/runtime/utils/auto-status.ts +33 -0
  286. package/src/runtime/utils/external-message-conversion.test.ts +113 -0
  287. package/src/runtime/utils/external-message-conversion.ts +494 -0
  288. package/src/runtime/utils/external-store-message.ts +2 -0
  289. package/src/runtime/utils/message-repository-session.test.ts +195 -0
  290. package/src/runtime/utils/message-repository-session.ts +176 -0
  291. package/src/runtime/utils/message-repository.ts +33 -22
  292. package/src/runtime/utils/pending-tool-calls.test.ts +57 -0
  293. package/src/runtime/utils/pending-tool-calls.ts +35 -0
  294. package/src/runtime/utils/thread-message-like.ts +2 -0
  295. package/src/runtimes/external-store/external-store-thread-list-runtime-core.ts +6 -14
  296. package/src/runtimes/external-store/external-store-thread-runtime-core.ts +179 -28
  297. package/src/runtimes/inert/InertThreadRuntimeCore.test.ts +253 -0
  298. package/src/runtimes/inert/InertThreadRuntimeCore.ts +232 -0
  299. package/src/runtimes/local/local-thread-runtime-core.test.ts +491 -1
  300. package/src/runtimes/local/local-thread-runtime-core.ts +86 -11
  301. package/src/runtimes/readonly/ReadonlyThreadRuntimeCore.ts +17 -209
  302. package/src/runtimes/remote-thread-list/adapter-changed.ts +10 -0
  303. package/src/runtimes/remote-thread-list/empty-thread-core.ts +28 -221
  304. package/src/runtimes/remote-thread-list/optimistic-state.test.ts +18 -0
  305. package/src/runtimes/remote-thread-list/optimistic-state.ts +13 -0
  306. package/src/runtimes/remote-thread-list/remote-thread-state.test.ts +37 -0
  307. package/src/runtimes/remote-thread-list/remote-thread-state.ts +123 -0
  308. package/src/runtimes/remote-thread-list/types.ts +4 -0
  309. package/src/runtimes/tool-invocations/EDGE_CASES.md +17 -0
  310. package/src/runtimes/tool-invocations/ToolInvocationTracker.test.ts +140 -0
  311. package/src/runtimes/tool-invocations/ToolInvocationTracker.ts +3 -0
  312. package/src/store/clients/external-thread.ts +17 -62
  313. package/src/store/clients/single-thread-list.ts +4 -1
  314. package/src/store/clients/suggestions.test.ts +31 -0
  315. package/src/store/clients/suggestions.ts +18 -19
  316. package/src/store/runtime-clients/handle-runtime-action.test.ts +40 -0
  317. package/src/store/runtime-clients/handle-runtime-action.ts +3 -0
  318. package/src/store/scopes/message.ts +1 -1
  319. package/src/store/scopes/queue-item.ts +2 -9
  320. package/src/tests/MessageRepository.test.ts +125 -0
  321. package/src/tests/RemoteThreadListThreadListRuntimeCore-errors.test.ts +2 -2
  322. package/src/tests/RemoteThreadListThreadListRuntimeCore-load-race.test.ts +194 -0
  323. package/src/tests/RemoteThreadListThreadListRuntimeCore-loadMore.test.ts +8 -6
  324. package/src/tests/RemoteThreadListThreadListRuntimeCore-title-race.test.ts +158 -0
  325. package/src/tests/empty-thread-core.test.ts +6 -0
  326. package/src/tests/external-store-thread-runtime-core-adapter.test.ts +184 -0
  327. package/src/tests/external-store-thread-runtime-core.test.ts +642 -0
  328. package/src/tests/external-thread-attachments.test.tsx +173 -0
  329. package/src/tests/external-thread-isEmpty.test.tsx +100 -0
  330. package/src/tests/remote-thread-list-adapter-switch.test.ts +383 -0
  331. package/src/tests/single-thread-list-item.test.tsx +47 -0
  332. package/src/tests/thread-message-like.test.ts +39 -1
  333. package/src/tests/useRemoteThreadListRuntime-controlled.test.tsx +67 -0
  334. package/src/types/message.ts +9 -4
  335. package/src/utils/data-url.test.ts +52 -1
  336. package/src/utils/data-url.ts +21 -0
  337. package/src/utils/invoke-user-callback.test.ts +82 -0
  338. package/src/utils/invoke-user-callback.ts +31 -0
  339. package/src/utils/normalizePartStatus.ts +1 -1
  340. package/src/utils/silent-runtime-action.ts +6 -0
  341. package/dist/store/scopes/queue-item.js.map +0 -1
@@ -0,0 +1,221 @@
1
+ import { isJSONValueEqual } from "../../utils/json/is-json-equal.js";
2
+ import { generateErrorMessageId } from "../../utils/id.js";
3
+ import { fromThreadMessageLike } from "./thread-message-like.js";
4
+ import { FALLBACK_ID_PREFIX, bindExternalStoreMessage, getExternalStoreMessages, symbolInnerMessage } from "./external-store-message.js";
5
+ import { getAutoStatus, isAutoStatus, isInterruptedToolCall, isPendingToolCall } from "./auto-status.js";
6
+ //#region src/runtime/utils/external-message-conversion.ts
7
+ const stringifyForError = (value) => {
8
+ let text;
9
+ try {
10
+ text = value instanceof Error ? String(value) : JSON.stringify(value);
11
+ } catch {}
12
+ text ??= String(value);
13
+ return text.length > 200 ? `${text.slice(0, 200)}…` : text;
14
+ };
15
+ const toCallbackOutputs = (output, input) => {
16
+ const outputs = Array.isArray(output) ? output : [output];
17
+ for (const o of outputs) if (!(typeof o === "object" && o !== null && (o.role === "tool" || (o.role === "assistant" || o.role === "user" || o.role === "system") && (typeof o.content === "string" || Array.isArray(o.content))))) throw new Error(`External message converter: the converter callback returned an invalid message (${stringifyForError(o)}) for input ${stringifyForError(input)}. Return an empty array to skip a message.`);
18
+ return outputs.filter((o) => {
19
+ if (o.role !== "tool") return true;
20
+ if (typeof o.toolCallId === "string" && o.toolCallId.length > 0) return true;
21
+ if (!warnedDroppedToolResults.has(o)) {
22
+ warnedDroppedToolResults.add(o);
23
+ console.warn(`External message converter: dropping a tool result without a toolCallId (${stringifyForError(o)}) for input ${stringifyForError(input)}.`);
24
+ }
25
+ return false;
26
+ });
27
+ };
28
+ const warnedDroppedToolResults = /* @__PURE__ */ new WeakSet();
29
+ const convertExternalMessageCallback = (input, callback, metadata) => ({
30
+ input,
31
+ outputs: toCallbackOutputs(callback(input, metadata), input)
32
+ });
33
+ const mergeInnerMessages = (existing, incoming) => ({ [symbolInnerMessage]: [...existing[symbolInnerMessage] ?? [], ...incoming[symbolInnerMessage] ?? []] });
34
+ const joinExternalMessages = (messages) => {
35
+ const assistantMessage = {
36
+ role: "assistant",
37
+ content: []
38
+ };
39
+ for (const output of messages) if (output.role === "tool") {
40
+ const toolCallIdx = assistantMessage.content.findIndex((c) => c.type === "tool-call" && c.toolCallId === output.toolCallId);
41
+ if (toolCallIdx !== -1) {
42
+ const toolCall = assistantMessage.content[toolCallIdx];
43
+ if (output.toolName != null) {
44
+ if (toolCall.toolName !== output.toolName) throw new Error(`Tool call name ${output.toolCallId} ${output.toolName} does not match existing tool call ${toolCall.toolName}`);
45
+ }
46
+ assistantMessage.content[toolCallIdx] = {
47
+ ...toolCall,
48
+ [symbolInnerMessage]: [...toolCall[symbolInnerMessage] ?? [], output],
49
+ result: output.result,
50
+ artifact: output.artifact,
51
+ isError: output.isError,
52
+ messages: output.messages
53
+ };
54
+ }
55
+ } else {
56
+ const role = output.role;
57
+ const content = (typeof output.content === "string" ? [{
58
+ type: "text",
59
+ text: output.content
60
+ }] : output.content).map((c) => ({
61
+ ...c,
62
+ [symbolInnerMessage]: [output]
63
+ }));
64
+ switch (role) {
65
+ case "system":
66
+ case "user": return {
67
+ ...output,
68
+ content
69
+ };
70
+ case "assistant":
71
+ if (assistantMessage.content.length === 0) {
72
+ assistantMessage.id = output.id;
73
+ assistantMessage.createdAt ??= output.createdAt;
74
+ assistantMessage.status ??= output.status;
75
+ if (output.attachments) assistantMessage.attachments = [...assistantMessage.attachments ?? [], ...output.attachments];
76
+ }
77
+ if (output.metadata) {
78
+ assistantMessage.metadata ??= {};
79
+ if (output.metadata.unstable_state !== void 0) assistantMessage.metadata.unstable_state = output.metadata.unstable_state;
80
+ if (output.metadata.unstable_annotations) assistantMessage.metadata.unstable_annotations = [...assistantMessage.metadata.unstable_annotations ?? [], ...output.metadata.unstable_annotations];
81
+ if (output.metadata.unstable_data) assistantMessage.metadata.unstable_data = [...assistantMessage.metadata.unstable_data ?? [], ...output.metadata.unstable_data];
82
+ if (output.metadata.steps) assistantMessage.metadata.steps = [...assistantMessage.metadata.steps ?? [], ...output.metadata.steps];
83
+ if (output.metadata.custom) assistantMessage.metadata.custom = {
84
+ ...assistantMessage.metadata.custom ?? {},
85
+ ...output.metadata.custom
86
+ };
87
+ if (output.metadata.timing) assistantMessage.metadata.timing = output.metadata.timing;
88
+ if (output.metadata.submittedFeedback) assistantMessage.metadata.submittedFeedback = output.metadata.submittedFeedback;
89
+ if (output.metadata.isOptimistic) assistantMessage.metadata.isOptimistic = true;
90
+ }
91
+ for (const part of content) {
92
+ if (part.type === "tool-call") {
93
+ const existingIdx = assistantMessage.content.findIndex((c) => c.type === "tool-call" && c.toolCallId === part.toolCallId);
94
+ if (existingIdx !== -1) {
95
+ const existing = assistantMessage.content[existingIdx];
96
+ assistantMessage.content[existingIdx] = {
97
+ ...existing,
98
+ ...part,
99
+ ...mergeInnerMessages(existing, part)
100
+ };
101
+ continue;
102
+ }
103
+ }
104
+ if (part.type === "reasoning" && "parentId" in part && part.parentId) {
105
+ const existingIdx = assistantMessage.content.findIndex((c) => c.type === "reasoning" && "parentId" in c && c.parentId === part.parentId);
106
+ if (existingIdx !== -1) {
107
+ const existing = assistantMessage.content[existingIdx];
108
+ assistantMessage.content[existingIdx] = {
109
+ ...existing,
110
+ text: `${existing.text}\n\n${part.text}`,
111
+ ...mergeInnerMessages(existing, part)
112
+ };
113
+ continue;
114
+ }
115
+ }
116
+ assistantMessage.content.push(part);
117
+ }
118
+ break;
119
+ default: throw new Error(`Unknown message role: ${role}`);
120
+ }
121
+ }
122
+ return assistantMessage;
123
+ };
124
+ const chunkExternalMessages = (callbackResults, joinStrategy) => {
125
+ const results = [];
126
+ let isAssistant = false;
127
+ let pendingNone = false;
128
+ let inputs = [];
129
+ let outputs = [];
130
+ const flush = () => {
131
+ if (outputs.length) results.push({
132
+ inputs,
133
+ outputs
134
+ });
135
+ inputs = [];
136
+ outputs = [];
137
+ isAssistant = false;
138
+ pendingNone = false;
139
+ };
140
+ for (const callbackResult of callbackResults) for (const output of callbackResult.outputs) {
141
+ if (pendingNone && output.role !== "tool" || !isAssistant || output.role === "user" || output.role === "system") flush();
142
+ isAssistant = output.role === "assistant" || output.role === "tool";
143
+ if (inputs.at(-1) !== callbackResult.input) inputs.push(callbackResult.input);
144
+ outputs.push(output);
145
+ if (output.role === "assistant" && (output.convertConfig?.joinStrategy === "none" || joinStrategy === "none")) pendingNone = true;
146
+ }
147
+ flush();
148
+ return results;
149
+ };
150
+ const shallowArrayEqual = (a, b) => {
151
+ if (a.length !== b.length) return false;
152
+ for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false;
153
+ return true;
154
+ };
155
+ const convertExternalMessageChunk = (message, idx, chunkCount, isRunning, error, cache) => {
156
+ const isLast = idx === chunkCount - 1;
157
+ const joined = joinExternalMessages(message.outputs);
158
+ const hasInterruptedToolCalls = typeof joined.content === "object" && joined.content.some(isInterruptedToolCall);
159
+ const hasPendingToolCalls = typeof joined.content === "object" && joined.content.some(isPendingToolCall);
160
+ const autoStatus = getAutoStatus(isLast, isRunning, hasInterruptedToolCalls, hasPendingToolCalls, isLast ? error : void 0);
161
+ const fallbackId = `${FALLBACK_ID_PREFIX}${idx}`;
162
+ const cachedMessage = cache?.message;
163
+ if (cachedMessage && (cachedMessage.role !== "assistant" || !isAutoStatus(cachedMessage.status) || cachedMessage.status === autoStatus || cachedMessage.status.type === "incomplete" && cachedMessage.status.reason === "error" && cachedMessage.status.error !== void 0 && autoStatus.type === "incomplete" && autoStatus.reason === "error" && autoStatus.error !== void 0 && (cachedMessage.status.error === autoStatus.error || isJSONValueEqual(cachedMessage.status.error, autoStatus.error)))) {
164
+ const inputs = getExternalStoreMessages(cachedMessage);
165
+ if (shallowArrayEqual(inputs, message.inputs)) {
166
+ if (cache.generatedFallbackMessages.has(cachedMessage) && cachedMessage.id !== fallbackId) {
167
+ const updated = {
168
+ ...cachedMessage,
169
+ id: fallbackId
170
+ };
171
+ cache.generatedFallbackMessages.add(updated);
172
+ bindExternalStoreMessage(updated, message.inputs);
173
+ return updated;
174
+ }
175
+ return cachedMessage;
176
+ }
177
+ }
178
+ const newMessage = fromThreadMessageLike(joined, fallbackId, autoStatus);
179
+ if (cache && joined.id == null) cache.generatedFallbackMessages.add(newMessage);
180
+ bindExternalStoreMessage(newMessage, message.inputs);
181
+ return newMessage;
182
+ };
183
+ function createErrorAssistantMessage(error) {
184
+ const msg = {
185
+ id: generateErrorMessageId(),
186
+ role: "assistant",
187
+ content: [],
188
+ status: {
189
+ type: "incomplete",
190
+ reason: "error",
191
+ error
192
+ },
193
+ createdAt: /* @__PURE__ */ new Date(),
194
+ metadata: {
195
+ unstable_state: null,
196
+ unstable_annotations: [],
197
+ unstable_data: [],
198
+ custom: {},
199
+ steps: []
200
+ }
201
+ };
202
+ bindExternalStoreMessage(msg, []);
203
+ return msg;
204
+ }
205
+ const completeExternalMessageConversion = (messages, error) => {
206
+ if (error) {
207
+ const lastMessage = messages.at(-1);
208
+ if (!lastMessage || lastMessage.role !== "assistant") messages.push(createErrorAssistantMessage(error));
209
+ }
210
+ return messages;
211
+ };
212
+ const convertExternalMessages = (messages, callback, isRunning, metadata) => {
213
+ const callbackResults = messages.map((message) => convertExternalMessageCallback(message, callback, metadata));
214
+ const chunks = chunkExternalMessages(callbackResults);
215
+ const result = chunks.map((message, idx) => convertExternalMessageChunk(message, idx, chunks.length, isRunning, metadata.error));
216
+ return completeExternalMessageConversion(result, metadata.error);
217
+ };
218
+ //#endregion
219
+ export { chunkExternalMessages, completeExternalMessageConversion, convertExternalMessageCallback, convertExternalMessageChunk, convertExternalMessages, joinExternalMessages, shallowArrayEqual };
220
+
221
+ //# sourceMappingURL=external-message-conversion.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"external-message-conversion.js","names":["ReadonlyJSONValue","ToolExecutionStatus","ThreadAssistantMessage","ThreadMessage","ToolCallMessagePart","MessageTiming","generateErrorMessageId","isJSONValueEqual","getAutoStatus","isAutoStatus","isInterruptedToolCall","isPendingToolCall","bindExternalStoreMessage","FALLBACK_ID_PREFIX","getExternalStoreMessages","symbolInnerMessage","fromThreadMessageLike","ThreadMessageLike","JoinStrategy","ExternalMessageConverterMessage","convertConfig","joinStrategy","role","toolCallId","toolName","result","artifact","isError","messages","ExternalMessageConverterMetadata","toolStatuses","Record","error","messageTiming","ExternalMessageConverterCallback","message","T","metadata","ExternalMessageConverterCallbackResult","input","outputs","ExternalMessageConverterChunk","inputs","Mutable","P","stringifyForError","value","text","Error","String","JSON","stringify","length","slice","toCallbackOutputs","output","Array","isArray","o","valid","content","filter","warnedDroppedToolResults","has","add","console","warn","WeakSet","convertExternalMessageCallback","callback","mergeInnerMessages","existing","incoming","joinExternalMessages","assistantMessage","Omit","Exclude","toolCallIdx","findIndex","c","type","toolCall","const","map","id","createdAt","status","attachments","unstable_state","undefined","unstable_annotations","unstable_data","steps","custom","timing","submittedFeedback","isOptimistic","part","existingIdx","parentId","push","unsupportedRole","chunkExternalMessages","callbackResults","results","isAssistant","pendingNone","flush","callbackResult","at","shallowArrayEqual","a","b","i","ExternalMessageConversionCache","generatedFallbackMessages","convertExternalMessageChunk","idx","chunkCount","isRunning","cache","isLast","joined","hasInterruptedToolCalls","some","hasPendingToolCalls","autoStatus","fallbackId","cachedMessage","reason","updated","newMessage","createErrorAssistantMessage","msg","Date","completeExternalMessageConversion","lastMessage","convertExternalMessages","WeakKey","chunks"],"sources":["../../../src/runtime/utils/external-message-conversion.ts"],"sourcesContent":["import type { ReadonlyJSONValue } from \"assistant-stream/utils\";\nimport type { ToolExecutionStatus } from \"../../runtimes/tool-invocations/ToolInvocationTracker\";\nimport type {\n ThreadAssistantMessage,\n ThreadMessage,\n ToolCallMessagePart,\n} from \"../../types/message\";\nimport type { MessageTiming } from \"../../types/message\";\nimport { generateErrorMessageId } from \"../../utils/id\";\nimport { isJSONValueEqual } from \"../../utils/json/is-json-equal\";\nimport {\n getAutoStatus,\n isAutoStatus,\n isInterruptedToolCall,\n isPendingToolCall,\n} from \"./auto-status\";\nimport {\n bindExternalStoreMessage,\n FALLBACK_ID_PREFIX,\n getExternalStoreMessages,\n symbolInnerMessage,\n} from \"./external-store-message\";\nimport {\n fromThreadMessageLike,\n type ThreadMessageLike,\n} from \"./thread-message-like\";\n\nexport type JoinStrategy = \"concat-content\" | \"none\";\n\nexport type ExternalMessageConverterMessage =\n | (ThreadMessageLike & {\n readonly convertConfig?: {\n readonly joinStrategy?: JoinStrategy;\n };\n })\n | {\n role: \"tool\";\n toolCallId: string;\n toolName?: string | undefined;\n result: any;\n artifact?: any;\n isError?: boolean;\n messages?: readonly ThreadMessage[];\n };\n\nexport type ExternalMessageConverterMetadata = {\n readonly toolStatuses?: Record<string, ToolExecutionStatus>;\n readonly error?: ReadonlyJSONValue;\n readonly messageTiming?: Record<string, MessageTiming>;\n};\n\nexport type ExternalMessageConverterCallback<T> = (\n message: T,\n metadata: ExternalMessageConverterMetadata,\n) => ExternalMessageConverterMessage | ExternalMessageConverterMessage[];\n\nexport type ExternalMessageConverterCallbackResult<T> = {\n input: T;\n outputs: ExternalMessageConverterMessage[];\n};\n\nexport type ExternalMessageConverterChunk<T> = {\n inputs: T[];\n outputs: ExternalMessageConverterMessage[];\n};\n\ntype Mutable<T> = {\n -readonly [P in keyof T]: T[P];\n};\n\nconst stringifyForError = (value: unknown) => {\n let text;\n try {\n text = value instanceof Error ? String(value) : JSON.stringify(value);\n } catch {\n /* circular */\n }\n text ??= String(value);\n return text.length > 200 ? `${text.slice(0, 200)}…` : text;\n};\n\nconst toCallbackOutputs = (\n output: ExternalMessageConverterMessage | ExternalMessageConverterMessage[],\n input: unknown,\n): ExternalMessageConverterMessage[] => {\n const outputs = Array.isArray(output) ? output : [output];\n for (const o of outputs) {\n const valid =\n typeof o === \"object\" &&\n o !== null &&\n (o.role === \"tool\" ||\n ((o.role === \"assistant\" || o.role === \"user\" || o.role === \"system\") &&\n (typeof o.content === \"string\" || Array.isArray(o.content))));\n if (!valid)\n throw new Error(\n `External message converter: the converter callback returned an invalid message (${stringifyForError(o)}) for input ${stringifyForError(input)}. Return an empty array to skip a message.`,\n );\n }\n // Providers can emit tool results without a usable id (react-langchain maps\n // a missing tool_call_id to \"\"); converters must not throw on those, so the\n // result is dropped like any other orphaned tool output.\n return outputs.filter((o) => {\n if (o.role !== \"tool\") return true;\n if (typeof o.toolCallId === \"string\" && o.toolCallId.length > 0)\n return true;\n if (!warnedDroppedToolResults.has(o)) {\n warnedDroppedToolResults.add(o);\n console.warn(\n `External message converter: dropping a tool result without a toolCallId (${stringifyForError(o)}) for input ${stringifyForError(input)}.`,\n );\n }\n return false;\n });\n};\n\nconst warnedDroppedToolResults = new WeakSet<object>();\n\nexport const convertExternalMessageCallback = <T>(\n input: T,\n callback: ExternalMessageConverterCallback<T>,\n metadata: ExternalMessageConverterMetadata,\n): ExternalMessageConverterCallbackResult<T> => ({\n input,\n outputs: toCallbackOutputs(callback(input, metadata), input),\n});\n\nconst mergeInnerMessages = (existing: object, incoming: object) => ({\n [symbolInnerMessage]: [\n ...((existing as any)[symbolInnerMessage] ?? []),\n ...((incoming as any)[symbolInnerMessage] ?? []),\n ],\n});\n\nexport const joinExternalMessages = (\n messages: readonly ExternalMessageConverterMessage[],\n): ThreadMessageLike => {\n const assistantMessage: Mutable<Omit<ThreadMessageLike, \"metadata\">> & {\n content: Exclude<ThreadMessageLike[\"content\"][0], string>[];\n metadata?: Mutable<ThreadMessageLike[\"metadata\"]>;\n } = {\n role: \"assistant\",\n content: [],\n };\n for (const output of messages) {\n if (output.role === \"tool\") {\n const toolCallIdx = assistantMessage.content.findIndex(\n (c) => c.type === \"tool-call\" && c.toolCallId === output.toolCallId,\n );\n // Ignore orphaned tool results so one bad tool message does not\n // prevent rendering the rest of the conversation.\n if (toolCallIdx !== -1) {\n const toolCall = assistantMessage.content[\n toolCallIdx\n ]! as ToolCallMessagePart;\n if (output.toolName != null) {\n if (toolCall.toolName !== output.toolName)\n throw new Error(\n `Tool call name ${output.toolCallId} ${output.toolName} does not match existing tool call ${toolCall.toolName}`,\n );\n }\n assistantMessage.content[toolCallIdx] = {\n ...toolCall,\n ...{\n [symbolInnerMessage]: [\n ...((toolCall as any)[symbolInnerMessage] ?? []),\n output,\n ],\n },\n result: output.result,\n artifact: output.artifact,\n isError: output.isError,\n messages: output.messages,\n };\n }\n } else {\n const role = output.role;\n const content = (\n typeof output.content === \"string\"\n ? [{ type: \"text\" as const, text: output.content }]\n : output.content\n ).map((c) => ({\n ...c,\n ...{ [symbolInnerMessage]: [output] },\n }));\n switch (role) {\n case \"system\":\n case \"user\":\n return {\n ...output,\n content,\n };\n case \"assistant\":\n if (assistantMessage.content.length === 0) {\n assistantMessage.id = output.id;\n assistantMessage.createdAt ??= output.createdAt;\n assistantMessage.status ??= output.status;\n\n if (output.attachments) {\n assistantMessage.attachments = [\n ...(assistantMessage.attachments ?? []),\n ...output.attachments,\n ];\n }\n }\n\n if (output.metadata) {\n assistantMessage.metadata ??= {};\n if (output.metadata.unstable_state !== undefined) {\n assistantMessage.metadata.unstable_state =\n output.metadata.unstable_state;\n }\n if (output.metadata.unstable_annotations) {\n assistantMessage.metadata.unstable_annotations = [\n ...(assistantMessage.metadata.unstable_annotations ?? []),\n ...output.metadata.unstable_annotations,\n ];\n }\n if (output.metadata.unstable_data) {\n assistantMessage.metadata.unstable_data = [\n ...(assistantMessage.metadata.unstable_data ?? []),\n ...output.metadata.unstable_data,\n ];\n }\n if (output.metadata.steps) {\n assistantMessage.metadata.steps = [\n ...(assistantMessage.metadata.steps ?? []),\n ...output.metadata.steps,\n ];\n }\n if (output.metadata.custom) {\n assistantMessage.metadata.custom = {\n ...(assistantMessage.metadata.custom ?? {}),\n ...output.metadata.custom,\n };\n }\n\n if (output.metadata.timing) {\n assistantMessage.metadata.timing = output.metadata.timing;\n }\n\n if (output.metadata.submittedFeedback) {\n assistantMessage.metadata.submittedFeedback =\n output.metadata.submittedFeedback;\n }\n\n if (output.metadata.isOptimistic) {\n assistantMessage.metadata.isOptimistic = true;\n }\n // TODO keep this in sync with ThreadMessageLike[\"metadata\"] / fromThreadMessageLike\n }\n\n // Add content parts, merging reasoning parts with same parentId\n for (const part of content) {\n if (part.type === \"tool-call\") {\n const existingIdx = assistantMessage.content.findIndex(\n (c) =>\n c.type === \"tool-call\" && c.toolCallId === part.toolCallId,\n );\n if (existingIdx !== -1) {\n const existing = assistantMessage.content[\n existingIdx\n ] as typeof part;\n assistantMessage.content[existingIdx] = {\n ...existing,\n ...part,\n ...mergeInnerMessages(existing, part),\n };\n continue;\n }\n }\n\n if (\n part.type === \"reasoning\" &&\n \"parentId\" in part &&\n part.parentId\n ) {\n const existingIdx = assistantMessage.content.findIndex(\n (c) =>\n c.type === \"reasoning\" &&\n \"parentId\" in c &&\n c.parentId === part.parentId,\n );\n if (existingIdx !== -1) {\n const existing = assistantMessage.content[\n existingIdx\n ] as typeof part;\n assistantMessage.content[existingIdx] = {\n ...existing,\n text: `${existing.text}\\n\\n${part.text}`,\n ...mergeInnerMessages(existing, part),\n };\n continue;\n }\n }\n assistantMessage.content.push(part);\n }\n break;\n default: {\n const unsupportedRole: never = role;\n throw new Error(`Unknown message role: ${unsupportedRole}`);\n }\n }\n }\n }\n return assistantMessage;\n};\n\nexport const chunkExternalMessages = <T>(\n callbackResults: ExternalMessageConverterCallbackResult<T>[],\n joinStrategy?: JoinStrategy,\n) => {\n const results: ExternalMessageConverterChunk<T>[] = [];\n let isAssistant = false;\n let pendingNone = false; // true if the previous assistant message had joinStrategy \"none\"\n let inputs: T[] = [];\n let outputs: ExternalMessageConverterMessage[] = [];\n\n const flush = () => {\n if (outputs.length) {\n results.push({\n inputs,\n outputs,\n });\n }\n inputs = [];\n outputs = [];\n isAssistant = false;\n pendingNone = false;\n };\n\n for (const callbackResult of callbackResults) {\n for (const output of callbackResult.outputs) {\n if (\n (pendingNone && output.role !== \"tool\") ||\n !isAssistant ||\n output.role === \"user\" ||\n output.role === \"system\"\n ) {\n flush();\n }\n isAssistant = output.role === \"assistant\" || output.role === \"tool\";\n\n if (inputs.at(-1) !== callbackResult.input) {\n inputs.push(callbackResult.input);\n }\n outputs.push(output);\n\n if (\n output.role === \"assistant\" &&\n (output.convertConfig?.joinStrategy === \"none\" ||\n joinStrategy === \"none\")\n ) {\n pendingNone = true;\n }\n }\n }\n flush();\n return results;\n};\n\nexport const shallowArrayEqual = (a: unknown[], b: unknown[]) => {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n if (a[i] !== b[i]) return false;\n }\n return true;\n};\n\ntype ExternalMessageConversionCache = {\n message: ThreadMessage | undefined;\n generatedFallbackMessages: WeakSet<object>;\n};\n\nexport const convertExternalMessageChunk = <T>(\n message: ExternalMessageConverterChunk<T>,\n idx: number,\n chunkCount: number,\n isRunning: boolean,\n error: ReadonlyJSONValue | undefined,\n cache?: ExternalMessageConversionCache,\n) => {\n const isLast = idx === chunkCount - 1;\n const joined = joinExternalMessages(message.outputs);\n const hasInterruptedToolCalls =\n typeof joined.content === \"object\" &&\n joined.content.some(isInterruptedToolCall);\n const hasPendingToolCalls =\n typeof joined.content === \"object\" &&\n joined.content.some(isPendingToolCall);\n const autoStatus = getAutoStatus(\n isLast,\n isRunning,\n hasInterruptedToolCalls,\n hasPendingToolCalls,\n isLast ? error : undefined,\n );\n const fallbackId = `${FALLBACK_ID_PREFIX}${idx}`;\n\n const cachedMessage = cache?.message;\n if (\n cachedMessage &&\n (cachedMessage.role !== \"assistant\" ||\n !isAutoStatus(cachedMessage.status) ||\n cachedMessage.status === autoStatus ||\n (cachedMessage.status.type === \"incomplete\" &&\n cachedMessage.status.reason === \"error\" &&\n cachedMessage.status.error !== undefined &&\n autoStatus.type === \"incomplete\" &&\n autoStatus.reason === \"error\" &&\n autoStatus.error !== undefined &&\n (cachedMessage.status.error === autoStatus.error ||\n isJSONValueEqual(cachedMessage.status.error, autoStatus.error))))\n ) {\n const inputs = getExternalStoreMessages<T>(cachedMessage);\n if (shallowArrayEqual(inputs, message.inputs)) {\n // A positional fallback id goes stale when messages are prepended\n // or reordered; serving it unchanged makes two messages collide on\n // one id and the dedup downstream drops one of them.\n if (\n cache.generatedFallbackMessages.has(cachedMessage) &&\n cachedMessage.id !== fallbackId\n ) {\n const updated = { ...cachedMessage, id: fallbackId };\n cache.generatedFallbackMessages.add(updated);\n bindExternalStoreMessage(updated, message.inputs);\n return updated;\n }\n return cachedMessage;\n }\n }\n\n const newMessage = fromThreadMessageLike(joined, fallbackId, autoStatus);\n if (cache && joined.id == null) {\n cache.generatedFallbackMessages.add(newMessage);\n }\n bindExternalStoreMessage(newMessage, message.inputs);\n return newMessage;\n};\n\nfunction createErrorAssistantMessage(\n error: ReadonlyJSONValue,\n): ThreadAssistantMessage {\n const msg: ThreadAssistantMessage = {\n id: generateErrorMessageId(),\n role: \"assistant\",\n content: [],\n status: { type: \"incomplete\", reason: \"error\", error },\n createdAt: new Date(),\n metadata: {\n unstable_state: null,\n unstable_annotations: [],\n unstable_data: [],\n custom: {},\n steps: [],\n },\n };\n bindExternalStoreMessage(msg, []);\n return msg;\n}\n\nexport const completeExternalMessageConversion = (\n messages: ThreadMessage[],\n error: ReadonlyJSONValue | undefined,\n) => {\n if (error) {\n const lastMessage = messages.at(-1);\n if (!lastMessage || lastMessage.role !== \"assistant\") {\n messages.push(createErrorAssistantMessage(error));\n }\n }\n return messages;\n};\n\nexport const convertExternalMessages = <T extends WeakKey>(\n messages: T[],\n callback: ExternalMessageConverterCallback<T>,\n isRunning: boolean,\n metadata: ExternalMessageConverterMetadata,\n) => {\n const callbackResults = messages.map((message) =>\n convertExternalMessageCallback(message, callback, metadata),\n );\n const chunks = chunkExternalMessages(callbackResults);\n const result = chunks.map((message, idx) =>\n convertExternalMessageChunk(\n message,\n idx,\n chunks.length,\n isRunning,\n metadata.error,\n ),\n );\n return completeExternalMessageConversion(result, metadata.error);\n};\n"],"mappings":"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"}
@@ -12,6 +12,7 @@ declare const bindExternalStoreMessage: <T>(target: object, message: T | T[]) =>
12
12
  declare const getExternalStoreMessages: <T>(input: {
13
13
  messages: readonly ThreadMessage[];
14
14
  } | ThreadMessage | ThreadMessage["content"][number]) => T[];
15
+ declare const FALLBACK_ID_PREFIX = "__external_store_fallback_";
15
16
  //#endregion
16
- export { bindExternalStoreMessage, getExternalStoreMessages, symbolInnerMessage };
17
+ export { FALLBACK_ID_PREFIX, bindExternalStoreMessage, getExternalStoreMessages, symbolInnerMessage };
17
18
  //# sourceMappingURL=external-store-message.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"external-store-message.d.ts","names":[],"sources":["../../../src/runtime/utils/external-store-message.ts"],"mappings":";;cAEa;;;;;;;;cAiBA,2BAA4B,GACvC,gBACA,SAAS,IAAI;cAMF,2BAA4B,GACvC;EACM,mBAAmB;IACrB,gBACA,qCAAgC"}
1
+ {"version":3,"file":"external-store-message.d.ts","names":[],"sources":["../../../src/runtime/utils/external-store-message.ts"],"mappings":";;cAEa;;;;;;;;cAiBA,2BAA4B,GACvC,gBACA,SAAS,IAAI;cAMF,2BAA4B,GACvC;EACM,mBAAmB;IACrB,gBACA,qCAAgC;cAczB"}
@@ -21,7 +21,8 @@ const getExternalStoreMessages = (input) => {
21
21
  container[symbolInnerMessages] = [value];
22
22
  return container[symbolInnerMessages];
23
23
  };
24
+ const FALLBACK_ID_PREFIX = "__external_store_fallback_";
24
25
  //#endregion
25
- export { bindExternalStoreMessage, getExternalStoreMessages, symbolInnerMessage };
26
+ export { FALLBACK_ID_PREFIX, bindExternalStoreMessage, getExternalStoreMessages, symbolInnerMessage };
26
27
 
27
28
  //# sourceMappingURL=external-store-message.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"external-store-message.js","names":["ThreadMessage","symbolInnerMessage","Symbol","symbolInnerMessages","WithInnerMessages","T","EMPTY_ARRAY","bindExternalStoreMessage","target","message","getExternalStoreMessages","input","messages","container","value","Array","isArray"],"sources":["../../../src/runtime/utils/external-store-message.ts"],"sourcesContent":["import type { ThreadMessage } from \"../../types/message\";\n\nexport const symbolInnerMessage = Symbol(\"innerMessage\");\nconst symbolInnerMessages = Symbol(\"innerMessages\");\n\ntype WithInnerMessages<T> = {\n [symbolInnerMessage]?: T | T[];\n [symbolInnerMessages]?: T[];\n};\n\nconst EMPTY_ARRAY: never[] = [];\n\n/**\n * Attach the original external store message(s) to a ThreadMessage or message part.\n * This is a no-op if the target already has a bound message.\n * Use `getExternalStoreMessages` to retrieve the bound messages later.\n *\n * @deprecated This API is experimental and may change without notice.\n */\nexport const bindExternalStoreMessage = <T>(\n target: object,\n message: T | T[],\n): void => {\n if (symbolInnerMessage in target) return;\n (target as WithInnerMessages<T>)[symbolInnerMessage] = message;\n};\n\nexport const getExternalStoreMessages = <T>(\n input:\n | { messages: readonly ThreadMessage[] }\n | ThreadMessage\n | ThreadMessage[\"content\"][number],\n) => {\n const container = (\n \"messages\" in input ? input.messages : input\n ) as WithInnerMessages<T>;\n const value = container[symbolInnerMessages] || container[symbolInnerMessage];\n if (!value) return EMPTY_ARRAY;\n if (Array.isArray(value)) {\n return value;\n }\n container[symbolInnerMessages] = [value];\n return container[symbolInnerMessages];\n};\n"],"mappings":";AAEA,MAAaC,qBAAqBC,OAAO,cAAc;AACvD,MAAMC,sBAAsBD,OAAO,eAAe;AAOlD,MAAMI,cAAuB,CAAA;;;;;;;;AAS7B,MAAaC,4BACXC,QACAC,YACS;CACT,IAAIR,sBAAsBO,QAAQ;CAClC,OAAiCP,sBAAsBQ;AACzD;AAEA,MAAaC,4BACXC,UAIG;CACH,MAAME,YACJ,cAAcF,QAAQA,MAAMC,WAAWD;CAEzC,MAAMG,QAAQD,UAAUV,wBAAwBU,UAAUZ;CAC1D,IAAI,CAACa,OAAO,OAAOR;CACnB,IAAIS,MAAMC,QAAQF,KAAK,GACrB,OAAOA;CAETD,UAAUV,uBAAuB,CAACW,KAAK;CACvC,OAAOD,UAAUV;AACnB"}
1
+ {"version":3,"file":"external-store-message.js","names":["ThreadMessage","symbolInnerMessage","Symbol","symbolInnerMessages","WithInnerMessages","T","EMPTY_ARRAY","bindExternalStoreMessage","target","message","getExternalStoreMessages","input","messages","container","value","Array","isArray","FALLBACK_ID_PREFIX"],"sources":["../../../src/runtime/utils/external-store-message.ts"],"sourcesContent":["import type { ThreadMessage } from \"../../types/message\";\n\nexport const symbolInnerMessage = Symbol(\"innerMessage\");\nconst symbolInnerMessages = Symbol(\"innerMessages\");\n\ntype WithInnerMessages<T> = {\n [symbolInnerMessage]?: T | T[];\n [symbolInnerMessages]?: T[];\n};\n\nconst EMPTY_ARRAY: never[] = [];\n\n/**\n * Attach the original external store message(s) to a ThreadMessage or message part.\n * This is a no-op if the target already has a bound message.\n * Use `getExternalStoreMessages` to retrieve the bound messages later.\n *\n * @deprecated This API is experimental and may change without notice.\n */\nexport const bindExternalStoreMessage = <T>(\n target: object,\n message: T | T[],\n): void => {\n if (symbolInnerMessage in target) return;\n (target as WithInnerMessages<T>)[symbolInnerMessage] = message;\n};\n\nexport const getExternalStoreMessages = <T>(\n input:\n | { messages: readonly ThreadMessage[] }\n | ThreadMessage\n | ThreadMessage[\"content\"][number],\n) => {\n const container = (\n \"messages\" in input ? input.messages : input\n ) as WithInnerMessages<T>;\n const value = container[symbolInnerMessages] || container[symbolInnerMessage];\n if (!value) return EMPTY_ARRAY;\n if (Array.isArray(value)) {\n return value;\n }\n container[symbolInnerMessages] = [value];\n return container[symbolInnerMessages];\n};\n\nexport const FALLBACK_ID_PREFIX = \"__external_store_fallback_\";\n"],"mappings":";AAEA,MAAaC,qBAAqBC,OAAO,cAAc;AACvD,MAAMC,sBAAsBD,OAAO,eAAe;AAOlD,MAAMI,cAAuB,CAAA;;;;;;;;AAS7B,MAAaC,4BACXC,QACAC,YACS;CACT,IAAIR,sBAAsBO,QAAQ;CAClC,OAAiCP,sBAAsBQ;AACzD;AAEA,MAAaC,4BACXC,UAIG;CACH,MAAME,YACJ,cAAcF,QAAQA,MAAMC,WAAWD;CAEzC,MAAMG,QAAQD,UAAUV,wBAAwBU,UAAUZ;CAC1D,IAAI,CAACa,OAAO,OAAOR;CACnB,IAAIS,MAAMC,QAAQF,KAAK,GACrB,OAAOA;CAETD,UAAUV,uBAAuB,CAACW,KAAK;CACvC,OAAOD,UAAUV;AACnB;AAEA,MAAac,qBAAqB"}
@@ -0,0 +1,30 @@
1
+ import { ThreadMessage } from "../../types/message.js";
2
+ import { ExportedMessageRepository, MessageRepository } from "./message-repository.js";
3
+ //#region src/runtime/utils/message-repository-session.d.ts
4
+ type MessageRepositorySessionOptions = {
5
+ decorateExport?: (exported: ExportedMessageRepository, repository: MessageRepository) => ExportedMessageRepository;
6
+ };
7
+ declare const createMessageRepositorySession: (options?: MessageRepositorySessionOptions) => {
8
+ getMessages: () => readonly ThreadMessage[];
9
+ readonly headId: string | null;
10
+ export: () => ExportedMessageRepository;
11
+ tryGetMessage: (messageId: string) => {
12
+ parentId: string | null;
13
+ message: ThreadMessage;
14
+ index: number;
15
+ } | undefined;
16
+ tryGetMessages: (messageId: string) => readonly ThreadMessage[] | undefined;
17
+ hasMessage: (messageId: string) => boolean;
18
+ addOrUpdateMessage: (parentId: string | null, message: ThreadMessage) => void;
19
+ deleteMessage: (messageId: string, replacementId?: string | null) => void;
20
+ tryDeleteMessage: (messageId: string) => boolean;
21
+ switchToBranch: (messageId: string) => void;
22
+ resetHead: (messageId: string | null) => void;
23
+ clear: () => void;
24
+ updateMessage: (messageId: string, updater: (message: ThreadMessage) => ThreadMessage) => boolean;
25
+ applyExternalMessageRepository: (loaded: ExportedMessageRepository) => void;
26
+ };
27
+ type MessageRepositorySession = ReturnType<typeof createMessageRepositorySession>;
28
+ //#endregion
29
+ export { MessageRepositorySession, MessageRepositorySessionOptions, createMessageRepositorySession };
30
+ //# sourceMappingURL=message-repository-session.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"message-repository-session.d.ts","names":[],"sources":["../../../src/runtime/utils/message-repository-session.ts"],"mappings":";;;KAMY;EACV,kBACE,UAAU,2BACV,YAAY,sBACT;;cAGM,iCACX,UAAS;EAKe,4BAAS;;EAsInB,cAAA;EAlIoB,gBAAA;;;;;EASrB,iBAAA,+BACD;EAQmB,aAAA;EAKnB,qBAAA,yBAAa,SACd;EAOE,gBAAA,mBAAM;EAOkB,mBAAA;EAMF,iBAAA;EAKL,YAAA;EAKZ;EAML,gBAAA,mBAAM,UACP,SAAS,kBAAkB;EAW7B,iCAAA,QAAA;;KA8EA,2BAA2B,kBAC9B"}
@@ -0,0 +1,130 @@
1
+ import { MessageRepository } from "./message-repository.js";
2
+ //#region src/runtime/utils/message-repository-session.ts
3
+ const createMessageRepositorySession = (options = {}) => {
4
+ const repository = new MessageRepository();
5
+ let exportedRepository;
6
+ const getMessages = () => {
7
+ return repository.getMessages();
8
+ };
9
+ const tryGetMessage = (messageId) => {
10
+ try {
11
+ return repository.getMessage(messageId);
12
+ } catch {
13
+ return;
14
+ }
15
+ };
16
+ const tryGetMessages = (messageId) => {
17
+ try {
18
+ return repository.getMessages(messageId);
19
+ } catch {
20
+ return;
21
+ }
22
+ };
23
+ const hasMessage = (messageId) => {
24
+ return tryGetMessage(messageId) !== void 0;
25
+ };
26
+ const addOrUpdateMessage = (parentId, message) => {
27
+ repository.addOrUpdateMessage(parentId, message);
28
+ exportedRepository = void 0;
29
+ };
30
+ const deleteMessage = (messageId, replacementId) => {
31
+ repository.deleteMessage(messageId, replacementId);
32
+ exportedRepository = void 0;
33
+ };
34
+ const tryDeleteMessage = (messageId) => {
35
+ if (!hasMessage(messageId)) return false;
36
+ deleteMessage(messageId);
37
+ return true;
38
+ };
39
+ const switchToBranch = (messageId) => {
40
+ repository.switchToBranch(messageId);
41
+ exportedRepository = void 0;
42
+ };
43
+ const resetHead = (messageId) => {
44
+ repository.resetHead(messageId);
45
+ exportedRepository = void 0;
46
+ };
47
+ const clear = () => {
48
+ repository.clear();
49
+ exportedRepository = void 0;
50
+ };
51
+ const updateMessage = (messageId, updater) => {
52
+ const item = tryGetMessage(messageId);
53
+ if (!item) return false;
54
+ const message = updater(item.message);
55
+ if (message === item.message) return false;
56
+ addOrUpdateMessage(item.parentId, message);
57
+ return true;
58
+ };
59
+ const applyExternalMessageRepository = (loaded) => {
60
+ const headId = loaded.headId ?? loaded.messages.at(-1)?.message.id ?? null;
61
+ const ids = /* @__PURE__ */ new Set();
62
+ let degenerate = false;
63
+ for (const { message } of loaded.messages) {
64
+ if (ids.has(message.id)) {
65
+ degenerate = true;
66
+ break;
67
+ }
68
+ ids.add(message.id);
69
+ }
70
+ if (headId !== null && !ids.has(headId)) degenerate = true;
71
+ if (!degenerate) {
72
+ clear();
73
+ let pending = [...loaded.messages];
74
+ const importedIds = /* @__PURE__ */ new Set();
75
+ while (pending.length > 0) {
76
+ const unresolved = [];
77
+ let progressed = false;
78
+ for (const item of pending) {
79
+ if (item.parentId !== null && !importedIds.has(item.parentId)) {
80
+ unresolved.push(item);
81
+ continue;
82
+ }
83
+ addOrUpdateMessage(item.parentId, item.message);
84
+ importedIds.add(item.message.id);
85
+ progressed = true;
86
+ }
87
+ if (!progressed) {
88
+ degenerate = true;
89
+ break;
90
+ }
91
+ pending = unresolved;
92
+ }
93
+ }
94
+ if (degenerate) {
95
+ clear();
96
+ let previousId = null;
97
+ for (const { message } of loaded.messages) {
98
+ const existing = tryGetMessage(message.id);
99
+ addOrUpdateMessage(existing ? existing.parentId : previousId, message);
100
+ previousId = message.id;
101
+ }
102
+ resetHead(previousId);
103
+ } else resetHead(headId);
104
+ };
105
+ return {
106
+ getMessages,
107
+ get headId() {
108
+ return repository.headId;
109
+ },
110
+ export: () => {
111
+ exportedRepository ??= options.decorateExport ? options.decorateExport(repository.export(), repository) : repository.export();
112
+ return exportedRepository;
113
+ },
114
+ tryGetMessage,
115
+ tryGetMessages,
116
+ hasMessage,
117
+ addOrUpdateMessage,
118
+ deleteMessage,
119
+ tryDeleteMessage,
120
+ switchToBranch,
121
+ resetHead,
122
+ clear,
123
+ updateMessage,
124
+ applyExternalMessageRepository
125
+ };
126
+ };
127
+ //#endregion
128
+ export { createMessageRepositorySession };
129
+
130
+ //# sourceMappingURL=message-repository-session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"message-repository-session.js","names":["ThreadMessage","MessageRepository","ExportedMessageRepository","MessageRepositorySessionOptions","decorateExport","exported","repository","createMessageRepositorySession","options","exportedRepository","getMessages","tryGetMessage","messageId","getMessage","undefined","tryGetMessages","hasMessage","addOrUpdateMessage","parentId","message","deleteMessage","replacementId","tryDeleteMessage","switchToBranch","resetHead","clear","updateMessage","updater","item","applyExternalMessageRepository","loaded","headId","messages","at","id","ids","Set","degenerate","has","add","pending","importedIds","length","unresolved","progressed","push","previousId","existing","export","MessageRepositorySession","ReturnType"],"sources":["../../../src/runtime/utils/message-repository-session.ts"],"sourcesContent":["import type { ThreadMessage } from \"../../types/message\";\nimport {\n MessageRepository,\n type ExportedMessageRepository,\n} from \"./message-repository\";\n\nexport type MessageRepositorySessionOptions = {\n decorateExport?: (\n exported: ExportedMessageRepository,\n repository: MessageRepository,\n ) => ExportedMessageRepository;\n};\n\nexport const createMessageRepositorySession = (\n options: MessageRepositorySessionOptions = {},\n) => {\n const repository = new MessageRepository();\n let exportedRepository: ExportedMessageRepository | undefined;\n\n const getMessages = (): readonly ThreadMessage[] => {\n return repository.getMessages();\n };\n\n const tryGetMessage = (messageId: string) => {\n try {\n return repository.getMessage(messageId);\n } catch {\n return undefined;\n }\n };\n\n const tryGetMessages = (\n messageId: string,\n ): readonly ThreadMessage[] | undefined => {\n try {\n return repository.getMessages(messageId);\n } catch {\n return undefined;\n }\n };\n\n const hasMessage = (messageId: string): boolean => {\n return tryGetMessage(messageId) !== undefined;\n };\n\n const addOrUpdateMessage = (\n parentId: string | null,\n message: ThreadMessage,\n ): void => {\n repository.addOrUpdateMessage(parentId, message);\n exportedRepository = undefined;\n };\n\n const deleteMessage = (\n messageId: string,\n replacementId?: string | null,\n ): void => {\n repository.deleteMessage(messageId, replacementId);\n exportedRepository = undefined;\n };\n\n const tryDeleteMessage = (messageId: string): boolean => {\n if (!hasMessage(messageId)) return false;\n deleteMessage(messageId);\n return true;\n };\n\n const switchToBranch = (messageId: string): void => {\n repository.switchToBranch(messageId);\n exportedRepository = undefined;\n };\n\n const resetHead = (messageId: string | null): void => {\n repository.resetHead(messageId);\n exportedRepository = undefined;\n };\n\n const clear = (): void => {\n repository.clear();\n exportedRepository = undefined;\n };\n\n const updateMessage = (\n messageId: string,\n updater: (message: ThreadMessage) => ThreadMessage,\n ): boolean => {\n const item = tryGetMessage(messageId);\n if (!item) return false;\n const message = updater(item.message);\n if (message === item.message) return false;\n addOrUpdateMessage(item.parentId, message);\n return true;\n };\n\n const applyExternalMessageRepository = (\n loaded: ExportedMessageRepository,\n ): void => {\n const headId = loaded.headId ?? loaded.messages.at(-1)?.message.id ?? null;\n const ids = new Set<string>();\n let degenerate = false;\n for (const { message } of loaded.messages) {\n if (ids.has(message.id)) {\n degenerate = true;\n break;\n }\n ids.add(message.id);\n }\n if (headId !== null && !ids.has(headId)) degenerate = true;\n\n if (!degenerate) {\n clear();\n let pending = [...loaded.messages];\n const importedIds = new Set<string>();\n\n while (pending.length > 0) {\n const unresolved: typeof pending = [];\n let progressed = false;\n for (const item of pending) {\n if (item.parentId !== null && !importedIds.has(item.parentId)) {\n unresolved.push(item);\n continue;\n }\n addOrUpdateMessage(item.parentId, item.message);\n importedIds.add(item.message.id);\n progressed = true;\n }\n if (!progressed) {\n degenerate = true;\n break;\n }\n pending = unresolved;\n }\n }\n\n if (degenerate) {\n clear();\n let previousId: string | null = null;\n for (const { message } of loaded.messages) {\n const existing = tryGetMessage(message.id);\n addOrUpdateMessage(existing ? existing.parentId : previousId, message);\n previousId = message.id;\n }\n resetHead(previousId);\n } else {\n resetHead(headId);\n }\n };\n\n return {\n getMessages,\n get headId() {\n return repository.headId;\n },\n export: (): ExportedMessageRepository => {\n exportedRepository ??= options.decorateExport\n ? options.decorateExport(repository.export(), repository)\n : repository.export();\n return exportedRepository;\n },\n tryGetMessage,\n tryGetMessages,\n hasMessage,\n addOrUpdateMessage,\n deleteMessage,\n tryDeleteMessage,\n switchToBranch,\n resetHead,\n clear,\n updateMessage,\n applyExternalMessageRepository,\n };\n};\n\nexport type MessageRepositorySession = ReturnType<\n typeof createMessageRepositorySession\n>;\n"],"mappings":"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"}
@@ -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;;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"}
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;;cAgEQ;UACH;UACA;UACA;UAKA;UAgBA;UA2DA;MAQJ;MAIA;EAUJ,YAAY,2BAAe;EAuB3B,mBAAmB,yBAAyB,SAAS;EAiCrD,WAAW;;;;;EAcX,cAAc,mBAAmB;EAsCjC,YAAY;;;;;;;;;UAmBJ;EA+BR,eAAe;EAkBf,UAAU;EAiDV;EAUA,UAAU;EAwBV,SAAS,QAAQ,YAAY"}
@@ -1,33 +1,32 @@
1
1
  import { generateId } from "../../utils/id.js";
2
2
  import { fromThreadMessageLike } from "./thread-message-like.js";
3
- import { getAutoStatus } from "./auto-status.js";
3
+ import { getContentAutoStatus } from "./auto-status.js";
4
4
  //#region src/runtime/utils/message-repository.ts
5
5
  const ExportedMessageRepository = {
6
6
  fromArray: (messages) => {
7
- const conv = messages.map((m) => fromThreadMessageLike(m, generateId(), getAutoStatus(false, false, false, false, void 0)));
7
+ const conv = messages.map((m) => fromThreadMessageLike(m, generateId(), getContentAutoStatus(m.content, false, false)));
8
8
  return { messages: conv.map((m, idx) => ({
9
9
  parentId: idx > 0 ? conv[idx - 1].id : null,
10
10
  message: m
11
11
  })) };
12
12
  },
13
13
  fromBranchableArray: (items, options) => {
14
- const fallbackStatus = getAutoStatus(false, false, false, false, void 0);
15
14
  return {
16
15
  ...options?.headId !== void 0 ? { headId: options.headId } : void 0,
17
16
  messages: items.map(({ message, parentId }) => {
18
17
  if (!message.id) throw new Error("ExportedMessageRepository.fromBranchableArray: Each message must have an 'id' field set.");
19
18
  return {
20
19
  parentId,
21
- message: fromThreadMessageLike(message, message.id, fallbackStatus)
20
+ message: fromThreadMessageLike(message, message.id, getContentAutoStatus(message.content, false, false))
22
21
  };
23
22
  })
24
23
  };
25
24
  }
26
25
  };
27
26
  const findHead = (message) => {
28
- if (message.next) return findHead(message.next);
29
- if ("current" in message) return message;
30
- return null;
27
+ let current = message;
28
+ while (current.next) current = current.next;
29
+ return "current" in current ? current : null;
31
30
  };
32
31
  var CachedValue = class {
33
32
  _value = null;
@@ -51,18 +50,28 @@ var MessageRepository = class {
51
50
  next: null
52
51
  };
53
52
  updateLevels(message, newLevel) {
54
- message.level = newLevel;
55
- for (const childId of message.children) {
56
- const childMessage = this.messages.get(childId);
57
- if (childMessage) this.updateLevels(childMessage, newLevel + 1);
53
+ const pending = [{
54
+ message,
55
+ level: newLevel
56
+ }];
57
+ while (pending.length > 0) {
58
+ const current = pending.pop();
59
+ current.message.level = current.level;
60
+ for (const childId of current.message.children) {
61
+ const childMessage = this.messages.get(childId);
62
+ if (childMessage) pending.push({
63
+ message: childMessage,
64
+ level: current.level + 1
65
+ });
66
+ }
58
67
  }
59
68
  }
60
69
  performOp(newParent, child, operation) {
61
70
  const parentOrRoot = child.prev ?? this.root;
62
71
  const newParentOrRoot = newParent ?? this.root;
63
72
  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.");
73
+ if (operation === "relink") {
74
+ for (let current = newParent; current; current = current.prev) if (current.current.id === child.current.id) throw new Error("MessageRepository(performOp/relink): 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
75
  }
67
76
  if (operation !== "link") {
68
77
  parentOrRoot.children = parentOrRoot.children.filter((m) => m !== child.current.id);
@@ -192,16 +201,15 @@ var MessageRepository = class {
192
201
  if (!message) throw new Error("MessageRepository(resetHead): Branch not found. This is likely an internal bug in assistant-ui.");
193
202
  const previousHead = this.head;
194
203
  if (message.children.length > 0) {
195
- const deleteDescendants = (msg) => {
196
- for (const childId of msg.children) {
197
- const childMessage = this.messages.get(childId);
198
- if (childMessage) {
199
- deleteDescendants(childMessage);
200
- this.messages.delete(childId);
201
- }
204
+ const pending = [...message.children];
205
+ while (pending.length > 0) {
206
+ const childId = pending.pop();
207
+ const childMessage = this.messages.get(childId);
208
+ if (childMessage) {
209
+ for (const descendantId of childMessage.children) pending.push(descendantId);
210
+ this.messages.delete(childId);
202
211
  }
203
- };
204
- deleteDescendants(message);
212
+ }
205
213
  message.children = [];
206
214
  message.next = null;
207
215
  }