feat(skills): 智能体 CRUD 四技能改经 ManageAgent 内置工具(实例鉴权适配) (#52)

## 摘要 / Summary

### 中文

主仓库 desirecore#1225 新增 `ManageAgent` 内置工具后,智能体 CRUD 四技能从"调本机 HTTP
API/curl"改写为调用该工具(实例鉴权上线后 Agent 直接访问本机 API 会 401):

- **create-agent 2.5.0**:`POST /api/agents` →
`ManageAgent(action='create', ...)`;补充保留标识(core/desirecore)拒创、config 仅允许
llm 白名单的错误处理
- **delete-agent 2.5.0**:`DELETE /api/agents/:id` →
`action='delete'`(工具层强制用户确认);错误处理改为工具拒绝语义(核心智能体/自删/活跃状态);补团队级联说明
- **discover-agent 2.6.0**:`GET /api/agents(/:id)` →
`action='list'/'get'`
- **update-agent
3.1.0**:结构化字段(name/description/llm/persona/principles)改经
`action='update'`(白名单+schema 校验+字段级合并语义),自由格式文件仍 Read/Write

四技能声明 `market.required_client_version:
10.0.90`,老客户端在市场端被门控禁装。中英双语正文同步改写,i18n source_hash 已重算(validate-i18n.py
通过);manifest 1.2.10。

### English

After desirecore#1225 shipped the `ManageAgent` builtin tool, the four
agent-CRUD skills are rewritten from local-HTTP-API/curl instructions to
tool calls (direct local API access now returns 401 under instance
auth). Each skill declares `market.required_client_version: 10.0.90` so
older clients are gated from installing. Both locales are rewritten in
sync and i18n source hashes recomputed (validate-i18n.py passes);
manifest bumped to 1.2.10.

主仓库回填:合并后将在 desirecore 主仓库执行 `npm run sync-market` 生成新的
defaults/market.zip 并单独提 PR。
This commit is contained in:
2026-07-18 23:05:18 +08:00
committed by GitHub
parent ea07d05550
commit 1c00b8e6c8
13 changed files with 524 additions and 408 deletions

View File

@@ -24,19 +24,24 @@ update-agent 是一个**元技能Meta-Skill**,允许用户通过对话
- **安全可控**:所有变更需用户确认,支持回滚
- **透明可见**:变更以 diff 形式展示,清晰明了
- **版本管理**:通过 Git 管理版本,可追溯历史
- **校验兜底**结构化字段name/description/llm/persona/principles经 ManageAgent 内置工具的白名单 + schema 校验,非法配置不会落盘
## L2详细规范
### 支持的更新类型
| 更新类型 | 目标文件 | 风险等级 | 示例 |
| --------------- | --------------- | -------- | -------------------- |
| Persona 更新 | `persona.md` | 中 | 修改沟通风格、价值观 |
| Principles 更新 | `principles.md` | 高 | 添加/修改行为规则 |
| Skills 安装 | `skills/` | 中 | 添加新技能包 |
| Skills 卸载 | `skills/` | | 移除技能包 |
| Memory 更新 | `memory/` | | 添加知识条目 |
| Tools 配置 | `tools/` | | 修改工具权限 |
| 更新类型 | 目标 | 更新手段 | 风险等级 | 示例 |
| --------------- | --------------- | ------------------- | -------- | -------------------- |
| 名称/描述 | `agent.json` | ManageAgent update | 低/中 | 改名、改简介 |
| LLM 配置 | `agent.json`llm | ManageAgent update | 中 | 换模型、调温度 |
| Persona 更新 | `persona.md` | ManageAgent update | 中 | 修改沟通风格、价值观 |
| Principles 更新 | `principles.md` | ManageAgent update | | 添加/修改行为规则 |
| Skills 安装 | `skills/` | Read/Write | 中 | 添加新技能包 |
| Skills 卸载 | `skills/` | Read/Write | | 移除技能包 |
| Memory 更新 | `memory/` | Read/Write | 低 | 添加知识条目 |
| Tools 配置 | `tools/` | Read/Write | 高 | 修改工具权限 |
**两条更新路径**结构化字段name/description/llm/persona/principles一律经进程内内置工具 **ManageAgent**`update` 动作更新(白名单 + schema 校验 + 合并语义);记忆、技能、工具等自由格式文件仍用 Read/Write 直接编辑。详见「阶段 5变更应用」。
### 对话流程
@@ -138,17 +143,70 @@ diff_metadata:
### 阶段 5变更应用
通过 AgentFS 直接读写文件完成变更。**不要调用 HTTP API不要直接操作 Git**(版本管理由后端自动处理)。
变更应用分两条路径,取决于目标是**结构化字段**还是**自由格式文件**。**不要调用 HTTP API**(实例鉴权后 Agent 无法访问本机 HTTP API**不要直接操作 Git**(版本管理由后端自动处理)。
> **修改智能体显示名称 → 必须用 Edit 工具同时改两个文件保持一致。** 若用户要改 Agent 的**显示名称**(如"把 X 改名为 Y"),用 Edit 工具**同时**更新两处:①`agent.json` 的 `name` 字段;②`persona.md` 的首行标题(`# 名称`)。只改其中一个会导致显示名与人格文档标题脱节。**绝不要在没有实际编辑文件的情况下声称已改名**——不真正编辑文件则磁盘不变、智能体列表也不会刷新。
#### 路径 A结构化字段 → ManageAgent 内置工具(强制)
以下字段**必须**通过进程内内置工具 `ManageAgent``update` 动作更新,**禁止**直接 Write `agent.json` / `persona.md` / `principles.md`
| 字段 | 约束 | 落地位置 |
| ------------- | -------------------------------------- | ----------------- |
| `name` | 150 字符 | `agent.json` |
| `description` | ≤200 字符 | `agent.json` |
| `config.llm` | 增量浅合并;**config 只允许 `llm`** | `agent.json` |
| `persona` | 结构化对象 `{L0, L1:{...}, L2}` 或 markdown 字符串 | `persona.md` |
| `principles` | 结构化对象 `{L0, L1:{...}, L2}` 或 markdown 字符串 | `principles.md` |
**调用形式**
```
ManageAgent(action='update', id='<agent-id>', name='新名称')
ManageAgent(action='update', id='<agent-id>', description='一句话简介')
ManageAgent(action='update', id='<agent-id>', config={ llm: { model: 'xxx', temperature: 0.7 } })
ManageAgent(action='update', id='<agent-id>', persona={ L1: { personality: '专业、严谨' } })
ManageAgent(action='update', id='<agent-id>', principles='...(完整 markdown...')
```
**合并语义(重要)**
- 结构化 `persona` / `principles` 是**字段级合并**:省略的字段保留原值(如只传 `L1.personality` 不会清掉 L0 / role
- markdown 字符串是**整体替换**(用于整篇重写)
- `config.llm` 是**增量浅合并**:只覆盖你传入的 key
- 合并后的 `agent.json` 会整体过 schema 校验,非法配置不落盘
**确认行为**
- 更新**自身**免二次确认
- 更新**其他智能体**会触发用户确认(与本技能的 diff 确认叠加)
- 核心智能体(`desirecore` / `core`)拒绝更新
**改前先读**:改之前先用 `ManageAgent(action='get', id='<agent-id>')` 读取现值,用于生成 diff、校对字段名persona / principles 的实际字段名以 `get` 返回的结构为准)。
**config 白名单**`config` 仅接受 `llm`。传入 `mcp_servers` / `tool_permissions` / `version` / `id` 等会被拒绝并指明字段名——`llm` 以外的运行时配置不走 ManageAgent见「阶段 5 · 路径 B」与错误处理。
**部分写入失败**:工具会精确报告"哪些字段已生效、哪个失败",重试时**只提交失败字段**,不要整体重发。
> **改名一次调用完成。** 用户要改**显示名称**(如"把 X 改名为 Y")时,直接 `ManageAgent(action='update', id='<agent-id>', name='Y')` 即可——`name` 写入 `agent.json` 并触发智能体列表刷新,无需再手动编辑任何文件。若用户希望人格文档标题也同步,可在同一轮追加一次 `persona` 更新。**绝不要在没有实际调用 ManageAgent 的情况下声称已改名。**
#### 路径 B自由格式文件 → Read/Write 直接编辑
记忆、技能、工具等**自由格式文件**不在 ManageAgent 范围,仍用 Read/Write 工具直接编辑:
| 目标 | AgentFS 路径 |
| -------- | ------------ |
| 记忆条目 | `memory/` |
| 技能包 | `skills/` |
| 工具配置 | `tools/` |
**AgentFS 根目录**`${DESIRECORE_ROOT}/agents/<agentId>/`
**读取文件**:使用 `cat` 命令读取目标文件当前内容。
**读取文件**:使用 Read 工具读取目标文件当前内容。
**写入文件**:使用文本编辑工具直接写入目标文件。写入后重新读取文件确认内容正确。
**写入文件**:使用 Write / Edit 工具直接写入目标文件。写入后重新读取文件确认内容正确。
**注意**直接写入文件后,后端文件监控会自动检测变更并触发 Git 提交,无需手动执行 git 命令
**受保护路径**编辑前对照 `_protected-paths.yaml`,触及受保护路径应阻断并提示需 owner 权限
**注意**:直接写入自由格式文件后,后端文件监控会自动检测变更并触发 Git 提交,无需手动执行 git 命令。
### 阶段 6回执生成
@@ -168,9 +226,13 @@ diff_metadata:
1. 在 Agent 目录下执行 `git log --oneline -10` 查看最近的版本历史
2. 使用 `git show <commit>:<file>` 获取目标版本的文件内容,展示给用户确认
3. 用户确认后,目标版本内容写入对应文件
3. 用户确认后,目标文件类型应用:
- **结构化字段**`persona.md` / `principles.md` / `agent.json` 的 name/description/llm→ 用 `ManageAgent(action='update', ...)` 写回persona / principles 以 markdown 字符串**整体替换**为该历史内容)
- **自由格式文件**`memory/` / `skills/`)→ 用 Write 工具直接写回
4. 展示变更 diff确认回滚成功
`git log` / `git show` 仅用于**读取**历史,回写一律走上述两条路径,不要用 git 命令直接改写工作区文件。)
```bash
# 查看版本历史
cd ${DESIRECORE_ROOT}/agents/<agentId>
@@ -186,24 +248,31 @@ git show <commit>:persona.md
**更新操作对照表**
| 用户意图 | 目标文件 | AgentFS 路径 |
| -------------- | --------------- | ---------------------------------------------- |
| **改名(显示名称)** | `agent.json` **+** `persona.md` | 用 Edit 同时改:`agent.json` 的 name 字段 + `persona.md` 首行 `# 标题` |
| 修改性格/风格 | `persona.md` | `${DESIRECORE_ROOT}/agents/<agentId>/persona.md` |
| 修改行为规则 | `principles.md` | `${DESIRECORE_ROOT}/agents/<agentId>/principles.md` |
| 安装/卸载技能 | `skills/` | `${DESIRECORE_ROOT}/agents/<agentId>/skills/` |
| 修改工具配置 | `tools/` | `${DESIRECORE_ROOT}/agents/<agentId>/tools/` |
| 添加记忆 | `memory/` | `${DESIRECORE_ROOT}/agents/<agentId>/memory/` |
| 修改运行时配置 | `agent.json` | `${DESIRECORE_ROOT}/agents/<agentId>/agent.json` |
| 用户意图 | 更新手段 |
| --------------------- | ------------------------------------------------------------------------ |
| **改名(显示名称)** | `ManageAgent(action='update', id, name='...')` |
| 改简介 | `ManageAgent(action='update', id, description='...')` |
| 修改 LLM 配置(模型/温度等) | `ManageAgent(action='update', id, config={ llm: {...} })` |
| 修改性格/风格 | `ManageAgent(action='update', id, persona={...} 或 markdown)` |
| 修改行为规则 | `ManageAgent(action='update', id, principles={...} 或 markdown)` |
| 安装/卸载技能 | Read/Write `skills/``${DESIRECORE_ROOT}/agents/<agentId>/skills/` |
| 添加记忆 | Read/Write `memory/``${DESIRECORE_ROOT}/agents/<agentId>/memory/` |
| 修改工具配置 | Read/Write `tools/``${DESIRECORE_ROOT}/agents/<agentId>/tools/`,注意受保护路径) |
> `agent.json` 中 `llm` 以外的运行时配置(`mcp_servers` / `tool_permissions` 等)当前不在 ManageAgent 白名单,也不应直接 Write `agent.json` 绕过校验。遇到此类需求,向用户说明暂需通过对应机制处理。
### 错误处理
| 错误场景 | 处理方式 |
| ------------------ | -------------------------------------- |
| 尝试修改受保护路径 | 阻断操作,提示需要 owner 权限 |
| 文件不存在 | Agent 或目标文件不存在,提示用户检查 |
| 权限不足 | 文件系统权限错误,提示用户检查目录权限 |
| 回滚版本不存在 | 列出可用版本,请用户重新选择 |
| 错误场景 | 处理方式 |
| ---------------------------- | ---------------------------------------------------------- |
| `config` 含非白名单字段 | ManageAgent 拒绝并指明字段名;改走对应机制或告知用户暂不支持 |
| schema 校验失败 | 非法配置不落盘;按工具返回修正字段后重试 |
| 更新核心智能体desirecore/core | ManageAgent 拒绝更新;告知用户核心智能体不可修改 |
| 部分字段写入失败 | 工具报告已生效/失败字段;仅重试失败字段,不整体重发 |
| 尝试修改受保护路径(自由文件) | 阻断操作,提示需要 owner 权限 |
| 文件不存在 | Agent 或目标文件不存在,提示用户检查 |
| 权限不足 | 文件系统权限错误,提示用户检查目录权限 |
| 回滚版本不存在 | 列出可用版本,请用户重新选择 |
### 权限要求
@@ -226,28 +295,26 @@ git show <commit>:persona.md
**操作流程**
```bash
# 1. 读取当前 persona.md
cat ${DESIRECORE_ROOT}/agents/legal-assistant/persona.md
```
# 1. 读取当前 persona,定位要改的字段(字段名以返回结构为准)
ManageAgent(action='get', id='legal-assistant')
# 输出示例:
# # 法律顾问小助手
# ## L0
# 专业的法律咨询助手
# ## L1
# ### Role
# 法律顾问
# ### Personality
# 友好、随和
# ### Communication Style
# 轻松幽默
# 返回示例persona 部分):
# L0: 专业的法律咨询助手
# L1:
# role: 法律顾问
# personality: 友好、随和
# communicationStyle: 轻松幽默
# 2. 分析需要修改的部分,生成 diff 展示给用户确认
# 3. 用户确认后,直接编辑文件,将 Personality 和 Communication Style 修改为目标值
# 3. 用户确认后,用 ManageAgent 字段级合并更新只改这两个字段L0/role 保留)
ManageAgent(action='update', id='legal-assistant', persona={
L1: { personality: '专业、严谨', communicationStyle: '正式、克制' }
})
# 4. 验证写入结果
cat ${DESIRECORE_ROOT}/agents/legal-assistant/persona.md
# 4. 复核结果
ManageAgent(action='get', id='legal-assistant')
```
---
@@ -273,6 +340,14 @@ cat ${DESIRECORE_ROOT}/agents/legal-assistant/persona.md
...
```
**用户确认后应用**:先 `ManageAgent(action='get', id)` 取当前 principles把整篇内容含新增规则以 markdown 字符串整体替换:
```
ManageAgent(action='update', id='legal-assistant', principles='...(整篇 markdown含新增规则...')
```
(若只改结构化对象的某个字段,也可用字段级合并传 `principles={ L1: { must: [...] } }`——字段名与结构以 `get` 返回为准。)
### 修改现有规则
**用户输入**"不要每次都提醒我,太啰嗦了"
@@ -287,3 +362,5 @@ cat ${DESIRECORE_ROOT}/agents/legal-assistant/persona.md
- - 每次回答后都提醒用户检查内容
+ - 仅在重要决策时提醒用户检查内容
```
**用户确认后应用**:同上,用 `ManageAgent(action='update', id, principles=...)` 写回修改后的内容。