docs: describe queue-based reasoning_plan fallback
- PLANNING.md: add WithFallbackPlanBackend to loose-coupling section; update auto-wiring section with priority order; rewrite graceful degradation section; add Queue-based fallback section covering queuePlanBackend, placeholder IDs, durability, and fan-out pattern - ARCHITECTURE.md: update planning prose, data flow diagram, extension points, and BuildAgentEnv description to cover fallback priority - README.md: update reasoning_plan bullet to mention queue fallback Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
1ac68c2ac1
commit
fda9919dce
|
|
@ -79,7 +79,7 @@ Five built-in tools across two servers:
|
|||
- `execute_tool` — run a named tool script from `OLLIE_TOOLS_PATH` (default: `~/.local/share/ollie/tools`)
|
||||
- `execute_pipe` — chain steps as a pipeline
|
||||
- `reasoning_think` — externalize intermediate reasoning
|
||||
- `reasoning_plan` — decompose a goal into ordered steps; persists to task backend if available
|
||||
- `reasoning_plan` — decompose a goal into ordered steps; persists to task backend if available, otherwise queued via fallback backend or in-context only
|
||||
|
||||
File operations go through `execute_code` using standard shell tools (`cat`, `grep`, `sed`, `ed`, `ssam` if plan9port is available, etc.).
|
||||
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ Consumers extend ollie by implementing or composing its interfaces:
|
|||
- **`tools.Server`** — add a new tool server (built-in or MCP-backed); all servers are equal
|
||||
- **`tools.Dispatcher`** — replace the tool router entirely (e.g. remote dispatcher, mock)
|
||||
- **task backend (MCP)** — any MCP server that exposes `task_create` is automatically wired as the persistence backend for `reasoning_plan` by `BuildAgentEnv`; no consumer code required. See [9beads-mcp](https://github.com/lneely/9beads-mcp) for the reference implementation and the interface contract.
|
||||
- **fallback plan backend** — consumers can supply a `tools.PlanBackend` via `agent.WithFallbackPlanBackend` that is used when no `task_create` MCP tool is found. ollie-9p uses this to enqueue plan steps into the session queue.
|
||||
- **`agent.Core`** — the agent's public API; frontends drive it without knowing internals
|
||||
|
||||
All tool servers implement the same `tools.Server` interface regardless of whether they are built-in or backed by MCP. There is no special "builtin" concept — `execute.Server` and `file.Server` are registered by name the same way MCP servers are, and are torn down and recreated on `/agent` switches just like MCP connections.
|
||||
|
|
@ -63,8 +64,10 @@ Frontend
|
|||
├── "reasoning" → tools.Server
|
||||
│ reasoning_think
|
||||
│ reasoning_plan
|
||||
│ └── tools.PlanBackend (optional)
|
||||
│ task_create / ... (any MCP task server)
|
||||
│ └── tools.PlanBackend (optional, priority order)
|
||||
│ 1. dispatchPlanBackend → task_create (MCP)
|
||||
│ 2. WithFallbackPlanBackend (e.g. queuePlanBackend)
|
||||
│ 3. nil → in-context plan only
|
||||
└── "<servername>" → tools.Server
|
||||
```
|
||||
|
||||
|
|
@ -92,7 +95,9 @@ Tool definitions live in `pkg/tools/builtin.go` to avoid import cycles — the s
|
|||
|
||||
`reasoning_plan` is a meta-cognitive tool for executive planning. It decomposes a goal into a dependency graph of steps before execution begins. If a task backend is available, the plan is committed to persistent storage.
|
||||
|
||||
The task backend is any MCP server that exposes a `task_create` tool. `BuildAgentEnv` scans available tools after connecting MCP servers: if `task_create` is found, it wires a `dispatchPlanBackend` to the reasoning server's `Plan` field via the `tools.PlanBackendSetter` interface. If not found, `reasoning_plan` produces an in-context plan only — degraded but functional.
|
||||
The task backend is any MCP server that exposes a `task_create` tool. `BuildAgentEnv` scans available tools after connecting MCP servers: if `task_create` is found, it wires a `dispatchPlanBackend` to the reasoning server's `Plan` field via the `tools.PlanBackendSetter` interface. If not found, it falls back to any `PlanBackend` supplied via `WithFallbackPlanBackend`. If neither is present, `reasoning_plan` produces an in-context plan only.
|
||||
|
||||
ollie-9p supplies a `queuePlanBackend` fallback for every session: when `task_create` is absent, plan steps are enqueued to the session's `enqueue` file in topological order and returned as placeholder IDs (`q1`, `q2`, …).
|
||||
|
||||
The reference task backend is [9beads-mcp](https://github.com/lneely/9beads-mcp), which wraps the [9beads](https://github.com/lneely/9beads) 9P task server.
|
||||
|
||||
|
|
@ -135,7 +140,7 @@ core := agent.NewAgentCore(agent.AgentCoreConfig{
|
|||
|
||||
`BuildAgentEnv` adds MCP servers from the config on top of the pre-registered servers. On `/agent` switches, `NewDispatcher` is called to produce a fresh dispatcher — all servers (built-in and MCP) are torn down and recreated for the new agent config. `WorkDir` is preserved across switches.
|
||||
|
||||
After connecting MCP servers, `BuildAgentEnv` scans the tool list for `task_create`. If found, it wires a `dispatchPlanBackend` to the reasoning server's `Plan` field via `tools.PlanBackendSetter`. This auto-wiring runs on every agent start and `/agent` switch.
|
||||
After connecting MCP servers, `BuildAgentEnv` scans the tool list for `task_create`. If found, it wires a `dispatchPlanBackend` to the reasoning server's `Plan` field via `tools.PlanBackendSetter`. If not found, it wires any fallback passed via `WithFallbackPlanBackend`. This auto-wiring runs on every agent start and `/agent` switch.
|
||||
|
||||
`Core.ListServers()` returns all registered tool servers and their tools, grouped by server name. Accessible via the `/mcp` command or `ollie/s/{sid}/mcp` in ollie-9p.
|
||||
|
||||
|
|
|
|||
|
|
@ -32,13 +32,22 @@ minimum for a built-in tool.
|
|||
|
||||
The reasoning server holds an optional `Plan tools.PlanBackend` field (nil by
|
||||
default). When nil, `reasoning_plan` produces an in-context plan only. When set,
|
||||
the plan is also committed to persistent storage.
|
||||
the plan is persisted (or queued) by the backend.
|
||||
|
||||
`tools.PlanBackend` and `tools.PlanBackendSetter` are defined in `pkg/tools`.
|
||||
The reasoning server implements `PlanBackendSetter`. The agent package implements
|
||||
`dispatchPlanBackend`, which routes task creation through the dispatcher. No
|
||||
import cycles: reasoning → tools, agent → tools, agent ↛ reasoning.
|
||||
|
||||
Consumers can supply a fallback backend via `agent.WithFallbackPlanBackend(b)`:
|
||||
|
||||
```go
|
||||
env := agent.BuildAgentEnv(cfg, d, workdir, agent.WithFallbackPlanBackend(myFallback))
|
||||
```
|
||||
|
||||
The fallback is only used when no `task_create` MCP tool is found. If a task
|
||||
backend is available it takes priority unconditionally.
|
||||
|
||||
### Task backend as an MCP server
|
||||
|
||||
The task backend is any MCP server that exposes `task_create`. There is no
|
||||
|
|
@ -67,20 +76,48 @@ After connecting MCP servers, `BuildAgentEnv` scans the tool list for
|
|||
the reasoning server via `PlanBackendSetter`. This wiring runs on every agent
|
||||
start and `/agent` switch, so the task backend is always current.
|
||||
|
||||
If `task_create` is not found, `BuildAgentEnv` checks whether the caller
|
||||
supplied a fallback via `WithFallbackPlanBackend`. If so, that backend is wired
|
||||
instead. Priority: task MCP > caller fallback > nil (in-context only).
|
||||
|
||||
No frontend changes are needed to gain planning capability — add a task MCP
|
||||
server to the agent config and it works.
|
||||
|
||||
### Graceful degradation
|
||||
|
||||
- No task MCP server configured → `reasoning_plan` produces an in-context plan.
|
||||
- Task MCP server configured but 9beads not running → `task_create` fails,
|
||||
- No task MCP server configured, no fallback → `reasoning_plan` produces an
|
||||
in-context plan only.
|
||||
- No task MCP server configured, fallback supplied → steps are handed to the
|
||||
fallback backend (e.g. queued for sequential execution). See
|
||||
[Queue-based fallback](#queue-based-fallback) below.
|
||||
- Task MCP server configured but unreachable → `task_create` fails,
|
||||
`CreatePlan` returns an error, reasoning server degrades to in-context plan
|
||||
with a warning.
|
||||
- 9beads running and mounted → full persistence, steps get IDs, plan is durable.
|
||||
- Task MCP server running → full persistence, steps get IDs, plan is durable.
|
||||
|
||||
The agent's behavior is identical in all cases: call `reasoning_plan`, get a
|
||||
formatted plan, proceed. The persistence difference is transparent.
|
||||
|
||||
### Queue-based fallback
|
||||
|
||||
ollie-9p registers a `queuePlanBackend` as the fallback for every session. When
|
||||
`task_create` is absent, `reasoning_plan` writes each step as a queued prompt to
|
||||
the session's `enqueue` file in topological order (blockers before dependents).
|
||||
|
||||
Steps are returned as placeholder IDs (`q1`, `q2`, …) so the agent can refer to
|
||||
them in subsequent `reasoning_think` calls. The queue persists independently of
|
||||
context — unlike an in-context-only plan, steps survive compaction.
|
||||
|
||||
The goal description is prepended to the first enqueued step for context.
|
||||
Dependency annotations (`after: q1, q2`) are included in each step's prompt so
|
||||
the agent retains the relationship even if it processes steps across multiple
|
||||
turns.
|
||||
|
||||
Fan-out parallelism is achievable by spawning sub-sessions: the enqueued step
|
||||
can instruct the agent to create a child session per parallel branch, nudge each
|
||||
with its task via `prompt`, and have sub-agents write completion notifications
|
||||
back to the parent via `enqueue`.
|
||||
|
||||
### Shell-out for everything else
|
||||
|
||||
Queries, comments, bulk operations, event watching — all of these belong in
|
||||
|
|
|
|||
Reference in New Issue