# 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/