mixdog 1.3.0 → 1.3.2
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 +52 -9
- package/README.md +8 -4
- package/package.json +2 -2
- package/scripts/native-release-status.mjs +238 -0
- package/src/defaults/shipped-history.json +8 -1
- package/src/defaults/skills/pptx/scripts/qc-pages.mjs +3 -2
- package/src/defaults/skills/setup/SKILL.md +23 -1
- package/src/defaults/skills/setup/references/actions.md +54 -4
- package/src/defaults/skills/setup/references/surfaces.md +23 -3
- package/src/defaults/skills/setup-guide/SKILL.md +17 -10
- package/src/defaults/skills/visualize/SKILL.md +9 -6
- package/src/defaults/skills/visualize/references/craft.md +8 -1
- package/src/help.mjs +1 -1
- package/src/lib/keychain-cjs.cjs +4 -1
- package/src/lib/rules-builder.cjs +14 -7
- package/src/output-styles/common.md +13 -8
- package/src/rules/agent-mode/AGENT_MODE.md +9 -6
- package/src/rules/agent-mode/MIXY.md +11 -6
- package/src/rules/lead/LEAD.md +2 -2
- package/src/rules/shared/10-tool-workflow.md +4 -0
- package/src/rules/shared/20-research.md +2 -0
- package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/preset.mjs +5 -0
- package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/session-prep.mjs +8 -0
- package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +6 -1
- package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +114 -26
- package/src/runtime/agent/orchestrator/agent-runtime/maintenance-route.mjs +8 -0
- package/src/runtime/agent/orchestrator/agent-runtime/room-supervisor-completion.mjs +5 -4
- package/src/runtime/agent/orchestrator/agent-trace.mjs +3 -0
- package/src/runtime/agent/orchestrator/cache-break-trace.mjs +4 -0
- package/src/runtime/agent/orchestrator/config-presets.mjs +2 -0
- package/src/runtime/agent/orchestrator/config-storage.mjs +10 -3
- package/src/runtime/agent/orchestrator/config.mjs +11 -0
- package/src/runtime/agent/orchestrator/context/role-instructions.mjs +81 -16
- package/src/runtime/agent/orchestrator/mcp/agent-connectors.mjs +97 -4
- package/src/runtime/agent/orchestrator/mcp/child-tree.mjs +6 -10
- package/src/runtime/agent/orchestrator/mcp/client.mjs +7 -4
- package/src/runtime/agent/orchestrator/providers/anthropic-api-request.mjs +80 -31
- package/src/runtime/agent/orchestrator/providers/anthropic-model-resolve.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +67 -38
- package/src/runtime/agent/orchestrator/providers/anthropic-turn-result.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/antigravity-oauth-catalog.mjs +7 -2
- package/src/runtime/agent/orchestrator/providers/antigravity-request.mjs +6 -2
- package/src/runtime/agent/orchestrator/providers/auto-effort.mjs +34 -16
- package/src/runtime/agent/orchestrator/providers/cursor-wire.mjs +31 -4
- package/src/runtime/agent/orchestrator/providers/cursor.mjs +4 -1
- package/src/runtime/agent/orchestrator/providers/custom-provider.mjs +11 -8
- package/src/runtime/agent/orchestrator/providers/lib/anthropic-prefix-trace.mjs +76 -0
- package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +19 -1
- package/src/runtime/agent/orchestrator/providers/lib/tail-reminder-split.mjs +13 -0
- package/src/runtime/agent/orchestrator/providers/lib/tool-call-wire-ids.mjs +65 -0
- package/src/runtime/agent/orchestrator/providers/media-normalization.mjs +16 -1
- package/src/runtime/agent/orchestrator/providers/mixdog-local.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/model-proxy-provider.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/openai-codex-metadata.mjs +5 -5
- package/src/runtime/agent/orchestrator/providers/openai-compat-models.mjs +9 -5
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses.mjs +9 -1
- package/src/runtime/agent/orchestrator/providers/openai-compat-retry-profile.mjs +8 -2
- package/src/runtime/agent/orchestrator/providers/openai-compat-wire.mjs +10 -2
- package/src/runtime/agent/orchestrator/providers/openai-direct-request.mjs +30 -3
- package/src/runtime/agent/orchestrator/providers/openai-model-capabilities.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/openai-responses-input.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/opencode-go-oauth.mjs +61 -8
- package/src/runtime/agent/orchestrator/providers/provider-error-kind.mjs +14 -2
- package/src/runtime/agent/orchestrator/providers/registry.mjs +9 -0
- package/src/runtime/agent/orchestrator/providers/retry-executor.mjs +17 -0
- package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +90 -24
- package/src/runtime/agent/orchestrator/runtime-core/fs-utils.mjs +8 -1
- package/src/runtime/agent/orchestrator/runtime-core/goal-mutations.mjs +1 -1
- package/src/runtime/agent/orchestrator/runtime-core/goal-storage.mjs +68 -22
- package/src/runtime/agent/orchestrator/runtime-core/goal-tool-exec.mjs +1 -1
- package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +5 -5
- package/src/runtime/agent/orchestrator/runtime-core/route-context-state.mjs +81 -0
- package/src/runtime/agent/orchestrator/runtime-core/session-text.mjs +2 -1
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +12 -1
- package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +17 -6
- package/src/runtime/agent/orchestrator/runtime-core/workflow/agents.mjs +41 -10
- package/src/runtime/agent/orchestrator/runtime-core/workflow/context.mjs +6 -4
- package/src/runtime/agent/orchestrator/runtime-core/workflow/packs.mjs +8 -4
- package/src/runtime/agent/orchestrator/runtime-core/workflow.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/agent-mode.mjs +0 -6
- package/src/runtime/agent/orchestrator/session/agent-room-supervisor.d.mts +1 -1
- package/src/runtime/agent/orchestrator/session/agent-room-supervisor.mjs +22 -4
- package/src/runtime/agent/orchestrator/session/agent-room.d.mts +21 -2
- package/src/runtime/agent/orchestrator/session/agent-room.mjs +149 -45
- package/src/runtime/agent/orchestrator/session/attachment-preflight.mjs +80 -0
- package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +4 -1
- package/src/runtime/agent/orchestrator/session/compact/execution-tail.mjs +14 -11
- package/src/runtime/agent/orchestrator/session/compact/forked-summary.mjs +3 -0
- package/src/runtime/agent/orchestrator/session/compact/runner.mjs +68 -18
- package/src/runtime/agent/orchestrator/session/compact/summary-mode.mjs +16 -0
- package/src/runtime/agent/orchestrator/session/compact/summary-route.mjs +87 -0
- package/src/runtime/agent/orchestrator/session/compact/summary.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/compact/text-utils.mjs +5 -1
- package/src/runtime/agent/orchestrator/session/compact/user-message-kind.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/compaction-archive-capture.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/context-utils.mjs +41 -10
- package/src/runtime/agent/orchestrator/session/human-gate/delegation.mjs +230 -0
- package/src/runtime/agent/orchestrator/session/human-gate/gate.mjs +156 -25
- package/src/runtime/agent/orchestrator/session/human-gate/outbound-policy.mjs +20 -0
- package/src/runtime/agent/orchestrator/session/human-gate/requests.mjs +21 -9
- package/src/runtime/agent/orchestrator/session/human-gate/run-policy.mjs +73 -0
- package/src/runtime/agent/orchestrator/session/human-gate/store.mjs +55 -27
- package/src/runtime/agent/orchestrator/session/human-gate/unattended-port.mjs +15 -0
- package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +4 -1
- package/src/runtime/agent/orchestrator/session/loop/fresh-context.mjs +189 -105
- package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +9 -0
- package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +6 -2
- package/src/runtime/agent/orchestrator/session/loop/route-fallback.mjs +111 -9
- package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +11 -14
- package/src/runtime/agent/orchestrator/session/loop/steering.mjs +3 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +38 -5
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +21 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +2 -1
- package/src/runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs +12 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-helpers.mjs +11 -5
- package/src/runtime/agent/orchestrator/session/loop/usage.mjs +46 -4
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-auto-effort.mjs +13 -2
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-commit.mjs +18 -8
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +4 -0
- 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 +44 -18
- package/src/runtime/agent/orchestrator/session/manager/orchestration-mode-switch-notice.mjs +99 -0
- package/src/runtime/agent/orchestrator/session/manager/owner-route-fallbacks.mjs +42 -0
- package/src/runtime/agent/orchestrator/session/manager/pending-messages.mjs +3 -9
- package/src/runtime/agent/orchestrator/session/manager/pending-spool-file.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/manager/pending-spool-shard.mjs +5 -3
- package/src/runtime/agent/orchestrator/session/manager/provider-replay.mjs +50 -0
- package/src/runtime/agent/orchestrator/session/manager/rules-cache.mjs +40 -1
- package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +12 -0
- package/src/runtime/agent/orchestrator/session/manager/runtime-state.mjs +20 -0
- package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +62 -47
- package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +6 -8
- package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +12 -1
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-journal.mjs +6 -15
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint.mjs +7 -1
- package/src/runtime/agent/orchestrator/session/manager/turn-interruption.mjs +24 -8
- package/src/runtime/agent/orchestrator/session/manager/usage-metrics.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/manager/workflow-switch-notice.mjs +94 -13
- package/src/runtime/agent/orchestrator/session/mixy-name.mjs +5 -2
- package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +42 -10
- package/src/runtime/agent/orchestrator/session/provider-prefix-guard.mjs +21 -3
- package/src/runtime/agent/orchestrator/session/routine-result.d.mts +35 -4
- package/src/runtime/agent/orchestrator/session/routine-result.mjs +179 -16
- package/src/runtime/agent/orchestrator/session/send-with-recovery.mjs +5 -1
- package/src/runtime/agent/orchestrator/session/side-question-store.mjs +3 -1
- package/src/runtime/agent/orchestrator/session/store/canonical-reader.mjs +41 -7
- package/src/runtime/agent/orchestrator/session/store/lifecycle-barriers.mjs +10 -2
- package/src/runtime/agent/orchestrator/session/store/load-cache.mjs +14 -2
- package/src/runtime/agent/orchestrator/session/store/session-delete.mjs +15 -1
- package/src/runtime/agent/orchestrator/session/store/sweep/sweep-record.mjs +8 -3
- package/src/runtime/agent/orchestrator/session/store/sweep/sweep-row.mjs +36 -1
- package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +4 -1
- package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +40 -5
- package/src/runtime/agent/orchestrator/session/store-summary-last-message.mjs +47 -2
- package/src/runtime/agent/orchestrator/session/tail-reminder-rules.mjs +125 -0
- package/src/runtime/agent/orchestrator/session/tool-batch/finalize.mjs +4 -0
- package/src/runtime/agent/orchestrator/session/tool-result-offload.mjs +78 -43
- package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +49 -14
- package/src/runtime/agent/orchestrator/session/transcript-restore/user-text.mjs +134 -17
- package/src/runtime/agent/orchestrator/tools/builtin/advisory-lock.mjs +35 -13
- package/src/runtime/agent/orchestrator/tools/builtin/atomic-write.mjs +25 -5
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/backgrounded-result.mjs +4 -3
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/completed-result.mjs +13 -14
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/transport-artifacts.mjs +9 -0
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +19 -14
- package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +7 -1
- package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-job-records.mjs +6 -14
- package/src/runtime/agent/orchestrator/tools/builtin/pdf-test-fixtures.mjs +5 -3
- package/src/runtime/agent/orchestrator/tools/builtin/read-image.mjs +4 -2
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-media.mjs +47 -2
- package/src/runtime/agent/orchestrator/tools/builtin/read-special-files.mjs +264 -87
- package/src/runtime/agent/orchestrator/tools/builtin/shell-analysis.mjs +10 -4
- package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +34 -21
- package/src/runtime/agent/orchestrator/tools/code-graph/constants.mjs +8 -4
- package/src/runtime/agent/orchestrator/tools/lib/shell-descendants.mjs +9 -30
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-settle.mjs +24 -12
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-spawn.mjs +3 -2
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-state.mjs +6 -2
- package/src/runtime/agent/orchestrator/tools/patch/delete-quarantine.mjs +2 -1
- package/src/runtime/agent/orchestrator/tools/patch/replay-capture.mjs +4 -2
- package/src/runtime/agent/orchestrator/tools/patch/rollback-state.mjs +33 -2
- package/src/runtime/agent/orchestrator/tools/patch-manifest.json +13 -13
- package/src/runtime/agent/orchestrator/tools/shell-command.mjs +5 -3
- package/src/runtime/agent/orchestrator/tools/shell-exec-output.mjs +3 -1
- package/src/runtime/attachments/attachment-reference.mjs +155 -0
- package/src/runtime/attachments/limits.mjs +5 -1
- package/src/runtime/attachments/office-extract.mjs +3 -6
- package/src/runtime/attachments/pdf-extract.mjs +84 -10
- package/src/runtime/attachments/store.mjs +55 -30
- package/src/runtime/browser-bridge/client.mjs +73 -20
- package/src/runtime/channels/lib/runtime-paths.mjs +1 -1
- package/src/runtime/channels/lib/scheduler.mjs +14 -7
- package/src/runtime/channels/lib/state-file.mjs +15 -15
- package/src/runtime/channels/lib/voice-runtime-fetcher.mjs +14 -13
- package/src/runtime/channels/lib/webhook/relay-tunnel.mjs +22 -18
- package/src/runtime/channels/lib/webhook/session-dispatch.mjs +14 -36
- package/src/runtime/channels/lib/worker-main.mjs +3 -2
- package/src/runtime/effort-judge/compact-tokenizer.mjs +8 -2
- package/src/runtime/effort-judge/judge-client.mjs +6 -3
- package/src/runtime/effort-judge/model-install.mjs +16 -8
- package/src/runtime/effort-judge/model-manifest.json +7 -7
- package/src/runtime/local-provider/asset-installer.mjs +10 -4
- package/src/runtime/local-provider/catalog.mjs +5 -2
- package/src/runtime/local-provider/registered-models.mjs +64 -27
- package/src/runtime/local-provider/server.mjs +2 -3
- package/src/runtime/media/adapters/image-api.mjs +89 -0
- package/src/runtime/media/auth.mjs +64 -1
- package/src/runtime/media/catalog.mjs +66 -4
- package/src/runtime/media/jobs.mjs +4 -0
- package/src/runtime/media/lanes.mjs +46 -5
- package/src/runtime/media/media-usage.mjs +17 -0
- package/src/runtime/media/renditions.mjs +15 -15
- package/src/runtime/media/store.mjs +36 -35
- package/src/runtime/media/tool.mjs +8 -1
- package/src/runtime/memory/lib/cycle-scheduler/health-ledger.mjs +8 -2
- package/src/runtime/memory/lib/embedding-model-files.mjs +30 -7
- package/src/runtime/memory/lib/ingest/transcript-tail.mjs +16 -7
- package/src/runtime/memory/lib/pg/process.mjs +8 -4
- package/src/runtime/memory/lib/project-id-resolver.mjs +5 -1
- package/src/runtime/memory/lib/runtime-fetcher.mjs +6 -1
- package/src/runtime/office/core/journal.mjs +7 -14
- package/src/runtime/office/design/library/design-library-core.mjs +4 -16
- package/src/runtime/office/pdf/ocr-engine-worker.mjs +37 -0
- package/src/runtime/office/pdf/ocr-engine.mjs +146 -0
- package/src/runtime/office/pdf/pdf-ocr.mjs +51 -21
- package/src/runtime/office/pdf/pdf-render.mjs +30 -18
- package/src/runtime/office/portable/ooxml-validator.mjs +2 -2
- package/src/runtime/office/portable/portable-soffice.mjs +4 -0
- package/src/runtime/shared/agent-kind-migration.mjs +200 -0
- package/src/runtime/shared/agent-kind.mjs +152 -0
- package/src/runtime/shared/agent-message-envelope.d.mts +6 -0
- package/src/runtime/shared/agent-message-envelope.mjs +44 -0
- package/src/runtime/shared/agent-reap-state.d.mts +4 -0
- package/src/runtime/shared/agent-route-config.d.mts +1 -0
- package/src/runtime/shared/agent-route-config.mjs +22 -8
- package/src/runtime/shared/agent-store.mjs +149 -0
- package/src/runtime/shared/agent-task-starts.mjs +27 -0
- package/src/runtime/shared/atomic-file.d.mts +50 -0
- package/src/runtime/shared/atomic-file.mjs +394 -132
- package/src/runtime/shared/background-tasks.mjs +7 -4
- package/src/runtime/shared/bot-hops.mjs +30 -0
- package/src/runtime/shared/bot-split-migration.mjs +457 -0
- package/src/runtime/shared/bounded-download.mjs +4 -2
- package/src/runtime/shared/config-patch.mjs +20 -1
- package/src/runtime/shared/config.mjs +39 -9
- package/src/runtime/shared/connector-catalog.d.mts +1 -2
- package/src/runtime/shared/connector-catalog.mjs +2 -4
- package/src/runtime/shared/connector-triggers.mjs +2 -0
- package/src/runtime/shared/defaults-separation.mjs +6 -2
- package/src/runtime/shared/delegated-approval-host.mjs +74 -0
- package/src/runtime/shared/err-text.mjs +7 -1
- package/src/runtime/shared/error-presentation.mjs +113 -10
- package/src/runtime/shared/file-has-data.mjs +28 -0
- package/src/runtime/shared/handoff-artifacts.d.mts +20 -0
- package/src/runtime/shared/handoff-artifacts.mjs +61 -0
- package/src/runtime/shared/llm/provider-model-identities.mjs +6 -1
- package/src/runtime/shared/llm/usage-accounting.mjs +7 -1
- package/src/runtime/shared/llm/usage-ledger-import.mjs +37 -18
- package/src/runtime/shared/model-route-fallback.mjs +79 -7
- package/src/runtime/shared/pending-agent-work.mjs +54 -0
- package/src/runtime/shared/plain-preview.mjs +22 -17
- package/src/runtime/shared/process-lifecycle.mjs +8 -12
- package/src/runtime/shared/projects.mjs +50 -41
- package/src/runtime/shared/provider-accounts.mjs +17 -12
- package/src/runtime/shared/routine-trigger.d.mts +6 -1
- package/src/runtime/shared/routine-trigger.mjs +14 -6
- package/src/runtime/shared/run-child.d.mts +3 -0
- package/src/runtime/shared/run-child.mjs +24 -3
- package/src/runtime/shared/sensitive-path-rules.d.mts +15 -0
- package/src/runtime/shared/sensitive-path-rules.mjs +256 -0
- package/src/runtime/shared/session-baseline-store.mjs +8 -2
- package/src/runtime/shared/singleton-owner.mjs +7 -6
- package/src/runtime/shared/skill-tool-dependencies.mjs +4 -10
- package/src/runtime/shared/staged-update.mjs +4 -2
- package/src/runtime/shared/statusline/statusline-segments.mjs +4 -15
- package/src/runtime/shared/tool-execution-contract.mjs +6 -0
- package/src/runtime/shared/transcript-metadata.mjs +28 -3
- package/src/runtime/shared/transcript-writer/session-record.mjs +7 -6
- package/src/runtime/shared/turn-snapshot-store.mjs +5 -4
- package/src/runtime/shared/turn-snapshot.mjs +44 -2
- package/src/runtime/shared/usage-readout-totals.mjs +15 -13
- package/src/runtime/shared/user-cwd.mjs +9 -4
- package/src/runtime/shared/user-data-guard.mjs +46 -44
- package/src/runtime/shared/utf8-cut.mjs +10 -0
- package/src/runtime/shared/worktrees/activity-gate.mjs +269 -61
- package/src/runtime/shared/worktrees/registry.mjs +26 -26
- package/src/runtime/tidy/core-install.mjs +26 -4
- package/src/runtime/tidy/install.mjs +91 -23
- package/src/runtime/web-search/lib/config.mjs +4 -16
- package/src/session-runtime/agent-home-delivery.mjs +859 -136
- package/src/session-runtime/agent-room-delivery.mjs +167 -19
- package/src/session-runtime/agent-task-sessions.mjs +831 -69
- package/src/session-runtime/agent-tool-routing.mjs +1 -0
- package/src/session-runtime/boot/apis.mjs +58 -24
- package/src/session-runtime/boot/config.mjs +1 -0
- package/src/session-runtime/boot/facade.mjs +11 -1
- package/src/session-runtime/boot/infrastructure.mjs +14 -2
- package/src/session-runtime/boot/providers.mjs +16 -6
- package/src/session-runtime/boot/shared.mjs +12 -6
- package/src/session-runtime/boot/tools.mjs +2 -2
- package/src/session-runtime/bot-status.mjs +432 -0
- package/src/session-runtime/config-lifecycle/lead-route-sync.mjs +29 -0
- package/src/session-runtime/config-lifecycle.mjs +78 -32
- package/src/session-runtime/cwd-plugins/core-memory-context.mjs +2 -4
- package/src/session-runtime/handoff-attachments.mjs +593 -0
- package/src/session-runtime/held-requests.mjs +36 -33
- package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +10 -1
- package/src/session-runtime/internal-tool-executor/feature-tools.mjs +2 -2
- package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +45 -6
- package/src/session-runtime/lifecycle/session-catalog.mjs +12 -2
- package/src/session-runtime/lifecycle/teardown.mjs +11 -3
- package/src/session-runtime/mcp-glue/connect.mjs +100 -186
- package/src/session-runtime/mcp-glue/initial-connect-gate.mjs +57 -0
- package/src/session-runtime/mcp-glue/server-connection.mjs +71 -0
- package/src/session-runtime/media-api.mjs +5 -2
- package/src/session-runtime/model-route/route-persist.mjs +2 -2
- package/src/session-runtime/model-route/route-tuning.mjs +11 -2
- package/src/session-runtime/model-route/set-route.mjs +82 -2
- package/src/session-runtime/native-web-search.mjs +2 -2
- package/src/session-runtime/new-session-config.mjs +6 -1
- package/src/session-runtime/owned-automation-run.mjs +8 -1
- package/src/session-runtime/room-member-gate.mjs +16 -3
- package/src/session-runtime/route-resolution.mjs +21 -19
- package/src/session-runtime/route-state.mjs +1 -59
- package/src/session-runtime/routine-home-turn.mjs +5 -3
- package/src/session-runtime/runtime-bootstrap.mjs +5 -3
- package/src/session-runtime/runtime-paths.mjs +11 -5
- package/src/session-runtime/runtime-tunables.mjs +6 -0
- package/src/session-runtime/services/agent-tool/close-flow/close-all.mjs +11 -2
- package/src/session-runtime/services/agent-tool/close-flow.mjs +4 -2
- package/src/session-runtime/services/agent-tool/execute-send.mjs +1 -0
- package/src/session-runtime/services/agent-tool/execute-spawn.mjs +1 -0
- package/src/session-runtime/services/agent-tool/helpers.mjs +24 -5
- package/src/session-runtime/services/agent-tool/restart-notify.mjs +10 -0
- package/src/session-runtime/services/agent-tool/send-flow.mjs +36 -24
- package/src/session-runtime/services/agent-tool/spawn-flow/job-start.mjs +4 -0
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-prep.mjs +6 -3
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-run.mjs +12 -6
- package/src/session-runtime/services/agent-tool/spawn-preset.mjs +5 -8
- package/src/session-runtime/services/agent-tool/tool-def.mjs +7 -0
- package/src/session-runtime/services/agent-tool/worker-index/row-liveness.mjs +22 -2
- package/src/session-runtime/services/agent-tool/worker-index.mjs +4 -6
- package/src/session-runtime/services/agent-tool.mjs +6 -0
- package/src/session-runtime/services/daemon-crash-capture/daemon-exit-record.mjs +1 -1
- package/src/session-runtime/services/daemon-crash-capture/retention.mjs +4 -3
- package/src/session-runtime/services/hook-bus/config-loader.mjs +14 -5
- package/src/session-runtime/services/hook-bus/rule-file.mjs +49 -11
- package/src/session-runtime/services/plugin-admin.mjs +26 -26
- package/src/session-runtime/services/provider-admin.mjs +14 -4
- package/src/session-runtime/services/schedule-access.mjs +33 -4
- package/src/session-runtime/services/seeds.mjs +4 -3
- package/src/session-runtime/services/usage-dashboard.mjs +1 -1
- package/src/session-runtime/services/usage-stats-model.mjs +2 -1
- package/src/session-runtime/session-create/materialize.mjs +2 -3
- package/src/session-runtime/session-create/session-options.mjs +15 -2
- package/src/session-runtime/settings-builtin-tools-api.mjs +63 -1
- package/src/session-runtime/settings-compaction-api.mjs +86 -39
- package/src/session-runtime/setup-tool/executor.mjs +20 -3
- package/src/session-runtime/setup-tool/extended-actions.mjs +19 -7
- package/src/session-runtime/setup-tool/settings-contract.mjs +37 -1
- package/src/session-runtime/setup-tool/tool-defs.mjs +20 -3
- package/src/session-runtime/skills-api.mjs +12 -5
- package/src/session-runtime/tool-policy/agent-profile-fold.mjs +265 -0
- package/src/session-runtime/tool-policy/mode-switch.mjs +54 -0
- package/src/session-runtime/tool-policy/pending-switches.mjs +59 -0
- package/src/session-runtime/tool-policy/policy-stage.mjs +165 -0
- package/src/session-runtime/tool-policy/session-switches.mjs +169 -0
- package/src/session-runtime/tool-policy/surface-helpers.mjs +114 -0
- package/src/session-runtime/tool-policy/workflow-overlay.mjs +145 -0
- package/src/session-runtime/tool-policy-refresh.mjs +47 -358
- package/src/session-runtime/tool-surface.mjs +5 -3
- package/src/session-runtime/turn/turn-run/turn-prepare.mjs +99 -81
- package/src/session-runtime/turn/turn-run/turn-timing.mjs +4 -3
- package/src/session-runtime/turn/turn-run.mjs +2 -1
- package/src/session-runtime/workflow-agents-api/agent-connectors.mjs +54 -7
- package/src/session-runtime/workflow-agents-api/agent-editor.mjs +578 -301
- package/src/session-runtime/workflow-agents-api/agent-route.mjs +113 -53
- package/src/session-runtime/workflow-agents-api/onboarding.mjs +11 -4
- package/src/session-runtime/workflow-agents-api/shared.mjs +5 -1
- package/src/session-runtime/workflow-agents-api/style-and-mode.mjs +14 -1
- package/src/session-runtime/workflow-agents-api/workflow-packs.mjs +6 -3
- package/src/session-runtime/workspace/workspace-state.mjs +7 -6
- package/src/standalone/daemon-agent-control.mjs +4 -1
- package/src/standalone/daemon-session-control.mjs +60 -11
- package/src/standalone/daemon.mjs +34 -4
- package/src/standalone/local-session-runtime.mjs +22 -14
- package/src/standalone/session-client.mjs +7 -2
- package/src/standalone/session-protocol.mjs +7 -0
- package/src/standalone/session-service/agent-tree/agent-turns.mjs +46 -3
- package/src/standalone/session-service/agent-tree.mjs +4 -3
- package/src/standalone/session-service/session-calls/session-turns.mjs +19 -0
- package/src/standalone/session-service.mjs +11 -0
- package/src/standalone/session-state-projection.mjs +19 -9
- package/src/standalone/session-tool-output.mjs +35 -9
- package/src/tui/app/maintenance-pickers/auto-clear-picker.mjs +19 -13
- package/src/tui/app/settings-picker/settings-rows.mjs +2 -2
- package/src/tui/app/slash-commands.mjs +1 -1
- package/src/tui/app/usage-context-panels/context-model.mjs +8 -2
- package/src/tui/dist/index.mjs +599 -342
- package/src/tui/prompt-history-store.mjs +16 -21
- package/src/tui/session/context-state.mjs +4 -0
- package/src/tui/session/notice-surface.mjs +3 -4
- package/src/tui/session/session-api/intake/abort.mjs +19 -1
- package/src/tui/session/session-api/media.mjs +2 -1
- package/src/tui/session/session-api/routes-agent-definitions.mjs +75 -0
- package/src/tui/session/session-api/routes-write.mjs +203 -0
- package/src/tui/session/session-api/routes.mjs +23 -236
- package/src/tui/session/session-api/settings.mjs +14 -1
- package/src/tui/session/session-flow/drain.mjs +28 -3
- package/src/tui/session/session-flow/failed-turn-rewind.mjs +4 -2
- package/src/tui/session/session-flow/queue/take-entries.mjs +8 -0
- package/src/tui/session/session-flow/steering.mjs +8 -3
- package/src/tui/session/tool-approval.mjs +185 -20
- package/src/tui/session/transcript-intake.mjs +4 -0
- package/src/tui/session/turn-live-call.mjs +11 -3
- package/src/tui/session/turn.mjs +36 -17
- package/src/tui/transcript-tool-failures.mjs +8 -2
- package/src/vendor/statusline/src/gateway/route-meta.mjs +7 -8
- package/src/vendor/statusline/src/gateway/session-routes.mjs +6 -7
- package/src/rules/agent-mode/ROUTINE.md +0 -6
|
@@ -2,8 +2,10 @@
|
|
|
2
2
|
// What a persisted session row contains and where each field comes from: the
|
|
3
3
|
// compaction budget, the origin/permission/cache metadata analytics slice on,
|
|
4
4
|
// the desktop classification, and the record assembled from them. Everything
|
|
5
|
-
// here is field derivation — no
|
|
5
|
+
// here is field derivation — no ownership, no prompt text; the only read is the
|
|
6
|
+
// parent's record a delegated session takes its root from.
|
|
6
7
|
import { toSessionWorkflowMeta } from '../../runtime-core/workflow.mjs';
|
|
8
|
+
import { delegationForNewSession } from '../human-gate/delegation.mjs';
|
|
7
9
|
import { sessionOrchestrationMode } from '../../../../shared/orchestration.mjs';
|
|
8
10
|
import { preserveBufferConfigFields } from './context-meta.mjs';
|
|
9
11
|
import { positiveInt } from '../../../../shared/numbers.mjs';
|
|
@@ -101,9 +103,18 @@ export function sessionOriginFields(opts, { profile, presetObj, providerCacheOpt
|
|
|
101
103
|
ownerSessionId: opts.ownerSessionId || null,
|
|
102
104
|
visibility: opts.visibility || null,
|
|
103
105
|
clientHostPid: opts.clientHostPid || null,
|
|
106
|
+
// A sub-agent's or a bot-created task session's root (who it works for, and
|
|
107
|
+
// how that root was acting), derived from the parent's record — the one
|
|
108
|
+
// read here — never taken from the options (human-gate/delegation.mjs).
|
|
109
|
+
...delegationFields(opts),
|
|
104
110
|
};
|
|
105
111
|
}
|
|
106
112
|
|
|
113
|
+
function delegationFields(opts) {
|
|
114
|
+
const delegation = delegationForNewSession(opts);
|
|
115
|
+
return delegation ? { delegation } : {};
|
|
116
|
+
}
|
|
117
|
+
|
|
107
118
|
// The persisted session record.
|
|
108
119
|
export function buildSessionRecord({ opts, route, presetObj, surface, prompt, messages, contextMeta, origin }) {
|
|
109
120
|
const {
|
|
@@ -35,10 +35,9 @@
|
|
|
35
35
|
// keeps the durable prefix.
|
|
36
36
|
import { appendFileSync, existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from 'node:fs';
|
|
37
37
|
import { appendFile, unlink, writeFile } from 'node:fs/promises';
|
|
38
|
-
import { randomBytes } from 'node:crypto';
|
|
39
38
|
import { join } from 'node:path';
|
|
40
39
|
import { getPluginData } from '../../config.mjs';
|
|
41
|
-
import {
|
|
40
|
+
import { writeFileAtomicSync } from '../../../../shared/atomic-file.mjs';
|
|
42
41
|
import { sanitizeContentForStoredHistory } from '../../providers/media-normalization.mjs';
|
|
43
42
|
import { promptContentText } from './prompt-utils.mjs';
|
|
44
43
|
|
|
@@ -145,19 +144,11 @@ export function writeCheckpointHeader(checkpoint) {
|
|
|
145
144
|
contextState: checkpoint.contextState ?? null,
|
|
146
145
|
updatedAt: Date.now(),
|
|
147
146
|
};
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
} catch (error) {
|
|
154
|
-
try {
|
|
155
|
-
unlinkSync(temp);
|
|
156
|
-
} catch {
|
|
157
|
-
/* best-effort */
|
|
158
|
-
}
|
|
159
|
-
throw error;
|
|
160
|
-
}
|
|
147
|
+
// Durable (fsynced through its handle, then renamed): a crash must not
|
|
148
|
+
// publish a header whose bytes never landed. A damaged header already reads
|
|
149
|
+
// as "no checkpoint" (parseTurnCheckpointHeader) and the next turn rewrites it.
|
|
150
|
+
writeFileAtomicSync(target, JSON.stringify(payload));
|
|
151
|
+
return true;
|
|
161
152
|
}
|
|
162
153
|
|
|
163
154
|
export function readTurnCheckpointHeader(sessionId) {
|
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
writeCheckpointHeader,
|
|
19
19
|
} from './turn-checkpoint-journal.mjs';
|
|
20
20
|
import { captureTurnCheckpointContextState, restoreTurnCheckpointContextState } from './turn-checkpoint-context.mjs';
|
|
21
|
+
import { stripProviderReplayMessages } from './provider-replay.mjs';
|
|
21
22
|
|
|
22
23
|
export { turnCheckpointPath, turnMessagesForCheckpoint };
|
|
23
24
|
export { captureTurnCheckpointContextState, restoreTurnCheckpointContextState };
|
|
@@ -198,7 +199,12 @@ export function recoverTurnCheckpoint(session) {
|
|
|
198
199
|
const current = Array.isArray(session.messages) ? session.messages : [];
|
|
199
200
|
const start = findTurnStart(current, checkpoint.currentUserContent);
|
|
200
201
|
const kept = start >= 0 ? current.slice(0, start) : current;
|
|
201
|
-
|
|
202
|
+
// The route switched models mid-turn (the marker says so) and the journal
|
|
203
|
+
// may predate the switch: its turn still carries the previous provider's
|
|
204
|
+
// native replay state, which the saved route's provider must not receive.
|
|
205
|
+
const turnMessages =
|
|
206
|
+
marker?.routeChanged === true ? stripProviderReplayMessages(finalized.messages) : finalized.messages;
|
|
207
|
+
session.messages = checkpoint.fullTranscript === true ? turnMessages : [...kept, ...turnMessages];
|
|
202
208
|
// Re-anchor provider usage / post-compact replacement state to the exact
|
|
203
209
|
// canonical checkpoint representation. If a legacy or corrupted checkpoint
|
|
204
210
|
// cannot prove alignment, retain the last provider reading for display but
|
|
@@ -20,7 +20,15 @@ const INTERRUPTED_TOOL_RESULT = 'Cancelled';
|
|
|
20
20
|
// PRESERVE the just-sent user turn: nothing restores the prompt there, and
|
|
21
21
|
// rewinding erases the user's message from the persisted transcript (the
|
|
22
22
|
// exact loss seen when the desktop app quits mid-turn).
|
|
23
|
-
|
|
23
|
+
//
|
|
24
|
+
// A user cancel the host will NOT answer with the prompt back in the input box
|
|
25
|
+
// (the desktop Stop button, a prompt carrying attachments cancelled from
|
|
26
|
+
// another device) names `USER_CANCEL_KEEP_PROMPT_REASON`: it is still a user
|
|
27
|
+
// cancel, but the unanswered prompt stays in the stored transcript. Rewinding
|
|
28
|
+
// it left a first message with zero stored messages — a session every catalog
|
|
29
|
+
// hides — and its text nowhere.
|
|
30
|
+
export const USER_CANCEL_KEEP_PROMPT_REASON = 'user-cancel-keep-prompt';
|
|
31
|
+
const USER_CANCEL_ABORT_REASONS = new Set(['cli-abort', 'user-cancel', 'turn-abort', USER_CANCEL_KEEP_PROMPT_REASON]);
|
|
24
32
|
|
|
25
33
|
function provisionalUserTurnIndex(messages, currentUserContent) {
|
|
26
34
|
const currentText = promptContentText(currentUserContent);
|
|
@@ -78,7 +86,17 @@ function finalizeInterruptedTurn({
|
|
|
78
86
|
// turn and its side effects from history.
|
|
79
87
|
const preserveResponse = responseStarted && (producedOutput || !userCancelled);
|
|
80
88
|
if (!preserveResponse) {
|
|
81
|
-
if (!userCancelled) {
|
|
89
|
+
if (!userCancelled || abortReason === USER_CANCEL_KEEP_PROMPT_REASON) {
|
|
90
|
+
// A kept prompt gets the generic interruption row (rendered as the
|
|
91
|
+
// Cancelled status, unlike the hidden by-user control row): without it a
|
|
92
|
+
// rebuilt transcript shows the stopped prompt as if it were still
|
|
93
|
+
// awaiting an answer, directly above the next one.
|
|
94
|
+
if (
|
|
95
|
+
abortReason === USER_CANCEL_KEEP_PROMPT_REASON &&
|
|
96
|
+
provisionalUserTurnIndex(messages, currentUserContent) >= 0
|
|
97
|
+
) {
|
|
98
|
+
messages.push({ role: 'user', content: SESSION_INTERRUPT_MESSAGE });
|
|
99
|
+
}
|
|
82
100
|
return {
|
|
83
101
|
messages,
|
|
84
102
|
responsePreserved: false,
|
|
@@ -145,18 +163,16 @@ function appendObservedTurnOutput(
|
|
|
145
163
|
if (!result?.toolCallId || representedToolResultIds.has(result.toolCallId)) continue;
|
|
146
164
|
messages.push({
|
|
147
165
|
role: 'tool',
|
|
148
|
-
content: result.content
|
|
166
|
+
content: result.content ?? '',
|
|
149
167
|
toolCallId: result.toolCallId,
|
|
150
168
|
...(result.toolKind ? { toolKind: result.toolKind } : {}),
|
|
151
169
|
});
|
|
152
170
|
representedToolResultIds.add(result.toolCallId);
|
|
153
171
|
}
|
|
154
172
|
|
|
155
|
-
const allToolCallIds =
|
|
173
|
+
const allToolCallIds = new Set();
|
|
156
174
|
for (const message of messages) {
|
|
157
|
-
for (const id of assistantToolCallIds(message))
|
|
158
|
-
if (!allToolCallIds.includes(id)) allToolCallIds.push(id);
|
|
159
|
-
}
|
|
175
|
+
for (const id of assistantToolCallIds(message)) allToolCallIds.add(id);
|
|
160
176
|
}
|
|
161
177
|
for (const callId of allToolCallIds) {
|
|
162
178
|
if (representedToolResultIds.has(callId)) continue;
|
|
@@ -283,7 +299,7 @@ export function createTurnInterruptionTracker() {
|
|
|
283
299
|
if (message.__earlyNotify === true) {
|
|
284
300
|
state.observedToolResults.set(callId, {
|
|
285
301
|
role: 'tool',
|
|
286
|
-
content: message.content
|
|
302
|
+
content: message.content ?? '',
|
|
287
303
|
toolCallId: callId,
|
|
288
304
|
toolKind: message.toolKind || (message.isError ? 'error' : null),
|
|
289
305
|
});
|
|
@@ -558,7 +558,7 @@ export async function persistIterationMetrics(delta) {
|
|
|
558
558
|
// per model call of this session (every tool-loop iteration), replaced
|
|
559
559
|
// immutably so a consumer can tell by identity that it changed. Sessions
|
|
560
560
|
// saved before this field began at their first call after it.
|
|
561
|
-
session.usageReadout = foldUsageReadout(session.usageReadout, delta, delta.
|
|
561
|
+
session.usageReadout = foldUsageReadout(session.usageReadout, delta, delta.requestMs);
|
|
562
562
|
recordLastContextTokens(session, iterationContext(delta));
|
|
563
563
|
}
|
|
564
564
|
session.lastIterationIndex = iterationIndex;
|
|
@@ -1,20 +1,97 @@
|
|
|
1
1
|
// manager/workflow-switch-notice.mjs
|
|
2
2
|
// A mid-conversation workflow switch (session-runtime/tool-policy-refresh.mjs
|
|
3
|
-
// switchSessionWorkflow)
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
//
|
|
11
|
-
//
|
|
3
|
+
// switchSessionWorkflow) leaves the request prefix — system blocks and tool
|
|
4
|
+
// schemas — byte-identical, so the provider cache survives. The switch lives
|
|
5
|
+
// in two pieces of session state:
|
|
6
|
+
// session.workflowOverlay — while the session's workflow differs from the
|
|
7
|
+
// one its system prompt carries: the prompt's workflow (`prompt`, and the
|
|
8
|
+
// orchestration mode its tool surface was built with), the new workflow,
|
|
9
|
+
// its tools that are refused at call time (`deniedTools`), the tools it
|
|
10
|
+
// allows that this session cannot reach (`unavailableTools`) and the
|
|
11
|
+
// self-contained reminder (`content`) with the new workflow's rules,
|
|
12
|
+
// orchestration and agents. It is folded into the prompt (and dropped) at
|
|
13
|
+
// the next point where the cache is cold anyway (tool-policy-refresh.mjs).
|
|
14
|
+
// session.workflowSwitch — the notice the next user turn carries in its
|
|
15
|
+
// reminder block. Lifecycle mirrors the working-folder notice
|
|
16
|
+
// (prompt-utils snapshotPendingWorkspaceNotice): snapshot when the turn is
|
|
17
|
+
// built, acknowledge once the provider accepted it, so a failed turn
|
|
18
|
+
// re-sends it. Delivered, it stays in the conversation. Replaced, never
|
|
19
|
+
// mutated:
|
|
20
|
+
// from — the workflow the model was last told about (kept across
|
|
21
|
+
// switches made before a notice reached it);
|
|
22
|
+
// to — the session's workflow now.
|
|
23
|
+
// Every notice says it replaces the earlier ones, so the latest one wins.
|
|
12
24
|
|
|
13
25
|
function workflowRef(workflow) {
|
|
14
26
|
const id = String(workflow?.id || '').trim();
|
|
15
27
|
return id ? { id, name: String(workflow?.name || id).trim() } : null;
|
|
16
28
|
}
|
|
17
29
|
|
|
30
|
+
/** The workflow the session's system prompt and tool surface were built with. */
|
|
31
|
+
export function promptWorkflowOf(session) {
|
|
32
|
+
return session?.workflowOverlay?.prompt || session?.workflow || null;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const lower = (name) => String(name || '').toLowerCase();
|
|
36
|
+
|
|
37
|
+
/** The refusal of a call to a tool the session's current workflow denies
|
|
38
|
+
* while its schema (built for the prompt's workflow) still carries it; null
|
|
39
|
+
* for any other call. */
|
|
40
|
+
export function workflowOverlayDenial(session, name) {
|
|
41
|
+
const overlay = session?.workflowOverlay;
|
|
42
|
+
if (!overlay?.deniedTools?.some((denied) => lower(denied) === lower(name))) return null;
|
|
43
|
+
return `Error: tool "${name}" is not available in workflow ${overlay.workflow.name}: this conversation switched to it. Do the work without it.`;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const listed = (names) => names.map((name) => `\`${name}\``).join(', ');
|
|
47
|
+
|
|
48
|
+
/** The reminder that makes the Lead follow `workflow` while its system prompt
|
|
49
|
+
* still carries `promptName`'s: self-contained (rules, orchestration, agents,
|
|
50
|
+
* tool changes) and superseding every earlier one. */
|
|
51
|
+
export function workflowOverlayContent({
|
|
52
|
+
promptName,
|
|
53
|
+
workflow,
|
|
54
|
+
instructions,
|
|
55
|
+
deniedTools = [],
|
|
56
|
+
loadableTools = [],
|
|
57
|
+
unavailableTools = [],
|
|
58
|
+
}) {
|
|
59
|
+
const name = workflow.name;
|
|
60
|
+
return [
|
|
61
|
+
'<system-reminder>',
|
|
62
|
+
'# Workflow Changed',
|
|
63
|
+
`This conversation now runs the ${name} workflow. The system prompt's Active Workflow, orchestration mode and available agents are still ${promptName}'s: they no longer apply; follow ${name}'s below instead. This replaces every earlier Workflow Changed reminder in this conversation.`,
|
|
64
|
+
...(deniedTools.length ? [`Not available in ${name} (calls are refused): ${listed(deniedTools)}.`] : []),
|
|
65
|
+
...(loadableTools.length
|
|
66
|
+
? [
|
|
67
|
+
`${name} adds ${listed(loadableTools)}: not among your directly defined tools yet; load ${loadableTools.length === 1 ? 'it' : 'them'} with \`load_tool\` before the first call.`,
|
|
68
|
+
]
|
|
69
|
+
: []),
|
|
70
|
+
...(unavailableTools.length
|
|
71
|
+
? [`${name} allows ${listed(unavailableTools)}, but this session cannot use them; a new session can.`]
|
|
72
|
+
: []),
|
|
73
|
+
`Agents already started under ${promptName} keep running with their own instructions; new delegation follows ${name}.`,
|
|
74
|
+
'',
|
|
75
|
+
instructions,
|
|
76
|
+
'</system-reminder>',
|
|
77
|
+
].join('\n');
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function messageText(message) {
|
|
81
|
+
if (typeof message?.content === 'string') return message.content;
|
|
82
|
+
if (!Array.isArray(message?.content)) return '';
|
|
83
|
+
return message.content.map((part) => (typeof part === 'string' ? part : part?.text || '')).join('');
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/** The conversation still holds `content` (a delivered reminder); false once
|
|
87
|
+
* a compaction or a clear dropped it. */
|
|
88
|
+
export function conversationHolds(session, content) {
|
|
89
|
+
if (!content) return false;
|
|
90
|
+
return (Array.isArray(session?.messages) ? session.messages : []).some(
|
|
91
|
+
(message) => message?.role !== 'system' && messageText(message).includes(content)
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
|
|
18
95
|
/** Stage the notice of a switch from `from` to `to`; a switch back to what the
|
|
19
96
|
* model was last told drops it. Returns the staged state or null. */
|
|
20
97
|
export function stageWorkflowSwitchNotice(session, from, to) {
|
|
@@ -29,13 +106,14 @@ export function stageWorkflowSwitchNotice(session, from, to) {
|
|
|
29
106
|
return session.workflowSwitch;
|
|
30
107
|
}
|
|
31
108
|
|
|
32
|
-
|
|
109
|
+
// The prompt itself carries `to` (a switch back to it, or the overlay folded in).
|
|
110
|
+
function promptWorkflowNoticeContent({ from, to }) {
|
|
33
111
|
const before = from?.name || 'the previous workflow';
|
|
34
112
|
return [
|
|
35
113
|
'<system-reminder>',
|
|
36
114
|
'# Workflow Changed',
|
|
37
|
-
`
|
|
38
|
-
`Agents already started under ${before} keep running with their own instructions; new delegation
|
|
115
|
+
`This conversation now runs the ${to.name} workflow, the one the system prompt carries: its Active Workflow, orchestration mode, available agents and tools apply. This replaces every earlier Workflow Changed reminder in this conversation.`,
|
|
116
|
+
`Agents already started under ${before} keep running with their own instructions; new delegation follows ${to.name}.`,
|
|
39
117
|
'</system-reminder>',
|
|
40
118
|
].join('\n');
|
|
41
119
|
}
|
|
@@ -47,7 +125,10 @@ function workflowNoticeContent({ from, to }) {
|
|
|
47
125
|
export function snapshotPendingWorkflowNotice(session) {
|
|
48
126
|
const pending = session?.workflowSwitch;
|
|
49
127
|
if (!pending?.to?.id) return null;
|
|
50
|
-
|
|
128
|
+
const overlay = session.workflowOverlay;
|
|
129
|
+
const content =
|
|
130
|
+
overlay?.workflow?.id === pending.to.id && overlay.content ? overlay.content : promptWorkflowNoticeContent(pending);
|
|
131
|
+
return { revision: pending.revision, content };
|
|
51
132
|
}
|
|
52
133
|
|
|
53
134
|
/** The notice of `revision` reached the model: nothing is due any more. */
|
|
@@ -4,8 +4,9 @@
|
|
|
4
4
|
// use so a rename applies at once. Text shared across agents (tool schemas,
|
|
5
5
|
// other agents' shared prompt block) says "the representative agent" instead,
|
|
6
6
|
// so a rename never changes cached bytes.
|
|
7
|
-
import { join } from 'node:path';
|
|
7
|
+
import { dirname, join } from 'node:path';
|
|
8
8
|
import { mixdogGlobalDir, readSafe } from '../context/skill-catalog.mjs';
|
|
9
|
+
import { mixyIdentityDir } from '../../../shared/agent-store.mjs';
|
|
9
10
|
|
|
10
11
|
export const DEFAULT_MIXY_NAME = 'Mixy';
|
|
11
12
|
|
|
@@ -17,7 +18,9 @@ export function mixyNameOf(manifest) {
|
|
|
17
18
|
|
|
18
19
|
export function mixyDisplayName() {
|
|
19
20
|
try {
|
|
20
|
-
|
|
21
|
+
// bots/mixy once Mixy is its own bot, agents/lead before (agent-store.mjs).
|
|
22
|
+
const dir = mixyIdentityDir(dirname(mixdogGlobalDir('agents')));
|
|
23
|
+
return mixyNameOf(JSON.parse(readSafe(join(dir, 'agent.json')) || '{}'));
|
|
21
24
|
} catch {
|
|
22
25
|
return DEFAULT_MIXY_NAME;
|
|
23
26
|
}
|
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
import { previewFreshContextCompaction, runFreshContextCompact } from './loop/fresh-context.mjs';
|
|
20
20
|
import { estimateMessagesTokensSafe } from './loop/compact-debug.mjs';
|
|
21
21
|
import { textPdfAllowanceDiscount } from './context-utils.mjs';
|
|
22
|
+
import { referenceOversizedAttachments } from './attachment-preflight.mjs';
|
|
22
23
|
import { providerNativePdf } from '../providers/registry.mjs';
|
|
23
24
|
import { messagesArrayChanged } from './loop/tool-helpers.mjs';
|
|
24
25
|
import { normalizeUsage, addUsage } from './loop/usage.mjs';
|
|
@@ -274,6 +275,9 @@ async function compactTranscript(ctx, run) {
|
|
|
274
275
|
goalReminderText: run.inlineGoalReminder?.content || '',
|
|
275
276
|
activeTurn: true,
|
|
276
277
|
requireReduction: decision.requireReduction,
|
|
278
|
+
// The provider refused this request as too long: whatever the estimate
|
|
279
|
+
// said, the latest request's attachments now travel by reference.
|
|
280
|
+
referenceLatestAttachments: decision.compactTrigger === 'reactive',
|
|
277
281
|
});
|
|
278
282
|
const freshMessages = Array.isArray(run.freshContextResult?.messages) ? run.freshContextResult.messages : null;
|
|
279
283
|
if (!freshMessages) throw new Error('fresh-context compact produced no messages');
|
|
@@ -290,6 +294,9 @@ function acknowledgeGoalReminder(sessionRef, run) {
|
|
|
290
294
|
}
|
|
291
295
|
}
|
|
292
296
|
|
|
297
|
+
// Detection is narrow on purpose — signal.aborted or a true AbortError — so
|
|
298
|
+
// the recall pipeline's SYNTHETIC "…aborted: memory … ; head preserved"
|
|
299
|
+
// failure (a real compact failure, message text aside) still escalates.
|
|
293
300
|
function isCompactAbort(signal, err) {
|
|
294
301
|
return signal?.aborted === true || err?.name === 'AbortError' || err?.code === 'ABORT_ERR' || err?.code === 'ABORT';
|
|
295
302
|
}
|
|
@@ -326,16 +333,6 @@ function reportCompactFailure(ctx, run, compactErr) {
|
|
|
326
333
|
});
|
|
327
334
|
}
|
|
328
335
|
|
|
329
|
-
// A failed compact pass ends the send. A genuine cancellation/abort surfaced
|
|
330
|
-
// from the compact pipeline is NOT a context overflow: the fresh-context
|
|
331
|
-
// pipeline deliberately rethrows the original abort error unchanged so the
|
|
332
|
-
// session records a clean cancellation — and the manual/auto-clear runner
|
|
333
|
-
// (manager/compaction-runner.mjs) likewise never fabricates an
|
|
334
|
-
// AGENT_CONTEXT_OVERFLOW for an aborted compact. Mirror that here: preserve
|
|
335
|
-
// the real error (code/name/cause intact) instead of masking it as overflow.
|
|
336
|
-
// Detection is narrow on purpose — signal.aborted or a true AbortError — so
|
|
337
|
-
// the recall pipeline's SYNTHETIC "…aborted: memory … ; head preserved"
|
|
338
|
-
// failure (a real compact failure, message text aside) still escalates.
|
|
339
336
|
function isGenuineCompactOverflow(compactErr) {
|
|
340
337
|
return (
|
|
341
338
|
compactErr?.code === 'AGENT_CONTEXT_OVERFLOW' ||
|
|
@@ -362,6 +359,13 @@ function retryCompactQuietly(ctx, run, compactErr) {
|
|
|
362
359
|
return true;
|
|
363
360
|
}
|
|
364
361
|
|
|
362
|
+
// A failed compact pass ends the send. A genuine cancellation/abort surfaced
|
|
363
|
+
// from the compact pipeline is NOT a context overflow: the fresh-context
|
|
364
|
+
// pipeline deliberately rethrows the original abort error unchanged so the
|
|
365
|
+
// session records a clean cancellation — and the manual/auto-clear runner
|
|
366
|
+
// (manager/compaction-runner.mjs) likewise never fabricates an
|
|
367
|
+
// AGENT_CONTEXT_OVERFLOW for an aborted compact. Mirror that here: preserve
|
|
368
|
+
// the real error (code/name/cause intact) instead of masking it as overflow.
|
|
365
369
|
function throwCompactFailure(ctx, run, compactErr) {
|
|
366
370
|
const { state, compactPolicy, decision } = ctx;
|
|
367
371
|
const { sessionRef, sessionId, signal, model } = state;
|
|
@@ -555,6 +559,33 @@ async function compactBeforeSend(ctx) {
|
|
|
555
559
|
await runCompactHook(ctx, 'postCompactHook');
|
|
556
560
|
}
|
|
557
561
|
|
|
562
|
+
// Attachments that would crowd the window travel by reference from this send
|
|
563
|
+
// on (session/attachment-preflight.mjs). Runs whether or not auto-compaction
|
|
564
|
+
// is on: it is what keeps an oversized attachment message from ever reaching
|
|
565
|
+
// the provider. A rewrite changes the transcript the provider chain was built
|
|
566
|
+
// on, so the continuation is dropped and the send is tagged exactly like an
|
|
567
|
+
// automatic compaction: the prefix guard accepts that boundary, whereas a
|
|
568
|
+
// transcript-repair tag would refuse the rewritten earlier message.
|
|
569
|
+
function preflightAttachments(ctx, compactPolicy) {
|
|
570
|
+
const { state } = ctx;
|
|
571
|
+
const contextWindow = compactPolicy?.contextWindow || state.sessionRef?.contextWindow;
|
|
572
|
+
const outcome = referenceOversizedAttachments(state.messages, {
|
|
573
|
+
contextWindow,
|
|
574
|
+
nativePdf: providerNativePdf(state.sessionRef?.provider),
|
|
575
|
+
});
|
|
576
|
+
if (!outcome.changed) return;
|
|
577
|
+
ctx.providerState = undefined;
|
|
578
|
+
ctx.providerStateCleared = true;
|
|
579
|
+
ctx.compactChanged = true;
|
|
580
|
+
if (state.opts && !String(state.opts.cacheBreakIntent || '').endsWith('_compaction')) {
|
|
581
|
+
state.opts.cacheBreakIntent = 'automatic_compaction';
|
|
582
|
+
}
|
|
583
|
+
writeStderrBestEffort(
|
|
584
|
+
`[loop] attachments sent by reference (sess=${state.sessionId || 'unknown'}): ` +
|
|
585
|
+
`${outcome.referencedMessages} message(s), inline estimate ${outcome.inlineTokensBefore} > budget ${outcome.budgetTokens}\n`
|
|
586
|
+
);
|
|
587
|
+
}
|
|
588
|
+
|
|
558
589
|
export async function runPreSendCompactPass(state) {
|
|
559
590
|
const ctx = {
|
|
560
591
|
state,
|
|
@@ -567,6 +598,7 @@ export async function runPreSendCompactPass(state) {
|
|
|
567
598
|
compactChanged: false,
|
|
568
599
|
};
|
|
569
600
|
const compactPolicy = resolveWorkerCompactPolicy(state.sessionRef, state.requestTools);
|
|
601
|
+
preflightAttachments(ctx, compactPolicy);
|
|
570
602
|
if (compactPolicy?.auto) {
|
|
571
603
|
ctx.compactPolicy = compactPolicy;
|
|
572
604
|
ctx.decision = preSendCompactDecision(state, compactPolicy);
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createHash } from 'node:crypto';
|
|
2
2
|
import { hasPlainPrototype } from '../../../shared/object.mjs';
|
|
3
|
+
import { withoutMessageIdsReplacer } from './message-ids.mjs';
|
|
3
4
|
|
|
4
5
|
const COMPACTION_INTENTS = new Set([
|
|
5
6
|
'automatic_compaction',
|
|
@@ -8,8 +9,8 @@ const COMPACTION_INTENTS = new Set([
|
|
|
8
9
|
'post_turn_compaction',
|
|
9
10
|
]);
|
|
10
11
|
|
|
11
|
-
function digest(value) {
|
|
12
|
-
const encoded = JSON.stringify(value);
|
|
12
|
+
function digest(value, replacer) {
|
|
13
|
+
const encoded = JSON.stringify(value, replacer);
|
|
13
14
|
if (typeof encoded !== 'string') {
|
|
14
15
|
throw new TypeError('provider prefix value is not serializable');
|
|
15
16
|
}
|
|
@@ -82,11 +83,28 @@ function matchShape(value, tokens, cursor) {
|
|
|
82
83
|
return count === tokens[cursor + 1] ? next : -1;
|
|
83
84
|
}
|
|
84
85
|
|
|
86
|
+
// A message's digest covers what the provider can see of it. The stable
|
|
87
|
+
// message id (`meta.transcript.messageId`, message-ids.mjs) is display
|
|
88
|
+
// bookkeeping that is stamped onto live messages in place — a compaction pass
|
|
89
|
+
// stamps every unstamped message before it runs, whatever it then decides —
|
|
90
|
+
// and no provider request builder reads or sends it (the rest of `meta` is
|
|
91
|
+
// not bookkeeping: `meta.source` and `meta.effortConfiguration` steer the
|
|
92
|
+
// wire and stay in the digest). Hashing it would make a pass that changes
|
|
93
|
+
// nothing look like a rewritten prefix on the next send.
|
|
94
|
+
//
|
|
95
|
+
// Only the message root's own `meta` is projected: a `meta` nested in content
|
|
96
|
+
// (e.g. a structured tool result) is provider-visible and stays in the digest.
|
|
97
|
+
function rootMessageIdsReplacer(message) {
|
|
98
|
+
return function replacer(key, value) {
|
|
99
|
+
return this === message ? withoutMessageIdsReplacer(key, value) : value;
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
|
|
85
103
|
function messageDigest(message) {
|
|
86
104
|
if (message === null || typeof message !== 'object') return digest(message);
|
|
87
105
|
const memo = messageDigestMemo.get(message);
|
|
88
106
|
if (memo && matchShape(message, memo.tokens, 0) === memo.tokens.length) return memo.hash;
|
|
89
|
-
const hash = digest(message);
|
|
107
|
+
const hash = digest(message, rootMessageIdsReplacer(message));
|
|
90
108
|
const tokens = [];
|
|
91
109
|
if (recordShape(message, tokens)) messageDigestMemo.set(message, { hash, tokens });
|
|
92
110
|
else messageDigestMemo.delete(message);
|
|
@@ -8,8 +8,10 @@ export interface RoutineProvenance {
|
|
|
8
8
|
|
|
9
9
|
export interface RoutineMessageMeta {
|
|
10
10
|
source: string;
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
/** A task report into a bot's home chat of a bot-to-bot send names the
|
|
12
|
+
* answering bot in `agentId` (the target's home session owner). */
|
|
13
|
+
routine: Record<string, unknown> & { agentId?: string };
|
|
14
|
+
transcript: { at: number; messageId?: string; attachments?: unknown[] };
|
|
13
15
|
}
|
|
14
16
|
export interface RoutineMessage {
|
|
15
17
|
role: 'user';
|
|
@@ -19,14 +21,26 @@ export interface RoutineMessage {
|
|
|
19
21
|
export interface RoutineNotice {
|
|
20
22
|
text: string;
|
|
21
23
|
tone: 'info' | 'warn';
|
|
22
|
-
routine: Record<string, unknown
|
|
24
|
+
routine: Record<string, unknown> & { agentId?: string };
|
|
23
25
|
/** Live run notices only (routineRunNotice). */
|
|
24
26
|
messageId?: string;
|
|
27
|
+
/** A task report's stored files (handoff-artifacts.mjs). */
|
|
28
|
+
attachments?: Array<{
|
|
29
|
+
id: string;
|
|
30
|
+
attachmentRef: string;
|
|
31
|
+
kind: string;
|
|
32
|
+
name: string;
|
|
33
|
+
mimeType: string;
|
|
34
|
+
size: number;
|
|
35
|
+
}>;
|
|
25
36
|
}
|
|
26
37
|
|
|
27
38
|
export const ROUTINE_RESULT_SOURCE: 'schedule-result';
|
|
28
39
|
export const TASK_LOOP_CAP: number;
|
|
29
40
|
export function routineSummary(text: unknown): string;
|
|
41
|
+
export const REPLY_LIMIT: number;
|
|
42
|
+
export function boundedReply(text: unknown): { text: string; chars: number };
|
|
43
|
+
export const WAKE_TEXT_BUDGET: number;
|
|
30
44
|
export function routineResultMessage(options: {
|
|
31
45
|
kind?: 'schedule' | 'webhook';
|
|
32
46
|
name: string;
|
|
@@ -40,16 +54,33 @@ export function routineResultMessage(options: {
|
|
|
40
54
|
messageId?: string;
|
|
41
55
|
}): RoutineMessage;
|
|
42
56
|
export function routineOmittedMessage(options: { count: number; at?: number; messageId?: string }): RoutineMessage;
|
|
57
|
+
export function agentTaskRelayFailedMessage(options: {
|
|
58
|
+
count: number;
|
|
59
|
+
tries: number;
|
|
60
|
+
at?: number;
|
|
61
|
+
messageId?: string;
|
|
62
|
+
}): RoutineMessage;
|
|
43
63
|
export function agentTaskMessage(options: {
|
|
44
64
|
title: string;
|
|
45
65
|
status: string;
|
|
46
66
|
text?: unknown;
|
|
67
|
+
/** Length of the whole reply when `text` is already a bounded part of it. */
|
|
68
|
+
textChars?: number;
|
|
69
|
+
/** The row's one-line summary, when made from the whole reply before `text` was bounded. */
|
|
70
|
+
summary?: string;
|
|
47
71
|
taskSessionId: string;
|
|
72
|
+
/** 'session': any session other than a task session the agent created. */
|
|
73
|
+
target?: 'task' | 'session';
|
|
48
74
|
round?: number;
|
|
75
|
+
/** false: the report was posted without waking the agent (round-trip cap). */
|
|
76
|
+
woken?: boolean;
|
|
77
|
+
/** The files the turn produced (handoff-artifacts.mjs). */
|
|
78
|
+
files?: ReadonlyArray<{ name: string; path: string; mimeType?: string; size?: number; kind?: string; id?: string }>;
|
|
79
|
+
omitted?: number;
|
|
49
80
|
at?: number;
|
|
50
81
|
messageId?: string;
|
|
51
82
|
}): RoutineMessage;
|
|
52
|
-
export function agentTaskWakePrompt(messages: ReadonlyArray<{ content: string }
|
|
83
|
+
export function agentTaskWakePrompt(messages: ReadonlyArray<{ content: string }>, options?: { more?: number }): string;
|
|
53
84
|
export function isRoutineResultMessage(message: unknown): boolean;
|
|
54
85
|
export function normalizeRoutineProvenance(value: unknown): RoutineProvenance | null;
|
|
55
86
|
export function routineProvenance(message: unknown): RoutineProvenance | null;
|