FluidVoice Configuration Options: Complete Guide to SettingsStore and Customization

FluidVoice stores all user-adjustable settings in the SettingsStore singleton, which serializes complex objects as JSON in UserDefaults while securing sensitive data like API keys in the macOS Keychain.

FluidVoice is an open-source macOS dictation application that provides extensive customization through its centralized configuration system. All settings are managed through the SettingsStore class located in Sources/Fluid/Persistence/SettingsStore.swift, offering programmatic access to AI processing parameters, prompt profiles, and system integration preferences. Understanding these FluidVoice configuration options allows you to tailor dictation shortcuts, custom LLM providers, and per-application behaviors to specific workflow requirements.

Core Configuration Architecture

The SettingsStore Singleton

The heart of FluidVoice's configuration system is the SettingsStore singleton, defined in Sources/Fluid/Persistence/SettingsStore.swift. This class acts as a thin wrapper around UserDefaults and Keychain, exposing type-safe properties for all user-adjustable values. The store handles JSON encoding for complex objects like prompt profiles and provider definitions, while delegating sensitive credentials to the KeychainService.

Persistence Mechanisms

FluidVoice uses a tiered persistence strategy:

  • Simple scalars (booleans, strings) are saved directly in UserDefaults via the defaults field
  • Complex collections (arrays of profiles, bindings, configurations) are JSON-encoded using JSONEncoder/JSONDecoder on each read/write operation
  • Sensitive data such as provider API keys are stored securely in the macOS Keychain via KeychainService.shared (defined in Sources/Fluid/Services/KeychainService.swift)

Available Configuration Categories

Dictation Modes and Prompt Profiles

