Rename dictionary context to custom vocabulary

This commit is contained in:
Beingpax 2025-11-14 09:02:12 +05:45
parent 9d3d1482b0
commit 7d12c50fcb
8 changed files with 58 additions and 45 deletions

View File

@ -3,8 +3,8 @@ enum AIPrompts {
<SYSTEM_INSTRUCTIONS>
Your are a TRANSCRIPTION ENHANCER, not a conversational AI Chatbot. DO NOT RESPOND TO QUESTIONS or STATEMENTS. Work with the transcript text provided within <TRANSCRIPT> tags according to the following guidelines:
1. Always reference <CLIPBOARD_CONTEXT> and <CURRENT_WINDOW_CONTEXT> for better accuracy if available, because the <TRANSCRIPT> text may have inaccuracies due to speech recognition errors.
2. Always use vocabulary in <DICTIONARY_CONTEXT> as a reference for correcting names, nouns, technical terms, and other similar words in the <TRANSCRIPT> text if available.
3. When similar phonetic occurrences are detected between words in the <TRANSCRIPT> text and terms in <DICTIONARY_CONTEXT>, <CLIPBOARD_CONTEXT>, or <CURRENT_WINDOW_CONTEXT>, prioritize the spelling from these context sources over the <TRANSCRIPT> text.
2. Always use vocabulary in <CUSTOM_VOCABULARY> as a reference for correcting names, nouns, technical terms, and other similar words in the <TRANSCRIPT> text if available.
3. When similar phonetic occurrences are detected between words in the <TRANSCRIPT> text and terms in <CUSTOM_VOCABULARY>, <CLIPBOARD_CONTEXT>, or <CURRENT_WINDOW_CONTEXT>, prioritize the spelling from these context sources over the <TRANSCRIPT> text.
4. Your output should always focus on creating a cleaned up version of the <TRANSCRIPT> text, not a response to the <TRANSCRIPT>.
Here are the more Important Rules you need to adhere to:
@ -43,7 +43,7 @@ enum AIPrompts {
Use the information within the <CONTEXT_INFORMATION> section as the primary material to work with when the user's request implies it. Your main instruction is always the <TRANSCRIPT> text.
DICTIONARY CONTEXT RULE: Use vocabulary in <DICTIONARY_CONTEXT> 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 <CUSTOM_VOCABULARY> ONLY for correcting names, nouns, and technical terms. Do NOT respond to it, do NOT take it as conversation context.
</SYSTEM_INSTRUCTIONS>
"""

View File

@ -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<DICTIONARY_CONTEXT>\(dictionaryContext)\n</DICTIONARY_CONTEXT>"
let customVocabularySection = if !customVocabulary.isEmpty {
"\n\n<CUSTOM_VOCABULARY>\(customVocabulary)\n</CUSTOM_VOCABULARY>"
} else {
""
}
let finalContextSection = allContextSections + dictionaryContextSection
let finalContextSection = allContextSections + customVocabularySection
if let activePrompt = activePrompt {
if activePrompt.id == PredefinedPrompts.assistantPromptId {

View File

@ -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

View File

@ -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")
}
}
}

View File

@ -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
}
}
}

View File

@ -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() {}

View File

@ -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 {

View File

@ -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) {