@mono-agent/agent-app 0.3.0 → 0.4.1

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 (186) hide show
  1. package/README.md +24 -10
  2. package/dist/adapter-send-tools-main.d.ts +3 -0
  3. package/dist/adapter-send-tools-main.d.ts.map +1 -0
  4. package/dist/adapter-send-tools-main.js +20 -0
  5. package/dist/adapter-send-tools-main.js.map +1 -0
  6. package/dist/adapter-send-tools.d.ts +125 -0
  7. package/dist/adapter-send-tools.d.ts.map +1 -0
  8. package/dist/adapter-send-tools.js +629 -0
  9. package/dist/adapter-send-tools.js.map +1 -0
  10. package/dist/app-config.d.ts +86 -26
  11. package/dist/app-config.d.ts.map +1 -1
  12. package/dist/app-config.js +284 -90
  13. package/dist/app-config.js.map +1 -1
  14. package/dist/app.d.ts +51 -20
  15. package/dist/app.d.ts.map +1 -1
  16. package/dist/app.js +889 -119
  17. package/dist/app.js.map +1 -1
  18. package/dist/artifact-retention.d.ts +32 -0
  19. package/dist/artifact-retention.d.ts.map +1 -0
  20. package/dist/artifact-retention.js +111 -0
  21. package/dist/artifact-retention.js.map +1 -0
  22. package/dist/audit-runs.d.ts +12 -0
  23. package/dist/audit-runs.d.ts.map +1 -0
  24. package/dist/audit-runs.js +68 -0
  25. package/dist/audit-runs.js.map +1 -0
  26. package/dist/backfill.d.ts +75 -0
  27. package/dist/backfill.d.ts.map +1 -0
  28. package/dist/backfill.js +350 -0
  29. package/dist/backfill.js.map +1 -0
  30. package/dist/background.d.ts +8 -5
  31. package/dist/background.d.ts.map +1 -1
  32. package/dist/background.js +279 -53
  33. package/dist/background.js.map +1 -1
  34. package/dist/broadcast-recorder.d.ts +27 -0
  35. package/dist/broadcast-recorder.d.ts.map +1 -0
  36. package/dist/broadcast-recorder.js +82 -0
  37. package/dist/broadcast-recorder.js.map +1 -0
  38. package/dist/channel-config-view.d.ts +28 -0
  39. package/dist/channel-config-view.d.ts.map +1 -0
  40. package/dist/channel-config-view.js +79 -0
  41. package/dist/channel-config-view.js.map +1 -0
  42. package/dist/channel-gate.d.ts +22 -0
  43. package/dist/channel-gate.d.ts.map +1 -0
  44. package/dist/channel-gate.js +35 -0
  45. package/dist/channel-gate.js.map +1 -0
  46. package/dist/channel-plugins.d.ts +39 -0
  47. package/dist/channel-plugins.d.ts.map +1 -0
  48. package/dist/channel-plugins.js +346 -0
  49. package/dist/channel-plugins.js.map +1 -0
  50. package/dist/channels.d.ts +62 -66
  51. package/dist/channels.d.ts.map +1 -1
  52. package/dist/channels.js +850 -120
  53. package/dist/channels.js.map +1 -1
  54. package/dist/cli.d.ts +103 -4
  55. package/dist/cli.d.ts.map +1 -1
  56. package/dist/cli.js +984 -112
  57. package/dist/cli.js.map +1 -1
  58. package/dist/config-reference.d.ts +24 -0
  59. package/dist/config-reference.d.ts.map +1 -0
  60. package/dist/config-reference.js +580 -0
  61. package/dist/config-reference.js.map +1 -0
  62. package/dist/configured-agent.d.ts +104 -0
  63. package/dist/configured-agent.d.ts.map +1 -0
  64. package/dist/configured-agent.js +578 -0
  65. package/dist/configured-agent.js.map +1 -0
  66. package/dist/consumer-contract.d.ts +36 -0
  67. package/dist/consumer-contract.d.ts.map +1 -0
  68. package/dist/consumer-contract.js +290 -0
  69. package/dist/consumer-contract.js.map +1 -0
  70. package/dist/doctor.d.ts +17 -0
  71. package/dist/doctor.d.ts.map +1 -1
  72. package/dist/doctor.js +392 -95
  73. package/dist/doctor.js.map +1 -1
  74. package/dist/index.d.ts +14 -6
  75. package/dist/index.d.ts.map +1 -1
  76. package/dist/index.js +7 -3
  77. package/dist/index.js.map +1 -1
  78. package/dist/init.d.ts +23 -7
  79. package/dist/init.d.ts.map +1 -1
  80. package/dist/init.js +91 -26
  81. package/dist/init.js.map +1 -1
  82. package/dist/install-skill.d.ts +1 -1
  83. package/dist/install-skill.js +2 -2
  84. package/dist/install-skill.js.map +1 -1
  85. package/dist/interaction-bridge.d.ts +72 -0
  86. package/dist/interaction-bridge.d.ts.map +1 -0
  87. package/dist/interaction-bridge.js +354 -0
  88. package/dist/interaction-bridge.js.map +1 -0
  89. package/dist/launchd.d.ts +0 -2
  90. package/dist/launchd.d.ts.map +1 -1
  91. package/dist/launchd.js +0 -2
  92. package/dist/launchd.js.map +1 -1
  93. package/dist/memory-command.d.ts +10 -0
  94. package/dist/memory-command.d.ts.map +1 -0
  95. package/dist/memory-command.js +649 -0
  96. package/dist/memory-command.js.map +1 -0
  97. package/dist/memory-recall-main.d.ts +3 -0
  98. package/dist/memory-recall-main.d.ts.map +1 -0
  99. package/dist/memory-recall-main.js +30 -0
  100. package/dist/memory-recall-main.js.map +1 -0
  101. package/dist/memory-recall.d.ts +147 -0
  102. package/dist/memory-recall.d.ts.map +1 -0
  103. package/dist/memory-recall.js +345 -0
  104. package/dist/memory-recall.js.map +1 -0
  105. package/dist/memory-rituals.d.ts +8 -11
  106. package/dist/memory-rituals.d.ts.map +1 -1
  107. package/dist/memory-rituals.js +26 -25
  108. package/dist/memory-rituals.js.map +1 -1
  109. package/dist/metrics.d.ts +13 -0
  110. package/dist/metrics.d.ts.map +1 -0
  111. package/dist/metrics.js +105 -0
  112. package/dist/metrics.js.map +1 -0
  113. package/dist/notify-destinations.d.ts +23 -0
  114. package/dist/notify-destinations.d.ts.map +1 -0
  115. package/dist/notify-destinations.js +79 -0
  116. package/dist/notify-destinations.js.map +1 -0
  117. package/dist/posted-message-index.d.ts +61 -0
  118. package/dist/posted-message-index.d.ts.map +1 -0
  119. package/dist/posted-message-index.js +178 -0
  120. package/dist/posted-message-index.js.map +1 -0
  121. package/dist/proactive-notify.d.ts +32 -0
  122. package/dist/proactive-notify.d.ts.map +1 -0
  123. package/dist/proactive-notify.js +62 -0
  124. package/dist/proactive-notify.js.map +1 -0
  125. package/dist/recipes/base.d.ts +15 -0
  126. package/dist/recipes/base.d.ts.map +1 -0
  127. package/dist/recipes/base.js +51 -0
  128. package/dist/recipes/base.js.map +1 -0
  129. package/dist/recipes/catalog.d.ts +4 -0
  130. package/dist/recipes/catalog.d.ts.map +1 -0
  131. package/dist/recipes/catalog.js +509 -0
  132. package/dist/recipes/catalog.js.map +1 -0
  133. package/dist/recipes/index.d.ts +11 -0
  134. package/dist/recipes/index.d.ts.map +1 -0
  135. package/dist/recipes/index.js +14 -0
  136. package/dist/recipes/index.js.map +1 -0
  137. package/dist/recipes/types.d.ts +70 -0
  138. package/dist/recipes/types.d.ts.map +1 -0
  139. package/dist/recipes/types.js +15 -0
  140. package/dist/recipes/types.js.map +1 -0
  141. package/dist/request-model-override.d.ts +67 -0
  142. package/dist/request-model-override.d.ts.map +1 -0
  143. package/dist/request-model-override.js +96 -0
  144. package/dist/request-model-override.js.map +1 -0
  145. package/dist/runs-health.d.ts +22 -0
  146. package/dist/runs-health.d.ts.map +1 -0
  147. package/dist/runs-health.js +144 -0
  148. package/dist/runs-health.js.map +1 -0
  149. package/dist/seen-conversations.d.ts +22 -0
  150. package/dist/seen-conversations.d.ts.map +1 -0
  151. package/dist/seen-conversations.js +120 -0
  152. package/dist/seen-conversations.js.map +1 -0
  153. package/dist/sessions.d.ts +21 -0
  154. package/dist/sessions.d.ts.map +1 -0
  155. package/dist/sessions.js +45 -0
  156. package/dist/sessions.js.map +1 -0
  157. package/dist/setup.d.ts +29 -0
  158. package/dist/setup.d.ts.map +1 -0
  159. package/dist/setup.js +97 -0
  160. package/dist/setup.js.map +1 -0
  161. package/dist/trigger-overrides.d.ts +17 -0
  162. package/dist/trigger-overrides.d.ts.map +1 -0
  163. package/dist/trigger-overrides.js +30 -0
  164. package/dist/trigger-overrides.js.map +1 -0
  165. package/dist/tui-command.d.ts +56 -0
  166. package/dist/tui-command.d.ts.map +1 -0
  167. package/dist/tui-command.js +160 -0
  168. package/dist/tui-command.js.map +1 -0
  169. package/dist/ui.d.ts +54 -0
  170. package/dist/ui.d.ts.map +1 -0
  171. package/dist/ui.js +157 -0
  172. package/dist/ui.js.map +1 -0
  173. package/dist/web-command.d.ts +39 -0
  174. package/dist/web-command.d.ts.map +1 -0
  175. package/dist/web-command.js +151 -0
  176. package/dist/web-command.js.map +1 -0
  177. package/package.json +22 -17
  178. package/schema/mono-agent.config.schema.json +1686 -0
  179. package/skills/mono-agent-composer/SKILL.md +38 -12
  180. package/skills/mono-agent-composer/agents/openai.yaml +4 -0
  181. package/skills/mono-agent-composer/references/config-blueprint.md +84 -31
  182. package/skills/mono-agent-composer/references/discovery-questions.md +49 -36
  183. package/skills/mono-agent-composer/references/feature-coverage.md +26 -19
  184. package/skills/mono-agent-composer/references/package-map.md +20 -22
  185. package/skills/mono-agent-composer/references/playbooks.md +209 -0
  186. package/skills/mono-agent-composer/references/validation.md +14 -5
