mixdog 1.2.5 → 1.3.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 (493) hide show
  1. package/LICENSES/simple-icons-CC0-1.0.txt +30 -0
  2. package/NOTICE.md +19 -0
  3. package/package.json +4 -1
  4. package/scripts/check-model-recommendations.mjs +89 -0
  5. package/scripts/gate-local.mjs +7 -0
  6. package/scripts/lib/gate-scheduler.mjs +2 -2
  7. package/scripts/lib/isolated-test-env.mjs +16 -0
  8. package/scripts/lib/run-node-tests.mjs +5 -14
  9. package/scripts/provider-pingpong-live.mjs +9 -9
  10. package/src/agents/advisor/AGENT.md +4 -4
  11. package/src/agents/advisor/agent.json +1 -1
  12. package/src/agents/reviewer/AGENT.md +5 -4
  13. package/src/agents/reviewer/agent.json +1 -1
  14. package/src/defaults/shipped-history.json +17 -0
  15. package/src/defaults/skills/browser-use/SKILL.md +7 -1
  16. package/src/defaults/skills/computer-use/SKILL.md +3 -1
  17. package/src/defaults/skills/memory-management/SKILL.md +4 -1
  18. package/src/defaults/skills/setup/references/actions.md +11 -4
  19. package/src/defaults/skills/setup-guide/SKILL.md +175 -0
  20. package/src/defaults/skills/setup-guide/model-recommendations.json +333 -0
  21. package/src/defaults/skills/visualize/SKILL.md +3 -2
  22. package/src/lib/rules-builder.cjs +56 -7
  23. package/src/output-styles/common.md +22 -6
  24. package/src/output-styles/detailed.md +7 -5
  25. package/src/output-styles/minimal.md +7 -3
  26. package/src/output-styles/simple.md +2 -3
  27. package/src/rules/agent/AGENT.md +7 -1
  28. package/src/rules/agent-mode/AGENT_MODE.md +24 -0
  29. package/src/rules/agent-mode/MIXY.md +21 -0
  30. package/src/rules/agent-mode/ROUTINE.md +6 -0
  31. package/src/rules/lead/LEAD.md +9 -4
  32. package/src/rules/shared/10-tool-workflow.md +2 -1
  33. package/src/rules/shared/60-verification.md +4 -5
  34. package/src/rules/shared/70-delivery.md +3 -0
  35. package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +2 -1
  36. package/src/runtime/agent/orchestrator/agent-runtime/room-supervisor-completion.mjs +86 -0
  37. package/src/runtime/agent/orchestrator/config.mjs +6 -0
  38. package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +77 -14
  39. package/src/runtime/agent/orchestrator/context/role-instructions.mjs +182 -13
  40. package/src/runtime/agent/orchestrator/context/skill-catalog.mjs +5 -3
  41. package/src/runtime/agent/orchestrator/internal-agents.mjs +10 -0
  42. package/src/runtime/agent/orchestrator/mcp/agent-connectors.mjs +215 -0
  43. package/src/runtime/agent/orchestrator/mcp/child-tree.mjs +58 -64
  44. package/src/runtime/agent/orchestrator/mcp/client-transport.mjs +10 -1
  45. package/src/runtime/agent/orchestrator/mcp/client.mjs +122 -15
  46. package/src/runtime/agent/orchestrator/mcp/oauth-account.mjs +97 -0
  47. package/src/runtime/agent/orchestrator/mcp/oauth-callback.mjs +2 -3
  48. package/src/runtime/agent/orchestrator/mcp/oauth-client.mjs +49 -0
  49. package/src/runtime/agent/orchestrator/mcp/oauth-credentials.mjs +59 -9
  50. package/src/runtime/agent/orchestrator/mcp/oauth-login.mjs +32 -7
  51. package/src/runtime/agent/orchestrator/mcp/oauth-provider.mjs +45 -6
  52. package/src/runtime/agent/orchestrator/mcp/oauth.mjs +195 -6
  53. package/src/runtime/agent/orchestrator/mcp/server-connectors.mjs +17 -0
  54. package/src/runtime/agent/orchestrator/providers/account-pool.mjs +9 -2
  55. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
  56. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-credentials.mjs +41 -19
  57. package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +3 -2
  58. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events/content-block-start.mjs +4 -1
  59. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events.mjs +2 -0
  60. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn.mjs +3 -0
  61. package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +2 -1
  62. package/src/runtime/agent/orchestrator/providers/anthropic.mjs +3 -1
  63. package/src/runtime/agent/orchestrator/providers/antigravity-oauth-login.mjs +11 -5
  64. package/src/runtime/agent/orchestrator/providers/antigravity-oauth-tokens.mjs +4 -0
  65. package/src/runtime/agent/orchestrator/providers/catalog-deadline.mjs +163 -0
  66. package/src/runtime/agent/orchestrator/providers/catalog-failures.mjs +34 -0
  67. package/src/runtime/agent/orchestrator/providers/cursor-client-version.mjs +1 -1
  68. package/src/runtime/agent/orchestrator/providers/grok-oauth-login.mjs +38 -14
  69. package/src/runtime/agent/orchestrator/providers/lib/oauth-page.mjs +100 -26
  70. package/src/runtime/agent/orchestrator/providers/lib/send-callbacks.mjs +24 -0
  71. package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +13 -0
  72. package/src/runtime/agent/orchestrator/providers/oauth-usage.mjs +2 -1
  73. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-send.mjs +1 -0
  74. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/chunk-events.mjs +4 -0
  75. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-state.mjs +3 -1
  76. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream.mjs +2 -0
  77. package/src/runtime/agent/orchestrator/providers/openai-compat-models.mjs +49 -4
  78. package/src/runtime/agent/orchestrator/providers/openai-compat-presets.mjs +0 -7
  79. package/src/runtime/agent/orchestrator/providers/openai-compat-responses-events.mjs +7 -1
  80. package/src/runtime/agent/orchestrator/providers/openai-compat-responses.mjs +1 -0
  81. package/src/runtime/agent/orchestrator/providers/openai-compat-stream.mjs +2 -0
  82. package/src/runtime/agent/orchestrator/providers/openai-compat-xai-send.mjs +1 -0
  83. package/src/runtime/agent/orchestrator/providers/openai-error-contract.mjs +17 -12
  84. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events.mjs +5 -1
  85. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state.mjs +11 -2
  86. package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +1 -0
  87. package/src/runtime/agent/orchestrator/providers/openai-oauth-login.mjs +45 -16
  88. package/src/runtime/agent/orchestrator/providers/openai-oauth-tokens.mjs +10 -0
  89. package/src/runtime/agent/orchestrator/providers/openai-oauth-ws.mjs +1 -0
  90. package/src/runtime/agent/orchestrator/providers/openai-ws-connect.mjs +196 -0
  91. package/src/runtime/agent/orchestrator/providers/openai-ws-pool.mjs +74 -9
  92. package/src/runtime/agent/orchestrator/providers/openai-ws-stream/event-switch.mjs +14 -1
  93. package/src/runtime/agent/orchestrator/providers/openai-ws-stream.mjs +2 -0
  94. package/src/runtime/agent/orchestrator/providers/opencode-go-oauth-login.mjs +194 -0
  95. package/src/runtime/agent/orchestrator/providers/opencode-go-oauth-tokens.mjs +353 -0
  96. package/src/runtime/agent/orchestrator/providers/opencode-go-oauth.mjs +293 -0
  97. package/src/runtime/agent/orchestrator/providers/opencode-go-usage.mjs +33 -100
  98. package/src/runtime/agent/orchestrator/providers/opencode-go.mjs +23 -14
  99. package/src/runtime/agent/orchestrator/providers/registry.mjs +41 -27
  100. package/src/runtime/agent/orchestrator/runtime-core/ask-user-tool-defs.mjs +98 -4
  101. package/src/runtime/agent/orchestrator/runtime-core/context-status-shape.mjs +4 -0
  102. package/src/runtime/agent/orchestrator/runtime-core/extension-scopes.mjs +6 -4
  103. package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +15 -8
  104. package/src/runtime/agent/orchestrator/runtime-core/plugin-mcp.mjs +1 -0
  105. package/src/runtime/agent/orchestrator/runtime-core/tool-bridge.mjs +12 -6
  106. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +32 -5
  107. package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +10 -4
  108. package/src/runtime/agent/orchestrator/runtime-core/workflow/agents.mjs +4 -1
  109. package/src/runtime/agent/orchestrator/runtime-core/workflow/context.mjs +50 -20
  110. package/src/runtime/agent/orchestrator/runtime-core/workflow-ids.mjs +2 -0
  111. package/src/runtime/agent/orchestrator/session/agent-home.d.mts +4 -0
  112. package/src/runtime/agent/orchestrator/session/agent-home.mjs +33 -0
  113. package/src/runtime/agent/orchestrator/session/agent-mode.mjs +62 -0
  114. package/src/runtime/agent/orchestrator/session/agent-pool-progress.mjs +15 -3
  115. package/src/runtime/agent/orchestrator/session/agent-room-supervisor.d.mts +31 -0
  116. package/src/runtime/agent/orchestrator/session/agent-room-supervisor.mjs +241 -0
  117. package/src/runtime/agent/orchestrator/session/agent-room.d.mts +162 -0
  118. package/src/runtime/agent/orchestrator/session/agent-room.mjs +641 -0
  119. package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +7 -1
  120. package/src/runtime/agent/orchestrator/session/compact/execution-tail.mjs +74 -13
  121. package/src/runtime/agent/orchestrator/session/compact/forked-summary.mjs +102 -0
  122. package/src/runtime/agent/orchestrator/session/compact/runner.mjs +8 -2
  123. package/src/runtime/agent/orchestrator/session/compact/summary.mjs +16 -0
  124. package/src/runtime/agent/orchestrator/session/compact/user-message-kind.mjs +2 -0
  125. package/src/runtime/agent/orchestrator/session/compaction-archive-capture.mjs +6 -2
  126. package/src/runtime/agent/orchestrator/session/human-gate/gate.mjs +165 -0
  127. package/src/runtime/agent/orchestrator/session/human-gate/held-message.mjs +95 -0
  128. package/src/runtime/agent/orchestrator/session/human-gate/outbound-policy.mjs +221 -0
  129. package/src/runtime/agent/orchestrator/session/human-gate/requests.mjs +195 -0
  130. package/src/runtime/agent/orchestrator/session/human-gate/store.mjs +167 -0
  131. package/src/runtime/agent/orchestrator/session/lifecycle-scan.mjs +9 -0
  132. package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +3 -1
  133. package/src/runtime/agent/orchestrator/session/loop/fresh-context.mjs +39 -2
  134. package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +10 -0
  135. package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +16 -1
  136. package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +82 -33
  137. package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +11 -4
  138. package/src/runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs +5 -4
  139. package/src/runtime/agent/orchestrator/session/loop/tool-helpers.mjs +13 -3
  140. package/src/runtime/agent/orchestrator/session/loop/usage.mjs +7 -0
  141. package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +1 -0
  142. package/src/runtime/agent/orchestrator/session/manager/ask-turn-loop-options.mjs +6 -1
  143. package/src/runtime/agent/orchestrator/session/manager/ask-turn-prepare.mjs +6 -0
  144. package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +2 -0
  145. package/src/runtime/agent/orchestrator/session/manager/ask-turn-steering-drain.mjs +13 -5
  146. package/src/runtime/agent/orchestrator/session/manager/pending-lifecycle-epoch.mjs +0 -8
  147. package/src/runtime/agent/orchestrator/session/manager/pending-message-entry.mjs +10 -7
  148. package/src/runtime/agent/orchestrator/session/manager/pending-messages.mjs +62 -22
  149. package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +44 -16
  150. package/src/runtime/agent/orchestrator/session/manager/rules-cache.mjs +22 -5
  151. package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +23 -1
  152. package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +81 -34
  153. package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +39 -4
  154. package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +27 -5
  155. package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +55 -8
  156. package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +16 -0
  157. package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +3 -2
  158. package/src/runtime/agent/orchestrator/session/manager/usage-metrics.mjs +6 -0
  159. package/src/runtime/agent/orchestrator/session/manager/workflow-switch-notice.mjs +58 -0
  160. package/src/runtime/agent/orchestrator/session/manager.mjs +2 -2
  161. package/src/runtime/agent/orchestrator/session/mixy-name.mjs +24 -0
  162. package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +32 -5
  163. package/src/runtime/agent/orchestrator/session/request-fork.mjs +47 -0
  164. package/src/runtime/agent/orchestrator/session/routine-result.d.mts +70 -0
  165. package/src/runtime/agent/orchestrator/session/routine-result.mjs +277 -0
  166. package/src/runtime/agent/orchestrator/session/side-question-store.mjs +16 -1
  167. package/src/runtime/agent/orchestrator/session/side-question.mjs +5 -43
  168. package/src/runtime/agent/orchestrator/session/store/fs-probe.mjs +10 -0
  169. package/src/runtime/agent/orchestrator/session/store/lifecycle-barriers.mjs +73 -6
  170. package/src/runtime/agent/orchestrator/session/store/load-session.mjs +40 -0
  171. package/src/runtime/agent/orchestrator/session/store/save-fault.mjs +15 -0
  172. package/src/runtime/agent/orchestrator/session/store/session-paths.mjs +12 -0
  173. package/src/runtime/agent/orchestrator/session/store/sweep/sweep-row.mjs +8 -0
  174. package/src/runtime/agent/orchestrator/session/store-agent-worker-header.mjs +36 -0
  175. package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +258 -43
  176. package/src/runtime/agent/orchestrator/session/store-record-strict-scan.mjs +325 -0
  177. package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +84 -21
  178. package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +44 -12
  179. package/src/runtime/agent/orchestrator/session/store-summary-last-message.mjs +46 -0
  180. package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +46 -30
  181. package/src/runtime/agent/orchestrator/session/store-summary-visibility.mjs +0 -4
  182. package/src/runtime/agent/orchestrator/session/store-transcript-cache.mjs +144 -45
  183. package/src/runtime/agent/orchestrator/session/store-transcript-projection.mjs +32 -13
  184. package/src/runtime/agent/orchestrator/session/store-transcript-worker.mjs +364 -38
  185. package/src/runtime/agent/orchestrator/session/store.mjs +9 -2
  186. package/src/runtime/agent/orchestrator/session/task-wait-control.mjs +43 -12
  187. package/src/runtime/agent/orchestrator/session/tool-result-offload.mjs +23 -6
  188. package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +44 -1
  189. package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +12 -6
  190. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/backgrounded-result.mjs +13 -7
  191. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/bashism-rewrite.mjs +1 -1
  192. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/benign-exit.mjs +7 -1
  193. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/completed-result.mjs +40 -7
  194. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/deadline-plan.mjs +37 -34
  195. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/inline-hoist.mjs +1 -1
  196. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/spawn-env.mjs +0 -4
  197. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +6 -0
  198. package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +29 -27
  199. package/src/runtime/agent/orchestrator/tools/builtin/external-tool-adapters.mjs +1 -1
  200. package/src/runtime/agent/orchestrator/tools/builtin/find-files-tool.mjs +28 -11
  201. package/src/runtime/agent/orchestrator/tools/builtin/git-command-policy.mjs +12 -3
  202. package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +203 -101
  203. package/src/runtime/agent/orchestrator/tools/builtin/git-repo-rw-lock.mjs +90 -41
  204. package/src/runtime/agent/orchestrator/tools/builtin/lib/list-helpers.mjs +17 -1
  205. package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-delivery.mjs +199 -0
  206. package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-job-records.mjs +12 -0
  207. package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-task-output.mjs +165 -39
  208. package/src/runtime/agent/orchestrator/tools/builtin/list-tool.mjs +25 -13
  209. package/src/runtime/agent/orchestrator/tools/builtin/native-search-client.mjs +113 -5
  210. package/src/runtime/agent/orchestrator/tools/builtin/read-batch.mjs +7 -6
  211. package/src/runtime/agent/orchestrator/tools/builtin/read-formatting.mjs +19 -4
  212. package/src/runtime/agent/orchestrator/tools/builtin/read-line-collector.mjs +5 -3
  213. package/src/runtime/agent/orchestrator/tools/builtin/read-single-render.mjs +25 -7
  214. package/src/runtime/agent/orchestrator/tools/builtin/read-special-files.mjs +2 -1
  215. package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-render.mjs +3 -1
  216. package/src/runtime/agent/orchestrator/tools/builtin/search-glob-tool.mjs +12 -5
  217. package/src/runtime/agent/orchestrator/tools/builtin/search-grep-tool.mjs +61 -22
  218. package/src/runtime/agent/orchestrator/tools/builtin/search-path-diagnostics.mjs +32 -8
  219. package/src/runtime/agent/orchestrator/tools/builtin/shell-analysis.mjs +193 -19
  220. package/src/runtime/agent/orchestrator/tools/builtin/shell-direct-exe.mjs +57 -7
  221. package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +123 -32
  222. package/src/runtime/agent/orchestrator/tools/builtin/shell-lossless-compact.mjs +26 -1
  223. package/src/runtime/agent/orchestrator/tools/builtin/shell-output.mjs +13 -28
  224. package/src/runtime/agent/orchestrator/tools/builtin/task-tool.mjs +90 -11
  225. package/src/runtime/agent/orchestrator/tools/builtin/wait-budgets.mjs +23 -0
  226. package/src/runtime/agent/orchestrator/tools/builtin.mjs +54 -10
  227. package/src/runtime/agent/orchestrator/tools/code-graph/build.mjs +22 -28
  228. package/src/runtime/agent/orchestrator/tools/code-graph/dispatch.mjs +11 -7
  229. package/src/runtime/agent/orchestrator/tools/destructive-warning.mjs +126 -9
  230. package/src/runtime/agent/orchestrator/tools/graph-manifest.json +13 -13
  231. package/src/runtime/agent/orchestrator/tools/lib/owned-shell-trees.mjs +15 -6
  232. package/src/runtime/agent/orchestrator/tools/lib/shell-descendants.mjs +64 -2
  233. package/src/runtime/agent/orchestrator/tools/lib/shell-run-background/promote-job.mjs +10 -2
  234. package/src/runtime/agent/orchestrator/tools/lib/shell-run-background/promotion-results.mjs +13 -3
  235. package/src/runtime/agent/orchestrator/tools/lib/shell-run-settle.mjs +8 -0
  236. package/src/runtime/agent/orchestrator/tools/lib/shell-run-state.mjs +6 -1
  237. package/src/runtime/agent/orchestrator/tools/patch/v4a-convert.mjs +1 -1
  238. package/src/runtime/agent/orchestrator/tools/shell-command.mjs +104 -55
  239. package/src/runtime/agent/orchestrator/tools/shell-policy.mjs +7 -2
  240. package/src/runtime/agent/orchestrator/tools/shell-powershell.mjs +39 -23
  241. package/src/runtime/agent/orchestrator/tools/shell-snapshot.mjs +6 -2
  242. package/src/runtime/agent/orchestrator/tools/spawn-manifest.json +13 -13
  243. package/src/runtime/attachments/office-extract.mjs +11 -9
  244. package/src/runtime/browser-bridge/client.mjs +24 -0
  245. package/src/runtime/channels/lib/scheduler.mjs +40 -12
  246. package/src/runtime/channels/lib/schedules-db.mjs +71 -12
  247. package/src/runtime/channels/lib/webhook/session-dispatch.mjs +36 -16
  248. package/src/runtime/channels/lib/webhook.mjs +0 -1
  249. package/src/runtime/channels/lib/webhooks-db.mjs +100 -10
  250. package/src/runtime/channels/lib/worker-main.mjs +17 -20
  251. package/src/runtime/computer-bridge/client.mjs +28 -1
  252. package/src/runtime/connectors/gmail-app-password.mjs +690 -0
  253. package/src/runtime/connectors/google-mcp.mjs +446 -0
  254. package/src/runtime/memory/lib/core-memory-access.mjs +69 -0
  255. package/src/runtime/memory/lib/core-memory-file.mjs +16 -8
  256. package/src/runtime/memory/lib/core-memory-index.mjs +15 -9
  257. package/src/runtime/memory/lib/core-memory-management.mjs +10 -4
  258. package/src/runtime/memory/lib/core-memory-store.mjs +53 -30
  259. package/src/runtime/memory/lib/core-memory-uniqueness.mjs +10 -6
  260. package/src/runtime/memory/lib/embedding-tokenizer.mjs +32 -18
  261. package/src/runtime/memory/lib/http-router/session-routes.mjs +3 -2
  262. package/src/runtime/memory/lib/memory-action-handlers/core-actions.mjs +44 -14
  263. package/src/runtime/memory/lib/memory-schema/core-and-meta.mjs +11 -0
  264. package/src/runtime/memory/lib/memory.mjs +7 -1
  265. package/src/runtime/memory/lib/query-core-recall.mjs +9 -1
  266. package/src/runtime/memory/lib/query-hybrid-search.mjs +2 -0
  267. package/src/runtime/memory/lib/runtime-fetcher.mjs +1 -1
  268. package/src/runtime/memory/lib/tool-call-handler.mjs +9 -5
  269. package/src/runtime/memory/tool-defs.mjs +5 -0
  270. package/src/runtime/office/authoring/pptx-script-normalize.mjs +11 -8
  271. package/src/runtime/office/core/tabular.mjs +1 -1
  272. package/src/runtime/office/design/library/design-template-inspect.mjs +7 -4
  273. package/src/runtime/office/portable/docx-formatting.mjs +1 -1
  274. package/src/runtime/office/portable/docx-runs.mjs +1 -1
  275. package/src/runtime/office/portable/docx-tracked-edits.mjs +2 -2
  276. package/src/runtime/office/portable/portable-docx-edits.mjs +11 -10
  277. package/src/runtime/office/portable/portable-docx-operations.mjs +21 -17
  278. package/src/runtime/office/portable/portable-docx-parts.mjs +15 -9
  279. package/src/runtime/office/portable/portable-docx-styles.mjs +4 -1
  280. package/src/runtime/office/portable/portable-docx-xml.mjs +9 -9
  281. package/src/runtime/office/portable/portable-opc.mjs +27 -13
  282. package/src/runtime/office/portable/portable-pivot.mjs +3 -3
  283. package/src/runtime/office/portable/portable-pptx-chart.mjs +3 -3
  284. package/src/runtime/office/portable/portable-pptx-charts.mjs +24 -18
  285. package/src/runtime/office/portable/portable-pptx-core.mjs +5 -5
  286. package/src/runtime/office/portable/portable-pptx-deck.mjs +8 -4
  287. package/src/runtime/office/portable/portable-pptx-package.mjs +7 -4
  288. package/src/runtime/office/portable/portable-pptx-shapes.mjs +18 -9
  289. package/src/runtime/office/portable/portable-sheet-parts.mjs +9 -3
  290. package/src/runtime/office/portable/portable-sheet-xml.mjs +5 -5
  291. package/src/runtime/office/portable/portable-xlsx-charts.mjs +4 -1
  292. package/src/runtime/office/portable/portable-xlsx-drawings.mjs +10 -6
  293. package/src/runtime/office/portable/portable-xlsx-operations.mjs +8 -5
  294. package/src/runtime/office/portable/portable-xlsx-pivot-ops.mjs +1 -1
  295. package/src/runtime/office/portable/portable-xlsx-reference-shift.mjs +11 -7
  296. package/src/runtime/office/portable/portable-xlsx-sheet-edits.mjs +6 -3
  297. package/src/runtime/office/portable/portable-xml.mjs +1 -1
  298. package/src/runtime/shared/agent-avatar-sprites.mjs +445 -0
  299. package/src/runtime/shared/agent-avatar.d.mts +64 -0
  300. package/src/runtime/shared/agent-avatar.mjs +320 -0
  301. package/src/runtime/shared/agent-route-config.d.mts +3 -0
  302. package/src/runtime/shared/agent-route-config.mjs +16 -0
  303. package/src/runtime/shared/atomic-file.mjs +36 -14
  304. package/src/runtime/shared/background-tasks.mjs +60 -20
  305. package/src/runtime/shared/child-spawn-gate.mjs +26 -16
  306. package/src/runtime/shared/config.mjs +8 -11
  307. package/src/runtime/shared/connector-accounts.mjs +15 -0
  308. package/src/runtime/shared/connector-catalog.d.mts +52 -0
  309. package/src/runtime/shared/connector-catalog.mjs +230 -0
  310. package/src/runtime/shared/connector-triggers.d.mts +3 -0
  311. package/src/runtime/shared/connector-triggers.mjs +43 -0
  312. package/src/runtime/shared/file-lock.mjs +7 -1
  313. package/src/runtime/shared/file-permissions-worker.mjs +38 -0
  314. package/src/runtime/shared/file-permissions.d.mts +19 -4
  315. package/src/runtime/shared/file-permissions.mjs +310 -4
  316. package/src/runtime/shared/git-runner-worker.mjs +6 -78
  317. package/src/runtime/shared/google-oauth-client.mjs +24 -0
  318. package/src/runtime/shared/held-request-host.d.mts +12 -0
  319. package/src/runtime/shared/held-request-host.mjs +71 -0
  320. package/src/runtime/shared/llm/http-agent.mjs +7 -3
  321. package/src/runtime/shared/llm/provider-catalog-registry.mjs +10 -0
  322. package/src/runtime/shared/llm/usage-accounting.mjs +2 -0
  323. package/src/runtime/shared/llm/usage-ledger-import.mjs +32 -3
  324. package/src/runtime/shared/llm/usage-ledger-rollup.mjs +12 -5
  325. package/src/runtime/shared/llm/usage-ledger-worker.mjs +1 -1
  326. package/src/runtime/shared/llm/usage-ledger.mjs +20 -5
  327. package/src/runtime/shared/memory-snapshot.mjs +5 -1
  328. package/src/runtime/shared/notify-trace.mjs +8 -1
  329. package/src/runtime/shared/plain-preview.d.mts +1 -0
  330. package/src/runtime/shared/plain-preview.mjs +28 -0
  331. package/src/runtime/shared/pristine-execution-contract.json +5 -1
  332. package/src/runtime/shared/process-runner-worker.mjs +7 -0
  333. package/src/runtime/shared/process-runner.mjs +38 -0
  334. package/src/runtime/shared/provider-accounts.mjs +2 -1
  335. package/src/runtime/shared/provider-api-key.mjs +0 -1
  336. package/src/runtime/shared/read-row-numbers.mjs +1 -1
  337. package/src/runtime/shared/resource-admission.mjs +60 -18
  338. package/src/runtime/shared/routine-limits.d.mts +11 -0
  339. package/src/runtime/shared/routine-limits.mjs +21 -0
  340. package/src/runtime/shared/routine-trigger.d.mts +10 -0
  341. package/src/runtime/shared/routine-trigger.mjs +44 -0
  342. package/src/runtime/shared/run-child.mjs +84 -0
  343. package/src/runtime/shared/schedule-model-ref.mjs +9 -10
  344. package/src/runtime/shared/session-activity-signal.mjs +23 -0
  345. package/src/runtime/shared/shell-output-summary.mjs +23 -0
  346. package/src/runtime/shared/singleton-owner.mjs +126 -42
  347. package/src/runtime/shared/slow-span.mjs +4 -12
  348. package/src/runtime/shared/statusline/statusline-segments.mjs +13 -1
  349. package/src/runtime/shared/tool-output-limit.mjs +4 -2
  350. package/src/runtime/shared/tool-output-marker.mjs +58 -0
  351. package/src/runtime/shared/transcript-metadata.mjs +10 -0
  352. package/src/runtime/shared/turn-changes.mjs +0 -8
  353. package/src/runtime/shared/usage-readout-totals.mjs +56 -0
  354. package/src/runtime/shared/user-data-guard.mjs +131 -34
  355. package/src/runtime/shared/worktrees/activity-gate.mjs +33 -8
  356. package/src/runtime/shared/worktrees/git-head.mjs +20 -2
  357. package/src/runtime/shared/worktrees/lock.mjs +3 -2
  358. package/src/runtime/terminal-bridge/tool-defs.mjs +1 -1
  359. package/src/runtime/tidy/runners/biome.mjs +3 -1
  360. package/src/runtime/tidy/shadow.mjs +2 -1
  361. package/src/runtime/web-search/index.mjs +5 -7
  362. package/src/runtime/web-search/lib/formatter.mjs +42 -6
  363. package/src/runtime/web-search/tool-defs.mjs +6 -1
  364. package/src/session-runtime/agent-home-delivery.mjs +459 -0
  365. package/src/session-runtime/agent-profile-changes.mjs +21 -0
  366. package/src/session-runtime/agent-room-delivery.mjs +92 -0
  367. package/src/session-runtime/agent-task-sessions.mjs +200 -0
  368. package/src/session-runtime/boot/apis.mjs +50 -18
  369. package/src/session-runtime/boot/facade.mjs +5 -8
  370. package/src/session-runtime/boot/infrastructure.mjs +28 -17
  371. package/src/session-runtime/boot/tools.mjs +3 -0
  372. package/src/session-runtime/channel-config-api.mjs +53 -5
  373. package/src/session-runtime/cwd-plugins/core-memory-context.mjs +36 -20
  374. package/src/session-runtime/cwd-plugins/plugin-status.mjs +6 -1
  375. package/src/session-runtime/held-requests.mjs +228 -0
  376. package/src/session-runtime/internal-tool-executor/ask-user-tool.mjs +121 -0
  377. package/src/session-runtime/internal-tool-executor/feature-tools.mjs +5 -1
  378. package/src/session-runtime/internal-tool-executor/knowledge-tools.mjs +31 -2
  379. package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +31 -2
  380. package/src/session-runtime/internal-tool-executor.mjs +2 -0
  381. package/src/session-runtime/lifecycle/session-catalog.mjs +9 -0
  382. package/src/session-runtime/lifecycle/session-switch/context-switch.mjs +4 -3
  383. package/src/session-runtime/lifecycle/session-switch/resume.mjs +11 -4
  384. package/src/session-runtime/lifecycle/session-switch/session-delete.mjs +3 -3
  385. package/src/session-runtime/lifecycle/shared.mjs +25 -2
  386. package/src/session-runtime/lifecycle/teardown/session-close.mjs +2 -0
  387. package/src/session-runtime/lifecycle/teardown.mjs +5 -2
  388. package/src/session-runtime/lifecycle-api.mjs +3 -1
  389. package/src/session-runtime/mcp-glue/server-catalog.mjs +8 -0
  390. package/src/session-runtime/mcp-glue/server-input.mjs +3 -0
  391. package/src/session-runtime/mcp-oauth-login.mjs +112 -15
  392. package/src/session-runtime/model-route/set-route.mjs +14 -3
  393. package/src/session-runtime/owned-automation-run.mjs +229 -0
  394. package/src/session-runtime/provider-auth/login.mjs +10 -6
  395. package/src/session-runtime/provider-auth/setup.mjs +19 -2
  396. package/src/session-runtime/provider-catalog-cache.mjs +101 -25
  397. package/src/session-runtime/provider-models/catalog-load.mjs +14 -3
  398. package/src/session-runtime/provider-models/row-hydration.mjs +4 -0
  399. package/src/session-runtime/provider-models.mjs +76 -10
  400. package/src/session-runtime/provider-readiness.mjs +4 -0
  401. package/src/session-runtime/resource-api.mjs +5 -0
  402. package/src/session-runtime/resource-mcp-api.mjs +107 -13
  403. package/src/session-runtime/resource-skills-api.mjs +12 -0
  404. package/src/session-runtime/room-member-gate.mjs +48 -0
  405. package/src/session-runtime/routine-home-turn.mjs +156 -0
  406. package/src/session-runtime/routine-owner.mjs +48 -0
  407. package/src/session-runtime/schedule-session-run.mjs +30 -64
  408. package/src/session-runtime/services/agent-tool/close-flow.mjs +2 -1
  409. package/src/session-runtime/services/agent-tool/helpers.mjs +10 -0
  410. package/src/session-runtime/services/agent-tool/job-views/agent-list.mjs +10 -2
  411. package/src/session-runtime/services/agent-tool/job-views/session-progress.mjs +13 -4
  412. package/src/session-runtime/services/agent-tool/notify.mjs +15 -4
  413. package/src/session-runtime/services/agent-tool/restart-notify.mjs +134 -0
  414. package/src/session-runtime/services/agent-tool/send-flow.mjs +24 -1
  415. package/src/session-runtime/services/agent-tool/spawn-flow/deferred-spawn.mjs +2 -1
  416. package/src/session-runtime/services/agent-tool/spawn-flow/job-start.mjs +4 -3
  417. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-plan.mjs +19 -4
  418. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-prep.mjs +2 -0
  419. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-run.mjs +5 -1
  420. package/src/session-runtime/services/agent-tool/tag-registry/tag-lookup.mjs +8 -3
  421. package/src/session-runtime/services/agent-tool/tag-registry.mjs +3 -0
  422. package/src/session-runtime/services/agent-tool/worker-index/row-shape.mjs +4 -0
  423. package/src/session-runtime/services/agent-tool/worker-index.mjs +44 -10
  424. package/src/session-runtime/services/agent-tool.mjs +20 -0
  425. package/src/session-runtime/services/channel-admin.mjs +93 -24
  426. package/src/session-runtime/services/memory-access.mjs +37 -0
  427. package/src/session-runtime/services/provider-admin.mjs +166 -59
  428. package/src/session-runtime/services/schedule-access.mjs +91 -0
  429. package/src/session-runtime/services/usage-dashboard-model.mjs +2 -2
  430. package/src/session-runtime/services/usage-dashboard.mjs +27 -69
  431. package/src/session-runtime/session-create/session-options.mjs +34 -7
  432. package/src/session-runtime/session-hooks.mjs +16 -8
  433. package/src/session-runtime/setup-tool/executor.mjs +68 -6
  434. package/src/session-runtime/setup-tool/extended-actions.mjs +72 -14
  435. package/src/session-runtime/setup-tool/settings-contract.mjs +8 -6
  436. package/src/session-runtime/setup-tool/tool-defs.mjs +8 -0
  437. package/src/session-runtime/skills-api.mjs +16 -1
  438. package/src/session-runtime/tool-policy-refresh.mjs +238 -29
  439. package/src/session-runtime/turn/session-ops.mjs +10 -3
  440. package/src/session-runtime/turn/turn-run/ask-callbacks.mjs +11 -2
  441. package/src/session-runtime/turn/turn-run/turn-prepare.mjs +3 -0
  442. package/src/session-runtime/usage-stats-api.mjs +6 -1
  443. package/src/session-runtime/webhook-session-run.mjs +49 -67
  444. package/src/session-runtime/workflow-agents-api/agent-connectors.mjs +239 -0
  445. package/src/session-runtime/workflow-agents-api/agent-editor.mjs +556 -22
  446. package/src/session-runtime/workflow-agents-api/workflow-packs.mjs +11 -1
  447. package/src/session-runtime/workflow-agents-api.mjs +4 -1
  448. package/src/standalone/channel-transport/http-routes.mjs +10 -9
  449. package/src/standalone/daemon-agent-control.mjs +1 -8
  450. package/src/standalone/daemon-desktop-runtime.mjs +20 -7
  451. package/src/standalone/daemon-owner.mjs +117 -25
  452. package/src/standalone/daemon-session-control.mjs +11 -2
  453. package/src/standalone/daemon.mjs +61 -17
  454. package/src/standalone/session-call-cache.mjs +6 -0
  455. package/src/standalone/session-protocol.mjs +28 -1
  456. package/src/standalone/session-service/retention/busy.mjs +7 -2
  457. package/src/standalone/session-service/session-calls/session-turns.mjs +9 -0
  458. package/src/standalone/session-service.mjs +19 -0
  459. package/src/standalone/session-transport/routes.mjs +7 -6
  460. package/src/tui/app/model-options.mjs +39 -2
  461. package/src/tui/app/model-picker.mjs +16 -2
  462. package/src/tui/app/provider-setup-picker.mjs +1 -2
  463. package/src/tui/app/slash-commands.mjs +20 -0
  464. package/src/tui/dist/index.mjs +487 -128
  465. package/src/tui/session/context-state.mjs +6 -1
  466. package/src/tui/session/notice-surface.mjs +35 -4
  467. package/src/tui/session/notice-text.mjs +0 -1
  468. package/src/tui/session/queue-helpers.mjs +2 -1
  469. package/src/tui/session/session-api/extensions.mjs +4 -0
  470. package/src/tui/session/session-api/intake/submission.mjs +12 -13
  471. package/src/tui/session/session-api/integrations.mjs +9 -5
  472. package/src/tui/session/session-api/lifecycle/session-reset.mjs +13 -3
  473. package/src/tui/session/session-api/lifecycle.mjs +17 -1
  474. package/src/tui/session/session-api/routes.mjs +48 -3
  475. package/src/tui/session/session-flow/drain.mjs +20 -3
  476. package/src/tui/session/session-flow/queue/entry-shape.mjs +2 -1
  477. package/src/tui/session/session-flow/queue/take-entries.mjs +3 -2
  478. package/src/tui/session/session-flow/steering.mjs +104 -24
  479. package/src/tui/session/session-flow.mjs +2 -0
  480. package/src/tui/session/tool-approval.mjs +26 -5
  481. package/src/tui/session/transcript-intake.mjs +6 -2
  482. package/src/tui/session/transcript-spill.mjs +5 -1
  483. package/src/tui/session/tui-steering-persist.mjs +65 -42
  484. package/src/tui/session/turn-live-call.mjs +56 -0
  485. package/src/tui/session/turn-stream.mjs +33 -0
  486. package/src/tui/session/turn.mjs +50 -7
  487. package/src/ui/statusline.mjs +1 -6
  488. package/src/ui/streaming-markdown-heal.mjs +24 -7
  489. package/src/vendor/statusline/bin/statusline-route.mjs +0 -1
  490. package/src/vendor/statusline/src/gateway/route-meta.mjs +0 -1
  491. package/src/workflows/default/WORKFLOW.md +9 -13
  492. package/src/session-runtime/automation-agents.mjs +0 -94
  493. package/src/session-runtime/automation-workflow.mjs +0 -59
