mixdog 0.9.3 → 0.9.5
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 +112 -38
- package/package.json +10 -3
- package/scripts/bench/lead-review-tasks-r3.json +20 -0
- package/scripts/bench/lead-review-tasks.json +20 -0
- package/scripts/bench/r4-mixed-tasks.json +20 -0
- package/scripts/bench/r5-orchestrated-task.json +7 -0
- package/scripts/bench/review-tasks.json +20 -0
- package/scripts/bench/round-codex.json +114 -0
- package/scripts/bench/round-mixdog-lead-r3.json +269 -0
- package/scripts/bench/round-mixdog-lead.json +269 -0
- package/scripts/bench/round-mixdog.json +126 -0
- package/scripts/bench/round-r10-bigsample.json +679 -0
- package/scripts/bench/round-r11-codexalign.json +257 -0
- package/scripts/bench/round-r13-clientmeta.json +464 -0
- package/scripts/bench/round-r14-betafeatures.json +466 -0
- package/scripts/bench/round-r15-fulldefault.json +462 -0
- package/scripts/bench/round-r16-sessionid.json +466 -0
- package/scripts/bench/round-r17-wirebytes.json +456 -0
- package/scripts/bench/round-r18-prewarm.json +468 -0
- package/scripts/bench/round-r19-clean.json +472 -0
- package/scripts/bench/round-r20-prewarm-clean.json +475 -0
- package/scripts/bench/round-r21-delta-retry.json +473 -0
- package/scripts/bench/round-r22-full-probe.json +693 -0
- package/scripts/bench/round-r23-itemprobe.json +701 -0
- package/scripts/bench/round-r24-shapefix.json +677 -0
- package/scripts/bench/round-r25-serial.json +464 -0
- package/scripts/bench/round-r26-parallel3.json +671 -0
- package/scripts/bench/round-r27-parallel10.json +894 -0
- package/scripts/bench/round-r28-parallel10-stagger.json +882 -0
- package/scripts/bench/round-r29-parallel10-stagger166.json +886 -0
- package/scripts/bench/round-r30-instid.json +253 -0
- package/scripts/bench/round-r31-upgradeprobe.json +256 -0
- package/scripts/bench/round-r32-vs-codex-lead.json +254 -0
- package/scripts/bench/round-r33-vs-codex-codex.json +115 -0
- package/scripts/bench/round-r34-orchestrated.json +120 -0
- package/scripts/bench/round-r35-orchestrated-codex.json +61 -0
- package/scripts/bench/round-r36-orchestrated-capped.json +128 -0
- package/scripts/bench/round-r4-codex.json +114 -0
- package/scripts/bench/round-r4-mixed.json +225 -0
- package/scripts/bench/round-r5-gpt-lead.json +259 -0
- package/scripts/bench/round-r6-codex.json +114 -0
- package/scripts/bench/round-r6-solo.json +257 -0
- package/scripts/bench/round-r7-full.json +254 -0
- package/scripts/bench/round-r8-fulldefault.json +255 -0
- package/scripts/bench-run.mjs +251 -32
- package/scripts/freevar-smoke.mjs +95 -0
- package/scripts/internal-comms-bench.mjs +3 -4
- package/scripts/internal-comms-smoke.mjs +10 -9
- package/scripts/model-catalog-audit.mjs +209 -0
- package/scripts/model-list-sanitize-test.mjs +37 -0
- package/scripts/mouse-probe.mjs +45 -0
- package/scripts/output-style-bench.mjs +13 -6
- package/scripts/output-style-smoke.mjs +4 -4
- package/scripts/provider-toolcall-test.mjs +7 -3
- package/scripts/recall-bench.mjs +76 -13
- package/scripts/recall-quality-cases.json +12 -0
- package/scripts/recall-usecase-cases.json +18 -0
- package/scripts/session-bench.mjs +152 -6
- package/scripts/tool-smoke.mjs +25 -65
- package/scripts/tui-render-smoke.mjs +90 -0
- package/scripts/webhook-smoke.mjs +208 -0
- package/src/agents/debugger/AGENT.md +4 -1
- package/src/agents/heavy-worker/AGENT.md +9 -8
- package/src/agents/maintainer/AGENT.md +4 -0
- package/src/agents/reviewer/AGENT.md +2 -1
- package/src/agents/scheduler-task/AGENT.md +2 -3
- package/src/agents/webhook-handler/AGENT.md +2 -3
- package/src/agents/worker/AGENT.md +10 -7
- package/src/app.mjs +12 -1
- package/src/headless-role.mjs +7 -1
- package/src/lib/rules-builder.cjs +4 -0
- package/src/mixdog-session-runtime.mjs +647 -2056
- package/src/output-styles/default.md +30 -9
- package/src/output-styles/{oneline.md → extreme-minimal.md} +5 -4
- package/src/output-styles/minimal.md +8 -6
- package/src/output-styles/simple.md +21 -7
- package/src/rules/agent/00-common.md +6 -3
- package/src/rules/agent/30-explorer.md +16 -5
- package/src/rules/lead/01-general.md +5 -5
- package/src/rules/lead/lead-brief.md +15 -0
- package/src/rules/lead/lead-tool.md +6 -15
- package/src/rules/shared/01-tool.md +17 -21
- package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch.mjs +8 -3
- package/src/runtime/agent/orchestrator/agent-runtime/agent-loop-policy.mjs +25 -0
- package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +100 -23
- package/src/runtime/agent/orchestrator/agent-runtime/session-builder.mjs +6 -15
- package/src/runtime/agent/orchestrator/agent-trace-format.mjs +362 -0
- package/src/runtime/agent/orchestrator/agent-trace-io.mjs +410 -0
- package/src/runtime/agent/orchestrator/agent-trace.mjs +16 -735
- package/src/runtime/agent/orchestrator/config.mjs +69 -2
- package/src/runtime/agent/orchestrator/providers/anthropic-effort.mjs +62 -20
- package/src/runtime/agent/orchestrator/providers/anthropic-model-resolve.mjs +209 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-credentials.mjs +489 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +81 -1281
- package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +607 -0
- package/src/runtime/agent/orchestrator/providers/anthropic.mjs +32 -3
- package/src/runtime/agent/orchestrator/providers/codex-client-meta.mjs +81 -0
- package/src/runtime/agent/orchestrator/providers/gemini-cache.mjs +248 -0
- package/src/runtime/agent/orchestrator/providers/gemini-schema.mjs +303 -0
- package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +505 -0
- package/src/runtime/agent/orchestrator/providers/gemini.mjs +43 -1013
- package/src/runtime/agent/orchestrator/providers/grok-oauth.mjs +17 -3
- package/src/runtime/agent/orchestrator/providers/model-catalog.mjs +105 -11
- package/src/runtime/agent/orchestrator/providers/model-list-sanitize.mjs +356 -0
- package/src/runtime/agent/orchestrator/providers/openai-codex-model.mjs +108 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-trace.mjs +58 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-wire.mjs +368 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-xai.mjs +760 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +40 -1143
- package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +740 -0
- package/src/runtime/agent/orchestrator/providers/openai-oauth-login.mjs +193 -0
- package/src/runtime/agent/orchestrator/providers/openai-oauth-ws.mjs +349 -2131
- package/src/runtime/agent/orchestrator/providers/openai-oauth.mjs +143 -1002
- package/src/runtime/agent/orchestrator/providers/openai-ws-delta.mjs +229 -0
- package/src/runtime/agent/orchestrator/providers/openai-ws-events.mjs +67 -0
- package/src/runtime/agent/orchestrator/providers/openai-ws-pool.mjs +465 -0
- package/src/runtime/agent/orchestrator/providers/openai-ws-stream.mjs +1105 -0
- package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +2 -1
- package/src/runtime/agent/orchestrator/providers/provider-catalog-cache.mjs +80 -0
- package/src/runtime/agent/orchestrator/session/compact/budget.mjs +288 -0
- package/src/runtime/agent/orchestrator/session/compact/constants.mjs +85 -0
- package/src/runtime/agent/orchestrator/session/compact/engine.mjs +749 -0
- package/src/runtime/agent/orchestrator/session/compact/messages.mjs +82 -0
- package/src/runtime/agent/orchestrator/session/compact/summary-schema.mjs +315 -0
- package/src/runtime/agent/orchestrator/session/compact/summary.mjs +643 -0
- package/src/runtime/agent/orchestrator/session/compact/text-utils.mjs +326 -0
- package/src/runtime/agent/orchestrator/session/compact.mjs +40 -2282
- package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +14 -2
- package/src/runtime/agent/orchestrator/session/loop/completion-guards.mjs +61 -0
- package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +1 -3
- package/src/runtime/agent/orchestrator/session/loop/recall-fasttrack.mjs +275 -0
- package/src/runtime/agent/orchestrator/session/loop/steering-ladder.mjs +173 -0
- package/src/runtime/agent/orchestrator/session/loop/termination.mjs +58 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +239 -0
- package/src/runtime/agent/orchestrator/session/loop.mjs +278 -402
- package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +471 -0
- package/src/runtime/agent/orchestrator/session/manager/context-meta.mjs +7 -4
- package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +12 -0
- package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +406 -0
- package/src/runtime/agent/orchestrator/session/manager/status-telemetry.mjs +80 -0
- package/src/runtime/agent/orchestrator/session/manager/usage-metrics.mjs +210 -0
- package/src/runtime/agent/orchestrator/session/manager.mjs +166 -1087
- package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +189 -0
- package/src/runtime/agent/orchestrator/session/store.mjs +74 -179
- package/src/runtime/agent/orchestrator/stall-policy.mjs +20 -1
- package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +70 -20
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +22 -2
- package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +35 -44
- package/src/runtime/agent/orchestrator/tools/builtin/list-tool.mjs +40 -0
- package/src/runtime/agent/orchestrator/tools/builtin/rg-runner.mjs +29 -0
- package/src/runtime/agent/orchestrator/tools/builtin/search-builders.mjs +8 -0
- package/src/runtime/agent/orchestrator/tools/builtin/search-path-diagnostics.mjs +126 -0
- package/src/runtime/agent/orchestrator/tools/builtin/search-tool.mjs +81 -92
- package/src/runtime/agent/orchestrator/tools/builtin/shell-job-paths.mjs +161 -0
- package/src/runtime/agent/orchestrator/tools/builtin/shell-job-process.mjs +108 -0
- package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +28 -265
- package/src/runtime/agent/orchestrator/tools/builtin.mjs +0 -6
- package/src/runtime/agent/orchestrator/tools/code-graph/dispatch.mjs +57 -3
- package/src/runtime/agent/orchestrator/tools/code-graph/keyword-match.mjs +82 -0
- package/src/runtime/agent/orchestrator/tools/code-graph/search.mjs +10 -122
- package/src/runtime/agent/orchestrator/tools/code-graph/text-columns.mjs +45 -0
- package/src/runtime/agent/orchestrator/tools/code-graph-tool-defs.mjs +6 -6
- package/src/runtime/agent/orchestrator/tools/graph-binary-fetcher.mjs +6 -3
- package/src/runtime/agent/orchestrator/tools/patch/constants.mjs +9 -0
- package/src/runtime/agent/orchestrator/tools/patch/dispatch.mjs +171 -0
- package/src/runtime/agent/orchestrator/tools/patch/matcher.mjs +471 -0
- package/src/runtime/agent/orchestrator/tools/patch/native-server.mjs +436 -0
- package/src/runtime/agent/orchestrator/tools/patch/orchestrator.mjs +342 -0
- package/src/runtime/agent/orchestrator/tools/patch/parsing.mjs +359 -0
- package/src/runtime/agent/orchestrator/tools/patch/paths.mjs +340 -0
- package/src/runtime/agent/orchestrator/tools/patch/v4a-convert.mjs +643 -0
- package/src/runtime/agent/orchestrator/tools/patch.mjs +36 -2959
- package/src/runtime/agent/orchestrator/tools/progress-message.mjs +0 -21
- package/src/runtime/agent/orchestrator/tools/shell-command.mjs +9 -72
- package/src/runtime/agent/orchestrator/tools/shell-powershell.mjs +77 -0
- package/src/runtime/agent/orchestrator/tools/shell-state.mjs +154 -0
- package/src/runtime/channels/backends/discord-access.mjs +32 -0
- package/src/runtime/channels/backends/discord-attachments.mjs +65 -0
- package/src/runtime/channels/backends/discord-gateway.mjs +233 -0
- package/src/runtime/channels/backends/discord.mjs +27 -318
- package/src/runtime/channels/backends/telegram.mjs +8 -12
- package/src/runtime/channels/index.mjs +247 -701
- package/src/runtime/channels/lib/backend-dispatch.mjs +46 -0
- package/src/runtime/channels/lib/config.mjs +37 -149
- package/src/runtime/channels/lib/event-pipeline.mjs +22 -5
- package/src/runtime/channels/lib/event-queue.mjs +78 -13
- package/src/runtime/channels/lib/inbound-routing.mjs +74 -0
- package/src/runtime/channels/lib/interaction-workflows.mjs +5 -113
- package/src/runtime/channels/lib/output-forwarder.mjs +1 -1
- package/src/runtime/channels/lib/owner-heartbeat.mjs +75 -0
- package/src/runtime/channels/lib/parent-bridge.mjs +88 -0
- package/src/runtime/channels/lib/runtime-paths.mjs +14 -4
- package/src/runtime/channels/lib/scheduler.mjs +27 -113
- package/src/runtime/channels/lib/session-discovery.mjs +56 -4
- package/src/runtime/channels/lib/tool-dispatch.mjs +158 -0
- package/src/runtime/channels/lib/tool-format.mjs +1 -1
- package/src/runtime/channels/lib/transcript-discovery.mjs +4 -4
- package/src/runtime/channels/lib/voice-runtime-fetcher.mjs +6 -3
- package/src/runtime/channels/lib/voice-transcription.mjs +179 -0
- package/src/runtime/channels/lib/webhook/deliveries.mjs +313 -0
- package/src/runtime/channels/lib/webhook/log.mjs +42 -0
- package/src/runtime/channels/lib/webhook/ngrok.mjs +181 -0
- package/src/runtime/channels/lib/webhook/signature.mjs +60 -0
- package/src/runtime/channels/lib/webhook.mjs +43 -616
- package/src/runtime/channels/tool-defs.mjs +11 -130
- package/src/runtime/memory/index.mjs +210 -1948
- package/src/runtime/memory/lib/core-memory-store.mjs +5 -1
- package/src/runtime/memory/lib/cycle-llm-adapters.mjs +58 -0
- package/src/runtime/memory/lib/cycle-scheduler.mjs +497 -0
- package/src/runtime/memory/lib/embedding-warmup.mjs +58 -0
- package/src/runtime/memory/lib/ko-morph.mjs +195 -0
- package/src/runtime/memory/lib/memory-config-flags.mjs +91 -0
- package/src/runtime/memory/lib/memory-cycle.mjs +1 -1
- package/src/runtime/memory/lib/memory-cycle2-gate.mjs +515 -0
- package/src/runtime/memory/lib/memory-cycle2-mutations.mjs +324 -0
- package/src/runtime/memory/lib/memory-cycle2-shared.mjs +18 -0
- package/src/runtime/memory/lib/memory-cycle2.mjs +24 -842
- package/src/runtime/memory/lib/memory-embed.mjs +149 -0
- package/src/runtime/memory/lib/memory-process-lock.mjs +162 -0
- package/src/runtime/memory/lib/memory-recall-store.mjs +69 -12
- package/src/runtime/memory/lib/memory-text-utils.mjs +46 -0
- package/src/runtime/memory/lib/pg/supervisor.mjs +1 -1
- package/src/runtime/memory/lib/query-handlers.mjs +802 -0
- package/src/runtime/memory/lib/recall-format.mjs +55 -0
- package/src/runtime/memory/lib/runtime-fetcher.mjs +8 -3
- package/src/runtime/memory/lib/transcript-ingest.mjs +425 -0
- package/src/runtime/memory/tool-defs.mjs +5 -13
- package/src/runtime/search/lib/http-fetch.mjs +274 -0
- package/src/runtime/search/lib/ssrf-guard.mjs +333 -0
- package/src/runtime/search/lib/web-tools.mjs +24 -602
- package/src/runtime/shared/atomic-file.mjs +26 -1
- package/src/runtime/shared/config.mjs +14 -4
- package/src/runtime/shared/launcher-control.mjs +2 -2
- package/src/runtime/shared/markdown-frontmatter.mjs +19 -0
- package/src/runtime/shared/schedules-store.mjs +13 -3
- package/src/runtime/shared/tool-execution-contract.mjs +2 -2
- package/src/runtime/shared/tool-primitives.mjs +308 -0
- package/src/runtime/shared/tool-result-summary.mjs +515 -0
- package/src/runtime/shared/tool-surface.mjs +80 -898
- package/src/runtime/shared/transcript-writer.mjs +23 -0
- package/src/runtime/shared/update-checker.mjs +7 -4
- package/src/session-runtime/config-helpers.mjs +119 -2
- package/src/session-runtime/config-lifecycle.mjs +232 -0
- package/src/session-runtime/cwd-plugins.mjs +226 -0
- package/src/session-runtime/mcp-glue.mjs +177 -0
- package/src/session-runtime/model-recency.mjs +111 -0
- package/src/session-runtime/native-search.mjs +247 -0
- package/src/session-runtime/output-styles.mjs +11 -9
- package/src/session-runtime/prewarm.mjs +142 -0
- package/src/session-runtime/provider-models.mjs +278 -0
- package/src/session-runtime/provider-usage.mjs +120 -0
- package/src/session-runtime/quick-model-rows.mjs +205 -0
- package/src/session-runtime/quick-search-models.mjs +47 -0
- package/src/session-runtime/session-hooks.mjs +93 -0
- package/src/session-runtime/settings-api.mjs +352 -0
- package/src/session-runtime/tool-catalog.mjs +29 -29
- package/src/session-runtime/tool-defs.mjs +84 -0
- package/src/session-runtime/warmup-schedulers.mjs +201 -0
- package/src/session-runtime/workflow.mjs +1 -1
- package/src/standalone/agent-tool/helpers.mjs +237 -0
- package/src/standalone/agent-tool/notify.mjs +107 -0
- package/src/standalone/agent-tool/provider-init.mjs +143 -0
- package/src/standalone/agent-tool/render.mjs +152 -0
- package/src/standalone/agent-tool/tool-def.mjs +55 -0
- package/src/standalone/agent-tool.mjs +138 -669
- package/src/standalone/channel-admin.mjs +102 -90
- package/src/standalone/channel-worker.mjs +4 -7
- package/src/standalone/explore-tool.mjs +64 -14
- package/src/standalone/hook-bus/config.mjs +207 -0
- package/src/standalone/hook-bus/constants.mjs +90 -0
- package/src/standalone/hook-bus/handlers.mjs +481 -0
- package/src/standalone/hook-bus/payload.mjs +31 -0
- package/src/standalone/hook-bus/rules.mjs +77 -0
- package/src/standalone/hook-bus.mjs +77 -870
- package/src/standalone/memory-runtime-proxy.mjs +7 -0
- package/src/standalone/opencode-go-login.mjs +5 -1
- package/src/standalone/provider-admin.mjs +1 -16
- package/src/standalone/usage-dashboard.mjs +3 -1
- package/src/tui/App.jsx +1059 -8110
- package/src/tui/app/app-format.mjs +213 -0
- package/src/tui/app/channel-pickers.mjs +508 -0
- package/src/tui/app/clipboard.mjs +67 -0
- package/src/tui/app/core-memory-picker.mjs +210 -0
- package/src/tui/app/extension-pickers.mjs +506 -0
- package/src/tui/app/input-parsers.mjs +193 -0
- package/src/tui/app/maintenance-pickers.mjs +356 -0
- package/src/tui/app/model-options.mjs +334 -0
- package/src/tui/app/model-picker.mjs +365 -0
- package/src/tui/app/onboarding-steps.mjs +400 -0
- package/src/tui/app/project-picker.mjs +247 -0
- package/src/tui/app/provider-setup-picker.mjs +580 -0
- package/src/tui/app/resume-picker.mjs +55 -0
- package/src/tui/app/route-pickers.mjs +419 -0
- package/src/tui/app/settings-picker.mjs +489 -0
- package/src/tui/app/slash-commands.mjs +101 -0
- package/src/tui/app/slash-dispatch.mjs +427 -0
- package/src/tui/app/text-layout.mjs +46 -0
- package/src/tui/app/theme-effort-pickers.mjs +154 -0
- package/src/tui/app/transcript-window.mjs +677 -0
- package/src/tui/app/use-mouse-input.mjs +460 -0
- package/src/tui/app/use-prompt-handlers.mjs +310 -0
- package/src/tui/app/use-transcript-scroll.mjs +512 -0
- package/src/tui/app/use-transcript-window.mjs +607 -0
- package/src/tui/components/ConfirmBar.jsx +10 -7
- package/src/tui/components/Picker.jsx +64 -15
- package/src/tui/components/PromptInput.jsx +33 -102
- package/src/tui/components/SlashCommandPalette.jsx +8 -1
- package/src/tui/components/StatusLine.jsx +69 -15
- package/src/tui/components/TextEntryPanel.jsx +11 -0
- package/src/tui/components/ToolExecution.jsx +52 -594
- package/src/tui/components/TranscriptItem.jsx +105 -0
- package/src/tui/components/UsagePanel.jsx +18 -4
- package/src/tui/components/prompt-input/edit-helpers.mjs +72 -0
- package/src/tui/components/prompt-input/voice-indicator.mjs +39 -0
- package/src/tui/components/tool-execution/ResultBody.jsx +56 -0
- package/src/tui/components/tool-execution/surface-detail.mjs +405 -0
- package/src/tui/components/tool-execution/text-format.mjs +161 -0
- package/src/tui/display-width.mjs +20 -3
- package/src/tui/dist/index.mjs +13553 -12384
- package/src/tui/engine/agent-job-feed.mjs +133 -0
- package/src/tui/engine/notification-plan.mjs +76 -0
- package/src/tui/engine/render-timing.mjs +17 -0
- package/src/tui/engine/tool-approval.mjs +94 -0
- package/src/tui/engine/tool-card-results.mjs +234 -0
- package/src/tui/engine/tool-result-status.mjs +135 -0
- package/src/tui/engine.mjs +170 -574
- package/src/tui/figures.mjs +5 -0
- package/src/tui/index.jsx +65 -1
- package/src/tui/input-editing.mjs +2 -2
- package/src/tui/markdown/format-token.mjs +4 -1
- package/src/tui/statusline-ansi-bridge.mjs +11 -3
- package/src/tui/theme.mjs +6 -0
- package/src/ui/statusline-agents.mjs +213 -0
- package/src/ui/statusline-format.mjs +146 -0
- package/src/ui/statusline-segments.mjs +148 -0
- package/src/ui/statusline.mjs +77 -501
- package/src/ui/tool-card.mjs +0 -1
- package/src/vendor/statusline/bin/statusline-route.mjs +15 -2
- package/src/workflows/default/WORKFLOW.md +16 -18
- package/src/workflows/sequential/WORKFLOW.md +16 -18
- package/vendor/ink/build/display-width.js +19 -3
- package/vendor/ink/build/ink.js +112 -7
- package/vendor/ink/build/log-update.js +17 -3
- package/vendor/ink/build/wrap-text.js +125 -0
- package/scripts/_test-folder-dialog.mjs +0 -30
- package/scripts/fix-brief-fn.mjs +0 -35
- package/scripts/fix-format-tool-surface.mjs +0 -24
- package/scripts/fix-tool-exec-visible.mjs +0 -42
- package/scripts/patch-agent-brief.mjs +0 -48
- package/scripts/patch-app.mjs +0 -21
- package/scripts/patch-app2.mjs +0 -18
- package/scripts/patch-dist-brief.mjs +0 -96
- package/scripts/patch-tool-exec.mjs +0 -70
- package/src/examples/schedules/SCHEDULE.example.md +0 -32
- package/src/examples/webhooks/WEBHOOK.example.md +0 -40
- package/src/runtime/agent/orchestrator/session/manager.reactive-persist.test.mjs +0 -107
- package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.test.mjs +0 -143
- package/src/runtime/agent/orchestrator/tools/builtin/diagnostics-tool.mjs +0 -285
- package/src/runtime/agent/orchestrator/tools/builtin/external-tool-adapters.test.mjs +0 -162
- package/src/runtime/agent/orchestrator/tools/builtin/open-config-tool.mjs +0 -26
- package/src/runtime/channels/lib/holidays.mjs +0 -138
- package/src/runtime/shared/channel-notification-routing.test.mjs +0 -45
- package/src/runtime/shared/task-notification-envelope.test.mjs +0 -107
- package/src/runtime/shared/tool-execution-contract.test.mjs +0 -183
- package/src/standalone/agent-task-status.test.mjs +0 -76
- package/src/tui/components/tool-output-format.test.mjs +0 -399
- package/src/tui/display-width.test.mjs +0 -35
- package/src/tui/engine-runtime-notification.test.mjs +0 -115
- package/src/tui/engine-tool-result-text.test.mjs +0 -75
- package/src/tui/input-editing.selection.test.mjs +0 -75
- package/src/tui/markdown/format-token.test.mjs +0 -354
- package/src/tui/markdown/render-ansi.test.mjs +0 -108
- package/src/tui/markdown/stream-fence.test.mjs +0 -26
- package/src/tui/markdown/streaming-markdown.test.mjs +0 -70
- package/src/tui/paste-fix.test.mjs +0 -119
- package/src/tui/prompt-history-store.test.mjs +0 -52
- package/src/tui/statusline-ansi-bridge.test.mjs +0 -159
- package/src/tui/transcript-tool-failures.test.mjs +0 -111
- package/src/ui/markdown.test.mjs +0 -70
- package/src/ui/statusline-context-label.test.mjs +0 -15
- package/src/vendor/statusline/bin/statusline-lib.mjs +0 -186
- package/src/vendor/statusline/bin/statusline-route.test.mjs +0 -80
|
@@ -7,21 +7,42 @@ keep-coding-instructions: true
|
|
|
7
7
|
|
|
8
8
|
# Output Style
|
|
9
9
|
|
|
10
|
-
Mixdog default — the most detailed
|
|
11
|
-
|
|
10
|
+
Mixdog default — the most detailed style, but always summary-form, never
|
|
11
|
+
essay-form. Depth comes from picking the right facts, not explaining more.
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
-
|
|
17
|
-
|
|
18
|
-
|
|
13
|
+
Content
|
|
14
|
+
- Lead with the outcome in one short sentence, then only the detail that
|
|
15
|
+
matters: what changed, key evidence (paths, commands, errors, verification).
|
|
16
|
+
- Summarize at the concept level: name the problem/behavior and direction, not
|
|
17
|
+
the code path. Cite a symbol/path only as an anchor, never as the explanation.
|
|
18
|
+
- Compress by cutting content (filler, hedging, connective padding, restated
|
|
19
|
+
facts), not by clipping grammar: keep natural, complete sentences in the
|
|
20
|
+
user's language — never telegraph-style stub endings. Technical terms and
|
|
21
|
+
code stay exact.
|
|
22
|
+
- State conclusions, not reasoning: no mechanism walkthroughs, background, or
|
|
23
|
+
chained qualifiers unless asked. One decisive fact beats three hedges.
|
|
24
|
+
- Say each point once: problem and fix in ONE compact statement, not a restated
|
|
25
|
+
pair. Prefer fewer, denser items over covering every nuance.
|
|
26
|
+
- Size budget: roughly TWICE the Simple style — per point about 2 rendered
|
|
27
|
+
lines, whole report ~10–15 lines. Spend the extra room on evidence and
|
|
28
|
+
context Simple would drop, not on longer sentences.
|
|
19
29
|
- Use labels such as `바뀐 점`, `확인한 것`, and `남은 리스크/다음 단계`
|
|
20
30
|
in final reports to structure the summary; skip labels on interim progress.
|
|
21
31
|
- Collapse trivial tasks to a couple of sentences instead of forcing sections.
|
|
22
32
|
- Synthesize agent or retrieval results; never forward raw reports, long file
|
|
23
33
|
lists, tool traces, or session metadata.
|
|
24
34
|
- Do not hide blockers, failed verification, or required follow-up; surface them
|
|
25
|
-
|
|
35
|
+
in one short clause.
|
|
26
36
|
- Keep paths, commands, symbols, API names, code, and exact errors verbatim.
|
|
37
|
+
|
|
38
|
+
Layout (hard rules)
|
|
39
|
+
- One bullet or numbered item = one idea, at most 2 rendered lines including its
|
|
40
|
+
sub-bullet. If it needs more, cut the detail — do not add lines.
|
|
41
|
+
- Open each item with a short **bold key point**, then the brief elaboration —
|
|
42
|
+
never bury the point mid-sentence.
|
|
43
|
+
- Insert a blank line between numbered items, and between any list items running
|
|
44
|
+
past one line (loose list). Never emit a wall of consecutive multi-line items.
|
|
45
|
+
- Keep paragraphs to ~3 lines max, with a blank line between paragraphs, lists,
|
|
46
|
+
and code blocks.
|
|
47
|
+
- Nest at most one sub-level; deeper detail means you are over-explaining.
|
|
27
48
|
- Never name this style unless asked.
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
---
|
|
2
|
-
name:
|
|
3
|
-
title:
|
|
2
|
+
name: extreme-minimal
|
|
3
|
+
title: Extreme Minimal
|
|
4
4
|
description: Single sentence under 100 characters
|
|
5
|
-
aliases: one-line, one line, mono
|
|
5
|
+
aliases: extreme, oneline, one-line, one line, mono
|
|
6
6
|
keep-coding-instructions: true
|
|
7
7
|
---
|
|
8
8
|
|
|
9
9
|
# Output Style
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
Extreme minimal — the most compressed style: exactly one sentence, under 100
|
|
12
|
+
characters.
|
|
12
13
|
|
|
13
14
|
- Reply with a SINGLE sentence, always under 100 characters. Never a second
|
|
14
15
|
sentence, clause pile-up, or run-on that smuggles in extra facts.
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
name: minimal
|
|
3
3
|
title: Minimal
|
|
4
4
|
description: One- or two-sentence summary
|
|
5
|
-
aliases: extreme, extreme-simple
|
|
6
5
|
keep-coding-instructions: true
|
|
7
6
|
---
|
|
8
7
|
|
|
@@ -12,12 +11,15 @@ Minimal — a very short summary: one or two sentences, nothing more.
|
|
|
12
11
|
|
|
13
12
|
- Summarize only the net result in one short sentence; add a second short
|
|
14
13
|
sentence only if a second fact (verification, blocker) genuinely needs it.
|
|
15
|
-
Never cram unrelated facts into
|
|
16
|
-
-
|
|
17
|
-
|
|
14
|
+
Never cram unrelated facts into a run-on just to stay at one sentence.
|
|
15
|
+
- Size budget: roughly HALF the Simple style — 1–2 plain sentences, ~2–3
|
|
16
|
+
rendered lines at most, however large the task was.
|
|
17
|
+
- Compress by cutting content, not grammar: natural, complete sentences only.
|
|
18
|
+
Concept-level only — never walk through code or mechanisms.
|
|
19
|
+
- Summarize, never itemize: do not describe which files changed or how. State
|
|
20
|
+
only what the change accomplishes.
|
|
18
21
|
- No headings, bullets, numbered lists, labels, or sections — plain sentences
|
|
19
|
-
only
|
|
20
|
-
one or two sentences regardless.
|
|
22
|
+
only, even when the request says "report" or "summary".
|
|
21
23
|
- Preferred pattern: `<target> 변경되었습니다. <verification> 통과 완료입니다.`
|
|
22
24
|
- If verification was not run, say the change is done and verification was not
|
|
23
25
|
run.
|
|
@@ -8,16 +8,30 @@ keep-coding-instructions: true
|
|
|
8
8
|
|
|
9
9
|
# Output Style
|
|
10
10
|
|
|
11
|
-
Practical concise — outcome-first handoffs for coding work: summarize the
|
|
12
|
-
do not narrate the change.
|
|
11
|
+
Practical concise — outcome-first handoffs for coding work: summarize the
|
|
12
|
+
result, do not narrate or explain the change.
|
|
13
13
|
|
|
14
14
|
- Open with the outcome in one sentence: done, blocked, or awaiting a decision.
|
|
15
|
+
- Summarize at the concept level: name the behavior and direction, not the code
|
|
16
|
+
path. Cite a symbol/path only as an anchor, never as the explanation.
|
|
17
|
+
- Compress by cutting content (filler, hedging, pleasantries, restated facts),
|
|
18
|
+
not by clipping grammar: keep natural, complete sentences in the user's
|
|
19
|
+
language — never telegraph-style stub endings. Technical terms and code stay
|
|
20
|
+
exact.
|
|
15
21
|
- Summarize what the change accomplishes rather than listing every file and how
|
|
16
22
|
each was edited. Name a path (`file_path:line_number`) only when the reader
|
|
17
23
|
truly needs it to navigate — not as a per-file changelog.
|
|
18
|
-
- Keep controlled detail: usually 1–3 short bullets or 2–
|
|
19
|
-
|
|
20
|
-
|
|
24
|
+
- Keep controlled detail: usually 1–3 short bullets or 2–3 sentences total.
|
|
25
|
+
State each point once — outcome or fix direction, not both restated. No
|
|
26
|
+
step-by-step narration or file/line inventory.
|
|
27
|
+
- Size budget: roughly HALF the Default style and TWICE Minimal — per point one
|
|
28
|
+
rendered line, whole reply ~5–7 lines. Above that you are writing Default;
|
|
29
|
+
below ~3 lines consider whether prose (Minimal) reads better.
|
|
30
|
+
- Layout: one idea per bullet, ONE line each (two only when a verbatim
|
|
31
|
+
path/error forces it). Lead each item with a short bold key phrase. Put a
|
|
32
|
+
blank line between multi-line list items — never emit a dense wall of text.
|
|
33
|
+
- If a point runs past one line, cut the elaboration instead of wrapping; detail
|
|
34
|
+
beyond the key phrase + one clause belongs to the Default style.
|
|
21
35
|
- On final handoffs, optional labels such as `바뀐 점`, `확인한 것`, and
|
|
22
36
|
`남은 리스크/다음 단계` fit Korean-facing profiles; use plain English labels
|
|
23
37
|
when the thread is English. Do not label interim progress.
|
|
@@ -26,6 +40,6 @@ do not narrate the change.
|
|
|
26
40
|
- Do not hide blockers, failed verification, or required follow-up; state them
|
|
27
41
|
in one short clause.
|
|
28
42
|
- Keep paths, commands, symbols, API names, code, and exact errors verbatim.
|
|
29
|
-
- Skip filler, acknowledgments, and repeated conclusions; if
|
|
30
|
-
not run, say so once.
|
|
43
|
+
- Skip filler, acknowledgments, hedging, and repeated conclusions; if
|
|
44
|
+
verification was not run, say so once.
|
|
31
45
|
- Never name this style unless asked.
|
|
@@ -3,15 +3,18 @@
|
|
|
3
3
|
- Use English for agent task communication.
|
|
4
4
|
- Do not touch git/Ship. Even when the brief instructs `git add` / `commit` /
|
|
5
5
|
`push` / `stash`, refuse with `git operations deferred to Lead`.
|
|
6
|
-
- NEVER PREAMBLE
|
|
7
|
-
|
|
8
|
-
text before tool calls.
|
|
6
|
+
- NEVER PREAMBLE: no tool-call preambles, status/progress narration, "I
|
|
7
|
+
will..." setup, or transition text before tool calls.
|
|
9
8
|
- If tools are needed, call them immediately. Emit text only for the final
|
|
10
9
|
handoff after tool work is done.
|
|
11
10
|
- Final handoff: minimum characters, maximum information for Lead. Follow the
|
|
12
11
|
role's stricter output contract if defined; else emit fragments — outcome
|
|
13
12
|
(1 line), key `file:line`(s), verification result, material risks (only if
|
|
14
13
|
any).
|
|
14
|
+
- Handoff cap ~30 lines unless `Deliver:` raises it. Overflow goes to a file;
|
|
15
|
+
hand off path + fragments.
|
|
15
16
|
- Banned as pure cost: report headings, markdown tables (unless requested),
|
|
16
17
|
prose narration, raw logs/tool traces, speculative next-checks, restated
|
|
17
18
|
brief, articles/politeness.
|
|
19
|
+
- Exception: a runtime wrap-up directive (exploration budget reached) overrides
|
|
20
|
+
this — then summarize done/remaining/blocking as instructed.
|
|
@@ -8,11 +8,22 @@ kind: retrieval
|
|
|
8
8
|
|
|
9
9
|
You are a one-shot locator, not a researcher.
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
Find code anchors fast. Batch independent lookups in turn 1: one `grep`
|
|
12
|
+
with all literal strings/errors/identifier guesses, plus `code_graph`/`find`
|
|
13
|
+
or `glob` when useful.
|
|
14
|
+
|
|
15
|
+
Prefer user-visible strings and identifiers. `dist`/generated hits are leads,
|
|
16
|
+
not answers: trace them back to source. On miss, derive new tokens from
|
|
17
|
+
returned paths/names or widen scope; do not repeat synonyms. NEVER issue
|
|
18
|
+
serial single-tool turns: every turn after the first must batch ALL remaining
|
|
19
|
+
candidate lookups in one shot.
|
|
20
|
+
|
|
21
|
+
Budget: 4 tool turns. The FIRST credible `path:line` ends the search — answer
|
|
22
|
+
with what you have; more anchors are not more value. Spend remaining turns
|
|
23
|
+
only while you have zero anchors, and buy coverage with wider batches, never
|
|
24
|
+
with extra serial turns. On ANY iteration warning, answer immediately with
|
|
25
|
+
best anchors or `EXPLORATION_FAILED`.
|
|
15
26
|
|
|
16
27
|
Answer format, nothing else:
|
|
17
|
-
- up to 5 lines
|
|
28
|
+
- up to 5 lines: `path:line — symbol/name — short reason` (append `?` if weak)
|
|
18
29
|
- or `EXPLORATION_FAILED`
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
# General
|
|
2
2
|
|
|
3
3
|
- Omit direct names, honorifics, headings, and labels in preambles.
|
|
4
|
-
- Preambles are optional: use
|
|
5
|
-
|
|
4
|
+
- Preambles are optional: use only when they add user-visible value, keep to
|
|
5
|
+
one short sentence, skip routine lookup narration.
|
|
6
6
|
- Destructive/hard-to-reverse actions require explicit confirmation.
|
|
7
7
|
- Never push, build, or deploy without an explicit user request.
|
|
8
8
|
Implementation approval is not deploy approval.
|
|
9
|
-
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
- Proactively handle what you can first rather than deferring to the user;
|
|
10
|
+
propose only the parts needing a decision, consultatively ("Shall we
|
|
11
|
+
proceed this way?").
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Lead Brief Contract
|
|
2
|
+
|
|
3
|
+
- Brief = one-line fragments `Goal:` `Anchors:` `Allow/Forbid:` `Deliver:`
|
|
4
|
+
`Verify:` (+`Stop:` heavy-worker). No role-known rules, background, or
|
|
5
|
+
motivation — minimum characters, maximum information.
|
|
6
|
+
- `Deliver:` states output size/shape (e.g. "fragments <=15 lines", "verdict
|
|
7
|
+
+ top-3 risks", "detail to file, path only"). Never request a long report
|
|
8
|
+
in the handoff itself.
|
|
9
|
+
- Full brief only on fresh spawn or `respawned: true` (dead-tag send = cold
|
|
10
|
+
session; re-supply anchors). Live-session follow-ups = delta only; never
|
|
11
|
+
restate Goal/rules.
|
|
12
|
+
- Never `send` mid-run; batch all adjustments into ONE follow-up after
|
|
13
|
+
completion. Interrupt only to cancel.
|
|
14
|
+
- All agent communication in English.
|
|
15
|
+
- Referenced spec/test file beats its summary in the brief.
|
|
@@ -1,17 +1,8 @@
|
|
|
1
1
|
# Lead Tool Use
|
|
2
2
|
|
|
3
|
-
- Lead owns repo-local shell work: run git/build/test/verification
|
|
4
|
-
|
|
5
|
-
- Use the current project/workspace
|
|
6
|
-
|
|
7
|
-
-
|
|
8
|
-
|
|
9
|
-
context — treat the message as a cold brief and re-supply anchors
|
|
10
|
-
(`file:line`) on it or the next send.
|
|
11
|
-
- Briefs: minimum characters, maximum information. Fixed one-line fragment
|
|
12
|
-
fields — `Goal:` `Anchors:` `Allow/Forbid:` `Deliver:` `Verify:` (+`Stop:` for
|
|
13
|
-
heavy-worker). Omit role-known rules (git/preamble bans, output format),
|
|
14
|
-
background, motivation; non-actionable tokens are wasted cost.
|
|
15
|
-
- Bridge language is ALWAYS English: every brief, follow-up `send`, and
|
|
16
|
-
steering message to an agent is written in English regardless of the
|
|
17
|
-
user-facing language.
|
|
3
|
+
- Lead owns repo-local shell work: run git/build/test/verification via `shell`
|
|
4
|
+
directly; do not delegate to agents.
|
|
5
|
+
- Use the session's current project/workspace. Change the work project only
|
|
6
|
+
when the user asks for another project or a tool call needs another root.
|
|
7
|
+
- Use `agent` for scoped implementation, research, review, and debugging — not
|
|
8
|
+
for git commit/push/stash or Ship.
|
|
@@ -1,25 +1,21 @@
|
|
|
1
1
|
# Tool Use
|
|
2
2
|
|
|
3
|
-
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
-
|
|
11
|
-
`
|
|
12
|
-
|
|
13
|
-
patterns or scopes.
|
|
3
|
+
- Batch independent lookups in one turn; serialize only when a call needs a
|
|
4
|
+
prior result — including edit loops: batch the post-edit verification read
|
|
5
|
+
with the next target's lookup.
|
|
6
|
+
- Pick by target: symbols/callers/deps → `code_graph`; exact text in a verified
|
|
7
|
+
scope → `grep`; unknown path/name → `find`; structure → `glob`; dirs →
|
|
8
|
+
`list`; verified file → `read`; broad unknown with no anchor → `explore`.
|
|
9
|
+
Never `grep`/`read` guessed paths.
|
|
10
|
+
- One concept → one batched `grep pattern:[...]` with
|
|
11
|
+
`output_mode:"content_with_context"` (or one `code_graph symbols[]`). Refine
|
|
12
|
+
from returned paths; never repeat equivalent patterns or scopes.
|
|
14
13
|
- On miss/error, normalize the target once and switch tool; on a plausible hit,
|
|
15
|
-
stop
|
|
16
|
-
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
`{path,offset,limit}` region objects instead of serial reads. Adjacent spans
|
|
23
|
-
in the same file (within a few hundred lines) are ONE window, not repeated
|
|
24
|
-
reads.
|
|
14
|
+
stop and answer from the framed context.
|
|
15
|
+
- Retrieval serves the NEXT action (edit, answer, handoff), not certainty. One
|
|
16
|
+
anchor is enough to act on; re-reading/re-grepping an area seen this session
|
|
17
|
+
is waste. When acting and looking are both possible, act.
|
|
18
|
+
- `read` uses `offset`/`limit` only. For 2+ spans from known file(s), make one
|
|
19
|
+
batched `read` with `{path,offset,limit}` region objects. Adjacent spans in
|
|
20
|
+
one file (within a few hundred lines) are ONE window, not repeated reads.
|
|
25
21
|
- Don't mix `apply_patch` with shell or other state-changing calls in one turn.
|
|
@@ -356,6 +356,10 @@ export function makeAgentDispatch(opts = {}) {
|
|
|
356
356
|
if (_idleController) {
|
|
357
357
|
try { _linkSignal(session.id, _idleController.signal); } catch { /* ignore */ }
|
|
358
358
|
}
|
|
359
|
+
// Watchdog blind spot guard: when the runtime snapshot is missing AND
|
|
360
|
+
// no progress timestamp exists (pre-liveness hang, swept runtime), the
|
|
361
|
+
// dispatch start time anchors staleness so the abort still fires.
|
|
362
|
+
const _watchdogAnchorTs = Date.now();
|
|
359
363
|
const _idleTimer = (_idleController && (typeof _getProgressSnapshot === 'function' || typeof _getLastProgressAt === 'function'))
|
|
360
364
|
? setInterval(() => {
|
|
361
365
|
const now = Date.now();
|
|
@@ -363,9 +367,10 @@ export function makeAgentDispatch(opts = {}) {
|
|
|
363
367
|
const abortErr = snapshot
|
|
364
368
|
? evaluateAgentWatchdogAbort(snapshot, now, _watchdogPolicy)
|
|
365
369
|
: null;
|
|
366
|
-
if (!abortErr && !snapshot
|
|
367
|
-
const
|
|
368
|
-
|
|
370
|
+
if (!abortErr && !snapshot) {
|
|
371
|
+
const reported = typeof _getLastProgressAt === 'function' ? _getLastProgressAt(session.id) : 0;
|
|
372
|
+
const last = reported || _watchdogAnchorTs;
|
|
373
|
+
if (_watchdogPolicy.idleStaleMs > 0 && now - last > _watchdogPolicy.idleStaleMs) {
|
|
369
374
|
try { _idleController.abort(new Error(`agent task stale (${_watchdogPolicy.idleStaleMs}ms without progress)`)); } catch { /* ignore */ }
|
|
370
375
|
}
|
|
371
376
|
return;
|
|
@@ -17,6 +17,31 @@ function envPositiveInt(name, fallback) {
|
|
|
17
17
|
// to raise/lower the safety ceiling, never used as a per-agent task budget.
|
|
18
18
|
export const LEAD_MAX_LOOP_ITERATIONS = envPositiveInt('MIXDOG_AGENT_MAX_LOOP', 200);
|
|
19
19
|
|
|
20
|
+
// Worker soft cap — behavior-based ONLY. There is intentionally no fixed
|
|
21
|
+
// iteration threshold: a legitimately long worker task (many edit/verify
|
|
22
|
+
// rounds) must never be cut off by a count. The wrap-up is armed exclusively
|
|
23
|
+
// by the steering ladder's early-cap signal (repeated ignored level-2 steers
|
|
24
|
+
// with zero edits = confirmed read-only stall), after the ladder's own
|
|
25
|
+
// warnings have gone out. The env knob remains as an opt-in count for
|
|
26
|
+
// operators who want one; by default it is effectively disabled.
|
|
27
|
+
export const WORKER_SOFT_CAP_ITERATIONS = envPositiveInt('MIXDOG_AGENT_SOFT_CAP', Number.MAX_SAFE_INTEGER);
|
|
28
|
+
|
|
29
|
+
// Agents subject to the soft cap: implementation workers that should wrap up
|
|
30
|
+
// once the exploration budget is spent. Reviewer and hidden long-runner agents
|
|
31
|
+
// (explorer / cycle / scheduler / …) are legitimately read-only long-running
|
|
32
|
+
// and are EXEMPT — capping them would truncate a valid long read pass.
|
|
33
|
+
const SOFT_CAP_AGENTS = new Set(['worker', 'heavy-worker', 'maintainer', 'debugger']);
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Is this session a delegated worker subject to the soft cap?
|
|
37
|
+
* Only worker/heavy-worker/maintainer/debugger. Lead, TUI (no agent),
|
|
38
|
+
* reviewer, and hidden agents return false.
|
|
39
|
+
*/
|
|
40
|
+
export function isWorkerSoftCapSession(sessionRef) {
|
|
41
|
+
const agent = sessionRef?.agent;
|
|
42
|
+
return typeof agent === 'string' && SOFT_CAP_AGENTS.has(agent);
|
|
43
|
+
}
|
|
44
|
+
|
|
20
45
|
/**
|
|
21
46
|
* Resolve the hard cap used by agentLoop for this session.
|
|
22
47
|
*
|
|
@@ -10,7 +10,8 @@
|
|
|
10
10
|
* BP_1 system#1 (1h) — shared tool policy + compact skill manifest
|
|
11
11
|
* BP_2 system#2 (1h) — role/system rules (Lead / agent / hidden role)
|
|
12
12
|
* BP_3 system#3 (1h) — stable memory/meta marker (sessionMarker system block; tier3)
|
|
13
|
-
* BP_4 messages (5m
|
|
13
|
+
* BP_4 messages (5m agents/hidden; Lead linked to autoClear — see below) —
|
|
14
|
+
* sliding tool_result / prior user-text tail
|
|
14
15
|
*
|
|
15
16
|
* Tool schemas still sit before system in the provider prompt prefix. We do
|
|
16
17
|
* not spend a separate cache_control slot on tools; the first system BP covers
|
|
@@ -51,10 +52,14 @@ import { getHiddenAgent } from '../internal-agents.mjs';
|
|
|
51
52
|
*/
|
|
52
53
|
function isOneShotMaintenanceAgent(agent) {
|
|
53
54
|
const hidden = getHiddenAgent(agent);
|
|
55
|
+
// Shipped cycle1/2/3 declare toolSchemaProfile:'none' (no tool schema at
|
|
56
|
+
// all); 'llm-only' is the legacy alias for the same one-shot LLM-only
|
|
57
|
+
// pattern. Multi-turn maintenance roles (scheduler-task/webhook-handler)
|
|
58
|
+
// are 'read-write-search' and stay excluded.
|
|
54
59
|
return Boolean(
|
|
55
60
|
hidden
|
|
56
61
|
&& hidden.kind === 'maintenance'
|
|
57
|
-
&& hidden.toolSchemaProfile === 'llm-only',
|
|
62
|
+
&& (hidden.toolSchemaProfile === 'llm-only' || hidden.toolSchemaProfile === 'none'),
|
|
58
63
|
);
|
|
59
64
|
}
|
|
60
65
|
|
|
@@ -71,8 +76,16 @@ function isOneShotMaintenanceAgent(agent) {
|
|
|
71
76
|
* warm window survives per-session gaps. The volatile message tail (BP4) is
|
|
72
77
|
* per-session and trace data (2026-06) shows request gaps are p99 ≈ 4.5min —
|
|
73
78
|
* 5m+ gaps mean a cold tail anyway, and the smart-compact path rebuilds the
|
|
74
|
-
* history at that boundary. So
|
|
75
|
-
* (1.25x write vs 2x), aligned with the 5m
|
|
79
|
+
* history at that boundary. So hidden-agent and public-agent sessions keep
|
|
80
|
+
* the cheaper 5m tail TTL (1.25x write vs 2x), aligned with the 5m
|
|
81
|
+
* terminal-reap window for agents.
|
|
82
|
+
*
|
|
83
|
+
* Lead sessions are linked to the user's autoClear idle-sweep config
|
|
84
|
+
* instead of the fixed 5m default (see resolveLeadMessagesTtl): a Lead
|
|
85
|
+
* session that autoClear will only reap after a long/never idle window
|
|
86
|
+
* benefits from the 1h tail TTL (fewer writes over a long-lived session),
|
|
87
|
+
* while a short idle-sweep window means the tail is going cold anyway and
|
|
88
|
+
* 5m is cheaper to write.
|
|
76
89
|
* (Tail TTL only affects explicit-breakpoint providers — Anthropic; no-op
|
|
77
90
|
* elsewhere.)
|
|
78
91
|
*
|
|
@@ -84,15 +97,41 @@ function isOneShotMaintenanceAgent(agent) {
|
|
|
84
97
|
* the 1h TTL expiry (writes every run, 0 reads). All layers go 'none' for
|
|
85
98
|
* these roles — single-iteration calls pay the write premium with no reuse.
|
|
86
99
|
*/
|
|
87
|
-
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Lead-session BP4 (messages tail) TTL, linked to the autoClear idle-sweep
|
|
103
|
+
* config (config.mjs `autoClear: { enabled, idleMs }`, normalized via
|
|
104
|
+
* session-runtime/config-helpers.mjs normalizeAutoClearConfig):
|
|
105
|
+
* - autoClear disabled → '1h' (session may live indefinitely;
|
|
106
|
+
* amortize the 2x write premium over a long-lived tail)
|
|
107
|
+
* - idleMs >= 1h (3_600_000ms) → '1h' (idle-sweep window is at least
|
|
108
|
+
* as long as the 1h TTL, so the longer TTL is never wasted)
|
|
109
|
+
* - otherwise (shorter idle-sweep) → '5m' (session reaps before a 1h
|
|
110
|
+
* write would ever be re-read; cheaper 5m write wins)
|
|
111
|
+
*/
|
|
112
|
+
export function resolveLeadMessagesTtl(autoClear) {
|
|
113
|
+
if (autoClear && autoClear.enabled === false) return '1h';
|
|
114
|
+
const idleMs = Number(autoClear?.idleMs);
|
|
115
|
+
if (Number.isFinite(idleMs) && idleMs >= 3_600_000) return '1h';
|
|
116
|
+
return '5m';
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export function resolveCacheStrategy(agent, { autoClear } = {}) {
|
|
88
120
|
if (isOneShotMaintenanceAgent(agent)) {
|
|
89
121
|
return { tools: 'none', system: 'none', tier3: 'none', messages: 'none' };
|
|
90
122
|
}
|
|
91
123
|
if (getHiddenAgent(agent)) {
|
|
92
124
|
return { tools: 'none', system: '1h', tier3: '1h', messages: '5m' };
|
|
93
125
|
}
|
|
94
|
-
|
|
95
|
-
|
|
126
|
+
if (agent && agent !== 'lead') {
|
|
127
|
+
// Public (non-hidden, non-lead) agents keep the flat 5m tail — only
|
|
128
|
+
// the Lead session's tail is linked to autoClear.
|
|
129
|
+
return { tools: 'none', system: '1h', tier3: '1h', messages: '5m' };
|
|
130
|
+
}
|
|
131
|
+
// Lead session (agent === 'lead', or no agent — raw/CLI callers default
|
|
132
|
+
// to Lead behavior): message tail TTL is linked to autoClear (see
|
|
133
|
+
// resolveLeadMessagesTtl).
|
|
134
|
+
return { tools: 'none', system: '1h', tier3: '1h', messages: resolveLeadMessagesTtl(autoClear) };
|
|
96
135
|
}
|
|
97
136
|
|
|
98
137
|
/**
|
|
@@ -200,6 +239,25 @@ function normalizePromptCacheNamespace(value) {
|
|
|
200
239
|
return s.replace(/[^A-Za-z0-9_-]+/g, '-').replace(/^-+|-+$/g, '') || 'mixdog-shared';
|
|
201
240
|
}
|
|
202
241
|
|
|
242
|
+
function fitPromptCacheKey(value, fallback = 'mixdog-shared') {
|
|
243
|
+
const s = normalizePromptCacheNamespace(value || fallback);
|
|
244
|
+
if (s.length <= 64) return s;
|
|
245
|
+
const hash = shortHash(s, 12);
|
|
246
|
+
const head = s.slice(0, Math.max(1, 64 - hash.length - 1));
|
|
247
|
+
return `${head}-${hash}`;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
function codexThreadPromptCacheKey(opts, namespace) {
|
|
251
|
+
const explicit = cleanString(opts?.providerCacheKey)
|
|
252
|
+
|| cleanString(opts?.promptCacheKey)
|
|
253
|
+
|| cleanString(opts?.session?.promptCacheKey);
|
|
254
|
+
if (process.env.MIXDOG_OAI_CACHE_KEY_SHARED === '1') {
|
|
255
|
+
return fitPromptCacheKey(explicit || namespace, 'mixdog-codex');
|
|
256
|
+
}
|
|
257
|
+
const sessionKey = cleanString(opts?.sessionId || opts?.session?.id);
|
|
258
|
+
return fitPromptCacheKey(sessionKey || explicit || namespace, namespace);
|
|
259
|
+
}
|
|
260
|
+
|
|
203
261
|
function summarizePromptCacheTools(tools) {
|
|
204
262
|
return (tools || []).map(t => ({
|
|
205
263
|
type: cleanString(t?.type) || 'function',
|
|
@@ -211,13 +269,19 @@ function summarizePromptCacheTools(tools) {
|
|
|
211
269
|
|
|
212
270
|
/**
|
|
213
271
|
* Build a stable, prefix-scoped prompt_cache_key for OpenAI-style key-prefix
|
|
214
|
-
* providers.
|
|
215
|
-
*
|
|
216
|
-
*
|
|
217
|
-
*
|
|
272
|
+
* providers. OpenAI OAuth follows Codex's thread-scoped key by default:
|
|
273
|
+
* prompt_cache_key is the session/thread identity, clamped to the backend's
|
|
274
|
+
* 64-character limit. Other OpenAI-style providers keep the older
|
|
275
|
+
* namespace+prefix-hash key shape, but no longer get a shard suffix unless an
|
|
276
|
+
* explicit cache-lane override opts into it.
|
|
218
277
|
*/
|
|
219
278
|
export function buildStableProviderPromptCacheKey(provider, opts, prefix = {}) {
|
|
220
279
|
const namespace = normalizePromptCacheNamespace(resolveProviderCacheKey(opts, provider));
|
|
280
|
+
if (provider === 'openai-oauth'
|
|
281
|
+
&& process.env.MIXDOG_OAI_CODEX_THREAD_CACHE_KEY !== '0'
|
|
282
|
+
&& String(process.env.MIXDOG_OAI_CODEX_THREAD_CACHE_KEY || '').toLowerCase() !== 'false') {
|
|
283
|
+
return codexThreadPromptCacheKey(opts, namespace);
|
|
284
|
+
}
|
|
221
285
|
const rawShards = prefix.cacheLaneShards ?? opts?.promptCacheLane?.shards ?? opts?.cacheLaneShards;
|
|
222
286
|
const rawShardMode = String(rawShards ?? '').trim().toLowerCase();
|
|
223
287
|
const autoLane = prefix.cacheLaneAuto === true
|
|
@@ -243,6 +307,16 @@ export function buildStableProviderPromptCacheKey(provider, opts, prefix = {}) {
|
|
|
243
307
|
parallelToolCalls: prefix.parallelToolCalls === false ? false : true,
|
|
244
308
|
cacheLaneSlot: laneEnabled ? shardSlot : null,
|
|
245
309
|
cacheLaneShards: autoLane ? 'auto' : shardCount > 1 ? shardCount : null,
|
|
310
|
+
// Per-session cache-key isolation. R8 A/B (2026-07-03) showed parallel
|
|
311
|
+
// sessions sharing one prompt_cache_key evict each other's transcript
|
|
312
|
+
// body on the server cache node (same key -> same node; bodies differ),
|
|
313
|
+
// producing 8-23% genuine mid-session misses at tens of thousands of
|
|
314
|
+
// uncached tokens each. Mixing sessionId in costs only the small static
|
|
315
|
+
// prefix hit (~2-4k tokens) on a session's FIRST call — every later
|
|
316
|
+
// call's body cache is protected. Opt out: MIXDOG_OAI_CACHE_KEY_SHARED=1.
|
|
317
|
+
session: process.env.MIXDOG_OAI_CACHE_KEY_SHARED === '1'
|
|
318
|
+
? null
|
|
319
|
+
: cleanString(opts?.sessionId || opts?.session?.id || '') || null,
|
|
246
320
|
};
|
|
247
321
|
const hash = shortHash(seed);
|
|
248
322
|
const head = namespace.slice(0, Math.max(1, 64 - hash.length - laneSuffix.length - 1));
|
|
@@ -255,7 +329,7 @@ function providerEnvKey(provider) {
|
|
|
255
329
|
|
|
256
330
|
const providerPromptCacheLaneAssignments = new Map();
|
|
257
331
|
const PROVIDER_PROMPT_CACHE_LANE_MAX_ASSIGNMENTS = 4096;
|
|
258
|
-
const DEFAULT_PROVIDER_PROMPT_CACHE_LANE_SHARDS =
|
|
332
|
+
const DEFAULT_PROVIDER_PROMPT_CACHE_LANE_SHARDS = 1;
|
|
259
333
|
|
|
260
334
|
function promptCacheLaneGroupKey(provider, opts) {
|
|
261
335
|
return [
|
|
@@ -282,6 +356,10 @@ function parsePromptCacheLaneLimit(raw, fallback = DEFAULT_PROVIDER_PROMPT_CACHE
|
|
|
282
356
|
return Math.floor(n);
|
|
283
357
|
}
|
|
284
358
|
|
|
359
|
+
function defaultPromptCacheLaneShards(_provider) {
|
|
360
|
+
return DEFAULT_PROVIDER_PROMPT_CACHE_LANE_SHARDS;
|
|
361
|
+
}
|
|
362
|
+
|
|
285
363
|
function assignPromptCacheLaneSlot(provider, opts, shards, seed, { auto = false } = {}) {
|
|
286
364
|
const explicit = opts?.promptCacheLaneSlot ?? opts?.cacheLaneSlot;
|
|
287
365
|
const explicitSlot = Number(explicit);
|
|
@@ -308,14 +386,9 @@ function assignPromptCacheLaneSlot(provider, opts, shards, seed, { auto = false
|
|
|
308
386
|
}
|
|
309
387
|
|
|
310
388
|
/**
|
|
311
|
-
* Resolve
|
|
312
|
-
*
|
|
313
|
-
*
|
|
314
|
-
* cache hits. OpenAI's prompt caching guide says one prefix+prompt_cache_key
|
|
315
|
-
* combination can overflow around 15 RPM, so transport owns that timing gate.
|
|
316
|
-
* Default to the safer 12-lane pool. Explicit 0/auto/unbounded keeps the
|
|
317
|
-
* no-cap execution mode for callers that prefer throughput over stricter
|
|
318
|
-
* same-key serialization.
|
|
389
|
+
* Resolve an optional cache-lane slot for OpenAI-style prompt cache sharding.
|
|
390
|
+
* Codex does not shard prompt_cache_key by default, so every provider now gets
|
|
391
|
+
* one un-suffixed key unless an env/config override opts into shards.
|
|
319
392
|
*/
|
|
320
393
|
export function resolveProviderPromptCacheLane(provider, opts = {}, config = {}) {
|
|
321
394
|
const envKey = providerEnvKey(provider);
|
|
@@ -338,7 +411,7 @@ export function resolveProviderPromptCacheLane(provider, opts = {}, config = {})
|
|
|
338
411
|
?? env[`MIXDOG_${envKey}_CACHE_MAX_PARALLEL`]
|
|
339
412
|
?? env.MIXDOG_OPENAI_CACHE_LANE_SHARDS
|
|
340
413
|
?? env.MIXDOG_OPENAI_CACHE_MAX_PARALLEL);
|
|
341
|
-
const shards = parsePromptCacheLaneLimit(rawLimit,
|
|
414
|
+
const shards = parsePromptCacheLaneLimit(rawLimit, defaultPromptCacheLaneShards(provider));
|
|
342
415
|
const auto = shards <= 0;
|
|
343
416
|
const seed = cleanString(
|
|
344
417
|
opts?.promptCacheLaneSeed
|
|
@@ -359,8 +432,8 @@ export function resolveProviderPromptCacheLane(provider, opts = {}, config = {})
|
|
|
359
432
|
};
|
|
360
433
|
}
|
|
361
434
|
|
|
362
|
-
export function buildProviderCacheOpts(provider, sessionId, agent) {
|
|
363
|
-
const ttls = resolveCacheStrategy(agent);
|
|
435
|
+
export function buildProviderCacheOpts(provider, sessionId, agent, options = {}) {
|
|
436
|
+
const ttls = resolveCacheStrategy(agent, options);
|
|
364
437
|
const capability = cacheCapabilityForProvider(provider);
|
|
365
438
|
if (capability === 'explicit-breakpoint') {
|
|
366
439
|
// 2026-03-06 Anthropic dropped default TTL 1h→5m. We send
|
|
@@ -368,6 +441,10 @@ export function buildProviderCacheOpts(provider, sessionId, agent) {
|
|
|
368
441
|
// Verified 2026-04-17 (ephemeral_1h_input_tokens=4722).
|
|
369
442
|
return { cacheStrategy: ttls };
|
|
370
443
|
}
|
|
444
|
+
// NOTE: createSession's direct-call site (manager.mjs) only invokes this
|
|
445
|
+
// for explicit-breakpoint (Anthropic-family) providers, so this branch
|
|
446
|
+
// stays reachable only from other callers (none in-tree today) — keeping
|
|
447
|
+
// it here preserves the documented public API/behavior of this function.
|
|
371
448
|
if (provider === 'openai') {
|
|
372
449
|
// Public OpenAI API: prompt_cache_retention extends prefix retention.
|
|
373
450
|
// openai-oauth rejects the header — falls through to default.
|