@openrouter/ai-sdk-provider 2.3.1 → 2.3.3

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
@@ -431,6 +431,7 @@ type OpenRouterCompletionSettings = {
431
431
  declare enum ReasoningFormat {
432
432
  Unknown = "unknown",
433
433
  OpenAIResponsesV1 = "openai-responses-v1",
434
+ AzureOpenAIResponsesV1 = "azure-openai-responses-v1",
434
435
  XAIResponsesV1 = "xai-responses-v1",
435
436
  AnthropicClaudeV1 = "anthropic-claude-v1",
436
437
  GoogleGeminiV1 = "google-gemini-v1"
package/dist/index.d.ts CHANGED
@@ -431,6 +431,7 @@ type OpenRouterCompletionSettings = {
431
431
  declare enum ReasoningFormat {
432
432
  Unknown = "unknown",
433
433
  OpenAIResponsesV1 = "openai-responses-v1",
434
+ AzureOpenAIResponsesV1 = "azure-openai-responses-v1",
434
435
  XAIResponsesV1 = "xai-responses-v1",
435
436
  AnthropicClaudeV1 = "anthropic-claude-v1",
436
437
  GoogleGeminiV1 = "google-gemini-v1"
package/dist/index.js CHANGED
@@ -2216,11 +2216,13 @@ function isDefinedOrNotNull(value) {
2216
2216
  var ReasoningFormat = /* @__PURE__ */ ((ReasoningFormat2) => {
2217
2217
  ReasoningFormat2["Unknown"] = "unknown";
2218
2218
  ReasoningFormat2["OpenAIResponsesV1"] = "openai-responses-v1";
2219
+ ReasoningFormat2["AzureOpenAIResponsesV1"] = "azure-openai-responses-v1";
2219
2220
  ReasoningFormat2["XAIResponsesV1"] = "xai-responses-v1";
2220
2221
  ReasoningFormat2["AnthropicClaudeV1"] = "anthropic-claude-v1";
2221
2222
  ReasoningFormat2["GoogleGeminiV1"] = "google-gemini-v1";
2222
2223
  return ReasoningFormat2;
2223
2224
  })(ReasoningFormat || {});
2225
+ var DEFAULT_REASONING_FORMAT = "anthropic-claude-v1" /* AnthropicClaudeV1 */;
2224
2226
 
2225
2227
  // src/schemas/reasoning-details.ts
2226
2228
  var CommonReasoningDetailSchema = import_v4.z.object({
@@ -2373,7 +2375,11 @@ var OpenRouterProviderMetadataSchema = import_v43.z.object({
2373
2375
  }).catchall(import_v43.z.any());
2374
2376
  var OpenRouterProviderOptionsSchema = import_v43.z.object({
2375
2377
  openrouter: import_v43.z.object({
2376
- reasoning_details: import_v43.z.array(ReasoningDetailUnionSchema).optional(),
2378
+ // Use ReasoningDetailArraySchema (with unknown fallback) instead of
2379
+ // z.array(ReasoningDetailUnionSchema) so that a single malformed entry
2380
+ // (e.g., a future format not yet in the enum) is individually dropped
2381
+ // rather than causing the entire array to fail parsing.
2382
+ reasoning_details: ReasoningDetailArraySchema.optional(),
2377
2383
  annotations: import_v43.z.array(FileAnnotationSchema).optional()
2378
2384
  }).optional()
2379
2385
  }).optional();
@@ -2785,8 +2791,24 @@ function convertToOpenRouterChatMessages(prompt) {
2785
2791
  const candidateReasoningDetails = messageReasoningDetails && Array.isArray(messageReasoningDetails) && messageReasoningDetails.length > 0 ? messageReasoningDetails : findFirstReasoningDetails(content);
2786
2792
  let finalReasoningDetails;
2787
2793
  if (candidateReasoningDetails && candidateReasoningDetails.length > 0) {
2794
+ const validDetails = candidateReasoningDetails.filter((detail) => {
2795
+ var _a17;
2796
+ if (detail.type !== "reasoning.text" /* Text */) {
2797
+ return true;
2798
+ }
2799
+ const format = (_a17 = detail.format) != null ? _a17 : DEFAULT_REASONING_FORMAT;
2800
+ if (format !== "anthropic-claude-v1" /* AnthropicClaudeV1 */) {
2801
+ return true;
2802
+ }
2803
+ return !!detail.signature;
2804
+ });
2805
+ if (validDetails.length < candidateReasoningDetails.length) {
2806
+ console.warn(
2807
+ "[openrouter] Some reasoning_details entries were removed because they were missing signatures. See https://github.com/OpenRouterTeam/ai-sdk-provider/issues/423 for more details."
2808
+ );
2809
+ }
2788
2810
  const uniqueDetails = [];
2789
- for (const detail of candidateReasoningDetails) {
2811
+ for (const detail of validDetails) {
2790
2812
  if (reasoningDetailsTracker.upsert(detail)) {
2791
2813
  uniqueDetails.push(detail);
2792
2814
  }
@@ -2835,20 +2857,135 @@ function getToolResultContent(input) {
2835
2857
  return input.output.value;
2836
2858
  case "json":
2837
2859
  case "error-json":
2838
- case "content":
2839
2860
  return JSON.stringify(input.output.value);
2861
+ case "content":
2862
+ return mapToolResultContentParts(input.output.value);
2840
2863
  case "execution-denied":
2841
2864
  return (_a16 = input.output.reason) != null ? _a16 : "Tool execution denied";
2842
2865
  }
2843
2866
  }
2867
+ function mapToolResultContentParts(parts) {
2868
+ return parts.map((part) => {
2869
+ var _a16, _b16, _c;
2870
+ switch (part.type) {
2871
+ case "text":
2872
+ return { type: "text", text: part.text };
2873
+ case "image-data":
2874
+ return {
2875
+ type: "image_url",
2876
+ image_url: {
2877
+ url: buildFileDataUrl({
2878
+ data: part.data,
2879
+ mediaType: part.mediaType,
2880
+ defaultMediaType: "image/jpeg"
2881
+ })
2882
+ }
2883
+ };
2884
+ case "image-url":
2885
+ return {
2886
+ type: "image_url",
2887
+ image_url: { url: part.url }
2888
+ };
2889
+ case "file-data": {
2890
+ const dataUrl = buildFileDataUrl({
2891
+ data: part.data,
2892
+ mediaType: part.mediaType,
2893
+ defaultMediaType: "application/octet-stream"
2894
+ });
2895
+ if ((_a16 = part.mediaType) == null ? void 0 : _a16.startsWith("image/")) {
2896
+ return {
2897
+ type: "image_url",
2898
+ image_url: { url: dataUrl }
2899
+ };
2900
+ }
2901
+ if ((_b16 = part.mediaType) == null ? void 0 : _b16.startsWith("audio/")) {
2902
+ const rawFormat = part.mediaType.replace("audio/", "");
2903
+ const format = MIME_TO_FORMAT[rawFormat];
2904
+ if (format !== void 0) {
2905
+ return {
2906
+ type: "input_audio",
2907
+ input_audio: {
2908
+ data: getBase64FromDataUrl(dataUrl),
2909
+ format
2910
+ }
2911
+ };
2912
+ }
2913
+ }
2914
+ return {
2915
+ type: "file",
2916
+ file: {
2917
+ filename: (_c = part.filename) != null ? _c : "",
2918
+ file_data: dataUrl
2919
+ }
2920
+ };
2921
+ }
2922
+ case "file-url": {
2923
+ if (looksLikeImageUrl(part.url)) {
2924
+ return {
2925
+ type: "image_url",
2926
+ image_url: { url: part.url }
2927
+ };
2928
+ }
2929
+ return {
2930
+ type: "file",
2931
+ file: {
2932
+ filename: filenameFromUrl(part.url),
2933
+ file_data: part.url
2934
+ }
2935
+ };
2936
+ }
2937
+ case "file-id":
2938
+ case "image-file-id":
2939
+ case "custom":
2940
+ return { type: "text", text: JSON.stringify(part) };
2941
+ default: {
2942
+ const _exhaustiveCheck = part;
2943
+ return { type: "text", text: JSON.stringify(_exhaustiveCheck) };
2944
+ }
2945
+ }
2946
+ });
2947
+ }
2948
+ var IMAGE_EXTENSIONS = /* @__PURE__ */ new Set([
2949
+ "jpg",
2950
+ "jpeg",
2951
+ "png",
2952
+ "gif",
2953
+ "webp",
2954
+ "svg",
2955
+ "bmp",
2956
+ "ico",
2957
+ "tif",
2958
+ "tiff",
2959
+ "avif"
2960
+ ]);
2961
+ function looksLikeImageUrl(url) {
2962
+ var _a16;
2963
+ try {
2964
+ const pathname = new URL(url).pathname;
2965
+ const ext = (_a16 = pathname.split(".").pop()) == null ? void 0 : _a16.toLowerCase();
2966
+ return ext !== void 0 && IMAGE_EXTENSIONS.has(ext);
2967
+ } catch (e) {
2968
+ return false;
2969
+ }
2970
+ }
2971
+ function filenameFromUrl(url) {
2972
+ try {
2973
+ const pathname = new URL(url).pathname;
2974
+ const last = pathname.split("/").pop();
2975
+ return (last == null ? void 0 : last.includes(".")) ? last : "";
2976
+ } catch (e) {
2977
+ return "";
2978
+ }
2979
+ }
2844
2980
  function findFirstReasoningDetails(content) {
2845
- var _a16, _b16, _c;
2981
+ var _a16, _b16, _c, _d;
2846
2982
  for (const part of content) {
2847
2983
  if (part.type === "tool-call") {
2848
- const openrouter2 = (_a16 = part.providerOptions) == null ? void 0 : _a16.openrouter;
2849
- const details = openrouter2 == null ? void 0 : openrouter2.reasoning_details;
2850
- if (Array.isArray(details) && details.length > 0) {
2851
- return details;
2984
+ const parsed = OpenRouterProviderOptionsSchema.safeParse(
2985
+ part.providerOptions
2986
+ );
2987
+ if (parsed.success && ((_b16 = (_a16 = parsed.data) == null ? void 0 : _a16.openrouter) == null ? void 0 : _b16.reasoning_details) && parsed.data.openrouter.reasoning_details.length > 0) {
2988
+ return parsed.data.openrouter.reasoning_details;
2852
2989
  }
2853
2990
  }
2854
2991
  }
@@ -2857,7 +2994,7 @@ function findFirstReasoningDetails(content) {
2857
2994
  const parsed = OpenRouterProviderOptionsSchema.safeParse(
2858
2995
  part.providerOptions
2859
2996
  );
2860
- if (parsed.success && ((_c = (_b16 = parsed.data) == null ? void 0 : _b16.openrouter) == null ? void 0 : _c.reasoning_details) && parsed.data.openrouter.reasoning_details.length > 0) {
2997
+ if (parsed.success && ((_d = (_c = parsed.data) == null ? void 0 : _c.openrouter) == null ? void 0 : _d.reasoning_details) && parsed.data.openrouter.reasoning_details.length > 0) {
2861
2998
  return parsed.data.openrouter.reasoning_details;
2862
2999
  }
2863
3000
  }
@@ -4610,7 +4747,7 @@ function withUserAgentSuffix2(headers, ...userAgentSuffixParts) {
4610
4747
  }
4611
4748
 
4612
4749
  // src/version.ts
4613
- var VERSION2 = false ? "0.0.0-test" : "2.3.1";
4750
+ var VERSION2 = false ? "0.0.0-test" : "2.3.3";
4614
4751
 
4615
4752
  // src/provider.ts
4616
4753
  function createOpenRouter(options = {}) {