Skip to content

Commit ec0fe9f

Browse files
committed
Add /doctor; remove /provider, /models-add and the advisor
- /doctor: health check with a pass/warn/fail line per subsystem — fd/rg/rtk, config files + warnings, provider + key source, model in the catalog, a live connectivity probe, MCP servers, session file, memory, hooks, LSP, telemetry, permissions - /provider and /models-add removed (one configured provider; presets were dead weight — the model_presets config field goes with them) - the advisor feature is removed entirely: tool, prompt, [advisor] config, /advisor, the setup-wizard opt-in; pierre remains the second-model feature (/pierre on) - docs (README, configuration, build-plan) updated to match
1 parent 9846f71 commit ec0fe9f

22 files changed

Lines changed: 262 additions & 845 deletions

README.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,8 +150,6 @@ non-tty `--setup`) · `3` max turns / max loop iterations.
150150
- **Hooks** — shell commands on lifecycle events (`PreToolUse`,
151151
`PostToolUse`, `Stop`, …) that return verdicts; they can only narrow
152152
permissions. `--hooks-test` dry-runs the pipeline.
153-
- **Advisor** — a second, stronger model the agent consults mid-task for
154-
strategy, with a per-session budget — or routed to *you* in handoff mode.
155153
- **Pierre mode** — when enabled, a second model reviews every finished
156154
task: it compares your request with the agent's result and tells you
157155
plainly whether it delivered. `/pierre on|off|model`.

docs/build-plan.md

Lines changed: 26 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ screen), talks to **OpenRouter** and any **generic OpenAI-compatible API** (loca
88
servers included), executes tools under a rich permission system, persists sessions, and
99
supports power features: subagents, MCP servers (with Exa and context7 auto-configured),
1010
git worktrees, skills, custom user-defined agents, LSP diagnostics, persistent memory,
11-
an advisor model, multimodal input, lifecycle hooks, session export, loop mode, prompt
12-
chaining.
11+
a post-task reviewer model, multimodal input, lifecycle hooks, session export, loop
12+
mode, prompt chaining.
1313

