修复: 高风险工具名单改注册表投影
新增 ai_list_tools 只读投影 name+risk,前端启动拉取构建 手写名单缺 10 个 High 工具致审批二次确认漏弹,现名单改兜底保留 顺带删除零调用方 get_script_safety 死命令及注册
This commit is contained in:
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -462,6 +462,8 @@ pub fn run() {
|
||||
// F-260619-03 Phase A: AI 工具文件访问授权目录白名单
|
||||
commands::ai::ai_get_allowed_dirs,
|
||||
commands::ai::ai_set_allowed_dirs,
|
||||
// 工具风险元数据投影(前端启动构建 High 风险名单,审批二次确认门控)
|
||||
commands::ai::ai_list_tools,
|
||||
// F-260619-03 Phase B: 路径授权弹窗决策(消费 AiDirAuthRequired 挂起)
|
||||
commands::ai::ai_authorize_dir,
|
||||
// 审批历史面板查 ai_tool_executions 表,敏感字段截断)
|
||||
@@ -495,7 +497,6 @@ pub fn run() {
|
||||
commands::settings::ai_set_approval_timeout,
|
||||
// ScriptNode 命令安全配置(白/黑名单,前端设置页写入)
|
||||
commands::settings::set_script_safety,
|
||||
commands::settings::get_script_safety,
|
||||
// Plan 执行开关
|
||||
commands::settings::set_plan_execution,
|
||||
commands::settings::get_plan_execution,
|
||||
|
||||
Reference in New Issue
Block a user