@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 +1 @@
1
- {"version":3,"file":"local-thread-runtime-core.js","names":["fromThreadMessageLike","generateId","ChatModelAdapter","ChatModelRunResult","shouldContinue","LocalRuntimeOptionsBase","consumeSuggestionResult","AddToolResultOptions","ResumeToolCallOptions","RespondToToolApprovalOptions","ThreadSuggestion","ThreadRuntimeCore","StartRunConfig","ResumeRunConfig","BaseThreadRuntimeCore","AppendMessage","ThreadAssistantMessage","RunConfig","MessageNotSentError","toAssistantError","ModelContextProvider","createMessageQueue","MessageQueueController","QueuePlacement","EMPTY_QUEUE_ITEMS","QueueItemState","captureThreadRuntimeGeneration","invalidateThreadRuntime","isThreadRuntimeGenerationCurrent","AbortError","Error","name","detach","constructor","message","LocalThreadRuntimeCore","capabilities","switchToBranch","switchBranchDuringRun","edit","delete","reload","refetchThread","cancel","unstable_copy","speech","dictation","voice","attachments","feedback","queue","abortController","AbortController","_queue","_queueRunInFlight","_activeRun","cancelled","_runGeneration","_historyWrites","Map","Promise","_chainHistoryWrite","id","write","next","get","resolve","then","stored","set","_persistPausedMessage","parentId","status","type","history","_options","adapters","update","bind","item","runConfig","_lastRunConfig","catch","isDisabled","isSendDisabled","_isLoading","isLoading","_suggestions","_suggestionsController","suggestions","contextProvider","options","__internal_setOptions","_getThreadId","__internal_setGetThreadId","getThreadId","_getInitializePromise","__internal_setGetInitializePromise","getPromise","extras","undefined","previousHistory","hasUpdates","canSpeak","canDictate","canVoice","canAttach","canFeedback","canDelete","canQueue","unstable_enableMessageQueue","run","generation","_runAppend","messages","at","finally","notifyIdle","subscribe","_notifySubscribers","_loadRequested","_loadPromise","length","__internal_load","error","console","promise","load","repo","repository","import","ensureInitialized","resume","unstable_resume","startRun","headId","sourceId","append","isTail","willRun","role","steer","adapter","enqueue","unstable_queueClearOnRewind","clear","getQueueItems","items","getSteerQueueItems","steerItems","moveQueueItem","queueItemId","placement","move","removeQueueItem","remove","_rollbackAppend","messageId","deleteMessage","rawMessage","enrichAppendMetadata","newMessage","reason","addOrUpdateMessage","initPromise","notSent","cause","historyWrite","runResult","historyResult","allSettled","resetHead","getMessages","messageIndex","findIndex","m","resumeRun","stream","startConfig","exportExternalState","importExternalState","unstable_notifySessionReset","runCallback","content","metadata","unstable_state","state","unstable_annotations","unstable_data","steps","custom","createdAt","Date","_runLoop","_notifyEventSubscribers","alreadyPersisted","active","notifyBusy","abort","performRoundtrip","unstable_humanToolNames","queueMicrotask","suggestion","signal","promiseOrGenerator","generate","onUpdate","r","initialContent","initialAnnotations","initialData","initialSteps","initialCustom","hasStoredMessage","getMessage","ownsMessage","updateMessage","Partial","newSteps","newAnnotations","newData","annotations","data","timing","maxSteps","unstable_composerMetadata","_","context","getModelContext","chatModel","abortSignal","shouldCancelMessage","aborted","threadId","unstable_assistantMessageId","unstable_threadId","unstable_parentId","unstable_getMessage","Symbol","asyncIterator","e","isTerminal","isPausing","cancelRun","unstable_queueClearOnCancel","notifyCancelled","addToolResult","toolCallId","result","isError","artifact","messageData","added","found","newContent","map","c","resumeToolCall","respondToToolApproval","approvalId","approved","optionId","findLast","some","approval","target","find","resolution","targetApproval"],"sources":["../../../src/runtimes/local/local-thread-runtime-core.ts"],"sourcesContent":["import { fromThreadMessageLike } from \"../../runtime/utils/thread-message-like\";\nimport { generateId } from \"../../utils/id\";\nimport type {\n ChatModelAdapter,\n ChatModelRunResult,\n} from \"../../runtime/utils/chat-model-adapter\";\nimport { shouldContinue } from \"./should-continue\";\nimport type { LocalRuntimeOptionsBase } from \"./local-runtime-options\";\nimport { consumeSuggestionResult } from \"../../adapters/suggestion\";\nimport type {\n AddToolResultOptions,\n ResumeToolCallOptions,\n RespondToToolApprovalOptions,\n ThreadSuggestion,\n ThreadRuntimeCore,\n StartRunConfig,\n ResumeRunConfig,\n} from \"../../runtime/interfaces/thread-runtime-core\";\nimport { BaseThreadRuntimeCore } from \"../../runtime/base/base-thread-runtime-core\";\nimport type {\n AppendMessage,\n ThreadAssistantMessage,\n} from \"../../types/message\";\nimport type { RunConfig } from \"../../types/message\";\nimport { MessageNotSentError, toAssistantError } from \"../../types/error\";\nimport type { ModelContextProvider } from \"../../model-context/types\";\nimport {\n createMessageQueue,\n type MessageQueueController,\n} from \"../../runtime/queue/message-queue\";\nimport type { QueuePlacement } from \"../../runtime/queue/external-thread-queue-adapter\";\nimport {\n EMPTY_QUEUE_ITEMS,\n type QueueItemState,\n} from \"../../store/scopes/queue-item\";\nimport {\n captureThreadRuntimeGeneration,\n invalidateThreadRuntime,\n isThreadRuntimeGenerationCurrent,\n} from \"../../runtime/utils/thread-runtime-lifecycle\";\n\nclass AbortError extends Error {\n override name = \"AbortError\";\n detach: boolean;\n\n constructor(detach: boolean, message?: string) {\n super(message);\n this.detach = detach;\n }\n}\n\nexport class LocalThreadRuntimeCore\n extends BaseThreadRuntimeCore\n implements ThreadRuntimeCore\n{\n public readonly capabilities = {\n switchToBranch: true,\n switchBranchDuringRun: true,\n edit: true,\n delete: false,\n reload: true,\n refetchThread: false,\n cancel: true,\n unstable_copy: true,\n speech: false,\n dictation: false,\n voice: false,\n attachments: false,\n feedback: false,\n queue: false,\n };\n\n private abortController: AbortController | null = null;\n\n private _queue: MessageQueueController | null = null;\n private _queueRunInFlight = false;\n private _activeRun: { cancelled: boolean } | null = null;\n private _runGeneration = 0;\n\n private _historyWrites = new Map<string, Promise<void>>();\n\n // Writes for one message id must land in issue order; an earlier paused\n // snapshot arriving after the terminal write would resurrect the pause.\n private _chainHistoryWrite(\n id: string,\n write: () => Promise<void>,\n ): Promise<void> {\n const next = (this._historyWrites.get(id) ?? Promise.resolve()).then(\n write,\n write,\n );\n const stored = next.then(\n () => {},\n () => {},\n );\n this._historyWrites.set(id, stored);\n void stored.then(() => {\n if (this._historyWrites.get(id) === stored) {\n this._historyWrites.delete(id);\n }\n });\n return next;\n }\n\n // A decision recorded on a still-paused message must reach history before\n // the run resumes, or a refresh would restore the message without it.\n private _persistPausedMessage(\n parentId: string | null,\n message: ThreadAssistantMessage,\n ) {\n if (message.status?.type !== \"requires-action\") return;\n const history = this._options.adapters.history;\n if (!history?.update) return;\n const update = history.update.bind(history);\n const item = { parentId, message, runConfig: this._lastRunConfig };\n this._chainHistoryWrite(message.id, () => update(item)).catch(() => {});\n }\n\n public readonly isDisabled = false;\n public readonly isSendDisabled = false;\n\n private _isLoading = false;\n public get isLoading() {\n return this._isLoading;\n }\n\n private _suggestions: readonly ThreadSuggestion[] = [];\n private _suggestionsController: AbortController | null = null;\n public get suggestions(): readonly ThreadSuggestion[] {\n return this._suggestions;\n }\n\n public get adapters() {\n return this._options.adapters;\n }\n\n constructor(\n contextProvider: ModelContextProvider,\n options: LocalRuntimeOptionsBase,\n ) {\n super(contextProvider);\n this.__internal_setOptions(options);\n }\n\n private _options!: LocalRuntimeOptionsBase;\n\n private _lastRunConfig: RunConfig = {};\n\n private _getThreadId?: () => string | undefined;\n\n public __internal_setGetThreadId(getThreadId: () => string | undefined) {\n this._getThreadId = getThreadId;\n }\n\n private _getInitializePromise?: () => Promise<unknown> | undefined;\n\n public __internal_setGetInitializePromise(\n getPromise: () => Promise<unknown> | undefined,\n ) {\n this._getInitializePromise = getPromise;\n }\n\n public get extras() {\n return undefined;\n }\n\n public __internal_setOptions(options: LocalRuntimeOptionsBase) {\n if (this._options === options) return;\n\n const previousHistory = this._options?.adapters.history;\n this._options = options;\n\n let hasUpdates = false;\n\n const canSpeak = options.adapters?.speech !== undefined;\n if (this.capabilities.speech !== canSpeak) {\n this.capabilities.speech = canSpeak;\n hasUpdates = true;\n }\n\n const canDictate = options.adapters?.dictation !== undefined;\n if (this.capabilities.dictation !== canDictate) {\n this.capabilities.dictation = canDictate;\n hasUpdates = true;\n }\n\n const canVoice = options.adapters?.voice !== undefined;\n if (this.capabilities.voice !== canVoice) {\n this.capabilities.voice = canVoice;\n hasUpdates = true;\n }\n\n const canAttach = options.adapters?.attachments !== undefined;\n if (this.capabilities.attachments !== canAttach) {\n this.capabilities.attachments = canAttach;\n hasUpdates = true;\n }\n\n const canFeedback = options.adapters?.feedback !== undefined;\n if (this.capabilities.feedback !== canFeedback) {\n this.capabilities.feedback = canFeedback;\n hasUpdates = true;\n }\n\n const canDelete = options.adapters?.history?.delete !== undefined;\n if (this.capabilities.delete !== canDelete) {\n this.capabilities.delete = canDelete;\n hasUpdates = true;\n }\n\n const canQueue = options.unstable_enableMessageQueue === true;\n if (canQueue && !this._queue) {\n this._queue = createMessageQueue({\n run: (message) => {\n // release the queue when the dispatch settles, even if it rejects\n // before reaching startRun's finally, so a failure can't deadlock it\n this._queueRunInFlight = true;\n const generation = this._runGeneration;\n // the tail may have moved since the message was enqueued\n void this._runAppend({\n ...message,\n parentId: this.messages.at(-1)?.id ?? null,\n })\n .finally(() => {\n this._queueRunInFlight = false;\n // a dispatch that failed before starting a run settles here;\n // runs that did start release from _runLoop\n if (this._runGeneration === generation) this._queue?.notifyIdle();\n })\n .catch(() => {});\n },\n });\n this._queue.subscribe(() => this._notifySubscribers());\n } else if (!canQueue && this._queue) {\n this._queue = null;\n }\n if (this.capabilities.queue !== canQueue) {\n this.capabilities.queue = canQueue;\n hasUpdates = true;\n }\n\n if (hasUpdates) this._notifySubscribers();\n\n if (\n this._loadRequested &&\n !this._loadPromise &&\n !previousHistory &&\n options.adapters.history &&\n this.messages.length === 0\n ) {\n void this.__internal_load().catch((error: unknown) => {\n console.error(\n \"[assistant-ui] local thread history load failed:\",\n error,\n );\n });\n }\n }\n\n private _loadPromise: Promise<void> | undefined;\n private _loadRequested = false;\n public __internal_load() {\n this._loadRequested = true;\n if (this._loadPromise) return this._loadPromise;\n if (!this.adapters.history) return Promise.resolve();\n\n const promise = this.adapters.history.load();\n\n this._isLoading = true;\n this._notifySubscribers();\n\n this._loadPromise = promise\n .then((repo) => {\n if (!repo) return;\n this.repository.import(repo);\n if (repo.messages.length > 0) {\n this.ensureInitialized();\n }\n this._notifySubscribers();\n\n const resume = this.adapters.history?.resume?.bind(\n this.adapters.history,\n );\n if (repo.unstable_resume && resume) {\n this.startRun(\n {\n parentId: this.repository.headId,\n sourceId: this.repository.headId,\n runConfig: this._lastRunConfig,\n },\n resume,\n ).catch(() => {});\n }\n })\n .finally(() => {\n this._isLoading = false;\n this._notifySubscribers();\n });\n\n return this._loadPromise;\n }\n\n public async append(message: AppendMessage): Promise<void> {\n const isTail = message.parentId === (this.messages.at(-1)?.id ?? null);\n const willRun = message.startRun ?? message.role === \"user\";\n if (this._queue && willRun && isTail) {\n if (message.steer ?? this._queueRunInFlight)\n this._queue.adapter.steer(message);\n else this._queue.adapter.enqueue(message);\n return;\n }\n if (\n this._queue &&\n !isTail &&\n (this._options.unstable_queueClearOnRewind ?? true)\n )\n this._queue.clear();\n return this._runAppend(message);\n }\n\n public getQueueItems(): readonly QueueItemState[] {\n // Reads can arrive during base-thread construction, before the queue field\n // is assigned, so guard against the unset field.\n return this._queue?.adapter.items ?? EMPTY_QUEUE_ITEMS;\n }\n\n public getSteerQueueItems(): readonly QueueItemState[] {\n return this._queue?.adapter.steerItems ?? EMPTY_QUEUE_ITEMS;\n }\n\n public moveQueueItem(queueItemId: string, placement: QueuePlacement): void {\n this._queue?.adapter.move(queueItemId, placement);\n }\n\n public removeQueueItem(queueItemId: string): void {\n this._queue?.adapter.remove(queueItemId);\n }\n\n private _rollbackAppend(messageId: string) {\n try {\n this.repository.deleteMessage(messageId);\n } catch {\n return;\n }\n this._notifySubscribers();\n }\n\n private async _runAppend(rawMessage: AppendMessage): Promise<void> {\n // Stamped here rather than in `append` so a queued message is gated after\n // the flush re-pointed its parentId at the current tail.\n const generation = captureThreadRuntimeGeneration(this);\n const message = this.enrichAppendMetadata(rawMessage);\n this.ensureInitialized();\n\n const newMessage = fromThreadMessageLike(message, generateId(), {\n type: \"complete\",\n reason: \"unknown\",\n });\n this.repository.addOrUpdateMessage(message.parentId, newMessage);\n this._notifySubscribers();\n\n // Initialization only gates the history write and the run; the message\n // is already on screen. A failed barrier rolls the optimistic message\n // back and rejects as an unsent message so the composer restores the\n // draft; a thread invalidated mid-wait rolls back silently.\n try {\n const initPromise = this._getInitializePromise?.();\n if (initPromise) {\n await initPromise;\n }\n } catch (error) {\n this._rollbackAppend(newMessage.id);\n if (!isThreadRuntimeGenerationCurrent(this, generation)) return;\n const notSent = new MessageNotSentError();\n notSent.cause = error;\n throw notSent;\n }\n if (!isThreadRuntimeGenerationCurrent(this, generation)) {\n this._rollbackAppend(newMessage.id);\n return;\n }\n const historyWrite = this._options.adapters.history?.append({\n parentId: message.parentId,\n message: newMessage,\n ...(message.runConfig !== undefined && { runConfig: message.runConfig }),\n });\n void historyWrite?.catch(() => {});\n\n const startRun = message.startRun ?? message.role === \"user\";\n if (startRun) {\n const [runResult, historyResult] = await Promise.allSettled([\n this.startRun({\n parentId: newMessage.id,\n sourceId: message.sourceId,\n runConfig: message.runConfig ?? {},\n }),\n historyWrite,\n ]);\n if (runResult.status === \"rejected\") throw runResult.reason;\n if (historyResult.status === \"rejected\") throw historyResult.reason;\n } else {\n this.repository.resetHead(newMessage.id);\n this._notifySubscribers();\n await historyWrite;\n }\n }\n\n public async deleteMessage(messageId: string): Promise<void> {\n const adapter = this._options.adapters.history;\n if (!adapter?.delete)\n throw new Error(\"Runtime does not support deleting messages.\");\n\n const messages = this.repository.getMessages();\n const messageIndex = messages.findIndex((m) => m.id === messageId);\n if (messageIndex === -1) throw new Error(\"Message not found.\");\n\n const message = messages[messageIndex]!;\n const parentId = messages[messageIndex - 1]?.id ?? null;\n const items = [{ parentId, message }];\n\n await adapter.delete(items);\n\n this.repository.deleteMessage(messageId);\n this._notifySubscribers();\n }\n\n public resumeRun({ stream, ...startConfig }: ResumeRunConfig): Promise<void> {\n if (!stream)\n throw new Error(\"You must pass a stream parameter to resume runs.\");\n return this.startRun(startConfig, stream);\n }\n\n public exportExternalState(): any {\n throw new Error(\"Runtime does not support exporting external states.\");\n }\n\n public importExternalState(): void {\n throw new Error(\"Runtime does not support importing external states.\");\n }\n\n public unstable_notifySessionReset(): void {\n throw new Error(\"Runtime does not support resetting sessions.\");\n }\n\n public async startRun(\n { parentId, runConfig }: StartRunConfig,\n runCallback?: ChatModelAdapter[\"run\"],\n ): Promise<void> {\n this.ensureInitialized();\n\n // add assistant message\n const id = generateId();\n const message: ThreadAssistantMessage = {\n id,\n role: \"assistant\",\n status: { type: \"running\" },\n content: [],\n metadata: {\n unstable_state: this.state,\n unstable_annotations: [],\n unstable_data: [],\n steps: [],\n custom: {},\n },\n createdAt: new Date(),\n };\n\n return this._runLoop(parentId, message, runConfig, runCallback);\n }\n\n private async _runLoop(\n parentId: string | null,\n message: ThreadAssistantMessage,\n runConfig: RunConfig | undefined,\n runCallback?: ChatModelAdapter[\"run\"],\n ): Promise<void> {\n this._notifyEventSubscribers(\"runStart\", {});\n\n // A run entered on a requires-action message resumes a pause an\n // update-capable adapter already holds (written at pause time or loaded).\n const alreadyPersisted =\n message.status?.type === \"requires-action\" &&\n this._options.adapters.history?.update !== undefined;\n\n const run = { cancelled: false };\n this._activeRun = run;\n this._runGeneration++;\n\n let active = false;\n try {\n // mark busy for runs not started through the queue (regenerate, resume)\n this._queue?.notifyBusy();\n this._suggestions = [];\n this._suggestionsController?.abort();\n this._suggestionsController = null;\n this._notifySubscribers();\n\n do {\n message = await this.performRoundtrip(\n parentId,\n message,\n runConfig,\n alreadyPersisted,\n run,\n runCallback,\n );\n runCallback = undefined;\n if (this._activeRun !== run) break;\n } while (shouldContinue(message, this._options.unstable_humanToolNames));\n } finally {\n this._notifyEventSubscribers(\"runEnd\", {});\n // the settle belongs to this run only while it is still the active run\n // or was cancelled (the engine expects a cancelled run's settle); a run\n // superseded by a newer one stays silent\n active = this._activeRun === run;\n if (active) this._activeRun = null;\n if (active || run.cancelled) {\n queueMicrotask(() => this._queue?.notifyIdle());\n }\n }\n\n if (\n active &&\n this.adapters.suggestion &&\n message.status?.type !== \"requires-action\"\n ) {\n this._suggestionsController = new AbortController();\n const signal = this._suggestionsController.signal;\n const adapter = this.adapters.suggestion;\n void (async () => {\n try {\n const promiseOrGenerator = adapter.generate({\n messages: this.messages,\n signal,\n });\n await consumeSuggestionResult(promiseOrGenerator, {\n signal,\n onUpdate: (r) => {\n this._suggestions = r;\n this._notifySubscribers();\n },\n });\n } catch {}\n })();\n }\n }\n\n private async performRoundtrip(\n parentId: string | null,\n message: ThreadAssistantMessage,\n runConfig: RunConfig | undefined,\n alreadyPersisted: boolean,\n run: { cancelled: boolean },\n runCallback?: ChatModelAdapter[\"run\"],\n ) {\n const messages = parentId ? this.repository.getMessages(parentId) : [];\n\n // abort existing run\n this.abortController?.abort();\n const abortController = new AbortController();\n this.abortController = abortController;\n\n const initialContent = message.content;\n const initialAnnotations = message.metadata?.unstable_annotations;\n const initialData = message.metadata?.unstable_data;\n const initialSteps = message.metadata?.steps;\n const initialCustom = message.metadata?.custom;\n let hasStoredMessage = true;\n try {\n this.repository.getMessage(message.id);\n } catch {\n hasStoredMessage = false;\n }\n // Other writers replace the stored message object, so identity distinguishes this run from a newer owner.\n const ownsMessage = () => {\n if (!hasStoredMessage) return this._activeRun === run;\n try {\n return this.repository.getMessage(message.id).message === message;\n } catch {\n return false;\n }\n };\n const updateMessage = (m: Partial<ChatModelRunResult>) => {\n if (!ownsMessage()) return;\n const newSteps = m.metadata?.steps;\n const steps = newSteps\n ? [...(initialSteps ?? []), ...newSteps]\n : undefined;\n\n const newAnnotations = m.metadata?.unstable_annotations;\n const newData = m.metadata?.unstable_data;\n const annotations = newAnnotations\n ? [...(initialAnnotations ?? []), ...newAnnotations]\n : undefined;\n const data = newData ? [...(initialData ?? []), ...newData] : undefined;\n\n message = {\n ...message,\n ...(m.content\n ? { content: [...initialContent, ...(m.content ?? [])] }\n : undefined),\n status: m.status ?? message.status,\n ...(m.metadata\n ? {\n metadata: {\n ...message.metadata,\n ...(m.metadata.unstable_state !== undefined\n ? { unstable_state: m.metadata.unstable_state }\n : undefined),\n ...(annotations\n ? { unstable_annotations: annotations }\n : undefined),\n ...(data ? { unstable_data: data } : undefined),\n ...(steps ? { steps } : undefined),\n ...(m.metadata?.timing\n ? { timing: m.metadata.timing }\n : undefined),\n ...(m.metadata?.custom\n ? {\n custom: {\n ...(initialCustom ?? {}),\n ...m.metadata.custom,\n },\n }\n : undefined),\n },\n }\n : undefined),\n };\n this.repository.addOrUpdateMessage(parentId, message);\n hasStoredMessage = true;\n this._notifySubscribers();\n };\n\n const maxSteps = this._options.maxSteps ?? 2;\n\n try {\n const steps = message.metadata?.steps?.length ?? 0;\n if (steps >= maxSteps) {\n updateMessage({\n status: {\n type: \"incomplete\",\n reason: \"tool-calls\",\n },\n });\n return message;\n }\n\n updateMessage({\n status: {\n type: \"running\",\n },\n });\n\n // Switch to the new message branch right after adding it for the first time\n this.repository.resetHead(message.id);\n this._notifySubscribers();\n\n this._lastRunConfig = runConfig ?? {};\n // unstable_composerMetadata is composer-only (stamped onto the outgoing\n // message); never expose it to the chat-model adapter's run context.\n const { unstable_composerMetadata: _, ...context } =\n this.getModelContext();\n\n runCallback =\n runCallback ??\n this.adapters.chatModel.run.bind(this.adapters.chatModel);\n\n const abortSignal = abortController.signal;\n const shouldCancelMessage = () =>\n abortSignal.aborted &&\n (message.status.type === \"running\" ||\n (message.status.type === \"requires-action\" &&\n (this._activeRun !== run ||\n shouldContinue(message, this._options.unstable_humanToolNames))));\n const threadId = this._getThreadId?.();\n const promiseOrGenerator = runCallback({\n messages,\n runConfig: this._lastRunConfig,\n abortSignal,\n context,\n unstable_assistantMessageId: message.id,\n unstable_threadId: threadId,\n unstable_parentId: parentId,\n unstable_getMessage() {\n return message;\n },\n });\n\n // handle async iterator for streaming results\n if (Symbol.asyncIterator in promiseOrGenerator) {\n for await (const r of promiseOrGenerator) {\n if (abortSignal.aborted) {\n if (shouldCancelMessage()) {\n updateMessage({\n status: { type: \"incomplete\", reason: \"cancelled\" },\n });\n }\n break;\n }\n\n updateMessage(r);\n }\n } else {\n updateMessage(await promiseOrGenerator);\n }\n\n if (shouldCancelMessage()) {\n updateMessage({\n status: { type: \"incomplete\", reason: \"cancelled\" },\n });\n } else if (message.status.type === \"running\") {\n updateMessage({\n status: { type: \"complete\", reason: \"unknown\" },\n });\n }\n } catch (e) {\n if (e instanceof AbortError) {\n updateMessage({\n status: { type: \"incomplete\", reason: \"cancelled\" },\n });\n } else if (e instanceof Error && e.name === \"AbortError\") {\n updateMessage({\n status: { type: \"incomplete\", reason: \"cancelled\" },\n });\n } else {\n updateMessage({\n status: {\n type: \"incomplete\",\n reason: \"error\",\n error: toAssistantError(e),\n },\n });\n\n throw e;\n }\n } finally {\n if (this.abortController === abortController) {\n this.abortController = null;\n }\n\n const history = this._options.adapters.history;\n const item = {\n parentId,\n message,\n runConfig: this._lastRunConfig,\n };\n const isTerminal =\n message.status.type === \"complete\" ||\n message.status.type === \"incomplete\";\n const isPausing =\n message.status.type === \"requires-action\" &&\n !shouldContinue(message, this._options.unstable_humanToolNames);\n\n // Pauses are written only for adapters that can rewrite the entry later;\n // an append-only adapter would strand a half-finished run in history.\n if (ownsMessage() && (isTerminal || (isPausing && history?.update))) {\n const write =\n alreadyPersisted && history?.update\n ? history.update.bind(history)\n : history?.append.bind(history);\n if (write) {\n await this._chainHistoryWrite(message.id, () => write(item));\n }\n }\n }\n return message;\n }\n\n public detach() {\n invalidateThreadRuntime(this);\n // drop the queue so pending items cannot dispatch on a detached thread\n this._queue = null;\n const error = new AbortError(true);\n this.abortController?.abort(error);\n this.abortController = null;\n this._suggestionsController?.abort();\n this._suggestionsController = null;\n }\n\n public cancelRun() {\n if (this._queue) {\n if (this._options.unstable_queueClearOnCancel ?? true) {\n this._queue.clear();\n } else {\n this._queue.notifyCancelled();\n if (this._activeRun) this._activeRun.cancelled = true;\n }\n }\n const error = new AbortError(false);\n this.abortController?.abort(error);\n this.abortController = null;\n this._suggestionsController?.abort();\n this._suggestionsController = null;\n }\n\n public addToolResult({\n messageId,\n toolCallId,\n result,\n isError,\n artifact,\n }: AddToolResultOptions) {\n const messageData = this.repository.getMessage(messageId);\n const { parentId } = messageData;\n let { message } = messageData;\n\n if (message.role !== \"assistant\")\n throw new Error(\"Tried to add tool result to non-assistant message\");\n\n let added = false;\n let found = false;\n const newContent = message.content.map((c) => {\n if (c.type !== \"tool-call\") return c;\n if (c.toolCallId !== toolCallId) return c;\n found = true;\n if (c.result === undefined) added = true;\n return {\n ...c,\n result,\n artifact,\n isError,\n };\n });\n\n if (!found)\n throw new Error(\"Tried to add tool result to non-existing tool call\");\n\n message = {\n ...message,\n content: newContent,\n };\n this.repository.addOrUpdateMessage(parentId, message);\n this._notifySubscribers();\n\n // a result may arrive mid-run or on a non-head message; the resume\n // intentionally aborts any in-flight run, unlike respondToToolApproval\n if (\n added &&\n shouldContinue(message, this._options.unstable_humanToolNames)\n ) {\n this._runLoop(parentId, message, this._lastRunConfig).catch(() => {});\n } else if (added) {\n this._persistPausedMessage(parentId, message);\n }\n }\n\n public resumeToolCall(_options: ResumeToolCallOptions) {\n throw new Error(\n \"Local runtime does not support resuming tool calls. For human-in-the-loop tools, list the tool in unstable_humanToolNames and complete the call with addToolResult.\",\n );\n }\n\n public respondToToolApproval({\n approvalId,\n approved,\n optionId,\n reason,\n }: RespondToToolApprovalOptions) {\n let message = this.repository\n .getMessages()\n .findLast(\n (m): m is ThreadAssistantMessage =>\n m.role === \"assistant\" &&\n m.content.some(\n (c) => c.type === \"tool-call\" && c.approval?.id === approvalId,\n ),\n );\n\n if (!message)\n throw new Error(\"Tried to respond to a non-existing tool approval\");\n\n if (this.abortController !== null)\n throw new Error(\n \"Tried to respond to a tool approval while a run is in progress\",\n );\n\n if (message.status?.type !== \"requires-action\")\n throw new Error(\n \"Tried to respond to a tool approval on a message whose status is not requires-action\",\n );\n\n const target = message.content.find(\n (c) => c.type === \"tool-call\" && c.approval?.id === approvalId,\n );\n if (target?.type !== \"tool-call\" || !target.approval)\n throw new Error(\"Tried to respond to a non-existing tool approval\");\n if (target.approval.resolution !== undefined)\n throw new Error(\n \"Tried to respond to a tool approval that was cancelled or expired\",\n );\n if (target.approval.approved !== undefined)\n throw new Error(\"Tried to respond to an already decided tool approval\");\n\n const targetApproval = target.approval;\n const newContent = message.content.map((c) => {\n if (c !== target) return c;\n const approval = {\n ...targetApproval,\n approved,\n ...(optionId != null && { optionId }),\n ...(reason != null && { reason }),\n };\n if (approved) return { ...c, approval };\n return {\n ...c,\n approval,\n result: { error: reason || \"Tool approval denied\" },\n isError: true,\n };\n });\n\n message = { ...message, content: newContent };\n const { parentId } = this.repository.getMessage(message.id);\n this.repository.addOrUpdateMessage(parentId, message);\n this._notifySubscribers();\n\n if (\n this.repository.headId === message.id &&\n shouldContinue(message, this._options.unstable_humanToolNames)\n ) {\n this._runLoop(parentId, message, this._lastRunConfig).catch(() => {});\n } else {\n this._persistPausedMessage(parentId, message);\n }\n }\n}\n"],"mappings":";;;;;;;;;;AAyCA,IAAM6B,aAAN,cAAyBC,MAAM;CAC7B,OAAgB;CAChBE;CAEAC,YAAYD,QAAiBE,SAAkB;EAC7C,MAAMA,OAAO;EACb,KAAKF,SAASA;CAChB;AACF;AAEA,IAAaG,yBAAb,cACUrB,sBAEV;CACE,eAA+B;EAC7BuB,gBAAgB;EAChBC,uBAAuB;EACvBC,MAAM;EACNC,QAAQ;EACRC,QAAQ;EACRC,eAAe;EACfC,QAAQ;EACRC,eAAe;EACfC,QAAQ;EACRC,WAAW;EACXC,OAAO;EACPC,aAAa;EACbC,UAAU;EACVC,OAAO;CACT;CAEA,kBAAkD;CAElD,SAAgD;CAChD,oBAA4B;CAC5B,aAAoD;CACpD,iBAAyB;CAEzB,iCAAyB,IAAIS,IAA2B;CAIxD,mBACEG,IACAC,OACe;EACf,MAAMC,QAAQ,KAAKN,eAAeO,IAAIH,EAAE,KAAKF,QAAQM,QAAQ,EAAA,CAAGC,KAC9DJ,OACAA,KACF;EACA,MAAMK,SAASJ,KAAKG,WACZ,CAAC,SACD,CAAC,CACT;EACA,KAAKT,eAAeW,IAAIP,IAAIM,MAAM;EAClC,OAAYD,WAAW;GACrB,IAAI,KAAKT,eAAeO,IAAIH,EAAE,MAAMM,QAClC,KAAKV,eAAelB,OAAOsB,EAAE;EAEjC,CAAC;EACD,OAAOE;CACT;CAIA,sBACEO,UACArC,SACA;EACA,IAAIA,QAAQsC,QAAQC,SAAS,mBAAmB;EAChD,MAAMC,UAAU,KAAKC,SAASC,SAASF;EACvC,IAAI,CAACA,SAASG,QAAQ;EACtB,MAAMA,SAASH,QAAQG,OAAOC,KAAKJ,OAAO;EAC1C,MAAMK,OAAO;GAAER;GAAUrC;GAAS8C,WAAW,KAAKC;EAAe;EACjE,KAAKpB,mBAAmB3B,QAAQ4B,UAAUe,OAAOE,IAAI,CAAC,CAAC,CAACG,YAAY,CAAC,CAAC;CACxE;CAEA,aAA6B;CAC7B,iBAAiC;CAEjC,aAAqB;CACrB,IAAWI,YAAY;EACrB,OAAO,KAAKD;CACd;CAEA,eAAoD,CAAA;CACpD,yBAAyD;CACzD,IAAWI,cAA2C;EACpD,OAAO,KAAKF;CACd;CAEA,IAAWX,WAAW;EACpB,OAAO,KAAKD,SAASC;CACvB;CAEA3C,YACEyD,iBACAC,SACA;EACA,MAAMD,eAAe;EACrB,KAAKE,sBAAsBD,OAAO;CACpC;CAEA;CAEA,iBAAoC,CAAC;CAErC;CAEA,0BAAiCI,aAAuC;EACtE,KAAKF,eAAeE;CACtB;CAEA;CAEA,mCACEG,YACA;EACA,KAAKF,wBAAwBE;CAC/B;CAEA,IAAWC,SAAS,CAEpB;CAEA,sBAA6BR,SAAkC;EAC7D,IAAI,KAAKhB,aAAagB,SAAS;EAE/B,MAAMU,kBAAkB,KAAK1B,UAAUC,SAASF;EAChD,KAAKC,WAAWgB;EAEhB,IAAIW,aAAa;EAEjB,MAAMC,WAAWZ,QAAQf,UAAU/B,WAAWuD,KAAAA;EAC9C,IAAI,KAAKhE,aAAaS,WAAW0D,UAAU;GACzC,KAAKnE,aAAaS,SAAS0D;GAC3BD,aAAa;EACf;EAEA,MAAME,aAAab,QAAQf,UAAU9B,cAAcsD,KAAAA;EACnD,IAAI,KAAKhE,aAAaU,cAAc0D,YAAY;GAC9C,KAAKpE,aAAaU,YAAY0D;GAC9BF,aAAa;EACf;EAEA,MAAMG,WAAWd,QAAQf,UAAU7B,UAAUqD,KAAAA;EAC7C,IAAI,KAAKhE,aAAaW,UAAU0D,UAAU;GACxC,KAAKrE,aAAaW,QAAQ0D;GAC1BH,aAAa;EACf;EAEA,MAAMI,YAAYf,QAAQf,UAAU5B,gBAAgBoD,KAAAA;EACpD,IAAI,KAAKhE,aAAaY,gBAAgB0D,WAAW;GAC/C,KAAKtE,aAAaY,cAAc0D;GAChCJ,aAAa;EACf;EAEA,MAAMK,cAAchB,QAAQf,UAAU3B,aAAamD,KAAAA;EACnD,IAAI,KAAKhE,aAAaa,aAAa0D,aAAa;GAC9C,KAAKvE,aAAaa,WAAW0D;GAC7BL,aAAa;EACf;EAEA,MAAMM,YAAYjB,QAAQf,UAAUF,SAASlC,WAAW4D,KAAAA;EACxD,IAAI,KAAKhE,aAAaI,WAAWoE,WAAW;GAC1C,KAAKxE,aAAaI,SAASoE;GAC3BN,aAAa;EACf;EAEA,MAAMO,WAAWlB,QAAQmB,gCAAgC;EACzD,IAAID,YAAY,CAAC,KAAKxD,QAAQ;GAC5B,KAAKA,SAAShC,mBAAmB,EAC/B0F,MAAM7E,YAAY;IAGhB,KAAKoB,oBAAoB;IACzB,MAAM0D,aAAa,KAAKvD;IAExB,KAAUwD,WAAW;KACnB,GAAG/E;KACHqC,UAAU,KAAK2C,SAASC,GAAG,EAAE,CAAC,EAAErD,MAAM;IACxC,CAAC,CAAC,CACCsD,cAAc;KACb,KAAK9D,oBAAoB;KAGzB,IAAI,KAAKG,mBAAmBuD,YAAY,KAAK3D,QAAQgE,WAAW;IAClE,CAAC,CAAC,CACDnC,YAAY,CAAC,CAAC;GACnB,EACF,CAAC;GACD,KAAK7B,OAAOiE,gBAAgB,KAAKC,mBAAmB,CAAC;EACvD,OAAO,IAAI,CAACV,YAAY,KAAKxD,QAC3B,KAAKA,SAAS;EAEhB,IAAI,KAAKjB,aAAac,UAAU2D,UAAU;GACxC,KAAKzE,aAAac,QAAQ2D;GAC1BP,aAAa;EACf;EAEA,IAAIA,YAAY,KAAKiB,mBAAmB;EAExC,IACE,KAAKC,kBACL,CAAC,KAAKC,gBACN,CAACpB,mBACDV,QAAQf,SAASF,WACjB,KAAKwC,SAASQ,WAAW,GAEzB,KAAUC,gBAAgB,CAAC,CAACzC,OAAO0C,UAAmB;GACpDC,QAAQD,MACN,oDACAA,KACF;EACF,CAAC;CAEL;CAEA;CACA,iBAAyB;CACzB,kBAAyB;EACvB,KAAKJ,iBAAiB;EACtB,IAAI,KAAKC,cAAc,OAAO,KAAKA;EACnC,IAAI,CAAC,KAAK7C,SAASF,SAAS,OAAOd,QAAQM,QAAQ;EAEnD,MAAM4D,UAAU,KAAKlD,SAASF,QAAQqD,KAAK;EAE3C,KAAK1C,aAAa;EAClB,KAAKkC,mBAAmB;EAExB,KAAKE,eAAeK,QACjB3D,MAAM6D,SAAS;GACd,IAAI,CAACA,MAAM;GACX,KAAKC,WAAWC,OAAOF,IAAI;GAC3B,IAAIA,KAAKd,SAASQ,SAAS,GACzB,KAAKS,kBAAkB;GAEzB,KAAKZ,mBAAmB;GAExB,MAAMa,SAAS,KAAKxD,SAASF,SAAS0D,QAAQtD,KAC5C,KAAKF,SAASF,OAChB;GACA,IAAIsD,KAAKK,mBAAmBD,QAC1B,KAAKE,SACH;IACE/D,UAAU,KAAK0D,WAAWM;IAC1BC,UAAU,KAAKP,WAAWM;IAC1BvD,WAAW,KAAKC;GAClB,GACAmD,MACF,CAAC,CAAClD,YAAY,CAAC,CAAC;EAEpB,CAAC,CAAC,CACDkC,cAAc;GACb,KAAK/B,aAAa;GAClB,KAAKkC,mBAAmB;EAC1B,CAAC;EAEH,OAAO,KAAKE;CACd;CAEA,MAAagB,OAAOvG,SAAuC;EACzD,MAAMwG,SAASxG,QAAQqC,cAAc,KAAK2C,SAASC,GAAG,EAAE,CAAC,EAAErD,MAAM;EACjE,MAAM6E,UAAUzG,QAAQoG,YAAYpG,QAAQ0G,SAAS;EACrD,IAAI,KAAKvF,UAAUsF,WAAWD,QAAQ;GACpC,IAAIxG,QAAQ2G,SAAS,KAAKvF,mBACxB,KAAKD,OAAOyF,QAAQD,MAAM3G,OAAO;QAC9B,KAAKmB,OAAOyF,QAAQC,QAAQ7G,OAAO;GACxC;EACF;EACA,IACE,KAAKmB,UACL,CAACqF,WACA,KAAK/D,SAASqE,+BAA+B,OAE9C,KAAK3F,OAAO4F,MAAM;EACpB,OAAO,KAAKhC,WAAW/E,OAAO;CAChC;CAEA,gBAAkD;EAGhD,OAAO,KAAKmB,QAAQyF,QAAQK,SAAS3H;CACvC;CAEA,qBAAuD;EACrD,OAAO,KAAK6B,QAAQyF,QAAQO,cAAc7H;CAC5C;CAEA,cAAqB+H,aAAqBC,WAAiC;EACzE,KAAKnG,QAAQyF,QAAQW,KAAKF,aAAaC,SAAS;CAClD;CAEA,gBAAuBD,aAA2B;EAChD,KAAKlG,QAAQyF,QAAQa,OAAOJ,WAAW;CACzC;CAEA,gBAAwBM,WAAmB;EACzC,IAAI;GACF,KAAK5B,WAAW6B,cAAcD,SAAS;EACzC,QAAQ;GACN;EACF;EACA,KAAKtC,mBAAmB;CAC1B;CAEA,MAAcN,WAAW8C,YAA0C;EAGjE,MAAM/C,aAAatF,+BAA+B,IAAI;EACtD,MAAMQ,UAAU,KAAK8H,qBAAqBD,UAAU;EACpD,KAAK5B,kBAAkB;EAEvB,MAAM8B,aAAajK,sBAAsBkC,SAASjC,WAAW,GAAG;GAC9DwE,MAAM;GACNyF,QAAQ;EACV,CAAC;EACD,KAAKjC,WAAWkC,mBAAmBjI,QAAQqC,UAAU0F,UAAU;EAC/D,KAAK1C,mBAAmB;EAMxB,IAAI;GACF,MAAM6C,cAAc,KAAKpE,wBAAwB;GACjD,IAAIoE,aACF,MAAMA;EAEV,SAASxC,OAAO;GACd,KAAKgC,gBAAgBK,WAAWnG,EAAE;GAClC,IAAI,CAAClC,iCAAiC,MAAMoF,UAAU,GAAG;GACzD,MAAMqD,UAAU,IAAInJ,oBAAoB;GACxCmJ,QAAQC,QAAQ1C;GAChB,MAAMyC;EACR;EACA,IAAI,CAACzI,iCAAiC,MAAMoF,UAAU,GAAG;GACvD,KAAK4C,gBAAgBK,WAAWnG,EAAE;GAClC;EACF;EACA,MAAMyG,eAAe,KAAK5F,SAASC,SAASF,SAAS+D,OAAO;GAC1DlE,UAAUrC,QAAQqC;GAClBrC,SAAS+H;GACT,GAAI/H,QAAQ8C,cAAcoB,KAAAA,KAAa,EAAEpB,WAAW9C,QAAQ8C,UAAU;EACxE,CAAC;EACD,cAAmBE,YAAY,CAAC,CAAC;EAGjC,IADiBhD,QAAQoG,YAAYpG,QAAQ0G,SAAS,QACxC;GACZ,MAAM,CAAC4B,WAAWC,iBAAiB,MAAM7G,QAAQ8G,WAAW,CAC1D,KAAKpC,SAAS;IACZ/D,UAAU0F,WAAWnG;IACrB0E,UAAUtG,QAAQsG;IAClBxD,WAAW9C,QAAQ8C,aAAa,CAAC;GACnC,CAAC,GACDuF,YAAY,CACb;GACD,IAAIC,UAAUhG,WAAW,YAAY,MAAMgG,UAAUN;GACrD,IAAIO,cAAcjG,WAAW,YAAY,MAAMiG,cAAcP;EAC/D,OAAO;GACL,KAAKjC,WAAW0C,UAAUV,WAAWnG,EAAE;GACvC,KAAKyD,mBAAmB;GACxB,MAAMgD;EACR;CACF;CAEA,MAAaT,cAAcD,WAAkC;EAC3D,MAAMf,UAAU,KAAKnE,SAASC,SAASF;EACvC,IAAI,CAACoE,SAAStG,QACZ,MAAM,IAAIV,MAAM,6CAA6C;EAE/D,MAAMoF,WAAW,KAAKe,WAAW2C,YAAY;EAC7C,MAAMC,eAAe3D,SAAS4D,WAAWC,MAAMA,EAAEjH,OAAO+F,SAAS;EACjE,IAAIgB,iBAAiB,IAAI,MAAM,IAAI/I,MAAM,oBAAoB;EAE7D,MAAMI,UAAUgF,SAAS2D;EAEzB,MAAM1B,QAAQ,CAAC;GAAE5E,UADA2C,SAAS2D,eAAe,EAAE,EAAE/G,MAAM;GACxB5B;EAAQ,CAAC;EAEpC,MAAM4G,QAAQtG,OAAO2G,KAAK;EAE1B,KAAKlB,WAAW6B,cAAcD,SAAS;EACvC,KAAKtC,mBAAmB;CAC1B;CAEA,UAAiB,EAAE0D,QAAQ,GAAGC,eAA+C;EAC3E,IAAI,CAACD,QACH,MAAM,IAAInJ,MAAM,kDAAkD;EACpE,OAAO,KAAKwG,SAAS4C,aAAaD,MAAM;CAC1C;CAEA,sBAAkC;EAChC,MAAM,IAAInJ,MAAM,qDAAqD;CACvE;CAEA,sBAAmC;EACjC,MAAM,IAAIA,MAAM,qDAAqD;CACvE;CAEA,8BAA2C;EACzC,MAAM,IAAIA,MAAM,8CAA8C;CAChE;CAEA,MAAawG,SACX,EAAE/D,UAAUS,aACZsG,aACe;EACf,KAAKnD,kBAAkB;EAIvB,MAAMjG,UAAkC;GACtC4B,IAFS7D,WAET6D;GACA8E,MAAM;GACNpE,QAAQ,EAAEC,MAAM,UAAU;GAC1B8G,SAAS,CAAA;GACTC,UAAU;IACRC,gBAAgB,KAAKC;IACrBC,sBAAsB,CAAA;IACtBC,eAAe,CAAA;IACfC,OAAO,CAAA;IACPC,QAAQ,CAAC;GACX;GACAC,2BAAW,IAAIC,KAAK;EACtB;EAEA,OAAO,KAAKC,SAAS1H,UAAUrC,SAAS8C,WAAWsG,WAAW;CAChE;CAEA,MAAcW,SACZ1H,UACArC,SACA8C,WACAsG,aACe;EACf,KAAKY,wBAAwB,YAAY,CAAC,CAAC;EAI3C,MAAMC,mBACJjK,QAAQsC,QAAQC,SAAS,qBACzB,KAAKE,SAASC,SAASF,SAASG,WAAWuB,KAAAA;EAE7C,MAAMW,MAAM,EAAEvD,WAAW,MAAM;EAC/B,KAAKD,aAAawD;EAClB,KAAKtD;EAEL,IAAI2I,SAAS;EACb,IAAI;GAEF,KAAK/I,QAAQgJ,WAAW;GACxB,KAAK9G,eAAe,CAAA;GACpB,KAAKC,wBAAwB8G,MAAM;GACnC,KAAK9G,yBAAyB;GAC9B,KAAK+B,mBAAmB;GAExB,GAAG;IACDrF,UAAU,MAAM,KAAKqK,iBACnBhI,UACArC,SACA8C,WACAmH,kBACApF,KACAuE,WACF;IACAA,cAAclF,KAAAA;IACd,IAAI,KAAK7C,eAAewD,KAAK;GAC/B,SAAS3G,eAAe8B,SAAS,KAAKyC,SAAS6H,uBAAuB;EACxE,UAAU;GACR,KAAKN,wBAAwB,UAAU,CAAC,CAAC;GAIzCE,SAAS,KAAK7I,eAAewD;GAC7B,IAAIqF,QAAQ,KAAK7I,aAAa;GAC9B,IAAI6I,UAAUrF,IAAIvD,WAChBiJ,qBAAqB,KAAKpJ,QAAQgE,WAAW,CAAC;EAElD;EAEA,IACE+E,UACA,KAAKxH,SAAS8H,cACdxK,QAAQsC,QAAQC,SAAS,mBACzB;GACA,KAAKe,yBAAyB,IAAIpC,gBAAgB;GAClD,MAAMuJ,SAAS,KAAKnH,uBAAuBmH;GAC3C,MAAM7D,UAAU,KAAKlE,SAAS8H;GAC9B,CAAM,YAAY;IAChB,IAAI;KACF,MAAME,qBAAqB9D,QAAQ+D,SAAS;MAC1C3F,UAAU,KAAKA;MACfyF;KACF,CAAC;KACD,MAAMrM,wBAAwBsM,oBAAoB;MAChDD;MACAG,WAAWC,MAAM;OACf,KAAKxH,eAAewH;OACpB,KAAKxF,mBAAmB;MAC1B;KACF,CAAC;IACH,QAAQ,CAAC;GACX,EAAA,CAAG;EACL;CACF;CAEA,MAAcgF,iBACZhI,UACArC,SACA8C,WACAmH,kBACApF,KACAuE,aACA;EACA,MAAMpE,WAAW3C,WAAW,KAAK0D,WAAW2C,YAAYrG,QAAQ,IAAI,CAAA;EAGpE,KAAKpB,iBAAiBmJ,MAAM;EAC5B,MAAMnJ,kBAAkB,IAAIC,gBAAgB;EAC5C,KAAKD,kBAAkBA;EAEvB,MAAM6J,iBAAiB9K,QAAQqJ;EAC/B,MAAM0B,qBAAqB/K,QAAQsJ,UAAUG;EAC7C,MAAMuB,cAAchL,QAAQsJ,UAAUI;EACtC,MAAMuB,eAAejL,QAAQsJ,UAAUK;EACvC,MAAMuB,gBAAgBlL,QAAQsJ,UAAUM;EACxC,IAAIuB,mBAAmB;EACvB,IAAI;GACF,KAAKpF,WAAWqF,WAAWpL,QAAQ4B,EAAE;EACvC,QAAQ;GACNuJ,mBAAmB;EACrB;EAEA,MAAME,oBAAoB;GACxB,IAAI,CAACF,kBAAkB,OAAO,KAAK9J,eAAewD;GAClD,IAAI;IACF,OAAO,KAAKkB,WAAWqF,WAAWpL,QAAQ4B,EAAE,CAAC,CAAC5B,YAAYA;GAC5D,QAAQ;IACN,OAAO;GACT;EACF;EACA,MAAMsL,iBAAiBzC,MAAmC;GACxD,IAAI,CAACwC,YAAY,GAAG;GACpB,MAAMG,WAAW3C,EAAES,UAAUK;GAC7B,MAAMA,QAAQ6B,WACV,CAAC,GAAIP,gBAAgB,CAAA,GAAK,GAAGO,QAAQ,IACrCtH,KAAAA;GAEJ,MAAMuH,iBAAiB5C,EAAES,UAAUG;GACnC,MAAMiC,UAAU7C,EAAES,UAAUI;GAC5B,MAAMiC,cAAcF,iBAChB,CAAC,GAAIV,sBAAsB,CAAA,GAAK,GAAGU,cAAc,IACjDvH,KAAAA;GACJ,MAAM0H,OAAOF,UAAU,CAAC,GAAIV,eAAe,CAAA,GAAK,GAAGU,OAAO,IAAIxH,KAAAA;GAE9DlE,UAAU;IACR,GAAGA;IACH,GAAI6I,EAAEQ,UACF,EAAEA,SAAS,CAAC,GAAGyB,gBAAgB,GAAIjC,EAAEQ,WAAW,CAAA,CAAG,EAAE,IACrDnF,KAAAA;IACJ5B,QAAQuG,EAAEvG,UAAUtC,QAAQsC;IAC5B,GAAIuG,EAAES,WACF,EACEA,UAAU;KACR,GAAGtJ,QAAQsJ;KACX,GAAIT,EAAES,SAASC,mBAAmBrF,KAAAA,IAC9B,EAAEqF,gBAAgBV,EAAES,SAASC,eAAe,IAC5CrF,KAAAA;KACJ,GAAIyH,cACA,EAAElC,sBAAsBkC,YAAY,IACpCzH,KAAAA;KACJ,GAAI0H,OAAO,EAAElC,eAAekC,KAAK,IAAI1H,KAAAA;KACrC,GAAIyF,QAAQ,EAAEA,MAAM,IAAIzF,KAAAA;KACxB,GAAI2E,EAAES,UAAUuC,SACZ,EAAEA,QAAQhD,EAAES,SAASuC,OAAO,IAC5B3H,KAAAA;KACJ,GAAI2E,EAAES,UAAUM,SACZ,EACEA,QAAQ;MACN,GAAIsB,iBAAiB,CAAC;MACtB,GAAGrC,EAAES,SAASM;KAChB,EACF,IACA1F,KAAAA;IACN,EACF,IACAA,KAAAA;GACN;GACA,KAAK6B,WAAWkC,mBAAmB5F,UAAUrC,OAAO;GACpDmL,mBAAmB;GACnB,KAAK9F,mBAAmB;EAC1B;EAEA,MAAMyG,WAAW,KAAKrJ,SAASqJ,YAAY;EAE3C,IAAI;GAEF,KADc9L,QAAQsJ,UAAUK,OAAOnE,UAAU,MACpCsG,UAAU;IACrBR,cAAc,EACZhJ,QAAQ;KACNC,MAAM;KACNyF,QAAQ;IACV,EACF,CAAC;IACD,OAAOhI;GACT;GAEAsL,cAAc,EACZhJ,QAAQ,EACNC,MAAM,UACR,EACF,CAAC;GAGD,KAAKwD,WAAW0C,UAAUzI,QAAQ4B,EAAE;GACpC,KAAKyD,mBAAmB;GAExB,KAAKtC,iBAAiBD,aAAa,CAAC;GAGpC,MAAM,EAAEiJ,2BAA2BC,GAAG,GAAGC,YACvC,KAAKC,gBAAgB;GAEvB9C,cACEA,eACA,KAAK1G,SAASyJ,UAAUtH,IAAIjC,KAAK,KAAKF,SAASyJ,SAAS;GAE1D,MAAMC,cAAcnL,gBAAgBwJ;GACpC,MAAM4B,4BACJD,YAAYE,YACXtM,QAAQsC,OAAOC,SAAS,aACtBvC,QAAQsC,OAAOC,SAAS,sBACtB,KAAKlB,eAAewD,OACnB3G,eAAe8B,SAAS,KAAKyC,SAAS6H,uBAAuB;GACrE,MAAMiC,WAAW,KAAK5I,eAAe;GACrC,MAAM+G,qBAAqBtB,YAAY;IACrCpE;IACAlC,WAAW,KAAKC;IAChBqJ;IACAH;IACAO,6BAA6BxM,QAAQ4B;IACrC6K,mBAAmBF;IACnBG,mBAAmBrK;IACnBsK,sBAAsB;KACpB,OAAO3M;IACT;GACF,CAAC;GAGD,IAAI4M,OAAOC,iBAAiBnC,oBAC1B,WAAW,MAAMG,KAAKH,oBAAoB;IACxC,IAAI0B,YAAYE,SAAS;KACvB,IAAID,oBAAoB,GACtBf,cAAc,EACZhJ,QAAQ;MAAEC,MAAM;MAAcyF,QAAQ;KAAY,EACpD,CAAC;KAEH;IACF;IAEAsD,cAAcT,CAAC;GACjB;QAEAS,cAAc,MAAMZ,kBAAkB;GAGxC,IAAI2B,oBAAoB,GACtBf,cAAc,EACZhJ,QAAQ;IAAEC,MAAM;IAAcyF,QAAQ;GAAY,EACpD,CAAC;QACI,IAAIhI,QAAQsC,OAAOC,SAAS,WACjC+I,cAAc,EACZhJ,QAAQ;IAAEC,MAAM;IAAYyF,QAAQ;GAAU,EAChD,CAAC;EAEL,SAAS8E,GAAG;GACV,IAAIA,aAAanN,YACf2L,cAAc,EACZhJ,QAAQ;IAAEC,MAAM;IAAcyF,QAAQ;GAAY,EACpD,CAAC;QACI,IAAI8E,aAAalN,SAASkN,EAAEjN,SAAS,cAC1CyL,cAAc,EACZhJ,QAAQ;IAAEC,MAAM;IAAcyF,QAAQ;GAAY,EACpD,CAAC;QACI;IACLsD,cAAc,EACZhJ,QAAQ;KACNC,MAAM;KACNyF,QAAQ;KACRtC,OAAOzG,iBAAiB6N,CAAC;IAC3B,EACF,CAAC;IAED,MAAMA;GACR;EACF,UAAU;GACR,IAAI,KAAK7L,oBAAoBA,iBAC3B,KAAKA,kBAAkB;GAGzB,MAAMuB,UAAU,KAAKC,SAASC,SAASF;GACvC,MAAMK,OAAO;IACXR;IACArC;IACA8C,WAAW,KAAKC;GAClB;GACA,MAAMgK,aACJ/M,QAAQsC,OAAOC,SAAS,cACxBvC,QAAQsC,OAAOC,SAAS;GAC1B,MAAMyK,YACJhN,QAAQsC,OAAOC,SAAS,qBACxB,CAACrE,eAAe8B,SAAS,KAAKyC,SAAS6H,uBAAuB;GAIhE,IAAIe,YAAY,MAAM0B,cAAeC,aAAaxK,SAASG,SAAU;IACnE,MAAMd,QACJoI,oBAAoBzH,SAASG,SACzBH,QAAQG,OAAOC,KAAKJ,OAAO,IAC3BA,SAAS+D,OAAO3D,KAAKJ,OAAO;IAClC,IAAIX,OACF,MAAM,KAAKF,mBAAmB3B,QAAQ4B,UAAUC,MAAMgB,IAAI,CAAC;GAE/D;EACF;EACA,OAAO7C;CACT;CAEA,SAAgB;EACdP,wBAAwB,IAAI;EAE5B,KAAK0B,SAAS;EACd,MAAMuE,QAAQ,IAAI/F,WAAW,IAAI;EACjC,KAAKsB,iBAAiBmJ,MAAM1E,KAAK;EACjC,KAAKzE,kBAAkB;EACvB,KAAKqC,wBAAwB8G,MAAM;EACnC,KAAK9G,yBAAyB;CAChC;CAEA,YAAmB;EACjB,IAAI,KAAKnC,QAAQ;GACf,IAAI,KAAKsB,SAASyK,+BAA+B,MAC/C,KAAK/L,OAAO4F,MAAM;QACb;IACL,KAAK5F,OAAOgM,gBAAgB;IAC5B,IAAI,KAAK9L,YAAY,KAAKA,WAAWC,YAAY;GACnD;EACF;EACA,MAAMoE,QAAQ,IAAI/F,WAAW,KAAK;EAClC,KAAKsB,iBAAiBmJ,MAAM1E,KAAK;EACjC,KAAKzE,kBAAkB;EACvB,KAAKqC,wBAAwB8G,MAAM;EACnC,KAAK9G,yBAAyB;CAChC;CAEA,cAAqB,EACnBqE,WACA0F,YACAC,QACAC,SACAC,YACuB;EACvB,MAAMC,cAAc,KAAK1H,WAAWqF,WAAWzD,SAAS;EACxD,MAAM,EAAEtF,aAAaoL;EACrB,IAAI,EAAEzN,YAAYyN;EAElB,IAAIzN,QAAQ0G,SAAS,aACnB,MAAM,IAAI9G,MAAM,mDAAmD;EAErE,IAAI8N,QAAQ;EACZ,IAAIC,QAAQ;EACZ,MAAMC,aAAa5N,QAAQqJ,QAAQwE,KAAKC,MAAM;GAC5C,IAAIA,EAAEvL,SAAS,aAAa,OAAOuL;GACnC,IAAIA,EAAET,eAAeA,YAAY,OAAOS;GACxCH,QAAQ;GACR,IAAIG,EAAER,WAAWpJ,KAAAA,GAAWwJ,QAAQ;GACpC,OAAO;IACL,GAAGI;IACHR;IACAE;IACAD;GACF;EACF,CAAC;EAED,IAAI,CAACI,OACH,MAAM,IAAI/N,MAAM,oDAAoD;EAEtEI,UAAU;GACR,GAAGA;GACHqJ,SAASuE;EACX;EACA,KAAK7H,WAAWkC,mBAAmB5F,UAAUrC,OAAO;EACpD,KAAKqF,mBAAmB;EAIxB,IACEqI,SACAxP,eAAe8B,SAAS,KAAKyC,SAAS6H,uBAAuB,GAE7D,KAAKP,SAAS1H,UAAUrC,SAAS,KAAK+C,cAAc,CAAC,CAACC,YAAY,CAAC,CAAC;OAC/D,IAAI0K,OACT,KAAKtL,sBAAsBC,UAAUrC,OAAO;CAEhD;CAEA,eAAsByC,UAAiC;EACrD,MAAM,IAAI7C,MACR,qKACF;CACF;CAEA,sBAA6B,EAC3BqO,YACAC,UACAC,UACAnG,UAC+B;EAC/B,IAAIhI,UAAU,KAAK+F,WAChB2C,YAAY,CAAC,CACb0F,UACEvF,MACCA,EAAEnC,SAAS,eACXmC,EAAEQ,QAAQgF,MACPP,MAAMA,EAAEvL,SAAS,eAAeuL,EAAEQ,UAAU1M,OAAOqM,UACtD,CACJ;EAEF,IAAI,CAACjO,SACH,MAAM,IAAIJ,MAAM,kDAAkD;EAEpE,IAAI,KAAKqB,oBAAoB,MAC3B,MAAM,IAAIrB,MACR,gEACF;EAEF,IAAII,QAAQsC,QAAQC,SAAS,mBAC3B,MAAM,IAAI3C,MACR,sFACF;EAEF,MAAM2O,SAASvO,QAAQqJ,QAAQmF,MAC5BV,MAAMA,EAAEvL,SAAS,eAAeuL,EAAEQ,UAAU1M,OAAOqM,UACtD;EACA,IAAIM,QAAQhM,SAAS,eAAe,CAACgM,OAAOD,UAC1C,MAAM,IAAI1O,MAAM,kDAAkD;EACpE,IAAI2O,OAAOD,SAASG,eAAevK,KAAAA,GACjC,MAAM,IAAItE,MACR,mEACF;EACF,IAAI2O,OAAOD,SAASJ,aAAahK,KAAAA,GAC/B,MAAM,IAAItE,MAAM,sDAAsD;EAExE,MAAM8O,iBAAiBH,OAAOD;EAC9B,MAAMV,aAAa5N,QAAQqJ,QAAQwE,KAAKC,MAAM;GAC5C,IAAIA,MAAMS,QAAQ,OAAOT;GACzB,MAAMQ,WAAW;IACf,GAAGI;IACHR;IACA,GAAIC,YAAY,QAAQ,EAAEA,SAAS;IACnC,GAAInG,UAAU,QAAQ,EAAEA,OAAO;GACjC;GACA,IAAIkG,UAAU,OAAO;IAAE,GAAGJ;IAAGQ;GAAS;GACtC,OAAO;IACL,GAAGR;IACHQ;IACAhB,QAAQ,EAAE5H,OAAOsC,UAAU,uBAAuB;IAClDuF,SAAS;GACX;EACF,CAAC;EAEDvN,UAAU;GAAE,GAAGA;GAASqJ,SAASuE;EAAW;EAC5C,MAAM,EAAEvL,aAAa,KAAK0D,WAAWqF,WAAWpL,QAAQ4B,EAAE;EAC1D,KAAKmE,WAAWkC,mBAAmB5F,UAAUrC,OAAO;EACpD,KAAKqF,mBAAmB;EAExB,IACE,KAAKU,WAAWM,WAAWrG,QAAQ4B,MACnC1D,eAAe8B,SAAS,KAAKyC,SAAS6H,uBAAuB,GAE7D,KAAKP,SAAS1H,UAAUrC,SAAS,KAAK+C,cAAc,CAAC,CAACC,YAAY,CAAC,CAAC;OAEpE,KAAKZ,sBAAsBC,UAAUrC,OAAO;CAEhD;AACF"}
1
+ {"version":3,"file":"local-thread-runtime-core.js","names":["fromThreadMessageLike","generateId","ChatModelAdapter","ChatModelRunResult","shouldContinue","getAutoStatus","ExportedMessageRepository","LocalRuntimeOptionsBase","consumeSuggestionResult","AddToolResultOptions","ResumeToolCallOptions","RespondToToolApprovalOptions","ThreadSuggestion","ThreadRuntimeCore","StartRunConfig","ResumeRunConfig","BaseThreadRuntimeCore","AppendMessage","ThreadAssistantMessage","RunConfig","ThreadMessage","MessageNotSentError","toAssistantError","ModelContextProvider","createMessageQueue","MessageQueueController","QueuePlacement","EMPTY_QUEUE_ITEMS","QueueItemState","captureThreadRuntimeGeneration","invalidateThreadRuntime","isThreadRuntimeGenerationCurrent","AbortError","Error","name","detach","constructor","message","withLocalPauseReason","role","status","type","reason","content","some","c","result","undefined","interrupt","withLocalPauseReasons","data","messages","map","item","LocalThreadRuntimeCore","capabilities","switchToBranch","switchBranchDuringRun","edit","delete","reload","refetchThread","cancel","unstable_copy","speech","dictation","voice","attachments","feedback","queue","abortController","AbortController","_queue","_queueRunInFlight","_activeRun","cancelled","_runGeneration","_historyWrites","Map","Promise","_chainHistoryWrite","id","write","next","get","resolve","then","stored","set","_persistPausedMessage","parentId","history","_options","adapters","update","bind","runConfig","_lastRunConfig","catch","isDisabled","isSendDisabled","_isLoading","isLoading","_suggestions","_suggestionsController","suggestions","contextProvider","options","__internal_setOptions","_getThreadId","__internal_setGetThreadId","getThreadId","_getInitializePromise","__internal_setGetInitializePromise","getPromise","extras","previousHistory","hasUpdates","canSpeak","canDictate","canVoice","canAttach","canFeedback","canDelete","canQueue","unstable_enableMessageQueue","run","generation","_runAppend","at","finally","notifyIdle","subscribe","_notifySubscribers","_loadRequested","_loadPromise","length","__internal_load","error","console","promise","load","repo","repository","import","ensureInitialized","resume","unstable_resume","startRun","headId","sourceId","append","isTail","willRun","steer","adapter","enqueue","unstable_queueClearOnRewind","clear","getQueueItems","items","getSteerQueueItems","steerItems","moveQueueItem","queueItemId","placement","move","removeQueueItem","remove","_rollbackAppend","messageId","deleteMessage","rawMessage","enrichAppendMetadata","newMessage","addOrUpdateMessage","initPromise","notSent","cause","historyWrite","runResult","historyResult","allSettled","resetHead","getMessages","messageIndex","findIndex","m","resumeRun","stream","startConfig","exportExternalState","importExternalState","unstable_notifySessionReset","runCallback","metadata","unstable_state","state","unstable_annotations","unstable_data","steps","custom","createdAt","Date","_runLoop","_notifyEventSubscribers","alreadyPersisted","active","notifyBusy","abort","performRoundtrip","unstable_humanToolNames","queueMicrotask","suggestion","signal","promiseOrGenerator","generate","onUpdate","r","initialContent","initialAnnotations","initialData","initialSteps","initialCustom","hasStoredMessage","getMessage","ownsMessage","updateMessage","Partial","newSteps","newAnnotations","newData","annotations","timing","maxSteps","unstable_composerMetadata","_","context","getModelContext","chatModel","abortSignal","shouldCancelMessage","aborted","threadId","unstable_assistantMessageId","unstable_threadId","unstable_parentId","unstable_getMessage","Symbol","asyncIterator","e","isTerminal","isPausing","cancelRun","unstable_queueClearOnCancel","notifyCancelled","addToolResult","toolCallId","isError","artifact","messageData","added","found","newContent","resumeToolCall","respondToToolApproval","approvalId","approved","optionId","findLast","approval","target","find","resolution","targetApproval"],"sources":["../../../src/runtimes/local/local-thread-runtime-core.ts"],"sourcesContent":["import { fromThreadMessageLike } from \"../../runtime/utils/thread-message-like\";\nimport { generateId } from \"../../utils/id\";\nimport type {\n ChatModelAdapter,\n ChatModelRunResult,\n} from \"../../runtime/utils/chat-model-adapter\";\nimport { shouldContinue } from \"./should-continue\";\nimport { getAutoStatus } from \"../../runtime/utils/auto-status\";\nimport type { ExportedMessageRepository } from \"../../runtime/utils/message-repository\";\nimport type { LocalRuntimeOptionsBase } from \"./local-runtime-options\";\nimport { consumeSuggestionResult } from \"../../adapters/suggestion\";\nimport type {\n AddToolResultOptions,\n ResumeToolCallOptions,\n RespondToToolApprovalOptions,\n ThreadSuggestion,\n ThreadRuntimeCore,\n StartRunConfig,\n ResumeRunConfig,\n} from \"../../runtime/interfaces/thread-runtime-core\";\nimport { BaseThreadRuntimeCore } from \"../../runtime/base/base-thread-runtime-core\";\nimport type {\n AppendMessage,\n ThreadAssistantMessage,\n} from \"../../types/message\";\nimport type { RunConfig, ThreadMessage } from \"../../types/message\";\nimport { MessageNotSentError, toAssistantError } from \"../../types/error\";\nimport type { ModelContextProvider } from \"../../model-context/types\";\nimport {\n createMessageQueue,\n type MessageQueueController,\n} from \"../../runtime/queue/message-queue\";\nimport type { QueuePlacement } from \"../../runtime/queue/external-thread-queue-adapter\";\nimport {\n EMPTY_QUEUE_ITEMS,\n type QueueItemState,\n} from \"../../runtime/queue/queue-item\";\nimport {\n captureThreadRuntimeGeneration,\n invalidateThreadRuntime,\n isThreadRuntimeGenerationCurrent,\n} from \"../../runtime/utils/thread-runtime-lifecycle\";\n\nclass AbortError extends Error {\n override name = \"AbortError\";\n detach: boolean;\n\n constructor(detach: boolean, message?: string) {\n super(message);\n this.detach = detach;\n }\n}\n\n// `shouldContinue` resumes only on `tool-calls` and `resumeToolCall` throws, so\n// an imported `interrupt` with no interrupt payload would be stranded here.\n// Provenance cannot gate it: a repository that went through JSON has no marker.\n// The replacement stays content-derived, so a message with nothing resultless\n// left to act on lands on `complete` rather than an unactionable pause.\nconst withLocalPauseReason = (message: ThreadMessage): ThreadMessage => {\n if (\n message.role !== \"assistant\" ||\n message.status.type !== \"requires-action\" ||\n message.status.reason !== \"interrupt\" ||\n message.content.some(\n (c) =>\n c.type === \"tool-call\" && c.result === undefined && c.interrupt != null,\n )\n )\n return message;\n return {\n ...message,\n status: getAutoStatus(\n false,\n false,\n false,\n message.content.some(\n (c) => c.type === \"tool-call\" && c.result === undefined,\n ),\n ),\n };\n};\n\nconst withLocalPauseReasons = (\n data: ExportedMessageRepository,\n): ExportedMessageRepository => ({\n ...data,\n messages: data.messages.map((item) => ({\n ...item,\n message: withLocalPauseReason(item.message),\n })),\n});\n\nexport class LocalThreadRuntimeCore\n extends BaseThreadRuntimeCore\n implements ThreadRuntimeCore\n{\n public readonly capabilities = {\n switchToBranch: true,\n switchBranchDuringRun: true,\n edit: true,\n delete: false,\n reload: true,\n refetchThread: false,\n cancel: true,\n unstable_copy: true,\n speech: false,\n dictation: false,\n voice: false,\n attachments: false,\n feedback: false,\n queue: false,\n };\n\n private abortController: AbortController | null = null;\n\n private _queue: MessageQueueController | null = null;\n private _queueRunInFlight = false;\n private _activeRun: { cancelled: boolean } | null = null;\n private _runGeneration = 0;\n\n private _historyWrites = new Map<string, Promise<void>>();\n\n // Writes for one message id must land in issue order; an earlier paused\n // snapshot arriving after the terminal write would resurrect the pause.\n private _chainHistoryWrite(\n id: string,\n write: () => Promise<void>,\n ): Promise<void> {\n const next = (this._historyWrites.get(id) ?? Promise.resolve()).then(\n write,\n write,\n );\n const stored = next.then(\n () => {},\n () => {},\n );\n this._historyWrites.set(id, stored);\n void stored.then(() => {\n if (this._historyWrites.get(id) === stored) {\n this._historyWrites.delete(id);\n }\n });\n return next;\n }\n\n // A decision recorded on a still-paused message must reach history before\n // the run resumes, or a refresh would restore the message without it.\n private _persistPausedMessage(\n parentId: string | null,\n message: ThreadAssistantMessage,\n ) {\n if (message.status?.type !== \"requires-action\") return;\n const history = this._options.adapters.history;\n if (!history?.update) return;\n const update = history.update.bind(history);\n const item = { parentId, message, runConfig: this._lastRunConfig };\n this._chainHistoryWrite(message.id, () => update(item)).catch(() => {});\n }\n\n public readonly isDisabled = false;\n public readonly isSendDisabled = false;\n\n private _isLoading = false;\n public get isLoading() {\n return this._isLoading;\n }\n\n private _suggestions: readonly ThreadSuggestion[] = [];\n private _suggestionsController: AbortController | null = null;\n public get suggestions(): readonly ThreadSuggestion[] {\n return this._suggestions;\n }\n\n public get adapters() {\n return this._options.adapters;\n }\n\n constructor(\n contextProvider: ModelContextProvider,\n options: LocalRuntimeOptionsBase,\n ) {\n super(contextProvider);\n this.__internal_setOptions(options);\n }\n\n private _options!: LocalRuntimeOptionsBase;\n\n private _lastRunConfig: RunConfig = {};\n\n private _getThreadId?: () => string | undefined;\n\n public __internal_setGetThreadId(getThreadId: () => string | undefined) {\n this._getThreadId = getThreadId;\n }\n\n private _getInitializePromise?: () => Promise<unknown> | undefined;\n\n public __internal_setGetInitializePromise(\n getPromise: () => Promise<unknown> | undefined,\n ) {\n this._getInitializePromise = getPromise;\n }\n\n public get extras() {\n return undefined;\n }\n\n public __internal_setOptions(options: LocalRuntimeOptionsBase) {\n if (this._options === options) return;\n\n const previousHistory = this._options?.adapters.history;\n this._options = options;\n\n let hasUpdates = false;\n\n const canSpeak = options.adapters?.speech !== undefined;\n if (this.capabilities.speech !== canSpeak) {\n this.capabilities.speech = canSpeak;\n hasUpdates = true;\n }\n\n const canDictate = options.adapters?.dictation !== undefined;\n if (this.capabilities.dictation !== canDictate) {\n this.capabilities.dictation = canDictate;\n hasUpdates = true;\n }\n\n const canVoice = options.adapters?.voice !== undefined;\n if (this.capabilities.voice !== canVoice) {\n this.capabilities.voice = canVoice;\n hasUpdates = true;\n }\n\n const canAttach = options.adapters?.attachments !== undefined;\n if (this.capabilities.attachments !== canAttach) {\n this.capabilities.attachments = canAttach;\n hasUpdates = true;\n }\n\n const canFeedback = options.adapters?.feedback !== undefined;\n if (this.capabilities.feedback !== canFeedback) {\n this.capabilities.feedback = canFeedback;\n hasUpdates = true;\n }\n\n const canDelete = options.adapters?.history?.delete !== undefined;\n if (this.capabilities.delete !== canDelete) {\n this.capabilities.delete = canDelete;\n hasUpdates = true;\n }\n\n const canQueue = options.unstable_enableMessageQueue === true;\n if (canQueue && !this._queue) {\n this._queue = createMessageQueue({\n run: (message) => {\n // release the queue when the dispatch settles, even if it rejects\n // before reaching startRun's finally, so a failure can't deadlock it\n this._queueRunInFlight = true;\n const generation = this._runGeneration;\n // the tail may have moved since the message was enqueued\n void this._runAppend({\n ...message,\n parentId: this.messages.at(-1)?.id ?? null,\n })\n .finally(() => {\n this._queueRunInFlight = false;\n // a dispatch that failed before starting a run settles here;\n // runs that did start release from _runLoop\n if (this._runGeneration === generation) this._queue?.notifyIdle();\n })\n .catch(() => {});\n },\n });\n this._queue.subscribe(() => this._notifySubscribers());\n } else if (!canQueue && this._queue) {\n this._queue = null;\n }\n if (this.capabilities.queue !== canQueue) {\n this.capabilities.queue = canQueue;\n hasUpdates = true;\n }\n\n if (hasUpdates) this._notifySubscribers();\n\n if (\n this._loadRequested &&\n !this._loadPromise &&\n !previousHistory &&\n options.adapters.history &&\n this.messages.length === 0\n ) {\n void this.__internal_load().catch((error: unknown) => {\n console.error(\n \"[assistant-ui] local thread history load failed:\",\n error,\n );\n });\n }\n }\n\n private _loadPromise: Promise<void> | undefined;\n private _loadRequested = false;\n public __internal_load() {\n this._loadRequested = true;\n if (this._loadPromise) return this._loadPromise;\n if (!this.adapters.history) return Promise.resolve();\n\n const promise = this.adapters.history.load();\n\n this._isLoading = true;\n this._notifySubscribers();\n\n this._loadPromise = promise\n .then((repo) => {\n if (!repo) return;\n this.repository.import(withLocalPauseReasons(repo));\n if (repo.messages.length > 0) {\n this.ensureInitialized();\n }\n this._notifySubscribers();\n\n const resume = this.adapters.history?.resume?.bind(\n this.adapters.history,\n );\n if (repo.unstable_resume && resume) {\n this.startRun(\n {\n parentId: this.repository.headId,\n sourceId: this.repository.headId,\n runConfig: this._lastRunConfig,\n },\n resume,\n ).catch(() => {});\n }\n })\n .finally(() => {\n this._isLoading = false;\n this._notifySubscribers();\n });\n\n return this._loadPromise;\n }\n\n public async append(message: AppendMessage): Promise<void> {\n const isTail = message.parentId === (this.messages.at(-1)?.id ?? null);\n const willRun = message.startRun ?? message.role === \"user\";\n if (this._queue && willRun && isTail) {\n if (message.steer ?? this._queueRunInFlight)\n this._queue.adapter.steer(message);\n else this._queue.adapter.enqueue(message);\n return;\n }\n if (\n this._queue &&\n !isTail &&\n (this._options.unstable_queueClearOnRewind ?? true)\n )\n this._queue.clear();\n return this._runAppend(message);\n }\n\n public getQueueItems(): readonly QueueItemState[] {\n // Reads can arrive during base-thread construction, before the queue field\n // is assigned, so guard against the unset field.\n return this._queue?.adapter.items ?? EMPTY_QUEUE_ITEMS;\n }\n\n public getSteerQueueItems(): readonly QueueItemState[] {\n return this._queue?.adapter.steerItems ?? EMPTY_QUEUE_ITEMS;\n }\n\n public moveQueueItem(queueItemId: string, placement: QueuePlacement): void {\n this._queue?.adapter.move(queueItemId, placement);\n }\n\n public removeQueueItem(queueItemId: string): void {\n this._queue?.adapter.remove(queueItemId);\n }\n\n private _rollbackAppend(messageId: string) {\n try {\n this.repository.deleteMessage(messageId);\n } catch {\n return;\n }\n this._notifySubscribers();\n }\n\n private async _runAppend(rawMessage: AppendMessage): Promise<void> {\n // Stamped here rather than in `append` so a queued message is gated after\n // the flush re-pointed its parentId at the current tail.\n const generation = captureThreadRuntimeGeneration(this);\n const message = this.enrichAppendMetadata(rawMessage);\n this.ensureInitialized();\n\n const newMessage = fromThreadMessageLike(message, generateId(), {\n type: \"complete\",\n reason: \"unknown\",\n });\n this.repository.addOrUpdateMessage(message.parentId, newMessage);\n this._notifySubscribers();\n\n // Initialization only gates the history write and the run; the message\n // is already on screen. A failed barrier rolls the optimistic message\n // back and rejects as an unsent message so the composer restores the\n // draft; a thread invalidated mid-wait rolls back silently.\n try {\n const initPromise = this._getInitializePromise?.();\n if (initPromise) {\n await initPromise;\n }\n } catch (error) {\n this._rollbackAppend(newMessage.id);\n if (!isThreadRuntimeGenerationCurrent(this, generation)) return;\n const notSent = new MessageNotSentError();\n notSent.cause = error;\n throw notSent;\n }\n if (!isThreadRuntimeGenerationCurrent(this, generation)) {\n this._rollbackAppend(newMessage.id);\n return;\n }\n const historyWrite = this._options.adapters.history?.append({\n parentId: message.parentId,\n message: newMessage,\n ...(message.runConfig !== undefined && { runConfig: message.runConfig }),\n });\n void historyWrite?.catch(() => {});\n\n const startRun = message.startRun ?? message.role === \"user\";\n if (startRun) {\n const [runResult, historyResult] = await Promise.allSettled([\n this.startRun({\n parentId: newMessage.id,\n sourceId: message.sourceId,\n runConfig: message.runConfig ?? {},\n }),\n historyWrite,\n ]);\n if (runResult.status === \"rejected\") throw runResult.reason;\n if (historyResult.status === \"rejected\") throw historyResult.reason;\n } else {\n this.repository.resetHead(newMessage.id);\n this._notifySubscribers();\n await historyWrite;\n }\n }\n\n public async deleteMessage(messageId: string): Promise<void> {\n const adapter = this._options.adapters.history;\n if (!adapter?.delete)\n throw new Error(\"Runtime does not support deleting messages.\");\n\n const messages = this.repository.getMessages();\n const messageIndex = messages.findIndex((m) => m.id === messageId);\n if (messageIndex === -1) throw new Error(\"Message not found.\");\n\n const message = messages[messageIndex]!;\n const parentId = messages[messageIndex - 1]?.id ?? null;\n const items = [{ parentId, message }];\n\n await adapter.delete(items);\n\n this.repository.deleteMessage(messageId);\n this._notifySubscribers();\n }\n\n public resumeRun({ stream, ...startConfig }: ResumeRunConfig): Promise<void> {\n if (!stream)\n throw new Error(\"You must pass a stream parameter to resume runs.\");\n return this.startRun(startConfig, stream);\n }\n\n public exportExternalState(): any {\n throw new Error(\"Runtime does not support exporting external states.\");\n }\n\n public override import(data: ExportedMessageRepository) {\n super.import(withLocalPauseReasons(data));\n }\n\n public importExternalState(): void {\n throw new Error(\"Runtime does not support importing external states.\");\n }\n\n public unstable_notifySessionReset(): void {\n throw new Error(\"Runtime does not support resetting sessions.\");\n }\n\n public async startRun(\n { parentId, runConfig }: StartRunConfig,\n runCallback?: ChatModelAdapter[\"run\"],\n ): Promise<void> {\n this.ensureInitialized();\n\n // add assistant message\n const id = generateId();\n const message: ThreadAssistantMessage = {\n id,\n role: \"assistant\",\n status: { type: \"running\" },\n content: [],\n metadata: {\n unstable_state: this.state,\n unstable_annotations: [],\n unstable_data: [],\n steps: [],\n custom: {},\n },\n createdAt: new Date(),\n };\n\n return this._runLoop(parentId, message, runConfig, runCallback);\n }\n\n private async _runLoop(\n parentId: string | null,\n message: ThreadAssistantMessage,\n runConfig: RunConfig | undefined,\n runCallback?: ChatModelAdapter[\"run\"],\n ): Promise<void> {\n this._notifyEventSubscribers(\"runStart\", {});\n\n // A run entered on a requires-action message resumes a pause an\n // update-capable adapter already holds (written at pause time or loaded).\n const alreadyPersisted =\n message.status?.type === \"requires-action\" &&\n this._options.adapters.history?.update !== undefined;\n\n const run = { cancelled: false };\n this._activeRun = run;\n this._runGeneration++;\n\n let active = false;\n try {\n // mark busy for runs not started through the queue (regenerate, resume)\n this._queue?.notifyBusy();\n this._suggestions = [];\n this._suggestionsController?.abort();\n this._suggestionsController = null;\n this._notifySubscribers();\n\n do {\n message = await this.performRoundtrip(\n parentId,\n message,\n runConfig,\n alreadyPersisted,\n run,\n runCallback,\n );\n runCallback = undefined;\n if (this._activeRun !== run) break;\n } while (shouldContinue(message, this._options.unstable_humanToolNames));\n } finally {\n this._notifyEventSubscribers(\"runEnd\", {});\n // the settle belongs to this run only while it is still the active run\n // or was cancelled (the engine expects a cancelled run's settle); a run\n // superseded by a newer one stays silent\n active = this._activeRun === run;\n if (active) this._activeRun = null;\n if (active || run.cancelled) {\n queueMicrotask(() => this._queue?.notifyIdle());\n }\n }\n\n if (\n active &&\n this.adapters.suggestion &&\n message.status?.type !== \"requires-action\"\n ) {\n this._suggestionsController = new AbortController();\n const signal = this._suggestionsController.signal;\n const adapter = this.adapters.suggestion;\n void (async () => {\n try {\n const promiseOrGenerator = adapter.generate({\n messages: this.messages,\n signal,\n });\n await consumeSuggestionResult(promiseOrGenerator, {\n signal,\n onUpdate: (r) => {\n this._suggestions = r;\n this._notifySubscribers();\n },\n });\n } catch {}\n })();\n }\n }\n\n private async performRoundtrip(\n parentId: string | null,\n message: ThreadAssistantMessage,\n runConfig: RunConfig | undefined,\n alreadyPersisted: boolean,\n run: { cancelled: boolean },\n runCallback?: ChatModelAdapter[\"run\"],\n ) {\n const messages = parentId ? this.repository.getMessages(parentId) : [];\n\n // abort existing run\n this.abortController?.abort();\n const abortController = new AbortController();\n this.abortController = abortController;\n\n const initialContent = message.content;\n const initialAnnotations = message.metadata?.unstable_annotations;\n const initialData = message.metadata?.unstable_data;\n const initialSteps = message.metadata?.steps;\n const initialCustom = message.metadata?.custom;\n let hasStoredMessage = true;\n try {\n this.repository.getMessage(message.id);\n } catch {\n hasStoredMessage = false;\n }\n // Other writers replace the stored message object, so identity distinguishes this run from a newer owner.\n const ownsMessage = () => {\n if (!hasStoredMessage) return this._activeRun === run;\n try {\n return this.repository.getMessage(message.id).message === message;\n } catch {\n return false;\n }\n };\n const updateMessage = (m: Partial<ChatModelRunResult>) => {\n if (!ownsMessage()) return;\n const newSteps = m.metadata?.steps;\n const steps = newSteps\n ? [...(initialSteps ?? []), ...newSteps]\n : undefined;\n\n const newAnnotations = m.metadata?.unstable_annotations;\n const newData = m.metadata?.unstable_data;\n const annotations = newAnnotations\n ? [...(initialAnnotations ?? []), ...newAnnotations]\n : undefined;\n const data = newData ? [...(initialData ?? []), ...newData] : undefined;\n\n message = {\n ...message,\n ...(m.content\n ? { content: [...initialContent, ...(m.content ?? [])] }\n : undefined),\n status: m.status ?? message.status,\n ...(m.metadata\n ? {\n metadata: {\n ...message.metadata,\n ...(m.metadata.unstable_state !== undefined\n ? { unstable_state: m.metadata.unstable_state }\n : undefined),\n ...(annotations\n ? { unstable_annotations: annotations }\n : undefined),\n ...(data ? { unstable_data: data } : undefined),\n ...(steps ? { steps } : undefined),\n ...(m.metadata?.timing\n ? { timing: m.metadata.timing }\n : undefined),\n ...(m.metadata?.custom\n ? {\n custom: {\n ...(initialCustom ?? {}),\n ...m.metadata.custom,\n },\n }\n : undefined),\n },\n }\n : undefined),\n };\n this.repository.addOrUpdateMessage(parentId, message);\n hasStoredMessage = true;\n this._notifySubscribers();\n };\n\n const maxSteps = this._options.maxSteps ?? 2;\n\n try {\n const steps = message.metadata?.steps?.length ?? 0;\n if (steps >= maxSteps) {\n updateMessage({\n status: {\n type: \"incomplete\",\n reason: \"tool-calls\",\n },\n });\n return message;\n }\n\n updateMessage({\n status: {\n type: \"running\",\n },\n });\n\n // Switch to the new message branch right after adding it for the first time\n this.repository.resetHead(message.id);\n this._notifySubscribers();\n\n this._lastRunConfig = runConfig ?? {};\n // unstable_composerMetadata is composer-only (stamped onto the outgoing\n // message); never expose it to the chat-model adapter's run context.\n const { unstable_composerMetadata: _, ...context } =\n this.getModelContext();\n\n runCallback =\n runCallback ??\n this.adapters.chatModel.run.bind(this.adapters.chatModel);\n\n const abortSignal = abortController.signal;\n const shouldCancelMessage = () =>\n abortSignal.aborted &&\n (message.status.type === \"running\" ||\n (message.status.type === \"requires-action\" &&\n (this._activeRun !== run ||\n shouldContinue(message, this._options.unstable_humanToolNames))));\n const threadId = this._getThreadId?.();\n const promiseOrGenerator = runCallback({\n messages,\n runConfig: this._lastRunConfig,\n abortSignal,\n context,\n unstable_assistantMessageId: message.id,\n unstable_threadId: threadId,\n unstable_parentId: parentId,\n unstable_getMessage() {\n return message;\n },\n });\n\n // handle async iterator for streaming results\n if (Symbol.asyncIterator in promiseOrGenerator) {\n for await (const r of promiseOrGenerator) {\n if (abortSignal.aborted) {\n if (shouldCancelMessage()) {\n updateMessage({\n status: { type: \"incomplete\", reason: \"cancelled\" },\n });\n }\n break;\n }\n\n updateMessage(r);\n }\n } else {\n updateMessage(await promiseOrGenerator);\n }\n\n if (shouldCancelMessage()) {\n updateMessage({\n status: { type: \"incomplete\", reason: \"cancelled\" },\n });\n } else if (message.status.type === \"running\") {\n updateMessage({\n status: { type: \"complete\", reason: \"unknown\" },\n });\n }\n } catch (e) {\n if (e instanceof AbortError) {\n updateMessage({\n status: { type: \"incomplete\", reason: \"cancelled\" },\n });\n } else if (e instanceof Error && e.name === \"AbortError\") {\n updateMessage({\n status: { type: \"incomplete\", reason: \"cancelled\" },\n });\n } else {\n updateMessage({\n status: {\n type: \"incomplete\",\n reason: \"error\",\n error: toAssistantError(e),\n },\n });\n\n throw e;\n }\n } finally {\n if (this.abortController === abortController) {\n this.abortController = null;\n }\n\n const history = this._options.adapters.history;\n const item = {\n parentId,\n message,\n runConfig: this._lastRunConfig,\n };\n const isTerminal =\n message.status.type === \"complete\" ||\n message.status.type === \"incomplete\";\n const isPausing =\n message.status.type === \"requires-action\" &&\n !shouldContinue(message, this._options.unstable_humanToolNames);\n\n // Pauses are written only for adapters that can rewrite the entry later;\n // an append-only adapter would strand a half-finished run in history.\n if (ownsMessage() && (isTerminal || (isPausing && history?.update))) {\n const write =\n alreadyPersisted && history?.update\n ? history.update.bind(history)\n : history?.append.bind(history);\n if (write) {\n await this._chainHistoryWrite(message.id, () => write(item));\n }\n }\n }\n return message;\n }\n\n public detach() {\n invalidateThreadRuntime(this);\n // drop the queue so pending items cannot dispatch on a detached thread\n this._queue = null;\n const error = new AbortError(true);\n this.abortController?.abort(error);\n this.abortController = null;\n this._suggestionsController?.abort();\n this._suggestionsController = null;\n }\n\n public cancelRun() {\n if (this._queue) {\n if (this._options.unstable_queueClearOnCancel ?? true) {\n this._queue.clear();\n } else {\n this._queue.notifyCancelled();\n if (this._activeRun) this._activeRun.cancelled = true;\n }\n }\n const error = new AbortError(false);\n this.abortController?.abort(error);\n this.abortController = null;\n this._suggestionsController?.abort();\n this._suggestionsController = null;\n }\n\n public addToolResult({\n messageId,\n toolCallId,\n result,\n isError,\n artifact,\n }: AddToolResultOptions) {\n const messageData = this.repository.getMessage(messageId);\n const { parentId } = messageData;\n let { message } = messageData;\n\n if (message.role !== \"assistant\")\n throw new Error(\"Tried to add tool result to non-assistant message\");\n\n let added = false;\n let found = false;\n const newContent = message.content.map((c) => {\n if (c.type !== \"tool-call\") return c;\n if (c.toolCallId !== toolCallId) return c;\n found = true;\n if (c.result === undefined) added = true;\n return {\n ...c,\n result,\n artifact,\n isError,\n };\n });\n\n if (!found)\n throw new Error(\"Tried to add tool result to non-existing tool call\");\n\n message = {\n ...message,\n content: newContent,\n };\n this.repository.addOrUpdateMessage(parentId, message);\n this._notifySubscribers();\n\n // a result may arrive mid-run or on a non-head message; the resume\n // intentionally aborts any in-flight run, unlike respondToToolApproval\n if (\n added &&\n shouldContinue(message, this._options.unstable_humanToolNames)\n ) {\n this._runLoop(parentId, message, this._lastRunConfig).catch(() => {});\n } else if (added) {\n this._persistPausedMessage(parentId, message);\n }\n }\n\n public resumeToolCall(_options: ResumeToolCallOptions) {\n throw new Error(\n \"Local runtime does not support resuming tool calls. For human-in-the-loop tools, list the tool in unstable_humanToolNames and complete the call with addToolResult.\",\n );\n }\n\n public respondToToolApproval({\n approvalId,\n approved,\n optionId,\n reason,\n }: RespondToToolApprovalOptions) {\n let message = this.repository\n .getMessages()\n .findLast(\n (m): m is ThreadAssistantMessage =>\n m.role === \"assistant\" &&\n m.content.some(\n (c) => c.type === \"tool-call\" && c.approval?.id === approvalId,\n ),\n );\n\n if (!message)\n throw new Error(\"Tried to respond to a non-existing tool approval\");\n\n if (this.abortController !== null)\n throw new Error(\n \"Tried to respond to a tool approval while a run is in progress\",\n );\n\n if (message.status?.type !== \"requires-action\")\n throw new Error(\n \"Tried to respond to a tool approval on a message whose status is not requires-action\",\n );\n\n const target = message.content.find(\n (c) => c.type === \"tool-call\" && c.approval?.id === approvalId,\n );\n if (target?.type !== \"tool-call\" || !target.approval)\n throw new Error(\"Tried to respond to a non-existing tool approval\");\n if (target.approval.resolution !== undefined)\n throw new Error(\n \"Tried to respond to a tool approval that was cancelled or expired\",\n );\n if (target.approval.approved !== undefined)\n throw new Error(\"Tried to respond to an already decided tool approval\");\n\n const targetApproval = target.approval;\n const newContent = message.content.map((c) => {\n if (c !== target) return c;\n const approval = {\n ...targetApproval,\n approved,\n ...(optionId != null && { optionId }),\n ...(reason != null && { reason }),\n };\n if (approved) return { ...c, approval };\n return {\n ...c,\n approval,\n result: { error: reason || \"Tool approval denied\" },\n isError: true,\n };\n });\n\n message = { ...message, content: newContent };\n const { parentId } = this.repository.getMessage(message.id);\n this.repository.addOrUpdateMessage(parentId, message);\n this._notifySubscribers();\n\n if (\n this.repository.headId === message.id &&\n shouldContinue(message, this._options.unstable_humanToolNames)\n ) {\n this._runLoop(parentId, message, this._lastRunConfig).catch(() => {});\n } else {\n this._persistPausedMessage(parentId, message);\n }\n }\n}\n"],"mappings":"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"}
@@ -7,6 +7,7 @@ type RemoteThreadData = {
7
7
  readonly status: "new";
8
8
  readonly title: undefined;
9
9
  readonly custom: undefined;
10
+ readonly localOrigin?: true;
10
11
  } | {
11
12
  readonly id: string;
12
13
  readonly initializeTask: Promise<RemoteThreadInitializeResponse>;
@@ -15,6 +16,7 @@ type RemoteThreadData = {
15
16
  readonly status: "regular" | "archived";
16
17
  readonly title?: string | undefined;
17
18
  readonly custom: undefined;
19
+ readonly localOrigin?: true;
18
20
  } | {
19
21
  readonly id: string;
20
22
  readonly initializeTask: Promise<RemoteThreadInitializeResponse>;
@@ -24,11 +26,13 @@ type RemoteThreadData = {
24
26
  readonly title?: string | undefined;
25
27
  readonly lastMessageAt?: Date | undefined;
26
28
  readonly custom?: Record<string, unknown> | undefined;
29
+ readonly localOrigin?: true;
27
30
  };
28
31
  type THREAD_MAPPING_ID = string & {
29
32
  __brand: "THREAD_MAPPING_ID";
30
33
  };
31
34
  declare function createThreadMappingId(id: string): THREAD_MAPPING_ID;
35
+ declare const LOCAL_THREAD_ID_PREFIX = "__LOCALID_";
32
36
  declare const normalizeCursor: (c: string | undefined) => string | undefined;
33
37
  type ClassifyAccumulator = {
34
38
  threadIds: string[];
@@ -47,8 +51,15 @@ type RemoteThreadState = {
47
51
  readonly threadIdMap: Readonly<Record<string, THREAD_MAPPING_ID>>;
48
52
  readonly threadData: Readonly<Record<THREAD_MAPPING_ID, RemoteThreadData>>;
49
53
  };
54
+ declare const createEmptyRemoteThreadState: () => RemoteThreadState;
55
+ declare const seedNewThread: (state: RemoteThreadState) => {
56
+ id: string;
57
+ state: RemoteThreadState;
58
+ };
59
+ declare const preserveMidLoadTransitions: (state: RemoteThreadState, priorOrder: Pick<RemoteThreadState, "threadIds" | "archivedThreadIds">, statusAtRequest: ReadonlyMap<string, RemoteThreadData["status"]>) => RemoteThreadState;
60
+ declare const statusSnapshot: (state: RemoteThreadState) => ReadonlyMap<string, RemoteThreadData["status"]>;
50
61
  declare const getThreadData: (state: RemoteThreadState, threadIdOrRemoteId: string) => RemoteThreadData | undefined;
51
62
  declare const updateStatusReducer: (state: RemoteThreadState, threadIdOrRemoteId: string, newStatus: "regular" | "archived" | "deleted") => RemoteThreadState;
52
63
  //#endregion
53
- export { RemoteThreadData, RemoteThreadState, THREAD_MAPPING_ID, classifyThreads, createThreadMappingId, getThreadData, normalizeCursor, updateStatusReducer };
64
+ export { LOCAL_THREAD_ID_PREFIX, RemoteThreadData, RemoteThreadState, THREAD_MAPPING_ID, classifyThreads, createEmptyRemoteThreadState, createThreadMappingId, getThreadData, normalizeCursor, preserveMidLoadTransitions, seedNewThread, statusSnapshot, updateStatusReducer };
54
65
  //# sourceMappingURL=remote-thread-state.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"remote-thread-state.d.ts","names":[],"sources":["../../../src/runtimes/remote-thread-list/remote-thread-state.ts"],"mappings":";;KAKY;WAEG;WACA;WACA;WACA;WACA;WACA;;WAGA;WACA,gBAAgB,QAAQ;WACxB;WACA;WACA;WACA;WACA;;WAGA;WACA,gBAAgB,QAAQ;WACxB;WACA;WACA;WACA;WACA,gBAAgB;WAChB,SAAS;;KAGZ;EAA+B;;iBAE3B,sBAAsB,aAAa;cAItC,kBAAmB;KAG3B;EACH;EACA;EACA,aAAa,eAAe;EAC5B,YAAY,OAAO,mBAAmB;;cAG3B,kBACX,kBAAkB,wBAClB,KAAK,wBACJ;KAoCS;WACD;WACA;WACA;WACA;WACA;WACA;WACA,aAAa,SAAS,eAAe;WACrC,YAAY,SAAS,OAAO,mBAAmB;;cAG7C,gBACX,OAAO,mBACP,+BAA0B;cAOf,sBACX,OAAO,mBACP,4BACA,kDAA6C"}
1
+ {"version":3,"file":"remote-thread-state.d.ts","names":[],"sources":["../../../src/runtimes/remote-thread-list/remote-thread-state.ts"],"mappings":";;KAMY;WAEG;WACA;WACA;WACA;WACA;WACA;WACA;;WAGA;WACA,gBAAgB,QAAQ;WACxB;WACA;WACA;WACA;WACA;WACA;;WAGA;WACA,gBAAgB,QAAQ;WACxB;WACA;WACA;WACA;WACA,gBAAgB;WAChB,SAAS;WACT;;KAGH;EAA+B;;iBAE3B,sBAAsB,aAAa;cAItC;cAEA,kBAAmB;KAG3B;EACH;EACA;EACA,aAAa,eAAe;EAC5B,YAAY,OAAO,mBAAmB;;cAG3B,kBACX,kBAAkB,wBAClB,KAAK,wBACJ;KAoCS;WACD;WACA;WACA;WACA;WACA;WACA;WACA,aAAa,SAAS,eAAe;WACrC,YAAY,SAAS,OAAO,mBAAmB;;cAG7C,oCAAmC;cAWnC,gBACX,OAAO;EACJ;EAAY,OAAO;;cA2CX,6BACX,OAAO,mBACP,YAAY,KAAK,uDACjB,iBAAiB,oBAAoB,gCACpC;cAoDU,iBACX,OAAO,sBACN,oBAAoB;cAGV,gBACX,OAAO,mBACP,+BAA0B;cAOf,sBACX,OAAO,mBACP,4BACA,kDAA6C"}
@@ -1,7 +1,9 @@
1
+ import { generateId } from "../../utils/id.js";
1
2
  //#region src/runtimes/remote-thread-list/remote-thread-state.ts
2
3
  function createThreadMappingId(id) {
3
4
  return id;
4
5
  }
6
+ const LOCAL_THREAD_ID_PREFIX = "__LOCALID_";
5
7
  const normalizeCursor = (c) => c || void 0;
6
8
  const classifyThreads = (threads, acc) => {
7
9
  for (const thread of threads) {
@@ -36,6 +38,80 @@ const classifyThreads = (threads, acc) => {
36
38
  }
37
39
  return acc;
38
40
  };
41
+ const createEmptyRemoteThreadState = () => ({
42
+ isLoading: true,
43
+ isLoadingMore: false,
44
+ cursor: void 0,
45
+ newThreadId: void 0,
46
+ threadIds: [],
47
+ archivedThreadIds: [],
48
+ threadIdMap: {},
49
+ threadData: {}
50
+ });
51
+ const seedNewThread = (state) => {
52
+ let id;
53
+ do
54
+ id = `${LOCAL_THREAD_ID_PREFIX}${generateId()}`;
55
+ while (state.threadIdMap[id]);
56
+ const mappingId = createThreadMappingId(id);
57
+ return {
58
+ id,
59
+ state: {
60
+ ...state,
61
+ newThreadId: id,
62
+ threadIdMap: {
63
+ ...state.threadIdMap,
64
+ [id]: mappingId
65
+ },
66
+ threadData: {
67
+ ...state.threadData,
68
+ [mappingId]: {
69
+ status: "new",
70
+ id,
71
+ remoteId: void 0,
72
+ externalId: void 0,
73
+ title: void 0,
74
+ custom: void 0,
75
+ localOrigin: true
76
+ }
77
+ }
78
+ }
79
+ };
80
+ };
81
+ const preserveMidLoadTransitions = (state, priorOrder, statusAtRequest) => {
82
+ const regular = new Set(state.threadIds);
83
+ const archived = new Set(state.archivedThreadIds);
84
+ const rescuedRegular = [];
85
+ const rescuedArchived = [];
86
+ const contains = (ids, data) => ids.has(data.id) || data.remoteId !== void 0 && ids.has(data.remoteId);
87
+ for (const data of Object.values(state.threadData)) {
88
+ const before = statusAtRequest.get(data.id);
89
+ if (before !== void 0 && before !== "new") continue;
90
+ if (before === void 0 && data.localOrigin !== true) continue;
91
+ if (data.status === "regular" && !contains(regular, data)) {
92
+ rescuedRegular.push(data);
93
+ regular.add(data.id);
94
+ } else if (data.status === "archived" && !contains(archived, data)) {
95
+ rescuedArchived.push(data);
96
+ archived.add(data.id);
97
+ }
98
+ }
99
+ if (rescuedRegular.length === 0 && rescuedArchived.length === 0) return state;
100
+ const position = (ids, data) => {
101
+ const byId = ids.indexOf(data.id);
102
+ if (byId !== -1) return byId;
103
+ const byRemoteId = data.remoteId !== void 0 ? ids.indexOf(data.remoteId) : -1;
104
+ return byRemoteId !== -1 ? byRemoteId : Number.MAX_SAFE_INTEGER;
105
+ };
106
+ rescuedRegular.sort((a, b) => position(priorOrder.threadIds, a) - position(priorOrder.threadIds, b));
107
+ rescuedArchived.sort((a, b) => position(priorOrder.archivedThreadIds, a) - position(priorOrder.archivedThreadIds, b));
108
+ return {
109
+ ...state,
110
+ threadIds: [...rescuedRegular.map((d) => d.id), ...state.threadIds],
111
+ archivedThreadIds: [...rescuedArchived.map((d) => d.id), ...state.archivedThreadIds]
112
+ };
113
+ };
114
+ const statusSnapshot = (state) => new Map(Object.values(state.threadData).map((d) => [d.id, d.status]));
39
115
  const getThreadData = (state, threadIdOrRemoteId) => {
40
116
  const idx = state.threadIdMap[threadIdOrRemoteId];
41
117
  if (idx === void 0) return void 0;
@@ -82,6 +158,6 @@ const updateStatusReducer = (state, threadIdOrRemoteId, newStatus) => {
82
158
  return newState;
83
159
  };
84
160
  //#endregion
85
- export { classifyThreads, createThreadMappingId, getThreadData, normalizeCursor, updateStatusReducer };
161
+ export { LOCAL_THREAD_ID_PREFIX, classifyThreads, createEmptyRemoteThreadState, createThreadMappingId, getThreadData, normalizeCursor, preserveMidLoadTransitions, seedNewThread, statusSnapshot, updateStatusReducer };
86
162
 
87
163
  //# sourceMappingURL=remote-thread-state.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"remote-thread-state.js","names":["RemoteThreadInitializeResponse","RemoteThreadMetadata","RemoteThreadData","id","remoteId","externalId","status","title","custom","initializeTask","Promise","lastMessageAt","Date","Record","THREAD_MAPPING_ID","__brand","createThreadMappingId","normalizeCursor","c","undefined","ClassifyAccumulator","threadIds","archivedThreadIds","threadIdMap","threadData","classifyThreads","threads","acc","thread","push","_exhaustiveCheck","Error","mappingId","resolve","RemoteThreadState","isLoading","isLoadingMore","cursor","newThreadId","Readonly","getThreadData","state","threadIdOrRemoteId","idx","updateStatusReducer","newStatus","data","lastStatus","newState","filter","t","Object","fromEntries","entries","key"],"sources":["../../../src/runtimes/remote-thread-list/remote-thread-state.ts"],"sourcesContent":["import type {\n RemoteThreadInitializeResponse,\n RemoteThreadMetadata,\n} from \"./types\";\n\nexport type RemoteThreadData =\n | {\n readonly id: string;\n readonly remoteId: undefined;\n readonly externalId: undefined;\n readonly status: \"new\";\n readonly title: undefined;\n readonly custom: undefined;\n }\n | {\n readonly id: string;\n readonly initializeTask: Promise<RemoteThreadInitializeResponse>;\n readonly remoteId: undefined;\n readonly externalId: undefined;\n readonly status: \"regular\" | \"archived\";\n readonly title?: string | undefined;\n readonly custom: undefined;\n }\n | {\n readonly id: string;\n readonly initializeTask: Promise<RemoteThreadInitializeResponse>;\n readonly remoteId: string;\n readonly externalId: string | undefined;\n readonly status: \"regular\" | \"archived\";\n readonly title?: string | undefined;\n readonly lastMessageAt?: Date | undefined;\n readonly custom?: Record<string, unknown> | undefined;\n };\n\nexport type THREAD_MAPPING_ID = string & { __brand: \"THREAD_MAPPING_ID\" };\n\nexport function createThreadMappingId(id: string): THREAD_MAPPING_ID {\n return id as THREAD_MAPPING_ID;\n}\n\nexport const normalizeCursor = (c: string | undefined): string | undefined =>\n c || undefined;\n\ntype ClassifyAccumulator = {\n threadIds: string[];\n archivedThreadIds: string[];\n threadIdMap: Record<string, THREAD_MAPPING_ID>;\n threadData: Record<THREAD_MAPPING_ID, RemoteThreadData>;\n};\n\nexport const classifyThreads = (\n threads: readonly RemoteThreadMetadata[],\n acc: ClassifyAccumulator,\n): ClassifyAccumulator => {\n for (const thread of threads) {\n if (acc.threadIdMap[thread.remoteId] !== undefined) continue;\n\n switch (thread.status) {\n case \"regular\":\n acc.threadIds.push(thread.remoteId);\n break;\n case \"archived\":\n acc.archivedThreadIds.push(thread.remoteId);\n break;\n default: {\n const _exhaustiveCheck: never = thread.status;\n throw new Error(`Unsupported state: ${_exhaustiveCheck}`);\n }\n }\n\n const mappingId = createThreadMappingId(thread.remoteId);\n acc.threadIdMap[thread.remoteId] = mappingId;\n acc.threadData[mappingId] = {\n id: thread.remoteId,\n remoteId: thread.remoteId,\n externalId: thread.externalId,\n status: thread.status,\n title: thread.title,\n lastMessageAt: thread.lastMessageAt,\n custom: thread.custom,\n initializeTask: Promise.resolve({\n remoteId: thread.remoteId,\n externalId: thread.externalId,\n }),\n };\n }\n return acc;\n};\n\nexport type RemoteThreadState = {\n readonly isLoading: boolean;\n readonly isLoadingMore: boolean;\n readonly cursor: string | undefined;\n readonly newThreadId: string | undefined;\n readonly threadIds: readonly string[];\n readonly archivedThreadIds: readonly string[];\n readonly threadIdMap: Readonly<Record<string, THREAD_MAPPING_ID>>;\n readonly threadData: Readonly<Record<THREAD_MAPPING_ID, RemoteThreadData>>;\n};\n\nexport const getThreadData = (\n state: RemoteThreadState,\n threadIdOrRemoteId: string,\n) => {\n const idx = state.threadIdMap[threadIdOrRemoteId];\n if (idx === undefined) return undefined;\n return state.threadData[idx];\n};\n\nexport const updateStatusReducer = (\n state: RemoteThreadState,\n threadIdOrRemoteId: string,\n newStatus: \"regular\" | \"archived\" | \"deleted\",\n) => {\n const data = getThreadData(state, threadIdOrRemoteId);\n if (!data) return state;\n\n const { id, remoteId, status: lastStatus } = data;\n if (lastStatus === newStatus) return state;\n\n const newState = { ...state };\n\n // lastStatus\n switch (lastStatus) {\n case \"new\":\n newState.newThreadId = undefined;\n break;\n case \"regular\":\n newState.threadIds = newState.threadIds.filter((t) => t !== id);\n break;\n case \"archived\":\n newState.archivedThreadIds = newState.archivedThreadIds.filter(\n (t) => t !== id,\n );\n break;\n\n default: {\n const _exhaustiveCheck: never = lastStatus;\n throw new Error(`Unsupported state: ${_exhaustiveCheck}`);\n }\n }\n\n // newStatus\n switch (newStatus) {\n case \"regular\":\n newState.threadIds = [id, ...newState.threadIds];\n break;\n\n case \"archived\":\n newState.archivedThreadIds = [id, ...newState.archivedThreadIds];\n break;\n\n case \"deleted\":\n newState.threadData = Object.fromEntries(\n Object.entries(newState.threadData).filter(([key]) => key !== id),\n );\n newState.threadIdMap = Object.fromEntries(\n Object.entries(newState.threadIdMap).filter(\n ([key]) => key !== id && key !== remoteId,\n ),\n );\n break;\n\n default: {\n const _exhaustiveCheck: never = newStatus;\n throw new Error(`Unsupported state: ${_exhaustiveCheck}`);\n }\n }\n\n if (newStatus !== \"deleted\") {\n newState.threadData = {\n ...newState.threadData,\n [id]: {\n ...data,\n status: newStatus,\n },\n };\n }\n\n return newState;\n};\n"],"mappings":";AAoCA,SAAgBgB,sBAAsBb,IAA+B;CACnE,OAAOA;AACT;AAEA,MAAac,mBAAmBC,MAC9BA,KAAKC,KAAAA;AASP,MAAaM,mBACXC,SACAC,QACwB;CACxB,KAAK,MAAMC,UAAUF,SAAS;EAC5B,IAAIC,IAAIJ,YAAYK,OAAOxB,cAAce,KAAAA,GAAW;EAEpD,QAAQS,OAAOtB,QAAf;GACE,KAAK;IACHqB,IAAIN,UAAUQ,KAAKD,OAAOxB,QAAQ;IAClC;GACF,KAAK;IACHuB,IAAIL,kBAAkBO,KAAKD,OAAOxB,QAAQ;IAC1C;GACF,SAAS;IACP,MAAM0B,mBAA0BF,OAAOtB;IACvC,MAAM,IAAIyB,MAAM,sBAAsBD,kBAAkB;GAC1D;EACF;EAEA,MAAME,YAAYhB,sBAAsBY,OAAOxB,QAAQ;EACvDuB,IAAIJ,YAAYK,OAAOxB,YAAY4B;EACnCL,IAAIH,WAAWQ,aAAa;GAC1B7B,IAAIyB,OAAOxB;GACXA,UAAUwB,OAAOxB;GACjBC,YAAYuB,OAAOvB;GACnBC,QAAQsB,OAAOtB;GACfC,OAAOqB,OAAOrB;GACdI,eAAeiB,OAAOjB;GACtBH,QAAQoB,OAAOpB;GACfC,gBAAgBC,QAAQuB,QAAQ;IAC9B7B,UAAUwB,OAAOxB;IACjBC,YAAYuB,OAAOvB;GACrB,CAAC;EACH;CACF;CACA,OAAOsB;AACT;AAaA,MAAaa,iBACXC,OACAC,uBACG;CACH,MAAMC,MAAMF,MAAMlB,YAAYmB;CAC9B,IAAIC,QAAQxB,KAAAA,GAAW,OAAOA,KAAAA;CAC9B,OAAOsB,MAAMjB,WAAWmB;AAC1B;AAEA,MAAaC,uBACXH,OACAC,oBACAG,cACG;CACH,MAAMC,OAAON,cAAcC,OAAOC,kBAAkB;CACpD,IAAI,CAACI,MAAM,OAAOL;CAElB,MAAM,EAAEtC,IAAIC,UAAUE,QAAQyC,eAAeD;CAC7C,IAAIC,eAAeF,WAAW,OAAOJ;CAErC,MAAMO,WAAW,EAAE,GAAGP,MAAM;CAG5B,QAAQM,YAAR;EACE,KAAK;GACHC,SAASV,cAAcnB,KAAAA;GACvB;EACF,KAAK;GACH6B,SAAS3B,YAAY2B,SAAS3B,UAAU4B,QAAQC,MAAMA,MAAM/C,EAAE;GAC9D;EACF,KAAK;GACH6C,SAAS1B,oBAAoB0B,SAAS1B,kBAAkB2B,QACrDC,MAAMA,MAAM/C,EACf;GACA;EAEF,SAEE,MAAM,IAAI4B,MAAM,sBAAsBD,YAAkB;CAE5D;CAGA,QAAQe,WAAR;EACE,KAAK;GACHG,SAAS3B,YAAY,CAAClB,IAAI,GAAG6C,SAAS3B,SAAS;GAC/C;EAEF,KAAK;GACH2B,SAAS1B,oBAAoB,CAACnB,IAAI,GAAG6C,SAAS1B,iBAAiB;GAC/D;EAEF,KAAK;GACH0B,SAASxB,aAAa2B,OAAOC,YAC3BD,OAAOE,QAAQL,SAASxB,UAAU,CAAC,CAACyB,QAAQ,CAACK,SAASA,QAAQnD,EAAE,CAClE;GACA6C,SAASzB,cAAc4B,OAAOC,YAC5BD,OAAOE,QAAQL,SAASzB,WAAW,CAAC,CAAC0B,QAClC,CAACK,SAASA,QAAQnD,MAAMmD,QAAQlD,QACnC,CACF;GACA;EAEF,SAEE,MAAM,IAAI2B,MAAM,sBAAsBD,WAAkB;CAE5D;CAEA,IAAIe,cAAc,WAChBG,SAASxB,aAAa;EACpB,GAAGwB,SAASxB;GACXrB,KAAK;GACJ,GAAG2C;GACHxC,QAAQuC;EACV;CACF;CAGF,OAAOG;AACT"}
1
+ {"version":3,"file":"remote-thread-state.js","names":["RemoteThreadInitializeResponse","RemoteThreadMetadata","generateId","RemoteThreadData","id","remoteId","externalId","status","title","custom","localOrigin","initializeTask","Promise","lastMessageAt","Date","Record","THREAD_MAPPING_ID","__brand","createThreadMappingId","LOCAL_THREAD_ID_PREFIX","normalizeCursor","c","undefined","ClassifyAccumulator","threadIds","archivedThreadIds","threadIdMap","threadData","classifyThreads","threads","acc","thread","push","_exhaustiveCheck","Error","mappingId","resolve","RemoteThreadState","isLoading","isLoadingMore","cursor","newThreadId","Readonly","createEmptyRemoteThreadState","seedNewThread","state","preserveMidLoadTransitions","priorOrder","Pick","statusAtRequest","ReadonlyMap","regular","Set","archived","rescuedRegular","rescuedArchived","contains","ids","ReadonlySet","data","has","Object","values","before","get","add","length","position","byId","indexOf","byRemoteId","Number","MAX_SAFE_INTEGER","sort","a","b","map","d","statusSnapshot","Map","getThreadData","threadIdOrRemoteId","idx","updateStatusReducer","newStatus","lastStatus","newState","filter","t","fromEntries","entries","key"],"sources":["../../../src/runtimes/remote-thread-list/remote-thread-state.ts"],"sourcesContent":["import type {\n RemoteThreadInitializeResponse,\n RemoteThreadMetadata,\n} from \"./types\";\nimport { generateId } from \"../../utils/id\";\n\nexport type RemoteThreadData =\n | {\n readonly id: string;\n readonly remoteId: undefined;\n readonly externalId: undefined;\n readonly status: \"new\";\n readonly title: undefined;\n readonly custom: undefined;\n readonly localOrigin?: true;\n }\n | {\n readonly id: string;\n readonly initializeTask: Promise<RemoteThreadInitializeResponse>;\n readonly remoteId: undefined;\n readonly externalId: undefined;\n readonly status: \"regular\" | \"archived\";\n readonly title?: string | undefined;\n readonly custom: undefined;\n readonly localOrigin?: true;\n }\n | {\n readonly id: string;\n readonly initializeTask: Promise<RemoteThreadInitializeResponse>;\n readonly remoteId: string;\n readonly externalId: string | undefined;\n readonly status: \"regular\" | \"archived\";\n readonly title?: string | undefined;\n readonly lastMessageAt?: Date | undefined;\n readonly custom?: Record<string, unknown> | undefined;\n readonly localOrigin?: true;\n };\n\nexport type THREAD_MAPPING_ID = string & { __brand: \"THREAD_MAPPING_ID\" };\n\nexport function createThreadMappingId(id: string): THREAD_MAPPING_ID {\n return id as THREAD_MAPPING_ID;\n}\n\nexport const LOCAL_THREAD_ID_PREFIX = \"__LOCALID_\";\n\nexport const normalizeCursor = (c: string | undefined): string | undefined =>\n c || undefined;\n\ntype ClassifyAccumulator = {\n threadIds: string[];\n archivedThreadIds: string[];\n threadIdMap: Record<string, THREAD_MAPPING_ID>;\n threadData: Record<THREAD_MAPPING_ID, RemoteThreadData>;\n};\n\nexport const classifyThreads = (\n threads: readonly RemoteThreadMetadata[],\n acc: ClassifyAccumulator,\n): ClassifyAccumulator => {\n for (const thread of threads) {\n if (acc.threadIdMap[thread.remoteId] !== undefined) continue;\n\n switch (thread.status) {\n case \"regular\":\n acc.threadIds.push(thread.remoteId);\n break;\n case \"archived\":\n acc.archivedThreadIds.push(thread.remoteId);\n break;\n default: {\n const _exhaustiveCheck: never = thread.status;\n throw new Error(`Unsupported state: ${_exhaustiveCheck}`);\n }\n }\n\n const mappingId = createThreadMappingId(thread.remoteId);\n acc.threadIdMap[thread.remoteId] = mappingId;\n acc.threadData[mappingId] = {\n id: thread.remoteId,\n remoteId: thread.remoteId,\n externalId: thread.externalId,\n status: thread.status,\n title: thread.title,\n lastMessageAt: thread.lastMessageAt,\n custom: thread.custom,\n initializeTask: Promise.resolve({\n remoteId: thread.remoteId,\n externalId: thread.externalId,\n }),\n };\n }\n return acc;\n};\n\nexport type RemoteThreadState = {\n readonly isLoading: boolean;\n readonly isLoadingMore: boolean;\n readonly cursor: string | undefined;\n readonly newThreadId: string | undefined;\n readonly threadIds: readonly string[];\n readonly archivedThreadIds: readonly string[];\n readonly threadIdMap: Readonly<Record<string, THREAD_MAPPING_ID>>;\n readonly threadData: Readonly<Record<THREAD_MAPPING_ID, RemoteThreadData>>;\n};\n\nexport const createEmptyRemoteThreadState = (): RemoteThreadState => ({\n isLoading: true,\n isLoadingMore: false,\n cursor: undefined,\n newThreadId: undefined,\n threadIds: [],\n archivedThreadIds: [],\n threadIdMap: {},\n threadData: {},\n});\n\nexport const seedNewThread = (\n state: RemoteThreadState,\n): { id: string; state: RemoteThreadState } => {\n let id: string;\n do {\n id = `${LOCAL_THREAD_ID_PREFIX}${generateId()}`;\n } while (state.threadIdMap[id]);\n const mappingId = createThreadMappingId(id);\n return {\n id,\n state: {\n ...state,\n newThreadId: id,\n threadIdMap: {\n ...state.threadIdMap,\n [id]: mappingId,\n },\n threadData: {\n ...state.threadData,\n [mappingId]: {\n status: \"new\",\n id,\n remoteId: undefined,\n externalId: undefined,\n title: undefined,\n custom: undefined,\n localOrigin: true,\n } satisfies RemoteThreadData,\n },\n },\n };\n};\n\n// A list() response predating a mid-flight local transition (a thread\n// initialized while the request was running) omits that thread, and the\n// completed-optimistic replay cannot re-add it because the merged threadData\n// already carries the final status. Threads whose status moved from new (or\n// nonexistent) at request time to regular/archived are re-inserted at the\n// top, in the order the pre-response lists carried them: updateStatusReducer\n// prepends as transitions happen, so the pre-response lists hold newest\n// first, which threadData insertion order need not match. Threads the server already knew stay governed by the response, so\n// a server-side deletion is not resurrected — and a thread unknown to the\n// snapshot is only rescued when it carries the localOrigin marker stamped at\n// draft creation, so a deep-linked thread the fetch path deliberately\n// appended at the tail is not hoisted, whatever its remote id looks like.\nexport const preserveMidLoadTransitions = (\n state: RemoteThreadState,\n priorOrder: Pick<RemoteThreadState, \"threadIds\" | \"archivedThreadIds\">,\n statusAtRequest: ReadonlyMap<string, RemoteThreadData[\"status\"]>,\n): RemoteThreadState => {\n const regular = new Set(state.threadIds);\n const archived = new Set(state.archivedThreadIds);\n const rescuedRegular: RemoteThreadData[] = [];\n const rescuedArchived: RemoteThreadData[] = [];\n\n const contains = (ids: ReadonlySet<string>, data: RemoteThreadData) =>\n ids.has(data.id) || (data.remoteId !== undefined && ids.has(data.remoteId));\n\n for (const data of Object.values(state.threadData)) {\n const before = statusAtRequest.get(data.id);\n if (before !== undefined && before !== \"new\") continue;\n if (before === undefined && data.localOrigin !== true) continue;\n\n if (data.status === \"regular\" && !contains(regular, data)) {\n rescuedRegular.push(data);\n regular.add(data.id);\n } else if (data.status === \"archived\" && !contains(archived, data)) {\n rescuedArchived.push(data);\n archived.add(data.id);\n }\n }\n\n if (rescuedRegular.length === 0 && rescuedArchived.length === 0) return state;\n\n const position = (ids: readonly string[], data: RemoteThreadData) => {\n const byId = ids.indexOf(data.id);\n if (byId !== -1) return byId;\n const byRemoteId =\n data.remoteId !== undefined ? ids.indexOf(data.remoteId) : -1;\n return byRemoteId !== -1 ? byRemoteId : Number.MAX_SAFE_INTEGER;\n };\n rescuedRegular.sort(\n (a, b) =>\n position(priorOrder.threadIds, a) - position(priorOrder.threadIds, b),\n );\n rescuedArchived.sort(\n (a, b) =>\n position(priorOrder.archivedThreadIds, a) -\n position(priorOrder.archivedThreadIds, b),\n );\n\n return {\n ...state,\n threadIds: [...rescuedRegular.map((d) => d.id), ...state.threadIds],\n archivedThreadIds: [\n ...rescuedArchived.map((d) => d.id),\n ...state.archivedThreadIds,\n ],\n };\n};\n\nexport const statusSnapshot = (\n state: RemoteThreadState,\n): ReadonlyMap<string, RemoteThreadData[\"status\"]> =>\n new Map(Object.values(state.threadData).map((d) => [d.id, d.status]));\n\nexport const getThreadData = (\n state: RemoteThreadState,\n threadIdOrRemoteId: string,\n) => {\n const idx = state.threadIdMap[threadIdOrRemoteId];\n if (idx === undefined) return undefined;\n return state.threadData[idx];\n};\n\nexport const updateStatusReducer = (\n state: RemoteThreadState,\n threadIdOrRemoteId: string,\n newStatus: \"regular\" | \"archived\" | \"deleted\",\n) => {\n const data = getThreadData(state, threadIdOrRemoteId);\n if (!data) return state;\n\n const { id, remoteId, status: lastStatus } = data;\n if (lastStatus === newStatus) return state;\n\n const newState = { ...state };\n\n // lastStatus\n switch (lastStatus) {\n case \"new\":\n newState.newThreadId = undefined;\n break;\n case \"regular\":\n newState.threadIds = newState.threadIds.filter((t) => t !== id);\n break;\n case \"archived\":\n newState.archivedThreadIds = newState.archivedThreadIds.filter(\n (t) => t !== id,\n );\n break;\n\n default: {\n const _exhaustiveCheck: never = lastStatus;\n throw new Error(`Unsupported state: ${_exhaustiveCheck}`);\n }\n }\n\n // newStatus\n switch (newStatus) {\n case \"regular\":\n newState.threadIds = [id, ...newState.threadIds];\n break;\n\n case \"archived\":\n newState.archivedThreadIds = [id, ...newState.archivedThreadIds];\n break;\n\n case \"deleted\":\n newState.threadData = Object.fromEntries(\n Object.entries(newState.threadData).filter(([key]) => key !== id),\n );\n newState.threadIdMap = Object.fromEntries(\n Object.entries(newState.threadIdMap).filter(\n ([key]) => key !== id && key !== remoteId,\n ),\n );\n break;\n\n default: {\n const _exhaustiveCheck: never = newStatus;\n throw new Error(`Unsupported state: ${_exhaustiveCheck}`);\n }\n }\n\n if (newStatus !== \"deleted\") {\n newState.threadData = {\n ...newState.threadData,\n [id]: {\n ...data,\n status: newStatus,\n },\n };\n }\n\n return newState;\n};\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"ToolInvocationTracker.d.ts","names":[],"sources":["../../../src/runtimes/tool-invocations/ToolInvocationTracker.ts"],"mappings":";;;;;;;KAuBY;EACN;;EAEA;EACA;IAAW;IAAe;;;KAGpB;WACD;WACA;WACA;WACA,QAAQ;WACR;WACA,WAAW;WACX,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;cA8EtB;mBACM;mBACA;mBAEA;mBACA;mBAQA;mBACA;UAET;UAEA;UACA;;UAGA;UACA;UAEA;;;;;;;;;UAUA;UACA;EAGN,YAAA,gBAAgB,eAAe,mBAC/B,WAAW,sBAAsB;;;;;;UAa3B;;;;;EAsDD,SAAS,UAAU,sBAAsB;;;;;;EAmEzC;;;;;EAwBA,SAAS;;;;;;;EAkCT,OAAO,oBAAoB;;;;;;;EAoB3B,eAAe,oBAAoB;UAMlC;UA6CA;UAaA;UAmCA;UAYA;UA0BA;UAiCA;UAWA;UAaA;UAOA;UAUA;UAKA;UAgBA;;;;;;;;UA4BA;UAWA;UA0GA;;kBAiFO;OACH,kBAAkB;OAElB;aACD,mBAAmB;;aAEnB;;;;;;aAMA;;OAGC;;;;;IAKV,WAAW,SAAS;;;;;;IAMpB,mBACE,UAAU,oBAAoB"}
1
+ {"version":3,"file":"ToolInvocationTracker.d.ts","names":[],"sources":["../../../src/runtimes/tool-invocations/ToolInvocationTracker.ts"],"mappings":";;;;;;;KAuBY;EACN;;EAEA;EACA;IAAW;IAAe;;;KAGpB;WACD;WACA;WACA;WACA,QAAQ;WACR;WACA,WAAW;WACX,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;cA8EtB;mBACM;mBACA;mBAEA;mBACA;mBAQA;mBACA;UAET;UAEA;UACA;;UAGA;UACA;UAEA;;;;;;;;;UAUA;UACA;EAGN,YAAA,gBAAgB,eAAe,mBAC/B,WAAW,sBAAsB;;;;;;UAa3B;;;;;EAsDD,SAAS,UAAU,sBAAsB;;;;;;EAmEzC;;;;;EAwBA,SAAS;;;;;;;EAkCT,OAAO,oBAAoB;;;;;;;EAoB3B,eAAe,oBAAoB;UAMlC;UA6CA;UAaA;UAmCA;UAYA;UA0BA;UAkCA;UAWA;UAaA;UAOA;UAUA;UAKA;UAgBA;;;;;;;;UA4BA;UAWA;UA0GA;;kBAmFO;OACH,kBAAkB;OAElB;aACD,mBAAmB;;aAEnB;;;;;;aAMA;;OAGC;;;;;IAKV,WAAW,SAAS;;;;;;IAMpB,mBACE,UAAU,oBAAoB"}
@@ -292,6 +292,7 @@ var ToolInvocationTracker = class {
292
292
  const entry = this._entries.get(toolCallId);
293
293
  if (!entry || entry.executionId !== executionId) return;
294
294
  if (entry?.hasResult) return;
295
+ if (entry.skipExecute) return;
295
296
  this._invokeOnResult({
296
297
  type: "add-tool-result",
297
298
  toolCallId,
@@ -457,6 +458,7 @@ var ToolInvocationTracker = class {
457
458
  entry = void 0;
458
459
  }
459
460
  if (!entry) entry = this._startActiveEntry(content.toolCallId, content.toolName, content.result !== void 0);
461
+ if (content.approval !== void 0) entry.skipExecute = true;
460
462
  this._processArgsText(entry, content);
461
463
  if (content.result !== void 0 && !entry.hasResult) {
462
464
  const { controller: activeController } = entry;