Adding a Provider
A provider is an adapter that turns BOR’s canonical messages into a vendor’s wire format and streams the reply back. Add one by writing the adapter and registering it.1. Write the adapter
Createserver/providers/myvendor.js exporting the common shape:
What stream must do
- Yield text chunks as they arrive (it’s an async generator).
- Respect the abort
signal. - Translate canonical messages — including
tool_use/tool_resultblocks and image blocks — to the vendor’s shape. Use the shared helpers inserver/providers/multimodal.js,sse-util.js, andlimits.jsso multimodal and streaming behave like every other provider.
2. Register it
Add your adapter toALL_PROVIDERS in server/providers/index.js. That’s what makes it appear in onboarding (publicCatalog()), which must keep working — onboarding and the public catalog depend on it.
3. Test it
- Re-run onboarding and pick My Vendor; enter a key (and base URL if
needsBaseUrl). - Run a simple turn (
<say>should stream). - Run a multimodal turn (attach a screenshot) to confirm image handling.
- Confirm a tool turn (e.g.
write_file) round-trips — the model must read<tool_results>and continue.
Conventions
- Provider parity. Your provider must be a first-class peer — never a second-class adapter. The chat loop, tools, surfaces, and bridge must behave identically.
- Model ids go stale. Don’t hardcode an old id as the default; fetch the vendor’s live docs and pick a current model.
- Caching. If the vendor supports prompt/context caching, wire it through the shared prompt-cache layer where the new harness uses it.
- Vision. If the vendor has a vision model, image-driven features (
locate_screen_element, browser/screenshot feedback) work; if it’s text-only, they won’t.
Checklist
- Adapter exports
{ id, label, defaultModel, models, signupUrl, needsBaseUrl, stream }. -
streamyields text deltas, respectssignal, handles image blocks. - Registered in
ALL_PROVIDERS(server/providers/index.js). - Appears in onboarding; simple + multimodal + tool turns all work.