@@ -4,7 +4,7 @@ Use this map to select the smallest mono-agent package set for a host. Package c
4
4
 
5
5
  ## App Join (default)
6
6
 
7
- `@mono-agent/agent-app` is the config-first host: it loads `mono-agent.config.json`, builds the responder through `agent-host`, and drives every configured channel plus the operator console and traceability. It ships the `mono-agent` CLI (`init`, `validate`, `start`) and is the only publishable package allowed to compose communication adapters.
7
+ `@mono-agent/agent-app` is the config-first host: it loads `mono-agent.config.json`, owns configured runtime/harness/responder/memory composition, and drives every configured channel plus traceability and any configured observability exporters. It ships the `mono-agent` CLI (`init`, `validate`, `start`) and is the only publishable package allowed to compose communication adapters.
8
8
 
9
9
  ```ts
10
10
  import { startMonoAgentApp } from "@mono-agent/agent-app";
@@ -23,13 +23,13 @@ Every real host needs these concepts:
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
25
  | Runtime facade | `@mono-agent/runtime-adapter` | Model refs, execution-mode validation, local provider runtime options | Prompts, adapters, memory |
26
- | Configured responder | `@mono-agent/agent-host` | Turns `MonoAgentConfig` into runtime, harness, and responder | Polling chats, serving APIs, adapter settings |
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:
29
29
 
30
30
  ```ts
