mixdog 1.2.3 → 1.2.5
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/package.json +1 -1
- package/scripts/gate-local.mjs +6 -4
- package/scripts/lib/gate-scheduler.mjs +29 -11
- package/scripts/mobile-release.mjs +5 -4
- package/scripts/probe-provider-catalog.mjs +31 -0
- package/scripts/provider-pingpong-live.mjs +128 -38
- package/scripts/session-sweep.mjs +5 -25
- 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 +7 -1
- package/src/defaults/skills/image/SKILL.md +21 -23
- package/src/lib/keychain-cjs.cjs +13 -11
- package/src/output-styles/common.md +2 -1
- package/src/rules/agent/AGENT.md +7 -5
- package/src/rules/lead/LEAD.md +13 -13
- 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/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-error-contract.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-messages.mjs +2 -3
- 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 +2 -5
- package/src/runtime/agent/orchestrator/providers/anthropic.mjs +4 -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 +81 -10
- package/src/runtime/agent/orchestrator/providers/antigravity-retry-policy.mjs +109 -5
- package/src/runtime/agent/orchestrator/providers/antigravity-stream.mjs +2 -1
- package/src/runtime/agent/orchestrator/providers/antigravity-transport.mjs +107 -37
- package/src/runtime/agent/orchestrator/providers/command-code-oauth.mjs +4 -1
- package/src/runtime/agent/orchestrator/providers/cursor-auth.mjs +3 -1
- 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 +41 -11
- package/src/runtime/agent/orchestrator/providers/cursor-wire-stream-messages.mjs +67 -5
- package/src/runtime/agent/orchestrator/providers/cursor-wire.mjs +14 -4
- package/src/runtime/agent/orchestrator/providers/cursor.mjs +14 -1
- package/src/runtime/agent/orchestrator/providers/custom-provider-config.mjs +9 -6
- package/src/runtime/agent/orchestrator/providers/custom-provider.mjs +7 -2
- package/src/runtime/agent/orchestrator/providers/effort-configuration.mjs +26 -4
- package/src/runtime/agent/orchestrator/providers/gemini-cache.mjs +12 -6
- package/src/runtime/agent/orchestrator/providers/gemini-error-contract.mjs +14 -6
- package/src/runtime/agent/orchestrator/providers/gemini-request-body.mjs +4 -4
- 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 +6 -1
- package/src/runtime/agent/orchestrator/providers/gemini-schema.mjs +22 -10
- package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +4 -2
- package/src/runtime/agent/orchestrator/providers/gemini-thinking.mjs +33 -7
- package/src/runtime/agent/orchestrator/providers/gemini.mjs +11 -2
- package/src/runtime/agent/orchestrator/providers/grok-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +9 -2
- package/src/runtime/agent/orchestrator/providers/lib/claude-bridge-schema.mjs +9 -5
- package/src/runtime/agent/orchestrator/providers/lib/request-compression.mjs +86 -0
- package/src/runtime/agent/orchestrator/providers/lib/wire-pairing.mjs +4 -2
- package/src/runtime/agent/orchestrator/providers/media-normalization.mjs +16 -5
- package/src/runtime/agent/orchestrator/providers/mimo-oauth.mjs +7 -1
- package/src/runtime/agent/orchestrator/providers/model-proxy-provider.mjs +60 -16
- package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +11 -13
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-send.mjs +30 -19
- 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 +5 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-models.mjs +42 -5
- package/src/runtime/agent/orchestrator/providers/openai-compat-reasoning-field.mjs +13 -9
- package/src/runtime/agent/orchestrator/providers/openai-compat-response-normalization.mjs +1 -3
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses-parity.fixtures.mjs +18 -7
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses.mjs +36 -3
- package/src/runtime/agent/orchestrator/providers/openai-compat-retry-profile.mjs +51 -3
- package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +11 -1
- 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/terminal-frames.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/openai-responses-input.mjs +2 -1
- package/src/runtime/agent/orchestrator/providers/openai-responses-payload.mjs +7 -1
- package/src/runtime/agent/orchestrator/providers/openai-ws-delta.mjs +1 -4
- package/src/runtime/agent/orchestrator/providers/openai-ws-response-state/tool-calls.mjs +0 -1
- package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +7 -6
- package/src/runtime/agent/orchestrator/providers/opencode-go-gemini.mjs +13 -2
- package/src/runtime/agent/orchestrator/providers/opencode-go.mjs +4 -1
- package/src/runtime/agent/orchestrator/providers/openrouter.mjs +1 -2
- package/src/runtime/agent/orchestrator/providers/provider-error-kind.mjs +5 -4
- package/src/runtime/agent/orchestrator/providers/registry.mjs +9 -1
- package/src/runtime/agent/orchestrator/providers/retry-classification.mjs +2 -1
- package/src/runtime/agent/orchestrator/providers/wire-gateway.mjs +11 -4
- package/src/runtime/agent/orchestrator/providers/wire-route.mjs +14 -4
- package/src/runtime/agent/orchestrator/providers/xai-tool-search.fixtures.mjs +15 -3
- package/src/runtime/agent/orchestrator/runtime-core/ask-user-tool-defs.mjs +6 -2
- package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +8 -6
- package/src/runtime/agent/orchestrator/runtime-core/deferred-tool-availability.mjs +4 -1
- 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/skill-tool-loading.mjs +3 -1
- package/src/runtime/agent/orchestrator/runtime-core/tool-bridge-contract.mjs +6 -0
- package/src/runtime/agent/orchestrator/runtime-core/tool-bridge.mjs +10 -10
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +3 -1
- package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +46 -8
- 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 +3 -11
- package/src/runtime/agent/orchestrator/session/catalog-db/worker.mjs +6 -22
- package/src/runtime/agent/orchestrator/session/compact/messages.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/compact/runner.mjs +16 -2
- package/src/runtime/agent/orchestrator/session/compact/user-message-kind.mjs +28 -0
- package/src/runtime/agent/orchestrator/session/compaction-archive-capture.mjs +1 -1
- 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 +1 -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 +2 -4
- package/src/runtime/agent/orchestrator/session/loop/context-overflow.mjs +3 -3
- package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +0 -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 +4 -1
- package/src/runtime/agent/orchestrator/session/loop/provider-tool-exclusions.mjs +4 -1
- package/src/runtime/agent/orchestrator/session/loop/request-boundary.mjs +1 -4
- package/src/runtime/agent/orchestrator/session/loop/route-fallback.mjs +76 -0
- package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +5 -1
- package/src/runtime/agent/orchestrator/session/loop/step-auto-effort.mjs +8 -9
- package/src/runtime/agent/orchestrator/session/loop/tool-classify.mjs +6 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +15 -2
- package/src/runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs +1 -4
- package/src/runtime/agent/orchestrator/session/loop/tool-phase.mjs +3 -4
- 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 +21 -1
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +38 -13
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-failure.mjs +33 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-prepare.mjs +5 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +19 -1
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-state.mjs +57 -13
- 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 +29 -8
- 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 +32 -14
- package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +17 -33
- package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +29 -13
- package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +3 -3
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-recovery.mjs +45 -0
- package/src/runtime/agent/orchestrator/session/manager.mjs +2 -9
- package/src/runtime/agent/orchestrator/session/send-instrumentation.mjs +2 -1
- package/src/runtime/agent/orchestrator/session/send-with-recovery.mjs +5 -2
- package/src/runtime/agent/orchestrator/session/side-question.mjs +12 -7
- package/src/runtime/agent/orchestrator/session/store/lifecycle-barriers.mjs +5 -12
- 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/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 +5 -11
- 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 -32
- 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 +1 -1
- package/src/runtime/agent/orchestrator/session/store-agent-worker-pool.mjs +5 -8
- package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +160 -212
- package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +50 -116
- 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 +7 -8
- package/src/runtime/agent/orchestrator/session/store-transcript-projection.mjs +9 -20
- package/src/runtime/agent/orchestrator/session/store.mjs +3 -16
- package/src/runtime/agent/orchestrator/session/tool-batch/execute-call.mjs +11 -12
- package/src/runtime/agent/orchestrator/session/tool-batch/finalize.mjs +37 -13
- package/src/runtime/agent/orchestrator/session/tool-batch/pre-dispatch.mjs +15 -4
- package/src/runtime/agent/orchestrator/session/tool-schema-rejection.mjs +4 -2
- 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/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/external-tool-adapters.mjs +204 -10
- 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 +200 -17
- 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/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-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/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 +178 -178
- 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 +118 -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/lib/ingest/transcript-rows.mjs +1 -0
- package/src/runtime/memory/lib/pg/process.mjs +5 -7
- package/src/runtime/memory/lib/pg/supervisor.mjs +4 -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/pdf-html-runner.mjs +1 -1
- package/src/runtime/office/authoring/pptx-html-measure.mjs +1 -1
- package/src/runtime/office/authoring/xlsx-html-runner.mjs +1 -1
- package/src/runtime/office/core/office-write-ledger.mjs +1 -5
- package/src/runtime/office/index.mjs +2 -3
- package/src/runtime/office/pdf/pdf-analysis.mjs +0 -68
- 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-line-diff.mjs +11 -2
- package/src/runtime/shared/browser-launch.mjs +15 -0
- package/src/runtime/shared/err-text.mjs +42 -4
- package/src/runtime/shared/file-lock.mjs +6 -5
- package/src/runtime/shared/llm/anthropic-betas.mjs +1 -2
- package/src/runtime/shared/llm/provider-model-identities.mjs +1 -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 +6 -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/slow-span.mjs +8 -1
- package/src/runtime/shared/statusline/statusline-segments.mjs +24 -2
- package/src/runtime/shared/tool-card-model/card-header.mjs +2 -1
- package/src/runtime/shared/tool-output-budget.mjs +2 -0
- package/src/runtime/shared/tool-result-summary.mjs +16 -2
- package/src/runtime/shared/tool-status.mjs +3 -2
- package/src/runtime/shared/tool-surface.mjs +2 -3
- package/src/runtime/shared/tool-work-units.mjs +22 -15
- 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/transcript-file.mjs +10 -1
- package/src/runtime/shared/transcript-writer.mjs +14 -4
- package/src/runtime/shared/turn-changes.mjs +2 -1
- package/src/runtime/shared/turn-snapshot.mjs +11 -3
- 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 +6 -4
- package/src/runtime/shared/worktrees/contract.mjs +27 -1
- package/src/runtime/shared/worktrees/dependencies.mjs +456 -0
- package/src/runtime/shared/worktrees/file-recovery.mjs +29 -13
- package/src/runtime/shared/worktrees/git-head.mjs +22 -13
- 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 +378 -32
- package/src/runtime/shared/worktrees/owner.mjs +2 -1
- 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 +14 -10
- package/src/session-runtime/boot/apis.mjs +7 -1
- package/src/session-runtime/boot/config.mjs +2 -0
- package/src/session-runtime/boot/facade.mjs +3 -0
- package/src/session-runtime/boot/session.mjs +3 -2
- package/src/session-runtime/boot/tools.mjs +3 -0
- package/src/session-runtime/conversation-import/service.mjs +1 -1
- package/src/session-runtime/goal-facade-api.mjs +2 -2
- package/src/session-runtime/internal-tool-executor/ask-user-tool.mjs +44 -18
- package/src/session-runtime/internal-tool-executor/knowledge-tools.mjs +4 -1
- package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +22 -8
- package/src/session-runtime/internal-tool-executor.mjs +2 -0
- package/src/session-runtime/lifecycle/cold-heir.mjs +0 -1
- package/src/session-runtime/lifecycle/session-catalog.mjs +14 -16
- package/src/session-runtime/lifecycle/session-switch/session-delete.mjs +18 -53
- 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 +7 -16
- 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 +114 -34
- 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.mjs +9 -8
- 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/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/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/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/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 +9 -6
- 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 +3 -9
- 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.mjs +28 -8
- package/src/session-runtime/services/agent-tool.mjs +4 -0
- package/src/session-runtime/services/agent-watchdog-registry.mjs +2 -0
- package/src/session-runtime/services/provider-admin.mjs +77 -0
- 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.mjs +4 -5
- package/src/session-runtime/session-turn-api.mjs +3 -9
- package/src/session-runtime/settings-builtin-tools-api.mjs +9 -6
- package/src/session-runtime/setup-tool/executor.mjs +23 -5
- package/src/session-runtime/setup-tool/extended-actions.mjs +6 -6
- package/src/session-runtime/setup-tool/settings-contract.mjs +7 -2
- package/src/session-runtime/setup-tool/tool-defs.mjs +13 -1
- package/src/session-runtime/tool-policy-refresh.mjs +83 -32
- package/src/session-runtime/turn/agent-ops.mjs +49 -2
- package/src/session-runtime/turn/side-question-ops.mjs +1 -4
- package/src/session-runtime/turn/turn-run/ask-callbacks.mjs +2 -0
- package/src/session-runtime/turn/turn-run/turn-prepare.mjs +4 -0
- package/src/session-runtime/turn/turn-run/turn-settle.mjs +8 -2
- package/src/session-runtime/turn/turn-run.mjs +1 -36
- package/src/session-runtime/usage-stats-api.mjs +4 -1
- 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 +28 -36
- package/src/session-runtime/workspace/transition-steps.mjs +96 -95
- package/src/session-runtime/workspace/transitions.mjs +248 -68
- package/src/standalone/channel-transport.mjs +3 -4
- package/src/standalone/daemon-desktop-runtime.mjs +32 -1
- package/src/standalone/daemon-pg-stop.mjs +1 -3
- package/src/standalone/daemon-session-control.mjs +88 -0
- package/src/standalone/daemon-stored-session-views.mjs +23 -3
- package/src/standalone/daemon.mjs +2 -0
- package/src/standalone/desktop-service-registry.mjs +32 -5
- package/src/standalone/local-session-runtime.mjs +11 -12
- package/src/standalone/session-protocol.mjs +7 -0
- package/src/standalone/session-runtime-inline-host.mjs +2 -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-turns.mjs +17 -6
- package/src/standalone/session-service/session-calls/session-views.mjs +6 -0
- package/src/standalone/session-tool-output.mjs +82 -0
- package/src/tui/app/app-view.jsx +2 -1
- 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/slash-commands.mjs +6 -0
- package/src/tui/app/slash-dispatch/session-commands.mjs +49 -0
- package/src/tui/components/Spinner.jsx +4 -0
- package/src/tui/components/SpinnerByline.jsx +21 -2
- package/src/tui/components/status-line/local-line.mjs +10 -2
- package/src/tui/dist/index.mjs +529 -270
- package/src/tui/session/active-tool-summary.mjs +1 -1
- package/src/tui/session/context-state.mjs +0 -3
- 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 +4 -10
- package/src/tui/session/session-api/controls.mjs +12 -0
- package/src/tui/session/session-api/lifecycle/dispose.mjs +2 -9
- package/src/tui/session/session-api/lifecycle/resume.mjs +2 -7
- package/src/tui/session/session-api/lifecycle.mjs +13 -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 +3 -3
- package/src/tui/session/session-api/worktree.mjs +3 -2
- 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 +17 -8
- 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 +5 -1
- package/src/tui/session/turn.mjs +38 -31
- 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/ui/streaming-markdown-heal.mjs +70 -18
- 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 -302
- 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
|
@@ -2,55 +2,37 @@
|
|
|
2
2
|
// /v1/messages returns 200 for Content-Encoding: gzip, 400 for zstd). Large turn
|
|
3
3
|
// bodies (system prompt + history, typically 50-100KB+) compress ~5-10x,
|
|
4
4
|
// trimming upload time off every call's header wait. Env kill-switch
|
|
5
|
-
// (MIXDOG_ANTHROPIC_REQ_GZIP=0)
|
|
6
|
-
// 400
|
|
7
|
-
// ~8KB the CPU + header cost outweighs the upload saving.
|
|
8
|
-
import { promisify } from 'node:util';
|
|
9
|
-
import { gzip } from 'node:zlib';
|
|
5
|
+
// (MIXDOG_ANTHROPIC_REQ_GZIP=0); the gzip policy (8KB floor, fail-open,
|
|
6
|
+
// 400/415 plain resend + latch-on-success) lives in lib/request-compression.mjs.
|
|
10
7
|
import { getLlmDispatcher } from '../../../../shared/llm/http-agent.mjs';
|
|
11
8
|
import { claudeCliUserAgent } from '../anthropic-oauth-client-version.mjs';
|
|
12
9
|
import { ANTHROPIC_VERSION } from '../lib/anthropic-models.mjs';
|
|
10
|
+
import { sendGzipCompressed } from '../lib/request-compression.mjs';
|
|
13
11
|
|
|
14
12
|
const API_URL = 'https://api.anthropic.com/v1/messages';
|
|
15
13
|
export { ANTHROPIC_VERSION };
|
|
16
14
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
},
|
|
39
|
-
|
|
40
|
-
signal,
|
|
41
|
-
dispatcher: getLlmDispatcher(),
|
|
42
|
-
});
|
|
43
|
-
let response = await sendAttempt(useGzip);
|
|
44
|
-
if (useGzip && response.status === 400) {
|
|
45
|
-
// Latch OFF process-wide and retry this attempt uncompressed, so a
|
|
46
|
-
// server-side behavior change can never wedge the session.
|
|
47
|
-
gzipLatchedOff = true;
|
|
48
|
-
try {
|
|
49
|
-
await response.arrayBuffer();
|
|
50
|
-
} catch {
|
|
51
|
-
/* drain best-effort */
|
|
52
|
-
}
|
|
53
|
-
response = await sendAttempt(false);
|
|
54
|
-
}
|
|
55
|
-
return response;
|
|
15
|
+
export async function postMessages({ accessToken, requestBody, betaHeaders, signal, compress }) {
|
|
16
|
+
const headers = {
|
|
17
|
+
Authorization: `Bearer ${accessToken}`,
|
|
18
|
+
'anthropic-version': ANTHROPIC_VERSION,
|
|
19
|
+
'anthropic-beta': betaHeaders,
|
|
20
|
+
'anthropic-dangerous-direct-browser-access': 'true',
|
|
21
|
+
'user-agent': claudeCliUserAgent(),
|
|
22
|
+
'x-app': 'cli',
|
|
23
|
+
'Content-Type': 'application/json',
|
|
24
|
+
};
|
|
25
|
+
return sendGzipCompressed({
|
|
26
|
+
raw: Buffer.from(JSON.stringify(requestBody)),
|
|
27
|
+
headers,
|
|
28
|
+
compress,
|
|
29
|
+
send: (body, sendHeaders) =>
|
|
30
|
+
fetch(API_URL, {
|
|
31
|
+
method: 'POST',
|
|
32
|
+
headers: sendHeaders,
|
|
33
|
+
body,
|
|
34
|
+
signal,
|
|
35
|
+
dispatcher: getLlmDispatcher(),
|
|
36
|
+
}),
|
|
37
|
+
});
|
|
56
38
|
}
|
|
@@ -90,8 +90,7 @@ const _oauthRefreshes = new Map();
|
|
|
90
90
|
// Anthropic OAuth contract for first-party OAuth clients: Claude requests
|
|
91
91
|
// are gated on this exact system-prompt prefix (Haiku 5.5 included).
|
|
92
92
|
const CLAUDE_CODE_SYSTEM_PREFIX = "You are Claude Code, Anthropic's official CLI for Claude.";
|
|
93
|
-
const OAUTH_BETA_HEADERS =
|
|
94
|
-
'oauth-2025-04-20,interleaved-thinking-2025-05-14,context-management-2025-06-27,extended-cache-ttl-2025-04-11';
|
|
93
|
+
const OAUTH_BETA_HEADERS = 'oauth-2025-04-20,interleaved-thinking-2025-05-14,context-management-2025-06-27';
|
|
95
94
|
|
|
96
95
|
function logQuiet(line) {
|
|
97
96
|
if (!process.env.MIXDOG_QUIET_PROVIDER_LOG) process.stderr.write(`[anthropic-oauth] ${line}\n`);
|
|
@@ -676,9 +675,7 @@ export class AnthropicOAuthProvider {
|
|
|
676
675
|
response.status === 400 &&
|
|
677
676
|
opts.fast === true &&
|
|
678
677
|
!opts._fastModeRetry &&
|
|
679
|
-
fastModeDowngraded(
|
|
680
|
-
noteFastModeCapacityError({ httpStatus: 400, message: scrubbedText }, { fast: true })
|
|
681
|
-
)
|
|
678
|
+
fastModeDowngraded(noteFastModeCapacityError({ httpStatus: 400, message: scrubbedText }, { fast: true }))
|
|
682
679
|
) {
|
|
683
680
|
process.stderr.write(`[anthropic-oauth] fast mode is not enabled for this account; retrying at standard speed\n`);
|
|
684
681
|
return this.send(messages, useModel, tools, { ...opts, _fastModeRetry: true });
|
|
@@ -13,6 +13,7 @@ import { ANTHROPIC_MAX_MIDSTREAM_RETRIES, parseSSEStream } from './anthropic-sse
|
|
|
13
13
|
import { buildAnthropicBetaHeaders } from './anthropic-betas.mjs';
|
|
14
14
|
import { buildAnthropicApiRequest } from './anthropic-api-request.mjs';
|
|
15
15
|
import { isCustomProviderName } from './custom-reasoning.mjs';
|
|
16
|
+
import { createAnthropicApiKeyFetch } from './anthropic-api-key-fetch.mjs';
|
|
16
17
|
import { ANTHROPIC_EFFORT_LEVELS, withEffortRejectionFallback } from './effort-rejection.mjs';
|
|
17
18
|
import { armFirstByteWatchdog, createAnthropicApiTransport } from './anthropic-api-transport.mjs';
|
|
18
19
|
import { createAnthropicApiRecovery } from './anthropic-api-recovery.mjs';
|
|
@@ -75,6 +76,9 @@ export class AnthropicProvider {
|
|
|
75
76
|
return new (loadAnthropic())({
|
|
76
77
|
...credentials,
|
|
77
78
|
...(this.config.baseURL ? { baseURL: this.config.baseURL } : {}),
|
|
79
|
+
// Gzip only toward the official origin (decided per request URL); a
|
|
80
|
+
// custom-* gateway keeps the SDK's plain fetch.
|
|
81
|
+
...(custom ? {} : { fetch: createAnthropicApiKeyFetch() }),
|
|
78
82
|
defaultHeaders: {
|
|
79
83
|
...(betaHeaders ? { 'anthropic-beta': betaHeaders } : {}),
|
|
80
84
|
...(keyless ? { 'x-api-key': null, authorization: null } : {}),
|
|
@@ -193,6 +193,18 @@ function antigravityCatalogModels() {
|
|
|
193
193
|
return _mirror || ANTIGRAVITY_MODELS;
|
|
194
194
|
}
|
|
195
195
|
|
|
196
|
+
/**
|
|
197
|
+
* The catalog `family` ('gemini-pro', 'gemini-flash', 'gpt-oss') of a picker
|
|
198
|
+
* id or one of its wire ids, or null when no record carries one (Claude, or
|
|
199
|
+
* an id the catalog does not list).
|
|
200
|
+
*/
|
|
201
|
+
export function antigravityModelFamily(model, models = antigravityCatalogModels()) {
|
|
202
|
+
const id = String(model || '');
|
|
203
|
+
const wires = (entry) => (entry?.wire && typeof entry.wire === 'object' ? Object.values(entry.wire) : [entry?.wire]);
|
|
204
|
+
const record = models.find((entry) => entry?.id === id) || models.find((entry) => wires(entry).includes(id));
|
|
205
|
+
return typeof record?.family === 'string' && record.family ? record.family : null;
|
|
206
|
+
}
|
|
207
|
+
|
|
196
208
|
/**
|
|
197
209
|
* Turn a picker model + effort into the wire id the gateway accepts. Tiered
|
|
198
210
|
* families consume the effort (the id encodes it); a bare id whose record
|
|
@@ -228,17 +240,34 @@ function quotaRow(label, bucket) {
|
|
|
228
240
|
};
|
|
229
241
|
}
|
|
230
242
|
|
|
231
|
-
|
|
243
|
+
// The gateway's bucket ids; group names are display text and may change.
|
|
244
|
+
const GEMINI_5H_BUCKET_ID = 'gemini-5h';
|
|
245
|
+
const GEMINI_WEEKLY_BUCKET_ID = 'gemini-weekly';
|
|
246
|
+
const ARGON_WEEKLY_BUCKET_ID = 'gemini-argon-wtu-weekly';
|
|
247
|
+
// The "Claude and GPT models" group (Claude Opus, Claude Sonnet, GPT-OSS) has
|
|
248
|
+
// its own pair of buckets, separate from the Gemini counters.
|
|
249
|
+
const THIRD_PARTY_5H_BUCKET_ID = '3p-5h';
|
|
250
|
+
const THIRD_PARTY_WEEKLY_BUCKET_ID = '3p-weekly';
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* Gemini 5H/7D rows from retrieveUserQuotaSummary, the separate weekly limit
|
|
254
|
+
* of the Gemini 4 Argon group (its own group with only a weekly bucket), and
|
|
255
|
+
* the Claude/GPT-OSS 5H/7D pair. Rows are selected by bucket id and window.
|
|
256
|
+
* Missing fields stay omitted.
|
|
257
|
+
*/
|
|
232
258
|
export function antigravityQuotaWindows(summary) {
|
|
233
|
-
const groups = Array.isArray(summary?.groups) ? summary.groups : []
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
259
|
+
const groups = (Array.isArray(summary?.groups) ? summary.groups : []).filter(
|
|
260
|
+
(entry) => entry && typeof entry === 'object'
|
|
261
|
+
);
|
|
262
|
+
const buckets = groups.flatMap((entry) => (Array.isArray(entry.buckets) ? entry.buckets : []));
|
|
263
|
+
const bucket = (id, window) =>
|
|
264
|
+
buckets.find((entry) => entry && typeof entry === 'object' && entry.bucketId === id && entry.window === window) ??
|
|
265
|
+
null;
|
|
266
|
+
return [
|
|
267
|
+
quotaRow('5H', bucket(GEMINI_5H_BUCKET_ID, '5h')),
|
|
268
|
+
quotaRow('7D', bucket(GEMINI_WEEKLY_BUCKET_ID, 'weekly')),
|
|
269
|
+
quotaRow('7D Argon', bucket(ARGON_WEEKLY_BUCKET_ID, 'weekly')),
|
|
270
|
+
quotaRow('5H Claude/GPT', bucket(THIRD_PARTY_5H_BUCKET_ID, '5h')),
|
|
271
|
+
quotaRow('7D Claude/GPT', bucket(THIRD_PARTY_WEEKLY_BUCKET_ID, 'weekly')),
|
|
272
|
+
].filter(Boolean);
|
|
244
273
|
}
|
|
@@ -20,7 +20,11 @@ import { preconnect } from '../../../shared/llm/http-agent.mjs';
|
|
|
20
20
|
import { createAntigravityStreamCollector } from './antigravity-stream.mjs';
|
|
21
21
|
import { createAntigravityRequest } from './antigravity-transport.mjs';
|
|
22
22
|
import { finalizeAntigravityTurn } from './antigravity-response.mjs';
|
|
23
|
-
import {
|
|
23
|
+
import {
|
|
24
|
+
ANTIGRAVITY_ACCOUNT_COOLDOWN_POLICY,
|
|
25
|
+
antigravityFirstBytePolicy,
|
|
26
|
+
antigravityFirstResponseBudget,
|
|
27
|
+
} from './antigravity-retry-policy.mjs';
|
|
24
28
|
import {
|
|
25
29
|
CONTENT_ENDPOINT,
|
|
26
30
|
ANTIGRAVITY_MODELS,
|
|
@@ -97,6 +101,13 @@ export class AntigravityOAuthProvider {
|
|
|
97
101
|
return configured || CONTENT_ENDPOINT;
|
|
98
102
|
}
|
|
99
103
|
|
|
104
|
+
// Longest one send to `model` may wait for response headers / first output,
|
|
105
|
+
// the whole transport retry ladder included; the agent watchdog's
|
|
106
|
+
// first-response deadlines are floored above it.
|
|
107
|
+
firstResponseBudget(model) {
|
|
108
|
+
return antigravityFirstResponseBudget(antigravityFirstBytePolicy(model || DEFAULT_ANTIGRAVITY_MODEL));
|
|
109
|
+
}
|
|
110
|
+
|
|
100
111
|
_buildBody(messages, model, tools, opts) {
|
|
101
112
|
const body = buildAntigravityRequest(messages, model, tools, opts, this._projectId);
|
|
102
113
|
dumpAntigravityRequest(body);
|
|
@@ -169,6 +180,7 @@ export class AntigravityOAuthProvider {
|
|
|
169
180
|
signal: passthrough.signal,
|
|
170
181
|
collector,
|
|
171
182
|
sleepFn: this.config.sleepFn,
|
|
183
|
+
firstByte: antigravityFirstBytePolicy(useModel),
|
|
172
184
|
});
|
|
173
185
|
try {
|
|
174
186
|
try {
|
|
@@ -60,9 +60,8 @@ function coalesceClaudeThoughts(parts) {
|
|
|
60
60
|
out.push(part);
|
|
61
61
|
continue;
|
|
62
62
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
: { ...part, text: typeof part.text === 'string' ? part.text : '' };
|
|
63
|
+
const partText = typeof part.text === 'string' ? part.text : '';
|
|
64
|
+
open = open ? { ...open, ...part, text: `${open.text}${partText}` } : { ...part, text: partText };
|
|
66
65
|
if (typeof part.thoughtSignature === 'string') {
|
|
67
66
|
out.push(open);
|
|
68
67
|
open = null;
|
|
@@ -72,6 +71,30 @@ function coalesceClaudeThoughts(parts) {
|
|
|
72
71
|
return out;
|
|
73
72
|
}
|
|
74
73
|
|
|
74
|
+
// The validator-bypass sentinel is a Gemini wire token: the Claude bridge
|
|
75
|
+
// sends a thinking block carrying it (or no signature at all) without a
|
|
76
|
+
// signature and Anthropic rejects the request ("thinking.signature: Field
|
|
77
|
+
// required"). Only a signature this route recorded is replayed to Claude;
|
|
78
|
+
// any other signature is removed, and a thinking block left without one (an
|
|
79
|
+
// interrupted run, another model's or provider's turn, legacy metadata) is
|
|
80
|
+
// dropped rather than turned into visible text.
|
|
81
|
+
const hasOwnClaudeSignature = (part) =>
|
|
82
|
+
typeof part.thoughtSignature === 'string' &&
|
|
83
|
+
part.thoughtSignature !== '' &&
|
|
84
|
+
part.thoughtSignature !== THOUGHT_SIGNATURE_SENTINEL;
|
|
85
|
+
|
|
86
|
+
function claudeReplayParts(parts, own) {
|
|
87
|
+
const signed = parts.map((part) => {
|
|
88
|
+
if (!part || typeof part !== 'object' || !('thoughtSignature' in part)) return part;
|
|
89
|
+
if (own && hasOwnClaudeSignature(part)) return part;
|
|
90
|
+
const { thoughtSignature: _foreign, ...unsigned } = part;
|
|
91
|
+
return unsigned;
|
|
92
|
+
});
|
|
93
|
+
return coalesceClaudeThoughts(signed.filter((part) => !isEmptyPlainTextPart(part))).filter(
|
|
94
|
+
(part) => part?.thought !== true || hasOwnClaudeSignature(part)
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
|
|
75
98
|
function signatureSafeMessages(messages, model) {
|
|
76
99
|
const claude = isAntigravityClaude(model);
|
|
77
100
|
return messages.flatMap((message) => {
|
|
@@ -80,11 +103,8 @@ function signatureSafeMessages(messages, model) {
|
|
|
80
103
|
// Repair tool signatures only after the complete history establishes
|
|
81
104
|
// the active turn, not while normalizing an isolated older message.
|
|
82
105
|
const sourceParts = ownParts || toGeminiContents([message], model, { repairToolSignatures: false })[0]?.parts;
|
|
83
|
-
const parts =
|
|
84
|
-
|
|
85
|
-
? coalesceClaudeThoughts(sourceParts.filter((part) => !isEmptyPlainTextPart(part)))
|
|
86
|
-
: sourceParts;
|
|
87
|
-
// A turn that held only empty parts is omitted, not sent as parts:[].
|
|
106
|
+
const parts = claude && sourceParts ? claudeReplayParts(sourceParts, !!ownParts) : sourceParts;
|
|
107
|
+
// A turn that held only empty or dropped parts is omitted, not sent as parts:[].
|
|
88
108
|
if (sourceParts?.length && !parts.length) return [];
|
|
89
109
|
if (!parts?.length) return [message];
|
|
90
110
|
for (const part of parts) {
|
|
@@ -100,6 +120,56 @@ function signatureSafeMessages(messages, model) {
|
|
|
100
120
|
});
|
|
101
121
|
}
|
|
102
122
|
|
|
123
|
+
const isToolResultTurn = (content) =>
|
|
124
|
+
content?.role === 'user' && !!content.parts?.some((part) => part?.functionResponse);
|
|
125
|
+
const isPromptTurn = (content) => content?.role === 'user' && !isToolResultTurn(content);
|
|
126
|
+
const hasSignedThinking = (content) =>
|
|
127
|
+
!!content?.parts?.some((part) => part?.thought === true && hasOwnClaudeSignature(part));
|
|
128
|
+
|
|
129
|
+
// With thinking on, Claude rejects a tool loop whose turn did not open with a
|
|
130
|
+
// signed thinking block, and a block that was dropped (unsigned, foreign or
|
|
131
|
+
// compacted away) cannot be restored. The outgoing request closes that loop
|
|
132
|
+
// instead: the closed part loses its thinking, a short model reply
|
|
133
|
+
// acknowledges the tool results, and a user nudge opens a fresh turn that
|
|
134
|
+
// Claude starts with new thinking. The closure sits after the results of the
|
|
135
|
+
// turn's last unthought model message, so later steps keep the signed
|
|
136
|
+
// thinking that the fresh turn produced. Wire-only: the caller's messages and
|
|
137
|
+
// recorded replays are never touched.
|
|
138
|
+
function closeUnthoughtToolLoop(contents) {
|
|
139
|
+
if (!isToolResultTurn(contents.at(-1))) return contents;
|
|
140
|
+
const promptIndex = contents.findLastIndex(isPromptTurn);
|
|
141
|
+
const modelIndexes = [];
|
|
142
|
+
for (let index = promptIndex + 1; index < contents.length; index += 1) {
|
|
143
|
+
if (contents[index]?.role === 'model') modelIndexes.push(index);
|
|
144
|
+
}
|
|
145
|
+
if (!modelIndexes.length || hasSignedThinking(contents[modelIndexes[0]])) return contents;
|
|
146
|
+
const unthought = modelIndexes.findLast((index) => !hasSignedThinking(contents[index]));
|
|
147
|
+
let cut = unthought + 1;
|
|
148
|
+
let results = 0;
|
|
149
|
+
while (isToolResultTurn(contents[cut])) {
|
|
150
|
+
results += contents[cut].parts.filter((part) => part?.functionResponse).length;
|
|
151
|
+
cut += 1;
|
|
152
|
+
}
|
|
153
|
+
if (!results) return contents;
|
|
154
|
+
const closed = contents.slice(0, cut).flatMap((content) => {
|
|
155
|
+
if (content?.role !== 'model') return [content];
|
|
156
|
+
const parts = content.parts.filter((part) => part?.thought !== true);
|
|
157
|
+
return parts.length ? [{ ...content, parts }] : [];
|
|
158
|
+
});
|
|
159
|
+
const ack = results === 1 ? '[Tool result received.]' : `[${results} tool results received.]`;
|
|
160
|
+
return [
|
|
161
|
+
...closed,
|
|
162
|
+
{ role: 'model', parts: [{ text: ack }] },
|
|
163
|
+
{ role: 'user', parts: [{ text: '[Continue.]' }] },
|
|
164
|
+
...contents.slice(cut),
|
|
165
|
+
];
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// The request turns Claude thinking on through an effort level or token
|
|
169
|
+
// budget; a `-thinking` wire id thinks without either.
|
|
170
|
+
const claudeThinkingEnabled = (model, thinkingConfig) =>
|
|
171
|
+
!!(thinkingConfig.thinkingLevel || thinkingConfig.thinkingBudget) || /-thinking$/i.test(String(model));
|
|
172
|
+
|
|
103
173
|
function sessionId(contents) {
|
|
104
174
|
const first = contents.find((content) => content?.role === 'user');
|
|
105
175
|
const text = first?.parts?.map((part) => (typeof part?.text === 'string' ? part.text : '')).join('') || '';
|
|
@@ -155,10 +225,11 @@ export function buildAntigravityRequest(messages, model, tools, opts = {}, proje
|
|
|
155
225
|
.map((message) => message.content)
|
|
156
226
|
.join('\n\n');
|
|
157
227
|
const chatMessages = messages.filter((message) => message.role !== 'system');
|
|
158
|
-
const
|
|
159
|
-
if (!
|
|
228
|
+
const history = toGeminiContents(signatureSafeMessages(chatMessages, model), model);
|
|
229
|
+
if (!history.length) throw new Error('No messages to send');
|
|
160
230
|
const claude = isAntigravityClaude(model);
|
|
161
231
|
const thinkingConfig = claude ? claudeThinkingConfig(opts) : antigravityGeminiThinkingConfig(model, opts);
|
|
232
|
+
const contents = claude && claudeThinkingEnabled(model, thinkingConfig) ? closeUnthoughtToolLoop(history) : history;
|
|
162
233
|
const generationConfig = {
|
|
163
234
|
...(claude ? { maxOutputTokens: CLAUDE_MAX_OUTPUT_TOKENS } : {}),
|
|
164
235
|
...(thinkingConfig ? { thinkingConfig } : {}),
|
|
@@ -14,11 +14,28 @@
|
|
|
14
14
|
* rotate; advice beyond 60s surfaces at once.
|
|
15
15
|
* QUOTA_EXHAUSTED (and any day/plan window): never retried here.
|
|
16
16
|
*
|
|
17
|
+
* First byte: the gateway queues or thinks server-side and sends the
|
|
18
|
+
* response headers together with the first chunk, so the window is chosen
|
|
19
|
+
* per model class from the catalog `family`: Pro-class Gemini (Pro tiers,
|
|
20
|
+
* Argon) waits MIXDOG_ANTIGRAVITY_FIRST_BYTE_TIMEOUT_MS (300s, clamped to
|
|
21
|
+
* the provider ceiling PROVIDER_MAX_BEFORE_WARN_MS, 285s by default),
|
|
22
|
+
* Flash-class Gemini the shared Gemini window (60s); both apply to the
|
|
23
|
+
* headers and again to the first chunk. A header or first-chunk timeout is
|
|
24
|
+
* retried at most MIXDOG_ANTIGRAVITY_FIRST_BYTE_RETRIES times (1), each
|
|
25
|
+
* retry doubling the window up to that ceiling; connect, 5xx and drop
|
|
26
|
+
* failures keep the full ladder (MIXDOG_ANTIGRAVITY_RETRY_MAX_ATTEMPTS, 4
|
|
27
|
+
* attempts, at MIXDOG_ANTIGRAVITY_RETRY_BACKOFF_MS 1s / 2s / 4s). Models
|
|
28
|
+
* without a Gemini family (Claude, GPT-OSS, unlisted ids) keep the shared
|
|
29
|
+
* Gemini window on that ladder.
|
|
30
|
+
*
|
|
17
31
|
* Replay stays gated by the stream-outcome contract: an attempt that exposed
|
|
18
32
|
* text or dispatched a tool is never re-issued.
|
|
19
33
|
*/
|
|
20
34
|
import { readStreamOutcome } from './lib/stream-outcome.mjs';
|
|
21
35
|
import { DETERMINISTIC_KINDS, providerErrorKind } from './provider-error-kind.mjs';
|
|
36
|
+
import { PROVIDER_MAX_BEFORE_WARN_MS, firstBytePolicyBudget, resolveTimeoutMs } from '../stall-policy.mjs';
|
|
37
|
+
import { GEMINI_FIRST_BYTE_TIMEOUT_MS } from './gemini-stream.mjs';
|
|
38
|
+
import { antigravityModelFamily } from './antigravity-oauth-catalog.mjs';
|
|
22
39
|
|
|
23
40
|
export const ANTIGRAVITY_CAPACITY_RETRIES = 3;
|
|
24
41
|
export const ANTIGRAVITY_CAPACITY_BASE_MS = 1000;
|
|
@@ -29,21 +46,103 @@ export const ANTIGRAVITY_CAPACITY_BUDGET_MS = 60_000;
|
|
|
29
46
|
export const ANTIGRAVITY_QUICK_RETRY_MS = 1000;
|
|
30
47
|
export const ANTIGRAVITY_QUICK_RETRY_MAX_ADVICE_MS = 60_000;
|
|
31
48
|
|
|
49
|
+
const DEFAULT_RETRY_BACKOFF_MS = Object.freeze([1000, 1000, 2000, 4000]);
|
|
50
|
+
|
|
51
|
+
function envInt(env, name, fallback, min, max) {
|
|
52
|
+
const raw = env?.[name];
|
|
53
|
+
if (raw == null || String(raw).trim() === '') return fallback;
|
|
54
|
+
const n = Number(raw);
|
|
55
|
+
if (!Number.isInteger(n)) return fallback;
|
|
56
|
+
return Math.min(Math.max(n, min), max);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function envBackoffMs(env, name) {
|
|
60
|
+
const raw = String(env?.[name] ?? '').trim();
|
|
61
|
+
if (!raw) return DEFAULT_RETRY_BACKOFF_MS;
|
|
62
|
+
const steps = raw.split(',').map((step) => Number(step.trim()));
|
|
63
|
+
if (!steps.every((step) => Number.isInteger(step) && step >= 0)) return DEFAULT_RETRY_BACKOFF_MS;
|
|
64
|
+
return Object.freeze(steps);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* The same-host ladder for everything that is not a 429, read from the
|
|
69
|
+
* environment: attempts (1–6), the backoff list (index n is the wait before
|
|
70
|
+
* attempt n) and how many first-byte timeouts a thinking model may retry.
|
|
71
|
+
*/
|
|
72
|
+
export function resolveAntigravityRetryConfig(env = process.env) {
|
|
73
|
+
return {
|
|
74
|
+
maxAttempts: envInt(env, 'MIXDOG_ANTIGRAVITY_RETRY_MAX_ATTEMPTS', ANTIGRAVITY_CAPACITY_RETRIES + 1, 1, 6),
|
|
75
|
+
backoffMs: envBackoffMs(env, 'MIXDOG_ANTIGRAVITY_RETRY_BACKOFF_MS'),
|
|
76
|
+
firstByteRetries: envInt(env, 'MIXDOG_ANTIGRAVITY_FIRST_BYTE_RETRIES', 1, 0, 5),
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const RETRY_CONFIG = resolveAntigravityRetryConfig();
|
|
81
|
+
|
|
32
82
|
// withRetry options for everything that is not a 429: transient transport and
|
|
33
83
|
// 5xx failures use the capacity schedule (the reference has no other same-host
|
|
34
84
|
// retry; the leading duplicate is the sleep-before-attempt index).
|
|
35
85
|
export const ANTIGRAVITY_RETRY = Object.freeze({
|
|
36
|
-
maxAttempts:
|
|
37
|
-
backoffMs:
|
|
86
|
+
maxAttempts: RETRY_CONFIG.maxAttempts,
|
|
87
|
+
backoffMs: RETRY_CONFIG.backoffMs,
|
|
38
88
|
retryJitterRatio: ANTIGRAVITY_CAPACITY_JITTER_RATIO,
|
|
39
89
|
// 429s are handled by antigravity429WaitMs, not the generic loop.
|
|
40
90
|
retry429: false,
|
|
41
91
|
});
|
|
42
92
|
|
|
93
|
+
export const ANTIGRAVITY_FIRST_BYTE_RETRIES = RETRY_CONFIG.firstByteRetries;
|
|
94
|
+
|
|
95
|
+
// Pro-class window: 300s requested, clamped to the provider ceiling.
|
|
96
|
+
export const ANTIGRAVITY_FIRST_BYTE_TIMEOUT_MS = resolveTimeoutMs('MIXDOG_ANTIGRAVITY_FIRST_BYTE_TIMEOUT_MS', 300_000, {
|
|
97
|
+
minMs: 30_000,
|
|
98
|
+
maxMs: PROVIDER_MAX_BEFORE_WARN_MS,
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
// First-attempt window per catalog family.
|
|
102
|
+
const FAMILY_FIRST_BYTE_MS = Object.freeze({
|
|
103
|
+
'gemini-pro': ANTIGRAVITY_FIRST_BYTE_TIMEOUT_MS,
|
|
104
|
+
'gemini-flash': GEMINI_FIRST_BYTE_TIMEOUT_MS,
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
// Models without a Gemini family: the shared Gemini window on the ordinary ladder.
|
|
108
|
+
export const ANTIGRAVITY_UNCLASSED_FIRST_BYTE = Object.freeze({
|
|
109
|
+
timeoutMs: GEMINI_FIRST_BYTE_TIMEOUT_MS,
|
|
110
|
+
maxMs: GEMINI_FIRST_BYTE_TIMEOUT_MS,
|
|
111
|
+
retries: null,
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* First-byte policy (see firstByteWindowMs) for one model, picker or wire id.
|
|
116
|
+
* The class comes from the catalog record's `family`.
|
|
117
|
+
*/
|
|
118
|
+
export function antigravityFirstBytePolicy(model, models) {
|
|
119
|
+
const timeoutMs = FAMILY_FIRST_BYTE_MS[antigravityModelFamily(model, models)];
|
|
120
|
+
if (!timeoutMs) return ANTIGRAVITY_UNCLASSED_FIRST_BYTE;
|
|
121
|
+
return {
|
|
122
|
+
timeoutMs,
|
|
123
|
+
maxMs: PROVIDER_MAX_BEFORE_WARN_MS,
|
|
124
|
+
retries: Math.min(ANTIGRAVITY_FIRST_BYTE_RETRIES, ANTIGRAVITY_RETRY.maxAttempts - 1),
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Longest a send may wait before its first output across the whole transport
|
|
130
|
+
* ladder ({ transportMs, semanticMs }, see firstBytePolicyBudget): the agent
|
|
131
|
+
* watchdog must not fire inside it. Drops and 5xx share the ladder with
|
|
132
|
+
* first-byte timeouts, so the budget is every backoff step of the ladder plus
|
|
133
|
+
* the windows of the first-byte timeouts the policy permits (all attempts for
|
|
134
|
+
* a policy without its own retry cap).
|
|
135
|
+
*/
|
|
136
|
+
export function antigravityFirstResponseBudget(policy, backoffMs = ANTIGRAVITY_RETRY.backoffMs) {
|
|
137
|
+
return firstBytePolicyBudget(policy, { attempts: ANTIGRAVITY_RETRY.maxAttempts, backoffMs });
|
|
138
|
+
}
|
|
139
|
+
|
|
43
140
|
/** Capacity wait for retry number `retryIndex` (0-based): 1s, 2s, 4s, 8s cap, ±10%. */
|
|
44
|
-
|
|
141
|
+
function antigravityCapacityDelayMs(retryIndex) {
|
|
45
142
|
const base = Math.min(ANTIGRAVITY_CAPACITY_BASE_MS * 2 ** retryIndex, ANTIGRAVITY_CAPACITY_MAX_MS);
|
|
46
|
-
return Math.round(
|
|
143
|
+
return Math.round(
|
|
144
|
+
base * (1 - ANTIGRAVITY_CAPACITY_JITTER_RATIO + Math.random() * 2 * ANTIGRAVITY_CAPACITY_JITTER_RATIO)
|
|
145
|
+
);
|
|
47
146
|
}
|
|
48
147
|
|
|
49
148
|
export function isAntigravityCapacityError(err) {
|
|
@@ -60,7 +159,12 @@ export function antigravity429WaitMs(err, state) {
|
|
|
60
159
|
if (status !== 429 && !(capacity && (status === 503 || status === 529))) return null;
|
|
61
160
|
if (readStreamOutcome(err).replaySafe !== true) return null;
|
|
62
161
|
const { kind, retryAfterMs } = providerErrorKind(err);
|
|
63
|
-
if (
|
|
162
|
+
if (
|
|
163
|
+
DETERMINISTIC_KINDS.has(kind) ||
|
|
164
|
+
err.code === 'quota_exhausted' ||
|
|
165
|
+
err.quotaScope === 'day' ||
|
|
166
|
+
err.quotaScope === 'plan'
|
|
167
|
+
) {
|
|
64
168
|
return null;
|
|
65
169
|
}
|
|
66
170
|
// Capacity waits at least the advised RetryInfo delay (the local schedule
|
|
@@ -80,10 +80,11 @@ export function createAntigravityStreamCollector({ tools, useModel, onToolCall,
|
|
|
80
80
|
textLeakGuard = null;
|
|
81
81
|
};
|
|
82
82
|
|
|
83
|
-
const consume = async (res, attemptSignal) => {
|
|
83
|
+
const consume = async (res, attemptSignal, { firstByteTimeoutMs } = {}) => {
|
|
84
84
|
try {
|
|
85
85
|
return await consumeGeminiRestStreamResponse(res, {
|
|
86
86
|
signal: attemptSignal,
|
|
87
|
+
firstByteTimeoutMs,
|
|
87
88
|
onStreamDelta,
|
|
88
89
|
onTextDelta: relayText,
|
|
89
90
|
onChunk,
|