Ship Paseo-equivalent provider snapshot, AgentComposerBar, ACP dispatch rewrite with streaming/persist, permission prompts, and agent commands. Follow-up: pane-scoped chat resolution, CoderMessageList tool timeline, WS user-delta replace, and inference orphan tool_call stripping. Archive openspec v2-2; update CHANGELOG and CURRENT. Co-authored-by: Cursor <cursoragent@cursor.com>
3.7 KiB
3.7 KiB
v2.3 Provider lifecycle — tasks
Implement in phase order from design.md. Do not commit unless Sam asks.
Phase 1 — Config + registry
- 1.1 Add
CODER_PROVIDERS_PATHtoapps/coder/src/config.ts(default/data/coder-providers.json) - 1.2 Add
data/coder-providers.jsonexample + wire inapps/coder/.env.host - 1.3 Implement
provider-config.ts(Zod schema + load/merge/save) - 1.4 Implement
provider-config-registry.ts(buildResolvedRegistry, module singleton + reload) - 1.5 Unit tests: built-in override, custom ACP add, enabled false, invalid entry skipped
- 1.6 Update
agent-probe.tsto iterate resolved registry (include custom ids, respect enabled)
Phase 2 — Snapshot lifecycle
- 2.1 Extend
ProviderSnapshotEntry/ status union in coder + web types (loading,unavailable,enabled) - 2.2 Add
command-availability.ts(isCommandAvailable) - 2.3 Rewrite
buildProviderEntry: never return null; handle disabled/uninstalled/loading - 2.4 Implement tier-2 skip using
available_agents.last_probed_at+PROVIDER_PROBE_TTL_MS - 2.5 Return
loadingentries synchronously on cache miss; complete via inflight promise - 2.6 Extend
provider-snapshot.test.tsfor disabled, uninstalled, fresh DB skip, force refresh - 2.7 Verify warm cache: second snapshot call does not invoke
probeAcpProvider(mock assert)
Phase 3 — Generic dispatch
- 3.1 Add
resolveLaunchSpec()toacp-spawn.ts - 3.2 Wire
acp-dispatch.tsto use launch spec + env merge - 3.3 Wire
dispatcher.tsto load resolved def by agent name - 3.4 Unit test: custom command argv reaches spawn
- 3.5 Smoke: task dispatch for one custom catalog provider (if installed on host)
Phase 4 — HTTP API
- 4.1
GET /api/providers/config - 4.2
PATCH /api/providers/config(merge + write file + reload registry + clear snapshot cache) - 4.3
POST /api/providers/refreshoptional body{ providers?: string[] } - 4.4
GET /api/providers/:id/diagnostic(plaintext report) - 4.5 Extend
apps/web/src/api/client.tscoder namespace - 4.6 Confirm BooChat proxy forwards new routes (or document direct :9502)
Phase 5 — Web UI
- 5.1 Create
apps/web/src/data/acp-provider-catalog.ts(5–10 curated entries) - 5.2
AddProviderModal.tsx— search, install → patch + refresh subset - 5.3
ProviderSettingsDrawer.tsx— list, status, toggle, refresh, link to add - 5.4 Entry point from CoderPane / AgentComposerBar (gear or settings link)
- 5.5 Filter
AgentComposerBarselectable providers (enabled && ready) - 5.6 Loading state while snapshot entries
loading(poll or one-shot refetch) - 5.7
npx tsc -p apps/web/tsconfig.app.json --noEmit
Phase 6 — Docs, deploy, closeout
- 6.1
BOOCODER.md— config file, refresh contract, enable/disable - 6.2 Update
docs/DEFERRED-WORK.md— mark tier-2 cold-probe item addressed - 6.3
CHANGELOG.mdentry when tagged - 6.4
pnpm -C apps/coder test && pnpm -C apps/coder build - 6.5
sudo systemctl restart boocoder - 6.6 Smoke via Tailscale:
curl http://100.114.205.53:9502/api/providers/snapshot- PATCH disable goose → absent from composer, visible in settings
- POST refresh → models repopulate
- Add catalog entry → appears after refresh
Optional (same batch if time)
- O.1 WS frame
provider_snapshot_updated(skip polling) - O.2
available_agents.enabledcolumn mirror - O.3 Diagnostic sheet UI (row click → modal)
Explicitly out of scope
- Port Paseo
ACPAgentClient/ per-provider SDK clients (see design §12) - Full 30+ ACP catalog
- MCP
list_providerstools - Voice providers