Styrr
@carloscortezcloud/styrr-llm
Multi-model LLM router with automatic ordered fallback. Try model A, if it fails → B → C. Zero config. Zero deps.
StyrRouter
The main class. Define your model chain — Styrr tries each model sequentially until one succeeds.
import { StyrRouter } from '@carloscortezcloud/styrr-llm';
const router = new StyrRouter({
apiKey: process.env.OPENROUTER_API_KEY, // From env
models: [ // Ordered — first available wins
{ id: 'nvidia/nemotron-3-ultra-550b:free' },
{ id: 'google/gemma-4-31b-it:free' },
{ id: 'meta-llama/llama-3.3-70b-instruct:free' },
],
baseUrl: 'https://openrouter.ai/api/v1', // Optional: default OpenRouter
onFallback: (model, error, next) => // Optional: observability
console.log(`${model} failed → ${next}`),
onAllFailed: (errors) => // Optional: all models failed
console.error('All models failed', errors),
});Methods
router.call(messages, tools?)Call the LLM chain with messages. Optionally pass tool schemas.
const result = await router.call([
{ role: 'user', content: 'Hello' }
]);
// → { text, modelUsed, latencyMs, toolCalls }RouterResult
| Field | Type | Description |
|---|---|---|
text | string | Response text (null if tool_calls) |
modelUsed | string | Which model responded |
latencyMs | number | Total time including fallbacks |
toolCalls | ToolCall[] | Structured tool call requests |
Fallback Behavior
Styrr intelligently decides when to fall back based on HTTP status codes:
| Status | Behavior | Description |
|---|---|---|
429 | Fallback | Rate limited — try next model |
404 | Fallback | Model removed — try next |
402 | Fallback | No credits — try next |
401 | Throw | Auth error — fail fast |
5xx | Fallback | Server error — try next |
Tool Calling
Pass tool schemas to let the LLM request tool calls. Styrr normalizes camelCase ↔ snake_case automatically.
const result = await router.call(messages, [
{
name: 'get_weather',
description: 'Get weather for a city',
parameters: {
type: 'object',
properties: { city: { type: 'string' } },
required: ['city'],
},
}
]);
// If LLM calls the tool:
console.log(result.toolCalls);
// → [{ function: { name: 'get_weather', arguments: { city: 'Lima' } } }]Provider Compatibility
Any provider with an OpenAI-compatible API. Just set baseUrl:
OpenRouter
https://openrouter.ai/api/v1DefaultOpenAI
https://api.openai.com/v1Ollama (local)
http://localhost:11434/v1NVIDIA NIM
https://integrate.api.nvidia.com/v1Error Handling
Styrr never throws on model errors — it falls back silently. Use hooks to observe:
const router = new StyrRouter({
apiKey: process.env.OPENROUTER_API_KEY,
models: [/* ... */],
onFallback: (model, error, next) => {
// Log fallback events to your observability system
console.warn(`${model} failed: ${error.message}`);
},
onAllFailed: (errors) => {
// All models exhausted — throw a custom error or return a fallback response
throw new Error('All LLM models unavailable');
},
});