mixdog 1.2.2 → 1.2.4

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 (692) hide show
  1. package/README.md +18 -0
  2. package/package.json +2 -1
  3. package/scripts/gate-local.mjs +6 -4
  4. package/scripts/lib/gate-scheduler.mjs +29 -11
  5. package/scripts/probe-provider-catalog.mjs +31 -0
  6. package/scripts/provider-pingpong-live.mjs +599 -0
  7. package/scripts/session-sweep.mjs +5 -25
  8. package/src/agents/advisor/AGENT.md +1 -1
  9. package/src/agents/advisor/agent.json +1 -1
  10. package/src/agents/maintainer/AGENT.md +1 -1
  11. package/src/agents/maintainer/agent.json +1 -1
  12. package/src/agents/reviewer/AGENT.md +2 -4
  13. package/src/agents/security/AGENT.md +1 -2
  14. package/src/agents/writer/AGENT.md +2 -3
  15. package/src/defaults/shipped-history.json +11 -1
  16. package/src/defaults/skills/image/SKILL.md +21 -23
  17. package/src/defaults/skills/setup/SKILL.md +6 -1
  18. package/src/defaults/skills/setup/references/actions.md +44 -22
  19. package/src/defaults/skills/setup/references/surfaces.md +10 -8
  20. package/src/headless-exec.mjs +15 -8
  21. package/src/lib/keychain-cjs.cjs +20 -15
  22. package/src/output-styles/common.md +11 -10
  23. package/src/rules/agent/AGENT.md +6 -4
  24. package/src/rules/lead/LEAD.md +7 -9
  25. package/src/rules/shared/45-destructive.md +4 -0
  26. package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/preset.mjs +1 -0
  27. package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +28 -7
  28. package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +2 -11
  29. package/src/runtime/agent/orchestrator/agent-trace-io.mjs +92 -61
  30. package/src/runtime/agent/orchestrator/cache-mtime.mjs +10 -1
  31. package/src/runtime/agent/orchestrator/config-providers-merge.mjs +7 -0
  32. package/src/runtime/agent/orchestrator/config.mjs +5 -0
  33. package/src/runtime/agent/orchestrator/context/collect.mjs +1 -0
  34. package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +26 -7
  35. package/src/runtime/agent/orchestrator/context/skill-catalog.mjs +112 -7
  36. package/src/runtime/agent/orchestrator/mcp/child-tree.mjs +101 -23
  37. package/src/runtime/agent/orchestrator/providers/account-pool.mjs +2 -0
  38. package/src/runtime/agent/orchestrator/providers/anthropic-api-key-fetch.mjs +36 -0
  39. package/src/runtime/agent/orchestrator/providers/anthropic-api-request.mjs +48 -20
  40. package/src/runtime/agent/orchestrator/providers/anthropic-error-contract.mjs +3 -1
  41. package/src/runtime/agent/orchestrator/providers/anthropic-max-tokens.mjs +24 -17
  42. package/src/runtime/agent/orchestrator/providers/anthropic-messages.mjs +9 -9
  43. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
  44. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-request/gzip-post.mjs +26 -44
  45. package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +31 -15
  46. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-blocks.mjs +20 -1
  47. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events/content-block-delta.mjs +15 -2
  48. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events/content-block-start.mjs +11 -4
  49. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events/message-events.mjs +3 -0
  50. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events.mjs +12 -5
  51. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-outcome.mjs +1 -0
  52. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-state.mjs +14 -0
  53. package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +2 -0
  54. package/src/runtime/agent/orchestrator/providers/anthropic-turn-result.mjs +9 -0
  55. package/src/runtime/agent/orchestrator/providers/anthropic.mjs +10 -0
  56. package/src/runtime/agent/orchestrator/providers/antigravity-oauth-catalog.mjs +41 -12
  57. package/src/runtime/agent/orchestrator/providers/antigravity-oauth.mjs +13 -1
  58. package/src/runtime/agent/orchestrator/providers/antigravity-request.mjs +131 -9
  59. package/src/runtime/agent/orchestrator/providers/antigravity-response.mjs +29 -10
  60. package/src/runtime/agent/orchestrator/providers/antigravity-retry-policy.mjs +125 -8
  61. package/src/runtime/agent/orchestrator/providers/antigravity-stream.mjs +12 -62
  62. package/src/runtime/agent/orchestrator/providers/antigravity-transport.mjs +117 -41
  63. package/src/runtime/agent/orchestrator/providers/codex-client-meta.mjs +1 -1
  64. package/src/runtime/agent/orchestrator/providers/command-code-oauth.mjs +117 -72
  65. package/src/runtime/agent/orchestrator/providers/compat-request-policy.mjs +78 -2
  66. package/src/runtime/agent/orchestrator/providers/cursor-auth.mjs +39 -5
  67. package/src/runtime/agent/orchestrator/providers/cursor-client-version.mjs +1 -1
  68. package/src/runtime/agent/orchestrator/providers/cursor-native-context.mjs +48 -0
  69. package/src/runtime/agent/orchestrator/providers/cursor-wire-exec.mjs +144 -34
  70. package/src/runtime/agent/orchestrator/providers/cursor-wire-protobuf.mjs +28 -4
  71. package/src/runtime/agent/orchestrator/providers/cursor-wire-request.mjs +8 -4
  72. package/src/runtime/agent/orchestrator/providers/cursor-wire-stream-bridge.mjs +42 -11
  73. package/src/runtime/agent/orchestrator/providers/cursor-wire-stream-messages.mjs +109 -6
  74. package/src/runtime/agent/orchestrator/providers/cursor-wire.mjs +17 -4
  75. package/src/runtime/agent/orchestrator/providers/cursor.mjs +22 -2
  76. package/src/runtime/agent/orchestrator/providers/custom-provider-config.mjs +73 -7
  77. package/src/runtime/agent/orchestrator/providers/custom-provider.mjs +75 -6
  78. package/src/runtime/agent/orchestrator/providers/custom-reasoning.mjs +34 -7
  79. package/src/runtime/agent/orchestrator/providers/custom-tool-wire.mjs +32 -6
  80. package/src/runtime/agent/orchestrator/providers/deepseek.mjs +67 -0
  81. package/src/runtime/agent/orchestrator/providers/effort-configuration.mjs +29 -5
  82. package/src/runtime/agent/orchestrator/providers/gemini-cache-policy.mjs +11 -4
  83. package/src/runtime/agent/orchestrator/providers/gemini-cache.mjs +36 -13
  84. package/src/runtime/agent/orchestrator/providers/gemini-error-contract.mjs +101 -11
  85. package/src/runtime/agent/orchestrator/providers/gemini-request-body.mjs +41 -5
  86. package/src/runtime/agent/orchestrator/providers/gemini-response.mjs +1 -0
  87. package/src/runtime/agent/orchestrator/providers/gemini-rest-stream/watchdogs.mjs +16 -5
  88. package/src/runtime/agent/orchestrator/providers/gemini-retry-policy.mjs +19 -14
  89. package/src/runtime/agent/orchestrator/providers/gemini-schema.mjs +371 -41
  90. package/src/runtime/agent/orchestrator/providers/gemini-sdk-request.mjs +1 -2
  91. package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +97 -49
  92. package/src/runtime/agent/orchestrator/providers/gemini-thinking.mjs +81 -10
  93. package/src/runtime/agent/orchestrator/providers/gemini.mjs +35 -8
  94. package/src/runtime/agent/orchestrator/providers/grok-client-version.mjs +1 -1
  95. package/src/runtime/agent/orchestrator/providers/grok-oauth.mjs +1 -0
  96. package/src/runtime/agent/orchestrator/providers/lib/action-input-contract.mjs +60 -0
  97. package/src/runtime/agent/orchestrator/providers/lib/anthropic-native-blocks.mjs +1 -0
  98. package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +253 -42
  99. package/src/runtime/agent/orchestrator/providers/lib/anthropic-server-tool-usage.mjs +18 -0
  100. package/src/runtime/agent/orchestrator/providers/lib/anthropic-system-blocks.mjs +27 -6
  101. package/src/runtime/agent/orchestrator/providers/lib/claude-bridge-schema.mjs +392 -0
  102. package/src/runtime/agent/orchestrator/providers/lib/inclusive-usage.mjs +54 -0
  103. package/src/runtime/agent/orchestrator/providers/lib/origin-bound-fetch.mjs +16 -0
  104. package/src/runtime/agent/orchestrator/providers/lib/request-compression.mjs +86 -0
  105. package/src/runtime/agent/orchestrator/providers/lib/responses-terminal-fields.mjs +11 -0
  106. package/src/runtime/agent/orchestrator/providers/lib/usage-primitives.mjs +8 -0
  107. package/src/runtime/agent/orchestrator/providers/lib/wire-pairing.mjs +50 -22
  108. package/src/runtime/agent/orchestrator/providers/media-normalization.mjs +133 -21
  109. package/src/runtime/agent/orchestrator/providers/mimo-oauth-profile.mjs +13 -15
  110. package/src/runtime/agent/orchestrator/providers/mimo-oauth.mjs +7 -1
  111. package/src/runtime/agent/orchestrator/providers/model-proxy-channel.d.mts +1 -1
  112. package/src/runtime/agent/orchestrator/providers/model-proxy-channel.mjs +1 -0
  113. package/src/runtime/agent/orchestrator/providers/model-proxy-provider.mjs +92 -16
  114. package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +13 -13
  115. package/src/runtime/agent/orchestrator/providers/openai-codex-metadata.mjs +2 -0
  116. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-send.mjs +133 -62
  117. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/chunk-events.mjs +35 -14
  118. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-result.mjs +5 -2
  119. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-state.mjs +39 -7
  120. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/tool-call-acc.mjs +2 -9
  121. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream.mjs +5 -0
  122. package/src/runtime/agent/orchestrator/providers/openai-compat-error-contract.mjs +1 -1
  123. package/src/runtime/agent/orchestrator/providers/openai-compat-models.mjs +84 -2
  124. package/src/runtime/agent/orchestrator/providers/openai-compat-options.mjs +47 -25
  125. package/src/runtime/agent/orchestrator/providers/openai-compat-presets.mjs +5 -1
  126. package/src/runtime/agent/orchestrator/providers/openai-compat-reasoning-field.mjs +155 -0
  127. package/src/runtime/agent/orchestrator/providers/openai-compat-response-normalization.mjs +40 -24
  128. package/src/runtime/agent/orchestrator/providers/openai-compat-responses-events.mjs +63 -25
  129. package/src/runtime/agent/orchestrator/providers/openai-compat-responses-head-parity.json +2901 -0
  130. package/src/runtime/agent/orchestrator/providers/openai-compat-responses-parity.fixtures.mjs +183 -0
  131. package/src/runtime/agent/orchestrator/providers/openai-compat-responses.mjs +87 -6
  132. package/src/runtime/agent/orchestrator/providers/openai-compat-retry-profile.mjs +51 -3
  133. package/src/runtime/agent/orchestrator/providers/openai-compat-stream.mjs +7 -1
  134. package/src/runtime/agent/orchestrator/providers/openai-compat-trace.mjs +2 -0
  135. package/src/runtime/agent/orchestrator/providers/openai-compat-wire.mjs +103 -26
  136. package/src/runtime/agent/orchestrator/providers/openai-compat-xai-send.mjs +23 -4
  137. package/src/runtime/agent/orchestrator/providers/openai-compat-xai.mjs +11 -6
  138. package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +17 -2
  139. package/src/runtime/agent/orchestrator/providers/openai-direct-request.mjs +15 -23
  140. package/src/runtime/agent/orchestrator/providers/openai-http-sse-request.mjs +64 -52
  141. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events/output-items.mjs +23 -10
  142. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events/terminal-frames.mjs +28 -5
  143. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events.mjs +10 -0
  144. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-items.mjs +18 -7
  145. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-outcome.mjs +4 -0
  146. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-state.mjs +5 -0
  147. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/text-relay.mjs +9 -1
  148. package/src/runtime/agent/orchestrator/providers/openai-model-capabilities.mjs +80 -0
  149. package/src/runtime/agent/orchestrator/providers/openai-oauth-dispatch.mjs +3 -1
  150. package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +7 -0
  151. package/src/runtime/agent/orchestrator/providers/openai-oauth.mjs +7 -1
  152. package/src/runtime/agent/orchestrator/providers/openai-responses-input.mjs +72 -24
  153. package/src/runtime/agent/orchestrator/providers/openai-responses-payload-parity.fixture.json +323 -0
  154. package/src/runtime/agent/orchestrator/providers/openai-responses-payload.mjs +50 -16
  155. package/src/runtime/agent/orchestrator/providers/openai-ws-delta.mjs +7 -19
  156. package/src/runtime/agent/orchestrator/providers/openai-ws-response-state/refusals.mjs +60 -0
  157. package/src/runtime/agent/orchestrator/providers/openai-ws-response-state/tool-calls.mjs +51 -36
  158. package/src/runtime/agent/orchestrator/providers/openai-ws-response-state.mjs +30 -0
  159. package/src/runtime/agent/orchestrator/providers/openai-ws-stream/event-switch.mjs +12 -0
  160. package/src/runtime/agent/orchestrator/providers/openai-ws-stream/terminal-frames.mjs +25 -6
  161. package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +18 -9
  162. package/src/runtime/agent/orchestrator/providers/opencode-go-gemini.mjs +181 -0
  163. package/src/runtime/agent/orchestrator/providers/opencode-go.mjs +78 -70
  164. package/src/runtime/agent/orchestrator/providers/openrouter.mjs +74 -0
  165. package/src/runtime/agent/orchestrator/providers/provider-error-kind.mjs +150 -10
  166. package/src/runtime/agent/orchestrator/providers/registry.mjs +13 -2
  167. package/src/runtime/agent/orchestrator/providers/retry-classification.mjs +7 -1
  168. package/src/runtime/agent/orchestrator/providers/transport-scope.d.mts +6 -0
  169. package/src/runtime/agent/orchestrator/providers/transport-scope.mjs +28 -0
  170. package/src/runtime/agent/orchestrator/providers/wire-gateway.mjs +164 -0
  171. package/src/runtime/agent/orchestrator/providers/wire-route.mjs +522 -0
  172. package/src/runtime/agent/orchestrator/providers/xai-tool-search-head-parity.json +1131 -0
  173. package/src/runtime/agent/orchestrator/providers/xai-tool-search.fixtures.mjs +195 -0
  174. package/src/runtime/agent/orchestrator/runtime-core/ask-user-tool-defs.mjs +104 -0
  175. package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +8 -6
  176. package/src/runtime/agent/orchestrator/runtime-core/deferred-tool-availability.mjs +24 -0
  177. package/src/runtime/agent/orchestrator/runtime-core/effort.mjs +15 -0
  178. package/src/runtime/agent/orchestrator/runtime-core/goal-store.mjs +30 -2
  179. package/src/runtime/agent/orchestrator/runtime-core/goal-turns.mjs +3 -2
  180. package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +8 -3
  181. package/src/runtime/agent/orchestrator/runtime-core/provider-request-snapshot.mjs +7 -3
  182. package/src/runtime/agent/orchestrator/runtime-core/session-title.mjs +21 -1
  183. package/src/runtime/agent/orchestrator/runtime-core/skill-tool-loading.mjs +16 -3
  184. package/src/runtime/agent/orchestrator/runtime-core/tool-bridge-contract.mjs +6 -0
  185. package/src/runtime/agent/orchestrator/runtime-core/tool-bridge.mjs +526 -0
  186. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog-data.mjs +3 -0
  187. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog-schema.mjs +10 -7
  188. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +178 -71
  189. package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +102 -12
  190. package/src/runtime/agent/orchestrator/runtime-core/tool-exposure.mjs +96 -0
  191. package/src/runtime/agent/orchestrator/runtime-core/workflow.mjs +10 -8
  192. package/src/runtime/agent/orchestrator/session/agent-loop.mjs +1 -2
  193. package/src/runtime/agent/orchestrator/session/agent-pool-progress.mjs +24 -0
  194. package/src/runtime/agent/orchestrator/session/cache/tool-result-reuse.mjs +10 -2
  195. package/src/runtime/agent/orchestrator/session/catalog-db/index.mjs +2 -3
  196. package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +5 -11
  197. package/src/runtime/agent/orchestrator/session/catalog-db/worker.mjs +6 -22
  198. package/src/runtime/agent/orchestrator/session/compact/constants.mjs +3 -2
  199. package/src/runtime/agent/orchestrator/session/compact/messages.mjs +16 -93
  200. package/src/runtime/agent/orchestrator/session/compact/runner.mjs +16 -2
  201. package/src/runtime/agent/orchestrator/session/compact/summary-anchor.mjs +5 -0
  202. package/src/runtime/agent/orchestrator/session/compact/user-message-kind.mjs +148 -0
  203. package/src/runtime/agent/orchestrator/session/compaction-archive-capture.mjs +1 -1
  204. package/src/runtime/agent/orchestrator/session/context-tool-schema.mjs +17 -2
  205. package/src/runtime/agent/orchestrator/session/context-utils.mjs +8 -4
  206. package/src/runtime/agent/orchestrator/session/conversation-import/claude.mjs +0 -6
  207. package/src/runtime/agent/orchestrator/session/conversation-import/codex.mjs +0 -6
  208. package/src/runtime/agent/orchestrator/session/eager-dispatch/admission.mjs +3 -2
  209. package/src/runtime/agent/orchestrator/session/eager-dispatch.mjs +6 -1
  210. package/src/runtime/agent/orchestrator/session/historical-session-closure.mjs +10 -0
  211. package/src/runtime/agent/orchestrator/session/loop/assistant-commit.mjs +2 -5
  212. package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +89 -1
  213. package/src/runtime/agent/orchestrator/session/loop/completion-guards.mjs +1 -1
  214. package/src/runtime/agent/orchestrator/session/loop/context-overflow.mjs +56 -0
  215. package/src/runtime/agent/orchestrator/session/loop/deferred-call-through.mjs +18 -8
  216. package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +1 -27
  217. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/output-limit.mjs +1 -1
  218. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/segments.mjs +4 -10
  219. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn.mjs +2 -9
  220. package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +24 -10
  221. package/src/runtime/agent/orchestrator/session/loop/provider-tool-exclusions.mjs +135 -0
  222. package/src/runtime/agent/orchestrator/session/loop/request-boundary.mjs +31 -4
  223. package/src/runtime/agent/orchestrator/session/loop/route-fallback.mjs +76 -0
  224. package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +67 -20
  225. package/src/runtime/agent/orchestrator/session/loop/step-auto-effort.mjs +10 -10
  226. package/src/runtime/agent/orchestrator/session/loop/tool-call-resolution.mjs +95 -0
  227. package/src/runtime/agent/orchestrator/session/loop/tool-classify.mjs +6 -0
  228. package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +30 -3
  229. package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +29 -5
  230. package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +15 -1
  231. package/src/runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs +147 -0
  232. package/src/runtime/agent/orchestrator/session/loop/tool-phase.mjs +7 -5
  233. package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +33 -3
  234. package/src/runtime/agent/orchestrator/session/manager/ask-support.mjs +0 -4
  235. package/src/runtime/agent/orchestrator/session/manager/ask-turn-auto-effort.mjs +23 -2
  236. package/src/runtime/agent/orchestrator/session/manager/ask-turn-commit.mjs +34 -12
  237. package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +54 -13
  238. package/src/runtime/agent/orchestrator/session/manager/ask-turn-failure.mjs +33 -0
  239. package/src/runtime/agent/orchestrator/session/manager/ask-turn-loop-options.mjs +57 -25
  240. package/src/runtime/agent/orchestrator/session/manager/ask-turn-prepare.mjs +11 -0
  241. package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +22 -0
  242. package/src/runtime/agent/orchestrator/session/manager/ask-turn-state.mjs +57 -13
  243. package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +8 -0
  244. package/src/runtime/agent/orchestrator/session/manager/failed-turn-rewind.mjs +16 -0
  245. package/src/runtime/agent/orchestrator/session/manager/pending-messages.mjs +6 -120
  246. package/src/runtime/agent/orchestrator/session/manager/pending-persist-queue.mjs +1 -1
  247. package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +231 -16
  248. package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +42 -49
  249. package/src/runtime/agent/orchestrator/session/manager/runtime-state.mjs +50 -0
  250. package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +47 -17
  251. package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +26 -4
  252. package/src/runtime/agent/orchestrator/session/manager/session-fallback-title.mjs +82 -0
  253. package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +36 -35
  254. package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +29 -13
  255. package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +6 -3
  256. package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +4 -1
  257. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-recovery.mjs +45 -0
  258. package/src/runtime/agent/orchestrator/session/manager.mjs +4 -10
  259. package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +6 -0
  260. package/src/runtime/agent/orchestrator/session/send-instrumentation.mjs +2 -1
  261. package/src/runtime/agent/orchestrator/session/send-with-recovery.mjs +17 -1
  262. package/src/runtime/agent/orchestrator/session/side-question-store.mjs +96 -0
  263. package/src/runtime/agent/orchestrator/session/side-question.mjs +197 -0
  264. package/src/runtime/agent/orchestrator/session/store/lifecycle-barriers.mjs +22 -15
  265. package/src/runtime/agent/orchestrator/session/store/lifecycle-read.mjs +1 -1
  266. package/src/runtime/agent/orchestrator/session/store/listing.mjs +2 -6
  267. package/src/runtime/agent/orchestrator/session/store/live-cache-eviction.mjs +1 -1
  268. package/src/runtime/agent/orchestrator/session/store/live-state.mjs +23 -0
  269. package/src/runtime/agent/orchestrator/session/store/liveness-veto.mjs +46 -37
  270. package/src/runtime/agent/orchestrator/session/store/load-cache.mjs +1 -1
  271. package/src/runtime/agent/orchestrator/session/store/load-session.mjs +1 -1
  272. package/src/runtime/agent/orchestrator/session/store/session-delete.mjs +44 -37
  273. package/src/runtime/agent/orchestrator/session/store/session-observers.mjs +4 -2
  274. package/src/runtime/agent/orchestrator/session/store/session-paths.mjs +59 -0
  275. package/src/runtime/agent/orchestrator/session/store/summary-cache.mjs +1 -1
  276. package/src/runtime/agent/orchestrator/session/store/sweep/stale-sweep.mjs +1 -1
  277. package/src/runtime/agent/orchestrator/session/store/sweep/sweep-finish.mjs +27 -21
  278. package/src/runtime/agent/orchestrator/session/store/sweep/sweep-plan.mjs +0 -8
  279. package/src/runtime/agent/orchestrator/session/store/sweep/sweep-record.mjs +6 -18
  280. package/src/runtime/agent/orchestrator/session/store/sweep/sweep-row.mjs +33 -106
  281. package/src/runtime/agent/orchestrator/session/store/write-admission.mjs +4 -2
  282. package/src/runtime/agent/orchestrator/session/store-agent-worker-pool.mjs +5 -8
  283. package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +136 -196
  284. package/src/runtime/agent/orchestrator/session/store-summary-archived-agent.mjs +34 -15
  285. package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +53 -115
  286. package/src/runtime/agent/orchestrator/session/store-summary-fields.mjs +8 -0
  287. package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +10 -1
  288. package/src/runtime/agent/orchestrator/session/store-summary-locations.mjs +3 -29
  289. package/src/runtime/agent/orchestrator/session/store-summary-reader-catalog-fixture.mjs +1 -1
  290. package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +17 -10
  291. package/src/runtime/agent/orchestrator/session/store-transcript-projection.mjs +9 -20
  292. package/src/runtime/agent/orchestrator/session/store.mjs +22 -19
  293. package/src/runtime/agent/orchestrator/session/tool-batch/execute-call.mjs +12 -12
  294. package/src/runtime/agent/orchestrator/session/tool-batch/finalize.mjs +38 -14
  295. package/src/runtime/agent/orchestrator/session/tool-batch/pre-dispatch.mjs +15 -4
  296. package/src/runtime/agent/orchestrator/session/tool-batch/record-outcome.mjs +1 -1
  297. package/src/runtime/agent/orchestrator/session/tool-batch/state.mjs +7 -1
  298. package/src/runtime/agent/orchestrator/session/tool-result-offload.mjs +4 -0
  299. package/src/runtime/agent/orchestrator/session/tool-schema-rejection.mjs +79 -0
  300. package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +72 -15
  301. package/src/runtime/agent/orchestrator/session/turn-failure.mjs +45 -0
  302. package/src/runtime/agent/orchestrator/stall-policy.mjs +50 -0
  303. package/src/runtime/agent/orchestrator/tools/bash-policy-scan.mjs +8 -2
  304. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/command-preflight.mjs +3 -3
  305. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/completed-result.mjs +5 -1
  306. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/inline-hoist.mjs +6 -2
  307. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +4 -1
  308. package/src/runtime/agent/orchestrator/tools/builtin/external-tool-adapters.mjs +218 -20
  309. package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +160 -39
  310. package/src/runtime/agent/orchestrator/tools/builtin/git-partial-stage.mjs +7 -5
  311. package/src/runtime/agent/orchestrator/tools/builtin/grep-formatting.mjs +14 -5
  312. package/src/runtime/agent/orchestrator/tools/builtin/lib/grep-context-expander.mjs +4 -3
  313. package/src/runtime/agent/orchestrator/tools/builtin/lib/grep-output.mjs +2 -1
  314. package/src/runtime/agent/orchestrator/tools/builtin/lib/grep-path-fanout.mjs +48 -44
  315. package/src/runtime/agent/orchestrator/tools/builtin/lib/search-input-helpers.mjs +10 -3
  316. package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-job-records.mjs +247 -49
  317. package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-task-output.mjs +5 -4
  318. package/src/runtime/agent/orchestrator/tools/builtin/read-formatting.mjs +6 -1
  319. package/src/runtime/agent/orchestrator/tools/builtin/runtime-capabilities.mjs +23 -1
  320. package/src/runtime/agent/orchestrator/tools/builtin/shell-analysis.mjs +20 -0
  321. package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +101 -2
  322. package/src/runtime/agent/orchestrator/tools/code-graph/dispatch/root-resolution.mjs +1 -1
  323. package/src/runtime/agent/orchestrator/tools/code-graph/search.mjs +1 -1
  324. package/src/runtime/agent/orchestrator/tools/code-graph-prewarm-worker.mjs +1 -1
  325. package/src/runtime/agent/orchestrator/tools/lib/owned-shell-trees.mjs +67 -0
  326. package/src/runtime/agent/orchestrator/tools/lib/process-table-fixture.mjs +50 -0
  327. package/src/runtime/agent/orchestrator/tools/lib/shell-descendants.mjs +303 -63
  328. package/src/runtime/agent/orchestrator/tools/lib/shell-run-background/promote-job.mjs +2 -0
  329. package/src/runtime/agent/orchestrator/tools/lib/shell-run-settle.mjs +108 -18
  330. package/src/runtime/agent/orchestrator/tools/lib/shell-run-spawn.mjs +77 -11
  331. package/src/runtime/agent/orchestrator/tools/lib/shell-run-state.mjs +81 -5
  332. package/src/runtime/agent/orchestrator/tools/patch/ui-diff.mjs +73 -39
  333. package/src/runtime/agent/orchestrator/tools/progress-message.mjs +18 -1
  334. package/src/runtime/agent/orchestrator/tools/shell-command.mjs +7 -4
  335. package/src/runtime/agent/orchestrator/tools/shell-exec-policy.mjs +88 -12
  336. package/src/runtime/agent/orchestrator/tools/shell-policy.mjs +2 -0
  337. package/src/runtime/attachments/store.d.mts +9 -0
  338. package/src/runtime/attachments/store.mjs +80 -9
  339. package/src/runtime/browser-bridge/browser-action-contract.d.mts +0 -1
  340. package/src/runtime/browser-bridge/browser-action-contract.mjs +0 -2
  341. package/src/runtime/computer-bridge/action-schema.mjs +219 -196
  342. package/src/runtime/computer-bridge/linux-readiness.d.mts +0 -2
  343. package/src/runtime/computer-bridge/linux-readiness.mjs +0 -16
  344. package/src/runtime/effort-judge/judge-client.mjs +21 -4
  345. package/src/runtime/effort-judge/judge-worker.mjs +4 -1
  346. package/src/runtime/github/tool.mjs +208 -17
  347. package/src/runtime/media/adapters/codex-image.mjs +140 -21
  348. package/src/runtime/media/catalog.mjs +4 -4
  349. package/src/runtime/media/chatgpt-usage.mjs +55 -0
  350. package/src/runtime/media/defaults.mjs +37 -0
  351. package/src/runtime/media/jobs.mjs +12 -2
  352. package/src/runtime/media/lanes.mjs +12 -0
  353. package/src/runtime/media/tool-defs.mjs +15 -4
  354. package/src/runtime/media/tool.mjs +41 -12
  355. package/src/runtime/media/upstream-error.mjs +72 -6
  356. package/src/runtime/memory/index.mjs +1 -0
  357. package/src/runtime/memory/lib/http-router/ingest-routes.mjs +22 -1
  358. package/src/runtime/memory/lib/ingest/transcript-offsets.mjs +2 -0
  359. package/src/runtime/memory/lib/ingest/transcript-rows.mjs +1 -0
  360. package/src/runtime/memory/lib/pg/adapter.mjs +98 -1
  361. package/src/runtime/memory/lib/pg/process.mjs +36 -33
  362. package/src/runtime/memory/lib/pg/run-child.mjs +49 -0
  363. package/src/runtime/memory/lib/pg/supervisor.mjs +112 -4
  364. package/src/runtime/memory/lib/runtime-fetcher.mjs +12 -13
  365. package/src/runtime/memory/lib/transcript-ingest.mjs +14 -0
  366. package/src/runtime/office/README.md +1 -1
  367. package/src/runtime/office/authoring/docx-html-runner.mjs +1 -1
  368. package/src/runtime/office/authoring/html-browser.mjs +18 -8
  369. package/src/runtime/office/authoring/html-document-author.mjs +2 -0
  370. package/src/runtime/office/authoring/pdf-html-runner.mjs +1 -1
  371. package/src/runtime/office/authoring/pptx-contact-sheet.mjs +2 -0
  372. package/src/runtime/office/authoring/pptx-html-measure.mjs +3 -1
  373. package/src/runtime/office/authoring/pptx-html-runner.mjs +2 -0
  374. package/src/runtime/office/authoring/xlsx-html-runner.mjs +3 -1
  375. package/src/runtime/office/core/office-actions-read.mjs +3 -0
  376. package/src/runtime/office/core/office-render-preview.mjs +2 -0
  377. package/src/runtime/office/core/office-session-dispatch.mjs +7 -0
  378. package/src/runtime/office/core/office-sessionless-actions.mjs +8 -0
  379. package/src/runtime/office/core/office-sessions.mjs +5 -0
  380. package/src/runtime/office/core/office-transactions.mjs +3 -0
  381. package/src/runtime/office/core/office-write-ledger.mjs +94 -0
  382. package/src/runtime/office/design/library/templates/mixdog-executive.mixdog-edit.pptx +0 -0
  383. package/src/runtime/office/index.mjs +29 -0
  384. package/src/runtime/office/pdf/pdf-analysis.mjs +0 -68
  385. package/src/runtime/office/pdf/pdf-edit-document.mjs +2 -0
  386. package/src/runtime/office/pdf/pdf-render.mjs +23 -7
  387. package/src/runtime/office/pdf/pdf-security.mjs +2 -0
  388. package/src/runtime/office/portable/portable-opc.mjs +4 -1
  389. package/src/runtime/office/quality/visual-diff.mjs +2 -0
  390. package/src/runtime/session-search/session-search-ingest.mjs +1 -1
  391. package/src/runtime/shared/agent-reap-state.mjs +13 -0
  392. package/src/runtime/shared/atomic-file.d.mts +1 -1
  393. package/src/runtime/shared/background-tasks.mjs +6 -1
  394. package/src/runtime/shared/bounded-file-read.mjs +13 -0
  395. package/src/runtime/shared/bounded-line-diff.mjs +191 -0
  396. package/src/runtime/shared/browser-launch.mjs +15 -0
  397. package/src/runtime/shared/buffered-appender.mjs +18 -0
  398. package/src/runtime/shared/config.mjs +78 -18
  399. package/src/runtime/shared/err-text.mjs +48 -4
  400. package/src/runtime/shared/file-lock.mjs +6 -5
  401. package/src/runtime/shared/file-permissions.d.mts +6 -1
  402. package/src/runtime/shared/file-permissions.mjs +54 -6
  403. package/src/runtime/shared/llm/anthropic-betas.mjs +1 -2
  404. package/src/runtime/shared/llm/anthropic-effort.mjs +6 -0
  405. package/src/runtime/shared/llm/provider-model-identities.mjs +1 -0
  406. package/src/runtime/shared/llm/usage-accounting.mjs +5 -2
  407. package/src/runtime/shared/llm/usage-ledger-rollup.mjs +3 -0
  408. package/src/runtime/shared/loopback-listener.mjs +9 -0
  409. package/src/runtime/shared/model-route-chain.d.mts +8 -0
  410. package/src/runtime/shared/model-route-chain.mjs +48 -0
  411. package/src/runtime/shared/model-route-fallback.mjs +22 -0
  412. package/src/runtime/shared/pid-liveness.mjs +12 -0
  413. package/src/runtime/shared/provider-api-key.mjs +8 -0
  414. package/src/runtime/shared/provider-timeout-phase.mjs +17 -0
  415. package/src/runtime/shared/quiet-progress.d.mts +35 -0
  416. package/src/runtime/shared/quiet-progress.mjs +101 -0
  417. package/src/runtime/shared/quota-resume-store.mjs +32 -1
  418. package/src/runtime/shared/read-row-numbers.mjs +44 -0
  419. package/src/runtime/shared/remote-intent.mjs +2 -42
  420. package/src/runtime/shared/review-diff.mjs +52 -0
  421. package/src/runtime/shared/session-sidebar-host.d.mts +4 -0
  422. package/src/runtime/shared/session-sidebar-host.mjs +38 -0
  423. package/src/runtime/shared/slow-span.mjs +121 -0
  424. package/src/runtime/shared/statusline/statusline-segments.mjs +52 -6
  425. package/src/runtime/shared/tool-card-model/card-header.mjs +7 -1
  426. package/src/runtime/shared/tool-card-model/generic-detail.mjs +39 -5
  427. package/src/runtime/shared/tool-card-model.mjs +5 -2
  428. package/src/runtime/shared/tool-output-budget.mjs +2 -0
  429. package/src/runtime/shared/tool-output-limit.mjs +4 -0
  430. package/src/runtime/shared/tool-primitives.mjs +13 -0
  431. package/src/runtime/shared/tool-result-summary.mjs +22 -1
  432. package/src/runtime/shared/tool-status.mjs +3 -2
  433. package/src/runtime/shared/tool-surface.mjs +20 -6
  434. package/src/runtime/shared/tool-work-units.mjs +54 -11
  435. package/src/runtime/shared/transcript-metadata.mjs +49 -1
  436. package/src/runtime/shared/transcript-turn-keys.mjs +33 -0
  437. package/src/runtime/shared/transcript-writer/purge.mjs +74 -0
  438. package/src/runtime/shared/transcript-writer/transcript-file.mjs +10 -1
  439. package/src/runtime/shared/transcript-writer.mjs +24 -6
  440. package/src/runtime/shared/turn-changes.mjs +269 -100
  441. package/src/runtime/shared/turn-review-reply.mjs +8 -39
  442. package/src/runtime/shared/turn-snapshot-store.mjs +19 -108
  443. package/src/runtime/shared/turn-snapshot.mjs +865 -683
  444. package/src/runtime/shared/turn-worktree-snapshot.mjs +183 -255
  445. package/src/runtime/shared/user-data-guard.mjs +262 -49
  446. package/src/runtime/shared/worktrees/activity-gate.mjs +175 -0
  447. package/src/runtime/shared/worktrees/branch-management.mjs +179 -0
  448. package/src/runtime/shared/worktrees/carry.mjs +533 -0
  449. package/src/runtime/shared/worktrees/contract.mjs +60 -0
  450. package/src/runtime/shared/worktrees/dependencies.mjs +456 -0
  451. package/src/runtime/shared/worktrees/file-recovery.mjs +84 -0
  452. package/src/runtime/shared/worktrees/git-head.mjs +214 -0
  453. package/src/runtime/shared/worktrees/git.mjs +8 -3
  454. package/src/runtime/shared/worktrees/include.mjs +125 -7
  455. package/src/runtime/shared/worktrees/lock.mjs +1 -1
  456. package/src/runtime/shared/worktrees/maintenance.mjs +20 -2
  457. package/src/runtime/shared/worktrees/manager.mjs +525 -31
  458. package/src/runtime/shared/worktrees/merge.mjs +31 -21
  459. package/src/runtime/shared/worktrees/owner.mjs +2 -1
  460. package/src/runtime/shared/worktrees/paths.d.mts +6 -0
  461. package/src/runtime/shared/worktrees/preparation-report.mjs +79 -0
  462. package/src/runtime/shared/worktrees/setup-commands.mjs +232 -0
  463. package/src/runtime/shared/worktrees/workspace-visibility.mjs +17 -0
  464. package/src/runtime/terminal-bridge/client.mjs +57 -20
  465. package/src/runtime/terminal-bridge/tool-defs.mjs +13 -6
  466. package/src/runtime/tidy/apply.mjs +47 -2
  467. package/src/runtime/tidy/run-engines.mjs +11 -5
  468. package/src/session-runtime/agent-tool-routing.mjs +19 -13
  469. package/src/session-runtime/boot/apis.mjs +20 -6
  470. package/src/session-runtime/boot/config.mjs +2 -0
  471. package/src/session-runtime/boot/facade.mjs +4 -0
  472. package/src/session-runtime/boot/infrastructure.mjs +6 -1
  473. package/src/session-runtime/boot/session.mjs +3 -3
  474. package/src/session-runtime/boot/tools.mjs +7 -1
  475. package/src/session-runtime/conversation-import/service.mjs +1 -1
  476. package/src/session-runtime/cwd-plugins/cwd-apply.mjs +12 -5
  477. package/src/session-runtime/goal-facade-api.mjs +2 -2
  478. package/src/session-runtime/internal-tool-executor/ask-user-tool.mjs +91 -0
  479. package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +3 -1
  480. package/src/session-runtime/internal-tool-executor/knowledge-tools.mjs +15 -5
  481. package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +137 -26
  482. package/src/session-runtime/internal-tool-executor.mjs +8 -2
  483. package/src/session-runtime/lifecycle/cold-heir.mjs +187 -0
  484. package/src/session-runtime/lifecycle/inheritance.mjs +71 -27
  485. package/src/session-runtime/lifecycle/session-catalog.mjs +25 -18
  486. package/src/session-runtime/lifecycle/session-switch/resume.mjs +6 -0
  487. package/src/session-runtime/lifecycle/session-switch/session-delete.mjs +36 -48
  488. package/src/session-runtime/lifecycle/session-switch.mjs +1 -1
  489. package/src/session-runtime/lifecycle/shared.mjs +5 -6
  490. package/src/session-runtime/lifecycle/teardown/session-close.mjs +6 -5
  491. package/src/session-runtime/lifecycle/teardown.mjs +70 -14
  492. package/src/session-runtime/lifecycle-api.mjs +1 -0
  493. package/src/session-runtime/mcp-glue/connect.mjs +17 -5
  494. package/src/session-runtime/media-api.mjs +8 -0
  495. package/src/session-runtime/model-route/route-ownership.mjs +60 -0
  496. package/src/session-runtime/model-route/route-persist.mjs +3 -2
  497. package/src/session-runtime/model-route/set-route.mjs +116 -36
  498. package/src/session-runtime/model-route/web-search-route.mjs +7 -2
  499. package/src/session-runtime/model-route-api.mjs +4 -2
  500. package/src/session-runtime/native-web-search/routes.mjs +37 -24
  501. package/src/session-runtime/native-web-search-usage.mjs +51 -0
  502. package/src/session-runtime/native-web-search.mjs +19 -9
  503. package/src/session-runtime/new-session-config.mjs +4 -2
  504. package/src/session-runtime/provider-auth/login.mjs +4 -0
  505. package/src/session-runtime/provider-auth/setup.mjs +4 -0
  506. package/src/session-runtime/provider-models/catalog-load.mjs +9 -0
  507. package/src/session-runtime/provider-models/web-search-catalog.mjs +23 -3
  508. package/src/session-runtime/provider-models.mjs +1 -0
  509. package/src/session-runtime/provider-usage.mjs +4 -0
  510. package/src/session-runtime/resource-scope-decorate.mjs +10 -3
  511. package/src/session-runtime/route-resolution.mjs +3 -1
  512. package/src/session-runtime/runtime-core.mjs +4 -0
  513. package/src/session-runtime/runtime-facade.mjs +6 -0
  514. package/src/session-runtime/runtime-review-api.mjs +8 -2
  515. package/src/session-runtime/services/agent-task-status.mjs +2 -0
  516. package/src/session-runtime/services/agent-tool/close-flow/close-all.mjs +0 -3
  517. package/src/session-runtime/services/agent-tool/close-flow.mjs +6 -7
  518. package/src/session-runtime/services/agent-tool/execute-send.mjs +2 -2
  519. package/src/session-runtime/services/agent-tool/execute-spawn.mjs +36 -3
  520. package/src/session-runtime/services/agent-tool/execute.mjs +9 -1
  521. package/src/session-runtime/services/agent-tool/helpers.mjs +30 -7
  522. package/src/session-runtime/services/agent-tool/index-write-queue.mjs +81 -20
  523. package/src/session-runtime/services/agent-tool/job-task-reconcile.mjs +7 -2
  524. package/src/session-runtime/services/agent-tool/job-views/session-progress.mjs +6 -3
  525. package/src/session-runtime/services/agent-tool/lead-worker-index/forgotten-leads.mjs +29 -0
  526. package/src/session-runtime/services/agent-tool/lead-worker-index/index-file.mjs +1 -1
  527. package/src/session-runtime/services/agent-tool/lead-worker-index/lead-rows.mjs +3 -4
  528. package/src/session-runtime/services/agent-tool/lead-worker-index/reap-timers.mjs +9 -3
  529. package/src/session-runtime/services/agent-tool/lead-worker-index/row-settlement.mjs +7 -18
  530. package/src/session-runtime/services/agent-tool/lead-worker-index.mjs +82 -13
  531. package/src/session-runtime/services/agent-tool/model-select.mjs +82 -0
  532. package/src/session-runtime/services/agent-tool/send-flow.mjs +24 -6
  533. package/src/session-runtime/services/agent-tool/spawn-flow/job-start.mjs +3 -1
  534. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-prep.mjs +19 -5
  535. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-run.mjs +5 -4
  536. package/src/session-runtime/services/agent-tool/spawn-flow.mjs +2 -1
  537. package/src/session-runtime/services/agent-tool/spawn-preset.mjs +3 -0
  538. package/src/session-runtime/services/agent-tool/tag-registry/tag-lookup.mjs +1 -3
  539. package/src/session-runtime/services/agent-tool/tag-registry/tag-refresh.mjs +1 -3
  540. package/src/session-runtime/services/agent-tool/tag-registry.mjs +18 -10
  541. package/src/session-runtime/services/agent-tool/terminal-reaper/scan-admission.mjs +8 -41
  542. package/src/session-runtime/services/agent-tool/terminal-reaper/stale-rows.mjs +3 -3
  543. package/src/session-runtime/services/agent-tool/terminal-reaper.mjs +6 -23
  544. package/src/session-runtime/services/agent-tool/terminal-trace.mjs +0 -1
  545. package/src/session-runtime/services/agent-tool/tool-def.mjs +7 -0
  546. package/src/session-runtime/services/agent-tool/worker-index/row-liveness.mjs +32 -20
  547. package/src/session-runtime/services/agent-tool/worker-index/row-shape.mjs +5 -2
  548. package/src/session-runtime/services/agent-tool/worker-index/row-store.mjs +10 -1
  549. package/src/session-runtime/services/agent-tool/worker-index.mjs +74 -15
  550. package/src/session-runtime/services/agent-tool.mjs +7 -0
  551. package/src/session-runtime/services/agent-watchdog-registry.mjs +2 -0
  552. package/src/session-runtime/services/channel-admin.mjs +19 -3
  553. package/src/session-runtime/services/memory-runtime-proxy/calls.mjs +4 -0
  554. package/src/session-runtime/services/memory-runtime-proxy.mjs +1 -0
  555. package/src/session-runtime/services/provider-admin.mjs +158 -15
  556. package/src/session-runtime/session-create/session-options.mjs +7 -5
  557. package/src/session-runtime/session-create/session-start-hook.mjs +2 -1
  558. package/src/session-runtime/session-transcript-purge.mjs +32 -0
  559. package/src/session-runtime/session-transcript.mjs +4 -5
  560. package/src/session-runtime/session-turn-api.mjs +17 -14
  561. package/src/session-runtime/settings-builtin-tools-api.mjs +18 -6
  562. package/src/session-runtime/setup-tool/executor.mjs +57 -9
  563. package/src/session-runtime/setup-tool/extended-actions.mjs +86 -6
  564. package/src/session-runtime/setup-tool/settings-contract.mjs +18 -3
  565. package/src/session-runtime/setup-tool/tool-defs.mjs +25 -4
  566. package/src/session-runtime/skills-api.mjs +3 -5
  567. package/src/session-runtime/tool-policy-refresh.mjs +83 -32
  568. package/src/session-runtime/tool-surface.mjs +5 -1
  569. package/src/session-runtime/turn/agent-ops.mjs +49 -2
  570. package/src/session-runtime/turn/compaction-gate.mjs +25 -0
  571. package/src/session-runtime/turn/session-ops.mjs +7 -5
  572. package/src/session-runtime/turn/side-question-ops.mjs +19 -0
  573. package/src/session-runtime/turn/turn-run/ask-callbacks.mjs +7 -1
  574. package/src/session-runtime/turn/turn-run/turn-prepare.mjs +12 -3
  575. package/src/session-runtime/turn/turn-run/turn-settle.mjs +18 -2
  576. package/src/session-runtime/turn/turn-run/turn-timing.mjs +4 -3
  577. package/src/session-runtime/turn/turn-run.mjs +26 -45
  578. package/src/session-runtime/usage-stats-api.mjs +46 -11
  579. package/src/session-runtime/workflow-agents-api/agent-route.mjs +16 -1
  580. package/src/session-runtime/workspace/admission-gate.mjs +44 -15
  581. package/src/session-runtime/workspace/project-branches.mjs +35 -41
  582. package/src/session-runtime/workspace/transition-steps.mjs +215 -116
  583. package/src/session-runtime/workspace/transitions.mjs +428 -73
  584. package/src/standalone/channel-transport.mjs +3 -4
  585. package/src/standalone/daemon-agent-control.mjs +9 -1
  586. package/src/standalone/daemon-desktop-runtime.mjs +32 -1
  587. package/src/standalone/daemon-local-session-bridge.mjs +14 -1
  588. package/src/standalone/daemon-owner.mjs +17 -4
  589. package/src/standalone/daemon-pg-stop.mjs +49 -0
  590. package/src/standalone/daemon-session-control.mjs +88 -0
  591. package/src/standalone/daemon-stop-budget.d.mts +2 -0
  592. package/src/standalone/daemon-stop-budget.mjs +18 -0
  593. package/src/standalone/daemon-stored-session-views.mjs +25 -3
  594. package/src/standalone/daemon-telemetry.mjs +19 -0
  595. package/src/standalone/daemon.mjs +63 -1
  596. package/src/standalone/desktop-service-registry.mjs +5 -0
  597. package/src/standalone/local-session-runtime.mjs +80 -30
  598. package/src/standalone/session-client.mjs +42 -0
  599. package/src/standalone/session-protocol.mjs +14 -0
  600. package/src/standalone/session-proxy/projection.mjs +41 -4
  601. package/src/standalone/session-runtime-inline-host/boot-loaders.mjs +15 -1
  602. package/src/standalone/session-runtime-inline-host.mjs +3 -0
  603. package/src/standalone/session-service/agent-tree/agent-cancel.mjs +91 -49
  604. package/src/standalone/session-service/agent-tree/agent-child.mjs +19 -1
  605. package/src/standalone/session-service/agent-tree/agent-registry.mjs +25 -0
  606. package/src/standalone/session-service/agent-tree/agent-turns.mjs +9 -1
  607. package/src/standalone/session-service/agent-tree.mjs +28 -2
  608. package/src/standalone/session-service/entries/session-loads.mjs +16 -5
  609. package/src/standalone/session-service/entries.mjs +1 -0
  610. package/src/standalone/session-service/projection/transcript-window.mjs +39 -0
  611. package/src/standalone/session-service/quota-resume.mjs +28 -13
  612. package/src/standalone/session-service/session-calls/session-action.mjs +18 -3
  613. package/src/standalone/session-service/session-calls/session-turns.mjs +17 -6
  614. package/src/standalone/session-service/session-calls/session-views.mjs +6 -0
  615. package/src/standalone/session-service-api.mjs +6 -1
  616. package/src/standalone/session-state-patch.d.mts +2 -1
  617. package/src/standalone/session-state-patch.mjs +41 -1
  618. package/src/standalone/session-tool-output.mjs +82 -0
  619. package/src/tui/App.jsx +25 -0
  620. package/src/tui/app/app-view/floating-panel.jsx +26 -1
  621. package/src/tui/app/app-view.jsx +2 -1
  622. package/src/tui/app/btw-controller.mjs +118 -0
  623. package/src/tui/app/create-app-pickers.mjs +2 -0
  624. package/src/tui/app/provider-setup/provider-items.mjs +8 -0
  625. package/src/tui/app/provider-setup-picker.mjs +15 -3
  626. package/src/tui/app/shell-layout/row-budgets.mjs +11 -1
  627. package/src/tui/app/shell-layout/surfaces.mjs +3 -1
  628. package/src/tui/app/slash-commands.mjs +19 -3
  629. package/src/tui/app/slash-dispatch/session-commands.mjs +68 -6
  630. package/src/tui/app/use-global-key-input/approval-shortcut.mjs +12 -0
  631. package/src/tui/app/use-global-key-input.mjs +5 -12
  632. package/src/tui/app/use-prompt-handlers.mjs +11 -0
  633. package/src/tui/components/BtwPanel.jsx +53 -0
  634. package/src/tui/components/QuestionPanel.jsx +275 -0
  635. package/src/tui/components/Spinner.jsx +4 -0
  636. package/src/tui/components/SpinnerByline.jsx +21 -2
  637. package/src/tui/components/question-panel-model.mjs +156 -0
  638. package/src/tui/components/status-line/local-line.mjs +10 -2
  639. package/src/tui/dist/index.mjs +2897 -1722
  640. package/src/tui/session/active-tool-summary.mjs +1 -1
  641. package/src/tui/session/context-state.mjs +4 -5
  642. package/src/tui/session/goal-continuation/continuation-queue.mjs +2 -3
  643. package/src/tui/session/goal-continuation/deadline-delivery.mjs +4 -2
  644. package/src/tui/session/goal-continuation/session-boundary.mjs +21 -0
  645. package/src/tui/session/quota-resume.mjs +140 -61
  646. package/src/tui/session/session-api/commands.mjs +14 -10
  647. package/src/tui/session/session-api/controls.mjs +14 -2
  648. package/src/tui/session/session-api/integrations.mjs +9 -2
  649. package/src/tui/session/session-api/lifecycle/dispose.mjs +3 -9
  650. package/src/tui/session/session-api/lifecycle/resume.mjs +2 -7
  651. package/src/tui/session/session-api/lifecycle.mjs +14 -11
  652. package/src/tui/session/session-api/media.mjs +2 -0
  653. package/src/tui/session/session-api/routes.mjs +81 -57
  654. package/src/tui/session/session-api/settings.mjs +9 -3
  655. package/src/tui/session/session-api/worktree.mjs +3 -2
  656. package/src/tui/session/session-api.mjs +1 -0
  657. package/src/tui/session/session-flow/auto-clear.mjs +1 -3
  658. package/src/tui/session/session-flow/drain.mjs +6 -4
  659. package/src/tui/session/session-flow/queue/entry-shape.mjs +2 -0
  660. package/src/tui/session/session-flow/queue/take-entries.mjs +2 -1
  661. package/src/tui/session/session-flow/queue.mjs +1 -1
  662. package/src/tui/session/tool-approval.mjs +20 -8
  663. package/src/tui/session/transcript-spill.mjs +14 -7
  664. package/src/tui/session/transcript-store/streaming-tail.mjs +1 -1
  665. package/src/tui/session/tui-steering-persist.mjs +3 -5
  666. package/src/tui/session/turn-quiet.mjs +53 -0
  667. package/src/tui/session/turn-stream.mjs +179 -32
  668. package/src/tui/session/turn.mjs +50 -36
  669. package/src/tui/session/worktree-setup-notice.mjs +38 -0
  670. package/src/tui/spinner-meta.mjs +10 -0
  671. package/src/tui/spinner-verbs.mjs +3 -0
  672. package/src/ui/statusline.mjs +13 -3
  673. package/src/workflows/default/WORKFLOW.md +3 -1
  674. package/src/runtime/agent/orchestrator/providers/model-pricing-rates.mjs +0 -1
  675. package/src/runtime/agent/orchestrator/session/manager/foreign-pending-messages.mjs +0 -346
  676. package/src/runtime/agent/orchestrator/session/manager/session-owner-liveness.mjs +0 -117
  677. package/src/runtime/agent/orchestrator/session/store/paths-heartbeat.mjs +0 -246
  678. package/src/session-runtime/services/agent-tool/terminal-reaper/reap-timers.mjs +0 -142
  679. package/src/session-runtime/turn/share-ops.mjs +0 -77
  680. package/src/tui/session/cross-surface-share.mjs +0 -406
  681. package/src/tui/session/live-share/delta.mjs +0 -153
  682. package/src/tui/session/live-share/mirror.mjs +0 -106
  683. package/src/tui/session/live-share/owner.mjs +0 -254
  684. package/src/tui/session/live-share/retry.mjs +0 -54
  685. package/src/tui/session/live-share/viewer/frame-router.mjs +0 -32
  686. package/src/tui/session/live-share/viewer/pipe-client.mjs +0 -108
  687. package/src/tui/session/live-share/viewer/submit-acks.mjs +0 -65
  688. package/src/tui/session/live-share/viewer/sync-waiters.mjs +0 -53
  689. package/src/tui/session/live-share/viewer.mjs +0 -99
  690. package/src/tui/session/live-share/wire.mjs +0 -44
  691. package/src/tui/session/live-share.mjs +0 -154
  692. package/src/tui/session/shared-dir-watch.mjs +0 -69
