mixdog 1.2.0 → 1.2.2
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 +7 -5
- package/package.json +1 -1
- package/scripts/gate-local.mjs +19 -3
- package/scripts/model-catalog-audit.mjs +1 -15
- package/src/agents/reviewer/AGENT.md +3 -3
- package/src/agents/reviewer/agent.json +1 -1
- package/src/defaults/shipped-history.json +5 -0
- package/src/defaults/skills/pptx/SKILL.md +6 -6
- package/src/defaults/skills/pptx/references/review.md +6 -4
- package/src/defaults/skills/pptx/scripts/source-extract.mjs +1 -1
- package/src/defaults/skills/setup/references/actions.md +13 -3
- package/src/defaults/skills/visualize/SKILL.md +12 -9
- package/src/repl/slash-commands.mjs +16 -1
- package/src/rules/shared/60-verification.md +3 -1
- package/src/rules/shared/70-delivery.md +4 -2
- 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/cache-mtime.mjs +26 -5
- package/src/runtime/agent/orchestrator/config.mjs +10 -4
- package/src/runtime/agent/orchestrator/context/collect.mjs +2 -1
- package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +11 -5
- package/src/runtime/agent/orchestrator/context/skill-catalog.mjs +74 -21
- package/src/runtime/agent/orchestrator/mcp/client-config.mjs +122 -15
- package/src/runtime/agent/orchestrator/mcp/client-handshake.mjs +54 -11
- package/src/runtime/agent/orchestrator/mcp/client-transport.mjs +104 -9
- package/src/runtime/agent/orchestrator/mcp/client.mjs +358 -140
- package/src/runtime/agent/orchestrator/mcp/lazy-output-validator.mjs +25 -0
- 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/mcp/plugin-placeholders.mjs +54 -0
- package/src/runtime/agent/orchestrator/providers/account-pool.mjs +294 -44
- package/src/runtime/agent/orchestrator/providers/anthropic-api-recovery.mjs +2 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-api-transport.mjs +94 -31
- package/src/runtime/agent/orchestrator/providers/anthropic-error-contract.mjs +96 -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 +25 -21
- package/src/runtime/agent/orchestrator/providers/anthropic-messages.mjs +3 -1
- 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 +73 -35
- 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.mjs +8 -1
- package/src/runtime/agent/orchestrator/providers/anthropic.mjs +53 -18
- 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 +30 -14
- package/src/runtime/agent/orchestrator/providers/antigravity-response.mjs +2 -1
- package/src/runtime/agent/orchestrator/providers/antigravity-retry-policy.mjs +93 -0
- package/src/runtime/agent/orchestrator/providers/antigravity-transport.mjs +82 -9
- package/src/runtime/agent/orchestrator/providers/auto-effort.mjs +9 -0
- package/src/runtime/agent/orchestrator/providers/command-code-oauth-login.mjs +337 -0
- package/src/runtime/agent/orchestrator/providers/command-code-oauth-tokens.mjs +159 -0
- package/src/runtime/agent/orchestrator/providers/command-code-oauth.mjs +447 -0
- package/src/runtime/agent/orchestrator/providers/cursor-auth.mjs +38 -5
- 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 +102 -23
- package/src/runtime/agent/orchestrator/providers/cursor-wire-transport.mjs +103 -33
- package/src/runtime/agent/orchestrator/providers/cursor-wire.mjs +29 -6
- package/src/runtime/agent/orchestrator/providers/cursor.mjs +18 -1
- package/src/runtime/agent/orchestrator/providers/custom-provider.mjs +7 -4
- package/src/runtime/agent/orchestrator/providers/effort-configuration.mjs +86 -19
- package/src/runtime/agent/orchestrator/providers/gemini-cache-policy.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/gemini-cache.mjs +29 -8
- package/src/runtime/agent/orchestrator/providers/gemini-error-contract.mjs +191 -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-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 +21 -82
- package/src/runtime/agent/orchestrator/providers/gemini-sdk-request.mjs +4 -1
- package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +71 -12
- package/src/runtime/agent/orchestrator/providers/gemini-thinking.mjs +21 -20
- package/src/runtime/agent/orchestrator/providers/gemini.mjs +97 -51
- package/src/runtime/agent/orchestrator/providers/grok-oauth-tokens.mjs +3 -0
- package/src/runtime/agent/orchestrator/providers/grok-oauth.mjs +68 -19
- package/src/runtime/agent/orchestrator/providers/lib/gemini-model-catalog.mjs +7 -1
- 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-bridge.mjs +1080 -0
- package/src/runtime/agent/orchestrator/providers/model-proxy-channel.d.mts +15 -0
- package/src/runtime/agent/orchestrator/providers/model-proxy-channel.mjs +35 -0
- package/src/runtime/agent/orchestrator/providers/muse-code-oauth.mjs +4 -9
- package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +12 -0
- package/src/runtime/agent/orchestrator/providers/oauth-usage.mjs +6 -5
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-send.mjs +5 -3
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-result.mjs +22 -0
- 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 +6 -2
- package/src/runtime/agent/orchestrator/providers/openai-compat-options.mjs +11 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-response-normalization.mjs +23 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses-events.mjs +16 -8
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses-state.mjs +3 -2
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses.mjs +94 -13
- 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 +2 -1
- package/src/runtime/agent/orchestrator/providers/openai-compat-wire.mjs +6 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-xai-send.mjs +6 -3
- package/src/runtime/agent/orchestrator/providers/openai-compat-xai.mjs +23 -14
- package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +26 -6
- package/src/runtime/agent/orchestrator/providers/openai-direct-request.mjs +42 -25
- 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/terminal-frames.mjs +18 -11
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-outcome.mjs +1 -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 +2 -3
- 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-oauth-dispatch.mjs +34 -3
- package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +5 -1
- package/src/runtime/agent/orchestrator/providers/openai-oauth-tokens.mjs +22 -2
- package/src/runtime/agent/orchestrator/providers/openai-oauth.mjs +5 -0
- package/src/runtime/agent/orchestrator/providers/openai-responses-input.mjs +5 -9
- package/src/runtime/agent/orchestrator/providers/openai-retry-policy.mjs +9 -0
- package/src/runtime/agent/orchestrator/providers/openai-ws-handshake.mjs +16 -8
- 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-terminal.mjs +18 -11
- package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +35 -24
- package/src/runtime/agent/orchestrator/providers/provider-error-kind.mjs +581 -0
- package/src/runtime/agent/orchestrator/providers/registry.mjs +35 -9
- package/src/runtime/agent/orchestrator/providers/retry-backoff.mjs +46 -7
- package/src/runtime/agent/orchestrator/providers/retry-classification.mjs +118 -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/runtime-core/config-helpers.mjs +3 -0
- package/src/runtime/agent/orchestrator/runtime-core/effort.mjs +3 -0
- package/src/runtime/agent/orchestrator/runtime-core/extension-scopes.mjs +15 -55
- package/src/runtime/agent/orchestrator/runtime-core/goal-control.mjs +15 -2
- 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 +268 -181
- package/src/runtime/agent/orchestrator/runtime-core/skill-tool-loading.mjs +4 -1
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog-schema.mjs +21 -0
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +54 -3
- package/src/runtime/agent/orchestrator/session/catalog-db/index.mjs +284 -0
- package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +270 -0
- package/src/runtime/agent/orchestrator/session/catalog-db/sqlite-gate.mjs +27 -0
- package/src/runtime/agent/orchestrator/session/catalog-db/worker.mjs +628 -0
- package/src/runtime/agent/orchestrator/session/compact/messages.mjs +6 -2
- package/src/runtime/agent/orchestrator/session/conversation-import/claude.mjs +184 -0
- package/src/runtime/agent/orchestrator/session/conversation-import/codex.mjs +136 -0
- package/src/runtime/agent/orchestrator/session/conversation-import/convert.mjs +128 -0
- package/src/runtime/agent/orchestrator/session/conversation-import/imported-session.mjs +127 -0
- package/src/runtime/agent/orchestrator/session/conversation-import/turns.mjs +101 -0
- package/src/runtime/agent/orchestrator/session/explicit-skills.mjs +83 -5
- package/src/runtime/agent/orchestrator/session/imported-message.mjs +11 -0
- package/src/runtime/agent/orchestrator/session/loop/completion-guards.mjs +2 -1
- package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn.mjs +3 -2
- package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +10 -4
- package/src/runtime/agent/orchestrator/session/loop/steering.mjs +4 -3
- package/src/runtime/agent/orchestrator/session/loop/step-auto-effort.mjs +102 -18
- package/src/runtime/agent/orchestrator/session/loop/tool-helpers.mjs +3 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-phase.mjs +3 -1
- package/src/runtime/agent/orchestrator/session/manager/ask-queue.mjs +42 -5
- package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +14 -3
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-auto-effort.mjs +20 -12
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +50 -23
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-loop-options.mjs +4 -0
- package/src/runtime/agent/orchestrator/session/manager/pending-message-entry.mjs +22 -14
- package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/manager/turn-interruption.mjs +18 -7
- package/src/runtime/agent/orchestrator/session/manager.mjs +0 -1
- package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +4 -3
- package/src/runtime/agent/orchestrator/session/send-with-recovery.mjs +155 -29
- package/src/runtime/agent/orchestrator/session/store/listing.mjs +6 -2
- package/src/runtime/agent/orchestrator/session/store/save-worker.mjs +6 -3
- package/src/runtime/agent/orchestrator/session/store/summary-cache.mjs +6 -0
- 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-catalog.mjs +819 -0
- package/src/runtime/agent/orchestrator/session/store-summary-fields.mjs +12 -0
- package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +22 -12
- package/src/runtime/agent/orchestrator/session/store-summary-reader-catalog-fixture.mjs +158 -0
- package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +183 -374
- package/src/runtime/agent/orchestrator/session/synthetic-user-envelope.mjs +3 -1
- package/src/runtime/agent/orchestrator/session/tool-batch/pre-dispatch.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +41 -3
- package/src/runtime/agent/orchestrator/session/transcript-restore/user-text.mjs +38 -17
- package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/deadline-plan.mjs +12 -15
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/invocation-plan.mjs +17 -1
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/spawn-env.mjs +4 -0
- package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +5 -5
- package/src/runtime/agent/orchestrator/tools/builtin/lib/list-helpers.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/builtin/path-diagnostics.mjs +6 -6
- package/src/runtime/agent/orchestrator/tools/builtin/read-range-index.mjs +173 -22
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-guards.mjs +8 -4
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-tool.mjs +5 -4
- package/src/runtime/agent/orchestrator/tools/builtin/read-source-windows.mjs +15 -2
- package/src/runtime/agent/orchestrator/tools/builtin/search-glob-tool.mjs +13 -10
- package/src/runtime/agent/orchestrator/tools/builtin/search-grep-tool.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/search-path-diagnostics.mjs +17 -12
- package/src/runtime/agent/orchestrator/tools/code-graph/dispatch/root-resolution.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/code-graph/dispatch.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/patch/apply-patch/codex-batch.mjs +4 -4
- package/src/runtime/agent/orchestrator/tools/patch/apply-patch/route.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/patch/orchestrator.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/patch/read-redirects.mjs +34 -30
- package/src/runtime/agent/orchestrator/tools/patch/sequence/units.mjs +7 -7
- package/src/runtime/agent/orchestrator/tools/patch/sequence.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/shell-snapshot.mjs +4 -0
- package/src/runtime/attachments/store.d.mts +3 -0
- package/src/runtime/channels/lib/owned-runtime/owned-start.mjs +1 -1
- package/src/runtime/channels/lib/webhook/session-dispatch.mjs +16 -4
- package/src/runtime/channels/lib/worker-main.mjs +17 -14
- package/src/runtime/computer-bridge/linux-readiness.mjs +0 -2
- package/src/runtime/effort-judge/judge-client.mjs +56 -18
- package/src/runtime/memory/lib/memory.mjs +1 -1
- package/src/runtime/memory/lib/pg/process.mjs +34 -24
- package/src/runtime/memory/lib/pg/supervisor.mjs +16 -13
- package/src/runtime/memory/lib/session-ingest.mjs +2 -2
- package/src/runtime/office/README.md +1 -1
- package/src/runtime/office/shared/values.mjs +0 -5
- package/src/runtime/shared/atomic-file.mjs +25 -4
- package/src/runtime/shared/background-tasks.mjs +92 -14
- package/src/runtime/shared/err-text.mjs +25 -0
- package/src/runtime/shared/error-presentation.mjs +159 -19
- package/src/runtime/shared/extension-scopes.mjs +5 -3
- package/src/runtime/shared/file-lock.mjs +37 -11
- package/src/runtime/shared/llm/anthropic-betas.mjs +4 -3
- package/src/runtime/shared/llm/anthropic-effort.mjs +134 -131
- package/src/runtime/shared/llm/anthropic-thinking-contract.mjs +50 -14
- package/src/runtime/shared/llm/model-catalog.mjs +53 -52
- package/src/runtime/shared/llm/openai-daybreak.mjs +4 -16
- package/src/runtime/shared/llm/provider-catalog-registry.mjs +17 -0
- package/src/runtime/shared/llm/provider-model-identities.mjs +13 -4
- package/src/runtime/shared/llm/usage-rollup.mjs +0 -1
- package/src/runtime/shared/model-display.mjs +13 -0
- package/src/runtime/shared/plugin-manifest.mjs +18 -9
- package/src/runtime/shared/pristine-execution-contract.json +9 -2
- package/src/runtime/shared/pristine-execution.mjs +28 -4
- package/src/runtime/shared/provider-accounts.mjs +124 -20
- package/src/runtime/shared/provider-api-key.mjs +12 -0
- package/src/runtime/shared/quota-resume-store.mjs +11 -0
- package/src/runtime/shared/session-baseline-store.mjs +960 -0
- package/src/runtime/shared/shell-display.mjs +9 -3
- package/src/runtime/shared/skill-mentions.d.mts +10 -0
- package/src/runtime/shared/skill-mentions.mjs +133 -0
- package/src/runtime/shared/skill-script-runtime.mjs +264 -0
- package/src/runtime/shared/statusline/statusline-format.mjs +4 -4
- package/src/runtime/shared/task-notification-envelope.mjs +2 -2
- package/src/runtime/shared/tool-primitives.mjs +35 -2
- package/src/runtime/shared/turn-changes.mjs +447 -219
- package/src/runtime/shared/turn-snapshot-store.mjs +182 -1
- package/src/runtime/shared/turn-snapshot.mjs +170 -48
- package/src/runtime/shared/turn-worktree-snapshot.mjs +160 -51
- package/src/runtime/shared/worker-requests.mjs +15 -2
- package/src/runtime/shared/worktrees/contract.mjs +0 -24
- package/src/runtime/shared/worktrees/test-support.mjs +19 -4
- package/src/session-runtime/automation-agents.mjs +8 -2
- package/src/session-runtime/boot/apis.mjs +61 -0
- package/src/session-runtime/boot/config.mjs +5 -2
- package/src/session-runtime/boot/facade.mjs +1 -0
- package/src/session-runtime/boot/infrastructure.mjs +35 -18
- package/src/session-runtime/conversation-import/discovery.mjs +698 -0
- package/src/session-runtime/conversation-import/service.mjs +369 -0
- package/src/session-runtime/cwd-plugins/cwd-apply.mjs +10 -5
- package/src/session-runtime/cwd-plugins/plugin-status.mjs +47 -42
- package/src/session-runtime/lifecycle/session-catalog.mjs +2 -0
- package/src/session-runtime/lifecycle/teardown.mjs +1 -1
- package/src/session-runtime/mcp-glue/connect.mjs +83 -16
- package/src/session-runtime/mcp-glue/plugin-servers.mjs +499 -0
- package/src/session-runtime/mcp-glue/server-catalog.mjs +135 -33
- package/src/session-runtime/mcp-glue.mjs +25 -2
- 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 +83 -15
- 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/new-session-config.mjs +3 -2
- package/src/session-runtime/notification-bus.mjs +9 -2
- package/src/session-runtime/provider-auth/accounts.mjs +33 -15
- package/src/session-runtime/provider-models/model-meta.mjs +12 -3
- package/src/session-runtime/provider-models/web-search-catalog.mjs +5 -1
- package/src/session-runtime/provider-readiness.mjs +16 -10
- 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 +24 -5
- package/src/session-runtime/resource-mcp-api.mjs +198 -78
- package/src/session-runtime/resource-plugins-api.mjs +29 -41
- package/src/session-runtime/resource-scope-decorate.mjs +6 -8
- package/src/session-runtime/resource-skills-api.mjs +23 -2
- package/src/session-runtime/runtime-review-api.mjs +13 -0
- package/src/session-runtime/schedule-session-run.mjs +1 -1
- 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/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/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-rows.mjs +17 -0
- package/src/session-runtime/services/channel-session-router.mjs +4 -1
- package/src/session-runtime/services/hook-bus/command-handler.mjs +4 -1
- package/src/session-runtime/services/hook-bus/handlers.mjs +7 -3
- package/src/session-runtime/services/provider-admin.mjs +64 -18
- package/src/session-runtime/services/usage-dashboard-model.mjs +3 -0
- package/src/session-runtime/settings-compaction-api.mjs +1 -0
- package/src/session-runtime/setup-tool/executor.mjs +12 -1
- package/src/session-runtime/setup-tool/extended-actions.mjs +1 -0
- package/src/session-runtime/setup-tool/settings-contract.mjs +1 -0
- package/src/session-runtime/setup-tool/tool-defs.mjs +7 -1
- package/src/session-runtime/skills-api.mjs +7 -3
- package/src/session-runtime/turn/turn-run/ask-callbacks.mjs +1 -0
- package/src/session-runtime/webhook-session-run.mjs +16 -4
- package/src/skill-script-entry.mjs +36 -0
- package/src/standalone/daemon-drain-policy.mjs +8 -0
- package/src/standalone/daemon-stored-session-views.mjs +11 -3
- package/src/standalone/daemon-telemetry.mjs +55 -0
- package/src/standalone/daemon.mjs +44 -11
- package/src/standalone/session-protocol.mjs +12 -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 +6 -1
- package/src/standalone/session-service-api.mjs +5 -0
- package/src/standalone/session-service.mjs +1 -0
- package/src/tui/App.jsx +9 -1
- package/src/tui/app/app-view/floating-panel.jsx +9 -1
- package/src/tui/app/app-view.jsx +7 -0
- package/src/tui/app/create-app-pickers.mjs +4 -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/plugins-pickers.mjs +35 -16
- package/src/tui/app/extension-pickers.mjs +2 -1
- package/src/tui/app/model-options.mjs +13 -16
- package/src/tui/app/skill-mention-palette.mjs +88 -0
- package/src/tui/app/slash-commands.mjs +7 -2
- package/src/tui/app/slash-dispatch/panel-commands.mjs +16 -1
- package/src/tui/app/slash-palette.mjs +23 -7
- package/src/tui/app/transcript-row-estimate.mjs +11 -3
- package/src/tui/app/use-prompt-draft-flow.mjs +7 -2
- package/src/tui/app/use-prompt-state.mjs +5 -0
- package/src/tui/components/Message.jsx +22 -1
- package/src/tui/components/PromptInput.jsx +21 -3
- package/src/tui/components/SlashCommandPalette.jsx +12 -3
- package/src/tui/components/StatusLine.jsx +2 -0
- package/src/tui/components/TranscriptItem.jsx +9 -1
- package/src/tui/components/prompt-input/key-handler.mjs +21 -8
- 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/components/user-message-skills.mjs +38 -0
- package/src/tui/dist/index.mjs +1323 -214
- package/src/tui/session/queue-helpers.mjs +7 -2
- package/src/tui/session/quota-resume.mjs +46 -14
- package/src/tui/session/session-api/commands.mjs +33 -24
- package/src/tui/session/session-api/extensions.mjs +26 -2
- package/src/tui/session/session-api/integrations.mjs +7 -0
- package/src/tui/session/session-api/lifecycle.mjs +5 -1
- package/src/tui/session/session-api/routes.mjs +71 -7
- package/src/tui/session/session-api/settings.mjs +12 -14
- package/src/tui/session/session-flow/drain.mjs +21 -5
- package/src/tui/session/session-flow/failed-turn-rewind.mjs +10 -4
- package/src/tui/session/tui-steering-persist.mjs +25 -9
- package/src/tui/session/turn.mjs +55 -15
- 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/runtime/effort-judge/previous-human-request.mjs +0 -162
- package/src/runtime/effort-judge/verified-context-input.mjs +0 -10
- package/src/runtime/memory/lib/memory-session-merge.mjs +0 -32
- package/src/runtime/shared/llm/usage-session-history.mjs +0 -266
|
@@ -50,6 +50,7 @@ export class ModelProxyChannel {
|
|
|
50
50
|
attachPublisher(publish: (snapshot: ModelProxySnapshot) => void): () => void;
|
|
51
51
|
disconnect(reason?: string): void;
|
|
52
52
|
setClientPresent(present: boolean): void;
|
|
53
|
+
onStateChange(listener: () => void): () => void;
|
|
53
54
|
request(
|
|
54
55
|
call: Record<string, unknown>,
|
|
55
56
|
options?: { signal?: AbortSignal | null; callbacks?: Record<string, (...args: unknown[]) => unknown> }
|
|
@@ -65,3 +66,17 @@ export class ModelProxyChannel {
|
|
|
65
66
|
}
|
|
66
67
|
|
|
67
68
|
export function getModelProxyChannel(): ModelProxyChannel;
|
|
69
|
+
|
|
70
|
+
/** The channel surface model-proxy providers use; the bridge child implements only this. */
|
|
71
|
+
export interface ModelProxyChannelLike {
|
|
72
|
+
readonly connected: boolean;
|
|
73
|
+
readonly generation: number;
|
|
74
|
+
whenConnected(timeoutMs: number): Promise<boolean>;
|
|
75
|
+
request(
|
|
76
|
+
call: Record<string, unknown>,
|
|
77
|
+
options?: { signal?: AbortSignal | null; callbacks?: Record<string, (...args: unknown[]) => unknown> }
|
|
78
|
+
): Promise<unknown>;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/** Swap the process-wide channel; the returned function restores the previous one. */
|
|
82
|
+
export function installModelProxyChannel(channel: ModelProxyChannel | ModelProxyChannelLike): () => void;
|
|
@@ -243,8 +243,24 @@ export class ModelProxyChannel {
|
|
|
243
243
|
});
|
|
244
244
|
}
|
|
245
245
|
|
|
246
|
+
#stateListeners = new Set();
|
|
247
|
+
|
|
248
|
+
/** `listener()` runs after every presence/generation change (the model
|
|
249
|
+
* proxy bridge pushes it to its clients). Returns the unsubscribe. */
|
|
250
|
+
onStateChange(listener) {
|
|
251
|
+
this.#stateListeners.add(listener);
|
|
252
|
+
return () => this.#stateListeners.delete(listener);
|
|
253
|
+
}
|
|
254
|
+
|
|
246
255
|
#connectionChanged() {
|
|
247
256
|
this.#generation += 1;
|
|
257
|
+
for (const listener of [...this.#stateListeners]) {
|
|
258
|
+
try {
|
|
259
|
+
listener();
|
|
260
|
+
} catch {
|
|
261
|
+
/* a listener never breaks the transport that reported the change */
|
|
262
|
+
}
|
|
263
|
+
}
|
|
248
264
|
if (!this.connected) return;
|
|
249
265
|
for (const waiter of [...this.#connectionWaiters]) waiter(true);
|
|
250
266
|
}
|
|
@@ -519,3 +535,22 @@ export function getModelProxyChannel() {
|
|
|
519
535
|
globalThis[CHANNEL_KEY] ??= new ModelProxyChannel();
|
|
520
536
|
return globalThis[CHANNEL_KEY];
|
|
521
537
|
}
|
|
538
|
+
|
|
539
|
+
/**
|
|
540
|
+
* Make `channel` the process-wide channel (a headless child talks through the
|
|
541
|
+
* daemon's model proxy bridge instead). The returned restore puts the previous
|
|
542
|
+
* channel back once, unless another install replaced this one since.
|
|
543
|
+
*/
|
|
544
|
+
export function installModelProxyChannel(channel) {
|
|
545
|
+
const hadPrevious = Object.hasOwn(globalThis, CHANNEL_KEY);
|
|
546
|
+
const previous = globalThis[CHANNEL_KEY];
|
|
547
|
+
globalThis[CHANNEL_KEY] = channel;
|
|
548
|
+
let restored = false;
|
|
549
|
+
return () => {
|
|
550
|
+
if (restored) return;
|
|
551
|
+
restored = true;
|
|
552
|
+
if (globalThis[CHANNEL_KEY] !== channel) return;
|
|
553
|
+
if (hadPrevious) globalThis[CHANNEL_KEY] = previous;
|
|
554
|
+
else delete globalThis[CHANNEL_KEY];
|
|
555
|
+
};
|
|
556
|
+
}
|
|
@@ -10,8 +10,10 @@ import { createHash } from 'node:crypto';
|
|
|
10
10
|
import { noteErrorUsage } from './lib/note-error-usage.mjs';
|
|
11
11
|
import { fileMtimeMs } from './lib/oauth-token-utils.mjs';
|
|
12
12
|
import { OpenAICompatProvider, preloadOpenAICompatRuntime } from './openai-compat.mjs';
|
|
13
|
+
import { COMPAT_RETRY_POLICY } from './openai-compat-retry-profile.mjs';
|
|
13
14
|
import { getModelMetadataSync } from './model-catalog.mjs';
|
|
14
15
|
import { makeModelCache } from './model-cache.mjs';
|
|
16
|
+
import { normalizeCacheKey } from '../agent-runtime/cache-strategy.mjs';
|
|
15
17
|
import { PRICING_RATE_KEYS } from '../../../shared/llm/model-pricing-rates.mjs';
|
|
16
18
|
import {
|
|
17
19
|
MUSE_DEFAULT_EFFORT_LEVELS as FIVE_LEVELS,
|
|
@@ -100,15 +102,6 @@ function museRow(id, discovered = null) {
|
|
|
100
102
|
const EFFORT_DOWNGRADE = { max: 'xhigh' };
|
|
101
103
|
const SUMMARY_MODES = new Set(['auto', 'detailed', 'concise']);
|
|
102
104
|
|
|
103
|
-
// Cache identities beyond the wire limit become a bounded hash identity.
|
|
104
|
-
function normalizeCacheKey(value) {
|
|
105
|
-
const text = String(value ?? '').trim();
|
|
106
|
-
if (!text) return '';
|
|
107
|
-
const wellFormed = text.toWellFormed();
|
|
108
|
-
if (wellFormed.length <= 64) return wellFormed;
|
|
109
|
-
return `pc_${createHash('sha256').update(wellFormed).digest('hex').slice(0, 32)}`;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
105
|
// Final request shaping on the Responses wire (installed through the shared
|
|
113
106
|
// transport's opt-in params hook).
|
|
114
107
|
function shapeResponsesParams(params, { opts, modelInfo }, config = {}) {
|
|
@@ -321,6 +314,8 @@ export class MuseCodeOAuthProvider {
|
|
|
321
314
|
nativePdf = false;
|
|
322
315
|
static inputExcludesCache = false;
|
|
323
316
|
name = 'muse-code-oauth';
|
|
317
|
+
// The retry profile's limits are final: no loop-level recovery cycles on top.
|
|
318
|
+
retryPolicy = COMPAT_RETRY_POLICY;
|
|
324
319
|
config;
|
|
325
320
|
tokens = null;
|
|
326
321
|
_inner = null;
|
|
@@ -181,6 +181,17 @@ function mimoOAuthState() {
|
|
|
181
181
|
);
|
|
182
182
|
}
|
|
183
183
|
|
|
184
|
+
function commandCodeOAuthState() {
|
|
185
|
+
const paths = [
|
|
186
|
+
boundProviderAuthPath('command-code-oauth') ||
|
|
187
|
+
process.env.COMMAND_CODE_OAUTH_CREDENTIALS_PATH ||
|
|
188
|
+
join(resolvePluginData(), 'command-code-oauth.json'),
|
|
189
|
+
];
|
|
190
|
+
return memoProbe('command-code-oauth', paths, () =>
|
|
191
|
+
resolveProbeState(paths, (docs) => docs.some((own) => typeof own?.apiKey === 'string' && !!own.apiKey.trim()))
|
|
192
|
+
);
|
|
193
|
+
}
|
|
194
|
+
|
|
184
195
|
function museCodeOAuthState() {
|
|
185
196
|
const paths = [
|
|
186
197
|
boundProviderAuthPath('muse-code-oauth') ||
|
|
@@ -255,6 +266,7 @@ const OAUTH_PROBE_STATES = new Map([
|
|
|
255
266
|
['openai-oauth', openAIOAuthState],
|
|
256
267
|
['grok-oauth', grokOAuthState],
|
|
257
268
|
['muse-code-oauth', museCodeOAuthState],
|
|
269
|
+
['command-code-oauth', commandCodeOAuthState],
|
|
258
270
|
['mimo-oauth', mimoOAuthState],
|
|
259
271
|
['cursor-oauth', cursorOAuthState],
|
|
260
272
|
['antigravity-oauth', antigravityOAuthState],
|
|
@@ -868,7 +868,8 @@ async function measureUsage(provider, providerObj, routeInfo) {
|
|
|
868
868
|
(provider === 'cursor-oauth' ||
|
|
869
869
|
provider === 'cursor-api' ||
|
|
870
870
|
provider === 'antigravity-oauth' ||
|
|
871
|
-
provider === 'muse-code-oauth'
|
|
871
|
+
provider === 'muse-code-oauth' ||
|
|
872
|
+
provider === 'command-code-oauth') &&
|
|
872
873
|
typeof providerObj?.getUsageSnapshot === 'function'
|
|
873
874
|
) {
|
|
874
875
|
return await providerObj.getUsageSnapshot();
|
|
@@ -893,12 +894,12 @@ async function measureUsageWithAuthRetry(provider, providerObj, routeInfo) {
|
|
|
893
894
|
// refresh cannot vouch for the reading it last produced: keeping a 100% meter
|
|
894
895
|
// earned by a dead token would hold the account out of the roster until its
|
|
895
896
|
// reset time, so the recorded quota goes with the credential.
|
|
896
|
-
function usageAfterFailure(err, provider, accountId, log) {
|
|
897
|
+
async function usageAfterFailure(err, provider, accountId, log) {
|
|
897
898
|
const snapshot = provider === 'anthropic-oauth' && accountId === 'default' ? latestClaudeStatuslineUsage() : null;
|
|
898
899
|
if (snapshot) return snapshot;
|
|
899
900
|
if (isUsageAuthRejection(err) && ACCOUNT_PROVIDERS.includes(provider)) {
|
|
900
901
|
try {
|
|
901
|
-
clearProviderAccountQuotaState(provider, accountId);
|
|
902
|
+
await clearProviderAccountQuotaState(provider, accountId);
|
|
902
903
|
} catch (error) {
|
|
903
904
|
log(`Account usage could not be cleared: ${error.message}`);
|
|
904
905
|
}
|
|
@@ -952,7 +953,7 @@ export async function fetchOAuthUsageSnapshot(routeInfo, providerObj, log = () =
|
|
|
952
953
|
try {
|
|
953
954
|
snapshot = await measureUsageWithAuthRetry(provider, providerObj, routeInfo);
|
|
954
955
|
} catch (err) {
|
|
955
|
-
snapshot = usageAfterFailure(err, provider, accountId, log);
|
|
956
|
+
snapshot = await usageAfterFailure(err, provider, accountId, log);
|
|
956
957
|
}
|
|
957
958
|
if (!isContentfulSnapshot(snapshot)) {
|
|
958
959
|
cacheNegative(key, 'empty');
|
|
@@ -961,7 +962,7 @@ export async function fetchOAuthUsageSnapshot(routeInfo, providerObj, log = () =
|
|
|
961
962
|
}
|
|
962
963
|
if (ACCOUNT_PROVIDERS.includes(provider)) {
|
|
963
964
|
try {
|
|
964
|
-
recordProviderAccountUsage(provider, accountId, snapshot);
|
|
965
|
+
await recordProviderAccountUsage(provider, accountId, snapshot);
|
|
965
966
|
} catch (error) {
|
|
966
967
|
log(`Account usage could not be saved: ${error.message}`);
|
|
967
968
|
}
|
|
@@ -21,6 +21,7 @@ import { normalizeCompatChatResponse } from './openai-compat-response-normalizat
|
|
|
21
21
|
import { applyCompatToolChoice, compatStreamRetryReporter } from './compat-request-policy.mjs';
|
|
22
22
|
import { ensureChatToolPairs } from './lib/wire-pairing.mjs';
|
|
23
23
|
import { xaiCacheRouting } from './openai-compat-xai.mjs';
|
|
24
|
+
import { compatRetryOptions, withCompatRetryProfile } from './openai-compat-retry-profile.mjs';
|
|
24
25
|
import { preparePdfTextForProvider } from './media-normalization.mjs';
|
|
25
26
|
import { isCustomProviderName, resolveCustomReasoning } from './custom-reasoning.mjs';
|
|
26
27
|
|
|
@@ -38,7 +39,7 @@ export async function sendCompatChat(provider, messages, useModel, tools, opts)
|
|
|
38
39
|
// global catalog must not shape a user-defined endpoint's request.
|
|
39
40
|
let modelInfo = null;
|
|
40
41
|
if (isCustom) modelInfo = provider.getCachedModelInfo(useModel) || null;
|
|
41
|
-
else if (provider.name === 'opencode-go')
|
|
42
|
+
else if (provider.name === 'opencode-go' || provider.name === 'command-code-oauth')
|
|
42
43
|
modelInfo = provider.getCachedModelInfo(useModel) || getModelMetadataSync(useModel, provider.name);
|
|
43
44
|
else if (profile?.resolveModelInfo) modelInfo = profile.resolveModelInfo(provider, useModel) || null;
|
|
44
45
|
// Resolved before lowering: replay eligibility depends on the snapped level
|
|
@@ -85,7 +86,7 @@ export async function sendCompatChat(provider, messages, useModel, tools, opts)
|
|
|
85
86
|
try {
|
|
86
87
|
try {
|
|
87
88
|
assembled = await withRetry(
|
|
88
|
-
refineAttemptErrors(profile, async ({ signal: attemptSignal }) => {
|
|
89
|
+
withCompatRetryProfile(provider.name, refineAttemptErrors(profile, async ({ signal: attemptSignal }) => {
|
|
89
90
|
try {
|
|
90
91
|
opts.onStageChange?.('requesting');
|
|
91
92
|
} catch {
|
|
@@ -139,11 +140,12 @@ export async function sendCompatChat(provider, messages, useModel, tools, opts)
|
|
|
139
140
|
}
|
|
140
141
|
throw error;
|
|
141
142
|
}
|
|
142
|
-
}),
|
|
143
|
+
})),
|
|
143
144
|
{
|
|
144
145
|
signal: totalSignal.signal,
|
|
145
146
|
onRetry: compatStreamRetryReporter(provider.name, opts),
|
|
146
147
|
retry529: opts.retry529,
|
|
148
|
+
...compatRetryOptions(provider.name),
|
|
147
149
|
}
|
|
148
150
|
);
|
|
149
151
|
} catch (streamErr) {
|
package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-result.mjs
CHANGED
|
@@ -8,6 +8,7 @@ import { truncatedCompatStreamError } from '../lib/openai-tool-args.mjs';
|
|
|
8
8
|
import {
|
|
9
9
|
emitCompatToolCallOnce,
|
|
10
10
|
firstByteCompatStreamError,
|
|
11
|
+
failingFinishReasonError,
|
|
11
12
|
markErrorLiveTextEmitted,
|
|
12
13
|
markUnsafeRetryIfToolEmitted,
|
|
13
14
|
} from '../openai-compat-stream-common.mjs';
|
|
@@ -61,7 +62,28 @@ function parseAccumulatedToolCalls(state, { label, parseToolCalls }) {
|
|
|
61
62
|
}
|
|
62
63
|
}
|
|
63
64
|
|
|
65
|
+
// A gateway-reported failing finish_reason (`network_error`, `error`) is an
|
|
66
|
+
// interruption: the stream carries no terminal, so exposure keeps its replay
|
|
67
|
+
// gates.
|
|
68
|
+
function finishReasonInterruption(state, err) {
|
|
69
|
+
attachPartial(state, err);
|
|
70
|
+
if (state.emittedText) {
|
|
71
|
+
markErrorLiveTextEmitted(err);
|
|
72
|
+
try {
|
|
73
|
+
err.streamStalled = true;
|
|
74
|
+
} catch {
|
|
75
|
+
/* best-effort */
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return stampCompatOutcome(state, markUnsafeRetryIfToolEmitted(err, state.streamEmitState), {
|
|
79
|
+
terminalObserved: false,
|
|
80
|
+
continuation: true,
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
|
|
64
84
|
export function settleCompatStream(state, { label, parseToolCalls }) {
|
|
85
|
+
const failing = failingFinishReasonError(state.stopReason, label);
|
|
86
|
+
if (failing) throw finishReasonInterruption(state, failing);
|
|
65
87
|
const response = buildResponse(state);
|
|
66
88
|
let toolCalls = parseAccumulatedToolCalls(state, { label, parseToolCalls });
|
|
67
89
|
if (Array.isArray(toolCalls) && toolCalls.length) {
|
|
@@ -71,6 +71,7 @@ export async function consumeCompatChatCompletionStream(
|
|
|
71
71
|
idleDeadlineAt: state.semanticIdleDeadlineAt,
|
|
72
72
|
idleEnabled: state.sawFirstEvent && idleEnabled && state.semanticIdleDeadlineAt > 0,
|
|
73
73
|
idleLabel: `${label} SSE idle`,
|
|
74
|
+
streamLabel: label,
|
|
74
75
|
emittedToolCall: () => toolWorkStarted(state),
|
|
75
76
|
});
|
|
76
77
|
if (done) {
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* openai-compat-error-contract.mjs — the error contract of the OpenAI-compatible
|
|
3
|
+
* provider boundary: `status`, lowercased `code` (from the wire error's `code`
|
|
4
|
+
* or `type`), `headers`, `retryAfterMs` and `resetAt` when the provider sent
|
|
5
|
+
* them. Evidence is structural only; message text is never parsed.
|
|
6
|
+
*/
|
|
7
|
+
import { retryAfterMsFromError, typedStatusFrom } from './retry-classifier.mjs';
|
|
8
|
+
|
|
9
|
+
const lowered = (value) => (typeof value === 'string' && value.trim() ? value.trim().toLowerCase() : '');
|
|
10
|
+
|
|
11
|
+
// Epoch seconds, epoch ms or an ISO date → epoch ms; `resets_in_seconds` is relative.
|
|
12
|
+
function resetAtFrom(wire, now) {
|
|
13
|
+
const inSeconds = Number(wire?.resets_in_seconds);
|
|
14
|
+
if (wire?.resets_in_seconds != null && Number.isFinite(inSeconds) && inSeconds >= 0) {
|
|
15
|
+
return now + Math.ceil(inSeconds * 1000);
|
|
16
|
+
}
|
|
17
|
+
const raw = wire?.resets_at ?? wire?.reset_at;
|
|
18
|
+
if (raw == null || raw === '') return null;
|
|
19
|
+
const numeric = Number(raw);
|
|
20
|
+
if (Number.isFinite(numeric) && numeric > 0) return numeric < 1e12 ? Math.round(numeric * 1000) : Math.round(numeric);
|
|
21
|
+
const parsed = Date.parse(String(raw));
|
|
22
|
+
return Number.isNaN(parsed) ? null : parsed;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** Stamp the boundary contract onto a provider error in place and return it. */
|
|
26
|
+
export function applyCompatErrorContract(err, detail = err?.error ?? err?.providerError, now = Date.now()) {
|
|
27
|
+
if (!err || typeof err !== 'object') return err;
|
|
28
|
+
try {
|
|
29
|
+
const wire = detail && typeof detail === 'object' ? detail : null;
|
|
30
|
+
const status = typedStatusFrom(err, err.response, wire);
|
|
31
|
+
if (status && !(Number(err.status) >= 100)) err.status = status;
|
|
32
|
+
const wireCode = lowered(wire?.code) || lowered(wire?.type) || lowered(err.type);
|
|
33
|
+
// Keep an errno / SDK-local code (ECONNRESET, ...) that is not the wire code.
|
|
34
|
+
if (wireCode && (typeof err.code !== 'string' || !err.code.trim() || lowered(err.code) === wireCode)) {
|
|
35
|
+
err.code = wireCode;
|
|
36
|
+
}
|
|
37
|
+
if (!err.headers && err.response?.headers) err.headers = err.response.headers;
|
|
38
|
+
if (!Number.isFinite(err.retryAfterMs)) {
|
|
39
|
+
const retryAfterMs = retryAfterMsFromError(err);
|
|
40
|
+
if (retryAfterMs != null) err.retryAfterMs = retryAfterMs;
|
|
41
|
+
}
|
|
42
|
+
if (!Number.isFinite(err.resetAt)) {
|
|
43
|
+
const resetAt = resetAtFrom(wire, now);
|
|
44
|
+
if (resetAt) err.resetAt = resetAt;
|
|
45
|
+
}
|
|
46
|
+
} catch {
|
|
47
|
+
/* the contract is best-effort; the original error stays authoritative */
|
|
48
|
+
}
|
|
49
|
+
return err;
|
|
50
|
+
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { resolveProviderApiKey } from '../../../shared/provider-api-key.mjs';
|
|
1
2
|
import { enrichModels } from './model-catalog.mjs';
|
|
2
3
|
import { sanitizeModelList } from './model-list-sanitize.mjs';
|
|
3
4
|
import { PROVIDER_GENERATE_TOTAL_TIMEOUT_MS, createTimeoutSignal, resolveTimeoutMs } from '../stall-policy.mjs';
|
|
@@ -10,12 +11,15 @@ const MODEL_LIST_TIMEOUT_MS = resolveTimeoutMs('MIXDOG_COMPAT_MODEL_LIST_TIMEOUT
|
|
|
10
11
|
// `keyless` omits the Authorization header entirely (keyless endpoints);
|
|
11
12
|
// `signal` aborts the request together with the list timeout.
|
|
12
13
|
export async function fetchCompatModelItems(provider, { signal = null, keyless = false } = {}) {
|
|
13
|
-
const
|
|
14
|
+
const name = provider.name;
|
|
15
|
+
const timeout = createTimeoutSignal(signal, MODEL_LIST_TIMEOUT_MS, `${name} model list`);
|
|
14
16
|
try {
|
|
15
17
|
const res = await fetch(`${String(provider.baseURL || '').replace(/\/+$/, '')}/models`, {
|
|
16
18
|
method: 'GET',
|
|
17
19
|
headers: {
|
|
18
|
-
...(keyless
|
|
20
|
+
...(keyless
|
|
21
|
+
? {}
|
|
22
|
+
: { Authorization: `Bearer ${resolveProviderApiKey(name, provider.config || provider) || 'no-key'}` }),
|
|
19
23
|
...(provider.defaultHeaders || {}),
|
|
20
24
|
},
|
|
21
25
|
signal: timeout.signal,
|
|
@@ -74,6 +74,17 @@ export function applyCompatProviderChatOptions(params, providerName, opts = {},
|
|
|
74
74
|
}
|
|
75
75
|
return params;
|
|
76
76
|
}
|
|
77
|
+
if (providerName === 'command-code-oauth') {
|
|
78
|
+
// The API's field is undocumented; mirror the common `reasoning_effort`
|
|
79
|
+
// (levels the catalog row declares, else low/medium/high).
|
|
80
|
+
const rawEffort = opts.effort ?? config?.reasoningEffort;
|
|
81
|
+
const declared = modelInfo?.reasoningOptions?.some((option) => option?.type === 'effort');
|
|
82
|
+
const effort = declared
|
|
83
|
+
? normalizeOpencodeGoReasoningEffort(rawEffort, modelInfo)
|
|
84
|
+
: normalizeReasoningEffort(rawEffort, ['low', 'medium', 'high']);
|
|
85
|
+
if (effort) params.reasoning_effort = effort;
|
|
86
|
+
return params;
|
|
87
|
+
}
|
|
77
88
|
if (providerName === 'opencode-go') {
|
|
78
89
|
const reasoningEffort = normalizeOpencodeGoReasoningEffort(opts.effort ?? config?.reasoningEffort, modelInfo);
|
|
79
90
|
// OpenCode Go's OpenAI-compatible contract exposes reasoning_effort,
|
|
@@ -7,6 +7,8 @@ import {
|
|
|
7
7
|
writeXaiResponsesCacheTrace,
|
|
8
8
|
} from './openai-compat-xai.mjs';
|
|
9
9
|
import { createProviderReplay } from './lib/provider-replay.mjs';
|
|
10
|
+
import { stampStreamOutcome, STREAM_TRANSPORTS } from './lib/stream-outcome.mjs';
|
|
11
|
+
import { failingFinishReasonError } from './openai-compat-stream-common.mjs';
|
|
10
12
|
|
|
11
13
|
const reportedNumber = (value) =>
|
|
12
14
|
value == null || (typeof value === 'string' && value.trim() === '') ? Number.NaN : Number(value);
|
|
@@ -141,6 +143,27 @@ export function normalizeCompatChatResponse({
|
|
|
141
143
|
const choice = response.choices[0];
|
|
142
144
|
const toolCalls = assembled.toolCalls;
|
|
143
145
|
const stopReason = choice?.finish_reason || null;
|
|
146
|
+
const failingFinish = failingFinishReasonError(stopReason, providerName);
|
|
147
|
+
if (failingFinish) {
|
|
148
|
+
const err = failingFinish;
|
|
149
|
+
const partialContent = choice?.message?.content || '';
|
|
150
|
+
Object.assign(err, {
|
|
151
|
+
partialContent,
|
|
152
|
+
partialToolCalls: Array.isArray(toolCalls) && toolCalls.length ? toolCalls : undefined,
|
|
153
|
+
pendingToolUse: false,
|
|
154
|
+
partialModel: response.model || useModel,
|
|
155
|
+
...(response.usage ? { partialUsage: chatCompletionUsage(providerName, response.usage) } : {}),
|
|
156
|
+
});
|
|
157
|
+
stampStreamOutcome(err, {
|
|
158
|
+
transport: STREAM_TRANSPORTS.NON_STREAMING,
|
|
159
|
+
provider: 'openai-compat',
|
|
160
|
+
terminalObserved: false,
|
|
161
|
+
continuation: true,
|
|
162
|
+
textObservedChars: partialContent.length,
|
|
163
|
+
toolCallsComplete: err.partialToolCalls?.length || 0,
|
|
164
|
+
});
|
|
165
|
+
throw err;
|
|
166
|
+
}
|
|
144
167
|
if (
|
|
145
168
|
(stopReason === 'length' && Array.isArray(toolCalls) && toolCalls.length > 0) ||
|
|
146
169
|
stopReason === 'content_filter'
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
// wire event type maps to one handler over the shared stream `state`; `ctx`
|
|
3
3
|
// carries the label, the caller callbacks and the leaked-text relay.
|
|
4
4
|
import { typedStatusFrom } from './retry-classifier.mjs';
|
|
5
|
+
import { applyCompatErrorContract } from './openai-compat-error-contract.mjs';
|
|
5
6
|
import { customToolCallFromResponseItem, nativeToolSearchCallFromArguments } from './custom-tool-wire.mjs';
|
|
6
7
|
import { emitCompatToolCallOnce } from './openai-compat-stream-common.mjs';
|
|
7
8
|
import { truncatedCompatStreamError, parseCompletedToolCallArgumentsJson } from './lib/openai-tool-args.mjs';
|
|
@@ -41,9 +42,11 @@ function typedResponsesFailure(message, event) {
|
|
|
41
42
|
if (code != null && code !== '') err.providerErrorCode = String(code);
|
|
42
43
|
if (detail) err.providerError = detail;
|
|
43
44
|
err.providerWireError = true;
|
|
44
|
-
return err;
|
|
45
|
+
return applyCompatErrorContract(err, detail || (event?.code != null ? { code: event.code } : null));
|
|
45
46
|
}
|
|
46
47
|
|
|
48
|
+
const streamLabel = (ctx) => ctx?.label || 'compat Responses';
|
|
49
|
+
|
|
47
50
|
// Reconcile a COMPLETED function_call item into state.toolCalls: fill in the
|
|
48
51
|
// id/name a streamed call may still be missing, or adopt the item as a new
|
|
49
52
|
// call. `response.output_item.done` and the `response.completed` sweep see the
|
|
@@ -289,6 +292,7 @@ function onCompleted(event, state, ctx) {
|
|
|
289
292
|
}
|
|
290
293
|
|
|
291
294
|
function onDone(event, state, ctx) {
|
|
295
|
+
const label = streamLabel(ctx);
|
|
292
296
|
if (!event.response || event.response.status === 'completed') {
|
|
293
297
|
state.completed = true;
|
|
294
298
|
// A stream that never emits response.completed: this frame carries usage.
|
|
@@ -298,7 +302,7 @@ function onDone(event, state, ctx) {
|
|
|
298
302
|
if (event.response.status === 'failed') {
|
|
299
303
|
const msg = event.response?.error?.message || 'response.done failed';
|
|
300
304
|
throw withIncompleteUsage(
|
|
301
|
-
typedResponsesFailure(
|
|
305
|
+
typedResponsesFailure(`${label} stream response.done failed: ${msg}`, event),
|
|
302
306
|
event,
|
|
303
307
|
state
|
|
304
308
|
);
|
|
@@ -306,27 +310,31 @@ function onDone(event, state, ctx) {
|
|
|
306
310
|
if (event.response.status === 'incomplete') {
|
|
307
311
|
const reason = incompleteReasonFromEvent(event);
|
|
308
312
|
if (isMaxOutputIncompleteReason(reason)) return settleMaxOutputIncomplete(event, state, ctx, reason);
|
|
309
|
-
throw withIncompleteUsage(new Error(
|
|
313
|
+
throw withIncompleteUsage(new Error(`${label} stream response.done incomplete: ${reason}`), event, state);
|
|
310
314
|
}
|
|
311
315
|
}
|
|
312
316
|
|
|
313
|
-
function onFailed(event, state) {
|
|
317
|
+
function onFailed(event, state, ctx) {
|
|
314
318
|
const msg = event.response?.error?.message || event.error?.message || event.message || 'response.failed';
|
|
315
319
|
// The wire event's OWN typed status/code is preserved verbatim. A
|
|
316
320
|
// forbidden/unknown failure is never coerced into a synthetic 500:
|
|
317
321
|
// without typed evidence it stays unclassified and is surfaced.
|
|
318
|
-
throw withIncompleteUsage(
|
|
322
|
+
throw withIncompleteUsage(
|
|
323
|
+
typedResponsesFailure(`${streamLabel(ctx)} stream response.failed: ${msg}`, event),
|
|
324
|
+
event,
|
|
325
|
+
state
|
|
326
|
+
);
|
|
319
327
|
}
|
|
320
328
|
|
|
321
329
|
function onIncomplete(event, state, ctx) {
|
|
322
330
|
const reason = incompleteReasonFromEvent(event);
|
|
323
331
|
if (isMaxOutputIncompleteReason(reason)) return settleMaxOutputIncomplete(event, state, ctx, reason);
|
|
324
|
-
throw withIncompleteUsage(new Error(
|
|
332
|
+
throw withIncompleteUsage(new Error(`${streamLabel(ctx)} stream response.incomplete: ${reason}`), event, state);
|
|
325
333
|
}
|
|
326
334
|
|
|
327
|
-
function onError(event) {
|
|
335
|
+
function onError(event, _state, ctx) {
|
|
328
336
|
const msg = event.message || event.error?.message || 'unknown';
|
|
329
|
-
throw typedResponsesFailure(
|
|
337
|
+
throw typedResponsesFailure(`${streamLabel(ctx)} stream error: ${msg}`, event);
|
|
330
338
|
}
|
|
331
339
|
|
|
332
340
|
const RESPONSES_EVENT_HANDLERS = new Map([
|
|
@@ -139,11 +139,11 @@ export function createResponsesOutcomeStamper(state, leakedCalls) {
|
|
|
139
139
|
}
|
|
140
140
|
|
|
141
141
|
/** A streamed function_call whose id/name never arrived cannot be dispatched. */
|
|
142
|
-
export function unresolvedSalvageError(state) {
|
|
142
|
+
export function unresolvedSalvageError(state, label) {
|
|
143
143
|
const unresolved = state.toolCalls.find((t) => t._pendingItemId);
|
|
144
144
|
if (!unresolved) return null;
|
|
145
145
|
return new Error(
|
|
146
|
-
|
|
146
|
+
`${label || 'compat Responses'} stream function_call salvage failed: missing call_id/name for item_id=${unresolved._pendingItemId || '?'}`
|
|
147
147
|
);
|
|
148
148
|
}
|
|
149
149
|
|
|
@@ -169,5 +169,6 @@ export function finalizeResponsesStream(state, { leakedCalls, parseResponsesTool
|
|
|
169
169
|
model: state.model || response.model || null,
|
|
170
170
|
responseId: state.responseId || response.id || null,
|
|
171
171
|
stopReason: state.stopReason || null,
|
|
172
|
+
reasoningEmitted: state.emittedReasoning === true,
|
|
172
173
|
};
|
|
173
174
|
}
|