// server/utils/openai.ts import OpenAI from "openai"; import type { BaseOptions } from "#shared/types/openai"; /** 通用 AI 调用函数(支持文本 / 图文 / 多模态) */ export const askAI = async ({ apiKey, model, baseURL, input }: BaseOptions & { input: OpenAI.Responses.ResponseCreateParams["input"]; }) => { const client = new OpenAI({ apiKey, baseURL }); return await client.responses.create({ model, input }); }; /** 调用文本模型 */ export const askText = async ( options: BaseOptions & { text: string; } ) => { const res = await askAI({ ...options, input: options.text }); return res.output_text; }; /** * 调用视觉模型:输入「文本 + 图片」,输出文本 * * 分辨率参数说明: * * | 值 | 含义 | * |------|--------------------------| * | low | 低分辨率(更快、更省成本) | * | high | 高分辨率(更精准) | * | auto | 自动选择 | * */ export const askVision = async ( options: BaseOptions & { text: string; image: string; detail?: "low" | "high" | "auto"; } ) => { // 如果图片不是 URL,也不是 data URL,就当成 base64 处理,自动补全 data URL 前缀 const normalizeImage = (img: string) => { if (img.startsWith("http")) return img; if (!img.startsWith("data:")) { return `data:image/png;base64,${img}`; } return img; }; const res = await askAI({ ...options, input: [ { role: "user", content: [ { type: "input_text", text: options.text }, { type: "input_image", image_url: normalizeImage(options.image), detail: options.detail || "auto" } ] } ] }); return res.output_text; }; /** 调用流式接口 */ export const askStream = async ( options: BaseOptions & { input: OpenAI.Responses.ResponseCreateParams["input"]; } ) => { const client = new OpenAI({ apiKey: options.apiKey, baseURL: options.baseURL }); const stream = await client.responses.stream({ model: options.model, input: options.input }); return stream; };