feat(canvas): 云端 Agent - 完成策略分层、节点能力注册与可解释审批改造

This commit is contained in:
ddCat
2026-09-14 17:58:21 +08:00
parent 9727656b2b
commit dca01886f9
65 changed files with 5347 additions and 918 deletions

View File

@@ -17,10 +17,11 @@ description: 影策后端核心持久化表与状态边界
| --- | --- | --- |
| `schema_migrations` | 保存已成功应用的结构版本、名称、校验和与时间 | 已应用版本的校验和发生变化时拒绝启动;数据库版本高于当前二进制支持版本时拒绝旧程序连接 |
| `cloud_agent_executions` | 保存 Agent 每轮的持久化执行状态、修订号和运行状态 | `(id, user_id)` 归属受服务端校验;状态通过 revision CAS 更新;`state_json` 包含技能快照、工具调用、审批、活动子任务和事件,不保存浏览器密钥 |
| `agent_profiles` | 保存用户、项目和画布层的 Agent 常驻偏好、哈希和独立 revision | `(user_id, scope, project_id, canvas_id)` 唯一;归属由 service 校验,写入使用 revision CAS;正文不能授权新能力 |
容器内命令 `migrate-schema up` 应用缺失迁移,`migrate-schema status` 输出当前和期望版本,`migrate-schema verify` 只检查兼容性。`CANVAS_AUTO_MIGRATE=true` 仅用于开发和旧部署兼容;受管生产部署设置为 `false`,并由 Compose 的一次性 `migrate` 服务先完成迁移。后续迁移必须新增版本,不得修改已经发布迁移的实现或校验和。
当前结构版本为 12。版本 2 为 `schema_migrations.applied_at` 增加 `idx_schema_migrations_applied_at` 索引;版本 3 `asset_taxonomy_candidate_identity` 为资产候选增加规范化名称和来源,收敛资产分类,并为待确认候选建立项目内部分唯一索引;版本 4 `resource_upload_key` 为资源上传幂等补充 `resources.upload_key` 列和用户维度唯一索引;版本 5 `payment_topup` 创建积分充值、支付通知和对账所需结构;版本 6 `resource_playback_variant` 增加资源播放副本状态;版本 7 `asset_library_folders` 增加用户素材自定义分类及 `assets.folder_id`;版本 8 `logical_model_active_code` 将前台模型 code 的唯一约束限定为未归档记录;版本 9 `channel_presentation` 为渠道添加 `public_alias`(默认空字符串)与 `sort_order`(默认 0),为渠道模型添加 `sort_order`(默认 0),不重写既有凭据、价格或能力配置;版本 10 `creation_runtime` 创建创作运行与提交表,并为任务增加可空且唯一的 `creation_submission_id`,旧任务无需伪造提交标识即可继续使用;版本 11 `cloud_agent_runtime` 创建 `cloud_agent_executions`,保存 Agent 的 durable runtime 状态和 revision CAS 信息;版本 12 `agent_token_charge_limit` 为账单增加可空语义的 `charge_limit_microcredits`,仅 Agent Token 任务写入非零值,将服务端预授权报价固化为最终用户扣费上限。
当前结构版本为 15。版本 2 为 `schema_migrations.applied_at` 增加 `idx_schema_migrations_applied_at` 索引;版本 3 `asset_taxonomy_candidate_identity` 为资产候选增加规范化名称和来源,收敛资产分类,并为待确认候选建立项目内部分唯一索引;版本 4 `resource_upload_key` 为资源上传幂等补充 `resources.upload_key` 列和用户维度唯一索引;版本 5 `payment_topup` 创建积分充值、支付通知和对账所需结构;版本 6 `resource_playback_variant` 增加资源播放副本状态;版本 7 `asset_library_folders` 增加用户素材自定义分类及 `assets.folder_id`;版本 8 `logical_model_active_code` 将前台模型 code 的唯一约束限定为未归档记录;版本 9 `channel_presentation` 为渠道添加 `public_alias`(默认空字符串)与 `sort_order`(默认 0),为渠道模型添加 `sort_order`(默认 0),不重写既有凭据、价格或能力配置;版本 10 `creation_runtime` 创建创作运行与提交表,并为任务增加可空且唯一的 `creation_submission_id`,旧任务无需伪造提交标识即可继续使用;版本 11 `cloud_agent_runtime` 创建 `cloud_agent_executions`;版本 12 `agent_token_charge_limit` 为账单增加 Agent Token 收费上限;版本 13 `cloud_agent_canvas_mutation` 持久化 Agent 画布变更;版本 14 `cloud_agent_recovery_control` 增加运行恢复控制字段和旧运行回填;版本 15 `agent_profiles` 创建常驻偏好表。已发布版本的实现和校验和不得修改。
历史发布曾使用版本 6 `asset_library_folders`,之后合并引入了上述 6/7 顺序冲突。迁移器仅在该历史记录的名称和校验和均精确匹配时选择历史顺序:保留版本 6 的素材目录记录及时间,在版本 7 应用 `resource_playback_variant`,再继续版本 8。新数据库及已采用“6 播放副本、7 素材目录”的数据库保持原顺序;状态检查与启动校验采用同一套识别规则。未知名称、被改动的校验和或冲突的版本 7 记录仍会拒绝迁移,不通过删除、改名或伪造已应用记录绕过检查。

