Architecture

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.

  1. 01
    Overlay

    Sends realtime:stop

    Recording ends; the main process flushes the audio buffer.

  2. 02
    Transcribe

    Whisper returns the raw text

    Two-pass strategy produces the transcript and diagnostics.

  3. 03
    AI

    Polish or transform

    Dictation → polish rewrite; Ask → transform the captured selection using the transcript as the instruction.

  4. 04
    Inject

    Paste into the target app

    Clipboard is swapped, the app reactivated, and ⌘V simulated.

  5. 05
    Persist

    Save history + notify UI

    The record is written and history:updated pushed to the dashboard.

The stop handler orchestrates transcription, the mode-specific AI call, injection, and history — measuring each stage.

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.

Ask user message shape
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.

FieldSourceUsed for
appNameAXApplicationRe-activating the target app before paste.
windowTitlefront windowA hint for polish and Ask prompts.
selectedTextAXSelectedTextThe source text Ask mode transforms.
elementRoleAXRoleFormatting-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.

  1. 01Guard against duplicatesA 500 ms minimum interval and a 5 s same-text dedup window prevent double-pastes and rapid-fire collisions.
  2. 02Save & set clipboardThe current clipboard is stashed, then the result text is written to it.
  3. 03Reactivate & (optionally) collapseThe target app is activated. For Ask's paste-at-cursor, the selection is collapsed with a simulated Right-arrow first.
  4. 04Paste & restore⌘V is simulated; ~500 ms later the original clipboard is restored.

Accessibility required

Simulated paste depends on Accessibility permission. Without it the text is still on your clipboard, but the automatic ⌘V won't fire.