mixdog 1.3.4 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (472) hide show
  1. package/LICENSES/oh-my-pi-MIT.txt +23 -0
  2. package/NOTICE.md +17 -2
  3. package/README.md +11 -0
  4. package/package.json +3 -11
  5. package/scripts/daemon-stub.mjs +1 -1
  6. package/scripts/embed-google-oauth-client.mjs +49 -0
  7. package/scripts/gate-local.mjs +4 -2
  8. package/scripts/lib/test-spawn-ledger.mjs +46 -1
  9. package/scripts/native-release-status.mjs +2 -2
  10. package/scripts/recall-history-cases.json +1 -1
  11. package/scripts/suite-health.mjs +10 -1
  12. package/scripts/test.mjs +12 -11
  13. package/src/agents/reviewer/AGENT.md +7 -11
  14. package/src/agents/reviewer/agent.json +1 -1
  15. package/src/defaults/shipped-history.json +25 -1
  16. package/src/defaults/skills/browser-use/SKILL.md +77 -17
  17. package/src/defaults/skills/code-tidy/SKILL.md +142 -270
  18. package/src/defaults/skills/code-tidy/references/agent-cleanup.md +4 -4
  19. package/src/defaults/skills/code-tidy/references/cleanup-report.md +31 -76
  20. package/src/defaults/skills/code-tidy/references/dead-code.md +6 -12
  21. package/src/defaults/skills/computer-use/SKILL.md +33 -9
  22. package/src/defaults/skills/setup/SKILL.md +29 -2
  23. package/src/defaults/skills/setup/references/actions.md +117 -28
  24. package/src/defaults/skills/setup/references/surfaces.md +77 -35
  25. package/src/defaults/skills/setup-guide/SKILL.md +3 -3
  26. package/src/defaults/skills/visualize/SKILL.md +2 -1
  27. package/src/lib/keychain-cjs.cjs +359 -29
  28. package/src/lib/rules-builder.cjs +10 -8
  29. package/src/rules/agent/AGENT.md +6 -6
  30. package/src/rules/agent-mode/AGENT_MODE.md +10 -2
  31. package/src/rules/agent-mode/MIXY.md +12 -0
  32. package/src/rules/lead/LEAD.md +18 -20
  33. package/src/rules/shared/05-tool-calls.md +5 -6
  34. package/src/rules/shared/10-tool-workflow.md +2 -0
  35. package/src/rules/shared/60-verification.md +7 -5
  36. package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +2 -3
  37. package/src/runtime/agent/orchestrator/agent-runtime/heartbeat-completion.mjs +193 -0
  38. package/src/runtime/agent/orchestrator/agent-runtime/title-completion.mjs +3 -1
  39. package/src/runtime/agent/orchestrator/agent-trace-format.mjs +3 -1
  40. package/src/runtime/agent/orchestrator/config.mjs +34 -0
  41. package/src/runtime/agent/orchestrator/context/collect.mjs +3 -0
  42. package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +72 -67
  43. package/src/runtime/agent/orchestrator/context/skill-catalog.mjs +54 -1
  44. package/src/runtime/agent/orchestrator/mcp/agent-connectors.mjs +3 -3
  45. package/src/runtime/agent/orchestrator/mcp/client-transport.mjs +177 -73
  46. package/src/runtime/agent/orchestrator/mcp/client.mjs +25 -2
  47. package/src/runtime/agent/orchestrator/mcp/oauth-callback.mjs +31 -2
  48. package/src/runtime/agent/orchestrator/mcp/oauth-client.mjs +16 -3
  49. package/src/runtime/agent/orchestrator/mcp/oauth-login.mjs +42 -7
  50. package/src/runtime/agent/orchestrator/mcp/oauth-provider.mjs +21 -2
  51. package/src/runtime/agent/orchestrator/mcp/oauth-shared.mjs +23 -0
  52. package/src/runtime/agent/orchestrator/mcp/oauth.mjs +11 -1
  53. package/src/runtime/agent/orchestrator/providers/account-pool.mjs +230 -137
  54. package/src/runtime/agent/orchestrator/providers/admission-scheduler.mjs +64 -7
  55. package/src/runtime/agent/orchestrator/providers/anthropic-api-request.mjs +18 -5
  56. package/src/runtime/agent/orchestrator/providers/anthropic-cache-warm.mjs +165 -0
  57. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
  58. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-credentials.mjs +4 -1
  59. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-request/gzip-post.mjs +14 -14
  60. package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +160 -69
  61. package/src/runtime/agent/orchestrator/providers/anthropic-overload-fallback.mjs +25 -3
  62. package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +64 -33
  63. package/src/runtime/agent/orchestrator/providers/anthropic.mjs +135 -87
  64. package/src/runtime/agent/orchestrator/providers/antigravity-oauth-catalog.mjs +52 -8
  65. package/src/runtime/agent/orchestrator/providers/antigravity-oauth.mjs +10 -1
  66. package/src/runtime/agent/orchestrator/providers/antigravity-request.mjs +22 -6
  67. package/src/runtime/agent/orchestrator/providers/antigravity-response.mjs +15 -4
  68. package/src/runtime/agent/orchestrator/providers/antigravity-stream.mjs +17 -2
  69. package/src/runtime/agent/orchestrator/providers/antigravity-transport.mjs +142 -104
  70. package/src/runtime/agent/orchestrator/providers/cache-warm-admission.mjs +90 -0
  71. package/src/runtime/agent/orchestrator/providers/codex-client-meta.mjs +1 -1
  72. package/src/runtime/agent/orchestrator/providers/cursor-wire-normalization.mjs +10 -4
  73. package/src/runtime/agent/orchestrator/providers/cursor-wire-protobuf.mjs +10 -217
  74. package/src/runtime/agent/orchestrator/providers/cursor-wire-transport.mjs +25 -9
  75. package/src/runtime/agent/orchestrator/providers/cursor.mjs +22 -6
  76. package/src/runtime/agent/orchestrator/providers/devin-auth.mjs +409 -0
  77. package/src/runtime/agent/orchestrator/providers/devin-wire-families.mjs +187 -0
  78. package/src/runtime/agent/orchestrator/providers/devin-wire-identity.mjs +342 -0
  79. package/src/runtime/agent/orchestrator/providers/devin-wire-models.mjs +541 -0
  80. package/src/runtime/agent/orchestrator/providers/devin-wire-protobuf.mjs +305 -0
  81. package/src/runtime/agent/orchestrator/providers/devin-wire-request.mjs +558 -0
  82. package/src/runtime/agent/orchestrator/providers/devin-wire-schema.mjs +880 -0
  83. package/src/runtime/agent/orchestrator/providers/devin-wire-session.mjs +190 -0
  84. package/src/runtime/agent/orchestrator/providers/devin-wire-tool-args.mjs +351 -0
  85. package/src/runtime/agent/orchestrator/providers/devin-wire-transport.mjs +560 -0
  86. package/src/runtime/agent/orchestrator/providers/devin.mjs +491 -0
  87. package/src/runtime/agent/orchestrator/providers/effort-configuration.mjs +3 -0
  88. package/src/runtime/agent/orchestrator/providers/gemini-output-limit.mjs +46 -0
  89. package/src/runtime/agent/orchestrator/providers/gemini-reasoning-relay.mjs +30 -0
  90. package/src/runtime/agent/orchestrator/providers/gemini-request-body.mjs +7 -11
  91. package/src/runtime/agent/orchestrator/providers/gemini-retry-policy.mjs +61 -22
  92. package/src/runtime/agent/orchestrator/providers/gemini-sdk-request.mjs +1 -0
  93. package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +71 -4
  94. package/src/runtime/agent/orchestrator/providers/gemini.mjs +25 -2
  95. package/src/runtime/agent/orchestrator/providers/grok-client-version.mjs +1 -1
  96. package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +96 -5
  97. package/src/runtime/agent/orchestrator/providers/lib/oauth-token-utils.mjs +17 -3
  98. package/src/runtime/agent/orchestrator/providers/lib/tail-reminder-split.mjs +23 -5
  99. package/src/runtime/agent/orchestrator/providers/media-normalization.mjs +52 -10
  100. package/src/runtime/agent/orchestrator/providers/model-proxy-channel.d.mts +8 -1
  101. package/src/runtime/agent/orchestrator/providers/model-proxy-channel.mjs +1 -0
  102. package/src/runtime/agent/orchestrator/providers/npm-cli-version.mjs +11 -3
  103. package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +19 -1
  104. package/src/runtime/agent/orchestrator/providers/oauth-usage.mjs +39 -3
  105. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-state.mjs +3 -1
  106. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream.mjs +2 -0
  107. package/src/runtime/agent/orchestrator/providers/openai-error-contract.mjs +6 -1
  108. package/src/runtime/agent/orchestrator/providers/openai-oauth-tokens.mjs +10 -9
  109. package/src/runtime/agent/orchestrator/providers/openai-ws-send/send-context.mjs +22 -3
  110. package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/attempt-context.mjs +43 -5
  111. package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/handshake-failure.mjs +3 -1
  112. package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/stream-failure.mjs +6 -3
  113. package/src/runtime/agent/orchestrator/providers/opencode-go-gemini.mjs +1 -0
  114. package/src/runtime/agent/orchestrator/providers/provider-availability.mjs +19 -0
  115. package/src/runtime/agent/orchestrator/providers/provider-error-kind.mjs +65 -1
  116. package/src/runtime/agent/orchestrator/providers/quota-reading.mjs +38 -12
  117. package/src/runtime/agent/orchestrator/providers/registry.mjs +43 -3
  118. package/src/runtime/agent/orchestrator/providers/retry-executor.mjs +39 -7
  119. package/src/runtime/agent/orchestrator/providers/statusline-route-meta.mjs +6 -0
  120. package/src/runtime/agent/orchestrator/providers/wire-protobuf-codec.mjs +368 -0
  121. package/src/runtime/agent/orchestrator/runtime-core/ask-user-tool-defs.mjs +12 -7
  122. package/src/runtime/agent/orchestrator/runtime-core/builtin-features.mjs +2 -0
  123. package/src/runtime/agent/orchestrator/runtime-core/compaction-config-keys.mjs +62 -0
  124. package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +37 -16
  125. package/src/runtime/agent/orchestrator/runtime-core/deferred-tool-delta.mjs +100 -23
  126. package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +1 -1
  127. package/src/runtime/agent/orchestrator/runtime-core/reaction-tool-defs.mjs +133 -0
  128. package/src/runtime/agent/orchestrator/runtime-core/session-text.mjs +2 -0
  129. package/src/runtime/agent/orchestrator/runtime-core/tool-bridge.mjs +19 -4
  130. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog-data.mjs +3 -0
  131. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +125 -30
  132. package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +23 -5
  133. package/src/runtime/agent/orchestrator/runtime-core/tool-profile.mjs +35 -10
  134. package/src/runtime/agent/orchestrator/runtime-core/workflow/agents.mjs +57 -10
  135. package/src/runtime/agent/orchestrator/runtime-core/workflow/context.mjs +9 -6
  136. package/src/runtime/agent/orchestrator/runtime-core/workflow-ids.mjs +1 -1
  137. package/src/runtime/agent/orchestrator/session/agent-loop.mjs +18 -0
  138. package/src/runtime/agent/orchestrator/session/agent-room.d.mts +0 -3
  139. package/src/runtime/agent/orchestrator/session/agent-room.mjs +10 -4
  140. package/src/runtime/agent/orchestrator/session/cache-warm.mjs +792 -0
  141. package/src/runtime/agent/orchestrator/session/compact/runner.mjs +148 -25
  142. package/src/runtime/agent/orchestrator/session/compaction-archive-capture.mjs +475 -58
  143. package/src/runtime/agent/orchestrator/session/compaction-archive.mjs +42 -17
  144. package/src/runtime/agent/orchestrator/session/eager-dispatch.mjs +8 -0
  145. package/src/runtime/agent/orchestrator/session/human-gate/gate.mjs +47 -9
  146. package/src/runtime/agent/orchestrator/session/human-gate/outbound-policy.mjs +6 -2
  147. package/src/runtime/agent/orchestrator/session/human-gate/requests.mjs +36 -4
  148. package/src/runtime/agent/orchestrator/session/human-gate/store.mjs +14 -2
  149. package/src/runtime/agent/orchestrator/session/loop/assistant-commit.mjs +8 -0
  150. package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +18 -22
  151. package/src/runtime/agent/orchestrator/session/loop/fresh-context.mjs +32 -3
  152. package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +11 -2
  153. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/segments.mjs +4 -1
  154. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn.mjs +51 -3
  155. package/src/runtime/agent/orchestrator/session/loop/route-fallback.mjs +17 -3
  156. package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +10 -2
  157. package/src/runtime/agent/orchestrator/session/loop/tool-exec/after-hook.mjs +2 -1
  158. package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +14 -4
  159. package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +16 -2
  160. package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +16 -1
  161. package/src/runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs +10 -0
  162. package/src/runtime/agent/orchestrator/session/loop/tool-helpers.mjs +3 -10
  163. package/src/runtime/agent/orchestrator/session/loop/tool-phase.mjs +23 -5
  164. package/src/runtime/agent/orchestrator/session/loop/turn-limits.mjs +60 -0
  165. package/src/runtime/agent/orchestrator/session/manager/ask-queue.mjs +12 -2
  166. package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +19 -1
  167. package/src/runtime/agent/orchestrator/session/manager/ask-turn-commit.mjs +2 -0
  168. package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +133 -90
  169. package/src/runtime/agent/orchestrator/session/manager/ask-turn-loop-options.mjs +14 -0
  170. package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +2 -1
  171. package/src/runtime/agent/orchestrator/session/manager/ask-turn-state.mjs +31 -4
  172. package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +30 -18
  173. package/src/runtime/agent/orchestrator/session/manager/owner-route-fallbacks.mjs +23 -13
  174. package/src/runtime/agent/orchestrator/session/manager/pending-message-entry.mjs +11 -2
  175. package/src/runtime/agent/orchestrator/session/manager/provider-replay.mjs +13 -0
  176. package/src/runtime/agent/orchestrator/session/manager/route-fallback-chain.mjs +129 -0
  177. package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +20 -2
  178. package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +2 -0
  179. package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +8 -0
  180. package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +1 -1
  181. package/src/runtime/agent/orchestrator/session/manager/session-tool-surface.mjs +13 -0
  182. package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +7 -2
  183. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-journal.mjs +102 -15
  184. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint.mjs +18 -5
  185. package/src/runtime/agent/orchestrator/session/message-ids.mjs +5 -3
  186. package/src/runtime/agent/orchestrator/session/message-reactions.mjs +89 -0
  187. package/src/runtime/agent/orchestrator/session/message-reactions.test-support.mjs +75 -0
  188. package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +19 -8
  189. package/src/runtime/agent/orchestrator/session/prompt-cache-idle-gaps.mjs +113 -0
  190. package/src/runtime/agent/orchestrator/session/prompt-cache-touch-store.mjs +127 -0
  191. package/src/runtime/agent/orchestrator/session/routine-result.d.mts +0 -2
  192. package/src/runtime/agent/orchestrator/session/routine-result.mjs +47 -11
  193. package/src/runtime/agent/orchestrator/session/send-with-recovery.mjs +20 -2
  194. package/src/runtime/agent/orchestrator/session/sensitive-projection.mjs +100 -0
  195. package/src/runtime/agent/orchestrator/session/sensitive-values.mjs +257 -0
  196. package/src/runtime/agent/orchestrator/session/side-question-store.mjs +20 -7
  197. package/src/runtime/agent/orchestrator/session/side-question.mjs +18 -0
  198. package/src/runtime/agent/orchestrator/session/skill-update-notice.mjs +60 -0
  199. package/src/runtime/agent/orchestrator/session/store/live-state.mjs +6 -3
  200. package/src/runtime/agent/orchestrator/session/store/save-delta.mjs +9 -5
  201. package/src/runtime/agent/orchestrator/session/store/serialize.mjs +9 -8
  202. package/src/runtime/agent/orchestrator/session/store/session-persistence-events.mjs +29 -0
  203. package/src/runtime/agent/orchestrator/session/store-agent-worker-header-cache.mjs +85 -0
  204. package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +133 -18
  205. package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +12 -2
  206. package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +44 -14
  207. package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +84 -3
  208. package/src/runtime/agent/orchestrator/session/stored-attachment-history.mjs +32 -0
  209. package/src/runtime/agent/orchestrator/session/tail-reminder-rules.mjs +11 -5
  210. package/src/runtime/agent/orchestrator/session/thinking-binding.mjs +108 -0
  211. package/src/runtime/agent/orchestrator/session/tool-batch/pre-dispatch.mjs +2 -2
  212. package/src/runtime/agent/orchestrator/session/tool-batch/record-outcome.mjs +2 -1
  213. package/src/runtime/agent/orchestrator/session/tool-batch/state.mjs +4 -0
  214. package/src/runtime/agent/orchestrator/session/tool-batch.mjs +5 -0
  215. package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +25 -2
  216. package/src/runtime/agent/orchestrator/session/transcript-restore/tool-result-status.mjs +9 -7
  217. package/src/runtime/agent/orchestrator/session/transcript-restore/tool-result-text.mjs +2 -2
  218. package/src/runtime/agent/orchestrator/session/turn-failure.mjs +5 -1
  219. package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +5 -2
  220. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/backgrounded-result.mjs +12 -1
  221. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/misuse-guard.mjs +240 -0
  222. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/result-format.mjs +1 -1
  223. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/shell-cwd.mjs +38 -0
  224. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +25 -5
  225. package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +65 -7
  226. package/src/runtime/agent/orchestrator/tools/builtin/shell-runtime.mjs +7 -1
  227. package/src/runtime/agent/orchestrator/tools/shell-command.mjs +36 -13
  228. package/src/runtime/browser-bridge/action-schema.mjs +13 -2
  229. package/src/runtime/browser-bridge/client.mjs +73 -8
  230. package/src/runtime/browser-bridge/input-fields.mjs +8 -9
  231. package/src/runtime/browser-bridge/mail-links.mjs +107 -0
  232. package/src/runtime/browser-bridge/tool-defs.mjs +1 -1
  233. package/src/runtime/channels/lib/config.mjs +6 -61
  234. package/src/runtime/channels/lib/crash-log.mjs +1 -1
  235. package/src/runtime/channels/lib/event-pipeline.mjs +4 -19
  236. package/src/runtime/channels/lib/event-queue.mjs +3 -18
  237. package/src/runtime/channels/lib/owned-runtime/automation-services.mjs +2 -2
  238. package/src/runtime/channels/lib/owned-runtime/automation-start.mjs +3 -4
  239. package/src/runtime/channels/lib/owned-runtime/config-reload.mjs +4 -59
  240. package/src/runtime/channels/lib/owned-runtime/owned-start.mjs +33 -115
  241. package/src/runtime/channels/lib/owned-runtime/owned-stop.mjs +5 -22
  242. package/src/runtime/channels/lib/owned-runtime/state.mjs +2 -8
  243. package/src/runtime/channels/lib/owned-runtime.mjs +6 -23
  244. package/src/runtime/channels/lib/parent-bridge.mjs +2 -2
  245. package/src/runtime/channels/lib/runtime-paths.mjs +4 -43
  246. package/src/runtime/channels/lib/schedule-errors.mjs +51 -0
  247. package/src/runtime/channels/lib/scheduler.mjs +135 -154
  248. package/src/runtime/channels/lib/schedules-db.mjs +83 -11
  249. package/src/runtime/channels/lib/status-snapshot.mjs +1 -1
  250. package/src/runtime/channels/lib/tool-dispatch.mjs +14 -2
  251. package/src/runtime/channels/lib/webhooks-db.mjs +5 -9
  252. package/src/runtime/channels/lib/worker-bootstrap.mjs +0 -1
  253. package/src/runtime/channels/lib/worker-ipc.mjs +0 -1
  254. package/src/runtime/channels/lib/worker-main.mjs +19 -34
  255. package/src/runtime/computer-bridge/action-schema.mjs +42 -1
  256. package/src/runtime/computer-bridge/actions.mjs +9 -1
  257. package/src/runtime/computer-bridge/client.mjs +180 -8
  258. package/src/runtime/computer-bridge/core-actions.mjs +2 -2
  259. package/src/runtime/computer-bridge/error-recovery.mjs +27 -2
  260. package/src/runtime/computer-bridge/linux-readiness.mjs +65 -23
  261. package/src/runtime/computer-bridge/pending-continuation.mjs +1 -1
  262. package/src/runtime/connectors/connector-accounts-mcp.mjs +230 -0
  263. package/src/runtime/connectors/gmail-app-password.mjs +172 -39
  264. package/src/runtime/connectors/google-mcp.mjs +10 -12
  265. package/src/runtime/memory/lib/pg/adapter.mjs +77 -70
  266. package/src/runtime/memory/lib/pg/supervisor.mjs +24 -12
  267. package/src/runtime/memory/lib/runtime-fetcher.mjs +23 -5
  268. package/src/runtime/office/com/com-adapter.mjs +17 -1
  269. package/src/runtime/office/com/office-com-host.ps1 +51 -1
  270. package/src/runtime/office/pdf/cfb-fixture.mjs +328 -0
  271. package/src/runtime/office/pdf/cfb-protection.mjs +311 -0
  272. package/src/runtime/office/pdf/document-preview.mjs +326 -8
  273. package/src/runtime/office/pdf/ooxml-crypto.mjs +469 -0
  274. package/src/runtime/office/pdf/ooxml-key-worker.mjs +14 -0
  275. package/src/runtime/office/portable/portable-soffice.mjs +45 -5
  276. package/src/runtime/session-search/session-search-db.mjs +73 -9
  277. package/src/runtime/session-search/session-search-ingest.mjs +110 -20
  278. package/src/runtime/shared/abort-race.mjs +89 -0
  279. package/src/runtime/shared/agent-avatar.d.mts +0 -1
  280. package/src/runtime/shared/agent-kind.mjs +4 -3
  281. package/src/runtime/shared/bot-hops.mjs +62 -2
  282. package/src/runtime/shared/bounded-download.mjs +8 -3
  283. package/src/runtime/shared/config.mjs +51 -35
  284. package/src/runtime/shared/connector-accounts.mjs +20 -10
  285. package/src/runtime/shared/connector-catalog.d.mts +33 -2
  286. package/src/runtime/shared/connector-catalog.mjs +166 -8
  287. package/src/runtime/shared/connector-triggers.mjs +22 -19
  288. package/src/runtime/shared/defaults-separation.mjs +2 -14
  289. package/src/runtime/shared/delegated-approval-host.mjs +103 -11
  290. package/src/runtime/shared/developer-options.mjs +32 -1
  291. package/src/runtime/shared/err-text.mjs +24 -15
  292. package/src/runtime/shared/file-permissions.d.mts +0 -8
  293. package/src/runtime/shared/file-permissions.mjs +0 -11
  294. package/src/runtime/shared/git-direct.test-support.mjs +19 -0
  295. package/src/runtime/shared/google-oauth-client.generated.json +4 -0
  296. package/src/runtime/shared/google-oauth-client.mjs +34 -9
  297. package/src/runtime/shared/heartbeat-interval.d.mts +4 -0
  298. package/src/runtime/shared/heartbeat-interval.mjs +19 -0
  299. package/src/runtime/shared/idle-auto-clear-gate.mjs +104 -0
  300. package/src/runtime/shared/llm/anthropic-betas.mjs +7 -0
  301. package/src/runtime/shared/llm/anthropic-thinking-contract.mjs +12 -0
  302. package/src/runtime/shared/llm/provider-catalog-registry.mjs +1 -0
  303. package/src/runtime/shared/llm/usage-rollup.mjs +1 -1
  304. package/src/runtime/shared/llm/well-formed.mjs +66 -0
  305. package/src/runtime/shared/mixy-presence.mjs +22 -0
  306. package/src/runtime/shared/orchestration.d.mts +2 -0
  307. package/src/runtime/shared/pg-schema-db.mjs +27 -16
  308. package/src/runtime/shared/profile-config.cjs +1 -1
  309. package/src/runtime/shared/prompt-origin.d.mts +4 -0
  310. package/src/runtime/shared/prompt-origin.mjs +21 -0
  311. package/src/runtime/shared/provider-accounts.mjs +231 -59
  312. package/src/runtime/shared/provider-api-key.mjs +19 -8
  313. package/src/runtime/shared/provider-display-name.mjs +29 -0
  314. package/src/runtime/shared/provider-timeout-phase.mjs +2 -0
  315. package/src/runtime/shared/routine-trigger.d.mts +2 -0
  316. package/src/runtime/shared/routine-trigger.mjs +52 -0
  317. package/src/runtime/shared/sensitive-path-rules.d.mts +2 -10
  318. package/src/runtime/shared/sensitive-path-rules.mjs +19 -41
  319. package/src/runtime/shared/session-activity-signal.mjs +34 -1
  320. package/src/runtime/shared/session-sidebar-host.d.mts +1 -1
  321. package/src/runtime/shared/session-sidebar-host.mjs +7 -3
  322. package/src/runtime/shared/session-turn-prelude.mjs +18 -0
  323. package/src/runtime/shared/tool-execution-contract.mjs +2 -0
  324. package/src/runtime/shared/tool-result-summary.mjs +1 -14
  325. package/src/runtime/shared/transcript-metadata.mjs +38 -0
  326. package/src/runtime/shared/user-data-guard.mjs +30 -2
  327. package/src/runtime/shared/worktrees/activity-gate.mjs +12 -5
  328. package/src/runtime/shared/worktrees/test-support.mjs +9 -4
  329. package/src/runtime/terminal-bridge/client.mjs +10 -1
  330. package/src/runtime/visualize-bridge/client.mjs +27 -8
  331. package/src/runtime/visualize-bridge/tool-defs.mjs +22 -8
  332. package/src/runtime/visualize-bridge/tool-meta.d.mts +5 -0
  333. package/src/runtime/visualize-bridge/tool-meta.mjs +22 -0
  334. package/src/runtime/web-search/lib/fetch-pipeline.mjs +2 -2
  335. package/src/session-runtime/agent-home-delivery.mjs +486 -179
  336. package/src/session-runtime/agent-room-delivery.mjs +28 -1
  337. package/src/session-runtime/agent-task-sessions.mjs +561 -199
  338. package/src/session-runtime/boot/apis.mjs +9 -0
  339. package/src/session-runtime/boot/begin.mjs +3 -2
  340. package/src/session-runtime/boot/infrastructure.mjs +4 -0
  341. package/src/session-runtime/boot/providers.mjs +3 -0
  342. package/src/session-runtime/boot/tools.mjs +8 -1
  343. package/src/session-runtime/bot-chain.mjs +32 -0
  344. package/src/session-runtime/bot-status.mjs +7 -4
  345. package/src/session-runtime/channel-config-api.mjs +63 -17
  346. package/src/session-runtime/config-lifecycle.mjs +6 -0
  347. package/src/session-runtime/connector-merge-migration.mjs +305 -0
  348. package/src/session-runtime/internal-tool-executor/ask-user-tool.mjs +132 -28
  349. package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +2 -0
  350. package/src/session-runtime/internal-tool-executor/reaction-tool.mjs +45 -0
  351. package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +72 -5
  352. package/src/session-runtime/internal-tool-executor.mjs +4 -0
  353. package/src/session-runtime/lifecycle/inheritance.mjs +16 -3
  354. package/src/session-runtime/lifecycle/session-catalog.mjs +3 -1
  355. package/src/session-runtime/lifecycle/teardown/runtime-stops.mjs +50 -4
  356. package/src/session-runtime/lifecycle/teardown.mjs +23 -5
  357. package/src/session-runtime/mcp-glue/server-catalog.mjs +61 -3
  358. package/src/session-runtime/mcp-oauth-login.mjs +5 -3
  359. package/src/session-runtime/mixy-heartbeat.mjs +927 -0
  360. package/src/session-runtime/model-route/route-tuning.mjs +10 -6
  361. package/src/session-runtime/notification-bus.mjs +31 -117
  362. package/src/session-runtime/notification-completion-queue.mjs +54 -0
  363. package/src/session-runtime/notification-listeners.mjs +76 -0
  364. package/src/session-runtime/owned-automation-run.mjs +35 -13
  365. package/src/session-runtime/prewarm/channel-start.mjs +3 -7
  366. package/src/session-runtime/provider-auth/login.mjs +7 -0
  367. package/src/session-runtime/provider-models/row-hydration.mjs +13 -2
  368. package/src/session-runtime/resource-mcp-api.mjs +143 -224
  369. package/src/session-runtime/resource-mcp-connector-accounts.mjs +163 -0
  370. package/src/session-runtime/resource-mcp-oauth-api.mjs +217 -0
  371. package/src/session-runtime/resource-mcp-secrets.mjs +82 -0
  372. package/src/session-runtime/resource-mcp-servers.mjs +78 -0
  373. package/src/session-runtime/resource-mcp-store.mjs +49 -0
  374. package/src/session-runtime/routine-home-turn.mjs +33 -6
  375. package/src/session-runtime/routine-owner.mjs +40 -9
  376. package/src/session-runtime/schedule-session-run.mjs +7 -3
  377. package/src/session-runtime/services/agent-tool/close-flow.mjs +3 -0
  378. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-plan.mjs +8 -12
  379. package/src/session-runtime/services/agent-tool/spawn-preset.mjs +7 -2
  380. package/src/session-runtime/services/agent-tool/tag-registry.mjs +1 -0
  381. package/src/session-runtime/services/agent-tool/worker-index/awaiting-user-sync.mjs +51 -0
  382. package/src/session-runtime/services/agent-tool/worker-index/disposal.mjs +55 -0
  383. package/src/session-runtime/services/agent-tool/worker-index/released-store.mjs +123 -0
  384. package/src/session-runtime/services/agent-tool/worker-index/restart-settlement.mjs +112 -0
  385. package/src/session-runtime/services/agent-tool/worker-index/row-reads.mjs +36 -0
  386. package/src/session-runtime/services/agent-tool/worker-index/row-shape.mjs +2 -0
  387. package/src/session-runtime/services/agent-tool/worker-index/row-store.mjs +17 -4
  388. package/src/session-runtime/services/agent-tool/worker-index/row-writes.mjs +58 -0
  389. package/src/session-runtime/services/agent-tool/worker-index.mjs +41 -241
  390. package/src/session-runtime/services/agent-tool/worker-rows.mjs +3 -0
  391. package/src/session-runtime/services/channel-admin.mjs +73 -31
  392. package/src/session-runtime/services/channel-session-router.mjs +4 -2
  393. package/src/session-runtime/services/channel-worker.mjs +1 -1
  394. package/src/session-runtime/services/provider-admin.mjs +128 -25
  395. package/src/session-runtime/services/schedule-access.mjs +14 -0
  396. package/src/session-runtime/services/seeds.mjs +0 -28
  397. package/src/session-runtime/services/usage-dashboard-model.mjs +1 -0
  398. package/src/session-runtime/session-compaction-sync.mjs +27 -0
  399. package/src/session-runtime/session-create/session-options.mjs +8 -4
  400. package/src/session-runtime/settings-builtin-tools-api.mjs +11 -0
  401. package/src/session-runtime/settings-compaction-api.mjs +2 -40
  402. package/src/session-runtime/settings-system-api.mjs +28 -1
  403. package/src/session-runtime/setup-tool/agent-settings-actions.mjs +65 -0
  404. package/src/session-runtime/setup-tool/executor.mjs +187 -29
  405. package/src/session-runtime/setup-tool/extended-actions.mjs +33 -2
  406. package/src/session-runtime/setup-tool/session-route-actions.mjs +152 -0
  407. package/src/session-runtime/setup-tool/settings-contract.mjs +68 -6
  408. package/src/session-runtime/setup-tool/tool-defs.mjs +92 -6
  409. package/src/session-runtime/task-session-route.mjs +99 -0
  410. package/src/session-runtime/tool-policy/agent-profile-fold.mjs +17 -13
  411. package/src/session-runtime/tool-policy/policy-stage.mjs +21 -4
  412. package/src/session-runtime/tool-policy/surface-helpers.mjs +2 -3
  413. package/src/session-runtime/tool-surface.mjs +4 -0
  414. package/src/session-runtime/turn/turn-run/ask-callbacks.mjs +1 -0
  415. package/src/session-runtime/workflow-agents-api/agent-editor.mjs +98 -21
  416. package/src/session-runtime/workflow-agents-api/style-and-mode.mjs +4 -0
  417. package/src/session-runtime/workflow-agents-api/workflow-packs.mjs +6 -1
  418. package/src/session-runtime/workspace/transitions.mjs +10 -2
  419. package/src/standalone/channel-transport/client-registry/client-records.mjs +65 -0
  420. package/src/standalone/channel-transport/client-registry/client-registration.mjs +118 -0
  421. package/src/standalone/channel-transport/client-registry.mjs +24 -163
  422. package/src/standalone/channel-transport.mjs +1 -1
  423. package/src/standalone/daemon-channels-loader.mjs +10 -8
  424. package/src/standalone/daemon-session-control/list-page.mjs +72 -0
  425. package/src/standalone/daemon-session-control/request.mjs +51 -0
  426. package/src/standalone/daemon-session-control/room-host.mjs +57 -0
  427. package/src/standalone/daemon-session-control/route-control.mjs +48 -0
  428. package/src/standalone/daemon-session-control/send-turn.mjs +60 -0
  429. package/src/standalone/daemon-session-control/worktree-control.mjs +40 -0
  430. package/src/standalone/daemon-session-control.mjs +161 -157
  431. package/src/standalone/daemon.mjs +33 -2
  432. package/src/standalone/session-client.mjs +7 -3
  433. package/src/standalone/session-protocol.mjs +10 -0
  434. package/src/standalone/session-service/agent-tree/agent-cancel.mjs +6 -2
  435. package/src/standalone/session-service/agent-tree/agent-child.mjs +1 -0
  436. package/src/standalone/session-service/quota-resume.mjs +3 -0
  437. package/src/standalone/session-service/retention/busy.mjs +65 -1
  438. package/src/standalone/session-service/session-calls/session-action.mjs +23 -2
  439. package/src/standalone/session-service/session-calls/session-turns.mjs +6 -0
  440. package/src/standalone/session-service/session-calls/session-views.mjs +8 -0
  441. package/src/standalone/session-service.mjs +13 -0
  442. package/src/standalone/session-tool-output.mjs +21 -10
  443. package/src/tui/app/model-options.mjs +4 -27
  444. package/src/tui/dist/index.mjs +81 -65
  445. package/src/tui/session/agent-job-feed/model-notification.mjs +3 -0
  446. package/src/tui/session/initial-state.mjs +3 -0
  447. package/src/tui/session/notice-surface.mjs +23 -1
  448. package/src/tui/session/queue-helpers.mjs +3 -42
  449. package/src/tui/session/session-api/integrations.mjs +1 -0
  450. package/src/tui/session/session-api/lifecycle.mjs +8 -0
  451. package/src/tui/session/session-api/routes-agent-definitions.mjs +14 -2
  452. package/src/tui/session/session-api/routes-write.mjs +5 -1
  453. package/src/tui/session/session-api/routes.mjs +1 -0
  454. package/src/tui/session/session-api/settings.mjs +30 -2
  455. package/src/tui/session/session-flow/auto-clear.mjs +4 -33
  456. package/src/tui/session/session-flow/drain-closed-queue.mjs +38 -0
  457. package/src/tui/session/session-flow/drain-enqueue.mjs +86 -0
  458. package/src/tui/session/session-flow/drain-retry.mjs +35 -0
  459. package/src/tui/session/session-flow/drain.mjs +118 -149
  460. package/src/tui/session/session-flow/queue/entry-shape.mjs +5 -0
  461. package/src/tui/session/session-flow/queue/take-entries.mjs +5 -2
  462. package/src/tui/session/tool-approval-delegation.mjs +64 -0
  463. package/src/tui/session/tool-approval-request.mjs +39 -0
  464. package/src/tui/session/tool-approval-settle.mjs +62 -0
  465. package/src/tui/session/tool-approval.mjs +69 -115
  466. package/src/tui/session/tui-steering-persist.mjs +8 -1
  467. package/src/tui/session/turn-stream.mjs +36 -3
  468. package/src/tui/session/turn.mjs +23 -2
  469. package/src/vendor/statusline/bin/statusline-route.mjs +1 -219
  470. package/src/vendor/statusline/src/gateway/route-meta.mjs +35 -13
  471. package/scripts/code-graph-description-contract.mjs +0 -188
  472. package/src/runtime/channels/lib/owned-runtime/ownership-refresh.mjs +0 -36
