mixdog 1.3.4 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (472) hide show
  1. package/LICENSES/oh-my-pi-MIT.txt +23 -0
  2. package/NOTICE.md +17 -2
  3. package/README.md +11 -0
  4. package/package.json +3 -11
  5. package/scripts/daemon-stub.mjs +1 -1
  6. package/scripts/embed-google-oauth-client.mjs +49 -0
  7. package/scripts/gate-local.mjs +4 -2
  8. package/scripts/lib/test-spawn-ledger.mjs +46 -1
  9. package/scripts/native-release-status.mjs +2 -2
  10. package/scripts/recall-history-cases.json +1 -1
  11. package/scripts/suite-health.mjs +10 -1
  12. package/scripts/test.mjs +12 -11
  13. package/src/agents/reviewer/AGENT.md +7 -11
  14. package/src/agents/reviewer/agent.json +1 -1
  15. package/src/defaults/shipped-history.json +25 -1
  16. package/src/defaults/skills/browser-use/SKILL.md +77 -17
  17. package/src/defaults/skills/code-tidy/SKILL.md +142 -270
  18. package/src/defaults/skills/code-tidy/references/agent-cleanup.md +4 -4
  19. package/src/defaults/skills/code-tidy/references/cleanup-report.md +31 -76
  20. package/src/defaults/skills/code-tidy/references/dead-code.md +6 -12
  21. package/src/defaults/skills/computer-use/SKILL.md +33 -9
  22. package/src/defaults/skills/setup/SKILL.md +29 -2
  23. package/src/defaults/skills/setup/references/actions.md +117 -28
  24. package/src/defaults/skills/setup/references/surfaces.md +77 -35
  25. package/src/defaults/skills/setup-guide/SKILL.md +3 -3
  26. package/src/defaults/skills/visualize/SKILL.md +2 -1
  27. package/src/lib/keychain-cjs.cjs +359 -29
  28. package/src/lib/rules-builder.cjs +10 -8
  29. package/src/rules/agent/AGENT.md +6 -6
  30. package/src/rules/agent-mode/AGENT_MODE.md +10 -2
  31. package/src/rules/agent-mode/MIXY.md +12 -0
  32. package/src/rules/lead/LEAD.md +18 -20
  33. package/src/rules/shared/05-tool-calls.md +5 -6
  34. package/src/rules/shared/10-tool-workflow.md +2 -0
  35. package/src/rules/shared/60-verification.md +7 -5
  36. package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +2 -3
  37. package/src/runtime/agent/orchestrator/agent-runtime/heartbeat-completion.mjs +193 -0
  38. package/src/runtime/agent/orchestrator/agent-runtime/title-completion.mjs +3 -1
  39. package/src/runtime/agent/orchestrator/agent-trace-format.mjs +3 -1
  40. package/src/runtime/agent/orchestrator/config.mjs +34 -0
  41. package/src/runtime/agent/orchestrator/context/collect.mjs +3 -0
  42. package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +72 -67
  43. package/src/runtime/agent/orchestrator/context/skill-catalog.mjs +54 -1
  44. package/src/runtime/agent/orchestrator/mcp/agent-connectors.mjs +3 -3
  45. package/src/runtime/agent/orchestrator/mcp/client-transport.mjs +177 -73
  46. package/src/runtime/agent/orchestrator/mcp/client.mjs +25 -2
  47. package/src/runtime/agent/orchestrator/mcp/oauth-callback.mjs +31 -2
  48. package/src/runtime/agent/orchestrator/mcp/oauth-client.mjs +16 -3
  49. package/src/runtime/agent/orchestrator/mcp/oauth-login.mjs +42 -7
  50. package/src/runtime/agent/orchestrator/mcp/oauth-provider.mjs +21 -2
  51. package/src/runtime/agent/orchestrator/mcp/oauth-shared.mjs +23 -0
  52. package/src/runtime/agent/orchestrator/mcp/oauth.mjs +11 -1
  53. package/src/runtime/agent/orchestrator/providers/account-pool.mjs +230 -137
  54. package/src/runtime/agent/orchestrator/providers/admission-scheduler.mjs +64 -7
  55. package/src/runtime/agent/orchestrator/providers/anthropic-api-request.mjs +18 -5
  56. package/src/runtime/agent/orchestrator/providers/anthropic-cache-warm.mjs +165 -0
  57. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
  58. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-credentials.mjs +4 -1
  59. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-request/gzip-post.mjs +14 -14
  60. package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +160 -69
  61. package/src/runtime/agent/orchestrator/providers/anthropic-overload-fallback.mjs +25 -3
  62. package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +64 -33
  63. package/src/runtime/agent/orchestrator/providers/anthropic.mjs +135 -87
  64. package/src/runtime/agent/orchestrator/providers/antigravity-oauth-catalog.mjs +52 -8
  65. package/src/runtime/agent/orchestrator/providers/antigravity-oauth.mjs +10 -1
  66. package/src/runtime/agent/orchestrator/providers/antigravity-request.mjs +22 -6
  67. package/src/runtime/agent/orchestrator/providers/antigravity-response.mjs +15 -4
  68. package/src/runtime/agent/orchestrator/providers/antigravity-stream.mjs +17 -2
  69. package/src/runtime/agent/orchestrator/providers/antigravity-transport.mjs +142 -104
  70. package/src/runtime/agent/orchestrator/providers/cache-warm-admission.mjs +90 -0
  71. package/src/runtime/agent/orchestrator/providers/codex-client-meta.mjs +1 -1
  72. package/src/runtime/agent/orchestrator/providers/cursor-wire-normalization.mjs +10 -4
  73. package/src/runtime/agent/orchestrator/providers/cursor-wire-protobuf.mjs +10 -217
  74. package/src/runtime/agent/orchestrator/providers/cursor-wire-transport.mjs +25 -9
  75. package/src/runtime/agent/orchestrator/providers/cursor.mjs +22 -6
  76. package/src/runtime/agent/orchestrator/providers/devin-auth.mjs +409 -0
  77. package/src/runtime/agent/orchestrator/providers/devin-wire-families.mjs +187 -0
  78. package/src/runtime/agent/orchestrator/providers/devin-wire-identity.mjs +342 -0
  79. package/src/runtime/agent/orchestrator/providers/devin-wire-models.mjs +541 -0
  80. package/src/runtime/agent/orchestrator/providers/devin-wire-protobuf.mjs +305 -0
  81. package/src/runtime/agent/orchestrator/providers/devin-wire-request.mjs +558 -0
  82. package/src/runtime/agent/orchestrator/providers/devin-wire-schema.mjs +880 -0
  83. package/src/runtime/agent/orchestrator/providers/devin-wire-session.mjs +190 -0
  84. package/src/runtime/agent/orchestrator/providers/devin-wire-tool-args.mjs +351 -0
  85. package/src/runtime/agent/orchestrator/providers/devin-wire-transport.mjs +560 -0
  86. package/src/runtime/agent/orchestrator/providers/devin.mjs +491 -0
  87. package/src/runtime/agent/orchestrator/providers/effort-configuration.mjs +3 -0
  88. package/src/runtime/agent/orchestrator/providers/gemini-output-limit.mjs +46 -0
  89. package/src/runtime/agent/orchestrator/providers/gemini-reasoning-relay.mjs +30 -0
  90. package/src/runtime/agent/orchestrator/providers/gemini-request-body.mjs +7 -11
  91. package/src/runtime/agent/orchestrator/providers/gemini-retry-policy.mjs +61 -22
  92. package/src/runtime/agent/orchestrator/providers/gemini-sdk-request.mjs +1 -0
  93. package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +71 -4
  94. package/src/runtime/agent/orchestrator/providers/gemini.mjs +25 -2
  95. package/src/runtime/agent/orchestrator/providers/grok-client-version.mjs +1 -1
  96. package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +96 -5
  97. package/src/runtime/agent/orchestrator/providers/lib/oauth-token-utils.mjs +17 -3
  98. package/src/runtime/agent/orchestrator/providers/lib/tail-reminder-split.mjs +23 -5
  99. package/src/runtime/agent/orchestrator/providers/media-normalization.mjs +52 -10
  100. package/src/runtime/agent/orchestrator/providers/model-proxy-channel.d.mts +8 -1
  101. package/src/runtime/agent/orchestrator/providers/model-proxy-channel.mjs +1 -0
  102. package/src/runtime/agent/orchestrator/providers/npm-cli-version.mjs +11 -3
  103. package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +19 -1
  104. package/src/runtime/agent/orchestrator/providers/oauth-usage.mjs +39 -3
  105. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-state.mjs +3 -1
  106. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream.mjs +2 -0
  107. package/src/runtime/agent/orchestrator/providers/openai-error-contract.mjs +6 -1
  108. package/src/runtime/agent/orchestrator/providers/openai-oauth-tokens.mjs +10 -9
  109. package/src/runtime/agent/orchestrator/providers/openai-ws-send/send-context.mjs +22 -3
  110. package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/attempt-context.mjs +43 -5
  111. package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/handshake-failure.mjs +3 -1
  112. package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/stream-failure.mjs +6 -3
  113. package/src/runtime/agent/orchestrator/providers/opencode-go-gemini.mjs +1 -0
  114. package/src/runtime/agent/orchestrator/providers/provider-availability.mjs +19 -0
  115. package/src/runtime/agent/orchestrator/providers/provider-error-kind.mjs +65 -1
  116. package/src/runtime/agent/orchestrator/providers/quota-reading.mjs +38 -12
  117. package/src/runtime/agent/orchestrator/providers/registry.mjs +43 -3
  118. package/src/runtime/agent/orchestrator/providers/retry-executor.mjs +39 -7
  119. package/src/runtime/agent/orchestrator/providers/statusline-route-meta.mjs +6 -0
  120. package/src/runtime/agent/orchestrator/providers/wire-protobuf-codec.mjs +368 -0
  121. package/src/runtime/agent/orchestrator/runtime-core/ask-user-tool-defs.mjs +12 -7
  122. package/src/runtime/agent/orchestrator/runtime-core/builtin-features.mjs +2 -0
  123. package/src/runtime/agent/orchestrator/runtime-core/compaction-config-keys.mjs +62 -0
  124. package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +37 -16
  125. package/src/runtime/agent/orchestrator/runtime-core/deferred-tool-delta.mjs +100 -23
  126. package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +1 -1
  127. package/src/runtime/agent/orchestrator/runtime-core/reaction-tool-defs.mjs +133 -0
  128. package/src/runtime/agent/orchestrator/runtime-core/session-text.mjs +2 -0
  129. package/src/runtime/agent/orchestrator/runtime-core/tool-bridge.mjs +19 -4
  130. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog-data.mjs +3 -0
  131. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +125 -30
  132. package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +23 -5
  133. package/src/runtime/agent/orchestrator/runtime-core/tool-profile.mjs +35 -10
  134. package/src/runtime/agent/orchestrator/runtime-core/workflow/agents.mjs +57 -10
  135. package/src/runtime/agent/orchestrator/runtime-core/workflow/context.mjs +9 -6
  136. package/src/runtime/agent/orchestrator/runtime-core/workflow-ids.mjs +1 -1
  137. package/src/runtime/agent/orchestrator/session/agent-loop.mjs +18 -0
  138. package/src/runtime/agent/orchestrator/session/agent-room.d.mts +0 -3
  139. package/src/runtime/agent/orchestrator/session/agent-room.mjs +10 -4
  140. package/src/runtime/agent/orchestrator/session/cache-warm.mjs +792 -0
  141. package/src/runtime/agent/orchestrator/session/compact/runner.mjs +148 -25
  142. package/src/runtime/agent/orchestrator/session/compaction-archive-capture.mjs +475 -58
  143. package/src/runtime/agent/orchestrator/session/compaction-archive.mjs +42 -17
  144. package/src/runtime/agent/orchestrator/session/eager-dispatch.mjs +8 -0
  145. package/src/runtime/agent/orchestrator/session/human-gate/gate.mjs +47 -9
  146. package/src/runtime/agent/orchestrator/session/human-gate/outbound-policy.mjs +6 -2
  147. package/src/runtime/agent/orchestrator/session/human-gate/requests.mjs +36 -4
  148. package/src/runtime/agent/orchestrator/session/human-gate/store.mjs +14 -2
  149. package/src/runtime/agent/orchestrator/session/loop/assistant-commit.mjs +8 -0
  150. package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +18 -22
  151. package/src/runtime/agent/orchestrator/session/loop/fresh-context.mjs +32 -3
  152. package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +11 -2
  153. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/segments.mjs +4 -1
  154. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn.mjs +51 -3
  155. package/src/runtime/agent/orchestrator/session/loop/route-fallback.mjs +17 -3
  156. package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +10 -2
  157. package/src/runtime/agent/orchestrator/session/loop/tool-exec/after-hook.mjs +2 -1
  158. package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +14 -4
  159. package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +16 -2
  160. package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +16 -1
  161. package/src/runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs +10 -0
  162. package/src/runtime/agent/orchestrator/session/loop/tool-helpers.mjs +3 -10
  163. package/src/runtime/agent/orchestrator/session/loop/tool-phase.mjs +23 -5
  164. package/src/runtime/agent/orchestrator/session/loop/turn-limits.mjs +60 -0
  165. package/src/runtime/agent/orchestrator/session/manager/ask-queue.mjs +12 -2
  166. package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +19 -1
  167. package/src/runtime/agent/orchestrator/session/manager/ask-turn-commit.mjs +2 -0
  168. package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +133 -90
  169. package/src/runtime/agent/orchestrator/session/manager/ask-turn-loop-options.mjs +14 -0
  170. package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +2 -1
  171. package/src/runtime/agent/orchestrator/session/manager/ask-turn-state.mjs +31 -4
  172. package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +30 -18
  173. package/src/runtime/agent/orchestrator/session/manager/owner-route-fallbacks.mjs +23 -13
  174. package/src/runtime/agent/orchestrator/session/manager/pending-message-entry.mjs +11 -2
  175. package/src/runtime/agent/orchestrator/session/manager/provider-replay.mjs +13 -0
  176. package/src/runtime/agent/orchestrator/session/manager/route-fallback-chain.mjs +129 -0
  177. package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +20 -2
  178. package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +2 -0
  179. package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +8 -0
  180. package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +1 -1
  181. package/src/runtime/agent/orchestrator/session/manager/session-tool-surface.mjs +13 -0
  182. package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +7 -2
  183. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-journal.mjs +102 -15
  184. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint.mjs +18 -5
  185. package/src/runtime/agent/orchestrator/session/message-ids.mjs +5 -3
  186. package/src/runtime/agent/orchestrator/session/message-reactions.mjs +89 -0
  187. package/src/runtime/agent/orchestrator/session/message-reactions.test-support.mjs +75 -0
  188. package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +19 -8
  189. package/src/runtime/agent/orchestrator/session/prompt-cache-idle-gaps.mjs +113 -0
  190. package/src/runtime/agent/orchestrator/session/prompt-cache-touch-store.mjs +127 -0
  191. package/src/runtime/agent/orchestrator/session/routine-result.d.mts +0 -2
  192. package/src/runtime/agent/orchestrator/session/routine-result.mjs +47 -11
  193. package/src/runtime/agent/orchestrator/session/send-with-recovery.mjs +20 -2
  194. package/src/runtime/agent/orchestrator/session/sensitive-projection.mjs +100 -0
  195. package/src/runtime/agent/orchestrator/session/sensitive-values.mjs +257 -0
  196. package/src/runtime/agent/orchestrator/session/side-question-store.mjs +20 -7
  197. package/src/runtime/agent/orchestrator/session/side-question.mjs +18 -0
  198. package/src/runtime/agent/orchestrator/session/skill-update-notice.mjs +60 -0
  199. package/src/runtime/agent/orchestrator/session/store/live-state.mjs +6 -3
  200. package/src/runtime/agent/orchestrator/session/store/save-delta.mjs +9 -5
  201. package/src/runtime/agent/orchestrator/session/store/serialize.mjs +9 -8
  202. package/src/runtime/agent/orchestrator/session/store/session-persistence-events.mjs +29 -0
  203. package/src/runtime/agent/orchestrator/session/store-agent-worker-header-cache.mjs +85 -0
  204. package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +133 -18
  205. package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +12 -2
  206. package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +44 -14
  207. package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +84 -3
  208. package/src/runtime/agent/orchestrator/session/stored-attachment-history.mjs +32 -0
  209. package/src/runtime/agent/orchestrator/session/tail-reminder-rules.mjs +11 -5
  210. package/src/runtime/agent/orchestrator/session/thinking-binding.mjs +108 -0
  211. package/src/runtime/agent/orchestrator/session/tool-batch/pre-dispatch.mjs +2 -2
  212. package/src/runtime/agent/orchestrator/session/tool-batch/record-outcome.mjs +2 -1
  213. package/src/runtime/agent/orchestrator/session/tool-batch/state.mjs +4 -0
  214. package/src/runtime/agent/orchestrator/session/tool-batch.mjs +5 -0
  215. package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +25 -2
  216. package/src/runtime/agent/orchestrator/session/transcript-restore/tool-result-status.mjs +9 -7
  217. package/src/runtime/agent/orchestrator/session/transcript-restore/tool-result-text.mjs +2 -2
  218. package/src/runtime/agent/orchestrator/session/turn-failure.mjs +5 -1
  219. package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +5 -2
  220. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/backgrounded-result.mjs +12 -1
  221. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/misuse-guard.mjs +240 -0
  222. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/result-format.mjs +1 -1
  223. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/shell-cwd.mjs +38 -0
  224. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +25 -5
  225. package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +65 -7
  226. package/src/runtime/agent/orchestrator/tools/builtin/shell-runtime.mjs +7 -1
  227. package/src/runtime/agent/orchestrator/tools/shell-command.mjs +36 -13
  228. package/src/runtime/browser-bridge/action-schema.mjs +13 -2
  229. package/src/runtime/browser-bridge/client.mjs +73 -8
  230. package/src/runtime/browser-bridge/input-fields.mjs +8 -9
  231. package/src/runtime/browser-bridge/mail-links.mjs +107 -0
  232. package/src/runtime/browser-bridge/tool-defs.mjs +1 -1
  233. package/src/runtime/channels/lib/config.mjs +6 -61
  234. package/src/runtime/channels/lib/crash-log.mjs +1 -1
  235. package/src/runtime/channels/lib/event-pipeline.mjs +4 -19
  236. package/src/runtime/channels/lib/event-queue.mjs +3 -18
  237. package/src/runtime/channels/lib/owned-runtime/automation-services.mjs +2 -2
  238. package/src/runtime/channels/lib/owned-runtime/automation-start.mjs +3 -4
  239. package/src/runtime/channels/lib/owned-runtime/config-reload.mjs +4 -59
  240. package/src/runtime/channels/lib/owned-runtime/owned-start.mjs +33 -115
  241. package/src/runtime/channels/lib/owned-runtime/owned-stop.mjs +5 -22
  242. package/src/runtime/channels/lib/owned-runtime/state.mjs +2 -8
  243. package/src/runtime/channels/lib/owned-runtime.mjs +6 -23
  244. package/src/runtime/channels/lib/parent-bridge.mjs +2 -2
  245. package/src/runtime/channels/lib/runtime-paths.mjs +4 -43
  246. package/src/runtime/channels/lib/schedule-errors.mjs +51 -0
  247. package/src/runtime/channels/lib/scheduler.mjs +135 -154
  248. package/src/runtime/channels/lib/schedules-db.mjs +83 -11
  249. package/src/runtime/channels/lib/status-snapshot.mjs +1 -1
  250. package/src/runtime/channels/lib/tool-dispatch.mjs +14 -2
  251. package/src/runtime/channels/lib/webhooks-db.mjs +5 -9
  252. package/src/runtime/channels/lib/worker-bootstrap.mjs +0 -1
  253. package/src/runtime/channels/lib/worker-ipc.mjs +0 -1
  254. package/src/runtime/channels/lib/worker-main.mjs +19 -34
  255. package/src/runtime/computer-bridge/action-schema.mjs +42 -1
  256. package/src/runtime/computer-bridge/actions.mjs +9 -1
  257. package/src/runtime/computer-bridge/client.mjs +180 -8
  258. package/src/runtime/computer-bridge/core-actions.mjs +2 -2
  259. package/src/runtime/computer-bridge/error-recovery.mjs +27 -2
  260. package/src/runtime/computer-bridge/linux-readiness.mjs +65 -23
  261. package/src/runtime/computer-bridge/pending-continuation.mjs +1 -1
  262. package/src/runtime/connectors/connector-accounts-mcp.mjs +230 -0
  263. package/src/runtime/connectors/gmail-app-password.mjs +172 -39
  264. package/src/runtime/connectors/google-mcp.mjs +10 -12
  265. package/src/runtime/memory/lib/pg/adapter.mjs +77 -70
  266. package/src/runtime/memory/lib/pg/supervisor.mjs +24 -12
  267. package/src/runtime/memory/lib/runtime-fetcher.mjs +23 -5
  268. package/src/runtime/office/com/com-adapter.mjs +17 -1
  269. package/src/runtime/office/com/office-com-host.ps1 +51 -1
  270. package/src/runtime/office/pdf/cfb-fixture.mjs +328 -0
  271. package/src/runtime/office/pdf/cfb-protection.mjs +311 -0
  272. package/src/runtime/office/pdf/document-preview.mjs +326 -8
  273. package/src/runtime/office/pdf/ooxml-crypto.mjs +469 -0
  274. package/src/runtime/office/pdf/ooxml-key-worker.mjs +14 -0
  275. package/src/runtime/office/portable/portable-soffice.mjs +45 -5
  276. package/src/runtime/session-search/session-search-db.mjs +73 -9
  277. package/src/runtime/session-search/session-search-ingest.mjs +110 -20
  278. package/src/runtime/shared/abort-race.mjs +89 -0
  279. package/src/runtime/shared/agent-avatar.d.mts +0 -1
  280. package/src/runtime/shared/agent-kind.mjs +4 -3
  281. package/src/runtime/shared/bot-hops.mjs +62 -2
  282. package/src/runtime/shared/bounded-download.mjs +8 -3
  283. package/src/runtime/shared/config.mjs +51 -35
  284. package/src/runtime/shared/connector-accounts.mjs +20 -10
  285. package/src/runtime/shared/connector-catalog.d.mts +33 -2
  286. package/src/runtime/shared/connector-catalog.mjs +166 -8
  287. package/src/runtime/shared/connector-triggers.mjs +22 -19
  288. package/src/runtime/shared/defaults-separation.mjs +2 -14
  289. package/src/runtime/shared/delegated-approval-host.mjs +103 -11
  290. package/src/runtime/shared/developer-options.mjs +32 -1
  291. package/src/runtime/shared/err-text.mjs +24 -15
  292. package/src/runtime/shared/file-permissions.d.mts +0 -8
  293. package/src/runtime/shared/file-permissions.mjs +0 -11
  294. package/src/runtime/shared/git-direct.test-support.mjs +19 -0
  295. package/src/runtime/shared/google-oauth-client.generated.json +4 -0
  296. package/src/runtime/shared/google-oauth-client.mjs +34 -9
  297. package/src/runtime/shared/heartbeat-interval.d.mts +4 -0
  298. package/src/runtime/shared/heartbeat-interval.mjs +19 -0
  299. package/src/runtime/shared/idle-auto-clear-gate.mjs +104 -0
  300. package/src/runtime/shared/llm/anthropic-betas.mjs +7 -0
  301. package/src/runtime/shared/llm/anthropic-thinking-contract.mjs +12 -0
  302. package/src/runtime/shared/llm/provider-catalog-registry.mjs +1 -0
  303. package/src/runtime/shared/llm/usage-rollup.mjs +1 -1
  304. package/src/runtime/shared/llm/well-formed.mjs +66 -0
  305. package/src/runtime/shared/mixy-presence.mjs +22 -0
  306. package/src/runtime/shared/orchestration.d.mts +2 -0
  307. package/src/runtime/shared/pg-schema-db.mjs +27 -16
  308. package/src/runtime/shared/profile-config.cjs +1 -1
  309. package/src/runtime/shared/prompt-origin.d.mts +4 -0
  310. package/src/runtime/shared/prompt-origin.mjs +21 -0
  311. package/src/runtime/shared/provider-accounts.mjs +231 -59
  312. package/src/runtime/shared/provider-api-key.mjs +19 -8
  313. package/src/runtime/shared/provider-display-name.mjs +29 -0
  314. package/src/runtime/shared/provider-timeout-phase.mjs +2 -0
  315. package/src/runtime/shared/routine-trigger.d.mts +2 -0
  316. package/src/runtime/shared/routine-trigger.mjs +52 -0
  317. package/src/runtime/shared/sensitive-path-rules.d.mts +2 -10
  318. package/src/runtime/shared/sensitive-path-rules.mjs +19 -41
  319. package/src/runtime/shared/session-activity-signal.mjs +34 -1
  320. package/src/runtime/shared/session-sidebar-host.d.mts +1 -1
  321. package/src/runtime/shared/session-sidebar-host.mjs +7 -3
  322. package/src/runtime/shared/session-turn-prelude.mjs +18 -0
  323. package/src/runtime/shared/tool-execution-contract.mjs +2 -0
  324. package/src/runtime/shared/tool-result-summary.mjs +1 -14
  325. package/src/runtime/shared/transcript-metadata.mjs +38 -0
  326. package/src/runtime/shared/user-data-guard.mjs +30 -2
  327. package/src/runtime/shared/worktrees/activity-gate.mjs +12 -5
  328. package/src/runtime/shared/worktrees/test-support.mjs +9 -4
  329. package/src/runtime/terminal-bridge/client.mjs +10 -1
  330. package/src/runtime/visualize-bridge/client.mjs +27 -8
  331. package/src/runtime/visualize-bridge/tool-defs.mjs +22 -8
  332. package/src/runtime/visualize-bridge/tool-meta.d.mts +5 -0
  333. package/src/runtime/visualize-bridge/tool-meta.mjs +22 -0
  334. package/src/runtime/web-search/lib/fetch-pipeline.mjs +2 -2
  335. package/src/session-runtime/agent-home-delivery.mjs +486 -179
  336. package/src/session-runtime/agent-room-delivery.mjs +28 -1
  337. package/src/session-runtime/agent-task-sessions.mjs +561 -199
  338. package/src/session-runtime/boot/apis.mjs +9 -0
  339. package/src/session-runtime/boot/begin.mjs +3 -2
  340. package/src/session-runtime/boot/infrastructure.mjs +4 -0
  341. package/src/session-runtime/boot/providers.mjs +3 -0
  342. package/src/session-runtime/boot/tools.mjs +8 -1
  343. package/src/session-runtime/bot-chain.mjs +32 -0
  344. package/src/session-runtime/bot-status.mjs +7 -4
  345. package/src/session-runtime/channel-config-api.mjs +63 -17
  346. package/src/session-runtime/config-lifecycle.mjs +6 -0
  347. package/src/session-runtime/connector-merge-migration.mjs +305 -0
  348. package/src/session-runtime/internal-tool-executor/ask-user-tool.mjs +132 -28
  349. package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +2 -0
  350. package/src/session-runtime/internal-tool-executor/reaction-tool.mjs +45 -0
  351. package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +72 -5
  352. package/src/session-runtime/internal-tool-executor.mjs +4 -0
  353. package/src/session-runtime/lifecycle/inheritance.mjs +16 -3
  354. package/src/session-runtime/lifecycle/session-catalog.mjs +3 -1
  355. package/src/session-runtime/lifecycle/teardown/runtime-stops.mjs +50 -4
  356. package/src/session-runtime/lifecycle/teardown.mjs +23 -5
  357. package/src/session-runtime/mcp-glue/server-catalog.mjs +61 -3
  358. package/src/session-runtime/mcp-oauth-login.mjs +5 -3
  359. package/src/session-runtime/mixy-heartbeat.mjs +927 -0
  360. package/src/session-runtime/model-route/route-tuning.mjs +10 -6
  361. package/src/session-runtime/notification-bus.mjs +31 -117
  362. package/src/session-runtime/notification-completion-queue.mjs +54 -0
  363. package/src/session-runtime/notification-listeners.mjs +76 -0
  364. package/src/session-runtime/owned-automation-run.mjs +35 -13
  365. package/src/session-runtime/prewarm/channel-start.mjs +3 -7
  366. package/src/session-runtime/provider-auth/login.mjs +7 -0
  367. package/src/session-runtime/provider-models/row-hydration.mjs +13 -2
  368. package/src/session-runtime/resource-mcp-api.mjs +143 -224
  369. package/src/session-runtime/resource-mcp-connector-accounts.mjs +163 -0
  370. package/src/session-runtime/resource-mcp-oauth-api.mjs +217 -0
  371. package/src/session-runtime/resource-mcp-secrets.mjs +82 -0
  372. package/src/session-runtime/resource-mcp-servers.mjs +78 -0
  373. package/src/session-runtime/resource-mcp-store.mjs +49 -0
  374. package/src/session-runtime/routine-home-turn.mjs +33 -6
  375. package/src/session-runtime/routine-owner.mjs +40 -9
  376. package/src/session-runtime/schedule-session-run.mjs +7 -3
  377. package/src/session-runtime/services/agent-tool/close-flow.mjs +3 -0
  378. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-plan.mjs +8 -12
  379. package/src/session-runtime/services/agent-tool/spawn-preset.mjs +7 -2
  380. package/src/session-runtime/services/agent-tool/tag-registry.mjs +1 -0
  381. package/src/session-runtime/services/agent-tool/worker-index/awaiting-user-sync.mjs +51 -0
  382. package/src/session-runtime/services/agent-tool/worker-index/disposal.mjs +55 -0
  383. package/src/session-runtime/services/agent-tool/worker-index/released-store.mjs +123 -0
  384. package/src/session-runtime/services/agent-tool/worker-index/restart-settlement.mjs +112 -0
  385. package/src/session-runtime/services/agent-tool/worker-index/row-reads.mjs +36 -0
  386. package/src/session-runtime/services/agent-tool/worker-index/row-shape.mjs +2 -0
  387. package/src/session-runtime/services/agent-tool/worker-index/row-store.mjs +17 -4
  388. package/src/session-runtime/services/agent-tool/worker-index/row-writes.mjs +58 -0
  389. package/src/session-runtime/services/agent-tool/worker-index.mjs +41 -241
  390. package/src/session-runtime/services/agent-tool/worker-rows.mjs +3 -0
  391. package/src/session-runtime/services/channel-admin.mjs +73 -31
  392. package/src/session-runtime/services/channel-session-router.mjs +4 -2
  393. package/src/session-runtime/services/channel-worker.mjs +1 -1
  394. package/src/session-runtime/services/provider-admin.mjs +128 -25
  395. package/src/session-runtime/services/schedule-access.mjs +14 -0
  396. package/src/session-runtime/services/seeds.mjs +0 -28
  397. package/src/session-runtime/services/usage-dashboard-model.mjs +1 -0
  398. package/src/session-runtime/session-compaction-sync.mjs +27 -0
  399. package/src/session-runtime/session-create/session-options.mjs +8 -4
  400. package/src/session-runtime/settings-builtin-tools-api.mjs +11 -0
  401. package/src/session-runtime/settings-compaction-api.mjs +2 -40
  402. package/src/session-runtime/settings-system-api.mjs +28 -1
  403. package/src/session-runtime/setup-tool/agent-settings-actions.mjs +65 -0
  404. package/src/session-runtime/setup-tool/executor.mjs +187 -29
  405. package/src/session-runtime/setup-tool/extended-actions.mjs +33 -2
  406. package/src/session-runtime/setup-tool/session-route-actions.mjs +152 -0
  407. package/src/session-runtime/setup-tool/settings-contract.mjs +68 -6
  408. package/src/session-runtime/setup-tool/tool-defs.mjs +92 -6
  409. package/src/session-runtime/task-session-route.mjs +99 -0
  410. package/src/session-runtime/tool-policy/agent-profile-fold.mjs +17 -13
  411. package/src/session-runtime/tool-policy/policy-stage.mjs +21 -4
  412. package/src/session-runtime/tool-policy/surface-helpers.mjs +2 -3
  413. package/src/session-runtime/tool-surface.mjs +4 -0
  414. package/src/session-runtime/turn/turn-run/ask-callbacks.mjs +1 -0
  415. package/src/session-runtime/workflow-agents-api/agent-editor.mjs +98 -21
  416. package/src/session-runtime/workflow-agents-api/style-and-mode.mjs +4 -0
  417. package/src/session-runtime/workflow-agents-api/workflow-packs.mjs +6 -1
  418. package/src/session-runtime/workspace/transitions.mjs +10 -2
  419. package/src/standalone/channel-transport/client-registry/client-records.mjs +65 -0
  420. package/src/standalone/channel-transport/client-registry/client-registration.mjs +118 -0
  421. package/src/standalone/channel-transport/client-registry.mjs +24 -163
  422. package/src/standalone/channel-transport.mjs +1 -1
  423. package/src/standalone/daemon-channels-loader.mjs +10 -8
  424. package/src/standalone/daemon-session-control/list-page.mjs +72 -0
  425. package/src/standalone/daemon-session-control/request.mjs +51 -0
  426. package/src/standalone/daemon-session-control/room-host.mjs +57 -0
  427. package/src/standalone/daemon-session-control/route-control.mjs +48 -0
  428. package/src/standalone/daemon-session-control/send-turn.mjs +60 -0
  429. package/src/standalone/daemon-session-control/worktree-control.mjs +40 -0
  430. package/src/standalone/daemon-session-control.mjs +161 -157
  431. package/src/standalone/daemon.mjs +33 -2
  432. package/src/standalone/session-client.mjs +7 -3
  433. package/src/standalone/session-protocol.mjs +10 -0
  434. package/src/standalone/session-service/agent-tree/agent-cancel.mjs +6 -2
  435. package/src/standalone/session-service/agent-tree/agent-child.mjs +1 -0
  436. package/src/standalone/session-service/quota-resume.mjs +3 -0
  437. package/src/standalone/session-service/retention/busy.mjs +65 -1
  438. package/src/standalone/session-service/session-calls/session-action.mjs +23 -2
  439. package/src/standalone/session-service/session-calls/session-turns.mjs +6 -0
  440. package/src/standalone/session-service/session-calls/session-views.mjs +8 -0
  441. package/src/standalone/session-service.mjs +13 -0
  442. package/src/standalone/session-tool-output.mjs +21 -10
  443. package/src/tui/app/model-options.mjs +4 -27
  444. package/src/tui/dist/index.mjs +81 -65
  445. package/src/tui/session/agent-job-feed/model-notification.mjs +3 -0
  446. package/src/tui/session/initial-state.mjs +3 -0
  447. package/src/tui/session/notice-surface.mjs +23 -1
  448. package/src/tui/session/queue-helpers.mjs +3 -42
  449. package/src/tui/session/session-api/integrations.mjs +1 -0
  450. package/src/tui/session/session-api/lifecycle.mjs +8 -0
  451. package/src/tui/session/session-api/routes-agent-definitions.mjs +14 -2
  452. package/src/tui/session/session-api/routes-write.mjs +5 -1
  453. package/src/tui/session/session-api/routes.mjs +1 -0
  454. package/src/tui/session/session-api/settings.mjs +30 -2
  455. package/src/tui/session/session-flow/auto-clear.mjs +4 -33
  456. package/src/tui/session/session-flow/drain-closed-queue.mjs +38 -0
  457. package/src/tui/session/session-flow/drain-enqueue.mjs +86 -0
  458. package/src/tui/session/session-flow/drain-retry.mjs +35 -0
  459. package/src/tui/session/session-flow/drain.mjs +118 -149
  460. package/src/tui/session/session-flow/queue/entry-shape.mjs +5 -0
  461. package/src/tui/session/session-flow/queue/take-entries.mjs +5 -2
  462. package/src/tui/session/tool-approval-delegation.mjs +64 -0
  463. package/src/tui/session/tool-approval-request.mjs +39 -0
  464. package/src/tui/session/tool-approval-settle.mjs +62 -0
  465. package/src/tui/session/tool-approval.mjs +69 -115
  466. package/src/tui/session/tui-steering-persist.mjs +8 -1
  467. package/src/tui/session/turn-stream.mjs +36 -3
  468. package/src/tui/session/turn.mjs +23 -2
  469. package/src/vendor/statusline/bin/statusline-route.mjs +1 -219
  470. package/src/vendor/statusline/src/gateway/route-meta.mjs +35 -13
  471. package/scripts/code-graph-description-contract.mjs +0 -188
  472. package/src/runtime/channels/lib/owned-runtime/ownership-refresh.mjs +0 -36
