@openrouter/ai-sdk-provider 2.2.5 → 2.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -151,6 +151,25 @@ type OpenRouterChatSettings = {
151
151
  */
152
152
  engine?: Engine;
153
153
  };
154
+ /**
155
+ * Enable Anthropic automatic prompt caching by setting a top-level cache_control
156
+ * directive on the request body. When set to `{ type: 'ephemeral' }`, Anthropic
157
+ * will automatically cache eligible content in your prompts.
158
+ *
159
+ * Only works with Anthropic models through OpenRouter.
160
+ *
161
+ * @see https://platform.claude.com/docs/en/build-with-claude/prompt-caching#automatic-caching
162
+ * @see https://openrouter.ai/docs
163
+ */
164
+ cache_control?: {
165
+ type: 'ephemeral';
166
+ /**
167
+ * Optional time-to-live for the cache entry.
168
+ * - `'5m'` — 5 minutes (default when omitted)
169
+ * - `'1h'` — 1 hour
170
+ */
171
+ ttl?: '5m' | '1h';
172
+ };
154
173
  /**
155
174
  * Debug options for troubleshooting API requests.
156
175
  * Only works with streaming requests.
package/dist/index.d.ts CHANGED
@@ -151,6 +151,25 @@ type OpenRouterChatSettings = {
151
151
  */
152
152
  engine?: Engine;
153
153
  };
