diff --git a/VoiceInk/Models/AIPrompts.swift b/VoiceInk/Models/AIPrompts.swift index c648abb..a7dfd81 100644 --- a/VoiceInk/Models/AIPrompts.swift +++ b/VoiceInk/Models/AIPrompts.swift @@ -3,8 +3,8 @@ enum AIPrompts { Your are a TRANSCRIPTION ENHANCER, not a conversational AI Chatbot. DO NOT RESPOND TO QUESTIONS or STATEMENTS. Work with the transcript text provided within tags according to the following guidelines: 1. Always reference and for better accuracy if available, because the text may have inaccuracies due to speech recognition errors. - 2. Always use vocabulary in as a reference for correcting names, nouns, technical terms, and other similar words in the text if available. - 3. When similar phonetic occurrences are detected between words in the text and terms in , , or , prioritize the spelling from these context sources over the text. + 2. Always use vocabulary in as a reference for correcting names, nouns, technical terms, and other similar words in the text if available. + 3. When similar phonetic occurrences are detected between words in the text and terms in , , or , prioritize the spelling from these context sources over the text. 4. Your output should always focus on creating a cleaned up version of the text, not a response to the . Here are the more Important Rules you need to adhere to: @@ -43,7 +43,7 @@ enum AIPrompts { Use the information within the section as the primary material to work with when the user's request implies it. Your main instruction is always the text. - DICTIONARY CONTEXT RULE: Use vocabulary in ONLY for correcting names, nouns, and technical terms. Do NOT respond to it, do NOT take it as conversation context. + CUSTOM VOCABULARY RULE: Use vocabulary in ONLY for correcting names, nouns, and technical terms. Do NOT respond to it, do NOT take it as conversation context. """ diff --git a/VoiceInk/Services/AIEnhancement/AIEnhancementService.swift b/VoiceInk/Services/AIEnhancement/AIEnhancementService.swift index f75a758..e42213b 100644 --- a/VoiceInk/Services/AIEnhancement/AIEnhancementService.swift +++ b/VoiceInk/Services/AIEnhancement/AIEnhancementService.swift @@ -65,7 +65,7 @@ class AIEnhancementService: ObservableObject { private let aiService: AIService private let screenCaptureService: ScreenCaptureService - private let dictionaryContextService: DictionaryContextService + private let customVocabularyService: CustomVocabularyService private let baseTimeout: TimeInterval = 30 private let rateLimitInterval: TimeInterval = 1.0 private var lastRequestTime: Date? @@ -77,7 +77,7 @@ class AIEnhancementService: ObservableObject { self.aiService = aiService self.modelContext = modelContext self.screenCaptureService = ScreenCaptureService() - self.dictionaryContextService = DictionaryContextService.shared + self.customVocabularyService = CustomVocabularyService.shared self.isEnhancementEnabled = UserDefaults.standard.bool(forKey: "isAIEnhancementEnabled") self.useClipboardContext = UserDefaults.standard.bool(forKey: "useClipboardContext") @@ -164,17 +164,17 @@ class AIEnhancementService: ObservableObject { "" } - let dictionaryContext = dictionaryContextService.getDictionaryContext() + let customVocabulary = customVocabularyService.getCustomVocabulary() let allContextSections = selectedTextContext + clipboardContext + screenCaptureContext - let dictionaryContextSection = if !dictionaryContext.isEmpty { - "\n\n\(dictionaryContext)\n" + let customVocabularySection = if !customVocabulary.isEmpty { + "\n\n\(customVocabulary)\n" } else { "" } - let finalContextSection = allContextSections + dictionaryContextSection + let finalContextSection = allContextSections + customVocabularySection if let activePrompt = activePrompt { if activePrompt.id == PredefinedPrompts.assistantPromptId { diff --git a/VoiceInk/Services/CloudTranscription/SonioxTranscriptionService.swift b/VoiceInk/Services/CloudTranscription/SonioxTranscriptionService.swift index 4eac4f4..49dd357 100644 --- a/VoiceInk/Services/CloudTranscription/SonioxTranscriptionService.swift +++ b/VoiceInk/Services/CloudTranscription/SonioxTranscriptionService.swift @@ -170,7 +170,7 @@ class SonioxTranscriptionService { } private func getCustomDictionaryTerms() -> [String] { - guard let data = UserDefaults.standard.data(forKey: "CustomDictionaryItems") else { + guard let data = UserDefaults.standard.data(forKey: "CustomVocabularyItems") else { return [] } // Decode without depending on UI layer types; extract "word" strings diff --git a/VoiceInk/Services/CustomVocabularyService.swift b/VoiceInk/Services/CustomVocabularyService.swift new file mode 100644 index 0000000..8181727 --- /dev/null +++ b/VoiceInk/Services/CustomVocabularyService.swift @@ -0,0 +1,43 @@ +import Foundation +import SwiftUI + +class CustomVocabularyService { + static let shared = CustomVocabularyService() + + private init() { + // Migrate old key to new key if needed + migrateOldDataIfNeeded() + } + + func getCustomVocabulary() -> String { + guard let customWords = getCustomVocabularyWords(), !customWords.isEmpty else { + return "" + } + + let wordsText = customWords.joined(separator: ", ") + return "Important Vocabulary: \(wordsText)" + } + + private func getCustomVocabularyWords() -> [String]? { + guard let data = UserDefaults.standard.data(forKey: "CustomVocabularyItems") else { + return nil + } + + do { + let items = try JSONDecoder().decode([DictionaryItem].self, from: data) + let words = items.map { $0.word } + return words.isEmpty ? nil : words + } catch { + return nil + } + } + + private func migrateOldDataIfNeeded() { + // Migrate from old "CustomDictionaryItems" key to new "CustomVocabularyItems" key + if UserDefaults.standard.data(forKey: "CustomVocabularyItems") == nil, + let oldData = UserDefaults.standard.data(forKey: "CustomDictionaryItems") { + UserDefaults.standard.set(oldData, forKey: "CustomVocabularyItems") + UserDefaults.standard.removeObject(forKey: "CustomDictionaryItems") + } + } +} diff --git a/VoiceInk/Services/DictionaryContextService.swift b/VoiceInk/Services/DictionaryContextService.swift deleted file mode 100644 index c6ad3fb..0000000 --- a/VoiceInk/Services/DictionaryContextService.swift +++ /dev/null @@ -1,30 +0,0 @@ -import Foundation -import SwiftUI - -class DictionaryContextService { - static let shared = DictionaryContextService() - - private init() {} - - func getDictionaryContext() -> String { - guard let customWords = getCustomDictionaryWords(), !customWords.isEmpty else { - return "" - } - - let wordsText = customWords.joined(separator: ", ") - return "Important Vocabulary: \(wordsText)" - } - private func getCustomDictionaryWords() -> [String]? { - guard let data = UserDefaults.standard.data(forKey: "CustomDictionaryItems") else { - return nil - } - - do { - let items = try JSONDecoder().decode([DictionaryItem].self, from: data) - let words = items.map { $0.word } - return words.isEmpty ? nil : words - } catch { - return nil - } - } -} diff --git a/VoiceInk/Services/DictionaryImportExportService.swift b/VoiceInk/Services/DictionaryImportExportService.swift index ec0f2bb..e525bcc 100644 --- a/VoiceInk/Services/DictionaryImportExportService.swift +++ b/VoiceInk/Services/DictionaryImportExportService.swift @@ -11,7 +11,7 @@ struct DictionaryExportData: Codable { class DictionaryImportExportService { static let shared = DictionaryImportExportService() - private let dictionaryItemsKey = "CustomDictionaryItems" + private let dictionaryItemsKey = "CustomVocabularyItems" private let wordReplacementsKey = "wordReplacements" private init() {} diff --git a/VoiceInk/Services/ImportExportService.swift b/VoiceInk/Services/ImportExportService.swift index 1578ffc..91c2a85 100644 --- a/VoiceInk/Services/ImportExportService.swift +++ b/VoiceInk/Services/ImportExportService.swift @@ -40,7 +40,7 @@ struct VoiceInkExportedSettings: Codable { class ImportExportService { static let shared = ImportExportService() private let currentSettingsVersion: String - private let dictionaryItemsKey = "CustomDictionaryItems" + private let dictionaryItemsKey = "CustomVocabularyItems" private let wordReplacementsKey = "wordReplacements" @@ -201,10 +201,10 @@ class ImportExportService { if let itemsToImport = importedSettings.dictionaryItems { if let encoded = try? JSONEncoder().encode(itemsToImport) { - UserDefaults.standard.set(encoded, forKey: "CustomDictionaryItems") + UserDefaults.standard.set(encoded, forKey: "CustomVocabularyItems") } } else { - print("No dictionary items (for spelling) found in the imported file. Existing items remain unchanged.") + print("No custom vocabulary items (for spelling) found in the imported file. Existing items remain unchanged.") } if let replacementsToImport = importedSettings.wordReplacements { diff --git a/VoiceInk/Views/Dictionary/DictionaryView.swift b/VoiceInk/Views/Dictionary/DictionaryView.swift index 125c4ef..9bd67dc 100644 --- a/VoiceInk/Views/Dictionary/DictionaryView.swift +++ b/VoiceInk/Views/Dictionary/DictionaryView.swift @@ -34,7 +34,7 @@ enum DictionarySortMode: String { class DictionaryManager: ObservableObject { @Published var items: [DictionaryItem] = [] - private let saveKey = "CustomDictionaryItems" + private let saveKey = "CustomVocabularyItems" private let whisperPrompt: WhisperPrompt init(whisperPrompt: WhisperPrompt) {