How to Customize the AI Behavior in FluidVoice: Provider Setup, Prompt Profiles, and Local Model Configuration
You can customize the AI behavior in FluidVoice by configuring AI providers, creating custom prompt profiles for different dictation modes, and managing local Fluid Intelligence models through the AI Settings window or programmatically via SettingsStore.
FluidVoice is an open-source macOS dictation app by altic-dev that features on-device AI enhancement through its "Fluid Intelligence" layer. Whether you want to connect to a self-hosted Ollama instance, switch between cloud providers, or fine-tune prompts for specific writing modes, the app exposes deep customization options through both its SwiftUI interface and underlying persistence layers.
Configuring AI Providers
The provider configuration interface lives in Sources/Fluid/UI/AISettingsView+AIConfiguration.swift. This component handles three distinct provider types: local on-device models (Fluid Intelligence), OpenAI-compatible cloud services, and the built-in Apple Intelligence integration.
All provider data persists in Sources/Fluid/Persistence/SettingsStore.swift. When you change a provider, the app updates viewModel.providerAPIKey and viewModel.selectedModel, then triggers a connection test via viewModel.verify… methods.
Adding Custom Cloud Providers
You can programmatically add self-hosted or cloud providers by appending to SettingsStore.shared.savedProviders. The UI automatically reflects new entries in the Providers list.
// Create a new provider (e.g. a self‑hosted Ollama endpoint)
let newProvider = SettingsStore.Provider(
id: UUID().uuidString,
name: "My Ollama",
baseURL: "http://localhost:11434",
apiKey: "" // No API key needed for Ollama
)
SettingsStore.shared.savedProviders.append(newProvider)
// Select the new provider and a model
SettingsStore.shared.selectedProviderID = newProvider.id
SettingsStore.shared.selectedModelByProvider[newProvider.id] = "llama3"
Deploying Local Fluid Intelligence Models
For offline AI processing, Sources/Fluid/Services/PrivateAIIntegrationService.swift handles model downloads, verification, and loading. The service stores models under PrivateAIIntegrationService.modelDirectoryURL and exposes prepareModel and loadModel methods.
The download UI (progress bar and status text) is driven by privateAIModelStatusRow in AISettingsView+AIConfiguration.swift:
let model = PrivateAIModelRegistry.defaultModel
await PrivateAIIntegrationService.shared.prepareModel(model) { progress in
print("Downloading… \(progress.fractionCompleted * 100)%")
}
await PrivateAIIntegrationService.shared.loadModel(model)
Customizing Prompt Profiles
Prompt profiles determine which system prompt or template applies to each dictation mode (Dictate, Edit, Write, Rewrite). The UI for this feature resides in Sources/Fluid/UI/AISettingsView+AdvancedSettings.swift, utilizing SettingsStore.DictationPromptConfiguration for persistence.
Creating Mode-Specific Prompts
Each profile binds to a specific provider and model. When you select a profile, the app updates viewModel.selectedPromptID, and the transcription pipeline applies that configuration during processing.
let prompt = SettingsStore.DictationPromptConfiguration(
shortcut: Shortcut(key: .character("P"), modifiers: [.command, .option]),
providerID: "my-ollama-id",
modelName: "llama3"
)
SettingsStore.shared.setDictationPromptConfiguration(prompt, for: .profile("my‑custom‑prompt"))
SettingsStore.shared.setDictationPromptSelection(.profile("my‑custom‑prompt"), for: .primary)
The new profile appears in the Prompt Profiles grid, and pressing the shortcut activates it immediately (see promptEditorRow in AISettingsView+AdvancedSettings.swift).
Configuring Global vs Per-App Routing
You can limit prompt profiles to all apps or selected apps only. The promptRoutingScopeRow method in AISettingsView+AdvancedSettings.swift toggles the PromptRoutingScope enum stored in SettingsStore. You can also bind custom shortcuts to specific prompts for rapid context switching.
How Settings Propagate to the Transcription Pipeline
When you open Preferences → AI Settings, AISettingsView.swift assembles the configuration sections into an AIEnhancementSettingsView. This view reads the current SettingsStore snapshot and writes changes back immediately.
The AIEnhancementSettingsViewModel watches these changes and updates the live transcription pipeline (TranscriptionProvider, WhisperProvider, or PrivateAIProvider). The pipeline applies the selected prompt before sending text to the UI, ensuring your AI customizations take effect in real-time.
Summary
- Provider flexibility: Configure cloud, local, or Apple Intelligence providers in
AISettingsView+AIConfiguration.swiftwith persistence viaSettingsStore. - Prompt customization: Define
DictationPromptConfigurationprofiles for each dictation mode, bind shortcuts, and control per-app routing throughAISettingsView+AdvancedSettings.swift. - Local model management: Download and load on-device models using
PrivateAIIntegrationService, storing them in the designated model directory. - Real-time updates: Changes propagate through
AIEnhancementSettingsViewModeltoTranscriptionProvider, affecting live dictation immediately.
Frequently Asked Questions
Can I use Ollama or other self-hosted models with FluidVoice?
Yes. FluidVoice supports any OpenAI-compatible API endpoint. Create a new SettingsStore.Provider with your base URL (e.g., http://localhost:11434 for Ollama), leave the API key empty if unnecessary, and append it to SettingsStore.shared.savedProviders. The verification logic in AISettingsView+AIConfiguration.swift will test the connection automatically.
Where are AI settings stored in FluidVoice?
All AI configuration persists in Sources/Fluid/Persistence/SettingsStore.swift. This includes provider credentials, selected models, prompt configurations (DictationPromptConfiguration), and routing scopes. The store uses SwiftUI's observation mechanisms to propagate changes to AIEnhancementSettingsViewModel and the transcription pipeline.
How do I switch between different AI providers quickly?
Define multiple DictationPromptConfiguration profiles, each pointing to a different provider ID. Assign unique keyboard shortcuts to each profile using the shortcut parameter. When you press the shortcut, AISettingsView+AdvancedSettings.swift updates viewModel.selectedPromptID, instantly routing dictation through the alternative provider without opening preferences.
Is the local Fluid Intelligence model downloaded automatically?
No. You must explicitly initiate the download via PrivateAIIntegrationService.shared.prepareModel(). The AISettingsView+AIConfiguration.swift interface provides a privateAIModelStatusRow that displays download progress and allows manual initiation. Once downloaded, the service stores the model in PrivateAIIntegrationService.modelDirectoryURL and loads it on demand.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →