@absolutejs/ai 0.0.55 → 0.0.57

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.
Files changed (44) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/README.md +42 -0
  3. package/changelog.json +30 -0
  4. package/dist/ai/client/index.js +5 -5
  5. package/dist/ai/client/index.js.map +1 -1
  6. package/dist/ai/index.js +1411 -889
  7. package/dist/ai/index.js.map +15 -12
  8. package/dist/ai/providers/anthropic.js +117 -1
  9. package/dist/ai/providers/anthropic.js.map +7 -6
  10. package/dist/ai/providers/gemini.js +97 -4
  11. package/dist/ai/providers/gemini.js.map +7 -6
  12. package/dist/ai/providers/ollama.js +3 -1
  13. package/dist/ai/providers/ollama.js.map +4 -4
  14. package/dist/ai/providers/openai.js +875 -41
  15. package/dist/ai/providers/openai.js.map +9 -6
  16. package/dist/ai/providers/openaiCompatible.js +882 -48
  17. package/dist/ai/providers/openaiCompatible.js.map +9 -6
  18. package/dist/ai/providers/openaiResponses.js +297 -3
  19. package/dist/ai/providers/openaiResponses.js.map +8 -6
  20. package/dist/ai/providers/openrouter.js +1098 -747
  21. package/dist/ai/providers/openrouter.js.map +10 -8
  22. package/dist/ai/providers/openrouterSDK.js +3 -3
  23. package/dist/ai/providers/openrouterSDK.js.map +1 -1
  24. package/dist/ai/tools/index.js +4 -4
  25. package/dist/ai/tools/index.js.map +2 -2
  26. package/dist/ai/tools/untrusted.js +3 -3
  27. package/dist/ai/tools/untrusted.js.map +2 -2
  28. package/dist/ai/ui/index.js +42 -42
  29. package/dist/ai/ui/index.js.map +2 -2
  30. package/dist/react/ai/index.js +3 -3
  31. package/dist/react/ai/index.js.map +1 -1
  32. package/dist/src/ai/generateAI.d.ts +4 -0
  33. package/dist/src/ai/index.d.ts +4 -0
  34. package/dist/src/ai/inputCapacity.d.ts +25 -0
  35. package/dist/src/ai/prepareTextInput.d.ts +21 -0
  36. package/dist/src/ai/providers/gemini.d.ts +1 -0
  37. package/dist/src/ai/providers/openai.d.ts +1 -0
  38. package/dist/src/ai/providers/openaiCapacity.d.ts +11 -0
  39. package/dist/src/ai/providers/openaiResponses.d.ts +2 -0
  40. package/dist/src/ai/providers/openrouterClient.d.ts +1 -1
  41. package/dist/types/ai.d.ts +5 -0
  42. package/dist/vue/ai/index.js +3 -3
  43. package/dist/vue/ai/index.js.map +1 -1
  44. package/package.json +204 -199
@@ -1,6 +1,286 @@
1
1
  // @bun
2
2
  var __require = import.meta.require;
3
3
 