@@ -1,6 +1,8 @@
1
1
  /**
2
- * set-route.mjs — select the main route: resolve and validate the request,
3
- * adopt it into config, then decide how the current session follows it
2
+ * set-route.mjs — select the runtime's route: resolve and validate the
3
+ * request, adopt it as the live route (its per-model settings saved; the main
4
+ * model only on an explicit main-model choice, keepMainModel: false), then
5
+ * decide when the current session follows it
4
6
  * (untouched, tuned, recreated, updated in place when empty, or switched in
5
7
  * place when the selection is addressed to an established conversation).
6
8
  */
@@ -20,7 +22,8 @@ import {
20
22
  sessionRouteCommitted,
21
23
  shouldRecreateEmptySessionForRouteChange,
22
24
  } from '../../runtime/agent/orchestrator/runtime-core/session-route-policy.mjs';
23
- import { rebuildDeferredToolSurfaceForProvider } from '../../runtime/agent/orchestrator/runtime-core/tool-catalog.mjs';
25
+ import { rebuildToolSurfaceForProviderWithMigration } from '../../runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs';
26
+ import { UNOWNED_LEASE, openRouteLease } from './route-ownership.mjs';
24
27
 
25
28
  /** The request, completed from the live route where the caller left gaps. */
26
29
  function completeRequest(deps, next) {
@@ -80,20 +83,26 @@ async function resolveSelectedRoute(deps, next) {
80
83
  }
81
84
 
82
85
  /** Close the empty session and materialize a fresh one for the new provider. */
83
- async function recreateEmptySession(deps) {
86
+ async function recreateEmptySession(deps, lease) {
84
87
  const { getSession, setSession, mgr, statusRoutes, createCurrentSession, invalidatePreSessionToolSurface } = deps;
85
88
  // If the boot create is still finishing SessionStart/deferred-surface
86
89
  // work, drain that promise first. Otherwise createCurrentSession()
87
90
  // would return the old in-flight promise after we tombstone/null the
88
91
  // session, racing the intended rebuild for the new provider.
89
92
  await createCurrentSession('model-switch-empty-drain');
90
- const emptySession = getSession();
91
- if (!emptySession?.id || sessionHasRouteHistory(emptySession)) return;
92
- statusRoutes?.clearGatewaySessionRoute?.(emptySession.id);
93
- mgr.closeSession?.(emptySession.id, 'cli-model-switch-empty', { tombstone: true });
94
- setSession(null);
95
- invalidatePreSessionToolSurface?.();
96
- await createCurrentSession('model-switch-empty');
93
+ const closed = lease.run(
94
+ () => {
95
+ const emptySession = getSession();
96
+ if (!emptySession?.id || sessionHasRouteHistory(emptySession)) return false;
97
+ statusRoutes?.clearGatewaySessionRoute?.(emptySession.id);
98
+ mgr.closeSession?.(emptySession.id, 'cli-model-switch-empty', { tombstone: true });
99
+ setSession(null);
100
+ invalidatePreSessionToolSurface?.();
101
+ return true;
102
+ },
103
+ () => false
104
+ );
105
+ if (closed) await createCurrentSession('model-switch-empty');
97
106
  }
98
107
 
99
108
  /** Rewrite the addressed empty session to the route it was asked to run on. */
@@ -114,7 +123,7 @@ function updateSessionInPlace(deps, session, updateOptions) {
114
123
  const updated = mgr.updateSessionRoute?.(session.id, fields, updateOptions);
115
124
  if (updated) setSession(updated);
116
125
  else Object.assign(session, fields);
117
- rebuildDeferredToolSurfaceForProvider(getSession(), route.provider);
126
+ rebuildToolSurfaceForProviderWithMigration(getSession(), route.provider);
118
127
  writeStatuslineRoute(statusRoutes, getSession(), route);
119
128
  }
120
129
 
@@ -164,7 +173,7 @@ function switchSessionInPlace(deps, session) {
164
173
  }
165
174
 
166
175
  /** Validate, persist and adopt the requested route as the runtime's route. */
167
- async function adoptRoute(deps, persist, next, options) {
176
+ async function adoptRoute(deps, persist, next, options, lease) {
168
177
  const {
169
178
  getConfig,
170
179
  getRoute,
@@ -175,15 +184,40 @@ async function adoptRoute(deps, persist, next, options) {
175
184
  scheduleStatuslineUsageRefresh,
176
185
  } = deps;
177
186
  const { selectedRoute, fastCapable, modelMeta } = await resolveSelectedRoute(deps, next);
178
- persist.saveRouteModelSettings(selectedRoute, fastCapable);
179
- // An heir opening on its source's model is not a main-model choice.
180
- const leadRoute = persist.persistAdoptedModelSettings(selectedRoute, {
181
- keepMainModel: options?.keepMainModel === true,
182
- });
183
- setRouteState(resolveRoute(getConfig(), leadRoute ? { model: workflowPresetId('lead') } : selectedRoute));
184
- await refreshRouteEffort(modelMeta);
185
- refreshStatuslineUsageSnapshot(getRoute());
186
- scheduleStatuslineUsageRefresh();
187
+ // Provider readiness may outlast the session the selection was made for.
188
+ const adopted = lease.run(
189
+ () => {
190
+ if (options?.sessionOnly === true) {
191
+ // An agent child's route belongs to that session alone: the shared
192
+ // modelSettings bucket (saved effort/Fast per model) and the main
193
+ // model (lead preset / default model) are never written.
194
+ setRouteState(resolveRoute(getConfig(), selectedRoute));
195
+ } else {
196
+ persist.saveRouteModelSettings(selectedRoute, fastCapable);
197
+ // The main model changes only on an explicit main-model choice
198
+ // (keepMainModel: false, e.g. the setup tool); every other selection
199
+ // — the session surface's model pick, an heir — keeps it.
200
+ const leadRoute = persist.persistAdoptedModelSettings(selectedRoute, {
201
+ keepMainModel: options?.keepMainModel !== false,
202
+ });
203
+ setRouteState(resolveRoute(getConfig(), leadRoute ? { model: workflowPresetId('lead') } : selectedRoute));
204
+ }
205
+ return true;
206
+ },
207
+ () => false
208
+ );
209
+ if (!adopted) return false;
210
+ // The refresh completes against the route just adopted and only while the
211
+ // selection still owns it.
212
+ await refreshRouteEffort(modelMeta, getRoute(), null, lease);
213
+ return lease.run(
214
+ () => {
215
+ refreshStatuslineUsageSnapshot(getRoute());
216
+ scheduleStatuslineUsageRefresh();
217
+ return true;
218
+ },
219
+ () => false
220
+ );
187
221
  }
188
222
 
189
223
  /**
@@ -194,17 +228,25 @@ async function adoptRoute(deps, persist, next, options) {
194
228
  * `{ modelSwitch }` with the recorded boundary (as setRoute does) so the
195
229
  * session surface shows the same live divider, or true when nothing switched.
196
230
  */
197
- export function createContinueSessionInModel(deps, persist) {
198
- const { getSession, invalidateContextStatusCache } = deps;
231
+ export function createContinueSessionInModel(deps, persist, clearPendingRoute) {
232
+ const { getSession, getSessionGeneration, invalidateContextStatusCache } = deps;
199
233
  return async function continueSessionInModel(sessionId, next) {
200
234
  const session = getSession();
201
235
  if (!sessionId || !session?.id || session.id !== sessionId) {
202
236
  throw new Error(`session ${sessionId || ''} is not the active session`);
203
237
  }
204
- await adoptRoute(deps, persist, next, {});
205
- const modelSwitch = switchSessionInPlace(deps, session);
206
- invalidateContextStatusCache();
207
- return modelSwitch ? { modelSwitch } : true;
238
+ const lease = openRouteLease(getSessionGeneration);
239
+ const adopted = await adoptRoute(deps, persist, next, {}, lease);
240
+ return lease.run(
241
+ () => {
242
+ if (!adopted) return true;
243
+ const modelSwitch = switchSessionInPlace(deps, session);
244
+ invalidateContextStatusCache();
245
+ clearPendingRoute?.();
246
+ return modelSwitch ? { modelSwitch } : true;
247
+ },
248
+ () => true
249
+ );
208
250
  };
209
251
  }
210
252
 
@@ -215,9 +257,10 @@ async function validateSelectedRoute(deps, next) {
215
257
  }
216
258
 
217
259
  export function createSetRoute(deps, persist) {
218
- const { getRoute, getSession, invalidateContextStatusCache, createCurrentSession } = deps;
260
+ const { getRoute, getSession, getSessionGeneration, invalidateContextStatusCache, createCurrentSession } = deps;
261
+ let pending = null;
219
262
 
220
- return async function setRoute(next, options = {}) {
263
+ async function setRoute(next, options = {}) {
221
264
  // Without an explicit durable address a selection is for a new/inherited
222
265
  // session and never rewrites an existing conversation's model, unless it
223
266
  // is the user's model choice for this conversation (`switchEstablished`,
@@ -225,11 +268,28 @@ export function createSetRoute(deps, persist) {
225
268
  // place while an empty one follows the unaddressed rules below.
226
269
  const applyToCurrentSession = options?.applyToCurrentSession === true;
227
270
  const switchEstablished = applyToCurrentSession || options?.switchEstablished === true;
228
- // Lets a caller prove the selection is acceptable before it does
229
- // irreversible work (compaction) ahead of the switch; changes nothing.
271
+ // Validate without persisting the selection or changing the session.
230
272
  if (options?.validateOnly === true) return validateSelectedRoute(deps, next);
231
- await adoptRoute(deps, persist, next, options);
273
+ // A selection addressed to a conversation belongs to the session
274
+ // generation it was enqueued under (the surface's enqueue boundary names
275
+ // it; a direct call is enqueued now). Once that generation has moved, every
276
+ // route or session effect is skipped by the lease and the current route
277
+ // stands.
278
+ const addressed = switchEstablished || options?.deferUntilNextTurn === true;
279
+ const lease = addressed ? openRouteLease(getSessionGeneration, options?.originGeneration) : UNOWNED_LEASE;
280
+ const adopted = await adoptRoute(deps, persist, next, options, lease);
281
+ if (!adopted) return getRoute();
282
+ return lease.run(() => followSession(options, lease, { switchEstablished, applyToCurrentSession }), getRoute);
283
+ }
284
+
285
+ /** What the adopted route does to the session it was selected for. */
286
+ async function followSession(options, lease, { switchEstablished, applyToCurrentSession }) {
232
287
  const session = getSession();
288
+ if (options.deferUntilNextTurn === true) {
289
+ pending = session?.id ? { generation: lease.token } : null;
290
+ return getRoute();
291
+ }
292
+ pending = null;
233
293
  // A session the user has already talked in or compacted keeps its route
234
294
  // unless the selection was addressed to it. A current session with no
235
295
  // model reply, no compaction summary and no in-flight first turn — empty,
@@ -240,8 +300,8 @@ export function createSetRoute(deps, persist) {
240
300
  if (!switchEstablished) return getRoute();
241
301
  const route = getRoute();
242
302
  // An addressed selection of another model switches the conversation
243
- // itself in place; the caller (session surface) refuses it while a
244
- // turn runs. A same-model update (effort/Fast) only tunes the session
303
+ // itself in place; the session surface defers it to the next turn
304
+ // instead. A same-model update (effort/Fast) only tunes the session
245
305
  // from its next turn.
246
306
  if (session && (route.provider !== session.provider || route.model !== session.model)) {
247
307
  const modelSwitch = switchSessionInPlace(deps, session);
@@ -259,7 +319,9 @@ export function createSetRoute(deps, persist) {
259
319
  session?.id &&
260
320
  typeof createCurrentSession === 'function'
261
321
  ) {
262
- await recreateEmptySession(deps);
322
+ // The recreation installs a new session itself, so nothing after it
323
+ // acts for the selection beyond dropping the stale gauge.
324
+ await recreateEmptySession(deps, lease);
263
325
  invalidateContextStatusCache();
264
326
  return getRoute();
265
327
  }
@@ -272,5 +334,23 @@ export function createSetRoute(deps, persist) {
272
334
  invalidateContextStatusCache();
273
335
  }
274
336
  return getRoute();
337
+ }
338
+ setRoute.applyPendingRoute = () => {
339
+ if (!pending) return null;
340
+ const selection = pending;
341
+ if (selection.generation !== getSessionGeneration()) {
342
+ pending = null;
343
+ return null;
344
+ }
345
+ // The live route is the latest selection: effort/Fast tuned after the
346
+ // deferred model choice replace it, so no snapshot is kept.
347
+ const modelSwitch = switchSessionInPlace(deps, getSession());
348
+ invalidateContextStatusCache();
349
+ pending = null;
350
+ return modelSwitch;
351
+ };
352
+ setRoute.clearPendingRoute = () => {
353
+ pending = null;
275
354
  };
355
+ return setRoute;
276
356
  }
@@ -6,6 +6,7 @@ import { clean, hasOwn } from '../../runtime/agent/orchestrator/runtime-core/ses
6
6
  import { coerceEffortFor } from '../../runtime/agent/orchestrator/runtime-core/effort.mjs';
7
7
  import { ensureProviderEnabled } from '../../runtime/agent/orchestrator/runtime-core/config-helpers.mjs';
8
8
  import { selectionFastCapable } from '../route-state.mjs';
9
+ import { routeChain } from '../../runtime/shared/model-route-chain.mjs';
9
10
  import {
10
11
  isDefaultWebSearchRouteConfig,
11
12
  isWebSearchCapableProvider,
@@ -93,9 +94,13 @@ export function createWebSearchRouteApi(deps) {
93
94
  if (isDefaultWebSearchRouteConfig(selectedRoute)) {
94
95
  await awaitKeychainPrewarm();
95
96
  ensureFullConfig();
96
- return saveWebSearchRoute(defaultWebSearchRoute(selectedRoute.toolType));
97
97
  }
98
- return saveWebSearchRoute(await resolveExplicitRoute(selectedRoute));
98
+ const resolved = [];
99
+ for (const entry of routeChain(selectedRoute)) {
100
+ resolved.push(isDefaultWebSearchRouteConfig(entry) ? entry : await resolveExplicitRoute(entry));
101
+ }
102
+ const [primary, ...fallbacks] = resolved;
103
+ return saveWebSearchRoute(normalizeWebSearchRouteConfig({ ...primary, fallbacks }));
99
104
  },
100
105
  };
101
106
  }
@@ -19,10 +19,12 @@ export { shouldRecreateEmptySessionForRouteChange } from '../runtime/agent/orche
19
19
 
20
20
  export function createModelRouteApi(deps) {
21
21
  const persist = createRoutePersistence(deps);
22
+ const setRoute = createSetRoute(deps, persist);
22
23
  return {
23
24
  ...createWebSearchRouteApi(deps),
24
- setRoute: createSetRoute(deps, persist),
25
- continueSessionInModel: createContinueSessionInModel(deps, persist),
25
+ setRoute,
26
+ applyPendingRoute: setRoute.applyPendingRoute,
27
+ continueSessionInModel: createContinueSessionInModel(deps, persist, setRoute.clearPendingRoute),
26
28
  ...createRouteTuning(deps, persist),
27
29
  };
28
30
  }
@@ -4,6 +4,7 @@
4
4
  * follow-Main default.
5
5
  */
6
6
  import { webSearchRouteOrDefault } from '../../runtime/agent/orchestrator/runtime-core/workflow.mjs';
7
+ import { routeChain, canonicalRouteProvider } from '../../runtime/shared/model-route-chain.mjs';
7
8
 
8
9
  export function createWebSearchRouteCandidates({
9
10
  getRoute,
@@ -50,35 +51,47 @@ export function createWebSearchRouteCandidates({
50
51
  // before the Main Model was ever consulted.
51
52
  const webSearchRoute = webSearchRouteOrDefault(cfg.webSearchRoute, getWebSearchRoute());
52
53
  setWebSearchRoute(webSearchRoute);
54
+ const candidates = [];
55
+ const seen = new Set();
56
+ for (const selected of routeChain(webSearchRoute)) {
57
+ const candidate = await resolveCandidate(selected, cfg, route);
58
+ if (!candidate) continue;
59
+ const provider = canonicalRouteProvider(candidate.provider);
60
+ if (seen.has(provider)) continue;
61
+ seen.add(provider);
62
+ candidates.push({ ...candidate, provider });
63
+ }
64
+ return candidates;
65
+ }
66
+
67
+ async function resolveCandidate(webSearchRoute, cfg, route) {
53
68
  if (isDefaultWebSearchRouteConfig(webSearchRoute)) {
54
69
  const loadedRow = route?.provider && route?.model ? await loadMainCatalogRow(cfg, route) : null;
55
70
  const mainModel = currentMainWebSearchModelMeta(loadedRow);
56
- if (!mainModel || !webSearchCapableFor(route.provider, mainModel)) return [];
57
- return [
58
- {
59
- key: `default\n${route.provider}\n${route.model}`,
60
- provider: normalizeWebSearchProviderId(route.provider),
61
- model: route.model,
62
- source: 'default-web-search-route',
63
- effort: route.effectiveEffort || route.effort || null,
64
- fast: route.fast === true,
65
- toolType: webSearchRoute.toolType || null,
66
- },
67
- ];
71
+ if (!mainModel || !webSearchCapableFor(route.provider, mainModel)) return null;
72
+ return {
73
+ key: `default\n${route.provider}\n${route.model}`,
74
+ provider: normalizeWebSearchProviderId(route.provider),
75
+ model: route.model,
76
+ source: 'default-web-search-route',
77
+ effort: route.effectiveEffort || route.effort || null,
78
+ fast: route.fast === true,
79
+ modelParameters: route.modelParameters || {},
80
+ toolType: webSearchRoute.toolType || null,
81
+ };
68
82
  }
69
83
  const providerName = normalizeWebSearchProviderId(webSearchRoute.provider);
70
- if (!isWebSearchCapableProvider(providerName)) return [];
71
- return [
72
- {
73
- key: `${providerName}\n${webSearchRoute.model}`,
74
- provider: providerName,
75
- model: webSearchRoute.model,
76
- source: 'web-search-route',
77
- effort: webSearchRoute.effort || null,
78
- fast: webSearchRoute.fast === true,
79
- toolType: webSearchRoute.toolType || null,
80
- },
81
- ];
84
+ if (!isWebSearchCapableProvider(providerName)) return null;
85
+ return {
86
+ key: `${providerName}\n${webSearchRoute.model}`,
87
+ provider: providerName,
88
+ model: webSearchRoute.model,
89
+ source: 'web-search-route',
90
+ effort: webSearchRoute.effort || null,
91
+ fast: webSearchRoute.fast === true,
92
+ modelParameters: webSearchRoute.modelParameters || {},
93
+ toolType: webSearchRoute.toolType || null,
94
+ };
82
95
  }
83
96
 
84
97
  return { currentMainWebSearchModelMeta, nativeWebSearchRoutes };
@@ -0,0 +1,51 @@
1
+ // Per-session sink for usage spent by native web-search sends. The search runs
2
+ // as its own provider send under a derived session id, so the main stream
3
+ // never reports it; a turn's caller opts in with `onNativeWebSearchUsage` and
4
+ // receives the same delta shape `onUsageDelta` carries.
5
+ //
6
+ // Keyed by the owning session id, not async-local state: tools can execute
7
+ // from stream callbacks whose async context belongs to a pooled transport
8
+ // connection, not to the ask that is waiting on them.
9
+ //
10
+ // Each registration is its own entry that only its own release removes, so
11
+ // overlapping turns on one session id never restore or drop each other. The
12
+ // session lock serializes turns, so the most recent live entry belongs to the
13
+ // turn that is running; callers register once their turn owns the session.
14
+ import { usageDeltaEvent } from '../runtime/agent/orchestrator/session/loop/usage.mjs';
15
+
16
+ const entriesBySession = new Map();
17
+
18
+ /** Adds an owned sink entry for `sessionId`; the returned release removes exactly that entry. */
19
+ export function registerNativeWebSearchUsageSink(sessionId, sink) {
20
+ if (typeof sink !== 'function' || !sessionId) return () => {};
21
+ const entry = { sink };
22
+ let entries = entriesBySession.get(sessionId);
23
+ if (!entries) {
24
+ entries = [];
25
+ entriesBySession.set(sessionId, entries);
26
+ }
27
+ entries.push(entry);
28
+ return () => {
29
+ const live = entriesBySession.get(sessionId);
30
+ const index = live ? live.indexOf(entry) : -1;
31
+ if (index === -1) return;
32
+ live.splice(index, 1);
33
+ if (live.length === 0) entriesBySession.delete(sessionId);
34
+ };
35
+ }
36
+
37
+ export function reportNativeWebSearchUsage({ ownerSessionId, sessionId, requestedModel, model, usage }) {
38
+ const entries = entriesBySession.get(ownerSessionId);
39
+ const sink = entries?.[entries.length - 1]?.sink;
40
+ if (!sink || !usage) return;
41
+ try {
42
+ const pending = sink({
43
+ ...usageDeltaEvent({ sessionId, iterationIndex: 0, requestedModel, model, usage }),
44
+ source: 'native_web_search',
45
+ agentRole: 'web-search',
46
+ });
47
+ if (typeof pending?.then === 'function') pending.then(undefined, () => {});
48
+ } catch {
49
+ /* telemetry must never fail the search */
50
+ }
51
+ }
@@ -13,6 +13,8 @@ import {
13
13
  normalizeWebSearchAllowedDomain,
14
14
  } from './native-web-search/tool-shape.mjs';
15
15
  import { createWebSearchRouteCandidates } from './native-web-search/routes.mjs';
16
+ import { reportNativeWebSearchUsage } from './native-web-search-usage.mjs';
17
+ import { canFallbackRoute } from '../runtime/shared/model-route-fallback.mjs';
16
18
 
17
19
  export function createNativeWebSearch(deps) {
18
20
  const {
@@ -58,10 +60,11 @@ export function createNativeWebSearch(deps) {
58
60
  }
59
61
  const family = webSearchProviderFamily(candidate.provider);
60
62
  const startedAt = Date.now();
63
+ const sendSessionId = `${getSession()?.id || 'web_search'}:native-web-search:${Date.now().toString(36)}`;
61
64
  const result = await providerImpl.send(nativeWebSearchMessages(webSearchArgs), candidate.model, undefined, {
62
65
  signal,
63
66
  role: 'web-search',
64
- sessionId: `${getSession()?.id || 'web_search'}:native-web-search:${Date.now().toString(36)}`,
67
+ sessionId: sendSessionId,
65
68
  sourceType: 'native-web-search',
66
69
  sourceName: 'web_search',
67
70
  nativeTools: [toolFor(webSearchArgs, toolType, candidate.provider)],
@@ -73,6 +76,13 @@ export function createNativeWebSearch(deps) {
73
76
  onStageChange: () => {},
74
77
  onStreamDelta: () => {},
75
78
  });
79
+ reportNativeWebSearchUsage({
80
+ ownerSessionId: getSession()?.id,
81
+ sessionId: sendSessionId,
82
+ requestedModel: candidate.model,
83
+ model: result?.model || candidate.model,
84
+ usage: result?.usage,
85
+ });
76
86
  return {
77
87
  content: String(result?.content || '').trim(),
78
88
  provider: candidate.provider,
@@ -89,14 +99,14 @@ export function createNativeWebSearch(deps) {
89
99
  if (!candidates.length) throw noCandidateError();
90
100
  const errors = [];
91
101
  for (const candidate of candidates) {
92
- for (const toolType of toolTypesFor(candidate)) {
93
- try {
94
- return await sendCandidate(candidate, toolType, webSearchArgs, signal);
95
- } catch (err) {
96
- errors.push(
97
- `${candidate.provider}${candidate.model ? `/${candidate.model}` : ''}/${toolType}: ${err?.message || String(err)}`
98
- );
99
- }
102
+ const [toolType] = toolTypesFor(candidate);
103
+ try {
104
+ return await sendCandidate(candidate, toolType, webSearchArgs, signal);
105
+ } catch (err) {
106
+ if (!canFallbackRoute(err, { signal })) throw err;
107
+ errors.push(
108
+ `${candidate.provider}${candidate.model ? `/${candidate.model}` : ''}/${toolType}: ${err?.message || String(err)}`
109
+ );
100
110
  }
101
111
  }
102
112
  throw new Error(`native web search failed: ${errors.join(' | ')}`);
@@ -12,7 +12,6 @@ export function createNewSessionConfig({
12
12
  initialRouteExplicit = false,
13
13
  invalidatePreSessionToolSurface,
14
14
  invalidateOutputStyleStatusCache,
15
- invalidateSkills,
16
15
  connectConfiguredMcp,
17
16
  configureEmbedding,
18
17
  }) {
@@ -33,7 +32,10 @@ export function createNewSessionConfig({
33
32
  }
34
33
  invalidateOutputStyleStatusCache();
35
34
  invalidatePreSessionToolSurface();
36
- invalidateSkills();
35
+ // The installed-skill list is NOT dropped here: its cache is change-gated
36
+ // (every skill root's mtime signature, kept by change watchers), so a new
37
+ // session already sees any skill edit. Clearing it made every session
38
+ // creation re-read and re-parse every SKILL.md on the event loop.
37
39
  await configureEmbedding(sharedCfgMod.readSection('memory')?.embedding || {});
38
40
  if (!firstSession || !isDeepStrictEqual(previousMcp, mcpSettings())) {
39
41
  // Reused runtimes may still own old connections. This reset is scoped to
@@ -12,6 +12,7 @@ import {
12
12
  removeCustomProvider,
13
13
  updateCustomProviderModel,
14
14
  testCustomProvider,
15
+ checkCustomProviderKeyEnv,
15
16
  discoverCustomProviderModels,
16
17
  } from '../services/provider-admin.mjs';
17
18
 
@@ -96,6 +97,9 @@ export function createLoginApi({ cfgMod, awaitKeychainPrewarm, reloadFullConfig,
96
97
  await awaitKeychainPrewarm();
97
98
  return await testCustomProvider(cfgMod, input);
98
99
  },
100
+ checkCustomProviderKeyEnv(name) {
101
+ return checkCustomProviderKeyEnv(name);
102
+ },
99
103
  async discoverCustomProviderModels(input) {
100
104
  await awaitKeychainPrewarm();
101
105
  return await discoverCustomProviderModels(cfgMod, input);
@@ -3,6 +3,7 @@
3
3
  // the model catalog.
4
4
  import { refreshKeychainStatus, retryKeychain } from '../../runtime/shared/config.mjs';
5
5
  import { keychainIssueFor } from '../services/provider-admin.mjs';
6
+ import { modelProxyClientMode } from '../../runtime/shared/model-proxy-mode.mjs';
6
7
 
7
8
  // The keyring alert must reflect the live state (it can lock or unlock while a
8
9
  // cached setup is served), so overlay it on every ready read.
@@ -26,6 +27,9 @@ export function createSetupApi({
26
27
  return {
27
28
  async getProviderSetup(options = {}) {
28
29
  const force = options?.force === true || options?.refresh === true;
30
+ if (modelProxyClientMode()) {
31
+ return cachedProviderSetup({ force: force || options?.recheckKeychain === true });
32
+ }
29
33
  // An unforced read never blocks: the authoritative setup waits on the OS
30
34
  // keychain, which can take seconds on a cold start and used to stall the
31
35
  // whole settings sweep behind it. Serve
@@ -2,6 +2,7 @@
2
2
  // One authoritative provider catalog load: secrets and providers ready, the
3
3
  // daemon-wide startup refresh joined (or a forced refresh run), then the shared
4
4
  // catalog flattened into deduplicated rows with per-provider profiling.
5
+ import { modelProxyClientMode } from '../../runtime/shared/model-proxy-mode.mjs';
5
6
  import { isSelectableLlmModel } from '../model-recency.mjs';
6
7
  import { sharedProviderCatalog } from '../provider-catalog-cache.mjs';
7
8
  import { NO_ENABLED_PROVIDERS } from '../../runtime/agent/orchestrator/providers/registry-errors.mjs';
@@ -49,6 +50,14 @@ export function createCatalogLoader({
49
50
  }
50
51
  const providersStartedAt = performance.now();
51
52
  try {
53
+ if (forceRefresh && modelProxyClientMode()) {
54
+ const { loadModelProxyProviderConfig } = await import(
55
+ '../../runtime/agent/orchestrator/providers/model-proxy-provider.mjs'
56
+ );
57
+ await loadModelProxyProviderConfig({ force: true });
58
+ // Rebuild even when daemon readiness already settled on the old PC set.
59
+ await reg().initProviders({});
60
+ }
52
61
  await ensureProvidersReady(config().providers || {});
53
62
  } catch (error) {
54
63
  if (error?.code === NO_ENABLED_PROVIDERS) return false;
@@ -4,6 +4,8 @@
4
4
  // the already-loaded provider rows over a provider round-trip.
5
5
  import { isSelectableLlmModel } from '../model-recency.mjs';
6
6
  import { catalogRevision } from '../provider-catalog-cache.mjs';
7
+ import { modelProxyClientMode } from '../../runtime/shared/model-proxy-mode.mjs';
8
+ import { loadModelProxyProviderConfig } from '../../runtime/agent/orchestrator/providers/model-proxy-provider.mjs';
7
9
 
8
10
  export function createWebSearchCatalog({
9
11
  caches,
@@ -14,15 +16,22 @@ export function createWebSearchCatalog({
14
16
  quickHelpers,
15
17
  normalizeWebSearchProviderId,
16
18
  isWebSearchCapableProvider,
19
+ collectProviderModels,
17
20
  ensureFullConfig,
18
21
  awaitKeychainPrewarm,
19
22
  ensureProvidersReady,
20
23
  }) {
21
24
  async function enabledWebSearchProviderConfig() {
22
- await awaitKeychainPrewarm();
23
- ensureFullConfig();
25
+ let providers;
26
+ if (modelProxyClientMode()) {
27
+ providers = await loadModelProxyProviderConfig();
28
+ } else {
29
+ await awaitKeychainPrewarm();
30
+ ensureFullConfig();
31
+ providers = config().providers;
32
+ }
24
33
  const out = {};
25
- for (const [name, providerConfig] of Object.entries(config().providers || {})) {
34
+ for (const [name, providerConfig] of Object.entries(providers || {})) {
26
35
  const providerName = normalizeWebSearchProviderId(name);
27
36
  if (!providerConfig?.enabled || !isWebSearchCapableProvider(providerName)) continue;
28
37
  out[providerName] = { ...providerConfig, enabled: true };
@@ -66,6 +75,12 @@ export function createWebSearchCatalog({
66
75
  }
67
76
 
68
77
  async function loadWebSearchProviderModelsFresh({ forceRefresh = false } = {}) {
78
+ if (modelProxyClientMode()) {
79
+ // Share the desktop-backed catalog's readiness, force refresh and retry
80
+ // semantics. Server-local quick rows cannot describe desktop accounts.
81
+ const models = await collectProviderModels({ force: forceRefresh });
82
+ return quickHelpers.webSearchRowsWithDefault(quickHelpers.webSearchModelsFromRows(models));
83
+ }
69
84
  const webSearchProviders = await enabledWebSearchProviderConfig();
70
85
  const providerNames = Object.keys(webSearchProviders);
71
86
  if (!providerNames.length) return [];
@@ -89,6 +104,11 @@ export function createWebSearchCatalog({
89
104
  }
90
105
 
91
106
  async function collectWebSearchProviderModels({ force = false } = {}) {
107
+ if (modelProxyClientMode()) {
108
+ // The main catalog owns caching in client mode, including incomplete
109
+ // loads; do not pin an empty/offline projection in a second cache.
110
+ return rows.providerModelsFromCacheRows(await loadWebSearchProviderModelsFresh({ forceRefresh: force }));
111
+ }
92
112
  const revision = meta.syncCatalogRevision();
93
113
  if (force) {
94
114
  const models = await loadWebSearchProviderModelsFresh({ forceRefresh: true });
@@ -63,6 +63,7 @@ export function createProviderModels({
63
63
  quickHelpers,
64
64
  normalizeWebSearchProviderId,
65
65
  isWebSearchCapableProvider,
66
+ collectProviderModels,
66
67
  ...readiness,
67
68
  });
68
69
  const loadProviderModelsFresh = createCatalogLoader({ caches, config, reg, meta, rows, profile, ...readiness });
@@ -5,6 +5,7 @@
5
5
  // references) and all config/registry reads flow through supplied accessors so
6
6
  // live-binding is preserved.
7
7
  import { clean } from '../runtime/agent/orchestrator/runtime-core/session-text.mjs';
8
+ import { modelProxyClientMode } from '../runtime/shared/model-proxy-mode.mjs';
8
9
 
9
10
  // A post-redeem dashboard rebuild is best effort: past this budget the caller
10
11
  // gets its confirmed outcome and the surface revalidates on its own cadence.
@@ -70,6 +71,9 @@ export function createProviderUsage({
70
71
  }
71
72
 
72
73
  async function cachedProviderSetup({ force = false, quick = false } = {}) {
74
+ // The proxy owns a short, connection-generation-aware cache. A session's
75
+ // indefinite local cache would hide PC sign-ins, sign-outs and reconnects.
76
+ if (modelProxyClientMode()) return providerSetup(displayConfig(), { force });
73
77
  if (!force && caches.providerSetupCache.setup) {
74
78
  return caches.providerSetupCache.setup;
75
79
  }