Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions .claude/settings.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
{
"enabledPlugins": {
"rust-lsp@claude-plugins-official": true
},
"permissions": {
"allow": [
"Bash(bun run:*)",
Expand All @@ -12,5 +9,9 @@
"Bash(git log:*)",
"Bash(git branch:*)"
]
},
"enabledPlugins": {
"rust-lsp@claude-plugins-official": true,
"rust-analyzer-lsp@claude-plugins-official": true
}
}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ dist-ssr
.ai_agents/session_context/
.ai_agents/
.ai_agents/coderabbit_output.txt
/.pi-subagents/
target/

# Environment
Expand Down
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ futures-util = "0.3"
sha2 = "0.10"
arc-swap = "1"

# Text post-processing
regex = "1"

# GPUI and UI dependencies
gpui = { git = "https://github.com/BumpyClock/gpui", rev = "4332ea7deae4838c12bad6ea64292ca22a33cf98", features = [
"font-kit",
Expand Down
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ A native cross-platform voice assistant built with Rust and GPUI.
## Architecture

This is a Rust workspace. Crates (see `[workspace].members` in `Cargo.toml` for the authoritative list):

- `crates/shared` - Shared utilities and types
- `crates/core` - Core backend services (audio, transcription, and platform permission/runtime bridges)
- `crates/app` - GPUI-based native UI application
Expand Down Expand Up @@ -50,6 +51,14 @@ KERNEL=="event*", SUBSYSTEM=="input", GROUP="input", MODE="0660"

Then add your user to the `input` group.

## Transcript enhancement

Settings include deterministic custom dictionary replacements, soft vocabulary boosting,
and optional AI enhancement via OpenAI-compatible providers (OpenAI, Ollama,
LM Studio). OpenAI reads API keys from an env var (default `OPENAI_API_KEY`);
local model hosting inside Ansible is deferred. See
`docs/design/ai-enhancement-dictionary-vocabulary.md`.

## Supported Models

| Model | Size | Notes |
Expand Down
30 changes: 22 additions & 8 deletions crates/app/src/ui/settings/sections/models/sidecar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ pub fn render_whisper_sidecar_card(
let muted_fg = cx.theme().muted_foreground;
let app_state = cx.global::<AppState>().clone();
let progress = status.progress.clamp(0.0, 100.0);
let needs_update = status.needs_update;
let override_configured = status.override_configured;

div()
.p_3()
Expand Down Expand Up @@ -53,20 +55,30 @@ pub fn render_whisper_sidecar_card(
.text_color(muted_fg),
)
.child(
Label::new("Install to show Whisper model cards.")
.text_xs()
.text_color(muted_fg),
Label::new(if override_configured {
"Managed install is unavailable while the sidecar path override is set."
} else if needs_update {
"Update the sidecar to restore Whisper model support."
} else {
"Install to show Whisper model cards."
})
.text_xs()
.text_color(muted_fg),
),
)
.child(
Button::new("install-whisper-sidecar")
.label(if status.installing {
"Installing…"
} else if override_configured {
"Managed install unavailable"
} else if needs_update {
"Update Whisper"
} else {
"Install Whisper"
})
.outline()
.disabled(status.installing)
.disabled(status.installing || override_configured)
.on_click(move |_event, _window, _cx| {
let runtime = app_state.runtime().clone();
let controller = app_state.controller().clone();
Expand Down Expand Up @@ -96,10 +108,12 @@ pub fn render_whisper_sidecar_card(
})
.when(status.last_error.is_some(), |this| {
let message = status.last_error.unwrap_or_default();
this.child(Alert::error(
"whisper-sidecar-error",
format!("Install failed: {message}"),
))
let message = if override_configured {
message
} else {
format!("Install failed: {message}")
};
this.child(Alert::error("whisper-sidecar-error", message))
})
.into_any_element()
}
6 changes: 6 additions & 0 deletions crates/app/src/ui/settings/sections/transcription.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ use ansible_shared::settings::SttAccelerator;
use gpui::*;
use gpui_component::setting::NumberFieldOptions;
use gpui_component::setting::{SettingControl, SettingGroup, SettingItem, SettingPage};
use transcription_enhancement::{create_ai_enhancement_group, create_dictionary_group};

#[path = "transcription_enhancement.rs"]
mod transcription_enhancement;

static STT_ACCELERATOR_OPTIONS: LazyLock<Vec<(SharedString, SharedString)>> = LazyLock::new(|| {
SttAccelerator::available()
Expand Down Expand Up @@ -115,6 +119,8 @@ pub fn create_transcription_section(state: &Entity<SettingsState>) -> SettingPag
),
),
)
.group(create_ai_enhancement_group(state))
.group(create_dictionary_group(state))
.group(
SettingGroup::new()
.title("Minimum Utterance")
Expand Down
Loading