mixdog 1.4.1 → 1.4.3

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 (630) hide show
  1. package/package.json +4 -3
  2. package/scripts/build-shipped-history.mjs +125 -33
  3. package/scripts/gate-local.mjs +220 -63
  4. package/scripts/graph-parity.mjs +8 -3
  5. package/scripts/lib/gate-scheduler.mjs +139 -32
  6. package/scripts/lib/gate-timing-reporter.mjs +16 -0
  7. package/scripts/lib/run-node-tests.mjs +71 -34
  8. package/scripts/lib/scoped-temp.mjs +1 -0
  9. package/scripts/lib/test-failure-records.mjs +14 -1
  10. package/scripts/lib/test-failure-summary.mjs +9 -4
  11. package/scripts/lib/test-spawn-ledger.mjs +43 -3
  12. package/scripts/post-release-check.mjs +26 -16
  13. package/scripts/pptx-kit-index.mjs +5 -6
  14. package/scripts/provider-pingpong-live.mjs +1 -1
  15. package/scripts/prune-embedding-runtime.mjs +3 -1
  16. package/scripts/release-paths.mjs +7 -1
  17. package/scripts/suite-health.mjs +110 -28
  18. package/scripts/test.mjs +9 -14
  19. package/src/agents/advisor/AGENT.md +4 -4
  20. package/src/agents/advisor/agent.json +1 -1
  21. package/src/agents/explore/AGENT.md +22 -0
  22. package/src/agents/explore/agent.json +6 -0
  23. package/src/cli.mjs +7 -0
  24. package/src/defaults/agents.json +7 -0
  25. package/src/defaults/shipped-history.json +38 -2
  26. package/src/defaults/skills/browser-use/SKILL.md +4 -1
  27. package/src/defaults/skills/code-tidy/SKILL.md +71 -102
  28. package/src/defaults/skills/code-tidy/references/agent-cleanup.md +66 -114
  29. package/src/defaults/skills/code-tidy/references/cleanup-report.md +19 -35
  30. package/src/defaults/skills/code-tidy/references/dead-code.md +3 -9
  31. package/src/defaults/skills/code-tidy/references/test-suite-slop.md +16 -27
  32. package/src/defaults/skills/computer-use/SKILL.md +12 -2
  33. package/src/defaults/skills/setup/SKILL.md +2 -2
  34. package/src/defaults/skills/setup/references/actions.md +28 -9
  35. package/src/defaults/skills/setup/references/surfaces.md +5 -2
  36. package/src/defaults/skills/setup-guide/SKILL.md +11 -3
  37. package/src/defaults/skills/setup-guide/model-recommendations.json +13 -0
  38. package/src/defaults/skills/skill-creator/SKILL.md +85 -190
  39. package/src/defaults/skills/skill-creator/references/design.md +70 -162
  40. package/src/defaults/skills/skill-creator/references/evaluation.md +33 -92
  41. package/src/defaults/skills/test-suite/SKILL.md +194 -0
  42. package/src/defaults/skills/test-suite/references/case-management.md +51 -0
  43. package/src/defaults/skills/test-suite/references/flaky-policy.md +39 -0
  44. package/src/defaults/skills/test-suite/references/reliability.md +49 -0
  45. package/src/defaults/skills/test-suite/references/suite-design.md +78 -0
  46. package/src/defaults/skills/test-suite/scripts/inventory.mjs +335 -0
  47. package/src/defaults/skills/visualize/SKILL.md +6 -2
  48. package/src/lib/instruction-text.cjs +36 -0
  49. package/src/lib/rules-builder.cjs +40 -50
  50. package/src/orchestration/balanced.md +23 -0
  51. package/src/orchestration/focused.md +22 -0
  52. package/src/orchestration/none.md +5 -0
  53. package/src/orchestration/swarm.md +24 -0
  54. package/src/rules/agent-mode/AGENT_MODE.md +3 -1
  55. package/src/rules/agent-mode/MIXY.md +2 -2
  56. package/src/rules/lead/LEAD.md +3 -3
  57. package/src/rules/shared/20-research.md +3 -6
  58. package/src/rules/shared/40-editing.md +1 -0
  59. package/src/rules/shared/60-verification.md +10 -9
  60. package/src/rules/shared/70-delivery.md +4 -3
  61. package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/abort-link.mjs +5 -1
  62. package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/session-prep.mjs +3 -3
  63. package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch.mjs +10 -2
  64. package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +132 -21
  65. package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +13 -9
  66. package/src/runtime/agent/orchestrator/agent-runtime/heartbeat-completion.mjs +2 -2
  67. package/src/runtime/agent/orchestrator/agent-runtime/maintenance-route.mjs +4 -1
  68. package/src/runtime/agent/orchestrator/agent-runtime/session-builder.mjs +67 -0
  69. package/src/runtime/agent/orchestrator/agent-trace-format.mjs +1 -0
  70. package/src/runtime/agent/orchestrator/config.mjs +12 -7
  71. package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +7 -7
  72. package/src/runtime/agent/orchestrator/context/role-instructions.mjs +9 -30
  73. package/src/runtime/agent/orchestrator/internal-agents.mjs +3 -14
  74. package/src/runtime/agent/orchestrator/mcp/agent-connectors.mjs +124 -12
  75. package/src/runtime/agent/orchestrator/mcp/child-tree.mjs +204 -49
  76. package/src/runtime/agent/orchestrator/mcp/client-config.mjs +16 -7
  77. package/src/runtime/agent/orchestrator/mcp/client-transport.mjs +157 -57
  78. package/src/runtime/agent/orchestrator/mcp/client.mjs +54 -23
  79. package/src/runtime/agent/orchestrator/mcp/oauth-client.mjs +1 -1
  80. package/src/runtime/agent/orchestrator/mcp/oauth-credentials.mjs +8 -2
  81. package/src/runtime/agent/orchestrator/mcp/oauth-login.mjs +83 -52
  82. package/src/runtime/agent/orchestrator/mcp/oauth-probe.mjs +1 -1
  83. package/src/runtime/agent/orchestrator/mcp/oauth-provider.mjs +14 -0
  84. package/src/runtime/agent/orchestrator/mcp/oauth.mjs +43 -27
  85. package/src/runtime/agent/orchestrator/providers/account-pool.mjs +43 -8
  86. package/src/runtime/agent/orchestrator/providers/anthropic-api-request.mjs +30 -28
  87. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
  88. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-credentials.mjs +31 -21
  89. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events/content-block-stop.mjs +3 -3
  90. package/src/runtime/agent/orchestrator/providers/antigravity-oauth-login.mjs +3 -1
  91. package/src/runtime/agent/orchestrator/providers/antigravity-oauth-tokens.mjs +2 -2
  92. package/src/runtime/agent/orchestrator/providers/codex-client-meta.mjs +1 -1
  93. package/src/runtime/agent/orchestrator/providers/command-code-oauth.mjs +1 -1
  94. package/src/runtime/agent/orchestrator/providers/custom-provider-config.mjs +40 -0
  95. package/src/runtime/agent/orchestrator/providers/custom-provider-keys.mjs +34 -0
  96. package/src/runtime/agent/orchestrator/providers/custom-provider.mjs +3 -0
  97. package/src/runtime/agent/orchestrator/providers/devin-auth.mjs +14 -7
  98. package/src/runtime/agent/orchestrator/providers/devin-wire-transport.mjs +3 -2
  99. package/src/runtime/agent/orchestrator/providers/gemini-response.mjs +2 -2
  100. package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +4 -1
  101. package/src/runtime/agent/orchestrator/providers/gemini-thinking.mjs +2 -2
  102. package/src/runtime/agent/orchestrator/providers/grok-oauth-login.mjs +48 -31
  103. package/src/runtime/agent/orchestrator/providers/lib/oauth-page.mjs +0 -18
  104. package/src/runtime/agent/orchestrator/providers/lib/oauth-token-utils.mjs +138 -6
  105. package/src/runtime/agent/orchestrator/providers/mimo-oauth.mjs +1 -1
  106. package/src/runtime/agent/orchestrator/providers/model-cache.mjs +100 -33
  107. package/src/runtime/agent/orchestrator/providers/muse-code-oauth.mjs +1 -1
  108. package/src/runtime/agent/orchestrator/providers/oauth-secret-fields.fixtures.mjs +45 -0
  109. package/src/runtime/agent/orchestrator/providers/openai-compat-response-normalization.mjs +4 -6
  110. package/src/runtime/agent/orchestrator/providers/openai-compat-responses-head-parity.json +2784 -2872
  111. package/src/runtime/agent/orchestrator/providers/openai-compat-xai.mjs +5 -8
  112. package/src/runtime/agent/orchestrator/providers/openai-oauth-login.mjs +26 -28
  113. package/src/runtime/agent/orchestrator/providers/openai-responses-payload-parity.fixture.json +288 -300
  114. package/src/runtime/agent/orchestrator/providers/openai-ws-stream/event-switch.mjs +3 -1
  115. package/src/runtime/agent/orchestrator/providers/openai-ws-watchdogs.mjs +1 -0
  116. package/src/runtime/agent/orchestrator/providers/opencode-go-oauth.mjs +1 -1
  117. package/src/runtime/agent/orchestrator/providers/opencode-go.mjs +3 -1
  118. package/src/runtime/agent/orchestrator/providers/registry.mjs +33 -2
  119. package/src/runtime/agent/orchestrator/providers/vertex-ai-auth.mjs +622 -0
  120. package/src/runtime/agent/orchestrator/providers/vertex-ai-maas.mjs +185 -0
  121. package/src/runtime/agent/orchestrator/providers/vertex-ai-models.mjs +445 -0
  122. package/src/runtime/agent/orchestrator/providers/vertex-ai.mjs +576 -0
  123. package/src/runtime/agent/orchestrator/providers/xai-tool-search-head-parity.json +10 -30
  124. package/src/runtime/agent/orchestrator/runtime-core/builtin-features.mjs +32 -0
  125. package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +0 -11
  126. package/src/runtime/agent/orchestrator/runtime-core/deferred-tool-availability.mjs +8 -0
  127. package/src/runtime/agent/orchestrator/runtime-core/deferred-tool-delta.mjs +17 -3
  128. package/src/runtime/agent/orchestrator/runtime-core/goal-control.mjs +47 -27
  129. package/src/runtime/agent/orchestrator/runtime-core/goal-deadlines.mjs +141 -10
  130. package/src/runtime/agent/orchestrator/runtime-core/goal-mutations.mjs +26 -63
  131. package/src/runtime/agent/orchestrator/runtime-core/goal-reminder.mjs +28 -3
  132. package/src/runtime/agent/orchestrator/runtime-core/goal-runtime.mjs +36 -11
  133. package/src/runtime/agent/orchestrator/runtime-core/goal-state.mjs +88 -56
  134. package/src/runtime/agent/orchestrator/runtime-core/goal-storage.mjs +4 -1
  135. package/src/runtime/agent/orchestrator/runtime-core/goal-store.mjs +51 -32
  136. package/src/runtime/agent/orchestrator/runtime-core/goal-text.mjs +45 -145
  137. package/src/runtime/agent/orchestrator/runtime-core/goal-tool-defs.mjs +15 -98
  138. package/src/runtime/agent/orchestrator/runtime-core/goal-tool-exec.mjs +32 -99
  139. package/src/runtime/agent/orchestrator/runtime-core/goal-turns.mjs +23 -78
  140. package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +69 -47
  141. package/src/runtime/agent/orchestrator/runtime-core/todo-list.mjs +367 -0
  142. package/src/runtime/agent/orchestrator/runtime-core/todo-tool-defs.mjs +47 -0
  143. package/src/runtime/agent/orchestrator/runtime-core/tool-availability.mjs +155 -0
  144. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog-data.mjs +12 -0
  145. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +119 -35
  146. package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +4 -1
  147. package/src/runtime/agent/orchestrator/runtime-core/workflow/context.mjs +15 -6
  148. package/src/runtime/agent/orchestrator/runtime-core/workflow-ids.mjs +1 -0
  149. package/src/runtime/agent/orchestrator/session/agent-loop.mjs +28 -22
  150. package/src/runtime/agent/orchestrator/session/agent-pool-progress.mjs +30 -0
  151. package/src/runtime/agent/orchestrator/session/agent-room.d.mts +30 -5
  152. package/src/runtime/agent/orchestrator/session/agent-room.mjs +171 -37
  153. package/src/runtime/agent/orchestrator/session/attachment-preflight.mjs +1 -1
  154. package/src/runtime/agent/orchestrator/session/cache-warm.mjs +94 -10
  155. package/src/runtime/agent/orchestrator/session/catalog-db/index.mjs +2 -2
  156. package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +1 -1
  157. package/src/runtime/agent/orchestrator/session/compact/execution-tail.mjs +1 -1
  158. package/src/runtime/agent/orchestrator/session/compact/runner.mjs +3 -0
  159. package/src/runtime/agent/orchestrator/session/compact/summary-route.mjs +1 -1
  160. package/src/runtime/agent/orchestrator/session/context-utils.mjs +8 -12
  161. package/src/runtime/agent/orchestrator/session/conversation-import/claude.mjs +4 -4
  162. package/src/runtime/agent/orchestrator/session/conversation-import/codex.mjs +11 -6
  163. package/src/runtime/agent/orchestrator/session/conversation-import/convert.mjs +6 -6
  164. package/src/runtime/agent/orchestrator/session/conversation-import/imported-session.mjs +7 -3
  165. package/src/runtime/agent/orchestrator/session/conversation-import/turns.mjs +11 -1
  166. package/src/runtime/agent/orchestrator/session/eager-dispatch.mjs +4 -3
  167. package/src/runtime/agent/orchestrator/session/human-gate/held-message.mjs +1 -1
  168. package/src/runtime/agent/orchestrator/session/human-gate/requests.mjs +37 -8
  169. package/src/runtime/agent/orchestrator/session/human-gate/run-policy.mjs +1 -1
  170. package/src/runtime/agent/orchestrator/session/image-strip-recovery.mjs +1 -1
  171. package/src/runtime/agent/orchestrator/session/loop/completion-guards.mjs +11 -1
  172. package/src/runtime/agent/orchestrator/session/loop/context-overflow.mjs +1 -1
  173. package/src/runtime/agent/orchestrator/session/loop/fresh-context.mjs +5 -3
  174. package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +8 -1
  175. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/todo-check.mjs +196 -0
  176. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn.mjs +116 -50
  177. package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +8 -1
  178. package/src/runtime/agent/orchestrator/session/loop/provider-tool-exclusions.mjs +1 -1
  179. package/src/runtime/agent/orchestrator/session/loop/route-fallback.mjs +1 -1
  180. package/src/runtime/agent/orchestrator/session/loop/steering.mjs +3 -1
  181. package/src/runtime/agent/orchestrator/session/loop/stored-tool-args.mjs +5 -6
  182. package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +27 -3
  183. package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +18 -2
  184. package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +23 -1
  185. package/src/runtime/agent/orchestrator/session/loop/turn-limits.mjs +13 -8
  186. package/src/runtime/agent/orchestrator/session/loop/turn-report.mjs +35 -0
  187. package/src/runtime/agent/orchestrator/session/loop/usage.mjs +1 -1
  188. package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +103 -50
  189. package/src/runtime/agent/orchestrator/session/manager/ask-turn-auto-effort.mjs +9 -7
  190. package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +21 -3
  191. package/src/runtime/agent/orchestrator/session/manager/ask-turn-failure.mjs +27 -11
  192. package/src/runtime/agent/orchestrator/session/manager/ask-turn-open.mjs +37 -34
  193. package/src/runtime/agent/orchestrator/session/manager/ask-turn-prepare.mjs +15 -0
  194. package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +25 -15
  195. package/src/runtime/agent/orchestrator/session/manager/ask-turn-state.mjs +79 -24
  196. package/src/runtime/agent/orchestrator/session/manager/ask-turn-steering-drain.mjs +3 -0
  197. package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +12 -1
  198. package/src/runtime/agent/orchestrator/session/manager/context-meta.mjs +1 -1
  199. package/src/runtime/agent/orchestrator/session/manager/idle-cleanup.mjs +6 -1
  200. package/src/runtime/agent/orchestrator/session/manager/pending-messages.mjs +9 -1
  201. package/src/runtime/agent/orchestrator/session/manager/pending-spool-path.mjs +2 -2
  202. package/src/runtime/agent/orchestrator/session/manager/pending-spool-shard.mjs +1 -1
  203. package/src/runtime/agent/orchestrator/session/manager/prompt-settings.mjs +598 -0
  204. package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +20 -0
  205. package/src/runtime/agent/orchestrator/session/manager/rules-cache.mjs +22 -14
  206. package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +2 -0
  207. package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +12 -0
  208. package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +15 -0
  209. package/src/runtime/agent/orchestrator/session/manager/session-fallback-title.mjs +1 -1
  210. package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +56 -14
  211. package/src/runtime/agent/orchestrator/session/manager/session-lock.mjs +31 -0
  212. package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +59 -20
  213. package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +2 -0
  214. package/src/runtime/agent/orchestrator/session/manager/session-scratch-environment.mjs +70 -0
  215. package/src/runtime/agent/orchestrator/session/manager/session-tool-surface.mjs +0 -3
  216. package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +18 -4
  217. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-context.mjs +8 -9
  218. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-journal.mjs +339 -88
  219. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-recovery.mjs +135 -11
  220. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint.mjs +377 -104
  221. package/src/runtime/agent/orchestrator/session/manager/turn-durability.mjs +144 -0
  222. package/src/runtime/agent/orchestrator/session/manager/turn-interruption.mjs +48 -30
  223. package/src/runtime/agent/orchestrator/session/manager/turn-reap.mjs +125 -0
  224. package/src/runtime/agent/orchestrator/session/manager/usage-metrics.mjs +4 -0
  225. package/src/runtime/agent/orchestrator/session/manager.mjs +6 -0
  226. package/src/runtime/agent/orchestrator/session/mixy-name.mjs +12 -6
  227. package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +8 -1
  228. package/src/runtime/agent/orchestrator/session/restart-prefix-parity.fixture.mjs +1 -1
  229. package/src/runtime/agent/orchestrator/session/save-session-worker.mjs +5 -1
  230. package/src/runtime/agent/orchestrator/session/store/canonical-reader.mjs +1 -1
  231. package/src/runtime/agent/orchestrator/session/store/liveness-veto.mjs +2 -2
  232. package/src/runtime/agent/orchestrator/session/store/save-worker.mjs +23 -2
  233. package/src/runtime/agent/orchestrator/session/store/sweep/sub-agent-retention.mjs +3 -3
  234. package/src/runtime/agent/orchestrator/session/store/transcript-durability.mjs +88 -0
  235. package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +5 -0
  236. package/src/runtime/agent/orchestrator/session/store-summary-log.mjs +1 -1
  237. package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +243 -38
  238. package/src/runtime/agent/orchestrator/session/store-transcript-cache.mjs +163 -64
  239. package/src/runtime/agent/orchestrator/session/store-transcript-projection.mjs +177 -8
  240. package/src/runtime/agent/orchestrator/session/store-transcript-worker.mjs +142 -18
  241. package/src/runtime/agent/orchestrator/session/store.mjs +5 -0
  242. package/src/runtime/agent/orchestrator/session/synthetic-user-envelope.mjs +7 -1
  243. package/src/runtime/agent/orchestrator/session/tail-reminder-rules.mjs +9 -1
  244. package/src/runtime/agent/orchestrator/session/transcript-restore/agent-envelope.mjs +1 -1
  245. package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +3 -1
  246. package/src/runtime/agent/orchestrator/session/transcript-restore/user-text.mjs +2 -2
  247. package/src/runtime/agent/orchestrator/stall-policy.mjs +3 -5
  248. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/backgrounded-result.mjs +4 -1
  249. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/completed-result.mjs +6 -2
  250. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/misuse-guard.mjs +21 -3
  251. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/result-format.mjs +1 -1
  252. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/worktree-add-guard.mjs +77 -0
  253. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +0 -1
  254. package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +42 -28
  255. package/src/runtime/agent/orchestrator/tools/builtin/git-worktree-tool.mjs +30 -14
  256. package/src/runtime/agent/orchestrator/tools/builtin/lib/search-input-helpers.mjs +2 -2
  257. package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-job-records.mjs +58 -20
  258. package/src/runtime/agent/orchestrator/tools/builtin/read-range-index.mjs +1 -1
  259. package/src/runtime/agent/orchestrator/tools/builtin/read-single-fast-paths.mjs +0 -1
  260. package/src/runtime/agent/orchestrator/tools/builtin/runtime-capabilities.mjs +20 -15
  261. package/src/runtime/agent/orchestrator/tools/builtin/search-tool.mjs +0 -10
  262. package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +95 -20
  263. package/src/runtime/agent/orchestrator/tools/builtin/task-tool.mjs +59 -10
  264. package/src/runtime/agent/orchestrator/tools/builtin.mjs +1 -24
  265. package/src/runtime/agent/orchestrator/tools/code-graph/graph-binary/child-kill.mjs +4 -3
  266. package/src/runtime/agent/orchestrator/tools/code-graph/graph-binary.mjs +1 -2
  267. package/src/runtime/agent/orchestrator/tools/code-graph/modes/calls.mjs +1 -1
  268. package/src/runtime/agent/orchestrator/tools/code-graph/modes/symbols.mjs +2 -2
  269. package/src/runtime/agent/orchestrator/tools/code-graph/search.mjs +4 -5
  270. package/src/runtime/agent/orchestrator/tools/code-graph/symbol-index.mjs +3 -4
  271. package/src/runtime/agent/orchestrator/tools/code-graph.mjs +4 -22
  272. package/src/runtime/agent/orchestrator/tools/graph-manifest.json +13 -13
  273. package/src/runtime/agent/orchestrator/tools/lib/native-spawn-client.mjs +99 -2
  274. package/src/runtime/agent/orchestrator/tools/lib/owned-shell-trees.mjs +2 -0
  275. package/src/runtime/agent/orchestrator/tools/lib/shell-descendants.mjs +105 -15
  276. package/src/runtime/agent/orchestrator/tools/lib/shell-run-background/promote-job.mjs +3 -1
  277. package/src/runtime/agent/orchestrator/tools/lib/shell-run-settle.mjs +49 -15
  278. package/src/runtime/agent/orchestrator/tools/lib/shell-run-spawn.mjs +45 -27
  279. package/src/runtime/agent/orchestrator/tools/lib/shell-run-state.mjs +35 -11
  280. package/src/runtime/agent/orchestrator/tools/lib/shell-warm-standby.mjs +2 -0
  281. package/src/runtime/agent/orchestrator/tools/lib/wait-until-fixture.mjs +26 -0
  282. package/src/runtime/agent/orchestrator/tools/shell-command.mjs +7 -6
  283. package/src/runtime/agent/orchestrator/tools/shell-policy.mjs +0 -1
  284. package/src/runtime/agent/orchestrator/tools/spawn-manifest.json +13 -13
  285. package/src/runtime/attachments/attachment-reference.mjs +1 -1
  286. package/src/runtime/attachments/pdf-extract.mjs +1 -1
  287. package/src/runtime/attachments/store.d.mts +1 -0
  288. package/src/runtime/attachments/store.mjs +2 -2
  289. package/src/runtime/channels/lib/config-reload-watch.mjs +42 -0
  290. package/src/runtime/channels/lib/owned-runtime/config-reload.mjs +29 -9
  291. package/src/runtime/channels/lib/scheduler.mjs +33 -0
  292. package/src/runtime/channels/lib/schedules-db.mjs +11 -4
  293. package/src/runtime/channels/lib/webhook/session-dispatch.mjs +4 -1
  294. package/src/runtime/channels/lib/webhooks-db.mjs +9 -3
  295. package/src/runtime/channels/lib/whisper-port.mjs +19 -10
  296. package/src/runtime/channels/lib/whisper-server.mjs +22 -13
  297. package/src/runtime/channels/lib/worker-main.mjs +9 -31
  298. package/src/runtime/computer-bridge/linux-readiness.mjs +10 -14
  299. package/src/runtime/connectors/connector-accounts-mcp.mjs +372 -103
  300. package/src/runtime/connectors/gmail-app-password.mjs +4 -4
  301. package/src/runtime/connectors/google-mcp.mjs +1 -1
  302. package/src/runtime/effort-judge/judge-client.mjs +2 -2
  303. package/src/runtime/effort-judge/judge-input.mjs +4 -4
  304. package/src/runtime/explore/explorer.mjs +88 -0
  305. package/src/runtime/explore/tool-defs.mjs +35 -0
  306. package/src/runtime/explore/tool.mjs +123 -0
  307. package/src/runtime/local-provider/hardware.mjs +1 -1
  308. package/src/runtime/media/adapters/codex-image.mjs +3 -3
  309. package/src/runtime/media/adapters/gemini-video.mjs +1 -1
  310. package/src/runtime/media/media-usage.mjs +1 -1
  311. package/src/runtime/media/store.mjs +1 -1
  312. package/src/runtime/memory/index.mjs +15 -1
  313. package/src/runtime/memory/lib/embedding-provider.mjs +4 -1
  314. package/src/runtime/memory/lib/embedding-reindex.mjs +27 -0
  315. package/src/runtime/memory/lib/embedding-worker.mjs +4 -0
  316. package/src/runtime/memory/lib/memory-embed.mjs +83 -14
  317. package/src/runtime/memory/lib/memory-process-lock.mjs +159 -36
  318. package/src/runtime/memory/lib/memory-text-utils.mjs +6 -1
  319. package/src/runtime/memory/lib/memory.mjs +17 -0
  320. package/src/runtime/memory/lib/pg/process.mjs +1 -1
  321. package/src/runtime/memory/lib/pg/supervisor.mjs +16 -96
  322. package/src/runtime/memory/lib/recall-hybrid/hybrid-sql.mjs +12 -3
  323. package/src/runtime/office/authoring/docx-html-runner.mjs +1 -1
  324. package/src/runtime/office/authoring/pptx-author-action.mjs +1 -1
  325. package/src/runtime/office/authoring/xlsx-html-build.mjs +1 -1
  326. package/src/runtime/office/authoring/xlsx-html-runner.mjs +1 -1
  327. package/src/runtime/office/capabilities.mjs +1 -1
  328. package/src/runtime/office/core/office-core.mjs +1 -1
  329. package/src/runtime/office/design/content-model.mjs +3 -3
  330. package/src/runtime/office/design/docx/design-docx/section.mjs +6 -6
  331. package/src/runtime/office/design/xlsx/design-xlsx-components.mjs +1 -1
  332. package/src/runtime/office/design/xlsx/design-xlsx.mjs +1 -1
  333. package/src/runtime/office/pdf/ocr-engine.mjs +1 -1
  334. package/src/runtime/office/pdf/pdf-writer.mjs +4 -4
  335. package/src/runtime/office/portable/portable-docx-operations.mjs +2 -2
  336. package/src/runtime/office/portable/portable-soffice.mjs +8 -6
  337. package/src/runtime/office/portable/xlsx-contract.mjs +1 -1
  338. package/src/runtime/office/quality/assurance-structure-docx.mjs +1 -1
  339. package/src/runtime/shared/agent-route-config.mjs +17 -2
  340. package/src/runtime/shared/atomic-file.d.mts +8 -0
  341. package/src/runtime/shared/atomic-file.mjs +103 -2
  342. package/src/runtime/shared/background-tasks.mjs +37 -10
  343. package/src/runtime/shared/background-wait.mjs +66 -0
  344. package/src/runtime/shared/child-guardian.mjs +17 -7
  345. package/src/runtime/shared/config.mjs +313 -16
  346. package/src/runtime/shared/connector-accounts.mjs +5 -5
  347. package/src/runtime/shared/connector-catalog.d.mts +14 -8
  348. package/src/runtime/shared/connector-catalog.mjs +70 -52
  349. package/src/runtime/shared/custom-provider-keys.mjs +20 -0
  350. package/src/runtime/shared/file-has-data.mjs +26 -2
  351. package/src/runtime/shared/file-lock.mjs +21 -18
  352. package/src/runtime/shared/git-launch.d.mts +9 -0
  353. package/src/runtime/shared/git-launch.mjs +213 -0
  354. package/src/runtime/shared/git-runner-worker.mjs +2 -1
  355. package/src/runtime/shared/git-runner.mjs +7 -2
  356. package/src/runtime/shared/idle-gc.mjs +30 -7
  357. package/src/runtime/shared/llm/cost.mjs +6 -1
  358. package/src/runtime/shared/llm/http-agent.mjs +316 -29
  359. package/src/runtime/shared/llm/model-catalog-projection.mjs +3 -2
  360. package/src/runtime/shared/llm/model-catalog.mjs +46 -6
  361. package/src/runtime/shared/llm/provider-catalog-registry.mjs +3 -0
  362. package/src/runtime/shared/llm/system-proxy.mjs +453 -0
  363. package/src/runtime/shared/llm/usage-ledger-quota.mjs +31 -12
  364. package/src/runtime/shared/llm/usage-ledger-rollup.mjs +84 -8
  365. package/src/runtime/shared/llm/usage-ledger.mjs +3 -0
  366. package/src/runtime/shared/llm/usage-rollup.mjs +48 -0
  367. package/src/runtime/shared/maintenance-schedule.mjs +109 -0
  368. package/src/runtime/shared/process-runner.mjs +8 -4
  369. package/src/runtime/shared/provider-accounts.mjs +52 -2
  370. package/src/runtime/shared/routine-trigger.d.mts +13 -0
  371. package/src/runtime/shared/routine-trigger.mjs +34 -0
  372. package/src/runtime/shared/run-child.d.mts +2 -1
  373. package/src/runtime/shared/run-child.mjs +70 -18
  374. package/src/runtime/shared/session-scratch.mjs +14 -2
  375. package/src/runtime/shared/shipped-definitions.mjs +7 -1
  376. package/src/runtime/shared/staged-install-worker.mjs +5 -0
  377. package/src/runtime/shared/staged-update.mjs +47 -2
  378. package/src/runtime/shared/tool-card-model.golden.json +3 -12
  379. package/src/runtime/shared/tool-execution-contract.mjs +2 -0
  380. package/src/runtime/shared/tool-surface.mjs +110 -36
  381. package/src/runtime/shared/tool-work-units.mjs +35 -6
  382. package/src/runtime/shared/turn-snapshot.mjs +26 -4
  383. package/src/runtime/shared/turn-worktree-snapshot.mjs +409 -54
  384. package/src/runtime/shared/worker-requests.mjs +17 -3
  385. package/src/runtime/shared/worktrees/activity-gate.mjs +215 -318
  386. package/src/runtime/shared/worktrees/activity-ledger-worker.mjs +56 -0
  387. package/src/runtime/shared/worktrees/activity-ledger.mjs +391 -0
  388. package/src/runtime/shared/worktrees/branch-management.mjs +5 -3
  389. package/src/runtime/shared/worktrees/contract.mjs +16 -6
  390. package/src/runtime/shared/worktrees/dependencies.mjs +127 -89
  391. package/src/runtime/shared/worktrees/disk.mjs +79 -2
  392. package/src/runtime/shared/worktrees/git.mjs +97 -7
  393. package/src/runtime/shared/worktrees/include.mjs +6 -4
  394. package/src/runtime/shared/worktrees/maintenance.mjs +422 -30
  395. package/src/runtime/shared/worktrees/manager.mjs +962 -197
  396. package/src/runtime/shared/worktrees/settings.mjs +33 -7
  397. package/src/runtime/shared/worktrees/test-support.mjs +5 -1
  398. package/src/runtime/shared/worktrees/worker-snapshots.mjs +82 -0
  399. package/src/runtime/tidy/install.mjs +95 -15
  400. package/src/runtime/tidy/languages.mjs +17 -15
  401. package/src/runtime/tidy/process.mjs +9 -5
  402. package/src/runtime/tidy/resolve.mjs +19 -16
  403. package/src/runtime/tidy/runners/biome.mjs +3 -3
  404. package/src/runtime/tidy/tool.mjs +1 -1
  405. package/src/runtime/tidy/worktree.mjs +10 -6
  406. package/src/runtime/visualize-bridge/client.mjs +4 -1
  407. package/src/runtime/visualize-bridge/tool-defs.mjs +7 -2
  408. package/src/runtime/web-search/index.mjs +4 -23
  409. package/src/runtime/web-search/lib/web-tools.mjs +2 -2
  410. package/src/runtime/web-search/tool-defs.mjs +17 -26
  411. package/src/session-runtime/agent-profile-changes.mjs +55 -4
  412. package/src/session-runtime/agent-task-sessions.mjs +410 -353
  413. package/src/session-runtime/boot/apis.mjs +27 -4
  414. package/src/session-runtime/boot/begin.mjs +2 -0
  415. package/src/session-runtime/boot/config.mjs +10 -1
  416. package/src/session-runtime/boot/facade.mjs +1 -0
  417. package/src/session-runtime/boot/providers.mjs +70 -3
  418. package/src/session-runtime/boot/session.mjs +2 -0
  419. package/src/session-runtime/boot/tools.mjs +71 -25
  420. package/src/session-runtime/bot-status.mjs +103 -103
  421. package/src/session-runtime/channel-config-api.mjs +1 -0
  422. package/src/session-runtime/config-change-effects.mjs +179 -0
  423. package/src/session-runtime/config-lifecycle/config-writers.mjs +1 -0
  424. package/src/session-runtime/config-lifecycle.mjs +160 -24
  425. package/src/session-runtime/connector-merge-migration.mjs +18 -15
  426. package/src/session-runtime/conversation-import/discovery.mjs +245 -47
  427. package/src/session-runtime/conversation-import/service.mjs +12 -5
  428. package/src/session-runtime/goal-facade-api.mjs +49 -3
  429. package/src/session-runtime/handoff-attachments.mjs +1 -1
  430. package/src/session-runtime/held-requests.mjs +3 -1
  431. package/src/session-runtime/internal-tool-executor/ask-user-tool.mjs +3 -0
  432. package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +3 -2
  433. package/src/session-runtime/internal-tool-executor/feature-tools.mjs +5 -11
  434. package/src/session-runtime/internal-tool-executor/knowledge-tools.mjs +8 -0
  435. package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +161 -120
  436. package/src/session-runtime/internal-tool-executor.mjs +12 -19
  437. package/src/session-runtime/lifecycle/cold-heir.mjs +7 -0
  438. package/src/session-runtime/lifecycle/memory-ingest.mjs +3 -3
  439. package/src/session-runtime/lifecycle/session-switch/session-delete.mjs +53 -5
  440. package/src/session-runtime/lifecycle/session-switch.mjs +13 -2
  441. package/src/session-runtime/lifecycle/teardown/session-close.mjs +10 -5
  442. package/src/session-runtime/lifecycle/teardown.mjs +1 -1
  443. package/src/session-runtime/lifecycle-api.mjs +1 -0
  444. package/src/session-runtime/mcp-glue/server-catalog.mjs +27 -10
  445. package/src/session-runtime/mcp-glue/server-connection.mjs +34 -8
  446. package/src/session-runtime/mcp-glue/server-input.mjs +4 -1
  447. package/src/session-runtime/mixy-heartbeat.mjs +1 -1
  448. package/src/session-runtime/model-route/set-route.mjs +40 -7
  449. package/src/session-runtime/native-web-search/routes.mjs +3 -3
  450. package/src/session-runtime/provider-auth/login.mjs +2 -2
  451. package/src/session-runtime/provider-auth/refresh.mjs +6 -3
  452. package/src/session-runtime/provider-auth/setup.mjs +1 -1
  453. package/src/session-runtime/provider-readiness.mjs +53 -4
  454. package/src/session-runtime/resource-api.mjs +1 -1
  455. package/src/session-runtime/resource-extension-sync.mjs +4 -8
  456. package/src/session-runtime/resource-mcp-api.mjs +98 -35
  457. package/src/session-runtime/resource-mcp-connector-accounts.mjs +49 -32
  458. package/src/session-runtime/resource-mcp-secrets.mjs +27 -10
  459. package/src/session-runtime/resource-mcp-servers.mjs +5 -4
  460. package/src/session-runtime/resource-plugins-api.mjs +4 -0
  461. package/src/session-runtime/routine-executor.mjs +152 -0
  462. package/src/session-runtime/routine-home-turn.mjs +46 -5
  463. package/src/session-runtime/runtime-facade.mjs +5 -0
  464. package/src/session-runtime/runtime-feature-gates.mjs +2 -11
  465. package/src/session-runtime/schedule-session-run.mjs +1 -0
  466. package/src/session-runtime/services/agent-tool/job-task-reconcile.mjs +6 -1
  467. package/src/session-runtime/services/agent-tool/job-views/session-progress.mjs +7 -0
  468. package/src/session-runtime/services/agent-tool/send-flow.mjs +120 -8
  469. package/src/session-runtime/services/agent-tool/spawn-flow/job-start.mjs +12 -0
  470. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-plan.mjs +5 -0
  471. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-prep.mjs +8 -3
  472. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-run.mjs +28 -7
  473. package/src/session-runtime/services/agent-tool.mjs +51 -1
  474. package/src/session-runtime/services/agent-watchdog-registry.mjs +32 -4
  475. package/src/session-runtime/services/channel-admin.mjs +18 -0
  476. package/src/session-runtime/services/channel-worker/daemon-spawn.mjs +2 -0
  477. package/src/session-runtime/services/daemon-candidate.mjs +4 -1
  478. package/src/session-runtime/services/hook-bus/command-handler.mjs +7 -11
  479. package/src/session-runtime/services/memory-runtime-proxy/daemon-spawn.mjs +4 -0
  480. package/src/session-runtime/services/plugin-admin.mjs +14 -6
  481. package/src/session-runtime/services/provider-admin.mjs +281 -10
  482. package/src/session-runtime/services/seeds.mjs +7 -0
  483. package/src/session-runtime/services/usage-stats-model.mjs +32 -11
  484. package/src/session-runtime/session-create/materialize.mjs +4 -2
  485. package/src/session-runtime/session-create/session-options.mjs +2 -0
  486. package/src/session-runtime/session-turn-api.mjs +2 -0
  487. package/src/session-runtime/settings-builtin-tools-api.mjs +5 -10
  488. package/src/session-runtime/settings-system-api.mjs +1 -1
  489. package/src/session-runtime/setup-tool/agent-settings-actions.mjs +13 -3
  490. package/src/session-runtime/setup-tool/connector-widen-approval.mjs +96 -0
  491. package/src/session-runtime/setup-tool/executor.mjs +14 -3
  492. package/src/session-runtime/setup-tool/extended-actions.mjs +2 -0
  493. package/src/session-runtime/setup-tool/settings-contract.mjs +28 -0
  494. package/src/session-runtime/setup-tool/tool-defs.mjs +28 -2
  495. package/src/session-runtime/tool-policy/agent-profile-fold.mjs +40 -43
  496. package/src/session-runtime/tool-policy/mode-switch.mjs +1 -1
  497. package/src/session-runtime/tool-policy/policy-stage.mjs +106 -8
  498. package/src/session-runtime/tool-policy/workflow-overlay.mjs +2 -1
  499. package/src/session-runtime/tool-policy-refresh.mjs +182 -5
  500. package/src/session-runtime/tool-surface.mjs +38 -1
  501. package/src/session-runtime/turn/agent-ops.mjs +33 -2
  502. package/src/session-runtime/turn/session-ops.mjs +2 -0
  503. package/src/session-runtime/turn/turn-run/turn-prepare.mjs +5 -0
  504. package/src/session-runtime/turn/turn-run.mjs +1 -1
  505. package/src/session-runtime/webhook-session-run.mjs +2 -0
  506. package/src/session-runtime/workflow-agents-api/agent-connectors.mjs +46 -11
  507. package/src/session-runtime/workflow-agents-api/agent-route.mjs +2 -0
  508. package/src/session-runtime/workflow-agents-api/instruction-files.mjs +165 -0
  509. package/src/session-runtime/workflow-agents-api/style-and-mode.mjs +5 -4
  510. package/src/session-runtime/workflow-agents-api/workflow-packs.mjs +2 -3
  511. package/src/session-runtime/workflow-agents-api.mjs +2 -0
  512. package/src/session-runtime/workspace/activity-guards.mjs +176 -0
  513. package/src/session-runtime/workspace/project-branches.mjs +1 -1
  514. package/src/session-runtime/workspace/session-view.mjs +149 -0
  515. package/src/session-runtime/workspace/side-checkouts.mjs +203 -0
  516. package/src/session-runtime/workspace/transition-runner.mjs +188 -0
  517. package/src/session-runtime/workspace/transitions.mjs +128 -1070
  518. package/src/session-runtime/workspace/workspace-merge.mjs +132 -0
  519. package/src/session-runtime/workspace/worktree-intents.mjs +242 -0
  520. package/src/session-runtime/workspace/worktree-maintenance.mjs +200 -0
  521. package/src/session-runtime/workspace/worktree-setup.mjs +97 -0
  522. package/src/session-runtime/workspace/worktree-tool.mjs +70 -54
  523. package/src/standalone/daemon-agent-control.mjs +25 -8
  524. package/src/standalone/daemon-desktop-runtime.mjs +8 -2
  525. package/src/standalone/daemon-lag-profiler.mjs +7 -7
  526. package/src/standalone/daemon-session-control.mjs +151 -136
  527. package/src/standalone/daemon.mjs +61 -2
  528. package/src/standalone/desktop-service-registry.mjs +9 -0
  529. package/src/standalone/local-session-runtime.mjs +21 -1
  530. package/src/standalone/session-client/daemon-unavailable.mjs +4 -1
  531. package/src/standalone/session-client.mjs +5 -1
  532. package/src/standalone/session-frame-stream.mjs +83 -11
  533. package/src/standalone/session-protocol.mjs +15 -0
  534. package/src/standalone/session-service/agent-route-follow.mjs +23 -20
  535. package/src/standalone/session-service/agent-tree/agent-turns.mjs +18 -6
  536. package/src/standalone/session-service/agent-tree.mjs +45 -9
  537. package/src/standalone/session-service/projection/transcript-window.mjs +700 -64
  538. package/src/standalone/session-service/quota-resume.mjs +9 -0
  539. package/src/standalone/session-service/session-calls/session-action.mjs +51 -1
  540. package/src/standalone/session-service/session-calls/session-turns.mjs +37 -18
  541. package/src/standalone/session-service/session-calls/session-views.mjs +160 -104
  542. package/src/standalone/session-service/session-calls/turn-gate.mjs +34 -0
  543. package/src/standalone/session-service/session-calls.mjs +2 -1
  544. package/src/standalone/session-service/stored-reader.mjs +127 -40
  545. package/src/tui/App.jsx +162 -164
  546. package/src/tui/app/app-view/floating-panel.jsx +3 -0
  547. package/src/tui/app/app-view/text-entry-labels.mjs +1 -0
  548. package/src/tui/app/clipboard.mjs +22 -11
  549. package/src/tui/app/create-app-pickers.mjs +2 -0
  550. package/src/tui/app/doctor.mjs +2 -2
  551. package/src/tui/app/panel-signature.mjs +1 -1
  552. package/src/tui/app/prompt-handlers/use-prompt-history-nav.mjs +1 -1
  553. package/src/tui/app/prompt-handlers/use-prompt-interrupt.mjs +3 -0
  554. package/src/tui/app/prompt-submit/provider-prompts.mjs +3 -1
  555. package/src/tui/app/provider-setup/api-key-actions.mjs +31 -1
  556. package/src/tui/app/provider-setup/oauth-actions.mjs +25 -6
  557. package/src/tui/app/provider-setup-picker.mjs +20 -13
  558. package/src/tui/app/settings-picker.mjs +53 -8
  559. package/src/tui/app/shell-layout/row-budgets.mjs +14 -12
  560. package/src/tui/app/slash-commands.mjs +2 -1
  561. package/src/tui/app/slash-dispatch/route-commands.mjs +1 -1
  562. package/src/tui/app/slash-dispatch/session-commands.mjs +47 -1
  563. package/src/tui/app/slash-dispatch.mjs +1 -1
  564. package/src/tui/app/use-btw-panel.mjs +29 -0
  565. package/src/tui/app/use-context-panel-refresh.mjs +31 -0
  566. package/src/tui/app/use-model-catalog-cache.mjs +13 -10
  567. package/src/tui/app/use-mouse-input.mjs +11 -0
  568. package/src/tui/app/use-onboarding-start.mjs +8 -3
  569. package/src/tui/app/use-panel-transition.mjs +10 -1
  570. package/src/tui/app/use-pasted-buffers.mjs +28 -20
  571. package/src/tui/app/use-prompt-draft-flow.mjs +7 -0
  572. package/src/tui/app/use-prompt-layout-rows.mjs +3 -3
  573. package/src/tui/app/use-prompt-queue-history.mjs +5 -4
  574. package/src/tui/app/use-selection-focus.mjs +11 -2
  575. package/src/tui/app/use-selection-geometry.mjs +18 -9
  576. package/src/tui/app/use-selection-paint.mjs +4 -4
  577. package/src/tui/app/use-selection-stitch.mjs +3 -3
  578. package/src/tui/app/use-slash-palette.mjs +62 -0
  579. package/src/tui/app/use-terminal-chrome.mjs +2 -2
  580. package/src/tui/app/use-transcript-activity.mjs +48 -33
  581. package/src/tui/app/use-transcript-follow.mjs +12 -4
  582. package/src/tui/app/use-transcript-scroll.mjs +46 -17
  583. package/src/tui/app/use-transcript-swap-reset.mjs +27 -0
  584. package/src/tui/app/use-transcript-window/geometry.mjs +20 -6
  585. package/src/tui/app/use-transcript-window/instance-state.mjs +4 -0
  586. package/src/tui/app/use-transcript-window/selection-shift.mjs +5 -1
  587. package/src/tui/app/use-transcript-window.mjs +21 -11
  588. package/src/tui/app/use-tui-ready.mjs +18 -0
  589. package/src/tui/app/use-welcome-prompt-hint.mjs +5 -0
  590. package/src/tui/app/use-workflow-tab-cycle.mjs +5 -3
  591. package/src/tui/components/Picker.jsx +27 -3
  592. package/src/tui/components/SignInUrl.jsx +68 -0
  593. package/src/tui/components/TextEntryPanel.jsx +76 -46
  594. package/src/tui/components/prompt-input/escape-policy.d.mts +0 -1
  595. package/src/tui/components/prompt-input/escape-policy.mjs +1 -1
  596. package/src/tui/components/question-panel-model.mjs +4 -4
  597. package/src/tui/components/sign-in-url-layout.mjs +24 -0
  598. package/src/tui/components/tool-execution/standard-card.jsx +3 -4
  599. package/src/tui/components/user-message-skills.mjs +1 -1
  600. package/src/tui/dist/index.mjs +2205 -1371
  601. package/src/tui/markdown/render-ansi.mjs +1 -1
  602. package/src/tui/session/agent-job-feed/notification-router.mjs +10 -0
  603. package/src/tui/session/agent-job-feed.mjs +2 -0
  604. package/src/tui/session/context-state.mjs +3 -0
  605. package/src/tui/session/goal-turn-state.mjs +6 -2
  606. package/src/tui/session/quota-resume.mjs +1 -1
  607. package/src/tui/session/session-api/controls.mjs +4 -0
  608. package/src/tui/session/session-api/extensions.mjs +8 -0
  609. package/src/tui/session/session-api/intake/abort.mjs +2 -1
  610. package/src/tui/session/session-api/intake.mjs +2 -0
  611. package/src/tui/session/session-api/integrations.mjs +2 -2
  612. package/src/tui/session/session-api/lifecycle/dispose.mjs +1 -0
  613. package/src/tui/session/session-api/lifecycle/session-reset.mjs +7 -0
  614. package/src/tui/session/session-api/routes-agent-definitions.mjs +6 -0
  615. package/src/tui/session/session-api/settings.mjs +2 -2
  616. package/src/tui/session/session-api/worktree.mjs +13 -1
  617. package/src/tui/session/session-flow/drain.mjs +11 -14
  618. package/src/tui/session/tool-card-results/grouped-result.mjs +2 -2
  619. package/src/tui/session/transcript-spill/spill-writer.mjs +15 -0
  620. package/src/tui/session/transcript-spill.mjs +92 -4
  621. package/src/tui/session/transcript-store.mjs +2 -0
  622. package/src/tui/session/turn-quiet.mjs +1 -1
  623. package/src/tui/session/turn.mjs +3 -0
  624. package/src/tui/session/worktree-setup-notice.mjs +1 -1
  625. package/src/tui/spinner-meta.mjs +3 -3
  626. package/src/tui/spinner-verbs.mjs +2 -2
  627. package/src/defaults/skills/goal-management/SKILL.md +0 -169
  628. package/src/defaults/skills/skill-creator/references/source-review.md +0 -94
  629. package/src/runtime/agent/orchestrator/runtime-core/goal-tasks.mjs +0 -156
  630. package/src/session-runtime/goal-tasks.mjs +0 -1
