mirror of
https://github.com/aiclientproxy/proxycast.git
synced 2026-10-30 18:41:42 +08:00
feat: 优化UI体验和添加帮助说明 v0.7.2
- 移除冗余的 OpenAI/Claude 自定义 Tab 和可用模型 Tab - 合并启动/停止服务按钮为单个切换按钮 - 添加可折叠的 HelpTip 组件 - 为凭证池、配置切换、API Server、MCP、Prompts、Skills 页面添加帮助说明 - 在关于页面添加使用说明 Q&A - 优化日志页面,添加回到顶部按钮 - 优化 Provider 切换提示,显示在框内 - 重命名 AI Clients 为配置切换,说明更清晰
This commit is contained in:
Generated
+1
-1
@@ -3153,7 +3153,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "proxycast"
|
||||
version = "0.7.0"
|
||||
version = "0.7.2"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-stream",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "proxycast"
|
||||
version = "0.7.0"
|
||||
version = "0.7.2"
|
||||
description = "AI API Proxy Desktop App"
|
||||
authors = ["you"]
|
||||
edition = "2021"
|
||||
|
||||
@@ -211,6 +211,13 @@ async fn set_default_provider(
|
||||
|
||||
let mut s = state.write().await;
|
||||
s.config.default_provider = provider.clone();
|
||||
|
||||
// 同时更新运行中服务器的 default_provider_ref
|
||||
{
|
||||
let mut dp = s.default_provider_ref.write().await;
|
||||
*dp = provider.clone();
|
||||
}
|
||||
|
||||
config::save_config(&s.config).map_err(|e| e.to_string())?;
|
||||
logs.write()
|
||||
.await
|
||||
|
||||
@@ -59,6 +59,7 @@ pub struct ServerState {
|
||||
pub qwen_provider: QwenProvider,
|
||||
pub openai_custom_provider: OpenAICustomProvider,
|
||||
pub claude_custom_provider: ClaudeCustomProvider,
|
||||
pub default_provider_ref: Arc<RwLock<String>>,
|
||||
shutdown_tx: Option<oneshot::Sender<()>>,
|
||||
}
|
||||
|
||||
@@ -69,6 +70,7 @@ impl ServerState {
|
||||
let qwen = QwenProvider::new();
|
||||
let openai_custom = OpenAICustomProvider::new();
|
||||
let claude_custom = ClaudeCustomProvider::new();
|
||||
let default_provider_ref = Arc::new(RwLock::new(config.default_provider.clone()));
|
||||
|
||||
Self {
|
||||
config,
|
||||
@@ -80,6 +82,7 @@ impl ServerState {
|
||||
qwen_provider: qwen,
|
||||
openai_custom_provider: openai_custom,
|
||||
claude_custom_provider: claude_custom,
|
||||
default_provider_ref,
|
||||
shutdown_tx: None,
|
||||
}
|
||||
}
|
||||
@@ -111,6 +114,7 @@ impl ServerState {
|
||||
let host = self.config.server.host.clone();
|
||||
let port = self.config.server.port;
|
||||
let api_key = self.config.server.api_key.clone();
|
||||
let default_provider_ref = self.default_provider_ref.clone();
|
||||
|
||||
// 重新加载凭证
|
||||
let _ = self.kiro_provider.load_credentials().await;
|
||||
@@ -121,6 +125,7 @@ impl ServerState {
|
||||
&host,
|
||||
port,
|
||||
&api_key,
|
||||
default_provider_ref,
|
||||
kiro,
|
||||
logs,
|
||||
rx,
|
||||
@@ -163,6 +168,7 @@ impl Clone for KiroProvider {
|
||||
struct AppState {
|
||||
api_key: String,
|
||||
base_url: String,
|
||||
default_provider: Arc<RwLock<String>>,
|
||||
kiro: Arc<RwLock<KiroProvider>>,
|
||||
logs: Arc<RwLock<LogStore>>,
|
||||
kiro_refresh_lock: Arc<tokio::sync::Mutex<()>>,
|
||||
@@ -177,6 +183,7 @@ async fn run_server(
|
||||
host: &str,
|
||||
port: u16,
|
||||
api_key: &str,
|
||||
default_provider: Arc<RwLock<String>>,
|
||||
kiro: KiroProvider,
|
||||
logs: Arc<RwLock<LogStore>>,
|
||||
shutdown: oneshot::Receiver<()>,
|
||||
@@ -188,6 +195,7 @@ async fn run_server(
|
||||
let state = AppState {
|
||||
api_key: api_key.to_string(),
|
||||
base_url,
|
||||
default_provider,
|
||||
kiro: Arc::new(RwLock::new(kiro)),
|
||||
logs,
|
||||
kiro_refresh_lock: Arc::new(tokio::sync::Mutex::new(())),
|
||||
@@ -311,6 +319,42 @@ async fn chat_completions(
|
||||
),
|
||||
);
|
||||
|
||||
// 获取当前默认 provider
|
||||
let default_provider = state.default_provider.read().await.clone();
|
||||
|
||||
// 尝试从凭证池中选择凭证
|
||||
let credential = match &state.db {
|
||||
Some(db) => state
|
||||
.pool_service
|
||||
.select_credential(db, &default_provider, Some(&request.model))
|
||||
.ok()
|
||||
.flatten(),
|
||||
None => None,
|
||||
};
|
||||
|
||||
// 如果找到凭证池中的凭证,使用它
|
||||
if let Some(cred) = credential {
|
||||
state.logs.write().await.add(
|
||||
"info",
|
||||
&format!(
|
||||
"[ROUTE] Using pool credential: type={} name={:?} uuid={}",
|
||||
cred.provider_type,
|
||||
cred.name,
|
||||
&cred.uuid[..8]
|
||||
),
|
||||
);
|
||||
return call_provider_openai(&state, &cred, &request).await;
|
||||
}
|
||||
|
||||
// 回退到旧的单凭证模式
|
||||
state.logs.write().await.add(
|
||||
"debug",
|
||||
&format!(
|
||||
"[ROUTE] No pool credential found for '{}', using legacy mode",
|
||||
default_provider
|
||||
),
|
||||
);
|
||||
|
||||
// 检查是否需要刷新 token(无 token 或即将过期)
|
||||
{
|
||||
let _guard = state.kiro_refresh_lock.lock().await;
|
||||
@@ -595,6 +639,45 @@ async fn anthropic_messages(
|
||||
);
|
||||
}
|
||||
|
||||
// 获取当前默认 provider
|
||||
let default_provider = state.default_provider.read().await.clone();
|
||||
|
||||
// 尝试从凭证池中选择凭证
|
||||
let credential = match &state.db {
|
||||
Some(db) => {
|
||||
// 根据 default_provider 配置选择凭证
|
||||
state
|
||||
.pool_service
|
||||
.select_credential(db, &default_provider, Some(&request.model))
|
||||
.ok()
|
||||
.flatten()
|
||||
}
|
||||
None => None,
|
||||
};
|
||||
|
||||
// 如果找到凭证池中的凭证,使用它
|
||||
if let Some(cred) = credential {
|
||||
state.logs.write().await.add(
|
||||
"info",
|
||||
&format!(
|
||||
"[ROUTE] Using pool credential: type={} name={:?} uuid={}",
|
||||
cred.provider_type,
|
||||
cred.name,
|
||||
&cred.uuid[..8]
|
||||
),
|
||||
);
|
||||
return call_provider_anthropic(&state, &cred, &request).await;
|
||||
}
|
||||
|
||||
// 回退到旧的单凭证模式
|
||||
state.logs.write().await.add(
|
||||
"debug",
|
||||
&format!(
|
||||
"[ROUTE] No pool credential found for '{}', using legacy mode",
|
||||
default_provider
|
||||
),
|
||||
);
|
||||
|
||||
// 检查是否需要刷新 token(无 token 或即将过期)
|
||||
{
|
||||
let _guard = state.kiro_refresh_lock.lock().await;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "https://schema.tauri.app/config/2",
|
||||
"productName": "ProxyCast",
|
||||
"version": "0.7.0",
|
||||
"version": "0.7.2",
|
||||
"identifier": "com.proxycast.app",
|
||||
"build": {
|
||||
"beforeDevCommand": "npm run dev",
|
||||
|
||||
Reference in New Issue
Block a user