31
31
  import { loadMonoAgentConfigWithSources } from "@mono-agent/config";
32
- import { createConfiguredAgentResponder } from "@mono-agent/agent-host";
32
+ import { createConfiguredAgentResponder } from "@mono-agent/agent-app";
33
33
 
34
34
  const config = await loadMonoAgentConfigWithSources({
35
35
  env: process.env,
@@ -37,7 +37,7 @@ const config = await loadMonoAgentConfigWithSources({
37
37
  jsonPath: "./mono-agent.config.json",
38
38
  });
39
39
 
40
- const responder = createConfiguredAgentResponder({ config });
40
+ const responder = await createConfiguredAgentResponder({ config });
41
41
  ```
42
42
 
43
43
  ## Context And Skill Join
@@ -46,17 +46,18 @@ Use this path when the agent needs identity, selected skills, history, and optio
46
46
 
47
47
  | Need | Package | Use |
48
48
  | --- | --- | --- |
49
- | Prompt assembly | `@mono-agent/context` | Load identity/SOUL/skills/history/memory into deterministic prompt context |
50
- | Selected skill bodies | `@mono-agent/skills` | Load only configured skills from `<skillsRoot>/<name>/SKILL.md` |
51
- | Memory substrate (schema, migrations, FTS+vector db, RRF) | `@mono-agent/memory-store` | SQLite storage, BM25 FTS, optional vector index, hybrid recall; `MemoryStore`/`MemoryBlock`/`MemoryWriteResult` contract |
52
- | Memory engine (all tiers: lite/journal/bujo) | `@mono-agent/memory-bujo` | `BujoMemoryStore` — tier-aware: FTS recall (lite), hybrid recall + decay (journal), LLM capture/reconcile + entity graph + reflection/migration + auto-scheduler (bujo) |
53
- | Embedding providers | `@mono-agent/memory-search` | Ollama/OpenAI embedding providers used by memory-store for vector recall |
49
+ | Prompt assembly | `@mono-agent/agent-harness` | Load identity/SOUL/skills/history/memory into deterministic prompt context |
50
+ | Selected skill bodies | `@mono-agent/agent-harness` | Load only configured skills from `<skillsRoot>/<name>/SKILL.md` |
51
+ | Memory substrate (schema, migrations, FTS+vector db, RRF) | `@mono-agent/memory/store` | SQLite storage, BM25 FTS, optional vector index, hybrid recall; re-exports `MemoryStore`/`MemoryBlock`/`MemoryWriteResult` from `@mono-agent/agent-contracts` |
52
+ | Memory engine (all tiers: lite/journal/bujo) | `@mono-agent/memory/bujo` | `BujoMemoryStore` — tier-aware: FTS recall (lite), hybrid recall + decay (journal), LLM capture/reconcile + entity graph + scheduled consolidation (bujo) |
53
+ | Embedding providers | `@mono-agent/memory/search` | Ollama/OpenAI embedding providers used by the store subpath for vector recall |
54
+ | Recall tool surface | `@mono-agent/agent-app` (bundled) | Auto-provisions a read-only `memory_recall` tool (hybrid keyword+semantic search) from `config.memory.recallTool.enabled`; spawns the bundled `mono-agent-memory` stdio child using the same memory root + embeddings as the in-app memory |
54
55
 
55
56
  Mono-agent selected skills are not auto-selected by description. The host chooses `context.selectedSkills`, and the harness loads those exact bodies.
56
57
 
57
58
  ## Execution Join
58
59
 
59
- Use `@mono-agent/agent-harness` directly when a host needs custom runtime, memory, history, recorder, or request-scoped runtime options. Use `@mono-agent/agent-host` when config-driven composition is enough.
60
+ Use `@mono-agent/agent-harness` directly when a host needs custom prompt/runtime/memory/history/recorder wiring below the config layer. Use `@mono-agent/agent-app` when config-driven composition is enough.
60
61
 
61
62
  `@mono-agent/agent-harness` owns:
62
63
 
@@ -71,10 +72,10 @@ Use `@mono-agent/agent-harness` directly when a host needs custom runtime, memor
71
72
 
72
73
  ## Tools And MCP Join
73
74
 
74
- Use `@mono-agent/tool-policy` for fail-closed tool/MCP policy normalization:
75
+ Use `@mono-agent/agent-harness` for fail-closed tool/MCP policy normalization:
75
76
 
76
77
  ```ts
77
- import { createToolPolicy, toolPolicyToRuntimeOptions } from "@mono-agent/tool-policy";
78
+ import { createToolPolicy, toolPolicyToRuntimeOptions } from "@mono-agent/agent-harness";
78
79
 
79
80
  const policy = createToolPolicy({
80
81
  allowedTools: ["Read", "Grep"],
@@ -97,25 +98,22 @@ Communication adapters are edge packages. They accept an `AgentResponder` and ow
97
98
  | Slack | `@mono-agent/slack-adapter` | Allowed channel or DM gets a streamed reply |
98
99
  | WhatsApp | `@mono-agent/whatsapp-adapter` | Allowed sender/group trigger produces a reply |
99
100
  | OpenAI-compatible API | `@mono-agent/openai-api-adapter` | `curl /v1/models` and `/v1/chat/completions` |
101
+ | Operator endpoints | `@mono-agent/operator-adapter` | `mono-agent tui` connects; `mono-agent web` observes live runs |
100
102
  | A2A provider/consumer | `@mono-agent/a2a-adapter` | Send text to the Agent Card URL |
101
103
  | Webhook | `@mono-agent/webhook-adapter` | `curl` the configured invocation path |
102
104
  | Cron | `@mono-agent/cron-adapter` | One scheduled or manually triggered invocation |
103
105
 
104
- Adapters must not import the harness, runtime adapter, memory packages (`memory-store`, `memory-bujo`, `memory-search`), or other adapters. `@mono-agent/agent-app` composes them from config; custom hosts and demos may compose them directly.
106
+ 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.
105
107
 
106
- ## Operator And Observability Join
108
+ ## Observability Join
107
109
 
108
110
  Use:
109
111
 
110
- - `@mono-agent/operator-console` for local browser settings and traceability (`console` config section; per-boot bearer token; saves re-apply live).
111
- - `@mono-agent/tui` for local terminal chat and redacted read-only config (`mono-agent-tui --config ./mono-agent.config.json`).
112
- - `@mono-agent/observability` for JSONL event artifacts, summaries, and trace-source registration.
112
+ - `@mono-agent/tui` for the pi-tui operator console (`mono-agent tui`): live chat with full stream-event insight, recorded-run replay, config view.
113
+ - `@mono-agent/operator-adapter` for the loopback NDJSON stream endpoint the console connects to (`tui` config section, on by default) and the live SSE endpoint `mono-agent web` observes (`live` config section, on by default).
114
+ - `@mono-agent/observability` for JSONL event artifacts, summaries, trace-source registration, and the `@mono-agent/observability/otel` Phoenix OTLP exporter configured via `observability.exporters`.
113
115
 
114
- Traceability is local-first. A running host registers a source manifest; the operator console reads artifacts by `(sourceId, runId)` so duplicate run ids do not collide.
115
-
116
- ## Evaluation Join
117
-
118
- Use `@mono-agent/agent-evals` to define end-to-end scenarios against a responder or harness: final-text assertions, trajectory/tool-call matching, cost/turn/duration budgets, and custom judges, with local JSON/markdown artifacts. Live-provider scenarios are skipped unless `MONO_AGENT_EVAL_LIVE=1`.
116
+ Traceability is local-first. A running host registers a source manifest; `mono-agent status` reads the trace-source registry to report live sources, and artifacts are keyed by `(sourceId, runId)` so duplicate run ids do not collide. Phoenix is the recommended trace viewer when an `observability.exporters` (phoenix) entry is configured; local JSONL artifacts are the fallback otherwise.
119
117
 
120
118
  ## Multi-Agent Join
121
119
 
@@ -0,0 +1,209 @@
1
+ # Playbooks
2
+
3
+ Condensed, offline copy of the end-to-end recipes. Each maps a persona/goal to a
4
+ concrete `mono-agent.config.json` shape and the `init → configure → validate →
5
+ start → smoke` flow. Mirrors the published Playbooks index
6
+ (<https://mono-agent-docs.vercel.app/playbooks/>); this file is the
7
+ self-contained in-skill version so the composer can offer a matching recipe
8
+ without fetching anything. Before hand-assembling a config in the Composition
9
+ Flow, check whether one of these fits and adapt it. Verify every key against
10
+ `references/config-blueprint.md`.
11
+
12
+ ---
13
+
14
+ ## 1. Personal Telegram assistant with BuJo memory
15
+ **For:** an individual wanting a private assistant that remembers.
16
+ **Goal:** a Telegram bot (long polling) that captures every turn into BuJo memory with scheduled consolidation and recalls past notes semantically.
17
+ **Features:** `telegram.long-polling`, `channel.final-only-delivery`, `memory.bujo`, `memory.per-turn-capture`, `memory.bujo-consolidation`, `memory.recall-tool`, `memory.embeddings`.
18
+
19
+ ```json
20
+ {
21
+ "runtime": { "model": "claude:claude-sonnet-4-6" },
22
+ "telegram": { "enabled": true, "botToken": "...", "allowedChatIds": ["123456789"] },
23
+ "memory": {
24
+ "mode": "bujo", "path": "./.mono-agent/memory", "writeMode": "capture",
25
+ "embeddings": { "provider": "ollama", "model": "nomic-embed-text:v1.5", "endpoint": "http://localhost:11434", "dim": 768 },
26
+ "llm": { "provider": "ollama", "model": "qwen3.6:latest" },
27
+ "consolidation": { "enabled": true, "cron": "0 */2 * * *" }
28
+ }
29
+ }
30
+ ```
31
+ **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`.
32
+ **Smoke:** send a fact from the allowed chat, then ask a paraphrased question later; confirm `memory_recall` in the run JSONL and that the answer uses it.
33
+
34
+ ## 2. Slack team bot with MCP tools
35
+ **For:** a DevOps engineer running a shared team bot.
36
+ **Goal:** a mention-triggered Slack Socket Mode bot with a custom MCP tool, Read/Grep, and `slack_send_message` for proactive posts.
37
+ **Features:** `slack.socket-mode`, `tool-policy.allowlist`, `tool-policy.mcp-servers`, `agent-app.adapter-send-tools`, `runtime.concurrency`.
38
+
39
+ ```json
40
+ {
41
+ "runtime": { "model": "claude:claude-sonnet-4-6" },
42
+ "slack": { "enabled": true, "botToken": "xoxb-...", "appToken": "xapp-...", "allowedChannelIds": ["C012345"], "botUserIds": ["U012345"], "mentionTextAliases": ["@agent"] },
43
+ "tools": { "allowedTools": ["Read", "Grep", "slack_send_message", "deployTool"], "mcpConfigPath": "./mcp.json" },
44
+ "concurrency": { "maxConcurrentRuns": 4, "maxPendingRuns": 8 }
45
+ }
46
+ ```
47
+ **Steps:** create a Slack app (Socket Mode app token + bot token) → `mono-agent init` → write `mcp.json` and add the MCP tool's exact name to `allowedTools` → add slack + `slack_send_message` → `validate` → `start`.
48
+ **Smoke:** mention the bot in an allowed channel; confirm the 👀 reaction, final answer, the MCP tool firing in the artifact, and that `slack_send_message` posts only to allowed channels.
49
+
50
+ ## 3. Fully local Ollama agent (no cloud)
51
+ **For:** a privacy-focused user with no cloud budget.
52
+ **Goal:** runs entirely on local Ollama via the Pi SDK, journal memory with local embeddings, no outbound network.
53
+ **Features:** `runtime.local-providers`, `runtime.multi-backend`, `memory.journal`, `memory.embeddings`, `sandbox.network-policy`.
54
+
55
+ ```json
56
+ {
57
+ "runtime": { "model": "pi:ollama:gemma4:31b" },
58
+ "providers": { "local": [{ "id": "ollama", "type": "ollama", "baseUrl": "http://localhost:11434", "enabled": true, "models": [{ "name": "gemma4:31b", "capabilities": { "context_window": 32768 } }] }] },
59
+ "memory": { "mode": "journal", "path": "./.mono-agent/memory", "embeddings": { "provider": "ollama", "model": "nomic-embed-text:v1.5", "endpoint": "http://localhost:11434", "dim": 768 } },
60
+ "sandbox": { "mode": "native", "network": { "mode": "localhost" } }
61
+ }
62
+ ```
63
+ **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`.
64
+ **Smoke:** `curl -X POST` the webhook path; confirm a local-model response and no outbound non-localhost network in the artifact.
65
+
66
+ ## 4. OpenAI-compatible endpoint for Open WebUI
67
+ **For:** an AI-infra engineer fronting the agent with a chat UI.
68
+ **Goal:** expose `/v1` (SSE) so Open WebUI can stream and keep multi-turn state.
69
+ **Features:** `openai-api.chat-completions`, `runtime.provider-sessions`.
70
+
71
+ ```json
72
+ {
73
+ "runtime": { "model": "claude:claude-sonnet-4-6", "session": { "mode": "continuous", "idleTimeoutMs": 1800000 } },
74
+ "openaiApi": { "enabled": true, "host": "0.0.0.0", "port": 4040, "basePath": "/v1", "allowNonLoopback": true, "modelId": "my-agent", "apiKey": "sk-secret" }
75
+ }
76
+ ```
77
+ **Steps:** `mono-agent init` → add `openaiApi` (set `allowNonLoopback`, `apiKey`, `modelId`) + continuous session → `validate` → `start` → in Open WebUI add an OpenAI connection at `http://host:4040/v1` with the bearer.
78
+ **Smoke:** `curl /v1/models` returns `my-agent`; two calls with the same `X-OpenWebUI-Chat-Id` resume the session and stream via SSE.
79
+
80
+ ## 5. Webhook automation (sync + async)
81
+ **For:** a backend developer wiring the agent into a pipeline.
82
+ **Goal:** fast sync calls + long-running async jobs (202 + status polling) across multiple named endpoints.
83
+ **Features:** `webhook.http-invoke` (sync/async modes, multiple endpoints, per-endpoint prompt).
84
+
85
+ ```json
86
+ {
87
+ "runtime": { "model": "claude:claude-sonnet-4-6" },
88
+ "webhook": {
89
+ "enabled": true, "host": "127.0.0.1", "port": 8080, "defaultMode": "sync",
90
+ "endpoints": [
91
+ { "name": "invoke", "path": "/webhook/invoke", "mode": "sync", "prompt": "Respond to this request:" },
92
+ { "name": "jobs", "path": "/webhook/jobs", "mode": "async" }
93
+ ],
94
+ "retentionMs": 300000, "maxStoredRequests": 100
95
+ }
96
+ }
97
+ ```
98
+ **Steps:** `mono-agent init` (webhook already enabled) → add `endpoints[]` (or `webhook/*.md` files; unique names AND paths) → `validate` → `start`.
99
+ **Smoke:** `POST /webhook/invoke` for an immediate body; `POST /webhook/jobs` → 202 + status URL → poll until the result returns.
100
+
101
+ ## 6. Cron digest with proactive Slack notify
102
+ **For:** a data analyst wanting a scheduled briefing pushed to the team.
103
+ **Goal:** a timezone-aware cron job that builds a daily digest with shared history and posts it to Slack.
104
+ **Features:** `cron.scheduled-prompts`, `agent-app.adapter-send-tools`, `slack.socket-mode`, `memory.journal`.
105
+
106
+ ```json
107
+ {
108
+ "runtime": { "model": "claude:claude-sonnet-4-6" },
109
+ "slack": { "enabled": true, "botToken": "xoxb-...", "appToken": "xapp-...", "allowedChannelIds": ["C012345"] },
110
+ "tools": { "allowedTools": ["slack_send_message", "WebSearch"] },
111
+ "cron": { "jobs": [{ "id": "morning-digest", "enabled": true, "expression": "0 9 * * *", "timezone": "America/New_York", "prompt": "Build the morning digest and post it to #team via slack_send_message.", "conversationId": "daily-digest" }] }
112
+ }
113
+ ```
114
+ **Steps:** `mono-agent init` → add slack + `slack_send_message` → add the cron job (or `cron/morning-digest.md`) with `conversationId` + IANA timezone → `validate` → `start`.
115
+ **Smoke:** trigger a one-off tick; confirm `slack_send_message` posts the digest to the allowed channel and `conversationId` shares context across ticks.
116
+
117
+ ## 7. A2A provider + consumer pair
118
+ **For:** a platform integrator connecting two agents over A2A.
119
+ **Goal:** publish agent A as an A2A provider (Agent Card, bearer); configure agent B to discover and call it.
120
+ **Features:** `a2a.provider`, `a2a.consumer`.
121
+
122
+ ```json
123
+ {
124
+ "a2a": {
125
+ "enabled": true,
126
+ "provider": { "host": "127.0.0.1", "port": 4201, "requireBearer": true, "bearerToken": "..." },
127
+ "agent": { "name": "Research Agent", "description": "Does research.", "version": "0.1.0" },
128
+ "skill": { "id": "research", "name": "Research", "description": "Web research", "tags": ["research"] },
129
+ "consumer": { "remoteAgentUrls": ["http://127.0.0.1:4201"], "defaultRemoteAgentUrl": "http://127.0.0.1:4201", "bearerToken": "...", "timeoutMs": 30000 }
130
+ }
131
+ }
132
+ ```
133
+ **Steps:** provider — `init`, add `a2a.provider/agent/skill` + bearer, `validate`, `start`, confirm the Agent Card is reachable. Consumer — set `a2a.consumer` (or compose `createA2AConsumerResponder`), send text to the provider's Agent Card URL with the bearer.
134
+ **Smoke:** send a message to the provider's Agent Card URL with the bearer; confirm a real response.
135
+
136
+ ## 8. Multi-agent orchestration (`ask_collaborator`) — code
137
+ **For:** a workflow designer composing specialist agents.
138
+ **Goal:** one orchestrator delegates to named collaborator responders via the loopback `ask_collaborator` MCP tool.
139
+ **Features:** `orchestrator.ask-collaborator`, `harness.request-runtime-options`, `runtime.custom`.
140
+
141
+ ```ts
142
+ const ext = createCollaboratorToolRuntimeExtension({
143
+ collaborators: [
144
+ { id: "researcher", label: "Research", responder: researcher },
145
+ { id: "writer", label: "Writer", responder: writer },
146
+ ],
147
+ conversationId, maxCalls: 10,
148
+ });
149
+ // pass ext.runtimeOptions via createConfiguredAgentResponder({ runtimeOptionsForRequest })
150
+ // call ext.cleanup() on disposal to close the ephemeral MCP server
151
+ ```
152
+ **Smoke:** give a compound task ("research X then write a summary"); confirm the artifact shows `ask_collaborator` delegating to both, and `cleanup()` closes the MCP port.
153
+
154
+ ## 9. Sandboxed code agent (loopback only, deny .env)
155
+ **For:** a security team deploying an internal code assistant.
156
+ **Goal:** read repos + run Bash inside the native srt sandbox with loopback-only network access and protected secrets.
157
+ **Features:** `sandbox.mode`, `sandbox.network-policy`, `sandbox.filesystem-scopes`, `sandbox.fallback`, `tool-policy.allowlist`, `memory.journal`.
158
+
159
+ ```json
160
+ {
161
+ "runtime": { "model": "claude:claude-sonnet-4-6" },
162
+ "tools": { "allowedTools": ["Read", "Write", "Edit", "Glob", "Grep", "Bash"] },
163
+ "sandbox": { "mode": "native", "network": { "mode": "localhost" }, "readableRoots": ["."], "writableRoots": ["."], "denyWrite": [".env", ".env.*", ".git/config", ".git/hooks/**"], "fallback": "fail-closed" }
164
+ }
165
+ ```
166
+ **Steps:** `mono-agent init --memory journal` → allow Read/Write/Edit/Glob/Grep/Bash → `sandbox.mode native` + `network localhost` + deny-write defaults → keep `fallback: fail-closed` (do NOT set `unsafe-host-process`) → `validate` → `start`.
167
+ **Smoke:** ask it to read a file + run Bash (works), then fetch an external URL or write `.env` (both blocked in the artifact). Note: provider CLI bridges run their own tool loops and may not be srt-wrapped — pair with provider sandboxing.
168
+
169
+ ## 10. Phoenix-observed agent with the TUI
170
+ **For:** an agent builder evaluating runs in a tracing dashboard.
171
+ **Goal:** run locally with the TUI and stream every run to Phoenix as OpenInference spans; local JSONL is the fallback.
172
+ **Features:** `observability.phoenix-exporter`, `observability.jsonl-artifacts`, `observability.trace-registry`, `tui.chat`.
173
+
174
+ ```json
175
+ {
176
+ "runtime": { "model": "claude:claude-sonnet-4-6" },
177
+ "artifacts": { "dir": ".mono-agent/artifacts" },
178
+ "traceability": { "registryDir": ".mono-agent/trace-sources", "sourceId": "my-agent", "heartbeatMs": 10000 },
179
+ "observability": { "exporters": [{ "type": "phoenix", "endpoint": "http://127.0.0.1:6006/v1/traces", "projectName": "my-project", "includeSensitiveData": false, "timeoutMs": 5000 }] }
180
+ }
181
+ ```
182
+ **Steps:** start Phoenix (6006) → `init` → add artifacts/traceability/exporter → `validate` (POSTs an empty protobuf) → `start` (prints the Phoenix endpoint) → `mono-agent tui`.
183
+ **Smoke:** complete a TUI prompt; confirm a redacted JSONL artifact AND a Phoenix trace with merged tool spans under the project.
184
+
185
+ ## 11. Backfill historical runs to Phoenix
186
+ **For:** an ops engineer onboarding observability after the fact.
187
+ **Goal:** retroactively export recorded JSONL runs to Phoenix with original timestamps, idempotently.
188
+ **Features:** `observability.backfill`, `observability.phoenix-exporter`, `observability.jsonl-artifacts`.
189
+
190
+ ```json
191
+ { "artifacts": { "dir": ".mono-agent/artifacts" }, "observability": { "exporters": [{ "type": "phoenix", "endpoint": "http://127.0.0.1:6006/v1/traces", "projectName": "my-project" }] } }
192
+ ```
193
+ **Steps:** ensure `run-*.summary.json` + `run-*.events.jsonl` exist and Phoenix is reachable → `mono-agent backfill --all --since <iso> --until <iso> --dry-run` → `mono-agent backfill --all --since <iso>`.
194
+ **Smoke:** dry-run then real export; historical timestamps preserved in Phoenix and a second run does not duplicate spans (deterministic ids).
195
+
196
+
197
+ ## 12. Multi-model fallback chain with transcript resume
198
+ **For:** a reliability-minded builder who can't afford a single-provider outage.
199
+ **Goal:** a primary model with ordered backups the native failover router tries on retryable failures, resuming from the transcript tail — reported, never silent.
200
+ **Features:** `runtime.multi-backend`, `runtime.fallback-models`, `runtime.pi-native-tuning`, `runtime.provider-sessions`.
201
+
202
+ ```json
203
+ {
204
+ "runtime": { "model": "claude:claude-sonnet-4-6", "fallbackModels": ["pi:openai-codex:gpt-5.5", "pi:ollama:gemma4:31b"], "session": { "mode": "continuous" } },
205
+ "providers": { "local": [{ "id": "ollama", "type": "ollama", "baseUrl": "http://localhost:11434", "enabled": true }], "piNative": { "piMaxRetries": 2, "maxRetryDelayMs": 60000, "piSessionsRoot": ".mono-agent/sessions" } }
206
+ }
207
+ ```
208
+ **Steps:** `ollama pull gemma4:31b` → `mono-agent init --model claude:claude-sonnet-4-6 --fallback-models pi:openai-codex:gpt-5.5,pi:ollama:gemma4:31b` → add `providers.local` + `piNative.piSessionsRoot` → `validate` → `start`.
209
+ **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.
@@ -10,7 +10,15 @@ In the user's agent folder:
10
10
  mono-agent validate
11
11
  ```
12
12
 
13
- The report covers core config, runtime support for the primary and every fallback model, identity/skills/memory/MCP paths, the sandbox policy, the operator console section, and every channel (`ok` / `waiting` / `off` / `error`). Exit 0 means the folder is ready to start. Fix every `[error]`; `[waiting]` channels are simply unconfigured.
13
+ The report covers core config, runtime support for the primary and every fallback model, identity/skills/memory/MCP paths, the sandbox policy, the observability section (artifacts, traceability, and any configured exporters), and every channel (`ok` / `waiting` / `off` / `error`). Exit 0 means the folder is ready to start. Fix every `[error]`; `[waiting]` channels are simply unconfigured.
14
+
15
+ From a separate orchestration folder, validate a downstream consumer without changing cwd:
16
+
17
+ ```bash
18
+ mono-agent validate --consumer <agent-folder>
19
+ ```
20
+
21
+ The consumer folder's `.env` loads by default, relative `--config` and `--env-file` paths resolve inside that folder, and missing memory roots warn read-only instead of being created.
14
22
 
15
23
  Then start and confirm the status lines:
16
24
 
@@ -27,7 +35,7 @@ agent's configured skills root, e.g. `./skills`):
27
35
 
28
36
  ```bash
29
37
  node --input-type=module - <<'EOF'
30
- import { loadSkillIndexFromDirectory } from '@mono-agent/context';
38
+ import { loadSkillIndexFromDirectory } from '@mono-agent/agent-harness';
31
39
 
32
40
  const skills = await loadSkillIndexFromDirectory('<skillsRoot>');
33
41
  console.log(JSON.stringify(skills, null, 2));
@@ -75,14 +83,15 @@ pnpm run test:demo
75
83
  | TUI | Start the host and complete one local prompt. |
76
84
  | Telegram | Send one allowed chat message and verify the reply. |
77
85
  | Slack | Send one allowed DM or channel message and verify formatting. |
86
+ | Adapter send tools | When `tools.allowedTools` includes `slack_send_message` / `telegram_send_message`, call them from a non-Slack/Telegram surface such as TUI, cron, or OpenAI API to an allowed destination and verify delivery. |
78
87
  | WhatsApp | Send one allowed sender/group trigger and verify the reply. |
79
88
  | OpenAI API | `curl /v1/models` and `/v1/chat/completions`. |
80
89
  | A2A | Send text to the Agent Card URL with `sendA2AMessage()`. |
81
90
  | Webhook | `curl` the invocation path and inspect the response body/status. |
82
91
  | Cron | Run a one-off scheduled invocation or wait for one tick. |
83
- | Operator console | Open Settings and Traceability; confirm redaction and a visible run artifact. |
84
- | Journal memory tools | Ask the agent to recall yesterday (`memory_read_day`/`memory_grep` should appear in the run artifact). |
85
- | Semantic memory search | With `memory.embeddings` set (Ollama: `ollama pull nomic-embed-text` first), ask a paraphrased question about an old note and confirm `memory_search` returns it. |
92
+ | Observability | Confirm a run writes a redacted JSONL artifact; if an `observability.exporters` Phoenix entry is set, confirm the trace appears in Phoenix. |
93
+ | Memory recall tool | With `memory.recallTool.enabled` (default on for journal/bujo with embeddings), ask the agent to recall an old note and confirm `memory_recall` appears in the run artifact and returns it. |
94
+ | Semantic memory search | With `memory.embeddings` set (Ollama: `ollama pull nomic-embed-text:v1.5` first), ask a paraphrased question about an old note and confirm `memory_recall` (hybrid keyword + semantic) returns it. |
86
95
 
87
96
  ## Failure Handling
88
97