diff --git a/README.md b/README.md index 789f941..a5ddfa8 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ make typescript # Run TypeScript monorepo examples │ ├── fetch/ - Raw fetch API examples │ ├── ai-sdk-v5/ - Vercel AI SDK v5 examples │ ├── effect-ai/ - Effect-TS examples -│ └── openrouter-sdk/ - OpenRouter SDK examples (TODO) +│ └── openrouter-sdk/ - OpenRouter SDK examples ├── docs/ - Feature documentation └── Makefile - Unified command interface ``` @@ -79,6 +79,7 @@ bash curl/prompt-caching.sh cd typescript/fetch && bun examples cd typescript/ai-sdk-v5 && bun examples cd typescript/effect-ai && bun examples +cd typescript/openrouter-sdk && bun examples ``` ## Benefits diff --git a/typescript/README.md b/typescript/README.md index 2995dc5..7e8341c 100644 --- a/typescript/README.md +++ b/typescript/README.md @@ -8,7 +8,7 @@ A Bun monorepo containing OpenRouter examples across different TypeScript ecosys - **fetch/** - Raw fetch API examples - **ai-sdk-v5/** - Vercel AI SDK v5 examples (using ai v4.x package) - **effect-ai/** - Effect-TS AI examples -- **openrouter-sdk/** - OpenRouter TypeScript SDK examples (TODO) +- **openrouter-sdk/** - OpenRouter TypeScript SDK examples ## Prerequisites @@ -41,6 +41,7 @@ bun examples cd fetch && bun examples cd ai-sdk-v5 && bun examples cd effect-ai && bun examples +cd openrouter-sdk && bun examples ``` ## Workspace Benefits diff --git a/typescript/bun.lockb b/typescript/bun.lockb new file mode 100755 index 0000000..112a190 Binary files /dev/null and b/typescript/bun.lockb differ diff --git a/typescript/openrouter-sdk/README.md b/typescript/openrouter-sdk/README.md new file mode 100644 index 0000000..5750a66 --- /dev/null +++ b/typescript/openrouter-sdk/README.md @@ -0,0 +1,28 @@ +# OpenRouter SDK Examples + +Examples using the OpenRouter TypeScript SDK (`@openrouter/sdk`). + +## Prerequisites + +- Bun runtime: `curl -fsSL https://bun.sh/install | bash` +- `OPENROUTER_API_KEY` environment variable + +## Running Examples + +```bash +# From monorepo root (typescript/) +bun examples + +# Or from this workspace +cd openrouter-sdk +bun examples +``` + +## Features + +- [basic](./src/basic/) - Quickstart chat completion using `openRouter.chat.send` + +## Dependencies + +- `@openrouter/sdk` - Official OpenRouter SDK (beta) +- `@openrouter-examples/shared` - Shared constants and utility modules diff --git a/typescript/openrouter-sdk/package.json b/typescript/openrouter-sdk/package.json new file mode 100644 index 0000000..5d370a4 --- /dev/null +++ b/typescript/openrouter-sdk/package.json @@ -0,0 +1,17 @@ +{ + "name": "@openrouter-examples/openrouter-sdk", + "version": "1.0.0", + "private": true, + "type": "module", + "scripts": { + "examples": "bun run run-examples.ts", + "typecheck": "tsc --noEmit" + }, + "dependencies": { + "@openrouter-examples/shared": "workspace:*", + "@openrouter/sdk": "0.8.0" + }, + "devDependencies": { + "@types/bun": "1.3.4" + } +} diff --git a/typescript/openrouter-sdk/run-examples.ts b/typescript/openrouter-sdk/run-examples.ts new file mode 100644 index 0000000..e9437a3 --- /dev/null +++ b/typescript/openrouter-sdk/run-examples.ts @@ -0,0 +1,50 @@ +import { readdirSync, statSync } from 'fs'; +import { join } from 'path'; +import { $ } from 'bun'; + +const srcDir = join(import.meta.dir, 'src'); + +function findExamples(dir: string): string[] { + const entries = readdirSync(dir); + const files: string[] = []; + + for (const entry of entries) { + const fullPath = join(dir, entry); + const stat = statSync(fullPath); + + if (stat.isDirectory()) { + files.push(...findExamples(fullPath)); + } else if (entry.endsWith('.ts')) { + files.push(fullPath); + } + } + + return files.sort(); +} + +const examples = findExamples(srcDir); +console.log(`Found ${examples.length} example(s)\n`); + +let failed = 0; +for (const example of examples) { + const relativePath = example.replace(import.meta.dir + '/', ''); + console.log(`\n${'='.repeat(80)}`); + console.log(`Running: ${relativePath}`); + console.log('='.repeat(80)); + + try { + await $`bun run ${example}`.quiet(); + console.log(`✅ ${relativePath} completed successfully`); + } catch (_error) { + console.error(`❌ ${relativePath} failed`); + failed++; + } +} + +console.log(`\n${'='.repeat(80)}`); +console.log(`Results: ${examples.length - failed}/${examples.length} passed`); +console.log('='.repeat(80)); + +if (failed > 0) { + process.exit(1); +} diff --git a/typescript/openrouter-sdk/src/basic/example.ts b/typescript/openrouter-sdk/src/basic/example.ts new file mode 100644 index 0000000..479766a --- /dev/null +++ b/typescript/openrouter-sdk/src/basic/example.ts @@ -0,0 +1,41 @@ +import { OpenRouter } from '@openrouter/sdk'; + +async function main() { + if (!process.env.OPENROUTER_API_KEY) { + throw new Error('OPENROUTER_API_KEY environment variable is not set'); + } + + const openRouter = new OpenRouter({ + apiKey: process.env.OPENROUTER_API_KEY, + httpReferer: 'https://github.com/openrouter/examples', + xTitle: 'OpenRouter SDK Example', + }); + + console.log('=== OpenRouter SDK Quickstart Example ===\n'); + + const completion = await openRouter.chat.send({ + chatGenerationParams: { + model: 'openai/gpt-5.2', + messages: [ + { + role: 'user', + content: 'Write a haiku about TypeScript.', + }, + ], + stream: false, + }, + }); + + const firstChoice = completion.choices?.[0]?.message?.content; + console.log('Response:'); + if (typeof firstChoice === 'string') { + console.log(firstChoice); + } else { + console.log(JSON.stringify(firstChoice, null, 2)); + } +} + +main().catch((error) => { + console.error('Error running OpenRouter SDK example:', error); + process.exit(1); +}); diff --git a/typescript/openrouter-sdk/tsconfig.json b/typescript/openrouter-sdk/tsconfig.json new file mode 100644 index 0000000..822a727 --- /dev/null +++ b/typescript/openrouter-sdk/tsconfig.json @@ -0,0 +1,16 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "ESNext", + "lib": ["ES2022"], + "moduleResolution": "bundler", + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true, + "types": ["bun-types"] + }, + "include": ["src/**/*"], + "exclude": ["node_modules"] +} diff --git a/typescript/package.json b/typescript/package.json index 7a3b0c5..50e7f1a 100644 --- a/typescript/package.json +++ b/typescript/package.json @@ -13,7 +13,8 @@ "shared", "fetch", "ai-sdk-v5", - "effect-ai" + "effect-ai", + "openrouter-sdk" ], "devDependencies": { "@types/bun": "1.3.2",