Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
9 changes: 7 additions & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ How to work in this repository, for coding agents and people alike. `CONTRIBUTIN
- `crates/` — the Rust workspace. `voltip-core` is the platform-free application core (commands in,
events out, ports for everything native); the other crates are its adapters: audio, cloud and
on-device recognition, clean-up, injection, platform tables, protocol, crypto, identity, pairing,
transport, relay, the network proxy every connection follows (`voltip-net`), the local speech
service's HTTP layer (`voltip-serve`), and the Tauri bridge.
transport, relay, the network proxy every connection follows (`voltip-net`), what a service said
when it refused a request (`voltip-reply`), the local speech service's HTTP layer
(`voltip-serve`), and the Tauri bridge.
- `apps/desktop`, `apps/mobile` — the Tauri 2 shells (`src-tauri/`) and their React front ends.
- `apps/mobile-rn` — the phone app on React Native (Expo, `docs/mobile-rn.md`): its own Rust shell
(`rust/`, UniFFI), shipped beside the Tauri phone app as `Voltip-RN_<version>_android_arm64.apk`.
Expand Down Expand Up @@ -61,6 +62,10 @@ make help # everything else
(`docs/site/README.md`).
- The mock backend (`@voltip/shared/mock`) and the dev-only pages load under `import.meta.env.DEV`
only; `scripts/check-web-bundle.sh` fails a release bundle that contains them.
- Vendor and brand icons follow LobeHub Icons and its designs (user decision 2026-10-25): copy the
paths of its static SVGs at a pinned commit into `packages/shared/src/provider-marks.ts`, with the
MIT notice; never fetch them at run time. The brand colour tints the tile softly; no solid brand
blocks.

## Secrets and hosts

Expand Down
10 changes: 10 additions & 0 deletions Cargo.lock

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

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ members = [
"crates/voltip-asr",
"crates/voltip-asr-local",
"crates/voltip-refine",
"crates/voltip-reply",
"crates/voltip-cloud",
"crates/voltip-inject",
"crates/voltip-platform",
Expand Down Expand Up @@ -190,6 +191,7 @@ voltip-audio = { path = "crates/voltip-audio" }
voltip-asr = { path = "crates/voltip-asr" }
voltip-asr-local = { path = "crates/voltip-asr-local" }
voltip-refine = { path = "crates/voltip-refine" }
voltip-reply = { path = "crates/voltip-reply" }
voltip-cloud = { path = "crates/voltip-cloud" }
voltip-inject = { path = "crates/voltip-inject" }
voltip-serve = { path = "crates/voltip-serve" }
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ https://github.com/user-attachments/assets/858ba275-ef2b-4864-ad8c-f189f354d6a9
CPU otherwise.
- Live preview while you speak (a streaming Zipformer model), and output as one block, sentence by
sentence, or from the stream directly.
- Clean-up by an LLM (the same providers, plus DeepSeek and a local Ollama), a personal dictionary
- Clean-up by an LLM (the same providers, plus Google AI Studio, DeepSeek, Kimi, Zhipu GLM,
Volcengine Ark, Tencent Hunyuan, Xiaomi MiMo, OpenRouter and a local Ollama), a personal dictionary
that fixes words the recogniser keeps getting wrong, literal and regex replacement rules, and
Simplified / Traditional Chinese normalisation.
- Voice edit: select text, hold `Ctrl+Alt+E`, say "make it more formal" or "translate to English",
Expand Down
2 changes: 2 additions & 0 deletions apps/desktop/src-tauri/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,8 @@ tauri-utils = { version = "=2.9.3", default-features = false }
# already uses).
json-patch = { version = "=4.2.0", default-features = false }
tempfile.workspace = true
# The automatic update's looks hours apart, on a paused clock (src/update.rs).
tokio = { workspace = true, features = ["test-util"] }
voltip-audio = { workspace = true, features = ["test-support"] }
voltip-pairing.workspace = true
# tests/ipc.rs: pairing runs only on a relay (docs/pairing.md 「只走中继」), so the pairing tests
Expand Down
11 changes: 6 additions & 5 deletions apps/desktop/src-tauri/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ use tauri::{Emitter as _, Manager as _, Runtime};
use voltip_core::ui::{GuidePage, ProjectLink, UI_EVENT_NAME, UiEvent, UiState, UpdateStatus};
use voltip_core::{
Activation, AppRef, ConsolePage, CoreConfig, DictionaryDraft, EdgeSource, EngineSettings, ImportMode, Locale, OverlayPlacement, PhoneTalkMode, PresetDraft,
PreviewDraft, ProviderId, RuleDraft, SceneDraft, ServiceKind, TakeKind, ThemeId, VocabularyPreview,
PreviewDraft, ProviderId, RuleDraft, SceneDraft, ServiceKind, SiteId, TakeKind, ThemeId, VocabularyPreview,
};
use voltip_identity::{KeyringSecretStore, SecretStore};
use voltip_tauri_bridge::{Bridge, BridgeError, UiCommand};
Expand Down Expand Up @@ -511,11 +511,12 @@ fn provider_models_refresh(bridge: tauri::State<'_, Bridge>, provider: ProviderI
Ok(bridge.dispatch(UiCommand::ProviderModelsRefresh { provider, kind })?)
}

/// Open the vendor's API-key page, or its page of free quota and usage, in the browser. Only
/// catalogue URLs can be opened: the webview names a provider and a page, never a URL.
/// Open the vendor's API-key page (the given site's, docs/dictation.md §3.2), or its page of free
/// quota and usage, in the browser. Only catalogue URLs can be opened: the webview names a
/// provider, a page and a site, never a URL.
#[tauri::command]
fn provider_console_open(provider: ProviderId, page: Option<ConsolePage>) -> Result<(), String> {
let url = provider.console_page(page.unwrap_or_default())?;
fn provider_console_open(provider: ProviderId, page: Option<ConsolePage>, site: Option<SiteId>) -> Result<(), String> {
let url = provider.console_page(page.unwrap_or_default(), site)?;
tauri_plugin_opener::open_url(url, None::<&str>).map_err(|e| e.to_string())
}

Expand Down
Loading
Loading