4
+ // src/ai/inputCapacity.ts
5
+ class AIInputError extends Error {
6
+ code;
7
+ constructor(code, message) {
8
+ super(message);
9
+ this.code = code;
10
+ this.name = "AIInputError";
11
+ }
12
+ }
13
+ var positiveTokenLimit = (value) => {
14
+ if (typeof value !== "number" || !Number.isSafeInteger(value) || value <= 0)
15
+ throw new AIInputError("capacity_unavailable", "The provider did not supply a valid model limit.");
16
+ return value;
17
+ };
18
+ var inputTokenCount = (value) => {
19
+ if (typeof value !== "number" || !Number.isSafeInteger(value) || value < 0)
20
+ throw new AIInputError("capacity_unavailable", "The provider did not supply a valid token count.");
21
+ return value;
22
+ };
23
+ var inspectAIInput = async (provider, params) => {
24
+ params.signal?.throwIfAborted();
25
+ if (!provider.inputCapacity)
26
+ throw new AIInputError("capacity_unavailable", "This provider does not expose model capacity and token counting.");
27
+ const [limits, tokens] = await Promise.all([
28
+ provider.inputCapacity.getLimits(params),
29
+ provider.inputCapacity.countTokens(params)
30
+ ]);
31
+ const inputTokens = inputTokenCount(tokens);
32
+ const outputTokens = positiveTokenLimit(provider.inputCapacity.outputTokens?.(params) ?? params.maxTokens ?? limits.maxOutputTokens);
33
+ const maxInputTokens = positiveTokenLimit(limits.maxInputTokens);
34
+ const maxOutputTokens = positiveTokenLimit(limits.maxOutputTokens);
35
+ const availableInputTokens = Math.max(0, Math.min(maxInputTokens, limits.contextWindowTokens === undefined ? maxInputTokens : positiveTokenLimit(limits.contextWindowTokens) - outputTokens));
36
+ return {
37
+ limits,
38
+ inputTokens,
39
+ outputTokens,
40
+ availableInputTokens,
41
+ fits: outputTokens <= maxOutputTokens && inputTokens <= availableInputTokens
42
+ };
43
+ };
44
+ var cacheModelLimits = (load, ttlMs = 300000) => {
45
+ const cache = new Map;
46
+ return async (params) => {
47
+ const entry = cache.get(params.model);
48
+ if (entry && Date.now() - entry.at < ttlMs)
49
+ return entry.limits;
50
+ const limits = await load(params);
51
+ positiveTokenLimit(limits.maxInputTokens);
52
+ positiveTokenLimit(limits.maxOutputTokens);
53
+ if (cache.size >= 100)
54
+ cache.clear();
55
+ cache.set(params.model, { at: Date.now(), limits });
56
+ return limits;
57
+ };
58
+ };
59
+ var capacityJson = async (response) => {
60
+ if (!response.ok)
61
+ throw new AIInputError("capacity_unavailable", `Model capacity request failed (${response.status}).`);
62
+ const value = await response.json();
63
+ if (!value || typeof value !== "object" || Array.isArray(value))
64
+ throw new AIInputError("capacity_unavailable", "Model capacity response was invalid.");
65
+ return value;
66
+ };
67
+
68
+ // src/ai/providers/openaiCapacity.ts
69
+ var LIMITS = {
70
+ "gpt-4.1": {
71
+ maxInputTokens: 1047576,
72
+ contextWindowTokens: 1047576,
73
+ maxOutputTokens: 32768
74
+ },
75
+ "gpt-4.1-2025-04-14": {
76
+ maxInputTokens: 1047576,
77
+ contextWindowTokens: 1047576,
78
+ maxOutputTokens: 32768
79
+ },
80
+ "gpt-4.1-mini": {
81
+ maxInputTokens: 1047576,
82
+ contextWindowTokens: 1047576,
83
+ maxOutputTokens: 32768
84
+ },
85
+ "gpt-4.1-mini-2025-04-14": {
86
+ maxInputTokens: 1047576,
87
+ contextWindowTokens: 1047576,
88
+ maxOutputTokens: 32768
89
+ },
90
+ "gpt-4.1-nano": {
91
+ maxInputTokens: 1047576,
92
+ contextWindowTokens: 1047576,
93
+ maxOutputTokens: 32768
94
+ },
95
+ "gpt-4.1-nano-2025-04-14": {
96
+ maxInputTokens: 1047576,
97
+ contextWindowTokens: 1047576,
98
+ maxOutputTokens: 32768
99
+ },
100
+ "gpt-4o": {
101
+ maxInputTokens: 128000,
102
+ contextWindowTokens: 128000,
103
+ maxOutputTokens: 16384
104
+ },
105
+ "gpt-4o-mini": {
106
+ maxInputTokens: 128000,
107
+ contextWindowTokens: 128000,
108
+ maxOutputTokens: 16384
109
+ },
110
+ "gpt-4o-mini-2024-07-18": {
111
+ maxInputTokens: 128000,
112
+ contextWindowTokens: 128000,
113
+ maxOutputTokens: 16384
114
+ },
115
+ "gpt-5": {
116
+ maxInputTokens: 272000,
117
+ contextWindowTokens: 400000,
118
+ maxOutputTokens: 128000
119
+ },
120
+ "gpt-5-mini": {
121
+ maxInputTokens: 272000,
122
+ contextWindowTokens: 400000,
123
+ maxOutputTokens: 128000
124
+ },
125
+ "gpt-5-mini-2025-08-07": {
126
+ maxInputTokens: 272000,
127
+ contextWindowTokens: 400000,
128
+ maxOutputTokens: 128000
129
+ },
130
+ "gpt-5-nano": {
131
+ maxInputTokens: 272000,
132
+ contextWindowTokens: 400000,
133
+ maxOutputTokens: 128000
134
+ },
135
+ "gpt-5-nano-2025-08-07": {
136
+ maxInputTokens: 272000,
137
+ contextWindowTokens: 400000,
138
+ maxOutputTokens: 128000
139
+ },
140
+ "gpt-5.4-mini": {
141
+ maxInputTokens: 272000,
142
+ contextWindowTokens: 400000,
143
+ maxOutputTokens: 128000
144
+ },
145
+ "gpt-5.4-nano": {
146
+ maxInputTokens: 272000,
147
+ contextWindowTokens: 400000,
148
+ maxOutputTokens: 128000
149
+ },
150
+ "gpt-5.1": {
151
+ maxInputTokens: 400000,
152
+ contextWindowTokens: 400000,
153
+ maxOutputTokens: 128000
154
+ },
155
+ "gpt-5.1-2025-11-13": {
156
+ maxInputTokens: 400000,
157
+ contextWindowTokens: 400000,
158
+ maxOutputTokens: 128000
159
+ },
160
+ "gpt-5.2": {
161
+ maxInputTokens: 400000,
162
+ contextWindowTokens: 400000,
163
+ maxOutputTokens: 128000
164
+ },
165
+ "gpt-5.2-2025-12-11": {
166
+ maxInputTokens: 400000,
167
+ contextWindowTokens: 400000,
168
+ maxOutputTokens: 128000
169
+ },
170
+ "gpt-5.4": {
171
+ maxInputTokens: 1050000,
172
+ contextWindowTokens: 1050000,
173
+ maxOutputTokens: 128000
174
+ },
175
+ "gpt-5.4-2026-03-05": {
176
+ maxInputTokens: 1050000,
177
+ contextWindowTokens: 1050000,
178
+ maxOutputTokens: 128000
179
+ },
180
+ "gpt-5.5": {
181
+ maxInputTokens: 1050000,
182
+ contextWindowTokens: 1050000,
183
+ maxOutputTokens: 128000
184
+ },
185
+ "gpt-6-astra": {
186
+ maxInputTokens: 922000,
187
+ contextWindowTokens: 1050000,
188
+ maxOutputTokens: 128000
189
+ },
190
+ "gpt-5.6-sol": {
191
+ maxInputTokens: 922000,
192
+ contextWindowTokens: 1050000,
193
+ maxOutputTokens: 128000
194
+ },
195
+ "gpt-5.6-terra": {
196
+ maxInputTokens: 922000,
197
+ contextWindowTokens: 1050000,
198
+ maxOutputTokens: 128000
199
+ },
200
+ "gpt-5.6-luna": {
201
+ maxInputTokens: 922000,
202
+ contextWindowTokens: 1050000,
203
+ maxOutputTokens: 128000
204
+ },
205
+ o3: {
206
+ maxInputTokens: 200000,
207
+ contextWindowTokens: 200000,
208
+ maxOutputTokens: 1e5
209
+ },
210
+ "o3-2025-04-16": {
211
+ maxInputTokens: 200000,
212
+ contextWindowTokens: 200000,
213
+ maxOutputTokens: 1e5
214
+ },
215
+ "o4-mini": {
216
+ maxInputTokens: 200000,
217
+ contextWindowTokens: 200000,
218
+ maxOutputTokens: 1e5
219
+ },
220
+ "o4-mini-2025-04-16": {
221
+ maxInputTokens: 200000,
222
+ contextWindowTokens: 200000,
223
+ maxOutputTokens: 1e5
224
+ },
225
+ "gpt-5-chat-latest": {
226
+ maxInputTokens: 128000,
227
+ contextWindowTokens: 128000,
228
+ maxOutputTokens: 16384
229
+ },
230
+ "gpt-5.1-chat-latest": {
231
+ maxInputTokens: 128000,
232
+ contextWindowTokens: 128000,
233
+ maxOutputTokens: 16384
234
+ },
235
+ "gpt-5.2-chat-latest": {
236
+ maxInputTokens: 128000,
237
+ contextWindowTokens: 128000,
238
+ maxOutputTokens: 16384
239
+ }
240
+ };
241
+ var openaiInputCapacity = (config) => ({
242
+ outputTokens: (params) => {
243
+ const value = config.body(params).max_output_tokens;
244
+ return value === undefined ? undefined : positiveTokenLimit(value);
245
+ },
246
+ getLimits: async (params) => {
247
+ if (config.modelLimits)
248
+ return config.modelLimits(params);
249
+ if (new URL(config.baseUrl).origin !== "https://api.openai.com")
250
+ throw new AIInputError("capacity_unavailable", "This compatible endpoint must expose its own model capacity.");
251
+ const limits = LIMITS[params.model];
252
+ if (!limits)
253
+ throw new AIInputError("capacity_unavailable", `Model limits are unavailable for ${params.model}; no character limit has been substituted.`);
254
+ return { ...limits };
255
+ },
256
+ countTokens: async (params) => {
257
+ const headers = new Headers(await config.headers(params));
258
+ headers.set("Authorization", `Bearer ${await config.key()}`);
259
+ headers.set("Content-Type", "application/json");
260
+ const body = config.body(params);
261
+ const counted = {};
262
+ for (const key of [
263
+ "model",
264
+ "input",
265
+ "instructions",
266
+ "tools",
267
+ "tool_choice",
268
+ "reasoning",
269
+ "text",
270
+ "parallel_tool_calls"
271
+ ])
272
+ if (body[key] !== undefined)
273
+ counted[key] = body[key];
274
+ const response = await config.fetch(`${config.baseUrl}/v1/responses/input_tokens`, {
275
+ method: "POST",
276
+ headers,
277
+ body: JSON.stringify(counted),
278
+ signal: params.signal ? AbortSignal.any([params.signal, AbortSignal.timeout(15000)]) : AbortSignal.timeout(15000)
279
+ });
280
+ return inputTokenCount((await capacityJson(response)).input_tokens);
281
+ }
282
+ });
283
+
4
284
  // src/ai/errors/providerError.ts
