Provider Patterns
SkillAI & modelsConfigure per-provider behavior, understand streaming quirks, and use the 5-hook adapter system for optimal performance across LLM providers.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the Provider Patterns skill
What this skill tells your AI
The instructions your AI receives, as published by tylerjrbuell/reactive-agents-ts in apps/docs/skills/provider-patterns/SKILL.md and read by ahel’s review.
Agent objective
Produce a builder with the correct provider + model + any provider-specific configuration; know which providers need special handling for streaming and tool calls.
When to load this skill
- Configuring a non-Anthropic provider
- Debugging tool call or streaming issues specific to one provider
- Using local models (Ollama) or proxy routing (LiteLLM)
- Enabling extended thinking or provider-specific model options
Implementation baseline
// Anthropic — highest quality, native FC, prompt caching
const agent = await ReactiveAgents.create()
.withProvider("anthropic")
.withModel("claude-sonnet-4-6")
.withReasoning({ defaultStrategy: "adaptive" })
.withTools()
.build();
// Local Ollama model
const agent = await ReactiveAgents.create()
.withProvider("ollama")
.withModel("qwen2.5:7b")
.withReasoning({ defaultStrategy: "reactive", maxIterations: 6 })
.withTools({ allowedTools: ["web-search"] })
.build();
Provider selection guide
| Provider | Best for | Key notes |
|---|---|---|
"anthropic" | Production, highest quality | Native FC, prompt caching, streaming |
"openai" | GPT-4o, broad compatibility | Native FC, streaming |
"gemini" | Multimodal, long context | Native FC; functionResponse.name quirk |
"ollama" | Local, privacy-first | Tool calls arrive on chunk.done |
"litellm" | Proxy routing, cost optimization | OpenAI-compatible; use for Groq, OpenRouter, etc. |
"test" | Unit tests, CI | Returns deterministic mock responses |
Key patterns
Extended thinking (Anthropic)
.withProvider("anthropic")
.withModel({ model: "claude-opus-4-6", thinking: true })
// Enables extended thinking — model reasons before responding
// Higher quality on complex reasoning tasks; adds latency and cost
LiteLLM for provider routing
// Groq, OpenRouter, Bedrock, Vertex — all through LiteLLM
.withProvider("litellm")
.withModel("groq/llama-3.1-70b-versatile")
// Model name format: "provider/model-name" as per LiteLLM docs
Circuit breaker for unreliable providers
.withProvider("ollama")
.withModel("llama3:8b")
.withCircuitBreaker({
failureThreshold: 3, // open after 3 consecutive failures
cooldownMs: 30_000, // wait 30s before half-open probe
halfOpenRequests: 1,
})
.withRateLimiting({ requestsPerMinute: 10 })
Enabling temperature and sampling
.withModel({ model: "gpt-4o", temperature: 0.2 }) // more deterministic
.withModel({ model: "claude-sonnet-4-6", temperature: 0.9 }) // more creative
5 adapter hooks (automatic — no configuration needed)
These hooks run automatically and adapt prompts/behavior for each provider's strengths:
| Hook | What it does |
|---|---|
continuationHint | Tells the model to continue after tool results while required tools are pending |
errorRecovery | Recovery prompt appended to the observation on tool errors |
synthesisPrompt | Final answer synthesis guidance on the research→produce transition |
qualityCheck | Post-step quality assessment (fires once before the final answer) |
parseToolCalls | Normalizes malformed native tool calls (e.g. qwen3 stringified arguments) in every provider complete()/stream() response |
Adapter selection is automatic via selectAdapter(capabilities, tier). Each provider (Anthropic, OpenAI, Gemini, Ollama) has an adapter with specialized implementations.
Builder API reference
| Method | Key params | Notes |
|---|---|---|
.withProvider(p) | "anthropic"|"openai"|"gemini"|"ollama"|"litellm"|"test" | Required |
.withModel(m) | string | { model, thinking?, temperature? } | thinking: true = extended reasoning |
.withCircuitBreaker(cfg?) | { failureThreshold?, cooldownMs?, halfOpenRequests? } | Auto-retry with backoff |
.withRateLimiting(cfg) | { requestsPerMinute?, tokensPerMinute?, maxConcurrent? } |
Pitfalls
"groq"and"openrouter"are not valid provider names — use"litellm"with the appropriate model prefix- Gemini:
functionResponse.namemust usemsg.toolName, not hard-coded"tool"— framework handles this but custom tool parsers must follow the same pattern - Ollama: tool_calls arrive on
chunk.done, not during the stream — don't parse mid-stream chunks for tool calls - Anthropic streaming: use raw
streamEvent, not helper events (inputJsonfires beforecontentBlockin streaming FC) thinking: truerequires a model that supports extended thinking — verify model capability before enabling- LiteLLM model names are
"provider/model"format — check LiteLLM docs for exact names
Signals
- GitHub stars
- 27
- Forks
- 4
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
provider-patterns- Source
- github.com/tylerjrbuell/reactive-agents-ts