
openrouter-kit
Powerful & flexible TypeScript SDK for the OpenRouter API. Streamlines building LLM applications with easy chat, adapter-based history, secure tool calling (function calling), cost tracking, and plugin support.
Stars: 59

OpenRouter Kit is a powerful TypeScript/JavaScript library for interacting with the OpenRouter API. It simplifies working with LLMs by providing a high-level API for chats, dialogue history management, tool calls with error handling, security module, and cost tracking. Ideal for building chatbots, AI agents, and integrating LLMs into applications.
README:
π·πΊ Π ΡΡΡΠΊΠΈΠΉ | π¬π§ English
OpenRouter Kit is a powerful, flexible, and user-friendly TypeScript/JavaScript library for interacting with the OpenRouter API. It significantly simplifies working with LLMs by providing a high-level API for chats, automatic dialogue history management (when an adapter is configured), seamless handling of tool calls (function calling) with structured error handling, a robust and configurable security module, and optional request cost tracking. It's ideal for building chatbots, AI agents, and integrating LLMs into your applications.
-
Simplicity: Complex API interactions, history management, and tool handling are hidden behind a simple
client.chat()
method. - Flexibility: Configure models, generation parameters, history storage (requires adapter), security, and much more.
- Security: The built-in security module helps protect your applications and users when using tools.
- Extensibility: Use plugins and middleware to add custom logic without modifying the library core.
- Reliability: Fully typed with TypeScript, predictable error handling (including structured tool errors), and resource management.
- π Key Features
- π¦ Installation
- β¨ Basic Usage
- π Example: Taxi Bot
- βοΈ API and Concepts
- π License
-
π€ Universal Chat: Simple and powerful API (
client.chat
) for interacting with any model available via OpenRouter.- Returns a structured
ChatCompletionResult
object with content (content
), token usage info (usage
), model used (model
), number of tool calls (toolCallsCount
), finish reason (finishReason
), execution time (durationMs
), request ID (id
), and calculated cost (cost
, optional).
- Returns a structured
-
π History Management (via Adapters): Requires
historyAdapter
configuration. Automatic loading, saving, and (potentially) trimming of dialogue history for each user or group whenuser
is passed toclient.chat()
.- Flexible history system based on adapters (
IHistoryStorage
). - Includes built-in adapters for memory (
MemoryHistoryStorage
) and disk (DiskHistoryStorage
, JSON files). Exported from the main module. - Easily plug in custom adapters (Redis, MongoDB, API, etc.) or use the provided plugin (
createRedisHistoryPlugin
). - Configure cache TTL and cleanup intervals via client options (
historyTtl
,historyCleanupInterval
). History limit management is delegated to the adapter.
- Flexible history system based on adapters (
-
π οΈ Tool Handling (Function Calling): Seamless integration for model-invoked calls to your functions.
- Define tools using the
Tool
interface and JSON Schema for argument validation. - Automatic argument parsing, schema validation, and security checks.
- Execution of your
execute
functions with context (ToolContext
, includinguserInfo
). - Automatic sending of results back to the model to get the final response.
-
Structured Tool Error Handling: Errors occurring during parsing, validation, security checks, or tool execution are formatted as a JSON string (
{"errorType": "...", "errorMessage": "...", "details": ...}
) and sent back to the model in therole: 'tool'
message, potentially allowing the LLM to understand and react to the issue better. - Configurable limit on the maximum number of tool call rounds (
maxToolCalls
) to prevent infinite loops.
- Define tools using the
-
π‘οΈ Security Module: Comprehensive and configurable protection for your applications.
-
Authentication: Built-in JWT support (generation, validation, caching) via
AuthManager
. Easily extensible for other methods (api-key
,custom
). -
Access Control (ACL): Flexible configuration of tool access (
AccessControlManager
) based on roles (roles
), API keys (allowedApiKeys
), permissions (scopes
), or explicit rules (allow
/deny
). Default policy (deny-all
/allow-all
). -
Rate Limiting: Apply limits (
RateLimitManager
) on tool calls for users or roles with configurable periods and limits. Important: The defaultRateLimitManager
implementation stores state in memory and is not suitable for distributed systems (multiple processes/servers). Custom adapters or plugins using external storage (e.g., Redis) are required for such scenarios. -
Argument Sanitization: Checks (
ArgumentSanitizer
) tool arguments for potentially dangerous patterns (SQLi, XSS, command injection, etc.) using global, tool-specific, and custom rules. Supports audit-only mode (auditOnlyMode
). -
Event System: Subscribe to security events (
access:denied
,ratelimit:exceeded
,security:dangerous_args
,token:invalid
,user:authenticated
, etc.) for monitoring and logging.
-
Authentication: Built-in JWT support (generation, validation, caching) via
-
π Cost Tracking: (Optional)
- Automatic calculation of approximate cost for each
chat()
call based on token usage (usage
) and OpenRouter model pricing. - Periodic background updates of model prices from the OpenRouter API (
/models
). -
getCreditBalance()
method to check your current OpenRouter credit balance. - Access cached prices via
getModelPrices()
.
- Automatic calculation of approximate cost for each
-
βοΈ Flexible Configuration: Configure API key, default model, endpoint (
apiEndpoint
for chat, base URL for other requests determined automatically), timeouts, proxy, headers (Referer
,X-Title
), fallback models (modelFallbacks
), response format (responseFormat
), tool call limit (maxToolCalls
), cost tracking (enableCostTracking
), history adapter (historyAdapter
), and many other parameters viaOpenRouterConfig
. - π‘ Typing: Fully written in TypeScript, providing strong typing, autocompletion, and type checking during development.
-
π¦ Error Handling: Clear hierarchy of custom errors (
APIError
,ValidationError
,SecurityError
,RateLimitError
,ToolError
,ConfigError
, etc.) inheriting fromOpenRouterError
, with codes (ErrorCode
) and details for easy handling. Includes amapError
function for normalizing errors. -
π Logging: Built-in flexible logger (
Logger
) with prefix support and debug mode (debug
). - β¨ Ease of Use: High-level API hiding the complexity of underlying interactions with LLMs, history, and tools.
-
π§Ή Resource Management:
client.destroy()
method for proper resource cleanup (timers, caches, event listeners), preventing leaks in long-running applications. -
π§© Plugin System: Extend client capabilities without modifying the core.
- Support for external and custom plugins via
client.use(plugin)
. - Plugins can add middleware, replace managers (history, security, cost), subscribe to events, and extend the client API.
- Support for external and custom plugins via
-
π Middleware Chain: Flexible request and response processing before and after API calls.
- Add middleware functions via
client.useMiddleware(fn)
. - Middleware can modify requests (
ctx.request
), responses (ctx.response
), implement auditing, access control, logging, cost limiting, caching, and more.
- Add middleware functions via
npm install openrouter-kit
# or
yarn add openrouter-kit
# or
pnpm add openrouter-kit
TypeScript:
import { OpenRouterClient, MemoryHistoryStorage } from 'openrouter-kit'; // Import directly
const client = new OpenRouterClient({
apiKey: process.env.OPENROUTER_API_KEY || 'sk-or-v1-...',
// !!! IMPORTANT: Provide an adapter to enable history !!!
historyAdapter: new MemoryHistoryStorage(), // Use the imported class
enableCostTracking: true,
debug: false,
});
async function main() {
try {
console.log('Sending request...');
const result = await client.chat({
prompt: 'Say hi to the world!',
model: 'google/gemini-2.0-flash-001',
user: 'test-user-1', // User ID for history tracking
});
console.log('--- Result ---');
console.log('Model Response:', result.content);
console.log('Token Usage:', result.usage);
console.log('Model Used:', result.model);
console.log('Tool Calls Count:', result.toolCallsCount);
console.log('Finish Reason:', result.finishReason);
console.log('Duration (ms):', result.durationMs);
if (result.cost !== null) {
console.log('Estimated Cost (USD):', result.cost.toFixed(8));
}
console.log('Request ID:', result.id);
console.log('\nChecking balance...');
const balance = await client.getCreditBalance();
console.log(`Credit Balance: Used $${balance.usage.toFixed(4)} of $${balance.limit.toFixed(2)}`);
// Get history (will work since historyAdapter was provided)
const historyManager = client.getHistoryManager();
if (historyManager) {
// Key is generated internally by the client, but showing format for example
const historyKey = `user:test-user-1`;
const history = await historyManager.getHistory(historyKey);
console.log(`\nMessages stored in history for ${historyKey}: ${history.length}`);
}
} catch (error: any) {
console.error(`\n--- Error ---`);
console.error(`Message: ${error.message}`);
if (error.code) console.error(`Error Code: ${error.code}`);
if (error.statusCode) console.error(`HTTP Status: ${error.statusCode}`);
if (error.details) console.error(`Details:`, error.details);
// console.error(error.stack);
} finally {
console.log('\nShutting down and releasing resources...');
await client.destroy();
console.log('Resources released.');
}
}
main();
JavaScript (CommonJS):
const { OpenRouterClient, MemoryHistoryStorage } = require("openrouter-kit"); // Destructure from main export
const client = new OpenRouterClient({
apiKey: process.env.OPENROUTER_API_KEY || 'sk-or-v1-...',
// !!! IMPORTANT: Provide an adapter to enable history !!!
historyAdapter: new MemoryHistoryStorage(), // Use the imported class
enableCostTracking: true,
});
async function main() {
try {
const result = await client.chat({
prompt: 'Hello, world!',
user: 'commonjs-user' // Specify user for history saving
});
console.log('Model Response:', result.content);
console.log('Usage:', result.usage);
console.log('Cost:', result.cost);
// Get history
const historyManager = client.getHistoryManager();
if (historyManager) {
// Key is generated internally, showing format for example
const historyKey = 'user:commonjs-user';
const history = await historyManager.getHistory(historyKey);
console.log(`\nHistory for '${historyKey}': ${history.length} messages`);
}
} catch (error) {
console.error(`Error: ${error.message}`, error.details || error);
} finally {
await client.destroy();
}
}
main();
This example demonstrates using dialogue history and tool calling. Note the required historyAdapter
and the corresponding require
.
// taxi-bot.js (CommonJS)
const { OpenRouterClient, MemoryHistoryStorage } = require("openrouter-kit"); // Destructure
const readline = require('readline').createInterface({
input: process.stdin,
output: process.stdout
});
// Example proxy config (if needed)
// const proxyConfig = {
// host: "",
// port: "",
// user: "",
// pass: "",
// };
const client = new OpenRouterClient({
apiKey: process.env.OPENROUTER_API_KEY || "sk-or-v1-...", // Replace!
model: "google/gemini-2.0-flash-001",
// !!! IMPORTANT: Provide an adapter to enable history !!!
historyAdapter: new MemoryHistoryStorage(), // Use imported class
// proxy: proxyConfig,
enableCostTracking: true,
debug: false, // Set true for verbose logs
// security: { /* ... */ } // Security config can be added here
});
let orderAccepted = false;
// --- Tool Definitions ---
const taxiTools = [
{
type: "function",
function: {
name: "estimateRideCost",
description: "Estimates the cost of a taxi ride between two addresses.",
parameters: {
type: "object",
properties: {
from: { type: "string", description: "Pickup address (e.g., '1 Lenin St, Moscow')" },
to: { type: "string", description: "Destination address (e.g., '10 Tverskaya St, Moscow')" }
},
required: ["from", "to"]
},
},
// Executable function for the tool
execute: async (args) => {
console.log(`[Tool estimateRideCost] Calculating cost from ${args.from} to ${args.to}...`);
// Simulate cost calculation
const cost = Math.floor(Math.random() * 900) + 100;
console.log(`[Tool estimateRideCost] Calculated cost: ${cost} RUB`);
// Return an object to be serialized to JSON
return { estimatedCost: cost, currency: "RUB" };
}
},
{
type: "function",
function: {
name: "acceptOrder",
description: "Accepts and confirms a taxi order, assigns a driver.",
parameters: {
type: "object",
properties: {
from: { type: "string", description: "Confirmed pickup address" },
to: { type: "string", description: "Confirmed destination address" },
estimatedCost: { type: "number", description: "Approximate ride cost (if known)"}
},
required: ["from", "to"]
},
},
// Executable function with context access
execute: async (args, context) => {
console.log(`[Tool acceptOrder] Accepting order from ${args.from} to ${args.to}...`);
// Example of using context (if security is configured)
console.log(`[Tool acceptOrder] Order initiated by user: ${context?.userInfo?.userId || 'anonymous'}`);
// Simulate driver assignment
const driverNumber = Math.floor(Math.random() * 100) + 1;
orderAccepted = true; // Set flag to end the loop
// Return a string for the model to relay to the user
return `Order successfully accepted! Driver #${driverNumber} has been assigned and will arrive shortly at ${args.from}. Destination: ${args.to}.`;
}
}
];
function askQuestion(query) {
return new Promise((resolve) => {
readline.question(query, (answer) => {
resolve(answer);
});
});
}
const systemPrompt = `You are a friendly and efficient taxi service operator named "Kit". Your task is to help the customer book a taxi.
1. Clarify the pickup address ('from') and destination address ('to') if the customer hasn't provided them. Be polite.
2. Once the addresses are known, you MUST use the 'estimateRideCost' tool to inform the customer of the approximate cost.
3. Wait for the customer to confirm they accept the cost and are ready to order (e.g., with words like "book it", "okay", "yes", "sounds good").
4. After customer confirmation, use the 'acceptOrder' tool, passing it the 'from' and 'to' addresses.
5. After calling 'acceptOrder', inform the customer of the result returned by the tool.
6. Do not invent driver numbers or order statuses yourself; rely on the response from the 'acceptOrder' tool.
7. If the user asks something unrelated to booking a taxi, politely steer the conversation back to the topic.`;
async function chatWithTaxiBot() {
const userId = `taxi-user-${Date.now()}`;
console.log(`\nKit Bot: Hello! I'm your virtual assistant... (Session ID: ${userId})`);
try {
while (!orderAccepted) {
const userMessage = await askQuestion("You: ");
if (userMessage.toLowerCase() === 'exit' || userMessage.toLowerCase() === 'quit') {
console.log("Kit Bot: Thank you for contacting us! Goodbye.");
break;
}
console.log("Kit Bot: One moment, processing your request...");
// Pass user: userId, history will be managed automatically
// because historyAdapter was provided
const result = await client.chat({
user: userId, // Key for history
prompt: userMessage,
systemPrompt: systemPrompt,
tools: taxiTools, // Provide available tools
temperature: 0.5,
maxToolCalls: 5 // Limit tool call cycles
});
// Output the assistant's final response
console.log(`\nKit Bot: ${result.content}\n`);
// Output debug info if enabled
if (client.isDebugMode()) {
console.log(`[Debug] Model: ${result.model}, Tool Calls: ${result.toolCallsCount}, Cost: ${result.cost !== null ? '$' + result.cost.toFixed(8) : 'N/A'}, Reason: ${result.finishReason}`);
}
// Check the flag set by the acceptOrder tool
if (orderAccepted) {
console.log("Kit Bot: If you have any more questions, I'm here to help!");
// Optionally break here if the conversation should end after ordering
}
}
} catch (error) {
console.error("\n--- An Error Occurred ---");
// Use instanceof to check error type
if (error instanceof Error) {
console.error(`Type: ${error.constructor.name}`);
console.error(`Message: ${error.message}`);
// Access custom fields via 'any' or type assertion
if ((error as any).code) console.error(`Code: ${(error as any).code}`);
if ((error as any).statusCode) console.error(`Status: ${(error as any).statusCode}`);
if ((error as any).details) console.error(`Details:`, (error as any).details);
} else {
console.error("Unknown error:", error);
}
} finally {
readline.close();
await client.destroy(); // Release resources
console.log("\nClient stopped. Session ended.");
}
}
chatWithTaxiBot();
The main class for interacting with the library.
An object passed when creating the client (new OpenRouterClient(config)
). Key fields:
-
apiKey
(string, required): Your OpenRouter API key. -
apiEndpoint?
(string): Override the chat completions API endpoint URL (default:https://openrouter.ai/api/v1/chat/completions
). -
model?
(string): Default model identifier for requests. -
debug?
(boolean): Enable detailed logging (default:false
). -
proxy?
(string | object): HTTP/HTTPS proxy settings. -
referer?
(string): Value for theHTTP-Referer
header. -
title?
(string): Value for theX-Title
header. -
axiosConfig?
(object): Additional configuration passed directly to Axios. -
historyAdapter?
(IHistoryStorage): Required for history management. An instance of a history storage adapter (e.g.,new MemoryHistoryStorage()
). -
historyTtl?
(number): Time-to-live (TTL) for entries in theUnifiedHistoryManager
cache (milliseconds). -
historyCleanupInterval?
(number): Interval for cleaning expired entries from theUnifiedHistoryManager
cache (milliseconds). -
providerPreferences?
(object): Settings specific to OpenRouter model providers. -
modelFallbacks?
(string[]): List of fallback models to try if the primary model fails. -
responseFormat?
(ResponseFormat | null): Default response format for all requests. -
maxToolCalls?
(number): Default maximum tool call cycles perchat()
invocation (default: 10). -
strictJsonParsing?
(boolean): Throw an error on invalid JSON response (if JSON format requested)? (default:false
, returnsnull
). -
security?
(SecurityConfig): Configuration for the security module (uses the baseSecurityConfig
type from./types
). -
enableCostTracking?
(boolean): Enable cost tracking (default:false
). -
priceRefreshIntervalMs?
(number): Interval for refreshing model prices (default: 6 hours). -
initialModelPrices?
(object): Provide initial model prices to avoid the first price fetch. -
Deprecated fields (ignored if
historyAdapter
is present):historyStorage
,chatsFolder
,maxHistoryEntries
,historyAutoSave
.
-
chat(options: OpenRouterRequestOptions): Promise<ChatCompletionResult>
: The primary method for sending chat requests. Takes anoptions
object (seeOpenRouterRequestOptions
intypes/index.ts
). Manages history only ifuser
is passed ANDhistoryAdapter
is configured. -
getHistoryManager(): UnifiedHistoryManager
: Returns the history manager instance (if created). -
getSecurityManager(): SecurityManager | null
: Returns the security manager instance (if configured). -
getCostTracker(): CostTracker | null
: Returns the cost tracker instance (if enabled). -
getCreditBalance(): Promise<CreditBalance>
: Fetches the OpenRouter account credit balance. -
getModelPrices(): Record<string, ModelPricingInfo>
: Returns the cached model prices. -
refreshModelPrices(): Promise<void>
: Forces a background refresh of model prices. -
createAccessToken(userInfo, expiresIn?): string
: Generates a JWT (ifsecurity.userAuthentication.type === 'jwt'
). -
use(plugin): Promise<void>
: Registers a plugin. -
useMiddleware(fn): void
: Registers middleware. -
on(event, handler)
/off(event, handler)
: Subscribe/unsubscribe from client events ('error'
) or security module events (prefixed events likesecurity:
,user:
,token:
,access:
,ratelimit:
,tool:
). -
destroy(): Promise<void>
: Releases resources (timers, listeners).
-
Plugins: Modules extending client functionality. Registered via
client.use(plugin)
. Can initialize services, replace standard managers (setSecurityManager
,setCostTracker
), add middleware. -
Middleware: Functions executed sequentially for each
client.chat()
call. Allow modification of requests (ctx.request
), responses (ctx.response
), or performing side effects (logging, auditing). Registered viaclient.useMiddleware(fn)
.
To enable automatic dialogue history management (loading, saving, trimming when user
is passed to client.chat()
), you MUST configure historyAdapter
in OpenRouterConfig
. Without it, history features will not work.
-
Adapter (
IHistoryStorage
): Defines the interface for storage (load
,save
,delete
,listKeys
,destroy?
). -
UnifiedHistoryManager
: Internal component using the adapter and managing an in-memory cache (with TTL and cleanup). -
Built-in Adapters:
-
MemoryHistoryStorage
: Stores history in RAM (default if no adapter specified). -
DiskHistoryStorage
: Stores history in JSON files on disk.
-
-
Usage:
import { OpenRouterClient, MemoryHistoryStorage, DiskHistoryStorage } from 'openrouter-kit'; // Using MemoryHistoryStorage const clientMemory = new OpenRouterClient({ /*...,*/ historyAdapter: new MemoryHistoryStorage() }); // Using DiskHistoryStorage const clientDisk = new OpenRouterClient({ /*...,*/ historyAdapter: new DiskHistoryStorage('./my-chat-histories') });
-
Redis Plugin: Use
createRedisHistoryPlugin
for easy Redis integration (requiresioredis
). -
Cache Settings:
historyTtl
,historyCleanupInterval
inOpenRouterConfig
control theUnifiedHistoryManager
's cache behavior.
Allows LLM models to invoke your JavaScript/TypeScript functions to retrieve external information, interact with other APIs, or perform real-world actions.
-
Defining a Tool (
Tool
): Define each tool as an object conforming to theTool
interface. Key fields:-
type: 'function'
(currently the only supported type). -
function
: An object describing the function for the LLM:-
name
(string): A unique name the model will use to call the function. -
description
(string, optional): A clear description of what the function does and when to use it. Crucial for the model to understand the tool's purpose. -
parameters
(object, optional): A JSON Schema object describing the structure, types, and required fields of the arguments your function expects. The library uses this schema to validate arguments received from the model. Omit if no arguments are needed.
-
-
execute: (args: any, context?: ToolContext) => Promise<any> | any
: Your async or sync function that gets executed when the model requests this tool call.-
args
: An object containing the arguments passed by the model, already parsed from the JSON string and (if a schema was provided) validated againstparameters
. -
context?
: An optionalToolContext
object containing additional call information, such as:-
userInfo?
: TheUserAuthInfo
object for the authenticated user (ifSecurityManager
is used andaccessToken
was passed). -
securityManager?
: TheSecurityManager
instance (if used).
-
-
-
security
(ToolSecurity, optional): An object defining tool-specific security rules likerequiredRole
,requiredScopes
, orrateLimit
. These are checked by theSecurityManager
beforeexecute
is called.
-
-
Using in
client.chat()
:- Pass an array of your defined tools to the
tools
option of theclient.chat()
method. - The library handles the complex interaction flow:
- Sends tool definitions (name, description, parameters schema) to the model with your prompt.
- If the model decides to call one or more tools, it returns a response with
finish_reason: 'tool_calls'
and a list oftool_calls
. - The library intercepts this response. For each requested
toolCall
:- Finds the corresponding tool in your
tools
array by name. - Parses the arguments string (
toolCall.function.arguments
) into a JavaScript object. - Validates the arguments object against the JSON Schema in
tool.function.parameters
(if provided). -
Performs security checks via
SecurityManager
(if configured): verifies user (userInfo
) access rights, applies rate limits, and checks arguments for dangerous content. - If all checks pass, calls your
tool.execute(parsedArgs, context)
function. - Waits for the result (or catches errors) from your
execute
function. -
Formats the result (or a structured error) into a JSON string and sends it back to the model in a new message with
role: 'tool'
and the correspondingtool_call_id
.
- Finds the corresponding tool in your
- The model receives the tool call results and generates the final, coherent response to the user (now with
role: 'assistant'
).
- The
maxToolCalls
option (inclient.chat()
or client config) limits the maximum number of these request-call-result cycles to prevent infinite loops if the model keeps requesting tools. - The
toolChoice
option controls the model's tool usage:'auto'
(default),'none'
(disallow calls), or force a specific function call{ type: "function", function: { name: "my_tool_name" } }
.
- Pass an array of your defined tools to the
-
Result: The final model response (after all potential tool calls) is available in
ChatCompletionResult.content
. TheChatCompletionResult.toolCallsCount
field indicates how many tools were successfully called and executed during the singleclient.chat()
invocation.
Provides multi-layered protection when using tools, crucial if tools perform actions or access data. Activated by passing a security: SecurityConfig
object to the OpenRouterClient
constructor.
Components:
-
AuthManager
: Handles user authentication. Supports JWT out-of-the-box (generation, validation, caching). UsesjwtSecret
from config. Extensible viacustomAuthenticator
. -
AccessControlManager
: Checks if the authenticated (or anonymous, if allowed) user has permission to call a specific tool based onsecurity.toolAccess
andsecurity.roles
rules. ConsidersdefaultPolicy
. -
RateLimitManager
: Tracks and enforces tool call frequency limits per user based on configuration (security.roles
,security.toolAccess
, ortool.security
). Important: Default implementation is in-memory and not suitable for distributed systems. -
ArgumentSanitizer
: Analyzes arguments passed to toolexecute
functions for potentially harmful patterns (SQLi, XSS, OS commands, etc.) using regex and blocklists defined insecurity.dangerousArguments
. Supports blocking or audit-only (auditOnlyMode
).
Configuration (SecurityConfig
):
Defines the security module's behavior in detail. Uses extended types (ExtendedSecurityConfig
, ExtendedUserAuthInfo
, etc.) exported by the library. Key fields:
-
defaultPolicy
('deny-all'
|'allow-all'
): Action if no explicit access rule matches?'deny-all'
recommended. -
requireAuthentication
(boolean): Must a validaccessToken
be present for any tool call? -
allowUnauthenticatedAccess
(boolean): IfrequireAuthentication: false
, can anonymous users call tools (if the tool itself allows it)? -
userAuthentication
(UserAuthConfig
): Authentication method setup (type: 'jwt'
,jwtSecret
,customAuthenticator
). Set a strongjwtSecret
if using JWT! -
toolAccess
(Record<string, ToolAccessConfig>
): Access rules per tool name or for all ('*'
). Includesallow
,roles
,scopes
,rateLimit
,allowedApiKeys
. -
roles
(RolesConfig
): Definitions of roles and their permissions/limits (allowedTools
,rateLimits
). -
dangerousArguments
(ExtendedDangerousArgumentsConfig
): Argument sanitization settings (globalPatterns
,toolSpecificPatterns
,blockedValues
,auditOnlyMode
).
Usage:
- Pass the
securityConfig
object to theOpenRouterClient
constructor. - For authenticated requests, pass the access token via
client.chat({ accessToken: '...' })
. - The library automatically calls
securityManager.checkToolAccessAndArgs()
before executing any tool. This performs all configured checks (auth, ACL, rate limits, args). - If any check fails, an appropriate error (
AuthorizationError
,AccessDeniedError
,RateLimitError
,SecurityError
) is thrown, and theexecute
function is not called. - Use
client.createAccessToken()
to generate JWTs (if configured). - Subscribe to security events (
client.on('access:denied', ...)
etc.) for monitoring.
Provides an approximate cost estimate for each client.chat()
call based on token usage and OpenRouter model prices.
-
Enabling: Set
enableCostTracking: true
inOpenRouterConfig
. -
Mechanism:
-
CostTracker
instance is created on client initialization. - It fetches current prices for all models from the OpenRouter API (
/models
) initially (unlessinitialModelPrices
is provided) and periodically thereafter (priceRefreshIntervalMs
, default 6 hours). - Prices (cost per million input/output tokens) are cached in memory.
- After a successful
client.chat()
call, the library gets token usage (usage
) from the API response. -
costTracker.calculateCost(model, usage)
is called, using cached prices and usage data to compute the cost. It accounts for prompt, completion, and intermediate tool call tokens. - The calculated value (USD number) or
null
(if prices are unknown or tracking is off) is added to thecost
field of the returnedChatCompletionResult
.
-
-
Related Client Methods:
-
getCreditBalance(): Promise<CreditBalance>
: Fetches current credit limit and usage from your OpenRouter account. -
getModelPrices(): Record<string, ModelPricingInfo>
: Returns the current cache of model prices used by the tracker. -
refreshModelPrices(): Promise<void>
: Manually triggers a background refresh of the model price cache. -
getCostTracker(): CostTracker | null
: Accesses theCostTracker
instance (if enabled).
-
- Accuracy: Remember this is an estimate. Actual billing might differ slightly due to rounding or price changes not yet reflected in the cache.
Instructs the model to generate its response content in JSON format, useful for structured data extraction.
-
Configuration: Set via the
responseFormat
option inOpenRouterConfig
(for a default) or in theclient.chat()
options (for a specific request). -
Types:
-
{ type: 'json_object' }
: Instructs the model to return any valid JSON object. -
{ type: 'json_schema', json_schema: { name: string, schema: object, strict?: boolean, description?: string } }
: Requires the model to return JSON conforming to the provided JSON Schema.-
name
: An arbitrary name for your schema. -
schema
: The JSON Schema object describing the expected JSON structure. -
strict
(optional): Request strict schema adherence (model-dependent). -
description
(optional): A description of the schema for the model.
-
-
-
Example:
import { OpenRouterClient, MemoryHistoryStorage } from 'openrouter-kit'; const client = new OpenRouterClient({ /* ... */ historyAdapter: new MemoryHistoryStorage() }); const userSchema = { type: "object", properties: { name: { type: "string"}, age: {type: "number"} }, required: ["name", "age"] }; async function getUserData() { const result = await client.chat({ prompt: 'Generate JSON for a user: name Alice, age 30.', responseFormat: { type: 'json_schema', json_schema: { name: 'UserData', schema: userSchema } } }); console.log(result.content); // Expect { name: "Alice", age: 30 } }
-
Parsing Error Handling:
- If
strictJsonParsing: false
(default): If the model returns invalid JSON or JSON not matching the schema,ChatCompletionResult.content
will benull
. - If
strictJsonParsing: true
: AValidationError
will be thrown in the same situation.
- If
-
Model Support: Not all models guarantee support for
responseFormat
. Check specific model documentation.
The library uses a structured error system for easier debugging and control flow.
-
Base Class
OpenRouterError
: All library errors inherit from this. Contains:-
message
: Human-readable error description. -
code
(ErrorCode
): String code for programmatic identification (e.g.,API_ERROR
,VALIDATION_ERROR
,RATE_LIMIT_ERROR
). -
statusCode?
(number): HTTP status code from the API response, if applicable. -
details?
(any): Additional context or the original error.
-
-
Subclasses: Specific error types for different situations:
-
APIError
: Error returned by the OpenRouter API (status >= 400). -
ValidationError
: Data validation failure (config, args, JSON/schema response). -
NetworkError
: Network issue connecting to the API. -
AuthenticationError
: Invalid API key or missing authentication (typically 401). -
AuthorizationError
: Invalid or expired access token (typically 401). -
AccessDeniedError
: Authenticated user lacks permissions (typically 403). -
RateLimitError
: Request limit exceeded (typically 429). Containsdetails.timeLeft
(ms). -
ToolError
: Error during toolexecute
function execution. -
ConfigError
: Invalid library configuration. -
SecurityError
: General security failure (includesDANGEROUS_ARGS
). -
TimeoutError
: API request timed out.
-
-
Enum
ErrorCode
: Contains all possible string error codes (e.g.,ErrorCode.API_ERROR
,ErrorCode.TOOL_ERROR
). -
Function
mapError(error)
: Internally used to convert Axios and standardError
objects into anOpenRouterError
subclass. Exported for potential external use. -
Handling Recommendations:
- Use
try...catch
blocks around client method calls (client.chat()
,client.getCreditBalance()
, etc.). - Check error type using
instanceof
(e.g.,if (error instanceof RateLimitError)
) or the code (if (error.code === ErrorCode.VALIDATION_ERROR)
). - Inspect
error.statusCode
anderror.details
for more context. - Subscribe to the global client
'error'
event (client.on('error', handler)
) for centralized logging or monitoring of unexpected errors.
- Use
import { OpenRouterClient, MemoryHistoryStorage, OpenRouterError, RateLimitError, ValidationError, ErrorCode } from 'openrouter-kit';
const client = new OpenRouterClient({ /* ... */ historyAdapter: new MemoryHistoryStorage() });
async function safeChat() {
try {
const result = await client.chat({ prompt: "..." });
// ... process successful result ...
} catch (error: any) {
if (error instanceof RateLimitError) {
const retryAfter = Math.ceil((error.details?.timeLeft || 1000) / 1000); // Seconds
console.warn(`Rate limit exceeded! Please try again in ${retryAfter} seconds.`);
} else if (error.code === ErrorCode.VALIDATION_ERROR) {
console.error(`Validation Error: ${error.message}`, error.details);
} else if (error.code === ErrorCode.TOOL_ERROR && error.message.includes('Maximum tool call depth')) {
console.error(`Tool call limit reached: ${error.message}`);
} else if (error instanceof OpenRouterError) {
console.error(`OpenRouter Kit Error (${error.code}, Status: ${error.statusCode || 'N/A'}): ${error.message}`);
if(error.details) console.error('Details:', error.details);
} else {
console.error(`Unknown error: ${error.message}`);
}
}
}
The library uses a built-in logger for debug information and event messages.
-
Activation: Set
debug: true
inOpenRouterConfig
when creating the client. -
Levels: Uses standard console levels:
console.debug
,console.log
,console.warn
,console.error
. Whendebug: false
, only critical initialization warnings or errors are shown. -
Prefixes: Messages are automatically prefixed with the component source (e.g.,
[OpenRouterClient]
,[SecurityManager]
,[CostTracker]
,[UnifiedHistoryManager]
) for easier debugging. -
Customization: While direct logger replacement isn't a standard API feature, you can pass custom loggers to some components (like
HistoryManager
if created manually) or use plugins/middleware to intercept and redirect logs. -
isDebugMode()
Method: Check the client's current debug status usingclient.isDebugMode()
.
Route requests to the OpenRouter API through an HTTP/HTTPS proxy using the proxy
option in OpenRouterConfig
.
-
Formats:
-
URL String: Full proxy URL, including protocol, optional authentication, host, and port.
proxy: 'http://user:[email protected]:8080'
proxy: 'https://secureproxy.com:9000'
-
Object: A structured object with fields:
-
host
(string, required): Proxy server hostname or IP. -
port
(number | string, required): Proxy server port. -
user?
(string, optional): Username for proxy authentication. -
pass?
(string, optional): Password for proxy authentication.
proxy: { host: '192.168.1.100', port: 8888, // can also be '8888' user: 'proxyUser', pass: 'proxyPassword' }
-
-
URL String: Full proxy URL, including protocol, optional authentication, host, and port.
-
Mechanism: The library uses
https-proxy-agent
to route HTTPS traffic through the specified HTTP/HTTPS proxy.
For Tasks:
Click tags to check more tools for each tasksFor Jobs:
Alternative AI tools for openrouter-kit
Similar Open Source Tools

openrouter-kit
OpenRouter Kit is a powerful TypeScript/JavaScript library for interacting with the OpenRouter API. It simplifies working with LLMs by providing a high-level API for chats, dialogue history management, tool calls with error handling, security module, and cost tracking. Ideal for building chatbots, AI agents, and integrating LLMs into applications.

generative-ai-python
The Google AI Python SDK is the easiest way for Python developers to build with the Gemini API. The Gemini API gives you access to Gemini models created by Google DeepMind. Gemini models are built from the ground up to be multimodal, so you can reason seamlessly across text, images, and code.

react-native-rag
React Native RAG is a library that enables private, local RAGs to supercharge LLMs with a custom knowledge base. It offers modular and extensible components like `LLM`, `Embeddings`, `VectorStore`, and `TextSplitter`, with multiple integration options. The library supports on-device inference, vector store persistence, and semantic search implementation. Users can easily generate text responses, manage documents, and utilize custom components for advanced use cases.

rust-genai
genai is a multi-AI providers library for Rust that aims to provide a common and ergonomic single API to various generative AI providers such as OpenAI, Anthropic, Cohere, Ollama, and Gemini. It focuses on standardizing chat completion APIs across major AI services, prioritizing ergonomics and commonality. The library initially focuses on text chat APIs and plans to expand to support images, function calling, and more in the future versions. Version 0.1.x will have breaking changes in patches, while version 0.2.x will follow semver more strictly. genai does not provide a full representation of a given AI provider but aims to simplify the differences at a lower layer for ease of use.

llm-scraper
LLM Scraper is a TypeScript library that allows you to convert any webpages into structured data using LLMs. It supports Local (GGUF), OpenAI, Groq chat models, and schemas defined with Zod. With full type-safety in TypeScript and based on the Playwright framework, it offers streaming when crawling multiple pages and supports four input modes: html, markdown, text, and image.

AirBnB_clone_v2
The AirBnB Clone - The Console project is the first segment of the AirBnB project at Holberton School, aiming to cover fundamental concepts of higher level programming. The goal is to deploy a server as a simple copy of the AirBnB Website (HBnB). The project includes a command interpreter to manage objects for the AirBnB website, allowing users to create new objects, retrieve objects, perform operations on objects, update object attributes, and destroy objects. The project is interpreted/tested on Ubuntu 14.04 LTS using Python 3.4.3.

docutranslate
Docutranslate is a versatile tool for translating documents efficiently. It supports multiple file formats and languages, making it ideal for businesses and individuals needing quick and accurate translations. The tool uses advanced algorithms to ensure high-quality translations while maintaining the original document's formatting. With its user-friendly interface, Docutranslate simplifies the translation process and saves time for users. Whether you need to translate legal documents, technical manuals, or personal letters, Docutranslate is the go-to solution for all your document translation needs.

desktop
E2B Desktop Sandbox is a secure virtual desktop environment powered by E2B, allowing users to create isolated sandboxes with customizable dependencies. It provides features such as streaming the desktop screen, mouse and keyboard control, taking screenshots, opening files, and running bash commands. The environment is based on Linux and Xfce, offering a fast and lightweight experience that can be fully customized to create unique desktop environments.

python-tgpt
Python-tgpt is a Python package that enables seamless interaction with over 45 free LLM providers without requiring an API key. It also provides image generation capabilities. The name _python-tgpt_ draws inspiration from its parent project tgpt, which operates on Golang. Through this Python adaptation, users can effortlessly engage with a number of free LLMs available, fostering a smoother AI interaction experience.

dashscope-sdk
DashScope SDK for .NET is an unofficial SDK maintained by Cnblogs, providing various APIs for text embedding, generation, multimodal generation, image synthesis, and more. Users can interact with the SDK to perform tasks such as text completion, chat generation, function calls, file operations, and more. The project is under active development, and users are advised to check the Release Notes before upgrading.

receipt-scanner
The receipt-scanner repository is an AI-Powered Receipt and Invoice Scanner for Laravel that allows users to easily extract structured receipt data from images, PDFs, and emails within their Laravel application using OpenAI. It provides a light wrapper around OpenAI Chat and Completion endpoints, supports various input formats, and integrates with Textract for OCR functionality. Users can install the package via composer, publish configuration files, and use it to extract data from plain text, PDFs, images, Word documents, and web content. The scanned receipt data is parsed into a DTO structure with main classes like Receipt, Merchant, and LineItem.

js-genai
The Google Gen AI JavaScript SDK is an experimental SDK for TypeScript and JavaScript developers to build applications powered by Gemini. It supports both the Gemini Developer API and Vertex AI. The SDK is designed to work with Gemini 2.0 features. Users can access API features through the GoogleGenAI classes, which provide submodules for querying models, managing caches, creating chats, uploading files, and starting live sessions. The SDK also allows for function calling to interact with external systems. Users can find more samples in the GitHub samples directory.

Webscout
WebScout is a versatile tool that allows users to search for anything using Google, DuckDuckGo, and phind.com. It contains AI models, can transcribe YouTube videos, generate temporary email and phone numbers, has TTS support, webai (terminal GPT and open interpreter), and offline LLMs. It also supports features like weather forecasting, YT video downloading, temp mail and number generation, text-to-speech, advanced web searches, and more.

llama.rn
React Native binding of llama.cpp, which is an inference of LLaMA model in pure C/C++. This tool allows you to use the LLaMA model in your React Native applications for various tasks such as text completion, tokenization, detokenization, and embedding. It provides a convenient interface to interact with the LLaMA model and supports features like grammar sampling and mocking for testing purposes.

Webscout
Webscout is an all-in-one Python toolkit for web search, AI interaction, digital utilities, and more. It provides access to diverse search engines, cutting-edge AI models, temporary communication tools, media utilities, developer helpers, and powerful CLI interfaces through a unified library. With features like comprehensive search leveraging Google and DuckDuckGo, AI powerhouse for accessing various AI models, YouTube toolkit for video and transcript management, GitAPI for GitHub data extraction, Tempmail & Temp Number for privacy, Text-to-Speech conversion, GGUF conversion & quantization, SwiftCLI for CLI interfaces, LitPrinter for styled console output, LitLogger for logging, LitAgent for user agent generation, Text-to-Image generation, Scout for web parsing and crawling, Awesome Prompts for specialized tasks, Weather Toolkit, and AI Search Providers.

client-js
The Mistral JavaScript client is a library that allows you to interact with the Mistral AI API. With this client, you can perform various tasks such as listing models, chatting with streaming, chatting without streaming, and generating embeddings. To use the client, you can install it in your project using npm and then set up the client with your API key. Once the client is set up, you can use it to perform the desired tasks. For example, you can use the client to chat with a model by providing a list of messages. The client will then return the response from the model. You can also use the client to generate embeddings for a given input. The embeddings can then be used for various downstream tasks such as clustering or classification.
For similar tasks

agentcloud
AgentCloud is an open-source platform that enables companies to build and deploy private LLM chat apps, empowering teams to securely interact with their data. It comprises three main components: Agent Backend, Webapp, and Vector Proxy. To run this project locally, clone the repository, install Docker, and start the services. The project is licensed under the GNU Affero General Public License, version 3 only. Contributions and feedback are welcome from the community.

zep-python
Zep is an open-source platform for building and deploying large language model (LLM) applications. It provides a suite of tools and services that make it easy to integrate LLMs into your applications, including chat history memory, embedding, vector search, and data enrichment. Zep is designed to be scalable, reliable, and easy to use, making it a great choice for developers who want to build LLM-powered applications quickly and easily.

lollms
LoLLMs Server is a text generation server based on large language models. It provides a Flask-based API for generating text using various pre-trained language models. This server is designed to be easy to install and use, allowing developers to integrate powerful text generation capabilities into their applications.

LlamaIndexTS
LlamaIndex.TS is a data framework for your LLM application. Use your own data with large language models (LLMs, OpenAI ChatGPT and others) in Typescript and Javascript.

semantic-kernel
Semantic Kernel is an SDK that integrates Large Language Models (LLMs) like OpenAI, Azure OpenAI, and Hugging Face with conventional programming languages like C#, Python, and Java. Semantic Kernel achieves this by allowing you to define plugins that can be chained together in just a few lines of code. What makes Semantic Kernel _special_ , however, is its ability to _automatically_ orchestrate plugins with AI. With Semantic Kernel planners, you can ask an LLM to generate a plan that achieves a user's unique goal. Afterwards, Semantic Kernel will execute the plan for the user.

botpress
Botpress is a platform for building next-generation chatbots and assistants powered by OpenAI. It provides a range of tools and integrations to help developers quickly and easily create and deploy chatbots for various use cases.

BotSharp
BotSharp is an open-source machine learning framework for building AI bot platforms. It provides a comprehensive set of tools and components for developing and deploying intelligent virtual assistants. BotSharp is designed to be modular and extensible, allowing developers to easily integrate it with their existing systems and applications. With BotSharp, you can quickly and easily create AI-powered chatbots, virtual assistants, and other conversational AI applications.

qdrant
Qdrant is a vector similarity search engine and vector database. It is written in Rust, which makes it fast and reliable even under high load. Qdrant can be used for a variety of applications, including: * Semantic search * Image search * Product recommendations * Chatbots * Anomaly detection Qdrant offers a variety of features, including: * Payload storage and filtering * Hybrid search with sparse vectors * Vector quantization and on-disk storage * Distributed deployment * Highlighted features such as query planning, payload indexes, SIMD hardware acceleration, async I/O, and write-ahead logging Qdrant is available as a fully managed cloud service or as an open-source software that can be deployed on-premises.
For similar jobs

goat
GOAT (Great Onchain Agent Toolkit) is an open-source framework designed to simplify the process of making AI agents perform onchain actions by providing a provider-agnostic solution that abstracts away the complexities of interacting with blockchain tools such as wallets, token trading, and smart contracts. It offers a catalog of ready-made blockchain actions for agent developers and allows dApp/smart contract developers to develop plugins for easy access by agents. With compatibility across popular agent frameworks, support for multiple blockchains and wallet providers, and customizable onchain functionalities, GOAT aims to streamline the integration of blockchain capabilities into AI agents.

typedai
TypedAI is a TypeScript-first AI platform designed for developers to create and run autonomous AI agents, LLM based workflows, and chatbots. It offers advanced autonomous agents, software developer agents, pull request code review agent, AI chat interface, Slack chatbot, and supports various LLM services. The platform features configurable Human-in-the-loop settings, functional callable tools/integrations, CLI and Web UI interface, and can be run locally or deployed on the cloud with multi-user/SSO support. It leverages the Python AI ecosystem through executing Python scripts/packages and provides flexible run/deploy options like single user mode, Firestore & Cloud Run deployment, and multi-user SSO enterprise deployment. TypedAI also includes UI examples, code examples, and automated LLM function schemas for seamless development and execution of AI workflows.

appworld
AppWorld is a high-fidelity execution environment of 9 day-to-day apps, operable via 457 APIs, populated with digital activities of ~100 people living in a simulated world. It provides a benchmark of natural, diverse, and challenging autonomous agent tasks requiring rich and interactive coding. The repository includes implementations of AppWorld apps and APIs, along with tests. It also introduces safety features for code execution and provides guides for building agents and extending the benchmark.

mcp-agent
mcp-agent is a simple, composable framework designed to build agents using the Model Context Protocol. It handles the lifecycle of MCP server connections and implements patterns for building production-ready AI agents in a composable way. The framework also includes OpenAI's Swarm pattern for multi-agent orchestration in a model-agnostic manner, making it the simplest way to build robust agent applications. It is purpose-built for the shared protocol MCP, lightweight, and closer to an agent pattern library than a framework. mcp-agent allows developers to focus on the core business logic of their AI applications by handling mechanics such as server connections, working with LLMs, and supporting external signals like human input.

openrouter-kit
OpenRouter Kit is a powerful TypeScript/JavaScript library for interacting with the OpenRouter API. It simplifies working with LLMs by providing a high-level API for chats, dialogue history management, tool calls with error handling, security module, and cost tracking. Ideal for building chatbots, AI agents, and integrating LLMs into applications.

ChatFAQ
ChatFAQ is an open-source comprehensive platform for creating a wide variety of chatbots: generic ones, business-trained, or even capable of redirecting requests to human operators. It includes a specialized NLP/NLG engine based on a RAG architecture and customized chat widgets, ensuring a tailored experience for users and avoiding vendor lock-in.

agentcloud
AgentCloud is an open-source platform that enables companies to build and deploy private LLM chat apps, empowering teams to securely interact with their data. It comprises three main components: Agent Backend, Webapp, and Vector Proxy. To run this project locally, clone the repository, install Docker, and start the services. The project is licensed under the GNU Affero General Public License, version 3 only. Contributions and feedback are welcome from the community.

anything-llm
AnythingLLM is a full-stack application that enables you to turn any document, resource, or piece of content into context that any LLM can use as references during chatting. This application allows you to pick and choose which LLM or Vector Database you want to use as well as supporting multi-user management and permissions.