// // Settings.swift // oAI // // Application settings and configuration // // SPDX-License-Identifier: AGPL-3.0-or-later // Copyright (C) 2026 Rune Olsen // // This file is part of oAI. // // oAI is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as // published by the Free Software Foundation, either version 3 of the // License, or (at your option) any later version. // // oAI is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General // Public License for more details. // // You should have received a copy of the GNU Affero General Public // License along with oAI. If not, see . import Foundation struct Settings: Codable { // Provider settings var defaultProvider: Provider var openrouterAPIKey: String? var anthropicAPIKey: String? var openaiAPIKey: String? var ollamaBaseURL: String // Model settings var defaultModel: String? var streamEnabled: Bool var maxTokens: Int var systemPrompt: String? var customPromptMode: CustomPromptMode // Feature flags var onlineMode: Bool var memoryEnabled: Bool var mcpEnabled: Bool // Web search var searchProvider: SearchProvider var googleAPIKey: String? var googleSearchEngineID: String? // UI var costWarningThreshold: Double enum Provider: String, Codable, CaseIterable { case openrouter case anthropic case openai case ollama var displayName: String { rawValue.capitalized } var iconName: String { switch self { case .openrouter: return "network" case .anthropic: return "brain" case .openai: return "sparkles" case .ollama: return "server.rack" } } } enum SearchProvider: String, Codable, CaseIterable { case anthropicNative = "anthropic_native" case duckduckgo case google var displayName: String { switch self { case .anthropicNative: return "Anthropic Native" case .duckduckgo: return "DuckDuckGo" case .google: return "Google" } } } enum CustomPromptMode: String, Codable, CaseIterable { case append = "append" case replace = "replace" var displayName: String { switch self { case .append: return "Append to Default" case .replace: return "Replace Default (BYOP)" } } var description: String { switch self { case .append: return "Your custom prompt will be added after the default system prompt" case .replace: return "Only use your custom prompt (Bring Your Own Prompt)" } } } // Default settings static let `default` = Settings( defaultProvider: .openrouter, openrouterAPIKey: nil, anthropicAPIKey: nil, openaiAPIKey: nil, ollamaBaseURL: "http://localhost:11434", defaultModel: nil, streamEnabled: true, maxTokens: 4096, systemPrompt: nil, customPromptMode: .append, onlineMode: false, memoryEnabled: true, mcpEnabled: false, searchProvider: .duckduckgo, googleAPIKey: nil, googleSearchEngineID: nil, costWarningThreshold: 1.0 ) }