mixdog 1.2.3 → 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/package.json +1 -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 +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 +6 -1
- package/src/defaults/skills/image/SKILL.md +21 -23
- package/src/lib/keychain-cjs.cjs +13 -11
- package/src/rules/agent/AGENT.md +7 -5
- 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/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 +136 -196
- 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/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 +478 -251
- 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/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
|
@@ -3,12 +3,14 @@
|
|
|
3
3
|
* to the shared stream state and relayed to the SSE sink. Returns the
|
|
4
4
|
* message's forward-progress kind for the watchdog.
|
|
5
5
|
*/
|
|
6
|
+
import { randomUUID } from 'node:crypto';
|
|
7
|
+
import { registerCursorNativeCall } from './cursor-native-context.mjs';
|
|
6
8
|
import { appendAgentTrace } from '../agent-trace.mjs';
|
|
7
9
|
import { decodeMessage } from './cursor-wire-protobuf.mjs';
|
|
8
10
|
import { MAX_CHECKPOINT_BYTES, cursorInteractionProgress } from './cursor-wire-guards.mjs';
|
|
9
11
|
import { buildCursorInteractionResponse } from './cursor-wire-interactions.mjs';
|
|
10
12
|
import { cursorError } from './cursor-wire-transport.mjs';
|
|
11
|
-
import { handleExecMessage, handleKvMessage, sendClientMessage } from './cursor-wire-exec.mjs';
|
|
13
|
+
import { handleExecMessage, handleKvMessage, sendClientMessage, sendToolResult } from './cursor-wire-exec.mjs';
|
|
12
14
|
|
|
13
15
|
// Unknown fields seen on every live frame: AgentServerMessage field 8 (timing
|
|
14
16
|
// doubles) and InteractionUpdate field 25 (epoch-ms timestamp). Never traced.
|
|
@@ -43,6 +45,31 @@ function traceUnknownFields(trace, sessionId, scope, unknown, noise) {
|
|
|
43
45
|
}
|
|
44
46
|
}
|
|
45
47
|
|
|
48
|
+
// Parent edit outcomes are diagnostics, not executable calls or read results.
|
|
49
|
+
function traceNativeEditFailure(trace, sessionId, update) {
|
|
50
|
+
const completed = update.toolCallCompleted;
|
|
51
|
+
const result = completed?.toolCall?.editToolCall?.result;
|
|
52
|
+
if (!result) return;
|
|
53
|
+
const outcome = ['fileNotFound', 'readPermissionDenied', 'writePermissionDenied', 'rejected', 'error'].find(
|
|
54
|
+
(key) => result[key] !== undefined
|
|
55
|
+
);
|
|
56
|
+
if (!outcome) return;
|
|
57
|
+
try {
|
|
58
|
+
trace({
|
|
59
|
+
sessionId,
|
|
60
|
+
kind: 'cursor_native_edit_failure',
|
|
61
|
+
provider: 'cursor',
|
|
62
|
+
payload: {
|
|
63
|
+
callId: (completed.callId || '').slice(0, 256),
|
|
64
|
+
modelCallId: (completed.modelCallId || '').slice(0, 256),
|
|
65
|
+
outcome,
|
|
66
|
+
},
|
|
67
|
+
});
|
|
68
|
+
} catch {
|
|
69
|
+
/* best-effort */
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
46
73
|
// Relays one interaction update to the SSE stream and returns its progress.
|
|
47
74
|
function applyInteractionUpdate(update, state, filter, emit) {
|
|
48
75
|
if (update.textDelta?.text) {
|
|
@@ -79,9 +106,32 @@ function applyCheckpointUpdate(update, conversation, state) {
|
|
|
79
106
|
}
|
|
80
107
|
|
|
81
108
|
// Announces a newly pending native/MCP tool call as a completion chunk once.
|
|
82
|
-
function announcePendingToolCall(state, pending, emit) {
|
|
83
|
-
|
|
109
|
+
function announcePendingToolCall(state, pending, emit, bridge, ownerSessionId) {
|
|
110
|
+
state.executions ??= new Map();
|
|
111
|
+
const executions = state.executions;
|
|
112
|
+
const execId = pending.exec.execId ?? pending.exec.id;
|
|
113
|
+
const previous = execId !== undefined ? executions.get(execId) : undefined;
|
|
114
|
+
if (previous) {
|
|
115
|
+
if (previous.completedResult) {
|
|
116
|
+
sendToolResult(
|
|
117
|
+
bridge,
|
|
118
|
+
{ ...previous, exec: pending.exec },
|
|
119
|
+
previous.completedResult.result,
|
|
120
|
+
previous.completedResult.ok
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
// A parent call can issue distinct executions; each needs its own local result.
|
|
126
|
+
if ([...executions.values(), ...state.pending].some((entry) => entry.toolCallId === pending.toolCallId)) {
|
|
127
|
+
pending.toolCallId = randomUUID();
|
|
128
|
+
}
|
|
129
|
+
if (execId !== undefined) executions.set(execId, pending);
|
|
130
|
+
registerCursorNativeCall(ownerSessionId, pending, executions);
|
|
84
131
|
state.pending.push(pending);
|
|
132
|
+
// Native execs may await their result before the server completes a step.
|
|
133
|
+
// The bridge hands off only after all currently received frames are whole.
|
|
134
|
+
if (pending.native) state.batchBoundaryReady = true;
|
|
85
135
|
emit({
|
|
86
136
|
tool_calls: [
|
|
87
137
|
{
|
|
@@ -101,12 +151,24 @@ function announcePendingToolCall(state, pending, emit) {
|
|
|
101
151
|
*/
|
|
102
152
|
export function processServerMessage(
|
|
103
153
|
bytes,
|
|
104
|
-
{
|
|
154
|
+
{
|
|
155
|
+
state,
|
|
156
|
+
filter,
|
|
157
|
+
emit,
|
|
158
|
+
conversation,
|
|
159
|
+
tools,
|
|
160
|
+
cloudRule,
|
|
161
|
+
bridge,
|
|
162
|
+
sessionId = '',
|
|
163
|
+
ownerSessionId = '',
|
|
164
|
+
trace = appendAgentTrace,
|
|
165
|
+
}
|
|
105
166
|
) {
|
|
106
167
|
const message = decodeMessage('AgentServerMessage', bytes);
|
|
107
168
|
traceUnknownFields(trace, sessionId, 'agent_server_message', message.$unknown, NOISE_SERVER_FIELDS);
|
|
108
169
|
if (message.interactionUpdate) {
|
|
109
170
|
traceUnknownFields(trace, sessionId, 'interaction_update', message.interactionUpdate.$unknown, NOISE_UPDATE_FIELDS);
|
|
171
|
+
traceNativeEditFailure(trace, sessionId, message.interactionUpdate);
|
|
110
172
|
}
|
|
111
173
|
if (message.interactionUpdate) return applyInteractionUpdate(message.interactionUpdate, state, filter, emit);
|
|
112
174
|
if (message.kvServerMessage) {
|
|
@@ -119,7 +181,7 @@ export function processServerMessage(
|
|
|
119
181
|
}
|
|
120
182
|
if (message.execServerMessage) {
|
|
121
183
|
const handled = handleExecMessage(bridge, message.execServerMessage, tools, cloudRule, (pending) =>
|
|
122
|
-
announcePendingToolCall(state, pending, emit)
|
|
184
|
+
announcePendingToolCall(state, pending, emit, bridge, ownerSessionId)
|
|
123
185
|
);
|
|
124
186
|
return handled === false ? 'park' : 'work';
|
|
125
187
|
}
|
|
@@ -328,11 +328,12 @@ function createPendingToolBatchResponse(active, model, key) {
|
|
|
328
328
|
}
|
|
329
329
|
|
|
330
330
|
// Stream state shared by the sink, the message router and the bridge controller.
|
|
331
|
-
function freshStreamState(sawTurnEnded) {
|
|
331
|
+
function freshStreamState(sawTurnEnded, executions) {
|
|
332
332
|
return {
|
|
333
333
|
outputTokens: 0,
|
|
334
334
|
contextTokens: null,
|
|
335
335
|
pending: [],
|
|
336
|
+
executions,
|
|
336
337
|
closed: false,
|
|
337
338
|
sawEnd: false,
|
|
338
339
|
sawTurnEnded: sawTurnEnded === true,
|
|
@@ -360,7 +361,9 @@ function createStreamResponse({
|
|
|
360
361
|
// Owning session, carried into the stored run so a session close can find
|
|
361
362
|
// and tear down the pending batch's bridge/heartbeat.
|
|
362
363
|
sessionId = '',
|
|
364
|
+
ownerSessionId = sessionId,
|
|
363
365
|
sawTurnEnded = false,
|
|
366
|
+
executions = new Map(),
|
|
364
367
|
restart = null,
|
|
365
368
|
sleep = undefined,
|
|
366
369
|
onStageChange = null,
|
|
@@ -376,7 +379,7 @@ function createStreamResponse({
|
|
|
376
379
|
const stream = new ReadableStream({
|
|
377
380
|
start(controller) {
|
|
378
381
|
const filter = thinkingFilter();
|
|
379
|
-
const state = freshStreamState(sawTurnEnded);
|
|
382
|
+
const state = freshStreamState(sawTurnEnded, executions);
|
|
380
383
|
const tuning = resolveCursorStreamTuning();
|
|
381
384
|
watchdog = createCursorStreamWatchdog({
|
|
382
385
|
idleTimeoutMs: tuning.idleTimeoutMs,
|
|
@@ -400,7 +403,7 @@ function createStreamResponse({
|
|
|
400
403
|
watchdog,
|
|
401
404
|
sink,
|
|
402
405
|
tuning,
|
|
403
|
-
run: { key, conversation, tools, cloudRule, modelParameters, maxMode, sessionId },
|
|
406
|
+
run: { key, conversation, tools, cloudRule, modelParameters, maxMode, sessionId, ownerSessionId },
|
|
404
407
|
runs,
|
|
405
408
|
restart,
|
|
406
409
|
sleep,
|
|
@@ -449,6 +452,7 @@ function resumeRun(active, toolResults, userText, model, key) {
|
|
|
449
452
|
}
|
|
450
453
|
const payload = { ...result, content: String(result.content ?? '') };
|
|
451
454
|
if (pendingUserText && pending.exec.execId === lastExecId) {
|
|
455
|
+
if (pending.native?.resultType === 'readResult') pending.nativeUserMessage = pendingUserText;
|
|
452
456
|
payload.content += `\n\n<user_message>\n${pendingUserText}\n</user_message>`;
|
|
453
457
|
userTextDelivered = true;
|
|
454
458
|
}
|
|
@@ -471,7 +475,11 @@ function noUserMessageResponse() {
|
|
|
471
475
|
});
|
|
472
476
|
}
|
|
473
477
|
|
|
474
|
-
export async function handleChatCompletion(
|
|
478
|
+
export async function handleChatCompletion(
|
|
479
|
+
body,
|
|
480
|
+
accessToken,
|
|
481
|
+
{ onStageChange = null, getAccessToken = null, resetActiveRun = false, ownerSessionId = '' } = {}
|
|
482
|
+
) {
|
|
475
483
|
await warmCursorClientVersion();
|
|
476
484
|
const parsed = parseMessages(body.messages);
|
|
477
485
|
if (
|
|
@@ -492,6 +500,7 @@ export async function handleChatCompletion(body, accessToken, { onStageChange =
|
|
|
492
500
|
const cloudRule = parsed.systems.join('\n\n') || undefined;
|
|
493
501
|
const active = activeRuns.get(key);
|
|
494
502
|
if (
|
|
503
|
+
!resetActiveRun &&
|
|
495
504
|
active &&
|
|
496
505
|
parsed.toolResults.length &&
|
|
497
506
|
active.bridge.alive &&
|
|
@@ -531,6 +540,7 @@ export async function handleChatCompletion(body, accessToken, { onStageChange =
|
|
|
531
540
|
maxMode,
|
|
532
541
|
key,
|
|
533
542
|
sessionId,
|
|
543
|
+
ownerSessionId,
|
|
534
544
|
onStageChange,
|
|
535
545
|
restart: async ({ fromCheckpoint, reason, error }) => {
|
|
536
546
|
if (reason === 'throttle') {
|
|
@@ -49,6 +49,7 @@ function toCursorMessages(messages, providerName, { nativePdf } = {}) {
|
|
|
49
49
|
...toolMessage,
|
|
50
50
|
mixdog_tool_error: message.toolKind === 'error' || message.isError === true,
|
|
51
51
|
...(media.length ? { mixdog_tool_media: media } : {}),
|
|
52
|
+
...(message.readWindow?.lineClipped === true ? { mixdog_read_window: { lineClipped: true } } : {}),
|
|
52
53
|
});
|
|
53
54
|
}
|
|
54
55
|
return output;
|
|
@@ -545,6 +546,9 @@ function selectCursorVariant(group, { effort = null, fast = false } = {}) {
|
|
|
545
546
|
class CursorProviderBase {
|
|
546
547
|
// Cursor's chat wire has no document block: PDFs lower to text.
|
|
547
548
|
nativePdf = false;
|
|
549
|
+
// Native read results are judged as exact source windows, so the tool
|
|
550
|
+
// finalizer reports their clipped lines next to the text.
|
|
551
|
+
consumesReadWindows = true;
|
|
548
552
|
|
|
549
553
|
static inputExcludesCache = false;
|
|
550
554
|
// The in-place stream retry budget is the whole recovery: a spent budget
|
|
@@ -640,6 +644,13 @@ class CursorProviderBase {
|
|
|
640
644
|
const response = await runtime.handleChatCompletion(body, accessToken, {
|
|
641
645
|
onStageChange: sendOpts.onStageChange,
|
|
642
646
|
getAccessToken: (options) => this._accessToken({ signal, ...options }),
|
|
647
|
+
// A deliberate history reset must reach Cursor's private parked run,
|
|
648
|
+
// not just the orchestrator's providerState.
|
|
649
|
+
resetActiveRun: Boolean(sendOpts.cacheBreakIntent),
|
|
650
|
+
// Native read/edit capabilities are process-local. An explicit empty
|
|
651
|
+
// executor (the model-proxy host: tools run in the server daemon)
|
|
652
|
+
// keeps every call an ordinary Mixdog tool call.
|
|
653
|
+
ownerSessionId: String(sendOpts.toolExecutionSessionId ?? (sendOpts.sessionId || '')),
|
|
643
654
|
});
|
|
644
655
|
try {
|
|
645
656
|
sendOpts.onStageChange?.('streaming');
|
|
@@ -699,7 +710,9 @@ class CursorProviderBase {
|
|
|
699
710
|
const sessionScope = String(
|
|
700
711
|
sendOpts.transportScope ||
|
|
701
712
|
sendOpts.sessionId ||
|
|
702
|
-
sendOpts.providerCacheKey ||
|
|
713
|
+
sendOpts.providerCacheKey ||
|
|
714
|
+
sendOpts.promptCacheKey ||
|
|
715
|
+
`cursor-call:${randomUUID()}`
|
|
703
716
|
);
|
|
704
717
|
const openAiTools = tools?.length
|
|
705
718
|
? toOpenAITools(acceptedWireTools(tools, 'openai', sendOpts.onToolExcluded, '[cursor] tool'))
|
|
@@ -386,6 +386,14 @@ function catalogLevels(row) {
|
|
|
386
386
|
return levels.size ? [...levels].sort(byRank) : null;
|
|
387
387
|
}
|
|
388
388
|
|
|
389
|
+
function reasoningLevelFields(levels) {
|
|
390
|
+
if (!levels) return {};
|
|
391
|
+
return {
|
|
392
|
+
reasoningOptions: levels.length ? [{ type: 'effort', values: [...levels] }] : [],
|
|
393
|
+
reasoningLevels: [...levels],
|
|
394
|
+
};
|
|
395
|
+
}
|
|
396
|
+
|
|
389
397
|
function effectiveRow(base, override, { providerId, discovered, newModelsHidden }) {
|
|
390
398
|
const ov = override || {};
|
|
391
399
|
const reasoning = ov.reasoning || {};
|
|
@@ -413,12 +421,7 @@ function effectiveRow(base, override, { providerId, discovered, newModelsHidden
|
|
|
413
421
|
hidden,
|
|
414
422
|
manual: ov.manual === true,
|
|
415
423
|
supportsReasoning: levels ? levels.some((level) => level !== 'none') : base.supportsReasoning === true,
|
|
416
|
-
...(levels
|
|
417
|
-
? {
|
|
418
|
-
reasoningOptions: levels.length ? [{ type: 'effort', values: [...levels] }] : [],
|
|
419
|
-
reasoningLevels: [...levels],
|
|
420
|
-
}
|
|
421
|
-
: {}),
|
|
424
|
+
...reasoningLevelFields(levels),
|
|
422
425
|
customReasoning: { wireFormat: reasoning.wireFormat ?? 'standard', wireValues, replay },
|
|
423
426
|
...(replay ? { reasoningContentField: 'reasoning_content' } : {}),
|
|
424
427
|
};
|
|
@@ -173,7 +173,11 @@ export async function createCustomProvider(id, config) {
|
|
|
173
173
|
if (providerOffersWire(providerId, 'messages')) {
|
|
174
174
|
const { AnthropicProvider } = await import('./anthropic.mjs');
|
|
175
175
|
// The Anthropic SDK appends /v1/messages itself; the endpoint's /v1 base maps to it.
|
|
176
|
-
messagesEngine = new AnthropicProvider({
|
|
176
|
+
messagesEngine = new AnthropicProvider({
|
|
177
|
+
...engine,
|
|
178
|
+
name: providerId,
|
|
179
|
+
baseURL: cfg.baseURL.replace(/\/v1$/i, ''),
|
|
180
|
+
});
|
|
177
181
|
messagesEngine.nativePdf = false;
|
|
178
182
|
}
|
|
179
183
|
class CompatBase extends OpenAICompatProvider {
|
|
@@ -207,7 +211,8 @@ export async function createCustomProvider(id, config) {
|
|
|
207
211
|
// The bound Messages engine reads the parent's model rows, so a routed
|
|
208
212
|
// Messages request carries the same row-driven thinking/effort as the
|
|
209
213
|
// Anthropic protocol.
|
|
210
|
-
if (provider.messagesEngine)
|
|
214
|
+
if (provider.messagesEngine)
|
|
215
|
+
provider.messagesEngine.getCachedModelInfo = (model) => provider.getCachedModelInfo(model);
|
|
211
216
|
provider.customConfig = cfg;
|
|
212
217
|
provider._customKeyless = keyless;
|
|
213
218
|
provider._applyCustomRows(provider._customRows());
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isVisibleStreamProgress } from '../../../shared/stream-progress.mjs';
|
|
1
2
|
import { anthropicEffortLevelsFor, normalizeAnthropicEffortInput } from './anthropic-effort.mjs';
|
|
2
3
|
import { CUSTOM_EFFORT_LEVELS, customEffortLevels, isCustomProviderName } from './custom-reasoning.mjs';
|
|
3
4
|
import { codexModelSupportsEffortUpdates } from './openai-oauth-catalog.mjs';
|
|
@@ -72,19 +73,40 @@ export function isEffortConfigurationRejection(status, text) {
|
|
|
72
73
|
/**
|
|
73
74
|
* Runs `send(opts)`; when the model rejects the mid-conversation effort
|
|
74
75
|
* update, switches the updates off for it and replays the request once
|
|
75
|
-
* without them.
|
|
76
|
+
* without them. Never replay after output reached the caller, cancellation,
|
|
77
|
+
* or an explicit opt-out; a late error is not evidence of missing support.
|
|
76
78
|
*/
|
|
77
79
|
export async function withEffortConfigurationFallback(provider, model, opts, send) {
|
|
80
|
+
let streamed = false;
|
|
81
|
+
const track =
|
|
82
|
+
(callback, isProgress = false) =>
|
|
83
|
+
(...args) => {
|
|
84
|
+
if (!isProgress || isVisibleStreamProgress(args[0])) streamed = true;
|
|
85
|
+
return callback(...args);
|
|
86
|
+
};
|
|
87
|
+
const tracked = { ...opts };
|
|
88
|
+
if (typeof opts?.onStreamDelta === 'function') tracked.onStreamDelta = track(opts.onStreamDelta, true);
|
|
89
|
+
if (typeof opts?.onTextDelta === 'function') tracked.onTextDelta = track(opts.onTextDelta);
|
|
90
|
+
if (typeof opts?.onToolCall === 'function') tracked.onToolCall = track(opts.onToolCall);
|
|
78
91
|
try {
|
|
79
|
-
return await send(
|
|
92
|
+
return await send(tracked);
|
|
80
93
|
} catch (error) {
|
|
81
94
|
const status = error?.status ?? error?.httpStatus;
|
|
82
|
-
|
|
95
|
+
const emitted =
|
|
96
|
+
streamed || error?.liveTextEmitted === true || error?.emittedToolCall === true || error?.unsafeToRetry === true;
|
|
97
|
+
if (
|
|
98
|
+
opts?._effortConfigurationRetry ||
|
|
99
|
+
opts?.effortConfigurationEnabled === false ||
|
|
100
|
+
opts?.signal?.aborted ||
|
|
101
|
+
emitted ||
|
|
102
|
+
!isEffortConfigurationRejection(status, error?.message)
|
|
103
|
+
)
|
|
104
|
+
throw error;
|
|
83
105
|
markEffortConfigurationUnsupported(provider, model);
|
|
84
106
|
process.stderr.write(
|
|
85
107
|
`[${provider}] ${model} rejected the mid-conversation effort update; retrying once without it\n`
|
|
86
108
|
);
|
|
87
|
-
return send({ ...
|
|
109
|
+
return send({ ...tracked, effortConfigurationEnabled: false, _effortConfigurationRetry: true });
|
|
88
110
|
}
|
|
89
111
|
}
|
|
90
112
|
const OPENAI_PROVIDERS = new Set(['openai', 'openai-oauth']);
|
|
@@ -77,7 +77,9 @@ const GEMINI_CACHE_MIN_TOKENS = 4096;
|
|
|
77
77
|
// Minimum prefix tokens for an explicit cache, or null when the docs exclude
|
|
78
78
|
// the model from explicit caching.
|
|
79
79
|
export function geminiExplicitCacheMinTokens(model) {
|
|
80
|
-
const bare = String(model || '')
|
|
80
|
+
const bare = String(model || '')
|
|
81
|
+
.replace(/^models\//i, '')
|
|
82
|
+
.toLowerCase();
|
|
81
83
|
const major = /^gemini-(\d+)/.exec(bare);
|
|
82
84
|
if (major && Number(major[1]) >= 4) return null;
|
|
83
85
|
if (/^gemini-2\.5-(?:pro|flash)(?!-lite)(?:-|$)/.test(bare)) return 2048;
|
|
@@ -263,19 +265,23 @@ export function _resolveGeminiCacheUsage({ usageMetadata, cachedContent, provide
|
|
|
263
265
|
// the prompt portion.
|
|
264
266
|
const toolUseTokens = firstFinite(usageMetadata?.toolUsePromptTokenCount, usageMetadata?.tool_use_prompt_token_count);
|
|
265
267
|
const inputTokens = hasExplicitPromptTokens ? promptTokens + toolUseTokens : Math.max(0, totalTokens - outputTokens);
|
|
266
|
-
const
|
|
268
|
+
const reportedCachedCount = [
|
|
267
269
|
// generateContent UsageMetadata field.
|
|
268
270
|
usageMetadata?.cachedContentTokenCount,
|
|
269
271
|
usageMetadata?.cached_content_token_count,
|
|
270
272
|
// Newer SDK convenience alias documented for implicit cache hits.
|
|
271
273
|
usageMetadata?.totalCachedTokens,
|
|
272
|
-
usageMetadata?.total_cached_tokens
|
|
273
|
-
|
|
274
|
+
usageMetadata?.total_cached_tokens,
|
|
275
|
+
]
|
|
276
|
+
.map((value) => (value == null ? NaN : Number(value)))
|
|
277
|
+
.find((value) => Number.isFinite(value) && value >= 0);
|
|
278
|
+
const reportedCachedTokens = reportedCachedCount ?? 0;
|
|
274
279
|
const cachedFallbackTokens = cachedContent ? Number(providerState?.gemini?.cacheTokenSize || 0) || 0 : 0;
|
|
275
|
-
|
|
280
|
+
// An explicit zero is a measured miss, not missing usage metadata.
|
|
281
|
+
const rawCachedTokens = reportedCachedCount ?? cachedFallbackTokens;
|
|
276
282
|
const cachedTokens = inputTokens > 0 ? Math.min(rawCachedTokens, inputTokens) : rawCachedTokens;
|
|
277
283
|
let cacheTokenSource = 'none';
|
|
278
|
-
if (
|
|
284
|
+
if (reportedCachedCount !== undefined) cacheTokenSource = 'usage_metadata';
|
|
279
285
|
else if (cachedFallbackTokens > 0) cacheTokenSource = 'cache_create_fallback';
|
|
280
286
|
return {
|
|
281
287
|
inputTokens,
|
|
@@ -97,7 +97,10 @@ export function geminiErrorContract({ details, errorDetails, googleStatus, messa
|
|
|
97
97
|
const scope = scopeOf(String(violation?.quotaId || ''));
|
|
98
98
|
if (scope) scopes.add(scope);
|
|
99
99
|
// A spent allowance is named by the typed violation, not by prose.
|
|
100
|
-
if (
|
|
100
|
+
if (
|
|
101
|
+
String(violation?.quotaValue ?? '').trim() === '0' ||
|
|
102
|
+
LIMIT_ZERO_RE.test(String(violation?.description || ''))
|
|
103
|
+
) {
|
|
101
104
|
zeroLimit = true;
|
|
102
105
|
}
|
|
103
106
|
}
|
|
@@ -121,7 +124,9 @@ export function geminiErrorContract({ details, errorDetails, googleStatus, messa
|
|
|
121
124
|
CAPACITY_REASONS.has(reason) ||
|
|
122
125
|
(!reason && scopes.size === 0 && retryAfterMs === undefined && CAPACITY_MESSAGE_RE.test(text));
|
|
123
126
|
// A per-day violation outlasts any per-minute one reported with it.
|
|
124
|
-
let quotaScope
|
|
127
|
+
let quotaScope;
|
|
128
|
+
if (scopes.has('day')) quotaScope = 'day';
|
|
129
|
+
else if (scopes.has('minute')) quotaScope = 'minute';
|
|
125
130
|
if (retryAfterMs === undefined) {
|
|
126
131
|
const named = MESSAGE_DELAY_RE.exec(text);
|
|
127
132
|
if (named) retryAfterMs = adviceMs(named[1]);
|
|
@@ -158,10 +163,13 @@ export function geminiInBandError(chunk, label) {
|
|
|
158
163
|
if (!detail || (typeof detail !== 'object' && typeof detail !== 'string')) return null;
|
|
159
164
|
const body = typeof detail === 'object' ? detail : { message: detail };
|
|
160
165
|
const googleStatus = typeof body.status === 'string' ? body.status : '';
|
|
161
|
-
const status =
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
166
|
+
const status =
|
|
167
|
+
Number.isFinite(Number(body.code)) && Number(body.code) > 0
|
|
168
|
+
? Number(body.code)
|
|
169
|
+
: GOOGLE_STATUS_HTTP[googleStatus.toUpperCase()];
|
|
170
|
+
const err = new Error(
|
|
171
|
+
`${label} in-band error${status ? ` ${status}` : ''}: ${String(body.message || googleStatus || 'unknown').slice(0, 300)}`
|
|
172
|
+
);
|
|
165
173
|
err.name = 'GeminiInBandError';
|
|
166
174
|
if (status) {
|
|
167
175
|
err.status = status;
|
|
@@ -44,10 +44,10 @@ export function buildGeminiRequest(messages, useModel, tools, opts) {
|
|
|
44
44
|
// explicit opts.includeThoughts still wins.
|
|
45
45
|
const thinkingConfig = geminiThinkingConfig(useModel, opts, { includeThoughts: true });
|
|
46
46
|
const controls = geminiGenerationControls(opts);
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
47
|
+
let generationConfig;
|
|
48
|
+
if (thinkingConfig || Object.keys(controls).length) {
|
|
49
|
+
generationConfig = { ...(thinkingConfig ? { thinkingConfig } : {}), ...controls };
|
|
50
|
+
}
|
|
51
51
|
const systemInstruction =
|
|
52
52
|
messages
|
|
53
53
|
.filter((m) => m.role === 'system')
|
|
@@ -149,6 +149,7 @@ export function resolveGeminiUsage(response, opts, cachedContent, useModel) {
|
|
|
149
149
|
}
|
|
150
150
|
|
|
151
151
|
export function geminiSendResult(parsed, useModel, opts, resolvedUsage) {
|
|
152
|
+
if (parsed.providerReplay) parsed.providerReplay.requestContext = { model: useModel };
|
|
152
153
|
return {
|
|
153
154
|
content: parsed.content,
|
|
154
155
|
model: useModel,
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
// First-byte and idle watchdogs of one Gemini REST SSE body. Either timeout
|
|
2
2
|
// cancels the reader and fails the pending read, so the caller surfaces a typed
|
|
3
|
-
// timeout instead of waiting on a stalled socket.
|
|
4
|
-
|
|
3
|
+
// timeout instead of waiting on a stalled socket. The idle timer re-arms only
|
|
4
|
+
// on decoded payloads (semantic progress), so it uses the semantic window.
|
|
5
|
+
// Each timeout names its phase (`timeoutPhase`): 'first-chunk' before any
|
|
6
|
+
// payload, 'idle' after one.
|
|
7
|
+
import { PROVIDER_SEMANTIC_IDLE_TIMEOUT_MS, PROVIDER_SSE_IDLE_WATCHDOG_ENABLED } from '../../stall-policy.mjs';
|
|
8
|
+
import { TIMEOUT_PHASE } from '../../../../shared/provider-timeout-phase.mjs';
|
|
5
9
|
|
|
6
10
|
export function createRestStreamWatchdogs({ reader, label, firstByteTimeoutMs, timeoutError }) {
|
|
7
11
|
let idleTimedOut = false;
|
|
@@ -19,11 +23,18 @@ export function createRestStreamWatchdogs({ reader, label, firstByteTimeoutMs, t
|
|
|
19
23
|
pendingReject = null;
|
|
20
24
|
reject(err);
|
|
21
25
|
};
|
|
22
|
-
const idleError = () =>
|
|
26
|
+
const idleError = () =>
|
|
27
|
+
Object.assign(timeoutError(`${label} SSE idle`, PROVIDER_SEMANTIC_IDLE_TIMEOUT_MS), {
|
|
28
|
+
timeoutPhase: TIMEOUT_PHASE.IDLE,
|
|
29
|
+
});
|
|
23
30
|
|
|
24
31
|
let firstByteTimer = setTimeout(() => {
|
|
25
32
|
cancelReader('first byte timeout');
|
|
26
|
-
failPending(
|
|
33
|
+
failPending(
|
|
34
|
+
Object.assign(timeoutError(`${label} first byte`, firstByteTimeoutMs), {
|
|
35
|
+
timeoutPhase: TIMEOUT_PHASE.FIRST_CHUNK,
|
|
36
|
+
})
|
|
37
|
+
);
|
|
27
38
|
}, firstByteTimeoutMs);
|
|
28
39
|
firstByteTimer.unref?.();
|
|
29
40
|
const clearFirstByte = () => {
|
|
@@ -46,7 +57,7 @@ export function createRestStreamWatchdogs({ reader, label, firstByteTimeoutMs, t
|
|
|
46
57
|
idleTimedOut = true;
|
|
47
58
|
cancelReader('SSE idle timeout');
|
|
48
59
|
failPending(idleError());
|
|
49
|
-
},
|
|
60
|
+
}, PROVIDER_SEMANTIC_IDLE_TIMEOUT_MS);
|
|
50
61
|
idleTimer.unref?.();
|
|
51
62
|
},
|
|
52
63
|
// One reader.read() with its reject handle registered for the watchdogs;
|
|
@@ -148,7 +148,12 @@ export async function runGeminiStreamAttempts({ run, signal, onRetry, sleepFn, a
|
|
|
148
148
|
} catch (err) {
|
|
149
149
|
const waitMs = connected ? geminiMidstreamDelayMs(err, streamAttempt, signal) : null;
|
|
150
150
|
if (waitMs == null) throw err;
|
|
151
|
-
onRetry?.({
|
|
151
|
+
onRetry?.({
|
|
152
|
+
attempt: streamAttempt + 1,
|
|
153
|
+
maxAttempts: GEMINI_MIDSTREAM_MAX_ATTEMPTS,
|
|
154
|
+
lastErr: err,
|
|
155
|
+
delayMs: waitMs,
|
|
156
|
+
});
|
|
152
157
|
await sleepWithAbort(waitMs, signal, sleepFn, 'Gemini stream retry wait aborted');
|
|
153
158
|
continue;
|
|
154
159
|
}
|
|
@@ -876,11 +876,11 @@ const isFailedToolResult = (message) => message.toolKind === 'error' || message.
|
|
|
876
876
|
// recorded part, and a recorded Gemini part may carry no id at all, in which
|
|
877
877
|
// case the response carries none either. An unmatched result keeps its own id.
|
|
878
878
|
function toGeminiToolResult(message, toolNameByCallId, nestMedia, callsByFinalId) {
|
|
879
|
-
const
|
|
879
|
+
const replayedCall = callsByFinalId?.get(message.toolCallId);
|
|
880
|
+
const functionName = replayedCall?.name || toolNameByCallId?.get(message.toolCallId) || message.toolCallId || '';
|
|
880
881
|
const { response: rawResponse, mediaParts } = splitGeminiToolContent(message.content);
|
|
881
882
|
const response = isFailedToolResult(message) && 'result' in rawResponse ? { error: rawResponse.result } : rawResponse;
|
|
882
883
|
const functionResponse = { name: functionName, response };
|
|
883
|
-
const replayedCall = callsByFinalId?.get(message.toolCallId);
|
|
884
884
|
const responseId = replayedCall ? replayedCall.id : message.toolCallId;
|
|
885
885
|
if (typeof responseId === 'string' && responseId) functionResponse.id = responseId;
|
|
886
886
|
if (!nestMedia) return { functionResponsePart: { functionResponse }, mediaParts };
|
|
@@ -895,16 +895,20 @@ function toGeminiToolResult(message, toolNameByCallId, nestMedia, callsByFinalId
|
|
|
895
895
|
// A replay recorded by a non-Gemini model (Claude behind Antigravity) carries
|
|
896
896
|
// signatures Gemini rejects: its replay envelope and the signed metadata
|
|
897
897
|
// derived from the same response must not reach a Gemini request.
|
|
898
|
-
function hasForeignReplay(message) {
|
|
898
|
+
function hasForeignReplay(message, model) {
|
|
899
899
|
const replay = message?.providerReplay;
|
|
900
900
|
if (replay?.provider !== 'gemini' && replay?.provider !== 'antigravity') return false;
|
|
901
901
|
const recorded = replay.requestContext?.model;
|
|
902
|
-
return
|
|
902
|
+
return (
|
|
903
|
+
typeof recorded === 'string' &&
|
|
904
|
+
recorded !== '' &&
|
|
905
|
+
(!isGeminiFamilyModel(recorded) || (replay.provider === 'gemini' && model && recorded !== model))
|
|
906
|
+
);
|
|
903
907
|
}
|
|
904
908
|
|
|
905
|
-
function toGeminiContent(message) {
|
|
909
|
+
function toGeminiContent(message, model) {
|
|
906
910
|
if (!message || message.role === 'system') return null;
|
|
907
|
-
const foreign = message.role === 'assistant' && hasForeignReplay(message);
|
|
911
|
+
const foreign = message.role === 'assistant' && hasForeignReplay(message, model);
|
|
908
912
|
if (foreign) message = { ...message, providerMetadata: undefined };
|
|
909
913
|
const orderedReplay =
|
|
910
914
|
message.role === 'assistant' && !foreign ? providerReplayItems(message, ['gemini', 'antigravity']) : undefined;
|
|
@@ -1019,7 +1023,7 @@ export function toGeminiContents(messages, model = '', { repairToolSignatures =
|
|
|
1019
1023
|
for (const tc of m.toolCalls) {
|
|
1020
1024
|
if (tc?.id && tc?.name) toolNameByCallId.set(tc.id, tc.name);
|
|
1021
1025
|
}
|
|
1022
|
-
const content = toGeminiContent(m);
|
|
1026
|
+
const content = toGeminiContent(m, model);
|
|
1023
1027
|
assistantContent.set(m, content);
|
|
1024
1028
|
const replayed = (content?.parts || []).filter((part) => part?.functionCall);
|
|
1025
1029
|
m.toolCalls.forEach((tc, index) => {
|
|
@@ -1039,6 +1043,7 @@ export function toGeminiContents(messages, model = '', { repairToolSignatures =
|
|
|
1039
1043
|
// first (one per call, in call order), then the media the results carried as
|
|
1040
1044
|
// sibling inlineData/fileData parts.
|
|
1041
1045
|
let toolTurn = null;
|
|
1046
|
+
let toolCallOrder = new Map();
|
|
1042
1047
|
const nestMedia = supportsFunctionResponseParts(model);
|
|
1043
1048
|
for (const message of messages) {
|
|
1044
1049
|
if (message?.role === 'tool') {
|
|
@@ -1049,16 +1054,23 @@ export function toGeminiContents(messages, model = '', { repairToolSignatures =
|
|
|
1049
1054
|
callsByFinalId
|
|
1050
1055
|
);
|
|
1051
1056
|
if (!toolTurn) {
|
|
1052
|
-
toolTurn = { content: { role: 'user', parts: [] }, responseCount: 0 };
|
|
1057
|
+
toolTurn = { content: { role: 'user', parts: [] }, responseCount: 0, responseOrder: [] };
|
|
1053
1058
|
contents.push(toolTurn.content);
|
|
1054
1059
|
}
|
|
1055
|
-
|
|
1060
|
+
// Completion order is not call order. Anonymous parallel calls to the
|
|
1061
|
+
// same function can only be correlated by their original position.
|
|
1062
|
+
const order = toolCallOrder.get(message.toolCallId) ?? Infinity;
|
|
1063
|
+
const next = toolTurn.responseOrder.findIndex((value) => value > order);
|
|
1064
|
+
const index = next < 0 ? toolTurn.responseCount : next;
|
|
1065
|
+
toolTurn.responseOrder.splice(index, 0, order);
|
|
1066
|
+
toolTurn.content.parts.splice(index, 0, functionResponsePart);
|
|
1056
1067
|
toolTurn.responseCount += 1;
|
|
1057
1068
|
toolTurn.content.parts.push(...mediaParts);
|
|
1058
1069
|
continue;
|
|
1059
1070
|
}
|
|
1060
1071
|
toolTurn = null;
|
|
1061
|
-
|
|
1072
|
+
toolCallOrder = new Map((message.toolCalls || []).map((call, index) => [call.id, index]));
|
|
1073
|
+
const content = assistantContent.has(message) ? assistantContent.get(message) : toGeminiContent(message, model);
|
|
1062
1074
|
if (content) contents.push(content);
|
|
1063
1075
|
}
|
|
1064
1076
|
return repairToolSignatures ? ensureGeminiToolCallSignatures(contents, model) : contents;
|
|
@@ -513,7 +513,8 @@ function createLeakGuardFinalizer(textLeakGuard) {
|
|
|
513
513
|
// `unwrapChunk` adapts a transport that nests the Gemini payload one level
|
|
514
514
|
// deeper. Cloud Code Assist (Antigravity) streams `{ response: { candidates … } }`
|
|
515
515
|
// while the public API streams the candidates directly; everything downstream —
|
|
516
|
-
// aggregation, leak guard, watchdogs — stays shared.
|
|
516
|
+
// aggregation, leak guard, watchdogs — stays shared. `firstByteTimeoutMs` is
|
|
517
|
+
// the wait for the first chunk once the response headers arrived.
|
|
517
518
|
export async function consumeGeminiRestStreamResponse(
|
|
518
519
|
response,
|
|
519
520
|
{
|
|
@@ -525,6 +526,7 @@ export async function consumeGeminiRestStreamResponse(
|
|
|
525
526
|
unwrapChunk = null,
|
|
526
527
|
onChunk = null,
|
|
527
528
|
failureUsage = null,
|
|
529
|
+
firstByteTimeoutMs = GEMINI_FIRST_BYTE_TIMEOUT_MS,
|
|
528
530
|
}
|
|
529
531
|
) {
|
|
530
532
|
const unwrap =
|
|
@@ -548,7 +550,7 @@ export async function consumeGeminiRestStreamResponse(
|
|
|
548
550
|
const watchdogs = createRestStreamWatchdogs({
|
|
549
551
|
reader,
|
|
550
552
|
label,
|
|
551
|
-
firstByteTimeoutMs
|
|
553
|
+
firstByteTimeoutMs,
|
|
552
554
|
timeoutError: geminiTimeoutError,
|
|
553
555
|
});
|
|
554
556
|
// One decoded chunk: collected for aggregation and relayed to every sink.
|