@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.
@@ -186,6 +186,25 @@ type OpenRouterChatSettings = {
186
186
  */
187
187
  engine?: Engine;
188
188
  };
189
+ /**
190
+ * Enable Anthropic automatic prompt caching by setting a top-level cache_control
191
+ * directive on the request body. When set to `{ type: 'ephemeral' }`, Anthropic
192
+ * will automatically cache eligible content in your prompts.
193
+ *
194
+ * Only works with Anthropic models through OpenRouter.
195
+ *
196
+ * @see https://platform.claude.com/docs/en/build-with-claude/prompt-caching#automatic-caching
197
+ * @see https://openrouter.ai/docs
198
+ */
199
+ cache_control?: {
200
+ type: 'ephemeral';
201
+ /**
202
+ * Optional time-to-live for the cache entry.
203
+ * - `'5m'` — 5 minutes (default when omitted)
204
+ * - `'1h'` — 1 hour
205
+ */
206
+ ttl?: '5m' | '1h';
207
+ };
189
208
  /**
190
209
  * Debug options for troubleshooting API requests.
191
210
  * Only works with streaming requests.
@@ -186,6 +186,25 @@ type OpenRouterChatSettings = {
186
186
  */
187
187
  engine?: Engine;
188
188
  };
189
+ /**
190
+ * Enable Anthropic automatic prompt caching by setting a top-level cache_control
191
+ * directive on the request body. When set to `{ type: 'ephemeral' }`, Anthropic
192
+ * will automatically cache eligible content in your prompts.
193
+ *
194
+ * Only works with Anthropic models through OpenRouter.
195
+ *
196
+ * @see https://platform.claude.com/docs/en/build-with-claude/prompt-caching#automatic-caching
197
+ * @see https://openrouter.ai/docs
198
+ */
199
+ cache_control?: {
200
+ type: 'ephemeral';
201
+ /**
202
+ * Optional time-to-live for the cache entry.
203
+ * - `'5m'` — 5 minutes (default when omitted)
204
+ * - `'1h'` — 1 hour
205
+ */
206
+ ttl?: '5m' | '1h';
207
+ };
189
208
  /**
190
209
  * Debug options for troubleshooting API requests.
191
210
  * Only works with streaming requests.
@@ -2759,11 +2759,12 @@ function convertToOpenRouterChatMessages(prompt) {
2759
2759
  }
2760
2760
  finalReasoningDetails = uniqueDetails.length > 0 ? uniqueDetails : void 0;
2761
2761
  }
2762
+ const effectiveReasoning = reasoning && finalReasoningDetails ? reasoning : void 0;
2762
2763
  messages.push({
2763
2764
  role: "assistant",
2764
2765
  content: text,
2765
2766
  tool_calls: toolCalls.length > 0 ? toolCalls : void 0,
2766
- reasoning: reasoning || void 0,
2767
+ reasoning: effectiveReasoning,
2767
2768
  reasoning_details: finalReasoningDetails,
2768
2769
  annotations: messageAnnotations,
2769
2770
  cache_control: getCacheControl(providerOptions)
@@ -3145,7 +3146,9 @@ var OpenRouterChatLanguageModel = class {
3145
3146
  // Provider routing settings:
3146
3147
  provider: this.settings.provider,
3147
3148
  // Debug settings:
3148
- debug: this.settings.debug
3149
+ debug: this.settings.debug,
3150
+ // Anthropic automatic caching:
3151
+ cache_control: this.settings.cache_control
3149
3152
  }, this.config.extraBody), this.settings.extraBody);
3150
3153
  if (tools && tools.length > 0) {
3151
3154
  const mappedTools = tools.filter(
@@ -3166,10 +3169,11 @@ var OpenRouterChatLanguageModel = class {
3166
3169
  return baseArgs;
3167
3170
  }
3168
3171
  async doGenerate(options) {
3169
- var _a16, _b16, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v;
3172
+ var _b16, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w;
3170
3173
  const providerOptions = options.providerOptions || {};
3171
3174
  const openrouterOptions = providerOptions.openrouter || {};
3172
- const args = __spreadValues(__spreadValues({}, this.getArgs(options)), openrouterOptions);
3175
+ const _a16 = openrouterOptions, { cacheControl } = _a16, restOpenrouterOptions = __objRest(_a16, ["cacheControl"]);
3176
+ const args = __spreadValues(__spreadValues(__spreadValues({}, this.getArgs(options)), restOpenrouterOptions), cacheControl != null && !("cache_control" in restOpenrouterOptions) ? { cache_control: cacheControl } : {});
3173
3177
  const { value: responseValue, responseHeaders } = await postJsonToApi({
3174
3178
  url: this.config.url({
3175
3179
  path: "/chat/completions",
@@ -3206,7 +3210,7 @@ var OpenRouterChatLanguageModel = class {
3206
3210
  });
3207
3211
  }
3208
3212
  const usageInfo = response.usage ? computeTokenUsage(response.usage) : emptyUsage();
3209
- const reasoningDetails = (_a16 = choice.message.reasoning_details) != null ? _a16 : [];
3213
+ const reasoningDetails = (_b16 = choice.message.reasoning_details) != null ? _b16 : [];
3210
3214
  const reasoning = reasoningDetails.length > 0 ? reasoningDetails.map((detail) => {
3211
3215
  switch (detail.type) {
3212
3216
  case "reasoning.text" /* Text */: {
@@ -3275,9 +3279,9 @@ var OpenRouterChatLanguageModel = class {
3275
3279
  for (const toolCall of choice.message.tool_calls) {
3276
3280
  content.push({
3277
3281
  type: "tool-call",
3278
- toolCallId: (_b16 = toolCall.id) != null ? _b16 : generateId(),
3282
+ toolCallId: (_c = toolCall.id) != null ? _c : generateId(),
3279
3283
  toolName: toolCall.function.name,
3280
- input: (_c = toolCall.function.arguments) != null ? _c : "{}",
3284
+ input: (_d = toolCall.function.arguments) != null ? _d : "{}",
3281
3285
  providerMetadata: !reasoningDetailsAttachedToToolCall ? {
3282
3286
  openrouter: {
3283
3287
  reasoning_details: reasoningDetails
@@ -3304,19 +3308,19 @@ var OpenRouterChatLanguageModel = class {
3304
3308
  sourceType: "url",
3305
3309
  id: annotation.url_citation.url,
3306
3310
  url: annotation.url_citation.url,
3307
- title: (_d = annotation.url_citation.title) != null ? _d : "",
3311
+ title: (_e = annotation.url_citation.title) != null ? _e : "",
3308
3312
  providerMetadata: {
3309
3313
  openrouter: {
3310
- content: (_e = annotation.url_citation.content) != null ? _e : "",
3311
- startIndex: (_f = annotation.url_citation.start_index) != null ? _f : 0,
3312
- endIndex: (_g = annotation.url_citation.end_index) != null ? _g : 0
3314
+ content: (_f = annotation.url_citation.content) != null ? _f : "",
3315
+ startIndex: (_g = annotation.url_citation.start_index) != null ? _g : 0,
3316
+ endIndex: (_h = annotation.url_citation.end_index) != null ? _h : 0
3313
3317
  }
3314
3318
  }
3315
3319
  });
3316
3320
  }
3317
3321
  }
3318
3322
  }
3319
- const fileAnnotations = (_h = choice.message.annotations) == null ? void 0 : _h.filter(
3323
+ const fileAnnotations = (_i = choice.message.annotations) == null ? void 0 : _i.filter(
3320
3324
  (a) => a.type === "file"
3321
3325
  );
3322
3326
  const hasToolCalls = choice.message.tool_calls && choice.message.tool_calls.length > 0;
@@ -3324,7 +3328,7 @@ var OpenRouterChatLanguageModel = class {
3324
3328
  (d) => d.type === "reasoning.encrypted" /* Encrypted */ && d.data
3325
3329
  );
3326
3330
  const shouldOverrideFinishReason = hasToolCalls && hasEncryptedReasoning && choice.finish_reason === "stop";
3327
- const effectiveFinishReason = shouldOverrideFinishReason ? createFinishReason("tool-calls", (_i = choice.finish_reason) != null ? _i : void 0) : mapOpenRouterFinishReason(choice.finish_reason);
3331
+ const effectiveFinishReason = shouldOverrideFinishReason ? createFinishReason("tool-calls", (_j = choice.finish_reason) != null ? _j : void 0) : mapOpenRouterFinishReason(choice.finish_reason);
3328
3332
  return {
3329
3333
  content,
3330
3334
  finishReason: effectiveFinishReason,
@@ -3332,22 +3336,22 @@ var OpenRouterChatLanguageModel = class {
3332
3336
  warnings: [],
3333
3337
  providerMetadata: {
3334
3338
  openrouter: OpenRouterProviderMetadataSchema.parse({
3335
- provider: (_j = response.provider) != null ? _j : "",
3336
- reasoning_details: (_k = choice.message.reasoning_details) != null ? _k : [],
3339
+ provider: (_k = response.provider) != null ? _k : "",
3340
+ reasoning_details: (_l = choice.message.reasoning_details) != null ? _l : [],
3337
3341
  annotations: fileAnnotations && fileAnnotations.length > 0 ? fileAnnotations : void 0,
3338
3342
  usage: __spreadValues(__spreadValues(__spreadValues(__spreadValues({
3339
- promptTokens: (_l = usageInfo.inputTokens.total) != null ? _l : 0,
3340
- completionTokens: (_m = usageInfo.outputTokens.total) != null ? _m : 0,
3341
- totalTokens: ((_n = usageInfo.inputTokens.total) != null ? _n : 0) + ((_o = usageInfo.outputTokens.total) != null ? _o : 0)
3342
- }, ((_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 ? {
3343
+ promptTokens: (_m = usageInfo.inputTokens.total) != null ? _m : 0,
3344
+ completionTokens: (_n = usageInfo.outputTokens.total) != null ? _n : 0,
3345
+ totalTokens: ((_o = usageInfo.inputTokens.total) != null ? _o : 0) + ((_p = usageInfo.outputTokens.total) != null ? _p : 0)
3346
+ }, ((_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 ? {
3343
3347
  promptTokensDetails: {
3344
3348
  cachedTokens: response.usage.prompt_tokens_details.cached_tokens
3345
3349
  }
3346
- } : {}), ((_t = (_s = response.usage) == null ? void 0 : _s.completion_tokens_details) == null ? void 0 : _t.reasoning_tokens) != null ? {
3350
+ } : {}), ((_u = (_t = response.usage) == null ? void 0 : _t.completion_tokens_details) == null ? void 0 : _u.reasoning_tokens) != null ? {
3347
3351
  completionTokensDetails: {
3348
3352
  reasoningTokens: response.usage.completion_tokens_details.reasoning_tokens
3349
3353
  }
3350
- } : {}), ((_v = (_u = response.usage) == null ? void 0 : _u.cost_details) == null ? void 0 : _v.upstream_inference_cost) != null ? {
3354
+ } : {}), ((_w = (_v = response.usage) == null ? void 0 : _v.cost_details) == null ? void 0 : _w.upstream_inference_cost) != null ? {
3351
3355
  costDetails: {
3352
3356
  upstreamInferenceCost: response.usage.cost_details.upstream_inference_cost
3353
3357
  }
@@ -3363,10 +3367,11 @@ var OpenRouterChatLanguageModel = class {
3363
3367
  };
3364
3368
  }
3365
3369
  async doStream(options) {
3366
- var _a16;
3370
+ var _b16;
3367
3371
  const providerOptions = options.providerOptions || {};
3368
3372
  const openrouterOptions = providerOptions.openrouter || {};
3369
- const args = __spreadValues(__spreadValues({}, this.getArgs(options)), openrouterOptions);
3373
+ const _a16 = openrouterOptions, { cacheControl } = _a16, restOpenrouterOptions = __objRest(_a16, ["cacheControl"]);
3374
+ const args = __spreadValues(__spreadValues(__spreadValues({}, this.getArgs(options)), restOpenrouterOptions), cacheControl != null && !("cache_control" in restOpenrouterOptions) ? { cache_control: cacheControl } : {});
3370
3375
  const { value: response, responseHeaders } = await postJsonToApi({
3371
3376
  url: this.config.url({
3372
3377
  path: "/chat/completions",
@@ -3378,7 +3383,7 @@ var OpenRouterChatLanguageModel = class {
3378
3383
  // only include stream_options when in strict compatibility mode:
3379
3384
  stream_options: this.config.compatibility === "strict" ? __spreadValues({
3380
3385
  include_usage: true
3381
- }, ((_a16 = this.settings.usage) == null ? void 0 : _a16.include) ? { include_usage: true } : {}) : void 0
3386
+ }, ((_b16 = this.settings.usage) == null ? void 0 : _b16.include) ? { include_usage: true } : {}) : void 0
3382
3387
  }),
3383
3388
  failedResponseHandler: openrouterFailedResponseHandler,
3384
3389
  successfulResponseHandler: createEventSourceResponseHandler(
@@ -3418,7 +3423,7 @@ var OpenRouterChatLanguageModel = class {
3418
3423
  stream: response.pipeThrough(
3419
3424
  new TransformStream({
3420
3425
  transform(chunk, controller) {
3421
- var _a17, _b16, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u;
3426
+ var _a17, _b17, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u;
3422
3427
  if (options.includeRawChunks) {
3423
3428
  controller.enqueue({ type: "raw", rawValue: chunk.rawValue });
3424
3429
  }
@@ -3455,7 +3460,7 @@ var OpenRouterChatLanguageModel = class {
3455
3460
  Object.assign(usage.outputTokens, computed.outputTokens);
3456
3461
  rawUsage = value.usage;
3457
3462
  const promptTokens = (_a17 = value.usage.prompt_tokens) != null ? _a17 : 0;
3458
- const completionTokens = (_b16 = value.usage.completion_tokens) != null ? _b16 : 0;
3463
+ const completionTokens = (_b17 = value.usage.completion_tokens) != null ? _b17 : 0;
3459
3464
  openrouterUsage.promptTokens = promptTokens;
3460
3465
  if (value.usage.prompt_tokens_details) {
3461
3466
  openrouterUsage.promptTokensDetails = {