mirror of
https://github.com/qingchencloud/clawpanel.git
synced 2026-05-07 06:03:02 +08:00
fix: cargo fmt + update docs version to 0.4.0
This commit is contained in:
@@ -34,7 +34,7 @@
|
||||
"description": "OpenClaw AI Agent 可视化管理面板,基于 Tauri v2 的跨平台桌面应用。支持仪表盘监控、多模型配置、实时 AI 聊天、记忆管理、Agent 管理、网关配置、内网穿透等功能。",
|
||||
"url": "https://claw.qt.cool/",
|
||||
"downloadUrl": "https://github.com/qingchencloud/clawpanel/releases/latest",
|
||||
"softwareVersion": "0.3.0",
|
||||
"softwareVersion": "0.4.0",
|
||||
"author": {
|
||||
"@type": "Organization",
|
||||
"name": "晴辰云 QingchenCloud",
|
||||
@@ -429,7 +429,7 @@
|
||||
<div class="orb orb-1" id="orb1"></div>
|
||||
<div class="orb orb-2" id="orb2"></div>
|
||||
<div class="hero-inner">
|
||||
<div class="reveal hero-badge"><span class="pulse"></span> v0.3.0 已发布 — 社区交流 & 高级视觉特效</div>
|
||||
<div class="reveal hero-badge"><span class="pulse"></span> v0.4.0 已发布 — Gateway 守护、配置同步、流式超时</div>
|
||||
<h1 class="reveal hero-title">管理你的 <span class="gradient-text shimmer">AI Agent</span><br>从未如此直观</h1>
|
||||
<p class="reveal hero-subtitle">ClawPanel 是 <strong>OpenClaw</strong> 的可视化管理面板,基于 Tauri v2 构建。<br>仪表盘、模型配置、实时聊天、记忆管理 — 一站式掌控。</p>
|
||||
<div class="reveal hero-cta">
|
||||
@@ -696,7 +696,7 @@
|
||||
<div class="orb orb-2" style="top:auto;bottom:-100px"></div>
|
||||
<div class="container-sm" style="position:relative;z-index:10">
|
||||
<div class="section-header">
|
||||
<div class="reveal download-version"><span class="pulse"></span> v0.3.0 最新版</div>
|
||||
<div class="reveal download-version"><span class="pulse"></span> v0.4.0 最新版</div>
|
||||
<h2 class="reveal section-title"><span class="gradient-text">下载安装</span></h2>
|
||||
<p class="reveal section-desc">选择你的操作系统,一键下载安装</p>
|
||||
</div>
|
||||
@@ -706,11 +706,11 @@
|
||||
<h3>macOS</h3>
|
||||
<p class="dl-desc">支持 Apple Silicon 和 Intel 芯片</p>
|
||||
<div class="dl-links">
|
||||
<a class="dl-link" href="https://github.com/qingchencloud/clawpanel/releases/latest/download/ClawPanel_0.3.0_aarch64.dmg" target="_blank" rel="noopener">
|
||||
<a class="dl-link" href="https://github.com/qingchencloud/clawpanel/releases/latest/download/ClawPanel_0.4.0_aarch64.dmg" target="_blank" rel="noopener">
|
||||
Apple Silicon (M1/M2/M3/M4)
|
||||
<span class="dl-format">.dmg</span>
|
||||
</a>
|
||||
<a class="dl-link" href="https://github.com/qingchencloud/clawpanel/releases/latest/download/ClawPanel_0.3.0_x64.dmg" target="_blank" rel="noopener">
|
||||
<a class="dl-link" href="https://github.com/qingchencloud/clawpanel/releases/latest/download/ClawPanel_0.4.0_x64.dmg" target="_blank" rel="noopener">
|
||||
Intel 芯片
|
||||
<span class="dl-format">.dmg</span>
|
||||
</a>
|
||||
@@ -721,11 +721,11 @@
|
||||
<h3>Windows</h3>
|
||||
<p class="dl-desc">支持 Windows 10 及以上版本</p>
|
||||
<div class="dl-links">
|
||||
<a class="dl-link" href="https://github.com/qingchencloud/clawpanel/releases/latest/download/ClawPanel_0.3.0_x64-setup.exe" target="_blank" rel="noopener">
|
||||
<a class="dl-link" href="https://github.com/qingchencloud/clawpanel/releases/latest/download/ClawPanel_0.4.0_x64-setup.exe" target="_blank" rel="noopener">
|
||||
安装程序
|
||||
<span class="dl-format">.exe</span>
|
||||
</a>
|
||||
<a class="dl-link" href="https://github.com/qingchencloud/clawpanel/releases/latest/download/ClawPanel_0.3.0_x64_en-US.msi" target="_blank" rel="noopener">
|
||||
<a class="dl-link" href="https://github.com/qingchencloud/clawpanel/releases/latest/download/ClawPanel_0.4.0_x64_en-US.msi" target="_blank" rel="noopener">
|
||||
MSI 安装包
|
||||
<span class="dl-format">.msi</span>
|
||||
</a>
|
||||
@@ -736,11 +736,11 @@
|
||||
<h3>Linux</h3>
|
||||
<p class="dl-desc">支持主流 Linux 发行版</p>
|
||||
<div class="dl-links">
|
||||
<a class="dl-link" href="https://github.com/qingchencloud/clawpanel/releases/latest/download/ClawPanel_0.3.0_amd64.AppImage" target="_blank" rel="noopener">
|
||||
<a class="dl-link" href="https://github.com/qingchencloud/clawpanel/releases/latest/download/ClawPanel_0.4.0_amd64.AppImage" target="_blank" rel="noopener">
|
||||
通用版
|
||||
<span class="dl-format">.AppImage</span>
|
||||
</a>
|
||||
<a class="dl-link" href="https://github.com/qingchencloud/clawpanel/releases/latest/download/ClawPanel_0.3.0_amd64.deb" target="_blank" rel="noopener">
|
||||
<a class="dl-link" href="https://github.com/qingchencloud/clawpanel/releases/latest/download/ClawPanel_0.4.0_amd64.deb" target="_blank" rel="noopener">
|
||||
Debian / Ubuntu
|
||||
<span class="dl-format">.deb</span>
|
||||
</a>
|
||||
|
||||
@@ -124,7 +124,8 @@ pub fn write_openclaw_config(config: Value) -> Result<(), String> {
|
||||
/// 包括:同步 baseUrl/apiKey/api、删除已移除的 provider、删除已移除的 model、
|
||||
/// 确保 Gateway 运行时不会引用 openclaw.json 中已不存在的模型
|
||||
fn sync_providers_to_agent_models(config: &Value) {
|
||||
let src_providers = config.pointer("/models/providers")
|
||||
let src_providers = config
|
||||
.pointer("/models/providers")
|
||||
.and_then(|p| p.as_object());
|
||||
|
||||
// 收集 openclaw.json 中所有有效的 provider/model 组合
|
||||
@@ -133,8 +134,7 @@ fn sync_providers_to_agent_models(config: &Value) {
|
||||
for (pk, pv) in providers {
|
||||
if let Some(models) = pv.get("models").and_then(|m| m.as_array()) {
|
||||
for m in models {
|
||||
let id = m.get("id").and_then(|v| v.as_str())
|
||||
.or_else(|| m.as_str());
|
||||
let id = m.get("id").and_then(|v| v.as_str()).or_else(|| m.as_str());
|
||||
if let Some(id) = id {
|
||||
valid_models.insert(format!("{}/{}", pk, id));
|
||||
}
|
||||
@@ -161,18 +161,27 @@ fn sync_providers_to_agent_models(config: &Value) {
|
||||
if !models_path.exists() {
|
||||
continue;
|
||||
}
|
||||
let Ok(content) = fs::read_to_string(&models_path) else { continue };
|
||||
let Ok(mut models_json) = serde_json::from_str::<Value>(&content) else { continue };
|
||||
let Ok(content) = fs::read_to_string(&models_path) else {
|
||||
continue;
|
||||
};
|
||||
let Ok(mut models_json) = serde_json::from_str::<Value>(&content) else {
|
||||
continue;
|
||||
};
|
||||
|
||||
let mut changed = false;
|
||||
|
||||
// 同步 providers
|
||||
if let Some(dst_providers) = models_json.get_mut("providers").and_then(|p| p.as_object_mut()) {
|
||||
if let Some(dst_providers) = models_json
|
||||
.get_mut("providers")
|
||||
.and_then(|p| p.as_object_mut())
|
||||
{
|
||||
// 1. 删除 openclaw.json 中已不存在的 provider
|
||||
if let Some(src) = src_providers {
|
||||
let to_remove: Vec<String> = dst_providers.keys()
|
||||
let to_remove: Vec<String> = dst_providers
|
||||
.keys()
|
||||
.filter(|k| !src.contains_key(k.as_str()))
|
||||
.cloned().collect();
|
||||
.cloned()
|
||||
.collect();
|
||||
for k in to_remove {
|
||||
dst_providers.remove(&k);
|
||||
changed = true;
|
||||
@@ -184,26 +193,42 @@ fn sync_providers_to_agent_models(config: &Value) {
|
||||
if let Some(dst_obj) = dst_provider.as_object_mut() {
|
||||
// 同步连接信息
|
||||
for field in ["baseUrl", "apiKey", "api"] {
|
||||
if let Some(src_val) = src_provider.get(field).and_then(|v| v.as_str()) {
|
||||
if dst_obj.get(field).and_then(|v| v.as_str()) != Some(src_val) {
|
||||
dst_obj.insert(field.to_string(), Value::String(src_val.to_string()));
|
||||
if let Some(src_val) =
|
||||
src_provider.get(field).and_then(|v| v.as_str())
|
||||
{
|
||||
if dst_obj.get(field).and_then(|v| v.as_str()) != Some(src_val)
|
||||
{
|
||||
dst_obj.insert(
|
||||
field.to_string(),
|
||||
Value::String(src_val.to_string()),
|
||||
);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
// 清理已删除的 models
|
||||
if let Some(dst_models) = dst_obj.get_mut("models").and_then(|m| m.as_array_mut()) {
|
||||
if let Some(dst_models) =
|
||||
dst_obj.get_mut("models").and_then(|m| m.as_array_mut())
|
||||
{
|
||||
let src_model_ids: std::collections::HashSet<String> = src_provider
|
||||
.get("models").and_then(|m| m.as_array())
|
||||
.map(|arr| arr.iter().filter_map(|m| {
|
||||
m.get("id").and_then(|v| v.as_str())
|
||||
.or_else(|| m.as_str())
|
||||
.map(|s| s.to_string())
|
||||
}).collect())
|
||||
.get("models")
|
||||
.and_then(|m| m.as_array())
|
||||
.map(|arr| {
|
||||
arr.iter()
|
||||
.filter_map(|m| {
|
||||
m.get("id")
|
||||
.and_then(|v| v.as_str())
|
||||
.or_else(|| m.as_str())
|
||||
.map(|s| s.to_string())
|
||||
})
|
||||
.collect()
|
||||
})
|
||||
.unwrap_or_default();
|
||||
let before = dst_models.len();
|
||||
dst_models.retain(|m| {
|
||||
let id = m.get("id").and_then(|v| v.as_str())
|
||||
let id = m
|
||||
.get("id")
|
||||
.and_then(|v| v.as_str())
|
||||
.or_else(|| m.as_str())
|
||||
.unwrap_or("");
|
||||
src_model_ids.contains(id)
|
||||
|
||||
Reference in New Issue
Block a user