### Install and Run Sample Agent TUI Source: https://github.com/openrouterteam/skills/blob/main/skills/create-agent-tui/README.md Navigate to the sample directory, install dependencies, and start the agent TUI. Customize launch options using command-line arguments. ```bash cd sample npm install OPENROUTER_API_KEY=your-key-here npm start ``` ```bash npm start -- --banner "Acme Bot" --model anthropic/claude-sonnet-4.6 --input bordered --tool-display emoji ``` -------------------------------- ### Install create-agent-tui Skill Source: https://github.com/openrouterteam/skills/blob/main/skills/create-agent-tui/README.md Install the skill using the GitHub CLI. You can install it for all projects, a specific agent, or globally. ```bash gh skill install OpenRouterTeam/skills create-agent-tui ``` -------------------------------- ### Initialize Project and Install Dependencies Source: https://github.com/openrouterteam/skills/blob/main/skills/create-agent-tui/SKILL.md Sets up a new Node.js project with module support and installs necessary OpenRouter agent packages and development tools. ```bash npm init -y npm pkg set type=module npm pkg set scripts.start="tsx src/cli.ts" npm pkg set scripts.dev="tsx watch src/cli.ts" npm install @openrouter/agent glob zod npm install -D tsx typescript @types/node ``` -------------------------------- ### Install and Link Agent Source: https://github.com/openrouterteam/skills/blob/main/skills/create-headless-agent/README.md Steps to install dependencies, set the API key, and link the agent for global CLI access. ```bash cd sample bun install export OPENROUTER_API_KEY=your-key # Register the agent as a global CLI (one-time setup) bun link # Now invoke it by name from anywhere my-agent "List all TypeScript files" ``` -------------------------------- ### CLI Integration Example Source: https://github.com/openrouterteam/skills/blob/main/skills/create-agent-tui/references/loader.md Demonstrates how to integrate the Loader class into a CLI application to provide visual feedback during agent operations. This includes starting the loader, showing a preview, and stopping the loader on completion or error. ```typescript import { Loader } from './loader.js'; // Before the agent call — show loader + a preview input box below it: const loader = new Loader(config.display.loader); loader.start(); showPreviewInput(); // draw a non-interactive input box below the loader // On first event (text or tool_call) — clear preview, stop loader: clearPreviewInput(); loader.stop(); // After tool_result (agent pauses between turns) — restart loader + preview: loader.start(); showPreviewInput(); // After response or on error: clearPreviewInput(); loader.stop(); ``` -------------------------------- ### Install OpenRouter Video Skill with GitHub CLI Source: https://github.com/openrouterteam/skills/blob/main/skills/openrouter-video/README.md Installs the openrouter-video skill using the GitHub CLI. Ensure you have version 2.90.0 or higher. The `--scope user` flag installs it for all projects, while `--agent ` targets a specific agent. ```bash gh skill install OpenRouterTeam/skills openrouter-video ``` -------------------------------- ### Start the Headless Agent Server (Bash) Source: https://github.com/openrouterteam/skills/blob/main/skills/create-headless-agent/references/entry-points.md Commands to start the agent server using Bun. You can configure authentication and CORS by setting environment variables. ```bash # Start the server bun run src/server.ts # With auth and CORS configured AGENT_API_SECRET=my-secret ALLOWED_ORIGIN=https://myapp.com bun run src/server.ts ``` -------------------------------- ### Install OpenRouter SDK Package Source: https://github.com/openrouterteam/skills/blob/main/skills/openrouter-typescript-sdk/SKILL.md Install the SDK package for platform features such as model listing, credits, and API key management. ```bash npm install @openrouter/sdk ``` -------------------------------- ### package.json Scripts for Skills Source: https://github.com/openrouterteam/skills/blob/main/skills/create-headless-agent/references/entry-points.md Defines npm/bun scripts for starting and developing skills. 'start' runs the skill directly, while 'dev' enables watch mode for automatic restarts during development. ```json { "scripts": { "start": "bun run src/cli.ts", "dev": "bun --watch src/cli.ts" } } ``` -------------------------------- ### Start Headless Agent HTTP Server (TypeScript) Source: https://github.com/openrouterteam/skills/blob/main/skills/create-headless-agent/README.md Demonstrates starting an HTTP server with SSE streaming for the headless agent. This allows wrapping the agent in an HTTP server. ```typescript import { runAgent, type AgentRunOptions, type AgentRunResult } from '@openrouter/agent' const server = Bun.serve({ async fetch(req) { const url = new URL(req.url) if (url.pathname === '/') { const prompt = await req.text() const result = await runAgent({ prompt, // ...other options }) const stream = result.getTextStream() return new Response(stream) } return new Response('Not found') }, port: 3000 }) console.log(`Listening on http://localhost:${server.port}`) ``` -------------------------------- ### Install a Single OpenRouter Skill with GitHub CLI Source: https://github.com/openrouterteam/skills/blob/main/README.md Install a specific OpenRouter skill, such as 'openrouter-images', using the GitHub CLI. Refer to individual skill READMEs for exact names. ```bash gh skill install OpenRouterTeam/skills openrouter-images ``` -------------------------------- ### Install All OpenRouter Skills with GitHub CLI Source: https://github.com/openrouterteam/skills/blob/main/README.md Install all available OpenRouter skills using the GitHub CLI. This command requires GitHub CLI v2.90.0 or later. ```bash gh skill install OpenRouterTeam/skills ``` -------------------------------- ### Install openrouter-tts Skill Source: https://github.com/openrouterteam/skills/blob/main/skills/openrouter-tts/README.md Installs the openrouter-tts skill using the GitHub CLI. This command is compatible with various agents and allows for user-wide or agent-specific installations. ```bash gh skill install OpenRouterTeam/skills openrouter-tts ``` -------------------------------- ### Install Headless Agent Skill (Bash) Source: https://github.com/openrouterteam/skills/blob/main/skills/create-headless-agent/README.md Installs the create-headless-agent skill using the GitHub CLI. Use `--scope user` for all projects or `--agent ` for a specific agent. ```bash gh skill install OpenRouterTeam/skills create-headless-agent ``` -------------------------------- ### Install OpenRouter Agent Skill Source: https://github.com/openrouterteam/skills/blob/main/skills/openrouter-agent-migration/README.md Install the openrouter-agent-migration skill using the GitHub CLI. This command is compatible with various agents that support the gh skill install command. ```bash gh skill install OpenRouterTeam/skills openrouter-agent-migration ``` -------------------------------- ### Complete OAuth Flow Example Source: https://github.com/openrouterteam/skills/blob/main/skills/openrouter-typescript-sdk/SKILL.md This example demonstrates the full OAuth 2.0 flow for user-facing applications. It covers initiating the flow, handling the callback, exchanging the code for an API key, and using the user's key to make model calls. ```typescript 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 }); }); ``` -------------------------------- ### Install OpenRouter Agent Package Source: https://github.com/openrouterteam/skills/blob/main/skills/openrouter-typescript-sdk/SKILL.md Install the agent package for features like callModel, tools, and stop conditions. ```bash npm install @openrouter/agent ``` -------------------------------- ### Install OpenRouter Skills at User Scope Source: https://context7.com/openrouterteam/skills/llms.txt Installs OpenRouter skills for the current user, making them available across all projects. Use the '--scope user' flag with the GitHub CLI. ```bash gh skill install OpenRouterTeam/skills openrouter-typescript-sdk --scope user ``` -------------------------------- ### Install OpenRouter Models Skill with GitHub CLI Source: https://github.com/openrouterteam/skills/blob/main/skills/openrouter-models/README.md Installs the OpenRouter Models skill using the GitHub CLI. Specify --scope user for all projects or --agent for a specific agent. ```bash gh skill install OpenRouterTeam/skills openrouter-models ``` -------------------------------- ### Install OpenRouter Skill with User Scope Source: https://github.com/openrouterteam/skills/blob/main/README.md Install a specific OpenRouter skill to be available across all projects for your current agent by using the --scope user flag. ```bash gh skill install OpenRouterTeam/skills openrouter-images --scope user ``` -------------------------------- ### Scaffold a Headless TypeScript Agent Source: https://context7.com/openrouterteam/skills/llms.txt Use the `create-headless-agent` tool to quickly set up a TypeScript agent. After scaffolding, install dependencies using `bun install` and run the agent from the command line. ```bash # Install dependencies after scaffolding bun install # Run agent from CLI research-bot "What's in this repo?" echo "Summarize README.md" | research-bot research-bot --json "List all TODOs" | jq . ``` -------------------------------- ### Install OpenRouter TypeScript SDK using GitHub CLI Source: https://github.com/openrouterteam/skills/blob/main/skills/openrouter-typescript-sdk/README.md Install the OpenRouter TypeScript SDK using the GitHub CLI. This command works with various agents and can be scoped to a user or a specific agent. ```bash gh skill install OpenRouterTeam/skills openrouter-typescript-sdk ``` -------------------------------- ### Package.json Scripts for Development Source: https://github.com/openrouterteam/skills/blob/main/skills/create-headless-agent/references/entry-points.md Scripts for starting, serving, and developing the agent application using Bun. ```json { "scripts": { "start": "bun run src/cli.ts", "serve": "bun run src/server.ts", "dev": "bun --watch src/cli.ts" } } ``` -------------------------------- ### Install OpenRouter Skills for Claude Code Source: https://github.com/openrouterteam/skills/blob/main/README.md Use this command to install all OpenRouter skills via the Claude Code plugin marketplace. ```bash /plugin marketplace add OpenRouterTeam/skills /plugin install openrouter@openrouter ``` -------------------------------- ### Install MCP SDK Dependency Source: https://github.com/openrouterteam/skills/blob/main/skills/create-headless-agent/references/entry-points.md Command to add the Model Context Protocol SDK as a project dependency. ```bash bun add @modelcontextprotocol/sdk ``` -------------------------------- ### Basic client.callModel Usage Source: https://github.com/openrouterteam/skills/blob/main/skills/openrouter-agent-migration/SKILL.md Example demonstrating the usage of client.callModel() after updating imports. The core functionality remains consistent. ```typescript const client = new OpenRouter({ apiKey: process.env.OPENROUTER_API_KEY }); const result = client.callModel({ model: 'openai/gpt-5-nano', input: 'Hello!', }); const text = await result.getText(); ``` -------------------------------- ### Invoking the Headless Agent Source: https://github.com/openrouterteam/skills/blob/main/skills/create-headless-agent/SKILL.md Examples of how to invoke the generated headless agent from the command line with different input methods. ```bash "What's in this repo?" echo "Summarize README.md" | --json "List all TODOs" | jq . ``` -------------------------------- ### Loader Configuration JSON Source: https://github.com/openrouterteam/skills/blob/main/skills/create-agent-tui/references/loader.md Example JSON configuration for the loader, specifying the text to display and the animation style. ```json { "display": { "loader": { "text": "Thinking", "style": "spinner" } } } ``` -------------------------------- ### Reasoning Item Example Source: https://github.com/openrouterteam/skills/blob/main/open-responses/references/protocol-and-items.md Demonstrates a reasoning item, which can include raw traces, encrypted content, or a user-safe summary. ```json { "id": "item_004", "type": "reasoning", "status": "completed", "summary": [ { "type": "summary_text", "text": "I need to consider the geographic and political context..." } ] } ``` -------------------------------- ### Start Interactive TUI Test Source: https://github.com/openrouterteam/skills/blob/main/skills/create-agent-tui/sample/test-tui.md Launches the TUI application for manual interactive testing. Requires an API key to be set. ```bash OPENROUTER_API_KEY=your-key npm start ``` -------------------------------- ### Complete Agent Example with Tools Source: https://github.com/openrouterteam/skills/blob/main/skills/openrouter-typescript-sdk/SKILL.md Demonstrates setting up an agent with multiple tools (web search and finish), defining input/output schemas using Zod, and configuring stop conditions. It shows how to stream tool calls and retrieve the final text response. ```typescript 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); ``` -------------------------------- ### Initialize Project with bun init Source: https://github.com/openrouterteam/skills/blob/main/skills/create-headless-agent/SKILL.md Use this bash command to initialize a new project and set up the basic package.json file. Subsequent edits to package.json are required. ```bash bun init -y # Then edit package.json: ``` -------------------------------- ### Install Dependencies and Tools Source: https://github.com/openrouterteam/skills/blob/main/skills/create-agent-tui/sample/test-tui.md Installs project dependencies and Playwright's Chromium browser. Also installs ttyd, a required tool for the screenshot pipeline on macOS. ```bash cd skills/create-agent-tui/sample npm install npx playwright install chromium brew install ttyd # macOS — required for screenshot pipeline ``` -------------------------------- ### Install OpenRouter OAuth Skill with GitHub CLI Source: https://github.com/openrouterteam/skills/blob/main/skills/openrouter-oauth/README.md Use the GitHub CLI to install the OpenRouter OAuth skill. You can install it globally for all projects or target a specific agent. ```bash gh skill install OpenRouterTeam/skills openrouter-oauth ``` -------------------------------- ### Install OpenRouter Skills for OpenCode Source: https://github.com/openrouterteam/skills/blob/main/README.md Clone the skills repository and copy the skills to the OpenCode configuration directory. Ensure to clean up the temporary directory afterwards. ```bash git clone https://github.com/OpenRouterTeam/skills.git /tmp/openrouter-skills cp -r /tmp/openrouter-skills/skills/* ~/.config/opencode/skills/ rm -rf /tmp/openrouter-skills ``` -------------------------------- ### Install OpenRouter STT Skill with GitHub CLI Source: https://github.com/openrouterteam/skills/blob/main/skills/openrouter-stt/README.md Install the OpenRouter STT skill using the GitHub CLI. This command is compatible with various agents that support gh skill install. ```bash gh skill install OpenRouterTeam/skills openrouter-stt ``` -------------------------------- ### Install @openrouter/agent Source: https://github.com/openrouterteam/skills/blob/main/skills/openrouter-agent-migration/SKILL.md Install the @openrouter/agent package using npm. If you only use agent features, you can uninstall @openrouter/sdk. ```bash npm install @openrouter/agent ``` ```bash npm uninstall @openrouter/sdk npm install @openrouter/agent ``` -------------------------------- ### Install Dependencies for Scripts Source: https://github.com/openrouterteam/skills/blob/main/skills/openrouter-images/SKILL.md Install necessary Node.js dependencies before running the image generation or editing scripts. ```bash cd /scripts && npm install ``` -------------------------------- ### Sign-in Button Implementation Source: https://github.com/openrouterteam/skills/blob/main/skills/openrouter-oauth/SKILL.md Guidance on creating a sign-in button that integrates with the `initiateOAuth` function, including styling variants and size options. ```APIDOC ## Sign-in Button Build a button component that calls `initiateOAuth()` on click. Include the OpenRouter logo and provide multiple visual variants. ### OpenRouter Logo SVG ```svg ``` ### Variants (Tailwind) Recommended classes for visual consistency with the reference implementation: | Variant | Classes | |---|---| | `default` | `rounded-lg border border-neutral-300 bg-white text-neutral-900 shadow-sm hover:bg-neutral-50` | | `minimal` | `text-neutral-700 underline-offset-4 hover:underline` | | `branded` | `rounded-lg bg-neutral-900 text-white shadow hover:bg-neutral-800` | | `icon` | Same as `default` + `aspect-square` (logo only, no text) | | `cta` | `rounded-xl bg-neutral-900 text-white shadow-lg hover:bg-neutral-800 hover:scale-[1.02] active:scale-[0.98]` | ### Sizes | Size | Classes | |---|---| | `sm` | `h-8 px-3 text-xs` | | `default` | `h-10 px-5 text-sm` | | `lg` | `h-12 px-8 text-base` | | `xl` | `h-14 px-10 text-lg` | All variants use: `inline-flex items-center justify-center gap-2 font-medium transition-all cursor-pointer disabled:opacity-50` Show a loading indicator while the key exchange is in progress. Default label: "Sign in with OpenRouter". ### Dark mode For dark mode support, add dark variants: swap light backgrounds to dark (`dark:bg-neutral-900 dark:text-white`) and vice versa for `branded`/`cta` (`dark:bg-white dark:text-neutral-900`). ``` -------------------------------- ### List All Available Models Source: https://github.com/openrouterteam/skills/blob/main/skills/openrouter-models/SKILL.md Fetch and display all models available on OpenRouter. Navigate to the scripts directory before execution. ```bash cd /scripts && npx tsx list-models.ts ``` -------------------------------- ### File Logging Setup Source: https://github.com/openrouterteam/skills/blob/main/skills/create-headless-agent/references/modules.md Shows how to attach the fileLogHandler to the AgentLogger instance for logging events to a file, suitable for server or queue-worker environments. ```typescript import { fileLogHandler } from './logger.js'; logger.on(fileLogHandler('./agent-events.jsonl')); ``` -------------------------------- ### Custom Trace Event Examples Source: https://github.com/openrouterteam/skills/blob/main/open-responses/references/extensions.md Provides examples of custom streaming trace events, including sequence number, trace ID, span, and duration. ```text event: acme:trace_event data: {"type":"acme:trace_event","sequence_number":1,"trace_id":"t_abc123","span":"model.inference","duration_ms":142} event: acme:trace_event data: {"type":"acme:trace_event","sequence_number":2,"trace_id":"t_abc123","span":"tool.execution","duration_ms":89} ``` -------------------------------- ### Initialize OpenRouter SDK Source: https://context7.com/openrouterteam/skills/llms.txt Instantiate the SDK client with your API key. Ensure the OPENROUTER_API_KEY environment variable is set. ```typescript import OpenRouter from '@openrouter/sdk'; const sdk = new OpenRouter({ apiKey: process.env.OPENROUTER_API_KEY }); ``` -------------------------------- ### Using Both SDK and Agent Clients in a Mixed Project Source: https://github.com/openrouterteam/skills/blob/main/skills/openrouter-agent-migration/SKILL.md This example shows how to use both the @openrouter/sdk for general API features and @openrouter/agent for agent-specific features within the same project. Ensure correct import aliases are used. ```typescript import OpenRouter from '@openrouter/sdk'; // SDK client for models, credits, etc. import { OpenRouter as Agent } from '@openrouter/agent'; // Agent client for callModel import { tool } from '@openrouter/agent/tool'; import { stepCountIs } from '@openrouter/agent/stop-conditions'; // Use SDK client for non-agent features const sdkClient = new OpenRouter({ apiKey: process.env.OPENROUTER_API_KEY }); const models = await sdkClient.models.list(); const credits = await sdkClient.credits.getCredits(); // Use Agent client for callModel const agent = new Agent({ apiKey: process.env.OPENROUTER_API_KEY }); const result = agent.callModel({ model: 'openai/gpt-5-nano', input: 'Hello!', tools: [myTool], stopWhen: stepCountIs(5), }); ``` -------------------------------- ### Full Video Generation Workflow Source: https://github.com/openrouterteam/skills/blob/main/skills/openrouter-video/SKILL.md A complete bash script demonstrating the asynchronous video generation process: submitting a prompt, polling for completion, and downloading the resulting video. Ensure the OPENROUTER_API_KEY environment variable is set. ```bash #!/usr/bin/env bash set -euo pipefail PROMPT="a golden retriever playing fetch on a sunny beach" MODEL="google/veo-3.1" OUTPUT="video-$(date +%Y%m%d-%H%M%S).mp4" # Build payload — extend with resolution/aspect_ratio/duration/etc. as needed. payload=$(jq -n --arg model "$MODEL" --arg prompt "$PROMPT" '{model: $model, prompt: $prompt}') submit=$(curl -sS -X POST https://openrouter.ai/api/v1/videos \ -H "Authorization: Bearer $OPENROUTER_API_KEY" \ -H "Content-Type: application/json" \ -d "$payload") poll_url=$(echo "$submit" | jq -r '.polling_url') echo "Submitted $(echo "$submit" | jq -r '.id')" >&2 while :; do sleep 30 resp=$(curl -sS "$poll_url" -H "Authorization: Bearer $OPENROUTER_API_KEY") # Avoid the name `status` — zsh treats it as read-only. st=$(echo "$resp" | jq -r '.status') echo "Status: $st" >&2 case "$st" in completed) break ;; failed|cancelled|expired) echo "Generation $st: $(echo "$resp" | jq -r '.error // "unknown"')" >&2 exit 1 ;; esac done curl -sS -L"$(echo "$resp" | jq -r '.unsigned_urls[0]')" \ -H "Authorization: Bearer $OPENROUTER_API_KEY" \ --output "$OUTPUT" echo "$resp" | jq --arg out "$(realpath "$OUTPUT")" '{job_id: .id, generation_id, video_saved: $out, usage}' ``` -------------------------------- ### Integrate buildSystemPrompt in agent.ts Source: https://github.com/openrouterteam/skills/blob/main/skills/create-agent-tui/references/system-prompt.md Example of how to integrate the `buildSystemPrompt` function into the `agent.ts` file. This replaces the raw config string with the dynamically generated prompt when calling the model. ```typescript import { buildSystemPrompt } from './system-prompt.js'; // In callModel: instructions: buildSystemPrompt(config), ``` -------------------------------- ### Custom Streaming Event Example Source: https://github.com/openrouterteam/skills/blob/main/open-responses/references/state-machines-and-streaming.md This example shows how providers can emit custom events using vendor-prefixed names. Custom events must include 'type' and 'sequence_number' fields and should not alter core response semantics. ```text event: acme:trace_event data: {"type":"acme:trace_event","sequence_number":1,"trace_id":"t_abc","span":"model.inference","duration_ms":142} ``` -------------------------------- ### Generate Image with OpenRouter Scripts Source: https://context7.com/openrouterteam/skills/llms.txt Use the `generate.ts` script to create images from text prompts. Install dependencies using `npm install` in the scripts directory. Options include specifying aspect ratio, output file, and model. ```bash # First-time setup cd /scripts && npm install # Generate a new image npx tsx generate.ts "a red panda wearing sunglasses" # → { model, prompt, images_saved: ["/abs/path/image-20260305-143022.png"], count: 1 } # Generate with options npx tsx generate.ts "futuristic cityscape at night" \ --aspect-ratio 16:9 \ --output cityscape.png \ --model google/gemini-2.5-flash-image ``` -------------------------------- ### Register Agent Globally Source: https://context7.com/openrouterteam/skills/llms.txt Command to link the agent locally and run it with a sample input. ```bash bun link && research-bot "Hello from anywhere" ``` -------------------------------- ### Get User Activity Source: https://context7.com/openrouterteam/skills/llms.txt Fetches usage analytics for the user. ```APIDOC ## Get User Activity ### Description Fetches usage analytics and activity data for the authenticated user. ### Method `sdk.analytics.getUserActivity()` ### Response #### Success Response (200) - **data** (object) - An object containing user activity data (details not specified in source). ### Request Example ```typescript const activity = await sdk.analytics.getUserActivity(); console.log(activity); ``` ``` -------------------------------- ### Get Credit Balance Source: https://context7.com/openrouterteam/skills/llms.txt Retrieves the current credit balance for the user. ```APIDOC ## Get Credit Balance ### Description Retrieves the current credit balance for the user, including total credits and usage. ### Method `sdk.credits.getCredits()` ### Response #### Success Response (200) - **data** (object) - An object containing credit information. - **total_credits** (number) - The total number of credits available. - **usage** (number) - The number of credits used. ### Request Example ```typescript const credits = await sdk.credits.getCredits(); console.log('Credits remaining:', credits.data.total_credits - credits.data.usage); ``` ### Response Example ```json { "data": { "total_credits": 1000, "usage": 50 } } ``` ``` -------------------------------- ### Register Default-ON Commands Source: https://github.com/openrouterteam/skills/blob/main/skills/create-agent-tui/references/slash-commands.md This example demonstrates how the agent generates a file to import and register default-ON commands. This is typically done via a side-effect import. ```typescript import './commands.js'; // Registers: /model, /new, /help ``` -------------------------------- ### Get Credit Balance Source: https://github.com/openrouterteam/skills/blob/main/skills/openrouter-typescript-sdk/SKILL.md Fetch the current credit balance for the OpenRouter account. ```typescript // Credit balance const credits = await sdkClient.credits.getCredits(); ``` -------------------------------- ### Run Agent with Tools and Stop Conditions Source: https://context7.com/openrouterteam/skills/llms.txt Initializes the OpenRouter client and configures the agent with specified tools, stop conditions (step count and cost), and event streaming. ```typescript import { OpenRouter } from '@openrouter/agent'; import { stepCountIs, maxCost } from '@openrouter/agent/stop-conditions'; import { tools } from './tools/index.js'; import type { AgentConfig } from './config.js'; export async function runAgent(config: AgentConfig, input: string, options?: { onEvent?: (event: AgentEvent) => void; signal?: AbortSignal; }) { const client = new OpenRouter({ apiKey: config.apiKey }); const result = client.callModel({ model: config.model, instructions: config.systemPrompt.replace('{cwd}', process.cwd()), input, tools, stopWhen: [stepCountIs(config.maxSteps), maxCost(config.maxCost)], }); // Wire AbortSignal const onAbort = () => result.cancel(); options?.signal?.addEventListener('abort', onAbort); let accumulatedText = ''; const callNames = new Map(); const streamText = async () => { for await (const delta of result.getTextStream()) { options?.onEvent?.({ type: 'text', delta }); accumulatedText += delta; } }; const streamTools = async () => { for await (const item of result.getItemsStream()) { if (item.type === 'function_call' && item.status === 'completed') { callNames.set(item.callId, item.name); options?.onEvent?.({ type: 'tool_call', name: item.name, callId: item.callId, args: JSON.parse(item.arguments || '{}') }); } else if (item.type === 'function_call_output') { options?.onEvent?.({ type: 'tool_result', name: callNames.get(item.callId) ?? 'unknown', callId: item.callId, output: String(item.output).slice(0, 200) }); options?.onEvent?.({ type: 'turn_end' }); } } }; await Promise.all([streamText(), streamTools()]); const response = await result.getResponse(); options?.signal?.removeEventListener('abort', onAbort); return { text: accumulatedText || response.outputText ?? '', usage: response.usage }; } ``` -------------------------------- ### Get User Activity Analytics Source: https://github.com/openrouterteam/skills/blob/main/skills/openrouter-typescript-sdk/SKILL.md Retrieve user activity data from the OpenRouter platform. ```typescript // Usage analytics const activity = await sdkClient.analytics.getUserActivity(); ``` -------------------------------- ### Get Current Key Metadata Source: https://github.com/openrouterteam/skills/blob/main/skills/openrouter-typescript-sdk/SKILL.md Retrieve information about the currently configured API key. ```APIDOC ## Get Current Key Metadata ### Description Retrieves metadata for the API key currently configured in the SDK client. ### Method `sdkClient.apiKeys.getCurrentKeyMetadata()` ### Endpoint N/A (SDK method) ### Parameters None ### Request Example ```typescript 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); ``` ### Response #### Success Response (200) - **name** (string) - The name of the API key. - **createdAt** (string) - The timestamp when the API key was created. #### Response Example ```json { "name": "My Key", "createdAt": "2023-10-27T10:00:00Z" } ``` ``` -------------------------------- ### Headless Agent Server Implementation (TypeScript) Source: https://github.com/openrouterteam/skills/blob/main/skills/create-headless-agent/references/entry-points.md This is the main server file that sets up an HTTP server using Bun.js. It handles CORS, authentication, request parsing, and delegates chat requests to the agent logic. Configure port, allowed origins, and API secret via environment variables. ```typescript import { loadConfig } from './config.js'; import { runAgentWithRetry, type AgentEvent } from './agent.js'; const config = loadConfig(); const PORT = parseInt(process.env.PORT ?? '3000', 10); const ALLOWED_ORIGIN = process.env.ALLOWED_ORIGIN ?? '*'; const API_SECRET = process.env.AGENT_API_SECRET; const MAX_BODY = 1 * 1024 * 1024; // 1 MB if (!API_SECRET) { console.warn( 'WARNING: AGENT_API_SECRET is not set. All requests will be rejected with 401.\n' + 'Set AGENT_API_SECRET= and send `Authorization: Bearer ` on every request.', ); } // ── Helpers ───────────────────────────────────────────────────────── function corsHeaders(): Record { return { 'Access-Control-Allow-Origin': ALLOWED_ORIGIN, 'Access-Control-Allow-Methods': 'POST, GET, OPTIONS', 'Access-Control-Allow-Headers': 'Content-Type, Authorization', }; } function json(data: unknown, status = 200): Response { return new Response(JSON.stringify(data), { status, headers: { 'Content-Type': 'application/json', ...corsHeaders() }, }); } function unauthorized(): Response { return json({ error: 'Unauthorized' }, 401); } // Fail-closed auth: require AGENT_API_SECRET to be set. The HTTP server // exposes shell execution and file mutation — running it unauthenticated // is an access-control footgun. See OWASP A01:2021. function checkAuth(req: Request): boolean { if (!API_SECRET) return false; return req.headers.get('Authorization') === `Bearer ${API_SECRET}`; } // ── Server ────────────────────────────────────────────────────────── Bun.serve({ port: PORT, // Enforce body limit at the server level — the Content-Length header // check is bypassable (chunked encoding, omitted header). Bun's default // is 128 MB which is too large for an agent RPC endpoint. maxRequestBodySize: MAX_BODY, async fetch(req) { const url = new URL(req.url); // CORS preflight if (req.method === 'OPTIONS') { return new Response(null, { status: 204, headers: corsHeaders() }); } // Health check if (req.method === 'GET' && url.pathname === '/health') { return json({ ok: true }); } // Chat endpoint if (req.method === 'POST' && url.pathname === '/chat') { if (!checkAuth(req)) return unauthorized(); // Enforce body size limit const contentLength = parseInt(req.headers.get('Content-Length') ?? '0', 10); if (contentLength > MAX_BODY) { return json({ error: 'Request body too large' }, 413); } let body: { prompt?: string; messages?: Array<{ role: string; content: string }>; stream?: boolean }; try { body = await req.json(); } catch { return json({ error: 'Invalid JSON' }, 400); } const { prompt, messages = [], stream = false } = body; const input = messages.length > 0 ? messages : prompt; if (!input) { return json({ error: 'Provide "prompt" (string) or "messages" (array)' }, 400); } // ── Streaming (SSE) ─────────────────────────────────────── if (stream) { const encoder = new TextEncoder(); const readable = new ReadableStream({ async start(controller) { try { const result = await runAgentWithRetry(config, input, { onEvent: (event: AgentEvent) => { if (event.type === 'text') { const data = JSON.stringify({ type: 'text', content: event.delta }); controller.enqueue(encoder.encode(`data: ${data}\n\n`)); } }, }); const done = JSON.stringify({ type: 'done', usage: result.usage }); controller.enqueue(encoder.encode(`data: ${done}\n\n`)); } catch (err: any) { const error = JSON.stringify({ type: 'error', message: err.message }); controller.enqueue(encoder.encode(`data: ${error}\n\n`)); } finally { controller.close(); } }, }); return new Response(readable, { headers: { 'Content-Type': 'text/event-stream', 'Cache-Control': 'no-cache', Connection: 'keep-alive', ...corsHeaders(), }, }); } // ── Non-streaming ───────────────────────────────────────── try { const result = await runAgentWithRetry(config, input); return json({ text: result.text, usage: result.usage }); } catch (err: any) { return json({ error: err.message }, 500); } } return json({ error: 'Not found' }, 404); }, }); console.log(`Agent server listening on http://localhost:${PORT}`); ``` -------------------------------- ### Custom Progress Event Example Source: https://github.com/openrouterteam/skills/blob/main/open-responses/references/extensions.md Demonstrates a custom streaming generation progress event, including percentage complete and estimated remaining time. ```text event: acme:generation_progress data: {"type":"acme:generation_progress","sequence_number":1,"percent_complete":35,"estimated_remaining_ms":800} ```