@ai-sdk/openai-compatible 3.0.0-beta.16 → 3.0.0-beta.17
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/CHANGELOG.md +6 -0
- package/dist/index.js +53 -23
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +53 -23
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/chat/openai-compatible-chat-language-model.ts +25 -10
- package/src/completion/openai-compatible-completion-language-model.ts +11 -3
- package/src/image/openai-compatible-image-model.ts +1 -4
- package/src/utils/to-camel-case.ts +19 -0
|
@@ -26,6 +26,7 @@ import {
|
|
|
26
26
|
ResponseHandler,
|
|
27
27
|
} from '@ai-sdk/provider-utils';
|
|
28
28
|
import { z } from 'zod/v4';
|
|
29
|
+
import { resolveProviderOptionsKey, toCamelCase } from '../utils/to-camel-case';
|
|
29
30
|
import {
|
|
30
31
|
defaultOpenAICompatibleErrorStructure,
|
|
31
32
|
ProviderErrorStructure,
|
|
@@ -156,6 +157,11 @@ export class OpenAICompatibleChatLanguageModel implements LanguageModelV4 {
|
|
|
156
157
|
providerOptions,
|
|
157
158
|
schema: openaiCompatibleLanguageModelChatOptions,
|
|
158
159
|
})) ?? {},
|
|
160
|
+
(await parseProviderOptions({
|
|
161
|
+
provider: toCamelCase(this.providerOptionsName),
|
|
162
|
+
providerOptions,
|
|
163
|
+
schema: openaiCompatibleLanguageModelChatOptions,
|
|
164
|
+
})) ?? {},
|
|
159
165
|
);
|
|
160
166
|
|
|
161
167
|
const strictJsonSchema = compatibleOptions?.strictJsonSchema ?? true;
|
|
@@ -186,7 +192,13 @@ export class OpenAICompatibleChatLanguageModel implements LanguageModelV4 {
|
|
|
186
192
|
toolChoice,
|
|
187
193
|
});
|
|
188
194
|
|
|
195
|
+
const metadataKey = resolveProviderOptionsKey(
|
|
196
|
+
this.providerOptionsName,
|
|
197
|
+
providerOptions,
|
|
198
|
+
);
|
|
199
|
+
|
|
189
200
|
return {
|
|
201
|
+
metadataKey,
|
|
190
202
|
args: {
|
|
191
203
|
// model id:
|
|
192
204
|
model: this.modelId,
|
|
@@ -219,9 +231,10 @@ export class OpenAICompatibleChatLanguageModel implements LanguageModelV4 {
|
|
|
219
231
|
stop: stopSequences,
|
|
220
232
|
seed,
|
|
221
233
|
...Object.fromEntries(
|
|
222
|
-
Object.entries(
|
|
223
|
-
providerOptions?.[this.providerOptionsName]
|
|
224
|
-
|
|
234
|
+
Object.entries({
|
|
235
|
+
...providerOptions?.[this.providerOptionsName],
|
|
236
|
+
...providerOptions?.[toCamelCase(this.providerOptionsName)],
|
|
237
|
+
}).filter(
|
|
225
238
|
([key]) =>
|
|
226
239
|
!Object.keys(
|
|
227
240
|
openaiCompatibleLanguageModelChatOptions.shape,
|
|
@@ -250,7 +263,7 @@ export class OpenAICompatibleChatLanguageModel implements LanguageModelV4 {
|
|
|
250
263
|
async doGenerate(
|
|
251
264
|
options: LanguageModelV4CallOptions,
|
|
252
265
|
): Promise<LanguageModelV4GenerateResult> {
|
|
253
|
-
const { args, warnings } = await this.getArgs({ ...options });
|
|
266
|
+
const { args, warnings, metadataKey } = await this.getArgs({ ...options });
|
|
254
267
|
|
|
255
268
|
const transformedBody = this.transformRequestBody(args);
|
|
256
269
|
const body = JSON.stringify(transformedBody);
|
|
@@ -306,7 +319,7 @@ export class OpenAICompatibleChatLanguageModel implements LanguageModelV4 {
|
|
|
306
319
|
...(thoughtSignature
|
|
307
320
|
? {
|
|
308
321
|
providerMetadata: {
|
|
309
|
-
[
|
|
322
|
+
[metadataKey]: { thoughtSignature },
|
|
310
323
|
},
|
|
311
324
|
}
|
|
312
325
|
: {}),
|
|
@@ -316,7 +329,7 @@ export class OpenAICompatibleChatLanguageModel implements LanguageModelV4 {
|
|
|
316
329
|
|
|
317
330
|
// provider metadata:
|
|
318
331
|
const providerMetadata: SharedV4ProviderMetadata = {
|
|
319
|
-
[
|
|
332
|
+
[metadataKey]: {},
|
|
320
333
|
...(await this.config.metadataExtractor?.extractMetadata?.({
|
|
321
334
|
parsedBody: rawResponse,
|
|
322
335
|
})),
|
|
@@ -324,11 +337,11 @@ export class OpenAICompatibleChatLanguageModel implements LanguageModelV4 {
|
|
|
324
337
|
const completionTokenDetails =
|
|
325
338
|
responseBody.usage?.completion_tokens_details;
|
|
326
339
|
if (completionTokenDetails?.accepted_prediction_tokens != null) {
|
|
327
|
-
providerMetadata[
|
|
340
|
+
providerMetadata[metadataKey].acceptedPredictionTokens =
|
|
328
341
|
completionTokenDetails?.accepted_prediction_tokens;
|
|
329
342
|
}
|
|
330
343
|
if (completionTokenDetails?.rejected_prediction_tokens != null) {
|
|
331
|
-
providerMetadata[
|
|
344
|
+
providerMetadata[metadataKey].rejectedPredictionTokens =
|
|
332
345
|
completionTokenDetails?.rejected_prediction_tokens;
|
|
333
346
|
}
|
|
334
347
|
|
|
@@ -353,7 +366,9 @@ export class OpenAICompatibleChatLanguageModel implements LanguageModelV4 {
|
|
|
353
366
|
async doStream(
|
|
354
367
|
options: LanguageModelV4CallOptions,
|
|
355
368
|
): Promise<LanguageModelV4StreamResult> {
|
|
356
|
-
const { args, warnings } = await this.getArgs({
|
|
369
|
+
const { args, warnings, metadataKey } = await this.getArgs({
|
|
370
|
+
...options,
|
|
371
|
+
});
|
|
357
372
|
|
|
358
373
|
const body = this.transformRequestBody({
|
|
359
374
|
...args,
|
|
@@ -401,7 +416,7 @@ export class OpenAICompatibleChatLanguageModel implements LanguageModelV4 {
|
|
|
401
416
|
let usage: z.infer<typeof openaiCompatibleTokenUsageSchema> | undefined =
|
|
402
417
|
undefined;
|
|
403
418
|
let isFirstChunk = true;
|
|
404
|
-
const providerOptionsName =
|
|
419
|
+
const providerOptionsName = metadataKey;
|
|
405
420
|
let isActiveReasoning = false;
|
|
406
421
|
let isActiveText = false;
|
|
407
422
|
|
|
@@ -21,6 +21,7 @@ import {
|
|
|
21
21
|
ResponseHandler,
|
|
22
22
|
} from '@ai-sdk/provider-utils';
|
|
23
23
|
import { z } from 'zod/v4';
|
|
24
|
+
import { toCamelCase } from '../utils/to-camel-case';
|
|
24
25
|
import {
|
|
25
26
|
defaultOpenAICompatibleErrorStructure,
|
|
26
27
|
ProviderErrorStructure,
|
|
@@ -101,13 +102,19 @@ export class OpenAICompatibleCompletionLanguageModel implements LanguageModelV4
|
|
|
101
102
|
}: LanguageModelV4CallOptions) {
|
|
102
103
|
const warnings: SharedV4Warning[] = [];
|
|
103
104
|
|
|
104
|
-
// Parse provider options
|
|
105
|
-
const completionOptions =
|
|
105
|
+
// Parse provider options (support both raw and camelCase keys)
|
|
106
|
+
const completionOptions = Object.assign(
|
|
106
107
|
(await parseProviderOptions({
|
|
107
108
|
provider: this.providerOptionsName,
|
|
108
109
|
providerOptions,
|
|
109
110
|
schema: openaiCompatibleLanguageModelCompletionOptions,
|
|
110
|
-
})) ?? {}
|
|
111
|
+
})) ?? {},
|
|
112
|
+
(await parseProviderOptions({
|
|
113
|
+
provider: toCamelCase(this.providerOptionsName),
|
|
114
|
+
providerOptions,
|
|
115
|
+
schema: openaiCompatibleLanguageModelCompletionOptions,
|
|
116
|
+
})) ?? {},
|
|
117
|
+
);
|
|
111
118
|
|
|
112
119
|
if (topK != null) {
|
|
113
120
|
warnings.push({ type: 'unsupported', feature: 'topK' });
|
|
@@ -153,6 +160,7 @@ export class OpenAICompatibleCompletionLanguageModel implements LanguageModelV4
|
|
|
153
160
|
presence_penalty: presencePenalty,
|
|
154
161
|
seed,
|
|
155
162
|
...providerOptions?.[this.providerOptionsName],
|
|
163
|
+
...providerOptions?.[toCamelCase(this.providerOptionsName)],
|
|
156
164
|
|
|
157
165
|
// prompt:
|
|
158
166
|
prompt: completionPrompt,
|
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
SharedV4ProviderOptions,
|
|
5
5
|
SharedV4Warning,
|
|
6
6
|
} from '@ai-sdk/provider';
|
|
7
|
+
import { toCamelCase } from '../utils/to-camel-case';
|
|
7
8
|
import {
|
|
8
9
|
combineHeaders,
|
|
9
10
|
convertBase64ToUint8Array,
|
|
@@ -199,7 +200,3 @@ async function fileToBlob(file: ImageModelV4File): Promise<Blob> {
|
|
|
199
200
|
|
|
200
201
|
return new Blob([data as BlobPart], { type: file.mediaType });
|
|
201
202
|
}
|
|
202
|
-
|
|
203
|
-
function toCamelCase(str: string): string {
|
|
204
|
-
return str.replace(/[_-]([a-z])/g, g => g[1].toUpperCase());
|
|
205
|
-
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export function toCamelCase(str: string): string {
|
|
2
|
+
return str.replace(/[_-]([a-z])/g, g => g[1].toUpperCase());
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
Resolves which key to use for providerMetadata based on what the caller
|
|
7
|
+
passed in providerOptions. Returns the camelCase variant when the caller
|
|
8
|
+
supplied it, otherwise falls back to the raw name.
|
|
9
|
+
*/
|
|
10
|
+
export function resolveProviderOptionsKey(
|
|
11
|
+
rawName: string,
|
|
12
|
+
providerOptions: Record<string, unknown> | undefined,
|
|
13
|
+
): string {
|
|
14
|
+
const camelName = toCamelCase(rawName);
|
|
15
|
+
if (camelName !== rawName && providerOptions?.[camelName] != null) {
|
|
16
|
+
return camelName;
|
|
17
|
+
}
|
|
18
|
+
return rawName;
|
|
19
|
+
}
|