Skip to content

feat(skills): 技能详情页配置脚本必需的供应商环境变量,缺失时标记暂不可用并在调用时引导 #582

Description

@AlphaCatMeow

背景

不少技能的脚本要调第三方供应商的 API(天气、翻译、图床、搜索等),运行前提是环境里有对应的 API Key 或账号配置。目前 SKILL.md 没有地方声明这类依赖:

  • 用户装完技能就能启用,直到脚本真正跑起来才报错,报错还是脚本自己的原始输出,看不出缺什么、去哪配;
  • 模型拿到失败结果后,可能反过来引导用户把密钥直接贴进聊天,既不安全也不好管理;
  • 技能作者只能把"请先设置 XXX_API_KEY"写在正文里,靠用户自觉,没有任何界面支撑。

期望行为

  1. 声明:技能在 SKILL.md frontmatter 里声明脚本必需的环境变量——变量名、供应商名称、用途说明、申请地址、是否可选。未声明的技能行为完全不变。
  2. 详情页配置:技能详情抽屉新增「运行要求」区块,逐项展示变量状态(未配置 / 已填写 / 使用系统环境变量),支持 masked 填写,也支持一键"从系统环境变量读取"(检测到系统已有该变量时,存引用不落盘值)。
  3. 可用性标记:必填变量未满足时,技能标记为「暂不可用」——卡片上出现提示徽标,注入模型的技能清单里也带上不可用标注和缺失项;不锁启用开关,不弹窗打断。
  4. 调用时兜底:会话中模型读取该技能(SkillsManager action=read 或 /技能名 提及)时先做前置检查,不满足则返回结构化的"缺少必要环境变量"结果;聊天界面渲染引导卡片,询问用户「跳转技能详情页填写」或「读取系统环境变量」,配置完成后可直接重试。
  5. 注入:用户填写的值在该技能启用的会话里注入 shell 工具的执行环境;"系统环境变量"模式下子进程本来就继承,不重复存值。

边界与安全

  • 值在界面上始终 mask,错误信息做 redact(参照 stt 模块 secretFields 的做法);
  • SkillsManager 的结果只回传"哪些变量缺失/已满足",不回传值本体;
  • 返回给模型的文案明确指示:等待用户在界面配置,不要请求用户在聊天中粘贴密钥;
  • 声明格式向后兼容,解析器忽略未知字段,其他工具读同一份 SKILL.md 不受影响。

涉及范围(初步)

  • Rust 技能服务:frontmatter 解析、list/read 响应扩展、读取前置检查(crates/agent-gui/src-tauri/src/services/skills/);
  • 前端共享层:SkillSummary 类型、SkillsSettings 存储、buildSkillsSystemPrompt 标注(crates/agent-ui/src/lib/skills/);
  • Skills Hub:InstalledSkillCard 徽标、InstalledSkillPreviewDrawer 运行要求区块;
  • 聊天:skillTools.ts 拦截、工具结果卡片与跳转交互;
  • shell 执行:按会话注入技能环境变量;
  • 双端:gateway webui 复用同一 Rust 后端(skills.manage 桥接)与共享组件,聊天侧引导卡片需要两端接入。

具体实现方案正在评审,定稿后补充到本 issue。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions