@ai-sdk/open-responses 2.0.51 → 2.0.54

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.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // src/version.ts
2
- var VERSION = true ? "2.0.51" : "0.0.0-test";
2
+ var VERSION = true ? "2.0.54" : "0.0.0-test";
3
3
 
4
4
  // src/open-responses-provider.ts
5
5
  import {
@@ -19,7 +19,7 @@ function createOpenResponsesExtensionRegistry(extensions) {
19
19
  byProviderToolId: /* @__PURE__ */ new Map(),
20
20
  byToolType: /* @__PURE__ */ new Map()
21
21
  };
22
- for (const extension of extensions != null ? extensions : []) {
22
+ for (const extension of extensions ?? []) {
23
23
  const namespaceSeparatorIndex = extension.id.indexOf(".");
24
24
  if (namespaceSeparatorIndex <= 0) {
25
25
  throw new Error(
@@ -188,6 +188,30 @@ function isOpenResponsesJSONValue(value) {
188
188
  return isOpenResponsesJSONObject(value);
189
189
  }
190
190
 
191
+ // src/open-responses-tools.ts
192
+ import {
193
+ createProviderDefinedToolFactory,
194
+ lazySchema,
195
+ zodSchema
196
+ } from "@ai-sdk/provider-utils";
197
+ import { z } from "zod/v4";
198
+ var customInputSchema = lazySchema(() => zodSchema(z.string()));
199
+ function createOpenResponsesTools({
200
+ customToolId
201
+ }) {
202
+ const customToolFactory = createProviderDefinedToolFactory({
203
+ id: customToolId,
204
+ inputSchema: customInputSchema
205
+ });
206
+ return {
207
+ /**
208
+ * Creates a caller-executed OpenAI-compatible custom tool. Custom tools accept
209
+ * a raw string, optionally constrained by a grammar. Requires endpoint support.
210
+ */
211
+ customTool: (options) => customToolFactory(options)
212
+ };
213
+ }
214
+
191
215
  // src/responses/open-responses-language-model.ts
192
216
  import {
193
217
  APICallError
@@ -208,7 +232,7 @@ import {
208
232
  WORKFLOW_SERIALIZE,
209
233
  WORKFLOW_DESERIALIZE
210
234
  } from "@ai-sdk/provider-utils";
211
- import { z as z3 } from "zod/v4";
235
+ import { z as z4 } from "zod/v4";
212
236
 
213
237
  // src/responses/convert-to-open-responses-input.ts
214
238
  import {
@@ -224,9 +248,9 @@ async function convertToOpenResponsesInput({
224
248
  providerOptionsName = "open-responses",
225
249
  extensionRegistry,
226
250
  providerToolsByName = /* @__PURE__ */ new Map(),
227
- strictResponseInput = false
251
+ strictResponseInput = false,
252
+ customToolId
228
253
  }) {
229
- var _a, _b, _c, _d;
230
254
  const input = [];
231
255
  const warnings = [];
232
256
  const systemMessages = [];
@@ -277,7 +301,7 @@ async function convertToOpenResponsesInput({
277
301
  const fullMediaType = resolveFullMediaType({ part });
278
302
  userContent.push({
279
303
  type: "input_file",
280
- filename: (_a = part.filename) != null ? _a : "data",
304
+ filename: part.filename ?? "data",
281
305
  file_data: `data:${fullMediaType};base64,${convertToBase64(part.data.data)}`
282
306
  });
283
307
  }
@@ -313,14 +337,11 @@ async function convertToOpenResponsesInput({
313
337
  status: "completed",
314
338
  role: "assistant",
315
339
  content: assistantContent.map(
316
- (part) => {
317
- var _a2, _b2;
318
- return part.type === "output_text" ? {
319
- ...part,
320
- annotations: (_a2 = part.annotations) != null ? _a2 : [],
321
- logprobs: (_b2 = part.logprobs) != null ? _b2 : []
322
- } : part;
323
- }
340
+ (part) => part.type === "output_text" ? {
341
+ ...part,
342
+ annotations: part.annotations ?? [],
343
+ logprobs: part.logprobs ?? []
344
+ } : part
324
345
  )
325
346
  });
326
347
  } else {
@@ -354,7 +375,7 @@ async function convertToOpenResponsesInput({
354
375
  }
355
376
  if (part.type === "tool-call" || part.type === "tool-result") {
356
377
  const providerTool = providerToolsByName.get(part.toolName);
357
- const extension = providerTool == null ? void 0 : extensionRegistry == null ? void 0 : extensionRegistry.byProviderToolId.get(providerTool.id);
378
+ const extension = providerTool == null ? void 0 : extensionRegistry?.byProviderToolId.get(providerTool.id);
358
379
  if (providerTool != null && extension != null) {
359
380
  flushAssistantContent();
360
381
  const encoded = await encodeExtensionInputPart({
@@ -377,18 +398,18 @@ async function convertToOpenResponsesInput({
377
398
  case "reasoning": {
378
399
  flushAssistantContent();
379
400
  const providerData = getProviderData(part, providerOptionsName);
380
- const itemId = typeof (providerData == null ? void 0 : providerData.itemId) === "string" ? providerData.itemId : void 0;
401
+ const itemId = typeof providerData?.itemId === "string" ? providerData.itemId : void 0;
381
402
  const summary = parseReasoningSummary(
382
- providerData == null ? void 0 : providerData.reasoningSummary
403
+ providerData?.reasoningSummary
383
404
  );
384
405
  const reasoningContent = parseReasoningContent(
385
- providerData == null ? void 0 : providerData.reasoningContent
406
+ providerData?.reasoningContent
386
407
  );
387
408
  const hasReasoningContent = providerData != null && "reasoningContent" in providerData;
388
- const encryptedContent = typeof (providerData == null ? void 0 : providerData.reasoningEncryptedContent) === "string" ? providerData.reasoningEncryptedContent : void 0;
409
+ const encryptedContent = typeof providerData?.reasoningEncryptedContent === "string" ? providerData.reasoningEncryptedContent : void 0;
389
410
  const reasoningItem = {
390
411
  type: "reasoning",
391
- summary: summary != null ? summary : [],
412
+ summary: summary ?? [],
392
413
  ...itemId != null && { id: itemId },
393
414
  ...reasoningContent != null ? { content: reasoningContent } : !hasReasoningContent && part.text.length > 0 ? {
394
415
  content: [
@@ -403,10 +424,10 @@ async function convertToOpenResponsesInput({
403
424
  }
404
425
  };
405
426
  const previousItem = input[input.length - 1];
406
- if (reasoningItem.id != null && (previousItem == null ? void 0 : previousItem.type) === "reasoning" && previousItem.id === reasoningItem.id) {
427
+ if (reasoningItem.id != null && previousItem?.type === "reasoning" && previousItem.id === reasoningItem.id) {
407
428
  if (reasoningItem.content != null) {
408
429
  previousItem.content = [
409
- ...(_b = previousItem.content) != null ? _b : [],
430
+ ...previousItem.content ?? [],
410
431
  ...reasoningItem.content
411
432
  ];
412
433
  }
@@ -417,9 +438,9 @@ async function convertToOpenResponsesInput({
417
438
  }
418
439
  case "text": {
419
440
  const providerData = getProviderData(part, providerOptionsName);
420
- const itemId = typeof (providerData == null ? void 0 : providerData.itemId) === "string" ? providerData.itemId : void 0;
441
+ const itemId = typeof providerData?.itemId === "string" ? providerData.itemId : void 0;
421
442
  const annotations = parseOutputTextAnnotations(
422
- providerData == null ? void 0 : providerData.annotations
443
+ providerData?.annotations
423
444
  );
424
445
  if (assistantContent.length > 0 && assistantMessageId !== itemId) {
425
446
  flushAssistantContent();
@@ -436,14 +457,25 @@ async function convertToOpenResponsesInput({
436
457
  flushAssistantContent();
437
458
  const argumentsValue = typeof part.input === "string" ? part.input : JSON.stringify(part.input);
438
459
  const providerData = getProviderData(part, providerOptionsName);
439
- const itemId = typeof (providerData == null ? void 0 : providerData.itemId) === "string" ? providerData.itemId : void 0;
440
- input.push({
441
- type: "function_call",
442
- ...itemId != null && { id: itemId },
443
- call_id: part.toolCallId,
444
- name: part.toolName,
445
- arguments: argumentsValue
446
- });
460
+ const itemId = typeof providerData?.itemId === "string" ? providerData.itemId : void 0;
461
+ const providerTool = providerToolsByName.get(part.toolName);
462
+ if (customToolId != null && providerTool?.id === customToolId) {
463
+ input.push({
464
+ type: "custom_tool_call",
465
+ ...itemId != null && { id: itemId },
466
+ call_id: part.toolCallId,
467
+ name: part.toolName,
468
+ input: argumentsValue
469
+ });
470
+ } else {
471
+ input.push({
472
+ type: "function_call",
473
+ ...itemId != null && { id: itemId },
474
+ call_id: part.toolCallId,
475
+ name: part.toolName,
476
+ arguments: argumentsValue
477
+ });
478
+ }
447
479
  break;
448
480
  }
449
481
  }
@@ -471,7 +503,7 @@ async function convertToOpenResponsesInput({
471
503
  continue;
472
504
  }
473
505
  const providerTool = providerToolsByName.get(part.toolName);
474
- const extension = providerTool == null ? void 0 : extensionRegistry == null ? void 0 : extensionRegistry.byProviderToolId.get(providerTool.id);
506
+ const extension = providerTool == null ? void 0 : extensionRegistry?.byProviderToolId.get(providerTool.id);
475
507
  if (providerTool != null && extension != null) {
476
508
  const encoded = await encodeExtensionInputPart({
477
509
  extensionRegistry,
@@ -496,7 +528,7 @@ async function convertToOpenResponsesInput({
496
528
  contentValue = output.value;
497
529
  break;
498
530
  case "execution-denied":
499
- contentValue = (_c = output.reason) != null ? _c : "Tool call execution denied.";
531
+ contentValue = output.reason ?? "Tool call execution denied.";
500
532
  break;
501
533
  case "json":
502
534
  case "error-json":
@@ -528,7 +560,7 @@ async function convertToOpenResponsesInput({
528
560
  } else {
529
561
  contentParts.push({
530
562
  type: "input_file",
531
- filename: (_d = item.filename) != null ? _d : "data",
563
+ filename: item.filename ?? "data",
532
564
  file_data: `data:${fullMediaType};base64,${convertToBase64(item.data.data)}`
533
565
  });
534
566
  }
@@ -567,7 +599,7 @@ async function convertToOpenResponsesInput({
567
599
  }
568
600
  }
569
601
  input.push({
570
- type: "function_call_output",
602
+ type: customToolId != null && providerTool?.id === customToolId ? "custom_tool_call_output" : "function_call_output",
571
603
  call_id: part.toolCallId,
572
604
  output: contentValue
573
605
  });
@@ -588,9 +620,9 @@ async function encodeExtensionInputPart({
588
620
  part,
589
621
  providerTool
590
622
  }) {
591
- const extension = extensionRegistry == null ? void 0 : extensionRegistry.byProviderToolId.get(providerTool.id);
592
- const encodeInputItem = extension == null ? void 0 : extension.encodeInputItem;
593
- const itemTypes = extension == null ? void 0 : extension.itemTypes;
623
+ const extension = extensionRegistry?.byProviderToolId.get(providerTool.id);
624
+ const encodeInputItem = extension?.encodeInputItem;
625
+ const itemTypes = extension?.itemTypes;
594
626
  if (encodeInputItem == null || itemTypes == null) {
595
627
  return void 0;
596
628
  }
@@ -606,7 +638,7 @@ async function encodeExtensionInputPart({
606
638
  return void 0;
607
639
  }
608
640
  return items;
609
- } catch (e) {
641
+ } catch {
610
642
  return void 0;
611
643
  }
612
644
  }
@@ -615,11 +647,10 @@ function getExtensionReplay({
615
647
  providerOptionsName,
616
648
  extensionRegistry
617
649
  }) {
618
- var _a, _b;
619
- const extensionData = (_a = getProviderData(
650
+ const extensionData = getProviderData(
620
651
  part,
621
652
  providerOptionsName
622
- )) == null ? void 0 : _a.openResponsesExtension;
653
+ )?.openResponsesExtension;
623
654
  if (extensionData == null || typeof extensionData !== "object" || Array.isArray(extensionData)) {
624
655
  return void 0;
625
656
  }
@@ -627,25 +658,23 @@ function getExtensionReplay({
627
658
  if (typeof id !== "string") {
628
659
  return void 0;
629
660
  }
630
- const extension = extensionRegistry == null ? void 0 : extensionRegistry.byExtensionId.get(
661
+ const extension = extensionRegistry?.byExtensionId.get(
631
662
  id
632
663
  );
633
664
  if (extension == null) {
634
665
  return void 0;
635
666
  }
636
- if (isOpenResponsesExtensionItem(item) && ((_b = extension.itemTypes) == null ? void 0 : _b.includes(item.type))) {
667
+ if (isOpenResponsesExtensionItem(item) && extension.itemTypes?.includes(item.type)) {
637
668
  return { item };
638
669
  }
639
670
  return typeof itemId === "string" ? {} : void 0;
640
671
  }
641
672
  function getProviderData(part, providerOptionsName) {
642
- var _a, _b, _c;
643
- const providerData = (_c = (_a = part.providerOptions) == null ? void 0 : _a[providerOptionsName]) != null ? _c : (_b = part.providerMetadata) == null ? void 0 : _b[providerOptionsName];
673
+ const providerData = part.providerOptions?.[providerOptionsName] ?? part.providerMetadata?.[providerOptionsName];
644
674
  return providerData != null && typeof providerData === "object" && !Array.isArray(providerData) ? providerData : void 0;
645
675
  }
646
676
  function getImageDetail(part, providerOptionsName) {
647
- var _a;
648
- const imageDetail = (_a = getProviderData(part, providerOptionsName)) == null ? void 0 : _a.imageDetail;
677
+ const imageDetail = getProviderData(part, providerOptionsName)?.imageDetail;
649
678
  return imageDetail === "low" || imageDetail === "high" || imageDetail === "auto" ? imageDetail : "auto";
650
679
  }
651
680
  function parseReasoningSummary(value) {
@@ -686,16 +715,16 @@ function parseOutputTextAnnotations(value) {
686
715
  }
687
716
 
688
717
  // src/responses/open-responses-api.ts
689
- import { lazySchema, zodSchema } from "@ai-sdk/provider-utils";
690
- import { z } from "zod/v4";
691
- var openResponsesErrorSchema = lazySchema(
692
- () => zodSchema(
693
- z.object({
694
- error: z.object({
695
- message: z.string(),
696
- type: z.string(),
697
- param: z.string(),
698
- code: z.string()
718
+ import { lazySchema as lazySchema2, zodSchema as zodSchema2 } from "@ai-sdk/provider-utils";
719
+ import { z as z2 } from "zod/v4";
720
+ var openResponsesErrorSchema = lazySchema2(
721
+ () => zodSchema2(
722
+ z2.object({
723
+ error: z2.object({
724
+ message: z2.string(),
725
+ type: z2.string().nullish(),
726
+ param: z2.string().nullish(),
727
+ code: z2.string().nullish()
699
728
  })
700
729
  })
701
730
  )
@@ -721,38 +750,41 @@ function mapOpenResponsesFinishReason({
721
750
 
722
751
  // src/responses/open-responses-language-model-options.ts
723
752
  import {
724
- lazySchema as lazySchema2,
725
- zodSchema as zodSchema2
753
+ lazySchema as lazySchema3,
754
+ zodSchema as zodSchema3
726
755
  } from "@ai-sdk/provider-utils";
727
- import { z as z2 } from "zod/v4";
728
- var openResponsesLanguageModelOptions = lazySchema2(
729
- () => zodSchema2(
730
- z2.object({
756
+ import { z as z3 } from "zod/v4";
757
+ var openResponsesLanguageModelOptions = lazySchema3(
758
+ () => zodSchema3(
759
+ z3.object({
731
760
  /**
732
761
  * Provider-native reasoning effort. The value is passed through to the
733
762
  * endpoint and takes precedence over the top-level `reasoning` setting.
734
763
  */
735
- reasoningEffort: z2.string().nullish(),
764
+ reasoningEffort: z3.string().nullish(),
736
765
  /**
737
766
  * Controls reasoning summary output from the model.
738
767
  * Valid values: 'concise', 'detailed', 'auto'.
739
768
  */
740
- reasoningSummary: z2.enum(["concise", "detailed", "auto"]).nullish()
769
+ reasoningSummary: z3.enum(["concise", "detailed", "auto"]).nullish()
741
770
  })
742
771
  )
743
772
  );
744
773
 
745
774
  // src/responses/open-responses-language-model.ts
775
+ var defaultFailedResponseHandler = createJsonErrorResponseHandler({
776
+ errorSchema: openResponsesErrorSchema,
777
+ errorToMessage: (error) => error.error.message
778
+ });
746
779
  var OpenResponsesLanguageModel = class _OpenResponsesLanguageModel {
747
780
  constructor(modelId, config) {
748
781
  this.specificationVersion = "v4";
749
782
  this.supportedUrls = {
750
783
  "image/*": [/^https?:\/\/.*$/]
751
784
  };
752
- var _a;
753
785
  this.modelId = modelId;
754
786
  this.config = config;
755
- this.extensionRegistry = (_a = config.extensionRegistry) != null ? _a : createOpenResponsesExtensionRegistry();
787
+ this.extensionRegistry = config.extensionRegistry ?? createOpenResponsesExtensionRegistry();
756
788
  }
757
789
  static [WORKFLOW_SERIALIZE](model) {
758
790
  if (model.extensionRegistry.byExtensionId.size > 0) {
@@ -787,7 +819,6 @@ var OpenResponsesLanguageModel = class _OpenResponsesLanguageModel {
787
819
  toolChoice,
788
820
  responseFormat
789
821
  }) {
790
- var _a, _b;
791
822
  const warnings = [];
792
823
  if (stopSequences != null) {
793
824
  warnings.push({ type: "unsupported", feature: "stopSequences" });
@@ -799,7 +830,7 @@ var OpenResponsesLanguageModel = class _OpenResponsesLanguageModel {
799
830
  warnings.push({ type: "unsupported", feature: "seed" });
800
831
  }
801
832
  const providerToolsByName = new Map(
802
- (tools != null ? tools : []).filter((tool) => tool.type === "provider").map((tool) => [tool.name, tool])
833
+ (tools ?? []).filter((tool) => tool.type === "provider").map((tool) => [tool.name, tool])
803
834
  );
804
835
  const {
805
836
  input,
@@ -810,13 +841,28 @@ var OpenResponsesLanguageModel = class _OpenResponsesLanguageModel {
810
841
  providerOptionsName: this.config.providerOptionsName,
811
842
  extensionRegistry: this.extensionRegistry,
812
843
  providerToolsByName,
813
- strictResponseInput: this.config.strictResponseInput
844
+ strictResponseInput: this.config.strictResponseInput,
845
+ customToolId: this.config.customToolId
814
846
  });
815
847
  warnings.push(...inputWarnings);
816
848
  const convertedTools = [];
817
849
  const encodedProviderToolsByName = /* @__PURE__ */ new Map();
818
- for (const tool of tools != null ? tools : []) {
850
+ for (const tool of tools ?? []) {
819
851
  if (tool.type === "provider") {
852
+ if (this.config.customToolId != null && tool.id === this.config.customToolId) {
853
+ const format = tool.args.format != null && typeof tool.args.format === "object" && !Array.isArray(tool.args.format) ? tool.args.format : void 0;
854
+ convertedTools.push({
855
+ type: "custom",
856
+ name: tool.name,
857
+ description: typeof tool.args.description === "string" ? tool.args.description : void 0,
858
+ format: format != null && "type" in format && format.type === "grammar" && "syntax" in format && (format.syntax === "regex" || format.syntax === "lark") && "definition" in format && typeof format.definition === "string" ? {
859
+ type: "grammar",
860
+ syntax: format.syntax,
861
+ definition: format.definition
862
+ } : format != null && "type" in format && format.type === "text" ? { type: "text" } : void 0
863
+ });
864
+ continue;
865
+ }
820
866
  const extension = this.extensionRegistry.byProviderToolId.get(tool.id);
821
867
  let encoded;
822
868
  if (extension != null) {
@@ -831,7 +877,7 @@ var OpenResponsesLanguageModel = class _OpenResponsesLanguageModel {
831
877
  type: extension.toolType
832
878
  };
833
879
  }
834
- } catch (e) {
880
+ } catch {
835
881
  }
836
882
  }
837
883
  if (encoded == null) {
@@ -858,12 +904,17 @@ var OpenResponsesLanguageModel = class _OpenResponsesLanguageModel {
858
904
  }
859
905
  }
860
906
  let convertedToolChoice;
861
- if ((toolChoice == null ? void 0 : toolChoice.type) === "tool") {
907
+ if (toolChoice?.type === "tool") {
862
908
  const registeredTool = encodedProviderToolsByName.get(
863
909
  toolChoice.toolName
864
910
  );
865
911
  if (registeredTool == null) {
866
- if (!providerToolsByName.has(toolChoice.toolName)) {
912
+ if (this.config.customToolId != null && providerToolsByName.get(toolChoice.toolName)?.id === this.config.customToolId) {
913
+ convertedToolChoice = {
914
+ type: "custom",
915
+ name: toolChoice.toolName
916
+ };
917
+ } else if (!providerToolsByName.has(toolChoice.toolName)) {
867
918
  convertedToolChoice = {
868
919
  type: "function",
869
920
  name: toolChoice.toolName
@@ -873,11 +924,11 @@ var OpenResponsesLanguageModel = class _OpenResponsesLanguageModel {
873
924
  const { encodeToolChoice, tool, toolType } = registeredTool;
874
925
  let fields = {};
875
926
  try {
876
- fields = await (encodeToolChoice == null ? void 0 : encodeToolChoice({
927
+ fields = await encodeToolChoice?.({
877
928
  name: tool.name,
878
929
  args: tool.args
879
- }));
880
- } catch (e) {
930
+ });
931
+ } catch {
881
932
  fields = void 0;
882
933
  }
883
934
  if (encodeToolChoice != null && !isOpenResponsesJSONObject(fields)) {
@@ -893,21 +944,24 @@ var OpenResponsesLanguageModel = class _OpenResponsesLanguageModel {
893
944
  }
894
945
  }
895
946
  } else {
896
- convertedToolChoice = toolChoice == null ? void 0 : toolChoice.type;
947
+ convertedToolChoice = toolChoice?.type;
897
948
  }
898
- const textFormat = (responseFormat == null ? void 0 : responseFormat.type) === "json" ? responseFormat.schema != null ? {
949
+ const textFormat = responseFormat?.type === "json" && this.config.structuredOutputs !== false ? responseFormat.schema != null ? {
899
950
  type: "json_schema",
900
- name: (_a = responseFormat.name) != null ? _a : "response",
951
+ name: responseFormat.name ?? "response",
901
952
  description: responseFormat.description,
902
953
  schema: responseFormat.schema,
903
954
  strict: true
904
955
  } : { type: "json_object" } : void 0;
956
+ if (responseFormat?.type === "json" && this.config.structuredOutputs === false) {
957
+ warnings.push({ type: "unsupported", feature: "responseFormat" });
958
+ }
905
959
  const openResponsesOptions = await parseProviderOptions({
906
960
  provider: this.config.providerOptionsName,
907
961
  providerOptions,
908
962
  schema: openResponsesLanguageModelOptions
909
963
  });
910
- const resolvedReasoningEffort = (_b = openResponsesOptions == null ? void 0 : openResponsesOptions.reasoningEffort) != null ? _b : isCustomReasoning(reasoning) ? reasoning === "none" ? "none" : mapReasoningToProviderEffort({
964
+ const resolvedReasoningEffort = openResponsesOptions?.reasoningEffort ?? (isCustomReasoning(reasoning) ? reasoning === "none" ? "none" : mapReasoningToProviderEffort({
911
965
  reasoning,
912
966
  effortMap: {
913
967
  minimal: "low",
@@ -917,7 +971,7 @@ var OpenResponsesLanguageModel = class _OpenResponsesLanguageModel {
917
971
  xhigh: "xhigh"
918
972
  },
919
973
  warnings
920
- }) : void 0;
974
+ }) : void 0);
921
975
  return {
922
976
  body: {
923
977
  model: this.modelId,
@@ -928,11 +982,11 @@ var OpenResponsesLanguageModel = class _OpenResponsesLanguageModel {
928
982
  top_p: topP,
929
983
  presence_penalty: presencePenalty,
930
984
  frequency_penalty: frequencyPenalty,
931
- reasoning: resolvedReasoningEffort != null || (openResponsesOptions == null ? void 0 : openResponsesOptions.reasoningSummary) != null ? {
985
+ reasoning: resolvedReasoningEffort != null || openResponsesOptions?.reasoningSummary != null ? {
932
986
  ...resolvedReasoningEffort != null && {
933
987
  effort: resolvedReasoningEffort
934
988
  },
935
- ...(openResponsesOptions == null ? void 0 : openResponsesOptions.reasoningSummary) != null && {
989
+ ...openResponsesOptions?.reasoningSummary != null && {
936
990
  summary: openResponsesOptions.reasoningSummary
937
991
  }
938
992
  } : void 0,
@@ -944,7 +998,6 @@ var OpenResponsesLanguageModel = class _OpenResponsesLanguageModel {
944
998
  };
945
999
  }
946
1000
  async doGenerate(options) {
947
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
948
1001
  const { body, warnings } = await this.getArgs(options);
949
1002
  const {
950
1003
  responseHeaders,
@@ -952,12 +1005,9 @@ var OpenResponsesLanguageModel = class _OpenResponsesLanguageModel {
952
1005
  rawValue: rawResponse
953
1006
  } = await postJsonToApi({
954
1007
  url: this.config.url,
955
- headers: combineHeaders((_b = (_a = this.config).headers) == null ? void 0 : _b.call(_a), options.headers),
1008
+ headers: combineHeaders(this.config.headers?.(), options.headers),
956
1009
  body,
957
- failedResponseHandler: createJsonErrorResponseHandler({
958
- errorSchema: openResponsesErrorSchema,
959
- errorToMessage: (error) => error.error.message
960
- }),
1010
+ failedResponseHandler: this.config.failedResponseHandler ?? defaultFailedResponseHandler,
961
1011
  successfulResponseHandler: createJsonResponseHandler(
962
1012
  // do not validate the response body, only apply types to the response body
963
1013
  jsonSchema(() => {
@@ -968,18 +1018,22 @@ var OpenResponsesLanguageModel = class _OpenResponsesLanguageModel {
968
1018
  fetch: this.config.fetch
969
1019
  });
970
1020
  if (response.error) {
1021
+ const errorMetadata = this.config.getResponseErrorMetadata?.(
1022
+ response.error
1023
+ );
971
1024
  throw new APICallError({
972
1025
  message: response.error.message,
973
1026
  url: this.config.url,
974
1027
  requestBodyValues: body,
975
- statusCode: 400,
1028
+ statusCode: errorMetadata?.statusCode ?? 400,
1029
+ isRetryable: errorMetadata?.isRetryable,
976
1030
  responseHeaders,
977
1031
  responseBody: rawResponse,
978
- isRetryable: false
1032
+ data: response.error
979
1033
  });
980
1034
  }
981
1035
  if (response.output == null) {
982
- const detail = (_d = (_c = response.incomplete_details) == null ? void 0 : _c.reason) != null ? _d : response.status;
1036
+ const detail = response.incomplete_details?.reason ?? response.status;
983
1037
  throw new APICallError({
984
1038
  message: detail ? `Responses API returned no output (${detail})` : "Responses API returned no output",
985
1039
  url: this.config.url,
@@ -996,7 +1050,7 @@ var OpenResponsesLanguageModel = class _OpenResponsesLanguageModel {
996
1050
  switch (part.type) {
997
1051
  // TODO AI SDK 7 adjust reasoning in the specification to better support the reasoning structure from open responses.
998
1052
  case "reasoning": {
999
- if (((_f = (_e = part.content) == null ? void 0 : _e.length) != null ? _f : 0) > 0) {
1053
+ if ((part.content?.length ?? 0) > 0) {
1000
1054
  for (const contentPart of part.content) {
1001
1055
  content.push({
1002
1056
  type: "reasoning",
@@ -1049,6 +1103,19 @@ var OpenResponsesLanguageModel = class _OpenResponsesLanguageModel {
1049
1103
  });
1050
1104
  break;
1051
1105
  }
1106
+ case "custom_tool_call": {
1107
+ hasToolCalls = true;
1108
+ content.push({
1109
+ type: "tool-call",
1110
+ toolCallId: part.call_id,
1111
+ toolName: part.name,
1112
+ input: JSON.stringify(part.input),
1113
+ providerMetadata: {
1114
+ [this.config.providerOptionsName]: { itemId: part.id }
1115
+ }
1116
+ });
1117
+ break;
1118
+ }
1052
1119
  default: {
1053
1120
  if (!isOpenResponsesExtensionItem(part)) {
1054
1121
  break;
@@ -1061,36 +1128,37 @@ var OpenResponsesLanguageModel = class _OpenResponsesLanguageModel {
1061
1128
  });
1062
1129
  if (decoded != null) {
1063
1130
  content.push(...decoded);
1064
- hasToolCalls || (hasToolCalls = decoded.some((part2) => part2.type === "tool-call"));
1131
+ hasToolCalls ||= decoded.some((part2) => part2.type === "tool-call");
1065
1132
  }
1066
1133
  break;
1067
1134
  }
1068
1135
  }
1069
1136
  }
1070
1137
  const usage = response.usage;
1071
- const inputTokens = usage == null ? void 0 : usage.input_tokens;
1072
- const cachedInputTokens = (_g = usage == null ? void 0 : usage.input_tokens_details) == null ? void 0 : _g.cached_tokens;
1073
- const outputTokens = usage == null ? void 0 : usage.output_tokens;
1074
- const reasoningTokens = (_h = usage == null ? void 0 : usage.output_tokens_details) == null ? void 0 : _h.reasoning_tokens;
1138
+ const inputTokens = usage?.input_tokens;
1139
+ const cachedInputTokens = usage?.input_tokens_details?.cached_tokens;
1140
+ const cacheWriteTokens = usage?.input_tokens_details?.cache_write_tokens;
1141
+ const outputTokens = usage?.output_tokens;
1142
+ const reasoningTokens = usage?.output_tokens_details?.reasoning_tokens;
1075
1143
  return {
1076
1144
  content,
1077
1145
  finishReason: {
1078
1146
  unified: mapOpenResponsesFinishReason({
1079
- finishReason: (_i = response.incomplete_details) == null ? void 0 : _i.reason,
1147
+ finishReason: response.incomplete_details?.reason,
1080
1148
  hasToolCalls
1081
1149
  }),
1082
- raw: (_k = (_j = response.incomplete_details) == null ? void 0 : _j.reason) != null ? _k : void 0
1150
+ raw: response.incomplete_details?.reason ?? void 0
1083
1151
  },
1084
1152
  usage: {
1085
1153
  inputTokens: {
1086
1154
  total: inputTokens,
1087
- noCache: (inputTokens != null ? inputTokens : 0) - (cachedInputTokens != null ? cachedInputTokens : 0),
1155
+ noCache: (inputTokens ?? 0) - (cachedInputTokens ?? 0) - (cacheWriteTokens ?? 0),
1088
1156
  cacheRead: cachedInputTokens,
1089
- cacheWrite: void 0
1157
+ cacheWrite: cacheWriteTokens
1090
1158
  },
1091
1159
  outputTokens: {
1092
1160
  total: outputTokens,
1093
- text: (outputTokens != null ? outputTokens : 0) - (reasoningTokens != null ? reasoningTokens : 0),
1161
+ text: (outputTokens ?? 0) - (reasoningTokens ?? 0),
1094
1162
  reasoning: reasoningTokens
1095
1163
  },
1096
1164
  raw: response.usage
@@ -1108,20 +1176,16 @@ var OpenResponsesLanguageModel = class _OpenResponsesLanguageModel {
1108
1176
  };
1109
1177
  }
1110
1178
  async doStream(options) {
1111
- var _a, _b;
1112
1179
  const { body, warnings } = await this.getArgs(options);
1113
1180
  const { responseHeaders, value: response } = await postJsonToApi({
1114
1181
  url: this.config.url,
1115
- headers: combineHeaders((_b = (_a = this.config).headers) == null ? void 0 : _b.call(_a), options.headers),
1182
+ headers: combineHeaders(this.config.headers?.(), options.headers),
1116
1183
  body: {
1117
1184
  ...body,
1118
1185
  stream: true
1119
1186
  },
1120
- failedResponseHandler: createJsonErrorResponseHandler({
1121
- errorSchema: openResponsesErrorSchema,
1122
- errorToMessage: (error) => error.error.message
1123
- }),
1124
- successfulResponseHandler: createEventSourceResponseHandler(z3.any()),
1187
+ failedResponseHandler: this.config.failedResponseHandler ?? defaultFailedResponseHandler,
1188
+ successfulResponseHandler: createEventSourceResponseHandler(z4.any()),
1125
1189
  abortSignal: options.abortSignal,
1126
1190
  fetch: this.config.fetch
1127
1191
  });
@@ -1139,23 +1203,23 @@ var OpenResponsesLanguageModel = class _OpenResponsesLanguageModel {
1139
1203
  }
1140
1204
  };
1141
1205
  const updateUsage = (responseUsage) => {
1142
- var _a2, _b2;
1143
1206
  if (!responseUsage) {
1144
1207
  return;
1145
1208
  }
1146
1209
  const inputTokens = responseUsage.input_tokens;
1147
- const cachedInputTokens = (_a2 = responseUsage.input_tokens_details) == null ? void 0 : _a2.cached_tokens;
1210
+ const cachedInputTokens = responseUsage.input_tokens_details?.cached_tokens;
1211
+ const cacheWriteTokens = responseUsage.input_tokens_details?.cache_write_tokens;
1148
1212
  const outputTokens = responseUsage.output_tokens;
1149
- const reasoningTokens = (_b2 = responseUsage.output_tokens_details) == null ? void 0 : _b2.reasoning_tokens;
1213
+ const reasoningTokens = responseUsage.output_tokens_details?.reasoning_tokens;
1150
1214
  usage.inputTokens = {
1151
1215
  total: inputTokens,
1152
- noCache: (inputTokens != null ? inputTokens : 0) - (cachedInputTokens != null ? cachedInputTokens : 0),
1216
+ noCache: (inputTokens ?? 0) - (cachedInputTokens ?? 0) - (cacheWriteTokens ?? 0),
1153
1217
  cacheRead: cachedInputTokens,
1154
- cacheWrite: void 0
1218
+ cacheWrite: cacheWriteTokens
1155
1219
  };
1156
1220
  usage.outputTokens = {
1157
1221
  total: outputTokens,
1158
- text: (outputTokens != null ? outputTokens : 0) - (reasoningTokens != null ? reasoningTokens : 0),
1222
+ text: (outputTokens ?? 0) - (reasoningTokens ?? 0),
1159
1223
  reasoning: reasoningTokens
1160
1224
  };
1161
1225
  usage.raw = responseUsage;
@@ -1167,9 +1231,11 @@ var OpenResponsesLanguageModel = class _OpenResponsesLanguageModel {
1167
1231
  raw: void 0
1168
1232
  };
1169
1233
  const toolCallsByItemId = /* @__PURE__ */ new Map();
1234
+ const customToolCallsByItemId = /* @__PURE__ */ new Map();
1170
1235
  const providerOptionsName = this.config.providerOptionsName;
1171
1236
  const extensionRegistry = this.extensionRegistry;
1172
1237
  const extensionStreamState = /* @__PURE__ */ new Map();
1238
+ const getResponseErrorMetadata = this.config.getResponseErrorMetadata;
1173
1239
  return {
1174
1240
  stream: response.pipeThrough(
1175
1241
  new TransformStream({
@@ -1177,7 +1243,6 @@ var OpenResponsesLanguageModel = class _OpenResponsesLanguageModel {
1177
1243
  controller.enqueue({ type: "stream-start", warnings });
1178
1244
  },
1179
1245
  async transform(parseResult, controller) {
1180
- var _a2, _b2, _c, _d, _e, _f, _g, _h;
1181
1246
  if (options.includeRawChunks) {
1182
1247
  controller.enqueue({
1183
1248
  type: "raw",
@@ -1191,15 +1256,15 @@ var OpenResponsesLanguageModel = class _OpenResponsesLanguageModel {
1191
1256
  const chunk = parseResult.value;
1192
1257
  if (isOpenResponsesExtensionEvent(chunk)) {
1193
1258
  const extension = extensionRegistry.byEventType.get(chunk.type);
1194
- if ((extension == null ? void 0 : extension.decodeEvent) != null) {
1259
+ if (extension?.decodeEvent != null) {
1195
1260
  try {
1196
1261
  const decoded = await extension.decodeEvent({
1197
1262
  event: chunk,
1198
1263
  state: extensionStreamState
1199
1264
  });
1200
- for (const part of decoded != null ? decoded : []) {
1265
+ for (const part of decoded ?? []) {
1201
1266
  controller.enqueue(part);
1202
- hasToolCalls || (hasToolCalls = part.type === "tool-call" || part.type === "tool-input-start");
1267
+ hasToolCalls ||= part.type === "tool-call" || part.type === "tool-input-start";
1203
1268
  }
1204
1269
  } catch (error) {
1205
1270
  controller.enqueue({ type: "error", error });
@@ -1222,7 +1287,7 @@ var OpenResponsesLanguageModel = class _OpenResponsesLanguageModel {
1222
1287
  });
1223
1288
  return;
1224
1289
  }
1225
- toolCall.arguments = ((_a2 = toolCall.arguments) != null ? _a2 : "") + functionCallChunk.delta;
1290
+ toolCall.arguments = (toolCall.arguments ?? "") + functionCallChunk.delta;
1226
1291
  } else if (chunk.type === "response.function_call_arguments.done") {
1227
1292
  const functionCallChunk = chunk;
1228
1293
  const toolCall = toolCallsByItemId.get(functionCallChunk.item_id);
@@ -1235,9 +1300,9 @@ var OpenResponsesLanguageModel = class _OpenResponsesLanguageModel {
1235
1300
  toolCall.arguments = functionCallChunk.arguments;
1236
1301
  } else if (chunk.type === "response.output_item.done" && chunk.item.type === "function_call") {
1237
1302
  const toolCall = toolCallsByItemId.get(chunk.item.id);
1238
- const toolName = (_b2 = toolCall == null ? void 0 : toolCall.toolName) != null ? _b2 : chunk.item.name;
1239
- const toolCallId = (_c = toolCall == null ? void 0 : toolCall.toolCallId) != null ? _c : chunk.item.call_id;
1240
- const input = (_e = (_d = toolCall == null ? void 0 : toolCall.arguments) != null ? _d : chunk.item.arguments) != null ? _e : "";
1303
+ const toolName = toolCall?.toolName ?? chunk.item.name;
1304
+ const toolCallId = toolCall?.toolCallId ?? chunk.item.call_id;
1305
+ const input = chunk.item.arguments !== "" ? chunk.item.arguments : toolCall?.arguments ?? "";
1241
1306
  controller.enqueue({
1242
1307
  type: "tool-call",
1243
1308
  toolCallId,
@@ -1251,6 +1316,56 @@ var OpenResponsesLanguageModel = class _OpenResponsesLanguageModel {
1251
1316
  });
1252
1317
  hasToolCalls = true;
1253
1318
  toolCallsByItemId.delete(chunk.item.id);
1319
+ } else if (chunk.type === "response.output_item.added" && chunk.item.type === "custom_tool_call") {
1320
+ customToolCallsByItemId.set(chunk.item.id, {
1321
+ toolName: chunk.item.name,
1322
+ toolCallId: chunk.item.call_id,
1323
+ input: chunk.item.input
1324
+ });
1325
+ controller.enqueue({
1326
+ type: "tool-input-start",
1327
+ id: chunk.item.call_id,
1328
+ toolName: chunk.item.name
1329
+ });
1330
+ } else if (chunk.type === "response.custom_tool_call_input.delta") {
1331
+ const toolCall = customToolCallsByItemId.get(chunk.item_id);
1332
+ if (toolCall == null) {
1333
+ customToolCallsByItemId.set(chunk.item_id, {
1334
+ input: chunk.delta
1335
+ });
1336
+ } else {
1337
+ toolCall.input = (toolCall.input ?? "") + chunk.delta;
1338
+ }
1339
+ controller.enqueue({
1340
+ type: "tool-input-delta",
1341
+ id: customToolCallsByItemId.get(chunk.item_id)?.toolCallId ?? chunk.item_id,
1342
+ delta: chunk.delta
1343
+ });
1344
+ } else if (chunk.type === "response.custom_tool_call_input.done") {
1345
+ const toolCall = customToolCallsByItemId.get(chunk.item_id);
1346
+ if (toolCall == null) {
1347
+ customToolCallsByItemId.set(chunk.item_id, {
1348
+ input: chunk.input
1349
+ });
1350
+ } else {
1351
+ toolCall.input = chunk.input;
1352
+ }
1353
+ } else if (chunk.type === "response.output_item.done" && chunk.item.type === "custom_tool_call") {
1354
+ const toolCall = customToolCallsByItemId.get(chunk.item.id);
1355
+ const toolCallId = toolCall?.toolCallId ?? chunk.item.call_id;
1356
+ const input = chunk.item.input !== "" ? chunk.item.input : toolCall?.input ?? "";
1357
+ controller.enqueue({ type: "tool-input-end", id: toolCallId });
1358
+ controller.enqueue({
1359
+ type: "tool-call",
1360
+ toolCallId,
1361
+ toolName: toolCall?.toolName ?? chunk.item.name,
1362
+ input: JSON.stringify(input),
1363
+ providerMetadata: {
1364
+ [providerOptionsName]: { itemId: chunk.item.id }
1365
+ }
1366
+ });
1367
+ hasToolCalls = true;
1368
+ customToolCallsByItemId.delete(chunk.item.id);
1254
1369
  } else if (chunk.type === "response.output_item.done" && isOpenResponsesExtensionItem(chunk.item)) {
1255
1370
  try {
1256
1371
  const decoded = await decodeExtensionItem({
@@ -1259,9 +1374,9 @@ var OpenResponsesLanguageModel = class _OpenResponsesLanguageModel {
1259
1374
  mode: "stream",
1260
1375
  providerOptionsName
1261
1376
  });
1262
- for (const part of decoded != null ? decoded : []) {
1377
+ for (const part of decoded ?? []) {
1263
1378
  controller.enqueue(part);
1264
- hasToolCalls || (hasToolCalls = part.type === "tool-call");
1379
+ hasToolCalls ||= part.type === "tool-call";
1265
1380
  }
1266
1381
  } catch (error) {
1267
1382
  controller.enqueue({ type: "error", error });
@@ -1314,19 +1429,19 @@ var OpenResponsesLanguageModel = class _OpenResponsesLanguageModel {
1314
1429
  }
1315
1430
  });
1316
1431
  } else if (chunk.type === "response.completed" || chunk.type === "response.incomplete") {
1317
- const reason = (_f = chunk.response.incomplete_details) == null ? void 0 : _f.reason;
1432
+ const reason = chunk.response.incomplete_details?.reason;
1318
1433
  finishReason = {
1319
1434
  unified: mapOpenResponsesFinishReason({
1320
1435
  finishReason: reason,
1321
1436
  hasToolCalls
1322
1437
  }),
1323
- raw: reason != null ? reason : void 0
1438
+ raw: reason ?? void 0
1324
1439
  };
1325
1440
  updateUsage(chunk.response.usage);
1326
1441
  } else if (chunk.type === "response.failed") {
1327
1442
  finishReason = {
1328
1443
  unified: "error",
1329
- raw: (_h = (_g = chunk.response.error) == null ? void 0 : _g.code) != null ? _h : chunk.response.status
1444
+ raw: chunk.response.error?.code ?? chunk.response.status
1330
1445
  };
1331
1446
  updateUsage(chunk.response.usage);
1332
1447
  if (chunk.response.error != null) {
@@ -1335,7 +1450,8 @@ var OpenResponsesLanguageModel = class _OpenResponsesLanguageModel {
1335
1450
  error: createOpenResponsesStreamError({
1336
1451
  type: chunk.type,
1337
1452
  error: chunk.response.error,
1338
- data: chunk
1453
+ data: chunk,
1454
+ getResponseErrorMetadata
1339
1455
  })
1340
1456
  });
1341
1457
  }
@@ -1349,7 +1465,8 @@ var OpenResponsesLanguageModel = class _OpenResponsesLanguageModel {
1349
1465
  error: createOpenResponsesStreamError({
1350
1466
  type: chunk.type,
1351
1467
  error: chunk.error,
1352
- data: chunk
1468
+ data: chunk,
1469
+ getResponseErrorMetadata
1353
1470
  })
1354
1471
  });
1355
1472
  }
@@ -1378,12 +1495,14 @@ var OpenResponsesLanguageModel = class _OpenResponsesLanguageModel {
1378
1495
  function createOpenResponsesStreamError({
1379
1496
  type,
1380
1497
  error,
1381
- data
1498
+ data,
1499
+ getResponseErrorMetadata
1382
1500
  }) {
1383
1501
  return createProviderStreamError({
1384
1502
  message: error.message,
1385
1503
  type,
1386
1504
  code: error.code,
1505
+ ...getResponseErrorMetadata?.(error),
1387
1506
  data
1388
1507
  });
1389
1508
  }
@@ -1463,8 +1582,7 @@ function addExtensionItemReferenceMetadata({
1463
1582
  part,
1464
1583
  providerOptionsName
1465
1584
  }) {
1466
- var _a;
1467
- const providerMetadata = (_a = part.providerMetadata) != null ? _a : {};
1585
+ const providerMetadata = part.providerMetadata ?? {};
1468
1586
  return {
1469
1587
  ...part,
1470
1588
  providerMetadata: {
@@ -1497,6 +1615,7 @@ function getOutputTextAnnotations(value) {
1497
1615
  // src/open-responses-provider.ts
1498
1616
  function createOpenResponses(options) {
1499
1617
  const providerName = options.name;
1618
+ const customToolId = options.customToolId ?? "open-responses.custom";
1500
1619
  const extensionRegistry = createOpenResponsesExtensionRegistry(
1501
1620
  options.experimental_extensions
1502
1621
  );
@@ -1505,9 +1624,9 @@ function createOpenResponses(options) {
1505
1624
  ...options.apiKey ? {
1506
1625
  Authorization: `Bearer ${options.apiKey}`
1507
1626
  } : {},
1508
- ...options.headers
1627
+ ...typeof options.headers === "function" ? options.headers() : options.headers
1509
1628
  },
1510
- `ai-sdk/open-responses/${VERSION}`
1629
+ options.userAgentSuffix ?? `ai-sdk/open-responses/${VERSION}`
1511
1630
  );
1512
1631
  const createResponsesModel = (modelId) => {
1513
1632
  return new OpenResponsesLanguageModel(modelId, {
@@ -1516,9 +1635,13 @@ function createOpenResponses(options) {
1516
1635
  headers: getHeaders,
1517
1636
  url: options.url,
1518
1637
  fetch: options.fetch,
1638
+ failedResponseHandler: options.failedResponseHandler,
1639
+ getResponseErrorMetadata: options.getResponseErrorMetadata,
1519
1640
  generateId: () => generateId(),
1520
1641
  extensionRegistry,
1521
- strictResponseInput: options.strictResponseInput
1642
+ strictResponseInput: options.strictResponseInput,
1643
+ customToolId,
1644
+ structuredOutputs: options.structuredOutputs
1522
1645
  });
1523
1646
  };
1524
1647
  const createLanguageModel = (modelId) => {
@@ -1534,6 +1657,7 @@ function createOpenResponses(options) {
1534
1657
  };
1535
1658
  provider.specificationVersion = "v4";
1536
1659
  provider.languageModel = createLanguageModel;
1660
+ provider.tools = createOpenResponsesTools({ customToolId });
1537
1661
  provider.embeddingModel = (modelId) => {
1538
1662
  throw new NoSuchModelError({ modelId, modelType: "embeddingModel" });
1539
1663
  };