154
+ /**
155
+ * Enable Anthropic automatic prompt caching by setting a top-level cache_control
156
+ * directive on the request body. When set to `{ type: 'ephemeral' }`, Anthropic
157
+ * will automatically cache eligible content in your prompts.
158
+ *
159
+ * Only works with Anthropic models through OpenRouter.
160
+ *
161
+ * @see https://platform.claude.com/docs/en/build-with-claude/prompt-caching#automatic-caching
162
+ * @see https://openrouter.ai/docs
163
+ */
164
+ cache_control?: {
165
+ type: 'ephemeral';
166
+ /**
167
+ * Optional time-to-live for the cache entry.
168
+ * - `'5m'` — 5 minutes (default when omitted)
169
+ * - `'1h'` — 1 hour
170
+ */
171
+ ttl?: '5m' | '1h';
172
+ };
154
173
  /**
155
174
  * Debug options for troubleshooting API requests.
156
175
  * Only works with streaming requests.
package/dist/index.js CHANGED
@@ -2793,11 +2793,12 @@ function convertToOpenRouterChatMessages(prompt) {
2793
2793
  }
2794
2794
  finalReasoningDetails = uniqueDetails.length > 0 ? uniqueDetails : void 0;
2795
2795
  }
2796
+ const effectiveReasoning = reasoning && finalReasoningDetails ? reasoning : void 0;
2796
2797
  messages.push({
2797
2798
  role: "assistant",
2798
2799
  content: text,
2799
2800
  tool_calls: toolCalls.length > 0 ? toolCalls : void 0,
2800
- reasoning: reasoning || void 0,
2801
+ reasoning: effectiveReasoning,
2801
2802
  reasoning_details: finalReasoningDetails,
2802
2803
  annotations: messageAnnotations,
2803
2804
  cache_control: getCacheControl(providerOptions)
@@ -3179,7 +3180,9 @@ var OpenRouterChatLanguageModel = class {
3179
3180
  // Provider routing settings:
3180
3181
  provider: this.settings.provider,
3181
3182
  // Debug settings:
3182
- debug: this.settings.debug
3183
+ debug: this.settings.debug,
3184
+ // Anthropic automatic caching:
3185
+ cache_control: this.settings.cache_control
3183
3186
  }, this.config.extraBody), this.settings.extraBody);
3184
3187
  if (tools && tools.length > 0) {
3185
3188
  const mappedTools = tools.filter(
@@ -3200,10 +3203,11 @@ var OpenRouterChatLanguageModel = class {
3200
3203
  return baseArgs;
3201
3204
  }
3202
3205
  async doGenerate(options) {
3203
- var _a16, _b16, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v;
3206
+ var _b16, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w;
3204
3207
  const providerOptions = options.providerOptions || {};
3205
3208
  const openrouterOptions = providerOptions.openrouter || {};
3206
- const args = __spreadValues(__spreadValues({}, this.getArgs(options)), openrouterOptions);
3209
+ const _a16 = openrouterOptions, { cacheControl } = _a16, restOpenrouterOptions = __objRest(_a16, ["cacheControl"]);
3210
+ const args = __spreadValues(__spreadValues(__spreadValues({}, this.getArgs(options)), restOpenrouterOptions), cacheControl != null && !("cache_control" in restOpenrouterOptions) ? { cache_control: cacheControl } : {});
3207
3211
  const { value: responseValue, responseHeaders } = await postJsonToApi({
3208
3212
  url: this.config.url({
3209
3213
  path: "/chat/completions",
@@ -3240,7 +3244,7 @@ var OpenRouterChatLanguageModel = class {
3240
3244
  });
3241
3245
  }
3242
3246
  const usageInfo = response.usage ? computeTokenUsage(response.usage) : emptyUsage();
3243
- const reasoningDetails = (_a16 = choice.message.reasoning_details) != null ? _a16 : [];
3247
+ const reasoningDetails = (_b16 = choice.message.reasoning_details) != null ? _b16 : [];
3244
3248
  const reasoning = reasoningDetails.length > 0 ? reasoningDetails.map((detail) => {
3245
3249
  switch (detail.type) {
3246
3250
  case "reasoning.text" /* Text */: {
@@ -3309,9 +3313,9 @@ var OpenRouterChatLanguageModel = class {
3309
3313
  for (const toolCall of choice.message.tool_calls) {
3310
3314
  content.push({
3311
3315
  type: "tool-call",
3312
- toolCallId: (_b16 = toolCall.id) != null ? _b16 : generateId(),
3316
+ toolCallId: (_c = toolCall.id) != null ? _c : generateId(),
3313
3317
  toolName: toolCall.function.name,
3314
- input: (_c = toolCall.function.arguments) != null ? _c : "{}",
3318
+ input: (_d = toolCall.function.arguments) != null ? _d : "{}",
3315
3319
  providerMetadata: !reasoningDetailsAttachedToToolCall ? {
3316
3320
  openrouter: {
3317
3321
  reasoning_details: reasoningDetails
@@ -3338,19 +3342,19 @@ var OpenRouterChatLanguageModel = class {
3338
3342
  sourceType: "url",
3339
3343
  id: annotation.url_citation.url,
3340
3344
  url: annotation.url_citation.url,
3341
- title: (_d = annotation.url_citation.title) != null ? _d : "",
3345
+ title: (_e = annotation.url_citation.title) != null ? _e : "",
3342
3346
  providerMetadata: {
3343
3347
  openrouter: {
3344
- content: (_e = annotation.url_citation.content) != null ? _e : "",
3345
- startIndex: (_f = annotation.url_citation.start_index) != null ? _f : 0,
3346
- endIndex: (_g = annotation.url_citation.end_index) != null ? _g : 0
3348
+ content: (_f = annotation.url_citation.content) != null ? _f : "",
3349
+ startIndex: (_g = annotation.url_citation.start_index) != null ? _g : 0,
3350
+ endIndex: (_h = annotation.url_citation.end_index) != null ? _h : 0
3347
3351
  }
3348
3352
  }
3349
3353
  });
3350
3354
  }
3351
3355
  }
3352
3356
  }
3353
- const fileAnnotations = (_h = choice.message.annotations) == null ? void 0 : _h.filter(
3357
+ const fileAnnotations = (_i = choice.message.annotations) == null ? void 0 : _i.filter(
3354
3358
  (a) => a.type === "file"
3355
3359
  );
3356
3360
  const hasToolCalls = choice.message.tool_calls && choice.message.tool_calls.length > 0;
@@ -3358,7 +3362,7 @@ var OpenRouterChatLanguageModel = class {
3358
3362
  (d) => d.type === "reasoning.encrypted" /* Encrypted */ && d.data
3359
3363
  );
3360
3364
  const shouldOverrideFinishReason = hasToolCalls && hasEncryptedReasoning && choice.finish_reason === "stop";
3361
- const effectiveFinishReason = shouldOverrideFinishReason ? createFinishReason("tool-calls", (_i = choice.finish_reason) != null ? _i : void 0) : mapOpenRouterFinishReason(choice.finish_reason);
3365
+ const effectiveFinishReason = shouldOverrideFinishReason ? createFinishReason("tool-calls", (_j = choice.finish_reason) != null ? _j : void 0) : mapOpenRouterFinishReason(choice.finish_reason);
3362
3366
  return {
3363
3367
  content,
3364
3368
  finishReason: effectiveFinishReason,
@@ -3366,22 +3370,22 @@ var OpenRouterChatLanguageModel = class {
3366
3370
  warnings: [],
3367
3371
  providerMetadata: {
3368
3372
  openrouter: OpenRouterProviderMetadataSchema.parse({
3369
- provider: (_j = response.provider) != null ? _j : "",
3370
- reasoning_details: (_k = choice.message.reasoning_details) != null ? _k : [],
3373
+ provider: (_k = response.provider) != null ? _k : "",
3374
+ reasoning_details: (_l = choice.message.reasoning_details) != null ? _l : [],
3371
3375
  annotations: fileAnnotations && fileAnnotations.length > 0 ? fileAnnotations : void 0,
3372
3376
  usage: __spreadValues(__spreadValues(__spreadValues(__spreadValues({
3373
- promptTokens: (_l = usageInfo.inputTokens.total) != null ? _l : 0,
3374
- completionTokens: (_m = usageInfo.outputTokens.total) != null ? _m : 0,
3375
- totalTokens: ((_n = usageInfo.inputTokens.total) != null ? _n : 0) + ((_o = usageInfo.outputTokens.total) != null ? _o : 0)
3376
- }, ((_p = response.usage) == null ? void 0 : _p.cost) != null ? { cost: response.usage.cost } : {}), ((_r = (_q = response.usage) == null ? void 0 : _q.prompt_tokens_details) == null ? void 0 : _r.cached_tokens) != null ? {
3377
+ promptTokens: (_m = usageInfo.inputTokens.total) != null ? _m : 0,
3378
+ completionTokens: (_n = usageInfo.outputTokens.total) != null ? _n : 0,
3379
+ totalTokens: ((_o = usageInfo.inputTokens.total) != null ? _o : 0) + ((_p = usageInfo.outputTokens.total) != null ? _p : 0)
3380
+ }, ((_q = response.usage) == null ? void 0 : _q.cost) != null ? { cost: response.usage.cost } : {}), ((_s = (_r = response.usage) == null ? void 0 : _r.prompt_tokens_details) == null ? void 0 : _s.cached_tokens) != null ? {
3377
3381
  promptTokensDetails: {
3378
3382
  cachedTokens: response.usage.prompt_tokens_details.cached_tokens
3379
3383
  }
3380
- } : {}), ((_t = (_s = response.usage) == null ? void 0 : _s.completion_tokens_details) == null ? void 0 : _t.reasoning_tokens) != null ? {
3384
+ } : {}), ((_u = (_t = response.usage) == null ? void 0 : _t.completion_tokens_details) == null ? void 0 : _u.reasoning_tokens) != null ? {
3381
3385
  completionTokensDetails: {
3382
3386
  reasoningTokens: response.usage.completion_tokens_details.reasoning_tokens
3383
3387
  }
3384
- } : {}), ((_v = (_u = response.usage) == null ? void 0 : _u.cost_details) == null ? void 0 : _v.upstream_inference_cost) != null ? {
3388
+ } : {}), ((_w = (_v = response.usage) == null ? void 0 : _v.cost_details) == null ? void 0 : _w.upstream_inference_cost) != null ? {
3385
3389
  costDetails: {
3386
3390
  upstreamInferenceCost: response.usage.cost_details.upstream_inference_cost
3387
3391
  }
@@ -3397,10 +3401,11 @@ var OpenRouterChatLanguageModel = class {
3397
3401
  };
3398
3402
  }
3399
3403
  async doStream(options) {
3400
- var _a16;
3404
+ var _b16;
3401
3405
  const providerOptions = options.providerOptions || {};
3402
3406
  const openrouterOptions = providerOptions.openrouter || {};
3403
- const args = __spreadValues(__spreadValues({}, this.getArgs(options)), openrouterOptions);
3407
+ const _a16 = openrouterOptions, { cacheControl } = _a16, restOpenrouterOptions = __objRest(_a16, ["cacheControl"]);
3408
+ const args = __spreadValues(__spreadValues(__spreadValues({}, this.getArgs(options)), restOpenrouterOptions), cacheControl != null && !("cache_control" in restOpenrouterOptions) ? { cache_control: cacheControl } : {});
3404
3409
  const { value: response, responseHeaders } = await postJsonToApi({
3405
3410
  url: this.config.url({
3406
3411
  path: "/chat/completions",
@@ -3412,7 +3417,7 @@ var OpenRouterChatLanguageModel = class {
3412
3417
  // only include stream_options when in strict compatibility mode:
3413
3418
  stream_options: this.config.compatibility === "strict" ? __spreadValues({
3414
3419
  include_usage: true
3415
- }, ((_a16 = this.settings.usage) == null ? void 0 : _a16.include) ? { include_usage: true } : {}) : void 0
3420
+ }, ((_b16 = this.settings.usage) == null ? void 0 : _b16.include) ? { include_usage: true } : {}) : void 0
3416
3421
  }),
3417
3422
  failedResponseHandler: openrouterFailedResponseHandler,
3418
3423
  successfulResponseHandler: createEventSourceResponseHandler(
@@ -3452,7 +3457,7 @@ var OpenRouterChatLanguageModel = class {
3452
3457
  stream: response.pipeThrough(
3453
3458
  new TransformStream({
3454
3459
  transform(chunk, controller) {
3455
- var _a17, _b16, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u;
3460
+ var _a17, _b17, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u;
3456
3461
  if (options.includeRawChunks) {
3457
3462
  controller.enqueue({ type: "raw", rawValue: chunk.rawValue });
3458
3463
  }
@@ -3489,7 +3494,7 @@ var OpenRouterChatLanguageModel = class {
3489
3494
  Object.assign(usage.outputTokens, computed.outputTokens);
3490
3495
  rawUsage = value.usage;
3491
3496
  const promptTokens = (_a17 = value.usage.prompt_tokens) != null ? _a17 : 0;
3492
- const completionTokens = (_b16 = value.usage.completion_tokens) != null ? _b16 : 0;
3497
+ const completionTokens = (_b17 = value.usage.completion_tokens) != null ? _b17 : 0;
3493
3498
  openrouterUsage.promptTokens = promptTokens;
3494
3499
  if (value.usage.prompt_tokens_details) {
3495
3500
  openrouterUsage.promptTokensDetails = {
@@ -4605,7 +4610,7 @@ function withUserAgentSuffix2(headers, ...userAgentSuffixParts) {
4605
4610
  }
4606
4611
 
4607
4612
  // src/version.ts
4608
- var VERSION2 = false ? "0.0.0-test" : "2.2.5";
4613
+ var VERSION2 = false ? "0.0.0-test" : "2.3.1";
4609
4614
 
4610
4615
  // src/provider.ts
4611
4616
  function createOpenRouter(options = {}) {