FluidVoice supports distinct operational modes controlled by the PromptMode enum (Sources/Fluid/Persistence/SettingsStore.swift#L43-L58):

  • dictate – Standard dictation enhancement mode
  • edit – Text editing and rewriting mode (legacy values write and rewrite are also supported for backwards compatibility)

Prompt profiles allow users to define named system prompts that can be selected per-app or globally. These are stored as DictationPromptProfile structs (SettingsStore.swift#L19-L27) containing:

  • id – Unique identifier
  • name – Display name
  • prompt – The actual system prompt text
  • mode – Associated PromptMode
  • includeContext – Boolean flag for context inclusion
  • timestamps – Creation/modification metadata

Shortcut Configurations and AI Providers

The application supports two dictation shortcut slots (DictationShortcutSlot enum: primary and secondary) defined at SettingsStore.swift#L96-L102. Each slot is configured via DictationPromptConfiguration (SettingsStore.swift#L28-L33), which specifies:

  • shortcut – Optional HotkeyShortcut (key code and modifier flags)
  • providerID – Identifier for the AI provider
  • modelName – Specific model to use for that shortcut

For custom LLM integration, SavedProvider structs (SettingsStore.swift#L234-L242) store:

  • Provider name and unique ID
  • Base URL for API endpoints
  • API key (stored in Keychain)
  • Available model list

App-Specific Prompt Bindings

AppPromptBinding structs (SettingsStore.swift#L68-L77) enable per-application customization by overriding prompts for specific bundle IDs. Each binding contains:

  • mode – The prompt mode to apply
  • bundleID – Target application identifier
  • appName – Human-readable application name
  • profileID – Optional reference to a custom DictationPromptProfile

AI Processing and Reasoning Controls

Global AI behavior is controlled by enableAIProcessing (SettingsStore.swift#L250-L253), a boolean that toggles the entire AI pipeline including dictation enhancement and reasoning.

For advanced model control, ModelReasoningConfig (SettingsStore.swift#L191-L210) stores per-model "thinking" parameters such as reasoning_effort and enable_thinking, allowing fine-tuned control over model behavior during transcription processing.

System Integration Settings

FluidVoice integrates deeply with macOS through several system-level configurations:

  • launchAtStartupEnabled – Controls login item registration (SettingsStore.swift#L20-L24)
  • launchAtStartupErrorMessage and launchAtStartupStatusMessage – Status reporting for startup registration
  • showMainWindowAtLoginLaunch – Boolean determining whether the main window appears automatically when FluidVoice launches at login (SettingsStore.swift#L158-L167)

Additionally, users can override built-in default prompts using:

  • defaultDictationPromptOverride – Replaces the standard dictation system prompt
  • defaultEditPromptOverride – Replaces the standard edit/rewrite system prompt

Accessing and Modifying Configuration Programmatically

All configuration values are accessible through SettingsStore.shared. Below are practical examples for common customization tasks.

Check AI Processing Status

import Fluid

let aiEnabled = SettingsStore.shared.enableAIProcessing   // Returns true or false

Configure a Dictation Shortcut

import Fluid

// Create a new configuration with Command+1 shortcut using OpenAI GPT-4o
let newConfig = SettingsStore.DictationPromptConfiguration(
    shortcut: HotkeyShortcut(keyCode: 0x31, modifiers: [.command]),
    providerID: "openai",
    modelName: "gpt-4o"
)

// Apply to the primary shortcut slot
SettingsStore.shared.setDictationPromptConfiguration(newConfig, for: .primary)

Create a Custom Prompt Profile

import Fluid

let profile = SettingsStore.DictationPromptProfile(
    name: "MyBusiness",
    prompt: SettingsStore.defaultPromptBodyText(for: .dictate) + "\n\nYou are a business‑style transcriber.",
    mode: .dictate,
    includeContext: true
)

// Append to stored profiles
var profiles = SettingsStore.shared.dictationPromptProfiles
profiles.append(profile)
SettingsStore.shared.dictationPromptProfiles = profiles

Override Default System Prompts

import Fluid

SettingsStore.shared.defaultDictationPromptOverride = """
You are a concise dictation cleaner. Remove filler words and keep only the final sentence.
"""

Add a Custom AI Provider

import Fluid

let provider = SettingsStore.SavedProvider(
    name: "Local LLaMA",
    baseURL: "http://127.0.0.1:8080/v1",
    apiKey: ""          // Empty for local servers without authentication
)

var providers = SettingsStore.shared.savedProviders
providers.append(provider)
SettingsStore.shared.savedProviders = providers

Configure Startup Behavior

import Fluid

SettingsStore.shared.launchAtStartupEnabled = true
SettingsStore.shared.showMainWindowAtLoginLaunch = false

UI Integration Points

The configuration system powers several key UI components:

Summary

  • FluidVoice configuration options are centralized in the SettingsStore singleton (SettingsStore.swift), which provides type-safe access to all settings.
  • Complex objects like DictationPromptProfile, SavedProvider, and AppPromptBinding are JSON-encoded for UserDefaults storage, while API keys are secured in the macOS Keychain.
  • Configuration categories include dictation modes (dictate vs. edit), shortcut slot configurations, per-app prompt bindings, AI reasoning parameters, and system integration settings.
  • All values are accessible programmatically via SettingsStore.shared, allowing automation and extension of the application's behavior.
  • UI components in AISettingsView, RecordingView, and NotchContentViews consume these settings to provide the user-facing configuration interface.

Frequently Asked Questions

How do I add a custom AI provider to FluidVoice?

Create a SavedProvider struct with your provider's name, base URL, and API key, then append it to SettingsStore.shared.savedProviders. The provider becomes available immediately in the AI provider selection dropdowns throughout the application. API keys are automatically stored in the macOS Keychain via KeychainService.

Where are FluidVoice settings stored on macOS?

Simple settings reside in UserDefaults under the application's bundle identifier, while complex objects are JSON-serialized before storage. Sensitive information such as LLM API keys are stored in the macOS Keychain. You can inspect raw values using the defaults command line tool, though complex objects will appear as JSON strings.

Can I set different prompts for different applications?

Yes. FluidVoice supports app-specific prompt bindings through the AppPromptBinding struct. You can create bindings that associate specific bundle IDs with custom DictationPromptProfile objects or default prompt overrides. The system automatically resolves the appropriate prompt when you activate dictation in different applications.

How do I disable AI processing entirely?

Set SettingsStore.shared.enableAIProcessing = false. This boolean flag (SettingsStore.swift#L250-L253) disables the entire AI enhancement pipeline, causing FluidVoice to function as a standard dictation tool without LLM post-processing. This is useful for offline usage or when you require raw transcription output without modification.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →