Merge remote-tracking branch 'upstream/main'
This commit is contained in:
@@ -26,6 +26,12 @@ description: 云端画布 Agent 的行为策略、上下文来源、运行提醒
|
||||
|
||||
## 用户目标与参考素材
|
||||
|
||||
### 视频首尾帧
|
||||
|
||||
`generate_media` 支持可选的 `videoStartFrameNodeId` 和 `videoEndFrameNodeId`。每个非空值必须是 `referenceNodeIds` 中已解析的图片引用,仅用于视频。参考数组决定素材编号,两个帧字段决定用途;在提示词中写“图片1作为首帧”不会自动选择首帧。
|
||||
|
||||
只编辑、不生成时,先用 `canvas_apply_ops` 建立图片到视频节点的引用连线,再通过 `update_node.patch` 设置同名字段;空字符串取消选择。节点读取会返回当前帧选择,生成审批也会显示首尾帧节点。生成工具仍需明确传入本次选择,不会根据历史提示词猜测用途;原有权限、素材归属、审批和计费流程不变。
|
||||
|
||||
- 新消息只覆盖与之冲突的旧要求。“继续”“可以”仍结合历史理解,不丢弃有效约束;已送达的运行中插话也进入后续可信历史。
|
||||
- 当前用户请求保留在 user 消息及运行记录里,不复制进 system 提示锁定目标。系统上下文只包含可验证事实,素材标题、摘要和标签编码为 JSON 数据。
|
||||
- 删除原先通过“参考图”“图生视频”等关键词推断强制引用的逻辑,否定句和概念解释不再被代码标记为引用任务。
|
||||
@@ -46,6 +52,8 @@ description: 云端画布 Agent 的行为策略、上下文来源、运行提醒
|
||||
|
||||
自动回归覆盖新目标继承、插话保留、否定参考需求、消息来源、计划取消、有界催办、恢复事件及 OpenAI Chat/Responses、Claude、Gemini 协议转换。测试使用临时 SQLite 和模拟模型结果,不证明真实模型的创作质量或指令遵循率。
|
||||
|
||||
当前系统策略版本为 6、编译器为 `cloud-agent-policy-compiler/v4`。不涉及数据库表结构或 HTTP API 变更。既有冻结合同校验仍生效:旧版本正在执行或等待审批的运行不能由新版服务继续执行;终态历史仍可读取,新消息建立使用新合同的运行。发布前应处理在途运行;回滚同样受版本校验限制,不应改写历史快照来强行恢复。
|
||||
当前系统策略版本为 13、编译器为 `cloud-agent-policy-compiler/v5`。助手身份由服务端从外观配置读取 `canvas.agentName`,通过执行上下文的 `agentIdentity.name` 提供;字段只表示名称,不能更改行为规则或工具权限。每个新回合重新读取配置,已完成对话的后续回合使用最新名称;身份变化改变规范系统提示及对应缓存键,不覆盖历史消息或冻结快照。
|
||||
|
||||
不涉及数据库表结构或 HTTP API 变更。既有冻结合同校验仍生效:旧版本正在执行或等待审批的运行不能由新版服务继续执行;终态历史仍可读取,新消息建立使用新合同的运行。发布前应处理在途运行;回滚同样受版本校验限制,不应改写历史快照来强行恢复。
|
||||
|
||||
本轮治理覆盖对话主链路。批量创作表的业务默认词、个人记忆压缩专用提示词属于独立生成入口,尚未迁移到版本化资源;后续应分别明确空提示词语义和结构化输出合同,并建立真实模型场景评估,不能把本轮回归称为全仓提示词治理完成。
|
||||
|
||||
@@ -5,6 +5,18 @@ description: 影策后端核心持久化表与状态边界
|
||||
|
||||
# 后端数据库
|
||||
|
||||
## 分片上传预留
|
||||
|
||||
Schema 45 新增 `upload_reservations`:`id`、`user_id`、`size`、`day`、`expires_at`。创建会话时在数据库事务内检查并行会话数、现有资源容量、未到期预留和每日上传用量,更新既有 `user_daily_upload_usages` 后插入预留。SQLite 先取得写锁,PostgreSQL 使用账号级事务 advisory lock。
|
||||
|
||||
资源变为 ready 与删除对应预留在同一事务中提交;普通资源上传及生成结果的容量提交也使用同一锁,并计入分片预留。沿用 `UserStoredFileBytes` 的 ready 物理对象去重口径,不改变容量配置。跨 UTC 日期完成时重新预留当天日额度并释放原日额度,失败则整体回滚。
|
||||
|
||||
预留有效期 90 分钟。失败或会话删除时释放原日额度;再次创建该账号会话时清理已到期预留。进程重启不批量删除其他实例的预留。分片文件与路由会话仍在本机,需要粘性路由;崩溃后的残片需要部署侧临时目录清理策略,未增加跨实例文件恢复或启动时全局清扫。
|
||||
|
||||
## 更新公告配置
|
||||
|
||||
外观 JSON 合同版本 10 新增 `updates`:`enabled`、`currentVersion`、`releases`。每个版本保存 `id/version/title/date/blocks`,内容块保存 `id/type/text/resourceId/caption/layout`;公共媒体 URL 由服务端按当前引用生成,不保存客户端 URL。关闭开关保留公告和资源引用,只关闭公共展示。不增加数据库表或 schema 迁移。
|
||||
|
||||
## 画布 Agent 外观配置
|
||||
|
||||
`system_settings` 的 `appearance` JSON 合同版本 9 新增 `canvas`:助手名称、入口标签、面板标题、欢迎文案、输入提示、`avatarType`(`orb|live2d`)、`avatarHeight`(120–360)、`live2dResourceId` 和服务端确认的 `live2dEntry`。独立于站点品牌;缺失时读取内置画布默认值。不新增数据库结构迁移,不改变全局 schema 版本。
|
||||
@@ -13,9 +25,17 @@ description: 影策后端核心持久化表与状态边界
|
||||
|
||||
后端通过 GORM 管理 SQLite 与 PostgreSQL 表结构。结构变化由 `migrate-schema` 按版本顺序执行并写入 `schema_migrations`;受管生产部署在 Backend 启动前运行独立迁移服务,Backend 只校验当前 Schema 是否与二进制兼容。业务写路径必须通过 service 和 repository 的状态约束,不能直接依赖前端状态。
|
||||
|
||||
## 素材资源引用边界
|
||||
|
||||
资源引用快照同时读取素材表现的 `resource_id` 和 `metadata_json`(包括嵌套资源字段);不能先按 `resource_id` 过滤表现记录,否则仅在 metadata 中引用的共享资源会漏检。素材批量删除保留其他素材仍引用的资源;管理员删除也复用这一引用边界。
|
||||
|
||||
## 结构迁移与版本
|
||||
|
||||
当前结构版本为 34。版本 34 `task_media_recovery` 为 `tasks` 增加 `media_recovery_json`(text)和 `media_stage`(最长 24 字)。版本 33 `oauth_state_accepted_terms` 为 `o_auth_states` 增加非空布尔列 `accepted_terms`,默认 `false`,不替历史流程补造同意记录。升级前备份,按既有流程执行 `migrate-schema up` 和 `verify` 后再启动新后端。旧版本二进制不支持版本 34,回退需恢复匹配的数据库备份。
|
||||
当前结构版本为 42。版本 42 `cloud_agent_pi_sessions` 新增 `cloud_agent_pi_sessions` 表,按运行 ID 保存 Pi 原生 JSONL 会话快照、用户 ID、乐观并发 revision 和更新时间;会话正文由 Agent runtime 管理,Go 只将其作为不透明快照读写,不替代有界控制检查点、事件日志或任务记录。版本 41 `resource_thumbnail` 为 `resources` 增加缩略图元数据。版本 40 `builtin_skill_tombstones` 新增内置技能删除记录,管理员删除平台技能后,后续启动同步不会重新创建该技能;版本 39 `skill_library_categories` 新增 `skill_library_categories` 表,并为 `user_skill_states` 增加 `library_category_id`,保存个人技能库分类及每个用户对技能的归类;分类不改变 `skills.tag` 的技能广场共享分类。版本 38 `prefixed_id_sequence_reconcile` 创建(若缺失)并校准 `id_sequences`:`CHANNEL`、`MODEL`、`PTIER`、`ATTEMPT`、`LMODEL`、`REVISION`、`ROUTE` 按对应业务表的最大有效 ID 前移,包含软删除记录,不回退已有序列、不重写业务 ID。分配新 ID 时再次校准并检查冲突;SQLite → PostgreSQL 迁移完成后也校准序列。
|
||||
|
||||
版本 36 `cloud_agent_gemini_cache` 创建 `cloud_agent_gemini_caches`,保存用户范围内的官方 Gemini 缓存元数据;版本 37 `cloud_agent_gemini_cache_identity` 将缓存标识约束修正为 `(user_id, cache_key)`,移除旧的全局 cache_key 唯一索引。版本 35 `auth_notifications` 为认证通知与组合验证补齐 `auth_verifications`、`notification_quotas`、`sms_channels`、`sms_records` 四张表,并为 `users` 增加 `phone`、`email_verified_at`、`phone_verified_at`,为 `email_verification_codes` 增加 `attempts`;同时创建非空手机号唯一索引。版本 34 `task_media_recovery` 为 `tasks` 增加 `media_recovery_json`(text)和 `media_stage`(最长 24 字)。版本 33 `oauth_state_accepted_terms` 为 `o_auth_states` 增加非空布尔列 `accepted_terms`,默认 `false`,不替历史流程补造同意记录。
|
||||
|
||||
升级前备份,按既有流程执行 `migrate-schema up` 和 `verify` 后再启动新后端。旧版本二进制不支持版本 42,回退需恢复匹配的数据库备份,并评估备份之后的新写入;不能只切回旧镜像。关闭自动迁移的生产环境必须运行正式迁移;手工改表不能更新 `schema_migrations` 的版本与校验和记录。
|
||||
|
||||
### 生成成功后的作品保存恢复
|
||||
|
||||
@@ -31,7 +51,7 @@ description: 影策后端核心持久化表与状态边界
|
||||
| 表 | 用途 | 关键边界 |
|
||||
| --- | --- | --- |
|
||||
| `schema_migrations` | 保存已成功应用的结构版本、名称、校验和与时间 | 已应用版本的校验和发生变化时拒绝启动;数据库版本高于当前二进制支持版本时拒绝旧程序连接 |
|
||||
| `cloud_agent_executions` | 保存 Agent 每轮的持久化执行状态、修订号和运行状态 | `(id, user_id)` 归属受服务端校验;状态通过 revision CAS 更新;`state_json` 包含技能快照、工具调用、审批、活动子任务和事件,不保存浏览器密钥 |
|
||||
| `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;正文不能授权新能力 |
|
||||
| `agent_lessons` | 用户私有的 Agent 记忆。Agent 写入待审,用户自己批准后才会注入该用户的会话 | 按 `author_user_id` 隔离;写入机械脱敏;`steps_json` 存路线;`hits` 是主动查阅、`injected` 是自动注入;管理员可按用户查看和删除,不能代批 |
|
||||
| `agent_memory_settings` | 用户私有的记忆压缩周期、文本模型和最近一次压缩任务状态 | 主键 `user_id`;压缩结果只在 `compact_task_id` 匹配时应用到该用户已批准记忆 |
|
||||
@@ -129,7 +149,10 @@ docker compose -f docker-compose.deploy.yml up -d backend web
|
||||
| `skills` | 保存技能公开元数据、当前版本指针、来源和 GitHub 同步状态 | `instruction` 仅保留入口 `SKILL.md` 的兼容投影;目录文件不展开写入该字段 |
|
||||
| `skill_versions` | 保存每次安装、编辑或同步形成的不可变技能版本 | 记录内容哈希、入口路径、规范化 ZIP 的存储键、文件数、总大小和 GitHub commit |
|
||||
| `skill_files` | 保存某个版本的文件索引 | `(skill_version_id, path)` 唯一;只保存路径、类型、MIME、大小和 SHA-256,不保存正文 |
|
||||
| `user_skill_states` | 保存用户的加入、收藏、安装版本和自动更新选择 | 技能正文读取仍经过公开性和归属校验,不能通过文件接口绕过私有技能权限 |
|
||||
| `skill_library_categories` | 保存个人技能库分类和管理员创建的平台分类 | personal 分类按用户隔离;platform 分类对所有用户可见;分类名在用户可见范围内唯一,删除分类只清除归类引用 |
|
||||
| `user_skill_states` | 保存用户的加入、收藏、安装版本、自动更新选择及该用户对技能的技能库分类 | `library_category_id` 属于用户技能库元数据,不修改 `skills.tag` 等技能广场共享分类;技能正文读取仍经过公开性和归属校验 |
|
||||
|
||||
技能库分类由 schema migration 39 创建/扩展;内置技能删除记录由 schema migration 40 创建。删除分类时在事务内清空对应 `user_skill_states.library_category_id` 后删除分类记录,不会级联删除任何技能。删除内置技能时写入 tombstone,后续启动同步会跳过该技能。
|
||||
|
||||
规范化技能包保存在后端数据目录的 `skill-packages/<skill-id>/<version-id>.zip`,数据库只保存索引和版本指针。上传 ZIP 时强制校验 `SKILL.md`、路径越界、软链接、重复路径、文件数量和解压大小;GitHub 技能保存公开仓库、分支、子目录和提交 SHA,后台每 6 小时检查一次开启自动更新的技能,并记录最近检查、同步时间及失败状态。
|
||||
|
||||
@@ -282,3 +305,9 @@ Schema 32 为 `channel_models` 新增 `tags`(TEXT、NOT NULL、默认 `'[]'`
|
||||
- 启动幂等装载 87 个预设(风格 45、运镜 33、九宫格 9),不下载第三方媒体。显式 ID 与用户工具冲突时启动报错,不覆盖用户数据;PostgreSQL 同步自增序列。
|
||||
- 工具预览纳入资源引用检查;自定义预览必须是当前用户已上传完成的资源。公开工具暂不接受私人预览资源。
|
||||
- SQLite → PostgreSQL 迁移包含上述两表。首次启动前备份测试数据;回退旧代码不能视为数据库降级,应使用备份恢复,不手工重写迁移记录。
|
||||
|
||||
## 可选技能策展
|
||||
|
||||
迁移 46 新增 skill_curation_settings、skill_curation_categories、skill_curation_assignments;默认关闭,不导入技能内容。表结构与事务规则见 [平台技能策展](./skill-curation)。
|
||||
|
||||
迁移 47 依赖 46,新增 skill_curation_roots 与 skill_curation_root_assignments;保留原五个根 ID,根停用时使用派生默认桶,根表为空回落固定五类。
|
||||
|
||||
@@ -7,7 +7,9 @@ description: 助手名称、文案、模型导入和运行库部署
|
||||
|
||||
管理员在「站点及外观 → 画布配置」设置助手名称、入口文字、面板标题、欢迎标题、欢迎说明和输入提示。助手名称独立于站点品牌,例如站点为“影策”、助手为“小鱼”。文案中的 `{agentName}` 会替换为助手名称,并作为普通文本渲染。
|
||||
|
||||
这些字段只改变展示,不改历史对话、模型提示词、AI 自我介绍、技能或工具权限。运行中插话提示保留原有操作说明。入口文字和欢迎说明允许留空。
|
||||
助手名称同时用于界面文案和 AI 自我介绍。服务端在每个新回合从同一份外观配置读取名称,将其作为 JSON 名称数据加入内置身份规则;站点品牌、模型供应商、个人设定和历史回复中的旧名称不覆盖它,也不将名称解释为行为指令。
|
||||
|
||||
保存后当前页面立即更新,其他已打开页面在重新获得焦点、切回前台或刷新时读取最新配置;刷新失败保留已有名称。新对话和已有对话的后续回合使用新名称,正在执行的回合保留创建时的身份快照,历史消息不重写。其他文案字段仍只改变展示,技能和工具权限不变。运行中插话提示保留原有操作说明。入口文字和欢迎说明允许留空。
|
||||
|
||||
## 模型来源与授权
|
||||
|
||||
|
||||
@@ -5,6 +5,12 @@ description: 从产品功能快速定位主要代码入口
|
||||
|
||||
# 代码功能地图
|
||||
|
||||
## 自定义更新公告
|
||||
|
||||
- 后台编辑:`web/src/pages/admin/settings/components/update-announcement-editor.tsx`;版本、排序与草稿校验:`web/src/lib/update-announcement.ts`。
|
||||
- 统一入口与弹窗:`web/src/components/layout/app-changelog-modal.tsx`、`app-changelog-dialog.tsx`;图文视频展示:`update-announcement-content.tsx`。
|
||||
- 服务端持久化、校验、公开投影及媒体访问:`backend/internal/app/appearance_updates.go` 与 `appearance.go`;HTTP 边界:`backend/internal/handler/appearance.go`。
|
||||
|
||||
## 画布 Agent 配置与 Live2D
|
||||
|
||||
- 后台入口:`web/src/pages/admin/settings/appearance-settings-page.tsx` 与 `components/canvas-appearance-editor.tsx`。
|
||||
@@ -16,7 +22,7 @@ description: 从产品功能快速定位主要代码入口
|
||||
|
||||
## 前端页面
|
||||
|
||||
云端 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,`app/cloud_agent_lessons.go` / `app/cloud_agent_memory_compact.go` / `repository/agent_lesson.go` / `handler/agent_lesson.go` 管理用户私有记忆的写入脱敏、召回注入、用户自审批与压缩优化,`web/src/pages/settings/agent-memory-pane.tsx` 是用户批准/添加/导入导出/压缩入口,`web/src/pages/admin/components/agent-lessons-panel.tsx` 是管理员按用户查看入口,`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 专题,未确认的真实登录态与上游联调见待测试清单。
|
||||
云端 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,`app/cloud_agent_lessons.go` / `app/cloud_agent_memory_compact.go` / `repository/agent_lesson.go` / `handler/agent_lesson.go` 管理用户私有记忆的写入脱敏、召回注入、用户自审批与压缩优化,`web/src/pages/settings/agent-memory-pane.tsx` 是用户批准/添加/导入导出/压缩入口,`web/src/pages/admin/components/agent-lessons-panel.tsx` 是管理员按用户查看入口,`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_pi_coordinator.go` 负责可恢复编排,原生 Pi runtime 协议适配位于 `internal/agent/runtime/` 与 `agent-runtime/pi/agent-runtime.mjs`;`cloud_agent_pi_sessions` 独立保存原生 JSONL 会话,控制检查点仍由 Go 管理。工具根据能力定义生成 schema,并从固定技能快照渐进读取 `SKILL.md` / reference;`app/cloud_agent_media.go` 负责收费媒体任务适配,`app/task_creation.go` 执行预算 admission,运行沿用任务 Worker。节点新增需要能力描述符和真实画布实现;新生成模式还需任务适配器,不由偏好或技能 md 授权。协议见 HTTP API 专题,未确认的真实登录态与上游联调见待测试清单。
|
||||
|
||||
| 功能 | 页面入口 | 主要协作模块 |
|
||||
| --- | --- | --- |
|
||||
@@ -43,7 +49,7 @@ description: 从产品功能快速定位主要代码入口
|
||||
| 职责 | 代码位置 |
|
||||
| --- | --- |
|
||||
| 页面装配和跨域动作协调 | `web/src/pages/canvas/project.tsx` |
|
||||
| 画布领域规则和生成协议 | `web/src/lib/canvas/canvas-project-domain.ts`、`canvas-project-generation.ts` |
|
||||
| 画布领域规则和生成协议 | `web/src/lib/canvas/canvas-project-domain.ts`、`canvas-project-generation.ts`、`produced-model.ts` |
|
||||
| 项目恢复、持久化和项目级动作 | `web/src/pages/canvas/use-canvas-project-lifecycle.ts` |
|
||||
| 云端版本校验与冲突草稿 | `web/src/services/user-data-sync.ts`、`canvas-sync-drafts.ts`、`web/src/lib/canvas/canvas-content.ts`、`web/src/pages/canvas/canvas-sync-status.tsx` |
|
||||
| 历史树与独立只读预览 | `web/src/pages/canvas/canvas-version-history.tsx`、`canvas-version-preview.tsx`;后端 `internal/canvas/canvas_history.go` 与 `repository/canvas_history.go`,Agent 写入桥接在 `app/canvas_bridge.go` |
|
||||
@@ -84,6 +90,8 @@ description: 从产品功能快速定位主要代码入口
|
||||
|
||||
## 后端调用链
|
||||
|
||||
AutoDL 画面规格由 `app/model_capability_screen_spec.go` 读取官方插件工作流合同,校验所选分辨率及默认值;`task_creation.go` 在价格选择之前归一化,任务校验与 `provider_video.go` 再次使用同一规则。前端 `lib/video-screen-specs.ts` 管理插件预设、所选规格与工作流切换,`ModelCapabilityEditor` 复用到系统及自定义渠道;无开关或独立草稿。
|
||||
|
||||
```text
|
||||
HTTP 请求 -> handler -> service(稳定导入面 / 别名)-> app(组合根)-> 业务域包 -> repository/model
|
||||
|
|
||||
@@ -107,6 +115,7 @@ HTTP 请求 -> handler -> service(稳定导入面 / 别名)-> app(组合
|
||||
| `auth` | 登录注册、OAuth、邮件验证码、LibTV/TapNow 导入 | **已抽出**:`internal/auth` |
|
||||
| `canvas` | 画布公开分享、媒体引用守卫、用户画布/素材库同步 | **已抽出**:`internal/canvas` |
|
||||
| `assets` | 资源 URL/引用解析、流式交付类型 | **部分抽出**:`internal/assets`;OSS/配额/转码仍在 `app` |
|
||||
| `agentcontext` | Agent 上下文检查点的编码、解析与压缩提示词(provider 中立,不含触发与调度) | **已抽出**:`internal/agentcontext`;触发、暂停与恢复在 `app/cloud_agent_context_compaction.go` |
|
||||
|
||||
组合根原则:`service.New`(委托 `app.New`)组装各域服务;coordinator 不得再持有整个 `*Service` 回灌域包。
|
||||
|
||||
@@ -150,3 +159,9 @@ HTTP 请求 -> handler -> service(稳定导入面 / 别名)-> app(组合
|
||||
- 任务入队 `internal/app/task_creation.go` 与生成执行 `internal/app/provider.go` 共用严格 token 解析。
|
||||
- 前端 `canvas-tool-presentation.ts` 共享轻量展示配置,`canvas-resource-references.ts` 统一 token;节点提示词与工具面板共用同一持久状态,不复制到 metadata 风格字段。
|
||||
- `canvas-workspace-panel.tsx` 提供常驻左侧菜单,按需挂载节点、资产、工具、任务和历史面板;资产面板复用素材分页服务与画布插入合同;主分支项目章节侧栏与工作区互斥。
|
||||
|
||||
## 技能策展
|
||||
|
||||
`internal/skills/skill_curation.go` 负责校验,`internal/repository/skill_curation.go` 负责分类持久化与 CAS 审计交易,handler/app bridge 接入原有技能域。
|
||||
|
||||
`skill_curation_roots.go` 扩展动态根维护、有效根查询和空表回落;数据库迁移 47 接续 46。
|
||||
|
||||
@@ -5,6 +5,24 @@ description: 信封、错误码与 OpenAPI
|
||||
|
||||
# HTTP API 合同
|
||||
|
||||
## 注册邮箱等价检查
|
||||
|
||||
公开注册与邮箱绑定的唯一性检查将 `gmail.com` 和 `googlemail.com` 视为同一域,移除本地部分的点及 `+` 后缀。例如 `a.b+x@googlemail.com` 与 `ab@gmail.com` 不允许创建两个账号。其他域保留点和 `+`;现有域名白名单规则保持不变。
|
||||
|
||||
邮箱原值仍按原有小写、去首尾空格规则保存。登录、密码重置、验证码收件地址保持精确邮箱匹配,避免既有重复别名账号被合并或错误授权。已存在的重复账号不迁移、不删除、不重新发放注册奖励;它们会阻止相同规范信箱的新注册。写入前在事务内重新检查,以覆盖不同实例使用不同验证码的并发注册。无数据库结构迁移;唯一性由公开注册与绑定的事务入口保证,直接 SQL 写入不属于该约束入口。
|
||||
|
||||
## 分片上传配额
|
||||
|
||||
`POST /resources/uploads` 在接收分片前预留整个文件的日额度和账号容量。文件大小必须严格小于 `resourceUploadMB`;同一账号最多 32 个未到期会话,跨后端实例共同计数。未满足配额的请求不会创建分片目录。分片和完成请求按会话串行执行;会话过期或已完成返回 404,重新创建会话后可整传重试。
|
||||
|
||||
完成上传时以数据库事务提交容量并消费预留,使用既有资源幂等标识。失败释放预留;跨 UTC 日期完成需要通过当天日额度检查。请求与响应字段不变。
|
||||
|
||||
## AutoDL 视频画面规格配置
|
||||
|
||||
渠道模型的 `capabilityConfig.video.resolutions` 与 `defaultResolution` 直接表示所选完整分辨率与默认值,始终生效;不再使用或返回 `customSizeEnabled`、`customScreenSpec`。AutoDL v2.3.0 未声明独立比例参数,因此 `ratios` 为空、`defaultRatio` 为空字符串,横竖与方形由完整分辨率标签表达。
|
||||
|
||||
服务端返回 `fixedScreenSpec` 供前端展示插件预设;写入时重新读取官方插件的当前工作流规格,不信任客户端传入的固定值。所选列表必须非空且属于插件预设,默认值必须属于所选列表;大小写归一化为插件原始标签。任务创建在价格选择前清空无效的 `size`、归一化 `vquality`;自动选择使用配置的默认值,不支持的显式选择被拒绝。价格档可保留全部插件预设,但任务和模型目录只采用所选列表。数据库继续使用现有能力 JSON 字段,无新增表或迁移。
|
||||
|
||||
路径前缀是 `/api`。前后端一起发布,不按 `/api/v1`、`/api/v2` 做路径版本。不兼容变更随版本一起改接口和调用方。
|
||||
|
||||
机器可读规范:运行中的 `GET /api/openapi.yaml`,源文件 `backend/internal/handler/openapi.yaml`。前端 TypeScript 仍走 `web/src/services/api` 的 `http`,不从 OpenAPI 生成客户端。
|
||||
@@ -13,6 +31,37 @@ description: 信封、错误码与 OpenAPI
|
||||
|
||||
模型 HTTP 失败及经过 Provider 错误转换的业务失败,在通用提示后追加经过过滤的 `;上游:具体原因`,供任务错误和画布卡片展示内容安全、提示词、尺寸等可操作信息。只读取上游 `error` / `message` / `msg` / `detail` 消息字段,不回传整个 JSON;消息中的 HTTP(S) URL 隐藏,包含余额、账务、凭据、请求诊断或 HTML 的消息不追加原文,保留通用分类提示。后台响应拦截规则仍对最终用户文案生效;不会修改历史任务错误或改变重试、退款策略。
|
||||
|
||||
## 资源访问与 OSS/CDN 分发
|
||||
|
||||
普通上传、分片合并及 URL 导入按内容签名识别 MIME,不以客户端声明或文件扩展名决定媒体类型;无法识别的内容仍可作为附件上传。上传标识对应的 ready/failed 重试均先读取内容,并核对检测后的 MIME、资源类型与大小;不一致返回 409,不覆盖原对象。这是内容判型与元数据一致性校验,不是完整格式解码或内容摘要去重。
|
||||
|
||||
非媒体文件(包括可执行脚本的 SVG)通过平台本地读取或代理交付,强制 `Content-Disposition: attachment` 与 `Content-Security-Policy: sandbox; default-src 'none'`,不向浏览器或访问描述返回其 OSS/CDN 直链。普通图片、音频及视频保持原有媒体分发规则。历史资源不在本次变更中批量重新判型。
|
||||
|
||||
资源展示、播放、下载、复制地址和模型输入统一消费资源访问合同,不在客户端通过 `direct=1`、`proxy=1` 或存储厂商规则选择出口。
|
||||
|
||||
- `POST /api/resources/access` 要求登录,请求体为 1–100 项 `{ resourceId, purpose?, variant? }`。`purpose` 支持 `display`、`copy`、`download`、`browser-process`、`provider-input`;`variant` 支持 `original`、`playback`、`thumbnail`(缩略图未生成前回落原件,`fallbackReason` 为 `thumbnail_not_ready`)。每项独立返回 `access` 或结构化 `error`。
|
||||
- `access.delivery` 为 `cdn`、`origin`、`platform-local` 或 `platform-proxy`。媒体配置了可用 CDN 时返回 CDN 地址;OSS 源站签名是源站直连,不等于 CDN。媒体的 `requireCDN` 开启且 CDN 鉴权不完整时失败,不静默回源。浏览器媒体的展示、复制、下载和本地处理不使用 `platform-proxy`,正文由 OSS/CDN 直接发送;`allowPrivateProxy` 允许服务端在 `provider-input` 场景读取私有媒体源站。非媒体附件始终通过平台控制响应头,不受上述媒体直连规则影响。
|
||||
- `expiresAt` / `refreshAt` 只描述当前授权有效期。有效期来自后台「资源与请求策略」(`provider-input` 与其余签名访问分别配置,默认均为 4 小时);公开 CDN 可没有 `expiresAt`。签名地址不写入画布或服务端持久化内容。
|
||||
- `display`、`copy`、`browser-process` 的源站签名把签名起始时间对齐到有效期 1/4 的时间窗(按 Unix 纪元对齐),过期时间为窗口起点加有效期:同一窗口内重复签发得到逐字节相同的 URL,刷新画布或多实例签发都能命中浏览器 HTTP 缓存;签名同时携带 `response-cache-control=private, max-age=<有效期>, immutable`,由对象存储回写缓存头。`download` 与 `provider-input` 仍按当前时间签发,不带缓存覆盖。
|
||||
- `GET /api/resources/:id/file` 仍是稳定平台入口,负责本地/平台代理字节流,可直连的云媒体返回 307 到 CDN 或对象存储,非媒体附件走平台流;`?access=1` 只返回访问描述,不打开正文。`Range` 只影响字节流路径。
|
||||
- 公共资源、画布分享、外观、公告、管理员资源和日志媒体复用同一个 HTTP 执行器。公共签名链接受自身到期时间和变体绑定限制,但已签发的外部 URL 不承诺立即撤销。
|
||||
|
||||
当前自动签名能力:公开 CDN、七牛私有下载签名和对象存储源站签名。阿里云/腾讯云私有 CDN 签名尚未自动支持,不能仅填写 CDN 域名就宣称已命中 CDN。真实 CORS、Range、CDN 命中率及账单收益必须在实际云环境通过浏览器网络记录和服务端流量观测验收。
|
||||
|
||||
## 画布资源完整性与 409
|
||||
|
||||
画布写入在保存历史快照前校验当前文档中的资源引用;引用须属于当前用户且处于 `ready`。引用收集器递归遍历受支持的资源字段,因此 `nodes[节点 ID].metadata.videoPreview.storageKey` 等嵌套派生封面也会参与检查。历史快照保存会一并校验新版本引用;若资源在保存期间缺失或状态变化,事务回滚,画布 revision 不递增。
|
||||
|
||||
HTTP 409 不能一概解释为 revision 冲突:普通版本冲突使用 `reason: conflict`;资源完整性失败使用 `reason: canvas_history_resources_missing`,并在 `details` 中返回 `resourceIds` 和 `missingResources`(含资源 ID、JSON 路径、节点 ID、引用类型及 `source`)。客户端应按 `reason` 分流,不解析 `msg` 猜测原因。显式资源修复写入仅允许历史 preimage 存在缺失资源,不允许新画布仍引用缺失资源,也不绕过 revision CAS。
|
||||
|
||||
运维扫描/修复仅处理当前画布中可安全清除的失效 `videoPreview`;不删除主媒体、不扫描并改写所有历史快照,也不替代备份。使用目标数据库对应的新版本二进制,先在维护窗口备份并执行只读扫描:
|
||||
|
||||
```sh
|
||||
CANVAS_BACKEND_DATA_DIR=/明确的数据目录 ./migrate-schema repair-canvas-resources
|
||||
```
|
||||
|
||||
复核 JSON 报告后,只有 `repairable` 项可由明确授权的操作员再次运行 `repair-canvas-resources --apply`。命令要求显式配置 `CANVAS_BACKEND_DATA_DIR` 或 `DATABASE_URL`,逐画布按版本 CAS 保存并保留原始历史;有未解决主媒体/素材绑定问题时以非零退出,不会自动恢复或重传。发生并发编辑时停止并重新扫描,不能用强制覆盖代替恢复有效历史或重新上传。
|
||||
|
||||
## 生成成功后的重试保存
|
||||
|
||||
`POST /tasks/:id/recover-media` 无需请求体。当前用户只能恢复自己有保存恢复记录的失败任务;重入队仍返回原任务 ID,不请求重新生成、不新建计费订单。已排队、运行或完成时幂等返回当前任务。取消任务、已退款订单、任务/账单归属不一致、项目已删除或归档时拒绝恢复。
|
||||
@@ -41,18 +90,28 @@ description: 信封、错误码与 OpenAPI
|
||||
- 物理空间由后台删除队列异步释放,失败保留任务重试;接口成功不代表对象存储已经清理完成。未选中素材使用的资源,以及其他 Resource 行(包括其他用户)复用的物理对象继续保留。
|
||||
- 旧画布 / 任务 / 历史快照记录本身保留,但被删媒体链接将失效。此操作不可恢复;没有数据库结构迁移。
|
||||
|
||||
## 密码登录限流
|
||||
|
||||
`POST /auth/login` 保留 IP 总请求限制与十分钟账号请求限制。同一 IP 下,用户名和邮箱解析为同一用户时共享账号计数;不存在的账号仍按去除首尾空白、转小写后的输入计次。错误密码与不存在的账号使用相同的 401 响应,达到限额后均返回 429,不返回限流键或用户身份。计数仍涵盖所有登录请求,成功不清零。
|
||||
|
||||
## 注册服务协议
|
||||
|
||||
`POST /auth/register` 的 JSON 请求必须携带布尔值 `acceptedTerms: true`,首次创建管理员也适用。缺省、`false` 或 `null` 均按未同意处理,在创建用户、消费验证码和创建会话前返回 HTTP 400,提示“请先同意影策服务协议”。原有注册开放、邮箱白名单、验证码与限流校验继续生效。
|
||||
`POST /auth/register` 的 JSON 请求必须携带布尔值 `acceptedTerms: true`,首次创建管理员也适用。缺省、`false` 或 `null` 均按未同意处理,在创建用户、消费验证码和创建会话前返回 HTTP 400,提示“请先同意<协议名称>”。原有注册开放、邮箱白名单、验证码与限流校验继续生效。
|
||||
|
||||
`GET /auth/linuxdo/start` 可携带 `acceptedTerms=true`,只有该精确值表示同意。服务端将标志写入一次性的 OAuth state;回调仅在新建 Linux.do 用户时要求该 state 已同意,不从回调参数重新取值。已有 Linux.do 用户可从登录页继续登录,无需传此参数;同意协议不绕过注册关闭策略。
|
||||
|
||||
注册页的协议名称为《影策服务协议》。正文暂留空,由维护者在 `web/src/pages/auth/register.tsx` 的 `SERVICE_AGREEMENT` 中手动填写正式条款并审核后再发布;占位提示不是正式协议。当前只校验本次注册的同意标志,不保存长期协议版本或签署凭证。前后端需一起更新,旧客户端缺少同意标志时无法注册。
|
||||
协议名称与正文由管理员在 `PATCH /admin/settings/registration` 配置,公开读取面是 `GET /auth/settings` 的 `agreementTitle`、`agreementContent`。`agreementTitle` 未配置时按当前外观品牌名生成“<品牌名>服务协议”,因此外观改名后注册页文案同步;接口返回的标题不含书名号,由注册页补《》。`agreementContent` 支持多段文本,按空行分段渲染,留空时注册页提示“服务协议内容待补充”。
|
||||
|
||||
读取注册配置失败(如 JSON 损坏)时,`RegistrationAgreement` 返回空标题而不是品牌名兜底标题,注册页据此隐藏协议入口并提示可重新读取,避免展示后台并不存在的协议名称;此时错误提示统一回落为“请先同意服务协议”。
|
||||
|
||||
`PATCH /admin/settings/registration` 的两个协议字段为可选指针语义:不提交表示保留已保存内容,提交空串表示明确清空。注册开关与协议正文可以分开保存,单独切换 `enabled` 不会覆盖协议。当前只校验本次注册的同意标志,不保存长期协议版本或签署凭证。前后端需一起更新,旧客户端缺少同意标志时无法注册。
|
||||
## 站点皮肤主按钮
|
||||
|
||||
### 画布配置与 Live2D(外观合同版本 9)
|
||||
### 画布配置、更新公告与 Live2D(外观合同版本 10)
|
||||
|
||||
`GET /public/appearance` 和管理员 `GET /admin/settings/appearance` 返回 `canvas`;管理员通过 `PATCH /admin/settings/appearance` 随外观配置统一保存。字段为 `agentName`(1–24 字)、`launcherLabel`(0–24 字)、`panelTitle`(1–40 字)、`welcomeTitle`(1–100 字)、`welcomeDescription`(0–200 字)、`inputPlaceholder`(1–160 字)、`avatarType`(`orb|live2d`)、`avatarHeight`(120–360 整数)、`live2dResourceId`、`live2dEntry`。入口由服务端核验覆盖;Live2D 无有效资源时拒绝启用。配置不修改 Agent 系统提示词。
|
||||
外观设置新增 `updates: { enabled, currentVersion, releases }`,由管理员通过 `PATCH /admin/settings/appearance` 保存;关闭开关保留草稿,但 `GET /public/appearance` 返回关闭状态与空公告列表,前端恢复内置更新日志。开启时公开版本与内容块,当前版本须对应公告版本。媒体上传、管理员预览、公开引用读取及限制详见 [自定义更新公告](/docs/backend/update-announcements)。JSON 请求上限为 512KB;无数据表迁移。
|
||||
|
||||
`GET /public/appearance` 和管理员 `GET /admin/settings/appearance` 返回 `canvas`;管理员通过 `PATCH /admin/settings/appearance` 随外观配置统一保存。字段为 `agentName`(1–24 字)、`launcherLabel`(0–24 字)、`panelTitle`(1–40 字)、`welcomeTitle`(1–100 字)、`welcomeDescription`(0–200 字)、`inputPlaceholder`(1–160 字)、`avatarType`(`orb|live2d`)、`avatarHeight`(120–360 整数)、`live2dResourceId`、`live2dEntry`。入口由服务端核验覆盖;Live2D 无有效资源时拒绝启用。名称以数据形式投影到每轮 Agent 执行上下文,不提供自由系统提示词配置,也不改变工具权限。
|
||||
|
||||
- `POST /admin/settings/appearance/live2d`:管理员 multipart `file` 上传,受上传频率和配额限制。成功信封的 `data.model` 为 `{ resourceId, entry }`,上传不会发布。ZIP 限 128 MiB、256 条目、解压合计 384 MiB、单文件 128 MiB;只接收 model3/MOC3/PNG/JSON,拒绝路径穿越、脚本和外部资源。
|
||||
- `GET /admin/settings/appearance/live2d/:id/*file`:管理员预览,校验资源归属;其他管理员仅能查看当前外观已引用模型。
|
||||
@@ -137,7 +196,7 @@ Token 报价的 `estimated` 为 `true`,`quantity` 是预留 Token 数。参考
|
||||
|
||||
| 接口 | 行为 |
|
||||
| --- | --- |
|
||||
| `GET /canvas-projects/:id` | 返回当前内容及权威版本号 |
|
||||
| `GET /canvas-projects/:id` | 返回当前内容及权威版本号;响应包含基于数据库 `revision` 的弱 `ETag` 和 `Cache-Control: private, no-cache`。请求可用 `If-None-Match` 做条件读取,版本未变化时返回无正文的 `304`。 |
|
||||
| `GET /canvas-projects/:id/history` | 返回 `snapshots` 摘要与 `currentRevision`,不批量读取历史正文 |
|
||||
| `GET /canvas-projects/:id/history/:snapshotId` | 按需返回 `snapshot` 摘要和 `project` 历史正文 |
|
||||
| `POST /canvas-projects/:id/history/:snapshotId/restore` | 请求 `{ revision }` 为当前画布版本,成功返回新版本摘要;恢复前强制备份当前内容 |
|
||||
@@ -146,6 +205,8 @@ Token 报价的 `estimated` 为 `true`,`quantity` 是预留 Token 数。参考
|
||||
|
||||
平移和缩放只持久化浏览器视口,内容 PUT 忽略客户端 `viewport` 和 `remoteContentHash`。前端遇到 409/428 会保留账号隔离的本地草稿、暂停该画布自动提交,并提供加载最新版和下载草稿入口;载入最新版前草稿写入失败时停止替换。其他画布仍可保存。
|
||||
|
||||
单画布读取会先查询归属用户的版本元数据,再判断 `If-None-Match`;命中时不会读取大型画布正文。未命中时返回完整项目 JSON。正文达到 1 KiB 且客户端声明接受 gzip 时响应使用 gzip 压缩,并带 `Vary: Accept-Encoding`;因此客户端应以 HTTP 状态码区分 `200` 正文和 `304` 未变化,不要把 `304` 当作业务错误。
|
||||
|
||||
云端 Agent 与创作任务的写入共用版本和历史事务;Agent `canvasPatch` 携带 `baseRevision`、`revision`,客户端只接受连续增量,跳过重复事件,缺口或同字段冲突时保留草稿并重新核对。删除、重排或顶层内容变化无法由增量完整表示时,事件携带 `requiresRefresh: true` 且不附 `canvasPatch`,客户端完整核对后才推进基线;撤销事件同样触发核对。保存日志仅记录请求/链路 ID、画布/用户 ID、版本、节点数量变化及 HTTP 状态,不记录正文、提示词或媒体 URL。
|
||||
|
||||
## 欢迎页开放配置
|
||||
@@ -170,9 +231,16 @@ Token 报价的 `estimated` 为 `true`,`quantity` 是预留 Token 数。参考
|
||||
- 创建和追加消息可选择 `reasoningMode`,默认 `off`;`auto`/`deep` 为服务端行为策略与模型推理配置的选择,不等于允许暴露内部思维链。供应商能力由后端校验;声明式 Agent 渠道不支持时明确报错。推理可能增加耗时和费用。
|
||||
- Cloud Agent 与首页创造的规划请求使用自动工具选择。OpenAI Chat Completion 兼容协议会把显式 `auto` 归一化为省略 `tool_choice`,沿用协议默认的自动选择语义;显式开启思考模式时还会在首个上游请求前移除 `required` 或指定函数对象。非思考模式仍保留艺术点评、提示词优化等结构化任务的强制函数选择。若上游隐式开启思考而本地未声明,仍按 `required` → `auto` → 省略字段做兼容重试。
|
||||
- `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`,只读清单中存在的层。没有偏好层时工具清单不含该工具。偏好仅是非授权数据,不能扩展工具、节点或预算,不能绕过审批;最多 12000 字符/层。
|
||||
- 系统行为策略与媒体默认策略是版本化、编译进后端发布物的资源,修改它们仍需发布后端,不是后台热更新;工具、校验、扣费和审批在代码侧强制执行。画布节点能力由服务端 registry 定义,工具 schema、创建、连线与画布摘要读取共同消费;新生成模式还必须接入媒体任务适配器,不能仅凭 md 或注册节点启用收费操作。
|
||||
- 系统行为策略与媒体默认策略是版本化、编译进后端发布物的资源,修改它们仍需发布后端,不是后台热更新;工具、校验、扣费和审批在代码侧强制执行。系统行为策略当前版本为 10:`canvasSummary` 被定义为节点目录,模型不得把它当成完整画布。画布节点能力由服务端 registry 定义,工具 schema、创建、连线与画布目录读取共同消费;新生成模式还必须接入媒体任务适配器,不能仅凭 md 或注册节点启用收费操作。
|
||||
- 已安装且属于当前用户的技能在创建时只保存版本、哈希和文本文件路径,不预存全部正文,也不按所有选中技能正文合计 128KB 拒绝创建。`skill_read_file` 按需读取 `SKILL.md` 或必要引用,支持字符偏移 `offset`(默认 0),每页最多 12000 字符,返回 `hasMore` / `nextOffset`。读取时重新验证用户权限、启用状态和版本;技能更新后拒绝混读,需新开一轮。技能是不可信数据,不能创造工具、改变权限或覆盖系统规则。
|
||||
- Agent 按实际文本模型的 `contextWindowTokens` 与 `maxOutputTokens` 计算输入预算,并在达到该模型预算的压缩阈值时移除较早工具结果中可重新读取的正文,保留工具调用/结果配对、用户原始要求、生成回执及最近完整工具轮次,并允许重新读取。此机制是确定性正文卸载,不是 LLM 语义摘要;运行 checkpoint 的持久化上限与模型上下文窗口独立。技能读取事件只保存回执,不复制正文,正文页只进入模型对话。
|
||||
- 达到同一条压缩线时整轮不再直接判死:Agent 先暂停步进循环,用一次独立模型调用(任务操作名 `cloud_agent_context_compaction`,按单步墙钟计时但不占本轮的模型调用步数)把历史压成结构化检查点,再以 `Resume` 用压缩后的上下文继续本轮;同一轮最多压缩 4 次,压完仍超过输入预算才回到原有的预算失败路径。检查点是固定字段的 JSON(`version` 为 1,字段为 `historySummary`、`scriptDesign`、`operationHistory`、`pendingTasks`、`currentWork`、`nextStep`、`decisions`、`constraints`、`userPreferences`、`compactedTurnCount`),未知字段一律拒绝,超过 64KiB 判为不合格。压缩后的上下文是「检查点帧 + 确认回执 + 最近 2 对完整对话」:不以 tool 回执或带工具调用的 assistant 开头,检查点帧不计为用户轮次,续轮交接不会再重复追加本轮的用户要求与回复。渠道没有配置模型上下文窗口时,判据退回既有的跨轮历史闸门(`cloudAgentHistoryKeepRounds` 轮与 `cloudAgentHistoryMaxBytes` 字节)。
|
||||
- 压缩过程对外只有两个事件:`context_compaction_requested` 带触发读数(`basis` 为 `tokens`/`bytes`、`projectedTokens`、`usableInputTokens`、`compactAtTokens`、`pressureRatio`、`budgetSource`、`sourceBytes`、`turnCount`),`context_compacted` 带 `mode`(`model` 为压缩模型输出,`fallback` 为服务端保底检查点)、`resume`、`historyMessages`、`compactedTurnCount`、`droppedTurns`,降级时附 `reason`。压缩模型失败、输出不合规、或本轮在压缩期间被取消/失败,服务端都落保底检查点并写 `mode=fallback`;终态轮次的收尾只落检查点与事件,不改写已经失败或已取消的状态。
|
||||
- 每次普通 Agent 步进模型调用发出之前都会落一条 `context_pressure` 事件(`schemaVersion: 2`、`phase: "before_request"`),把"这次请求装了多少、离装不下还有多远"作为可观测读数下发,`requestId` 是本次请求的任务 ID。主读数是 `projectedNextInputTokens`:有可采信的上游实测锚点时等于"锚点实测 + 本地估算的有符号增量"(`tokenSource` / `measurementSource` 为 `provider`,`tokenScale` 给出实测÷估算的换算比例);没有实测时退回纯本地估算(`tokenSource` 为 `estimate`)。两把尺子各有自己的名字、谁也**不覆盖**谁:`estimatedInputTokens`(`readingScope: "next_request"`、`estimateMethod: "local_v1"`)永远是本地下一次请求的估算,`pressureTokens` / `providerUsage`(`providerMeasurementScope: "previous_request"`)永远是上游对**上一次**请求的实测,消费方不得把两者画成一条曲线。本读数只增加可观测性:请求准入与正文裁剪的既有判据不变。
|
||||
- 上游实测锚点的采信与治理:上游没有回 usage 的调用(`usage_available=false`)不定锚、不猜用量,读数继续用估算;只有"模型调用"这一步能配锚(媒体任务发的是另一份信封,`operation` 不匹配即跳过)。上游实测与本地估算差出一个量级时不采信(比值低于 0.5× 或高于 2×,通常是换了模型或计量口径),事件给 `anchorRejected` 说明原因并继续用估算。锚点可以跨步沿用,但**换模型、换线路、换系统提示或工具 schema、换模型窗口,以及超过 3 步未刷新**(`anchor.ageSteps`)都会作废:真机上出现过锚点被冻结、估算已经涨了 50% 而读数还停在老值的情况。
|
||||
- 事件还带 `breakdown` 占用分布:三个桶(`system` 系统提示(含画布摘要)、`tools` 工具 schema、`messages` 会话消息(含工具结果))各自的字节与估算 Token,协议外壳余量 `envelopeBytes`(tool choice、缓存键这类不属于任何桶的部分,单独报而不摊进桶里),按锚点比例换算的 `tokenScale` 与每桶/每分段的 `scaledTokens`,以及 `systemSegments` 系统提示内部分段(`policy` / `mediaPolicy` / `capabilities` / `execution` / `memory` 个人记忆 / `other` 零头)。分段按编译顺序逐块量出,合计与 `system` 桶严格相等:编译之后才拼接的个人记忆由 `memory` 登记,零头归入 `other`,不出现"分段加不到桶"的错觉。
|
||||
- 窗口口径由 `contextWindowTokens` / `reservedOutputTokens` / `overheadTokens` / `inputBudgetTokens` / `usableInputTokens` / `budgetSource` 给出:输入预算 = 上下文窗口 − 输出预留 − overhead,其中 overhead 是工具 schema、协议包装与兜底轮的比例预留(窗口的 4%,夹在 4096–32768),`compactAtTokens` 是既有的"可重读正文就地裁剪"触发线(输入预算的 85%),`budgetSource` 说明这份窗口来自渠道模型还是逻辑模型的线路交集。**没有解析到模型自己声明的窗口时不下发这些字段、也不给占用率**(`modelLimitConfigured: false`):窗口未知就说未知,不拿兜底默认窗口冒充真实能力编一个百分比。
|
||||
- `context_transition` 事件说明"读数为什么变":`window_resolved`(窗口从未确认变为已确认,读数改用窗口口径,**不是**上下文变少)、`model_changed` / `route_changed` / `window_changed`(锚点因换模型、换线路或换窗口而作废;窗口变化另带 `before` / `after` 的窗口读数)。它只解释口径与锚点状态,不携带任何授权语义,也不改变执行边界。
|
||||
- 画布 Agent 的看图能力:当且仅当本轮渠道模型的能力合同声明了图片输入(`text.references.maxImages > 0`)时,额外暴露 `canvas_inspect_image(nodeId, refresh?)`。工具校验图片节点、资源归属、就绪状态、媒体类型和模型文件大小限制;检查点与任务输入只保存 `resource:ID` 占位及授权参考清单。worker 复用资源读取链路,在内存中将占位替换为真实图片数据后展开模型协议,不持久化 base64 或签名 URL,不依赖 `CANVAS_PUBLIC_BASE_URL`,不接受任意外部地址。多图在本批所有 tool 回执后统一附送;图片保留最近 3 个工具轮次,发给模型时还按数量上限保留最新图片,本批超限则明确要求分批查看。同一张图一轮内附送两次后只回执文字,确需重看时传 `refresh=true`。工具成功不等于识别成功,普通模型正文不再自动写入 `visualNote`,旧 `inspected` 标记及观察不跨轮继承;`visualIdentity=unknown` 表示没有已确认缓存,不表示模型不能查看随附图片。画面内文字仍按不可信数据处理;资源读取失败则真实失败,不凭标题推断画面。其他需要公网 URL 的生成协议仍遵循各自存储配置合同。
|
||||
- 平台支持工具全集为 `agent_profile_read`、`plan_update`、`ask_user`、`recall_lessons`、`remember_lesson`、`canvas_list_node_types`、`canvas_get_state`、`canvas_inspect_image`、`canvas_read_batch_table`、`canvas_read_storyboard`、`skill_read_file`、`skill_search`、`task_get`、`model_list`、`canvas_create_storyboard`、`canvas_edit_storyboard`、`canvas_edit_batch_table`、`canvas_apply_ops`、`canvas_arrange_nodes`、`generate_media`、`image_layer_split`、`image_text_detect`、`image_annotation_render`;单轮实际工具仍按偏好快照、技能、权限、画布上下文和生成预算裁剪。画布写入工具要求本轮授权 `contextScope: ["canvas"]`。禁止 shell、任意网络请求和外部 MCP。`remember_lesson` 在 `read_only` 下不可用。
|
||||
- `plan_update` 维护本轮结构化待办清单(整表替换,最多 20 项),跨轮继承未完成项,并在界面以 PlanBar 展示。权限为 `request_approval` 时,首次建立至少 2 项的清单会先进入审批;`auto` 直接写入清单。新一轮的第一次模型请求就会带上继承的清单。模型在没有工具调用且清单仍有未完成项时,服务端会催办并要求继续调用工具;这是软约束,不验证工作是否真的完成,也不会在没有清单时强行催建。
|
||||
@@ -192,11 +260,14 @@ Token 报价的 `estimated` 为 `true`,`quantity` 是预留 Token 数。参考
|
||||
- `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 任务。
|
||||
- 必须有当前用户已保存的画布。系统提示里的 `canvasSummary` 是节点目录,不是整张画布的 JSON:每条只含 `id`、`type`、截断后的 `title`,以及不支持操作的类型标记;最多列入 120 个节点,并按约 24KB 兜底截断,装不下的节点记入 `omittedNodes` 与 `totalNodes`。正文、提示词、媒体和结构化表不进目录,由 `canvas_get_state` 按 `offset` 每页读取 40 个节点、资产可引用状态及相关连线,按 `nodeIds` 精读最多 8 个节点(正文每字段最多 16000 字符),通过 `hasMore` / `nextOffset` 和字段 `Truncated` 判断是否完整。工具结果留在当轮消息里,历史压缩会卸掉可重读正文,不会在后续每一步把整页结果再打包一次。分镜表包含镜头、角色节点与资产绑定;摘要每页最多 20 行,精读每次 1 行,可用 `storyboardOffset` 翻页;单行叙事文本累计最多 24000 字符,角色 / 绑定各最多 16 项。上下文不含媒体 URL、任意元数据或未同步修改;节点名称不等于图像视觉识别。普通任务重试接口不能重试 Agent 任务。
|
||||
- `canvas_get_state` 首次调用传 `{}`,仅接受可选的 `offset`、`storyboardOffset`(非负整数)和 `nodeIds`(最多 8 个字符串组成的数组);当前画布由运行绑定,不接受 `canvasId`、`limit` 或 `page`。读取工具分别反馈非对象 / 多对象、JSON 格式错误、未知字段和字段类型错误。可纠正的工具参数失败在 `tool_failed.result` 及模型工具结果中返回 `reason: invalid_tool_arguments`、本轮已声明的 `parameters` 和 `guidance`;画布读取额外给出 `exampleArguments: {}`。失败调用仍如实记录,由模型修正参数后继续,不静默丢弃字段或自动重放写操作;资源归属、审批、快照和收费校验仍按原规则执行。
|
||||
- `GET /agent/runs/:id` 返回运行信息;`POST /agent/runs/:id/cancel` 取消当前运行及活动子任务;`POST /agent/runs/:id/approvals/:approvalId/decision` 接受 `{"decision":"approve"|"reject","reason":"..."}`,审批决定幂等且服务端校验归属。
|
||||
- `GET /agent/skills/usage` 需要登录,只聚合当前用户最近最多 200 次 Agent 运行的日志;返回技能启用次数、检索命中、成功/失败读取、总纲/卡片读取和最多 5 条最常读卡片路径,不返回技能正文。损坏的日志会返回错误而非静默给出不完整统计。
|
||||
- 运行详情的事件**分页**:事件全量在 `cloud_agent_event_records`(append-only,主键 `run_id` + `sequence`),运行详情默认只返回**尾部一窗**(最新 40 条),并同时给出四个位置字段:`eventSeqBase`(本次返回的首条事件之前已入库的条数,不变量是 `events[i].seq == eventSeqBase + i + 1`)、`eventCount`(该轮次累计事件条数)、`latestSeq`(本次返回的最后一条序号,可直接作为下次 `sinceSeq`)、`eventsTruncated`(还有更早的记录没随本次返回)。不返回事件时 `eventsTruncated` 为 false,`eventSeqBase` 退回内存窗口在整条日志里的偏移。
|
||||
- 运行详情查询参数:`?sinceSeq=<seq>` 只返回该序号**之后**的事件(增量 / 断线重连,单次最多 500 条,按 seq 升序);`?eventLimit=<n>` 覆盖默认页大小,取值 1–500,大于窗口时由服务端从事件表往前补页。两个参数都必须是整数,越界或非法返回 400;游标追平或越界时返回空 `events` 而不是报错。读取一律走 `(run_id, sequence)` 的 keyset 分页(`sequence > ? ORDER BY sequence LIMIT ?`),不用 offset,也不会为这些字段载入整条日志。升级前把事件放在 `state_json` 里的旧轮次在事件表中没有行,读取回退到内存窗口,行为与升级前一致。
|
||||
- 首次通过取消接口取消运行时记录一次 `run_cancelled` 事件,`source: user_request` 表示来自用户取消 API,并携带当时的 `activeTaskId` / `mediaTaskId`;此事件表示取消请求已接收,关联任务最终状态以任务查询及收尾状态为准。运行记录损坏或超限时优先保证取消和后台收尾,事件无法保存会记录服务端告警;旧导出日志不能据此追溯取消发起来源。
|
||||
- `GET /agent/runs/:id/events` 返回 `agent_event` 和首次 / 状态版本变化时的紧凑 `run_snapshot` SSE;无变化时只发送 heartbeat。事件 `Seq` 在运行内递增;支持 `?after=` / `Last-Event-ID`,游标不是运行 ID。`cleanupPending: true` 时即使运行已进入终态也会继续推送,直到后台收尾完成。前端应以快照恢复状态,代理只对这一精确路径关闭缓冲。
|
||||
- `GET /agent/runs/:id/events` 返回 `agent_event` 和首次 / 状态版本变化时的紧凑 `run_snapshot` SSE;无变化时只发送 heartbeat。事件 `Seq` 在运行内递增;支持 `?after=` / `Last-Event-ID`,游标不是运行 ID,服务端把它作为运行详情的 `sinceSeq`,因此断线重连只读该游标之后的增量。`cleanupPending: true` 时即使运行已进入终态也会继续推送,直到后台收尾完成。前端应以快照恢复状态,代理只对这一精确路径关闭缓冲。
|
||||
- `generation_task_created` 携带 `canvasId`、`nodeId`、`taskId`、`title`、`mode`、`referenceNodeIds`。草稿、提交、画布工具写入,以及媒体成功 / 失败 / 取消的真实节点变更,均在画布写入与运行检查点的同一事务持久化 `canvas_updated`。节点已删除或换任务时不伪造更新;`run_failed` 本身不代表节点媒体任务失败。
|
||||
- 未注册 Agent 能力的节点不阻断整张画布读取:摘要和 `canvas_get_state` 仅返回基础信息,并标记 `agentSupported: false` 与原因;不暴露任意 metadata,不授予该类型的创建、修改、连线或媒体引用能力。
|
||||
- `approval.preview` 和 `canvas_updated.actions` 是服务端根据同一解析、快照与 Capability 规划流程生成的解释信息,不是授权凭证。审批卡片明确列出新增/修改节点、节点类型、修改字段、名称变化和连线两端;执行事件保存同样的可读信息,供历史消息显示和点击定位。实际写入仍重新校验用户归属、`snapshotHash`、Capability、节点锁、预算和审批 `callHash`。
|
||||
@@ -286,6 +357,7 @@ CSV 使用中文表头、UTF-8 BOM、CRLF;金额按整数分精确转换为两
|
||||
| 403 | 403 | `forbidden` | 无权限 |
|
||||
| 404 | 404 | `not_found` | 资源不存在 |
|
||||
| 409 | 409 | `conflict` | 冲突 |
|
||||
| 409 | 409 | `project_name_conflict` | `POST /projects` 同一用户下已有同名项目;客户端可有限更换名称重试 |
|
||||
| 429 | 429 | `rate_limited` | 限流(未细分) |
|
||||
| 500 | 500 | `internal` | 内部错误 |
|
||||
| 502 | 502 | `bad_gateway` | 上游失败 |
|
||||
@@ -297,7 +369,22 @@ CSV 使用中文表头、UTF-8 BOM、CRLF;金额按整数分精确转换为两
|
||||
|
||||
模型错误把已有字符串码放进 `reason`(如 `model_capability_not_supported`),`code` 仍为 400。
|
||||
|
||||
常量:后端 `service/error_codes.go`,前端 `web/src/services/api/error-codes.ts`。
|
||||
常量:后端标准原因定义在 `backend/internal/kernel/error_codes.go`,由 `app` 和 `service` 兼容导出;前端业务模块按 `ApiError.reason` 分支。
|
||||
|
||||
## 技能库分类 API
|
||||
|
||||
以下接口需要登录。技能库分类与技能广场共享分类分离:`skills.tag` 仍表示共享市场分类;用户技能库分类记录在用户自己的技能状态中,只影响该用户技能库和画布 Agent。
|
||||
|
||||
| 方法 | 路径 | 行为 |
|
||||
| --- | --- | --- |
|
||||
| GET | `/api/skills/library-categories?scope=mine\|created` | 返回当前用户可见的个人分类和平台分类,以及所选视图下每类数量、全部技能数和未分类数量。`mine` 包含自己创建及已加入的公开技能;`created` 只统计自己创建的技能。 |
|
||||
| POST | `/api/skills/library-categories` | 请求 `{ "name": "分镜", "scope": "personal" }`。`scope` 可省略并默认为 `personal`;管理员可指定 `platform`,该分类对所有用户可见、可分配和筛选。同一用户可见范围内分类名唯一。 |
|
||||
| DELETE | `/api/skills/library-categories/:id` | 删除个人分类(仅分类所有者)或平台分类(仅管理员),只解除该分类与技能的关联,不删除技能。 |
|
||||
| PATCH | `/api/skills/:id/library-category` | 请求 `{ "categoryId": "分类 ID" }` 设置分类;空字符串清除分类。仅允许对自己创建或已加入的技能操作,并且只能使用当前用户的个人分类或平台分类。 |
|
||||
|
||||
`GET /api/skills` 可带 `libraryCategoryId` 或 `libraryUncategorized=true`,仅用于 `scope=mine` / `scope=created`,且两者不能同时使用。它们可与共享分类筛选 `tag` 同时提供,结果需同时满足两个筛选条件。分类列表的数量不受搜索词影响,表示对应技能库范围内的完整数量。
|
||||
|
||||
技能列表响应中的 `categories` 是技能广场共享分类,包含 `value`、`label` 和 `count`;`count` 统计已启用且公开的技能,不受当前搜索词、分页和视图筛选影响。它与技能库个人/平台分类是两套独立分类。
|
||||
|
||||
## 画布工具 API
|
||||
|
||||
@@ -312,3 +399,9 @@ CSV 使用中文表头、UTF-8 BOM、CRLF;金额按整数分精确转换为两
|
||||
| DELETE | `/api/tools/:id` | 仅删除自己的用户工具,不能删除内置或他人工具 |
|
||||
|
||||
生成提示词工具引用格式为 `@[tool:type:ID:label:icon]`,label 使用 URI 编码。名称和图标只用于展示,不作为授权依据。服务端在任务入队及执行前检查用户可见性、启用状态、工具类型和生成模式;无效、越权、嵌套工具或数据库错误必须失败,不能把未解析 token 发送给模型。风格和九宫格仅用于图片,运镜和特效仅用于视频。入队校验不冻结工具快照:排队期间删除工具将导致执行失败。
|
||||
|
||||
## 平台技能策展
|
||||
|
||||
新增登录读取 `/api/skills/curation` 与管理员 GET/PUT `/api/admin/skill-curation`;原技能列表仅在策展开启时应用新增分类筛选,响应结构不变。见 [接口与行为](./skill-curation)。
|
||||
|
||||
一级分类扩展:管理写入增加 root 命令,assignment.rootId 与子分类完整集合一起保存;列表增加 platformRootId 筛选。关闭模式继续忽略新增筛选。
|
||||
|
||||
43
docs/content/docs/backend/skill-curation.mdx
Normal file
43
docs/content/docs/backend/skill-curation.mdx
Normal file
@@ -0,0 +1,43 @@
|
||||
---
|
||||
title: 平台技能策展
|
||||
description: 可选的后台一级分类和子分类维护
|
||||
---
|
||||
|
||||
平台策展模式在“后台 → 技能分类”中开启,默认关闭。关闭时原有 `/skills` JSON、固定五类、个人技能库分类保持不变,新增筛选参数被忽略。分类设置可以在开启前准备。
|
||||
|
||||
管理员可以新增、改名、排序、停用子分类,并给公开且启用的技能设置同根的多个子分类。停用不删除指派或个人加入状态,恢复后重新生效。技能 tag 改变时旧跨根指派不再生效;删除技能同时清理指派。无有效指派的技能进入“未细分”。
|
||||
|
||||
## API
|
||||
|
||||
- `GET /api/skills/curation`:登录后读取分类及公开有效技能指派;关闭时返回空集合。
|
||||
- `GET /api/admin/skill-curation`:管理员读取设置、revision、含停用的子分类及公开技能指派。
|
||||
- `PUT /api/admin/skill-curation`:管理员提交 `expectedRevision`,及 `enabled`、完整 `category`、完整 `assignment` 三者之一。category 含 id(新建为空)、rootTag、name、sortOrder、enabled。assignment 含 skillId、categoryIds;空数组清除,null 拒绝。
|
||||
- `GET /api/skills` 新增 `platformCategoryId` 或 `platformUncategorized=true`,仅开启时生效;与原有 scope、搜索、排序、个人分类组合,分页前筛选,不改变响应字段。
|
||||
|
||||
写请求上限 64 KiB、单技能最多 32 类;拒绝未知字段、重复指派、跨根、私人技能、过期版本。409 后重新加载核对修改。管理员身份在业务层和事务内检查,revision CAS、修改和 AdminAuditEvent 同事务。审计只记录分类元数据,不记录技能正文。分类不是使用技能的授权。
|
||||
|
||||
## 数据库
|
||||
|
||||
迁移 46 `skill_curation`,checksum `sha256:skill-curation-v46-20261005`:
|
||||
|
||||
| 表 | 用途 |
|
||||
| --- | --- |
|
||||
| skill_curation_settings | 单例 id=1,enabled 默认 false,revision 用于并发写入 |
|
||||
| skill_curation_categories | 稳定 id、root_tag、名称及规范化名称、sort_order、enabled;同根名称唯一 |
|
||||
| skill_curation_assignments | skill_id + category_id 联合主键 |
|
||||
|
||||
迁移只建表及默认关闭的设置,不导入技能或分类内容。44、45 由独立变更保留;完整迁移程序支持缺号补跑。停用开关不是数据库降版;回退旧程序需要匹配的数据库备份。
|
||||
|
||||
## 待验证
|
||||
|
||||
SQLite 及 HTTP recorder 可在无网络环境验证。PostgreSQL、前端构建、浏览器中的明暗主题、键盘操作和分页交互需要单独验证。
|
||||
|
||||
## 一级分类维护
|
||||
|
||||
迁移 47 `skill_curation_roots`,checksum `sha256:skill-curation-roots-v47-20261005`,依赖迁移 46。新增 `skill_curation_roots`(id、name、normalized_name 唯一索引、icon_key、sort_order、enabled)及 `skill_curation_root_assignments`(skill_id 主键、root_id 索引)。仅创建原目录的五个中性根,保持 U39 的 rootTag 引用,不导入任何技能指派。
|
||||
|
||||
管理员在同一页面维护一级分类;PUT 增加 `root` 命令,含 id(新建为空)、name、iconKey、sortOrder、enabled。图示只接受空值或 shapes/film/shopping-bag/megaphone/landmark/palette/users/wrench,客户端未知值使用 Shapes。根表为空时回落原五类;第一次编辑时将回落值保存入表。读取或数据库错误不冒充空表。
|
||||
|
||||
`assignment` 可带 `rootId`,空字符串清除指定;改根必须同时提交完整 categoryIds,跨根则整笔回滚。原 tag、技能内容、版本和安装状态不变。未指定时按原 tag 对应稳定根 ID;指定优先,目标停用或不存在时进入派生桶 `__unassigned__`(未归入启用分类),此桶不可编辑或指派。根停用不删除子分类、指派或已挂载技能。
|
||||
|
||||
策展快照开启时增加 roots/rootAssignments;公开读取隐藏停用根及其子分类,不公开私人技能指派。`GET /api/skills?platformRootId=...` 在原有可见性和分页查询前筛选;关闭时忽略该参数,原响应结构和五类不变。后台界面和市场/技能库根导览、分组、图示均读取同一快照。场景预设来源及 scene 仍不变。
|
||||
@@ -19,7 +19,7 @@ description: Host Updater、Release 检查、数据库备份迁移、健康验
|
||||
4. 拉取目标 backend/web 镜像并要求存在仓库 `sha256` 摘要。任何失败都在停服前中止。
|
||||
5. 停止 web/backend,等待 Backend 的 SIGTERM drain 完成;PostgreSQL 和 Redis 保持运行。
|
||||
6. 用目标 backend 镜像独立执行 `migrate-schema up`。整批迁移在事务和 PostgreSQL advisory lock 内完成,迁移名称与 checksum 必须匹配。
|
||||
7. 原子更新 `CANVAS_IMAGE_TAG` 和 Compose 文件,启动目标版本。
|
||||
7. 解析目标 backend/web 镜像的仓库 digest,原子更新 `CANVAS_IMAGE_TAG`、`CANVAS_BACKEND_IMAGE`、`CANVAS_WEB_IMAGE` 和 Compose 文件,启动目标版本;运行容器始终使用 `image@sha256:...`,不使用 `latest`。
|
||||
8. 连续检查 `/api/health/ready` 的数据库、运行时、schema 和 build version,并经过稳定窗口后才标记成功。
|
||||
|
||||
更新状态写入 `/var/lib/open-ai-canvas-updater/state.json`。Backend 或浏览器在切换期间断线不会终止宿主机操作,恢复后可继续读取日志。
|
||||
@@ -30,20 +30,27 @@ description: Host Updater、Release 检查、数据库备份迁移、健康验
|
||||
|
||||
1. 停止目标 web/backend;
|
||||
2. 恢复更新前保存的 Compose 文件;
|
||||
3. 再次校验备份 ZIP 和 SHA-256;
|
||||
4. 使用 `pg_restore --clean --if-exists` 恢复 PostgreSQL;
|
||||
5. 恢复旧 `CANVAS_IMAGE_TAG`,启动旧服务并重新进行稳定窗口验证。
|
||||
3. 恢复更新前保存的 `.env`,确保 backend/web 镜像仍绑定到原 digest;
|
||||
4. 再次校验备份 ZIP 和 SHA-256;
|
||||
5. 使用 `pg_restore --clean --if-exists` 恢复 PostgreSQL;
|
||||
6. 启动旧服务并重新进行稳定窗口验证。
|
||||
|
||||
回退任一步失败时状态变为 `manual_intervention`,不伪造成功。管理后台仅在存在旧版本和已校验备份时开放人工回退按钮。
|
||||
|
||||
## 安装与升级约束
|
||||
|
||||
GHCR 镜像部署必须把 `CANVAS_IMAGE_TAG` 固定到具体 Release,不可使用 `latest`。安装更新器:
|
||||
GHCR 镜像部署必须把 `CANVAS_IMAGE_TAG` 固定到具体 Release,并把 `CANVAS_BACKEND_IMAGE`、`CANVAS_WEB_IMAGE` 固定到对应 GHCR digest,不可使用 `latest` 或仅使用可变 tag。首次安装时显式指定 Release:
|
||||
|
||||
```bash
|
||||
curl -fsSL https://raw.githubusercontent.com/ddcat-ai/open-ai-canvas/main/scripts/install-server-image.sh \
|
||||
| sudo env CANVAS_IMAGE_TAG=v1.5.7.1 bash
|
||||
```
|
||||
|
||||
已有部署只安装更新器时,先确认 `.env` 已包含两个 `@sha256:...` 镜像引用,再执行:
|
||||
|
||||
```bash
|
||||
cd /opt/open-ai-canvas
|
||||
curl -fsSL https://raw.githubusercontent.com/ddcat-ai/open-ai-canvas/main/scripts/install-host-updater.sh | sudo bash
|
||||
sudo docker compose --env-file .env -f docker-compose.deploy.yml up -d --force-recreate backend web --wait
|
||||
```
|
||||
|
||||
脚本会下载与当前 Release 匹配的 Linux amd64/arm64 二进制和 `SHA256SUMS`,生成随机 `CANVAS_UPDATER_TOKEN`,创建 systemd 服务、Socket 目录、状态目录和 `backups/`。Token 只保存在服务器 `.env` 与 root-only 更新器环境文件中。
|
||||
@@ -59,7 +66,7 @@ sudo docker compose --env-file .env -f docker-compose.deploy.yml up -d --force-r
|
||||
3. 前端 Bun 构建阶段固定到 `BUILDPLATFORM`,静态资源只生成一次,再放入 AMD64/ARM64 nginx 镜像。Bun 与 `web/package.json`、质量检查保持 `1.3.9` 一致。
|
||||
4. 先推送 `sha-<完整提交>-amd64/arm64` 后端镜像及 `sha-<完整提交>-multi` 前端镜像,以摘要 artifact 传递结果。两种后端架构和前端全部成功后,才从摘要合并发布 manifest,不用可变标签作为合并源。
|
||||
5. 同一 SHA 的 main/tag 发布串行运行;后到的一轮仍经过质量门禁,然后复用已有 SHA 镜像,不重复编译。只有明确的镜像不存在可以转入构建,鉴权、限流、网络和异常摘要必须报错。
|
||||
6. 发布保留完整 SHA 和短 SHA 标签;只有版本 tag 推送写入具体版本标签。`main` 只有在仍是远端最新提交时才更新 `latest`,旧提交的慢任务不能覆盖新版本。正式部署仍应固定版本标签,不依赖 `latest`。
|
||||
6. 发布保留完整 SHA 和短 SHA 标签;只有版本 tag 推送写入具体版本标签。`main` 只有在仍是远端最新提交时才更新 `latest`,旧提交的慢任务不能覆盖新版本。正式部署由安装器和更新器解析并落盘 digest,不依赖 `latest`。
|
||||
|
||||
Go 检查显式使用 `backend/go.sum` 作为缓存依赖键,并上传 `go-test-timings`(JSONL),可按 `Test` / `Elapsed` 定位慢测试。Docker 的后端模块下载保留在普通镜像层,编译步骤可以直接读取;支付插件只按实际 import 下载依赖,不重复预取完整后端模块图。版本参数下移到编译入口。GHA 构建缓存按镜像和架构隔离,避免并行任务共用同一 scope。`go-build` cache mount 只用于同一个 builder 内的复用,当前没有额外的跨 Runner mount 导出方案;不能把它当作持久编译缓存。冷缓存首轮和缓存上传仍可能较慢,需要比较连续两轮的实际耗时。
|
||||
|
||||
|
||||
@@ -5,6 +5,10 @@ description: 热点回源保护、并发租约、故障边界和上线验收
|
||||
|
||||
# 任务缓存与队列稳定性
|
||||
|
||||
## 排队后的自定义渠道检查
|
||||
|
||||
worker 在准备模型路由前重新读取自定义渠道开关,覆盖首次排队和失败后重新入队。排队期间关闭开关的任务以“自定义渠道”不可用的明确错误进入失败终态,不调用渠道;未发出的预扣沿用已有失败退款路径。已接受、提交不明或原本待核对的订单仍进入既有待核对路径,不将可能已发生的费用自动退回。已生成作品的媒体保存恢复不重新生成,不受此入口阻断。
|
||||
|
||||
## 详情读取和日志筛选边界
|
||||
|
||||
任务中心打开详情只读取任务和日志,不在该路径调用画布结果同步。后台同步遇到短剧领域项目任务(`domainProjectId` 等于任务 `projectId`)或没有生成节点关联时跳过画布写回,避免把短剧项目 ID 当作画布 ID 查询。
|
||||
|
||||
18
docs/content/docs/backend/update-announcements.mdx
Normal file
18
docs/content/docs/backend/update-announcements.mdx
Normal file
@@ -0,0 +1,18 @@
|
||||
---
|
||||
title: 自定义更新公告
|
||||
description: 站点更新公告的编辑、开关、媒体与同步
|
||||
---
|
||||
|
||||
# 自定义更新公告
|
||||
|
||||
在「站点及外观 → 更新公告」编辑公告,点击页面顶部「保存修改」统一保存。开关默认关闭,此时工作台与管理后台入口展示原有内置更新日志及真实构建版本;开启后,两处入口和公告弹窗采用自定义当前版本与公告内容。后台「系统更新」继续使用真实程序版本和官方 Release。
|
||||
|
||||
支持最多 30 个版本;每个版本有版本号、可选标题与发布日期,以及最多 50 个可排序的文字、图片、视频内容块。文字支持换行、列表和 Markdown 加粗,原始 HTML 不执行。内容块可选择整行或半行,相邻半行并排,窄屏自动单列。编辑区域提供即时预览,视频手动播放。
|
||||
|
||||
图片支持 PNG、JPEG、WebP,最大 10MB;视频支持 MP4、WebM,最大 256MB。媒体使用现有平台资源存储,管理员身份、文件真实 MIME 和新资源归属均由服务端校验。未保存媒体只能由上传管理员预览;已保存媒体可由其他管理员预览;公开读取仅允许当前已启用公告引用的媒体,支持视频 Range 请求。关闭开关保留全部自定义内容及素材引用保护,公共外观响应不返回关闭的公告正文。
|
||||
|
||||
当前版本必须对应已添加的版本,版本号不能重复,空文字或未上传媒体不能提交;正文总大小最多 200KB,外观 PATCH 请求上限 512KB。保存成功后同步本页公共状态,其他页面在激活、聚焦或打开更新日志时重新读取;读取失败保留已有状态,过期响应不能覆盖较新的保存结果。
|
||||
|
||||
配置保存在现有 `system_settings` 的 `appearance` JSON 的 `updates` 中,外观合同版本为 10;不增加数据表或数据库迁移。恢复默认外观会清空自定义公告并关闭开关,恢复原日志,已上传媒体仍保留在存储资源中。
|
||||
|
||||
媒体接口:`POST /admin/settings/appearance/assets/update-image|update-video`;管理员预览 `GET /admin/settings/appearance/updates/:id`;公开读取 `GET /public/appearance/updates/:id`。公开媒体不接受任意外部 URL,只从当前公告引用的资源生成访问地址。
|
||||
@@ -5,9 +5,41 @@ description: 当前项目已实现的核心工作台能力与使用入口
|
||||
|
||||
# 功能清单
|
||||
|
||||
## 卡藏 Midjourney
|
||||
|
||||
画布接收一次任务返回的全部图片,四张结果自动组成收起的图片堆叠,可展开、选择主图和分别使用。每张图保留独立资源及素材绑定,保存、刷新和任务重复同步不会将后续图片覆盖为第一张。已有仅显示首图的成功 Midjourney 节点在重新打开画布时从原任务恢复遗漏结果,无需再次生成。
|
||||
|
||||
`kacang-midjourney` 统一声明式插件提供 V6/V8 特惠、V7 特惠、稳定/高速三个生图协议。选择协议后自动填入供应商比例、默认比例、参考图上限和一次提交;禁用无合同的蒙版和通用输出参数。稳定版数值 quality 通过插件命名空间设置,不与宿主分辨率档混用。
|
||||
|
||||
特惠使用标准图片端点,稳定/高速使用受理和任务查询端点。结果支持顶层与 data 信封,全部单图及可选四宫格封面交给宿主立即保存;失败和空结果保留真实失败语义。完整模型和字段合同见插件包内 `docs/interface.md`。
|
||||
|
||||
## 沧元 Midjourney
|
||||
|
||||
`cangyuan-midjourney` 声明式插件分别提供 V7 与 1K/2K(供应商默认 V8.2)协议。V7 使用 `midjourney-v7`;1K/2K 使用 `midjourney-1k`、`midjourney-2k`,可在提示词显式写 `--v 8.2`。一次提交固定 `n=1`,全部结果交由宿主下载保存,参考图按供应商合同发送 HTTPS URL 字符串。
|
||||
|
||||
两条线路的参数、编辑端点和响应格式分别适配,不自动换模型。1K/2K 返回官网 CDN 原链,HTTP 403 会如实保留保存失败与原任务重试能力;插件不能消除供应商 CDN 的访问限制。完整字段与接口合同见插件包内 README 和 `docs/interface.md`。
|
||||
|
||||
创作页按整个任务一次消费返回图片,保留各图片的输出序号;一次请求返回多张时,素材与消息幂等去重不会再把后续结果当作第一张合并。
|
||||
|
||||
后台选择这两个协议时,“能力与参数”自动使用线路专属默认值:V7 为 4000 字符、五张参考图、不支持蒙版;V8.2 默认单张编辑源图、支持蒙版和十五种比例。两者默认自动尺寸、一次提交,关闭不支持的质量、透明背景、响应格式和输出格式选项。V8.2 在模型名未明确时暂用 1K,识别到上游 `midjourney-2k` 后改为 2K,切换档位保留管理员的参考限制、默认比例和价格。像素预设由宿主换算供页面展示,提交上游仍使用比例,实际尺寸由供应商决定。
|
||||
|
||||
## 自定义更新公告
|
||||
|
||||
「站点及外观 → 更新公告」提供开关、当前版本、多版本文字/图片/视频编辑、内容排序、整行/半行布局与即时预览。关闭展示原日志,开启展示自定义内容,保存后同步工作台和后台入口;后台系统更新保留真实构建版本。详见 [自定义更新公告](/docs/backend/update-announcements)。
|
||||
|
||||
## AutoDL 画面规格
|
||||
|
||||
AutoDL 视频模型在“能力与参数 → 画面规格”直接多选当前插件工作流声明的完整分辨率,并设置默认值;配置始终可编辑并生效。卡片沿用原有标题、副标题与字段样式,不再显示自定义开关或额外说明。AutoDL ComfyUI 视频与音频 v2.3.0 通过完整分辨率标签控制横、竖、方形,不显示未声明的独立比例控件。时长、音频与参考素材配置继续各自生效。
|
||||
|
||||
后台保存、用户模型目录、画布参数归一化、计费规格选择、服务端校验及插件请求使用同一套所选规格。仅允许选择插件预设,不能输入新标签;至少选一项,默认值必须属于所选列表。价格档可保留全部插件预设的价格,但不会扩大实际允许生成的分辨率范围。
|
||||
|
||||
## 画布媒体产出模型
|
||||
|
||||
图片、视频、音频在生成成功并写入节点后,会冻结当时提交的产出模型。提示词面板里的模型下拉仍是下一次要用的选用模型,改下拉不会改掉已经生成的内容。画布外观中的「媒体信息」打开后,有内容的媒体节点在左下角显示产出模型;图片右下角继续显示尺寸和体积。上传、粘贴、截取、合并、提取音频和本地加工不记录产出模型。本次改动之前的节点不回填。分享页和版本预览画布不显示这块信息。
|
||||
|
||||
## 画布 Agent 名称、文案与形象
|
||||
|
||||
「站点及外观 → 画布配置」提供独立助手名称、入口文字、面板标题和欢迎/输入文案。支持导入授权的 Live2D Cubism 3/4 运行时 ZIP,预览后保存启用、调整高度、切回默认动态球。加载失败保留可点击的默认入口,上传和资源访问具有管理员校验和引用保护。Cubism Core 由部署者提供,真实播放待验收;不含图片自动建模或 AI 自我介绍同步。详见 [画布 Agent 外观与 Live2D](/docs/backend/canvas-agent-appearance)。
|
||||
「站点及外观 → 画布配置」提供独立助手名称、入口文字、面板标题和欢迎/输入文案。助手名称同步用于界面和后续对话的自我介绍;名称只是数据,不改变工具权限,历史消息保留原文。支持导入授权的 Live2D Cubism 3/4 运行时 ZIP,预览后保存启用、调整高度、切回默认动态球。加载失败保留可点击的默认入口,上传和资源访问具有管理员校验和引用保护。Cubism Core 由部署者提供,真实播放待验收;不含图片自动建模。详见 [画布 Agent 外观与 Live2D](/docs/backend/canvas-agent-appearance)。
|
||||
|
||||
## 素材库分类与画布媒体链路
|
||||
|
||||
@@ -83,6 +115,14 @@ description: 当前项目已实现的核心工作台能力与使用入口
|
||||
|
||||
云端画布 Agent 已分离行为策略、用户目标、参考事实和运行状态。续聊保留已送达插话,不再继承代码预设的创作自由;旧待办只作上下文,可移除取消项,催办不会强制工具调用或无限重复。提示词来源与发布约束见[画布 Agent 提示词与用户意图](/docs/backend/agent-prompt-policy),真实模型行为仍待场景验收。
|
||||
|
||||
## 导演台 3D-BOX 核心 MVP(待真实页面验收)
|
||||
|
||||
导演台默认进入“快速镜头”工作流:演员、白模姿态、景别、运镜、当前视图设机位和预演入口集中在同一条路径;完整摆场、骨骼、动画和时间轴能力保留在“高级工作台”。“生成预演”沿用真实 Three.js 视口录制白模视频,并把产物回写为画布视频节点。画布 Agent 新增 `director_scene_read` 安全摘要读取和 `director_preview` 预演请求,后端不返回模型 URL / storage key,浏览器导演台执行实际录制。该版本是自研的 3D-BOX 核心闭环,不复制第三方实现;复杂场景编辑、Agent 语义写入和多镜头剪辑仍在后续阶段。
|
||||
|
||||
## 技能库个人分类与画布 Agent 筛选
|
||||
|
||||
技能库保留原有头部和技能广场共享分类;在“我的技能 / 我创建的”视图增加左侧个人技能库分类及技能数量。用户可为已加入或自建技能创建、分配个人分类;管理员也可创建对所有用户可见、可选、可用于筛选的分类。个人分类仅影响当前用户的技能库和画布 Agent,不改动技能广场共享分类。删除分类只解除相关归类,技能仍保留。画布 Agent 的“我的技能 / 已启用”列表可按个人或平台技能库分类快速筛选,市场页仍按共享分类浏览。
|
||||
|
||||
## 画布保存保护与版本记录
|
||||
|
||||
旧页面或旧缓存不能覆盖云端新内容。每次内容保存核对服务端版本,发生冲突会停止该画布自动提交并保留本地草稿;平移、缩放和打开画布不触发整份内容保存。画布顶部显示保存状态,可保留草稿后加载云端最新版。
|
||||
@@ -408,3 +448,9 @@ SEO 标题、描述、可选关键词会投影到浏览器 metadata、Open Graph
|
||||
## 画布生成工具(待本地验收)
|
||||
|
||||
画布支持风格、运镜、九宫格提示词工具及自定义特效工具,提供收藏和私有自定义工具。工具仅加入提示词或创建待生成子节点,选择工具不自动发起生成。画布左侧提供主页、折叠、节点、资产、任务和历史菜单,不再提供独立工具菜单,展开面板沿用主分支主题。资产支持分类、搜索、分页和直接插入,复用现有素材服务及插入合同;任务和历史独立,历史明确展示最近 30 条。图片节点直接展示风格和预设,不再展示提示词模板入口;其他节点的提示词模板保持不变。
|
||||
|
||||
## 平台技能策展
|
||||
|
||||
后台可选开启子分类维护,市场和技能库支持子分类浏览;默认关闭,保留原行为。
|
||||
|
||||
开启时一级分类也可在后台新增、改名、排序、停用和选择图示,未归入技能仍有默认入口。
|
||||
|
||||
@@ -5,6 +5,167 @@ description: 当前项目已实现功能的手工验证清单与未确认边界
|
||||
|
||||
# 待测试
|
||||
|
||||
## 复制生图节点后节点消失
|
||||
|
||||
- 已修复:副本不再继承原节点的 `generationEffectKeys`,避免普通保存把它误判为未确认的生成结果。图片内容、提示词和参考字段仍保留,原节点不受影响。
|
||||
- [x] 回归测试在修改前复现副本无法保存;修改后覆盖复制、普通保存、新生成结果提交及重新读取。
|
||||
- [ ] 在真实画布中通过复制粘贴和“创建副本”分别验证,生成完成并刷新后副本仍保留。已丢失的副本不会自动恢复,也不会自动重试生图。
|
||||
|
||||
## Agent 视频首尾帧选择
|
||||
|
||||
- 已实现:生成工具支持明确指定首尾帧,视频节点编辑支持设置和取消已连接的图片;画布读取和生成审批展示当前选择。
|
||||
- [x] 专项测试覆盖工具字段、视频模式和图片引用校验、编辑与取消、禁止其他节点类型修改帧字段。
|
||||
- [x] PostgreSQL 独立测试区验证帧选择进入任务输入和持久化草稿,协议按明确字段识别首尾帧,不依赖参考数组顺序;未调用外部模型,测试区已删除。
|
||||
- [ ] 开启新的 Agent 对话,确认 Agent 能设置下方首尾帧选项,刷新后仍保留;用户确认后再批准真实视频生成。
|
||||
|
||||
## 上传内容与附件交付
|
||||
|
||||
- [ ] 运行 `TestUploadContentImportSocket` 验证 URL 导入与重试;在可解析外部存储域名的环境复测 `TestResolveAccessPolicyMatrix`。
|
||||
- [ ] PostgreSQL 上传重试、真实 OSS 附件代理与浏览器附件下载验收。
|
||||
|
||||
## 排队后的自定义渠道检查
|
||||
|
||||
- [ ] PostgreSQL 环境验证排队期间关闭自定义渠道:首次与重试任务均停止调用,未发出订单退款,已提交或待核对订单保持待核对。
|
||||
|
||||
## Agent 失败消息合并与展示
|
||||
|
||||
- 已修复:同一运行的 `run_failed` / `error` 与失败状态快照共用一条错误消息;以公开失败原因补全内容,重放、乱序和空原因不覆盖已有详细说明。不同运行即使错误文本相同也分别保留,工具失败与连接错误不合并。
|
||||
- 已调整:错误提示使用紧凑中性表面和状态图标,不重复渲染相同的标题与正文;诊断号放入默认折叠、支持键盘展开的「诊断信息」。旧对话中带相同运行 ID 的事件错误与终态提示只展示一次。
|
||||
- [x] 自动专项测试通过:8 个 Agent 错误/对话相关测试文件共 77 项通过、0 失败(304 个断言);前端 `tsc --noEmit` 与本次文件 Prettier 检查通过。
|
||||
- [x] 已在本地真实登录画布的历史失败对话中核对:同一失败只显示一张错误卡,模型调用失败原因仍可见;展开「诊断信息」可看到诊断号,未触发新的模型生成或写入操作。
|
||||
- [ ] 明暗画布、窄面板与长错误文本的可读性,以及诊断展开、键盘焦点和历史滚动体验。
|
||||
|
||||
## 画布 Midjourney 四图堆叠
|
||||
|
||||
- 已修复:画布按一次任务的真实输出数组保留全部图片,以现有图片批次机制默认堆叠,每张图保留资源和素材绑定;单图仍为单节点。
|
||||
- 已实现:稳定子节点 ID 和整批持久化,任务重放保留用户移动、改名及其他画布内容;成功的旧 Midjourney 首图节点可从原任务补齐。
|
||||
- [ ] 用户验收四图默认堆叠、展开、切换主图、保存和刷新后的完整结果。
|
||||
|
||||
## 卡藏 Midjourney
|
||||
|
||||
- 已实现:三个声明式生图协议、公开模型与参考图限制校验、稳定版参数默认映射、受理和任务查询、顶层/data 信封解析、所有单图及可选四宫格保存。
|
||||
- 已实现:选择协议自动填入默认能力;特惠 16:9、稳定/高速 9:16;参考图分别 1/5 张,固定一次提交,无蒙版或未声明的分辨率参数。
|
||||
- [ ] 用户验收默认参数、真实特惠与稳定版任务、图片保存和刷新后的完整显示。
|
||||
- [ ] 多参考图、Raw/数值画质与风格扩展参数的供应商实测,以及全部版本的真实生成;不以两条文生图验收替代这些边界。
|
||||
|
||||
## 沧元 Midjourney V7 与 V8.2
|
||||
|
||||
- 已实现:独立声明式插件及 V7、1K/2K Provider,固定一次提交、URL 响应、全部结果提取;参考图、编辑、蒙版、速度及模型名按各线路合同校验。
|
||||
- [x] 协议专项与完整 `internal/protocol` 测试通过,覆盖多图响应、查询端点、错误、非法模型与媒体输入,以及包内文档合同一致性。
|
||||
- [x] V7 实际任务完成,四张 1456×816 PNG 均已写入 OSS。一次请求返回多图不增加生成次数;积分价格由部署者配置,不代表供应商费用。
|
||||
- 已修复:创作页按完整任务消费多图结果,保持真实 outputIndex,避免逐图投影为 outputIndex=0 后被素材及消息幂等去重合并。
|
||||
- 已实现:选择 V7/V8.2 协议自动载入专属能力默认值;V8.2 空模型名暂用 1K,上游模型改为 `midjourney-2k` 自动切换预设档位并保留其他参数和价格。
|
||||
- [ ] 用户验收协议选择、1K/2K 档位联动、保存并重新打开的能力参数,以及重新提交后的创作页四图显示。
|
||||
- [ ] 用户验收原提示词的 V7 生成效果、全部图片显示和刷新后的保存结果。
|
||||
- [ ] 1K/2K 实际生成与保存:官网 CDN HTTP 403 已确认,需供应商提供可下载地址或解决访问限制后验证;协议测试不替代该线路实际保存验收。
|
||||
- [ ] 参考图、蒙版、style/moodboard 及 fast 档的上游执行验收;专项测试仅验证请求合同。
|
||||
|
||||
## 自定义更新公告
|
||||
|
||||
- 已实现:站点及外观新增更新公告页签,开关控制原日志/自定义公告;多版本文字、图片和视频可排序并选择整行/半行布局,保存同步公共外观状态。
|
||||
- [ ] 用户验收实际发布内容、版本排序、图片比例和视频播放效果;关闭并重新启用确认保存的自定义内容仍保留。
|
||||
|
||||
## 画布助手身份与名称同步
|
||||
|
||||
- 已实现:后台助手名称与内置身份共用外观配置,新对话及已有对话的后续回合采用最新名称;历史消息和运行快照保留,工具权限不变。
|
||||
- 专项覆盖:保存名称进入规范提示词、续聊改名、品牌独立、名称 JSON 编码、缓存键变化、历史保留、配置读取失败及前端刷新失败保留旧值。
|
||||
- [ ] 用户验收在「站点及外观 → 画布配置」改名保存,切回画布后新开或继续对话询问身份,与界面名称一致。
|
||||
|
||||
## AutoDL 画面规格简化
|
||||
|
||||
- 已实现:去除画面规格开关与额外说明,保留原标题、副标题和字段样式;完整分辨率多选与默认值始终可编辑、生效,仅允许当前插件工作流预设,删除旧草稿和开关分支。
|
||||
- 专项覆盖:所选列表与默认值保存恢复、画布过期选择、真实组件渲染;后端插件预设校验、保存与目录、价格范围、任务校验和声明式请求传参。
|
||||
- [ ] 用户验收真实页面多选增删、默认值联动、保存与重新打开,确认仅显示六种插件预设及所选值生效。
|
||||
- [ ] 用户验收实际 AutoDL GPU 生成,确认选定完整标签对应横、竖和方形输出;专项测试不替代付费上游执行。
|
||||
|
||||
## 素材彻底删除恢复不拦截、CI 提速与大文件拆分
|
||||
|
||||
- 已恢复:`DELETE /assets/:id`、批量删除、清空回收站、回收站素材删除与过期自动清理不再被画布、任务、项目或画布历史快照引用拦截(9 月 21 日 dc1ad680 的契约,9 月 24 日 5b382726 曾误收紧)。事务移除对应历史资源索引,物理对象经 Outbox 异步删除;其他素材复用的资源继续保留。与 `http-api.mdx`、`openapi.yaml` 及删除确认弹窗文案一致。
|
||||
- 已修复:审批后的媒体等待在服务停机被取消时,不再继续回写与恢复运行时;`MediaTaskID` 保留,重启后重新挂上等待。
|
||||
- CI 提速:每次构造 Service 都会完整解压 85MB 官方插件包(每次约 4 秒,1000 余个用例累计 7 分钟以上)。现启动只读清单、进程内缓存官方包读取结果、支付运行目录只解压本机平台的可执行文件;`internal/app` 本地由约 488 秒降到约 144 秒。发布流程的镜像构建与质量检查并行(可变标签推广仍等待检查通过),PR 连续推送取消旧检查。
|
||||
- 拆分:`cloud_agent_runtime.go`、`cloud_agent_tools.go`、`cloud_agent_pi_coordinator.go`、`workflow_provider.go`、`repository.go`、Agent 面板与输入区按职责拆成多个文件,逐声明校验为纯移动;新文件带职责说明。
|
||||
- [x] 后端 `go vet ./...`、`go test ./...` 全部通过(依赖 Postgres/Redis 的 7 个用例本地跳过,CI 会执行);新增取消等待、插件包按需解压与本机平台产物回归用例。
|
||||
- [x] 前端 `tsc`、lint、改动文件格式检查与 2103 项测试通过。
|
||||
- [ ] 真实页面:删除被画布引用的素材应直接成功;画布再次打开时断链由修复流程处理;共享给其他素材的文件仍可访问。
|
||||
- [ ] 推送后确认 GitHub Actions 后端检查耗时下降,镜像构建与检查并行、检查失败时不会推广 latest / 版本标签。
|
||||
|
||||
## 后端统一日志与降噪
|
||||
|
||||
- 已实现:新增 `backend/internal/logging`,统一接管 slog、标准库 `log`、GORM 与 Gin 访问日志,级别与格式由 `CANVAS_LOG_LEVEL` / `CANVAS_LOG_FORMAT` 控制。`info` 下不再输出成功的查询类请求、成功 SQL、`[Agent] message_end` 等流式事件及常规画布自动保存;4xx/5xx、慢请求、慢 SQL、SQL 失败和 panic 仍会记录,SQL 不带参数值。
|
||||
- [x] `go build ./...`、`go test ./...` 与 `internal/logging` 单元测试通过。
|
||||
- [ ] 部署到服务器后观察一段时间的日志量,确认没有遗漏的高频输出;临时切换 `CANVAS_LOG_LEVEL=debug` 验证 Agent 事件与查询请求可以重新看到,再切回 `info`。
|
||||
- [ ] 若接入日志采集,验证 `CANVAS_LOG_FORMAT=json` 的字段(`request_id`、`status`、`latency_ms`)可被正确解析。
|
||||
|
||||
## 模型选择弹窗长描述与视口边界
|
||||
|
||||
- 已调整:共用 `ModelPicker` 的宽度由共享样式统一控制,移除按内容撑宽及触发器最小宽度约束;渠道描述支持换行,字号统一使用说明文字 token(12px),行高为 1.5,移除旧 9px / 10px 覆盖;模型名称与价格在空间不足时分行显示,长价格文本可换行。
|
||||
- 调用方排查:画布与创作、短剧新建/章节提取/分镜制作/项目默认模型、Agent 对话与设置、提示词优化、批量生成、图片编辑/蒙版/图层拆解及视频分段等入口复用同一组件,均继承修复。
|
||||
- [x] 现有模型分组、价格展示、共享样式、Agent 和分镜选择器共 20 项专项测试通过;不代表浏览器布局验收通过。
|
||||
- [ ] 真实页面验证 500 字中英文描述、连续无空格文本、长价格、禁用原因与无描述选项;检查 1440px / 768px / 390px 视口、明暗主题、靠近浏览器左右边缘的弹窗、键盘切换和关闭。本次未完成浏览器验收。
|
||||
|
||||
## 分镜视频预览画幅
|
||||
|
||||
- 已调整:分镜制作右侧的视频播放器使用媒体原始比例和完整画面适配,避免共享预览样式的固定 16:9 与 `object-fit: cover` 裁剪竖屏视频。
|
||||
- [ ] 真实分镜页面播放已有 9:16、16:9 视频,确认画面完整、控制条可用;切换镜头与历史版本,检查明暗主题和窄屏下的预览区滚动。本次仅核对组件与样式,未完成浏览器验收。
|
||||
## 角色卡引用与本地参考图交付
|
||||
|
||||
- 已修复:Agent 任务保留模型侧图片槽位,画布编辑器单独使用角色/图片编号;仅有角色卡输入时可解析图片别名,混合输入时不猜测、不交换素材。引用仍由真实角色节点和资源归属校验决定。
|
||||
- 已修复:OpenAI Images 插件允许 JSON 图片编辑请求携带 Base64 data URL,本地资源经后端授权读取后在内存中交付,不再错误要求公网存储地址;其他仅支持公网 URL 的协议要求不变。
|
||||
- [x] 用户已在本地真实画布测试,扶颦参考图生成完成并上传;未额外发起收费生成。此结果不代表最新主分支集成后的完整 Agent 流程或生产环境已验收。
|
||||
|
||||
## 导演台 3D-BOX 核心 MVP
|
||||
|
||||
- 已实现:默认快速镜头工作流、演员快速添加与落位、语义姿态/景别/运镜、当前视图设机位、真实 Three.js 白模预演视频及画布视频回写。
|
||||
- 已实现:画布 Agent 的 `director_scene_read` 安全摘要与 `director_preview` 请求桥;当前预演由已打开的浏览器导演台执行,不在后端伪造 Three.js 渲染。
|
||||
- [ ] 登录真实画布验收:快速/高级模式切换、添加演员、地面落位、姿态、景别、运镜、白模预演、视频节点回写。
|
||||
- [ ] Agent 场景验收:先读取导演场景,再请求指定镜头预演;确认只对当前画布/场景生效,确认模型 URL、storage key 等敏感字段不出现在工具结果。
|
||||
- [ ] 验收明暗主题、窄屏滚动、录制期间修改场景的快照保护、WebGL context loss 恢复;当前未启动开发服务器做真实浏览器验收。
|
||||
|
||||
## 技能库个人分类与画布 Agent 筛选
|
||||
|
||||
- 已实现:结构迁移 v39 增加用户技能库分类,v40 增加内置技能删除记录;个人分类与平台共享技能广场分类分离。管理员可创建平台分类,用户可为已加入或自建技能归类;删除分类只解除归类,删除内置技能后启动同步不会重新创建。技能库个人视图和画布 Agent 的“我的技能 / 已启用”列表均可按分类筛选。
|
||||
- [ ] 使用真实登录页面验收技能库左侧分类及数量、创建/分配/删除、未分类筛选;确认删除分类后技能仍存在,管理员平台分类对其他账号可见、可选,技能广场共享分类不变。
|
||||
- [ ] 在画布 Agent 技能选择弹窗分别验证“我的技能”和“已启用”的个人/平台分类筛选;市场页仍按共享分类筛选。
|
||||
- [ ] 在隔离 SQLite 与 PostgreSQL 数据库备份后执行 schema v39 / v40 `up` / `verify`,确认 `user_skill_states.library_category_id`、分类表和 `builtin_skill_tombstones` 迁移正确;未在生产数据库执行迁移或改写数据。
|
||||
|
||||
## 发布回归与资源引用保护
|
||||
|
||||
- 已修复:素材表现只在 `metadata_json` 引用资源时,批量删除和管理员资源检查仍识别该引用,不误删共享资源。已有回归覆盖共享对象、跨用户别名、事务回滚和删除队列。
|
||||
- 已更新:启动并行外观加载、主题联动、统一下拉框、画布首帧与 Agent 插话的回归断言;资源消费竞态测试通过模拟 HTTP 传输验证真实持久化链路,不依赖外部网络。
|
||||
- [ ] 升级到 schema 40 前备份数据库,执行正式迁移及 verify;验证已有渠道和逻辑模型继续生成唯一可读 ID,并确认内置技能删除记录不会在启动同步时被重新创建。
|
||||
- [ ] 登录真实页面验收素材删除、生成结果转画布、Agent 插话、SSE 断线续传及资源访问。健康检查不能代替这些路径。
|
||||
|
||||
## 注册服务协议后台配置
|
||||
|
||||
- 已实现:协议名称与条款正文由后台「登录与注册」第 3 区块配置,经 `PATCH /admin/settings/registration` 保存,公开下发在 `GET /auth/settings` 的 `agreementTitle` / `agreementContent`。标题未配置时跟随外观品牌名生成;正文按空行分段渲染,留空时注册页提示待补充。注册开关单独切换不会覆盖协议(后端按可选指针字段合并)。
|
||||
- [ ] 在真实后台改品牌名与协议正文后,用未登录浏览器打开注册页,确认勾选框与弹窗标题、正文段落在明暗主题下正确显示;再确认协议留空时的占位提示与开关关闭时的注册拦截文案。
|
||||
- [ ] 用管理员账号验证「注册开关」与「服务协议」两次保存互不覆盖,撤销与离开页面提醒不丢内容;未确认服务端并发写入与多管理员同时编辑的冲突表现。
|
||||
|
||||
## 工作区 100% 缩放下的界面密度
|
||||
|
||||
- 已收紧用户工作区侧栏、顶栏和导航行、画布桌面端 Dock、Agent 内边距及默认浮窗尺寸;Agent 旧的手动调整尺寸仍保留,可点标题栏「恢复 Agent 紧凑窗口」自行重置。技能组合标签维持透明底和彩色描边。
|
||||
- 画布编辑器左侧图标菜单与展开内容改用一块低圆角、半透明磨砂表面;删除双重标题、硬分隔线和搜索框边框。侧栏现在浮在真实画布上方,打开/折叠不再改变画布视口宽度;顶栏和左下缩放控件避开侧栏。工作区下拉菜单及共享单选下拉去掉高亮描边,用背景和阴影建立层次,键盘焦点保留低对比提示。仍待登录态真实页面验收明暗主题、画布节点透视、窄屏抽屉、菜单键盘导航和弹层层级。
|
||||
- [ ] 在已登录的真实画布和用户工作区以浏览器 100% 缩放验收明暗主题、侧栏展开/折叠、顶部/底部工具栏、Agent 历史与设置、输入区和标签横向滚动;再检查窄屏与触屏下是否截断或遮挡。当前本地独立浏览器会跳转登录页,未将静态检查视为视觉验收。
|
||||
|
||||
## 画布资源断链、前端发布兼容与画布热点
|
||||
|
||||
- 已实现:统一递归识别持久资源字段(含嵌套 `videoPreview`);保存前和历史快照保存时校验当前资源归属/ready 状态,资源缺失返回带路径和 ID 的结构化 409。显式修复保留坏版本历史但要求新版本完整且 revision CAS 成功。后台 `repair-canvas-resources` 默认只读,仅可清除确认缺失的派生视频预览;主媒体问题报告为 unresolved。
|
||||
- 已实现:哈希 chunk 采用长缓存,缺失资源不缓存;HTML 显式 `no-cache, must-revalidate`。静态容器发布保留当前与上一发布 chunk,并在保留窗口内清理更旧资源;Vite preload 失败只自动恢复一次,之后交由路由错误页,用户手动重试仍可用。已有数据卷不会凭空恢复首次部署前已删的 chunk。
|
||||
- 已实现:同步显式 repair/force 请求不会被正在运行的普通同步吞掉;素材元数据请求按账号 scope/generation 隔离迟到响应。画布内容 hash 对 viewport/revision-only 副本复用;视口更新走轻量路径;loading 节点共享画布级 ticker,页面隐藏时暂停该 ticker。
|
||||
- [ ] 先备份隔离/测试数据库,验证 `repair-canvas-resources` dry-run、`--apply`、重复运行幂等、并发 revision 冲突、只清派生 preview、不改主媒体;检查 unresolved 后人工恢复历史或重传。未扫描或改写生产数据库。
|
||||
- [ ] 使用发布测试卷连续发布三版以上:旧 tab 延迟触发旧 chunk 后仍可加载;验证 HTML 与哈希资源 Cache-Control、旧 chunk 404 不被 SPA fallback 改写,以及浏览器一次性恢复不循环。当前没有 CDN/Ingress 线上响应证据,Firefox MIME 具体响应类型未确认。
|
||||
- [ ] Firefox/Chrome/Safari 实际页面走关键 lazy route;检查离线草稿、登录切换和错误重试行为。尚未做真实浏览器/CDN 验收。
|
||||
- [ ] 使用 React Profiler 与长时间运行的大画布记录任务更新、节点数/可见数、主线程长任务和页面隐藏行为。当前只做结构性降热点,不推断整画布必然全量重渲染或已达到某个帧率。
|
||||
|
||||
## 画布媒体产出模型
|
||||
|
||||
- 产出模型与选用模型分开保存。生成成功才冻结产出模型;生成中、失败和只改模型下拉不改已有产出模型。
|
||||
- [ ] 打开画布外观「媒体信息」后,新生成的图片、视频、音频左下角显示模型展示名或模型 ID。图片右下角仍显示尺寸和体积。关闭开关后这两处都不显示。视频标题旁的宽高保持可见;视频播放时角标不盖住控制条。
|
||||
- [ ] 生成成功后把下拉改成另一个模型且不重新生成,角标仍是原来的产出模型。重新生成成功后角标换成新模型。
|
||||
- [ ] 上传、粘贴、宫格切分、截取、合并、提取音频不显示产出模型。节点详情和版本对比在没有产出模型时留空,不显示「默认模型」。搜索能按产出模型名称和选用模型找到节点。
|
||||
- [ ] 分享页和版本预览画布不显示产出模型。旧画布节点在重新生成成功之前不出现角标。
|
||||
- [ ] 真实浏览器验收尚未执行。
|
||||
|
||||
## 原任务 ID 媒体保存恢复
|
||||
|
||||
- [x] 故障注入:下载 503 后服务实例重建继续原任务、OSS 上传失败保留暂存文件及资源 ID、素材登记异常使任务成功事务回滚,登记恢复无需再次下载。
|
||||
@@ -1131,6 +1292,13 @@ PR #507 核心能力已按主分支实现保留,并补齐小视口尺寸约束
|
||||
- [ ] 登录后用 DeepSeek 等 chat-completion 渠道跑「开始一部新短剧 → AI 生成章节」,确认章节正常导入。
|
||||
- [ ] Claude、Gemini、OpenAI Responses 渠道各跑一次文本生成,确认系统指令生效且没有重复出现在正文里。
|
||||
|
||||
## AI 生成章节的同名项目处理
|
||||
|
||||
- 已实现:创建项目遇到同一用户下的重名时返回 HTTP/code 409、`reason=project_name_conflict`;前端只对该原因有限更换名称重试,其他冲突和服务错误直接显示,不调用模型。
|
||||
- [x] 隔离 PostgreSQL 的仓储和服务测试、HTTP 响应及前端重试边界测试通过:同用户重名返回结构化冲突、不同用户可同名、项目 ID 冲突不被误判、原项目和工作流不被覆盖;更换名称后可正常创建。
|
||||
- [ ] SQLite 同组用例待在启用 CGO 的环境运行。
|
||||
- [ ] 登录真实页面,用已存在项目的同一故事再次执行「AI 生成章节」,确认自动创建带后缀项目、章节正常导入,且只有一次模型生成请求;确认其他 HTTP 409 不触发重试。
|
||||
|
||||
## 画布智能引用
|
||||
|
||||
- [ ] 在简洁、专业模式及展开提示词面板中打开智能引用,检查明暗主题、弹层宽度和开关状态。
|
||||
@@ -2698,3 +2866,77 @@ SSE 现在按 revision 变化发送紧凑快照,无变化只 heartbeat;客
|
||||
画布页本轮改动:区域选择(底部工具栏胶囊切到「区域选择」)下滚轮改为上下平移画布,缩放保留给 Command/Ctrl + 滚轮(含触控板捏合);带 `data-canvas-wheel-scroll` 的节点内部区域仍保持自身滚动。顶栏分享按钮右侧新增「账户与设置」按钮,点击复用画布内「去设置」的 `navigateToSettings({ section: "channels", continueCreation: true })`,进入 `/settings?section=channels&continue=1`(顶部有「返回创作 / 保存并返回」,与模型缺失时的跳转一致,不新增全局配置弹窗)。曾尝试在画布内用抽屉内嵌设置页,因嵌套 Router 报错已移除。类型检查通过;待登录态浏览器验收:区域选择的滚轮方向与实际滚动手感,设置按钮跳转后返回画布时画布内容与滚动位置是否保持,以及设置项保存后画布生成默认值立即生效。
|
||||
|
||||
节点面板快捷键:`[data-canvas-node-panel]` 面板内任意位置按 ⌘/Ctrl + Enter 触发面板主按钮(目前只有创作面板的生成按钮带 `data-canvas-panel-submit`),生成中或提示词为空时按钮禁用,快捷键不拦截按键。待验收:文本框内按下不插入换行、输入法组合中不触发、面板内其他输入框与配置面板不被误触发。
|
||||
## 画布媒体交互与 Agent 循环止损复测(2026-09-23)
|
||||
|
||||
本轮针对画布媒体节点、生成任务状态及云端 Agent 重复读取问题完成实现和复测。代码仍未提交,以下结论基于当前工作区的专项测试与隔离本地浏览器环境,不代表已部署生产。
|
||||
|
||||
- [x] 第三方 API 已提交后,前后端均拒绝取消:任务存在 `providerRequestId`、取消状态、媒体阶段、未知运行阶段或已进入媒体保存阶段时不再显示取消按钮,也不接受取消请求。
|
||||
- [x] 图片、视频、音频下载改为浏览器直接导航 OSS/CDN 签名地址;不再 `fetch → Blob`,平台只签发短时地址,不中转媒体正文。隔离浏览器下载的 Host 为 `cn-nb1.rains3.com`。
|
||||
- [x] 生成节点初始状态统一显示“作品创作中”;“正在准备参考素材”和“正在连接上游”等技术阶段也统一映射为该文案。没有上游真实进度时不显示 `0%` 或素材准备假进度,只有上游返回真实进度才显示百分比。
|
||||
- [x] 图片预览弹窗增加非纯黑加载占位、边框、虚线内框、Spinner、错误态和加载完成淡入;已用 2.5 秒图片响应延迟在浏览器中验证加载态可见。
|
||||
- [x] 视频节点无持久化 poster 时主动从 OSS/CDN 视频取首帧;已验证首帧静态预览真实显示,视频资源请求返回 Range `206`,持久化 poster 仍优先使用对象存储地址。
|
||||
- [x] 视频播放器不再因未知音轨默认静音;已验证视频解码音频字节持续增加,`muted=false`,播放期间 `paused=false`,音量滑块可操作并从 100% 调至 85%。
|
||||
- [x] Agent 只读工具增加同参数缓存、同结果重复回放护栏、跨参数累计 32 次安全上限;识图按画布版本和资源限制重复调用,并受本轮总识图预算约束,超过上限直接结束本轮,避免继续消耗模型调用和 Token。附件事件序列已解析确认事故主要是只读工具循环(`canvas_get_state` 6 次、`canvas_read_storyboard` 2 次、`agent_profile_read` 4 次),不是单一图片识别失败。
|
||||
- [x] Agent 媒体审批快照忽略节点位置和展示性变化;仅移动节点不会使已审批生成失效,提示词、资源、连接、锁定状态和任务状态等真实生成输入变化仍会使审批失效。
|
||||
|
||||
自动验证记录:
|
||||
|
||||
- 前端 `bun run test:canvas`:37 项通过;媒体与生成显示专项:36 项通过。
|
||||
- 前端 `bun run typecheck`、`bun run lint`、`bun run build`:通过;构建仍有既有大 chunk 提示。
|
||||
- 后端 Agent 读取、识图、审批、媒体依赖专项:通过;资源/OSS、取消、上游进度专项:通过。
|
||||
- 后端全量 `go test ./...`:未通过,阻断点为既有 `TestPluginViewIncludesDocumentationForEveryOfficialProtocol` 插件视图数量断言(实际 99,对断言期望 97),与本轮媒体和 Agent 修复无直接关系;因此不能记录为后端全量通过。
|
||||
|
||||
仍待真实环境验收:
|
||||
|
||||
- [ ] 使用真实生产渠道重新执行 Agent 图片识别和“识别多张图片后命名节点”流程;本轮未再次调用付费生产模型。生产渠道仍建议将“最大参考图片数”设为 `0`,不需要识图的渠道不要暴露图片识别能力。
|
||||
- [ ] 使用真实 Agent 会话完成审批后仅移动节点、再提交生成的端到端验收;后端回归已覆盖该语义,真实模型会话尚未执行。
|
||||
- [ ] 对含音轨视频做人工听觉验收;当前隔离视频已由浏览器运行时确认音频解码和音量控制可用。
|
||||
- [ ] 修复或单独核对插件视图数量断言后,再执行后端全量测试;本轮不修改与媒体/Agent 无关的插件注册逻辑。
|
||||
|
||||
## Pi Agent runtime 与存储边界预发布验证(2026-09-29)
|
||||
|
||||
- 已实现:在线画布 Agent 切换到 Pi 原生会话 runtime;Go 保留权限、工具审批、模型桥和控制检查点,Pi JSONL 会话按运行 ID 持久化;画布能力工具、错误映射、技能渐进读取、运行时镜像依赖和存储运行策略已有回归覆盖。
|
||||
- 已修正验证门禁:旧的 2026-09-23 记录称 `TestPluginViewIncludesDocumentationForEveryOfficialProtocol` 固定期望 97、实际 99;当前断言已改为根据官方包和内置插件动态计算数量,该专项现已通过。不要把该历史记录当作当前未解决的失败。
|
||||
- 本地自动验证:后端 `go test ./... -count=1 -timeout=15m` 全量通过;PostgreSQL 资产迁移、资源字节修复及画布版本历史依赖用例通过。前端类型检查、退场 lint、全量测试(2096 项)和生产构建通过;文档站 `bun run types:check` 通过。
|
||||
- 本机没有 `redis-server`,因此 Redis 租约及缓存白名单两个真实 Redis 用例在全量本地运行中会跳过;质量工作流已安装 Redis、连接 PostgreSQL,并强制检查 5 个依赖型用例均真实执行并通过。需以 GitHub Actions 的结果作为合并/发布门禁。
|
||||
|
||||
仍待真实环境验收:
|
||||
|
||||
- [ ] GitHub Actions 确认 PostgreSQL / Redis 依赖测试、前后端检查、支付插件双架构 smoke 和 amd64/arm64 镜像构建全部通过后再部署。
|
||||
- [ ] 部署后使用真实登录态验证 Agent 多轮会话、Skill 按需读取、工具审批/继续、进程重启后的会话恢复,以及用户/画布之间的会话隔离;不以健康检查替代该链路。
|
||||
- [ ] 在隔离数据库备份上验收 schema v42 的 `cloud_agent_pi_sessions` 迁移与回滚方案;不得在生产服务器手工改数据库或代码。
|
||||
|
||||
## Agent 角色卡读取与图文参考待验收
|
||||
|
||||
画布角色卡仍为 `text` 节点,但角色设定由项目角色资产按当前版或固定版读取;Agent 的节点目录标注 `kind: character`,精读返回角色设定、形象/声音状态及图片参考就绪情况,不再把空 `content` 当作空角色卡。选择角色卡作为媒体参考时,后端从同一角色版本解析三视图图片,并把角色设定加入本次生成提示词;只选 `sourceNodeId` 则使用文字设定。审批期间角色版本变化会阻止旧输入提交。生成仍需用户确认或符合 auto 准入,不在读取时发起付费任务。
|
||||
|
||||
待登录态页面验收:对「扶颦」精读应返回实际外貌和服装;选择该卡生成时,审批/任务输入应同时包含该版设定与已绑定三视图;故意改动角色版本后旧审批不能提交。声音档案可精读,音频任务在未显式选择音色时采用角色绑定的 voiceKey 与声音指令;跨模型适配及真实音色效果仍需单独验收。此轮不代表生产已部署。
|
||||
|
||||
|
||||
## 存储满额生成拦截与 Live2D 开关稳定性(2026-09-30)
|
||||
|
||||
- 已修复:图片、视频、音频生成任务在创建、积分预留和上游调用之前检查账号文件容量;容量已满时返回配额错误并提示先清理素材,文本任务不受文件容量限制。普通画布与 Agent 媒体生成共用该 admission 边界。
|
||||
- 已修复:Agent 面板开合时保留 Live2D 入口组件和已加载模型,仅隐藏入口并暂停不可见渲染,不再因反复卸载、重建 PIXI/Live2D 上下文而短暂回退默认动态球。
|
||||
- 自动验证:后端纯 admission 专项测试通过(CGO 关闭,3 项);前端 Live2D 生命周期专项测试通过;前端生产构建通过。既有 Agent 位置测试在当前 Windows 环境因 Bun 将磁盘路径解析为 `/E:/...` 而未进入测试逻辑。
|
||||
|
||||
仍待真实环境验收:
|
||||
|
||||
- [ ] 将测试账号文件容量填满后,从普通画布和 Agent 分别提交图片、视频、音频生成,确认立即显示容量提示、没有创建计费订单、没有调用上游;清理出容量后可恢复生成。
|
||||
- [ ] 使用自定义 Live2D 模型连续开合 Agent 面板,确认不出现默认动态球闪回,拖动、窗口缩放和重新进入画布仍正常。
|
||||
|
||||
|
||||
## 后台存储资源用户筛选(2026-09-30)
|
||||
|
||||
- 已修复:后台存储资源列表的用户筛选不再只接受完整用户 ID;现在支持按用户 ID、用户名、昵称和邮箱进行不区分大小写的模糊匹配,并可与资源类型、状态、存储位置、资源关键词组合使用。
|
||||
- API 新增可读性更高的 `user` 查询参数,后端继续兼容旧 `userId` 参数;前端请求同时发送两者,避免滚动升级期间旧后端忽略新参数并错误返回全量资源。
|
||||
- 自动验证:后台 UI 回归 17 项通过;前端生产构建通过;后端参数规范化专项通过。SQLite 集成用例已补充四种用户字段匹配,但当前 Windows 本机 CGO/GCC 无法解析生成的对象文件,未在本机实际执行该数据库用例。
|
||||
|
||||
仍待真实环境验收:
|
||||
|
||||
- [ ] 在管理员后台存储资源页分别输入完整/部分用户名、昵称、邮箱和用户 ID,确认返回同一用户资源;再叠加类型、状态和存储位置筛选,确认分页与清空筛选正常。
|
||||
|
||||
## 平台技能策展
|
||||
|
||||
SQLite 与 HTTP recorder 已验证;PostgreSQL 16/17、前端构建及浏览器中的开关、分类维护、市场/技能库筛选、分页与明暗主题待验证。
|
||||
|
||||
一级分类还需 PostgreSQL 验证 46→47 与并发改归/删除,以及浏览器图示、根停用默认桶与空根表回落。handler 全套涉及 socket,受限环境中未完成。
|
||||
|
||||
Reference in New Issue
Block a user