diff --git a/VoiceInk/Models/AIPrompts.swift b/VoiceInk/Models/AIPrompts.swift
index 24505a8..c4e4533 100644
--- a/VoiceInk/Models/AIPrompts.swift
+++ b/VoiceInk/Models/AIPrompts.swift
@@ -13,14 +13,16 @@ enum AIPrompts {
static let assistantMode = """
- Give a helpful and informative response to the user's query. Use information from the section if directly related to the user's query.
- Remember to:
- 1. ALWAYS provide ONLY the direct answer to the user's query.
- 2. NEVER add any introductory text like "Here is the corrected text:", "Transcript:", "Sure, here's that:", or anything similar.
- 3. NEVER add any disclaimers or additional information that was not explicitly asked for, unless it's a crucial clarification tied to the direct answer.
- 4. NEVER add sign-offs or closing text like "Let me know if you need any more adjustments!", or anything like that.
- 5. Your response must be directly address the user's request.
- 6. Maintain a friendly, casual tone.
+ You are a powerful AI assistant. Your primary goal is to provide a direct, clean, and unadorned response to the user's request from the .
+
+ YOUR RESPONSE MUST BE PURE. This means:
+ - NO commentary.
+ - NO introductory phrases like "Here is the result:" or "Sure, here's the text:".
+ - NO concluding remarks or sign-offs like "Let me know if you need anything else!".
+ - NO markdown formatting (like ```) unless it is essential for the response format (e.g., code).
+ - ONLY provide the direct answer or the modified text that was requested.
+
+ 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 user's .
"""
diff --git a/VoiceInk/Services/AIEnhancementService.swift b/VoiceInk/Services/AIEnhancementService.swift
index 34048a7..14a4a8d 100644
--- a/VoiceInk/Services/AIEnhancementService.swift
+++ b/VoiceInk/Services/AIEnhancementService.swift
@@ -126,6 +126,17 @@ class AIEnhancementService: ObservableObject {
}
private func getSystemMessage(for mode: EnhancementPrompt) -> String {
+ let selectedText = SelectedTextService.fetchSelectedText()
+
+ if let activePrompt = activePrompt,
+ activePrompt.id == PredefinedPrompts.assistantPromptId,
+ let selectedText = selectedText, !selectedText.isEmpty {
+
+ let selectedTextContext = "\n\nSelected Text: \(selectedText)"
+ let contextSection = "\n\n\(AIPrompts.contextInstructions)\n\n\(selectedTextContext)\n"
+ return activePrompt.promptText + contextSection
+ }
+
let clipboardContext = if useClipboardContext,
let clipboardText = NSPasteboard.general.string(forType: .string),
!clipboardText.isEmpty {
diff --git a/VoiceInk/Services/SelectedTextService.swift b/VoiceInk/Services/SelectedTextService.swift
new file mode 100644
index 0000000..97a66c3
--- /dev/null
+++ b/VoiceInk/Services/SelectedTextService.swift
@@ -0,0 +1,51 @@
+import Foundation
+import AppKit
+
+class SelectedTextService {
+ static func fetchSelectedText() -> String? {
+ guard let frontmostApp = NSWorkspace.shared.frontmostApplication,
+ frontmostApp.bundleIdentifier != "com.prakashjoshipax.VoiceInk" else {
+ return nil
+ }
+
+ let systemWideElement = AXUIElementCreateSystemWide()
+ var focusedElement: CFTypeRef?
+
+ guard AXUIElementCopyAttributeValue(systemWideElement, kAXFocusedUIElementAttribute as CFString, &focusedElement) == .success,
+ let element = focusedElement else {
+ return nil
+ }
+
+ return findSelectedText(in: element as! AXUIElement)
+ }
+
+ private static func findSelectedText(in element: AXUIElement) -> String? {
+ var selectedTextValue: CFTypeRef?
+ if AXUIElementCopyAttributeValue(element, kAXSelectedTextAttribute as CFString, &selectedTextValue) == .success {
+ if let selectedText = selectedTextValue as? String, !selectedText.isEmpty {
+ return selectedText
+ }
+ }
+
+ // Fallback for apps that use kAXValueAttribute for selected text (like some Electron apps)
+ var value: CFTypeRef?
+ if AXUIElementCopyAttributeValue(element, kAXValueAttribute as CFString, &value) == .success {
+ if let selectedText = value as? String, !selectedText.isEmpty {
+ return selectedText
+ }
+ }
+
+ var children: CFTypeRef?
+ if AXUIElementCopyAttributeValue(element, kAXChildrenAttribute as CFString, &children) == .success {
+ if let axChildren = children as? [AXUIElement] {
+ for child in axChildren {
+ if let foundText = findSelectedText(in: child) {
+ return foundText
+ }
+ }
+ }
+ }
+
+ return nil
+ }
+}
\ No newline at end of file