@assistant-ui/core 0.3.15 → 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 (251) hide show
  1. package/dist/internal.d.ts +7 -2
  2. package/dist/internal.js +8 -3
  3. package/dist/model-context/frame/host.d.ts.map +1 -1
  4. package/dist/model-context/frame/host.js +3 -2
  5. package/dist/model-context/frame/host.js.map +1 -1
  6. package/dist/model-context/frame/provider.d.ts +2 -0
  7. package/dist/model-context/frame/provider.d.ts.map +1 -1
  8. package/dist/model-context/frame/provider.js +88 -25
  9. package/dist/model-context/frame/provider.js.map +1 -1
  10. package/dist/model-context/interactable-composer-metadata.d.ts +1 -1
  11. package/dist/model-context/interactable-composer-metadata.js +1 -1
  12. package/dist/model-context/interactable-composer-metadata.js.map +1 -1
  13. package/dist/model-context/registry.d.ts +2 -2
  14. package/dist/model-context/registry.d.ts.map +1 -1
  15. package/dist/model-context/registry.js +9 -28
  16. package/dist/model-context/registry.js.map +1 -1
  17. package/dist/react/client/InMemoryThreadList.d.ts.map +1 -1
  18. package/dist/react/client/InMemoryThreadList.js +24 -20
  19. package/dist/react/client/InMemoryThreadList.js.map +1 -1
  20. package/dist/react/client/Interactables.d.ts.map +1 -1
  21. package/dist/react/client/Interactables.js +59 -177
  22. package/dist/react/client/Interactables.js.map +1 -1
  23. package/dist/react/client/RemoteThreadList.d.ts.map +1 -1
  24. package/dist/react/client/RemoteThreadList.js +23 -56
  25. package/dist/react/client/RemoteThreadList.js.map +1 -1
  26. package/dist/react/index.d.ts +2 -1
  27. package/dist/react/interactables-legacy/Interactables.d.ts.map +1 -1
  28. package/dist/react/interactables-legacy/Interactables.js +56 -174
  29. package/dist/react/interactables-legacy/Interactables.js.map +1 -1
  30. package/dist/react/interactables-shared/useInteractablePersistenceQueue.d.ts +24 -0
  31. package/dist/react/interactables-shared/useInteractablePersistenceQueue.d.ts.map +1 -0
  32. package/dist/react/interactables-shared/useInteractablePersistenceQueue.js +138 -0
  33. package/dist/react/interactables-shared/useInteractablePersistenceQueue.js.map +1 -0
  34. package/dist/react/primitives/composer/ComposerIf.js.map +1 -1
  35. package/dist/react/primitives/composer/ComposerQueue.d.ts +2 -1
  36. package/dist/react/primitives/composer/ComposerQueue.d.ts.map +1 -1
  37. package/dist/react/primitives/message/MessageParts.js.map +1 -1
  38. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.d.ts +1 -1
  39. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts +1 -1
  40. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts.map +1 -1
  41. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js +23 -55
  42. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.js.map +1 -1
  43. package/dist/react/runtimes/assistant-transport/runManager.d.ts.map +1 -1
  44. package/dist/react/runtimes/assistant-transport/runManager.js +2 -12
  45. package/dist/react/runtimes/assistant-transport/runManager.js.map +1 -1
  46. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.d.ts +3 -10
  47. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.d.ts.map +1 -1
  48. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.js +20 -67
  49. package/dist/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.js.map +1 -1
  50. package/dist/react/runtimes/cloud/createCloudThreadListAdapterCreateFallback.d.ts +12 -0
  51. package/dist/react/runtimes/cloud/createCloudThreadListAdapterCreateFallback.d.ts.map +1 -0
  52. package/dist/react/runtimes/cloud/createCloudThreadListAdapterCreateFallback.js +10 -0
  53. package/dist/react/runtimes/cloud/createCloudThreadListAdapterCreateFallback.js.map +1 -0
  54. package/dist/react/runtimes/cloud/useCloudThreadListRuntime.js.map +1 -1
  55. package/dist/react/runtimes/createMessageConverter.d.ts +2 -1
  56. package/dist/react/runtimes/createMessageConverter.d.ts.map +1 -1
  57. package/dist/react/runtimes/external-message-converter.d.ts +6 -25
  58. package/dist/react/runtimes/external-message-converter.d.ts.map +1 -1
  59. package/dist/react/runtimes/external-message-converter.js +33 -233
  60. package/dist/react/runtimes/external-message-converter.js.map +1 -1
  61. package/dist/runtime/api/composer-runtime.d.ts +1 -1
  62. package/dist/runtime/api/composer-runtime.js.map +1 -1
  63. package/dist/runtime/api/thread-runtime.d.ts +1 -2
  64. package/dist/runtime/api/thread-runtime.d.ts.map +1 -1
  65. package/dist/runtime/base/base-composer-runtime-core.d.ts +1 -1
  66. package/dist/runtime/base/base-composer-runtime-core.d.ts.map +1 -1
  67. package/dist/runtime/base/base-composer-runtime-core.js +14 -29
  68. package/dist/runtime/base/base-composer-runtime-core.js.map +1 -1
  69. package/dist/runtime/base/base-thread-runtime-core.d.ts +2 -4
  70. package/dist/runtime/base/base-thread-runtime-core.d.ts.map +1 -1
  71. package/dist/runtime/base/base-thread-runtime-core.js +3 -9
  72. package/dist/runtime/base/base-thread-runtime-core.js.map +1 -1
  73. package/dist/runtime/base/default-thread-composer-runtime-core.d.ts +1 -1
  74. package/dist/runtime/base/default-thread-composer-runtime-core.d.ts.map +1 -1
  75. package/dist/runtime/base/default-thread-composer-runtime-core.js +1 -1
  76. package/dist/runtime/base/default-thread-composer-runtime-core.js.map +1 -1
  77. package/dist/runtime/interfaces/composer-runtime-core.d.ts +1 -1
  78. package/dist/runtime/interfaces/thread-runtime-core.d.ts +1 -1
  79. package/dist/runtime/internal.d.ts +2 -1
  80. package/dist/runtime/internal.js +2 -1
  81. package/dist/runtime/queue/external-thread-queue-adapter.d.ts +1 -1
  82. package/dist/runtime/queue/message-queue.d.ts.map +1 -1
  83. package/dist/runtime/queue/message-queue.js +1 -1
  84. package/dist/runtime/queue/message-queue.js.map +1 -1
  85. package/dist/runtime/queue/queue-item.d.ts +12 -0
  86. package/dist/runtime/queue/queue-item.d.ts.map +1 -0
  87. package/dist/runtime/queue/queue-item.js +6 -0
  88. package/dist/runtime/queue/queue-item.js.map +1 -0
  89. package/dist/runtime/utils/abortable-thread-load.d.ts +15 -0
  90. package/dist/runtime/utils/abortable-thread-load.d.ts.map +1 -0
  91. package/dist/runtime/utils/abortable-thread-load.js +35 -0
  92. package/dist/runtime/utils/abortable-thread-load.js.map +1 -0
  93. package/dist/runtime/utils/attachment-add-operations.d.ts +18 -0
  94. package/dist/runtime/utils/attachment-add-operations.d.ts.map +1 -0
  95. package/dist/runtime/utils/attachment-add-operations.js +43 -0
  96. package/dist/runtime/utils/attachment-add-operations.js.map +1 -0
  97. package/dist/runtime/utils/auto-status.d.ts +6 -1
  98. package/dist/runtime/utils/auto-status.d.ts.map +1 -1
  99. package/dist/runtime/utils/auto-status.js +7 -1
  100. package/dist/runtime/utils/auto-status.js.map +1 -1
  101. package/dist/runtime/utils/external-message-conversion.d.ts +47 -0
  102. package/dist/runtime/utils/external-message-conversion.d.ts.map +1 -0
  103. package/dist/runtime/utils/external-message-conversion.js +221 -0
  104. package/dist/runtime/utils/external-message-conversion.js.map +1 -0
  105. package/dist/runtime/utils/external-store-message.d.ts +2 -1
  106. package/dist/runtime/utils/external-store-message.d.ts.map +1 -1
  107. package/dist/runtime/utils/external-store-message.js +2 -1
  108. package/dist/runtime/utils/external-store-message.js.map +1 -1
  109. package/dist/runtime/utils/message-repository-session.d.ts +30 -0
  110. package/dist/runtime/utils/message-repository-session.d.ts.map +1 -0
  111. package/dist/runtime/utils/message-repository-session.js +130 -0
  112. package/dist/runtime/utils/message-repository-session.js.map +1 -0
  113. package/dist/runtime/utils/message-repository.d.ts.map +1 -1
  114. package/dist/runtime/utils/message-repository.js +3 -4
  115. package/dist/runtime/utils/message-repository.js.map +1 -1
  116. package/dist/runtime/utils/pending-tool-calls.d.ts +20 -0
  117. package/dist/runtime/utils/pending-tool-calls.d.ts.map +1 -0
  118. package/dist/runtime/utils/pending-tool-calls.js +22 -0
  119. package/dist/runtime/utils/pending-tool-calls.js.map +1 -0
  120. package/dist/runtime/utils/thread-message-like.d.ts +2 -1
  121. package/dist/runtime/utils/thread-message-like.d.ts.map +1 -1
  122. package/dist/runtime/utils/thread-message-like.js.map +1 -1
  123. package/dist/runtimes/external-store/external-store-thread-list-runtime-core.d.ts +2 -5
  124. package/dist/runtimes/external-store/external-store-thread-list-runtime-core.d.ts.map +1 -1
  125. package/dist/runtimes/external-store/external-store-thread-list-runtime-core.js +3 -10
  126. package/dist/runtimes/external-store/external-store-thread-list-runtime-core.js.map +1 -1
  127. package/dist/runtimes/external-store/external-store-thread-runtime-core.d.ts +19 -1
  128. package/dist/runtimes/external-store/external-store-thread-runtime-core.d.ts.map +1 -1
  129. package/dist/runtimes/external-store/external-store-thread-runtime-core.js +122 -20
  130. package/dist/runtimes/external-store/external-store-thread-runtime-core.js.map +1 -1
  131. package/dist/runtimes/local/local-thread-runtime-core.d.ts +3 -1
  132. package/dist/runtimes/local/local-thread-runtime-core.d.ts.map +1 -1
  133. package/dist/runtimes/local/local-thread-runtime-core.js +20 -2
  134. package/dist/runtimes/local/local-thread-runtime-core.js.map +1 -1
  135. package/dist/runtimes/remote-thread-list/remote-thread-state.d.ts +12 -1
  136. package/dist/runtimes/remote-thread-list/remote-thread-state.d.ts.map +1 -1
  137. package/dist/runtimes/remote-thread-list/remote-thread-state.js +77 -1
  138. package/dist/runtimes/remote-thread-list/remote-thread-state.js.map +1 -1
  139. package/dist/runtimes/tool-invocations/ToolInvocationTracker.d.ts.map +1 -1
  140. package/dist/runtimes/tool-invocations/ToolInvocationTracker.js +2 -0
  141. package/dist/runtimes/tool-invocations/ToolInvocationTracker.js.map +1 -1
  142. package/dist/store/clients/external-thread.d.ts.map +1 -1
  143. package/dist/store/clients/external-thread.js +74 -99
  144. package/dist/store/clients/external-thread.js.map +1 -1
  145. package/dist/store/clients/single-thread-list.d.ts.map +1 -1
  146. package/dist/store/clients/single-thread-list.js +1 -1
  147. package/dist/store/clients/single-thread-list.js.map +1 -1
  148. package/dist/store/clients/suggestions.d.ts.map +1 -1
  149. package/dist/store/clients/suggestions.js +16 -7
  150. package/dist/store/clients/suggestions.js.map +1 -1
  151. package/dist/store/index.d.ts +4 -2
  152. package/dist/store/scope-registration.d.ts +1 -1
  153. package/dist/store/scopes/composer.d.ts +2 -1
  154. package/dist/store/scopes/composer.d.ts.map +1 -1
  155. package/dist/store/scopes/message.d.ts +1 -1
  156. package/dist/store/scopes/queue-item.d.ts +2 -9
  157. package/dist/store/scopes/queue-item.d.ts.map +1 -1
  158. package/dist/store/scopes/queue-item.js +0 -6
  159. package/dist/types/message.d.ts +7 -3
  160. package/dist/types/message.d.ts.map +1 -1
  161. package/dist/types/message.js.map +1 -1
  162. package/dist/utils/data-url.d.ts +14 -1
  163. package/dist/utils/data-url.d.ts.map +1 -1
  164. package/dist/utils/data-url.js +13 -1
  165. package/dist/utils/data-url.js.map +1 -1
  166. package/dist/utils/invoke-user-callback.d.ts +5 -0
  167. package/dist/utils/invoke-user-callback.d.ts.map +1 -0
  168. package/dist/utils/invoke-user-callback.js +19 -0
  169. package/dist/utils/invoke-user-callback.js.map +1 -0
  170. package/dist/utils/normalizePartStatus.js.map +1 -1
  171. package/package.json +10 -10
  172. package/src/internal.ts +12 -0
  173. package/src/model-context/frame/host.test.ts +91 -7
  174. package/src/model-context/frame/host.ts +7 -2
  175. package/src/model-context/frame/provider.test.ts +267 -12
  176. package/src/model-context/frame/provider.ts +113 -31
  177. package/src/model-context/interactable-composer-metadata.ts +1 -1
  178. package/src/model-context/registry.test.ts +44 -0
  179. package/src/model-context/registry.ts +13 -35
  180. package/src/react/client/InMemoryThreadList.test.tsx +49 -0
  181. package/src/react/client/InMemoryThreadList.ts +7 -1
  182. package/src/react/client/Interactables.ts +19 -178
  183. package/src/react/client/RemoteThreadList.test.ts +96 -0
  184. package/src/react/client/RemoteThreadList.ts +27 -59
  185. package/src/react/interactables-legacy/Interactables.ts +20 -177
  186. package/src/react/interactables-shared/useInteractablePersistenceQueue.test.tsx +161 -0
  187. package/src/react/interactables-shared/useInteractablePersistenceQueue.ts +206 -0
  188. package/src/react/runtimes/RemoteThreadListThreadListRuntimeCore.tsx +26 -56
  189. package/src/react/runtimes/assistant-transport/runManager.ts +4 -17
  190. package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.test.tsx +92 -0
  191. package/src/react/runtimes/cloud/AssistantCloudThreadHistoryAdapter.ts +40 -141
  192. package/src/react/runtimes/cloud/createCloudThreadListAdapterCreateFallback.test.ts +37 -0
  193. package/src/react/runtimes/cloud/createCloudThreadListAdapterCreateFallback.ts +18 -0
  194. package/src/react/runtimes/external-message-converter.test.ts +0 -14
  195. package/src/react/runtimes/external-message-converter.test.tsx +77 -0
  196. package/src/react/runtimes/external-message-converter.ts +58 -481
  197. package/src/runtime/api/composer-runtime.ts +1 -1
  198. package/src/runtime/api/message-runtime.test.ts +28 -1
  199. package/src/runtime/base/base-composer-runtime-core.ts +20 -40
  200. package/src/runtime/base/base-thread-runtime-core.test.ts +16 -0
  201. package/src/runtime/base/base-thread-runtime-core.ts +6 -11
  202. package/src/runtime/base/default-thread-composer-runtime-core.ts +1 -4
  203. package/src/runtime/interfaces/composer-runtime-core.ts +1 -1
  204. package/src/runtime/interfaces/thread-runtime-core.ts +1 -1
  205. package/src/runtime/internal.ts +5 -0
  206. package/src/runtime/queue/external-thread-queue-adapter.ts +1 -1
  207. package/src/runtime/queue/message-queue.ts +1 -4
  208. package/src/runtime/queue/queue-item.ts +10 -0
  209. package/src/runtime/utils/abortable-thread-load.test.ts +87 -0
  210. package/src/runtime/utils/abortable-thread-load.ts +53 -0
  211. package/src/runtime/utils/attachment-add-operations.ts +59 -0
  212. package/src/runtime/utils/auto-status.ts +33 -0
  213. package/src/runtime/utils/external-message-conversion.test.ts +113 -0
  214. package/src/runtime/utils/external-message-conversion.ts +494 -0
  215. package/src/runtime/utils/external-store-message.ts +2 -0
  216. package/src/runtime/utils/message-repository-session.test.ts +195 -0
  217. package/src/runtime/utils/message-repository-session.ts +176 -0
  218. package/src/runtime/utils/message-repository.ts +7 -4
  219. package/src/runtime/utils/pending-tool-calls.test.ts +57 -0
  220. package/src/runtime/utils/pending-tool-calls.ts +35 -0
  221. package/src/runtime/utils/thread-message-like.ts +2 -0
  222. package/src/runtimes/external-store/external-store-thread-list-runtime-core.ts +6 -14
  223. package/src/runtimes/external-store/external-store-thread-runtime-core.ts +175 -28
  224. package/src/runtimes/local/local-thread-runtime-core.test.ts +172 -1
  225. package/src/runtimes/local/local-thread-runtime-core.ts +48 -3
  226. package/src/runtimes/remote-thread-list/remote-thread-state.test.ts +37 -0
  227. package/src/runtimes/remote-thread-list/remote-thread-state.ts +123 -0
  228. package/src/runtimes/tool-invocations/EDGE_CASES.md +17 -0
  229. package/src/runtimes/tool-invocations/ToolInvocationTracker.test.ts +140 -0
  230. package/src/runtimes/tool-invocations/ToolInvocationTracker.ts +3 -0
  231. package/src/store/clients/external-thread.ts +16 -61
  232. package/src/store/clients/single-thread-list.ts +4 -1
  233. package/src/store/clients/suggestions.test.ts +31 -0
  234. package/src/store/clients/suggestions.ts +18 -19
  235. package/src/store/scopes/message.ts +1 -1
  236. package/src/store/scopes/queue-item.ts +2 -9
  237. package/src/tests/MessageRepository.test.ts +77 -0
  238. package/src/tests/RemoteThreadListThreadListRuntimeCore-load-race.test.ts +194 -0
  239. package/src/tests/RemoteThreadListThreadListRuntimeCore-title-race.test.ts +158 -0
  240. package/src/tests/external-store-thread-runtime-core-adapter.test.ts +164 -0
  241. package/src/tests/external-store-thread-runtime-core.test.ts +642 -0
  242. package/src/tests/external-thread-attachments.test.tsx +173 -0
  243. package/src/tests/single-thread-list-item.test.tsx +47 -0
  244. package/src/tests/thread-message-like.test.ts +39 -1
  245. package/src/types/message.ts +8 -3
  246. package/src/utils/data-url.test.ts +52 -1
  247. package/src/utils/data-url.ts +21 -0
  248. package/src/utils/invoke-user-callback.test.ts +82 -0
  249. package/src/utils/invoke-user-callback.ts +31 -0
  250. package/src/utils/normalizePartStatus.ts +1 -1
  251. package/dist/store/scopes/queue-item.js.map +0 -1
