修复: 高风险工具名单改注册表投影

新增 ai_list_tools 只读投影 name+risk,前端启动拉取构建
手写名单缺 10 个 High 工具致审批二次确认漏弹,现名单改兜底保留
顺带删除零调用方 get_script_safety 死命令及注册
This commit is contained in:
lxy
2026-10-01 08:28:07 +08:00
parent 4b445e96b8
commit 7b5a2c83b0
8 changed files with 88 additions and 16 deletions
@@ -24,6 +24,8 @@ use tauri::State;
// 来自 commands/ai/skills.rs,本域 IPC 复用,不重复定义。
use super::super::skills::{invalidate_skills, skills_cached, SkillInfo};
use df_ai::ai_tools::RiskLevel;
use crate::state::AppState;
/// 列出本机 Claude 技能(skills + commands + plugins 三类),供前端 `/` 联想
@@ -128,3 +130,37 @@ pub async fn ai_set_allowed_dirs(
) -> Result<Vec<String>, String> {
state.set_allowed_dirs(dirs).await.map_err(|e| e.to_string())
}
// ============================================================
// AI 工具风险元数据投影(只读,前端审批二次确认门控的数据源)
// ============================================================
/// 单个 AI 工具的风险元数据(来自 AiToolRegistry 注册时声明的 risk_level)。
/// risk 沿用 RiskLevel 的 serde 序列化(小写 low/medium/high,与 audit risk_str 同口径)。
#[derive(serde::Serialize)]
pub struct AiToolMeta {
pub name: String,
pub risk: RiskLevel,
}
/// 列出全部已注册 AI 工具的名称与风险级。
///
/// 唯一消费方:前端启动(AiChat onMounted)拉取后构建 High 风险名单,
/// 供审批二次确认门控(useToolApproval)。数据源 = 工具注册表元数据,
/// 根治前端手写名单与 tools/*.rs 分散注册的双写漂移(新增 High 工具免改前端)。
#[tauri::command]
pub async fn ai_list_tools(state: State<'_, AppState>) -> Result<Vec<AiToolMeta>, String> {
let registry = state.ai_tools.as_ref();
// tool_names 拿 owned 键再 get 取 risk(不给 df-ai 加迭代器导出);排序稳定输出(HashMap 遍历序随机)
let mut metas: Vec<AiToolMeta> = registry
.tool_names()
.into_iter()
.filter_map(|name| {
registry
.get(&name)
.map(|t| AiToolMeta { name, risk: t.risk_level })
})
.collect();
metas.sort_by(|a, b| a.name.cmp(&b.name));
Ok(metas)
}
-11
View File
@@ -116,17 +116,6 @@ pub async fn set_script_safety(
Ok(())
}
/// 读取脚本安全配置。
#[tauri::command]
pub async fn get_script_safety(
state: State<'_, AppState>,
) -> Result<(String, String), String> {
// appSettings.set(JSON.stringify 带引号)与 settingsApi.set(裸串)双通道写入并存,读端归一
let wl = state.settings.get("df-script-whitelist").await.map_err(err_str)?.map(|v| v.trim_matches('"').to_string()).unwrap_or_default();
let bl = state.settings.get("df-script-blacklist").await.map_err(err_str)?.map(|v| v.trim_matches('"').to_string()).unwrap_or_default();
Ok((wl, bl))
}
/// 设置多 ReAct Plan 执行开关(默认关)。
/// 开启后 process_tool_calls 内以 JoinSet 并行执行同层工具。
#[tauri::command]