@aihubmix/ai-sdk-provider
Version:
<div align="center"> <a href="README.md">πΊπΈ English</a> | <a href="README.zh.md">π¨π³ δΈζ</a> | <a href="README.ja.md">π―π΅ ζ₯ζ¬θͺ</a> </div>
478 lines (471 loc) β’ 15.8 kB
JavaScript
// src/aihubmix-provider.ts
import {
OpenAICompatibleChatLanguageModel,
OpenAICompatibleCompletionLanguageModel,
OpenAICompatibleEmbeddingModel,
OpenAICompatibleImageModel
} from "@ai-sdk/openai-compatible";
import {
OpenAIResponsesLanguageModel,
OpenAITranscriptionModel,
OpenAISpeechModel
} from "@ai-sdk/openai/internal";
import { AnthropicMessagesLanguageModel } from "@ai-sdk/anthropic/internal";
import { GoogleGenerativeAILanguageModel } from "@ai-sdk/google/internal";
import { loadApiKey } from "@ai-sdk/provider-utils";
// src/tool/code-interpreter.ts
import { createProviderToolFactoryWithOutputSchema } from "@ai-sdk/provider-utils";
import { z } from "zod";
var codeInterpreterInputSchema = z.object({
code: z.string().nullish(),
containerId: z.string()
});
var codeInterpreterOutputSchema = z.object({
outputs: z.array(
z.discriminatedUnion("type", [
z.object({ type: z.literal("logs"), logs: z.string() }),
z.object({ type: z.literal("image"), url: z.string() })
])
).nullish()
});
var codeInterpreterArgsSchema = z.object({
container: z.union([
z.string(),
z.object({
fileIds: z.array(z.string()).optional()
})
]).optional()
});
var codeInterpreterToolFactory = createProviderToolFactoryWithOutputSchema({
id: "aihubmix.code_interpreter",
inputSchema: codeInterpreterInputSchema,
outputSchema: codeInterpreterOutputSchema
});
var codeInterpreter = (args = {}) => {
return codeInterpreterToolFactory(args);
};
// src/tool/file-search.ts
import { createProviderToolFactoryWithOutputSchema as createProviderToolFactoryWithOutputSchema2 } from "@ai-sdk/provider-utils";
import { z as z2 } from "zod";
var comparisonFilterSchema = z2.object({
key: z2.string(),
type: z2.enum(["eq", "ne", "gt", "gte", "lt", "lte"]),
value: z2.union([z2.string(), z2.number(), z2.boolean()])
});
var compoundFilterSchema = z2.object({
type: z2.enum(["and", "or"]),
filters: z2.array(
z2.union([comparisonFilterSchema, z2.lazy(() => compoundFilterSchema)])
)
});
var fileSearchArgsSchema = z2.object({
vectorStoreIds: z2.array(z2.string()),
maxNumResults: z2.number().optional(),
ranking: z2.object({
ranker: z2.string().optional(),
scoreThreshold: z2.number().optional()
}).optional(),
filters: z2.union([comparisonFilterSchema, compoundFilterSchema]).optional()
});
var fileSearchOutputSchema = z2.object({
queries: z2.array(z2.string()),
results: z2.array(
z2.object({
attributes: z2.record(z2.string(), z2.unknown()),
fileId: z2.string(),
filename: z2.string(),
score: z2.number(),
text: z2.string()
})
).nullable()
});
var fileSearch = createProviderToolFactoryWithOutputSchema2({
id: "aihubmix.file_search",
inputSchema: z2.object({}),
outputSchema: fileSearchOutputSchema
});
// src/tool/image-generation.ts
import { createProviderToolFactoryWithOutputSchema as createProviderToolFactoryWithOutputSchema3 } from "@ai-sdk/provider-utils";
import { z as z3 } from "zod";
var imageGenerationArgsSchema = z3.object({
background: z3.enum(["auto", "opaque", "transparent"]).optional(),
inputFidelity: z3.enum(["low", "high"]).optional(),
inputImageMask: z3.object({
fileId: z3.string().optional(),
imageUrl: z3.string().optional()
}).optional(),
model: z3.string().optional(),
moderation: z3.enum(["auto"]).optional(),
outputCompression: z3.number().int().min(0).max(100).optional(),
outputFormat: z3.enum(["png", "jpeg", "webp"]).optional(),
quality: z3.enum(["auto", "low", "medium", "high"]).optional(),
size: z3.enum(["1024x1024", "1024x1536", "1536x1024", "auto"]).optional()
}).strict();
var imageGenerationOutputSchema = z3.object({
result: z3.string()
});
var imageGenerationToolFactory = createProviderToolFactoryWithOutputSchema3({
id: "aihubmix.image_generation",
inputSchema: z3.object({}),
outputSchema: imageGenerationOutputSchema
});
var imageGeneration = (args = {}) => {
return imageGenerationToolFactory(args);
};
// src/tool/web-search.ts
import { createProviderToolFactory } from "@ai-sdk/provider-utils";
import { z as z4 } from "zod";
var webSearchArgsSchema = z4.object({
filters: z4.object({
allowedDomains: z4.array(z4.string()).optional()
}).optional(),
searchContextSize: z4.enum(["low", "medium", "high"]).optional(),
userLocation: z4.object({
type: z4.literal("approximate"),
country: z4.string().optional(),
city: z4.string().optional(),
region: z4.string().optional(),
timezone: z4.string().optional()
}).optional()
});
var webSearchToolFactory = createProviderToolFactory({
id: "aihubmix.web_search",
inputSchema: z4.object({
action: z4.discriminatedUnion("type", [
z4.object({
type: z4.literal("search"),
query: z4.string().nullish()
}),
z4.object({
type: z4.literal("open_page"),
url: z4.string()
}),
z4.object({
type: z4.literal("find"),
url: z4.string(),
pattern: z4.string()
})
]).nullish()
})
});
var webSearch = (args = {}) => {
return webSearchToolFactory(args);
};
// src/tool/web-search-preview.ts
import { createProviderToolFactory as createProviderToolFactory2 } from "@ai-sdk/provider-utils";
import { z as z5 } from "zod";
var webSearchPreviewArgsSchema = z5.object({
/**
* Search context size to use for the web search.
* - high: Most comprehensive context, highest cost, slower response
* - medium: Balanced context, cost, and latency (default)
* - low: Least context, lowest cost, fastest response
*/
searchContextSize: z5.enum(["low", "medium", "high"]).optional(),
/**
* User location information to provide geographically relevant search results.
*/
userLocation: z5.object({
/**
* Type of location (always 'approximate')
*/
type: z5.literal("approximate"),
/**
* Two-letter ISO country code (e.g., 'US', 'GB')
*/
country: z5.string().optional(),
/**
* City name (free text, e.g., 'Minneapolis')
*/
city: z5.string().optional(),
/**
* Region name (free text, e.g., 'Minnesota')
*/
region: z5.string().optional(),
/**
* IANA timezone (e.g., 'America/Chicago')
*/
timezone: z5.string().optional()
}).optional()
});
var webSearchPreview = createProviderToolFactory2({
id: "aihubmix.web_search_preview",
inputSchema: z5.object({
action: z5.discriminatedUnion("type", [
z5.object({
type: z5.literal("search"),
query: z5.string().nullish()
}),
z5.object({
type: z5.literal("open_page"),
url: z5.string()
}),
z5.object({
type: z5.literal("find"),
url: z5.string(),
pattern: z5.string()
})
]).nullish()
})
});
// src/aihubmix-tools.ts
var aihubmixTools = {
/**
* The Code Interpreter tool allows models to write and run Python code in a
* sandboxed environment to solve complex problems in domains like data analysis,
* coding, and math.
*
* @param container - The container to use for the code interpreter.
*
* Must have name `code_interpreter`.
*/
codeInterpreter,
/**
* File search is a tool available in the Responses API. It enables models to
* retrieve information in a knowledge base of previously uploaded files through
* semantic and keyword search.
*
* Must have name `file_search`.
*
* @param vectorStoreIds - The vector store IDs to use for the file search.
* @param maxNumResults - The maximum number of results to return.
* @param ranking - The ranking options to use for the file search.
* @param filters - The filters to use for the file search.
*/
fileSearch,
/**
* The image generation tool allows you to generate images using a text prompt,
* and optionally image inputs. It leverages the GPT Image model,
* and automatically optimizes text inputs for improved performance.
*
* Must have name `image_generation`.
*
* @param size - Image dimensions (e.g., 1024x1024, 1024x1536)
* @param quality - Rendering quality (e.g. low, medium, high)
* @param format - File output format
* @param compression - Compression level (0-100%) for JPEG and WebP formats
* @param background - Transparent or opaque
*/
imageGeneration,
/**
* Web search allows models to access up-to-date information from the internet
* and provide answers with sourced citations.
*
* Must have name `web_search_preview`.
*
* @param searchContextSize - The search context size to use for the web search.
* @param userLocation - The user location to use for the web search.
*
* @deprecated Use `webSearch` instead.
*/
webSearchPreview,
/**
* Web search allows models to access up-to-date information from the internet
* and provide answers with sourced citations.
*
* Must have name `web_search`.
*
* @param filters - The filters to use for the web search.
* @param searchContextSize - The search context size to use for the web search.
* @param userLocation - The user location to use for the web search.
*/
webSearch
};
// src/aihubmix-provider.ts
var AihubmixTranscriptionModel = class extends OpenAITranscriptionModel {
async doGenerate(options) {
if (options.mediaType) {
const mimeTypeMap = {
"audio/mpeg": "mp3",
"audio/mp3": "mp3",
"audio/wav": "wav",
"audio/flac": "flac",
"audio/m4a": "m4a",
"audio/mp4": "mp4",
"audio/ogg": "ogg",
"audio/webm": "webm",
"audio/oga": "oga",
"audio/mpga": "mpga"
};
const extension = mimeTypeMap[options.mediaType];
if (extension) {
const originalGetArgs = this.getArgs;
this.getArgs = async function(args) {
const result = await originalGetArgs.call(this, args);
if (result.formData) {
const fileEntry = result.formData.get("file");
if (fileEntry && typeof fileEntry === "object" && "name" in fileEntry) {
try {
const newFile = new File([fileEntry], `audio.${extension}`, {
type: options.mediaType
});
result.formData.set("file", newFile);
} catch (error) {
console.log("Failed to create new File object:", error);
if (fileEntry && typeof fileEntry === "object" && "arrayBuffer" in fileEntry) {
try {
const arrayBuffer = await fileEntry.arrayBuffer();
const newFile = new File([arrayBuffer], `audio.${extension}`, {
type: options.mediaType
});
result.formData.set("file", newFile);
console.log("Created new file from arrayBuffer with name:", `audio.${extension}`);
} catch (bufferError) {
console.log("Failed to create file from arrayBuffer:", bufferError);
}
}
}
}
}
return result;
};
}
}
return super.doGenerate(options);
}
};
function transformRequestBody(body) {
if (body.tools && Array.isArray(body.tools) && body.tools.length === 0 && body.tool_choice) {
const { tool_choice, ...rest } = body;
return rest;
}
return body;
}
function createAihubmix(options = {}) {
const getHeaders = () => ({
Authorization: `Bearer ${loadApiKey({
apiKey: options.apiKey,
environmentVariableName: "AIHUBMIX_API_KEY",
description: "Aihubmix"
})}`,
"APP-Code": "WHVL9885",
"Content-Type": "application/json"
});
const getTranscriptionHeaders = () => ({
Authorization: `Bearer ${loadApiKey({
apiKey: options.apiKey,
environmentVariableName: "AIHUBMIX_API_KEY",
description: "Aihubmix"
})}`,
"APP-Code": "WHVL9885"
});
const url = ({ path, modelId }) => {
const baseURL = "https://aihubmix.com/v1";
return `${baseURL}${path}`;
};
const createChatModel = (deploymentName, settings = {}) => {
const headers = getHeaders();
if (deploymentName.startsWith("claude-")) {
const { Authorization, ...restHeaders } = headers;
return new AnthropicMessagesLanguageModel(deploymentName, {
provider: "aihubmix.chat",
baseURL: url({ path: "", modelId: deploymentName }),
headers: {
...restHeaders,
"x-api-key": Authorization.split(" ")[1]
},
supportedUrls: () => ({
"image/*": [/^https?:\/\/.*$/]
})
});
}
if ((deploymentName.startsWith("gemini") || deploymentName.startsWith("imagen")) && !deploymentName.endsWith("-nothink") && !deploymentName.endsWith("-search")) {
const { Authorization, ...restHeaders } = headers;
return new GoogleGenerativeAILanguageModel(
deploymentName,
{
provider: "aihubmix.chat",
baseURL: "https://aihubmix.com/gemini/v1beta",
headers: {
...restHeaders,
"x-goog-api-key": Authorization.split(" ")[1]
},
generateId: () => `aihubmix-${Date.now()}`,
supportedUrls: () => ({})
}
);
}
return new OpenAICompatibleChatLanguageModel(deploymentName, {
provider: "aihubmix.chat",
url,
headers: getHeaders,
fetch: options.fetch,
includeUsage: true,
supportsStructuredOutputs: true,
transformRequestBody
});
};
const createCompletionModel = (modelId, settings = {}) => new OpenAICompatibleCompletionLanguageModel(modelId, {
provider: "aihubmix.completion",
url,
headers: getHeaders,
fetch: options.fetch,
includeUsage: true
});
const createEmbeddingModel = (modelId, settings = {}) => {
return new OpenAICompatibleEmbeddingModel(modelId, {
provider: "aihubmix.embeddings",
url,
headers: getHeaders,
fetch: options.fetch
});
};
const createResponsesModel = (modelId) => new OpenAIResponsesLanguageModel(modelId, {
provider: "aihubmix.responses",
url,
headers: getHeaders
});
const createImageModel = (modelId, settings = {}) => {
return new OpenAICompatibleImageModel(modelId, {
provider: "aihubmix.image",
url,
headers: getHeaders,
fetch: options.fetch
});
};
const createTranscriptionModel = (modelId) => new AihubmixTranscriptionModel(modelId, {
provider: "aihubmix.transcription",
url,
headers: getTranscriptionHeaders,
fetch: options.fetch
});
const createSpeechModel = (modelId) => new OpenAISpeechModel(modelId, {
provider: "aihubmix.speech",
url,
headers: getHeaders,
fetch: options.fetch
});
const providerFn = function(deploymentId, settings) {
if (new.target) {
throw new Error(
"The Aihubmix model function cannot be called with the new keyword."
);
}
return createChatModel(deploymentId, settings);
};
const provider = Object.assign(providerFn, {
specificationVersion: "v3",
languageModel: createChatModel,
chat: createChatModel,
completion: createCompletionModel,
responses: createResponsesModel,
embedding: createEmbeddingModel,
embeddingModel: createEmbeddingModel,
textEmbedding: createEmbeddingModel,
textEmbeddingModel: createEmbeddingModel,
image: createImageModel,
imageModel: createImageModel,
transcription: createTranscriptionModel,
transcriptionModel: createTranscriptionModel,
speech: createSpeechModel,
speechModel: createSpeechModel,
tools: aihubmixTools
});
return provider;
}
var aihubmix = createAihubmix();
export {
aihubmix,
createAihubmix
};
//# sourceMappingURL=index.mjs.map