// // ProviderID.swift // Zyquo Agent // // Author: Simon-Pierre Boucher // Mail: contact@spboucher.ai // // Ported verbatim from Zyquo Cloud — same providers, same base URLs, same // wire formats. See docs/PROVIDER-REUSE.md. // import Foundation /// The 12 built-in cloud AI providers, plus user-defined custom endpoints. enum ProviderID: String, Codable, CaseIterable, Identifiable, Hashable { case openai case anthropic case xai case mistral case gemini case qwen case deepseek case kimi case perplexity case together case deepinfra case cerebras case custom var id: String { rawValue } /// User-facing display name. var displayName: String { switch self { case .openai: return "OpenAI" case .anthropic: return "Anthropic" case .xai: return "xAI" case .mistral: return "Mistral" case .gemini: return "Google Gemini" case .qwen: return "Alibaba Qwen" case .deepseek: return "DeepSeek" case .kimi: return "Kimi" case .perplexity: return "Perplexity" case .together: return "Together AI" case .deepinfra: return "DeepInfra" case .cerebras: return "Cerebras" case .custom: return "Custom" } } /// Wire protocol used by this provider's chat endpoint. var wireFormat: WireFormat { switch self { case .anthropic: return .anthropicMessages default: return .openAIChatCompletions } } /// Base URL of the provider's API (chat + models live under this root). /// `custom` has no fixed base URL — it comes from the user's endpoint config. var defaultBaseURL: URL? { switch self { case .openai: return URL(string: "https://api.openai.com/v1") case .anthropic: return URL(string: "https://api.anthropic.com/v1") case .xai: return URL(string: "https://api.x.ai/v1") case .mistral: return URL(string: "https://api.mistral.ai/v1") case .gemini: return URL(string: "https://generativelanguage.googleapis.com/v1beta/openai") case .qwen: return URL(string: "https://dashscope-intl.aliyuncs.com/compatible-mode/v1") case .deepseek: return URL(string: "https://api.deepseek.com") case .kimi: return URL(string: "https://api.moonshot.ai/v1") case .perplexity: return URL(string: "https://api.perplexity.ai") case .together: return URL(string: "https://api.together.xyz/v1") case .deepinfra: return URL(string: "https://api.deepinfra.com/v1/openai") case .cerebras: return URL(string: "https://api.cerebras.ai/v1") case .custom: return nil } } /// Whether the provider exposes a `/models` listing endpoint usable for dynamic refresh. var supportsModelListing: Bool { self != .perplexity } /// Providers shown in Settings (custom endpoints are managed separately). static var builtIn: [ProviderID] { allCases.filter { $0 != .custom } } } /// The request/response schema a provider speaks. enum WireFormat: String, Codable { /// OpenAI `/chat/completions` schema (used by 11 of the 12 built-in providers). case openAIChatCompletions /// Anthropic `/v1/messages` schema. case anthropicMessages }