# How to Customize the AI Behavior in FluidVoice: Provider Setup, Prompt Profiles, and Local Model Configuration

> Customize AI behavior in FluidVoice. Learn to configure AI providers, prompt profiles, and local models for tailored dictation. Master AI settings and programmatic control.

- Repository: [ALTIC/FluidVoice](https://github.com/altic-dev/FluidVoice)
- Tags: how-to-guide
- Published: 2026-06-30

---

**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`](https://github.com/altic-dev/FluidVoice/blob/main/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.

```swift
// 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`](https://github.com/altic-dev/FluidVoice/blob/main/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`:

```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.

```swift
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`](https://github.com/altic-dev/FluidVoice/blob/main/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.swift` with persistence via `SettingsStore`.
- **Prompt customization**: Define `DictationPromptConfiguration` profiles for each dictation mode, bind shortcuts, and control per-app routing through `AISettingsView+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 `AIEnhancementSettingsViewModel` to `TranscriptionProvider`, 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`](https://github.com/altic-dev/FluidVoice/blob/main/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.