mixdog 1.3.4 → 1.4.0

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 (472) hide show
  1. package/LICENSES/oh-my-pi-MIT.txt +23 -0
  2. package/NOTICE.md +17 -2
  3. package/README.md +11 -0
  4. package/package.json +3 -11
  5. package/scripts/daemon-stub.mjs +1 -1
  6. package/scripts/embed-google-oauth-client.mjs +49 -0
  7. package/scripts/gate-local.mjs +4 -2
  8. package/scripts/lib/test-spawn-ledger.mjs +46 -1
  9. package/scripts/native-release-status.mjs +2 -2
  10. package/scripts/recall-history-cases.json +1 -1
  11. package/scripts/suite-health.mjs +10 -1
  12. package/scripts/test.mjs +12 -11
  13. package/src/agents/reviewer/AGENT.md +7 -11
  14. package/src/agents/reviewer/agent.json +1 -1
  15. package/src/defaults/shipped-history.json +25 -1
  16. package/src/defaults/skills/browser-use/SKILL.md +77 -17
  17. package/src/defaults/skills/code-tidy/SKILL.md +142 -270
  18. package/src/defaults/skills/code-tidy/references/agent-cleanup.md +4 -4
  19. package/src/defaults/skills/code-tidy/references/cleanup-report.md +31 -76
  20. package/src/defaults/skills/code-tidy/references/dead-code.md +6 -12
  21. package/src/defaults/skills/computer-use/SKILL.md +33 -9
  22. package/src/defaults/skills/setup/SKILL.md +29 -2
  23. package/src/defaults/skills/setup/references/actions.md +117 -28
  24. package/src/defaults/skills/setup/references/surfaces.md +77 -35
  25. package/src/defaults/skills/setup-guide/SKILL.md +3 -3
  26. package/src/defaults/skills/visualize/SKILL.md +2 -1
  27. package/src/lib/keychain-cjs.cjs +359 -29
  28. package/src/lib/rules-builder.cjs +10 -8
  29. package/src/rules/agent/AGENT.md +6 -6
  30. package/src/rules/agent-mode/AGENT_MODE.md +10 -2
  31. package/src/rules/agent-mode/MIXY.md +12 -0
  32. package/src/rules/lead/LEAD.md +18 -20
  33. package/src/rules/shared/05-tool-calls.md +5 -6
  34. package/src/rules/shared/10-tool-workflow.md +2 -0
  35. package/src/rules/shared/60-verification.md +7 -5
  36. package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +2 -3
  37. package/src/runtime/agent/orchestrator/agent-runtime/heartbeat-completion.mjs +193 -0
  38. package/src/runtime/agent/orchestrator/agent-runtime/title-completion.mjs +3 -1
  39. package/src/runtime/agent/orchestrator/agent-trace-format.mjs +3 -1
  40. package/src/runtime/agent/orchestrator/config.mjs +34 -0
  41. package/src/runtime/agent/orchestrator/context/collect.mjs +3 -0
  42. package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +72 -67
  43. package/src/runtime/agent/orchestrator/context/skill-catalog.mjs +54 -1
  44. package/src/runtime/agent/orchestrator/mcp/agent-connectors.mjs +3 -3
  45. package/src/runtime/agent/orchestrator/mcp/client-transport.mjs +177 -73
  46. package/src/runtime/agent/orchestrator/mcp/client.mjs +25 -2
  47. package/src/runtime/agent/orchestrator/mcp/oauth-callback.mjs +31 -2
  48. package/src/runtime/agent/orchestrator/mcp/oauth-client.mjs +16 -3
  49. package/src/runtime/agent/orchestrator/mcp/oauth-login.mjs +42 -7
  50. package/src/runtime/agent/orchestrator/mcp/oauth-provider.mjs +21 -2
  51. package/src/runtime/agent/orchestrator/mcp/oauth-shared.mjs +23 -0
  52. package/src/runtime/agent/orchestrator/mcp/oauth.mjs +11 -1
  53. package/src/runtime/agent/orchestrator/providers/account-pool.mjs +230 -137
  54. package/src/runtime/agent/orchestrator/providers/admission-scheduler.mjs +64 -7
  55. package/src/runtime/agent/orchestrator/providers/anthropic-api-request.mjs +18 -5
  56. package/src/runtime/agent/orchestrator/providers/anthropic-cache-warm.mjs +165 -0
  57. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
  58. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-credentials.mjs +4 -1
  59. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-request/gzip-post.mjs +14 -14
  60. package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +160 -69
  61. package/src/runtime/agent/orchestrator/providers/anthropic-overload-fallback.mjs +25 -3
  62. package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +64 -33
  63. package/src/runtime/agent/orchestrator/providers/anthropic.mjs +135 -87
  64. package/src/runtime/agent/orchestrator/providers/antigravity-oauth-catalog.mjs +52 -8
  65. package/src/runtime/agent/orchestrator/providers/antigravity-oauth.mjs +10 -1
  66. package/src/runtime/agent/orchestrator/providers/antigravity-request.mjs +22 -6
  67. package/src/runtime/agent/orchestrator/providers/antigravity-response.mjs +15 -4
  68. package/src/runtime/agent/orchestrator/providers/antigravity-stream.mjs +17 -2
  69. package/src/runtime/agent/orchestrator/providers/antigravity-transport.mjs +142 -104
  70. package/src/runtime/agent/orchestrator/providers/cache-warm-admission.mjs +90 -0
  71. package/src/runtime/agent/orchestrator/providers/codex-client-meta.mjs +1 -1
  72. package/src/runtime/agent/orchestrator/providers/cursor-wire-normalization.mjs +10 -4
  73. package/src/runtime/agent/orchestrator/providers/cursor-wire-protobuf.mjs +10 -217
  74. package/src/runtime/agent/orchestrator/providers/cursor-wire-transport.mjs +25 -9
  75. package/src/runtime/agent/orchestrator/providers/cursor.mjs +22 -6
  76. package/src/runtime/agent/orchestrator/providers/devin-auth.mjs +409 -0
  77. package/src/runtime/agent/orchestrator/providers/devin-wire-families.mjs +187 -0
  78. package/src/runtime/agent/orchestrator/providers/devin-wire-identity.mjs +342 -0
  79. package/src/runtime/agent/orchestrator/providers/devin-wire-models.mjs +541 -0
  80. package/src/runtime/agent/orchestrator/providers/devin-wire-protobuf.mjs +305 -0
  81. package/src/runtime/agent/orchestrator/providers/devin-wire-request.mjs +558 -0
  82. package/src/runtime/agent/orchestrator/providers/devin-wire-schema.mjs +880 -0
  83. package/src/runtime/agent/orchestrator/providers/devin-wire-session.mjs +190 -0
  84. package/src/runtime/agent/orchestrator/providers/devin-wire-tool-args.mjs +351 -0
  85. package/src/runtime/agent/orchestrator/providers/devin-wire-transport.mjs +560 -0
  86. package/src/runtime/agent/orchestrator/providers/devin.mjs +491 -0
  87. package/src/runtime/agent/orchestrator/providers/effort-configuration.mjs +3 -0
  88. package/src/runtime/agent/orchestrator/providers/gemini-output-limit.mjs +46 -0
  89. package/src/runtime/agent/orchestrator/providers/gemini-reasoning-relay.mjs +30 -0
  90. package/src/runtime/agent/orchestrator/providers/gemini-request-body.mjs +7 -11
  91. package/src/runtime/agent/orchestrator/providers/gemini-retry-policy.mjs +61 -22
  92. package/src/runtime/agent/orchestrator/providers/gemini-sdk-request.mjs +1 -0
  93. package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +71 -4
  94. package/src/runtime/agent/orchestrator/providers/gemini.mjs +25 -2
  95. package/src/runtime/agent/orchestrator/providers/grok-client-version.mjs +1 -1
  96. package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +96 -5
  97. package/src/runtime/agent/orchestrator/providers/lib/oauth-token-utils.mjs +17 -3
  98. package/src/runtime/agent/orchestrator/providers/lib/tail-reminder-split.mjs +23 -5
  99. package/src/runtime/agent/orchestrator/providers/media-normalization.mjs +52 -10
  100. package/src/runtime/agent/orchestrator/providers/model-proxy-channel.d.mts +8 -1
  101. package/src/runtime/agent/orchestrator/providers/model-proxy-channel.mjs +1 -0
  102. package/src/runtime/agent/orchestrator/providers/npm-cli-version.mjs +11 -3
  103. package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +19 -1
  104. package/src/runtime/agent/orchestrator/providers/oauth-usage.mjs +39 -3
  105. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-state.mjs +3 -1
  106. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream.mjs +2 -0
  107. package/src/runtime/agent/orchestrator/providers/openai-error-contract.mjs +6 -1
  108. package/src/runtime/agent/orchestrator/providers/openai-oauth-tokens.mjs +10 -9
  109. package/src/runtime/agent/orchestrator/providers/openai-ws-send/send-context.mjs +22 -3
  110. package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/attempt-context.mjs +43 -5
  111. package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/handshake-failure.mjs +3 -1
  112. package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/stream-failure.mjs +6 -3
  113. package/src/runtime/agent/orchestrator/providers/opencode-go-gemini.mjs +1 -0
  114. package/src/runtime/agent/orchestrator/providers/provider-availability.mjs +19 -0
  115. package/src/runtime/agent/orchestrator/providers/provider-error-kind.mjs +65 -1
  116. package/src/runtime/agent/orchestrator/providers/quota-reading.mjs +38 -12
  117. package/src/runtime/agent/orchestrator/providers/registry.mjs +43 -3
  118. package/src/runtime/agent/orchestrator/providers/retry-executor.mjs +39 -7
  119. package/src/runtime/agent/orchestrator/providers/statusline-route-meta.mjs +6 -0
  120. package/src/runtime/agent/orchestrator/providers/wire-protobuf-codec.mjs +368 -0
  121. package/src/runtime/agent/orchestrator/runtime-core/ask-user-tool-defs.mjs +12 -7
  122. package/src/runtime/agent/orchestrator/runtime-core/builtin-features.mjs +2 -0
  123. package/src/runtime/agent/orchestrator/runtime-core/compaction-config-keys.mjs +62 -0
  124. package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +37 -16
  125. package/src/runtime/agent/orchestrator/runtime-core/deferred-tool-delta.mjs +100 -23
  126. package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +1 -1
  127. package/src/runtime/agent/orchestrator/runtime-core/reaction-tool-defs.mjs +133 -0
  128. package/src/runtime/agent/orchestrator/runtime-core/session-text.mjs +2 -0
  129. package/src/runtime/agent/orchestrator/runtime-core/tool-bridge.mjs +19 -4
  130. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog-data.mjs +3 -0
  131. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +125 -30
  132. package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +23 -5
  133. package/src/runtime/agent/orchestrator/runtime-core/tool-profile.mjs +35 -10
  134. package/src/runtime/agent/orchestrator/runtime-core/workflow/agents.mjs +57 -10
  135. package/src/runtime/agent/orchestrator/runtime-core/workflow/context.mjs +9 -6
  136. package/src/runtime/agent/orchestrator/runtime-core/workflow-ids.mjs +1 -1
  137. package/src/runtime/agent/orchestrator/session/agent-loop.mjs +18 -0
  138. package/src/runtime/agent/orchestrator/session/agent-room.d.mts +0 -3
  139. package/src/runtime/agent/orchestrator/session/agent-room.mjs +10 -4
  140. package/src/runtime/agent/orchestrator/session/cache-warm.mjs +792 -0
  141. package/src/runtime/agent/orchestrator/session/compact/runner.mjs +148 -25
  142. package/src/runtime/agent/orchestrator/session/compaction-archive-capture.mjs +475 -58
  143. package/src/runtime/agent/orchestrator/session/compaction-archive.mjs +42 -17
  144. package/src/runtime/agent/orchestrator/session/eager-dispatch.mjs +8 -0
  145. package/src/runtime/agent/orchestrator/session/human-gate/gate.mjs +47 -9
  146. package/src/runtime/agent/orchestrator/session/human-gate/outbound-policy.mjs +6 -2
  147. package/src/runtime/agent/orchestrator/session/human-gate/requests.mjs +36 -4
  148. package/src/runtime/agent/orchestrator/session/human-gate/store.mjs +14 -2
  149. package/src/runtime/agent/orchestrator/session/loop/assistant-commit.mjs +8 -0
  150. package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +18 -22
  151. package/src/runtime/agent/orchestrator/session/loop/fresh-context.mjs +32 -3
  152. package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +11 -2
  153. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/segments.mjs +4 -1
  154. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn.mjs +51 -3
  155. package/src/runtime/agent/orchestrator/session/loop/route-fallback.mjs +17 -3
  156. package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +10 -2
  157. package/src/runtime/agent/orchestrator/session/loop/tool-exec/after-hook.mjs +2 -1
  158. package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +14 -4
  159. package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +16 -2
  160. package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +16 -1
  161. package/src/runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs +10 -0
  162. package/src/runtime/agent/orchestrator/session/loop/tool-helpers.mjs +3 -10
  163. package/src/runtime/agent/orchestrator/session/loop/tool-phase.mjs +23 -5
  164. package/src/runtime/agent/orchestrator/session/loop/turn-limits.mjs +60 -0
  165. package/src/runtime/agent/orchestrator/session/manager/ask-queue.mjs +12 -2
  166. package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +19 -1
  167. package/src/runtime/agent/orchestrator/session/manager/ask-turn-commit.mjs +2 -0
  168. package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +133 -90
  169. package/src/runtime/agent/orchestrator/session/manager/ask-turn-loop-options.mjs +14 -0
  170. package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +2 -1
  171. package/src/runtime/agent/orchestrator/session/manager/ask-turn-state.mjs +31 -4
  172. package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +30 -18
  173. package/src/runtime/agent/orchestrator/session/manager/owner-route-fallbacks.mjs +23 -13
  174. package/src/runtime/agent/orchestrator/session/manager/pending-message-entry.mjs +11 -2
  175. package/src/runtime/agent/orchestrator/session/manager/provider-replay.mjs +13 -0
  176. package/src/runtime/agent/orchestrator/session/manager/route-fallback-chain.mjs +129 -0
  177. package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +20 -2
  178. package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +2 -0
  179. package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +8 -0
  180. package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +1 -1
  181. package/src/runtime/agent/orchestrator/session/manager/session-tool-surface.mjs +13 -0
  182. package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +7 -2
  183. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-journal.mjs +102 -15
  184. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint.mjs +18 -5
  185. package/src/runtime/agent/orchestrator/session/message-ids.mjs +5 -3
  186. package/src/runtime/agent/orchestrator/session/message-reactions.mjs +89 -0
  187. package/src/runtime/agent/orchestrator/session/message-reactions.test-support.mjs +75 -0
  188. package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +19 -8
  189. package/src/runtime/agent/orchestrator/session/prompt-cache-idle-gaps.mjs +113 -0
  190. package/src/runtime/agent/orchestrator/session/prompt-cache-touch-store.mjs +127 -0
  191. package/src/runtime/agent/orchestrator/session/routine-result.d.mts +0 -2
  192. package/src/runtime/agent/orchestrator/session/routine-result.mjs +47 -11
  193. package/src/runtime/agent/orchestrator/session/send-with-recovery.mjs +20 -2
  194. package/src/runtime/agent/orchestrator/session/sensitive-projection.mjs +100 -0
  195. package/src/runtime/agent/orchestrator/session/sensitive-values.mjs +257 -0
  196. package/src/runtime/agent/orchestrator/session/side-question-store.mjs +20 -7
  197. package/src/runtime/agent/orchestrator/session/side-question.mjs +18 -0
  198. package/src/runtime/agent/orchestrator/session/skill-update-notice.mjs +60 -0
  199. package/src/runtime/agent/orchestrator/session/store/live-state.mjs +6 -3
  200. package/src/runtime/agent/orchestrator/session/store/save-delta.mjs +9 -5
  201. package/src/runtime/agent/orchestrator/session/store/serialize.mjs +9 -8
  202. package/src/runtime/agent/orchestrator/session/store/session-persistence-events.mjs +29 -0
  203. package/src/runtime/agent/orchestrator/session/store-agent-worker-header-cache.mjs +85 -0
  204. package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +133 -18
  205. package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +12 -2
  206. package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +44 -14
  207. package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +84 -3
  208. package/src/runtime/agent/orchestrator/session/stored-attachment-history.mjs +32 -0
  209. package/src/runtime/agent/orchestrator/session/tail-reminder-rules.mjs +11 -5
  210. package/src/runtime/agent/orchestrator/session/thinking-binding.mjs +108 -0
  211. package/src/runtime/agent/orchestrator/session/tool-batch/pre-dispatch.mjs +2 -2
  212. package/src/runtime/agent/orchestrator/session/tool-batch/record-outcome.mjs +2 -1
  213. package/src/runtime/agent/orchestrator/session/tool-batch/state.mjs +4 -0
  214. package/src/runtime/agent/orchestrator/session/tool-batch.mjs +5 -0
  215. package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +25 -2
  216. package/src/runtime/agent/orchestrator/session/transcript-restore/tool-result-status.mjs +9 -7
  217. package/src/runtime/agent/orchestrator/session/transcript-restore/tool-result-text.mjs +2 -2
  218. package/src/runtime/agent/orchestrator/session/turn-failure.mjs +5 -1
  219. package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +5 -2
  220. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/backgrounded-result.mjs +12 -1
  221. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/misuse-guard.mjs +240 -0
  222. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/result-format.mjs +1 -1
  223. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/shell-cwd.mjs +38 -0
  224. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +25 -5
  225. package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +65 -7
  226. package/src/runtime/agent/orchestrator/tools/builtin/shell-runtime.mjs +7 -1
  227. package/src/runtime/agent/orchestrator/tools/shell-command.mjs +36 -13
  228. package/src/runtime/browser-bridge/action-schema.mjs +13 -2
  229. package/src/runtime/browser-bridge/client.mjs +73 -8
  230. package/src/runtime/browser-bridge/input-fields.mjs +8 -9
  231. package/src/runtime/browser-bridge/mail-links.mjs +107 -0
  232. package/src/runtime/browser-bridge/tool-defs.mjs +1 -1
  233. package/src/runtime/channels/lib/config.mjs +6 -61
  234. package/src/runtime/channels/lib/crash-log.mjs +1 -1
  235. package/src/runtime/channels/lib/event-pipeline.mjs +4 -19
  236. package/src/runtime/channels/lib/event-queue.mjs +3 -18
  237. package/src/runtime/channels/lib/owned-runtime/automation-services.mjs +2 -2
  238. package/src/runtime/channels/lib/owned-runtime/automation-start.mjs +3 -4
  239. package/src/runtime/channels/lib/owned-runtime/config-reload.mjs +4 -59
  240. package/src/runtime/channels/lib/owned-runtime/owned-start.mjs +33 -115
  241. package/src/runtime/channels/lib/owned-runtime/owned-stop.mjs +5 -22
  242. package/src/runtime/channels/lib/owned-runtime/state.mjs +2 -8
  243. package/src/runtime/channels/lib/owned-runtime.mjs +6 -23
  244. package/src/runtime/channels/lib/parent-bridge.mjs +2 -2
  245. package/src/runtime/channels/lib/runtime-paths.mjs +4 -43
  246. package/src/runtime/channels/lib/schedule-errors.mjs +51 -0
  247. package/src/runtime/channels/lib/scheduler.mjs +135 -154
  248. package/src/runtime/channels/lib/schedules-db.mjs +83 -11
  249. package/src/runtime/channels/lib/status-snapshot.mjs +1 -1
  250. package/src/runtime/channels/lib/tool-dispatch.mjs +14 -2
  251. package/src/runtime/channels/lib/webhooks-db.mjs +5 -9
  252. package/src/runtime/channels/lib/worker-bootstrap.mjs +0 -1
  253. package/src/runtime/channels/lib/worker-ipc.mjs +0 -1
  254. package/src/runtime/channels/lib/worker-main.mjs +19 -34
  255. package/src/runtime/computer-bridge/action-schema.mjs +42 -1
  256. package/src/runtime/computer-bridge/actions.mjs +9 -1
  257. package/src/runtime/computer-bridge/client.mjs +180 -8
  258. package/src/runtime/computer-bridge/core-actions.mjs +2 -2
  259. package/src/runtime/computer-bridge/error-recovery.mjs +27 -2
  260. package/src/runtime/computer-bridge/linux-readiness.mjs +65 -23
  261. package/src/runtime/computer-bridge/pending-continuation.mjs +1 -1
  262. package/src/runtime/connectors/connector-accounts-mcp.mjs +230 -0
  263. package/src/runtime/connectors/gmail-app-password.mjs +172 -39
  264. package/src/runtime/connectors/google-mcp.mjs +10 -12
  265. package/src/runtime/memory/lib/pg/adapter.mjs +77 -70
  266. package/src/runtime/memory/lib/pg/supervisor.mjs +24 -12
  267. package/src/runtime/memory/lib/runtime-fetcher.mjs +23 -5
  268. package/src/runtime/office/com/com-adapter.mjs +17 -1
  269. package/src/runtime/office/com/office-com-host.ps1 +51 -1
  270. package/src/runtime/office/pdf/cfb-fixture.mjs +328 -0
  271. package/src/runtime/office/pdf/cfb-protection.mjs +311 -0
  272. package/src/runtime/office/pdf/document-preview.mjs +326 -8
  273. package/src/runtime/office/pdf/ooxml-crypto.mjs +469 -0
  274. package/src/runtime/office/pdf/ooxml-key-worker.mjs +14 -0
  275. package/src/runtime/office/portable/portable-soffice.mjs +45 -5
  276. package/src/runtime/session-search/session-search-db.mjs +73 -9
  277. package/src/runtime/session-search/session-search-ingest.mjs +110 -20
  278. package/src/runtime/shared/abort-race.mjs +89 -0
  279. package/src/runtime/shared/agent-avatar.d.mts +0 -1
  280. package/src/runtime/shared/agent-kind.mjs +4 -3
  281. package/src/runtime/shared/bot-hops.mjs +62 -2
  282. package/src/runtime/shared/bounded-download.mjs +8 -3
  283. package/src/runtime/shared/config.mjs +51 -35
  284. package/src/runtime/shared/connector-accounts.mjs +20 -10
  285. package/src/runtime/shared/connector-catalog.d.mts +33 -2
  286. package/src/runtime/shared/connector-catalog.mjs +166 -8
  287. package/src/runtime/shared/connector-triggers.mjs +22 -19
  288. package/src/runtime/shared/defaults-separation.mjs +2 -14
  289. package/src/runtime/shared/delegated-approval-host.mjs +103 -11
  290. package/src/runtime/shared/developer-options.mjs +32 -1
  291. package/src/runtime/shared/err-text.mjs +24 -15
  292. package/src/runtime/shared/file-permissions.d.mts +0 -8
  293. package/src/runtime/shared/file-permissions.mjs +0 -11
  294. package/src/runtime/shared/git-direct.test-support.mjs +19 -0
  295. package/src/runtime/shared/google-oauth-client.generated.json +4 -0
  296. package/src/runtime/shared/google-oauth-client.mjs +34 -9
  297. package/src/runtime/shared/heartbeat-interval.d.mts +4 -0
  298. package/src/runtime/shared/heartbeat-interval.mjs +19 -0
  299. package/src/runtime/shared/idle-auto-clear-gate.mjs +104 -0
  300. package/src/runtime/shared/llm/anthropic-betas.mjs +7 -0
  301. package/src/runtime/shared/llm/anthropic-thinking-contract.mjs +12 -0
  302. package/src/runtime/shared/llm/provider-catalog-registry.mjs +1 -0
  303. package/src/runtime/shared/llm/usage-rollup.mjs +1 -1
  304. package/src/runtime/shared/llm/well-formed.mjs +66 -0
  305. package/src/runtime/shared/mixy-presence.mjs +22 -0
  306. package/src/runtime/shared/orchestration.d.mts +2 -0
  307. package/src/runtime/shared/pg-schema-db.mjs +27 -16
  308. package/src/runtime/shared/profile-config.cjs +1 -1
  309. package/src/runtime/shared/prompt-origin.d.mts +4 -0
  310. package/src/runtime/shared/prompt-origin.mjs +21 -0
  311. package/src/runtime/shared/provider-accounts.mjs +231 -59
  312. package/src/runtime/shared/provider-api-key.mjs +19 -8
  313. package/src/runtime/shared/provider-display-name.mjs +29 -0
  314. package/src/runtime/shared/provider-timeout-phase.mjs +2 -0
  315. package/src/runtime/shared/routine-trigger.d.mts +2 -0
  316. package/src/runtime/shared/routine-trigger.mjs +52 -0
  317. package/src/runtime/shared/sensitive-path-rules.d.mts +2 -10
  318. package/src/runtime/shared/sensitive-path-rules.mjs +19 -41
  319. package/src/runtime/shared/session-activity-signal.mjs +34 -1
  320. package/src/runtime/shared/session-sidebar-host.d.mts +1 -1
  321. package/src/runtime/shared/session-sidebar-host.mjs +7 -3
  322. package/src/runtime/shared/session-turn-prelude.mjs +18 -0
  323. package/src/runtime/shared/tool-execution-contract.mjs +2 -0
  324. package/src/runtime/shared/tool-result-summary.mjs +1 -14
  325. package/src/runtime/shared/transcript-metadata.mjs +38 -0
  326. package/src/runtime/shared/user-data-guard.mjs +30 -2
  327. package/src/runtime/shared/worktrees/activity-gate.mjs +12 -5
  328. package/src/runtime/shared/worktrees/test-support.mjs +9 -4
  329. package/src/runtime/terminal-bridge/client.mjs +10 -1
  330. package/src/runtime/visualize-bridge/client.mjs +27 -8
  331. package/src/runtime/visualize-bridge/tool-defs.mjs +22 -8
  332. package/src/runtime/visualize-bridge/tool-meta.d.mts +5 -0
  333. package/src/runtime/visualize-bridge/tool-meta.mjs +22 -0
  334. package/src/runtime/web-search/lib/fetch-pipeline.mjs +2 -2
  335. package/src/session-runtime/agent-home-delivery.mjs +486 -179
  336. package/src/session-runtime/agent-room-delivery.mjs +28 -1
  337. package/src/session-runtime/agent-task-sessions.mjs +561 -199
  338. package/src/session-runtime/boot/apis.mjs +9 -0
  339. package/src/session-runtime/boot/begin.mjs +3 -2
  340. package/src/session-runtime/boot/infrastructure.mjs +4 -0
  341. package/src/session-runtime/boot/providers.mjs +3 -0
  342. package/src/session-runtime/boot/tools.mjs +8 -1
  343. package/src/session-runtime/bot-chain.mjs +32 -0
  344. package/src/session-runtime/bot-status.mjs +7 -4
  345. package/src/session-runtime/channel-config-api.mjs +63 -17
  346. package/src/session-runtime/config-lifecycle.mjs +6 -0
  347. package/src/session-runtime/connector-merge-migration.mjs +305 -0
  348. package/src/session-runtime/internal-tool-executor/ask-user-tool.mjs +132 -28
  349. package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +2 -0
  350. package/src/session-runtime/internal-tool-executor/reaction-tool.mjs +45 -0
  351. package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +72 -5
  352. package/src/session-runtime/internal-tool-executor.mjs +4 -0
  353. package/src/session-runtime/lifecycle/inheritance.mjs +16 -3
  354. package/src/session-runtime/lifecycle/session-catalog.mjs +3 -1
  355. package/src/session-runtime/lifecycle/teardown/runtime-stops.mjs +50 -4
  356. package/src/session-runtime/lifecycle/teardown.mjs +23 -5
  357. package/src/session-runtime/mcp-glue/server-catalog.mjs +61 -3
  358. package/src/session-runtime/mcp-oauth-login.mjs +5 -3
  359. package/src/session-runtime/mixy-heartbeat.mjs +927 -0
  360. package/src/session-runtime/model-route/route-tuning.mjs +10 -6
  361. package/src/session-runtime/notification-bus.mjs +31 -117
  362. package/src/session-runtime/notification-completion-queue.mjs +54 -0
  363. package/src/session-runtime/notification-listeners.mjs +76 -0
  364. package/src/session-runtime/owned-automation-run.mjs +35 -13
  365. package/src/session-runtime/prewarm/channel-start.mjs +3 -7
  366. package/src/session-runtime/provider-auth/login.mjs +7 -0
  367. package/src/session-runtime/provider-models/row-hydration.mjs +13 -2
  368. package/src/session-runtime/resource-mcp-api.mjs +143 -224
  369. package/src/session-runtime/resource-mcp-connector-accounts.mjs +163 -0
  370. package/src/session-runtime/resource-mcp-oauth-api.mjs +217 -0
  371. package/src/session-runtime/resource-mcp-secrets.mjs +82 -0
  372. package/src/session-runtime/resource-mcp-servers.mjs +78 -0
  373. package/src/session-runtime/resource-mcp-store.mjs +49 -0
  374. package/src/session-runtime/routine-home-turn.mjs +33 -6
  375. package/src/session-runtime/routine-owner.mjs +40 -9
  376. package/src/session-runtime/schedule-session-run.mjs +7 -3
  377. package/src/session-runtime/services/agent-tool/close-flow.mjs +3 -0
  378. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-plan.mjs +8 -12
  379. package/src/session-runtime/services/agent-tool/spawn-preset.mjs +7 -2
  380. package/src/session-runtime/services/agent-tool/tag-registry.mjs +1 -0
  381. package/src/session-runtime/services/agent-tool/worker-index/awaiting-user-sync.mjs +51 -0
  382. package/src/session-runtime/services/agent-tool/worker-index/disposal.mjs +55 -0
  383. package/src/session-runtime/services/agent-tool/worker-index/released-store.mjs +123 -0
  384. package/src/session-runtime/services/agent-tool/worker-index/restart-settlement.mjs +112 -0
  385. package/src/session-runtime/services/agent-tool/worker-index/row-reads.mjs +36 -0
  386. package/src/session-runtime/services/agent-tool/worker-index/row-shape.mjs +2 -0
  387. package/src/session-runtime/services/agent-tool/worker-index/row-store.mjs +17 -4
  388. package/src/session-runtime/services/agent-tool/worker-index/row-writes.mjs +58 -0
  389. package/src/session-runtime/services/agent-tool/worker-index.mjs +41 -241
  390. package/src/session-runtime/services/agent-tool/worker-rows.mjs +3 -0
  391. package/src/session-runtime/services/channel-admin.mjs +73 -31
  392. package/src/session-runtime/services/channel-session-router.mjs +4 -2
  393. package/src/session-runtime/services/channel-worker.mjs +1 -1
  394. package/src/session-runtime/services/provider-admin.mjs +128 -25
  395. package/src/session-runtime/services/schedule-access.mjs +14 -0
  396. package/src/session-runtime/services/seeds.mjs +0 -28
  397. package/src/session-runtime/services/usage-dashboard-model.mjs +1 -0
  398. package/src/session-runtime/session-compaction-sync.mjs +27 -0
  399. package/src/session-runtime/session-create/session-options.mjs +8 -4
  400. package/src/session-runtime/settings-builtin-tools-api.mjs +11 -0
  401. package/src/session-runtime/settings-compaction-api.mjs +2 -40
  402. package/src/session-runtime/settings-system-api.mjs +28 -1
  403. package/src/session-runtime/setup-tool/agent-settings-actions.mjs +65 -0
  404. package/src/session-runtime/setup-tool/executor.mjs +187 -29
  405. package/src/session-runtime/setup-tool/extended-actions.mjs +33 -2
  406. package/src/session-runtime/setup-tool/session-route-actions.mjs +152 -0
  407. package/src/session-runtime/setup-tool/settings-contract.mjs +68 -6
  408. package/src/session-runtime/setup-tool/tool-defs.mjs +92 -6
  409. package/src/session-runtime/task-session-route.mjs +99 -0
  410. package/src/session-runtime/tool-policy/agent-profile-fold.mjs +17 -13
  411. package/src/session-runtime/tool-policy/policy-stage.mjs +21 -4
  412. package/src/session-runtime/tool-policy/surface-helpers.mjs +2 -3
  413. package/src/session-runtime/tool-surface.mjs +4 -0
  414. package/src/session-runtime/turn/turn-run/ask-callbacks.mjs +1 -0
  415. package/src/session-runtime/workflow-agents-api/agent-editor.mjs +98 -21
  416. package/src/session-runtime/workflow-agents-api/style-and-mode.mjs +4 -0
  417. package/src/session-runtime/workflow-agents-api/workflow-packs.mjs +6 -1
  418. package/src/session-runtime/workspace/transitions.mjs +10 -2
  419. package/src/standalone/channel-transport/client-registry/client-records.mjs +65 -0
  420. package/src/standalone/channel-transport/client-registry/client-registration.mjs +118 -0
  421. package/src/standalone/channel-transport/client-registry.mjs +24 -163
  422. package/src/standalone/channel-transport.mjs +1 -1
  423. package/src/standalone/daemon-channels-loader.mjs +10 -8
  424. package/src/standalone/daemon-session-control/list-page.mjs +72 -0
  425. package/src/standalone/daemon-session-control/request.mjs +51 -0
  426. package/src/standalone/daemon-session-control/room-host.mjs +57 -0
  427. package/src/standalone/daemon-session-control/route-control.mjs +48 -0
  428. package/src/standalone/daemon-session-control/send-turn.mjs +60 -0
  429. package/src/standalone/daemon-session-control/worktree-control.mjs +40 -0
  430. package/src/standalone/daemon-session-control.mjs +161 -157
  431. package/src/standalone/daemon.mjs +33 -2
  432. package/src/standalone/session-client.mjs +7 -3
  433. package/src/standalone/session-protocol.mjs +10 -0
  434. package/src/standalone/session-service/agent-tree/agent-cancel.mjs +6 -2
  435. package/src/standalone/session-service/agent-tree/agent-child.mjs +1 -0
  436. package/src/standalone/session-service/quota-resume.mjs +3 -0
  437. package/src/standalone/session-service/retention/busy.mjs +65 -1
  438. package/src/standalone/session-service/session-calls/session-action.mjs +23 -2
  439. package/src/standalone/session-service/session-calls/session-turns.mjs +6 -0
  440. package/src/standalone/session-service/session-calls/session-views.mjs +8 -0
  441. package/src/standalone/session-service.mjs +13 -0
  442. package/src/standalone/session-tool-output.mjs +21 -10
  443. package/src/tui/app/model-options.mjs +4 -27
  444. package/src/tui/dist/index.mjs +81 -65
  445. package/src/tui/session/agent-job-feed/model-notification.mjs +3 -0
  446. package/src/tui/session/initial-state.mjs +3 -0
  447. package/src/tui/session/notice-surface.mjs +23 -1
  448. package/src/tui/session/queue-helpers.mjs +3 -42
  449. package/src/tui/session/session-api/integrations.mjs +1 -0
  450. package/src/tui/session/session-api/lifecycle.mjs +8 -0
  451. package/src/tui/session/session-api/routes-agent-definitions.mjs +14 -2
  452. package/src/tui/session/session-api/routes-write.mjs +5 -1
  453. package/src/tui/session/session-api/routes.mjs +1 -0
  454. package/src/tui/session/session-api/settings.mjs +30 -2
  455. package/src/tui/session/session-flow/auto-clear.mjs +4 -33
  456. package/src/tui/session/session-flow/drain-closed-queue.mjs +38 -0
  457. package/src/tui/session/session-flow/drain-enqueue.mjs +86 -0
  458. package/src/tui/session/session-flow/drain-retry.mjs +35 -0
  459. package/src/tui/session/session-flow/drain.mjs +118 -149
  460. package/src/tui/session/session-flow/queue/entry-shape.mjs +5 -0
  461. package/src/tui/session/session-flow/queue/take-entries.mjs +5 -2
  462. package/src/tui/session/tool-approval-delegation.mjs +64 -0
  463. package/src/tui/session/tool-approval-request.mjs +39 -0
  464. package/src/tui/session/tool-approval-settle.mjs +62 -0
  465. package/src/tui/session/tool-approval.mjs +69 -115
  466. package/src/tui/session/tui-steering-persist.mjs +8 -1
  467. package/src/tui/session/turn-stream.mjs +36 -3
  468. package/src/tui/session/turn.mjs +23 -2
  469. package/src/vendor/statusline/bin/statusline-route.mjs +1 -219
  470. package/src/vendor/statusline/src/gateway/route-meta.mjs +35 -13
  471. package/scripts/code-graph-description-contract.mjs +0 -188
  472. package/src/runtime/channels/lib/owned-runtime/ownership-refresh.mjs +0 -36
