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
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// OpenAI retry schedule: 200ms base, factor 2, ±10%.
|
|
2
|
+
// Provider-owned values; the shared retry core only takes them as options.
|
|
3
|
+
// CODEX_STREAM_BACKOFF_MS — indexed by the 1-based retry number
|
|
4
|
+
// (midstreamBackoffFor).
|
|
5
|
+
// CODEX_REQUEST_RETRY_BACKOFF_MS — leading duplicate for withRetry's
|
|
6
|
+
// sleep-before-attempt index.
|
|
7
|
+
export const CODEX_STREAM_BACKOFF_MS = Object.freeze([200, 400, 800, 1600, 3200]);
|
|
8
|
+
export const CODEX_REQUEST_RETRY_BACKOFF_MS = Object.freeze([200, ...CODEX_STREAM_BACKOFF_MS]);
|
|
9
|
+
export const CODEX_RETRY_JITTER_RATIO = 0.1;
|
|
@@ -279,7 +279,7 @@ function _stripResponseItemsFromHead(items, responseItems) {
|
|
|
279
279
|
// Official OpenAI Responses WebSocket guide: response.create WS frames mirror
|
|
280
280
|
// the Responses body EXCEPT the transport-only fields `stream`/`background`,
|
|
281
281
|
// which the socket carries implicitly and the guide says to omit. This set is
|
|
282
|
-
// stripped from a frame (any build shape)
|
|
282
|
+
// always stripped from a frame (any build shape).
|
|
283
283
|
const TRANSPORT_ONLY_FRAME_FIELDS = new Set(['stream', 'background']);
|
|
284
284
|
|
|
285
285
|
// Canonical response.create frame builder. Every WS send (main full-frame
|
|
@@ -293,14 +293,12 @@ const TRANSPORT_ONLY_FRAME_FIELDS = new Set(['stream', 'background']);
|
|
|
293
293
|
// response, so dropping them here strips the system/lead prompt from every
|
|
294
294
|
// continuation turn. Only an empty instructions string is omitted.
|
|
295
295
|
// Full frames pass the body unchanged and keep every key in place.
|
|
296
|
-
// omitTransportFields is used by wire-parity helpers to drop stream/background.
|
|
297
296
|
export function _buildResponseCreateFrame(
|
|
298
297
|
body,
|
|
299
|
-
{ previousResponseId = null, inputOverride
|
|
298
|
+
{ previousResponseId = null, inputOverride } = {}
|
|
300
299
|
) {
|
|
301
300
|
const src = body && typeof body === 'object' ? body : {};
|
|
302
301
|
if (previousResponseId == null && inputOverride === undefined) {
|
|
303
|
-
if (!omitTransportFields) return { type: 'response.create', ...src };
|
|
304
302
|
const frame = { type: 'response.create' };
|
|
305
303
|
for (const key of Object.keys(src)) {
|
|
306
304
|
if (TRANSPORT_ONLY_FRAME_FIELDS.has(key)) continue;
|
|
@@ -310,7 +308,7 @@ export function _buildResponseCreateFrame(
|
|
|
310
308
|
}
|
|
311
309
|
const frame = { type: 'response.create' };
|
|
312
310
|
for (const key of Object.keys(src)) {
|
|
313
|
-
if (
|
|
311
|
+
if (TRANSPORT_ONLY_FRAME_FIELDS.has(key)) continue;
|
|
314
312
|
if (key === 'instructions') {
|
|
315
313
|
const instr = src.instructions;
|
|
316
314
|
if (typeof instr === 'string' && instr.length) frame.instructions = instr;
|
|
@@ -366,17 +364,10 @@ export function _computeDelta({ entry, body, traceProvider }) {
|
|
|
366
364
|
if (!entry?.lastRequestSansInput || !entry.lastResponseId) {
|
|
367
365
|
return { mode: 'full', reason: 'no_anchor', frame: buildFrame(body) };
|
|
368
366
|
}
|
|
369
|
-
//
|
|
370
|
-
//
|
|
371
|
-
//
|
|
372
|
-
//
|
|
373
|
-
// previous_response_not_found, so the opt-out degrades to full frames.
|
|
374
|
-
// openai-oauth/Codex (per-WS-session server state) and xAI (in-connection
|
|
375
|
-
// ZDR continuation with encrypted reasoning) both anchor without the store
|
|
376
|
-
// and are deliberately excluded from this gate.
|
|
377
|
-
if (traceProvider === 'openai-direct' && body?.store !== true) {
|
|
378
|
-
return { mode: 'full', reason: 'store_disabled', frame: buildFrame(body) };
|
|
379
|
-
}
|
|
367
|
+
// WebSocket mode keeps the latest response in a connection-local cache, so
|
|
368
|
+
// previous_response_id continues on the same socket even with store:false.
|
|
369
|
+
// If the server no longer has the anchor (previous_response_not_found), the
|
|
370
|
+
// caller recovers with a full-context frame.
|
|
380
371
|
if (!deltaForce && !deltaRefs && !entry.turnState) {
|
|
381
372
|
return { mode: 'full', reason: 'delta_missing_turn_state', frame: buildFrame(body) };
|
|
382
373
|
}
|
|
@@ -9,6 +9,11 @@
|
|
|
9
9
|
import { appendFileSync, chmodSync } from 'node:fs';
|
|
10
10
|
import { errText } from '../../../shared/err-text.mjs';
|
|
11
11
|
import { _cfCookieCapture, _formatRedactedHeaders } from './openai-ws-headers.mjs';
|
|
12
|
+
import { httpResponseError } from './openai-error-contract.mjs';
|
|
13
|
+
|
|
14
|
+
// Enough of the handshake body to parse a typed JSON error; diagnostics are
|
|
15
|
+
// truncated separately by the error message.
|
|
16
|
+
const HANDSHAKE_BODY_LIMIT = 16 * 1024;
|
|
12
17
|
|
|
13
18
|
/** CF cookie jar refresh plus the opt-in upgrade-header dump. */
|
|
14
19
|
export function captureHandshakeUpgrade(auth, res) {
|
|
@@ -85,7 +90,7 @@ export function attachHandshakeFailureHandlers({ socket, errLabel, openStart, is
|
|
|
85
90
|
const status = res?.statusCode || 0;
|
|
86
91
|
let body = '';
|
|
87
92
|
res.on('data', (c) => {
|
|
88
|
-
if (body.length <
|
|
93
|
+
if (body.length < HANDSHAKE_BODY_LIMIT) body += c.toString('utf-8');
|
|
89
94
|
});
|
|
90
95
|
res.on('end', () => {
|
|
91
96
|
if (process.env.MIXDOG_DEBUG_AGENT) {
|
|
@@ -96,13 +101,16 @@ export function attachHandshakeFailureHandlers({ socket, errLabel, openStart, is
|
|
|
96
101
|
try {
|
|
97
102
|
socket.terminate();
|
|
98
103
|
} catch {}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
104
|
+
// Status, headers and the parsed body ride on the error; only the
|
|
105
|
+
// message is truncated.
|
|
106
|
+
const err = httpResponseError({
|
|
107
|
+
label: `${errLabel} handshake`,
|
|
108
|
+
status,
|
|
109
|
+
headers: res.headers,
|
|
110
|
+
text: body,
|
|
111
|
+
});
|
|
112
|
+
err.httpBody = body;
|
|
113
|
+
settle(false, err);
|
|
106
114
|
});
|
|
107
115
|
});
|
|
108
116
|
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
// Refusal content of one Responses stream. The model's refusal arrives as
|
|
2
|
+
// `response.refusal.delta` / `response.refusal.done` and as a
|
|
3
|
+
// `{type:'refusal', refusal}` content part of the message item
|
|
4
|
+
// (output_item.done and the terminal output bundle). Parts are keyed by item
|
|
5
|
+
// id + content index so the streamed, item-done and terminal copies of one
|
|
6
|
+
// part fold into one text; a full (done / final-part) text replaces the
|
|
7
|
+
// accumulated deltas. Shared by the WS and HTTP/SSE collectors.
|
|
8
|
+
export function createRefusals() {
|
|
9
|
+
const parts = new Map();
|
|
10
|
+
const keyOf = (itemId, contentIndex) => `${itemId || ''}:${Number.isInteger(contentIndex) ? contentIndex : 0}`;
|
|
11
|
+
|
|
12
|
+
return {
|
|
13
|
+
/** response.refusal.delta */
|
|
14
|
+
delta(event) {
|
|
15
|
+
if (typeof event?.delta !== 'string') return;
|
|
16
|
+
const key = keyOf(event.item_id, event.content_index);
|
|
17
|
+
parts.set(key, (parts.get(key) || '') + event.delta);
|
|
18
|
+
},
|
|
19
|
+
/** response.refusal.done */
|
|
20
|
+
done(event) {
|
|
21
|
+
if (typeof event?.refusal !== 'string') return;
|
|
22
|
+
parts.set(keyOf(event.item_id, event.content_index), event.refusal);
|
|
23
|
+
},
|
|
24
|
+
/** A message item's refusal parts. Returns whether it carried any. */
|
|
25
|
+
absorbMessage(item) {
|
|
26
|
+
if (item?.type !== 'message' || !Array.isArray(item.content)) return false;
|
|
27
|
+
let found = false;
|
|
28
|
+
item.content.forEach((part, index) => {
|
|
29
|
+
if (part?.type !== 'refusal' || typeof part.refusal !== 'string') return;
|
|
30
|
+
found = true;
|
|
31
|
+
// An id-less item cannot be matched to its streamed copy; the
|
|
32
|
+
// streamed text already stands for it.
|
|
33
|
+
if (!item.id && parts.size > 0) return;
|
|
34
|
+
parts.set(keyOf(item.id, index), part.refusal);
|
|
35
|
+
});
|
|
36
|
+
return found;
|
|
37
|
+
},
|
|
38
|
+
get seen() {
|
|
39
|
+
return parts.size > 0;
|
|
40
|
+
},
|
|
41
|
+
get text() {
|
|
42
|
+
return [...parts.values()].filter(Boolean).join('\n');
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** The typed stop reason of a refused turn (read by the agent loop). */
|
|
48
|
+
export const REFUSAL_STOP_REASON = 'refusal';
|
|
49
|
+
|
|
50
|
+
/** Result fields for a refused turn — the shared result shape:
|
|
51
|
+
* stopReason: REFUSAL_STOP_REASON
|
|
52
|
+
* refusal: the refusal text (joined parts; may be '')
|
|
53
|
+
* content: the output_text, or the refusal text when there was none
|
|
54
|
+
* so a refusal never reads as an empty successful answer. Empty object when
|
|
55
|
+
* the response carried no refusal. */
|
|
56
|
+
export function refusalResultFields(refusals, content) {
|
|
57
|
+
if (!refusals.seen) return {};
|
|
58
|
+
const refusal = refusals.text;
|
|
59
|
+
return { content: content || refusal, refusal, stopReason: REFUSAL_STOP_REASON };
|
|
60
|
+
}
|
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
import { makeInvalidToolArgsMarker } from '../lib/openai-tool-args.mjs';
|
|
2
2
|
import { synthLeakedOpenAICall } from '../openai-compat-stream-common.mjs';
|
|
3
3
|
import { createToolCallDedupe, dedupeToolCallList } from '../lib/leaked-toolcall.mjs';
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
customToolCallFromResponseItem,
|
|
6
|
+
nativeToolSearchCallFromArguments,
|
|
7
|
+
qualifiedToolCallName,
|
|
8
|
+
withToolCallNamespace,
|
|
9
|
+
} from '../custom-tool-wire.mjs';
|
|
5
10
|
import { createActiveToolItemTracker } from '../tool-stream-state.mjs';
|
|
6
11
|
|
|
7
12
|
// tool_search_call.arguments parse. Module-scope (exported) for direct test
|
|
@@ -64,7 +69,7 @@ export function createWsToolCalls({ onToolCall, midState, replayItems }) {
|
|
|
64
69
|
} catch {}
|
|
65
70
|
}
|
|
66
71
|
function emit(call) {
|
|
67
|
-
if (!toolDedupe.shouldDispatch(call
|
|
72
|
+
if (!toolDedupe.shouldDispatch(qualifiedToolCallName(call), call?.arguments, call?.id)) return;
|
|
68
73
|
fire(call);
|
|
69
74
|
}
|
|
70
75
|
function settle() {
|
|
@@ -84,6 +89,8 @@ export function createWsToolCalls({ onToolCall, midState, replayItems }) {
|
|
|
84
89
|
}
|
|
85
90
|
function pushToolSearchCall(item) {
|
|
86
91
|
if (item?.type !== 'tool_search_call') return;
|
|
92
|
+
// Server-executed search already ran inside the response; replay-only.
|
|
93
|
+
if (item.execution === 'server') return;
|
|
87
94
|
const callId = item.call_id || item.id || '';
|
|
88
95
|
if (!callId || toolCalls.some((call) => call.id === callId)) return;
|
|
89
96
|
const call = nativeToolSearchCallFromArguments(callId, parseToolSearchArgs(item.arguments));
|
|
@@ -106,7 +113,10 @@ export function createWsToolCalls({ onToolCall, midState, replayItems }) {
|
|
|
106
113
|
const type = item?.type;
|
|
107
114
|
if (type === 'function_call') {
|
|
108
115
|
markStarted(item);
|
|
109
|
-
pendingCalls.set(
|
|
116
|
+
pendingCalls.set(
|
|
117
|
+
item.id || '',
|
|
118
|
+
withToolCallNamespace({ name: item.name || '', callId: item.call_id || '' }, item)
|
|
119
|
+
);
|
|
110
120
|
} else if (type === 'custom_tool_call' || type === 'tool_search_call') {
|
|
111
121
|
// tool_search is marked in-flight at item-added time too, so the
|
|
112
122
|
// semantic-idle stall gate's pendingToolUse never drops a mid-flight
|
|
@@ -134,7 +144,7 @@ export function createWsToolCalls({ onToolCall, midState, replayItems }) {
|
|
|
134
144
|
argumentsText: event.arguments || JSON.stringify(args),
|
|
135
145
|
});
|
|
136
146
|
if (pending?.callId && pending?.name) {
|
|
137
|
-
const call = { id: pending.callId, name: pending.name, arguments: args };
|
|
147
|
+
const call = withToolCallNamespace({ id: pending.callId, name: pending.name, arguments: args }, pending);
|
|
138
148
|
toolCalls.push(call);
|
|
139
149
|
emit(call);
|
|
140
150
|
pendingCalls.delete(itemId);
|
|
@@ -150,31 +160,45 @@ export function createWsToolCalls({ onToolCall, midState, replayItems }) {
|
|
|
150
160
|
// bundle. If salvage also fails the stream fails explicitly — masking the
|
|
151
161
|
// gap with a synthetic id just shifts the failure one turn later under a
|
|
152
162
|
// confusing "No tool output found for function call" error.
|
|
153
|
-
toolCalls.push(
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
163
|
+
toolCalls.push(
|
|
164
|
+
withToolCallNamespace(
|
|
165
|
+
{
|
|
166
|
+
id: pending?.callId || '',
|
|
167
|
+
name: pending?.name || '',
|
|
168
|
+
arguments: args,
|
|
169
|
+
_pendingItemId: itemId,
|
|
170
|
+
_deferred: true,
|
|
171
|
+
},
|
|
172
|
+
pending
|
|
173
|
+
)
|
|
174
|
+
);
|
|
160
175
|
}
|
|
161
176
|
|
|
162
|
-
/**
|
|
177
|
+
/** A complete function_call item (output_item.done, or the terminal
|
|
178
|
+
* response output bundle) through the one deduplicated collector: it
|
|
179
|
+
* resolves the deferred placeholder for its item (canonical call_id/name
|
|
180
|
+
* from the item, missing ones kept from the placeholder), is skipped when
|
|
181
|
+
* its call_id is already recorded, and is otherwise created and
|
|
182
|
+
* dispatched — so a call present only in the terminal bundle still runs. */
|
|
163
183
|
function completeFunctionCallItem(item) {
|
|
164
184
|
const itemId = item.id || '';
|
|
165
185
|
const callId = item.call_id || '';
|
|
166
186
|
const name = item.name || '';
|
|
167
187
|
const args = parseFunctionCallArgs(argsTextOf(item.arguments));
|
|
168
188
|
const deferred = toolCalls.find((tc) => tc?._deferred && (!itemId || tc._pendingItemId === itemId));
|
|
169
|
-
if (deferred
|
|
170
|
-
deferred.id = callId;
|
|
171
|
-
deferred.name = name;
|
|
172
|
-
deferred
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
189
|
+
if (deferred) {
|
|
190
|
+
deferred.id = callId || deferred.id;
|
|
191
|
+
deferred.name = name || deferred.name;
|
|
192
|
+
withToolCallNamespace(deferred, item);
|
|
193
|
+
if (deferred.id && deferred.name) {
|
|
194
|
+
deferred.arguments =
|
|
195
|
+
deferred.arguments && Object.keys(deferred.arguments).length > 0 ? deferred.arguments : args;
|
|
196
|
+
delete deferred._deferred;
|
|
197
|
+
delete deferred._pendingItemId;
|
|
198
|
+
emit(deferred);
|
|
199
|
+
}
|
|
176
200
|
} else if (callId && name && !toolCalls.some((tc) => tc?.id === callId)) {
|
|
177
|
-
const call = { id: callId, name, arguments: args };
|
|
201
|
+
const call = withToolCallNamespace({ id: callId, name, arguments: args }, item);
|
|
178
202
|
toolCalls.push(call);
|
|
179
203
|
emit(call);
|
|
180
204
|
}
|
|
@@ -193,20 +217,6 @@ export function createWsToolCalls({ onToolCall, midState, replayItems }) {
|
|
|
193
217
|
settle();
|
|
194
218
|
}
|
|
195
219
|
|
|
196
|
-
/** response.completed salvage: when arguments.done fired before (or
|
|
197
|
-
* without) a matching output_item.added, the deferred placeholder has an
|
|
198
|
-
* empty id/name; the bundle carries the canonical call_id/name. */
|
|
199
|
-
function salvageFunctionCall(item) {
|
|
200
|
-
const tc = toolCalls.find((t) => t._deferred && t._pendingItemId === (item.id || ''));
|
|
201
|
-
if (!tc) return;
|
|
202
|
-
if (!tc.id && item.call_id) tc.id = item.call_id;
|
|
203
|
-
if (!tc.name && item.name) tc.name = item.name;
|
|
204
|
-
if (tc.id && tc.name) {
|
|
205
|
-
delete tc._deferred;
|
|
206
|
-
delete tc._pendingItemId;
|
|
207
|
-
emit(tc);
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
220
|
|
|
211
221
|
return {
|
|
212
222
|
get calls() {
|
|
@@ -238,6 +248,12 @@ export function createWsToolCalls({ onToolCall, midState, replayItems }) {
|
|
|
238
248
|
completeFunctionCallItem,
|
|
239
249
|
completeToolSearchItem,
|
|
240
250
|
completeCustomToolItem,
|
|
241
|
-
|
|
251
|
+
/** A server-truncated call item: kept in flight, never collected. */
|
|
252
|
+
holdIncompleteItem: markStarted,
|
|
253
|
+
// Terminal-bundle salvage (response.completed / success response.done):
|
|
254
|
+
// the same collector as output_item.done. When arguments.done fired
|
|
255
|
+
// before (or without) output_item.added, the deferred placeholder has an
|
|
256
|
+
// empty id/name and the bundle carries the canonical call_id/name.
|
|
257
|
+
salvageFunctionCall: completeFunctionCallItem,
|
|
242
258
|
};
|
|
243
259
|
}
|
|
@@ -13,6 +13,8 @@ import { createReplayItems } from './openai-ws-response-state/replay-items.mjs';
|
|
|
13
13
|
import { createCitations } from './openai-ws-response-state/citations.mjs';
|
|
14
14
|
import { createWsToolCalls } from './openai-ws-response-state/tool-calls.mjs';
|
|
15
15
|
import { normalizeWsUsage } from './openai-ws-response-state/usage.mjs';
|
|
16
|
+
import { createRefusals, refusalResultFields } from './openai-ws-response-state/refusals.mjs';
|
|
17
|
+
import { isIncompleteToolItem } from './lib/responses-terminal-fields.mjs';
|
|
16
18
|
|
|
17
19
|
export { parseToolSearchArgs } from './openai-ws-response-state/tool-calls.mjs';
|
|
18
20
|
|
|
@@ -37,6 +39,7 @@ export function createWsResponseState({ onToolCall, onStreamDelta, midState, tra
|
|
|
37
39
|
const reasoningDeltas = { text: 0, summary: 0, other: 0 };
|
|
38
40
|
const replayItems = createReplayItems();
|
|
39
41
|
const citations = createCitations();
|
|
42
|
+
const refusals = createRefusals();
|
|
40
43
|
const tools = createWsToolCalls({ onToolCall, midState, replayItems });
|
|
41
44
|
const replayProvider = traceProvider === 'xai' ? 'xai-responses' : 'openai-responses';
|
|
42
45
|
const progress = (kind) => {
|
|
@@ -49,6 +52,11 @@ export function createWsResponseState({ onToolCall, onStreamDelta, midState, tra
|
|
|
49
52
|
// anything the per-item events never carried. Returns whether any progress
|
|
50
53
|
// was reported.
|
|
51
54
|
function salvageCompletedItem(item, relayFinalText) {
|
|
55
|
+
if (isIncompleteToolItem(item)) {
|
|
56
|
+
tools.holdIncompleteItem(item);
|
|
57
|
+
progress('tool');
|
|
58
|
+
return true;
|
|
59
|
+
}
|
|
52
60
|
replayItems.push(item);
|
|
53
61
|
let reported = false;
|
|
54
62
|
if (item.type === 'message') {
|
|
@@ -64,6 +72,10 @@ export function createWsResponseState({ onToolCall, onStreamDelta, midState, tra
|
|
|
64
72
|
}
|
|
65
73
|
citations.pushOutputTextAnnotations(c);
|
|
66
74
|
}
|
|
75
|
+
if (refusals.absorbMessage(item)) {
|
|
76
|
+
progress('semantic');
|
|
77
|
+
reported = true;
|
|
78
|
+
}
|
|
67
79
|
}
|
|
68
80
|
if (item.type === 'web_search_call') {
|
|
69
81
|
citations.pushWebSearchCall(item);
|
|
@@ -146,10 +158,19 @@ export function createWsResponseState({ onToolCall, onStreamDelta, midState, tra
|
|
|
146
158
|
noteToolInputDelta: tools.noteToolInputDelta,
|
|
147
159
|
/** response.function_call_arguments.done */
|
|
148
160
|
completeFunctionCallArguments: tools.completeFunctionCallArguments,
|
|
161
|
+
/** response.refusal.delta */
|
|
162
|
+
noteRefusalDelta: refusals.delta,
|
|
163
|
+
/** response.refusal.done */
|
|
164
|
+
noteRefusalDone: refusals.done,
|
|
149
165
|
/** response.output_item.done. Returns the progress kind to report. */
|
|
150
166
|
completeOutputItem(item) {
|
|
167
|
+
if (isIncompleteToolItem(item)) {
|
|
168
|
+
tools.holdIncompleteItem(item);
|
|
169
|
+
return 'tool';
|
|
170
|
+
}
|
|
151
171
|
replayItems.push(item);
|
|
152
172
|
const type = item?.type || '';
|
|
173
|
+
if (type === 'message') refusals.absorbMessage(item);
|
|
153
174
|
// function_call / output_text already arrive via their dedicated
|
|
154
175
|
// streaming events; `reasoning` carries encrypted_content that keeps the
|
|
155
176
|
// openai-oauth server-side prompt cache prefix warm.
|
|
@@ -189,6 +210,13 @@ export function createWsResponseState({ onToolCall, onStreamDelta, midState, tra
|
|
|
189
210
|
if (!responseId && response?.id) responseId = response.id;
|
|
190
211
|
return usage;
|
|
191
212
|
},
|
|
213
|
+
/** A cutoff frame's output bundle: call items the server truncated stay
|
|
214
|
+
* in flight so the cutoff reads as a pending-tool turn. */
|
|
215
|
+
holdIncompleteBundleItems(response) {
|
|
216
|
+
for (const item of response?.output || []) {
|
|
217
|
+
if (isIncompleteToolItem(item)) tools.holdIncompleteItem(item);
|
|
218
|
+
}
|
|
219
|
+
},
|
|
192
220
|
/** max_output_tokens maps cleanly to Anthropic's stop_reason=max_tokens. */
|
|
193
221
|
markMaxOutputIncomplete(reason) {
|
|
194
222
|
incompleteReason = reason;
|
|
@@ -227,6 +255,8 @@ export function createWsResponseState({ onToolCall, onStreamDelta, midState, tra
|
|
|
227
255
|
...(typeof endTurn === 'boolean' ? { endTurn } : {}),
|
|
228
256
|
responseId: responseId || undefined,
|
|
229
257
|
serviceTier: responseServiceTier || undefined,
|
|
258
|
+
// A refused turn: typed stop reason and the refusal text.
|
|
259
|
+
...refusalResultFields(refusals, content),
|
|
230
260
|
};
|
|
231
261
|
},
|
|
232
262
|
};
|
package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/attempt-context.mjs
CHANGED
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
* WS send, plus the surface/backoff primitives both failure resolvers use.
|
|
4
4
|
*/
|
|
5
5
|
import { performance } from 'node:perf_hooks';
|
|
6
|
-
import { retryAfterMsFromError } from '../retry-classifier.mjs';
|
|
7
6
|
import { _sleepWithAbort, MIDSTREAM_WS_TRANSIENT_RETRY_LIMIT, midstreamBackoffFor, tag } from './policy.mjs';
|
|
8
7
|
|
|
9
8
|
export function createAttemptContext(deps) {
|
|
@@ -35,7 +34,7 @@ export function createAttemptContext(deps) {
|
|
|
35
34
|
const backoff = async (retryNumber, err = null) => {
|
|
36
35
|
const sleepStart = performance.now();
|
|
37
36
|
try {
|
|
38
|
-
await _sleepWithAbort(
|
|
37
|
+
await _sleepWithAbort(midstreamBackoffFor(retryNumber, err), externalSignal, sleepFn);
|
|
39
38
|
} catch (sleepErr) {
|
|
40
39
|
sendSpan.retryBackoffMs += performance.now() - sleepStart;
|
|
41
40
|
sendSpan.emit('error');
|
|
@@ -2,12 +2,13 @@
|
|
|
2
2
|
* policy.mjs — the WS send retry budget, its backoff curves and the
|
|
3
3
|
* classification wrappers shared by the handshake and stream resolvers.
|
|
4
4
|
*/
|
|
5
|
+
import { CODEX_RETRY_JITTER_RATIO, CODEX_STREAM_BACKOFF_MS } from '../openai-retry-policy.mjs';
|
|
5
6
|
import {
|
|
6
7
|
classifyHandshakeError,
|
|
7
8
|
classifyMidstreamError,
|
|
8
9
|
isWsMessageTooBigClose,
|
|
9
|
-
jitterDelayMs,
|
|
10
10
|
MIDSTREAM_RETRY_POLICY,
|
|
11
|
+
midstreamBackoffFor as sharedMidstreamBackoffFor,
|
|
11
12
|
sleepWithAbort,
|
|
12
13
|
} from '../retry-classifier.mjs';
|
|
13
14
|
|
|
@@ -15,23 +16,26 @@ import {
|
|
|
15
16
|
// by connect/handshake and pre-output stream failures.
|
|
16
17
|
export const MIDSTREAM_WS_TRANSIENT_RETRY_LIMIT = MIDSTREAM_RETRY_POLICY.ws.transientCloseRetries;
|
|
17
18
|
const MIDSTREAM_DEFAULT_RETRY_LIMIT = MIDSTREAM_RETRY_POLICY.ws.defaultRetries;
|
|
18
|
-
// The
|
|
19
|
-
//
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
// The stream retry schedule (200ms base, factor 2, ±10%) lives in
|
|
20
|
+
// openai-retry-policy.mjs, shared with the HTTP request loop.
|
|
21
|
+
// Advice-gated retry (OAuth and API-key WS alike): an overload and an untyped 429
|
|
22
|
+
// retry only when the server gave advice.
|
|
23
|
+
const ADVICE_GATES = Object.freeze({
|
|
24
|
+
overloadRetryRequiresAdvice: true,
|
|
25
|
+
generic429RetryRequiresAdvice: true,
|
|
26
|
+
});
|
|
22
27
|
// Policy object passed to the shared classifyMidstreamError for the WS path.
|
|
23
28
|
const WS_MIDSTREAM_POLICY = {
|
|
24
29
|
mode: 'ws',
|
|
25
30
|
transientCloseRetries: MIDSTREAM_RETRY_POLICY.ws.transientCloseRetries,
|
|
26
31
|
defaultRetries: MIDSTREAM_RETRY_POLICY.ws.defaultRetries,
|
|
32
|
+
...ADVICE_GATES,
|
|
27
33
|
};
|
|
28
34
|
|
|
29
35
|
// Kept for the _acquireWithRetry test seam and non-Codex callers.
|
|
30
36
|
// sendViaWebSocket deliberately invokes it with maxAttempts:1 so handshake
|
|
31
37
|
// failures consume the same stream budget as pre-output disconnects.
|
|
32
38
|
export const HANDSHAKE_MAX_ATTEMPTS = MIDSTREAM_WS_TRANSIENT_RETRY_LIMIT + 1;
|
|
33
|
-
const HANDSHAKE_BACKOFF_BASE_MS = 200;
|
|
34
|
-
const HANDSHAKE_BACKOFF_CAP_MS = 3200;
|
|
35
39
|
// These statuses are decisions made by the CURRENT attempt. They must never
|
|
36
40
|
// be replaced by a stale transient from an earlier retry: auth recovery,
|
|
37
41
|
// transport fallback, and Retry-After handling all depend on the live error.
|
|
@@ -47,8 +51,15 @@ export function _mustSurfaceCurrentAttempt(err, externalSignal) {
|
|
|
47
51
|
);
|
|
48
52
|
}
|
|
49
53
|
|
|
50
|
-
export function _classifyHandshakeError(
|
|
51
|
-
|
|
54
|
+
export function _classifyHandshakeError(
|
|
55
|
+
err,
|
|
56
|
+
{
|
|
57
|
+
retry429 = true,
|
|
58
|
+
overloadRetryRequiresAdvice = ADVICE_GATES.overloadRetryRequiresAdvice,
|
|
59
|
+
generic429RetryRequiresAdvice = ADVICE_GATES.generic429RetryRequiresAdvice,
|
|
60
|
+
} = {}
|
|
61
|
+
) {
|
|
62
|
+
return classifyHandshakeError(err, { retry429, overloadRetryRequiresAdvice, generic429RetryRequiresAdvice });
|
|
52
63
|
}
|
|
53
64
|
|
|
54
65
|
/**
|
|
@@ -103,15 +114,15 @@ export function midstreamRetryLimit(classifier) {
|
|
|
103
114
|
: MIDSTREAM_DEFAULT_RETRY_LIMIT;
|
|
104
115
|
}
|
|
105
116
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
117
|
+
// Passing the failure makes server advice replace the step for retryable
|
|
118
|
+
// kinds only (midstreamRetryDelayMs).
|
|
119
|
+
export function midstreamBackoffFor(retryNumber, err = null) {
|
|
120
|
+
return sharedMidstreamBackoffFor(retryNumber, CODEX_STREAM_BACKOFF_MS, err, CODEX_RETRY_JITTER_RATIO);
|
|
109
121
|
}
|
|
110
122
|
|
|
111
123
|
export function _backoffFor(attempt) {
|
|
112
124
|
// attempt is 1-based; exponential backoff is capped before jitter.
|
|
113
|
-
|
|
114
|
-
return jitterDelayMs(Math.min(raw, HANDSHAKE_BACKOFF_CAP_MS), CODEX_RETRY_JITTER_RATIO);
|
|
125
|
+
return midstreamBackoffFor(attempt);
|
|
115
126
|
}
|
|
116
127
|
|
|
117
128
|
export const _defaultSleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
@@ -88,6 +88,18 @@ export function createWsEventSwitch({ response, textRelay, watchdogs, midState,
|
|
|
88
88
|
progress('tool');
|
|
89
89
|
watchdogs.bumpSemantic();
|
|
90
90
|
break;
|
|
91
|
+
// Refusal text is model output but never visible answer text: it is
|
|
92
|
+
// collected for the typed refusal result, not relayed live.
|
|
93
|
+
case 'response.refusal.delta':
|
|
94
|
+
response.noteRefusalDelta(event);
|
|
95
|
+
progress('semantic');
|
|
96
|
+
watchdogs.bumpSemantic();
|
|
97
|
+
break;
|
|
98
|
+
case 'response.refusal.done':
|
|
99
|
+
response.noteRefusalDone(event);
|
|
100
|
+
progress('semantic');
|
|
101
|
+
watchdogs.bumpSemantic();
|
|
102
|
+
break;
|
|
91
103
|
case 'response.output_item.done': {
|
|
92
104
|
const kind = response.completeOutputItem(event.item);
|
|
93
105
|
// Item-done is genuine lifecycle progress — reset semantic idle so
|
|
@@ -27,11 +27,30 @@ export function createTerminalFrameHandlers({ response, textRelay, midState, err
|
|
|
27
27
|
|
|
28
28
|
// Most incomplete reasons are real failures. max_output_tokens maps cleanly
|
|
29
29
|
// to Anthropic's stop_reason=max_tokens; treating it as an error makes
|
|
30
|
-
// Claude retry the same over-budget turn
|
|
30
|
+
// Claude retry the same over-budget turn — unless a tool call's input was
|
|
31
|
+
// still streaming: its arguments were truncated, so the cutoff is a
|
|
32
|
+
// stalled pending-tool turn (same guard as HTTP/SSE), never a clean length
|
|
33
|
+
// completion that would surface the partial call as successful.
|
|
31
34
|
function settleIncomplete(event, label, options) {
|
|
32
35
|
const usage = response.noteTerminal(event.response);
|
|
33
36
|
const reasonStr = _incompleteReasonFromEvent(event);
|
|
34
37
|
if (_isMaxOutputIncompleteReason(reasonStr)) {
|
|
38
|
+
response.holdIncompleteBundleItems(event.response);
|
|
39
|
+
if (response.pendingToolUse) {
|
|
40
|
+
const error = new Error(`${label} (max_output_tokens) with tool call in flight`);
|
|
41
|
+
try {
|
|
42
|
+
textRelay.flush();
|
|
43
|
+
} catch {
|
|
44
|
+
/* best-effort */
|
|
45
|
+
}
|
|
46
|
+
Object.assign(error, response.partialState());
|
|
47
|
+
error.streamStalled = true;
|
|
48
|
+
error.pendingToolUse = true;
|
|
49
|
+
error.incompleteReason = reasonStr;
|
|
50
|
+
if (usage) error.partialUsage = usage;
|
|
51
|
+
failWith(error, options);
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
35
54
|
response.markMaxOutputIncomplete(reasonStr);
|
|
36
55
|
completeTurn();
|
|
37
56
|
return;
|
|
@@ -105,11 +124,11 @@ export function createTerminalFrameHandlers({ response, textRelay, midState, err
|
|
|
105
124
|
failWith(responseDoneStatusError(status, `${errLabel} response.done unexpected status`), { markDone: true });
|
|
106
125
|
return;
|
|
107
126
|
}
|
|
108
|
-
// Success-shaped response.done (status '' or 'completed')
|
|
109
|
-
//
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
127
|
+
// Success-shaped response.done (status '' or 'completed') is the same
|
|
128
|
+
// terminal as response.completed: usage, end_turn, and its output bundle
|
|
129
|
+
// reconciled through the same deduplicated collectors (calls that appear
|
|
130
|
+
// only in the bundle are created; unresolvable deferred calls fail).
|
|
131
|
+
onResponseCompleted(event);
|
|
113
132
|
}
|
|
114
133
|
|
|
115
134
|
function onResponseIncomplete(event) {
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* builder returns a tagged Error the stream loop stores as terminalError.
|
|
5
5
|
*/
|
|
6
6
|
import { typedStatusFrom } from './retry-classifier.mjs';
|
|
7
|
+
import { applyErrorContract, markContentFilter } from './openai-error-contract.mjs';
|
|
7
8
|
import { _httpStatusFromWsClose } from './openai-ws-events.mjs';
|
|
8
9
|
|
|
9
10
|
/** A server `event.error` on any frame. Same wire-error contract as
|
|
@@ -17,10 +18,9 @@ export function serverErrorEventError(error, event) {
|
|
|
17
18
|
try {
|
|
18
19
|
err.payload = error;
|
|
19
20
|
err.responseFailed = event;
|
|
20
|
-
const typed = typedStatusFrom(error, event);
|
|
21
|
-
if (typed) err.httpStatus = typed;
|
|
22
21
|
const code = error.code ?? error.type ?? null;
|
|
23
22
|
if (typeof code === 'string' && code) err.providerErrorCode = code;
|
|
23
|
+
applyErrorContract(err, { status: typedStatusFrom(error, event), error, event });
|
|
24
24
|
} catch {}
|
|
25
25
|
return err;
|
|
26
26
|
}
|
|
@@ -32,23 +32,27 @@ export function serverErrorEventError(error, event) {
|
|
|
32
32
|
export function responseFailedError(event, { label, fallbackMessage, providerErrorCode = false }) {
|
|
33
33
|
const msg = event.response?.error?.message || event.error?.message || event.message || fallbackMessage;
|
|
34
34
|
const err = Object.assign(new Error(`${label}: ${msg}`), { responseFailed: event });
|
|
35
|
-
const
|
|
36
|
-
if (typed) err.httpStatus = typed;
|
|
35
|
+
const detail = event.response?.error || event.error || null;
|
|
37
36
|
if (providerErrorCode) {
|
|
38
|
-
const detail = event.response?.error || event.error || null;
|
|
39
37
|
const code = detail?.code ?? detail?.type ?? null;
|
|
40
38
|
if (typeof code === 'string' && code) err.providerErrorCode = code;
|
|
41
39
|
}
|
|
42
|
-
return err
|
|
40
|
+
return applyErrorContract(err, {
|
|
41
|
+
status: typedStatusFrom(event.response?.error, event.error, event),
|
|
42
|
+
error: detail,
|
|
43
|
+
event,
|
|
44
|
+
});
|
|
43
45
|
}
|
|
44
46
|
|
|
45
47
|
/** response.incomplete (or response.done status 'incomplete') for a reason
|
|
46
|
-
* other than max_output_tokens.
|
|
48
|
+
* other than max_output_tokens. A content_filter stop is a typed policy
|
|
49
|
+
* refusal (code 'content_filter'), not an untyped failure. */
|
|
47
50
|
export function responseIncompleteError(event, reasonStr, label) {
|
|
48
|
-
|
|
51
|
+
const err = Object.assign(new Error(`${label}: ${reasonStr}`), {
|
|
49
52
|
responseIncomplete: event,
|
|
50
53
|
incompleteReason: reasonStr,
|
|
51
54
|
});
|
|
55
|
+
return markContentFilter(err, reasonStr);
|
|
52
56
|
}
|
|
53
57
|
|
|
54
58
|
/** response.done with a status that is neither completed, failed nor incomplete. */
|
|
@@ -63,11 +67,14 @@ export function errorFrameError(event, label) {
|
|
|
63
67
|
const errMsg = String(event.message || event.error?.message || 'unknown');
|
|
64
68
|
const err = new Error(`${label}: ${errMsg}`);
|
|
65
69
|
err.responseFailed = event;
|
|
66
|
-
const typed = typedStatusFrom(event.error, event);
|
|
67
|
-
if (typed) err.httpStatus = typed;
|
|
68
70
|
const code = event.error?.code ?? event.error?.type ?? event.code ?? null;
|
|
69
71
|
if (typeof code === 'string' && code) err.providerErrorCode = code;
|
|
70
|
-
return err
|
|
72
|
+
return applyErrorContract(err, {
|
|
73
|
+
status: typedStatusFrom(event.error, event),
|
|
74
|
+
code: typeof code === 'string' ? code : undefined,
|
|
75
|
+
error: event.error,
|
|
76
|
+
event,
|
|
77
|
+
});
|
|
71
78
|
}
|
|
72
79
|
|
|
73
80
|
/** The socket closed before a terminal frame. */
|