mixdog 1.2.0 → 1.2.2

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 (386) hide show
  1. package/README.md +7 -5
  2. package/package.json +1 -1
  3. package/scripts/gate-local.mjs +19 -3
  4. package/scripts/model-catalog-audit.mjs +1 -15
  5. package/src/agents/reviewer/AGENT.md +3 -3
  6. package/src/agents/reviewer/agent.json +1 -1
  7. package/src/defaults/shipped-history.json +5 -0
  8. package/src/defaults/skills/pptx/SKILL.md +6 -6
  9. package/src/defaults/skills/pptx/references/review.md +6 -4
  10. package/src/defaults/skills/pptx/scripts/source-extract.mjs +1 -1
  11. package/src/defaults/skills/setup/references/actions.md +13 -3
  12. package/src/defaults/skills/visualize/SKILL.md +12 -9
  13. package/src/repl/slash-commands.mjs +16 -1
  14. package/src/rules/shared/60-verification.md +3 -1
  15. package/src/rules/shared/70-delivery.md +4 -2
  16. package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +29 -4
  17. package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +10 -0
  18. package/src/runtime/agent/orchestrator/cache-mtime.mjs +26 -5
  19. package/src/runtime/agent/orchestrator/config.mjs +10 -4
  20. package/src/runtime/agent/orchestrator/context/collect.mjs +2 -1
  21. package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +11 -5
  22. package/src/runtime/agent/orchestrator/context/skill-catalog.mjs +74 -21
  23. package/src/runtime/agent/orchestrator/mcp/client-config.mjs +122 -15
  24. package/src/runtime/agent/orchestrator/mcp/client-handshake.mjs +54 -11
  25. package/src/runtime/agent/orchestrator/mcp/client-transport.mjs +104 -9
  26. package/src/runtime/agent/orchestrator/mcp/client.mjs +358 -140
  27. package/src/runtime/agent/orchestrator/mcp/lazy-output-validator.mjs +25 -0
  28. package/src/runtime/agent/orchestrator/mcp/oauth-callback.mjs +103 -0
  29. package/src/runtime/agent/orchestrator/mcp/oauth-credentials.mjs +150 -0
  30. package/src/runtime/agent/orchestrator/mcp/oauth-login.mjs +111 -0
  31. package/src/runtime/agent/orchestrator/mcp/oauth-probe.mjs +87 -0
  32. package/src/runtime/agent/orchestrator/mcp/oauth-provider.mjs +95 -0
  33. package/src/runtime/agent/orchestrator/mcp/oauth-request.mjs +122 -0
  34. package/src/runtime/agent/orchestrator/mcp/oauth-shared.mjs +9 -0
  35. package/src/runtime/agent/orchestrator/mcp/oauth.mjs +229 -0
  36. package/src/runtime/agent/orchestrator/mcp/plugin-placeholders.mjs +54 -0
  37. package/src/runtime/agent/orchestrator/providers/account-pool.mjs +294 -44
  38. package/src/runtime/agent/orchestrator/providers/anthropic-api-recovery.mjs +2 -1
  39. package/src/runtime/agent/orchestrator/providers/anthropic-api-transport.mjs +94 -31
  40. package/src/runtime/agent/orchestrator/providers/anthropic-error-contract.mjs +96 -0
  41. package/src/runtime/agent/orchestrator/providers/anthropic-fast-mode.mjs +39 -18
  42. package/src/runtime/agent/orchestrator/providers/anthropic-max-tokens-recovery.mjs +55 -0
  43. package/src/runtime/agent/orchestrator/providers/anthropic-max-tokens.mjs +25 -21
  44. package/src/runtime/agent/orchestrator/providers/anthropic-messages.mjs +3 -1
  45. package/src/runtime/agent/orchestrator/providers/anthropic-midstream-recovery.mjs +18 -4
  46. package/src/runtime/agent/orchestrator/providers/anthropic-model-resolve.mjs +13 -1
  47. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
  48. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-midstream.mjs +10 -1
  49. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-recovery.mjs +23 -9
  50. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-request/initial-status.mjs +46 -20
  51. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-request.mjs +14 -9
  52. package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +73 -35
  53. package/src/runtime/agent/orchestrator/providers/anthropic-overload-fallback.mjs +69 -0
  54. package/src/runtime/agent/orchestrator/providers/anthropic-server-fallback.mjs +4 -0
  55. package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +8 -1
  56. package/src/runtime/agent/orchestrator/providers/anthropic.mjs +53 -18
  57. package/src/runtime/agent/orchestrator/providers/antigravity-oauth-catalog.mjs +30 -9
  58. package/src/runtime/agent/orchestrator/providers/antigravity-oauth.mjs +7 -0
  59. package/src/runtime/agent/orchestrator/providers/antigravity-request.mjs +30 -14
  60. package/src/runtime/agent/orchestrator/providers/antigravity-response.mjs +2 -1
  61. package/src/runtime/agent/orchestrator/providers/antigravity-retry-policy.mjs +93 -0
  62. package/src/runtime/agent/orchestrator/providers/antigravity-transport.mjs +82 -9
  63. package/src/runtime/agent/orchestrator/providers/auto-effort.mjs +9 -0
  64. package/src/runtime/agent/orchestrator/providers/command-code-oauth-login.mjs +337 -0
  65. package/src/runtime/agent/orchestrator/providers/command-code-oauth-tokens.mjs +159 -0
  66. package/src/runtime/agent/orchestrator/providers/command-code-oauth.mjs +447 -0
  67. package/src/runtime/agent/orchestrator/providers/cursor-auth.mjs +38 -5
  68. package/src/runtime/agent/orchestrator/providers/cursor-client-version.mjs +1 -1
  69. package/src/runtime/agent/orchestrator/providers/cursor-wire-guards.mjs +97 -2
  70. package/src/runtime/agent/orchestrator/providers/cursor-wire-stream-bridge.mjs +102 -23
  71. package/src/runtime/agent/orchestrator/providers/cursor-wire-transport.mjs +103 -33
  72. package/src/runtime/agent/orchestrator/providers/cursor-wire.mjs +29 -6
  73. package/src/runtime/agent/orchestrator/providers/cursor.mjs +18 -1
  74. package/src/runtime/agent/orchestrator/providers/custom-provider.mjs +7 -4
  75. package/src/runtime/agent/orchestrator/providers/effort-configuration.mjs +86 -19
  76. package/src/runtime/agent/orchestrator/providers/gemini-cache-policy.mjs +1 -1
  77. package/src/runtime/agent/orchestrator/providers/gemini-cache.mjs +29 -8
  78. package/src/runtime/agent/orchestrator/providers/gemini-error-contract.mjs +191 -0
  79. package/src/runtime/agent/orchestrator/providers/gemini-family.mjs +9 -0
  80. package/src/runtime/agent/orchestrator/providers/gemini-history-signatures.mjs +9 -4
  81. package/src/runtime/agent/orchestrator/providers/gemini-response.mjs +3 -1
  82. package/src/runtime/agent/orchestrator/providers/gemini-retry-policy.mjs +180 -0
  83. package/src/runtime/agent/orchestrator/providers/gemini-schema.mjs +21 -82
  84. package/src/runtime/agent/orchestrator/providers/gemini-sdk-request.mjs +4 -1
  85. package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +71 -12
  86. package/src/runtime/agent/orchestrator/providers/gemini-thinking.mjs +21 -20
  87. package/src/runtime/agent/orchestrator/providers/gemini.mjs +97 -51
  88. package/src/runtime/agent/orchestrator/providers/grok-oauth-tokens.mjs +3 -0
  89. package/src/runtime/agent/orchestrator/providers/grok-oauth.mjs +68 -19
  90. package/src/runtime/agent/orchestrator/providers/lib/gemini-model-catalog.mjs +7 -1
  91. package/src/runtime/agent/orchestrator/providers/mimo-oauth.mjs +3 -0
  92. package/src/runtime/agent/orchestrator/providers/model-list-sanitize.mjs +2 -1
  93. package/src/runtime/agent/orchestrator/providers/model-proxy-bridge.mjs +1080 -0
  94. package/src/runtime/agent/orchestrator/providers/model-proxy-channel.d.mts +15 -0
  95. package/src/runtime/agent/orchestrator/providers/model-proxy-channel.mjs +35 -0
  96. package/src/runtime/agent/orchestrator/providers/muse-code-oauth.mjs +4 -9
  97. package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +12 -0
  98. package/src/runtime/agent/orchestrator/providers/oauth-usage.mjs +6 -5
  99. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-send.mjs +5 -3
  100. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-result.mjs +22 -0
  101. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream.mjs +1 -0
  102. package/src/runtime/agent/orchestrator/providers/openai-compat-error-contract.mjs +50 -0
  103. package/src/runtime/agent/orchestrator/providers/openai-compat-models.mjs +6 -2
  104. package/src/runtime/agent/orchestrator/providers/openai-compat-options.mjs +11 -0
  105. package/src/runtime/agent/orchestrator/providers/openai-compat-response-normalization.mjs +23 -0
  106. package/src/runtime/agent/orchestrator/providers/openai-compat-responses-events.mjs +16 -8
  107. package/src/runtime/agent/orchestrator/providers/openai-compat-responses-state.mjs +3 -2
  108. package/src/runtime/agent/orchestrator/providers/openai-compat-responses.mjs +94 -13
  109. package/src/runtime/agent/orchestrator/providers/openai-compat-retry-profile.mjs +193 -0
  110. package/src/runtime/agent/orchestrator/providers/openai-compat-stream-common.mjs +66 -2
  111. package/src/runtime/agent/orchestrator/providers/openai-compat-stream.mjs +2 -1
  112. package/src/runtime/agent/orchestrator/providers/openai-compat-wire.mjs +6 -0
  113. package/src/runtime/agent/orchestrator/providers/openai-compat-xai-send.mjs +6 -3
  114. package/src/runtime/agent/orchestrator/providers/openai-compat-xai.mjs +23 -14
  115. package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +26 -6
  116. package/src/runtime/agent/orchestrator/providers/openai-direct-request.mjs +42 -25
  117. package/src/runtime/agent/orchestrator/providers/openai-error-contract.mjs +274 -0
  118. package/src/runtime/agent/orchestrator/providers/openai-http-sse-request.mjs +72 -32
  119. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events/terminal-frames.mjs +18 -11
  120. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-outcome.mjs +1 -2
  121. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-stamps.mjs +2 -2
  122. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-state.mjs +2 -3
  123. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state.mjs +2 -2
  124. package/src/runtime/agent/orchestrator/providers/openai-http-sse-watchdogs.mjs +1 -3
  125. package/src/runtime/agent/orchestrator/providers/openai-oauth-dispatch.mjs +34 -3
  126. package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +5 -1
  127. package/src/runtime/agent/orchestrator/providers/openai-oauth-tokens.mjs +22 -2
  128. package/src/runtime/agent/orchestrator/providers/openai-oauth.mjs +5 -0
  129. package/src/runtime/agent/orchestrator/providers/openai-responses-input.mjs +5 -9
  130. package/src/runtime/agent/orchestrator/providers/openai-retry-policy.mjs +9 -0
  131. package/src/runtime/agent/orchestrator/providers/openai-ws-handshake.mjs +16 -8
  132. package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/attempt-context.mjs +1 -2
  133. package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/policy.mjs +25 -14
  134. package/src/runtime/agent/orchestrator/providers/openai-ws-terminal.mjs +18 -11
  135. package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +35 -24
  136. package/src/runtime/agent/orchestrator/providers/provider-error-kind.mjs +581 -0
  137. package/src/runtime/agent/orchestrator/providers/registry.mjs +35 -9
  138. package/src/runtime/agent/orchestrator/providers/retry-backoff.mjs +46 -7
  139. package/src/runtime/agent/orchestrator/providers/retry-classification.mjs +118 -219
  140. package/src/runtime/agent/orchestrator/providers/retry-classifier.mjs +2 -0
  141. package/src/runtime/agent/orchestrator/providers/retry-executor.mjs +148 -45
  142. package/src/runtime/agent/orchestrator/providers/retry-midstream.mjs +81 -16
  143. package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +3 -0
  144. package/src/runtime/agent/orchestrator/runtime-core/effort.mjs +3 -0
  145. package/src/runtime/agent/orchestrator/runtime-core/extension-scopes.mjs +15 -55
  146. package/src/runtime/agent/orchestrator/runtime-core/goal-control.mjs +15 -2
  147. package/src/runtime/agent/orchestrator/runtime-core/goal-reminder.mjs +0 -18
  148. package/src/runtime/agent/orchestrator/runtime-core/model-capabilities.mjs +57 -28
  149. package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +19 -16
  150. package/src/runtime/agent/orchestrator/runtime-core/plugin-mcp.mjs +268 -181
  151. package/src/runtime/agent/orchestrator/runtime-core/skill-tool-loading.mjs +4 -1
  152. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog-schema.mjs +21 -0
  153. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +54 -3
  154. package/src/runtime/agent/orchestrator/session/catalog-db/index.mjs +284 -0
  155. package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +270 -0
  156. package/src/runtime/agent/orchestrator/session/catalog-db/sqlite-gate.mjs +27 -0
  157. package/src/runtime/agent/orchestrator/session/catalog-db/worker.mjs +628 -0
  158. package/src/runtime/agent/orchestrator/session/compact/messages.mjs +6 -2
  159. package/src/runtime/agent/orchestrator/session/conversation-import/claude.mjs +184 -0
  160. package/src/runtime/agent/orchestrator/session/conversation-import/codex.mjs +136 -0
  161. package/src/runtime/agent/orchestrator/session/conversation-import/convert.mjs +128 -0
  162. package/src/runtime/agent/orchestrator/session/conversation-import/imported-session.mjs +127 -0
  163. package/src/runtime/agent/orchestrator/session/conversation-import/turns.mjs +101 -0
  164. package/src/runtime/agent/orchestrator/session/explicit-skills.mjs +83 -5
  165. package/src/runtime/agent/orchestrator/session/imported-message.mjs +11 -0
  166. package/src/runtime/agent/orchestrator/session/loop/completion-guards.mjs +2 -1
  167. package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +1 -1
  168. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn.mjs +3 -2
  169. package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +10 -4
  170. package/src/runtime/agent/orchestrator/session/loop/steering.mjs +4 -3
  171. package/src/runtime/agent/orchestrator/session/loop/step-auto-effort.mjs +102 -18
  172. package/src/runtime/agent/orchestrator/session/loop/tool-helpers.mjs +3 -0
  173. package/src/runtime/agent/orchestrator/session/loop/tool-phase.mjs +3 -1
  174. package/src/runtime/agent/orchestrator/session/manager/ask-queue.mjs +42 -5
  175. package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +14 -3
  176. package/src/runtime/agent/orchestrator/session/manager/ask-turn-auto-effort.mjs +20 -12
  177. package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +50 -23
  178. package/src/runtime/agent/orchestrator/session/manager/ask-turn-loop-options.mjs +4 -0
  179. package/src/runtime/agent/orchestrator/session/manager/pending-message-entry.mjs +22 -14
  180. package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +1 -1
  181. package/src/runtime/agent/orchestrator/session/manager/turn-interruption.mjs +18 -7
  182. package/src/runtime/agent/orchestrator/session/manager.mjs +0 -1
  183. package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +4 -3
  184. package/src/runtime/agent/orchestrator/session/send-with-recovery.mjs +155 -29
  185. package/src/runtime/agent/orchestrator/session/store/listing.mjs +6 -2
  186. package/src/runtime/agent/orchestrator/session/store/save-worker.mjs +6 -3
  187. package/src/runtime/agent/orchestrator/session/store/summary-cache.mjs +6 -0
  188. package/src/runtime/agent/orchestrator/session/store/write-guards.mjs +16 -0
  189. package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +22 -10
  190. package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +819 -0
  191. package/src/runtime/agent/orchestrator/session/store-summary-fields.mjs +12 -0
  192. package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +22 -12
  193. package/src/runtime/agent/orchestrator/session/store-summary-reader-catalog-fixture.mjs +158 -0
  194. package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +183 -374
  195. package/src/runtime/agent/orchestrator/session/synthetic-user-envelope.mjs +3 -1
  196. package/src/runtime/agent/orchestrator/session/tool-batch/pre-dispatch.mjs +1 -1
  197. package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +41 -3
  198. package/src/runtime/agent/orchestrator/session/transcript-restore/user-text.mjs +38 -17
  199. package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +2 -2
  200. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/deadline-plan.mjs +12 -15
  201. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/invocation-plan.mjs +17 -1
  202. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/spawn-env.mjs +4 -0
  203. package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +5 -5
  204. package/src/runtime/agent/orchestrator/tools/builtin/lib/list-helpers.mjs +2 -2
  205. package/src/runtime/agent/orchestrator/tools/builtin/path-diagnostics.mjs +6 -6
  206. package/src/runtime/agent/orchestrator/tools/builtin/read-range-index.mjs +173 -22
  207. package/src/runtime/agent/orchestrator/tools/builtin/read-single-guards.mjs +8 -4
  208. package/src/runtime/agent/orchestrator/tools/builtin/read-single-tool.mjs +5 -4
  209. package/src/runtime/agent/orchestrator/tools/builtin/read-source-windows.mjs +15 -2
  210. package/src/runtime/agent/orchestrator/tools/builtin/search-glob-tool.mjs +13 -10
  211. package/src/runtime/agent/orchestrator/tools/builtin/search-grep-tool.mjs +1 -1
  212. package/src/runtime/agent/orchestrator/tools/builtin/search-path-diagnostics.mjs +17 -12
  213. package/src/runtime/agent/orchestrator/tools/code-graph/dispatch/root-resolution.mjs +2 -2
  214. package/src/runtime/agent/orchestrator/tools/code-graph/dispatch.mjs +1 -1
  215. package/src/runtime/agent/orchestrator/tools/patch/apply-patch/codex-batch.mjs +4 -4
  216. package/src/runtime/agent/orchestrator/tools/patch/apply-patch/route.mjs +2 -2
  217. package/src/runtime/agent/orchestrator/tools/patch/orchestrator.mjs +1 -1
  218. package/src/runtime/agent/orchestrator/tools/patch/read-redirects.mjs +34 -30
  219. package/src/runtime/agent/orchestrator/tools/patch/sequence/units.mjs +7 -7
  220. package/src/runtime/agent/orchestrator/tools/patch/sequence.mjs +1 -1
  221. package/src/runtime/agent/orchestrator/tools/shell-snapshot.mjs +4 -0
  222. package/src/runtime/attachments/store.d.mts +3 -0
  223. package/src/runtime/channels/lib/owned-runtime/owned-start.mjs +1 -1
  224. package/src/runtime/channels/lib/webhook/session-dispatch.mjs +16 -4
  225. package/src/runtime/channels/lib/worker-main.mjs +17 -14
  226. package/src/runtime/computer-bridge/linux-readiness.mjs +0 -2
  227. package/src/runtime/effort-judge/judge-client.mjs +56 -18
  228. package/src/runtime/memory/lib/memory.mjs +1 -1
  229. package/src/runtime/memory/lib/pg/process.mjs +34 -24
  230. package/src/runtime/memory/lib/pg/supervisor.mjs +16 -13
  231. package/src/runtime/memory/lib/session-ingest.mjs +2 -2
  232. package/src/runtime/office/README.md +1 -1
  233. package/src/runtime/office/shared/values.mjs +0 -5
  234. package/src/runtime/shared/atomic-file.mjs +25 -4
  235. package/src/runtime/shared/background-tasks.mjs +92 -14
  236. package/src/runtime/shared/err-text.mjs +25 -0
  237. package/src/runtime/shared/error-presentation.mjs +159 -19
  238. package/src/runtime/shared/extension-scopes.mjs +5 -3
  239. package/src/runtime/shared/file-lock.mjs +37 -11
  240. package/src/runtime/shared/llm/anthropic-betas.mjs +4 -3
  241. package/src/runtime/shared/llm/anthropic-effort.mjs +134 -131
  242. package/src/runtime/shared/llm/anthropic-thinking-contract.mjs +50 -14
  243. package/src/runtime/shared/llm/model-catalog.mjs +53 -52
  244. package/src/runtime/shared/llm/openai-daybreak.mjs +4 -16
  245. package/src/runtime/shared/llm/provider-catalog-registry.mjs +17 -0
  246. package/src/runtime/shared/llm/provider-model-identities.mjs +13 -4
  247. package/src/runtime/shared/llm/usage-rollup.mjs +0 -1
  248. package/src/runtime/shared/model-display.mjs +13 -0
  249. package/src/runtime/shared/plugin-manifest.mjs +18 -9
  250. package/src/runtime/shared/pristine-execution-contract.json +9 -2
  251. package/src/runtime/shared/pristine-execution.mjs +28 -4
  252. package/src/runtime/shared/provider-accounts.mjs +124 -20
  253. package/src/runtime/shared/provider-api-key.mjs +12 -0
  254. package/src/runtime/shared/quota-resume-store.mjs +11 -0
  255. package/src/runtime/shared/session-baseline-store.mjs +960 -0
  256. package/src/runtime/shared/shell-display.mjs +9 -3
  257. package/src/runtime/shared/skill-mentions.d.mts +10 -0
  258. package/src/runtime/shared/skill-mentions.mjs +133 -0
  259. package/src/runtime/shared/skill-script-runtime.mjs +264 -0
  260. package/src/runtime/shared/statusline/statusline-format.mjs +4 -4
  261. package/src/runtime/shared/task-notification-envelope.mjs +2 -2
  262. package/src/runtime/shared/tool-primitives.mjs +35 -2
  263. package/src/runtime/shared/turn-changes.mjs +447 -219
  264. package/src/runtime/shared/turn-snapshot-store.mjs +182 -1
  265. package/src/runtime/shared/turn-snapshot.mjs +170 -48
  266. package/src/runtime/shared/turn-worktree-snapshot.mjs +160 -51
  267. package/src/runtime/shared/worker-requests.mjs +15 -2
  268. package/src/runtime/shared/worktrees/contract.mjs +0 -24
  269. package/src/runtime/shared/worktrees/test-support.mjs +19 -4
  270. package/src/session-runtime/automation-agents.mjs +8 -2
  271. package/src/session-runtime/boot/apis.mjs +61 -0
  272. package/src/session-runtime/boot/config.mjs +5 -2
  273. package/src/session-runtime/boot/facade.mjs +1 -0
  274. package/src/session-runtime/boot/infrastructure.mjs +35 -18
  275. package/src/session-runtime/conversation-import/discovery.mjs +698 -0
  276. package/src/session-runtime/conversation-import/service.mjs +369 -0
  277. package/src/session-runtime/cwd-plugins/cwd-apply.mjs +10 -5
  278. package/src/session-runtime/cwd-plugins/plugin-status.mjs +47 -42
  279. package/src/session-runtime/lifecycle/session-catalog.mjs +2 -0
  280. package/src/session-runtime/lifecycle/teardown.mjs +1 -1
  281. package/src/session-runtime/mcp-glue/connect.mjs +83 -16
  282. package/src/session-runtime/mcp-glue/plugin-servers.mjs +499 -0
  283. package/src/session-runtime/mcp-glue/server-catalog.mjs +135 -33
  284. package/src/session-runtime/mcp-glue.mjs +25 -2
  285. package/src/session-runtime/mcp-oauth-login.mjs +174 -0
  286. package/src/session-runtime/model-route/model-switch-target.mjs +34 -0
  287. package/src/session-runtime/model-route/set-route.mjs +83 -15
  288. package/src/session-runtime/model-route/web-search-route.mjs +1 -1
  289. package/src/session-runtime/native-web-search/routes.mjs +22 -3
  290. package/src/session-runtime/new-session-config.mjs +3 -2
  291. package/src/session-runtime/notification-bus.mjs +9 -2
  292. package/src/session-runtime/provider-auth/accounts.mjs +33 -15
  293. package/src/session-runtime/provider-models/model-meta.mjs +12 -3
  294. package/src/session-runtime/provider-models/web-search-catalog.mjs +5 -1
  295. package/src/session-runtime/provider-readiness.mjs +16 -10
  296. package/src/session-runtime/quick-model-rows/web-search-rows.mjs +13 -8
  297. package/src/session-runtime/quick-web-search-models.mjs +13 -38
  298. package/src/session-runtime/resource-extension-sync.mjs +24 -5
  299. package/src/session-runtime/resource-mcp-api.mjs +198 -78
  300. package/src/session-runtime/resource-plugins-api.mjs +29 -41
  301. package/src/session-runtime/resource-scope-decorate.mjs +6 -8
  302. package/src/session-runtime/resource-skills-api.mjs +23 -2
  303. package/src/session-runtime/runtime-review-api.mjs +13 -0
  304. package/src/session-runtime/schedule-session-run.mjs +1 -1
  305. package/src/session-runtime/services/agent-tool/job-task-reconcile.mjs +13 -1
  306. package/src/session-runtime/services/agent-tool/job-views/agent-list.mjs +7 -2
  307. package/src/session-runtime/services/agent-tool/send-flow.mjs +22 -4
  308. package/src/session-runtime/services/agent-tool/spawn-flow/job-start.mjs +2 -0
  309. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-run.mjs +22 -5
  310. package/src/session-runtime/services/agent-tool/worker-index/row-liveness.mjs +8 -1
  311. package/src/session-runtime/services/agent-tool/worker-index/row-shape.mjs +2 -2
  312. package/src/session-runtime/services/agent-tool/worker-rows.mjs +17 -0
  313. package/src/session-runtime/services/channel-session-router.mjs +4 -1
  314. package/src/session-runtime/services/hook-bus/command-handler.mjs +4 -1
  315. package/src/session-runtime/services/hook-bus/handlers.mjs +7 -3
  316. package/src/session-runtime/services/provider-admin.mjs +64 -18
  317. package/src/session-runtime/services/usage-dashboard-model.mjs +3 -0
  318. package/src/session-runtime/settings-compaction-api.mjs +1 -0
  319. package/src/session-runtime/setup-tool/executor.mjs +12 -1
  320. package/src/session-runtime/setup-tool/extended-actions.mjs +1 -0
  321. package/src/session-runtime/setup-tool/settings-contract.mjs +1 -0
  322. package/src/session-runtime/setup-tool/tool-defs.mjs +7 -1
  323. package/src/session-runtime/skills-api.mjs +7 -3
  324. package/src/session-runtime/turn/turn-run/ask-callbacks.mjs +1 -0
  325. package/src/session-runtime/webhook-session-run.mjs +16 -4
  326. package/src/skill-script-entry.mjs +36 -0
  327. package/src/standalone/daemon-drain-policy.mjs +8 -0
  328. package/src/standalone/daemon-stored-session-views.mjs +11 -3
  329. package/src/standalone/daemon-telemetry.mjs +55 -0
  330. package/src/standalone/daemon.mjs +44 -11
  331. package/src/standalone/session-protocol.mjs +12 -0
  332. package/src/standalone/session-service/agent-tree/agent-cancel.mjs +33 -2
  333. package/src/standalone/session-service/agent-tree/agent-turns.mjs +26 -10
  334. package/src/standalone/session-service/agent-tree.mjs +12 -0
  335. package/src/standalone/session-service/quota-resume.mjs +8 -0
  336. package/src/standalone/session-service/retention/busy.mjs +15 -1
  337. package/src/standalone/session-service/session-calls/session-action.mjs +6 -1
  338. package/src/standalone/session-service-api.mjs +5 -0
  339. package/src/standalone/session-service.mjs +1 -0
  340. package/src/tui/App.jsx +9 -1
  341. package/src/tui/app/app-view/floating-panel.jsx +9 -1
  342. package/src/tui/app/app-view.jsx +7 -0
  343. package/src/tui/app/create-app-pickers.mjs +4 -0
  344. package/src/tui/app/extension-pickers/mcp-login.mjs +107 -0
  345. package/src/tui/app/extension-pickers/mcp-servers-picker.mjs +2 -1
  346. package/src/tui/app/extension-pickers/plugins-pickers.mjs +35 -16
  347. package/src/tui/app/extension-pickers.mjs +2 -1
  348. package/src/tui/app/model-options.mjs +13 -16
  349. package/src/tui/app/skill-mention-palette.mjs +88 -0
  350. package/src/tui/app/slash-commands.mjs +7 -2
  351. package/src/tui/app/slash-dispatch/panel-commands.mjs +16 -1
  352. package/src/tui/app/slash-palette.mjs +23 -7
  353. package/src/tui/app/transcript-row-estimate.mjs +11 -3
  354. package/src/tui/app/use-prompt-draft-flow.mjs +7 -2
  355. package/src/tui/app/use-prompt-state.mjs +5 -0
  356. package/src/tui/components/Message.jsx +22 -1
  357. package/src/tui/components/PromptInput.jsx +21 -3
  358. package/src/tui/components/SlashCommandPalette.jsx +12 -3
  359. package/src/tui/components/StatusLine.jsx +2 -0
  360. package/src/tui/components/TranscriptItem.jsx +9 -1
  361. package/src/tui/components/prompt-input/key-handler.mjs +21 -8
  362. package/src/tui/components/status-line/local-line.mjs +5 -2
  363. package/src/tui/components/status-line/use-statusline-text.mjs +7 -1
  364. package/src/tui/components/user-message-skills.mjs +38 -0
  365. package/src/tui/dist/index.mjs +1323 -214
  366. package/src/tui/session/queue-helpers.mjs +7 -2
  367. package/src/tui/session/quota-resume.mjs +46 -14
  368. package/src/tui/session/session-api/commands.mjs +33 -24
  369. package/src/tui/session/session-api/extensions.mjs +26 -2
  370. package/src/tui/session/session-api/integrations.mjs +7 -0
  371. package/src/tui/session/session-api/lifecycle.mjs +5 -1
  372. package/src/tui/session/session-api/routes.mjs +71 -7
  373. package/src/tui/session/session-api/settings.mjs +12 -14
  374. package/src/tui/session/session-flow/drain.mjs +21 -5
  375. package/src/tui/session/session-flow/failed-turn-rewind.mjs +10 -4
  376. package/src/tui/session/tui-steering-persist.mjs +25 -9
  377. package/src/tui/session/turn.mjs +55 -15
  378. package/src/tui/statusline-ansi-bridge.mjs +1 -1
  379. package/src/ui/statusline-agents.mjs +15 -4
  380. package/src/ui/statusline.mjs +7 -3
  381. package/src/ui/streaming-markdown-heal.mjs +34 -3
  382. package/src/vendor/statusline/src/gateway/claude-current.mjs +14 -4
  383. package/src/runtime/effort-judge/previous-human-request.mjs +0 -162
  384. package/src/runtime/effort-judge/verified-context-input.mjs +0 -10
  385. package/src/runtime/memory/lib/memory-session-merge.mjs +0 -32
  386. package/src/runtime/shared/llm/usage-session-history.mjs +0 -266
