@mono-agent/agent-app 0.20.10 → 0.20.14

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 (222) hide show
  1. package/README.md +33 -18
  2. package/dist/app-config.d.ts +2 -2
  3. package/dist/app-controller-channels.d.ts +4 -0
  4. package/dist/app-controller-channels.d.ts.map +1 -1
  5. package/dist/app-controller-channels.js +20 -2
  6. package/dist/app-controller-channels.js.map +1 -1
  7. package/dist/app-controller-continuation.d.ts.map +1 -1
  8. package/dist/app-controller-continuation.js +2 -3
  9. package/dist/app-controller-continuation.js.map +1 -1
  10. package/dist/app-controller-lifecycle.d.ts +4 -0
  11. package/dist/app-controller-lifecycle.d.ts.map +1 -1
  12. package/dist/app-controller-lifecycle.js +7 -0
  13. package/dist/app-controller-lifecycle.js.map +1 -1
  14. package/dist/app-controller-monitors.d.ts +26 -0
  15. package/dist/app-controller-monitors.d.ts.map +1 -0
  16. package/dist/app-controller-monitors.js +127 -0
  17. package/dist/app-controller-monitors.js.map +1 -0
  18. package/dist/app-controller-responder.d.ts +7 -17
  19. package/dist/app-controller-responder.d.ts.map +1 -1
  20. package/dist/app-controller-responder.js +33 -69
  21. package/dist/app-controller-responder.js.map +1 -1
  22. package/dist/app-controller-utils.d.ts +1 -5
  23. package/dist/app-controller-utils.d.ts.map +1 -1
  24. package/dist/app-controller-utils.js +4 -21
  25. package/dist/app-controller-utils.js.map +1 -1
  26. package/dist/app-controller.d.ts +25 -11
  27. package/dist/app-controller.d.ts.map +1 -1
  28. package/dist/app-controller.js +36 -1
  29. package/dist/app-controller.js.map +1 -1
  30. package/dist/channel-drivers/slack.d.ts.map +1 -1
  31. package/dist/channel-drivers/slack.js +24 -0
  32. package/dist/channel-drivers/slack.js.map +1 -1
  33. package/dist/channel-drivers/telegram.d.ts.map +1 -1
  34. package/dist/channel-drivers/telegram.js +26 -0
  35. package/dist/channel-drivers/telegram.js.map +1 -1
  36. package/dist/channel-drivers/tui.d.ts +68 -8
  37. package/dist/channel-drivers/tui.d.ts.map +1 -1
  38. package/dist/channel-drivers/tui.js +388 -89
  39. package/dist/channel-drivers/tui.js.map +1 -1
  40. package/dist/channel-runtime-controls.d.ts +2 -1
  41. package/dist/channel-runtime-controls.d.ts.map +1 -1
  42. package/dist/channel-runtime-controls.js +79 -22
  43. package/dist/channel-runtime-controls.js.map +1 -1
  44. package/dist/cli-args.d.ts +4 -6
  45. package/dist/cli-args.d.ts.map +1 -1
  46. package/dist/cli-args.js +16 -36
  47. package/dist/cli-args.js.map +1 -1
  48. package/dist/cli-commands.d.ts.map +1 -1
  49. package/dist/cli-commands.js +11 -0
  50. package/dist/cli-commands.js.map +1 -1
  51. package/dist/cli-help.d.ts +26 -0
  52. package/dist/cli-help.d.ts.map +1 -1
  53. package/dist/cli-help.js +25 -34
  54. package/dist/cli-help.js.map +1 -1
  55. package/dist/cli-init-command.d.ts +1 -2
  56. package/dist/cli-init-command.d.ts.map +1 -1
  57. package/dist/cli-init-command.js +5 -49
  58. package/dist/cli-init-command.js.map +1 -1
  59. package/dist/config-reference.d.ts.map +1 -1
  60. package/dist/config-reference.js +161 -52
  61. package/dist/config-reference.js.map +1 -1
  62. package/dist/configuration-proposal-tool.d.ts.map +1 -1
  63. package/dist/configuration-proposal-tool.js +3 -11
  64. package/dist/configuration-proposal-tool.js.map +1 -1
  65. package/dist/configured-agent.d.ts +18 -3
  66. package/dist/configured-agent.d.ts.map +1 -1
  67. package/dist/configured-agent.js +67 -86
  68. package/dist/configured-agent.js.map +1 -1
  69. package/dist/conversation-title.d.ts.map +1 -1
  70. package/dist/conversation-title.js +9 -2
  71. package/dist/conversation-title.js.map +1 -1
  72. package/dist/doctor.d.ts +7 -13
  73. package/dist/doctor.d.ts.map +1 -1
  74. package/dist/doctor.js +191 -725
  75. package/dist/doctor.js.map +1 -1
  76. package/dist/first-run-readiness.d.ts.map +1 -1
  77. package/dist/first-run-readiness.js +0 -6
  78. package/dist/first-run-readiness.js.map +1 -1
  79. package/dist/local-configuration.d.ts.map +1 -1
  80. package/dist/local-configuration.js +9 -37
  81. package/dist/local-configuration.js.map +1 -1
  82. package/dist/memory-remember.d.ts +49 -0
  83. package/dist/memory-remember.d.ts.map +1 -0
  84. package/dist/memory-remember.js +190 -0
  85. package/dist/memory-remember.js.map +1 -0
  86. package/dist/memory-retrieval.d.ts +24 -0
  87. package/dist/memory-retrieval.d.ts.map +1 -1
  88. package/dist/memory-retrieval.js +23 -0
  89. package/dist/memory-retrieval.js.map +1 -1
  90. package/dist/model-effort-capabilities.d.ts +8 -9
  91. package/dist/model-effort-capabilities.d.ts.map +1 -1
  92. package/dist/model-effort-capabilities.js +17 -35
  93. package/dist/model-effort-capabilities.js.map +1 -1
  94. package/dist/modules/base.d.ts +3 -4
  95. package/dist/modules/base.d.ts.map +1 -1
  96. package/dist/modules/base.js +3 -5
  97. package/dist/modules/base.js.map +1 -1
  98. package/dist/modules/catalog.d.ts.map +1 -1
  99. package/dist/modules/catalog.js +11 -9
  100. package/dist/modules/catalog.js.map +1 -1
  101. package/dist/modules/known-tools.d.ts +2 -2
  102. package/dist/modules/known-tools.d.ts.map +1 -1
  103. package/dist/modules/known-tools.js +6 -0
  104. package/dist/modules/known-tools.js.map +1 -1
  105. package/dist/monitor-channel-routing.d.ts +20 -0
  106. package/dist/monitor-channel-routing.d.ts.map +1 -0
  107. package/dist/monitor-channel-routing.js +73 -0
  108. package/dist/monitor-channel-routing.js.map +1 -0
  109. package/dist/monitors-command.d.ts +23 -0
  110. package/dist/monitors-command.d.ts.map +1 -0
  111. package/dist/monitors-command.js +207 -0
  112. package/dist/monitors-command.js.map +1 -0
  113. package/dist/monitors-config.d.ts +74 -0
  114. package/dist/monitors-config.d.ts.map +1 -0
  115. package/dist/monitors-config.js +146 -0
  116. package/dist/monitors-config.js.map +1 -0
  117. package/dist/monitors-context.d.ts +58 -0
  118. package/dist/monitors-context.d.ts.map +1 -0
  119. package/dist/monitors-context.js +182 -0
  120. package/dist/monitors-context.js.map +1 -0
  121. package/dist/monitors-runtime.d.ts +36 -0
  122. package/dist/monitors-runtime.d.ts.map +1 -0
  123. package/dist/monitors-runtime.js +103 -0
  124. package/dist/monitors-runtime.js.map +1 -0
  125. package/dist/monitors-service.d.ts +71 -0
  126. package/dist/monitors-service.d.ts.map +1 -0
  127. package/dist/monitors-service.js +1665 -0
  128. package/dist/monitors-service.js.map +1 -0
  129. package/dist/monitors-store.d.ts +83 -0
  130. package/dist/monitors-store.d.ts.map +1 -0
  131. package/dist/monitors-store.js +283 -0
  132. package/dist/monitors-store.js.map +1 -0
  133. package/dist/process-jobs-context.d.ts +8 -0
  134. package/dist/process-jobs-context.d.ts.map +1 -1
  135. package/dist/process-jobs-context.js +11 -0
  136. package/dist/process-jobs-context.js.map +1 -1
  137. package/dist/process-jobs-protection.js +1 -1
  138. package/dist/process-jobs-protection.js.map +1 -1
  139. package/dist/process-jobs-runtime.d.ts.map +1 -1
  140. package/dist/process-jobs-runtime.js +1 -12
  141. package/dist/process-jobs-runtime.js.map +1 -1
  142. package/dist/process-jobs-service.d.ts.map +1 -1
  143. package/dist/process-jobs-service.js +3 -149
  144. package/dist/process-jobs-service.js.map +1 -1
  145. package/dist/process-output-redaction.d.ts +33 -0
  146. package/dist/process-output-redaction.d.ts.map +1 -0
  147. package/dist/process-output-redaction.js +149 -0
  148. package/dist/process-output-redaction.js.map +1 -0
  149. package/dist/provider-model-catalog.d.ts +78 -0
  150. package/dist/provider-model-catalog.d.ts.map +1 -0
  151. package/dist/provider-model-catalog.js +439 -0
  152. package/dist/provider-model-catalog.js.map +1 -0
  153. package/dist/provider-setup.d.ts +4 -13
  154. package/dist/provider-setup.d.ts.map +1 -1
  155. package/dist/provider-setup.js +5 -115
  156. package/dist/provider-setup.js.map +1 -1
  157. package/dist/readiness-probe-worker.d.ts +1 -2
  158. package/dist/readiness-probe-worker.d.ts.map +1 -1
  159. package/dist/readiness-probe-worker.js +3 -8
  160. package/dist/readiness-probe-worker.js.map +1 -1
  161. package/dist/readiness-probe.d.ts +1 -1
  162. package/dist/readiness-probe.d.ts.map +1 -1
  163. package/dist/readiness-probe.js +3 -33
  164. package/dist/readiness-probe.js.map +1 -1
  165. package/dist/request-model-override.d.ts +4 -36
  166. package/dist/request-model-override.d.ts.map +1 -1
  167. package/dist/request-model-override.js +58 -146
  168. package/dist/request-model-override.js.map +1 -1
  169. package/dist/runtime-option-extensions.d.ts +2 -4
  170. package/dist/runtime-option-extensions.d.ts.map +1 -1
  171. package/dist/runtime-option-extensions.js +4 -8
  172. package/dist/runtime-option-extensions.js.map +1 -1
  173. package/dist/runtime-routes.d.ts +5 -5
  174. package/dist/runtime-routes.d.ts.map +1 -1
  175. package/dist/runtime-routes.js +29 -18
  176. package/dist/runtime-routes.js.map +1 -1
  177. package/dist/sandbox-settings-cleanup.d.ts +15 -0
  178. package/dist/sandbox-settings-cleanup.d.ts.map +1 -0
  179. package/dist/sandbox-settings-cleanup.js +88 -0
  180. package/dist/sandbox-settings-cleanup.js.map +1 -0
  181. package/dist/trigger-overrides.d.ts +6 -0
  182. package/dist/trigger-overrides.d.ts.map +1 -1
  183. package/dist/trigger-overrides.js +36 -4
  184. package/dist/trigger-overrides.js.map +1 -1
  185. package/dist/untrusted-text.d.ts +36 -0
  186. package/dist/untrusted-text.d.ts.map +1 -0
  187. package/dist/untrusted-text.js +150 -0
  188. package/dist/untrusted-text.js.map +1 -0
  189. package/dist/wizard/answers.d.ts +3 -9
  190. package/dist/wizard/answers.d.ts.map +1 -1
  191. package/dist/wizard/answers.js +11 -36
  192. package/dist/wizard/answers.js.map +1 -1
  193. package/dist/wizard/from-flags.d.ts +1 -2
  194. package/dist/wizard/from-flags.d.ts.map +1 -1
  195. package/dist/wizard/from-flags.js +8 -3
  196. package/dist/wizard/from-flags.js.map +1 -1
  197. package/dist/wizard/model-discovery.d.ts +7 -8
  198. package/dist/wizard/model-discovery.d.ts.map +1 -1
  199. package/dist/wizard/model-discovery.js +58 -431
  200. package/dist/wizard/model-discovery.js.map +1 -1
  201. package/dist/wizard/presets.js +2 -2
  202. package/dist/wizard/presets.js.map +1 -1
  203. package/dist/wizard/prompts.d.ts +13 -12
  204. package/dist/wizard/prompts.d.ts.map +1 -1
  205. package/dist/wizard/prompts.js +24 -45
  206. package/dist/wizard/prompts.js.map +1 -1
  207. package/dist/wizard/run.d.ts.map +1 -1
  208. package/dist/wizard/run.js +29 -152
  209. package/dist/wizard/run.js.map +1 -1
  210. package/package.json +17 -17
  211. package/schema/mono-agent.config.schema.json +197 -47
  212. package/skills/mono-agent-composer/SKILL.md +2 -2
  213. package/skills/mono-agent-composer/references/config-blueprint.md +45 -40
  214. package/skills/mono-agent-composer/references/discovery-questions.md +8 -13
  215. package/skills/mono-agent-composer/references/feature-coverage.md +11 -9
  216. package/skills/mono-agent-composer/references/package-map.md +22 -16
  217. package/skills/mono-agent-composer/references/playbooks.md +22 -26
  218. package/skills/mono-agent-composer/references/validation.md +1 -4
  219. package/dist/codex-model-catalog.d.ts +0 -15
  220. package/dist/codex-model-catalog.d.ts.map +0 -1
  221. package/dist/codex-model-catalog.js +0 -220
  222. package/dist/codex-model-catalog.js.map +0 -1