@@ -0,0 +1,293 @@
1
+ /**
2
+ * OpenCode Go through an OpenCode Console OAuth login.
3
+ *
4
+ * The organization's remote config (`/api/v2/config` → providers.opencode-go)
5
+ * is the authority for the inference base URL, the request headers and the
6
+ * model catalog (the gateway's own `/models` is not served on this base).
7
+ * Requests run on the OpenCode Go gateway engines (opencode-go.mjs) with the
8
+ * access token as the bearer; a 401 refreshes the token once and retries.
9
+ */
10
+ import { scrubOAuthSecrets } from './lib/oauth-token-utils.mjs';
11
+ import { getModelMetadataSync } from './model-catalog.mjs';
12
+ import { makeModelCache } from './model-cache.mjs';
13
+ import { OpenCodeGoProvider, WIRE_API_BY_NPM, resolveOpenCodeGoWireRoute } from './opencode-go.mjs';
14
+ import { fetchOpenCodeGoOAuthUsageSnapshot } from './opencode-go-usage.mjs';
15
+ import {
16
+ CONFIG_PROVIDER_KEY,
17
+ CONFIG_URL,
18
+ FALLBACK_BASE_URL,
19
+ PROVIDER_ID,
20
+ consoleGetJson,
21
+ ensureFreshTokens,
22
+ loadTokens,
23
+ openCodeGoError,
24
+ openCodeGoReauthError,
25
+ } from './opencode-go-oauth-tokens.mjs';
26
+
27
+ export {
28
+ hasOpenCodeGoOAuthCredentials,
29
+ describeOpenCodeGoOAuthCredentials,
30
+ forgetOpenCodeGoOAuthCredentials,
31
+ } from './opencode-go-oauth-tokens.mjs';
32
+ export { beginOAuthLogin, loginOAuth } from './opencode-go-oauth-login.mjs';
33
+
34
+ const CONFIG_TTL_MS = 10 * 60_000;
35
+
36
+ // The catalog the remote config listed, with the base URL and headers it
37
+ // named, so the shared sync lookup and a send whose config read fails see it.
38
+ const goModelCache = makeModelCache({ fileName: 'opencode-go-oauth-models.json', ttlMs: 24 * 60 * 60_000, version: 1 });
39
+
40
+ const isPlainObject = (value) => Boolean(value) && typeof value === 'object' && !Array.isArray(value);
41
+ const positive = (value) => (Number.isFinite(Number(value)) && Number(value) > 0 ? Number(value) : null);
42
+ const finite = (value) => (value !== null && value !== '' && Number.isFinite(Number(value)) ? Number(value) : null);
43
+
44
+ function stringHeaders(value) {
45
+ if (!isPlainObject(value)) return {};
46
+ return Object.fromEntries(Object.entries(value).filter(([, v]) => typeof v === 'string'));
47
+ }
48
+
49
+ // The untiered price (or the first one) in USD per million tokens.
50
+ function costFields(cost) {
51
+ const list = Array.isArray(cost) ? cost : [cost];
52
+ const base = list.find((entry) => isPlainObject(entry) && !entry.tier) || list.find(isPlainObject);
53
+ if (!base) return {};
54
+ const fields = {
55
+ inputCostPerM: finite(base.input),
56
+ outputCostPerM: finite(base.output),
57
+ cacheReadCostPerM: finite(base.cache?.read),
58
+ cacheWriteCostPerM: finite(base.cache?.write),
59
+ };
60
+ return Object.fromEntries(Object.entries(fields).filter(([, v]) => v !== null));
61
+ }
62
+
63
+ function reasoningFields(reasoning) {
64
+ if (!isPlainObject(reasoning) || typeof reasoning.supported !== 'boolean') return {};
65
+ if (!reasoning.supported) return { supportsReasoning: false, reasoningOptions: [], reasoningLevels: [] };
66
+ const levels = Array.isArray(reasoning.effort) ? reasoning.effort.filter((v) => typeof v === 'string' && v) : [];
67
+ return {
68
+ supportsReasoning: true,
69
+ ...(levels.length ? { reasoningOptions: [{ type: 'effort', values: levels }], reasoningLevels: levels } : {}),
70
+ };
71
+ }
72
+
73
+ function catalogRow(id, model, providerPackage) {
74
+ const name = typeof model.name === 'string' && model.name.trim() ? model.name.trim() : id;
75
+ const wirePackage = typeof model.package === 'string' ? model.package : providerPackage;
76
+ const wire = Object.hasOwn(WIRE_API_BY_NPM, wirePackage || '') ? WIRE_API_BY_NPM[wirePackage] : null;
77
+ const baseURL = typeof model.settings?.baseURL === 'string' ? model.settings.baseURL : '';
78
+ const headers = stringHeaders(model.headers);
79
+ return {
80
+ id,
81
+ provider: PROVIDER_ID,
82
+ name,
83
+ ...(positive(model.limit?.context) ? { contextWindow: positive(model.limit.context) } : {}),
84
+ ...(positive(model.limit?.output) ? { outputTokens: positive(model.limit.output) } : {}),
85
+ ...reasoningFields(model.capabilities?.reasoning),
86
+ ...costFields(model.cost),
87
+ ...(wire ? { wire } : {}),
88
+ ...(baseURL ? { baseURL } : {}),
89
+ ...(Object.keys(headers).length ? { headers } : {}),
90
+ };
91
+ }
92
+
93
+ /**
94
+ * The Go provider of a remote config response: `{ baseURL, headers, models }`
95
+ * with one catalog row per enabled model.
96
+ */
97
+ export function goConfigFromResponse(json) {
98
+ const entry = json?.providers?.[CONFIG_PROVIDER_KEY];
99
+ if (!isPlainObject(entry)) {
100
+ throw openCodeGoError(`[${PROVIDER_ID}] the OpenCode organization config has no OpenCode Go provider`, {
101
+ kind: 'catalog',
102
+ });
103
+ }
104
+ const providerPackage = typeof entry.package === 'string' ? entry.package : '';
105
+ const models = Object.entries(isPlainObject(entry.models) ? entry.models : {})
106
+ .filter(([id, model]) => id && isPlainObject(model) && model.disabled !== true)
107
+ .map(([id, model]) => catalogRow(id, model, providerPackage));
108
+ return {
109
+ baseURL:
110
+ typeof entry.settings?.baseURL === 'string' && entry.settings.baseURL
111
+ ? entry.settings.baseURL
112
+ : FALLBACK_BASE_URL,
113
+ headers: stringHeaders(entry.headers),
114
+ models,
115
+ };
116
+ }
117
+
118
+ // The model list rows (the request routing fields stay in the cache).
119
+ function listRow({ wire: _wire, baseURL: _baseURL, headers: _headers, ...row }) {
120
+ return row;
121
+ }
122
+
123
+ const isUnauthorized = (err) => Number(err?.status || err?.httpStatus) === 401;
124
+ const emittedOutput = (err) =>
125
+ err?.liveTextEmitted === true || err?.emittedToolCall === true || err?.unsafeToRetry === true;
126
+
127
+ // The gateway engines on a fixed credential: the compat 401 handler re-reads
128
+ // the OpenCode Go API key from config, which must never reach this endpoint.
129
+ const pinCredential = (engine) => {
130
+ engine.reloadApiKey = () => {};
131
+ return engine;
132
+ };
133
+
134
+ class OpenCodeGoOAuthEngine extends OpenCodeGoProvider {
135
+ constructor(config) {
136
+ super(config);
137
+ pinCredential(this.openai);
138
+ pinCredential(this.anthropic);
139
+ }
140
+
141
+ async _geminiEngine() {
142
+ return pinCredential(await super._geminiEngine());
143
+ }
144
+ }
145
+
146
+ export class OpenCodeGoOAuthProvider {
147
+ // No document block on this wire: a PDF is lowered to text before the request is built.
148
+ nativePdf = false;
149
+ static inputExcludesCache = false;
150
+ name = PROVIDER_ID;
151
+ config;
152
+ tokens = null;
153
+ _remote = null;
154
+ _engines = new Map();
155
+
156
+ constructor(config) {
157
+ this.config = config || {};
158
+ this.tokens = loadTokens();
159
+ }
160
+
161
+ async ensureAuth({ forceRefresh = false } = {}) {
162
+ this.tokens = await ensureFreshTokens({ force: forceRefresh, fetchFn: this.config.fetchImpl });
163
+ return this.tokens;
164
+ }
165
+
166
+ // The remote config for this credential, re-read after CONFIG_TTL_MS; only
167
+ // a read with the still-signed-in account publishes the catalog.
168
+ async _remoteConfig(tokens, { force = false } = {}) {
169
+ const key = `${tokens.account_id}\0${tokens.org_id}`;
170
+ if (!force && this._remote?.key === key && Date.now() - this._remote.fetchedAt < CONFIG_TTL_MS) return this._remote;
171
+ const publish = goModelCache.beginSave(() => {
172
+ const current = loadTokens();
173
+ return current?.account_id === tokens.account_id && current?.org_id === tokens.org_id;
174
+ });
175
+ const remote = goConfigFromResponse(
176
+ await consoleGetJson(CONFIG_URL, tokens, { fetchFn: this.config.fetchImpl, refresh: true })
177
+ );
178
+ publish(remote.models, {
179
+ baseURL: remote.baseURL,
180
+ headers: remote.headers,
181
+ accountId: tokens.account_id,
182
+ orgId: tokens.org_id,
183
+ });
184
+ this._remote = { key, fetchedAt: Date.now(), ...remote, byId: new Map(remote.models.map((row) => [row.id, row])) };
185
+ return this._remote;
186
+ }
187
+
188
+ // A send keeps working on the last catalog of the same account and
189
+ // organization when the config cannot be read right now (its headers route
190
+ // to that organization); a rejected credential is never papered over.
191
+ async _sendConfig(tokens) {
192
+ try {
193
+ return await this._remoteConfig(tokens);
194
+ } catch (err) {
195
+ if (isUnauthorized(err) || err?.reauthRequired) throw err;
196
+ const entry = goModelCache.loadEntrySync({ allowStale: true });
197
+ if (!entry || entry.accountId !== tokens.account_id || entry.orgId !== tokens.org_id) throw err;
198
+ return {
199
+ baseURL: entry.baseURL || FALLBACK_BASE_URL,
200
+ headers: stringHeaders(entry.headers),
201
+ models: entry.models,
202
+ byId: new Map(entry.models.map((row) => [row.id, row])),
203
+ };
204
+ }
205
+ }
206
+
207
+ // The configured wire per model; the user's own modelWires win.
208
+ _modelWires(models) {
209
+ const wires = Object.fromEntries(models.filter((row) => row.wire).map((row) => [row.id, row.wire]));
210
+ return { ...wires, ...(this.config.modelWires || {}) };
211
+ }
212
+
213
+ _engine(tokens, remote, row) {
214
+ const baseURL = row?.baseURL || remote.baseURL;
215
+ const headers = { ...(this.config.extraHeaders || {}), ...remote.headers, ...(row?.headers || {}) };
216
+ const modelWires = this._modelWires(remote.models);
217
+ const signature = JSON.stringify([baseURL, headers, modelWires]);
218
+ const cached = this._engines.get(signature);
219
+ if (cached && cached.token === tokens.access_token) return cached.engine;
220
+ const { fetchImpl, apiKeyEnv: _env, ...config } = this.config;
221
+ const engine = new OpenCodeGoOAuthEngine({
222
+ ...config,
223
+ apiKey: tokens.access_token,
224
+ baseURL,
225
+ extraHeaders: headers,
226
+ modelWires,
227
+ // Explicit nulls keep OPENAI_ORG_ID / OPENAI_PROJECT_ID out of the requests.
228
+ clientOptions: { organization: null, project: null, ...(fetchImpl ? { fetch: fetchImpl } : {}) },
229
+ });
230
+ this._engines.set(signature, { token: tokens.access_token, engine });
231
+ return engine;
232
+ }
233
+
234
+ _scrub(err) {
235
+ if (err && typeof err.message === 'string' && this.tokens) {
236
+ err.message = scrubOAuthSecrets(err.message, [this.tokens.access_token, this.tokens.refresh_token]);
237
+ }
238
+ return err;
239
+ }
240
+
241
+ async send(messages, model, tools, sendOpts) {
242
+ const attempt = async (forceRefresh) => {
243
+ const tokens = await this.ensureAuth({ forceRefresh });
244
+ const remote = await this._sendConfig(tokens);
245
+ return this._engine(tokens, remote, remote.byId.get(model)).send(messages, model, tools, sendOpts);
246
+ };
247
+ try {
248
+ return await attempt(false);
249
+ } catch (err) {
250
+ if (!isUnauthorized(err) || err?.reauthRequired || emittedOutput(err)) throw this._scrub(err);
251
+ }
252
+ // The stored expiry cannot see a revoked session: refresh once and ask again.
253
+ try {
254
+ return await attempt(true);
255
+ } catch (err) {
256
+ if (isUnauthorized(err) && !err?.reauthRequired) throw openCodeGoReauthError('inference 401');
257
+ throw this._scrub(err);
258
+ }
259
+ }
260
+
261
+ resolveWireRoute(model, ctx = {}) {
262
+ const models = this._remote?.models || goModelCache.loadSync({ allowStale: true }) || [];
263
+ return resolveOpenCodeGoWireRoute(model, { ...ctx, override: this._modelWires(models)[model] ?? null });
264
+ }
265
+
266
+ async listModels() {
267
+ try {
268
+ const tokens = await this.ensureAuth();
269
+ const remote = await this._remoteConfig(tokens, { force: true });
270
+ return remote.models.map((row) => ({ ...this.getCachedModelInfo(row.id), ...listRow(row) }));
271
+ } catch (err) {
272
+ throw this._scrub(err);
273
+ }
274
+ }
275
+
276
+ getCachedModelInfo(model) {
277
+ const rows = this._remote?.models || goModelCache.loadSync({ allowStale: true }) || [];
278
+ const row = rows.find((candidate) => candidate?.id === model);
279
+ const meta = getModelMetadataSync(model, PROVIDER_ID);
280
+ if (!row && !meta) return null;
281
+ return { ...(meta || {}), ...(row ? listRow(row) : {}), id: model, provider: PROVIDER_ID };
282
+ }
283
+
284
+ /** Go 5-hour / weekly / monthly meters of this account's organization. */
285
+ async getUsageSnapshot() {
286
+ const tokens = await this.ensureAuth();
287
+ return await fetchOpenCodeGoOAuthUsageSnapshot(tokens, { fetchFn: this.config.fetchImpl });
288
+ }
289
+
290
+ async isAvailable() {
291
+ return loadTokens() !== null;
292
+ }
293
+ }
@@ -1,28 +1,15 @@
1
- import { join } from 'node:path';
2
- import { updateJsonAtomicSync } from '../../../shared/atomic-file.mjs';
3
- import { resolvePluginData } from '../../../shared/plugin-paths.mjs';
4
- import { getAgentApiKey, getOpenCodeGoConsoleKey } from '../../../shared/config.mjs';
5
1
  import { round, cleanString as clean } from './lib/usage-primitives.mjs';
