| name | maintain-assistant-providers |
| description | Maintain Voice Layer's local llama-server, experimental ChatGPT OAuth/Responses, and OpenRouter BYOK assistant routes. Use when changing provider selection, credentials, model policy, privacy, streaming, tools, cancellation, or provider teardown. |
Maintain assistant providers
Boundary
Rust owns provider execution and policy. The WebView selects typed, curated
values but never supplies endpoints, arbitrary provider JSON, or runtime
options. Keep Local as the default. ChatGPT is an explicit experimental
subscription route; OpenRouter is an explicit BYOK route with a closed model
allowlist and one typed key-save credential boundary.
Source map
src/settings.ts: closed provider/model choices, persistence, migration, and
route snapshots; src/assistant-provider-settings.ts: assistant options,
ChatGPT account controls, OpenRouter key controls, and provider transitions;
src/app-lifecycle-signals.ts: typed selection signals, ChatGPT follow-up
order, and subscription cleanup; src/main.ts: markup and composition.
src/llm.ts, src/assistant-ipc.ts, src/assistant-coordinator.ts, and
src/debug-page.ts (connection readout): typed requests, provider-aware
status copy, correlation, and lifetime.
src-tauri/src/llm/mod.rs: local Rig/llama-server policy;
src-tauri/src/llm/provider_execution.rs: shared admission, command lifecycle,
terminal mapping, and cancellation plus external-provider visible streaming
and tool-loop execution. The local route retains its distinct text-protocol
loop in llm/mod.rs.
src-tauri/src/chatgpt/: native PKCE OAuth, app-owned credential storage,
fixed Luna model/effort policy, Responses SSE, bounded tools, and cancellation.
src-tauri/src/openrouter/: BYOK credential store, embedded allowlist
validation, OpenAI-compatible streaming, cancellation, and connection test.
src-tauri/src/live/: provider-aware Live preflight and lifecycle.
Invariants
- Never start, stop, or configure the user's
llama-server; validate its
selected alias at use time.
- ChatGPT never accepts API keys or reads an external tool's account state.
Keep credentials in Rust under Voice Layer app data.
- ChatGPT supports only
gpt-5.6-luna with low, medium, or high effort;
default to low and reject unsupported values.
- OpenRouter accepts a key only through its typed save command, validates model
IDs against the embedded allowlist, and returns only redacted credential
status. It sends no reasoning parameters in v1.
- Send visible conversation text externally only for the explicitly selected
ChatGPT or OpenRouter reply. Keep audio, local inference configuration, stored
credentials, and raw provider payloads outside the WebView.
- Preserve request correlation and settle affected generation and Live work
before switching providers, forgetting ChatGPT, or removing an OpenRouter key.
- Emit provider/model selection changes only through
appLifecycleSignals so
thinking, status chrome, Debug, and provider-specific follow-ups share one
typed exactly-once notification and cleanup contract.
- Keep external native tool calling off by default and bounded when enabled.
Validation
Run focused provider, settings, coordinator, and Live tests, then just test,
just check, and git diff --check as needed. Real OAuth, a real OpenRouter
key, and signed-in generation remain opt-in packaged acceptance checks.