mixdog 0.9.2 → 0.9.4

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.
Files changed (417) hide show
  1. package/package.json +8 -3
  2. package/scripts/anthropic-maxtokens-test.mjs +119 -0
  3. package/scripts/bench/lead-review-tasks-r3.json +20 -0
  4. package/scripts/bench/lead-review-tasks.json +20 -0
  5. package/scripts/bench/r4-mixed-tasks.json +20 -0
  6. package/scripts/bench/review-tasks.json +20 -0
  7. package/scripts/bench/round-codex.json +114 -0
  8. package/scripts/bench/round-mixdog-lead-r3.json +269 -0
  9. package/scripts/bench/round-mixdog-lead.json +269 -0
  10. package/scripts/bench/round-mixdog.json +126 -0
  11. package/scripts/bench/round-r10-bigsample.json +679 -0
  12. package/scripts/bench/round-r11-codexalign.json +257 -0
  13. package/scripts/bench/round-r4-codex.json +114 -0
  14. package/scripts/bench/round-r4-mixed.json +225 -0
  15. package/scripts/bench/round-r5-gpt-lead.json +259 -0
  16. package/scripts/bench/round-r6-codex.json +114 -0
  17. package/scripts/bench/round-r6-solo.json +257 -0
  18. package/scripts/bench/round-r7-full.json +254 -0
  19. package/scripts/bench/round-r8-fulldefault.json +255 -0
  20. package/scripts/bench-run.mjs +215 -29
  21. package/scripts/build-tui.mjs +13 -1
  22. package/scripts/explore-bench.mjs +124 -0
  23. package/scripts/freevar-smoke.mjs +95 -0
  24. package/scripts/hook-bus-test.mjs +191 -0
  25. package/scripts/internal-comms-bench.mjs +1 -0
  26. package/scripts/internal-comms-smoke.mjs +10 -9
  27. package/scripts/mouse-probe.mjs +45 -0
  28. package/scripts/output-style-bench.mjs +13 -6
  29. package/scripts/output-style-smoke.mjs +4 -4
  30. package/scripts/path-suffix-test.mjs +57 -0
  31. package/scripts/provider-toolcall-test.mjs +7 -3
  32. package/scripts/recall-bench.mjs +207 -0
  33. package/scripts/recall-usecase-cases.json +18 -0
  34. package/scripts/recall-usecase-probe.json +6 -0
  35. package/scripts/session-bench.mjs +152 -6
  36. package/scripts/tool-smoke.mjs +30 -67
  37. package/scripts/tui-render-smoke.mjs +90 -0
  38. package/scripts/webhook-smoke.mjs +208 -0
  39. package/src/agents/debugger/AGENT.md +5 -2
  40. package/src/agents/heavy-worker/AGENT.md +21 -11
  41. package/src/agents/maintainer/AGENT.md +4 -0
  42. package/src/agents/reviewer/AGENT.md +3 -2
  43. package/src/agents/worker/AGENT.md +21 -11
  44. package/src/lib/rules-builder.cjs +4 -0
  45. package/src/mixdog-session-runtime.mjs +933 -3731
  46. package/src/output-styles/default.md +34 -9
  47. package/src/output-styles/{oneline.md → extreme-minimal.md} +5 -4
  48. package/src/output-styles/minimal.md +4 -1
  49. package/src/output-styles/simple.md +22 -7
  50. package/src/repl.mjs +5 -5
  51. package/src/rules/agent/00-common.md +2 -0
  52. package/src/rules/agent/30-explorer.md +8 -11
  53. package/src/rules/lead/lead-brief.md +12 -0
  54. package/src/rules/lead/lead-tool.md +2 -9
  55. package/src/rules/shared/01-tool.md +11 -5
  56. package/src/runtime/agent/orchestrator/agent-runtime/agent-loop-policy.mjs +25 -0
  57. package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +100 -23
  58. package/src/runtime/agent/orchestrator/agent-runtime/session-builder.mjs +6 -15
  59. package/src/runtime/agent/orchestrator/agent-trace-format.mjs +362 -0
  60. package/src/runtime/agent/orchestrator/agent-trace-io.mjs +410 -0
  61. package/src/runtime/agent/orchestrator/agent-trace.mjs +16 -735
  62. package/src/runtime/agent/orchestrator/config.mjs +69 -2
  63. package/src/runtime/agent/orchestrator/context/collect.mjs +51 -0
  64. package/src/runtime/agent/orchestrator/mcp/client.mjs +6 -2
  65. package/src/runtime/agent/orchestrator/providers/anthropic-effort.mjs +63 -21
  66. package/src/runtime/agent/orchestrator/providers/anthropic-max-tokens.mjs +93 -0
  67. package/src/runtime/agent/orchestrator/providers/anthropic-model-resolve.mjs +209 -0
  68. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-credentials.mjs +489 -0
  69. package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +97 -1343
  70. package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +607 -0
  71. package/src/runtime/agent/orchestrator/providers/anthropic.mjs +78 -10
  72. package/src/runtime/agent/orchestrator/providers/api-usage.mjs +1 -13
  73. package/src/runtime/agent/orchestrator/providers/codex-client-meta.mjs +81 -0
  74. package/src/runtime/agent/orchestrator/providers/gemini-cache.mjs +248 -0
  75. package/src/runtime/agent/orchestrator/providers/gemini-schema.mjs +303 -0
  76. package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +505 -0
  77. package/src/runtime/agent/orchestrator/providers/gemini.mjs +44 -1014
  78. package/src/runtime/agent/orchestrator/providers/grok-oauth.mjs +18 -4
  79. package/src/runtime/agent/orchestrator/providers/lib/usage-primitives.mjs +32 -0
  80. package/src/runtime/agent/orchestrator/providers/model-catalog.mjs +86 -11
  81. package/src/runtime/agent/orchestrator/providers/model-list-sanitize.mjs +348 -0
  82. package/src/runtime/agent/orchestrator/providers/oauth-usage.mjs +54 -20
  83. package/src/runtime/agent/orchestrator/providers/openai-codex-model.mjs +108 -0
  84. package/src/runtime/agent/orchestrator/providers/openai-compat-stream.mjs +19 -12
  85. package/src/runtime/agent/orchestrator/providers/openai-compat-trace.mjs +58 -0
  86. package/src/runtime/agent/orchestrator/providers/openai-compat-wire.mjs +368 -0
  87. package/src/runtime/agent/orchestrator/providers/openai-compat-xai.mjs +760 -0
  88. package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +41 -1142
  89. package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +732 -0
  90. package/src/runtime/agent/orchestrator/providers/openai-oauth-login.mjs +193 -0
  91. package/src/runtime/agent/orchestrator/providers/openai-oauth-ws.mjs +303 -2119
  92. package/src/runtime/agent/orchestrator/providers/openai-oauth.mjs +140 -995
  93. package/src/runtime/agent/orchestrator/providers/openai-ws-delta.mjs +227 -0
  94. package/src/runtime/agent/orchestrator/providers/openai-ws-events.mjs +67 -0
  95. package/src/runtime/agent/orchestrator/providers/openai-ws-pool.mjs +436 -0
  96. package/src/runtime/agent/orchestrator/providers/openai-ws-stream.mjs +1105 -0
  97. package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +2 -1
  98. package/src/runtime/agent/orchestrator/providers/opencode-go-usage.mjs +38 -12
  99. package/src/runtime/agent/orchestrator/providers/retry-classifier.mjs +7 -8
  100. package/src/runtime/agent/orchestrator/session/compact/budget.mjs +288 -0
  101. package/src/runtime/agent/orchestrator/session/compact/constants.mjs +85 -0
  102. package/src/runtime/agent/orchestrator/session/compact/engine.mjs +749 -0
  103. package/src/runtime/agent/orchestrator/session/compact/messages.mjs +82 -0
  104. package/src/runtime/agent/orchestrator/session/compact/summary-schema.mjs +315 -0
  105. package/src/runtime/agent/orchestrator/session/compact/summary.mjs +643 -0
  106. package/src/runtime/agent/orchestrator/session/compact/text-utils.mjs +326 -0
  107. package/src/runtime/agent/orchestrator/session/compact.mjs +40 -2282
  108. package/src/runtime/agent/orchestrator/session/loop/compact-debug.mjs +28 -0
  109. package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +274 -0
  110. package/src/runtime/agent/orchestrator/session/loop/completion-guards.mjs +61 -0
  111. package/src/runtime/agent/orchestrator/session/loop/context-overflow.mjs +38 -0
  112. package/src/runtime/agent/orchestrator/session/loop/env.mjs +14 -0
  113. package/src/runtime/agent/orchestrator/session/loop/hidden-agents.mjs +21 -0
  114. package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +47 -0
  115. package/src/runtime/agent/orchestrator/session/loop/recall-fasttrack.mjs +182 -0
  116. package/src/runtime/agent/orchestrator/session/loop/steering-ladder.mjs +173 -0
  117. package/src/runtime/agent/orchestrator/session/loop/steering.mjs +63 -0
  118. package/src/runtime/agent/orchestrator/session/loop/stored-tool-args.mjs +100 -0
  119. package/src/runtime/agent/orchestrator/session/loop/termination.mjs +58 -0
  120. package/src/runtime/agent/orchestrator/session/loop/tool-classify.mjs +52 -0
  121. package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +239 -0
  122. package/src/runtime/agent/orchestrator/session/loop/tool-helpers.mjs +218 -0
  123. package/src/runtime/agent/orchestrator/session/loop/transcript-repair.mjs +101 -0
  124. package/src/runtime/agent/orchestrator/session/loop/usage.mjs +35 -0
  125. package/src/runtime/agent/orchestrator/session/loop.mjs +409 -1304
  126. package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +471 -0
  127. package/src/runtime/agent/orchestrator/session/manager/context-meta.mjs +230 -0
  128. package/src/runtime/agent/orchestrator/session/manager/pending-messages.mjs +235 -0
  129. package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +149 -0
  130. package/src/runtime/agent/orchestrator/session/manager/rules-cache.mjs +155 -0
  131. package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +406 -0
  132. package/src/runtime/agent/orchestrator/session/manager/status-telemetry.mjs +80 -0
  133. package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +303 -0
  134. package/src/runtime/agent/orchestrator/session/manager/usage-metrics.mjs +210 -0
  135. package/src/runtime/agent/orchestrator/session/manager.mjs +226 -2114
  136. package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +189 -0
  137. package/src/runtime/agent/orchestrator/session/store.mjs +74 -179
  138. package/src/runtime/agent/orchestrator/stall-policy.mjs +3 -3
  139. package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +70 -20
  140. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +22 -2
  141. package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +33 -42
  142. package/src/runtime/agent/orchestrator/tools/builtin/external-tool-adapters.mjs +241 -0
  143. package/src/runtime/agent/orchestrator/tools/builtin/fuzzy-match.mjs +1 -1
  144. package/src/runtime/agent/orchestrator/tools/builtin/list-tool.mjs +40 -0
  145. package/src/runtime/agent/orchestrator/tools/builtin/path-diagnostics.mjs +42 -2
  146. package/src/runtime/agent/orchestrator/tools/builtin/read-formatting.mjs +1 -1
  147. package/src/runtime/agent/orchestrator/tools/builtin/read-single-tool.mjs +11 -4
  148. package/src/runtime/agent/orchestrator/tools/builtin/rg-runner.mjs +29 -0
  149. package/src/runtime/agent/orchestrator/tools/builtin/search-builders.mjs +8 -0
  150. package/src/runtime/agent/orchestrator/tools/builtin/search-path-diagnostics.mjs +126 -0
  151. package/src/runtime/agent/orchestrator/tools/builtin/search-tool.mjs +81 -87
  152. package/src/runtime/agent/orchestrator/tools/builtin/shell-job-paths.mjs +161 -0
  153. package/src/runtime/agent/orchestrator/tools/builtin/shell-job-process.mjs +108 -0
  154. package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +78 -304
  155. package/src/runtime/agent/orchestrator/tools/builtin.mjs +11 -6
  156. package/src/runtime/agent/orchestrator/tools/code-graph/build.mjs +303 -0
  157. package/src/runtime/agent/orchestrator/tools/code-graph/constants.mjs +43 -0
  158. package/src/runtime/agent/orchestrator/tools/code-graph/disk-cache.mjs +382 -0
  159. package/src/runtime/agent/orchestrator/tools/code-graph/dispatch.mjs +551 -0
  160. package/src/runtime/agent/orchestrator/tools/code-graph/graph-binary.mjs +295 -0
  161. package/src/runtime/agent/orchestrator/tools/code-graph/graph-model.mjs +158 -0
  162. package/src/runtime/agent/orchestrator/tools/code-graph/keyword-match.mjs +82 -0
  163. package/src/runtime/agent/orchestrator/tools/code-graph/lang-predicates.mjs +128 -0
  164. package/src/runtime/agent/orchestrator/tools/code-graph/memory-cache.mjs +66 -0
  165. package/src/runtime/agent/orchestrator/tools/code-graph/project-root.mjs +44 -0
  166. package/src/runtime/agent/orchestrator/tools/code-graph/search.mjs +1080 -0
  167. package/src/runtime/agent/orchestrator/tools/code-graph/source-access.mjs +81 -0
  168. package/src/runtime/agent/orchestrator/tools/code-graph/span.mjs +19 -0
  169. package/src/runtime/agent/orchestrator/tools/code-graph/symbol-index.mjs +280 -0
  170. package/src/runtime/agent/orchestrator/tools/code-graph/text-columns.mjs +45 -0
  171. package/src/runtime/agent/orchestrator/tools/code-graph/text-mask.mjs +347 -0
  172. package/src/runtime/agent/orchestrator/tools/code-graph-tool-defs.mjs +6 -6
  173. package/src/runtime/agent/orchestrator/tools/code-graph.mjs +36 -4277
  174. package/src/runtime/agent/orchestrator/tools/graph-binary-fetcher.mjs +6 -3
  175. package/src/runtime/agent/orchestrator/tools/patch/constants.mjs +9 -0
  176. package/src/runtime/agent/orchestrator/tools/patch/dispatch.mjs +171 -0
  177. package/src/runtime/agent/orchestrator/tools/patch/matcher.mjs +471 -0
  178. package/src/runtime/agent/orchestrator/tools/patch/native-server.mjs +436 -0
  179. package/src/runtime/agent/orchestrator/tools/patch/orchestrator.mjs +342 -0
  180. package/src/runtime/agent/orchestrator/tools/patch/parsing.mjs +359 -0
  181. package/src/runtime/agent/orchestrator/tools/patch/paths.mjs +340 -0
  182. package/src/runtime/agent/orchestrator/tools/patch/v4a-convert.mjs +643 -0
  183. package/src/runtime/agent/orchestrator/tools/patch.mjs +36 -2959
  184. package/src/runtime/agent/orchestrator/tools/progress-message.mjs +1 -23
  185. package/src/runtime/agent/orchestrator/tools/shell-command.mjs +10 -74
  186. package/src/runtime/agent/orchestrator/tools/shell-powershell.mjs +77 -0
  187. package/src/runtime/agent/orchestrator/tools/shell-snapshot.mjs +2 -4
  188. package/src/runtime/agent/orchestrator/tools/shell-state.mjs +154 -0
  189. package/src/runtime/channels/backends/discord-access.mjs +32 -0
  190. package/src/runtime/channels/backends/discord-attachments.mjs +65 -0
  191. package/src/runtime/channels/backends/discord-gateway.mjs +233 -0
  192. package/src/runtime/channels/backends/discord.mjs +12 -292
  193. package/src/runtime/channels/index.mjs +241 -894
  194. package/src/runtime/channels/lib/backend-dispatch.mjs +44 -0
  195. package/src/runtime/channels/lib/boot-profile.mjs +23 -0
  196. package/src/runtime/channels/lib/crash-log.mjs +106 -0
  197. package/src/runtime/channels/lib/event-pipeline.mjs +18 -1
  198. package/src/runtime/channels/lib/event-queue.mjs +63 -4
  199. package/src/runtime/channels/lib/inbound-routing.mjs +111 -0
  200. package/src/runtime/channels/lib/index-drop-trace.mjs +72 -0
  201. package/src/runtime/channels/lib/output-forwarder.mjs +9 -1
  202. package/src/runtime/channels/lib/owner-heartbeat.mjs +75 -0
  203. package/src/runtime/channels/lib/parent-bridge.mjs +88 -0
  204. package/src/runtime/channels/lib/runtime-paths.mjs +14 -4
  205. package/src/runtime/channels/lib/session-discovery.mjs +56 -4
  206. package/src/runtime/channels/lib/telegram-format.mjs +19 -22
  207. package/src/runtime/channels/lib/tool-dispatch.mjs +158 -0
  208. package/src/runtime/channels/lib/tool-format.mjs +1 -1
  209. package/src/runtime/channels/lib/transcript-discovery.mjs +4 -4
  210. package/src/runtime/channels/lib/voice-runtime-fetcher.mjs +6 -3
  211. package/src/runtime/channels/lib/voice-transcription.mjs +179 -0
  212. package/src/runtime/channels/lib/webhook/deliveries.mjs +312 -0
  213. package/src/runtime/channels/lib/webhook/log.mjs +42 -0
  214. package/src/runtime/channels/lib/webhook/ngrok.mjs +181 -0
  215. package/src/runtime/channels/lib/webhook/signature.mjs +60 -0
  216. package/src/runtime/channels/lib/webhook.mjs +36 -570
  217. package/src/runtime/channels/lib/whisper-language.mjs +42 -0
  218. package/src/runtime/channels/tool-defs.mjs +11 -130
  219. package/src/runtime/memory/index.mjs +258 -2050
  220. package/src/runtime/memory/lib/core-memory-store.mjs +351 -1
  221. package/src/runtime/memory/lib/cycle-llm-adapters.mjs +58 -0
  222. package/src/runtime/memory/lib/cycle-scheduler.mjs +497 -0
  223. package/src/runtime/memory/lib/cycle-signatures.mjs +34 -0
  224. package/src/runtime/memory/lib/embedding-warmup.mjs +58 -0
  225. package/src/runtime/memory/lib/http-wire.mjs +57 -0
  226. package/src/runtime/memory/lib/memory-config-flags.mjs +91 -0
  227. package/src/runtime/memory/lib/memory-cycle.mjs +1 -1
  228. package/src/runtime/memory/lib/memory-cycle2-gate.mjs +515 -0
  229. package/src/runtime/memory/lib/memory-cycle2-mutations.mjs +324 -0
  230. package/src/runtime/memory/lib/memory-cycle2-shared.mjs +18 -0
  231. package/src/runtime/memory/lib/memory-cycle2.mjs +72 -837
  232. package/src/runtime/memory/lib/memory-embed.mjs +149 -0
  233. package/src/runtime/memory/lib/memory-process-lock.mjs +162 -0
  234. package/src/runtime/memory/lib/memory-recall-scope-filter.mjs +24 -0
  235. package/src/runtime/memory/lib/memory-recall-store.mjs +22 -2
  236. package/src/runtime/memory/lib/memory-retrievers.mjs +8 -0
  237. package/src/runtime/memory/lib/memory.mjs +20 -0
  238. package/src/runtime/memory/lib/pg/supervisor.mjs +1 -1
  239. package/src/runtime/memory/lib/promotion-fingerprint.mjs +50 -0
  240. package/src/runtime/memory/lib/query-handlers.mjs +780 -0
  241. package/src/runtime/memory/lib/recall-format.mjs +238 -0
  242. package/src/runtime/memory/lib/runtime-fetcher.mjs +8 -3
  243. package/src/runtime/memory/lib/transcript-ingest.mjs +425 -0
  244. package/src/runtime/memory/tool-defs.mjs +6 -14
  245. package/src/runtime/search/lib/http-fetch.mjs +274 -0
  246. package/src/runtime/search/lib/ssrf-guard.mjs +333 -0
  247. package/src/runtime/search/lib/web-tools.mjs +24 -602
  248. package/src/runtime/shared/abort-controller.mjs +1 -1
  249. package/src/runtime/shared/atomic-file.mjs +26 -1
  250. package/src/runtime/shared/background-tasks.mjs +2 -3
  251. package/src/runtime/shared/buffered-appender.mjs +149 -0
  252. package/src/runtime/shared/launcher-control.mjs +2 -2
  253. package/src/runtime/shared/task-notification-envelope.mjs +98 -0
  254. package/src/runtime/shared/tool-execution-contract.mjs +2 -2
  255. package/src/runtime/shared/tool-primitives.mjs +308 -0
  256. package/src/runtime/shared/tool-result-summary.mjs +515 -0
  257. package/src/runtime/shared/tool-surface.mjs +80 -898
  258. package/src/runtime/shared/transcript-writer.mjs +52 -2
  259. package/src/runtime/shared/update-checker.mjs +7 -4
  260. package/src/session-runtime/config-helpers.mjs +291 -0
  261. package/src/session-runtime/config-lifecycle.mjs +232 -0
  262. package/src/session-runtime/cwd-plugins.mjs +226 -0
  263. package/src/session-runtime/effort.mjs +128 -0
  264. package/src/session-runtime/fs-utils.mjs +10 -0
  265. package/src/session-runtime/mcp-glue.mjs +177 -0
  266. package/src/session-runtime/model-capabilities.mjs +130 -0
  267. package/src/session-runtime/model-recency.mjs +111 -0
  268. package/src/session-runtime/native-search.mjs +247 -0
  269. package/src/session-runtime/output-styles.mjs +126 -0
  270. package/src/session-runtime/plugin-mcp.mjs +114 -0
  271. package/src/session-runtime/prewarm.mjs +142 -0
  272. package/src/session-runtime/provider-models.mjs +278 -0
  273. package/src/session-runtime/provider-usage.mjs +120 -0
  274. package/src/session-runtime/quick-model-rows.mjs +170 -0
  275. package/src/session-runtime/quick-search-models.mjs +46 -0
  276. package/src/session-runtime/session-hooks.mjs +93 -0
  277. package/src/session-runtime/session-text.mjs +100 -0
  278. package/src/session-runtime/settings-api.mjs +319 -0
  279. package/src/session-runtime/statusline-route.mjs +35 -0
  280. package/src/session-runtime/tool-catalog.mjs +720 -0
  281. package/src/session-runtime/tool-defs.mjs +84 -0
  282. package/src/session-runtime/warmup-schedulers.mjs +201 -0
  283. package/src/session-runtime/workflow.mjs +358 -0
  284. package/src/standalone/agent-tool/helpers.mjs +237 -0
  285. package/src/standalone/agent-tool/notify.mjs +107 -0
  286. package/src/standalone/agent-tool/provider-init.mjs +143 -0
  287. package/src/standalone/agent-tool/render.mjs +152 -0
  288. package/src/standalone/agent-tool/tool-def.mjs +55 -0
  289. package/src/standalone/agent-tool.mjs +155 -677
  290. package/src/standalone/channel-worker.mjs +7 -9
  291. package/src/standalone/explore-tool.mjs +40 -12
  292. package/src/standalone/hook-bus/config.mjs +207 -0
  293. package/src/standalone/hook-bus/constants.mjs +90 -0
  294. package/src/standalone/hook-bus/handlers.mjs +481 -0
  295. package/src/standalone/hook-bus/payload.mjs +31 -0
  296. package/src/standalone/hook-bus/rules.mjs +77 -0
  297. package/src/standalone/hook-bus.mjs +110 -746
  298. package/src/standalone/memory-runtime-proxy.mjs +7 -0
  299. package/src/standalone/opencode-go-login.mjs +125 -0
  300. package/src/standalone/provider-admin.mjs +15 -19
  301. package/src/standalone/usage-dashboard.mjs +3 -1
  302. package/src/tui/App.jsx +1163 -7571
  303. package/src/tui/app/app-format.mjs +206 -0
  304. package/src/tui/app/channel-pickers.mjs +510 -0
  305. package/src/tui/app/clipboard.mjs +67 -0
  306. package/src/tui/app/core-memory-picker.mjs +210 -0
  307. package/src/tui/app/extension-pickers.mjs +506 -0
  308. package/src/tui/app/input-parsers.mjs +193 -0
  309. package/src/tui/app/maintenance-pickers.mjs +324 -0
  310. package/src/tui/app/model-options.mjs +330 -0
  311. package/src/tui/app/model-picker.mjs +365 -0
  312. package/src/tui/app/onboarding-steps.mjs +400 -0
  313. package/src/tui/app/project-picker.mjs +247 -0
  314. package/src/tui/app/provider-setup-picker.mjs +580 -0
  315. package/src/tui/app/resume-picker.mjs +55 -0
  316. package/src/tui/app/route-pickers.mjs +419 -0
  317. package/src/tui/app/settings-picker.mjs +490 -0
  318. package/src/tui/app/slash-commands.mjs +101 -0
  319. package/src/tui/app/slash-dispatch.mjs +427 -0
  320. package/src/tui/app/text-layout.mjs +46 -0
  321. package/src/tui/app/theme-effort-pickers.mjs +154 -0
  322. package/src/tui/app/transcript-window.mjs +671 -0
  323. package/src/tui/app/use-mouse-input.mjs +460 -0
  324. package/src/tui/app/use-prompt-handlers.mjs +310 -0
  325. package/src/tui/app/use-transcript-scroll.mjs +510 -0
  326. package/src/tui/app/use-transcript-window.mjs +589 -0
  327. package/src/tui/components/ConfirmBar.jsx +1 -1
  328. package/src/tui/components/Picker.jsx +32 -4
  329. package/src/tui/components/PromptInput.jsx +259 -80
  330. package/src/tui/components/SlashCommandPalette.jsx +8 -1
  331. package/src/tui/components/StatusLine.jsx +63 -12
  332. package/src/tui/components/TextEntryPanel.jsx +11 -0
  333. package/src/tui/components/ToolExecution.jsx +56 -588
  334. package/src/tui/components/TranscriptItem.jsx +105 -0
  335. package/src/tui/components/UsagePanel.jsx +18 -4
  336. package/src/tui/components/prompt-input/edit-helpers.mjs +72 -0
  337. package/src/tui/components/prompt-input/voice-indicator.mjs +39 -0
  338. package/src/tui/components/tool-execution/ResultBody.jsx +56 -0
  339. package/src/tui/components/tool-execution/surface-detail.mjs +405 -0
  340. package/src/tui/components/tool-execution/text-format.mjs +161 -0
  341. package/src/tui/components/tool-output-format.mjs +2 -2
  342. package/src/tui/display-width.mjs +20 -3
  343. package/src/tui/dist/index.mjs +18034 -17188
  344. package/src/tui/engine/agent-envelope.mjs +296 -0
  345. package/src/tui/engine/agent-job-feed.mjs +133 -0
  346. package/src/tui/engine/boot-profile.mjs +21 -0
  347. package/src/tui/engine/labels.mjs +67 -0
  348. package/src/tui/engine/notice-text.mjs +112 -0
  349. package/src/tui/engine/notification-plan.mjs +76 -0
  350. package/src/tui/engine/queue-helpers.mjs +161 -0
  351. package/src/tui/engine/render-timing.mjs +17 -0
  352. package/src/tui/engine/session-stats.mjs +46 -0
  353. package/src/tui/engine/tool-approval.mjs +94 -0
  354. package/src/tui/engine/tool-call-fields.mjs +23 -0
  355. package/src/tui/engine/tool-card-results.mjs +234 -0
  356. package/src/tui/engine/tool-result-status.mjs +135 -0
  357. package/src/tui/engine/tool-result-text.mjs +126 -0
  358. package/src/tui/engine.mjs +405 -1385
  359. package/src/tui/figures.mjs +5 -0
  360. package/src/tui/index.jsx +105 -0
  361. package/src/tui/input-editing.mjs +60 -10
  362. package/src/tui/keyboard-protocol.mjs +2 -2
  363. package/src/tui/lib/voice-recorder.mjs +35 -19
  364. package/src/tui/markdown/format-token.mjs +11 -9
  365. package/src/tui/paste-attachments.mjs +38 -0
  366. package/src/tui/statusline-ansi-bridge.mjs +11 -3
  367. package/src/tui/theme.mjs +6 -0
  368. package/src/tui/themes/base.mjs +2 -2
  369. package/src/tui/themes/kanagawa.mjs +4 -4
  370. package/src/tui/themes/teal.mjs +4 -5
  371. package/src/tui/themes/utils.mjs +1 -1
  372. package/src/ui/statusline-agents.mjs +213 -0
  373. package/src/ui/statusline-format.mjs +146 -0
  374. package/src/ui/statusline-segments.mjs +148 -0
  375. package/src/ui/statusline.mjs +77 -462
  376. package/src/ui/tool-card.mjs +0 -1
  377. package/src/vendor/statusline/bin/statusline-route.mjs +15 -2
  378. package/src/workflows/default/WORKFLOW.md +16 -9
  379. package/src/workflows/sequential/WORKFLOW.md +16 -11
  380. package/src/workflows/solo/WORKFLOW.md +5 -1
  381. package/vendor/ink/build/display-width.js +19 -3
  382. package/vendor/ink/build/ink.js +103 -6
  383. package/vendor/ink/build/log-update.js +17 -3
  384. package/vendor/ink/build/wrap-text.js +125 -0
  385. package/scripts/_test-folder-dialog.mjs +0 -30
  386. package/scripts/fix-brief-fn.mjs +0 -35
  387. package/scripts/fix-format-tool-surface.mjs +0 -24
  388. package/scripts/fix-tool-exec-visible.mjs +0 -42
  389. package/scripts/patch-agent-brief.mjs +0 -48
  390. package/scripts/patch-app.mjs +0 -21
  391. package/scripts/patch-app2.mjs +0 -18
  392. package/scripts/patch-dist-brief.mjs +0 -96
  393. package/scripts/patch-tool-exec.mjs +0 -70
  394. package/src/examples/schedules/SCHEDULE.example.md +0 -32
  395. package/src/examples/webhooks/WEBHOOK.example.md +0 -40
  396. package/src/runtime/agent/orchestrator/session/manager.reactive-persist.test.mjs +0 -107
  397. package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.test.mjs +0 -143
  398. package/src/runtime/agent/orchestrator/tools/builtin/diagnostics-tool.mjs +0 -285
  399. package/src/runtime/agent/orchestrator/tools/builtin/open-config-tool.mjs +0 -26
  400. package/src/runtime/shared/channel-notification-routing.test.mjs +0 -45
  401. package/src/runtime/shared/tool-execution-contract.test.mjs +0 -183
  402. package/src/standalone/agent-task-status.test.mjs +0 -76
  403. package/src/tui/components/tool-output-format.test.mjs +0 -399
  404. package/src/tui/display-width.test.mjs +0 -35
  405. package/src/tui/engine-runtime-notification.test.mjs +0 -115
  406. package/src/tui/engine-tool-result-text.test.mjs +0 -75
  407. package/src/tui/markdown/format-token.test.mjs +0 -354
  408. package/src/tui/markdown/render-ansi.test.mjs +0 -108
  409. package/src/tui/markdown/stream-fence.test.mjs +0 -26
  410. package/src/tui/markdown/streaming-markdown.test.mjs +0 -70
  411. package/src/tui/prompt-history-store.test.mjs +0 -52
  412. package/src/tui/statusline-ansi-bridge.test.mjs +0 -159
  413. package/src/tui/transcript-tool-failures.test.mjs +0 -111
  414. package/src/ui/markdown.test.mjs +0 -70
  415. package/src/ui/statusline-context-label.test.mjs +0 -15
  416. package/src/vendor/statusline/bin/statusline-lib.mjs +0 -186
  417. package/src/vendor/statusline/bin/statusline-route.test.mjs +0 -80