View File

@@ -9,7 +9,7 @@ description: 从产品功能快速定位主要代码入口
## 前端页面
云端 Agent:`web/src/components/canvas/canvas-cloud-agent-panel.tsx` 协调对话、Skills 和审批,`services/api/agent.ts` 适配运行快照与事件流;后端 `handler/agent.go` 负责 HTTP 合同,`app/cloud_agent.go` 负责权限、幂等、可信历史与画布摘要,`app/cloud_agent_runtime.go` 负责持久化模型循环,`app/cloud_agent_tools.go` 负责技能快照、画布工具和生成工具,`app/task_creation.go` 执行预算 admission,运行沿用任务 Worker。协议见 HTTP API 专题,未确认的真实登录态与上游联调见待测试清单。
云端 Agent:`web/src/components/canvas/canvas-cloud-agent-panel.tsx` 协调对话、Skills 和审批,`canvas-cloud-agent-settings.tsx` 编辑长期偏好,`services/api/agent.ts` 适配运行快照与事件流;画布手工编辑与引用同步共用 `web/src/lib/canvas/canvas-node-prompt.ts`,已有媒体结果只更新 `composerContent` 草稿,不覆盖生成结果和已提交提示词。后端 `handler/agent.go` 负责 HTTP 合同,`app/cloud_agent.go` 负责权限、幂等、可信历史,`app/cloud_agent_profile.go` / `repository/agent_profile.go` 管理用户、项目、画布偏好及 revision CAS,`internal/prompts/agent-*-policy.md` 是随发布物编译、并在文档头声明 ID/版本的行为资源,`app/cloud_agent_policy.go` 编译本轮策略快照,`internal/canvas/capability/` 注册服务端节点能力和字段映射,`app/cloud_agent_canvas_state.go` 投影画布摘要和精读,`app/cloud_agent_runtime.go` 负责持久化模型循环,`app/cloud_agent_tools.go` 根据能力定义生成工具 schema,并从固定技能快照渐进读取 `SKILL.md` / reference,`app/cloud_agent_media.go` 负责收费媒体任务适配,`app/task_creation.go` 执行预算 admission,运行沿用任务 Worker。节点新增需要能力描述符和真实画布实现;新生成模式还需任务适配器,不由偏好或技能 md 授权。协议见 HTTP API 专题,未确认的真实登录态与上游联调见待测试清单。
| 功能 | 页面入口 | 主要协作模块 |
| --- | --- | --- |

View File