6
- import { JsonMemoryCache } from './lib/json-memory-cache.mjs';
7
- import { recordQuotaReadings } from './lib/quota-readings.mjs';
2
+ import { STATUS_URL, consoleHeaders, withConsoleTokenRetry } from './opencode-go-oauth-tokens.mjs';
8
3
 
9
- const CACHE_FILE = 'opencode-go-usage-cache.json';
10
- const LIVE_TTL_MS = 5 * 60_000;
11
- const STALE_TTL_MS = 60 * 60_000;
12
4
  const FETCH_TIMEOUT_MS = 6500;
13
- // The console replaced its server-rendered page (usage inlined in the HTML) with
14
- // a SPA over this REST API, so scraping `/workspace/{id}/go` now yields an empty
15
- // shell. `GET /api/go/status` answers a service-account key that carries the
16
- // `all` permission and rejects `inference-only` keys with 403. The key itself
17
- // resolves the workspace, so no workspace id or `x-org-id` header is needed.
18
- const BASE_URL = 'https://opencode.ai/console';
5
+ // `GET /api/go/status` answers an OpenCode Console OAuth token; the token
6
+ // names its organization through `x-org-id`.
19
7
  const USER_AGENT =
20
8
  'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143 Safari/537.36';
21
9
  // Meters report micro-cents as strings: "1200000000" is the $12 five-hour cap.
