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
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { randomBytes } from 'node:crypto';
|
|
2
2
|
import { PROVIDER_FIRST_BYTE_TIMEOUT_MS, providerTimeoutError, streamStalledError } from '../stall-policy.mjs';
|
|
3
3
|
import { typedStatusFrom } from './retry-classifier.mjs';
|
|
4
|
+
import { applyCompatErrorContract } from './openai-compat-error-contract.mjs';
|
|
5
|
+
import { truncatedCompatStreamError } from './lib/openai-tool-args.mjs';
|
|
4
6
|
|
|
5
7
|
// Shared lifecycle and replay boundaries for both OpenAI-compatible protocols.
|
|
6
8
|
|
|
@@ -22,10 +24,68 @@ function markInBandWireError(err) {
|
|
|
22
24
|
if (typed && !err.httpStatus) err.httpStatus = typed;
|
|
23
25
|
const code = detail.code ?? detail.type ?? null;
|
|
24
26
|
if (code != null && code !== '' && !err.providerErrorCode) err.providerErrorCode = String(code);
|
|
27
|
+
applyCompatErrorContract(err, detail);
|
|
25
28
|
} catch {}
|
|
26
29
|
return err;
|
|
27
30
|
}
|
|
28
31
|
|
|
32
|
+
/**
|
|
33
|
+
* A frame the SDK failed to JSON-decode. Raised only at the wire-decoding
|
|
34
|
+
* boundary (the iterator's own next()); consumers stamp the exposure evidence
|
|
35
|
+
* (partial output, replay safety) on it in their failure path.
|
|
36
|
+
*/
|
|
37
|
+
export function malformedCompatStreamError(label, cause) {
|
|
38
|
+
const err = new Error(`${label || 'compat SSE'} malformed stream frame: ${cause?.message || 'invalid JSON'}`, {
|
|
39
|
+
cause,
|
|
40
|
+
});
|
|
41
|
+
err.name = 'MalformedStreamError';
|
|
42
|
+
err.code = 'malformed_stream';
|
|
43
|
+
err.malformedStream = true;
|
|
44
|
+
return err;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* A chat `finish_reason: network_error` is an interruption the gateway reports
|
|
49
|
+
* in-band, never a completion. Typed as a truncated stream so the shared
|
|
50
|
+
* classifier treats it as transient; exposure gates decide replay.
|
|
51
|
+
*/
|
|
52
|
+
export function networkInterruptedCompatStreamError(label) {
|
|
53
|
+
const err = truncatedCompatStreamError(label, 'finish_reason=network_error');
|
|
54
|
+
err.name = 'StreamInterruptedError';
|
|
55
|
+
err.streamInterrupted = true;
|
|
56
|
+
err.finishReason = 'network_error';
|
|
57
|
+
return err;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export function isNetworkErrorFinishReason(finishReason) {
|
|
61
|
+
return typeof finishReason === 'string' && finishReason.trim().toLowerCase() === 'network_error';
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* A chat `finish_reason: error` means the upstream failed the generation
|
|
66
|
+
* (gateways surface it as a 502 upstream_error). Typed like the network interruption, with the gateway status.
|
|
67
|
+
*/
|
|
68
|
+
export function upstreamErrorCompatStreamError(label) {
|
|
69
|
+
const err = truncatedCompatStreamError(label, 'finish_reason=error');
|
|
70
|
+
err.name = 'StreamInterruptedError';
|
|
71
|
+
err.streamInterrupted = true;
|
|
72
|
+
err.finishReason = 'error';
|
|
73
|
+
err.status = 502;
|
|
74
|
+
err.code = 'upstream_error';
|
|
75
|
+
return err;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export function isErrorFinishReason(finishReason) {
|
|
79
|
+
return typeof finishReason === 'string' && finishReason.trim().toLowerCase() === 'error';
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/** The typed interruption for a failing chat finish_reason, or null for any other value. */
|
|
83
|
+
export function failingFinishReasonError(finishReason, label) {
|
|
84
|
+
if (isNetworkErrorFinishReason(finishReason)) return networkInterruptedCompatStreamError(label);
|
|
85
|
+
if (isErrorFinishReason(finishReason)) return upstreamErrorCompatStreamError(label);
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
|
|
29
89
|
export function synthLeakedOpenAICall(recovered) {
|
|
30
90
|
let args = recovered?.arguments;
|
|
31
91
|
if (args === null || typeof args !== 'object' || Array.isArray(args)) args = {};
|
|
@@ -59,7 +119,7 @@ export function closeCompatStream(stream, iterator) {
|
|
|
59
119
|
|
|
60
120
|
export async function nextAsyncWithWatchdog(
|
|
61
121
|
iterator,
|
|
62
|
-
{ signal, idleMs, idleDeadlineAt, idleEnabled, idleLabel, emittedToolCall } = {}
|
|
122
|
+
{ signal, idleMs, idleDeadlineAt, idleEnabled, idleLabel, streamLabel, emittedToolCall } = {}
|
|
63
123
|
) {
|
|
64
124
|
let idleTimer = null;
|
|
65
125
|
let idleReject = null;
|
|
@@ -106,7 +166,11 @@ export async function nextAsyncWithWatchdog(
|
|
|
106
166
|
};
|
|
107
167
|
signal.addEventListener('abort', onAbort, { once: true });
|
|
108
168
|
}
|
|
109
|
-
|
|
169
|
+
// The SDK JSON-decodes each frame inside next(): a SyntaxError here is a
|
|
170
|
+
// malformed wire frame, typed at this boundary and nowhere else.
|
|
171
|
+
iterator.next().then(resolve, (error) =>
|
|
172
|
+
reject(error instanceof SyntaxError ? malformedCompatStreamError(streamLabel || idleLabel, error) : error)
|
|
173
|
+
);
|
|
110
174
|
});
|
|
111
175
|
} catch (err) {
|
|
112
176
|
if (idleTimedOut)
|
|
@@ -31,6 +31,7 @@ import {
|
|
|
31
31
|
finalizeResponsesStream,
|
|
32
32
|
unresolvedSalvageError,
|
|
33
33
|
} from './openai-compat-responses-state.mjs';
|
|
34
|
+
import { createRefusals, refusalResultFields } from './openai-ws-response-state/refusals.mjs';
|
|
34
35
|
import { responsesUsage } from './openai-compat-response-normalization.mjs';
|
|
35
36
|
import { noteAbandonedUsage } from '../../../shared/llm/usage-context.mjs';
|
|
36
37
|
|
|
@@ -99,6 +100,7 @@ export async function consumeCompatResponsesStream(
|
|
|
99
100
|
idleDeadlineAt: state.semanticIdleDeadlineAt,
|
|
100
101
|
idleEnabled: sawFirstEvent && idleEnabled && state.semanticIdleDeadlineAt > 0,
|
|
101
102
|
idleLabel: `${label} SSE idle`,
|
|
103
|
+
streamLabel: label,
|
|
102
104
|
// Unsafe-to-retry once any tool call (native or recovered-leaked)
|
|
103
105
|
// has been emitted this stream — avoid a double side-effect.
|
|
104
106
|
emittedToolCall: () => state.emittedToolCall || leakedCalls.length > 0,
|
|
@@ -144,13 +146,18 @@ export async function consumeCompatResponsesStream(
|
|
|
144
146
|
}
|
|
145
147
|
throw stampOutcome(err);
|
|
146
148
|
}
|
|
147
|
-
const unresolved = unresolvedSalvageError(state);
|
|
149
|
+
const unresolved = unresolvedSalvageError(state, label);
|
|
148
150
|
if (unresolved) {
|
|
149
151
|
attachPartialState(unresolved, state, leakedCalls);
|
|
150
152
|
throw stampOutcome(unresolved);
|
|
151
153
|
}
|
|
152
154
|
try {
|
|
153
|
-
|
|
155
|
+
const result = finalizeResponsesStream(state, { leakedCalls, parseResponsesToolCalls, responseOutputText, label });
|
|
156
|
+
// The terminal output bundle's refusal parts join the streamed ones (keyed
|
|
157
|
+
// by item id + content index, so copies of one part fold into one text).
|
|
158
|
+
state.refusals ||= createRefusals();
|
|
159
|
+
for (const item of result.response?.output || []) state.refusals.absorbMessage(item);
|
|
160
|
+
return { ...result, ...refusalResultFields(state.refusals, result.content) };
|
|
154
161
|
} catch (err) {
|
|
155
162
|
attachPartialState(err, state, leakedCalls);
|
|
156
163
|
throw stampOutcome(err);
|
|
@@ -37,6 +37,8 @@ export function extractCompatCachedTokens(usage) {
|
|
|
37
37
|
usage?.input_tokens_details?.cached_tokens,
|
|
38
38
|
usage?.prompt_cache_hit_tokens,
|
|
39
39
|
usage?.cached_prompt_text_tokens,
|
|
40
|
+
// Together reports it top-level; first-positive wins, so it never stacks on a nested count.
|
|
41
|
+
usage?.cached_tokens,
|
|
40
42
|
];
|
|
41
43
|
for (const v of candidates) {
|
|
42
44
|
const n = Number(v);
|
|
@@ -17,7 +17,11 @@ import {
|
|
|
17
17
|
} from './media-normalization.mjs';
|
|
18
18
|
import { customToolCallFromResponseItem, nativeToolSearchCallFromArguments } from './custom-tool-wire.mjs';
|
|
19
19
|
import { providerReplayItems } from './lib/provider-replay.mjs';
|
|
20
|
+
import { acceptedWireTools } from './lib/claude-bridge-schema.mjs';
|
|
20
21
|
import { ensureResponsesCallOutputs } from './lib/wire-pairing.mjs';
|
|
22
|
+
import { responsesEffortUpdates } from './effort-configuration.mjs';
|
|
23
|
+
import { convertMessagesToResponsesInput } from './openai-responses-input.mjs';
|
|
24
|
+
import { COMPAT_REASONING_METADATA_KEY, contentWithThinkingChunk } from './openai-compat-reasoning-field.mjs';
|
|
21
25
|
|
|
22
26
|
function positiveTokenInt(value) {
|
|
23
27
|
const n = Number(value);
|
|
@@ -38,19 +42,23 @@ export function toOpenAIMessages(messages, providerName, options = {}) {
|
|
|
38
42
|
// strict providers (xai) reject unknown roles/types and would 400 the
|
|
39
43
|
// request. Documented in v0.1.160 (GPT reasoning replay).
|
|
40
44
|
//
|
|
41
|
-
// DeepSeek
|
|
42
|
-
//
|
|
43
|
-
//
|
|
44
|
-
//
|
|
45
|
-
//
|
|
46
|
-
//
|
|
47
|
-
// assistant reasoning_content is replayed; reasoning_effort itself remains
|
|
48
|
-
// caller/user-selected.
|
|
45
|
+
// DeepSeek thinking-mode models with tools REQUIRE the prior turn's
|
|
46
|
+
// `reasoning_content` echoed back (400 without it); without tools it is
|
|
47
|
+
// ignored, so the caller (options.replaysReasoningContent) always replays it.
|
|
48
|
+
// xAI reasoning models preserve their official multi-turn shape and cache
|
|
49
|
+
// prefix stability when prior assistant reasoning_content is replayed;
|
|
50
|
+
// reasoning_effort itself remains caller/user-selected.
|
|
49
51
|
//
|
|
50
52
|
// Custom providers pass options.customReplay (custom-reasoning.mjs replay
|
|
51
53
|
// eligibility). When it is a boolean it alone decides; a replaying custom
|
|
52
54
|
// endpoint also needs a non-empty reasoning_content on every assistant
|
|
53
55
|
// tool-call turn, so missing/empty reasoning there is padded with " ".
|
|
56
|
+
//
|
|
57
|
+
// options.reasoningShape (openai-compat-reasoning-field.mjs) names the
|
|
58
|
+
// endpoint families with their own reasoning fields; they decide the resend
|
|
59
|
+
// key and win over the flags above. options.developerRole keeps the
|
|
60
|
+
// `developer` role for endpoints that document it; every other chat endpoint
|
|
61
|
+
// only knows `system`, so developer instructions go out as system messages.
|
|
54
62
|
const customReplay = typeof options.customReplay === 'boolean' ? options.customReplay : null;
|
|
55
63
|
const replaysReasoningContent = customReplay ?? (options.replaysReasoningContent === true || providerName === 'xai');
|
|
56
64
|
const out = [];
|
|
@@ -61,8 +69,25 @@ export function toOpenAIMessages(messages, providerName, options = {}) {
|
|
|
61
69
|
const details = metadata?.reasoning_details ?? metadata?.reasoningDetails;
|
|
62
70
|
return Array.isArray(details) && details.length ? details : null;
|
|
63
71
|
};
|
|
72
|
+
const shape = options.reasoningShape || null;
|
|
73
|
+
// Receive and resend fields differ per endpoint family: the key a reply's
|
|
74
|
+
// reasoning arrived on is recorded in providerMetadata at receive time.
|
|
75
|
+
const receivedField = (message) => message?.providerMetadata?.[COMPAT_REASONING_METADATA_KEY]?.reasoningField;
|
|
76
|
+
const attachShapeReasoning = (msg, message, stored) => {
|
|
77
|
+
if (!stored) return;
|
|
78
|
+
if (shape.resend === 'same_key') {
|
|
79
|
+
msg[receivedField(message) === 'reasoning' ? 'reasoning' : 'reasoning_content'] = stored;
|
|
80
|
+
} else if (shape.resend === 'reasoning') {
|
|
81
|
+
// OpenRouter: reasoning_details replace the text when present.
|
|
82
|
+
if (!openRouterReasoningDetails(message)) msg.reasoning = stored;
|
|
83
|
+
} else if (shape.resend === 'content_chunks' && receivedField(message) === 'content_chunks') {
|
|
84
|
+
msg.content = contentWithThinkingChunk(msg.content, stored);
|
|
85
|
+
}
|
|
86
|
+
};
|
|
64
87
|
const attachAssistantReasoning = (msg, message) => {
|
|
65
|
-
if (
|
|
88
|
+
if (shape) {
|
|
89
|
+
attachShapeReasoning(msg, message, typeof message.reasoningContent === 'string' ? message.reasoningContent : '');
|
|
90
|
+
} else if (customReplay) {
|
|
66
91
|
const stored = typeof message.reasoningContent === 'string' ? message.reasoningContent : '';
|
|
67
92
|
if (stored) msg.reasoning_content = stored;
|
|
68
93
|
else if (Array.isArray(msg.tool_calls) && msg.tool_calls.length) msg.reasoning_content = ' ';
|
|
@@ -103,8 +128,12 @@ export function toOpenAIMessages(messages, providerName, options = {}) {
|
|
|
103
128
|
continue;
|
|
104
129
|
}
|
|
105
130
|
const msg = {
|
|
106
|
-
role: m.role,
|
|
107
|
-
content: normalizeContentForOpenAIChat(m.content, {
|
|
131
|
+
role: m.role === 'developer' && options.developerRole !== true ? 'system' : m.role,
|
|
132
|
+
content: normalizeContentForOpenAIChat(m.content, {
|
|
133
|
+
role: m.role,
|
|
134
|
+
nativePdf: options.nativePdf,
|
|
135
|
+
cacheControl: options.cacheControl === true,
|
|
136
|
+
}),
|
|
108
137
|
};
|
|
109
138
|
out.push(m.role === 'assistant' ? attachAssistantReasoning(msg, m) : msg);
|
|
110
139
|
}
|
|
@@ -112,18 +141,6 @@ export function toOpenAIMessages(messages, providerName, options = {}) {
|
|
|
112
141
|
return out;
|
|
113
142
|
}
|
|
114
143
|
|
|
115
|
-
// deepseek-reasoner returns 400 when `reasoning_content` appears in the input
|
|
116
|
-
// messages; every other DeepSeek thinking model needs it back once tools are in
|
|
117
|
-
// play. Unknown DeepSeek ids default to replaying: a missing echo breaks the
|
|
118
|
-
// tool loop, while a stray field on a non-thinking model is ignored.
|
|
119
|
-
export function deepseekReplaysReasoningContent(model) {
|
|
120
|
-
return !/reasoner/.test(
|
|
121
|
-
String(model || '')
|
|
122
|
-
.trim()
|
|
123
|
-
.toLowerCase()
|
|
124
|
-
);
|
|
125
|
-
}
|
|
126
|
-
|
|
127
144
|
export function toOpenAITools(tools) {
|
|
128
145
|
return tools.map((t) => ({
|
|
129
146
|
type: 'function',
|
|
@@ -145,9 +162,42 @@ function functionToolFromSessionTool(t, name = t?.name) {
|
|
|
145
162
|
};
|
|
146
163
|
}
|
|
147
164
|
|
|
148
|
-
|
|
165
|
+
// xAI hosts tool search itself (docs.x.ai progressive tool disclosure): a
|
|
166
|
+
// `{type:'tool_search'}` server tool loads the definitions of function tools
|
|
167
|
+
// marked `defer_loading: true`, and the server returns the search as
|
|
168
|
+
// tool_search_call / tool_search_output items. The client loader (`load_tool`)
|
|
169
|
+
// is therefore replaced by that one server tool; with deferred tools but no
|
|
170
|
+
// loader the server tool is still added, or the deferred tools could never load.
|
|
171
|
+
function toServerToolSearchTools(tools) {
|
|
172
|
+
let hasSearch = false;
|
|
173
|
+
let hasDeferred = false;
|
|
174
|
+
const out = tools.map((t) => {
|
|
175
|
+
if (t?.name === 'load_tool' || t?.name === 'tool_search') {
|
|
176
|
+
if (hasSearch) return null;
|
|
177
|
+
hasSearch = true;
|
|
178
|
+
return { type: 'tool_search' };
|
|
179
|
+
}
|
|
180
|
+
if (t?.deferLoading === true || t?.defer_loading === true) {
|
|
181
|
+
hasDeferred = true;
|
|
182
|
+
return { ...functionToolFromSessionTool(t), defer_loading: true };
|
|
183
|
+
}
|
|
184
|
+
return functionToolFromSessionTool(t);
|
|
185
|
+
});
|
|
186
|
+
if (hasDeferred && !hasSearch) out.push({ type: 'tool_search' });
|
|
187
|
+
return out.filter(Boolean);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
export function toResponsesTools(allTools, options = {}) {
|
|
149
191
|
const provider = String(options?.provider || '').toLowerCase();
|
|
192
|
+
// A Responses endpoint rejects the whole request for one invalid
|
|
193
|
+
// `parameters`; a tool broken even after lowering is left out and reported.
|
|
194
|
+
const tools = acceptedWireTools(allTools, 'openai', options?.onToolExcluded, `[${provider || 'responses'}] tool`);
|
|
195
|
+
if (options?.serverToolSearch === true) return toServerToolSearchTools(tools);
|
|
196
|
+
// A route pinned with verified native deferred tools declares the native
|
|
197
|
+
// client tool_search tool and marks deferred definitions `defer_loading`.
|
|
198
|
+
const nativeDeferred = options?.nativeDeferredTools === true;
|
|
150
199
|
const allowNativeToolSearch =
|
|
200
|
+
nativeDeferred ||
|
|
151
201
|
options?.nativeToolSearch === true ||
|
|
152
202
|
(options?.nativeToolSearch !== false && (provider === 'openai' || provider === 'openai-oauth'));
|
|
153
203
|
return tools.map((t) => {
|
|
@@ -169,6 +219,9 @@ export function toResponsesTools(tools, options = {}) {
|
|
|
169
219
|
// tools (e.g. apply_patch) as ordinary function tools instead. Grammar
|
|
170
220
|
// tools may carry no usable inputSchema, so fall back to a permissive
|
|
171
221
|
// object schema so grok still registers a valid function tool.
|
|
222
|
+
if (nativeDeferred && (t?.deferLoading === true || t?.defer_loading === true)) {
|
|
223
|
+
return { ...functionToolFromSessionTool(t), defer_loading: true };
|
|
224
|
+
}
|
|
172
225
|
return functionToolFromSessionTool(t);
|
|
173
226
|
});
|
|
174
227
|
}
|
|
@@ -236,7 +289,7 @@ export function parseResponsesToolCalls(response, label) {
|
|
|
236
289
|
} else if (item?.type === 'custom_tool_call') {
|
|
237
290
|
const call = customToolCallFromResponseItem(item);
|
|
238
291
|
if (call) out.push(call);
|
|
239
|
-
} else if (item?.type === 'tool_search_call') {
|
|
292
|
+
} else if (item?.type === 'tool_search_call' && item.execution !== 'server') {
|
|
240
293
|
const searchArgs =
|
|
241
294
|
item.arguments && typeof item.arguments === 'object' && !Array.isArray(item.arguments)
|
|
242
295
|
? item.arguments
|
|
@@ -408,25 +461,54 @@ export function toXaiResponsesInput(messages, providerState, options = {}) {
|
|
|
408
461
|
let history = [];
|
|
409
462
|
if (Array.isArray(state?.encryptedReasoningHistory)) history = state.encryptedReasoningHistory;
|
|
410
463
|
else if (Array.isArray(state?.encryptedReasoningItems)) {
|
|
411
|
-
history = [{ messageIndex: seen, items: state.encryptedReasoningItems }];
|
|
464
|
+
history = [{ messageIndex: seen, items: state.encryptedReasoningItems, owner: state.owner }];
|
|
412
465
|
}
|
|
413
466
|
for (const entry of history) {
|
|
414
467
|
const index = Number(entry?.messageIndex);
|
|
415
468
|
if (!Number.isInteger(index) || index < 0 || !Array.isArray(entry?.items)) continue;
|
|
469
|
+
// Owner-tagged reasoning (compat routes) never replays under another
|
|
470
|
+
// owner, even when a caller passes provider state across providers.
|
|
471
|
+
if (entry.owner !== undefined && entry.owner !== replayProvider) continue;
|
|
416
472
|
const bucket = reasoningByMessageIndex.get(index) || [];
|
|
417
473
|
bucket.push(...entry.items.map((item) => ({ ...item })));
|
|
418
474
|
reasoningByMessageIndex.set(index, bucket);
|
|
419
475
|
}
|
|
420
476
|
}
|
|
477
|
+
if (options.nativeLowering === true) {
|
|
478
|
+
// Native-item-capable Responses routes share the first-party lowering:
|
|
479
|
+
// native tool_search / custom calls keep their own output type, and only
|
|
480
|
+
// this route's own replay tag and reasoning state are replayed.
|
|
481
|
+
return {
|
|
482
|
+
input: convertMessagesToResponsesInput(messages, {
|
|
483
|
+
startIndex,
|
|
484
|
+
includeSystem,
|
|
485
|
+
nativePdf: options.nativePdf,
|
|
486
|
+
replayProvider,
|
|
487
|
+
// Compat-owned tool_search payloads are tagged with the route name.
|
|
488
|
+
nativeToolSearchProvider: options.providerName,
|
|
489
|
+
replayOwnedReasoning: true,
|
|
490
|
+
reasoningByMessageIndex,
|
|
491
|
+
effortProjection: options.effortProjection,
|
|
492
|
+
splitToolContent: (content) => splitToolContentForXaiResponses(content, { nativePdf: options.nativePdf }),
|
|
493
|
+
}),
|
|
494
|
+
previousResponseId,
|
|
495
|
+
startIndex,
|
|
496
|
+
continuationResetReason: resetReason,
|
|
497
|
+
};
|
|
498
|
+
}
|
|
421
499
|
const pendingToolMedia = [];
|
|
422
500
|
const flushToolMedia = () => {
|
|
423
501
|
if (!pendingToolMedia.length) return;
|
|
424
502
|
input.push({ role: 'user', content: pendingToolMedia.splice(0) });
|
|
425
503
|
};
|
|
504
|
+
// `options.effortProjection` (custom GPT-6+ routes) carries wire-ready effort updates.
|
|
505
|
+
const effortUpdates = responsesEffortUpdates(options.effortProjection);
|
|
426
506
|
for (let messageIndex = startIndex; messageIndex < messages.length; messageIndex += 1) {
|
|
427
507
|
const m = messages[messageIndex];
|
|
428
508
|
if (!includeSystem && m.role === 'system') continue;
|
|
509
|
+
const updates = effortUpdates.before(m);
|
|
429
510
|
if (m.role !== 'tool') flushToolMedia();
|
|
511
|
+
input.push(...updates);
|
|
430
512
|
const orderedReplay = m.role === 'assistant' ? providerReplayItems(m, replayProvider) : undefined;
|
|
431
513
|
if (orderedReplay?.length) {
|
|
432
514
|
input.push(...orderedReplay);
|
|
@@ -444,6 +526,7 @@ export function toXaiResponsesInput(messages, providerState, options = {}) {
|
|
|
444
526
|
flushToolMedia();
|
|
445
527
|
const trailingReasoning = reasoningByMessageIndex.get(messages.length);
|
|
446
528
|
if (trailingReasoning) input.push(...trailingReasoning);
|
|
529
|
+
input.push(...effortUpdates.end());
|
|
447
530
|
// Wire-level pairing guard: replay envelopes can carry a call whose
|
|
448
531
|
// result never committed (cancel/abort). The provider hard-rejects the
|
|
449
532
|
// unpaired call, so synthesize the missing outputs here.
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { resolveProviderApiKey } from '../../../shared/provider-api-key.mjs';
|
|
2
2
|
import { markProviderRecoveryExhausted, withRetry } from './retry-classifier.mjs';
|
|
3
|
+
import { compatRetryOptions, withCompatRetryProfile } from './openai-compat-retry-profile.mjs';
|
|
3
4
|
import { consumeCompatResponsesStream } from './openai-compat-stream.mjs';
|
|
4
5
|
import { PROVIDER_FIRST_BYTE_TIMEOUT_MS, createPassthroughSignal } from '../stall-policy.mjs';
|
|
5
6
|
import {
|
|
6
7
|
nativeResponsesTools,
|
|
8
|
+
resolveCompatMaxOutputTokens,
|
|
7
9
|
toOpenAIMessages,
|
|
8
10
|
toResponsesTools,
|
|
9
11
|
toXaiResponsesInput,
|
|
@@ -25,17 +27,34 @@ import { applyCompatToolChoice, compatStreamRetryReporter } from './compat-reque
|
|
|
25
27
|
import { envFlag as _envFlag } from '../../../shared/env.mjs';
|
|
26
28
|
import { resolveResponsesTransportPolicy, RESPONSES_TRANSPORT_CAPABILITIES } from './openai-transport-policy.mjs';
|
|
27
29
|
|
|
30
|
+
// Server-side tool search is strictly opt-in, from the provider's own config
|
|
31
|
+
// (`xaiServerToolSearch`, shared by grok-oauth's inner xai provider) or the
|
|
32
|
+
// request opts. Unset, every xAI request body is unchanged: deferred tools go
|
|
33
|
+
// out as plain function tools and the client `load_tool` stays a function.
|
|
34
|
+
// Server-executed search items replay through the owner-tagged providerReplay
|
|
35
|
+
// envelope in either mode and are never dispatched locally.
|
|
36
|
+
function xaiServerToolSearchEnabled(provider, opts) {
|
|
37
|
+
return (opts.xaiServerToolSearch ?? provider.config?.xaiServerToolSearch) === true;
|
|
38
|
+
}
|
|
39
|
+
|
|
28
40
|
// Tool list, parallel tool calls, tool choice and reasoning effort shared by
|
|
29
41
|
// the HTTP/SSE and WebSocket Responses bodies.
|
|
30
42
|
function applyXaiResponsesToolsAndEffort(params, { provider, tools, opts, useModel }) {
|
|
31
43
|
const nativeTools = nativeResponsesTools(opts);
|
|
32
44
|
if (tools?.length || nativeTools.length) {
|
|
33
|
-
|
|
45
|
+
const toolOptions = xaiServerToolSearchEnabled(provider, opts)
|
|
46
|
+
? { provider: 'xai', serverToolSearch: true, onToolExcluded: opts.onToolExcluded }
|
|
47
|
+
: { provider: 'xai', onToolExcluded: opts.onToolExcluded };
|
|
48
|
+
params.tools = [...nativeTools, ...toResponsesTools(tools || [], toolOptions)];
|
|
34
49
|
}
|
|
35
50
|
// Explicit parallel tool calls, matching the OpenAI Responses
|
|
36
51
|
// reference shape. Probe-verified accepted by api.x.ai (HTTP 200,
|
|
37
|
-
// 2026-08-16); absent, the service default decides per turn.
|
|
38
|
-
|
|
52
|
+
// 2026-08-16); absent, the service default decides per turn. An explicit
|
|
53
|
+
// caller `parallelToolCalls:false` is honored (docs.x.ai function-calling).
|
|
54
|
+
if (params.tools?.length) params.parallel_tool_calls = opts.parallelToolCalls !== false;
|
|
55
|
+
// Caller output cap (docs.x.ai text best-practices): max_output_tokens.
|
|
56
|
+
const maxOutputTokens = resolveCompatMaxOutputTokens(opts);
|
|
57
|
+
if (maxOutputTokens) params.max_output_tokens = maxOutputTokens;
|
|
39
58
|
applyCompatToolChoice(params, opts);
|
|
40
59
|
const reasoningEffort = normalizeXaiReasoningEffort(
|
|
41
60
|
opts.xaiReasoningEffort ??
|
|
@@ -91,7 +110,7 @@ export async function sendXaiResponses(provider, messages, useModel, tools, opts
|
|
|
91
110
|
let streamed;
|
|
92
111
|
try {
|
|
93
112
|
streamed = await withRetry(
|
|
94
|
-
async ({ signal: attemptSignal }) => {
|
|
113
|
+
withCompatRetryProfile(provider.name, async ({ signal: attemptSignal }) => {
|
|
95
114
|
const stream = await withRetry(
|
|
96
115
|
({ signal: openSignal }) => provider.client.responses.create(params, { signal: openSignal }),
|
|
97
116
|
{
|
|
@@ -127,11 +146,12 @@ export async function sendXaiResponses(provider, messages, useModel, tools, opts
|
|
|
127
146
|
}
|
|
128
147
|
throw error;
|
|
129
148
|
}
|
|
130
|
-
},
|
|
149
|
+
}),
|
|
131
150
|
{
|
|
132
151
|
signal: totalSignal.signal,
|
|
133
152
|
onRetry: compatStreamRetryReporter('xai:responses', opts),
|
|
134
153
|
retry529: opts.retry529,
|
|
154
|
+
...compatRetryOptions(provider.name),
|
|
135
155
|
}
|
|
136
156
|
);
|
|
137
157
|
} finally {
|
|
@@ -199,7 +219,8 @@ export async function sendXaiResponsesWebSocket(provider, messages, useModel, to
|
|
|
199
219
|
onTextDelta: typeof opts.onTextDelta === 'function' ? opts.onTextDelta : null,
|
|
200
220
|
onStageChange: typeof opts.onStageChange === 'function' ? opts.onStageChange : null,
|
|
201
221
|
externalSignal: signal,
|
|
202
|
-
|
|
222
|
+
// A forked request runs in its own transport scope (transport-scope.mjs).
|
|
223
|
+
poolKey: opts.transportScope || opts.sessionId || opts.session?.id || null,
|
|
203
224
|
cacheKey: cacheRouting.key,
|
|
204
225
|
iteration,
|
|
205
226
|
useModel,
|
|
@@ -14,7 +14,7 @@ import { appendAgentTrace } from '../agent-trace.mjs';
|
|
|
14
14
|
import { resolveProviderCacheKey, resolveProviderPromptCacheLane } from '../agent-runtime/cache-strategy.mjs';
|
|
15
15
|
import { shouldFallbackTransport } from './retry-classifier.mjs';
|
|
16
16
|
import { envFlag as _envFlag } from '../../../shared/env.mjs';
|
|
17
|
-
import { getModelsDevRowSync } from '../../../shared/llm/model-catalog.mjs';
|
|
17
|
+
import { getModelMetadataSync, getModelsDevRowSync } from '../../../shared/llm/model-catalog.mjs';
|
|
18
18
|
import {
|
|
19
19
|
traceHash,
|
|
20
20
|
stableTraceStringify,
|
|
@@ -166,26 +166,35 @@ export function normalizeXaiReasoningEffort(value) {
|
|
|
166
166
|
return ['low', 'medium', 'high', 'xhigh'].includes(effort) ? effort : null;
|
|
167
167
|
}
|
|
168
168
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
//
|
|
173
|
-
//
|
|
169
|
+
const hasEffortValues = (modelOptions) =>
|
|
170
|
+
(modelOptions || []).some((option) => option?.type === 'effort' && option.values?.length > 0);
|
|
171
|
+
|
|
172
|
+
// The first Grok generations (grok-3, grok-4, grok-4-fast, grok-code-fast)
|
|
173
|
+
// REJECT reasoning_effort outright (HTTP 400 "does not support parameter
|
|
174
|
+
// reasoningEffort"). That generation is closed: it is told apart by a bare
|
|
175
|
+
// major with no minor version, so a later release never matches.
|
|
176
|
+
const LEGACY_NO_EFFORT_GROK = /^grok[-_]?(?:[123]|4|code)(?![.\d])/;
|
|
177
|
+
|
|
178
|
+
// The parameter ships when the catalog says the model takes it. A model the
|
|
179
|
+
// catalog does not list yet is sent the caller's effort (the server decides),
|
|
180
|
+
// as is an unknown/absent model id — a custom xAI-compatible deployment that
|
|
181
|
+
// never saw the 400 must not silently lose the caller's effort choice. Only
|
|
182
|
+
// the closed legacy generation above is held back offline, because sending to
|
|
183
|
+
// it hard-fails.
|
|
174
184
|
export function xaiModelSupportsReasoningEffort(model) {
|
|
175
185
|
const id = String(model || '')
|
|
176
186
|
.trim()
|
|
177
187
|
.toLowerCase();
|
|
178
188
|
if (!id) return true;
|
|
179
189
|
if (!id.startsWith('grok')) return true;
|
|
180
|
-
// The catalog answers first
|
|
181
|
-
//
|
|
182
|
-
|
|
190
|
+
// The catalog answers first, from the live roster and the pricing catalogs:
|
|
191
|
+
// a model that publishes effort values takes the parameter.
|
|
192
|
+
if (hasEffortValues(getModelMetadataSync(id, 'xai')?.reasoningOptions)) return true;
|
|
193
|
+
// A listed model takes the parameter exactly when it publishes effort
|
|
194
|
+
// values (grok-4.3 does, grok-4.20-*-reasoning does not).
|
|
183
195
|
const listed = getModelsDevRowSync(id, 'xai');
|
|
184
|
-
if (listed)
|
|
185
|
-
|
|
186
|
-
}
|
|
187
|
-
// grok-4.5 / grok-4.6 and anything newer in that line.
|
|
188
|
-
return /grok[-_]?4\.(?:[5-9]|\d{2,})/.test(id);
|
|
196
|
+
if (listed) return hasEffortValues(listed.reasoning_options);
|
|
197
|
+
return !LEGACY_NO_EFFORT_GROK.test(id);
|
|
189
198
|
}
|
|
190
199
|
|
|
191
200
|
function opencodeGoReasoningEffortValues(modelInfo) {
|
|
@@ -226,13 +235,18 @@ export function useXaiResponsesApi(opts, config) {
|
|
|
226
235
|
}
|
|
227
236
|
|
|
228
237
|
export function useXaiResponsesWebSocket(opts, config) {
|
|
238
|
+
// A pinned route (grok-oauth's cli-chat-proxy) takes its transport from the
|
|
239
|
+
// config alone: the xAI WebSocket connector targets api.x.ai, so no request
|
|
240
|
+
// option or env override may carry the OAuth bearer there.
|
|
229
241
|
const raw =
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
242
|
+
config?.transportPinned === true
|
|
243
|
+
? config.responsesTransport
|
|
244
|
+
: (opts?.xaiResponsesTransport ??
|
|
245
|
+
opts?.xaiTransport ??
|
|
246
|
+
config?.responsesTransport ??
|
|
247
|
+
config?.transport ??
|
|
248
|
+
process.env.MIXDOG_XAI_RESPONSES_TRANSPORT ??
|
|
249
|
+
process.env.MIXDOG_XAI_TRANSPORT);
|
|
236
250
|
// Reference xAI/Grok parity is HTTP/SSE. WebSocket remains available only
|
|
237
251
|
// when a caller explicitly selects a WS transport.
|
|
238
252
|
if (raw == null || raw === '') return false;
|
|
@@ -13,7 +13,9 @@ import {
|
|
|
13
13
|
_shouldFallbackXaiWsToHttp,
|
|
14
14
|
} from './openai-compat-xai.mjs';
|
|
15
15
|
import { withEffortRejectionFallback } from './effort-rejection.mjs';
|
|
16
|
+
import { applyCompatErrorContract } from './openai-compat-error-contract.mjs';
|
|
16
17
|
import { sendCompatResponses } from './openai-compat-responses.mjs';
|
|
18
|
+
import { COMPAT_RETRY_POLICY, COMPAT_RETRY_PROFILES, XAI_COMPAT_RETRY_POLICY } from './openai-compat-retry-profile.mjs';
|
|
17
19
|
import { sendCompatChat, recoverCompatNonStreaming } from './openai-compat-chat-send.mjs';
|
|
18
20
|
import { sendXaiResponses, sendXaiResponsesWebSocket } from './openai-compat-xai-send.mjs';
|
|
19
21
|
import {
|
|
@@ -71,9 +73,14 @@ export class OpenAICompatProvider {
|
|
|
71
73
|
const baseURL = assertSafeBaseURL(config.baseURL || preset?.baseURL || 'http://localhost:8080/v1', name);
|
|
72
74
|
const apiKey = resolveProviderApiKey(name, config) || 'no-key';
|
|
73
75
|
this.name = name;
|
|
76
|
+
// A profiled provider's limits are final: no loop-level recovery cycles on top.
|
|
77
|
+
if (COMPAT_RETRY_PROFILES[name]) this.retryPolicy = name === 'xai' ? XAI_COMPAT_RETRY_POLICY : COMPAT_RETRY_POLICY;
|
|
74
78
|
this.config = config;
|
|
75
79
|
this.baseURL = baseURL;
|
|
76
80
|
this.apiKey = apiKey;
|
|
81
|
+
// Whether Chat content blocks keep their Anthropic-style `cache_control`
|
|
82
|
+
// (OpenRouter documents it); a gateway that does not ignores or rejects it.
|
|
83
|
+
this.chatCacheControl = (config.chatCacheControl ?? preset?.chatCacheControl) === true;
|
|
77
84
|
// Merge caller-supplied headers (config.extraHeaders) over the preset's.
|
|
78
85
|
// Used e.g. by grok-oauth to inject the Grok CLI client headers for the
|
|
79
86
|
// grok-build proxy. Backward-compatible: providers that pass no
|
|
@@ -168,9 +175,19 @@ export class OpenAICompatProvider {
|
|
|
168
175
|
}
|
|
169
176
|
async _doSend(messages, model, tools, sendOpts) {
|
|
170
177
|
const useModel = model || this.defaultModel;
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
178
|
+
try {
|
|
179
|
+
return await withEffortRejectionFallback(
|
|
180
|
+
this.name,
|
|
181
|
+
useModel,
|
|
182
|
+
sendOpts || {},
|
|
183
|
+
this.config?.reasoningEffort,
|
|
184
|
+
(opts) => this._sendWithOpts(messages, useModel, tools, opts)
|
|
185
|
+
);
|
|
186
|
+
} catch (err) {
|
|
187
|
+
// Every provider built on this transport (custom, grok, muse, mimo,
|
|
188
|
+
// command-code, local) leaves through here with the boundary contract.
|
|
189
|
+
throw applyCompatErrorContract(err);
|
|
190
|
+
}
|
|
174
191
|
}
|
|
175
192
|
async _sendWithOpts(messages, useModel, tools, opts) {
|
|
176
193
|
// Re-warm a kept-alive socket to the provider origin before the turn so
|
|
@@ -242,7 +259,9 @@ export class OpenAICompatProvider {
|
|
|
242
259
|
return fetchCompatModelItems(this);
|
|
243
260
|
}
|
|
244
261
|
async listModels() {
|
|
245
|
-
|
|
262
|
+
// A failed /models request must surface; an empty list would be cached as
|
|
263
|
+
// a complete catalog by the shared catalog loader.
|
|
264
|
+
return listCompatModels(this, { throwOnError: true });
|
|
246
265
|
}
|
|
247
266
|
async isAvailable() {
|
|
248
267
|
return isCompatProviderAvailable(this);
|