mixdog 1.2.2 → 1.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -0
- package/package.json +2 -1
- package/scripts/gate-local.mjs +6 -4
- package/scripts/lib/gate-scheduler.mjs +29 -11
- package/scripts/probe-provider-catalog.mjs +31 -0
- package/scripts/provider-pingpong-live.mjs +599 -0
- package/scripts/session-sweep.mjs +5 -25
- package/src/agents/advisor/AGENT.md +1 -1
- package/src/agents/advisor/agent.json +1 -1
- package/src/agents/maintainer/AGENT.md +1 -1
- package/src/agents/maintainer/agent.json +1 -1
- package/src/agents/reviewer/AGENT.md +2 -4
- package/src/agents/security/AGENT.md +1 -2
- package/src/agents/writer/AGENT.md +2 -3
- package/src/defaults/shipped-history.json +11 -1
- package/src/defaults/skills/image/SKILL.md +21 -23
- package/src/defaults/skills/setup/SKILL.md +6 -1
- package/src/defaults/skills/setup/references/actions.md +44 -22
- package/src/defaults/skills/setup/references/surfaces.md +10 -8
- package/src/headless-exec.mjs +15 -8
- package/src/lib/keychain-cjs.cjs +20 -15
- package/src/output-styles/common.md +11 -10
- package/src/rules/agent/AGENT.md +6 -4
- package/src/rules/lead/LEAD.md +7 -9
- package/src/rules/shared/45-destructive.md +4 -0
- package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/preset.mjs +1 -0
- package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +28 -7
- package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +2 -11
- package/src/runtime/agent/orchestrator/agent-trace-io.mjs +92 -61
- package/src/runtime/agent/orchestrator/cache-mtime.mjs +10 -1
- package/src/runtime/agent/orchestrator/config-providers-merge.mjs +7 -0
- package/src/runtime/agent/orchestrator/config.mjs +5 -0
- package/src/runtime/agent/orchestrator/context/collect.mjs +1 -0
- package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +26 -7
- package/src/runtime/agent/orchestrator/context/skill-catalog.mjs +112 -7
- package/src/runtime/agent/orchestrator/mcp/child-tree.mjs +101 -23
- package/src/runtime/agent/orchestrator/providers/account-pool.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-api-key-fetch.mjs +36 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-api-request.mjs +48 -20
- package/src/runtime/agent/orchestrator/providers/anthropic-error-contract.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-max-tokens.mjs +24 -17
- package/src/runtime/agent/orchestrator/providers/anthropic-messages.mjs +9 -9
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-request/gzip-post.mjs +26 -44
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +31 -15
- package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-blocks.mjs +20 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events/content-block-delta.mjs +15 -2
- package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events/content-block-start.mjs +11 -4
- package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events/message-events.mjs +3 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events.mjs +12 -5
- package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-outcome.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-state.mjs +14 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-turn-result.mjs +9 -0
- package/src/runtime/agent/orchestrator/providers/anthropic.mjs +10 -0
- package/src/runtime/agent/orchestrator/providers/antigravity-oauth-catalog.mjs +41 -12
- package/src/runtime/agent/orchestrator/providers/antigravity-oauth.mjs +13 -1
- package/src/runtime/agent/orchestrator/providers/antigravity-request.mjs +131 -9
- package/src/runtime/agent/orchestrator/providers/antigravity-response.mjs +29 -10
- package/src/runtime/agent/orchestrator/providers/antigravity-retry-policy.mjs +125 -8
- package/src/runtime/agent/orchestrator/providers/antigravity-stream.mjs +12 -62
- package/src/runtime/agent/orchestrator/providers/antigravity-transport.mjs +117 -41
- package/src/runtime/agent/orchestrator/providers/codex-client-meta.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/command-code-oauth.mjs +117 -72
- package/src/runtime/agent/orchestrator/providers/compat-request-policy.mjs +78 -2
- package/src/runtime/agent/orchestrator/providers/cursor-auth.mjs +39 -5
- package/src/runtime/agent/orchestrator/providers/cursor-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/cursor-native-context.mjs +48 -0
- package/src/runtime/agent/orchestrator/providers/cursor-wire-exec.mjs +144 -34
- package/src/runtime/agent/orchestrator/providers/cursor-wire-protobuf.mjs +28 -4
- package/src/runtime/agent/orchestrator/providers/cursor-wire-request.mjs +8 -4
- package/src/runtime/agent/orchestrator/providers/cursor-wire-stream-bridge.mjs +42 -11
- package/src/runtime/agent/orchestrator/providers/cursor-wire-stream-messages.mjs +109 -6
- package/src/runtime/agent/orchestrator/providers/cursor-wire.mjs +17 -4
- package/src/runtime/agent/orchestrator/providers/cursor.mjs +22 -2
- package/src/runtime/agent/orchestrator/providers/custom-provider-config.mjs +73 -7
- package/src/runtime/agent/orchestrator/providers/custom-provider.mjs +75 -6
- package/src/runtime/agent/orchestrator/providers/custom-reasoning.mjs +34 -7
- package/src/runtime/agent/orchestrator/providers/custom-tool-wire.mjs +32 -6
- package/src/runtime/agent/orchestrator/providers/deepseek.mjs +67 -0
- package/src/runtime/agent/orchestrator/providers/effort-configuration.mjs +29 -5
- package/src/runtime/agent/orchestrator/providers/gemini-cache-policy.mjs +11 -4
- package/src/runtime/agent/orchestrator/providers/gemini-cache.mjs +36 -13
- package/src/runtime/agent/orchestrator/providers/gemini-error-contract.mjs +101 -11
- package/src/runtime/agent/orchestrator/providers/gemini-request-body.mjs +41 -5
- package/src/runtime/agent/orchestrator/providers/gemini-response.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/gemini-rest-stream/watchdogs.mjs +16 -5
- package/src/runtime/agent/orchestrator/providers/gemini-retry-policy.mjs +19 -14
- package/src/runtime/agent/orchestrator/providers/gemini-schema.mjs +371 -41
- package/src/runtime/agent/orchestrator/providers/gemini-sdk-request.mjs +1 -2
- package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +97 -49
- package/src/runtime/agent/orchestrator/providers/gemini-thinking.mjs +81 -10
- package/src/runtime/agent/orchestrator/providers/gemini.mjs +35 -8
- package/src/runtime/agent/orchestrator/providers/grok-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/grok-oauth.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/lib/action-input-contract.mjs +60 -0
- package/src/runtime/agent/orchestrator/providers/lib/anthropic-native-blocks.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +253 -42
- package/src/runtime/agent/orchestrator/providers/lib/anthropic-server-tool-usage.mjs +18 -0
- package/src/runtime/agent/orchestrator/providers/lib/anthropic-system-blocks.mjs +27 -6
- package/src/runtime/agent/orchestrator/providers/lib/claude-bridge-schema.mjs +392 -0
- package/src/runtime/agent/orchestrator/providers/lib/inclusive-usage.mjs +54 -0
- package/src/runtime/agent/orchestrator/providers/lib/origin-bound-fetch.mjs +16 -0
- package/src/runtime/agent/orchestrator/providers/lib/request-compression.mjs +86 -0
- package/src/runtime/agent/orchestrator/providers/lib/responses-terminal-fields.mjs +11 -0
- package/src/runtime/agent/orchestrator/providers/lib/usage-primitives.mjs +8 -0
- package/src/runtime/agent/orchestrator/providers/lib/wire-pairing.mjs +50 -22
- package/src/runtime/agent/orchestrator/providers/media-normalization.mjs +133 -21
- package/src/runtime/agent/orchestrator/providers/mimo-oauth-profile.mjs +13 -15
- package/src/runtime/agent/orchestrator/providers/mimo-oauth.mjs +7 -1
- package/src/runtime/agent/orchestrator/providers/model-proxy-channel.d.mts +1 -1
- package/src/runtime/agent/orchestrator/providers/model-proxy-channel.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/model-proxy-provider.mjs +92 -16
- package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +13 -13
- package/src/runtime/agent/orchestrator/providers/openai-codex-metadata.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-send.mjs +133 -62
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/chunk-events.mjs +35 -14
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-result.mjs +5 -2
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-state.mjs +39 -7
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/tool-call-acc.mjs +2 -9
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream.mjs +5 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-error-contract.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/openai-compat-models.mjs +84 -2
- package/src/runtime/agent/orchestrator/providers/openai-compat-options.mjs +47 -25
- package/src/runtime/agent/orchestrator/providers/openai-compat-presets.mjs +5 -1
- package/src/runtime/agent/orchestrator/providers/openai-compat-reasoning-field.mjs +155 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-response-normalization.mjs +40 -24
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses-events.mjs +63 -25
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses-head-parity.json +2901 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses-parity.fixtures.mjs +183 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses.mjs +87 -6
- package/src/runtime/agent/orchestrator/providers/openai-compat-retry-profile.mjs +51 -3
- package/src/runtime/agent/orchestrator/providers/openai-compat-stream.mjs +7 -1
- package/src/runtime/agent/orchestrator/providers/openai-compat-trace.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-wire.mjs +103 -26
- package/src/runtime/agent/orchestrator/providers/openai-compat-xai-send.mjs +23 -4
- package/src/runtime/agent/orchestrator/providers/openai-compat-xai.mjs +11 -6
- package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +17 -2
- package/src/runtime/agent/orchestrator/providers/openai-direct-request.mjs +15 -23
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-request.mjs +64 -52
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events/output-items.mjs +23 -10
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events/terminal-frames.mjs +28 -5
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events.mjs +10 -0
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-items.mjs +18 -7
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-outcome.mjs +4 -0
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-state.mjs +5 -0
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/text-relay.mjs +9 -1
- package/src/runtime/agent/orchestrator/providers/openai-model-capabilities.mjs +80 -0
- package/src/runtime/agent/orchestrator/providers/openai-oauth-dispatch.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +7 -0
- package/src/runtime/agent/orchestrator/providers/openai-oauth.mjs +7 -1
- package/src/runtime/agent/orchestrator/providers/openai-responses-input.mjs +72 -24
- package/src/runtime/agent/orchestrator/providers/openai-responses-payload-parity.fixture.json +323 -0
- package/src/runtime/agent/orchestrator/providers/openai-responses-payload.mjs +50 -16
- package/src/runtime/agent/orchestrator/providers/openai-ws-delta.mjs +7 -19
- package/src/runtime/agent/orchestrator/providers/openai-ws-response-state/refusals.mjs +60 -0
- package/src/runtime/agent/orchestrator/providers/openai-ws-response-state/tool-calls.mjs +51 -36
- package/src/runtime/agent/orchestrator/providers/openai-ws-response-state.mjs +30 -0
- package/src/runtime/agent/orchestrator/providers/openai-ws-stream/event-switch.mjs +12 -0
- package/src/runtime/agent/orchestrator/providers/openai-ws-stream/terminal-frames.mjs +25 -6
- package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +18 -9
- package/src/runtime/agent/orchestrator/providers/opencode-go-gemini.mjs +181 -0
- package/src/runtime/agent/orchestrator/providers/opencode-go.mjs +78 -70
- package/src/runtime/agent/orchestrator/providers/openrouter.mjs +74 -0
- package/src/runtime/agent/orchestrator/providers/provider-error-kind.mjs +150 -10
- package/src/runtime/agent/orchestrator/providers/registry.mjs +13 -2
- package/src/runtime/agent/orchestrator/providers/retry-classification.mjs +7 -1
- package/src/runtime/agent/orchestrator/providers/transport-scope.d.mts +6 -0
- package/src/runtime/agent/orchestrator/providers/transport-scope.mjs +28 -0
- package/src/runtime/agent/orchestrator/providers/wire-gateway.mjs +164 -0
- package/src/runtime/agent/orchestrator/providers/wire-route.mjs +522 -0
- package/src/runtime/agent/orchestrator/providers/xai-tool-search-head-parity.json +1131 -0
- package/src/runtime/agent/orchestrator/providers/xai-tool-search.fixtures.mjs +195 -0
- package/src/runtime/agent/orchestrator/runtime-core/ask-user-tool-defs.mjs +104 -0
- package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +8 -6
- package/src/runtime/agent/orchestrator/runtime-core/deferred-tool-availability.mjs +24 -0
- package/src/runtime/agent/orchestrator/runtime-core/effort.mjs +15 -0
- package/src/runtime/agent/orchestrator/runtime-core/goal-store.mjs +30 -2
- package/src/runtime/agent/orchestrator/runtime-core/goal-turns.mjs +3 -2
- package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +8 -3
- package/src/runtime/agent/orchestrator/runtime-core/provider-request-snapshot.mjs +7 -3
- package/src/runtime/agent/orchestrator/runtime-core/session-title.mjs +21 -1
- package/src/runtime/agent/orchestrator/runtime-core/skill-tool-loading.mjs +16 -3
- package/src/runtime/agent/orchestrator/runtime-core/tool-bridge-contract.mjs +6 -0
- package/src/runtime/agent/orchestrator/runtime-core/tool-bridge.mjs +526 -0
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog-data.mjs +3 -0
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog-schema.mjs +10 -7
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +178 -71
- package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +102 -12
- package/src/runtime/agent/orchestrator/runtime-core/tool-exposure.mjs +96 -0
- package/src/runtime/agent/orchestrator/runtime-core/workflow.mjs +10 -8
- package/src/runtime/agent/orchestrator/session/agent-loop.mjs +1 -2
- package/src/runtime/agent/orchestrator/session/agent-pool-progress.mjs +24 -0
- package/src/runtime/agent/orchestrator/session/cache/tool-result-reuse.mjs +10 -2
- package/src/runtime/agent/orchestrator/session/catalog-db/index.mjs +2 -3
- package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +5 -11
- package/src/runtime/agent/orchestrator/session/catalog-db/worker.mjs +6 -22
- package/src/runtime/agent/orchestrator/session/compact/constants.mjs +3 -2
- package/src/runtime/agent/orchestrator/session/compact/messages.mjs +16 -93
- package/src/runtime/agent/orchestrator/session/compact/runner.mjs +16 -2
- package/src/runtime/agent/orchestrator/session/compact/summary-anchor.mjs +5 -0
- package/src/runtime/agent/orchestrator/session/compact/user-message-kind.mjs +148 -0
- package/src/runtime/agent/orchestrator/session/compaction-archive-capture.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/context-tool-schema.mjs +17 -2
- package/src/runtime/agent/orchestrator/session/context-utils.mjs +8 -4
- package/src/runtime/agent/orchestrator/session/conversation-import/claude.mjs +0 -6
- package/src/runtime/agent/orchestrator/session/conversation-import/codex.mjs +0 -6
- package/src/runtime/agent/orchestrator/session/eager-dispatch/admission.mjs +3 -2
- package/src/runtime/agent/orchestrator/session/eager-dispatch.mjs +6 -1
- package/src/runtime/agent/orchestrator/session/historical-session-closure.mjs +10 -0
- package/src/runtime/agent/orchestrator/session/loop/assistant-commit.mjs +2 -5
- package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +89 -1
- package/src/runtime/agent/orchestrator/session/loop/completion-guards.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/context-overflow.mjs +56 -0
- package/src/runtime/agent/orchestrator/session/loop/deferred-call-through.mjs +18 -8
- package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +1 -27
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/output-limit.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/segments.mjs +4 -10
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn.mjs +2 -9
- package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +24 -10
- package/src/runtime/agent/orchestrator/session/loop/provider-tool-exclusions.mjs +135 -0
- package/src/runtime/agent/orchestrator/session/loop/request-boundary.mjs +31 -4
- package/src/runtime/agent/orchestrator/session/loop/route-fallback.mjs +76 -0
- package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +67 -20
- package/src/runtime/agent/orchestrator/session/loop/step-auto-effort.mjs +10 -10
- package/src/runtime/agent/orchestrator/session/loop/tool-call-resolution.mjs +95 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-classify.mjs +6 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +30 -3
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +29 -5
- package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +15 -1
- package/src/runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs +147 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-phase.mjs +7 -5
- package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +33 -3
- package/src/runtime/agent/orchestrator/session/manager/ask-support.mjs +0 -4
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-auto-effort.mjs +23 -2
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-commit.mjs +34 -12
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +54 -13
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-failure.mjs +33 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-loop-options.mjs +57 -25
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-prepare.mjs +11 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +22 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-state.mjs +57 -13
- package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +8 -0
- package/src/runtime/agent/orchestrator/session/manager/failed-turn-rewind.mjs +16 -0
- package/src/runtime/agent/orchestrator/session/manager/pending-messages.mjs +6 -120
- package/src/runtime/agent/orchestrator/session/manager/pending-persist-queue.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +231 -16
- package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +42 -49
- package/src/runtime/agent/orchestrator/session/manager/runtime-state.mjs +50 -0
- package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +47 -17
- package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +26 -4
- package/src/runtime/agent/orchestrator/session/manager/session-fallback-title.mjs +82 -0
- package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +36 -35
- package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +29 -13
- package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +6 -3
- package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +4 -1
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-recovery.mjs +45 -0
- package/src/runtime/agent/orchestrator/session/manager.mjs +4 -10
- package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +6 -0
- package/src/runtime/agent/orchestrator/session/send-instrumentation.mjs +2 -1
- package/src/runtime/agent/orchestrator/session/send-with-recovery.mjs +17 -1
- package/src/runtime/agent/orchestrator/session/side-question-store.mjs +96 -0
- package/src/runtime/agent/orchestrator/session/side-question.mjs +197 -0
- package/src/runtime/agent/orchestrator/session/store/lifecycle-barriers.mjs +22 -15
- package/src/runtime/agent/orchestrator/session/store/lifecycle-read.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/store/listing.mjs +2 -6
- package/src/runtime/agent/orchestrator/session/store/live-cache-eviction.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/store/live-state.mjs +23 -0
- package/src/runtime/agent/orchestrator/session/store/liveness-veto.mjs +46 -37
- package/src/runtime/agent/orchestrator/session/store/load-cache.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/store/load-session.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/store/session-delete.mjs +44 -37
- package/src/runtime/agent/orchestrator/session/store/session-observers.mjs +4 -2
- package/src/runtime/agent/orchestrator/session/store/session-paths.mjs +59 -0
- package/src/runtime/agent/orchestrator/session/store/summary-cache.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/store/sweep/stale-sweep.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/store/sweep/sweep-finish.mjs +27 -21
- package/src/runtime/agent/orchestrator/session/store/sweep/sweep-plan.mjs +0 -8
- package/src/runtime/agent/orchestrator/session/store/sweep/sweep-record.mjs +6 -18
- package/src/runtime/agent/orchestrator/session/store/sweep/sweep-row.mjs +33 -106
- package/src/runtime/agent/orchestrator/session/store/write-admission.mjs +4 -2
- package/src/runtime/agent/orchestrator/session/store-agent-worker-pool.mjs +5 -8
- package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +136 -196
- package/src/runtime/agent/orchestrator/session/store-summary-archived-agent.mjs +34 -15
- package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +53 -115
- package/src/runtime/agent/orchestrator/session/store-summary-fields.mjs +8 -0
- package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +10 -1
- package/src/runtime/agent/orchestrator/session/store-summary-locations.mjs +3 -29
- package/src/runtime/agent/orchestrator/session/store-summary-reader-catalog-fixture.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +17 -10
- package/src/runtime/agent/orchestrator/session/store-transcript-projection.mjs +9 -20
- package/src/runtime/agent/orchestrator/session/store.mjs +22 -19
- package/src/runtime/agent/orchestrator/session/tool-batch/execute-call.mjs +12 -12
- package/src/runtime/agent/orchestrator/session/tool-batch/finalize.mjs +38 -14
- package/src/runtime/agent/orchestrator/session/tool-batch/pre-dispatch.mjs +15 -4
- package/src/runtime/agent/orchestrator/session/tool-batch/record-outcome.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/tool-batch/state.mjs +7 -1
- package/src/runtime/agent/orchestrator/session/tool-result-offload.mjs +4 -0
- package/src/runtime/agent/orchestrator/session/tool-schema-rejection.mjs +79 -0
- package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +72 -15
- package/src/runtime/agent/orchestrator/session/turn-failure.mjs +45 -0
- package/src/runtime/agent/orchestrator/stall-policy.mjs +50 -0
- package/src/runtime/agent/orchestrator/tools/bash-policy-scan.mjs +8 -2
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/command-preflight.mjs +3 -3
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/completed-result.mjs +5 -1
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/inline-hoist.mjs +6 -2
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +4 -1
- package/src/runtime/agent/orchestrator/tools/builtin/external-tool-adapters.mjs +218 -20
- package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +160 -39
- package/src/runtime/agent/orchestrator/tools/builtin/git-partial-stage.mjs +7 -5
- package/src/runtime/agent/orchestrator/tools/builtin/grep-formatting.mjs +14 -5
- package/src/runtime/agent/orchestrator/tools/builtin/lib/grep-context-expander.mjs +4 -3
- package/src/runtime/agent/orchestrator/tools/builtin/lib/grep-output.mjs +2 -1
- package/src/runtime/agent/orchestrator/tools/builtin/lib/grep-path-fanout.mjs +48 -44
- package/src/runtime/agent/orchestrator/tools/builtin/lib/search-input-helpers.mjs +10 -3
- package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-job-records.mjs +247 -49
- package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-task-output.mjs +5 -4
- package/src/runtime/agent/orchestrator/tools/builtin/read-formatting.mjs +6 -1
- package/src/runtime/agent/orchestrator/tools/builtin/runtime-capabilities.mjs +23 -1
- package/src/runtime/agent/orchestrator/tools/builtin/shell-analysis.mjs +20 -0
- package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +101 -2
- package/src/runtime/agent/orchestrator/tools/code-graph/dispatch/root-resolution.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/code-graph/search.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/code-graph-prewarm-worker.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/lib/owned-shell-trees.mjs +67 -0
- package/src/runtime/agent/orchestrator/tools/lib/process-table-fixture.mjs +50 -0
- package/src/runtime/agent/orchestrator/tools/lib/shell-descendants.mjs +303 -63
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-background/promote-job.mjs +2 -0
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-settle.mjs +108 -18
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-spawn.mjs +77 -11
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-state.mjs +81 -5
- package/src/runtime/agent/orchestrator/tools/patch/ui-diff.mjs +73 -39
- package/src/runtime/agent/orchestrator/tools/progress-message.mjs +18 -1
- package/src/runtime/agent/orchestrator/tools/shell-command.mjs +7 -4
- package/src/runtime/agent/orchestrator/tools/shell-exec-policy.mjs +88 -12
- package/src/runtime/agent/orchestrator/tools/shell-policy.mjs +2 -0
- package/src/runtime/attachments/store.d.mts +9 -0
- package/src/runtime/attachments/store.mjs +80 -9
- package/src/runtime/browser-bridge/browser-action-contract.d.mts +0 -1
- package/src/runtime/browser-bridge/browser-action-contract.mjs +0 -2
- package/src/runtime/computer-bridge/action-schema.mjs +219 -196
- package/src/runtime/computer-bridge/linux-readiness.d.mts +0 -2
- package/src/runtime/computer-bridge/linux-readiness.mjs +0 -16
- package/src/runtime/effort-judge/judge-client.mjs +21 -4
- package/src/runtime/effort-judge/judge-worker.mjs +4 -1
- package/src/runtime/github/tool.mjs +208 -17
- package/src/runtime/media/adapters/codex-image.mjs +140 -21
- package/src/runtime/media/catalog.mjs +4 -4
- package/src/runtime/media/chatgpt-usage.mjs +55 -0
- package/src/runtime/media/defaults.mjs +37 -0
- package/src/runtime/media/jobs.mjs +12 -2
- package/src/runtime/media/lanes.mjs +12 -0
- package/src/runtime/media/tool-defs.mjs +15 -4
- package/src/runtime/media/tool.mjs +41 -12
- package/src/runtime/media/upstream-error.mjs +72 -6
- package/src/runtime/memory/index.mjs +1 -0
- package/src/runtime/memory/lib/http-router/ingest-routes.mjs +22 -1
- package/src/runtime/memory/lib/ingest/transcript-offsets.mjs +2 -0
- package/src/runtime/memory/lib/ingest/transcript-rows.mjs +1 -0
- package/src/runtime/memory/lib/pg/adapter.mjs +98 -1
- package/src/runtime/memory/lib/pg/process.mjs +36 -33
- package/src/runtime/memory/lib/pg/run-child.mjs +49 -0
- package/src/runtime/memory/lib/pg/supervisor.mjs +112 -4
- package/src/runtime/memory/lib/runtime-fetcher.mjs +12 -13
- package/src/runtime/memory/lib/transcript-ingest.mjs +14 -0
- package/src/runtime/office/README.md +1 -1
- package/src/runtime/office/authoring/docx-html-runner.mjs +1 -1
- package/src/runtime/office/authoring/html-browser.mjs +18 -8
- package/src/runtime/office/authoring/html-document-author.mjs +2 -0
- package/src/runtime/office/authoring/pdf-html-runner.mjs +1 -1
- package/src/runtime/office/authoring/pptx-contact-sheet.mjs +2 -0
- package/src/runtime/office/authoring/pptx-html-measure.mjs +3 -1
- package/src/runtime/office/authoring/pptx-html-runner.mjs +2 -0
- package/src/runtime/office/authoring/xlsx-html-runner.mjs +3 -1
- package/src/runtime/office/core/office-actions-read.mjs +3 -0
- package/src/runtime/office/core/office-render-preview.mjs +2 -0
- package/src/runtime/office/core/office-session-dispatch.mjs +7 -0
- package/src/runtime/office/core/office-sessionless-actions.mjs +8 -0
- package/src/runtime/office/core/office-sessions.mjs +5 -0
- package/src/runtime/office/core/office-transactions.mjs +3 -0
- package/src/runtime/office/core/office-write-ledger.mjs +94 -0
- package/src/runtime/office/design/library/templates/mixdog-executive.mixdog-edit.pptx +0 -0
- package/src/runtime/office/index.mjs +29 -0
- package/src/runtime/office/pdf/pdf-analysis.mjs +0 -68
- package/src/runtime/office/pdf/pdf-edit-document.mjs +2 -0
- package/src/runtime/office/pdf/pdf-render.mjs +23 -7
- package/src/runtime/office/pdf/pdf-security.mjs +2 -0
- package/src/runtime/office/portable/portable-opc.mjs +4 -1
- package/src/runtime/office/quality/visual-diff.mjs +2 -0
- package/src/runtime/session-search/session-search-ingest.mjs +1 -1
- package/src/runtime/shared/agent-reap-state.mjs +13 -0
- package/src/runtime/shared/atomic-file.d.mts +1 -1
- package/src/runtime/shared/background-tasks.mjs +6 -1
- package/src/runtime/shared/bounded-file-read.mjs +13 -0
- package/src/runtime/shared/bounded-line-diff.mjs +191 -0
- package/src/runtime/shared/browser-launch.mjs +15 -0
- package/src/runtime/shared/buffered-appender.mjs +18 -0
- package/src/runtime/shared/config.mjs +78 -18
- package/src/runtime/shared/err-text.mjs +48 -4
- package/src/runtime/shared/file-lock.mjs +6 -5
- package/src/runtime/shared/file-permissions.d.mts +6 -1
- package/src/runtime/shared/file-permissions.mjs +54 -6
- package/src/runtime/shared/llm/anthropic-betas.mjs +1 -2
- package/src/runtime/shared/llm/anthropic-effort.mjs +6 -0
- package/src/runtime/shared/llm/provider-model-identities.mjs +1 -0
- package/src/runtime/shared/llm/usage-accounting.mjs +5 -2
- package/src/runtime/shared/llm/usage-ledger-rollup.mjs +3 -0
- package/src/runtime/shared/loopback-listener.mjs +9 -0
- package/src/runtime/shared/model-route-chain.d.mts +8 -0
- package/src/runtime/shared/model-route-chain.mjs +48 -0
- package/src/runtime/shared/model-route-fallback.mjs +22 -0
- package/src/runtime/shared/pid-liveness.mjs +12 -0
- package/src/runtime/shared/provider-api-key.mjs +8 -0
- package/src/runtime/shared/provider-timeout-phase.mjs +17 -0
- package/src/runtime/shared/quiet-progress.d.mts +35 -0
- package/src/runtime/shared/quiet-progress.mjs +101 -0
- package/src/runtime/shared/quota-resume-store.mjs +32 -1
- package/src/runtime/shared/read-row-numbers.mjs +44 -0
- package/src/runtime/shared/remote-intent.mjs +2 -42
- package/src/runtime/shared/review-diff.mjs +52 -0
- package/src/runtime/shared/session-sidebar-host.d.mts +4 -0
- package/src/runtime/shared/session-sidebar-host.mjs +38 -0
- package/src/runtime/shared/slow-span.mjs +121 -0
- package/src/runtime/shared/statusline/statusline-segments.mjs +52 -6
- package/src/runtime/shared/tool-card-model/card-header.mjs +7 -1
- package/src/runtime/shared/tool-card-model/generic-detail.mjs +39 -5
- package/src/runtime/shared/tool-card-model.mjs +5 -2
- package/src/runtime/shared/tool-output-budget.mjs +2 -0
- package/src/runtime/shared/tool-output-limit.mjs +4 -0
- package/src/runtime/shared/tool-primitives.mjs +13 -0
- package/src/runtime/shared/tool-result-summary.mjs +22 -1
- package/src/runtime/shared/tool-status.mjs +3 -2
- package/src/runtime/shared/tool-surface.mjs +20 -6
- package/src/runtime/shared/tool-work-units.mjs +54 -11
- package/src/runtime/shared/transcript-metadata.mjs +49 -1
- package/src/runtime/shared/transcript-turn-keys.mjs +33 -0
- package/src/runtime/shared/transcript-writer/purge.mjs +74 -0
- package/src/runtime/shared/transcript-writer/transcript-file.mjs +10 -1
- package/src/runtime/shared/transcript-writer.mjs +24 -6
- package/src/runtime/shared/turn-changes.mjs +269 -100
- package/src/runtime/shared/turn-review-reply.mjs +8 -39
- package/src/runtime/shared/turn-snapshot-store.mjs +19 -108
- package/src/runtime/shared/turn-snapshot.mjs +865 -683
- package/src/runtime/shared/turn-worktree-snapshot.mjs +183 -255
- package/src/runtime/shared/user-data-guard.mjs +262 -49
- package/src/runtime/shared/worktrees/activity-gate.mjs +175 -0
- package/src/runtime/shared/worktrees/branch-management.mjs +179 -0
- package/src/runtime/shared/worktrees/carry.mjs +533 -0
- package/src/runtime/shared/worktrees/contract.mjs +60 -0
- package/src/runtime/shared/worktrees/dependencies.mjs +456 -0
- package/src/runtime/shared/worktrees/file-recovery.mjs +84 -0
- package/src/runtime/shared/worktrees/git-head.mjs +214 -0
- package/src/runtime/shared/worktrees/git.mjs +8 -3
- package/src/runtime/shared/worktrees/include.mjs +125 -7
- package/src/runtime/shared/worktrees/lock.mjs +1 -1
- package/src/runtime/shared/worktrees/maintenance.mjs +20 -2
- package/src/runtime/shared/worktrees/manager.mjs +525 -31
- package/src/runtime/shared/worktrees/merge.mjs +31 -21
- package/src/runtime/shared/worktrees/owner.mjs +2 -1
- package/src/runtime/shared/worktrees/paths.d.mts +6 -0
- package/src/runtime/shared/worktrees/preparation-report.mjs +79 -0
- package/src/runtime/shared/worktrees/setup-commands.mjs +232 -0
- package/src/runtime/shared/worktrees/workspace-visibility.mjs +17 -0
- package/src/runtime/terminal-bridge/client.mjs +57 -20
- package/src/runtime/terminal-bridge/tool-defs.mjs +13 -6
- package/src/runtime/tidy/apply.mjs +47 -2
- package/src/runtime/tidy/run-engines.mjs +11 -5
- package/src/session-runtime/agent-tool-routing.mjs +19 -13
- package/src/session-runtime/boot/apis.mjs +20 -6
- package/src/session-runtime/boot/config.mjs +2 -0
- package/src/session-runtime/boot/facade.mjs +4 -0
- package/src/session-runtime/boot/infrastructure.mjs +6 -1
- package/src/session-runtime/boot/session.mjs +3 -3
- package/src/session-runtime/boot/tools.mjs +7 -1
- package/src/session-runtime/conversation-import/service.mjs +1 -1
- package/src/session-runtime/cwd-plugins/cwd-apply.mjs +12 -5
- package/src/session-runtime/goal-facade-api.mjs +2 -2
- package/src/session-runtime/internal-tool-executor/ask-user-tool.mjs +91 -0
- package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +3 -1
- package/src/session-runtime/internal-tool-executor/knowledge-tools.mjs +15 -5
- package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +137 -26
- package/src/session-runtime/internal-tool-executor.mjs +8 -2
- package/src/session-runtime/lifecycle/cold-heir.mjs +187 -0
- package/src/session-runtime/lifecycle/inheritance.mjs +71 -27
- package/src/session-runtime/lifecycle/session-catalog.mjs +25 -18
- package/src/session-runtime/lifecycle/session-switch/resume.mjs +6 -0
- package/src/session-runtime/lifecycle/session-switch/session-delete.mjs +36 -48
- package/src/session-runtime/lifecycle/session-switch.mjs +1 -1
- package/src/session-runtime/lifecycle/shared.mjs +5 -6
- package/src/session-runtime/lifecycle/teardown/session-close.mjs +6 -5
- package/src/session-runtime/lifecycle/teardown.mjs +70 -14
- package/src/session-runtime/lifecycle-api.mjs +1 -0
- package/src/session-runtime/mcp-glue/connect.mjs +17 -5
- package/src/session-runtime/media-api.mjs +8 -0
- package/src/session-runtime/model-route/route-ownership.mjs +60 -0
- package/src/session-runtime/model-route/route-persist.mjs +3 -2
- package/src/session-runtime/model-route/set-route.mjs +116 -36
- package/src/session-runtime/model-route/web-search-route.mjs +7 -2
- package/src/session-runtime/model-route-api.mjs +4 -2
- package/src/session-runtime/native-web-search/routes.mjs +37 -24
- package/src/session-runtime/native-web-search-usage.mjs +51 -0
- package/src/session-runtime/native-web-search.mjs +19 -9
- package/src/session-runtime/new-session-config.mjs +4 -2
- package/src/session-runtime/provider-auth/login.mjs +4 -0
- package/src/session-runtime/provider-auth/setup.mjs +4 -0
- package/src/session-runtime/provider-models/catalog-load.mjs +9 -0
- package/src/session-runtime/provider-models/web-search-catalog.mjs +23 -3
- package/src/session-runtime/provider-models.mjs +1 -0
- package/src/session-runtime/provider-usage.mjs +4 -0
- package/src/session-runtime/resource-scope-decorate.mjs +10 -3
- package/src/session-runtime/route-resolution.mjs +3 -1
- package/src/session-runtime/runtime-core.mjs +4 -0
- package/src/session-runtime/runtime-facade.mjs +6 -0
- package/src/session-runtime/runtime-review-api.mjs +8 -2
- package/src/session-runtime/services/agent-task-status.mjs +2 -0
- package/src/session-runtime/services/agent-tool/close-flow/close-all.mjs +0 -3
- package/src/session-runtime/services/agent-tool/close-flow.mjs +6 -7
- package/src/session-runtime/services/agent-tool/execute-send.mjs +2 -2
- package/src/session-runtime/services/agent-tool/execute-spawn.mjs +36 -3
- package/src/session-runtime/services/agent-tool/execute.mjs +9 -1
- package/src/session-runtime/services/agent-tool/helpers.mjs +30 -7
- package/src/session-runtime/services/agent-tool/index-write-queue.mjs +81 -20
- package/src/session-runtime/services/agent-tool/job-task-reconcile.mjs +7 -2
- package/src/session-runtime/services/agent-tool/job-views/session-progress.mjs +6 -3
- package/src/session-runtime/services/agent-tool/lead-worker-index/forgotten-leads.mjs +29 -0
- package/src/session-runtime/services/agent-tool/lead-worker-index/index-file.mjs +1 -1
- package/src/session-runtime/services/agent-tool/lead-worker-index/lead-rows.mjs +3 -4
- package/src/session-runtime/services/agent-tool/lead-worker-index/reap-timers.mjs +9 -3
- package/src/session-runtime/services/agent-tool/lead-worker-index/row-settlement.mjs +7 -18
- package/src/session-runtime/services/agent-tool/lead-worker-index.mjs +82 -13
- package/src/session-runtime/services/agent-tool/model-select.mjs +82 -0
- package/src/session-runtime/services/agent-tool/send-flow.mjs +24 -6
- package/src/session-runtime/services/agent-tool/spawn-flow/job-start.mjs +3 -1
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-prep.mjs +19 -5
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-run.mjs +5 -4
- package/src/session-runtime/services/agent-tool/spawn-flow.mjs +2 -1
- package/src/session-runtime/services/agent-tool/spawn-preset.mjs +3 -0
- package/src/session-runtime/services/agent-tool/tag-registry/tag-lookup.mjs +1 -3
- package/src/session-runtime/services/agent-tool/tag-registry/tag-refresh.mjs +1 -3
- package/src/session-runtime/services/agent-tool/tag-registry.mjs +18 -10
- package/src/session-runtime/services/agent-tool/terminal-reaper/scan-admission.mjs +8 -41
- package/src/session-runtime/services/agent-tool/terminal-reaper/stale-rows.mjs +3 -3
- package/src/session-runtime/services/agent-tool/terminal-reaper.mjs +6 -23
- package/src/session-runtime/services/agent-tool/terminal-trace.mjs +0 -1
- package/src/session-runtime/services/agent-tool/tool-def.mjs +7 -0
- package/src/session-runtime/services/agent-tool/worker-index/row-liveness.mjs +32 -20
- package/src/session-runtime/services/agent-tool/worker-index/row-shape.mjs +5 -2
- package/src/session-runtime/services/agent-tool/worker-index/row-store.mjs +10 -1
- package/src/session-runtime/services/agent-tool/worker-index.mjs +74 -15
- package/src/session-runtime/services/agent-tool.mjs +7 -0
- package/src/session-runtime/services/agent-watchdog-registry.mjs +2 -0
- package/src/session-runtime/services/channel-admin.mjs +19 -3
- package/src/session-runtime/services/memory-runtime-proxy/calls.mjs +4 -0
- package/src/session-runtime/services/memory-runtime-proxy.mjs +1 -0
- package/src/session-runtime/services/provider-admin.mjs +158 -15
- package/src/session-runtime/session-create/session-options.mjs +7 -5
- package/src/session-runtime/session-create/session-start-hook.mjs +2 -1
- package/src/session-runtime/session-transcript-purge.mjs +32 -0
- package/src/session-runtime/session-transcript.mjs +4 -5
- package/src/session-runtime/session-turn-api.mjs +17 -14
- package/src/session-runtime/settings-builtin-tools-api.mjs +18 -6
- package/src/session-runtime/setup-tool/executor.mjs +57 -9
- package/src/session-runtime/setup-tool/extended-actions.mjs +86 -6
- package/src/session-runtime/setup-tool/settings-contract.mjs +18 -3
- package/src/session-runtime/setup-tool/tool-defs.mjs +25 -4
- package/src/session-runtime/skills-api.mjs +3 -5
- package/src/session-runtime/tool-policy-refresh.mjs +83 -32
- package/src/session-runtime/tool-surface.mjs +5 -1
- package/src/session-runtime/turn/agent-ops.mjs +49 -2
- package/src/session-runtime/turn/compaction-gate.mjs +25 -0
- package/src/session-runtime/turn/session-ops.mjs +7 -5
- package/src/session-runtime/turn/side-question-ops.mjs +19 -0
- package/src/session-runtime/turn/turn-run/ask-callbacks.mjs +7 -1
- package/src/session-runtime/turn/turn-run/turn-prepare.mjs +12 -3
- package/src/session-runtime/turn/turn-run/turn-settle.mjs +18 -2
- package/src/session-runtime/turn/turn-run/turn-timing.mjs +4 -3
- package/src/session-runtime/turn/turn-run.mjs +26 -45
- package/src/session-runtime/usage-stats-api.mjs +46 -11
- package/src/session-runtime/workflow-agents-api/agent-route.mjs +16 -1
- package/src/session-runtime/workspace/admission-gate.mjs +44 -15
- package/src/session-runtime/workspace/project-branches.mjs +35 -41
- package/src/session-runtime/workspace/transition-steps.mjs +215 -116
- package/src/session-runtime/workspace/transitions.mjs +428 -73
- package/src/standalone/channel-transport.mjs +3 -4
- package/src/standalone/daemon-agent-control.mjs +9 -1
- package/src/standalone/daemon-desktop-runtime.mjs +32 -1
- package/src/standalone/daemon-local-session-bridge.mjs +14 -1
- package/src/standalone/daemon-owner.mjs +17 -4
- package/src/standalone/daemon-pg-stop.mjs +49 -0
- package/src/standalone/daemon-session-control.mjs +88 -0
- package/src/standalone/daemon-stop-budget.d.mts +2 -0
- package/src/standalone/daemon-stop-budget.mjs +18 -0
- package/src/standalone/daemon-stored-session-views.mjs +25 -3
- package/src/standalone/daemon-telemetry.mjs +19 -0
- package/src/standalone/daemon.mjs +63 -1
- package/src/standalone/desktop-service-registry.mjs +5 -0
- package/src/standalone/local-session-runtime.mjs +80 -30
- package/src/standalone/session-client.mjs +42 -0
- package/src/standalone/session-protocol.mjs +14 -0
- package/src/standalone/session-proxy/projection.mjs +41 -4
- package/src/standalone/session-runtime-inline-host/boot-loaders.mjs +15 -1
- package/src/standalone/session-runtime-inline-host.mjs +3 -0
- package/src/standalone/session-service/agent-tree/agent-cancel.mjs +91 -49
- package/src/standalone/session-service/agent-tree/agent-child.mjs +19 -1
- package/src/standalone/session-service/agent-tree/agent-registry.mjs +25 -0
- package/src/standalone/session-service/agent-tree/agent-turns.mjs +9 -1
- package/src/standalone/session-service/agent-tree.mjs +28 -2
- package/src/standalone/session-service/entries/session-loads.mjs +16 -5
- package/src/standalone/session-service/entries.mjs +1 -0
- package/src/standalone/session-service/projection/transcript-window.mjs +39 -0
- package/src/standalone/session-service/quota-resume.mjs +28 -13
- package/src/standalone/session-service/session-calls/session-action.mjs +18 -3
- package/src/standalone/session-service/session-calls/session-turns.mjs +17 -6
- package/src/standalone/session-service/session-calls/session-views.mjs +6 -0
- package/src/standalone/session-service-api.mjs +6 -1
- package/src/standalone/session-state-patch.d.mts +2 -1
- package/src/standalone/session-state-patch.mjs +41 -1
- package/src/standalone/session-tool-output.mjs +82 -0
- package/src/tui/App.jsx +25 -0
- package/src/tui/app/app-view/floating-panel.jsx +26 -1
- package/src/tui/app/app-view.jsx +2 -1
- package/src/tui/app/btw-controller.mjs +118 -0
- package/src/tui/app/create-app-pickers.mjs +2 -0
- package/src/tui/app/provider-setup/provider-items.mjs +8 -0
- package/src/tui/app/provider-setup-picker.mjs +15 -3
- package/src/tui/app/shell-layout/row-budgets.mjs +11 -1
- package/src/tui/app/shell-layout/surfaces.mjs +3 -1
- package/src/tui/app/slash-commands.mjs +19 -3
- package/src/tui/app/slash-dispatch/session-commands.mjs +68 -6
- package/src/tui/app/use-global-key-input/approval-shortcut.mjs +12 -0
- package/src/tui/app/use-global-key-input.mjs +5 -12
- package/src/tui/app/use-prompt-handlers.mjs +11 -0
- package/src/tui/components/BtwPanel.jsx +53 -0
- package/src/tui/components/QuestionPanel.jsx +275 -0
- package/src/tui/components/Spinner.jsx +4 -0
- package/src/tui/components/SpinnerByline.jsx +21 -2
- package/src/tui/components/question-panel-model.mjs +156 -0
- package/src/tui/components/status-line/local-line.mjs +10 -2
- package/src/tui/dist/index.mjs +2897 -1722
- package/src/tui/session/active-tool-summary.mjs +1 -1
- package/src/tui/session/context-state.mjs +4 -5
- package/src/tui/session/goal-continuation/continuation-queue.mjs +2 -3
- package/src/tui/session/goal-continuation/deadline-delivery.mjs +4 -2
- package/src/tui/session/goal-continuation/session-boundary.mjs +21 -0
- package/src/tui/session/quota-resume.mjs +140 -61
- package/src/tui/session/session-api/commands.mjs +14 -10
- package/src/tui/session/session-api/controls.mjs +14 -2
- package/src/tui/session/session-api/integrations.mjs +9 -2
- package/src/tui/session/session-api/lifecycle/dispose.mjs +3 -9
- package/src/tui/session/session-api/lifecycle/resume.mjs +2 -7
- package/src/tui/session/session-api/lifecycle.mjs +14 -11
- package/src/tui/session/session-api/media.mjs +2 -0
- package/src/tui/session/session-api/routes.mjs +81 -57
- package/src/tui/session/session-api/settings.mjs +9 -3
- package/src/tui/session/session-api/worktree.mjs +3 -2
- package/src/tui/session/session-api.mjs +1 -0
- package/src/tui/session/session-flow/auto-clear.mjs +1 -3
- package/src/tui/session/session-flow/drain.mjs +6 -4
- package/src/tui/session/session-flow/queue/entry-shape.mjs +2 -0
- package/src/tui/session/session-flow/queue/take-entries.mjs +2 -1
- package/src/tui/session/session-flow/queue.mjs +1 -1
- package/src/tui/session/tool-approval.mjs +20 -8
- package/src/tui/session/transcript-spill.mjs +14 -7
- package/src/tui/session/transcript-store/streaming-tail.mjs +1 -1
- package/src/tui/session/tui-steering-persist.mjs +3 -5
- package/src/tui/session/turn-quiet.mjs +53 -0
- package/src/tui/session/turn-stream.mjs +179 -32
- package/src/tui/session/turn.mjs +50 -36
- package/src/tui/session/worktree-setup-notice.mjs +38 -0
- package/src/tui/spinner-meta.mjs +10 -0
- package/src/tui/spinner-verbs.mjs +3 -0
- package/src/ui/statusline.mjs +13 -3
- package/src/workflows/default/WORKFLOW.md +3 -1
- package/src/runtime/agent/orchestrator/providers/model-pricing-rates.mjs +0 -1
- package/src/runtime/agent/orchestrator/session/manager/foreign-pending-messages.mjs +0 -346
- package/src/runtime/agent/orchestrator/session/manager/session-owner-liveness.mjs +0 -117
- package/src/runtime/agent/orchestrator/session/store/paths-heartbeat.mjs +0 -246
- package/src/session-runtime/services/agent-tool/terminal-reaper/reap-timers.mjs +0 -142
- package/src/session-runtime/turn/share-ops.mjs +0 -77
- package/src/tui/session/cross-surface-share.mjs +0 -406
- package/src/tui/session/live-share/delta.mjs +0 -153
- package/src/tui/session/live-share/mirror.mjs +0 -106
- package/src/tui/session/live-share/owner.mjs +0 -254
- package/src/tui/session/live-share/retry.mjs +0 -54
- package/src/tui/session/live-share/viewer/frame-router.mjs +0 -32
- package/src/tui/session/live-share/viewer/pipe-client.mjs +0 -108
- package/src/tui/session/live-share/viewer/submit-acks.mjs +0 -65
- package/src/tui/session/live-share/viewer/sync-waiters.mjs +0 -53
- package/src/tui/session/live-share/viewer.mjs +0 -99
- package/src/tui/session/live-share/wire.mjs +0 -44
- package/src/tui/session/live-share.mjs +0 -154
- package/src/tui/session/shared-dir-watch.mjs +0 -69
|
@@ -175,6 +175,24 @@ export function appendBuffered(path, text) {
|
|
|
175
175
|
}
|
|
176
176
|
}
|
|
177
177
|
|
|
178
|
+
/**
|
|
179
|
+
* Drop every not-yet-written chunk for `path` (its file is being deleted, so a
|
|
180
|
+
* later flush must not recreate it). A write already handed to the OS cannot
|
|
181
|
+
* be recalled; callers unlink after this and it lands before or is removed.
|
|
182
|
+
*/
|
|
183
|
+
export function discardBuffered(path) {
|
|
184
|
+
const q = queues.get(path);
|
|
185
|
+
if (!q) return;
|
|
186
|
+
if (q.timer) {
|
|
187
|
+
clearTimeout(q.timer);
|
|
188
|
+
q.timer = null;
|
|
189
|
+
}
|
|
190
|
+
q.chunks = [];
|
|
191
|
+
q.bytes = 0;
|
|
192
|
+
q.failCount = 0;
|
|
193
|
+
deleteIfIdle(path, q);
|
|
194
|
+
}
|
|
195
|
+
|
|
178
196
|
/** Observable overflow counters for buffered append queues. */
|
|
179
197
|
export function getBufferedAppenderStats(path) {
|
|
180
198
|
const q = queues.get(path);
|
|
@@ -18,8 +18,10 @@ import {
|
|
|
18
18
|
backupUserData,
|
|
19
19
|
backupUserDataAsync,
|
|
20
20
|
markUserDataInitialized,
|
|
21
|
+
ensureUserDataInitialized,
|
|
21
22
|
loadLatestMixdogConfigFromBackup,
|
|
22
|
-
|
|
23
|
+
isUserDataRecoveryExpected,
|
|
24
|
+
findLegacyUserDataEvidence,
|
|
23
25
|
} from './user-data-guard.mjs';
|
|
24
26
|
import { AGENT_PROVIDER_ENV, AGENT_PROVIDER_ENV_ALIASES, getAgentApiKey } from './provider-api-key.mjs';
|
|
25
27
|
|
|
@@ -236,7 +238,7 @@ function readConfigFile() {
|
|
|
236
238
|
}
|
|
237
239
|
}
|
|
238
240
|
|
|
239
|
-
function writeConfigFile(data) {
|
|
241
|
+
function writeConfigFile(data, postBackupReason = 'post-config-write') {
|
|
240
242
|
// R4 data-at-rest: mixdog-config.json holds provider apiKeys; clamp to
|
|
241
243
|
// owner-only on POSIX via 0o600/0o700 mode bits, AND fail-closed on
|
|
242
244
|
// Windows where those bits are advisory — `secret: true` makes the
|
|
@@ -261,29 +263,76 @@ function writeConfigFile(data) {
|
|
|
261
263
|
markUserDataInitialized(resolvePluginData());
|
|
262
264
|
} catch {}
|
|
263
265
|
try {
|
|
264
|
-
backupUserData(resolvePluginData(),
|
|
266
|
+
backupUserData(resolvePluginData(), postBackupReason);
|
|
265
267
|
} catch {}
|
|
266
268
|
}
|
|
267
269
|
|
|
270
|
+
// Config paths whose restore could not be persisted: the in-memory restore is
|
|
271
|
+
// still served, but the failure is logged (and the write retried) only once
|
|
272
|
+
// per process instead of on every read.
|
|
273
|
+
const _restorePersistFailed = new Set();
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* Write a config restored on a plain read back to disk through the normal save
|
|
277
|
+
* path (atomic write + backups), so later reads hit the file instead of
|
|
278
|
+
* restoring again. Try-once lock: a contended lock means a writer (possibly
|
|
279
|
+
* this process's own outer RMW) is about to persist, so the next read retries.
|
|
280
|
+
*/
|
|
281
|
+
function persistRestoredConfig(restored) {
|
|
282
|
+
const path = configPath();
|
|
283
|
+
if (_restorePersistFailed.has(path)) return;
|
|
284
|
+
try {
|
|
285
|
+
const wrote = withFileLockSync(
|
|
286
|
+
`${path}.lock`,
|
|
287
|
+
() => {
|
|
288
|
+
if (existsSync(path)) return false;
|
|
289
|
+
writeAll(restored, 'post-restore');
|
|
290
|
+
return true;
|
|
291
|
+
},
|
|
292
|
+
{ timeoutMs: 0 }
|
|
293
|
+
);
|
|
294
|
+
if (wrote) {
|
|
295
|
+
process.stderr.write(
|
|
296
|
+
'[config] read: restored mixdog-config.json from latest user-data backup (missing after init) and saved it\n'
|
|
297
|
+
);
|
|
298
|
+
}
|
|
299
|
+
} catch (err) {
|
|
300
|
+
if (err?.code === 'ELOCKCONTENDED') return;
|
|
301
|
+
_restorePersistFailed.add(path);
|
|
302
|
+
process.stderr.write(
|
|
303
|
+
`[config] read: restored mixdog-config.json from latest user-data backup (missing after init); saving it failed, serving it from memory: ${err?.message || err}\n`
|
|
304
|
+
);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
|
|
268
308
|
function readAll() {
|
|
269
309
|
const parsed = readConfigFile();
|
|
270
|
-
if (parsed != null)
|
|
310
|
+
if (parsed != null) {
|
|
311
|
+
// A data dir from before the in-dir init marker gets one (plus a first
|
|
312
|
+
// scoped snapshot) once per process, so its config stays recoverable.
|
|
313
|
+
try {
|
|
314
|
+
ensureUserDataInitialized(resolvePluginData());
|
|
315
|
+
} catch {}
|
|
316
|
+
return canonicalizeUnifiedConfig(parsed);
|
|
317
|
+
}
|
|
271
318
|
// Symmetric with readAllForRmW(): a missing/unreadable config on a data
|
|
272
319
|
// dir that was previously initialized means the file was LOST (deleted,
|
|
273
|
-
// failed write), not a fresh install.
|
|
320
|
+
// failed write), not a fresh install. A recreated data dir has no marker
|
|
321
|
+
// and starts fresh. Self-heal from this data dir's newest
|
|
274
322
|
// structurally-complete backup instead of silently collapsing to {} —
|
|
275
323
|
// which callers (readSection/getCapabilities) merge with in-memory
|
|
276
|
-
// defaults, dropping the user's presets/agent routes/sections.
|
|
277
|
-
//
|
|
278
|
-
//
|
|
279
|
-
//
|
|
280
|
-
|
|
324
|
+
// defaults, dropping the user's presets/agent routes/sections. The restore
|
|
325
|
+
// is persisted under the config lock (only if the file is still missing) so
|
|
326
|
+
// later reads hit the file instead of restoring and logging again.
|
|
327
|
+
// An upgraded data dir (legacy marker / matching legacy backup, no in-dir
|
|
328
|
+
// marker yet) is a recovery case too; without a verifiable backup reads stay
|
|
329
|
+
// empty and RMW writes refuse (see readAllForRmW).
|
|
330
|
+
if (isUserDataRecoveryExpected(resolvePluginData())) {
|
|
281
331
|
const restored = loadLatestMixdogConfigFromBackup(resolvePluginData());
|
|
282
332
|
if (restored && isPlainObject(restored)) {
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
return canonicalizeUnifiedConfig(restored);
|
|
333
|
+
const config = canonicalizeUnifiedConfig(restored);
|
|
334
|
+
persistRestoredConfig(config);
|
|
335
|
+
return config;
|
|
287
336
|
}
|
|
288
337
|
}
|
|
289
338
|
return {};
|
|
@@ -300,11 +349,22 @@ function quarantineMalformedConfig(parseErr) {
|
|
|
300
349
|
}
|
|
301
350
|
|
|
302
351
|
function restoreAllForRmWOrThrow(reason) {
|
|
303
|
-
const restored = loadLatestMixdogConfigFromBackup(resolvePluginData());
|
|
352
|
+
const restored = loadLatestMixdogConfigFromBackup(resolvePluginData(), { fresh: true });
|
|
304
353
|
if (restored && isPlainObject(restored)) {
|
|
305
354
|
process.stderr.write(`[config] RMW read: restored mixdog-config.json from latest user-data backup (${reason})\n`);
|
|
306
355
|
return restored;
|
|
307
356
|
}
|
|
357
|
+
const legacy = findLegacyUserDataEvidence(resolvePluginData(), { fresh: true });
|
|
358
|
+
if (legacy) {
|
|
359
|
+
const err = new Error(
|
|
360
|
+
`[config] mixdog-config.json is missing but this data dir (${resolvePluginData()}) was initialized by an older ` +
|
|
361
|
+
`Mixdog build and no backup verified to belong to it was found; refusing to write a fresh config over a ` +
|
|
362
|
+
`recoverable state. Restore mixdog-config.json from a backup under ${legacy.roots.join(' or ')}, or delete ` +
|
|
363
|
+
`the legacy marker(s) to start fresh: ${legacy.markers.join(', ') || '(none; matching legacy backups are incomplete)'}`
|
|
364
|
+
);
|
|
365
|
+
err.code = 'EUSERDATARECOVERY';
|
|
366
|
+
throw err;
|
|
367
|
+
}
|
|
308
368
|
throw new Error(
|
|
309
369
|
`[config] mixdog-config.json is unreadable and no valid backup was found (${reason}); refusing section write that would wipe other sections`
|
|
310
370
|
);
|
|
@@ -321,7 +381,7 @@ function readAllForRmW() {
|
|
|
321
381
|
raw = readFileSync(configPath(), 'utf8');
|
|
322
382
|
} catch (err) {
|
|
323
383
|
if (err.code === 'ENOENT') {
|
|
324
|
-
if (
|
|
384
|
+
if (isUserDataRecoveryExpected(resolvePluginData(), { fresh: true })) {
|
|
325
385
|
return restoreAllForRmWOrThrow('config file missing after user-data was initialized');
|
|
326
386
|
}
|
|
327
387
|
return {};
|
|
@@ -402,8 +462,8 @@ export function subscribeConfigChange(listener) {
|
|
|
402
462
|
};
|
|
403
463
|
}
|
|
404
464
|
|
|
405
|
-
function writeAll(data) {
|
|
406
|
-
writeConfigFile(canonicalizeUnifiedConfig(data));
|
|
465
|
+
function writeAll(data, postBackupReason) {
|
|
466
|
+
writeConfigFile(canonicalizeUnifiedConfig(data), postBackupReason);
|
|
407
467
|
notifyConfigChanged();
|
|
408
468
|
}
|
|
409
469
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { transportErrorText } from './transport-error-text.mjs';
|
|
2
2
|
import { describeError, safeErrorDetails } from './error-presentation.mjs';
|
|
3
3
|
import { oneLine } from './clean.mjs';
|
|
4
|
+
import { TIMEOUT_PHASE, isFirstByteTimeout } from './provider-timeout-phase.mjs';
|
|
4
5
|
|
|
5
6
|
// HTTP status carried by a provider/transport error, or 0 when absent.
|
|
6
7
|
export function errorHttpStatus(err) {
|
|
@@ -185,7 +186,9 @@ export function isCancelLikeError(error) {
|
|
|
185
186
|
const KIND_LINES = {
|
|
186
187
|
overloaded: 'Provider is busy at capacity.',
|
|
187
188
|
rate_limited: ({ retryAfterMs }) =>
|
|
188
|
-
retryAfterMs
|
|
189
|
+
retryAfterMs
|
|
190
|
+
? `Provider is rate-limited (retry in ${formatDurationMs(retryAfterMs)}).`
|
|
191
|
+
: 'Provider is rate-limited.',
|
|
189
192
|
quota_exhausted: 'Provider usage limit reached.',
|
|
190
193
|
entitlement: 'Not included in your plan.',
|
|
191
194
|
billing: 'Out of credits or at spend limit.',
|
|
@@ -198,7 +201,38 @@ const KIND_LINES = {
|
|
|
198
201
|
// A bare message carries none, so its wording keeps the legacy text path.
|
|
199
202
|
function hasTypedEvidence(error) {
|
|
200
203
|
if (!error || typeof error !== 'object') return false;
|
|
201
|
-
return
|
|
204
|
+
return (
|
|
205
|
+
Boolean(error.errorKind?.kind) || errorHttpStatus(error) > 0 || Boolean(error.code) || Boolean(error.retryAfterMs)
|
|
206
|
+
);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// The window a provider timeout names (providerTimeoutError's message), or 0.
|
|
210
|
+
const timedOutMs = (text) => Number(/timed out after (\d+)ms/i.exec(text)?.[1]) || 0;
|
|
211
|
+
|
|
212
|
+
// A provider timeout before the model produced anything (isFirstByteTimeout):
|
|
213
|
+
// the model is slow, not the connection.
|
|
214
|
+
function stillThinkingText(error, text) {
|
|
215
|
+
const ms = Number(error.waitedMs) || timedOutMs(text);
|
|
216
|
+
const provider =
|
|
217
|
+
typeof error.providerLabel === 'string' && error.providerLabel ? error.providerLabel : 'the provider';
|
|
218
|
+
const attempts = Number(error.attempts) > 0 ? `; attempts: ${Math.floor(Number(error.attempts))}` : '';
|
|
219
|
+
return `Model still thinking: no output in ${formatDurationMs(ms)}; ${provider} sent nothing yet${attempts}.`;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// Stamped provider timeout phases and stream cuts. Null when the error names
|
|
223
|
+
// neither, so the text rules below decide.
|
|
224
|
+
function typedStreamFailureText(error, text) {
|
|
225
|
+
if (!error || typeof error !== 'object') return null;
|
|
226
|
+
if (isFirstByteTimeout(error)) return stillThinkingText(error, text);
|
|
227
|
+
if (error.timeoutPhase === TIMEOUT_PHASE.IDLE) {
|
|
228
|
+
const ms = timedOutMs(text);
|
|
229
|
+
return ms > 0 ? `No progress ${formatDurationMs(ms)}.` : 'No progress.';
|
|
230
|
+
}
|
|
231
|
+
// A stream that ended before its finish marker lost its connection.
|
|
232
|
+
if (error.code === 'TRUNCATED_STREAM' && error.streamCorruption !== true) {
|
|
233
|
+
return 'Connection to the provider was lost (TRUNCATED_STREAM).';
|
|
234
|
+
}
|
|
235
|
+
return null;
|
|
202
236
|
}
|
|
203
237
|
|
|
204
238
|
export function presentErrorText(error, options = {}) {
|
|
@@ -215,12 +249,20 @@ export function presentErrorText(error, options = {}) {
|
|
|
215
249
|
const name = error && typeof error === 'object' ? String(error.name || '') : '';
|
|
216
250
|
const code = error && typeof error === 'object' ? String(error.code || '') : '';
|
|
217
251
|
const status = errorHttpStatus(error);
|
|
252
|
+
// The fixed request overhead error is actionable as written (sizes,
|
|
253
|
+
// contributors, remedy): keep its lines instead of a generic "Context too
|
|
254
|
+
// large." that would suggest compacting.
|
|
255
|
+
if (code === 'TOOL_SURFACE_EXCEEDS_CONTEXT' || /\(TOOL_SURFACE_EXCEEDS_CONTEXT\)/.test(text)) {
|
|
256
|
+
return stripErrorPrefix(text);
|
|
257
|
+
}
|
|
218
258
|
const jsonError = extractJsonError(text);
|
|
219
259
|
if (jsonError) text = jsonError;
|
|
220
260
|
const embeddedError = extractEmbeddedError(text);
|
|
221
261
|
if (embeddedError) text = embeddedError;
|
|
222
262
|
text = oneLine(stripErrorPrefix(text));
|
|
223
263
|
if (!text) return 'Unknown error';
|
|
264
|
+
const streamFailure = typedStreamFailureText(error, text);
|
|
265
|
+
if (streamFailure) return streamFailure;
|
|
224
266
|
|
|
225
267
|
if (code === 'PROVIDER_PREFIX_MUTATION' || name === 'ProviderPrefixMutationError') {
|
|
226
268
|
return 'Session state changed unexpectedly.';
|
|
@@ -276,9 +318,10 @@ export function presentErrorText(error, options = {}) {
|
|
|
276
318
|
return Number.isFinite(ms) && ms > 0 ? `No first response ${formatDurationMs(ms)}.` : 'No first response.';
|
|
277
319
|
}
|
|
278
320
|
|
|
321
|
+
// The agent's own watchdog, worded apart from any provider timeout.
|
|
279
322
|
const firstTransport = /first (?:transport|semantic response) stale\s*\((\d+)ms\)/i.exec(text);
|
|
280
323
|
if (firstTransport) {
|
|
281
|
-
return `
|
|
324
|
+
return `Agent watchdog stopped the run: no model response in ${formatDurationMs(firstTransport[1])}.`;
|
|
282
325
|
}
|
|
283
326
|
|
|
284
327
|
const firstResponse = /(?:agent\s+)?first response stale\s*\((\d+)ms\)/i.exec(text);
|
|
@@ -357,7 +400,8 @@ export function backgroundTaskFailureStatusLabel(status, error, options = {}) {
|
|
|
357
400
|
/^timeout$/i.test(statusNorm) ||
|
|
358
401
|
watchdog?.kind === 'timeout' ||
|
|
359
402
|
/first response stale/i.test(raw) ||
|
|
360
|
-
/no first response from/i.test(presented)
|
|
403
|
+
/no first response from/i.test(presented) ||
|
|
404
|
+
/^(?:Model still thinking|Agent watchdog stopped the run):/.test(presented)
|
|
361
405
|
)
|
|
362
406
|
head = 'Timeout';
|
|
363
407
|
else if (
|
|
@@ -278,12 +278,13 @@ function* releaseReclaimGuard(reclaim) {
|
|
|
278
278
|
|
|
279
279
|
// A lock is reclaimable when its recorded owner is dead, or when it names no
|
|
280
280
|
// owner at all and has outlived the stale window.
|
|
281
|
-
function lockReclaimable(owner, stat, staleMs) {
|
|
281
|
+
function lockReclaimable(owner, stat, staleMs, strictOwner = false) {
|
|
282
282
|
if (owner.pid !== null) return !ownerIsLive(owner);
|
|
283
|
+
if (strictOwner) return false;
|
|
283
284
|
return Date.now() - (Number(stat.mtimeMs) || 0) >= Math.max(0, staleMs);
|
|
284
285
|
}
|
|
285
286
|
|
|
286
|
-
function* tryReclaimStaleLock(lockPath, staleMs) {
|
|
287
|
+
function* tryReclaimStaleLock(lockPath, staleMs, strictOwner = false) {
|
|
287
288
|
let initial;
|
|
288
289
|
try {
|
|
289
290
|
initial = yield ['stat', lockPath];
|
|
@@ -291,7 +292,7 @@ function* tryReclaimStaleLock(lockPath, staleMs) {
|
|
|
291
292
|
return false;
|
|
292
293
|
}
|
|
293
294
|
const owner = yield* readLockOwner(lockPath);
|
|
294
|
-
if (!lockReclaimable(owner, initial, staleMs)) return false;
|
|
295
|
+
if (!lockReclaimable(owner, initial, staleMs, strictOwner)) return false;
|
|
295
296
|
const reclaim = yield* tryAcquireReclaimGuard(lockPath);
|
|
296
297
|
if (reclaim === null) return false;
|
|
297
298
|
try {
|
|
@@ -303,7 +304,7 @@ function* tryReclaimStaleLock(lockPath, staleMs) {
|
|
|
303
304
|
}
|
|
304
305
|
const currentOwner = yield* readLockOwner(lockPath);
|
|
305
306
|
if (currentOwner.pid !== owner.pid || currentOwner.token !== owner.token) return false;
|
|
306
|
-
if (lockReclaimable(currentOwner, current, staleMs)) {
|
|
307
|
+
if (lockReclaimable(currentOwner, current, staleMs, strictOwner)) {
|
|
307
308
|
try {
|
|
308
309
|
yield ['unlink', lockPath];
|
|
309
310
|
return true;
|
|
@@ -429,7 +430,7 @@ function* acquireLock(lockPath, opts, mode, markHeld, timing = null) {
|
|
|
429
430
|
// The reclaim runs synchronously in both modes: it is a few metadata
|
|
430
431
|
// calls, and an await inside it would let a process exit strand its guard.
|
|
431
432
|
try {
|
|
432
|
-
if (runSync(tryReclaimStaleLock(lockPath, staleMs))) continue;
|
|
433
|
+
if (runSync(tryReclaimStaleLock(lockPath, staleMs, opts.strictOwner === true))) continue;
|
|
433
434
|
} catch {}
|
|
434
435
|
if (timeoutMs <= 0) throw contentionError(lockPath, error, yield* describeLockHolder(lockPath));
|
|
435
436
|
if (Date.now() >= deadline) break;
|
|
@@ -1,3 +1,8 @@
|
|
|
1
1
|
export function enforceOwnerOnlyAclWin32(targetPath: string, options?: { fresh?: boolean }): void;
|
|
2
2
|
|
|
3
|
-
export function enforceOwnerOnlyAclWin32Async(
|
|
3
|
+
export function enforceOwnerOnlyAclWin32Async(
|
|
4
|
+
targetPath: string,
|
|
5
|
+
options?: { fresh?: boolean }
|
|
6
|
+
): Promise<void>;
|
|
7
|
+
|
|
8
|
+
export function enforceOwnerOnlyDirectoryWin32Async(targetPath: string): Promise<void>;
|
|
@@ -73,6 +73,16 @@ function icaclsPath() {
|
|
|
73
73
|
return path;
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
+
const quoteForPowerShell = (value) => `'${String(value).replaceAll("'", "''")}'`;
|
|
77
|
+
|
|
78
|
+
function powerShellCommand(icacls, script) {
|
|
79
|
+
return {
|
|
80
|
+
executable: join(dirname(icacls), 'WindowsPowerShell', 'v1.0', 'powershell.exe'),
|
|
81
|
+
label: 'Windows ACL update',
|
|
82
|
+
args: ['-NoProfile', '-NonInteractive', '-EncodedCommand', Buffer.from(script, 'utf16le').toString('base64')],
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
|
|
76
86
|
function ownerOnlyAclCommand(targetPath, sid, fresh, icacls) {
|
|
77
87
|
if (fresh) {
|
|
78
88
|
return {
|
|
@@ -84,7 +94,7 @@ function ownerOnlyAclCommand(targetPath, sid, fresh, icacls) {
|
|
|
84
94
|
// Never /reset a published secret: that temporarily restores broad parent
|
|
85
95
|
// grants, and a later failure leaves them in place. Build the protected DACL
|
|
86
96
|
// in memory and publish it in one native ACL update instead.
|
|
87
|
-
const quote =
|
|
97
|
+
const quote = quoteForPowerShell;
|
|
88
98
|
const script = [
|
|
89
99
|
"$ErrorActionPreference = 'Stop';",
|
|
90
100
|
`$path = ${quote(targetPath)};`,
|
|
@@ -100,11 +110,37 @@ function ownerOnlyAclCommand(targetPath, sid, fresh, icacls) {
|
|
|
100
110
|
'if ($directory) { [System.IO.Directory]::SetAccessControl($path, $acl) }',
|
|
101
111
|
'else { [System.IO.File]::SetAccessControl($path, $acl) };',
|
|
102
112
|
].join(' ');
|
|
103
|
-
return
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
113
|
+
return powerShellCommand(icacls, script);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Replaces a directory's whole DACL (explicit grants to anyone else included)
|
|
117
|
+
// with one protected, inheritable owner-only grant, in one native update, so
|
|
118
|
+
// files created inside need no ACL call of their own. Files already inside
|
|
119
|
+
// that carry an explicit grant or any other principal's grant are reset to
|
|
120
|
+
// inherit only that owner grant.
|
|
121
|
+
function ownerOnlyDirectoryCommand(targetPath, sid, icacls) {
|
|
122
|
+
const script = [
|
|
123
|
+
"$ErrorActionPreference = 'Stop';",
|
|
124
|
+
`$path = ${quoteForPowerShell(targetPath)};`,
|
|
125
|
+
`$sid = [System.Security.Principal.SecurityIdentifier]::new(${quoteForPowerShell(sid)});`,
|
|
126
|
+
'$acl = [System.Security.AccessControl.DirectorySecurity]::new();',
|
|
127
|
+
'$acl.SetAccessRuleProtection($true, $false);',
|
|
128
|
+
'$acl.AddAccessRule([System.Security.AccessControl.FileSystemAccessRule]::new(',
|
|
129
|
+
'$sid, [System.Security.AccessControl.FileSystemRights]::FullControl,',
|
|
130
|
+
"[System.Security.AccessControl.InheritanceFlags]'ContainerInherit, ObjectInherit',",
|
|
131
|
+
'[System.Security.AccessControl.PropagationFlags]::None,',
|
|
132
|
+
'[System.Security.AccessControl.AccessControlType]::Allow));',
|
|
133
|
+
'[System.IO.Directory]::SetAccessControl($path, $acl);',
|
|
134
|
+
'foreach ($file in [System.IO.Directory]::GetFiles($path)) {',
|
|
135
|
+
'$current = [System.IO.File]::GetAccessControl($file);',
|
|
136
|
+
'$rules = @($current.GetAccessRules($true, $true, [System.Security.Principal.SecurityIdentifier]));',
|
|
137
|
+
'$foreign = @($rules | Where-Object { -not $_.IsInherited -or $_.IdentityReference -ne $sid });',
|
|
138
|
+
'if ($current.AreAccessRulesProtected -or $foreign.Count -gt 0) {',
|
|
139
|
+
'$reset = [System.Security.AccessControl.FileSecurity]::new();',
|
|
140
|
+
'$reset.SetAccessRuleProtection($false, $false);',
|
|
141
|
+
'[System.IO.File]::SetAccessControl($file, $reset) } };',
|
|
142
|
+
].join(' ');
|
|
143
|
+
return powerShellCommand(icacls, script);
|
|
108
144
|
}
|
|
109
145
|
|
|
110
146
|
function aclFailure(targetPath, cause, label = 'icacls') {
|
|
@@ -143,3 +179,15 @@ export async function enforceOwnerOnlyAclWin32Async(targetPath, { fresh = false
|
|
|
143
179
|
throw aclFailure(targetPath, error, command.label);
|
|
144
180
|
}
|
|
145
181
|
}
|
|
182
|
+
|
|
183
|
+
export async function enforceOwnerOnlyDirectoryWin32Async(targetPath) {
|
|
184
|
+
if (process.platform !== 'win32') return;
|
|
185
|
+
const icacls = icaclsPath();
|
|
186
|
+
if (cachedUserSid === null) cachedUserSid = await resolveCurrentUserPrincipalAsync();
|
|
187
|
+
const command = ownerOnlyDirectoryCommand(targetPath, cachedUserSid, icacls);
|
|
188
|
+
try {
|
|
189
|
+
await execFileAsync(command.executable, command.args, { windowsHide: true, timeout: 15_000 });
|
|
190
|
+
} catch (error) {
|
|
191
|
+
throw aclFailure(targetPath, error, command.label);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
@@ -2,7 +2,6 @@ import { EFFORT_BETA_HEADER } from './anthropic-effort.mjs';
|
|
|
2
2
|
import { normalizeClaudeModelId } from './anthropic-thinking-contract.mjs';
|
|
3
3
|
import { getModelMetadataSync } from './model-catalog.mjs';
|
|
4
4
|
|
|
5
|
-
const EXTENDED_CACHE_TTL_BETA_HEADER = 'extended-cache-ttl-2025-04-11';
|
|
6
5
|
const INTERLEAVED_THINKING_BETA_HEADER = 'interleaved-thinking-2025-05-14';
|
|
7
6
|
const FAST_MODE_BETA_HEADER = 'fast-mode-2026-02-01';
|
|
8
7
|
const TOOL_SEARCH_BETA_HEADER = 'advanced-tool-use-2025-11-20';
|
|
@@ -23,7 +22,7 @@ export function supportsAnthropicFastMode(model) {
|
|
|
23
22
|
}
|
|
24
23
|
|
|
25
24
|
export function buildAnthropicBetaHeaders({
|
|
26
|
-
base =
|
|
25
|
+
base = INTERLEAVED_THINKING_BETA_HEADER,
|
|
27
26
|
fastMode = false,
|
|
28
27
|
toolSearch = false,
|
|
29
28
|
effort = false,
|
|
@@ -291,6 +291,12 @@ export function applyAnthropicEffortToBody(
|
|
|
291
291
|
) {
|
|
292
292
|
if (!body || typeof body !== 'object') return;
|
|
293
293
|
|
|
294
|
+
// A gateway that declares its own effort contract (DeepSeek ignores
|
|
295
|
+
// budget_tokens) projects effort itself; returning true skips the Claude rules.
|
|
296
|
+
if (typeof opts.messagesEffortProjection === 'function') {
|
|
297
|
+
if (opts.messagesEffortProjection(body, { model, effort: opts.effort }) === true) return;
|
|
298
|
+
}
|
|
299
|
+
|
|
294
300
|
const thinkingBudgetTokens = Number(opts.thinkingBudgetTokens);
|
|
295
301
|
if (Number.isFinite(thinkingBudgetTokens) && thinkingBudgetTokens > 0) {
|
|
296
302
|
assertAnthropicManualBudgetSupported(model);
|
|
@@ -28,6 +28,7 @@ export const ANTIGRAVITY_MODELS = Object.freeze([
|
|
|
28
28
|
low: 'gemini-3.1-pro-low',
|
|
29
29
|
high: 'gemini-3.1-pro-high',
|
|
30
30
|
}),
|
|
31
|
+
fallbackModel('gemini-4-argon', 'Gemini 4 Argon', 'gemini-pro', 1048576, 'gemini-4-argon', ['low', 'medium', 'high']),
|
|
31
32
|
fallbackModel('claude-opus-4-6-thinking', 'Claude Opus 4.6 (Thinking)', null, 250000, 'claude-opus-4-6-thinking', [
|
|
32
33
|
'low',
|
|
33
34
|
'medium',
|
|
@@ -8,6 +8,7 @@ import { currentProviderAccountId } from '../provider-auth-binding.mjs';
|
|
|
8
8
|
// fallback, catalog retry) runs its own accounting and its result or error
|
|
9
9
|
// then returns through the enclosing send, which must not write it again.
|
|
10
10
|
const recorded = new WeakSet();
|
|
11
|
+
const UNMEASURED_USAGE = Object.freeze({ inputTokens: null, inputTokensKnown: false });
|
|
11
12
|
const hasTokens = (usage) =>
|
|
12
13
|
['inputTokens', 'outputTokens', 'cachedTokens', 'cacheWriteTokens'].some((key) => Number(usage?.[key]) > 0);
|
|
13
14
|
// One rule for every reported usage object: tokens, or a provider-reported
|
|
@@ -51,7 +52,9 @@ export async function accountProviderSend(provider, instance, send, model, opts
|
|
|
51
52
|
// abandoned attempt or a failure shares that clock with the final attempt,
|
|
52
53
|
// so timing it too would count the same seconds twice and understate speed.
|
|
53
54
|
const record = async (result, id, owner, timed) => {
|
|
54
|
-
|
|
55
|
+
// A completed call that reported no usage is still a call: it is recorded
|
|
56
|
+
// as unmeasured (unknown input, unpriced) instead of vanishing from totals.
|
|
57
|
+
if (!result?.usage && !(timed && result && typeof result === 'object')) return;
|
|
55
58
|
// A nested send (e.g. a fallback model re-send) already stamped its own
|
|
56
59
|
// final attempt's tier; the outer context only saw the abandoned attempt.
|
|
57
60
|
result.requestServiceTier ??= identity.requestServiceTier || '';
|
|
@@ -59,7 +62,7 @@ export async function accountProviderSend(provider, instance, send, model, opts
|
|
|
59
62
|
if (openingError) throw openingError;
|
|
60
63
|
if (!ledger) return;
|
|
61
64
|
recorded.add(owner);
|
|
62
|
-
const usage = result.usage;
|
|
65
|
+
const usage = result.usage || UNMEASURED_USAGE;
|
|
63
66
|
const row = makeUsageRecord({
|
|
64
67
|
id: result.responseId ? undefined : id,
|
|
65
68
|
ts: Date.now(),
|
|
@@ -61,6 +61,8 @@ const add = (target, row) => {
|
|
|
61
61
|
costBilled: row.cost_source === 'provider' ? row.cost_usd : 0,
|
|
62
62
|
costEstimated: row.cost_source === 'provider' ? 0 : row.cost_usd,
|
|
63
63
|
});
|
|
64
|
+
// A call recorded without provider usage is unmeasured whatever its provider.
|
|
65
|
+
if (row.unmeasured && !usage.unmeasuredTurns) usage.unmeasuredTurns = usage.turns || 0;
|
|
64
66
|
for (const field of [
|
|
65
67
|
'turns',
|
|
66
68
|
'input',
|
|
@@ -311,6 +313,7 @@ export function readSessionUsage(db, sessionIds) {
|
|
|
311
313
|
json_extract(r.signature,'$[1]') AS model,
|
|
312
314
|
json_extract(r.signature,'$[4]') AS cost_source,
|
|
313
315
|
json_extract(r.signature,'$[7]') AS rank,
|
|
316
|
+
COALESCE(json_extract(json_extract(r.signature,'$[5]'),'$.inputTokensKnown'),1)=0 AS unmeasured,
|
|
314
317
|
m.turns,m.input,m.output,m.cache_read,m.cache_write,m.cost_usd,m.duration_ms,
|
|
315
318
|
m.speed_output,m.speed_ms
|
|
316
319
|
FROM mine m JOIN usage_routes r ON r.id=m.route
|
|
@@ -9,6 +9,15 @@ export function createLoopbackListener({
|
|
|
9
9
|
let current = null;
|
|
10
10
|
let closing = null;
|
|
11
11
|
|
|
12
|
+
// close() drops only the keep-alive sockets idle at that moment; one whose
|
|
13
|
+
// in-flight response ends later would hold the close for the server's whole
|
|
14
|
+
// keepAliveTimeout (~5 s). Drop each as its response settles while stopping.
|
|
15
|
+
server.on('request', (_req, res) => {
|
|
16
|
+
res.once('close', () => {
|
|
17
|
+
if (closing) server.closeIdleConnections();
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
|
|
12
21
|
function start() {
|
|
13
22
|
if (closing) return Promise.reject(new Error('HTTP listener is stopping'));
|
|
14
23
|
if (current) return current.promise;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export function canonicalRouteProvider(value: unknown): string;
|
|
2
|
+
export function routeChain(route: Record<string, unknown>): Record<string, unknown>[];
|
|
3
|
+
export function validateRouteChainProviders(routes: Record<string, unknown>[]): void;
|
|
4
|
+
export function normalizeRouteChain(
|
|
5
|
+
route: Record<string, unknown>,
|
|
6
|
+
normalizeLeaf: (route: Record<string, unknown>, fallback: Record<string, unknown>) => Record<string, unknown> | null,
|
|
7
|
+
fallback?: Record<string, unknown>
|
|
8
|
+
): Record<string, unknown> | null;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
const PROVIDER_ALIASES = Object.freeze({
|
|
2
|
+
'openai-api': 'openai',
|
|
3
|
+
'xai-api': 'xai',
|
|
4
|
+
'gemini-api': 'gemini',
|
|
5
|
+
'anthropic-api': 'anthropic',
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
export function canonicalRouteProvider(value) {
|
|
9
|
+
const id = String(value || '').trim();
|
|
10
|
+
return PROVIDER_ALIASES[id] || id;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function routeChain(route) {
|
|
14
|
+
if (!route || typeof route !== 'object' || Array.isArray(route)) return [];
|
|
15
|
+
const { fallbacks = [], ...primary } = route;
|
|
16
|
+
if (!Array.isArray(fallbacks)) throw new Error('route.fallbacks must be an array');
|
|
17
|
+
for (const entry of fallbacks) {
|
|
18
|
+
if (!entry || typeof entry !== 'object' || Array.isArray(entry) || Object.hasOwn(entry, 'fallbacks')) {
|
|
19
|
+
throw new Error('fallback routes must be leaf route objects');
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return [primary, ...fallbacks];
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function validateRouteChainProviders(routes) {
|
|
26
|
+
const providers = new Set();
|
|
27
|
+
for (const route of routes) {
|
|
28
|
+
const provider = canonicalRouteProvider(route.provider);
|
|
29
|
+
if (!provider || !String(route.model || '').trim()) throw new Error('route requires provider and model');
|
|
30
|
+
if (providers.has(provider)) throw new Error(`duplicate route provider "${provider}"`);
|
|
31
|
+
if (providers.size && provider === 'default') throw new Error('follow Main is only allowed as the primary route');
|
|
32
|
+
providers.add(provider);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function normalizeRouteChain(route, normalizeLeaf, fallback = {}) {
|
|
37
|
+
const raw = routeChain({ ...fallback, ...route });
|
|
38
|
+
const primary = normalizeLeaf(route, fallback);
|
|
39
|
+
if (!primary) return null;
|
|
40
|
+
const routes = raw.map((entry, index) => {
|
|
41
|
+
const normalized = index === 0 ? primary : normalizeLeaf(entry, {});
|
|
42
|
+
if (!normalized) throw new Error('fallback route requires provider and model');
|
|
43
|
+
return { ...normalized, provider: canonicalRouteProvider(normalized.provider) };
|
|
44
|
+
});
|
|
45
|
+
validateRouteChainProviders(routes);
|
|
46
|
+
const [first, ...rest] = routes;
|
|
47
|
+
return rest.length ? { ...first, fallbacks: rest } : first;
|
|
48
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { providerErrorKind } from '../agent/orchestrator/providers/provider-error-kind.mjs';
|
|
2
|
+
import { readStreamOutcome } from '../agent/orchestrator/providers/lib/stream-outcome.mjs';
|
|
3
|
+
|
|
4
|
+
const ELIGIBLE = new Set(['rate_limited', 'quota_exhausted', 'overloaded', 'transient']);
|
|
5
|
+
|
|
6
|
+
export function canFallbackRoute(error, { signal, outcome = readStreamOutcome(error), committed = false } = {}) {
|
|
7
|
+
if (signal?.aborted || committed || outcome.userAbort || outcome.stallObserved) return false;
|
|
8
|
+
if (
|
|
9
|
+
!outcome.replaySafe ||
|
|
10
|
+
outcome.observedOutput ||
|
|
11
|
+
outcome.toolCallsStarted ||
|
|
12
|
+
outcome.pendingToolInput ||
|
|
13
|
+
outcome.continuation ||
|
|
14
|
+
outcome.terminalObserved
|
|
15
|
+
)
|
|
16
|
+
return false;
|
|
17
|
+
const { kind, status } = providerErrorKind(error);
|
|
18
|
+
if (!ELIGIBLE.has(kind)) return false;
|
|
19
|
+
// A rejected HTTP request or a provider account-pool refusal proves no
|
|
20
|
+
// generation started. A transport disconnect alone does not.
|
|
21
|
+
return status === 429 || status === 503 || (kind === 'quota_exhausted' && error?.quotaExhausted != null);
|
|
22
|
+
}
|
|
@@ -25,3 +25,15 @@ export function isPidAlive(value) {
|
|
|
25
25
|
return error?.code === 'EPERM';
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
|
+
|
|
29
|
+
/** Destructive operations require proof of death, not merely a failed probe. */
|
|
30
|
+
export function isPidAliveOrUnknown(value) {
|
|
31
|
+
const pid = parsePid(value);
|
|
32
|
+
if (!pid) return true;
|
|
33
|
+
try {
|
|
34
|
+
process.kill(pid, 0);
|
|
35
|
+
return true;
|
|
36
|
+
} catch (error) {
|
|
37
|
+
return error?.code !== 'ESRCH';
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -72,12 +72,20 @@ export function getAgentApiKey(provider) {
|
|
|
72
72
|
/** The one API-key resolver for key-based providers: an explicit config key
|
|
73
73
|
* wins, otherwise the environment/keychain (getAgentApiKey). */
|
|
74
74
|
export function resolveProviderApiKey(provider, config) {
|
|
75
|
+
if (config?.apiKeyEnv) return process.env[config.apiKeyEnv] || '';
|
|
75
76
|
return config?.apiKey || getAgentApiKey(provider) || '';
|
|
76
77
|
}
|
|
77
78
|
|
|
79
|
+
/** Presence twin of resolveProviderApiKey, same precedence, no key value read. */
|
|
80
|
+
export function hasProviderApiKey(provider, config) {
|
|
81
|
+
if (config?.apiKeyEnv) return Boolean(process.env[config.apiKeyEnv]);
|
|
82
|
+
return Boolean(config?.apiKey) || hasAgentApiKey(provider);
|
|
83
|
+
}
|
|
84
|
+
|
|
78
85
|
/** Auth-error reload: the stored/environment key is re-read first so a
|
|
79
86
|
* rotated key beats the stale one captured in config. */
|
|
80
87
|
export function reloadProviderApiKey(provider, config) {
|
|
88
|
+
if (config?.apiKeyEnv) return process.env[config.apiKeyEnv] || '';
|
|
81
89
|
return getAgentApiKey(provider) || config?.apiKey || '';
|
|
82
90
|
}
|
|
83
91
|
|