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
|
@@ -15,6 +15,8 @@ import { crossTurnSignature, isEditProgressTool } from '../loop/completion-guard
|
|
|
15
15
|
import { isEagerDispatchable, isToolCallDedupEligible, parseNativeToolSearchPayload } from '../loop/tool-helpers.mjs';
|
|
16
16
|
import { restoreToolCallBodyForId } from '../loop/stored-tool-args.mjs';
|
|
17
17
|
import { stageToolResult } from './state.mjs';
|
|
18
|
+
import { providerConsumesReadWindows } from '../../providers/registry.mjs';
|
|
19
|
+
import { remoteReadWindowReport } from '../../tools/builtin/external-tool-adapters.mjs';
|
|
18
20
|
import { toolMetaPatchFromMessage } from '../transcript-restore/tool-result-status.mjs';
|
|
19
21
|
import {
|
|
20
22
|
compactToolResultImage,
|
|
@@ -42,12 +44,30 @@ export async function finalizeBatchResults(batch) {
|
|
|
42
44
|
for (const state of offloadStates) {
|
|
43
45
|
if (state?.result && typeof state.result === 'object') state.result = await compactResultImages(state.result);
|
|
44
46
|
}
|
|
47
|
+
await reportReadWindows(batch);
|
|
45
48
|
for (let index = 0; index < batch.completed.length; index += 1) {
|
|
46
49
|
postProcessCompleted(batch, batch.completed[index], offloadStates[index]);
|
|
47
50
|
batch.throwIfAborted();
|
|
48
51
|
}
|
|
49
52
|
}
|
|
50
53
|
|
|
54
|
+
// A provider that declares `consumesReadWindows` (also through a remote/proxy
|
|
55
|
+
// stand-in) only receives the read text. Its read results carry the
|
|
56
|
+
// structured clip report next to the text, for every serving path (live,
|
|
57
|
+
// eager or cached). Failure fails closed.
|
|
58
|
+
async function reportReadWindows(batch) {
|
|
59
|
+
if (!providerConsumesReadWindows(batch.sessionRef?.provider)) return;
|
|
60
|
+
for (const completed of batch.completed) {
|
|
61
|
+
if (!completed.executeOk || !_isReadTool(completed.call.name)) continue;
|
|
62
|
+
try {
|
|
63
|
+
const report = await remoteReadWindowReport(completed.call.arguments, batch.cwd, completed.result);
|
|
64
|
+
if (report) completed.readWindow = report;
|
|
65
|
+
} catch {
|
|
66
|
+
completed.readWindow = { lineClipped: true };
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
51
71
|
// An image no provider can take is replaced by fixed text here, before it can
|
|
52
72
|
// reach the transcript and fail every later send.
|
|
53
73
|
const unsupportedImageText = (mimeType) => `[image omitted: ${mimeType} is not a supported image type]`;
|
|
@@ -57,7 +77,10 @@ const UNDECODABLE_IMAGE_TEXT = '[image omitted: could not be decoded]';
|
|
|
57
77
|
// inline image is fully decoded (not only large ones); with no decoder
|
|
58
78
|
// installed the image is kept as is.
|
|
59
79
|
async function rejectedImageText(base64, rawMime) {
|
|
60
|
-
const mimeType = String(rawMime || 'image/png')
|
|
80
|
+
const mimeType = String(rawMime || 'image/png')
|
|
81
|
+
.split(';')[0]
|
|
82
|
+
.trim()
|
|
83
|
+
.toLowerCase();
|
|
61
84
|
if (!SUPPORTED_IMAGE_MIME_TYPES.has(mimeType)) return unsupportedImageText(mimeType);
|
|
62
85
|
try {
|
|
63
86
|
await resizeImageBuffer(Buffer.from(base64, 'base64'), mimeType.split('/')[1]);
|
|
@@ -73,8 +96,8 @@ async function rejectedImageText(base64, rawMime) {
|
|
|
73
96
|
// the result reaches the read cache or the transcript; stored history is never
|
|
74
97
|
// revisited.
|
|
75
98
|
export async function compactResultImages(result) {
|
|
76
|
-
const parts = Array.isArray(result) ? result :
|
|
77
|
-
if (!parts) return result;
|
|
99
|
+
const parts = Array.isArray(result) ? result : result?.content;
|
|
100
|
+
if (!Array.isArray(parts)) return result;
|
|
78
101
|
let changed = false;
|
|
79
102
|
const next = [];
|
|
80
103
|
for (const part of parts) {
|
|
@@ -101,16 +124,16 @@ export async function compactResultImages(result) {
|
|
|
101
124
|
if (dims.originalWidth !== dims.displayWidth || dims.originalHeight !== dims.displayHeight) {
|
|
102
125
|
next.push({ type: 'text', text: supersedingImageMetadataText(dims) });
|
|
103
126
|
}
|
|
104
|
-
|
|
105
|
-
source
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
127
|
+
if (source) {
|
|
128
|
+
next.push({ ...part, source: { ...source, data: compacted.data, media_type: compacted.mimeType } });
|
|
129
|
+
} else {
|
|
130
|
+
next.push({
|
|
131
|
+
...part,
|
|
132
|
+
data: compacted.data,
|
|
133
|
+
mimeType: compacted.mimeType,
|
|
134
|
+
...(part.mediaType ? { mediaType: compacted.mimeType } : {}),
|
|
135
|
+
});
|
|
136
|
+
}
|
|
114
137
|
}
|
|
115
138
|
if (!changed) return result;
|
|
116
139
|
return Array.isArray(result) ? next : { ...result, content: next };
|
|
@@ -281,6 +304,7 @@ function completedToolResult(completed, result, postprocessStartedAt) {
|
|
|
281
304
|
toolKind: completed.resultKind,
|
|
282
305
|
toolTiming: toolTiming(completed, postprocessStartedAt),
|
|
283
306
|
...(completed.nativeToolSearch ? { nativeToolSearch: completed.nativeToolSearch } : {}),
|
|
307
|
+
...(completed.readWindow ? { readWindow: completed.readWindow } : {}),
|
|
284
308
|
...(uiDiff !== null ? { uiDiff } : {}),
|
|
285
309
|
...toolMetaPatchFromMessage(completed.result),
|
|
286
310
|
};
|
|
@@ -3,7 +3,12 @@
|
|
|
3
3
|
// and the repeat-failure / argument-shape guards. `skip` is the staged tool
|
|
4
4
|
// message for a resolved call, or null when the call may execute.
|
|
5
5
|
import { appendAgentTrace } from '../../agent-trace.mjs';
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
_argShapeSig,
|
|
8
|
+
_repeatFailureSig,
|
|
9
|
+
_repeatFailurePatternWouldContinue,
|
|
10
|
+
requiresReadBody,
|
|
11
|
+
} from '../loop/tool-classify.mjs';
|
|
7
12
|
import { preDispatchDenyForSession } from '../loop/pre-dispatch-deny.mjs';
|
|
8
13
|
import { crossTurnSignature, crossTurnDedupStub } from '../loop/completion-guards.mjs';
|
|
9
14
|
import { isToolCallDedupEligible } from '../loop/tool-helpers.mjs';
|
|
@@ -27,7 +32,7 @@ export function preDispatchSkip(batch, call) {
|
|
|
27
32
|
'error'
|
|
28
33
|
);
|
|
29
34
|
}
|
|
30
|
-
if (plan.duplicateCallIds.has(call.id)) {
|
|
35
|
+
if (plan.duplicateCallIds.has(call.id) && !requiresReadBody(call.name, sessionRef)) {
|
|
31
36
|
const firstId = plan.dupFirstId.get(call.id);
|
|
32
37
|
// Explicitly NOT a success: no tool executed for this call. 'skipped'
|
|
33
38
|
// keeps the transcript/UI non-error while the unresolved-tool-failure
|
|
@@ -43,7 +48,7 @@ export function preDispatchSkip(batch, call) {
|
|
|
43
48
|
let ctSig = null;
|
|
44
49
|
if (isToolCallDedupEligible(call.name, tools)) {
|
|
45
50
|
ctSig = crossTurnSignature(call.name, call.arguments);
|
|
46
|
-
const stub = crossTurnStub(batch, call, ctSig);
|
|
51
|
+
const stub = requiresReadBody(call.name, sessionRef) ? null : crossTurnStub(batch, call, ctSig);
|
|
47
52
|
if (stub !== null) return skipped(stub, 'skipped', ctSig);
|
|
48
53
|
}
|
|
49
54
|
const sigs = {
|
|
@@ -60,7 +65,13 @@ export function preDispatchSkip(batch, call) {
|
|
|
60
65
|
function crossTurnStub(batch, call, ctSig) {
|
|
61
66
|
const prior = batch.crossTurnCalls.get(ctSig);
|
|
62
67
|
if (!prior || prior.firstIteration >= batch.iterations) return null;
|
|
63
|
-
const cached = lookupToolResultReuse({
|
|
68
|
+
const cached = lookupToolResultReuse({
|
|
69
|
+
sessionId: batch.sessionId,
|
|
70
|
+
call,
|
|
71
|
+
cwd: batch.cwd,
|
|
72
|
+
touch: false,
|
|
73
|
+
sessionRef: batch.sessionRef,
|
|
74
|
+
});
|
|
64
75
|
if (!cached || !prior.toolUseId || cached.entry.firstToolUseId !== prior.toolUseId) {
|
|
65
76
|
batch.crossTurnCalls.delete(ctSig);
|
|
66
77
|
return null;
|
|
@@ -61,13 +61,15 @@ export function rejectedToolSchema(error, { sendTools, sessionRef, opts }) {
|
|
|
61
61
|
const nativeCount = providerNativeToolPrefixCount(tools);
|
|
62
62
|
// The wire list: the request's tools minus those the wire left out.
|
|
63
63
|
const wire = tools.filter((tool) => !providerToolExclusionReason(sessionRef, tool?.name));
|
|
64
|
-
const hosted =
|
|
64
|
+
const hosted =
|
|
65
|
+
sessionRef?.wireRoute?.wire !== 'chat' && Array.isArray(opts?.nativeTools) ? opts.nativeTools.length : 0;
|
|
65
66
|
const entries = evidence(error);
|
|
66
67
|
let name = '';
|
|
67
68
|
for (const entry of entries) {
|
|
68
69
|
const found = target(entry);
|
|
69
70
|
if (!found) continue;
|
|
70
|
-
const
|
|
71
|
+
const shift = found.shifted ? hosted : 0;
|
|
72
|
+
const tool = found.name ? wire.find((t) => t?.name === found.name) : wire[found.index - shift];
|
|
71
73
|
name = typeof tool?.name === 'string' ? tool.name : '';
|
|
72
74
|
if (name) break;
|
|
73
75
|
}
|
|
@@ -37,8 +37,24 @@ import {
|
|
|
37
37
|
isTranscriptCancelledStatusText,
|
|
38
38
|
} from '../../../../shared/tool-execution-contract.mjs';
|
|
39
39
|
import { toolResultTerminalStatus } from '../../../../shared/tool-status.mjs';
|
|
40
|
-
import { transcriptRouteMetadataFields } from '../../../../shared/transcript-metadata.mjs';
|
|
40
|
+
import { transcriptAttachmentFields, transcriptRouteMetadataFields } from '../../../../shared/transcript-metadata.mjs';
|
|
41
41
|
import { isImportedMessage } from '../imported-message.mjs';
|
|
42
|
+
import { isContextAckMessage } from '../compact/user-message-kind.mjs';
|
|
43
|
+
|
|
44
|
+
/** A failed turn's recorded end: its route, reason and quota stop, the same
|
|
45
|
+
* fields the live turndone carries. */
|
|
46
|
+
function restoredFailureFields(value) {
|
|
47
|
+
if (value.status !== 'failed') return {};
|
|
48
|
+
const errorKind = value.errorKind && typeof value.errorKind === 'object' ? value.errorKind : null;
|
|
49
|
+
const quota = value.quota && typeof value.quota === 'object' ? value.quota : null;
|
|
50
|
+
return {
|
|
51
|
+
...transcriptRouteMetadataFields(value),
|
|
52
|
+
...(typeof value.detail === 'string' && value.detail ? { detail: value.detail } : {}),
|
|
53
|
+
...(typeof value.errorDetails === 'string' && value.errorDetails ? { errorDetails: value.errorDetails } : {}),
|
|
54
|
+
...(errorKind && typeof errorKind.kind === 'string' ? { errorKind: { ...errorKind } } : {}),
|
|
55
|
+
...(quota && typeof quota.provider === 'string' ? { quota: { ...quota } } : {}),
|
|
56
|
+
};
|
|
57
|
+
}
|
|
42
58
|
|
|
43
59
|
function restoredTranscriptMetadata(message) {
|
|
44
60
|
const value = message?.meta?.transcript;
|
|
@@ -53,6 +69,10 @@ function restoredTranscriptMetadata(message) {
|
|
|
53
69
|
if (typeof completionValue.checkpointId === 'string' && completionValue.checkpointId) {
|
|
54
70
|
completion.checkpointId = completionValue.checkpointId;
|
|
55
71
|
}
|
|
72
|
+
Object.assign(completion, restoredFailureFields(completionValue));
|
|
73
|
+
const attemptId = completionValue.attemptId || value.attemptId;
|
|
74
|
+
if (typeof attemptId === 'string' && attemptId) completion.attemptId = attemptId;
|
|
75
|
+
if (Number.isFinite(Number(completionValue.at))) completion.at = Number(completionValue.at);
|
|
56
76
|
}
|
|
57
77
|
return {
|
|
58
78
|
// The stable message id lets a live view map a compaction's dropped
|
|
@@ -63,6 +83,9 @@ function restoredTranscriptMetadata(message) {
|
|
|
63
83
|
...(typeof value.sender === 'string' && value.sender ? { sender: value.sender } : {}),
|
|
64
84
|
...(typeof value.device === 'string' && value.device ? { device: value.device } : {}),
|
|
65
85
|
...(typeof value.checkpointId === 'string' && value.checkpointId ? { checkpointId: value.checkpointId } : {}),
|
|
86
|
+
// The attachments this prompt carried, by content hash: a restored row
|
|
87
|
+
// opens/downloads them by id from the attachment store.
|
|
88
|
+
...transcriptAttachmentFields(value),
|
|
66
89
|
// Skills this user turn explicitly loaded (header selection or `$name`).
|
|
67
90
|
...(Array.isArray(value.appliedSkills) && value.appliedSkills.length
|
|
68
91
|
? { appliedSkills: value.appliedSkills.filter((name) => typeof name === 'string' && name) }
|
|
@@ -71,24 +94,45 @@ function restoredTranscriptMetadata(message) {
|
|
|
71
94
|
};
|
|
72
95
|
}
|
|
73
96
|
|
|
97
|
+
function restoredTurnDoneItem(completion, metadata, nextId, finalAssistantId = '') {
|
|
98
|
+
const at = Number.isFinite(completion.at) ? completion.at : metadata.at;
|
|
99
|
+
return {
|
|
100
|
+
kind: 'turndone',
|
|
101
|
+
id: nextId(),
|
|
102
|
+
...completion,
|
|
103
|
+
...(completion.status === 'done' && finalAssistantId ? { finalAssistantId } : {}),
|
|
104
|
+
...(Number.isFinite(at) ? { at } : {}),
|
|
105
|
+
...(metadata.messageId ? { messageId: metadata.messageId } : {}),
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
|
|
74
109
|
function restoredAssistantTranscriptItems(message, nextId) {
|
|
75
110
|
const text = (typeof message?.content === 'string' ? message.content : toolResultText(message?.content)).trim();
|
|
76
111
|
if (!text) return [];
|
|
77
112
|
const { completion, ...metadata } = restoredTranscriptMetadata(message);
|
|
78
113
|
const items = [{ kind: 'assistant', id: nextId(), text, ...metadata }];
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
id: nextId(),
|
|
83
|
-
...completion,
|
|
84
|
-
...(completion.status === 'done' ? { finalAssistantId: items[0].id } : {}),
|
|
85
|
-
...(metadata.at ? { at: metadata.at } : {}),
|
|
86
|
-
...(metadata.messageId ? { messageId: metadata.messageId } : {}),
|
|
87
|
-
});
|
|
114
|
+
// A failed end follows the message's tool calls (restoreTranscriptRange).
|
|
115
|
+
if (completion && completion.status !== 'failed') {
|
|
116
|
+
items.push(restoredTurnDoneItem(completion, metadata, nextId, items[0].id));
|
|
88
117
|
}
|
|
89
118
|
return items;
|
|
90
119
|
}
|
|
91
120
|
|
|
121
|
+
/** The failed end recorded on a message that holds no reply text before it:
|
|
122
|
+
* the prompt itself, a tool call or a tool result. */
|
|
123
|
+
function restoredFailedTurnItems(message, nextId) {
|
|
124
|
+
const { completion, ...metadata } = restoredTranscriptMetadata(message);
|
|
125
|
+
const previous = Array.isArray(message?.meta?.transcript?.previousCompletions)
|
|
126
|
+
? message.meta.transcript.previousCompletions
|
|
127
|
+
: [];
|
|
128
|
+
const items = previous.flatMap((value) => {
|
|
129
|
+
const historical = restoredTranscriptMetadata({ meta: { transcript: { completion: value, at: value?.at } } });
|
|
130
|
+
return historical.completion ? [restoredTurnDoneItem(historical.completion, historical, nextId)] : [];
|
|
131
|
+
});
|
|
132
|
+
if (completion?.status === 'failed') items.push(restoredTurnDoneItem(completion, metadata, nextId));
|
|
133
|
+
return items;
|
|
134
|
+
}
|
|
135
|
+
|
|
92
136
|
// Restored tool cards: stored assistant messages keep their (compacted)
|
|
93
137
|
// tool_calls and the follow-up role:'tool' results. Rebuild one transcript
|
|
94
138
|
// tool item per call and attach its result by tool_call_id, so a reopened
|
|
@@ -289,13 +333,17 @@ function restoredMessageItemUpperBound(message) {
|
|
|
289
333
|
const boundaries =
|
|
290
334
|
(Array.isArray(message?.meta?.sessionInheritances) ? message.meta.sessionInheritances.length : 0) +
|
|
291
335
|
(Array.isArray(message?.meta?.modelSwitches) ? message.meta.modelSwitches.length : 0);
|
|
292
|
-
|
|
293
|
-
|
|
336
|
+
const completionCount =
|
|
337
|
+
Number(Boolean(message?.meta?.transcript?.completion)) +
|
|
338
|
+
(Array.isArray(message?.meta?.transcript?.previousCompletions)
|
|
339
|
+
? message.meta.transcript.previousCompletions.length
|
|
340
|
+
: 0);
|
|
341
|
+
if (message?.role === 'user') return 1 + completionCount + boundaries;
|
|
342
|
+
if (message?.role !== 'assistant') return completionCount + boundaries;
|
|
294
343
|
const calls = restoredMessageToolCalls(message);
|
|
295
344
|
const content = message?.content;
|
|
296
345
|
const hasContent = typeof content === 'string' ? content.length > 0 : Array.isArray(content) && content.length > 0;
|
|
297
|
-
|
|
298
|
-
return Number(hasContent) + Number(hasCompletion) + calls.length + boundaries;
|
|
346
|
+
return Number(hasContent) + completionCount + calls.length + boundaries;
|
|
299
347
|
}
|
|
300
348
|
|
|
301
349
|
// One restored tool card for a parsed notification/completion envelope.
|
|
@@ -404,12 +452,14 @@ function restoreTranscriptRange(messages, start, sessionId) {
|
|
|
404
452
|
const restoredId = () => `hist_${sessionId}_${index}_${++part}`;
|
|
405
453
|
if (message?.role === 'user') {
|
|
406
454
|
items.push(...restoredUserTranscriptItems(message, restoredId));
|
|
407
|
-
} else if (message?.role === 'assistant') {
|
|
455
|
+
} else if (message?.role === 'assistant' && !isContextAckMessage(message, messages[index - 1])) {
|
|
408
456
|
items.push(...restoredAssistantTranscriptItems(message, restoredId));
|
|
409
457
|
items.push(...restoredToolCallItems(message, restoredId, pendingToolCalls));
|
|
410
458
|
} else if (message?.role === 'tool') {
|
|
411
459
|
attachRestoredToolResult(message, pendingToolCalls);
|
|
412
460
|
}
|
|
461
|
+
const eventStart = items.length;
|
|
462
|
+
items.push(...restoredFailedTurnItems(message, restoredId));
|
|
413
463
|
for (const boundary of Array.isArray(message?.meta?.sessionInheritances) ? message.meta.sessionInheritances : []) {
|
|
414
464
|
if (!boundary?.sessionId || !boundary?.provider || !boundary?.modelId) continue;
|
|
415
465
|
items.push({
|
|
@@ -427,6 +477,13 @@ function restoreTranscriptRange(messages, start, sessionId) {
|
|
|
427
477
|
if (!boundary?.provider || !boundary?.modelId) continue;
|
|
428
478
|
items.push(modelSwitchItem(restoredId(), boundary));
|
|
429
479
|
}
|
|
480
|
+
if (message?.meta?.transcript?.previousCompletions?.length) {
|
|
481
|
+
const events = items.slice(eventStart);
|
|
482
|
+
if (events.every((item) => Number.isFinite(item.at))) {
|
|
483
|
+
events.sort((left, right) => left.at - right.at);
|
|
484
|
+
items.splice(eventStart, events.length, ...events);
|
|
485
|
+
}
|
|
486
|
+
}
|
|
430
487
|
}
|
|
431
488
|
return mergeRestoredToolItems(items);
|
|
432
489
|
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
// The failed-turn record shared by the live turn close (tui/session/turn.mjs)
|
|
2
|
+
// and the durable turn end (manager/ask-turn-failure.mjs), so a reopened
|
|
3
|
+
// session shows the same failure, reason and quota stop as the live one.
|
|
4
|
+
import { errText } from '../../../shared/err-text.mjs';
|
|
5
|
+
import { safeErrorDetails } from '../../../shared/error-presentation.mjs';
|
|
6
|
+
import { providerErrorKind } from '../providers/provider-error-kind.mjs';
|
|
7
|
+
import { toolErrorDisplay } from './transcript-restore/tool-result-text.mjs';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* `{ providerKind, errorKind, quota, detail, errorDetails }` for one turn
|
|
11
|
+
* error. `quota` is null unless the pool validated an exhaustion or the
|
|
12
|
+
* provider named the real reset time; `route` fills its provider/model.
|
|
13
|
+
*/
|
|
14
|
+
export function turnFailureRecord(error, route = {}) {
|
|
15
|
+
// Presentation only: legacy untyped failure text may still name a usage limit.
|
|
16
|
+
const providerKind = providerErrorKind(error, { legacyQuotaWording: true });
|
|
17
|
+
const errorKind = {
|
|
18
|
+
kind: providerKind.kind,
|
|
19
|
+
code: providerKind.code,
|
|
20
|
+
status: providerKind.status,
|
|
21
|
+
retryAfterMs: providerKind.retryAfterMs,
|
|
22
|
+
resetAt: providerKind.resetAt,
|
|
23
|
+
};
|
|
24
|
+
const exhausted = error?.quotaExhausted;
|
|
25
|
+
const resetKnown = providerKind.kind === 'quota_exhausted' && Number.isFinite(providerKind.resetAt);
|
|
26
|
+
let quota = null;
|
|
27
|
+
if ((exhausted && typeof exhausted === 'object') || resetKnown) {
|
|
28
|
+
const source = exhausted && typeof exhausted === 'object' ? exhausted : {};
|
|
29
|
+
let resetAt = null;
|
|
30
|
+
if (Number.isFinite(source.resetAt)) resetAt = source.resetAt;
|
|
31
|
+
else if (Number.isFinite(providerKind.resetAt)) resetAt = providerKind.resetAt;
|
|
32
|
+
quota = {
|
|
33
|
+
provider: String(source.provider || route.provider || ''),
|
|
34
|
+
model: String(source.model || route.model || ''),
|
|
35
|
+
resetAt,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
return {
|
|
39
|
+
providerKind,
|
|
40
|
+
errorKind,
|
|
41
|
+
quota,
|
|
42
|
+
detail: toolErrorDisplay(error, 'turn').replace(/^Error:\s*/i, ''),
|
|
43
|
+
errorDetails: safeErrorDetails(errText(error)),
|
|
44
|
+
};
|
|
45
|
+
}
|
|
@@ -259,6 +259,56 @@ export const PROVIDER_WS_SEMANTIC_IDLE_TIMEOUT_MS = resolveTimeoutMs(
|
|
|
259
259
|
{ minMs: 10_000, maxMs: Math.max(10_000, STALL_ABORT_MS - STALL_TICK_MS) }
|
|
260
260
|
);
|
|
261
261
|
|
|
262
|
+
/**
|
|
263
|
+
* The longest a provider's own first-byte handling may legitimately run
|
|
264
|
+
* before it gives up, over every attempt it permits: `windowMs(n)` is the wait
|
|
265
|
+
* of attempt n, applied to the response headers and again to the first chunk,
|
|
266
|
+
* and `backoffMs[n]` the sleep before attempt n (index 0 unused, the last
|
|
267
|
+
* value repeats). `transportMs` covers the header stage only; `semanticMs`
|
|
268
|
+
* covers headers plus first chunk. The agent watchdog's first-response
|
|
269
|
+
* deadlines sit above these, so the provider's timeout and retry decide first.
|
|
270
|
+
*/
|
|
271
|
+
export function providerFirstResponseBudget({ attempts, windowMs, backoffMs = [] }) {
|
|
272
|
+
let transportMs = 0;
|
|
273
|
+
let semanticMs = 0;
|
|
274
|
+
for (let attempt = 0; attempt < Math.max(1, attempts); attempt++) {
|
|
275
|
+
const backoff = attempt > 0 ? (backoffMs[Math.min(attempt, backoffMs.length - 1)] ?? 0) : 0;
|
|
276
|
+
const window = windowMs(attempt);
|
|
277
|
+
transportMs += backoff + window;
|
|
278
|
+
semanticMs += backoff + 2 * window;
|
|
279
|
+
}
|
|
280
|
+
return { transportMs, semanticMs };
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* A provider's first-byte policy `{ timeoutMs, maxMs, retries }`: `timeoutMs`
|
|
285
|
+
* is the first attempt's window (headers, and again the first chunk); each
|
|
286
|
+
* first-byte timeout doubles the next window up to `maxMs`, and `retries` caps
|
|
287
|
+
* how many of those timeouts are retried. `retries: null` leaves first-byte
|
|
288
|
+
* timeouts to the provider's ordinary ladder, every attempt on `timeoutMs`.
|
|
289
|
+
* Returns the window of an attempt after `timeouts` first-byte timeouts.
|
|
290
|
+
*/
|
|
291
|
+
export function firstByteWindowMs(policy, timeouts = 0) {
|
|
292
|
+
if (policy.retries == null) return policy.timeoutMs;
|
|
293
|
+
return Math.min(policy.timeoutMs * 2 ** timeouts, Math.max(policy.timeoutMs, policy.maxMs));
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* providerFirstResponseBudget for a first-byte policy over a ladder of
|
|
298
|
+
* `attempts` sends. Connection drops and 5xx responses share that ladder with
|
|
299
|
+
* first-byte timeouts, and such a failure can land just before the timeout, so
|
|
300
|
+
* every attempt is budgeted a full window. A window only grows with the
|
|
301
|
+
* timeouts before it and at most `retries` timeouts are retried, so the worst
|
|
302
|
+
* case has the timeouts first, then later attempts at the widest window.
|
|
303
|
+
*/
|
|
304
|
+
export function firstBytePolicyBudget(policy, { attempts, backoffMs }) {
|
|
305
|
+
return providerFirstResponseBudget({
|
|
306
|
+
attempts,
|
|
307
|
+
windowMs: (attempt) => firstByteWindowMs(policy, Math.min(attempt, policy.retries ?? 0)),
|
|
308
|
+
backoffMs,
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
|
|
262
312
|
// First retry has a small floor (250ms) instead of 0ms: an immediate reissue on
|
|
263
313
|
// a transient 5xx burst lets parallel workers thundering-herd the backend in
|
|
264
314
|
// lockstep (jitter alone can't decluster a 0ms base). Subsequent steps keep the
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { renderBackgroundTask, startBackgroundTask } from '../../../../../shared/background-tasks.mjs';
|
|
2
2
|
import { killShellDescendants, waitForShellDescendants } from '../../lib/shell-descendants.mjs';
|
|
3
|
+
import { releaseShellJobWorkspace } from '../lib/shell-job-records.mjs';
|
|
3
4
|
import { consumeFilterTeeCapture } from '../shell-analysis.mjs';
|
|
4
5
|
import { compactShellOutputLosslessly, renderShellOutputBody } from '../shell-lossless-compact.mjs';
|
|
5
6
|
import { removeTransportFileNow } from './transport-artifacts.mjs';
|
|
@@ -33,7 +34,10 @@ function trackSurvivingDescendants(handle, { command, cwd, options, startedAtMs
|
|
|
33
34
|
meta: { task_id: handle.taskId, stdout: null, stderr: null, cwd, timeoutMs: 0 },
|
|
34
35
|
resultType: 'shell_task_result',
|
|
35
36
|
run: async () => {
|
|
36
|
-
await waitForShellDescendants(handle
|
|
37
|
+
await waitForShellDescendants(handle);
|
|
38
|
+
// The folder reservation the finished command handed to its
|
|
39
|
+
// survivors ends with the last of them.
|
|
40
|
+
releaseShellJobWorkspace(handle.taskId);
|
|
37
41
|
return {
|
|
38
42
|
task_id: handle.taskId,
|
|
39
43
|
status: 'completed',
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
1
2
|
import { writeFileSync } from 'node:fs';
|
|
2
3
|
import { tmpdir } from 'node:os';
|
|
3
4
|
import { join as pathJoin } from 'node:path';
|
|
@@ -23,12 +24,15 @@ export function hoistInlineScript(command, shellType) {
|
|
|
23
24
|
planLongShellScriptFileTransport(command, transport);
|
|
24
25
|
if (!hoist) return { command, hoistPath: null };
|
|
25
26
|
try {
|
|
26
|
-
|
|
27
|
+
// One file per command: parallel calls start within the same millisecond,
|
|
28
|
+
// and a shared name let a later script overwrite an earlier one before it
|
|
29
|
+
// ran. The exclusive flag refuses any name that already exists.
|
|
30
|
+
const file = pathJoin(tmpdir(), `mixdog-inline-${process.pid}-${randomUUID()}${hoist.extension}`);
|
|
27
31
|
// Windows PowerShell 5.1 interprets UTF-8 without BOM as the active ANSI
|
|
28
32
|
// codepage. Preserve non-ASCII command text when the transport changes a
|
|
29
33
|
// long command into a .ps1 file.
|
|
30
34
|
const fileBody = hoist.extension === '.ps1' ? `\uFEFF${hoist.body}` : hoist.body;
|
|
31
|
-
writeFileSync(file, fileBody, 'utf8');
|
|
35
|
+
writeFileSync(file, fileBody, { encoding: 'utf8', flag: 'wx' });
|
|
32
36
|
return { command: hoist.replace(file.replace(/\\/g, '/')), hoistPath: file };
|
|
33
37
|
} catch {
|
|
34
38
|
return { command, hoistPath: null };
|