diff --git a/docs/prds/0052-user-provider-plugins.md b/docs/prds/0052-user-provider-plugins.md new file mode 100644 index 0000000..a02ad72 --- /dev/null +++ b/docs/prds/0052-user-provider-plugins.md @@ -0,0 +1,186 @@ +# PRD 0052: User-defined agent provider plugins + +- **Status:** Draft +- **Author:** claude +- **Created:** 2026-06-04 + +## Summary + +The `get_provider()` registry in `bot_bottle/agent_provider.py` is a closed list — +only `"claude"` and `"codex"` are valid templates, validated at manifest-load time and +again at launch. Users who want to run a different agent (Gemini, Aider, a custom +local model wrapper) cannot add a provider without forking the package. + +This PRD opens the registry to user-defined plugins. A plugin placed at +`~/.bot-bottle/contrib//agent_provider.py` is discovered and loaded at launch +time. The manifest accepts any non-empty template string that names a built-in or +resolves to a user plugin at that path. No changes to the built-in providers or the +internal `bot_bottle/contrib/` layout. + +The preceding commit on this PR moves `codex_auth.py` from `bot_bottle/` into +`bot_bottle/contrib/codex/` — a clean-up that fits naturally here since this PR +also clarifies that `contrib/` is the per-provider home. + +## Problem + +Users building unconventional setups hit a hard wall: the template validation in +`manifest_agent.AgentProvider.from_dict` rejects any string not in `PROVIDER_TEMPLATES`. +There is no escape hatch short of editing bot-bottle's source. + +PRD 0050 moved provider logic into `contrib/` specifically so a third provider would +be "cheap to add" — but "cheap" today still means a pull request against the bot-bottle +repo, not a drop-in file in the user's home directory. The filesystem layout is already +the right shape; the discovery step is missing. + +## Goals / Success Criteria + +1. A user places `~/.bot-bottle/contrib//agent_provider.py` — a file that exports + a class inheriting `AgentProvider` — sets `agent_provider.template: ` in a + bottle's frontmatter, and launches a bottle using that provider with no changes to + the bot-bottle source. +2. The manifest validator accepts any non-empty template string. Unknown templates that + resolve to no user plugin still raise a clear error, but at launch (via `get_provider`) + rather than at manifest-load time. +3. Built-in provider knobs (`auth_token` → claude only; `forward_host_credentials` → + codex only) are guarded to built-in template names. Bottles using a user provider + may set neither knob. +4. `get_provider(template)` checks `~/.bot-bottle/contrib/