mixdog 1.3.4 → 1.4.0
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/LICENSES/oh-my-pi-MIT.txt +23 -0
- package/NOTICE.md +17 -2
- package/README.md +11 -0
- package/package.json +3 -11
- package/scripts/daemon-stub.mjs +1 -1
- package/scripts/embed-google-oauth-client.mjs +49 -0
- package/scripts/gate-local.mjs +4 -2
- package/scripts/lib/test-spawn-ledger.mjs +46 -1
- package/scripts/native-release-status.mjs +2 -2
- package/scripts/recall-history-cases.json +1 -1
- package/scripts/suite-health.mjs +10 -1
- package/scripts/test.mjs +12 -11
- package/src/agents/reviewer/AGENT.md +7 -11
- package/src/agents/reviewer/agent.json +1 -1
- package/src/defaults/shipped-history.json +25 -1
- package/src/defaults/skills/browser-use/SKILL.md +77 -17
- package/src/defaults/skills/code-tidy/SKILL.md +142 -270
- package/src/defaults/skills/code-tidy/references/agent-cleanup.md +4 -4
- package/src/defaults/skills/code-tidy/references/cleanup-report.md +31 -76
- package/src/defaults/skills/code-tidy/references/dead-code.md +6 -12
- package/src/defaults/skills/computer-use/SKILL.md +33 -9
- package/src/defaults/skills/setup/SKILL.md +29 -2
- package/src/defaults/skills/setup/references/actions.md +117 -28
- package/src/defaults/skills/setup/references/surfaces.md +77 -35
- package/src/defaults/skills/setup-guide/SKILL.md +3 -3
- package/src/defaults/skills/visualize/SKILL.md +2 -1
- package/src/lib/keychain-cjs.cjs +359 -29
- package/src/lib/rules-builder.cjs +10 -8
- package/src/rules/agent/AGENT.md +6 -6
- package/src/rules/agent-mode/AGENT_MODE.md +10 -2
- package/src/rules/agent-mode/MIXY.md +12 -0
- package/src/rules/lead/LEAD.md +18 -20
- package/src/rules/shared/05-tool-calls.md +5 -6
- package/src/rules/shared/10-tool-workflow.md +2 -0
- package/src/rules/shared/60-verification.md +7 -5
- package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +2 -3
- package/src/runtime/agent/orchestrator/agent-runtime/heartbeat-completion.mjs +193 -0
- package/src/runtime/agent/orchestrator/agent-runtime/title-completion.mjs +3 -1
- package/src/runtime/agent/orchestrator/agent-trace-format.mjs +3 -1
- package/src/runtime/agent/orchestrator/config.mjs +34 -0
- package/src/runtime/agent/orchestrator/context/collect.mjs +3 -0
- package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +72 -67
- package/src/runtime/agent/orchestrator/context/skill-catalog.mjs +54 -1
- package/src/runtime/agent/orchestrator/mcp/agent-connectors.mjs +3 -3
- package/src/runtime/agent/orchestrator/mcp/client-transport.mjs +177 -73
- package/src/runtime/agent/orchestrator/mcp/client.mjs +25 -2
- package/src/runtime/agent/orchestrator/mcp/oauth-callback.mjs +31 -2
- package/src/runtime/agent/orchestrator/mcp/oauth-client.mjs +16 -3
- package/src/runtime/agent/orchestrator/mcp/oauth-login.mjs +42 -7
- package/src/runtime/agent/orchestrator/mcp/oauth-provider.mjs +21 -2
- package/src/runtime/agent/orchestrator/mcp/oauth-shared.mjs +23 -0
- package/src/runtime/agent/orchestrator/mcp/oauth.mjs +11 -1
- package/src/runtime/agent/orchestrator/providers/account-pool.mjs +230 -137
- package/src/runtime/agent/orchestrator/providers/admission-scheduler.mjs +64 -7
- package/src/runtime/agent/orchestrator/providers/anthropic-api-request.mjs +18 -5
- package/src/runtime/agent/orchestrator/providers/anthropic-cache-warm.mjs +165 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-credentials.mjs +4 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-request/gzip-post.mjs +14 -14
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +160 -69
- package/src/runtime/agent/orchestrator/providers/anthropic-overload-fallback.mjs +25 -3
- package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +64 -33
- package/src/runtime/agent/orchestrator/providers/anthropic.mjs +135 -87
- package/src/runtime/agent/orchestrator/providers/antigravity-oauth-catalog.mjs +52 -8
- package/src/runtime/agent/orchestrator/providers/antigravity-oauth.mjs +10 -1
- package/src/runtime/agent/orchestrator/providers/antigravity-request.mjs +22 -6
- package/src/runtime/agent/orchestrator/providers/antigravity-response.mjs +15 -4
- package/src/runtime/agent/orchestrator/providers/antigravity-stream.mjs +17 -2
- package/src/runtime/agent/orchestrator/providers/antigravity-transport.mjs +142 -104
- package/src/runtime/agent/orchestrator/providers/cache-warm-admission.mjs +90 -0
- package/src/runtime/agent/orchestrator/providers/codex-client-meta.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/cursor-wire-normalization.mjs +10 -4
- package/src/runtime/agent/orchestrator/providers/cursor-wire-protobuf.mjs +10 -217
- package/src/runtime/agent/orchestrator/providers/cursor-wire-transport.mjs +25 -9
- package/src/runtime/agent/orchestrator/providers/cursor.mjs +22 -6
- package/src/runtime/agent/orchestrator/providers/devin-auth.mjs +409 -0
- package/src/runtime/agent/orchestrator/providers/devin-wire-families.mjs +187 -0
- package/src/runtime/agent/orchestrator/providers/devin-wire-identity.mjs +342 -0
- package/src/runtime/agent/orchestrator/providers/devin-wire-models.mjs +541 -0
- package/src/runtime/agent/orchestrator/providers/devin-wire-protobuf.mjs +305 -0
- package/src/runtime/agent/orchestrator/providers/devin-wire-request.mjs +558 -0
- package/src/runtime/agent/orchestrator/providers/devin-wire-schema.mjs +880 -0
- package/src/runtime/agent/orchestrator/providers/devin-wire-session.mjs +190 -0
- package/src/runtime/agent/orchestrator/providers/devin-wire-tool-args.mjs +351 -0
- package/src/runtime/agent/orchestrator/providers/devin-wire-transport.mjs +560 -0
- package/src/runtime/agent/orchestrator/providers/devin.mjs +491 -0
- package/src/runtime/agent/orchestrator/providers/effort-configuration.mjs +3 -0
- package/src/runtime/agent/orchestrator/providers/gemini-output-limit.mjs +46 -0
- package/src/runtime/agent/orchestrator/providers/gemini-reasoning-relay.mjs +30 -0
- package/src/runtime/agent/orchestrator/providers/gemini-request-body.mjs +7 -11
- package/src/runtime/agent/orchestrator/providers/gemini-retry-policy.mjs +61 -22
- package/src/runtime/agent/orchestrator/providers/gemini-sdk-request.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +71 -4
- package/src/runtime/agent/orchestrator/providers/gemini.mjs +25 -2
- package/src/runtime/agent/orchestrator/providers/grok-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +96 -5
- package/src/runtime/agent/orchestrator/providers/lib/oauth-token-utils.mjs +17 -3
- package/src/runtime/agent/orchestrator/providers/lib/tail-reminder-split.mjs +23 -5
- package/src/runtime/agent/orchestrator/providers/media-normalization.mjs +52 -10
- package/src/runtime/agent/orchestrator/providers/model-proxy-channel.d.mts +8 -1
- package/src/runtime/agent/orchestrator/providers/model-proxy-channel.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/npm-cli-version.mjs +11 -3
- package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +19 -1
- package/src/runtime/agent/orchestrator/providers/oauth-usage.mjs +39 -3
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-state.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/openai-error-contract.mjs +6 -1
- package/src/runtime/agent/orchestrator/providers/openai-oauth-tokens.mjs +10 -9
- package/src/runtime/agent/orchestrator/providers/openai-ws-send/send-context.mjs +22 -3
- package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/attempt-context.mjs +43 -5
- package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/handshake-failure.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/stream-failure.mjs +6 -3
- package/src/runtime/agent/orchestrator/providers/opencode-go-gemini.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/provider-availability.mjs +19 -0
- package/src/runtime/agent/orchestrator/providers/provider-error-kind.mjs +65 -1
- package/src/runtime/agent/orchestrator/providers/quota-reading.mjs +38 -12
- package/src/runtime/agent/orchestrator/providers/registry.mjs +43 -3
- package/src/runtime/agent/orchestrator/providers/retry-executor.mjs +39 -7
- package/src/runtime/agent/orchestrator/providers/statusline-route-meta.mjs +6 -0
- package/src/runtime/agent/orchestrator/providers/wire-protobuf-codec.mjs +368 -0
- package/src/runtime/agent/orchestrator/runtime-core/ask-user-tool-defs.mjs +12 -7
- package/src/runtime/agent/orchestrator/runtime-core/builtin-features.mjs +2 -0
- package/src/runtime/agent/orchestrator/runtime-core/compaction-config-keys.mjs +62 -0
- package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +37 -16
- package/src/runtime/agent/orchestrator/runtime-core/deferred-tool-delta.mjs +100 -23
- package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +1 -1
- package/src/runtime/agent/orchestrator/runtime-core/reaction-tool-defs.mjs +133 -0
- package/src/runtime/agent/orchestrator/runtime-core/session-text.mjs +2 -0
- package/src/runtime/agent/orchestrator/runtime-core/tool-bridge.mjs +19 -4
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog-data.mjs +3 -0
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +125 -30
- package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +23 -5
- package/src/runtime/agent/orchestrator/runtime-core/tool-profile.mjs +35 -10
- package/src/runtime/agent/orchestrator/runtime-core/workflow/agents.mjs +57 -10
- package/src/runtime/agent/orchestrator/runtime-core/workflow/context.mjs +9 -6
- package/src/runtime/agent/orchestrator/runtime-core/workflow-ids.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/agent-loop.mjs +18 -0
- package/src/runtime/agent/orchestrator/session/agent-room.d.mts +0 -3
- package/src/runtime/agent/orchestrator/session/agent-room.mjs +10 -4
- package/src/runtime/agent/orchestrator/session/cache-warm.mjs +792 -0
- package/src/runtime/agent/orchestrator/session/compact/runner.mjs +148 -25
- package/src/runtime/agent/orchestrator/session/compaction-archive-capture.mjs +475 -58
- package/src/runtime/agent/orchestrator/session/compaction-archive.mjs +42 -17
- package/src/runtime/agent/orchestrator/session/eager-dispatch.mjs +8 -0
- package/src/runtime/agent/orchestrator/session/human-gate/gate.mjs +47 -9
- package/src/runtime/agent/orchestrator/session/human-gate/outbound-policy.mjs +6 -2
- package/src/runtime/agent/orchestrator/session/human-gate/requests.mjs +36 -4
- package/src/runtime/agent/orchestrator/session/human-gate/store.mjs +14 -2
- package/src/runtime/agent/orchestrator/session/loop/assistant-commit.mjs +8 -0
- package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +18 -22
- package/src/runtime/agent/orchestrator/session/loop/fresh-context.mjs +32 -3
- package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +11 -2
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/segments.mjs +4 -1
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn.mjs +51 -3
- package/src/runtime/agent/orchestrator/session/loop/route-fallback.mjs +17 -3
- package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +10 -2
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/after-hook.mjs +2 -1
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +14 -4
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +16 -2
- package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +16 -1
- package/src/runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs +10 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-helpers.mjs +3 -10
- package/src/runtime/agent/orchestrator/session/loop/tool-phase.mjs +23 -5
- package/src/runtime/agent/orchestrator/session/loop/turn-limits.mjs +60 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-queue.mjs +12 -2
- package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +19 -1
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-commit.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +133 -90
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-loop-options.mjs +14 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +2 -1
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-state.mjs +31 -4
- package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +30 -18
- package/src/runtime/agent/orchestrator/session/manager/owner-route-fallbacks.mjs +23 -13
- package/src/runtime/agent/orchestrator/session/manager/pending-message-entry.mjs +11 -2
- package/src/runtime/agent/orchestrator/session/manager/provider-replay.mjs +13 -0
- package/src/runtime/agent/orchestrator/session/manager/route-fallback-chain.mjs +129 -0
- package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +20 -2
- package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +8 -0
- package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/manager/session-tool-surface.mjs +13 -0
- package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +7 -2
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-journal.mjs +102 -15
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint.mjs +18 -5
- package/src/runtime/agent/orchestrator/session/message-ids.mjs +5 -3
- package/src/runtime/agent/orchestrator/session/message-reactions.mjs +89 -0
- package/src/runtime/agent/orchestrator/session/message-reactions.test-support.mjs +75 -0
- package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +19 -8
- package/src/runtime/agent/orchestrator/session/prompt-cache-idle-gaps.mjs +113 -0
- package/src/runtime/agent/orchestrator/session/prompt-cache-touch-store.mjs +127 -0
- package/src/runtime/agent/orchestrator/session/routine-result.d.mts +0 -2
- package/src/runtime/agent/orchestrator/session/routine-result.mjs +47 -11
- package/src/runtime/agent/orchestrator/session/send-with-recovery.mjs +20 -2
- package/src/runtime/agent/orchestrator/session/sensitive-projection.mjs +100 -0
- package/src/runtime/agent/orchestrator/session/sensitive-values.mjs +257 -0
- package/src/runtime/agent/orchestrator/session/side-question-store.mjs +20 -7
- package/src/runtime/agent/orchestrator/session/side-question.mjs +18 -0
- package/src/runtime/agent/orchestrator/session/skill-update-notice.mjs +60 -0
- package/src/runtime/agent/orchestrator/session/store/live-state.mjs +6 -3
- package/src/runtime/agent/orchestrator/session/store/save-delta.mjs +9 -5
- package/src/runtime/agent/orchestrator/session/store/serialize.mjs +9 -8
- package/src/runtime/agent/orchestrator/session/store/session-persistence-events.mjs +29 -0
- package/src/runtime/agent/orchestrator/session/store-agent-worker-header-cache.mjs +85 -0
- package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +133 -18
- package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +12 -2
- package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +44 -14
- package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +84 -3
- package/src/runtime/agent/orchestrator/session/stored-attachment-history.mjs +32 -0
- package/src/runtime/agent/orchestrator/session/tail-reminder-rules.mjs +11 -5
- package/src/runtime/agent/orchestrator/session/thinking-binding.mjs +108 -0
- package/src/runtime/agent/orchestrator/session/tool-batch/pre-dispatch.mjs +2 -2
- package/src/runtime/agent/orchestrator/session/tool-batch/record-outcome.mjs +2 -1
- package/src/runtime/agent/orchestrator/session/tool-batch/state.mjs +4 -0
- package/src/runtime/agent/orchestrator/session/tool-batch.mjs +5 -0
- package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +25 -2
- package/src/runtime/agent/orchestrator/session/transcript-restore/tool-result-status.mjs +9 -7
- package/src/runtime/agent/orchestrator/session/transcript-restore/tool-result-text.mjs +2 -2
- package/src/runtime/agent/orchestrator/session/turn-failure.mjs +5 -1
- package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +5 -2
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/backgrounded-result.mjs +12 -1
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/misuse-guard.mjs +240 -0
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/result-format.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/shell-cwd.mjs +38 -0
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +25 -5
- package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +65 -7
- package/src/runtime/agent/orchestrator/tools/builtin/shell-runtime.mjs +7 -1
- package/src/runtime/agent/orchestrator/tools/shell-command.mjs +36 -13
- package/src/runtime/browser-bridge/action-schema.mjs +13 -2
- package/src/runtime/browser-bridge/client.mjs +73 -8
- package/src/runtime/browser-bridge/input-fields.mjs +8 -9
- package/src/runtime/browser-bridge/mail-links.mjs +107 -0
- package/src/runtime/browser-bridge/tool-defs.mjs +1 -1
- package/src/runtime/channels/lib/config.mjs +6 -61
- package/src/runtime/channels/lib/crash-log.mjs +1 -1
- package/src/runtime/channels/lib/event-pipeline.mjs +4 -19
- package/src/runtime/channels/lib/event-queue.mjs +3 -18
- package/src/runtime/channels/lib/owned-runtime/automation-services.mjs +2 -2
- package/src/runtime/channels/lib/owned-runtime/automation-start.mjs +3 -4
- package/src/runtime/channels/lib/owned-runtime/config-reload.mjs +4 -59
- package/src/runtime/channels/lib/owned-runtime/owned-start.mjs +33 -115
- package/src/runtime/channels/lib/owned-runtime/owned-stop.mjs +5 -22
- package/src/runtime/channels/lib/owned-runtime/state.mjs +2 -8
- package/src/runtime/channels/lib/owned-runtime.mjs +6 -23
- package/src/runtime/channels/lib/parent-bridge.mjs +2 -2
- package/src/runtime/channels/lib/runtime-paths.mjs +4 -43
- package/src/runtime/channels/lib/schedule-errors.mjs +51 -0
- package/src/runtime/channels/lib/scheduler.mjs +135 -154
- package/src/runtime/channels/lib/schedules-db.mjs +83 -11
- package/src/runtime/channels/lib/status-snapshot.mjs +1 -1
- package/src/runtime/channels/lib/tool-dispatch.mjs +14 -2
- package/src/runtime/channels/lib/webhooks-db.mjs +5 -9
- package/src/runtime/channels/lib/worker-bootstrap.mjs +0 -1
- package/src/runtime/channels/lib/worker-ipc.mjs +0 -1
- package/src/runtime/channels/lib/worker-main.mjs +19 -34
- package/src/runtime/computer-bridge/action-schema.mjs +42 -1
- package/src/runtime/computer-bridge/actions.mjs +9 -1
- package/src/runtime/computer-bridge/client.mjs +180 -8
- package/src/runtime/computer-bridge/core-actions.mjs +2 -2
- package/src/runtime/computer-bridge/error-recovery.mjs +27 -2
- package/src/runtime/computer-bridge/linux-readiness.mjs +65 -23
- package/src/runtime/computer-bridge/pending-continuation.mjs +1 -1
- package/src/runtime/connectors/connector-accounts-mcp.mjs +230 -0
- package/src/runtime/connectors/gmail-app-password.mjs +172 -39
- package/src/runtime/connectors/google-mcp.mjs +10 -12
- package/src/runtime/memory/lib/pg/adapter.mjs +77 -70
- package/src/runtime/memory/lib/pg/supervisor.mjs +24 -12
- package/src/runtime/memory/lib/runtime-fetcher.mjs +23 -5
- package/src/runtime/office/com/com-adapter.mjs +17 -1
- package/src/runtime/office/com/office-com-host.ps1 +51 -1
- package/src/runtime/office/pdf/cfb-fixture.mjs +328 -0
- package/src/runtime/office/pdf/cfb-protection.mjs +311 -0
- package/src/runtime/office/pdf/document-preview.mjs +326 -8
- package/src/runtime/office/pdf/ooxml-crypto.mjs +469 -0
- package/src/runtime/office/pdf/ooxml-key-worker.mjs +14 -0
- package/src/runtime/office/portable/portable-soffice.mjs +45 -5
- package/src/runtime/session-search/session-search-db.mjs +73 -9
- package/src/runtime/session-search/session-search-ingest.mjs +110 -20
- package/src/runtime/shared/abort-race.mjs +89 -0
- package/src/runtime/shared/agent-avatar.d.mts +0 -1
- package/src/runtime/shared/agent-kind.mjs +4 -3
- package/src/runtime/shared/bot-hops.mjs +62 -2
- package/src/runtime/shared/bounded-download.mjs +8 -3
- package/src/runtime/shared/config.mjs +51 -35
- package/src/runtime/shared/connector-accounts.mjs +20 -10
- package/src/runtime/shared/connector-catalog.d.mts +33 -2
- package/src/runtime/shared/connector-catalog.mjs +166 -8
- package/src/runtime/shared/connector-triggers.mjs +22 -19
- package/src/runtime/shared/defaults-separation.mjs +2 -14
- package/src/runtime/shared/delegated-approval-host.mjs +103 -11
- package/src/runtime/shared/developer-options.mjs +32 -1
- package/src/runtime/shared/err-text.mjs +24 -15
- package/src/runtime/shared/file-permissions.d.mts +0 -8
- package/src/runtime/shared/file-permissions.mjs +0 -11
- package/src/runtime/shared/git-direct.test-support.mjs +19 -0
- package/src/runtime/shared/google-oauth-client.generated.json +4 -0
- package/src/runtime/shared/google-oauth-client.mjs +34 -9
- package/src/runtime/shared/heartbeat-interval.d.mts +4 -0
- package/src/runtime/shared/heartbeat-interval.mjs +19 -0
- package/src/runtime/shared/idle-auto-clear-gate.mjs +104 -0
- package/src/runtime/shared/llm/anthropic-betas.mjs +7 -0
- package/src/runtime/shared/llm/anthropic-thinking-contract.mjs +12 -0
- package/src/runtime/shared/llm/provider-catalog-registry.mjs +1 -0
- package/src/runtime/shared/llm/usage-rollup.mjs +1 -1
- package/src/runtime/shared/llm/well-formed.mjs +66 -0
- package/src/runtime/shared/mixy-presence.mjs +22 -0
- package/src/runtime/shared/orchestration.d.mts +2 -0
- package/src/runtime/shared/pg-schema-db.mjs +27 -16
- package/src/runtime/shared/profile-config.cjs +1 -1
- package/src/runtime/shared/prompt-origin.d.mts +4 -0
- package/src/runtime/shared/prompt-origin.mjs +21 -0
- package/src/runtime/shared/provider-accounts.mjs +231 -59
- package/src/runtime/shared/provider-api-key.mjs +19 -8
- package/src/runtime/shared/provider-display-name.mjs +29 -0
- package/src/runtime/shared/provider-timeout-phase.mjs +2 -0
- package/src/runtime/shared/routine-trigger.d.mts +2 -0
- package/src/runtime/shared/routine-trigger.mjs +52 -0
- package/src/runtime/shared/sensitive-path-rules.d.mts +2 -10
- package/src/runtime/shared/sensitive-path-rules.mjs +19 -41
- package/src/runtime/shared/session-activity-signal.mjs +34 -1
- package/src/runtime/shared/session-sidebar-host.d.mts +1 -1
- package/src/runtime/shared/session-sidebar-host.mjs +7 -3
- package/src/runtime/shared/session-turn-prelude.mjs +18 -0
- package/src/runtime/shared/tool-execution-contract.mjs +2 -0
- package/src/runtime/shared/tool-result-summary.mjs +1 -14
- package/src/runtime/shared/transcript-metadata.mjs +38 -0
- package/src/runtime/shared/user-data-guard.mjs +30 -2
- package/src/runtime/shared/worktrees/activity-gate.mjs +12 -5
- package/src/runtime/shared/worktrees/test-support.mjs +9 -4
- package/src/runtime/terminal-bridge/client.mjs +10 -1
- package/src/runtime/visualize-bridge/client.mjs +27 -8
- package/src/runtime/visualize-bridge/tool-defs.mjs +22 -8
- package/src/runtime/visualize-bridge/tool-meta.d.mts +5 -0
- package/src/runtime/visualize-bridge/tool-meta.mjs +22 -0
- package/src/runtime/web-search/lib/fetch-pipeline.mjs +2 -2
- package/src/session-runtime/agent-home-delivery.mjs +486 -179
- package/src/session-runtime/agent-room-delivery.mjs +28 -1
- package/src/session-runtime/agent-task-sessions.mjs +561 -199
- package/src/session-runtime/boot/apis.mjs +9 -0
- package/src/session-runtime/boot/begin.mjs +3 -2
- package/src/session-runtime/boot/infrastructure.mjs +4 -0
- package/src/session-runtime/boot/providers.mjs +3 -0
- package/src/session-runtime/boot/tools.mjs +8 -1
- package/src/session-runtime/bot-chain.mjs +32 -0
- package/src/session-runtime/bot-status.mjs +7 -4
- package/src/session-runtime/channel-config-api.mjs +63 -17
- package/src/session-runtime/config-lifecycle.mjs +6 -0
- package/src/session-runtime/connector-merge-migration.mjs +305 -0
- package/src/session-runtime/internal-tool-executor/ask-user-tool.mjs +132 -28
- package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +2 -0
- package/src/session-runtime/internal-tool-executor/reaction-tool.mjs +45 -0
- package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +72 -5
- package/src/session-runtime/internal-tool-executor.mjs +4 -0
- package/src/session-runtime/lifecycle/inheritance.mjs +16 -3
- package/src/session-runtime/lifecycle/session-catalog.mjs +3 -1
- package/src/session-runtime/lifecycle/teardown/runtime-stops.mjs +50 -4
- package/src/session-runtime/lifecycle/teardown.mjs +23 -5
- package/src/session-runtime/mcp-glue/server-catalog.mjs +61 -3
- package/src/session-runtime/mcp-oauth-login.mjs +5 -3
- package/src/session-runtime/mixy-heartbeat.mjs +927 -0
- package/src/session-runtime/model-route/route-tuning.mjs +10 -6
- package/src/session-runtime/notification-bus.mjs +31 -117
- package/src/session-runtime/notification-completion-queue.mjs +54 -0
- package/src/session-runtime/notification-listeners.mjs +76 -0
- package/src/session-runtime/owned-automation-run.mjs +35 -13
- package/src/session-runtime/prewarm/channel-start.mjs +3 -7
- package/src/session-runtime/provider-auth/login.mjs +7 -0
- package/src/session-runtime/provider-models/row-hydration.mjs +13 -2
- package/src/session-runtime/resource-mcp-api.mjs +143 -224
- package/src/session-runtime/resource-mcp-connector-accounts.mjs +163 -0
- package/src/session-runtime/resource-mcp-oauth-api.mjs +217 -0
- package/src/session-runtime/resource-mcp-secrets.mjs +82 -0
- package/src/session-runtime/resource-mcp-servers.mjs +78 -0
- package/src/session-runtime/resource-mcp-store.mjs +49 -0
- package/src/session-runtime/routine-home-turn.mjs +33 -6
- package/src/session-runtime/routine-owner.mjs +40 -9
- package/src/session-runtime/schedule-session-run.mjs +7 -3
- package/src/session-runtime/services/agent-tool/close-flow.mjs +3 -0
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-plan.mjs +8 -12
- package/src/session-runtime/services/agent-tool/spawn-preset.mjs +7 -2
- package/src/session-runtime/services/agent-tool/tag-registry.mjs +1 -0
- package/src/session-runtime/services/agent-tool/worker-index/awaiting-user-sync.mjs +51 -0
- package/src/session-runtime/services/agent-tool/worker-index/disposal.mjs +55 -0
- package/src/session-runtime/services/agent-tool/worker-index/released-store.mjs +123 -0
- package/src/session-runtime/services/agent-tool/worker-index/restart-settlement.mjs +112 -0
- package/src/session-runtime/services/agent-tool/worker-index/row-reads.mjs +36 -0
- package/src/session-runtime/services/agent-tool/worker-index/row-shape.mjs +2 -0
- package/src/session-runtime/services/agent-tool/worker-index/row-store.mjs +17 -4
- package/src/session-runtime/services/agent-tool/worker-index/row-writes.mjs +58 -0
- package/src/session-runtime/services/agent-tool/worker-index.mjs +41 -241
- package/src/session-runtime/services/agent-tool/worker-rows.mjs +3 -0
- package/src/session-runtime/services/channel-admin.mjs +73 -31
- package/src/session-runtime/services/channel-session-router.mjs +4 -2
- package/src/session-runtime/services/channel-worker.mjs +1 -1
- package/src/session-runtime/services/provider-admin.mjs +128 -25
- package/src/session-runtime/services/schedule-access.mjs +14 -0
- package/src/session-runtime/services/seeds.mjs +0 -28
- package/src/session-runtime/services/usage-dashboard-model.mjs +1 -0
- package/src/session-runtime/session-compaction-sync.mjs +27 -0
- package/src/session-runtime/session-create/session-options.mjs +8 -4
- package/src/session-runtime/settings-builtin-tools-api.mjs +11 -0
- package/src/session-runtime/settings-compaction-api.mjs +2 -40
- package/src/session-runtime/settings-system-api.mjs +28 -1
- package/src/session-runtime/setup-tool/agent-settings-actions.mjs +65 -0
- package/src/session-runtime/setup-tool/executor.mjs +187 -29
- package/src/session-runtime/setup-tool/extended-actions.mjs +33 -2
- package/src/session-runtime/setup-tool/session-route-actions.mjs +152 -0
- package/src/session-runtime/setup-tool/settings-contract.mjs +68 -6
- package/src/session-runtime/setup-tool/tool-defs.mjs +92 -6
- package/src/session-runtime/task-session-route.mjs +99 -0
- package/src/session-runtime/tool-policy/agent-profile-fold.mjs +17 -13
- package/src/session-runtime/tool-policy/policy-stage.mjs +21 -4
- package/src/session-runtime/tool-policy/surface-helpers.mjs +2 -3
- package/src/session-runtime/tool-surface.mjs +4 -0
- package/src/session-runtime/turn/turn-run/ask-callbacks.mjs +1 -0
- package/src/session-runtime/workflow-agents-api/agent-editor.mjs +98 -21
- package/src/session-runtime/workflow-agents-api/style-and-mode.mjs +4 -0
- package/src/session-runtime/workflow-agents-api/workflow-packs.mjs +6 -1
- package/src/session-runtime/workspace/transitions.mjs +10 -2
- package/src/standalone/channel-transport/client-registry/client-records.mjs +65 -0
- package/src/standalone/channel-transport/client-registry/client-registration.mjs +118 -0
- package/src/standalone/channel-transport/client-registry.mjs +24 -163
- package/src/standalone/channel-transport.mjs +1 -1
- package/src/standalone/daemon-channels-loader.mjs +10 -8
- package/src/standalone/daemon-session-control/list-page.mjs +72 -0
- package/src/standalone/daemon-session-control/request.mjs +51 -0
- package/src/standalone/daemon-session-control/room-host.mjs +57 -0
- package/src/standalone/daemon-session-control/route-control.mjs +48 -0
- package/src/standalone/daemon-session-control/send-turn.mjs +60 -0
- package/src/standalone/daemon-session-control/worktree-control.mjs +40 -0
- package/src/standalone/daemon-session-control.mjs +161 -157
- package/src/standalone/daemon.mjs +33 -2
- package/src/standalone/session-client.mjs +7 -3
- package/src/standalone/session-protocol.mjs +10 -0
- package/src/standalone/session-service/agent-tree/agent-cancel.mjs +6 -2
- package/src/standalone/session-service/agent-tree/agent-child.mjs +1 -0
- package/src/standalone/session-service/quota-resume.mjs +3 -0
- package/src/standalone/session-service/retention/busy.mjs +65 -1
- package/src/standalone/session-service/session-calls/session-action.mjs +23 -2
- package/src/standalone/session-service/session-calls/session-turns.mjs +6 -0
- package/src/standalone/session-service/session-calls/session-views.mjs +8 -0
- package/src/standalone/session-service.mjs +13 -0
- package/src/standalone/session-tool-output.mjs +21 -10
- package/src/tui/app/model-options.mjs +4 -27
- package/src/tui/dist/index.mjs +81 -65
- package/src/tui/session/agent-job-feed/model-notification.mjs +3 -0
- package/src/tui/session/initial-state.mjs +3 -0
- package/src/tui/session/notice-surface.mjs +23 -1
- package/src/tui/session/queue-helpers.mjs +3 -42
- package/src/tui/session/session-api/integrations.mjs +1 -0
- package/src/tui/session/session-api/lifecycle.mjs +8 -0
- package/src/tui/session/session-api/routes-agent-definitions.mjs +14 -2
- package/src/tui/session/session-api/routes-write.mjs +5 -1
- package/src/tui/session/session-api/routes.mjs +1 -0
- package/src/tui/session/session-api/settings.mjs +30 -2
- package/src/tui/session/session-flow/auto-clear.mjs +4 -33
- package/src/tui/session/session-flow/drain-closed-queue.mjs +38 -0
- package/src/tui/session/session-flow/drain-enqueue.mjs +86 -0
- package/src/tui/session/session-flow/drain-retry.mjs +35 -0
- package/src/tui/session/session-flow/drain.mjs +118 -149
- package/src/tui/session/session-flow/queue/entry-shape.mjs +5 -0
- package/src/tui/session/session-flow/queue/take-entries.mjs +5 -2
- package/src/tui/session/tool-approval-delegation.mjs +64 -0
- package/src/tui/session/tool-approval-request.mjs +39 -0
- package/src/tui/session/tool-approval-settle.mjs +62 -0
- package/src/tui/session/tool-approval.mjs +69 -115
- package/src/tui/session/tui-steering-persist.mjs +8 -1
- package/src/tui/session/turn-stream.mjs +36 -3
- package/src/tui/session/turn.mjs +23 -2
- package/src/vendor/statusline/bin/statusline-route.mjs +1 -219
- package/src/vendor/statusline/src/gateway/route-meta.mjs +35 -13
- package/scripts/code-graph-description-contract.mjs +0 -188
- package/src/runtime/channels/lib/owned-runtime/ownership-refresh.mjs +0 -36
|
@@ -274,7 +274,7 @@ function* walkContentParts(content) {
|
|
|
274
274
|
* beforehand by preparePdfTextForProvider, so one reaching here is a bug.
|
|
275
275
|
* Null when the part is not a file at all.
|
|
276
276
|
*/
|
|
277
|
-
|
|
277
|
+
function textFormOfFilePart(part) {
|
|
278
278
|
if (part?.type !== 'file' && part?.type !== 'document') return null;
|
|
279
279
|
try {
|
|
280
280
|
const file = fileInfo(part);
|
|
@@ -840,6 +840,56 @@ function partCarriesLiveMedia(part) {
|
|
|
840
840
|
return Array.isArray(part.content) && contentCarriesLiveMedia(part.content);
|
|
841
841
|
}
|
|
842
842
|
|
|
843
|
+
/** An image part in any spelling the providers use: inline, URL, file id or
|
|
844
|
+
* URI, Gemini inline data. */
|
|
845
|
+
function isImagePart(part) {
|
|
846
|
+
return Boolean(
|
|
847
|
+
part.type === 'image' ||
|
|
848
|
+
part.type === 'image_url' ||
|
|
849
|
+
part.type === 'input_image' ||
|
|
850
|
+
imageUrlFromPart(part) ||
|
|
851
|
+
imageFileIdFromPart(part) ||
|
|
852
|
+
imageFileUriFromPart(part) ||
|
|
853
|
+
geminiInlineInfo(part)
|
|
854
|
+
);
|
|
855
|
+
}
|
|
856
|
+
|
|
857
|
+
function mapPartText(part, mapText) {
|
|
858
|
+
if (typeof part === 'string') return mapText(part);
|
|
859
|
+
if (!part || typeof part !== 'object') return part;
|
|
860
|
+
// Media and attachment references are encodings, never text.
|
|
861
|
+
if (isAttachmentReference(part) || isImagePart(part) || fileInfo(part)) return part;
|
|
862
|
+
for (const key of ['text', 'content']) {
|
|
863
|
+
if (typeof part[key] === 'string') {
|
|
864
|
+
const next = mapText(part[key]);
|
|
865
|
+
return next === part[key] ? part : { ...part, [key]: next };
|
|
866
|
+
}
|
|
867
|
+
}
|
|
868
|
+
if (Array.isArray(part.content)) {
|
|
869
|
+
const nextContent = mapContentText(part.content, mapText);
|
|
870
|
+
if (nextContent !== part.content) return { ...part, content: nextContent };
|
|
871
|
+
}
|
|
872
|
+
return part;
|
|
873
|
+
}
|
|
874
|
+
|
|
875
|
+
/** `content` with `mapText` applied to its text and nothing else: a string,
|
|
876
|
+
* the text a text part or a part's string content carries (textFromPart),
|
|
877
|
+
* and nested part content; media parts and attachment references stay as
|
|
878
|
+
* they are. The same value when nothing changed. */
|
|
879
|
+
export function mapContentText(content, mapText) {
|
|
880
|
+
if (typeof content === 'string') return mapText(content);
|
|
881
|
+
const parts = contentParts(content);
|
|
882
|
+
if (!parts) return content;
|
|
883
|
+
let changed = false;
|
|
884
|
+
const out = parts.map((part) => {
|
|
885
|
+
const next = mapPartText(part, mapText);
|
|
886
|
+
if (next !== part) changed = true;
|
|
887
|
+
return next;
|
|
888
|
+
});
|
|
889
|
+
if (!changed) return content;
|
|
890
|
+
return Array.isArray(content) ? out : { ...content, content: out };
|
|
891
|
+
}
|
|
892
|
+
|
|
843
893
|
function sanitizePartForStoredHistory(part) {
|
|
844
894
|
if (typeof part === 'string') return part;
|
|
845
895
|
if (!part || typeof part !== 'object') return part;
|
|
@@ -849,15 +899,7 @@ function sanitizePartForStoredHistory(part) {
|
|
|
849
899
|
// reloading the session keeps the provider prompt cache intact.
|
|
850
900
|
const storedImage = part.type === 'image' ? storedImagePart(part) : null;
|
|
851
901
|
if (storedImage) return storedImage;
|
|
852
|
-
if (
|
|
853
|
-
part.type === 'image' ||
|
|
854
|
-
part.type === 'image_url' ||
|
|
855
|
-
part.type === 'input_image' ||
|
|
856
|
-
imageUrlFromPart(part) ||
|
|
857
|
-
imageFileIdFromPart(part) ||
|
|
858
|
-
imageFileUriFromPart(part) ||
|
|
859
|
-
geminiInlineInfo(part)
|
|
860
|
-
) {
|
|
902
|
+
if (isImagePart(part)) {
|
|
861
903
|
return { type: 'text', text: storedHistoryImagePlaceholder(part) };
|
|
862
904
|
}
|
|
863
905
|
const file = fileInfo(part);
|
|
@@ -5,7 +5,14 @@ export const MODEL_PROXY_OPERATIONS: Readonly<{
|
|
|
5
5
|
resolve: 'modelProxyResolve';
|
|
6
6
|
heartbeat: 'modelProxyHeartbeat';
|
|
7
7
|
}>;
|
|
8
|
-
export type ModelProxyMethod =
|
|
8
|
+
export type ModelProxyMethod =
|
|
9
|
+
| 'send'
|
|
10
|
+
| 'listModels'
|
|
11
|
+
| 'refreshModels'
|
|
12
|
+
| 'isAvailable'
|
|
13
|
+
| 'quotaUsable'
|
|
14
|
+
| 'resolveWireRoute'
|
|
15
|
+
| 'providerConfig';
|
|
9
16
|
export const MODEL_PROXY_METHODS: ReadonlyArray<ModelProxyMethod>;
|
|
10
17
|
export const MODEL_PROXY_HEARTBEAT_MS: number;
|
|
11
18
|
export const MODEL_PROXY_LEASE_MS: number;
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
// so a new process (or an offline one) starts from the newest version this
|
|
9
9
|
// machine has seen rather than from a floor that only moves with a release.
|
|
10
10
|
|
|
11
|
+
import { runAbortable } from '../../../shared/abort-race.mjs';
|
|
11
12
|
import { readLastKnownVersion, rememberLastKnownVersion } from './client-version-store.mjs';
|
|
12
13
|
|
|
13
14
|
const SEMVER = /^\d+\.\d+\.\d+$/;
|
|
@@ -41,11 +42,18 @@ export async function parseNpmLatest(res) {
|
|
|
41
42
|
return SEMVER.test(v) ? v : null;
|
|
42
43
|
}
|
|
43
44
|
|
|
44
|
-
/** One GET of `url` parsed to a version; null when offline, slow, or unrecognised.
|
|
45
|
+
/** One GET of `url` parsed to a version; null when offline, slow, or unrecognised.
|
|
46
|
+
* The deadline settles the lookup itself instead of relying on the request
|
|
47
|
+
* and its body read to honour the abort: a send awaits this lookup, and its
|
|
48
|
+
* timer is unref'd, so once the abort tears the socket down nothing else is
|
|
49
|
+
* left to wake a read that missed it. */
|
|
45
50
|
export async function fetchRemoteVersion(url, parse, timeoutMs = TIMEOUT_MS) {
|
|
51
|
+
const signal = AbortSignal.timeout(timeoutMs);
|
|
46
52
|
try {
|
|
47
|
-
|
|
48
|
-
|
|
53
|
+
return await runAbortable(signal, async () => {
|
|
54
|
+
const res = await fetch(url, { signal });
|
|
55
|
+
return res.ok ? (await parse(res)) || null : null;
|
|
56
|
+
});
|
|
49
57
|
} catch {
|
|
50
58
|
return null;
|
|
51
59
|
}
|
|
@@ -4,6 +4,8 @@ import { join } from 'node:path';
|
|
|
4
4
|
import { resolvePluginData } from '../../../shared/plugin-paths.mjs';
|
|
5
5
|
import { boundProviderAuthPath } from '../../../shared/provider-auth-binding.mjs';
|
|
6
6
|
import { cursorTokenExpiry } from './cursor-auth.mjs';
|
|
7
|
+
import { describeDevinOAuthCredentials } from './devin-auth.mjs';
|
|
8
|
+
import { isSignedInTokenDocument } from './lib/oauth-token-utils.mjs';
|
|
7
9
|
import { isValidMuseCredentialDocument } from './muse-code-oauth-tokens.mjs';
|
|
8
10
|
import { isValidOpenCodeGoCredentialDocument } from './opencode-go-oauth-tokens.mjs';
|
|
9
11
|
import { developerOptionEnabled, developerOptionForProvider } from '../../../shared/developer-options.mjs';
|
|
@@ -151,7 +153,7 @@ function openAIOAuthState() {
|
|
|
151
153
|
join(resolvePluginData(), 'openai-oauth.json'),
|
|
152
154
|
];
|
|
153
155
|
return memoProbe('openai-oauth', paths, () =>
|
|
154
|
-
resolveProbeState(paths, (docs) => docs.some((raw) =>
|
|
156
|
+
resolveProbeState(paths, (docs) => docs.some((raw) => isSignedInTokenDocument(raw)))
|
|
155
157
|
);
|
|
156
158
|
}
|
|
157
159
|
|
|
@@ -273,6 +275,21 @@ function cursorOAuthState() {
|
|
|
273
275
|
);
|
|
274
276
|
}
|
|
275
277
|
|
|
278
|
+
// Account-scoped like the token store: the selected account's file wins. Expiry
|
|
279
|
+
// comes from describeDevinOAuthCredentials (no refresh is attempted here); an
|
|
280
|
+
// expired access token still counts when a refresh token can renew it.
|
|
281
|
+
function devinOAuthState() {
|
|
282
|
+
const paths = [
|
|
283
|
+
boundProviderAuthPath('devin-oauth') ||
|
|
284
|
+
process.env.DEVIN_OAUTH_CREDENTIALS_PATH ||
|
|
285
|
+
join(resolvePluginData(), 'devin-oauth.json'),
|
|
286
|
+
];
|
|
287
|
+
return memoProbe('devin-oauth', paths, () => {
|
|
288
|
+
const info = describeDevinOAuthCredentials();
|
|
289
|
+
return info?.authenticated && (info.usable || info.refreshable) ? 'present' : 'absent';
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
|
|
276
293
|
const OAUTH_PROBE_STATES = new Map([
|
|
277
294
|
['anthropic-oauth', anthropicOAuthState],
|
|
278
295
|
['openai-oauth', openAIOAuthState],
|
|
@@ -281,6 +298,7 @@ const OAUTH_PROBE_STATES = new Map([
|
|
|
281
298
|
['command-code-oauth', commandCodeOAuthState],
|
|
282
299
|
['mimo-oauth', mimoOAuthState],
|
|
283
300
|
['cursor-oauth', cursorOAuthState],
|
|
301
|
+
['devin-oauth', devinOAuthState],
|
|
284
302
|
['antigravity-oauth', antigravityOAuthState],
|
|
285
303
|
['opencode-go-oauth', openCodeGoOAuthState],
|
|
286
304
|
]);
|
|
@@ -609,14 +609,47 @@ function balanceFromAnthropicSpend(spend) {
|
|
|
609
609
|
return null;
|
|
610
610
|
}
|
|
611
611
|
|
|
612
|
+
// The server's limit id, in the one spelling headers and the usage payload share.
|
|
613
|
+
const codexLimitId = (value) => (cleanString(value) || '').toLowerCase().replace(/-/g, '_');
|
|
614
|
+
|
|
615
|
+
// Model-specific limits beside the plan's own: one per server limit id
|
|
616
|
+
// (`metered_feature`), whose `limit_name` names the model it meters. Each
|
|
617
|
+
// window gates that model alone.
|
|
618
|
+
function codexAdditionalLimits(list) {
|
|
619
|
+
return (Array.isArray(list) ? list : []).flatMap((entry) => {
|
|
620
|
+
const limit = codexLimitId(entry?.metered_feature || entry?.limit_name);
|
|
621
|
+
if (!limit) return [];
|
|
622
|
+
const name = cleanString(entry.limit_name) || limit;
|
|
623
|
+
const rate = entry.rate_limit && typeof entry.rate_limit === 'object' ? entry.rate_limit : {};
|
|
624
|
+
const windows = [
|
|
625
|
+
windowFromPercent('5H', rate.primary_window || rate.primary, 'openai-codex-oauth'),
|
|
626
|
+
windowFromPercent('7D', rate.secondary_window || rate.secondary, 'openai-codex-oauth'),
|
|
627
|
+
]
|
|
628
|
+
.filter(Boolean)
|
|
629
|
+
.map((window) => ({ ...window, label: `${window.label} ${name}`, limit, models: [name.toLowerCase()] }));
|
|
630
|
+
// A limit without a usable window meters nothing we can read: its model
|
|
631
|
+
// stays under the plan's windows.
|
|
632
|
+
return windows.length ? [{ model: name.toLowerCase(), windows }] : [];
|
|
633
|
+
});
|
|
634
|
+
}
|
|
635
|
+
|
|
612
636
|
export function normalizeOpenAIWhamUsage(data) {
|
|
613
637
|
const rate = data?.rate_limit && typeof data.rate_limit === 'object' ? data.rate_limit : null;
|
|
614
638
|
if (!rate) return null;
|
|
639
|
+
const additional = codexAdditionalLimits(data.additional_rate_limits);
|
|
640
|
+
// The plan's windows gate every model that no model-specific limit meters.
|
|
641
|
+
const plan = {
|
|
642
|
+
limit: 'codex',
|
|
643
|
+
...(additional.length ? { except: additional.map((entry) => entry.model) } : {}),
|
|
644
|
+
};
|
|
615
645
|
const windows = [
|
|
616
646
|
windowFromPercent('5H', rate.primary_window || rate.primary, 'openai-codex-oauth'),
|
|
617
647
|
windowFromPercent('7D', rate.secondary_window || rate.secondary, 'openai-codex-oauth'),
|
|
618
|
-
]
|
|
648
|
+
]
|
|
649
|
+
.filter(Boolean)
|
|
650
|
+
.map((window) => ({ ...window, ...plan }));
|
|
619
651
|
if (!windows.length) return null;
|
|
652
|
+
windows.push(...additional.flatMap((entry) => entry.windows));
|
|
620
653
|
return {
|
|
621
654
|
provider: 'openai-oauth',
|
|
622
655
|
source: 'openai-codex-wham',
|
|
@@ -687,12 +720,14 @@ function anthropicLimitWindows(limits, source) {
|
|
|
687
720
|
.filter(Boolean);
|
|
688
721
|
}
|
|
689
722
|
|
|
690
|
-
// The extra-usage (pay-as-you-go) window when it is enabled, else null.
|
|
723
|
+
// The extra-usage (pay-as-you-go) window when it is enabled, else null. It is
|
|
724
|
+
// shown, never a limit: paid overage spent to its cap leaves the plan's own
|
|
725
|
+
// windows serving, so it gates no model (`models: []`).
|
|
691
726
|
function anthropicExtraUsageWindow(extraUsage) {
|
|
692
727
|
if (extraUsage?.is_enabled !== true) return null;
|
|
693
728
|
const limitUsd = num(extraUsage.monthly_limit, 0) / 100;
|
|
694
729
|
const usedUsd = num(extraUsage.used_credits, 0) / 100;
|
|
695
|
-
|
|
730
|
+
const window = windowFromPercent(
|
|
696
731
|
'EXTRA',
|
|
697
732
|
{
|
|
698
733
|
utilization: extraUsage.utilization,
|
|
@@ -702,6 +737,7 @@ function anthropicExtraUsageWindow(extraUsage) {
|
|
|
702
737
|
},
|
|
703
738
|
'anthropic-oauth-extra'
|
|
704
739
|
);
|
|
740
|
+
return window ? { ...window, models: [] } : null;
|
|
705
741
|
}
|
|
706
742
|
|
|
707
743
|
export function normalizeAnthropicUsage(data, source = 'anthropic-oauth') {
|
|
@@ -23,6 +23,8 @@ export function createCompatStreamState({
|
|
|
23
23
|
onToolCall,
|
|
24
24
|
onTextDelta,
|
|
25
25
|
onStreamItemStart,
|
|
26
|
+
// false: text stays text; only native tool_calls deltas become calls.
|
|
27
|
+
leakedToolCallRecovery = true,
|
|
26
28
|
}) {
|
|
27
29
|
const toolDedupe = createToolCallDedupe();
|
|
28
30
|
return {
|
|
@@ -49,7 +51,7 @@ export function createCompatStreamState({
|
|
|
49
51
|
rawUsage: null,
|
|
50
52
|
toolAcc: createToolCallAccumulator(),
|
|
51
53
|
streamEmitState: { emittedToolCallKeys: new Set(), emittedToolCall: false, _toolDedupe: toolDedupe },
|
|
52
|
-
leakGuard: createLeakGuard({ knownToolNames, harmony: true }),
|
|
54
|
+
leakGuard: createLeakGuard({ knownToolNames: leakedToolCallRecovery ? knownToolNames : [], harmony: true }),
|
|
53
55
|
leakedCalls: [],
|
|
54
56
|
pendingLeakedCalls: [],
|
|
55
57
|
};
|
|
@@ -44,6 +44,7 @@ export async function consumeCompatChatCompletionStream(
|
|
|
44
44
|
knownToolNames,
|
|
45
45
|
semanticIdleTimeoutMs,
|
|
46
46
|
firstByteTimeoutMs,
|
|
47
|
+
leakedToolCallRecovery = true,
|
|
47
48
|
} = {}
|
|
48
49
|
) {
|
|
49
50
|
const idleOverrideEnabled = Number.isFinite(Number(semanticIdleTimeoutMs)) && Number(semanticIdleTimeoutMs) > 0;
|
|
@@ -57,6 +58,7 @@ export async function consumeCompatChatCompletionStream(
|
|
|
57
58
|
onToolCall,
|
|
58
59
|
onTextDelta,
|
|
59
60
|
onStreamItemStart,
|
|
61
|
+
leakedToolCallRecovery,
|
|
60
62
|
});
|
|
61
63
|
reportTransport(state);
|
|
62
64
|
const iterator = stream[Symbol.asyncIterator]();
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
* headers response headers (HTTP, WS handshake, nested error.headers)
|
|
8
8
|
* retryAfterMs server advice, uncapped (Retry-After / Retry-After-Ms)
|
|
9
9
|
* resetAt epoch ms from quota reset fields (resets_at, resets_in_seconds)
|
|
10
|
+
* quotaLimit limit id from x-codex-active-limit, `-` normalized to `_`
|
|
10
11
|
*
|
|
11
12
|
* Pure: no I/O. Message text is never parsed for status or code.
|
|
12
13
|
*/
|
|
@@ -18,7 +19,7 @@ const isObject = (value) => value !== null && typeof value === 'object' && !Arra
|
|
|
18
19
|
* Parse an HTTP error body ONCE into its contract fields. `message` is the
|
|
19
20
|
* body's own message (untruncated); callers truncate for diagnostics.
|
|
20
21
|
*/
|
|
21
|
-
|
|
22
|
+
function parseErrorBody(text) {
|
|
22
23
|
let json = null;
|
|
23
24
|
try {
|
|
24
25
|
json = JSON.parse(String(text || ''));
|
|
@@ -206,6 +207,10 @@ export function applyErrorContract(err, { status, headers, code, error, event }
|
|
|
206
207
|
const wireHeaders =
|
|
207
208
|
headers ?? error?.headers ?? event?.error?.headers ?? event?.response?.error?.headers ?? event?.headers;
|
|
208
209
|
if (wireHeaders && typeof wireHeaders === 'object') err.headers = wireHeaders;
|
|
210
|
+
// The limit a refusal hit, by the server's limit id (`codex` is the plan's
|
|
211
|
+
// own; others are model-specific), so the account pool blocks only it.
|
|
212
|
+
const activeLimit = headerValue(err.headers, 'x-codex-active-limit').toLowerCase().replace(/-/g, '_');
|
|
213
|
+
if (activeLimit) err.quotaLimit = activeLimit;
|
|
209
214
|
const rawCode = code ?? error?.code ?? error?.type ?? null;
|
|
210
215
|
if (typeof rawCode === 'string' && rawCode.trim()) err.code = rawCode.trim().toLowerCase();
|
|
211
216
|
const resetAt = resetAtFrom(error, event?.error, event?.response?.error, event);
|
|
@@ -18,12 +18,15 @@ import { getPluginData } from '../config.mjs';
|
|
|
18
18
|
import { writeJsonAtomicSync, withFileLock } from '../../../shared/atomic-file.mjs';
|
|
19
19
|
import { boundProviderAuthPath } from '../../../shared/provider-auth-binding.mjs';
|
|
20
20
|
import { getLlmDispatcher } from '../../../shared/llm/http-agent.mjs';
|
|
21
|
+
import { TIMEOUT_PHASE } from '../../../shared/provider-timeout-phase.mjs';
|
|
21
22
|
import { modelProxyClientMode, serverModelCredentialsDisabledError } from '../../../shared/model-proxy-mode.mjs';
|
|
22
23
|
import {
|
|
23
24
|
accountIdentityFields,
|
|
24
25
|
decodeJwtPayload,
|
|
25
26
|
expiryFromAccessToken,
|
|
27
|
+
isSignedInTokenDocument,
|
|
26
28
|
normalizeAccountIdentity,
|
|
29
|
+
normalizeExpiresAtMs,
|
|
27
30
|
oauthCredentialStatus,
|
|
28
31
|
} from './lib/oauth-token-utils.mjs';
|
|
29
32
|
import { createOpenAIOAuthLogin } from './openai-oauth-login.mjs';
|
|
@@ -60,11 +63,8 @@ function getRefreshLockPath() {
|
|
|
60
63
|
return `${getOwnTokenPath()}.refresh.lock`;
|
|
61
64
|
}
|
|
62
65
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
if (!Number.isFinite(n) || n <= 0) return 0;
|
|
66
|
-
return n < 1e12 ? n * 1000 : n;
|
|
67
|
-
}
|
|
66
|
+
// One normalizer for the store and the sign-in predicate (isSignedInTokenDocument).
|
|
67
|
+
const _normalizeExpiresAt = normalizeExpiresAtMs;
|
|
68
68
|
|
|
69
69
|
export function extractAccountId(token) {
|
|
70
70
|
return decodeJwtPayload(token)?.['https://api.openai.com/auth']?.chatgpt_account_id;
|
|
@@ -117,7 +117,7 @@ export function loadTokens() {
|
|
|
117
117
|
try {
|
|
118
118
|
const stat = statSync(ownPath);
|
|
119
119
|
const own = JSON.parse(readFileSync(ownPath, 'utf-8'));
|
|
120
|
-
if (own
|
|
120
|
+
if (isSignedInTokenDocument(own)) {
|
|
121
121
|
const identity = identityFromTokens(own.id_token, own.access_token);
|
|
122
122
|
return {
|
|
123
123
|
...own,
|
|
@@ -144,8 +144,7 @@ export function saveTokens(tokens) {
|
|
|
144
144
|
// same loader the runtime uses (loadTokens), no parallel hard-coded path probe.
|
|
145
145
|
export function hasOpenAIOAuthCredentials() {
|
|
146
146
|
try {
|
|
147
|
-
|
|
148
|
-
return !!(tokens?.access_token && tokens?.refresh_token);
|
|
147
|
+
return !!loadTokens()?.access_token;
|
|
149
148
|
} catch {
|
|
150
149
|
return false;
|
|
151
150
|
}
|
|
@@ -256,7 +255,9 @@ async function exchangeRefreshToken(refreshToken, previousIdentity = null) {
|
|
|
256
255
|
return tokens;
|
|
257
256
|
} catch (err) {
|
|
258
257
|
if (err?.name === 'AbortError')
|
|
259
|
-
throw new Error(`OpenAI OAuth token refresh timed out after ${TOKEN_REFRESH_TIMEOUT_MS}ms`)
|
|
258
|
+
throw Object.assign(new Error(`OpenAI OAuth token refresh timed out after ${TOKEN_REFRESH_TIMEOUT_MS}ms`), {
|
|
259
|
+
timeoutPhase: TIMEOUT_PHASE.AUTH,
|
|
260
|
+
});
|
|
260
261
|
throw err;
|
|
261
262
|
} finally {
|
|
262
263
|
clearTimeout(timeout);
|
|
@@ -7,13 +7,17 @@ import { createStreamSafetyStamps, resolveStallRetryBudget } from '../retry-clas
|
|
|
7
7
|
import { _codexWsCompatibilityHeaders } from '../openai-codex-metadata.mjs';
|
|
8
8
|
import { createWsSendAttempts } from '../openai-ws-send-attempts.mjs';
|
|
9
9
|
import { createWsSendSpan } from '../openai-ws-send-span.mjs';
|
|
10
|
+
import { emitProviderRetryStage } from '../retry-executor.mjs';
|
|
11
|
+
import { retryReasonClass } from '../provider-error-kind.mjs';
|
|
10
12
|
|
|
11
13
|
/** Stage callbacks are observers; a throwing one never fails the send. */
|
|
12
14
|
export function notifyStage(onStageChange, stage, detail) {
|
|
13
15
|
try {
|
|
14
16
|
if (detail === undefined) onStageChange?.(stage);
|
|
15
17
|
else onStageChange?.(stage, detail);
|
|
16
|
-
} catch {
|
|
18
|
+
} catch {
|
|
19
|
+
// the stage observer is advisory
|
|
20
|
+
}
|
|
17
21
|
}
|
|
18
22
|
|
|
19
23
|
export function createWsSendContext(opts) {
|
|
@@ -81,10 +85,24 @@ export function createWsSendContext(opts) {
|
|
|
81
85
|
// Single caller-visible recovery path for both handshake/acquire retries
|
|
82
86
|
// and retryable stream failures. The session/TUI stage bridge renders this
|
|
83
87
|
// as non-terminal reconnect progress; transport code must not also print it
|
|
84
|
-
// to stderr.
|
|
85
|
-
|
|
88
|
+
// to stderr. A retry that knows its failure carries the reason and the wait
|
|
89
|
+
// (retryAt), so a long server-advised wait counts down with its cause
|
|
90
|
+
// instead of sitting silently at "n/max".
|
|
91
|
+
const emitReconnectProgress = ({ attempt, max, classifier, error = null, waitMs = 0 }) => {
|
|
86
92
|
const retryAttempt = Number(attempt) || 1;
|
|
87
93
|
const retryMax = Number(max) || 1;
|
|
94
|
+
if (error) {
|
|
95
|
+
// The reason shown is the fixed class, never the server's own text.
|
|
96
|
+
emitProviderRetryStage(onStageChange, {
|
|
97
|
+
attempt: retryAttempt,
|
|
98
|
+
maxAttempts: retryMax,
|
|
99
|
+
lastErr: error,
|
|
100
|
+
delayMs: waitMs,
|
|
101
|
+
classifier,
|
|
102
|
+
reasonClass: retryReasonClass(error),
|
|
103
|
+
});
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
88
106
|
notifyStage(onStageChange, 'reconnecting', {
|
|
89
107
|
attempt: retryAttempt,
|
|
90
108
|
max: retryMax,
|
|
@@ -105,6 +123,7 @@ export function createWsSendContext(opts) {
|
|
|
105
123
|
retry429,
|
|
106
124
|
stallRetryBudget,
|
|
107
125
|
trace: { poolKey, traceProvider, useModel },
|
|
126
|
+
traceFn: _agentTraceFn,
|
|
108
127
|
auth,
|
|
109
128
|
body,
|
|
110
129
|
});
|
package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/attempt-context.mjs
CHANGED
|
@@ -3,7 +3,34 @@
|
|
|
3
3
|
* WS send, plus the surface/backoff primitives both failure resolvers use.
|
|
4
4
|
*/
|
|
5
5
|
import { performance } from 'node:perf_hooks';
|
|
6
|
+
import { appendAgentTrace } from '../../agent-trace.mjs';
|
|
6
7
|
import { _sleepWithAbort, MIDSTREAM_WS_TRANSIENT_RETRY_LIMIT, midstreamBackoffFor, tag } from './policy.mjs';
|
|
8
|
+
import { retryReasonClass, safeRetryErrorCode } from '../provider-error-kind.mjs';
|
|
9
|
+
|
|
10
|
+
/** One row per WS retry: the server's typed verdict (status, close code, an
|
|
11
|
+
* identifier-shaped code, the reason class) and the wait it bought, so a
|
|
12
|
+
* long advised wait is diagnosable after the fact. Never the server's free
|
|
13
|
+
* text: it can echo request content. Diagnostics only; never throws. */
|
|
14
|
+
function traceRetry(traceFn, trace, err, { attempt, max, classifier, waitMs }) {
|
|
15
|
+
try {
|
|
16
|
+
const payload = {
|
|
17
|
+
provider: trace?.traceProvider || null,
|
|
18
|
+
model: trace?.useModel || null,
|
|
19
|
+
transport: 'websocket',
|
|
20
|
+
attempt,
|
|
21
|
+
max,
|
|
22
|
+
classifier: classifier || null,
|
|
23
|
+
reason: retryReasonClass(err),
|
|
24
|
+
wait_ms: Math.round(Number(waitMs) || 0),
|
|
25
|
+
http_status: Number(err?.httpStatus || err?.status || 0) || null,
|
|
26
|
+
code: safeRetryErrorCode(err),
|
|
27
|
+
ws_close_code: Number(err?.wsCloseCode || 0) || null,
|
|
28
|
+
};
|
|
29
|
+
traceFn({ sessionId: trace?.poolKey || null, kind: 'ws_retry', ...payload, payload });
|
|
30
|
+
} catch {
|
|
31
|
+
// the retry trace sink is advisory
|
|
32
|
+
}
|
|
33
|
+
}
|
|
7
34
|
|
|
8
35
|
export function createAttemptContext(deps) {
|
|
9
36
|
const { sendSpan, externalSignal, sleepFn, safetyStamps } = deps;
|
|
@@ -31,10 +58,13 @@ export function createAttemptContext(deps) {
|
|
|
31
58
|
};
|
|
32
59
|
// Server advice (Retry-After, or a typed rate limit's "try again in")
|
|
33
60
|
// replaces the local curve, like the reference client's retry deadline.
|
|
34
|
-
|
|
61
|
+
// Resolved before the retry is announced so the reconnect stage can name
|
|
62
|
+
// the wait it is about to sit through.
|
|
63
|
+
const retryWaitMs = (retryNumber, err = null) => midstreamBackoffFor(retryNumber, err);
|
|
64
|
+
const backoff = async (waitMs) => {
|
|
35
65
|
const sleepStart = performance.now();
|
|
36
66
|
try {
|
|
37
|
-
await _sleepWithAbort(
|
|
67
|
+
await _sleepWithAbort(waitMs, externalSignal, sleepFn);
|
|
38
68
|
} catch (sleepErr) {
|
|
39
69
|
sendSpan.retryBackoffMs += performance.now() - sleepStart;
|
|
40
70
|
sendSpan.emit('error');
|
|
@@ -53,14 +83,21 @@ export function createAttemptContext(deps) {
|
|
|
53
83
|
}
|
|
54
84
|
return first;
|
|
55
85
|
};
|
|
56
|
-
/** Stash the error a retry is about to leave behind and announce the retry
|
|
57
|
-
|
|
86
|
+
/** Stash the error a retry is about to leave behind and announce the retry
|
|
87
|
+
* with its cause and the wait before the next attempt. */
|
|
88
|
+
const scheduleRetry = (err, { attemptIndex, classifier, retryLimit, remember, waitMs = 0 }) => {
|
|
58
89
|
if (remember) {
|
|
59
90
|
state.firstAttemptError = err;
|
|
60
91
|
state.firstAttemptClassifier = classifier;
|
|
61
92
|
}
|
|
62
93
|
tag(err, { midstreamClassifier: classifier });
|
|
63
|
-
deps.emitReconnectProgress({ attempt: attemptIndex + 1, max: retryLimit, classifier });
|
|
94
|
+
deps.emitReconnectProgress({ attempt: attemptIndex + 1, max: retryLimit, classifier, error: err, waitMs });
|
|
95
|
+
traceRetry(deps.traceFn || appendAgentTrace, deps.trace, err, {
|
|
96
|
+
attempt: attemptIndex + 1,
|
|
97
|
+
max: retryLimit,
|
|
98
|
+
classifier,
|
|
99
|
+
waitMs,
|
|
100
|
+
});
|
|
64
101
|
};
|
|
65
102
|
|
|
66
103
|
return {
|
|
@@ -69,6 +106,7 @@ export function createAttemptContext(deps) {
|
|
|
69
106
|
maxMidstreamRetries: MIDSTREAM_WS_TRANSIENT_RETRY_LIMIT,
|
|
70
107
|
stampAll,
|
|
71
108
|
surface,
|
|
109
|
+
retryWaitMs,
|
|
72
110
|
backoff,
|
|
73
111
|
surfaceFirstAttempt,
|
|
74
112
|
scheduleRetry,
|
package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/handshake-failure.mjs
CHANGED
|
@@ -81,13 +81,15 @@ export async function resolveHandshakeFailure(
|
|
|
81
81
|
const retryable =
|
|
82
82
|
classifier && status !== 401 && status !== 426 && err?.unsafeToRetry !== true && !externalSignal?.aborted;
|
|
83
83
|
if (retryable && attemptIndex < ctx.maxMidstreamRetries) {
|
|
84
|
+
const waitMs = ctx.retryWaitMs(attemptIndex + 1, err);
|
|
84
85
|
ctx.scheduleRetry(err, {
|
|
85
86
|
attemptIndex,
|
|
86
87
|
classifier,
|
|
87
88
|
retryLimit: ctx.maxMidstreamRetries,
|
|
88
89
|
remember: !state.firstAttemptError,
|
|
90
|
+
waitMs,
|
|
89
91
|
});
|
|
90
|
-
await ctx.backoff(
|
|
92
|
+
await ctx.backoff(waitMs);
|
|
91
93
|
return true;
|
|
92
94
|
}
|
|
93
95
|
// A later auth/upgrade decision must win over an earlier transient
|
|
@@ -77,7 +77,9 @@ export async function resolveStreamFailure(ctx, err, { attemptIndex, entry, midS
|
|
|
77
77
|
process.stderr.write(
|
|
78
78
|
`[openai-oauth] stall retry budget exhausted (${STREAM_STALL_RETRY_BUDGET_MS}ms since first stall) — surfacing provider-terminal failure\n`
|
|
79
79
|
);
|
|
80
|
-
} catch {
|
|
80
|
+
} catch {
|
|
81
|
+
// diagnostic write only; the provider-terminal failure is thrown next
|
|
82
|
+
}
|
|
81
83
|
throw ctx.surface(markProviderRecoveryExhausted(err, { owner: 'openai-oauth-ws-stall-budget' }));
|
|
82
84
|
}
|
|
83
85
|
const retryLimit = classifier ? midstreamRetryLimit(classifier) : 0;
|
|
@@ -89,8 +91,9 @@ export async function resolveStreamFailure(ctx, err, { attemptIndex, entry, midS
|
|
|
89
91
|
state.carryForwardCache = null;
|
|
90
92
|
tag(entry, { lastResponseId: null });
|
|
91
93
|
}
|
|
92
|
-
ctx.
|
|
93
|
-
|
|
94
|
+
const waitMs = ctx.retryWaitMs(attemptIndex + 1, err);
|
|
95
|
+
ctx.scheduleRetry(err, { attemptIndex, classifier, retryLimit, remember: true, waitMs });
|
|
96
|
+
await ctx.backoff(waitMs);
|
|
94
97
|
return true;
|
|
95
98
|
}
|
|
96
99
|
// Not retryable, OR we've already exhausted the retry budget. Do not
|
|
@@ -144,6 +144,7 @@ export class OpenCodeGoGeminiEngine extends GeminiProvider {
|
|
|
144
144
|
);
|
|
145
145
|
},
|
|
146
146
|
afterToolResult: geminiEndsWithFunctionResponse(contents),
|
|
147
|
+
failureUsage: geminiFailureUsage(opts, null, useModel),
|
|
147
148
|
run: async ({ signal: attemptSignal, connected }) => {
|
|
148
149
|
try {
|
|
149
150
|
opts.onStageChange?.('requesting');
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { modelProxyClientMode } from '../../../shared/model-proxy-mode.mjs';
|
|
2
|
+
import { isOAuthProviderAvailable } from './oauth-credential-probes.mjs';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Whether the named provider may be looked up or sent through right now. Remote
|
|
6
|
+
* client mode serves the PC's providers, whose availability the PC already
|
|
7
|
+
* decided; only a locally run provider answers to the local Developer option.
|
|
8
|
+
*/
|
|
9
|
+
export function providerAvailable(name) {
|
|
10
|
+
return modelProxyClientMode() || isOAuthProviderAvailable(name);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/** The error a send raises when its provider was switched off after lookup. */
|
|
14
|
+
export function providerUnavailableError(name) {
|
|
15
|
+
return Object.assign(
|
|
16
|
+
new Error(`Provider "${name}" is disabled: its Developer option was switched off before the request was sent.`),
|
|
17
|
+
{ code: 'EPROVIDERUNAVAILABLE', provider: name }
|
|
18
|
+
);
|
|
19
|
+
}
|