ai-chatbot/lib/ai/detail-replacement-vision-runtime.ts

57 lines
1.8 KiB
TypeScript

import "server-only";
import { createOpenAI } from "@ai-sdk/openai";
import { isAlibabaDashScopeBaseUrl } from "@/lib/ai/detail-agent-model-config";
import {
DETAIL_REPLACEMENT_VISION_MODEL_CONFIG_KEY,
normalizeDetailReplacementVisionModelConfig,
} from "@/lib/ai/detail-replacement-vision-model-config";
import { getAiProvidersByType, getSystemSetting } from "@/lib/db/queries";
const ALIBABA_COMPATIBLE_BASE_URL =
"https://dashscope.aliyuncs.com/compatible-mode/v1";
function createNonThinkingVisionFetch(baseFetch: typeof fetch = fetch): typeof fetch {
return async (input, init) => {
if (typeof init?.body !== "string") return baseFetch(input, init);
try {
const body = JSON.parse(init.body) as Record<string, unknown>;
return baseFetch(input, {
...init,
body: JSON.stringify({ ...body, enable_thinking: false }),
});
} catch {
return baseFetch(input, init);
}
};
}
export async function resolveDetailReplacementVisionRuntime() {
const [setting, providers] = await Promise.all([
getSystemSetting({ key: DETAIL_REPLACEMENT_VISION_MODEL_CONFIG_KEY }).catch(
() => null,
),
getAiProvidersByType({ type: "alibaba", enabledOnly: true }).catch(() => []),
]);
const provider = providers.find(
(item) =>
Boolean(item.apiKey?.trim()) &&
(!item.baseUrl?.trim() || isAlibabaDashScopeBaseUrl(item.baseUrl)),
);
if (!provider?.apiKey) return null;
const config = normalizeDetailReplacementVisionModelConfig(setting?.value);
const runtime = createOpenAI({
apiKey: provider.apiKey.trim(),
baseURL: provider.baseUrl?.trim() || ALIBABA_COMPATIBLE_BASE_URL,
fetch: createNonThinkingVisionFetch(),
});
return {
kind: "configured_vision" as const,
model: runtime.chat(config.modelId),
modelName: config.modelId,
};
}