5
285
  var PROVIDER_STATUS_PAGES = {
6
286
  anthropic: "https://status.claude.com",
@@ -231,6 +511,7 @@ var withResilience = (provider, providerName = "unknown") => {
231
511
  }
232
512
  };
233
513
  return {
514
+ ...provider,
234
515
  stream: (params) => {
235
516
  const tripped = circuitOpen(providerName);
236
517
  if (tripped) {
@@ -247,6 +528,7 @@ var withResilience = (provider, providerName = "unknown") => {
247
528
  var instrumentAIProvider = (provider, providerName) => {
248
529
  const resilient = withResilience(provider, providerName);
249
530
  return {
531
+ ...provider,
250
532
  stream: (params) => {
251
533
  if (!params.onUsage && !params.onSpan) {
252
534
  return resilient.stream(params);
@@ -388,14 +670,558 @@ var openaiEffortValue = (model, reasoning) => {
388
670
  return clampEffort(requested, allowed);
389
671
  };
390
672
 
391
- // src/ai/providers/openai.ts
673
+ // src/ai/providers/openaiResponses.ts
392
674
  var h2IfHttps = (url) => url.startsWith("https://") ? { protocol: "http2" } : {};
393
675
  var DEFAULT_BASE_URL = "https://api.openai.com";
676
+ var EVENT_PREFIX_LENGTH = 7;
677
+ var DATA_PREFIX_LENGTH = 6;
678
+ var isRecord = (value) => typeof value === "object" && value !== null;
679
+ var isRecordArray = (value) => Array.isArray(value) && value.length > 0 && isRecord(value[0]);
680
+ var mapBlockToResponsesFormat = (block) => {
681
+ if (block.type === "text") {
682
+ return { text: block.content, type: "input_text" };
683
+ }
684
+ if (block.type === "image") {
685
+ return {
686
+ image_url: {
687
+ url: block.source.type === "url" ? block.source.url : `data:${block.source.media_type};base64,${block.source.data}`
688
+ },
689
+ type: "input_image"
690
+ };
691
+ }
692
+ if (block.type === "document") {
693
+ return {
694
+ file: {
695
+ file_data: block.source.type === "url" ? block.source.url : `data:${block.source.media_type};base64,${block.source.data}`,
696
+ filename: block.name ?? "document.pdf"
697
+ },
698
+ type: "input_file"
699
+ };
700
+ }
701
+ if (block.type === "audio") {
702
+ return {
703
+ input_audio: { data: block.source.data, format: block.source.format },
704
+ type: "input_audio"
705
+ };
706
+ }
707
+ if (block.type === "video") {
708
+ return {
709
+ type: "input_video",
710
+ video_url: block.source.type === "url" ? block.source.url : `data:${block.source.media_type};base64,${block.source.data}`
711
+ };
712
+ }
713
+ return null;
714
+ };
715
+ var mapContentToResponsesFormat = (content) => {
716
+ if (typeof content === "string") {
717
+ return content;
718
+ }
719
+ const parts = content.map(mapBlockToResponsesFormat).filter((mapped) => mapped !== null);
720
+ return parts.length > 0 ? parts : "";
721
+ };
722
+ var hasToolBlocks = (content) => content.some((block) => block.type === "tool_use" || block.type === "tool_result");
723
+ var convertToolBlock = (block) => {
724
+ if (block.type === "provider_data" && block.provider === "openrouter") {
725
+ return { ...block.data };
726
+ }
727
+ if (block.type === "tool_use") {
728
+ if (block.providerData)
729
+ return { ...block.providerData };
730
+ return {
731
+ arguments: typeof block.input === "string" ? block.input : JSON.stringify(block.input),
732
+ call_id: block.id,
733
+ name: block.name,
734
+ type: "function_call"
735
+ };
736
+ }
737
+ if (block.type === "tool_result") {
738
+ return {
739
+ call_id: block.tool_use_id,
740
+ output: typeof block.content === "string" ? block.content : "",
741
+ type: "function_call_output"
742
+ };
743
+ }
744
+ return null;
745
+ };
746
+ var convertToolBlocks = (content) => content.map(convertToolBlock).filter((converted) => converted !== null);
747
+ var convertMessage = (msg) => {
748
+ if (typeof msg.content !== "string" && Array.isArray(msg.content) && hasToolBlocks(msg.content)) {
749
+ return convertToolBlocks(msg.content);
750
+ }
751
+ const content = mapContentToResponsesFormat(msg.content);
752
+ return [
753
+ {
754
+ content,
755
+ role: msg.role === "system" ? "developer" : msg.role,
756
+ type: "message"
757
+ }
758
+ ];
759
+ };
760
+ var buildInput = (messages) => {
761
+ const input = [];
762
+ for (const msg of messages) {
763
+ input.push(...convertMessage(msg));
764
+ }
765
+ return input;
766
+ };
767
+ var mapToolDefinition = (tool) => ({
768
+ description: tool.description,
769
+ name: tool.name,
770
+ parameters: tool.input_schema,
771
+ type: "function"
772
+ });
773
+ var buildTools = (tools, isImageModel) => {
774
+ const mapped = tools ? tools.map(mapToolDefinition) : [];
775
+ const result = [...mapped];
776
+ if (isImageModel) {
777
+ result.push({ type: "image_generation" });
778
+ }
779
+ return result.length > 0 ? result : undefined;
780
+ };
781
+ var buildResponsesRequestBody = (params, isImageModel, capabilityModel = params.model) => {
782
+ const body = {
783
+ input: buildInput(params.messages),
784
+ model: params.model,
785
+ stream: true
786
+ };
787
+ if (params.systemPrompt) {
788
+ body.instructions = params.systemPrompt;
789
+ }
790
+ const tools = buildTools(params.tools, isImageModel);
791
+ if (tools) {
792
+ body.tools = tools;
793
+ if (params.toolChoice === "auto" || params.toolChoice === "none" || params.toolChoice === "required") {
794
+ body.tool_choice = params.toolChoice;
795
+ } else if (params.toolChoice && typeof params.toolChoice === "object") {
796
+ body.tool_choice = {
797
+ name: params.toolChoice.name,
798
+ type: "function"
799
+ };
800
+ }
801
+ if (typeof params.parallelToolCalls === "boolean") {
802
+ body.parallel_tool_calls = params.parallelToolCalls;
803
+ }
804
+ }
805
+ if (typeof params.temperature === "number")
806
+ body.temperature = params.temperature;
807
+ if (typeof params.topP === "number")
808
+ body.top_p = params.topP;
809
+ if (typeof params.maxTokens === "number")
810
+ body.max_output_tokens = params.maxTokens;
811
+ if (params.stopSequences && params.stopSequences.length > 0)
812
+ body.stop = params.stopSequences;
813
+ if (typeof params.seed === "number")
814
+ body.seed = params.seed;
815
+ if (typeof params.frequencyPenalty === "number")
816
+ body.frequency_penalty = params.frequencyPenalty;
817
+ if (typeof params.presencePenalty === "number")
818
+ body.presence_penalty = params.presencePenalty;
819
+ if (params.responseFormat) {
820
+ if (params.responseFormat.type === "text" || params.responseFormat.type === "json_object") {
821
+ body.text = { format: { type: params.responseFormat.type } };
822
+ } else if (params.responseFormat.type === "json_schema") {
823
+ body.text = {
824
+ format: {
825
+ name: params.responseFormat.name,
826
+ schema: params.responseFormat.schema,
827
+ strict: params.responseFormat.strict ?? true,
828
+ type: "json_schema"
829
+ }
830
+ };
831
+ }
832
+ }
833
+ if (params.reasoning && isOpenAIReasoningModel(capabilityModel)) {
834
+ const effort = openaiEffortValue(capabilityModel, params.reasoning);
835
+ if (effort) {
836
+ body.reasoning = {
837
+ effort,
838
+ summary: "auto"
839
+ };
840
+ }
841
+ }
842
+ return body;
843
+ };
844
+ var parseJSON = (data) => {
845
+ try {
846
+ return JSON.parse(data);
847
+ } catch {
848
+ return null;
849
+ }
850
+ };
851
+ var parseToolInput = (rawArguments) => {
852
+ try {
853
+ return JSON.parse(rawArguments);
854
+ } catch {
855
+ return rawArguments;
856
+ }
857
+ };
858
+ var extractUsage = (response) => {
859
+ if (!isRecord(response.usage)) {
860
+ return;
861
+ }
862
+ const { usage } = response;
863
+ const input = typeof usage.input_tokens === "number" ? usage.input_tokens : 0;
864
+ const cached = isRecord(usage.input_tokens_details) && typeof usage.input_tokens_details.cached_tokens === "number" ? usage.input_tokens_details.cached_tokens : 0;
865
+ const outputDetails = isRecord(usage.output_tokens_details) ? usage.output_tokens_details : undefined;
866
+ const inputDetails = isRecord(usage.input_tokens_details) ? usage.input_tokens_details : undefined;
867
+ const costDetails = isRecord(usage.cost_details) ? usage.cost_details : undefined;
868
+ const normalized = {
869
+ cacheReadInputTokens: cached,
870
+ cacheWriteInputTokens: inputDetails && typeof inputDetails.cache_write_tokens === "number" ? inputDetails.cache_write_tokens : undefined,
871
+ costCredits: typeof usage.cost === "number" ? usage.cost : undefined,
872
+ inputTokens: Math.max(0, input - cached),
873
+ outputTokens: typeof usage.output_tokens === "number" ? usage.output_tokens : 0,
874
+ reasoningTokens: outputDetails && typeof outputDetails.reasoning_tokens === "number" ? outputDetails.reasoning_tokens : undefined,
875
+ upstreamInferenceCostCredits: costDetails && typeof costDetails.upstream_inference_cost === "number" ? costDetails.upstream_inference_cost : undefined
876
+ };
877
+ if (isRecord(usage.server_tool_use)) {
878
+ normalized.serverToolUse = Object.fromEntries(Object.entries(usage.server_tool_use).filter((entry) => typeof entry[1] === "number"));
879
+ }
880
+ return normalized;
881
+ };
882
+ var extractResponseMetadata = (response) => {
883
+ const providerMetadata = isRecord(response.openrouter_metadata) ? response.openrouter_metadata : undefined;
884
+ const generationId = typeof response.id === "string" ? response.id : undefined;
885
+ const model = typeof response.model === "string" ? response.model : undefined;
886
+ const provider = typeof response.provider === "string" ? response.provider : undefined;
887
+ const serviceTier = typeof response.service_tier === "string" ? response.service_tier : undefined;
888
+ if (!providerMetadata && !generationId && !model && !provider && !serviceTier)
889
+ return;
890
+ return { generationId, model, provider, providerMetadata, serviceTier };
891
+ };
892
+ var extractMimeFormat = (mimeType) => {
893
+ if (typeof mimeType !== "string") {
894
+ return "png";
895
+ }
896
+ if (mimeType.includes("jpeg"))
897
+ return "jpeg";
898
+ if (mimeType.includes("webp"))
899
+ return "webp";
900
+ return "png";
901
+ };
902
+ var processTextDelta = function* (parsed) {
903
+ if (typeof parsed.delta === "string") {
904
+ yield { content: parsed.delta, type: "text" };
905
+ }
906
+ };
907
+ var processPartialImage = function* (parsed) {
908
+ const itemId = typeof parsed.item_id === "string" ? parsed.item_id : undefined;
909
+ const b64 = typeof parsed.partial_image_b64 === "string" ? parsed.partial_image_b64 : undefined;
910
+ if (b64) {
911
+ yield {
912
+ data: b64,
913
+ format: "png",
914
+ imageId: itemId,
915
+ isPartial: true,
916
+ type: "image"
917
+ };
918
+ }
919
+ };
920
+ var processFunctionCallArgumentsDelta = (parsed, pendingCalls) => {
921
+ const itemId = typeof parsed.item_id === "string" ? parsed.item_id : "";
922
+ const callId = typeof parsed.call_id === "string" ? parsed.call_id : "";
923
+ const delta = typeof parsed.arguments_delta === "string" ? parsed.arguments_delta : "";
924
+ const existing = pendingCalls.get(itemId);
925
+ if (existing) {
926
+ existing.arguments += delta;
927
+ } else {
928
+ pendingCalls.set(itemId, {
929
+ arguments: delta,
930
+ callId,
931
+ name: ""
932
+ });
933
+ }
934
+ };
935
+ var processFunctionCallArgumentsDone = function* (parsed, pendingCalls) {
936
+ const itemId = typeof parsed.item_id === "string" ? parsed.item_id : "";
937
+ const callId = typeof parsed.call_id === "string" ? parsed.call_id : "";
938
+ const fullArgs = typeof parsed.arguments === "string" ? parsed.arguments : "";
939
+ const pending = pendingCalls.get(itemId);
940
+ const name = pending?.name ?? "";
941
+ const args = fullArgs || pending?.arguments || "";
942
+ pendingCalls.delete(itemId);
943
+ yield {
944
+ id: callId || pending?.callId || itemId,
945
+ input: parseToolInput(args),
946
+ name,
947
+ providerData: pending?.providerData ? { ...pending.providerData, arguments: args } : undefined,
948
+ type: "tool_use"
949
+ };
950
+ };
951
+ var processOutputItemAdded = (parsed, pendingCalls) => {
952
+ if (!isRecord(parsed.item)) {
953
+ return;
954
+ }
955
+ const { item } = parsed;
956
+ const itemId = typeof item.id === "string" ? item.id : "";
957
+ const itemType = typeof item.type === "string" ? item.type : "";
958
+ if (itemType !== "function_call") {
959
+ return;
960
+ }
961
+ const callId = typeof item.call_id === "string" ? item.call_id : "";
962
+ const name = typeof item.name === "string" ? item.name : "";
963
+ pendingCalls.set(itemId, {
964
+ arguments: "",
965
+ callId,
966
+ name,
967
+ providerData: { ...item }
968
+ });
969
+ };
970
+ var processOutputItemDone = function* (parsed) {
971
+ if (!isRecord(parsed.item) || typeof parsed.item.type !== "string")
972
+ return;
973
+ if (!parsed.item.type.startsWith("openrouter:"))
974
+ return;
975
+ yield {
976
+ data: { ...parsed.item },
977
+ provider: "openrouter",
978
+ type: "provider_event"
979
+ };
980
+ };
981
+ var isCompletedImageGeneration = (item) => item.type === "image_generation_call" && item.status === "completed" && typeof item.result === "string" && item.result !== "";
982
+ var buildImageChunk = (item) => ({
983
+ data: typeof item.result === "string" ? item.result : "",
984
+ format: extractMimeFormat(item.output_format),
985
+ imageId: typeof item.id === "string" ? item.id : undefined,
986
+ isPartial: false,
987
+ revisedPrompt: typeof item.revised_prompt === "string" ? item.revised_prompt : undefined,
988
+ type: "image"
989
+ });
990
+ var extractImageFromOutput = function* (output) {
991
+ const completedImages = output.filter(isCompletedImageGeneration);
992
+ for (const item of completedImages) {
993
+ yield buildImageChunk(item);
994
+ }
995
+ };
996
+ var extractCitationsFromOutput = function* (output) {
997
+ for (const item of output) {
998
+ if (!isRecordArray(item.content))
999
+ continue;
1000
+ for (const content of item.content) {
1001
+ if (!Array.isArray(content.annotations))
1002
+ continue;
1003
+ for (const annotation of content.annotations) {
1004
+ if (!isRecord(annotation) || annotation.type !== "url_citation")
1005
+ continue;
1006
+ if (typeof annotation.url !== "string")
1007
+ continue;
1008
+ yield {
1009
+ content: typeof annotation.content === "string" ? annotation.content : undefined,
1010
+ endIndex: typeof annotation.end_index === "number" ? annotation.end_index : undefined,
1011
+ startIndex: typeof annotation.start_index === "number" ? annotation.start_index : undefined,
1012
+ title: typeof annotation.title === "string" ? annotation.title : undefined,
1013
+ type: "citation",
1014
+ url: annotation.url
1015
+ };
1016
+ }
1017
+ }
1018
+ }
1019
+ };
1020
+ var processCompleted = function* (parsed) {
1021
+ if (!isRecord(parsed.response)) {
1022
+ yield { type: "done", usage: undefined };
1023
+ return;
1024
+ }
1025
+ const { response } = parsed;
1026
+ const usage = extractUsage(response);
1027
+ const metadata = extractResponseMetadata(response);
1028
+ if (isRecordArray(response.output)) {
1029
+ yield* extractCitationsFromOutput(response.output);
1030
+ yield* extractImageFromOutput(response.output);
1031
+ }
1032
+ yield { metadata, type: "done", usage };
1033
+ };
1034
+ var responseFailure = (eventType, parsed, providerName) => {
1035
+ const response = isRecord(parsed.response) ? parsed.response : parsed;
1036
+ const error = isRecord(response.error) ? response.error : undefined;
1037
+ const type = typeof response.error_type === "string" ? response.error_type : error && typeof error.code === "string" ? error.code : eventType;
1038
+ return new ProviderError({
1039
+ message: error && typeof error.message === "string" ? error.message : `OpenRouter Responses API: ${eventType}`,
1040
+ metadata: response,
1041
+ provider: providerName,
1042
+ retryable: type === "rate_limit_exceeded" || type === "provider_overloaded" || type === "provider_unavailable" || type === "server",
1043
+ type
1044
+ });
1045
+ };
1046
+ var processSSEEvent = function* (eventType, parsed, pendingCalls, providerName) {
1047
+ switch (eventType) {
1048
+ case "response.reasoning_summary_text.delta": {
1049
+ const delta = typeof parsed.delta === "string" ? parsed.delta : "";
1050
+ if (!delta)
1051
+ break;
1052
+ yield {
1053
+ content: delta,
1054
+ type: "thinking"
1055
+ };
1056
+ break;
1057
+ }
1058
+ case "response.output_text.delta":
1059
+ yield* processTextDelta(parsed);
1060
+ break;
1061
+ case "response.image_generation_call.partial_image":
1062
+ yield* processPartialImage(parsed);
1063
+ break;
1064
+ case "response.output_item.added":
1065
+ processOutputItemAdded(parsed, pendingCalls);
1066
+ break;
1067
+ case "response.output_item.done":
1068
+ yield* processOutputItemDone(parsed);
1069
+ break;
1070
+ case "response.function_call_arguments.delta":
1071
+ processFunctionCallArgumentsDelta(parsed, pendingCalls);
1072
+ break;
1073
+ case "response.function_call_arguments.done":
1074
+ yield* processFunctionCallArgumentsDone(parsed, pendingCalls);
1075
+ break;
1076
+ case "response.completed":
1077
+ yield* processCompleted(parsed);
1078
+ break;
1079
+ case "response.failed":
1080
+ case "response.incomplete":
1081
+ case "response.error":
1082
+ case "error":
1083
+ throw responseFailure(eventType, parsed, providerName);
1084
+ }
1085
+ };
1086
+ var flushSSEBuffer = function* (state) {
1087
+ if (!state.currentEvent || !state.buffer) {
1088
+ return;
1089
+ }
1090
+ const parsed = parseJSON(state.buffer);
1091
+ if (parsed) {
1092
+ yield* processSSEEvent(state.currentEvent, parsed, state.pendingCalls, state.providerName);
1093
+ }
1094
+ state.currentEvent = "";
1095
+ state.buffer = "";
1096
+ };
1097
+ var parseSSELine = (trimmed, state) => {
1098
+ if (trimmed.startsWith("event: ")) {
1099
+ state.currentEvent = trimmed.slice(EVENT_PREFIX_LENGTH);
1100
+ } else if (trimmed.startsWith("data: ")) {
1101
+ state.buffer = trimmed.slice(DATA_PREFIX_LENGTH);
1102
+ }
1103
+ };
1104
+ var processSSELine = function* (line, state) {
1105
+ const trimmed = line.trim();
1106
+ if (trimmed) {
1107
+ parseSSELine(trimmed, state);
1108
+ return;
1109
+ }
1110
+ yield* flushSSEBuffer(state);
1111
+ };
1112
+ var processSSELines = function* (lines, state) {
1113
+ for (const line of lines) {
1114
+ yield* processSSELine(line, state);
1115
+ }
1116
+ };
1117
+ var drainReader = async function* (reader, decoder, state, signal) {
1118
+ let textBuffer = "";
1119
+ for (let result = await reader.read();!result.done && !signal?.aborted; result = await reader.read()) {
1120
+ textBuffer += decoder.decode(result.value, { stream: true });
1121
+ const lines = textBuffer.split(`
1122
+ `);
1123
+ textBuffer = lines.pop() ?? "";
1124
+ yield* processSSELines(lines, state);
1125
+ }
1126
+ if (textBuffer.trim()) {
1127
+ yield* processSSELines([textBuffer, ""], state);
1128
+ }
1129
+ };
1130
+ var parseSSEStream = async function* (body, providerName, signal) {
1131
+ const reader = body.getReader();
1132
+ const decoder = new TextDecoder;
1133
+ const state = {
1134
+ buffer: "",
1135
+ currentEvent: "",
1136
+ pendingCalls: new Map,
1137
+ usage: undefined,
1138
+ providerName
1139
+ };
1140
+ try {
1141
+ yield* drainReader(reader, decoder, state, signal);
1142
+ yield* flushSSEBuffer(state);
1143
+ } finally {
1144
+ reader.releaseLock();
1145
+ }
1146
+ };
1147
+ var fetchResponsesStream = async function* (baseUrl, apiKey, body, fetchImpl, headers, providerName, signal) {
1148
+ const target = `${baseUrl}/v1/responses`;
1149
+ const requestHeaders = new Headers(headers);
1150
+ requestHeaders.set("Authorization", `Bearer ${apiKey}`);
1151
+ requestHeaders.set("Content-Type", "application/json");
1152
+ const response = await fetchImpl(target, {
1153
+ ...h2IfHttps(target),
1154
+ body: JSON.stringify(body),
1155
+ headers: requestHeaders,
1156
+ method: "POST",
1157
+ signal
1158
+ });
1159
+ if (!response.ok) {
1160
+ const errorText = await response.text();
1161
+ throw ProviderError.fromResponse(providerName, response.status, errorText);
1162
+ }
1163
+ if (!response.body) {
1164
+ throw new ProviderError({
1165
+ message: `${providerName} Responses API returned no response body`,
1166
+ provider: providerName,
1167
+ retryable: true
1168
+ });
1169
+ }
1170
+ yield* parseSSEStream(response.body, providerName, signal);
1171
+ };
1172
+ var resolveImageModels = (imageModels) => {
1173
+ if (!imageModels) {
1174
+ return new Set;
1175
+ }
1176
+ if (imageModels instanceof Set) {
1177
+ return imageModels;
1178
+ }
1179
+ return new Set(imageModels);
1180
+ };
1181
+ var openaiResponses = (config2) => {
1182
+ if (!config2.apiKey && !config2.tokenSource)
1183
+ throw new Error("openaiResponses() requires either apiKey or tokenSource");
1184
+ const baseUrl = config2.baseUrl ?? DEFAULT_BASE_URL;
1185
+ const fetchImpl = config2.fetch ?? globalThis.fetch;
1186
+ const imageModels = resolveImageModels(config2.imageModels);
1187
+ const providerName = config2.providerName ?? "openai-responses";
1188
+ const resolveKey = async () => config2.tokenSource ? await Promise.resolve(config2.tokenSource()) : config2.apiKey;
1189
+ const resolveHeaders = async (params) => typeof config2.headers === "function" ? await config2.headers(params) : config2.headers ?? {};
1190
+ return instrumentAIProvider({
1191
+ inputCapacity: openaiInputCapacity({
1192
+ baseUrl,
1193
+ fetch: fetchImpl,
1194
+ key: resolveKey,
1195
+ headers: resolveHeaders,
1196
+ modelLimits: config2.modelLimits,
1197
+ body: (params) => {
1198
+ const built = buildResponsesRequestBody(params, imageModels.has(params.model), config2.modelForCapabilities?.(params.model) ?? params.model);
1199
+ return config2.transformRequestBody ? config2.transformRequestBody(built, params) : built;
1200
+ }
1201
+ }),
1202
+ stream: (params) => {
1203
+ const isImageModel = imageModels.has(params.model);
1204
+ const builtBody = buildResponsesRequestBody(params, isImageModel, config2.modelForCapabilities?.(params.model) ?? params.model);
1205
+ const body = config2.transformRequestBody ? config2.transformRequestBody(builtBody, params) : builtBody;
1206
+ return async function* () {
1207
+ const [apiKey, headers] = await Promise.all([
1208
+ resolveKey(),
1209
+ resolveHeaders(params)
1210
+ ]);
1211
+ yield* fetchResponsesStream(baseUrl, apiKey, body, fetchImpl, headers, providerName, params.signal);
1212
+ }();
1213
+ }
1214
+ }, providerName);
1215
+ };
1216
+
1217
+ // src/ai/providers/openai.ts
1218
+ var h2IfHttps2 = (url) => url.startsWith("https://") ? { protocol: "http2" } : {};
1219
+ var DEFAULT_BASE_URL2 = "https://api.openai.com";
394
1220
  var SSE_DATA_PREFIX_LENGTH = 6;
395
1221
  var DONE_SENTINEL = "[DONE]";
396
1222
  var NOT_FOUND = -1;
397
- var isRecord = (value) => typeof value === "object" && value !== null;
398
- var isRecordArray = (value) => Array.isArray(value) && value.length > 0 && isRecord(value[0]);
1223
+ var isRecord2 = (value) => typeof value === "object" && value !== null;
1224
+ var isRecordArray2 = (value) => Array.isArray(value) && value.length > 0 && isRecord2(value[0]);
399
1225
  var hasArrayContent = (msg) => typeof msg.content !== "string" && Array.isArray(msg.content);
400
1226
  var buildToolMessages = (blocks) => {
401
1227
  const toolUseBlocks = blocks.filter((block) => block.type === "tool_use");
@@ -428,8 +1254,8 @@ var processMessageAtIndex = (result, msg, idx) => {
428
1254
  if (!hasArrayContent(msg)) {
429
1255
  return;
430
1256
  }
431
- const hasToolBlocks = msg.content.some((block) => block.type === "tool_use" || block.type === "tool_result");
432
- if (!hasToolBlocks) {
1257
+ const hasToolBlocks2 = msg.content.some((block) => block.type === "tool_use" || block.type === "tool_result");
1258
+ if (!hasToolBlocks2) {
433
1259
  return;
434
1260
  }
435
1261
  const toolMessages = buildToolMessages(msg.content);
@@ -573,7 +1399,7 @@ var buildRequestBody = (params, capabilityModel = params.model) => {
573
1399
  }
574
1400
  return body;
575
1401
  };
576
- var parseToolInput = (rawArguments) => {
1402
+ var parseToolInput2 = (rawArguments) => {
577
1403
  try {
578
1404
  return JSON.parse(rawArguments);
579
1405
  } catch {
@@ -582,7 +1408,7 @@ var parseToolInput = (rawArguments) => {
582
1408
  };
583
1409
  var flushPendingToolCalls = function* (pendingToolCalls) {
584
1410
  for (const [, tool] of pendingToolCalls) {
585
- const input = parseToolInput(tool.arguments);
1411
+ const input = parseToolInput2(tool.arguments);
586
1412
  yield {
587
1413
  id: tool.id,
588
1414
  input,
@@ -592,7 +1418,7 @@ var flushPendingToolCalls = function* (pendingToolCalls) {
592
1418
  }
593
1419
  pendingToolCalls.clear();
594
1420
  };
595
- var extractUsage = (parsedUsage) => {
1421
+ var extractUsage2 = (parsedUsage) => {
596
1422
  const prompt = parsedUsage.prompt_tokens ?? 0;
597
1423
  const cached = parsedUsage.cached_tokens ?? 0;
598
1424
  return {
@@ -637,7 +1463,7 @@ var processToolCallDelta = (toolCall, pendingToolCalls) => {
637
1463
  if (index === undefined) {
638
1464
  return;
639
1465
  }
640
- const func = isRecord(toolCall.function) ? toolCall.function : null;
1466
+ const func = isRecord2(toolCall.function) ? toolCall.function : null;
641
1467
  initPendingToolCall(toolCall, func, index, pendingToolCalls);
642
1468
  const pending = pendingToolCalls.get(index);
643
1469
  if (!pending) {
@@ -654,7 +1480,7 @@ var processDelta = function* (delta, pendingToolCalls) {
654
1480
  if (typeof delta.content === "string") {
655
1481
  yield { content: delta.content, type: "text" };
656
1482
  }
657
- if (isRecord(delta.audio)) {
1483
+ if (isRecord2(delta.audio)) {
658
1484
  const audio = delta.audio;
659
1485
  if (typeof audio.data === "string" || typeof audio.transcript === "string") {
660
1486
  yield {
@@ -666,14 +1492,14 @@ var processDelta = function* (delta, pendingToolCalls) {
666
1492
  };
667
1493
  }
668
1494
  }
669
- if (isRecordArray(delta.tool_calls)) {
1495
+ if (isRecordArray2(delta.tool_calls)) {
670
1496
  processToolCallDeltas(delta.tool_calls, pendingToolCalls);
671
1497
  }
672
1498
  if (Array.isArray(delta.annotations)) {
673
1499
  for (const annotation of delta.annotations) {
674
- if (!isRecord(annotation) || annotation.type !== "url_citation")
1500
+ if (!isRecord2(annotation) || annotation.type !== "url_citation")
675
1501
  continue;
676
- const citation = isRecord(annotation.url_citation) ? annotation.url_citation : annotation;
1502
+ const citation = isRecord2(annotation.url_citation) ? annotation.url_citation : annotation;
677
1503
  if (typeof citation.url !== "string")
678
1504
  continue;
679
1505
  yield {
@@ -688,19 +1514,19 @@ var processDelta = function* (delta, pendingToolCalls) {
688
1514
  }
689
1515
  };
690
1516
  var narrowResponseMetadata = (parsed) => {
691
- const providerMetadata = isRecord(parsed.openrouter_metadata) ? parsed.openrouter_metadata : undefined;
1517
+ const providerMetadata = isRecord2(parsed.openrouter_metadata) ? parsed.openrouter_metadata : undefined;
692
1518
  const generationId = typeof parsed.id === "string" ? parsed.id : undefined;
693
1519
  const model = typeof parsed.model === "string" ? parsed.model : undefined;
694
1520
  const serviceTier = typeof parsed.service_tier === "string" ? parsed.service_tier : undefined;
695
- const selected = providerMetadata && isRecord(providerMetadata.endpoints) ? providerMetadata.endpoints.available : undefined;
696
- const selectedEndpoint = Array.isArray(selected) ? selected.find((entry) => isRecord(entry) && entry.selected === true) : undefined;
697
- const provider = isRecord(selectedEndpoint) && typeof selectedEndpoint.provider === "string" ? selectedEndpoint.provider : undefined;
1521
+ const selected = providerMetadata && isRecord2(providerMetadata.endpoints) ? providerMetadata.endpoints.available : undefined;
1522
+ const selectedEndpoint = Array.isArray(selected) ? selected.find((entry) => isRecord2(entry) && entry.selected === true) : undefined;
1523
+ const provider = isRecord2(selectedEndpoint) && typeof selectedEndpoint.provider === "string" ? selectedEndpoint.provider : undefined;
698
1524
  if (!providerMetadata && !generationId && !model && !serviceTier)
699
1525
  return;
700
1526
  return { generationId, model, provider, providerMetadata, serviceTier };
701
1527
  };
702
1528
  var processChoice = function* (choice, pendingToolCalls) {
703
- const delta = isRecord(choice.delta) ? choice.delta : null;
1529
+ const delta = isRecord2(choice.delta) ? choice.delta : null;
704
1530
  if (delta) {
705
1531
  yield* processDelta(delta, pendingToolCalls);
706
1532
  }
@@ -709,18 +1535,18 @@ var processChoice = function* (choice, pendingToolCalls) {
709
1535
  }
710
1536
  };
711
1537
  var narrowUsageRecord = (parsed) => {
712
- if (!isRecord(parsed.usage)) {
1538
+ if (!isRecord2(parsed.usage)) {
713
1539
  return;
714
1540
  }
715
1541
  const { usage } = parsed;
716
1542
  const promptTokens = typeof usage.prompt_tokens === "number" ? usage.prompt_tokens : 0;
717
1543
  const completionTokens = typeof usage.completion_tokens === "number" ? usage.completion_tokens : 0;
718
- const cachedTokens = isRecord(usage.prompt_tokens_details) && typeof usage.prompt_tokens_details.cached_tokens === "number" ? usage.prompt_tokens_details.cached_tokens : 0;
719
- const cacheWriteTokens = isRecord(usage.prompt_tokens_details) && typeof usage.prompt_tokens_details.cache_write_tokens === "number" ? usage.prompt_tokens_details.cache_write_tokens : 0;
720
- const reasoningTokens = isRecord(usage.completion_tokens_details) && typeof usage.completion_tokens_details.reasoning_tokens === "number" ? usage.completion_tokens_details.reasoning_tokens : 0;
1544
+ const cachedTokens = isRecord2(usage.prompt_tokens_details) && typeof usage.prompt_tokens_details.cached_tokens === "number" ? usage.prompt_tokens_details.cached_tokens : 0;
1545
+ const cacheWriteTokens = isRecord2(usage.prompt_tokens_details) && typeof usage.prompt_tokens_details.cache_write_tokens === "number" ? usage.prompt_tokens_details.cache_write_tokens : 0;
1546
+ const reasoningTokens = isRecord2(usage.completion_tokens_details) && typeof usage.completion_tokens_details.reasoning_tokens === "number" ? usage.completion_tokens_details.reasoning_tokens : 0;
721
1547
  const cost = typeof usage.cost === "number" ? usage.cost : undefined;
722
- const upstreamInferenceCost = isRecord(usage.cost_details) && typeof usage.cost_details.upstream_inference_cost === "number" ? usage.cost_details.upstream_inference_cost : undefined;
723
- const normalized = extractUsage({
1548
+ const upstreamInferenceCost = isRecord2(usage.cost_details) && typeof usage.cost_details.upstream_inference_cost === "number" ? usage.cost_details.upstream_inference_cost : undefined;
1549
+ const normalized = extractUsage2({
724
1550
  cache_write_tokens: cacheWriteTokens,
725
1551
  cached_tokens: cachedTokens,
726
1552
  completion_tokens: completionTokens,
@@ -729,12 +1555,12 @@ var narrowUsageRecord = (parsed) => {
729
1555
  reasoning_tokens: reasoningTokens,
730
1556
  upstream_inference_cost: upstreamInferenceCost
731
1557
  });
732
- if (isRecord(usage.server_tool_use)) {
1558
+ if (isRecord2(usage.server_tool_use)) {
733
1559
  normalized.serverToolUse = Object.fromEntries(Object.entries(usage.server_tool_use).filter((entry) => typeof entry[1] === "number"));
734
1560
  }
735
1561
  return normalized;
736
1562
  };
737
- var processSSELine = function* (line, pendingToolCalls, providerName) {
1563
+ var processSSELine2 = function* (line, pendingToolCalls, providerName) {
738
1564
  const trimmed = line.trim();
739
1565
  if (!trimmed || !trimmed.startsWith("data: ")) {
740
1566
  return;
@@ -750,9 +1576,9 @@ var processSSELine = function* (line, pendingToolCalls, providerName) {
750
1576
  } catch {
751
1577
  return;
752
1578
  }
753
- if (isRecord(parsed.error)) {
1579
+ if (isRecord2(parsed.error)) {
754
1580
  const error = parsed.error;
755
- const metadata2 = isRecord(error.metadata) ? error.metadata : undefined;
1581
+ const metadata2 = isRecord2(error.metadata) ? error.metadata : undefined;
756
1582
  const status = typeof error.code === "number" ? error.code : null;
757
1583
  const type = metadata2 && typeof metadata2.error_type === "string" ? metadata2.error_type : typeof error.error_type === "string" ? error.error_type : null;
758
1584
  throw new ProviderError({
@@ -773,16 +1599,16 @@ var processSSELine = function* (line, pendingToolCalls, providerName) {
773
1599
  yield { metadata, type: "response_metadata" };
774
1600
  }
775
1601
  const { choices } = parsed;
776
- if (!isRecordArray(choices)) {
1602
+ if (!isRecordArray2(choices)) {
777
1603
  return;
778
1604
  }
779
1605
  const [firstChoice] = choices;
780
1606
  if (!firstChoice) {
781
1607
  return;
782
1608
  }
783
- if (isRecord(firstChoice.error)) {
1609
+ if (isRecord2(firstChoice.error)) {
784
1610
  const error = firstChoice.error;
785
- const metadata2 = isRecord(error.metadata) ? error.metadata : undefined;
1611
+ const metadata2 = isRecord2(error.metadata) ? error.metadata : undefined;
786
1612
  const status = typeof error.code === "number" ? error.code : null;
787
1613
  throw new ProviderError({
788
1614
  message: typeof error.message === "string" ? error.message : "OpenRouter stream failed",
@@ -797,7 +1623,7 @@ var processSSELine = function* (line, pendingToolCalls, providerName) {
797
1623
  };
798
1624
  var isUsageUpdate = (chunk) => chunk.type === "usage_update";
799
1625
  var collectYieldableChunks = (line, pendingToolCalls, usageRef, metadataRef, providerName) => {
800
- const allChunks = Array.from(processSSELine(line, pendingToolCalls, providerName));
1626
+ const allChunks = Array.from(processSSELine2(line, pendingToolCalls, providerName));
801
1627
  const usageChunks = allChunks.filter(isUsageUpdate);
802
1628
  const lastUsage = usageChunks.at(NOT_FOUND);
803
1629
  if (lastUsage) {
@@ -817,7 +1643,7 @@ var collectYieldableChunks = (line, pendingToolCalls, usageRef, metadataRef, pro
817
1643
  }
818
1644
  return allChunks.filter((chunk) => !isUsageUpdate(chunk) && chunk.type !== "response_metadata");
819
1645
  };
820
- var processSSELines = function* (lines, pendingToolCalls, usageRef, metadataRef, providerName) {
1646
+ var processSSELines2 = function* (lines, pendingToolCalls, usageRef, metadataRef, providerName) {
821
1647
  for (const line of lines) {
822
1648
  yield* collectYieldableChunks(line, pendingToolCalls, usageRef, metadataRef, providerName);
823
1649
  }
@@ -829,13 +1655,13 @@ var processStreamValue = (value, decoder, state) => {
829
1655
  state.buffer = lines.pop() ?? "";
830
1656
  return lines;
831
1657
  };
832
- var drainReader = async function* (reader, decoder, state, signal) {
1658
+ var drainReader2 = async function* (reader, decoder, state, signal) {
833
1659
  for (let result = await reader.read();!result.done && !signal?.aborted; result = await reader.read()) {
834
1660
  const lines = processStreamValue(result.value, decoder, state);
835
- yield* processSSELines(lines, state.pendingToolCalls, state.usageRef, state.metadataRef, state.providerName);
1661
+ yield* processSSELines2(lines, state.pendingToolCalls, state.usageRef, state.metadataRef, state.providerName);
836
1662
  }
837
1663
  };
838
- var parseSSEStream = async function* (body, initialMetadata, providerName = "openai", signal) {
1664
+ var parseSSEStream2 = async function* (body, initialMetadata, providerName = "openai", signal) {
839
1665
  const reader = body.getReader();
840
1666
  const decoder = new TextDecoder;
841
1667
  const state = {
@@ -846,7 +1672,7 @@ var parseSSEStream = async function* (body, initialMetadata, providerName = "ope
846
1672
  usageRef: { current: undefined }
847
1673
  };
848
1674
  try {
849
- yield* drainReader(reader, decoder, state, signal);
1675
+ yield* drainReader2(reader, decoder, state, signal);
850
1676
  yield {
851
1677
  metadata: state.metadataRef.current,
852
1678
  type: "done",
@@ -862,7 +1688,7 @@ var fetchOpenAIStream = async function* (baseUrl, apiKey, body, fetchImpl, heade
862
1688
  requestHeaders.set("Authorization", `Bearer ${apiKey}`);
863
1689
  requestHeaders.set("Content-Type", "application/json");
864
1690
  const response = await fetchImpl(target, {
865
- ...h2IfHttps(target),
1691
+ ...h2IfHttps2(target),
866
1692
  body: JSON.stringify(body),
867
1693
  headers: requestHeaders,
868
1694
  method: "POST",
@@ -879,7 +1705,7 @@ var fetchOpenAIStream = async function* (baseUrl, apiKey, body, fetchImpl, heade
879
1705
  retryable: true
880
1706
  });
881
1707
  }
882
- yield* parseSSEStream(response.body, {
1708
+ yield* parseSSEStream2(response.body, {
883
1709
  generationId: response.headers.get("X-Generation-Id") ?? undefined,
884
1710
  providerMetadata: {
885
1711
  cacheAge: response.headers.get("X-OpenRouter-Cache-Age") ?? undefined,
@@ -890,7 +1716,7 @@ var fetchOpenAIStream = async function* (baseUrl, apiKey, body, fetchImpl, heade
890
1716
  }, providerName, signal);
891
1717
  };
892
1718
  var openai = (config2) => {
893
- const baseUrl = config2.baseUrl ?? DEFAULT_BASE_URL;
1719
+ const baseUrl = config2.baseUrl ?? DEFAULT_BASE_URL2;
894
1720
  const fetchImpl = config2.fetch ?? globalThis.fetch;
895
1721
  const providerName = config2.providerName ?? "openai";
896
1722
  if (!config2.apiKey && !config2.tokenSource) {
@@ -904,6 +1730,14 @@ var openai = (config2) => {
904
1730
  };
905
1731
  const resolveHeaders = async (params) => typeof config2.headers === "function" ? await config2.headers(params) : config2.headers ?? {};
906
1732
  return instrumentAIProvider({
1733
+ inputCapacity: config2.transformRequestBody ? undefined : openaiInputCapacity({
1734
+ baseUrl,
1735
+ fetch: fetchImpl,
1736
+ key: resolveKey,
1737
+ headers: resolveHeaders,
1738
+ modelLimits: config2.modelLimits,
1739
+ body: (params) => buildResponsesRequestBody(params, false, config2.modelForCapabilities?.(params.model) ?? params.model)
1740
+ }),
907
1741
  stream: (params) => {
908
1742
  const openaiBody = buildRequestBody(params, config2.modelForCapabilities?.(params.model) ?? params.model);
909
1743
  const body = config2.transformRequestBody ? config2.transformRequestBody(openaiBody, params) : openaiBody;
@@ -921,5 +1755,5 @@ export {
921
1755
  openai
922
1756
  };
923
1757
 
924
- //# debugId=89626FDD4663206064756E2164756E21
1758
+ //# debugId=D8DCEEFFFA068E6864756E2164756E21
925
1759
  //# sourceMappingURL=openai.js.map