From 334959d651eed74b7a7c17b027c5268f6b81051d Mon Sep 17 00:00:00 2001 From: Tom Aylott Date: Tue, 11 Nov 2025 17:35:09 -0500 Subject: [PATCH 1/3] Add basic OpenRouter SDK example extracted from wrapper repo --- .../openrouter-sdk/src/basic/example.ts | 96 +++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 typescript/openrouter-sdk/src/basic/example.ts diff --git a/typescript/openrouter-sdk/src/basic/example.ts b/typescript/openrouter-sdk/src/basic/example.ts new file mode 100644 index 0000000..aba529a --- /dev/null +++ b/typescript/openrouter-sdk/src/basic/example.ts @@ -0,0 +1,96 @@ +/** + * Example usage of the @openrouter/sdk package + * + * This demonstrates the OpenRouter TypeScript SDK's idiomatic usage patterns: + * - Type-safe client initialization + * - Non-streaming chat completions + * - Streaming chat completions with async iteration + * - Automatic usage tracking + * + * Run with: bun examples/basic/example-basic-openrouter-sdk.ts + */ + +import { OpenRouter } from "@openrouter/sdk"; + +// Initialize the OpenRouter SDK client +// The SDK automatically reads OPENROUTER_API_KEY from environment +const openRouter = new OpenRouter({ + apiKey: process.env.OPENROUTER_API_KEY ?? "", +}); + +async function nonStreamingExample() { + console.log("=== Non-Streaming Example ===\n"); + + // Basic chat completion - returns the full response at once + const result = await openRouter.chat.send({ + model: "openai/gpt-4o-mini", + messages: [ + { + role: "user", + content: "What is the capital of France?", + }, + ], + stream: false, // Explicitly set stream to false for non-streaming + }); + + // The SDK provides strong typing - result has 'choices' property + if ("choices" in result && result.choices[0]) { + console.log("Model:", result.model); + console.log("Response:", result.choices[0].message.content); + console.log("Usage:", result.usage); + console.log(); + } +} + +async function streamingExample() { + console.log("=== Streaming Example ===\n"); + + // Streaming chat completion - returns an async iterable + const stream = await openRouter.chat.send({ + model: "openai/gpt-4o-mini", + messages: [ + { + role: "user", + content: "Write a haiku about TypeScript", + }, + ], + stream: true, // Enable streaming mode + streamOptions: { + includeUsage: true, // Include token usage in the final chunk + }, + }); + + console.log("Streaming response:"); + let fullContent = ""; + + // The SDK returns an async iterable that you can iterate with for-await-of + for await (const chunk of stream) { + // Each chunk contains partial data + if (chunk.choices?.[0]?.delta?.content) { + const content = chunk.choices[0].delta.content; + process.stdout.write(content); // Write without newline to see real-time streaming + fullContent += content; + } + + // Usage stats are included in the final chunk when streamOptions.includeUsage is true + if (chunk.usage) { + console.log("\n\nStream usage:", chunk.usage); + } + } + + console.log("\n\nFull response:", fullContent); + console.log(); +} + +async function main() { + try { + // Demonstrate both streaming and non-streaming modes + await nonStreamingExample(); + await streamingExample(); + } catch (error) { + console.error("Error:", error); + process.exit(1); + } +} + +main(); From 4a2c87a3c91ba10993b33de769ab98f348d2fdb5 Mon Sep 17 00:00:00 2001 From: Tom Aylott Date: Tue, 11 Nov 2025 18:18:20 -0500 Subject: [PATCH 2/3] Run biome format --- .../openrouter-sdk/src/basic/example.ts | 42 +++++++++---------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/typescript/openrouter-sdk/src/basic/example.ts b/typescript/openrouter-sdk/src/basic/example.ts index aba529a..7213fd0 100644 --- a/typescript/openrouter-sdk/src/basic/example.ts +++ b/typescript/openrouter-sdk/src/basic/example.ts @@ -1,57 +1,57 @@ /** * Example usage of the @openrouter/sdk package - * + * * This demonstrates the OpenRouter TypeScript SDK's idiomatic usage patterns: * - Type-safe client initialization * - Non-streaming chat completions * - Streaming chat completions with async iteration * - Automatic usage tracking - * + * * Run with: bun examples/basic/example-basic-openrouter-sdk.ts */ -import { OpenRouter } from "@openrouter/sdk"; +import { OpenRouter } from '@openrouter/sdk'; // Initialize the OpenRouter SDK client // The SDK automatically reads OPENROUTER_API_KEY from environment const openRouter = new OpenRouter({ - apiKey: process.env.OPENROUTER_API_KEY ?? "", + apiKey: process.env.OPENROUTER_API_KEY ?? '', }); async function nonStreamingExample() { - console.log("=== Non-Streaming Example ===\n"); + console.log('=== Non-Streaming Example ===\n'); // Basic chat completion - returns the full response at once const result = await openRouter.chat.send({ - model: "openai/gpt-4o-mini", + model: 'openai/gpt-4o-mini', messages: [ { - role: "user", - content: "What is the capital of France?", + role: 'user', + content: 'What is the capital of France?', }, ], stream: false, // Explicitly set stream to false for non-streaming }); // The SDK provides strong typing - result has 'choices' property - if ("choices" in result && result.choices[0]) { - console.log("Model:", result.model); - console.log("Response:", result.choices[0].message.content); - console.log("Usage:", result.usage); + if ('choices' in result && result.choices[0]) { + console.log('Model:', result.model); + console.log('Response:', result.choices[0].message.content); + console.log('Usage:', result.usage); console.log(); } } async function streamingExample() { - console.log("=== Streaming Example ===\n"); + console.log('=== Streaming Example ===\n'); // Streaming chat completion - returns an async iterable const stream = await openRouter.chat.send({ - model: "openai/gpt-4o-mini", + model: 'openai/gpt-4o-mini', messages: [ { - role: "user", - content: "Write a haiku about TypeScript", + role: 'user', + content: 'Write a haiku about TypeScript', }, ], stream: true, // Enable streaming mode @@ -60,8 +60,8 @@ async function streamingExample() { }, }); - console.log("Streaming response:"); - let fullContent = ""; + console.log('Streaming response:'); + let fullContent = ''; // The SDK returns an async iterable that you can iterate with for-await-of for await (const chunk of stream) { @@ -74,11 +74,11 @@ async function streamingExample() { // Usage stats are included in the final chunk when streamOptions.includeUsage is true if (chunk.usage) { - console.log("\n\nStream usage:", chunk.usage); + console.log('\n\nStream usage:', chunk.usage); } } - console.log("\n\nFull response:", fullContent); + console.log('\n\nFull response:', fullContent); console.log(); } @@ -88,7 +88,7 @@ async function main() { await nonStreamingExample(); await streamingExample(); } catch (error) { - console.error("Error:", error); + console.error('Error:', error); process.exit(1); } } From f5b54a8bc70d575f0992efffd2ec8d00b5d1c856 Mon Sep 17 00:00:00 2001 From: Tom Aylott Date: Wed, 12 Nov 2025 18:06:12 -0500 Subject: [PATCH 3/3] Remove run command from docs to prevent sync issues --- typescript/openrouter-sdk/src/basic/example.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/typescript/openrouter-sdk/src/basic/example.ts b/typescript/openrouter-sdk/src/basic/example.ts index 7213fd0..57f2991 100644 --- a/typescript/openrouter-sdk/src/basic/example.ts +++ b/typescript/openrouter-sdk/src/basic/example.ts @@ -6,8 +6,6 @@ * - Non-streaming chat completions * - Streaming chat completions with async iteration * - Automatic usage tracking - * - * Run with: bun examples/basic/example-basic-openrouter-sdk.ts */ import { OpenRouter } from '@openrouter/sdk';