@@ -73,7 +73,12 @@ export async function collectGarbageNow() {
73
73
  * @param {(message: string) => void} [options.log]
74
74
  * @param {string} [options.label] Log prefix.
75
75
  */
76
- export function createIdleGc({ isBusy, log = () => {}, label = 'idle gc' } = {}) {
76
+ export function createIdleGc({
77
+ isBusy,
78
+ log = () => {},
79
+ label = 'idle gc',
80
+ memoryUsage = () => process.memoryUsage(),
81
+ } = {}) {
77
82
  const enabled = !DISABLED.test(String(process.env.MIXDOG_IDLE_GC || ''));
78
83
  // Long enough that the pause between two turns of one conversation never
79
84
  // triggers a sweep, short enough that a desktop left alone reclaims soon.
@@ -90,6 +95,11 @@ export function createIdleGc({ isBusy, log = () => {}, label = 'idle gc' } = {})
90
95
  // between committed and used is itself a reason to sweep — the collection is
91
96
  // what lets V8 release those pages — so either signal alone arms the sweep.
92
97
  const minSlackBytes = envNumber('MIXDOG_IDLE_GC_MIN_SLACK_MB', 64) * MB;
98
+ // Buffers, ArrayBuffers and external strings live outside the JS heap, so a
99
+ // daemon can sit on gigabytes of dead attachment data behind a tiny heap
100
+ // (external 2.8GB beside heapTotal 7MB was measured) and never trip the heap
101
+ // floors above. Only a collection frees them.
102
+ const minExternalBytes = envNumber('MIXDOG_IDLE_GC_MIN_EXTERNAL_MB', 96) * MB;
93
103
  // Re-sweeping a process that has not allocated since the last sweep only
94
104
  // burns CPU; require real growth (or an announced release, see
95
105
  // noteMemoryRelease) before running again.
@@ -98,6 +108,7 @@ export function createIdleGc({ isBusy, log = () => {}, label = 'idle gc' } = {})
98
108
  let timer = null;
99
109
  let lastBusyAt = Date.now();
100
110
  let lastSweptHeap = 0;
111
+ let lastSweptExternal = 0;
101
112
  let sweptReleaseSeq = releaseSeq;
102
113
  let appliedReleaseAt = lastReleaseAt;
103
114
  let sweeping = false;
@@ -123,12 +134,22 @@ export function createIdleGc({ isBusy, log = () => {}, label = 'idle gc' } = {})
123
134
  lastBusyAt = Math.max(lastBusyAt, Math.min(lastReleaseAt, Date.now()));
124
135
  }
125
136
  if (Date.now() - lastBusyAt < idleMs) return 'settling';
126
- const usageBefore = process.memoryUsage();
137
+ const usageBefore = memoryUsage();
127
138
  const before = usageBefore.heapUsed;
139
+ const externalBefore = usageBefore.external || 0;
128
140
  const slackBefore = Math.max(0, usageBefore.heapTotal - before);
129
- if (before < minHeapBytes && slackBefore < minSlackBytes) return 'small';
141
+ if (before < minHeapBytes && slackBefore < minSlackBytes && externalBefore < minExternalBytes) {
142
+ return 'small';
143
+ }
130
144
  const released = releaseSeq !== sweptReleaseSeq;
131
- if (lastSweptHeap && !released && before < lastSweptHeap + growthBytes) return 'unchanged';
145
+ if (
146
+ lastSweptHeap &&
147
+ !released &&
148
+ before < lastSweptHeap + growthBytes &&
149
+ externalBefore < lastSweptExternal + growthBytes
150
+ ) {
151
+ return 'unchanged';
152
+ }
132
153
 
133
154
  sweeping = true;
134
155
  const releaseSeqAtSweep = releaseSeq;
@@ -139,9 +160,10 @@ export function createIdleGc({ isBusy, log = () => {}, label = 'idle gc' } = {})
139
160
  disarm();
140
161
  return 'unavailable';
141
162
  }
142
- const usageAfter = process.memoryUsage();
163
+ const usageAfter = memoryUsage();
143
164
  const after = usageAfter.heapUsed;
144
165
  lastSweptHeap = after;
166
+ lastSweptExternal = usageAfter.external || 0;
145
167
  // Releases announced while this sweep ran still get their own.
146
168
  sweptReleaseSeq = releaseSeqAtSweep;
147
169
  const mb = (bytes) => (bytes / MB).toFixed(1);
@@ -150,7 +172,8 @@ export function createIdleGc({ isBusy, log = () => {}, label = 'idle gc' } = {})
150
172
  log(
151
173
  `${label}: heapUsed ${mb(before)} -> ${mb(after)} MB` +
152
174
  ` (reclaimed ${mb(before - after)} MB) in ${Date.now() - startedAt}ms` +
153
- `, committed ${mb(usageBefore.heapTotal)} -> ${mb(usageAfter.heapTotal)} MB`
175
+ `, committed ${mb(usageBefore.heapTotal)} -> ${mb(usageAfter.heapTotal)} MB` +
176
+ `, external ${mb(externalBefore)} -> ${mb(usageAfter.external || 0)} MB`
154
177
  );
155
178
  return 'swept';
156
179
  } catch (e) {
@@ -185,6 +208,6 @@ export function createIdleGc({ isBusy, log = () => {}, label = 'idle gc' } = {})
185
208
  },
