import { AIProvider, ChatOptions, EmptyContentError, ApiRequestError } from './base'; import { t } from '../../i18n/messages'; export class ClaudeProvider extends AIProvider { id = 'claude'; name = 'Anthropic Claude'; async chat(systemPrompt: string, userPrompt: string, options: ChatOptions): Promise { const url = `${this.baseUrl}/messages`; const body = JSON.stringify({ model: options.model, max_tokens: options.maxTokens, temperature: options.temperature, system: systemPrompt, messages: [ { role: 'user', content: userPrompt }, ], }); const controller = new AbortController(); const timeout = setTimeout(() => controller.abort(), options.timeoutMs); try { const response = await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json', 'x-api-key': this.apiKey, 'anthropic-version': '2023-06-01', }, body, signal: controller.signal, }); if (!response.ok) { const errorText = await response.text(); if (response.status === 401) { throw new ApiRequestError('API Key 无效,请重新设置', 401); } throw new ApiRequestError(`Claude API 请求失败 (${response.status}): ${errorText}`, response.status); } const data = await response.json() as { content?: Array<{ text?: string }>; stop_reason?: string; error?: { message?: string }; }; const text = data.content?.[0]?.text; if (text === undefined || text === null || text.trim() === '') { const parts = [`stop_reason=${data.stop_reason ?? 'unknown'}`]; if (data.error?.message) { parts.push(data.error.message); } throw new EmptyContentError(t('adapter.emptyContent', { 0: parts.join(', ') })); } return text; } finally { clearTimeout(timeout); } } }