Commit 0c45a46
committed
AI: Use genai crate to handle multi-provider quirks
Replace the hand-rolled OpenAI-compatible chat-completions client with
`genai 0.6.0-beta.19`. Fixes two production failures observed in BYOK
mode: (1) GPT-5 / o-series chat models 400ing on `temperature`, and
(2) `gpt-*-pro` / `*-codex` models 404ing on `/v1/chat/completions`
because they only respond on `/v1/responses`.
`genai` auto-routes Responses-only models, normalizes the wire format
across OpenAI / Anthropic / Gemini / xAI / Groq / DeepSeek / OpenRouter
/ Ollama, and exposes a unified `ReasoningEffort` knob. We layer one
small heuristic (`is_openai_chat_reasoning_model`) on top to also
strip `temperature` for `o1*`/`o3*`/`o4*`/`chatgpt-*` chat-completion
models, where `genai` doesn't auto-route.
- `client.rs` rewritten around `genai::Client`. `AiBackend` is now a
struct bundling a long-lived `Client` with the model name, built via
`AiBackend::local(port)` or `AiBackend::remote(key, url, model)`.
- `manager.rs`: rename internal `openai_*` config fields to `cloud_*`,
rename `get_openai_config` to `get_cloud_config`, add
`BackendResolution` + `resolve_backend` so callers don't reimplement
provider routing.
- `suggestions.rs` and `commands/search.rs` use `resolve_backend()`;
identical inline match logic deleted.
- Provider value `openai-compatible` → `cloud`. Persisted settings
`ai.openaiApiKey`/`BaseUrl`/`Model` and their legacy migration
removed (cloud config has lived in `ai.cloudProviderConfigs` since
the per-provider redesign; the legacy keys were dead weight).
- Tauri command `configure_ai` parameter renames mirror the above.
- UI label "Cloud / API" → "Cloud AI"; tooltip updated to mention
Anthropic, Gemini, xAI, Groq, DeepSeek, OpenRouter natively. Fix
Anthropic preset description (was wrongly claiming OpenAI-compat).
- Map `genai::Error` to `AiError` by pattern-matching the
`WebAdapterCall`/`WebModelCall` + `webc::Error` tree, not by string
scraping the `Display` output.
- Better error message when reasoning models eat `max_tokens` for
thinking and emit no output text.
- Fix latent bug discovered while writing tests: `genai`'s
`Url::join("chat/completions")` strips the last path segment unless
`base_url` ends with `/`. Without the fix, `https://api.openai.com/v1`
silently becomes `https://api.openai.com/chat/completions` (404).
Tests:
- 8 wiremock integration tests covering request shape per adapter
(chat completions vs Responses), parsing, error mapping.
- 3 `#[ignore]`-gated real-OpenAI smoke tests (`gpt-4o-mini`,
`gpt-5-mini`, `o3-mini`). All three pass against `api.openai.com`.
- Existing `parse_suggestions` unit tests untouched.
Updates `apps/desktop/src-tauri/src/ai/CLAUDE.md` with new
architecture, decisions, and gotchas (trailing-slash quirk;
reasoning models consuming `max_tokens` budget; per-adapter routing
rules; defense-in-depth reasoning-model heuristic).1 parent c9fad17 commit 0c45a46
18 files changed
Lines changed: 1032 additions & 376 deletions
File tree
- apps/desktop
- src-tauri
- src
- ai
- commands
- src/lib
- ai
- settings
- components
- sections
- tauri-commands
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
100 | 100 | | |
101 | 101 | | |
102 | 102 | | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
103 | 117 | | |
104 | 118 | | |
105 | 119 | | |
| |||
183 | 197 | | |
184 | 198 | | |
185 | 199 | | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
186 | 204 | | |
187 | 205 | | |
188 | 206 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | | - | |
| 3 | + | |
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
7 | | - | |
| 7 | + | |
8 | 8 | | |
9 | 9 | | |
10 | 10 | | |
11 | 11 | | |
12 | 12 | | |
13 | 13 | | |
14 | 14 | | |
15 | | - | |
| 15 | + | |
16 | 16 | | |
17 | 17 | | |
18 | 18 | | |
19 | | - | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
20 | 22 | | |
21 | 23 | | |
22 | 24 | | |
| |||
42 | 44 | | |
43 | 45 | | |
44 | 46 | | |
45 | | - | |
| 47 | + | |
46 | 48 | | |
47 | | - | |
48 | | - | |
49 | | - | |
50 | | - | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
51 | 56 | | |
52 | 57 | | |
53 | 58 | | |
| |||
108 | 113 | | |
109 | 114 | | |
110 | 115 | | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
111 | 119 | | |
112 | 120 | | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
113 | 127 | | |
114 | 128 | | |
115 | 129 | | |
| |||
127 | 141 | | |
128 | 142 | | |
129 | 143 | | |
130 | | - | |
| 144 | + | |
| 145 | + | |
131 | 146 | | |
0 commit comments