@ai-sdk/openai-compatible 2.0.39 → 2.0.40
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 +51 -23
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +51 -23
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/chat/openai-compatible-chat-language-model.ts +23 -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
|
@@ -25,6 +25,7 @@ import {
|
|
|
25
25
|
ResponseHandler,
|
|
26
26
|
} from '@ai-sdk/provider-utils';
|
|
27
27
|
import { z } from 'zod/v4';
|
|
28
|
+
import { resolveProviderOptionsKey, toCamelCase } from '../utils/to-camel-case';
|
|
28
29
|
import {
|
|
29
30
|
defaultOpenAICompatibleErrorStructure,
|
|
30
31
|
ProviderErrorStructure,
|
|
@@ -154,6 +155,11 @@ export class OpenAICompatibleChatLanguageModel implements LanguageModelV3 {
|
|
|
154
155
|
providerOptions,
|
|
155
156
|
schema: openaiCompatibleLanguageModelChatOptions,
|
|
156
157
|
})) ?? {},
|
|
158
|
+
(await parseProviderOptions({
|
|
159
|
+
provider: toCamelCase(this.providerOptionsName),
|
|
160
|
+
providerOptions,
|
|
161
|
+
schema: openaiCompatibleLanguageModelChatOptions,
|
|
162
|
+
})) ?? {},
|
|
157
163
|
);
|
|
158
164
|
|
|
159
165
|
const strictJsonSchema = compatibleOptions?.strictJsonSchema ?? true;
|
|
@@ -184,7 +190,13 @@ export class OpenAICompatibleChatLanguageModel implements LanguageModelV3 {
|
|
|
184
190
|
toolChoice,
|
|
185
191
|
});
|
|
186
192
|
|
|
193
|
+
const metadataKey = resolveProviderOptionsKey(
|
|
194
|
+
this.providerOptionsName,
|
|
195
|
+
providerOptions,
|
|
196
|
+
);
|
|
197
|
+
|
|
187
198
|
return {
|
|
199
|
+
metadataKey,
|
|
188
200
|
args: {
|
|
189
201
|
// model id:
|
|
190
202
|
model: this.modelId,
|
|
@@ -217,9 +229,10 @@ export class OpenAICompatibleChatLanguageModel implements LanguageModelV3 {
|
|
|
217
229
|
stop: stopSequences,
|
|
218
230
|
seed,
|
|
219
231
|
...Object.fromEntries(
|
|
220
|
-
Object.entries(
|
|
221
|
-
providerOptions?.[this.providerOptionsName]
|
|
222
|
-
|
|
232
|
+
Object.entries({
|
|
233
|
+
...providerOptions?.[this.providerOptionsName],
|
|
234
|
+
...providerOptions?.[toCamelCase(this.providerOptionsName)],
|
|
235
|
+
}).filter(
|
|
223
236
|
([key]) =>
|
|
224
237
|
!Object.keys(
|
|
225
238
|
openaiCompatibleLanguageModelChatOptions.shape,
|
|
@@ -244,7 +257,7 @@ export class OpenAICompatibleChatLanguageModel implements LanguageModelV3 {
|
|
|
244
257
|
async doGenerate(
|
|
245
258
|
options: LanguageModelV3CallOptions,
|
|
246
259
|
): Promise<LanguageModelV3GenerateResult> {
|
|
247
|
-
const { args, warnings } = await this.getArgs({ ...options });
|
|
260
|
+
const { args, warnings, metadataKey } = await this.getArgs({ ...options });
|
|
248
261
|
|
|
249
262
|
const transformedBody = this.transformRequestBody(args);
|
|
250
263
|
const body = JSON.stringify(transformedBody);
|
|
@@ -300,7 +313,7 @@ export class OpenAICompatibleChatLanguageModel implements LanguageModelV3 {
|
|
|
300
313
|
...(thoughtSignature
|
|
301
314
|
? {
|
|
302
315
|
providerMetadata: {
|
|
303
|
-
[
|
|
316
|
+
[metadataKey]: { thoughtSignature },
|
|
304
317
|
},
|
|
305
318
|
}
|
|
306
319
|
: {}),
|
|
@@ -310,7 +323,7 @@ export class OpenAICompatibleChatLanguageModel implements LanguageModelV3 {
|
|
|
310
323
|
|
|
311
324
|
// provider metadata:
|
|
312
325
|
const providerMetadata: SharedV3ProviderMetadata = {
|
|
313
|
-
[
|
|
326
|
+
[metadataKey]: {},
|
|
314
327
|
...(await this.config.metadataExtractor?.extractMetadata?.({
|
|
315
328
|
parsedBody: rawResponse,
|
|
316
329
|
})),
|
|
@@ -318,11 +331,11 @@ export class OpenAICompatibleChatLanguageModel implements LanguageModelV3 {
|
|
|
318
331
|
const completionTokenDetails =
|
|
319
332
|
responseBody.usage?.completion_tokens_details;
|
|
320
333
|
if (completionTokenDetails?.accepted_prediction_tokens != null) {
|
|
321
|
-
providerMetadata[
|
|
334
|
+
providerMetadata[metadataKey].acceptedPredictionTokens =
|
|
322
335
|
completionTokenDetails?.accepted_prediction_tokens;
|
|
323
336
|
}
|
|
324
337
|
if (completionTokenDetails?.rejected_prediction_tokens != null) {
|
|
325
|
-
providerMetadata[
|
|
338
|
+
providerMetadata[metadataKey].rejectedPredictionTokens =
|
|
326
339
|
completionTokenDetails?.rejected_prediction_tokens;
|
|
327
340
|
}
|
|
328
341
|
|
|
@@ -347,7 +360,7 @@ export class OpenAICompatibleChatLanguageModel implements LanguageModelV3 {
|
|
|
347
360
|
async doStream(
|
|
348
361
|
options: LanguageModelV3CallOptions,
|
|
349
362
|
): Promise<LanguageModelV3StreamResult> {
|
|
350
|
-
const { args, warnings } = await this.getArgs({ ...options });
|
|
363
|
+
const { args, warnings, metadataKey } = await this.getArgs({ ...options });
|
|
351
364
|
|
|
352
365
|
const body = this.transformRequestBody({
|
|
353
366
|
...args,
|
|
@@ -395,7 +408,7 @@ export class OpenAICompatibleChatLanguageModel implements LanguageModelV3 {
|
|
|
395
408
|
let usage: z.infer<typeof openaiCompatibleTokenUsageSchema> | undefined =
|
|
396
409
|
undefined;
|
|
397
410
|
let isFirstChunk = true;
|
|
398
|
-
const providerOptionsName =
|
|
411
|
+
const providerOptionsName = metadataKey;
|
|
399
412
|
let isActiveReasoning = false;
|
|
400
413
|
let isActiveText = false;
|
|
401
414
|
|
|
@@ -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 LanguageModelV3
|
|
|
101
102
|
}: LanguageModelV3CallOptions) {
|
|
102
103
|
const warnings: SharedV3Warning[] = [];
|
|
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 LanguageModelV3
|
|
|
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
|
SharedV3ProviderOptions,
|
|
5
5
|
SharedV3Warning,
|
|
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: ImageModelV3File): 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
|
+
}
|