@@ -1,8 +1,13 @@
1
1
  import { MessageStatus } from "../../types/message.js";
2
+ import { ThreadMessageLike } from "./thread-message-like.js";
2
3
  import { ReadonlyJSONValue } from "assistant-stream/utils";
3
4
  //#region src/runtime/utils/auto-status.d.ts
5
+ type ThreadMessageLikeContentItem = Exclude<ThreadMessageLike["content"], string>[number];
6
+ declare const isPendingToolCall: (c: ThreadMessageLikeContentItem) => boolean;
7
+ declare const isInterruptedToolCall: (c: ThreadMessageLikeContentItem) => boolean;
4
8
  declare const isAutoStatus: (status: MessageStatus) => boolean;
5
9
  declare const getAutoStatus: (isLast: boolean, isRunning: boolean, hasInterruptedToolCalls: boolean, hasPendingToolCalls: boolean, error?: ReadonlyJSONValue) => MessageStatus;
10
+ declare const getContentAutoStatus: (content: ThreadMessageLike["content"], isLast: boolean, isRunning: boolean) => MessageStatus;
6
11
  //#endregion
7
- export { getAutoStatus, isAutoStatus };
12
+ export { getAutoStatus, getContentAutoStatus, isAutoStatus, isInterruptedToolCall, isPendingToolCall };
8
13
  //# sourceMappingURL=auto-status.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"auto-status.d.ts","names":[],"sources":["../../../src/runtime/utils/auto-status.ts"],"mappings":";;;cAsCa,eAAgB,QAAQ;cAGxB,gBACX,iBACA,oBACA,kCACA,8BACA,QAAQ,sBACP"}