@@ -7,21 +7,46 @@ keep-coding-instructions: true
7
7
 
8
8
  # Output Style
9
9
 
10
- Mixdog default — the most detailed of the three styles, but only as long as the
11
- task warrants.
10
+ Mixdog default — the most detailed style, but always summary-form, never
11
+ essay-form. Depth comes from picking the right facts, not from explaining more.
12
12
 
13
- - Lead with the outcome, then add the supporting detail that matters: what
14
- changed, key evidence (paths, commands, errors, verification), and important
15
- context. Include trade-offs or follow-up only when they actually matter.
16
- - Use a few bullets or short paragraphs when they add signal; this style may run
17
- longer than Simple, but match length to the work do not pad a small change
18
- into a full report. Cut anything that does not earn its place.
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 the direction,
17
+ not the code path. Cite a symbol or path only as an anchor, never as the
18
+ explanation.
19
+ - Compress by cutting content (filler, hedging, connective padding, restated
20
+ facts), not by clipping grammar: keep natural, complete sentences in the
21
+ user's language — never telegraph-style stub endings. Technical terms and
22
+ code stay exact.
23
+ - State conclusions, not reasoning: no mechanism walkthroughs, background, or
24
+ chained qualifiers unless the user asks. One decisive fact beats three
25
+ hedges.
26
+ - Say each point once: problem and fix in ONE compact statement, not a
27
+ restated pair. Prefer fewer, denser items over full coverage of every
28
+ nuance.
29
+ - Size budget: roughly TWICE the Simple style — per point about 2 rendered
30
+ lines, whole report ~10–15 lines. Spend the extra room on evidence and
31
+ context Simple would drop, not on longer sentences.
19
32
  - Use labels such as `바뀐 점`, `확인한 것`, and `남은 리스크/다음 단계`
