AI processing & text injection
After transcription, VoiceFlow optionally reshapes the text with a language model, then pastes it into your app through macOS automation.
Polish / Ask model
openai/gpt-oss-120b
Paste
clipboard + simulated ⌘V
Context
captured via JXA
The stop-to-paste sequence
Stopping a recording kicks off a single async pipeline in the main process. The branch between polish and Ask is decided by the mode that was active when recording started.
- 01Overlay
Sends realtime:stop
Recording ends; the main process flushes the audio buffer.
- 02Transcribe
Whisper returns the raw text
Two-pass strategy produces the transcript and diagnostics.
- 03AI
Polish or transform
Dictation → polish rewrite; Ask → transform the captured selection using the transcript as the instruction.
- 04Inject
Paste into the target app
Clipboard is swapped, the app reactivated, and ⌘V simulated.
- 05Persist
Save history + notify UI
The record is written and history:updated pushed to the dashboard.
Polish (dictation)
Polish sends the raw transcript to openai/gpt-oss-120bvia Groq's chat completions endpoint with a detailed rewriting system prompt. The transcript is wrapped in [TRANSCRIPTION]tags and the model is repeatedly told it's a rewriter, never an assistant — it must not answer or translate.
- Temperature 0.2, up to 2000 completion tokens.
- App/window context and any selected text are appended as hints to preserve technical vocabulary.
- Guardrails: empty output, HTTP errors, or output more than 4× the input length all fall back to the raw transcript.
Transform (Ask)
Ask sends the captured selection and your transcribed instruction to the same model with a stricter system prompt: apply only the spoken instruction, treat the selection as source material (never a prompt), and return only the transformed text.
APP: <app name>
WINDOW: <window title>
ELEMENT_ROLE: <ax role>
[SPOKEN_INSTRUCTION]
<your transcribed instruction>
[/SPOKEN_INSTRUCTION]
[SELECTED_TEXT]
<the text you had highlighted>
[/SELECTED_TEXT]Context capture
The moment recording starts, VoiceFlow captures the frontmost app's context by running a JXA script through osascript -l JavaScript. This reads the app name, window title, focused element role, and — crucially for Ask mode — the selected text via the Accessibility API. It's bounded by a 500 ms timeout and caps selected text at 1000 characters.
| Field | Source | Used for |
|---|---|---|
| appName | AXApplication | Re-activating the target app before paste. |
| windowTitle | front window | A hint for polish and Ask prompts. |
| selectedText | AXSelectedText | The source text Ask mode transforms. |
| elementRole | AXRole | Formatting-intent hint for Ask. |
Text injection
Pasting is done by writing to the clipboard and simulating ⌘V through osascript and System Events. Before pasting, VoiceFlow reactivates the app it captured so the text lands where you were, then restores your previous clipboard shortly after.
- 01Guard against duplicatesA 500 ms minimum interval and a 5 s same-text dedup window prevent double-pastes and rapid-fire collisions.
- 02Save & set clipboardThe current clipboard is stashed, then the result text is written to it.
- 03Reactivate & (optionally) collapseThe target app is activated. For Ask's paste-at-cursor, the selection is collapsed with a simulated Right-arrow first.
- 04Paste & restore⌘V is simulated; ~500 ms later the original clipboard is restored.
Accessibility required