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
|
@@ -29,9 +29,52 @@ import { routeChain, validateRouteChainProviders } from '../../runtime/shared/mo
|
|
|
29
29
|
// lead preset, so an agent that reused it silently rewrote Main's effort/fast
|
|
30
30
|
// for the next session. The agent's own stored route is the fallback instead,
|
|
31
31
|
// and the bucket is never written here.
|
|
32
|
+
// Tuning-only edits keep the stored model's effort/fast/modelParameters;
|
|
33
|
+
// a model change starts from the resolved defaults. Fast is then clamped
|
|
34
|
+
// to what the selected model supports. The ONE normalizer of a chain entry:
|
|
35
|
+
// agents, bots, Mixy and the Lead's fallbacks all pass through it.
|
|
36
|
+
export async function resolveChainEntry(deps, requested, stored) {
|
|
37
|
+
const { getConfig, resolveRoute, lookupModelMeta, ensureProvidersReady } = deps;
|
|
38
|
+
let selectedRoute = resolveRoute(getConfig(), requested);
|
|
39
|
+
const sameModel =
|
|
40
|
+
clean(selectedRoute.provider) === clean(stored.provider) && clean(selectedRoute.model) === clean(stored.model);
|
|
41
|
+
const inheritedEffort = sameModel ? stored.effort || null : null;
|
|
42
|
+
const inheritedModelParameters = sameModel ? stored.modelParameters || {} : {};
|
|
43
|
+
// A requested percent replaces the stored exact window and requested
|
|
44
|
+
// tokens replace the stored percent.
|
|
45
|
+
const requestsPercent = requested.contextPercent !== undefined;
|
|
46
|
+
const requestsTokens = requested.contextTokens !== undefined;
|
|
47
|
+
const inheritedContextPercent = sameModel && !requestsTokens ? stored.contextPercent : undefined;
|
|
48
|
+
const inheritedContextTokens = sameModel && !requestsPercent ? stored.contextTokens : undefined;
|
|
49
|
+
selectedRoute = {
|
|
50
|
+
...selectedRoute,
|
|
51
|
+
effort: requested.effort !== undefined ? selectedRoute.effort : inheritedEffort,
|
|
52
|
+
fast: requested.fast !== undefined ? selectedRoute.fast === true : sameModel && stored.fast === true,
|
|
53
|
+
// Main's modelSettings bucket must not decide an agent's Auto effort.
|
|
54
|
+
autoEffort:
|
|
55
|
+
requested.autoEffort !== undefined ? requested.autoEffort !== false : !sameModel || stored.autoEffort !== false,
|
|
56
|
+
modelParameters: requested.modelParameters !== undefined ? selectedRoute.modelParameters : inheritedModelParameters,
|
|
57
|
+
// resolveRoute reads contextPercent from Main's modelSettings bucket;
|
|
58
|
+
// an agent route owns its own.
|
|
59
|
+
contextPercent: requestsPercent ? requested.contextPercent : inheritedContextPercent,
|
|
60
|
+
contextTokens: requestsTokens ? requested.contextTokens : inheritedContextTokens,
|
|
61
|
+
};
|
|
62
|
+
await ensureProvidersReady(ensureProviderEnabled(getConfig(), selectedRoute.provider));
|
|
63
|
+
const modelMeta = await lookupModelMeta(selectedRoute.provider, selectedRoute.model);
|
|
64
|
+
// Stored clamped, and not at all at the default window, as for Main.
|
|
65
|
+
const contextState = resolveRouteContextState(selectedRoute, modelMeta);
|
|
66
|
+
if (contextState.contextDefaultPercent !== undefined) selectedRoute.contextTokens = contextState.contextTokens;
|
|
67
|
+
const fastCapable = selectionFastCapable(
|
|
68
|
+
selectedRoute.provider,
|
|
69
|
+
modelMeta,
|
|
70
|
+
selectedRoute.effort,
|
|
71
|
+
selectedRoute.modelParameters
|
|
72
|
+
);
|
|
73
|
+
return { ...selectedRoute, fast: fastCapable ? selectedRoute.fast === true : false };
|
|
74
|
+
}
|
|
75
|
+
|
|
32
76
|
export function createAgentRouteApi(deps) {
|
|
33
|
-
const { getConfig, resolveRoute,
|
|
34
|
-
deps;
|
|
77
|
+
const { getConfig, resolveRoute, saveConfigAndAdopt, agentRouteFromConfig } = deps;
|
|
35
78
|
|
|
36
79
|
function saveDisabled(id, disabled) {
|
|
37
80
|
saveConfigAndAdopt(canonicalizeAgentRouteStorage(withAgentDisabled(getConfig(), id, disabled)));
|
|
@@ -76,49 +119,6 @@ export function createAgentRouteApi(deps) {
|
|
|
76
119
|
return { ...(inherited || {}), inherited: true };
|
|
77
120
|
}
|
|
78
121
|
|
|
79
|
-
// Tuning-only edits keep the stored model's effort/fast/modelParameters;
|
|
80
|
-
// a model change starts from the resolved defaults. Fast is then clamped
|
|
81
|
-
// to what the selected model supports.
|
|
82
|
-
async function resolveSelectedRoute(requested, stored) {
|
|
83
|
-
let selectedRoute = resolveRoute(getConfig(), requested);
|
|
84
|
-
const sameModel =
|
|
85
|
-
clean(selectedRoute.provider) === clean(stored.provider) && clean(selectedRoute.model) === clean(stored.model);
|
|
86
|
-
const inheritedEffort = sameModel ? stored.effort || null : null;
|
|
87
|
-
const inheritedModelParameters = sameModel ? stored.modelParameters || {} : {};
|
|
88
|
-
// A requested percent replaces the stored exact window and requested
|
|
89
|
-
// tokens replace the stored percent.
|
|
90
|
-
const requestsPercent = requested.contextPercent !== undefined;
|
|
91
|
-
const requestsTokens = requested.contextTokens !== undefined;
|
|
92
|
-
const inheritedContextPercent = sameModel && !requestsTokens ? stored.contextPercent : undefined;
|
|
93
|
-
const inheritedContextTokens = sameModel && !requestsPercent ? stored.contextTokens : undefined;
|
|
94
|
-
selectedRoute = {
|
|
95
|
-
...selectedRoute,
|
|
96
|
-
effort: requested.effort !== undefined ? selectedRoute.effort : inheritedEffort,
|
|
97
|
-
fast: requested.fast !== undefined ? selectedRoute.fast === true : sameModel && stored.fast === true,
|
|
98
|
-
// Main's modelSettings bucket must not decide an agent's Auto effort.
|
|
99
|
-
autoEffort:
|
|
100
|
-
requested.autoEffort !== undefined ? requested.autoEffort !== false : !sameModel || stored.autoEffort !== false,
|
|
101
|
-
modelParameters:
|
|
102
|
-
requested.modelParameters !== undefined ? selectedRoute.modelParameters : inheritedModelParameters,
|
|
103
|
-
// resolveRoute reads contextPercent from Main's modelSettings bucket;
|
|
104
|
-
// an agent route owns its own.
|
|
105
|
-
contextPercent: requestsPercent ? requested.contextPercent : inheritedContextPercent,
|
|
106
|
-
contextTokens: requestsTokens ? requested.contextTokens : inheritedContextTokens,
|
|
107
|
-
};
|
|
108
|
-
await ensureProvidersReady(ensureProviderEnabled(getConfig(), selectedRoute.provider));
|
|
109
|
-
const modelMeta = await lookupModelMeta(selectedRoute.provider, selectedRoute.model);
|
|
110
|
-
// Stored clamped, and not at all at the default window, as for Main.
|
|
111
|
-
const contextState = resolveRouteContextState(selectedRoute, modelMeta);
|
|
112
|
-
if (contextState.contextDefaultPercent !== undefined) selectedRoute.contextTokens = contextState.contextTokens;
|
|
113
|
-
const fastCapable = selectionFastCapable(
|
|
114
|
-
selectedRoute.provider,
|
|
115
|
-
modelMeta,
|
|
116
|
-
selectedRoute.effort,
|
|
117
|
-
selectedRoute.modelParameters
|
|
118
|
-
);
|
|
119
|
-
return { ...selectedRoute, fast: fastCapable ? selectedRoute.fast === true : false };
|
|
120
|
-
}
|
|
121
|
-
|
|
122
122
|
async function setAgentRoute(agentId, next) {
|
|
123
123
|
const id = agentEditorId(agentId);
|
|
124
124
|
if (!id) throw new Error(`unknown agent "${agentId}"`);
|
|
@@ -175,7 +175,7 @@ export function createAgentRouteApi(deps) {
|
|
|
175
175
|
const previous = storedChain.find(
|
|
176
176
|
(candidate) => candidate.provider === entry.provider && candidate.model === entry.model
|
|
177
177
|
);
|
|
178
|
-
resolved.push(await
|
|
178
|
+
resolved.push(await resolveChainEntry(deps, entry, previous || {}));
|
|
179
179
|
}
|
|
180
180
|
const [primary, ...fallbacks] = resolved;
|
|
181
181
|
const routeToSave = normalizeWorkflowRoute({ ...primary, fallbacks });
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { oneLine } from '../../runtime/shared/clean.mjs';
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
normalizeAgentId,
|
|
4
|
+
normalizeWorkflowId,
|
|
5
|
+
normalizeWorkflowRoute,
|
|
6
|
+
} from '../../runtime/agent/orchestrator/runtime-core/workflow.mjs';
|
|
3
7
|
|
|
4
8
|
export function resolveDataDir({ cfgMod, STANDALONE_DATA_DIR }) {
|
|
5
9
|
return cfgMod.getPluginData?.() || STANDALONE_DATA_DIR;
|
|
@@ -35,10 +35,23 @@ export function createStyleAndModeApi(deps) {
|
|
|
35
35
|
return { ...freshStatus, appliedToCurrentSession };
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
|
|
38
|
+
// `{ scope: 'session' }` (the composer's selector in a session), like
|
|
39
|
+
// setWorkflow: a session with a conversation switches alone
|
|
40
|
+
// (switchSessionOrchestrationMode; deferred to its next turn while one
|
|
41
|
+
// runs) and the configured mode — the default for new sessions — stays.
|
|
42
|
+
// Otherwise the choice becomes the configured mode and an empty session
|
|
43
|
+
// picks it up in place.
|
|
44
|
+
async function setOrchestrationMode(mode, options = {}) {
|
|
39
45
|
if (!ORCHESTRATION_MODES.includes(mode)) {
|
|
40
46
|
throw new Error(`orchestration mode must be one of ${ORCHESTRATION_MODES.join(', ')}`);
|
|
41
47
|
}
|
|
48
|
+
if (options?.scope === 'session') {
|
|
49
|
+
const switched = await deps.switchSessionOrchestrationMode?.(mode);
|
|
50
|
+
if (switched) {
|
|
51
|
+
invalidateContextStatusCache();
|
|
52
|
+
return switched;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
42
55
|
saveConfigAndAdopt({ ...getConfig(), orchestrationMode: mode });
|
|
43
56
|
const applied = await deps.refreshEmptySessionToolPolicy?.();
|
|
44
57
|
deps.invalidatePreSessionToolSurface?.();
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { join } from 'node:path';
|
|
2
|
-
import { existsSync, mkdirSync, rmSync
|
|
2
|
+
import { existsSync, mkdirSync, rmSync } from 'node:fs';
|
|
3
|
+
import { writeFileAtomicSync } from '../../runtime/shared/atomic-file.mjs';
|
|
3
4
|
import { serializeFrontmatterDoc } from '../../runtime/shared/markdown-frontmatter.mjs';
|
|
4
5
|
import {
|
|
5
6
|
normalizeWorkflowId,
|
|
@@ -44,6 +45,7 @@ export function createWorkflowPacksApi(deps) {
|
|
|
44
45
|
name: workflow.name,
|
|
45
46
|
description: workflow.description,
|
|
46
47
|
source: workflow.source,
|
|
48
|
+
...(workflow.overridesBuiltIn ? { overridesBuiltIn: true } : {}),
|
|
47
49
|
active: workflow.id === active,
|
|
48
50
|
}));
|
|
49
51
|
}
|
|
@@ -106,9 +108,10 @@ export function createWorkflowPacksApi(deps) {
|
|
|
106
108
|
if (!absorbed) {
|
|
107
109
|
const dir = join(dataDir, 'workflows', id);
|
|
108
110
|
mkdirSync(dir, { recursive: true });
|
|
109
|
-
|
|
111
|
+
writeFileAtomicSync(
|
|
110
112
|
join(dir, 'WORKFLOW.md'),
|
|
111
|
-
serializeFrontmatterDoc({ id, name, ...(description ? { description } : {}) }, body)
|
|
113
|
+
serializeFrontmatterDoc({ id, name, ...(description ? { description } : {}) }, body),
|
|
114
|
+
{ backup: true, mode: 0o644 }
|
|
112
115
|
);
|
|
113
116
|
}
|
|
114
117
|
return getWorkflowPack(id);
|
|
@@ -4,8 +4,9 @@
|
|
|
4
4
|
* resume (missing worktree → recovery), and carrying the Project's memory
|
|
5
5
|
* identity into a new worktree.
|
|
6
6
|
*/
|
|
7
|
-
import { existsSync,
|
|
8
|
-
import {
|
|
7
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
8
|
+
import { join } from 'node:path';
|
|
9
|
+
import { holdsNoData, writeFileAtomicSync } from '../../runtime/shared/atomic-file.mjs';
|
|
9
10
|
import { isWorktreeBound, nextRevision, normalizeSessionWorkspace } from '../../runtime/shared/worktrees/contract.mjs';
|
|
10
11
|
import { isWithin, samePath } from '../../runtime/shared/worktrees/paths.mjs';
|
|
11
12
|
import { resolveProjectId } from '../../runtime/memory/lib/project-id-resolver.mjs';
|
|
@@ -103,10 +104,10 @@ export function restoreWorkspaceAfterResume(session) {
|
|
|
103
104
|
*/
|
|
104
105
|
export function copyProjectIdentity(projectPath, worktreePath) {
|
|
105
106
|
const target = join(worktreePath, '.mixdog', 'project.id');
|
|
106
|
-
|
|
107
|
+
// An id file with no data (empty, or NUL-filled by a crash) is missing.
|
|
108
|
+
if (existsSync(target) && !holdsNoData(readFileSync(target))) return false;
|
|
107
109
|
const id = resolveProjectId(projectPath);
|
|
108
|
-
if (!id) return false;
|
|
109
|
-
|
|
110
|
-
writeFileSync(target, `${id}\n`, 'utf8');
|
|
110
|
+
if (!id || holdsNoData(id)) return false;
|
|
111
|
+
writeFileAtomicSync(target, `${id}\n`, { mode: 0o644 });
|
|
111
112
|
return true;
|
|
112
113
|
}
|
|
@@ -54,7 +54,10 @@ export function createCanonicalAgentControl({ getSessionService, getSessionRunti
|
|
|
54
54
|
ownerSessionId: sessionService.rootOwnerSessionId(parentSessionId),
|
|
55
55
|
};
|
|
56
56
|
if (String(args?.type || '') === '__close_all') {
|
|
57
|
-
await tool.closeAll?.(String(args?.reason || 'agent owner closed'), {
|
|
57
|
+
await tool.closeAll?.(String(args?.reason || 'agent owner closed'), {
|
|
58
|
+
callerSessionId: parentSessionId || null,
|
|
59
|
+
processExit: args?.processExit === true,
|
|
60
|
+
});
|
|
58
61
|
await sessionService.cancelAgentDescendants(parentSessionId, String(args?.reason || 'agent owner closed'));
|
|
59
62
|
return 'agent close all: ok';
|
|
60
63
|
}
|
|
@@ -1,19 +1,25 @@
|
|
|
1
1
|
import { SESSION_ID_PATTERN } from '../runtime/agent/orchestrator/runtime-core/session-id.mjs';
|
|
2
2
|
import { sessionListOutput, sessionReadOutput, SESSION_TOOL_OUTPUT_BYTES } from './session-tool-output.mjs';
|
|
3
3
|
import { createAgentTaskSessions } from '../session-runtime/agent-task-sessions.mjs';
|
|
4
|
+
import { createBotStatus, scanCatalog, scopedBot, sessionBotOf } from '../session-runtime/bot-status.mjs';
|
|
4
5
|
import { handoffContent } from '../session-runtime/handoff-attachments.mjs';
|
|
6
|
+
import { BOT_HOP_LIMIT_ERROR, MAX_BOT_HOPS } from '../runtime/shared/bot-hops.mjs';
|
|
7
|
+
import { rebindDelegation } from '../runtime/agent/orchestrator/session/human-gate/delegation.mjs';
|
|
5
8
|
|
|
6
9
|
const TARGET_ACTIONS = new Set(['status', 'read', 'send', 'cancel', 'delete']);
|
|
7
10
|
const MUTATING_ACTIONS = new Set(['send', 'cancel', 'delete']);
|
|
11
|
+
// Why a send from a conversation that is no bot's reports nothing back.
|
|
12
|
+
const NOT_BOT_REASON = 'only a bot conversation gets session results reported back; check that session for the result';
|
|
8
13
|
|
|
9
14
|
/** Model-facing session operations over the same service used by desktop and TUI. */
|
|
10
15
|
export function createSessionControl({
|
|
11
16
|
getSessionService,
|
|
12
17
|
agentTasks = createAgentTaskSessions({ getSessionService }),
|
|
18
|
+
botStatus = createBotStatus({ getSessionService }),
|
|
13
19
|
}) {
|
|
14
20
|
return async function executeSessionControl(args = {}, context = {}) {
|
|
15
21
|
const action = args.action;
|
|
16
|
-
if (action !== 'list' && action !== 'create' && !TARGET_ACTIONS.has(action)) {
|
|
22
|
+
if (action !== 'list' && action !== 'create' && action !== 'bots' && !TARGET_ACTIONS.has(action)) {
|
|
17
23
|
throw new Error(`session: unsupported remote action "${action}"`);
|
|
18
24
|
}
|
|
19
25
|
const caller = context.callerSessionId;
|
|
@@ -22,8 +28,10 @@ export function createSessionControl({
|
|
|
22
28
|
}
|
|
23
29
|
// `callerAgentId`: set only for an attended agent conversation (workspace-tools.mjs).
|
|
24
30
|
if (action === 'create') return agentTasks.create(args, context);
|
|
31
|
+
// `callerScope`: the caller's schedule-access scope (workspace-tools.mjs).
|
|
32
|
+
if (action === 'bots') return botStatus(args, context);
|
|
25
33
|
const sessionId = typeof args.session_id === 'string' ? args.session_id.trim() : '';
|
|
26
|
-
if (TARGET_ACTIONS.has(action) &&
|
|
34
|
+
if (TARGET_ACTIONS.has(action) && !SESSION_ID_PATTERN.test(sessionId)) {
|
|
27
35
|
throw new Error(`session: session_id is required for action=${action}`);
|
|
28
36
|
}
|
|
29
37
|
if (MUTATING_ACTIONS.has(action) && sessionId === caller) {
|
|
@@ -45,8 +53,19 @@ export function createSessionControl({
|
|
|
45
53
|
const service = getSessionService();
|
|
46
54
|
if (!service) throw new Error('session: session service is unavailable');
|
|
47
55
|
if (action === 'list') {
|
|
56
|
+
// Scoped like bots (`callerScope`, bot-status.mjs): the human's sessions
|
|
57
|
+
// list everything, a bot (or its unattended run) only its own sessions,
|
|
58
|
+
// anything else the plain rows without previews.
|
|
59
|
+
const own = scopedBot(context.callerScope);
|
|
60
|
+
if (own) {
|
|
61
|
+
const scan = await scanCatalog(service, (row) => sessionBotOf(row) === own, {
|
|
62
|
+
cursor: args.cursor || null,
|
|
63
|
+
want: limit,
|
|
64
|
+
});
|
|
65
|
+
return sessionListOutput({ sessions: scan.rows, nextCursor: scan.nextCursor }, limit);
|
|
66
|
+
}
|
|
48
67
|
const page = await service.listSessionCatalog({ page: { limit, cursor: args.cursor || null } });
|
|
49
|
-
return sessionListOutput(page, limit);
|
|
68
|
+
return sessionListOutput(page, limit, { rich: own === '' });
|
|
50
69
|
}
|
|
51
70
|
if (action === 'send') {
|
|
52
71
|
if (typeof args.prompt !== 'string' || !args.prompt.trim()) {
|
|
@@ -57,17 +76,40 @@ export function createSessionControl({
|
|
|
57
76
|
// session by an origin for this send only.
|
|
58
77
|
// Forwarded files ride along as stored attachment parts (workspace-tools.mjs).
|
|
59
78
|
const prompt = handoffContent(args.prompt, context.attachmentParts);
|
|
60
|
-
|
|
79
|
+
let origin = await agentTasks.reportOrigin(sessionId, context.callerAgentId, caller);
|
|
80
|
+
// A send made in a bot-descended turn (`callerHop` > 0), or by a bot to
|
|
81
|
+
// another session, extends the chain by one; a bot's own task session
|
|
82
|
+
// only continues it. Refused past the limit, whatever the target.
|
|
83
|
+
const turnHop = Number(context.callerHop) || 0;
|
|
84
|
+
const chained = (hop) => {
|
|
85
|
+
if (hop > MAX_BOT_HOPS) throw new Error(BOT_HOP_LIMIT_ERROR);
|
|
86
|
+
return hop;
|
|
87
|
+
};
|
|
61
88
|
if (origin) {
|
|
62
|
-
const
|
|
63
|
-
|
|
89
|
+
const hop = chained(origin.target === 'session' ? turnHop + 1 : turnHop);
|
|
90
|
+
if (hop > 0) origin = { ...origin, hop };
|
|
91
|
+
// The task session a bot created acts as the sending conversation does
|
|
92
|
+
// from now on (attended chat or run); another's session keeps its own.
|
|
93
|
+
if (origin.target !== 'session') await rebindDelegation(sessionId, caller);
|
|
94
|
+
const sent = await agentTasks.send(sessionId, prompt, origin);
|
|
95
|
+
return { sessionId, ...sent, ...(hop > 0 ? { hop } : {}) };
|
|
64
96
|
}
|
|
97
|
+
const hop = turnHop > 0 ? chained(turnHop + 1) : 0;
|
|
98
|
+
// New work from this sender: a delegated target acts as the sender does.
|
|
99
|
+
await rebindDelegation(sessionId, caller);
|
|
65
100
|
const result = await service.submitSession({
|
|
66
101
|
sessionId,
|
|
67
102
|
prompt,
|
|
68
|
-
options: { mode: 'prompt', transcriptMeta: { sender: 'lead' } },
|
|
103
|
+
options: { mode: 'prompt', transcriptMeta: { sender: 'lead', ...(hop > 0 ? { hop } : {}) } },
|
|
69
104
|
});
|
|
70
|
-
|
|
105
|
+
const accepted = result.accepted === true;
|
|
106
|
+
return {
|
|
107
|
+
sessionId,
|
|
108
|
+
accepted,
|
|
109
|
+
reportsBack: false,
|
|
110
|
+
...(accepted ? { reportsBackReason: NOT_BOT_REASON } : {}),
|
|
111
|
+
...(hop > 0 ? { hop } : {}),
|
|
112
|
+
};
|
|
71
113
|
}
|
|
72
114
|
if (action === 'cancel') {
|
|
73
115
|
const result = await service.abortSession({ sessionId });
|
|
@@ -91,7 +133,7 @@ export function createSessionControl({
|
|
|
91
133
|
});
|
|
92
134
|
const snapshot = result.full;
|
|
93
135
|
if (!snapshot) throw new Error(`session: ${sessionId} is unavailable`);
|
|
94
|
-
|
|
136
|
+
return {
|
|
95
137
|
sessionId,
|
|
96
138
|
title: snapshot.title ?? null,
|
|
97
139
|
cwd: snapshot.cwd ?? null,
|
|
@@ -100,6 +142,5 @@ export function createSessionControl({
|
|
|
100
142
|
busy: snapshot.busy === true,
|
|
101
143
|
quotaResume: snapshot.quotaResume ?? null,
|
|
102
144
|
};
|
|
103
|
-
return status;
|
|
104
145
|
};
|
|
105
146
|
}
|
|
@@ -928,7 +928,14 @@ async function main() {
|
|
|
928
928
|
});
|
|
929
929
|
canonicalAgentControl = agentControl;
|
|
930
930
|
// Agents' cross-session sends and task sessions, and their report watches.
|
|
931
|
-
const agentTasks = createAgentTaskSessions({
|
|
931
|
+
const agentTasks = createAgentTaskSessions({
|
|
932
|
+
getSessionService: () => sessionService,
|
|
933
|
+
// A task session re-attached after a restart takes its agents' queued
|
|
934
|
+
// results through the owner runtime's notification bus.
|
|
935
|
+
deliverCompletion: (sessionId, text, meta) =>
|
|
936
|
+
sessionRuntimeHost?.notifySessionCompletion?.(sessionId, text, meta) === true,
|
|
937
|
+
settleAgentResults: async () => (await agentControl.canonicalAgentTool()).settleRestartFailures(),
|
|
938
|
+
});
|
|
932
939
|
const requestedRuntimeMode = String(process.env.MIXDOG_SESSION_RUNTIME_MODE || '')
|
|
933
940
|
.trim()
|
|
934
941
|
.toLowerCase();
|
|
@@ -990,15 +997,26 @@ async function main() {
|
|
|
990
997
|
busy: (sessionId) => sessionService.liveSessionBusy(sessionId),
|
|
991
998
|
notice: (sessionId, notice) => sessionService.pushLiveSessionNotice(sessionId, notice),
|
|
992
999
|
// A task session's result (session create): the agent relays it in one
|
|
993
|
-
// turn. Resolves
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1000
|
+
// turn. Resolves false when the turn was refused, else `{ settled }`, the
|
|
1001
|
+
// turn's end status ('done' when it finished).
|
|
1002
|
+
wake: async (sessionId, prompt, { id, hop = 0 } = {}) => {
|
|
1003
|
+
let settle = () => {};
|
|
1004
|
+
const settled = new Promise((resolveSettled) => {
|
|
1005
|
+
settle = resolveSettled;
|
|
1006
|
+
});
|
|
1007
|
+
const result = await sessionService.submitSession({
|
|
1008
|
+
sessionId,
|
|
1009
|
+
prompt,
|
|
1010
|
+
options: {
|
|
1011
|
+
mode: 'prompt',
|
|
1012
|
+
kickoff: true,
|
|
1013
|
+
...(id ? { id } : {}),
|
|
1014
|
+
...(hop > 0 ? { transcriptMeta: { hop } } : {}),
|
|
1015
|
+
onSettled: (detail) => settle(String(detail?.status || 'failed')),
|
|
1016
|
+
},
|
|
1017
|
+
});
|
|
1018
|
+
return result?.accepted === true ? { settled } : false;
|
|
1019
|
+
},
|
|
1002
1020
|
// A routine fire: one queued turn in its bot's thread (routine-home-turn.mjs).
|
|
1003
1021
|
submit: async (sessionId, prompt, options) =>
|
|
1004
1022
|
(await sessionService.submitSession({ sessionId, prompt, options }))?.accepted === true,
|
|
@@ -12,7 +12,7 @@ import { performance } from 'node:perf_hooks';
|
|
|
12
12
|
import { isDeepStrictEqual } from 'node:util';
|
|
13
13
|
import { bootProfile } from '../tui/session/boot-profile.mjs';
|
|
14
14
|
import { createGoalContinuation } from '../tui/session/goal-continuation.mjs';
|
|
15
|
-
import { createToolApproval } from '../tui/session/tool-approval.mjs';
|
|
15
|
+
import { createToolApproval, resolveToolApprovalTimeoutMs } from '../tui/session/tool-approval.mjs';
|
|
16
16
|
import { createToolCardResults } from '../tui/session/tool-card-results.mjs';
|
|
17
17
|
import { createAgentJobFeed } from '../tui/session/agent-job-feed.mjs';
|
|
18
18
|
import { createWorktreeSetupNotices } from '../tui/session/worktree-setup-notice.mjs';
|
|
@@ -83,10 +83,9 @@ export function setSessionRuntimeImporterForTest(importer) {
|
|
|
83
83
|
sessionRuntimeModulePromise = null;
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
})();
|
|
86
|
+
// An approval waits until the user answers (Deny, Stop or a closing runtime
|
|
87
|
+
// settle it); MIXDOG_TOOL_APPROVAL_TIMEOUT_MS opts into a limit for tests/ops.
|
|
88
|
+
const TOOL_APPROVAL_TIMEOUT_MS = resolveToolApprovalTimeoutMs();
|
|
90
89
|
|
|
91
90
|
export {
|
|
92
91
|
cleanupStaleTranscriptSpillDirs,
|
|
@@ -306,15 +305,22 @@ export async function createLocalSessionRuntime({
|
|
|
306
305
|
pushItem,
|
|
307
306
|
replaceItems,
|
|
308
307
|
});
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
308
|
+
// A sub-agent's approvals also show in the top-level chat (human-gate/gate.mjs).
|
|
309
|
+
const { approvalSurface } = await import('../runtime/agent/orchestrator/session/human-gate/gate.mjs');
|
|
310
|
+
const {
|
|
311
|
+
presentNextToolApproval,
|
|
312
|
+
finishToolApproval,
|
|
313
|
+
denyAllToolApprovals,
|
|
314
|
+
requestToolApproval,
|
|
315
|
+
adoptDelegatedApprovals,
|
|
316
|
+
} = createToolApproval({
|
|
317
|
+
getState,
|
|
318
|
+
set,
|
|
319
|
+
nextId,
|
|
320
|
+
getDisposed: () => flags.disposed,
|
|
321
|
+
timeoutMs: TOOL_APPROVAL_TIMEOUT_MS,
|
|
322
|
+
surfaceOf: approvalSurface,
|
|
323
|
+
});
|
|
318
324
|
const runtimePulse = createRuntimePulse({
|
|
319
325
|
flags,
|
|
320
326
|
getState,
|
|
@@ -336,6 +342,8 @@ export async function createLocalSessionRuntime({
|
|
|
336
342
|
lifecycle.runtimePulseTimer = setInterval(() => {
|
|
337
343
|
headWatch.retarget();
|
|
338
344
|
runtimePulse();
|
|
345
|
+
// A sub-agent's approval made before this session loaded (or bound its id).
|
|
346
|
+
adoptDelegatedApprovals();
|
|
339
347
|
}, 2000);
|
|
340
348
|
lifecycle.runtimePulseTimer.unref?.();
|
|
341
349
|
|
|
@@ -148,12 +148,12 @@ function request({
|
|
|
148
148
|
}
|
|
149
149
|
);
|
|
150
150
|
req.on('timeout', () => {
|
|
151
|
-
req.destroy(
|
|
151
|
+
req.destroy(sessionTimeoutError(method, urlPath));
|
|
152
152
|
});
|
|
153
153
|
req.on('error', reject);
|
|
154
154
|
if (deadlineMs > 0) {
|
|
155
155
|
deadlineTimer = setTimeout(() => {
|
|
156
|
-
const error =
|
|
156
|
+
const error = sessionTimeoutError(method, urlPath);
|
|
157
157
|
reject(error);
|
|
158
158
|
req.destroy(error);
|
|
159
159
|
}, deadlineMs);
|
|
@@ -163,6 +163,11 @@ function request({
|
|
|
163
163
|
});
|
|
164
164
|
}
|
|
165
165
|
|
|
166
|
+
/** No answer within the request's bound: the daemon may be busy with it, not gone. */
|
|
167
|
+
function sessionTimeoutError(method, urlPath) {
|
|
168
|
+
return Object.assign(new Error(`session timeout: ${method} ${urlPath}`), { code: 'ESESSIONTIMEOUT' });
|
|
169
|
+
}
|
|
170
|
+
|
|
166
171
|
/** /health within `timeoutMs` of total duration; null when it does not answer. */
|
|
167
172
|
export async function probeSessionHealth({ port, token, timeoutMs = 800 } = {}) {
|
|
168
173
|
try {
|
|
@@ -15,6 +15,7 @@ export const SESSION_READ_ACTIONS = Object.freeze([
|
|
|
15
15
|
'getAgentAvatarImage',
|
|
16
16
|
'getAgentConnectors',
|
|
17
17
|
'getProjectConnectors',
|
|
18
|
+
'getAgentAlwaysAllowedTools',
|
|
18
19
|
'getAgentPermissions',
|
|
19
20
|
'listConnectors',
|
|
20
21
|
'listConnectorTools',
|
|
@@ -45,6 +46,8 @@ export const SESSION_READ_ACTIONS = Object.freeze([
|
|
|
45
46
|
'getQuotaHistory',
|
|
46
47
|
'getRecapSettings',
|
|
47
48
|
'getSessionTitleSettings',
|
|
49
|
+
'getLeadAppearance',
|
|
50
|
+
'getBotOrder',
|
|
48
51
|
'getWebSearchRoute',
|
|
49
52
|
'getSettingsSnapshot',
|
|
50
53
|
'getSystemShell',
|
|
@@ -188,6 +191,7 @@ export const SESSION_CONFIGURE_ACTIONS = Object.freeze([
|
|
|
188
191
|
'setAgentConnectorToolPermission',
|
|
189
192
|
'setProjectConnectorEnabled',
|
|
190
193
|
'setAgentPermission',
|
|
194
|
+
'recordAgentApprovalAudit',
|
|
191
195
|
'saveLeadPersona',
|
|
192
196
|
'saveLeadAgentBody',
|
|
193
197
|
'setLeadCreated',
|
|
@@ -233,6 +237,8 @@ export const SESSION_CONFIGURE_ACTIONS = Object.freeze([
|
|
|
233
237
|
'setProgressHint',
|
|
234
238
|
'setRecapEnabled',
|
|
235
239
|
'setAiSessionTitles',
|
|
240
|
+
'setLeadAppearance',
|
|
241
|
+
'setBotOrder',
|
|
236
242
|
'setRoute',
|
|
237
243
|
'setScheduleEnabled',
|
|
238
244
|
'setWebSearchRoute',
|
|
@@ -241,6 +247,7 @@ export const SESSION_CONFIGURE_ACTIONS = Object.freeze([
|
|
|
241
247
|
'setToolMode',
|
|
242
248
|
'setWebSearchEnabled',
|
|
243
249
|
'setInstructionFiles',
|
|
250
|
+
'setAutoEffortBase',
|
|
244
251
|
'setWebhookConfig',
|
|
245
252
|
'setWebhookEnabled',
|
|
246
253
|
'setWorkflow',
|
|
@@ -23,6 +23,7 @@ import { createViewerRegistry } from './session-service/viewers.mjs';
|
|
|
23
23
|
import { createSessionEntries } from './session-service/entries.mjs';
|
|
24
24
|
import { createSessionCalls } from './session-service/session-calls.mjs';
|
|
25
25
|
import { createQuotaResumeScheduler } from './session-service/quota-resume.mjs';
|
|
26
|
+
import { registerDelegatedApprovalOpener } from '../runtime/shared/delegated-approval-host.mjs';
|
|
26
27
|
|
|
27
28
|
const EXTERNAL_SESSION_ACTIONS = new Set([
|
|
28
29
|
...SESSION_READ_ACTION_SET,
|
|
@@ -205,6 +206,9 @@ export function createSessionService({
|
|
|
205
206
|
retainUnwatched: retention.retainUnwatched,
|
|
206
207
|
createSession: calls.createSession,
|
|
207
208
|
});
|
|
209
|
+
// A sub-agent's approval shows in its top-level chat; one not loaded is
|
|
210
|
+
// brought up so the copy (and its notifications) appear there.
|
|
211
|
+
const unregisterApprovalOpener = registerDelegatedApprovalOpener((sessionId) => calls.materializeSession(sessionId));
|
|
208
212
|
const quotaUsableReader = typeof readQuotaUsable === 'function' ? readQuotaUsable : async () => false;
|
|
209
213
|
const quotaResume = quotaResumeStore
|
|
210
214
|
? createQuotaResumeScheduler({
|
|
@@ -219,6 +223,7 @@ export function createSessionService({
|
|
|
219
223
|
function stop(reason = 'service stop') {
|
|
220
224
|
if (stopPromise) return stopPromise;
|
|
221
225
|
closed = true;
|
|
226
|
+
unregisterApprovalOpener();
|
|
222
227
|
quotaResume?.stop();
|
|
223
228
|
stopPromise = Promise.resolve().then(async () => {
|
|
224
229
|
try {
|
|
@@ -243,6 +248,11 @@ export function createSessionService({
|
|
|
243
248
|
return Boolean(owner) && retention.stateBusy(owner.runtime?.getState?.());
|
|
244
249
|
}
|
|
245
250
|
|
|
251
|
+
/** Whether the runtime hosting `sessionId` shows an approval card waiting on the user. */
|
|
252
|
+
function liveSessionAwaitingApproval(sessionId) {
|
|
253
|
+
return Boolean(projection.sessionOwner(sessionId)?.runtime?.getState?.()?.toolApproval);
|
|
254
|
+
}
|
|
255
|
+
|
|
246
256
|
/** Show a transcript notice in the hosted runtime of `sessionId` (no turn)
|
|
247
257
|
* and publish it to its views; false when no runtime hosts it. */
|
|
248
258
|
function pushLiveSessionNotice(sessionId, { text, tone = 'info', ...options } = {}) {
|
|
@@ -300,6 +310,7 @@ export function createSessionService({
|
|
|
300
310
|
methods: {
|
|
301
311
|
...calls,
|
|
302
312
|
liveSessionBusy,
|
|
313
|
+
liveSessionAwaitingApproval,
|
|
303
314
|
pushLiveSessionNotice,
|
|
304
315
|
stop,
|
|
305
316
|
startQuotaResume: () => quotaResume?.start(),
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { sanitizeForWire } from './session-wire-values.mjs';
|
|
2
|
+
import { stripAgentMessageEnvelope } from '../runtime/shared/agent-message-envelope.mjs';
|
|
3
|
+
import { transcriptSourceFields } from '../runtime/shared/transcript-metadata.mjs';
|
|
2
4
|
|
|
3
5
|
/** Immutable source fields keep their wire identity until they actually change.
|
|
4
6
|
* In particular, a live tail must not rebuild the settled transcript or resend
|
|
@@ -29,15 +31,23 @@ export function projectSessionState(entry, raw) {
|
|
|
29
31
|
}
|
|
30
32
|
let cloned;
|
|
31
33
|
if (key === 'queued' && Array.isArray(value)) {
|
|
32
|
-
cloned = value.map((item) =>
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
34
|
+
cloned = value.map((item) => {
|
|
35
|
+
// A queued bot message reads like its delivered row: the sender tag
|
|
36
|
+
// and the message without its envelope.
|
|
37
|
+
const source = transcriptSourceFields(item?.transcriptMeta);
|
|
38
|
+
const queuedText = String(item?.displayText ?? item?.text ?? '');
|
|
39
|
+
const text = (source.fromAgent ? stripAgentMessageEnvelope(queuedText) : queuedText).slice(0, 2_000);
|
|
40
|
+
return {
|
|
41
|
+
id: item?.id,
|
|
42
|
+
submittedAt: item?.submittedAt,
|
|
43
|
+
text,
|
|
44
|
+
displayText: text,
|
|
45
|
+
mode: item?.mode || 'prompt',
|
|
46
|
+
priority: item?.priority || 'next',
|
|
47
|
+
...source,
|
|
48
|
+
...(Array.isArray(item?.images) && item.images.length ? { images: item.images } : {}),
|
|
49
|
+
};
|
|
50
|
+
});
|
|
41
51
|
} else if (key === 'items' && Array.isArray(value)) {
|
|
42
52
|
const items = entry.itemCache;
|
|
43
53
|
const nextItems = new Map();
|