@@ -0,0 +1,129 @@
1
+ // The fallback chain a running session follows, read from its settings when
2
+ // it is needed (a hop, a status read) instead of the copy taken at creation:
3
+ // an edit made while the session runs applies from its next model request,
4
+ // and a chain cleared to [] stops further hops at once.
5
+ // - A Lead-class session (coding Lead, a bot's chat, Mixy) follows its
6
+ // owner's stored route (owner-route-fallbacks.mjs);
7
+ // - a delegated agent follows the route it was spawned from
8
+ // (`routeFallbackSource`: its agent's route, else Main's, or a named preset).
9
+ // The stored chain applies only while the session's primary — the route it
10
+ // ran on before its first hop — is that stored route's model. A session
11
+ // whose source cannot be read (an older record, a direct route) keeps its own.
12
+ import { findPreset } from '../../runtime-core/config-helpers.mjs';
13
+ import { normalizeWorkflowRoute } from '../../runtime-core/workflow.mjs';
14
+ import { configuredAgentRouteCandidates } from '../../../../shared/agent-route-config.mjs';
15
+ import { CODING_MODE, resolveSessionMode } from '../agent-mode.mjs';
16
+ import { _liveSessions } from '../store/live-state.mjs';
17
+ import { ownerConfiguredRoute, sameRouteModel } from './owner-route-fallbacks.mjs';
18
+
19
+ const LEAF_FIELDS = ['effort', 'fast', 'autoEffort', 'modelParameters', 'contextPercent', 'contextTokens'];
20
+
21
+ /** The switchable fields of a route or session record (no chain). */
22
+ export function routeLeaf(route) {
23
+ const leaf = { provider: route?.provider || '', model: route?.model || '' };
24
+ for (const key of LEAF_FIELDS) if (route?.[key] !== undefined && route[key] !== null) leaf[key] = route[key];
25
+ return leaf;
26
+ }
27
+
28
+ /** The route the session ran on before its first fallback hop; its own route
29
+ * while it has not hopped. */
30
+ export function sessionRoutePrimary(session) {
31
+ if (session?.routeFallbackPrimary?.provider) return session.routeFallbackPrimary;
32
+ const first = session?.routeFallbackFailures?.[0];
33
+ if (first?.provider && first?.model) return { provider: first.provider, model: first.model };
34
+ return routeLeaf(session);
35
+ }
36
+
37
+ function normalizedOrNull(stored) {
38
+ if (!stored) return null;
39
+ try {
40
+ return normalizeWorkflowRoute(stored) || null;
41
+ } catch {
42
+ return null;
43
+ }
44
+ }
45
+
46
+ /** The stored route the session's chain comes from, read now; null when the
47
+ * session has no readable source (it then keeps its own chain). */
48
+ export function sessionChainSource(session, config) {
49
+ const { mode, agentId } = resolveSessionMode({ session });
50
+ if (agentId) return ownerConfiguredRoute({ sessionMode: mode, agentId, config });
51
+ const source = session?.routeFallbackSource;
52
+ if (source?.agent) {
53
+ // As the spawn resolved it: the agent's own route, else Main's.
54
+ const own = configuredAgentRouteCandidates(config, source.agent).map(normalizedOrNull).find(Boolean);
55
+ return own || normalizedOrNull(findPreset(config, config?.default));
56
+ }
57
+ if (source?.preset) return normalizedOrNull(findPreset(config, source.preset));
58
+ return null;
59
+ }
60
+
61
+ /** `{ chain, fromSettings }`: the fallback routes the session follows now. */
62
+ export function liveRouteFallbacks(session, config) {
63
+ const source = sessionChainSource(session, config);
64
+ if (!source)
65
+ return { chain: Array.isArray(session?.routeFallbacks) ? session.routeFallbacks : [], fromSettings: false };
66
+ const onSourcePrimary = sameRouteModel(source, sessionRoutePrimary(session));
67
+ return { chain: onSourcePrimary ? source.fallbacks || [] : [], fromSettings: true };
68
+ }
69
+
70
+ /** Index in `chain` of the next route to try: the first after the session's
71
+ * current model that this session has not already run (its primary and the
72
+ * models it already left); `chain.length` when none is left. */
73
+ export function nextRouteFallbackIndex(session, chain) {
74
+ const tried = [sessionRoutePrimary(session), ...(session?.routeFallbackFailures || []), session];
75
+ const at = chain.findIndex((entry) => sameRouteModel(entry, session));
76
+ for (let index = at + 1; index < chain.length; index += 1) {
77
+ if (!tried.some((route) => sameRouteModel(chain[index], route))) return index;
78
+ }
79
+ return chain.length;
80
+ }
81
+
82
+ const modelOf = (route) => ({ provider: route?.provider || '', model: route?.model || '' });
83
+
84
+ /** The public fallback position of one session: the route it is on against
85
+ * its primary, the hop index, the chain it follows now and why it left each model. */
86
+ export function routeFallbackPosition(session, config) {
87
+ const { chain, fromSettings } = liveRouteFallbacks(session, config);
88
+ const next = chain[nextRouteFallbackIndex(session, chain)] || null;
89
+ const primary = sessionRoutePrimary(session);
90
+ const { mode, agentId } = resolveSessionMode({ session });
91
+ let kind = 'agent';
92
+ if (agentId) kind = mode === CODING_MODE ? 'lead' : 'bot';
93
+ return {
94
+ sessionId: session.id,
95
+ kind,
96
+ agent: agentId || session.agent || null,
97
+ current: modelOf(session),
98
+ primary: modelOf(primary),
99
+ onPrimary: sameRouteModel(primary, session),
100
+ fallbackIndex: Number(session.routeFallbackIndex) || 0,
101
+ fallbacks: chain.map(modelOf),
102
+ chainFrom: fromSettings ? 'settings' : 'session',
103
+ next: next ? modelOf(next) : null,
104
+ failures: (session.routeFallbackFailures || []).map(({ provider, model, kind: errorKind, error }) => ({
105
+ provider,
106
+ model,
107
+ kind: errorKind,
108
+ error,
109
+ })),
110
+ };
111
+ }
112
+
113
+ /** Whether the session has left its primary for a fallback model. */
114
+ export const routeFallbackHopped = (session) =>
115
+ Number(session?.routeFallbackIndex) > 0 || Boolean(session?.routeFallbackFailures?.length);
116
+
117
+ /** Positions of the sessions held in this process that follow a chain or have
118
+ * hopped; `keep(position)` narrows them. */
119
+ export function liveRouteFallbackPositions(config, keep = () => true) {
120
+ const rows = [];
121
+ for (const session of _liveSessions.values()) {
122
+ // Only a session with an agent hops (advanceAgentRoute).
123
+ if (!session?.id || session.closed === true || !session.agent) continue;
124
+ const position = routeFallbackPosition(session, config);
125
+ if (!position.fallbacks.length && !routeFallbackHopped(session)) continue;
126
+ if (keep(position)) rows.push(position);
127
+ }
128
+ return rows;
129
+ }
@@ -23,10 +23,12 @@
23
23
  // }