20
33
  in final reports to structure the summary; skip labels on interim progress.
21
34
  - Collapse trivial tasks to a couple of sentences instead of forcing sections.
22
35
  - Synthesize agent or retrieval results; never forward raw reports, long file
23
36
  lists, tool traces, or session metadata.
24
37
  - Do not hide blockers, failed verification, or required follow-up; surface them
25
- explicitly rather than omitting them.
38
+ in one short clause.
26
39
  - Keep paths, commands, symbols, API names, code, and exact errors verbatim.
40
+
41
+ Layout (hard rules)
42
+ - One bullet or numbered item = one idea, at most 2 rendered lines including
43
+ its sub-bullet. If it needs more, cut the detail — do not add lines.
44
+ - Open each list item with a short **bold key point**, then the brief
45
+ elaboration — never bury the point mid-sentence.
46
+ - Insert a blank line between numbered items, and between any list items that
47
+ run past one line (loose list). Never emit a wall of consecutive multi-line
48
+ items.
49
+ - Keep paragraphs to ~3 lines max, with a blank line between paragraphs,
50
+ lists, and code blocks.
51
+ - Nest at most one sub-level; deeper detail means you are over-explaining.
27
52
  - Never name this style unless asked.
@@ -1,14 +1,15 @@
1
1
  ---
