AI Post-Processing (LLM Cleanup)
Relevant source files
The following files were used as context for generating this wiki page:
AI Post-Processing is a core feature of mausVoice designed to refine raw transcription data into polished, structured text. The system utilizes Large Language Models (LLMs) to remove filler words (e.g., "um", "uh", "like"), apply proper punctuation and formatting, and transform the text according to specific writing styles or "tones".
This module operates as a secondary step following AI Transcription. While transcription handles the audio-to-text conversion, post-processing ensures the output is professional and contextually appropriate for the target application, such as emails, chat messages, or formal documents.
Sources: llms.txt:51-54, README.md:46-48, apps/desktop/PRODUCT.md:12-14
System Architecture and Data Flow
The post-processing logic is orchestrated in TypeScript within the desktop application. It follows a "TypeScript is the Brain" pattern where logic is managed by Zustand state and Immer, while external AI providers (such as Groq or OpenRouter) handle the heavy lifting of text transformation.
The diagram shows the transformation of raw speech-to-text data into cleaned text through LLM interaction and validation.
Sources: llms.txt:30-35, apps/desktop/test/evals/post-processing-eval.test.ts:38-51, apps/desktop/src/utils/ai.utils.ts:80-90
Key Transformation Components
- Prompt Engineering: The system constructs a "System" and "User" prompt based on the transcript, the selected
ToneConfig, the dictation language, and the user's name. - Structured Output: To ensure reliability, the system expects a JSON response containing the processed result, validated against
PROCESSED_TRANSCRIPTION_SCHEMA. - Resilience Layer: A specialized utility parses and repairs truncated JSON responses if the LLM hits token limits, preventing the loss of the entire result.
Sources: apps/desktop/test/evals/post-processing-eval.test.ts:38-55, apps/desktop/src/utils/ai.utils.ts:60-78
Writing Styles and Tones
Users can configure how the cleanup is applied by selecting different writing styles. These styles guide the LLM's behavior via specific instructions embedded in the prompt.
| Style | Description | Key Transformations |
|---|---|---|
| Default | Balanced cleanup | Removes filler, fixes false starts, adds paragraph breaks. |
| Professional correspondence | Adds greetings, bodies, and sign-offs; formats lists. | |
| Chat | Casual messaging | Short, concise, removes formal headers/signatures. |
| Formal | Official register | Removes contractions/slang, uses polished vocabulary. |
| Verbatim | No processing | Bypasses cleanup for literal transcription. |
| Sources: apps/desktop/test/evals/post-processing-eval.test.ts:100-110, apps/desktop/test/evals/post-processing-eval.test.ts:285-295, apps/desktop/src/i18n/locales/en.json:442-446 |
Prompt Construction Logic
The buildPostProcessingPrompt and buildSystemPostProcessingTonePrompt functions combine user input with predefined tone templates. For example, the Email tone includes a sign-off using the userName provided in settings.
Sources: apps/desktop/test/evals/post-processing-eval.test.ts:38-45, apps/desktop/test/evals/post-processing-eval.test.ts:377-385
Data Parsing and Error Handling
Since LLMs typically return text, mausVoice implements robust extraction and repair logic to handle structured JSON data.
JSON Extraction and Repair
The parsePostProcessingJson function implements a "truncation repair" algorithm. If a JSON string is cut off (causing a syntax error), the system walks backwards from the end of the string, attempting to find a valid boundary (like a comma or quote) to re-close the object and extract whatever survived.
// apps/desktop/src/utils/ai.utils.ts:60-78
export const parsePostProcessingJson = (raw: string): unknown => {
const extracted = extractJsonFromMarkdown(raw);
try {
return JSON.parse(extracted);
} catch {}
let cut = extracted.length;
while (cut > 0) {
const boundary = Math.max(
extracted.lastIndexOf(","), // and others...
);
// ... logic to replace tail with "}" and retry JSON.parse
}
throw new Error("Could not parse or repair LLM JSON output");
};
Sources: apps/desktop/src/utils/ai.utils.ts:60-78
Markdown Handling
The system also includes extractJsonFromMarkdown, which strips ```json code fences if the LLM wraps its response in markdown formatting.
Sources: apps/desktop/src/utils/ai.utils.ts:35-50
Configuration and Providers
Post-processing behavior is highly configurable through the application settings.
| Configuration Field | Description | Source |
|---|---|---|
mode | The LLM provider (e.g., Groq, OpenRouter). | aiPostProcessing.mode |
selectedApiKeyId | The ID of the encrypted API key to use. | aiPostProcessing.selectedApiKeyId |
tone | The active writing style configuration. | ToneConfig |
language | The target language for the final text. | dictationLanguage |
| Sources: apps/desktop/src/utils/ai.utils.ts:98-100, apps/desktop/src/i18n/locales/en.json:45-47, llms.txt:70-75 |
Summary
AI Post-Processing transforms mausVoice from a simple dictation tool into a writing assistant. By layering LLM-based cleanup on top of raw transcription, the system handles self-corrections (e.g., "Monday... no wait, Wednesday"), removes verbal tics, and ensures text is formatted correctly for the user's specific workflow. All operations are performed using encrypted keys stored locally, maintaining the project's focus on privacy and user control.
Sources: README.md:46-52, apps/desktop/PRODUCT.md:12-16, apps/desktop/test/evals/post-processing-eval.test.ts:430-435