"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.AIProviderService = exports.AIProviderType = exports.AIProviderCapability = void 0; var AIProviderCapability; (function (AIProviderCapability) { AIProviderCapability["CHAT"] = "chat"; AIProviderCapability["COMPLETION"] = "completion"; AIProviderCapability["EMBEDDING"] = "embedding"; AIProviderCapability["VISION"] = "vision"; AIProviderCapability["TOOL_USE"] = "tool_use"; AIProviderCapability["STREAMING"] = "streaming"; })(AIProviderCapability = exports.AIProviderCapability || (exports.AIProviderCapability = {})); var AIProviderType; (function (AIProviderType) { AIProviderType["OPENAI"] = "openai"; AIProviderType["ANTHROPIC"] = "anthropic"; AIProviderType["OLLAMA"] = "ollama"; AIProviderType["GROQ"] = "groq"; AIProviderType["OPENROUTER"] = "openrouter"; AIProviderType["CUSTOM"] = "custom"; AIProviderType["GOOGLE_GEMINI"] = "google_gemini"; AIProviderType["COMMAND_CODE"] = "command_code"; AIProviderType["NVIDIA_NIM"] = "nvidia_nim"; AIProviderType["CROF_AI"] = "crof_ai"; AIProviderType["KILO_AI"] = "kilo_ai"; AIProviderType["OPEN_ADAPTER"] = "open_adapter"; AIProviderType["Z_AI"] = "z_ai"; AIProviderType["GOOGLE_ANTIGRAVITY"] = "google_antigravity"; })(AIProviderType = exports.AIProviderType || (exports.AIProviderType = {})); const PROVIDER_PRESETS = { "Custom": { type: AIProviderType.CUSTOM, endpoint: "", capabilities: [AIProviderCapability.CHAT, AIProviderCapability.STREAMING], }, "OpenAI": { type: AIProviderType.OPENAI, endpoint: "https://api.openai.com/v1", models: ["gpt-4o", "gpt-4o-mini", "gpt-4-turbo", "gpt-3.5-turbo"], capabilities: [AIProviderCapability.CHAT, AIProviderCapability.COMPLETION, AIProviderCapability.EMBEDDING, AIProviderCapability.VISION, AIProviderCapability.TOOL_USE, AIProviderCapability.STREAMING], }, "Anthropic": { type: AIProviderType.ANTHROPIC, endpoint: "https://api.anthropic.com/v1", models: ["claude-sonnet-4-20250514", "claude-3-5-sonnet-latest", "claude-3-opus-latest", "claude-3-haiku-latest"], capabilities: [AIProviderCapability.CHAT, AIProviderCapability.VISION, AIProviderCapability.TOOL_USE, AIProviderCapability.STREAMING], }, "OpenCode Zen (OpenAI-compatible)": { type: AIProviderType.CUSTOM, endpoint: "https://opencode.ai/zen/v1", models: [ "glm-5.1", "glm-5", "kimi-k2.5", "kimi-k2.6", "minimax-m2.7", "minimax-m2.5", "minimax-m2.5-free", "deepseek-v4-flash-free", "nemotron-3-super-free", "qwen3.6-plus", "qwen3.5-plus", "big-pickle", ], capabilities: [AIProviderCapability.CHAT, AIProviderCapability.COMPLETION, AIProviderCapability.STREAMING], }, "OpenCode Zen (Anthropic)": { type: AIProviderType.ANTHROPIC, endpoint: "https://opencode.ai/zen/v1", models: [ "claude-opus-4-7", "claude-opus-4-6", "claude-opus-4-5", "claude-opus-4-1", "claude-sonnet-4-6", "claude-sonnet-4-5", "claude-sonnet-4", "claude-haiku-4-5", "claude-3-5-haiku", ], capabilities: [AIProviderCapability.CHAT, AIProviderCapability.VISION, AIProviderCapability.TOOL_USE, AIProviderCapability.STREAMING], }, "OpenCode Go (OpenAI-compatible)": { type: AIProviderType.CUSTOM, endpoint: "https://opencode.ai/zen/go/v1", models: [ "glm-5.1", "glm-5", "kimi-k2.5", "kimi-k2.6", "mimo-v2.5", "mimo-v2.5-pro", "minimax-m2.7", "minimax-m2.5", "qwen3.6-plus", "qwen3.5-plus", "deepseek-v4-pro", "deepseek-v4-flash", ], capabilities: [AIProviderCapability.CHAT, AIProviderCapability.COMPLETION, AIProviderCapability.STREAMING], }, "OpenCode Go (Anthropic)": { type: AIProviderType.ANTHROPIC, endpoint: "https://opencode.ai/zen/go/v1", models: ["minimax-m2.7", "minimax-m2.5"], capabilities: [AIProviderCapability.CHAT, AIProviderCapability.VISION, AIProviderCapability.TOOL_USE, AIProviderCapability.STREAMING], }, "Crof.ai": { type: AIProviderType.CUSTOM, endpoint: "https://crof.ai/v1", models: [], capabilities: [AIProviderCapability.CHAT, AIProviderCapability.COMPLETION, AIProviderCapability.STREAMING], }, "NVIDIA NIM": { type: AIProviderType.NVIDIA_NIM, endpoint: "https://integrate.api.nvidia.com/v1", models: [], capabilities: [AIProviderCapability.CHAT, AIProviderCapability.COMPLETION, AIProviderCapability.STREAMING], }, "Kilo.ai Gateway": { type: AIProviderType.KILO_AI, endpoint: "https://api.kilo.ai/api/gateway", models: [], capabilities: [AIProviderCapability.CHAT, AIProviderCapability.COMPLETION, AIProviderCapability.STREAMING], }, "Command Code": { type: AIProviderType.COMMAND_CODE, endpoint: "https://api.commandcode.ai", models: [ "deepseek/deepseek-v4-flash", "deepseek/deepseek-v4-pro", "anthropic:claude-sonnet-4-6", "anthropic:claude-haiku-4-5-20251001", "anthropic:claude-opus-4-7", "anthropic:claude-opus-4-6", "openai:gpt-5.5", "openai:gpt-5.4", "openai:gpt-5.4-mini", "openai:gpt-5.3-codex", "moonshotai/Kimi-K2.6", "moonshotai/Kimi-K2.5", "zai-org/GLM-5.1", "zai-org/GLM-5", "MiniMaxAI/MiniMax-M2.7", "MiniMaxAI/MiniMax-M2.5", "Qwen/Qwen3.6-Max-Preview", "Qwen/Qwen3.6-Plus", "stepfun/Step-3.5-Flash", "google/gemini-3.1-flash-lite", ], capabilities: [AIProviderCapability.CHAT, AIProviderCapability.TOOL_USE, AIProviderCapability.STREAMING], }, "OpenRouter": { type: AIProviderType.OPENROUTER, endpoint: "https://openrouter.ai/api/v1", models: [], capabilities: [AIProviderCapability.CHAT, AIProviderCapability.COMPLETION, AIProviderCapability.STREAMING], }, "Google Gemini (API Key)": { type: AIProviderType.GOOGLE_GEMINI, endpoint: "https://generativelanguage.googleapis.com/v1beta/openai", models: [ "gemini-2.5-flash", "gemini-2.5-pro", "gemini-2.0-flash", "gemini-2.0-flash-lite", "gemini-2.5-flash-preview-native-audio-dialog", ], capabilities: [AIProviderCapability.CHAT, AIProviderCapability.VISION, AIProviderCapability.STREAMING], }, "Google Gemini (OAuth)": { type: AIProviderType.GOOGLE_GEMINI, endpoint: "https://cloudcode-pa.googleapis.com", models: ["gemini-2.5-flash", "gemini-2.5-pro"], capabilities: [AIProviderCapability.CHAT, AIProviderCapability.VISION, AIProviderCapability.TOOL_USE, AIProviderCapability.STREAMING], }, "Google Antigravity (OAuth)": { type: AIProviderType.GOOGLE_ANTIGRAVITY, endpoint: "https://daily-cloudcode-pa.sandbox.googleapis.com", models: [ "antigravity-gemini-3-flash", "antigravity-gemini-3-pro", "antigravity-gemini-3.1-pro", "antigravity-claude-sonnet-4-6", "antigravity-claude-opus-4-6-thinking", "gemini-2.5-flash", "gemini-2.5-pro", "gemini-3-flash-preview", "gemini-3-pro-preview", "gemini-3.1-pro-preview", ], capabilities: [AIProviderCapability.CHAT, AIProviderCapability.VISION, AIProviderCapability.TOOL_USE, AIProviderCapability.STREAMING], }, "OpenAdapter": { type: AIProviderType.OPEN_ADAPTER, endpoint: "https://api.openadapter.in/v1", models: [ "0G-DeepSeek-V3", "0G-DeepSeek-v4-Pro", "0G-GLM-5", "0G-GLM-5.1", "0G-Qwen3.6", "0G-Qwen-VL", ], capabilities: [AIProviderCapability.CHAT, AIProviderCapability.COMPLETION, AIProviderCapability.STREAMING], }, "Z.ai Coding": { type: AIProviderType.Z_AI, endpoint: "https://api.z.ai/api/coding/paas/v4", models: [ "glm-5.1", "glm-4.7", "GLM-4-Plus", "GLM-4-Long", "GLM-4-Flash", "GLM-4-FlashX", "GLM-Z1-Flash", ], capabilities: [AIProviderCapability.CHAT, AIProviderCapability.COMPLETION, AIProviderCapability.STREAMING], }, "Ollama (Local)": { type: AIProviderType.OLLAMA, endpoint: "http://localhost:11434/v1", apiKey: "ollama", models: ["llama3", "codellama", "mistral", "neural-chat"], capabilities: [AIProviderCapability.CHAT, AIProviderCapability.COMPLETION, AIProviderCapability.STREAMING], }, "Groq": { type: AIProviderType.GROQ, endpoint: "https://api.groq.com/openai/v1", models: ["llama-3.1-8b-instant", "llama-3.1-70b-versatile", "mixtral-8x7b-32768"], capabilities: [AIProviderCapability.CHAT, AIProviderCapability.COMPLETION, AIProviderCapability.STREAMING], }, }; const DEFAULT_PROVIDERS = [ { id: 'openai-default', name: 'OpenAI', type: AIProviderType.OPENAI, endpoint: 'https://api.openai.com/v1', apiKey: '', models: ['gpt-4o', 'gpt-4o-mini', 'gpt-4-turbo', 'gpt-3.5-turbo'], defaultModel: 'gpt-4o', capabilities: [ AIProviderCapability.CHAT, AIProviderCapability.COMPLETION, AIProviderCapability.EMBEDDING, AIProviderCapability.VISION, AIProviderCapability.TOOL_USE, AIProviderCapability.STREAMING, ], isEnabled: true, isDefault: true, }, { id: 'anthropic-default', name: 'Anthropic', type: AIProviderType.ANTHROPIC, endpoint: 'https://api.anthropic.com/v1', apiKey: '', models: ['claude-sonnet-4-20250514', 'claude-3-5-sonnet-latest', 'claude-3-opus-latest', 'claude-3-haiku-latest'], defaultModel: 'claude-sonnet-4-20250514', capabilities: [ AIProviderCapability.CHAT, AIProviderCapability.VISION, AIProviderCapability.TOOL_USE, AIProviderCapability.STREAMING, ], isEnabled: true, isDefault: false, }, { id: 'ollama-default', name: 'Ollama (Local)', type: AIProviderType.OLLAMA, endpoint: 'http://localhost:11434/v1', apiKey: 'ollama', models: ['llama3', 'codellama', 'mistral', 'neural-chat'], defaultModel: 'llama3', capabilities: [ AIProviderCapability.CHAT, AIProviderCapability.COMPLETION, AIProviderCapability.STREAMING, ], isEnabled: true, isDefault: false, }, ]; class AIProviderService { constructor(storageManager) { this.storageManager = storageManager; this.providers = new Map(); this.eventEmitter = new (require('events').EventEmitter)(); } async initialize() { const items = await this.storageManager.getItems(); const storedProviders = items['aiProviders']; if (storedProviders) { try { const providersArray = JSON.parse(storedProviders); providersArray.forEach((provider) => { this.providers.set(provider.id, provider); }); } catch (e) { console.error('Error loading AI providers:', e); this.loadDefaultProviders(); } } else { this.loadDefaultProviders(); } } loadDefaultProviders() { DEFAULT_PROVIDERS.forEach((provider) => { this.providers.set(provider.id, { ...provider }); }); this.persistProviders(); } async persistProviders() { const providersArray = Array.from(this.providers.values()); await this.storageManager.updateItems({ 'aiProviders': JSON.stringify(providersArray), }); } getAllProviders() { return Array.from(this.providers.values()); } getProvider(id) { return this.providers.get(id); } getEnabledProviders() { return this.getAllProviders().filter(p => p.isEnabled); } getDefaultProvider() { return this.getAllProviders().find(p => p.isDefault) || this.getAllProviders()[0]; } getAvailablePresets() { return Object.keys(PROVIDER_PRESETS); } getPreset(presetName) { return PROVIDER_PRESETS[presetName]; } async addProvider(provider) { const newProvider = { id: `custom-${Date.now()}`, name: provider.name || 'Custom Provider', type: provider.type || AIProviderType.CUSTOM, endpoint: provider.endpoint || '', apiKey: provider.apiKey || '', models: provider.models || [], defaultModel: provider.defaultModel || (provider.models && provider.models[0]) || '', capabilities: provider.capabilities || [AIProviderCapability.CHAT], isEnabled: true, isDefault: false, ...provider, }; this.providers.set(newProvider.id, newProvider); await this.persistProviders(); this.emit('provider-added', newProvider); return newProvider; } async addProviderFromPreset(presetName, apiKey = '') { const preset = PROVIDER_PRESETS[presetName]; if (!preset) { throw new Error(`Preset "${presetName}" not found`); } const normalizedName = presetName.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, ''); const newProvider = { id: `${normalizedName}-${Date.now()}`, name: presetName, type: preset.type || AIProviderType.CUSTOM, endpoint: preset.endpoint || '', apiKey: apiKey || preset.apiKey || '', models: preset.models || [], defaultModel: preset.models && preset.models[0] || '', capabilities: preset.capabilities || [AIProviderCapability.CHAT, AIProviderCapability.STREAMING], isEnabled: true, isDefault: false, presetName: presetName, }; this.providers.set(newProvider.id, newProvider); await this.persistProviders(); this.emit('provider-added', newProvider); return newProvider; } async updateProvider(id, updates) { const provider = this.providers.get(id); if (!provider) { throw new Error(`Provider with id ${id} not found`); } const updatedProvider = { ...provider, ...updates, id: provider.id, }; this.providers.set(id, updatedProvider); await this.persistProviders(); this.emit('provider-updated', updatedProvider); return updatedProvider; } async deleteProvider(id) { const provider = this.providers.get(id); if (!provider) { throw new Error(`Provider with id ${id} not found`); } this.providers.delete(id); await this.persistProviders(); this.emit('provider-deleted', id); } async setDefaultProvider(id) { const provider = this.providers.get(id); if (!provider) { throw new Error(`Provider with id ${id} not found`); } this.getAllProviders().forEach((p) => { p.isDefault = p.id === id; }); await this.persistProviders(); this.emit('default-provider-changed', id); } async toggleProvider(id, enabled) { const provider = this.providers.get(id); if (!provider) { throw new Error(`Provider with id ${id} not found`); } provider.isEnabled = enabled; await this.persistProviders(); this.emit('provider-toggled', { id, enabled }); } async testConnection(id) { const provider = this.providers.get(id); if (!provider) { throw new Error(`Provider with id ${id} not found`); } if (!provider.endpoint) { return { success: false, status: -1, message: 'No endpoint configured', }; } try { const headers = { 'Content-Type': 'application/json', }; if (provider.apiKey && provider.apiKey !== 'ollama') { headers['Authorization'] = `Bearer ${provider.apiKey}`; } const response = await fetch(`${provider.endpoint}/models`, { method: 'GET', headers: headers, }); return { success: response.ok, status: response.status, message: response.ok ? 'Connection successful' : `Error: ${response.statusText}`, }; } catch (error) { return { success: false, status: -1, message: `Connection failed: ${error.message}`, }; } } async fetchModels(id) { const provider = this.providers.get(id); if (!provider) { throw new Error(`Provider with id ${id} not found`); } if (!provider.endpoint) { throw new Error('No endpoint configured'); } try { const headers = { 'Content-Type': 'application/json', }; if (provider.apiKey && provider.apiKey !== 'ollama') { headers['Authorization'] = `Bearer ${provider.apiKey}`; } const response = await fetch(`${provider.endpoint}/models`, { method: 'GET', headers: headers, }); if (!response.ok) { throw new Error(`API error: ${response.statusText}`); } const data = await response.json(); let models = []; if (data.data && Array.isArray(data.data)) { models = data.data.map(model => model.id || model.model || model.name).filter(Boolean); } else if (data.models && Array.isArray(data.models)) { models = data.models.map(model => model.id || model.model || model.name).filter(Boolean); } if (models.length > 0) { provider.models = models; provider.defaultModel = models[0]; await this.persistProviders(); this.emit('provider-updated', provider); } return models; } catch (error) { throw new Error(`Failed to fetch models: ${error.message}`); } } on(event, listener) { this.eventEmitter.on(event, listener); } off(event, listener) { this.eventEmitter.off(event, listener); } emit(event, ...args) { this.eventEmitter.emit(event, ...args); } } exports.AIProviderService = AIProviderService;