mixdog 1.2.2 → 1.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -0
- package/package.json +2 -1
- package/scripts/provider-pingpong-live.mjs +509 -0
- package/src/agents/advisor/AGENT.md +1 -1
- package/src/agents/advisor/agent.json +1 -1
- package/src/defaults/shipped-history.json +5 -0
- package/src/defaults/skills/setup/SKILL.md +6 -1
- package/src/defaults/skills/setup/references/actions.md +44 -22
- package/src/defaults/skills/setup/references/surfaces.md +10 -8
- package/src/headless-exec.mjs +15 -8
- package/src/lib/keychain-cjs.cjs +7 -4
- package/src/output-styles/common.md +11 -10
- package/src/rules/agent/AGENT.md +5 -5
- package/src/rules/lead/LEAD.md +5 -5
- package/src/runtime/agent/orchestrator/agent-trace-io.mjs +92 -61
- package/src/runtime/agent/orchestrator/cache-mtime.mjs +10 -1
- package/src/runtime/agent/orchestrator/config-providers-merge.mjs +7 -0
- package/src/runtime/agent/orchestrator/config.mjs +5 -0
- package/src/runtime/agent/orchestrator/context/collect.mjs +1 -0
- package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +26 -7
- package/src/runtime/agent/orchestrator/context/skill-catalog.mjs +112 -7
- package/src/runtime/agent/orchestrator/providers/anthropic-api-request.mjs +48 -20
- package/src/runtime/agent/orchestrator/providers/anthropic-error-contract.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-max-tokens.mjs +24 -17
- package/src/runtime/agent/orchestrator/providers/anthropic-messages.mjs +7 -6
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +29 -10
- package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-blocks.mjs +20 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events/content-block-delta.mjs +15 -2
- package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events/content-block-start.mjs +11 -4
- package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events/message-events.mjs +3 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events.mjs +12 -5
- package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-outcome.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-state.mjs +14 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-turn-result.mjs +9 -0
- package/src/runtime/agent/orchestrator/providers/anthropic.mjs +6 -0
- package/src/runtime/agent/orchestrator/providers/antigravity-request.mjs +58 -7
- package/src/runtime/agent/orchestrator/providers/antigravity-response.mjs +29 -10
- package/src/runtime/agent/orchestrator/providers/antigravity-retry-policy.mjs +16 -3
- package/src/runtime/agent/orchestrator/providers/antigravity-stream.mjs +10 -61
- package/src/runtime/agent/orchestrator/providers/antigravity-transport.mjs +12 -6
- package/src/runtime/agent/orchestrator/providers/codex-client-meta.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/command-code-oauth.mjs +114 -72
- package/src/runtime/agent/orchestrator/providers/compat-request-policy.mjs +78 -2
- package/src/runtime/agent/orchestrator/providers/cursor-auth.mjs +37 -5
- package/src/runtime/agent/orchestrator/providers/cursor-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/cursor-wire-stream-bridge.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/cursor-wire-stream-messages.mjs +43 -2
- package/src/runtime/agent/orchestrator/providers/cursor-wire.mjs +3 -0
- package/src/runtime/agent/orchestrator/providers/cursor.mjs +9 -2
- package/src/runtime/agent/orchestrator/providers/custom-provider-config.mjs +64 -1
- package/src/runtime/agent/orchestrator/providers/custom-provider.mjs +70 -6
- package/src/runtime/agent/orchestrator/providers/custom-reasoning.mjs +34 -7
- package/src/runtime/agent/orchestrator/providers/custom-tool-wire.mjs +32 -6
- package/src/runtime/agent/orchestrator/providers/deepseek.mjs +67 -0
- package/src/runtime/agent/orchestrator/providers/effort-configuration.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/gemini-cache-policy.mjs +11 -4
- package/src/runtime/agent/orchestrator/providers/gemini-cache.mjs +25 -8
- package/src/runtime/agent/orchestrator/providers/gemini-error-contract.mjs +87 -5
- package/src/runtime/agent/orchestrator/providers/gemini-request-body.mjs +41 -5
- package/src/runtime/agent/orchestrator/providers/gemini-retry-policy.mjs +13 -13
- package/src/runtime/agent/orchestrator/providers/gemini-schema.mjs +355 -37
- package/src/runtime/agent/orchestrator/providers/gemini-sdk-request.mjs +1 -2
- package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +93 -47
- package/src/runtime/agent/orchestrator/providers/gemini-thinking.mjs +55 -10
- package/src/runtime/agent/orchestrator/providers/gemini.mjs +26 -8
- package/src/runtime/agent/orchestrator/providers/grok-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/grok-oauth.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/lib/action-input-contract.mjs +60 -0
- package/src/runtime/agent/orchestrator/providers/lib/anthropic-native-blocks.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +246 -42
- package/src/runtime/agent/orchestrator/providers/lib/anthropic-server-tool-usage.mjs +18 -0
- package/src/runtime/agent/orchestrator/providers/lib/anthropic-system-blocks.mjs +27 -6
- package/src/runtime/agent/orchestrator/providers/lib/claude-bridge-schema.mjs +388 -0
- package/src/runtime/agent/orchestrator/providers/lib/inclusive-usage.mjs +54 -0
- package/src/runtime/agent/orchestrator/providers/lib/origin-bound-fetch.mjs +16 -0
- package/src/runtime/agent/orchestrator/providers/lib/responses-terminal-fields.mjs +11 -0
- package/src/runtime/agent/orchestrator/providers/lib/usage-primitives.mjs +8 -0
- package/src/runtime/agent/orchestrator/providers/lib/wire-pairing.mjs +48 -22
- package/src/runtime/agent/orchestrator/providers/media-normalization.mjs +119 -18
- package/src/runtime/agent/orchestrator/providers/mimo-oauth-profile.mjs +13 -15
- package/src/runtime/agent/orchestrator/providers/model-proxy-channel.d.mts +1 -1
- package/src/runtime/agent/orchestrator/providers/model-proxy-channel.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/model-proxy-provider.mjs +33 -1
- package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/openai-codex-metadata.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-send.mjs +121 -61
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/chunk-events.mjs +35 -14
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-result.mjs +5 -2
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-state.mjs +37 -7
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/tool-call-acc.mjs +2 -9
- package/src/runtime/agent/orchestrator/providers/openai-compat-error-contract.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/openai-compat-models.mjs +47 -2
- package/src/runtime/agent/orchestrator/providers/openai-compat-options.mjs +47 -25
- package/src/runtime/agent/orchestrator/providers/openai-compat-presets.mjs +5 -1
- package/src/runtime/agent/orchestrator/providers/openai-compat-reasoning-field.mjs +151 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-response-normalization.mjs +42 -24
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses-events.mjs +63 -25
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses-head-parity.json +2901 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses-parity.fixtures.mjs +172 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses.mjs +53 -5
- package/src/runtime/agent/orchestrator/providers/openai-compat-stream.mjs +7 -1
- package/src/runtime/agent/orchestrator/providers/openai-compat-trace.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-wire.mjs +103 -26
- package/src/runtime/agent/orchestrator/providers/openai-compat-xai-send.mjs +23 -4
- package/src/runtime/agent/orchestrator/providers/openai-compat-xai.mjs +11 -6
- package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +6 -1
- package/src/runtime/agent/orchestrator/providers/openai-direct-request.mjs +15 -23
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events/output-items.mjs +23 -10
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events/terminal-frames.mjs +25 -4
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events.mjs +10 -0
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-items.mjs +18 -7
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-outcome.mjs +4 -0
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-state.mjs +5 -0
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/text-relay.mjs +9 -1
- package/src/runtime/agent/orchestrator/providers/openai-model-capabilities.mjs +80 -0
- package/src/runtime/agent/orchestrator/providers/openai-oauth-dispatch.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +7 -0
- package/src/runtime/agent/orchestrator/providers/openai-oauth.mjs +7 -1
- package/src/runtime/agent/orchestrator/providers/openai-responses-input.mjs +71 -24
- package/src/runtime/agent/orchestrator/providers/openai-responses-payload-parity.fixture.json +323 -0
- package/src/runtime/agent/orchestrator/providers/openai-responses-payload.mjs +44 -16
- package/src/runtime/agent/orchestrator/providers/openai-ws-delta.mjs +7 -16
- package/src/runtime/agent/orchestrator/providers/openai-ws-response-state/refusals.mjs +60 -0
- package/src/runtime/agent/orchestrator/providers/openai-ws-response-state/tool-calls.mjs +51 -35
- package/src/runtime/agent/orchestrator/providers/openai-ws-response-state.mjs +30 -0
- package/src/runtime/agent/orchestrator/providers/openai-ws-stream/event-switch.mjs +12 -0
- package/src/runtime/agent/orchestrator/providers/openai-ws-stream/terminal-frames.mjs +25 -6
- package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +11 -3
- package/src/runtime/agent/orchestrator/providers/opencode-go-gemini.mjs +170 -0
- package/src/runtime/agent/orchestrator/providers/opencode-go.mjs +75 -70
- package/src/runtime/agent/orchestrator/providers/openrouter.mjs +75 -0
- package/src/runtime/agent/orchestrator/providers/provider-error-kind.mjs +147 -8
- package/src/runtime/agent/orchestrator/providers/registry.mjs +4 -1
- package/src/runtime/agent/orchestrator/providers/retry-classification.mjs +5 -0
- package/src/runtime/agent/orchestrator/providers/transport-scope.d.mts +6 -0
- package/src/runtime/agent/orchestrator/providers/transport-scope.mjs +28 -0
- package/src/runtime/agent/orchestrator/providers/wire-gateway.mjs +157 -0
- package/src/runtime/agent/orchestrator/providers/wire-route.mjs +512 -0
- package/src/runtime/agent/orchestrator/providers/xai-tool-search-head-parity.json +1131 -0
- package/src/runtime/agent/orchestrator/providers/xai-tool-search.fixtures.mjs +183 -0
- package/src/runtime/agent/orchestrator/runtime-core/ask-user-tool-defs.mjs +100 -0
- package/src/runtime/agent/orchestrator/runtime-core/deferred-tool-availability.mjs +21 -0
- package/src/runtime/agent/orchestrator/runtime-core/effort.mjs +15 -0
- package/src/runtime/agent/orchestrator/runtime-core/provider-request-snapshot.mjs +7 -3
- package/src/runtime/agent/orchestrator/runtime-core/session-title.mjs +21 -1
- package/src/runtime/agent/orchestrator/runtime-core/skill-tool-loading.mjs +14 -3
- package/src/runtime/agent/orchestrator/runtime-core/tool-bridge.mjs +526 -0
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog-data.mjs +3 -0
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog-schema.mjs +10 -7
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +176 -71
- package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +62 -10
- package/src/runtime/agent/orchestrator/runtime-core/tool-exposure.mjs +96 -0
- package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +3 -1
- package/src/runtime/agent/orchestrator/session/compact/constants.mjs +3 -2
- package/src/runtime/agent/orchestrator/session/compact/messages.mjs +14 -93
- package/src/runtime/agent/orchestrator/session/compact/summary-anchor.mjs +5 -0
- package/src/runtime/agent/orchestrator/session/compact/user-message-kind.mjs +120 -0
- package/src/runtime/agent/orchestrator/session/context-tool-schema.mjs +17 -2
- package/src/runtime/agent/orchestrator/session/context-utils.mjs +8 -4
- package/src/runtime/agent/orchestrator/session/eager-dispatch/admission.mjs +2 -1
- package/src/runtime/agent/orchestrator/session/eager-dispatch.mjs +6 -1
- package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +91 -1
- package/src/runtime/agent/orchestrator/session/loop/completion-guards.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/context-overflow.mjs +56 -0
- package/src/runtime/agent/orchestrator/session/loop/deferred-call-through.mjs +18 -8
- package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +1 -0
- package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +21 -10
- package/src/runtime/agent/orchestrator/session/loop/provider-tool-exclusions.mjs +132 -0
- package/src/runtime/agent/orchestrator/session/loop/request-boundary.mjs +30 -0
- package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +63 -20
- package/src/runtime/agent/orchestrator/session/loop/step-auto-effort.mjs +2 -1
- package/src/runtime/agent/orchestrator/session/loop/tool-call-resolution.mjs +95 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +30 -3
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +15 -4
- package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +15 -1
- package/src/runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs +150 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-phase.mjs +4 -1
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-auto-effort.mjs +2 -1
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-commit.mjs +34 -12
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +16 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-loop-options.mjs +57 -25
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-prepare.mjs +6 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +4 -0
- package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +8 -0
- package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +208 -14
- package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +15 -3
- package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +25 -3
- package/src/runtime/agent/orchestrator/session/manager/session-fallback-title.mjs +82 -0
- package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +19 -2
- package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +3 -0
- package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +4 -1
- package/src/runtime/agent/orchestrator/session/manager.mjs +2 -1
- package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +6 -0
- package/src/runtime/agent/orchestrator/session/send-with-recovery.mjs +13 -0
- package/src/runtime/agent/orchestrator/session/side-question-store.mjs +96 -0
- package/src/runtime/agent/orchestrator/session/side-question.mjs +192 -0
- package/src/runtime/agent/orchestrator/session/store/lifecycle-barriers.mjs +17 -3
- package/src/runtime/agent/orchestrator/session/store/live-state.mjs +23 -0
- package/src/runtime/agent/orchestrator/session/store/paths-heartbeat.mjs +58 -2
- package/src/runtime/agent/orchestrator/session/store/session-delete.mjs +41 -28
- package/src/runtime/agent/orchestrator/session/store/session-observers.mjs +4 -2
- package/src/runtime/agent/orchestrator/session/store/sweep/sweep-finish.mjs +12 -1
- package/src/runtime/agent/orchestrator/session/store/write-admission.mjs +3 -1
- package/src/runtime/agent/orchestrator/session/store-summary-archived-agent.mjs +34 -15
- package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +4 -0
- package/src/runtime/agent/orchestrator/session/store-summary-fields.mjs +8 -0
- package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +10 -1
- package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +10 -2
- package/src/runtime/agent/orchestrator/session/store.mjs +19 -3
- package/src/runtime/agent/orchestrator/session/tool-batch/execute-call.mjs +1 -0
- package/src/runtime/agent/orchestrator/session/tool-batch/finalize.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/tool-batch/record-outcome.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/tool-batch/state.mjs +7 -1
- package/src/runtime/agent/orchestrator/session/tool-result-offload.mjs +4 -0
- package/src/runtime/agent/orchestrator/session/tool-schema-rejection.mjs +77 -0
- package/src/runtime/agent/orchestrator/tools/bash-policy-scan.mjs +8 -2
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/command-preflight.mjs +3 -3
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +4 -1
- package/src/runtime/agent/orchestrator/tools/builtin/external-tool-adapters.mjs +14 -10
- package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-job-records.mjs +49 -34
- package/src/runtime/agent/orchestrator/tools/builtin/runtime-capabilities.mjs +23 -1
- package/src/runtime/agent/orchestrator/tools/code-graph/dispatch/root-resolution.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/code-graph/search.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/patch/ui-diff.mjs +73 -39
- package/src/runtime/agent/orchestrator/tools/progress-message.mjs +18 -1
- package/src/runtime/agent/orchestrator/tools/shell-command.mjs +7 -4
- package/src/runtime/agent/orchestrator/tools/shell-exec-policy.mjs +88 -12
- package/src/runtime/agent/orchestrator/tools/shell-policy.mjs +2 -0
- package/src/runtime/computer-bridge/action-schema.mjs +44 -21
- package/src/runtime/github/tool.mjs +92 -2
- package/src/runtime/memory/index.mjs +1 -0
- package/src/runtime/memory/lib/http-router/ingest-routes.mjs +22 -1
- package/src/runtime/memory/lib/ingest/transcript-offsets.mjs +2 -0
- package/src/runtime/memory/lib/pg/adapter.mjs +98 -1
- package/src/runtime/memory/lib/pg/process.mjs +31 -26
- package/src/runtime/memory/lib/pg/run-child.mjs +49 -0
- package/src/runtime/memory/lib/pg/supervisor.mjs +108 -3
- package/src/runtime/memory/lib/runtime-fetcher.mjs +12 -13
- package/src/runtime/memory/lib/transcript-ingest.mjs +14 -0
- package/src/runtime/office/README.md +1 -1
- package/src/runtime/office/authoring/html-document-author.mjs +2 -0
- package/src/runtime/office/authoring/pptx-contact-sheet.mjs +2 -0
- package/src/runtime/office/authoring/pptx-html-measure.mjs +2 -0
- package/src/runtime/office/authoring/pptx-html-runner.mjs +2 -0
- package/src/runtime/office/authoring/xlsx-html-runner.mjs +2 -0
- package/src/runtime/office/core/office-actions-read.mjs +3 -0
- package/src/runtime/office/core/office-render-preview.mjs +2 -0
- package/src/runtime/office/core/office-session-dispatch.mjs +7 -0
- package/src/runtime/office/core/office-sessionless-actions.mjs +8 -0
- package/src/runtime/office/core/office-sessions.mjs +5 -0
- package/src/runtime/office/core/office-transactions.mjs +3 -0
- package/src/runtime/office/core/office-write-ledger.mjs +98 -0
- package/src/runtime/office/design/library/templates/mixdog-executive.mixdog-edit.pptx +0 -0
- package/src/runtime/office/index.mjs +30 -0
- package/src/runtime/office/pdf/pdf-edit-document.mjs +2 -0
- package/src/runtime/office/pdf/pdf-render.mjs +23 -7
- package/src/runtime/office/pdf/pdf-security.mjs +2 -0
- package/src/runtime/office/portable/portable-opc.mjs +4 -1
- package/src/runtime/office/quality/visual-diff.mjs +2 -0
- package/src/runtime/shared/bounded-file-read.mjs +13 -0
- package/src/runtime/shared/bounded-line-diff.mjs +182 -0
- package/src/runtime/shared/buffered-appender.mjs +18 -0
- package/src/runtime/shared/config.mjs +78 -18
- package/src/runtime/shared/err-text.mjs +6 -0
- package/src/runtime/shared/file-permissions.d.mts +6 -1
- package/src/runtime/shared/file-permissions.mjs +54 -6
- package/src/runtime/shared/llm/anthropic-effort.mjs +6 -0
- package/src/runtime/shared/llm/usage-accounting.mjs +5 -2
- package/src/runtime/shared/llm/usage-ledger-rollup.mjs +3 -0
- package/src/runtime/shared/loopback-listener.mjs +9 -0
- package/src/runtime/shared/provider-api-key.mjs +2 -0
- package/src/runtime/shared/review-diff.mjs +52 -0
- package/src/runtime/shared/session-sidebar-host.d.mts +4 -0
- package/src/runtime/shared/session-sidebar-host.mjs +38 -0
- package/src/runtime/shared/slow-span.mjs +114 -0
- package/src/runtime/shared/statusline/statusline-segments.mjs +28 -4
- package/src/runtime/shared/tool-card-model/card-header.mjs +6 -1
- package/src/runtime/shared/tool-card-model/generic-detail.mjs +39 -5
- package/src/runtime/shared/tool-card-model.mjs +5 -2
- package/src/runtime/shared/tool-output-limit.mjs +4 -0
- package/src/runtime/shared/tool-primitives.mjs +13 -0
- package/src/runtime/shared/tool-result-summary.mjs +8 -1
- package/src/runtime/shared/tool-surface.mjs +18 -3
- package/src/runtime/shared/tool-work-units.mjs +40 -4
- package/src/runtime/shared/transcript-writer/purge.mjs +74 -0
- package/src/runtime/shared/transcript-writer.mjs +10 -2
- package/src/runtime/shared/turn-changes.mjs +268 -100
- package/src/runtime/shared/turn-review-reply.mjs +8 -39
- package/src/runtime/shared/turn-snapshot-store.mjs +19 -108
- package/src/runtime/shared/turn-snapshot.mjs +857 -683
- package/src/runtime/shared/turn-worktree-snapshot.mjs +183 -255
- package/src/runtime/shared/user-data-guard.mjs +262 -49
- package/src/runtime/shared/worktrees/carry.mjs +531 -0
- package/src/runtime/shared/worktrees/contract.mjs +34 -0
- package/src/runtime/shared/worktrees/file-recovery.mjs +68 -0
- package/src/runtime/shared/worktrees/git-head.mjs +205 -0
- package/src/runtime/shared/worktrees/git.mjs +8 -3
- package/src/runtime/shared/worktrees/maintenance.mjs +1 -1
- package/src/runtime/shared/worktrees/manager.mjs +156 -8
- package/src/runtime/shared/worktrees/merge.mjs +31 -21
- package/src/runtime/shared/worktrees/paths.d.mts +6 -0
- package/src/runtime/terminal-bridge/client.mjs +44 -11
- package/src/runtime/terminal-bridge/tool-defs.mjs +13 -6
- package/src/runtime/tidy/apply.mjs +47 -2
- package/src/runtime/tidy/run-engines.mjs +11 -5
- package/src/session-runtime/agent-tool-routing.mjs +19 -13
- package/src/session-runtime/boot/apis.mjs +13 -5
- package/src/session-runtime/boot/facade.mjs +1 -0
- package/src/session-runtime/boot/infrastructure.mjs +6 -1
- package/src/session-runtime/boot/session.mjs +0 -1
- package/src/session-runtime/boot/tools.mjs +4 -1
- package/src/session-runtime/cwd-plugins/cwd-apply.mjs +12 -5
- package/src/session-runtime/internal-tool-executor/ask-user-tool.mjs +65 -0
- package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +3 -1
- package/src/session-runtime/internal-tool-executor/knowledge-tools.mjs +11 -4
- package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +115 -18
- package/src/session-runtime/internal-tool-executor.mjs +6 -2
- package/src/session-runtime/lifecycle/cold-heir.mjs +188 -0
- package/src/session-runtime/lifecycle/inheritance.mjs +71 -27
- package/src/session-runtime/lifecycle/session-catalog.mjs +12 -3
- package/src/session-runtime/lifecycle/session-switch/resume.mjs +6 -0
- package/src/session-runtime/lifecycle/session-switch/session-delete.mjs +29 -6
- package/src/session-runtime/lifecycle/teardown.mjs +72 -7
- package/src/session-runtime/lifecycle-api.mjs +1 -0
- package/src/session-runtime/mcp-glue/connect.mjs +17 -5
- package/src/session-runtime/model-route/set-route.mjs +2 -2
- package/src/session-runtime/native-web-search-usage.mjs +51 -0
- package/src/session-runtime/native-web-search.mjs +10 -1
- package/src/session-runtime/new-session-config.mjs +4 -2
- package/src/session-runtime/provider-auth/login.mjs +4 -0
- package/src/session-runtime/resource-scope-decorate.mjs +10 -3
- package/src/session-runtime/runtime-review-api.mjs +8 -2
- package/src/session-runtime/services/agent-tool/index-write-queue.mjs +81 -20
- package/src/session-runtime/services/agent-tool/lead-worker-index/forgotten-leads.mjs +29 -0
- package/src/session-runtime/services/agent-tool/lead-worker-index/index-file.mjs +1 -1
- package/src/session-runtime/services/agent-tool/lead-worker-index.mjs +73 -7
- package/src/session-runtime/services/agent-tool/tag-registry.mjs +15 -1
- package/src/session-runtime/services/agent-tool/worker-index/row-store.mjs +10 -1
- package/src/session-runtime/services/agent-tool/worker-index.mjs +46 -7
- package/src/session-runtime/services/agent-tool.mjs +3 -0
- package/src/session-runtime/services/channel-admin.mjs +19 -3
- package/src/session-runtime/services/memory-runtime-proxy/calls.mjs +4 -0
- package/src/session-runtime/services/memory-runtime-proxy.mjs +1 -0
- package/src/session-runtime/services/provider-admin.mjs +81 -15
- package/src/session-runtime/session-transcript-purge.mjs +32 -0
- package/src/session-runtime/session-turn-api.mjs +14 -5
- package/src/session-runtime/settings-builtin-tools-api.mjs +9 -0
- package/src/session-runtime/setup-tool/executor.mjs +36 -6
- package/src/session-runtime/setup-tool/extended-actions.mjs +86 -6
- package/src/session-runtime/setup-tool/settings-contract.mjs +13 -3
- package/src/session-runtime/setup-tool/tool-defs.mjs +13 -4
- package/src/session-runtime/skills-api.mjs +3 -5
- package/src/session-runtime/tool-surface.mjs +5 -1
- package/src/session-runtime/turn/compaction-gate.mjs +25 -0
- package/src/session-runtime/turn/session-ops.mjs +7 -5
- package/src/session-runtime/turn/side-question-ops.mjs +22 -0
- package/src/session-runtime/turn/turn-run/ask-callbacks.mjs +5 -1
- package/src/session-runtime/turn/turn-run/turn-prepare.mjs +8 -3
- package/src/session-runtime/turn/turn-run/turn-settle.mjs +10 -0
- package/src/session-runtime/turn/turn-run/turn-timing.mjs +4 -3
- package/src/session-runtime/turn/turn-run.mjs +25 -9
- package/src/session-runtime/usage-stats-api.mjs +43 -11
- package/src/session-runtime/workspace/project-branches.mjs +7 -5
- package/src/session-runtime/workspace/transition-steps.mjs +129 -31
- package/src/session-runtime/workspace/transitions.mjs +190 -15
- package/src/standalone/daemon-agent-control.mjs +9 -1
- package/src/standalone/daemon-local-session-bridge.mjs +14 -1
- package/src/standalone/daemon-owner.mjs +17 -4
- package/src/standalone/daemon-pg-stop.mjs +51 -0
- package/src/standalone/daemon-stop-budget.d.mts +2 -0
- package/src/standalone/daemon-stop-budget.mjs +18 -0
- package/src/standalone/daemon-stored-session-views.mjs +2 -0
- package/src/standalone/daemon-telemetry.mjs +19 -0
- package/src/standalone/daemon.mjs +61 -1
- package/src/standalone/desktop-service-registry.mjs +5 -0
- package/src/standalone/local-session-runtime.mjs +70 -19
- package/src/standalone/session-client.mjs +42 -0
- package/src/standalone/session-protocol.mjs +7 -0
- package/src/standalone/session-proxy/projection.mjs +41 -4
- package/src/standalone/session-runtime-inline-host/boot-loaders.mjs +15 -1
- package/src/standalone/session-runtime-inline-host.mjs +1 -0
- package/src/standalone/session-service/session-calls/session-action.mjs +18 -3
- package/src/standalone/session-service-api.mjs +6 -1
- package/src/standalone/session-state-patch.d.mts +2 -1
- package/src/standalone/session-state-patch.mjs +41 -1
- package/src/tui/App.jsx +25 -0
- package/src/tui/app/app-view/floating-panel.jsx +26 -1
- package/src/tui/app/btw-controller.mjs +118 -0
- package/src/tui/app/create-app-pickers.mjs +2 -0
- package/src/tui/app/shell-layout/row-budgets.mjs +11 -1
- package/src/tui/app/shell-layout/surfaces.mjs +3 -1
- package/src/tui/app/slash-commands.mjs +13 -3
- package/src/tui/app/slash-dispatch/session-commands.mjs +19 -6
- package/src/tui/app/use-global-key-input/approval-shortcut.mjs +12 -0
- package/src/tui/app/use-global-key-input.mjs +5 -12
- package/src/tui/app/use-prompt-handlers.mjs +11 -0
- package/src/tui/components/BtwPanel.jsx +53 -0
- package/src/tui/components/QuestionPanel.jsx +275 -0
- package/src/tui/components/question-panel-model.mjs +156 -0
- package/src/tui/dist/index.mjs +2413 -1465
- package/src/tui/session/context-state.mjs +4 -2
- package/src/tui/session/session-api/commands.mjs +10 -0
- package/src/tui/session/session-api/controls.mjs +2 -2
- package/src/tui/session/session-api/integrations.mjs +9 -2
- package/src/tui/session/session-api/lifecycle/dispose.mjs +1 -0
- package/src/tui/session/session-api/lifecycle.mjs +2 -1
- package/src/tui/session/session-api/settings.mjs +6 -0
- package/src/tui/session/session-api.mjs +1 -0
- package/src/tui/session/tool-approval.mjs +10 -7
- package/src/tui/session/transcript-spill.mjs +14 -7
- package/src/tui/session/turn-stream.mjs +174 -31
- package/src/tui/session/turn.mjs +12 -5
- package/src/workflows/default/WORKFLOW.md +3 -1
|
@@ -35,13 +35,19 @@ function dispatchMcp(name, args, { cwd, callerSessionId, sessionRef, executeOpts
|
|
|
35
35
|
});
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
function dispatchInternal(
|
|
38
|
+
function dispatchInternal(
|
|
39
|
+
name,
|
|
40
|
+
args,
|
|
41
|
+
{ cwd, callerSessionId, sessionRef, executeOpts, notifyFn, toolApprovalHook, elevationApproved }
|
|
42
|
+
) {
|
|
39
43
|
// callerSessionId propagates into server.mjs dispatchTool so that
|
|
40
44
|
// dispatchAiWrapped can detect and reject recursive calls from a
|
|
41
45
|
// hidden-role session (recall/search → self).
|
|
42
46
|
return executeInternalTool(name, args, {
|
|
43
47
|
scopeId: sessionRef?.mcpScopeId || null,
|
|
44
48
|
callerSessionId,
|
|
49
|
+
// The calling session itself: bridge tools answer within its scope.
|
|
50
|
+
callerSession: sessionRef || null,
|
|
45
51
|
callerCwd: cwd,
|
|
46
52
|
setCallerCwd: async (nextCwd) => {
|
|
47
53
|
const applyForCaller = sessionRef?._applyResolvedCwdForCaller;
|
|
@@ -58,6 +64,8 @@ function dispatchInternal(name, args, { cwd, callerSessionId, sessionRef, execut
|
|
|
58
64
|
notifyFn,
|
|
59
65
|
toolApprovalHook,
|
|
60
66
|
toolCallId: executeOpts.toolCallId || null,
|
|
67
|
+
// Runtime-granted for this call only (terminal run); never from model args.
|
|
68
|
+
elevationApproved: elevationApproved === true,
|
|
61
69
|
invocationSource: 'model-tool',
|
|
62
70
|
});
|
|
63
71
|
}
|
|
@@ -90,9 +98,12 @@ export function dispatchToolCall({ name, args }, ctx) {
|
|
|
90
98
|
// variants) adapt to a native execution inside executeBuiltinTool's default
|
|
91
99
|
// case; on a shape mismatch it falls back to the redirect guidance message.
|
|
92
100
|
if (name === 'shell' || isBuiltinTool(name) || isExternalAdapterTool(name)) {
|
|
93
|
-
const builtinOpts =
|
|
94
|
-
|
|
95
|
-
:
|
|
101
|
+
const builtinOpts = {
|
|
102
|
+
...completionToolOpts,
|
|
103
|
+
...(executeOpts.suppressReadUnchangedStub ? { suppressReadUnchangedStub: true } : {}),
|
|
104
|
+
// Runtime-granted only; any value inherited from executeOpts is overridden.
|
|
105
|
+
elevationApproved: ctx.elevationApproved === true,
|
|
106
|
+
};
|
|
96
107
|
return executeBuiltinTool(name, args, cwd, builtinOpts);
|
|
97
108
|
}
|
|
98
109
|
return formatUnknownBuiltinToolMessage(name, args, 'tool');
|
|
@@ -8,12 +8,13 @@
|
|
|
8
8
|
import { isMcpTool } from '../../mcp/client.mjs';
|
|
9
9
|
import { prepareDeferredToolCallThrough } from './deferred-call-through.mjs';
|
|
10
10
|
import { refreshDeferredMcpToolCatalog } from '../../runtime-core/tool-catalog.mjs';
|
|
11
|
+
import { bridgeTargetUnavailable } from '../../runtime-core/tool-bridge.mjs';
|
|
11
12
|
import { preDispatchDenyForSession, routeWebFetchCall } from './pre-dispatch-deny.mjs';
|
|
12
13
|
import { runWithToolExecutionOwner } from '../../../../shared/tool-execution-owner.mjs';
|
|
13
14
|
import { runWithLocalSearchTelemetry } from '../../tools/builtin/local-search-telemetry.mjs';
|
|
14
15
|
import { throwIfAborted } from '../../../../shared/abort-race.mjs';
|
|
15
16
|
import { prepareToolCall } from './tool-exec/call-prep.mjs';
|
|
16
|
-
import { applyBeforeToolHook } from './tool-exec/before-hook.mjs';
|
|
17
|
+
import { applyBeforeToolHook, applyShellElevationGate } from './tool-exec/before-hook.mjs';
|
|
17
18
|
import { dispatchToolCall } from './tool-exec/dispatch.mjs';
|
|
18
19
|
import { applyAfterToolHook } from './tool-exec/after-hook.mjs';
|
|
19
20
|
import { runReadOnlyIoWithDeadline } from './tool-exec/read-only-deadline.mjs';
|
|
@@ -65,6 +66,18 @@ async function executeToolOwned(name, args, cwd, callerSessionId, sessionRef, ex
|
|
|
65
66
|
if (isMcpTool(call.name)) refreshDeferredMcpToolCatalog(sessionRef);
|
|
66
67
|
const deferredPrep = prepareDeferredToolCallThrough(sessionRef, call.name);
|
|
67
68
|
if (deferredPrep?.deny) return deferredPrep.deny;
|
|
69
|
+
// A bridged target was resolved when its call_tool was projected; it must
|
|
70
|
+
// still be available in this session's scope (also after a hook rewrite).
|
|
71
|
+
// The authorized identity is the public tool name, not its transport
|
|
72
|
+
// (web_fetch routed to local_fetch/image_fetch stays web_fetch here).
|
|
73
|
+
if (executeOpts.bridgeWireCall) {
|
|
74
|
+
const unavailable = bridgeTargetUnavailable(sessionRef, finalCall.schemaName || finalCall.name);
|
|
75
|
+
if (unavailable) return unavailable;
|
|
76
|
+
}
|
|
77
|
+
// Elevated launches ask the user first; denied / no approval UI refuses the call.
|
|
78
|
+
const elevation = await applyShellElevationGate(call, { callerSessionId, executeOpts, toolApprovalHook });
|
|
79
|
+
if (elevation.denial) return elevation.denial;
|
|
80
|
+
throwIfAborted(executeOpts.signal);
|
|
68
81
|
const result = await runReadOnlyIoWithDeadline(call.name, executeOpts.signal || null, async (deadlineSignal) => {
|
|
69
82
|
let callOpts = executeOpts;
|
|
70
83
|
if (deadlineSignal !== executeOpts.signal) {
|
|
@@ -80,6 +93,7 @@ async function executeToolOwned(name, args, cwd, callerSessionId, sessionRef, ex
|
|
|
80
93
|
completionToolOpts,
|
|
81
94
|
notifyFn,
|
|
82
95
|
toolApprovalHook,
|
|
96
|
+
elevationApproved: elevation.elevationApproved === true,
|
|
83
97
|
});
|
|
84
98
|
});
|
|
85
99
|
return applyAfterToolHook(result, hookFrom(executeOpts, sessionRef, 'afterToolHook'), {
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
// Tool-exposure migration (native ↔ bridge-v1, and pre-versioned fixed
|
|
2
|
+
// surfaces → bridge-v1). The surface itself is rebuilt by
|
|
3
|
+
// applyDeferredToolSurface; this module adds what a changed request prefix
|
|
4
|
+
// invalidates: provider state, the prefix guard, the context baseline and the
|
|
5
|
+
// cache-break tag. Historical tool calls are never rewritten.
|
|
6
|
+
import {
|
|
7
|
+
applyDeferredToolSurface,
|
|
8
|
+
rebuildDeferredToolSurfaceForProvider,
|
|
9
|
+
} from '../../runtime-core/tool-catalog.mjs';
|
|
10
|
+
import {
|
|
11
|
+
bridgeSurfaceOutdated,
|
|
12
|
+
sessionToolExposure,
|
|
13
|
+
TOOL_EXPOSURE_BRIDGE,
|
|
14
|
+
TOOL_SURFACE_MIGRATION_INTENT,
|
|
15
|
+
toolExposureMigrationNeeded,
|
|
16
|
+
toolExposureModeForProvider,
|
|
17
|
+
} from '../../runtime-core/tool-exposure.mjs';
|
|
18
|
+
import { applyInitialDeferredToolManifestToBp2 } from '../../context/collect.mjs';
|
|
19
|
+
import { isAgentOwner } from '../../agent-owner.mjs';
|
|
20
|
+
import { honoredSchemaAllowlist } from '../manager/session-tool-surface.mjs';
|
|
21
|
+
import { syncSystemPrefix } from '../manager/prompt-utils.mjs';
|
|
22
|
+
import { invalidateProviderContextBaseline } from './compact-policy.mjs';
|
|
23
|
+
|
|
24
|
+
/** Drop everything measured against the previous tool surface. */
|
|
25
|
+
function invalidateForToolSurfaceMigration(session) {
|
|
26
|
+
delete session.providerState;
|
|
27
|
+
delete session._providerPrefixGuardState;
|
|
28
|
+
invalidateProviderContextBaseline(session);
|
|
29
|
+
session.updatedAt = Date.now();
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* After a surface re-apply outside a request (resume, provider switch)
|
|
34
|
+
* migrated the exposure: the first send of the next turn carries the tag.
|
|
35
|
+
*/
|
|
36
|
+
export function markToolSurfaceMigrated(session) {
|
|
37
|
+
invalidateForToolSurfaceMigration(session);
|
|
38
|
+
session.pendingCacheBreakIntent = TOOL_SURFACE_MIGRATION_INTENT;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** Provider switch: rebuild the surface for `provider`, migrating bridge ↔ native. */
|
|
42
|
+
export function rebuildToolSurfaceForProviderWithMigration(session, provider) {
|
|
43
|
+
if (!session) return false;
|
|
44
|
+
const migrating = toolExposureMigrationNeeded(session, provider);
|
|
45
|
+
rebuildDeferredToolSurfaceForProvider(session, provider);
|
|
46
|
+
if (migrating) markToolSurfaceMigrated(session);
|
|
47
|
+
return migrating;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// The latest assistant tool turn still waits for a result: not a safe boundary.
|
|
51
|
+
function hasUnansweredToolCalls(messages) {
|
|
52
|
+
const list = Array.isArray(messages) ? messages : [];
|
|
53
|
+
const index = list.findLastIndex((message) => message?.role === 'assistant' && message.toolCalls?.length);
|
|
54
|
+
if (index < 0) return false;
|
|
55
|
+
const answered = new Set(
|
|
56
|
+
list.slice(index + 1).flatMap((message) => (message?.role === 'tool' ? [message.toolCallId] : []))
|
|
57
|
+
);
|
|
58
|
+
return list[index].toolCalls.some((call) => call?.id && !answered.has(call.id));
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Request-boundary migration of a live session whose persisted exposure
|
|
63
|
+
* differs from its provider's. `messages` is the transcript the request is
|
|
64
|
+
* built from; the fixed-guidance rewrite lands there (and on the session).
|
|
65
|
+
* Returns true when the surface changed; the caller drops its frozen tool
|
|
66
|
+
* snapshot and provider state and tags the send.
|
|
67
|
+
*/
|
|
68
|
+
export function migrateToolExposureAtBoundary(session, messages) {
|
|
69
|
+
if (!session || !toolExposureMigrationNeeded(session) || hasUnansweredToolCalls(messages)) return false;
|
|
70
|
+
const stored = session.messages;
|
|
71
|
+
const working = Array.isArray(messages) ? messages : stored;
|
|
72
|
+
if (Array.isArray(working)) session.messages = working;
|
|
73
|
+
try {
|
|
74
|
+
applyDeferredToolSurface(session, session.deferredSurfaceMode || 'lead', [], {
|
|
75
|
+
provider: session.provider,
|
|
76
|
+
model: session.model,
|
|
77
|
+
});
|
|
78
|
+
} finally {
|
|
79
|
+
if (Array.isArray(working) && session.messages !== working) {
|
|
80
|
+
// The rewrite may drop an emptied system message: keep the request
|
|
81
|
+
// transcript array identity the loop holds.
|
|
82
|
+
working.splice(0, working.length, ...session.messages);
|
|
83
|
+
}
|
|
84
|
+
session.messages = stored;
|
|
85
|
+
}
|
|
86
|
+
// The rewritten prompt messages are fresh objects; the canonical transcript
|
|
87
|
+
// the save path persists takes them too, so the next save writes the new
|
|
88
|
+
// prompt together with the new exposure.
|
|
89
|
+
if (Array.isArray(stored) && Array.isArray(working) && stored !== working) syncSystemPrefix(stored, working);
|
|
90
|
+
invalidateForToolSurfaceMigration(session);
|
|
91
|
+
return true;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Bridge state an agent surface carries; dropped when it returns to the full array.
|
|
95
|
+
const AGENT_BRIDGE_FIELDS = [
|
|
96
|
+
'toolExposureMode',
|
|
97
|
+
'deferredProviderMode',
|
|
98
|
+
'deferredNativeTools',
|
|
99
|
+
'deferredSurfaceMode',
|
|
100
|
+
'deferredToolUsage',
|
|
101
|
+
'deferredDefaultTools',
|
|
102
|
+
'deferredSelectedTools',
|
|
103
|
+
'deferredDiscoveredTools',
|
|
104
|
+
'deferredCallableTools',
|
|
105
|
+
'deferredAnnouncedTools',
|
|
106
|
+
'deferredToolDeltaRevision',
|
|
107
|
+
'nativeDeferredDiscovery',
|
|
108
|
+
'mcpServerInstructions',
|
|
109
|
+
];
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Agent (worker) sessions. Call right after their tools were resolved
|
|
113
|
+
* (create, resume, route change): on a bridge provider the eager surface
|
|
114
|
+
* becomes the full-mode core plus the bridge, built only from those
|
|
115
|
+
* role/policy-filtered tools; a native provider keeps the full array. A
|
|
116
|
+
* session honouring its own schema allowlist (a hidden specialist role) is
|
|
117
|
+
* already a small explicit surface and keeps it. `existing`: the session had
|
|
118
|
+
* a surface before, so a changed exposure is a migration.
|
|
119
|
+
*/
|
|
120
|
+
export function applyAgentToolExposure(session, { existing = false } = {}) {
|
|
121
|
+
if (!session || !Array.isArray(session.tools) || !isAgentOwner(session)) return false;
|
|
122
|
+
const before = sessionToolExposure(session);
|
|
123
|
+
const allowlisted = honoredSchemaAllowlist(session.schemaAllowedTools, { ownerIsAgent: true, agent: session.agent });
|
|
124
|
+
const bridge =
|
|
125
|
+
!allowlisted && toolExposureModeForProvider(session.provider, session.wireRoute) === TOOL_EXPOSURE_BRIDGE;
|
|
126
|
+
if (!bridge && before === null) return false;
|
|
127
|
+
// A surface an earlier bridge revision built is rebuilt now.
|
|
128
|
+
const outdated = bridgeSurfaceOutdated(session);
|
|
129
|
+
// The tools just resolved are the whole authority: no earlier catalog, MCP
|
|
130
|
+
// availability snapshot or pending MCP delta survives. (A bridge surface
|
|
131
|
+
// re-takes the snapshot at its next request boundary; a native agent has no
|
|
132
|
+
// refresh, so a stale snapshot would hide a connected server's tools.)
|
|
133
|
+
delete session.deferredToolCatalog;
|
|
134
|
+
delete session.deferredLateToolCatalog;
|
|
135
|
+
delete session.deferredMcpToolNames;
|
|
136
|
+
delete session.pendingDeferredToolDelta;
|
|
137
|
+
if (bridge) {
|
|
138
|
+
// The resolved list may be shared (prepared-resume cache): rebuild a copy.
|
|
139
|
+
session.tools = session.tools.slice();
|
|
140
|
+
applyDeferredToolSurface(session, 'full', [], { provider: session.provider, model: session.model });
|
|
141
|
+
} else {
|
|
142
|
+
for (const field of AGENT_BRIDGE_FIELDS) delete session[field];
|
|
143
|
+
// Without bridge state the fixed slot composes empty: the guidance goes.
|
|
144
|
+
if (Array.isArray(session.messages)) applyInitialDeferredToolManifestToBp2(session, [], { rebuild: true });
|
|
145
|
+
delete session.deferredToolBp2Applied;
|
|
146
|
+
}
|
|
147
|
+
const changed = before !== sessionToolExposure(session) || outdated;
|
|
148
|
+
if (existing && changed) markToolSurfaceMigrated(session);
|
|
149
|
+
return changed;
|
|
150
|
+
}
|
|
@@ -8,6 +8,7 @@ import { traceLoopPhaseTiming } from './diagnostics.mjs';
|
|
|
8
8
|
import { processToolBatch } from '../tool-batch.mjs';
|
|
9
9
|
import { CROSS_TURN_CAP, REPEAT_FAIL_LIMIT } from './loop-state.mjs';
|
|
10
10
|
import { markStepEffort } from './step-auto-effort.mjs';
|
|
11
|
+
import { resolveExecutionToolCalls } from './tool-call-resolution.mjs';
|
|
11
12
|
|
|
12
13
|
function isSleepLikeToolCall(call) {
|
|
13
14
|
const name = String(call?.name || call?.toolName || call?.function?.name || '').toLowerCase();
|
|
@@ -34,7 +35,9 @@ export async function runToolPhase(state, round, sent, onToolCall) {
|
|
|
34
35
|
}
|
|
35
36
|
// Per-turn batch shape — one row per assistant turn so trace consumers can
|
|
36
37
|
// derive the multi-tool adoption ratio without scanning message bodies.
|
|
37
|
-
|
|
38
|
+
// Audit records what runs: a bridged call_tool is recorded as its target.
|
|
39
|
+
// The wire calls stay the transcript identity (assistant turn below).
|
|
40
|
+
const toolBatchId = recordToolBatch(sessionId, resolveExecutionToolCalls(calls, sessionRef), state.iterations);
|
|
38
41
|
await Promise.resolve(onToolCall?.(state.iterations, calls));
|
|
39
42
|
const assistantTurnMsg = buildToolCallAssistantMessage(response, { calls, suppressMidTurnText, opts });
|
|
40
43
|
commitAssistantMessage(messages, assistantTurnMsg, opts);
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
resolveAutoEffort,
|
|
16
16
|
} from '../../providers/auto-effort.mjs';
|
|
17
17
|
import { builtinFeatureActive } from '../../runtime-core/builtin-features.mjs';
|
|
18
|
-
import { effortOptionsFor } from '../../runtime-core/effort.mjs';
|
|
18
|
+
import { effortOptionsFor, warnEmptyAutoEffortLadder } from '../../runtime-core/effort.mjs';
|
|
19
19
|
import { effortJudgeSupportsSteps, judgeTurn, recordEffortDecision } from '../../../../effort-judge/judge-client.mjs';
|
|
20
20
|
import { promptContentText } from './prompt-utils.mjs';
|
|
21
21
|
|
|
@@ -98,6 +98,7 @@ export async function resolveTurnAutoEffort({ sessionId, session, provider, inpu
|
|
|
98
98
|
// the judge is not asked (in observe mode too: nothing would be logged).
|
|
99
99
|
if (!autoEffortApplicable({ base, options })) {
|
|
100
100
|
recordEffortDecision({ ...record, skipped: 'default-outside-auto-range' });
|
|
101
|
+
warnEmptyAutoEffortLadder(session.provider, session.model, base);
|
|
101
102
|
return null;
|
|
102
103
|
}
|
|
103
104
|
// The previous user request shows the work a short follow-up continues.
|
|
@@ -120,22 +120,44 @@ function recordAgentRuntimeCall(session, result) {
|
|
|
120
120
|
export async function recordAskUsage({ session, result, askStartedAt, turnSignal }) {
|
|
121
121
|
const prefixHashForLog = recordAgentRuntimeCall(session, result);
|
|
122
122
|
if (!result.usage) return;
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
123
|
+
await logSessionLlmUsage({
|
|
124
|
+
session,
|
|
125
|
+
usage: result.usage,
|
|
126
|
+
startedAt: askStartedAt,
|
|
127
|
+
signal: turnSignal,
|
|
128
|
+
prefixHash: prefixHashForLog,
|
|
129
|
+
transportTiming: result.transportTiming || null,
|
|
130
|
+
});
|
|
131
|
+
recordStandaloneStatusTelemetry(session, result, Date.now() - askStartedAt);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/** The usage-ledger row of one provider call billed to `session`. `mode`
|
|
135
|
+
* labels a call made outside the turn loop (a /btw side question). */
|
|
136
|
+
export async function logSessionLlmUsage({
|
|
137
|
+
session,
|
|
138
|
+
usage,
|
|
139
|
+
startedAt,
|
|
140
|
+
signal = null,
|
|
141
|
+
prefixHash = null,
|
|
142
|
+
transportTiming = null,
|
|
143
|
+
mode = null,
|
|
144
|
+
}) {
|
|
145
|
+
const inputTokens = usage.inputTokens || 0;
|
|
146
|
+
const outputTokens = usage.outputTokens || 0;
|
|
147
|
+
const cacheReadTokens = usage.cachedTokens || 0;
|
|
148
|
+
const cacheWriteTokens = usage.cacheWriteTokens || 0;
|
|
127
149
|
// Unified total-prompt field. Anthropic = input+cache_read+cache_write
|
|
128
150
|
// (additive); OpenAI OAuth/API/Gemini = input_tokens already includes the
|
|
129
151
|
// cached portion (inclusive), so the fallback must not double-count.
|
|
130
152
|
const { isInclusiveProvider, computeCostUsd } = await runAbortable(
|
|
131
|
-
|
|
153
|
+
signal,
|
|
132
154
|
() => import('../../../../shared/llm/cost.mjs')
|
|
133
155
|
);
|
|
134
156
|
const inclusive = isInclusiveProvider(session.provider);
|
|
135
157
|
let promptTokens = inputTokens + cacheReadTokens + cacheWriteTokens;
|
|
136
|
-
if (typeof
|
|
158
|
+
if (typeof usage.promptTokens === 'number') promptTokens = usage.promptTokens;
|
|
137
159
|
else if (inclusive) promptTokens = Math.max(inputTokens, cacheReadTokens + cacheWriteTokens);
|
|
138
|
-
let costUsd =
|
|
160
|
+
let costUsd = usage.costUsd || 0;
|
|
139
161
|
if (!costUsd) {
|
|
140
162
|
try {
|
|
141
163
|
costUsd = computeCostUsd({
|
|
@@ -145,7 +167,7 @@ export async function recordAskUsage({ session, result, askStartedAt, turnSignal
|
|
|
145
167
|
outputTokens,
|
|
146
168
|
cacheReadTokens,
|
|
147
169
|
cacheWriteTokens,
|
|
148
|
-
cacheWrite1hTokens:
|
|
170
|
+
cacheWrite1hTokens: usage.cacheWrite1hTokens || 0,
|
|
149
171
|
});
|
|
150
172
|
} catch {
|
|
151
173
|
/* best-effort */
|
|
@@ -158,7 +180,8 @@ export async function recordAskUsage({ session, result, askStartedAt, turnSignal
|
|
|
158
180
|
preset: session.presetName || null,
|
|
159
181
|
model: session.model,
|
|
160
182
|
provider: session.provider,
|
|
161
|
-
|
|
183
|
+
...(mode ? { mode } : {}),
|
|
184
|
+
duration: Date.now() - startedAt,
|
|
162
185
|
profileId: session.profileId || null,
|
|
163
186
|
sessionId: session.id,
|
|
164
187
|
inputTokens,
|
|
@@ -166,11 +189,10 @@ export async function recordAskUsage({ session, result, askStartedAt, turnSignal
|
|
|
166
189
|
cacheReadTokens,
|
|
167
190
|
cacheWriteTokens,
|
|
168
191
|
promptTokens,
|
|
169
|
-
prefixHash
|
|
192
|
+
prefixHash,
|
|
170
193
|
costUsd,
|
|
171
|
-
transportTiming
|
|
194
|
+
transportTiming,
|
|
172
195
|
});
|
|
173
|
-
recordStandaloneStatusTelemetry(session, result, Date.now() - askStartedAt);
|
|
174
196
|
}
|
|
175
197
|
|
|
176
198
|
/** Persist opaque providerState for stateful providers. The update bit
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
// (runAskAgentLoop). Provider-not-available and trim failures throw here so
|
|
6
6
|
// the caller marks the session errored instead of leaving stage='connecting'.
|
|
7
7
|
import { getProvider } from '../../providers/registry.mjs';
|
|
8
|
+
import { pinSessionWireRoute } from '../../providers/wire-route.mjs';
|
|
8
9
|
import { notifySkillsApplied, prepareExplicitSkills, recordAppliedSkills } from '../explicit-skills.mjs';
|
|
9
10
|
import { prepareTurnEffortConfiguration } from '../../providers/effort-configuration.mjs';
|
|
10
11
|
import { resolveTurnAutoEffort, turnStepAutoEffort } from './ask-turn-auto-effort.mjs';
|
|
@@ -17,6 +18,7 @@ import { applyTurnContextMeta, buildUserTurn, startProviderPrewarm, traceTurnCon
|
|
|
17
18
|
import { rewindUnansweredPrompt } from './failed-turn-rewind.mjs';
|
|
18
19
|
import { buildAgentLoopOptions, trackedToolCallHook } from './ask-turn-loop-options.mjs';
|
|
19
20
|
import { _api_call_with_interrupt } from './ask-call-interrupt.mjs';
|
|
21
|
+
import { backfillFallbackSessionTitle } from './session-fallback-title.mjs';
|
|
20
22
|
|
|
21
23
|
/** Resolves the provider, builds the user turn and pre-commits it; returns
|
|
22
24
|
* what the loop and the commit need from this preparation. */
|
|
@@ -27,6 +29,10 @@ export async function prepareAskTurn({ sessionId, opened, input, cwdOverride, tr
|
|
|
27
29
|
// Register the live session object for synchronous close snapshots.
|
|
28
30
|
runtime.session = session;
|
|
29
31
|
if (!provider) throw new Error(`Provider "${session.provider}" not available`);
|
|
32
|
+
// The session's wire is pinned before its first request (an existing
|
|
33
|
+
// session keeps the wire it started on); read from the history as the turn
|
|
34
|
+
// found it, awaited with the user turn below.
|
|
35
|
+
const wireRoutePending = pinSessionWireRoute(session, provider);
|
|
30
36
|
// The turn-level judgment runs while the rest of the turn is prepared; it
|
|
31
37
|
// reads the session as the turn found it (synchronously, on this call).
|
|
32
38
|
// The first request still carries its decision: it is awaited below,
|
|
@@ -65,6 +71,7 @@ export async function prepareAskTurn({ sessionId, opened, input, cwdOverride, tr
|
|
|
65
71
|
turnPromptSource: input.promptSource,
|
|
66
72
|
effortConfiguration: null,
|
|
67
73
|
}),
|
|
74
|
+
wireRoutePending,
|
|
68
75
|
]);
|
|
69
76
|
const turnEffort = autoEffort?.applied ? autoEffort.effort : session.effort || null;
|
|
70
77
|
const effortConfiguration = prepareTurnEffortConfiguration(
|
|
@@ -107,6 +114,14 @@ export async function prepareAskTurn({ sessionId, opened, input, cwdOverride, tr
|
|
|
107
114
|
// user turn is introduced.
|
|
108
115
|
session.messages = filterModelVisibleSessionMessages(outgoing);
|
|
109
116
|
session.liveTurnMessages = outgoing;
|
|
117
|
+
// Name a titleless session from its first human prompt before the first
|
|
118
|
+
// save, so the title outlives any later compaction of the transcript. The
|
|
119
|
+
// earliest human turn already in the history wins; this turn's prompt is the
|
|
120
|
+
// fallback (runtime-injected turns carrying a promptSource never name it).
|
|
121
|
+
backfillFallbackSessionTitle(session, [
|
|
122
|
+
...historyMessages,
|
|
123
|
+
...(input.promptSource ? [] : [{ role: 'user', content: input.prompt }]),
|
|
124
|
+
]);
|
|
110
125
|
session.activeTurnCheckpoint = {
|
|
111
126
|
version: 1,
|
|
112
127
|
turnToken,
|
|
@@ -147,6 +162,7 @@ export async function prepareAskTurn({ sessionId, opened, input, cwdOverride, tr
|
|
|
147
162
|
beforeCount: historyMessages.length + 1,
|
|
148
163
|
deferredToolDelta: userTurn.deferredToolDelta,
|
|
149
164
|
goalReminder: userTurn.goalReminder,
|
|
165
|
+
workspaceNotice: userTurn.workspaceNotice,
|
|
150
166
|
};
|
|
151
167
|
}
|
|
152
168
|
|
|
@@ -18,6 +18,53 @@ const relay = (fn, ...args) => {
|
|
|
18
18
|
}
|
|
19
19
|
};
|
|
20
20
|
|
|
21
|
+
/**
|
|
22
|
+
* The callback-free send options that shape a turn's provider request (effort,
|
|
23
|
+
* model parameters, cache routing, continuation state, Codex wire identity and
|
|
24
|
+
* the session's provider cache settings). agentLoop's options spread them, and
|
|
25
|
+
* a /btw request built before any turn has run uses them as they are.
|
|
26
|
+
*/
|
|
27
|
+
export function buildRequestSendOptions({
|
|
28
|
+
sessionId,
|
|
29
|
+
session,
|
|
30
|
+
turnEffort,
|
|
31
|
+
effortConfiguration,
|
|
32
|
+
stepAutoEffort,
|
|
33
|
+
codexTurnId,
|
|
34
|
+
startedAtMs,
|
|
35
|
+
signal,
|
|
36
|
+
}) {
|
|
37
|
+
return {
|
|
38
|
+
effort: turnEffort,
|
|
39
|
+
effortConfiguration,
|
|
40
|
+
// { request, base } when each tool-result step is judged (step-auto-effort.mjs).
|
|
41
|
+
stepAutoEffort: stepAutoEffort || null,
|
|
42
|
+
fast: session.fast === true,
|
|
43
|
+
modelParameters: session.modelParameters || {},
|
|
44
|
+
selectedContextWindow: session.selectedContextWindow || session.contextWindow || null,
|
|
45
|
+
sessionId,
|
|
46
|
+
// Same projection compaction uses, so a session presents one identity on
|
|
47
|
+
// every request it makes.
|
|
48
|
+
...(codexWireSendOpts(session, { turnId: codexTurnId, startedAtMs }) || {}),
|
|
49
|
+
promptCacheKey: session.promptCacheKey || sessionId,
|
|
50
|
+
// Provider-scoped cache key (mixdog-codex, mixdog-claude…). Distinct
|
|
51
|
+
// from sessionId — providers that pool sockets per-session (openai-oauth
|
|
52
|
+
// WS) use sessionId as the pool bucket and providerCacheKey as the
|
|
53
|
+
// server-side prompt-cache shard so parallel callers don't collide on a
|
|
54
|
+
// mid-turn socket while still sharing prefix cache.
|
|
55
|
+
providerCacheKey: session.promptCacheKey || null,
|
|
56
|
+
signal,
|
|
57
|
+
providerState: session.providerState ?? undefined,
|
|
58
|
+
// The wire this session is pinned to (wire-route.mjs).
|
|
59
|
+
wireRoute: session.wireRoute ?? undefined,
|
|
60
|
+
session,
|
|
61
|
+
// Agent Runtime cache settings — merged last so session overrides don't
|
|
62
|
+
// get overridden by defaults. When session has no profile,
|
|
63
|
+
// providerCacheOpts is null and this spread is a no-op.
|
|
64
|
+
...(session.providerCacheOpts || {}),
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
|
|
21
68
|
/**
|
|
22
69
|
* @param {object} input
|
|
23
70
|
* @param {string} input.sessionId
|
|
@@ -49,14 +96,6 @@ export function buildAgentLoopOptions({
|
|
|
49
96
|
// (ask-turn-steering-drain.mjs).
|
|
50
97
|
const drainSteering = createAskSteeringDrain({ sessionId, turn, askOpts });
|
|
51
98
|
return {
|
|
52
|
-
effort: turnEffort,
|
|
53
|
-
effortConfiguration,
|
|
54
|
-
// { request, base } when each tool-result step is judged (step-auto-effort.mjs).
|
|
55
|
-
stepAutoEffort: stepAutoEffort || null,
|
|
56
|
-
fast: session.fast === true,
|
|
57
|
-
modelParameters: session.modelParameters || {},
|
|
58
|
-
selectedContextWindow: session.selectedContextWindow || session.contextWindow || null,
|
|
59
|
-
sessionId,
|
|
60
99
|
onTextDelta: (chunk) => {
|
|
61
100
|
interruption.recordTextDelta(chunk);
|
|
62
101
|
checkpoint.schedule();
|
|
@@ -157,23 +196,16 @@ export function buildAgentLoopOptions({
|
|
|
157
196
|
relay(askOpts?.onSkillsApplied, names, detail);
|
|
158
197
|
},
|
|
159
198
|
notifyFn: optionalFn(askOpts?.notifyFn),
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
signal,
|
|
171
|
-
providerState: session.providerState ?? undefined,
|
|
172
|
-
session,
|
|
173
|
-
// Agent Runtime cache settings — merged last so session overrides don't
|
|
174
|
-
// get overridden by defaults. When session has no profile,
|
|
175
|
-
// providerCacheOpts is null and this spread is a no-op.
|
|
176
|
-
...(session.providerCacheOpts || {}),
|
|
199
|
+
...buildRequestSendOptions({
|
|
200
|
+
sessionId,
|
|
201
|
+
session,
|
|
202
|
+
turnEffort,
|
|
203
|
+
effortConfiguration,
|
|
204
|
+
stepAutoEffort,
|
|
205
|
+
codexTurnId,
|
|
206
|
+
startedAtMs,
|
|
207
|
+
signal,
|
|
208
|
+
}),
|
|
177
209
|
onStageChange: (stage, detail) => {
|
|
178
210
|
updateSessionStage(sessionId, stage);
|
|
179
211
|
relay(askOpts?.onStageChange, stage, detail);
|
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
prefixUserTurnContent,
|
|
17
17
|
suffixUserTurnReminders,
|
|
18
18
|
buildCurrentTimeBlock,
|
|
19
|
+
snapshotPendingWorkspaceNotice,
|
|
19
20
|
} from './prompt-utils.mjs';
|
|
20
21
|
import { codexWireSendOpts } from './session-id.mjs';
|
|
21
22
|
import { _tryBridgeExplicitPrefetch } from './prefetch-bridge.mjs';
|
|
@@ -173,7 +174,11 @@ export async function buildUserTurn({
|
|
|
173
174
|
// input intake: either can precede the previous turn's pause.
|
|
174
175
|
// This supplies context only; it never resumes the Goal.
|
|
175
176
|
const goalReminder = snapshotPendingGoalReminder(session, { includePaused: true });
|
|
177
|
+
// A mid-conversation working-folder change: the system prompt keeps its
|
|
178
|
+
// old root (cache intact) and the new folder's facts ride this turn.
|
|
179
|
+
const workspaceNotice = snapshotPendingWorkspaceNotice(session);
|
|
176
180
|
const reminderBlock = [
|
|
181
|
+
workspaceNotice?.content || '',
|
|
177
182
|
currentTimeBlock ? `<system-reminder>\n# Current Time\n${currentTimeBlock}\n</system-reminder>` : '',
|
|
178
183
|
deferredToolDelta?.content || '',
|
|
179
184
|
goalReminder?.content || '',
|
|
@@ -200,6 +205,7 @@ export async function buildUserTurn({
|
|
|
200
205
|
historyMessages,
|
|
201
206
|
deferredToolDelta,
|
|
202
207
|
goalReminder,
|
|
208
|
+
workspaceNotice,
|
|
203
209
|
userTurnMessage,
|
|
204
210
|
outgoing: [...historyMessages, userTurnMessage],
|
|
205
211
|
};
|
|
@@ -8,6 +8,7 @@ import { ingestSessionTurn } from '../../../../session-search/session-search-ing
|
|
|
8
8
|
import { persistedAssistantTranscriptMetadata } from '../../../../shared/transcript-metadata.mjs';
|
|
9
9
|
import { acknowledgePendingDeferredToolDelta } from '../../runtime-core/deferred-tool-delta.mjs';
|
|
10
10
|
import { acknowledgePendingGoalReminder } from '../../runtime-core/goal-reminder.mjs';
|
|
11
|
+
import { acknowledgePendingWorkspaceNotice } from './prompt-utils.mjs';
|
|
11
12
|
import {
|
|
12
13
|
finalizePendingMessageDelivery,
|
|
13
14
|
drainPendingMessages,
|
|
@@ -121,6 +122,9 @@ export async function commitAskTurn({ sessionId, opened, prepared, result, rawTr
|
|
|
121
122
|
if (prepared.goalReminder) {
|
|
122
123
|
acknowledgePendingGoalReminder(session, prepared.goalReminder.revision);
|
|
123
124
|
}
|
|
125
|
+
if (prepared.workspaceNotice) {
|
|
126
|
+
acknowledgePendingWorkspaceNotice(session, prepared.workspaceNotice.revision);
|
|
127
|
+
}
|
|
124
128
|
return {
|
|
125
129
|
...result,
|
|
126
130
|
trimmed: messagesDropped > 0,
|
|
@@ -21,7 +21,9 @@ import { uncachedInputTokensForProvider } from './usage-metrics.mjs';
|
|
|
21
21
|
import { pruneOffloadSession } from '../tool-result-offload.mjs';
|
|
22
22
|
import { _getPendingMessagesForSession } from './pending-messages.mjs';
|
|
23
23
|
import { isSessionCompactionBlocked } from './runtime-liveness.mjs';
|
|
24
|
+
import { backfillFallbackSessionTitle } from './session-fallback-title.mjs';
|
|
24
25
|
import { resetReadStateAfterCompaction } from '../read-dedup.mjs';
|
|
26
|
+
import { applyPendingWorkspaceReroot } from './prompt-utils.mjs';
|
|
25
27
|
import {
|
|
26
28
|
compactTargetBudget as compactTargetBudgetForPolicy,
|
|
27
29
|
compactDisplayBeforeTokens,
|
|
@@ -629,7 +631,13 @@ async function commitSessionCompaction(plan, run, compactStartedAt) {
|
|
|
629
631
|
let unchangedReason = null;
|
|
630
632
|
if (!changed) unchangedReason = force ? 'nothing to compact' : 'below threshold';
|
|
631
633
|
const now = Date.now();
|
|
634
|
+
// Older titleless sessions: keep a name before the transcript that carries
|
|
635
|
+
// the first prompt is replaced.
|
|
636
|
+
if (changed) backfillFallbackSessionTitle(session, messages);
|
|
632
637
|
session.messages = transcript;
|
|
638
|
+
// The compacted transcript breaks the cache anyway: a staged working-folder
|
|
639
|
+
// change re-roots the system prompt now and needs no notice any more.
|
|
640
|
+
if (changed) applyPendingWorkspaceReroot(session);
|
|
633
641
|
if (changed) resetReadStateAfterCompaction(resolvedSessionId);
|
|
634
642
|
await pruneCompactedOffloads(session, resolvedSessionId);
|
|
635
643
|
if (changed) session.providerState = undefined;
|