refactor(ai): consolidate AI around chat tool-calling; add OpenRouter

- rework chat backend (chat.rs, chat_tools.rs, ai.rs, models, state) around tool calls
- add OpenRouter provider alongside Ollama/Fireworks in settings
- drop inline AiBar, ResultsPanel explain/fix UI and ChartPreview in favour of the chat panel
- add frontend chat tool-registry
This commit is contained in:
2026-05-23 15:01:52 +03:00
parent a485cf7ee3
commit 0cba457fb7
19 changed files with 1244 additions and 1931 deletions

View File

@@ -1,13 +1,26 @@
use serde::{Deserialize, Serialize};
use serde::{Deserialize, Deserializer, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Default)]
#[serde(rename_all = "lowercase")]
pub enum AiProvider {
#[default]
Ollama,
OpenAi,
Anthropic,
Fireworks,
OpenRouter,
}
/// Deserialize a provider string, coercing legacy `openai`/`anthropic` and any
/// unknown value to `Ollama`. Keeps existing config files loadable after the
/// stub providers were removed.
impl<'de> Deserialize<'de> for AiProvider {
fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
let s = String::deserialize(d)?;
Ok(match s.as_str() {
"fireworks" => AiProvider::Fireworks,
"openrouter" => AiProvider::OpenRouter,
_ => AiProvider::Ollama,
})
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
@@ -15,11 +28,9 @@ pub struct AiSettings {
pub provider: AiProvider,
pub ollama_url: String,
#[serde(default)]
pub openai_api_key: Option<String>,
#[serde(default)]
pub anthropic_api_key: Option<String>,
#[serde(default)]
pub fireworks_api_key: Option<String>,
#[serde(default)]
pub openrouter_api_key: Option<String>,
pub model: String,
}
@@ -28,9 +39,8 @@ impl Default for AiSettings {
Self {
provider: AiProvider::Ollama,
ollama_url: "http://localhost:11434".to_string(),
openai_api_key: None,
anthropic_api_key: None,
fireworks_api_key: None,
openrouter_api_key: None,
model: String::new(),
}
}
@@ -71,7 +81,9 @@ pub struct OllamaModel {
}
// ---------------------------------------------------------------------------
// Fireworks (OpenAI-compatible chat-completions)
// OpenAI-compatible chat-completions (Fireworks, OpenRouter)
// These request/response shapes are shared by every OpenAI-compatible provider;
// the `Fireworks*` names are retained for historical reasons.
// ---------------------------------------------------------------------------
#[derive(Debug, Clone, Serialize)]