22
10
  // Limits come from the response, so a plan change needs no code change.
23
11
  const MICRO_CENTS_PER_USD = 1e8;
24
12
  const METER_LABELS = Object.freeze({ fiveHour: '5H', week: '7D', month: 'M' });
25
- const diskJsonCache = new JsonMemoryCache();
26
13
 
27
14
  // Local unguarded `num`: this module intentionally coerces '' to 0 via
28
15
  // Number(''), unlike the guarded shared num() in lib/usage-primitives.mjs.
@@ -32,61 +19,18 @@ function num(value, fallback = null) {
32
19
  return Number.isFinite(n) ? n : fallback;
33
20
  }
34
21
 
35
- function cachePath() {
36
- return join(resolvePluginData(), CACHE_FILE);
37
- }
38
-
39
- // Synchronous atomic+lock write (updateJsonAtomicSync) instead of the prior
40
- // fire-and-forget fsp.writeFile: this cache is single-entry (one snapshot
41
- // per file, no cross-process merge), so the lock protects against a torn
42
- // write racing readers, not a lost-update merge. Only one write happens
43
- // per successful fetch (TTL-gated, at most once per LIVE_TTL_MS), so the
44
- // switch off async has no meaningful latency impact on the request path.
45
- function writeJson(file, value) {
46
- let next = null;
47
- try {
48
- next = updateJsonAtomicSync(file, () => value, { lock: true, fsyncDir: true, timeoutMs: 1000 }); // best-effort cache write: short lock timeout, don't block on contention
49
- } catch {}
50
- if (next) diskJsonCache.remember(file, next);
51
- }
52
-
53
- function freshSnapshot(snapshot, ttlMs) {
54
- const cachedAt = num(snapshot?.cachedAt, 0);
55
- if (!cachedAt || Date.now() - cachedAt > ttlMs) return null;
56
- return Array.isArray(snapshot?.quotaWindows) && snapshot.quotaWindows.length ? snapshot : null;
57
- }
58
-
59
- function isConsoleKey(value) {
60
- return /^(?:oc_sk_|sk-)/.test(String(value || ''));
61
- }
62
-
63
- // Usage auth is a console API key holding the `all` permission; the inference
64
- // key is the fallback when one key serves both roles. A stored value that is
65
- // not key-shaped predates the API migration, so it counts as "not configured"
66
- // and the UI asks for a key instead of surfacing an opaque 401.
67
- function consoleApiKey() {
68
- const stored = clean(getOpenCodeGoConsoleKey());
69
- if (isConsoleKey(stored)) return stored;
70
- const inferenceKey = clean(getAgentApiKey('opencode-go'));
71
- return isConsoleKey(inferenceKey) ? inferenceKey : null;
72
- }
73
-
22
+ // `status` lets the usage path refresh the token on a 401.
74
23
  function statusError(status) {
75
24
  if (status === 401) {
76
- const err = new Error('OpenCode console API key was rejected');
77
- err.code = 'OPENCODE_GO_USAGE_AUTH_FAILED';
78
- return err;
79
- }
80
- if (status === 403) {
81
- const err = new Error(
82
- 'OpenCode console API key lacks permission: subscription usage needs an "all" key, not an inference-only key'
83
- );
84
- err.code = 'OPENCODE_GO_USAGE_FORBIDDEN';
85
- return err;
25
+ return Object.assign(new Error('OpenCode console credential was rejected'), {
26
+ code: 'OPENCODE_GO_USAGE_AUTH_FAILED',
27
+ status,
28
+ });
86
29
  }
87
- const err = new Error(`OpenCode Go usage fetch failed (${status})`);
88
- err.code = 'OPENCODE_GO_USAGE_FETCH_FAILED';
89
- return err;
30
+ return Object.assign(new Error(`OpenCode Go usage fetch failed (${status})`), {
31
+ code: 'OPENCODE_GO_USAGE_FETCH_FAILED',
32
+ status,
33
+ });
90
34
  }
