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
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
// Versioned tool exposure. deferredProviderMode classifies the provider
|
|
2
|
+
// (native tool search or not); toolExposureMode records how the session's
|
|
3
|
+
// tools reach the model. Non-native providers use the fixed bridge: a small
|
|
4
|
+
// eager core plus the shared load_tool and call_tool, with every other tool
|
|
5
|
+
// only in the session's scoped catalog. Native sessions carry no field.
|
|
6
|
+
import { deferredProviderMode } from './tool-catalog-schema.mjs';
|
|
7
|
+
import { TOOL_SEARCH_TOOL } from './tool-defs.mjs';
|
|
8
|
+
|
|
9
|
+
export const TOOL_EXPOSURE_BRIDGE = 'bridge-v1';
|
|
10
|
+
export const TOOL_EXPOSURE_NATIVE = 'native';
|
|
11
|
+
export const TOOL_SURFACE_MIGRATION_INTENT = 'tool_surface_bridge_migration';
|
|
12
|
+
|
|
13
|
+
const BRIDGE_PROVIDER_MODES = new Set(['canonical', 'manifest']);
|
|
14
|
+
// call_tool, and the retired search_tools an older bridge surface carried.
|
|
15
|
+
const BRIDGE_ONLY_TOOL_NAMES = new Set(['search_tools', 'call_tool']);
|
|
16
|
+
// load_tool definitions earlier bridge surfaces carried: the describe-only
|
|
17
|
+
// bridge loader, and the shared loader with query/cursor inputs.
|
|
18
|
+
const LEGACY_BRIDGE_LOAD_TOOL_DESCRIPTIONS = new Set([
|
|
19
|
+
'Describe tools by exact name: description, input schema and annotations, or the part one JSON Pointer selects. Large definitions arrive in chunks; pass nextCursor back for the rest. Describing never enables a tool.',
|
|
20
|
+
'Load full schemas for missing deferred tool names/aliases; batch needed names in one call. Or find tools by keyword with query. Pass nextCursor back for the next page.',
|
|
21
|
+
]);
|
|
22
|
+
const SHARED_LOAD_TOOL_SCHEMA = JSON.stringify(TOOL_SEARCH_TOOL.inputSchema);
|
|
23
|
+
|
|
24
|
+
/** `route`: the session's pinned wire route (session.wireRoute), when one exists. */
|
|
25
|
+
export function toolExposureModeForProvider(provider, route = null) {
|
|
26
|
+
return BRIDGE_PROVIDER_MODES.has(deferredProviderMode(provider, route)) ? TOOL_EXPOSURE_BRIDGE : TOOL_EXPOSURE_NATIVE;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function isToolBridgeEnabled(session) {
|
|
30
|
+
return session?.toolExposureMode === TOOL_EXPOSURE_BRIDGE;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* The exposure a session's persisted surface was built with, or null before
|
|
35
|
+
* it has one. Surfaces persisted before exposure versions: native providers
|
|
36
|
+
* were already native; fixed-surface providers carried the whole catalog.
|
|
37
|
+
*/
|
|
38
|
+
export function sessionToolExposure(session) {
|
|
39
|
+
if (session?.toolExposureMode) return session.toolExposureMode;
|
|
40
|
+
if (!session?.deferredProviderMode) return null;
|
|
41
|
+
return session.deferredProviderMode === 'native' ? TOOL_EXPOSURE_NATIVE : 'legacy-fixed';
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* True when an existing surface was built for another exposure than
|
|
46
|
+
* `provider` needs, or is a bridge surface an earlier bridge revision built
|
|
47
|
+
* (bridgeSurfaceOutdated).
|
|
48
|
+
*/
|
|
49
|
+
export function toolExposureMigrationNeeded(session, provider = session?.provider) {
|
|
50
|
+
const current = sessionToolExposure(session);
|
|
51
|
+
if (current === null) return false;
|
|
52
|
+
const target = toolExposureModeForProvider(provider, session?.wireRoute);
|
|
53
|
+
return current !== target || (target === TOOL_EXPOSURE_BRIDGE && bridgeSurfaceOutdated(session));
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* A bridge session an earlier bridge revision built: its fixed prompt holds
|
|
58
|
+
* other bridge guidance than the current one (the guidance-only block, or
|
|
59
|
+
* guidance naming search_tools or query), or its eager surface still carries
|
|
60
|
+
* search_tools or a load_tool other than the shared one.
|
|
61
|
+
*/
|
|
62
|
+
export function bridgeSurfaceOutdated(session) {
|
|
63
|
+
if (!isToolBridgeEnabled(session)) return false;
|
|
64
|
+
const tools = Array.isArray(session.tools) ? session.tools : [];
|
|
65
|
+
const staleTool = tools.some(
|
|
66
|
+
(tool) =>
|
|
67
|
+
tool?.name === 'search_tools' ||
|
|
68
|
+
(tool?.name === TOOL_SEARCH_TOOL.name &&
|
|
69
|
+
(tool.description !== TOOL_SEARCH_TOOL.description ||
|
|
70
|
+
JSON.stringify(tool.inputSchema) !== SHARED_LOAD_TOOL_SCHEMA))
|
|
71
|
+
);
|
|
72
|
+
if (staleTool) return true;
|
|
73
|
+
return (Array.isArray(session.messages) ? session.messages : []).some(
|
|
74
|
+
(message) =>
|
|
75
|
+
message?.role === 'system' &&
|
|
76
|
+
typeof message.content === 'string' &&
|
|
77
|
+
message.content.includes('<tool-bridge>') &&
|
|
78
|
+
!message.content.includes(TOOL_BRIDGE_GUIDANCE)
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/** A bridge-only definition (never part of the scoped catalog). */
|
|
83
|
+
export function isBridgeToolDefinition(tool) {
|
|
84
|
+
const name = String(tool?.name || '');
|
|
85
|
+
if (BRIDGE_ONLY_TOOL_NAMES.has(name)) return true;
|
|
86
|
+
return name === TOOL_SEARCH_TOOL.name && LEGACY_BRIDGE_LOAD_TOOL_DESCRIPTIONS.has(tool?.description);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Static and byte-stable; it follows the deferred roster (the same
|
|
90
|
+
// <available-deferred-tools> block native sessions get), never replaces it.
|
|
91
|
+
// A prompt holding any other bridge guidance is migrated once.
|
|
92
|
+
export const TOOL_BRIDGE_GUIDANCE = [
|
|
93
|
+
'<tool-bridge>',
|
|
94
|
+
'Deferred tools (listed above, or announced later as added) are not defined here: run one with call_tool {name, arguments}, and use load_tool first to see its parameters (a keyword instead of a name searches the deferred tools). Call directly defined tools directly.',
|
|
95
|
+
'</tool-bridge>',
|
|
96
|
+
].join('\n');
|
|
@@ -11,7 +11,7 @@ import { createHash } from 'node:crypto';
|
|
|
11
11
|
|
|
12
12
|
/** Bumped whenever the table layout or a codec changes: the DB is then
|
|
13
13
|
* dropped and backfilled again from the JSON catalog. */
|
|
14
|
-
export const SCHEMA_VERSION =
|
|
14
|
+
export const SCHEMA_VERSION = 5;
|
|
15
15
|
/** PRAGMA application_id ('MXSC'): a file without it is not this catalog. */
|
|
16
16
|
export const APPLICATION_ID = 0x4d585343;
|
|
17
17
|
|
|
@@ -59,6 +59,8 @@ const FIELDS = [
|
|
|
59
59
|
['importKey', 'import_key', 'loose'],
|
|
60
60
|
// Source session of an inherited (forked) session (schema 4).
|
|
61
61
|
['inheritedFromSessionId', 'inherited_from_session_id', 'loose'],
|
|
62
|
+
// Real human turns (null for a row written before schema 5).
|
|
63
|
+
['realTurnCount', 'real_turn_count', 'loose'],
|
|
62
64
|
];
|
|
63
65
|
|
|
64
66
|
const COLUMN_TYPES = { text: 'TEXT', real: 'REAL', int: 'INTEGER', bool: 'INTEGER', json: 'TEXT', optjson: 'TEXT' };
|
|
@@ -15,8 +15,9 @@ export {
|
|
|
15
15
|
compactionBufferTokensForBoundary,
|
|
16
16
|
};
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
import { SUMMARY_PREFIX_ANCHOR } from './summary-anchor.mjs';
|
|
19
|
+
|
|
20
|
+
export { SUMMARY_PREFIX_ANCHOR };
|
|
20
21
|
export const SUMMARY_PREFIX = `${SUMMARY_PREFIX_ANCHOR} Build on the work already done and avoid duplicating it. The summary covers the session; retained requests and execution records follow it. Actual tool outcomes take precedence over plans or older claims in the summary.`;
|
|
21
22
|
export const SUMMARY_OUTPUT_TOKENS = 4_096;
|
|
22
23
|
// Longest a handoff summary call may run: the default, the config fallback,
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
// Message classification, protected-context splitting, and summary-message
|
|
2
2
|
// construction helpers.
|
|
3
|
-
import { SUMMARY_PREFIX
|
|
3
|
+
import { SUMMARY_PREFIX } from './constants.mjs';
|
|
4
4
|
import { sha16, roleCounts } from './text-utils.mjs';
|
|
5
5
|
import { carryMessageId, withoutMessageIdsReplacer } from '../message-ids.mjs';
|
|
6
|
-
import { isImportedMessage } from '../imported-message.mjs';
|
|
7
6
|
import {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
isActualUserInstructionMessage,
|
|
8
|
+
isInjectedSkillBodyMessage,
|
|
9
|
+
isProtectedContextUserMessage,
|
|
10
|
+
isSummaryMessage,
|
|
11
|
+
} from './user-message-kind.mjs';
|
|
11
12
|
|
|
12
13
|
export function compactHeader(oldHistory) {
|
|
13
14
|
// Stable display ids are bookkeeping, not conversation: the header names
|
|
@@ -23,94 +24,14 @@ export function makeSummaryMessage(content) {
|
|
|
23
24
|
return { role: 'user', content, meta: { source: 'compact-summary' } };
|
|
24
25
|
}
|
|
25
26
|
|
|
26
|
-
//
|
|
27
|
-
//
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
!isImportedMessage(m) &&
|
|
35
|
-
(String(m?.meta?.source || '') === 'compact-summary' ||
|
|
36
|
-
(typeof m.content === 'string' &&
|
|
37
|
-
m.content.startsWith(SUMMARY_PREFIX_ANCHOR) &&
|
|
38
|
-
/\nmessages=\d+\s+(?:sha256=|compact_type=)/.test(m.content)))
|
|
39
|
-
);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export function isProtectedContextUserMessage(m) {
|
|
43
|
-
if (m?.role !== 'user' || typeof m.content !== 'string' || isImportedMessage(m)) return false;
|
|
44
|
-
let content = m.content.trim();
|
|
45
|
-
if (!content.toLowerCase().startsWith('<system-reminder>')) return false;
|
|
46
|
-
const closingTag = '</system-reminder>';
|
|
47
|
-
// A runtime turn may carry several reminders (Goal, clock, tool delta).
|
|
48
|
-
// Only text outside those envelopes is a human instruction. Keep this
|
|
49
|
-
// compatible with stored turns that predate explicit source metadata.
|
|
50
|
-
while (content.toLowerCase().startsWith('<system-reminder>')) {
|
|
51
|
-
const closingIndex = content.toLowerCase().indexOf(closingTag);
|
|
52
|
-
if (closingIndex < 0) return true;
|
|
53
|
-
content = content.slice(closingIndex + closingTag.length).trim();
|
|
54
|
-
}
|
|
55
|
-
return content === '';
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
// An injected Skill-body user message (the general newMessages channel carries
|
|
59
|
-
// the full SKILL.md body as a role:'user' message after the Skill tool_result).
|
|
60
|
-
// Like isSummaryMessage / isProtectedContextUserMessage, it is detected by
|
|
61
|
-
// content prefix (the `<skill>` envelope from buildSkillResultEnvelope) so the
|
|
62
|
-
// check survives even if the synthetic `meta` field is dropped during a tail
|
|
63
|
-
// rebuild. It is NOT the human's latest prompt and must be excluded from
|
|
64
|
-
// "latest human request" selection (deriveCurrentRequest). The `meta:'skill'`
|
|
65
|
-
// marker is also honoured.
|
|
66
|
-
export function isInjectedSkillBodyMessage(m) {
|
|
67
|
-
if (m?.role !== 'user' || isImportedMessage(m)) return false;
|
|
68
|
-
if (m.meta === 'skill') return true;
|
|
69
|
-
return typeof m.content === 'string' && m.content.trimStart().startsWith('<skill>');
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
const SYNTHETIC_USER_SOURCES = new Set([
|
|
73
|
-
'goal-continuation',
|
|
74
|
-
'goal-closeout',
|
|
75
|
-
'compact-context',
|
|
76
|
-
'compact-active-turn-continuation',
|
|
77
|
-
'compact-execution-recovery',
|
|
78
|
-
'max-output-recovery',
|
|
79
|
-
'refusal-recovery',
|
|
80
|
-
'stream-cut-recovery',
|
|
81
|
-
]);
|
|
82
|
-
const SYNTHETIC_USER_CONTROL_RE =
|
|
83
|
-
/^(?:\[mixdog-runtime\]|\[request interrupted(?: by user(?: for tool use)?| by process restart)?\])(?:\s|$)/i;
|
|
84
|
-
|
|
85
|
-
function userMessageText(message) {
|
|
86
|
-
if (typeof message?.content === 'string') return message.content;
|
|
87
|
-
if (!Array.isArray(message?.content)) return '';
|
|
88
|
-
return message.content.map((block) => (typeof block === 'string' ? block : block?.text || '')).join('');
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
export function isActualUserInstructionMessage(message) {
|
|
92
|
-
if (
|
|
93
|
-
message?.role !== 'user' ||
|
|
94
|
-
isSummaryMessage(message) ||
|
|
95
|
-
isProtectedContextUserMessage(message) ||
|
|
96
|
-
isInjectedSkillBodyMessage(message)
|
|
97
|
-
) {
|
|
98
|
-
return false;
|
|
99
|
-
}
|
|
100
|
-
const text = userMessageText(message);
|
|
101
|
-
// Imported prose is the user's own words whatever it looks like.
|
|
102
|
-
if (isImportedMessage(message)) return text.trim().length > 0;
|
|
103
|
-
if (/^Reference files:\s*/i.test(text.trimStart())) return false;
|
|
104
|
-
if (
|
|
105
|
-
SYNTHETIC_USER_CONTROL_RE.test(text.trimStart()) ||
|
|
106
|
-
isInternalRuntimeNotificationText(text) ||
|
|
107
|
-
isModelVisibleToolCompletionWrapper(text) ||
|
|
108
|
-
SYNTHETIC_USER_SOURCES.has(String(message?.meta?.source || ''))
|
|
109
|
-
) {
|
|
110
|
-
return false;
|
|
111
|
-
}
|
|
112
|
-
return text.trim().length > 0 || (Array.isArray(message.content) && message.content.length > 0);
|
|
113
|
-
}
|
|
27
|
+
// User-message classification lives in the import-light user-message-kind.mjs
|
|
28
|
+
// (the session store counts real turns with it); re-exported for callers.
|
|
29
|
+
export {
|
|
30
|
+
isActualUserInstructionMessage,
|
|
31
|
+
isInjectedSkillBodyMessage,
|
|
32
|
+
isProtectedContextUserMessage,
|
|
33
|
+
isSummaryMessage,
|
|
34
|
+
};
|
|
114
35
|
|
|
115
36
|
export function latestActualUserInstructionIndex(messages) {
|
|
116
37
|
for (let index = (Array.isArray(messages) ? messages.length : 0) - 1; index >= 0; index -= 1) {
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
// Leaf constant: the anchor sentence every compact summary message opens with.
|
|
2
|
+
// Kept import-free so store-layer code can classify messages without pulling
|
|
3
|
+
// the context-utils graph (which cycles back into the session store).
|
|
4
|
+
export const SUMMARY_PREFIX_ANCHOR =
|
|
5
|
+
'A previous model worked on this task and produced the compacted handoff summary below.';
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
// Classification of role:'user' messages: the human's own instruction versus
|
|
2
|
+
// compact summaries and runtime-injected turns. Import-light on purpose (no
|
|
3
|
+
// context-utils graph) so the session store can count real human turns;
|
|
4
|
+
// compact/messages.mjs re-exports everything here.
|
|
5
|
+
import { SUMMARY_PREFIX_ANCHOR } from './summary-anchor.mjs';
|
|
6
|
+
import { isImportedMessage } from '../imported-message.mjs';
|
|
7
|
+
import {
|
|
8
|
+
isInternalRuntimeNotificationText,
|
|
9
|
+
isModelVisibleToolCompletionWrapper,
|
|
10
|
+
} from '../../../../shared/tool-execution-contract.mjs';
|
|
11
|
+
|
|
12
|
+
// A compact summary message is a synthetic role:'user' message carrying the
|
|
13
|
+
// SUMMARY_PREFIX anchor. It is NOT a real user turn: it must be excluded from
|
|
14
|
+
// real user-turn boundary calculations and treated as merge input, otherwise
|
|
15
|
+
// an old summary can sit in the preserved tail as a live user message,
|
|
16
|
+
// duplicate, or fail to merge across repeated compaction.
|
|
17
|
+
export function isSummaryMessage(m) {
|
|
18
|
+
return (
|
|
19
|
+
m?.role === 'user' &&
|
|
20
|
+
!isImportedMessage(m) &&
|
|
21
|
+
(String(m?.meta?.source || '') === 'compact-summary' ||
|
|
22
|
+
(typeof m.content === 'string' &&
|
|
23
|
+
m.content.startsWith(SUMMARY_PREFIX_ANCHOR) &&
|
|
24
|
+
/\nmessages=\d+\s+(?:sha256=|compact_type=)/.test(m.content)))
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function isProtectedContextUserMessage(m) {
|
|
29
|
+
if (m?.role !== 'user' || typeof m.content !== 'string' || isImportedMessage(m)) return false;
|
|
30
|
+
let content = m.content.trim();
|
|
31
|
+
if (!content.toLowerCase().startsWith('<system-reminder>')) return false;
|
|
32
|
+
const closingTag = '</system-reminder>';
|
|
33
|
+
// A runtime turn may carry several reminders (Goal, clock, tool delta).
|
|
34
|
+
// Only text outside those envelopes is a human instruction. Keep this
|
|
35
|
+
// compatible with stored turns that predate explicit source metadata.
|
|
36
|
+
while (content.toLowerCase().startsWith('<system-reminder>')) {
|
|
37
|
+
const closingIndex = content.toLowerCase().indexOf(closingTag);
|
|
38
|
+
if (closingIndex < 0) return true;
|
|
39
|
+
content = content.slice(closingIndex + closingTag.length).trim();
|
|
40
|
+
}
|
|
41
|
+
return content === '';
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// An injected Skill-body user message (the general newMessages channel carries
|
|
45
|
+
// the full SKILL.md body as a role:'user' message after the Skill tool_result).
|
|
46
|
+
// Like isSummaryMessage / isProtectedContextUserMessage, it is detected by
|
|
47
|
+
// content prefix (the `<skill>` envelope from buildSkillResultEnvelope) so the
|
|
48
|
+
// check survives even if the synthetic `meta` field is dropped during a tail
|
|
49
|
+
// rebuild. It is NOT the human's latest prompt and must be excluded from
|
|
50
|
+
// "latest human request" selection (deriveCurrentRequest). The `meta:'skill'`
|
|
51
|
+
// marker is also honoured.
|
|
52
|
+
export function isInjectedSkillBodyMessage(m) {
|
|
53
|
+
if (m?.role !== 'user' || isImportedMessage(m)) return false;
|
|
54
|
+
if (m.meta === 'skill') return true;
|
|
55
|
+
return typeof m.content === 'string' && m.content.trimStart().startsWith('<skill>');
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const SYNTHETIC_USER_SOURCES = new Set([
|
|
59
|
+
'goal-continuation',
|
|
60
|
+
'goal-closeout',
|
|
61
|
+
'compact-context',
|
|
62
|
+
'compact-active-turn-continuation',
|
|
63
|
+
'compact-execution-recovery',
|
|
64
|
+
'max-output-recovery',
|
|
65
|
+
'refusal-recovery',
|
|
66
|
+
'stream-cut-recovery',
|
|
67
|
+
]);
|
|
68
|
+
const SYNTHETIC_USER_CONTROL_RE =
|
|
69
|
+
/^(?:\[mixdog-runtime\]|\[request interrupted(?: by user(?: for tool use)?| by process restart)?\])(?:\s|$)/i;
|
|
70
|
+
|
|
71
|
+
function userMessageText(message) {
|
|
72
|
+
if (typeof message?.content === 'string') return message.content;
|
|
73
|
+
if (!Array.isArray(message?.content)) return '';
|
|
74
|
+
return message.content.map((block) => (typeof block === 'string' ? block : block?.text || '')).join('');
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export function isActualUserInstructionMessage(message) {
|
|
78
|
+
if (
|
|
79
|
+
message?.role !== 'user' ||
|
|
80
|
+
isSummaryMessage(message) ||
|
|
81
|
+
isProtectedContextUserMessage(message) ||
|
|
82
|
+
isInjectedSkillBodyMessage(message)
|
|
83
|
+
) {
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
const text = userMessageText(message);
|
|
87
|
+
// Imported prose is the user's own words whatever it looks like.
|
|
88
|
+
if (isImportedMessage(message)) return text.trim().length > 0;
|
|
89
|
+
if (/^Reference files:\s*/i.test(text.trimStart())) return false;
|
|
90
|
+
if (
|
|
91
|
+
SYNTHETIC_USER_CONTROL_RE.test(text.trimStart()) ||
|
|
92
|
+
isInternalRuntimeNotificationText(text) ||
|
|
93
|
+
isModelVisibleToolCompletionWrapper(text) ||
|
|
94
|
+
SYNTHETIC_USER_SOURCES.has(String(message?.meta?.source || ''))
|
|
95
|
+
) {
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
return text.trim().length > 0 || (Array.isArray(message.content) && message.content.length > 0);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Control rows the runtime writes as user turns when a turn is cut short.
|
|
102
|
+
// isActualUserInstructionMessage deliberately keeps treating "[truncated]" as
|
|
103
|
+
// an instruction (compaction tail selection depends on it), so the real-turn
|
|
104
|
+
// predicate below recognizes it on its own.
|
|
105
|
+
const CONTROL_MARKER_RE = /^\[(?:truncated|request interrupted(?: by user(?: for tool use)?| by process restart)?)\]$/i;
|
|
106
|
+
|
|
107
|
+
/** Whether a message stands for real human conversation: a compact summary
|
|
108
|
+
* (it replaced earlier human turns), imported prose, or the user's own
|
|
109
|
+
* instruction without runtime provenance (`meta.source`/`meta.synthetic`,
|
|
110
|
+
* `internal`/`synthetic` flags) or a recognized control marker. Used to tell
|
|
111
|
+
* a real conversation from a synthetic-only transcript in catalog rows. */
|
|
112
|
+
export function isRealTurnMessage(message) {
|
|
113
|
+
if (isSummaryMessage(message)) return true;
|
|
114
|
+
if (!isActualUserInstructionMessage(message)) return false;
|
|
115
|
+
if (isImportedMessage(message)) return true;
|
|
116
|
+
if (message.internal === true || message.synthetic === true) return false;
|
|
117
|
+
const meta = message.meta;
|
|
118
|
+
if (meta && typeof meta === 'object' && (meta.synthetic === true || meta.source)) return false;
|
|
119
|
+
return !CONTROL_MARKER_RE.test(userMessageText(message).trim());
|
|
120
|
+
}
|
|
@@ -8,6 +8,13 @@ import {
|
|
|
8
8
|
} from '../runtime-core/provider-request-tools.mjs';
|
|
9
9
|
|
|
10
10
|
const toolSchemaAnalysisMemo = new WeakMap();
|
|
11
|
+
// Token cost by schema signature. Every new session builds its own tools array
|
|
12
|
+
// with the same schemas; re-estimating the whole serialization (tens of ms,
|
|
13
|
+
// synchronous) per first turn blocked the event loop during session creation.
|
|
14
|
+
// The signature hashes the full serialization, deferred flags included, so it
|
|
15
|
+
// determines the metered text exactly.
|
|
16
|
+
const toolSchemaTokensBySignature = new Map();
|
|
17
|
+
const TOOL_SCHEMA_TOKENS_LIMIT = 32;
|
|
11
18
|
|
|
12
19
|
function isDeferredToolSchema(tool) {
|
|
13
20
|
return tool?.deferLoading === true || tool?.defer_loading === true;
|
|
@@ -58,8 +65,16 @@ function analyzeToolSchemas(tools) {
|
|
|
58
65
|
// full weight inflated the request reserve. The SIGNATURE keeps hashing
|
|
59
66
|
// the full serialization (a deferred tool joining/leaving must still
|
|
60
67
|
// re-fingerprint the surface); only the token cost drops deferred entries.
|
|
61
|
-
|
|
62
|
-
|
|
68
|
+
let tokens = toolSchemaTokensBySignature.get(signature);
|
|
69
|
+
if (tokens === undefined) {
|
|
70
|
+
const meterText = list.some(isDeferredToolSchema) ? serializeToolSchemas(list, { excludeDeferred: true }) : text;
|
|
71
|
+
tokens = estimateTokens(meterText);
|
|
72
|
+
if (toolSchemaTokensBySignature.size >= TOOL_SCHEMA_TOKENS_LIMIT) {
|
|
73
|
+
toolSchemaTokensBySignature.delete(toolSchemaTokensBySignature.keys().next().value);
|
|
74
|
+
}
|
|
75
|
+
toolSchemaTokensBySignature.set(signature, tokens);
|
|
76
|
+
}
|
|
77
|
+
const analysis = { signature, tokens };
|
|
63
78
|
if (Array.isArray(tools)) toolSchemaAnalysisMemo.set(tools, analysis);
|
|
64
79
|
return analysis;
|
|
65
80
|
}
|
|
@@ -225,10 +225,14 @@ function messageTextTokens(m, precomputedText = null, precomputedReplay = null)
|
|
|
225
225
|
m?.role === 'assistant' && Array.isArray(m.providerReplay?.items) && m.providerReplay.items.length
|
|
226
226
|
? m.providerReplay.items
|
|
227
227
|
: null;
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
228
|
+
if (!replayItems) return estimateTokens(text);
|
|
229
|
+
// With visible replay items the text is exactly `${base}\n${replay}`. Meter
|
|
230
|
+
// each half on its own: the estimator's minimum-cost floors apply to the
|
|
231
|
+
// joined string, so subtracting est(replay) from est(base + replay)
|
|
232
|
+
// overstates base.
|
|
233
|
+
const replay = precomputedReplay ?? nativeBlocksEstimateText(replayItems);
|
|
234
|
+
const base = text.slice(0, text.length - replay.length - 1);
|
|
235
|
+
return Math.max(estimateTokens(base), estimateTokens(replay));
|
|
232
236
|
}
|
|
233
237
|
function imageDescriptorAllowance(descriptor) {
|
|
234
238
|
if (descriptor.width && descriptor.height) {
|
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
} from '../loop/tool-classify.mjs';
|
|
13
13
|
import { isSingleCallPerTurnTool, isToolCallDedupEligible } from '../loop/tool-helpers.mjs';
|
|
14
14
|
import { lookupToolResultReuse } from '../cache/tool-result-reuse.mjs';
|
|
15
|
+
import { bridgeClassificationTools } from '../loop/tool-call-resolution.mjs';
|
|
15
16
|
|
|
16
17
|
export function createEagerAdmission({ tools, cwd, sessionId, sessionRef, repeatFailLimit }) {
|
|
17
18
|
// Streaming-time intra-turn dedup. When the LLM emits two
|
|
@@ -63,7 +64,7 @@ export function createEagerAdmission({ tools, cwd, sessionId, sessionRef, repeat
|
|
|
63
64
|
// Authorization precedes cache lookup and dedup, not just IO.
|
|
64
65
|
if (preDispatchDenyForSession(sessionRef, call) !== null) return null;
|
|
65
66
|
const sig = _intraTurnSig(call.name, call.arguments);
|
|
66
|
-
const dedupEligible = isToolCallDedupEligible(call.name, tools);
|
|
67
|
+
const dedupEligible = isToolCallDedupEligible(call.name, bridgeClassificationTools(tools, [call]));
|
|
67
68
|
if (dedupEligible && _eagerInFlightSigs.has(sig)) return null;
|
|
68
69
|
// Repeat-failure guard also gates eager dispatch (reviewer-flagged):
|
|
69
70
|
// streaming onToolCall / startEagerRun would otherwise re-run an
|
|
@@ -10,6 +10,7 @@ import { createEagerBarriers } from './eager-dispatch/barriers.mjs';
|
|
|
10
10
|
import { createEagerEntry, runEagerEntry } from './eager-dispatch/entry.mjs';
|
|
11
11
|
import { executeTool } from './loop/tool-exec.mjs';
|
|
12
12
|
import { isParallelDispatchable } from './loop/tool-helpers.mjs';
|
|
13
|
+
import { resolveExecutionToolCall } from './loop/tool-call-resolution.mjs';
|
|
13
14
|
|
|
14
15
|
export function createEagerDispatcher({
|
|
15
16
|
tools,
|
|
@@ -45,9 +46,13 @@ export function createEagerDispatcher({
|
|
|
45
46
|
iteration: getNextIteration(),
|
|
46
47
|
localSearchTelemetry: entry.localSearchTelemetry,
|
|
47
48
|
resultTelemetry: entry.resultTelemetry,
|
|
49
|
+
...(call.wireCall ? { bridgeWireCall: call.wireCall } : {}),
|
|
48
50
|
});
|
|
49
51
|
|
|
50
|
-
const startEagerTool = (
|
|
52
|
+
const startEagerTool = (wireCall) => {
|
|
53
|
+
// Streamed call_tool requests are admitted, ordered and executed as their
|
|
54
|
+
// targets; a projection error is answered by the serial batch instead.
|
|
55
|
+
const call = resolveExecutionToolCall(wireCall, sessionRef);
|
|
51
56
|
if (!call?.id || pending.has(call.id) || !isParallelDispatchable(call.name)) return null;
|
|
52
57
|
const admitted = admission.admit(call);
|
|
53
58
|
if (!admitted) return null;
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
contextMessagesSignature,
|
|
8
8
|
estimateMessagesTokens,
|
|
9
9
|
estimateRequestReserveTokens,
|
|
10
|
+
estimateToolSchemaTokens,
|
|
10
11
|
providerTokenCalibration,
|
|
11
12
|
resolveSessionCompactPolicy,
|
|
12
13
|
toolSchemaSignature,
|
|
@@ -18,6 +19,7 @@ import { positiveInt } from '../../../../shared/numbers.mjs';
|
|
|
18
19
|
import { isAgentOwner } from '../../agent-owner.mjs';
|
|
19
20
|
import { providerInputExcludesCache, providerNativePdf } from '../../providers/registry.mjs';
|
|
20
21
|
import { contentMediaBytes, contentMediaCount } from '../../providers/media-normalization.mjs';
|
|
22
|
+
import { splitProtectedContext } from '../compact/messages.mjs';
|
|
21
23
|
|
|
22
24
|
// Unified context-share rule (compact/constants.mjs CONTEXT_SHARE_RATIO): the
|
|
23
25
|
// post-compaction target is 25% of the boundary/context window. One
|
|
@@ -589,6 +591,95 @@ export function compactTargetBudget(policy) {
|
|
|
589
591
|
const singleShot = policy?.singleShot === true || (rawTrigger > 0 && reserve >= rawTrigger);
|
|
590
592
|
return compactTargetBudgetForTrigger(rawBoundary, rawTarget, reserve, rawTrigger, singleShot, policy?.force === true);
|
|
591
593
|
}
|
|
594
|
+
const OVERHEAD_TOP_TOOLS = 5;
|
|
595
|
+
|
|
596
|
+
/**
|
|
597
|
+
* The per-request overhead no compaction can shrink — the finalized wire tool
|
|
598
|
+
* schemas (policy.requestReserveTokens), the protected system/fixed prompt
|
|
599
|
+
* every compaction keeps verbatim, and the configured operator headroom — in
|
|
600
|
+
* the provider-scale units of the compact boundary (calibrated estimates, the
|
|
601
|
+
* configured headroom as configured). Only that fixed estimate can justify a
|
|
602
|
+
* refusal; a provider reading aligned to this prefix and these tool schemas
|
|
603
|
+
* can only withdraw one (it includes compactable history). Null unless the
|
|
604
|
+
* fixed part reaches the boundary: kind 'fixed_overhead' when schemas +
|
|
605
|
+
* system alone do, 'configured_reserve' when the configured headroom pushes
|
|
606
|
+
* the fixed part there.
|
|
607
|
+
*/
|
|
608
|
+
export function fixedRequestOverhead(policy, messages, tools, sessionRef = null) {
|
|
609
|
+
if (!policy?.auto) return null;
|
|
610
|
+
const boundary = positiveInt(policy.boundaryTokens);
|
|
611
|
+
if (!boundary) return null;
|
|
612
|
+
const calibration = policyTokenCalibration(policy);
|
|
613
|
+
const toProviderScale = (raw) => Math.ceil(Math.max(0, raw) * calibration);
|
|
614
|
+
const toolTokens = toProviderScale(policyRequestReserveTokens(policy));
|
|
615
|
+
const systemTokens = toProviderScale(
|
|
616
|
+
estimateMessagesTokens(splitProtectedContext(messages || []).protectedPrefix)
|
|
617
|
+
);
|
|
618
|
+
const configuredReserve = Math.max(0, Number(policy.configuredReserveTokens) || 0);
|
|
619
|
+
const fixed = toolTokens + systemTokens;
|
|
620
|
+
// A provider reading of this very prefix with these very tools measured
|
|
621
|
+
// the whole request, compactable history included: an upper bound of the
|
|
622
|
+
// fixed part, never proof of it. When it is not above the estimate, the
|
|
623
|
+
// estimate is known to overstate the fixed part by an unknown amount, so
|
|
624
|
+
// nothing here can show that compaction is futile.
|
|
625
|
+
const measuredRequestTokens = measuredFixedRequestTokens(sessionRef, messages, policy);
|
|
626
|
+
if (measuredRequestTokens !== null && measuredRequestTokens <= fixed) return null;
|
|
627
|
+
// Refuse only when the fixed part itself (plus the headroom, for the
|
|
628
|
+
// reserve kind) reaches the boundary — never on a near miss of a heuristic
|
|
629
|
+
// estimate: those requests compact or go out, and the provider's own
|
|
630
|
+
// overflow handling decides.
|
|
631
|
+
let kind = null;
|
|
632
|
+
if (fixed >= boundary) kind = 'fixed_overhead';
|
|
633
|
+
else if (configuredReserve > 0 && fixed + configuredReserve >= boundary) kind = 'configured_reserve';
|
|
634
|
+
if (!kind) return null;
|
|
635
|
+
const counted = (Array.isArray(tools) ? tools : []).filter(
|
|
636
|
+
(tool) => tool?.deferLoading !== true && tool?.defer_loading !== true
|
|
637
|
+
);
|
|
638
|
+
const largestTools = counted
|
|
639
|
+
.map((tool) => ({
|
|
640
|
+
name: String(tool?.name || tool?.type || 'tool'),
|
|
641
|
+
tokens: toProviderScale(estimateToolSchemaTokens([tool])),
|
|
642
|
+
}))
|
|
643
|
+
.sort((a, b) => b.tokens - a.tokens || a.name.localeCompare(b.name))
|
|
644
|
+
.slice(0, OVERHEAD_TOP_TOOLS);
|
|
645
|
+
return {
|
|
646
|
+
kind,
|
|
647
|
+
contextWindowTokens: positiveInt(policy.contextWindow) || boundary,
|
|
648
|
+
boundaryTokens: boundary,
|
|
649
|
+
toolCount: counted.length,
|
|
650
|
+
toolTokens,
|
|
651
|
+
systemTokens,
|
|
652
|
+
configuredReserveTokens: configuredReserve,
|
|
653
|
+
measuredRequestTokens,
|
|
654
|
+
largestTools,
|
|
655
|
+
};
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
/**
|
|
659
|
+
* Identity of the fixed inputs fixedRequestOverhead judges: the wire tool
|
|
660
|
+
* schemas, the protected system context, the configured headroom and the
|
|
661
|
+
* boundary. A verdict holds while this is unchanged; the provider reading is
|
|
662
|
+
* deliberately not part of it (compaction clears it, fixed overhead stays).
|
|
663
|
+
*/
|
|
664
|
+
export function fixedRequestOverheadInputs(policy, messages) {
|
|
665
|
+
if (!policy?.auto) return null;
|
|
666
|
+
return JSON.stringify([
|
|
667
|
+
policy.toolSchemaSignature || '',
|
|
668
|
+
contextMessagesSignature(splitProtectedContext(messages || []).protectedPrefix),
|
|
669
|
+
Math.max(0, Number(policy.configuredReserveTokens) || 0),
|
|
670
|
+
positiveInt(policy.boundaryTokens) || 0,
|
|
671
|
+
]);
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
// The provider-measured size of the last request when it still describes
|
|
675
|
+
// this transcript prefix and was sent with the same tool schemas; else null.
|
|
676
|
+
function measuredFixedRequestTokens(sessionRef, messages, policy) {
|
|
677
|
+
if (!sessionRef || !Array.isArray(messages)) return null;
|
|
678
|
+
const aligned = providerBaselineCoverage(sessionRef, messages);
|
|
679
|
+
if (!aligned || !aligned.toolSignature || aligned.toolSignature !== policy?.toolSchemaSignature) return null;
|
|
680
|
+
return aligned.tokens;
|
|
681
|
+
}
|
|
682
|
+
|
|
592
683
|
// Anthropic refuses a request body over 32 MB (HTTP 413) however few tokens it
|
|
593
684
|
// holds, and inline media is what gets there: an image is priced at no more
|
|
594
685
|
// than ~1.6k tokens yet carries up to 5 MB of base64. Tool-result media is the
|
|
@@ -707,7 +798,6 @@ function compactionTelemetryRecord(sessionRef, policy, meta, prev) {
|
|
|
707
798
|
return {
|
|
708
799
|
...prev,
|
|
709
800
|
auto: policy.auto !== false,
|
|
710
|
-
reservedTokens: policy.configuredReserveTokens || prev.reservedTokens || null,
|
|
711
801
|
requestReserveTokens: policy.requestReserveTokens || 0,
|
|
712
802
|
reserveTokens: policy.reserveTokens || 0,
|
|
713
803
|
boundaryTokens: policy.boundaryTokens || null,
|
|
@@ -37,7 +37,7 @@ export function crossTurnSignature(name, args) {
|
|
|
37
37
|
// they must not reset the escalation ladder's "zero edit" condition. Skill /
|
|
38
38
|
// recall / agent / task / cwd / load_tool are exploration/meta plumbing.
|
|
39
39
|
// (tool_search kept as legacy alias for old transcripts.)
|
|
40
|
-
const NON_PROGRESS_TOOLS = new Set(['Skill', 'recall', 'agent', 'task', 'cwd', 'load_tool', 'tool_search']);
|
|
40
|
+
const NON_PROGRESS_TOOLS = new Set(['Skill', 'recall', 'agent', 'task', 'cwd', 'session', 'load_tool', 'tool_search']);
|
|
41
41
|
|
|
42
42
|
// True when a successfully-executed tool represents real edit/progress. A tool
|
|
43
43
|
// counts as progress only if its def lacks readOnlyHint (not eager) AND it is
|