SPB Git

spb/zyquo-router Public MIT

One local endpoint, every AI provider — a private OpenAI-compatible LLM gateway for your Mac (170 models, 12 providers).

Swift 95.7% Python 2.3% Shell 1.2% Makefile 0.9%
3.1 KB · 94 lines swift
Raw Blame History
1//2//  ProviderID.swift3//  Zyquo Router4//5//  Author: Simon-Pierre Boucher6//  Mail: contact@spboucher.ai7//89import Foundation1011/// The 12 built-in cloud AI providers, plus user-defined custom endpoints.12enum ProviderID: String, Codable, CaseIterable, Identifiable, Hashable {13    case openai14    case anthropic15    case xai16    case mistral17    case gemini18    case qwen19    case deepseek20    case kimi21    case perplexity22    case together23    case deepinfra24    case cerebras25    case custom2627    var id: String { rawValue }2829    /// User-facing display name.30    var displayName: String {31        switch self {32        case .openai: return "OpenAI"33        case .anthropic: return "Anthropic"34        case .xai: return "xAI"35        case .mistral: return "Mistral"36        case .gemini: return "Google Gemini"37        case .qwen: return "Alibaba Qwen"38        case .deepseek: return "DeepSeek"39        case .kimi: return "Kimi"40        case .perplexity: return "Perplexity"41        case .together: return "Together AI"42        case .deepinfra: return "DeepInfra"43        case .cerebras: return "Cerebras"44        case .custom: return "Custom"45        }46    }4748    /// Wire protocol used by this provider's chat endpoint.49    var wireFormat: WireFormat {50        switch self {51        case .anthropic: return .anthropicMessages52        default: return .openAIChatCompletions53        }54    }5556    /// Base URL of the provider's API (chat + models live under this root).57    /// `custom` has no fixed base URL — it comes from the user's endpoint config.58    var defaultBaseURL: URL? {59        switch self {60        case .openai: return URL(string: "https://api.openai.com/v1")61        case .anthropic: return URL(string: "https://api.anthropic.com/v1")62        case .xai: return URL(string: "https://api.x.ai/v1")63        case .mistral: return URL(string: "https://api.mistral.ai/v1")64        case .gemini: return URL(string: "https://generativelanguage.googleapis.com/v1beta/openai")65        case .qwen: return URL(string: "https://dashscope-intl.aliyuncs.com/compatible-mode/v1")66        case .deepseek: return URL(string: "https://api.deepseek.com")67        case .kimi: return URL(string: "https://api.moonshot.ai/v1")68        case .perplexity: return URL(string: "https://api.perplexity.ai")69        case .together: return URL(string: "https://api.together.xyz/v1")70        case .deepinfra: return URL(string: "https://api.deepinfra.com/v1/openai")71        case .cerebras: return URL(string: "https://api.cerebras.ai/v1")72        case .custom: return nil73        }74    }7576    /// Whether the provider exposes a `/models` listing endpoint usable for dynamic refresh.77    var supportsModelListing: Bool {78        self != .perplexity79    }8081    /// Providers shown in Settings (custom endpoints are managed separately).82    static var builtIn: [ProviderID] {83        allCases.filter { $0 != .custom }84    }85}8687/// The request/response schema a provider speaks.88enum WireFormat: String, Codable {89    /// OpenAI `/chat/completions` schema (used by 11 of the 12 built-in providers).90    case openAIChatCompletions91    /// Anthropic `/v1/messages` schema.92    case anthropicMessages93}94