24
24
  import { createAbortController } from '../../../../shared/abort-controller.mjs';
25
25
  import { emitSessionApprovalWaitChange } from '../../../../shared/session-approval-wait.mjs';
26
- import { emitSessionActivityChange } from '../../../../shared/session-activity-signal.mjs';
26
+ import { emitSessionActivityChange, emitSessionTurnStart } from '../../../../shared/session-activity-signal.mjs';
27
27
  import { DEFAULT_ACTIVITY_HEARTBEAT_MS } from '../../stall-policy.mjs';
28
28
  import { MODEL_THINKING_STAGE, awaitingModelResponse, lastProgressAt } from '../../../../shared/quiet-progress.mjs';
29
- import { finishBrowserTurn } from '../../../../browser-bridge/client.mjs';
29
+ import { beginBrowserTurn, finishBrowserTurn, forgetBrowserSession } from '../../../../browser-bridge/client.mjs';
30
+ import { registerSessionPurgeHook } from '../store.mjs';
31
+ import { finishComputerTurn } from '../../../../computer-bridge/client.mjs';
30
32
  import { configureUsageMetricsRuntime, dropMetricSeenState, bumpUsageMetricsTurnId } from './usage-metrics.mjs';
31
33
  import { runtimeState as _runtimeState, isTurnInFlight } from './runtime-state.mjs';