2
- name: oneline
3
- title: Oneline
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
- Oneline — the most minimal style: exactly one sentence, under 100 characters.
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
 
@@ -13,6 +12,10 @@ Minimal — a very short summary: one or two sentences, nothing more.
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
14
  Never cram unrelated facts into one run-on line 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.
16
19
  - Summarize, never itemize: do not describe which files changed or how they were
17
20
  edited. State only what the change accomplishes.
18
21
  - No headings, bullets, numbered lists, labels, or sections — plain sentences
@@ -8,16 +8,31 @@ keep-coding-instructions: true
8
8
 
9
9
  # Output Style
10
10
 
11
- Practical concise — outcome-first handoffs for coding work: summarize the result,
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 the direction, not the
16
+ code 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–4 sentences total. No
19
- step-by-step narration, no exhaustive file/line inventory. Expand only when the
20
- user asks, scope is ambiguous, or a blocker needs concrete next steps.
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
28
+ one rendered line, whole reply ~5–7 lines. Above that you are writing
29
+ Default; 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;
34
+ detail beyond the key phrase + one clause belongs to the Default style, not
35
+ this one.
21
36
  - On final handoffs, optional labels such as `바뀐 점`, `확인한 것`, and
22
37
  `남은 리스크/다음 단계` fit Korean-facing profiles; use plain English labels
