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
|
@@ -20,7 +20,8 @@ export function createRoomSupervisorCompletion(deps = {}) {
|
|
|
20
20
|
const log = deps.log || ((line) => process.stderr.write(line));
|
|
21
21
|
|
|
22
22
|
/** The decision for one step (parseRoomDecision), null for an unusable
|
|
23
|
-
* reply
|
|
23
|
+
* reply, `{ action: 'unmanaged' }` when no Maintainer model is configured;
|
|
24
|
+
* throws when the configured provider is unavailable. */
|
|
24
25
|
return async function decideRoomTurn(input = {}) {
|
|
25
26
|
const members = (Array.isArray(input?.members) ? input.members : [])
|
|
26
27
|
.filter((member) => member && typeof member.id === 'string' && member.id)
|
|
@@ -32,12 +33,12 @@ export function createRoomSupervisorCompletion(deps = {}) {
|
|
|
32
33
|
if (!members.length) return null;
|
|
33
34
|
const config = load();
|
|
34
35
|
// The Maintainer's own route only: a step runs after every turn, so it
|
|
35
|
-
// never falls back to the default (Lead) model the user pays most for
|
|
36
|
-
//
|
|
36
|
+
// never falls back to the default (Lead) model the user pays most for.
|
|
37
|
+
// Without one the room is unmoderated: the members called answer once.
|
|
37
38
|
const route = resolveRoute({ agent: 'cycle1-agent', config, includeDefault: false });
|
|
38
39
|
const providerName = String(route?.provider || '').trim();
|
|
39
40
|
const model = String(route?.model || '').trim();
|
|
40
|
-
if (!providerName || !model)
|
|
41
|
+
if (!providerName || !model) return { action: 'unmanaged' };
|
|
41
42
|
const signal = AbortSignal.timeout(TIMEOUT_MS);
|
|
42
43
|
await initialize(config.providers || {}, { signal });
|
|
43
44
|
const provider = providerFor(providerName);
|
|
@@ -237,6 +237,8 @@ function traceAgentUsage({
|
|
|
237
237
|
chainContinuous,
|
|
238
238
|
continuationResetReason,
|
|
239
239
|
inputTokensInclusive,
|
|
240
|
+
// Anthropic: per-block prefix hashes of the request (providers/lib/anthropic-prefix-trace.mjs).
|
|
241
|
+
prefixBlocks,
|
|
240
242
|
}) {
|
|
241
243
|
const identity = currentUsageContext();
|
|
242
244
|
provider = identity?.provider || provider;
|
|
@@ -291,6 +293,7 @@ function traceAgentUsage({
|
|
|
291
293
|
service_tier: resolvedServiceTier,
|
|
292
294
|
raw_usage: rawUsage || null,
|
|
293
295
|
...chainFields,
|
|
296
|
+
...(prefixBlocks ? { prefix_blocks: prefixBlocks } : {}),
|
|
294
297
|
},
|
|
295
298
|
});
|
|
296
299
|
}
|
|
@@ -51,6 +51,8 @@ export function buildCacheBreakPayload(record = {}) {
|
|
|
51
51
|
input_prefix_mismatch_expected_hash: cleanHash(record.inputPrefixMismatchExpectedHash),
|
|
52
52
|
input_prefix_mismatch_actual_type: cleanText(record.inputPrefixMismatchActualType),
|
|
53
53
|
input_prefix_mismatch_actual_hash: cleanHash(record.inputPrefixMismatchActualHash),
|
|
54
|
+
changed_blocks: cleanText(record.changedBlocks),
|
|
55
|
+
system_markers_changed: typeof record.markersChanged === 'boolean' ? record.markersChanged : null,
|
|
54
56
|
};
|
|
55
57
|
return Object.fromEntries(Object.entries(payload).filter(([, value]) => value !== null));
|
|
56
58
|
}
|
|
@@ -77,6 +79,8 @@ function formatCacheBreakLine(record = {}) {
|
|
|
77
79
|
['previousCachedPrefixTokens', payload.previous_cached_prefix_tokens],
|
|
78
80
|
['idleMs', payload.idle_ms],
|
|
79
81
|
['noGuardBaseline', payload.missing_prefix_guard_baseline],
|
|
82
|
+
['changedBlocks', payload.changed_blocks],
|
|
83
|
+
['systemMarkersChanged', payload.system_markers_changed],
|
|
80
84
|
].filter(([, value]) => value !== null && value !== undefined);
|
|
81
85
|
return `[cache-break] ${fields.map(([key, value]) => (typeof value === 'string' ? `${key}=${JSON.stringify(value)}` : `${key}=${value}`)).join(' ')}`;
|
|
82
86
|
}
|
|
@@ -144,6 +144,8 @@ export function normalizePreset(preset) {
|
|
|
144
144
|
// Auto effort is on unless the preset opts out; only the off state is kept.
|
|
145
145
|
if (preset.autoEffort === false) out.autoEffort = false;
|
|
146
146
|
out.tools = ['full', 'readonly', 'mcp'].includes(preset.tools) ? preset.tools : 'full';
|
|
147
|
+
// The Lead preset's fallback models (validated when written, by the route normalizer).
|
|
148
|
+
if (Array.isArray(preset.fallbacks) && preset.fallbacks.length) out.fallbacks = preset.fallbacks;
|
|
147
149
|
return out;
|
|
148
150
|
}
|
|
149
151
|
|
|
@@ -127,9 +127,16 @@ function canonicalizeAutoClearStorage(value) {
|
|
|
127
127
|
const provider = String(key || '')
|
|
128
128
|
.trim()
|
|
129
129
|
.toLowerCase();
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
130
|
+
// 0 (also 'unlimited' / 'never') is the stored "never auto-clear" value
|
|
131
|
+
// (runtime-core/config-helpers.mjs AUTO_CLEAR_UNLIMITED).
|
|
132
|
+
const text = typeof candidate === 'string' ? candidate.trim().toLowerCase() : null;
|
|
133
|
+
let duration;
|
|
134
|
+
if (text === 'unlimited' || text === 'never') duration = 0;
|
|
135
|
+
else if (text === '') duration = Number.NaN;
|
|
136
|
+
else duration = Number(candidate);
|
|
137
|
+
if (!provider || candidate === null || typeof candidate === 'boolean' || !Number.isFinite(duration) || duration < 0)
|
|
138
|
+
continue;
|
|
139
|
+
providerIdleMs[provider] = duration === 0 ? 0 : Math.max(60_000, Math.round(duration));
|
|
133
140
|
}
|
|
134
141
|
delete next.thresholdMs;
|
|
135
142
|
delete next.idleMillis;
|
|
@@ -4,6 +4,7 @@ import { mergeStoredProviders } from './config-providers-merge.mjs';
|
|
|
4
4
|
import { normalizeExtensionScopes } from '../../shared/extension-scopes.mjs';
|
|
5
5
|
import { applyConfigPatch, diffConfig } from '../../shared/config-patch.mjs';
|
|
6
6
|
import { normalizeWorkflowSelection } from '../../shared/orchestration.mjs';
|
|
7
|
+
import { AUTO_EFFORT_BASE, autoEffortBase } from './providers/auto-effort.mjs';
|
|
7
8
|
import { DEFAULT_INSTRUCTION_FILES_MODE, normalizeInstructionFilesMode } from '../../shared/instruction-files-mode.mjs';
|
|
8
9
|
import {
|
|
9
10
|
DEFAULT_DISABLED_AGENT_ROSTER,
|
|
@@ -205,6 +206,13 @@ function storedInstructionFiles(agent) {
|
|
|
205
206
|
return mode === DEFAULT_INSTRUCTION_FILES_MODE ? {} : { instructionFiles: mode };
|
|
206
207
|
}
|
|
207
208
|
|
|
209
|
+
// `autoEffortBase` (providers/auto-effort.mjs): only a valid non-default level
|
|
210
|
+
// is kept; absent means medium.
|
|
211
|
+
function storedAutoEffortBase(agent) {
|
|
212
|
+
const base = autoEffortBase(agent?.autoEffortBase);
|
|
213
|
+
return base === AUTO_EFFORT_BASE ? {} : { autoEffortBase: base };
|
|
214
|
+
}
|
|
215
|
+
|
|
208
216
|
export function loadConfig(options = {}) {
|
|
209
217
|
const includeSecrets = options.secrets !== false;
|
|
210
218
|
// `secrets: 'presence'`: credentials are detected (env, OAuth files, which
|
|
@@ -269,6 +277,7 @@ export function loadConfig(options = {}) {
|
|
|
269
277
|
disabledAgents: legacyDisabledAgents ? disabledAgentIds(raw) : effectiveDisabledAgents(raw),
|
|
270
278
|
...(raw.memoryTools && typeof raw.memoryTools === 'object' ? { memoryTools: { ...raw.memoryTools } } : {}),
|
|
271
279
|
...storedInstructionFiles(raw),
|
|
280
|
+
...storedAutoEffortBase(raw),
|
|
272
281
|
...normalizeWorkflowSelection(raw),
|
|
273
282
|
profile: normalizeProfileConfig(raw.profile),
|
|
274
283
|
skills: normalizeSkillsConfig(raw.skills),
|
|
@@ -463,6 +472,8 @@ function buildAgentSaveBuilder(config) {
|
|
|
463
472
|
else delete next.aiSessionTitles;
|
|
464
473
|
delete next.instructionFiles;
|
|
465
474
|
Object.assign(next, storedInstructionFiles(config));
|
|
475
|
+
delete next.autoEffortBase;
|
|
476
|
+
Object.assign(next, storedAutoEffortBase(config));
|
|
466
477
|
delete next.workflowRoutes;
|
|
467
478
|
// Defaults live in code: values equal to the current default are not stored.
|
|
468
479
|
return storedAgentForm(removeRetiredAgentFields(next));
|
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
import { createHash } from 'node:crypto';
|
|
4
4
|
import { existsSync, readdirSync } from 'node:fs';
|
|
5
|
-
import { join } from 'node:path';
|
|
5
|
+
import { basename, dirname, join } from 'node:path';
|
|
6
6
|
import { compareCodePoints } from '../../../shared/code-point-order.mjs';
|
|
7
|
+
import { BOTS_DIR, MIXY_BOT_ID, botStoreActive, isStoreBot, mixyIdentityDir } from '../../../shared/agent-store.mjs';
|
|
7
8
|
import { mixdogRoot } from '../../../shared/plugin-paths.mjs';
|
|
8
9
|
import { readMarkdownDocument } from '../../../shared/markdown-frontmatter.mjs';
|
|
9
10
|
import { listHiddenAgentsByKind, getAgentCatalogShareAgents } from '../internal-agents.mjs';
|
|
@@ -89,9 +90,35 @@ function agentSectionDirs(pluginRoot) {
|
|
|
89
90
|
} catch {
|
|
90
91
|
/* unresolvable data dir — built-in roles still load */
|
|
91
92
|
}
|
|
93
|
+
// Bots of the store (agent-store.mjs), last: a bot's own folder wins over
|
|
94
|
+
// the agents/ original the split left behind.
|
|
95
|
+
const root = userDataRoot();
|
|
96
|
+
if (root && botStoreActive(root)) dirs.push(join(root, BOTS_DIR));
|
|
92
97
|
return dirs;
|
|
93
98
|
}
|
|
94
99
|
|
|
100
|
+
// The user data dir (parent of agents/), or '' when it cannot be resolved.
|
|
101
|
+
function userDataRoot() {
|
|
102
|
+
try {
|
|
103
|
+
const userDir = mixdogGlobalDir('agents');
|
|
104
|
+
return userDir ? dirname(userDir) : '';
|
|
105
|
+
} catch {
|
|
106
|
+
return '';
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// A store bot's own folder, or ''.
|
|
111
|
+
function storeBotDir(agent) {
|
|
112
|
+
const root = userDataRoot();
|
|
113
|
+
return root && isStoreBot(root, agent) ? join(root, BOTS_DIR, agent) : '';
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Mixy's identity folder: bots/mixy with the store, agents/lead before.
|
|
117
|
+
function mixyDir() {
|
|
118
|
+
const root = userDataRoot();
|
|
119
|
+
return root ? mixyIdentityDir(root) : '';
|
|
120
|
+
}
|
|
121
|
+
|
|
95
122
|
function loadAgentSections(pluginRoot) {
|
|
96
123
|
// agents/ accepts both the compatibility flat layout and the current
|
|
97
124
|
// nested agents/<agent>/AGENT.md layout.
|
|
@@ -117,6 +144,7 @@ function loadAgentSections(pluginRoot) {
|
|
|
117
144
|
// Mixy's own AGENT.md (agents/lead/) rides only Mixy's agent-mode
|
|
118
145
|
// prompt (loadMixyRoleSection), never another role catalog.
|
|
119
146
|
if (!name || !raw || name === 'lead') continue;
|
|
147
|
+
if (name === MIXY_BOT_ID && basename(agentsDir) === BOTS_DIR) continue;
|
|
120
148
|
const { body } = readMarkdownDocument(raw);
|
|
121
149
|
if (!body) continue;
|
|
122
150
|
byName.set(name, roleSection(name, body));
|
|
@@ -255,6 +283,12 @@ export function truncatePersona(text, max = PERSONA_MAX_CHARS) {
|
|
|
255
283
|
export function loadAgentPersonaSection(agent) {
|
|
256
284
|
if (typeof agent !== 'string' || !PERSONA_AGENT_ID.test(agent) || agent.includes('..')) return '';
|
|
257
285
|
const isLead = agent === 'lead';
|
|
286
|
+
// Mixy's persona is in its own folder; a store bot's in its bots/ folder.
|
|
287
|
+
const own = isLead ? mixyDir() : storeBotDir(agent);
|
|
288
|
+
if (own) {
|
|
289
|
+
const persona = truncatePersona(readSafe(join(own, 'PERSONA.md')) || '');
|
|
290
|
+
return persona ? personaSection(persona) : '';
|
|
291
|
+
}
|
|
258
292
|
const pluginRoot = mixdogRoot();
|
|
259
293
|
const roots = [];
|
|
260
294
|
try {
|
|
@@ -272,17 +306,21 @@ export function loadAgentPersonaSection(agent) {
|
|
|
272
306
|
if (isLead) continue;
|
|
273
307
|
return '';
|
|
274
308
|
}
|
|
275
|
-
return
|
|
276
|
-
'## Persona',
|
|
277
|
-
'',
|
|
278
|
-
'Tone and style guide for how you speak, address the user and carry yourself. It never overrides tool, safety or role rules; those always win.',
|
|
279
|
-
'',
|
|
280
|
-
persona,
|
|
281
|
-
].join('\n');
|
|
309
|
+
return personaSection(persona);
|
|
282
310
|
}
|
|
283
311
|
return '';
|
|
284
312
|
}
|
|
285
313
|
|
|
314
|
+
function personaSection(persona) {
|
|
315
|
+
return [
|
|
316
|
+
'## Persona',
|
|
317
|
+
'',
|
|
318
|
+
'Tone and style guide for how you speak, address the user and carry yourself. It never overrides tool, safety or role rules; those always win.',
|
|
319
|
+
'',
|
|
320
|
+
persona,
|
|
321
|
+
].join('\n');
|
|
322
|
+
}
|
|
323
|
+
|
|
286
324
|
// --- Mixy's working style (agents/lead/AGENT.md, user data dir) ---
|
|
287
325
|
// The user-editable 일하는 방식 of Mixy, framed like any agent's role section.
|
|
288
326
|
// Agent mode only; empty or missing means no section. Re-read per
|
|
@@ -290,8 +328,8 @@ export function loadAgentPersonaSection(agent) {
|
|
|
290
328
|
export function loadMixyRoleSection() {
|
|
291
329
|
let raw = '';
|
|
292
330
|
try {
|
|
293
|
-
const
|
|
294
|
-
raw =
|
|
331
|
+
const dir = mixyDir();
|
|
332
|
+
raw = dir ? readSafe(join(dir, 'AGENT.md')) || '' : '';
|
|
295
333
|
} catch {
|
|
296
334
|
return '';
|
|
297
335
|
}
|
|
@@ -306,6 +344,15 @@ export function loadMixyRoleSection() {
|
|
|
306
344
|
// (the Lead configuration, id `lead`) has its own line, under the display name
|
|
307
345
|
// the user gave it (session/mixy-name.mjs), Mixy by default.
|
|
308
346
|
function agentManifest(agent) {
|
|
347
|
+
const own = storeBotDir(agent);
|
|
348
|
+
if (own) {
|
|
349
|
+
try {
|
|
350
|
+
const value = JSON.parse(readSafe(join(own, 'agent.json')) || '{}');
|
|
351
|
+
return value && typeof value === 'object' ? value : {};
|
|
352
|
+
} catch {
|
|
353
|
+
return {};
|
|
354
|
+
}
|
|
355
|
+
}
|
|
309
356
|
const roots = [];
|
|
310
357
|
try {
|
|
311
358
|
const userDir = mixdogGlobalDir('agents');
|
|
@@ -328,6 +375,14 @@ function agentManifest(agent) {
|
|
|
328
375
|
return {};
|
|
329
376
|
}
|
|
330
377
|
|
|
378
|
+
/** The name a bot goes by (its manifest name, Mixy's display name), else its id. */
|
|
379
|
+
export function agentDisplayName(agent) {
|
|
380
|
+
if (agent === 'lead') return mixyDisplayName();
|
|
381
|
+
if (typeof agent !== 'string' || !PERSONA_AGENT_ID.test(agent) || agent.includes('..')) return String(agent || '');
|
|
382
|
+
const name = agentManifest(agent).name;
|
|
383
|
+
return (typeof name === 'string' ? name.replace(/\s+/g, ' ').trim() : '') || agent;
|
|
384
|
+
}
|
|
385
|
+
|
|
331
386
|
export function agentModeIdentityLine(agent) {
|
|
332
387
|
if (agent === 'lead') return `You are ${mixyDisplayName()}, the user's assistant in Mixdog.`;
|
|
333
388
|
if (typeof agent !== 'string' || !PERSONA_AGENT_ID.test(agent) || agent.includes('..')) return '';
|
|
@@ -344,9 +399,13 @@ export function agentModeIdentityLine(agent) {
|
|
|
344
399
|
// the shipped tree — as one hash. A session stamps it when its prompt is
|
|
345
400
|
// composed; another value means the profile was edited since
|
|
346
401
|
// (session-runtime/tool-policy-refresh.mjs refreshAgentProfile). '' for an
|
|
347
|
-
// invalid id.
|
|
348
|
-
|
|
402
|
+
// invalid id. A coding Lead (`lead` outside Mixy's own thread) embeds no
|
|
403
|
+
// profile file at all, so its stamp is a constant: editing Mixy never
|
|
404
|
+
// rebuilds a coding session's prompt.
|
|
405
|
+
export const CODING_LEAD_PROFILE_REVISION = 'coding-lead';
|
|
406
|
+
export function agentProfileRevision(agent, { mixy = true } = {}) {
|
|
349
407
|
if (typeof agent !== 'string' || !PERSONA_AGENT_ID.test(agent) || agent.includes('..')) return '';
|
|
408
|
+
if (agent === 'lead' && !mixy) return CODING_LEAD_PROFILE_REVISION;
|
|
350
409
|
const roots = [mixdogGlobalDir('agents')];
|
|
351
410
|
const pluginRoot = mixdogRoot();
|
|
352
411
|
if (pluginRoot) roots.push(join(pluginRoot, 'agents'));
|
|
@@ -356,6 +415,13 @@ export function agentProfileRevision(agent) {
|
|
|
356
415
|
hash.update(`${root}\0${file}\0${readSafe(join(root, agent, file)) ?? '\u0001'}\0`);
|
|
357
416
|
}
|
|
358
417
|
}
|
|
418
|
+
// Mixy's or a store bot's own folder, when it has one.
|
|
419
|
+
const own = agent === 'lead' ? mixyDir() : storeBotDir(agent);
|
|
420
|
+
if (own && own !== join(roots[0] || '', agent)) {
|
|
421
|
+
for (const file of ['agent.json', 'AGENT.md', 'PERSONA.md']) {
|
|
422
|
+
hash.update(`${own}\0${file}\0${readSafe(join(own, file)) ?? '\u0001'}\0`);
|
|
423
|
+
}
|
|
424
|
+
}
|
|
359
425
|
return hash.digest('hex').slice(0, 24);
|
|
360
426
|
}
|
|
361
427
|
|
|
@@ -417,8 +483,8 @@ export function composeSystemPrompt(opts) {
|
|
|
417
483
|
? loadMixyRoleSection()
|
|
418
484
|
: loadScopedRoleInstructions(opts.agent || null, opts.provider || null);
|
|
419
485
|
}
|
|
420
|
-
// Persona follows the role;
|
|
421
|
-
//
|
|
486
|
+
// Persona follows the role; Mixy's own thread carries Mixy's persona
|
|
487
|
+
// (bots/mixy/PERSONA.md) — a coding Lead's prompt never does (skipPersona).
|
|
422
488
|
const personaContext = opts.agent && !opts.skipPersona ? loadAgentPersonaSection(opts.agent) : '';
|
|
423
489
|
const coreMemory = skip.memory ? '' : trimmedPromptSlice(opts.coreMemoryContext);
|
|
424
490
|
// User AGENTS.md / CLAUDE.md block (context/instruction-files.mjs), already
|
|
@@ -431,7 +497,7 @@ export function composeSystemPrompt(opts) {
|
|
|
431
497
|
// variants, AGENT_MODE.md, the sub-agent catalog (the same for every
|
|
432
498
|
// agent other than Mixy);
|
|
433
499
|
// 3. Mixy only — MIXY.md and its contact-agent catalog;
|
|
434
|
-
// 4. per session or agent, last —
|
|
500
|
+
// 4. per session or agent, last — identity, caller prompt,
|
|
435
501
|
// role, persona, instruction files and core memory (changes most).
|
|
436
502
|
const sessionMarkerCore = joinPromptSlices([
|
|
437
503
|
trimmedPromptSlice(opts.workflowContext),
|
|
@@ -442,7 +508,6 @@ export function composeSystemPrompt(opts) {
|
|
|
442
508
|
trimmedPromptSlice(opts.agentCatalogContext),
|
|
443
509
|
opts.mixyRules || '',
|
|
444
510
|
trimmedPromptSlice(opts.contactCatalogContext),
|
|
445
|
-
opts.routineRules || '',
|
|
446
511
|
opts.identityContext || '',
|
|
447
512
|
opts.userPrompt || '',
|
|
448
513
|
roleInstructionContext,
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
// or a project may use. Every installed connector is on by default for every
|
|
3
3
|
// agent and project, existing and future ones; a policy only switches some off:
|
|
4
4
|
// agents/<id>/agent.json connectors: { off: [serverId…], tools?: { [serverId]: { [tool]: permission } } }
|
|
5
|
+
// (bots/<id>/ for a store bot; Mixy — runtime id `lead` — in her identity folder)
|
|
5
6
|
// <data>/project-connectors.json { projects: { [projectRoot]: { off: [serverId…] } } }
|
|
6
7
|
// `tools` keeps per-tool overrides (auto | needs_approval | disabled); a tool
|
|
7
8
|
// without one is auto, except a catalog connector's high-risk tools, which
|
|
@@ -12,10 +13,16 @@
|
|
|
12
13
|
// connected tool, so the schema and the BP2 manifest stay shared.
|
|
13
14
|
import { readFileSync, statSync } from 'node:fs';
|
|
14
15
|
import { join } from 'node:path';
|
|
16
|
+
import { holdsNoData, parseJsonText, readJsonStateSync } from '../../../shared/atomic-file.mjs';
|
|
17
|
+
|
|
18
|
+
const NO_DATA = new Error('the file holds no data');
|
|
15
19
|
import { cwdWithinProjects } from '../../../shared/extension-scopes.mjs';
|
|
16
20
|
import { resolvePluginData } from '../../../shared/plugin-paths.mjs';
|
|
21
|
+
import { mixyIdentityDir, userDefinitionDir } from '../../../shared/agent-store.mjs';
|
|
17
22
|
import { isSelfMcpToolName, parseMcpToolName } from '../../../shared/tool-primitives.mjs';
|
|
18
23
|
import { connectorToolDefault } from '../../../shared/connector-catalog.mjs';
|
|
24
|
+
import { MIXY_AGENT_ID } from '../session/agent-home.mjs';
|
|
25
|
+
import { AGENT_MODE, sessionModeOf } from '../session/agent-mode.mjs';
|
|
19
26
|
import { serverConnector } from './server-connectors.mjs';
|
|
20
27
|
|
|
21
28
|
export const CONNECTOR_PERMISSIONS = Object.freeze(['auto', 'needs_approval', 'disabled']);
|
|
@@ -126,9 +133,25 @@ function readJson(path, parse) {
|
|
|
126
133
|
return error?.code === 'ENOENT' || error?.code === 'ENOTDIR' ? null : unreadable(path, error);
|
|
127
134
|
}
|
|
128
135
|
try {
|
|
129
|
-
|
|
136
|
+
if (holdsNoData(text)) throw NO_DATA;
|
|
137
|
+
return parse(parseJsonText(text));
|
|
130
138
|
} catch (error) {
|
|
131
|
-
return
|
|
139
|
+
return recoverDamaged(path, parse, error);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// A damaged policy (empty, NUL-filled, torn, invalid) must never fail open.
|
|
144
|
+
// With a valid last good copy `<file>.bak` the damaged file is kept aside and
|
|
145
|
+
// the copy restored, so the user's deny list survives. Without one the file
|
|
146
|
+
// stays where it is (`keepWithoutBackup`) and every connector stays off until
|
|
147
|
+
// the policy is saved again — moving it aside would make the next read "no
|
|
148
|
+
// policy" (all on). A busy recovery lock also answers deny-all.
|
|
149
|
+
function recoverDamaged(path, parse, error) {
|
|
150
|
+
try {
|
|
151
|
+
const value = readJsonStateSync(path, { validate: parse, fallback: DENY_ALL_CONNECTORS, keepWithoutBackup: true });
|
|
152
|
+
return value === DENY_ALL_CONNECTORS ? unreadable(path, error) : value;
|
|
153
|
+
} catch (recoveryError) {
|
|
154
|
+
return unreadable(path, recoveryError);
|
|
132
155
|
}
|
|
133
156
|
}
|
|
134
157
|
|
|
@@ -145,11 +168,22 @@ export function readConnectorsFile(path) {
|
|
|
145
168
|
return readJson(path, (manifest) => parseConnectorPolicy(manifest?.connectors));
|
|
146
169
|
}
|
|
147
170
|
|
|
148
|
-
/** The agent's saved policy under `dataDir`, or null when it has none.
|
|
171
|
+
/** The agent's saved policy under `dataDir`, or null when it has none. Mixy's
|
|
172
|
+
* runtime id is `lead`: her policy is in her identity folder (bots/mixy once
|
|
173
|
+
* the bot store is active, agents/lead before), the file her profile writes. */
|
|
149
174
|
export function agentConnectors(agentId, dataDir = resolvePluginData()) {
|
|
150
175
|
const id = clean(agentId);
|
|
151
176
|
if (!id || !AGENT_DIR_ID.test(id)) return null;
|
|
152
|
-
|
|
177
|
+
const dir = id === MIXY_AGENT_ID ? mixyIdentityDir(dataDir) : userDefinitionDir(dataDir, id);
|
|
178
|
+
return cachedRead(join(dir, 'agent.json'), readConnectorsFile);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/** The agent whose connector policy `session` runs under. A coding Lead shares
|
|
182
|
+
* Mixy's runtime id `lead` but is not her: the policy her profile edits is
|
|
183
|
+
* hers alone, so a coding Lead has none ('') and only its Project's applies. */
|
|
184
|
+
export function connectorPolicyAgentOf(session) {
|
|
185
|
+
const agent = clean(session?.agent);
|
|
186
|
+
return agent === MIXY_AGENT_ID && sessionModeOf(session) !== AGENT_MODE ? '' : agent;
|
|
153
187
|
}
|
|
154
188
|
|
|
155
189
|
/** Uncached: the project policy file → `[{ root, off }]`, null without one,
|
|
@@ -185,6 +219,65 @@ export function connectorToolPermission(policy, toolOrName) {
|
|
|
185
219
|
return policy?.tools?.[mcp.server]?.[mcp.tool] || connectorToolDefault(serverConnector(mcp.server), mcp.tool);
|
|
186
220
|
}
|
|
187
221
|
|
|
222
|
+
const PERMISSION_RANK = Object.freeze({ disabled: 0, needs_approval: 1, auto: 2 });
|
|
223
|
+
export const NO_WIDEN_MESSAGE = 'This change would widen what the bot may do without asking; make it on the desktop.';
|
|
224
|
+
|
|
225
|
+
/** Whether replacing the stored policy `before` (a stored value, a parsed
|
|
226
|
+
* policy or null) with `after` (`{ off, tools }` or null) could give any
|
|
227
|
+
* tool more authority, judged on EFFECTIVE permissions: a connector switched
|
|
228
|
+
* back on, a tool allowed, or an override removed (the tool then runs on its
|
|
229
|
+
* default, which is `needs_approval` for a catalog connector's high-risk
|
|
230
|
+
* tools and `auto` otherwise). A legacy allow list or an unreadable policy is
|
|
231
|
+
* not compared: it counts as widening. */
|
|
232
|
+
export function connectorPolicyWidens(before, after) {
|
|
233
|
+
let old;
|
|
234
|
+
try {
|
|
235
|
+
old = before == null ? { off: [], tools: {} } : parseConnectorPolicy(before);
|
|
236
|
+
} catch {
|
|
237
|
+
return true;
|
|
238
|
+
}
|
|
239
|
+
if (old.allow) return true;
|
|
240
|
+
const next = after == null ? { off: [], tools: {} } : after;
|
|
241
|
+
const offBefore = new Set(old.off);
|
|
242
|
+
const offAfter = new Set(next.off || []);
|
|
243
|
+
for (const server of offBefore) if (!offAfter.has(server)) return true;
|
|
244
|
+
const toolsBefore = old.tools || {};
|
|
245
|
+
const toolsAfter = next.tools || {};
|
|
246
|
+
for (const server of new Set([...Object.keys(toolsBefore), ...Object.keys(toolsAfter)])) {
|
|
247
|
+
const tools = new Set([...Object.keys(toolsBefore[server] || {}), ...Object.keys(toolsAfter[server] || {})]);
|
|
248
|
+
for (const tool of tools) {
|
|
249
|
+
// No override: at least asks / at most runs freely.
|
|
250
|
+
const was = offBefore.has(server) ? 0 : (PERMISSION_RANK[toolsBefore[server]?.[tool]] ?? 1);
|
|
251
|
+
const now = offAfter.has(server) ? 0 : (PERMISSION_RANK[toolsAfter[server]?.[tool]] ?? 2);
|
|
252
|
+
if (now > was) return true;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
return false;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/** Throws NO_WIDEN_MESSAGE when `after` could widen `before` (see connectorPolicyWidens). */
|
|
259
|
+
export function assertConnectorPolicyNotWidened(before, after) {
|
|
260
|
+
if (connectorPolicyWidens(before, after)) throw new Error(NO_WIDEN_MESSAGE);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
let toolPermissionWriter = null;
|
|
264
|
+
/** The host attaches the one writer of an agent's per-tool permission (the
|
|
265
|
+
* agent editor keeps every other agent.json key). */
|
|
266
|
+
export function setConnectorToolPermissionWriter(write) {
|
|
267
|
+
toolPermissionWriter = typeof write === 'function' ? write : null;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/** Save `permission` for the connector tool `toolOrName` under `agentId`'s own
|
|
271
|
+
* policy. False when it is no connector tool or no writer is attached. */
|
|
272
|
+
export async function writeAgentMcpToolPermission(agentId, toolOrName, permission) {
|
|
273
|
+
const mcp = parseMcpToolName(toolOrName);
|
|
274
|
+
if (!toolPermissionWriter || !mcp || isSelfMcpToolName(toolOrName) || !CONNECTOR_PERMISSIONS.includes(permission)) {
|
|
275
|
+
return false;
|
|
276
|
+
}
|
|
277
|
+
await toolPermissionWriter(agentId, mcp.server, mcp.tool, permission);
|
|
278
|
+
return true;
|
|
279
|
+
}
|
|
280
|
+
|
|
188
281
|
/** The permission `agentId` has for the MCP tool `toolOrName`. */
|
|
189
282
|
export function agentMcpToolPermission(agentId, toolOrName) {
|
|
190
283
|
if (!parseMcpToolName(toolOrName)) return 'auto';
|
|
@@ -117,14 +117,11 @@ async function enumerate({ strict = false } = {}) {
|
|
|
117
117
|
* names and (POSIX) process groups. Rejects instead of returning a partial
|
|
118
118
|
* table, so callers can tell "nothing found" from "could not look".
|
|
119
119
|
*
|
|
120
|
-
*
|
|
121
|
-
*
|
|
122
|
-
*
|
|
123
|
-
*
|
|
124
|
-
*
|
|
125
|
-
* confirmation by a whole re-check. Such a caller starts a read when none
|
|
126
|
-
* runs, else joins the one queued to begin when the running read settles —
|
|
127
|
-
* every observer asking meanwhile shares it. At most one enumerator runs at
|
|
120
|
+
* Every caller sees a table from a read begun after it asked: an earlier
|
|
121
|
+
* read may miss newly spawned descendants before a kill, or report a killed
|
|
122
|
+
* tree alive afterwards. A caller starts a read when none runs, else joins
|
|
123
|
+
* the one queued to begin when the running read settles — every caller
|
|
124
|
+
* asking meanwhile shares it. At most one enumerator runs at
|
|
128
125
|
* a time, however many shells settle or watch at once (each one is a
|
|
129
126
|
* PowerShell process on Windows; one per settle and watch pass compounded
|
|
130
127
|
* machine load into multi-second daemon stalls). */
|
|
@@ -137,8 +134,7 @@ function startTableRead() {
|
|
|
137
134
|
tableInFlight = read;
|
|
138
135
|
return read;
|
|
139
136
|
}
|
|
140
|
-
export function readProcessTable(
|
|
141
|
-
if (shared && tableInFlight) return tableInFlight;
|
|
137
|
+
export function readProcessTable() {
|
|
142
138
|
if (nextTable) return nextTable;
|
|
143
139
|
if (!tableInFlight) return startTableRead();
|
|
144
140
|
const settled = () => {};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { setMaxListeners } from 'node:events';
|
|
2
|
-
import { mkdirSync
|
|
2
|
+
import { mkdirSync } from 'node:fs';
|
|
3
|
+
import { writeFileAtomicSync } from '../../../shared/atomic-file.mjs';
|
|
3
4
|
import { writeFile } from 'node:fs/promises';
|
|
4
5
|
import {
|
|
5
6
|
MAX_ATTACHMENT_BLOB_BYTES,
|
|
@@ -772,9 +773,11 @@ function spillMcpBinary(buffer, extension) {
|
|
|
772
773
|
const path = join(dir, `mcp-${hash}.${extension}`);
|
|
773
774
|
try {
|
|
774
775
|
mkdirSync(dir, { recursive: true });
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
776
|
+
// Named by its content hash: whole-file create-if-absent (a crash never
|
|
777
|
+
// leaves a torn file under the name that would be trusted as the content).
|
|
778
|
+
writeFileAtomicSync(path, buffer, { createOnly: true });
|
|
779
|
+
} catch {
|
|
780
|
+
return null;
|
|
778
781
|
}
|
|
779
782
|
return path;
|
|
780
783
|
}
|