@@ -6,16 +6,16 @@ Every framework capability and how a composed agent reaches it. This table is th
6
6
 
7
7
  | Capability | Coverage | Where | Registry config ids |
8
8
  | --- | --- | --- | --- |
9
- | Model backends: claude (sdk/cli), codex (cli direct fallback), pi sdk providers (OpenAI, OpenAI-Codex preferred when Pi auth exists, Copilot, OpenRouter, OpenCode-through-Pi, Ollama, LM Studio, ...), plus hand-authored opencode runtime refs (cli, `opencode:<provider>:<model>` via the OpenCode server) | config | `runtime.model` | `runtime.multi-backend` |
9
+ | Model backends: Pi-only `<provider>:<model>` (OpenAI, OpenAI-Codex, Copilot, Anthropic, OpenRouter, OpenCode-through-Pi, Ollama, LM Studio, ...); a legacy `pi:` prefix is canonicalized away | config | `runtime.model` | `runtime.multi-backend` |
10
10
  | Subagent delegation via the Agent tool | config | pi runtime only. Requires BOTH `subagents.enabled: true` and `Agent` in `tools.allowedTools`. Each definition needs exactly one of `prompt` or `promptPath`; omitted `allowedTools` means a read-only default set and `"*"` is rejected. Subagents are capped by `maxConcurrent` (5) and `maxPerTurn` (20), never receive Agent/AskUser/channel-send tools, and cannot spawn subagents | `runtime.subagents` |
11
11
  | Same-model retries before failover | config | `runtime.retry.primaryAttempts` (default 2) gives the primary a second attempt before the chain advances; per-route `runtime.fallbacks[].attempts` opts a backup in. Only transient provider failures retry — context overflow and bad credentials still advance. Set `primaryAttempts` to 1 to disable | `runtime.retry` |
12
- | Backup models on retryable provider failure | config | New configs use `runtime.fallbacks[]` with optional per-route effort. Legacy `runtime.fallbackModels` / `MONO_AGENT_FALLBACK_MODELS` remain compatibility inputs with no removal deadline; do not emit them for new agents | `runtime.fallback-models` |
13
- | Route-safety contract for primary and fallback models | config | `runtime.routeSafety`: `uniform` (default) or `per-route-native` | `runtime.route-safety` |
14
- | Execution mode (sdk/cli), effort, max turns, workspace | config + cli | `runtime.executionMode`, `runtime.effort` (`none` / `minimal` / `low` / `medium` / `high` / `xhigh` / `max` / `ultra`; `mono-agent init --effort <level>`). Reasoning-capable `pi:*` maps `ultra` to LOW; Pi without reasoning uses OFF. Direct `codex:*` forwards `ultra` unchanged. Mono-agent rejects `ultra` on its Claude SDK route because the pinned SDK public contract ends at `max` (the SDK JavaScript itself forwards the value). The Claude CLI route passes `--effort ultra`, but both tested Claude Code binaries (SDK-bundled 2.1.206 and local 2.1.210) warn that it is unknown, ignore it, and use default effort. Direct OpenCode rejects explicit effort. Ranking above `max` only prevents keyword downgrade. `runtime.maxTurns`, `runtime.workspace` | `runtime.execution-modes`, `runtime.effort`, `runtime.max-turns`, `runtime.workspace` |
15
- | Tool-permission posture for CLI backends (direct OpenCode asks/rejects unanswered by default; configure explicitly) | config | `runtime.permissionMode` | `runtime.permission-mode` |
12
+ | Backup models on retryable provider failure | config | `runtime.fallbacks[]`, each route owning optional exact effort (omission = provider default) | `runtime.fallback-models` |
13
+ | Effort, max turns, workspace | config + cli | `runtime.effort` (`none` / `minimal` / `low` / `medium` / `high` / `xhigh` / `max` / `ultra`; `mono-agent init --effort <level>`). Reasoning-capable models map `ultra` to LOW; models without reasoning use OFF. `max` degrades to `xhigh` unless the resolved model advertises it. `mono-agent doctor` validates effort against the model's advertised levels and warns, naming the nearest supported level, when a configured value is outside that set. Ranking above `max` only prevents keyword downgrade. `runtime.maxTurns`, `runtime.workspace` | `runtime.effort`, `runtime.max-turns`, `runtime.workspace` |
14
+ | Tool-permission posture | config | `runtime.permissionMode` (validated and forwarded, not consumed by the Pi runtime) | `runtime.permission-mode` |
16
15
  | Continuous provider sessions with idle eviction and optional daily rollover | config | `runtime.session.{mode,idleTimeoutMs,rollover,rolloverTimezone,rolloverNotice}` | `runtime.provider-sessions` |