1
+ {"version":3,"file":"auto-status.d.ts","names":[],"sources":["../../../src/runtime/utils/auto-status.ts"],"mappings":";;;;KAIK,+BAA+B,QAClC;cAIW,oBAAqB,GAAG;cAGxB,wBACX,GAAG;cA8CQ,eAAgB,QAAQ;cAGxB,gBACX,iBACA,oBACA,kCACA,8BACA,QAAQ,sBACP;cAqBU,uBACX,SAAS,8BACT,iBACA,uBACC"}
@@ -1,4 +1,9 @@
1
1
  //#region src/runtime/utils/auto-status.ts
2
+ const isPendingToolCall = (c) => c.type === "tool-call" && c.result === void 0;
3
+ const isInterruptedToolCall = (c) => {
4
+ if (c.type !== "tool-call" || c.result !== void 0) return false;
5
+ return c.interrupt != null || c.approval != null && c.approval.approved === void 0 && c.approval.resolution === void 0;
6
+ };
2
7
  const symbolAutoStatus = Symbol("autoStatus");
3
8
  const AUTO_STATUS_RUNNING = Object.freeze(Object.assign({ type: "running" }, { [symbolAutoStatus]: true }));
4
9
  const AUTO_STATUS_COMPLETE = Object.freeze(Object.assign({
@@ -22,7 +27,8 @@ const getAutoStatus = (isLast, isRunning, hasInterruptedToolCalls, hasPendingToo
22
27
  }, { [symbolAutoStatus]: true });
23
28
  return isLast && isRunning ? AUTO_STATUS_RUNNING : hasInterruptedToolCalls ? AUTO_STATUS_INTERRUPT : hasPendingToolCalls ? AUTO_STATUS_PENDING : AUTO_STATUS_COMPLETE;
24
29
  };
30
+ const getContentAutoStatus = (content, isLast, isRunning) => getAutoStatus(isLast, isRunning, typeof content !== "string" && content.some(isInterruptedToolCall), typeof content !== "string" && content.some(isPendingToolCall));
25
31
  //#endregion
26
- export { getAutoStatus, isAutoStatus };
32
+ export { getAutoStatus, getContentAutoStatus, isAutoStatus, isInterruptedToolCall, isPendingToolCall };
27
33
 
28
34
  //# sourceMappingURL=auto-status.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"auto-status.js","names":["MessageStatus","ReadonlyJSONValue","symbolAutoStatus","Symbol","AUTO_STATUS_RUNNING","Object","freeze","assign","type","const","AUTO_STATUS_COMPLETE","reason","AUTO_STATUS_PENDING","AUTO_STATUS_INTERRUPT","isAutoStatus","status","getAutoStatus","isLast","isRunning","hasInterruptedToolCalls","hasPendingToolCalls","error"],"sources":["../../../src/runtime/utils/auto-status.ts"],"sourcesContent":["import type { MessageStatus } from \"../../types/message\";\nimport type { ReadonlyJSONValue } from \"assistant-stream/utils\";\n\nconst symbolAutoStatus = Symbol(\"autoStatus\");\n\nconst AUTO_STATUS_RUNNING = Object.freeze(\n Object.assign({ type: \"running\" as const }, { [symbolAutoStatus]: true }),\n);\nconst AUTO_STATUS_COMPLETE = Object.freeze(\n Object.assign(\n {\n type: \"complete\" as const,\n reason: \"unknown\" as const,\n },\n { [symbolAutoStatus]: true },\n ),\n);\n\nconst AUTO_STATUS_PENDING = Object.freeze(\n Object.assign(\n {\n type: \"requires-action\" as const,\n reason: \"tool-calls\" as const,\n },\n { [symbolAutoStatus]: true },\n ),\n);\n\nconst AUTO_STATUS_INTERRUPT = Object.freeze(\n Object.assign(\n {\n type: \"requires-action\" as const,\n reason: \"interrupt\" as const,\n },\n { [symbolAutoStatus]: true },\n ),\n);\n\nexport const isAutoStatus = (status: MessageStatus) =>\n (status as any)[symbolAutoStatus] === true;\n\nexport const getAutoStatus = (\n isLast: boolean,\n isRunning: boolean,\n hasInterruptedToolCalls: boolean,\n hasPendingToolCalls: boolean,\n error?: ReadonlyJSONValue,\n): MessageStatus => {\n if (isLast && error) {\n return Object.assign(\n {\n type: \"incomplete\" as const,\n reason: \"error\" as const,\n error: error,\n },\n { [symbolAutoStatus]: true },\n );\n }\n\n return isLast && isRunning\n ? AUTO_STATUS_RUNNING\n : hasInterruptedToolCalls\n ? AUTO_STATUS_INTERRUPT\n : hasPendingToolCalls\n ? AUTO_STATUS_PENDING\n : AUTO_STATUS_COMPLETE;\n};\n"],"mappings":";AAGA,MAAME,mBAAmBC,OAAO,YAAY;AAE5C,MAAMC,sBAAsBC,OAAOC,OACjCD,OAAOE,OAAO,EAAEC,MAAM,UAAmB,GAAG,GAAGN,mBAAmB,KAAK,CAAC,CAC1E;AACA,MAAMQ,uBAAuBL,OAAOC,OAClCD,OAAOE,OACL;CACEC,MAAM;CACNG,QAAQ;AACV,GACA,GAAGT,mBAAmB,KAAK,CAC7B,CACF;AAEA,MAAMU,sBAAsBP,OAAOC,OACjCD,OAAOE,OACL;CACEC,MAAM;CACNG,QAAQ;AACV,GACA,GAAGT,mBAAmB,KAAK,CAC7B,CACF;AAEA,MAAMW,wBAAwBR,OAAOC,OACnCD,OAAOE,OACL;CACEC,MAAM;CACNG,QAAQ;AACV,GACA,GAAGT,mBAAmB,KAAK,CAC7B,CACF;AAEA,MAAaY,gBAAgBC,WAC1BA,OAAeb,sBAAsB;AAExC,MAAac,iBACXC,QACAC,WACAC,yBACAC,qBACAC,UACkB;CAClB,IAAIJ,UAAUI,OACZ,OAAOhB,OAAOE,OACZ;EACEC,MAAM;EACNG,QAAQ;EACDU;CACT,GACA,GAAGnB,mBAAmB,KAAK,CAC7B;CAGF,OAAOe,UAAUC,YACbd,sBACAe,0BACEN,wBACAO,sBACER,sBACAF;AACV"}
1
+ {"version":3,"file":"auto-status.js","names":["MessageStatus","ReadonlyJSONValue","ThreadMessageLike","ThreadMessageLikeContentItem","Exclude","isPendingToolCall","c","type","result","undefined","isInterruptedToolCall","interrupt","approval","approved","resolution","symbolAutoStatus","Symbol","AUTO_STATUS_RUNNING","Object","freeze","assign","const","AUTO_STATUS_COMPLETE","reason","AUTO_STATUS_PENDING","AUTO_STATUS_INTERRUPT","isAutoStatus","status","getAutoStatus","isLast","isRunning","hasInterruptedToolCalls","hasPendingToolCalls","error","getContentAutoStatus","content","some"],"sources":["../../../src/runtime/utils/auto-status.ts"],"sourcesContent":["import type { MessageStatus } from \"../../types/message\";\nimport type { ReadonlyJSONValue } from \"assistant-stream/utils\";\nimport type { ThreadMessageLike } from \"./thread-message-like\";\n\ntype ThreadMessageLikeContentItem = Exclude<\n ThreadMessageLike[\"content\"],\n string\n>[number];\n\nexport const isPendingToolCall = (c: ThreadMessageLikeContentItem): boolean =>\n c.type === \"tool-call\" && c.result === undefined;\n\nexport const isInterruptedToolCall = (\n c: ThreadMessageLikeContentItem,\n): boolean => {\n if (c.type !== \"tool-call\" || c.result !== undefined) return false;\n return (\n c.interrupt != null ||\n (c.approval != null &&\n c.approval.approved === undefined &&\n c.approval.resolution === undefined)\n );\n};\n\nconst symbolAutoStatus = Symbol(\"autoStatus\");\n\nconst AUTO_STATUS_RUNNING = Object.freeze(\n Object.assign({ type: \"running\" as const }, { [symbolAutoStatus]: true }),\n);\nconst AUTO_STATUS_COMPLETE = Object.freeze(\n Object.assign(\n {\n type: \"complete\" as const,\n reason: \"unknown\" as const,\n },\n { [symbolAutoStatus]: true },\n ),\n);\n\nconst AUTO_STATUS_PENDING = Object.freeze(\n Object.assign(\n {\n type: \"requires-action\" as const,\n reason: \"tool-calls\" as const,\n },\n { [symbolAutoStatus]: true },\n ),\n);\n\nconst AUTO_STATUS_INTERRUPT = Object.freeze(\n Object.assign(\n {\n type: \"requires-action\" as const,\n reason: \"interrupt\" as const,\n },\n { [symbolAutoStatus]: true },\n ),\n);\n\nexport const isAutoStatus = (status: MessageStatus) =>\n (status as any)[symbolAutoStatus] === true;\n\nexport const getAutoStatus = (\n isLast: boolean,\n isRunning: boolean,\n hasInterruptedToolCalls: boolean,\n hasPendingToolCalls: boolean,\n error?: ReadonlyJSONValue,\n): MessageStatus => {\n if (isLast && error) {\n return Object.assign(\n {\n type: \"incomplete\" as const,\n reason: \"error\" as const,\n error: error,\n },\n { [symbolAutoStatus]: true },\n );\n }\n\n return isLast && isRunning\n ? AUTO_STATUS_RUNNING\n : hasInterruptedToolCalls\n ? AUTO_STATUS_INTERRUPT\n : hasPendingToolCalls\n ? AUTO_STATUS_PENDING\n : AUTO_STATUS_COMPLETE;\n};\n\nexport const getContentAutoStatus = (\n content: ThreadMessageLike[\"content\"],\n isLast: boolean,\n isRunning: boolean,\n): MessageStatus =>\n getAutoStatus(\n isLast,\n isRunning,\n typeof content !== \"string\" && content.some(isInterruptedToolCall),\n typeof content !== \"string\" && content.some(isPendingToolCall),\n );\n"],"mappings":";AASA,MAAaK,qBAAqBC,MAChCA,EAAEC,SAAS,eAAeD,EAAEE,WAAWC,KAAAA;AAEzC,MAAaC,yBACXJ,MACY;CACZ,IAAIA,EAAEC,SAAS,eAAeD,EAAEE,WAAWC,KAAAA,GAAW,OAAO;CAC7D,OACEH,EAAEK,aAAa,QACdL,EAAEM,YAAY,QACbN,EAAEM,SAASC,aAAaJ,KAAAA,KACxBH,EAAEM,SAASE,eAAeL,KAAAA;AAEhC;AAEA,MAAMM,mBAAmBC,OAAO,YAAY;AAE5C,MAAMC,sBAAsBC,OAAOC,OACjCD,OAAOE,OAAO,EAAEb,MAAM,UAAmB,GAAG,GAAGQ,mBAAmB,KAAK,CAAC,CAC1E;AACA,MAAMO,uBAAuBJ,OAAOC,OAClCD,OAAOE,OACL;CACEb,MAAM;CACNgB,QAAQ;AACV,GACA,GAAGR,mBAAmB,KAAK,CAC7B,CACF;AAEA,MAAMS,sBAAsBN,OAAOC,OACjCD,OAAOE,OACL;CACEb,MAAM;CACNgB,QAAQ;AACV,GACA,GAAGR,mBAAmB,KAAK,CAC7B,CACF;AAEA,MAAMU,wBAAwBP,OAAOC,OACnCD,OAAOE,OACL;CACEb,MAAM;CACNgB,QAAQ;AACV,GACA,GAAGR,mBAAmB,KAAK,CAC7B,CACF;AAEA,MAAaW,gBAAgBC,WAC1BA,OAAeZ,sBAAsB;AAExC,MAAaa,iBACXC,QACAC,WACAC,yBACAC,qBACAC,UACkB;CAClB,IAAIJ,UAAUI,OACZ,OAAOf,OAAOE,OACZ;EACEb,MAAM;EACNgB,QAAQ;EACDU;CACT,GACA,GAAGlB,mBAAmB,KAAK,CAC7B;CAGF,OAAOc,UAAUC,YACbb,sBACAc,0BACEN,wBACAO,sBACER,sBACAF;AACV;AAEA,MAAaY,wBACXC,SACAN,QACAC,cAEAF,cACEC,QACAC,WACA,OAAOK,YAAY,YAAYA,QAAQC,KAAK1B,qBAAqB,GACjE,OAAOyB,YAAY,YAAYA,QAAQC,KAAK/B,iBAAiB,CAC/D"}
@@ -0,0 +1,47 @@
1
+ import { MessageTiming, ThreadMessage } from "../../types/message.js";
2
+ import { ThreadMessageLike } from "./thread-message-like.js";
3
+ import { ToolExecutionStatus } from "../../runtimes/tool-invocations/ToolInvocationTracker.js";
4
+ import { ReadonlyJSONValue } from "assistant-stream/utils";
5
+ //#region src/runtime/utils/external-message-conversion.d.ts
6
+ type JoinStrategy = "concat-content" | "none";
7
+ type ExternalMessageConverterMessage = (ThreadMessageLike & {
8
+ readonly convertConfig?: {
9
+ readonly joinStrategy?: JoinStrategy;
10
+ };
11
+ }) | {
12
+ role: "tool";
13
+ toolCallId: string;
14
+ toolName?: string | undefined;
15
+ result: any;
16
+ artifact?: any;
17
+ isError?: boolean;
18
+ messages?: readonly ThreadMessage[];
19
+ };
20
+ type ExternalMessageConverterMetadata = {
21
+ readonly toolStatuses?: Record<string, ToolExecutionStatus>;
22
+ readonly error?: ReadonlyJSONValue;
23
+ readonly messageTiming?: Record<string, MessageTiming>;
24
+ };
25
+ type ExternalMessageConverterCallback<T> = (message: T, metadata: ExternalMessageConverterMetadata) => ExternalMessageConverterMessage | ExternalMessageConverterMessage[];
26
+ type ExternalMessageConverterCallbackResult<T> = {
27
+ input: T;
28
+ outputs: ExternalMessageConverterMessage[];
29
+ };
30
+ type ExternalMessageConverterChunk<T> = {
31
+ inputs: T[];
32
+ outputs: ExternalMessageConverterMessage[];
33
+ };
34
+ declare const convertExternalMessageCallback: <T>(input: T, callback: ExternalMessageConverterCallback<T>, metadata: ExternalMessageConverterMetadata) => ExternalMessageConverterCallbackResult<T>;
35
+ declare const joinExternalMessages: (messages: readonly ExternalMessageConverterMessage[]) => ThreadMessageLike;
36
+ declare const chunkExternalMessages: <T>(callbackResults: ExternalMessageConverterCallbackResult<T>[], joinStrategy?: JoinStrategy) => ExternalMessageConverterChunk<T>[];
37
+ declare const shallowArrayEqual: (a: unknown[], b: unknown[]) => boolean;
38
+ type ExternalMessageConversionCache = {
39
+ message: ThreadMessage | undefined;
40
+ generatedFallbackMessages: WeakSet<object>;
41
+ };
42
+ declare const convertExternalMessageChunk: <T>(message: ExternalMessageConverterChunk<T>, idx: number, chunkCount: number, isRunning: boolean, error: ReadonlyJSONValue | undefined, cache?: ExternalMessageConversionCache) => ThreadMessage;
43
+ declare const completeExternalMessageConversion: (messages: ThreadMessage[], error: ReadonlyJSONValue | undefined) => ThreadMessage[];
44
+ declare const convertExternalMessages: <T extends WeakKey>(messages: T[], callback: ExternalMessageConverterCallback<T>, isRunning: boolean, metadata: ExternalMessageConverterMetadata) => ThreadMessage[];
45
+ //#endregion
46
+ export { ExternalMessageConverterCallback, ExternalMessageConverterCallbackResult, ExternalMessageConverterChunk, ExternalMessageConverterMessage, ExternalMessageConverterMetadata, JoinStrategy, chunkExternalMessages, completeExternalMessageConversion, convertExternalMessageCallback, convertExternalMessageChunk, convertExternalMessages, joinExternalMessages, shallowArrayEqual };
47
+ //# sourceMappingURL=external-message-conversion.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"external-message-conversion.d.ts","names":[],"sources":["../../../src/runtime/utils/external-message-conversion.ts"],"mappings":";;;;;KA2BY;KAEA,mCACP;WACU;aACE,eAAe;;;EAI1B;EACA;EACA;EACA;EACA;EACA;EACA,oBAAoB;;KAGd;WACD,eAAe,eAAe;WAC9B,QAAQ;WACR,gBAAgB,eAAe;;KAG9B,iCAAiC,MAC3C,SAAS,GACT,UAAU,qCACP,kCAAkC;KAE3B,uCAAuC;EACjD,OAAO;EACP,SAAS;;KAGC,8BAA8B;EACxC,QAAQ;EACR,SAAS;;cAsDE,iCAAkC,GAC7C,OAAO,GACP,UAAU,iCAAiC,IAC3C,UAAU,qCACT,uCAAuC;cAY7B,uBACX,mBAAmB,sCAClB;cA4KU,wBAAyB,GACpC,iBAAiB,uCAAuC,MACxD,eAAe,iBAAY,8BAAA;cAmDhB,oBAAqB,cAAc;KAQ3C;EACH,SAAS;EACT,2BAA2B;;cAGhB,8BAA+B,GAC1C,SAAS,8BAA8B,IACvC,aACA,oBACA,oBACA,OAAO,+BACP,QAAQ,mCAA8B;cAiF3B,oCACX,UAAU,iBACV,OAAO,kCAA6B;cAWzB,0BAA2B,UAAU,SAChD,UAAU,KACV,UAAU,iCAAiC,IAC3C,oBACA,UAAU,qCAAgC"}
@@ -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;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
+ {"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"}