chore: init main branch
This commit is contained in:
commit
549c8b5b13
231 files changed
+27286
No files matched your search
@@ -0,0 +1,235 @@
|
||||
use indexmap::IndexMap;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::Value;
|
||||
|
||||
/// Target agent whose provider/model config is being edited.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum Agent {
|
||||
KimiCode,
|
||||
Pi,
|
||||
}
|
||||
|
||||
impl Agent {
|
||||
pub fn as_str(&self) -> &'static str {
|
||||
match self {
|
||||
Agent::KimiCode => "kimi_code",
|
||||
Agent::Pi => "pi",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum ProviderType {
|
||||
Anthropic,
|
||||
Openai,
|
||||
#[serde(rename = "openai_responses")]
|
||||
OpenaiResponses,
|
||||
#[serde(rename = "google-genai")]
|
||||
GoogleGenai,
|
||||
Vertexai,
|
||||
/// Kept for compatibility; mapped to OpenAI-compatible in Pi.
|
||||
Kimi,
|
||||
}
|
||||
|
||||
const fn default_true() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
impl ProviderType {
|
||||
pub fn as_str(&self) -> &'static str {
|
||||
match self {
|
||||
ProviderType::Anthropic => "anthropic",
|
||||
ProviderType::Openai => "openai",
|
||||
ProviderType::OpenaiResponses => "openai_responses",
|
||||
ProviderType::GoogleGenai => "google-genai",
|
||||
ProviderType::Vertexai => "vertexai",
|
||||
ProviderType::Kimi => "kimi",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn default_base_url(&self) -> Option<&'static str> {
|
||||
match self {
|
||||
ProviderType::Openai | ProviderType::OpenaiResponses | ProviderType::Kimi => {
|
||||
Some("https://api.openai.com/v1")
|
||||
}
|
||||
ProviderType::GoogleGenai => Some("https://generativelanguage.googleapis.com"),
|
||||
ProviderType::Anthropic | ProviderType::Vertexai => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_openai_compatible(&self) -> bool {
|
||||
matches!(
|
||||
self,
|
||||
ProviderType::Kimi | ProviderType::Openai | ProviderType::OpenaiResponses
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize)]
|
||||
pub struct Provider {
|
||||
pub name: String,
|
||||
pub provider_type: ProviderType,
|
||||
pub base_url: Option<String>,
|
||||
pub api_key: Option<String>,
|
||||
#[serde(default)]
|
||||
pub env: IndexMap<String, String>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub note: Option<String>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub official_url: Option<String>,
|
||||
#[serde(default)]
|
||||
pub managed: bool,
|
||||
#[serde(default = "default_true")]
|
||||
pub enabled: bool,
|
||||
#[serde(default)]
|
||||
pub active: bool,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub icon: Option<String>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub icon_color: Option<String>,
|
||||
#[serde(default, skip_serializing_if = "Value::is_null")]
|
||||
pub raw_other: Value,
|
||||
/// Billing/usage query kinds for this provider (e.g. "balance:deepseek",
|
||||
/// "plan:kimi_coding"). Persisted in the SQLite settings table under
|
||||
/// `usage_kinds:<provider_name>`, NOT in the agent's config.toml — both
|
||||
/// export paths (kimi_code_io manual TOML, pi_io PiProvider struct) are
|
||||
/// explicit and never serialize this field, while the IPC payload to the
|
||||
/// frontend does carry it.
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub usage_kinds: Option<Vec<String>>,
|
||||
}
|
||||
|
||||
impl PartialEq for Provider {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.name == other.name
|
||||
&& self.provider_type == other.provider_type
|
||||
&& self.base_url == other.base_url
|
||||
&& self.api_key == other.api_key
|
||||
&& self.env == other.env
|
||||
&& self.note == other.note
|
||||
&& self.official_url == other.official_url
|
||||
&& self.managed == other.managed
|
||||
&& self.enabled == other.enabled
|
||||
&& self.active == other.active
|
||||
&& self.icon == other.icon
|
||||
&& self.icon_color == other.icon_color
|
||||
&& self.raw_other == other.raw_other
|
||||
&& self.usage_kinds == other.usage_kinds
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for Provider {}
|
||||
|
||||
impl std::fmt::Debug for Provider {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_struct("Provider")
|
||||
.field("name", &self.name)
|
||||
.field("provider_type", &self.provider_type)
|
||||
.field("base_url", &self.base_url)
|
||||
.field("api_key", &"<redacted>")
|
||||
.field("env", &"<redacted>")
|
||||
.field("managed", &self.managed)
|
||||
.field("enabled", &self.enabled)
|
||||
.field("active", &self.active)
|
||||
.field("icon", &self.icon)
|
||||
.field("icon_color", &self.icon_color)
|
||||
.field("raw_other", &"<json>")
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize)]
|
||||
pub struct Model {
|
||||
pub alias: String,
|
||||
pub provider: String,
|
||||
pub model: String,
|
||||
pub max_context_size: u64,
|
||||
pub display_name: Option<String>,
|
||||
#[serde(default, skip_serializing_if = "std::ops::Not::not")]
|
||||
pub supports_1m: bool,
|
||||
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
||||
pub capabilities: Vec<String>,
|
||||
#[serde(default, skip_serializing_if = "Value::is_null")]
|
||||
pub raw_other: Value,
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for Model {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_struct("Model")
|
||||
.field("alias", &self.alias)
|
||||
.field("provider", &self.provider)
|
||||
.field("model", &self.model)
|
||||
.field("max_context_size", &self.max_context_size)
|
||||
.field("display_name", &self.display_name)
|
||||
.field("supports_1m", &self.supports_1m)
|
||||
.field("capabilities", &self.capabilities)
|
||||
.field("raw_other", &"<json>")
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for Model {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.alias == other.alias
|
||||
&& self.provider == other.provider
|
||||
&& self.model == other.model
|
||||
&& self.max_context_size == other.max_context_size
|
||||
&& self.display_name == other.display_name
|
||||
&& self.supports_1m == other.supports_1m
|
||||
&& self.capabilities == other.capabilities
|
||||
&& self.raw_other == other.raw_other
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for Model {}
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize)]
|
||||
pub struct Config {
|
||||
pub default_model: Option<String>,
|
||||
#[serde(default)]
|
||||
pub providers: IndexMap<String, Provider>,
|
||||
#[serde(default)]
|
||||
pub models: IndexMap<String, Model>,
|
||||
#[serde(default, skip_serializing_if = "Value::is_null")]
|
||||
pub raw_other: Value,
|
||||
}
|
||||
|
||||
impl PartialEq for Config {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.default_model == other.default_model
|
||||
&& self.providers == other.providers
|
||||
&& self.models == other.models
|
||||
&& self.raw_other == other.raw_other
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for Config {}
|
||||
|
||||
impl std::fmt::Debug for Config {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_struct("Config")
|
||||
.field("default_model", &self.default_model)
|
||||
.field(
|
||||
"providers",
|
||||
&format!(
|
||||
"{:?} ({} providers)",
|
||||
self.providers.keys().collect::<Vec<_>>(),
|
||||
self.providers.len()
|
||||
),
|
||||
)
|
||||
.field("models", &self.models)
|
||||
.field("raw_other", &"<json>")
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
/// A model discovered from a provider's API endpoint.
|
||||
/// The frontend uses this to populate a `Model` form entry.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct DiscoveredModel {
|
||||
pub id: String,
|
||||
pub display_name: Option<String>,
|
||||
pub max_context_size: Option<u64>,
|
||||
}
|
||||
Reference in new issue
Block a user