import Foundation enum RecognitionLanguage: String, CaseIterable { case chineseSimplified = "zh-CN" case english = "en-US" case chineseTraditional = "zh-TW" case japanese = "ja-JP" case korean = "ko-KR" var displayName: String { switch self { case .chineseSimplified: return "简体中文" case .english: return "English" case .chineseTraditional: return "繁體中文" case .japanese: return "日本語" case .korean: return "한국어" } } } enum LLMMode { case input // Fn 键:语音输入纠错 case assist // Control 键:AI 助手对话 } struct LLMConfig { var enabled: Bool var baseURL: String var apiKey: String var model: String var isConfigured: Bool { !baseURL.isEmpty && !apiKey.isEmpty && !model.isEmpty } } final class Config { static let shared = Config() private init() {} private let defaults = UserDefaults.standard private enum Keys { static let language = "recognition_language" // Fn 键模式(语音输入纠错) static let inputLLMEnabled = "input_llm_enabled" static let inputLLMBaseURL = "input_llm_base_url" static let inputLLMAPIKey = "input_llm_api_key" static let inputLLMModel = "input_llm_model" // Control 键模式(AI 助手) static let assistLLMEnabled = "assist_llm_enabled" static let assistLLMBaseURL = "assist_llm_base_url" static let assistLLMAPIKey = "assist_llm_api_key" static let assistLLMModel = "assist_llm_model" } var language: RecognitionLanguage { get { guard let raw = defaults.string(forKey: Keys.language), let lang = RecognitionLanguage(rawValue: raw) else { return .chineseSimplified } return lang } set { defaults.set(newValue.rawValue, forKey: Keys.language) } } // MARK: - Fn 键模式配置(语音输入纠错) var inputLLM: LLMConfig { get { LLMConfig( enabled: defaults.bool(forKey: Keys.inputLLMEnabled), baseURL: defaults.string(forKey: Keys.inputLLMBaseURL) ?? "", apiKey: defaults.string(forKey: Keys.inputLLMAPIKey) ?? "", model: defaults.string(forKey: Keys.inputLLMModel) ?? "" ) } set { defaults.set(newValue.enabled, forKey: Keys.inputLLMEnabled) defaults.set(newValue.baseURL, forKey: Keys.inputLLMBaseURL) defaults.set(newValue.apiKey, forKey: Keys.inputLLMAPIKey) defaults.set(newValue.model, forKey: Keys.inputLLMModel) } } // 兼容旧版本 var llmEnabled: Bool { get { inputLLM.enabled } set { var cfg = inputLLM cfg.enabled = newValue inputLLM = cfg } } var llmBaseURL: String { get { inputLLM.baseURL } set { var cfg = inputLLM cfg.baseURL = newValue inputLLM = cfg } } var llmAPIKey: String { get { inputLLM.apiKey } set { var cfg = inputLLM cfg.apiKey = newValue inputLLM = cfg } } var llmModel: String { get { inputLLM.model } set { var cfg = inputLLM cfg.model = newValue inputLLM = cfg } } var isLLMConfigured: Bool { inputLLM.isConfigured } // MARK: - Control 键模式配置(AI 助手) var assistLLM: LLMConfig { get { LLMConfig( enabled: defaults.bool(forKey: Keys.assistLLMEnabled), baseURL: defaults.string(forKey: Keys.assistLLMBaseURL) ?? "", apiKey: defaults.string(forKey: Keys.assistLLMAPIKey) ?? "", model: defaults.string(forKey: Keys.assistLLMModel) ?? "" ) } set { defaults.set(newValue.enabled, forKey: Keys.assistLLMEnabled) defaults.set(newValue.baseURL, forKey: Keys.assistLLMBaseURL) defaults.set(newValue.apiKey, forKey: Keys.assistLLMAPIKey) defaults.set(newValue.model, forKey: Keys.assistLLMModel) } } func getLLMConfig(for mode: LLMMode) -> LLMConfig { switch mode { case .input: return inputLLM case .assist: return assistLLM } } func setLLMConfig(_ config: LLMConfig, for mode: LLMMode) { switch mode { case .input: inputLLM = config case .assist: assistLLM = config } } }