Guide: Adding a New LLM Provider
The Agenthood is LLM-agnostic by design. Adding a new provider means
implementing one interface and registering it in two places.
Overview
Every provider lives in src/llm/providers/ and implements ILLMProvider.
Once registered, the provider is available in the failover chain, configurable
via .agenthood/config.json, and routeable per member.
Step-by-step
1. Create the provider file
2. Implement ILLMProvider
You must implement all five methods:
| Method | Signature | What it does |
|---|---|---|
complete | (request: LLMRequest) => Promise<LLMResponse> | Synchronous text generation |
stream | (request: LLMRequest) => Promise<AsyncGenerator<LLMChunk>> | Streaming text generation |
embed | (text: string) => Promise<number[]> | Vector embedding (may throw UnsupportedOperationError) |
getContextWindow | () => number | Max context window in tokens |
setModel | (model: string) => void | Switch model at runtime (for Strategy 4 downgrade) |
3. Follow the constructor pattern
- Accept
LLMConfigas the sole constructor argument - Read credentials from
config.apiKeyfirst, then fall back toprocess.env - Use
undefinedinstead of''as the final fallback for SDK clients that reject empty strings in the constructor (e.g., OpenAI SDK v6+) - Store
config.model(with a sensible default)
4. Map SDK errors to Agenthood error classes
Wrap SDK calls and translate provider-specific errors into the canonical types
in src/llm/errors.ts:
| SDK error | Map to | Effect |
|---|---|---|
| 401 / invalid auth | AuthError | Permanent circuit trip |
| 402 / quota | PaymentRequiredError | Permanent circuit trip |
| 429 / rate limit | RateLimitedError | Cooldown + retry |
| 408 / timeout | TimeoutError | Retry with backoff |
| 503 / down | ServiceUnavailableError | Failover |
| 404 / bad model | ModelNotFoundError | Skip to next fallback model |
Example:
5. Register the provider factory in LLMRouter
Add a lazy-loaded factory to LLMRouter.providerFactories insrc/llm/LLMRouter.ts:
The key (opencode) becomes the provider name used in config files and on the CLI.
6. Add to the config example
Update .agenthood/config.example.json with an example entry:
For the failover chain with model fallback:
7. Verify it works
| Check | Command |
|---|---|
| No type errors | npx tsc --noEmit |
| Basic completion | npx agenthood run the-scribe "hello" --provider opencode |
| All tests pass | npx vitest run --exclude 'vscode-extension/**' |
| Failover triggers | Configure a bad API key for OpenCode + working Groq backup |
Checklist
- File created at
src/llm/providers/<Name>Provider.ts - All five
ILLMProvidermethods implemented - Error mapping covers 401/402/429/408/503/404
- Factory registered in
LLMRouter.providerFactories -
embed()throwsUnsupportedOperationErrorif not supported - No type errors
- Provider works with
npx agenthood runvia--provider - Provider participates in failover chain when configured