{"_id":"@biubiupiu/openrouter-sdk-provider","name":"@biubiupiu/openrouter-sdk-provider","dist-tags":{"latest":"1.5.5"},"versions":{"1.5.5":{"name":"@biubiupiu/openrouter-sdk-provider","version":"1.5.5","license":"Apache-2.0","sideEffects":false,"main":"./dist/index.js","module":"./dist/index.mjs","types":"./dist/index.d.ts","exports":{"./package.json":"./package.json",".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"},"./internal":{"types":"./dist/internal/index.d.ts","import":"./dist/internal/index.mjs","module":"./dist/internal/index.mjs","require":"./dist/internal/index.js"}},"devDependencies":{"@ai-sdk/provider":"2.0.0","@ai-sdk/provider-utils":"3.0.1","@biomejs/biome":"2.3.7","@changesets/changelog-github":"0.5.1","@changesets/cli":"2.29.7","@edge-runtime/vm":"5.0.0","@types/node":"24.2.0","ai":"5.0.104","dotenv":"17.2.1","tsup":"8.5.0","typescript":"5.9.2","vite-tsconfig-paths":"5.1.4","vitest":"3.2.4","zod":"3.25.76"},"peerDependencies":{"ai":"^5.0.0","zod":"^3.24.1 || ^v4"},"engines":{"node":">=18"},"publishConfig":{"access":"public"},"homepage":"https://github.com/OpenRouterTeam/ai-sdk-provider","repository":{"type":"git","url":"git+https://github.com/OpenRouterTeam/ai-sdk-provider.git"},"bugs":{"url":"https://github.com/OpenRouterTeam/ai-sdk-provider/issues"},"keywords":["ai"],"dependencies":{"@openrouter/sdk":"^0.1.27"},"scripts":{"build":"tsup","clean":"rm -rf dist && rm -rf internal/dist","dev":"tsup --watch","stylecheck":"biome check","typecheck":"tsc --noEmit","format":"biome format --write","prepublish":"pnpm run build","test":"pnpm test:node && pnpm test:edge","test:edge":"vitest --config vitest.edge.config.ts --run","test:node":"vitest --config vitest.node.config.ts --run","test:e2e":"vitest --config vitest.e2e.config.ts --run","changeset":"changeset","changeset-version":"changeset version","changeset-publish":"pnpm build && pnpm test && changeset publish --provenance"},"_id":"@biubiupiu/openrouter-sdk-provider@1.5.5","description":"The [OpenRouter](https://openrouter.ai/) provider for the [Vercel AI SDK](https://sdk.vercel.ai/docs) gives access to over 300 large language models on the OpenRouter chat and completion APIs.","_integrity":"sha512-M900/I60/RKN8J4L3jBQ/qjlSJPcF9KTXMCV2xEjHpHFeJYBbuqOvfsqRR/EGcDfFdjmlurXXRlVXixmMbifHw==","_resolved":"/private/var/folders/m7/tnzcz08x68g1vnh6n86bm_dc0000gn/T/f3a3083f5b81af9e3f3689d0fac5cff8/biubiupiu-openrouter-sdk-provider-1.5.5.tgz","_from":"file:biubiupiu-openrouter-sdk-provider-1.5.5.tgz","_nodeVersion":"20.19.6","_npmVersion":"10.8.2","dist":{"integrity":"sha512-M900/I60/RKN8J4L3jBQ/qjlSJPcF9KTXMCV2xEjHpHFeJYBbuqOvfsqRR/EGcDfFdjmlurXXRlVXixmMbifHw==","shasum":"09434bb17cb2d176d9e2bc7581e3d949218196d5","tarball":"https://registry.npmjs.org/@biubiupiu/openrouter-sdk-provider/-/openrouter-sdk-provider-1.5.5.tgz","fileCount":15,"unpackedSize":1564980,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDmrE4wzxpn4za9+ZB5rMvtdSIeBfI9uaYTKycRta5uxAIhAOX83RD3tG1TI462knUaQhWAh9/lXdwNi+fjnivhodyy"}]},"_npmUser":{"name":"biubiupiu","email":"biubiupiu_email@qq.com"},"directories":{},"maintainers":[{"name":"biubiupiu","email":"biubiupiu_email@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/openrouter-sdk-provider_1.5.5_1766420841983_0.8072494569931843"},"_hasShrinkwrap":false}},"time":{"created":"2025-12-22T16:27:21.899Z","1.5.5":"2025-12-22T16:27:22.151Z","modified":"2025-12-22T16:27:22.417Z"},"maintainers":[{"name":"biubiupiu","email":"biubiupiu_email@qq.com"}],"description":"The [OpenRouter](https://openrouter.ai/) provider for the [Vercel AI SDK](https://sdk.vercel.ai/docs) gives access to over 300 large language models on the OpenRouter chat and completion APIs.","homepage":"https://github.com/OpenRouterTeam/ai-sdk-provider","keywords":["ai"],"repository":{"type":"git","url":"git+https://github.com/OpenRouterTeam/ai-sdk-provider.git"},"bugs":{"url":"https://github.com/OpenRouterTeam/ai-sdk-provider/issues"},"license":"Apache-2.0","readme":"# OpenRouter Provider for Vercel AI SDK\n\nThe [OpenRouter](https://openrouter.ai/) provider for the [Vercel AI SDK](https://sdk.vercel.ai/docs) gives access to over 300 large language models on the OpenRouter chat and completion APIs.\n\n## Setup for AI SDK v5\n\n```bash\n# For pnpm\npnpm add @openrouter/ai-sdk-provider\n\n# For npm\nnpm install @openrouter/ai-sdk-provider\n\n# For yarn\nyarn add @openrouter/ai-sdk-provider\n```\n\n## (LEGACY) Setup for AI SDK v4\n\n```bash\n# For pnpm\npnpm add @openrouter/ai-sdk-provider@ai-sdk-v4\n\n# For npm\nnpm install @openrouter/ai-sdk-provider@ai-sdk-v4\n\n# For yarn\nyarn add @openrouter/ai-sdk-provider@ai-sdk-v4\n\n```\n\n## Provider Instance\n\nYou can import the default provider instance `openrouter` from `@openrouter/ai-sdk-provider`:\n\n```ts\nimport { openrouter } from '@openrouter/ai-sdk-provider';\n```\n\n## Example\n\n```ts\nimport { openrouter } from '@openrouter/ai-sdk-provider';\nimport { generateText } from 'ai';\n\nconst { text } = await generateText({\n  model: openrouter('openai/gpt-4o'),\n  prompt: 'Write a vegetarian lasagna recipe for 4 people.',\n});\n```\n\n## Supported models\n\nThis list is not a definitive list of models supported by OpenRouter, as it constantly changes as we add new models (and deprecate old ones) to our system. You can find the latest list of models supported by OpenRouter [here](https://openrouter.ai/models).\n\nYou can find the latest list of tool-supported models supported by OpenRouter [here](https://openrouter.ai/models?order=newest&supported_parameters=tools). (Note: This list may contain models that are not compatible with the AI SDK.)\n\n## Embeddings\n\nOpenRouter supports embedding models for semantic search, RAG pipelines, and vector-native features. The provider exposes embeddings compatible with both AI SDK v5 and v4.\n\n### AI SDK v5 (Recommended)\n\n```ts\nimport { embed } from 'ai';\nimport { openrouter } from '@openrouter/ai-sdk-provider';\n\nconst { embedding } = await embed({\n  model: openrouter.textEmbeddingModel('openai/text-embedding-3-small'),\n  value: 'sunny day at the beach',\n});\n\nconsole.log(embedding); // Array of numbers representing the embedding\n```\n\n### Batch Embeddings\n\n```ts\nimport { embedMany } from 'ai';\nimport { openrouter } from '@openrouter/ai-sdk-provider';\n\nconst { embeddings } = await embedMany({\n  model: openrouter.textEmbeddingModel('openai/text-embedding-3-small'),\n  values: [\n    'sunny day at the beach',\n    'rainy day in the city',\n    'snowy mountain peak',\n  ],\n});\n\nconsole.log(embeddings); // Array of embedding arrays\n```\n\n### AI SDK v4 (Deprecated)\n\nFor backwards compatibility, the `embedding` method is also available:\n\n```ts\nimport { embed } from 'ai';\nimport { openrouter } from '@openrouter/ai-sdk-provider';\n\nconst { embedding } = await embed({\n  model: openrouter.embedding('openai/text-embedding-3-small'),\n  value: 'sunny day at the beach',\n});\n```\n\n### Supported Embedding Models\n\nOpenRouter supports various embedding models including:\n- `openai/text-embedding-3-small`\n- `openai/text-embedding-3-large`\n- `openai/text-embedding-ada-002`\n- And more available on [OpenRouter](https://openrouter.ai/models?output_modalities=embeddings)\n\n## Passing Extra Body to OpenRouter\n\nThere are 3 ways to pass extra body to OpenRouter:\n\n1. Via the `providerOptions.openrouter` property:\n\n   ```typescript\n   import { createOpenRouter } from '@openrouter/ai-sdk-provider';\n   import { streamText } from 'ai';\n\n   const openrouter = createOpenRouter({ apiKey: 'your-api-key' });\n   const model = openrouter('anthropic/claude-3.7-sonnet:thinking');\n   await streamText({\n     model,\n     messages: [{ role: 'user', content: 'Hello' }],\n     providerOptions: {\n       openrouter: {\n         reasoning: {\n           max_tokens: 10,\n         },\n       },\n     },\n   });\n   ```\n\n2. Via the `extraBody` property in the model settings:\n\n   ```typescript\n   import { createOpenRouter } from '@openrouter/ai-sdk-provider';\n   import { streamText } from 'ai';\n\n   const openrouter = createOpenRouter({ apiKey: 'your-api-key' });\n   const model = openrouter('anthropic/claude-3.7-sonnet:thinking', {\n     extraBody: {\n       reasoning: {\n         max_tokens: 10,\n       },\n     },\n   });\n   await streamText({\n     model,\n     messages: [{ role: 'user', content: 'Hello' }],\n   });\n   ```\n\n3. Via the `extraBody` property in the model factory.\n\n   ```typescript\n   import { createOpenRouter } from '@openrouter/ai-sdk-provider';\n   import { streamText } from 'ai';\n\n   const openrouter = createOpenRouter({\n     apiKey: 'your-api-key',\n     extraBody: {\n       reasoning: {\n         max_tokens: 10,\n       },\n     },\n   });\n   const model = openrouter('anthropic/claude-3.7-sonnet:thinking');\n   await streamText({\n     model,\n     messages: [{ role: 'user', content: 'Hello' }],\n   });\n   ```\n\n## Anthropic Prompt Caching\n\nYou can include Anthropic-specific options directly in your messages when using functions like `streamText`. The OpenRouter provider will automatically convert these messages to the correct format internally.\n\n### Basic Usage\n\n```typescript\nimport { createOpenRouter } from '@openrouter/ai-sdk-provider';\nimport { streamText } from 'ai';\n\nconst openrouter = createOpenRouter({ apiKey: 'your-api-key' });\nconst model = openrouter('anthropic/<supported-caching-model>');\n\nawait streamText({\n  model,\n  messages: [\n    {\n      role: 'system',\n      content:\n        'You are a podcast summary assistant. You are detail-oriented and critical about the content.',\n    },\n    {\n      role: 'user',\n      content: [\n        {\n          type: 'text',\n          text: 'Given the text body below:',\n        },\n        {\n          type: 'text',\n          text: `<LARGE BODY OF TEXT>`,\n          providerOptions: {\n            openrouter: {\n              cacheControl: { type: 'ephemeral' },\n            },\n          },\n        },\n        {\n          type: 'text',\n          text: 'List the speakers?',\n        },\n      ],\n    },\n  ],\n});\n```\n## Anthropic Beta Features\n\nYou can enable Anthropic beta features by passing custom headers through the OpenRouter SDK.\n\n### Fine-grained Tool Streaming\n\n[Fine-grained tool streaming](https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/fine-grained-tool-streaming) allows streaming tool parameters without buffering, reducing latency for large schemas. This is particularly useful when working with large nested JSON structures.\n\n**Important:** This is a beta feature from Anthropic. Make sure to evaluate responses before using in production.\n\n#### Basic Usage\n\n```typescript\nimport { createOpenRouter } from '@openrouter/ai-sdk-provider';\nimport { streamObject } from 'ai';\n\nconst provider = createOpenRouter({\n  apiKey: process.env.OPENROUTER_API_KEY,\n  headers: {\n    'anthropic-beta': 'fine-grained-tool-streaming-2025-05-14',\n  },\n});\n\nconst model = provider.chat('anthropic/claude-sonnet-4');\n\nconst result = await streamObject({\n  model,\n  schema: yourLargeSchema,\n  prompt: 'Generate a complex object...',\n});\n\nfor await (const partialObject of result.partialObjectStream) {\n  console.log(partialObject);\n}\n```\n\nYou can also pass the header at the request level:\n\n```typescript\nimport { createOpenRouter } from '@openrouter/ai-sdk-provider';\nimport { generateText } from 'ai';\n\nconst provider = createOpenRouter({\n  apiKey: process.env.OPENROUTER_API_KEY,\n});\n\nconst model = provider.chat('anthropic/claude-sonnet-4');\n\nawait generateText({\n  model,\n  prompt: 'Hello',\n  headers: {\n    'anthropic-beta': 'fine-grained-tool-streaming-2025-05-14',\n  },\n});\n```\n\n**Note:** Fine-grained tool streaming is specific to Anthropic models. When using models from other providers, the header will be ignored.\n\n#### Use Case: Large Component Generation\n\nThis feature is particularly beneficial when streaming large, nested JSON structures like UI component trees:\n\n```typescript\nimport { createOpenRouter } from '@openrouter/ai-sdk-provider';\nimport { streamObject } from 'ai';\nimport { z } from 'zod';\n\nconst componentSchema = z.object({\n  type: z.string(),\n  props: z.record(z.any()),\n  children: z.array(z.lazy(() => componentSchema)).optional(),\n});\n\nconst provider = createOpenRouter({\n  apiKey: process.env.OPENROUTER_API_KEY,\n  headers: {\n    'anthropic-beta': 'fine-grained-tool-streaming-2025-05-14',\n  },\n});\n\nconst model = provider.chat('anthropic/claude-sonnet-4');\n\nconst result = await streamObject({\n  model,\n  schema: componentSchema,\n  prompt: 'Create a responsive dashboard layout',\n});\n\nfor await (const partialComponent of result.partialObjectStream) {\n  console.log('Partial component:', partialComponent);\n}\n```\n\n\n\n## Use Cases\n\n### Debugging API Requests\n\nThe provider supports a debug mode that echoes back the request body sent to the upstream provider. This is useful for troubleshooting and understanding how your requests are being processed. Note that debug mode only works with streaming requests.\n\n```typescript\nimport { createOpenRouter } from '@openrouter/ai-sdk-provider';\nimport { streamText } from 'ai';\n\nconst openrouter = createOpenRouter({ apiKey: 'your-api-key' });\nconst model = openrouter('anthropic/claude-3.5-sonnet', {\n  debug: {\n    echo_upstream_body: true,\n  },\n});\n\nconst result = await streamText({\n  model,\n  prompt: 'Hello, how are you?',\n});\n\n// The debug data is available in the stream's first chunk\n// and in the final response's providerMetadata\nfor await (const chunk of result.fullStream) {\n  // Debug chunks have empty choices and contain debug.echo_upstream_body\n  console.log(chunk);\n}\n```\n\nThe debug response will include the request body that was sent to the upstream provider, with sensitive data redacted (user IDs, base64 content, etc.). This helps you understand how OpenRouter transforms your request before sending it to the model provider.\n\n### Usage Accounting\n\nThe provider supports [OpenRouter usage accounting](https://openrouter.ai/docs/use-cases/usage-accounting), which allows you to track token usage details directly in your API responses, without making additional API calls.\n\n```typescript\n// Enable usage accounting\nconst model = openrouter('openai/gpt-3.5-turbo', {\n  usage: {\n    include: true,\n  },\n});\n\n// Access usage accounting data\nconst result = await generateText({\n  model,\n  prompt: 'Hello, how are you today?',\n});\n\n// Provider-specific usage details (available in providerMetadata)\nif (result.providerMetadata?.openrouter?.usage) {\n  console.log('Cost:', result.providerMetadata.openrouter.usage.cost);\n  console.log(\n    'Total Tokens:',\n    result.providerMetadata.openrouter.usage.totalTokens,\n  );\n}\n```\n\nIt also supports BYOK (Bring Your Own Key) [usage accounting](https://openrouter.ai/docs/docs/guides/usage-accounting#cost-breakdown), which allows you to track passthrough costs when you are using a provider's own API key in your OpenRouter account.\n\n```typescript\n// Assuming you have set an OpenAI API key in https://openrouter.ai/settings/integrations\n\n// Enable usage accounting\nconst model = openrouter('openai/gpt-3.5-turbo', {\n  usage: {\n    include: true,\n  },\n});\n\n// Access usage accounting data\nconst result = await generateText({\n  model,\n  prompt: 'Hello, how are you today?',\n});\n\n// Provider-specific BYOK usage details (available in providerMetadata)\nif (result.providerMetadata?.openrouter?.usage) {\n  const costDetails = result.providerMetadata.openrouter.usage.costDetails;\n  if (costDetails) {\n    console.log('BYOK cost:', costDetails.upstreamInferenceCost);\n  }\n  console.log('OpenRouter credits cost:', result.providerMetadata.openrouter.usage.cost);\n  console.log(\n    'Total Tokens:',\n    result.providerMetadata.openrouter.usage.totalTokens,\n  );\n}\n```\n","readmeFilename":"README.md","_rev":"1-c0449efb6d20a09b30ce399b92502a7a"}