23
38
  when the thread is English. Do not label interim progress.
@@ -26,6 +41,6 @@ do not narrate the change.
26
41
  - Do not hide blockers, failed verification, or required follow-up; state them
27
42
  in one short clause.
28
43
  - Keep paths, commands, symbols, API names, code, and exact errors verbatim.
29
- - Skip filler, acknowledgments, and repeated conclusions; if verification was
30
- not run, say so once.
44
+ - Skip filler, acknowledgments, hedging, and repeated conclusions; if
45
+ verification was not run, say so once.
31
46
  - Never name this style unless asked.
package/src/repl.mjs CHANGED
@@ -1,16 +1,16 @@
1
1
  /**
2
- * mixdog REPL — styled inline terminal loop over the ported mixdog brain.
2
+ * mixdog REPL — styled inline terminal loop over the mixdog session runtime.
3
3
  *
4
- * Drives the *ported mixdog brain* through mixdog-session-runtime.mjs:
4
+ * Drives the session runtime through mixdog-session-runtime.mjs:
5
5
  * createSession + askSession own agentLoop/provider/tools/compaction, while
6
6
  * this module stays presentation-only: markdown-rendered replies, tool-call
7
7
  * cards, a per-turn statusline footer, slash commands, and arrow-key history.
8
8
  *
9
9
  * Flow: stdin line → runtime.ask(prompt) → onTextDelta streams tokens to
10
- * stdout live → tool calls render as cards → on turn end we re-render
11
- * the assistant text as markdown → statusline footer.
10
+ * stdout live → tool calls render as cards → on turn end we re-render
11
+ * the assistant text as markdown → statusline footer.
12
12
  *
13
- * STREAMING DECISION (approach (a) from the brief):
13
+ * STREAMING DECISION:
14
14
  * Live token streaming via onTextDelta conflicts with post-hoc markdown
15
15
  * rendering (you can't style a heading until you've seen the whole line).
16
16
  * We choose: stream raw tokens live so the turn FEELS alive, then on turn
@@ -15,3 +15,5 @@
15
15
  - Banned as pure cost: report headings, markdown tables (unless requested),
16
16
  prose narration, raw logs/tool traces, speculative next-checks, restated
17
17
  brief, articles/politeness.
18
+ - Exception: a runtime wrap-up directive (exploration budget reached)
19
+ overrides this — then summarize done/remaining/blocking as instructed.
@@ -6,16 +6,13 @@ kind: retrieval
6
6
 
7
7
  # Role: explorer
8
8
 
9
- Locator only: likely file/symbol/line anchors; no analysis, debugging, decisions,
10
- or recommendations.
9
+ You are a one-shot locator, not a researcher.
11
10
 
12
- Output only:
13
- - `path:line symbol/name short reason`
14
- - or `EXPLORATION_FAILED`
15
-
16
- No preambles/tool-call preambles, bullets, headings, summaries, code quotes,
17
- verdicts, or invented coordinates. Weak anchors: `?`.
11
+ Procedure: send ONE turn containing one `grep` (all synonyms in one
12
+ `pattern:[...]`, output_mode content_with_context) plus one `code_graph`
13
+ call. The results contain path:line — answer immediately from them.
14
+ If both miss, answer `EXPLORATION_FAILED`. Do not send a second lookup turn.
18
15
 
19
- One batched lookup turn; first plausible anchor wins. No verification loop,
20
- synonym sweep, or proof-chasing. Hard stop after 5 tool calls; if uncertain,
21
- return best weak anchors with `?`.
16
+ Answer format, nothing else:
17
+ - up to 5 lines of `path:line symbol/name short reason` (append `?` if weak)
18
+ - or `EXPLORATION_FAILED`
@@ -0,0 +1,12 @@
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
+ - Full brief only on fresh spawn or `respawned: true` (dead-tag send =
7
+ cold session; re-supply anchors). Live-session follow-ups = delta only;
8
+ never restate Goal/rules.
9
+ - Never `send` mid-run; batch all adjustments into ONE follow-up after
10
+ completion. Interrupt only to cancel.
11
+ - All agent communication in English.
12
+ - Referenced spec/test file beats its summary in the brief.
@@ -1,13 +1,6 @@
1
1
  # Lead Tool Use
2
2
 
3
- - Lead owns repo-local shell work: git, build, test, run, and verification commands.
3
+ - Lead owns repo-local shell work: run git/build/test/verification commands via
4
+ `shell` directly; do not delegate them to agents.
4
5
  - Use the current project/workspace selected by the session. Only change the work project when the user asks for a different project or a tool call explicitly needs another project root.
5
- - Use `shell` directly for approved git/build/test/run work; do not delegate those commands to agents.
6
6
  - Use `agent` for scoped implementation, research, review, and debugging, not for git commit/push/stash or Ship.
7
- - Reuse the same agent tag/session for follow-up on the same scope (`send` or
8
- `spawn` with the same tag reuses a live session). Spawn a new tag only for a
9
- genuinely independent scope.
10
- - Briefs: minimum characters, maximum information. Fixed one-line fragment
11
- fields — `Goal:` `Anchors:` `Allow/Forbid:` `Deliver:` `Verify:` (+`Stop:` for
12
- heavy-worker). Omit role-known rules (git/preamble bans, output format),
13
- background, motivation; non-actionable tokens are wasted cost.
@@ -1,6 +1,8 @@
1
1
  # Tool Use
2
2
 
3
- - Independent lookups MUST batch in one turn; serialize only when a call needs a prior result.
3
+ - Independent lookups MUST batch in one turn; serialize only when a call needs
4
+ a prior result. This includes edit loops: batch the post-edit verification
5
+ read with the next target's lookup instead of emitting single-call turns.
4
6
  - Target validity comes first: symbols/callers/deps → `code_graph`; exact text in
5
7
  a verified scope → `grep`; unknown path/name → `find`; structure → `glob`;
6
8
  dirs → `list`; verified file → `read`; broad unknown with no anchor →
@@ -10,10 +12,14 @@
10
12
  `code_graph symbols[]`). Refine from returned paths; do not repeat equivalent
11
13
  patterns or scopes.
12
14
  - On miss/error, normalize the target once and switch tool; on a plausible hit,
13
- stop searching and answer from the framed context. Do not follow
14
- `content_with_context` with `read` unless the needed span is not shown.
15
+ stop searching and answer from the framed context.
16
+ - Lookup budget: retrieval exists to reach the NEXT action (edit, answer,
17
+ handoff), not to build certainty. One anchor is enough to act on; re-reading
18
+ or re-grepping an area you already saw this session is waste. When acting
19
+ and looking are both possible, act.
15
20
  - Avoid read fragmentation: `read` uses `offset`/`limit` only. If you need 2+
16
21
  spans from one or more known files, make one batched `read` call with
17
- `{path,offset,limit}` region objects instead of serial reads.
18
- - `search`/`web_fetch` for external info; `recall` for history.
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.
19
25
  - Don't mix `apply_patch` with shell or other state-changing calls in one turn.
@@ -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) — sliding tool_result / prior user-text tail
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 every session's tail uses the cheaper 5m TTL
75
- * (1.25x write vs 2x), aligned with the 5m terminal-reap window for agents.
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
- export function resolveCacheStrategy(agent) {
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
- // Lead + public agents: per-session volatile tail -> 5m (see doc above).
95
- return { tools: 'none', system: '1h', tier3: '1h', messages: '5m' };
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. The base namespace still comes from resolveProviderCacheKey()
215
- * (so overrides keep working), but a model/system/tools hash is appended so
216
- * unrelated main/worker prefixes do not evict each other inside one shared
217
- * provider lane.
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 = 12;
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 a stable cache-lane slot for OpenAI-style prompt cache sharding.
312
- * The shard count is the maximum same-prefix parallelism; each final shard key
313
- * is still internally queued and rate-shaped by the transport for stable server
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, DEFAULT_PROVIDER_PROMPT_CACHE_LANE_SHARDS);
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.
@@ -24,28 +24,21 @@ import { loadConfig } from '../config.mjs';
24
24
  import { AGENT_OWNER } from '../agent-owner.mjs';
25
25
 
26
26
  import {
27
- COMPACT_TYPE_RECALL_FASTTRACK,
28
27
  COMPACT_TYPE_SEMANTIC,
29
28
  normalizeCompactType,
30
29
  } from '../session/compact.mjs';
31
30
 
32
- function memoryModuleEnabled(config) {
33
- const entry = config?.modules?.memory;
34
- if (entry && typeof entry === 'object' && entry.enabled === false) return false;
35
- return true;
36
- }
37
-
38
31
  function normalizeAgentCompactionConfig(value = {}, { memoryEnabled = true } = {}) {
39
32
  const raw = value && typeof value === 'object' ? value : {};
40
33
  let compactType = normalizeCompactType(
41
34
  raw.compactType ?? raw.compact_type ?? raw.type,
42
35
  COMPACT_TYPE_SEMANTIC,
43
36
  );
44
- // recall-fasttrack depends on memory ingest/recall; fall back to semantic when
45
- // the memory module is disabled (same rule as Lead session runtime).
46
- if (compactType === COMPACT_TYPE_RECALL_FASTTRACK && memoryEnabled === false) {
47
- compactType = COMPACT_TYPE_SEMANTIC;
48
- }
37
+ // Memory is now always-on, so recall-fasttrack no longer downgrades to
38
+ // semantic. `memoryEnabled` is retained as a param for API compatibility
39
+ // but is intentionally ignored (fasttrack drains run on-demand regardless
40
+ // of the recap/background-cycle toggle) — mirrors config-helpers.mjs.
41
+ void memoryEnabled;
49
42
  return {
50
43
  ...raw,
51
44
  auto: raw.auto !== false && raw.enabled !== false,
@@ -109,9 +102,7 @@ export function prepareAgentSession({
109
102
  try {
110
103
  const cfg = loadConfig({ secrets: false });
111
104
  if (cfg?.compaction && typeof cfg.compaction === 'object') {
112
- compaction = normalizeAgentCompactionConfig(cfg.compaction, {
113
- memoryEnabled: memoryModuleEnabled(cfg),
114
- });
105
+ compaction = normalizeAgentCompactionConfig(cfg.compaction);
115
106
  }
116
107
  } catch { /* config is best-effort for agent compaction policy */ }
117
108
  const sessionOpts = {