fix(canvas): 画布智能体 - 严格校验模型选择并修正任务与 DNS 错误诊断
This commit is contained in:
@@ -9,6 +9,8 @@ description: 信封、错误码与 OpenAPI
|
||||
|
||||
机器可读规范:运行中的 `GET /api/openapi.yaml`,源文件 `backend/internal/handler/openapi.yaml`。前端 TypeScript 仍走 `web/src/services/api` 的 `http`,不从 OpenAPI 生成客户端。
|
||||
|
||||
出站模型服务域名解析失败返回 HTTP / `code: 502`、`reason: upstream_dns_failed`,不归类为用户参数错误。公开消息不包含上游域名、DNS 服务器或请求 URL;原始解析错误仅保留在内部错误链。此分类不会自动重试、切换渠道或放宽 SSRF 校验;上下文取消仍按取消处理。
|
||||
|
||||
## 站点皮肤主按钮
|
||||
|
||||
`GET /public/appearance` 返回当前 `activeSkin`;管理员通过 `GET/PUT /admin/settings/appearance` 读取、保存完整主题库。外观合同版本 8 新增 `tokens.buttons.light/dark`,字段为 `mode`(`solid|gradient`)、整数 `angle`(0–360)、HEX 色值 `start/end`、`hoverStart/hoverEnd`、`activeStart/activeEnd`、`foreground`。纯色模式使用既有主操作颜色,渐变仅用于主按钮。非法模式、角度、色值或修改锁定经典主题均拒绝保存;整块缺失的旧配置按主题身份补齐。此变更不增加数据表迁移。
|
||||
@@ -132,6 +134,8 @@ Token 报价的 `estimated` 为 `true`,`quantity` 是预留 Token 数。参考
|
||||
- `generate_media.prompt` 使用 `@图片1`、`@视频1`、`@音频1` 引用素材,各类型按 `referenceNodeIds` 的出现顺序独立编号,文本来源不占媒体编号。已有标签保留;遗漏的画布素材以“素材名称:@标签”补入 `【资产参考】`,不推断素材用途。节点入边同步排列,草稿、审批和实际任务保存同一份带标签的提示词。未绑定的媒体编号和补齐后超过16000字符的提示词会在提交前被拒绝,模型自身的提示词长度限制仍由任务准入校验。临时标注图没有持久画布节点,不自动添加无法解析的编辑器标签;历史节点不自动改写。
|
||||
- Agent 的 `snapshotHash` 忽略顶层 `viewport`、`updatedAt`。`canvas_get_state` 另返回 `mediaSnapshotHash`,供 `generate_media.snapshotHash` 使用:仅比较节点与连线,节点忽略 `position`、`width`、`height`、`createdAt`、`updatedAt`,保留全部业务字段及未知 metadata。生成草稿审批也固定该哈希,移动、调整显示尺寸、自动补时间戳和保存聊天记录不会使生成审批失效,执行保留最新展示信息;提示词、素材、锁定状态、任务绑定和连线变化仍需重新读取并审批。画布修改与撤销继续使用完整内容哈希,数据库写入保持完整快照 CAS。发布前已按旧算法生成的待审批内容可能要求重新读取和审批,不自动替换旧快照重提任务。
|
||||
- `canvas_get_state.nodes[].outputReference` 的 `ready` / `issue` 仅表示该节点产物能否作为其他生成的参考,不诊断本节点的生成输入。`generation` 返回当前画布、当前用户所属任务的 `taskId`、`taskStatus` 和安全的失败 / 取消 `error`;无任务绑定为 `not_submitted`,无法验证归属或读取失败为 `unavailable`。节点无法作为草稿提交时返回 `submitBlockedReason` / `submitBlockedIssue`,与写路径共用节点准入规则;未被阻止不等于已获授权,草稿所属运行和审批仍在提交时校验。`task_get` 同样返回安全错误详情。`generate_media` 准入失败可返回 `snapshot_conflict`、`task_bound`、`target_locked` 等结构化 `reason` 和 `nodeId`,不自动选择新节点或重新生成。
|
||||
- `task_get` / `generation` 的执行状态与回写状态分开:`succeeded` 不返回执行 `error`;回写失败仍通过 `writebackOutcome` / `writebackError` 暴露,不能因生成成功而隐藏。失败 / 取消任务保留脱敏错误,缺少详情不能伪装成成功。Agent 文本步骤的持久诊断为 `upstream_dns_failed` 时,`run_failed.reason` 同步该分类并明确提示检查渠道域名及后端 DNS,不自动重跑。
|
||||
- `generate_media` / `image_layer_split` 必须将 `model_list.selection` 展开到顶层参数:提供非空 `logicalModelId`,或完整的非空 `channelId` + `channelModelKey`,不得混用;未使用的字段可省略或传空字符串,不能传 `null` 或仅含空白的字符串。后端在读取画布、创建草稿、审批与计费前校验选择结构;返回 `reason: invalid_tool_arguments`、`field`、`issue` 和本轮工具 `parameters`,区分 `required`、`mutually_exclusive`、`type_mismatch`、`invalid_value`。合法结构不代表模型可用,仍须通过目录、能力、权限和价格校验;不猜测模型、不补全选择、不切换渠道,也不吞掉未知字段。
|
||||
- `canvas_apply_ops` 创建节点、编辑提示词或连线不会提交生成任务,也不会改变已提交任务的输入;收费生成独立使用 `generate_media`。操作参数错误按数组项返回 `field`(例如 `ops[0].snapshotHash`)和 `issue`(例如 `unexpected_field`、`type_mismatch`、`required`),并附本轮工具 schema;不把未知字段误报成缺少其他必填字段,不回显任意参数键和值。
|
||||
- `read_only` 只允许读取;`request_approval` 对写画布和媒体生成暂停为 `waiting_approval`;`auto` 可在预算内执行已授权画布操作,但图片 / 视频生成始终独立审批,不能绕过。`maxGenerationTasks` / `maxVideoSeconds` 为非负整数,0 表示该项不设业务上限,正数按本轮累计执行;不再固定 8 次模型调用、8 个生成任务或 120 秒视频。积分上限仍必填且大于 0,实际报价在任务创建与预留积分前校验,时长必须符合所选模型的实际能力。失败事件保留具体错误和已有任务的 `taskId`、`nodeId`、`status`;媒体结果的 `phase` 区分 `admission` 与 `completion`,`taskSubmitted` 表达是否已提交。已提交的收费生成失败作为工具错误交回模型,整轮保持可继续,不得自动重试收费生成;只有生成结果无法回写画布时才把整轮标为 `failed`。模型应报告错误,不能自行删减提示词。
|
||||
- 必须有当前用户已保存的画布。首轮摘要最多取前 80 个节点,并按约 60KB 预算截断;装不下的节点记入 `omittedNodes`,不因摘要过大整轮拒绝。`canvas_get_state` 可按 `offset` 每页读取 40 个节点、资产可引用状态及相关连线,按 `nodeIds` 精读最多 8 个节点(正文每字段最多 16000 字符),通过 `hasMore` / `nextOffset` 和字段 `Truncated` 判断是否完整。分镜表包含镜头、角色节点与资产绑定;摘要每页最多 20 行,精读每次 1 行,可用 `storyboardOffset` 翻页;单行叙事文本累计最多 24000 字符,角色 / 绑定各最多 16 项。上下文不含媒体 URL、任意元数据或未同步修改;节点名称不等于图像视觉识别。普通任务重试接口不能重试 Agent 任务。
|
||||
|
||||
@@ -5,6 +5,14 @@ description: 当前项目已实现功能的手工验证清单与未确认边界
|
||||
|
||||
# 待测试
|
||||
|
||||
## Agent 任务诊断与模型选择强校验
|
||||
|
||||
- 已修复:成功任务不再由空错误文本生成“任务未完成”;执行失败与回写失败独立保留。模型选择缺失、不完整、混用、`null` 和空白值在读画布及产生草稿 / 审批 / 收费任务前拒绝,返回字段级修正信息;未知字段继续拒绝,不自动选择模型或重放收费任务。
|
||||
- 已修复:出站 DNS 失败使用 `502 / upstream_dns_failed`,保留内部原因链且不公开请求地址;Agent 按持久诊断展示 DNS 原因,不修改代理、解析器、私网放行或自动重试策略。
|
||||
- [x] 本地专项回归:Agent 参数与执行流程、任务诊断、出站 DNS / 取消 / SSRF、HTTP 错误脱敏通过;缺失模型选择不会新增任务、账单、审批或画布草稿。
|
||||
- [ ] 全量回归发现 `TestDeleteGeneratedAssetTaskReferences/failed_output` 查询 `resource_deletion_jobs` 时遇到 SQLite 表锁;该用例单独复跑通过,未修改资源删除逻辑或增加重试,仍需排查并发稳定性。
|
||||
- [ ] 部署后检查真实模型渠道域名及后端 DNS;在真实 Agent 会话中验证失败提示、纠正参数后重新审批,以及成功任务与回写失败的分离展示。本地回归不等于部署 DNS 已恢复,也不替代真实供应商与浏览器验收。
|
||||
|
||||
## 画布 Agent 入口拖动
|
||||
|
||||
- [x] 右下角 Agent 图标支持鼠标和触屏拖动,使用指针捕获与 6px 阈值区分点击和拖动;拖动结束不打开面板,中断或失去捕获时结束手势,不传播到画布。
|
||||
|
||||
Reference in New Issue
Block a user