1414
**Mandatory session naming**: every interactive start asks for a session name up front,
1515
before the chat opens — the prompt cannot be skipped or left empty (Ctrl-C/Ctrl-D
@@ -73,10 +73,8 @@ DuckDuckGo web tools (Exa MCP instead), anonymous sessions.
7373
cap), daily logs, project scratchpad checklists, named notes; four tools
7474
(`memory_write/edit/read/search`, regex keyword search); compaction summaries flushed
7575
to the daily log; atomic writes + `.bak` backups; `/memory` commands
76-
- **Advisor**: a second "expert" model the agent calls mid-task for strategic guidance
77-
(`advisor` tool, own system prompt, context truncated to a KB budget, max-uses
78-
counter); human-handoff mode routes advisor calls to the user; `/advisor
79-
on|off|handoff|model|max-uses|context-limit`
76+
- **Pierre mode**: a post-task reviewer — a second model compares the user's request
77+
with the finished result and reports whether it delivered; `/pierre on|off|model`
8078
- **Multimodal input**: image/audio/PDF attachments via `/add` and the `@` picker
8179
(20 MB cap), sent as OpenAI-compatible content parts where the selected model
8280
supports them
@@ -144,8 +142,8 @@ portal.
144142
`[tools]`, `[ui]` (theme, thinking collapse, welcome shortcuts, hidden models),
145143
`[permissions]`, `[notifications]`, `[mcp]` (`enable_exa` default true,
146144
`enable_context7` default false, server table), `[lsp]` (server overrides),
147-
`[memory]`, `[advisor]`, `[hooks]` (event → handler commands), plus permission rule
148-
tables, colors, named model presets, custom provider definitions (name → base_url +
145+
`[memory]`, `[pierre]`, `[hooks]` (event → handler commands), plus permission rule
146+
tables, colors, custom provider definitions (name → base_url +
149147
api_key_env + headers).
150148
- **Providers**: OpenRouter (first-class preset: model catalog refresh, pricing,
151149
app-identity headers, caching) + generic OpenAI-compatible endpoints (Ollama, LM
@@ -163,7 +161,7 @@ portal.
163161
whitespace-normalized search/replace and CRC-anchored line addressing), `bash`
164162
(timeout, truncation, idle timeout, `rtk` output compaction), `grep` (regex + glob +
165163
context; implemented over `rg`), `find_files` (glob; implemented over `fd`); plus
166-
`list_dir`, `todo_write`, `lsp_diagnostics`, `advisor`, the four `memory_*` tools;
164+
`list_dir`, `todo_write`, `lsp_diagnostics`, the four `memory_*` tools;
167165
MCP-provided web search/fetch via Exa.
168166
- **Custom agents**: built-in primaries `build` (full access) and `plan` (read-only +
169167
ask), cycled with Tab and shown in the statusline; user agents from markdown files
@@ -193,11 +191,8 @@ portal.
193191
`memory_read` / `memory_search` (regex keyword search); compaction summaries appended
194192
to the daily log; atomic writes with `.bak` backups; `/memory show|edit|search|log`
195193
commands.
196-
- **Advisor**: `advisor` tool — the agent asks a (usually stronger) second model for
197-
strategic guidance mid-task; conversation context truncated head/tail to a configured
198-
KB budget; max-uses counter per session; `handoff` mode routes the advisor call to
199-
the human inline instead of a model; `/advisor on|off|handoff|model|max-uses|
200-
context-limit`.
194+
- **Pierre mode**: after every completed task, a second model compares the request
195+
with the result and gives feedback in the feed; `/pierre on|off|model`.
201196
- **Multimodal input**: `/add` and `@` accept image/audio/PDF files (20 MB cap);
202197
attachments sent as OpenAI-compatible `image_url` / document content parts; a clear
203198
error when the selected model lacks the modality; attachment list shown in the feed.
@@ -229,17 +224,17 @@ portal.
229224
queued prompts (Enter while running) + steer queue (Alt+Enter, priority, 5+5 limits);
230225
streaming markdown feed with syntax highlighting; collapsible thinking blocks;
231226
**fixed statusline** (session name · agent · model · git branch · context meter ·
232-
tokens · cost · state); braille spinner; inline permission prompt (y/a/n/ESC) and
233-
inline advisor-handoff prompt; 17+ JSON themes (`/theme`); OSC 8 hyperlinks;
227+
tokens · cost · state); braille spinner; inline permission prompt (y/a/n/ESC);
228+
17+ JSON themes (`/theme`); OSC 8 hyperlinks;
234229
clipboard (OSC 52 / pbcopy / xclip), `/copy`; audio notifications; `--no-color`.
235230
- **Slash commands** (~50): `/new /clear /resume /session /undo /redo /rewind /retry
236-
/rename /history /quit /exit /handoff /compact /compress /model /models /models-add
237-
/provider /thinking /reasoning /permissions /mode /toggle /theme /themes /prompt
231+
/rename /history /quit /exit /handoff /compact /compress /model /models
232+
/thinking /reasoning /permissions /mode /toggle /theme /themes /prompt
238233
/editsys /add /drop /drop-all /init /help /welcome
239234
/tutor /review /btw /queue /copy /export /import /share /loop /worktree /wt-exit
240-
/wt-merge /mcp /model-subagent /models-subagent /notifications /memory /advisor
241-
/hooks /agents` + skill-registered commands. Prefixes: `!cmd`, `!!cmd`, `.prompt`,
242-
`@file`, `@agent`.
235+
/wt-merge /mcp /model-subagent /models-subagent /notifications /memory /pierre
236+
/doctor /hooks /agents` + skill-registered commands. Prefixes: `!cmd`, `!!cmd`,
237+
`.prompt`, `@file`, `@agent`.
243238
- **Headless**: `-p [prompt]` (inline or stdin), tools auto-approved, final response to
244239
stdout, exit codes 0/1/2/3, auto-generated session name; `--loop` iterative mode
245240
against a plan file with optional per-iteration command and max iterations.
@@ -287,7 +282,7 @@ lecode/
287282
│ ├── agent/
288283
│ │ ├── runner.py # asyncio multi-turn streaming loop
289284
│ │ ├── builder.py # prompt assembly (minimal|rich), tool/skill/agent wiring
290-
│ │ └── tools/ # core tools (rg/fd/rtk backed) + task + advisor +
285+
│ │ └── tools/ # core tools (rg/fd/rtk backed) + task +
291286
│ │ # memory_* + MCP bridge
292287
│ ├── lsp/ # async JSON-RPC client, server registry, manager,
293288
│ │ # lsp_diagnostics tool
@@ -322,7 +317,7 @@ lecode/
322317

323318
- One `asyncio` loop; components communicate over `asyncio.Queue`s with a small event
324319
taxonomy (`Token / Reasoning / ToolCall / ToolResult / Error / Retrying / Done`, user
325-
input, permission ask/reply, advisor-handoff ask/reply). TUI never calls providers;
320+
input, permission ask/reply). TUI never calls providers;
326321
runner never renders.
327322
- Startup sequence (interactive): dependency check → config load → `--setup` if
328323
unconfigured → **session-name prompt** (loop until non-empty; Ctrl-C/Ctrl-D exits
@@ -332,8 +327,8 @@ lecode/
332327
steer queue is a second priority input queue drained first between turns.
333328
- One streaming client implementation (OpenAI Chat Completions with SSE via
334329
`httpx.AsyncClient.stream()` + line iteration); OpenRouter behavior is a thin preset
335-
layer over it (headers, catalog/pricing fetch, routing params). The advisor and
336-
subagents reuse the same client with different model/prompt params.
330+
layer over it (headers, catalog/pricing fetch, routing params). Subagents and the
331+
pierre reviewer reuse the same client with different model/prompt params.
337332
- External binaries: one shared async subprocess wrapper
338333
(`asyncio.create_subprocess_exec`, timeout, output caps) used by `grep` (rg),
339334
`find_files` (fd), `bash` (rtk), and the hook handlers. Presence verified once at
@@ -360,8 +355,8 @@ lecode/
360355
`uv run python -m pytest`; `respx` for HTTP-level mocking. CI runners install
361356
fd/ripgrep/rtk (or a shim for rtk) before the suite runs.
362357
- **Fake provider**: scripted streaming responder (text chunks, tool calls, errors) with
363-
request/history capture — headless end-to-end tests of the full agent loop. The
364-
advisor and subagents run against the same fake.
358+
request/history capture — headless end-to-end tests of the full agent loop. Pierre
359+
and subagents run against the same fake.
365360
- **Provider contract tests**: SSE decode, tool-call round-trips, multimodal payload
366361
shaping, retry classification, OpenRouter headers/catalog handling, error mapping,
367362
keyless local endpoints.
@@ -412,8 +407,8 @@ lecode/
412407
collapse, pickers (incl. session picker with delete), the fixed statusline, spinner,
413408
themes, inline permission prompt, clipboard, `/copy`, notifications, attachment
414409
display.
415-
9. **Slash commands + advisor + multimodal** — full command registry; advisor tool with
416-
handoff mode and `/advisor`; multimodal `/add` + `@` attachments with capability
410+
9. **Slash commands + pierre + multimodal** — full command registry; pierre post-task
411+
review (`/pierre`); multimodal `/add` + `@` attachments with capability
417412
checks.
418413
10. **Power features** — in order: subagents, prompt chaining, export/import/share,
419414
git worktrees, loop mode, status signals, LSP integration (registry, manager,
@@ -426,7 +421,7 @@ lecode/
426421

427422
## Sizing
428423

429-
Roughly 19–26k LOC of Python (memory ~1k, hooks ~1.2k, advisor ~0.4k, multimodal ~0.3k,
424+
Roughly 19–26k LOC of Python (memory ~1k, hooks ~1.2k, pierre ~0.2k, multimodal ~0.3k,
430425
custom agents ~0.8k, LSP ~0.8k on top of the ~14–19k base). Phases 2–5 are the critical
431426
path to a usable agent; phase 8 is the largest single chunk; MCP + LSP (phase 10) are
432427
the biggest extras.
@@ -442,5 +437,5 @@ the biggest extras.
442437
- End of phase 8: interactive start requires a session name (empty rejected, duplicate
443438
suffixed, abort leaves no session file); `-p` skips the prompt.
444439
- End of phase 11: clean-machine `uv tool install``--setup` → one real coding task
445-
completed (including one hook firing, one advisor call, one image attachment); suite
440+
completed (including one hook firing, one pierre review, one image attachment); suite
446441
green in CI.

docs/configuration.md

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ kind = "glob" # "glob" (default) or "regex"
111111

112112
Last match wins within a table; deny rules are unbypassable (even in `yolo`),
113113
and `ask` rules still prompt. Read-class tools (`read`, `grep`, `find_files`,
114-
`list_dir`, `lsp_diagnostics`, `memory_read`, `memory_search`, `advisor`,
114+
`list_dir`, `lsp_diagnostics`, `memory_read`, `memory_search`,
115115
`task`, and Exa/context7/grep.app MCP tools) are the only tools allowed in
116116
`readonly`. A 3rd identical consecutive call escalates Allow → Ask, the 4th
117117
is denied (doom-loop guard).
@@ -176,16 +176,6 @@ trouble never blocks the agent.
176176

177177
See [memory.md](memory.md).
178178

179-
## `[advisor]`
180-
181-
| field | default | meaning |
182-
|---|---|---|
183-
| `enabled` | `false` | the advisor tool + `/advisor` |
184-
| `model` | unset | advisor model id (defaults to the main model) |
185-
| `max_uses` | `5` | per-session call budget |
186-
| `context_limit_kb` | `32` | conversation context sent along |
187-
| `mode` | `"model"` | `model` \| `handoff` (ask the human inline) |
188-
189179
## `[pierre]`
190180

191181
Post-task reviewer: after every completed task, a second model compares the
@@ -210,10 +200,8 @@ Events: `PreToolUse`, `PostToolUse`, `UserPromptSubmit`, `Stop`,
210200
`SessionStart`, `SessionEnd`, `SubagentStart`, `SubagentEnd`. Hooks can only
211201
narrow permission verdicts. See [hooks.md](hooks.md).
212202

213-
## `[model_presets]`, `[custom_providers]`
203+
## `[custom_providers]`
214204

215-
- `[model_presets]``alias = "model-id"` shortcuts added to `/models`
216-
(`/models-add` writes here).
217205
- `[custom_providers.<name>]` — extra OpenRouter-compatible providers:
218206

219207
```toml

src/lecode/agent/builder.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -88,12 +88,9 @@ def build_runtime(
8888
)
8989

9090
tools = core_tools()
91-
# The advisor and task tools are always registered; a disabled advisor
92-
# reports how to enable, and task needs no configuration at all.
93-
from lecode.agent.tools import advisor as advisor_tool
91+
# The task tool is always registered; it needs no configuration at all.
9492
from lecode.agent.tools import task as task_tool
9593

96-
tools.append(advisor_tool.make_tool())
9794
tools.append(task_tool.make_tool())
9895
if config.memory.enabled:
9996
memory_store = MemoryStore(memory_root(cwd), max_bytes=config.memory.max_bytes)

0 commit comments

Comments
 (0)