@ai-sdk/openai-compatible 3.0.0-beta.22 → 3.0.0-beta.24

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.mjs DELETED
@@ -1,1815 +0,0 @@
1
- // src/chat/openai-compatible-chat-language-model.ts
2
- import {
3
- InvalidResponseDataError
4
- } from "@ai-sdk/provider";
5
- import {
6
- combineHeaders,
7
- createEventSourceResponseHandler,
8
- createJsonErrorResponseHandler,
9
- createJsonResponseHandler,
10
- generateId,
11
- isCustomReasoning,
12
- isParsableJson,
13
- parseProviderOptions,
14
- postJsonToApi
15
- } from "@ai-sdk/provider-utils";
16
- import { z as z3 } from "zod/v4";
17
-
18
- // src/utils/to-camel-case.ts
19
- function toCamelCase(str) {
20
- return str.replace(/[_-]([a-z])/g, (g) => g[1].toUpperCase());
21
- }
22
- function resolveProviderOptionsKey(rawName, providerOptions) {
23
- const camelName = toCamelCase(rawName);
24
- if (camelName !== rawName && (providerOptions == null ? void 0 : providerOptions[camelName]) != null) {
25
- return camelName;
26
- }
27
- return rawName;
28
- }
29
- function warnIfDeprecatedProviderOptionsKey({
30
- rawName,
31
- providerOptions,
32
- warnings
33
- }) {
34
- const camelName = toCamelCase(rawName);
35
- if (camelName !== rawName && (providerOptions == null ? void 0 : providerOptions[rawName]) != null) {
36
- warnings.push({
37
- type: "deprecated",
38
- setting: `providerOptions key '${rawName}'`,
39
- message: `Use '${camelName}' instead.`
40
- });
41
- }
42
- }
43
-
44
- // src/openai-compatible-error.ts
45
- import { z } from "zod/v4";
46
- var openaiCompatibleErrorDataSchema = z.object({
47
- error: z.object({
48
- message: z.string(),
49
- // The additional information below is handled loosely to support
50
- // OpenAI-compatible providers that have slightly different error
51
- // responses:
52
- type: z.string().nullish(),
53
- param: z.any().nullish(),
54
- code: z.union([z.string(), z.number()]).nullish()
55
- })
56
- });
57
- var defaultOpenAICompatibleErrorStructure = {
58
- errorSchema: openaiCompatibleErrorDataSchema,
59
- errorToMessage: (data) => data.error.message
60
- };
61
-
62
- // src/chat/convert-openai-compatible-chat-usage.ts
63
- function convertOpenAICompatibleChatUsage(usage) {
64
- var _a, _b, _c, _d, _e, _f;
65
- if (usage == null) {
66
- return {
67
- inputTokens: {
68
- total: void 0,
69
- noCache: void 0,
70
- cacheRead: void 0,
71
- cacheWrite: void 0
72
- },
73
- outputTokens: {
74
- total: void 0,
75
- text: void 0,
76
- reasoning: void 0
77
- },
78
- raw: void 0
79
- };
80
- }
81
- const promptTokens = (_a = usage.prompt_tokens) != null ? _a : 0;
82
- const completionTokens = (_b = usage.completion_tokens) != null ? _b : 0;
83
- const cacheReadTokens = (_d = (_c = usage.prompt_tokens_details) == null ? void 0 : _c.cached_tokens) != null ? _d : 0;
84
- const reasoningTokens = (_f = (_e = usage.completion_tokens_details) == null ? void 0 : _e.reasoning_tokens) != null ? _f : 0;
85
- return {
86
- inputTokens: {
87
- total: promptTokens,
88
- noCache: promptTokens - cacheReadTokens,
89
- cacheRead: cacheReadTokens,
90
- cacheWrite: void 0
91
- },
92
- outputTokens: {
93
- total: completionTokens,
94
- text: completionTokens - reasoningTokens,
95
- reasoning: reasoningTokens
96
- },
97
- raw: usage
98
- };
99
- }
100
-
101
- // src/chat/convert-to-openai-compatible-chat-messages.ts
102
- import {
103
- UnsupportedFunctionalityError
104
- } from "@ai-sdk/provider";
105
- import {
106
- convertBase64ToUint8Array,
107
- convertToBase64,
108
- isProviderReference
109
- } from "@ai-sdk/provider-utils";
110
- function getOpenAIMetadata(message) {
111
- var _a, _b;
112
- return (_b = (_a = message == null ? void 0 : message.providerOptions) == null ? void 0 : _a.openaiCompatible) != null ? _b : {};
113
- }
114
- function getAudioFormat(mediaType) {
115
- switch (mediaType) {
116
- case "audio/wav":
117
- return "wav";
118
- case "audio/mp3":
119
- case "audio/mpeg":
120
- return "mp3";
121
- default:
122
- return null;
123
- }
124
- }
125
- function convertToOpenAICompatibleChatMessages(prompt) {
126
- var _a, _b, _c;
127
- const messages = [];
128
- for (const { role, content, ...message } of prompt) {
129
- const metadata = getOpenAIMetadata({ ...message });
130
- switch (role) {
131
- case "system": {
132
- messages.push({ role: "system", content, ...metadata });
133
- break;
134
- }
135
- case "user": {
136
- if (content.length === 1 && content[0].type === "text") {
137
- messages.push({
138
- role: "user",
139
- content: content[0].text,
140
- ...getOpenAIMetadata(content[0])
141
- });
142
- break;
143
- }
144
- messages.push({
145
- role: "user",
146
- content: content.map((part) => {
147
- var _a2;
148
- const partMetadata = getOpenAIMetadata(part);
149
- switch (part.type) {
150
- case "text": {
151
- return { type: "text", text: part.text, ...partMetadata };
152
- }
153
- case "file": {
154
- if (isProviderReference(part.data)) {
155
- throw new UnsupportedFunctionalityError({
156
- functionality: "file parts with provider references"
157
- });
158
- }
159
- if (part.mediaType.startsWith("image/")) {
160
- const mediaType = part.mediaType === "image/*" ? "image/jpeg" : part.mediaType;
161
- return {
162
- type: "image_url",
163
- image_url: {
164
- url: part.data instanceof URL ? part.data.toString() : `data:${mediaType};base64,${convertToBase64(part.data)}`
165
- },
166
- ...partMetadata
167
- };
168
- }
169
- if (part.mediaType.startsWith("audio/")) {
170
- if (part.data instanceof URL) {
171
- throw new UnsupportedFunctionalityError({
172
- functionality: "audio file parts with URLs"
173
- });
174
- }
175
- const format = getAudioFormat(part.mediaType);
176
- if (format === null) {
177
- throw new UnsupportedFunctionalityError({
178
- functionality: `audio media type ${part.mediaType}`
179
- });
180
- }
181
- return {
182
- type: "input_audio",
183
- input_audio: {
184
- data: convertToBase64(part.data),
185
- format
186
- },
187
- ...partMetadata
188
- };
189
- }
190
- if (part.mediaType === "application/pdf") {
191
- if (part.data instanceof URL) {
192
- throw new UnsupportedFunctionalityError({
193
- functionality: "PDF file parts with URLs"
194
- });
195
- }
196
- return {
197
- type: "file",
198
- file: {
199
- filename: (_a2 = part.filename) != null ? _a2 : "document.pdf",
200
- file_data: `data:application/pdf;base64,${convertToBase64(part.data)}`
201
- },
202
- ...partMetadata
203
- };
204
- }
205
- if (part.mediaType.startsWith("text/")) {
206
- const textContent = part.data instanceof URL ? part.data.toString() : typeof part.data === "string" ? new TextDecoder().decode(
207
- convertBase64ToUint8Array(part.data)
208
- ) : new TextDecoder().decode(part.data);
209
- return {
210
- type: "text",
211
- text: textContent,
212
- ...partMetadata
213
- };
214
- }
215
- throw new UnsupportedFunctionalityError({
216
- functionality: `file part media type ${part.mediaType}`
217
- });
218
- }
219
- }
220
- }),
221
- ...metadata
222
- });
223
- break;
224
- }
225
- case "assistant": {
226
- let text = "";
227
- let reasoning = "";
228
- const toolCalls = [];
229
- for (const part of content) {
230
- const partMetadata = getOpenAIMetadata(part);
231
- switch (part.type) {
232
- case "text": {
233
- text += part.text;
234
- break;
235
- }
236
- case "reasoning": {
237
- reasoning += part.text;
238
- break;
239
- }
240
- case "tool-call": {
241
- const thoughtSignature = (_b = (_a = part.providerOptions) == null ? void 0 : _a.google) == null ? void 0 : _b.thoughtSignature;
242
- toolCalls.push({
243
- id: part.toolCallId,
244
- type: "function",
245
- function: {
246
- name: part.toolName,
247
- arguments: JSON.stringify(part.input)
248
- },
249
- ...partMetadata,
250
- // Include extra_content for Google Gemini thought signatures
251
- ...thoughtSignature ? {
252
- extra_content: {
253
- google: {
254
- thought_signature: String(thoughtSignature)
255
- }
256
- }
257
- } : {}
258
- });
259
- break;
260
- }
261
- }
262
- }
263
- messages.push({
264
- role: "assistant",
265
- content: text,
266
- ...reasoning.length > 0 ? { reasoning_content: reasoning } : {},
267
- tool_calls: toolCalls.length > 0 ? toolCalls : void 0,
268
- ...metadata
269
- });
270
- break;
271
- }
272
- case "tool": {
273
- for (const toolResponse of content) {
274
- if (toolResponse.type === "tool-approval-response") {
275
- continue;
276
- }
277
- const output = toolResponse.output;
278
- let contentValue;
279
- switch (output.type) {
280
- case "text":
281
- case "error-text":
282
- contentValue = output.value;
283
- break;
284
- case "execution-denied":
285
- contentValue = (_c = output.reason) != null ? _c : "Tool execution denied.";
286
- break;
287
- case "content":
288
- case "json":
289
- case "error-json":
290
- contentValue = JSON.stringify(output.value);
291
- break;
292
- }
293
- const toolResponseMetadata = getOpenAIMetadata(toolResponse);
294
- messages.push({
295
- role: "tool",
296
- tool_call_id: toolResponse.toolCallId,
297
- content: contentValue,
298
- ...toolResponseMetadata
299
- });
300
- }
301
- break;
302
- }
303
- default: {
304
- const _exhaustiveCheck = role;
305
- throw new Error(`Unsupported role: ${_exhaustiveCheck}`);
306
- }
307
- }
308
- }
309
- return messages;
310
- }
311
-
312
- // src/chat/get-response-metadata.ts
313
- function getResponseMetadata({
314
- id,
315
- model,
316
- created
317
- }) {
318
- return {
319
- id: id != null ? id : void 0,
320
- modelId: model != null ? model : void 0,
321
- timestamp: created != null ? new Date(created * 1e3) : void 0
322
- };
323
- }
324
-
325
- // src/chat/map-openai-compatible-finish-reason.ts
326
- function mapOpenAICompatibleFinishReason(finishReason) {
327
- switch (finishReason) {
328
- case "stop":
329
- return "stop";
330
- case "length":
331
- return "length";
332
- case "content_filter":
333
- return "content-filter";
334
- case "function_call":
335
- case "tool_calls":
336
- return "tool-calls";
337
- default:
338
- return "other";
339
- }
340
- }
341
-
342
- // src/chat/openai-compatible-chat-options.ts
343
- import { z as z2 } from "zod/v4";
344
- var openaiCompatibleLanguageModelChatOptions = z2.object({
345
- /**
346
- * A unique identifier representing your end-user, which can help the provider to
347
- * monitor and detect abuse.
348
- */
349
- user: z2.string().optional(),
350
- /**
351
- * Reasoning effort for reasoning models. Defaults to `medium`.
352
- */
353
- reasoningEffort: z2.string().optional(),
354
- /**
355
- * Controls the verbosity of the generated text. Defaults to `medium`.
356
- */
357
- textVerbosity: z2.string().optional(),
358
- /**
359
- * Whether to use strict JSON schema validation.
360
- * When true, the model uses constrained decoding to guarantee schema compliance.
361
- * Only used when the provider supports structured outputs and a schema is provided.
362
- *
363
- * @default true
364
- */
365
- strictJsonSchema: z2.boolean().optional()
366
- });
367
-
368
- // src/chat/openai-compatible-prepare-tools.ts
369
- import {
370
- UnsupportedFunctionalityError as UnsupportedFunctionalityError2
371
- } from "@ai-sdk/provider";
372
- function prepareTools({
373
- tools,
374
- toolChoice
375
- }) {
376
- tools = (tools == null ? void 0 : tools.length) ? tools : void 0;
377
- const toolWarnings = [];
378
- if (tools == null) {
379
- return { tools: void 0, toolChoice: void 0, toolWarnings };
380
- }
381
- const openaiCompatTools = [];
382
- for (const tool of tools) {
383
- if (tool.type === "provider") {
384
- toolWarnings.push({
385
- type: "unsupported",
386
- feature: `provider-defined tool ${tool.id}`
387
- });
388
- } else {
389
- openaiCompatTools.push({
390
- type: "function",
391
- function: {
392
- name: tool.name,
393
- description: tool.description,
394
- parameters: tool.inputSchema,
395
- ...tool.strict != null ? { strict: tool.strict } : {}
396
- }
397
- });
398
- }
399
- }
400
- if (toolChoice == null) {
401
- return { tools: openaiCompatTools, toolChoice: void 0, toolWarnings };
402
- }
403
- const type = toolChoice.type;
404
- switch (type) {
405
- case "auto":
406
- case "none":
407
- case "required":
408
- return { tools: openaiCompatTools, toolChoice: type, toolWarnings };
409
- case "tool":
410
- return {
411
- tools: openaiCompatTools,
412
- toolChoice: {
413
- type: "function",
414
- function: { name: toolChoice.toolName }
415
- },
416
- toolWarnings
417
- };
418
- default: {
419
- const _exhaustiveCheck = type;
420
- throw new UnsupportedFunctionalityError2({
421
- functionality: `tool choice type: ${_exhaustiveCheck}`
422
- });
423
- }
424
- }
425
- }
426
-
427
- // src/chat/openai-compatible-chat-language-model.ts
428
- var OpenAICompatibleChatLanguageModel = class {
429
- // type inferred via constructor
430
- constructor(modelId, config) {
431
- this.specificationVersion = "v4";
432
- var _a, _b;
433
- this.modelId = modelId;
434
- this.config = config;
435
- const errorStructure = (_a = config.errorStructure) != null ? _a : defaultOpenAICompatibleErrorStructure;
436
- this.chunkSchema = createOpenAICompatibleChatChunkSchema(
437
- errorStructure.errorSchema
438
- );
439
- this.failedResponseHandler = createJsonErrorResponseHandler(errorStructure);
440
- this.supportsStructuredOutputs = (_b = config.supportsStructuredOutputs) != null ? _b : false;
441
- }
442
- get provider() {
443
- return this.config.provider;
444
- }
445
- get providerOptionsName() {
446
- return this.config.provider.split(".")[0].trim();
447
- }
448
- get supportedUrls() {
449
- var _a, _b, _c;
450
- return (_c = (_b = (_a = this.config).supportedUrls) == null ? void 0 : _b.call(_a)) != null ? _c : {};
451
- }
452
- transformRequestBody(args) {
453
- var _a, _b, _c;
454
- return (_c = (_b = (_a = this.config).transformRequestBody) == null ? void 0 : _b.call(_a, args)) != null ? _c : args;
455
- }
456
- async getArgs({
457
- prompt,
458
- maxOutputTokens,
459
- temperature,
460
- topP,
461
- topK,
462
- frequencyPenalty,
463
- presencePenalty,
464
- reasoning,
465
- providerOptions,
466
- stopSequences,
467
- responseFormat,
468
- seed,
469
- toolChoice,
470
- tools
471
- }) {
472
- var _a, _b, _c, _d, _e, _f;
473
- const warnings = [];
474
- const deprecatedOptions = await parseProviderOptions({
475
- provider: "openai-compatible",
476
- providerOptions,
477
- schema: openaiCompatibleLanguageModelChatOptions
478
- });
479
- if (deprecatedOptions != null) {
480
- warnings.push({
481
- type: "deprecated",
482
- setting: "providerOptions key 'openai-compatible'",
483
- message: "Use 'openaiCompatible' instead."
484
- });
485
- }
486
- warnIfDeprecatedProviderOptionsKey({
487
- rawName: this.providerOptionsName,
488
- providerOptions,
489
- warnings
490
- });
491
- const compatibleOptions = Object.assign(
492
- deprecatedOptions != null ? deprecatedOptions : {},
493
- (_a = await parseProviderOptions({
494
- provider: "openaiCompatible",
495
- providerOptions,
496
- schema: openaiCompatibleLanguageModelChatOptions
497
- })) != null ? _a : {},
498
- (_b = await parseProviderOptions({
499
- provider: this.providerOptionsName,
500
- providerOptions,
501
- schema: openaiCompatibleLanguageModelChatOptions
502
- })) != null ? _b : {},
503
- (_c = await parseProviderOptions({
504
- provider: toCamelCase(this.providerOptionsName),
505
- providerOptions,
506
- schema: openaiCompatibleLanguageModelChatOptions
507
- })) != null ? _c : {}
508
- );
509
- const strictJsonSchema = (_d = compatibleOptions == null ? void 0 : compatibleOptions.strictJsonSchema) != null ? _d : true;
510
- if (topK != null) {
511
- warnings.push({ type: "unsupported", feature: "topK" });
512
- }
513
- if ((responseFormat == null ? void 0 : responseFormat.type) === "json" && responseFormat.schema != null && !this.supportsStructuredOutputs) {
514
- warnings.push({
515
- type: "unsupported",
516
- feature: "responseFormat",
517
- details: "JSON response format schema is only supported with structuredOutputs"
518
- });
519
- }
520
- const {
521
- tools: openaiTools,
522
- toolChoice: openaiToolChoice,
523
- toolWarnings
524
- } = prepareTools({
525
- tools,
526
- toolChoice
527
- });
528
- const metadataKey = resolveProviderOptionsKey(
529
- this.providerOptionsName,
530
- providerOptions
531
- );
532
- return {
533
- metadataKey,
534
- args: {
535
- // model id:
536
- model: this.modelId,
537
- // model specific settings:
538
- user: compatibleOptions.user,
539
- // standardized settings:
540
- max_tokens: maxOutputTokens,
541
- temperature,
542
- top_p: topP,
543
- frequency_penalty: frequencyPenalty,
544
- presence_penalty: presencePenalty,
545
- response_format: (responseFormat == null ? void 0 : responseFormat.type) === "json" ? this.supportsStructuredOutputs === true && responseFormat.schema != null ? {
546
- type: "json_schema",
547
- json_schema: {
548
- schema: responseFormat.schema,
549
- strict: strictJsonSchema,
550
- name: (_e = responseFormat.name) != null ? _e : "response",
551
- description: responseFormat.description
552
- }
553
- } : { type: "json_object" } : void 0,
554
- stop: stopSequences,
555
- seed,
556
- ...Object.fromEntries(
557
- Object.entries({
558
- ...providerOptions == null ? void 0 : providerOptions[this.providerOptionsName],
559
- ...providerOptions == null ? void 0 : providerOptions[toCamelCase(this.providerOptionsName)]
560
- }).filter(
561
- ([key]) => !Object.keys(
562
- openaiCompatibleLanguageModelChatOptions.shape
563
- ).includes(key)
564
- )
565
- ),
566
- reasoning_effort: (_f = compatibleOptions.reasoningEffort) != null ? _f : isCustomReasoning(reasoning) && reasoning !== "none" ? reasoning : void 0,
567
- verbosity: compatibleOptions.textVerbosity,
568
- // messages:
569
- messages: convertToOpenAICompatibleChatMessages(prompt),
570
- // tools:
571
- tools: openaiTools,
572
- tool_choice: openaiToolChoice
573
- },
574
- warnings: [...warnings, ...toolWarnings]
575
- };
576
- }
577
- async doGenerate(options) {
578
- var _a, _b, _c, _d, _e, _f, _g, _h;
579
- const { args, warnings, metadataKey } = await this.getArgs({ ...options });
580
- const transformedBody = this.transformRequestBody(args);
581
- const body = JSON.stringify(transformedBody);
582
- const {
583
- responseHeaders,
584
- value: responseBody,
585
- rawValue: rawResponse
586
- } = await postJsonToApi({
587
- url: this.config.url({
588
- path: "/chat/completions",
589
- modelId: this.modelId
590
- }),
591
- headers: combineHeaders(this.config.headers(), options.headers),
592
- body: transformedBody,
593
- failedResponseHandler: this.failedResponseHandler,
594
- successfulResponseHandler: createJsonResponseHandler(
595
- OpenAICompatibleChatResponseSchema
596
- ),
597
- abortSignal: options.abortSignal,
598
- fetch: this.config.fetch
599
- });
600
- const choice = responseBody.choices[0];
601
- const content = [];
602
- const text = choice.message.content;
603
- if (text != null && text.length > 0) {
604
- content.push({ type: "text", text });
605
- }
606
- const reasoning = (_a = choice.message.reasoning_content) != null ? _a : choice.message.reasoning;
607
- if (reasoning != null && reasoning.length > 0) {
608
- content.push({
609
- type: "reasoning",
610
- text: reasoning
611
- });
612
- }
613
- if (choice.message.tool_calls != null) {
614
- for (const toolCall of choice.message.tool_calls) {
615
- const thoughtSignature = (_c = (_b = toolCall.extra_content) == null ? void 0 : _b.google) == null ? void 0 : _c.thought_signature;
616
- content.push({
617
- type: "tool-call",
618
- toolCallId: (_d = toolCall.id) != null ? _d : generateId(),
619
- toolName: toolCall.function.name,
620
- input: toolCall.function.arguments,
621
- ...thoughtSignature ? {
622
- providerMetadata: {
623
- [metadataKey]: { thoughtSignature }
624
- }
625
- } : {}
626
- });
627
- }
628
- }
629
- const providerMetadata = {
630
- [metadataKey]: {},
631
- ...await ((_f = (_e = this.config.metadataExtractor) == null ? void 0 : _e.extractMetadata) == null ? void 0 : _f.call(_e, {
632
- parsedBody: rawResponse
633
- }))
634
- };
635
- const completionTokenDetails = (_g = responseBody.usage) == null ? void 0 : _g.completion_tokens_details;
636
- if ((completionTokenDetails == null ? void 0 : completionTokenDetails.accepted_prediction_tokens) != null) {
637
- providerMetadata[metadataKey].acceptedPredictionTokens = completionTokenDetails == null ? void 0 : completionTokenDetails.accepted_prediction_tokens;
638
- }
639
- if ((completionTokenDetails == null ? void 0 : completionTokenDetails.rejected_prediction_tokens) != null) {
640
- providerMetadata[metadataKey].rejectedPredictionTokens = completionTokenDetails == null ? void 0 : completionTokenDetails.rejected_prediction_tokens;
641
- }
642
- return {
643
- content,
644
- finishReason: {
645
- unified: mapOpenAICompatibleFinishReason(choice.finish_reason),
646
- raw: (_h = choice.finish_reason) != null ? _h : void 0
647
- },
648
- usage: convertOpenAICompatibleChatUsage(responseBody.usage),
649
- providerMetadata,
650
- request: { body },
651
- response: {
652
- ...getResponseMetadata(responseBody),
653
- headers: responseHeaders,
654
- body: rawResponse
655
- },
656
- warnings
657
- };
658
- }
659
- async doStream(options) {
660
- var _a;
661
- const { args, warnings, metadataKey } = await this.getArgs({
662
- ...options
663
- });
664
- const body = this.transformRequestBody({
665
- ...args,
666
- stream: true,
667
- // only include stream_options when in strict compatibility mode:
668
- stream_options: this.config.includeUsage ? { include_usage: true } : void 0
669
- });
670
- const metadataExtractor = (_a = this.config.metadataExtractor) == null ? void 0 : _a.createStreamExtractor();
671
- const { responseHeaders, value: response } = await postJsonToApi({
672
- url: this.config.url({
673
- path: "/chat/completions",
674
- modelId: this.modelId
675
- }),
676
- headers: combineHeaders(this.config.headers(), options.headers),
677
- body,
678
- failedResponseHandler: this.failedResponseHandler,
679
- successfulResponseHandler: createEventSourceResponseHandler(
680
- this.chunkSchema
681
- ),
682
- abortSignal: options.abortSignal,
683
- fetch: this.config.fetch
684
- });
685
- const toolCalls = [];
686
- let finishReason = {
687
- unified: "other",
688
- raw: void 0
689
- };
690
- let usage = void 0;
691
- let isFirstChunk = true;
692
- const providerOptionsName = metadataKey;
693
- let isActiveReasoning = false;
694
- let isActiveText = false;
695
- return {
696
- stream: response.pipeThrough(
697
- new TransformStream({
698
- start(controller) {
699
- controller.enqueue({ type: "stream-start", warnings });
700
- },
701
- transform(chunk, controller) {
702
- var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r;
703
- if (options.includeRawChunks) {
704
- controller.enqueue({ type: "raw", rawValue: chunk.rawValue });
705
- }
706
- if (!chunk.success) {
707
- finishReason = { unified: "error", raw: void 0 };
708
- controller.enqueue({ type: "error", error: chunk.error });
709
- return;
710
- }
711
- metadataExtractor == null ? void 0 : metadataExtractor.processChunk(chunk.rawValue);
712
- if ("error" in chunk.value) {
713
- finishReason = { unified: "error", raw: void 0 };
714
- controller.enqueue({
715
- type: "error",
716
- error: chunk.value.error.message
717
- });
718
- return;
719
- }
720
- const value = chunk.value;
721
- if (isFirstChunk) {
722
- isFirstChunk = false;
723
- controller.enqueue({
724
- type: "response-metadata",
725
- ...getResponseMetadata(value)
726
- });
727
- }
728
- if (value.usage != null) {
729
- usage = value.usage;
730
- }
731
- const choice = value.choices[0];
732
- if ((choice == null ? void 0 : choice.finish_reason) != null) {
733
- finishReason = {
734
- unified: mapOpenAICompatibleFinishReason(choice.finish_reason),
735
- raw: (_a2 = choice.finish_reason) != null ? _a2 : void 0
736
- };
737
- }
738
- if ((choice == null ? void 0 : choice.delta) == null) {
739
- return;
740
- }
741
- const delta = choice.delta;
742
- const reasoningContent = (_b = delta.reasoning_content) != null ? _b : delta.reasoning;
743
- if (reasoningContent) {
744
- if (!isActiveReasoning) {
745
- controller.enqueue({
746
- type: "reasoning-start",
747
- id: "reasoning-0"
748
- });
749
- isActiveReasoning = true;
750
- }
751
- controller.enqueue({
752
- type: "reasoning-delta",
753
- id: "reasoning-0",
754
- delta: reasoningContent
755
- });
756
- }
757
- if (delta.content) {
758
- if (isActiveReasoning) {
759
- controller.enqueue({
760
- type: "reasoning-end",
761
- id: "reasoning-0"
762
- });
763
- isActiveReasoning = false;
764
- }
765
- if (!isActiveText) {
766
- controller.enqueue({ type: "text-start", id: "txt-0" });
767
- isActiveText = true;
768
- }
769
- controller.enqueue({
770
- type: "text-delta",
771
- id: "txt-0",
772
- delta: delta.content
773
- });
774
- }
775
- if (delta.tool_calls != null) {
776
- if (isActiveReasoning) {
777
- controller.enqueue({
778
- type: "reasoning-end",
779
- id: "reasoning-0"
780
- });
781
- isActiveReasoning = false;
782
- }
783
- for (const toolCallDelta of delta.tool_calls) {
784
- const index = (_c = toolCallDelta.index) != null ? _c : toolCalls.length;
785
- if (toolCalls[index] == null) {
786
- if (toolCallDelta.id == null) {
787
- throw new InvalidResponseDataError({
788
- data: toolCallDelta,
789
- message: `Expected 'id' to be a string.`
790
- });
791
- }
792
- if (((_d = toolCallDelta.function) == null ? void 0 : _d.name) == null) {
793
- throw new InvalidResponseDataError({
794
- data: toolCallDelta,
795
- message: `Expected 'function.name' to be a string.`
796
- });
797
- }
798
- controller.enqueue({
799
- type: "tool-input-start",
800
- id: toolCallDelta.id,
801
- toolName: toolCallDelta.function.name
802
- });
803
- toolCalls[index] = {
804
- id: toolCallDelta.id,
805
- type: "function",
806
- function: {
807
- name: toolCallDelta.function.name,
808
- arguments: (_e = toolCallDelta.function.arguments) != null ? _e : ""
809
- },
810
- hasFinished: false,
811
- thoughtSignature: (_h = (_g = (_f = toolCallDelta.extra_content) == null ? void 0 : _f.google) == null ? void 0 : _g.thought_signature) != null ? _h : void 0
812
- };
813
- const toolCall2 = toolCalls[index];
814
- if (((_i = toolCall2.function) == null ? void 0 : _i.name) != null && ((_j = toolCall2.function) == null ? void 0 : _j.arguments) != null) {
815
- if (toolCall2.function.arguments.length > 0) {
816
- controller.enqueue({
817
- type: "tool-input-delta",
818
- id: toolCall2.id,
819
- delta: toolCall2.function.arguments
820
- });
821
- }
822
- if (isParsableJson(toolCall2.function.arguments)) {
823
- controller.enqueue({
824
- type: "tool-input-end",
825
- id: toolCall2.id
826
- });
827
- controller.enqueue({
828
- type: "tool-call",
829
- toolCallId: (_k = toolCall2.id) != null ? _k : generateId(),
830
- toolName: toolCall2.function.name,
831
- input: toolCall2.function.arguments,
832
- ...toolCall2.thoughtSignature ? {
833
- providerMetadata: {
834
- [providerOptionsName]: {
835
- thoughtSignature: toolCall2.thoughtSignature
836
- }
837
- }
838
- } : {}
839
- });
840
- toolCall2.hasFinished = true;
841
- }
842
- }
843
- continue;
844
- }
845
- const toolCall = toolCalls[index];
846
- if (toolCall.hasFinished) {
847
- continue;
848
- }
849
- if (((_l = toolCallDelta.function) == null ? void 0 : _l.arguments) != null) {
850
- toolCall.function.arguments += (_n = (_m = toolCallDelta.function) == null ? void 0 : _m.arguments) != null ? _n : "";
851
- }
852
- controller.enqueue({
853
- type: "tool-input-delta",
854
- id: toolCall.id,
855
- delta: (_o = toolCallDelta.function.arguments) != null ? _o : ""
856
- });
857
- if (((_p = toolCall.function) == null ? void 0 : _p.name) != null && ((_q = toolCall.function) == null ? void 0 : _q.arguments) != null && isParsableJson(toolCall.function.arguments)) {
858
- controller.enqueue({
859
- type: "tool-input-end",
860
- id: toolCall.id
861
- });
862
- controller.enqueue({
863
- type: "tool-call",
864
- toolCallId: (_r = toolCall.id) != null ? _r : generateId(),
865
- toolName: toolCall.function.name,
866
- input: toolCall.function.arguments,
867
- ...toolCall.thoughtSignature ? {
868
- providerMetadata: {
869
- [providerOptionsName]: {
870
- thoughtSignature: toolCall.thoughtSignature
871
- }
872
- }
873
- } : {}
874
- });
875
- toolCall.hasFinished = true;
876
- }
877
- }
878
- }
879
- },
880
- flush(controller) {
881
- var _a2, _b, _c, _d, _e;
882
- if (isActiveReasoning) {
883
- controller.enqueue({ type: "reasoning-end", id: "reasoning-0" });
884
- }
885
- if (isActiveText) {
886
- controller.enqueue({ type: "text-end", id: "txt-0" });
887
- }
888
- for (const toolCall of toolCalls.filter(
889
- (toolCall2) => !toolCall2.hasFinished
890
- )) {
891
- controller.enqueue({
892
- type: "tool-input-end",
893
- id: toolCall.id
894
- });
895
- controller.enqueue({
896
- type: "tool-call",
897
- toolCallId: (_a2 = toolCall.id) != null ? _a2 : generateId(),
898
- toolName: toolCall.function.name,
899
- input: toolCall.function.arguments,
900
- ...toolCall.thoughtSignature ? {
901
- providerMetadata: {
902
- [providerOptionsName]: {
903
- thoughtSignature: toolCall.thoughtSignature
904
- }
905
- }
906
- } : {}
907
- });
908
- }
909
- const providerMetadata = {
910
- [providerOptionsName]: {},
911
- ...metadataExtractor == null ? void 0 : metadataExtractor.buildMetadata()
912
- };
913
- if (((_b = usage == null ? void 0 : usage.completion_tokens_details) == null ? void 0 : _b.accepted_prediction_tokens) != null) {
914
- providerMetadata[providerOptionsName].acceptedPredictionTokens = (_c = usage == null ? void 0 : usage.completion_tokens_details) == null ? void 0 : _c.accepted_prediction_tokens;
915
- }
916
- if (((_d = usage == null ? void 0 : usage.completion_tokens_details) == null ? void 0 : _d.rejected_prediction_tokens) != null) {
917
- providerMetadata[providerOptionsName].rejectedPredictionTokens = (_e = usage == null ? void 0 : usage.completion_tokens_details) == null ? void 0 : _e.rejected_prediction_tokens;
918
- }
919
- controller.enqueue({
920
- type: "finish",
921
- finishReason,
922
- usage: convertOpenAICompatibleChatUsage(usage),
923
- providerMetadata
924
- });
925
- }
926
- })
927
- ),
928
- request: { body },
929
- response: { headers: responseHeaders }
930
- };
931
- }
932
- };
933
- var openaiCompatibleTokenUsageSchema = z3.looseObject({
934
- prompt_tokens: z3.number().nullish(),
935
- completion_tokens: z3.number().nullish(),
936
- total_tokens: z3.number().nullish(),
937
- prompt_tokens_details: z3.object({
938
- cached_tokens: z3.number().nullish()
939
- }).nullish(),
940
- completion_tokens_details: z3.object({
941
- reasoning_tokens: z3.number().nullish(),
942
- accepted_prediction_tokens: z3.number().nullish(),
943
- rejected_prediction_tokens: z3.number().nullish()
944
- }).nullish()
945
- }).nullish();
946
- var OpenAICompatibleChatResponseSchema = z3.looseObject({
947
- id: z3.string().nullish(),
948
- created: z3.number().nullish(),
949
- model: z3.string().nullish(),
950
- choices: z3.array(
951
- z3.object({
952
- message: z3.object({
953
- role: z3.literal("assistant").nullish(),
954
- content: z3.string().nullish(),
955
- reasoning_content: z3.string().nullish(),
956
- reasoning: z3.string().nullish(),
957
- tool_calls: z3.array(
958
- z3.object({
959
- id: z3.string().nullish(),
960
- function: z3.object({
961
- name: z3.string(),
962
- arguments: z3.string()
963
- }),
964
- // Support for Google Gemini thought signatures via OpenAI compatibility
965
- extra_content: z3.object({
966
- google: z3.object({
967
- thought_signature: z3.string().nullish()
968
- }).nullish()
969
- }).nullish()
970
- })
971
- ).nullish()
972
- }),
973
- finish_reason: z3.string().nullish()
974
- })
975
- ),
976
- usage: openaiCompatibleTokenUsageSchema
977
- });
978
- var chunkBaseSchema = z3.looseObject({
979
- id: z3.string().nullish(),
980
- created: z3.number().nullish(),
981
- model: z3.string().nullish(),
982
- choices: z3.array(
983
- z3.object({
984
- delta: z3.object({
985
- role: z3.enum(["assistant"]).nullish(),
986
- content: z3.string().nullish(),
987
- // Most openai-compatible models set `reasoning_content`, but some
988
- // providers serving `gpt-oss` set `reasoning`. See #7866
989
- reasoning_content: z3.string().nullish(),
990
- reasoning: z3.string().nullish(),
991
- tool_calls: z3.array(
992
- z3.object({
993
- index: z3.number().nullish(),
994
- //google does not send index
995
- id: z3.string().nullish(),
996
- function: z3.object({
997
- name: z3.string().nullish(),
998
- arguments: z3.string().nullish()
999
- }),
1000
- // Support for Google Gemini thought signatures via OpenAI compatibility
1001
- extra_content: z3.object({
1002
- google: z3.object({
1003
- thought_signature: z3.string().nullish()
1004
- }).nullish()
1005
- }).nullish()
1006
- })
1007
- ).nullish()
1008
- }).nullish(),
1009
- finish_reason: z3.string().nullish()
1010
- })
1011
- ),
1012
- usage: openaiCompatibleTokenUsageSchema
1013
- });
1014
- var createOpenAICompatibleChatChunkSchema = (errorSchema) => z3.union([chunkBaseSchema, errorSchema]);
1015
-
1016
- // src/completion/openai-compatible-completion-language-model.ts
1017
- import {
1018
- combineHeaders as combineHeaders2,
1019
- createEventSourceResponseHandler as createEventSourceResponseHandler2,
1020
- createJsonErrorResponseHandler as createJsonErrorResponseHandler2,
1021
- createJsonResponseHandler as createJsonResponseHandler2,
1022
- parseProviderOptions as parseProviderOptions2,
1023
- postJsonToApi as postJsonToApi2
1024
- } from "@ai-sdk/provider-utils";
1025
- import { z as z5 } from "zod/v4";
1026
-
1027
- // src/completion/convert-openai-compatible-completion-usage.ts
1028
- function convertOpenAICompatibleCompletionUsage(usage) {
1029
- var _a, _b;
1030
- if (usage == null) {
1031
- return {
1032
- inputTokens: {
1033
- total: void 0,
1034
- noCache: void 0,
1035
- cacheRead: void 0,
1036
- cacheWrite: void 0
1037
- },
1038
- outputTokens: {
1039
- total: void 0,
1040
- text: void 0,
1041
- reasoning: void 0
1042
- },
1043
- raw: void 0
1044
- };
1045
- }
1046
- const promptTokens = (_a = usage.prompt_tokens) != null ? _a : 0;
1047
- const completionTokens = (_b = usage.completion_tokens) != null ? _b : 0;
1048
- return {
1049
- inputTokens: {
1050
- total: promptTokens,
1051
- noCache: promptTokens,
1052
- cacheRead: void 0,
1053
- cacheWrite: void 0
1054
- },
1055
- outputTokens: {
1056
- total: completionTokens,
1057
- text: completionTokens,
1058
- reasoning: void 0
1059
- },
1060
- raw: usage
1061
- };
1062
- }
1063
-
1064
- // src/completion/convert-to-openai-compatible-completion-prompt.ts
1065
- import {
1066
- InvalidPromptError,
1067
- UnsupportedFunctionalityError as UnsupportedFunctionalityError3
1068
- } from "@ai-sdk/provider";
1069
- function convertToOpenAICompatibleCompletionPrompt({
1070
- prompt,
1071
- user = "user",
1072
- assistant = "assistant"
1073
- }) {
1074
- let text = "";
1075
- if (prompt[0].role === "system") {
1076
- text += `${prompt[0].content}
1077
-
1078
- `;
1079
- prompt = prompt.slice(1);
1080
- }
1081
- for (const { role, content } of prompt) {
1082
- switch (role) {
1083
- case "system": {
1084
- throw new InvalidPromptError({
1085
- message: "Unexpected system message in prompt: ${content}",
1086
- prompt
1087
- });
1088
- }
1089
- case "user": {
1090
- const userMessage = content.map((part) => {
1091
- switch (part.type) {
1092
- case "text": {
1093
- return part.text;
1094
- }
1095
- }
1096
- }).filter(Boolean).join("");
1097
- text += `${user}:
1098
- ${userMessage}
1099
-
1100
- `;
1101
- break;
1102
- }
1103
- case "assistant": {
1104
- const assistantMessage = content.map((part) => {
1105
- switch (part.type) {
1106
- case "text": {
1107
- return part.text;
1108
- }
1109
- case "tool-call": {
1110
- throw new UnsupportedFunctionalityError3({
1111
- functionality: "tool-call messages"
1112
- });
1113
- }
1114
- }
1115
- }).join("");
1116
- text += `${assistant}:
1117
- ${assistantMessage}
1118
-
1119
- `;
1120
- break;
1121
- }
1122
- case "tool": {
1123
- throw new UnsupportedFunctionalityError3({
1124
- functionality: "tool messages"
1125
- });
1126
- }
1127
- default: {
1128
- const _exhaustiveCheck = role;
1129
- throw new Error(`Unsupported role: ${_exhaustiveCheck}`);
1130
- }
1131
- }
1132
- }
1133
- text += `${assistant}:
1134
- `;
1135
- return {
1136
- prompt: text,
1137
- stopSequences: [`
1138
- ${user}:`]
1139
- };
1140
- }
1141
-
1142
- // src/completion/get-response-metadata.ts
1143
- function getResponseMetadata2({
1144
- id,
1145
- model,
1146
- created
1147
- }) {
1148
- return {
1149
- id: id != null ? id : void 0,
1150
- modelId: model != null ? model : void 0,
1151
- timestamp: created != null ? new Date(created * 1e3) : void 0
1152
- };
1153
- }
1154
-
1155
- // src/completion/map-openai-compatible-finish-reason.ts
1156
- function mapOpenAICompatibleFinishReason2(finishReason) {
1157
- switch (finishReason) {
1158
- case "stop":
1159
- return "stop";
1160
- case "length":
1161
- return "length";
1162
- case "content_filter":
1163
- return "content-filter";
1164
- case "function_call":
1165
- case "tool_calls":
1166
- return "tool-calls";
1167
- default:
1168
- return "other";
1169
- }
1170
- }
1171
-
1172
- // src/completion/openai-compatible-completion-options.ts
1173
- import { z as z4 } from "zod/v4";
1174
- var openaiCompatibleLanguageModelCompletionOptions = z4.object({
1175
- /**
1176
- * Echo back the prompt in addition to the completion.
1177
- */
1178
- echo: z4.boolean().optional(),
1179
- /**
1180
- * Modify the likelihood of specified tokens appearing in the completion.
1181
- *
1182
- * Accepts a JSON object that maps tokens (specified by their token ID in
1183
- * the GPT tokenizer) to an associated bias value from -100 to 100.
1184
- */
1185
- logitBias: z4.record(z4.string(), z4.number()).optional(),
1186
- /**
1187
- * The suffix that comes after a completion of inserted text.
1188
- */
1189
- suffix: z4.string().optional(),
1190
- /**
1191
- * A unique identifier representing your end-user, which can help providers to
1192
- * monitor and detect abuse.
1193
- */
1194
- user: z4.string().optional()
1195
- });
1196
-
1197
- // src/completion/openai-compatible-completion-language-model.ts
1198
- var OpenAICompatibleCompletionLanguageModel = class {
1199
- // type inferred via constructor
1200
- constructor(modelId, config) {
1201
- this.specificationVersion = "v4";
1202
- var _a;
1203
- this.modelId = modelId;
1204
- this.config = config;
1205
- const errorStructure = (_a = config.errorStructure) != null ? _a : defaultOpenAICompatibleErrorStructure;
1206
- this.chunkSchema = createOpenAICompatibleCompletionChunkSchema(
1207
- errorStructure.errorSchema
1208
- );
1209
- this.failedResponseHandler = createJsonErrorResponseHandler2(errorStructure);
1210
- }
1211
- get provider() {
1212
- return this.config.provider;
1213
- }
1214
- get providerOptionsName() {
1215
- return this.config.provider.split(".")[0].trim();
1216
- }
1217
- get supportedUrls() {
1218
- var _a, _b, _c;
1219
- return (_c = (_b = (_a = this.config).supportedUrls) == null ? void 0 : _b.call(_a)) != null ? _c : {};
1220
- }
1221
- async getArgs({
1222
- prompt,
1223
- maxOutputTokens,
1224
- temperature,
1225
- topP,
1226
- topK,
1227
- frequencyPenalty,
1228
- presencePenalty,
1229
- stopSequences: userStopSequences,
1230
- responseFormat,
1231
- seed,
1232
- providerOptions,
1233
- tools,
1234
- toolChoice
1235
- }) {
1236
- var _a, _b;
1237
- const warnings = [];
1238
- warnIfDeprecatedProviderOptionsKey({
1239
- rawName: this.providerOptionsName,
1240
- providerOptions,
1241
- warnings
1242
- });
1243
- const completionOptions = Object.assign(
1244
- (_a = await parseProviderOptions2({
1245
- provider: this.providerOptionsName,
1246
- providerOptions,
1247
- schema: openaiCompatibleLanguageModelCompletionOptions
1248
- })) != null ? _a : {},
1249
- (_b = await parseProviderOptions2({
1250
- provider: toCamelCase(this.providerOptionsName),
1251
- providerOptions,
1252
- schema: openaiCompatibleLanguageModelCompletionOptions
1253
- })) != null ? _b : {}
1254
- );
1255
- if (topK != null) {
1256
- warnings.push({ type: "unsupported", feature: "topK" });
1257
- }
1258
- if (tools == null ? void 0 : tools.length) {
1259
- warnings.push({ type: "unsupported", feature: "tools" });
1260
- }
1261
- if (toolChoice != null) {
1262
- warnings.push({ type: "unsupported", feature: "toolChoice" });
1263
- }
1264
- if (responseFormat != null && responseFormat.type !== "text") {
1265
- warnings.push({
1266
- type: "unsupported",
1267
- feature: "responseFormat",
1268
- details: "JSON response format is not supported."
1269
- });
1270
- }
1271
- const { prompt: completionPrompt, stopSequences } = convertToOpenAICompatibleCompletionPrompt({ prompt });
1272
- const stop = [...stopSequences != null ? stopSequences : [], ...userStopSequences != null ? userStopSequences : []];
1273
- return {
1274
- args: {
1275
- // model id:
1276
- model: this.modelId,
1277
- // model specific settings:
1278
- echo: completionOptions.echo,
1279
- logit_bias: completionOptions.logitBias,
1280
- suffix: completionOptions.suffix,
1281
- user: completionOptions.user,
1282
- // standardized settings:
1283
- max_tokens: maxOutputTokens,
1284
- temperature,
1285
- top_p: topP,
1286
- frequency_penalty: frequencyPenalty,
1287
- presence_penalty: presencePenalty,
1288
- seed,
1289
- ...providerOptions == null ? void 0 : providerOptions[this.providerOptionsName],
1290
- ...providerOptions == null ? void 0 : providerOptions[toCamelCase(this.providerOptionsName)],
1291
- // prompt:
1292
- prompt: completionPrompt,
1293
- // stop sequences:
1294
- stop: stop.length > 0 ? stop : void 0
1295
- },
1296
- warnings
1297
- };
1298
- }
1299
- async doGenerate(options) {
1300
- const { args, warnings } = await this.getArgs(options);
1301
- const {
1302
- responseHeaders,
1303
- value: response,
1304
- rawValue: rawResponse
1305
- } = await postJsonToApi2({
1306
- url: this.config.url({
1307
- path: "/completions",
1308
- modelId: this.modelId
1309
- }),
1310
- headers: combineHeaders2(this.config.headers(), options.headers),
1311
- body: args,
1312
- failedResponseHandler: this.failedResponseHandler,
1313
- successfulResponseHandler: createJsonResponseHandler2(
1314
- openaiCompatibleCompletionResponseSchema
1315
- ),
1316
- abortSignal: options.abortSignal,
1317
- fetch: this.config.fetch
1318
- });
1319
- const choice = response.choices[0];
1320
- const content = [];
1321
- if (choice.text != null && choice.text.length > 0) {
1322
- content.push({ type: "text", text: choice.text });
1323
- }
1324
- return {
1325
- content,
1326
- usage: convertOpenAICompatibleCompletionUsage(response.usage),
1327
- finishReason: {
1328
- unified: mapOpenAICompatibleFinishReason2(choice.finish_reason),
1329
- raw: choice.finish_reason
1330
- },
1331
- request: { body: args },
1332
- response: {
1333
- ...getResponseMetadata2(response),
1334
- headers: responseHeaders,
1335
- body: rawResponse
1336
- },
1337
- warnings
1338
- };
1339
- }
1340
- async doStream(options) {
1341
- const { args, warnings } = await this.getArgs(options);
1342
- const body = {
1343
- ...args,
1344
- stream: true,
1345
- // only include stream_options when in strict compatibility mode:
1346
- stream_options: this.config.includeUsage ? { include_usage: true } : void 0
1347
- };
1348
- const { responseHeaders, value: response } = await postJsonToApi2({
1349
- url: this.config.url({
1350
- path: "/completions",
1351
- modelId: this.modelId
1352
- }),
1353
- headers: combineHeaders2(this.config.headers(), options.headers),
1354
- body,
1355
- failedResponseHandler: this.failedResponseHandler,
1356
- successfulResponseHandler: createEventSourceResponseHandler2(
1357
- this.chunkSchema
1358
- ),
1359
- abortSignal: options.abortSignal,
1360
- fetch: this.config.fetch
1361
- });
1362
- let finishReason = {
1363
- unified: "other",
1364
- raw: void 0
1365
- };
1366
- let usage = void 0;
1367
- let isFirstChunk = true;
1368
- return {
1369
- stream: response.pipeThrough(
1370
- new TransformStream({
1371
- start(controller) {
1372
- controller.enqueue({ type: "stream-start", warnings });
1373
- },
1374
- transform(chunk, controller) {
1375
- var _a;
1376
- if (options.includeRawChunks) {
1377
- controller.enqueue({ type: "raw", rawValue: chunk.rawValue });
1378
- }
1379
- if (!chunk.success) {
1380
- finishReason = { unified: "error", raw: void 0 };
1381
- controller.enqueue({ type: "error", error: chunk.error });
1382
- return;
1383
- }
1384
- const value = chunk.value;
1385
- if ("error" in value) {
1386
- finishReason = { unified: "error", raw: void 0 };
1387
- controller.enqueue({ type: "error", error: value.error });
1388
- return;
1389
- }
1390
- if (isFirstChunk) {
1391
- isFirstChunk = false;
1392
- controller.enqueue({
1393
- type: "response-metadata",
1394
- ...getResponseMetadata2(value)
1395
- });
1396
- controller.enqueue({
1397
- type: "text-start",
1398
- id: "0"
1399
- });
1400
- }
1401
- if (value.usage != null) {
1402
- usage = value.usage;
1403
- }
1404
- const choice = value.choices[0];
1405
- if ((choice == null ? void 0 : choice.finish_reason) != null) {
1406
- finishReason = {
1407
- unified: mapOpenAICompatibleFinishReason2(choice.finish_reason),
1408
- raw: (_a = choice.finish_reason) != null ? _a : void 0
1409
- };
1410
- }
1411
- if ((choice == null ? void 0 : choice.text) != null) {
1412
- controller.enqueue({
1413
- type: "text-delta",
1414
- id: "0",
1415
- delta: choice.text
1416
- });
1417
- }
1418
- },
1419
- flush(controller) {
1420
- if (!isFirstChunk) {
1421
- controller.enqueue({ type: "text-end", id: "0" });
1422
- }
1423
- controller.enqueue({
1424
- type: "finish",
1425
- finishReason,
1426
- usage: convertOpenAICompatibleCompletionUsage(usage)
1427
- });
1428
- }
1429
- })
1430
- ),
1431
- request: { body },
1432
- response: { headers: responseHeaders }
1433
- };
1434
- }
1435
- };
1436
- var usageSchema = z5.object({
1437
- prompt_tokens: z5.number(),
1438
- completion_tokens: z5.number(),
1439
- total_tokens: z5.number()
1440
- });
1441
- var openaiCompatibleCompletionResponseSchema = z5.object({
1442
- id: z5.string().nullish(),
1443
- created: z5.number().nullish(),
1444
- model: z5.string().nullish(),
1445
- choices: z5.array(
1446
- z5.object({
1447
- text: z5.string(),
1448
- finish_reason: z5.string()
1449
- })
1450
- ),
1451
- usage: usageSchema.nullish()
1452
- });
1453
- var createOpenAICompatibleCompletionChunkSchema = (errorSchema) => z5.union([
1454
- z5.object({
1455
- id: z5.string().nullish(),
1456
- created: z5.number().nullish(),
1457
- model: z5.string().nullish(),
1458
- choices: z5.array(
1459
- z5.object({
1460
- text: z5.string(),
1461
- finish_reason: z5.string().nullish(),
1462
- index: z5.number()
1463
- })
1464
- ),
1465
- usage: usageSchema.nullish()
1466
- }),
1467
- errorSchema
1468
- ]);
1469
-
1470
- // src/embedding/openai-compatible-embedding-model.ts
1471
- import {
1472
- TooManyEmbeddingValuesForCallError
1473
- } from "@ai-sdk/provider";
1474
- import {
1475
- combineHeaders as combineHeaders3,
1476
- createJsonErrorResponseHandler as createJsonErrorResponseHandler3,
1477
- createJsonResponseHandler as createJsonResponseHandler3,
1478
- parseProviderOptions as parseProviderOptions3,
1479
- postJsonToApi as postJsonToApi3
1480
- } from "@ai-sdk/provider-utils";
1481
- import { z as z7 } from "zod/v4";
1482
-
1483
- // src/embedding/openai-compatible-embedding-options.ts
1484
- import { z as z6 } from "zod/v4";
1485
- var openaiCompatibleEmbeddingModelOptions = z6.object({
1486
- /**
1487
- * The number of dimensions the resulting output embeddings should have.
1488
- * Only supported in text-embedding-3 and later models.
1489
- */
1490
- dimensions: z6.number().optional(),
1491
- /**
1492
- * A unique identifier representing your end-user, which can help providers to
1493
- * monitor and detect abuse.
1494
- */
1495
- user: z6.string().optional()
1496
- });
1497
-
1498
- // src/embedding/openai-compatible-embedding-model.ts
1499
- var OpenAICompatibleEmbeddingModel = class {
1500
- constructor(modelId, config) {
1501
- this.specificationVersion = "v4";
1502
- this.modelId = modelId;
1503
- this.config = config;
1504
- }
1505
- get provider() {
1506
- return this.config.provider;
1507
- }
1508
- get maxEmbeddingsPerCall() {
1509
- var _a;
1510
- return (_a = this.config.maxEmbeddingsPerCall) != null ? _a : 2048;
1511
- }
1512
- get supportsParallelCalls() {
1513
- var _a;
1514
- return (_a = this.config.supportsParallelCalls) != null ? _a : true;
1515
- }
1516
- get providerOptionsName() {
1517
- return this.config.provider.split(".")[0].trim();
1518
- }
1519
- async doEmbed({
1520
- values,
1521
- headers,
1522
- abortSignal,
1523
- providerOptions
1524
- }) {
1525
- var _a, _b, _c;
1526
- const warnings = [];
1527
- const deprecatedOptions = await parseProviderOptions3({
1528
- provider: "openai-compatible",
1529
- providerOptions,
1530
- schema: openaiCompatibleEmbeddingModelOptions
1531
- });
1532
- if (deprecatedOptions != null) {
1533
- warnings.push({
1534
- type: "deprecated",
1535
- setting: "providerOptions key 'openai-compatible'",
1536
- message: "Use 'openaiCompatible' instead."
1537
- });
1538
- }
1539
- warnIfDeprecatedProviderOptionsKey({
1540
- rawName: this.providerOptionsName,
1541
- providerOptions,
1542
- warnings
1543
- });
1544
- const compatibleOptions = Object.assign(
1545
- deprecatedOptions != null ? deprecatedOptions : {},
1546
- (_a = await parseProviderOptions3({
1547
- provider: "openaiCompatible",
1548
- providerOptions,
1549
- schema: openaiCompatibleEmbeddingModelOptions
1550
- })) != null ? _a : {},
1551
- (_b = await parseProviderOptions3({
1552
- provider: this.providerOptionsName,
1553
- providerOptions,
1554
- schema: openaiCompatibleEmbeddingModelOptions
1555
- })) != null ? _b : {}
1556
- );
1557
- if (values.length > this.maxEmbeddingsPerCall) {
1558
- throw new TooManyEmbeddingValuesForCallError({
1559
- provider: this.provider,
1560
- modelId: this.modelId,
1561
- maxEmbeddingsPerCall: this.maxEmbeddingsPerCall,
1562
- values
1563
- });
1564
- }
1565
- const {
1566
- responseHeaders,
1567
- value: response,
1568
- rawValue
1569
- } = await postJsonToApi3({
1570
- url: this.config.url({
1571
- path: "/embeddings",
1572
- modelId: this.modelId
1573
- }),
1574
- headers: combineHeaders3(this.config.headers(), headers),
1575
- body: {
1576
- model: this.modelId,
1577
- input: values,
1578
- encoding_format: "float",
1579
- dimensions: compatibleOptions.dimensions,
1580
- user: compatibleOptions.user
1581
- },
1582
- failedResponseHandler: createJsonErrorResponseHandler3(
1583
- (_c = this.config.errorStructure) != null ? _c : defaultOpenAICompatibleErrorStructure
1584
- ),
1585
- successfulResponseHandler: createJsonResponseHandler3(
1586
- openaiTextEmbeddingResponseSchema
1587
- ),
1588
- abortSignal,
1589
- fetch: this.config.fetch
1590
- });
1591
- return {
1592
- warnings,
1593
- embeddings: response.data.map((item) => item.embedding),
1594
- usage: response.usage ? { tokens: response.usage.prompt_tokens } : void 0,
1595
- providerMetadata: response.providerMetadata,
1596
- response: { headers: responseHeaders, body: rawValue }
1597
- };
1598
- }
1599
- };
1600
- var openaiTextEmbeddingResponseSchema = z7.object({
1601
- data: z7.array(z7.object({ embedding: z7.array(z7.number()) })),
1602
- usage: z7.object({ prompt_tokens: z7.number() }).nullish(),
1603
- providerMetadata: z7.record(z7.string(), z7.record(z7.string(), z7.any())).optional()
1604
- });
1605
-
1606
- // src/image/openai-compatible-image-model.ts
1607
- import {
1608
- combineHeaders as combineHeaders4,
1609
- convertBase64ToUint8Array as convertBase64ToUint8Array2,
1610
- convertToFormData,
1611
- createJsonErrorResponseHandler as createJsonErrorResponseHandler4,
1612
- createJsonResponseHandler as createJsonResponseHandler4,
1613
- downloadBlob,
1614
- postFormDataToApi,
1615
- postJsonToApi as postJsonToApi4
1616
- } from "@ai-sdk/provider-utils";
1617
- import { z as z8 } from "zod/v4";
1618
- var OpenAICompatibleImageModel = class {
1619
- constructor(modelId, config) {
1620
- this.modelId = modelId;
1621
- this.config = config;
1622
- this.specificationVersion = "v4";
1623
- this.maxImagesPerCall = 10;
1624
- }
1625
- get provider() {
1626
- return this.config.provider;
1627
- }
1628
- /**
1629
- * The provider options key used to extract provider-specific options.
1630
- */
1631
- get providerOptionsKey() {
1632
- return this.config.provider.split(".")[0].trim();
1633
- }
1634
- getArgs(providerOptions, warnings) {
1635
- warnIfDeprecatedProviderOptionsKey({
1636
- rawName: this.providerOptionsKey,
1637
- providerOptions,
1638
- warnings
1639
- });
1640
- return {
1641
- ...providerOptions[this.providerOptionsKey],
1642
- ...providerOptions[toCamelCase(this.providerOptionsKey)]
1643
- };
1644
- }
1645
- async doGenerate({
1646
- prompt,
1647
- n,
1648
- size,
1649
- aspectRatio,
1650
- seed,
1651
- providerOptions,
1652
- headers,
1653
- abortSignal,
1654
- files,
1655
- mask
1656
- }) {
1657
- var _a, _b, _c, _d, _e;
1658
- const warnings = [];
1659
- if (aspectRatio != null) {
1660
- warnings.push({
1661
- type: "unsupported",
1662
- feature: "aspectRatio",
1663
- details: "This model does not support aspect ratio. Use `size` instead."
1664
- });
1665
- }
1666
- if (seed != null) {
1667
- warnings.push({ type: "unsupported", feature: "seed" });
1668
- }
1669
- const currentDate = (_c = (_b = (_a = this.config._internal) == null ? void 0 : _a.currentDate) == null ? void 0 : _b.call(_a)) != null ? _c : /* @__PURE__ */ new Date();
1670
- const args = this.getArgs(providerOptions, warnings);
1671
- if (files != null && files.length > 0) {
1672
- const { value: response2, responseHeaders: responseHeaders2 } = await postFormDataToApi({
1673
- url: this.config.url({
1674
- path: "/images/edits",
1675
- modelId: this.modelId
1676
- }),
1677
- headers: combineHeaders4(this.config.headers(), headers),
1678
- formData: convertToFormData({
1679
- model: this.modelId,
1680
- prompt,
1681
- image: await Promise.all(files.map((file) => fileToBlob(file))),
1682
- mask: mask != null ? await fileToBlob(mask) : void 0,
1683
- n,
1684
- size,
1685
- ...args
1686
- }),
1687
- failedResponseHandler: createJsonErrorResponseHandler4(
1688
- (_d = this.config.errorStructure) != null ? _d : defaultOpenAICompatibleErrorStructure
1689
- ),
1690
- successfulResponseHandler: createJsonResponseHandler4(
1691
- openaiCompatibleImageResponseSchema
1692
- ),
1693
- abortSignal,
1694
- fetch: this.config.fetch
1695
- });
1696
- return {
1697
- images: response2.data.map((item) => item.b64_json),
1698
- warnings,
1699
- response: {
1700
- timestamp: currentDate,
1701
- modelId: this.modelId,
1702
- headers: responseHeaders2
1703
- }
1704
- };
1705
- }
1706
- const { value: response, responseHeaders } = await postJsonToApi4({
1707
- url: this.config.url({
1708
- path: "/images/generations",
1709
- modelId: this.modelId
1710
- }),
1711
- headers: combineHeaders4(this.config.headers(), headers),
1712
- body: {
1713
- model: this.modelId,
1714
- prompt,
1715
- n,
1716
- size,
1717
- ...args,
1718
- response_format: "b64_json"
1719
- },
1720
- failedResponseHandler: createJsonErrorResponseHandler4(
1721
- (_e = this.config.errorStructure) != null ? _e : defaultOpenAICompatibleErrorStructure
1722
- ),
1723
- successfulResponseHandler: createJsonResponseHandler4(
1724
- openaiCompatibleImageResponseSchema
1725
- ),
1726
- abortSignal,
1727
- fetch: this.config.fetch
1728
- });
1729
- return {
1730
- images: response.data.map((item) => item.b64_json),
1731
- warnings,
1732
- response: {
1733
- timestamp: currentDate,
1734
- modelId: this.modelId,
1735
- headers: responseHeaders
1736
- }
1737
- };
1738
- }
1739
- };
1740
- var openaiCompatibleImageResponseSchema = z8.object({
1741
- data: z8.array(z8.object({ b64_json: z8.string() }))
1742
- });
1743
- async function fileToBlob(file) {
1744
- if (file.type === "url") {
1745
- return downloadBlob(file.url);
1746
- }
1747
- const data = file.data instanceof Uint8Array ? file.data : convertBase64ToUint8Array2(file.data);
1748
- return new Blob([data], { type: file.mediaType });
1749
- }
1750
-
1751
- // src/openai-compatible-provider.ts
1752
- import {
1753
- withoutTrailingSlash,
1754
- withUserAgentSuffix
1755
- } from "@ai-sdk/provider-utils";
1756
-
1757
- // src/version.ts
1758
- var VERSION = true ? "3.0.0-beta.22" : "0.0.0-test";
1759
-
1760
- // src/openai-compatible-provider.ts
1761
- function createOpenAICompatible(options) {
1762
- const baseURL = withoutTrailingSlash(options.baseURL);
1763
- const providerName = options.name;
1764
- const headers = {
1765
- ...options.apiKey && { Authorization: `Bearer ${options.apiKey}` },
1766
- ...options.headers
1767
- };
1768
- const getHeaders = () => withUserAgentSuffix(headers, `ai-sdk/openai-compatible/${VERSION}`);
1769
- const getCommonModelConfig = (modelType) => ({
1770
- provider: `${providerName}.${modelType}`,
1771
- url: ({ path }) => {
1772
- const url = new URL(`${baseURL}${path}`);
1773
- if (options.queryParams) {
1774
- url.search = new URLSearchParams(options.queryParams).toString();
1775
- }
1776
- return url.toString();
1777
- },
1778
- headers: getHeaders,
1779
- fetch: options.fetch
1780
- });
1781
- const createLanguageModel = (modelId) => createChatModel(modelId);
1782
- const createChatModel = (modelId) => new OpenAICompatibleChatLanguageModel(modelId, {
1783
- ...getCommonModelConfig("chat"),
1784
- includeUsage: options.includeUsage,
1785
- supportsStructuredOutputs: options.supportsStructuredOutputs,
1786
- transformRequestBody: options.transformRequestBody,
1787
- metadataExtractor: options.metadataExtractor
1788
- });
1789
- const createCompletionModel = (modelId) => new OpenAICompatibleCompletionLanguageModel(modelId, {
1790
- ...getCommonModelConfig("completion"),
1791
- includeUsage: options.includeUsage
1792
- });
1793
- const createEmbeddingModel = (modelId) => new OpenAICompatibleEmbeddingModel(modelId, {
1794
- ...getCommonModelConfig("embedding")
1795
- });
1796
- const createImageModel = (modelId) => new OpenAICompatibleImageModel(modelId, getCommonModelConfig("image"));
1797
- const provider = (modelId) => createLanguageModel(modelId);
1798
- provider.specificationVersion = "v4";
1799
- provider.languageModel = createLanguageModel;
1800
- provider.chatModel = createChatModel;
1801
- provider.completionModel = createCompletionModel;
1802
- provider.embeddingModel = createEmbeddingModel;
1803
- provider.textEmbeddingModel = createEmbeddingModel;
1804
- provider.imageModel = createImageModel;
1805
- return provider;
1806
- }
1807
- export {
1808
- OpenAICompatibleChatLanguageModel,
1809
- OpenAICompatibleCompletionLanguageModel,
1810
- OpenAICompatibleEmbeddingModel,
1811
- OpenAICompatibleImageModel,
1812
- VERSION,
1813
- createOpenAICompatible
1814
- };
1815
- //# sourceMappingURL=index.mjs.map