@@ -14,12 +14,15 @@ description: 信封、错误码与 OpenAPI
所有 `/agent` 路径都需要登录 Cookie。`GET /agent/capabilities` 返回当前版本(2)、权限模式、上下文范围、技能和工具清单。Agent 运行由服务端任务 Worker 驱动,浏览器断开不会停止运行。
- `POST /agent/runs` 创建一轮;`POST /agent/runs/:id/messages` 以上一轮为父节点创建新的不可变轮次,两者返回 `{ run }`,追加后必须使用新的 `run.id` 订阅。
- 请求字段:`canvasId`、`prompt`、受管 `logicalModelId` 或 `channelId` + `channelModelKey`、`permissionMode: "read_only" | "request_approval" | "auto"`、`skillIds`、`contextScope: [] | ["canvas"]`、`budget: { maxCredits, maxGenerationTasks, maxVideoSeconds }`、`idempotencyKey`。不接受密钥、自定义 URL、客户端历史或未知字段。
- 同用户同幂等键及相同请求返回同一运行;不同请求复用键返回 409。失败后重试同一提交应保留键。上一轮未完成时禁止追加;成功轮次历史从服务端加载,最多携带 8 对历史消息及 64KB 历史 JSON,超限提示新建对话。
- 创建和追加消息可传 `thinking: boolean`(默认关闭),贯穿首轮及工具后续模型调用;内置 Chat Completions、Responses、Claude 协议复用文本推理配置,上游模型仍需支持。声明式 Agent 渠道暂不支持,开启时明确报错,不静默忽略。思考模式可能增加耗时和费用。
- 已安装且属于当前用户的技能会在创建时固定版本快照,模型只能通过 `skill_read_file` 读取快照文件。技能正文是不可信输入,不能改变权限或系统规则。
- 当前工具为 `canvas_get_state`、`skill_read_file`、`task_get`、`model_list`、`canvas_apply_ops`、`generate_media`。画布写入工具要求本轮授权 `contextScope: ["canvas"]`。禁止 shell、任意网络请求和外部 MCP。
- `canvas_apply_ops` 必须带 `snapshotHash`,每批最多 20 项;支持新增文本、Markdown、图片、视频、音频、分组与分镜表节点,以及 `connect_nodes` 引用连线。媒体占位节点的 `content` 是提示词,不是媒体 URL;只建节点不提交收费生成。`update_node` 仅允许更新未锁定文本 / Markdown 的标题和正文;禁止删除、任意元数据写入、自连接、重复边与不存在的端点。
- 请求字段:`canvasId`、`prompt`、受管 `logicalModelId` 或 `channelId` + `channelModelKey`、`permissionMode: "read_only" | "request_approval" | "auto"`、`reasoningMode: "off" | "auto" | "deep"`、`profileRevision`、`skillIds`、`contextScope: [] | ["canvas"]`、`budget: { maxCredits, maxGenerationTasks, maxVideoSeconds }`、`idempotencyKey`。不接受密钥、自定义 URL、客户端历史或未知字段。
- 同用户同幂等键及相同请求返回同一运行;不同请求复用键返回 409。失败后重试同一提交应保留键。上一轮未完成时禁止追加;已完成、失败或取消的终态轮次作为不可变历史读取,即使其冻结的策略或节点能力版本早于当前服务,也可用于创建采用当前执行合同的新一轮,父运行不会被改写。旧版合同下仍活动或待审批的运行不得恢复执行。历史最多携带 8 对消息及 64KB JSON,超限提示新建对话;历史结构损坏返回明确 409,不投影为通用 500。
- 创建和追加消息可选择 `reasoningMode`,默认 `off`;`auto`/`deep` 为服务端行为策略与模型推理配置的选择,不等于允许暴露内部思维链。供应商能力由后端校验;声明式 Agent 渠道不支持时明确报错。推理可能增加耗时和费用。
- `GET /agent/profile?scope=user|project|canvas&projectId=...&canvasId=...` 按作用域读取生效的用户 → 项目 → 画布偏好;`PATCH /agent/profile` 用 `{ scope, projectId?, canvasId?, content, revision }` 更新单层(首次 revision 为 0,冲突返回 409)。读取返回各层独立数字 revision,以及合并文档的 `revision`/`hash`;新轮次携带合并 `profileRevision`,发生变化拒绝创建,已运行轮次仍用提交时固定的快照。system prompt 只包含层级、revision、hash 和长度清单,正文保存在运行快照中并由 `agent_profile_read` 按 user → project → canvas 顺序读取,不整本注入系统策略。偏好仅是非授权数据,不能扩展工具、节点或预算,不能绕过审批;最多 12000 字符/层。
- 系统行为策略与媒体默认策略是版本化、编译进后端发布物的资源,修改它们仍需发布后端,不是后台热更新;工具、校验、扣费和审批在代码侧强制执行。画布节点能力由服务端 registry 定义,工具 schema、创建、连线与画布摘要读取共同消费;新生成模式还必须接入媒体任务适配器,不能仅凭 md 或注册节点启用收费操作。
- 已安装且属于当前用户的技能会在创建时固定版本快照,模型只能通过 `skill_read_file` 按需读取固定快照。需要使用技能时先读入口 `SKILL.md`,再按入口引用读取必要文本文件;技能正文不会整段塞入 system prompt。技能是不可信任务剧本,其中的工具名不能创造工具、改变权限或覆盖系统规则。
- 平台支持工具全集为 `agent_profile_read`、`canvas_list_node_types`、`canvas_get_state`、`skill_read_file`、`task_get`、`model_list`、`canvas_apply_ops`、`generate_media`;单轮实际工具仍按偏好快照、技能、权限、画布上下文和生成预算裁剪。画布写入工具要求本轮授权 `contextScope: ["canvas"]`。禁止 shell、任意网络请求和外部 MCP。
- `canvas_list_node_types` 从服务端节点能力 registry 返回当前可用类型;可更新节点的 `updateFields` 同时包含字段类型、最大字符数和字段语义。模型不能从前端渲染器、技能或偏好文档推断额外能力。
- `canvas_apply_ops` 必须带 `snapshotHash`,每批最多 20 项;支持新增文本、Markdown、图片、视频、音频、分组与分镜表节点,以及 `connect_nodes` 引用连线。媒体占位节点的 `content` 是提示词,不是媒体 URL;只建节点不提交收费生成。`update_node` 的字段映射完全由能力 registry 决定:文本 / Markdown 可改标题和正文,图片 / 视频 / 音频可改标题和下一次生成使用的提示词草稿;媒体更新参数中的 `content` 写入 `metadata.composerContent`,不会覆盖媒体结果 `metadata.content`、已提交提示词 `metadata.prompt`、任务状态或引用状态。锁定节点、删除、任意元数据写入、自连接、重复边与不存在的端点仍被服务端拒绝。
- `model_list` 复用生成面板的当前模型目录。每项的 `selection` 是 `logicalModelId` 或 `channelId` + `channelModelKey`,工具调用必须原样选择一种,不猜 ID 或混用;能力、规格、价格与任务准入再次核对。
- `generate_media` 支持图片 / 视频:必填 `mode`、`prompt`、`size`、`durationSeconds`(图片为 0)、`snapshotHash`、新 `nodeId`、`title`、有序 `referenceNodeIds`(无参考传空数组),再加一种模型选择;可传来源节点 `sourceNodeId`、`quality`、视频 `videoGenerateAudio`。`sourceNodeId` 仅接文本 / 镜头提示词节点;参考图片、视频、音频只放 `referenceNodeIds`,无文本来源时留空且不重复传入。引用从当前画布节点的账号资源解析,校验归属、类型、就绪状态和模型能力,不接受任意 URL。图片生成仅接图片参考;视频可按模型能力接图片、视频、音频参考。
- 参数选择与收费授权分开:用户明确说“随便 / 你决定 / 按默认”时,Agent 可从当前目录选择能力及预算匹配的模型,优先用户最近明确使用的可用模型,其次价格清楚的低成本选项;支持时沿用参考图原始比例,否则选目录默认,时长用目录默认。未要求音频且模型不支持时用默片。用户接受已推荐方案后不再要求特定确认口令;仅真正缺失或冲突的阻塞项一次性询问。本轮已有目录结果应复用。以上是 Agent 的参数选择策略,服务端仍强校验具体规格,不提供绕过预算 / 能力校验的默认兜底,也不绕过独立收费审批。
@@ -30,14 +33,15 @@ description: 信封、错误码与 OpenAPI
- `GET /agent/runs/:id` 返回运行信息;`POST /agent/runs/:id/cancel` 取消当前运行及活动子任务;`POST /agent/runs/:id/approvals/:approvalId/decision` 接受 `{"decision":"approve"|"reject","reason":"..."}`,审批决定幂等且服务端校验归属。
- `GET /agent/runs/:id/events` 返回 `agent_event` 和首次 / 状态版本变化时的紧凑 `run_snapshot` SSE;无变化时只发送 heartbeat。事件 `Seq` 在运行内递增;支持 `?after=` / `Last-Event-ID`,游标不是运行 ID。`cleanupPending: true` 时即使运行已进入终态也会继续推送,直到后台收尾完成。前端应以快照恢复状态,代理只对这一精确路径关闭缓冲。
- `generation_task_created` 携带 `canvasId`、`nodeId`、`taskId`、`title`、`mode`、`referenceNodeIds`。草稿、提交、画布工具写入,以及媒体成功 / 失败 / 取消的真实节点变更,均在画布写入与运行检查点的同一事务持久化 `canvas_updated`。节点已删除或换任务时不伪造更新;`run_failed` 本身不代表节点媒体任务失败。
- `canvas_updated` 包含 `canvasId`、`operation`、`callId`、`actions` 和 `canvasPatch`。`canvasPatch` 为 `{ canvasId, updatedAt, nodes: [{ before, after }], connections: [{ before, after }] }`;新增对象的 `before` 为 `null`,仅包含有变化的节点和连线。当前工具不开放删除。`actions` 固定保存操作类型、节点 ID、标题、类型,引用操作还带目标节点 ID,供历史消息显示和点击定位;`callId` 用于合并同一画布操作的工具完成消息。
- `approval.preview` 和 `canvas_updated.actions` 是服务端根据同一解析、快照与 Capability 规划流程生成的解释信息,不是授权凭证。审批卡片明确列出新增/修改节点、节点类型、修改字段、名称变化和连线两端;执行事件保存同样的可读信息,供历史消息显示和点击定位。实际写入仍重新校验用户归属、`snapshotHash`、Capability、节点锁、预算和审批 `callHash`。
- `canvas_updated` 包含 `canvasId`、`operation`、`callId`、`actions`、可选的 `preview`/`text` 和 `canvasPatch`。`canvasPatch` 为 `{ canvasId, updatedAt, nodes: [{ before, after }], connections: [{ before, after }] }`;新增对象的 `before` 为 `null`,仅包含有变化的节点和连线。当前工具不开放删除。节点 action 保存操作、节点 ID、执行前标题、类型、修改字段和可选的修改后标题;引用 action 同时保存来源与目标节点 ID、标题和类型,不要求前端从内部 ID 猜测对象。`callId` 用于合并同一画布操作的工具完成消息。
- 前端对增量按 40ms 窗口合批,三方合并远端基线、当前 Store 和编辑器,正常完成 / 失败无需全量 GET;保留无关节点编辑、拖动与视口,同字段冲突、删除或新任务绑定不强行覆盖。只有事件缺口、断流、增量冲突或没有增量的事件源需要全量校准,同一画布协调器最多每秒发起一次,单请求在途,期间重复通知合并为一次尾随校准。已识别增量协议后,相邻 `tool_failed` / `run_failed` 不重复触发整图刷新。
- Agent 创建 / 续聊请求在客户端先持久化完整正文、幂等键、父运行和消息 ID,再提交;网络超时或响应丢失只允许用同一正文和 key 有界重放,不能换 key 生成新收费轮次。待确认记录损坏时对话暂停发送,不把它当成“从未提交”。
- Agent 创建 / 续聊请求在客户端先持久化完整正文、幂等键、父运行和消息 ID,再提交;网络超时或响应丢失只允许用同一正文和 key 有界重放,不能换 key 生成新收费轮次。客户端区分“服务端已明确返回错误”和“未收到服务端确认”,不再把 HTTP 409/500 一律描述成请求未确认。待确认记录损坏时对话暂停发送,不把它当成“从未提交”。
- 生成按钮与提交入口共用节点任务状态:排队 / 运行中不可重复生成,终态解除任务锁,历史 `taskId` 不永久禁用。聊天留痕保留节点名、引用与失败任务 ID,点击使用现有画布聚焦;已删除节点只提示,不自动重建。聊天缓存不重复保存增量中的完整节点正文。
Agent 的聊天列表缓存只负责 UI 恢复;运行、技能快照、审批、工具调用、子任务和事件均以服务端持久化状态为准。提交响应丢失时,客户端应使用同一幂等键重试,不生成新的提交。
Skills 的 `tool_completed` / `tool_failed` 事件附带 `skillId`、`skillName`(已启用技能)和 `path`;空路径表示列目录,不表示已读取文件。目录结果中的 `files` 为本轮固定快照的可读路径,空数组时应使用已加载正文继续。同一运行内同技能同路径只允许请求一次(包括不存在的路径),重复请求返回工具失败和继续执行指引,状态随运行持久化。模型初始上下文包含技能 ID 和可读文件清单。
Skills 的 `tool_completed` / `tool_failed` 事件附带 `skillId`、`skillName`(已启用技能)和 `path`;空路径表示列目录,不表示已读取文件。目录结果中的 `entryPath` 固定为 `SKILL.md`,`files` 为本轮固定快照的可读路径;Agent 先读取入口,再按入口引用读取必要文件。同一运行内同技能同路径只允许请求一次(包括不存在的路径),重复请求返回工具失败和继续执行指引,状态随运行持久化。模型初始上下文只包含技能版本、哈希、入口和可读文件清单,不包含技能正文。
模型任务失败的 `run_failed` 事件保留 `taskId`,并提供安全分类 `reason`:`model_connection_reset`、`model_request_timeout`、`model_connection_refused` 或 `model_task_failed`。`text` 不透传原始上游错误,避免泄露地址和凭证;前端用事件类型而非摘要关键词判断工具成功 / 失败。失败不会触发自动付费重试。

