130 lines
3.6 KiB
Swift
130 lines
3.6 KiB
Swift
//
|
|
// 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 <https://www.gnu.org/licenses/>.
|
|
|
|
|
|
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
|
|
)
|
|
}
|