feat: v0.5.0 - provider icon actions, duplicate & connectivity test, dashboard chart fixes
- ProviderList: icon buttons (edit/copy/test/delete) via lucide-react, speed-test badge before enable/switch button - Duplicate provider: deep-copy provider + models as xxx-copy - test_connectivity command (cc-switch semantics: GET base_url, any HTTP response = reachable), latency badge green/orange/red, auto-dismiss 6s - Dashboard: daily bars anchored to panel bottom, Card flex height fix (heatmap stays content-height)
This commit is contained in:
1 parent
6b172914be
commit
b1d137f072
12 files changed
+232
-12
No files matched your search
Generated
+1
-1
@@ -1958,7 +1958,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "kimiswitch"
|
||||
version = "0.4.0"
|
||||
version = "0.5.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"chrono",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "kimiswitch"
|
||||
version = "0.4.1"
|
||||
version = "0.5.0"
|
||||
description = "Kimi Switch - model config manager"
|
||||
authors = ["you"]
|
||||
edition = "2021"
|
||||
|
||||
@@ -211,6 +211,55 @@ pub async fn list_provider_models(provider: Provider) -> Result<Vec<DiscoveredMo
|
||||
}
|
||||
}
|
||||
|
||||
/// Test reachability of a provider's base URL (cc-switch semantics):
|
||||
/// any HTTP response counts as reachable; only network-layer errors fail.
|
||||
#[derive(Debug, Serialize, Clone)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct ConnectivityResult {
|
||||
pub ok: bool,
|
||||
pub latency_ms: u64,
|
||||
pub status_code: Option<u16>,
|
||||
pub error: Option<String>,
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn test_connectivity(provider: Provider) -> Result<ConnectivityResult, String> {
|
||||
let base = resolve_base_url(&provider);
|
||||
if base.trim().is_empty() {
|
||||
return Ok(ConnectivityResult {
|
||||
ok: false,
|
||||
latency_ms: 0,
|
||||
status_code: None,
|
||||
error: Some("no base URL configured".to_string()),
|
||||
});
|
||||
}
|
||||
let client = reqwest::Client::builder()
|
||||
.timeout(std::time::Duration::from_secs(8))
|
||||
.build()
|
||||
.map_err(|e| format!("failed to build HTTP client: {e}"))?;
|
||||
let start = std::time::Instant::now();
|
||||
match client.get(base.as_str()).send().await {
|
||||
Ok(resp) => Ok(ConnectivityResult {
|
||||
ok: true,
|
||||
latency_ms: start.elapsed().as_millis() as u64,
|
||||
status_code: Some(resp.status().as_u16()),
|
||||
error: None,
|
||||
}),
|
||||
Err(e) => Ok(ConnectivityResult {
|
||||
ok: false,
|
||||
latency_ms: start.elapsed().as_millis() as u64,
|
||||
status_code: None,
|
||||
error: Some(if e.is_connect() {
|
||||
"connection refused / DNS failed".to_string()
|
||||
} else if e.is_timeout() {
|
||||
"request timed out".to_string()
|
||||
} else {
|
||||
e.to_string()
|
||||
}),
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
fn resolve_api_key(provider: &Provider) -> Option<String> {
|
||||
if provider.managed {
|
||||
return Some("managed".to_string());
|
||||
|
||||
@@ -99,6 +99,7 @@ pub fn run() {
|
||||
commands::open_agent_config_dir,
|
||||
commands::get_app_version,
|
||||
commands::list_provider_models,
|
||||
commands::test_connectivity,
|
||||
commands::debug_log,
|
||||
commands::get_app_setting,
|
||||
commands::set_app_setting,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"productName": "Kimi Switch",
|
||||
"version": "0.4.1",
|
||||
"version": "0.5.0",
|
||||
"identifier": "com.kimiswitch.app",
|
||||
"build": {
|
||||
"beforeDevCommand": "npm run dev",
|
||||
|
||||
Reference in new issue
Block a user