@@ -7,19 +7,37 @@ import { webSearchRouteOrDefault } from '../../runtime/agent/orchestrator/runtim
7
7
 
8
8
  export function createWebSearchRouteCandidates({
9
9
  getRoute,
10
+ getReg,
10
11
  getWebSearchRoute,
11
12
  setWebSearchRoute,
12
13
  ensureFullConfig,
13
14
  awaitKeychainPrewarm,
15
+ ensureProvidersReady,
16
+ ensureProviderEnabled,
14
17
  normalizeWebSearchProviderId,
15
18
  isDefaultWebSearchRouteConfig,
16
19
  isWebSearchCapableProvider,
17
20
  webSearchCapableFor,
18
21
  }) {
19
- function currentMainWebSearchModelMeta() {
22
+ function currentMainWebSearchModelMeta(loadedRow = null) {
20
23
  const route = getRoute();
21
24
  if (!route?.provider || !route?.model) return null;
22
- return { ...route, id: route.model, display: route.model, name: route.model };
25
+ // Capability comes from the provider's catalog row (supportedTools etc.),
26
+ // not from the bare model id.
27
+ const catalogRow = getReg()?.getProvider(route.provider)?.getCachedModelInfo?.(route.model) || loadedRow;
28
+ return { ...catalogRow, ...route, id: route.model, display: route.model, name: route.model };
29
+ }
30
+
31
+ /** A cold catalog (fresh or model-proxy provider instance) is loaded once
32
+ * before the capability check, so it never falls back to the bare id.
33
+ * Returns the listed row, which carries the catalog fields even when the
34
+ * provider keeps no per-model cache. */
35
+ async function loadMainCatalogRow(cfg, route) {
36
+ await ensureProvidersReady(ensureProviderEnabled(cfg, route.provider));
37
+ const provider = getReg().getProvider(route.provider);
38
+ if (provider?.getCachedModelInfo?.(route.model) || typeof provider?.listModels !== 'function') return null;
39
+ const models = await provider.listModels();
40
+ return (Array.isArray(models) ? models.find((m) => m?.id === route.model) : null) || null;
23
41
  }
24
42
 
25
43
  async function nativeWebSearchRoutes() {
@@ -33,7 +51,8 @@ export function createWebSearchRouteCandidates({
33
51
  const webSearchRoute = webSearchRouteOrDefault(cfg.webSearchRoute, getWebSearchRoute());
34
52
  setWebSearchRoute(webSearchRoute);
35
53
  if (isDefaultWebSearchRouteConfig(webSearchRoute)) {
36
- const mainModel = currentMainWebSearchModelMeta();
54
+ const loadedRow = route?.provider && route?.model ? await loadMainCatalogRow(cfg, route) : null;
55
+ const mainModel = currentMainWebSearchModelMeta(loadedRow);
37
56
  if (!mainModel || !webSearchCapableFor(route.provider, mainModel)) return [];
38
57
  return [
39
58
  {
@@ -21,7 +21,8 @@ export function createNewSessionConfig({
21
21
  await flushPendingSessionConfigWrites();
22
22
  await sharedCfgMod.pendingConfigWrites();
23
23
  sharedCfgMod.invalidateConfigReadCache();
24
- const previousMcp = rt.config.mcpServers;
24
+ const mcpSettings = () => [rt.config.mcpServers, rt.config.pluginMcp];
25
+ const previousMcp = mcpSettings();
25
26
  // Headless callers inject a deliberately isolated config. Never replace
26
27
  // their explicit policy with the interactive profile on disk.
27
28
  if (!initialConfig || typeof initialConfig !== 'object') {
@@ -34,7 +35,7 @@ export function createNewSessionConfig({
34
35
  invalidatePreSessionToolSurface();
35
36
  invalidateSkills();
36
37
  await configureEmbedding(sharedCfgMod.readSection('memory')?.embedding || {});
37
- if (!firstSession || !isDeepStrictEqual(previousMcp, rt.config.mcpServers)) {
38
+ if (!firstSession || !isDeepStrictEqual(previousMcp, mcpSettings())) {
38
39
  // Reused runtimes may still own old connections. This reset is scoped to
39
40
  // the runtime that is constructing the new session, not to its peers.
40
41
  await connectConfiguredMcp({ reset: true });
@@ -3,7 +3,10 @@
3
3
  // pending queue so the model sees it next turn. The delivered registry keeps
4
4
  // those two paths from double-injecting the same completion.
5
5
  import { modelVisibleToolCompletionMessage } from '../runtime/shared/tool-execution-contract.mjs';
6
- import { markCompletionEntry } from '../runtime/agent/orchestrator/session/manager/pending-messages.mjs';
6
+ import {
7
+ PENDING_MODE_TASK_NOTIFICATION,
8
+ markCompletionEntry,
9
+ } from '../runtime/agent/orchestrator/session/manager/pending-messages.mjs';
7
10
  import {
8
11
  isDeliveredCompletion,
9
12
  logDuplicateSkip,
@@ -144,7 +147,11 @@ export function createNotificationBus({ listeners, mgr, onCompletionQueued, getO
144
147
  if (!open) return false;
145
148
  if (typeof mgr.enqueuePendingMessage !== 'function') return false;
146
149
  try {
147
- return mgr.enqueuePendingMessage(targetSessionId, content) > 0;
150
+ // A channel notification (webhook event rules, schedule injects, relays)
151
+ // is the runtime reporting, exactly as an attached TUI queues it: a
152
+ // task notification, so text inside it — fenced external webhook values
153
+ // included — never drives explicit skill selection.
154
+ return mgr.enqueuePendingMessage(targetSessionId, { content, mode: PENDING_MODE_TASK_NOTIFICATION }) > 0;
148
155
  } catch {
149
156
  return false;
150
157
  }
@@ -1,6 +1,10 @@
1
1
  // provider-auth/accounts.mjs — the per-provider account roster and account
2
2
  // switching, with the bounded background usage sweep that refreshes quotas.
3
- import { listProviderAccounts, updateProviderAccounts } from '../services/provider-admin.mjs';
3
+ import {
4
+ listProviderAccounts,
5
+ materializeProviderAccounts,
6
+ updateProviderAccounts,
7
+ } from '../services/provider-admin.mjs';
4
8
  import { getProvider } from '../../runtime/agent/orchestrator/providers/registry.mjs';
5
9
  import { fetchOAuthUsageSnapshot } from '../../runtime/agent/orchestrator/providers/oauth-usage.mjs';
6
10
 
@@ -11,21 +15,23 @@ export function createAccountApi(
11
15
  // One in-flight usage sweep per provider; a reopened picker reuses it.
12
16
  const accountUsageSweeps = new Map();
13
17
 
18
+ async function measureAccountUsage(providerId, provider, accounts, force = false) {
19
+ await awaitKeychainPrewarm();
20
+ for (let offset = 0; offset < accounts.length; offset += 4) {
21
+ await Promise.all(
22
+ accounts.slice(offset, offset + 4).map((account) => {
23
+ const target = { provider: providerId, accountId: account.id };
24
+ return fetchOAuthUsageSnapshot(target, provider.forAccount(account.id), () => {}, { force }).catch(
25
+ () => null
26
+ );
27
+ })
28
+ );
29
+ }
30
+ }
31
+
14
32
  async function sweepAccountUsage(providerId, provider, accounts) {
15
33
  try {
16
- await awaitKeychainPrewarm();
17
- for (let offset = 0; offset < accounts.length; offset += 4) {
18
- await Promise.all(
19
- accounts
20
- .slice(offset, offset + 4)
21
- .map((account) =>
22
- fetchOAuthUsageSnapshot(
23
- { provider: providerId, accountId: account.id },
24
- provider.forAccount(account.id)
25
- ).catch(() => null)
26
- )
27
- );
28
- }
34
+ await measureAccountUsage(providerId, provider, accounts);
29
35
  } finally {
30
36
  accountUsageSweeps.delete(providerId);
31
37
  }
@@ -69,8 +75,20 @@ export function createAccountApi(
69
75
  return pool;
70
76
  },
71
77
  async updateProviderAccounts(providerId, change) {
78
+ // `{ refreshUsage: true }` re-measures every account now (the roster's
79
+ // "Refresh usage") and changes nothing else in the roster. The implicit
80
+ // signed-in account is stored first so its measurement has a row to land on.
81
+ if (change?.refreshUsage === true && Object.keys(change).length === 1) {
82
+ const provider = getProvider(providerId);
83
+ if (typeof provider?.forAccount === 'function') {
84
+ await awaitKeychainPrewarm();
85
+ const { accounts } = await materializeProviderAccounts(providerId);
86
+ await measureAccountUsage(providerId, provider, accounts, true);
87
+ }
88
+ return listProviderAccounts(providerId);
89
+ }
72
90
  await awaitKeychainPrewarm();
73
- const result = updateProviderAccounts(providerId, change);
91
+ const result = await updateProviderAccounts(providerId, change);
74
92
  reloadFullConfig();
75
93
  invalidateProviderCaches();
76
94
  warmProviderModelCache();
@@ -10,6 +10,8 @@ export function modelMetaKey(providerId, modelId) {
10
10
 
11
11
  export function createModelMetaIndex({ caches, modelMetaByRoute, reg, scheduleProviderModelWarmup }) {
12
12
  let observedCatalogRevision = catalogRevision(reg());
13
+ // Keys holding only the bare-id placeholder: a fetching lookup replaces them.
14
+ const placeholderKeys = new Set();
13
15
 
14
16
  /** Invalidates the provider caches when the registry's catalog moved on;
15
17
  * returns the current revision either way. */
@@ -22,6 +24,7 @@ export function createModelMetaIndex({ caches, modelMetaByRoute, reg, schedulePr
22
24
  caches.providerModelsPromise = null;
23
25
  caches.webSearchProviderModelsCache = { models: null, at: 0, revision };
24
26
  modelMetaByRoute.clear();
27
+ placeholderKeys.clear();
25
28
  return revision;
26
29
  }
27
30
 
@@ -32,14 +35,16 @@ export function createModelMetaIndex({ caches, modelMetaByRoute, reg, schedulePr
32
35
  }
33
36
 
34
37
  function remember(providerId, modelId, meta) {
35
- modelMetaByRoute.set(modelMetaKey(providerId, modelId), meta);
38
+ const key = modelMetaKey(providerId, modelId);
39
+ modelMetaByRoute.set(key, meta);
40
+ placeholderKeys.delete(key);
36
41
  }
37
42
 
38
43
  async function lookupModelMeta(providerId, modelId, { allowFetch = false } = {}) {
39
44
  const revision = syncCatalogRevision();
40
45
  const seq = caches.providerModelsLoadSeq;
41
46
  const key = modelMetaKey(providerId, modelId);
42
- if (modelMetaByRoute.has(key)) return modelMetaByRoute.get(key);
47
+ if (modelMetaByRoute.has(key) && !(allowFetch && placeholderKeys.has(key))) return modelMetaByRoute.get(key);
43
48
  const fallback = () => ({ id: modelId, provider: providerId });
44
49
  const providerImpl = reg().getProvider(providerId);
45
50
  if (!providerImpl || typeof providerImpl.listModels !== 'function') {
@@ -58,6 +63,7 @@ export function createModelMetaIndex({ caches, modelMetaByRoute, reg, schedulePr
58
63
  if (!allowFetch) {
59
64
  const meta = fallback();
60
65
  modelMetaByRoute.set(key, meta);
66
+ placeholderKeys.add(key);
61
67
  scheduleProviderModelWarmup();
62
68
  return meta;
63
69
  }
@@ -65,7 +71,10 @@ export function createModelMetaIndex({ caches, modelMetaByRoute, reg, schedulePr
65
71
  const models = await providerImpl.listModels();
66
72
  const found = Array.isArray(models) ? models.find((m) => m?.id === modelId) : null;
67
73
  const meta = found || fallback();
68
- if (snapshotIsCurrent(revision, seq)) modelMetaByRoute.set(key, meta);
74
+ if (snapshotIsCurrent(revision, seq)) {
75
+ modelMetaByRoute.set(key, meta);
76
+ placeholderKeys.delete(key);
77
+ }
69
78
  return meta;
70
79
  } catch {
71
80
  // A failed fetch is not authoritative: nothing is pinned.
@@ -38,7 +38,11 @@ export function createWebSearchCatalog({
38
38
  try {
39
39
  let models = null;
40
40
  if (forceRefresh && typeof provider._refreshModelCache === 'function') {
41
- models = await provider._refreshModelCache();
41
+ try {
42
+ models = await provider._refreshModelCache();
43
+ } catch {
44
+ models = null; // fall back to listModels below
45
+ }
42
46
  }
43
47
  if (!Array.isArray(models)) models = await provider.listModels();
44
48
  if (!Array.isArray(models)) return [];
@@ -67,16 +67,17 @@ export function createProviderReadiness({ rt, keychain, getReg, getWarmProviderM
67
67
  await awaitKeychainPrewarm();
68
68
  if (rt.closeRequested) throw new Error('runtime is closing');
69
69
  const initKey = providerInitCacheKey(providerConfig);
70
- const existing = providerInitPromises.get(initKey);
71
- if (existing) return await existing;
72
70
  // Provider initialization is idempotent for one normalized config. Keep
73
71
  // the fulfilled promise, not only the in-flight one: session resume used
74
72
  // to rerun registry/keychain setup on every click even though neither the
75
73
  // provider config nor the registry had changed. Auth/config mutations call
76
74
  // invalidateProviderCaches(), which clears this gate and preserves the
77
75
  // existing refresh semantics.
78
- const providerInitPromise = Promise.resolve().then(() => getReg().initProviders(providerConfig));
79
- providerInitPromises.set(initKey, providerInitPromise);
76
+ let providerInitPromise = providerInitPromises.get(initKey);
77
+ if (!providerInitPromise) {
78
+ providerInitPromise = Promise.resolve().then(() => getReg().initProviders(providerConfig));
79
+ providerInitPromises.set(initKey, providerInitPromise);
80
+ }
80
81
  let result;
81
82
  try {
82
83
  result = await providerInitPromise;
@@ -84,13 +85,18 @@ export function createProviderReadiness({ rt, keychain, getReg, getWarmProviderM
84
85
  if (providerInitPromises.get(initKey) === providerInitPromise) providerInitPromises.delete(initKey);
85
86
  throw error;
86
87
  }
87
- if (!rt.startupProviderCatalogRefreshStarted && !rt.closeRequested) {
88
- rt.startupProviderCatalogRefreshStarted = true;
89
- rt.startupProviderCatalogRefreshPending = true;
88
+ if (!rt.closeRequested) {
90
89
  try {
91
- void Promise.resolve(getReg().refreshProviderCatalogsOnStartup())
90
+ // The registry memoizes the refresh per catalog epoch; a provider set
91
+ // change yields a new promise, which gets its own completion handling.
92
+ const refresh = getReg().refreshProviderCatalogsOnStartup();
93
+ if (refresh === rt.startupProviderCatalogRefreshObserved) return result;
94
+ rt.startupProviderCatalogRefreshObserved = refresh;
95
+ rt.startupProviderCatalogRefreshPending = true;
96
+ const isLatest = () => rt.startupProviderCatalogRefreshObserved === refresh;
97
+ void Promise.resolve(refresh)
92
98
  .then(() => {
93
- rt.startupProviderCatalogRefreshPending = false;
99
+ if (isLatest()) rt.startupProviderCatalogRefreshPending = false;
94
100
  if (rt.closeRequested) return;
95
101
  // Fresh catalog rows invalidate model-derived caches, but the
96
102
  // already initialized provider registry remains valid.
@@ -103,7 +109,7 @@ export function createProviderReadiness({ rt, keychain, getReg, getWarmProviderM
103
109
  bootProfile('provider-catalogs:refresh-ready');
104
110
  })
105
111
  .catch((error) => {
106
- rt.startupProviderCatalogRefreshPending = false;
112
+ if (isLatest()) rt.startupProviderCatalogRefreshPending = false;
107
113
  bootProfile('provider-catalogs:refresh-failed', { error: error?.message || String(error) });
108
114
  });
109
115
  bootProfile('provider-catalogs:refresh-started');
@@ -2,8 +2,11 @@
2
2
  // main model, cached or built-in quick models per capable provider, and the
3
3
  // configured/current routes, deduplicated per provider:model.
4
4
  import { clean } from '../../runtime/agent/orchestrator/runtime-core/session-text.mjs';
5
- import { QUICK_WEB_SEARCH_MODELS } from '../quick-web-search-models.mjs';
6
- import { WEB_SEARCH_DEFAULT_PROVIDER, WEB_SEARCH_DEFAULT_MODEL } from '../../runtime/agent/orchestrator/runtime-core/workflow.mjs';
5
+ import { quickWebSearchModels } from '../quick-web-search-models.mjs';
6
+ import {
7
+ WEB_SEARCH_DEFAULT_PROVIDER,
8
+ WEB_SEARCH_DEFAULT_MODEL,
9
+ } from '../../runtime/agent/orchestrator/runtime-core/workflow.mjs';
7
10
  import { providerCachedModelsSync } from '../../runtime/agent/orchestrator/providers/provider-catalog-cache.mjs';
8
11
  import { hydratedModel } from './model-meta.mjs';
9
12
 
@@ -33,7 +36,12 @@ export function createQuickWebSearchRows({
33
36
  contextWindow: resolved?.contextWindow || null,
34
37
  outputTokens: resolved?.outputTokens || null,
35
38
  latest: resolved?.latest === true,
36
- supportsWebSearch: true,
39
+ // Only what the source row itself declares; webSearchCapableFor adds the
40
+ // provider catalog's row and the id fallback. Never forced on.
41
+ ...(typeof model?.supportsWebSearch === 'boolean' ? { supportsWebSearch: model.supportsWebSearch } : {}),
42
+ ...(Array.isArray(model?.supportedTools) ? { supportedTools: model.supportedTools } : {}),
43
+ ...(Array.isArray(model?.tools) ? { tools: model.tools } : {}),
44
+ ...(model?.capabilities && typeof model.capabilities === 'object' ? { capabilities: model.capabilities } : {}),
37
45
  supportsFunctionCalling: resolved?.supportsFunctionCalling === true,
38
46
  supportsPromptCaching: resolved?.supportsPromptCaching === true,
39
47
  supportsReasoning: resolved?.supportsReasoning === true,
@@ -95,7 +103,7 @@ export function createQuickWebSearchRows({
95
103
  const providerName = normalizeWebSearchProviderId(name);
96
104
  if (!providerConfig?.enabled || !isWebSearchCapableProvider(providerName)) continue;
97
105
  const cachedModels = providerCachedModelsSync(providerName);
98
- const quickModels = cachedModels.length ? cachedModels : QUICK_WEB_SEARCH_MODELS[providerName] || [];
106
+ const quickModels = cachedModels.length ? cachedModels : quickWebSearchModels(providerName);
99
107
  for (const model of quickModels) {
100
108
  addQuickWebSearchModel(rows, seen, providerName, model);
101
109
  }
@@ -110,10 +118,7 @@ export function createQuickWebSearchRows({
110
118
  }
111
119
  const mainModel = currentMainWebSearchModelMeta();
112
120
  if (mainModel && webSearchCapableFor(route.provider, mainModel)) {
113
- addQuickWebSearchModel(rows, seen, route.provider, {
114
- id: route.model,
115
- display: route.model,
116
- });
121
+ addQuickWebSearchModel(rows, seen, route.provider, mainModel);
117
122
  }
118
123
  return webSearchModelsFromRows(rows);
119
124
  }
@@ -1,41 +1,16 @@
1
- // Static quick-pick model ids surfaced during onboarding / web-search setup.
2
- // Limits are intentionally not hardcoded here: rows are hydrated from live
3
- // provider caches and provider-scoped metadata during catalog construction.
1
+ // Offline quick-pick model rows for onboarding / web-search setup. No model id
2
+ // is listed here: when a provider has no live roster yet, its newest rows come
3
+ // from the provider-scoped public catalog, so a new release appears without a
4
+ // code change. Rows are hydrated further during catalog construction.
5
+ import { getModelsDevProviderModelsSync } from '../runtime/shared/llm/model-catalog.mjs';
4
6
 
5
7
  export const ONBOARDING_VERSION = 1;
6
8
 
7
- export const QUICK_WEB_SEARCH_MODELS = Object.freeze({
8
- 'openai-oauth': [
9
- { id: 'gpt-6-sol', display: 'GPT-6 Sol', latest: true },
10
- { id: 'gpt-6-luna', display: 'GPT-6 Luna', latest: true },
11
- { id: 'gpt-5.6-sol', display: 'GPT-5.6 Sol' },
12
- { id: 'gpt-5.6-terra', display: 'GPT-5.6 Terra' },
13
- { id: 'gpt-5.6-luna', display: 'GPT-5.6 Luna' },
14
- ],
15
- openai: [
16
- { id: 'gpt-5.5', display: 'GPT-5.5', latest: true },
17
- { id: 'gpt-5.4', display: 'GPT-5.4', latest: true },
18
- { id: 'gpt-5', display: 'GPT-5' },
19
- { id: 'gpt-4.1', display: 'GPT-4.1' },
20
- { id: 'gpt-4o', display: 'GPT-4o' },
21
- ],
22
- 'grok-oauth': [{ id: 'grok-4.5', display: 'Grok 4.5', latest: true }],
23
- xai: [{ id: 'grok-4.5', display: 'Grok 4.5', latest: true }],
24
- gemini: [
25
- { id: 'gemini-3.6-flash', display: 'Gemini 3.6 Flash', latest: true },
26
- { id: 'gemini-3.5-flash-lite', display: 'Gemini 3.5 Flash Lite', latest: true },
27
- { id: 'gemini-3.1-pro-preview', display: 'Gemini 3.1 Pro Preview' },
28
- ],
29
- 'anthropic-oauth': [
30
- { id: 'claude-opus-5-5', display: 'Claude Opus 5.5', latest: true },
31
- { id: 'claude-sonnet-5', display: 'Claude Sonnet 5', latest: true },
32
- { id: 'claude-fable-5', display: 'Claude Fable 5', latest: true },
33
- { id: 'claude-haiku-4-5-20251001', display: 'Claude Haiku 4.5' },
34
- ],
35
- anthropic: [
36
- { id: 'claude-opus-5-5', display: 'Claude Opus 5.5', latest: true },
37
- { id: 'claude-sonnet-5', display: 'Claude Sonnet 5', latest: true },
38
- { id: 'claude-fable-5', display: 'Claude Fable 5', latest: true },
39
- { id: 'claude-haiku-4-5-20251001', display: 'Claude Haiku 4.5' },
40
- ],
41
- });
9
+ const QUICK_ROWS_PER_PROVIDER = 5;
10
+
11
+ export function quickWebSearchModels(provider, models = getModelsDevProviderModelsSync(provider)) {
12
+ return Object.entries(models || {})
13
+ .map(([id, row]) => ({ id, display: row?.name || id, releaseDate: row?.release_date || null }))
14
+ .sort((a, b) => (Date.parse(b.releaseDate) || 0) - (Date.parse(a.releaseDate) || 0))
15
+ .slice(0, QUICK_ROWS_PER_PROVIDER);
16
+ }
@@ -5,6 +5,7 @@ import { publishGlobalExtensionChange, subscribeGlobalExtensionChanges } from '.
5
5
 
6
6
  export function createExtensionSync({
7
7
  connectConfiguredMcp,
8
+ cancelMcpLogin,
8
9
  invalidatePreSessionToolSurface,
9
10
  refreshEmptySessionToolPolicy,
10
11
  reloadFullConfig,
@@ -28,11 +29,13 @@ export function createExtensionSync({
28
29
  }
29
30
  }
30
31
 
31
- // Apply per-server MCP changes in order; every other server stays untouched.
32
+ // Apply per-server MCP changes in order, then reconcile: a configured server
33
+ // added, renamed or removed can move a plugin server to another name, and
34
+ // only the reconcile connects it there and drops the stale name. Servers
35
+ // whose resolved config is unchanged stay untouched.
32
36
  async function applyMcpChanges(changes) {
33
- let status;
34
- for (const { name, enabled } of changes) status = await connectConfiguredMcp({ only: name, enabled });
35
- return status;
37
+ for (const { name, enabled } of changes) await connectConfiguredMcp({ only: name, enabled });
38
+ return connectConfiguredMcp({ reconcile: true });
36
39
  }
37
40
 
38
41
  async function refreshState(kind, detail = null) {
@@ -41,7 +44,11 @@ export function createExtensionSync({
41
44
  const mcpChanges = kind === 'mcp' ? detail?.mcpChanges : null;
42
45
  if (Array.isArray(mcpChanges)) {
43
46
  await applyMcpChanges(mcpChanges);
44
- } else if (kind === 'mcp' || kind === 'plugins') {
47
+ } else if (kind === 'plugins') {
48
+ // Plugin servers are derived from the registry: connect what is new or
49
+ // changed, drop what is gone or disabled, leave the rest connected.
50
+ await connectConfiguredMcp({ reconcile: true });
51
+ } else if (kind === 'mcp') {
45
52
  await connectConfiguredMcp({ reset: true });
46
53
  }
47
54
  await refreshSurface(kind);
@@ -54,6 +61,9 @@ export function createExtensionSync({
54
61
  const chain = mcpToggleChains.get(serverName) || { desired: enabled, running: null };
55
62
  chain.desired = enabled;
56
63
  mcpToggleChains.set(serverName, chain);
64
+ // A disable riding the chain would otherwise wait out an explicit sign-in
65
+ // (beginMcpOAuthLogin) of this server still in flight.
66
+ if (enabled === false) cancelMcpLogin?.(serverName);
57
67
  if (!chain.running) {
58
68
  chain.running = (async () => {
59
69
  let status;
@@ -101,12 +111,21 @@ export function createExtensionSync({
101
111
  return status;
102
112
  }
103
113
 
114
+ /** After a plugin registry change: reconcile this runtime's MCP connections
115
+ * with the derived server set first, then let peers do the same. */
116
+ async function reconcilePluginsAndAnnounce() {
117
+ const status = await connectConfiguredMcp({ reconcile: true });
118
+ await announce('plugins');
119
+ return status;
120
+ }
121
+
104
122
  return {
105
123
  refreshSurface,
106
124
  publish,
107
125
  scheduleMcpToggle,
108
126
  announce,
109
127
  reconnectMcpAndAnnounce,
128
+ reconcilePluginsAndAnnounce,
110
129
  dispose: () => subscription.unsubscribe(),
111
130
  };
112
131
  }