@@ -5,6 +5,7 @@
5
5
  // to the older fields (httpStatus, responseFailed, providerError, SDK error
6
6
  // bodies, RPC status strings). Message text is consulted only for untyped
7
7
  // errors and only for unambiguous wordings.
8
+ import { TIMEOUT_PHASE, isFirstByteTimeout } from '../../../shared/provider-timeout-phase.mjs';
8
9
 
9
10
  export const PROVIDER_ERROR_KINDS = Object.freeze([
10
11
  'overloaded',
@@ -391,6 +392,13 @@ const CODE_KINDS = new Map(
391
392
  }).flatMap(([kind, codes]) => codes.map((code) => [code, kind]))
392
393
  );
393
394
  const RESOURCE_EXHAUSTED = 'resource_exhausted';
395
+
396
+ /** True when `code` is one of the provider error codes this module classifies
397
+ * (rate/usage limits, quota, overload, server/transient, context length,
398
+ * model not found, auth, policy, …): a known vocabulary word, never free text. */
399
+ function isKnownProviderErrorCode(code) {
400
+ return typeof code === 'string' && (CODE_KINDS.has(code) || code === RESOURCE_EXHAUSTED);
401
+ }
394
402
  // When several typed codes are present (an envelope type plus a specific
395
403
  // code), the most specific verdict wins.
