{"repo": "amkyawdev/api-test-web", "files": {"src/services/apiService.ts": {"9c98c21d58907c041729988d3739501bfbd83dde": {"t": 1785746041.8111353, "n": 24561, "h": "3f24cc1465bb1e29", "c": "import type { ApiTestResult } from '../types/api.types';\n\n// Real API Endpoints\nconst API_ENDPOINTS: Record = {\n 'openai': { url: 'https://api.openai.com/v1/chat/completions', method: 'POST' },\n 'gemini': { url: 'https://generativelanguage.googleapis.com/v1beta/models', method: 'POST' },\n 'claude': { url: 'https://api.anthropic.com/v1/messages', method: 'POST' },\n 'deepseek': { url: 'https://api.deepseek.com/chat/completions', method: 'POST' },\n 'groq': { url: 'https://api.groq.com/openai/v1/chat/completions', method: 'POST' },\n 'together': { url: 'https://api.together.xyz/v1/chat/completions', method: 'POST' },\n 'openrouter': { url: 'https://openrouter.ai/api/v1/chat/completions', method: 'POST' },\n 'perplexity': { url: 'https://api.perplexity.ai/chat/completions', method: 'POST' },\n 'mistral': { url: 'https://api.mistral.ai/v1/chat/completions', method: 'POST' },\n 'cohere': { url: 'https://api.cohere.ai/v1/chat', method: 'POST' },\n 'cerebras': { url: 'https://api.cerebras.ai/v1/chat/completions', method: 'POST' },\n 'grok': { url: 'https://api.x.ai/v1/chat/completions', method: 'POST' },\n 'anyscale': { url: 'https://api.endpoints.anyscale.com/v1/chat/completions', method: 'POST' },\n 'ollama': { url: 'http://localhost:11434/api/chat', method: 'POST' },\n 'minimax': { url: 'https://api.minimax.chat/v1/text/chatcompletion_v2', method: 'POST' },\n 'elevenlabs': { url: 'https://api.elevenlabs.io/v1/text-to-speech', method: 'POST' },\n 'nvidia': { url: 'https://integrate.api.nvidia.com/v1/chat/completions', method: 'POST' },\n // New Providers\n 'fireworks': { url: 'https://api.fireworks.ai/inference/v1/chat/completions', method: 'POST' },\n 'replicate': { url: 'https://api.replicate.com/v1/predictions', method: 'POST' },\n 'cloudflare': { url: 'https://api.cloudflare.com/client/v4/accounts/workers/ai/run', method: 'POST' },\n 'lepton': { url: 'https://api.lepton.ai/v1/chat/completions', method: 'POST' },\n 'novita': { url: 'https://api.novita.ai/v3/chat/completions', method: 'POST' },\n 'hyperbolic': { url: 'https://api.hyperbolic.xyz/v1/chat/completions', method: 'POST' },\n};\n\nexport const apiService = {\n testApiKey: async (serverId: string, apiKey: string): Promise => {\n const startTime = Date.now();\n try {\n await new Promise(resolve => setTimeout(resolve, 1500));\n const latency = Date.now() - startTime;\n const isValid = apiKey.length >= 10 && !apiKey.includes(' ');\n return {\n success: isValid,\n message: isValid ? `API key validated for ${serverId}! Ready to use.` : 'Invalid API key format.',\n server: serverId,\n timestamp: new Date(),\n latency,\n };\n } catch (error) {\n return { success: false, message: 'Connection failed.', server: serverId, timestamp: new Date(), latency: Date.now() - startTime };\n }\n },\n\n sendMessage: async (serverId: string, apiKey: string, model: string, messages: { role: string; content: string }[]): Promise => {\n const endpoint = API_ENDPOINTS[serverId];\n if (!endpoint) throw new Error(`⚠️ Server မထောက်ပံ့ပါ။: ${serverId}`);\n\n // Ollama special case\n if (serverId === 'ollama') {\n const response = await fetch(endpoint.url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ model, messages, stream: false }),\n });\n if (!response.ok) throw new Error(`⚠️ Ollama အမှား (${response.status}): Server မှာ အမှားဖြစ်နေပါသည်။`);\n const data = await response.json();\n return data.message?.content || 'No response';\n }\n\n // Gemini special case\n if (serverId === 'gemini') {\n const geminiEndpoint = `https://generativelanguage.googleapis.com/v1beta/models/${model}:generateContent?key=${apiKey}`;\n const response = await fetch(geminiEndpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n contents: messages.map(m => ({ role: m.role === 'user' ? 'user' : 'model', parts: [{ text: m.content }] }))\n }),\n });\n if (!response.ok) {\n if (response.status === 404) throw new Error(`🔍 Gemini Model မရှိပါ။\\n\\n\"${model}\" သည် မရှိသော Model ဖြစ်ပါသည်။\\n\\n🔧 ဖြေရှင်းနည်း: Model ID ကို စစ်ဆေးပါ။`);\n throw new Error(`⚠️ Gemini အမှား (${response.status}): Server မှာ အမှားဖြစ်နေပါသည်။`);\n }\n const data = await response.json();\n return data.candidates?.[0]?.content?.parts?.[0]?.text || 'No response';\n }\n\n // Claude special case\n if (serverId === 'claude') {\n const response = await fetch(endpoint.url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n 'anthropic-version': '2023-06-01',\n },\n body: JSON.stringify({ model, max_tokens: 4096, messages: messages.map(m => ({ role: m.role, content: m.content })) }),\n });\n if (!response.ok) throw new Error(`⚠️ Claude အမှား (${response.status}): Server မှာ အမှားဖြစ်နေပါသည်။`);\n const data = await response.json();\n return data.content?.[0]?.text || 'No response';\n }\n\n // Cohere special case\n if (serverId === 'cohere') {\n const response = await fetch(endpoint.url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${apiKey}` },\n body: JSON.stringify({ model, messages: messages.map(m => ({ role: m.role === 'user' ? 'User' : 'Chatbot', message: m.content })) }),\n });\n if (!response.ok) throw new Error(`⚠️ Cohere အမှား (${response.status}): Server မှာ အမှားဖြစ်နေပါသည်။`);\n const data = await response.json();\n return data.text || 'No response';\n }\n\n // Standard OpenAI-compatible API\n const headers: Record = { 'Content-Type': 'application/json' };\n let body: Record = { model, messages };\n\n // Add auth headers\n if (serverId === 'openrouter') {\n headers['Authorization'] = `Bearer ${apiKey}`;\n headers['HTTP-Referer'] = window.location.origin;\n headers['X-Title'] = 'API Test Hub';\n } else {\n headers['Authorization'] = `Bearer ${apiKey}`;\n }\n\n // ElevenLabs special case\n if (serverId === 'elevenlabs') {\n body = { text: messages[messages.length - 1]?.content, model_id: model };\n }\n\n const response = await fetch(endpoint.url, { method: 'POST', headers, body: JSON.stringify(body) });\n\n if (!response.ok) {\n let errorData: Record = {};\n let errorText = '';\n \n // Try to parse JSON error response\n try {\n errorData = await response.json();\n } catch {\n // If not JSON, try to get text\n try {\n errorText = await response.text();\n } catch {\n errorText = '';\n }\n }\n \n // Extract error information from various possible locations\n const errorMessage = \n (errorData as any)?.error?.message || \n (errorData as any)?.message || \n (errorData as any)?.error?.type ||\n (errorData as any)?.type ||\n errorText || \n '';\n const errorCode = (errorData as any)?.error?.code || (errorData as any)?.code || '';\n const errorStatus = response.status;\n const errorModel = (errorData as any)?.error?.meta?.model_name || (errorData as any)?.model || model;\n \n // ===== API Key Expired / Invalid Errors =====\n if (\n errorMessage.includes('api_key_expired') || \n errorMessage.includes('API key has expired') ||\n errorMessage.includes('expired') ||\n errorCode.includes('expired') ||\n errorMessage.includes('key_expired')\n ) {\n throw new Error(`❌ API သော့ သက်တမ်းကုန်သွားပါပြီ။\\n\\nသင်၏ API သော့သည် သက်တမ်းလွန်နေပါပြီ။\\n\\n🔧 ဖြေရှင်းနည်း: API သော့အသစ်ထုတ်ယူပြီး ပြန်လည်ကြိုးစားပါ။`);\n }\n\n // ===== Invalid API Key Errors =====\n if (\n errorMessage.includes('invalid_api_key') || \n errorMessage.includes('Incorrect API key') ||\n errorMessage.includes('invalid api key') ||\n errorCode.includes('invalid_api_key') ||\n errorMessage.includes('api_key_invalid')\n ) {\n throw new Error(`❌ API Key Error!\\n\\nသင်၏ API key မှာ မှားယွင်းနေပါသည်။\\n\\n🔧 ဖြေရှင်းနည်း: API key ကို စစ်ဆေးပြီး ပြန်လည်ထည့်သွင်းပါ။`);\n }\n\n // ===== No Endpoints / Model Not Found =====\n if (\n errorMessage.toLowerCase().includes('no endpoints found') || \n errorMessage.toLowerCase().includes('model not found') ||\n errorMessage.toLowerCase().includes('model_not_found') ||\n errorCode.toLowerCase().includes('model_not_found') ||\n errorMessage.toLowerCase().includes('does not exist') ||\n errorMessage.toLowerCase().includes('not found for model') ||\n errorMessage.toLowerCase().includes('no valid routes')\n ) {\n throw new Error(`❌ Model မရရှိနိုင်ပါ။\\n\\n\"${errorModel}\" သည် သင်၏ API အကောင့်တွင် ရရှိနိုင်မှုမရှိပါ။\\n\\n🔧 ဖြေရှင်းနည်း:\\n• ဤ Model သည် Free tier တွင် မရရှိပါ\\n• OpenRouter တွင် Credits $1+ ထည့်သွင်းပါ\\n• Free tier Model များဖြစ်သော Gemma, Llama 3.1 8B, Mistral စသည်တို့ကို စမ်းသုံးကြည့်ပါ`);\n }\n\n // ===== Rate Limit Errors =====\n if (\n errorMessage.includes('rate_limit') || \n errorMessage.includes('Rate limit') ||\n errorMessage.includes('rate limit exceeded') ||\n errorCode.includes('rate_limit') ||\n errorMessage.includes('too many requests')\n ) {\n throw new Error(`⏳ Rate Limit ကျော်လွန်သွားပါပြီ။\\n\\nသင်အသုံးပြုမှုပမာဏသည် ကန့်သတ်ချက်ထက် မြင့်တက်သွားပါပြီ။\\n\\n🔧 ဖြေရှင်းနည်း: ခဏစောင့်ဆိုင်းပြီးနောက် ပြန်လည်ကြိုးစားပါ။`);\n }\n\n // ===== Insufficient Quota / Credits =====\n if (\n errorMessage.includes('insufficient_quota') || \n errorMessage.includes('quota') ||\n errorMessage.includes('Insufficient credits') ||\n errorMessage.includes('not enough credits') ||\n errorCode.includes('quota')\n ) {\n throw new Error(`💰 API သော့ Quota ကုန်ဆုံးသွားပါပြီ။\\n\\nသင်၏ API အကောင့်တွင် လက်ကျန်ငွေမရှိတော့ပါ။\\n\\n🔧 ဖြေရှင်းနည်း: သင်၏ API အကောင့်တွင် ငွေကြေးထည့်သွင်းပါ။`);\n }\n\n // ===== 401 Unauthorized =====\n if (errorStatus === 401) {\n throw new Error(`🔐 API သော့ တရားဝင်မဟုတ်ပါ။\\n\\nဤ API သော့သည် တရားဝင်မှုမရှိတော့ပါ (401 Unauthorized)။\\n\\n🔧 ဖြေရှင်းနည်း: API သော့အသစ်ထုတ်ယူပါ။`);\n }\n\n // ===== 403 Forbidden =====\n if (errorStatus === 403) {\n throw new Error(`🚫 ဝင်ခွင့်ငြင်းပယ်ခြင်း။\\n\\nဤ API သော့မှာ ဤဆောင်ရွက်မှုအတွက် ခွင့်မပြုပါ (403 Forbidden)။\\n\\n🔧 ဖြေရှင်းနည်း: API သော့၏ ခွင့်ပြုချက်များကို စစ်ဆေးပါ။`);\n }\n\n // ===== 429 Too Many Requests =====\n if (errorStatus === 429) {\n throw new Error(`⏰ တောင်းဆိုမှုအရမ်းများနေပါသည်။\\n\\nသင်၏ တောင်းဆိုမှုများသည် အရမ်းများနေပါပြီ (429 Too Many Requests)။\\n\\n🔧 ဖြေရှင်းနည်း: ခဏစောင့်ဆိုင်းပြီးနောက် ပြန်လည်ကြိုးစားပါ။`);\n }\n\n // ===== 500 Internal Server Error =====\n if (errorStatus >= 500) {\n throw new Error(`🛠️ Server အမှားဖြစ်ပါသည်။\\n\\nAPI Provider Server မှာ အမှားဖြစ်နေပါ (${errorStatus} Internal Server Error)။\\n\\n🔧 ဖြေရှင်းနည်း: ခဏစောင့်ဆိုင်းပြီးနောက် ပြန်လည်ကြိုးစားပါ။`);\n }\n\n // ===== Default Error =====\n throw new Error(`⚠️ API Error (${errorStatus}): ${errorMessage || 'အမည်မသိအမှားဖြစ်ပါသည်။'}`);\n }\n\n const data = await response.json();\n\n // Extract response - handle various API response formats\n let content = '';\n\n // Standard OpenAI-compatible format\n if (data.choices?.[0]?.message?.content) {\n content = data.choices[0].message.content;\n }\n // Alternative format with text field\n else if (data.choices?.[0]?.text) {\n content = data.choices[0].text;\n }\n // StreamLake/DeepSeek format with choices array\n else if (data.choices?.[0]?.delta?.content) {\n content = data.choices[0].delta.content;\n }\n // Generic choices array iteration\n else if (data.choices && data.choices.length > 0) {\n const firstChoice = data.choices[0];\n content = firstChoice.message?.content || firstChoice.delta?.content || firstChoice.text || '';\n }\n // Response as direct string\n else if (typeof data === 'string') {\n content = data;\n }\n // Response with response or text field at root\n else if (data.response) {\n content = typeof data.response === 'string' ? data.response : data.response.choices?.[0]?.message?.content || JSON.stringify(data.response);\n }\n else if (data.text) {\n content = data.text;\n }\n\n // Clean up content - remove any JSON metadata that might be included\n if (content && typeof content === 'string') {\n // Check if content starts with JSON-like pattern and try to extract actual text\n const jsonMatch = content.match(/^\\s*\\{.*\\}\\s*$/);\n if (jsonMatch && !content.includes('\\n') && content.length < 500) {\n try {\n const parsed = JSON.parse(content);\n // If it's JSON, try to extract meaningful content\n content = parsed.content || parsed.message || parsed.text || parsed.choices?.[0]?.message?.content || parsed.choices?.[0]?.text || content;\n } catch {\n // Not valid JSON, keep original\n }\n }\n }\n\n return content || 'No response';\n },\n\n sendMessageWithThinking: async (serverId: string, apiKey: string, model: string, messages: { role: string; content: string }[]): Promise<{ content: string; thinking?: string }> => {\n // Handle DeepSeek reasoning content\n if (serverId === 'deepseek' || serverId === 'openrouter') {\n const endpoint = API_ENDPOINTS[serverId];\n if (!endpoint) throw new Error(`Unsupported server: ${serverId}`);\n\n const headers: Record = { 'Content-Type': 'application/json' };\n let body: Record = { model, messages };\n\n if (serverId === 'openrouter') {\n headers['Authorization'] = `Bearer ${apiKey}`;\n headers['HTTP-Referer'] = window.location.origin;\n headers['X-Title'] = 'API Test Hub';\n } else {\n headers['Authorization'] = `Bearer ${apiKey}`;\n }\n\n const response = await fetch(endpoint.url, { method: 'POST', headers, body: JSON.stringify(body) });\n\n if (!response.ok) {\n let errorData: Record = {};\n let errorText = '';\n \n // Try to parse JSON error response\n try {\n errorData = await response.json();\n } catch {\n // If not JSON, try to get text\n try {\n errorText = await response.text();\n } catch {\n errorText = '';\n }\n }\n \n // Extract error information from various possible locations\n const errorMessage = \n (errorData as any)?.error?.message || \n (errorData as any)?.message || \n (errorData as any)?.error?.type ||\n (errorData as any)?.type ||\n errorText || \n '';\n const errorCode = (errorData as any)?.error?.code || (errorData as any)?.code || '';\n const errorStatus = response.status;\n const errorModel = (errorData as any)?.error?.meta?.model_name || (errorData as any)?.model || model;\n \n // ===== API Key Expired / Invalid Errors =====\n if (\n errorMessage.includes('api_key_expired') || \n errorMessage.includes('API key has expired') ||\n errorMessage.includes('expired') ||\n errorCode.includes('expired') ||\n errorMessage.includes('key_expired')\n ) {\n throw new Error(`❌ API သော့ သက်တမ်းကုန်သွားပါပြီ။\\n\\nသင်၏ API သော့သည် သက်တမ်းလွန်နေပါပြီ။\\n\\n🔧 ဖြေရှင်းနည်း: API သော့အသစ်ထုတ်ယူပြီး ပြန်လည်ကြိုးစားပါ။`);\n }\n\n // ===== Invalid API Key Errors =====\n if (\n errorMessage.includes('invalid_api_key') || \n errorMessage.includes('Incorrect API key') ||\n errorMessage.includes('invalid api key') ||\n errorCode.includes('invalid_api_key') ||\n errorMessage.includes('api_key_invalid')\n ) {\n throw new Error(`❌ API Key Error!\\n\\nသင်၏ API key မှာ မှားယွင်းနေပါသည်။\\n\\n🔧 ဖြေရှင်းနည်း: API key ကို စစ်ဆေးပြီး ပြန်လည်ထည့်သွင်းပါ။`);\n }\n\n // ===== No Endpoints / Model Not Found =====\n if (\n errorMessage.toLowerCase().includes('no endpoints found') || \n errorMessage.toLowerCase().includes('model not found') ||\n errorMessage.toLowerCase().includes('model_not_found') ||\n errorCode.toLowerCase().includes('model_not_found') ||\n errorMessage.toLowerCase().includes('does not exist') ||\n errorMessage.toLowerCase().includes('not found for model') ||\n errorMessage.toLowerCase().includes('no valid routes')\n ) {\n throw new Error(`❌ Model မရရှိနိုင်ပါ။\\n\\n\"${errorModel}\" သည် သင်၏ API အကောင့်တွင် ရရှိနိုင်မှုမရှိပါ။\\n\\n🔧 ဖြေရှင်းနည်း:\\n• ဤ Model သည် Free tier တွင် မရရှိပါ\\n• OpenRouter တွင် Credits $1+ ထည့်သွင်းပါ\\n• Free tier Model များဖြစ်သော Gemma, Llama 3.1 8B, Mistral စသည်တို့ကို စမ်းသုံးကြည့်ပါ`);\n }\n\n // ===== Rate Limit Errors =====\n if (\n errorMessage.includes('rate_limit') || \n errorMessage.includes('Rate limit') ||\n errorMessage.includes('rate limit exceeded') ||\n errorCode.includes('rate_limit') ||\n errorMessage.includes('too many requests')\n ) {\n throw new Error(`⏳ Rate Limit ကျော်လွန်သွားပါပြီ။\\n\\nသင်အသုံးပြုမှုပမာဏသည် ကန့်သတ်ချက်ထက် မြင့်တက်သွားပါပြီ။\\n\\n🔧 ဖြေရှင်းနည်း: ခဏစောင့်ဆိုင်းပြီးနောက် ပြန်လည်ကြိုးစားပါ။`);\n }\n\n // ===== Insufficient Quota / Credits =====\n if (\n errorMessage.includes('insufficient_quota') || \n errorMessage.includes('quota') ||\n errorMessage.includes('Insufficient credits') ||\n errorMessage.includes('not enough credits') ||\n errorCode.includes('quota')\n ) {\n throw new Error(`💰 API သော့ Quota ကုန်ဆုံးသွားပါပြီ။\\n\\nသင်၏ API အကောင့်တွင် လက်ကျန်ငွေမရှိတော့ပါ။\\n\\n🔧 ဖြေရှင်းနည်း: သင်၏ API အကောင့်တွင် ငွေကြေးထည့်သွင်းပါ။`);\n }\n\n // ===== 401 Unauthorized =====\n if (errorStatus === 401) {\n throw new Error(`🔐 API သော့ တရားဝင်မဟုတ်ပါ။\\n\\nဤ API သော့သည် တရားဝင်မှုမရှိတော့ပါ (401 Unauthorized)။\\n\\n🔧 ဖြေရှင်းနည်း: API သော့အသစ်ထုတ်ယူပါ။`);\n }\n\n // ===== 403 Forbidden =====\n if (errorStatus === 403) {\n throw new Error(`🚫 ဝင်ခွင့်ငြင်းပယ်ခြင်း။\\n\\nဤ API သော့မှာ ဤဆောင်ရွက်မှုအတွက် ခွင့်မပြုပါ (403 Forbidden)။\\n\\n🔧 ဖြေရှင်းနည်း: API သော့၏ ခွင့်ပြုချက်များကို စစ်ဆေးပါ။`);\n }\n\n // ===== 429 Too Many Requests =====\n if (errorStatus === 429) {\n throw new Error(`⏰ တောင်းဆိုမှုအရမ်းများနေပါသည်။\\n\\nသင်၏ တောင်းဆိုမှုများသည် အရမ်းများနေပါပြီ (429 Too Many Requests)။\\n\\n🔧 ဖြေရှင်းနည်း: ခဏစောင့်ဆိုင်းပြီးနောက် ပြန်လည်ကြိုးစားပါ။`);\n }\n\n // ===== 500 Internal Server Error =====\n if (errorStatus >= 500) {\n throw new Error(`🛠️ Server အမှားဖြစ်ပါသည်။\\n\\nAPI Provider Server မှာ အမှားဖြစ်နေပါ (${errorStatus} Internal Server Error)။\\n\\n🔧 ဖြေရှင်းနည်း: ခဏစောင့်ဆိုင်းပြီးနောက် ပြန်လည်ကြိုးစားပါ။`);\n }\n\n // ===== Default Error =====\n throw new Error(`⚠️ API Error (${errorStatus}): ${errorMessage || 'အမည်မသိအမှားဖြစ်ပါသည်။'}`);\n }\n\n const data = await response.json();\n \n // Try to extract reasoning/thinking content\n let thinking: string | undefined;\n let content = '';\n\n // DeepSeek reasoning format\n if (data.choices?.[0]?.message?.reasoning) {\n thinking = data.choices[0].message.reasoning;\n }\n // OpenAI o1 style reasoning\n else if (data.choices?.[0]?.message?.reasoning !== undefined) {\n thinking = data.choices[0].message.reasoning;\n }\n // Anthropic Claude extended thinking\n else if (data.choices?.[0]?.message?.thinking) {\n thinking = data.choices[0].message.thinking;\n }\n \n // Extract content\n if (data.choices?.[0]?.message?.content) {\n content = data.choices[0].message.content;\n } else if (data.choices?.[0]?.text) {\n content = data.choices[0].text;\n } else if (data.choices?.[0]?.delta?.content) {\n content = data.choices[0].delta.content;\n }\n\n return { content: content || 'No response', thinking };\n }\n\n // Default behavior for other servers - use direct fetch logic\n const endpoint = API_ENDPOINTS[serverId];\n if (!endpoint) throw new Error(`Unsupported server: ${serverId}`);\n\n // Ollama special case\n if (serverId === 'ollama') {\n const response = await fetch(endpoint.url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ model, messages, stream: false }),\n });\n if (!response.ok) throw new Error(`⚠️ Ollama အမှား (${response.status}): Server မှာ အမှားဖြစ်နေပါသည်။`);\n const data = await response.json();\n return { content: data.message?.content || 'No response' };\n }\n\n // Gemini special case\n if (serverId === 'gemini') {\n const geminiEndpoint = `https://generativelanguage.googleapis.com/v1beta/models/${model}:generateContent?key=${apiKey}`;\n const response = await fetch(geminiEndpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n contents: messages.map(m => ({ role: m.role === 'user' ? 'user' : 'model', parts: [{ text: m.content }] }))\n }),\n });\n if (!response.ok) {\n if (response.status === 404) throw new Error(`🔍 Gemini Model မရှိပါ။\\n\\n\"${model}\" သည် မရှိသော Model ဖြစ်ပါသည်။\\n\\n🔧 ဖြေရှင်းနည်း: Model ID ကို စစ်ဆေးပါ။`);\n throw new Error(`⚠️ Gemini အမှား (${response.status}): Server မှာ အမှားဖြစ်နေပါသည်။`);\n }\n const data = await response.json();\n return { content: data.candidates?.[0]?.content?.parts?.[0]?.text || 'No response' };\n }\n\n // Claude special case\n if (serverId === 'claude') {\n const response = await fetch(endpoint.url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n 'anthropic-version': '2023-06-01',\n },\n body: JSON.stringify({ model, max_tokens: 4096, messages: messages.map(m => ({ role: m.role, content: m.content })) }),\n });\n if (!response.ok) throw new Error(`⚠️ Claude အမှား (${response.status}): Server မှာ အမှားဖြစ်နေပါသည်။`);\n const data = await response.json();\n return { content: data.content?.[0]?.text || 'No response' };\n }\n\n // Cohere special case\n if (serverId === 'cohere') {\n const response = await fetch(endpoint.url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${apiKey}` },\n body: JSON.stringify({ model, messages: messages.map(m => ({ role: m.role === 'user' ? 'User' : 'Chatbot', message: m.content })) }),\n });\n if (!response.ok) throw new Error(`⚠️ Cohere အမှား (${response.status}): Server မှာ အမှားဖြစ်နေပါသည်။`);\n const data = await response.json();\n return { content: data.text || 'No response' };\n }\n\n // Standard OpenAI-compatible API\n const headers: Record = { 'Content-Type': 'application/json' };\n headers['Authorization'] = `Bearer ${apiKey}`;\n let body: Record = { model, messages };\n\n // ElevenLabs special case\n if (serverId === 'elevenlabs') {\n body = { text: messages[messages.length - 1]?.content, model_id: model };\n }\n\n const response = await fetch(endpoint.url, { method: 'POST', headers, body: JSON.stringify(body) });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n throw new Error(errorData.error?.message || `⚠️ API အမှား (${response.status}): Server မှာ အမှားဖြစ်နေပါသည်။`);\n }\n\n const data = await response.json();\n\n // Extract response\n let content = '';\n if (data.choices?.[0]?.message?.content) {\n content = data.choices[0].message.content;\n } else if (data.choices?.[0]?.text) {\n content = data.choices[0].text;\n } else if (data.choices?.[0]?.delta?.content) {\n content = data.choices[0].delta.content;\n }\n\n return { content: content || 'No response' };\n },\n\n getEndpoint: (serverId: string): string | undefined => API_ENDPOINTS[serverId]?.url,\n};\n"}, "9b84eed72d8e54b84ff804a9c3d0853a83977fbd": {"t": 1785759142.3413124, "n": 24561, "h": "3f24cc1465bb1e29", "c": "import type { ApiTestResult } from '../types/api.types';\n\n// Real API Endpoints\nconst API_ENDPOINTS: Record = {\n 'openai': { url: 'https://api.openai.com/v1/chat/completions', method: 'POST' },\n 'gemini': { url: 'https://generativelanguage.googleapis.com/v1beta/models', method: 'POST' },\n 'claude': { url: 'https://api.anthropic.com/v1/messages', method: 'POST' },\n 'deepseek': { url: 'https://api.deepseek.com/chat/completions', method: 'POST' },\n 'groq': { url: 'https://api.groq.com/openai/v1/chat/completions', method: 'POST' },\n 'together': { url: 'https://api.together.xyz/v1/chat/completions', method: 'POST' },\n 'openrouter': { url: 'https://openrouter.ai/api/v1/chat/completions', method: 'POST' },\n 'perplexity': { url: 'https://api.perplexity.ai/chat/completions', method: 'POST' },\n 'mistral': { url: 'https://api.mistral.ai/v1/chat/completions', method: 'POST' },\n 'cohere': { url: 'https://api.cohere.ai/v1/chat', method: 'POST' },\n 'cerebras': { url: 'https://api.cerebras.ai/v1/chat/completions', method: 'POST' },\n 'grok': { url: 'https://api.x.ai/v1/chat/completions', method: 'POST' },\n 'anyscale': { url: 'https://api.endpoints.anyscale.com/v1/chat/completions', method: 'POST' },\n 'ollama': { url: 'http://localhost:11434/api/chat', method: 'POST' },\n 'minimax': { url: 'https://api.minimax.chat/v1/text/chatcompletion_v2', method: 'POST' },\n 'elevenlabs': { url: 'https://api.elevenlabs.io/v1/text-to-speech', method: 'POST' },\n 'nvidia': { url: 'https://integrate.api.nvidia.com/v1/chat/completions', method: 'POST' },\n // New Providers\n 'fireworks': { url: 'https://api.fireworks.ai/inference/v1/chat/completions', method: 'POST' },\n 'replicate': { url: 'https://api.replicate.com/v1/predictions', method: 'POST' },\n 'cloudflare': { url: 'https://api.cloudflare.com/client/v4/accounts/workers/ai/run', method: 'POST' },\n 'lepton': { url: 'https://api.lepton.ai/v1/chat/completions', method: 'POST' },\n 'novita': { url: 'https://api.novita.ai/v3/chat/completions', method: 'POST' },\n 'hyperbolic': { url: 'https://api.hyperbolic.xyz/v1/chat/completions', method: 'POST' },\n};\n\nexport const apiService = {\n testApiKey: async (serverId: string, apiKey: string): Promise => {\n const startTime = Date.now();\n try {\n await new Promise(resolve => setTimeout(resolve, 1500));\n const latency = Date.now() - startTime;\n const isValid = apiKey.length >= 10 && !apiKey.includes(' ');\n return {\n success: isValid,\n message: isValid ? `API key validated for ${serverId}! Ready to use.` : 'Invalid API key format.',\n server: serverId,\n timestamp: new Date(),\n latency,\n };\n } catch (error) {\n return { success: false, message: 'Connection failed.', server: serverId, timestamp: new Date(), latency: Date.now() - startTime };\n }\n },\n\n sendMessage: async (serverId: string, apiKey: string, model: string, messages: { role: string; content: string }[]): Promise => {\n const endpoint = API_ENDPOINTS[serverId];\n if (!endpoint) throw new Error(`⚠️ Server မထောက်ပံ့ပါ။: ${serverId}`);\n\n // Ollama special case\n if (serverId === 'ollama') {\n const response = await fetch(endpoint.url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ model, messages, stream: false }),\n });\n if (!response.ok) throw new Error(`⚠️ Ollama အမှား (${response.status}): Server မှာ အမှားဖြစ်နေပါသည်။`);\n const data = await response.json();\n return data.message?.content || 'No response';\n }\n\n // Gemini special case\n if (serverId === 'gemini') {\n const geminiEndpoint = `https://generativelanguage.googleapis.com/v1beta/models/${model}:generateContent?key=${apiKey}`;\n const response = await fetch(geminiEndpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n contents: messages.map(m => ({ role: m.role === 'user' ? 'user' : 'model', parts: [{ text: m.content }] }))\n }),\n });\n if (!response.ok) {\n if (response.status === 404) throw new Error(`🔍 Gemini Model မရှိပါ။\\n\\n\"${model}\" သည် မရှိသော Model ဖြစ်ပါသည်။\\n\\n🔧 ဖြေရှင်းနည်း: Model ID ကို စစ်ဆေးပါ။`);\n throw new Error(`⚠️ Gemini အမှား (${response.status}): Server မှာ အမှားဖြစ်နေပါသည်။`);\n }\n const data = await response.json();\n return data.candidates?.[0]?.content?.parts?.[0]?.text || 'No response';\n }\n\n // Claude special case\n if (serverId === 'claude') {\n const response = await fetch(endpoint.url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n 'anthropic-version': '2023-06-01',\n },\n body: JSON.stringify({ model, max_tokens: 4096, messages: messages.map(m => ({ role: m.role, content: m.content })) }),\n });\n if (!response.ok) throw new Error(`⚠️ Claude အမှား (${response.status}): Server မှာ အမှားဖြစ်နေပါသည်။`);\n const data = await response.json();\n return data.content?.[0]?.text || 'No response';\n }\n\n // Cohere special case\n if (serverId === 'cohere') {\n const response = await fetch(endpoint.url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${apiKey}` },\n body: JSON.stringify({ model, messages: messages.map(m => ({ role: m.role === 'user' ? 'User' : 'Chatbot', message: m.content })) }),\n });\n if (!response.ok) throw new Error(`⚠️ Cohere အမှား (${response.status}): Server မှာ အမှားဖြစ်နေပါသည်။`);\n const data = await response.json();\n return data.text || 'No response';\n }\n\n // Standard OpenAI-compatible API\n const headers: Record = { 'Content-Type': 'application/json' };\n let body: Record = { model, messages };\n\n // Add auth headers\n if (serverId === 'openrouter') {\n headers['Authorization'] = `Bearer ${apiKey}`;\n headers['HTTP-Referer'] = window.location.origin;\n headers['X-Title'] = 'API Test Hub';\n } else {\n headers['Authorization'] = `Bearer ${apiKey}`;\n }\n\n // ElevenLabs special case\n if (serverId === 'elevenlabs') {\n body = { text: messages[messages.length - 1]?.content, model_id: model };\n }\n\n const response = await fetch(endpoint.url, { method: 'POST', headers, body: JSON.stringify(body) });\n\n if (!response.ok) {\n let errorData: Record = {};\n let errorText = '';\n \n // Try to parse JSON error response\n try {\n errorData = await response.json();\n } catch {\n // If not JSON, try to get text\n try {\n errorText = await response.text();\n } catch {\n errorText = '';\n }\n }\n \n // Extract error information from various possible locations\n const errorMessage = \n (errorData as any)?.error?.message || \n (errorData as any)?.message || \n (errorData as any)?.error?.type ||\n (errorData as any)?.type ||\n errorText || \n '';\n const errorCode = (errorData as any)?.error?.code || (errorData as any)?.code || '';\n const errorStatus = response.status;\n const errorModel = (errorData as any)?.error?.meta?.model_name || (errorData as any)?.model || model;\n \n // ===== API Key Expired / Invalid Errors =====\n if (\n errorMessage.includes('api_key_expired') || \n errorMessage.includes('API key has expired') ||\n errorMessage.includes('expired') ||\n errorCode.includes('expired') ||\n errorMessage.includes('key_expired')\n ) {\n throw new Error(`❌ API သော့ သက်တမ်းကုန်သွားပါပြီ။\\n\\nသင်၏ API သော့သည် သက်တမ်းလွန်နေပါပြီ။\\n\\n🔧 ဖြေရှင်းနည်း: API သော့အသစ်ထုတ်ယူပြီး ပြန်လည်ကြိုးစားပါ။`);\n }\n\n // ===== Invalid API Key Errors =====\n if (\n errorMessage.includes('invalid_api_key') || \n errorMessage.includes('Incorrect API key') ||\n errorMessage.includes('invalid api key') ||\n errorCode.includes('invalid_api_key') ||\n errorMessage.includes('api_key_invalid')\n ) {\n throw new Error(`❌ API Key Error!\\n\\nသင်၏ API key မှာ မှားယွင်းနေပါသည်။\\n\\n🔧 ဖြေရှင်းနည်း: API key ကို စစ်ဆေးပြီး ပြန်လည်ထည့်သွင်းပါ။`);\n }\n\n // ===== No Endpoints / Model Not Found =====\n if (\n errorMessage.toLowerCase().includes('no endpoints found') || \n errorMessage.toLowerCase().includes('model not found') ||\n errorMessage.toLowerCase().includes('model_not_found') ||\n errorCode.toLowerCase().includes('model_not_found') ||\n errorMessage.toLowerCase().includes('does not exist') ||\n errorMessage.toLowerCase().includes('not found for model') ||\n errorMessage.toLowerCase().includes('no valid routes')\n ) {\n throw new Error(`❌ Model မရရှိနိုင်ပါ။\\n\\n\"${errorModel}\" သည် သင်၏ API အကောင့်တွင် ရရှိနိုင်မှုမရှိပါ။\\n\\n🔧 ဖြေရှင်းနည်း:\\n• ဤ Model သည် Free tier တွင် မရရှိပါ\\n• OpenRouter တွင် Credits $1+ ထည့်သွင်းပါ\\n• Free tier Model များဖြစ်သော Gemma, Llama 3.1 8B, Mistral စသည်တို့ကို စမ်းသုံးကြည့်ပါ`);\n }\n\n // ===== Rate Limit Errors =====\n if (\n errorMessage.includes('rate_limit') || \n errorMessage.includes('Rate limit') ||\n errorMessage.includes('rate limit exceeded') ||\n errorCode.includes('rate_limit') ||\n errorMessage.includes('too many requests')\n ) {\n throw new Error(`⏳ Rate Limit ကျော်လွန်သွားပါပြီ။\\n\\nသင်အသုံးပြုမှုပမာဏသည် ကန့်သတ်ချက်ထက် မြင့်တက်သွားပါပြီ။\\n\\n🔧 ဖြေရှင်းနည်း: ခဏစောင့်ဆိုင်းပြီးနောက် ပြန်လည်ကြိုးစားပါ။`);\n }\n\n // ===== Insufficient Quota / Credits =====\n if (\n errorMessage.includes('insufficient_quota') || \n errorMessage.includes('quota') ||\n errorMessage.includes('Insufficient credits') ||\n errorMessage.includes('not enough credits') ||\n errorCode.includes('quota')\n ) {\n throw new Error(`💰 API သော့ Quota ကုန်ဆုံးသွားပါပြီ။\\n\\nသင်၏ API အကောင့်တွင် လက်ကျန်ငွေမရှိတော့ပါ။\\n\\n🔧 ဖြေရှင်းနည်း: သင်၏ API အကောင့်တွင် ငွေကြေးထည့်သွင်းပါ။`);\n }\n\n // ===== 401 Unauthorized =====\n if (errorStatus === 401) {\n throw new Error(`🔐 API သော့ တရားဝင်မဟုတ်ပါ။\\n\\nဤ API သော့သည် တရားဝင်မှုမရှိတော့ပါ (401 Unauthorized)။\\n\\n🔧 ဖြေရှင်းနည်း: API သော့အသစ်ထုတ်ယူပါ။`);\n }\n\n // ===== 403 Forbidden =====\n if (errorStatus === 403) {\n throw new Error(`🚫 ဝင်ခွင့်ငြင်းပယ်ခြင်း။\\n\\nဤ API သော့မှာ ဤဆောင်ရွက်မှုအတွက် ခွင့်မပြုပါ (403 Forbidden)။\\n\\n🔧 ဖြေရှင်းနည်း: API သော့၏ ခွင့်ပြုချက်များကို စစ်ဆေးပါ။`);\n }\n\n // ===== 429 Too Many Requests =====\n if (errorStatus === 429) {\n throw new Error(`⏰ တောင်းဆိုမှုအရမ်းများနေပါသည်။\\n\\nသင်၏ တောင်းဆိုမှုများသည် အရမ်းများနေပါပြီ (429 Too Many Requests)။\\n\\n🔧 ဖြေရှင်းနည်း: ခဏစောင့်ဆိုင်းပြီးနောက် ပြန်လည်ကြိုးစားပါ။`);\n }\n\n // ===== 500 Internal Server Error =====\n if (errorStatus >= 500) {\n throw new Error(`🛠️ Server အမှားဖြစ်ပါသည်။\\n\\nAPI Provider Server မှာ အမှားဖြစ်နေပါ (${errorStatus} Internal Server Error)။\\n\\n🔧 ဖြေရှင်းနည်း: ခဏစောင့်ဆိုင်းပြီးနောက် ပြန်လည်ကြိုးစားပါ။`);\n }\n\n // ===== Default Error =====\n throw new Error(`⚠️ API Error (${errorStatus}): ${errorMessage || 'အမည်မသိအမှားဖြစ်ပါသည်။'}`);\n }\n\n const data = await response.json();\n\n // Extract response - handle various API response formats\n let content = '';\n\n // Standard OpenAI-compatible format\n if (data.choices?.[0]?.message?.content) {\n content = data.choices[0].message.content;\n }\n // Alternative format with text field\n else if (data.choices?.[0]?.text) {\n content = data.choices[0].text;\n }\n // StreamLake/DeepSeek format with choices array\n else if (data.choices?.[0]?.delta?.content) {\n content = data.choices[0].delta.content;\n }\n // Generic choices array iteration\n else if (data.choices && data.choices.length > 0) {\n const firstChoice = data.choices[0];\n content = firstChoice.message?.content || firstChoice.delta?.content || firstChoice.text || '';\n }\n // Response as direct string\n else if (typeof data === 'string') {\n content = data;\n }\n // Response with response or text field at root\n else if (data.response) {\n content = typeof data.response === 'string' ? data.response : data.response.choices?.[0]?.message?.content || JSON.stringify(data.response);\n }\n else if (data.text) {\n content = data.text;\n }\n\n // Clean up content - remove any JSON metadata that might be included\n if (content && typeof content === 'string') {\n // Check if content starts with JSON-like pattern and try to extract actual text\n const jsonMatch = content.match(/^\\s*\\{.*\\}\\s*$/);\n if (jsonMatch && !content.includes('\\n') && content.length < 500) {\n try {\n const parsed = JSON.parse(content);\n // If it's JSON, try to extract meaningful content\n content = parsed.content || parsed.message || parsed.text || parsed.choices?.[0]?.message?.content || parsed.choices?.[0]?.text || content;\n } catch {\n // Not valid JSON, keep original\n }\n }\n }\n\n return content || 'No response';\n },\n\n sendMessageWithThinking: async (serverId: string, apiKey: string, model: string, messages: { role: string; content: string }[]): Promise<{ content: string; thinking?: string }> => {\n // Handle DeepSeek reasoning content\n if (serverId === 'deepseek' || serverId === 'openrouter') {\n const endpoint = API_ENDPOINTS[serverId];\n if (!endpoint) throw new Error(`Unsupported server: ${serverId}`);\n\n const headers: Record = { 'Content-Type': 'application/json' };\n let body: Record = { model, messages };\n\n if (serverId === 'openrouter') {\n headers['Authorization'] = `Bearer ${apiKey}`;\n headers['HTTP-Referer'] = window.location.origin;\n headers['X-Title'] = 'API Test Hub';\n } else {\n headers['Authorization'] = `Bearer ${apiKey}`;\n }\n\n const response = await fetch(endpoint.url, { method: 'POST', headers, body: JSON.stringify(body) });\n\n if (!response.ok) {\n let errorData: Record = {};\n let errorText = '';\n \n // Try to parse JSON error response\n try {\n errorData = await response.json();\n } catch {\n // If not JSON, try to get text\n try {\n errorText = await response.text();\n } catch {\n errorText = '';\n }\n }\n \n // Extract error information from various possible locations\n const errorMessage = \n (errorData as any)?.error?.message || \n (errorData as any)?.message || \n (errorData as any)?.error?.type ||\n (errorData as any)?.type ||\n errorText || \n '';\n const errorCode = (errorData as any)?.error?.code || (errorData as any)?.code || '';\n const errorStatus = response.status;\n const errorModel = (errorData as any)?.error?.meta?.model_name || (errorData as any)?.model || model;\n \n // ===== API Key Expired / Invalid Errors =====\n if (\n errorMessage.includes('api_key_expired') || \n errorMessage.includes('API key has expired') ||\n errorMessage.includes('expired') ||\n errorCode.includes('expired') ||\n errorMessage.includes('key_expired')\n ) {\n throw new Error(`❌ API သော့ သက်တမ်းကုန်သွားပါပြီ။\\n\\nသင်၏ API သော့သည် သက်တမ်းလွန်နေပါပြီ။\\n\\n🔧 ဖြေရှင်းနည်း: API သော့အသစ်ထုတ်ယူပြီး ပြန်လည်ကြိုးစားပါ။`);\n }\n\n // ===== Invalid API Key Errors =====\n if (\n errorMessage.includes('invalid_api_key') || \n errorMessage.includes('Incorrect API key') ||\n errorMessage.includes('invalid api key') ||\n errorCode.includes('invalid_api_key') ||\n errorMessage.includes('api_key_invalid')\n ) {\n throw new Error(`❌ API Key Error!\\n\\nသင်၏ API key မှာ မှားယွင်းနေပါသည်။\\n\\n🔧 ဖြေရှင်းနည်း: API key ကို စစ်ဆေးပြီး ပြန်လည်ထည့်သွင်းပါ။`);\n }\n\n // ===== No Endpoints / Model Not Found =====\n if (\n errorMessage.toLowerCase().includes('no endpoints found') || \n errorMessage.toLowerCase().includes('model not found') ||\n errorMessage.toLowerCase().includes('model_not_found') ||\n errorCode.toLowerCase().includes('model_not_found') ||\n errorMessage.toLowerCase().includes('does not exist') ||\n errorMessage.toLowerCase().includes('not found for model') ||\n errorMessage.toLowerCase().includes('no valid routes')\n ) {\n throw new Error(`❌ Model မရရှိနိုင်ပါ။\\n\\n\"${errorModel}\" သည် သင်၏ API အကောင့်တွင် ရရှိနိုင်မှုမရှိပါ။\\n\\n🔧 ဖြေရှင်းနည်း:\\n• ဤ Model သည် Free tier တွင် မရရှိပါ\\n• OpenRouter တွင် Credits $1+ ထည့်သွင်းပါ\\n• Free tier Model များဖြစ်သော Gemma, Llama 3.1 8B, Mistral စသည်တို့ကို စမ်းသုံးကြည့်ပါ`);\n }\n\n // ===== Rate Limit Errors =====\n if (\n errorMessage.includes('rate_limit') || \n errorMessage.includes('Rate limit') ||\n errorMessage.includes('rate limit exceeded') ||\n errorCode.includes('rate_limit') ||\n errorMessage.includes('too many requests')\n ) {\n throw new Error(`⏳ Rate Limit ကျော်လွန်သွားပါပြီ။\\n\\nသင်အသုံးပြုမှုပမာဏသည် ကန့်သတ်ချက်ထက် မြင့်တက်သွားပါပြီ။\\n\\n🔧 ဖြေရှင်းနည်း: ခဏစောင့်ဆိုင်းပြီးနောက် ပြန်လည်ကြိုးစားပါ။`);\n }\n\n // ===== Insufficient Quota / Credits =====\n if (\n errorMessage.includes('insufficient_quota') || \n errorMessage.includes('quota') ||\n errorMessage.includes('Insufficient credits') ||\n errorMessage.includes('not enough credits') ||\n errorCode.includes('quota')\n ) {\n throw new Error(`💰 API သော့ Quota ကုန်ဆုံးသွားပါပြီ။\\n\\nသင်၏ API အကောင့်တွင် လက်ကျန်ငွေမရှိတော့ပါ။\\n\\n🔧 ဖြေရှင်းနည်း: သင်၏ API အကောင့်တွင် ငွေကြေးထည့်သွင်းပါ။`);\n }\n\n // ===== 401 Unauthorized =====\n if (errorStatus === 401) {\n throw new Error(`🔐 API သော့ တရားဝင်မဟုတ်ပါ။\\n\\nဤ API သော့သည် တရားဝင်မှုမရှိတော့ပါ (401 Unauthorized)။\\n\\n🔧 ဖြေရှင်းနည်း: API သော့အသစ်ထုတ်ယူပါ။`);\n }\n\n // ===== 403 Forbidden =====\n if (errorStatus === 403) {\n throw new Error(`🚫 ဝင်ခွင့်ငြင်းပယ်ခြင်း။\\n\\nဤ API သော့မှာ ဤဆောင်ရွက်မှုအတွက် ခွင့်မပြုပါ (403 Forbidden)။\\n\\n🔧 ဖြေရှင်းနည်း: API သော့၏ ခွင့်ပြုချက်များကို စစ်ဆေးပါ။`);\n }\n\n // ===== 429 Too Many Requests =====\n if (errorStatus === 429) {\n throw new Error(`⏰ တောင်းဆိုမှုအရမ်းများနေပါသည်။\\n\\nသင်၏ တောင်းဆိုမှုများသည် အရမ်းများနေပါပြီ (429 Too Many Requests)။\\n\\n🔧 ဖြေရှင်းနည်း: ခဏစောင့်ဆိုင်းပြီးနောက် ပြန်လည်ကြိုးစားပါ။`);\n }\n\n // ===== 500 Internal Server Error =====\n if (errorStatus >= 500) {\n throw new Error(`🛠️ Server အမှားဖြစ်ပါသည်။\\n\\nAPI Provider Server မှာ အမှားဖြစ်နေပါ (${errorStatus} Internal Server Error)။\\n\\n🔧 ဖြေရှင်းနည်း: ခဏစောင့်ဆိုင်းပြီးနောက် ပြန်လည်ကြိုးစားပါ။`);\n }\n\n // ===== Default Error =====\n throw new Error(`⚠️ API Error (${errorStatus}): ${errorMessage || 'အမည်မသိအမှားဖြစ်ပါသည်။'}`);\n }\n\n const data = await response.json();\n \n // Try to extract reasoning/thinking content\n let thinking: string | undefined;\n let content = '';\n\n // DeepSeek reasoning format\n if (data.choices?.[0]?.message?.reasoning) {\n thinking = data.choices[0].message.reasoning;\n }\n // OpenAI o1 style reasoning\n else if (data.choices?.[0]?.message?.reasoning !== undefined) {\n thinking = data.choices[0].message.reasoning;\n }\n // Anthropic Claude extended thinking\n else if (data.choices?.[0]?.message?.thinking) {\n thinking = data.choices[0].message.thinking;\n }\n \n // Extract content\n if (data.choices?.[0]?.message?.content) {\n content = data.choices[0].message.content;\n } else if (data.choices?.[0]?.text) {\n content = data.choices[0].text;\n } else if (data.choices?.[0]?.delta?.content) {\n content = data.choices[0].delta.content;\n }\n\n return { content: content || 'No response', thinking };\n }\n\n // Default behavior for other servers - use direct fetch logic\n const endpoint = API_ENDPOINTS[serverId];\n if (!endpoint) throw new Error(`Unsupported server: ${serverId}`);\n\n // Ollama special case\n if (serverId === 'ollama') {\n const response = await fetch(endpoint.url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ model, messages, stream: false }),\n });\n if (!response.ok) throw new Error(`⚠️ Ollama အမှား (${response.status}): Server မှာ အမှားဖြစ်နေပါသည်။`);\n const data = await response.json();\n return { content: data.message?.content || 'No response' };\n }\n\n // Gemini special case\n if (serverId === 'gemini') {\n const geminiEndpoint = `https://generativelanguage.googleapis.com/v1beta/models/${model}:generateContent?key=${apiKey}`;\n const response = await fetch(geminiEndpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n contents: messages.map(m => ({ role: m.role === 'user' ? 'user' : 'model', parts: [{ text: m.content }] }))\n }),\n });\n if (!response.ok) {\n if (response.status === 404) throw new Error(`🔍 Gemini Model မရှိပါ။\\n\\n\"${model}\" သည် မရှိသော Model ဖြစ်ပါသည်။\\n\\n🔧 ဖြေရှင်းနည်း: Model ID ကို စစ်ဆေးပါ။`);\n throw new Error(`⚠️ Gemini အမှား (${response.status}): Server မှာ အမှားဖြစ်နေပါသည်။`);\n }\n const data = await response.json();\n return { content: data.candidates?.[0]?.content?.parts?.[0]?.text || 'No response' };\n }\n\n // Claude special case\n if (serverId === 'claude') {\n const response = await fetch(endpoint.url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n 'anthropic-version': '2023-06-01',\n },\n body: JSON.stringify({ model, max_tokens: 4096, messages: messages.map(m => ({ role: m.role, content: m.content })) }),\n });\n if (!response.ok) throw new Error(`⚠️ Claude အမှား (${response.status}): Server မှာ အမှားဖြစ်နေပါသည်။`);\n const data = await response.json();\n return { content: data.content?.[0]?.text || 'No response' };\n }\n\n // Cohere special case\n if (serverId === 'cohere') {\n const response = await fetch(endpoint.url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${apiKey}` },\n body: JSON.stringify({ model, messages: messages.map(m => ({ role: m.role === 'user' ? 'User' : 'Chatbot', message: m.content })) }),\n });\n if (!response.ok) throw new Error(`⚠️ Cohere အမှား (${response.status}): Server မှာ အမှားဖြစ်နေပါသည်။`);\n const data = await response.json();\n return { content: data.text || 'No response' };\n }\n\n // Standard OpenAI-compatible API\n const headers: Record = { 'Content-Type': 'application/json' };\n headers['Authorization'] = `Bearer ${apiKey}`;\n let body: Record = { model, messages };\n\n // ElevenLabs special case\n if (serverId === 'elevenlabs') {\n body = { text: messages[messages.length - 1]?.content, model_id: model };\n }\n\n const response = await fetch(endpoint.url, { method: 'POST', headers, body: JSON.stringify(body) });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n throw new Error(errorData.error?.message || `⚠️ API အမှား (${response.status}): Server မှာ အမှားဖြစ်နေပါသည်။`);\n }\n\n const data = await response.json();\n\n // Extract response\n let content = '';\n if (data.choices?.[0]?.message?.content) {\n content = data.choices[0].message.content;\n } else if (data.choices?.[0]?.text) {\n content = data.choices[0].text;\n } else if (data.choices?.[0]?.delta?.content) {\n content = data.choices[0].delta.content;\n }\n\n return { content: content || 'No response' };\n },\n\n getEndpoint: (serverId: string): string | undefined => API_ENDPOINTS[serverId]?.url,\n};\n"}, "18bab7a9ae5bb9c4c88db033b15ce88914df160c": {"t": 1785759145.084279, "n": 23885, "h": "068b1e487ad1b6a5", "c": "import type { ApiTestResult } from '../types/api.types';\n\n// Real API Endpoints\nconst API_ENDPOINTS: Record = {\n 'openai': { url: 'https://api.openai.com/v1/chat/completions', method: 'POST' },\n 'gemini': { url: 'https://generativelanguage.googleapis.com/v1beta/models', method: 'POST' },\n 'claude': { url: 'https://api.anthropic.com/v1/messages', method: 'POST' },\n 'deepseek': { url: 'https://api.deepseek.com/chat/completions', method: 'POST' },\n 'groq': { url: 'https://api.groq.com/openai/v1/chat/completions', method: 'POST' },\n 'together': { url: 'https://api.together.xyz/v1/chat/completions', method: 'POST' },\n 'openrouter': { url: 'https://openrouter.ai/api/v1/chat/completions', method: 'POST' },\n 'perplexity': { url: 'https://api.perplexity.ai/chat/completions', method: 'POST' },\n 'mistral': { url: 'https://api.mistral.ai/v1/chat/completions', method: 'POST' },\n 'cohere': { url: 'https://api.cohere.ai/v1/chat', method: 'POST' },\n 'cerebras': { url: 'https://api.cerebras.ai/v1/chat/completions', method: 'POST' },\n 'grok': { url: 'https://api.x.ai/v1/chat/completions', method: 'POST' },\n 'anyscale': { url: 'https://api.endpoints.anyscale.com/v1/chat/completions', method: 'POST' },\n 'ollama': { url: 'http://localhost:11434/api/chat', method: 'POST' },\n 'minimax': { url: 'https://api.minimax.chat/v1/text/chatcompletion_v2', method: 'POST' },\n 'elevenlabs': { url: 'https://api.elevenlabs.io/v1/text-to-speech', method: 'POST' },\n 'nvidia': { url: 'https://integrate.api.nvidia.com/v1/chat/completions', method: 'POST' },\n // New Providers\n 'fireworks': { url: 'https://api.fireworks.ai/inference/v1/chat/completions', method: 'POST' },\n 'replicate': { url: 'https://api.replicate.com/v1/predictions', method: 'POST' },\n 'cloudflare': { url: 'https://api.cloudflare.com/client/v4/accounts/workers/ai/run', method: 'POST' },\n 'lepton': { url: 'https://api.lepton.ai/v1/chat/completions', method: 'POST' },\n 'novita': { url: 'https://api.novita.ai/v3/chat/completions', method: 'POST' },\n 'hyperbolic': { url: 'https://api.hyperbolic.xyz/v1/chat/completions', method: 'POST' },\n};\n\nexport const apiService = {\n testApiKey: async (serverId: string, apiKey: string): Promise => {\n const startTime = Date.now();\n try {\n await new Promise(resolve => setTimeout(resolve, 1500));\n const latency = Date.now() - startTime;\n const isValid = apiKey.length >= 10 && !apiKey.includes(' ');\n return {\n success: isValid,\n message: isValid ? `API key validated for ${serverId}! Ready to use.` : 'Invalid API key format.',\n server: serverId,\n timestamp: new Date(),\n latency,\n };\n } catch (error) {\n return { success: false, message: 'Connection failed.', server: serverId, timestamp: new Date(), latency: Date.now() - startTime };\n }\n },\n\n sendMessage: async (serverId: string, apiKey: string, model: string, messages: { role: string; content: string }[]): Promise => {\n const endpoint = API_ENDPOINTS[serverId];\n if (!endpoint) throw new Error(`Unsupported server: ${serverId}`);\n\n // Ollama special case\n if (serverId === 'ollama') {\n const response = await fetch(endpoint.url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ model, messages, stream: false }),\n });\n if (!response.ok) throw new Error(`Ollama error: ${response.status}`);\n const data = await response.json();\n return data.message?.content || 'No response';\n }\n\n // Gemini special case\n if (serverId === 'gemini') {\n const geminiEndpoint = `https://generativelanguage.googleapis.com/v1beta/models/${model}:generateContent?key=${apiKey}`;\n const response = await fetch(geminiEndpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n contents: messages.map(m => ({ role: m.role === 'user' ? 'user' : 'model', parts: [{ text: m.content }] }))\n }),\n });\n if (!response.ok) throw new Error(`Gemini error: ${response.status}`);\n const data = await response.json();\n return data.candidates?.[0]?.content?.parts?.[0]?.text || 'No response';\n }\n\n // Claude special case\n if (serverId === 'claude') {\n const response = await fetch(endpoint.url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n 'anthropic-version': '2023-06-01',\n },\n body: JSON.stringify({ model, max_tokens: 4096, messages: messages.map(m => ({ role: m.role, content: m.content })) }),\n });\n if (!response.ok) throw new Error(`Claude error: ${response.status}`);\n const data = await response.json();\n return data.content?.[0]?.text || 'No response';\n }\n\n // Cohere special case\n if (serverId === 'cohere') {\n const response = await fetch(endpoint.url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${apiKey}` },\n body: JSON.stringify({ model, messages: messages.map(m => ({ role: m.role === 'user' ? 'User' : 'Chatbot', message: m.content })) }),\n });\n if (!response.ok) throw new Error(`Cohere error: ${response.status}`);\n const data = await response.json();\n return data.text || 'No response';\n }\n\n // Standard OpenAI-compatible API\n const headers: Record = { 'Content-Type': 'application/json' };\n let body: Record = { model, messages };\n\n // Add auth headers\n if (serverId === 'openrouter') {\n headers['Authorization'] = `Bearer ${apiKey}`;\n headers['HTTP-Referer'] = window.location.origin;\n headers['X-Title'] = 'API Test Hub';\n } else {\n headers['Authorization'] = `Bearer ${apiKey}`;\n }\n\n // ElevenLabs special case\n if (serverId === 'elevenlabs') {\n body = { text: messages[messages.length - 1]?.content, model_id: model };\n }\n\n const response = await fetch(endpoint.url, { method: 'POST', headers, body: JSON.stringify(body) });\n\n if (!response.ok) {\n let errorData: Record = {};\n let errorText = '';\n \n // Try to parse JSON error response\n try {\n errorData = await response.json();\n } catch {\n // If not JSON, try to get text\n try {\n errorText = await response.text();\n } catch {\n errorText = '';\n }\n }\n \n // Extract error information from various possible locations\n const errorMessage = \n (errorData as any)?.error?.message || \n (errorData as any)?.message || \n (errorData as any)?.error?.type ||\n (errorData as any)?.type ||\n errorText || \n '';\n const errorCode = (errorData as any)?.error?.code || (errorData as any)?.code || '';\n const errorStatus = response.status;\n const errorModel = (errorData as any)?.error?.meta?.model_name || (errorData as any)?.model || model;\n \n // ===== API Key Expired / Invalid Errors =====\n if (\n errorMessage.includes('api_key_expired') || \n errorMessage.includes('API key has expired') ||\n errorMessage.includes('expired') ||\n errorCode.includes('expired') ||\n errorMessage.includes('key_expired')\n ) {\n throw new Error(`❌ API သော့ သက်တမ်းကုန်သွားပါပြီ။\\n\\nသင်၏ API သော့သည် သက်တမ်းလွန်နေပါပြီ။\\n\\n🔧 ဖြေရှင်းနည်း: API သော့အသစ်ထုတ်ယူပြီး ပြန်လည်ကြိုးစားပါ။`);\n }\n\n // ===== Invalid API Key Errors =====\n if (\n errorMessage.includes('invalid_api_key') || \n errorMessage.includes('Incorrect API key') ||\n errorMessage.includes('invalid api key') ||\n errorCode.includes('invalid_api_key') ||\n errorMessage.includes('api_key_invalid')\n ) {\n throw new Error(`❌ API Key Error!\\n\\nသင်၏ API key မှာ မှားယွင်းနေပါသည်။\\n\\n🔧 ဖြေရှင်းနည်း: API key ကို စစ်ဆေးပြီး ပြန်လည်ထည့်သွင်းပါ။`);\n }\n\n // ===== No Endpoints / Model Not Found =====\n if (\n errorMessage.toLowerCase().includes('no endpoints found') || \n errorMessage.toLowerCase().includes('model not found') ||\n errorMessage.toLowerCase().includes('model_not_found') ||\n errorCode.toLowerCase().includes('model_not_found') ||\n errorMessage.toLowerCase().includes('does not exist') ||\n errorMessage.toLowerCase().includes('not found for model') ||\n errorMessage.toLowerCase().includes('no valid routes')\n ) {\n throw new Error(`❌ Model မရရှိနိုင်ပါ။\\n\\n\"${errorModel}\" သည် သင်၏ API အကောင့်တွင် ရရှိနိုင်မှုမရှိပါ။\\n\\n🔧 ဖြေရှင်းနည်း:\\n• ဤ Model သည် Free tier တွင် မရရှိပါ\\n• OpenRouter တွင် Credits $1+ ထည့်သွင်းပါ\\n• Free tier Model များဖြစ်သော Gemma, Llama 3.1 8B, Mistral စသည်တို့ကို စမ်းသုံးကြည့်ပါ`);\n }\n\n // ===== Rate Limit Errors =====\n if (\n errorMessage.includes('rate_limit') || \n errorMessage.includes('Rate limit') ||\n errorMessage.includes('rate limit exceeded') ||\n errorCode.includes('rate_limit') ||\n errorMessage.includes('too many requests')\n ) {\n throw new Error(`⏳ Rate Limit ကျော်လွန်သွားပါပြီ။\\n\\nသင်အသုံးပြုမှုပမာဏသည် ကန့်သတ်ချက်ထက် မြင့်တက်သွားပါပြီ။\\n\\n🔧 ဖြေရှင်းနည်း: ခဏစောင့်ဆိုင်းပြီးနောက် ပြန်လည်ကြိုးစားပါ။`);\n }\n\n // ===== Insufficient Quota / Credits =====\n if (\n errorMessage.includes('insufficient_quota') || \n errorMessage.includes('quota') ||\n errorMessage.includes('Insufficient credits') ||\n errorMessage.includes('not enough credits') ||\n errorCode.includes('quota')\n ) {\n throw new Error(`💰 API သော့ Quota ကုန်ဆုံးသွားပါပြီ။\\n\\nသင်၏ API အကောင့်တွင် လက်ကျန်ငွေမရှိတော့ပါ။\\n\\n🔧 ဖြေရှင်းနည်း: သင်၏ API အကောင့်တွင် ငွေကြေးထည့်သွင်းပါ။`);\n }\n\n // ===== 401 Unauthorized =====\n if (errorStatus === 401) {\n throw new Error(`🔐 API သော့ တရားဝင်မဟုတ်ပါ။\\n\\nဤ API သော့သည် တရားဝင်မှုမရှိတော့ပါ (401 Unauthorized)။\\n\\n🔧 ဖြေရှင်းနည်း: API သော့အသစ်ထုတ်ယူပါ။`);\n }\n\n // ===== 403 Forbidden =====\n if (errorStatus === 403) {\n throw new Error(`🚫 ဝင်ခွင့်ငြင်းပယ်ခြင်း။\\n\\nဤ API သော့မှာ ဤဆောင်ရွက်မှုအတွက် ခွင့်မပြုပါ (403 Forbidden)။\\n\\n🔧 ဖြေရှင်းနည်း: API သော့၏ ခွင့်ပြုချက်များကို စစ်ဆေးပါ။`);\n }\n\n // ===== 429 Too Many Requests =====\n if (errorStatus === 429) {\n throw new Error(`⏰ တောင်းဆိုမှုအရမ်းများနေပါသည်။\\n\\nသင်၏ တောင်းဆိုမှုများသည် အရမ်းများနေပါပြီ (429 Too Many Requests)။\\n\\n🔧 ဖြေရှင်းနည်း: ခဏစောင့်ဆိုင်းပြီးနောက် ပြန်လည်ကြိုးစားပါ။`);\n }\n\n // ===== 500 Internal Server Error =====\n if (errorStatus >= 500) {\n throw new Error(`🛠️ Server အမှားဖြစ်ပါသည်။\\n\\nAPI Provider Server မှာ အမှားဖြစ်နေပါ (${errorStatus} Internal Server Error)။\\n\\n🔧 ဖြေရှင်းနည်း: ခဏစောင့်ဆိုင်းပြီးနောက် ပြန်လည်ကြိုးစားပါ။`);\n }\n\n // ===== Default Error =====\n throw new Error(`⚠️ API Error (${errorStatus}): ${errorMessage || 'အမည်မသိအမှားဖြစ်ပါသည်။'}`);\n }\n\n const data = await response.json();\n\n // Extract response - handle various API response formats\n let content = '';\n\n // Standard OpenAI-compatible format\n if (data.choices?.[0]?.message?.content) {\n content = data.choices[0].message.content;\n }\n // Alternative format with text field\n else if (data.choices?.[0]?.text) {\n content = data.choices[0].text;\n }\n // StreamLake/DeepSeek format with choices array\n else if (data.choices?.[0]?.delta?.content) {\n content = data.choices[0].delta.content;\n }\n // Generic choices array iteration\n else if (data.choices && data.choices.length > 0) {\n const firstChoice = data.choices[0];\n content = firstChoice.message?.content || firstChoice.delta?.content || firstChoice.text || '';\n }\n // Response as direct string\n else if (typeof data === 'string') {\n content = data;\n }\n // Response with response or text field at root\n else if (data.response) {\n content = typeof data.response === 'string' ? data.response : data.response.choices?.[0]?.message?.content || JSON.stringify(data.response);\n }\n else if (data.text) {\n content = data.text;\n }\n\n // Clean up content - remove any JSON metadata that might be included\n if (content && typeof content === 'string') {\n // Check if content starts with JSON-like pattern and try to extract actual text\n const jsonMatch = content.match(/^\\s*\\{.*\\}\\s*$/);\n if (jsonMatch && !content.includes('\\n') && content.length < 500) {\n try {\n const parsed = JSON.parse(content);\n // If it's JSON, try to extract meaningful content\n content = parsed.content || parsed.message || parsed.text || parsed.choices?.[0]?.message?.content || parsed.choices?.[0]?.text || content;\n } catch {\n // Not valid JSON, keep original\n }\n }\n }\n\n return content || 'No response';\n },\n\n sendMessageWithThinking: async (serverId: string, apiKey: string, model: string, messages: { role: string; content: string }[]): Promise<{ content: string; thinking?: string }> => {\n // Handle DeepSeek reasoning content\n if (serverId === 'deepseek' || serverId === 'openrouter') {\n const endpoint = API_ENDPOINTS[serverId];\n if (!endpoint) throw new Error(`Unsupported server: ${serverId}`);\n\n const headers: Record = { 'Content-Type': 'application/json' };\n let body: Record = { model, messages };\n\n if (serverId === 'openrouter') {\n headers['Authorization'] = `Bearer ${apiKey}`;\n headers['HTTP-Referer'] = window.location.origin;\n headers['X-Title'] = 'API Test Hub';\n } else {\n headers['Authorization'] = `Bearer ${apiKey}`;\n }\n\n const response = await fetch(endpoint.url, { method: 'POST', headers, body: JSON.stringify(body) });\n\n if (!response.ok) {\n let errorData: Record = {};\n let errorText = '';\n \n // Try to parse JSON error response\n try {\n errorData = await response.json();\n } catch {\n // If not JSON, try to get text\n try {\n errorText = await response.text();\n } catch {\n errorText = '';\n }\n }\n \n // Extract error information from various possible locations\n const errorMessage = \n (errorData as any)?.error?.message || \n (errorData as any)?.message || \n (errorData as any)?.error?.type ||\n (errorData as any)?.type ||\n errorText || \n '';\n const errorCode = (errorData as any)?.error?.code || (errorData as any)?.code || '';\n const errorStatus = response.status;\n const errorModel = (errorData as any)?.error?.meta?.model_name || (errorData as any)?.model || model;\n \n // ===== API Key Expired / Invalid Errors =====\n if (\n errorMessage.includes('api_key_expired') || \n errorMessage.includes('API key has expired') ||\n errorMessage.includes('expired') ||\n errorCode.includes('expired') ||\n errorMessage.includes('key_expired')\n ) {\n throw new Error(`❌ API သော့ သက်တမ်းကုန်သွားပါပြီ။\\n\\nသင်၏ API သော့သည် သက်တမ်းလွန်နေပါပြီ။\\n\\n🔧 ဖြေရှင်းနည်း: API သော့အသစ်ထုတ်ယူပြီး ပြန်လည်ကြိုးစားပါ။`);\n }\n\n // ===== Invalid API Key Errors =====\n if (\n errorMessage.includes('invalid_api_key') || \n errorMessage.includes('Incorrect API key') ||\n errorMessage.includes('invalid api key') ||\n errorCode.includes('invalid_api_key') ||\n errorMessage.includes('api_key_invalid')\n ) {\n throw new Error(`❌ API Key Error!\\n\\nသင်၏ API key မှာ မှားယွင်းနေပါသည်။\\n\\n🔧 ဖြေရှင်းနည်း: API key ကို စစ်ဆေးပြီး ပြန်လည်ထည့်သွင်းပါ။`);\n }\n\n // ===== No Endpoints / Model Not Found =====\n if (\n errorMessage.toLowerCase().includes('no endpoints found') || \n errorMessage.toLowerCase().includes('model not found') ||\n errorMessage.toLowerCase().includes('model_not_found') ||\n errorCode.toLowerCase().includes('model_not_found') ||\n errorMessage.toLowerCase().includes('does not exist') ||\n errorMessage.toLowerCase().includes('not found for model') ||\n errorMessage.toLowerCase().includes('no valid routes')\n ) {\n throw new Error(`❌ Model မရရှိနိုင်ပါ။\\n\\n\"${errorModel}\" သည် သင်၏ API အကောင့်တွင် ရရှိနိုင်မှုမရှိပါ။\\n\\n🔧 ဖြေရှင်းနည်း:\\n• ဤ Model သည် Free tier တွင် မရရှိပါ\\n• OpenRouter တွင် Credits $1+ ထည့်သွင်းပါ\\n• Free tier Model များဖြစ်သော Gemma, Llama 3.1 8B, Mistral စသည်တို့ကို စမ်းသုံးကြည့်ပါ`);\n }\n\n // ===== Rate Limit Errors =====\n if (\n errorMessage.includes('rate_limit') || \n errorMessage.includes('Rate limit') ||\n errorMessage.includes('rate limit exceeded') ||\n errorCode.includes('rate_limit') ||\n errorMessage.includes('too many requests')\n ) {\n throw new Error(`⏳ Rate Limit ကျော်လွန်သွားပါပြီ။\\n\\nသင်အသုံးပြုမှုပမာဏသည် ကန့်သတ်ချက်ထက် မြင့်တက်သွားပါပြီ။\\n\\n🔧 ဖြေရှင်းနည်း: ခဏစောင့်ဆိုင်းပြီးနောက် ပြန်လည်ကြိုးစားပါ။`);\n }\n\n // ===== Insufficient Quota / Credits =====\n if (\n errorMessage.includes('insufficient_quota') || \n errorMessage.includes('quota') ||\n errorMessage.includes('Insufficient credits') ||\n errorMessage.includes('not enough credits') ||\n errorCode.includes('quota')\n ) {\n throw new Error(`💰 API သော့ Quota ကုန်ဆုံးသွားပါပြီ။\\n\\nသင်၏ API အကောင့်တွင် လက်ကျန်ငွေမရှိတော့ပါ။\\n\\n🔧 ဖြေရှင်းနည်း: သင်၏ API အကောင့်တွင် ငွေကြေးထည့်သွင်းပါ။`);\n }\n\n // ===== 401 Unauthorized =====\n if (errorStatus === 401) {\n throw new Error(`🔐 API သော့ တရားဝင်မဟုတ်ပါ။\\n\\nဤ API သော့သည် တရားဝင်မှုမရှိတော့ပါ (401 Unauthorized)။\\n\\n🔧 ဖြေရှင်းနည်း: API သော့အသစ်ထုတ်ယူပါ။`);\n }\n\n // ===== 403 Forbidden =====\n if (errorStatus === 403) {\n throw new Error(`🚫 ဝင်ခွင့်ငြင်းပယ်ခြင်း။\\n\\nဤ API သော့မှာ ဤဆောင်ရွက်မှုအတွက် ခွင့်မပြုပါ (403 Forbidden)။\\n\\n🔧 ဖြေရှင်းနည်း: API သော့၏ ခွင့်ပြုချက်များကို စစ်ဆေးပါ။`);\n }\n\n // ===== 429 Too Many Requests =====\n if (errorStatus === 429) {\n throw new Error(`⏰ တောင်းဆိုမှုအရမ်းများနေပါသည်။\\n\\nသင်၏ တောင်းဆိုမှုများသည် အရမ်းများနေပါပြီ (429 Too Many Requests)။\\n\\n🔧 ဖြေရှင်းနည်း: ခဏစောင့်ဆိုင်းပြီးနောက် ပြန်လည်ကြိုးစားပါ။`);\n }\n\n // ===== 500 Internal Server Error =====\n if (errorStatus >= 500) {\n throw new Error(`🛠️ Server အမှားဖြစ်ပါသည်။\\n\\nAPI Provider Server မှာ အမှားဖြစ်နေပါ (${errorStatus} Internal Server Error)။\\n\\n🔧 ဖြေရှင်းနည်း: ခဏစောင့်ဆိုင်းပြီးနောက် ပြန်လည်ကြိုးစားပါ။`);\n }\n\n // ===== Default Error =====\n throw new Error(`⚠️ API Error (${errorStatus}): ${errorMessage || 'အမည်မသိအမှားဖြစ်ပါသည်။'}`);\n }\n\n const data = await response.json();\n \n // Try to extract reasoning/thinking content\n let thinking: string | undefined;\n let content = '';\n\n // DeepSeek reasoning format\n if (data.choices?.[0]?.message?.reasoning) {\n thinking = data.choices[0].message.reasoning;\n }\n // OpenAI o1 style reasoning\n else if (data.choices?.[0]?.message?.reasoning !== undefined) {\n thinking = data.choices[0].message.reasoning;\n }\n // Anthropic Claude extended thinking\n else if (data.choices?.[0]?.message?.thinking) {\n thinking = data.choices[0].message.thinking;\n }\n \n // Extract content\n if (data.choices?.[0]?.message?.content) {\n content = data.choices[0].message.content;\n } else if (data.choices?.[0]?.text) {\n content = data.choices[0].text;\n } else if (data.choices?.[0]?.delta?.content) {\n content = data.choices[0].delta.content;\n }\n\n return { content: content || 'No response', thinking };\n }\n\n // Default behavior for other servers - use direct fetch logic\n const endpoint = API_ENDPOINTS[serverId];\n if (!endpoint) throw new Error(`Unsupported server: ${serverId}`);\n\n // Ollama special case\n if (serverId === 'ollama') {\n const response = await fetch(endpoint.url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ model, messages, stream: false }),\n });\n if (!response.ok) throw new Error(`Ollama error: ${response.status}`);\n const data = await response.json();\n return { content: data.message?.content || 'No response' };\n }\n\n // Gemini special case\n if (serverId === 'gemini') {\n const geminiEndpoint = `https://generativelanguage.googleapis.com/v1beta/models/${model}:generateContent?key=${apiKey}`;\n const response = await fetch(geminiEndpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n contents: messages.map(m => ({ role: m.role === 'user' ? 'user' : 'model', parts: [{ text: m.content }] }))\n }),\n });\n if (!response.ok) throw new Error(`Gemini error: ${response.status}`);\n const data = await response.json();\n return { content: data.candidates?.[0]?.content?.parts?.[0]?.text || 'No response' };\n }\n\n // Claude special case\n if (serverId === 'claude') {\n const response = await fetch(endpoint.url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n 'anthropic-version': '2023-06-01',\n },\n body: JSON.stringify({ model, max_tokens: 4096, messages: messages.map(m => ({ role: m.role, content: m.content })) }),\n });\n if (!response.ok) throw new Error(`Claude error: ${response.status}`);\n const data = await response.json();\n return { content: data.content?.[0]?.text || 'No response' };\n }\n\n // Cohere special case\n if (serverId === 'cohere') {\n const response = await fetch(endpoint.url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${apiKey}` },\n body: JSON.stringify({ model, messages: messages.map(m => ({ role: m.role === 'user' ? 'User' : 'Chatbot', message: m.content })) }),\n });\n if (!response.ok) throw new Error(`Cohere error: ${response.status}`);\n const data = await response.json();\n return { content: data.text || 'No response' };\n }\n\n // Standard OpenAI-compatible API\n const headers: Record = { 'Content-Type': 'application/json' };\n headers['Authorization'] = `Bearer ${apiKey}`;\n let body: Record = { model, messages };\n\n // ElevenLabs special case\n if (serverId === 'elevenlabs') {\n body = { text: messages[messages.length - 1]?.content, model_id: model };\n }\n\n const response = await fetch(endpoint.url, { method: 'POST', headers, body: JSON.stringify(body) });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n throw new Error(errorData.error?.message || `API Error: ${response.status}`);\n }\n\n const data = await response.json();\n\n // Extract response\n let content = '';\n if (data.choices?.[0]?.message?.content) {\n content = data.choices[0].message.content;\n } else if (data.choices?.[0]?.text) {\n content = data.choices[0].text;\n } else if (data.choices?.[0]?.delta?.content) {\n content = data.choices[0].delta.content;\n }\n\n return { content: content || 'No response' };\n },\n\n getEndpoint: (serverId: string): string | undefined => API_ENDPOINTS[serverId]?.url,\n};\n"}, "5cdc0b7af7862e9fd803fcfd01bf72ecbcbb9eb3": {"t": 1785759147.1876795, "n": 23877, "h": "e5ddfca72ea52c2c", "c": "import type { ApiTestResult } from '../types/api.types';\n\n// Real API Endpoints\nconst API_ENDPOINTS: Record = {\n 'openai': { url: 'https://api.openai.com/v1/chat/completions', method: 'POST' },\n 'gemini': { url: 'https://generativelanguage.googleapis.com/v1beta/models', method: 'POST' },\n 'claude': { url: 'https://api.anthropic.com/v1/messages', method: 'POST' },\n 'deepseek': { url: 'https://api.deepseek.com/chat/completions', method: 'POST' },\n 'groq': { url: 'https://api.groq.com/openai/v1/chat/completions', method: 'POST' },\n 'together': { url: 'https://api.together.xyz/v1/chat/completions', method: 'POST' },\n 'openrouter': { url: 'https://openrouter.ai/api/v1/chat/completions', method: 'POST' },\n 'perplexity': { url: 'https://api.perplexity.ai/chat/completions', method: 'POST' },\n 'mistral': { url: 'https://api.mistral.ai/v1/chat/completions', method: 'POST' },\n 'cohere': { url: 'https://api.cohere.ai/v1/chat', method: 'POST' },\n 'cerebras': { url: 'https://api.cerebras.ai/v1/chat/completions', method: 'POST' },\n 'grok': { url: 'https://api.x.ai/v1/chat/completions', method: 'POST' },\n 'anyscale': { url: 'https://api.endpoints.anyscale.com/v1/chat/completions', method: 'POST' },\n 'ollama': { url: 'http://localhost:11434/api/chat', method: 'POST' },\n 'minimax': { url: 'https://api.minimax.chat/v1/text/chatcompletion_v2', method: 'POST' },\n 'elevenlabs': { url: 'https://api.elevenlabs.io/v1/text-to-speech', method: 'POST' },\n 'nvidia': { url: 'https://integrate.api.nvidia.com/v1/chat/completions', method: 'POST' },\n // New Providers\n 'fireworks': { url: 'https://api.fireworks.ai/inference/v1/chat/completions', method: 'POST' },\n 'replicate': { url: 'https://api.replicate.com/v1/predictions', method: 'POST' },\n 'cloudflare': { url: 'https://api.cloudflare.com/client/v4/accounts/workers/ai/run', method: 'POST' },\n 'lepton': { url: 'https://api.lepton.ai/v1/chat/completions', method: 'POST' },\n 'novita': { url: 'https://api.novita.ai/v3/chat/completions', method: 'POST' },\n 'hyperbolic': { url: 'https://api.hyperbolic.xyz/v1/chat/completions', method: 'POST' },\n};\n\nexport const apiService = {\n testApiKey: async (serverId: string, apiKey: string): Promise => {\n const startTime = Date.now();\n try {\n await new Promise(resolve => setTimeout(resolve, 1500));\n const latency = Date.now() - startTime;\n const isValid = apiKey.length >= 10 && !apiKey.includes(' ');\n return {\n success: isValid,\n message: isValid ? `API key validated for ${serverId}! Ready to use.` : 'Invalid API key format.',\n server: serverId,\n timestamp: new Date(),\n latency,\n };\n } catch (error) {\n return { success: false, message: 'Connection failed.', server: serverId, timestamp: new Date(), latency: Date.now() - startTime };\n }\n },\n\n sendMessage: async (serverId: string, apiKey: string, model: string, messages: { role: string; content: string }[]): Promise => {\n const endpoint = API_ENDPOINTS[serverId];\n if (!endpoint) throw new Error(`Unsupported server: ${serverId}`);\n\n // Ollama special case\n if (serverId === 'ollama') {\n const response = await fetch(endpoint.url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ model, messages, stream: false }),\n });\n if (!response.ok) throw new Error(`Ollama error: ${response.status}`);\n const data = await response.json();\n return data.message?.content || 'No response';\n }\n\n // Gemini special case\n if (serverId === 'gemini') {\n const geminiEndpoint = `https://generativelanguage.googleapis.com/v1beta/models/${model}:generateContent?key=${apiKey}`;\n const response = await fetch(geminiEndpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n contents: messages.map(m => ({ role: m.role === 'user' ? 'user' : 'model', parts: [{ text: m.content }] }))\n }),\n });\n if (!response.ok) throw new Error(`Gemini error: ${response.status}`);\n const data = await response.json();\n return data.candidates?.[0]?.content?.parts?.[0]?.text || 'No response';\n }\n\n // Claude special case\n if (serverId === 'claude') {\n const response = await fetch(endpoint.url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n 'anthropic-version': '2023-06-01',\n },\n body: JSON.stringify({ model, max_tokens: 4096, messages: messages.map(m => ({ role: m.role, content: m.content })) }),\n });\n if (!response.ok) throw new Error(`Claude error: ${response.status}`);\n const data = await response.json();\n return data.content?.[0]?.text || 'No response';\n }\n\n // Cohere special case\n if (serverId === 'cohere') {\n const response = await fetch(endpoint.url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${apiKey}` },\n body: JSON.stringify({ model, messages: messages.map(m => ({ role: m.role === 'user' ? 'User' : 'Chatbot', message: m.content })) }),\n });\n if (!response.ok) throw new Error(`Cohere error: ${response.status}`);\n const data = await response.json();\n return data.text || 'No response';\n }\n\n // Standard OpenAI-compatible API\n const headers: Record = { 'Content-Type': 'application/json' };\n let body: Record = { model, messages };\n\n // Add auth headers\n if (serverId === 'openrouter') {\n headers['Authorization'] = `Bearer ${apiKey}`;\n headers['HTTP-Referer'] = window.location.origin;\n headers['X-Title'] = 'API Test Hub';\n } else {\n headers['Authorization'] = `Bearer ${apiKey}`;\n }\n\n // ElevenLabs special case\n if (serverId === 'elevenlabs') {\n body = { text: messages[messages.length - 1]?.content, model_id: model };\n }\n\n const response = await fetch(endpoint.url, { method: 'POST', headers, body: JSON.stringify(body) });\n\n if (!response.ok) {\n let errorData: Record = {};\n let errorText = '';\n \n // Try to parse JSON error response\n try {\n errorData = await response.json();\n } catch {\n // If not JSON, try to get text\n try {\n errorText = await response.text();\n } catch {\n errorText = '';\n }\n }\n \n // Extract error information from various possible locations\n const errorMessage = \n (errorData as any)?.error?.message || \n (errorData as any)?.message || \n (errorData as any)?.error?.type ||\n (errorData as any)?.type ||\n errorText || \n '';\n const errorCode = (errorData as any)?.error?.code || (errorData as any)?.code || '';\n const errorStatus = response.status;\n const errorModel = (errorData as any)?.error?.meta?.model_name || (errorData as any)?.model || model;\n \n // ===== API Key Expired / Invalid Errors =====\n if (\n errorMessage.includes('api_key_expired') || \n errorMessage.includes('API key has expired') ||\n errorMessage.includes('expired') ||\n errorCode.includes('expired') ||\n errorMessage.includes('key_expired')\n ) {\n throw new Error(`❌ API သော့ သက်တမ်းကုန်သွားပါပြီ။\\n\\nသင်၏ API သော့သည် သက်တမ်းလွန်နေပါပြီ။\\n\\n🔧 ဖြေရှင်းနည်း: API သော့အသစ်ထုတ်ယူပြီး ပြန်လည်ကြိုးစားပါ။`);\n }\n\n // ===== Invalid API Key Errors =====\n if (\n errorMessage.includes('invalid_api_key') || \n errorMessage.includes('Incorrect API key') ||\n errorMessage.includes('invalid api key') ||\n errorCode.includes('invalid_api_key') ||\n errorMessage.includes('api_key_invalid')\n ) {\n throw new Error(`❌ API Key Error!\\n\\nYour API key is invalid or incorrect.\\n\\n🔧 Solution: Please check and re-enter your API key.`);\n }\n\n // ===== No Endpoints / Model Not Found =====\n if (\n errorMessage.toLowerCase().includes('no endpoints found') || \n errorMessage.toLowerCase().includes('model not found') ||\n errorMessage.toLowerCase().includes('model_not_found') ||\n errorCode.toLowerCase().includes('model_not_found') ||\n errorMessage.toLowerCase().includes('does not exist') ||\n errorMessage.toLowerCase().includes('not found for model') ||\n errorMessage.toLowerCase().includes('no valid routes')\n ) {\n throw new Error(`❌ Model မရရှိနိုင်ပါ။\\n\\n\"${errorModel}\" သည် သင်၏ API အကောင့်တွင် ရရှိနိုင်မှုမရှိပါ။\\n\\n🔧 ဖြေရှင်းနည်း:\\n• ဤ Model သည် Free tier တွင် မရရှိပါ\\n• OpenRouter တွင် Credits $1+ ထည့်သွင်းပါ\\n• Free tier Model များဖြစ်သော Gemma, Llama 3.1 8B, Mistral စသည်တို့ကို စမ်းသုံးကြည့်ပါ`);\n }\n\n // ===== Rate Limit Errors =====\n if (\n errorMessage.includes('rate_limit') || \n errorMessage.includes('Rate limit') ||\n errorMessage.includes('rate limit exceeded') ||\n errorCode.includes('rate_limit') ||\n errorMessage.includes('too many requests')\n ) {\n throw new Error(`⏳ Rate Limit ကျော်လွန်သွားပါပြီ။\\n\\nသင်အသုံးပြုမှုပမာဏသည် ကန့်သတ်ချက်ထက် မြင့်တက်သွားပါပြီ။\\n\\n🔧 ဖြေရှင်းနည်း: ခဏစောင့်ဆိုင်းပြီးနောက် ပြန်လည်ကြိုးစားပါ။`);\n }\n\n // ===== Insufficient Quota / Credits =====\n if (\n errorMessage.includes('insufficient_quota') || \n errorMessage.includes('quota') ||\n errorMessage.includes('Insufficient credits') ||\n errorMessage.includes('not enough credits') ||\n errorCode.includes('quota')\n ) {\n throw new Error(`💰 API သော့ Quota ကုန်ဆုံးသွားပါပြီ။\\n\\nသင်၏ API အကောင့်တွင် လက်ကျန်ငွေမရှိတော့ပါ။\\n\\n🔧 ဖြေရှင်းနည်း: သင်၏ API အကောင့်တွင် ငွေကြေးထည့်သွင်းပါ။`);\n }\n\n // ===== 401 Unauthorized =====\n if (errorStatus === 401) {\n throw new Error(`🔐 API သော့ တရားဝင်မဟုတ်ပါ။\\n\\nဤ API သော့သည် တရားဝင်မှုမရှိတော့ပါ (401 Unauthorized)။\\n\\n🔧 ဖြေရှင်းနည်း: API သော့အသစ်ထုတ်ယူပါ။`);\n }\n\n // ===== 403 Forbidden =====\n if (errorStatus === 403) {\n throw new Error(`🚫 ဝင်ခွင့်ငြင်းပယ်ခြင်း။\\n\\nဤ API သော့မှာ ဤဆောင်ရွက်မှုအတွက် ခွင့်မပြုပါ (403 Forbidden)။\\n\\n🔧 ဖြေရှင်းနည်း: API သော့၏ ခွင့်ပြုချက်များကို စစ်ဆေးပါ။`);\n }\n\n // ===== 429 Too Many Requests =====\n if (errorStatus === 429) {\n throw new Error(`⏰ တောင်းဆိုမှုအရမ်းများနေပါသည်။\\n\\nသင်၏ တောင်းဆိုမှုများသည် အရမ်းများနေပါပြီ (429 Too Many Requests)။\\n\\n🔧 ဖြေရှင်းနည်း: ခဏစောင့်ဆိုင်းပြီးနောက် ပြန်လည်ကြိုးစားပါ။`);\n }\n\n // ===== 500 Internal Server Error =====\n if (errorStatus >= 500) {\n throw new Error(`🛠️ Server အမှားဖြစ်ပါသည်။\\n\\nAPI Provider Server မှာ အမှားဖြစ်နေပါ (${errorStatus} Internal Server Error)။\\n\\n🔧 ဖြေရှင်းနည်း: ခဏစောင့်ဆိုင်းပြီးနောက် ပြန်လည်ကြိုးစားပါ။`);\n }\n\n // ===== Default Error =====\n throw new Error(`⚠️ API Error (${errorStatus}): ${errorMessage || 'အမည်မသိအမှားဖြစ်ပါသည်။'}`);\n }\n\n const data = await response.json();\n\n // Extract response - handle various API response formats\n let content = '';\n\n // Standard OpenAI-compatible format\n if (data.choices?.[0]?.message?.content) {\n content = data.choices[0].message.content;\n }\n // Alternative format with text field\n else if (data.choices?.[0]?.text) {\n content = data.choices[0].text;\n }\n // StreamLake/DeepSeek format with choices array\n else if (data.choices?.[0]?.delta?.content) {\n content = data.choices[0].delta.content;\n }\n // Generic choices array iteration\n else if (data.choices && data.choices.length > 0) {\n const firstChoice = data.choices[0];\n content = firstChoice.message?.content || firstChoice.delta?.content || firstChoice.text || '';\n }\n // Response as direct string\n else if (typeof data === 'string') {\n content = data;\n }\n // Response with response or text field at root\n else if (data.response) {\n content = typeof data.response === 'string' ? data.response : data.response.choices?.[0]?.message?.content || JSON.stringify(data.response);\n }\n else if (data.text) {\n content = data.text;\n }\n\n // Clean up content - remove any JSON metadata that might be included\n if (content && typeof content === 'string') {\n // Check if content starts with JSON-like pattern and try to extract actual text\n const jsonMatch = content.match(/^\\s*\\{.*\\}\\s*$/);\n if (jsonMatch && !content.includes('\\n') && content.length < 500) {\n try {\n const parsed = JSON.parse(content);\n // If it's JSON, try to extract meaningful content\n content = parsed.content || parsed.message || parsed.text || parsed.choices?.[0]?.message?.content || parsed.choices?.[0]?.text || content;\n } catch {\n // Not valid JSON, keep original\n }\n }\n }\n\n return content || 'No response';\n },\n\n sendMessageWithThinking: async (serverId: string, apiKey: string, model: string, messages: { role: string; content: string }[]): Promise<{ content: string; thinking?: string }> => {\n // Handle DeepSeek reasoning content\n if (serverId === 'deepseek' || serverId === 'openrouter') {\n const endpoint = API_ENDPOINTS[serverId];\n if (!endpoint) throw new Error(`Unsupported server: ${serverId}`);\n\n const headers: Record = { 'Content-Type': 'application/json' };\n let body: Record = { model, messages };\n\n if (serverId === 'openrouter') {\n headers['Authorization'] = `Bearer ${apiKey}`;\n headers['HTTP-Referer'] = window.location.origin;\n headers['X-Title'] = 'API Test Hub';\n } else {\n headers['Authorization'] = `Bearer ${apiKey}`;\n }\n\n const response = await fetch(endpoint.url, { method: 'POST', headers, body: JSON.stringify(body) });\n\n if (!response.ok) {\n let errorData: Record = {};\n let errorText = '';\n \n // Try to parse JSON error response\n try {\n errorData = await response.json();\n } catch {\n // If not JSON, try to get text\n try {\n errorText = await response.text();\n } catch {\n errorText = '';\n }\n }\n \n // Extract error information from various possible locations\n const errorMessage = \n (errorData as any)?.error?.message || \n (errorData as any)?.message || \n (errorData as any)?.error?.type ||\n (errorData as any)?.type ||\n errorText || \n '';\n const errorCode = (errorData as any)?.error?.code || (errorData as any)?.code || '';\n const errorStatus = response.status;\n const errorModel = (errorData as any)?.error?.meta?.model_name || (errorData as any)?.model || model;\n \n // ===== API Key Expired / Invalid Errors =====\n if (\n errorMessage.includes('api_key_expired') || \n errorMessage.includes('API key has expired') ||\n errorMessage.includes('expired') ||\n errorCode.includes('expired') ||\n errorMessage.includes('key_expired')\n ) {\n throw new Error(`❌ API သော့ သက်တမ်းကုန်သွားပါပြီ။\\n\\nသင်၏ API သော့သည် သက်တမ်းလွန်နေပါပြီ။\\n\\n🔧 ဖြေရှင်းနည်း: API သော့အသစ်ထုတ်ယူပြီး ပြန်လည်ကြိုးစားပါ။`);\n }\n\n // ===== Invalid API Key Errors =====\n if (\n errorMessage.includes('invalid_api_key') || \n errorMessage.includes('Incorrect API key') ||\n errorMessage.includes('invalid api key') ||\n errorCode.includes('invalid_api_key') ||\n errorMessage.includes('api_key_invalid')\n ) {\n throw new Error(`❌ API Key Error!\\n\\nYour API key is invalid or incorrect.\\n\\n🔧 Solution: Please check and re-enter your API key.`);\n }\n\n // ===== No Endpoints / Model Not Found =====\n if (\n errorMessage.toLowerCase().includes('no endpoints found') || \n errorMessage.toLowerCase().includes('model not found') ||\n errorMessage.toLowerCase().includes('model_not_found') ||\n errorCode.toLowerCase().includes('model_not_found') ||\n errorMessage.toLowerCase().includes('does not exist') ||\n errorMessage.toLowerCase().includes('not found for model') ||\n errorMessage.toLowerCase().includes('no valid routes')\n ) {\n throw new Error(`❌ Model မရရှိနိုင်ပါ။\\n\\n\"${errorModel}\" သည် သင်၏ API အကောင့်တွင် ရရှိနိုင်မှုမရှိပါ။\\n\\n🔧 ဖြေရှင်းနည်း:\\n• ဤ Model သည် Free tier တွင် မရရှိပါ\\n• OpenRouter တွင် Credits $1+ ထည့်သွင်းပါ\\n• Free tier Model များဖြစ်သော Gemma, Llama 3.1 8B, Mistral စသည်တို့ကို စမ်းသုံးကြည့်ပါ`);\n }\n\n // ===== Rate Limit Errors =====\n if (\n errorMessage.includes('rate_limit') || \n errorMessage.includes('Rate limit') ||\n errorMessage.includes('rate limit exceeded') ||\n errorCode.includes('rate_limit') ||\n errorMessage.includes('too many requests')\n ) {\n throw new Error(`⏳ Rate Limit ကျော်လွန်သွားပါပြီ။\\n\\nသင်အသုံးပြုမှုပမာဏသည် ကန့်သတ်ချက်ထက် မြင့်တက်သွားပါပြီ။\\n\\n🔧 ဖြေရှင်းနည်း: ခဏစောင့်ဆိုင်းပြီးနောက် ပြန်လည်ကြိုးစားပါ။`);\n }\n\n // ===== Insufficient Quota / Credits =====\n if (\n errorMessage.includes('insufficient_quota') || \n errorMessage.includes('quota') ||\n errorMessage.includes('Insufficient credits') ||\n errorMessage.includes('not enough credits') ||\n errorCode.includes('quota')\n ) {\n throw new Error(`💰 API သော့ Quota ကုန်ဆုံးသွားပါပြီ။\\n\\nသင်၏ API အကောင့်တွင် လက်ကျန်ငွေမရှိတော့ပါ။\\n\\n🔧 ဖြေရှင်းနည်း: သင်၏ API အကောင့်တွင် ငွေကြေးထည့်သွင်းပါ။`);\n }\n\n // ===== 401 Unauthorized =====\n if (errorStatus === 401) {\n throw new Error(`🔐 API သော့ တရားဝင်မဟုတ်ပါ။\\n\\nဤ API သော့သည် တရားဝင်မှုမရှိတော့ပါ (401 Unauthorized)။\\n\\n🔧 ဖြေရှင်းနည်း: API သော့အသစ်ထုတ်ယူပါ။`);\n }\n\n // ===== 403 Forbidden =====\n if (errorStatus === 403) {\n throw new Error(`🚫 ဝင်ခွင့်ငြင်းပယ်ခြင်း။\\n\\nဤ API သော့မှာ ဤဆောင်ရွက်မှုအတွက် ခွင့်မပြုပါ (403 Forbidden)။\\n\\n🔧 ဖြေရှင်းနည်း: API သော့၏ ခွင့်ပြုချက်များကို စစ်ဆေးပါ။`);\n }\n\n // ===== 429 Too Many Requests =====\n if (errorStatus === 429) {\n throw new Error(`⏰ တောင်းဆိုမှုအရမ်းများနေပါသည်။\\n\\nသင်၏ တောင်းဆိုမှုများသည် အရမ်းများနေပါပြီ (429 Too Many Requests)။\\n\\n🔧 ဖြေရှင်းနည်း: ခဏစောင့်ဆိုင်းပြီးနောက် ပြန်လည်ကြိုးစားပါ။`);\n }\n\n // ===== 500 Internal Server Error =====\n if (errorStatus >= 500) {\n throw new Error(`🛠️ Server အမှားဖြစ်ပါသည်။\\n\\nAPI Provider Server မှာ အမှားဖြစ်နေပါ (${errorStatus} Internal Server Error)။\\n\\n🔧 ဖြေရှင်းနည်း: ခဏစောင့်ဆိုင်းပြီးနောက် ပြန်လည်ကြိုးစားပါ။`);\n }\n\n // ===== Default Error =====\n throw new Error(`⚠️ API Error (${errorStatus}): ${errorMessage || 'အမည်မသိအမှားဖြစ်ပါသည်။'}`);\n }\n\n const data = await response.json();\n \n // Try to extract reasoning/thinking content\n let thinking: string | undefined;\n let content = '';\n\n // DeepSeek reasoning format\n if (data.choices?.[0]?.message?.reasoning) {\n thinking = data.choices[0].message.reasoning;\n }\n // OpenAI o1 style reasoning\n else if (data.choices?.[0]?.message?.reasoning !== undefined) {\n thinking = data.choices[0].message.reasoning;\n }\n // Anthropic Claude extended thinking\n else if (data.choices?.[0]?.message?.thinking) {\n thinking = data.choices[0].message.thinking;\n }\n \n // Extract content\n if (data.choices?.[0]?.message?.content) {\n content = data.choices[0].message.content;\n } else if (data.choices?.[0]?.text) {\n content = data.choices[0].text;\n } else if (data.choices?.[0]?.delta?.content) {\n content = data.choices[0].delta.content;\n }\n\n return { content: content || 'No response', thinking };\n }\n\n // Default behavior for other servers - use direct fetch logic\n const endpoint = API_ENDPOINTS[serverId];\n if (!endpoint) throw new Error(`Unsupported server: ${serverId}`);\n\n // Ollama special case\n if (serverId === 'ollama') {\n const response = await fetch(endpoint.url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ model, messages, stream: false }),\n });\n if (!response.ok) throw new Error(`Ollama error: ${response.status}`);\n const data = await response.json();\n return { content: data.message?.content || 'No response' };\n }\n\n // Gemini special case\n if (serverId === 'gemini') {\n const geminiEndpoint = `https://generativelanguage.googleapis.com/v1beta/models/${model}:generateContent?key=${apiKey}`;\n const response = await fetch(geminiEndpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n contents: messages.map(m => ({ role: m.role === 'user' ? 'user' : 'model', parts: [{ text: m.content }] }))\n }),\n });\n if (!response.ok) throw new Error(`Gemini error: ${response.status}`);\n const data = await response.json();\n return { content: data.candidates?.[0]?.content?.parts?.[0]?.text || 'No response' };\n }\n\n // Claude special case\n if (serverId === 'claude') {\n const response = await fetch(endpoint.url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n 'anthropic-version': '2023-06-01',\n },\n body: JSON.stringify({ model, max_tokens: 4096, messages: messages.map(m => ({ role: m.role, content: m.content })) }),\n });\n if (!response.ok) throw new Error(`Claude error: ${response.status}`);\n const data = await response.json();\n return { content: data.content?.[0]?.text || 'No response' };\n }\n\n // Cohere special case\n if (serverId === 'cohere') {\n const response = await fetch(endpoint.url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${apiKey}` },\n body: JSON.stringify({ model, messages: messages.map(m => ({ role: m.role === 'user' ? 'User' : 'Chatbot', message: m.content })) }),\n });\n if (!response.ok) throw new Error(`Cohere error: ${response.status}`);\n const data = await response.json();\n return { content: data.text || 'No response' };\n }\n\n // Standard OpenAI-compatible API\n const headers: Record = { 'Content-Type': 'application/json' };\n headers['Authorization'] = `Bearer ${apiKey}`;\n let body: Record = { model, messages };\n\n // ElevenLabs special case\n if (serverId === 'elevenlabs') {\n body = { text: messages[messages.length - 1]?.content, model_id: model };\n }\n\n const response = await fetch(endpoint.url, { method: 'POST', headers, body: JSON.stringify(body) });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n throw new Error(errorData.error?.message || `API Error: ${response.status}`);\n }\n\n const data = await response.json();\n\n // Extract response\n let content = '';\n if (data.choices?.[0]?.message?.content) {\n content = data.choices[0].message.content;\n } else if (data.choices?.[0]?.text) {\n content = data.choices[0].text;\n } else if (data.choices?.[0]?.delta?.content) {\n content = data.choices[0].delta.content;\n }\n\n return { content: content || 'No response' };\n },\n\n getEndpoint: (serverId: string): string | undefined => API_ENDPOINTS[serverId]?.url,\n};\n"}, "93a89a103104b6c04ec9f32f10077f3eb5f6c1a5": {"t": 1785759149.2664442, "n": 23316, "h": "e99e5e0070d063c4", "c": "import type { ApiTestResult } from '../types/api.types';\n\n// Real API Endpoints\nconst API_ENDPOINTS: Record = {\n 'openai': { url: 'https://api.openai.com/v1/chat/completions', method: 'POST' },\n 'gemini': { url: 'https://generativelanguage.googleapis.com/v1beta/models', method: 'POST' },\n 'claude': { url: 'https://api.anthropic.com/v1/messages', method: 'POST' },\n 'deepseek': { url: 'https://api.deepseek.com/chat/completions', method: 'POST' },\n 'groq': { url: 'https://api.groq.com/openai/v1/chat/completions', method: 'POST' },\n 'together': { url: 'https://api.together.xyz/v1/chat/completions', method: 'POST' },\n 'openrouter': { url: 'https://openrouter.ai/api/v1/chat/completions', method: 'POST' },\n 'perplexity': { url: 'https://api.perplexity.ai/chat/completions', method: 'POST' },\n 'mistral': { url: 'https://api.mistral.ai/v1/chat/completions', method: 'POST' },\n 'cohere': { url: 'https://api.cohere.ai/v1/chat', method: 'POST' },\n 'cerebras': { url: 'https://api.cerebras.ai/v1/chat/completions', method: 'POST' },\n 'grok': { url: 'https://api.x.ai/v1/chat/completions', method: 'POST' },\n 'anyscale': { url: 'https://api.endpoints.anyscale.com/v1/chat/completions', method: 'POST' },\n 'ollama': { url: 'http://localhost:11434/api/chat', method: 'POST' },\n 'minimax': { url: 'https://api.minimax.chat/v1/text/chatcompletion_v2', method: 'POST' },\n 'elevenlabs': { url: 'https://api.elevenlabs.io/v1/text-to-speech', method: 'POST' },\n 'nvidia': { url: 'https://integrate.api.nvidia.com/v1/chat/completions', method: 'POST' },\n};\n\nexport const apiService = {\n testApiKey: async (serverId: string, apiKey: string): Promise => {\n const startTime = Date.now();\n try {\n await new Promise(resolve => setTimeout(resolve, 1500));\n const latency = Date.now() - startTime;\n const isValid = apiKey.length >= 10 && !apiKey.includes(' ');\n return {\n success: isValid,\n message: isValid ? `API key validated for ${serverId}! Ready to use.` : 'Invalid API key format.',\n server: serverId,\n timestamp: new Date(),\n latency,\n };\n } catch (error) {\n return { success: false, message: 'Connection failed.', server: serverId, timestamp: new Date(), latency: Date.now() - startTime };\n }\n },\n\n sendMessage: async (serverId: string, apiKey: string, model: string, messages: { role: string; content: string }[]): Promise => {\n const endpoint = API_ENDPOINTS[serverId];\n if (!endpoint) throw new Error(`Unsupported server: ${serverId}`);\n\n // Ollama special case\n if (serverId === 'ollama') {\n const response = await fetch(endpoint.url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ model, messages, stream: false }),\n });\n if (!response.ok) throw new Error(`Ollama error: ${response.status}`);\n const data = await response.json();\n return data.message?.content || 'No response';\n }\n\n // Gemini special case\n if (serverId === 'gemini') {\n const geminiEndpoint = `https://generativelanguage.googleapis.com/v1beta/models/${model}:generateContent?key=${apiKey}`;\n const response = await fetch(geminiEndpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n contents: messages.map(m => ({ role: m.role === 'user' ? 'user' : 'model', parts: [{ text: m.content }] }))\n }),\n });\n if (!response.ok) throw new Error(`Gemini error: ${response.status}`);\n const data = await response.json();\n return data.candidates?.[0]?.content?.parts?.[0]?.text || 'No response';\n }\n\n // Claude special case\n if (serverId === 'claude') {\n const response = await fetch(endpoint.url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n 'anthropic-version': '2023-06-01',\n },\n body: JSON.stringify({ model, max_tokens: 4096, messages: messages.map(m => ({ role: m.role, content: m.content })) }),\n });\n if (!response.ok) throw new Error(`Claude error: ${response.status}`);\n const data = await response.json();\n return data.content?.[0]?.text || 'No response';\n }\n\n // Cohere special case\n if (serverId === 'cohere') {\n const response = await fetch(endpoint.url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${apiKey}` },\n body: JSON.stringify({ model, messages: messages.map(m => ({ role: m.role === 'user' ? 'User' : 'Chatbot', message: m.content })) }),\n });\n if (!response.ok) throw new Error(`Cohere error: ${response.status}`);\n const data = await response.json();\n return data.text || 'No response';\n }\n\n // Standard OpenAI-compatible API\n const headers: Record = { 'Content-Type': 'application/json' };\n let body: Record = { model, messages };\n\n // Add auth headers\n if (serverId === 'openrouter') {\n headers['Authorization'] = `Bearer ${apiKey}`;\n headers['HTTP-Referer'] = window.location.origin;\n headers['X-Title'] = 'API Test Hub';\n } else {\n headers['Authorization'] = `Bearer ${apiKey}`;\n }\n\n // ElevenLabs special case\n if (serverId === 'elevenlabs') {\n body = { text: messages[messages.length - 1]?.content, model_id: model };\n }\n\n const response = await fetch(endpoint.url, { method: 'POST', headers, body: JSON.stringify(body) });\n\n if (!response.ok) {\n let errorData: Record = {};\n let errorText = '';\n \n // Try to parse JSON error response\n try {\n errorData = await response.json();\n } catch {\n // If not JSON, try to get text\n try {\n errorText = await response.text();\n } catch {\n errorText = '';\n }\n }\n \n // Extract error information from various possible locations\n const errorMessage = \n (errorData as any)?.error?.message || \n (errorData as any)?.message || \n (errorData as any)?.error?.type ||\n (errorData as any)?.type ||\n errorText || \n '';\n const errorCode = (errorData as any)?.error?.code || (errorData as any)?.code || '';\n const errorStatus = response.status;\n const errorModel = (errorData as any)?.error?.meta?.model_name || (errorData as any)?.model || model;\n \n // ===== API Key Expired / Invalid Errors =====\n if (\n errorMessage.includes('api_key_expired') || \n errorMessage.includes('API key has expired') ||\n errorMessage.includes('expired') ||\n errorCode.includes('expired') ||\n errorMessage.includes('key_expired')\n ) {\n throw new Error(`❌ API သော့ သက်တမ်းကုန်သွားပါပြီ။\\n\\nသင်၏ API သော့သည် သက်တမ်းလွန်နေပါပြီ။\\n\\n🔧 ဖြေရှင်းနည်း: API သော့အသစ်ထုတ်ယူပြီး ပြန်လည်ကြိုးစားပါ။`);\n }\n\n // ===== Invalid API Key Errors =====\n if (\n errorMessage.includes('invalid_api_key') || \n errorMessage.includes('Incorrect API key') ||\n errorMessage.includes('invalid api key') ||\n errorCode.includes('invalid_api_key') ||\n errorMessage.includes('api_key_invalid')\n ) {\n throw new Error(`❌ API Key Error!\\n\\nYour API key is invalid or incorrect.\\n\\n🔧 Solution: Please check and re-enter your API key.`);\n }\n\n // ===== No Endpoints / Model Not Found =====\n if (\n errorMessage.toLowerCase().includes('no endpoints found') || \n errorMessage.toLowerCase().includes('model not found') ||\n errorMessage.toLowerCase().includes('model_not_found') ||\n errorCode.toLowerCase().includes('model_not_found') ||\n errorMessage.toLowerCase().includes('does not exist') ||\n errorMessage.toLowerCase().includes('not found for model') ||\n errorMessage.toLowerCase().includes('no valid routes')\n ) {\n throw new Error(`❌ Model မရရှိနိုင်ပါ။\\n\\n\"${errorModel}\" သည် သင်၏ API အကောင့်တွင် ရရှိနိုင်မှုမရှိပါ။\\n\\n🔧 ဖြေရှင်းနည်း:\\n• ဤ Model သည် Free tier တွင် မရရှိပါ\\n• OpenRouter တွင် Credits $1+ ထည့်သွင်းပါ\\n• Free tier Model များဖြစ်သော Gemma, Llama 3.1 8B, Mistral စသည်တို့ကို စမ်းသုံးကြည့်ပါ`);\n }\n\n // ===== Rate Limit Errors =====\n if (\n errorMessage.includes('rate_limit') || \n errorMessage.includes('Rate limit') ||\n errorMessage.includes('rate limit exceeded') ||\n errorCode.includes('rate_limit') ||\n errorMessage.includes('too many requests')\n ) {\n throw new Error(`⏳ Rate Limit ကျော်လွန်သွားပါပြီ။\\n\\nသင်အသုံးပြုမှုပမာဏသည် ကန့်သတ်ချက်ထက် မြင့်တက်သွားပါပြီ။\\n\\n🔧 ဖြေရှင်းနည်း: ခဏစောင့်ဆိုင်းပြီးနောက် ပြန်လည်ကြိုးစားပါ။`);\n }\n\n // ===== Insufficient Quota / Credits =====\n if (\n errorMessage.includes('insufficient_quota') || \n errorMessage.includes('quota') ||\n errorMessage.includes('Insufficient credits') ||\n errorMessage.includes('not enough credits') ||\n errorCode.includes('quota')\n ) {\n throw new Error(`💰 API သော့ Quota ကုန်ဆုံးသွားပါပြီ။\\n\\nသင်၏ API အကောင့်တွင် လက်ကျန်ငွေမရှိတော့ပါ။\\n\\n🔧 ဖြေရှင်းနည်း: သင်၏ API အကောင့်တွင် ငွေကြေးထည့်သွင်းပါ။`);\n }\n\n // ===== 401 Unauthorized =====\n if (errorStatus === 401) {\n throw new Error(`🔐 API သော့ တရားဝင်မဟုတ်ပါ။\\n\\nဤ API သော့သည် တရားဝင်မှုမရှိတော့ပါ (401 Unauthorized)။\\n\\n🔧 ဖြေရှင်းနည်း: API သော့အသစ်ထုတ်ယူပါ။`);\n }\n\n // ===== 403 Forbidden =====\n if (errorStatus === 403) {\n throw new Error(`🚫 ဝင်ခွင့်ငြင်းပယ်ခြင်း။\\n\\nဤ API သော့မှာ ဤဆောင်ရွက်မှုအတွက် ခွင့်မပြုပါ (403 Forbidden)။\\n\\n🔧 ဖြေရှင်းနည်း: API သော့၏ ခွင့်ပြုချက်များကို စစ်ဆေးပါ။`);\n }\n\n // ===== 429 Too Many Requests =====\n if (errorStatus === 429) {\n throw new Error(`⏰ တောင်းဆိုမှုအရမ်းများနေပါသည်။\\n\\nသင်၏ တောင်းဆိုမှုများသည် အရမ်းများနေပါပြီ (429 Too Many Requests)။\\n\\n🔧 ဖြေရှင်းနည်း: ခဏစောင့်ဆိုင်းပြီးနောက် ပြန်လည်ကြိုးစားပါ။`);\n }\n\n // ===== 500 Internal Server Error =====\n if (errorStatus >= 500) {\n throw new Error(`🛠️ Server အမှားဖြစ်ပါသည်။\\n\\nAPI Provider Server မှာ အမှားဖြစ်နေပါ (${errorStatus} Internal Server Error)။\\n\\n🔧 ဖြေရှင်းနည်း: ခဏစောင့်ဆိုင်းပြီးနောက် ပြန်လည်ကြိုးစားပါ။`);\n }\n\n // ===== Default Error =====\n throw new Error(`⚠️ API Error (${errorStatus}): ${errorMessage || 'အမည်မသိအမှားဖြစ်ပါသည်။'}`);\n }\n\n const data = await response.json();\n\n // Extract response - handle various API response formats\n let content = '';\n\n // Standard OpenAI-compatible format\n if (data.choices?.[0]?.message?.content) {\n content = data.choices[0].message.content;\n }\n // Alternative format with text field\n else if (data.choices?.[0]?.text) {\n content = data.choices[0].text;\n }\n // StreamLake/DeepSeek format with choices array\n else if (data.choices?.[0]?.delta?.content) {\n content = data.choices[0].delta.content;\n }\n // Generic choices array iteration\n else if (data.choices && data.choices.length > 0) {\n const firstChoice = data.choices[0];\n content = firstChoice.message?.content || firstChoice.delta?.content || firstChoice.text || '';\n }\n // Response as direct string\n else if (typeof data === 'string') {\n content = data;\n }\n // Response with response or text field at root\n else if (data.response) {\n content = typeof data.response === 'string' ? data.response : data.response.choices?.[0]?.message?.content || JSON.stringify(data.response);\n }\n else if (data.text) {\n content = data.text;\n }\n\n // Clean up content - remove any JSON metadata that might be included\n if (content && typeof content === 'string') {\n // Check if content starts with JSON-like pattern and try to extract actual text\n const jsonMatch = content.match(/^\\s*\\{.*\\}\\s*$/);\n if (jsonMatch && !content.includes('\\n') && content.length < 500) {\n try {\n const parsed = JSON.parse(content);\n // If it's JSON, try to extract meaningful content\n content = parsed.content || parsed.message || parsed.text || parsed.choices?.[0]?.message?.content || parsed.choices?.[0]?.text || content;\n } catch {\n // Not valid JSON, keep original\n }\n }\n }\n\n return content || 'No response';\n },\n\n sendMessageWithThinking: async (serverId: string, apiKey: string, model: string, messages: { role: string; content: string }[]): Promise<{ content: string; thinking?: string }> => {\n // Handle DeepSeek reasoning content\n if (serverId === 'deepseek' || serverId === 'openrouter') {\n const endpoint = API_ENDPOINTS[serverId];\n if (!endpoint) throw new Error(`Unsupported server: ${serverId}`);\n\n const headers: Record = { 'Content-Type': 'application/json' };\n let body: Record = { model, messages };\n\n if (serverId === 'openrouter') {\n headers['Authorization'] = `Bearer ${apiKey}`;\n headers['HTTP-Referer'] = window.location.origin;\n headers['X-Title'] = 'API Test Hub';\n } else {\n headers['Authorization'] = `Bearer ${apiKey}`;\n }\n\n const response = await fetch(endpoint.url, { method: 'POST', headers, body: JSON.stringify(body) });\n\n if (!response.ok) {\n let errorData: Record = {};\n let errorText = '';\n \n // Try to parse JSON error response\n try {\n errorData = await response.json();\n } catch {\n // If not JSON, try to get text\n try {\n errorText = await response.text();\n } catch {\n errorText = '';\n }\n }\n \n // Extract error information from various possible locations\n const errorMessage = \n (errorData as any)?.error?.message || \n (errorData as any)?.message || \n (errorData as any)?.error?.type ||\n (errorData as any)?.type ||\n errorText || \n '';\n const errorCode = (errorData as any)?.error?.code || (errorData as any)?.code || '';\n const errorStatus = response.status;\n const errorModel = (errorData as any)?.error?.meta?.model_name || (errorData as any)?.model || model;\n \n // ===== API Key Expired / Invalid Errors =====\n if (\n errorMessage.includes('api_key_expired') || \n errorMessage.includes('API key has expired') ||\n errorMessage.includes('expired') ||\n errorCode.includes('expired') ||\n errorMessage.includes('key_expired')\n ) {\n throw new Error(`❌ API သော့ သက်တမ်းကုန်သွားပါပြီ။\\n\\nသင်၏ API သော့သည် သက်တမ်းလွန်နေပါပြီ။\\n\\n🔧 ဖြေရှင်းနည်း: API သော့အသစ်ထုတ်ယူပြီး ပြန်လည်ကြိုးစားပါ။`);\n }\n\n // ===== Invalid API Key Errors =====\n if (\n errorMessage.includes('invalid_api_key') || \n errorMessage.includes('Incorrect API key') ||\n errorMessage.includes('invalid api key') ||\n errorCode.includes('invalid_api_key') ||\n errorMessage.includes('api_key_invalid')\n ) {\n throw new Error(`❌ API Key Error!\\n\\nYour API key is invalid or incorrect.\\n\\n🔧 Solution: Please check and re-enter your API key.`);\n }\n\n // ===== No Endpoints / Model Not Found =====\n if (\n errorMessage.toLowerCase().includes('no endpoints found') || \n errorMessage.toLowerCase().includes('model not found') ||\n errorMessage.toLowerCase().includes('model_not_found') ||\n errorCode.toLowerCase().includes('model_not_found') ||\n errorMessage.toLowerCase().includes('does not exist') ||\n errorMessage.toLowerCase().includes('not found for model') ||\n errorMessage.toLowerCase().includes('no valid routes')\n ) {\n throw new Error(`❌ Model မရရှိနိုင်ပါ။\\n\\n\"${errorModel}\" သည် သင်၏ API အကောင့်တွင် ရရှိနိုင်မှုမရှိပါ။\\n\\n🔧 ဖြေရှင်းနည်း:\\n• ဤ Model သည် Free tier တွင် မရရှိပါ\\n• OpenRouter တွင် Credits $1+ ထည့်သွင်းပါ\\n• Free tier Model များဖြစ်သော Gemma, Llama 3.1 8B, Mistral စသည်တို့ကို စမ်းသုံးကြည့်ပါ`);\n }\n\n // ===== Rate Limit Errors =====\n if (\n errorMessage.includes('rate_limit') || \n errorMessage.includes('Rate limit') ||\n errorMessage.includes('rate limit exceeded') ||\n errorCode.includes('rate_limit') ||\n errorMessage.includes('too many requests')\n ) {\n throw new Error(`⏳ Rate Limit ကျော်လွန်သွားပါပြီ။\\n\\nသင်အသုံးပြုမှုပမာဏသည် ကန့်သတ်ချက်ထက် မြင့်တက်သွားပါပြီ။\\n\\n🔧 ဖြေရှင်းနည်း: ခဏစောင့်ဆိုင်းပြီးနောက် ပြန်လည်ကြိုးစားပါ။`);\n }\n\n // ===== Insufficient Quota / Credits =====\n if (\n errorMessage.includes('insufficient_quota') || \n errorMessage.includes('quota') ||\n errorMessage.includes('Insufficient credits') ||\n errorMessage.includes('not enough credits') ||\n errorCode.includes('quota')\n ) {\n throw new Error(`💰 API သော့ Quota ကုန်ဆုံးသွားပါပြီ။\\n\\nသင်၏ API အကောင့်တွင် လက်ကျန်ငွေမရှိတော့ပါ။\\n\\n🔧 ဖြေရှင်းနည်း: သင်၏ API အကောင့်တွင် ငွေကြေးထည့်သွင်းပါ။`);\n }\n\n // ===== 401 Unauthorized =====\n if (errorStatus === 401) {\n throw new Error(`🔐 API သော့ တရားဝင်မဟုတ်ပါ။\\n\\nဤ API သော့သည် တရားဝင်မှုမရှိတော့ပါ (401 Unauthorized)။\\n\\n🔧 ဖြေရှင်းနည်း: API သော့အသစ်ထုတ်ယူပါ။`);\n }\n\n // ===== 403 Forbidden =====\n if (errorStatus === 403) {\n throw new Error(`🚫 ဝင်ခွင့်ငြင်းပယ်ခြင်း။\\n\\nဤ API သော့မှာ ဤဆောင်ရွက်မှုအတွက် ခွင့်မပြုပါ (403 Forbidden)။\\n\\n🔧 ဖြေရှင်းနည်း: API သော့၏ ခွင့်ပြုချက်များကို စစ်ဆေးပါ။`);\n }\n\n // ===== 429 Too Many Requests =====\n if (errorStatus === 429) {\n throw new Error(`⏰ တောင်းဆိုမှုအရမ်းများနေပါသည်။\\n\\nသင်၏ တောင်းဆိုမှုများသည် အရမ်းများနေပါပြီ (429 Too Many Requests)။\\n\\n🔧 ဖြေရှင်းနည်း: ခဏစောင့်ဆိုင်းပြီးနောက် ပြန်လည်ကြိုးစားပါ။`);\n }\n\n // ===== 500 Internal Server Error =====\n if (errorStatus >= 500) {\n throw new Error(`🛠️ Server အမှားဖြစ်ပါသည်။\\n\\nAPI Provider Server မှာ အမှားဖြစ်နေပါ (${errorStatus} Internal Server Error)။\\n\\n🔧 ဖြေရှင်းနည်း: ခဏစောင့်ဆိုင်းပြီးနောက် ပြန်လည်ကြိုးစားပါ။`);\n }\n\n // ===== Default Error =====\n throw new Error(`⚠️ API Error (${errorStatus}): ${errorMessage || 'အမည်မသိအမှားဖြစ်ပါသည်။'}`);\n }\n\n const data = await response.json();\n \n // Try to extract reasoning/thinking content\n let thinking: string | undefined;\n let content = '';\n\n // DeepSeek reasoning format\n if (data.choices?.[0]?.message?.reasoning) {\n thinking = data.choices[0].message.reasoning;\n }\n // OpenAI o1 style reasoning\n else if (data.choices?.[0]?.message?.reasoning !== undefined) {\n thinking = data.choices[0].message.reasoning;\n }\n // Anthropic Claude extended thinking\n else if (data.choices?.[0]?.message?.thinking) {\n thinking = data.choices[0].message.thinking;\n }\n \n // Extract content\n if (data.choices?.[0]?.message?.content) {\n content = data.choices[0].message.content;\n } else if (data.choices?.[0]?.text) {\n content = data.choices[0].text;\n } else if (data.choices?.[0]?.delta?.content) {\n content = data.choices[0].delta.content;\n }\n\n return { content: content || 'No response', thinking };\n }\n\n // Default behavior for other servers - use direct fetch logic\n const endpoint = API_ENDPOINTS[serverId];\n if (!endpoint) throw new Error(`Unsupported server: ${serverId}`);\n\n // Ollama special case\n if (serverId === 'ollama') {\n const response = await fetch(endpoint.url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ model, messages, stream: false }),\n });\n if (!response.ok) throw new Error(`Ollama error: ${response.status}`);\n const data = await response.json();\n return { content: data.message?.content || 'No response' };\n }\n\n // Gemini special case\n if (serverId === 'gemini') {\n const geminiEndpoint = `https://generativelanguage.googleapis.com/v1beta/models/${model}:generateContent?key=${apiKey}`;\n const response = await fetch(geminiEndpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n contents: messages.map(m => ({ role: m.role === 'user' ? 'user' : 'model', parts: [{ text: m.content }] }))\n }),\n });\n if (!response.ok) throw new Error(`Gemini error: ${response.status}`);\n const data = await response.json();\n return { content: data.candidates?.[0]?.content?.parts?.[0]?.text || 'No response' };\n }\n\n // Claude special case\n if (serverId === 'claude') {\n const response = await fetch(endpoint.url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n 'anthropic-version': '2023-06-01',\n },\n body: JSON.stringify({ model, max_tokens: 4096, messages: messages.map(m => ({ role: m.role, content: m.content })) }),\n });\n if (!response.ok) throw new Error(`Claude error: ${response.status}`);\n const data = await response.json();\n return { content: data.content?.[0]?.text || 'No response' };\n }\n\n // Cohere special case\n if (serverId === 'cohere') {\n const response = await fetch(endpoint.url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${apiKey}` },\n body: JSON.stringify({ model, messages: messages.map(m => ({ role: m.role === 'user' ? 'User' : 'Chatbot', message: m.content })) }),\n });\n if (!response.ok) throw new Error(`Cohere error: ${response.status}`);\n const data = await response.json();\n return { content: data.text || 'No response' };\n }\n\n // Standard OpenAI-compatible API\n const headers: Record = { 'Content-Type': 'application/json' };\n headers['Authorization'] = `Bearer ${apiKey}`;\n let body: Record = { model, messages };\n\n // ElevenLabs special case\n if (serverId === 'elevenlabs') {\n body = { text: messages[messages.length - 1]?.content, model_id: model };\n }\n\n const response = await fetch(endpoint.url, { method: 'POST', headers, body: JSON.stringify(body) });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n throw new Error(errorData.error?.message || `API Error: ${response.status}`);\n }\n\n const data = await response.json();\n\n // Extract response\n let content = '';\n if (data.choices?.[0]?.message?.content) {\n content = data.choices[0].message.content;\n } else if (data.choices?.[0]?.text) {\n content = data.choices[0].text;\n } else if (data.choices?.[0]?.delta?.content) {\n content = data.choices[0].delta.content;\n }\n\n return { content: content || 'No response' };\n },\n\n getEndpoint: (serverId: string): string | undefined => API_ENDPOINTS[serverId]?.url,\n};\n"}, "981470ad224a827aceb5ee00519632ce74755aee": {"t": 1785759150.8052459, "n": 21403, "h": "1f86104b450d2f6f", "c": "import type { ApiTestResult } from '../types/api.types';\n\n// Real API Endpoints\nconst API_ENDPOINTS: Record = {\n 'openai': { url: 'https://api.openai.com/v1/chat/completions', method: 'POST' },\n 'gemini': { url: 'https://generativelanguage.googleapis.com/v1beta/models', method: 'POST' },\n 'claude': { url: 'https://api.anthropic.com/v1/messages', method: 'POST' },\n 'deepseek': { url: 'https://api.deepseek.com/chat/completions', method: 'POST' },\n 'groq': { url: 'https://api.groq.com/openai/v1/chat/completions', method: 'POST' },\n 'together': { url: 'https://api.together.xyz/v1/chat/completions', method: 'POST' },\n 'openrouter': { url: 'https://openrouter.ai/api/v1/chat/completions', method: 'POST' },\n 'perplexity': { url: 'https://api.perplexity.ai/chat/completions', method: 'POST' },\n 'mistral': { url: 'https://api.mistral.ai/v1/chat/completions', method: 'POST' },\n 'cohere': { url: 'https://api.cohere.ai/v1/chat', method: 'POST' },\n 'cerebras': { url: 'https://api.cerebras.ai/v1/chat/completions', method: 'POST' },\n 'grok': { url: 'https://api.x.ai/v1/chat/completions', method: 'POST' },\n 'anyscale': { url: 'https://api.endpoints.anyscale.com/v1/chat/completions', method: 'POST' },\n 'ollama': { url: 'http://localhost:11434/api/chat', method: 'POST' },\n 'minimax': { url: 'https://api.minimax.chat/v1/text/chatcompletion_v2', method: 'POST' },\n 'elevenlabs': { url: 'https://api.elevenlabs.io/v1/text-to-speech', method: 'POST' },\n 'nvidia': { url: 'https://integrate.api.nvidia.com/v1/chat/completions', method: 'POST' },\n};\n\nexport const apiService = {\n testApiKey: async (serverId: string, apiKey: string): Promise => {\n const startTime = Date.now();\n try {\n await new Promise(resolve => setTimeout(resolve, 1500));\n const latency = Date.now() - startTime;\n const isValid = apiKey.length >= 10 && !apiKey.includes(' ');\n return {\n success: isValid,\n message: isValid ? `API key validated for ${serverId}! Ready to use.` : 'Invalid API key format.',\n server: serverId,\n timestamp: new Date(),\n latency,\n };\n } catch (error) {\n return { success: false, message: 'Connection failed.', server: serverId, timestamp: new Date(), latency: Date.now() - startTime };\n }\n },\n\n sendMessage: async (serverId: string, apiKey: string, model: string, messages: { role: string; content: string }[]): Promise => {\n const endpoint = API_ENDPOINTS[serverId];\n if (!endpoint) throw new Error(`Unsupported server: ${serverId}`);\n\n // Ollama special case\n if (serverId === 'ollama') {\n const response = await fetch(endpoint.url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ model, messages, stream: false }),\n });\n if (!response.ok) throw new Error(`Ollama error: ${response.status}`);\n const data = await response.json();\n return data.message?.content || 'No response';\n }\n\n // Gemini special case\n if (serverId === 'gemini') {\n const geminiEndpoint = `https://generativelanguage.googleapis.com/v1beta/models/${model}:generateContent?key=${apiKey}`;\n const response = await fetch(geminiEndpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n contents: messages.map(m => ({ role: m.role === 'user' ? 'user' : 'model', parts: [{ text: m.content }] }))\n }),\n });\n if (!response.ok) throw new Error(`Gemini error: ${response.status}`);\n const data = await response.json();\n return data.candidates?.[0]?.content?.parts?.[0]?.text || 'No response';\n }\n\n // Claude special case\n if (serverId === 'claude') {\n const response = await fetch(endpoint.url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n 'anthropic-version': '2023-06-01',\n },\n body: JSON.stringify({ model, max_tokens: 4096, messages: messages.map(m => ({ role: m.role, content: m.content })) }),\n });\n if (!response.ok) throw new Error(`Claude error: ${response.status}`);\n const data = await response.json();\n return data.content?.[0]?.text || 'No response';\n }\n\n // Cohere special case\n if (serverId === 'cohere') {\n const response = await fetch(endpoint.url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${apiKey}` },\n body: JSON.stringify({ model, messages: messages.map(m => ({ role: m.role === 'user' ? 'User' : 'Chatbot', message: m.content })) }),\n });\n if (!response.ok) throw new Error(`Cohere error: ${response.status}`);\n const data = await response.json();\n return data.text || 'No response';\n }\n\n // Standard OpenAI-compatible API\n const headers: Record = { 'Content-Type': 'application/json' };\n let body: Record = { model, messages };\n\n // Add auth headers\n if (serverId === 'openrouter') {\n headers['Authorization'] = `Bearer ${apiKey}`;\n headers['HTTP-Referer'] = window.location.origin;\n headers['X-Title'] = 'API Test Hub';\n } else {\n headers['Authorization'] = `Bearer ${apiKey}`;\n }\n\n // ElevenLabs special case\n if (serverId === 'elevenlabs') {\n body = { text: messages[messages.length - 1]?.content, model_id: model };\n }\n\n const response = await fetch(endpoint.url, { method: 'POST', headers, body: JSON.stringify(body) });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n const errorMessage = errorData.error?.message || errorData.message || errorData.error?.type || '';\n const errorCode = errorData.error?.code || '';\n const errorStatus = response.status;\n \n // ===== API Key Expired / Invalid Errors =====\n if (\n errorMessage.includes('api_key_expired') || \n errorMessage.includes('API key has expired') ||\n errorMessage.includes('expired') ||\n errorCode.includes('expired') ||\n errorMessage.includes('key_expired')\n ) {\n throw new Error(`❌ API သော့ သက်တမ်းကုန်သွားပါပြီ။\\n\\nသင်၏ API သော့သည် သက်တမ်းလွန်နေပါပြီ။\\n\\n🔧 ဖြေရှင်းနည်း: API သော့အသစ်ထုတ်ယူပြီး ပြန်လည်ကြိုးစားပါ။`);\n }\n\n // ===== Invalid API Key Errors =====\n if (\n errorMessage.includes('invalid_api_key') || \n errorMessage.includes('Incorrect API key') ||\n errorMessage.includes('invalid api key') ||\n errorCode.includes('invalid_api_key') ||\n errorMessage.includes('api_key_invalid')\n ) {\n throw new Error(`❌ API Key Error!\\n\\nYour API key is invalid or incorrect.\\n\\n🔧 Solution: Please check and re-enter your API key.`);\n }\n\n // ===== No Endpoints / Model Not Found =====\n if (\n errorMessage.includes('No endpoints found') || \n errorMessage.includes('model not found') ||\n errorMessage.includes('model_not_found') ||\n errorCode.includes('model_not_found')\n ) {\n throw new Error(`❌ Model မရရှိနိုင်ပါ။\\n\\nဤ Model သည် သင်၏ အကောင့်တွင် မရရှိနိုင်ပါ။\\n\\n🔧 ဖြေရှင်းနည်း: အခြား Model တစ်ခုကို ရွေးချယ်ပါ သို့မဟုတ် သင်၏ API အကောင့်တွင် ငွေကြေးထည့်သွင်းပါ။`);\n }\n\n // ===== Rate Limit Errors =====\n if (\n errorMessage.includes('rate_limit') || \n errorMessage.includes('Rate limit') ||\n errorMessage.includes('rate limit exceeded') ||\n errorCode.includes('rate_limit') ||\n errorMessage.includes('too many requests')\n ) {\n throw new Error(`⏳ Rate Limit ကျော်လွန်သွားပါပြီ။\\n\\nသင်အသုံးပြုမှုပမာဏသည် ကန့်သတ်ချက်ထက် မြင့်တက်သွားပါပြီ။\\n\\n🔧 ဖြေရှင်းနည်း: ခဏစောင့်ဆိုင်းပြီးနောက် ပြန်လည်ကြိုးစားပါ။`);\n }\n\n // ===== Insufficient Quota / Credits =====\n if (\n errorMessage.includes('insufficient_quota') || \n errorMessage.includes('quota') ||\n errorMessage.includes('Insufficient credits') ||\n errorMessage.includes('not enough credits') ||\n errorCode.includes('quota')\n ) {\n throw new Error(`💰 API သော့ Quota ကုန်ဆုံးသွားပါပြီ။\\n\\nသင်၏ API အကောင့်တွင် လက်ကျန်ငွေမရှိတော့ပါ။\\n\\n🔧 ဖြေရှင်းနည်း: သင်၏ API အကောင့်တွင် ငွေကြေးထည့်သွင်းပါ။`);\n }\n\n // ===== 401 Unauthorized =====\n if (errorStatus === 401) {\n throw new Error(`🔐 API သော့ တရားဝင်မဟုတ်ပါ။\\n\\nဤ API သော့သည် တရားဝင်မှုမရှိတော့ပါ (401 Unauthorized)။\\n\\n🔧 ဖြေရှင်းနည်း: API သော့အသစ်ထုတ်ယူပါ။`);\n }\n\n // ===== 403 Forbidden =====\n if (errorStatus === 403) {\n throw new Error(`🚫 ဝင်ခွင့်ငြင်းပယ်ခြင်း။\\n\\nဤ API သော့မှာ ဤဆောင်ရွက်မှုအတွက် ခွင့်မပြုပါ (403 Forbidden)။\\n\\n🔧 ဖြေရှင်းနည်း: API သော့၏ ခွင့်ပြုချက်များကို စစ်ဆေးပါ။`);\n }\n\n // ===== 429 Too Many Requests =====\n if (errorStatus === 429) {\n throw new Error(`⏰ တောင်းဆိုမှုအရမ်းများနေပါသည်။\\n\\nသင်၏ တောင်းဆိုမှုများသည် အရမ်းများနေပါပြီ (429 Too Many Requests)။\\n\\n🔧 ဖြေရှင်းနည်း: ခဏစောင့်ဆိုင်းပြီးနောက် ပြန်လည်ကြိုးစားပါ။`);\n }\n\n // ===== 500 Internal Server Error =====\n if (errorStatus >= 500) {\n throw new Error(`🛠️ Server အမှားဖြစ်ပါသည်။\\n\\nAPI Provider Server မှာ အမှားဖြစ်နေပါ (${errorStatus} Internal Server Error)။\\n\\n🔧 ဖြေရှင်းနည်း: ခဏစောင့်ဆိုင်းပြီးနောက် ပြန်လည်ကြိုးစားပါ။`);\n }\n\n // ===== Default Error =====\n throw new Error(`⚠️ API Error (${errorStatus}): ${errorMessage || 'အမည်မသိအမှားဖြစ်ပါသည်။'}`);\n }\n\n const data = await response.json();\n\n // Extract response - handle various API response formats\n let content = '';\n\n // Standard OpenAI-compatible format\n if (data.choices?.[0]?.message?.content) {\n content = data.choices[0].message.content;\n }\n // Alternative format with text field\n else if (data.choices?.[0]?.text) {\n content = data.choices[0].text;\n }\n // StreamLake/DeepSeek format with choices array\n else if (data.choices?.[0]?.delta?.content) {\n content = data.choices[0].delta.content;\n }\n // Generic choices array iteration\n else if (data.choices && data.choices.length > 0) {\n const firstChoice = data.choices[0];\n content = firstChoice.message?.content || firstChoice.delta?.content || firstChoice.text || '';\n }\n // Response as direct string\n else if (typeof data === 'string') {\n content = data;\n }\n // Response with response or text field at root\n else if (data.response) {\n content = typeof data.response === 'string' ? data.response : data.response.choices?.[0]?.message?.content || JSON.stringify(data.response);\n }\n else if (data.text) {\n content = data.text;\n }\n\n // Clean up content - remove any JSON metadata that might be included\n if (content && typeof content === 'string') {\n // Check if content starts with JSON-like pattern and try to extract actual text\n const jsonMatch = content.match(/^\\s*\\{.*\\}\\s*$/);\n if (jsonMatch && !content.includes('\\n') && content.length < 500) {\n try {\n const parsed = JSON.parse(content);\n // If it's JSON, try to extract meaningful content\n content = parsed.content || parsed.message || parsed.text || parsed.choices?.[0]?.message?.content || parsed.choices?.[0]?.text || content;\n } catch {\n // Not valid JSON, keep original\n }\n }\n }\n\n return content || 'No response';\n },\n\n sendMessageWithThinking: async (serverId: string, apiKey: string, model: string, messages: { role: string; content: string }[]): Promise<{ content: string; thinking?: string }> => {\n // Handle DeepSeek reasoning content\n if (serverId === 'deepseek' || serverId === 'openrouter') {\n const endpoint = API_ENDPOINTS[serverId];\n if (!endpoint) throw new Error(`Unsupported server: ${serverId}`);\n\n const headers: Record = { 'Content-Type': 'application/json' };\n let body: Record = { model, messages };\n\n if (serverId === 'openrouter') {\n headers['Authorization'] = `Bearer ${apiKey}`;\n headers['HTTP-Referer'] = window.location.origin;\n headers['X-Title'] = 'API Test Hub';\n } else {\n headers['Authorization'] = `Bearer ${apiKey}`;\n }\n\n const response = await fetch(endpoint.url, { method: 'POST', headers, body: JSON.stringify(body) });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n const errorMessage = errorData.error?.message || errorData.message || errorData.error?.type || '';\n const errorCode = errorData.error?.code || '';\n const errorStatus = response.status;\n \n // ===== API Key Expired / Invalid Errors =====\n if (\n errorMessage.includes('api_key_expired') || \n errorMessage.includes('API key has expired') ||\n errorMessage.includes('expired') ||\n errorCode.includes('expired') ||\n errorMessage.includes('key_expired')\n ) {\n throw new Error(`❌ API သော့ သက်တမ်းကုန်သွားပါပြီ။\\n\\nသင်၏ API သော့သည် သက်တမ်းလွန်နေပါပြီ။\\n\\n🔧 ဖြေရှင်းနည်း: API သော့အသစ်ထုတ်ယူပြီး ပြန်လည်ကြိုးစားပါ။`);\n }\n\n // ===== Invalid API Key Errors =====\n if (\n errorMessage.includes('invalid_api_key') || \n errorMessage.includes('Incorrect API key') ||\n errorMessage.includes('invalid api key') ||\n errorCode.includes('invalid_api_key') ||\n errorMessage.includes('api_key_invalid')\n ) {\n throw new Error(`❌ API Key Error!\\n\\nYour API key is invalid or incorrect.\\n\\n🔧 Solution: Please check and re-enter your API key.`);\n }\n\n // ===== No Endpoints / Model Not Found =====\n if (\n errorMessage.includes('No endpoints found') || \n errorMessage.includes('model not found') ||\n errorMessage.includes('model_not_found') ||\n errorCode.includes('model_not_found') ||\n errorMessage.includes('no valid routes')\n ) {\n throw new Error(`❌ Model မရရှိနိုင်ပါ။\\n\\n\"${model}\" သည် သင်၏ API အကောင့်တွင် ရရှိနိုင်မှုမရှိပါ။\\n\\n🔧 ဖြေရှင်းနည်း: \\n• အခြား Model တစ်ခုကို ရွေးချယ်ပါ\\n• OpenRouter တွင် Credits ထည့်သွင်းပါ\\n• Free tier Model များဖြစ်သော Gemma, Llama စသည်တို့ကို စမ်းသုံးကြည့်ပါ`);\n }\n\n // ===== Rate Limit Errors =====\n if (\n errorMessage.includes('rate_limit') || \n errorMessage.includes('Rate limit') ||\n errorMessage.includes('rate limit exceeded') ||\n errorCode.includes('rate_limit') ||\n errorMessage.includes('too many requests')\n ) {\n throw new Error(`⏳ Rate Limit ကျော်လွန်သွားပါပြီ။\\n\\nသင်အသုံးပြုမှုပမာဏသည် ကန့်သတ်ချက်ထက် မြင့်တက်သွားပါပြီ။\\n\\n🔧 ဖြေရှင်းနည်း: ခဏစောင့်ဆိုင်းပြီးနောက် ပြန်လည်ကြိုးစားပါ။`);\n }\n\n // ===== Insufficient Quota / Credits =====\n if (\n errorMessage.includes('insufficient_quota') || \n errorMessage.includes('quota') ||\n errorMessage.includes('Insufficient credits') ||\n errorMessage.includes('not enough credits') ||\n errorCode.includes('quota')\n ) {\n throw new Error(`💰 API သော့ Quota ကုန်ဆုံးသွားပါပြီ။\\n\\nသင်၏ API အကောင့်တွင် လက်ကျန်ငွေမရှိတော့ပါ။\\n\\n🔧 ဖြေရှင်းနည်း: သင်၏ API အကောင့်တွင် ငွေကြေးထည့်သွင်းပါ။`);\n }\n\n // ===== 401 Unauthorized =====\n if (errorStatus === 401) {\n throw new Error(`🔐 API သော့ တရားဝင်မဟုတ်ပါ။\\n\\nဤ API သော့သည် တရားဝင်မှုမရှိတော့ပါ (401 Unauthorized)။\\n\\n🔧 ဖြေရှင်းနည်း: API သော့အသစ်ထုတ်ယူပါ။`);\n }\n\n // ===== 403 Forbidden =====\n if (errorStatus === 403) {\n throw new Error(`🚫 ဝင်ခွင့်ငြင်းပယ်ခြင်း။\\n\\nဤ API သော့မှာ ဤဆောင်ရွက်မှုအတွက် ခွင့်မပြုပါ (403 Forbidden)။\\n\\n🔧 ဖြေရှင်းနည်း: API သော့၏ ခွင့်ပြုချက်များကို စစ်ဆေးပါ။`);\n }\n\n // ===== 429 Too Many Requests =====\n if (errorStatus === 429) {\n throw new Error(`⏰ တောင်းဆိုမှုအရမ်းများနေပါသည်။\\n\\nသင်၏ တောင်းဆိုမှုများသည် အရမ်းများနေပါပြီ (429 Too Many Requests)။\\n\\n🔧 ဖြေရှင်းနည်း: ခဏစောင့်ဆိုင်းပြီးနောက် ပြန်လည်ကြိုးစားပါ။`);\n }\n\n // ===== 500 Internal Server Error =====\n if (errorStatus >= 500) {\n throw new Error(`🛠️ Server အမှားဖြစ်ပါသည်။\\n\\nAPI Provider Server မှာ အမှားဖြစ်နေပါ (${errorStatus} Internal Server Error)။\\n\\n🔧 ဖြေရှင်းနည်း: ခဏစောင့်ဆိုင်းပြီးနောက် ပြန်လည်ကြိုးစားပါ။`);\n }\n\n // ===== Default Error =====\n throw new Error(`⚠️ API Error (${errorStatus}): ${errorMessage || 'အမည်မသိအမှားဖြစ်ပါသည်။'}`);\n }\n\n const data = await response.json();\n \n // Try to extract reasoning/thinking content\n let thinking: string | undefined;\n let content = '';\n\n // DeepSeek reasoning format\n if (data.choices?.[0]?.message?.reasoning) {\n thinking = data.choices[0].message.reasoning;\n }\n // OpenAI o1 style reasoning\n else if (data.choices?.[0]?.message?.reasoning !== undefined) {\n thinking = data.choices[0].message.reasoning;\n }\n // Anthropic Claude extended thinking\n else if (data.choices?.[0]?.message?.thinking) {\n thinking = data.choices[0].message.thinking;\n }\n \n // Extract content\n if (data.choices?.[0]?.message?.content) {\n content = data.choices[0].message.content;\n } else if (data.choices?.[0]?.text) {\n content = data.choices[0].text;\n } else if (data.choices?.[0]?.delta?.content) {\n content = data.choices[0].delta.content;\n }\n\n return { content: content || 'No response', thinking };\n }\n\n // Default behavior for other servers - use direct fetch logic\n const endpoint = API_ENDPOINTS[serverId];\n if (!endpoint) throw new Error(`Unsupported server: ${serverId}`);\n\n // Ollama special case\n if (serverId === 'ollama') {\n const response = await fetch(endpoint.url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ model, messages, stream: false }),\n });\n if (!response.ok) throw new Error(`Ollama error: ${response.status}`);\n const data = await response.json();\n return { content: data.message?.content || 'No response' };\n }\n\n // Gemini special case\n if (serverId === 'gemini') {\n const geminiEndpoint = `https://generativelanguage.googleapis.com/v1beta/models/${model}:generateContent?key=${apiKey}`;\n const response = await fetch(geminiEndpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n contents: messages.map(m => ({ role: m.role === 'user' ? 'user' : 'model', parts: [{ text: m.content }] }))\n }),\n });\n if (!response.ok) throw new Error(`Gemini error: ${response.status}`);\n const data = await response.json();\n return { content: data.candidates?.[0]?.content?.parts?.[0]?.text || 'No response' };\n }\n\n // Claude special case\n if (serverId === 'claude') {\n const response = await fetch(endpoint.url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n 'anthropic-version': '2023-06-01',\n },\n body: JSON.stringify({ model, max_tokens: 4096, messages: messages.map(m => ({ role: m.role, content: m.content })) }),\n });\n if (!response.ok) throw new Error(`Claude error: ${response.status}`);\n const data = await response.json();\n return { content: data.content?.[0]?.text || 'No response' };\n }\n\n // Cohere special case\n if (serverId === 'cohere') {\n const response = await fetch(endpoint.url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${apiKey}` },\n body: JSON.stringify({ model, messages: messages.map(m => ({ role: m.role === 'user' ? 'User' : 'Chatbot', message: m.content })) }),\n });\n if (!response.ok) throw new Error(`Cohere error: ${response.status}`);\n const data = await response.json();\n return { content: data.text || 'No response' };\n }\n\n // Standard OpenAI-compatible API\n const headers: Record = { 'Content-Type': 'application/json' };\n headers['Authorization'] = `Bearer ${apiKey}`;\n let body: Record = { model, messages };\n\n // ElevenLabs special case\n if (serverId === 'elevenlabs') {\n body = { text: messages[messages.length - 1]?.content, model_id: model };\n }\n\n const response = await fetch(endpoint.url, { method: 'POST', headers, body: JSON.stringify(body) });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n throw new Error(errorData.error?.message || `API Error: ${response.status}`);\n }\n\n const data = await response.json();\n\n // Extract response\n let content = '';\n if (data.choices?.[0]?.message?.content) {\n content = data.choices[0].message.content;\n } else if (data.choices?.[0]?.text) {\n content = data.choices[0].text;\n } else if (data.choices?.[0]?.delta?.content) {\n content = data.choices[0].delta.content;\n }\n\n return { content: content || 'No response' };\n },\n\n getEndpoint: (serverId: string): string | undefined => API_ENDPOINTS[serverId]?.url,\n};\n"}, "6dc76b033951b018af197da15b1e93c18a60e9a2": {"t": 1785759152.415663, "n": 17386, "h": "b3a687da54649e79", "c": "import type { ApiTestResult } from '../types/api.types';\n\n// Real API Endpoints\nconst API_ENDPOINTS: Record = {\n 'openai': { url: 'https://api.openai.com/v1/chat/completions', method: 'POST' },\n 'gemini': { url: 'https://generativelanguage.googleapis.com/v1beta/models', method: 'POST' },\n 'claude': { url: 'https://api.anthropic.com/v1/messages', method: 'POST' },\n 'deepseek': { url: 'https://api.deepseek.com/chat/completions', method: 'POST' },\n 'groq': { url: 'https://api.groq.com/openai/v1/chat/completions', method: 'POST' },\n 'together': { url: 'https://api.together.xyz/v1/chat/completions', method: 'POST' },\n 'openrouter': { url: 'https://openrouter.ai/api/v1/chat/completions', method: 'POST' },\n 'perplexity': { url: 'https://api.perplexity.ai/chat/completions', method: 'POST' },\n 'mistral': { url: 'https://api.mistral.ai/v1/chat/completions', method: 'POST' },\n 'cohere': { url: 'https://api.cohere.ai/v1/chat', method: 'POST' },\n 'cerebras': { url: 'https://api.cerebras.ai/v1/chat/completions', method: 'POST' },\n 'grok': { url: 'https://api.x.ai/v1/chat/completions', method: 'POST' },\n 'anyscale': { url: 'https://api.endpoints.anyscale.com/v1/chat/completions', method: 'POST' },\n 'ollama': { url: 'http://localhost:11434/api/chat', method: 'POST' },\n 'minimax': { url: 'https://api.minimax.chat/v1/text/chatcompletion_v2', method: 'POST' },\n 'elevenlabs': { url: 'https://api.elevenlabs.io/v1/text-to-speech', method: 'POST' },\n 'nvidia': { url: 'https://integrate.api.nvidia.com/v1/chat/completions', method: 'POST' },\n};\n\nexport const apiService = {\n testApiKey: async (serverId: string, apiKey: string): Promise => {\n const startTime = Date.now();\n try {\n await new Promise(resolve => setTimeout(resolve, 1500));\n const latency = Date.now() - startTime;\n const isValid = apiKey.length >= 10 && !apiKey.includes(' ');\n return {\n success: isValid,\n message: isValid ? `API key validated for ${serverId}! Ready to use.` : 'Invalid API key format.',\n server: serverId,\n timestamp: new Date(),\n latency,\n };\n } catch (error) {\n return { success: false, message: 'Connection failed.', server: serverId, timestamp: new Date(), latency: Date.now() - startTime };\n }\n },\n\n sendMessage: async (serverId: string, apiKey: string, model: string, messages: { role: string; content: string }[]): Promise => {\n const endpoint = API_ENDPOINTS[serverId];\n if (!endpoint) throw new Error(`Unsupported server: ${serverId}`);\n\n // Ollama special case\n if (serverId === 'ollama') {\n const response = await fetch(endpoint.url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ model, messages, stream: false }),\n });\n if (!response.ok) throw new Error(`Ollama error: ${response.status}`);\n const data = await response.json();\n return data.message?.content || 'No response';\n }\n\n // Gemini special case\n if (serverId === 'gemini') {\n const geminiEndpoint = `https://generativelanguage.googleapis.com/v1beta/models/${model}:generateContent?key=${apiKey}`;\n const response = await fetch(geminiEndpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n contents: messages.map(m => ({ role: m.role === 'user' ? 'user' : 'model', parts: [{ text: m.content }] }))\n }),\n });\n if (!response.ok) throw new Error(`Gemini error: ${response.status}`);\n const data = await response.json();\n return data.candidates?.[0]?.content?.parts?.[0]?.text || 'No response';\n }\n\n // Claude special case\n if (serverId === 'claude') {\n const response = await fetch(endpoint.url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n 'anthropic-version': '2023-06-01',\n },\n body: JSON.stringify({ model, max_tokens: 4096, messages: messages.map(m => ({ role: m.role, content: m.content })) }),\n });\n if (!response.ok) throw new Error(`Claude error: ${response.status}`);\n const data = await response.json();\n return data.content?.[0]?.text || 'No response';\n }\n\n // Cohere special case\n if (serverId === 'cohere') {\n const response = await fetch(endpoint.url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${apiKey}` },\n body: JSON.stringify({ model, messages: messages.map(m => ({ role: m.role === 'user' ? 'User' : 'Chatbot', message: m.content })) }),\n });\n if (!response.ok) throw new Error(`Cohere error: ${response.status}`);\n const data = await response.json();\n return data.text || 'No response';\n }\n\n // Standard OpenAI-compatible API\n const headers: Record = { 'Content-Type': 'application/json' };\n let body: Record = { model, messages };\n\n // Add auth headers\n if (serverId === 'openrouter') {\n headers['Authorization'] = `Bearer ${apiKey}`;\n headers['HTTP-Referer'] = window.location.origin;\n headers['X-Title'] = 'API Test Hub';\n } else {\n headers['Authorization'] = `Bearer ${apiKey}`;\n }\n\n // ElevenLabs special case\n if (serverId === 'elevenlabs') {\n body = { text: messages[messages.length - 1]?.content, model_id: model };\n }\n\n const response = await fetch(endpoint.url, { method: 'POST', headers, body: JSON.stringify(body) });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n const errorMessage = errorData.error?.message || errorData.message || errorData.error?.type || '';\n const errorCode = errorData.error?.code || '';\n const errorStatus = response.status;\n \n // ===== API Key Expired / Invalid Errors =====\n if (\n errorMessage.includes('api_key_expired') || \n errorMessage.includes('API key has expired') ||\n errorMessage.includes('expired') ||\n errorCode.includes('expired') ||\n errorMessage.includes('key_expired')\n ) {\n throw new Error(`❌ API သော့ သက်တမ်းကုန်သွားပါပြီ။\\n\\nသင်၏ API သော့သည် သက်တမ်းလွန်နေပါပြီ။\\n\\n🔧 ဖြေရှင်းနည်း: API သော့အသစ်ထုတ်ယူပြီး ပြန်လည်ကြိုးစားပါ။`);\n }\n\n // ===== Invalid API Key Errors =====\n if (\n errorMessage.includes('invalid_api_key') || \n errorMessage.includes('Incorrect API key') ||\n errorMessage.includes('invalid api key') ||\n errorCode.includes('invalid_api_key') ||\n errorMessage.includes('api_key_invalid')\n ) {\n throw new Error(`❌ API Key Error!\\n\\nYour API key is invalid or incorrect.\\n\\n🔧 Solution: Please check and re-enter your API key.`);\n }\n\n // ===== No Endpoints / Model Not Found =====\n if (\n errorMessage.includes('No endpoints found') || \n errorMessage.includes('model not found') ||\n errorMessage.includes('model_not_found') ||\n errorCode.includes('model_not_found')\n ) {\n throw new Error(`❌ Model မရရှိနိုင်ပါ။\\n\\nဤ Model သည် သင်၏ အကောင့်တွင် မရရှိနိုင်ပါ။\\n\\n🔧 ဖြေရှင်းနည်း: အခြား Model တစ်ခုကို ရွေးချယ်ပါ သို့မဟုတ် သင်၏ API အကောင့်တွင် ငွေကြေးထည့်သွင်းပါ။`);\n }\n\n // ===== Rate Limit Errors =====\n if (\n errorMessage.includes('rate_limit') || \n errorMessage.includes('Rate limit') ||\n errorMessage.includes('rate limit exceeded') ||\n errorCode.includes('rate_limit') ||\n errorMessage.includes('too many requests')\n ) {\n throw new Error(`⏳ Rate Limit ကျော်လွန်သွားပါပြီ။\\n\\nသင်အသုံးပြုမှုပမာဏသည် ကန့်သတ်ချက်ထက် မြင့်တက်သွားပါပြီ။\\n\\n🔧 ဖြေရှင်းနည်း: ခဏစောင့်ဆိုင်းပြီးနောက် ပြန်လည်ကြိုးစားပါ။`);\n }\n\n // ===== Insufficient Quota / Credits =====\n if (\n errorMessage.includes('insufficient_quota') || \n errorMessage.includes('quota') ||\n errorMessage.includes('Insufficient credits') ||\n errorMessage.includes('not enough credits') ||\n errorCode.includes('quota')\n ) {\n throw new Error(`💰 API သော့ Quota ကုန်ဆုံးသွားပါပြီ။\\n\\nသင်၏ API အကောင့်တွင် လက်ကျန်ငွေမရှိတော့ပါ။\\n\\n🔧 ဖြေရှင်းနည်း: သင်၏ API အကောင့်တွင် ငွေကြေးထည့်သွင်းပါ။`);\n }\n\n // ===== 401 Unauthorized =====\n if (errorStatus === 401) {\n throw new Error(`🔐 API သော့ တရားဝင်မဟုတ်ပါ။\\n\\nဤ API သော့သည် တရားဝင်မှုမရှိတော့ပါ (401 Unauthorized)။\\n\\n🔧 ဖြေရှင်းနည်း: API သော့အသစ်ထုတ်ယူပါ။`);\n }\n\n // ===== 403 Forbidden =====\n if (errorStatus === 403) {\n throw new Error(`🚫 ဝင်ခွင့်ငြင်းပယ်ခြင်း။\\n\\nဤ API သော့မှာ ဤဆောင်ရွက်မှုအတွက် ခွင့်မပြုပါ (403 Forbidden)။\\n\\n🔧 ဖြေရှင်းနည်း: API သော့၏ ခွင့်ပြုချက်များကို စစ်ဆေးပါ။`);\n }\n\n // ===== 429 Too Many Requests =====\n if (errorStatus === 429) {\n throw new Error(`⏰ တောင်းဆိုမှုအရမ်းများနေပါသည်။\\n\\nသင်၏ တောင်းဆိုမှုများသည် အရမ်းများနေပါပြီ (429 Too Many Requests)။\\n\\n🔧 ဖြေရှင်းနည်း: ခဏစောင့်ဆိုင်းပြီးနောက် ပြန်လည်ကြိုးစားပါ။`);\n }\n\n // ===== 500 Internal Server Error =====\n if (errorStatus >= 500) {\n throw new Error(`🛠️ Server အမှားဖြစ်ပါသည်။\\n\\nAPI Provider Server မှာ အမှားဖြစ်နေပါ (${errorStatus} Internal Server Error)။\\n\\n🔧 ဖြေရှင်းနည်း: ခဏစောင့်ဆိုင်းပြီးနောက် ပြန်လည်ကြိုးစားပါ။`);\n }\n\n // ===== Default Error =====\n throw new Error(`⚠️ API Error (${errorStatus}): ${errorMessage || 'အမည်မသိအမှားဖြစ်ပါသည်။'}`);\n }\n\n const data = await response.json();\n\n // Extract response - handle various API response formats\n let content = '';\n\n // Standard OpenAI-compatible format\n if (data.choices?.[0]?.message?.content) {\n content = data.choices[0].message.content;\n }\n // Alternative format with text field\n else if (data.choices?.[0]?.text) {\n content = data.choices[0].text;\n }\n // StreamLake/DeepSeek format with choices array\n else if (data.choices?.[0]?.delta?.content) {\n content = data.choices[0].delta.content;\n }\n // Generic choices array iteration\n else if (data.choices && data.choices.length > 0) {\n const firstChoice = data.choices[0];\n content = firstChoice.message?.content || firstChoice.delta?.content || firstChoice.text || '';\n }\n // Response as direct string\n else if (typeof data === 'string') {\n content = data;\n }\n // Response with response or text field at root\n else if (data.response) {\n content = typeof data.response === 'string' ? data.response : data.response.choices?.[0]?.message?.content || JSON.stringify(data.response);\n }\n else if (data.text) {\n content = data.text;\n }\n\n // Clean up content - remove any JSON metadata that might be included\n if (content && typeof content === 'string') {\n // Check if content starts with JSON-like pattern and try to extract actual text\n const jsonMatch = content.match(/^\\s*\\{.*\\}\\s*$/);\n if (jsonMatch && !content.includes('\\n') && content.length < 500) {\n try {\n const parsed = JSON.parse(content);\n // If it's JSON, try to extract meaningful content\n content = parsed.content || parsed.message || parsed.text || parsed.choices?.[0]?.message?.content || parsed.choices?.[0]?.text || content;\n } catch {\n // Not valid JSON, keep original\n }\n }\n }\n\n return content || 'No response';\n },\n\n sendMessageWithThinking: async (serverId: string, apiKey: string, model: string, messages: { role: string; content: string }[]): Promise<{ content: string; thinking?: string }> => {\n // Handle DeepSeek reasoning content\n if (serverId === 'deepseek' || serverId === 'openrouter') {\n const endpoint = API_ENDPOINTS[serverId];\n if (!endpoint) throw new Error(`Unsupported server: ${serverId}`);\n\n const headers: Record = { 'Content-Type': 'application/json' };\n let body: Record = { model, messages };\n\n if (serverId === 'openrouter') {\n headers['Authorization'] = `Bearer ${apiKey}`;\n headers['HTTP-Referer'] = window.location.origin;\n headers['X-Title'] = 'API Test Hub';\n } else {\n headers['Authorization'] = `Bearer ${apiKey}`;\n }\n\n const response = await fetch(endpoint.url, { method: 'POST', headers, body: JSON.stringify(body) });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n throw new Error(errorData.error?.message || `API Error: ${response.status}`);\n }\n\n const data = await response.json();\n \n // Try to extract reasoning/thinking content\n let thinking: string | undefined;\n let content = '';\n\n // DeepSeek reasoning format\n if (data.choices?.[0]?.message?.reasoning) {\n thinking = data.choices[0].message.reasoning;\n }\n // OpenAI o1 style reasoning\n else if (data.choices?.[0]?.message?.reasoning !== undefined) {\n thinking = data.choices[0].message.reasoning;\n }\n // Anthropic Claude extended thinking\n else if (data.choices?.[0]?.message?.thinking) {\n thinking = data.choices[0].message.thinking;\n }\n \n // Extract content\n if (data.choices?.[0]?.message?.content) {\n content = data.choices[0].message.content;\n } else if (data.choices?.[0]?.text) {\n content = data.choices[0].text;\n } else if (data.choices?.[0]?.delta?.content) {\n content = data.choices[0].delta.content;\n }\n\n return { content: content || 'No response', thinking };\n }\n\n // Default behavior for other servers - use direct fetch logic\n const endpoint = API_ENDPOINTS[serverId];\n if (!endpoint) throw new Error(`Unsupported server: ${serverId}`);\n\n // Ollama special case\n if (serverId === 'ollama') {\n const response = await fetch(endpoint.url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ model, messages, stream: false }),\n });\n if (!response.ok) throw new Error(`Ollama error: ${response.status}`);\n const data = await response.json();\n return { content: data.message?.content || 'No response' };\n }\n\n // Gemini special case\n if (serverId === 'gemini') {\n const geminiEndpoint = `https://generativelanguage.googleapis.com/v1beta/models/${model}:generateContent?key=${apiKey}`;\n const response = await fetch(geminiEndpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n contents: messages.map(m => ({ role: m.role === 'user' ? 'user' : 'model', parts: [{ text: m.content }] }))\n }),\n });\n if (!response.ok) throw new Error(`Gemini error: ${response.status}`);\n const data = await response.json();\n return { content: data.candidates?.[0]?.content?.parts?.[0]?.text || 'No response' };\n }\n\n // Claude special case\n if (serverId === 'claude') {\n const response = await fetch(endpoint.url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n 'anthropic-version': '2023-06-01',\n },\n body: JSON.stringify({ model, max_tokens: 4096, messages: messages.map(m => ({ role: m.role, content: m.content })) }),\n });\n if (!response.ok) throw new Error(`Claude error: ${response.status}`);\n const data = await response.json();\n return { content: data.content?.[0]?.text || 'No response' };\n }\n\n // Cohere special case\n if (serverId === 'cohere') {\n const response = await fetch(endpoint.url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${apiKey}` },\n body: JSON.stringify({ model, messages: messages.map(m => ({ role: m.role === 'user' ? 'User' : 'Chatbot', message: m.content })) }),\n });\n if (!response.ok) throw new Error(`Cohere error: ${response.status}`);\n const data = await response.json();\n return { content: data.text || 'No response' };\n }\n\n // Standard OpenAI-compatible API\n const headers: Record = { 'Content-Type': 'application/json' };\n headers['Authorization'] = `Bearer ${apiKey}`;\n let body: Record = { model, messages };\n\n // ElevenLabs special case\n if (serverId === 'elevenlabs') {\n body = { text: messages[messages.length - 1]?.content, model_id: model };\n }\n\n const response = await fetch(endpoint.url, { method: 'POST', headers, body: JSON.stringify(body) });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n throw new Error(errorData.error?.message || `API Error: ${response.status}`);\n }\n\n const data = await response.json();\n\n // Extract response\n let content = '';\n if (data.choices?.[0]?.message?.content) {\n content = data.choices[0].message.content;\n } else if (data.choices?.[0]?.text) {\n content = data.choices[0].text;\n } else if (data.choices?.[0]?.delta?.content) {\n content = data.choices[0].delta.content;\n }\n\n return { content: content || 'No response' };\n },\n\n getEndpoint: (serverId: string): string | undefined => API_ENDPOINTS[serverId]?.url,\n};\n"}, "6e70627cbccb8c50a3980dfb0482431fa494c33c": {"t": 1785759153.9692912, "n": 14654, "h": "10fdc073a41bf31d", "c": "import type { ApiTestResult } from '../types/api.types';\n\n// Real API Endpoints\nconst API_ENDPOINTS: Record = {\n 'openai': { url: 'https://api.openai.com/v1/chat/completions', method: 'POST' },\n 'gemini': { url: 'https://generativelanguage.googleapis.com/v1beta/models', method: 'POST' },\n 'claude': { url: 'https://api.anthropic.com/v1/messages', method: 'POST' },\n 'deepseek': { url: 'https://api.deepseek.com/chat/completions', method: 'POST' },\n 'groq': { url: 'https://api.groq.com/openai/v1/chat/completions', method: 'POST' },\n 'together': { url: 'https://api.together.xyz/v1/chat/completions', method: 'POST' },\n 'openrouter': { url: 'https://openrouter.ai/api/v1/chat/completions', method: 'POST' },\n 'perplexity': { url: 'https://api.perplexity.ai/chat/completions', method: 'POST' },\n 'mistral': { url: 'https://api.mistral.ai/v1/chat/completions', method: 'POST' },\n 'cohere': { url: 'https://api.cohere.ai/v1/chat', method: 'POST' },\n 'cerebras': { url: 'https://api.cerebras.ai/v1/chat/completions', method: 'POST' },\n 'grok': { url: 'https://api.x.ai/v1/chat/completions', method: 'POST' },\n 'anyscale': { url: 'https://api.endpoints.anyscale.com/v1/chat/completions', method: 'POST' },\n 'ollama': { url: 'http://localhost:11434/api/chat', method: 'POST' },\n 'minimax': { url: 'https://api.minimax.chat/v1/text/chatcompletion_v2', method: 'POST' },\n 'elevenlabs': { url: 'https://api.elevenlabs.io/v1/text-to-speech', method: 'POST' },\n 'nvidia': { url: 'https://integrate.api.nvidia.com/v1/chat/completions', method: 'POST' },\n};\n\nexport const apiService = {\n testApiKey: async (serverId: string, apiKey: string): Promise => {\n const startTime = Date.now();\n try {\n await new Promise(resolve => setTimeout(resolve, 1500));\n const latency = Date.now() - startTime;\n const isValid = apiKey.length >= 10 && !apiKey.includes(' ');\n return {\n success: isValid,\n message: isValid ? `API key validated for ${serverId}! Ready to use.` : 'Invalid API key format.',\n server: serverId,\n timestamp: new Date(),\n latency,\n };\n } catch (error) {\n return { success: false, message: 'Connection failed.', server: serverId, timestamp: new Date(), latency: Date.now() - startTime };\n }\n },\n\n sendMessage: async (serverId: string, apiKey: string, model: string, messages: { role: string; content: string }[]): Promise => {\n const endpoint = API_ENDPOINTS[serverId];\n if (!endpoint) throw new Error(`Unsupported server: ${serverId}`);\n\n // Ollama special case\n if (serverId === 'ollama') {\n const response = await fetch(endpoint.url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ model, messages, stream: false }),\n });\n if (!response.ok) throw new Error(`Ollama error: ${response.status}`);\n const data = await response.json();\n return data.message?.content || 'No response';\n }\n\n // Gemini special case\n if (serverId === 'gemini') {\n const geminiEndpoint = `https://generativelanguage.googleapis.com/v1beta/models/${model}:generateContent?key=${apiKey}`;\n const response = await fetch(geminiEndpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n contents: messages.map(m => ({ role: m.role === 'user' ? 'user' : 'model', parts: [{ text: m.content }] }))\n }),\n });\n if (!response.ok) throw new Error(`Gemini error: ${response.status}`);\n const data = await response.json();\n return data.candidates?.[0]?.content?.parts?.[0]?.text || 'No response';\n }\n\n // Claude special case\n if (serverId === 'claude') {\n const response = await fetch(endpoint.url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n 'anthropic-version': '2023-06-01',\n },\n body: JSON.stringify({ model, max_tokens: 4096, messages: messages.map(m => ({ role: m.role, content: m.content })) }),\n });\n if (!response.ok) throw new Error(`Claude error: ${response.status}`);\n const data = await response.json();\n return data.content?.[0]?.text || 'No response';\n }\n\n // Cohere special case\n if (serverId === 'cohere') {\n const response = await fetch(endpoint.url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${apiKey}` },\n body: JSON.stringify({ model, messages: messages.map(m => ({ role: m.role === 'user' ? 'User' : 'Chatbot', message: m.content })) }),\n });\n if (!response.ok) throw new Error(`Cohere error: ${response.status}`);\n const data = await response.json();\n return data.text || 'No response';\n }\n\n // Standard OpenAI-compatible API\n const headers: Record = { 'Content-Type': 'application/json' };\n let body: Record = { model, messages };\n\n // Add auth headers\n if (serverId === 'openrouter') {\n headers['Authorization'] = `Bearer ${apiKey}`;\n headers['HTTP-Referer'] = window.location.origin;\n headers['X-Title'] = 'API Test Hub';\n } else {\n headers['Authorization'] = `Bearer ${apiKey}`;\n }\n\n // ElevenLabs special case\n if (serverId === 'elevenlabs') {\n body = { text: messages[messages.length - 1]?.content, model_id: model };\n }\n\n const response = await fetch(endpoint.url, { method: 'POST', headers, body: JSON.stringify(body) });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n const errorMessage = errorData.error?.message || errorData.message || `API Error: ${response.status}`;\n \n // Provide helpful error messages for common issues\n if (errorMessage.includes('No endpoints found') || errorMessage.includes('model not found')) {\n throw new Error(`Model not available: This model may require credits or not be available on your current plan. Try a different model or check your API account.`);\n }\n if (errorMessage.includes('invalid_api_key') || errorMessage.includes('Incorrect API key')) {\n throw new Error(`Invalid API key: Please check your API key and try again.`);\n }\n if (errorMessage.includes('rate_limit') || errorMessage.includes('Rate limit')) {\n throw new Error(`Rate limit exceeded: Please wait a moment and try again.`);\n }\n if (errorMessage.includes('insufficient_quota') || errorMessage.includes('quota')) {\n throw new Error(`Quota exceeded: Your API account has run out of credits. Please add more credits to your account.`);\n }\n \n throw new Error(errorMessage);\n }\n\n const data = await response.json();\n\n // Extract response - handle various API response formats\n let content = '';\n\n // Standard OpenAI-compatible format\n if (data.choices?.[0]?.message?.content) {\n content = data.choices[0].message.content;\n }\n // Alternative format with text field\n else if (data.choices?.[0]?.text) {\n content = data.choices[0].text;\n }\n // StreamLake/DeepSeek format with choices array\n else if (data.choices?.[0]?.delta?.content) {\n content = data.choices[0].delta.content;\n }\n // Generic choices array iteration\n else if (data.choices && data.choices.length > 0) {\n const firstChoice = data.choices[0];\n content = firstChoice.message?.content || firstChoice.delta?.content || firstChoice.text || '';\n }\n // Response as direct string\n else if (typeof data === 'string') {\n content = data;\n }\n // Response with response or text field at root\n else if (data.response) {\n content = typeof data.response === 'string' ? data.response : data.response.choices?.[0]?.message?.content || JSON.stringify(data.response);\n }\n else if (data.text) {\n content = data.text;\n }\n\n // Clean up content - remove any JSON metadata that might be included\n if (content && typeof content === 'string') {\n // Check if content starts with JSON-like pattern and try to extract actual text\n const jsonMatch = content.match(/^\\s*\\{.*\\}\\s*$/);\n if (jsonMatch && !content.includes('\\n') && content.length < 500) {\n try {\n const parsed = JSON.parse(content);\n // If it's JSON, try to extract meaningful content\n content = parsed.content || parsed.message || parsed.text || parsed.choices?.[0]?.message?.content || parsed.choices?.[0]?.text || content;\n } catch {\n // Not valid JSON, keep original\n }\n }\n }\n\n return content || 'No response';\n },\n\n sendMessageWithThinking: async (serverId: string, apiKey: string, model: string, messages: { role: string; content: string }[]): Promise<{ content: string; thinking?: string }> => {\n // Handle DeepSeek reasoning content\n if (serverId === 'deepseek' || serverId === 'openrouter') {\n const endpoint = API_ENDPOINTS[serverId];\n if (!endpoint) throw new Error(`Unsupported server: ${serverId}`);\n\n const headers: Record = { 'Content-Type': 'application/json' };\n let body: Record = { model, messages };\n\n if (serverId === 'openrouter') {\n headers['Authorization'] = `Bearer ${apiKey}`;\n headers['HTTP-Referer'] = window.location.origin;\n headers['X-Title'] = 'API Test Hub';\n } else {\n headers['Authorization'] = `Bearer ${apiKey}`;\n }\n\n const response = await fetch(endpoint.url, { method: 'POST', headers, body: JSON.stringify(body) });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n throw new Error(errorData.error?.message || `API Error: ${response.status}`);\n }\n\n const data = await response.json();\n \n // Try to extract reasoning/thinking content\n let thinking: string | undefined;\n let content = '';\n\n // DeepSeek reasoning format\n if (data.choices?.[0]?.message?.reasoning) {\n thinking = data.choices[0].message.reasoning;\n }\n // OpenAI o1 style reasoning\n else if (data.choices?.[0]?.message?.reasoning !== undefined) {\n thinking = data.choices[0].message.reasoning;\n }\n // Anthropic Claude extended thinking\n else if (data.choices?.[0]?.message?.thinking) {\n thinking = data.choices[0].message.thinking;\n }\n \n // Extract content\n if (data.choices?.[0]?.message?.content) {\n content = data.choices[0].message.content;\n } else if (data.choices?.[0]?.text) {\n content = data.choices[0].text;\n } else if (data.choices?.[0]?.delta?.content) {\n content = data.choices[0].delta.content;\n }\n\n return { content: content || 'No response', thinking };\n }\n\n // Default behavior for other servers - use direct fetch logic\n const endpoint = API_ENDPOINTS[serverId];\n if (!endpoint) throw new Error(`Unsupported server: ${serverId}`);\n\n // Ollama special case\n if (serverId === 'ollama') {\n const response = await fetch(endpoint.url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ model, messages, stream: false }),\n });\n if (!response.ok) throw new Error(`Ollama error: ${response.status}`);\n const data = await response.json();\n return { content: data.message?.content || 'No response' };\n }\n\n // Gemini special case\n if (serverId === 'gemini') {\n const geminiEndpoint = `https://generativelanguage.googleapis.com/v1beta/models/${model}:generateContent?key=${apiKey}`;\n const response = await fetch(geminiEndpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n contents: messages.map(m => ({ role: m.role === 'user' ? 'user' : 'model', parts: [{ text: m.content }] }))\n }),\n });\n if (!response.ok) throw new Error(`Gemini error: ${response.status}`);\n const data = await response.json();\n return { content: data.candidates?.[0]?.content?.parts?.[0]?.text || 'No response' };\n }\n\n // Claude special case\n if (serverId === 'claude') {\n const response = await fetch(endpoint.url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n 'anthropic-version': '2023-06-01',\n },\n body: JSON.stringify({ model, max_tokens: 4096, messages: messages.map(m => ({ role: m.role, content: m.content })) }),\n });\n if (!response.ok) throw new Error(`Claude error: ${response.status}`);\n const data = await response.json();\n return { content: data.content?.[0]?.text || 'No response' };\n }\n\n // Cohere special case\n if (serverId === 'cohere') {\n const response = await fetch(endpoint.url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${apiKey}` },\n body: JSON.stringify({ model, messages: messages.map(m => ({ role: m.role === 'user' ? 'User' : 'Chatbot', message: m.content })) }),\n });\n if (!response.ok) throw new Error(`Cohere error: ${response.status}`);\n const data = await response.json();\n return { content: data.text || 'No response' };\n }\n\n // Standard OpenAI-compatible API\n const headers: Record = { 'Content-Type': 'application/json' };\n headers['Authorization'] = `Bearer ${apiKey}`;\n let body: Record = { model, messages };\n\n // ElevenLabs special case\n if (serverId === 'elevenlabs') {\n body = { text: messages[messages.length - 1]?.content, model_id: model };\n }\n\n const response = await fetch(endpoint.url, { method: 'POST', headers, body: JSON.stringify(body) });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n throw new Error(errorData.error?.message || `API Error: ${response.status}`);\n }\n\n const data = await response.json();\n\n // Extract response\n let content = '';\n if (data.choices?.[0]?.message?.content) {\n content = data.choices[0].message.content;\n } else if (data.choices?.[0]?.text) {\n content = data.choices[0].text;\n } else if (data.choices?.[0]?.delta?.content) {\n content = data.choices[0].delta.content;\n }\n\n return { content: content || 'No response' };\n },\n\n getEndpoint: (serverId: string): string | undefined => API_ENDPOINTS[serverId]?.url,\n};\n"}, "b2c275c1e0018975a70ed65f0ec3f5a84e593eeb": {"t": 1785759155.5493712, "n": 8848, "h": "86c8cd0ed03d3752", "c": "import type { ApiTestResult } from '../types/api.types';\n\n// Real API Endpoints\nconst API_ENDPOINTS: Record = {\n 'openai': { url: 'https://api.openai.com/v1/chat/completions', method: 'POST' },\n 'gemini': { url: 'https://generativelanguage.googleapis.com/v1beta/models', method: 'POST' },\n 'claude': { url: 'https://api.anthropic.com/v1/messages', method: 'POST' },\n 'deepseek': { url: 'https://api.deepseek.com/chat/completions', method: 'POST' },\n 'groq': { url: 'https://api.groq.com/openai/v1/chat/completions', method: 'POST' },\n 'together': { url: 'https://api.together.xyz/v1/chat/completions', method: 'POST' },\n 'openrouter': { url: 'https://openrouter.ai/api/v1/chat/completions', method: 'POST' },\n 'perplexity': { url: 'https://api.perplexity.ai/chat/completions', method: 'POST' },\n 'mistral': { url: 'https://api.mistral.ai/v1/chat/completions', method: 'POST' },\n 'cohere': { url: 'https://api.cohere.ai/v1/chat', method: 'POST' },\n 'cerebras': { url: 'https://api.cerebras.ai/v1/chat/completions', method: 'POST' },\n 'grok': { url: 'https://api.x.ai/v1/chat/completions', method: 'POST' },\n 'anyscale': { url: 'https://api.endpoints.anyscale.com/v1/chat/completions', method: 'POST' },\n 'ollama': { url: 'http://localhost:11434/api/chat', method: 'POST' },\n 'minimax': { url: 'https://api.minimax.chat/v1/text/chatcompletion_v2', method: 'POST' },\n 'elevenlabs': { url: 'https://api.elevenlabs.io/v1/text-to-speech', method: 'POST' },\n 'nvidia': { url: 'https://integrate.api.nvidia.com/v1/chat/completions', method: 'POST' },\n};\n\nexport const apiService = {\n testApiKey: async (serverId: string, apiKey: string): Promise => {\n const startTime = Date.now();\n try {\n await new Promise(resolve => setTimeout(resolve, 1500));\n const latency = Date.now() - startTime;\n const isValid = apiKey.length >= 10 && !apiKey.includes(' ');\n return {\n success: isValid,\n message: isValid ? `API key validated for ${serverId}! Ready to use.` : 'Invalid API key format.',\n server: serverId,\n timestamp: new Date(),\n latency,\n };\n } catch (error) {\n return { success: false, message: 'Connection failed.', server: serverId, timestamp: new Date(), latency: Date.now() - startTime };\n }\n },\n\n sendMessage: async (serverId: string, apiKey: string, model: string, messages: { role: string; content: string }[]): Promise => {\n const endpoint = API_ENDPOINTS[serverId];\n if (!endpoint) throw new Error(`Unsupported server: ${serverId}`);\n\n // Ollama special case\n if (serverId === 'ollama') {\n const response = await fetch(endpoint.url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ model, messages, stream: false }),\n });\n if (!response.ok) throw new Error(`Ollama error: ${response.status}`);\n const data = await response.json();\n return data.message?.content || 'No response';\n }\n\n // Gemini special case\n if (serverId === 'gemini') {\n const geminiEndpoint = `https://generativelanguage.googleapis.com/v1beta/models/${model}:generateContent?key=${apiKey}`;\n const response = await fetch(geminiEndpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n contents: messages.map(m => ({ role: m.role === 'user' ? 'user' : 'model', parts: [{ text: m.content }] }))\n }),\n });\n if (!response.ok) throw new Error(`Gemini error: ${response.status}`);\n const data = await response.json();\n return data.candidates?.[0]?.content?.parts?.[0]?.text || 'No response';\n }\n\n // Claude special case\n if (serverId === 'claude') {\n const response = await fetch(endpoint.url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n 'anthropic-version': '2023-06-01',\n },\n body: JSON.stringify({ model, max_tokens: 4096, messages: messages.map(m => ({ role: m.role, content: m.content })) }),\n });\n if (!response.ok) throw new Error(`Claude error: ${response.status}`);\n const data = await response.json();\n return data.content?.[0]?.text || 'No response';\n }\n\n // Cohere special case\n if (serverId === 'cohere') {\n const response = await fetch(endpoint.url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${apiKey}` },\n body: JSON.stringify({ model, messages: messages.map(m => ({ role: m.role === 'user' ? 'User' : 'Chatbot', message: m.content })) }),\n });\n if (!response.ok) throw new Error(`Cohere error: ${response.status}`);\n const data = await response.json();\n return data.text || 'No response';\n }\n\n // Standard OpenAI-compatible API\n const headers: Record = { 'Content-Type': 'application/json' };\n let body: Record = { model, messages };\n\n // Add auth headers\n if (serverId === 'openrouter') {\n headers['Authorization'] = `Bearer ${apiKey}`;\n headers['HTTP-Referer'] = window.location.origin;\n headers['X-Title'] = 'API Test Hub';\n } else {\n headers['Authorization'] = `Bearer ${apiKey}`;\n }\n\n // ElevenLabs special case\n if (serverId === 'elevenlabs') {\n body = { text: messages[messages.length - 1]?.content, model_id: model };\n }\n\n const response = await fetch(endpoint.url, { method: 'POST', headers, body: JSON.stringify(body) });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n const errorMessage = errorData.error?.message || errorData.message || `API Error: ${response.status}`;\n \n // Provide helpful error messages for common issues\n if (errorMessage.includes('No endpoints found') || errorMessage.includes('model not found')) {\n throw new Error(`Model not available: This model may require credits or not be available on your current plan. Try a different model or check your API account.`);\n }\n if (errorMessage.includes('invalid_api_key') || errorMessage.includes('Incorrect API key')) {\n throw new Error(`Invalid API key: Please check your API key and try again.`);\n }\n if (errorMessage.includes('rate_limit') || errorMessage.includes('Rate limit')) {\n throw new Error(`Rate limit exceeded: Please wait a moment and try again.`);\n }\n if (errorMessage.includes('insufficient_quota') || errorMessage.includes('quota')) {\n throw new Error(`Quota exceeded: Your API account has run out of credits. Please add more credits to your account.`);\n }\n \n throw new Error(errorMessage);\n }\n\n const data = await response.json();\n\n // Extract response - handle various API response formats\n let content = '';\n\n // Standard OpenAI-compatible format\n if (data.choices?.[0]?.message?.content) {\n content = data.choices[0].message.content;\n }\n // Alternative format with text field\n else if (data.choices?.[0]?.text) {\n content = data.choices[0].text;\n }\n // StreamLake/DeepSeek format with choices array\n else if (data.choices?.[0]?.delta?.content) {\n content = data.choices[0].delta.content;\n }\n // Generic choices array iteration\n else if (data.choices && data.choices.length > 0) {\n const firstChoice = data.choices[0];\n content = firstChoice.message?.content || firstChoice.delta?.content || firstChoice.text || '';\n }\n // Response as direct string\n else if (typeof data === 'string') {\n content = data;\n }\n // Response with response or text field at root\n else if (data.response) {\n content = typeof data.response === 'string' ? data.response : data.response.choices?.[0]?.message?.content || JSON.stringify(data.response);\n }\n else if (data.text) {\n content = data.text;\n }\n\n // Clean up content - remove any JSON metadata that might be included\n if (content && typeof content === 'string') {\n // Check if content starts with JSON-like pattern and try to extract actual text\n const jsonMatch = content.match(/^\\s*\\{.*\\}\\s*$/);\n if (jsonMatch && !content.includes('\\n') && content.length < 500) {\n try {\n const parsed = JSON.parse(content);\n // If it's JSON, try to extract meaningful content\n content = parsed.content || parsed.message || parsed.text || parsed.choices?.[0]?.message?.content || parsed.choices?.[0]?.text || content;\n } catch {\n // Not valid JSON, keep original\n }\n }\n }\n\n return content || 'No response';\n },\n\n getEndpoint: (serverId: string): string | undefined => API_ENDPOINTS[serverId]?.url,\n};\n"}, "da0326bba1ac921806b633237d957202c25aeda5": {"t": 1785759156.8725042, "n": 7834, "h": "cefd84b140b12e44", "c": "import type { ApiTestResult } from '../types/api.types';\n\n// Real API Endpoints\nconst API_ENDPOINTS: Record = {\n 'openai': { url: 'https://api.openai.com/v1/chat/completions', method: 'POST' },\n 'gemini': { url: 'https://generativelanguage.googleapis.com/v1beta/models', method: 'POST' },\n 'claude': { url: 'https://api.anthropic.com/v1/messages', method: 'POST' },\n 'deepseek': { url: 'https://api.deepseek.com/chat/completions', method: 'POST' },\n 'groq': { url: 'https://api.groq.com/openai/v1/chat/completions', method: 'POST' },\n 'together': { url: 'https://api.together.xyz/v1/chat/completions', method: 'POST' },\n 'openrouter': { url: 'https://openrouter.ai/api/v1/chat/completions', method: 'POST' },\n 'perplexity': { url: 'https://api.perplexity.ai/chat/completions', method: 'POST' },\n 'mistral': { url: 'https://api.mistral.ai/v1/chat/completions', method: 'POST' },\n 'cohere': { url: 'https://api.cohere.ai/v1/chat', method: 'POST' },\n 'cerebras': { url: 'https://api.cerebras.ai/v1/chat/completions', method: 'POST' },\n 'grok': { url: 'https://api.x.ai/v1/chat/completions', method: 'POST' },\n 'anyscale': { url: 'https://api.endpoints.anyscale.com/v1/chat/completions', method: 'POST' },\n 'ollama': { url: 'http://localhost:11434/api/chat', method: 'POST' },\n 'minimax': { url: 'https://api.minimax.chat/v1/text/chatcompletion_v2', method: 'POST' },\n 'elevenlabs': { url: 'https://api.elevenlabs.io/v1/text-to-speech', method: 'POST' },\n 'nvidia': { url: 'https://integrate.api.nvidia.com/v1/chat/completions', method: 'POST' },\n};\n\nexport const apiService = {\n testApiKey: async (serverId: string, apiKey: string): Promise => {\n const startTime = Date.now();\n try {\n await new Promise(resolve => setTimeout(resolve, 1500));\n const latency = Date.now() - startTime;\n const isValid = apiKey.length >= 10 && !apiKey.includes(' ');\n return {\n success: isValid,\n message: isValid ? `API key validated for ${serverId}! Ready to use.` : 'Invalid API key format.',\n server: serverId,\n timestamp: new Date(),\n latency,\n };\n } catch (error) {\n return { success: false, message: 'Connection failed.', server: serverId, timestamp: new Date(), latency: Date.now() - startTime };\n }\n },\n\n sendMessage: async (serverId: string, apiKey: string, model: string, messages: { role: string; content: string }[]): Promise => {\n const endpoint = API_ENDPOINTS[serverId];\n if (!endpoint) throw new Error(`Unsupported server: ${serverId}`);\n\n // Ollama special case\n if (serverId === 'ollama') {\n const response = await fetch(endpoint.url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ model, messages, stream: false }),\n });\n if (!response.ok) throw new Error(`Ollama error: ${response.status}`);\n const data = await response.json();\n return data.message?.content || 'No response';\n }\n\n // Gemini special case\n if (serverId === 'gemini') {\n const geminiEndpoint = `https://generativelanguage.googleapis.com/v1beta/models/${model}:generateContent?key=${apiKey}`;\n const response = await fetch(geminiEndpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n contents: messages.map(m => ({ role: m.role === 'user' ? 'user' : 'model', parts: [{ text: m.content }] }))\n }),\n });\n if (!response.ok) throw new Error(`Gemini error: ${response.status}`);\n const data = await response.json();\n return data.candidates?.[0]?.content?.parts?.[0]?.text || 'No response';\n }\n\n // Claude special case\n if (serverId === 'claude') {\n const response = await fetch(endpoint.url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n 'anthropic-version': '2023-06-01',\n },\n body: JSON.stringify({ model, max_tokens: 4096, messages: messages.map(m => ({ role: m.role, content: m.content })) }),\n });\n if (!response.ok) throw new Error(`Claude error: ${response.status}`);\n const data = await response.json();\n return data.content?.[0]?.text || 'No response';\n }\n\n // Cohere special case\n if (serverId === 'cohere') {\n const response = await fetch(endpoint.url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${apiKey}` },\n body: JSON.stringify({ model, messages: messages.map(m => ({ role: m.role === 'user' ? 'User' : 'Chatbot', message: m.content })) }),\n });\n if (!response.ok) throw new Error(`Cohere error: ${response.status}`);\n const data = await response.json();\n return data.text || 'No response';\n }\n\n // Standard OpenAI-compatible API\n const headers: Record = { 'Content-Type': 'application/json' };\n let body: Record = { model, messages };\n\n // Add auth headers\n if (serverId === 'openrouter') {\n headers['Authorization'] = `Bearer ${apiKey}`;\n headers['HTTP-Referer'] = window.location.origin;\n headers['X-Title'] = 'API Test Hub';\n } else {\n headers['Authorization'] = `Bearer ${apiKey}`;\n }\n\n // ElevenLabs special case\n if (serverId === 'elevenlabs') {\n body = { text: messages[messages.length - 1]?.content, model_id: model };\n }\n\n const response = await fetch(endpoint.url, { method: 'POST', headers, body: JSON.stringify(body) });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n throw new Error(errorData.error?.message || `API Error: ${response.status}`);\n }\n\n const data = await response.json();\n\n // Extract response - handle various API response formats\n let content = '';\n\n // Standard OpenAI-compatible format\n if (data.choices?.[0]?.message?.content) {\n content = data.choices[0].message.content;\n }\n // Alternative format with text field\n else if (data.choices?.[0]?.text) {\n content = data.choices[0].text;\n }\n // StreamLake/DeepSeek format with choices array\n else if (data.choices?.[0]?.delta?.content) {\n content = data.choices[0].delta.content;\n }\n // Generic choices array iteration\n else if (data.choices && data.choices.length > 0) {\n const firstChoice = data.choices[0];\n content = firstChoice.message?.content || firstChoice.delta?.content || firstChoice.text || '';\n }\n // Response as direct string\n else if (typeof data === 'string') {\n content = data;\n }\n // Response with response or text field at root\n else if (data.response) {\n content = typeof data.response === 'string' ? data.response : data.response.choices?.[0]?.message?.content || JSON.stringify(data.response);\n }\n else if (data.text) {\n content = data.text;\n }\n\n // Clean up content - remove any JSON metadata that might be included\n if (content && typeof content === 'string') {\n // Check if content starts with JSON-like pattern and try to extract actual text\n const jsonMatch = content.match(/^\\s*\\{.*\\}\\s*$/);\n if (jsonMatch && !content.includes('\\n') && content.length < 500) {\n try {\n const parsed = JSON.parse(content);\n // If it's JSON, try to extract meaningful content\n content = parsed.content || parsed.message || parsed.text || parsed.choices?.[0]?.message?.content || parsed.choices?.[0]?.text || content;\n } catch {\n // Not valid JSON, keep original\n }\n }\n }\n\n return content || 'No response';\n },\n\n getEndpoint: (serverId: string): string | undefined => API_ENDPOINTS[serverId]?.url,\n};\n"}, "8af957a622bbb20e3505a06910528cc50224ae61": {"t": 1785759158.349679, "n": 6100, "h": "660c2e64acca5e9a", "c": "import type { ApiTestResult } from '../types/api.types';\n\n// Real API Endpoints\nconst API_ENDPOINTS: Record = {\n 'openai': { url: 'https://api.openai.com/v1/chat/completions', method: 'POST' },\n 'gemini': { url: 'https://generativelanguage.googleapis.com/v1beta/models', method: 'POST' },\n 'claude': { url: 'https://api.anthropic.com/v1/messages', method: 'POST' },\n 'deepseek': { url: 'https://api.deepseek.com/chat/completions', method: 'POST' },\n 'groq': { url: 'https://api.groq.com/openai/v1/chat/completions', method: 'POST' },\n 'together': { url: 'https://api.together.xyz/v1/chat/completions', method: 'POST' },\n 'openrouter': { url: 'https://openrouter.ai/api/v1/chat/completions', method: 'POST' },\n 'perplexity': { url: 'https://api.perplexity.ai/chat/completions', method: 'POST' },\n 'mistral': { url: 'https://api.mistral.ai/v1/chat/completions', method: 'POST' },\n 'cohere': { url: 'https://api.cohere.ai/v1/chat', method: 'POST' },\n 'cerebras': { url: 'https://api.cerebras.ai/v1/chat/completions', method: 'POST' },\n 'grok': { url: 'https://api.x.ai/v1/chat/completions', method: 'POST' },\n 'anyscale': { url: 'https://api.endpoints.anyscale.com/v1/chat/completions', method: 'POST' },\n 'ollama': { url: 'http://localhost:11434/api/chat', method: 'POST' },\n 'minimax': { url: 'https://api.minimax.chat/v1/text/chatcompletion_v2', method: 'POST' },\n 'elevenlabs': { url: 'https://api.elevenlabs.io/v1/text-to-speech', method: 'POST' },\n 'nvidia': { url: 'https://integrate.api.nvidia.com/v1/chat/completions', method: 'POST' },\n};\n\nexport const apiService = {\n testApiKey: async (serverId: string, apiKey: string): Promise => {\n const startTime = Date.now();\n try {\n await new Promise(resolve => setTimeout(resolve, 1500));\n const latency = Date.now() - startTime;\n const isValid = apiKey.length >= 10 && !apiKey.includes(' ');\n return {\n success: isValid,\n message: isValid ? `API key validated for ${serverId}! Ready to use.` : 'Invalid API key format.',\n server: serverId,\n timestamp: new Date(),\n latency,\n };\n } catch (error) {\n return { success: false, message: 'Connection failed.', server: serverId, timestamp: new Date(), latency: Date.now() - startTime };\n }\n },\n\n sendMessage: async (serverId: string, apiKey: string, model: string, messages: { role: string; content: string }[]): Promise => {\n const endpoint = API_ENDPOINTS[serverId];\n if (!endpoint) throw new Error(`Unsupported server: ${serverId}`);\n\n // Ollama special case\n if (serverId === 'ollama') {\n const response = await fetch(endpoint.url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ model, messages, stream: false }),\n });\n if (!response.ok) throw new Error(`Ollama error: ${response.status}`);\n const data = await response.json();\n return data.message?.content || 'No response';\n }\n\n // Gemini special case\n if (serverId === 'gemini') {\n const geminiEndpoint = `https://generativelanguage.googleapis.com/v1beta/models/${model}:generateContent?key=${apiKey}`;\n const response = await fetch(geminiEndpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n contents: messages.map(m => ({ role: m.role === 'user' ? 'user' : 'model', parts: [{ text: m.content }] }))\n }),\n });\n if (!response.ok) throw new Error(`Gemini error: ${response.status}`);\n const data = await response.json();\n return data.candidates?.[0]?.content?.parts?.[0]?.text || 'No response';\n }\n\n // Claude special case\n if (serverId === 'claude') {\n const response = await fetch(endpoint.url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': apiKey,\n 'anthropic-version': '2023-06-01',\n },\n body: JSON.stringify({ model, max_tokens: 4096, messages: messages.map(m => ({ role: m.role, content: m.content })) }),\n });\n if (!response.ok) throw new Error(`Claude error: ${response.status}`);\n const data = await response.json();\n return data.content?.[0]?.text || 'No response';\n }\n\n // Cohere special case\n if (serverId === 'cohere') {\n const response = await fetch(endpoint.url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${apiKey}` },\n body: JSON.stringify({ model, messages: messages.map(m => ({ role: m.role === 'user' ? 'User' : 'Chatbot', message: m.content })) }),\n });\n if (!response.ok) throw new Error(`Cohere error: ${response.status}`);\n const data = await response.json();\n return data.text || 'No response';\n }\n\n // Standard OpenAI-compatible API\n const headers: Record = { 'Content-Type': 'application/json' };\n let body: Record = { model, messages };\n\n // Add auth headers\n if (serverId === 'openrouter') {\n headers['Authorization'] = `Bearer ${apiKey}`;\n headers['HTTP-Referer'] = window.location.origin;\n headers['X-Title'] = 'API Test Hub';\n } else {\n headers['Authorization'] = `Bearer ${apiKey}`;\n }\n\n // ElevenLabs special case\n if (serverId === 'elevenlabs') {\n body = { text: messages[messages.length - 1]?.content, model_id: model };\n }\n\n const response = await fetch(endpoint.url, { method: 'POST', headers, body: JSON.stringify(body) });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n throw new Error(errorData.error?.message || `API Error: ${response.status}`);\n }\n\n const data = await response.json();\n\n // Extract response\n if (serverId === 'cohere') return data.text || 'No response';\n return data.choices?.[0]?.message?.content || 'No response';\n },\n\n getEndpoint: (serverId: string): string | undefined => API_ENDPOINTS[serverId]?.url,\n};\n"}, "632ac170bdc109dab42cee1a40f8da3c2ca9eb3e": {"t": 1785759159.8782334, "n": 7274, "h": "b81fa73c3cdfabe8", "c": "import type { ApiTestResult } from '../types/api.types';\n\n// Real API Endpoints\nconst API_ENDPOINTS: Record = {\n // OpenAI\n 'openai': {\n url: 'https://api.openai.com/v1/chat/completions',\n method: 'POST'\n },\n // Google Gemini\n 'gemini': {\n url: 'https://generativelanguage.googleapis.com/v1beta/models',\n method: 'POST'\n },\n // Anthropic Claude\n 'claude': {\n url: 'https://api.anthropic.com/v1/messages',\n method: 'POST'\n },\n // DeepSeek\n 'deepseek': {\n url: 'https://api.deepseek.com/chat/completions',\n method: 'POST'\n },\n // Groq\n 'groq': {\n url: 'https://api.groq.com/openai/v1/chat/completions',\n method: 'POST'\n },\n // Together AI\n 'together': {\n url: 'https://api.together.xyz/v1/chat/completions',\n method: 'POST'\n },\n // OpenRouter\n 'openrouter': {\n url: 'https://openrouter.ai/api/v1/chat/completions',\n method: 'POST'\n },\n // Perplexity\n 'perplexity': {\n url: 'https://api.perplexity.ai/chat/completions',\n method: 'POST'\n },\n // Mistral AI\n 'mistral': {\n url: 'https://api.mistral.ai/v1/chat/completions',\n method: 'POST'\n },\n // Cohere\n 'cohere': {\n url: 'https://api.cohere.ai/v1/chat',\n method: 'POST'\n },\n // Cerebras\n 'cerebras': {\n url: 'https://api.cerebras.ai/v1/chat/completions',\n method: 'POST'\n },\n // xAI Grok\n 'grok': {\n url: 'https://api.x.ai/v1/chat/completions',\n method: 'POST'\n },\n // Anyscale\n 'anyscale': {\n url: 'https://api.endpoints.anyscale.com/v1/chat/completions',\n method: 'POST'\n },\n // Ollama (Local)\n 'ollama': {\n url: 'http://localhost:11434/api/chat',\n method: 'POST'\n },\n // MiniMax\n 'minimax': {\n url: 'https://api.minimax.chat/v1/text/chatcompletion_v2',\n method: 'POST'\n },\n // ElevenLabs\n 'elevenlabs': {\n url: 'https://api.elevenlabs.io/v1/text-to-speech',\n method: 'POST'\n },\n};\n\nexport const apiService = {\n // Test API key validity\n testApiKey: async (serverId: string, apiKey: string): Promise => {\n const startTime = Date.now();\n \n try {\n await new Promise(resolve => setTimeout(resolve, 1500));\n const latency = Date.now() - startTime;\n const isValid = apiKey.length >= 10 && !apiKey.includes(' ');\n \n return {\n success: isValid,\n message: isValid \n ? `API key validated for ${serverId}! Ready to use.` \n : 'Invalid API key format. Please check and try again.',\n server: serverId,\n timestamp: new Date(),\n latency,\n };\n } catch (error) {\n return {\n success: false,\n message: 'Connection failed. Please check your network.',\n server: serverId,\n timestamp: new Date(),\n latency: Date.now() - startTime,\n };\n }\n },\n\n // Send message to AI - Real API implementation\n sendMessage: async (\n serverId: string, \n apiKey: string, \n model: string, \n messages: { role: string; content: string }[]\n ): Promise => {\n const endpoint = API_ENDPOINTS[serverId];\n \n if (!endpoint) {\n throw new Error(`Unsupported server: ${serverId}`);\n }\n\n // Ollama special case - local server\n if (serverId === 'ollama') {\n const response = await fetch(endpoint.url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ model, messages, stream: false }),\n });\n \n if (!response.ok) throw new Error(`Ollama error: ${response.status}`);\n const data = await response.json();\n return data.message?.content || 'No response';\n }\n\n // Build headers\n const headers: Record = {\n 'Content-Type': 'application/json',\n };\n\n let body: Record = {};\n\n switch (serverId) {\n case 'openai':\n case 'groq':\n case 'together':\n case 'deepseek':\n case 'perplexity':\n case 'cerebras':\n case 'anyscale':\n case 'mistral':\n headers['Authorization'] = `Bearer ${apiKey}`;\n body = { model, messages };\n break;\n\n case 'claude':\n headers['x-api-key'] = apiKey;\n headers['anthropic-version'] = '2023-06-01';\n body = {\n model,\n max_tokens: 4096,\n messages: messages.map(m => ({ role: m.role, content: m.content }))\n };\n break;\n\n case 'gemini':\n headers['Authorization'] = `Bearer ${apiKey}`;\n const geminiModel = model.includes('gemini') ? model : `${model}`;\n const geminiEndpoint = `https://generativelanguage.googleapis.com/v1beta/models/${geminiModel}:generateContent?key=${apiKey}`;\n const geminiResponse = await fetch(geminiEndpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n contents: messages.map(m => ({\n role: m.role === 'user' ? 'user' : 'model',\n parts: [{ text: m.content }]\n }))\n }),\n });\n \n if (!geminiResponse.ok) throw new Error(`Gemini API error: ${geminiResponse.status}`);\n const geminiData = await geminiResponse.json();\n return geminiData.candidates?.[0]?.content?.parts?.[0]?.text || 'No response';\n\n case 'openrouter':\n headers['Authorization'] = `Bearer ${apiKey}`;\n headers['HTTP-Referer'] = window.location.origin;\n headers['X-Title'] = 'API Test Hub';\n body = { model, messages };\n break;\n\n case 'cohere':\n headers['Authorization'] = `Bearer ${apiKey}`;\n body = { \n model, \n messages: messages.map(m => ({ role: m.role === 'user' ? 'User' : 'Chatbot', message: m.content }))\n };\n break;\n\n case 'grok':\n headers['Authorization'] = `Bearer ${apiKey}`;\n body = { model, messages };\n break;\n\n case 'minimax':\n headers['Authorization'] = `Bearer ${apiKey}`;\n body = {\n model,\n messages: messages.map(m => ({ role: m.role, content: m.content })),\n };\n break;\n\n default:\n headers['Authorization'] = `Bearer ${apiKey}`;\n body = { model, messages };\n }\n\n // Make API call\n const response = await fetch(endpoint.url, {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n throw new Error(errorData.error?.message || `API Error: ${response.status}`);\n }\n\n const data = await response.json();\n \n // Extract response based on server format\n switch (serverId) {\n case 'openai':\n case 'groq':\n case 'together':\n case 'deepseek':\n case 'perplexity':\n case 'cerebras':\n case 'anyscale':\n case 'mistral':\n case 'grok':\n return data.choices?.[0]?.message?.content || 'No response';\n\n case 'claude':\n return data.content?.[0]?.text || 'No response';\n\n case 'cohere':\n return data.text || 'No response';\n\n default:\n return JSON.stringify(data).substring(0, 500);\n }\n },\n\n getEndpoint: (serverId: string): string | undefined => {\n return API_ENDPOINTS[serverId]?.url;\n },\n};\n"}, "d0dd1483bad1f95daec12c478535dcfdbf1345f8": {"t": 1785759161.1920688, "n": 6763, "h": "4eb7211de8de1988", "c": "import type { ApiTestResult } from '../types/api.types';\n\n// API endpoints for different services\nconst API_ENDPOINTS: Record = {\n openai: 'https://api.openai.com/v1/chat/completions',\n gemini: 'https://generativelanguage.googleapis.com/v1beta/models',\n claude: 'https://api.anthropic.com/v1/messages',\n deepseek: 'https://api.deepseek.com/chat/completions',\n ollama: 'http://localhost:11434/api/chat',\n groq: 'https://api.groq.com/openai/v1/chat/completions',\n together: 'https://api.together.xyz/v1/chat/completions',\n openrouter: 'https://openrouter.ai/api/v1/chat/completions',\n cerebras: 'https://api.cerebras.ai/v1/chat/completions',\n perplexity: 'https://api.perplexity.ai/chat/completions',\n minimax: 'https://api.minimax.chat/v1/text/chat_completion_pro',\n cohere: 'https://api.cohere.ai/v1/chat',\n mistral: 'https://api.mistral.ai/v1/chat/completions',\n anyscale: 'https://api.endpoints.anyscale.com/v1/chat/completions',\n elevenlabs: 'https://api.elevenlabs.io/v1/text-to-speech',\n grok: 'https://api.x.ai/v1/chat/completions',\n aws: 'https://{region}.bedrock.amazonaws.com/bedrock/{model}',\n azure: 'https://{resource}.openai.azure.com/openai/deployments/{deployment}/chat/completions',\n vertex: 'https://{project}.{location}.aiplatform.googleapis.com/v1/projects/{project}/locations/{location}/publishers/google/models/{model}:predict',\n};\n\nexport const apiService = {\n // Test API key validity\n testApiKey: async (serverId: string, apiKey: string): Promise => {\n const startTime = Date.now();\n \n try {\n // For demo/testing, simulate validation\n // In production, this would make actual API calls to verify the key\n await new Promise(resolve => setTimeout(resolve, 1500));\n \n const latency = Date.now() - startTime;\n \n // Basic validation - key should be reasonable length\n const isValid = apiKey.length >= 10 && !apiKey.includes(' ');\n \n return {\n success: isValid,\n message: isValid \n ? `API key validated for ${serverId}! Ready to use.` \n : 'Invalid API key format. Please check and try again.',\n server: serverId,\n timestamp: new Date(),\n latency,\n };\n } catch (error) {\n return {\n success: false,\n message: 'Connection failed. Please check your network.',\n server: serverId,\n timestamp: new Date(),\n latency: Date.now() - startTime,\n };\n }\n },\n\n // Send message to AI - Real API implementation\n sendMessage: async (\n serverId: string, \n apiKey: string, \n model: string, \n messages: { role: string; content: string }[]\n ): Promise => {\n const endpoint = API_ENDPOINTS[serverId];\n \n if (!endpoint) {\n throw new Error(`Unsupported server: ${serverId}`);\n }\n\n // Build headers based on server\n const headers: Record = {\n 'Content-Type': 'application/json',\n };\n\n let body: Record = {};\n \n switch (serverId) {\n case 'openai':\n headers['Authorization'] = `Bearer ${apiKey}`;\n body = { model, messages };\n break;\n \n case 'azure':\n headers['api-key'] = apiKey;\n headers['Content-Type'] = 'application/json';\n body = { messages };\n break;\n \n case 'claude':\n headers['x-api-key'] = apiKey;\n headers['anthropic-version'] = '2023-06-01';\n headers['Content-Type'] = 'application/json';\n body = {\n model,\n max_tokens: 4096,\n messages: messages.map(m => ({ role: m.role, content: m.content }))\n };\n break;\n \n case 'gemini':\n headers['Authorization'] = `Bearer ${apiKey}`;\n body = {\n contents: messages.map(m => ({\n role: m.role === 'user' ? 'user' : 'model',\n parts: [{ text: m.content }]\n }))\n };\n break;\n \n case 'ollama':\n body = {\n model,\n messages,\n stream: false\n };\n break;\n \n case 'groq':\n headers['Authorization'] = `Bearer ${apiKey}`;\n body = { model, messages };\n break;\n \n case 'together':\n headers['Authorization'] = `Bearer ${apiKey}`;\n body = { model, messages };\n break;\n \n case 'openrouter':\n headers['Authorization'] = `Bearer ${apiKey}`;\n headers['HTTP-Referer'] = window.location.origin;\n headers['X-Title'] = 'API Test Hub';\n body = { model, messages };\n break;\n \n case 'deepseek':\n headers['Authorization'] = `Bearer ${apiKey}`;\n body = { model, messages };\n break;\n \n case 'cohere':\n headers['Authorization'] = `Bearer ${apiKey}`;\n body = { \n model, \n messages: messages.map(m => ({ role: m.role === 'user' ? 'User' : 'Chatbot', message: m.content }))\n };\n break;\n \n default:\n headers['Authorization'] = `Bearer ${apiKey}`;\n body = { model, messages };\n }\n\n // For servers that don't need real API calls (demo mode)\n if (serverId === 'ollama' && apiKey === 'demo') {\n await new Promise(resolve => setTimeout(resolve, 1500));\n return `This is a demo response from ${model}. In production, enter your ${serverId} API key to get real responses.`;\n }\n\n // Make the actual API call\n const response = await fetch(endpoint, {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n throw new Error(errorData.error?.message || `API Error: ${response.status}`);\n }\n\n const data = await response.json();\n \n // Extract response based on server format\n switch (serverId) {\n case 'openai':\n case 'groq':\n case 'together':\n case 'deepseek':\n case 'openrouter':\n case 'cerebras':\n case 'perplexity':\n case 'mistral':\n case 'anyscale':\n case 'grok':\n return data.choices?.[0]?.message?.content || 'No response';\n \n case 'claude':\n return data.content?.[0]?.text || 'No response';\n \n case 'gemini':\n return data.candidates?.[0]?.content?.parts?.[0]?.text || 'No response';\n \n case 'ollama':\n return data.message?.content || 'No response';\n \n case 'cohere':\n return data.text || 'No response';\n \n default:\n return JSON.stringify(data).substring(0, 500);\n }\n },\n\n // Get available models for a server\n getEndpoint: (serverId: string): string | undefined => {\n return API_ENDPOINTS[serverId];\n },\n};\n"}, "5413954a5ad71d1e6f25685a4525bccadc1b9e48": {"t": 1785759162.4153183, "n": 1624, "h": "c5b514aa887a8003", "c": "import type { ApiTestResult } from '../types/api.types';\n\nexport const apiService = {\n testApiKey: async (serverId: string, apiKey: string): Promise => {\n const startTime = Date.now();\n \n // Simulate API test with animation\n await new Promise(resolve => setTimeout(resolve, 2000 + Math.random() * 1000));\n \n const latency = Date.now() - startTime;\n \n // For demo purposes, simulate validation\n // In real app, this would make actual API calls\n const isValid = apiKey.length >= 10 && !apiKey.includes('invalid');\n \n return {\n success: isValid,\n message: isValid \n ? `Successfully connected to ${serverId}!` \n : 'Invalid API key. Please check and try again.',\n server: serverId,\n timestamp: new Date(),\n latency,\n };\n },\n\n sendMessage: async (\n serverId: string, \n _apiKey: string, \n model: string, \n _message: string\n ): Promise => {\n // Simulate API call with typing delay\n const delay = 1500 + Math.random() * 2000;\n await new Promise(resolve => setTimeout(resolve, delay));\n \n // Demo response based on message content\n const responses = [\n \"I understand. Let me help you with that.\",\n \"That's an interesting question! Here's what I think...\",\n \"Thanks for sharing. Let me provide some insights.\",\n \"I've processed your request. Here's my response:\",\n \"Great question! Let me elaborate on that topic.\",\n ];\n \n return responses[Math.floor(Math.random() * responses.length)] + \n `\\n\\n[This is a demo response from ${model} via ${serverId}]`;\n },\n};\n"}}}}