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
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import { GoogleGenerativeAI } from '@google/generative-ai';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { reloadProviderApiKey, resolveProviderApiKey } from '../../../shared/provider-api-key.mjs';
|
|
3
|
+
import {
|
|
4
|
+
canFallbackNonStreaming,
|
|
5
|
+
emitProviderRetryStage,
|
|
6
|
+
markProviderRecoveryExhausted,
|
|
7
|
+
withRetry,
|
|
8
|
+
} from './retry-classifier.mjs';
|
|
4
9
|
import { noteErrorUsage } from './lib/note-error-usage.mjs';
|
|
5
10
|
import { traceNonStreamingFallback } from './lib/transport-fallback-trace.mjs';
|
|
6
11
|
import {
|
|
@@ -12,6 +17,13 @@ import {
|
|
|
12
17
|
} from '../stall-policy.mjs';
|
|
13
18
|
import { getLlmDispatcher, preconnect } from '../../../shared/llm/http-agent.mjs';
|
|
14
19
|
import { GEMINI_FIRST_BYTE_TIMEOUT_MS, consumeGeminiRestStreamResponse } from './gemini-stream.mjs';
|
|
20
|
+
import { applyGeminiErrorContract } from './gemini-error-contract.mjs';
|
|
21
|
+
import {
|
|
22
|
+
GEMINI_MIDSTREAM_MAX_ATTEMPTS,
|
|
23
|
+
geminiEndsWithFunctionResponse,
|
|
24
|
+
geminiInvalidStreamReason,
|
|
25
|
+
runGeminiStreamAttempts,
|
|
26
|
+
} from './gemini-retry-policy.mjs';
|
|
15
27
|
import { geminiTextLeakGuardFor, streamGeminiSdkAttempt } from './gemini-sdk-request.mjs';
|
|
16
28
|
import { emitGeminiToolCalls } from './gemini-schema.mjs';
|
|
17
29
|
import { buildGeminiRequest, geminiCachedRestBody } from './gemini-request-body.mjs';
|
|
@@ -32,6 +44,8 @@ import {
|
|
|
32
44
|
GEMINI_GLOBAL_CACHE_DELETE_GRACE_MS,
|
|
33
45
|
_geminiCredentialFingerprint,
|
|
34
46
|
_invalidateGeminiCachesForCredentialFingerprint,
|
|
47
|
+
geminiExplicitCacheRefused,
|
|
48
|
+
markGeminiExplicitCacheRefused,
|
|
35
49
|
} from './gemini-cache.mjs';
|
|
36
50
|
import {
|
|
37
51
|
awaitSharedCreate,
|
|
@@ -59,7 +73,7 @@ import {
|
|
|
59
73
|
let _modelRefreshInFlight = null;
|
|
60
74
|
const GEMINI_AVAILABILITY_TIMEOUT_MS = 1_000;
|
|
61
75
|
|
|
62
|
-
function geminiRestError(res, text, label) {
|
|
76
|
+
export function geminiRestError(res, text, label) {
|
|
63
77
|
let payload = null;
|
|
64
78
|
try {
|
|
65
79
|
payload = text ? JSON.parse(text) : null;
|
|
@@ -78,16 +92,11 @@ function geminiRestError(res, text, label) {
|
|
|
78
92
|
err.error = detail;
|
|
79
93
|
err.data = payload;
|
|
80
94
|
if (detail.status) err.geminiStatus = detail.status;
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
//
|
|
84
|
-
//
|
|
85
|
-
|
|
86
|
-
// A 429 RESOURCE_EXHAUSTED is a request-local rate limit even without
|
|
87
|
-
// Retry-After (Google/LiteLLM retry). Do not stamp it as a quota code.
|
|
88
|
-
if (detail.status && (retryAfter == null || retryAfter === '') && res.status !== 429) {
|
|
89
|
-
err.code = detail.status;
|
|
90
|
-
}
|
|
95
|
+
const details = detail.details ?? detail.errorDetails;
|
|
96
|
+
if (Array.isArray(details)) err.details = details;
|
|
97
|
+
// Typed contract (code/retryAfterMs/resetAt/quotaScope); the core decides
|
|
98
|
+
// whether a 429 RESOURCE_EXHAUSTED is request-local or a quota refusal.
|
|
99
|
+
applyGeminiErrorContract(err, { details, googleStatus: detail.status, message: detail.message });
|
|
91
100
|
}
|
|
92
101
|
return err;
|
|
93
102
|
}
|
|
@@ -139,6 +148,9 @@ export class GeminiProvider {
|
|
|
139
148
|
// input already includes cache. See registry.mjs.
|
|
140
149
|
static inputExcludesCache = false;
|
|
141
150
|
name = 'gemini';
|
|
151
|
+
// The two-phase ladder (gemini-retry-policy.mjs) is the whole recovery:
|
|
152
|
+
// a spent ladder surfaces instead of parking on loop recovery cycles.
|
|
153
|
+
retryPolicy = Object.freeze({ recoveryCycles: false });
|
|
142
154
|
genAI;
|
|
143
155
|
config;
|
|
144
156
|
_fetch;
|
|
@@ -153,8 +165,9 @@ export class GeminiProvider {
|
|
|
153
165
|
this._createGenAI =
|
|
154
166
|
typeof config.createGenAI === 'function' ? config.createGenAI : (apiKey) => new GoogleGenerativeAI(apiKey);
|
|
155
167
|
this._modelCache = config.modelCache || _modelCache;
|
|
156
|
-
|
|
157
|
-
this.
|
|
168
|
+
this._injectedGenAI = Boolean(config.genAI);
|
|
169
|
+
this._genAIKey = resolveProviderApiKey('gemini', config);
|
|
170
|
+
this.genAI = config.genAI || this._createGenAI(this._genAIKey);
|
|
158
171
|
// Warm a kept-alive socket to the Gemini REST API so the first cache/
|
|
159
172
|
// generateContent request skips the cold TLS handshake. Best-effort.
|
|
160
173
|
this._preconnect('https://generativelanguage.googleapis.com');
|
|
@@ -162,12 +175,13 @@ export class GeminiProvider {
|
|
|
162
175
|
|
|
163
176
|
reloadApiKey() {
|
|
164
177
|
try {
|
|
165
|
-
const newKey =
|
|
178
|
+
const newKey = reloadProviderApiKey('gemini', this.config);
|
|
166
179
|
if (newKey) {
|
|
167
|
-
// Keep this.config in sync so REST/cache paths
|
|
168
|
-
// key
|
|
169
|
-
// the stale key after a rotation; genAI alone is not enough.
|
|
180
|
+
// Keep this.config in sync so REST/cache paths don't keep using the
|
|
181
|
+
// stale key after a rotation; genAI alone is not enough.
|
|
170
182
|
this.config = { ...(this.config || {}), apiKey: newKey };
|
|
183
|
+
this._injectedGenAI = false;
|
|
184
|
+
this._genAIKey = newKey;
|
|
171
185
|
this.genAI = this._createGenAI(newKey);
|
|
172
186
|
}
|
|
173
187
|
return newKey || '';
|
|
@@ -178,7 +192,18 @@ export class GeminiProvider {
|
|
|
178
192
|
}
|
|
179
193
|
|
|
180
194
|
_getApiKey() {
|
|
181
|
-
return this.config
|
|
195
|
+
return resolveProviderApiKey('gemini', this.config);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// SDK client for the currently resolved key; rebuilt when the key changed
|
|
199
|
+
// since construction (e.g. a keyless-constructed instance).
|
|
200
|
+
_currentGenAI() {
|
|
201
|
+
const key = this._getApiKey();
|
|
202
|
+
if (!this._injectedGenAI && key !== this._genAIKey) {
|
|
203
|
+
this._genAIKey = key;
|
|
204
|
+
this.genAI = this._createGenAI(key);
|
|
205
|
+
}
|
|
206
|
+
return this.genAI;
|
|
182
207
|
}
|
|
183
208
|
|
|
184
209
|
/**
|
|
@@ -250,7 +275,7 @@ export class GeminiProvider {
|
|
|
250
275
|
if (decision.canReuseState) {
|
|
251
276
|
return state.cacheName;
|
|
252
277
|
}
|
|
253
|
-
if (!apiKey) return null;
|
|
278
|
+
if (!apiKey || geminiExplicitCacheRefused(model)) return null;
|
|
254
279
|
const { canAttachState } = decision;
|
|
255
280
|
if (geminiPrefixBelowMinimum({ model, systemInstruction, geminiTools, contents, opts, currentIter })) {
|
|
256
281
|
return canAttachState ? state.cacheName : null;
|
|
@@ -430,6 +455,7 @@ export class GeminiProvider {
|
|
|
430
455
|
_setGeminiGlobalCache(globalCacheKey, entry);
|
|
431
456
|
return entry;
|
|
432
457
|
} catch (err) {
|
|
458
|
+
markGeminiExplicitCacheRefused(model, err);
|
|
433
459
|
process.stderr.write(`[gemini] cachedContents.create error: ${err?.message || err}\n`);
|
|
434
460
|
return null;
|
|
435
461
|
}
|
|
@@ -561,7 +587,18 @@ export class GeminiProvider {
|
|
|
561
587
|
emitGeminiToolCalls(parsed.nativeToolCalls, callbacks.onToolCall);
|
|
562
588
|
const usage = resolveGeminiUsage(response, opts, cachedContent, useModel);
|
|
563
589
|
const incomplete = geminiIncompleteError(response, parsed, useModel, usage);
|
|
564
|
-
if (incomplete)
|
|
590
|
+
if (incomplete) {
|
|
591
|
+
// A malformed / unexpected tool call that survived the stream ladder
|
|
592
|
+
// (4 attempts) is spent; the loop must not multiply that budget.
|
|
593
|
+
if (
|
|
594
|
+
geminiInvalidStreamReason(response, textLeakGuard, {
|
|
595
|
+
afterToolResult: geminiEndsWithFunctionResponse(request.contents),
|
|
596
|
+
})
|
|
597
|
+
) {
|
|
598
|
+
markProviderRecoveryExhausted(incomplete, { owner: 'gemini-stream', attempts: GEMINI_MIDSTREAM_MAX_ATTEMPTS });
|
|
599
|
+
}
|
|
600
|
+
throw incomplete;
|
|
601
|
+
}
|
|
565
602
|
return geminiSendResult(parsed, useModel, opts, usage);
|
|
566
603
|
}
|
|
567
604
|
|
|
@@ -630,12 +667,19 @@ export class GeminiProvider {
|
|
|
630
667
|
const restPassthrough = createPassthroughSignal(signal);
|
|
631
668
|
const totalSignal = restPassthrough.signal;
|
|
632
669
|
try {
|
|
633
|
-
|
|
634
|
-
|
|
670
|
+
const afterToolResult = geminiEndsWithFunctionResponse(contents);
|
|
671
|
+
return await runGeminiStreamAttempts({
|
|
672
|
+
signal: totalSignal,
|
|
673
|
+
sleepFn: this.config?.sleepFn,
|
|
674
|
+
onRetry: geminiRetryLogger(opts, '[gemini-rest]'),
|
|
675
|
+
afterToolResult,
|
|
676
|
+
run: async ({ signal: attemptSignal, connected }) => {
|
|
635
677
|
signalRequesting(opts);
|
|
636
678
|
const res = await this._openRestStream(genUrl, body, attemptSignal);
|
|
679
|
+
connected();
|
|
637
680
|
const textLeakGuard = geminiTextLeakGuardFor(stream);
|
|
638
681
|
const response = await consumeGeminiRestStreamResponse(res, {
|
|
682
|
+
acceptEmptyNoFinish: afterToolResult,
|
|
639
683
|
signal: attemptSignal,
|
|
640
684
|
onStreamDelta: callbacks.onStreamDelta,
|
|
641
685
|
onTextDelta: callbacks.onTextDelta,
|
|
@@ -645,8 +689,7 @@ export class GeminiProvider {
|
|
|
645
689
|
});
|
|
646
690
|
return { response, textLeakGuard };
|
|
647
691
|
},
|
|
648
|
-
|
|
649
|
-
);
|
|
692
|
+
});
|
|
650
693
|
} catch (err) {
|
|
651
694
|
if (
|
|
652
695
|
!internal.skipExplicitCache &&
|
|
@@ -673,7 +716,7 @@ export class GeminiProvider {
|
|
|
673
716
|
|
|
674
717
|
async _streamViaSdk(stream) {
|
|
675
718
|
const { opts, signal, useModel, systemInstruction, geminiTools, toolConfig, generationConfig, contents } = stream;
|
|
676
|
-
const genModel = this.
|
|
719
|
+
const genModel = this._currentGenAI().getGenerativeModel({
|
|
677
720
|
model: useModel,
|
|
678
721
|
systemInstruction,
|
|
679
722
|
tools: geminiTools,
|
|
@@ -685,13 +728,16 @@ export class GeminiProvider {
|
|
|
685
728
|
const sdkPassthrough = createPassthroughSignal(signal);
|
|
686
729
|
const totalSignal = sdkPassthrough.signal;
|
|
687
730
|
try {
|
|
688
|
-
return await
|
|
689
|
-
|
|
731
|
+
return await runGeminiStreamAttempts({
|
|
732
|
+
signal: totalSignal,
|
|
733
|
+
sleepFn: this.config?.sleepFn,
|
|
734
|
+
onRetry: geminiRetryLogger(opts, '[gemini]'),
|
|
735
|
+
afterToolResult: geminiEndsWithFunctionResponse(contents),
|
|
736
|
+
run: async ({ signal: attemptSignal, connected }) => {
|
|
690
737
|
signalRequesting(opts);
|
|
691
|
-
return await streamGeminiSdkAttempt(genModel, stream, attemptSignal);
|
|
738
|
+
return await streamGeminiSdkAttempt(genModel, stream, attemptSignal, connected);
|
|
692
739
|
},
|
|
693
|
-
|
|
694
|
-
);
|
|
740
|
+
});
|
|
695
741
|
} catch (err) {
|
|
696
742
|
const recovered = await this._recoverGeminiNonStreaming({
|
|
697
743
|
streamErr: err,
|
|
@@ -714,7 +760,7 @@ export class GeminiProvider {
|
|
|
714
760
|
const cached = this._modelCache.loadSync();
|
|
715
761
|
if (cached) return cached;
|
|
716
762
|
// Dynamic lookup via Gemini v1beta /models. Requires API key.
|
|
717
|
-
const apiKey = this.
|
|
763
|
+
const apiKey = this._getApiKey();
|
|
718
764
|
if (!apiKey) return MODELS; // no key — return minimal static list
|
|
719
765
|
try {
|
|
720
766
|
return await this._fetchAndCacheModels(apiKey);
|
|
@@ -738,26 +784,26 @@ export class GeminiProvider {
|
|
|
738
784
|
|
|
739
785
|
// Force a catalog refresh (ignores the 24h disk TTL). De-duped via
|
|
740
786
|
// _modelRefreshInFlight so concurrent callers share one HTTP round-trip.
|
|
741
|
-
//
|
|
787
|
+
// Resolves null when there is no key; fetch/normalize failures reject so
|
|
788
|
+
// callers (registry refresh) report them.
|
|
742
789
|
async _refreshModelCache() {
|
|
743
790
|
if (_modelRefreshInFlight) return _modelRefreshInFlight;
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
return enriched;
|
|
752
|
-
} catch (err) {
|
|
753
|
-
if (!process.env.MIXDOG_QUIET_PROVIDER_LOG)
|
|
754
|
-
process.stderr.write(`[gemini] catalog refresh failed (${err.message})\n`);
|
|
755
|
-
return null;
|
|
756
|
-
} finally {
|
|
757
|
-
_modelRefreshInFlight = null;
|
|
758
|
-
}
|
|
791
|
+
const refresh = (async () => {
|
|
792
|
+
const apiKey = this._getApiKey();
|
|
793
|
+
if (!apiKey) return null; // no key — nothing to refresh
|
|
794
|
+
const enriched = await this._fetchAndCacheModels(apiKey);
|
|
795
|
+
if (!process.env.MIXDOG_QUIET_PROVIDER_LOG)
|
|
796
|
+
process.stderr.write(`[gemini] catalog refreshed (${enriched.length} models)\n`);
|
|
797
|
+
return enriched;
|
|
759
798
|
})();
|
|
760
|
-
|
|
799
|
+
// Clear only after the shared promise is published: a refresh that settles
|
|
800
|
+
// synchronously (no key) must not leave its settled promise memoized.
|
|
801
|
+
_modelRefreshInFlight = refresh;
|
|
802
|
+
try {
|
|
803
|
+
return await refresh;
|
|
804
|
+
} finally {
|
|
805
|
+
if (_modelRefreshInFlight === refresh) _modelRefreshInFlight = null;
|
|
806
|
+
}
|
|
761
807
|
}
|
|
762
808
|
|
|
763
809
|
async isAvailable() {
|
|
@@ -766,7 +812,7 @@ export class GeminiProvider {
|
|
|
766
812
|
controller.abort(providerTimeoutError('Gemini availability probe', GEMINI_AVAILABILITY_TIMEOUT_MS));
|
|
767
813
|
}, GEMINI_AVAILABILITY_TIMEOUT_MS);
|
|
768
814
|
try {
|
|
769
|
-
const model = this.
|
|
815
|
+
const model = this._currentGenAI().getGenerativeModel({ model: DEFAULT_MODEL });
|
|
770
816
|
const generation = Promise.resolve(model.generateContent('hi', { signal: controller.signal }));
|
|
771
817
|
generation.catch(() => {});
|
|
772
818
|
await Promise.race([
|
|
@@ -333,6 +333,9 @@ async function _postRefresh(tokens) {
|
|
|
333
333
|
isTerminalRefresh,
|
|
334
334
|
reauthRequired: isTerminalRefresh,
|
|
335
335
|
oauthError: oauthError || null,
|
|
336
|
+
status: res.status,
|
|
337
|
+
headers: res.headers,
|
|
338
|
+
...(oauthError ? { code: oauthError } : {}),
|
|
336
339
|
});
|
|
337
340
|
}
|
|
338
341
|
const accessToken = json?.access_token;
|
|
@@ -18,6 +18,8 @@ import { enrichModels, getModelMetadataSync } from './model-catalog.mjs';
|
|
|
18
18
|
import { sanitizeModelList } from './model-list-sanitize.mjs';
|
|
19
19
|
import { makeModelCache } from './model-cache.mjs';
|
|
20
20
|
import { OpenAICompatProvider, preloadOpenAICompatRuntime } from './openai-compat.mjs';
|
|
21
|
+
import { xaiModelSupportsReasoningEffort } from './openai-compat-xai.mjs';
|
|
22
|
+
import { XAI_COMPAT_RETRY_POLICY } from './openai-compat-retry-profile.mjs';
|
|
21
23
|
import { createTimeoutSignal } from '../stall-policy.mjs';
|
|
22
24
|
import { getLlmDispatcher, preconnect } from '../../../shared/llm/http-agent.mjs';
|
|
23
25
|
import { normalizeGrokToolSchemas } from './lib/grok-tool-schema.mjs';
|
|
@@ -48,19 +50,44 @@ export {
|
|
|
48
50
|
} from './grok-oauth-tokens.mjs';
|
|
49
51
|
export { beginOAuthLogin, loginOAuth } from './grok-oauth-login.mjs';
|
|
50
52
|
|
|
53
|
+
// Typed wire codes that say the bearer itself expired or was revoked. An
|
|
54
|
+
// ordinary permission 403 carries none of them and is never a refresh signal.
|
|
55
|
+
const EXPIRED_TOKEN_CODES = new Set([
|
|
56
|
+
'token_expired',
|
|
57
|
+
'expired_token',
|
|
58
|
+
'access_token_expired',
|
|
59
|
+
'token_revoked',
|
|
60
|
+
'revoked_token',
|
|
61
|
+
'invalid_token',
|
|
62
|
+
]);
|
|
63
|
+
|
|
64
|
+
function hasExpiredTokenSignature(err) {
|
|
65
|
+
return [err?.code, err?.type, err?.providerErrorCode, err?.error?.code, err?.error?.type].some(
|
|
66
|
+
(field) => typeof field === 'string' && EXPIRED_TOKEN_CODES.has(field.trim().toLowerCase())
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
|
|
51
70
|
const _modelCache = makeModelCache({
|
|
52
71
|
fileName: 'grok-oauth-models.json',
|
|
53
72
|
ttlMs: MODEL_CACHE_TTL_MS,
|
|
54
73
|
version: GROK_MODEL_CACHE_SCHEMA_VERSION,
|
|
55
74
|
});
|
|
56
75
|
|
|
57
|
-
|
|
76
|
+
// A model takes a reasoning effort when its own roster row or the catalog
|
|
77
|
+
// publishes effort values; otherwise the shared xAI rule decides (catalog row
|
|
78
|
+
// first, then pass-through). Two id tokens are kept: xAI's own
|
|
79
|
+
// `non-reasoning` variant marker, and the Build endpoint family. Neither
|
|
80
|
+
// publishes capabilities, and both 400 on any effort.
|
|
81
|
+
function _grokModelSupportsEffort(id, model = null) {
|
|
58
82
|
const text = String(id || '').toLowerCase();
|
|
59
83
|
if (!text) return false;
|
|
60
84
|
if (NON_CHAT_MODEL_RE.test(text)) return false;
|
|
61
|
-
if (
|
|
62
|
-
if (
|
|
63
|
-
|
|
85
|
+
if (_grokCatalogEffortValues(model).length || _grokApiEffortValues(model).length) return true;
|
|
86
|
+
if (/non[-_]?reasoning/.test(text)) return false;
|
|
87
|
+
// Build endpoint models reject reasoning_effort outright; a catalog or
|
|
88
|
+
// roster that publishes effort values has already answered above.
|
|
89
|
+
if (/^grok[-_]build/.test(text)) return false;
|
|
90
|
+
return xaiModelSupportsReasoningEffort(text);
|
|
64
91
|
}
|
|
65
92
|
|
|
66
93
|
// Pre-catalog fallback matches Grok 4.5 (low/medium/high). Grok 4.6 adds
|
|
@@ -86,7 +113,8 @@ function _grokApiEffortValues(model) {
|
|
|
86
113
|
model?.reasoningEfforts ??
|
|
87
114
|
model?.reasoning_efforts ??
|
|
88
115
|
model?._meta?.reasoningEfforts ??
|
|
89
|
-
model?._meta?.reasoning_efforts
|
|
116
|
+
model?._meta?.reasoning_efforts ??
|
|
117
|
+
model?.capabilities?.reasoning_effort;
|
|
90
118
|
return Array.isArray(raw) ? _uniqueKnownGrokEfforts(raw) : [];
|
|
91
119
|
}
|
|
92
120
|
|
|
@@ -103,7 +131,7 @@ function _grokCatalogEffortValues(model) {
|
|
|
103
131
|
}
|
|
104
132
|
|
|
105
133
|
function _grokReasoningLevels(id, model) {
|
|
106
|
-
if (!_grokModelSupportsEffort(id)) return [];
|
|
134
|
+
if (!_grokModelSupportsEffort(id, model)) return [];
|
|
107
135
|
const catalog = _grokCatalogEffortValues(model);
|
|
108
136
|
if (catalog.length) return catalog;
|
|
109
137
|
const api = _grokApiEffortValues(model);
|
|
@@ -144,13 +172,14 @@ function _normalizeGrokModel(m) {
|
|
|
144
172
|
const contextWindow = _grokApiContextWindow(m);
|
|
145
173
|
const apiEfforts = _grokApiEffortValues(m);
|
|
146
174
|
const reasoningOptions = apiEfforts.length ? [{ type: 'effort', values: apiEfforts }] : undefined;
|
|
175
|
+
const row = { ...m, reasoningOptions };
|
|
147
176
|
return {
|
|
148
177
|
id,
|
|
149
178
|
name: id,
|
|
150
179
|
display: _displayGrokModel(m),
|
|
151
180
|
provider: 'grok-oauth',
|
|
152
|
-
family: _normalizeGrokFamily(id),
|
|
153
|
-
reasoningLevels: _grokReasoningLevels(id,
|
|
181
|
+
family: _normalizeGrokFamily(id, row),
|
|
182
|
+
reasoningLevels: _grokReasoningLevels(id, row),
|
|
154
183
|
...(reasoningOptions ? { reasoningOptions } : {}),
|
|
155
184
|
tier: 'version',
|
|
156
185
|
latest: false,
|
|
@@ -165,7 +194,7 @@ function _sanitizeGrokModels(models) {
|
|
|
165
194
|
const next = models.map((m) => {
|
|
166
195
|
let out = m;
|
|
167
196
|
const display = _displayGrokModel(m);
|
|
168
|
-
const family = _normalizeGrokFamily(m?.id);
|
|
197
|
+
const family = _normalizeGrokFamily(m?.id, out);
|
|
169
198
|
const reasoningLevels = _grokReasoningLevels(m?.id, out);
|
|
170
199
|
// api.x.ai /models does not expose a max-output field. Historical
|
|
171
200
|
// enrichment could persist contextWindow as outputTokens (for example
|
|
@@ -248,6 +277,15 @@ function resolveLatestGrokModel() {
|
|
|
248
277
|
return _newestDatedGrokChatModel(cached)?.id || null;
|
|
249
278
|
}
|
|
250
279
|
|
|
280
|
+
// Whether a request for this model may carry an effort: the levels its cached
|
|
281
|
+
// roster row already resolved from the roster and catalog answer, else the id
|
|
282
|
+
// alone follows the catalog rule.
|
|
283
|
+
function _grokSendSupportsEffort(id) {
|
|
284
|
+
const cached = _modelCache.loadSync();
|
|
285
|
+
const row = Array.isArray(cached) ? cached.find((m) => m?.id === id) : null;
|
|
286
|
+
return Array.isArray(row?.reasoningLevels) ? row.reasoningLevels.length > 0 : _grokModelSupportsEffort(id);
|
|
287
|
+
}
|
|
288
|
+
|
|
251
289
|
async function ensureLatestGrokModel(provider) {
|
|
252
290
|
let m = resolveLatestGrokModel();
|
|
253
291
|
if (m) return m;
|
|
@@ -265,6 +303,8 @@ export class GrokOAuthProvider {
|
|
|
265
303
|
// OpenAI-compatible usage: prompt_tokens includes cached. See registry.mjs.
|
|
266
304
|
static inputExcludesCache = false;
|
|
267
305
|
name = 'grok-oauth';
|
|
306
|
+
// The inner xai profile's limits are final: no loop-level recovery cycles on top.
|
|
307
|
+
retryPolicy = XAI_COMPAT_RETRY_POLICY;
|
|
268
308
|
config;
|
|
269
309
|
tokens = null;
|
|
270
310
|
_inner = null;
|
|
@@ -395,11 +435,12 @@ export class GrokOAuthProvider {
|
|
|
395
435
|
});
|
|
396
436
|
const inner = this._ensureInner(tokens.access_token, useModel, requestHeaders);
|
|
397
437
|
const grokTools = normalizeGrokToolSchemas(tools);
|
|
398
|
-
// Effort-less models
|
|
399
|
-
//
|
|
400
|
-
//
|
|
401
|
-
//
|
|
402
|
-
|
|
438
|
+
// Effort-less models: the service 400s on ANY reasoningEffort parameter,
|
|
439
|
+
// and pinned model settings can carry one (e.g. the bench harness pins
|
|
440
|
+
// effort per route). Strip it here so a saved effort never breaks a model
|
|
441
|
+
// that cannot accept it. The model's own roster row decides; a model not
|
|
442
|
+
// on the roster yet follows the catalog rule.
|
|
443
|
+
if (sendOpts && !_grokSendSupportsEffort(useModel)) {
|
|
403
444
|
// 'none' (not null) so the ?? fallback chain in the xai builder
|
|
404
445
|
// cannot fall through to a config/env effort; the normalizer maps
|
|
405
446
|
// it to "omit the parameter".
|
|
@@ -414,9 +455,10 @@ export class GrokOAuthProvider {
|
|
|
414
455
|
return await inner._doSend(messages, useModel, grokTools, sendOpts);
|
|
415
456
|
} catch (err) {
|
|
416
457
|
noteErrorUsage(err);
|
|
417
|
-
// Refresh-and-retry on a server-rejected OAuth session
|
|
418
|
-
//
|
|
419
|
-
// text is never
|
|
458
|
+
// Refresh-and-retry on a server-rejected OAuth session: 401, or a 403
|
|
459
|
+
// carrying an explicit expired/revoked-token code. TYPED evidence only:
|
|
460
|
+
// message text is never an auth verdict, and a plain permission 403 is
|
|
461
|
+
// surfaced as-is.
|
|
420
462
|
const rejectedStatus = Number(err?.httpStatus || err?.status);
|
|
421
463
|
// 426 = client version gate. Retry once only when the body stated a
|
|
422
464
|
// minimum we did not already satisfy; nothing was emitted before it.
|
|
@@ -434,7 +476,7 @@ export class GrokOAuthProvider {
|
|
|
434
476
|
sendOpts
|
|
435
477
|
);
|
|
436
478
|
}
|
|
437
|
-
if (rejectedStatus === 401 || rejectedStatus === 403) {
|
|
479
|
+
if (rejectedStatus === 401 || (rejectedStatus === 403 && hasExpiredTokenSignature(err))) {
|
|
438
480
|
// A stream-level rejection after text/tool dispatch cannot be safely
|
|
439
481
|
// replayed: the client has already observed output or may have
|
|
440
482
|
// executed a side-effecting tool.
|
|
@@ -444,7 +486,14 @@ export class GrokOAuthProvider {
|
|
|
444
486
|
process.stderr.write(`[grok-oauth] ${rejectedStatus}, force-refreshing token...\n`);
|
|
445
487
|
const fresh = await this.ensureAuth({ forceRefresh: true });
|
|
446
488
|
const retryInner = this._ensureInner(fresh.access_token, useModel, requestHeaders);
|
|
447
|
-
|
|
489
|
+
try {
|
|
490
|
+
return await retryInner._doSend(messages, useModel, grokTools, sendOpts);
|
|
491
|
+
} catch (retryErr) {
|
|
492
|
+
// Rejected again on a token that was just refreshed: re-login is the
|
|
493
|
+
// only remaining path.
|
|
494
|
+
if (Number(retryErr?.httpStatus || retryErr?.status) === 401) retryErr.reauthRequired = true;
|
|
495
|
+
throw retryErr;
|
|
496
|
+
}
|
|
448
497
|
}
|
|
449
498
|
throw err;
|
|
450
499
|
}
|
|
@@ -79,7 +79,13 @@ function resolveLatestGeminiModel() {
|
|
|
79
79
|
export async function ensureLatestGeminiModel(provider) {
|
|
80
80
|
let model = resolveLatestGeminiModel();
|
|
81
81
|
if (model) return model;
|
|
82
|
-
|
|
82
|
+
try {
|
|
83
|
+
await provider._refreshModelCache();
|
|
84
|
+
} catch (err) {
|
|
85
|
+
throw new Error(`[gemini] model catalog refresh failed — cannot resolve default model (${err.message})`, {
|
|
86
|
+
cause: err,
|
|
87
|
+
});
|
|
88
|
+
}
|
|
83
89
|
model = resolveLatestGeminiModel();
|
|
84
90
|
if (model) return model;
|
|
85
91
|
throw new Error('[gemini] model catalog unavailable after warmup — cannot resolve default model');
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
import { noteErrorUsage } from './lib/note-error-usage.mjs';
|
|
10
10
|
import { fileMtimeMs, scrubOAuthSecrets } from './lib/oauth-token-utils.mjs';
|
|
11
11
|
import { OpenAICompatProvider, preloadOpenAICompatRuntime } from './openai-compat.mjs';
|
|
12
|
+
import { COMPAT_RETRY_POLICY } from './openai-compat-retry-profile.mjs';
|
|
12
13
|
import { fetchCompatModelItems, listCompatModels } from './openai-compat-models.mjs';
|
|
13
14
|
import { makeModelCache } from './model-cache.mjs';
|
|
14
15
|
import {
|
|
@@ -114,6 +115,8 @@ export class MimoOAuthProvider {
|
|
|
114
115
|
// OpenAI-compatible usage: prompt_tokens includes cached. See registry.mjs.
|
|
115
116
|
static inputExcludesCache = false;
|
|
116
117
|
name = 'mimo-oauth';
|
|
118
|
+
// The retry profile's limits are final: no loop-level recovery cycles on top.
|
|
119
|
+
retryPolicy = COMPAT_RETRY_POLICY;
|
|
117
120
|
config;
|
|
118
121
|
tokens = null;
|
|
119
122
|
_inner = null;
|
|
@@ -208,7 +208,8 @@ function _stalenessFamily(row, id) {
|
|
|
208
208
|
const modelId = String(id || row?.id || row?.name || '')
|
|
209
209
|
.trim()
|
|
210
210
|
.toLowerCase();
|
|
211
|
-
|
|
211
|
+
// Claude ids name their family right after the brand (`claude-<family>-<version>`).
|
|
212
|
+
const claude = modelId.match(/(?:^|\/)claude-([a-z]+)(?:-|$)/);
|
|
212
213
|
if (claude) return `claude-${claude[1]}`;
|
|
213
214
|
const family = row && typeof row.family === 'string' ? row.family.trim().toLowerCase() : '';
|
|
214
215
|
return family || null;
|