17
16
  | Per-channel run admission/execution bounds | config | `concurrency.maxConcurrentRuns`, `concurrency.maxPendingRuns` | `runtime.concurrency` |
18
- | Local providers (Ollama / LM Studio / OpenAI-compatible) | config | `providers.local[]` | `runtime.local-providers` |
17
+ | Local providers (Ollama / LM Studio / OpenAI-compatible) | config | `providers.<id>.{type,baseUrl,enabled,trustPublicUrl,apiKeyEnv,models,maxAdvertisedModels}`; the legacy `providers.local[]` array is still accepted and migrated on load | `runtime.local-providers` |
18
+ | Provider catalog (declares supported providers, widening model selection to each provider's full catalog) | config | the `providers` map, keyed by provider id — `providers.piAuthPath`, `providers.piNative`, and `providers.local` are reserved keys, never provider ids, and `providers.entries` is the resolved in-memory shape, not a JSON key. `ollama` and `lmstudio` are zero-config autodiscovered via localhost; a route naming any other provider that is not a Pi builtin fails config load until the map declares it with a `baseUrl` | `runtime.providers` |
19
19
  | Pi OAuth credentials | config | `providers.piAuthPath` | `runtime.pi-credentials` |
20
20
  | Pi-native transport, retry, and durable provider-session tuning | config | `providers.piNative.{transport,piMaxRetries,maxRetryDelayMs,piSessionsRoot}` | `runtime.pi-native-tuning` |
21
21
  | Tool-output bloat guard, cost tracking | auto | built into every run | — |
@@ -38,7 +38,7 @@ Every framework capability and how a composed agent reaches it. This table is th
38
38
  | Lite memory (FTS keyword recall + rapid-log capture; no external deps) | config | `memory.mode: "lite"`, `path`, `maxBytes`, `writeMode` | `memory.lite` |
39
39
  | Semantic embedding provider selection for Journal/BuJo | config + cli | `memory.embeddings.{provider,endpoint,model,dim,apiKeyEnv}`; guided init supports exclusive Ollama or LM Studio discovery and proof | `memory.embeddings-config` |
40
40
  | Journal memory (hybrid recall BM25+vector + static canonical salience; needs configured embeddings) | config | `memory.mode: "journal"`, `path`, `memory.embeddings.{provider,endpoint,model,dim,apiKeyEnv}` (`provider: "ollama" \| "lmstudio" \| "openai"`; exclusive, no cross-provider fallback) | `memory.journal` |
41
- | BuJo memory (journal + LLM capture/reconcile ADD/UPDATE/SUPERSEDE/NOOP + entity graph + auto-scheduled consolidation; needs embeddings + an app-level `memory.llm`) | config | `memory.mode: "bujo"`, `path`; selected Ollama/LM Studio/OpenAI embeddings are independent from explicit `memory.llm` with `provider: "ollama"` (`model`, optional `endpoint`) or `provider: "agent-host"` (`model` is an SDK runtime model ref, optional `executionMode: "sdk"`) — see `docs/memory/index.md` | `memory.bujo` |
41
+ | BuJo memory (journal + LLM capture/reconcile ADD/UPDATE/SUPERSEDE/NOOP + entity graph + auto-scheduled consolidation; needs embeddings + an app-level `memory.llm`) | config | `memory.mode: "bujo"`, `path`; selected Ollama/LM Studio/OpenAI embeddings are independent from explicit `memory.llm` with `provider: "ollama"` (`model`, optional `endpoint`) or `provider: "agent-host"` (`model` is a runtime model ref) — see `docs/memory/index.md` | `memory.bujo` |
42
42
  | Supermemory external backend (server-side extraction/consolidation; async ingestion; explicitly installed plugin) | config | `memory.backend: "supermemory"`, `memory.writeMode`, `memory.supermemory.{baseUrl,apiKey,apiKeyEnv,container,timeoutMs,exposeMcpServer}`; install the exact matching `@mono-agent/memory-supermemory` version | `memory.backend-supermemory` |
43
43
  | BuJo consolidation auto-scheduler (projection-only `index.md` refresh + empty `future-log.md` stub + duplicate-group reporting; in-app, no external cron needed) | config | `memory.consolidation.{enabled,cron}` (five-field UTC, default `0 */2 * * *`, no hashed `H`); env `MONO_AGENT_MEMORY_CONSOLIDATION_CRON`, `MONO_AGENT_MEMORY_CONSOLIDATION_ENABLED` | `memory.bujo-consolidation` |
44
44
  | Memory maintenance CLI | cli | `mono-agent memory <subcommand>` from the agent folder (stats/today/show/search/top/audit/inspect/rebuild/rollback/…). The standalone `memory-bujo <subcommand> <root>` CLI and bin were removed; routine BuJo consolidation runs via the in-app scheduler | — |
@@ -46,6 +46,7 @@ Every framework capability and how a composed agent reaches it. This table is th
46
46
  | Memory liveness check (managed tier/provider/model/dimension identity; provider-native typed discovery plus real finite-vector/dimension probe for Ollama or LM Studio; declared auth env; BuJo LLM config + consolidation cadence; no cross-provider fallback) | cli | `mono-agent validate` | — |
47
47
  | Memory write modes and per-turn BuJo capture | config | `memory.writeMode`: `disabled`, `append-host-summary`, or `capture`; capture requires `memory.mode: "bujo"` | `memory.write-mode`, `memory.per-turn-capture` |
48
48
  | Auto-provisioned read-only `MemoryRecall` tool exposed for every configured memory tier; no chat LLM | config | `config.memory.recallTool.enabled` (`MONO_AGENT_MEMORY_RECALL_TOOL_ENABLED`, default on; explicit false opts out) | `memory.recall-tool` |
49
+ | Agent-callable `Remember` tool that durably stores one explicitly stated fact; deterministic, append-only, no chat LLM; bujo backend and writable stores only; allowlist-gated and rejects credential-bearing text | config | `config.memory.rememberTool.enabled` (`MONO_AGENT_MEMORY_REMEMBER_TOOL_ENABLED`, default on for the bujo backend; explicit false opts out); a restrictive `tools.allowedTools` must name `Remember` | `memory.remember-tool` |
49
50
  | In-app memory LLM call timeout | config | `memory.llm.timeoutMs` (`MONO_AGENT_MEMORY_LLM_TIMEOUT_MS`, default 60000) | `memory.llm-timeout` |
50
51
 
51
52
  ## Tools, MCP, sandbox
@@ -55,13 +56,14 @@ Every framework capability and how a composed agent reaches it. This table is th
55
56
  | Allow-all tool policy (omitted / `["*"]` = all tools; `[]` = none) | config | default `tools.allowedTools`; the harness no-policy safety net is `failClosedToolPolicy()` | `tool-policy.allow-all` |
56
57
  | Built-in tool allow/deny lists (deny wins, even under allow-all; pi doesn't deny external MCP tools) | config | `tools.allowedTools`, `tools.disallowedTools`; managed built-ins are Read/Write/Edit/Glob/Grep/Exec/Bash/NodeRepl/WebFetch/WebSearch | `tool-policy.allowlist`, `tool-policy.denylist`, `runtime.builtin-tools` |
57
58
  | Pi-native Exec/Bash background process jobs with exact-thread wake | config + cli + auto | `processJobs.*` opts in (default off; unsupported on Windows). Only controller-ready exact Slack, Telegram, and web-console turns gain optional `background`; foreground schemas/behavior stay unchanged otherwise. Host-owned queue/runtime/output/depth/retention caps, owner-private records, inherited POSIX process groups, restart interruption, unforgeable-depth normal-tool wakes, Slack/Telegram same-message lifecycle updates, fail-closed live store health, `mono-agent jobs list\|get\|cancel`, and durable web cards are built in. Busy pre-turn wake admission remains pending without consuming its retry budget. JSON-only `unsafeAllowUnprotectedState` is an explicit sandbox-off/all-Pi trusted-host posture: it suppresses ProcessJobs and clear-sessions SRT while retaining registry, lease, private-root, and provider-zero route invariants, and warns that ProcessJobs state plus the operator secret are model-accessible. Commands that daemonize into another group or session are unsupported | `agent-app.process-jobs` |
59
+ | Pi-native `Monitor`/`MonitorStop` streaming watches with per-batch conversation wakes | config + cli | `monitors.*` opts in (default off; additionally requires `processJobs.enabled`, whose protected private-state root, registration proof and origin binding it reuses; unsupported on Windows). A monitor keeps a command alive after the turn returns, treats each stdout line as one event, coalesces within `coalesceMs`, and wakes the exact originating conversation per batch plus once at the end, steering an in-flight run or queuing its own turn and holding no provider slot. Command preparation, workdir rules, environment cleaning, sandbox seam and output redaction are shared with `Bash`, so there is no separate command allowlist. Capacity is counted independently of `processJobs.*`; one wake per monitor is in flight at a time, pending batches are bounded in lines and bytes with oldest-drop accounting reported to the model, and a sustained firehose stops the watch with `rate_limited` plus one terminal wake. A pre-dispatch refusal is re-offered with the same batch and sequence; every other delivery failure is never replayed. Restart marks live monitors `interrupted`, terminates the incarnation-matched group, and owes exactly one recovery wake without re-running a model-authored command. The fenced envelope declares the turn host-raised and its content untrusted, and a `NOTHING_TO_REPORT` reply is suppressed. Availability is Telegram and Slack only — cron, webhook, TUI-direct and the web console never receive the tools. `mono-agent monitors list\|get\|cancel` is the operator surface | `agent-app.monitors` |
58
60
  | Local-first public-web research | config + auto | `tools.web.search.{backend,endpoint,codex.model}` selects strict/first-choice loopback SearXNG, structured ChatGPT-subscription Codex search, or public no-credentials fallbacks; `auto` uses that order and rejects irrelevant/domain-mismatched results before stopping. `tools.web.fetch.{render,browserCommand}` keeps static extraction as the default and optionally enables isolated agent-browser rendering; transient-fetch retry behavior is automatic rather than config-bearing | `runtime.web-research` |
59
61
  | MCP servers (stdio/sse/http) from a JSON file | config | `tools.mcpConfigPath` | `tool-policy.mcp-servers` |
60
62
  | Generated reply files and Pi-native MCP Apps | config + auto | `PublishReplyFile` is included under allow-all or must be named in a restrictive `tools.allowedTools`; it publishes confined files through owner-private integrity storage for native Slack/Telegram upload and web download. MCP Apps appear only when every configured runtime route supports the Pi-owned bridge, and render only in the hardened web console. Files and Apps share a 20-part run cap; retention follows `artifacts.retention.maxAgeDays` | `agent-app.rich-replies` |
61
63
  | Durable origin-bound continuations for trusted stdio/loopback-HTTP MCP services | config + auto | `tools.continuationServers` + `continuations.*`; interactive claims pin a bounded immutable origin snapshot before commit, exact rollover buckets are preserved, v3 state is restart-safe, and unavailable/legacy snapshots use a fixed zero-model fallback | `agent-app.durable-continuations` |
62
64
  | Adapter-derived send tools for enabled Slack/Telegram adapters | config | auto-available under allow-all once the channel is enabled; a **specific** `tools.allowedTools` must include `SlackSendMessage` / `TelegramSendMessage`; valid `slack.*` / `telegram.*` config and existing adapter allowlists provide credentials and destination bounds; confirmed message posts are idempotently recorded in destination history | `agent-app.adapter-send-tools` |
63
65
  | Interaction bridge for adapter-send history, structured blocking asks, and MCP progress | config + auto | `interaction.bridge.{host,port}`, `interaction.askUser.timeoutMs`, `interaction.progress.enabled`; env `MONO_AGENT_INTERACTION_BRIDGE_HOST`, `MONO_AGENT_INTERACTION_BRIDGE_PORT`, `MONO_AGENT_ASK_USER_TIMEOUT_MS`, `MONO_AGENT_PROGRESS_ENABLED`. It auto-starts for configured Slack/Telegram send tools, when `AskUser` is allowed, when an `interaction` block or interaction env override is configured, or when `interaction.progress.enabled` resolves true and `tools.mcpRequestContextServers` names at least one opted project stdio MCP server. AskUser presents all questions together on web and sequential native controls on Slack/Telegram. | `interaction.bridge` |
64
- | Sandbox on/off + srt engine (Pi-owned tools; direct Codex has its own sandbox, Claude/direct OpenCode reject native mono policy) | config | `sandbox.mode` | `sandbox.mode` |
66
+ | Sandbox on/off + srt engine (Pi-owned tools) | config | `sandbox.mode` | `sandbox.mode` |
65
67
  | Network policy (none/localhost/allowlist/all) | config | `sandbox.network.{mode,allowlist}` | `sandbox.network-policy` |
66
68
  | Filesystem scopes (readable/writable roots, deny-write globs) | config | `sandbox.readableRoots`, `sandbox.writableRoots`, `sandbox.denyWrite` | `sandbox.filesystem-scopes` |
67
69
  | Fallback behavior when srt is unavailable | config | `sandbox.fallback`, `sandbox.unsafeAllowHostProcess` | `sandbox.fallback` |
@@ -76,7 +78,7 @@ Every framework capability and how a composed agent reaches it. This table is th
76
78
  | Telegram long polling, chat allowlist, and group trigger boundary | config | `telegram` section; `telegram.groupMode` (`any` or `mention`) and `telegram.stripMentionText` | `telegram.long-polling` |
77
79
  | Telegram runtime/command/reaction/button/file interactivity | config + code | built-in per-chat `/model` and `/effort` use configured primary/fallback models (no Telegram config key); `telegram.commands[]`, `telegram.reactions`, `telegram.quietHours`; `AskUser`, non-blocking `TelegramSendMessage.reply_options`, and `TelegramSendFile` | `telegram.interactive` |
78
80
  | Telegram inbound audio transcription | config | `telegram.transcription.{endpoint,model,language,timeoutMs}`; opt-in OpenAI-compatible transcription endpoint for voice notes, audio files, and round-video attachments | `telegram.transcription` |
79
- | Slack (Socket Mode, channel allowlist, mention handling, native runtime controls) | config + code | `slack` section; built-in Block Kit controls use configured primary/fallback choices through DM-wide/thread-local `@agent /model` and `@agent /effort`, plus channel-wide workspace commands `/<bot>-model` and `/<bot>-effort` derived from `auth.test.user` (Slack app registration + `commands` scope; no mono-agent config key) | `slack.socket-mode` |
81
+ | Slack (Socket Mode, channel allowlist, mention handling, native runtime controls) | config + code | `slack` section; optional `slack.unfurlLinks` / `slack.unfurlMedia` control native agent message previews while omission preserves Slack defaults; built-in Block Kit controls use configured primary/fallback choices through DM-wide/thread-local `@agent /model` and `@agent /effort`, plus channel-wide workspace commands `/<bot>-model` and `/<bot>-effort` derived from `auth.test.user` (Slack app registration + `commands` scope; no mono-agent config key) | `slack.socket-mode` |
80
82
  | Slack speaker names (who sent each turn) | config | `slack.resolveUserNames` (default `true`) resolves the sender's display name and handle via `users.info`; requires the `users:read` bot scope; best-effort, so a missing scope leaves turns unnamed instead of failing them; the resolved name is durable (stored turn + memory label) | `slack.speaker-names` |
81
83
  | Surface awareness (which channel/DM the turn is in) | config | Always on for Slack and Telegram: the Session block states the surface kind, its id, and the per-message character budget. `slack.resolveChannelNames` (default `true`) adds the Slack channel NAME via `conversations.info` and requires `channels:read`/`groups:read`; best-effort, so a missing scope leaves the surface named by kind and id. Surface ids are model-visible by design — pair with an explicit `slack.allowedChannelIds` allowlist if `SlackSendMessage` is enabled | `channels.surface-awareness` |
82
84
  | Slack thread/channel turn context (what was said before the agent was triggered) | config | `slack.threadContext.{enabled,maxMessages,requestLimit,timeoutMs,includeBotMessages}`, defaults `true`/`15`/`15`/`4000`/`true`; reads `conversations.replies` in a thread and `conversations.history` otherwise; requires `channels:history` / `groups:history` / `im:history` / `mpim:history`; one request per turn with a per-channel rate-limit breaker; best-effort, so a missing scope or rate limit sends no transcript instead of failing the turn | `slack.thread-context` |
@@ -22,7 +22,7 @@ Every real host needs these concepts:
22
22
  | --- | --- | --- | --- |
23
23
  | Shared request/response shape | `@mono-agent/agent-contracts` | `AgentResponder`, request, response, stream, cancellation contracts | Prompt building, runtime execution, transport |
24
24
  | Core config | `@mono-agent/config` | Runtime, context, memory, tools, artifact, traceability settings | Adapter credentials, chat allowlists |
25
- | Runtime facade | `@mono-agent/runtime-adapter` | Model refs, execution-mode validation, local provider runtime options | Prompts, adapters, memory |
25
+ | Runtime facade | `@mono-agent/runtime-adapter` | Canonical `<provider>:<model>` refs, the Pi backend descriptor, sandbox policy, local provider runtime options | Prompts, adapters, memory |
26
26
  | Configured responder | `@mono-agent/agent-app` | Turns `MonoAgentConfig` into runtime, memory, harness, and responder | Polling chats, serving APIs, adapter settings |
27
27
 
28
28
  Minimal local host:
@@ -87,18 +87,19 @@ request-scoped tools, not entries for `mcp.json`. `SessionHistory` searches the
87
87
  current logical session's retained managed-tool calls/results and needs no config
88
88
  key. `SetConversationTitle` appears only for writable interactive web threads;
89
89
  it keeps automatic semantic titles current, while a user rename permanently
90
- wins. Allow-all exposes eligible tools on compatible routes; a specific
91
- allowlist must name each one. Direct OpenCode suppresses all three; direct ACP
92
- retains and cold-projects lifecycle evidence but cannot expose `SessionHistory`.
90
+ wins. Allow-all exposes eligible tools; a specific allowlist must name each one.
91
+ Every route is Pi-native, so no route family suppresses any of the three; the
92
+ surface conditions above (writable interactive web thread, retained managed-tool
93
+ calls) are the only gates.
93
94
  `@mono-agent/agent-app` also owns rich reply composition. `PublishReplyFile`
94
95
  copies a confined generated file into owner-private integrity storage and is
95
96
  available under allow-all (or by exact name in a restrictive policy). Supported
96
97
  Pi-native MCP tool results can register their declared MCP App UI resource for
97
- the web console. An all-Pi route chain is required for Apps; direct or fallback
98
- routes that cannot carry the bridge do not advertise it. Adapters consume the
99
- shared reply-part contract: Slack and Telegram confirm native uploads, the web
100
- serves authorized downloads and sandboxed Apps, and machine/verbatim adapters
101
- preserve answer text when they cannot represent a part.
98
+ the web console, and because every route is Pi-native the whole fallback chain
99
+ carries that bridge. Adapters consume the shared reply-part contract: Slack and
100
+ Telegram confirm native uploads, the web serves authorized downloads and
101
+ sandboxed Apps, and machine/verbatim adapters preserve answer text when they
102
+ cannot represent a part.
102
103
 
103
104
  ```ts
104
105
  import { createToolPolicy, toolPolicyToRuntimeOptions } from "@mono-agent/agent-harness";
@@ -129,7 +130,7 @@ Communication adapters are edge packages. They accept an `AgentResponder` and ow
129
130
  | Webhook | `@mono-agent/webhook-adapter` | `curl` the configured invocation path (with `Authorization: Bearer ...` when `apiKey` is set) |
130
131
  | Cron | `@mono-agent/cron-adapter` | One scheduled or manually triggered invocation |
131
132
 
132
- Adapters must not import the harness, runtime adapter, memory package (`@mono-agent/memory` subpaths), or other adapters. `@mono-agent/agent-app` composes them from config; custom hosts and demos may compose them directly.
133
+ Adapters must not import the harness, runtime adapter, memory package (`@mono-agent/memory` subpaths), or other adapters. `@mono-agent/agent-app` composes them from config; custom app hosts may compose them directly.
133
134
 
134
135
  ## Observability Join
135
136
 
@@ -150,11 +151,16 @@ Use `@mono-agent/agent-orchestrator` when one runtime should call named collabor
150
151
 
151
152
  Use `@mono-agent/runtime-adapter` unless the host has a custom runtime implementation that already satisfies `MonoRuntimeLike`.
152
153
 
153
- Supported model reference families:
154
-
155
- - `codex:<model>` with CLI execution
156
- - `claude:<model>` with SDK or CLI execution
157
- - `pi:<provider>:<model>` with SDK execution, including Pi OpenAI-Codex, OpenCode-through-Pi (`pi:opencode-go:*`), and local providers such as Ollama and LM Studio
158
- - `opencode:<provider>:<model>` with CLI execution for hand-authored OpenCode backend config
154
+ There is one supported model reference family: canonical `<provider>:<model>`,
155
+ run Pi-native. Only the first colon is structural, so `ollama:gemma4:31b` is
156
+ provider `ollama` and model `gemma4:31b`. `<provider>` is a Pi provider id —
157
+ `openai-codex`, `anthropic`, `openai`, `github-copilot`, `openrouter`,
158
+ `opencode-go`, or a local/self-hosted id such as `ollama` or `lmstudio`.
159
+
160
+ A leading `pi:` is canonicalized away, so `pi:ollama:gemma4:31b` still loads —
161
+ but emit the canonical form. `codex:`, `claude:`, `claude-code:`, `codex-cli:`,
162
+ `acp:`, `vercel:` and the nested `opencode:<provider>:<model>` form were
163
+ retired in 0.21.0 and are rejected at load with the replacement named. Tier
164
+ aliases (`haiku`, `sonnet`, `opus`) are not model ids; use an exact model id.
159
165
 
160
166
  Provider credentials belong in the provider/runtime environment, not in committed config.
@@ -20,7 +20,7 @@ Put `MONO_AGENT_TELEGRAM_BOT_TOKEN=...` in `.env`; the source config omits the c
20
20
 
21
21
  ```json
22
22
  {
23
- "runtime": { "model": "pi:openai-codex:gpt-5.6-terra" },
23
+ "runtime": { "model": "openai-codex:gpt-5.6-terra" },
24
24
  "telegram": { "enabled": true, "allowedChatIds": ["123456789"] },
25
25
  "memory": {
26
26
  "mode": "bujo", "path": "./.mono-agent/memory", "writeMode": "capture",
@@ -30,7 +30,7 @@ Put `MONO_AGENT_TELEGRAM_BOT_TOKEN=...` in `.env`; the source config omits the c
30
30
  }
31
31
  }
32
32
  ```
33
- **Steps:** `ollama pull nomic-embed-text:v1.5 && ollama pull qwen3.6:latest` → `mono-agent init --model claude:claude-sonnet-4-6 --memory bujo` → add telegram + fill embeddings/llm + `writeMode: capture` → `mono-agent validate` (confirm memory liveness + consolidation cadence) → `mono-agent start`.
33
+ **Steps:** `ollama pull nomic-embed-text:v1.5 && ollama pull qwen3.6:latest` → `mono-agent init --model anthropic:claude-sonnet-4-6 --memory bujo` → add telegram + fill embeddings/llm + `writeMode: capture` → `mono-agent validate` (confirm memory liveness + consolidation cadence) → `mono-agent start`.
34
34
  **Smoke:** send a fact from the allowed chat, then ask a paraphrased question later; confirm the final answer arrives separately and the temporary memory-tool activity disappears, `MemoryRecall` appears in the run JSONL, and the answer uses it.
35
35
 
36
36
  ## 2. Slack team bot with MCP tools
@@ -42,7 +42,7 @@ Put `MONO_AGENT_SLACK_BOT_TOKEN` and `MONO_AGENT_SLACK_APP_TOKEN` in `.env`; the
42
42
 
43
43
  ```json
44
44
  {
45
- "runtime": { "model": "pi:openai-codex:gpt-5.6-terra" },
45
+ "runtime": { "model": "openai-codex:gpt-5.6-terra" },
46
46
  "slack": { "enabled": true, "allowedChannelIds": ["C012345"], "stripMentionText": true },
47
47
  "tools": { "allowedTools": ["Read", "Grep", "SlackSendMessage", "deployTool"], "mcpConfigPath": "./mcp.json" },
48
48
  "concurrency": { "maxConcurrentRuns": 4, "maxPendingRuns": 8 }
@@ -58,13 +58,13 @@ Put `MONO_AGENT_SLACK_BOT_TOKEN` and `MONO_AGENT_SLACK_APP_TOKEN` in `.env`; the
58
58
 
59
59
  ```json
60
60
  {
61
- "runtime": { "model": "pi:ollama:gemma4:31b" },
61
+ "runtime": { "model": "ollama:gemma4:31b" },
62
62
  "providers": { "local": [{ "id": "ollama", "type": "ollama", "baseUrl": "http://localhost:11434", "enabled": true, "models": [{ "name": "gemma4:31b", "capabilities": { "context_window": 32768 } }] }] },
63
63
  "memory": { "mode": "journal", "path": "./.mono-agent/memory", "embeddings": { "provider": "ollama", "model": "nomic-embed-text:v1.5", "endpoint": "http://localhost:11434", "dim": 768 } },
64
64
  "sandbox": { "mode": "native", "network": { "mode": "localhost" } }
65
65
  }
66
66
  ```
67
- **Steps:** pull both models → `mono-agent init --model pi:ollama:gemma4:31b --memory journal` → add `providers.local` + embeddings + `sandbox.network.mode: localhost` → `validate` (Ollama reachable, models pulled) → `start`.
67
+ **Steps:** pull both models → `mono-agent init --model ollama:gemma4:31b --memory journal` → add `providers.local` + embeddings + `sandbox.network.mode: localhost` → `validate` (Ollama reachable, models pulled) → `start`.
68
68
  **Smoke:** `curl -X POST` the webhook path; confirm a local-model response and no outbound non-localhost network in the artifact.
69
69
 
70
70
  ## 4. OpenAI-compatible endpoint for Open WebUI
@@ -74,7 +74,7 @@ Put `MONO_AGENT_SLACK_BOT_TOKEN` and `MONO_AGENT_SLACK_APP_TOKEN` in `.env`; the
74
74
 
75
75
  ```json
76
76
  {
77
- "runtime": { "model": "claude:claude-sonnet-4-6", "session": { "mode": "continuous", "idleTimeoutMs": 1800000 } },
77
+ "runtime": { "model": "anthropic:claude-sonnet-4-6", "session": { "mode": "continuous", "idleTimeoutMs": 1800000 } },
78
78
  "openaiApi": { "enabled": true, "host": "0.0.0.0", "port": 4040, "basePath": "/v1", "allowNonLoopback": true, "modelId": "my-agent" }
79
79
  }
80
80
  ```
@@ -88,7 +88,7 @@ Put `MONO_AGENT_SLACK_BOT_TOKEN` and `MONO_AGENT_SLACK_APP_TOKEN` in `.env`; the
88
88
 
89
89
  ```json
90
90
  {
91
- "runtime": { "model": "claude:claude-sonnet-4-6" },
91
+ "runtime": { "model": "anthropic:claude-sonnet-4-6" },
92
92
  "webhook": {
93
93
  "enabled": true, "host": "127.0.0.1", "port": 8080, "defaultMode": "sync",
94
94
  "endpoints": [
@@ -113,13 +113,13 @@ Put `MONO_AGENT_SLACK_BOT_TOKEN` and `MONO_AGENT_SLACK_APP_TOKEN` in `.env`; the
113
113
 
114
114
  ```json
115
115
  {
116
- "runtime": { "model": "claude:claude-sonnet-4-6" },
117
- "slack": { "enabled": true, "allowedChannelIds": ["C012345"] },
116
+ "runtime": { "model": "anthropic:claude-sonnet-4-6" },
117
+ "slack": { "enabled": true, "allowedChannelIds": ["C012345"], "unfurlLinks": false, "unfurlMedia": false },
118
118
  "cron": { "jobs": [{ "id": "morning-digest", "enabled": true, "expression": "0 9 * * *", "timezone": "America/New_York", "prompt": "Build the morning digest. Your final answer is the digest to notify.", "conversationId": "daily-digest", "notify": true, "notifyConversationId": "slack:C012345" }] }
119
119
  }
120
120
  ```
121
121
  **Steps:** `mono-agent init` → add the destination adapter and allowlist → add the cron job (or `cron/morning-digest.md`) with `conversationId`, IANA timezone, `notify: true`, and optional `notifyConversationId` → `validate` → `start`.
122
- **Smoke:** trigger a one-off tick; confirm the final answer lands verbatim in the allowed destination with no tool call and `conversationId` shares context across ticks. Return `NOTHING_TO_REPORT` to test the silent path.
122
+ **Smoke:** trigger a one-off tick; confirm the final answer lands verbatim in the allowed destination with no tool call, no Slack link/media preview under the example config, and `conversationId` shares context across ticks. Return `NOTHING_TO_REPORT` to test the silent path.
123
123
 
124
124
  ## 7. A2A provider + consumer pair
125
125
  **For:** a platform integrator connecting two agents over A2A.
@@ -180,13 +180,13 @@ const orchestrator = await createConfiguredAgentResponder({
180
180
 
181
181
  ```json
182
182
  {
183
- "runtime": { "model": "pi:openai-codex:gpt-5.6-terra" },
183
+ "runtime": { "model": "openai-codex:gpt-5.6-terra" },
184
184
  "tools": { "allowedTools": ["*"] },
185
185
  "sandbox": { "mode": "native", "network": { "mode": "localhost" }, "readableRoots": ["."], "writableRoots": ["."], "denyWrite": [".env", ".env.*", ".git/config", ".git/hooks/**"], "fallback": "fail-closed" }
186
186
  }
187
187
  ```
188
188
  **Steps:** `mono-agent init --memory journal` → leave tools at the allow-all default (`["*"]`); the **sandbox**, not an allowlist, is what constrains the code tools → `sandbox.mode native` + `network localhost` + deny-write defaults → keep `fallback: fail-closed` (do NOT set `unsafe-host-process`) → `validate` → `start`.
189
- **Smoke:** ask it to read a file, use Exec for one argv-safe command, run one Bash pipeline, then use NodeRepl twice to retain a variable and produce `42` (all work); next fetch an external URL or write `.env` (both blocked in the artifact). Keep every primary/fallback/trigger model on Pi; direct Codex, Claude, and direct OpenCode reject this mono-agent sandbox policy.
189
+ **Smoke:** ask it to read a file, use Exec for one argv-safe command, run one Bash pipeline, then use NodeRepl twice to retain a variable and produce `42` (all work); next fetch an external URL or write `.env` (both blocked in the artifact). Every route is Pi-native, so this sandbox policy applies uniformly to the primary, every fallback, and every per-trigger override.
190
190
 
191
191
  ## 10. Phoenix-observed agent with the TUI
192
192
  **For:** an agent builder evaluating runs in a tracing dashboard.
@@ -195,7 +195,7 @@ const orchestrator = await createConfiguredAgentResponder({
195
195
 
196
196
  ```json
197
197
  {
198
- "runtime": { "model": "claude:claude-sonnet-4-6" },
198
+ "runtime": { "model": "anthropic:claude-sonnet-4-6" },
199
199
  "artifacts": { "dir": ".mono-agent/artifacts" },
200
200
  "traceability": { "registryDir": ".mono-agent/trace-sources", "sourceId": "my-agent", "heartbeatMs": 10000 },
201
201
  "observability": { "exporters": [{ "type": "phoenix", "endpoint": "http://127.0.0.1:6006/v1/traces", "projectName": "my-project", "includeSensitiveData": false, "contentPatternRedaction": false, "timeoutMs": 5000 }] }
@@ -223,16 +223,12 @@ const orchestrator = await createConfiguredAgentResponder({
223
223
 
224
224
  ```json
225
225
  {
226
- "runtime": { "model": "claude:claude-sonnet-4-6", "fallbacks": [{ "model": "pi:openai-codex:gpt-5.5" }, { "model": "pi:ollama:gemma4:31b" }], "session": { "mode": "continuous" } },
226
+ "runtime": { "model": "anthropic:claude-sonnet-4-6", "fallbacks": [{ "model": "openai-codex:gpt-5.6-sol" }, { "model": "ollama:gemma4:31b" }], "session": { "mode": "continuous" } },
227
227
  "providers": { "local": [{ "id": "ollama", "type": "ollama", "baseUrl": "http://localhost:11434", "enabled": true }], "piNative": { "transport": "auto", "piMaxRetries": 2, "maxRetryDelayMs": 60000, "piSessionsRoot": ".mono-agent/sessions" } }
228
228
  }
229
229
  ```
230
- Legacy `runtime.fallbackModels` and `MONO_AGENT_FALLBACK_MODELS` remain supported
231
- with no removal deadline, but this playbook intentionally emits the canonical
232
- per-route form for a new agent.
233
- **Steps:** `ollama pull gemma4:31b` → `mono-agent init --model claude:claude-sonnet-4-6 --fallback pi:openai-codex:gpt-5.5 --fallback pi:ollama:gemma4:31b` → add `providers.local` + `piNative.piSessionsRoot` → `validate` → `start`.
234
- **Boundary:** this mixed Pi/Claude chain intentionally omits the native mono-agent sandbox. Keep direct Codex chains all-direct; keep every route on Pi (including `pi:opencode-go:*`, not direct `opencode:*`) when `sandbox.mode` is `native`.
235
- **Smoke:** force a retryable primary failure; confirm the run result reports failover to the next model (not silent) and the conversation resumes from the transcript tail.
230
+ `runtime.fallbackModels` and `MONO_AGENT_FALLBACK_MODELS` were retired in 0.21.0
231
+ and are rejected at load; emit `runtime.fallbacks[]` only.
236
232
 
237
233
  ## 13. Personal Telegram assistant with Supermemory
238
234
  **For:** a power user trying an external memory layer while keeping the agent local.
@@ -241,7 +237,7 @@ per-route form for a new agent.
241
237
 
242
238
  ```json
243
239
  {
244
- "runtime": { "model": "claude:claude-sonnet-4-6" },
240
+ "runtime": { "model": "anthropic:claude-sonnet-4-6" },
245
241
  "telegram": { "enabled": true, "allowedChatIds": ["123456789"] },
246
242
  "memory": {
247
243
  "backend": "supermemory", "mode": "lite", "path": "./.mono-agent/memory",
@@ -261,13 +257,13 @@ per-route form for a new agent.
261
257
 
262
258
  ```json
263
259
  {
264
- "runtime": { "model": "pi:lmstudio:qwen3.6-32b" },
260
+ "runtime": { "model": "lmstudio:qwen3.6-32b" },
265
261
  "providers": { "local": [{ "id": "lmstudio", "type": "lmstudio", "baseUrl": "http://localhost:1234", "enabled": true }] },
266
262
  "memory": { "mode": "lite", "path": "./.mono-agent/memory", "writeMode": "append-host-summary" },
267
263
  "webhook": { "enabled": true }
268
264
  }
269
265
  ```
270
- **Steps:** start LM Studio's local server with the chosen model loaded → `mono-agent init --model pi:lmstudio:qwen3.6-32b --memory lite` (the `pi:lmstudio:*` model auto-adds the LM Studio provider block; there is no LM Studio preset — `local-private` is Ollama-based) → adjust `runtime.model` if the displayed model id differs → `validate` → `start`.
266
+ **Steps:** start LM Studio's local server with the chosen model loaded → `mono-agent init --model lmstudio:qwen3.6-32b --memory lite` (the `lmstudio:*` model auto-adds the LM Studio provider block; there is no LM Studio preset — `local-private` is Ollama-based) → adjust `runtime.model` if the displayed model id differs → `validate` → `start`.
271
267
  **Smoke:** `curl` the webhook invoke URL and confirm the response comes from the local LM Studio model.
272
268
 
273
269
  ## 15. Interactive agent with long jobs and large media
@@ -279,7 +275,7 @@ per-route form for a new agent.
279
275
 
280
276
  ```json
281
277
  {
282
- "runtime": { "model": "pi:openai-codex:gpt-5.5", "executionMode": "sdk" },
278
+ "runtime": { "model": "openai-codex:gpt-5.6-sol" },
283
279
  "tools": { "allowedTools": ["Read", "AskUser", "TelegramSendFile", "PublishReplyFile"], "mcpConfigPath": "./.mcp.json", "mcpCallMaxTotalTimeoutMs": 2700000 },
284
280
  "interaction": { "bridge": { "host": "127.0.0.1", "port": 4471 }, "askUser": { "timeoutMs": 600000 }, "progress": { "enabled": true } },
285
281
  "telegram": { "enabled": true, "allowedChatIds": ["123456789"], "apiRoot": "http://127.0.0.1:8081", "attachments": { "maxBytes": 268435456, "maxUploadBytes": 268435456 } }
@@ -295,7 +291,7 @@ per-route form for a new agent.
295
291
 
296
292
  ```json
297
293
  {
298
- "runtime": { "model": "pi:openai-codex:gpt-5.5" },
294
+ "runtime": { "model": "openai-codex:gpt-5.6-sol" },
299
295
  "tools": {
300
296
  "allowedTools": ["Read", "Glob", "Grep", "WebSearch", "WebFetch"],
301
297
  "web": {
@@ -307,6 +303,6 @@ per-route form for a new agent.
307
303
  }
308
304
  ```
309
305
 
310
- **Steps:** start the pinned loopback companion from `demos/searxng` → keep strict `searxng` or choose `auto` for ChatGPT-subscription Codex then keyless fallback → keep render `never`, or install `agent-browser >=0.33.1` and opt into `auto` for SPA pages → `validate` → `start`.
306
+ **Steps:** provision an operator-owned loopback SearXNG instance with JSON responses enabled → keep strict `searxng` or choose `auto` for ChatGPT-subscription Codex then keyless fallback → keep render `never`, or install `agent-browser >=0.33.1` and opt into `auto` for SPA pages → `validate` → `start`.
311
307
  **Boundary:** local SearXNG is private infrastructure, not an offline index; it contacts public engines and WebFetch contacts result sites. `localhost` permits the companion but blocks public fetches.
312
308
  **Smoke:** ask for two query variants and one official-page fetch; require canonical ranked URLs, untrusted-content boundaries, bounded timing metadata without query/URL leakage, and no duplicate network work for an identical call in the run.
@@ -101,14 +101,11 @@ pnpm --filter @mono-agent/<package> run build
101
101
  pnpm --filter @mono-agent/<package> run typecheck
102
102
  ```
103
103
 
104
- For broad host or demo changes, run the full workspace gate:
104
+ For broad host or repository changes, run the full workspace gate:
105
105
 
106
106
  ```bash
107
107
  pnpm run build
108
108
  pnpm test
109
- pnpm run build:demo
110
- pnpm run typecheck:demo
111
- pnpm run test:demo
112
109
  ```
113
110
 
114
111
  ## Smoke Tests By Surface
@@ -1,15 +0,0 @@
1
- import type { EffortLevel } from "@mono-agent/config";
2
- export interface CodexCatalogModel {
3
- readonly id: string;
4
- readonly displayName: string;
5
- readonly supportedEfforts: readonly EffortLevel[];
6
- readonly defaultEffort?: EffortLevel;
7
- readonly isDefault?: boolean;
8
- }
9
- /** Exact non-secret environment used by live Codex model/list discovery. */
10
- export declare function codexModelDiscoveryEnvironment(persistedEnv?: Readonly<Record<string, string | undefined>>, shellEnv?: Readonly<Record<string, string | undefined>>): Record<string, string | undefined>;
11
- export declare function normalizeEffort(value: unknown): EffortLevel | undefined;
12
- export declare function normalizeEfforts(values: readonly unknown[]): EffortLevel[];
13
- export declare function normalizeCodexCatalog(rows: readonly unknown[]): CodexCatalogModel[];
14
- export declare function requestCodexModelList(timeoutMs: number, environment: Readonly<Record<string, string | undefined>>, abortSignal?: AbortSignal): Promise<CodexCatalogModel[]>;
15
- //# sourceMappingURL=codex-model-catalog.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"codex-model-catalog.d.ts","sourceRoot":"","sources":["../src/codex-model-catalog.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAItD,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,gBAAgB,EAAE,SAAS,WAAW,EAAE,CAAC;IAClD,QAAQ,CAAC,aAAa,CAAC,EAAE,WAAW,CAAC;IACrC,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;CAC9B;AAgDD,4EAA4E;AAC5E,wBAAgB,8BAA8B,CAC5C,YAAY,GAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAM,EAC/D,QAAQ,GAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAe,GACnE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAOpC;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,WAAW,GAAG,SAAS,CAGvE;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,OAAO,EAAE,GAAG,WAAW,EAAE,CAE1E;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,SAAS,OAAO,EAAE,GAAG,iBAAiB,EAAE,CAsBnF;AAED,wBAAsB,qBAAqB,CACzC,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,EACzD,WAAW,CAAC,EAAE,WAAW,GACxB,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAoH9B"}
@@ -1,220 +0,0 @@
1
- import { spawn } from "node:child_process";
2
- import { homedir } from "node:os";
3
- import { createInterface } from "node:readline";
4
- import { credentialNeutralProviderStatusEnvironment } from "./provider-setup.js";
5
- const SUPPORTED_EFFORTS = new Set([
6
- "none",
7
- "minimal",
8
- "low",
9
- "medium",
10
- "high",
11
- "xhigh",
12
- "max",
13
- "ultra",
14
- ]);
15
- function isRecord(value) {
16
- return typeof value === "object" && value !== null && !Array.isArray(value);
17
- }
18
- function boundedCatalogText(value, limit) {
19
- const normalized = typeof value === "string"
20
- ? value.replace(/[\u0000-\u001f\u007f]/gu, " ").replace(/\s+/gu, " ").trim()
21
- : "";
22
- return normalized.length <= limit ? normalized : `${normalized.slice(0, Math.max(0, limit - 1))}…`;
23
- }
24
- function safeDiscoveryProcessEnv(source = process.env) {
25
- const env = {};
26
- for (const key of [
27
- "PATH",
28
- "LANG",
29
- "LC_ALL",
30
- "LC_CTYPE",
31
- "SHELL",
32
- "TMPDIR",
33
- "TMP",
34
- "TEMP",
35
- "SystemRoot",
36
- "WINDIR",
37
- "ComSpec",
38
- "PATHEXT",
39
- ]) {
40
- const value = source[key];
41
- if (typeof value === "string" && value.length > 0)
42
- env[key] = value;
43
- }
44
- return env;
45
- }
46
- /** Exact non-secret environment used by live Codex model/list discovery. */
47
- export function codexModelDiscoveryEnvironment(persistedEnv = {}, shellEnv = process.env) {
48
- const neutral = credentialNeutralProviderStatusEnvironment(shellEnv, persistedEnv);
49
- return {
50
- ...safeDiscoveryProcessEnv(shellEnv),
51
- HOME: neutral.HOME ?? homedir(),
52
- ...(neutral.CODEX_HOME === undefined ? {} : { CODEX_HOME: neutral.CODEX_HOME }),
53
- };
54
- }
55
- export function normalizeEffort(value) {
56
- const normalized = value === "off" ? "none" : typeof value === "string" ? value : "";
57
- return SUPPORTED_EFFORTS.has(normalized) ? normalized : undefined;
58
- }
59
- export function normalizeEfforts(values) {
60
- return [...new Set(values.map(normalizeEffort).filter((value) => value !== undefined))];
61
- }
62
- export function normalizeCodexCatalog(rows) {
63
- const result = [];
64
- const seen = new Set();
65
- for (const raw of rows.slice(0, 1_000)) {
66
- if (!isRecord(raw))
67
- continue;
68
- const id = typeof raw.id === "string" ? raw.id.trim() : "";
69
- if (id.length === 0 || id.length > 160 || seen.has(id))
70
- continue;
71
- const supportedRows = Array.isArray(raw.supportedReasoningEfforts)
72
- ? raw.supportedReasoningEfforts.map((entry) => isRecord(entry) ? entry.reasoningEffort : entry)
73
- : [];
74
- const supportedEfforts = normalizeEfforts(supportedRows);
75
- const normalizedDefault = normalizeEffort(raw.defaultReasoningEffort);
76
- seen.add(id);
77
- result.push({
78
- id,
79
- displayName: boundedCatalogText(raw.displayName, 160) || id,
80
- supportedEfforts,
81
- ...(normalizedDefault === undefined ? {} : { defaultEffort: normalizedDefault }),
82
- ...(typeof raw.isDefault === "boolean" ? { isDefault: raw.isDefault } : {}),
83
- });
84
- }
85
- return result;
86
- }
87
- export async function requestCodexModelList(timeoutMs, environment, abortSignal) {
88
- const child = spawn("codex", ["app-server", "--listen", "stdio://", "-c", "project_doc_max_bytes=0"], {
89
- stdio: ["pipe", "pipe", "ignore"],
90
- env: { ...environment },
91
- });
92
- const lines = createInterface({ input: child.stdout });
93
- return await new Promise((resolveResult, rejectResult) => {
94
- let settled = false;
95
- let timer;
96
- const ignoreStdinError = () => undefined;
97
- child.stdin.on("error", ignoreStdinError);
98
- const childClosedWithin = async (milliseconds) => {
99
- if (child.exitCode !== null || child.signalCode !== null)
100
- return true;
101
- return await new Promise((resolveClosed) => {
102
- const onClose = () => {
103
- clearTimeout(closeTimer);
104
- resolveClosed(true);
105
- };
106
- const closeTimer = setTimeout(() => {
107
- child.off("close", onClose);
108
- resolveClosed(false);
109
- }, milliseconds);
110
- closeTimer.unref?.();
111
- child.once("close", onClose);
112
- });
113
- };
114
- const stopChild = async () => {
115
- lines.removeAllListeners("line");
116
- lines.close();
117
- try {
118
- child.stdin.end();
119
- }
120
- catch { /* best effort */ }
121
- if (await childClosedWithin(25))
122
- return;
123
- try {
124
- child.kill("SIGTERM");
125
- }
126
- catch { /* best effort */ }
127
- if (await childClosedWithin(250))
128
- return;
129
- try {
130
- child.kill("SIGKILL");
131
- }
132
- catch { /* best effort */ }
133
- if (!await childClosedWithin(250)) {
134
- child.stdin.destroy();
135
- child.stdout.destroy();
136
- child.unref();
137
- }
138
- };
139
- let settle;
140
- const onChildError = () => void settle(new Error("Codex app-server is unavailable."));
141
- const onChildClose = () => void settle(new Error("Codex app-server closed before returning models."));
142
- const onAbort = () => {
143
- const error = new Error("Codex model catalog discovery was interrupted.");
144
- error.name = "AbortError";
145
- void settle(error);
146
- };
147
- settle = async (error, models = []) => {
148
- if (settled)
149
- return;
150
- settled = true;
151
- clearTimeout(timer);
152
- child.off("error", onChildError);
153
- child.off("close", onChildClose);
154
- abortSignal?.removeEventListener("abort", onAbort);
155
- await stopChild();
156
- child.stdin.off("error", ignoreStdinError);
157
- if (error === undefined)
158
- resolveResult(models);
159
- else
160
- rejectResult(error);
161
- };
162
- const writeMessage = (message) => {
163
- if (settled || child.stdin.destroyed || child.stdin.writableEnded)
164
- return;
165
- try {
166
- child.stdin.write(`${JSON.stringify(message)}\n`);
167
- }
168
- catch { /* bounded shutdown handles the process */ }
169
- };
170
- timer = setTimeout(() => void settle(new Error("Codex model catalog discovery timed out.")), Math.max(250, Math.min(10_000, timeoutMs)));
171
- timer.unref?.();
172
- child.once("error", onChildError);
173
- child.once("close", onChildClose);
174
- abortSignal?.addEventListener("abort", onAbort, { once: true });
175
- lines.on("line", (line) => {
176
- let message;
177
- try {
178
- message = JSON.parse(line);
179
- }
180
- catch {
181
- return;
182
- }
183
- if (!isRecord(message))
184
- return;
185
- if (typeof message.method === "string" && (typeof message.id === "string" || typeof message.id === "number")) {
186
- writeMessage({
187
- id: message.id,
188
- error: { code: -32601, message: "Model catalog discovery does not support server requests." },
189
- });
190
- return;
191
- }
192
- if (message.id === 1 && isRecord(message.result)) {
193
- writeMessage({
194
- id: 2,
195
- method: "model/list",
196
- params: { includeHidden: false, limit: 1_000 },
197
- });
198
- return;
199
- }
200
- if (message.id !== 2)
201
- return;
202
- if (!isRecord(message.result) || !Array.isArray(message.result.data)) {
203
- void settle(new Error("Codex app-server returned an invalid model catalog."));
204
- return;
205
- }
206
- void settle(undefined, normalizeCodexCatalog(message.result.data));
207
- });
208
- writeMessage({
209
- id: 1,
210
- method: "initialize",
211
- params: {
212
- clientInfo: { name: "mono-agent", title: "mono-agent", version: "0" },
213
- capabilities: { experimentalApi: true },
214
- },
215
- });
216
- if (abortSignal?.aborted === true)
217
- onAbort();
218
- });
219
- }
220
- //# sourceMappingURL=codex-model-catalog.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"codex-model-catalog.js","sourceRoot":"","sources":["../src/codex-model-catalog.ts"],"names":[],"mappings":"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"}