docs: v2.3 provider-lifecycle closeout (Phase 6)
BOOCODER.md gains a Provider lifecycle section (config file + schema, gitignored-with-exception, the 24h PROVIDER_PROBE_TTL_MS refresh contract, enable/disable via Settings → Providers, custom-ACP add, native boocode always-on, the honest subset-refresh known limitation, deploy + smoke). docs/DEFERRED-WORK.md §2 (cold-probe skip) marked ADDRESSED with the still- deferred Tier-2 follow-ups listed. CHANGELOG gets the v2.5.13 batch-closeout entry. Docs only — no code. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
78
BOOCODER.md
78
BOOCODER.md
@@ -37,3 +37,81 @@ Every file modification queues in `pending_changes` before touching disk. The us
|
||||
- Never count `dist/` directory sizes as source lines. Only count `src/**/*.ts` files. Compiled output is inflated by inlined types and transpilation artifacts.
|
||||
- Before claiming a feature works, run the actual command and show the output. "Should work" is not verification. Acceptable evidence: test output (`pnpm test`), build output (`pnpm build`), curl response, docker logs, `\d tablename` output. If you can't run it, say so explicitly — don't assert success without evidence.
|
||||
- When reporting counts (tools, tests, files, routes, lines), derive the number from a command (`grep -c`, `wc -l`, test runner output) — not from memory or approximation.
|
||||
|
||||
## Provider lifecycle (v2.3)
|
||||
|
||||
BooCoder's coding agents are a **config-backed registry**: built-ins live in `provider-registry.ts`, and `data/coder-providers.json` layers overrides + custom entries on top. Registration ≠ installation — the config lists what you *want*; a probe reports what's *ready*.
|
||||
|
||||
### Config file: `data/coder-providers.json`
|
||||
|
||||
Resolved from `CODER_PROVIDERS_PATH` (default `/data/coder-providers.json`; dev/host path `/opt/boocode/data/coder-providers.json`). It is **tracked in git** via a `.gitignore` exception (the rest of `data/*` is ignored). A missing file, invalid JSON, or a schema mismatch all fall back to built-ins-only — loading never throws at startup.
|
||||
|
||||
```json
|
||||
{
|
||||
"providers": {
|
||||
"goose": { "enabled": false },
|
||||
"amp-acp": {
|
||||
"extends": "acp",
|
||||
"label": "Amp",
|
||||
"description": "ACP wrapper for Amp",
|
||||
"command": ["amp-acp"],
|
||||
"enabled": true
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Per-provider override fields (all optional):
|
||||
|
||||
| Field | Meaning |
|
||||
|-------|---------|
|
||||
| `extends` | `"acp"` — required for a NEW (custom) provider; built-in overrides omit it |
|
||||
| `label` | Display name (required for custom) |
|
||||
| `description` | Sub-label shown in the picker / settings |
|
||||
| `command` | `[binary, ...args]` to spawn (required for custom; overrides a built-in's default argv) |
|
||||
| `env` | Extra env vars merged into the spawn |
|
||||
| `enabled` | Default `true`; `false` hides it from the composer |
|
||||
| `order` | UI sort key |
|
||||
| `models` / `additionalModels` | Replace / merge onto the discovered model list |
|
||||
|
||||
A PATCH to one provider id **replaces that id's override object wholesale** (per-id shallow merge), so to flip a single field keep the rest; a `null` value for an id deletes its override (reverts to the built-in default).
|
||||
|
||||
### Refresh contract
|
||||
|
||||
The snapshot is cached and a provider's cold ACP probe (tier-2) is **skipped** while `available_agents.last_probed_at` is younger than `PROVIDER_PROBE_TTL_MS` (default `86400000` = 24h). Opening the composer is therefore fast and does not re-probe. To force a cold re-probe (after installing a CLI or editing models): **`POST /api/providers/refresh`** (the Refresh button in the Providers settings tab), which clears the cache and re-probes.
|
||||
|
||||
### Enable / disable
|
||||
|
||||
Two ways:
|
||||
- **Settings → Providers tab** — open the sidebar → **Settings** → **Providers**: toggle a provider on/off, refresh it, or open its diagnostic. (Earlier builds exposed a gear in the composer; that control was moved into Settings.)
|
||||
- **Edit the config** (`"enabled": false`) then `POST /api/providers/refresh`.
|
||||
|
||||
A **disabled** provider leaves the composer's provider picker but stays listed in the Providers tab (status "Disabled") so you can re-enable it. **Native `boocode` is always-on** — an `enabled:false` on it is ignored (with a warn log) and it is never rendered as toggleable.
|
||||
|
||||
### Adding a custom ACP provider
|
||||
|
||||
- **Catalog modal**: Providers tab → **Add provider** → pick an entry → it PATCHes the config (`extends:'acp'` + label + command, enabled) and refreshes that provider.
|
||||
- **Hand-edit** `data/coder-providers.json`: add an id with `extends:'acp'`, `label`, and `command`, then `POST /api/providers/refresh`.
|
||||
|
||||
Either way, **adding to config does NOT install the binary.** Until the CLI is on `PATH` the provider shows **"Not installed"** (status `unavailable`) and does not appear in the composer picker.
|
||||
|
||||
### Known limitation — subset refresh
|
||||
|
||||
`POST /api/providers/refresh` accepts an optional `{ "providers": ["id", ...] }` body and returns a `refreshed` count scoped to that subset — **but the underlying cold re-probe currently covers ALL installed providers**, not just the requested subset. True per-provider force is a future change (it needs a snapshot-internal parameter). This is intentional for now, not a bug: a subset refresh still re-probes everything; only the reported count is scoped.
|
||||
|
||||
### Deploy + smoke
|
||||
|
||||
Two deploy targets:
|
||||
- **Routes (host service):** `pnpm -C apps/server build && pnpm -C apps/coder build && sudo systemctl restart boocoder`
|
||||
- **Web UI (container):** `docker compose up --build -d boocode`
|
||||
|
||||
Green gate (verified across phases 1–5): `pnpm -C apps/coder test` (134 passing) `&& pnpm -C apps/coder build`.
|
||||
|
||||
Smoke (via Tailscale):
|
||||
|
||||
```bash
|
||||
curl http://100.114.205.53:9502/api/providers/snapshot # lists every registered provider
|
||||
curl http://100.114.205.53:9500/api/coder/providers/config # raw config, through the BooChat proxy
|
||||
# Settings → Providers: disable goose → it leaves the composer picker, stays in the tab
|
||||
# POST refresh → models repopulate; Add a catalog entry → it appears after refresh (unavailable until its CLI is installed)
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user