mixdog 1.3.1 → 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/README.md +8 -4
- package/package.json +2 -2
- package/scripts/native-release-status.mjs +238 -0
- package/src/defaults/shipped-history.json +5 -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 +50 -3
- package/src/defaults/skills/setup/references/surfaces.md +23 -3
- package/src/defaults/skills/setup-guide/SKILL.md +7 -3
- 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/rules/agent-mode/AGENT_MODE.md +8 -5
- package/src/rules/agent-mode/MIXY.md +6 -8
- 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 +9 -2
- package/src/runtime/agent/orchestrator/mcp/agent-connectors.mjs +97 -5
- 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-request.mjs +6 -2
- package/src/runtime/agent/orchestrator/providers/auto-effort.mjs +27 -8
- 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 +16 -0
- package/src/runtime/agent/orchestrator/providers/lib/tail-reminder-split.mjs +13 -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-wire.mjs +2 -1
- 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-ws.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/opencode-go-oauth.mjs +61 -8
- package/src/runtime/agent/orchestrator/providers/registry.mjs +9 -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 +4 -6
- 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 +6 -5
- package/src/runtime/agent/orchestrator/runtime-core/workflow/agents.mjs +7 -6
- package/src/runtime/agent/orchestrator/runtime-core/workflow/context.mjs +1 -1
- 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 +17 -2
- package/src/runtime/agent/orchestrator/session/agent-room.mjs +133 -38
- 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 +136 -32
- 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/pre-dispatch-deny.mjs +6 -2
- package/src/runtime/agent/orchestrator/session/loop/route-fallback.mjs +5 -5
- package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +3 -0
- 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/manager/ask-turn-auto-effort.mjs +13 -2
- 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/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 +55 -27
- package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +3 -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-interruption.mjs +24 -8
- package/src/runtime/agent/orchestrator/session/manager/workflow-switch-notice.mjs +94 -13
- 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 +18 -3
- package/src/runtime/agent/orchestrator/session/routine-result.mjs +120 -9
- 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 +35 -5
- package/src/runtime/agent/orchestrator/session/transcript-restore/user-text.mjs +42 -2
- 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 +49 -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 +5 -2
- package/src/runtime/effort-judge/model-install.mjs +16 -8
- 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-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-store.mjs +24 -7
- 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 +1 -1
- package/src/runtime/shared/bounded-download.mjs +4 -2
- package/src/runtime/shared/config.mjs +39 -9
- 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 +4 -0
- package/src/runtime/shared/error-presentation.mjs +22 -4
- package/src/runtime/shared/file-has-data.mjs +28 -0
- package/src/runtime/shared/llm/usage-ledger-import.mjs +37 -18
- package/src/runtime/shared/pending-agent-work.mjs +54 -0
- 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/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/user-cwd.mjs +9 -4
- package/src/runtime/shared/user-data-guard.mjs +41 -42
- 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 +555 -199
- package/src/session-runtime/agent-room-delivery.mjs +143 -36
- package/src/session-runtime/agent-task-sessions.mjs +667 -165
- package/src/session-runtime/agent-tool-routing.mjs +1 -0
- package/src/session-runtime/boot/apis.mjs +45 -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 +2 -2
- 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 +60 -55
- package/src/session-runtime/cwd-plugins/core-memory-context.mjs +2 -4
- 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 +19 -4
- 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-tuning.mjs +4 -1
- package/src/session-runtime/model-route/set-route.mjs +61 -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 +16 -8
- 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/restart-notify.mjs +10 -0
- package/src/session-runtime/services/agent-tool/send-flow.mjs +25 -21
- 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 +8 -5
- 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 +8 -2
- package/src/session-runtime/setup-tool/settings-contract.mjs +31 -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 -369
- package/src/session-runtime/tool-surface.mjs +5 -3
- package/src/session-runtime/turn/turn-run/turn-prepare.mjs +95 -88
- 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 +519 -333
- package/src/session-runtime/workflow-agents-api/agent-route.mjs +46 -46
- 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 +51 -10
- package/src/standalone/daemon.mjs +28 -10
- 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.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 +529 -333
- package/src/tui/prompt-history-store.mjs +16 -21
- package/src/tui/session/context-state.mjs +4 -0
- 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 -247
- 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 +2 -0
- package/src/tui/session/turn.mjs +23 -14
- 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
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
bridgeSurfaceOutdated,
|
|
9
9
|
sessionToolExposure,
|
|
10
10
|
TOOL_EXPOSURE_BRIDGE,
|
|
11
|
+
TOOL_EXPOSURE_NATIVE,
|
|
11
12
|
TOOL_SURFACE_MIGRATION_INTENT,
|
|
12
13
|
toolExposureMigrationNeeded,
|
|
13
14
|
toolExposureModeForProvider,
|
|
@@ -122,6 +123,17 @@ export function applyAgentToolExposure(session, { existing = false } = {}) {
|
|
|
122
123
|
const bridge =
|
|
123
124
|
!allowlisted && toolExposureModeForProvider(session.provider, session.wireRoute) === TOOL_EXPOSURE_BRIDGE;
|
|
124
125
|
if (!bridge && before === null) return false;
|
|
126
|
+
// A native deferred surface (the session runtime builds one) stays one:
|
|
127
|
+
// re-selected over the tools just resolved, never stripped to the full
|
|
128
|
+
// array. Native → native is no exposure change, so nothing is tagged.
|
|
129
|
+
if (!bridge && before === TOOL_EXPOSURE_NATIVE) {
|
|
130
|
+
session.tools = session.tools.slice();
|
|
131
|
+
applyDeferredToolSurface(session, session.deferredSurfaceMode || 'full', [], {
|
|
132
|
+
provider: session.provider,
|
|
133
|
+
model: session.model,
|
|
134
|
+
});
|
|
135
|
+
return false;
|
|
136
|
+
}
|
|
125
137
|
// A surface an earlier bridge revision built is rebuilt now.
|
|
126
138
|
const outdated = bridgeSurfaceOutdated(session);
|
|
127
139
|
// The tools just resolved are the whole authority: no earlier catalog, MCP
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
// native tool-search payload parsing, bash-session routing, and approval.
|
|
4
4
|
import { isMcpTool } from '../../mcp/client.mjs';
|
|
5
5
|
import { unattendedApprovalPort } from '../human-gate/gate.mjs';
|
|
6
|
+
import { isGrantedRun, runAskOutcome } from '../human-gate/run-policy.mjs';
|
|
6
7
|
import { isBuiltinTool } from '../../tools/builtin.mjs';
|
|
7
8
|
import { isInternalTool } from '../../internal-tools.mjs';
|
|
8
9
|
import { loadSkillToolDependencies } from '../../runtime-core/skill-tool-loading.mjs';
|
|
@@ -212,12 +213,13 @@ export async function resolvePreToolAskApproval({
|
|
|
212
213
|
}) {
|
|
213
214
|
const name = String(toolName || 'tool');
|
|
214
215
|
const reason = String(askReason || 'approval requested by hook').trim();
|
|
215
|
-
//
|
|
216
|
-
// run
|
|
216
|
+
// A schedule or webhook run never asks: saving it was the user's grant
|
|
217
|
+
// (human-gate/run-policy.mjs). A room member is held for its owner when no
|
|
217
218
|
// approval UI is attached (session-runtime/held-requests.mjs).
|
|
218
219
|
const unattended = unattendedApprovalPort();
|
|
219
220
|
const run = unattended?.runOf?.(sessionId) || null;
|
|
220
|
-
|
|
221
|
+
if (isGrantedRun(run)) return runAskOutcome({ name, request });
|
|
222
|
+
const held = run && typeof toolApprovalHook !== 'function';
|
|
221
223
|
const ask = held ? unattended.hold : toolApprovalHook;
|
|
222
224
|
if (typeof ask !== 'function') {
|
|
223
225
|
return { denial: formatMissingToolApprovalUiDenial(name, reason) };
|
|
@@ -238,8 +240,12 @@ export async function resolvePreToolAskApproval({
|
|
|
238
240
|
return { denial: `Error: tool "${name}" denied by hook: ${detail}` };
|
|
239
241
|
}
|
|
240
242
|
if (!approvalGranted(approval)) {
|
|
241
|
-
|
|
242
|
-
|
|
243
|
+
// A person (or the hold for one) said no: never a policy hook to work around.
|
|
244
|
+
const detail = String(approvalReason(approval, reason || 'not approved')).replace(/[.\s]+$/, '');
|
|
245
|
+
return {
|
|
246
|
+
denial: `Error: tool "${name}" was not approved: ${detail}. Do not retry it or reach the same result another way; report it.`,
|
|
247
|
+
approval,
|
|
248
|
+
};
|
|
243
249
|
}
|
|
244
250
|
return { approval };
|
|
245
251
|
}
|
|
@@ -11,6 +11,7 @@ import { autoEffortModel, turnEffortConfigurationMode } from '../../providers/ef
|
|
|
11
11
|
import {
|
|
12
12
|
autoEffortApplicable,
|
|
13
13
|
autoEffortBase,
|
|
14
|
+
clampAutoEffortBase,
|
|
14
15
|
normalizeAutoEffortMode,
|
|
15
16
|
resolveAutoEffort,
|
|
16
17
|
} from '../../providers/auto-effort.mjs';
|
|
@@ -58,6 +59,15 @@ export function autoEffortMode() {
|
|
|
58
59
|
}
|
|
59
60
|
}
|
|
60
61
|
|
|
62
|
+
/** The global "Auto reasoning base" setting; absent or unreadable is medium. */
|
|
63
|
+
export function autoEffortBaseSetting() {
|
|
64
|
+
try {
|
|
65
|
+
return autoEffortBase(readSection('agent')?.autoEffortBase);
|
|
66
|
+
} catch {
|
|
67
|
+
return autoEffortBase(undefined);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
61
71
|
/**
|
|
62
72
|
* Starts the judge worker when a session is created or opened on a route that
|
|
63
73
|
* Auto effort can judge, so the first judged turn does not wait for the cold
|
|
@@ -102,7 +112,9 @@ export async function resolveTurnAutoEffort({ sessionId, session, provider, inpu
|
|
|
102
112
|
if (!request || request.startsWith('<')) return null;
|
|
103
113
|
if (!turnEffortConfigurationMode(session, provider)) return null;
|
|
104
114
|
const chosen = String(session.effort || '').toLowerCase();
|
|
105
|
-
const
|
|
115
|
+
const options = effortOptionsFor(session.provider, autoEffortModel(session.provider, provider, session.model));
|
|
116
|
+
const setting = autoEffortBaseSetting();
|
|
117
|
+
const base = clampAutoEffortBase({ base: setting, options }) ?? autoEffortBase(setting);
|
|
106
118
|
const record = {
|
|
107
119
|
at: new Date().toISOString(),
|
|
108
120
|
sessionId,
|
|
@@ -113,7 +125,6 @@ export async function resolveTurnAutoEffort({ sessionId, session, provider, inpu
|
|
|
113
125
|
base,
|
|
114
126
|
requestChars: request.length,
|
|
115
127
|
};
|
|
116
|
-
const options = effortOptionsFor(session.provider, autoEffortModel(session.provider, provider, session.model));
|
|
117
128
|
// No judged outcome can apply when the base is off the model's ladder, so
|
|
118
129
|
// the judge is not asked (in observe mode too: nothing would be logged).
|
|
119
130
|
if (!autoEffortApplicable({ base, options })) {
|
|
@@ -19,12 +19,15 @@ import { retainedFailedTurnInput, rewindUnansweredPrompt } from './failed-turn-r
|
|
|
19
19
|
import { buildAgentLoopOptions, trackedToolCallHook } from './ask-turn-loop-options.mjs';
|
|
20
20
|
import { _api_call_with_interrupt } from './ask-call-interrupt.mjs';
|
|
21
21
|
import { backfillFallbackSessionTitle } from './session-fallback-title.mjs';
|
|
22
|
+
import { stampTurnHop } from '../../../../shared/bot-hops.mjs';
|
|
22
23
|
|
|
23
24
|
/** Resolves the provider, builds the user turn and pre-commits it; returns
|
|
24
25
|
* what the loop and the commit need from this preparation. */
|
|
25
26
|
export async function prepareAskTurn({ sessionId, opened, input, cwdOverride, transcriptMeta }) {
|
|
26
27
|
const { turn, runtime, turnSignal, askGeneration, checkpoint, turnToken, startedAt, codexTurnId } = opened;
|
|
27
28
|
const session = turn.session;
|
|
29
|
+
// Where the turn sits in a bot-to-bot chain (session-runtime/bot-hops.mjs).
|
|
30
|
+
stampTurnHop(session, transcriptMeta, input.promptSource);
|
|
28
31
|
const retained = input.retryTurnId
|
|
29
32
|
? retainedFailedTurnInput(session.messages, input.retryTurnId, input.retryAttemptId)
|
|
30
33
|
: null;
|
|
@@ -187,6 +190,7 @@ export async function prepareAskTurn({ sessionId, opened, input, cwdOverride, tr
|
|
|
187
190
|
deferredToolDelta: userTurn.deferredToolDelta,
|
|
188
191
|
goalReminder: userTurn.goalReminder,
|
|
189
192
|
workflowNotice: userTurn.workflowNotice,
|
|
193
|
+
orchestrationModeNotice: userTurn.orchestrationModeNotice,
|
|
190
194
|
workspaceNotice: userTurn.workspaceNotice,
|
|
191
195
|
setupNotice: userTurn.setupNotice,
|
|
192
196
|
};
|
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
snapshotPendingSetupNotice,
|
|
21
21
|
} from './prompt-utils.mjs';
|
|
22
22
|
import { snapshotPendingWorkflowNotice } from './workflow-switch-notice.mjs';
|
|
23
|
+
import { snapshotPendingOrchestrationModeNotice } from './orchestration-mode-switch-notice.mjs';
|
|
23
24
|
import { codexWireSendOpts } from './session-id.mjs';
|
|
24
25
|
import { _tryBridgeExplicitPrefetch } from './prefetch-bridge.mjs';
|
|
25
26
|
import { filterModelVisibleSessionMessages } from './message-sanitize.mjs';
|
|
@@ -184,8 +185,12 @@ export async function buildUserTurn({
|
|
|
184
185
|
// A mid-conversation workflow switch: the prompt and tools were rebuilt
|
|
185
186
|
// for the new workflow; this turn tells the model once.
|
|
186
187
|
const workflowNotice = snapshotPendingWorkflowNotice(session);
|
|
188
|
+
// A mid-conversation orchestration mode switch, after the workflow notice
|
|
189
|
+
// so the mode it names wins over the one a workflow reminder carries.
|
|
190
|
+
const orchestrationModeNotice = snapshotPendingOrchestrationModeNotice(session);
|
|
187
191
|
const reminderBlock = [
|
|
188
192
|
workflowNotice?.content || '',
|
|
193
|
+
orchestrationModeNotice?.content || '',
|
|
189
194
|
workspaceNotice?.content || '',
|
|
190
195
|
setupNotice?.content || '',
|
|
191
196
|
currentTimeBlock ? `<system-reminder>\n# Current Time\n${currentTimeBlock}\n</system-reminder>` : '',
|
|
@@ -215,6 +220,7 @@ export async function buildUserTurn({
|
|
|
215
220
|
deferredToolDelta,
|
|
216
221
|
goalReminder,
|
|
217
222
|
workflowNotice,
|
|
223
|
+
orchestrationModeNotice,
|
|
218
224
|
workspaceNotice,
|
|
219
225
|
setupNotice,
|
|
220
226
|
userTurnMessage,
|
|
@@ -10,6 +10,7 @@ import { acknowledgePendingDeferredToolDelta } from '../../runtime-core/deferred
|
|
|
10
10
|
import { acknowledgePendingGoalReminder } from '../../runtime-core/goal-reminder.mjs';
|
|
11
11
|
import { acknowledgePendingSetupNotice, acknowledgePendingWorkspaceNotice } from './prompt-utils.mjs';
|
|
12
12
|
import { acknowledgePendingWorkflowNotice } from './workflow-switch-notice.mjs';
|
|
13
|
+
import { acknowledgePendingOrchestrationModeNotice } from './orchestration-mode-switch-notice.mjs';
|
|
13
14
|
import {
|
|
14
15
|
finalizePendingMessageDelivery,
|
|
15
16
|
drainPendingMessages,
|
|
@@ -141,6 +142,9 @@ export async function commitAskTurn({ sessionId, opened, prepared, result, rawTr
|
|
|
141
142
|
acknowledgePendingGoalReminder(session, prepared.goalReminder.revision);
|
|
142
143
|
}
|
|
143
144
|
if (prepared.workflowNotice) acknowledgePendingWorkflowNotice(session, prepared.workflowNotice.revision);
|
|
145
|
+
if (prepared.orchestrationModeNotice) {
|
|
146
|
+
acknowledgePendingOrchestrationModeNotice(session, prepared.orchestrationModeNotice.revision);
|
|
147
|
+
}
|
|
144
148
|
if (prepared.workspaceNotice) {
|
|
145
149
|
acknowledgePendingWorkspaceNotice(session, prepared.workspaceNotice.revision);
|
|
146
150
|
}
|
|
@@ -110,17 +110,12 @@ function withoutLegacyCompactFields(value) {
|
|
|
110
110
|
delete next[key];
|
|
111
111
|
return next;
|
|
112
112
|
}
|
|
113
|
-
// Handoff-summary timeout
|
|
114
|
-
//
|
|
115
|
-
//
|
|
116
|
-
//
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
function handoffSummaryTimeoutMs(session, messageTokens) {
|
|
120
|
-
const override = positiveInt(session?.compaction?.timeoutMs);
|
|
121
|
-
if (override) return override;
|
|
122
|
-
const scaled = Math.ceil((messageTokens || 0) / 25_000) * 10_000;
|
|
123
|
-
return Math.min(HANDOFF_TIMEOUT_MAX_MS, Math.max(60_000, scaled));
|
|
113
|
+
// Handoff-summary timeout (clear/manual path): the same 300s as automatic
|
|
114
|
+
// compaction, whatever the transcript size — the summary may run on a slow
|
|
115
|
+
// reasoning model or a stalled provider connection, and a timeout fails the
|
|
116
|
+
// compaction. session.compaction.timeoutMs still overrides.
|
|
117
|
+
function handoffSummaryTimeoutMs(session) {
|
|
118
|
+
return positiveInt(session?.compaction?.timeoutMs) || HANDOFF_TIMEOUT_MAX_MS;
|
|
124
119
|
}
|
|
125
120
|
/**
|
|
126
121
|
* ONE wiring for the fresh-context handoff pass: provider, summary model,
|
|
@@ -144,13 +139,8 @@ export async function runHandoffCompaction({
|
|
|
144
139
|
provider = null,
|
|
145
140
|
model = null,
|
|
146
141
|
config,
|
|
147
|
-
messageTokensEst = null,
|
|
148
142
|
requireReduction = false,
|
|
149
143
|
} = {}) {
|
|
150
|
-
const messageList = Array.isArray(messages) ? messages : [];
|
|
151
|
-
const transcriptTokens = Number.isFinite(Number(messageTokensEst))
|
|
152
|
-
? Number(messageTokensEst)
|
|
153
|
-
: estimateMessagesTokens(messageList);
|
|
154
144
|
return runFreshContextCompact({
|
|
155
145
|
sessionRef: session,
|
|
156
146
|
messages,
|
|
@@ -159,7 +149,7 @@ export async function runHandoffCompaction({
|
|
|
159
149
|
reserveTokens,
|
|
160
150
|
contextWindow: positiveInt(contextWindow) || positiveInt(session?.contextWindow) || boundaryTokens,
|
|
161
151
|
boundaryTokens,
|
|
162
|
-
handoffTimeoutMs: handoffSummaryTimeoutMs(session
|
|
152
|
+
handoffTimeoutMs: handoffSummaryTimeoutMs(session),
|
|
163
153
|
},
|
|
164
154
|
sessionId,
|
|
165
155
|
signal,
|
|
@@ -336,7 +326,6 @@ async function runSessionHandoff(plan, opts) {
|
|
|
336
326
|
provider: opts.provider || getProvider(session.provider) || null,
|
|
337
327
|
model: opts.model,
|
|
338
328
|
config: opts.config,
|
|
339
|
-
messageTokensEst: plan.beforeMessageTokens,
|
|
340
329
|
requireReduction: plan.requireReduction,
|
|
341
330
|
});
|
|
342
331
|
if (Array.isArray(run.freshContextResult?.messages)) {
|
|
@@ -609,7 +598,43 @@ function withAppendedMessages(plan, numbers, appended) {
|
|
|
609
598
|
const TRANSCRIPT_MOVED_ERROR =
|
|
610
599
|
'compact: the conversation changed while compacting; compaction not applied, run it again';
|
|
611
600
|
|
|
601
|
+
// Why a compaction took as long as it did: persisted next to lastSummaryModel
|
|
602
|
+
// and echoed as one daemon.log line. Wall time runs start → end of commit; the
|
|
603
|
+
// summary call's own time comes from the handoff pipeline, so the remainder is
|
|
604
|
+
// planning, transcript comparison and the commit below. The archive write is
|
|
605
|
+
// scheduled by the commit and runs later, off it.
|
|
606
|
+
function recordCompactionTiming(plan, freshContextResult, { startedAt, commitStartedAt, afterTokens }) {
|
|
607
|
+
const { session, resolvedSessionId } = plan;
|
|
608
|
+
const committedAt = Date.now();
|
|
609
|
+
const pipeline = freshContextResult?.diagnostics?.pipeline;
|
|
610
|
+
const summaryMs = pipeline?.generated?.durationMs ?? null;
|
|
611
|
+
// How the summary ran: a fork of the cached request or the isolated
|
|
612
|
+
// request, and on which route (session / maintenance / lighter).
|
|
613
|
+
let summaryRun = null;
|
|
614
|
+
if (pipeline?.summaryRoute) {
|
|
615
|
+
const kind = pipeline.generated?.mode === 'shared-prefix' ? 'fork' : 'isolated';
|
|
616
|
+
summaryRun = `${kind}:${pipeline.summaryRoute}`;
|
|
617
|
+
}
|
|
618
|
+
const timing = {
|
|
619
|
+
lastStartedAt: startedAt,
|
|
620
|
+
lastCommittedAt: committedAt,
|
|
621
|
+
lastDurationMs: committedAt - startedAt,
|
|
622
|
+
lastPipelineMs: pipeline?.totalMs ?? null,
|
|
623
|
+
lastSummaryMs: summaryMs,
|
|
624
|
+
lastCommitMs: committedAt - commitStartedAt,
|
|
625
|
+
lastCompactMode: summaryRun ? `${pipeline.mode}:${summaryRun}` : pipeline?.mode || null,
|
|
626
|
+
};
|
|
627
|
+
Object.assign(session.compaction, timing);
|
|
628
|
+
writeStderrBestEffort(
|
|
629
|
+
`compaction session=${resolvedSessionId || 'unknown'} source=${freshContextResult?.handoffSource || 'session-local'} ` +
|
|
630
|
+
`model=${freshContextResult?.summaryModel || '-'} mode=${summaryRun || '-'} total=${timing.lastDurationMs}ms ` +
|
|
631
|
+
`summary=${summaryMs ?? 0}ms commit=${timing.lastCommitMs}ms ` +
|
|
632
|
+
`in=${plan.beforeTokens} out=${afterTokens}\n`
|
|
633
|
+
);
|
|
634
|
+
}
|
|
635
|
+
|
|
612
636
|
async function commitSessionCompaction(plan, run, compactStartedAt) {
|
|
637
|
+
const commitStartedAt = Date.now();
|
|
613
638
|
const { session, messages, mode, force, resolvedSessionId, reserveTokens } = plan;
|
|
614
639
|
const { freshContextResult } = run;
|
|
615
640
|
const numbers = await afterCompactionNumbers(plan, run.compacted);
|
|
@@ -688,6 +713,7 @@ async function commitSessionCompaction(plan, run, compactStartedAt) {
|
|
|
688
713
|
if (changed) {
|
|
689
714
|
session.pendingCacheBreakIntent = mode === 'auto' ? 'post_turn_compaction' : 'manual_compaction';
|
|
690
715
|
}
|
|
716
|
+
recordCompactionTiming(plan, freshContextResult, { startedAt: compactStartedAt, commitStartedAt, afterTokens });
|
|
691
717
|
return compactionResult(
|
|
692
718
|
plan,
|
|
693
719
|
{ changed, reason: unchangedReason },
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
// manager/orchestration-mode-switch-notice.mjs
|
|
2
|
+
// A mid-conversation delegation (orchestration) mode switch
|
|
3
|
+
// (session-runtime/tool-policy-refresh.mjs switchSessionOrchestrationMode),
|
|
4
|
+
// on the workflow switch's pattern (workflow-switch-notice.mjs): the request
|
|
5
|
+
// prefix — system blocks and tool schemas — stays byte-identical, so the
|
|
6
|
+
// provider cache survives. The switch lives in two pieces of session state:
|
|
7
|
+
// session.orchestrationModeOverlay — while the session's mode differs from
|
|
8
|
+
// the one its system prompt carries: the prompt's mode (`prompt`), the
|
|
9
|
+
// new mode, the tools the model must load before using them
|
|
10
|
+
// (`loadableTools`) and the self-contained reminder (`content`) with the
|
|
11
|
+
// new mode's rules (the same block BP3 carries). It is folded into the
|
|
12
|
+
// prompt (and dropped) at the next point where the cache is cold anyway.
|
|
13
|
+
// session.orchestrationModeSwitch — the notice the next user turn carries
|
|
14
|
+
// in its reminder block: snapshot when the turn is built, acknowledge once
|
|
15
|
+
// the provider accepted it. `from` is the mode the model was last told
|
|
16
|
+
// about, `to` the session's mode now.
|
|
17
|
+
// Every notice says it replaces the earlier ones, so the latest one wins.
|
|
18
|
+
import { normalizeOrchestrationMode } from '../../../../shared/orchestration.mjs';
|
|
19
|
+
import { orchestrationInstructions } from '../../runtime-core/orchestration.mjs';
|
|
20
|
+
|
|
21
|
+
/** The mode's name as its BP3 block titles it (`# Orchestration Mode: …`). */
|
|
22
|
+
export function orchestrationModeName(value) {
|
|
23
|
+
const mode = normalizeOrchestrationMode(value);
|
|
24
|
+
return mode === 'none' ? 'Solo' : `${mode[0].toUpperCase()}${mode.slice(1)}`;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** The mode the session's system prompt and tool surface were built with. */
|
|
28
|
+
export function promptOrchestrationModeOf(session) {
|
|
29
|
+
if (session?.workflowOverlay) return session.workflowOverlay.promptOrchestrationMode;
|
|
30
|
+
if (session?.orchestrationModeOverlay) return session.orchestrationModeOverlay.prompt;
|
|
31
|
+
return session?.orchestrationMode;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const listed = (names) => names.map((name) => `\`${name}\``).join(', ');
|
|
35
|
+
|
|
36
|
+
/** The reminder that makes the Lead follow `mode`: self-contained (the mode's
|
|
37
|
+
* rules) and superseding every earlier one. `carried`: the system prompt
|
|
38
|
+
* carries this mode itself (a switch back, or the overlay folded in). */
|
|
39
|
+
export function orchestrationModeNoticeContent({ mode, carried = false, loadableTools = [] }) {
|
|
40
|
+
const name = orchestrationModeName(mode);
|
|
41
|
+
const lead = carried
|
|
42
|
+
? `This conversation now uses the ${name} orchestration mode, the one the system prompt carries.`
|
|
43
|
+
: `This conversation now uses the ${name} orchestration mode. The system prompt's Orchestration Mode no longer applies; follow ${name}'s below instead.`;
|
|
44
|
+
const pronoun = loadableTools.length === 1 ? 'it' : 'them';
|
|
45
|
+
return [
|
|
46
|
+
'<system-reminder>',
|
|
47
|
+
'# Orchestration Mode Changed',
|
|
48
|
+
`${lead} This replaces every earlier Orchestration Mode Changed reminder in this conversation.`,
|
|
49
|
+
...(loadableTools.length
|
|
50
|
+
? [
|
|
51
|
+
`${listed(loadableTools)}: not among your directly defined tools yet; load ${pronoun} with \`load_tool\` before the first call.`,
|
|
52
|
+
]
|
|
53
|
+
: []),
|
|
54
|
+
`Agents already started keep running with their own instructions; new delegation follows ${name}.`,
|
|
55
|
+
'',
|
|
56
|
+
orchestrationInstructions(mode),
|
|
57
|
+
'</system-reminder>',
|
|
58
|
+
].join('\n');
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/** Stage the notice of a switch from `from` to `to`; a switch back to what the
|
|
62
|
+
* model was last told drops it. Returns the staged state or null. */
|
|
63
|
+
export function stageOrchestrationModeSwitchNotice(session, from, to) {
|
|
64
|
+
const prior = session.orchestrationModeSwitch;
|
|
65
|
+
const told = prior ? prior.from : from;
|
|
66
|
+
if (!to || told === to) {
|
|
67
|
+
delete session.orchestrationModeSwitch;
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
session.orchestrationModeSwitch = {
|
|
71
|
+
version: 1,
|
|
72
|
+
revision: (Number(prior?.revision) || 0) + 1,
|
|
73
|
+
from: told,
|
|
74
|
+
to,
|
|
75
|
+
};
|
|
76
|
+
return session.orchestrationModeSwitch;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* The orchestration mode notice the next user turn carries, or null.
|
|
81
|
+
* @returns {{ revision: number, content: string } | null}
|
|
82
|
+
*/
|
|
83
|
+
export function snapshotPendingOrchestrationModeNotice(session) {
|
|
84
|
+
const pending = session?.orchestrationModeSwitch;
|
|
85
|
+
if (!pending?.to) return null;
|
|
86
|
+
const overlay = session.orchestrationModeOverlay;
|
|
87
|
+
const content =
|
|
88
|
+
overlay?.mode === pending.to && overlay.content
|
|
89
|
+
? overlay.content
|
|
90
|
+
: orchestrationModeNoticeContent({ mode: pending.to, carried: true });
|
|
91
|
+
return { revision: pending.revision, content };
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/** The notice of `revision` reached the model: nothing is due any more. */
|
|
95
|
+
export function acknowledgePendingOrchestrationModeNotice(session, revision) {
|
|
96
|
+
if (!session?.orchestrationModeSwitch || session.orchestrationModeSwitch.revision !== Number(revision)) return false;
|
|
97
|
+
delete session.orchestrationModeSwitch;
|
|
98
|
+
return true;
|
|
99
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
// The fallback models a Lead-class session starts with. Agents get theirs from
|
|
2
|
+
// their spawn preset (agent-child.mjs); a Lead-class session gets its OWNER's:
|
|
3
|
+
// - a coding Lead (new task, task a bot created): the Lead route, i.e. the
|
|
4
|
+
// preset of `config.default` (workflow-lead);
|
|
5
|
+
// - an agent-mode Lead (a bot's home chat, a room turn, a routine run, or
|
|
6
|
+
// Mixy's own thread): that bot's own route in its folder (agent.json), so
|
|
7
|
+
// Mixy and the Lead keep separate chains.
|
|
8
|
+
// The chain applies only while the session runs on the owner's configured
|
|
9
|
+
// primary model. A session the user put on another model (composer picker,
|
|
10
|
+
// New Task) is a deliberate choice and gets none. Route changes recompute it
|
|
11
|
+
// (updateSessionRoute `routeFallbacks`); a fallback hop does not.
|
|
12
|
+
import { loadConfig } from '../../config.mjs';
|
|
13
|
+
import { findPreset } from '../../runtime-core/config-helpers.mjs';
|
|
14
|
+
import { normalizeWorkflowRoute } from '../../runtime-core/workflow.mjs';
|
|
15
|
+
import { canonicalRouteProvider } from '../../../../shared/model-route-chain.mjs';
|
|
16
|
+
import { storedBotRoute } from '../../../../shared/agent-store.mjs';
|
|
17
|
+
import { configuredAgentRouteCandidates } from '../../../../shared/agent-route-config.mjs';
|
|
18
|
+
import { CODING_MODE } from '../agent-mode.mjs';
|
|
19
|
+
|
|
20
|
+
export function ownerRouteFallbacks({ sessionMode, agentId, provider, model, config = null }) {
|
|
21
|
+
if (!agentId) return [];
|
|
22
|
+
const cfg = () => config || loadConfig({ secrets: false });
|
|
23
|
+
let stored;
|
|
24
|
+
if (sessionMode === CODING_MODE) {
|
|
25
|
+
stored = findPreset(cfg(), cfg()?.default);
|
|
26
|
+
} else {
|
|
27
|
+
// Before the bot split a bot's route is still in the config (Mixy's never).
|
|
28
|
+
stored = storedBotRoute(agentId) || (agentId === 'lead' ? null : configuredAgentRouteCandidates(cfg(), agentId)[0]);
|
|
29
|
+
}
|
|
30
|
+
if (!stored?.fallbacks?.length) return [];
|
|
31
|
+
let route;
|
|
32
|
+
try {
|
|
33
|
+
route = normalizeWorkflowRoute(stored);
|
|
34
|
+
} catch {
|
|
35
|
+
return [];
|
|
36
|
+
}
|
|
37
|
+
const onPrimary =
|
|
38
|
+
route &&
|
|
39
|
+
canonicalRouteProvider(route.provider) === canonicalRouteProvider(provider) &&
|
|
40
|
+
String(route.model) === String(model);
|
|
41
|
+
return onPrimary ? route.fallbacks || [] : [];
|
|
42
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// Steering / pending-message queue with sync buffering and atomic persistence.
|
|
2
|
-
import {
|
|
2
|
+
import { readJsonStateSync } from '../../../../shared/atomic-file.mjs';
|
|
3
3
|
import { loadSession } from '../store.mjs';
|
|
4
4
|
import {
|
|
5
5
|
currentPendingLifecycleToken,
|
|
@@ -602,14 +602,8 @@ export function _getPendingMessagesForSession(sessionId) {
|
|
|
602
602
|
const queued = [...(_sessionPendingMessages.get(sessionId) || []), ...(_pendingPersistBuffers.get(sessionId) || [])];
|
|
603
603
|
// The not-yet-migrated global spool can still hold this session's rows.
|
|
604
604
|
for (const path of [pendingMessagesPath(sessionId), legacyPendingMessagesPath()]) {
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
raw = readFileSync(path, 'utf8');
|
|
608
|
-
} catch (err) {
|
|
609
|
-
if (err?.code === 'ENOENT') continue;
|
|
610
|
-
throw err;
|
|
611
|
-
}
|
|
612
|
-
const persisted = normalizePendingStore(JSON.parse(raw)).sessions[sessionId];
|
|
605
|
+
// A damaged spool file is kept aside and reads as empty; it never throws.
|
|
606
|
+
const persisted = normalizePendingStore(readJsonStateSync(path, { fallback: null })).sessions[sessionId];
|
|
613
607
|
if (Array.isArray(persisted)) queued.push(...persisted);
|
|
614
608
|
}
|
|
615
609
|
return queued;
|
|
@@ -17,7 +17,7 @@ export const _pendingPersistTails = new Map();
|
|
|
17
17
|
export { pendingMessagesPath, touchPendingSessionEntry } from './pending-spool-path.mjs';
|
|
18
18
|
|
|
19
19
|
// Single spool transaction shape: every mutation touches only `sessionId`'s
|
|
20
|
-
// own shard file, locked, compact and
|
|
20
|
+
// own shard file, locked, compact and durable; `extra` only ever relaxes the
|
|
21
21
|
// lock timeout.
|
|
22
22
|
export function updateSpool(sessionId, mutate, extra = null) {
|
|
23
23
|
return updatePendingShard(sessionId, mutate, extra);
|
|
@@ -21,7 +21,8 @@ function storeIsEmpty(store) {
|
|
|
21
21
|
);
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
// One shard transaction: locked, compact,
|
|
24
|
+
// One shard transaction: locked, compact, durable (queued user messages must
|
|
25
|
+
// survive a crash; a damaged shard is kept aside by updateJsonAtomic). A shard emptied by the
|
|
25
26
|
// mutation (or found empty) is deleted under the same lock, so the directory
|
|
26
27
|
// holds only sessions that actually have queued rows.
|
|
27
28
|
async function updateShardFile(key, mutate, extra = null) {
|
|
@@ -33,7 +34,6 @@ async function updateShardFile(key, mutate, extra = null) {
|
|
|
33
34
|
compact: true,
|
|
34
35
|
lock: true,
|
|
35
36
|
mode: PENDING_MESSAGES_MODE,
|
|
36
|
-
fsync: false,
|
|
37
37
|
...extra,
|
|
38
38
|
});
|
|
39
39
|
if (storeIsEmpty(result)) {
|
|
@@ -50,7 +50,9 @@ async function updateShardFile(key, mutate, extra = null) {
|
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
function rowKey(row) {
|
|
53
|
-
return row && typeof row === 'object' && typeof row.id === 'string' && row.id
|
|
53
|
+
return row && typeof row === 'object' && typeof row.id === 'string' && row.id
|
|
54
|
+
? `id:${row.id}`
|
|
55
|
+
: `json:${JSON.stringify(row)}`;
|
|
54
56
|
}
|
|
55
57
|
|
|
56
58
|
// Idempotent merge of one legacy bucket into its shard: legacy rows (older)
|
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
// Prompt-layer rules builders. Source revision tracking lives separately so
|
|
2
2
|
// every layer observes deletions, replacements and timestamp rollbacks alike.
|
|
3
|
+
import { createHash } from 'node:crypto';
|
|
3
4
|
import { createRequire } from 'node:module';
|
|
4
5
|
import { join } from 'node:path';
|
|
5
6
|
import { resolvePluginData, mixdogRoot } from '../../../../shared/plugin-paths.mjs';
|
|
6
7
|
import { createRulesSourceCache } from './rules-source-cache.mjs';
|
|
8
|
+
import {
|
|
9
|
+
AGENT_MODE_DELEGATION,
|
|
10
|
+
MIXY_CONTACTS_INTRO,
|
|
11
|
+
orchestrationInstructions,
|
|
12
|
+
} from '../../runtime-core/orchestration.mjs';
|
|
7
13
|
|
|
8
14
|
// Phase B: Pool B Tier 2 content builder (common rules only).
|
|
9
15
|
// Loaded once per process via createRequire so the CJS module reaches us.
|
|
@@ -129,7 +135,7 @@ export function _buildLeadRules({ includeLeadBrief = true, part = 'common' } = {
|
|
|
129
135
|
);
|
|
130
136
|
}
|
|
131
137
|
|
|
132
|
-
// One agent-mode rule file (rules/agent-mode): 'conduct'
|
|
138
|
+
// One agent-mode rule file (rules/agent-mode): 'conduct' or 'mixy'.
|
|
133
139
|
export function _buildAgentModeRules({ part = 'conduct' } = {}) {
|
|
134
140
|
const PLUGIN_ROOT = mixdogRoot();
|
|
135
141
|
return buildCachedRules(
|
|
@@ -141,6 +147,30 @@ export function _buildAgentModeRules({ part = 'conduct' } = {}) {
|
|
|
141
147
|
);
|
|
142
148
|
}
|
|
143
149
|
|
|
150
|
+
// --- Rules revision ---
|
|
151
|
+
// The shipped rule texts a bot thread's prompt embeds — the shared tool
|
|
152
|
+
// policy (canonical variant), every LEAD.md part, the agent-mode files and
|
|
153
|
+
// the orchestration/delegation texts — as one hash. A bot thread stamps it
|
|
154
|
+
// at creation; another value (a release changed a rule) rebuilds its prompt
|
|
155
|
+
// once (session-runtime/tool-policy-refresh.mjs). Built from the cached
|
|
156
|
+
// builders, so a check costs a few stats.
|
|
157
|
+
export function promptRulesRevision() {
|
|
158
|
+
const hash = createHash('sha256');
|
|
159
|
+
const texts = [
|
|
160
|
+
_buildSharedRules(),
|
|
161
|
+
...['common', 'coding', 'agent', 'identity'].flatMap((part) =>
|
|
162
|
+
[true, false].map((includeLeadBrief) => _buildLeadRules({ includeLeadBrief, part }))
|
|
163
|
+
),
|
|
164
|
+
_buildAgentModeRules({ part: 'conduct' }),
|
|
165
|
+
_buildAgentModeRules({ part: 'mixy' }),
|
|
166
|
+
AGENT_MODE_DELEGATION,
|
|
167
|
+
MIXY_CONTACTS_INTRO,
|
|
168
|
+
...['none', 'focused', 'balanced', 'swarm'].map(orchestrationInstructions),
|
|
169
|
+
];
|
|
170
|
+
for (const text of texts) hash.update(`${text}\0`);
|
|
171
|
+
return hash.digest('hex').slice(0, 24);
|
|
172
|
+
}
|
|
173
|
+
|
|
144
174
|
export function _buildLeadMetaContext({ includeOutputStyle = true } = {}) {
|
|
145
175
|
const PLUGIN_ROOT = mixdogRoot();
|
|
146
176
|
const DATA_DIR = resolvePluginData();
|
|
@@ -162,6 +192,15 @@ export function _buildLeadMetaContext({ includeOutputStyle = true } = {}) {
|
|
|
162
192
|
// Trailing BP3 block: the configured response language. Kept out of BP2 so
|
|
163
193
|
// it is the last instruction before the conversation (see
|
|
164
194
|
// rules-builder.cjs buildLeadLanguageContent).
|
|
195
|
+
// The configured response language as {id, name}, or null (a rule's `language`
|
|
196
|
+
// condition compares the id; its text's {language} is the name).
|
|
197
|
+
export function _buildLeadLanguage() {
|
|
198
|
+
const DATA_DIR = resolvePluginData();
|
|
199
|
+
return buildCachedRules('buildLeadLanguage', 'lead language', [join(DATA_DIR, 'mixdog-config.json')], {
|
|
200
|
+
DATA_DIR,
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
|
|
165
204
|
export function _buildLeadLanguageContext() {
|
|
166
205
|
const DATA_DIR = resolvePluginData();
|
|
167
206
|
return buildCachedRules('buildLeadLanguageContent', 'lead language context', [join(DATA_DIR, 'mixdog-config.json')], {
|
|
@@ -298,6 +298,16 @@ export function markSessionToolOutputTail(id, tail) {
|
|
|
298
298
|
entry.toolOutputTail = text ? text.slice(-4000) : null;
|
|
299
299
|
entry.toolOutputTailAt = Date.now();
|
|
300
300
|
}
|
|
301
|
+
// An approval has no wait limit, and the progress watchdog treats a turn with
|
|
302
|
+
// `awaitingUser` as waiting on the user, not stalled. The user's answer is
|
|
303
|
+
// progress: a wait begins and ends with a fresh progress stamp, so the hours
|
|
304
|
+
// spent waiting are never counted as silence once the turn runs again.
|
|
305
|
+
function _stampApprovalProgress(entry) {
|
|
306
|
+
if (entry.closed || entry.controller?.signal?.aborted || TERMINAL_STAGES.has(entry.stage)) return;
|
|
307
|
+
const now = Date.now();
|
|
308
|
+
entry.lastProgressAt = now;
|
|
309
|
+
entry.updatedAt = now;
|
|
310
|
+
}
|
|
301
311
|
// A turn blocked on the user: a PreToolUse `ask` waiting for the tool
|
|
302
312
|
// approval only the user can give. Published as `awaitingUser: 'approval'` so
|
|
303
313
|
// status surfaces stop presenting the session as working. Counted, because one
|
|
@@ -309,6 +319,7 @@ export function beginSessionApprovalWait(id) {
|
|
|
309
319
|
if (!entry) return () => {};
|
|
310
320
|
entry.approvalWaits = (entry.approvalWaits || 0) + 1;
|
|
311
321
|
entry.awaitingUser = 'approval';
|
|
322
|
+
_stampApprovalProgress(entry);
|
|
312
323
|
// The waiting turn: the end transition carries the begin's turn even when
|
|
313
324
|
// the turn has settled (askStartedAt cleared) by the time it releases.
|
|
314
325
|
const meta = { turnAt: entry.askStartedAt || 0 };
|
|
@@ -321,6 +332,7 @@ export function beginSessionApprovalWait(id) {
|
|
|
321
332
|
entry.approvalWaits = Math.max(0, (entry.approvalWaits || 0) - 1);
|
|
322
333
|
if (entry.approvalWaits > 0) return;
|
|
323
334
|
entry.awaitingUser = null;
|
|
335
|
+
_stampApprovalProgress(entry);
|
|
324
336
|
emitSessionApprovalWaitChange(id, null, meta);
|
|
325
337
|
};
|
|
326
338
|
}
|
|
@@ -19,6 +19,25 @@ export function isTurnInFlight(entry) {
|
|
|
19
19
|
return IN_FLIGHT_STAGES.has(entry.stage);
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
+
// Sessions whose turn was handed to the runtime but has not claimed its
|
|
23
|
+
// controller yet (spawn dispatched, askSession still loading the session).
|
|
24
|
+
// The row already declares work; without this the pool cannot tell that
|
|
25
|
+
// first-turn gap from a worker it lost track of, and reads `unknown`.
|
|
26
|
+
const dispatchedTurns = new Map();
|
|
27
|
+
|
|
28
|
+
/** Runs `run` (the turn's dispatch) with `id` counted as working until it
|
|
29
|
+
* settles, covering the gap before the turn's own runtime entry is in flight. */
|
|
30
|
+
export async function whileTurnDispatched(id, run) {
|
|
31
|
+
dispatchedTurns.set(id, (dispatchedTurns.get(id) || 0) + 1);
|
|
32
|
+
try {
|
|
33
|
+
return await run();
|
|
34
|
+
} finally {
|
|
35
|
+
const left = dispatchedTurns.get(id) - 1;
|
|
36
|
+
if (left > 0) dispatchedTurns.set(id, left);
|
|
37
|
+
else dispatchedTurns.delete(id);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
22
41
|
const cleanLower = (value) =>
|
|
23
42
|
String(value || '')
|
|
24
43
|
.trim()
|
|
@@ -32,6 +51,7 @@ const cleanLower = (value) =>
|
|
|
32
51
|
export function inFlightSessionActivity() {
|
|
33
52
|
const working = new Set();
|
|
34
53
|
const agentWorking = new Set();
|
|
54
|
+
for (const id of dispatchedTurns.keys()) working.add(id);
|
|
35
55
|
for (const [id, entry] of runtimeState) {
|
|
36
56
|
if (!isTurnInFlight(entry)) continue;
|
|
37
57
|
working.add(id);
|