| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798 |
- const config = require('../config');
- const PATH = 'chat/completions';
- /** 读图较慢,与 ai.js REQUEST_TIMEOUT_IMG_MS 对齐 */
- const TIMEOUT_MS = 180000;
- /**
- * 将单 URL 或 URL 数组规范为字符串数组(OpenAI 兼容:同一 user 消息里多段 image_url = 多图)
- */
- function normalizeImageUrls (imageUrlOrUrls) {
- if (Array.isArray(imageUrlOrUrls)) {
- return imageUrlOrUrls.map((u) => String(u || '').trim()).filter(Boolean);
- }
- const s = String(imageUrlOrUrls || '').trim();
- return s ? [s] : [];
- }
- function buildUserContent (prompt, imageUrlOrUrls) {
- const urls = normalizeImageUrls(imageUrlOrUrls);
- const content = [{ type: 'text', text: String(prompt || '') }];
- for (const url of urls) {
- content.push({
- type: 'image_url',
- image_url: { url, detail: 'high' },
- });
- }
- return content;
- }
- function resolveModel (modelOverride) {
- return (
- (modelOverride && String(modelOverride).trim()) ||
- (config.IMG2TEXT_MODEL && String(config.IMG2TEXT_MODEL).trim()) ||
- config.MODEL_NAME ||
- 'gpt-4o'
- );
- }
- /** 截图 ROI(img-center):默认读 config.IMG_CENTER_MODEL,与 img2text 默认解耦 */
- function resolveImgCenterModel (modelOverride) {
- return (
- (modelOverride && String(modelOverride).trim()) ||
- (config.IMG_CENTER_MODEL && String(config.IMG_CENTER_MODEL).trim()) ||
- (config.IMG2TEXT_MODEL && String(config.IMG2TEXT_MODEL).trim()) ||
- config.MODEL_NAME ||
- 'gpt-5.4'
- );
- }
- /**
- * OpenAI 兼容 POST /v1/chat/completions
- * @param {string} prompt
- * @param {string|string[]} imageUrlOrUrls 单张 data URL / https URL,或多张(多附件)
- * @param {string} [modelOverride]
- */
- function getBody (prompt, imageUrlOrUrls, modelOverride) {
- const urls = normalizeImageUrls(imageUrlOrUrls);
- if (urls.length === 0) {
- throw new Error('img2text: 至少提供一张图片(字符串 URL 或 URL 数组)');
- }
- const model = resolveModel(modelOverride);
- const content = buildUserContent(prompt, imageUrlOrUrls);
- return {
- model,
- messages: [{ role: 'user', content }],
- // 勿与 max_completion_tokens 同时传:部分聚合网关(如 ChatAnywhere)会报错
- max_tokens: 1024,
- stream: false,
- };
- }
- function getDoubaoBody (prompt, imageUrlOrUrls, modelOverride) {
- const urls = normalizeImageUrls(imageUrlOrUrls);
- if (urls.length === 0) {
- throw new Error('img2text: 至少提供一张图片');
- }
- const model =
- (modelOverride && String(modelOverride).trim()) || config.DOUBAO_MODEL;
- const content = buildUserContent(prompt, imageUrlOrUrls);
- return {
- model,
- messages: [{ role: 'user', content }],
- max_tokens: 1024,
- stream: false,
- };
- }
- module.exports = {
- path: PATH,
- getBody,
- getDoubaoBody,
- /** img-center:无 override 时用 config.IMG_CENTER_MODEL(环境变量 IMG_CENTER_MODEL) */
- resolveImgCenterModel,
- timeoutMs: TIMEOUT_MS,
- /** 测试/调试:看 content 结构 */
- buildUserContent,
- normalizeImageUrls,
- };
|