openrouter-typescript-sdk について
openrouter-typescript-sdk は、OpenRouter を利用する TypeScript 開発者向けのスキルです。エージェント処理用とプラットフォーム機能用の 2 つのパッケージで、モデル呼び出し、ツール実行、ストリーミング、OAuth、API キー管理を扱います。
主な機能
- 01統一インターフェースでモデルを呼び出し
- 02テキスト・複数ターン・マルチモーダル入力
- 03テキストとツール呼び出し結果のストリーミング
- 04型検証付きツールの定義
- 05モデル・クレジット・OAuth・API キーの管理
活用シーン
- 01TypeScript アプリからモデルを呼び出す
- 02ツールを実行する複数ターンの処理を構築
- 03モデル応答をストリームとして処理
- 04ユーザー向けアプリに OAuth を追加
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ openrouterteam/ skills --skill openrouter-typescript-sdkインストール後、Claude Code で/openrouter-typescript-sdkを入力して読み込まれたか確認します。
同梱ファイルmetadata.jsonREADME.md
詳細
OpenRouter TypeScript SDK
OpenRouter の統合 API を利用するための包括的な TypeScript SDK です。単一の型安全なインターフェースを通じて、300 以上の AI モデルにアクセスできます。このスキルにより、AI エージェントは callModel パターンを活用して、テキスト生成、ツールの使用、ストリーミング、複数ターンの会話を行えます。
SDK は 2 つのパッケージに分かれています。
@openrouter/agent— エージェント機能:callModel、tool()、停止条件、ストリーミング、フォーマット変換@openrouter/sdk— プラットフォーム機能:モデル一覧、チャット補完、クレジット、OAuth、API キー管理
インストール
# For agent features (callModel, tools, stop conditions)
npm install @openrouter/agent
# For platform features (models, credits, OAuth, API keys)
npm install @openrouter/sdk
セットアップ
openrouter.ai/settings/keys から API キーを取得し、初期化します。
import { OpenRouter } from '@openrouter/agent';
const client = new OpenRouter({
apiKey: process.env.OPENROUTER_API_KEY
});
認証
SDK は 2 種類の認証方式をサポートしています。サーバーサイドアプリケーション向けの API キーと、ユーザー向けアプリケーション向けの OAuth PKCE フローです。
API キー認証
主な認証方式では、OpenRouter アカウントの API キーを使用します。
API キーの取得
- openrouter.ai/settings/keys にアクセスします
- 新しい API キーを作成します
- 環境変数に安全に保存します
環境の設定
export OPENROUTER_API_KEY=sk-or-v1-your-key-here
クライアントの初期化
import { OpenRouter } from '@openrouter/agent';
const client = new OpenRouter({
apiKey: process.env.OPENROUTER_API_KEY
});
クライアントは、以降のすべてのリクエストでこのキーを自動的に使用します。
// API key is automatically included
const result = client.callModel({
model: 'openai/gpt-5-nano',
input: 'Hello!'
});
現在のキーのメタデータを取得
現在設定されている API キーの情報を取得します(@openrouter/sdk が必要です)。
import OpenRouter from '@openrouter/sdk';
const sdkClient = new OpenRouter({ apiKey: process.env.OPENROUTER_API_KEY });
const keyInfo = await sdkClient.apiKeys.getCurrentKeyMetadata();
console.log('Key name:', keyInfo.name);
console.log('Created:', keyInfo.createdAt);
API キーの管理
プログラムから API キーを管理します。
// List all keys
const keys = await client.apiKeys.list();
// Create a new key
const newKey = await client.apiKeys.create({
name: 'Production API Key'
});
// Get a specific key by hash
const key = await client.apiKeys.get({
hash: 'sk-or-v1-...'
});
// Update a key
await client.apiKeys.update({
hash: 'sk-or-v1-...',
requestBody: {
name: 'Updated Key Name'
}
});
// Delete a key
await client.apiKeys.delete({
hash: 'sk-or-v1-...'
});
OAuth 認証(PKCE フロー)
ユーザーが自身の API キーを管理するユーザー向けアプリケーションでは、OpenRouter は PKCE(Proof Key for Code Exchange)を用いた OAuth をサポートしています。このフローでは、アプリケーションがユーザーの認証情報を扱うことなく、ブラウザーでの認可フローを通じてユーザーが API キーを生成できます。
createAuthCode
OAuth フローを開始するための認可コードと URL を生成します。
const authResponse = await client.oAuth.createAuthCode({
callbackUrl: 'https://myapp.com/auth/callback'
});
// authResponse contains:
// - authorizationUrl: URL to redirect the user to
// - code: The authorization code for later exchange
console.log('Redirect user to:', authResponse.authorizationUrl);
パラメーター:
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
callbackUrl | string | はい | ユーザーの認可後に戻る、アプリケーションのコールバック URL |
ブラウザーのリダイレクト:
// In a browser environment
window.location.href = authResponse.authorizationUrl;
// Or in a server-rendered app, return a redirect response
res.redirect(authResponse.authorizationUrl);
exchangeAuthCodeForAPIKey
ユーザーがアプリケーションを認可すると、認可コードを含む状態でコールバック URL にリダイレクトされます。このコードを API キーと交換します。
// In your callback handler
const code = req.query.code; // From the redirect URL
const apiKeyResponse = await client.oAuth.exchangeAuthCodeForAPIKey({
code: code
});
// apiKeyResponse contains:
// - key: The user's API key
// - Additional metadata about the key
const userApiKey = apiKeyResponse.key;
// Store securely for this user's future requests
await saveUserApiKey(userId, userApiKey);
パラメーター:
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
code | string | はい | OAuth リダイレクトから取得した認可コード |
OAuth フローの完全な例
import OpenRouter from '@openrouter/sdk';
import { OpenRouter as Agent } from '@openrouter/agent';
import express from 'express';
const app = express();
// SDK client for OAuth and API key management
const client = new OpenRouter({
apiKey: process.env.OPENROUTER_API_KEY
});
// Step 1: Initiate OAuth flow
app.get('/auth/start', async (req, res) => {
const authResponse = await client.oAuth.createAuthCode({
callbackUrl: 'https://myapp.com/auth/callback'
});
// Store any state needed for the callback
req.session.oauthState = { /* ... */ };
// Redirect user to OpenRouter authorization page
res.redirect(authResponse.authorizationUrl);
});
// Step 2: Handle callback and exchange code
app.get('/auth/callback', async (req, res) => {
const { code } = req.query;
if (!code) {
return res.status(400).send('Authorization code missing');
}
try {
const apiKeyResponse = await client.oAuth.exchangeAuthCodeForAPIKey({
code: code as string
});
// Store the user's API key securely
await saveUserApiKey(req.session.userId, apiKeyResponse.key);
res.redirect('/dashboard?auth=success');
} catch (error) {
console.error('OAuth exchange failed:', error);
res.redirect('/auth/error');
}
});
// Step 3: Use the user's API key for their requests
app.post('/api/chat', async (req, res) => {
const userApiKey = await getUserApiKey(req.session.userId);
// Create an agent client with the user's key
const userAgent = new Agent({
apiKey: userApiKey
});
const result = userAgent.callModel({
model: 'openai/gpt-5-nano',
input: req.body.message
});
const text = await result.getText();
res.json({ response: text });
});
セキュリティのベストプラクティス
- 環境変数:API キーは環境変数に保存し、コードには決して記述しないでください
- キーのローテーション:キー管理 API を使って、定期的にキーをローテーションしてください
- 環境の分離:開発、ステージング、本番環境では異なるキーを使用してください
- ユーザー向けには OAuth を使用:ユーザーの認証情報を扱わないよう、ユーザー向けアプリでは OAuth PKCE フローを使用してください
- 安全な保存:ユーザーの API キーはデータベースに暗号化して保存してください
- 権限を最小限にする:必要な権限のみを付与したキーを作成してください
基本概念:callModel
callModel 関数は、テキスト生成のための主要なインターフェースです。サポートされているあらゆるモデルを、統一された型安全な方法で利用できます。
基本的な使い方
const result = client.callModel({
model: 'openai/gpt-5-nano',
input: 'Explain quantum computing in one sentence.',
});
const text = await result.getText();
主な利点
- 型安全なパラメーターにより、IDE の自動補完を最大限に活用できます
- OpenAPI 仕様から自動生成されるため、新しいモデルに合わせて自動的に更新されます
- 複数の利用パターンに対応し、テキスト、ストリーミング、構造化データを扱えます
- 複数ターンに対応し、ツールを自動的に実行できます
入力形式
SDK は input パラメーターに柔軟な入力型を受け付けます。
文字列入力
単純な文字列はユーザーメッセージになります。
const result = client.callModel({
model: 'openai/gpt-5-nano',
input: 'Hello, how are you?'
});
メッセージ配列
複数ターンの会話には、次のように指定します。
const result = client.callModel({
model: 'openai/gpt-5-nano',
input: [
{ role: 'user', content: 'What is the capital of France?' },
{ role: 'assistant', content: 'The capital of France is Paris.' },
{ role: 'user', content: 'What is its population?' }
]
});
マルチモーダルコンテンツ
画像とテキストを含める場合:
const result = client.callModel({
model: 'openai/gpt-5-nano',
input: [
{
role: 'user',
content: [
{ type: 'text', text: 'What is in this image?' },
{ type: 'image_url', image_url: { url: 'https://example.com/image.png' } }
]
}
]
});
システム指示
システムレベルのガイダンスには instructions パラメーターを使用します。
const result = client.callModel({
model: 'openai/gpt-5-nano',
instructions: 'You are a helpful coding assistant. Be concise.',
input: 'How do I reverse a string in Python?'
});
レスポンスの取得方法
結果オブジェクトには、レスポンスを取得するための複数のメソッドが用意されています。
| メソッド | 用途 |
|---|---|
getText() | すべてのツールの完了後に、テキスト全体を取得します |
getResponse() | トークン使用量を含む、完全なレスポンスオブジェクトを取得します |
getTextStream() | 到着したテキストの差分をストリーミングします |
getReasoningStream() | 推論トークンをストリーミングします(o1/推論モデルの場合) |
getToolCallsStream() | 完了したツール呼び出しをストリーミングします |
getText()
const result = client.callModel({
model: 'openai/gpt-5-nano',
input: 'Write a haiku about coding'
});
const text = await result.getText();
console.log(text);
getResponse()
const result = client.callModel({
model: 'openai/gpt-5-nano',
input: 'Hello!'
});
const response = await result.getResponse();
console.log('Text:', response.text);
console.log('Token usage:', response.usage);
getTextStream()
const result = client.callModel({
model: 'openai/gpt-5-nano',
input: 'Write a short story'
});
for await (const delta of result.getTextStream()) {
process.stdout.write(delta);
}
ツールシステム
Zod スキーマを使って型安全なツールを作成すると、自動検証と型推論が可能になります。
ツールの定義
import { tool } from '@openrouter/agent/tool';
import { z } from 'zod';
const weatherTool = tool({
name: 'get_weather',
description: 'Get current weather for a location',
inputSchema: z.object({
location: z.string().describe('City name'),
units: z.enum(['celsius', 'fahrenheit']).optional().default('celsius')
}),
outputSchema: z.object({
temperature: z.number(),
conditions: z.string(),
humidity: z.number()
}),
execute: async (params) => {
// Implement weather fetching logic
return {
temperature: 22,
conditions: 'Sunny',
humidity: 45
};
}
});
callModel でツールを使用する
const result = client.callModel({
model: 'openai/gpt-5-nano',
input: 'What is the weather in Paris?',
tools: [weatherTool]
});
const text = await result.getText();
// The SDK automatically executes the tool and continues the conversation
ツールの種類
通常のツール
結果を返す標準的な実行関数です。
const calculatorTool = tool({
name: 'calculate',
description: 'Perform mathematical calculations',
inputSchema: z.object({
expression: z.string()
}),
execute: async ({ expression }) => {
return { result: eval(expression) };
}
});
ジェネレーターツール
eventSchema を使って進捗イベントを生成します。
const searchTool = tool({
name: 'web_search',
description: 'Search the web',
inputSchema: z.object({ query: z.string() }),
eventSchema: z.object({
type: z.literal('progress'),
message: z.string()
}),
outputSchema: z.object({ results: z.array(z.string()) }),
execute: async function* ({ query }) {
yield { type: 'progress', message: 'Searching...' };
yield { type: 'progress', message: 'Processing results...' };
return { results: ['Result 1', 'Result 2'] };
}
});
手動ツール
execute: false を設定すると、ツール呼び出しを独自に処理できます。
const manualTool = tool({
name: 'user_confirmation',
description: 'Request user confirmation',
inputSchema: z.object({ message: z.string() }),
execute: false
});
停止条件を使ったマルチターン会話
停止条件を使って、自動的なツール実行を制御します。
import { stepCountIs, maxCost, hasToolCall } from '@openrouter/agent/stop-conditions';
const result = client.callModel({
model: 'openai/gpt-5.2',
input: 'Research this topic thoroughly',
tools: [searchTool, analyzeTool],
stopWhen: [
stepCountIs(10), // Stop after 10 turns
maxCost(1.00), // Stop if cost exceeds $1.00
hasToolCall('finish') // Stop when 'finish' tool is called
]
});
使用可能な停止条件
| 条件 | 説明 |
|---|---|
stepCountIs(n) | n ターン後に停止します |
maxCost(amount) | コストが指定額を超えたときに停止します |
hasToolCall(name) | 特定のツールが呼び出されたときに停止します |
カスタム停止条件
const customStop = (context) => {
return context.messages.length > 20;
};
const result = client.callModel({
model: 'openai/gpt-5-nano',
input: 'Complex task',
tools: [myTool],
stopWhen: customStop
});
動的パラメーター
会話のコンテキストに基づいてパラメーターを計算します。
const result = client.callModel({
model: (ctx) => ctx.numberOfTurns > 3 ? 'openai/gpt-4' : 'openai/gpt-4o-mini',
temperature: (ctx) => ctx.numberOfTurns > 1 ? 0.3 : 0.7,
input: 'Hello!'
});
コンテキストオブジェクトのプロパティ
| プロパティ | 型 | 説明 |
|---|---|---|
numberOfTurns | number | 現在のターン数 |
messages | array | これまでのすべてのメッセージ |
instructions | string | 現在のシステム指示 |
totalCost | number | 累積コスト |
nextTurnParams:コンテキストの注入
ツールは後続のターンのパラメーターを変更できます。これにより、スキルやコンテキストを考慮した動作が可能になります。
const skillTool = tool({
name: 'load_skill',
description: 'Load a specialized skill',
inputSchema: z.object({
skill: z.string().describe('Name of the skill to load')
}),
nextTurnParams: {
instructions: (params, context) => {
const skillInstructions = loadSkillInstructions(params.skill);
return `${context.instructions}\n\n${skillInstructions}`;
}
},
execute: async ({ skill }) => {
return { loaded: skill };
}
});
nextTurnParams のユースケース
- スキルシステム:専門的な機能を動的に読み込みます
- コンテキストの蓄積:複数のターンにわたってコンテキストを構築します
- モードの切り替え:会話の途中でモデルの動作を変更します
- メモリの注入:取得したコンテキストを指示に追加します
生成パラメーター
以下のパラメーターでモデルの動作を制御します。
const result = client.callModel({
model: 'openai/gpt-5-nano',
input: 'Write a creative story',
temperature: 0.7, // Creativity (0-2, default varies by model)
maxOutputTokens: 1000, // Maximum tokens to generate
topP: 0.9, // Nucleus sampling parameter
frequencyPenalty: 0.5, // Reduce repetition
presencePenalty: 0.5, // Encourage new topics
stop: ['\n\n'] // Stop sequences
});
ストリーミング
すべてのストリーミングメソッドは、単一の結果オブジェクトから複数のコンシューマーを同時にサポートします。
const result = client.callModel({
model: 'openai/gpt-5-nano',
input: 'Write a detailed explanation'
});
// Consumer 1: Stream text to console
const textPromise = (async () => {
for await (const delta of result.getTextStream()) {
process.stdout.write(delta);
}
})();
// Consumer 2: Get full response simultaneously
const responsePromise = result.getResponse();
// Both run concurrently
const [, response] = await Promise.all([textPromise, responsePromise]);
console.log('\n\nTotal tokens:', response.usage.totalTokens);
ツール呼び出しのストリーミング
const result = client.callModel({
model: 'openai/gpt-5-nano',
input: 'Search for information about TypeScript',
tools: [searchTool]
});
for await (const toolCall of result.getToolCallsStream()) {
console.log(`Tool called: ${toolCall.name}`);
console.log(`Arguments: ${JSON.stringify(toolCall.arguments)}`);
console.log(`Result: ${JSON.stringify(toolCall.result)}`);
}
フォーマット変換
相互運用性のため、エコシステム間でフォーマットを変換します。
OpenAI 形式
import { fromChatMessages, toChatMessage } from '@openrouter/agent';
// OpenAI messages → OpenRouter format
const result = client.callModel({
model: 'openai/gpt-5-nano',
input: fromChatMessages(openaiMessages)
});
// Response → OpenAI chat message format
const response = await result.getResponse();
const chatMsg = toChatMessage(response);
Claude 形式
import { fromClaudeMessages, toClaudeMessage } from '@openrouter/agent';
// Claude messages → OpenRouter format
const result = client.callModel({
model: 'anthropic/claude-3-opus',
input: fromClaudeMessages(claudeMessages)
});
// Response → Claude message format
const response = await result.getResponse();
const claudeMsg = toClaudeMessage(response);
Responses API のメッセージ形式
SDK はメッセージに OpenResponses 形式を使用します。堅牢なエージェントを構築するには、これらの形式を理解することが不可欠です。
メッセージのロール
メッセージには、メッセージの種類を決定する role プロパティが含まれます。
| ロール | 説明 |
|---|---|
user | ユーザーが提供した入力 |
assistant | モデルが生成したレスポンス |
system | システム指示 |
developer | 開発者レベルの指示 |
tool | ツールの実行結果 |
テキストメッセージ
ユーザーまたはアシスタントからのシンプルなテキストコンテンツです。
interface TextMessage {
role: 'user' | 'assistant';
content: string;
}
マルチモーダルメッセージ(配列コンテンツ)
複数のコンテンツタイプが混在するメッセージです。
interface MultimodalMessage {
role: 'user';
content: Array<
| { type: 'input_text'; text: string }
| { type: 'input_image'; imageUrl: string; detail?: 'auto' | 'low' | 'high' }
| {
type: 'image';
source: {
type: 'url' | 'base64';
url?: string;
media_type?: string;
data?: string
}
}
>;
}
ツール関数呼び出しメッセージ
モデルがツールの実行を要求したときに使用します。
interface ToolCallMessage {
role: 'assistant';
content?: null;
tool_calls?: Array<{
id: string;
type: 'function';
function: {
name: string;
arguments: string; // JSON-encoded arguments
};
}>;
}
ツール結果メッセージ
ツールの実行後に返される結果です。
interface ToolResultMessage {
role: 'tool';
tool_call_id: string;
content: string; // JSON-encoded result
}
非ストリーミングレスポンスの構造
getResponse() から返される完全なレスポンスオブジェクトです。
interface OpenResponsesNonStreamingResponse {
output: Array<ResponseMessage>;
usage?: {
inputTokens: number;
outputTokens: number;
cachedTokens?: number;
};
finishReason?: string;
warnings?: Array<{
type: string;
message: string
}>;
experimental_providerMetadata?: Record<string, unknown>;
}
レスポンスメッセージの種類
レスポンス配列内の出力メッセージです。
// Text/content message
interface ResponseOutputMessage {
type: 'message';
role: 'assistant';
content: string | Array<ContentPart>;
reasoning?: string; // For reasoning models (o1, etc.)
}
// Tool result in output
interface FunctionCallOutputMessage {
type: 'function_call_output';
call_id: string;
output: string;
}
解析済みツール呼び出し
レスポンスからツール呼び出しを解析した場合に使用します。
interface ParsedToolCall {
id: string;
name: string;
arguments: unknown; // Validated against inputSchema
}
ツール実行結果
ツールの実行完了後に返されます。
interface ToolExecutionResult {
toolCallId: string;
toolName: string;
result: unknown; // Validated against outputSchema
preliminaryResults?: unknown[]; // From generator tools
error?: Error;
}
ステップ結果(停止条件用)
カスタム停止条件のコールバック内で使用できます。
interface StepResult {
stepType: 'initial' | 'continue';
text: string;
toolCalls: ParsedToolCall[];
toolResults: ToolExecutionResult[];
response: OpenResponsesNonStreamingResponse;
usage?: {
inputTokens: number;
outputTokens: number;
cachedTokens?: number;
};
finishReason?: string;
warnings?: Array<{ type: string; message: string }>;
experimental_providerMetadata?: Record<string, unknown>;
}
TurnContext
ツールおよび動的パラメーター関数で利用できます:
interface TurnContext {
numberOfTurns: number; // Turn count (1-indexed)
turnRequest?: OpenResponsesRequest; // Current request being made
toolCall?: OpenResponsesFunctionToolCall; // Current tool call (in tool context)
}
イベントの形式
SDK には、異なるイベント型を返す複数のストリーミングメソッドが用意されています。
レスポンスストリームのイベント
getFullResponsesStream() メソッドは、次のイベント型を返します。
type EnhancedResponseStreamEvent =
| ResponseCreatedEvent
| ResponseInProgressEvent
| OutputTextDeltaEvent
| OutputTextDoneEvent
| ReasoningDeltaEvent
| ReasoningDoneEvent
| FunctionCallArgumentsDeltaEvent
| FunctionCallArgumentsDoneEvent
| ResponseCompletedEvent
| ToolPreliminaryResultEvent;
イベント型のリファレンス
| イベント型 | 説明 | ペイロード |
|---|---|---|
response.created | レスポンスオブジェクトが初期化されました | { response: ResponseObject } |
response.in_progress | 生成が開始されました | {} |
response.output_text.delta | テキストチャンクを受信しました | { delta: string } |
response.output_text.done | テキスト生成が完了しました | { text: string } |
response.reasoning.delta | 推論チャンク(o1 モデル) | { delta: string } |
response.reasoning.done | 推論が完了しました | { reasoning: string } |
response.function_call_arguments.delta | ツール引数のチャンク | { delta: string } |
response.function_call_arguments.done | ツール引数が揃いました | { arguments: string } |
response.completed | レスポンス全体が完了しました | { response: ResponseObject } |
tool.preliminary_result | ジェネレーターツールの進行状況 | { toolCallId: string; result: unknown } |
テキストデルタイベント
interface OutputTextDeltaEvent {
type: 'response.output_text.delta';
delta: string;
}
推論デルタイベント
推論モデル(o1 など)の場合:
interface ReasoningDeltaEvent {
type: 'response.reasoning.delta';
delta: string;
}
関数呼び出し引数のデルタイベント
interface FunctionCallArgumentsDeltaEvent {
type: 'response.function_call_arguments.delta';
delta: string;
}
ツールの暫定結果イベント
進行状況を返すジェネレーターツールからのイベントです:
interface ToolPreliminaryResultEvent {
type: 'tool.preliminary_result';
toolCallId: string;
result: unknown; // Matches the tool's eventSchema
}
レスポンス完了イベント
interface ResponseCompletedEvent {
type: 'response.completed';
response: OpenResponsesNonStreamingResponse;
}
ツールストリームのイベント
getToolStream() メソッドは次のイベントを返します。
type ToolStreamEvent =
| { type: 'delta'; content: string }
| { type: 'preliminary_result'; toolCallId: string; result: unknown };
例:ストリームイベントの処理
const result = client.callModel({
model: 'openai/gpt-5-nano',
input: 'Analyze this data',
tools: [analysisTool]
});
for await (const event of result.getFullResponsesStream()) {
switch (event.type) {
case 'response.output_text.delta':
process.stdout.write(event.delta);
break;
case 'response.reasoning.delta':
console.log('[Reasoning]', event.delta);
break;
case 'response.function_call_arguments.delta':
console.log('[Tool Args]', event.delta);
break;
case 'tool.preliminary_result':
console.log(`[Progress: ${event.toolCallId}]`, event.result);
break;
case 'response.completed':
console.log('\n[Complete]', event.response.usage);
break;
}
}
メッセージストリームのイベント
getNewMessagesStream() は、OpenResponses 形式の更新を返します。
type MessageStreamUpdate =
| ResponsesOutputMessage // Text/content updates
| OpenResponsesFunctionCallOutput; // Tool results
例:新しいメッセージの追跡
const result = client.callModel({
model: 'openai/gpt-5-nano',
input: 'Research this topic',
tools: [searchTool]
});
const allMessages: MessageStreamUpdate[] = [];
for await (const message of result.getNewMessagesStream()) {
allMessages.push(message);
if (message.type === 'message') {
console.log('Assistant:', message.content);
} else if (message.type === 'function_call_output') {
console.log('Tool result:', message.output);
}
}
API リファレンス
クライアントメソッド
callModel に加えて、SDK クライアント(@openrouter/sdk)からプラットフォーム API エンドポイントにアクセスできます。
import OpenRouter from '@openrouter/sdk';
const sdkClient = new OpenRouter({
apiKey: process.env.OPENROUTER_API_KEY
});
// List available models
const models = await sdkClient.models.list();
// Chat completions (alternative to callModel)
const completion = await sdkClient.chat.send({
model: 'openai/gpt-5-nano',
messages: [{ role: 'user', content: 'Hello!' }]
});
// Legacy completions format
const legacyCompletion = await sdkClient.completions.generate({
model: 'openai/gpt-5-nano',
prompt: 'Once upon a time'
});
// Usage analytics
const activity = await sdkClient.analytics.getUserActivity();
// Credit balance
const credits = await sdkClient.credits.getCredits();
// API key management
const keys = await sdkClient.apiKeys.list();
エラー処理
SDK には、実行可能なメッセージを含む特定のエラー型が用意されています。
try {
const result = await client.callModel({
model: 'openai/gpt-5-nano',
input: 'Hello!'
});
const text = await result.getText();
} catch (error) {
if (error.statusCode === 401) {
console.error('Invalid API key - check your OPENROUTER_API_KEY');
} else if (error.statusCode === 402) {
console.error('Insufficient credits - add credits at openrouter.ai');
} else if (error.statusCode === 429) {
console.error('Rate limited - implement backoff retry');
} else if (error.statusCode === 503) {
console.error('Model temporarily unavailable - try again or use fallback');
} else {
console.error('Unexpected error:', error.message);
}
}
エラーステータスコード
| コード | 意味 | 対処方法 |
|---|---|---|
| 400 | 不正なリクエスト | リクエストパラメーターを確認します |
| 401 | 認証されていません | API キーを確認します |
| 402 | 支払いが必要です | クレジットを追加します |
| 429 | レート制限に達しました | 指数バックオフを実装します |
| 500 | サーバーエラー | バックオフして再試行します |
| 503 | サービスを利用できません | 別のモデルを試します |
完全な例:ツールを使用するエージェント
import { OpenRouter } from '@openrouter/agent';
import { tool } from '@openrouter/agent/tool';
import { stepCountIs, hasToolCall } from '@openrouter/agent/stop-conditions';
import { z } from 'zod';
const client = new OpenRouter({
apiKey: process.env.OPENROUTER_API_KEY
});
// Define tools
const searchTool = tool({
name: 'web_search',
description: 'Search the web for information',
inputSchema: z.object({
query: z.string().describe('Search query')
}),
outputSchema: z.object({
results: z.array(z.object({
title: z.string(),
snippet: z.string(),
url: z.string()
}))
}),
execute: async ({ query }) => {
// Implement actual search
return {
results: [
{ title: 'Example', snippet: 'Example result', url: 'https://example.com' }
]
};
}
});
const finishTool = tool({
name: 'finish',
description: 'Complete the task with final answer',
inputSchema: z.object({
answer: z.string().describe('The final answer')
}),
execute: async ({ answer }) => ({ answer })
});
// Run agent
async function runAgent(task: string) {
const result = client.callModel({
model: 'openai/gpt-5-nano',
instructions: 'You are a helpful research assistant. Use web_search to find information, then use finish to provide your final answer.',
input: task,
tools: [searchTool, finishTool],
stopWhen: [
stepCountIs(10),
hasToolCall('finish')
]
});
// Stream progress
for await (const toolCall of result.getToolCallsStream()) {
console.log(`[${toolCall.name}] ${JSON.stringify(toolCall.arguments)}`);
}
return await result.getText();
}
// Usage
const answer = await runAgent('What are the latest developments in quantum computing?');
console.log('Final answer:', answer);
ベストプラクティス
1. 直接 API を呼び出すより callModel を優先する
callModel パターンを使用すると、ツールの自動実行、型安全性、複数ターンの処理が可能です。
2. ツールスキーマには Zod を使用する
Zod は実行時検証と優れた TypeScript の型推論を提供します。
import { z } from 'zod';
const schema = z.object({
name: z.string().min(1),
age: z.number().int().positive()
});
3. 停止条件を実装する
コストが際限なく増えるのを防ぐため、常に妥当な上限を設定してください。
stopWhen: [stepCountIs(20), maxCost(5.00)]
4. エラーを適切に処理する
一時的な障害に備えて、再試行ロジックを実装してください。
async function callWithRetry(params, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
return await client.callModel(params).getText();
} catch (error) {
if (error.statusCode === 429 || error.statusCode >= 500) {
await sleep(Math.pow(2, i) * 1000);
continue;
}
throw error;
}
}
}
5. 長いレスポンスにはストリーミングを使用する
ストリーミングによってユーザー体験が向上し、早期終了も可能になります。
for await (const delta of result.getTextStream()) {
// Process incrementally
}
その他のリソース
- API キー:openrouter.ai/settings/keys
- モデル一覧:openrouter.ai/models
- エージェント SDK:github.com/OpenRouterTeam/typescript-agent
- SDK の問題:github.com/OpenRouterTeam/typescript-sdk/issues
SDK のステータス:ベータ版 - GitHub で問題を報告してください