32
34
 
@@ -48,11 +50,25 @@ const VALID_STAGES = new Set([
48
50
  ]);
49
51
  const TERMINAL_STAGES = new Set(['done', 'error']);
50
52
 
53
+ function beginBrowserWork(id, entry) {
54
+ void beginBrowserTurn(id, entry.browserTurnId).catch((error) => {
55
+ process.stderr.write(`[browser] Task start failed: ${error?.message || error}\n`);
56
+ });
57
+ }
58
+
59
+ // A session deleted for good no longer has browser turns to report.
60
+ registerSessionPurgeHook(forgetBrowserSession);
61
+
51
62
  function finishBrowserWork(id, entry, aborted = false) {
52
63
  const turnId = Number(entry.browserTurnId ?? entry.session?.usageMetricsTurnId) || 0;
53
64
  void finishBrowserTurn(id, turnId, { aborted }).catch((error) => {
54
65
  process.stderr.write(`[browser] Task cleanup failed: ${error?.message || error}\n`);
55
66
  });
67
+ // The same terminal state settles the turn's Computer Use saved-login fills
68
+ // (lead and sub-agent sessions alike).
69
+ void finishComputerTurn(id, turnId).catch((error) => {
70
+ process.stderr.write(`[computer] Turn settlement failed: ${error?.message || error}\n`);
71
+ });
56
72
  }