@@ -2,6 +2,7 @@ import { randomUUID } from 'node:crypto';
2
2
  import { renameSync } from 'node:fs';
3
3
  import { modelProxyClientMode, serverModelCredentialsDisabledError } from '../../runtime/shared/model-proxy-mode.mjs';
4
4
  import { sameAccountIdentity } from '../../runtime/agent/orchestrator/providers/lib/oauth-token-utils.mjs';
5
+ import { agentApiKeyEnvName } from '../../runtime/shared/provider-api-key.mjs';
5
6
  import {
6
7
  AGENT_PROVIDER_ENV,
7
8
  SECRET_ACCOUNTS,
@@ -9,6 +10,7 @@ import {
9
10
  getAgentApiKey,
10
11
  getKeychainStatus,
11
12
  hasStoredSecret,
13
+ isFallbackSecret,
12
14
  saveSecretAsync,
13
15
  } from '../../runtime/shared/config.mjs';
14
16
  import {
@@ -80,6 +82,13 @@ import {
80
82
  hasCursorOAuthCredentials,
81
83
  loginCursorOAuth,
82
84
  } from '../../runtime/agent/orchestrator/providers/cursor-auth.mjs';
85
+ import {
86
+ beginDevinOAuthLogin,
87
+ describeDevinOAuthCredentials,
88
+ forgetDevinOAuthCredentials,
89
+ hasDevinOAuthCredentials,
90
+ loginDevinOAuth,
91
+ } from '../../runtime/agent/orchestrator/providers/devin-auth.mjs';
83
92
  import {
84
93
  describeAntigravityOAuthCredentials,
85
94
  forgetAntigravityOAuthCredentials,
@@ -100,6 +109,7 @@ import {
100
109
  removeProviderAccount,
101
110
  clearProviderAccountQuotaState,
102
111
  providerAccountLimit,
112
+ providerAccountBlockedUntil,
103
113
  ACCOUNT_PROVIDERS,
104
114
  } from '../../runtime/shared/provider-accounts.mjs';
105
115
  import { currentProviderAccountId, withProviderAccount } from '../../runtime/shared/provider-auth-binding.mjs';
@@ -214,6 +224,16 @@ const OAUTH_PROVIDERS = Object.freeze([
214
224
  begin: beginCursorOAuthLogin,
215
225
  login: loginCursorOAuth,
216
226
  }),
227
+ Object.freeze({
228
+ id: 'devin-oauth',
229
+ name: 'Devin',
230
+ desc: 'Sign in with your Devin account',
231
+ has: hasDevinOAuthCredentials,
232
+ describe: describeDevinOAuthCredentials,
233
+ forget: forgetDevinOAuthCredentials,
234
+ begin: beginDevinOAuthLogin,
235
+ login: loginDevinOAuth,
236
+ }),
217
237
  Object.freeze({
218
238
  id: 'antigravity-oauth',
219
239
  name: 'Antigravity OAuth',
@@ -231,7 +251,7 @@ const BUILTIN_PROVIDER_IDS = new Set(['mixdog-local']);
231
251
  const API_PROVIDER_IDS = new Set(API_PROVIDERS.map((p) => p.id));
232
252
  const OAUTH_BY_ID = new Map(OAUTH_PROVIDERS.map((p) => [p.id, p]));
233
253
 
234
- // Dev-only entries (cursor-oauth, antigravity-oauth, mimo-oauth) are unknown to
254
+ // Dev-only entries (cursor-oauth, devin-oauth, antigravity-oauth, mimo-oauth) are unknown to
235
255
  // settings/login while the Developer → Providers option is off. Filtered per
236
256
  // call, so toggling the option takes effect without a restart.
237
257
  function availableOAuthProviders() {
@@ -320,33 +340,71 @@ const KEYCHAIN_HINTS = Object.freeze({
320
340
  error: 'The system keyring could not be read — check that it is running and unlocked.',
321
341
  });
322
342
 
343
+ // The private-file store being ignored, by what is wrong with it (the repair
344
+ // differs: chmod cannot fix an owner or a symlink, and a save fails through a
345
+ // foreign or symlinked folder).
346
+ const UNSAFE_STORE_HINTS = Object.freeze({
347
+ permissions:
348
+ 'The private secrets folder has unsafe permissions, so its keys are ignored — run chmod 700 on the folder and chmod 600 on its files, or save the key again.',
349
+ owner:
350
+ 'The private secrets folder or one of its files belongs to another user, so its keys are ignored — change its owner to the current user (chown).',
351
+ type: 'The private secrets folder or one of its files is a symlink or not a regular file, so its keys are ignored — remove it and save the key again.',
352
+ });
353
+
323
354
  export function keychainIssueFor(checkSecrets) {
324
355
  if (!checkSecrets) return null;
325
- const { state } = getKeychainStatus();
356
+ // A host with no keychain provider keeps its keys in the private secrets
357
+ // file (keychain-cjs.cjs "Linux fallback file"): that works, so nothing to
358
+ // report — unless the store's permissions make reads ignore it, which is
359
+ // reported with the folder to repair. A locked keyring is still an issue.
360
+ const { state, fallback, unsafeStore } = getKeychainStatus();
361
+ if (fallback && unsafeStore) {
362
+ const { kind, path } = unsafeStore;
363
+ return { state: 'unsafe-store', kind, message: UNSAFE_STORE_HINTS[kind] ?? UNSAFE_STORE_HINTS.permissions, path };
364
+ }
365
+ if (fallback) return null;
326
366
  const message = KEYCHAIN_HINTS[state];
327
367
  return message ? { state, message } : null;
328
368
  }
329
369
 
330
- function apiProviderSetup(p, providers, checkSecrets) {
370
+ // Where a stored key lives, for a row's detail line: decided per account, so a
371
+ // key that is still only in the fallback file reads as such after the keychain
372
+ // recovers.
373
+ function storedSecretDetail(account) {
374
+ return isFallbackSecret(account) ? 'stored in private file' : 'stored in keychain';
375
+ }
376
+
377
+ // `keychainIssue`: the setup response's one keyring check (never asked per row).
378
+ function apiProviderSetup(p, providers, checkSecrets, keychainIssue) {
331
379
  const configured = providers[p.id] || {};
332
- const envName = AGENT_PROVIDER_ENV[p.id] || p.env;
333
- const env = Boolean(envName && process.env[envName]);
380
+ // The environment variable the key resolver actually reads (aliases included);
381
+ // it wins over a stored key, so provenance follows it, not the stored secret.
382
+ const resolvedEnv = agentApiKeyEnvName(p.id);
383
+ const declaredEnv = AGENT_PROVIDER_ENV[p.id] || p.env;
384
+ const envName = resolvedEnv || declaredEnv;
385
+ const env = Boolean(resolvedEnv || (declaredEnv && process.env[declaredEnv]));
334
386
  const configuredEnabled = configured.enabled === true;
335
387
  const stored = checkSecrets ? hasStoredSecret(SECRET_ACCOUNTS.agentApiKey(p.id)) : false;
336
388
  const authenticated = env || stored || (checkSecrets ? Boolean(getAgentApiKey(p.id)) : configuredEnabled);
337
389
  let status = configuredEnabled ? 'No Key' : 'Off';
338
- if (stored) status = 'Set';
339
- else if (env) status = 'Env';
340
- else if (authenticated) status = 'Set';
390
+ if (env) status = 'Env';
391
+ else if (stored || authenticated) status = 'Set';
392
+ // Where the effective credential comes from: environment | private-file | keychain.
393
+ let credentialSource = null;
341
394
  let detail = envName;
342
- if (stored) detail = 'stored in keychain';
343
- else if (env) detail = envName;
344
- else if (authenticated) detail = 'runtime credential';
345
- const keychainIssue = authenticated ? null : keychainIssueFor(checkSecrets);
346
- if (keychainIssue) detail = keychainIssue.message;
395
+ if (env) {
396
+ credentialSource = 'environment';
397
+ } else if (stored) {
398
+ detail = storedSecretDetail(SECRET_ACCOUNTS.agentApiKey(p.id));
399
+ credentialSource = detail === 'stored in private file' ? 'private-file' : 'keychain';
400
+ } else if (authenticated) {
401
+ detail = 'runtime credential';
402
+ }
403
+ const rowIssue = authenticated ? null : keychainIssue;
404
+ if (rowIssue) detail = rowIssue.message;
347
405
  return {
348
406
  ...p,
349
- ...(keychainIssue ? { keychainIssue } : {}),
407
+ ...(rowIssue ? { keychainIssue: rowIssue } : {}),
350
408
  group: 'api',
351
409
  type: 'api-key',
352
410
  enabled: configuredEnabled || authenticated,
@@ -356,6 +414,7 @@ function apiProviderSetup(p, providers, checkSecrets) {
356
414
  envName,
357
415
  status,
358
416
  detail,
417
+ ...(credentialSource ? { credentialSource } : {}),
359
418
  };
360
419
  }
361
420
 
@@ -469,7 +528,7 @@ function customProviderRow(id, entry, checkSecrets = true) {
469
528
  const stored = checkSecrets ? hasStoredSecret(SECRET_ACCOUNTS.agentApiKey(id)) : false;
470
529
  const unstoredStatus = configuredEnabled ? 'No Key' : 'Off';
471
530
  let status = stored ? 'Set' : unstoredStatus;
472
- let detail = stored ? 'stored in keychain' : 'custom endpoint';
531
+ let detail = stored ? storedSecretDetail(SECRET_ACCOUNTS.agentApiKey(id)) : 'custom endpoint';
473
532
  if (apiKeyEnv) {
474
533
  status = envSet ? 'Env' : unstoredStatus;
475
534
  detail = apiKeyEnv;
@@ -533,7 +592,7 @@ export async function providerSetup(config = {}, options = {}) {
533
592
  return {
534
593
  ...(keychain ? { keychain } : {}),
535
594
  api: [
536
- ...API_PROVIDERS.map((p) => apiProviderSetup(p, providers, checkSecrets)),
595
+ ...API_PROVIDERS.map((p) => apiProviderSetup(p, providers, checkSecrets, keychain)),
537
596
  ...customProviderRows(providers, checkSecrets),
538
597
  ],
539
598
  oauth: availableOAuthProviders().map((p) => oauthProviderSetup(p, providers, checkSecrets)),
@@ -885,7 +944,8 @@ export function listProviderAccounts(provider) {
885
944
  authenticated: auth.authenticated === true,
886
945
  reauthRequired: auth.reauthRequired === true,
887
946
  usage: row.usage || null,
888
- blockedUntil: row.blockedUntil || null,
947
+ // When the limit shown lifts: the latest deadline of every block.
948
+ blockedUntil: providerAccountBlockedUntil(row) || null,
889
949
  // The limit holding the account now: account-wide, or only for one
890
950
  // model family ("7D Fable") while other models still run.
891
951
  limit: providerAccountLimit(row, now, { useCredits: pool.useCredits === true }),
@@ -1113,6 +1173,44 @@ export async function saveCustomProvider(cfgMod, rawInput) {
1113
1173
  return typed ? serializeCustomKeySave(id, commit) : commit();
1114
1174
  }
1115
1175
 
1176
+ // Replaces only the stored key of an existing custom provider. The provider's
1177
+ // settings are never read back and rewritten, so a concurrent edit of them
1178
+ // (or a removal) is never reverted.
1179
+ export async function saveCustomProviderKey(cfgMod, rawId, rawKey) {
1180
+ requireLocalProviderManagement();
1181
+ const id = String(rawId || '').trim();
1182
+ if (typeof rawKey !== 'string' || rawKey.length > CUSTOM_API_KEY_MAX) throw new TypeError('custom provider apiKey is invalid');
1183
+ const key = rawKey.trim();
1184
+ if (!key) throw new Error('API key is required');
1185
+ const takesStoredKey = () => {
1186
+ const entry = existingCustomEntry(cfgMod.loadConfig(), id);
1187
+ const config = storedCustomConfig(entry);
1188
+ if ((config?.auth ?? entry.auth) === 'none') throw new Error('this custom provider needs no API key');
1189
+ if (config?.apiKeyEnv) throw new Error(`this custom provider reads its key from ${config.apiKeyEnv}`);
1190
+ return entry;
1191
+ };
1192
+ takesStoredKey();
1193
+ // The provider's removal runs in the same queue, so it never lands between
1194
+ // the checks and the write below; a removal queued earlier is seen by the
1195
+ // check, before anything is written.
1196
+ return serializeCustomKeySave(id, async () => {
1197
+ takesStoredKey();
1198
+ const account = SECRET_ACCOUNTS.agentApiKey(id);
1199
+ const previousKey = getAgentApiKey(id);
1200
+ await saveSecretAsync(account, key);
1201
+ try {
1202
+ return customProviderRow(id, takesStoredKey());
1203
+ } catch (error) {
1204
+ // Switched to keyless (or the provider is gone) meanwhile: the key written
1205
+ // is dropped, and the previous one is only put back for a provider that exists.
1206
+ const exists = isCustomProviderConfig(cfgMod.loadConfig().providers?.[id]);
1207
+ if (exists && previousKey) await saveSecretAsync(account, previousKey);
1208
+ else await deleteSecretAsync(account);
1209
+ throw error;
1210
+ }
1211
+ });
1212
+ }
1213
+
1116
1214
  const MODEL_PATCH_KEYS = new Set([
1117
1215
  'manual',
1118
1216
  'hidden',
@@ -1292,14 +1390,19 @@ export async function removeCustomProvider(cfgMod, rawId) {
1292
1390
  requireLocalProviderManagement();
1293
1391
  const id = String(rawId || '').trim();
1294
1392
  existingCustomEntry(cfgMod.loadConfig(), id);
1295
- // Secret first: a real keychain failure (locked, permission) leaves the
1296
- // provider registered so the removal can be retried. A missing secret
1297
- // (keyless provider) is not an error.
1298
- await deleteSecretAsync(SECRET_ACCOUNTS.agentApiKey(id));
1299
- const current = cfgMod.loadConfig();
1300
- const { [id]: _removed, ...providers } = current.providers || {};
1301
- cfgMod.saveConfig(withoutProviderReferences({ ...current, providers }, id), { baseConfig: current });
1302
- return { provider: id, type: 'custom', removed: true };
1393
+ // In the provider's key queue: a key write in flight finishes first and
1394
+ // none starts between the secret's deletion and the config's.
1395
+ return serializeCustomKeySave(id, async () => {
1396
+ existingCustomEntry(cfgMod.loadConfig(), id);
1397
+ // Secret first: a real keychain failure (locked, permission) leaves the
1398
+ // provider registered so the removal can be retried. A missing secret
1399
+ // (keyless provider) is not an error.
1400
+ await deleteSecretAsync(SECRET_ACCOUNTS.agentApiKey(id));
1401
+ const current = cfgMod.loadConfig();
1402
+ const { [id]: _removed, ...providers } = current.providers || {};
1403
+ cfgMod.saveConfig(withoutProviderReferences({ ...current, providers }, id), { baseConfig: current });
1404
+ return { provider: id, type: 'custom', removed: true };
1405
+ });
1303
1406
  }
1304
1407
 
1305
1408
  export async function testCustomProvider(cfgMod, rawInput) {
@@ -21,6 +21,7 @@ import { MIXY_AGENT_ID, agentIdOfHomeSession } from '../../runtime/agent/orchest
21
21
  import { roomMemberOfSession } from '../../runtime/agent/orchestrator/session/agent-room.mjs';
22
22
  import { mixyDisplayName } from '../../runtime/agent/orchestrator/session/mixy-name.mjs';
23
23
  import { isAgentOwner } from '../../runtime/agent/orchestrator/agent-owner.mjs';
24
+ import { isHeartbeatSession } from '../../runtime/shared/routine-trigger.mjs';
24
25
  import { unattendedRunOf } from '../held-requests.mjs';
25
26
 
26
27
  const INTERACTIVE_SOURCE_TYPES = new Set(['', 'lead', 'cli']);
@@ -40,6 +41,8 @@ function provenanceScope(session, id) {
40
41
  if (member) return { kind: 'room-member', agentId: member.agentId };
41
42
  const homeAgent = agentIdOfHomeSession(id);
42
43
  if (homeAgent) return homeAgent === MIXY_AGENT_ID ? { kind: 'human' } : { kind: 'agent', agentId: homeAgent };
44
+ // Mixy's hidden heartbeat session: her own scope, as her chat's routine turns get.
45
+ if (isHeartbeatSession(id)) return { kind: 'agent', agentId: MIXY_AGENT_ID };
43
46
  const headless =
44
47
  !id ||
45
48
  isAgentOwner(session) ||
@@ -108,6 +111,17 @@ export function assertOwnAgentSettings(scope, agentId, action) {
108
111
  }
109
112
  }
110
113
 
114
+ /** Throws unless Mixy's heartbeat session `sessionId` may take setup `action`
115
+ * with `args`: on her own she only pauses a routine or runs one again; every
116
+ * other change she proposes (MIXY.md). Any other session passes. */
117
+ export function assertHeartbeatSetupAction(sessionId, action, args) {
118
+ if (!isHeartbeatSession(sessionId)) return;
119
+ if (action === 'run_automation' || (action === 'set_automation_enabled' && args?.enabled === false)) return;
120
+ throw new Error(
121
+ `A heartbeat turn only pauses a routine or runs one again (setup ${action} is refused); propose other changes with session action suggest`
122
+ );
123
+ }
124
+
111
125
  /** Throws when `scope` is a headless run: it reads settings, never changes
112
126
  * them; an unattended run changes only its own bot's automations and route. */
113
127
  export function assertInteractiveCaller(scope, action) {
@@ -49,34 +49,6 @@ export function ensureStandaloneEnvironment({ rootDir, dataDir }) {
49
49
  /* marker only; the sweep simply repeats */
50
50
  }
51
51
  }
52
- cleanupRetiredChannelSecrets(dataDir);
53
- }
54
-
55
- // One-shot keychain cleanup: Discord/Telegram messaging is retired, so any
56
- // stored bot tokens are orphans. Marker-gated so the (potentially slow) OS
57
- // keychain roundtrip runs once per install; lazy import so shared config
58
- // resolves its paths only after the env above is established.
59
- function cleanupRetiredChannelSecrets(dataDir) {
60
- const marker = join(dataDir, '.retired-channel-secrets-cleaned');
61
- if (existsSync(marker)) return;
62
- void import('../../runtime/shared/config.mjs')
63
- .then(async ({ deleteSecretAsync }) => {
64
- for (const account of ['discord.token', 'telegram.token']) {
65
- try {
66
- await deleteSecretAsync(account);
67
- } catch {
68
- /* best-effort */
69
- }
70
- }
71
- try {
72
- writeFileAtomicSync(marker, `${new Date().toISOString()}\n`);
73
- } catch {
74
- /* marker only */
75
- }
76
- })
77
- .catch(() => {
78
- /* cleanup is best-effort */
79
- });
80
52
  }
81
53
 
82
54
  // Shipped definitions live in code (read in place from the package); the data
@@ -348,6 +348,7 @@ const PROVIDER_RANKS = {
348
348
  'command-code-oauth': 33.5,
349
349
  'mimo-oauth': 34,
350
350
  'cursor-oauth': 35,
351
+ 'devin-oauth': 35.5,
351
352
  'antigravity-oauth': 36,
352
353
  'opencode-go-oauth': 38,
353
354
  openai: 50,
@@ -0,0 +1,27 @@
1
+ // Keeps a live session's compaction settings on the saved global ones. One
2
+ // helper for every path that can leave a session behind the config: saving the
3
+ // settings, a shared-config reload, and adopting a resumed or swapped session.
4
+ import { normalizeCompactionConfig } from '../runtime/agent/orchestrator/runtime-core/config-helpers.mjs';
5
+ import { COMPACTION_CONFIG_KEYS } from '../runtime/agent/orchestrator/runtime-core/compaction-config-keys.mjs';
6
+
7
+ /** A headless caller injects its own isolated config: its sessions keep the
8
+ * compaction they were created with instead of following the profile on disk. */
9
+ export function usesInjectedConfig(params) {
10
+ return Boolean(params?.initialConfig) && typeof params.initialConfig === 'object';
11
+ }
12
+
13
+ /** Replace the live session's compaction fields with the saved (normalized) ones. */
14
+ export function adoptSessionCompaction(session, saved) {
15
+ if (!session) return;
16
+ const currentSessionCompaction = { ...(session.compaction || {}) };
17
+ // Anything outside the config-owned set (per-session thresholds, archive
18
+ // state, timing) is the session's own and survives.
19
+ for (const key of COMPACTION_CONFIG_KEYS) delete currentSessionCompaction[key];
20
+ session.compaction = { ...currentSessionCompaction, ...saved };
21
+ }
22
+
23
+ /** Follow `config.compaction` on a session; a config without the section leaves it alone. */
24
+ export function syncSessionCompaction(session, config) {
25
+ if (!config?.compaction || typeof config.compaction !== 'object') return;
26
+ adoptSessionCompaction(session, normalizeCompactionConfig(config.compaction));
27
+ }
@@ -9,7 +9,7 @@ import { readAgentFrontmatterPermission } from '../services/agent-tool/helpers.m
9
9
  import { LEAD_DISALLOWED_TOOLS } from '../../runtime/agent/orchestrator/runtime-core/tool-defs.mjs';
10
10
  import { HEADLESS_TOOL_PROFILE } from '../../runtime/agent/orchestrator/runtime-core/tool-profile.mjs';
11
11
  import { AGENT_MODE, resolveSessionMode } from '../../runtime/agent/orchestrator/session/agent-mode.mjs';
12
- import { MIXY_AGENT_ID, agentIdOfHomeSession } from '../../runtime/agent/orchestrator/session/agent-home.mjs';
12
+ import { agentIdOfHomeSession } from '../../runtime/agent/orchestrator/session/agent-home.mjs';
13
13
  import { roomMemberOfSession } from '../../runtime/agent/orchestrator/session/agent-room.mjs';
14
14
  import { unattendedApprovalPort } from '../../runtime/agent/orchestrator/session/human-gate/gate.mjs';
15
15
 
@@ -33,6 +33,7 @@ function agentOwnedSessionFields(sessionProfile) {
33
33
  agentTag: sessionProfile?.agentTag || null,
34
34
  taskType: sessionProfile?.taskType || null,
35
35
  ...(sessionProfile?.routeFallbacks !== undefined ? { routeFallbacks: sessionProfile.routeFallbacks } : {}),
36
+ ...(sessionProfile?.routeFallbackSource ? { routeFallbackSource: sessionProfile.routeFallbackSource } : {}),
36
37
  permission: sessionProfile?.permission || undefined,
37
38
  permissionMode: sessionProfile?.permissionMode || undefined,
38
39
  schemaAllowedTools: Array.isArray(sessionProfile?.schemaAllowedTools)
@@ -70,7 +71,7 @@ export function sessionOptions(deps, coreMemoryContext) {
70
71
  const workflowContext = packContext;
71
72
  const leadWorkflowParts = agentOwned
72
73
  ? undefined
73
- : leadPromptParts({ agentMode: sessionMode === AGENT_MODE, mixy: actingAgent === MIXY_AGENT_ID });
74
+ : leadPromptParts({ agentMode: sessionMode === AGENT_MODE, agentId: actingAgent });
74
75
  const callerDisallowedTools = [
75
76
  ...(agentOwned ? [] : LEAD_DISALLOWED_TOOLS),
76
77
  ...(!agentOwned && rt.disallowDelegation ? ['agent'] : []),
@@ -88,17 +89,20 @@ export function sessionOptions(deps, coreMemoryContext) {
88
89
  lane: agentOwned ? 'agent' : 'cli',
89
90
  // One-shot `mixdog exec` runs carry their own source so session catalogs
90
91
  // can keep them out of the user's resumable list.
92
+ // A hidden run of an agent (Mixy's heartbeat) is an exec run too.
91
93
  sourceType: agentOwned
92
94
  ? sessionProfile?.sourceType || 'agent'
93
- : rt.toolProfile === HEADLESS_TOOL_PROFILE
95
+ : rt.toolProfile === HEADLESS_TOOL_PROFILE || sessionProfile?.sourceType === 'exec'
94
96
  ? 'exec'
95
97
  : 'lead',
96
98
  sourceName: agentOwned
97
99
  ? sessionProfile?.sourceName || sessionProfile?.agent || 'agent'
98
100
  : taskOrigin
99
101
  ? `agent:${taskOrigin.agentId}${taskOriginSuffix(taskOrigin)}`
100
- : 'main',
102
+ : clean(sessionProfile?.sourceName) || 'main',
101
103
  ...(taskOrigin ? { taskOrigin } : {}),
104
+ // The agent a run acts for (agent mode, its memory; agent-mode.mjs).
105
+ ...(!agentOwned && clean(sessionProfile?.ownerAgentId) ? { ownerAgentId: clean(sessionProfile.ownerAgentId) } : {}),
102
106
  ...(rt.approvalMode ? { approvalMode: rt.approvalMode } : {}),
103
107
  clientHostPid: sessionProfile?.clientHostPid || process.pid,
104
108
  mcpScopeId: rt.mcpScopeId,
@@ -96,6 +96,17 @@ export function createBuiltinToolSettings(
96
96
  saveConfigAndAdopt({ ...getConfig(), aiSessionTitles: enabled !== false });
97
97
  return this.getSessionTitleSettings();
98
98
  },
99
+ // Prompt-cache warming on/off (orchestrator session/cache-warm.mjs);
100
+ // default on. The warmer reads the saved value at each
101
+ // warm, so a change applies without a restart.
102
+ getCacheWarmingSettings() {
103
+ return { enabled: getConfig()?.promptCacheWarming !== false };
104
+ },
105
+ setCacheWarmingEnabled(enabled) {
106
+ if (typeof enabled !== 'boolean') throw new TypeError('cache warming must be on or off (a boolean)');
107
+ saveConfigAndAdopt({ ...getConfig(), promptCacheWarming: enabled });
108
+ return this.getCacheWarmingSettings();
109
+ },
99
110
  // The one pixel face every Lead row on the bot page wears, shared by every
100
111
  // device that follows this host. Only a mascot look counts; null (the
101
112
  // default grey pup) is stored as no key.
@@ -6,38 +6,8 @@ import {
6
6
  import { isAutoClearUnlimited } from '../runtime/agent/orchestrator/runtime-core/config-helpers.mjs';
7
7
  import { COMPACTION_SUMMARY_MODES } from '../runtime/agent/orchestrator/session/compact/summary-mode.mjs';
8
8
 
9
- // Every spelling of the main-context buffer budget; a new representation
10
- // replaces the previous one.
11
- const MAIN_BUFFER_KEYS = [
12
- 'mainBufferTokens',
13
- 'mainBuffer',
14
- 'mainBufferPercent',
15
- 'mainBufferPct',
16
- 'mainBufferRatio',
17
- 'mainBufferFraction',
18
- ];
19
- // Session-level compaction fields that the saved config owns from now on.
20
- const SESSION_COMPACTION_KEYS = [
21
- 'type',
22
- 'compactType',
23
- 'compact_type',
24
- 'semantic',
25
- 'semanticModel',
26
- 'prune',
27
- 'tailTurns',
28
- 'recallMemoryTimeoutMs',
29
- 'recallIngestLimit',
30
- 'recallChunkLimit',
31
- 'recallLimit',
32
- 'recallCycle1BatchSize',
33
- 'recallRowsPerSession',
34
- 'recallWindowSize',
35
- 'recallConcurrency',
36
- 'recallCycle1DeadlineMs',
37
- // Replaced by summaryMode.
38
- 'useMaintainer',
39
- ...MAIN_BUFFER_KEYS,
40
- ];
9
+ import { MAIN_BUFFER_KEYS } from '../runtime/agent/orchestrator/runtime-core/compaction-config-keys.mjs';
10
+ import { adoptSessionCompaction } from './session-compaction-sync.mjs';
41
11
 
42
12
  // Unlimited (never auto-clear) typed as a duration.
43
13
  const UNLIMITED_DURATION = /^(?:unlimited|never)$/i;
@@ -66,14 +36,6 @@ function applyCompactionInput(next, input, hasOwn) {
66
36
  return next;
67
37
  }
68
38
 
69
- /** Replace the live session's compaction fields with the saved config's. */
70
- function adoptSessionCompaction(session, saved) {
71
- if (!session) return;
72
- const currentSessionCompaction = { ...(session.compaction || {}) };
73
- for (const key of SESSION_COMPACTION_KEYS) delete currentSessionCompaction[key];
74
- session.compaction = { ...currentSessionCompaction, ...saved };
75
- }
76
-
77
39
  // Advanced picker shows only providers the user actually has enabled
78
40
  // (config.providers[*].enabled), plus the active route provider, any
79
41
  // provider with a custom override, and the 'default' fallback row —
@@ -1,4 +1,10 @@
1
- // Automation worker status, the system shell and self-update settings.
1
+ // Automation worker status, the system shell, self-update, Mixy's heartbeat
2
+ // and bots' reactions settings.
3
+ import {
4
+ normalizeHeartbeatIntervalMinutes,
5
+ requireHeartbeatIntervalMinutes,
6
+ } from '../runtime/shared/heartbeat-interval.mjs';
7
+
2
8
  export function createSystemSettings({
3
9
  getConfig,
4
10
  saveConfigAndAdopt,
@@ -49,6 +55,27 @@ export function createSystemSettings({
49
55
  });
50
56
  return this.getUpdateSettings();
51
57
  },
58
+ getHeartbeatSettings() {
59
+ return {
60
+ heartbeat: getConfig()?.heartbeat !== false,
61
+ intervalMinutes: normalizeHeartbeatIntervalMinutes(getConfig()?.heartbeatIntervalMinutes),
62
+ };
63
+ },
64
+ setHeartbeatEnabled(enabled) {
65
+ saveConfigAndAdopt({ ...getConfig(), heartbeat: enabled === true });
66
+ return this.getHeartbeatSettings();
67
+ },
68
+ setHeartbeatInterval(minutes) {
69
+ saveConfigAndAdopt({ ...getConfig(), heartbeatIntervalMinutes: requireHeartbeatIntervalMinutes(minutes) });
70
+ return this.getHeartbeatSettings();
71
+ },
72
+ getReactionSettings() {
73
+ return { reactions: getConfig()?.reactions !== false };
74
+ },
75
+ setReactionsEnabled(enabled) {
76
+ saveConfigAndAdopt({ ...getConfig(), reactions: enabled === true });
77
+ return this.getReactionSettings();
78
+ },
52
79
  async checkForUpdate(options = {}) {
53
80
  await checkForUpdateInternal({ force: options?.force === true });
54
81
  return this.getUpdateSettings();
@@ -0,0 +1,65 @@
1
+ /** Setup actions for per-agent and per-project switches and the bot roster:
2
+ * action permissions, connector switches, archived bots, bot order and
3
+ * prompt-cache warming. Each goes through the runtime method its settings
4
+ * surface uses. Permission and connector writes are made as a remote client's
5
+ * are (`noWiden`): a chat may take authority away, never give an agent more
6
+ * without asking — that stays with the person in the desktop app. */
7
+ import { agentPermissions, setAgentPermission } from '../../runtime/agent/orchestrator/session/human-gate/store.mjs';
8
+ import { clean } from '../../runtime/agent/orchestrator/runtime-core/session-text.mjs';
9
+
10
+ const NO_WIDEN = Object.freeze({ noWiden: true });
11
+
12
+ function requireText(value, label) {
13
+ const text = clean(value);
14
+ if (!text) throw new Error(`${label} is required`);
15
+ return text;
16
+ }
17
+
18
+ export const AGENT_SETTINGS_HANDLERS = {
19
+ async read_agent_settings(rt, args) {
20
+ const agent = requireText(args.agent, 'agent');
21
+ const [permissions, connectors, alwaysAllowedTools] = await Promise.all([
22
+ agentPermissions(agent),
23
+ rt.getAgentConnectors(agent),
24
+ rt.getAgentAlwaysAllowedTools(agent),
25
+ ]);
26
+ return { agent, permissions, connectors, alwaysAllowedTools };
27
+ },
28
+ read_project_connectors: async (rt, args) => {
29
+ const projectPath = requireText(args.projectPath, 'projectPath');
30
+ return { projectPath, connectors: await rt.getProjectConnectors(projectPath) };
31
+ },
32
+ async set_agent_permission(_rt, args) {
33
+ const agent = requireText(args.agent, 'agent');
34
+ return { agent, permissions: await setAgentPermission(agent, args.actionKind, args.permissionMode, NO_WIDEN) };
35
+ },
36
+ async set_agent_connector(rt, args) {
37
+ const agent = requireText(args.agent, 'agent');
38
+ const name = requireText(args.name, 'name');
39
+ return { agent, connectors: await rt.setAgentConnectorEnabled(agent, name, args.enabled, NO_WIDEN) };
40
+ },
41
+ async set_agent_connector_tool(rt, args) {
42
+ const agent = requireText(args.agent, 'agent');
43
+ const name = requireText(args.name, 'name');
44
+ const tool = requireText(args.tool, 'tool');
45
+ await rt.setAgentConnectorToolPermission(agent, name, tool, args.permission, NO_WIDEN);
46
+ return { agent, connector: name, tool, permission: args.permission };
47
+ },
48
+ async set_project_connector(rt, args) {
49
+ const projectPath = requireText(args.projectPath, 'projectPath');
50
+ const name = requireText(args.name, 'name');
51
+ return { projectPath, connectors: await rt.setProjectConnectorEnabled(projectPath, name, args.enabled, NO_WIDEN) };
52
+ },
53
+ async restore_definition(rt, args) {
54
+ if (args.definitionKind !== 'agent') {
55
+ throw new Error('Only an archived agent or bot can be restored; a deleted workflow is gone');
56
+ }
57
+ const name = requireText(args.name, 'name');
58
+ await rt.restoreAgentDefinition(name);
59
+ return { restored: name, note: 'Its chat is back; its routines stay off until they are turned on.' };
60
+ },
61
+ set_bot_order: (rt, args) => ({ botOrder: rt.setBotOrder(args.botOrder).order }),
62
+ set_cache_warming_enabled: (rt, args) => ({
63
+ promptCacheWarming: rt.setCacheWarmingEnabled(args.enabled).enabled,
64
+ }),
65
+ };