paper-burner/js/process/prompt-pool-api.js

101 lines
4.5 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// process/prompt-pool-api.js
// 提示词池 - 统一生成调用配置,复用 translation.js 的构建逻辑
(function() {
/**
* 构建用于提示词池生成请求的 API 配置。
* - 预设模型使用与翻译相同的端点与请求格式deepseek/mistral/gemini
* - 自定义源站点:复用 buildCustomApiConfig自动补全兼容端点/v1/chat/completions 等)。
*
* @param {string} apiModel - 预设模型名mistral/deepseek/gemini或 "siteId:modelId"。
* @param {string} apiKey - 对应模型的 API Key。
* @returns {{endpoint:string, modelName:string, headers:Object, bodyBuilder:Function, responseExtractor:Function}}
*/
function buildPromptPoolGenerationConfig(apiModel, apiKey) {
if (!apiModel) throw new Error('未指定模型');
if (!apiKey) throw new Error('未提供 API Key');
// 延迟检查,避免初始化时机问题
const ensureBuilders = () => {
if (typeof processModule === 'undefined' ||
typeof processModule.buildCustomApiConfig !== 'function' ||
typeof processModule.buildPredefinedApiConfig !== 'function') {
throw new Error('translation.js 尚未加载,无法构建 API 配置');
}
};
// 自定义源站点格式siteId:modelId
if (apiModel.includes(':')) {
ensureBuilders();
const separatorIndex = apiModel.indexOf(':');
const siteId = apiModel.slice(0, separatorIndex);
const modelId = apiModel.slice(separatorIndex + 1);
const allSites = (typeof loadAllCustomSourceSites === 'function') ? loadAllCustomSourceSites() : {};
const site = allSites[siteId];
if (!site) throw new Error(`未找到源站点配置:${siteId}`);
// 复用 translation.js 的自定义构建,自动处理端点后缀与请求格式
return processModule.buildCustomApiConfig(
apiKey,
site.apiEndpoint || site.apiBaseUrl,
modelId || site.modelId,
site.requestFormat || 'openai',
site.temperature !== undefined ? site.temperature : 0.5,
site.max_tokens !== undefined ? site.max_tokens : 8000,
{
endpointMode: site.endpointMode || 'auto'
}
);
}
// 预设模型(与 translateMarkdown 保持一致)
ensureBuilders();
const settings = (typeof loadSettings === 'function') ? loadSettings() : {};
const temperature = (settings.customModelSettings && settings.customModelSettings.temperature) || 0.5;
const maxTokens = (settings.customModelSettings && settings.customModelSettings.max_tokens) || 8000;
const predefined = {
deepseek: {
endpoint: 'https://api.deepseek.com/v1/chat/completions',
modelName: 'DeepSeek v3 (deepseek-v3)',
headers: { 'Content-Type': 'application/json' },
bodyBuilder: (sys, user) => ({
model: 'deepseek-chat',
messages: [ { role: 'system', content: sys }, { role: 'user', content: user } ],
temperature, max_tokens: maxTokens
}),
responseExtractor: d => d?.choices?.[0]?.message?.content
},
gemini: {
endpoint: 'https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent',
modelName: 'Google Gemini 2.0 Flash',
headers: { 'Content-Type': 'application/json' },
bodyBuilder: (sys, user) => ({
contents: [ { role: 'user', parts: [{ text: `${sys}\n\n${user}` }] } ],
generationConfig: { temperature, maxOutputTokens: maxTokens }
}),
responseExtractor: d => d?.candidates?.[0]?.content?.parts?.[0]?.text || ''
},
mistral: {
endpoint: 'https://api.mistral.ai/v1/chat/completions',
modelName: 'Mistral Large (mistral-large-latest)',
headers: { 'Content-Type': 'application/json' },
bodyBuilder: (sys, user) => ({
model: 'mistral-large-latest',
messages: [ { role: 'system', content: sys }, { role: 'user', content: user } ],
temperature, max_tokens: maxTokens
}),
responseExtractor: d => d?.choices?.[0]?.message?.content
}
};
if (!predefined[apiModel]) throw new Error(`不支持的模型:${apiModel}`);
return processModule.buildPredefinedApiConfig(predefined[apiModel], apiKey);
}
// 暴露到全局
if (typeof window !== 'undefined') {
window.buildPromptPoolGenerationConfig = buildPromptPoolGenerationConfig;
}
})();