57
73
 
58
74
  // Injected deps that would otherwise pull manager.mjs's store/provider surface
@@ -149,6 +165,7 @@ export function markSessionAskStart(id) {
149
165
  const sessionForTurn = entry.session ?? _deps.loadSession(id);
150
166
  if (sessionForTurn) bumpUsageMetricsTurnId(sessionForTurn);
151
167
  entry.browserTurnId = Number(sessionForTurn?.usageMetricsTurnId) || 0;
168
+ beginBrowserWork(id, entry);
152
169
  entry.stage = 'connecting';
153
170
  entry.lastStreamDeltaAt = null;
154
171
  entry.lastTransportAt = null;
@@ -179,6 +196,7 @@ export function markSessionAskStart(id) {
179
196
  entry.lastProgressAt = now;
180
197
  entry.updatedAt = now;
181
198
  entry.taskWaits = 0;
199
+ emitSessionTurnStart(id);
182
200
  emitSessionActivityChange(id);
183
201
  }
184
202
  /** The provider put the request on the wire; its response headers are
@@ -24,6 +24,7 @@ import {
24
24
  } from './runtime-liveness.mjs';
25
25
  import { clearTurnCheckpoint } from './turn-checkpoint.mjs';
26
26
  import { forgetSessionSaveBaseline } from '../store/save-worker.mjs';
27
+ import { publishSessionPersistence } from '../store/session-persistence-events.mjs';
27
28
  import { forgetSessionLoadCache } from '../store/load-cache.mjs';
28
29
  import { releaseReadSnapshotScope } from '../../tools/builtin/snapshot-store.mjs';
29
30
  import { cancelOwnedShellTrees } from '../../tools/lib/owned-shell-trees.mjs';
@@ -142,6 +143,7 @@ function finishClose({ id, reason, tombstone, entry, closeSnapshot, newGen, outc
142
143
  // above; committing it stops the turn's checkpoint writer. Only now is it
143
144
  // safe to remove the crash fallback.
144
145
  closeSnapshot?.commit();
146
+ publishSessionPersistence(id, 'closed');
145
147
  _stopToolActivityHeartbeat(id);
146
148
  cancelOwnedShellProcesses({ id, reason, tombstone });
147
149
  clearTurnCheckpoint(id);
@@ -288,6 +288,13 @@ export function createSession(createOpts) {
288
288
  if (rulesRevision) session.rulesRevision = rulesRevision;
289
289
  }
290
290
  if (routeFallbacks?.length) session.routeFallbacks = routeFallbacks;
291
+ // Where an agent's chain is read from at each hop (route-fallback-chain.mjs).
292
+ const fallbackSource = Object.hasOwn(opts, 'routeFallbackSource')
293
+ ? opts.routeFallbackSource
294
+ : presetObj?.fallbackSource;
295
+ if (!actingAgent && fallbackSource && typeof fallbackSource === 'object') {
296
+ session.routeFallbackSource = { ...fallbackSource };
297
+ }
291
298
  // A non-native agent sends core + bridge, built from its filtered tools.
292
299
  applyAgentToolExposure(session);
293
300
  refreshSessionBp3Environment(session, opts.cwd);
@@ -364,6 +371,7 @@ function applyRouteFields(session, route) {
364
371
  else delete session.routeFallbacks;
365
372
  delete session.routeFallbackIndex;
366
373
  delete session.routeFallbackFailures;
374
+ delete session.routeFallbackPrimary;
367
375
  }
368
376
  ensureCodexWireSessionId(session);
369
377
  if (Object.hasOwn(route, 'modelParameters')) {
@@ -36,7 +36,7 @@ export function normalizeDesktopSessionMetadata(value, cwd = null) {
36
36
  return null;
37
37
  }
38
38
 
39
- function initialCompactionConfig(compaction = {}, contextMeta = {}) {
39
+ export function initialCompactionConfig(compaction = {}, contextMeta = {}) {
40
40
  return {
41
41
  auto: compaction?.auto !== false,
42
42
  model: compaction?.model || null,
@@ -10,6 +10,9 @@ import { isAgentOwner } from '../../agent-owner.mjs';
10
10
  import { getHiddenAgent } from '../../internal-agents.mjs';
11
11
  import { workflowDisallowsAgentTool } from '../../runtime-core/workflow.mjs';
12
12
  import { isAgentModeSession } from '../agent-mode.mjs';
13
+ import { agentIdOfHomeSession } from '../agent-home.mjs';
14
+ import { roomMemberOfSession } from '../agent-room.mjs';
15
+ import { REACTION_TOOL_NAME } from '../../runtime-core/reaction-tool-defs.mjs';
13
16
  import { finalizeSessionToolList, resolveSessionTools, permissionFromToolSpec } from './tool-resolution.mjs';
14
17
  import { unusedModelEditToolName } from '../../../../shared/edit-tool-dialect.mjs';
15
18
  import { getAgentRuntimeSync } from './agent-runtime-singleton.mjs';
@@ -24,6 +27,14 @@ export function delegationDisabled(source, ownerIsAgent) {
24
27
  );
25
28
  }
26
29
 
30
+ // The react tool belongs to a bot's own chat with the user: its home chat
31
+ // (`sess_home_<id>`) or its seat in a group room (`sess_rmem_…`), decided by the
32
+ // session's id, never a coding session or a delegated worker.
33
+ export function reactionDisabled(source, ownerIsAgent) {
34
+ const id = String(source?.id || '');
35
+ return ownerIsAgent || !(agentIdOfHomeSession(id) || roomMemberOfSession(id));
36
+ }
37
+
27
38
  // Exactly two schema surfaces exist: Lead and Agent. Every Agent role gets
28
39
  // the full Lead-capable base bundle; the recursive `agent` control tool is
29
40
  // removed later at the owner boundary. Role permission remains prompt/
@@ -79,6 +90,7 @@ export function resolveSessionToolSurface(opts, { profile, toolPreset, modelName
79
90
  const sessionDeny = [
80
91
  ...(Array.isArray(opts.disallowedTools) ? opts.disallowedTools : []),
81
92
  ...(delegationDisabled(opts, ownerIsAgent) ? ['agent'] : []),
93
+ ...(reactionDisabled(opts, ownerIsAgent) ? [REACTION_TOOL_NAME] : []),
82
94
  ];
83
95
  // Role permission is prompt/diagnostic metadata only. Resolve and persist
84
96
  // it without shaping the provider-visible Agent schema.
@@ -144,6 +156,7 @@ export function _prepareResumeTools(session, preset) {
144
156
  disallowedTools: [
145
157
  ...(Array.isArray(session.disallowedTools) ? session.disallowedTools : []),
146
158
  ...(delegationDisabled(session, ownerIsAgent) ? ['agent'] : []),
159
+ ...(reactionDisabled(session, ownerIsAgent) ? [REACTION_TOOL_NAME] : []),
147
160
  ],
148
161
  ownerIsAgent,
149
162
  }),
@@ -3,7 +3,8 @@
3
3
  import { compareCodePoints } from '../../../../shared/code-point-order.mjs';
4
4
  import { getMcpTools } from '../../mcp/client.mjs';
5
5
  import { getInternalTools } from '../../internal-tools.mjs';
6
- import { BUILTIN_TOOLS } from '../../tools/builtin/builtin-tools.mjs';
6
+ import { BUILTIN_TOOLS, bindShellKind } from '../../tools/builtin/builtin-tools.mjs';
7
+ import { resolveShellFor } from '../../tools/builtin/shell-runtime.mjs';
7
8
  import { PATCH_TOOL_DEFS } from '../../tools/patch-tool-defs.mjs';
8
9
  import { CODE_GRAPH_TOOL_DEFS } from '../../tools/code-graph-tool-defs.mjs';
9
10
  import { buildSkillToolDefs } from '../../context/collect.mjs';
@@ -101,7 +102,11 @@ export function resolveSessionTools(
101
102
  // time (loop.mjs), so the schema bytes stay bit-identical across roles /
102
103
  // cwds and the provider cache shard does not fragment.
103
104
  const skillTools = buildSkillToolDefs(skills, { ownerIsAgentSession });
104
- return filterModelEditTools(_computeBaseTools(toolSpec, mcp, skillTools), modelName);
105
+ // The shell text follows the system shell the runtime actually resolves
106
+ // (Git Bash/WSL on Windows, pwsh on POSIX), before the edit-dialect rewrite.
107
+ const shellKind = resolveShellFor('default')?.shellType;
108
+ const base = _computeBaseTools(toolSpec, mcp, skillTools).map((tool) => bindShellKind(tool, shellKind));
109
+ return filterModelEditTools(base, modelName);
105
110
  }
106
111
 
107
112
  export function previewSessionTools(toolSpec, skills = [], options = {}) {
@@ -39,6 +39,8 @@ import { join } from 'node:path';
39
39
  import { getPluginData } from '../../config.mjs';
40
40
  import { writeFileAtomicSync } from '../../../../shared/atomic-file.mjs';
41
41
  import { sanitizeContentForStoredHistory } from '../../providers/media-normalization.mjs';
42
+ import { redactSettledText, sensitiveValuesVersion } from '../sensitive-values.mjs';
43
+ import { redactSensitiveContent, redactSensitiveMessage, redactSensitiveToolCall } from '../sensitive-projection.mjs';
42
44
  import { promptContentText } from './prompt-utils.mjs';
43
45
 
44
46
  const TURN_CHECKPOINT_VERSION = 1;
@@ -96,7 +98,7 @@ export function checkpointMessage(message) {
96
98
  return content === message.content ? message : { ...message, content };
97
99
  }
98
100
 
99
- export function matchingUserMessage(message, currentUserContent) {
101
+ function matchingUserMessage(message, currentUserContent) {
100
102
  return (
101
103
  message?.role === 'user' &&
102
104
  (message.content === currentUserContent ||
@@ -131,16 +133,54 @@ export function emptyInterruptionSnapshot() {
131
133
  };
132
134
  }
133
135
 
134
- // ── Header (write-once, atomic) ─────────────────────────────────────────────
136
+ // Observed tool calls ([id, { call, eagerStarted }]) and early tool results
137
+ // ([id, tool message]) as a checkpoint stores them (sensitive-projection.mjs).
138
+ const storedCallEntries = (sessionId, entries) =>
139
+ entries.map(([id, entry]) => {
140
+ const call = redactSensitiveToolCall(sessionId, entry?.call);
141
+ return [id, call === entry?.call ? entry : { ...entry, call }];
142
+ });
143
+ const storedResultEntries = (sessionId, entries) =>
144
+ entries.map(([id, message]) => [id, redactSensitiveMessage(sessionId, message)]);
145
+
146
+ /** Interruption snapshot `snapshot` as `sessionId`'s checkpoint stores it:
147
+ * sensitive values (sensitive-values.mjs) replaced, and of the partial text
148
+ * only what no value can still complete. */
149
+ function redactInterruptionSnapshot(sessionId, snapshot) {
150
+ const source = snapshot ?? emptyInterruptionSnapshot();
151
+ if (!sensitiveValuesVersion(sessionId)) return source;
152
+ return {
153
+ ...source,
154
+ partialAssistantContent: redactSettledText(sessionId, String(source.partialAssistantContent || '')),
155
+ partialReasoningContent: redactSettledText(sessionId, String(source.partialReasoningContent || '')),
156
+ observedToolCalls: storedCallEntries(
157
+ sessionId,
158
+ Array.isArray(source.observedToolCalls) ? source.observedToolCalls : []
159
+ ),
160
+ observedToolResults: storedResultEntries(
161
+ sessionId,
162
+ Array.isArray(source.observedToolResults) ? source.observedToolResults : []
163
+ ),
164
+ };
165
+ }
166
+
167
+ // ── Header (written once per turn, again when a sensitive value is marked) ──
135
168
 
136
169
  export function writeCheckpointHeader(checkpoint) {
137
- const target = turnCheckpointPath(checkpoint.sessionId);
170
+ const { sessionId } = checkpoint;
171
+ const target = turnCheckpointPath(sessionId);
138
172
  const payload = {
139
173
  ...checkpoint,
140
174
  version: TURN_CHECKPOINT_VERSION,
141
- currentUserContent: sanitizeContentForStoredHistory(checkpoint.currentUserContent),
142
- turnMessages: (Array.isArray(checkpoint.turnMessages) ? checkpoint.turnMessages : []).map(checkpointMessage),
143
- interruption: checkpoint.interruption ?? emptyInterruptionSnapshot(),
175
+ currentUserContent: redactSensitiveContent(
176
+ sessionId,
177
+ sanitizeContentForStoredHistory(checkpoint.currentUserContent)
178
+ ),
179
+ turnMessages: (Array.isArray(checkpoint.turnMessages) ? checkpoint.turnMessages : []).map((message) =>
180
+ redactSensitiveMessage(sessionId, checkpointMessage(message))
181
+ ),
182
+ interruption: redactInterruptionSnapshot(sessionId, checkpoint.interruption),
183
+ // Counts, token readings and signatures only: no text.
144
184
  contextState: checkpoint.contextState ?? null,
145
185
  updatedAt: Date.now(),
146
186
  };
@@ -488,7 +528,15 @@ export function replayTurnJournal(header) {
488
528
  if (seq > expected) break;
489
529
  expected = seq + 1;
490
530
  if (!head) {
491
- if (record.t !== 'h' || record.turnToken !== header.turnToken) return header;
531
+ // A header rewritten for a newly marked sensitive value starts a new
532
+ // journal epoch; the journal it replaces never replays onto it.
533
+ if (
534
+ record.t !== 'h' ||
535
+ record.turnToken !== header.turnToken ||
536
+ (Number(record.e) || 0) !== (Number(header.journalEpoch) || 0)
537
+ ) {
538
+ return header;
539
+ }
492
540
  head = true;
493
541
  continue;
494
542
  }
@@ -529,7 +577,7 @@ export function replayTurnJournal(header) {
529
577
  * turn-relative index) plus an opaque interruption cursor, so each encode()
530
578
  * touches only what changed since the previous flush.
531
579
  */
532
- export function createTurnJournalEncoder({ turnToken } = {}) {
580
+ export function createTurnJournalEncoder({ turnToken, sessionId = null } = {}) {
533
581
  let journaled = [];
534
582
  let fullTranscript = false;
535
583
  let cursor = null;
@@ -537,27 +585,65 @@ export function createTurnJournalEncoder({ turnToken } = {}) {
537
585
  // Per-turn record sequence. It is assigned where records are produced, so
538
586
  // the number line is exactly the enqueue order the write lane preserves.
539
587
  let seq = 0;
588
+ // Set while the session has sensitive values (sensitive-values.mjs): the
589
+ // tracker's state as its deltas build it (`raw`) and the state the journal
590
+ // replays to (`written`). Interruption deltas are then journaled as the
591
+ // difference of the redacted text, so a value that streams in across
592
+ // flushes never lands in pieces. A newly marked value reseeds the encoder
593
+ // (turn-checkpoint.mjs), so the session's values are known whenever this is null.
594
+ let mirror = null;
540
595
  const line = (record) => {
541
596
  const stamped = { ...record, s: seq };
542
597
  seq += 1;
543
598
  return `${JSON.stringify(stamped)}\n`;
544
599
  };
600
+ const stored = (message) => redactSensitiveMessage(sessionId, checkpointMessage(message));
601
+ const interruptionRecord = (delta) => {
602
+ if (!mirror) return delta;
603
+ applyInterruptionDelta(mirror.raw, delta);
604
+ const out = {};
605
+ for (const key of ['rs', 'ph', 'cc', 'od']) if (Object.hasOwn(delta, key)) out[key] = delta[key];
606
+ for (const [field, setKey, appendKey] of [
607
+ ['text', 'ts', 'ta'],
608
+ ['reasoning', 'qs', 'qa'],
609
+ ]) {
610
+ const settled = redactSettledText(sessionId, mirror.raw[field]);
611
+ const written = mirror.written[field];
612
+ if (settled === written) continue;
613
+ if (settled.startsWith(written)) out[appendKey] = settled.slice(written.length);
614
+ else out[setKey] = settled;
615
+ }
616
+ if (Object.hasOwn(delta, 'tb')) out.tb = redactSensitiveContent(sessionId, mirror.raw.tomb);
617
+ if (delta.cs) out.cs = storedCallEntries(sessionId, delta.cs);
618
+ if (delta.os) out.os = storedResultEntries(sessionId, delta.os);
619
+ applyInterruptionDelta(mirror.written, out);
620
+ return out;
621
+ };
545
622
  return {
546
623
  /** Seed from the turn's opening state; returns the header's messages
547
624
  * and the journal's opening lines (head record, plus — defensively —
548
625
  * the delta that makes the journal authoritative if the tracker already
549
- * carried state at open time). */
550
- seed(turnOutgoing, currentUserContent, interruption, contextState = null) {
626
+ * carried state at open time). `snapshot` is the tracker snapshot the
627
+ * header stores; `epoch` names the journal a rewritten header starts. */
628
+ seed(turnOutgoing, currentUserContent, interruption, contextState = null, { snapshot = null, epoch = 0 } = {}) {
551
629
  const source = Array.isArray(turnOutgoing) ? turnOutgoing : [];
552
630
  const start = findTurnStart(source, currentUserContent);
553
631
  fullTranscript = start < 0;
554
632
  journaled = fullTranscript ? source.slice() : source.slice(start);
633
+ mirror = sensitiveValuesVersion(sessionId)
634
+ ? {
635
+ raw: interruptionStateFromSnapshot(snapshot),
636
+ written: interruptionStateFromSnapshot(redactInterruptionSnapshot(sessionId, snapshot)),
637
+ }
638
+ : null;
555
639
  const seeded = typeof interruption?.journalDelta === 'function' ? interruption.journalDelta(null) : null;
556
640
  cursor = seeded ? seeded.cursor : null;
557
641
  contextStateKey = contextState == null ? null : JSON.stringify(contextState);
558
642
  seq = 0;
559
- const openLines = [line({ t: 'h', turnToken, at: Date.now() })];
560
- if (seeded?.changed) openLines.push(line({ t: 'x', d: seeded.delta, at: Date.now() }));
643
+ const openLines = [line({ t: 'h', turnToken, ...(epoch ? { e: epoch } : {}), at: Date.now() })];
644
+ const seededDelta = seeded?.changed ? interruptionRecord(seeded.delta) : null;
645
+ if (seededDelta && Object.keys(seededDelta).length)
646
+ openLines.push(line({ t: 'x', d: seededDelta, at: Date.now() }));
561
647
  return {
562
648
  turnMessages: journaled.map(checkpointMessage),
563
649
  fullTranscript,
@@ -579,7 +665,7 @@ export function createTurnJournalEncoder({ turnToken } = {}) {
579
665
  journaled = source.slice();
580
666
  records.push({
581
667
  t: 'full',
582
- ms: journaled.map(checkpointMessage),
668
+ ms: journaled.map(stored),
583
669
  });
584
670
  } else {
585
671
  const offset = fullTranscript ? 0 : start;
@@ -588,7 +674,7 @@ export function createTurnJournalEncoder({ turnToken } = {}) {
588
674
  const raw = source[offset + index];
589
675
  if (journaled[index] === raw) continue;
590
676
  journaled[index] = raw;
591
- records.push({ t: 'm', i: index, m: checkpointMessage(raw) });
677
+ records.push({ t: 'm', i: index, m: stored(raw) });
592
678
  }
593
679
  if (journaled.length > length) {
594
680
  journaled.length = length;
@@ -598,7 +684,8 @@ export function createTurnJournalEncoder({ turnToken } = {}) {
598
684
  if (typeof interruption?.journalDelta === 'function') {
599
685
  const next = interruption.journalDelta(cursor);
600
686
  cursor = next.cursor;
601
- if (next.changed) records.push({ t: 'x', d: next.delta });
687
+ const delta = next.changed ? interruptionRecord(next.delta) : null;
688
+ if (delta && Object.keys(delta).length) records.push({ t: 'x', d: delta });
602
689
  }
603
690
  const nextContextStateKey = contextState == null ? null : JSON.stringify(contextState);
604
691
  if (nextContextStateKey !== contextStateKey) {
@@ -19,6 +19,7 @@ import {
19
19
  } from './turn-checkpoint-journal.mjs';
20
20
  import { captureTurnCheckpointContextState, restoreTurnCheckpointContextState } from './turn-checkpoint-context.mjs';
21
21
  import { stripProviderReplayMessages } from './provider-replay.mjs';
22
+ import { sensitiveValuesVersion } from '../sensitive-values.mjs';
22
23
 
23
24
  export { turnCheckpointPath, turnMessagesForCheckpoint };
24
25
  export { captureTurnCheckpointContextState, restoreTurnCheckpointContextState };
@@ -67,9 +68,14 @@ export function projectTurnCheckpointMessages(session, checkpoint) {
67
68
  // long tool-heavy turn no longer amplifies into the shared engine thread that
68
69
  // every fanned-out agent session shares.
69
70
  export function createTurnCheckpointRecorder({ sessionId, generation, turnToken, startedAt }) {
70
- const encoder = createTurnJournalEncoder({ turnToken });
71
+ const encoder = createTurnJournalEncoder({ turnToken, sessionId });
71
72
  let opened = false;
72
73
  let stopped = false;
74
+ // The sensitive-values version (sensitive-values.mjs) the header and
75
+ // journal were written under. A newly marked value rewrites both from the
76
+ // turn's current state with the value replaced, under a new journal epoch,
77
+ // so no recovery record keeps it.
78
+ let openedVersion = 0;
73
79
  return {
74
80
  get opened() {
75
81
  return opened;
@@ -77,8 +83,14 @@ export function createTurnCheckpointRecorder({ sessionId, generation, turnToken,
77
83
  /** True when this call wrote or queued durable state. */
78
84
  record({ currentUserContent, turnOutgoing, interruption, contextState = null }) {
79
85
  if (stopped || !sessionId || !turnToken) return false;
80
- if (!opened) {
81
- const seed = encoder.seed(turnOutgoing, currentUserContent, interruption, contextState);
86
+ const version = sensitiveValuesVersion(sessionId);
87
+ if (!opened || version !== openedVersion) {
88
+ const snapshot =
89
+ typeof interruption?.snapshot === 'function' ? interruption.snapshot() : emptyInterruptionSnapshot();
90
+ const seed = encoder.seed(turnOutgoing, currentUserContent, interruption, contextState, {
91
+ snapshot,
92
+ epoch: version,
93
+ });
82
94
  writeCheckpointHeader({
83
95
  sessionId,
84
96
  generation,
@@ -87,10 +99,11 @@ export function createTurnCheckpointRecorder({ sessionId, generation, turnToken,
87
99
  currentUserContent,
88
100
  turnMessages: seed.turnMessages,
89
101
  ...(seed.fullTranscript ? { fullTranscript: true } : {}),
90
- interruption:
91
- typeof interruption?.snapshot === 'function' ? interruption.snapshot() : emptyInterruptionSnapshot(),
102
+ ...(version ? { journalEpoch: version } : {}),
103
+ interruption: snapshot,
92
104
  contextState: seed.contextState,
93
105
  });
106
+ openedVersion = version;
94
107
  // Opening the journal is part of the anchor: a leftover journal
95
108
  // from an earlier turn of this session must never replay onto
96
109
  // the new header. It lands synchronously when the lane is idle
@@ -26,7 +26,7 @@ export function messageIdOf(message) {
26
26
  }
27
27
 
28
28
  /** Whether `meta` can hold a transcript id (absent or a plain object). */
29
- export function canCarryMessageId(message) {
29
+ function canCarryMessageId(message) {
30
30
  if (!message || typeof message !== 'object') return false;
31
31
  const meta = message.meta;
32
32
  return meta === undefined || meta === null || (typeof meta === 'object' && !Array.isArray(meta));
@@ -101,12 +101,14 @@ export function stampMessageIds(messages, { sessionId = '' } = {}) {
101
101
 
102
102
  /** JSON.stringify replacer that leaves stable ids out: hashes and archives
103
103
  * the compactor derives from message JSON describe the conversation, not
104
- * its display bookkeeping (a meta that only held the id is left out too). */
104
+ * its display bookkeeping (a meta that only held the id is left out too).
105
+ * Reactions on a message (message-reactions.mjs) are display bookkeeping of
106
+ * the same kind, written in place mid-turn, and are left out with the id. */
105
107
  export function withoutMessageIdsReplacer(key, value) {
106
108
  if (key !== 'meta' || !value || typeof value !== 'object' || typeof value.transcript?.messageId !== 'string') {
107
109
  return value;
108
110
  }
109
- const { messageId: _id, ...transcript } = value.transcript;
111
+ const { messageId: _id, reactions: _reactions, ...transcript } = value.transcript;
110
112
  const meta = { ...value };
111
113
  if (Object.keys(transcript).length) meta.transcript = transcript;
112
114
  else delete meta.transcript;