@ai-sdk/open-responses 2.0.34 → 2.0.36

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.34" : "0.0.0-test";
2
+ var VERSION = true ? "2.0.36" : "0.0.0-test";
3
3
 
4
4
  // src/open-responses-provider.ts
5
5
  import {
@@ -10,6 +10,184 @@ import {
10
10
  withUserAgentSuffix
11
11
  } from "@ai-sdk/provider-utils";
12
12
 
13
+ // src/open-responses-extension.ts
14
+ function createOpenResponsesExtensionRegistry(extensions) {
15
+ const registry = {
16
+ byEventType: /* @__PURE__ */ new Map(),
17
+ byExtensionId: /* @__PURE__ */ new Map(),
18
+ byItemType: /* @__PURE__ */ new Map(),
19
+ byProviderToolId: /* @__PURE__ */ new Map(),
20
+ byToolType: /* @__PURE__ */ new Map()
21
+ };
22
+ for (const extension of extensions != null ? extensions : []) {
23
+ const namespaceSeparatorIndex = extension.id.indexOf(".");
24
+ if (namespaceSeparatorIndex <= 0) {
25
+ throw new Error(
26
+ `Open Responses extension ID ${extension.id} must use <implementor>.<extension> format.`
27
+ );
28
+ }
29
+ const namespace = extension.id.slice(0, namespaceSeparatorIndex);
30
+ registerUnique({
31
+ map: registry.byExtensionId,
32
+ key: extension.id,
33
+ extension,
34
+ field: "id"
35
+ });
36
+ const hasToolType = extension.toolType != null;
37
+ const hasToolEncoder = extension.encodeTool != null;
38
+ if (hasToolType !== hasToolEncoder) {
39
+ throw new Error(
40
+ `Open Responses extension ${extension.id} must provide toolType and encodeTool together.`
41
+ );
42
+ }
43
+ if (extension.encodeToolChoice != null && !hasToolEncoder) {
44
+ throw new Error(
45
+ `Open Responses extension ${extension.id} cannot provide encodeToolChoice without toolType and encodeTool.`
46
+ );
47
+ }
48
+ if (hasToolType && hasToolEncoder) {
49
+ const toolExtension = extension;
50
+ assertNamespacedType({
51
+ extensionId: extension.id,
52
+ namespace,
53
+ type: toolExtension.toolType,
54
+ field: "toolType"
55
+ });
56
+ registerUnique({
57
+ map: registry.byProviderToolId,
58
+ key: extension.id,
59
+ extension: toolExtension,
60
+ field: "provider-tool id"
61
+ });
62
+ registerUnique({
63
+ map: registry.byToolType,
64
+ key: toolExtension.toolType,
65
+ extension: toolExtension,
66
+ field: "toolType"
67
+ });
68
+ }
69
+ const hasItemTypes = extension.itemTypes != null;
70
+ const hasItemDecoder = extension.decodeItem != null;
71
+ if (hasItemTypes !== hasItemDecoder) {
72
+ throw new Error(
73
+ `Open Responses extension ${extension.id} must provide itemTypes and decodeItem together.`
74
+ );
75
+ }
76
+ if (extension.encodeInputItem != null && !hasItemDecoder) {
77
+ throw new Error(
78
+ `Open Responses extension ${extension.id} cannot provide encodeInputItem without itemTypes and decodeItem.`
79
+ );
80
+ }
81
+ if (hasItemTypes && hasItemDecoder) {
82
+ const itemExtension = extension;
83
+ if (itemExtension.itemTypes.length === 0) {
84
+ throw new Error(
85
+ `Open Responses extension ${extension.id} must register at least one item type.`
86
+ );
87
+ }
88
+ for (const itemType of itemExtension.itemTypes) {
89
+ assertNamespacedType({
90
+ extensionId: extension.id,
91
+ namespace,
92
+ type: itemType,
93
+ field: "itemTypes"
94
+ });
95
+ registerUnique({
96
+ map: registry.byItemType,
97
+ key: itemType,
98
+ extension: itemExtension,
99
+ field: "item type"
100
+ });
101
+ }
102
+ }
103
+ const hasEventTypes = extension.eventTypes != null;
104
+ const hasEventDecoder = extension.decodeEvent != null;
105
+ if (hasEventTypes !== hasEventDecoder) {
106
+ throw new Error(
107
+ `Open Responses extension ${extension.id} must provide eventTypes and decodeEvent together.`
108
+ );
109
+ }
110
+ if (hasEventTypes && hasEventDecoder) {
111
+ const eventExtension = extension;
112
+ if (eventExtension.eventTypes.length === 0) {
113
+ throw new Error(
114
+ `Open Responses extension ${extension.id} must register at least one event type.`
115
+ );
116
+ }
117
+ for (const eventType of eventExtension.eventTypes) {
118
+ assertNamespacedType({
119
+ extensionId: extension.id,
120
+ namespace,
121
+ type: eventType,
122
+ field: "eventTypes"
123
+ });
124
+ registerUnique({
125
+ map: registry.byEventType,
126
+ key: eventType,
127
+ extension: eventExtension,
128
+ field: "event type"
129
+ });
130
+ }
131
+ }
132
+ if (!hasToolEncoder && !hasItemDecoder && !hasEventDecoder) {
133
+ throw new Error(
134
+ `Open Responses extension ${extension.id} must register a tool, item, or event capability.`
135
+ );
136
+ }
137
+ }
138
+ return registry;
139
+ }
140
+ function assertNamespacedType({
141
+ extensionId,
142
+ namespace,
143
+ type,
144
+ field
145
+ }) {
146
+ if (!type.includes(":") || type.slice(0, type.indexOf(":")) !== namespace) {
147
+ throw new Error(
148
+ `Open Responses extension ${extensionId} has invalid ${field} value ${type}. Extension wire types must use the ${namespace}: namespace.`
149
+ );
150
+ }
151
+ }
152
+ function registerUnique({
153
+ map,
154
+ key,
155
+ extension,
156
+ field
157
+ }) {
158
+ const existing = map.get(key);
159
+ if (existing != null) {
160
+ throw new Error(
161
+ `Open Responses extension ${extension.id} cannot register ${field} ${String(key)} because it is already registered by ${existing.id}.`
162
+ );
163
+ }
164
+ map.set(key, extension);
165
+ }
166
+ function isOpenResponsesNamespacedType(value) {
167
+ return typeof value === "string" && value.includes(":");
168
+ }
169
+ function isOpenResponsesExtensionRecord(value) {
170
+ return isOpenResponsesJSONObject(value) && isOpenResponsesNamespacedType(value.type);
171
+ }
172
+ function isOpenResponsesJSONObject(value) {
173
+ return value != null && typeof value === "object" && !Array.isArray(value) && Object.getPrototypeOf(value) === Object.prototype && Object.values(value).every(isOpenResponsesJSONValue);
174
+ }
175
+ function isOpenResponsesExtensionItem(value) {
176
+ return isOpenResponsesExtensionRecord(value) && typeof value.id === "string" && typeof value.status === "string";
177
+ }
178
+ function isOpenResponsesExtensionEvent(value) {
179
+ return isOpenResponsesExtensionRecord(value) && typeof value.sequence_number === "number";
180
+ }
181
+ function isOpenResponsesJSONValue(value) {
182
+ if (value == null || typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
183
+ return true;
184
+ }
185
+ if (Array.isArray(value)) {
186
+ return value.every(isOpenResponsesJSONValue);
187
+ }
188
+ return isOpenResponsesJSONObject(value);
189
+ }
190
+
13
191
  // src/responses/open-responses-language-model.ts
14
192
  import {
15
193
  APICallError
@@ -25,6 +203,7 @@ import {
25
203
  mapReasoningToProviderEffort,
26
204
  parseProviderOptions,
27
205
  postJsonToApi,
206
+ SerializationError,
28
207
  serializeModelOptions,
29
208
  WORKFLOW_SERIALIZE,
30
209
  WORKFLOW_DESERIALIZE
@@ -42,12 +221,15 @@ import {
42
221
  } from "@ai-sdk/provider-utils";
43
222
  async function convertToOpenResponsesInput({
44
223
  prompt,
45
- providerOptionsName = "open-responses"
224
+ providerOptionsName = "open-responses",
225
+ extensionRegistry,
226
+ providerToolsByName = /* @__PURE__ */ new Map()
46
227
  }) {
47
228
  var _a, _b, _c, _d;
48
229
  const input = [];
49
230
  const warnings = [];
50
231
  const systemMessages = [];
232
+ const replayedExtensionItems = /* @__PURE__ */ new Set();
51
233
  for (const { role, content } of prompt) {
52
234
  switch (role) {
53
235
  case "system": {
@@ -124,6 +306,44 @@ async function convertToOpenResponsesInput({
124
306
  assistantMessageId = void 0;
125
307
  };
126
308
  for (const part of content) {
309
+ const extensionReplay = getExtensionReplay({
310
+ part,
311
+ providerOptionsName,
312
+ extensionRegistry
313
+ });
314
+ if (extensionReplay != null) {
315
+ flushAssistantContent();
316
+ const replayItem = extensionReplay.item;
317
+ if (replayItem != null) {
318
+ const replayKey = `${replayItem.type}:${replayItem.id}`;
319
+ if (!replayedExtensionItems.has(replayKey)) {
320
+ input.push(replayItem);
321
+ replayedExtensionItems.add(replayKey);
322
+ }
323
+ }
324
+ continue;
325
+ }
326
+ if (part.type === "tool-call" || part.type === "tool-result") {
327
+ const providerTool = providerToolsByName.get(part.toolName);
328
+ const extension = providerTool == null ? void 0 : extensionRegistry == null ? void 0 : extensionRegistry.byProviderToolId.get(providerTool.id);
329
+ if (providerTool != null && extension != null) {
330
+ flushAssistantContent();
331
+ const encoded = await encodeExtensionInputPart({
332
+ extensionRegistry,
333
+ part,
334
+ providerTool
335
+ });
336
+ if (encoded == null) {
337
+ warnings.push({
338
+ type: "unsupported",
339
+ feature: `provider-defined tool ${providerTool.id} ${part.type} history`
340
+ });
341
+ } else {
342
+ input.push(...encoded);
343
+ }
344
+ continue;
345
+ }
346
+ }
127
347
  switch (part.type) {
128
348
  case "reasoning": {
129
349
  flushAssistantContent();
@@ -205,6 +425,40 @@ async function convertToOpenResponsesInput({
205
425
  case "tool": {
206
426
  for (const part of content) {
207
427
  if (part.type === "tool-result") {
428
+ const extensionReplay = getExtensionReplay({
429
+ part,
430
+ providerOptionsName,
431
+ extensionRegistry
432
+ });
433
+ if (extensionReplay != null) {
434
+ const replayItem = extensionReplay.item;
435
+ if (replayItem != null) {
436
+ const replayKey = `${replayItem.type}:${replayItem.id}`;
437
+ if (!replayedExtensionItems.has(replayKey)) {
438
+ input.push(replayItem);
439
+ replayedExtensionItems.add(replayKey);
440
+ }
441
+ }
442
+ continue;
443
+ }
444
+ const providerTool = providerToolsByName.get(part.toolName);
445
+ const extension = providerTool == null ? void 0 : extensionRegistry == null ? void 0 : extensionRegistry.byProviderToolId.get(providerTool.id);
446
+ if (providerTool != null && extension != null) {
447
+ const encoded = await encodeExtensionInputPart({
448
+ extensionRegistry,
449
+ part,
450
+ providerTool
451
+ });
452
+ if (encoded == null) {
453
+ warnings.push({
454
+ type: "unsupported",
455
+ feature: `provider-defined tool ${providerTool.id} tool-result history`
456
+ });
457
+ } else {
458
+ input.push(...encoded);
459
+ }
460
+ continue;
461
+ }
208
462
  const output = part.output;
209
463
  let contentValue;
210
464
  switch (output.type) {
@@ -298,6 +552,61 @@ async function convertToOpenResponsesInput({
298
552
  warnings
299
553
  };
300
554
  }
555
+ async function encodeExtensionInputPart({
556
+ extensionRegistry,
557
+ part,
558
+ providerTool
559
+ }) {
560
+ const extension = extensionRegistry == null ? void 0 : extensionRegistry.byProviderToolId.get(providerTool.id);
561
+ const encodeInputItem = extension == null ? void 0 : extension.encodeInputItem;
562
+ const itemTypes = extension == null ? void 0 : extension.itemTypes;
563
+ if (encodeInputItem == null || itemTypes == null) {
564
+ return void 0;
565
+ }
566
+ try {
567
+ const value = await encodeInputItem({
568
+ part,
569
+ tool: providerTool
570
+ });
571
+ const items = value == null ? void 0 : Array.isArray(value) ? value : [value];
572
+ if (items == null || items.length === 0 || !items.every(
573
+ (item) => isOpenResponsesExtensionItem(item) && itemTypes.includes(item.type)
574
+ )) {
575
+ return void 0;
576
+ }
577
+ return items;
578
+ } catch (e) {
579
+ return void 0;
580
+ }
581
+ }
582
+ function getExtensionReplay({
583
+ part,
584
+ providerOptionsName,
585
+ extensionRegistry
586
+ }) {
587
+ var _a, _b;
588
+ const extensionData = (_a = getProviderData(
589
+ part,
590
+ providerOptionsName
591
+ )) == null ? void 0 : _a.openResponsesExtension;
592
+ if (extensionData == null || typeof extensionData !== "object" || Array.isArray(extensionData)) {
593
+ return void 0;
594
+ }
595
+ const { id, item, itemId } = extensionData;
596
+ if (typeof id !== "string") {
597
+ return void 0;
598
+ }
599
+ const extension = extensionRegistry == null ? void 0 : extensionRegistry.byExtensionId.get(
600
+ id
601
+ );
602
+ if (extension == null) {
603
+ return void 0;
604
+ }
605
+ if (isOpenResponsesExtensionItem(item) && ((_b = extension.itemTypes) == null ? void 0 : _b.includes(item.type))) {
606
+ return { item };
607
+ }
608
+ return typeof itemId === "string" ? {} : void 0;
609
+ }
301
610
  function getProviderData(part, providerOptionsName) {
302
611
  var _a, _b, _c;
303
612
  const providerData = (_c = (_a = part.providerOptions) == null ? void 0 : _a[providerOptionsName]) != null ? _c : (_b = part.providerMetadata) == null ? void 0 : _b[providerOptionsName];
@@ -404,10 +713,17 @@ var OpenResponsesLanguageModel = class _OpenResponsesLanguageModel {
404
713
  this.supportedUrls = {
405
714
  "image/*": [/^https?:\/\/.*$/]
406
715
  };
716
+ var _a;
407
717
  this.modelId = modelId;
408
718
  this.config = config;
719
+ this.extensionRegistry = (_a = config.extensionRegistry) != null ? _a : createOpenResponsesExtensionRegistry();
409
720
  }
410
721
  static [WORKFLOW_SERIALIZE](model) {
722
+ if (model.extensionRegistry.byExtensionId.size > 0) {
723
+ throw new SerializationError({
724
+ message: "Open Responses models with registered extensions cannot be serialized across workflow boundaries. Recreate the provider with its extension codecs inside the workflow step."
725
+ });
726
+ }
411
727
  return serializeModelOptions({
412
728
  modelId: model.modelId,
413
729
  config: model.config
@@ -446,24 +762,56 @@ var OpenResponsesLanguageModel = class _OpenResponsesLanguageModel {
446
762
  if (seed != null) {
447
763
  warnings.push({ type: "unsupported", feature: "seed" });
448
764
  }
765
+ const providerToolsByName = new Map(
766
+ (tools != null ? tools : []).filter((tool) => tool.type === "provider").map((tool) => [tool.name, tool])
767
+ );
449
768
  const {
450
769
  input,
451
770
  instructions,
452
771
  warnings: inputWarnings
453
772
  } = await convertToOpenResponsesInput({
454
773
  prompt,
455
- providerOptionsName: this.config.providerOptionsName
774
+ providerOptionsName: this.config.providerOptionsName,
775
+ extensionRegistry: this.extensionRegistry,
776
+ providerToolsByName
456
777
  });
457
778
  warnings.push(...inputWarnings);
458
- const functionTools = [];
779
+ const convertedTools = [];
780
+ const encodedProviderToolsByName = /* @__PURE__ */ new Map();
459
781
  for (const tool of tools != null ? tools : []) {
460
782
  if (tool.type === "provider") {
461
- warnings.push({
462
- type: "unsupported",
463
- feature: `provider-defined tool ${tool.id}`
464
- });
783
+ const extension = this.extensionRegistry.byProviderToolId.get(tool.id);
784
+ let encoded;
785
+ if (extension != null) {
786
+ try {
787
+ const fields = await extension.encodeTool({
788
+ name: tool.name,
789
+ args: tool.args
790
+ });
791
+ if (isOpenResponsesJSONObject(fields)) {
792
+ encoded = {
793
+ ...fields,
794
+ type: extension.toolType
795
+ };
796
+ }
797
+ } catch (e) {
798
+ }
799
+ }
800
+ if (encoded == null) {
801
+ warnings.push({
802
+ type: "unsupported",
803
+ feature: `provider-defined tool ${tool.id}`
804
+ });
805
+ } else if (extension != null) {
806
+ convertedTools.push(encoded);
807
+ encodedProviderToolsByName.set(tool.name, {
808
+ toolType: extension.toolType,
809
+ encodeToolChoice: extension.encodeToolChoice,
810
+ tool
811
+ });
812
+ }
465
813
  } else {
466
- functionTools.push({
814
+ convertedTools.push({
467
815
  type: "function",
468
816
  name: tool.name,
469
817
  description: tool.description,
@@ -472,7 +820,44 @@ var OpenResponsesLanguageModel = class _OpenResponsesLanguageModel {
472
820
  });
473
821
  }
474
822
  }
475
- const convertedToolChoice = toolChoice == null ? void 0 : toolChoice.type === "tool" ? { type: "function", name: toolChoice.toolName } : toolChoice.type;
823
+ let convertedToolChoice;
824
+ if ((toolChoice == null ? void 0 : toolChoice.type) === "tool") {
825
+ const registeredTool = encodedProviderToolsByName.get(
826
+ toolChoice.toolName
827
+ );
828
+ if (registeredTool == null) {
829
+ if (!providerToolsByName.has(toolChoice.toolName)) {
830
+ convertedToolChoice = {
831
+ type: "function",
832
+ name: toolChoice.toolName
833
+ };
834
+ }
835
+ } else {
836
+ const { encodeToolChoice, tool, toolType } = registeredTool;
837
+ let fields = {};
838
+ try {
839
+ fields = await (encodeToolChoice == null ? void 0 : encodeToolChoice({
840
+ name: tool.name,
841
+ args: tool.args
842
+ }));
843
+ } catch (e) {
844
+ fields = void 0;
845
+ }
846
+ if (encodeToolChoice != null && !isOpenResponsesJSONObject(fields)) {
847
+ warnings.push({
848
+ type: "unsupported",
849
+ feature: `tool choice for provider-defined tool ${tool.id}`
850
+ });
851
+ } else {
852
+ convertedToolChoice = {
853
+ ...isOpenResponsesJSONObject(fields) ? fields : {},
854
+ type: toolType
855
+ };
856
+ }
857
+ }
858
+ } else {
859
+ convertedToolChoice = toolChoice == null ? void 0 : toolChoice.type;
860
+ }
476
861
  const textFormat = (responseFormat == null ? void 0 : responseFormat.type) === "json" ? {
477
862
  type: "json_schema",
478
863
  ...responseFormat.schema != null ? {
@@ -516,7 +901,7 @@ var OpenResponsesLanguageModel = class _OpenResponsesLanguageModel {
516
901
  summary: openResponsesOptions.reasoningSummary
517
902
  }
518
903
  } : void 0,
519
- tools: functionTools.length ? functionTools : void 0,
904
+ tools: convertedTools.length ? convertedTools : void 0,
520
905
  tool_choice: convertedToolChoice,
521
906
  ...textFormat != null && { text: { format: textFormat } }
522
907
  },
@@ -629,6 +1014,22 @@ var OpenResponsesLanguageModel = class _OpenResponsesLanguageModel {
629
1014
  });
630
1015
  break;
631
1016
  }
1017
+ default: {
1018
+ if (!isOpenResponsesExtensionItem(part)) {
1019
+ break;
1020
+ }
1021
+ const decoded = await decodeExtensionItem({
1022
+ extensionRegistry: this.extensionRegistry,
1023
+ item: part,
1024
+ mode: "generate",
1025
+ providerOptionsName: this.config.providerOptionsName
1026
+ });
1027
+ if (decoded != null) {
1028
+ content.push(...decoded);
1029
+ hasToolCalls || (hasToolCalls = decoded.some((part2) => part2.type === "tool-call"));
1030
+ }
1031
+ break;
1032
+ }
632
1033
  }
633
1034
  }
634
1035
  const usage = response.usage;
@@ -732,13 +1133,15 @@ var OpenResponsesLanguageModel = class _OpenResponsesLanguageModel {
732
1133
  };
733
1134
  const toolCallsByItemId = /* @__PURE__ */ new Map();
734
1135
  const providerOptionsName = this.config.providerOptionsName;
1136
+ const extensionRegistry = this.extensionRegistry;
1137
+ const extensionStreamState = /* @__PURE__ */ new Map();
735
1138
  return {
736
1139
  stream: response.pipeThrough(
737
1140
  new TransformStream({
738
1141
  start(controller) {
739
1142
  controller.enqueue({ type: "stream-start", warnings });
740
1143
  },
741
- transform(parseResult, controller) {
1144
+ async transform(parseResult, controller) {
742
1145
  var _a2, _b2, _c, _d, _e, _f, _g, _h;
743
1146
  if (options.includeRawChunks) {
744
1147
  controller.enqueue({
@@ -751,6 +1154,24 @@ var OpenResponsesLanguageModel = class _OpenResponsesLanguageModel {
751
1154
  return;
752
1155
  }
753
1156
  const chunk = parseResult.value;
1157
+ if (isOpenResponsesExtensionEvent(chunk)) {
1158
+ const extension = extensionRegistry.byEventType.get(chunk.type);
1159
+ if ((extension == null ? void 0 : extension.decodeEvent) != null) {
1160
+ try {
1161
+ const decoded = await extension.decodeEvent({
1162
+ event: chunk,
1163
+ state: extensionStreamState
1164
+ });
1165
+ for (const part of decoded != null ? decoded : []) {
1166
+ controller.enqueue(part);
1167
+ hasToolCalls || (hasToolCalls = part.type === "tool-call" || part.type === "tool-input-start");
1168
+ }
1169
+ } catch (error) {
1170
+ controller.enqueue({ type: "error", error });
1171
+ }
1172
+ }
1173
+ return;
1174
+ }
754
1175
  if (chunk.type === "response.output_item.added" && chunk.item.type === "function_call") {
755
1176
  toolCallsByItemId.set(chunk.item.id, {
756
1177
  toolName: chunk.item.name,
@@ -795,6 +1216,21 @@ var OpenResponsesLanguageModel = class _OpenResponsesLanguageModel {
795
1216
  });
796
1217
  hasToolCalls = true;
797
1218
  toolCallsByItemId.delete(chunk.item.id);
1219
+ } else if (chunk.type === "response.output_item.done" && isOpenResponsesExtensionItem(chunk.item)) {
1220
+ try {
1221
+ const decoded = await decodeExtensionItem({
1222
+ extensionRegistry,
1223
+ item: chunk.item,
1224
+ mode: "stream",
1225
+ providerOptionsName
1226
+ });
1227
+ for (const part of decoded != null ? decoded : []) {
1228
+ controller.enqueue(part);
1229
+ hasToolCalls || (hasToolCalls = part.type === "tool-call");
1230
+ }
1231
+ } catch (error) {
1232
+ controller.enqueue({ type: "error", error });
1233
+ }
798
1234
  } else if (chunk.type === "response.output_item.added" && chunk.item.type === "reasoning") {
799
1235
  controller.enqueue({
800
1236
  type: "reasoning-start",
@@ -938,6 +1374,76 @@ function createReasoningProviderMetadata({
938
1374
  }
939
1375
  };
940
1376
  }
1377
+ async function decodeExtensionItem({
1378
+ extensionRegistry,
1379
+ item,
1380
+ mode,
1381
+ providerOptionsName
1382
+ }) {
1383
+ const extension = extensionRegistry.byItemType.get(item.type);
1384
+ if (extension == null) {
1385
+ return void 0;
1386
+ }
1387
+ const decoded = await extension.decodeItem({ item, mode });
1388
+ if (decoded == null) {
1389
+ return void 0;
1390
+ }
1391
+ return [
1392
+ createExtensionReplayCarrier({
1393
+ extension,
1394
+ item,
1395
+ providerOptionsName
1396
+ }),
1397
+ ...decoded.map(
1398
+ (part) => addExtensionItemReferenceMetadata({
1399
+ extension,
1400
+ item,
1401
+ part,
1402
+ providerOptionsName
1403
+ })
1404
+ )
1405
+ ];
1406
+ }
1407
+ function createExtensionReplayCarrier({
1408
+ extension,
1409
+ item,
1410
+ providerOptionsName
1411
+ }) {
1412
+ return {
1413
+ type: "custom",
1414
+ kind: "open-responses.extension-replay",
1415
+ providerMetadata: {
1416
+ [providerOptionsName]: {
1417
+ openResponsesExtension: {
1418
+ id: extension.id,
1419
+ item
1420
+ }
1421
+ }
1422
+ }
1423
+ };
1424
+ }
1425
+ function addExtensionItemReferenceMetadata({
1426
+ extension,
1427
+ item,
1428
+ part,
1429
+ providerOptionsName
1430
+ }) {
1431
+ var _a;
1432
+ const providerMetadata = (_a = part.providerMetadata) != null ? _a : {};
1433
+ return {
1434
+ ...part,
1435
+ providerMetadata: {
1436
+ ...providerMetadata,
1437
+ [providerOptionsName]: {
1438
+ ...providerMetadata[providerOptionsName],
1439
+ openResponsesExtension: {
1440
+ id: extension.id,
1441
+ itemId: item.id
1442
+ }
1443
+ }
1444
+ }
1445
+ };
1446
+ }
941
1447
  function getOutputTextAnnotations(value) {
942
1448
  if (value == null || typeof value !== "object" || !("annotations" in value) || !Array.isArray(value.annotations) || !value.annotations.every(
943
1449
  (annotation) => annotation != null && typeof annotation === "object" && annotation.type === "url_citation" && typeof annotation.start_index === "number" && typeof annotation.end_index === "number" && typeof annotation.url === "string" && typeof annotation.title === "string"
@@ -956,6 +1462,9 @@ function getOutputTextAnnotations(value) {
956
1462
  // src/open-responses-provider.ts
957
1463
  function createOpenResponses(options) {
958
1464
  const providerName = options.name;
1465
+ const extensionRegistry = createOpenResponsesExtensionRegistry(
1466
+ options.experimental_extensions
1467
+ );
959
1468
  const getHeaders = () => withUserAgentSuffix(
960
1469
  {
961
1470
  ...options.apiKey ? {
@@ -972,7 +1481,8 @@ function createOpenResponses(options) {
972
1481
  headers: getHeaders,
973
1482
  url: options.url,
974
1483
  fetch: options.fetch,
975
- generateId: () => generateId()
1484
+ generateId: () => generateId(),
1485
+ extensionRegistry
976
1486
  });
977
1487
  };
978
1488
  const createLanguageModel = (modelId) => {