mixdog 1.3.5 → 1.4.1
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/NOTICE.md +2 -2
- package/README.md +2 -2
- package/package.json +2 -11
- package/scripts/check-voice-runtime-inputs.mjs +25 -0
- package/scripts/daemon-stub.mjs +1 -1
- package/scripts/gate-local.mjs +16 -5
- package/scripts/latest-guard.mjs +21 -9
- package/scripts/lib/isolated-test-env.mjs +10 -5
- package/scripts/lib/run-node-tests.mjs +37 -37
- package/scripts/lib/scoped-temp.d.mts +16 -0
- package/scripts/lib/scoped-temp.mjs +123 -0
- package/scripts/lib/stale-temp.mjs +44 -0
- package/scripts/native-release-status.mjs +2 -2
- package/scripts/post-release-check.mjs +1 -6
- package/scripts/pptx-kit-index.mjs +17 -4
- package/scripts/recall-history-cases.json +1 -1
- package/scripts/suite-health.mjs +20 -2
- package/scripts/test-data-dir.mjs +10 -7
- package/scripts/test.mjs +7 -11
- package/src/agents/reviewer/AGENT.md +7 -11
- package/src/agents/reviewer/agent.json +1 -1
- package/src/app.mjs +4 -0
- package/src/defaults/shipped-history.json +22 -1
- package/src/defaults/skills/browser-use/SKILL.md +62 -12
- package/src/defaults/skills/code-tidy/SKILL.md +142 -270
- package/src/defaults/skills/code-tidy/references/agent-cleanup.md +4 -4
- package/src/defaults/skills/code-tidy/references/cleanup-report.md +31 -76
- package/src/defaults/skills/code-tidy/references/dead-code.md +6 -12
- package/src/defaults/skills/computer-use/SKILL.md +35 -9
- package/src/defaults/skills/setup/SKILL.md +22 -0
- package/src/defaults/skills/setup/references/actions.md +39 -5
- package/src/defaults/skills/setup/references/surfaces.md +11 -2
- package/src/defaults/skills/visualize/SKILL.md +2 -1
- package/src/lib/rules-builder.cjs +39 -20
- package/src/output-styles/common.md +2 -2
- package/src/output-styles/simple.md +1 -1
- package/src/rules/agent/AGENT.md +11 -10
- package/src/rules/lead/LEAD.md +23 -20
- package/src/rules/shared/05-tool-calls.md +5 -6
- package/src/rules/shared/10-tool-workflow.md +4 -0
- package/src/rules/shared/45-destructive.md +0 -2
- package/src/rules/shared/50-execution.md +2 -0
- package/src/rules/shared/60-verification.md +7 -5
- package/src/rules/shared/70-delivery.md +7 -9
- package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +29 -6
- package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +2 -3
- package/src/runtime/agent/orchestrator/agent-runtime/title-completion.mjs +3 -1
- package/src/runtime/agent/orchestrator/agent-trace-format.mjs +3 -1
- package/src/runtime/agent/orchestrator/cache-break-trace.mjs +2 -0
- package/src/runtime/agent/orchestrator/config.mjs +17 -1
- package/src/runtime/agent/orchestrator/context/collect.mjs +3 -0
- package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +73 -68
- package/src/runtime/agent/orchestrator/context/skill-catalog.mjs +57 -2
- package/src/runtime/agent/orchestrator/mcp/agent-connectors.mjs +3 -3
- package/src/runtime/agent/orchestrator/mcp/client-transport.mjs +176 -72
- package/src/runtime/agent/orchestrator/mcp/client.mjs +19 -0
- package/src/runtime/agent/orchestrator/mcp/oauth-login.mjs +5 -2
- package/src/runtime/agent/orchestrator/providers/account-pool.mjs +192 -133
- package/src/runtime/agent/orchestrator/providers/admission-scheduler.mjs +42 -6
- package/src/runtime/agent/orchestrator/providers/anthropic-api-recovery.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-api-request.mjs +7 -3
- package/src/runtime/agent/orchestrator/providers/anthropic-api-transport.mjs +8 -2
- package/src/runtime/agent/orchestrator/providers/anthropic-cache-warm.mjs +165 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-max-tokens-recovery.mjs +6 -2
- package/src/runtime/agent/orchestrator/providers/anthropic-messages.mjs +2 -2
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-credentials.mjs +4 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-request/gzip-post.mjs +14 -14
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-request/initial-status.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +159 -69
- package/src/runtime/agent/orchestrator/providers/anthropic-overload-fallback.mjs +25 -3
- package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +70 -33
- package/src/runtime/agent/orchestrator/providers/anthropic-turn-result.mjs +2 -2
- package/src/runtime/agent/orchestrator/providers/anthropic.mjs +135 -87
- package/src/runtime/agent/orchestrator/providers/antigravity-transport.mjs +123 -102
- package/src/runtime/agent/orchestrator/providers/cache-warm-admission.mjs +90 -0
- package/src/runtime/agent/orchestrator/providers/command-code-oauth-login.mjs +1 -10
- package/src/runtime/agent/orchestrator/providers/cursor-wire-transport.mjs +25 -9
- package/src/runtime/agent/orchestrator/providers/cursor.mjs +25 -13
- package/src/runtime/agent/orchestrator/providers/devin-wire-transport.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/devin.mjs +3 -0
- package/src/runtime/agent/orchestrator/providers/grok-oauth-login.mjs +210 -20
- package/src/runtime/agent/orchestrator/providers/lib/anthropic-prefix-trace.mjs +76 -11
- package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +45 -6
- package/src/runtime/agent/orchestrator/providers/lib/first-output-window.mjs +58 -0
- package/src/runtime/agent/orchestrator/providers/lib/listen-on.mjs +14 -0
- package/src/runtime/agent/orchestrator/providers/lib/oauth-token-utils.mjs +17 -3
- package/src/runtime/agent/orchestrator/providers/media-normalization.mjs +52 -10
- package/src/runtime/agent/orchestrator/providers/mimo-oauth-login.mjs +1 -10
- package/src/runtime/agent/orchestrator/providers/model-proxy-channel.d.mts +8 -1
- package/src/runtime/agent/orchestrator/providers/model-proxy-channel.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/npm-cli-version.mjs +11 -3
- package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +2 -1
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-send.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/chunk-events.mjs +9 -2
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-state.mjs +7 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream.mjs +14 -3
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses-events.mjs +4 -2
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-stream-common.mjs +5 -3
- package/src/runtime/agent/orchestrator/providers/openai-compat-stream.mjs +16 -3
- package/src/runtime/agent/orchestrator/providers/openai-compat-xai-send.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events/output-items.mjs +5 -2
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events.mjs +13 -3
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state.mjs +13 -2
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-watchdogs.mjs +81 -42
- package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +8 -0
- package/src/runtime/agent/orchestrator/providers/openai-oauth-login.mjs +136 -5
- package/src/runtime/agent/orchestrator/providers/openai-oauth-tokens.mjs +10 -9
- package/src/runtime/agent/orchestrator/providers/openai-ws-send/send-context.mjs +22 -3
- package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/attempt-context.mjs +43 -5
- package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/handshake-failure.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/stream-failure.mjs +6 -3
- package/src/runtime/agent/orchestrator/providers/openai-ws-stream/event-switch.mjs +20 -12
- package/src/runtime/agent/orchestrator/providers/openai-ws-stream.mjs +7 -1
- package/src/runtime/agent/orchestrator/providers/openai-ws-watchdogs.mjs +48 -22
- package/src/runtime/agent/orchestrator/providers/provider-error-kind.mjs +65 -1
- package/src/runtime/agent/orchestrator/providers/quota-reading.mjs +38 -12
- package/src/runtime/agent/orchestrator/providers/registry.mjs +38 -0
- package/src/runtime/agent/orchestrator/providers/retry-executor.mjs +39 -7
- package/src/runtime/agent/orchestrator/providers/statusline-route-meta.mjs +6 -0
- package/src/runtime/agent/orchestrator/runtime-core/ask-user-tool-defs.mjs +49 -16
- package/src/runtime/agent/orchestrator/runtime-core/compaction-config-keys.mjs +62 -0
- package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +37 -16
- package/src/runtime/agent/orchestrator/runtime-core/deferred-tool-delta.mjs +100 -23
- package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +7 -6
- package/src/runtime/agent/orchestrator/runtime-core/session-text.mjs +9 -3
- package/src/runtime/agent/orchestrator/runtime-core/tool-bridge.mjs +19 -4
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +125 -30
- package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +3 -1
- package/src/runtime/agent/orchestrator/runtime-core/workflow.mjs +5 -2
- package/src/runtime/agent/orchestrator/session/cache/scoped-cache.mjs +1 -3
- package/src/runtime/agent/orchestrator/session/cache-warm.mjs +798 -0
- package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +4 -1
- package/src/runtime/agent/orchestrator/session/compact/execution-tail.mjs +1 -8
- package/src/runtime/agent/orchestrator/session/compact/messages.mjs +23 -0
- package/src/runtime/agent/orchestrator/session/compact/observation-supersession.mjs +103 -23
- package/src/runtime/agent/orchestrator/session/compact/runner.mjs +280 -45
- package/src/runtime/agent/orchestrator/session/compaction-archive-capture.mjs +475 -58
- package/src/runtime/agent/orchestrator/session/compaction-archive.mjs +42 -17
- package/src/runtime/agent/orchestrator/session/context-utils.mjs +13 -1
- package/src/runtime/agent/orchestrator/session/conversation-import/claude.mjs +163 -22
- package/src/runtime/agent/orchestrator/session/conversation-import/codex.mjs +132 -17
- package/src/runtime/agent/orchestrator/session/conversation-import/convert.mjs +38 -7
- package/src/runtime/agent/orchestrator/session/conversation-import/imported-session.mjs +3 -0
- package/src/runtime/agent/orchestrator/session/conversation-import/turns.mjs +90 -22
- package/src/runtime/agent/orchestrator/session/eager-dispatch.mjs +4 -1
- package/src/runtime/agent/orchestrator/session/human-gate/gate.mjs +11 -5
- package/src/runtime/agent/orchestrator/session/human-gate/outbound-policy.mjs +0 -2
- package/src/runtime/agent/orchestrator/session/human-gate/requests.mjs +36 -4
- package/src/runtime/agent/orchestrator/session/human-gate/store.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +51 -25
- package/src/runtime/agent/orchestrator/session/loop/fresh-context.mjs +37 -3
- package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +3 -1
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/provider-tool-exclusions.mjs +13 -5
- package/src/runtime/agent/orchestrator/session/loop/route-fallback.mjs +31 -3
- package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +20 -3
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/after-hook.mjs +2 -1
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +5 -4
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +16 -2
- package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +16 -1
- package/src/runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs +49 -21
- package/src/runtime/agent/orchestrator/session/loop/tool-helpers.mjs +3 -10
- package/src/runtime/agent/orchestrator/session/loop/tool-phase.mjs +12 -3
- package/src/runtime/agent/orchestrator/session/manager/ask-queue.mjs +12 -2
- package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +19 -1
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +133 -90
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-loop-options.mjs +3 -3
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +3 -1
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-state.mjs +31 -4
- package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +30 -18
- package/src/runtime/agent/orchestrator/session/manager/owner-route-fallbacks.mjs +24 -14
- package/src/runtime/agent/orchestrator/session/manager/pending-message-entry.mjs +11 -2
- package/src/runtime/agent/orchestrator/session/manager/provider-replay.mjs +13 -0
- package/src/runtime/agent/orchestrator/session/manager/route-fallback-chain.mjs +130 -0
- package/src/runtime/agent/orchestrator/session/manager/rules-cache.mjs +27 -9
- package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +81 -8
- package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +27 -8
- package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +12 -5
- package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +9 -4
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-context.mjs +4 -0
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-journal.mjs +102 -15
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint.mjs +21 -5
- package/src/runtime/agent/orchestrator/session/manager/turn-interruption.mjs +9 -0
- package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +24 -9
- package/src/runtime/agent/orchestrator/session/prompt-cache-idle-gaps.mjs +113 -0
- package/src/runtime/agent/orchestrator/session/prompt-cache-touch-store.mjs +150 -0
- package/src/runtime/agent/orchestrator/session/restart-prefix-parity.fixture.mjs +154 -0
- package/src/runtime/agent/orchestrator/session/routine-result.mjs +36 -9
- package/src/runtime/agent/orchestrator/session/sensitive-projection.mjs +100 -0
- package/src/runtime/agent/orchestrator/session/sensitive-values.mjs +257 -0
- package/src/runtime/agent/orchestrator/session/side-question-store.mjs +20 -7
- package/src/runtime/agent/orchestrator/session/side-question.mjs +18 -0
- package/src/runtime/agent/orchestrator/session/skill-update-notice.mjs +60 -0
- package/src/runtime/agent/orchestrator/session/store/live-state.mjs +6 -3
- package/src/runtime/agent/orchestrator/session/store/save-delta.mjs +9 -5
- package/src/runtime/agent/orchestrator/session/store/serialize.mjs +9 -8
- package/src/runtime/agent/orchestrator/session/store/session-delete.mjs +7 -0
- package/src/runtime/agent/orchestrator/session/store/session-persistence-events.mjs +29 -0
- package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +8 -6
- package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +16 -2
- package/src/runtime/agent/orchestrator/session/store-summary-fields.mjs +15 -0
- package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +81 -22
- package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +92 -3
- package/src/runtime/agent/orchestrator/session/stored-attachment-history.mjs +32 -0
- package/src/runtime/agent/orchestrator/session/thinking-binding.mjs +108 -0
- package/src/runtime/agent/orchestrator/session/tool-batch/pre-dispatch.mjs +2 -2
- package/src/runtime/agent/orchestrator/session/tool-batch/record-outcome.mjs +2 -1
- package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +79 -3
- package/src/runtime/agent/orchestrator/session/transcript-restore/tool-result-status.mjs +9 -7
- package/src/runtime/agent/orchestrator/session/transcript-restore/tool-result-text.mjs +2 -2
- package/src/runtime/agent/orchestrator/session/turn-failure.mjs +5 -1
- package/src/runtime/agent/orchestrator/stall-policy.mjs +23 -0
- package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +5 -2
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/backgrounded-result.mjs +12 -1
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/invocation-plan.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/misuse-guard.mjs +240 -0
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/result-format.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/shell-cwd.mjs +38 -0
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/spawn-env.mjs +4 -2
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +31 -6
- package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +110 -26
- package/src/runtime/agent/orchestrator/tools/builtin/cache-layers.mjs +7 -1
- package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +31 -5
- package/src/runtime/agent/orchestrator/tools/builtin/git-worktree-tool.mjs +22 -8
- package/src/runtime/agent/orchestrator/tools/builtin/lib/scoped-search-flight.mjs +9 -5
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-stream.mjs +7 -1
- package/src/runtime/agent/orchestrator/tools/builtin/read-streaming.mjs +6 -3
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-dispatch.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-publication.mjs +23 -12
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-snapshot.mjs +6 -1
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool.mjs +1 -8
- package/src/runtime/agent/orchestrator/tools/builtin/shell-runtime.mjs +7 -1
- package/src/runtime/agent/orchestrator/tools/code-graph/dispatch/federation.mjs +3 -1
- package/src/runtime/agent/orchestrator/tools/code-graph-tool-defs.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/graph-manifest.json +13 -13
- package/src/runtime/agent/orchestrator/tools/lib/isolated-test-env.mjs +4 -3
- package/src/runtime/agent/orchestrator/tools/lib/shell-warm-standby.mjs +26 -4
- package/src/runtime/agent/orchestrator/tools/shell-command.mjs +36 -13
- package/src/runtime/browser-bridge/action-schema.mjs +13 -2
- package/src/runtime/browser-bridge/client.mjs +73 -8
- package/src/runtime/browser-bridge/input-fields.mjs +8 -9
- package/src/runtime/browser-bridge/mail-links.mjs +107 -0
- package/src/runtime/browser-bridge/tool-defs.mjs +1 -1
- package/src/runtime/channels/lib/config.mjs +6 -61
- package/src/runtime/channels/lib/crash-log.mjs +1 -1
- package/src/runtime/channels/lib/event-pipeline.mjs +4 -19
- package/src/runtime/channels/lib/event-queue.mjs +3 -18
- package/src/runtime/channels/lib/owned-runtime/automation-services.mjs +2 -2
- package/src/runtime/channels/lib/owned-runtime/automation-start.mjs +3 -4
- package/src/runtime/channels/lib/owned-runtime/config-reload.mjs +4 -59
- package/src/runtime/channels/lib/owned-runtime/owned-start.mjs +33 -115
- package/src/runtime/channels/lib/owned-runtime/owned-stop.mjs +5 -22
- package/src/runtime/channels/lib/owned-runtime/state.mjs +2 -8
- package/src/runtime/channels/lib/owned-runtime.mjs +6 -23
- package/src/runtime/channels/lib/parent-bridge.mjs +2 -2
- package/src/runtime/channels/lib/runtime-paths.mjs +4 -43
- package/src/runtime/channels/lib/scheduler.mjs +33 -147
- package/src/runtime/channels/lib/schedules-db.mjs +34 -11
- package/src/runtime/channels/lib/status-snapshot.mjs +1 -1
- package/src/runtime/channels/lib/tool-dispatch.mjs +1 -2
- package/src/runtime/channels/lib/webhook/signature.mjs +4 -1
- package/src/runtime/channels/lib/webhooks-db.mjs +5 -9
- package/src/runtime/channels/lib/whisper-port.mjs +10 -1
- package/src/runtime/channels/lib/worker-bootstrap.mjs +0 -1
- package/src/runtime/channels/lib/worker-ipc.mjs +0 -1
- package/src/runtime/channels/lib/worker-main.mjs +10 -34
- package/src/runtime/computer-bridge/action-schema.mjs +42 -1
- package/src/runtime/computer-bridge/actions.mjs +9 -1
- package/src/runtime/computer-bridge/client.mjs +180 -8
- package/src/runtime/computer-bridge/core-actions.mjs +2 -2
- package/src/runtime/computer-bridge/error-recovery.mjs +28 -2
- package/src/runtime/computer-bridge/linux-action-capabilities.mjs +24 -5
- package/src/runtime/computer-bridge/linux-readiness.d.mts +7 -2
- package/src/runtime/computer-bridge/linux-readiness.mjs +65 -23
- package/src/runtime/computer-bridge/pending-continuation.mjs +1 -1
- package/src/runtime/connectors/connector-accounts-mcp.mjs +230 -0
- package/src/runtime/connectors/gmail-app-password.mjs +172 -39
- package/src/runtime/connectors/google-mcp.mjs +10 -12
- package/src/runtime/local-provider/server-process.mjs +2 -1
- package/src/runtime/media/adapters/gemini-video.mjs +4 -1
- package/src/runtime/media/adapters/xai-media.mjs +2 -1
- package/src/runtime/memory/lib/embedding-worker.mjs +6 -3
- package/src/runtime/memory/lib/memory-action-handlers/cycle-backfill-action.mjs +1 -7
- package/src/runtime/memory/lib/memory-chunk-quality.mjs +1 -6
- package/src/runtime/memory/lib/pg/adapter.mjs +77 -70
- package/src/runtime/memory/lib/pg/supervisor.mjs +24 -12
- package/src/runtime/memory/lib/runtime-fetcher.mjs +23 -5
- package/src/runtime/office/authoring/pdf-author-action.mjs +1 -6
- package/src/runtime/office/design/design-art-direction.mjs +29 -27
- package/src/runtime/office/pdf/pdf-writer.mjs +6 -1
- package/src/runtime/office/portable/portable-snapshot-docx.mjs +7 -1
- package/src/runtime/office/portable/portable-snapshot-shared.mjs +6 -1
- package/src/runtime/office/quality/assurance-rendered.mjs +9 -2
- package/src/runtime/office/quality/assurance-structure-docx.mjs +3 -1
- package/src/runtime/office/quality/design-review.mjs +1 -5
- package/src/runtime/office/quality/document-brief.mjs +1 -5
- package/src/runtime/office/quality/forced-break-pages.mjs +9 -6
- package/src/runtime/office/quality/quality-pipeline.mjs +1 -1
- package/src/runtime/session-search/session-search-db.mjs +73 -9
- package/src/runtime/session-search/session-search-ingest.mjs +110 -20
- package/src/runtime/shared/abort-race.mjs +89 -0
- package/src/runtime/shared/agent-avatar.d.mts +0 -1
- package/src/runtime/shared/agent-kind.mjs +4 -3
- package/src/runtime/shared/bot-owned-work.mjs +56 -0
- package/src/runtime/shared/bounded-download.mjs +8 -3
- package/src/runtime/shared/config.mjs +2 -13
- package/src/runtime/shared/connector-accounts.mjs +20 -10
- package/src/runtime/shared/connector-catalog.d.mts +29 -0
- package/src/runtime/shared/connector-catalog.mjs +150 -0
- package/src/runtime/shared/connector-triggers.mjs +22 -19
- package/src/runtime/shared/defaults-separation.mjs +2 -17
- package/src/runtime/shared/delegated-approval-host.mjs +103 -11
- package/src/runtime/shared/err-text.mjs +24 -15
- package/src/runtime/shared/fetch-safe-listen.d.mts +16 -0
- package/src/runtime/shared/fetch-safe-listen.mjs +50 -0
- package/src/runtime/shared/file-permissions.d.mts +0 -8
- package/src/runtime/shared/file-permissions.mjs +0 -11
- package/src/runtime/shared/git-direct.test-support.mjs +19 -0
- package/src/runtime/shared/handoff-artifacts.d.mts +2 -1
- package/src/runtime/shared/handoff-artifacts.mjs +18 -8
- package/src/runtime/shared/heartbeat-interval.d.mts +4 -0
- package/src/runtime/shared/heartbeat-interval.mjs +19 -0
- package/src/runtime/shared/idle-auto-clear-gate.mjs +126 -0
- package/src/runtime/shared/llm/cost.mjs +5 -1
- package/src/runtime/shared/llm/usage-rollup.mjs +1 -1
- package/src/runtime/shared/loopback-listener.mjs +25 -2
- package/src/runtime/shared/mixy-presence.mjs +22 -0
- package/src/runtime/shared/model-route-chain.d.mts +7 -2
- package/src/runtime/shared/model-route-chain.mjs +22 -4
- package/src/runtime/shared/open-url.mjs +10 -0
- package/src/runtime/shared/orchestration.d.mts +2 -0
- package/src/runtime/shared/pg-schema-db.mjs +27 -16
- package/src/runtime/shared/profile-config.cjs +1 -1
- package/src/runtime/shared/prompt-origin.d.mts +4 -0
- package/src/runtime/shared/prompt-origin.mjs +21 -0
- package/src/runtime/shared/provider-accounts.mjs +7 -1
- package/src/runtime/shared/provider-display-name.mjs +29 -0
- package/src/runtime/shared/provider-timeout-phase.mjs +2 -0
- package/src/runtime/shared/routine-trigger.d.mts +2 -0
- package/src/runtime/shared/routine-trigger.mjs +10 -0
- package/src/runtime/shared/sensitive-path-rules.d.mts +2 -10
- package/src/runtime/shared/sensitive-path-rules.mjs +19 -41
- package/src/runtime/shared/session-activity-signal.mjs +48 -1
- package/src/runtime/shared/session-scratch.mjs +37 -0
- package/src/runtime/shared/session-sidebar-host.d.mts +1 -1
- package/src/runtime/shared/session-sidebar-host.mjs +7 -3
- package/src/runtime/shared/session-turn-prelude.mjs +18 -0
- package/src/runtime/shared/tool-card-model/agent-surface.mjs +1 -3
- package/src/runtime/shared/tool-card-model/card-status.mjs +15 -2
- package/src/runtime/shared/tool-result-summary.mjs +2 -15
- package/src/runtime/shared/tool-surface.mjs +3 -0
- package/src/runtime/shared/tool-work-units.mjs +2 -0
- package/src/runtime/shared/turn-snapshot-store.mjs +13 -6
- package/src/runtime/shared/worktrees/contract.mjs +4 -1
- package/src/runtime/shared/worktrees/git.mjs +15 -0
- package/src/runtime/shared/worktrees/manager.mjs +87 -38
- package/src/runtime/shared/worktrees/test-support.mjs +14 -13
- package/src/runtime/terminal-bridge/client.mjs +10 -1
- package/src/runtime/visualize-bridge/client.mjs +29 -8
- package/src/runtime/visualize-bridge/tool-defs.mjs +22 -8
- package/src/runtime/visualize-bridge/tool-meta.d.mts +5 -0
- package/src/runtime/visualize-bridge/tool-meta.mjs +22 -0
- package/src/runtime/web-search/lib/fetch-pipeline.mjs +2 -2
- package/src/session-runtime/agent-home-delivery.mjs +489 -185
- package/src/session-runtime/agent-task-sessions.mjs +467 -229
- package/src/session-runtime/agent-tool-routing.mjs +8 -41
- package/src/session-runtime/boot/apis.mjs +9 -0
- package/src/session-runtime/boot/infrastructure.mjs +4 -0
- package/src/session-runtime/boot/providers.mjs +3 -0
- package/src/session-runtime/boot/tools.mjs +11 -2
- package/src/session-runtime/bot-status.mjs +12 -6
- package/src/session-runtime/bot-target.mjs +38 -0
- package/src/session-runtime/channel-config-api.mjs +6 -1
- package/src/session-runtime/config-lifecycle.mjs +6 -0
- package/src/session-runtime/connector-merge-migration.mjs +305 -0
- package/src/session-runtime/conversation-import/codex-titles.mjs +88 -0
- package/src/session-runtime/conversation-import/discovery.mjs +271 -25
- package/src/session-runtime/conversation-import/service.mjs +26 -5
- package/src/session-runtime/handoff-attachments.mjs +82 -31
- package/src/session-runtime/internal-tool-executor/ask-user-tool.mjs +144 -41
- package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +3 -0
- package/src/session-runtime/internal-tool-executor/reaction-tool.mjs +4 -1
- package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +8 -2
- package/src/session-runtime/lifecycle/cold-heir.mjs +11 -6
- package/src/session-runtime/lifecycle/inheritance.mjs +16 -3
- package/src/session-runtime/lifecycle/session-catalog.mjs +12 -2
- package/src/session-runtime/lifecycle/teardown/runtime-stops.mjs +50 -4
- package/src/session-runtime/lifecycle/teardown.mjs +23 -5
- package/src/session-runtime/mcp-glue/server-catalog.mjs +55 -3
- package/src/session-runtime/mcp-oauth-login.mjs +5 -3
- package/src/session-runtime/mixy-heartbeat.mjs +153 -33
- package/src/session-runtime/model-route/set-route.mjs +11 -2
- package/src/session-runtime/notification-bus.mjs +31 -117
- package/src/session-runtime/notification-completion-queue.mjs +54 -0
- package/src/session-runtime/notification-listeners.mjs +76 -0
- package/src/session-runtime/owned-automation-run.mjs +2 -1
- package/src/session-runtime/prewarm/channel-start.mjs +3 -7
- package/src/session-runtime/provider-catalog-cache.mjs +82 -36
- package/src/session-runtime/provider-models/catalog-load.mjs +23 -6
- package/src/session-runtime/provider-models.mjs +4 -2
- package/src/session-runtime/resource-mcp-api.mjs +143 -224
- package/src/session-runtime/resource-mcp-connector-accounts.mjs +163 -0
- package/src/session-runtime/resource-mcp-oauth-api.mjs +217 -0
- package/src/session-runtime/resource-mcp-secrets.mjs +82 -0
- package/src/session-runtime/resource-mcp-servers.mjs +78 -0
- package/src/session-runtime/resource-mcp-store.mjs +49 -0
- package/src/session-runtime/resource-recall-api.mjs +6 -1
- package/src/session-runtime/routine-owner.mjs +40 -9
- package/src/session-runtime/runtime-feature-gates.mjs +5 -1
- package/src/session-runtime/services/agent-tool/close-flow.mjs +3 -0
- package/src/session-runtime/services/agent-tool/execute.mjs +14 -9
- package/src/session-runtime/services/agent-tool/job-views/agent-list.mjs +20 -4
- package/src/session-runtime/services/agent-tool/model-select.mjs +48 -7
- package/src/session-runtime/services/agent-tool/render.mjs +71 -17
- package/src/session-runtime/services/agent-tool/spawn-preset.mjs +13 -4
- package/src/session-runtime/services/agent-tool/tag-registry.mjs +1 -0
- package/src/session-runtime/services/agent-tool/tool-def.mjs +9 -9
- package/src/session-runtime/services/agent-tool/worker-index/awaiting-user-sync.mjs +51 -0
- package/src/session-runtime/services/agent-tool/worker-index/disposal.mjs +55 -0
- package/src/session-runtime/services/agent-tool/worker-index/released-store.mjs +123 -0
- package/src/session-runtime/services/agent-tool/worker-index/restart-settlement.mjs +112 -0
- package/src/session-runtime/services/agent-tool/worker-index/row-reads.mjs +36 -0
- package/src/session-runtime/services/agent-tool/worker-index/row-shape.mjs +2 -0
- package/src/session-runtime/services/agent-tool/worker-index/row-store.mjs +17 -4
- package/src/session-runtime/services/agent-tool/worker-index/row-writes.mjs +58 -0
- package/src/session-runtime/services/agent-tool/worker-index.mjs +41 -241
- package/src/session-runtime/services/agent-tool/worker-rows.mjs +3 -0
- package/src/session-runtime/services/channel-admin.mjs +7 -13
- package/src/session-runtime/services/channel-session-router.mjs +4 -2
- package/src/session-runtime/services/provider-admin.mjs +2 -1
- package/src/session-runtime/services/seeds.mjs +0 -28
- package/src/session-runtime/session-compaction-sync.mjs +27 -0
- package/src/session-runtime/session-create/session-options.mjs +1 -0
- package/src/session-runtime/settings-builtin-tools-api.mjs +11 -0
- package/src/session-runtime/settings-compaction-api.mjs +2 -40
- package/src/session-runtime/settings-system-api.mjs +13 -1
- package/src/session-runtime/setup-tool/agent-settings-actions.mjs +65 -0
- package/src/session-runtime/setup-tool/executor.mjs +145 -22
- package/src/session-runtime/setup-tool/extended-actions.mjs +8 -3
- package/src/session-runtime/setup-tool/session-route-actions.mjs +152 -0
- package/src/session-runtime/setup-tool/settings-contract.mjs +4 -3
- package/src/session-runtime/setup-tool/tool-defs.mjs +64 -5
- package/src/session-runtime/tool-policy/agent-profile-fold.mjs +17 -13
- package/src/session-runtime/tool-policy/policy-stage.mjs +17 -2
- package/src/session-runtime/turn/turn-run/ask-callbacks.mjs +1 -0
- package/src/session-runtime/workflow-agents-api/agent-editor.mjs +5 -1
- package/src/session-runtime/workflow-agents-api/agent-route.mjs +15 -4
- package/src/session-runtime/workflow-agents-api/onboarding.mjs +3 -3
- package/src/session-runtime/workflow-agents-api/style-and-mode.mjs +4 -0
- package/src/session-runtime/workspace/transitions.mjs +25 -0
- package/src/session-runtime/workspace/worktree-tool.mjs +26 -9
- package/src/standalone/channel-transport/client-registry/client-records.mjs +65 -0
- package/src/standalone/channel-transport/client-registry/client-registration.mjs +118 -0
- package/src/standalone/channel-transport/client-registry.mjs +24 -163
- package/src/standalone/channel-transport.mjs +1 -1
- package/src/standalone/daemon-channels-loader.mjs +10 -8
- package/src/standalone/daemon-session-control/list-page.mjs +72 -0
- package/src/standalone/daemon-session-control/request.mjs +51 -0
- package/src/standalone/daemon-session-control/room-host.mjs +57 -0
- package/src/standalone/daemon-session-control/route-control.mjs +48 -0
- package/src/standalone/daemon-session-control/send-turn.mjs +60 -0
- package/src/standalone/daemon-session-control/worktree-control.mjs +40 -0
- package/src/standalone/daemon-session-control.mjs +142 -190
- package/src/standalone/daemon.mjs +26 -3
- package/src/standalone/session-client.mjs +7 -3
- package/src/standalone/session-protocol.mjs +5 -0
- package/src/standalone/session-service/agent-tree/agent-child.mjs +1 -0
- package/src/standalone/session-service/agent-tree/agent-turns.mjs +16 -12
- package/src/standalone/session-service/quota-resume.mjs +3 -0
- package/src/standalone/session-service/retention/busy.mjs +65 -1
- package/src/standalone/session-service/session-calls/session-action.mjs +30 -2
- package/src/standalone/session-service/session-calls/session-views.mjs +8 -0
- package/src/standalone/session-tool-output.mjs +15 -7
- package/src/standalone/session-transport/client-registry/client-grace.mjs +12 -9
- package/src/tui/app/app-view/floating-panel.jsx +7 -4
- package/src/tui/app/model-options.mjs +3 -28
- package/src/tui/app/model-picker/route-selection/fast-parameters.mjs +1 -3
- package/src/tui/app/model-picker/route-selection.mjs +5 -6
- package/src/tui/app/provider-setup/oauth-actions.mjs +38 -20
- package/src/tui/app/provider-setup/provider-items.mjs +8 -2
- package/src/tui/app/provider-setup-picker.mjs +9 -5
- package/src/tui/components/QuestionPanel.jsx +13 -4
- package/src/tui/dist/index.mjs +133 -92
- package/src/tui/session/agent-job-feed/model-notification.mjs +3 -0
- package/src/tui/session/initial-state.mjs +3 -0
- package/src/tui/session/notice-surface.mjs +7 -1
- package/src/tui/session/queue-helpers.mjs +3 -42
- package/src/tui/session/session-api/routes-agent-definitions.mjs +14 -2
- package/src/tui/session/session-api/routes-write.mjs +5 -1
- package/src/tui/session/session-api/routes.mjs +1 -0
- package/src/tui/session/session-api/settings.mjs +17 -1
- package/src/tui/session/session-flow/auto-clear.mjs +4 -33
- package/src/tui/session/session-flow/drain-closed-queue.mjs +38 -0
- package/src/tui/session/session-flow/drain-enqueue.mjs +86 -0
- package/src/tui/session/session-flow/drain-retry.mjs +35 -0
- package/src/tui/session/session-flow/drain.mjs +118 -149
- package/src/tui/session/session-flow/queue/entry-shape.mjs +5 -0
- package/src/tui/session/session-flow/queue/take-entries.mjs +16 -2
- package/src/tui/session/tool-approval-delegation.mjs +64 -0
- package/src/tui/session/tool-approval-request.mjs +39 -0
- package/src/tui/session/tool-approval-settle.mjs +62 -0
- package/src/tui/session/tool-approval.mjs +69 -115
- package/src/tui/session/tui-steering-persist.mjs +8 -1
- package/src/tui/session/turn-stream.mjs +19 -2
- package/src/tui/session/turn.mjs +1 -0
- package/src/ui/statusline-agents.mjs +1 -3
- package/src/vendor/statusline/bin/statusline-route.mjs +1 -219
- package/src/vendor/statusline/src/gateway/route-meta.mjs +35 -13
- package/scripts/code-graph-description-contract.mjs +0 -188
- package/src/runtime/channels/lib/owned-runtime/ownership-refresh.mjs +0 -36
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// Rule-based Compact preserves conversation verbatim by default. A bounded
|
|
2
2
|
// cumulative handoff replaces only the conversation part when requested by
|
|
3
3
|
// its independent threshold policy.
|
|
4
|
+
import { createHash } from 'node:crypto';
|
|
4
5
|
import { estimateMessagesTokens, reconcileDedupStubs, sanitizeToolPairs } from '../context-utils.mjs';
|
|
5
6
|
import { HANDOFF_TIMEOUT_MAX_MS, SUMMARY_OUTPUT_TOKENS, compactDebugLog } from './constants.mjs';
|
|
6
7
|
import {
|
|
@@ -11,6 +12,7 @@ import {
|
|
|
11
12
|
textByteLength,
|
|
12
13
|
} from './text-utils.mjs';
|
|
13
14
|
import {
|
|
15
|
+
callArguments,
|
|
14
16
|
contextAckMessage,
|
|
15
17
|
isCompactConversationRow,
|
|
16
18
|
isProtectedContextAckMessage,
|
|
@@ -22,8 +24,9 @@ import {
|
|
|
22
24
|
} from './messages.mjs';
|
|
23
25
|
import { activeTurnContinuationMessage } from './continuation.mjs';
|
|
24
26
|
import { EXECUTION_RECOVERY_SOURCE, buildExecutionTail } from './execution-tail.mjs';
|
|
25
|
-
import { latestSkillBodies } from '../../context/skill-state.mjs';
|
|
27
|
+
import { latestSkillBodies, skillMessageText } from '../../context/skill-state.mjs';
|
|
26
28
|
import { effectiveBudget } from './budget.mjs';
|
|
29
|
+
import { parseMcpToolName } from '../../../../shared/tool-primitives.mjs';
|
|
27
30
|
import { stripRuntimeUserContext, withRuntimeUserContext } from '../runtime-user-context.mjs';
|
|
28
31
|
import { carryMessageId, messageIdOf } from '../message-ids.mjs';
|
|
29
32
|
import { normalizeIngestRole, shouldExcludeIngestMessage } from '../../../../memory/lib/session-ingest.mjs';
|
|
@@ -69,12 +72,23 @@ function splitFreshSource(messages) {
|
|
|
69
72
|
break;
|
|
70
73
|
}
|
|
71
74
|
}
|
|
75
|
+
// Where the previous Compact's skill-use window opens: `live` index after
|
|
76
|
+
// the history it kept (see SKILL_WINDOW_SOURCE). Without a marker the whole
|
|
77
|
+
// transcript is the window.
|
|
78
|
+
const isKept = (message) => !isSummaryMessage(message) && message?.meta?.source !== SKILL_WINDOW_SOURCE;
|
|
79
|
+
const markerAt = conversation.findLastIndex((message) => message?.meta?.source === SKILL_WINDOW_SOURCE);
|
|
80
|
+
const span = conversation[markerAt]?.meta?.span;
|
|
81
|
+
const skillWindowStart =
|
|
82
|
+
markerAt >= 0 && Number.isInteger(span) && span >= 0
|
|
83
|
+
? conversation.slice(0, markerAt).filter(isKept).length + span
|
|
84
|
+
: 0;
|
|
72
85
|
const latestUserIndex = latestActualUserInstructionIndex(conversation);
|
|
73
86
|
return {
|
|
74
87
|
protectedPrefix,
|
|
75
88
|
previousSummary: previousSummaryMessage?.content || null,
|
|
76
89
|
previousSummaryMessage,
|
|
77
90
|
previousAck,
|
|
91
|
+
skillWindowStart,
|
|
78
92
|
// Budgeting, AI input and rule-only retention use this same projection.
|
|
79
93
|
// Keep current-turn reminders; remove only proven runtime additions from
|
|
80
94
|
// older requests. Unmarked legacy text remains part of the summary budget.
|
|
@@ -85,7 +99,7 @@ function splitFreshSource(messages) {
|
|
|
85
99
|
.map((message, index) =>
|
|
86
100
|
index === latestUserIndex ? message : referenceMessageMedia(stripRuntimeUserContext(message))
|
|
87
101
|
)
|
|
88
|
-
.filter(
|
|
102
|
+
.filter(isKept),
|
|
89
103
|
sanitized,
|
|
90
104
|
};
|
|
91
105
|
}
|
|
@@ -134,9 +148,11 @@ function toolCallSummaryLine(call, result) {
|
|
|
134
148
|
// Arguments arrive redacted (splitFreshSource); the outcome is redacted
|
|
135
149
|
// here, before any cut can split a secret from its key.
|
|
136
150
|
const outcome = redactRawSecretString(contentText(result?.content)).trim();
|
|
137
|
-
// An ask_user result is the user's own answer: never cut.
|
|
151
|
+
// An ask_user or handoff_user result is the user's own answer: never cut.
|
|
138
152
|
const shown =
|
|
139
|
-
call.name === 'ask_user'
|
|
153
|
+
call.name === 'ask_user' || call.name === 'handoff_user'
|
|
154
|
+
? outcome
|
|
155
|
+
: boundedSummaryText(outcome.replace(/\s+/g, ' '), SUMMARY_TOOL_OUTCOME_CHARS);
|
|
140
156
|
return `[tool call] ${call.name}(${args}) → ${result ? shown || '(empty result)' : '(no result)'}`;
|
|
141
157
|
}
|
|
142
158
|
|
|
@@ -413,6 +429,47 @@ function prependLatestUserContext(message, prefix) {
|
|
|
413
429
|
});
|
|
414
430
|
}
|
|
415
431
|
|
|
432
|
+
const LOADED_SKILL_RESULT_RE = /^Loaded (?:built-in )?skill: /;
|
|
433
|
+
|
|
434
|
+
// A Skill load the retained execution tail keeps states what the skill
|
|
435
|
+
// delivered then: its tool list (the native payload or the summary text). It
|
|
436
|
+
// is brought to what the skill delivers now, in place, so its call stays
|
|
437
|
+
// paired: a skill that no longer loads keeps a result saying so, with no tool
|
|
438
|
+
// payload; a skill whose dependencies changed carries its current payload.
|
|
439
|
+
// Failed loads (errors) are left as they are. `currentSkill` absent, or a
|
|
440
|
+
// skill's `native` undefined (a preview), keeps the result.
|
|
441
|
+
function reconcileRetainedSkillLoads(messages, currentSkill) {
|
|
442
|
+
if (!currentSkill) return messages;
|
|
443
|
+
const calls = new Map(
|
|
444
|
+
messages.flatMap((message) =>
|
|
445
|
+
message?.role === 'assistant' ? (message.toolCalls || []).map((call) => [call.id, call]) : []
|
|
446
|
+
)
|
|
447
|
+
);
|
|
448
|
+
const withoutPayload = ({ nativeToolSearch: _native, ...message }, content) => ({ ...message, content });
|
|
449
|
+
return messages.map((message) => {
|
|
450
|
+
if (message?.role !== 'tool') return message;
|
|
451
|
+
const call = calls.get(message.toolCallId);
|
|
452
|
+
const name = call?.name === 'Skill' ? String(call.arguments?.name || '').trim() : '';
|
|
453
|
+
if (!name) return message;
|
|
454
|
+
const text = contentText(message.content);
|
|
455
|
+
if (!message.nativeToolSearch && !LOADED_SKILL_RESULT_RE.test(text)) return message;
|
|
456
|
+
const skill = currentSkill(name);
|
|
457
|
+
if (skill === null) {
|
|
458
|
+
return withoutPayload(
|
|
459
|
+
message,
|
|
460
|
+
`Skill "${name}" is no longer available in this session (switched off, removed, or outside this project's scope); its instructions and tools are not active.`
|
|
461
|
+
);
|
|
462
|
+
}
|
|
463
|
+
if (skill?.native === undefined) return message;
|
|
464
|
+
if (skill.native) {
|
|
465
|
+
return nativeToolsKey(message.nativeToolSearch) === nativeToolsKey(skill.native)
|
|
466
|
+
? message
|
|
467
|
+
: { ...message, content: skill.native.summary, nativeToolSearch: skill.native };
|
|
468
|
+
}
|
|
469
|
+
return !message.nativeToolSearch && text === skill.summary ? message : withoutPayload(message, skill.summary);
|
|
470
|
+
});
|
|
471
|
+
}
|
|
472
|
+
|
|
416
473
|
// The retained execution tail plus the current-turn messages that must
|
|
417
474
|
// survive every compaction verbatim.
|
|
418
475
|
function freshContextTail(source, budgetTokens, preserveConversation, opts) {
|
|
@@ -423,10 +480,11 @@ function freshContextTail(source, budgetTokens, preserveConversation, opts) {
|
|
|
423
480
|
preview: opts.preview === true,
|
|
424
481
|
});
|
|
425
482
|
const latestUser = latestActualUserInstructionMessage(source.live);
|
|
426
|
-
const
|
|
483
|
+
const executed = reconcileRetainedSkillLoads(execution.messages, opts.currentSkill);
|
|
484
|
+
const latestIndex = executed.findLastIndex(
|
|
427
485
|
(message) => message.role === 'user' && message.content === latestUser?.content
|
|
428
486
|
);
|
|
429
|
-
const retainedTail =
|
|
487
|
+
const retainedTail = executed.map((message, index) =>
|
|
430
488
|
index === latestIndex ? prependLatestUserContext(message, opts.latestUserPrefix) : message
|
|
431
489
|
);
|
|
432
490
|
// The turn's input: the latest real request or an unanswered notification
|
|
@@ -459,11 +517,9 @@ function freshContextTail(source, budgetTokens, preserveConversation, opts) {
|
|
|
459
517
|
};
|
|
460
518
|
}
|
|
461
519
|
|
|
462
|
-
//
|
|
463
|
-
//
|
|
464
|
-
|
|
465
|
-
// without the tools they require.
|
|
466
|
-
function skillLoaderPair(live, bodyIndex, name, retainedCallIds) {
|
|
520
|
+
// The executed Skill call (its owner message, the call and its result) that
|
|
521
|
+
// delivered the body at `bodyIndex`, or null.
|
|
522
|
+
function skillLoader(live, bodyIndex, name) {
|
|
467
523
|
for (let index = bodyIndex - 1; index >= 0; index -= 1) {
|
|
468
524
|
const result = live[index];
|
|
469
525
|
if (result?.role !== 'tool') continue;
|
|
@@ -473,65 +529,211 @@ function skillLoaderPair(live, bodyIndex, name, retainedCallIds) {
|
|
|
473
529
|
(message) => message?.role === 'assistant' && message.toolCalls?.some((c) => c.id === result.toolCallId)
|
|
474
530
|
);
|
|
475
531
|
const call = owner?.toolCalls.find((entry) => entry.id === result.toolCallId);
|
|
476
|
-
if (call?.name
|
|
477
|
-
if (!result.nativeToolSearch || retainedCallIds.has(result.toolCallId)) return [];
|
|
478
|
-
// The re-attached call is part of its owner message: it keeps that id.
|
|
479
|
-
return [carryMessageId({ role: 'assistant', content: '', toolCalls: [call] }, owner), result];
|
|
532
|
+
if (call?.name === 'Skill' && call.arguments?.name === name) return { owner, call, result };
|
|
480
533
|
}
|
|
481
|
-
return
|
|
534
|
+
return null;
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
const nativeToolsKey = (native) =>
|
|
538
|
+
JSON.stringify([native?.provider || '', native?.toolReferences || [], native?.openaiTools || []]);
|
|
539
|
+
|
|
540
|
+
const SKILL_RESTORE_SOURCE = 'compact-skill-restore';
|
|
541
|
+
|
|
542
|
+
// Native tool search exposes a skill's linked tools only through the executed
|
|
543
|
+
// Skill result that referenced them. A restored body keeps that pair, unless
|
|
544
|
+
// the retained tail already carries it, so its instructions never return
|
|
545
|
+
// without the tools they require. `current.native` is the payload the skill's
|
|
546
|
+
// current dependencies produce (null: none to expose); the transcript pair is
|
|
547
|
+
// kept while it matches, otherwise rebuilt from it. `current` absent, or its
|
|
548
|
+
// `native` undefined, keeps the transcript pair as it is.
|
|
549
|
+
function skillLoaderPair(live, bodyIndex, name, retainedCallIds, current) {
|
|
550
|
+
const loader = skillLoader(live, bodyIndex, name);
|
|
551
|
+
if (loader && retainedCallIds.has(loader.result.toolCallId)) return [];
|
|
552
|
+
const native = current?.native === undefined ? loader?.result.nativeToolSearch : current.native;
|
|
553
|
+
if (!native) return [];
|
|
554
|
+
// The re-attached call is part of its owner message: it keeps that id.
|
|
555
|
+
const callMessage = (call) =>
|
|
556
|
+
loader
|
|
557
|
+
? carryMessageId({ role: 'assistant', content: '', toolCalls: [call] }, loader.owner)
|
|
558
|
+
: { role: 'assistant', content: '', toolCalls: [call], meta: { source: SKILL_RESTORE_SOURCE, synthetic: true } };
|
|
559
|
+
if (loader?.result.nativeToolSearch && nativeToolsKey(loader.result.nativeToolSearch) === nativeToolsKey(native)) {
|
|
560
|
+
return [callMessage(loader.call), loader.result];
|
|
561
|
+
}
|
|
562
|
+
// A body that arrived without a native pair still needs one now: a
|
|
563
|
+
// per-skill call id, stable across later Compacts that keep it.
|
|
564
|
+
const call = loader?.call || {
|
|
565
|
+
id: `skill-restore-${createHash('sha256').update(name).digest('hex').slice(0, 24)}`,
|
|
566
|
+
name: 'Skill',
|
|
567
|
+
arguments: { name },
|
|
568
|
+
};
|
|
569
|
+
const result = { role: 'tool', toolCallId: call.id, content: native.summary, nativeToolSearch: native };
|
|
570
|
+
return [callMessage(call), loader ? carryMessageId(result, loader.result) : result];
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
// The body to restore: the transcript copy while it is what the Skill tool
|
|
574
|
+
// delivers now, else the current body.
|
|
575
|
+
function currentSkillBodyMessage(message, current) {
|
|
576
|
+
if (!current || skillMessageText(message.content).trimStart() === current.body) return message;
|
|
577
|
+
return { role: 'user', content: current.body, meta: 'skill' };
|
|
482
578
|
}
|
|
483
579
|
|
|
484
580
|
const SKILL_RELOAD_SOURCE = 'compact-skill-reload';
|
|
485
581
|
|
|
486
|
-
|
|
582
|
+
// How many Compacts in a row a skill may go unused before even its reload
|
|
583
|
+
// line is dropped: a skill untouched that long belongs to finished work, and
|
|
584
|
+
// the model can still load it by name from the skill manifest.
|
|
585
|
+
export const SKILL_RELOAD_MAX_IDLE = 3;
|
|
586
|
+
|
|
587
|
+
const SKILL_TOOL_NAMES = new Set(['Skill', 'skill_view']);
|
|
588
|
+
|
|
589
|
+
function skillReloadReminder(name, idle = 0) {
|
|
487
590
|
return {
|
|
488
591
|
role: 'user',
|
|
489
|
-
content: `[mixdog-runtime] Skill "${name}" was active, but
|
|
490
|
-
meta: { source: SKILL_RELOAD_SOURCE, synthetic: true, skill: name },
|
|
592
|
+
content: `[mixdog-runtime] Skill "${name}" was active earlier, but Compact did not keep its instructions. Reload it with the Skill tool before relying on them.`,
|
|
593
|
+
meta: { source: SKILL_RELOAD_SOURCE, synthetic: true, skill: name, idle },
|
|
491
594
|
};
|
|
492
595
|
}
|
|
493
596
|
|
|
494
|
-
//
|
|
597
|
+
// Every Compact leaves this marker just ahead of the skills it restores, with
|
|
598
|
+
// `span`: how many messages follow it (restored skills and retained tail).
|
|
599
|
+
// All of them happened before that Compact, so the next one reads the skill
|
|
600
|
+
// use window from after them, whether or not a summary exists. The marker is
|
|
601
|
+
// not conversation: the next Compact removes it and writes a new one.
|
|
602
|
+
const SKILL_WINDOW_SOURCE = 'compact-skill-window';
|
|
603
|
+
|
|
604
|
+
function skillWindowMarker(span = 0) {
|
|
605
|
+
return {
|
|
606
|
+
role: 'user',
|
|
607
|
+
content: '[mixdog-runtime] Compact boundary.',
|
|
608
|
+
meta: { source: SKILL_WINDOW_SOURCE, synthetic: true, span },
|
|
609
|
+
};
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
// Restore the skills the session used since the previous Compact, each as the
|
|
613
|
+
// Skill tool would deliver it now. A skill is used when it was loaded or one of
|
|
614
|
+
// its linked tools ran in that window (`windowStart` onward); its linked
|
|
615
|
+
// tools are the native tool references of its loader pair and, when the
|
|
616
|
+
// resolver gives them, `tools`. `currentSkill(name)` (the caller's resolver)
|
|
617
|
+
// answers `{ body, native, summary, tools? }` for a skill that still loads in
|
|
618
|
+
// the session, or null for one switched off, outside its scope or removed:
|
|
619
|
+
// such a skill is restored neither as a body nor as a reload line, since its
|
|
620
|
+
// instructions are no longer in force. Without a resolver the transcript
|
|
621
|
+
// copies are kept.
|
|
495
622
|
// Never summarize/truncate operating instructions or displace the handoff
|
|
496
|
-
// and current task.
|
|
497
|
-
//
|
|
498
|
-
//
|
|
499
|
-
//
|
|
500
|
-
|
|
623
|
+
// and current task. Every other active skill, and a used one whose body does
|
|
624
|
+
// not fit, is left as a one-line reload line. The line counts the Compacts
|
|
625
|
+
// the skill went unused (`meta.idle`) and is dropped past SKILL_RELOAD_MAX_IDLE.
|
|
626
|
+
// Reload lines are charged to the same budget: every possible line is
|
|
627
|
+
// reserved before any body is restored, and restoring a body releases its own.
|
|
628
|
+
function restoreSkillBodies(live, skillBudget, retainedTail, currentSkill = null, windowStart = 0) {
|
|
501
629
|
const retainedCallIds = new Set(retainedTail.filter((m) => m?.role === 'tool').map((m) => m.toolCallId));
|
|
502
|
-
const
|
|
503
|
-
const
|
|
504
|
-
const
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
const
|
|
630
|
+
const current = (name) => (currentSkill ? currentSkill(name) : undefined);
|
|
631
|
+
const loads = (name) => current(name) !== null;
|
|
632
|
+
const transcriptBodies = latestSkillBodies(live);
|
|
633
|
+
const loaded = new Set(transcriptBodies.map((body) => body.name));
|
|
634
|
+
const bodies = transcriptBodies.filter((body) => loads(body.name));
|
|
635
|
+
// Reload lines from earlier Compacts: skill -> Compacts it went unused.
|
|
636
|
+
const earlier = new Map();
|
|
637
|
+
for (const m of live) {
|
|
638
|
+
if (m?.meta?.source !== SKILL_RELOAD_SOURCE || loaded.has(m.meta.skill) || !loads(m.meta.skill)) continue;
|
|
639
|
+
earlier.delete(m.meta.skill);
|
|
640
|
+
earlier.set(m.meta.skill, Number.isFinite(m.meta.idle) ? m.meta.idle : 0);
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
// A loader pair can sit anywhere in the transcript (a restored body stays
|
|
644
|
+
// ahead of the retained tail's pair), so read them all.
|
|
645
|
+
const results = new Map(live.filter((m) => m?.role === 'tool').map((m) => [m.toolCallId, m]));
|
|
646
|
+
const loaderTools = new Map();
|
|
647
|
+
for (const message of live) {
|
|
648
|
+
for (const call of message?.role === 'assistant' ? message.toolCalls || [] : []) {
|
|
649
|
+
const references = results.get(call.id)?.nativeToolSearch?.toolReferences;
|
|
650
|
+
if (call.name !== 'Skill' || !references) continue;
|
|
651
|
+
const name = String(callArguments(call).name || '').trim();
|
|
652
|
+
loaderTools.set(name, [...(loaderTools.get(name) || []), ...references]);
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
const skillsOfTool = new Map();
|
|
656
|
+
for (const name of new Set([...earlier.keys(), ...bodies.map((body) => body.name)])) {
|
|
657
|
+
const skill = current(name);
|
|
658
|
+
const tools = [...(skill?.native?.toolReferences || []), ...(skill?.tools || []), ...(loaderTools.get(name) || [])];
|
|
659
|
+
for (const tool of tools) skillsOfTool.set(tool, (skillsOfTool.get(tool) || new Set()).add(name));
|
|
660
|
+
}
|
|
661
|
+
// Use since the previous Compact (from `windowStart`): the newest transcript
|
|
662
|
+
// position of a load or of a linked tool's call.
|
|
663
|
+
const lastUse = new Map();
|
|
664
|
+
const noteUse = (name, index) => lastUse.set(name, Math.max(lastUse.get(name) ?? -1, index));
|
|
665
|
+
live.forEach((message, index) => {
|
|
666
|
+
if (index < windowStart || message?.role !== 'assistant') return;
|
|
667
|
+
for (const call of message.toolCalls || []) {
|
|
668
|
+
const args = callArguments(call);
|
|
669
|
+
if (SKILL_TOOL_NAMES.has(call.name)) noteUse(String(args.name || '').trim(), index);
|
|
670
|
+
else {
|
|
671
|
+
const tool = call.name === 'call_tool' ? args.name : call.name;
|
|
672
|
+
const mcpServer = `mcp:${parseMcpToolName(tool)?.server}`;
|
|
673
|
+
for (const name of [...(skillsOfTool.get(tool) || []), ...(skillsOfTool.get(mcpServer) || [])]) {
|
|
674
|
+
noteUse(name, index);
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
});
|
|
679
|
+
for (const { name, message } of bodies) {
|
|
680
|
+
const index = live.lastIndexOf(message);
|
|
681
|
+
if (index >= windowStart) noteUse(name, index);
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
// Every active skill without a body ends as a reload line: an unused one
|
|
685
|
+
// ages by a Compact and goes once past the bound; one used (or whose body
|
|
686
|
+
// did not fit) starts over.
|
|
687
|
+
const reminders = new Map();
|
|
688
|
+
for (const [name, idle] of earlier) {
|
|
689
|
+
if (lastUse.has(name)) reminders.set(name, 0);
|
|
690
|
+
else if (idle < SKILL_RELOAD_MAX_IDLE) reminders.set(name, idle + 1);
|
|
691
|
+
}
|
|
692
|
+
const used = bodies.filter(({ name }) => lastUse.has(name)).sort((a, b) => lastUse.get(b.name) - lastUse.get(a.name));
|
|
693
|
+
const unused = bodies.filter(({ name }) => !lastUse.has(name));
|
|
694
|
+
|
|
695
|
+
const reminderCost = (name, idle = 0) => estimateMessagesTokens([skillReloadReminder(name, idle)]);
|
|
696
|
+
let reserved =
|
|
697
|
+
[...reminders].reduce((sum, [name, idle]) => sum + reminderCost(name, idle), 0) +
|
|
698
|
+
unused.reduce((sum, { name }) => sum + reminderCost(name, 1), 0) +
|
|
699
|
+
used.reduce((sum, { name }) => sum + reminderCost(name), 0);
|
|
700
|
+
const dropped = new Set();
|
|
510
701
|
const restoredSkills = [];
|
|
511
702
|
let skillTokens = 0;
|
|
512
|
-
for (const { name, message } of
|
|
513
|
-
const
|
|
703
|
+
for (const { name, message } of used) {
|
|
704
|
+
const skill = current(name);
|
|
705
|
+
const restored = [
|
|
706
|
+
...skillLoaderPair(live, live.lastIndexOf(message), name, retainedCallIds, skill),
|
|
707
|
+
currentSkillBodyMessage(message, skill),
|
|
708
|
+
];
|
|
514
709
|
const cost = estimateMessagesTokens(restored);
|
|
515
710
|
const own = reminderCost(name);
|
|
516
711
|
if (skillTokens + cost + reserved - own > skillBudget) {
|
|
517
|
-
dropped.
|
|
712
|
+
dropped.add(name);
|
|
518
713
|
continue;
|
|
519
714
|
}
|
|
520
715
|
restoredSkills.unshift(...restored);
|
|
521
716
|
skillTokens += cost;
|
|
522
717
|
reserved -= own;
|
|
523
718
|
}
|
|
524
|
-
//
|
|
719
|
+
// In transcript order, after the lines of earlier Compacts.
|
|
720
|
+
for (const { name } of bodies) {
|
|
721
|
+
if (!lastUse.has(name)) reminders.set(name, 1);
|
|
722
|
+
else if (dropped.has(name)) reminders.set(name, 0);
|
|
723
|
+
}
|
|
724
|
+
// Newest skill first; only a budget too small for the lines themselves
|
|
525
725
|
// leaves one out.
|
|
526
|
-
const pending = [...
|
|
726
|
+
const pending = [...reminders];
|
|
527
727
|
const reminded = new Set();
|
|
528
|
-
for (const name of pending.toReversed()) {
|
|
529
|
-
const cost = reminderCost(name);
|
|
728
|
+
for (const [name, idle] of pending.toReversed()) {
|
|
729
|
+
const cost = reminderCost(name, idle);
|
|
530
730
|
if (skillTokens + cost > skillBudget) continue;
|
|
531
731
|
reminded.add(name);
|
|
532
732
|
skillTokens += cost;
|
|
533
733
|
}
|
|
534
|
-
restoredSkills.push(
|
|
734
|
+
restoredSkills.push(
|
|
735
|
+
...pending.filter(([name]) => reminded.has(name)).map(([name, idle]) => skillReloadReminder(name, idle))
|
|
736
|
+
);
|
|
535
737
|
return { restoredSkills, skillTokens };
|
|
536
738
|
}
|
|
537
739
|
|
|
@@ -716,7 +918,19 @@ function assertHandoffFits(summaryMessage, room) {
|
|
|
716
918
|
}
|
|
717
919
|
}
|
|
718
920
|
|
|
719
|
-
|
|
921
|
+
// One resolution per skill per Compact: the retained tail and the restored
|
|
922
|
+
// bodies read the same answer (the real pass re-arms dependencies once).
|
|
923
|
+
function memoizedSkillResolver(resolve) {
|
|
924
|
+
if (!resolve) return null;
|
|
925
|
+
const known = new Map();
|
|
926
|
+
return (name) => {
|
|
927
|
+
if (!known.has(name)) known.set(name, resolve(name));
|
|
928
|
+
return known.get(name);
|
|
929
|
+
};
|
|
930
|
+
}
|
|
931
|
+
|
|
932
|
+
export function freshContextCompactMessages(messages, budgetTokens, options = {}) {
|
|
933
|
+
const opts = { ...options, currentSkill: memoizedSkillResolver(options.currentSkill) };
|
|
720
934
|
const startedAt = Date.now();
|
|
721
935
|
const targetBudget = effectiveBudget(budgetTokens, opts);
|
|
722
936
|
const baseSanitized = reconcileDedupStubs(sanitizeToolPairs(messages));
|
|
@@ -756,12 +970,33 @@ export function freshContextCompactMessages(messages, budgetTokens, opts = {}) {
|
|
|
756
970
|
const summaryContent = String(summaryMessage?.content || '');
|
|
757
971
|
assertHandoffFits(summaryMessage, handoff.room);
|
|
758
972
|
const skillBudget = freshSkillBudget(targetBudget, budget, [...stableHead, ...tail.volatileTail]);
|
|
759
|
-
|
|
760
|
-
const
|
|
761
|
-
const
|
|
973
|
+
// Restored skills carry the window marker, which is charged to their budget.
|
|
974
|
+
const markerCost = estimateMessagesTokens([skillWindowMarker()]);
|
|
975
|
+
const skills = {
|
|
976
|
+
...restoreSkillBodies(
|
|
977
|
+
source.live,
|
|
978
|
+
Math.max(0, skillBudget - markerCost),
|
|
979
|
+
tail.volatileTail,
|
|
980
|
+
opts.currentSkill,
|
|
981
|
+
source.skillWindowStart
|
|
982
|
+
),
|
|
983
|
+
skillBudget,
|
|
984
|
+
};
|
|
985
|
+
// A session with no skill state has no use to window: no marker.
|
|
986
|
+
const marker = skills.restoredSkills.length ? [skillWindowMarker()] : [];
|
|
987
|
+
const stablePrefixMessages = [...stableHead, ...marker, ...skills.restoredSkills];
|
|
988
|
+
const compacted = rebaseCompactedEffortConfiguration(
|
|
762
989
|
baseSanitized,
|
|
763
990
|
reconcileDedupStubs(sanitizeToolPairs([...stablePrefixMessages, ...tail.volatileTail]))
|
|
764
991
|
);
|
|
992
|
+
// The next Compact reads everything after the marker as history, not as use.
|
|
993
|
+
const markerAt = compacted.findLastIndex((message) => message?.meta?.source === SKILL_WINDOW_SOURCE);
|
|
994
|
+
const result =
|
|
995
|
+
markerAt < 0
|
|
996
|
+
? compacted
|
|
997
|
+
: compacted.map((message, index) =>
|
|
998
|
+
index === markerAt ? skillWindowMarker(compacted.length - markerAt - 1) : message
|
|
999
|
+
);
|
|
765
1000
|
const finalTokens = estimateMessagesTokens(result);
|
|
766
1001
|
if (finalTokens > budget) {
|
|
767
1002
|
throw new Error(`freshContextCompactMessages: compacted result exceeds budget=${budget} (result=${finalTokens})`);
|