Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,4 @@ docs/promo-video.mp4

# Rust 开发工具
src-tauri/.cargo/
.ace-tool/
5 changes: 3 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 15 additions & 0 deletions scripts/dev-api.js
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,21 @@ const handlers = {
return true
},

// 使用 openclaw CLI 安全地设置 fallbacks 配置
set_fallbacks_config({ fallbacks }) {
try {
// 使用 openclaw config set 命令安全地设置配置
const fallbacksJson = JSON.stringify(fallbacks)
execSync(`openclaw config set agents.defaults.model.fallbacks '${fallbacksJson}'`, {
encoding: 'utf8',
stdio: ['ignore', 'pipe', 'pipe']
})
return true
} catch (e) {
throw new Error(`设置 fallbacks 配置失败: ${e.message}`)
}
},

read_mcp_config() {
if (!fs.existsSync(MCP_CONFIG_PATH)) return {}
return JSON.parse(fs.readFileSync(MCP_CONFIG_PATH, 'utf8'))
Expand Down
81 changes: 81 additions & 0 deletions src-tauri/src/commands/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1356,3 +1356,84 @@ pub fn set_npm_registry(registry: String) -> Result<(), String> {
let path = super::openclaw_dir().join("npm-registry.txt");
fs::write(&path, registry.trim()).map_err(|e| format!("保存失败: {e}"))
}

// === Fallbacks 历史记录 ===

#[derive(serde::Serialize, serde::Deserialize, Clone)]
struct FallbacksHistoryRecord {
timestamp: i64,
fallbacks: Vec<String>,
primary: String,
}

#[tauri::command]
pub fn get_fallbacks_history_path() -> Result<String, String> {
let path = super::openclaw_dir().join("fallbacks-history.json");
Ok(path.to_string_lossy().to_string())
}

#[tauri::command]
pub fn load_fallbacks_history() -> Result<Value, String> {
let path = super::openclaw_dir().join("fallbacks-history.json");
if !path.exists() {
return Ok(serde_json::json!([]));
}

let content = fs::read_to_string(&path).map_err(|e| format!("读取历史记录失败: {e}"))?;
let history: Vec<FallbacksHistoryRecord> = serde_json::from_str(&content)
.map_err(|e| format!("解析历史记录失败: {e}"))?;

serde_json::to_value(history).map_err(|e| format!("序列化失败: {e}"))
}

#[tauri::command]
pub fn save_fallbacks_history(history: Value) -> Result<(), String> {
let dir = super::openclaw_dir();
if !dir.exists() {
fs::create_dir_all(&dir).map_err(|e| format!("创建目录失败: {e}"))?;
}

let path = dir.join("fallbacks-history.json");
let json = serde_json::to_string_pretty(&history)
.map_err(|e| format!("序列化历史记录失败: {e}"))?;
fs::write(&path, json).map_err(|e| format!("保存历史记录失败: {e}"))
}

#[tauri::command]
pub fn clear_fallbacks_history() -> Result<(), String> {
let path = super::openclaw_dir().join("fallbacks-history.json");
if path.exists() {
fs::remove_file(&path).map_err(|e| format!("删除历史记录失败: {e}"))?;
}
Ok(())
}

/// 使用 openclaw CLI 安全地设置 fallbacks 配置
#[tauri::command]
pub async fn set_fallbacks_config(fallbacks: Vec<String>) -> Result<(), String> {
use crate::utils::openclaw_command_async;

// 将 fallbacks 数组转换为 JSON 字符串
let fallbacks_json = serde_json::to_string(&fallbacks)
.map_err(|e| format!("序列化 fallbacks 失败: {e}"))?;

// 使用 openclaw config set 命令安全地设置配置
let output = openclaw_command_async()
.args(["config", "set", "agents.defaults.model.fallbacks", &fallbacks_json])
.output()
.await
.map_err(|e| {
if e.kind() == std::io::ErrorKind::NotFound {
"OpenClaw CLI 未找到,请确认已安装并重启 ClawPanel。".to_string()
} else {
format!("执行 openclaw config set 失败: {e}")
}
})?;

if !output.status.success() {
let stderr = String::from_utf8_lossy(&output.stderr);
return Err(format!("设置 fallbacks 配置失败: {stderr}"));
}

Ok(())
}
5 changes: 5 additions & 0 deletions src-tauri/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ pub fn run() {
config::write_panel_config,
config::get_npm_registry,
config::set_npm_registry,
config::get_fallbacks_history_path,
config::load_fallbacks_history,
config::save_fallbacks_history,
config::clear_fallbacks_history,
config::set_fallbacks_config,
// 设备密钥 + Gateway 握手
device::create_connect_frame,
// 设备配对
Expand Down
10 changes: 10 additions & 0 deletions src/lib/tauri-api.js
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,16 @@ export const api = {
uninstallGateway: () => invoke('uninstall_gateway'),
getNpmRegistry: () => cachedInvoke('get_npm_registry', {}, 30000),
setNpmRegistry: (registry) => { invalidate('get_npm_registry'); return invoke('set_npm_registry', { registry }) },

// Fallbacks 历史记录
getFallbacksHistoryPath: () => invoke('get_fallbacks_history_path'),
loadFallbacksHistory: () => invoke('load_fallbacks_history'),
saveFallbacksHistory: (history) => invoke('save_fallbacks_history', { history }),
clearFallbacksHistory: () => invoke('clear_fallbacks_history'),

// 使用 openclaw CLI 安全地设置 fallbacks 配置
setFallbacksConfig: (fallbacks) => invoke('set_fallbacks_config', { fallbacks }),

testModel: (baseUrl, apiKey, modelId) => invoke('test_model', { baseUrl, apiKey, modelId }),
listRemoteModels: (baseUrl, apiKey) => invoke('list_remote_models', { baseUrl, apiKey }),

Expand Down
Loading