@ai-sdk/deepinfra 2.0.28 → 2.0.30
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 +12 -0
- package/dist/index.js +137 -5
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +134 -3
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
- package/src/deepinfra-chat-language-model.ts +174 -0
- package/src/deepinfra-provider.ts +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @ai-sdk/deepinfra
|
|
2
2
|
|
|
3
|
+
## 2.0.30
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- e152eef: fix: correct token usage calculation for Gemini/Gemma models
|
|
8
|
+
|
|
9
|
+
## 2.0.29
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- 2fd5085: fix: correct token usage calculation for Gemini/Gemma models
|
|
14
|
+
|
|
3
15
|
## 2.0.28
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
package/dist/index.js
CHANGED
|
@@ -27,7 +27,7 @@ __export(src_exports, {
|
|
|
27
27
|
module.exports = __toCommonJS(src_exports);
|
|
28
28
|
|
|
29
29
|
// src/deepinfra-provider.ts
|
|
30
|
-
var
|
|
30
|
+
var import_openai_compatible2 = require("@ai-sdk/openai-compatible");
|
|
31
31
|
var import_provider_utils2 = require("@ai-sdk/provider-utils");
|
|
32
32
|
|
|
33
33
|
// src/deepinfra-image-model.ts
|
|
@@ -160,8 +160,140 @@ async function fileToBlob(file) {
|
|
|
160
160
|
return new Blob([data], { type: file.mediaType });
|
|
161
161
|
}
|
|
162
162
|
|
|
163
|
+
// src/deepinfra-chat-language-model.ts
|
|
164
|
+
var import_openai_compatible = require("@ai-sdk/openai-compatible");
|
|
165
|
+
var DeepInfraChatLanguageModel = class extends import_openai_compatible.OpenAICompatibleChatLanguageModel {
|
|
166
|
+
constructor(modelId, config) {
|
|
167
|
+
super(modelId, config);
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Fixes incorrect token usage for Gemini/Gemma models from DeepInfra.
|
|
171
|
+
*
|
|
172
|
+
* DeepInfra's API returns completion_tokens that don't include reasoning_tokens
|
|
173
|
+
* for Gemini/Gemma models, which violates the OpenAI-compatible spec.
|
|
174
|
+
* According to the spec, completion_tokens should include reasoning_tokens.
|
|
175
|
+
*
|
|
176
|
+
* Example of incorrect data from DeepInfra:
|
|
177
|
+
* {
|
|
178
|
+
* "completion_tokens": 84, // text-only tokens
|
|
179
|
+
* "completion_tokens_details": {
|
|
180
|
+
* "reasoning_tokens": 1081 // reasoning tokens not included above
|
|
181
|
+
* }
|
|
182
|
+
* }
|
|
183
|
+
*
|
|
184
|
+
* This would result in negative text tokens: 84 - 1081 = -997
|
|
185
|
+
*
|
|
186
|
+
* The fix: If reasoning_tokens > completion_tokens, add reasoning_tokens
|
|
187
|
+
* to completion_tokens: 84 + 1081 = 1165
|
|
188
|
+
*/
|
|
189
|
+
fixUsageForGeminiModels(usage) {
|
|
190
|
+
var _a, _b;
|
|
191
|
+
if (!usage || !((_a = usage.completion_tokens_details) == null ? void 0 : _a.reasoning_tokens)) {
|
|
192
|
+
return usage;
|
|
193
|
+
}
|
|
194
|
+
const completionTokens = (_b = usage.completion_tokens) != null ? _b : 0;
|
|
195
|
+
const reasoningTokens = usage.completion_tokens_details.reasoning_tokens;
|
|
196
|
+
if (reasoningTokens > completionTokens) {
|
|
197
|
+
const correctedCompletionTokens = completionTokens + reasoningTokens;
|
|
198
|
+
return {
|
|
199
|
+
...usage,
|
|
200
|
+
// Add reasoning_tokens to completion_tokens to get the correct total
|
|
201
|
+
completion_tokens: correctedCompletionTokens,
|
|
202
|
+
// Update total_tokens if present
|
|
203
|
+
total_tokens: usage.total_tokens != null ? usage.total_tokens + reasoningTokens : void 0
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
return usage;
|
|
207
|
+
}
|
|
208
|
+
async doGenerate(options) {
|
|
209
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
210
|
+
const result = await super.doGenerate(options);
|
|
211
|
+
if ((_a = result.usage) == null ? void 0 : _a.raw) {
|
|
212
|
+
const fixedRawUsage = this.fixUsageForGeminiModels(result.usage.raw);
|
|
213
|
+
if (fixedRawUsage !== result.usage.raw) {
|
|
214
|
+
const promptTokens = (_b = fixedRawUsage.prompt_tokens) != null ? _b : 0;
|
|
215
|
+
const completionTokens = (_c = fixedRawUsage.completion_tokens) != null ? _c : 0;
|
|
216
|
+
const cacheReadTokens = (_e = (_d = fixedRawUsage.prompt_tokens_details) == null ? void 0 : _d.cached_tokens) != null ? _e : 0;
|
|
217
|
+
const reasoningTokens = (_g = (_f = fixedRawUsage.completion_tokens_details) == null ? void 0 : _f.reasoning_tokens) != null ? _g : 0;
|
|
218
|
+
return {
|
|
219
|
+
...result,
|
|
220
|
+
usage: {
|
|
221
|
+
inputTokens: {
|
|
222
|
+
total: promptTokens,
|
|
223
|
+
noCache: promptTokens - cacheReadTokens,
|
|
224
|
+
cacheRead: cacheReadTokens,
|
|
225
|
+
cacheWrite: void 0
|
|
226
|
+
},
|
|
227
|
+
outputTokens: {
|
|
228
|
+
total: completionTokens,
|
|
229
|
+
text: completionTokens - reasoningTokens,
|
|
230
|
+
reasoning: reasoningTokens
|
|
231
|
+
},
|
|
232
|
+
raw: fixedRawUsage
|
|
233
|
+
}
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
return result;
|
|
238
|
+
}
|
|
239
|
+
async doStream(options) {
|
|
240
|
+
const result = await super.doStream(options);
|
|
241
|
+
const originalStream = result.stream;
|
|
242
|
+
const fixUsage = this.fixUsageForGeminiModels.bind(this);
|
|
243
|
+
const transformedStream = new ReadableStream({
|
|
244
|
+
async start(controller) {
|
|
245
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
246
|
+
const reader = originalStream.getReader();
|
|
247
|
+
try {
|
|
248
|
+
while (true) {
|
|
249
|
+
const { done, value } = await reader.read();
|
|
250
|
+
if (done) break;
|
|
251
|
+
if (value.type === "finish" && ((_a = value.usage) == null ? void 0 : _a.raw)) {
|
|
252
|
+
const fixedRawUsage = fixUsage(value.usage.raw);
|
|
253
|
+
if (fixedRawUsage !== value.usage.raw) {
|
|
254
|
+
const promptTokens = (_b = fixedRawUsage.prompt_tokens) != null ? _b : 0;
|
|
255
|
+
const completionTokens = (_c = fixedRawUsage.completion_tokens) != null ? _c : 0;
|
|
256
|
+
const cacheReadTokens = (_e = (_d = fixedRawUsage.prompt_tokens_details) == null ? void 0 : _d.cached_tokens) != null ? _e : 0;
|
|
257
|
+
const reasoningTokens = (_g = (_f = fixedRawUsage.completion_tokens_details) == null ? void 0 : _f.reasoning_tokens) != null ? _g : 0;
|
|
258
|
+
controller.enqueue({
|
|
259
|
+
...value,
|
|
260
|
+
usage: {
|
|
261
|
+
inputTokens: {
|
|
262
|
+
total: promptTokens,
|
|
263
|
+
noCache: promptTokens - cacheReadTokens,
|
|
264
|
+
cacheRead: cacheReadTokens,
|
|
265
|
+
cacheWrite: void 0
|
|
266
|
+
},
|
|
267
|
+
outputTokens: {
|
|
268
|
+
total: completionTokens,
|
|
269
|
+
text: completionTokens - reasoningTokens,
|
|
270
|
+
reasoning: reasoningTokens
|
|
271
|
+
},
|
|
272
|
+
raw: fixedRawUsage
|
|
273
|
+
}
|
|
274
|
+
});
|
|
275
|
+
} else {
|
|
276
|
+
controller.enqueue(value);
|
|
277
|
+
}
|
|
278
|
+
} else {
|
|
279
|
+
controller.enqueue(value);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
controller.close();
|
|
283
|
+
} catch (error) {
|
|
284
|
+
controller.error(error);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
});
|
|
288
|
+
return {
|
|
289
|
+
...result,
|
|
290
|
+
stream: transformedStream
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
};
|
|
294
|
+
|
|
163
295
|
// src/version.ts
|
|
164
|
-
var VERSION = true ? "2.0.
|
|
296
|
+
var VERSION = true ? "2.0.30" : "0.0.0-test";
|
|
165
297
|
|
|
166
298
|
// src/deepinfra-provider.ts
|
|
167
299
|
function createDeepInfra(options = {}) {
|
|
@@ -187,16 +319,16 @@ function createDeepInfra(options = {}) {
|
|
|
187
319
|
fetch: options.fetch
|
|
188
320
|
});
|
|
189
321
|
const createChatModel = (modelId) => {
|
|
190
|
-
return new
|
|
322
|
+
return new DeepInfraChatLanguageModel(
|
|
191
323
|
modelId,
|
|
192
324
|
getCommonModelConfig("chat")
|
|
193
325
|
);
|
|
194
326
|
};
|
|
195
|
-
const createCompletionModel = (modelId) => new
|
|
327
|
+
const createCompletionModel = (modelId) => new import_openai_compatible2.OpenAICompatibleCompletionLanguageModel(
|
|
196
328
|
modelId,
|
|
197
329
|
getCommonModelConfig("completion")
|
|
198
330
|
);
|
|
199
|
-
const createEmbeddingModel = (modelId) => new
|
|
331
|
+
const createEmbeddingModel = (modelId) => new import_openai_compatible2.OpenAICompatibleEmbeddingModel(
|
|
200
332
|
modelId,
|
|
201
333
|
getCommonModelConfig("embedding")
|
|
202
334
|
);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/deepinfra-provider.ts","../src/deepinfra-image-model.ts","../src/version.ts"],"sourcesContent":["export { createDeepInfra, deepinfra } from './deepinfra-provider';\nexport type {\n DeepInfraProvider,\n DeepInfraProviderSettings,\n} from './deepinfra-provider';\nexport type { OpenAICompatibleErrorData as DeepInfraErrorData } from '@ai-sdk/openai-compatible';\nexport { VERSION } from './version';\n","import {\n LanguageModelV3,\n EmbeddingModelV3,\n ProviderV3,\n ImageModelV3,\n} from '@ai-sdk/provider';\nimport {\n OpenAICompatibleChatLanguageModel,\n OpenAICompatibleCompletionLanguageModel,\n OpenAICompatibleEmbeddingModel,\n} from '@ai-sdk/openai-compatible';\nimport {\n FetchFunction,\n loadApiKey,\n withoutTrailingSlash,\n withUserAgentSuffix,\n} from '@ai-sdk/provider-utils';\nimport { DeepInfraChatModelId } from './deepinfra-chat-options';\nimport { DeepInfraEmbeddingModelId } from './deepinfra-embedding-options';\nimport { DeepInfraCompletionModelId } from './deepinfra-completion-options';\nimport { DeepInfraImageModelId } from './deepinfra-image-settings';\nimport { DeepInfraImageModel } from './deepinfra-image-model';\nimport { VERSION } from './version';\n\nexport interface DeepInfraProviderSettings {\n /**\n * DeepInfra API key.\n */\n apiKey?: string;\n /**\n * Base URL for the API calls.\n */\n baseURL?: string;\n /**\n * Custom headers to include in the requests.\n */\n headers?: Record<string, string>;\n /**\n * Custom fetch implementation. You can use it as a middleware to intercept requests,\n * or to provide a custom fetch implementation for e.g. testing.\n */\n fetch?: FetchFunction;\n}\n\nexport interface DeepInfraProvider extends ProviderV3 {\n /**\n * Creates a model for text generation.\n */\n (modelId: DeepInfraChatModelId): LanguageModelV3;\n\n /**\n * Creates a chat model for text generation.\n */\n chatModel(modelId: DeepInfraChatModelId): LanguageModelV3;\n\n /**\n * Creates a model for image generation.\n */\n image(modelId: DeepInfraImageModelId): ImageModelV3;\n\n /**\n * Creates a model for image generation.\n */\n imageModel(modelId: DeepInfraImageModelId): ImageModelV3;\n\n /**\n * Creates a chat model for text generation.\n */\n languageModel(modelId: DeepInfraChatModelId): LanguageModelV3;\n\n /**\n * Creates a completion model for text generation.\n */\n completionModel(modelId: DeepInfraCompletionModelId): LanguageModelV3;\n\n /**\n * Creates a embedding model for text generation.\n */\n embeddingModel(modelId: DeepInfraEmbeddingModelId): EmbeddingModelV3;\n\n /**\n * @deprecated Use `embeddingModel` instead.\n */\n textEmbeddingModel(modelId: DeepInfraEmbeddingModelId): EmbeddingModelV3;\n}\n\nexport function createDeepInfra(\n options: DeepInfraProviderSettings = {},\n): DeepInfraProvider {\n const baseURL = withoutTrailingSlash(\n options.baseURL ?? 'https://api.deepinfra.com/v1',\n );\n const getHeaders = () =>\n withUserAgentSuffix(\n {\n Authorization: `Bearer ${loadApiKey({\n apiKey: options.apiKey,\n environmentVariableName: 'DEEPINFRA_API_KEY',\n description: \"DeepInfra's API key\",\n })}`,\n ...options.headers,\n },\n `ai-sdk/deepinfra/${VERSION}`,\n );\n\n interface CommonModelConfig {\n provider: string;\n url: ({ path }: { path: string }) => string;\n headers: () => Record<string, string>;\n fetch?: FetchFunction;\n }\n\n const getCommonModelConfig = (modelType: string): CommonModelConfig => ({\n provider: `deepinfra.${modelType}`,\n url: ({ path }) => `${baseURL}/openai${path}`,\n headers: getHeaders,\n fetch: options.fetch,\n });\n\n const createChatModel = (modelId: DeepInfraChatModelId) => {\n return new OpenAICompatibleChatLanguageModel(\n modelId,\n getCommonModelConfig('chat'),\n );\n };\n\n const createCompletionModel = (modelId: DeepInfraCompletionModelId) =>\n new OpenAICompatibleCompletionLanguageModel(\n modelId,\n getCommonModelConfig('completion'),\n );\n\n const createEmbeddingModel = (modelId: DeepInfraEmbeddingModelId) =>\n new OpenAICompatibleEmbeddingModel(\n modelId,\n getCommonModelConfig('embedding'),\n );\n\n const createImageModel = (modelId: DeepInfraImageModelId) =>\n new DeepInfraImageModel(modelId, {\n ...getCommonModelConfig('image'),\n baseURL: baseURL\n ? `${baseURL}/inference`\n : 'https://api.deepinfra.com/v1/inference',\n });\n\n const provider = (modelId: DeepInfraChatModelId) => createChatModel(modelId);\n\n provider.specificationVersion = 'v3' as const;\n provider.completionModel = createCompletionModel;\n provider.chatModel = createChatModel;\n provider.image = createImageModel;\n provider.imageModel = createImageModel;\n provider.languageModel = createChatModel;\n provider.embeddingModel = createEmbeddingModel;\n provider.textEmbeddingModel = createEmbeddingModel;\n\n return provider;\n}\n\nexport const deepinfra = createDeepInfra();\n","import {\n ImageModelV3,\n ImageModelV3File,\n SharedV3Warning,\n} from '@ai-sdk/provider';\nimport {\n combineHeaders,\n convertBase64ToUint8Array,\n convertToFormData,\n createJsonErrorResponseHandler,\n createJsonResponseHandler,\n downloadBlob,\n FetchFunction,\n postFormDataToApi,\n postJsonToApi,\n} from '@ai-sdk/provider-utils';\nimport { DeepInfraImageModelId } from './deepinfra-image-settings';\nimport { z } from 'zod/v4';\n\ninterface DeepInfraImageModelConfig {\n provider: string;\n baseURL: string;\n headers: () => Record<string, string>;\n fetch?: FetchFunction;\n _internal?: {\n currentDate?: () => Date;\n };\n}\n\nexport class DeepInfraImageModel implements ImageModelV3 {\n readonly specificationVersion = 'v3';\n readonly maxImagesPerCall = 1;\n\n get provider(): string {\n return this.config.provider;\n }\n\n constructor(\n readonly modelId: DeepInfraImageModelId,\n private config: DeepInfraImageModelConfig,\n ) {}\n\n async doGenerate({\n prompt,\n n,\n size,\n aspectRatio,\n seed,\n providerOptions,\n headers,\n abortSignal,\n files,\n mask,\n }: Parameters<ImageModelV3['doGenerate']>[0]): Promise<\n Awaited<ReturnType<ImageModelV3['doGenerate']>>\n > {\n const warnings: Array<SharedV3Warning> = [];\n const currentDate = this.config._internal?.currentDate?.() ?? new Date();\n\n // Image editing mode - use OpenAI-compatible /images/edits endpoint\n if (files != null && files.length > 0) {\n const { value: response, responseHeaders } = await postFormDataToApi({\n url: this.getEditUrl(),\n headers: combineHeaders(this.config.headers(), headers),\n formData: convertToFormData<DeepInfraFormDataInput>(\n {\n model: this.modelId,\n prompt,\n image: await Promise.all(files.map(file => fileToBlob(file))),\n mask: mask != null ? await fileToBlob(mask) : undefined,\n n,\n size,\n ...(providerOptions.deepinfra ?? {}),\n },\n { useArrayBrackets: false },\n ),\n failedResponseHandler: createJsonErrorResponseHandler({\n errorSchema: deepInfraEditErrorSchema,\n errorToMessage: error => error.error?.message ?? 'Unknown error',\n }),\n successfulResponseHandler: createJsonResponseHandler(\n deepInfraEditResponseSchema,\n ),\n abortSignal,\n fetch: this.config.fetch,\n });\n\n return {\n images: response.data.map(item => item.b64_json),\n warnings,\n response: {\n timestamp: currentDate,\n modelId: this.modelId,\n headers: responseHeaders,\n },\n };\n }\n\n // Standard image generation mode\n // Some deepinfra models support size while others support aspect ratio.\n // Allow passing either and leave it up to the server to validate.\n const splitSize = size?.split('x');\n const { value: response, responseHeaders } = await postJsonToApi({\n url: `${this.config.baseURL}/${this.modelId}`,\n headers: combineHeaders(this.config.headers(), headers),\n body: {\n prompt,\n num_images: n,\n ...(aspectRatio && { aspect_ratio: aspectRatio }),\n ...(splitSize && { width: splitSize[0], height: splitSize[1] }),\n ...(seed != null && { seed }),\n ...(providerOptions.deepinfra ?? {}),\n },\n failedResponseHandler: createJsonErrorResponseHandler({\n errorSchema: deepInfraErrorSchema,\n errorToMessage: error => error.detail.error,\n }),\n successfulResponseHandler: createJsonResponseHandler(\n deepInfraImageResponseSchema,\n ),\n abortSignal,\n fetch: this.config.fetch,\n });\n\n return {\n images: response.images.map(image =>\n image.replace(/^data:image\\/\\w+;base64,/, ''),\n ),\n warnings,\n response: {\n timestamp: currentDate,\n modelId: this.modelId,\n headers: responseHeaders,\n },\n };\n }\n\n private getEditUrl(): string {\n // Use OpenAI-compatible endpoint for image editing\n // baseURL is typically https://api.deepinfra.com/v1/inference\n // We need to use https://api.deepinfra.com/v1/openai/images/edits\n const baseUrl = this.config.baseURL.replace('/inference', '/openai');\n return `${baseUrl}/images/edits`;\n }\n}\n\nexport const deepInfraErrorSchema = z.object({\n detail: z.object({\n error: z.string(),\n }),\n});\n\n// limited version of the schema, focussed on what is needed for the implementation\n// this approach limits breakages when the API changes and increases efficiency\nexport const deepInfraImageResponseSchema = z.object({\n images: z.array(z.string()),\n});\n\n// Schema for OpenAI-compatible image edit endpoint errors\nexport const deepInfraEditErrorSchema = z.object({\n error: z\n .object({\n message: z.string(),\n })\n .optional(),\n});\n\n// Schema for OpenAI-compatible image edit endpoint response\nexport const deepInfraEditResponseSchema = z.object({\n data: z.array(z.object({ b64_json: z.string() })),\n});\n\ntype DeepInfraFormDataInput = {\n model: string;\n prompt: string | undefined;\n image: Blob | Blob[];\n mask?: Blob;\n n: number;\n size: `${number}x${number}` | undefined;\n [key: string]: unknown;\n};\n\nasync function fileToBlob(file: ImageModelV3File): Promise<Blob> {\n if (file.type === 'url') {\n return downloadBlob(file.url);\n }\n\n const data =\n file.data instanceof Uint8Array\n ? file.data\n : convertBase64ToUint8Array(file.data);\n\n return new Blob([data as BlobPart], { type: file.mediaType });\n}\n","// Version string of this package injected at build time.\ndeclare const __PACKAGE_VERSION__: string | undefined;\nexport const VERSION: string =\n typeof __PACKAGE_VERSION__ !== 'undefined'\n ? __PACKAGE_VERSION__\n : '0.0.0-test';\n"],"mappings":"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","names":["import_provider_utils","response","responseHeaders","_a","_b"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/deepinfra-provider.ts","../src/deepinfra-image-model.ts","../src/deepinfra-chat-language-model.ts","../src/version.ts"],"sourcesContent":["export { createDeepInfra, deepinfra } from './deepinfra-provider';\nexport type {\n DeepInfraProvider,\n DeepInfraProviderSettings,\n} from './deepinfra-provider';\nexport type { OpenAICompatibleErrorData as DeepInfraErrorData } from '@ai-sdk/openai-compatible';\nexport { VERSION } from './version';\n","import {\n LanguageModelV3,\n EmbeddingModelV3,\n ProviderV3,\n ImageModelV3,\n} from '@ai-sdk/provider';\nimport {\n OpenAICompatibleCompletionLanguageModel,\n OpenAICompatibleEmbeddingModel,\n} from '@ai-sdk/openai-compatible';\nimport {\n FetchFunction,\n loadApiKey,\n withoutTrailingSlash,\n withUserAgentSuffix,\n} from '@ai-sdk/provider-utils';\nimport { DeepInfraChatModelId } from './deepinfra-chat-options';\nimport { DeepInfraEmbeddingModelId } from './deepinfra-embedding-options';\nimport { DeepInfraCompletionModelId } from './deepinfra-completion-options';\nimport { DeepInfraImageModelId } from './deepinfra-image-settings';\nimport { DeepInfraImageModel } from './deepinfra-image-model';\nimport { DeepInfraChatLanguageModel } from './deepinfra-chat-language-model';\nimport { VERSION } from './version';\n\nexport interface DeepInfraProviderSettings {\n /**\n * DeepInfra API key.\n */\n apiKey?: string;\n /**\n * Base URL for the API calls.\n */\n baseURL?: string;\n /**\n * Custom headers to include in the requests.\n */\n headers?: Record<string, string>;\n /**\n * Custom fetch implementation. You can use it as a middleware to intercept requests,\n * or to provide a custom fetch implementation for e.g. testing.\n */\n fetch?: FetchFunction;\n}\n\nexport interface DeepInfraProvider extends ProviderV3 {\n /**\n * Creates a model for text generation.\n */\n (modelId: DeepInfraChatModelId): LanguageModelV3;\n\n /**\n * Creates a chat model for text generation.\n */\n chatModel(modelId: DeepInfraChatModelId): LanguageModelV3;\n\n /**\n * Creates a model for image generation.\n */\n image(modelId: DeepInfraImageModelId): ImageModelV3;\n\n /**\n * Creates a model for image generation.\n */\n imageModel(modelId: DeepInfraImageModelId): ImageModelV3;\n\n /**\n * Creates a chat model for text generation.\n */\n languageModel(modelId: DeepInfraChatModelId): LanguageModelV3;\n\n /**\n * Creates a completion model for text generation.\n */\n completionModel(modelId: DeepInfraCompletionModelId): LanguageModelV3;\n\n /**\n * Creates a embedding model for text generation.\n */\n embeddingModel(modelId: DeepInfraEmbeddingModelId): EmbeddingModelV3;\n\n /**\n * @deprecated Use `embeddingModel` instead.\n */\n textEmbeddingModel(modelId: DeepInfraEmbeddingModelId): EmbeddingModelV3;\n}\n\nexport function createDeepInfra(\n options: DeepInfraProviderSettings = {},\n): DeepInfraProvider {\n const baseURL = withoutTrailingSlash(\n options.baseURL ?? 'https://api.deepinfra.com/v1',\n );\n const getHeaders = () =>\n withUserAgentSuffix(\n {\n Authorization: `Bearer ${loadApiKey({\n apiKey: options.apiKey,\n environmentVariableName: 'DEEPINFRA_API_KEY',\n description: \"DeepInfra's API key\",\n })}`,\n ...options.headers,\n },\n `ai-sdk/deepinfra/${VERSION}`,\n );\n\n interface CommonModelConfig {\n provider: string;\n url: ({ path }: { path: string }) => string;\n headers: () => Record<string, string>;\n fetch?: FetchFunction;\n }\n\n const getCommonModelConfig = (modelType: string): CommonModelConfig => ({\n provider: `deepinfra.${modelType}`,\n url: ({ path }) => `${baseURL}/openai${path}`,\n headers: getHeaders,\n fetch: options.fetch,\n });\n\n const createChatModel = (modelId: DeepInfraChatModelId) => {\n return new DeepInfraChatLanguageModel(\n modelId,\n getCommonModelConfig('chat'),\n );\n };\n\n const createCompletionModel = (modelId: DeepInfraCompletionModelId) =>\n new OpenAICompatibleCompletionLanguageModel(\n modelId,\n getCommonModelConfig('completion'),\n );\n\n const createEmbeddingModel = (modelId: DeepInfraEmbeddingModelId) =>\n new OpenAICompatibleEmbeddingModel(\n modelId,\n getCommonModelConfig('embedding'),\n );\n\n const createImageModel = (modelId: DeepInfraImageModelId) =>\n new DeepInfraImageModel(modelId, {\n ...getCommonModelConfig('image'),\n baseURL: baseURL\n ? `${baseURL}/inference`\n : 'https://api.deepinfra.com/v1/inference',\n });\n\n const provider = (modelId: DeepInfraChatModelId) => createChatModel(modelId);\n\n provider.specificationVersion = 'v3' as const;\n provider.completionModel = createCompletionModel;\n provider.chatModel = createChatModel;\n provider.image = createImageModel;\n provider.imageModel = createImageModel;\n provider.languageModel = createChatModel;\n provider.embeddingModel = createEmbeddingModel;\n provider.textEmbeddingModel = createEmbeddingModel;\n\n return provider;\n}\n\nexport const deepinfra = createDeepInfra();\n","import {\n ImageModelV3,\n ImageModelV3File,\n SharedV3Warning,\n} from '@ai-sdk/provider';\nimport {\n combineHeaders,\n convertBase64ToUint8Array,\n convertToFormData,\n createJsonErrorResponseHandler,\n createJsonResponseHandler,\n downloadBlob,\n FetchFunction,\n postFormDataToApi,\n postJsonToApi,\n} from '@ai-sdk/provider-utils';\nimport { DeepInfraImageModelId } from './deepinfra-image-settings';\nimport { z } from 'zod/v4';\n\ninterface DeepInfraImageModelConfig {\n provider: string;\n baseURL: string;\n headers: () => Record<string, string>;\n fetch?: FetchFunction;\n _internal?: {\n currentDate?: () => Date;\n };\n}\n\nexport class DeepInfraImageModel implements ImageModelV3 {\n readonly specificationVersion = 'v3';\n readonly maxImagesPerCall = 1;\n\n get provider(): string {\n return this.config.provider;\n }\n\n constructor(\n readonly modelId: DeepInfraImageModelId,\n private config: DeepInfraImageModelConfig,\n ) {}\n\n async doGenerate({\n prompt,\n n,\n size,\n aspectRatio,\n seed,\n providerOptions,\n headers,\n abortSignal,\n files,\n mask,\n }: Parameters<ImageModelV3['doGenerate']>[0]): Promise<\n Awaited<ReturnType<ImageModelV3['doGenerate']>>\n > {\n const warnings: Array<SharedV3Warning> = [];\n const currentDate = this.config._internal?.currentDate?.() ?? new Date();\n\n // Image editing mode - use OpenAI-compatible /images/edits endpoint\n if (files != null && files.length > 0) {\n const { value: response, responseHeaders } = await postFormDataToApi({\n url: this.getEditUrl(),\n headers: combineHeaders(this.config.headers(), headers),\n formData: convertToFormData<DeepInfraFormDataInput>(\n {\n model: this.modelId,\n prompt,\n image: await Promise.all(files.map(file => fileToBlob(file))),\n mask: mask != null ? await fileToBlob(mask) : undefined,\n n,\n size,\n ...(providerOptions.deepinfra ?? {}),\n },\n { useArrayBrackets: false },\n ),\n failedResponseHandler: createJsonErrorResponseHandler({\n errorSchema: deepInfraEditErrorSchema,\n errorToMessage: error => error.error?.message ?? 'Unknown error',\n }),\n successfulResponseHandler: createJsonResponseHandler(\n deepInfraEditResponseSchema,\n ),\n abortSignal,\n fetch: this.config.fetch,\n });\n\n return {\n images: response.data.map(item => item.b64_json),\n warnings,\n response: {\n timestamp: currentDate,\n modelId: this.modelId,\n headers: responseHeaders,\n },\n };\n }\n\n // Standard image generation mode\n // Some deepinfra models support size while others support aspect ratio.\n // Allow passing either and leave it up to the server to validate.\n const splitSize = size?.split('x');\n const { value: response, responseHeaders } = await postJsonToApi({\n url: `${this.config.baseURL}/${this.modelId}`,\n headers: combineHeaders(this.config.headers(), headers),\n body: {\n prompt,\n num_images: n,\n ...(aspectRatio && { aspect_ratio: aspectRatio }),\n ...(splitSize && { width: splitSize[0], height: splitSize[1] }),\n ...(seed != null && { seed }),\n ...(providerOptions.deepinfra ?? {}),\n },\n failedResponseHandler: createJsonErrorResponseHandler({\n errorSchema: deepInfraErrorSchema,\n errorToMessage: error => error.detail.error,\n }),\n successfulResponseHandler: createJsonResponseHandler(\n deepInfraImageResponseSchema,\n ),\n abortSignal,\n fetch: this.config.fetch,\n });\n\n return {\n images: response.images.map(image =>\n image.replace(/^data:image\\/\\w+;base64,/, ''),\n ),\n warnings,\n response: {\n timestamp: currentDate,\n modelId: this.modelId,\n headers: responseHeaders,\n },\n };\n }\n\n private getEditUrl(): string {\n // Use OpenAI-compatible endpoint for image editing\n // baseURL is typically https://api.deepinfra.com/v1/inference\n // We need to use https://api.deepinfra.com/v1/openai/images/edits\n const baseUrl = this.config.baseURL.replace('/inference', '/openai');\n return `${baseUrl}/images/edits`;\n }\n}\n\nexport const deepInfraErrorSchema = z.object({\n detail: z.object({\n error: z.string(),\n }),\n});\n\n// limited version of the schema, focussed on what is needed for the implementation\n// this approach limits breakages when the API changes and increases efficiency\nexport const deepInfraImageResponseSchema = z.object({\n images: z.array(z.string()),\n});\n\n// Schema for OpenAI-compatible image edit endpoint errors\nexport const deepInfraEditErrorSchema = z.object({\n error: z\n .object({\n message: z.string(),\n })\n .optional(),\n});\n\n// Schema for OpenAI-compatible image edit endpoint response\nexport const deepInfraEditResponseSchema = z.object({\n data: z.array(z.object({ b64_json: z.string() })),\n});\n\ntype DeepInfraFormDataInput = {\n model: string;\n prompt: string | undefined;\n image: Blob | Blob[];\n mask?: Blob;\n n: number;\n size: `${number}x${number}` | undefined;\n [key: string]: unknown;\n};\n\nasync function fileToBlob(file: ImageModelV3File): Promise<Blob> {\n if (file.type === 'url') {\n return downloadBlob(file.url);\n }\n\n const data =\n file.data instanceof Uint8Array\n ? file.data\n : convertBase64ToUint8Array(file.data);\n\n return new Blob([data as BlobPart], { type: file.mediaType });\n}\n","import {\n LanguageModelV3CallOptions,\n LanguageModelV3GenerateResult,\n LanguageModelV3StreamResult,\n} from '@ai-sdk/provider';\nimport { OpenAICompatibleChatLanguageModel } from '@ai-sdk/openai-compatible';\nimport { FetchFunction } from '@ai-sdk/provider-utils';\n\ntype DeepInfraChatConfig = {\n provider: string;\n url: (options: { path: string; modelId?: string }) => string;\n headers: () => Record<string, string | undefined>;\n fetch?: FetchFunction;\n};\n\nexport class DeepInfraChatLanguageModel extends OpenAICompatibleChatLanguageModel {\n constructor(modelId: string, config: DeepInfraChatConfig) {\n super(modelId, config);\n }\n\n /**\n * Fixes incorrect token usage for Gemini/Gemma models from DeepInfra.\n *\n * DeepInfra's API returns completion_tokens that don't include reasoning_tokens\n * for Gemini/Gemma models, which violates the OpenAI-compatible spec.\n * According to the spec, completion_tokens should include reasoning_tokens.\n *\n * Example of incorrect data from DeepInfra:\n * {\n * \"completion_tokens\": 84, // text-only tokens\n * \"completion_tokens_details\": {\n * \"reasoning_tokens\": 1081 // reasoning tokens not included above\n * }\n * }\n *\n * This would result in negative text tokens: 84 - 1081 = -997\n *\n * The fix: If reasoning_tokens > completion_tokens, add reasoning_tokens\n * to completion_tokens: 84 + 1081 = 1165\n */\n private fixUsageForGeminiModels(usage: any): typeof usage {\n if (!usage || !usage.completion_tokens_details?.reasoning_tokens) {\n return usage;\n }\n\n const completionTokens = usage.completion_tokens ?? 0;\n const reasoningTokens = usage.completion_tokens_details.reasoning_tokens;\n\n // If reasoning tokens exceed completion tokens, the API data is incorrect\n // DeepInfra is returning only text tokens in completion_tokens, not including reasoning\n if (reasoningTokens > completionTokens) {\n const correctedCompletionTokens = completionTokens + reasoningTokens;\n\n return {\n ...usage,\n // Add reasoning_tokens to completion_tokens to get the correct total\n completion_tokens: correctedCompletionTokens,\n // Update total_tokens if present\n total_tokens:\n usage.total_tokens != null\n ? usage.total_tokens + reasoningTokens\n : undefined,\n };\n }\n\n return usage;\n }\n\n async doGenerate(\n options: LanguageModelV3CallOptions,\n ): Promise<LanguageModelV3GenerateResult> {\n const result = await super.doGenerate(options);\n\n // Fix usage if needed\n if (result.usage?.raw) {\n const fixedRawUsage = this.fixUsageForGeminiModels(result.usage.raw);\n if (fixedRawUsage !== result.usage.raw) {\n // Recalculate usage with fixed data\n const promptTokens = fixedRawUsage.prompt_tokens ?? 0;\n const completionTokens = fixedRawUsage.completion_tokens ?? 0;\n const cacheReadTokens =\n fixedRawUsage.prompt_tokens_details?.cached_tokens ?? 0;\n const reasoningTokens =\n fixedRawUsage.completion_tokens_details?.reasoning_tokens ?? 0;\n\n return {\n ...result,\n usage: {\n inputTokens: {\n total: promptTokens,\n noCache: promptTokens - cacheReadTokens,\n cacheRead: cacheReadTokens,\n cacheWrite: undefined,\n },\n outputTokens: {\n total: completionTokens,\n text: completionTokens - reasoningTokens,\n reasoning: reasoningTokens,\n },\n raw: fixedRawUsage,\n },\n };\n }\n }\n\n return result;\n }\n\n async doStream(\n options: LanguageModelV3CallOptions,\n ): Promise<LanguageModelV3StreamResult> {\n const result = await super.doStream(options);\n\n // Wrap the stream to fix usage in the final chunk\n const originalStream = result.stream;\n const fixUsage = this.fixUsageForGeminiModels.bind(this);\n\n const transformedStream = new ReadableStream({\n async start(controller) {\n const reader = originalStream.getReader();\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n // Fix usage in finish chunks\n if (value.type === 'finish' && value.usage?.raw) {\n const fixedRawUsage = fixUsage(value.usage.raw);\n if (fixedRawUsage !== value.usage.raw) {\n const promptTokens = fixedRawUsage.prompt_tokens ?? 0;\n const completionTokens = fixedRawUsage.completion_tokens ?? 0;\n const cacheReadTokens =\n fixedRawUsage.prompt_tokens_details?.cached_tokens ?? 0;\n const reasoningTokens =\n fixedRawUsage.completion_tokens_details?.reasoning_tokens ??\n 0;\n\n controller.enqueue({\n ...value,\n usage: {\n inputTokens: {\n total: promptTokens,\n noCache: promptTokens - cacheReadTokens,\n cacheRead: cacheReadTokens,\n cacheWrite: undefined,\n },\n outputTokens: {\n total: completionTokens,\n text: completionTokens - reasoningTokens,\n reasoning: reasoningTokens,\n },\n raw: fixedRawUsage,\n },\n });\n } else {\n controller.enqueue(value);\n }\n } else {\n controller.enqueue(value);\n }\n }\n controller.close();\n } catch (error) {\n controller.error(error);\n }\n },\n });\n\n return {\n ...result,\n stream: transformedStream,\n };\n }\n}\n","// Version string of this package injected at build time.\ndeclare const __PACKAGE_VERSION__: string | undefined;\nexport const VERSION: string =\n typeof __PACKAGE_VERSION__ !== 'undefined'\n ? __PACKAGE_VERSION__\n : '0.0.0-test';\n"],"mappings":"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","names":["import_openai_compatible","import_provider_utils","response","responseHeaders","_a","_b"]}
|
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
// src/deepinfra-provider.ts
|
|
2
2
|
import {
|
|
3
|
-
OpenAICompatibleChatLanguageModel,
|
|
4
3
|
OpenAICompatibleCompletionLanguageModel,
|
|
5
4
|
OpenAICompatibleEmbeddingModel
|
|
6
5
|
} from "@ai-sdk/openai-compatible";
|
|
@@ -149,8 +148,140 @@ async function fileToBlob(file) {
|
|
|
149
148
|
return new Blob([data], { type: file.mediaType });
|
|
150
149
|
}
|
|
151
150
|
|
|
151
|
+
// src/deepinfra-chat-language-model.ts
|
|
152
|
+
import { OpenAICompatibleChatLanguageModel } from "@ai-sdk/openai-compatible";
|
|
153
|
+
var DeepInfraChatLanguageModel = class extends OpenAICompatibleChatLanguageModel {
|
|
154
|
+
constructor(modelId, config) {
|
|
155
|
+
super(modelId, config);
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Fixes incorrect token usage for Gemini/Gemma models from DeepInfra.
|
|
159
|
+
*
|
|
160
|
+
* DeepInfra's API returns completion_tokens that don't include reasoning_tokens
|
|
161
|
+
* for Gemini/Gemma models, which violates the OpenAI-compatible spec.
|
|
162
|
+
* According to the spec, completion_tokens should include reasoning_tokens.
|
|
163
|
+
*
|
|
164
|
+
* Example of incorrect data from DeepInfra:
|
|
165
|
+
* {
|
|
166
|
+
* "completion_tokens": 84, // text-only tokens
|
|
167
|
+
* "completion_tokens_details": {
|
|
168
|
+
* "reasoning_tokens": 1081 // reasoning tokens not included above
|
|
169
|
+
* }
|
|
170
|
+
* }
|
|
171
|
+
*
|
|
172
|
+
* This would result in negative text tokens: 84 - 1081 = -997
|
|
173
|
+
*
|
|
174
|
+
* The fix: If reasoning_tokens > completion_tokens, add reasoning_tokens
|
|
175
|
+
* to completion_tokens: 84 + 1081 = 1165
|
|
176
|
+
*/
|
|
177
|
+
fixUsageForGeminiModels(usage) {
|
|
178
|
+
var _a, _b;
|
|
179
|
+
if (!usage || !((_a = usage.completion_tokens_details) == null ? void 0 : _a.reasoning_tokens)) {
|
|
180
|
+
return usage;
|
|
181
|
+
}
|
|
182
|
+
const completionTokens = (_b = usage.completion_tokens) != null ? _b : 0;
|
|
183
|
+
const reasoningTokens = usage.completion_tokens_details.reasoning_tokens;
|
|
184
|
+
if (reasoningTokens > completionTokens) {
|
|
185
|
+
const correctedCompletionTokens = completionTokens + reasoningTokens;
|
|
186
|
+
return {
|
|
187
|
+
...usage,
|
|
188
|
+
// Add reasoning_tokens to completion_tokens to get the correct total
|
|
189
|
+
completion_tokens: correctedCompletionTokens,
|
|
190
|
+
// Update total_tokens if present
|
|
191
|
+
total_tokens: usage.total_tokens != null ? usage.total_tokens + reasoningTokens : void 0
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
return usage;
|
|
195
|
+
}
|
|
196
|
+
async doGenerate(options) {
|
|
197
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
198
|
+
const result = await super.doGenerate(options);
|
|
199
|
+
if ((_a = result.usage) == null ? void 0 : _a.raw) {
|
|
200
|
+
const fixedRawUsage = this.fixUsageForGeminiModels(result.usage.raw);
|
|
201
|
+
if (fixedRawUsage !== result.usage.raw) {
|
|
202
|
+
const promptTokens = (_b = fixedRawUsage.prompt_tokens) != null ? _b : 0;
|
|
203
|
+
const completionTokens = (_c = fixedRawUsage.completion_tokens) != null ? _c : 0;
|
|
204
|
+
const cacheReadTokens = (_e = (_d = fixedRawUsage.prompt_tokens_details) == null ? void 0 : _d.cached_tokens) != null ? _e : 0;
|
|
205
|
+
const reasoningTokens = (_g = (_f = fixedRawUsage.completion_tokens_details) == null ? void 0 : _f.reasoning_tokens) != null ? _g : 0;
|
|
206
|
+
return {
|
|
207
|
+
...result,
|
|
208
|
+
usage: {
|
|
209
|
+
inputTokens: {
|
|
210
|
+
total: promptTokens,
|
|
211
|
+
noCache: promptTokens - cacheReadTokens,
|
|
212
|
+
cacheRead: cacheReadTokens,
|
|
213
|
+
cacheWrite: void 0
|
|
214
|
+
},
|
|
215
|
+
outputTokens: {
|
|
216
|
+
total: completionTokens,
|
|
217
|
+
text: completionTokens - reasoningTokens,
|
|
218
|
+
reasoning: reasoningTokens
|
|
219
|
+
},
|
|
220
|
+
raw: fixedRawUsage
|
|
221
|
+
}
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
return result;
|
|
226
|
+
}
|
|
227
|
+
async doStream(options) {
|
|
228
|
+
const result = await super.doStream(options);
|
|
229
|
+
const originalStream = result.stream;
|
|
230
|
+
const fixUsage = this.fixUsageForGeminiModels.bind(this);
|
|
231
|
+
const transformedStream = new ReadableStream({
|
|
232
|
+
async start(controller) {
|
|
233
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
234
|
+
const reader = originalStream.getReader();
|
|
235
|
+
try {
|
|
236
|
+
while (true) {
|
|
237
|
+
const { done, value } = await reader.read();
|
|
238
|
+
if (done) break;
|
|
239
|
+
if (value.type === "finish" && ((_a = value.usage) == null ? void 0 : _a.raw)) {
|
|
240
|
+
const fixedRawUsage = fixUsage(value.usage.raw);
|
|
241
|
+
if (fixedRawUsage !== value.usage.raw) {
|
|
242
|
+
const promptTokens = (_b = fixedRawUsage.prompt_tokens) != null ? _b : 0;
|
|
243
|
+
const completionTokens = (_c = fixedRawUsage.completion_tokens) != null ? _c : 0;
|
|
244
|
+
const cacheReadTokens = (_e = (_d = fixedRawUsage.prompt_tokens_details) == null ? void 0 : _d.cached_tokens) != null ? _e : 0;
|
|
245
|
+
const reasoningTokens = (_g = (_f = fixedRawUsage.completion_tokens_details) == null ? void 0 : _f.reasoning_tokens) != null ? _g : 0;
|
|
246
|
+
controller.enqueue({
|
|
247
|
+
...value,
|
|
248
|
+
usage: {
|
|
249
|
+
inputTokens: {
|
|
250
|
+
total: promptTokens,
|
|
251
|
+
noCache: promptTokens - cacheReadTokens,
|
|
252
|
+
cacheRead: cacheReadTokens,
|
|
253
|
+
cacheWrite: void 0
|
|
254
|
+
},
|
|
255
|
+
outputTokens: {
|
|
256
|
+
total: completionTokens,
|
|
257
|
+
text: completionTokens - reasoningTokens,
|
|
258
|
+
reasoning: reasoningTokens
|
|
259
|
+
},
|
|
260
|
+
raw: fixedRawUsage
|
|
261
|
+
}
|
|
262
|
+
});
|
|
263
|
+
} else {
|
|
264
|
+
controller.enqueue(value);
|
|
265
|
+
}
|
|
266
|
+
} else {
|
|
267
|
+
controller.enqueue(value);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
controller.close();
|
|
271
|
+
} catch (error) {
|
|
272
|
+
controller.error(error);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
});
|
|
276
|
+
return {
|
|
277
|
+
...result,
|
|
278
|
+
stream: transformedStream
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
};
|
|
282
|
+
|
|
152
283
|
// src/version.ts
|
|
153
|
-
var VERSION = true ? "2.0.
|
|
284
|
+
var VERSION = true ? "2.0.30" : "0.0.0-test";
|
|
154
285
|
|
|
155
286
|
// src/deepinfra-provider.ts
|
|
156
287
|
function createDeepInfra(options = {}) {
|
|
@@ -176,7 +307,7 @@ function createDeepInfra(options = {}) {
|
|
|
176
307
|
fetch: options.fetch
|
|
177
308
|
});
|
|
178
309
|
const createChatModel = (modelId) => {
|
|
179
|
-
return new
|
|
310
|
+
return new DeepInfraChatLanguageModel(
|
|
180
311
|
modelId,
|
|
181
312
|
getCommonModelConfig("chat")
|
|
182
313
|
);
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/deepinfra-provider.ts","../src/deepinfra-image-model.ts","../src/version.ts"],"sourcesContent":["import {\n LanguageModelV3,\n EmbeddingModelV3,\n ProviderV3,\n ImageModelV3,\n} from '@ai-sdk/provider';\nimport {\n OpenAICompatibleChatLanguageModel,\n OpenAICompatibleCompletionLanguageModel,\n OpenAICompatibleEmbeddingModel,\n} from '@ai-sdk/openai-compatible';\nimport {\n FetchFunction,\n loadApiKey,\n withoutTrailingSlash,\n withUserAgentSuffix,\n} from '@ai-sdk/provider-utils';\nimport { DeepInfraChatModelId } from './deepinfra-chat-options';\nimport { DeepInfraEmbeddingModelId } from './deepinfra-embedding-options';\nimport { DeepInfraCompletionModelId } from './deepinfra-completion-options';\nimport { DeepInfraImageModelId } from './deepinfra-image-settings';\nimport { DeepInfraImageModel } from './deepinfra-image-model';\nimport { VERSION } from './version';\n\nexport interface DeepInfraProviderSettings {\n /**\n * DeepInfra API key.\n */\n apiKey?: string;\n /**\n * Base URL for the API calls.\n */\n baseURL?: string;\n /**\n * Custom headers to include in the requests.\n */\n headers?: Record<string, string>;\n /**\n * Custom fetch implementation. You can use it as a middleware to intercept requests,\n * or to provide a custom fetch implementation for e.g. testing.\n */\n fetch?: FetchFunction;\n}\n\nexport interface DeepInfraProvider extends ProviderV3 {\n /**\n * Creates a model for text generation.\n */\n (modelId: DeepInfraChatModelId): LanguageModelV3;\n\n /**\n * Creates a chat model for text generation.\n */\n chatModel(modelId: DeepInfraChatModelId): LanguageModelV3;\n\n /**\n * Creates a model for image generation.\n */\n image(modelId: DeepInfraImageModelId): ImageModelV3;\n\n /**\n * Creates a model for image generation.\n */\n imageModel(modelId: DeepInfraImageModelId): ImageModelV3;\n\n /**\n * Creates a chat model for text generation.\n */\n languageModel(modelId: DeepInfraChatModelId): LanguageModelV3;\n\n /**\n * Creates a completion model for text generation.\n */\n completionModel(modelId: DeepInfraCompletionModelId): LanguageModelV3;\n\n /**\n * Creates a embedding model for text generation.\n */\n embeddingModel(modelId: DeepInfraEmbeddingModelId): EmbeddingModelV3;\n\n /**\n * @deprecated Use `embeddingModel` instead.\n */\n textEmbeddingModel(modelId: DeepInfraEmbeddingModelId): EmbeddingModelV3;\n}\n\nexport function createDeepInfra(\n options: DeepInfraProviderSettings = {},\n): DeepInfraProvider {\n const baseURL = withoutTrailingSlash(\n options.baseURL ?? 'https://api.deepinfra.com/v1',\n );\n const getHeaders = () =>\n withUserAgentSuffix(\n {\n Authorization: `Bearer ${loadApiKey({\n apiKey: options.apiKey,\n environmentVariableName: 'DEEPINFRA_API_KEY',\n description: \"DeepInfra's API key\",\n })}`,\n ...options.headers,\n },\n `ai-sdk/deepinfra/${VERSION}`,\n );\n\n interface CommonModelConfig {\n provider: string;\n url: ({ path }: { path: string }) => string;\n headers: () => Record<string, string>;\n fetch?: FetchFunction;\n }\n\n const getCommonModelConfig = (modelType: string): CommonModelConfig => ({\n provider: `deepinfra.${modelType}`,\n url: ({ path }) => `${baseURL}/openai${path}`,\n headers: getHeaders,\n fetch: options.fetch,\n });\n\n const createChatModel = (modelId: DeepInfraChatModelId) => {\n return new OpenAICompatibleChatLanguageModel(\n modelId,\n getCommonModelConfig('chat'),\n );\n };\n\n const createCompletionModel = (modelId: DeepInfraCompletionModelId) =>\n new OpenAICompatibleCompletionLanguageModel(\n modelId,\n getCommonModelConfig('completion'),\n );\n\n const createEmbeddingModel = (modelId: DeepInfraEmbeddingModelId) =>\n new OpenAICompatibleEmbeddingModel(\n modelId,\n getCommonModelConfig('embedding'),\n );\n\n const createImageModel = (modelId: DeepInfraImageModelId) =>\n new DeepInfraImageModel(modelId, {\n ...getCommonModelConfig('image'),\n baseURL: baseURL\n ? `${baseURL}/inference`\n : 'https://api.deepinfra.com/v1/inference',\n });\n\n const provider = (modelId: DeepInfraChatModelId) => createChatModel(modelId);\n\n provider.specificationVersion = 'v3' as const;\n provider.completionModel = createCompletionModel;\n provider.chatModel = createChatModel;\n provider.image = createImageModel;\n provider.imageModel = createImageModel;\n provider.languageModel = createChatModel;\n provider.embeddingModel = createEmbeddingModel;\n provider.textEmbeddingModel = createEmbeddingModel;\n\n return provider;\n}\n\nexport const deepinfra = createDeepInfra();\n","import {\n ImageModelV3,\n ImageModelV3File,\n SharedV3Warning,\n} from '@ai-sdk/provider';\nimport {\n combineHeaders,\n convertBase64ToUint8Array,\n convertToFormData,\n createJsonErrorResponseHandler,\n createJsonResponseHandler,\n downloadBlob,\n FetchFunction,\n postFormDataToApi,\n postJsonToApi,\n} from '@ai-sdk/provider-utils';\nimport { DeepInfraImageModelId } from './deepinfra-image-settings';\nimport { z } from 'zod/v4';\n\ninterface DeepInfraImageModelConfig {\n provider: string;\n baseURL: string;\n headers: () => Record<string, string>;\n fetch?: FetchFunction;\n _internal?: {\n currentDate?: () => Date;\n };\n}\n\nexport class DeepInfraImageModel implements ImageModelV3 {\n readonly specificationVersion = 'v3';\n readonly maxImagesPerCall = 1;\n\n get provider(): string {\n return this.config.provider;\n }\n\n constructor(\n readonly modelId: DeepInfraImageModelId,\n private config: DeepInfraImageModelConfig,\n ) {}\n\n async doGenerate({\n prompt,\n n,\n size,\n aspectRatio,\n seed,\n providerOptions,\n headers,\n abortSignal,\n files,\n mask,\n }: Parameters<ImageModelV3['doGenerate']>[0]): Promise<\n Awaited<ReturnType<ImageModelV3['doGenerate']>>\n > {\n const warnings: Array<SharedV3Warning> = [];\n const currentDate = this.config._internal?.currentDate?.() ?? new Date();\n\n // Image editing mode - use OpenAI-compatible /images/edits endpoint\n if (files != null && files.length > 0) {\n const { value: response, responseHeaders } = await postFormDataToApi({\n url: this.getEditUrl(),\n headers: combineHeaders(this.config.headers(), headers),\n formData: convertToFormData<DeepInfraFormDataInput>(\n {\n model: this.modelId,\n prompt,\n image: await Promise.all(files.map(file => fileToBlob(file))),\n mask: mask != null ? await fileToBlob(mask) : undefined,\n n,\n size,\n ...(providerOptions.deepinfra ?? {}),\n },\n { useArrayBrackets: false },\n ),\n failedResponseHandler: createJsonErrorResponseHandler({\n errorSchema: deepInfraEditErrorSchema,\n errorToMessage: error => error.error?.message ?? 'Unknown error',\n }),\n successfulResponseHandler: createJsonResponseHandler(\n deepInfraEditResponseSchema,\n ),\n abortSignal,\n fetch: this.config.fetch,\n });\n\n return {\n images: response.data.map(item => item.b64_json),\n warnings,\n response: {\n timestamp: currentDate,\n modelId: this.modelId,\n headers: responseHeaders,\n },\n };\n }\n\n // Standard image generation mode\n // Some deepinfra models support size while others support aspect ratio.\n // Allow passing either and leave it up to the server to validate.\n const splitSize = size?.split('x');\n const { value: response, responseHeaders } = await postJsonToApi({\n url: `${this.config.baseURL}/${this.modelId}`,\n headers: combineHeaders(this.config.headers(), headers),\n body: {\n prompt,\n num_images: n,\n ...(aspectRatio && { aspect_ratio: aspectRatio }),\n ...(splitSize && { width: splitSize[0], height: splitSize[1] }),\n ...(seed != null && { seed }),\n ...(providerOptions.deepinfra ?? {}),\n },\n failedResponseHandler: createJsonErrorResponseHandler({\n errorSchema: deepInfraErrorSchema,\n errorToMessage: error => error.detail.error,\n }),\n successfulResponseHandler: createJsonResponseHandler(\n deepInfraImageResponseSchema,\n ),\n abortSignal,\n fetch: this.config.fetch,\n });\n\n return {\n images: response.images.map(image =>\n image.replace(/^data:image\\/\\w+;base64,/, ''),\n ),\n warnings,\n response: {\n timestamp: currentDate,\n modelId: this.modelId,\n headers: responseHeaders,\n },\n };\n }\n\n private getEditUrl(): string {\n // Use OpenAI-compatible endpoint for image editing\n // baseURL is typically https://api.deepinfra.com/v1/inference\n // We need to use https://api.deepinfra.com/v1/openai/images/edits\n const baseUrl = this.config.baseURL.replace('/inference', '/openai');\n return `${baseUrl}/images/edits`;\n }\n}\n\nexport const deepInfraErrorSchema = z.object({\n detail: z.object({\n error: z.string(),\n }),\n});\n\n// limited version of the schema, focussed on what is needed for the implementation\n// this approach limits breakages when the API changes and increases efficiency\nexport const deepInfraImageResponseSchema = z.object({\n images: z.array(z.string()),\n});\n\n// Schema for OpenAI-compatible image edit endpoint errors\nexport const deepInfraEditErrorSchema = z.object({\n error: z\n .object({\n message: z.string(),\n })\n .optional(),\n});\n\n// Schema for OpenAI-compatible image edit endpoint response\nexport const deepInfraEditResponseSchema = z.object({\n data: z.array(z.object({ b64_json: z.string() })),\n});\n\ntype DeepInfraFormDataInput = {\n model: string;\n prompt: string | undefined;\n image: Blob | Blob[];\n mask?: Blob;\n n: number;\n size: `${number}x${number}` | undefined;\n [key: string]: unknown;\n};\n\nasync function fileToBlob(file: ImageModelV3File): Promise<Blob> {\n if (file.type === 'url') {\n return downloadBlob(file.url);\n }\n\n const data =\n file.data instanceof Uint8Array\n ? file.data\n : convertBase64ToUint8Array(file.data);\n\n return new Blob([data as BlobPart], { type: file.mediaType });\n}\n","// Version string of this package injected at build time.\ndeclare const __PACKAGE_VERSION__: string | undefined;\nexport const VERSION: string =\n typeof __PACKAGE_VERSION__ !== 'undefined'\n ? __PACKAGE_VERSION__\n : '0.0.0-test';\n"],"mappings":"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","names":["response","responseHeaders","_a","_b"]}
|
|
1
|
+
{"version":3,"sources":["../src/deepinfra-provider.ts","../src/deepinfra-image-model.ts","../src/deepinfra-chat-language-model.ts","../src/version.ts"],"sourcesContent":["import {\n LanguageModelV3,\n EmbeddingModelV3,\n ProviderV3,\n ImageModelV3,\n} from '@ai-sdk/provider';\nimport {\n OpenAICompatibleCompletionLanguageModel,\n OpenAICompatibleEmbeddingModel,\n} from '@ai-sdk/openai-compatible';\nimport {\n FetchFunction,\n loadApiKey,\n withoutTrailingSlash,\n withUserAgentSuffix,\n} from '@ai-sdk/provider-utils';\nimport { DeepInfraChatModelId } from './deepinfra-chat-options';\nimport { DeepInfraEmbeddingModelId } from './deepinfra-embedding-options';\nimport { DeepInfraCompletionModelId } from './deepinfra-completion-options';\nimport { DeepInfraImageModelId } from './deepinfra-image-settings';\nimport { DeepInfraImageModel } from './deepinfra-image-model';\nimport { DeepInfraChatLanguageModel } from './deepinfra-chat-language-model';\nimport { VERSION } from './version';\n\nexport interface DeepInfraProviderSettings {\n /**\n * DeepInfra API key.\n */\n apiKey?: string;\n /**\n * Base URL for the API calls.\n */\n baseURL?: string;\n /**\n * Custom headers to include in the requests.\n */\n headers?: Record<string, string>;\n /**\n * Custom fetch implementation. You can use it as a middleware to intercept requests,\n * or to provide a custom fetch implementation for e.g. testing.\n */\n fetch?: FetchFunction;\n}\n\nexport interface DeepInfraProvider extends ProviderV3 {\n /**\n * Creates a model for text generation.\n */\n (modelId: DeepInfraChatModelId): LanguageModelV3;\n\n /**\n * Creates a chat model for text generation.\n */\n chatModel(modelId: DeepInfraChatModelId): LanguageModelV3;\n\n /**\n * Creates a model for image generation.\n */\n image(modelId: DeepInfraImageModelId): ImageModelV3;\n\n /**\n * Creates a model for image generation.\n */\n imageModel(modelId: DeepInfraImageModelId): ImageModelV3;\n\n /**\n * Creates a chat model for text generation.\n */\n languageModel(modelId: DeepInfraChatModelId): LanguageModelV3;\n\n /**\n * Creates a completion model for text generation.\n */\n completionModel(modelId: DeepInfraCompletionModelId): LanguageModelV3;\n\n /**\n * Creates a embedding model for text generation.\n */\n embeddingModel(modelId: DeepInfraEmbeddingModelId): EmbeddingModelV3;\n\n /**\n * @deprecated Use `embeddingModel` instead.\n */\n textEmbeddingModel(modelId: DeepInfraEmbeddingModelId): EmbeddingModelV3;\n}\n\nexport function createDeepInfra(\n options: DeepInfraProviderSettings = {},\n): DeepInfraProvider {\n const baseURL = withoutTrailingSlash(\n options.baseURL ?? 'https://api.deepinfra.com/v1',\n );\n const getHeaders = () =>\n withUserAgentSuffix(\n {\n Authorization: `Bearer ${loadApiKey({\n apiKey: options.apiKey,\n environmentVariableName: 'DEEPINFRA_API_KEY',\n description: \"DeepInfra's API key\",\n })}`,\n ...options.headers,\n },\n `ai-sdk/deepinfra/${VERSION}`,\n );\n\n interface CommonModelConfig {\n provider: string;\n url: ({ path }: { path: string }) => string;\n headers: () => Record<string, string>;\n fetch?: FetchFunction;\n }\n\n const getCommonModelConfig = (modelType: string): CommonModelConfig => ({\n provider: `deepinfra.${modelType}`,\n url: ({ path }) => `${baseURL}/openai${path}`,\n headers: getHeaders,\n fetch: options.fetch,\n });\n\n const createChatModel = (modelId: DeepInfraChatModelId) => {\n return new DeepInfraChatLanguageModel(\n modelId,\n getCommonModelConfig('chat'),\n );\n };\n\n const createCompletionModel = (modelId: DeepInfraCompletionModelId) =>\n new OpenAICompatibleCompletionLanguageModel(\n modelId,\n getCommonModelConfig('completion'),\n );\n\n const createEmbeddingModel = (modelId: DeepInfraEmbeddingModelId) =>\n new OpenAICompatibleEmbeddingModel(\n modelId,\n getCommonModelConfig('embedding'),\n );\n\n const createImageModel = (modelId: DeepInfraImageModelId) =>\n new DeepInfraImageModel(modelId, {\n ...getCommonModelConfig('image'),\n baseURL: baseURL\n ? `${baseURL}/inference`\n : 'https://api.deepinfra.com/v1/inference',\n });\n\n const provider = (modelId: DeepInfraChatModelId) => createChatModel(modelId);\n\n provider.specificationVersion = 'v3' as const;\n provider.completionModel = createCompletionModel;\n provider.chatModel = createChatModel;\n provider.image = createImageModel;\n provider.imageModel = createImageModel;\n provider.languageModel = createChatModel;\n provider.embeddingModel = createEmbeddingModel;\n provider.textEmbeddingModel = createEmbeddingModel;\n\n return provider;\n}\n\nexport const deepinfra = createDeepInfra();\n","import {\n ImageModelV3,\n ImageModelV3File,\n SharedV3Warning,\n} from '@ai-sdk/provider';\nimport {\n combineHeaders,\n convertBase64ToUint8Array,\n convertToFormData,\n createJsonErrorResponseHandler,\n createJsonResponseHandler,\n downloadBlob,\n FetchFunction,\n postFormDataToApi,\n postJsonToApi,\n} from '@ai-sdk/provider-utils';\nimport { DeepInfraImageModelId } from './deepinfra-image-settings';\nimport { z } from 'zod/v4';\n\ninterface DeepInfraImageModelConfig {\n provider: string;\n baseURL: string;\n headers: () => Record<string, string>;\n fetch?: FetchFunction;\n _internal?: {\n currentDate?: () => Date;\n };\n}\n\nexport class DeepInfraImageModel implements ImageModelV3 {\n readonly specificationVersion = 'v3';\n readonly maxImagesPerCall = 1;\n\n get provider(): string {\n return this.config.provider;\n }\n\n constructor(\n readonly modelId: DeepInfraImageModelId,\n private config: DeepInfraImageModelConfig,\n ) {}\n\n async doGenerate({\n prompt,\n n,\n size,\n aspectRatio,\n seed,\n providerOptions,\n headers,\n abortSignal,\n files,\n mask,\n }: Parameters<ImageModelV3['doGenerate']>[0]): Promise<\n Awaited<ReturnType<ImageModelV3['doGenerate']>>\n > {\n const warnings: Array<SharedV3Warning> = [];\n const currentDate = this.config._internal?.currentDate?.() ?? new Date();\n\n // Image editing mode - use OpenAI-compatible /images/edits endpoint\n if (files != null && files.length > 0) {\n const { value: response, responseHeaders } = await postFormDataToApi({\n url: this.getEditUrl(),\n headers: combineHeaders(this.config.headers(), headers),\n formData: convertToFormData<DeepInfraFormDataInput>(\n {\n model: this.modelId,\n prompt,\n image: await Promise.all(files.map(file => fileToBlob(file))),\n mask: mask != null ? await fileToBlob(mask) : undefined,\n n,\n size,\n ...(providerOptions.deepinfra ?? {}),\n },\n { useArrayBrackets: false },\n ),\n failedResponseHandler: createJsonErrorResponseHandler({\n errorSchema: deepInfraEditErrorSchema,\n errorToMessage: error => error.error?.message ?? 'Unknown error',\n }),\n successfulResponseHandler: createJsonResponseHandler(\n deepInfraEditResponseSchema,\n ),\n abortSignal,\n fetch: this.config.fetch,\n });\n\n return {\n images: response.data.map(item => item.b64_json),\n warnings,\n response: {\n timestamp: currentDate,\n modelId: this.modelId,\n headers: responseHeaders,\n },\n };\n }\n\n // Standard image generation mode\n // Some deepinfra models support size while others support aspect ratio.\n // Allow passing either and leave it up to the server to validate.\n const splitSize = size?.split('x');\n const { value: response, responseHeaders } = await postJsonToApi({\n url: `${this.config.baseURL}/${this.modelId}`,\n headers: combineHeaders(this.config.headers(), headers),\n body: {\n prompt,\n num_images: n,\n ...(aspectRatio && { aspect_ratio: aspectRatio }),\n ...(splitSize && { width: splitSize[0], height: splitSize[1] }),\n ...(seed != null && { seed }),\n ...(providerOptions.deepinfra ?? {}),\n },\n failedResponseHandler: createJsonErrorResponseHandler({\n errorSchema: deepInfraErrorSchema,\n errorToMessage: error => error.detail.error,\n }),\n successfulResponseHandler: createJsonResponseHandler(\n deepInfraImageResponseSchema,\n ),\n abortSignal,\n fetch: this.config.fetch,\n });\n\n return {\n images: response.images.map(image =>\n image.replace(/^data:image\\/\\w+;base64,/, ''),\n ),\n warnings,\n response: {\n timestamp: currentDate,\n modelId: this.modelId,\n headers: responseHeaders,\n },\n };\n }\n\n private getEditUrl(): string {\n // Use OpenAI-compatible endpoint for image editing\n // baseURL is typically https://api.deepinfra.com/v1/inference\n // We need to use https://api.deepinfra.com/v1/openai/images/edits\n const baseUrl = this.config.baseURL.replace('/inference', '/openai');\n return `${baseUrl}/images/edits`;\n }\n}\n\nexport const deepInfraErrorSchema = z.object({\n detail: z.object({\n error: z.string(),\n }),\n});\n\n// limited version of the schema, focussed on what is needed for the implementation\n// this approach limits breakages when the API changes and increases efficiency\nexport const deepInfraImageResponseSchema = z.object({\n images: z.array(z.string()),\n});\n\n// Schema for OpenAI-compatible image edit endpoint errors\nexport const deepInfraEditErrorSchema = z.object({\n error: z\n .object({\n message: z.string(),\n })\n .optional(),\n});\n\n// Schema for OpenAI-compatible image edit endpoint response\nexport const deepInfraEditResponseSchema = z.object({\n data: z.array(z.object({ b64_json: z.string() })),\n});\n\ntype DeepInfraFormDataInput = {\n model: string;\n prompt: string | undefined;\n image: Blob | Blob[];\n mask?: Blob;\n n: number;\n size: `${number}x${number}` | undefined;\n [key: string]: unknown;\n};\n\nasync function fileToBlob(file: ImageModelV3File): Promise<Blob> {\n if (file.type === 'url') {\n return downloadBlob(file.url);\n }\n\n const data =\n file.data instanceof Uint8Array\n ? file.data\n : convertBase64ToUint8Array(file.data);\n\n return new Blob([data as BlobPart], { type: file.mediaType });\n}\n","import {\n LanguageModelV3CallOptions,\n LanguageModelV3GenerateResult,\n LanguageModelV3StreamResult,\n} from '@ai-sdk/provider';\nimport { OpenAICompatibleChatLanguageModel } from '@ai-sdk/openai-compatible';\nimport { FetchFunction } from '@ai-sdk/provider-utils';\n\ntype DeepInfraChatConfig = {\n provider: string;\n url: (options: { path: string; modelId?: string }) => string;\n headers: () => Record<string, string | undefined>;\n fetch?: FetchFunction;\n};\n\nexport class DeepInfraChatLanguageModel extends OpenAICompatibleChatLanguageModel {\n constructor(modelId: string, config: DeepInfraChatConfig) {\n super(modelId, config);\n }\n\n /**\n * Fixes incorrect token usage for Gemini/Gemma models from DeepInfra.\n *\n * DeepInfra's API returns completion_tokens that don't include reasoning_tokens\n * for Gemini/Gemma models, which violates the OpenAI-compatible spec.\n * According to the spec, completion_tokens should include reasoning_tokens.\n *\n * Example of incorrect data from DeepInfra:\n * {\n * \"completion_tokens\": 84, // text-only tokens\n * \"completion_tokens_details\": {\n * \"reasoning_tokens\": 1081 // reasoning tokens not included above\n * }\n * }\n *\n * This would result in negative text tokens: 84 - 1081 = -997\n *\n * The fix: If reasoning_tokens > completion_tokens, add reasoning_tokens\n * to completion_tokens: 84 + 1081 = 1165\n */\n private fixUsageForGeminiModels(usage: any): typeof usage {\n if (!usage || !usage.completion_tokens_details?.reasoning_tokens) {\n return usage;\n }\n\n const completionTokens = usage.completion_tokens ?? 0;\n const reasoningTokens = usage.completion_tokens_details.reasoning_tokens;\n\n // If reasoning tokens exceed completion tokens, the API data is incorrect\n // DeepInfra is returning only text tokens in completion_tokens, not including reasoning\n if (reasoningTokens > completionTokens) {\n const correctedCompletionTokens = completionTokens + reasoningTokens;\n\n return {\n ...usage,\n // Add reasoning_tokens to completion_tokens to get the correct total\n completion_tokens: correctedCompletionTokens,\n // Update total_tokens if present\n total_tokens:\n usage.total_tokens != null\n ? usage.total_tokens + reasoningTokens\n : undefined,\n };\n }\n\n return usage;\n }\n\n async doGenerate(\n options: LanguageModelV3CallOptions,\n ): Promise<LanguageModelV3GenerateResult> {\n const result = await super.doGenerate(options);\n\n // Fix usage if needed\n if (result.usage?.raw) {\n const fixedRawUsage = this.fixUsageForGeminiModels(result.usage.raw);\n if (fixedRawUsage !== result.usage.raw) {\n // Recalculate usage with fixed data\n const promptTokens = fixedRawUsage.prompt_tokens ?? 0;\n const completionTokens = fixedRawUsage.completion_tokens ?? 0;\n const cacheReadTokens =\n fixedRawUsage.prompt_tokens_details?.cached_tokens ?? 0;\n const reasoningTokens =\n fixedRawUsage.completion_tokens_details?.reasoning_tokens ?? 0;\n\n return {\n ...result,\n usage: {\n inputTokens: {\n total: promptTokens,\n noCache: promptTokens - cacheReadTokens,\n cacheRead: cacheReadTokens,\n cacheWrite: undefined,\n },\n outputTokens: {\n total: completionTokens,\n text: completionTokens - reasoningTokens,\n reasoning: reasoningTokens,\n },\n raw: fixedRawUsage,\n },\n };\n }\n }\n\n return result;\n }\n\n async doStream(\n options: LanguageModelV3CallOptions,\n ): Promise<LanguageModelV3StreamResult> {\n const result = await super.doStream(options);\n\n // Wrap the stream to fix usage in the final chunk\n const originalStream = result.stream;\n const fixUsage = this.fixUsageForGeminiModels.bind(this);\n\n const transformedStream = new ReadableStream({\n async start(controller) {\n const reader = originalStream.getReader();\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n // Fix usage in finish chunks\n if (value.type === 'finish' && value.usage?.raw) {\n const fixedRawUsage = fixUsage(value.usage.raw);\n if (fixedRawUsage !== value.usage.raw) {\n const promptTokens = fixedRawUsage.prompt_tokens ?? 0;\n const completionTokens = fixedRawUsage.completion_tokens ?? 0;\n const cacheReadTokens =\n fixedRawUsage.prompt_tokens_details?.cached_tokens ?? 0;\n const reasoningTokens =\n fixedRawUsage.completion_tokens_details?.reasoning_tokens ??\n 0;\n\n controller.enqueue({\n ...value,\n usage: {\n inputTokens: {\n total: promptTokens,\n noCache: promptTokens - cacheReadTokens,\n cacheRead: cacheReadTokens,\n cacheWrite: undefined,\n },\n outputTokens: {\n total: completionTokens,\n text: completionTokens - reasoningTokens,\n reasoning: reasoningTokens,\n },\n raw: fixedRawUsage,\n },\n });\n } else {\n controller.enqueue(value);\n }\n } else {\n controller.enqueue(value);\n }\n }\n controller.close();\n } catch (error) {\n controller.error(error);\n }\n },\n });\n\n return {\n ...result,\n stream: transformedStream,\n };\n }\n}\n","// Version string of this package injected at build time.\ndeclare const __PACKAGE_VERSION__: string | undefined;\nexport const VERSION: string =\n typeof __PACKAGE_VERSION__ !== 'undefined'\n ? __PACKAGE_VERSION__\n : '0.0.0-test';\n"],"mappings":"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","names":["response","responseHeaders","_a","_b"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-sdk/deepinfra",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.30",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -30,8 +30,8 @@
|
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
32
|
"@ai-sdk/openai-compatible": "2.0.26",
|
|
33
|
-
"@ai-sdk/provider": "
|
|
34
|
-
"@ai-sdk/provider
|
|
33
|
+
"@ai-sdk/provider-utils": "4.0.13",
|
|
34
|
+
"@ai-sdk/provider": "3.0.7"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
37
|
"@types/node": "20.17.24",
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import {
|
|
2
|
+
LanguageModelV3CallOptions,
|
|
3
|
+
LanguageModelV3GenerateResult,
|
|
4
|
+
LanguageModelV3StreamResult,
|
|
5
|
+
} from '@ai-sdk/provider';
|
|
6
|
+
import { OpenAICompatibleChatLanguageModel } from '@ai-sdk/openai-compatible';
|
|
7
|
+
import { FetchFunction } from '@ai-sdk/provider-utils';
|
|
8
|
+
|
|
9
|
+
type DeepInfraChatConfig = {
|
|
10
|
+
provider: string;
|
|
11
|
+
url: (options: { path: string; modelId?: string }) => string;
|
|
12
|
+
headers: () => Record<string, string | undefined>;
|
|
13
|
+
fetch?: FetchFunction;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export class DeepInfraChatLanguageModel extends OpenAICompatibleChatLanguageModel {
|
|
17
|
+
constructor(modelId: string, config: DeepInfraChatConfig) {
|
|
18
|
+
super(modelId, config);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Fixes incorrect token usage for Gemini/Gemma models from DeepInfra.
|
|
23
|
+
*
|
|
24
|
+
* DeepInfra's API returns completion_tokens that don't include reasoning_tokens
|
|
25
|
+
* for Gemini/Gemma models, which violates the OpenAI-compatible spec.
|
|
26
|
+
* According to the spec, completion_tokens should include reasoning_tokens.
|
|
27
|
+
*
|
|
28
|
+
* Example of incorrect data from DeepInfra:
|
|
29
|
+
* {
|
|
30
|
+
* "completion_tokens": 84, // text-only tokens
|
|
31
|
+
* "completion_tokens_details": {
|
|
32
|
+
* "reasoning_tokens": 1081 // reasoning tokens not included above
|
|
33
|
+
* }
|
|
34
|
+
* }
|
|
35
|
+
*
|
|
36
|
+
* This would result in negative text tokens: 84 - 1081 = -997
|
|
37
|
+
*
|
|
38
|
+
* The fix: If reasoning_tokens > completion_tokens, add reasoning_tokens
|
|
39
|
+
* to completion_tokens: 84 + 1081 = 1165
|
|
40
|
+
*/
|
|
41
|
+
private fixUsageForGeminiModels(usage: any): typeof usage {
|
|
42
|
+
if (!usage || !usage.completion_tokens_details?.reasoning_tokens) {
|
|
43
|
+
return usage;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const completionTokens = usage.completion_tokens ?? 0;
|
|
47
|
+
const reasoningTokens = usage.completion_tokens_details.reasoning_tokens;
|
|
48
|
+
|
|
49
|
+
// If reasoning tokens exceed completion tokens, the API data is incorrect
|
|
50
|
+
// DeepInfra is returning only text tokens in completion_tokens, not including reasoning
|
|
51
|
+
if (reasoningTokens > completionTokens) {
|
|
52
|
+
const correctedCompletionTokens = completionTokens + reasoningTokens;
|
|
53
|
+
|
|
54
|
+
return {
|
|
55
|
+
...usage,
|
|
56
|
+
// Add reasoning_tokens to completion_tokens to get the correct total
|
|
57
|
+
completion_tokens: correctedCompletionTokens,
|
|
58
|
+
// Update total_tokens if present
|
|
59
|
+
total_tokens:
|
|
60
|
+
usage.total_tokens != null
|
|
61
|
+
? usage.total_tokens + reasoningTokens
|
|
62
|
+
: undefined,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return usage;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
async doGenerate(
|
|
70
|
+
options: LanguageModelV3CallOptions,
|
|
71
|
+
): Promise<LanguageModelV3GenerateResult> {
|
|
72
|
+
const result = await super.doGenerate(options);
|
|
73
|
+
|
|
74
|
+
// Fix usage if needed
|
|
75
|
+
if (result.usage?.raw) {
|
|
76
|
+
const fixedRawUsage = this.fixUsageForGeminiModels(result.usage.raw);
|
|
77
|
+
if (fixedRawUsage !== result.usage.raw) {
|
|
78
|
+
// Recalculate usage with fixed data
|
|
79
|
+
const promptTokens = fixedRawUsage.prompt_tokens ?? 0;
|
|
80
|
+
const completionTokens = fixedRawUsage.completion_tokens ?? 0;
|
|
81
|
+
const cacheReadTokens =
|
|
82
|
+
fixedRawUsage.prompt_tokens_details?.cached_tokens ?? 0;
|
|
83
|
+
const reasoningTokens =
|
|
84
|
+
fixedRawUsage.completion_tokens_details?.reasoning_tokens ?? 0;
|
|
85
|
+
|
|
86
|
+
return {
|
|
87
|
+
...result,
|
|
88
|
+
usage: {
|
|
89
|
+
inputTokens: {
|
|
90
|
+
total: promptTokens,
|
|
91
|
+
noCache: promptTokens - cacheReadTokens,
|
|
92
|
+
cacheRead: cacheReadTokens,
|
|
93
|
+
cacheWrite: undefined,
|
|
94
|
+
},
|
|
95
|
+
outputTokens: {
|
|
96
|
+
total: completionTokens,
|
|
97
|
+
text: completionTokens - reasoningTokens,
|
|
98
|
+
reasoning: reasoningTokens,
|
|
99
|
+
},
|
|
100
|
+
raw: fixedRawUsage,
|
|
101
|
+
},
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return result;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
async doStream(
|
|
110
|
+
options: LanguageModelV3CallOptions,
|
|
111
|
+
): Promise<LanguageModelV3StreamResult> {
|
|
112
|
+
const result = await super.doStream(options);
|
|
113
|
+
|
|
114
|
+
// Wrap the stream to fix usage in the final chunk
|
|
115
|
+
const originalStream = result.stream;
|
|
116
|
+
const fixUsage = this.fixUsageForGeminiModels.bind(this);
|
|
117
|
+
|
|
118
|
+
const transformedStream = new ReadableStream({
|
|
119
|
+
async start(controller) {
|
|
120
|
+
const reader = originalStream.getReader();
|
|
121
|
+
try {
|
|
122
|
+
while (true) {
|
|
123
|
+
const { done, value } = await reader.read();
|
|
124
|
+
if (done) break;
|
|
125
|
+
|
|
126
|
+
// Fix usage in finish chunks
|
|
127
|
+
if (value.type === 'finish' && value.usage?.raw) {
|
|
128
|
+
const fixedRawUsage = fixUsage(value.usage.raw);
|
|
129
|
+
if (fixedRawUsage !== value.usage.raw) {
|
|
130
|
+
const promptTokens = fixedRawUsage.prompt_tokens ?? 0;
|
|
131
|
+
const completionTokens = fixedRawUsage.completion_tokens ?? 0;
|
|
132
|
+
const cacheReadTokens =
|
|
133
|
+
fixedRawUsage.prompt_tokens_details?.cached_tokens ?? 0;
|
|
134
|
+
const reasoningTokens =
|
|
135
|
+
fixedRawUsage.completion_tokens_details?.reasoning_tokens ??
|
|
136
|
+
0;
|
|
137
|
+
|
|
138
|
+
controller.enqueue({
|
|
139
|
+
...value,
|
|
140
|
+
usage: {
|
|
141
|
+
inputTokens: {
|
|
142
|
+
total: promptTokens,
|
|
143
|
+
noCache: promptTokens - cacheReadTokens,
|
|
144
|
+
cacheRead: cacheReadTokens,
|
|
145
|
+
cacheWrite: undefined,
|
|
146
|
+
},
|
|
147
|
+
outputTokens: {
|
|
148
|
+
total: completionTokens,
|
|
149
|
+
text: completionTokens - reasoningTokens,
|
|
150
|
+
reasoning: reasoningTokens,
|
|
151
|
+
},
|
|
152
|
+
raw: fixedRawUsage,
|
|
153
|
+
},
|
|
154
|
+
});
|
|
155
|
+
} else {
|
|
156
|
+
controller.enqueue(value);
|
|
157
|
+
}
|
|
158
|
+
} else {
|
|
159
|
+
controller.enqueue(value);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
controller.close();
|
|
163
|
+
} catch (error) {
|
|
164
|
+
controller.error(error);
|
|
165
|
+
}
|
|
166
|
+
},
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
return {
|
|
170
|
+
...result,
|
|
171
|
+
stream: transformedStream,
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
}
|
|
@@ -5,7 +5,6 @@ import {
|
|
|
5
5
|
ImageModelV3,
|
|
6
6
|
} from '@ai-sdk/provider';
|
|
7
7
|
import {
|
|
8
|
-
OpenAICompatibleChatLanguageModel,
|
|
9
8
|
OpenAICompatibleCompletionLanguageModel,
|
|
10
9
|
OpenAICompatibleEmbeddingModel,
|
|
11
10
|
} from '@ai-sdk/openai-compatible';
|
|
@@ -20,6 +19,7 @@ import { DeepInfraEmbeddingModelId } from './deepinfra-embedding-options';
|
|
|
20
19
|
import { DeepInfraCompletionModelId } from './deepinfra-completion-options';
|
|
21
20
|
import { DeepInfraImageModelId } from './deepinfra-image-settings';
|
|
22
21
|
import { DeepInfraImageModel } from './deepinfra-image-model';
|
|
22
|
+
import { DeepInfraChatLanguageModel } from './deepinfra-chat-language-model';
|
|
23
23
|
import { VERSION } from './version';
|
|
24
24
|
|
|
25
25
|
export interface DeepInfraProviderSettings {
|
|
@@ -118,7 +118,7 @@ export function createDeepInfra(
|
|
|
118
118
|
});
|
|
119
119
|
|
|
120
120
|
const createChatModel = (modelId: DeepInfraChatModelId) => {
|
|
121
|
-
return new
|
|
121
|
+
return new DeepInfraChatLanguageModel(
|
|
122
122
|
modelId,
|
|
123
123
|
getCommonModelConfig('chat'),
|
|
124
124
|
);
|