mixdog 1.2.1 → 1.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -0
- package/package.json +2 -1
- package/scripts/gate-local.mjs +19 -3
- package/scripts/model-catalog-audit.mjs +1 -15
- package/scripts/provider-pingpong-live.mjs +509 -0
- package/src/agents/advisor/AGENT.md +1 -1
- package/src/agents/advisor/agent.json +1 -1
- package/src/agents/reviewer/AGENT.md +3 -3
- package/src/agents/reviewer/agent.json +1 -1
- package/src/defaults/shipped-history.json +6 -0
- package/src/defaults/skills/setup/SKILL.md +6 -1
- package/src/defaults/skills/setup/references/actions.md +44 -22
- package/src/defaults/skills/setup/references/surfaces.md +10 -8
- package/src/headless-exec.mjs +15 -8
- package/src/lib/keychain-cjs.cjs +7 -4
- package/src/output-styles/common.md +11 -10
- package/src/repl/slash-commands.mjs +16 -1
- package/src/rules/agent/AGENT.md +5 -5
- package/src/rules/lead/LEAD.md +5 -5
- package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +29 -4
- package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +10 -0
- package/src/runtime/agent/orchestrator/agent-trace-io.mjs +92 -61
- package/src/runtime/agent/orchestrator/cache-mtime.mjs +10 -1
- package/src/runtime/agent/orchestrator/config-providers-merge.mjs +7 -0
- package/src/runtime/agent/orchestrator/config.mjs +5 -0
- package/src/runtime/agent/orchestrator/context/collect.mjs +1 -0
- package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +26 -7
- package/src/runtime/agent/orchestrator/context/skill-catalog.mjs +112 -7
- package/src/runtime/agent/orchestrator/mcp/client-config.mjs +36 -7
- package/src/runtime/agent/orchestrator/mcp/client-handshake.mjs +49 -10
- package/src/runtime/agent/orchestrator/mcp/client-transport.mjs +40 -3
- package/src/runtime/agent/orchestrator/mcp/client.mjs +230 -96
- package/src/runtime/agent/orchestrator/mcp/oauth-callback.mjs +103 -0
- package/src/runtime/agent/orchestrator/mcp/oauth-credentials.mjs +150 -0
- package/src/runtime/agent/orchestrator/mcp/oauth-login.mjs +111 -0
- package/src/runtime/agent/orchestrator/mcp/oauth-probe.mjs +87 -0
- package/src/runtime/agent/orchestrator/mcp/oauth-provider.mjs +95 -0
- package/src/runtime/agent/orchestrator/mcp/oauth-request.mjs +122 -0
- package/src/runtime/agent/orchestrator/mcp/oauth-shared.mjs +9 -0
- package/src/runtime/agent/orchestrator/mcp/oauth.mjs +229 -0
- package/src/runtime/agent/orchestrator/providers/account-pool.mjs +188 -29
- package/src/runtime/agent/orchestrator/providers/anthropic-api-recovery.mjs +2 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-api-request.mjs +48 -20
- package/src/runtime/agent/orchestrator/providers/anthropic-api-transport.mjs +94 -31
- package/src/runtime/agent/orchestrator/providers/anthropic-error-contract.mjs +98 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-fast-mode.mjs +39 -18
- package/src/runtime/agent/orchestrator/providers/anthropic-max-tokens-recovery.mjs +55 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-max-tokens.mjs +48 -37
- package/src/runtime/agent/orchestrator/providers/anthropic-messages.mjs +10 -7
- package/src/runtime/agent/orchestrator/providers/anthropic-midstream-recovery.mjs +18 -4
- package/src/runtime/agent/orchestrator/providers/anthropic-model-resolve.mjs +13 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-midstream.mjs +10 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-recovery.mjs +23 -9
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-request/initial-status.mjs +46 -20
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-request.mjs +14 -9
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +102 -45
- package/src/runtime/agent/orchestrator/providers/anthropic-overload-fallback.mjs +69 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-server-fallback.mjs +4 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-blocks.mjs +20 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events/content-block-delta.mjs +15 -2
- package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events/content-block-start.mjs +11 -4
- package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events/message-events.mjs +3 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events.mjs +12 -5
- package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-outcome.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-state.mjs +14 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +10 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-turn-result.mjs +9 -0
- package/src/runtime/agent/orchestrator/providers/anthropic.mjs +40 -7
- package/src/runtime/agent/orchestrator/providers/antigravity-oauth-catalog.mjs +30 -9
- package/src/runtime/agent/orchestrator/providers/antigravity-oauth.mjs +7 -0
- package/src/runtime/agent/orchestrator/providers/antigravity-request.mjs +88 -21
- package/src/runtime/agent/orchestrator/providers/antigravity-response.mjs +30 -10
- package/src/runtime/agent/orchestrator/providers/antigravity-retry-policy.mjs +106 -0
- package/src/runtime/agent/orchestrator/providers/antigravity-stream.mjs +10 -61
- package/src/runtime/agent/orchestrator/providers/antigravity-transport.mjs +94 -15
- package/src/runtime/agent/orchestrator/providers/codex-client-meta.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/command-code-oauth.mjs +117 -72
- package/src/runtime/agent/orchestrator/providers/compat-request-policy.mjs +78 -2
- package/src/runtime/agent/orchestrator/providers/cursor-auth.mjs +75 -10
- package/src/runtime/agent/orchestrator/providers/cursor-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/cursor-wire-guards.mjs +97 -2
- package/src/runtime/agent/orchestrator/providers/cursor-wire-stream-bridge.mjs +103 -23
- package/src/runtime/agent/orchestrator/providers/cursor-wire-stream-messages.mjs +43 -2
- package/src/runtime/agent/orchestrator/providers/cursor-wire-transport.mjs +103 -33
- package/src/runtime/agent/orchestrator/providers/cursor-wire.mjs +32 -6
- package/src/runtime/agent/orchestrator/providers/cursor.mjs +27 -3
- package/src/runtime/agent/orchestrator/providers/custom-provider-config.mjs +64 -1
- package/src/runtime/agent/orchestrator/providers/custom-provider.mjs +70 -6
- package/src/runtime/agent/orchestrator/providers/custom-reasoning.mjs +34 -7
- package/src/runtime/agent/orchestrator/providers/custom-tool-wire.mjs +32 -6
- package/src/runtime/agent/orchestrator/providers/deepseek.mjs +67 -0
- package/src/runtime/agent/orchestrator/providers/effort-configuration.mjs +80 -18
- package/src/runtime/agent/orchestrator/providers/gemini-cache-policy.mjs +11 -4
- package/src/runtime/agent/orchestrator/providers/gemini-cache.mjs +46 -8
- package/src/runtime/agent/orchestrator/providers/gemini-error-contract.mjs +273 -0
- package/src/runtime/agent/orchestrator/providers/gemini-family.mjs +9 -0
- package/src/runtime/agent/orchestrator/providers/gemini-history-signatures.mjs +9 -4
- package/src/runtime/agent/orchestrator/providers/gemini-request-body.mjs +41 -5
- package/src/runtime/agent/orchestrator/providers/gemini-response.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/gemini-retry-policy.mjs +180 -0
- package/src/runtime/agent/orchestrator/providers/gemini-schema.mjs +369 -112
- package/src/runtime/agent/orchestrator/providers/gemini-sdk-request.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +140 -35
- package/src/runtime/agent/orchestrator/providers/gemini-thinking.mjs +70 -24
- package/src/runtime/agent/orchestrator/providers/gemini.mjs +80 -29
- package/src/runtime/agent/orchestrator/providers/grok-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/grok-oauth-tokens.mjs +3 -0
- package/src/runtime/agent/orchestrator/providers/grok-oauth.mjs +69 -19
- package/src/runtime/agent/orchestrator/providers/lib/action-input-contract.mjs +60 -0
- package/src/runtime/agent/orchestrator/providers/lib/anthropic-native-blocks.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +246 -42
- package/src/runtime/agent/orchestrator/providers/lib/anthropic-server-tool-usage.mjs +18 -0
- package/src/runtime/agent/orchestrator/providers/lib/anthropic-system-blocks.mjs +27 -6
- package/src/runtime/agent/orchestrator/providers/lib/claude-bridge-schema.mjs +388 -0
- package/src/runtime/agent/orchestrator/providers/lib/inclusive-usage.mjs +54 -0
- package/src/runtime/agent/orchestrator/providers/lib/origin-bound-fetch.mjs +16 -0
- package/src/runtime/agent/orchestrator/providers/lib/responses-terminal-fields.mjs +11 -0
- package/src/runtime/agent/orchestrator/providers/lib/usage-primitives.mjs +8 -0
- package/src/runtime/agent/orchestrator/providers/lib/wire-pairing.mjs +48 -22
- package/src/runtime/agent/orchestrator/providers/media-normalization.mjs +119 -18
- package/src/runtime/agent/orchestrator/providers/mimo-oauth-profile.mjs +13 -15
- package/src/runtime/agent/orchestrator/providers/mimo-oauth.mjs +3 -0
- package/src/runtime/agent/orchestrator/providers/model-list-sanitize.mjs +2 -1
- package/src/runtime/agent/orchestrator/providers/model-proxy-channel.d.mts +1 -1
- package/src/runtime/agent/orchestrator/providers/model-proxy-channel.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/model-proxy-provider.mjs +33 -1
- package/src/runtime/agent/orchestrator/providers/muse-code-oauth.mjs +4 -9
- package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/openai-codex-metadata.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-send.mjs +123 -61
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/chunk-events.mjs +35 -14
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-result.mjs +27 -2
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-state.mjs +37 -7
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/tool-call-acc.mjs +2 -9
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-error-contract.mjs +50 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-models.mjs +47 -2
- package/src/runtime/agent/orchestrator/providers/openai-compat-options.mjs +47 -25
- package/src/runtime/agent/orchestrator/providers/openai-compat-presets.mjs +5 -1
- package/src/runtime/agent/orchestrator/providers/openai-compat-reasoning-field.mjs +151 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-response-normalization.mjs +64 -23
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses-events.mjs +79 -33
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses-head-parity.json +2901 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses-parity.fixtures.mjs +172 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses-state.mjs +3 -2
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses.mjs +144 -15
- package/src/runtime/agent/orchestrator/providers/openai-compat-retry-profile.mjs +193 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-stream-common.mjs +66 -2
- package/src/runtime/agent/orchestrator/providers/openai-compat-stream.mjs +9 -2
- package/src/runtime/agent/orchestrator/providers/openai-compat-trace.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-wire.mjs +109 -26
- package/src/runtime/agent/orchestrator/providers/openai-compat-xai-send.mjs +27 -6
- package/src/runtime/agent/orchestrator/providers/openai-compat-xai.mjs +34 -20
- package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +23 -4
- package/src/runtime/agent/orchestrator/providers/openai-direct-request.mjs +37 -28
- package/src/runtime/agent/orchestrator/providers/openai-error-contract.mjs +274 -0
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-request.mjs +72 -32
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events/output-items.mjs +23 -10
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events/terminal-frames.mjs +43 -15
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events.mjs +10 -0
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-items.mjs +18 -7
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-outcome.mjs +5 -2
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-stamps.mjs +2 -2
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-state.mjs +7 -3
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/text-relay.mjs +9 -1
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state.mjs +2 -2
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-watchdogs.mjs +1 -3
- package/src/runtime/agent/orchestrator/providers/openai-model-capabilities.mjs +80 -0
- package/src/runtime/agent/orchestrator/providers/openai-oauth-dispatch.mjs +37 -4
- package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +12 -1
- package/src/runtime/agent/orchestrator/providers/openai-oauth-tokens.mjs +22 -2
- package/src/runtime/agent/orchestrator/providers/openai-oauth.mjs +12 -1
- package/src/runtime/agent/orchestrator/providers/openai-responses-input.mjs +76 -33
- package/src/runtime/agent/orchestrator/providers/openai-responses-payload-parity.fixture.json +323 -0
- package/src/runtime/agent/orchestrator/providers/openai-responses-payload.mjs +44 -16
- package/src/runtime/agent/orchestrator/providers/openai-retry-policy.mjs +9 -0
- package/src/runtime/agent/orchestrator/providers/openai-ws-delta.mjs +7 -16
- package/src/runtime/agent/orchestrator/providers/openai-ws-handshake.mjs +16 -8
- package/src/runtime/agent/orchestrator/providers/openai-ws-response-state/refusals.mjs +60 -0
- package/src/runtime/agent/orchestrator/providers/openai-ws-response-state/tool-calls.mjs +51 -35
- package/src/runtime/agent/orchestrator/providers/openai-ws-response-state.mjs +30 -0
- package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/attempt-context.mjs +1 -2
- package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/policy.mjs +25 -14
- package/src/runtime/agent/orchestrator/providers/openai-ws-stream/event-switch.mjs +12 -0
- package/src/runtime/agent/orchestrator/providers/openai-ws-stream/terminal-frames.mjs +25 -6
- package/src/runtime/agent/orchestrator/providers/openai-ws-terminal.mjs +18 -11
- package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +41 -22
- package/src/runtime/agent/orchestrator/providers/opencode-go-gemini.mjs +170 -0
- package/src/runtime/agent/orchestrator/providers/opencode-go.mjs +75 -70
- package/src/runtime/agent/orchestrator/providers/openrouter.mjs +75 -0
- package/src/runtime/agent/orchestrator/providers/provider-error-kind.mjs +720 -0
- package/src/runtime/agent/orchestrator/providers/registry.mjs +4 -1
- package/src/runtime/agent/orchestrator/providers/retry-backoff.mjs +46 -7
- package/src/runtime/agent/orchestrator/providers/retry-classification.mjs +123 -219
- package/src/runtime/agent/orchestrator/providers/retry-classifier.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/retry-executor.mjs +148 -45
- package/src/runtime/agent/orchestrator/providers/retry-midstream.mjs +81 -16
- package/src/runtime/agent/orchestrator/providers/transport-scope.d.mts +6 -0
- package/src/runtime/agent/orchestrator/providers/transport-scope.mjs +28 -0
- package/src/runtime/agent/orchestrator/providers/wire-gateway.mjs +157 -0
- package/src/runtime/agent/orchestrator/providers/wire-route.mjs +512 -0
- package/src/runtime/agent/orchestrator/providers/xai-tool-search-head-parity.json +1131 -0
- package/src/runtime/agent/orchestrator/providers/xai-tool-search.fixtures.mjs +183 -0
- package/src/runtime/agent/orchestrator/runtime-core/ask-user-tool-defs.mjs +100 -0
- package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +3 -0
- package/src/runtime/agent/orchestrator/runtime-core/deferred-tool-availability.mjs +21 -0
- package/src/runtime/agent/orchestrator/runtime-core/effort.mjs +15 -0
- package/src/runtime/agent/orchestrator/runtime-core/goal-reminder.mjs +0 -18
- package/src/runtime/agent/orchestrator/runtime-core/model-capabilities.mjs +57 -28
- package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +19 -16
- package/src/runtime/agent/orchestrator/runtime-core/plugin-mcp.mjs +1 -97
- package/src/runtime/agent/orchestrator/runtime-core/provider-request-snapshot.mjs +7 -3
- package/src/runtime/agent/orchestrator/runtime-core/session-title.mjs +21 -1
- package/src/runtime/agent/orchestrator/runtime-core/skill-tool-loading.mjs +14 -3
- package/src/runtime/agent/orchestrator/runtime-core/tool-bridge.mjs +526 -0
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog-data.mjs +3 -0
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog-schema.mjs +10 -7
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +176 -71
- package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +62 -10
- package/src/runtime/agent/orchestrator/runtime-core/tool-exposure.mjs +96 -0
- package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +5 -1
- package/src/runtime/agent/orchestrator/session/compact/constants.mjs +3 -2
- package/src/runtime/agent/orchestrator/session/compact/messages.mjs +14 -93
- package/src/runtime/agent/orchestrator/session/compact/summary-anchor.mjs +5 -0
- package/src/runtime/agent/orchestrator/session/compact/user-message-kind.mjs +120 -0
- package/src/runtime/agent/orchestrator/session/context-tool-schema.mjs +17 -2
- package/src/runtime/agent/orchestrator/session/context-utils.mjs +8 -4
- package/src/runtime/agent/orchestrator/session/eager-dispatch/admission.mjs +2 -1
- package/src/runtime/agent/orchestrator/session/eager-dispatch.mjs +6 -1
- package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +91 -1
- package/src/runtime/agent/orchestrator/session/loop/completion-guards.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/context-overflow.mjs +56 -0
- package/src/runtime/agent/orchestrator/session/loop/deferred-call-through.mjs +18 -8
- package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +1 -0
- package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +21 -10
- package/src/runtime/agent/orchestrator/session/loop/provider-tool-exclusions.mjs +132 -0
- package/src/runtime/agent/orchestrator/session/loop/request-boundary.mjs +30 -0
- package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +67 -20
- package/src/runtime/agent/orchestrator/session/loop/step-auto-effort.mjs +104 -19
- package/src/runtime/agent/orchestrator/session/loop/tool-call-resolution.mjs +95 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +30 -3
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +15 -4
- package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +15 -1
- package/src/runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs +150 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-phase.mjs +7 -2
- package/src/runtime/agent/orchestrator/session/manager/ask-queue.mjs +30 -2
- package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +11 -2
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-auto-effort.mjs +2 -1
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-commit.mjs +34 -12
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +57 -21
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-loop-options.mjs +57 -25
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-prepare.mjs +6 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +4 -0
- package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +8 -0
- package/src/runtime/agent/orchestrator/session/manager/pending-message-entry.mjs +5 -10
- package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +208 -14
- package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +16 -4
- package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +25 -3
- package/src/runtime/agent/orchestrator/session/manager/session-fallback-title.mjs +82 -0
- package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +19 -2
- package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +3 -0
- package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +4 -1
- package/src/runtime/agent/orchestrator/session/manager/turn-interruption.mjs +18 -7
- package/src/runtime/agent/orchestrator/session/manager.mjs +2 -1
- package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +6 -0
- package/src/runtime/agent/orchestrator/session/send-with-recovery.mjs +168 -29
- package/src/runtime/agent/orchestrator/session/side-question-store.mjs +96 -0
- package/src/runtime/agent/orchestrator/session/side-question.mjs +192 -0
- package/src/runtime/agent/orchestrator/session/store/lifecycle-barriers.mjs +17 -3
- package/src/runtime/agent/orchestrator/session/store/live-state.mjs +23 -0
- package/src/runtime/agent/orchestrator/session/store/paths-heartbeat.mjs +58 -2
- package/src/runtime/agent/orchestrator/session/store/save-worker.mjs +6 -3
- package/src/runtime/agent/orchestrator/session/store/session-delete.mjs +41 -28
- package/src/runtime/agent/orchestrator/session/store/session-observers.mjs +4 -2
- package/src/runtime/agent/orchestrator/session/store/sweep/sweep-finish.mjs +12 -1
- package/src/runtime/agent/orchestrator/session/store/write-admission.mjs +3 -1
- package/src/runtime/agent/orchestrator/session/store/write-guards.mjs +16 -0
- package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +22 -10
- package/src/runtime/agent/orchestrator/session/store-summary-archived-agent.mjs +34 -15
- package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +6 -0
- package/src/runtime/agent/orchestrator/session/store-summary-fields.mjs +13 -0
- package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +13 -1
- package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +10 -2
- package/src/runtime/agent/orchestrator/session/store.mjs +19 -3
- package/src/runtime/agent/orchestrator/session/tool-batch/execute-call.mjs +1 -0
- package/src/runtime/agent/orchestrator/session/tool-batch/finalize.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/tool-batch/record-outcome.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/tool-batch/state.mjs +7 -1
- package/src/runtime/agent/orchestrator/session/tool-result-offload.mjs +4 -0
- package/src/runtime/agent/orchestrator/session/tool-schema-rejection.mjs +77 -0
- package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +20 -1
- package/src/runtime/agent/orchestrator/tools/bash-policy-scan.mjs +8 -2
- package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/command-preflight.mjs +3 -3
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/deadline-plan.mjs +12 -15
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +4 -1
- package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +5 -5
- package/src/runtime/agent/orchestrator/tools/builtin/external-tool-adapters.mjs +14 -10
- package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-job-records.mjs +49 -34
- package/src/runtime/agent/orchestrator/tools/builtin/runtime-capabilities.mjs +23 -1
- package/src/runtime/agent/orchestrator/tools/code-graph/dispatch/root-resolution.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/code-graph/search.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/patch/ui-diff.mjs +73 -39
- package/src/runtime/agent/orchestrator/tools/progress-message.mjs +18 -1
- package/src/runtime/agent/orchestrator/tools/shell-command.mjs +7 -4
- package/src/runtime/agent/orchestrator/tools/shell-exec-policy.mjs +88 -12
- package/src/runtime/agent/orchestrator/tools/shell-policy.mjs +2 -0
- package/src/runtime/computer-bridge/action-schema.mjs +44 -21
- package/src/runtime/github/tool.mjs +92 -2
- package/src/runtime/memory/index.mjs +1 -0
- package/src/runtime/memory/lib/http-router/ingest-routes.mjs +22 -1
- package/src/runtime/memory/lib/ingest/transcript-offsets.mjs +2 -0
- package/src/runtime/memory/lib/pg/adapter.mjs +98 -1
- package/src/runtime/memory/lib/pg/process.mjs +65 -50
- package/src/runtime/memory/lib/pg/run-child.mjs +49 -0
- package/src/runtime/memory/lib/pg/supervisor.mjs +124 -16
- package/src/runtime/memory/lib/runtime-fetcher.mjs +12 -13
- package/src/runtime/memory/lib/transcript-ingest.mjs +14 -0
- package/src/runtime/office/README.md +2 -2
- package/src/runtime/office/authoring/html-document-author.mjs +2 -0
- package/src/runtime/office/authoring/pptx-contact-sheet.mjs +2 -0
- package/src/runtime/office/authoring/pptx-html-measure.mjs +2 -0
- package/src/runtime/office/authoring/pptx-html-runner.mjs +2 -0
- package/src/runtime/office/authoring/xlsx-html-runner.mjs +2 -0
- package/src/runtime/office/core/office-actions-read.mjs +3 -0
- package/src/runtime/office/core/office-render-preview.mjs +2 -0
- package/src/runtime/office/core/office-session-dispatch.mjs +7 -0
- package/src/runtime/office/core/office-sessionless-actions.mjs +8 -0
- package/src/runtime/office/core/office-sessions.mjs +5 -0
- package/src/runtime/office/core/office-transactions.mjs +3 -0
- package/src/runtime/office/core/office-write-ledger.mjs +98 -0
- package/src/runtime/office/design/library/templates/mixdog-executive.mixdog-edit.pptx +0 -0
- package/src/runtime/office/index.mjs +30 -0
- package/src/runtime/office/pdf/pdf-edit-document.mjs +2 -0
- package/src/runtime/office/pdf/pdf-render.mjs +23 -7
- package/src/runtime/office/pdf/pdf-security.mjs +2 -0
- package/src/runtime/office/portable/portable-opc.mjs +4 -1
- package/src/runtime/office/quality/visual-diff.mjs +2 -0
- package/src/runtime/office/shared/values.mjs +0 -5
- package/src/runtime/shared/background-tasks.mjs +92 -14
- package/src/runtime/shared/bounded-file-read.mjs +13 -0
- package/src/runtime/shared/bounded-line-diff.mjs +182 -0
- package/src/runtime/shared/buffered-appender.mjs +18 -0
- package/src/runtime/shared/config.mjs +78 -18
- package/src/runtime/shared/err-text.mjs +31 -0
- package/src/runtime/shared/error-presentation.mjs +159 -19
- package/src/runtime/shared/file-permissions.d.mts +6 -1
- package/src/runtime/shared/file-permissions.mjs +54 -6
- package/src/runtime/shared/llm/anthropic-betas.mjs +4 -3
- package/src/runtime/shared/llm/anthropic-effort.mjs +129 -134
- package/src/runtime/shared/llm/anthropic-thinking-contract.mjs +50 -14
- package/src/runtime/shared/llm/model-catalog.mjs +53 -40
- package/src/runtime/shared/llm/openai-daybreak.mjs +4 -16
- package/src/runtime/shared/llm/provider-catalog-registry.mjs +11 -0
- package/src/runtime/shared/llm/provider-model-identities.mjs +13 -4
- package/src/runtime/shared/llm/usage-accounting.mjs +5 -2
- package/src/runtime/shared/llm/usage-ledger-rollup.mjs +3 -0
- package/src/runtime/shared/llm/usage-rollup.mjs +0 -1
- package/src/runtime/shared/loopback-listener.mjs +9 -0
- package/src/runtime/shared/model-display.mjs +13 -0
- package/src/runtime/shared/provider-api-key.mjs +2 -0
- package/src/runtime/shared/quota-resume-store.mjs +11 -0
- package/src/runtime/shared/review-diff.mjs +52 -0
- package/src/runtime/shared/session-baseline-store.mjs +960 -0
- package/src/runtime/shared/session-sidebar-host.d.mts +4 -0
- package/src/runtime/shared/session-sidebar-host.mjs +38 -0
- package/src/runtime/shared/slow-span.mjs +114 -0
- package/src/runtime/shared/statusline/statusline-format.mjs +4 -4
- package/src/runtime/shared/statusline/statusline-segments.mjs +28 -4
- package/src/runtime/shared/task-notification-envelope.mjs +2 -2
- package/src/runtime/shared/tool-card-model/card-header.mjs +6 -1
- package/src/runtime/shared/tool-card-model/generic-detail.mjs +39 -5
- package/src/runtime/shared/tool-card-model.mjs +5 -2
- package/src/runtime/shared/tool-output-limit.mjs +4 -0
- package/src/runtime/shared/tool-primitives.mjs +13 -0
- package/src/runtime/shared/tool-result-summary.mjs +8 -1
- package/src/runtime/shared/tool-surface.mjs +18 -3
- package/src/runtime/shared/tool-work-units.mjs +40 -4
- package/src/runtime/shared/transcript-writer/purge.mjs +74 -0
- package/src/runtime/shared/transcript-writer.mjs +10 -2
- package/src/runtime/shared/turn-changes.mjs +670 -274
- package/src/runtime/shared/turn-review-reply.mjs +8 -39
- package/src/runtime/shared/turn-snapshot-store.mjs +94 -2
- package/src/runtime/shared/turn-snapshot.mjs +986 -690
- package/src/runtime/shared/turn-worktree-snapshot.mjs +279 -262
- package/src/runtime/shared/user-data-guard.mjs +262 -49
- package/src/runtime/shared/worktrees/carry.mjs +531 -0
- package/src/runtime/shared/worktrees/contract.mjs +34 -24
- package/src/runtime/shared/worktrees/file-recovery.mjs +68 -0
- package/src/runtime/shared/worktrees/git-head.mjs +205 -0
- package/src/runtime/shared/worktrees/git.mjs +8 -3
- package/src/runtime/shared/worktrees/maintenance.mjs +1 -1
- package/src/runtime/shared/worktrees/manager.mjs +156 -8
- package/src/runtime/shared/worktrees/merge.mjs +31 -21
- package/src/runtime/shared/worktrees/paths.d.mts +6 -0
- package/src/runtime/shared/worktrees/test-support.mjs +19 -4
- package/src/runtime/terminal-bridge/client.mjs +44 -11
- package/src/runtime/terminal-bridge/tool-defs.mjs +13 -6
- package/src/runtime/tidy/apply.mjs +47 -2
- package/src/runtime/tidy/run-engines.mjs +11 -5
- package/src/session-runtime/agent-tool-routing.mjs +19 -13
- package/src/session-runtime/boot/apis.mjs +19 -5
- package/src/session-runtime/boot/facade.mjs +1 -0
- package/src/session-runtime/boot/infrastructure.mjs +12 -1
- package/src/session-runtime/boot/session.mjs +0 -1
- package/src/session-runtime/boot/tools.mjs +4 -1
- package/src/session-runtime/cwd-plugins/cwd-apply.mjs +12 -5
- package/src/session-runtime/internal-tool-executor/ask-user-tool.mjs +65 -0
- package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +3 -1
- package/src/session-runtime/internal-tool-executor/knowledge-tools.mjs +11 -4
- package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +115 -18
- package/src/session-runtime/internal-tool-executor.mjs +6 -2
- package/src/session-runtime/lifecycle/cold-heir.mjs +188 -0
- package/src/session-runtime/lifecycle/inheritance.mjs +71 -27
- package/src/session-runtime/lifecycle/session-catalog.mjs +14 -3
- package/src/session-runtime/lifecycle/session-switch/resume.mjs +6 -0
- package/src/session-runtime/lifecycle/session-switch/session-delete.mjs +29 -6
- package/src/session-runtime/lifecycle/teardown.mjs +73 -8
- package/src/session-runtime/lifecycle-api.mjs +1 -0
- package/src/session-runtime/mcp-glue/connect.mjs +46 -14
- package/src/session-runtime/mcp-glue/server-catalog.mjs +20 -3
- package/src/session-runtime/mcp-glue.mjs +3 -0
- package/src/session-runtime/mcp-oauth-login.mjs +174 -0
- package/src/session-runtime/model-route/model-switch-target.mjs +34 -0
- package/src/session-runtime/model-route/set-route.mjs +85 -17
- package/src/session-runtime/model-route/web-search-route.mjs +1 -1
- package/src/session-runtime/native-web-search/routes.mjs +22 -3
- package/src/session-runtime/native-web-search-usage.mjs +51 -0
- package/src/session-runtime/native-web-search.mjs +10 -1
- package/src/session-runtime/new-session-config.mjs +4 -2
- package/src/session-runtime/provider-auth/login.mjs +4 -0
- package/src/session-runtime/provider-models/model-meta.mjs +12 -3
- package/src/session-runtime/quick-model-rows/web-search-rows.mjs +13 -8
- package/src/session-runtime/quick-web-search-models.mjs +13 -38
- package/src/session-runtime/resource-extension-sync.mjs +4 -0
- package/src/session-runtime/resource-mcp-api.mjs +98 -2
- package/src/session-runtime/resource-scope-decorate.mjs +10 -3
- package/src/session-runtime/runtime-review-api.mjs +21 -2
- package/src/session-runtime/services/agent-tool/index-write-queue.mjs +81 -20
- package/src/session-runtime/services/agent-tool/job-task-reconcile.mjs +13 -1
- package/src/session-runtime/services/agent-tool/job-views/agent-list.mjs +7 -2
- package/src/session-runtime/services/agent-tool/lead-worker-index/forgotten-leads.mjs +29 -0
- package/src/session-runtime/services/agent-tool/lead-worker-index/index-file.mjs +1 -1
- package/src/session-runtime/services/agent-tool/lead-worker-index.mjs +73 -7
- package/src/session-runtime/services/agent-tool/send-flow.mjs +22 -4
- package/src/session-runtime/services/agent-tool/spawn-flow/job-start.mjs +2 -0
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-run.mjs +22 -5
- package/src/session-runtime/services/agent-tool/tag-registry.mjs +15 -1
- package/src/session-runtime/services/agent-tool/worker-index/row-liveness.mjs +8 -1
- package/src/session-runtime/services/agent-tool/worker-index/row-shape.mjs +2 -2
- package/src/session-runtime/services/agent-tool/worker-index/row-store.mjs +10 -1
- package/src/session-runtime/services/agent-tool/worker-index.mjs +46 -7
- package/src/session-runtime/services/agent-tool/worker-rows.mjs +17 -0
- package/src/session-runtime/services/agent-tool.mjs +3 -0
- package/src/session-runtime/services/channel-admin.mjs +19 -3
- package/src/session-runtime/services/memory-runtime-proxy/calls.mjs +4 -0
- package/src/session-runtime/services/memory-runtime-proxy.mjs +1 -0
- package/src/session-runtime/services/provider-admin.mjs +81 -15
- package/src/session-runtime/session-transcript-purge.mjs +32 -0
- package/src/session-runtime/session-turn-api.mjs +14 -5
- package/src/session-runtime/settings-builtin-tools-api.mjs +9 -0
- package/src/session-runtime/settings-compaction-api.mjs +1 -0
- package/src/session-runtime/setup-tool/executor.mjs +36 -6
- package/src/session-runtime/setup-tool/extended-actions.mjs +86 -6
- package/src/session-runtime/setup-tool/settings-contract.mjs +13 -3
- package/src/session-runtime/setup-tool/tool-defs.mjs +13 -4
- package/src/session-runtime/skills-api.mjs +3 -5
- package/src/session-runtime/tool-surface.mjs +5 -1
- package/src/session-runtime/turn/compaction-gate.mjs +25 -0
- package/src/session-runtime/turn/session-ops.mjs +7 -5
- package/src/session-runtime/turn/side-question-ops.mjs +22 -0
- package/src/session-runtime/turn/turn-run/ask-callbacks.mjs +5 -1
- package/src/session-runtime/turn/turn-run/turn-prepare.mjs +8 -3
- package/src/session-runtime/turn/turn-run/turn-settle.mjs +10 -0
- package/src/session-runtime/turn/turn-run/turn-timing.mjs +4 -3
- package/src/session-runtime/turn/turn-run.mjs +25 -9
- package/src/session-runtime/usage-stats-api.mjs +43 -11
- package/src/session-runtime/workspace/project-branches.mjs +7 -5
- package/src/session-runtime/workspace/transition-steps.mjs +129 -31
- package/src/session-runtime/workspace/transitions.mjs +190 -15
- package/src/standalone/daemon-agent-control.mjs +9 -1
- package/src/standalone/daemon-drain-policy.mjs +8 -0
- package/src/standalone/daemon-local-session-bridge.mjs +14 -1
- package/src/standalone/daemon-owner.mjs +17 -4
- package/src/standalone/daemon-pg-stop.mjs +51 -0
- package/src/standalone/daemon-stop-budget.d.mts +2 -0
- package/src/standalone/daemon-stop-budget.mjs +18 -0
- package/src/standalone/daemon-stored-session-views.mjs +2 -0
- package/src/standalone/daemon-telemetry.mjs +74 -0
- package/src/standalone/daemon.mjs +64 -8
- package/src/standalone/desktop-service-registry.mjs +5 -0
- package/src/standalone/local-session-runtime.mjs +70 -19
- package/src/standalone/session-client.mjs +42 -0
- package/src/standalone/session-protocol.mjs +14 -0
- package/src/standalone/session-proxy/projection.mjs +41 -4
- package/src/standalone/session-runtime-inline-host/boot-loaders.mjs +15 -1
- package/src/standalone/session-runtime-inline-host.mjs +1 -0
- package/src/standalone/session-service/agent-tree/agent-cancel.mjs +33 -2
- package/src/standalone/session-service/agent-tree/agent-turns.mjs +26 -10
- package/src/standalone/session-service/agent-tree.mjs +12 -0
- package/src/standalone/session-service/quota-resume.mjs +8 -0
- package/src/standalone/session-service/retention/busy.mjs +15 -1
- package/src/standalone/session-service/session-calls/session-action.mjs +18 -3
- package/src/standalone/session-service-api.mjs +11 -1
- package/src/standalone/session-service.mjs +1 -0
- package/src/standalone/session-state-patch.d.mts +2 -1
- package/src/standalone/session-state-patch.mjs +41 -1
- package/src/tui/App.jsx +25 -0
- package/src/tui/app/app-view/floating-panel.jsx +26 -1
- package/src/tui/app/app-view.jsx +1 -0
- package/src/tui/app/btw-controller.mjs +118 -0
- package/src/tui/app/create-app-pickers.mjs +6 -0
- package/src/tui/app/extension-pickers/mcp-login.mjs +107 -0
- package/src/tui/app/extension-pickers/mcp-servers-picker.mjs +2 -1
- package/src/tui/app/extension-pickers.mjs +2 -1
- package/src/tui/app/model-options.mjs +11 -16
- package/src/tui/app/shell-layout/row-budgets.mjs +11 -1
- package/src/tui/app/shell-layout/surfaces.mjs +3 -1
- package/src/tui/app/slash-commands.mjs +20 -5
- package/src/tui/app/slash-dispatch/panel-commands.mjs +16 -1
- package/src/tui/app/slash-dispatch/session-commands.mjs +19 -6
- package/src/tui/app/use-global-key-input/approval-shortcut.mjs +12 -0
- package/src/tui/app/use-global-key-input.mjs +5 -12
- package/src/tui/app/use-prompt-handlers.mjs +11 -0
- package/src/tui/components/BtwPanel.jsx +53 -0
- package/src/tui/components/QuestionPanel.jsx +275 -0
- package/src/tui/components/StatusLine.jsx +2 -0
- package/src/tui/components/question-panel-model.mjs +156 -0
- package/src/tui/components/status-line/local-line.mjs +5 -2
- package/src/tui/components/status-line/use-statusline-text.mjs +7 -1
- package/src/tui/dist/index.mjs +3221 -1500
- package/src/tui/session/context-state.mjs +4 -2
- package/src/tui/session/quota-resume.mjs +46 -14
- package/src/tui/session/session-api/commands.mjs +43 -24
- package/src/tui/session/session-api/controls.mjs +2 -2
- package/src/tui/session/session-api/extensions.mjs +22 -0
- package/src/tui/session/session-api/integrations.mjs +16 -2
- package/src/tui/session/session-api/lifecycle/dispose.mjs +1 -0
- package/src/tui/session/session-api/lifecycle.mjs +7 -2
- package/src/tui/session/session-api/routes.mjs +71 -7
- package/src/tui/session/session-api/settings.mjs +11 -14
- package/src/tui/session/session-api.mjs +1 -0
- package/src/tui/session/session-flow/drain.mjs +7 -1
- package/src/tui/session/session-flow/failed-turn-rewind.mjs +10 -4
- package/src/tui/session/tool-approval.mjs +10 -7
- package/src/tui/session/transcript-spill.mjs +14 -7
- package/src/tui/session/turn-stream.mjs +174 -31
- package/src/tui/session/turn.mjs +46 -16
- package/src/tui/statusline-ansi-bridge.mjs +1 -1
- package/src/ui/statusline-agents.mjs +15 -4
- package/src/ui/statusline.mjs +7 -3
- package/src/ui/streaming-markdown-heal.mjs +34 -3
- package/src/vendor/statusline/src/gateway/claude-current.mjs +14 -4
- package/src/workflows/default/WORKFLOW.md +3 -1
- package/src/runtime/memory/lib/memory-session-merge.mjs +0 -32
- package/src/runtime/shared/llm/usage-session-history.mjs +0 -266
|
@@ -18,6 +18,7 @@ import { withEffortConfigurationFallback } from './effort-configuration.mjs';
|
|
|
18
18
|
import { enrichModels } from './model-catalog.mjs';
|
|
19
19
|
import { sanitizeModelList } from './model-list-sanitize.mjs';
|
|
20
20
|
import { sendViaHttpSse, _envFlag } from './openai-oauth-http-sse.mjs';
|
|
21
|
+
import { waitForRetryDeadline } from './openai-error-contract.mjs';
|
|
21
22
|
import { isWsMessageTooBigClose, shouldFallbackTransport } from './retry-classifier.mjs';
|
|
22
23
|
import { resolveOpenAiTransportPolicy } from './openai-transport-policy.mjs';
|
|
23
24
|
import { applyOpenAIDirectCachePolicy } from './openai-direct-request.mjs';
|
|
@@ -77,6 +78,9 @@ export class OpenAIDirectProvider {
|
|
|
77
78
|
// input_tokens INCLUDES cached tokens (OpenAI convention). See registry.mjs.
|
|
78
79
|
static inputExcludesCache = false;
|
|
79
80
|
name = 'openai';
|
|
81
|
+
// Loop retry policy (send-with-recovery loopRetryPolicy): a connect failure waits for
|
|
82
|
+
// the network, and a content_filter refusal is replayed under the budget.
|
|
83
|
+
retryPolicy = Object.freeze({ unboundedConnectionRetry: true, contentFilterRetryable: true });
|
|
80
84
|
config;
|
|
81
85
|
// Sessions (WS pool keys) the server refused with close 1009. Every later
|
|
82
86
|
// full frame of such a session would be refused again, so it stays on
|
|
@@ -107,6 +111,10 @@ export class OpenAIDirectProvider {
|
|
|
107
111
|
}
|
|
108
112
|
return null;
|
|
109
113
|
}
|
|
114
|
+
/** Drop a disposed transport scope's sticky transport record. */
|
|
115
|
+
releaseTransportScope(scope) {
|
|
116
|
+
this._httpFallbackPoolKeys.delete(scope);
|
|
117
|
+
}
|
|
110
118
|
send(messages, model, tools, sendOpts) {
|
|
111
119
|
return withEffortConfigurationFallback('openai', model, sendOpts || {}, (opts) =>
|
|
112
120
|
this._sendOnce(messages, model, tools, opts)
|
|
@@ -135,8 +143,9 @@ export class OpenAIDirectProvider {
|
|
|
135
143
|
// poolKey MUST be sessionId-only. Falling back to promptCacheKey would
|
|
136
144
|
// let unrelated raw sessions sharing the same provider-scoped cache
|
|
137
145
|
// bucket reuse each other's pooled socket and inherit lastResponseId
|
|
138
|
-
// delta state, producing cross-session prompt corruption.
|
|
139
|
-
|
|
146
|
+
// delta state, producing cross-session prompt corruption. A forked
|
|
147
|
+
// request runs in its own transport scope (transport-scope.mjs).
|
|
148
|
+
const poolKey = opts.transportScope || opts.sessionId || null;
|
|
140
149
|
// cacheKey (prompt_cache_key) only groups the server-side prefix-cache
|
|
141
150
|
// shard — safe to share across sessions, unlike the sessionId poolKey
|
|
142
151
|
// above. buildRequestBody derives it from the base namespace plus a
|
|
@@ -190,26 +199,14 @@ export class OpenAIDirectProvider {
|
|
|
190
199
|
// any liveTextEmitted/emittedToolCall/unsafeToRetry outcome.
|
|
191
200
|
const transportPolicy = resolveOpenAiTransportPolicy();
|
|
192
201
|
const httpFallbackEnabled = transportPolicy.allowHttpFallback && _envFlag('MIXDOG_OPENAI_HTTP_FALLBACK', true);
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
}
|
|
197
|
-
return sendHttp({ ...common, auth: a, opts, fetchFn: opts._fetchFn });
|
|
198
|
-
};
|
|
199
|
-
// Transport-policy switch (MIXDOG_OAI_TRANSPORT). 'http-sse' forces the
|
|
200
|
-
// HTTP/SSE transport directly — no WS attempt, so skip the fallback log
|
|
201
|
-
// that dispatchHttp emits (it is not a fallback here). All other modes
|
|
202
|
-
// ('auto'/'ws-full'/'ws-delta') keep the WS-first path below; ws-full vs
|
|
203
|
-
// ws-delta only affects the delta gate inside openai-ws-delta.mjs.
|
|
204
|
-
if (
|
|
205
|
-
transportPolicy.transport === 'http' ||
|
|
206
|
-
(poolKey && httpFallbackEnabled && this._httpFallbackPoolKeys.has(poolKey))
|
|
207
|
-
) {
|
|
202
|
+
// One HTTP/SSE send with the single replay-safe 401 key reload. `reload`
|
|
203
|
+
// is false when the key was already reloaded earlier in this send.
|
|
204
|
+
const sendHttpWithKeyReload = async (a, reload = true) => {
|
|
208
205
|
try {
|
|
209
|
-
return await sendHttp({ ...common, auth, opts, fetchFn: opts._fetchFn });
|
|
206
|
+
return await sendHttp({ ...common, auth: a, opts, fetchFn: opts._fetchFn });
|
|
210
207
|
} catch (err) {
|
|
211
208
|
const unsafe = err?.liveTextEmitted === true || err?.emittedToolCall === true || err?.unsafeToRetry === true;
|
|
212
|
-
if (err?.httpStatus !== 401 || unsafe) throw err;
|
|
209
|
+
if (!reload || err?.httpStatus !== 401 || unsafe) throw err;
|
|
213
210
|
// The replay discards this attempt; its reported usage stays billed.
|
|
214
211
|
noteErrorUsage(err);
|
|
215
212
|
process.stderr.write('[openai-ws] 401 — reloading apiKey and retrying once over HTTP\n');
|
|
@@ -222,10 +219,32 @@ export class OpenAIDirectProvider {
|
|
|
222
219
|
fetchFn: opts._fetchFn,
|
|
223
220
|
});
|
|
224
221
|
}
|
|
222
|
+
};
|
|
223
|
+
const dispatchHttp = (a, reload = true) => {
|
|
224
|
+
if (!process.env.MIXDOG_QUIET_PROVIDER_LOG) {
|
|
225
|
+
process.stderr.write('[openai-ws] WebSocket unhealthy; falling back to HTTP/SSE\n');
|
|
226
|
+
}
|
|
227
|
+
return sendHttpWithKeyReload(a, reload);
|
|
228
|
+
};
|
|
229
|
+
// Transport-policy switch (MIXDOG_OAI_TRANSPORT). 'http-sse' forces the
|
|
230
|
+
// HTTP/SSE transport directly — no WS attempt, so skip the fallback log
|
|
231
|
+
// that dispatchHttp emits (it is not a fallback here). All other modes
|
|
232
|
+
// ('auto'/'ws-full'/'ws-delta') keep the WS-first path below; ws-full vs
|
|
233
|
+
// ws-delta only affects the delta gate inside openai-ws-delta.mjs.
|
|
234
|
+
if (
|
|
235
|
+
transportPolicy.transport === 'http' ||
|
|
236
|
+
(poolKey &&
|
|
237
|
+
httpFallbackEnabled &&
|
|
238
|
+
// A forked scope follows its session's refusal; it records its own.
|
|
239
|
+
(this._httpFallbackPoolKeys.has(poolKey) || this._httpFallbackPoolKeys.has(opts.sessionId)))
|
|
240
|
+
) {
|
|
241
|
+
return await sendHttpWithKeyReload(auth);
|
|
225
242
|
}
|
|
226
|
-
const fallbackHttp = (a, error) => {
|
|
243
|
+
const fallbackHttp = async (a, error, reload = true) => {
|
|
227
244
|
if (poolKey && isWsMessageTooBigClose(error)) this._httpFallbackPoolKeys.add(poolKey);
|
|
228
|
-
|
|
245
|
+
// Changing transport must not bypass the server's retry deadline.
|
|
246
|
+
await waitForRetryDeadline(error, externalSignal, opts._sleepFn);
|
|
247
|
+
return dispatchHttp(a, reload);
|
|
229
248
|
};
|
|
230
249
|
try {
|
|
231
250
|
return await dispatchWs(auth);
|
|
@@ -254,7 +273,7 @@ export class OpenAIDirectProvider {
|
|
|
254
273
|
return await dispatchWs(retryAuth);
|
|
255
274
|
} catch (retryErr) {
|
|
256
275
|
if (shouldFallbackDirectTransport(retryErr, { signal: externalSignal, enabled: httpFallbackEnabled })) {
|
|
257
|
-
return await fallbackHttp(retryAuth, retryErr);
|
|
276
|
+
return await fallbackHttp(retryAuth, retryErr, false);
|
|
258
277
|
}
|
|
259
278
|
throw retryErr;
|
|
260
279
|
}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenCode Go's Gemini route: `@ai-sdk/google` models are served by the
|
|
3
|
+
* gateway's generateContent endpoint, `{base}/models/{id}:streamGenerateContent`
|
|
4
|
+
* (https://opencode.ai/docs/go/ — Endpoints table). This engine reuses the
|
|
5
|
+
* direct Gemini adapter's request builder, stream consumer, retry ladder and
|
|
6
|
+
* result shaping, and only moves the transport onto the gateway: the Go key
|
|
7
|
+
* (never GEMINI_API_KEY) goes to the Go origin only, as a bearer token and the
|
|
8
|
+
* `x-goog-api-key` header, with the session / User-Agent headers of every Go
|
|
9
|
+
* request. Gateway models have no explicit cachedContents.
|
|
10
|
+
*/
|
|
11
|
+
import { GeminiProvider, geminiRestError } from './gemini.mjs';
|
|
12
|
+
import { GEMINI_FIRST_BYTE_TIMEOUT_MS, consumeGeminiRestStreamResponse } from './gemini-stream.mjs';
|
|
13
|
+
import { geminiBareModelId } from './gemini-cache-policy.mjs';
|
|
14
|
+
import { geminiFailureUsage } from './gemini-response.mjs';
|
|
15
|
+
import { geminiEndsWithFunctionResponse, runGeminiStreamAttempts } from './gemini-retry-policy.mjs';
|
|
16
|
+
import { geminiTextLeakGuardFor } from './gemini-sdk-request.mjs';
|
|
17
|
+
import { emitProviderRetryStage } from './retry-classifier.mjs';
|
|
18
|
+
import { originBoundFetch } from './lib/origin-bound-fetch.mjs';
|
|
19
|
+
import { createPassthroughSignal, createTimeoutSignal } from '../stall-policy.mjs';
|
|
20
|
+
import { getLlmDispatcher } from '../../../shared/llm/http-agent.mjs';
|
|
21
|
+
import { reloadProviderApiKey, resolveProviderApiKey } from '../../../shared/provider-api-key.mjs';
|
|
22
|
+
|
|
23
|
+
const PROVIDER = 'opencode-go';
|
|
24
|
+
|
|
25
|
+
/** The generateContent request body for a built Gemini request. */
|
|
26
|
+
export function openCodeGoGeminiBody({ contents, systemInstruction, geminiTools, toolConfig, generationConfig, safetySettings }) {
|
|
27
|
+
return {
|
|
28
|
+
contents,
|
|
29
|
+
...(systemInstruction ? { systemInstruction: { parts: [{ text: systemInstruction }] } } : {}),
|
|
30
|
+
...(geminiTools ? { tools: geminiTools } : {}),
|
|
31
|
+
...(toolConfig ? { toolConfig } : {}),
|
|
32
|
+
...(generationConfig ? { generationConfig } : {}),
|
|
33
|
+
...(safetySettings ? { safetySettings } : {}),
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export class OpenCodeGoGeminiEngine extends GeminiProvider {
|
|
38
|
+
name = PROVIDER;
|
|
39
|
+
|
|
40
|
+
/** @param {object} config the Go provider config; `baseURL` is the OpenAI-style `.../v1` base */
|
|
41
|
+
constructor(config) {
|
|
42
|
+
const base = String(config.baseURL || '').replace(/\/+$/, '');
|
|
43
|
+
super({
|
|
44
|
+
...config,
|
|
45
|
+
fetchFn: originBoundFetch(new URL(base).origin, config.fetchImpl, PROVIDER),
|
|
46
|
+
// No Google host to warm and no Google SDK client: this engine never uses either.
|
|
47
|
+
preconnectFn: () => {},
|
|
48
|
+
createGenAI: () => null,
|
|
49
|
+
});
|
|
50
|
+
this.gatewayBase = base;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
_getApiKey() {
|
|
54
|
+
return resolveProviderApiKey(PROVIDER, this.config);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
reloadApiKey() {
|
|
58
|
+
const key = reloadProviderApiKey(PROVIDER, this.config);
|
|
59
|
+
if (key) this.config = { ...(this.config || {}), apiKey: key };
|
|
60
|
+
return key || '';
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
async isAvailable() {
|
|
64
|
+
return Boolean(this._getApiKey());
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// The gateway has no cachedContents resource.
|
|
68
|
+
async _ensureGeminiCache() {
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
_headers(opts) {
|
|
73
|
+
const key = this._getApiKey();
|
|
74
|
+
return {
|
|
75
|
+
'Content-Type': 'application/json',
|
|
76
|
+
...(key ? { Authorization: `Bearer ${key}`, 'x-goog-api-key': key } : {}),
|
|
77
|
+
...(this.config?.extraHeaders || {}),
|
|
78
|
+
...(opts?.requestHeaders || {}),
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
_url(model, method) {
|
|
83
|
+
return `${this.gatewayBase}/models/${encodeURIComponent(geminiBareModelId(model))}:${method}`;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
async _openGatewayStream(url, body, opts, attemptSignal) {
|
|
87
|
+
const openFirstByte = createTimeoutSignal(attemptSignal, GEMINI_FIRST_BYTE_TIMEOUT_MS, 'OpenCode Go Gemini first byte');
|
|
88
|
+
let res;
|
|
89
|
+
try {
|
|
90
|
+
res = await this._fetch(url, {
|
|
91
|
+
method: 'POST',
|
|
92
|
+
headers: this._headers(opts),
|
|
93
|
+
body: JSON.stringify(body),
|
|
94
|
+
signal: openFirstByte.signal,
|
|
95
|
+
dispatcher: getLlmDispatcher(),
|
|
96
|
+
});
|
|
97
|
+
} finally {
|
|
98
|
+
openFirstByte.cleanup();
|
|
99
|
+
}
|
|
100
|
+
if (!res.ok) {
|
|
101
|
+
throw geminiRestError(res, await res.text().catch(() => ''), 'OpenCode Go Gemini streamGenerateContent');
|
|
102
|
+
}
|
|
103
|
+
return res;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
async _generateContent(model, body, opts, signal) {
|
|
107
|
+
const res = await this._fetch(this._url(model, 'generateContent'), {
|
|
108
|
+
method: 'POST',
|
|
109
|
+
headers: this._headers(opts),
|
|
110
|
+
body: JSON.stringify(body),
|
|
111
|
+
signal,
|
|
112
|
+
dispatcher: getLlmDispatcher(),
|
|
113
|
+
});
|
|
114
|
+
if (!res.ok) {
|
|
115
|
+
throw geminiRestError(res, await res.text().catch(() => ''), 'OpenCode Go Gemini generateContent');
|
|
116
|
+
}
|
|
117
|
+
return await res.json();
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
async _streamViaSdk(stream) {
|
|
121
|
+
const { opts, signal, useModel, contents, callbacks } = stream;
|
|
122
|
+
const body = openCodeGoGeminiBody(stream);
|
|
123
|
+
const url = `${this._url(useModel, 'streamGenerateContent')}?alt=sse`;
|
|
124
|
+
const passthrough = createPassthroughSignal(signal);
|
|
125
|
+
try {
|
|
126
|
+
return await runGeminiStreamAttempts({
|
|
127
|
+
signal: passthrough.signal,
|
|
128
|
+
sleepFn: this.config?.sleepFn,
|
|
129
|
+
onRetry: ({ attempt, maxAttempts, lastErr, delayMs }) => {
|
|
130
|
+
emitProviderRetryStage(opts.onStageChange, { attempt: attempt + 1, maxAttempts, lastErr, delayMs });
|
|
131
|
+
process.stderr.write(
|
|
132
|
+
`[opencode-go:gemini] retry attempt ${attempt + 1} after ${lastErr?.message || lastErr?.code || 'transient error'}\n`
|
|
133
|
+
);
|
|
134
|
+
},
|
|
135
|
+
afterToolResult: geminiEndsWithFunctionResponse(contents),
|
|
136
|
+
run: async ({ signal: attemptSignal, connected }) => {
|
|
137
|
+
try {
|
|
138
|
+
opts.onStageChange?.('requesting');
|
|
139
|
+
} catch {
|
|
140
|
+
/* heartbeat best-effort */
|
|
141
|
+
}
|
|
142
|
+
const res = await this._openGatewayStream(url, body, opts, attemptSignal);
|
|
143
|
+
connected();
|
|
144
|
+
const textLeakGuard = geminiTextLeakGuardFor(stream);
|
|
145
|
+
const response = await consumeGeminiRestStreamResponse(res, {
|
|
146
|
+
signal: attemptSignal,
|
|
147
|
+
onStreamDelta: callbacks.onStreamDelta,
|
|
148
|
+
onTextDelta: callbacks.onTextDelta,
|
|
149
|
+
textLeakGuard,
|
|
150
|
+
label: 'OpenCode Go Gemini streamGenerateContent',
|
|
151
|
+
failureUsage: geminiFailureUsage(opts, null, useModel),
|
|
152
|
+
});
|
|
153
|
+
return { response, textLeakGuard };
|
|
154
|
+
},
|
|
155
|
+
});
|
|
156
|
+
} catch (err) {
|
|
157
|
+
const recovered = await this._recoverGeminiNonStreaming({
|
|
158
|
+
streamErr: err,
|
|
159
|
+
signal: passthrough.signal,
|
|
160
|
+
opts,
|
|
161
|
+
model: useModel,
|
|
162
|
+
generate: (fallbackSignal) => this._generateContent(useModel, body, opts, fallbackSignal),
|
|
163
|
+
});
|
|
164
|
+
if (!recovered) throw err;
|
|
165
|
+
return { response: recovered, textLeakGuard: null };
|
|
166
|
+
} finally {
|
|
167
|
+
passthrough.cleanup();
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
@@ -1,30 +1,49 @@
|
|
|
1
1
|
import { randomUUID } from 'node:crypto';
|
|
2
2
|
import { AnthropicProvider } from './anthropic.mjs';
|
|
3
3
|
import { OpenAICompatProvider, OPENAI_COMPAT_PRESETS } from './openai-compat.mjs';
|
|
4
|
-
import { currentUsageContext } from '../../../shared/llm/usage-context.mjs';
|
|
5
4
|
import { getModelMetadataSync, getModelsDevRowSync } from './model-catalog.mjs';
|
|
5
|
+
import { toInclusiveUsage, withInclusiveUsage } from './lib/inclusive-usage.mjs';
|
|
6
|
+
import { providerOffersWire, resolveWireRoute, sendOnRoute } from './wire-route.mjs';
|
|
7
|
+
import { gatewayMessagesOpts } from './wire-gateway.mjs';
|
|
8
|
+
|
|
9
|
+
// The Go Anthropic route: the shared request builder gets the model's output
|
|
10
|
+
// ceiling (models.dev limit) through the gateway options.
|
|
11
|
+
class OpenCodeGoMessagesEngine extends AnthropicProvider {
|
|
12
|
+
_sendOnce(messages, model, tools, opts) {
|
|
13
|
+
return super._sendOnce(messages, model, tools, gatewayMessagesOpts(this.config, model, messages, opts));
|
|
14
|
+
}
|
|
15
|
+
}
|
|
6
16
|
|
|
7
17
|
// OpenCode Go publishes OpenAI chat/completions, OpenAI Responses, and
|
|
8
18
|
// Anthropic Messages endpoints, and each upstream brand answers on only one
|
|
9
|
-
// of them (muse-spark / gpt / grok 500 on chat/completions; minimax
|
|
10
|
-
// Messages). models.dev names the SDK package per model, which
|
|
11
|
-
// authoritative wire selector;
|
|
12
|
-
|
|
13
|
-
|
|
19
|
+
// of them (muse-spark / gpt / grok 500 on chat/completions; minimax and
|
|
20
|
+
// Claude expect Messages). models.dev names the SDK package per model, which
|
|
21
|
+
// is the authoritative wire selector; wire-route.mjs holds the cold-catalog
|
|
22
|
+
// prefix fallback. `@ai-sdk/google` names the Gemini generateContent wire
|
|
23
|
+
// (opencode-go-gemini.mjs).
|
|
14
24
|
const WIRE_API_BY_NPM = Object.freeze({
|
|
15
25
|
'@ai-sdk/openai': 'responses',
|
|
16
26
|
'@ai-sdk/anthropic': 'messages',
|
|
17
27
|
'@ai-sdk/openai-compatible': 'chat',
|
|
28
|
+
'@ai-sdk/google': 'gemini',
|
|
18
29
|
});
|
|
19
30
|
|
|
31
|
+
function openCodeGoCatalogWire(model) {
|
|
32
|
+
const npm = getModelsDevRowSync(String(model || ''), 'opencode-go')?.npm;
|
|
33
|
+
return typeof npm === 'string' && Object.hasOwn(WIRE_API_BY_NPM, npm) ? WIRE_API_BY_NPM[npm] : null;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function resolveOpenCodeGoWireRoute(model, ctx = {}) {
|
|
37
|
+
const catalogWire = openCodeGoCatalogWire(model);
|
|
38
|
+
// Each Go model answers on the one wire the catalog names: it narrows the
|
|
39
|
+
// offered endpoints, so an override cannot pick a wire the model lacks.
|
|
40
|
+
const endpoints = providerOffersWire('opencode-go', catalogWire) ? [catalogWire] : null;
|
|
41
|
+
return resolveWireRoute('opencode-go', model, { ...ctx, catalogWire, endpoints });
|
|
42
|
+
}
|
|
43
|
+
|
|
20
44
|
/** Wire API for a Go model: 'responses' | 'messages' | 'chat'. */
|
|
21
45
|
function openCodeGoWireApi(model) {
|
|
22
|
-
|
|
23
|
-
const npm = getModelsDevRowSync(String(model || ''), 'opencode-go')?.npm;
|
|
24
|
-
if (npm && WIRE_API_BY_NPM[npm]) return WIRE_API_BY_NPM[npm];
|
|
25
|
-
if (RESPONSES_MODEL_PREFIXES.some((prefix) => id.startsWith(prefix))) return 'responses';
|
|
26
|
-
if (ANTHROPIC_MODEL_PREFIXES.some((prefix) => id.startsWith(prefix))) return 'messages';
|
|
27
|
-
return 'chat';
|
|
46
|
+
return resolveOpenCodeGoWireRoute(model).wire;
|
|
28
47
|
}
|
|
29
48
|
|
|
30
49
|
export function isAnthropicGoModel(model) {
|
|
@@ -48,42 +67,8 @@ export function openCodeGoEndpointForModel(model, configuredBaseURL) {
|
|
|
48
67
|
return `${bases.openai}/chat/completions`;
|
|
49
68
|
}
|
|
50
69
|
|
|
51
|
-
//
|
|
52
|
-
|
|
53
|
-
// and one source object always converts to the same object, so an abandoned
|
|
54
|
-
// attempt and the error that later carries it stay one record.
|
|
55
|
-
const inclusiveUsage = new WeakSet();
|
|
56
|
-
const convertedUsage = new WeakMap();
|
|
57
|
-
|
|
58
|
-
export function toInclusiveOpenCodeGoUsage(usage) {
|
|
59
|
-
if (!usage || inclusiveUsage.has(usage)) return usage;
|
|
60
|
-
if (convertedUsage.has(usage)) return convertedUsage.get(usage);
|
|
61
|
-
const input = Number(usage.inputTokens) || 0;
|
|
62
|
-
const cached = Number(usage.cachedTokens) || 0;
|
|
63
|
-
const cacheWrite = Number(usage.cacheWriteTokens) || 0;
|
|
64
|
-
const inclusiveInput = input + cached + cacheWrite;
|
|
65
|
-
const converted = {
|
|
66
|
-
...usage,
|
|
67
|
-
inputTokens: inclusiveInput,
|
|
68
|
-
promptTokens: Math.max(Number(usage.promptTokens) || 0, inclusiveInput),
|
|
69
|
-
};
|
|
70
|
-
inclusiveUsage.add(converted);
|
|
71
|
-
convertedUsage.set(usage, converted);
|
|
72
|
-
return converted;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
function normalizeOpenCodeGoResultUsage(result, anthropicRoute) {
|
|
76
|
-
if (!anthropicRoute || !result?.usage) return result;
|
|
77
|
-
return { ...result, usage: toInclusiveOpenCodeGoUsage(result.usage) };
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
function normalizeOpenCodeGoError(error) {
|
|
81
|
-
if (error && typeof error === 'object') {
|
|
82
|
-
if (error.usage) error.usage = toInclusiveOpenCodeGoUsage(error.usage);
|
|
83
|
-
if (error.partialUsage) error.partialUsage = toInclusiveOpenCodeGoUsage(error.partialUsage);
|
|
84
|
-
}
|
|
85
|
-
return error;
|
|
86
|
-
}
|
|
70
|
+
// The Messages route reports usage in the provider's inclusive convention.
|
|
71
|
+
export const toInclusiveOpenCodeGoUsage = toInclusiveUsage;
|
|
87
72
|
|
|
88
73
|
function opencodeGoContextWindow(modelId, current = 0) {
|
|
89
74
|
const native = Number(current);
|
|
@@ -118,11 +103,15 @@ export class OpenCodeGoProvider {
|
|
|
118
103
|
const preset = OPENAI_COMPAT_PRESETS['opencode-go'];
|
|
119
104
|
const bases = resolveOpenCodeGoBaseURLs(config.baseURL || preset.baseURL);
|
|
120
105
|
this.openai = new OpenAICompatProvider('opencode-go', { ...config, baseURL: bases.openai });
|
|
121
|
-
this.anthropic = new
|
|
106
|
+
this.anthropic = new OpenCodeGoMessagesEngine({
|
|
122
107
|
...config,
|
|
123
108
|
name: 'opencode-go',
|
|
124
109
|
baseURL: bases.anthropic,
|
|
125
110
|
disableBetaHeaders: true,
|
|
111
|
+
// The preset's identifying headers (User-Agent) ride the Messages wire
|
|
112
|
+
// too; the user's own headers win.
|
|
113
|
+
extraHeaders: { ...(preset.extraHeaders || {}), ...(config.extraHeaders || {}) },
|
|
114
|
+
modelMaxOutputTokens: (model) => this.getCachedModelInfo(model)?.outputTokens,
|
|
126
115
|
});
|
|
127
116
|
// The Anthropic route answers for this provider: PDFs lower to text.
|
|
128
117
|
this.anthropic.nativePdf = this.nativePdf;
|
|
@@ -142,29 +131,45 @@ export class OpenCodeGoProvider {
|
|
|
142
131
|
'x-opencode-session': sessionId,
|
|
143
132
|
},
|
|
144
133
|
};
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
return
|
|
163
|
-
} catch (error) {
|
|
164
|
-
throw normalizeOpenCodeGoError(error);
|
|
134
|
+
// The session's pinned route, else this model's route (wire-route.mjs);
|
|
135
|
+
// the resolved route is the only wire authority (a caller's own wire
|
|
136
|
+
// switches never reach an engine), and one clear "unsupported" refusal
|
|
137
|
+
// moves the send to the next wire once.
|
|
138
|
+
return sendOnRoute(this, model, tools, sendOpts, messages, async (wire, history, opts) => {
|
|
139
|
+
if (wire === 'responses') {
|
|
140
|
+
// OpenAI-family brands on the gateway (Muse Spark, GPT, Grok)
|
|
141
|
+
// only answer on /responses; the compat transport switches wire
|
|
142
|
+
// shape per request via this flag.
|
|
143
|
+
return this.openai.send(history, model, tools, { ...opts, compatWireApi: 'responses' });
|
|
144
|
+
}
|
|
145
|
+
if (wire === 'messages') {
|
|
146
|
+
// The Anthropic-style Go endpoint reports cached read/write usage
|
|
147
|
+
// and accepts the standard message shape. Preserve the caller's
|
|
148
|
+
// cache strategy so the shared Anthropic live-tail marker advances
|
|
149
|
+
// through tool loops instead of forcing every request fully cold.
|
|
150
|
+
// Abandoned attempts noted by the inner provider use the same conversion.
|
|
151
|
+
return withInclusiveUsage(() => this.anthropic.send(history, model, tools, opts));
|
|
165
152
|
}
|
|
153
|
+
if (wire === 'gemini') return (await this._geminiEngine()).send(history, model, tools, opts);
|
|
154
|
+
return this.openai.send(history, model, tools, opts);
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// The Gemini generateContent route; the Google SDK loads only when a Gemini model is used.
|
|
159
|
+
async _geminiEngine() {
|
|
160
|
+
if (!this.gemini) {
|
|
161
|
+
const { OpenCodeGoGeminiEngine } = await import('./opencode-go-gemini.mjs');
|
|
162
|
+
this.gemini = new OpenCodeGoGeminiEngine({
|
|
163
|
+
...this.config,
|
|
164
|
+
baseURL: this.openai.baseURL,
|
|
165
|
+
extraHeaders: { ...(OPENAI_COMPAT_PRESETS['opencode-go'].extraHeaders || {}), ...(this.config.extraHeaders || {}) },
|
|
166
|
+
});
|
|
166
167
|
}
|
|
167
|
-
return this.
|
|
168
|
+
return this.gemini;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
resolveWireRoute(model, ctx = {}) {
|
|
172
|
+
return resolveOpenCodeGoWireRoute(model, { ...ctx, override: this.config?.modelWires?.[model] ?? null });
|
|
168
173
|
}
|
|
169
174
|
|
|
170
175
|
async listModels() {
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenRouter: one API key, three wires. Claude (`anthropic/*`, `~anthropic/*`)
|
|
3
|
+
* goes through the Anthropic Messages engine at https://openrouter.ai/api (the
|
|
4
|
+
* SDK appends /v1/messages); OpenAI GPT / o-series (`openai/gpt-*`,
|
|
5
|
+
* `openai/o*`, `~openai/*`) through the OpenAI-compatible engine's Responses
|
|
6
|
+
* wire; openrouter/auto and every other model through Chat Completions.
|
|
7
|
+
* Account-level provider-routing preferences stay OpenRouter's: no request
|
|
8
|
+
* names a provider order.
|
|
9
|
+
*/
|
|
10
|
+
import { WireGatewayProvider, messagesBaseFromOpenAIBase } from './wire-gateway.mjs';
|
|
11
|
+
import { OPENAI_COMPAT_PRESETS } from './openai-compat-presets.mjs';
|
|
12
|
+
import { openRouterReasoning } from './openai-compat-options.mjs';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* The Claude id a routing slug stands for: an alias (`~anthropic/claude-opus-latest`)
|
|
16
|
+
* reads its catalog `alias_target`, the vendor prefix and a `:variant` suffix
|
|
17
|
+
* drop. Capability lookup only — the request still names the routing slug.
|
|
18
|
+
*/
|
|
19
|
+
export function openRouterCapabilityModel(model, aliasTarget = null) {
|
|
20
|
+
return String(aliasTarget || model || '')
|
|
21
|
+
.replace(/^~/, '')
|
|
22
|
+
.replace(/^anthropic\//i, '')
|
|
23
|
+
.replace(/:[^/]*$/, '');
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Responses requests carry the same reasoning control as Chat requests
|
|
27
|
+
// (`openRouterReasoningEffort`, else the turn effort, else the configured
|
|
28
|
+
// effort; `none` disables reasoning).
|
|
29
|
+
function openRouterResponsesParams(config) {
|
|
30
|
+
return (params, { opts }) => {
|
|
31
|
+
const reasoning = openRouterReasoning(opts, config);
|
|
32
|
+
if (reasoning) params.reasoning = reasoning;
|
|
33
|
+
else delete params.reasoning;
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// The Messages route takes the same control: the effort to send ('none' = no
|
|
38
|
+
// thinking), or null to keep the engine's own handling.
|
|
39
|
+
function openRouterMessagesEffort(config) {
|
|
40
|
+
return (opts) => {
|
|
41
|
+
const reasoning = openRouterReasoning(opts, config);
|
|
42
|
+
if (!reasoning) return null;
|
|
43
|
+
return reasoning.enabled === false ? 'none' : reasoning.effort;
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** A roster row carrying `top_provider.max_completion_tokens` as its output ceiling. */
|
|
48
|
+
export function withTopProviderOutputCeiling(item) {
|
|
49
|
+
const ceiling = Number(item?.top_provider?.max_completion_tokens);
|
|
50
|
+
if (!(ceiling > 0) || item.max_output_tokens !== undefined) return item;
|
|
51
|
+
return { ...item, max_output_tokens: ceiling };
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export class OpenRouterProvider extends WireGatewayProvider {
|
|
55
|
+
constructor(config = {}) {
|
|
56
|
+
const baseURL = config.baseURL || OPENAI_COMPAT_PRESETS.openrouter.baseURL;
|
|
57
|
+
super(
|
|
58
|
+
'openrouter',
|
|
59
|
+
config,
|
|
60
|
+
{
|
|
61
|
+
baseURL: messagesBaseFromOpenAIBase(baseURL),
|
|
62
|
+
authScheme: 'bearer',
|
|
63
|
+
// OpenRouter Messages takes PDFs natively as document blocks.
|
|
64
|
+
nativePdf: true,
|
|
65
|
+
messagesEffort: openRouterMessagesEffort(config),
|
|
66
|
+
capabilityModel: (model) => openRouterCapabilityModel(model, this.getCachedModelInfo(model)?.aliasTarget),
|
|
67
|
+
},
|
|
68
|
+
{ responsesParamsHook: openRouterResponsesParams(config) }
|
|
69
|
+
);
|
|
70
|
+
// The roster's output ceiling is `top_provider.max_completion_tokens`.
|
|
71
|
+
const fetchItems = this.openai._fetchModelItems.bind(this.openai);
|
|
72
|
+
this.openai._fetchModelItems = async (options) =>
|
|
73
|
+
(await fetchItems(options)).map(withTopProviderOutputCeiling);
|
|
74
|
+
}
|
|
75
|
+
}
|