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

FieldTypeDescription
textstringResponse text (null if tool_calls)
modelUsedstringWhich model responded
latencyMsnumberTotal time including fallbacks
toolCallsToolCall[]Structured tool call requests

Fallback Behavior

Styrr intelligently decides when to fall back based on HTTP status codes:

StatusBehaviorDescription
429FallbackRate limited — try next model
404FallbackModel removed — try next
402FallbackNo credits — try next
401ThrowAuth error — fail fast
5xxFallbackServer 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:

OpenRouterhttps://openrouter.ai/api/v1Default
OpenAIhttps://api.openai.com/v1
Ollama (local)http://localhost:11434/v1
NVIDIA NIMhttps://integrate.api.nvidia.com/v1

Error 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');
  },
});