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

@@ -1,5 +1,14 @@
# Changelog
## [3.1.0] - 2026-07-18
- 结构化字段name/description/llm/persona/principles改经进程内内置工具 **ManageAgent**`update` 动作更新(白名单 + schema 校验 + 合并语义),移除对 `agent.json` / `persona.md` / `principles.md` 的直接 Write 指引
- 补充合并语义说明:结构化 persona/principles 为字段级合并省略字段保留原值、markdown 字符串为整体替换、config.llm 为增量浅合并;非法配置不落盘
- 补充确认行为更新自身免确认、更新其他智能体触发用户确认、核心智能体desirecore/core拒绝更新
- 补充错误处理config 非白名单字段被拒、schema 校验失败、部分字段写入失败仅重试失败字段
- 记忆、技能、工具等自由格式文件仍用 Read/Write 直接编辑(注意 `_protected-paths.yaml` 受保护路径),版本回滚按目标类型分流(结构化走 ManageAgent、自由文件直接写回
- 声明 `required_client_version: 10.0.90`
## [3.0.0] - 2026-03-17
- **Breaking**:从 HTTP API 迁移到 AgentFS 直接文件操作

View File

@@ -3,7 +3,7 @@ name: update-agent
description: >-
安全更新现有智能体的配置、人格、原则、技能与记忆,输出可审阅 diff 并在确认后应用与提交。Use when 用户要求修改 Agent
行为、安装/卸载技能、调整配置、回滚变更或修订规则。
version: 3.0.5
version: 3.1.0
type: meta
risk_level: low
status: enabled
@@ -14,7 +14,7 @@ tags:
- meta
metadata:
author: desirecore
updated_at: '2026-03-17'
updated_at: '2026-07-18'
i18n:
default_locale: en-US
source_locale: zh-CN
@@ -27,7 +27,7 @@ metadata:
description: >-
安全更新现有智能体的配置、人格、原则、技能与记忆,输出可审阅 diff 并在确认后应用与提交。Use when 用户要求修改 Agent 行为、安装/卸载技能、调整配置、回滚变更或修订规则。
body: ./SKILL.zh-CN.md
source_hash: sha256:a0fecd84f92204bd
source_hash: sha256:eeb2187b0f08bc47
translated_by: human
en-US:
name: Update Agent
@@ -35,9 +35,9 @@ metadata:
description: >-
Safely update an existing Agent's config, persona, principles, skills, and memory, producing reviewable diffs that are applied and committed only after confirmation. Use when the user asks to modify Agent behavior, install/uninstall skills, adjust config, roll back changes, or revise rules.
body: ./SKILL.md
source_hash: sha256:a920af860d6f6a19
translated_by: human
translated_at: '2026-05-03'
source_hash: sha256:eeb2187b0f08bc47
translated_by: ai:claude-fable-5
translated_at: '2026-07-18'
market:
icon: >-
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0
@@ -58,6 +58,7 @@ market:
verified: true
compatible_agents: []
channel: latest
required_client_version: 10.0.90
---
# update-agent skill
@@ -84,19 +85,24 @@ update-agent is a **Meta-Skill** that lets users modify various Agent configurat
- **Safe and controllable**: All changes require user confirmation, with rollback support
- **Transparent and visible**: Changes are presented as diffs, clear and obvious
- **Version management**: Versions are managed via Git, with traceable history
- **Validation backstop**: Structured fields (name/description/llm/persona/principles) go through the ManageAgent built-in tool's allowlist + schema validation; invalid config is never written to disk
## L2: Detailed Specification
### Supported Update Types
| Update Type | Target File | Risk Level | Example |
| ------------------ | --------------- | ---------- | -------------------------------------- |
| Persona update | `persona.md` | Medium | Modify communication style, values |
| Principles update | `principles.md` | High | Add/modify behavioral rules |
| Skills install | `skills/` | Medium | Add new skill package |
| Skills uninstall | `skills/` | Low | Remove skill package |
| Memory update | `memory/` | Low | Add knowledge entry |
| Tools config | `tools/` | High | Modify tool permissions |
| Update Type | Target | Update Method | Risk Level | Example |
| ----------------- | ------------------- | ------------------- | ---------- | ---------------------------------- |
| Name/Description | `agent.json` | ManageAgent update | Low/Medium | Rename, edit summary |
| LLM config | `agent.json` (llm) | ManageAgent update | Medium | Switch model, adjust temperature |
| Persona update | `persona.md` | ManageAgent update | Medium | Modify communication style, values |
| Principles update | `principles.md` | ManageAgent update | High | Add/modify behavioral rules |
| Skills install | `skills/` | Read/Write | Medium | Add new skill package |
| Skills uninstall | `skills/` | Read/Write | Low | Remove skill package |
| Memory update | `memory/` | Read/Write | Low | Add knowledge entry |
| Tools config | `tools/` | Read/Write | High | Modify tool permissions |
**Two update paths**: Structured fields (name/description/llm/persona/principles) are always updated through the `update` action of the in-process built-in tool **ManageAgent** (allowlist + schema validation + merge semantics); free-form files such as memory, skills, and tools are still edited directly with Read/Write. See "Stage 5: Apply Changes".
### Conversation Flow
@@ -198,17 +204,70 @@ diff_metadata:
### Stage 5: Apply Changes
Apply the change by reading and writing files directly through AgentFS. **Do not call HTTP APIs, and do not operate Git directly** (version management is handled automatically by the backend).
Applying a change takes one of two paths, depending on whether the target is a **structured field** or a **free-form file**. **Do not call HTTP APIs** (after instance authentication, the Agent cannot reach the machine's local HTTP API), and **do not operate Git directly** (version management is handled automatically by the backend).
> **Renaming an Agent's display name — you MUST edit two files to keep them in sync.** If the user wants to change the Agent's **display name** (e.g. "rename X to Y"), use the Edit tool to update **both**: (1) the `name` field in `agent.json`, and (2) the first-line title heading (`# Name`) in `persona.md`. Editing only one leaves the display name and the persona title out of sync. **Never claim the rename is done without actually editing the files** — if no edit runs, nothing changes on disk and the Agent list will not refresh.
#### Path A: Structured fields → ManageAgent built-in tool (mandatory)
The following fields **must** be updated through the `update` action of the in-process built-in tool `ManageAgent`. **Never** directly Write `agent.json` / `persona.md` / `principles.md`:
| Field | Constraint | Storage location |
| ------------- | ----------------------------------------------------- | ----------------- |
| `name` | 150 characters | `agent.json` |
| `description` | ≤200 characters | `agent.json` |
| `config.llm` | Incremental shallow merge; **config only allows `llm`** | `agent.json` |
| `persona` | Structured object `{L0, L1:{...}, L2}` or markdown string | `persona.md` |
| `principles` | Structured object `{L0, L1:{...}, L2}` or markdown string | `principles.md` |
**Call forms**:
```
ManageAgent(action='update', id='<agent-id>', name='New name')
ManageAgent(action='update', id='<agent-id>', description='One-line summary')
ManageAgent(action='update', id='<agent-id>', config={ llm: { model: 'xxx', temperature: 0.7 } })
ManageAgent(action='update', id='<agent-id>', persona={ L1: { personality: 'professional, rigorous' } })
ManageAgent(action='update', id='<agent-id>', principles='...(full markdown)...')
```
**Merge semantics (important)**:
- Structured `persona` / `principles` are **field-level merges**: omitted fields retain their original values (e.g. passing only `L1.personality` will not clear L0 / role)
- A markdown string is a **whole replacement** (used to rewrite the entire document)
- `config.llm` is an **incremental shallow merge**: only the keys you pass are overwritten
- The merged `agent.json` is validated against the schema as a whole; invalid config is never written to disk
**Confirmation behavior**:
- Updating **yourself** requires no secondary confirmation
- Updating **another Agent** triggers user confirmation (stacked on top of this skill's diff confirmation)
- The core Agent (`desirecore` / `core`) refuses updates
**Read before you write**: Before making a change, read the current values with `ManageAgent(action='get', id='<agent-id>')`, to generate the diff and verify field names (the actual field names of persona / principles follow the structure returned by `get`).
**config allowlist**: `config` only accepts `llm`. Passing `mcp_servers` / `tool_permissions` / `version` / `id`, etc., is rejected with the field name indicated — runtime config other than `llm` does not go through ManageAgent; see "Stage 5 · Path B" and Error Handling.
**Partial write failure**: The tool reports precisely "which fields took effect, which one failed"; on retry, **submit only the failed fields**, do not resend everything.
> **Renaming is a single call.** When the user wants to change the **display name** (e.g. "rename X to Y"), just call `ManageAgent(action='update', id='<agent-id>', name='Y')` — `name` is written to `agent.json` and triggers the Agent list to refresh; no need to manually edit any other file. If the user also wants the persona document title synced, append one `persona` update in the same round. **Never claim the rename is done without actually calling ManageAgent.**
#### Path B: Free-form files → edit directly with Read/Write
Free-form files such as memory, skills, and tools are not in ManageAgent's scope and are still edited directly with the Read/Write tools:
| Target | AgentFS path |
| ------------ | ------------ |
| Memory entry | `memory/` |
| Skill package | `skills/` |
| Tools config | `tools/` |
**AgentFS root directory**: `${DESIRECORE_ROOT}/agents/<agentId>/`
**Read file**: Use the `cat` command to read the current contents of the target file.
**Read file**: Use the Read tool to read the current contents of the target file.
**Write file**: Use a text-editing tool to write directly to the target file. After writing, re-read the file to verify the contents are correct.
**Write file**: Use the Write / Edit tool to write directly to the target file. After writing, re-read the file to verify the contents are correct.
**Note**: After writing the file directly, the backend file watcher automatically detects the change and triggers a Git commit; no manual git command is required.
**Protected paths**: Before editing, cross-check `_protected-paths.yaml`; touching a protected path should be blocked with a prompt that owner permission is required.
**Note**: After directly writing a free-form file, the backend file watcher automatically detects the change and triggers a Git commit; no manual git command is required.
### Stage 6: Receipt Generation
@@ -228,9 +287,13 @@ After a successful change, present a user-friendly receipt (do not expose intern
1. Run `git log --oneline -10` in the Agent directory to view recent version history
2. Use `git show <commit>:<file>` to fetch the file contents of the target version, and present them to the user for confirmation
3. After user confirmation, write the target version's contents to the corresponding file
3. After user confirmation, apply according to the target file type:
- **Structured fields** (`persona.md` / `principles.md` / the name/description/llm in `agent.json`) → write back with `ManageAgent(action='update', ...)` (persona / principles are **wholly replaced** with that historical content as a markdown string)
- **Free-form files** (`memory/` / `skills/`) → write back directly with the Write tool
4. Show the change diff and confirm rollback success
(`git log` / `git show` are only used to **read** history; write-back always goes through the two paths above — do not use git commands to directly rewrite working-tree files.)
```bash
# 查看版本历史
cd ${DESIRECORE_ROOT}/agents/<agentId>
@@ -246,24 +309,31 @@ git show <commit>:persona.md
**Update operation reference table**:
| User Intent | Target File | AgentFS Path |
| ---------------------------- | --------------- | ---------------------------------------------- |
| **Rename (display name)** | `agent.json` **+** `persona.md` | Edit BOTH: `name` in `agent.json` AND the `# Title` first line in `persona.md` |
| Modify personality/style | `persona.md` | `${DESIRECORE_ROOT}/agents/<agentId>/persona.md` |
| Modify behavioral rules | `principles.md` | `${DESIRECORE_ROOT}/agents/<agentId>/principles.md` |
| Install/uninstall skills | `skills/` | `${DESIRECORE_ROOT}/agents/<agentId>/skills/` |
| Modify tools config | `tools/` | `${DESIRECORE_ROOT}/agents/<agentId>/tools/` |
| Add memory | `memory/` | `${DESIRECORE_ROOT}/agents/<agentId>/memory/` |
| Modify runtime config | `agent.json` | `${DESIRECORE_ROOT}/agents/<agentId>/agent.json` |
| User Intent | Update Method |
| ------------------------------- | ----------------------------------------------------------------------- |
| **Rename (display name)** | `ManageAgent(action='update', id, name='...')` |
| Edit summary | `ManageAgent(action='update', id, description='...')` |
| Modify LLM config (model/temperature/etc.) | `ManageAgent(action='update', id, config={ llm: {...} })` |
| Modify personality/style | `ManageAgent(action='update', id, persona={...} or markdown)` |
| Modify behavioral rules | `ManageAgent(action='update', id, principles={...} or markdown)` |
| Install/uninstall skills | Read/Write `skills/` (`${DESIRECORE_ROOT}/agents/<agentId>/skills/`) |
| Add memory | Read/Write `memory/` (`${DESIRECORE_ROOT}/agents/<agentId>/memory/`) |
| Modify tools config | Read/Write `tools/` (`${DESIRECORE_ROOT}/agents/<agentId>/tools/`, mind protected paths) |
> Runtime config in `agent.json` other than `llm` (`mcp_servers` / `tool_permissions`, etc.) is currently not in the ManageAgent allowlist, and should not be written to `agent.json` directly to bypass validation. When such a need arises, explain to the user that it must be handled through the corresponding mechanism for now.
### Error Handling
| Error Scenario | Handling |
| ----------------------------------- | -------------------------------------------------------- |
| Attempt to modify a protected path | Block the operation; prompt that owner permission is required |
| File does not exist | The Agent or target file does not exist; ask user to check |
| Insufficient permission | Filesystem permission error; ask user to check directory permissions |
| Rollback target version not found | List available versions and ask the user to reselect |
| Error Scenario | Handling |
| ------------------------------------- | ------------------------------------------------------------------- |
| `config` contains a non-allowlisted field | ManageAgent rejects it and indicates the field name; switch to the corresponding mechanism or tell the user it is not yet supported |
| Schema validation fails | Invalid config is not written to disk; fix the fields per the tool's response and retry |
| Updating the core Agent (desirecore/core) | ManageAgent refuses the update; tell the user the core Agent cannot be modified |
| Partial field write failure | The tool reports which fields took effect / failed; retry only the failed fields, do not resend everything |
| Attempt to modify a protected path (free-form file) | Block the operation; prompt that owner permission is required |
| File does not exist | The Agent or target file does not exist; ask the user to check |
| Insufficient permission | Filesystem permission error; ask the user to check directory permissions |
| Rollback target version not found | List available versions and ask the user to reselect |
### Permission Requirements
@@ -286,28 +356,26 @@ git show <commit>:persona.md
**Operation flow**:
```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')
```
---
@@ -333,6 +401,14 @@ cat ${DESIRECORE_ROOT}/agents/legal-assistant/persona.md
...
```
**Apply after user confirmation**: First read the current principles with `ManageAgent(action='get', id)`, then replace the whole document (including the new rule) as a markdown string:
```
ManageAgent(action='update', id='legal-assistant', principles='...(full markdown, including the new rule)...')
```
(If you only change one field of the structured object, you can also use a field-level merge and pass `principles={ L1: { must: [...] } }` — the field names and structure follow what `get` returns.)
### Modify Existing Rule
**User input**: "Don't remind me every time, it's too verbose"
@@ -347,3 +423,5 @@ cat ${DESIRECORE_ROOT}/agents/legal-assistant/persona.md
- - 每次回答后都提醒用户检查内容
+ - 仅在重要决策时提醒用户检查内容
```
**Apply after user confirmation**: Same as above — write the modified content back with `ManageAgent(action='update', id, principles=...)`.

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=...)` 写回修改后的内容。