396
404
  const KIND_RANK = [
@@ -435,7 +443,7 @@ const GATEWAY_ERROR_TYPE_CODES = Object.freeze({
435
443
  });
436
444
 
437
445
  /** The typed code a gateway `error_type` names, or null for an absent/unmapped one. */
438
- export function gatewayErrorTypeCode(errorType) {
446
+ function gatewayErrorTypeCode(errorType) {
439
447
  const key = typeof errorType === 'string' ? errorType.trim().toLowerCase() : '';
440
448
  return key && Object.hasOwn(GATEWAY_ERROR_TYPE_CODES, key) ? GATEWAY_ERROR_TYPE_CODES[key] : null;
441
449
  }
@@ -718,6 +726,62 @@ export function providerErrorKind(err, options = {}) {
718
726
  return describe(kind, code || undefined);
719
727
  }
720
728
 
729
+ // ── Retry reason, without server text ───────────────────────────────────────
730
+ // A server error's free text can echo request content (prompt, tokens,
731
+ // account ids), so neither the retry trace nor the reconnect status carries
732
+ // it: only a fixed reason class derived from typed status/code, and a code
733
+ // only when it is a known provider error code (an identifier-shaped value can
734
+ // still be private, e.g. an account id in a `code` field).
735
+ const SERVER_ERROR_CODES = new Set([
736
+ 'server_error',
737
+ 'api_error',
738
+ 'internal',
739
+ 'internal_error',
740
+ 'unavailable',
741
+ 'service_unavailable',
742
+ ]);
743
+ // Responses failure codes the WS retry classifier acts on beyond the shared
744
+ // provider vocabulary.
745
+ const WS_RETRY_ERROR_CODES = new Set(['auth_context_expired', 'auth_expired']);
746
+
747
+ /** The typed error code when it is a known provider error code; null otherwise. */
748
+ export function safeRetryErrorCode(err) {
749
+ const code = providerErrorKind(err).code;
750
+ return isKnownProviderErrorCode(code) || WS_RETRY_ERROR_CODES.has(code) ? code : null;
751
+ }
752
+
753
+ const STALL_ERROR_NAMES = new Set(['StreamStalledError', 'StreamStalledAbortError']);
754
+
755
+ /**
756
+ * One of rate_limited / overloaded / server_error / auth / first_response_timeout /
757
+ * stalled / other. The timeout classes read our own typed timeout stamps
758
+ * (name, code, timeoutPhase), never message text.
759
+ */
760
+ export function retryReasonClass(err) {
761
+ const { kind, status } = providerErrorKind(err);
762
+ const code = safeRetryErrorCode(err);
763
+ if (kind === 'rate_limited' || kind === 'quota_exhausted' || status === 429) return 'rate_limited';
764
+ if (kind === 'overloaded' || status === 529) return 'overloaded';
765
+ if (kind === 'auth' || kind === 'permission' || status === 401 || status === 403) return 'auth';
766
+ // A token-refresh timeout is a sign-in problem, not a slow model.
767
+ if (err?.timeoutPhase === TIMEOUT_PHASE.AUTH) return 'auth';
768
+ if ((status >= 500 && status < 600) || (code && SERVER_ERROR_CODES.has(code))) return 'server_error';
769
+ if (err?.timeoutPhase === TIMEOUT_PHASE.IDLE || STALL_ERROR_NAMES.has(err?.name) || err?.code === 'ESTREAMSTALL') {
770
+ return 'stalled';
771
+ }
772
+ // `firstByteTimeout` is the stamp the Anthropic first-message and OpenAI
773
+ // WS/HTTP first-event watchdogs put on their errors.
774
+ if (
775
+ isFirstByteTimeout(err) ||
776
+ err?.firstByteTimeout === true ||
777
+ err?.name === 'ProviderTimeoutError' ||
778
+ err?.code === 'EPROVIDERTIMEOUT'
779
+ ) {
780
+ return 'first_response_timeout';
781
+ }
782
+ return 'other';
783
+ }
784
+
721
785
  /** Kinds whose refusal no wait or replay can change: quota, plan and billing. */
722
786
  export const QUOTA_KINDS = new Set(['quota_exhausted', 'entitlement', 'billing']);
723
787
  /** Kinds that are deterministic refusals of this request (never replayed as-is). */
@@ -13,6 +13,8 @@ import {
13
13
  } from '../../../shared/provider-accounts.mjs';
14
14
  import { fetchOAuthUsageSnapshot } from './oauth-usage.mjs';
15
15
  import { getProvider } from './registry.mjs';
16
+ import { modelProxyClientMode } from '../../../shared/model-proxy-mode.mjs';
17
+ import { getModelProxyChannel } from './model-proxy-channel.mjs';
16
18
 
17
19
  const forcedReading = (routeInfo, providerObj) =>
18
20
  fetchOAuthUsageSnapshot(routeInfo, providerObj, () => {}, { force: true }).catch(() => null);
@@ -40,15 +42,15 @@ function readingServesModel(reading, model, useCredits) {
40
42
  return measured.length > 0 && measured.every((window) => window.usedPct < 100);
41
43
  }
42
44
 
43
- export async function providerQuotaUsable(providerName, model = '', { provider = getProvider(providerName) } = {}) {
45
+ /** The model-independent, account-wide measurement: one forced usage reading
46
+ * per roster account (or the single credential). Null for a provider that
47
+ * reports no exhausted quota. */
48
+ export async function measureProviderQuota(providerName, { provider } = {}) {
44
49
  // Only an account-pooled provider reports exhausted quota at all.
45
- if (!ACCOUNT_PROVIDERS.includes(providerName)) return true;
50
+ if (!ACCOUNT_PROVIDERS.includes(providerName)) return null;
51
+ if (provider === undefined) provider = getProvider(providerName);
46
52
  const pool = readProviderAccountPool(providerName);
47
53
  const useCredits = pool.useCredits === true;
48
- // Only this reading counts as evidence: an account whose forced reading
49
- // failed or measured nothing for this model stays exhausted however its
50
- // older record reads; the pool's own choice (selection, blocks) decides
51
- // among the rest.
52
54
  if (pool.accounts.length > 0) {
53
55
  const readings = await Promise.all(
54
56
  pool.accounts.map((row) =>
@@ -58,13 +60,37 @@ export async function providerQuotaUsable(providerName, model = '', { provider =
58
60
  )
59
61
  )
60
62
  );
61
- const unproven = new Set(
62
- pool.accounts.filter((_, index) => !readingServesModel(readings[index], model, useCredits)).map((row) => row.id)
63
- );
64
- if (unproven.size === pool.accounts.length) return false;
65
- return chooseProviderAccount(readProviderAccountPool(providerName), unproven, Date.now(), model) !== null;
63
+ return {
64
+ providerName,
65
+ useCredits,
66
+ accounts: pool.accounts.map((row, index) => ({ id: row.id, reading: readings[index] })),
67
+ };
66
68
  }
67
69
  // No roster: the single credential's fresh meter decides.
68
70
  const reading = await forcedReading({ provider: providerName, model: '' }, provider);
69
- return readingServesModel(reading, model, useCredits);
71
+ return { providerName, useCredits, accounts: null, reading };
72
+ }
73
+
74
+ /** Whether `model` can be served per `measurement` (from measureProviderQuota).
75
+ * Only the measurement counts as evidence: an account whose forced reading
76
+ * failed or measured nothing for this model stays exhausted however its
77
+ * older record reads; the pool's own choice (selection, blocks) decides
78
+ * among the rest. */
79
+ export function quotaMeasurementServesModel(measurement, model = '') {
80
+ if (!measurement) return true;
81
+ const { providerName, useCredits, accounts } = measurement;
82
+ if (!accounts) return readingServesModel(measurement.reading, model, useCredits);
83
+ const unproven = new Set(
84
+ accounts.filter((row) => !readingServesModel(row.reading, model, useCredits)).map((row) => row.id)
85
+ );
86
+ if (unproven.size === accounts.length) return false;
87
+ return chooseProviderAccount(readProviderAccountPool(providerName), unproven, Date.now(), model) !== null;
88
+ }
89
+
90
+ export async function providerQuotaUsable(providerName, model = '', { provider } = {}) {
91
+ // The PC owns the accounts in proxy mode; do not resolve a server provider.
92
+ if (modelProxyClientMode()) {
93
+ return (await getModelProxyChannel().request({ provider: providerName, method: 'quotaUsable', model })) === true;
94
+ }
95
+ return quotaMeasurementServesModel(await measureProviderQuota(providerName, { provider }), model);
70
96
  }
@@ -1,5 +1,6 @@
1
1
  import { OPENAI_COMPAT_PRESETS } from './openai-compat-presets.mjs';
2
2
  import { oauthCredentialProbeState } from './oauth-credential-probes.mjs';
3
+ import { providerAvailable } from './provider-availability.mjs';
3
4
  import { refreshCatalog as refreshMetadataCatalog } from './model-catalog.mjs';
4
5
  import { wrapProviderAdmission } from './admission-scheduler.mjs';
5
6
  import { createAccountPoolProvider } from './account-pool.mjs';
@@ -33,6 +34,7 @@ export const OAUTH_PROVIDER_NAMES = new Set([
33
34
  'command-code-oauth',
34
35
  'mimo-oauth',
35
36
  'cursor-oauth',
37
+ 'devin-oauth',
36
38
  'antigravity-oauth',
37
39
  'opencode-go-oauth',
38
40
  ]);
@@ -68,6 +70,17 @@ let _initChain = Promise.resolve();
68
70
  let _inFlightPromise = null;
69
71
  let _inFlightSig = null;
70
72
  let _lastAppliedSig = null;
73
+ // Settles when an initialization by the owning runtime first applies.
74
+ let _markProvidersInitialized;
75
+ const _providersInitialized = new Promise((resolve) => {
76
+ _markProvidersInitialized = resolve;
77
+ });
78
+
79
+ /** Read-only readiness: resolves once the owning runtime's provider
80
+ * initialization has applied a config (never starts one). */
81
+ export function providersInitialized() {
82
+ return _providersInitialized;
83
+ }
71
84
  // Provider instances are process-global inside the daemon. Catalog
72
85
  // readers use this revision to share one raw model snapshot while still
73
86
  // rebuilding their cheap route/config projection after auth/config changes.
@@ -176,6 +189,7 @@ const PROVIDER_MODULES = {
176
189
  'command-code-oauth': ['./command-code-oauth.mjs', 'CommandCodeOAuthProvider'],
177
190
  'mimo-oauth': ['./mimo-oauth.mjs', 'MimoOAuthProvider'],
178
191
  'cursor-oauth': ['./cursor.mjs', 'CursorOAuthProvider'],
192
+ 'devin-oauth': ['./devin.mjs', 'DevinOAuthProvider'],
179
193
  'antigravity-oauth': ['./antigravity-oauth.mjs', 'AntigravityOAuthProvider'],
180
194
  'cursor-api': ['./cursor.mjs', 'CursorApiProvider'],
181
195
  openai: ['./openai-ws.mjs', 'OpenAIDirectProvider'],
@@ -220,7 +234,14 @@ async function instantiateProvider(name, Ctor, cfg, proxyChannel = null) {
220
234
  return createAccountPoolProvider(name, () => wrapProviderAdmission(new Ctor(cfg), name));
221
235
  }
222
236
 
237
+ let _initProvidersCalls = 0;
238
+ /** Test seam: how many times initProviders was called in this process. */
239
+ export function _initProvidersCallCountForTest() {
240
+ return _initProvidersCalls;
241
+ }
242
+
223
243
  export async function initProviders(config, { signal = null } = {}) {
244
+ _initProvidersCalls += 1;
224
245
  throwIfAborted(signal);
225
246
  // Remote mode: provider availability and config are the PC's, never this
226
247
  // server's credential probes. No connected client fails here, clearly.
@@ -260,6 +281,7 @@ export async function initProviders(config, { signal = null } = {}) {
260
281
  if (_lastAppliedSig !== sig) _providerCatalogRevision += 1;
261
282
  _lastAppliedSig = sig;
262
283
  settle();
284
+ _markProvidersInitialized();
263
285
  return v;
264
286
  },
265
287
  (err) => {
@@ -290,6 +312,9 @@ async function _initProvidersUnsynchronized(config, signal = null, proxyChannel
290
312
  const enabledResults = await Promise.all(
291
313
  entries.map(async ([name, cfg]) => {
292
314
  if (!cfg.enabled) return null;
315
+ // A dev-gated provider whose Developer option is off is never admitted,
316
+ // even from a config that still says enabled:true.
317
+ if (!providerAvailable(name)) return null;
293
318
  // A retired provider's saved config is inert: its replacement is its own entry.
294
319
  if (Object.hasOwn(RETIRED_PROVIDER_ALIASES, name)) return null;
295
320
  // Idempotent reuse: an enabled provider whose config signature is
@@ -446,10 +471,20 @@ function _scheduleOAuthSelfHeal(name) {
446
471
  // by its replacement account. When that account is not connected the lookup
447
472
  // misses like any other unconnected provider.
448
473
  const RETIRED_PROVIDER_ALIASES = Object.freeze({ 'opencode-go': 'opencode-go-oauth' });
474
+
475
+ /** The instance registered under `name` right now, or null — a read-only
476
+ * lookup (no lazy registration, unlike getProvider). */
477
+ export function registeredProvider(name) {
478
+ return providers.get(name) || null;
479
+ }
480
+
449
481
  export function getProvider(requestedName) {
450
482
  const name = Object.hasOwn(RETIRED_PROVIDER_ALIASES, requestedName)
451
483
  ? RETIRED_PROVIDER_ALIASES[requestedName]
452
484
  : requestedName;
485
+ // Availability first: switching a dev-gated provider's option off takes
486
+ // effect on the next lookup, even for an already-initialized instance.
487
+ if (!providerAvailable(name)) return undefined;
453
488
  const cached = providers.get(name);
454
489
  if (cached) return cached;
455
490
  // OAuth lazy fallback. Covers the boot-time race where the credential probe
@@ -539,7 +574,12 @@ export function providerConsumesReadWindows(name) {
539
574
  export function getAllProviders() {
540
575
  // Defensive copy — callers must not mutate the live registry or retain
541
576
  // stale entries across re-init (initProviders rebuilds the map in place).
542
- return new Map(providers);
577
+ return new Map(availableProviderEntries());
578
+ }
579
+
580
+ // Live instances minus dev-gated providers whose Developer option is off.
581
+ function availableProviderEntries() {
582
+ return [...providers].filter(([name]) => providerAvailable(name));
543
583
  }
544
584
 
545
585
  export function disableProvider(name) {
@@ -629,7 +669,7 @@ export function refreshProviderCatalogsOnStartup() {
629
669
  if (_startupCatalogRefreshPromise) return _startupCatalogRefreshPromise;
630
670
  armNextCatalogRefresh();
631
671
  const pending = [];
632
- for (const [name, provider] of providers) {
672
+ for (const [name, provider] of availableProviderEntries()) {
633
673
  const refreshFn = providerCatalogRefreshFn(provider);
634
674
  if (!refreshFn) continue;
635
675
  pending.push(boundedCatalogRefresh(name, provider, refreshFn, 'startup catalog refresh'));
@@ -669,7 +709,7 @@ export function refreshCatalogs(options = {}) {
669
709
  const msg = error instanceof Error ? error.message : String(error);
670
710
  process.stderr.write(`[model-catalog] metadata refresh failed: ${msg}\n`);
671
711
  });
672
- for (const [name, provider] of providers) {
712
+ for (const [name, provider] of availableProviderEntries()) {
673
713
  const refreshFn = providerCatalogRefreshFn(provider);
674
714
  if (!refreshFn) continue;
675
715
  pending.push(metadataReady.then(() => boundedCatalogRefresh(name, provider, refreshFn, 'catalog refresh')));
@@ -4,7 +4,7 @@ import { PROVIDER_RETRY_JITTER_RATIO, createTimeoutSignal } from '../stall-polic
4
4
  import { readStreamOutcome } from './lib/stream-outcome.mjs';
5
5
  import { recycleLlmDispatcher } from '../../../shared/llm/http-agent.mjs';
6
6
  import { noteErrorUsage } from './lib/note-error-usage.mjs';
7
- import { retryReasonText, retryStatusLine } from '../../../shared/err-text.mjs';
7
+ import { retryStatusLine, retryTimeoutText } from '../../../shared/err-text.mjs';
8
8
  import {
9
9
  TERMINAL_EDGE_STATUSES,
10
10
  boundedCauseChain,
@@ -13,7 +13,14 @@ import {
13
13
  isToolInputCut,
14
14
  retryAfterMsFromError,
15
15
  } from './retry-classification.mjs';
16
- import { DETERMINISTIC_KINDS, QUOTA_KINDS, errorHeaderValue, providerErrorKind } from './provider-error-kind.mjs';
16
+ import {
17
+ DETERMINISTIC_KINDS,
18
+ QUOTA_KINDS,
19
+ errorHeaderValue,
20
+ providerErrorKind,
21
+ retryReasonClass,
22
+ safeRetryErrorCode,
23
+ } from './provider-error-kind.mjs';
17
24
  import { adviceGatedRetry } from './retry-midstream.mjs';
18
25
  import {
19
26
  ModelFallbackTriggeredError,
@@ -35,7 +42,9 @@ export function createStreamSafetyStamps() {
35
42
  try {
36
43
  e.liveTextEmitted = true;
37
44
  e.unsafeToRetry = true;
38
- } catch {}
45
+ } catch {
46
+ // the error object may be frozen; the live-text stamp is advisory
47
+ }
39
48
  }
40
49
  return e;
41
50
  };
@@ -44,7 +53,9 @@ export function createStreamSafetyStamps() {
44
53
  try {
45
54
  e.emittedToolCall = true;
46
55
  e.unsafeToRetry = true;
47
- } catch {}
56
+ } catch {
57
+ // the error object may be frozen; the tool-call stamp is advisory
58
+ }
48
59
  }
49
60
  return e;
50
61
  };
@@ -313,6 +324,19 @@ function retryWaitMs(
313
324
  return retryAfterJitterRatio > 0 ? jitterDelayMs(wait, retryAfterJitterRatio, 'positive') : wait;
314
325
  }
315
326
 
327
+ /** Fixed status phrases for a caller-classified retry reason. */
328
+ const RETRY_REASON_TEXT = Object.freeze({
329
+ rate_limited: 'Rate limited by the provider',
330
+ overloaded: 'Provider overloaded',
331
+ server_error: 'Provider server error',
332
+ auth: 'Provider rejected the sign-in',
333
+ other: 'Connection interrupted',
334
+ });
335
+
336
+ // Timeout classes read our own typed timeout stamps (retryTimeoutText), so
337
+ // their phrases carry the wait window.
338
+ const TIMEOUT_REASON_CLASSES = new Set(['first_response_timeout', 'stalled']);
339
+
316
340
  /**
317
341
  * Display-only 'reconnecting' stage for one retry wait, so it reads as a
318
342
  * reconnect instead of a silent spinner. `attempt` is the attempt about to run
@@ -321,20 +345,28 @@ function retryWaitMs(
321
345
  */
322
346
  export function emitProviderRetryStage(
323
347
  onStageChange,
324
- { attempt, maxAttempts, lastErr, delayMs, classifier = null, extra = null }
348
+ { attempt, maxAttempts, lastErr, delayMs, classifier = null, extra = null, reasonClass = null, providerLabel = null }
325
349
  ) {
326
350
  if (typeof onStageChange !== 'function') return;
327
351
  try {
328
- const reason = retryReasonText(lastErr);
352
+ // The reason is a fixed phrase for a class (the caller's, else derived from
353
+ // the error's typed status/code), never the error's own text; an
354
+ // unrecognized class reads as `other`.
355
+ const cls = reasonClass == null ? retryReasonClass(lastErr) : reasonClass;
356
+ const fixedClass = Object.hasOwn(RETRY_REASON_TEXT, cls) || TIMEOUT_REASON_CLASSES.has(cls) ? cls : 'other';
357
+ const reason = TIMEOUT_REASON_CLASSES.has(fixedClass)
358
+ ? retryTimeoutText(lastErr, fixedClass, providerLabel)
359
+ : RETRY_REASON_TEXT[fixedClass];
329
360
  const waitMs = Math.max(0, Number(delayMs) || 0);
330
361
  onStageChange('reconnecting', {
331
362
  ...extra,
363
+ reasonClass: fixedClass,
332
364
  attempt,
333
365
  max: maxAttempts,
334
366
  waitMs,
335
367
  retryAt: Date.now() + waitMs,
336
368
  reason,
337
- classifier: classifier || lastErr?.retryClassifier || lastErr?.code || null,
369
+ classifier: classifier || lastErr?.retryClassifier || safeRetryErrorCode(lastErr),
338
370
  message: retryStatusLine({ reason, attempt, maxAttempts, delayMs: waitMs }),
339
371
  });
340
372
  } catch {
@@ -34,6 +34,12 @@ export function recordGatewayUsageEvent(summary) {
34
34
  return requireRouteMeta().recordGatewayUsageEvent(summary);
35
35
  }
36
36
 
37
+ /** Resolves once every recorded usage event has been written; nothing was
38
+ * recorded while the module is not loaded. */
39
+ export function settleGatewayUsageWrites() {
40
+ return routeMeta ? routeMeta.settleGatewayUsageWrites() : Promise.resolve();
41
+ }
42
+
37
43
  export function summarizeGatewayUsage(routeInfo, providerOut, compact = null, durationMs = null) {
38
44
  return requireRouteMeta().summarizeGatewayUsage(routeInfo, providerOut, compact, durationMs);
39
45
  }