View File

@@ -5,9 +5,9 @@ description: 当前项目已实现的核心工作台能力与使用入口
# 功能清单
## 云端 Agent(只读阶段,待真实环境验收)
## 云端 Agent(写入与生成仍待真实环境验收)
浮窗支持移动、调整大小和浏览器偏好恢复;聊天发送后跟随到底部,上翻阅读时暂停跟随。后端已接入持久化的逐轮对话、可信历史、取消和文本事件回放,可分析已保存画布的有限摘要。每条消息独立检查固定计价预算;审批、Skills、MCP、画布写入及媒体生成尚未开放,不应按完整工具 Agent 使用。
浮窗支持移动、调整大小和浏览器偏好恢复;后端支持逐轮对话、可信历史、取消、Skills 快照、画布摘要/精读、审批后的画布写入及媒体生成。终态旧轮次按其冻结合同保留为不可变历史,新消息使用当前合同创建新轮,不篡改父运行;旧合同下仍活动或待审批的运行不会被新版服务恢复执行。生成由预算和独立审批控制,画布写入使用内容快照哈希;未开放外部 MCP。系统行为策略以版本化资源发布,用户/项目/画布可编辑常驻偏好;偏好正文固定在运行快照并按层只读,不整段塞入 system prompt,也不能提权或跳过审批。节点创建、更新字段、摘要投影和连线限制来自服务端能力 registry;图片、视频和音频节点可安全修改标题与下一版提示词草稿,既有媒体、已提交提示词和任务状态不会被草稿编辑覆盖。审批和执行记录明确展示目标节点、类型、修改字段、名称变化及连线两端,前端不再依靠内部 ID 猜测;这些预览不替代服务端归属、快照、Capability、锁、预算与调用哈希校验。真实模型计费与浏览器联调仍待验收。
## 画布智能引用
@@ -87,7 +87,7 @@ SEO 标题、描述、可选关键词会投影到浏览器 metadata、Open Graph
当前操作包括:章节资产提取、分镜规划/修复、分镜首帧、分镜视频、角色卡提取、角色三视图、短剧大纲、技能草稿。短剧一句话生成和技能库 AI 草稿只提交 `promptTemplateOperation` 与变量,占位 prompt 不会成为模型看到的正文。
画布内置预设、反推提示词、工作流起步稿、文本改写包装、视频操作包装和字幕高亮指令属于客户端目录 `web/src/lib/prompts`。云端 Agent 的系统提示词、工具权限和计费规则由后端运行时统一控制,不由浏览器覆盖。
画布内置预设、反推提示词、工作流起步稿、文本改写包装、视频操作包装和字幕高亮指令属于客户端目录 `web/src/lib/prompts`。云端 Agent 的行为策略在后端版本化 md 资源中,用户常驻偏好可编辑;工具权限和计费规则仍由服务端代码强制执行,不由浏览器或偏好文档覆盖。
### 相关实现

