Installation
npm install @carloscortezcloud/styrr-llm
Basic Setup
Create a router with an ordered list of models. Styrr tries each one sequentially:
import { StyrRouter } from '@carloscortezcloud/styrr-llm';
const router = new StyrRouter({
apiKey: process.env.OPENROUTER_API_KEY,
models: [
{ id: 'nvidia/nemotron-3-ultra-550b:free' },
{ id: 'google/gemma-4-31b-it:free' },
{ id: 'meta-llama/llama-3.3-70b-instruct:free' },
],
});
// Call the LLM
const result = await router.call([
{ role: 'user', content: 'Explain FinOps in 2 sentences' }
]);
console.log(result.text); // "FinOps is..."
console.log(result.modelUsed); // which model responded
console.log(result.latencyMs); // total time including fallbacks
With Tool Calling
Pass tool schemas with the messages:
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 (result.toolCalls) {
// LLM requested tool calls
for (const tool of result.toolCalls) {
console.log(tool.function.name, tool.function.arguments);
}
}
Return Value
interface RouterResult {
text: string | null; // Response text (null if tool_calls)
modelUsed: string; // Which model responded
latencyMs: number; // Total time including fallbacks
toolCalls: ToolCall[]; // Tool call requests from LLM
}
Fallback Behavior
| Status | Behavior |
|---|---|
| 429 (rate limit) | Fallback to next model |
| 404 (removed) | Fallback to next model |
| 402 (no credits) | Fallback to next model |
| 401 (auth) | Throw immediately |
| 5xx | Fallback to next model |
Use onFallback and onAllFailed hooks for observability.