feat: keep provider records on switch, only mark active; filter on save
This commit is contained in:
@@ -124,6 +124,7 @@ pub fn kimi_code_to_config(value: &TomlValue) -> Config {
|
|||||||
official_url: None,
|
official_url: None,
|
||||||
managed,
|
managed,
|
||||||
enabled,
|
enabled,
|
||||||
|
active: true,
|
||||||
raw_other,
|
raw_other,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@@ -225,8 +226,15 @@ pub fn config_to_kimi_code(config: &Config, existing: Option<&TomlValue>) -> Tom
|
|||||||
.unwrap_or(TomlValue::String("".to_string())),
|
.unwrap_or(TomlValue::String("".to_string())),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let is_kimi_native = |p: &Provider| p.managed;
|
||||||
|
|
||||||
let mut providers_table = Table::new();
|
let mut providers_table = Table::new();
|
||||||
for (name, provider) in &config.providers {
|
for (name, provider) in &config.providers {
|
||||||
|
// Skip inactive custom providers when writing to Kimi Code config.
|
||||||
|
// Kimi native (managed) providers are always preserved.
|
||||||
|
if !is_kimi_native(provider) && !provider.active {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
let mut pt = Table::new();
|
let mut pt = Table::new();
|
||||||
pt.insert("type".to_string(), TomlValue::String(provider.provider_type.as_str().to_string()));
|
pt.insert("type".to_string(), TomlValue::String(provider.provider_type.as_str().to_string()));
|
||||||
if let Some(base_url) = provider.base_url.clone().filter(|s| !s.is_empty()) {
|
if let Some(base_url) = provider.base_url.clone().filter(|s| !s.is_empty()) {
|
||||||
@@ -261,8 +269,19 @@ pub fn config_to_kimi_code(config: &Config, existing: Option<&TomlValue>) -> Tom
|
|||||||
}
|
}
|
||||||
root.insert("providers".to_string(), TomlValue::Table(providers_table));
|
root.insert("providers".to_string(), TomlValue::Table(providers_table));
|
||||||
|
|
||||||
|
// Collect provider names that survived the filter above.
|
||||||
|
let active_provider_names: std::collections::HashSet<&str> = config
|
||||||
|
.providers
|
||||||
|
.values()
|
||||||
|
.filter(|p| is_kimi_native(p) || p.active)
|
||||||
|
.map(|p| p.name.as_str())
|
||||||
|
.collect();
|
||||||
|
|
||||||
let mut models_table = Table::new();
|
let mut models_table = Table::new();
|
||||||
for (alias, model) in &config.models {
|
for (alias, model) in &config.models {
|
||||||
|
if !active_provider_names.contains(model.provider.as_str()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
let mut mt = Table::new();
|
let mut mt = Table::new();
|
||||||
mt.insert("provider".to_string(), TomlValue::String(model.provider.clone()));
|
mt.insert("provider".to_string(), TomlValue::String(model.provider.clone()));
|
||||||
mt.insert("model".to_string(), TomlValue::String(model.model.clone()));
|
mt.insert("model".to_string(), TomlValue::String(model.model.clone()));
|
||||||
|
|||||||
@@ -83,6 +83,8 @@ pub struct Provider {
|
|||||||
pub managed: bool,
|
pub managed: bool,
|
||||||
#[serde(default = "default_true")]
|
#[serde(default = "default_true")]
|
||||||
pub enabled: bool,
|
pub enabled: bool,
|
||||||
|
#[serde(default)]
|
||||||
|
pub active: bool,
|
||||||
#[serde(default, skip_serializing_if = "Value::is_null")]
|
#[serde(default, skip_serializing_if = "Value::is_null")]
|
||||||
pub raw_other: Value,
|
pub raw_other: Value,
|
||||||
}
|
}
|
||||||
@@ -98,6 +100,7 @@ impl PartialEq for Provider {
|
|||||||
&& self.official_url == other.official_url
|
&& self.official_url == other.official_url
|
||||||
&& self.managed == other.managed
|
&& self.managed == other.managed
|
||||||
&& self.enabled == other.enabled
|
&& self.enabled == other.enabled
|
||||||
|
&& self.active == other.active
|
||||||
&& self.raw_other == other.raw_other
|
&& self.raw_other == other.raw_other
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -201,6 +201,7 @@ pub fn pi_file_to_config(file: &PiModelsFile) -> Config {
|
|||||||
official_url: None,
|
official_url: None,
|
||||||
managed: false,
|
managed: false,
|
||||||
enabled: pi_provider.enabled,
|
enabled: pi_provider.enabled,
|
||||||
|
active: true,
|
||||||
raw_other: pi_provider.extra.clone(),
|
raw_other: pi_provider.extra.clone(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+6
-16
@@ -194,37 +194,27 @@ export default function App() {
|
|||||||
const handleSwitchProvider = (name: string) => {
|
const handleSwitchProvider = (name: string) => {
|
||||||
updateConfig((cfg) => {
|
updateConfig((cfg) => {
|
||||||
const target = cfg.providers[name];
|
const target = cfg.providers[name];
|
||||||
if (!target) return cfg;
|
if (!target || target.managed) return cfg;
|
||||||
|
|
||||||
const isKimiNative = (p: Provider) => p.managed === true;
|
const isKimiNative = (p: Provider) => p.managed === true;
|
||||||
|
|
||||||
// Keep Kimi native (managed) providers and the selected provider only.
|
// Mark the selected provider as active and deactivate other custom providers.
|
||||||
|
// Kimi native providers are left untouched. No provider/model records are deleted.
|
||||||
const providers: Record<string, Provider> = {};
|
const providers: Record<string, Provider> = {};
|
||||||
for (const [key, p] of Object.entries(cfg.providers)) {
|
for (const [key, p] of Object.entries(cfg.providers)) {
|
||||||
if (isKimiNative(p)) {
|
providers[key] = { ...p, active: isKimiNative(p) ? undefined : key === name };
|
||||||
providers[key] = p;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
providers[name] = { ...target, enabled: true };
|
|
||||||
|
|
||||||
// Drop models whose provider was removed.
|
|
||||||
const models: Record<string, Model> = {};
|
|
||||||
for (const [key, m] of Object.entries(cfg.models)) {
|
|
||||||
if (providers[m.provider]) {
|
|
||||||
models[key] = m;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set default model to the first model of the selected provider.
|
// Set default model to the first model of the selected provider.
|
||||||
let default_model: string | null = null;
|
let default_model: string | null = null;
|
||||||
for (const [key, m] of Object.entries(models)) {
|
for (const [key, m] of Object.entries(cfg.models)) {
|
||||||
if (m.provider === name) {
|
if (m.provider === name) {
|
||||||
default_model = key;
|
default_model = key;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return { ...cfg, providers, models, default_model };
|
return { ...cfg, providers, default_model };
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -93,10 +93,7 @@ export function ProviderList({
|
|||||||
? models[defaultModel]?.display_name || defaultModel
|
? models[defaultModel]?.display_name || defaultModel
|
||||||
: null;
|
: null;
|
||||||
const isKimiNative = provider.managed === true;
|
const isKimiNative = provider.managed === true;
|
||||||
const isActive =
|
const isActive = !isKimiNative && provider.active === true;
|
||||||
!isKimiNative &&
|
|
||||||
defaultModel !== null &&
|
|
||||||
models[defaultModel]?.provider === provider.name;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ export interface Provider {
|
|||||||
managed?: boolean;
|
managed?: boolean;
|
||||||
/** Whether the provider is enabled/activated. */
|
/** Whether the provider is enabled/activated. */
|
||||||
enabled?: boolean;
|
enabled?: boolean;
|
||||||
|
/** Whether this provider is the currently active one for Kimi Code. */
|
||||||
|
active?: boolean;
|
||||||
/** Extra agent-specific provider fields preserved across edits. */
|
/** Extra agent-specific provider fields preserved across edits. */
|
||||||
raw_other?: unknown;
|
raw_other?: unknown;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user