feat: add unified reverse proxy URL support for all API endpoints

Extract URL construction into src/utils/url-builder.js, replacing 8
scattered inline implementations. Now properly handles reverse proxy
paths like /Gemini/v1 or /antigravity/v1 by detecting version segments
at any path depth. Fixes inconsistent Anthropic URL in multi-ai-generator.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Cola-Echo
2026-03-31 23:23:55 +08:00
parent 10ea8cc1f4
commit 3a554028ae
10 changed files with 133 additions and 61 deletions

View File

@@ -7,6 +7,7 @@ import Logger from '@core/logger';
import { StreamingHandler } from './streaming-handler';
import { getEnabledProviders } from '@config/config-manager';
import { buildMessagesFromPreset, getPromptPresetById } from '@ui/modals/prompt-preset';
import { buildOpenAIChatUrl, buildAnthropicUrl } from '@utils/url-builder';
const log = Logger.createModuleLogger('多AI生成');
@@ -225,18 +226,12 @@ export class MultiAIGenerator {
async callProvider(provider, messages, signal, onChunk) {
const { apiFormat, apiUrl, apiKey, model, maxTokens, temperature, streaming } = provider;
// 构建请求URL
// 构建请求URL(统一的反代兼容 URL 构造)
let requestUrl = apiUrl;
if (apiFormat === 'openai') {
if (apiUrl.endsWith('/v1') || apiUrl.endsWith('/v1/')) {
requestUrl = apiUrl.replace(/\/v1\/?$/, '/v1/chat/completions');
} else if (!apiUrl.includes('/chat/completions') && !apiUrl.includes('/completions')) {
requestUrl = apiUrl.replace(/\/?$/, '/chat/completions');
}
requestUrl = buildOpenAIChatUrl(apiUrl);
} else if (apiFormat === 'anthropic') {
if (!apiUrl.includes('/messages')) {
requestUrl = apiUrl.replace(/\/?$/, '/messages');
}
requestUrl = buildAnthropicUrl(apiUrl);
} else if (apiFormat === 'google') {
// Google Gemini API
if (!apiUrl.includes(':generateContent')) {