91
35
 
92
36
  function usdFromMicroCents(value) {
@@ -125,37 +69,15 @@ function snapshotFromStatus(status) {
125
69
  return { provider: 'opencode-go', source: 'opencode-go-console', quotaWindows };
126
70
  }
127
71
 
128
- export function readCachedOpenCodeGoUsageSnapshot({ allowStale = true } = {}) {
129
- const raw = diskJsonCache.read(cachePath());
130
- const snapshot = raw?.snapshot || raw;
131
- return freshSnapshot(snapshot, allowStale ? STALE_TTL_MS : LIVE_TTL_MS);
132
- }
133
-
134
- export function openCodeGoUsageConfigStatus() {
135
- return { ready: Boolean(consoleApiKey()) };
136
- }
137
-
138
- export async function fetchOpenCodeGoUsageSnapshot(_config = {}, { force = false } = {}) {
139
- if (!force) {
140
- const fresh = readCachedOpenCodeGoUsageSnapshot({ allowStale: false });
141
- if (fresh) return fresh;
142
- }
143
- const apiKey = consoleApiKey();
144
- if (!apiKey) {
145
- const err = new Error('OpenCode Go usage requires an OpenCode console API key');
146
- err.code = 'OPENCODE_GO_USAGE_AUTH_REQUIRED';
147
- throw err;
148
- }
72
+ // One `/api/go/status` read. `headers` carry the OAuth token plus `x-org-id`.
73
+ async function requestGoStatus(headers, fetchFn = fetch) {
149
74
  const controller = new AbortController();
150
75
  const timer = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);
151
76
  try {
152
- const res = await fetch(`${BASE_URL}/api/go/status`, {
77
+ const res = await fetchFn(STATUS_URL, {
153
78
  signal: controller.signal,
154
- headers: {
155
- Accept: 'application/json',
156
- Authorization: `Bearer ${apiKey}`,
157
- 'User-Agent': USER_AGENT,
158
- },
79
+ redirect: 'error',
80
+ headers: { Accept: 'application/json', 'User-Agent': USER_AGENT, ...headers },
159
81
  });
160
82
  if (!res.ok) throw statusError(res.status);
161
83
  const parsed = snapshotFromStatus(await res.json().catch(() => null));
@@ -164,12 +86,23 @@ export async function fetchOpenCodeGoUsageSnapshot(_config = {}, { force = false
164
86
  err.code = 'OPENCODE_GO_USAGE_PARSE_FAILED';
165
87
  throw err;
166
88
  }
167
- const snapshot = { ...parsed, cachedAt: Date.now() };
168
- writeJson(cachePath(), { version: 1, updatedAt: Date.now(), snapshot });
169
- // One console key serves the whole subscription: a single account.
170
- void recordQuotaReadings('opencode-go', 'default', snapshot);
171
- return snapshot;
89
+ return parsed;
172
90
  } finally {
173
91
  clearTimeout(timer);
174
92
  }
175
93
  }
94
+
95
+ /** Go meters for one OpenCode Go OAuth account (its token and organization). */
96
+ export async function fetchOpenCodeGoOAuthUsageSnapshot(tokens, { fetchFn } = {}) {
97
+ const parsed = await withConsoleTokenRetry(tokens, (current) => requestGoStatus(consoleHeaders(current), fetchFn), {
98
+ fetchFn,
99
+ });
100
+ return {
101
+ ...parsed,
102
+ provider: 'opencode-go-oauth',
103
+ model: null,
104
+ fetchedAt: Date.now(),
105
+ ...(tokens.email ? { email: tokens.email } : {}),
106
+ ...(tokens.account_id ? { accountId: tokens.account_id } : {}),
107
+ };
108
+ }
@@ -1,11 +1,21 @@
1
1
  import { randomUUID } from 'node:crypto';
2
2
  import { AnthropicProvider } from './anthropic.mjs';
3
- import { OpenAICompatProvider, OPENAI_COMPAT_PRESETS } from './openai-compat.mjs';
3
+ import { OpenAICompatProvider } from './openai-compat.mjs';
4
4
  import { getModelMetadataSync, getModelsDevRowSync } from './model-catalog.mjs';
5
- import { toInclusiveUsage, withInclusiveUsage } from './lib/inclusive-usage.mjs';
5
+ import { withInclusiveUsage } from './lib/inclusive-usage.mjs';
6
6
  import { providerOffersWire, resolveWireRoute, sendOnRoute } from './wire-route.mjs';
7
7
  import { gatewayMessagesOpts } from './wire-gateway.mjs';
8
8
 
9
+ // The OpenCode Go gateway engines. Not a registered provider: the
10
+ // `opencode-go-oauth` provider (opencode-go-oauth.mjs) runs its requests here
11
+ // on the account's OAuth access token. `opencode-go` stays the engines' internal
12
+ // wire/catalog id.
13
+ const GO_GATEWAY_PRESET = Object.freeze({
14
+ baseURL: 'https://opencode.ai/inference/go/v1',
15
+ // The gateway expects an application User-Agent (not the SDK default).
16
+ extraHeaders: Object.freeze({ 'User-Agent': 'mixdog' }),
17
+ });
18
+
9
19
  // The Go Anthropic route: the shared request builder gets the model's output
10
20
  // ceiling (models.dev limit) through the gateway options.
11
21
  class OpenCodeGoMessagesEngine extends AnthropicProvider {
@@ -21,7 +31,7 @@ class OpenCodeGoMessagesEngine extends AnthropicProvider {
21
31
  // is the authoritative wire selector; wire-route.mjs holds the cold-catalog
22
32
  // prefix fallback. `@ai-sdk/google` names the Gemini generateContent wire
23
33
  // (opencode-go-gemini.mjs).
24
- const WIRE_API_BY_NPM = Object.freeze({
34
+ export const WIRE_API_BY_NPM = Object.freeze({
25
35
  '@ai-sdk/openai': 'responses',
26
36
  '@ai-sdk/anthropic': 'messages',
27
37
  '@ai-sdk/openai-compatible': 'chat',
@@ -33,7 +43,7 @@ function openCodeGoCatalogWire(model) {
33
43
  return typeof npm === 'string' && Object.hasOwn(WIRE_API_BY_NPM, npm) ? WIRE_API_BY_NPM[npm] : null;
34
44
  }
35
45
 
36
- function resolveOpenCodeGoWireRoute(model, ctx = {}) {
46
+ export function resolveOpenCodeGoWireRoute(model, ctx = {}) {
37
47
  const catalogWire = openCodeGoCatalogWire(model);
38
48
  // Each Go model answers on the one wire the catalog names: it narrows the
39
49
  // offered endpoints, so an override cannot pick a wire the model lacks.
@@ -51,8 +61,7 @@ export function isAnthropicGoModel(model) {
51
61
  }
52
62
 
53
63
  export function resolveOpenCodeGoBaseURLs(configuredBaseURL) {
54
- const presetBase = OPENAI_COMPAT_PRESETS['opencode-go'].baseURL;
55
- const openai = String(configuredBaseURL || presetBase).replace(/\/+$/, '');
64
+ const openai = String(configuredBaseURL || GO_GATEWAY_PRESET.baseURL).replace(/\/+$/, '');
56
65
  // Anthropic's SDK appends `/v1/messages` itself. Supplying the OpenAI base
57
66
  // (`.../v1`) would therefore produce the invalid `.../v1/v1/messages`.
58
67
  const anthropic = openai.replace(/\/v1$/i, '');
@@ -67,9 +76,6 @@ export function openCodeGoEndpointForModel(model, configuredBaseURL) {
67
76
  return `${bases.openai}/chat/completions`;
68
77
  }
69
78
 
70
- // The Messages route reports usage in the provider's inclusive convention.
71
- export const toInclusiveOpenCodeGoUsage = toInclusiveUsage;
72
-
73
79
  function opencodeGoContextWindow(modelId, current = 0) {
74
80
  const native = Number(current);
75
81
  if (Number.isFinite(native) && native > 0) return native;
@@ -100,9 +106,12 @@ export class OpenCodeGoProvider {
100
106
  // lane. The delegated transports are intentionally not independently
101
107
  // wrapped, so all model-family routes share this one 64-wide account.
102
108
  this.config = config;
103
- const preset = OPENAI_COMPAT_PRESETS['opencode-go'];
104
- const bases = resolveOpenCodeGoBaseURLs(config.baseURL || preset.baseURL);
105
- this.openai = new OpenAICompatProvider('opencode-go', { ...config, baseURL: bases.openai });
109
+ const bases = resolveOpenCodeGoBaseURLs(config.baseURL);
110
+ this.openai = new OpenAICompatProvider('opencode-go', {
111
+ ...config,
112
+ baseURL: bases.openai,
113
+ extraHeaders: { ...GO_GATEWAY_PRESET.extraHeaders, ...(config.extraHeaders || {}) },
114
+ });
106
115
  this.anthropic = new OpenCodeGoMessagesEngine({
107
116
  ...config,
108
117
  name: 'opencode-go',
@@ -110,7 +119,7 @@ export class OpenCodeGoProvider {
110
119
  disableBetaHeaders: true,
111
120
  // The preset's identifying headers (User-Agent) ride the Messages wire
112
121
  // too; the user's own headers win.
113
- extraHeaders: { ...(preset.extraHeaders || {}), ...(config.extraHeaders || {}) },
122
+ extraHeaders: { ...GO_GATEWAY_PRESET.extraHeaders, ...(config.extraHeaders || {}) },
114
123
  modelMaxOutputTokens: (model) => this.getCachedModelInfo(model)?.outputTokens,
115
124
  });
116
125
  // The Anthropic route answers for this provider: PDFs lower to text.
@@ -163,7 +172,7 @@ export class OpenCodeGoProvider {
163
172
  ...this.config,
164
173
  baseURL: this.openai.baseURL,
165
174
  extraHeaders: {
166
- ...(OPENAI_COMPAT_PRESETS['opencode-go'].extraHeaders || {}),
175
+ ...GO_GATEWAY_PRESET.extraHeaders,
167
176
  ...(this.config.extraHeaders || {}),
168
177
  },
169
178
  });