View File

@@ -5,6 +5,21 @@ description: 当前项目已实现功能的手工验证清单与未确认边界
# 待测试
## 云端 Agent 行为、能力和偏好分层(待真实环境验收)
- [x] 系统/媒体行为资源由后端发布物加载,运行快照记录策略和能力版本/哈希;用户 → 项目 → 画布偏好经归属校验和独立 revision CAS,合并 revision 固定到新轮次,旧轮次保留原快照。system prompt 只注入偏好清单,正文由 `agent_profile_read` 从固定快照按层读取。工具 schema、节点类型、可写字段和画布读取来自服务端节点能力 registry;收费生成还需实际媒体任务适配器。写入、审批与预算仍以服务端强校验为准。
- [x] 数据库 append-only 迁移 v15 为关闭自动迁移的部署创建 `agent_profiles`;OpenAPI、功能清单、代码地图和数据库文档已同步。相关 Go 专项测试与前端构建结果以本次交付记录为准。
- [x] 图片 / 视频 / 音频能力描述符允许更新标题和下一版提示词草稿,`content` 经字段合同映射到 `metadata.composerContent`;服务端回归测试覆盖失败视频节点,确认媒体结果、已提交 `prompt`、任务状态和引用问题不被覆盖。前端手工编辑与引用同步也已收敛到统一提示词写入器,纯函数测试覆盖三种媒体、空草稿、仅 storageKey 图片和文本节点。
- [x] 终态旧 Capability 轮次可作为不可变历史创建当前合同的新轮,父运行保持原始 JSON;旧合同活动运行会明确终止,不恢复模型或工具执行。历史结构损坏改为 409,不再落成通用 500。客户端提交错误区分服务端明确失败和未收到响应。
- [x] 审批预览与实际画布写入共用解析/校验/规划路径并固定 `callHash`;审批卡和 `canvas_updated.actions` 均携带节点标题、类型、修改字段、修改后标题及引用连线两端。解释信息不授权能力,执行仍校验归属、快照、Capability、锁和预算。
- [ ] 在备份后的隔离 PostgreSQL 部署执行 `migrate-schema up` 和 `migrate-schema verify`,确认 v14→v15 后原有 Agent 轮次可查,新用户/项目/画布偏好能独立更新且不串账号。
- [ ] 在真实登录态检查偏好编辑、并发冲突、三层继承、SSE 重连及续聊:修改偏好后新轮次使用新版本,旧轮次历史保持原样;试图在偏好中要求越权工具、跳过审批、任意 URL 或提升预算应被服务端拒绝。
- [ ] 使用真实模型、计费与画布验证 read_only / request_approval / auto、节点精读/分页和 image/video/audio 生成的审批、收费限额、引用边界与失败恢复。静态测试不等于生产验收;系统策略 md 当前不是后台热更新。
- [ ] 在真实画布分别选择失败和已完成的图片 / 视频 / 音频节点,让 Agent 修改标题与下一版提示词:编辑框应显示新草稿,旧媒体仍可预览或播放,已提交提示词、任务状态和引用状态保持不变;刷新后结果一致。
- [ ] 对锁定媒体节点执行同类更新应被拒绝;尝试经 Agent 修改媒体 URL、`storageKey`、任务字段或其他未登记 metadata 也应被服务端拒绝,不能因 `content` 草稿别名扩大写权限。
- [ ] 更新后重启本地后端,用调试包中的已完成父轮次 `ag045cb29d5cebb44cb42cedb235d2fc5a` 续发“继续操作”:应创建当前 Capability 合同的新轮,不再返回“系统处理失败”;父轮次状态和冻结合同保持不变。
- [ ] 在真实审批和执行结果中确认:更新节点显示执行前名称、节点类型、修改字段和修改后名称;新增连线显示来源与目标标题/类型,点击可定位对应节点;普通 UI 不暴露完整内部 ID。
## Agent 增量联动与可点击操作留痕
- 服务端将草稿、提交和媒体成功 / 失败 / 取消的节点增量与运行检查点一起持久化;前端 40ms 合批投影,不按每条完成 / 失败事件全量刷新。缺口、断流或冲突才单请求校准,发起间隔至少 1 秒,期间重复通知仅保留一次尾随校准。
@@ -41,7 +56,7 @@ description: 当前项目已实现功能的手工验证清单与未确认边界
- [ ] Agent 工具调用后的下一轮模型请求:Chat Completions 的 `tool_calls` 补齐 `type: "function"`,Claude 保留 `tool_use`;真实渠道连续调用与失败任务重新发起待验收。
- [ ] 后端重启窗口内读取已加入 Skills:对 5xx 做最多 3 次有限重试,恢复后清除旧错误卡;裸代理 502 不再展示 Axios 英文错误。需在重启后端期间打开 Agent 面板确认自动恢复且不污染对话。
- [ ] Skills 工具回归:空目录显示“无可读参考文件”,实际读取显示技能名与路径;失败事件不再出现成功摘要。同一轮同技能同路径的重复请求被拒绝,并引导使用历史结果 / 已加载正文;刷新恢复后仍保留去重状态。
- [ ] Skills 工具回归:目录始终列出固定快照入口 `SKILL.md`,Agent 先读入口再读取必要 reference;实际读取显示技能名与路径,失败事件不再出现成功摘要。同一轮同技能同路径的重复请求被拒绝,并引导使用历史结果;刷新恢复后仍保留去重状态。技能正文不整段进入 system prompt,入口中的未知工具名不能突破本轮工具清单。
- [ ] 模型断连回归:连接重置、超时、拒绝连接显示安全分类和模型任务 ID,未知错误仍引导任务中心排查;不向聊天面板暴露原始上游地址或密钥。不自动重试或恢复旧失败运行。
- [x] Skills 反馈专项:前端 19 项工具摘要 / 错误语义 / 审批与布局测试通过,前端构建通过;后端 `TestCloudAgent` 专项通过,覆盖空目录、重复路径持久化、不同技能与文件隔离、缺失文件反馈,以及模型失败事件与脱敏。未调用真实模型或重启现有服务,真实浏览器验收仍待完成。
- `/api/agent` 已注册能力、创建、追加消息、读取、取消、审批与事件流路由;一条消息对应一个持久化 `canvas_text` 任务,`cloud_agent_executions` 保存模型循环、工具、审批和事件状态,复用现有 Worker 与扣费事务。