186
209
  /** Drives one cycle synchronously for tests; returns the decision taken. */
187
210
  _tickForTest: tick,
188
- _configForTest: { enabled, idleMs, checkMs, minHeapBytes, minSlackBytes, growthBytes },
211
+ _configForTest: { enabled, idleMs, checkMs, minHeapBytes, minSlackBytes, minExternalBytes, growthBytes },
189
212
  };
190
213
  }
@@ -133,7 +133,12 @@ export function priceUsage(args) {
133
133
  // premium request needs the model's published Fast/Priority rates.
134
134
  const anthropicFast = premium && sentTier === 'fast' && supportsAnthropicFastMode(identity.pricingModel);
135
135
  const premiumPricing = sentTier === 'ultrafast' ? meta.ultrafastPricing : meta.fastPricing;
136
- const rateMeta = premium && !anthropicFast ? premiumPricing || {} : meta;
136
+ // A request the server reports as served on Flex (Vertex Flex PayGo can be
137
+ // served by Provisioned Throughput first) bills the catalog's flex columns.
138
+ const flex = args.serviceTier === 'flex';
139
+ let rateMeta = meta;
140
+ if (flex) rateMeta = meta.flexPricing || {};
141
+ else if (premium && !anthropicFast) rateMeta = premiumPricing || {};
137
142
  if (args.historicalAggregate && rateMeta.pricingTiers?.some((tier) => promptTokens > tier.aboveInputTokens)) {
138
143
  // A daily sum cannot establish which individual requests crossed a
139
144
  // context boundary. Do not price the whole day as one huge prompt.
@@ -20,6 +20,7 @@
20
20
  */
21
21
 
22
22
  import { createRequire } from 'node:module';
23
+ import { BlockList, isIP } from 'node:net';
23
24
 
24
25
  const require = createRequire(import.meta.url);
25
26
  let _undici = null;
@@ -30,6 +31,8 @@ function undici() {
30
31
 
31
32
  let _agent = null;
32
33
  let _globalInstalled = false;
34
+ /** The system-proxy router (adoptPrivateProxy), installed as the global dispatcher. */
35
+ let _router = null;
33
36
 
34
37
  function envInt(name, fallback) {
35
38
  const raw = process.env[name];
@@ -57,10 +60,12 @@ function envInt(name, fallback) {
57
60
  */
58
61
  function proxyConfigured() {
59
62
  const env = process.env;
60
- if (env.HTTP_PROXY || env.HTTPS_PROXY || env.http_proxy || env.https_proxy) return true;
63
+ if (PROXY_VARS.some((name) => env[name])) return true;
61
64
  if (env.NODE_USE_ENV_PROXY) return true;
62
65
  try {
63
66
  const g = undici().getGlobalDispatcher?.();
67
+ // Our own router sends its direct origins to the shared pool below.
68
+ if (_router && g === _router) return false;
64
69
  // Any non-default global dispatcher (constructor name other than the plain
65
70
  // `Agent` undici installs by default) is treated as custom — ProxyAgent,
66
71
  // EnvHttpProxyAgent, MockAgent, or a user subclass — and we step aside.
@@ -71,6 +76,305 @@ function proxyConfigured() {
71
76
  return false;
72
77
  }
73
78
 
79
+ const PROXY_VARS = ['HTTPS_PROXY', 'https_proxy', 'HTTP_PROXY', 'http_proxy'];
80
+ // Loopback, private (RFC 1918) and link-local IPv4.
81
+ const LOCAL_V4_RANGES = [
82
+ ['127.0.0.0', '127.255.255.255'],
83
+ ['10.0.0.0', '10.255.255.255'],
84
+ ['172.16.0.0', '172.31.255.255'],
85
+ ['192.168.0.0', '192.168.255.255'],
86
+ ['169.254.0.0', '169.254.255.255'],
87
+ ];
88
+ // Loopback, unique-local and link-local IPv6.
89
+ const LOCAL_V6_SUBNETS = [
90
+ ['::1', 128],
91
+ ['fc00::', 7],
92
+ ['fe80::', 10],
93
+ ];
94
+
95
+ /**
96
+ * NO_PROXY for processes that follow the proxy variables natively (children,
97
+ * Node's http module). NO_PROXY matching is by name, suffix or exact address;
98
+ * fetch has no address ranges at all and Node's http module takes `a-b`
99
+ * ranges, so this list is a fallback: in-process, isLocalHost decides.
100
+ */
101
+ export const LOCAL_NO_PROXY = [
102
+ 'localhost',
103
+ '127.0.0.1',
104
+ '::1',
105
+ '.local',
106
+ ...LOCAL_V4_RANGES.map(([start, end]) => `${start}-${end}`),
107
+ ].join(',');
108
+
109
+ let _localAddresses = null;
110
+ function localAddresses() {
111
+ if (!_localAddresses) {
112
+ _localAddresses = new BlockList();
113
+ for (const [start, end] of LOCAL_V4_RANGES) _localAddresses.addRange(start, end, 'ipv4');
114
+ for (const [network, prefix] of LOCAL_V6_SUBNETS) _localAddresses.addSubnet(network, prefix, 'ipv6');
115
+ }
116
+ return _localAddresses;
117
+ }
118
+
119
+ export function normalizeHost(hostname) {
120
+ return String(hostname)
121
+ .replace(/^\[(.*)\]$/, '$1')
122
+ .replace(/\.$/, '')
123
+ .toLowerCase();
124
+ }
125
+
126
+ /**
127
+ * A host that never goes through the proxy: a loopback, private or
128
+ * link-local address, a dotless name (`localhost`, a LAN machine) or a
129
+ * `.local` / `.localhost` name — local providers and LAN services.
130
+ */
131
+ export function isLocalHost(hostname) {
132
+ const host = normalizeHost(hostname);
133
+ const family = isIP(host);
134
+ if (family) return localAddresses().check(host, family === 4 ? 'ipv4' : 'ipv6');
135
+ return !host.includes('.') || host.endsWith('.local') || host.endsWith('.localhost');
136
+ }
137
+
138
+ /**
139
+ * `env` plus what Node needs to honour its proxy variables: NODE_USE_ENV_PROXY
140
+ * (Node ignores HTTPS_PROXY without it) and a local NO_PROXY. Unchanged when
141
+ * no proxy variable is set or the user set NODE_USE_ENV_PROXY / NO_PROXY.
142
+ */
143
+ export function withEnvProxy(env) {
144
+ if (env.NODE_USE_ENV_PROXY !== undefined || !PROXY_VARS.some((name) => env[name])) return env;
145
+ const noProxy = env.NO_PROXY || env.no_proxy ? {} : { NO_PROXY: LOCAL_NO_PROXY };
146
+ return { ...env, NODE_USE_ENV_PROXY: '1', ...noProxy };
147
+ }
148
+
149
+ /**
150
+ * The global dispatcher under a proxy: local and LAN hosts (isLocalHost, which
151
+ * includes every dotless name) connect directly, every other host follows the
152
+ * proxy variables and NO_PROXY. `direct` and `proxied` replace the two inner
153
+ * dispatchers (tests).
154
+ */
155
+ export function createProxyDispatcher({ direct = null, proxied = null } = {}) {
156
+ const { Agent, Dispatcher, EnvHttpProxyAgent } = undici();
157
+ class LocalBypassProxyAgent extends Dispatcher {
158
+ #direct = direct ?? new Agent();
159
+ #proxied = proxied ?? new EnvHttpProxyAgent();
160
+
161
+ dispatch(opts, handler) {
162
+ const { hostname } = new URL(opts.origin);
163
+ return (isLocalHost(hostname) ? this.#direct : this.#proxied).dispatch(opts, handler);
164
+ }
165
+
166
+ async close() {
167
+ await Promise.all([this.#direct.close(), this.#proxied.close()]);
168
+ }
169
+
170
+ async destroy(error) {
171
+ await Promise.all([this.#direct.destroy(error), this.#proxied.destroy(error)]);
172
+ }
173
+ }
174
+ return new LocalBypassProxyAgent();
175
+ }
176
+
177
+ let _envProxyAdopted = false;
178
+
179
+ /**
180
+ * Honour proxy variables in this already-running process (createProxyDispatcher
181
+ * as the global dispatcher) and, through the inherited env, in every child it
182
+ * spawns. No-op without a proxy variable, when the user set NODE_USE_ENV_PROXY
183
+ * to anything but 1, or once adopted.
184
+ */
185
+ export function adoptEnvProxy(env = process.env) {
186
+ const next = withEnvProxy(env);
187
+ if (_envProxyAdopted || next.NODE_USE_ENV_PROXY !== '1' || !PROXY_VARS.some((name) => next[name])) return false;
188
+ env.NODE_USE_ENV_PROXY = '1';
189
+ if (next.NO_PROXY !== undefined) env.NO_PROXY = next.NO_PROXY;
190
+ undici().setGlobalDispatcher(createProxyDispatcher());
191
+ _envProxyAdopted = true;
192
+ return true;
193
+ }
194
+
195
+ /** A request the router could not hand to a leg fails through its handler. */
196
+ function failDispatch(handler, error) {
197
+ if (typeof handler.onResponseError === 'function') handler.onResponseError(null, error);
198
+ else handler.onError?.(error);
199
+ }
200
+
201
+ const RESPONSE_CALLBACKS = [
202
+ 'onRequestUpgrade',
203
+ 'onResponseStart',
204
+ 'onResponseData',
205
+ 'onResponseEnd',
206
+ 'onResponseError',
207
+ ];
208
+
209
+ /**
210
+ * Start a request whose leg is not known yet: its handler gets a controller at
211
+ * once, so an abort while the route is looked up settles it right away instead
212
+ * of when the lookup answers. Returns the handler to give the leg (which binds
213
+ * the controller to the real request), or null once aborted. Legacy handlers
214
+ * (no onRequestStart) start with the leg as before.
215
+ */
216
+ function startDeferred(handler) {
217
+ if (typeof handler.onRequestStart !== 'function') return () => handler;
218
+ let inner = null;
219
+ let reason = null;
220
+ const controller = {
221
+ get aborted() {
222
+ return inner ? inner.aborted : reason !== null;
223
+ },
224
+ get paused() {
225
+ return inner?.paused ?? false;
226
+ },
227
+ get reason() {
228
+ return inner ? inner.reason : reason;
229
+ },
230
+ get rawHeaders() {
231
+ return inner?.rawHeaders;
232
+ },
233
+ get rawTrailers() {
234
+ return inner?.rawTrailers;
235
+ },
236
+ abort(cause) {
237
+ if (inner) return inner.abort(cause);
238
+ if (reason !== null) return;
239
+ reason = cause ?? new (undici().errors.RequestAbortedError)();
240
+ handler.onResponseError?.(controller, reason);
241
+ },
242
+ pause() {
243
+ inner?.pause();
244
+ },
245
+ resume() {
246
+ inner?.resume();
247
+ },
248
+ };
249
+ handler.onRequestStart(controller, {});
250
+ const forwarded = {
251
+ onRequestStart(real) {
252
+ inner = real;
253
+ },
254
+ };
255
+ for (const name of RESPONSE_CALLBACKS) {
256
+ if (typeof handler[name] === 'function') forwarded[name] = (...args) => handler[name](...args);
257
+ }
258
+ return () => (reason === null ? forwarded : null);
259
+ }
260
+
261
+ /**
262
+ * A dispatcher that routes each origin on its own: local and LAN hosts connect
263
+ * directly without asking, every other origin by `route(origin)` — `{ proxy }`
264
+ * (a proxy URL, or null for direct), or a promise of one, which the request
265
+ * waits for. A request aborted meanwhile settles at once and is never sent.
266
+ * `direct()` gives the direct leg (read per request: the pool can be replaced),
267
+ * `proxied(uri)` builds the leg of one proxy, kept for reuse.
268
+ */
269
+ export function createRoutedProxyDispatcher({
270
+ route,
271
+ direct = null,
272
+ proxied = (uri) => new (undici().ProxyAgent)({ uri }),
273
+ }) {
274
+ const { Agent, Dispatcher } = undici();
275
+ let ownDirect = null;
276
+ const directLeg = direct ?? (() => (ownDirect ??= new Agent()));
277
+ class SystemProxyRouter extends Dispatcher {
278
+ #proxied = new Map();
279
+
280
+ #leg(decision) {
281
+ const uri = decision?.proxy;
282
+ if (!uri) return directLeg();
283
+ let leg = this.#proxied.get(uri);
284
+ if (!leg) {
285
+ leg = proxied(uri);
286
+ this.#proxied.set(uri, leg);
287
+ }
288
+ return leg;
289
+ }
290
+
291
+ dispatch(opts, handler) {
292
+ const url = new URL(opts.origin);
293
+ const decided = isLocalHost(url.hostname) ? null : route(url.origin);
294
+ if (typeof decided?.then !== 'function') return this.#leg(decided).dispatch(opts, handler);
295
+ const started = startDeferred(handler);
296
+ decided
297
+ .then(
298
+ (decision) => decision,
299
+ () => null
300
+ )
301
+ .then((decision) => {
302
+ const legHandler = started();
303
+ if (!legHandler) return;
304
+ try {
305
+ this.#leg(decision).dispatch(opts, legHandler);
306
+ } catch (error) {
307
+ failDispatch(legHandler, error);
308
+ }
309
+ });
310
+ return true;
311
+ }
312
+
313
+ async close() {
314
+ await Promise.all([directLeg().close(), ...[...this.#proxied.values()].map((leg) => leg.close())]);
315
+ }
316
+
317
+ async destroy(error) {
318
+ await Promise.all([directLeg().destroy(error), ...[...this.#proxied.values()].map((leg) => leg.destroy(error))]);
319
+ }
320
+ }
321
+ return new SystemProxyRouter();
322
+ }
323
+
324
+ /**
325
+ * Route this process's fetch per origin by a proxy decision that came from the
326
+ * OS rather than from the user's environment (system-proxy.mjs): `route` as in
327
+ * createRoutedProxyDispatcher. It lives in the dispatcher only: no proxy
328
+ * variable is written, so shells, tools and other CLIs this process spawns see
329
+ * none. Direct origins use the shared LLM pool and every proxy leg its
330
+ * settings. No-op once a proxy is adopted.
331
+ */
332
+ export function adoptPrivateProxy(route) {
333
+ if (_envProxyAdopted) return false;
334
+ const router = createRoutedProxyDispatcher({
335
+ route,
336
+ direct: llmAgent,
337
+ proxied: (uri) => new (undici().ProxyAgent)({ ...llmAgentOptions(), uri }),
338
+ });
339
+ undici().setGlobalDispatcher(router);
340
+ _router = router;
341
+ _envProxyAdopted = true;
342
+ return true;
343
+ }
344
+
345
+ function llmAgentOptions() {
346
+ return {
347
+ keepAliveTimeout: envInt('MIXDOG_LLM_KEEPALIVE_MS', 60_000),
348
+ keepAliveMaxTimeout: envInt('MIXDOG_LLM_KEEPALIVE_MAX_MS', 90_000),
349
+ // No per-origin socket cap by default: each streaming (SSE) response
350
+ // holds its HTTP/1.1 socket for the whole generation, so a cap of N
351
+ // queued the (N+1)th concurrent agent until another finished. Rate
352
+ // limiting is the server's call (429 → admission cooldown).
353
+ connections: envInt('MIXDOG_LLM_CONNECTIONS', null),
354
+ // undici defaults both of these to 300s, which beheaded the Anthropic
355
+ // NON-STREAMING stall fallback (2026-08-03 regex-chess probe:
356
+ // UND_ERR_HEADERS_TIMEOUT at exactly 300s) — a non-streaming completion
357
+ // sends NO response headers until generation finishes, so a long silent
358
+ // generation legitimately exceeds 300s of header wait. Raise both to
359
+ // 600s: first-byte/idle protection is owned by the app-level watchdogs
360
+ // (provider first-byte + semantic idle + agent stall abort), which all
361
+ // fire below this transport ceiling; this layer is only the last-resort
362
+ // dead-socket bound.
363
+ headersTimeout: envInt('MIXDOG_LLM_HEADERS_TIMEOUT_MS', 600_000),
364
+ bodyTimeout: envInt('MIXDOG_LLM_BODY_TIMEOUT_MS', 600_000),
365
+ };
366
+ }
367
+
368
+ /** The shared LLM pool, created again once closed or destroyed. */
369
+ function llmAgent() {
370
+ if (_agent?.destroyed || _agent?.closed) {
371
+ _agent = null;
372
+ _globalInstalled = false;
373
+ }
374
+ _agent ??= new (undici().Agent)(llmAgentOptions());
375
+ return _agent;
376
+ }
377
+
74
378
  /**
75
379
  * The shared singleton dispatcher for LLM API requests. Created on first use.
76
380
  *
@@ -81,36 +385,12 @@ function proxyConfigured() {
81
385
  * Returns `undefined` when a proxy / any custom (non-default) global dispatcher
82
386
  * is configured, so `fetch({ dispatcher: undefined })` falls back to that
83
387
  * global dispatcher instead of bypassing it. `dispatcher: undefined` is a
84
- * harmless fetch option, so call sites need no change.
388
+ * harmless fetch option, so call sites need no change. Under the system-proxy
389
+ * router (the global dispatcher) the pool is its direct leg.
85
390
  */
86
391
  export function getLlmDispatcher() {
87
- if (proxyConfigured()) return undefined;
88
- if (_agent?.destroyed || _agent?.closed) {
89
- _agent = null;
90
- _globalInstalled = false;
91
- }
92
- if (!_agent) {
93
- _agent = new (undici().Agent)({
94
- keepAliveTimeout: envInt('MIXDOG_LLM_KEEPALIVE_MS', 60_000),
95
- keepAliveMaxTimeout: envInt('MIXDOG_LLM_KEEPALIVE_MAX_MS', 90_000),
96
- // No per-origin socket cap by default: each streaming (SSE) response
97
- // holds its HTTP/1.1 socket for the whole generation, so a cap of N
98
- // queued the (N+1)th concurrent agent until another finished. Rate
99
- // limiting is the server's call (429 → admission cooldown).
100
- connections: envInt('MIXDOG_LLM_CONNECTIONS', null),
101
- // undici defaults both of these to 300s, which beheaded the Anthropic
102
- // NON-STREAMING stall fallback (2026-08-03 regex-chess probe:
103
- // UND_ERR_HEADERS_TIMEOUT at exactly 300s) — a non-streaming completion
104
- // sends NO response headers until generation finishes, so a long silent
105
- // generation legitimately exceeds 300s of header wait. Raise both to
106
- // 600s: first-byte/idle protection is owned by the app-level watchdogs
107
- // (provider first-byte + semantic idle + agent stall abort), which all
108
- // fire below this transport ceiling; this layer is only the last-resort
109
- // dead-socket bound.
110
- headersTimeout: envInt('MIXDOG_LLM_HEADERS_TIMEOUT_MS', 600_000),
111
- bodyTimeout: envInt('MIXDOG_LLM_BODY_TIMEOUT_MS', 600_000),
112
- });
113
- }
392
+ if (proxyConfigured() || _router) return undefined;
393
+ llmAgent();
114
394
  // mixdog standalone: separate undici instance from Node's fetch undici, so
115
395
  // a per-request dispatcher throws UND_ERR_INVALID_ARG. Install globally once
116
396
  // and omit the per-request dispatcher. See port-plan D7.
@@ -138,6 +418,13 @@ export function recycleLlmDispatcher() {
138
418
  _agent = null;
139
419
  _globalInstalled = false;
140
420
  _preconnectedAt.clear();
421
+ // The router asks for the pool per request, so the next one gets a new pool.
422
+ if (_router) {
423
+ try {
424
+ old.close().catch(() => {});
425
+ } catch {}
426
+ return true;
427
+ }
141
428
  getLlmDispatcher();
142
429
  if (undici().getGlobalDispatcher() !== _agent) {
143
430
  const unused = _agent;
@@ -155,10 +155,11 @@ function projectLitellmRow(row) {
155
155
  // litellmPricing), not just the base price.
156
156
  for (const [field, value] of Object.entries(row)) {
157
157
  if (
158
- (/^(?:input_cost_per_token|output_cost_per_token|cache_read_input_token_cost|cache_creation_input_token_cost)(?:_above_\d+k_tokens)?(?:_priority|_ultrafast)?$/.test(
158
+ (/^(?:input_cost_per_token|output_cost_per_token|cache_read_input_token_cost|cache_creation_input_token_cost)(?:_above_\d+k_tokens)?(?:_priority|_ultrafast|_flex)?$/.test(
159
159
  field
160
160
  ) ||
161
- /^output_cost_per_second_\w+$/.test(field)) &&
161
+ /^output_cost_per_second_\w+$/.test(field) ||
162
+ field === 'regional_endpoint_uplift_multiplier') &&
162
163
  typeof value === 'number' &&
163
164
  Number.isFinite(value)
164
165
  )
@@ -105,6 +105,7 @@ const _CATALOG_SIMPLE_PREFIXES = [
105
105
  'deepseek/',
106
106
  'openrouter/anthropic/',
107
107
  'openrouter/openai/',
108
+ 'vertex_ai/',
108
109
  ];
109
110
  // Bedrock-style variants: catalog key = <prefix><id>-v1:0
110
111
  const _CATALOG_BEDROCK_PREFIXES = ['anthropic.', 'bedrock/anthropic.'];
@@ -123,6 +124,7 @@ const _PROVIDER_CATALOG_PREFIXES = {
123
124
  xai: ['xai/'],
124
125
  deepseek: ['deepseek/'],
125
126
  azure: ['azure_ai/'],
127
+ 'google-vertex': ['vertex_ai/'],
126
128
  };
127
129
  function _prefixesForProvider(mappedProvider, allPrefixes) {
128
130
  if (!mappedProvider) return allPrefixes;
@@ -438,6 +440,26 @@ const PRICED_VARIANTS = Object.freeze({
438
440
  }),
439
441
  });
440
442
 
443
+ // Vertex AI bills Claude and generally available Gemini 3+ models on regional
444
+ // and multi-region endpoints 10% above the global list price (Standard and
445
+ // Priority alike); the provider marks those requests' SKU `<id>@regional`.
446
+ // https://docs.anthropic.com/en/docs/about-claude/pricing (verified 2026-10-27)
447
+ // https://cloud.google.com/gemini-enterprise-agent-platform/generative-ai/pricing (verified 2026-10-28)
448
+ const VERTEX_REGIONAL_SUFFIX = '@regional';
449
+ function pricedVariant(provider, id) {
450
+ const listed = PRICED_VARIANTS[provider]?.[id];
451
+ if (listed) return listed;
452
+ if (provider === 'vertex-ai' && id.endsWith(VERTEX_REGIONAL_SUFFIX)) {
453
+ // The base row's own uplift wins; the documented 10% applies where the row has none.
454
+ return { base: id.slice(0, -VERTEX_REGIONAL_SUFFIX.length), rateMultiplier: 1.1, rowMultiplier: 'regionalUplift' };
455
+ }
456
+ // A pinned Vertex version (claude-sonnet-4-5@20250929, @default) bills as its
457
+ // model when no row prices the version itself.
458
+ const version = provider === 'vertex-ai' ? id.indexOf('@') : -1;
459
+ if (version > 0) return { base: id.slice(0, version), rateMultiplier: 1 };
460
+ return null;
461
+ }
462
+
441
463
  // Cursor-billed rates no catalog publishes: Cursor's first-party SKUs and Fast
442
464
  // rates Cursor sells beyond the vendor's own catalog. `fast` is the rate of a
443
465
  // request Cursor ran in Fast mode. Other Cursor Fast requests bill at the
@@ -486,6 +508,7 @@ const PRICING_FIELDS = Object.freeze([
486
508
  'pricingTiers',
487
509
  'fastPricing',
488
510
  'ultrafastPricing',
511
+ 'flexPricing',
489
512
  'offPeakMultiplier',
490
513
  'outputImageCostPerM',
491
514
  'outputVideoCostPerM',
@@ -649,17 +672,27 @@ function lookupModelMetadata(originalId, provider, catalog, modelsDevCatalog, li
649
672
  if (source?.relay && !hasRates(meta) && hasRates(guess)) {
650
673
  meta = meta ? { ...meta, ...pricingFields(guess) } : pricingOnly(guess);
651
674
  }
652
- const variant = PRICED_VARIANTS[source?.provider || '']?.[id];
675
+ const variant = pricedVariant(source?.provider || '', id);
653
676
  if (variant && !hasRates(meta)) {
654
677
  const base = lookupModelMetadata(variant.base, provider, catalog, modelsDevCatalog);
655
678
  if (base && PRICING_RATE_KEYS.some((key) => base[key] != null)) {
656
- meta = {
657
- ...meta,
658
- ...scaledRates(base, variant.rateMultiplier),
659
- pricingTiers: (base.pricingTiers || []).map((tier) => ({
679
+ const factor = (variant.rowMultiplier && base[variant.rowMultiplier]) || variant.rateMultiplier;
680
+ const scaled = (rateSet) => ({
681
+ ...scaledRates(rateSet, factor),
682
+ pricingTiers: (rateSet.pricingTiers || []).map((tier) => ({
660
683
  ...tier,
661
- ...scaledRates(tier, variant.rateMultiplier),
684
+ ...scaledRates(tier, factor),
662
685
  })),
686
+ });
687
+ meta = {
688
+ ...meta,
689
+ ...scaled(base),
690
+ // The variant's premium applies to every service tier the base publishes.
691
+ ...Object.fromEntries(
692
+ ['fastPricing', 'ultrafastPricing', 'flexPricing']
693
+ .filter((key) => base[key])
694
+ .map((key) => [key, scaled(base[key])])
695
+ ),
663
696
  pricingSource: base.pricingSource,
664
697
  supportsPromptCaching: base.supportsPromptCaching,
665
698
  };
@@ -740,6 +773,8 @@ function _normalize(entry) {
740
773
  // OpenAI's Priority processing (since renamed Fast mode) columns.
741
774
  const fastPricing = litellmPricing(entry, '_priority');
742
775
  const ultrafastPricing = litellmPricing(entry, '_ultrafast');
776
+ // Flex processing (Vertex Flex PayGo, OpenAI flex) columns.
777
+ const flexPricing = litellmPricing(entry, '_flex');
743
778
  return {
744
779
  contextWindow: entry.max_input_tokens || entry.max_tokens || null,
745
780
  outputTokens: entry.max_output_tokens || null,
@@ -747,7 +782,12 @@ function _normalize(entry) {
747
782
  ...litellmMediaPricing(entry),
748
783
  ...(PRICING_RATE_KEYS.some((key) => fastPricing[key] != null) ? { fastPricing } : {}),
749
784
  ...(PRICING_RATE_KEYS.some((key) => ultrafastPricing[key] != null) ? { ultrafastPricing } : {}),
785
+ ...(PRICING_RATE_KEYS.some((key) => flexPricing[key] != null) ? { flexPricing } : {}),
750
786
  ...(entry.off_peak_multiplier ? { offPeakMultiplier: entry.off_peak_multiplier } : {}),
787
+ // Vertex AI regional / multi-region endpoint premium over the global rate.
788
+ ...(entry.regional_endpoint_uplift_multiplier > 0
789
+ ? { regionalUplift: entry.regional_endpoint_uplift_multiplier }
790
+ : {}),
751
791
  // Tri-state: true/false as declared, undefined when the row is silent.
752
792
  supportsVision: capabilityFlag(entry.supports_vision),
753
793
  supportsFunctionCalling: capabilityFlag(entry.supports_function_calling),
@@ -58,6 +58,9 @@ const PROVIDER_CATALOGS = Object.freeze({
58
58
  anthropic: { modelsDev: 'anthropic', sameEndpoint: true, rosterFiles: ['anthropic-oauth-models.json'] },
59
59
  // generativelanguage.googleapis.com — the endpoint models.dev `google` describes.
60
60
  gemini: { modelsDev: 'google', sameEndpoint: true, rosterFiles: ['gemini-models.json'] },
61
+ // *aiplatform.googleapis.com: Gemini and Claude publisher models, priced by
62
+ // the LiteLLM `vertex_ai/` rows (model-catalog.mjs prefix table).
63
+ 'vertex-ai': { modelsDev: 'google-vertex', sameEndpoint: true },
61
64
  // cli-chat-proxy.grok.com, not api.x.ai.
62
65
  'grok-oauth': {
63
66
  modelsDev: 'xai',