diff --git a/app/api/canvas/agent-capabilities/route.ts b/app/api/canvas/agent-capabilities/route.ts index 3665a4ff7..fdbfeaccc 100644 --- a/app/api/canvas/agent-capabilities/route.ts +++ b/app/api/canvas/agent-capabilities/route.ts @@ -1,3 +1,4 @@ +import { PROJECT_AGENT_OPERATIONS, projectOperationAuthorized } from "@/lib/ai/canvas-agent-runtime/project-operation-catalog"; import { NextResponse } from "next/server"; import { z } from "zod"; import { and, eq } from "drizzle-orm"; @@ -28,6 +29,8 @@ export async function GET(request: Request) { return NextResponse.json( { workspace: project.workspace, + projectServices: PROJECT_AGENT_OPERATIONS.map(item => ({ ...item, authorized: projectOperationAuthorized(item) })), + utilityTools: ["getWeather", "createDocument", "updateDocument", "requestSuggestions", "loadProjectSkill"], capabilities: getCanvasAgentAccessManifest(config).filter( (item) => item.workspace === (project.workspace === "video" ? "video" : "canvas"), ), diff --git a/app/api/canvas/agent-chat/route.ts b/app/api/canvas/agent-chat/route.ts index 63beb9e14..69fd9ba5c 100644 --- a/app/api/canvas/agent-chat/route.ts +++ b/app/api/canvas/agent-chat/route.ts @@ -1,3 +1,5 @@ +import { registerProjectAgentTools } from "@/lib/ai/canvas-agent-runtime/project-tools"; +import { isZcodeWorkspaceAuthorized } from "@/lib/ai/canvas-agent-runtime/authorization"; import { createUIMessageStream, createUIMessageStreamResponse, @@ -79,8 +81,10 @@ export async function POST(request: Request) { const [ownedProject] = await db.select({ userId: canvasProject.userId, workspaceType: canvasProject.workspaceType }) .from(canvasProject).where(eq(canvasProject.id, projectId)).limit(1); if (!ownedProject || ownedProject.userId !== session.user.id) throw new AgentRunError("画布不存在", 404); + if (!isZcodeWorkspaceAuthorized(ownedProject.workspaceType)) throw new AgentRunError("视频画布暂未授权给 ZCode Agent,请使用手工功能。", 403); const isVideo = ownedProject.workspaceType === "video"; const preset = body.agentPresetId ? await getAccessibleAgentPresetById({ id: body.agentPresetId, userId: session.user.id }) : null; + if (preset && String(preset.type) === "video") throw new AgentRunError("视频技能暂未授权给 ZCode Agent", 403); if (body.agentPresetId && (!preset || preset.status !== "active")) throw new AgentRunError("此 Agent 预设不可用", 403); const objective = body.message.parts .filter((part) => part.type === "text") @@ -306,6 +310,8 @@ export async function POST(request: Request) { ), emit, }); + await registerProjectAgentTools({ session, projectId, request, objective: snapshot.objective, + definitions: tools.definitions, executable: tools.executable, emit }); const gateway = await createZcodeModelGateway(configured); activeModelController = new AbortController(); const status = await runZcodeCanvasTask({ diff --git a/components/canvas/LiblibVideoCanvasReplica.tsx b/components/canvas/LiblibVideoCanvasReplica.tsx index 4e0c4d856..35a7483c4 100644 --- a/components/canvas/LiblibVideoCanvasReplica.tsx +++ b/components/canvas/LiblibVideoCanvasReplica.tsx @@ -65,6 +65,7 @@ import { useState, } from "react"; import { toast } from "sonner"; +import { ZCODE_VIDEO_CANVAS_AUTHORIZED } from "@/lib/ai/canvas-agent-runtime/authorization"; import { CanvasAgentUiListener } from "./chat-panel/canvas-agent-ui-listener"; import type { CanvasAgentUiCommand } from "@/lib/ai/canvas-agent-runtime/ui-command"; import { VideoCanvasAgentPanel } from "./chat-panel/video-canvas-agent-panel"; @@ -11556,7 +11557,7 @@ export function LiblibVideoCanvasReplica({ /> ) : null} - {isVideoAgentOpen ? ( + {ZCODE_VIDEO_CANVAS_AUTHORIZED && (isVideoAgentOpen ? ( 视频 Agent - )} + ))} ZCode Agent 工具授权清单

ZCode Agent 工具授权清单

图片画布及非视频项目业务已授权;视频画布与分镜暂不授权;底层用户权限与服务开关仍生效。管理、密钥、支付、身份认证、系统任务和Claw不属于创作Agent工具。

共 312 项能力;每一项均保留实际执行方式与限制。接口鉴权不等于业务结果已完成。

范围能力授权工具 / 操作编号执行限制
canvas添加到对话已授权image_add_to_chat
canvas识物已授权image_pick_object
canvas高清增强已授权enhanceImage
canvas抠图去背已授权removeBackground
canvasAI洗图已授权image_ai_wash参数齐全时执行,否则打开真实交互面板
canvas图片改字已授权image_text_edit参数齐全时执行,否则打开真实交互面板
canvas框选抠图已授权boxCutout参数齐全时执行,否则打开真实交互面板
canvas局部编辑已授权localEditImage参数齐全时执行,否则打开真实交互面板
canvas排版替换已授权image_layout_replace
canvas比例调整已授权image_scale_adjust参数齐全时执行,否则打开真实交互面板
canvas去水印已授权removeWatermark
canvas尺寸调整已授权resizeImage参数齐全时执行,否则打开真实交互面板
canvas多视角已授权angleEditImage参数齐全时执行,否则打开真实交互面板
canvas生成3D模型已授权image_generate_3d_model参数齐全时执行,否则打开真实交互面板
canvas生成3D世界已授权image_generate_3d_world参数齐全时执行,否则打开真实交互面板
canvas图层拆分已授权image_layer_split
canvas扩图已授权extendImage
canvas裁剪已授权image_crop参数齐全时执行,否则打开真实交互面板
canvas画面调整已授权image_adjust
canvas翻转与旋转已授权image_flip_rotate参数齐全时执行,否则打开真实交互面板
canvas提示词重绘已授权editTargetImage参数齐全时执行,否则打开真实交互面板
canvas添加批注已授权image_note参数齐全时执行,否则打开真实交互面板
canvas重命名已授权image_rename参数齐全时执行,否则打开真实交互面板
canvas下载图片已授权image_download
canvas删除图片已授权image_delete需要用户明确要求及明确目标;模型不能自行确认
canvas画布主工具栏 · 选择已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas画布主工具栏 · 平移已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas画布主工具栏 · 保存到云端已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas画布主工具栏 · 云文件列表已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas画布主工具栏 · 标记已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas画布主工具栏 · 工作流连线已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas画布主工具栏 · 风格化模式已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas画布主工具栏 · 风格化 PRO已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas画布主工具栏 · 批量处理已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas画布主工具栏 · 添加图片已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas画布主工具栏 · 图片槽位已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas画布主工具栏 · 添加图片输入已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas画布主工具栏 · 添加文本已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas画布主工具栏 · 添加脚本节点已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas画布主工具栏 · 添加视频输入已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas画布主工具栏 · 视频工作流节点库已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas画布主工具栏 · 实时画布模式已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas画布主工具栏 · 图像增强模式已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas画布主工具栏 · 3D生成已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas画布主工具栏 · 导出视频画布已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas画布主工具栏 · 导入视频画布已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas画布主工具栏 · 新建画布已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas画布主工具栏 · 新建视频画布已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas画布快捷工具条 · 撤销已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas画布快捷工具条 · 重做已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas画布快捷工具条 · 缩小已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas画布快捷工具条 · 重置缩放已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas画布快捷工具条 · 放大已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas画布快捷工具条 · 下载文件夹已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas节点工具栏 · 更多操作已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas节点工具栏 · 添加对话已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas节点工具栏 · 识物已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas节点工具栏 · 高清已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas节点工具栏 · 抠图已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas节点工具栏 · 框选抠图已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas节点工具栏 · 局部编辑已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas节点工具栏 · 排版替换已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas节点工具栏 · 去水印已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas节点工具栏 · 尺寸已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas节点工具栏 · 文字已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas节点工具栏 · 多视角已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas节点工具栏 · 3D模型已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas节点工具栏 · 3D世界已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas节点工具栏 · 图层拆分已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas节点工具栏 · 扩图已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas节点工具栏 · 裁剪已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas节点工具栏 · 调整已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas节点工具栏 · 翻转与旋转已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas节点工具栏 · 重绘已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas节点工具栏 · 添加批注已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas节点工具栏 · 改名已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas节点工具栏 · 下载已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas节点工具栏 · 删除已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas节点工具栏 · 开启对比已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas节点工具栏 · 确认抠图已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas节点工具栏 · 取消抠图已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas节点工具栏 · 删除文本模块已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas节点工具栏 · 检查并修复 UI已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas节点工具栏 · 删除 UI Screen已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas节点工具栏 · 保存已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas节点工具栏 · 上传视频已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas节点工具栏 · 播放已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas节点工具栏 · 暂停已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas节点工具栏 · 静音已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas节点工具栏 · 取消静音已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas节点工具栏 · 更多操作已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas节点工具栏 · 下载已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas节点工具栏 · 删除已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas节点工具栏 · 删除模块已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas节点工具栏 · 打开 3D已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas节点工具栏 · 打开 World已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas节点工具栏 · 更多操作已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas节点工具栏 · 打开 Mesh已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas节点工具栏 · 打开图像已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas节点工具栏 · 下载已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas节点工具栏 · 复制链接已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas节点工具栏 · 删除已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas节点工具栏 · World 视图已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas节点工具栏 · 图像视图已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas节点工具栏 · Mesh 视图已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas节点工具栏 · 进入漫游已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas节点工具栏 · 添加热点已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas节点工具栏 · 更多操作已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas节点工具栏 · 打开 Mesh已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas节点工具栏 · 打开图像已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas节点工具栏 · 下载模型已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas节点工具栏 · 复制链接已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas节点工具栏 · 删除已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas实时画布工具栏 · 返回画布已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas实时画布工具栏 · 实时画布模式已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas实时画布工具栏 · 图像增强模式已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas实时画布工具栏 · 图层已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas实时画布工具栏 · 图层拆分导入已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas实时画布工具栏 · 添加图片图层已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas实时画布工具栏 · 下载图片已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas实时画布工具栏 · 鼠标已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas实时画布工具栏 · 画笔已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas实时画布工具栏 · 橡皮已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas实时画布工具栏 · 形状已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas实时画布工具栏 · 保存项目已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas实时画布工具栏 · 项目列表已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas实时画布工具栏 · 新建空白已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas实时画布工具栏 · 生成已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas实时画布工具栏 · 发送到画布已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas对话框工具栏 · Auto Agent已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas对话框工具栏 · 预设Agent已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas对话框工具栏 · Agent对话已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas对话框工具栏 · AI详情已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas对话框工具栏 · AI详情生成已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas对话框工具栏 · 生图已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas对话框工具栏 · 图像生成已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas对话框工具栏 · 视频已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas对话框工具栏 · 视频生成已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas对话框工具栏 · 上传图片已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas对话框工具栏 · 深度思考已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas对话框工具栏 · 选择模型已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas对话框工具栏 · 积分已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas对话框工具栏 · 发送已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas对话框工具栏 · 开始生成已授权openCanvasFeature操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成
canvas画布操作 · 创建输出槽位已授权editCanvasNodes
canvas画布操作 · 创建文本节点已授权editCanvasNodes
canvas画布操作 · 填充输出槽位已授权editCanvasNodes
canvas画布操作 · 在素材旁添加结果已授权editCanvasNodes
canvas画布操作 · 追加素材版本已授权editCanvasNodes
canvas画布操作 · 替换节点媒体已授权editCanvasNodes
canvas画布操作 · 添加标注已授权editCanvasNodes
canvas画布操作 · 节点连线已授权editCanvasNodes
canvas画布操作 · 移动节点已授权editCanvasNodes
canvas画布操作 · 删除节点已授权editCanvasNodes
canvas画布操作 · 重命名节点已授权editCanvasNodes
canvas画布操作 · 更新批注已授权editCanvasNodes
canvas画布操作 · 更新文本已授权editCanvasNodes
video剧情推演四宫格暂未授权runVideoCanvasFunction用户暂未授权视频画布能力
video角色三视图生成暂未授权runVideoCanvasFunction用户暂未授权视频画布能力
video多机位九宫格暂未授权runVideoCanvasFunction用户暂未授权视频画布能力
video25宫格连贯分镜暂未授权runVideoCanvasFunction用户暂未授权视频画布能力
video电影级光影校正暂未授权runVideoCanvasFunction用户暂未授权视频画布能力
video画面推演 - 3秒后暂未授权runVideoCanvasFunction用户暂未授权视频画布能力
video画面推演 - 5秒前暂未授权runVideoCanvasFunction用户暂未授权视频画布能力
video宫格切分暂未授权runVideoCanvasFunction用户暂未授权视频画布能力
video打光暂未授权runVideoCanvasFunction用户暂未授权视频画布能力
video高清暂未授权runVideoCanvasFunction用户暂未授权视频画布能力
video720 全景暂未授权runVideoCanvasFunction用户暂未授权视频画布能力
video扩图暂未授权runVideoCanvasFunction用户暂未授权视频画布能力
video重绘暂未授权runVideoCanvasFunction用户暂未授权视频画布能力
video擦除暂未授权runVideoCanvasFunction用户暂未授权视频画布能力
video抠图暂未授权runVideoCanvasFunction用户暂未授权视频画布能力
video裁剪暂未授权runVideoCanvasFunction用户暂未授权视频画布能力
video多角度编辑器暂未授权runVideoCanvasFunction用户暂未授权视频画布能力
video故事脚本生成暂未授权runVideoCanvasFunction用户暂未授权视频画布能力
video视频解析暂未授权runVideoCanvasFunction用户暂未授权视频画布能力
video图片反推提示词暂未授权runVideoCanvasFunction用户暂未授权视频画布能力
video视频元素标记暂未授权runVideoCanvasFunction用户暂未授权视频画布能力
video文生视频暂未授权runVideoCanvasFunction用户暂未授权视频画布能力
video首帧图生视频暂未授权runVideoCanvasFunction用户暂未授权视频画布能力
video首尾帧生成视频暂未授权runVideoCanvasFunction用户暂未授权视频画布能力
video音频生视频暂未授权runVideoCanvasFunction用户暂未授权视频画布能力;当前页面未接真实音频驱动视频后端,已授权入口但不能伪称完成音频驱动
video节点重命名暂未授权editVideoCanvas用户暂未授权视频画布能力
video节点移动暂未授权editVideoCanvas用户暂未授权视频画布能力
video复制节点暂未授权editVideoCanvas用户暂未授权视频画布能力
video删除节点暂未授权editVideoCanvas用户暂未授权视频画布能力
video工作流连线暂未授权editVideoCanvas用户暂未授权视频画布能力
video移除连线暂未授权editVideoCanvas用户暂未授权视频画布能力
video节点批注暂未授权editVideoCanvas用户暂未授权视频画布能力
video编辑文本暂未授权editVideoCanvas用户暂未授权视频画布能力
video添加文本节点暂未授权editVideoCanvas用户暂未授权视频画布能力
video排列节点暂未授权editVideoCanvas用户暂未授权视频画布能力
video画布缩放与定位暂未授权editVideoCanvas用户暂未授权视频画布能力
video真实视频截帧暂未授权processVideoMedia用户暂未授权视频画布能力;使用真实媒体处理并上传现有存储,不复用页面的模拟产物;单次视频不超过120秒
video真实视频剪辑导出暂未授权processVideoMedia用户暂未授权视频画布能力;使用真实媒体处理并上传现有存储,不复用页面的模拟产物;单次视频不超过120秒
video真实视频裁剪暂未授权processVideoMedia用户暂未授权视频画布能力;使用真实媒体处理并上传现有存储,不复用页面的模拟产物;单次视频不超过120秒
video提取完整音轨暂未授权processVideoMedia用户暂未授权视频画布能力;使用真实媒体处理并上传现有存储,不复用页面的模拟产物;单次视频不超过120秒
video生成无声视频暂未授权processVideoMedia用户暂未授权视频画布能力;使用真实媒体处理并上传现有存储,不复用页面的模拟产物;单次视频不超过120秒
video上传图片暂未授权openVideoCanvasFeature用户暂未授权视频画布能力
video上传视频暂未授权openVideoCanvasFeature用户暂未授权视频画布能力
video上传音频暂未授权openVideoCanvasFeature用户暂未授权视频画布能力
video下载素材暂未授权openVideoCanvasFeature用户暂未授权视频画布能力
video预览素材暂未授权openVideoCanvasFeature用户暂未授权视频画布能力
video局部编辑暂未授权openVideoCanvasFeature用户暂未授权视频画布能力
video标注暂未授权openVideoCanvasFeature用户暂未授权视频画布能力
video视频高清暂未授权openVideoCanvasFeature用户暂未授权视频画布能力;页面当前为占位/模拟流程;只授权设置入口,不执行模拟产物或声称媒体已处理
video选择视频剪辑范围暂未授权openVideoCanvasFeature用户暂未授权视频画布能力
video视频裁剪面板暂未授权openVideoCanvasFeature用户暂未授权视频画布能力;页面当前为占位/模拟流程;只授权设置入口,不执行模拟产物或声称媒体已处理
video去字幕面板暂未授权openVideoCanvasFeature用户暂未授权视频画布能力;页面当前为占位/模拟流程;只授权设置入口,不执行模拟产物或声称媒体已处理
video音视频分离面板暂未授权openVideoCanvasFeature用户暂未授权视频画布能力;页面当前为占位/模拟流程;只授权设置入口,不执行模拟产物或声称媒体已处理
video人声分离面板暂未授权openVideoCanvasFeature用户暂未授权视频画布能力;页面当前为占位/模拟流程;只授权设置入口,不执行模拟产物或声称媒体已处理
video背景音分离面板暂未授权openVideoCanvasFeature用户暂未授权视频画布能力;页面当前为占位/模拟流程;只授权设置入口,不执行模拟产物或声称媒体已处理
video导演台暂未授权openVideoCanvasFeature用户暂未授权视频画布能力
video分镜工作台暂未授权openVideoCanvasFeature用户暂未授权视频画布能力
video批量生成分镜暂未授权openVideoCanvasFeature用户暂未授权视频画布能力
video批量生成视频暂未授权openVideoCanvasFeature用户暂未授权视频画布能力
video素材库暂未授权openVideoCanvasFeature用户暂未授权视频画布能力
video角色库暂未授权openVideoCanvasFeature用户暂未授权视频画布能力
video风格库暂未授权openVideoCanvasFeature用户暂未授权视频画布能力
video特效库暂未授权openVideoCanvasFeature用户暂未授权视频画布能力
video生成历史暂未授权openVideoCanvasFeature用户暂未授权视频画布能力
video工作流模板暂未授权openVideoCanvasFeature用户暂未授权视频画布能力
video保存画布暂未授权openVideoCanvasFeature用户暂未授权视频画布能力
video导出画布暂未授权openVideoCanvasFeature用户暂未授权视频画布能力
video导入画布暂未授权openVideoCanvasFeature用户暂未授权视频画布能力
video分享设置暂未授权openVideoCanvasFeature用户暂未授权视频画布能力
video发布设置暂未授权openVideoCanvasFeature用户暂未授权视频画布能力
video视频技能暂未授权openVideoCanvasFeature用户暂未授权视频画布能力
video帮助与快捷键暂未授权openVideoCanvasFeature用户暂未授权视频画布能力
video提取首帧暂未授权openVideoCanvasFeature用户暂未授权视频画布能力;页面当前为占位/模拟流程;只授权设置入口,不执行模拟产物或声称媒体已处理
video提取尾帧暂未授权openVideoCanvasFeature用户暂未授权视频画布能力;页面当前为占位/模拟流程;只授权设置入口,不执行模拟产物或声称媒体已处理
video提取指定时间帧暂未授权openVideoCanvasFeature用户暂未授权视频画布能力;页面当前为占位/模拟流程;只授权设置入口,不执行模拟产物或声称媒体已处理
技能可访问技能列表已授权skills.getquery: categoryId、search(可选)。执行技能前用 loadProjectSkill 读取真实提示词和参数,再由当前原生核心编排已有工具。
技能技能分类已授权skill-categories.get无需参数
素材商品 SKU/SPU 素材检索已授权materials.getquery: keyword必填,source=primary/secondary、queryType=sku/spu、requiredCount可选
素材参考图检索已授权references.getquery: keyword、source、queryType;以接口返回的实际素材为准
素材素材外观识别已授权appearance.postbody: imageUrls等图片参数,接口验证服务配置与格式
素材第三方图片素材检索已授权third-party-materials.getquery: keyword、page、pageSize;沿用站点数据权限
素材图库素材已授权gallery.getquery: page、pageSize、category、keyword可选
素材精选素材已授权featured.getquery: category、page可选
素材素材排行榜已授权ranking.getquery: type、limit可选
PSDPSD 模板列表已授权psd-templates.getquery: category、keyword可选
PSDPSD 模板图层信息已授权psd-template.getpathParams: id=模板编号
PSDPSD 真正渲染与任务状态已授权psd-render.getPOST body: templateId必填,imageAssignments/textAssignments/hiddenLayerIds/layerOrderIds/imagePlacements等;GET query: taskId。pending/running只代表已受理,必须轮询到succeeded且有result.url才可交付。
PSDPSD 真正渲染与任务状态已授权psd-render.postPOST body: templateId必填,imageAssignments/textAssignments/hiddenLayerIds/layerOrderIds/imagePlacements等;GET query: taskId。pending/running只代表已受理,必须轮询到succeeded且有result.url才可交付。
详情与设计详情页与 UI 设计规划已授权detail-plan.postbody: prompt、图片和设计上下文;遵循接口校验
详情与设计详情结果验收已授权detail-review.postbody: prompt、imageUrls等真实设计图信息
详情与设计详情主体分析已授权detail-subject.postbody: 图片与产品信息
详情与设计UI 页面验收已授权ui-review.postbody: 真实页面设计文档与审核要求
详情与设计图片文案建议已授权text-copy.postbody: imageUrl、prompt等文案上下文
详情与设计详情图片拼接已授权detail-stitch.postbody: images或imageUrls等拼接参数
详情与设计详情图片归一化已授权detail-normalize.postbody: 图片链接与尺寸参数
详情与设计风格化可用模型已授权style-models.get无需参数,不返回密钥
详情与设计风格化 PRO 生成已授权style-generate.postbody: 模型、提示词与参考图,遵守用户指定模型;不改站点配置
详情与设计AI 图像处理可用模型已授权wash-models.get无需参数
详情与设计AI 图像处理已授权wash-generate.postbody: 用户图像与参数;结果未确认不能重提收费任务
商品策划商品图片分析已授权planning-image.postbody: imageUrl与产品上下文;底层功能开关仍生效
商品策划商品 SKU 分析已授权planning-sku.postbody: sku与用户商品信息
商品策划评价与问大家分析已授权planning-analysis.postbody: kind=review/qa,rows为真实评价或问答数组
商品策划关键词洞察已授权planning-keywords.getquery: keyword等检索参数
商品策划taobao 商品详情已授权planning-taobao-item.getquery: itemId等商品编号
商品策划jd 商品详情已授权planning-jd-item.getquery: itemId等商品编号
商品策划淘宝真实评价已授权planning-reviews.getquery: itemId、page等
商品策划淘宝月销量已授权planning-sales.getquery: itemId
商品策划淘宝问大家已授权planning-qa.postbody: itemId等商品编号
商品策划平台商品检索已授权planning-market-items.postbody: platform、keyword等检索参数
商品策划策划模板列表与保存已授权planning-templates.getPOST body: title与策划内容;只保存当前用户自己的模板
商品策划策划模板列表与保存已授权planning-templates.postPOST body: title与策划内容;只保存当前用户自己的模板
商品策划策划模板读取与删除已授权planning-template.getpathParams: id;删除需要用户明确指定此编号
商品策划策划模板读取与删除已授权planning-template.deletepathParams: id;删除需要用户明确指定此编号
流程白板白板文件列表与创建已授权flow-files.getPOST body: title、snapshot;snapshot必须为真实白板快照
流程白板白板文件列表与创建已授权flow-files.postPOST body: title、snapshot;snapshot必须为真实白板快照
流程白板白板文件读取、修改、删除已授权flow-file.getpathParams: id;PUT body: title、snapshot;先读取原文件,保留无关节点和工作表;删除需明确指定编号
流程白板白板文件读取、修改、删除已授权flow-file.putpathParams: id;PUT body: title、snapshot;先读取原文件,保留无关节点和工作表;删除需明确指定编号
流程白板白板文件读取、修改、删除已授权flow-file.deletepathParams: id;PUT body: title、snapshot;先读取原文件,保留无关节点和工作表;删除需明确指定编号
流程白板白板草稿读取与保存已授权flow-draft.getPUT body: title、snapshot;只操作当前用户草稿
流程白板白板草稿读取与保存已授权flow-draft.putPUT body: title、snapshot;只操作当前用户草稿
分镜任务视频模型能力与参数暂未授权video-capabilities.getquery: modelId等;沿用用户模型
分镜任务用户视频任务列表暂未授权video-tasks.getquery: page、limit等;仅当前用户任务
分镜任务分镜任务与阶段推进暂未授权storyboard-task.getpathParams: taskId;读取实际状态后再按接口动作推进,不重启已有收费任务
分镜任务确认用户分镜参数暂未授权storyboard-confirm.postpathParams: taskId;body: 用户实际确认的镜头与参数,不虚构用户确认
分镜任务停止指定分镜任务暂未授权storyboard-cancel.postpathParams: taskId;需用户明确要求停止此编号
分镜任务分镜镜头修订暂未授权storyboard-shot.patchpathParams: taskId、shotIndex;body: 用户要求的镜头修改
分镜任务指定镜头高清处理暂未授权storyboard-hd.postpathParams: taskId、shotIndex;会产生费用,只有用户要求高清才执行
项目Agent 创作项目列表与创建已授权agent-projects.getPOST body: title等项目数据;不写入其他用户项目
项目Agent 创作项目列表与创建已授权agent-projects.postPOST body: title等项目数据;不写入其他用户项目
项目Agent 创作项目读写已授权agent-project.getpathParams: id;修改先读当前内容,删除需用户明确指定编号
项目Agent 创作项目读写已授权agent-project.putpathParams: id;修改先读当前内容,删除需用户明确指定编号
项目Agent 创作项目读写已授权agent-project.deletepathParams: id;修改先读当前内容,删除需用户明确指定编号
项目用户画布列表与创建已授权canvas-list.getPOST body: title、workspaceType=canvas/video等
项目用户画布列表与创建已授权canvas-list.postPOST body: title、workspaceType=canvas/video等
项目读取用户画布已授权canvas-read.getpathParams: id;只读取当前用户有权限的画布,节点写入使用专用画布工具
项目画布详情归档已授权detail-archives.getpathParams: id=当前画布编号;body/query按详情归档接口,删除需明确授权
项目画布详情归档已授权detail-archives.postpathParams: id=当前画布编号;body/query按详情归档接口,删除需明确授权
项目画布详情归档已授权detail-archives.patchpathParams: id=当前画布编号;body/query按详情归档接口,删除需明确授权
项目画布详情归档已授权detail-archives.deletepathParams: id=当前画布编号;body/query按详情归档接口,删除需明确授权
项目3D 资产归档已授权model-assets.getpathParams: id=当前画布编号;只处理拥有权限的资产
项目3D 资产归档已授权model-assets.postpathParams: id=当前画布编号;只处理拥有权限的资产
项目3D 资产归档已授权model-assets.patchpathParams: id=当前画布编号;只处理拥有权限的资产
项目3D 资产归档已授权model-assets.deletepathParams: id=当前画布编号;只处理拥有权限的资产
3D3D 生成任务状态已授权3d-task.getpathParams: taskId;生成用已有3D专用能力,不重复提交
3D场景生成任务状态已授权world-task.getpathParams: taskId;生成用已有场景专用能力
智能编辑智能图层编辑能力已授权smart-edit.get无需参数;仅当该部署版本已有此功能时可用
文档读取与保存用户文档已授权documents.getquery: id=文档UUID;POST body: title、kind=text/code/sheet/image、content。更新前先读取原文档,不操作其他用户文档。
文档读取与保存用户文档已授权documents.postquery: id=文档UUID;POST body: title、kind=text/code/sheet/image、content。更新前先读取原文档,不操作其他用户文档。
图像处理专业高清处理任务与查询已授权enhance-pro.getPOST body按接口实际模型与尺寸要求,GET query: taskId。仅任务成功后才能交付,不能重复付费提交。
图像处理专业高清处理任务与查询已授权enhance-pro.postPOST body按接口实际模型与尺寸要求,GET query: taskId。仅任务成功后才能交付,不能重复付费提交。
文档、天气与技能getWeather已授权getWeather
文档、天气与技能createDocument已授权createDocument
文档、天气与技能updateDocument已授权updateDocument
文档、天气与技能requestSuggestions已授权requestSuggestions
文档、天气与技能loadProjectSkill已授权loadProjectSkill
\ No newline at end of file diff --git a/docs/specs/zcode-canvas/authorization-audit.json b/docs/specs/zcode-canvas/authorization-audit.json new file mode 100644 index 000000000..22aadd968 --- /dev/null +++ b/docs/specs/zcode-canvas/authorization-audit.json @@ -0,0 +1,3327 @@ +{ + "policy": "图片画布及非视频项目业务已授权;视频画布与分镜暂不授权;底层用户权限与服务开关仍生效。管理、密钥、支付、身份认证、系统任务和Claw不属于创作Agent工具。", + "upstreamCommit": "0a1fc56d279fd1001f78387bd81aec1c26767411", + "rows": [ + { + "id": "image.add_to_chat", + "workspace": "canvas", + "title": "添加到对话", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "image_add_to_chat" + }, + { + "id": "image.pick_object", + "workspace": "canvas", + "title": "识物", + "authorized": true, + "previouslyExposed": true, + "execution": "interactive", + "entry": "image_pick_object" + }, + { + "id": "image.enhance", + "workspace": "canvas", + "title": "高清增强", + "authorized": true, + "previouslyExposed": true, + "execution": "server", + "entry": "enhanceImage" + }, + { + "id": "image.remove_background", + "workspace": "canvas", + "title": "抠图去背", + "authorized": true, + "previouslyExposed": true, + "execution": "server", + "entry": "removeBackground" + }, + { + "id": "image.ai_wash", + "workspace": "canvas", + "title": "AI洗图", + "authorized": true, + "previouslyExposed": true, + "execution": "server", + "entry": "image_ai_wash", + "note": "参数齐全时执行,否则打开真实交互面板" + }, + { + "id": "image.text_edit", + "workspace": "canvas", + "title": "图片改字", + "authorized": true, + "previouslyExposed": true, + "execution": "interactive", + "entry": "image_text_edit", + "note": "参数齐全时执行,否则打开真实交互面板" + }, + { + "id": "image.box_cutout", + "workspace": "canvas", + "title": "框选抠图", + "authorized": true, + "previouslyExposed": true, + "execution": "server", + "entry": "boxCutout", + "note": "参数齐全时执行,否则打开真实交互面板" + }, + { + "id": "image.local_edit", + "workspace": "canvas", + "title": "局部编辑", + "authorized": true, + "previouslyExposed": true, + "execution": "interactive", + "entry": "localEditImage", + "note": "参数齐全时执行,否则打开真实交互面板" + }, + { + "id": "image.layout_replace", + "workspace": "canvas", + "title": "排版替换", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "image_layout_replace" + }, + { + "id": "image.scale_adjust", + "workspace": "canvas", + "title": "比例调整", + "authorized": true, + "previouslyExposed": true, + "execution": "interactive", + "entry": "image_scale_adjust", + "note": "参数齐全时执行,否则打开真实交互面板" + }, + { + "id": "image.remove_watermark", + "workspace": "canvas", + "title": "去水印", + "authorized": true, + "previouslyExposed": true, + "execution": "server", + "entry": "removeWatermark" + }, + { + "id": "image.resize", + "workspace": "canvas", + "title": "尺寸调整", + "authorized": true, + "previouslyExposed": true, + "execution": "server", + "entry": "resizeImage", + "note": "参数齐全时执行,否则打开真实交互面板" + }, + { + "id": "image.multi_angle", + "workspace": "canvas", + "title": "多视角", + "authorized": true, + "previouslyExposed": true, + "execution": "server", + "entry": "angleEditImage", + "note": "参数齐全时执行,否则打开真实交互面板" + }, + { + "id": "image.generate_3d_model", + "workspace": "canvas", + "title": "生成3D模型", + "authorized": true, + "previouslyExposed": false, + "execution": "server", + "entry": "image_generate_3d_model", + "note": "参数齐全时执行,否则打开真实交互面板" + }, + { + "id": "image.generate_3d_world", + "workspace": "canvas", + "title": "生成3D世界", + "authorized": true, + "previouslyExposed": false, + "execution": "server", + "entry": "image_generate_3d_world", + "note": "参数齐全时执行,否则打开真实交互面板" + }, + { + "id": "image.layer_split", + "workspace": "canvas", + "title": "图层拆分", + "authorized": true, + "previouslyExposed": true, + "execution": "server", + "entry": "image_layer_split" + }, + { + "id": "image.extend", + "workspace": "canvas", + "title": "扩图", + "authorized": true, + "previouslyExposed": true, + "execution": "server", + "entry": "extendImage" + }, + { + "id": "image.crop", + "workspace": "canvas", + "title": "裁剪", + "authorized": true, + "previouslyExposed": true, + "execution": "interactive", + "entry": "image_crop", + "note": "参数齐全时执行,否则打开真实交互面板" + }, + { + "id": "image.adjust", + "workspace": "canvas", + "title": "画面调整", + "authorized": true, + "previouslyExposed": true, + "execution": "interactive", + "entry": "image_adjust" + }, + { + "id": "image.flip_rotate", + "workspace": "canvas", + "title": "翻转与旋转", + "authorized": true, + "previouslyExposed": true, + "execution": "interactive", + "entry": "image_flip_rotate", + "note": "参数齐全时执行,否则打开真实交互面板" + }, + { + "id": "image.prompt_regenerate", + "workspace": "canvas", + "title": "提示词重绘", + "authorized": true, + "previouslyExposed": true, + "execution": "server", + "entry": "editTargetImage", + "note": "参数齐全时执行,否则打开真实交互面板" + }, + { + "id": "image.note", + "workspace": "canvas", + "title": "添加批注", + "authorized": true, + "previouslyExposed": true, + "execution": "server", + "entry": "image_note", + "note": "参数齐全时执行,否则打开真实交互面板" + }, + { + "id": "image.rename", + "workspace": "canvas", + "title": "重命名", + "authorized": true, + "previouslyExposed": true, + "execution": "server", + "entry": "image_rename", + "note": "参数齐全时执行,否则打开真实交互面板" + }, + { + "id": "image.download", + "workspace": "canvas", + "title": "下载图片", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "image_download" + }, + { + "id": "image.delete", + "workspace": "canvas", + "title": "删除图片", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "image_delete", + "note": "需要用户明确要求及明确目标;模型不能自行确认" + }, + { + "id": "canvas.ui.selectTool", + "workspace": "canvas", + "title": "画布主工具栏 · 选择", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.panTool", + "workspace": "canvas", + "title": "画布主工具栏 · 平移", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.saveCanvas", + "workspace": "canvas", + "title": "画布主工具栏 · 保存到云端", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.cloudFiles", + "workspace": "canvas", + "title": "画布主工具栏 · 云文件列表", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.markerPanel", + "workspace": "canvas", + "title": "画布主工具栏 · 标记", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.workflowConnection", + "workspace": "canvas", + "title": "画布主工具栏 · 工作流连线", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.styleMode", + "workspace": "canvas", + "title": "画布主工具栏 · 风格化模式", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.stylePro", + "workspace": "canvas", + "title": "画布主工具栏 · 风格化 PRO", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.batchProcessing", + "workspace": "canvas", + "title": "画布主工具栏 · 批量处理", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.addImage", + "workspace": "canvas", + "title": "画布主工具栏 · 添加图片", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.addAgentImageSlot", + "workspace": "canvas", + "title": "画布主工具栏 · 图片槽位", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.addImageInput", + "workspace": "canvas", + "title": "画布主工具栏 · 添加图片输入", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.addText", + "workspace": "canvas", + "title": "画布主工具栏 · 添加文本", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.addScriptNode", + "workspace": "canvas", + "title": "画布主工具栏 · 添加脚本节点", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.addVideoInput", + "workspace": "canvas", + "title": "画布主工具栏 · 添加视频输入", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.workflowNodeLibrary", + "workspace": "canvas", + "title": "画布主工具栏 · 视频工作流节点库", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.realtimeCanvas", + "workspace": "canvas", + "title": "画布主工具栏 · 实时画布模式", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.enhanceCanvas", + "workspace": "canvas", + "title": "画布主工具栏 · 图像增强模式", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.model3d", + "workspace": "canvas", + "title": "画布主工具栏 · 3D生成", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.exportVideoCanvas", + "workspace": "canvas", + "title": "画布主工具栏 · 导出视频画布", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.importVideoCanvas", + "workspace": "canvas", + "title": "画布主工具栏 · 导入视频画布", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.newCanvas", + "workspace": "canvas", + "title": "画布主工具栏 · 新建画布", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.newVideoCanvas", + "workspace": "canvas", + "title": "画布主工具栏 · 新建视频画布", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.undo", + "workspace": "canvas", + "title": "画布快捷工具条 · 撤销", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.redo", + "workspace": "canvas", + "title": "画布快捷工具条 · 重做", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.zoomOut", + "workspace": "canvas", + "title": "画布快捷工具条 · 缩小", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.resetZoom", + "workspace": "canvas", + "title": "画布快捷工具条 · 重置缩放", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.zoomIn", + "workspace": "canvas", + "title": "画布快捷工具条 · 放大", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.downloadFolder", + "workspace": "canvas", + "title": "画布快捷工具条 · 下载文件夹", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.imageNodeMore", + "workspace": "canvas", + "title": "节点工具栏 · 更多操作", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.imageAddToChat", + "workspace": "canvas", + "title": "节点工具栏 · 添加对话", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.imagePickObject", + "workspace": "canvas", + "title": "节点工具栏 · 识物", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.imageEnhance", + "workspace": "canvas", + "title": "节点工具栏 · 高清", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.imageRemoveBackground", + "workspace": "canvas", + "title": "节点工具栏 · 抠图", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.imageBoxCutout", + "workspace": "canvas", + "title": "节点工具栏 · 框选抠图", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.imageLocalEdit", + "workspace": "canvas", + "title": "节点工具栏 · 局部编辑", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.imageLayoutReplace", + "workspace": "canvas", + "title": "节点工具栏 · 排版替换", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.imageRemoveWatermark", + "workspace": "canvas", + "title": "节点工具栏 · 去水印", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.imageResize", + "workspace": "canvas", + "title": "节点工具栏 · 尺寸", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.imageTextEdit", + "workspace": "canvas", + "title": "节点工具栏 · 文字", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.imageMultiAngle", + "workspace": "canvas", + "title": "节点工具栏 · 多视角", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.imageGenerate3dModel", + "workspace": "canvas", + "title": "节点工具栏 · 3D模型", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.imageGenerate3dWorld", + "workspace": "canvas", + "title": "节点工具栏 · 3D世界", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.imageLayerSplit", + "workspace": "canvas", + "title": "节点工具栏 · 图层拆分", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.imageExtend", + "workspace": "canvas", + "title": "节点工具栏 · 扩图", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.imageCrop", + "workspace": "canvas", + "title": "节点工具栏 · 裁剪", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.imageAdjust", + "workspace": "canvas", + "title": "节点工具栏 · 调整", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.imageFlipRotate", + "workspace": "canvas", + "title": "节点工具栏 · 翻转与旋转", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.imagePromptRegenerate", + "workspace": "canvas", + "title": "节点工具栏 · 重绘", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.imageNote", + "workspace": "canvas", + "title": "节点工具栏 · 添加批注", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.imageRename", + "workspace": "canvas", + "title": "节点工具栏 · 改名", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.imageDownload", + "workspace": "canvas", + "title": "节点工具栏 · 下载", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.imageDelete", + "workspace": "canvas", + "title": "节点工具栏 · 删除", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.imageCompare", + "workspace": "canvas", + "title": "节点工具栏 · 开启对比", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.imageConfirmCutout", + "workspace": "canvas", + "title": "节点工具栏 · 确认抠图", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.imageCancelCutout", + "workspace": "canvas", + "title": "节点工具栏 · 取消抠图", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.textDelete", + "workspace": "canvas", + "title": "节点工具栏 · 删除文本模块", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.uiScreenReview", + "workspace": "canvas", + "title": "节点工具栏 · 检查并修复 UI", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.uiScreenDelete", + "workspace": "canvas", + "title": "节点工具栏 · 删除 UI Screen", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.uiScreenSaveText", + "workspace": "canvas", + "title": "节点工具栏 · 保存", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.videoUpload", + "workspace": "canvas", + "title": "节点工具栏 · 上传视频", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.videoPlay", + "workspace": "canvas", + "title": "节点工具栏 · 播放", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.videoPause", + "workspace": "canvas", + "title": "节点工具栏 · 暂停", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.videoMute", + "workspace": "canvas", + "title": "节点工具栏 · 静音", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.videoUnmute", + "workspace": "canvas", + "title": "节点工具栏 · 取消静音", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.videoMore", + "workspace": "canvas", + "title": "节点工具栏 · 更多操作", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.videoDownload", + "workspace": "canvas", + "title": "节点工具栏 · 下载", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.videoDelete", + "workspace": "canvas", + "title": "节点工具栏 · 删除", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.workflowDelete", + "workspace": "canvas", + "title": "节点工具栏 · 删除模块", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.model3dOpen3d", + "workspace": "canvas", + "title": "节点工具栏 · 打开 3D", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.model3dOpenWorld", + "workspace": "canvas", + "title": "节点工具栏 · 打开 World", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.model3dMore", + "workspace": "canvas", + "title": "节点工具栏 · 更多操作", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.model3dOpenMesh", + "workspace": "canvas", + "title": "节点工具栏 · 打开 Mesh", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.model3dOpenImage", + "workspace": "canvas", + "title": "节点工具栏 · 打开图像", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.model3dDownload", + "workspace": "canvas", + "title": "节点工具栏 · 下载", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.model3dCopy", + "workspace": "canvas", + "title": "节点工具栏 · 复制链接", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.model3dDelete", + "workspace": "canvas", + "title": "节点工具栏 · 删除", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.world3dViewSplat", + "workspace": "canvas", + "title": "节点工具栏 · World 视图", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.world3dViewImage", + "workspace": "canvas", + "title": "节点工具栏 · 图像视图", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.world3dViewMesh", + "workspace": "canvas", + "title": "节点工具栏 · Mesh 视图", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.world3dFirstPerson", + "workspace": "canvas", + "title": "节点工具栏 · 进入漫游", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.world3dHotspot", + "workspace": "canvas", + "title": "节点工具栏 · 添加热点", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.world3dMore", + "workspace": "canvas", + "title": "节点工具栏 · 更多操作", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.world3dOpenMesh", + "workspace": "canvas", + "title": "节点工具栏 · 打开 Mesh", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.world3dOpenImage", + "workspace": "canvas", + "title": "节点工具栏 · 打开图像", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.world3dDownload", + "workspace": "canvas", + "title": "节点工具栏 · 下载模型", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.world3dCopy", + "workspace": "canvas", + "title": "节点工具栏 · 复制链接", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.world3dDelete", + "workspace": "canvas", + "title": "节点工具栏 · 删除", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.realtimeReturnCanvas", + "workspace": "canvas", + "title": "实时画布工具栏 · 返回画布", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.realtimeModeRealtime", + "workspace": "canvas", + "title": "实时画布工具栏 · 实时画布模式", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.realtimeModeEnhance", + "workspace": "canvas", + "title": "实时画布工具栏 · 图像增强模式", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.realtimeLayerPanel", + "workspace": "canvas", + "title": "实时画布工具栏 · 图层", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.realtimeLayerSplitImport", + "workspace": "canvas", + "title": "实时画布工具栏 · 图层拆分导入", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.realtimeAddImageLayer", + "workspace": "canvas", + "title": "实时画布工具栏 · 添加图片图层", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.realtimeDownloadPreview", + "workspace": "canvas", + "title": "实时画布工具栏 · 下载图片", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.realtimeSelectTool", + "workspace": "canvas", + "title": "实时画布工具栏 · 鼠标", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.realtimeBrushTool", + "workspace": "canvas", + "title": "实时画布工具栏 · 画笔", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.realtimeEraserTool", + "workspace": "canvas", + "title": "实时画布工具栏 · 橡皮", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.realtimeShapeTool", + "workspace": "canvas", + "title": "实时画布工具栏 · 形状", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.realtimeSaveProject", + "workspace": "canvas", + "title": "实时画布工具栏 · 保存项目", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.realtimeProjectList", + "workspace": "canvas", + "title": "实时画布工具栏 · 项目列表", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.realtimeNewBlank", + "workspace": "canvas", + "title": "实时画布工具栏 · 新建空白", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.realtimeGenerate", + "workspace": "canvas", + "title": "实时画布工具栏 · 生成", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.realtimeSendToCanvas", + "workspace": "canvas", + "title": "实时画布工具栏 · 发送到画布", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.chatModeAgentActive", + "workspace": "canvas", + "title": "对话框工具栏 · Auto Agent", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.chatModePresetAgent", + "workspace": "canvas", + "title": "对话框工具栏 · 预设Agent", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.chatModeAgentMenu", + "workspace": "canvas", + "title": "对话框工具栏 · Agent对话", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.chatModeDetailActive", + "workspace": "canvas", + "title": "对话框工具栏 · AI详情", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.chatModeDetailMenu", + "workspace": "canvas", + "title": "对话框工具栏 · AI详情生成", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.chatModeImageActive", + "workspace": "canvas", + "title": "对话框工具栏 · 生图", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.chatModeImageMenu", + "workspace": "canvas", + "title": "对话框工具栏 · 图像生成", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.chatModeVideoActive", + "workspace": "canvas", + "title": "对话框工具栏 · 视频", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.chatModeVideoMenu", + "workspace": "canvas", + "title": "对话框工具栏 · 视频生成", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.chatAttach", + "workspace": "canvas", + "title": "对话框工具栏 · 上传图片", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.chatDeepThinking", + "workspace": "canvas", + "title": "对话框工具栏 · 深度思考", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.chatModelSelector", + "workspace": "canvas", + "title": "对话框工具栏 · 选择模型", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.chatPoints", + "workspace": "canvas", + "title": "对话框工具栏 · 积分", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.chatSend", + "workspace": "canvas", + "title": "对话框工具栏 · 发送", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.ui.chatStartGeneration", + "workspace": "canvas", + "title": "对话框工具栏 · 开始生成", + "authorized": true, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openCanvasFeature", + "note": "操作当前可见的真实入口;隐藏入口保持隐藏,文件选择、支付、登录、发布和发送消息由用户完成" + }, + { + "id": "canvas.operation.create_agent_slot", + "workspace": "canvas", + "title": "画布操作 · 创建输出槽位", + "authorized": true, + "previouslyExposed": false, + "execution": "server", + "entry": "editCanvasNodes" + }, + { + "id": "canvas.operation.create_text_node", + "workspace": "canvas", + "title": "画布操作 · 创建文本节点", + "authorized": true, + "previouslyExposed": false, + "execution": "server", + "entry": "editCanvasNodes" + }, + { + "id": "canvas.operation.fill_slot", + "workspace": "canvas", + "title": "画布操作 · 填充输出槽位", + "authorized": true, + "previouslyExposed": false, + "execution": "server", + "entry": "editCanvasNodes" + }, + { + "id": "canvas.operation.insert_beside", + "workspace": "canvas", + "title": "画布操作 · 在素材旁添加结果", + "authorized": true, + "previouslyExposed": false, + "execution": "server", + "entry": "editCanvasNodes" + }, + { + "id": "canvas.operation.append_revision", + "workspace": "canvas", + "title": "画布操作 · 追加素材版本", + "authorized": true, + "previouslyExposed": false, + "execution": "server", + "entry": "editCanvasNodes" + }, + { + "id": "canvas.operation.replace_node_media", + "workspace": "canvas", + "title": "画布操作 · 替换节点媒体", + "authorized": true, + "previouslyExposed": false, + "execution": "server", + "entry": "editCanvasNodes" + }, + { + "id": "canvas.operation.add_annotation", + "workspace": "canvas", + "title": "画布操作 · 添加标注", + "authorized": true, + "previouslyExposed": false, + "execution": "server", + "entry": "editCanvasNodes" + }, + { + "id": "canvas.operation.link_nodes", + "workspace": "canvas", + "title": "画布操作 · 节点连线", + "authorized": true, + "previouslyExposed": false, + "execution": "server", + "entry": "editCanvasNodes" + }, + { + "id": "canvas.operation.move_nodes", + "workspace": "canvas", + "title": "画布操作 · 移动节点", + "authorized": true, + "previouslyExposed": false, + "execution": "server", + "entry": "editCanvasNodes" + }, + { + "id": "canvas.operation.delete_nodes", + "workspace": "canvas", + "title": "画布操作 · 删除节点", + "authorized": true, + "previouslyExposed": false, + "execution": "server", + "entry": "editCanvasNodes" + }, + { + "id": "canvas.operation.rename_node", + "workspace": "canvas", + "title": "画布操作 · 重命名节点", + "authorized": true, + "previouslyExposed": false, + "execution": "server", + "entry": "editCanvasNodes" + }, + { + "id": "canvas.operation.update_note", + "workspace": "canvas", + "title": "画布操作 · 更新批注", + "authorized": true, + "previouslyExposed": false, + "execution": "server", + "entry": "editCanvasNodes" + }, + { + "id": "canvas.operation.update_text", + "workspace": "canvas", + "title": "画布操作 · 更新文本", + "authorized": true, + "previouslyExposed": false, + "execution": "server", + "entry": "editCanvasNodes" + }, + { + "id": "video.function.story-beat-grid-4", + "workspace": "video", + "title": "剧情推演四宫格", + "authorized": false, + "previouslyExposed": false, + "execution": "server", + "entry": "runVideoCanvasFunction", + "note": "用户暂未授权视频画布能力" + }, + { + "id": "video.function.character-three-view", + "workspace": "video", + "title": "角色三视图生成", + "authorized": false, + "previouslyExposed": false, + "execution": "server", + "entry": "runVideoCanvasFunction", + "note": "用户暂未授权视频画布能力" + }, + { + "id": "video.function.multi-view-nine-grid", + "workspace": "video", + "title": "多机位九宫格", + "authorized": false, + "previouslyExposed": false, + "execution": "server", + "entry": "runVideoCanvasFunction", + "note": "用户暂未授权视频画布能力" + }, + { + "id": "video.function.continuous-storyboard-grid-25", + "workspace": "video", + "title": "25宫格连贯分镜", + "authorized": false, + "previouslyExposed": false, + "execution": "server", + "entry": "runVideoCanvasFunction", + "note": "用户暂未授权视频画布能力" + }, + { + "id": "video.function.cinematic-lighting-correction", + "workspace": "video", + "title": "电影级光影校正", + "authorized": false, + "previouslyExposed": false, + "execution": "server", + "entry": "runVideoCanvasFunction", + "note": "用户暂未授权视频画布能力" + }, + { + "id": "video.function.frame-prediction-plus-3s", + "workspace": "video", + "title": "画面推演 - 3秒后", + "authorized": false, + "previouslyExposed": false, + "execution": "server", + "entry": "runVideoCanvasFunction", + "note": "用户暂未授权视频画布能力" + }, + { + "id": "video.function.frame-prediction-minus-5s", + "workspace": "video", + "title": "画面推演 - 5秒前", + "authorized": false, + "previouslyExposed": false, + "execution": "server", + "entry": "runVideoCanvasFunction", + "note": "用户暂未授权视频画布能力" + }, + { + "id": "video.function.grid-split", + "workspace": "video", + "title": "宫格切分", + "authorized": false, + "previouslyExposed": false, + "execution": "interactive", + "entry": "runVideoCanvasFunction", + "note": "用户暂未授权视频画布能力" + }, + { + "id": "video.function.lighting", + "workspace": "video", + "title": "打光", + "authorized": false, + "previouslyExposed": false, + "execution": "server", + "entry": "runVideoCanvasFunction", + "note": "用户暂未授权视频画布能力" + }, + { + "id": "video.function.hd-upscale", + "workspace": "video", + "title": "高清", + "authorized": false, + "previouslyExposed": false, + "execution": "server", + "entry": "runVideoCanvasFunction", + "note": "用户暂未授权视频画布能力" + }, + { + "id": "video.function.panorama-720", + "workspace": "video", + "title": "720 全景", + "authorized": false, + "previouslyExposed": false, + "execution": "server", + "entry": "runVideoCanvasFunction", + "note": "用户暂未授权视频画布能力" + }, + { + "id": "video.function.image-outpaint", + "workspace": "video", + "title": "扩图", + "authorized": false, + "previouslyExposed": false, + "execution": "server", + "entry": "runVideoCanvasFunction", + "note": "用户暂未授权视频画布能力" + }, + { + "id": "video.function.image-repaint", + "workspace": "video", + "title": "重绘", + "authorized": false, + "previouslyExposed": false, + "execution": "server", + "entry": "runVideoCanvasFunction", + "note": "用户暂未授权视频画布能力" + }, + { + "id": "video.function.image-erase", + "workspace": "video", + "title": "擦除", + "authorized": false, + "previouslyExposed": false, + "execution": "server", + "entry": "runVideoCanvasFunction", + "note": "用户暂未授权视频画布能力" + }, + { + "id": "video.function.remove-bg", + "workspace": "video", + "title": "抠图", + "authorized": false, + "previouslyExposed": false, + "execution": "server", + "entry": "runVideoCanvasFunction", + "note": "用户暂未授权视频画布能力" + }, + { + "id": "video.function.image-crop", + "workspace": "video", + "title": "裁剪", + "authorized": false, + "previouslyExposed": false, + "execution": "interactive", + "entry": "runVideoCanvasFunction", + "note": "用户暂未授权视频画布能力" + }, + { + "id": "video.function.angle-edit", + "workspace": "video", + "title": "多角度编辑器", + "authorized": false, + "previouslyExposed": false, + "execution": "server", + "entry": "runVideoCanvasFunction", + "note": "用户暂未授权视频画布能力" + }, + { + "id": "video.function.story-script", + "workspace": "video", + "title": "故事脚本生成", + "authorized": false, + "previouslyExposed": true, + "execution": "server", + "entry": "runVideoCanvasFunction", + "note": "用户暂未授权视频画布能力" + }, + { + "id": "video.function.video-analysis", + "workspace": "video", + "title": "视频解析", + "authorized": false, + "previouslyExposed": true, + "execution": "server", + "entry": "runVideoCanvasFunction", + "note": "用户暂未授权视频画布能力" + }, + { + "id": "video.function.image-to-prompt", + "workspace": "video", + "title": "图片反推提示词", + "authorized": false, + "previouslyExposed": true, + "execution": "server", + "entry": "runVideoCanvasFunction", + "note": "用户暂未授权视频画布能力" + }, + { + "id": "video.function.element-mark", + "workspace": "video", + "title": "视频元素标记", + "authorized": false, + "previouslyExposed": false, + "execution": "interactive", + "entry": "runVideoCanvasFunction", + "note": "用户暂未授权视频画布能力" + }, + { + "id": "video.function.text-to-video", + "workspace": "video", + "title": "文生视频", + "authorized": false, + "previouslyExposed": true, + "execution": "server", + "entry": "runVideoCanvasFunction", + "note": "用户暂未授权视频画布能力" + }, + { + "id": "video.function.first-frame-video", + "workspace": "video", + "title": "首帧图生视频", + "authorized": false, + "previouslyExposed": true, + "execution": "server", + "entry": "runVideoCanvasFunction", + "note": "用户暂未授权视频画布能力" + }, + { + "id": "video.function.first-last-frame-video", + "workspace": "video", + "title": "首尾帧生成视频", + "authorized": false, + "previouslyExposed": true, + "execution": "server", + "entry": "runVideoCanvasFunction", + "note": "用户暂未授权视频画布能力" + }, + { + "id": "video.function.audio-to-video", + "workspace": "video", + "title": "音频生视频", + "authorized": false, + "previouslyExposed": false, + "execution": "backend_required", + "entry": "runVideoCanvasFunction", + "note": "用户暂未授权视频画布能力;当前页面未接真实音频驱动视频后端,已授权入口但不能伪称完成音频驱动" + }, + { + "id": "video.node.rename", + "workspace": "video", + "title": "节点重命名", + "authorized": false, + "previouslyExposed": false, + "execution": "server", + "entry": "editVideoCanvas", + "note": "用户暂未授权视频画布能力" + }, + { + "id": "video.node.move", + "workspace": "video", + "title": "节点移动", + "authorized": false, + "previouslyExposed": false, + "execution": "server", + "entry": "editVideoCanvas", + "note": "用户暂未授权视频画布能力" + }, + { + "id": "video.node.duplicate", + "workspace": "video", + "title": "复制节点", + "authorized": false, + "previouslyExposed": false, + "execution": "server", + "entry": "editVideoCanvas", + "note": "用户暂未授权视频画布能力" + }, + { + "id": "video.node.delete", + "workspace": "video", + "title": "删除节点", + "authorized": false, + "previouslyExposed": false, + "execution": "server", + "entry": "editVideoCanvas", + "note": "用户暂未授权视频画布能力" + }, + { + "id": "video.node.connect", + "workspace": "video", + "title": "工作流连线", + "authorized": false, + "previouslyExposed": false, + "execution": "server", + "entry": "editVideoCanvas", + "note": "用户暂未授权视频画布能力" + }, + { + "id": "video.node.disconnect", + "workspace": "video", + "title": "移除连线", + "authorized": false, + "previouslyExposed": false, + "execution": "server", + "entry": "editVideoCanvas", + "note": "用户暂未授权视频画布能力" + }, + { + "id": "video.node.note", + "workspace": "video", + "title": "节点批注", + "authorized": false, + "previouslyExposed": false, + "execution": "server", + "entry": "editVideoCanvas", + "note": "用户暂未授权视频画布能力" + }, + { + "id": "video.node.text", + "workspace": "video", + "title": "编辑文本", + "authorized": false, + "previouslyExposed": false, + "execution": "server", + "entry": "editVideoCanvas", + "note": "用户暂未授权视频画布能力" + }, + { + "id": "video.node.create-text", + "workspace": "video", + "title": "添加文本节点", + "authorized": false, + "previouslyExposed": false, + "execution": "server", + "entry": "editVideoCanvas", + "note": "用户暂未授权视频画布能力" + }, + { + "id": "video.node.arrange", + "workspace": "video", + "title": "排列节点", + "authorized": false, + "previouslyExposed": false, + "execution": "server", + "entry": "editVideoCanvas", + "note": "用户暂未授权视频画布能力" + }, + { + "id": "video.node.viewport", + "workspace": "video", + "title": "画布缩放与定位", + "authorized": false, + "previouslyExposed": false, + "execution": "server", + "entry": "editVideoCanvas", + "note": "用户暂未授权视频画布能力" + }, + { + "id": "video.media.extract-frame", + "workspace": "video", + "title": "真实视频截帧", + "authorized": false, + "previouslyExposed": false, + "execution": "server", + "entry": "processVideoMedia", + "note": "用户暂未授权视频画布能力;使用真实媒体处理并上传现有存储,不复用页面的模拟产物;单次视频不超过120秒" + }, + { + "id": "video.media.trim", + "workspace": "video", + "title": "真实视频剪辑导出", + "authorized": false, + "previouslyExposed": false, + "execution": "server", + "entry": "processVideoMedia", + "note": "用户暂未授权视频画布能力;使用真实媒体处理并上传现有存储,不复用页面的模拟产物;单次视频不超过120秒" + }, + { + "id": "video.media.crop", + "workspace": "video", + "title": "真实视频裁剪", + "authorized": false, + "previouslyExposed": false, + "execution": "server", + "entry": "processVideoMedia", + "note": "用户暂未授权视频画布能力;使用真实媒体处理并上传现有存储,不复用页面的模拟产物;单次视频不超过120秒" + }, + { + "id": "video.media.extract-audio", + "workspace": "video", + "title": "提取完整音轨", + "authorized": false, + "previouslyExposed": false, + "execution": "server", + "entry": "processVideoMedia", + "note": "用户暂未授权视频画布能力;使用真实媒体处理并上传现有存储,不复用页面的模拟产物;单次视频不超过120秒" + }, + { + "id": "video.media.mute", + "workspace": "video", + "title": "生成无声视频", + "authorized": false, + "previouslyExposed": false, + "execution": "server", + "entry": "processVideoMedia", + "note": "用户暂未授权视频画布能力;使用真实媒体处理并上传现有存储,不复用页面的模拟产物;单次视频不超过120秒" + }, + { + "id": "video.ui.upload-image", + "workspace": "video", + "title": "上传图片", + "authorized": false, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openVideoCanvasFeature", + "note": "用户暂未授权视频画布能力" + }, + { + "id": "video.ui.upload-video", + "workspace": "video", + "title": "上传视频", + "authorized": false, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openVideoCanvasFeature", + "note": "用户暂未授权视频画布能力" + }, + { + "id": "video.ui.upload-audio", + "workspace": "video", + "title": "上传音频", + "authorized": false, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openVideoCanvasFeature", + "note": "用户暂未授权视频画布能力" + }, + { + "id": "video.ui.download", + "workspace": "video", + "title": "下载素材", + "authorized": false, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openVideoCanvasFeature", + "note": "用户暂未授权视频画布能力" + }, + { + "id": "video.ui.preview", + "workspace": "video", + "title": "预览素材", + "authorized": false, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openVideoCanvasFeature", + "note": "用户暂未授权视频画布能力" + }, + { + "id": "video.ui.local-edit", + "workspace": "video", + "title": "局部编辑", + "authorized": false, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openVideoCanvasFeature", + "note": "用户暂未授权视频画布能力" + }, + { + "id": "video.ui.annotate", + "workspace": "video", + "title": "标注", + "authorized": false, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openVideoCanvasFeature", + "note": "用户暂未授权视频画布能力" + }, + { + "id": "video.ui.video-hd", + "workspace": "video", + "title": "视频高清", + "authorized": false, + "previouslyExposed": false, + "execution": "backend_required", + "entry": "openVideoCanvasFeature", + "note": "用户暂未授权视频画布能力;页面当前为占位/模拟流程;只授权设置入口,不执行模拟产物或声称媒体已处理" + }, + { + "id": "video.ui.video-clip", + "workspace": "video", + "title": "选择视频剪辑范围", + "authorized": false, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openVideoCanvasFeature", + "note": "用户暂未授权视频画布能力" + }, + { + "id": "video.ui.video-crop", + "workspace": "video", + "title": "视频裁剪面板", + "authorized": false, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openVideoCanvasFeature", + "note": "用户暂未授权视频画布能力;页面当前为占位/模拟流程;只授权设置入口,不执行模拟产物或声称媒体已处理" + }, + { + "id": "video.ui.subtitle-erase", + "workspace": "video", + "title": "去字幕面板", + "authorized": false, + "previouslyExposed": false, + "execution": "backend_required", + "entry": "openVideoCanvasFeature", + "note": "用户暂未授权视频画布能力;页面当前为占位/模拟流程;只授权设置入口,不执行模拟产物或声称媒体已处理" + }, + { + "id": "video.ui.audio-split", + "workspace": "video", + "title": "音视频分离面板", + "authorized": false, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openVideoCanvasFeature", + "note": "用户暂未授权视频画布能力;页面当前为占位/模拟流程;只授权设置入口,不执行模拟产物或声称媒体已处理" + }, + { + "id": "video.ui.voice-split", + "workspace": "video", + "title": "人声分离面板", + "authorized": false, + "previouslyExposed": false, + "execution": "backend_required", + "entry": "openVideoCanvasFeature", + "note": "用户暂未授权视频画布能力;页面当前为占位/模拟流程;只授权设置入口,不执行模拟产物或声称媒体已处理" + }, + { + "id": "video.ui.background-split", + "workspace": "video", + "title": "背景音分离面板", + "authorized": false, + "previouslyExposed": false, + "execution": "backend_required", + "entry": "openVideoCanvasFeature", + "note": "用户暂未授权视频画布能力;页面当前为占位/模拟流程;只授权设置入口,不执行模拟产物或声称媒体已处理" + }, + { + "id": "video.ui.director", + "workspace": "video", + "title": "导演台", + "authorized": false, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openVideoCanvasFeature", + "note": "用户暂未授权视频画布能力" + }, + { + "id": "video.ui.storyboard", + "workspace": "video", + "title": "分镜工作台", + "authorized": false, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openVideoCanvasFeature", + "note": "用户暂未授权视频画布能力" + }, + { + "id": "video.ui.batch-storyboard", + "workspace": "video", + "title": "批量生成分镜", + "authorized": false, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openVideoCanvasFeature", + "note": "用户暂未授权视频画布能力" + }, + { + "id": "video.ui.batch-video", + "workspace": "video", + "title": "批量生成视频", + "authorized": false, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openVideoCanvasFeature", + "note": "用户暂未授权视频画布能力" + }, + { + "id": "video.ui.assets", + "workspace": "video", + "title": "素材库", + "authorized": false, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openVideoCanvasFeature", + "note": "用户暂未授权视频画布能力" + }, + { + "id": "video.ui.roles", + "workspace": "video", + "title": "角色库", + "authorized": false, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openVideoCanvasFeature", + "note": "用户暂未授权视频画布能力" + }, + { + "id": "video.ui.styles", + "workspace": "video", + "title": "风格库", + "authorized": false, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openVideoCanvasFeature", + "note": "用户暂未授权视频画布能力" + }, + { + "id": "video.ui.effects", + "workspace": "video", + "title": "特效库", + "authorized": false, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openVideoCanvasFeature", + "note": "用户暂未授权视频画布能力" + }, + { + "id": "video.ui.history", + "workspace": "video", + "title": "生成历史", + "authorized": false, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openVideoCanvasFeature", + "note": "用户暂未授权视频画布能力" + }, + { + "id": "video.ui.workflows", + "workspace": "video", + "title": "工作流模板", + "authorized": false, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openVideoCanvasFeature", + "note": "用户暂未授权视频画布能力" + }, + { + "id": "video.ui.save", + "workspace": "video", + "title": "保存画布", + "authorized": false, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openVideoCanvasFeature", + "note": "用户暂未授权视频画布能力" + }, + { + "id": "video.ui.export", + "workspace": "video", + "title": "导出画布", + "authorized": false, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openVideoCanvasFeature", + "note": "用户暂未授权视频画布能力" + }, + { + "id": "video.ui.import", + "workspace": "video", + "title": "导入画布", + "authorized": false, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openVideoCanvasFeature", + "note": "用户暂未授权视频画布能力" + }, + { + "id": "video.ui.share", + "workspace": "video", + "title": "分享设置", + "authorized": false, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openVideoCanvasFeature", + "note": "用户暂未授权视频画布能力" + }, + { + "id": "video.ui.publish", + "workspace": "video", + "title": "发布设置", + "authorized": false, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openVideoCanvasFeature", + "note": "用户暂未授权视频画布能力" + }, + { + "id": "video.ui.skills", + "workspace": "video", + "title": "视频技能", + "authorized": false, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openVideoCanvasFeature", + "note": "用户暂未授权视频画布能力" + }, + { + "id": "video.ui.help", + "workspace": "video", + "title": "帮助与快捷键", + "authorized": false, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openVideoCanvasFeature", + "note": "用户暂未授权视频画布能力" + }, + { + "id": "video.ui.frame-first", + "workspace": "video", + "title": "提取首帧", + "authorized": false, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openVideoCanvasFeature", + "note": "用户暂未授权视频画布能力;页面当前为占位/模拟流程;只授权设置入口,不执行模拟产物或声称媒体已处理" + }, + { + "id": "video.ui.frame-last", + "workspace": "video", + "title": "提取尾帧", + "authorized": false, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openVideoCanvasFeature", + "note": "用户暂未授权视频画布能力;页面当前为占位/模拟流程;只授权设置入口,不执行模拟产物或声称媒体已处理" + }, + { + "id": "video.ui.frame-current", + "workspace": "video", + "title": "提取指定时间帧", + "authorized": false, + "previouslyExposed": false, + "execution": "interactive", + "entry": "openVideoCanvasFeature", + "note": "用户暂未授权视频画布能力;页面当前为占位/模拟流程;只授权设置入口,不执行模拟产物或声称媒体已处理" + }, + { + "id": "skills.get", + "title": "可访问技能列表", + "group": "技能", + "path": "/api/agents", + "method": "GET", + "hint": "query: categoryId、search(可选)。执行技能前用 loadProjectSkill 读取真实提示词和参数,再由当前原生核心编排已有工具。", + "readOnly": true, + "result": "json", + "authorized": true, + "previouslyExposed": false, + "execution": "server" + }, + { + "id": "skill-categories.get", + "title": "技能分类", + "group": "技能", + "path": "/api/agent-categories", + "method": "GET", + "hint": "无需参数", + "readOnly": true, + "result": "json", + "authorized": true, + "previouslyExposed": false, + "execution": "server" + }, + { + "id": "materials.get", + "title": "商品 SKU/SPU 素材检索", + "group": "素材", + "path": "/api/agent-workflow/material-search", + "method": "GET", + "hint": "query: keyword必填,source=primary/secondary、queryType=sku/spu、requiredCount可选", + "readOnly": true, + "result": "json", + "authorized": true, + "previouslyExposed": false, + "execution": "server" + }, + { + "id": "references.get", + "title": "参考图检索", + "group": "素材", + "path": "/api/agent-workflow/reference-search", + "method": "GET", + "hint": "query: keyword、source、queryType;以接口返回的实际素材为准", + "readOnly": true, + "result": "json", + "authorized": true, + "previouslyExposed": false, + "execution": "server" + }, + { + "id": "appearance.post", + "title": "素材外观识别", + "group": "素材", + "path": "/api/agent-workflow/material-appearance", + "method": "POST", + "hint": "body: imageUrls等图片参数,接口验证服务配置与格式", + "readOnly": false, + "result": "json", + "authorized": true, + "previouslyExposed": false, + "execution": "server" + }, + { + "id": "third-party-materials.get", + "title": "第三方图片素材检索", + "group": "素材", + "path": "/api/third-party-image-materials/search", + "method": "GET", + "hint": "query: keyword、page、pageSize;沿用站点数据权限", + "readOnly": true, + "result": "json", + "authorized": true, + "previouslyExposed": false, + "execution": "server" + }, + { + "id": "gallery.get", + "title": "图库素材", + "group": "素材", + "path": "/api/gallery", + "method": "GET", + "hint": "query: page、pageSize、category、keyword可选", + "readOnly": true, + "result": "json", + "authorized": true, + "previouslyExposed": false, + "execution": "server" + }, + { + "id": "featured.get", + "title": "精选素材", + "group": "素材", + "path": "/api/featured", + "method": "GET", + "hint": "query: category、page可选", + "readOnly": true, + "result": "json", + "authorized": true, + "previouslyExposed": false, + "execution": "server" + }, + { + "id": "ranking.get", + "title": "素材排行榜", + "group": "素材", + "path": "/api/featured/ranking", + "method": "GET", + "hint": "query: type、limit可选", + "readOnly": true, + "result": "json", + "authorized": true, + "previouslyExposed": false, + "execution": "server" + }, + { + "id": "psd-templates.get", + "title": "PSD 模板列表", + "group": "PSD", + "path": "/api/psd-templates", + "method": "GET", + "hint": "query: category、keyword可选", + "readOnly": true, + "result": "json", + "authorized": true, + "previouslyExposed": false, + "execution": "server" + }, + { + "id": "psd-template.get", + "title": "PSD 模板图层信息", + "group": "PSD", + "path": "/api/psd-templates/[id]", + "method": "GET", + "hint": "pathParams: id=模板编号", + "readOnly": true, + "result": "json", + "authorized": true, + "previouslyExposed": false, + "execution": "server" + }, + { + "id": "psd-render.get", + "title": "PSD 真正渲染与任务状态", + "group": "PSD", + "path": "/api/psd-templates/render", + "method": "GET", + "hint": "POST body: templateId必填,imageAssignments/textAssignments/hiddenLayerIds/layerOrderIds/imagePlacements等;GET query: taskId。pending/running只代表已受理,必须轮询到succeeded且有result.url才可交付。", + "readOnly": true, + "result": "json", + "authorized": true, + "previouslyExposed": false, + "execution": "server" + }, + { + "id": "psd-render.post", + "title": "PSD 真正渲染与任务状态", + "group": "PSD", + "path": "/api/psd-templates/render", + "method": "POST", + "hint": "POST body: templateId必填,imageAssignments/textAssignments/hiddenLayerIds/layerOrderIds/imagePlacements等;GET query: taskId。pending/running只代表已受理,必须轮询到succeeded且有result.url才可交付。", + "readOnly": false, + "result": "json", + "authorized": true, + "previouslyExposed": false, + "execution": "server" + }, + { + "id": "detail-plan.post", + "title": "详情页与 UI 设计规划", + "group": "详情与设计", + "path": "/api/canvas/detail-plan", + "method": "POST", + "hint": "body: prompt、图片和设计上下文;遵循接口校验", + "readOnly": false, + "result": "json", + "authorized": true, + "previouslyExposed": false, + "execution": "server" + }, + { + "id": "detail-review.post", + "title": "详情结果验收", + "group": "详情与设计", + "path": "/api/canvas/detail-review", + "method": "POST", + "hint": "body: prompt、imageUrls等真实设计图信息", + "readOnly": false, + "result": "json", + "authorized": true, + "previouslyExposed": false, + "execution": "server" + }, + { + "id": "detail-subject.post", + "title": "详情主体分析", + "group": "详情与设计", + "path": "/api/canvas/detail-subject-analyze", + "method": "POST", + "hint": "body: 图片与产品信息", + "readOnly": false, + "result": "json", + "authorized": true, + "previouslyExposed": false, + "execution": "server" + }, + { + "id": "ui-review.post", + "title": "UI 页面验收", + "group": "详情与设计", + "path": "/api/canvas/ui-screen/review", + "method": "POST", + "hint": "body: 真实页面设计文档与审核要求", + "readOnly": false, + "result": "json", + "authorized": true, + "previouslyExposed": false, + "execution": "server" + }, + { + "id": "text-copy.post", + "title": "图片文案建议", + "group": "详情与设计", + "path": "/api/canvas/text-copy-suggestions", + "method": "POST", + "hint": "body: imageUrl、prompt等文案上下文", + "readOnly": false, + "result": "json", + "authorized": true, + "previouslyExposed": false, + "execution": "server" + }, + { + "id": "detail-stitch.post", + "title": "详情图片拼接", + "group": "详情与设计", + "path": "/api/agent-workflow/detail-stitch", + "method": "POST", + "hint": "body: images或imageUrls等拼接参数", + "readOnly": false, + "result": "json", + "authorized": true, + "previouslyExposed": false, + "execution": "server" + }, + { + "id": "detail-normalize.post", + "title": "详情图片归一化", + "group": "详情与设计", + "path": "/api/agent-workflow/detail-image-normalize", + "method": "POST", + "hint": "body: 图片链接与尺寸参数", + "readOnly": false, + "result": "json", + "authorized": true, + "previouslyExposed": false, + "execution": "server" + }, + { + "id": "style-models.get", + "title": "风格化可用模型", + "group": "详情与设计", + "path": "/api/style-pro/model-options", + "method": "GET", + "hint": "无需参数,不返回密钥", + "readOnly": true, + "result": "json", + "authorized": true, + "previouslyExposed": false, + "execution": "server" + }, + { + "id": "style-generate.post", + "title": "风格化 PRO 生成", + "group": "详情与设计", + "path": "/api/style-pro/generate", + "method": "POST", + "hint": "body: 模型、提示词与参考图,遵守用户指定模型;不改站点配置", + "readOnly": false, + "result": "json", + "authorized": true, + "previouslyExposed": false, + "execution": "server" + }, + { + "id": "wash-models.get", + "title": "AI 图像处理可用模型", + "group": "详情与设计", + "path": "/api/ai-wash/model-options", + "method": "GET", + "hint": "无需参数", + "readOnly": true, + "result": "json", + "authorized": true, + "previouslyExposed": false, + "execution": "server" + }, + { + "id": "wash-generate.post", + "title": "AI 图像处理", + "group": "详情与设计", + "path": "/api/ai-wash/generate", + "method": "POST", + "hint": "body: 用户图像与参数;结果未确认不能重提收费任务", + "readOnly": false, + "result": "json", + "authorized": true, + "previouslyExposed": false, + "execution": "server" + }, + { + "id": "planning-image.post", + "title": "商品图片分析", + "group": "商品策划", + "path": "/api/product-planning/analyze-image", + "method": "POST", + "hint": "body: imageUrl与产品上下文;底层功能开关仍生效", + "readOnly": false, + "result": "json", + "authorized": true, + "previouslyExposed": false, + "execution": "server" + }, + { + "id": "planning-sku.post", + "title": "商品 SKU 分析", + "group": "商品策划", + "path": "/api/product-planning/analyze-sku", + "method": "POST", + "hint": "body: sku与用户商品信息", + "readOnly": false, + "result": "json", + "authorized": true, + "previouslyExposed": false, + "execution": "server" + }, + { + "id": "planning-analysis.post", + "title": "评价与问大家分析", + "group": "商品策划", + "path": "/api/product-planning/analyze", + "method": "POST", + "hint": "body: kind=review/qa,rows为真实评价或问答数组", + "readOnly": false, + "result": "json", + "authorized": true, + "previouslyExposed": false, + "execution": "server" + }, + { + "id": "planning-keywords.get", + "title": "关键词洞察", + "group": "商品策划", + "path": "/api/product-planning/keyword-insight", + "method": "GET", + "hint": "query: keyword等检索参数", + "readOnly": true, + "result": "json", + "authorized": true, + "previouslyExposed": false, + "execution": "server" + }, + { + "id": "planning-taobao-item.get", + "title": "taobao 商品详情", + "group": "商品策划", + "path": "/api/product-planning/taobao/item", + "method": "GET", + "hint": "query: itemId等商品编号", + "readOnly": true, + "result": "json", + "authorized": true, + "previouslyExposed": false, + "execution": "server" + }, + { + "id": "planning-jd-item.get", + "title": "jd 商品详情", + "group": "商品策划", + "path": "/api/product-planning/jd/item", + "method": "GET", + "hint": "query: itemId等商品编号", + "readOnly": true, + "result": "json", + "authorized": true, + "previouslyExposed": false, + "execution": "server" + }, + { + "id": "planning-reviews.get", + "title": "淘宝真实评价", + "group": "商品策划", + "path": "/api/product-planning/taobao/reviews", + "method": "GET", + "hint": "query: itemId、page等", + "readOnly": true, + "result": "json", + "authorized": true, + "previouslyExposed": false, + "execution": "server" + }, + { + "id": "planning-sales.get", + "title": "淘宝月销量", + "group": "商品策划", + "path": "/api/product-planning/taobao/month-sale", + "method": "GET", + "hint": "query: itemId", + "readOnly": true, + "result": "json", + "authorized": true, + "previouslyExposed": false, + "execution": "server" + }, + { + "id": "planning-qa.post", + "title": "淘宝问大家", + "group": "商品策划", + "path": "/api/product-planning/taobao/qa", + "method": "POST", + "hint": "body: itemId等商品编号", + "readOnly": false, + "result": "json", + "authorized": true, + "previouslyExposed": false, + "execution": "server" + }, + { + "id": "planning-market-items.post", + "title": "平台商品检索", + "group": "商品策划", + "path": "/api/product-planning/marketplace/items", + "method": "POST", + "hint": "body: platform、keyword等检索参数", + "readOnly": false, + "result": "json", + "authorized": true, + "previouslyExposed": false, + "execution": "server" + }, + { + "id": "planning-templates.get", + "title": "策划模板列表与保存", + "group": "商品策划", + "path": "/api/product-planning/templates", + "method": "GET", + "hint": "POST body: title与策划内容;只保存当前用户自己的模板", + "readOnly": true, + "result": "json", + "authorized": true, + "previouslyExposed": false, + "execution": "server" + }, + { + "id": "planning-templates.post", + "title": "策划模板列表与保存", + "group": "商品策划", + "path": "/api/product-planning/templates", + "method": "POST", + "hint": "POST body: title与策划内容;只保存当前用户自己的模板", + "readOnly": false, + "result": "json", + "authorized": true, + "previouslyExposed": false, + "execution": "server" + }, + { + "id": "planning-template.get", + "title": "策划模板读取与删除", + "group": "商品策划", + "path": "/api/product-planning/templates/[id]", + "method": "GET", + "hint": "pathParams: id;删除需要用户明确指定此编号", + "readOnly": true, + "result": "json", + "authorized": true, + "previouslyExposed": false, + "execution": "server" + }, + { + "id": "planning-template.delete", + "title": "策划模板读取与删除", + "group": "商品策划", + "path": "/api/product-planning/templates/[id]", + "method": "DELETE", + "hint": "pathParams: id;删除需要用户明确指定此编号", + "readOnly": false, + "result": "json", + "authorized": true, + "previouslyExposed": false, + "execution": "server" + }, + { + "id": "flow-files.get", + "title": "白板文件列表与创建", + "group": "流程白板", + "path": "/api/flow-board/files", + "method": "GET", + "hint": "POST body: title、snapshot;snapshot必须为真实白板快照", + "readOnly": true, + "result": "json", + "authorized": true, + "previouslyExposed": false, + "execution": "server" + }, + { + "id": "flow-files.post", + "title": "白板文件列表与创建", + "group": "流程白板", + "path": "/api/flow-board/files", + "method": "POST", + "hint": "POST body: title、snapshot;snapshot必须为真实白板快照", + "readOnly": false, + "result": "json", + "authorized": true, + "previouslyExposed": false, + "execution": "server" + }, + { + "id": "flow-file.get", + "title": "白板文件读取、修改、删除", + "group": "流程白板", + "path": "/api/flow-board/files/[id]", + "method": "GET", + "hint": "pathParams: id;PUT body: title、snapshot;先读取原文件,保留无关节点和工作表;删除需明确指定编号", + "readOnly": true, + "result": "json", + "authorized": true, + "previouslyExposed": false, + "execution": "server" + }, + { + "id": "flow-file.put", + "title": "白板文件读取、修改、删除", + "group": "流程白板", + "path": "/api/flow-board/files/[id]", + "method": "PUT", + "hint": "pathParams: id;PUT body: title、snapshot;先读取原文件,保留无关节点和工作表;删除需明确指定编号", + "readOnly": false, + "result": "json", + "authorized": true, + "previouslyExposed": false, + "execution": "server" + }, + { + "id": "flow-file.delete", + "title": "白板文件读取、修改、删除", + "group": "流程白板", + "path": "/api/flow-board/files/[id]", + "method": "DELETE", + "hint": "pathParams: id;PUT body: title、snapshot;先读取原文件,保留无关节点和工作表;删除需明确指定编号", + "readOnly": false, + "result": "json", + "authorized": true, + "previouslyExposed": false, + "execution": "server" + }, + { + "id": "flow-draft.get", + "title": "白板草稿读取与保存", + "group": "流程白板", + "path": "/api/flow-board/draft", + "method": "GET", + "hint": "PUT body: title、snapshot;只操作当前用户草稿", + "readOnly": true, + "result": "json", + "authorized": true, + "previouslyExposed": false, + "execution": "server" + }, + { + "id": "flow-draft.put", + "title": "白板草稿读取与保存", + "group": "流程白板", + "path": "/api/flow-board/draft", + "method": "PUT", + "hint": "PUT body: title、snapshot;只操作当前用户草稿", + "readOnly": false, + "result": "json", + "authorized": true, + "previouslyExposed": false, + "execution": "server" + }, + { + "id": "video-capabilities.get", + "title": "视频模型能力与参数", + "group": "分镜任务", + "path": "/api/video-model-capabilities", + "method": "GET", + "hint": "query: modelId等;沿用用户模型", + "readOnly": true, + "result": "json", + "authorized": false, + "previouslyExposed": false, + "execution": "server" + }, + { + "id": "video-tasks.get", + "title": "用户视频任务列表", + "group": "分镜任务", + "path": "/api/video-tasks", + "method": "GET", + "hint": "query: page、limit等;仅当前用户任务", + "readOnly": true, + "result": "json", + "authorized": false, + "previouslyExposed": false, + "execution": "server" + }, + { + "id": "storyboard-task.get", + "title": "分镜任务与阶段推进", + "group": "分镜任务", + "path": "/api/video/storyboard/tasks/[taskId]", + "method": "GET", + "hint": "pathParams: taskId;读取实际状态后再按接口动作推进,不重启已有收费任务", + "readOnly": true, + "result": "json", + "authorized": false, + "previouslyExposed": false, + "execution": "server" + }, + { + "id": "storyboard-confirm.post", + "title": "确认用户分镜参数", + "group": "分镜任务", + "path": "/api/video/storyboard/tasks/[taskId]/confirm", + "method": "POST", + "hint": "pathParams: taskId;body: 用户实际确认的镜头与参数,不虚构用户确认", + "readOnly": false, + "result": "json", + "authorized": false, + "previouslyExposed": false, + "execution": "server" + }, + { + "id": "storyboard-cancel.post", + "title": "停止指定分镜任务", + "group": "分镜任务", + "path": "/api/video/storyboard/tasks/[taskId]/cancel", + "method": "POST", + "hint": "pathParams: taskId;需用户明确要求停止此编号", + "readOnly": false, + "result": "json", + "authorized": false, + "previouslyExposed": false, + "execution": "server" + }, + { + "id": "storyboard-shot.patch", + "title": "分镜镜头修订", + "group": "分镜任务", + "path": "/api/video/storyboard/tasks/[taskId]/shots/[shotIndex]", + "method": "PATCH", + "hint": "pathParams: taskId、shotIndex;body: 用户要求的镜头修改", + "readOnly": false, + "result": "json", + "authorized": false, + "previouslyExposed": false, + "execution": "server" + }, + { + "id": "storyboard-hd.post", + "title": "指定镜头高清处理", + "group": "分镜任务", + "path": "/api/video/storyboard/tasks/[taskId]/shots/[shotIndex]/regenerate-hd", + "method": "POST", + "hint": "pathParams: taskId、shotIndex;会产生费用,只有用户要求高清才执行", + "readOnly": false, + "result": "json", + "authorized": false, + "previouslyExposed": false, + "execution": "server" + }, + { + "id": "agent-projects.get", + "title": "Agent 创作项目列表与创建", + "group": "项目", + "path": "/api/agent-projects", + "method": "GET", + "hint": "POST body: title等项目数据;不写入其他用户项目", + "readOnly": true, + "result": "json", + "authorized": true, + "previouslyExposed": false, + "execution": "server" + }, + { + "id": "agent-projects.post", + "title": "Agent 创作项目列表与创建", + "group": "项目", + "path": "/api/agent-projects", + "method": "POST", + "hint": "POST body: title等项目数据;不写入其他用户项目", + "readOnly": false, + "result": "json", + "authorized": true, + "previouslyExposed": false, + "execution": "server" + }, + { + "id": "agent-project.get", + "title": "Agent 创作项目读写", + "group": "项目", + "path": "/api/agent-projects/[id]", + "method": "GET", + "hint": "pathParams: id;修改先读当前内容,删除需用户明确指定编号", + "readOnly": true, + "result": "json", + "authorized": true, + "previouslyExposed": false, + "execution": "server" + }, + { + "id": "agent-project.put", + "title": "Agent 创作项目读写", + "group": "项目", + "path": "/api/agent-projects/[id]", + "method": "PUT", + "hint": "pathParams: id;修改先读当前内容,删除需用户明确指定编号", + "readOnly": false, + "result": "json", + "authorized": true, + "previouslyExposed": false, + "execution": "server" + }, + { + "id": "agent-project.delete", + "title": "Agent 创作项目读写", + "group": "项目", + "path": "/api/agent-projects/[id]", + "method": "DELETE", + "hint": "pathParams: id;修改先读当前内容,删除需用户明确指定编号", + "readOnly": false, + "result": "json", + "authorized": true, + "previouslyExposed": false, + "execution": "server" + }, + { + "id": "canvas-list.get", + "title": "用户画布列表与创建", + "group": "项目", + "path": "/api/canvas", + "method": "GET", + "hint": "POST body: title、workspaceType=canvas/video等", + "readOnly": true, + "result": "json", + "authorized": true, + "previouslyExposed": false, + "execution": "server" + }, + { + "id": "canvas-list.post", + "title": "用户画布列表与创建", + "group": "项目", + "path": "/api/canvas", + "method": "POST", + "hint": "POST body: title、workspaceType=canvas/video等", + "readOnly": false, + "result": "json", + "authorized": true, + "previouslyExposed": false, + "execution": "server" + }, + { + "id": "canvas-read.get", + "title": "读取用户画布", + "group": "项目", + "path": "/api/canvas/[id]", + "method": "GET", + "hint": "pathParams: id;只读取当前用户有权限的画布,节点写入使用专用画布工具", + "readOnly": true, + "result": "json", + "authorized": true, + "previouslyExposed": false, + "execution": "server" + }, + { + "id": "detail-archives.get", + "title": "画布详情归档", + "group": "项目", + "path": "/api/canvas/[id]/detail-archives", + "method": "GET", + "hint": "pathParams: id=当前画布编号;body/query按详情归档接口,删除需明确授权", + "readOnly": true, + "result": "json", + "authorized": true, + "previouslyExposed": false, + "execution": "server" + }, + { + "id": "detail-archives.post", + "title": "画布详情归档", + "group": "项目", + "path": "/api/canvas/[id]/detail-archives", + "method": "POST", + "hint": "pathParams: id=当前画布编号;body/query按详情归档接口,删除需明确授权", + "readOnly": false, + "result": "json", + "authorized": true, + "previouslyExposed": false, + "execution": "server" + }, + { + "id": "detail-archives.patch", + "title": "画布详情归档", + "group": "项目", + "path": "/api/canvas/[id]/detail-archives", + "method": "PATCH", + "hint": "pathParams: id=当前画布编号;body/query按详情归档接口,删除需明确授权", + "readOnly": false, + "result": "json", + "authorized": true, + "previouslyExposed": false, + "execution": "server" + }, + { + "id": "detail-archives.delete", + "title": "画布详情归档", + "group": "项目", + "path": "/api/canvas/[id]/detail-archives", + "method": "DELETE", + "hint": "pathParams: id=当前画布编号;body/query按详情归档接口,删除需明确授权", + "readOnly": false, + "result": "json", + "authorized": true, + "previouslyExposed": false, + "execution": "server" + }, + { + "id": "model-assets.get", + "title": "3D 资产归档", + "group": "项目", + "path": "/api/canvas/[id]/model3d-assets", + "method": "GET", + "hint": "pathParams: id=当前画布编号;只处理拥有权限的资产", + "readOnly": true, + "result": "json", + "authorized": true, + "previouslyExposed": false, + "execution": "server" + }, + { + "id": "model-assets.post", + "title": "3D 资产归档", + "group": "项目", + "path": "/api/canvas/[id]/model3d-assets", + "method": "POST", + "hint": "pathParams: id=当前画布编号;只处理拥有权限的资产", + "readOnly": false, + "result": "json", + "authorized": true, + "previouslyExposed": false, + "execution": "server" + }, + { + "id": "model-assets.patch", + "title": "3D 资产归档", + "group": "项目", + "path": "/api/canvas/[id]/model3d-assets", + "method": "PATCH", + "hint": "pathParams: id=当前画布编号;只处理拥有权限的资产", + "readOnly": false, + "result": "json", + "authorized": true, + "previouslyExposed": false, + "execution": "server" + }, + { + "id": "model-assets.delete", + "title": "3D 资产归档", + "group": "项目", + "path": "/api/canvas/[id]/model3d-assets", + "method": "DELETE", + "hint": "pathParams: id=当前画布编号;只处理拥有权限的资产", + "readOnly": false, + "result": "json", + "authorized": true, + "previouslyExposed": false, + "execution": "server" + }, + { + "id": "3d-task.get", + "title": "3D 生成任务状态", + "group": "3D", + "path": "/api/canvas/3d/tasks/[taskId]", + "method": "GET", + "hint": "pathParams: taskId;生成用已有3D专用能力,不重复提交", + "readOnly": true, + "result": "json", + "authorized": true, + "previouslyExposed": false, + "execution": "server" + }, + { + "id": "world-task.get", + "title": "场景生成任务状态", + "group": "3D", + "path": "/api/canvas/world/tasks/[taskId]", + "method": "GET", + "hint": "pathParams: taskId;生成用已有场景专用能力", + "readOnly": true, + "result": "json", + "authorized": true, + "previouslyExposed": false, + "execution": "server" + }, + { + "id": "smart-edit.get", + "title": "智能图层编辑能力", + "group": "智能编辑", + "path": "/api/canvas/smart-edit/capabilities", + "method": "GET", + "hint": "无需参数;仅当该部署版本已有此功能时可用", + "readOnly": true, + "result": "json", + "authorized": true, + "previouslyExposed": false, + "execution": "server" + }, + { + "id": "documents.get", + "title": "读取与保存用户文档", + "group": "文档", + "path": "/api/document", + "method": "GET", + "hint": "query: id=文档UUID;POST body: title、kind=text/code/sheet/image、content。更新前先读取原文档,不操作其他用户文档。", + "readOnly": true, + "result": "json", + "authorized": true, + "previouslyExposed": false, + "execution": "server" + }, + { + "id": "documents.post", + "title": "读取与保存用户文档", + "group": "文档", + "path": "/api/document", + "method": "POST", + "hint": "query: id=文档UUID;POST body: title、kind=text/code/sheet/image、content。更新前先读取原文档,不操作其他用户文档。", + "readOnly": false, + "result": "json", + "authorized": true, + "previouslyExposed": false, + "execution": "server" + }, + { + "id": "enhance-pro.get", + "title": "专业高清处理任务与查询", + "group": "图像处理", + "path": "/api/enhance/pro", + "method": "GET", + "hint": "POST body按接口实际模型与尺寸要求,GET query: taskId。仅任务成功后才能交付,不能重复付费提交。", + "readOnly": true, + "result": "json", + "authorized": true, + "previouslyExposed": false, + "execution": "server" + }, + { + "id": "enhance-pro.post", + "title": "专业高清处理任务与查询", + "group": "图像处理", + "path": "/api/enhance/pro", + "method": "POST", + "hint": "POST body按接口实际模型与尺寸要求,GET query: taskId。仅任务成功后才能交付,不能重复付费提交。", + "readOnly": false, + "result": "json", + "authorized": true, + "previouslyExposed": false, + "execution": "server" + }, + { + "id": "getWeather", + "title": "getWeather", + "group": "文档、天气与技能", + "authorized": true, + "previouslyExposed": false, + "entry": "getWeather", + "execution": "server" + }, + { + "id": "createDocument", + "title": "createDocument", + "group": "文档、天气与技能", + "authorized": true, + "previouslyExposed": false, + "entry": "createDocument", + "execution": "server" + }, + { + "id": "updateDocument", + "title": "updateDocument", + "group": "文档、天气与技能", + "authorized": true, + "previouslyExposed": false, + "entry": "updateDocument", + "execution": "server" + }, + { + "id": "requestSuggestions", + "title": "requestSuggestions", + "group": "文档、天气与技能", + "authorized": true, + "previouslyExposed": false, + "entry": "requestSuggestions", + "execution": "server" + }, + { + "id": "loadProjectSkill", + "title": "loadProjectSkill", + "group": "文档、天气与技能", + "authorized": true, + "previouslyExposed": false, + "entry": "loadProjectSkill", + "execution": "server" + } + ], + "verifiedRoutes": 74, + "deploymentOnly": [ + "smart-edit.get" + ] +} diff --git a/lib/ai/canvas-agent-runtime/authorization.ts b/lib/ai/canvas-agent-runtime/authorization.ts new file mode 100644 index 000000000..8717111af --- /dev/null +++ b/lib/ai/canvas-agent-runtime/authorization.ts @@ -0,0 +1,5 @@ +/** User decision: video canvas authorization is paused; manual video features are unchanged. */ +export const ZCODE_VIDEO_CANVAS_AUTHORIZED = false; +export function isZcodeWorkspaceAuthorized(workspace: string) { + return workspace !== "video" || ZCODE_VIDEO_CANVAS_AUTHORIZED; +} diff --git a/lib/ai/canvas-agent-runtime/capability-access.ts b/lib/ai/canvas-agent-runtime/capability-access.ts index a92ce7c72..03f467e79 100644 --- a/lib/ai/canvas-agent-runtime/capability-access.ts +++ b/lib/ai/canvas-agent-runtime/capability-access.ts @@ -1,3 +1,4 @@ +import { isZcodeWorkspaceAuthorized } from "./authorization"; import { CANVAS_CAPABILITY_REGISTRY } from "@/lib/canvas/capabilities/registry"; import { DEFAULT_CANVAS_TOOLBAR_ITEMS } from "@/lib/canvas-toolbar-config"; import { @@ -9,7 +10,7 @@ export type AgentCapabilityAccess = { id: string; workspace: "canvas" | "video"; title: string; - authorized: true; + authorized: boolean; previouslyExposed: boolean; execution: "server" | "interactive" | "backend_required"; entry: string; @@ -19,12 +20,13 @@ export type AgentCapabilityAccess = { // The full audit manifest is for the report/API. Repeating audit metadata and UI // descriptions in model history can exhaust context before the first edit. export function summarizeAgentCapabilities(items: AgentCapabilityAccess[]) { - return items.map(({ id, title, execution, entry, note }) => ({ + return items.map(({ id, title, execution, entry, note, authorized }) => ({ id, title, + authorized, execution, - ...(execution === "server" ? { entry } : {}), - ...(execution === "backend_required" ? { note } : {}), + ...(authorized && execution === "server" ? { entry } : {}), + ...(execution === "backend_required" || !authorized ? { note } : {}), })); } export const VIDEO_CANVAS_EXTRA_ACTIONS = [ @@ -260,5 +262,6 @@ export function getCanvasAgentAccessManifest( : undefined, }), ), - ]; + ].map(item => ({ ...item, authorized: isZcodeWorkspaceAuthorized(item.workspace), + ...(!isZcodeWorkspaceAuthorized(item.workspace) ? { note: ["用户暂未授权视频画布能力", item.note].filter(Boolean).join(";") } : {}) })); } diff --git a/lib/ai/canvas-agent-runtime/project-operation-catalog.ts b/lib/ai/canvas-agent-runtime/project-operation-catalog.ts new file mode 100644 index 000000000..79704918f --- /dev/null +++ b/lib/ai/canvas-agent-runtime/project-operation-catalog.ts @@ -0,0 +1,89 @@ +/** Fixed business operations, never an arbitrary URL or administrator API proxy. */ +export type ProjectAgentOperation = { + id: string; title: string; group: string; path: string; method: "GET" | "POST" | "PUT" | "PATCH" | "DELETE"; + hint: string; readOnly: boolean; result: "json"; authorized: true; +}; +export const PROJECT_AGENT_OPERATIONS: ProjectAgentOperation[] = []; +function add(group: string, id: string, title: string, path: string, methods: string, hint: string) { + for (const method of methods.split(",") as ProjectAgentOperation["method"][]) PROJECT_AGENT_OPERATIONS.push({ + id: `${id}.${method.toLowerCase()}`, title, group, path, method, hint, readOnly: method === "GET", result: "json", authorized: true, + }); +} +add("技能", "skills", "可访问技能列表", "/api/agents", "GET", "query: categoryId、search(可选)。执行技能前用 loadProjectSkill 读取真实提示词和参数,再由当前原生核心编排已有工具。"); +add("技能", "skill-categories", "技能分类", "/api/agent-categories", "GET", "无需参数"); +add("素材", "materials", "商品 SKU/SPU 素材检索", "/api/agent-workflow/material-search", "GET", "query: keyword必填,source=primary/secondary、queryType=sku/spu、requiredCount可选"); +add("素材", "references", "参考图检索", "/api/agent-workflow/reference-search", "GET", "query: keyword、source、queryType;以接口返回的实际素材为准"); +add("素材", "appearance", "素材外观识别", "/api/agent-workflow/material-appearance", "POST", "body: imageUrls等图片参数,接口验证服务配置与格式"); +add("素材", "third-party-materials", "第三方图片素材检索", "/api/third-party-image-materials/search", "GET", "query: keyword、page、pageSize;沿用站点数据权限"); +add("素材", "gallery", "图库素材", "/api/gallery", "GET", "query: page、pageSize、category、keyword可选"); +add("素材", "featured", "精选素材", "/api/featured", "GET", "query: category、page可选"); +add("素材", "ranking", "素材排行榜", "/api/featured/ranking", "GET", "query: type、limit可选"); +add("PSD", "psd-templates", "PSD 模板列表", "/api/psd-templates", "GET", "query: category、keyword可选"); +add("PSD", "psd-template", "PSD 模板图层信息", "/api/psd-templates/[id]", "GET", "pathParams: id=模板编号"); +add("PSD", "psd-render", "PSD 真正渲染与任务状态", "/api/psd-templates/render", "GET,POST", "POST body: templateId必填,imageAssignments/textAssignments/hiddenLayerIds/layerOrderIds/imagePlacements等;GET query: taskId。pending/running只代表已受理,必须轮询到succeeded且有result.url才可交付。"); +add("详情与设计", "detail-plan", "详情页与 UI 设计规划", "/api/canvas/detail-plan", "POST", "body: prompt、图片和设计上下文;遵循接口校验"); +add("详情与设计", "detail-review", "详情结果验收", "/api/canvas/detail-review", "POST", "body: prompt、imageUrls等真实设计图信息"); +add("详情与设计", "detail-subject", "详情主体分析", "/api/canvas/detail-subject-analyze", "POST", "body: 图片与产品信息"); +add("详情与设计", "ui-review", "UI 页面验收", "/api/canvas/ui-screen/review", "POST", "body: 真实页面设计文档与审核要求"); +add("详情与设计", "text-copy", "图片文案建议", "/api/canvas/text-copy-suggestions", "POST", "body: imageUrl、prompt等文案上下文"); +add("详情与设计", "detail-stitch", "详情图片拼接", "/api/agent-workflow/detail-stitch", "POST", "body: images或imageUrls等拼接参数"); +add("详情与设计", "detail-normalize", "详情图片归一化", "/api/agent-workflow/detail-image-normalize", "POST", "body: 图片链接与尺寸参数"); +add("详情与设计", "style-models", "风格化可用模型", "/api/style-pro/model-options", "GET", "无需参数,不返回密钥"); +add("详情与设计", "style-generate", "风格化 PRO 生成", "/api/style-pro/generate", "POST", "body: 模型、提示词与参考图,遵守用户指定模型;不改站点配置"); +add("详情与设计", "wash-models", "AI 图像处理可用模型", "/api/ai-wash/model-options", "GET", "无需参数"); +add("详情与设计", "wash-generate", "AI 图像处理", "/api/ai-wash/generate", "POST", "body: 用户图像与参数;结果未确认不能重提收费任务"); +add("商品策划", "planning-image", "商品图片分析", "/api/product-planning/analyze-image", "POST", "body: imageUrl与产品上下文;底层功能开关仍生效"); +add("商品策划", "planning-sku", "商品 SKU 分析", "/api/product-planning/analyze-sku", "POST", "body: sku与用户商品信息"); +add("商品策划", "planning-analysis", "评价与问大家分析", "/api/product-planning/analyze", "POST", "body: kind=review/qa,rows为真实评价或问答数组"); +add("商品策划", "planning-keywords", "关键词洞察", "/api/product-planning/keyword-insight", "GET", "query: keyword等检索参数"); +for (const platform of ["taobao", "jd"]) add("商品策划", `planning-${platform}-item`, `${platform} 商品详情`, `/api/product-planning/${platform}/item`, "GET", "query: itemId等商品编号"); +add("商品策划", "planning-reviews", "淘宝真实评价", "/api/product-planning/taobao/reviews", "GET", "query: itemId、page等"); +add("商品策划", "planning-sales", "淘宝月销量", "/api/product-planning/taobao/month-sale", "GET", "query: itemId"); +add("商品策划", "planning-qa", "淘宝问大家", "/api/product-planning/taobao/qa", "POST", "body: itemId等商品编号"); +add("商品策划", "planning-market-items", "平台商品检索", "/api/product-planning/marketplace/items", "POST", "body: platform、keyword等检索参数"); +add("商品策划", "planning-templates", "策划模板列表与保存", "/api/product-planning/templates", "GET,POST", "POST body: title与策划内容;只保存当前用户自己的模板"); +add("商品策划", "planning-template", "策划模板读取与删除", "/api/product-planning/templates/[id]", "GET,DELETE", "pathParams: id;删除需要用户明确指定此编号"); +add("流程白板", "flow-files", "白板文件列表与创建", "/api/flow-board/files", "GET,POST", "POST body: title、snapshot;snapshot必须为真实白板快照"); +add("流程白板", "flow-file", "白板文件读取、修改、删除", "/api/flow-board/files/[id]", "GET,PUT,DELETE", "pathParams: id;PUT body: title、snapshot;先读取原文件,保留无关节点和工作表;删除需明确指定编号"); +add("流程白板", "flow-draft", "白板草稿读取与保存", "/api/flow-board/draft", "GET,PUT", "PUT body: title、snapshot;只操作当前用户草稿"); +add("分镜任务", "video-capabilities", "视频模型能力与参数", "/api/video-model-capabilities", "GET", "query: modelId等;沿用用户模型"); +add("分镜任务", "video-tasks", "用户视频任务列表", "/api/video-tasks", "GET", "query: page、limit等;仅当前用户任务"); +add("分镜任务", "storyboard-task", "分镜任务与阶段推进", "/api/video/storyboard/tasks/[taskId]", "GET", "pathParams: taskId;读取实际状态后再按接口动作推进,不重启已有收费任务"); +add("分镜任务", "storyboard-confirm", "确认用户分镜参数", "/api/video/storyboard/tasks/[taskId]/confirm", "POST", "pathParams: taskId;body: 用户实际确认的镜头与参数,不虚构用户确认"); +add("分镜任务", "storyboard-cancel", "停止指定分镜任务", "/api/video/storyboard/tasks/[taskId]/cancel", "POST", "pathParams: taskId;需用户明确要求停止此编号"); +add("分镜任务", "storyboard-shot", "分镜镜头修订", "/api/video/storyboard/tasks/[taskId]/shots/[shotIndex]", "PATCH", "pathParams: taskId、shotIndex;body: 用户要求的镜头修改"); +add("分镜任务", "storyboard-hd", "指定镜头高清处理", "/api/video/storyboard/tasks/[taskId]/shots/[shotIndex]/regenerate-hd", "POST", "pathParams: taskId、shotIndex;会产生费用,只有用户要求高清才执行"); +add("项目", "agent-projects", "Agent 创作项目列表与创建", "/api/agent-projects", "GET,POST", "POST body: title等项目数据;不写入其他用户项目"); +add("项目", "agent-project", "Agent 创作项目读写", "/api/agent-projects/[id]", "GET,PUT,DELETE", "pathParams: id;修改先读当前内容,删除需用户明确指定编号"); +add("项目", "canvas-list", "用户画布列表与创建", "/api/canvas", "GET,POST", "POST body: title、workspaceType=canvas/video等"); +add("项目", "canvas-read", "读取用户画布", "/api/canvas/[id]", "GET", "pathParams: id;只读取当前用户有权限的画布,节点写入使用专用画布工具"); +add("项目", "detail-archives", "画布详情归档", "/api/canvas/[id]/detail-archives", "GET,POST,PATCH,DELETE", "pathParams: id=当前画布编号;body/query按详情归档接口,删除需明确授权"); +add("项目", "model-assets", "3D 资产归档", "/api/canvas/[id]/model3d-assets", "GET,POST,PATCH,DELETE", "pathParams: id=当前画布编号;只处理拥有权限的资产"); +add("3D", "3d-task", "3D 生成任务状态", "/api/canvas/3d/tasks/[taskId]", "GET", "pathParams: taskId;生成用已有3D专用能力,不重复提交"); +add("3D", "world-task", "场景生成任务状态", "/api/canvas/world/tasks/[taskId]", "GET", "pathParams: taskId;生成用已有场景专用能力"); +add("智能编辑", "smart-edit", "智能图层编辑能力", "/api/canvas/smart-edit/capabilities", "GET", "无需参数;仅当该部署版本已有此功能时可用"); +add("文档", "documents", "读取与保存用户文档", "/api/document", "GET,POST", "query: id=文档UUID;POST body: title、kind=text/code/sheet/image、content。更新前先读取原文档,不操作其他用户文档。"); +add("图像处理", "enhance-pro", "专业高清处理任务与查询", "/api/enhance/pro", "GET,POST", "POST body按接口实际模型与尺寸要求,GET query: taskId。仅任务成功后才能交付,不能重复付费提交。"); +export function projectOperationAuthorized(operation: ProjectAgentOperation) { + return operation.group !== "分镜任务"; +} +export function projectOperationUrl(operation: ProjectAgentOperation, pathParams: Record, query: Record) { + const path = operation.path.replace(/\[([^\]]+)\]/g, (_all, key: string) => { + const value = pathParams[key]; + if (!value || !/^[a-zA-Z0-9_-]{1,180}$/.test(value)) throw new Error(`缺少或无效的路径参数:${key}`); + return encodeURIComponent(value); + }); + const values = new URLSearchParams(); + for (const [key, value] of Object.entries(query)) { + if (!/^[\w.-]{1,80}$/.test(key) || !["string", "number", "boolean"].includes(typeof value)) throw new Error("查询参数格式无效"); + values.set(key, String(value)); + } + return path + (values.size ? `?${values}` : ""); +} +export function sanitizeProjectToolOutput(value: unknown): unknown { + if (Array.isArray(value)) return value.map(sanitizeProjectToolOutput); + if (value && typeof value === "object") return Object.fromEntries(Object.entries(value) + .filter(([key]) => !/^(?:api[-_]?key|access[-_]?key|secret(?:[-_]?key)?|token|password(?:hash)?|ak|sk|accessKeyId|secretAccessKey|clientSecret|accessToken|refreshToken|authorization|cookie|headers|credentials|providerConfig)$/i.test(key)) + .map(([key, entry]) => [key, sanitizeProjectToolOutput(entry)])); + return value; +} diff --git a/lib/ai/canvas-agent-runtime/project-operation-contracts.json b/lib/ai/canvas-agent-runtime/project-operation-contracts.json new file mode 100644 index 000000000..3c395777f --- /dev/null +++ b/lib/ai/canvas-agent-runtime/project-operation-contracts.json @@ -0,0 +1,873 @@ +{ + "skills.get": { + "source": "app/api/agents/route.ts", + "methods": [ + "GET", + "POST" + ], + "schemas": { + "listQuerySchema": "z.object({\n scope: z.enum([\"all\", \"public\", \"private\"]).default(\"all\"),\n type: z.enum([\"image\", \"video\", \"text\"]).optional(),\n sectionId: z.string().trim().max(64).optional(),\n level1Id: z.string().trim().max(64).optional(),\n level2Id: z.string().trim().max(64).optional(),\n level3Id: z.string().trim().max(64).optional(),\n productCategory: z.string().trim().max(64).optional(),\n audienceTag: z.string().trim().max(64).optional(),\n usageScenario: z.string().trim().max(64).optional(),\n brand: z.string().trim().max(64).optional(),\n keyword: z.string().trim().max(128).optional(),\n sort: z.enum([\"latest\", \"hottest\", \"most_used\"]).default(\"latest\"),\n})", + "slotSchema": "z.object({\n title: z.string().trim().max(128).optional(),\n promptTemplate: z.string().trim().min(1).max(8000),\n defaultParams: z.record(z.string(), z.any()).optional(),\n requireUpload: z.boolean().optional(),\n uploadLabel: z.string().trim().max(128).optional(),\n referenceAssetIds: z.array(z.string().uuid()).max(12).optional(),\n})" + }, + "interfaces": {}, + "queryKeys": [ + "scope", + "type", + "sectionId", + "level1Id", + "level2Id", + "level3Id", + "productCategory", + "audienceTag", + "usageScenario", + "brand", + "keyword", + "sort" + ] + }, + "skill-categories.get": { + "source": "app/api/agent-categories/route.ts", + "methods": [ + "GET", + "POST" + ], + "schemas": { + "scopeSchema": "z.enum([\"all\", \"public\", \"private\"]).default(\"public\")", + "createCategorySchema": "z.object({\n name: z.string().trim().min(1).max(64),\n scope: z.enum([\"public\", \"private\"]).default(\"public\"),\n})" + }, + "interfaces": {}, + "queryKeys": [ + "scope" + ] + }, + "materials.get": { + "source": "app/api/agent-workflow/material-search/route.ts", + "methods": [ + "GET" + ], + "schemas": { + "querySchema": "z.object({\n keyword: z.string().trim().min(1).max(64),\n source: z.enum([\"primary\", \"secondary\"]).optional(),\n queryType: z.enum([\"sku\", \"spu\"]).optional(),\n requiredCount: z.coerce.number().int().min(1).max(4).optional(),\n appearanceRecognitionEnabled: z.enum([\"true\", \"false\", \"1\", \"0\"]).optional(),\n})" + }, + "interfaces": {}, + "queryKeys": [ + "keyword", + "source", + "queryType", + "requiredCount", + "appearanceRecognitionEnabled" + ] + }, + "references.get": { + "source": "app/api/agent-workflow/reference-search/route.ts", + "methods": [ + "GET" + ], + "schemas": { + "productDetailChannelSchema": "z.preprocess((value) => {\n const normalized = typeof value === \"string\" ? value.trim() : \"\";\n return normalized || undefined;\n}, z.enum([\"taobao\", \"1688\", \"douyin\", \"jd\"]).optional())", + "querySchema": "z.object({\n keyword: z.string().trim().min(1).max(64),\n queryType: z.enum([\"sku\", \"spu\", \"productId\"]).default(\"spu\"),\n target: z.enum([\"main\", \"detail\", \"sku\"]),\n brandName: z.string().trim().max(64).optional(),\n channel: productDetailChannelSchema,\n strictQueryType: z.enum([\"true\", \"false\", \"1\", \"0\"]).optional(),\n})" + }, + "interfaces": {}, + "queryKeys": [ + "item_id", + "channel", + "keyword", + "queryType", + "target", + "brandName", + "strictQueryType" + ] + }, + "appearance.post": { + "source": "app/api/agent-workflow/material-appearance/route.ts", + "methods": [ + "POST" + ], + "schemas": { + "payloadSchema": "z.object({\n imageUrl: z.string().trim().url().max(2000),\n})" + }, + "interfaces": {}, + "queryKeys": [] + }, + "third-party-materials.get": { + "source": "app/api/third-party-image-materials/search/route.ts", + "methods": [ + "GET" + ], + "schemas": { + "querySchema": "z.object({\n resourceType: z.enum([\"white-background\", \"task-detail\"]).default(\"white-background\"),\n sku: z.string().trim().max(64).optional(),\n spu: z.string().trim().max(64).optional(),\n keyword: z.string().trim().max(64).optional(),\n queryType: z.enum([\"sku\", \"spu\"]).optional(),\n})" + }, + "interfaces": {}, + "queryKeys": [ + "resourceType", + "sku", + "spu", + "keyword", + "queryType" + ] + }, + "gallery.get": { + "source": "app/api/gallery/route.ts", + "methods": [ + "GET" + ], + "schemas": {}, + "interfaces": {}, + "queryKeys": [ + "page", + "pageSize" + ] + }, + "featured.get": { + "source": "app/api/featured/route.ts", + "methods": [ + "GET" + ], + "schemas": {}, + "interfaces": {}, + "queryKeys": [ + "page", + "pageSize" + ] + }, + "ranking.get": { + "source": "app/api/featured/ranking/route.ts", + "methods": [ + "GET" + ], + "schemas": {}, + "interfaces": {}, + "queryKeys": [] + }, + "psd-templates.get": { + "source": "app/api/psd-templates/route.ts", + "methods": [ + "GET" + ], + "schemas": {}, + "interfaces": {}, + "queryKeys": [ + "brand", + "mode", + "summary" + ] + }, + "psd-template.get": { + "source": "app/api/psd-templates/[id]/route.ts", + "methods": [ + "GET" + ], + "schemas": {}, + "interfaces": {}, + "queryKeys": [] + }, + "psd-render.get": { + "source": "app/api/psd-templates/render/route.ts", + "methods": [ + "GET", + "POST" + ], + "schemas": {}, + "interfaces": {}, + "queryKeys": [ + "taskId" + ] + }, + "psd-render.post": { + "source": "app/api/psd-templates/render/route.ts", + "methods": [ + "GET", + "POST" + ], + "schemas": {}, + "interfaces": {}, + "queryKeys": [ + "taskId" + ] + }, + "detail-plan.post": { + "source": "app/api/canvas/detail-plan/route.ts", + "methods": [ + "POST" + ], + "schemas": {}, + "interfaces": {}, + "queryKeys": [] + }, + "detail-review.post": { + "source": "app/api/canvas/detail-review/route.ts", + "methods": [ + "POST" + ], + "schemas": {}, + "interfaces": {}, + "queryKeys": [] + }, + "detail-subject.post": { + "source": "app/api/canvas/detail-subject-analyze/route.ts", + "methods": [ + "POST" + ], + "schemas": {}, + "interfaces": {}, + "queryKeys": [] + }, + "ui-review.post": { + "source": "app/api/canvas/ui-screen/review/route.ts", + "methods": [ + "POST" + ], + "schemas": {}, + "interfaces": {}, + "queryKeys": [] + }, + "text-copy.post": { + "source": "app/api/canvas/text-copy-suggestions/route.ts", + "methods": [ + "POST" + ], + "schemas": { + "requestSchema": "z.object({\n imageUrl: z.string().min(1, \"图片地址不能为空\"),\n originalText: z.string().min(1, \"原文不能为空\"),\n currentText: z.string().optional(),\n title: z.string().optional(),\n pageTexts: z.array(z.string()).optional(),\n audience: z.string().optional(),\n usageScenario: z.string().optional(),\n coreNeed: z.string().optional(),\n productName: z.string().optional(),\n workflowSummary: z.string().optional(),\n workflowPrompt: z.string().optional(),\n userPrompt: z.string().optional(),\n presetName: z.string().optional(),\n})" + }, + "interfaces": {}, + "queryKeys": [] + }, + "detail-stitch.post": { + "source": "app/api/agent-workflow/detail-stitch/route.ts", + "methods": [ + "POST" + ], + "schemas": {}, + "interfaces": {}, + "queryKeys": [] + }, + "detail-normalize.post": { + "source": "app/api/agent-workflow/detail-image-normalize/route.ts", + "methods": [ + "POST" + ], + "schemas": {}, + "interfaces": {}, + "queryKeys": [] + }, + "style-models.get": { + "source": "app/api/style-pro/model-options/route.ts", + "methods": [ + "GET" + ], + "schemas": {}, + "interfaces": {}, + "queryKeys": [] + }, + "style-generate.post": { + "source": "app/api/style-pro/generate/route.ts", + "methods": [ + "GET", + "POST" + ], + "schemas": { + "generateRequestSchema": "z.object({\n canvasId: z.string().trim().min(1).max(160).optional(),\n requestId: z.string().uuid().optional(),\n sourceImageUrl: z.string().trim().min(1).max(4000),\n generationMode: z.enum([\"style\", \"realistic\"]).optional(),\n modelId: z.string().trim().min(1).max(160).optional(),\n selections: z.record(z.array(z.string().trim().min(1).max(120)).max(20)),\n customInputs: z\n .object({\n global: z.record(z.string().max(2000)).optional(),\n categories: z.record(z.record(z.string().max(2000))).optional(),\n })\n .optional(),\n})" + }, + "interfaces": {}, + "queryKeys": [ + "taskId" + ] + }, + "wash-models.get": { + "source": "app/api/ai-wash/model-options/route.ts", + "methods": [ + "GET" + ], + "schemas": {}, + "interfaces": {}, + "queryKeys": [] + }, + "wash-generate.post": { + "source": "app/api/ai-wash/generate/route.ts", + "methods": [ + "POST" + ], + "schemas": { + "requestSchema": "z.object({\n prompt: z.string().min(1).max(5000),\n referenceImage: z.string().min(1).max(200000),\n selectedModelId: z.string().min(1).max(128),\n imageSize: z.string().min(1).max(16).optional(),\n promptExtend: z.boolean().optional(),\n aspectRatio: z.string().min(1).max(16).optional(),\n title: z.string().max(128).optional(),\n})" + }, + "interfaces": {}, + "queryKeys": [] + }, + "planning-image.post": { + "source": "app/api/product-planning/analyze-image/route.ts", + "methods": [ + "POST" + ], + "schemas": { + "requestSchema": "z.object({\n itemId: z.string().trim().min(1),\n imageUrl: z.string().trim().url(),\n title: z.string().trim().optional(),\n})" + }, + "interfaces": {}, + "queryKeys": [] + }, + "planning-sku.post": { + "source": "app/api/product-planning/analyze-sku/route.ts", + "methods": [ + "POST" + ], + "schemas": { + "requestSchema": "z.object({\n itemId: z.string().trim().min(1),\n title: z.string().trim().optional(),\n platform: z.enum([\"taobao\", \"jd\"]),\n skus: z\n .array(\n z.object({\n name: z.string().trim().min(1),\n price: z.number().nullable(),\n })\n )\n .min(1),\n})" + }, + "interfaces": {}, + "queryKeys": [] + }, + "planning-analysis.post": { + "source": "app/api/product-planning/analyze/route.ts", + "methods": [ + "POST" + ], + "schemas": { + "requestSchema": "z.union([\n z.object({\n kind: z.literal(\"review\"),\n rows: z\n .array(\n z.object({\n itemId: z.string(),\n date: z.string(),\n content: z.string(),\n appendComment: z.string().optional(),\n sku: z.string().optional(),\n userId: z.string().optional(),\n images: z.array(z.string()),\n videoUrls: z.array(z.string()),\n })\n )\n .min(1),\n }),\n z.object({\n kind: z.literal(\"qa\"),\n rows: z\n .array(\n z.object({\n itemId: z.string(),\n question: z.string(),\n questionDetail: z.string().optional(),\n answer: z.string(),\n answerUser: z.string().optional(),\n answerDate: z.string().optional(),\n isOfficial: z.boolean(),\n })\n )\n .min(1),\n }),\n])" + }, + "interfaces": {}, + "queryKeys": [] + }, + "planning-keywords.get": { + "source": "app/api/product-planning/keyword-insight/route.ts", + "methods": [ + "GET" + ], + "schemas": {}, + "interfaces": {}, + "queryKeys": [ + "q" + ] + }, + "planning-taobao-item.get": { + "source": "app/api/product-planning/taobao/item/route.ts", + "methods": [ + "GET" + ], + "schemas": {}, + "interfaces": {}, + "queryKeys": [ + "id" + ] + }, + "planning-jd-item.get": { + "source": "app/api/product-planning/jd/item/route.ts", + "methods": [ + "GET" + ], + "schemas": {}, + "interfaces": {}, + "queryKeys": [ + "id" + ] + }, + "planning-reviews.get": { + "source": "app/api/product-planning/taobao/reviews/route.ts", + "methods": [ + "GET" + ], + "schemas": {}, + "interfaces": {}, + "queryKeys": [ + "id", + "page" + ] + }, + "planning-sales.get": { + "source": "app/api/product-planning/taobao/month-sale/route.ts", + "methods": [ + "GET" + ], + "schemas": {}, + "interfaces": {}, + "queryKeys": [ + "id" + ] + }, + "planning-qa.post": { + "source": "app/api/product-planning/taobao/qa/route.ts", + "methods": [ + "POST" + ], + "schemas": { + "requestSchema": "z.object({\n itemId: z.string().trim().min(1),\n page: z.number().int().min(1).max(20).default(1),\n})" + }, + "interfaces": {}, + "queryKeys": [] + }, + "planning-market-items.post": { + "source": "app/api/product-planning/marketplace/items/route.ts", + "methods": [ + "POST" + ], + "schemas": {}, + "interfaces": {}, + "queryKeys": [] + }, + "planning-templates.get": { + "source": "app/api/product-planning/templates/route.ts", + "methods": [ + "GET", + "POST" + ], + "schemas": {}, + "interfaces": {}, + "queryKeys": [] + }, + "planning-templates.post": { + "source": "app/api/product-planning/templates/route.ts", + "methods": [ + "GET", + "POST" + ], + "schemas": {}, + "interfaces": {}, + "queryKeys": [] + }, + "planning-template.get": { + "source": "app/api/product-planning/templates/[id]/route.ts", + "methods": [ + "GET", + "DELETE" + ], + "schemas": {}, + "interfaces": {}, + "queryKeys": [] + }, + "planning-template.delete": { + "source": "app/api/product-planning/templates/[id]/route.ts", + "methods": [ + "GET", + "DELETE" + ], + "schemas": {}, + "interfaces": {}, + "queryKeys": [] + }, + "flow-files.get": { + "source": "app/api/flow-board/files/route.ts", + "methods": [ + "GET", + "POST" + ], + "schemas": {}, + "interfaces": {}, + "queryKeys": [] + }, + "flow-files.post": { + "source": "app/api/flow-board/files/route.ts", + "methods": [ + "GET", + "POST" + ], + "schemas": {}, + "interfaces": {}, + "queryKeys": [] + }, + "flow-file.get": { + "source": "app/api/flow-board/files/[id]/route.ts", + "methods": [ + "GET", + "PUT", + "DELETE" + ], + "schemas": {}, + "interfaces": {}, + "queryKeys": [] + }, + "flow-file.put": { + "source": "app/api/flow-board/files/[id]/route.ts", + "methods": [ + "GET", + "PUT", + "DELETE" + ], + "schemas": {}, + "interfaces": {}, + "queryKeys": [] + }, + "flow-file.delete": { + "source": "app/api/flow-board/files/[id]/route.ts", + "methods": [ + "GET", + "PUT", + "DELETE" + ], + "schemas": {}, + "interfaces": {}, + "queryKeys": [] + }, + "flow-draft.get": { + "source": "app/api/flow-board/draft/route.ts", + "methods": [ + "GET", + "PUT" + ], + "schemas": {}, + "interfaces": {}, + "queryKeys": [] + }, + "flow-draft.put": { + "source": "app/api/flow-board/draft/route.ts", + "methods": [ + "GET", + "PUT" + ], + "schemas": {}, + "interfaces": {}, + "queryKeys": [] + }, + "video-capabilities.get": { + "source": "app/(chat)/api/video-model-capabilities/route.ts", + "methods": [ + "GET" + ], + "schemas": {}, + "interfaces": {}, + "queryKeys": [ + "modelId" + ] + }, + "video-tasks.get": { + "source": "app/(chat)/api/video-tasks/route.ts", + "methods": [ + "GET" + ], + "schemas": {}, + "interfaces": {}, + "queryKeys": [ + "chatId" + ] + }, + "storyboard-task.get": { + "source": "app/(chat)/api/video/storyboard/tasks/[taskId]/route.ts", + "methods": [ + "GET" + ], + "schemas": { + "paramsSchema": "z.object({\n taskId: z.string().uuid(),\n})" + }, + "interfaces": {}, + "queryKeys": [] + }, + "storyboard-confirm.post": { + "source": "app/(chat)/api/video/storyboard/tasks/[taskId]/confirm/route.ts", + "methods": [ + "POST" + ], + "schemas": { + "paramsSchema": "z.object({\n taskId: z.string().uuid(),\n})" + }, + "interfaces": {}, + "queryKeys": [] + }, + "storyboard-cancel.post": { + "source": "app/(chat)/api/video/storyboard/tasks/[taskId]/cancel/route.ts", + "methods": [ + "POST" + ], + "schemas": { + "paramsSchema": "z.object({\n taskId: z.string().uuid(),\n})" + }, + "interfaces": {}, + "queryKeys": [] + }, + "storyboard-shot.patch": { + "source": "app/(chat)/api/video/storyboard/tasks/[taskId]/shots/[shotIndex]/route.ts", + "methods": [ + "PATCH" + ], + "schemas": { + "paramsSchema": "z.object({\n taskId: z.string().uuid(),\n shotIndex: z.coerce.number().int().min(1).max(99),\n})", + "bodySchema": "z.object({\n prompt: z.string().trim().min(1).max(4000),\n regenerateHd: z.boolean().optional().default(true),\n})" + }, + "interfaces": {}, + "queryKeys": [] + }, + "storyboard-hd.post": { + "source": "app/(chat)/api/video/storyboard/tasks/[taskId]/shots/[shotIndex]/regenerate-hd/route.ts", + "methods": [ + "POST" + ], + "schemas": { + "paramsSchema": "z.object({\n taskId: z.string().uuid(),\n shotIndex: z.coerce.number().int().min(1).max(99),\n})" + }, + "interfaces": {}, + "queryKeys": [] + }, + "agent-projects.get": { + "source": "app/api/agent-projects/route.ts", + "methods": [ + "GET", + "POST" + ], + "schemas": {}, + "interfaces": {}, + "queryKeys": [] + }, + "agent-projects.post": { + "source": "app/api/agent-projects/route.ts", + "methods": [ + "GET", + "POST" + ], + "schemas": {}, + "interfaces": {}, + "queryKeys": [] + }, + "agent-project.get": { + "source": "app/api/agent-projects/[id]/route.ts", + "methods": [ + "GET", + "PUT", + "DELETE" + ], + "schemas": {}, + "interfaces": {}, + "queryKeys": [] + }, + "agent-project.put": { + "source": "app/api/agent-projects/[id]/route.ts", + "methods": [ + "GET", + "PUT", + "DELETE" + ], + "schemas": {}, + "interfaces": {}, + "queryKeys": [] + }, + "agent-project.delete": { + "source": "app/api/agent-projects/[id]/route.ts", + "methods": [ + "GET", + "PUT", + "DELETE" + ], + "schemas": {}, + "interfaces": {}, + "queryKeys": [] + }, + "canvas-list.get": { + "source": "app/api/canvas/route.ts", + "methods": [ + "GET", + "POST" + ], + "schemas": {}, + "interfaces": {}, + "queryKeys": [ + "workspaceType", + "limit", + "page" + ] + }, + "canvas-list.post": { + "source": "app/api/canvas/route.ts", + "methods": [ + "GET", + "POST" + ], + "schemas": {}, + "interfaces": {}, + "queryKeys": [ + "workspaceType", + "limit", + "page" + ] + }, + "canvas-read.get": { + "source": "app/api/canvas/[id]/route.ts", + "methods": [ + "GET", + "PUT", + "DELETE" + ], + "schemas": {}, + "interfaces": {}, + "queryKeys": [] + }, + "detail-archives.get": { + "source": "app/api/canvas/[id]/detail-archives/route.ts", + "methods": [ + "GET", + "POST", + "PATCH", + "DELETE" + ], + "schemas": {}, + "interfaces": {}, + "queryKeys": [ + "archiveId" + ] + }, + "detail-archives.post": { + "source": "app/api/canvas/[id]/detail-archives/route.ts", + "methods": [ + "GET", + "POST", + "PATCH", + "DELETE" + ], + "schemas": {}, + "interfaces": {}, + "queryKeys": [ + "archiveId" + ] + }, + "detail-archives.patch": { + "source": "app/api/canvas/[id]/detail-archives/route.ts", + "methods": [ + "GET", + "POST", + "PATCH", + "DELETE" + ], + "schemas": {}, + "interfaces": {}, + "queryKeys": [ + "archiveId" + ] + }, + "detail-archives.delete": { + "source": "app/api/canvas/[id]/detail-archives/route.ts", + "methods": [ + "GET", + "POST", + "PATCH", + "DELETE" + ], + "schemas": {}, + "interfaces": {}, + "queryKeys": [ + "archiveId" + ] + }, + "model-assets.get": { + "source": "app/api/canvas/[id]/model3d-assets/route.ts", + "methods": [ + "GET", + "POST", + "DELETE", + "PATCH" + ], + "schemas": {}, + "interfaces": {}, + "queryKeys": [ + "taskId" + ] + }, + "model-assets.post": { + "source": "app/api/canvas/[id]/model3d-assets/route.ts", + "methods": [ + "GET", + "POST", + "DELETE", + "PATCH" + ], + "schemas": {}, + "interfaces": {}, + "queryKeys": [ + "taskId" + ] + }, + "model-assets.patch": { + "source": "app/api/canvas/[id]/model3d-assets/route.ts", + "methods": [ + "GET", + "POST", + "DELETE", + "PATCH" + ], + "schemas": {}, + "interfaces": {}, + "queryKeys": [ + "taskId" + ] + }, + "model-assets.delete": { + "source": "app/api/canvas/[id]/model3d-assets/route.ts", + "methods": [ + "GET", + "POST", + "DELETE", + "PATCH" + ], + "schemas": {}, + "interfaces": {}, + "queryKeys": [ + "taskId" + ] + }, + "3d-task.get": { + "source": "app/api/canvas/3d/tasks/[taskId]/route.ts", + "methods": [ + "GET" + ], + "schemas": {}, + "interfaces": {}, + "queryKeys": [ + "providerId" + ] + }, + "world-task.get": { + "source": "app/api/canvas/world/tasks/[taskId]/route.ts", + "methods": [ + "GET" + ], + "schemas": {}, + "interfaces": {}, + "queryKeys": [ + "providerId" + ] + }, + "documents.get": { + "source": "app/(chat)/api/document/route.ts", + "methods": [ + "GET", + "POST", + "DELETE" + ], + "schemas": {}, + "interfaces": {}, + "queryKeys": [ + "id", + "timestamp" + ] + }, + "documents.post": { + "source": "app/(chat)/api/document/route.ts", + "methods": [ + "GET", + "POST", + "DELETE" + ], + "schemas": {}, + "interfaces": {}, + "queryKeys": [ + "id", + "timestamp" + ] + }, + "enhance-pro.get": { + "source": "app/api/enhance/pro/route.ts", + "methods": [ + "GET", + "POST" + ], + "schemas": {}, + "interfaces": {}, + "queryKeys": [ + "taskId" + ] + }, + "enhance-pro.post": { + "source": "app/api/enhance/pro/route.ts", + "methods": [ + "GET", + "POST" + ], + "schemas": {}, + "interfaces": {}, + "queryKeys": [ + "taskId" + ] + } +} diff --git a/lib/ai/canvas-agent-runtime/project-tools.ts b/lib/ai/canvas-agent-runtime/project-tools.ts new file mode 100644 index 000000000..61291eaa6 --- /dev/null +++ b/lib/ai/canvas-agent-runtime/project-tools.ts @@ -0,0 +1,94 @@ +import "server-only"; +import { tool, type ToolSet } from "ai"; +import type { Session } from "next-auth"; +import { z } from "zod"; +import contracts from "./project-operation-contracts.json"; +import { getAccessibleAgentPresetById, getDocumentById } from "@/lib/db/queries"; +import { getEnabledTools } from "@/lib/ai/tools-registry"; +import { getWeather } from "@/lib/ai/tools/get-weather"; +import { createDocument } from "@/lib/ai/tools/create-document"; +import { updateDocument } from "@/lib/ai/tools/update-document"; +import { requestSuggestions } from "@/lib/ai/tools/request-suggestions"; +import { PROJECT_AGENT_OPERATIONS, projectOperationAuthorized, projectOperationUrl, sanitizeProjectToolOutput } from "./project-operation-catalog"; +import { isExplicitDestructiveIntent } from "./capability-access"; +import type { CanvasAgentTool } from "./loop"; + +export async function registerProjectAgentTools(params: { + session: Session; projectId: string; request: Request; objective: string; + definitions: ToolSet; executable: Record; + emit: (type: string, data: unknown) => void; +}) { + const userId = params.session.user!.id!; + function register(name: string, description: string, schema: z.ZodTypeAny, execute: CanvasAgentTool["execute"], readOnly = true) { + params.definitions[name] = tool({ description, inputSchema: schema }); + params.executable[name] = { title: description.slice(0, 32), readOnly, concurrentSafe: readOnly, execute }; + } + register("listProjectServices", "列出图片画布之外的全部项目业务工具、真实接口及输入提示。可按分组筛选;authorized=false的分镜/视频功能暂不授权。", z.object({ group: z.string().max(100).optional(), operationId: z.string().max(120).optional() }), + async input => ({ services: PROJECT_AGENT_OPERATIONS.filter(item => (!input.group || item.group === input.group) && (!input.operationId || item.id === input.operationId)) + .map(item => ({ ...item, authorized: projectOperationAuthorized(item), ...(input.operationId ? { requestContract: (contracts as Record)[item.id] } : {}) })), legacyTools: ["getWeather", "createDocument", "updateDocument", "requestSuggestions"], + limits: "仅当前用户权限;无后台管理、密钥、支付、系统任务和Claw控制权限;文件选择用浏览器入口;异步任务必须轮询真实状态。" })); + const invokeSchema = z.object({ operationId: z.string().min(1).max(120), pathParams: z.record(z.string().max(180)).default({}), + query: z.record(z.union([z.string().max(4000), z.number(), z.boolean()])).default({}), body: z.record(z.unknown()).optional() }); + async function invoke(input: Record, callId: string, readOnly: boolean): Promise> { + const args = invokeSchema.parse(input); + const operation = PROJECT_AGENT_OPERATIONS.find(item => item.id === args.operationId); + if (!operation || operation.readOnly !== readOnly) throw new Error("请使用清单中对应读写类别的固定业务工具"); + if (!projectOperationAuthorized(operation)) throw new Error("用户暂未授权视频画布和分镜工具"); + if (JSON.stringify(args.body || {}).length > 2 * 1024 * 1024) throw new Error("业务工具输入超过大小限制"); + if (args.body?.workspaceType === "video" || args.query.workspaceType === "video" || args.body?.type === "video") throw new Error("视频画布暂未授权"); + if (operation.path.startsWith("/api/canvas/[id]")) { + if (args.pathParams.id !== params.projectId) throw new Error("画布业务接口仅授权当前画布,不能跨画布读取或写入"); + } + if (operation.method === "DELETE" && (!isExplicitDestructiveIntent(params.objective) || !Object.values(args.pathParams).some(id => params.objective.includes(id)))) + throw new Error("删除项目文件需要用户明确提出删除,并在要求中指定文件编号;模型不能自行授权"); + if (operation.id === "canvas-list.post" && !/新建|创建|新增/.test(params.objective)) throw new Error("请先确认需要新建画布"); + if (args.body?.userId && args.body.userId !== userId) throw new Error("不能指定其他用户身份"); + const route = projectOperationUrl(operation, args.pathParams, args.query); + const incoming = new URL(params.request.url); + const port = incoming.port || process.env.PORT || "3125"; + if (!/^\d{2,5}$/.test(port) || Number(port) > 65535) throw new Error("业务网关端口未配置"); + const headers = new Headers({ "Content-Type": "application/json", "x-canvas-agent-call-id": callId }); + // Auth is inherited from the original request; models cannot supply headers, + // cookies, another host, URL, user identity or provider credentials. + for (const key of ["cookie", "host", "x-forwarded-host", "x-forwarded-proto"]) + if (params.request.headers.has(key)) headers.set(key, params.request.headers.get(key)!); + const response = await fetch(`http://127.0.0.1:${port}${route}`, { method: operation.method, headers, redirect: "error", cache: "no-store", + ...(operation.method !== "GET" ? { body: JSON.stringify(args.body || {}) } : {}), signal: AbortSignal.timeout(300000) }); + if (!response.headers.get("content-type")?.includes("application/json")) { await response.body?.cancel(); throw new Error(`此工具未返回可核验JSON结果(${response.status});请使用真实界面处理文件或流式操作`); } + const raw = await response.text(); if (raw.length > 2 * 1024 * 1024) throw new Error("业务返回过大,请缩小查询范围"); + const payload = JSON.parse(raw); + if (!response.ok || payload?.success === false || payload?.error) throw new Error(`业务工具 ${operation.title} 未成功(${response.status}):${typeof payload?.error === "string" ? payload.error.slice(0, 200) : "请核对输入参数或底层服务权限"}`); + if (operation.id === "canvas-list.get" && Array.isArray(payload?.data)) payload.data = payload.data.filter((row: { workspaceType?: string }) => row.workspaceType !== "video"); + const status = payload?.processing || ["pending", "running", "queued"].includes(payload?.status) ? "pending" : payload?.status === "failed" ? "failed" : "succeeded"; + return { projectService: true, operationId: operation.id, status, taskId: payload?.taskId, + result: sanitizeProjectToolOutput(payload), message: status === "pending" ? "仅已受理,必须轮询状态确认实际结果;禁止重复创建任务。" : "已获得真实业务接口结果" }; + } + register("readProjectService", "读取项目业务数据。先 listProjectServices 查看 operationId、pathParams和query要求;仅执行已授权GET接口。", invokeSchema, (input, id) => invoke(input, id, true)); + register("runProjectService", "执行固定项目业务接口。先查清单和真实数据、制定计划;仅当前用户权限。pending表示任务已受理,不能声称完成或重复收费。", invokeSchema, (input, id) => invoke(input, id, false), false); + register("loadProjectSkill", "读取用户可访问的技能完整提示词、槽位和默认参数,由当前ZCode核心执行;不会调用另一个旧Agent或自动生成收费内容。", z.object({ presetId: z.string().uuid() }), async input => { + const preset = await getAccessibleAgentPresetById({ id: String(input.presetId), userId }); + if (!preset || preset.status !== "active") throw new Error("此技能不可用或无权访问"); + if (preset.type === "video") throw new Error("视频技能暂未授权给 ZCode Agent"); + return { id: preset.id, name: preset.name, type: preset.type, promptTemplate: preset.promptTemplate, defaultModelId: preset.defaultModelId, + defaultParams: sanitizeProjectToolOutput(preset.defaultParams), slots: preset.slots.map(slot => ({ title: slot.title, promptTemplate: slot.promptTemplate, defaultParams: sanitizeProjectToolOutput(slot.defaultParams) })), + message: "请按用户当前任务采用技能指令,并使用真实已授权工具执行;不得虚构结果。" }; + }); + const enabled = new Set(await getEnabledTools()); + const dataStream = { write: (part: { type: string; data?: unknown }) => params.emit(part.type, part.data) }; + const legacy: ToolSet = { getWeather, createDocument: createDocument({ session: params.session, dataStream: dataStream as never }), + updateDocument: updateDocument({ session: params.session, dataStream: dataStream as never }), requestSuggestions: requestSuggestions({ session: params.session, dataStream: dataStream as never }) }; + for (const [name, definition] of Object.entries(legacy)) { + params.definitions[name] = { ...definition, execute: undefined }; + params.executable[name] = { title: name, readOnly: name === "getWeather", concurrentSafe: name === "getWeather", execute: async (input, callId) => { + if (!enabled.has(name as never)) throw new Error("管理员尚未启用此工具;授权清单不绕过底层服务开关"); + const id = input.id || input.documentId; + if (name !== "getWeather" && name !== "createDocument") { const doc = await getDocumentById({ id: String(id) }); + if (!doc || doc.userId !== userId) throw new Error("文档不存在或不属于当前用户"); } + const output = await definition.execute!(input as never, { toolCallId: callId, messages: [] }); + if (!output || typeof output !== "object" || "error" in output) throw new Error("业务工具未返回有效结果"); + if (name !== "getWeather") { const doc = await getDocumentById({ id: String((output as { id?: string }).id) }); + if (!doc || doc.userId !== userId || !doc.content) throw new Error("文档尚未保存,不能声称完成"); } + return { projectService: true, status: "succeeded", ...sanitizeProjectToolOutput(output) as Record }; + } }; + } +} diff --git a/lib/ai/canvas-agent-runtime/routing.ts b/lib/ai/canvas-agent-runtime/routing.ts index 2e961277e..9cc309b23 100644 --- a/lib/ai/canvas-agent-runtime/routing.ts +++ b/lib/ai/canvas-agent-runtime/routing.ts @@ -1,10 +1,12 @@ +import { isZcodeWorkspaceAuthorized } from "./authorization"; /** Agent/Auto Agent/presets always use native ZCode. Claw and direct media modes retain their routes. */ export function shouldUseCanvasAgentRuntime(body: { composerMode?: string; + workspaceVariant?: string; agentPresetId?: string; resumeRunId?: string; contextPayload?: { source?: string; projectId?: string }; message?: { parts?: Array<{ type?: string; text?: string }> }; }) { - return body.composerMode === "agent" && body.contextPayload?.source === "canvas" && Boolean(body.contextPayload.projectId); + return body.composerMode === "agent" && body.contextPayload?.source === "canvas" && Boolean(body.contextPayload.projectId) && isZcodeWorkspaceAuthorized(body.workspaceVariant || "canvas"); } diff --git a/lib/ai/zcode-agent/task.ts b/lib/ai/zcode-agent/task.ts index d31a63bdd..9d536ac32 100644 --- a/lib/ai/zcode-agent/task.ts +++ b/lib/ai/zcode-agent/task.ts @@ -45,9 +45,10 @@ export async function runZcodeCanvasTask(ports: Ports): Promise { const call = snapshot.calls.find(call => call.id === callId)!; call.status = "succeeded"; call.output = output; + if (output.projectService && output.status === "succeeded" && typeof output.taskId === "string") { + for (const accepted of snapshot.calls) if (accepted.output?.projectService && accepted.output.taskId === output.taskId && accepted.output.status === "pending") + accepted.output = { ...accepted.output, status: "succeeded", verifiedResult: output.result }; + } if (name === "planCanvasTask") snapshot.requirements = { ...snapshot.requirements, ...(typeof output.expectedImageCount === "number" ? { expectedImageCount: output.expectedImageCount } : {}), ...(typeof output.aspectRatio === "string" ? { aspectRatio: output.aspectRatio } : {}) }; @@ -156,6 +161,12 @@ export async function runZcodeCanvasTask(ports: Ports): Promise !startedInputs.has(input.id)); if (supplements.length) { prompt = supplements.map(input => input.text).join("\n"); continue; } + const projectWrites = snapshot.calls.filter(call => !ports.tools[call.name]?.readOnly && call.output?.projectService); + const canvasWrites = snapshot.calls.filter(call => !ports.tools[call.name]?.readOnly && !call.output?.projectService); + if (projectWrites.length && !canvasWrites.length && !snapshot.requirements?.expectedImageCount) { + const pending = projectWrites.some(call => call.output?.status !== "succeeded"); + return await save(pending ? "业务任务已受理或等待核对,请读取实际任务状态,保留原任务编号继续。" : result.response || "项目业务操作已完成。", pending ? "needs_review" : "completed"); + } // Text/analysis tasks have no generated media to inspect. Mutating tasks // still use the existing independent checks against actual saved nodes. const mutated = snapshot.calls.some(call => !ports.tools[call.name]?.readOnly); diff --git a/playwright.canvas-agent.config.ts b/playwright.canvas-agent.config.ts index 35d99e3be..4b8066e4b 100644 --- a/playwright.canvas-agent.config.ts +++ b/playwright.canvas-agent.config.ts @@ -2,7 +2,7 @@ import { defineConfig } from "@playwright/test"; export default defineConfig({ testDir: "./tests/routes", - testMatch: /(?:canvas-agent-runtime(?:-store|-review|-video)?|agent-capability-access)\.test\.ts/, + testMatch: /(?:canvas-agent-runtime(?:-store|-review|-video)?|canvas-agent-project-tools|agent-capability-access)\.test\.ts/, fullyParallel: true, retries: 0, workers: 2, diff --git a/scripts/zcode-agent/audit-project-tools.mjs b/scripts/zcode-agent/audit-project-tools.mjs new file mode 100644 index 000000000..434072259 --- /dev/null +++ b/scripts/zcode-agent/audit-project-tools.mjs @@ -0,0 +1,41 @@ +import ts from 'typescript'; +import { readFile, writeFile, access } from 'node:fs/promises'; +import { execFileSync } from 'node:child_process'; +const catalog = JSON.parse(execFileSync(process.execPath, ['node_modules/tsx/dist/cli.mjs','-e', "import {PROJECT_AGENT_OPERATIONS} from './lib/ai/canvas-agent-runtime/project-operation-catalog';console.log(JSON.stringify(PROJECT_AGENT_OPERATIONS))"], { encoding: 'utf8' })); +const contracts = {}; const mismatch = []; +for (const operation of catalog) { + let file; + for (const root of ['app/api','app/(chat)/api']) { + const path = `${root}/${operation.path.slice('/api/'.length)}/route.ts`; + try { await access(path); file = path; break; } catch {} + } + if (!file) { if (operation.id !== 'smart-edit.get') mismatch.push(`${operation.id}: missing route`); continue; } + const source = await readFile(file,'utf8'); + const methods = [...source.matchAll(/export\s+(?:async\s+)?function\s+(GET|POST|PUT|PATCH|DELETE)/g)].map(match => match[1]); + if (!methods.includes(operation.method)) mismatch.push(`${operation.id}: method not implemented`); + const ast = ts.createSourceFile(file,source,ts.ScriptTarget.Latest,true); const schemas = {}, interfaces = {}; + function walk(node) { + if (ts.isVariableDeclaration(node) && node.initializer && /schema$/i.test(node.name.getText(ast)) && /^z\./.test(node.initializer.getText(ast))) + schemas[node.name.getText(ast)] = node.initializer.getText(ast).slice(0,6000); + if (ts.isInterfaceDeclaration(node) && /request|payload|body/i.test(node.name.getText(ast))) interfaces[node.name.getText(ast)] = node.getText(ast).slice(0,6000); + ts.forEachChild(node,walk); + } + walk(ast); + contracts[operation.id] = { source: file, methods, schemas, interfaces, + queryKeys: [...new Set([...source.matchAll(/(?:searchParams|params)\.get\(["']([^"']+)["']\)/g)].map(match=>match[1]))] }; +} +if (mismatch.length) throw new Error(mismatch.join('\n')); +await writeFile('lib/ai/canvas-agent-runtime/project-operation-contracts.json',JSON.stringify(contracts,null,2)+'\n'); +console.log(JSON.stringify({ operations: catalog.length, routeContracts: Object.keys(contracts).length, deploymentOnly: 'smart-edit.get', unsupportedMethods: mismatch.length })); + +const canvas = JSON.parse(execFileSync(process.execPath, ['node_modules/tsx/dist/cli.mjs','-e', "import {getCanvasAgentAccessManifest} from './lib/ai/canvas-agent-runtime/capability-access';console.log(JSON.stringify(getCanvasAgentAccessManifest()))"], { encoding: 'utf8' })); +const project = catalog.map(item=>({...item, authorized:item.group !== '分镜任务', previouslyExposed:false, execution:'server'})); +const utilities = ['getWeather','createDocument','updateDocument','requestSuggestions','loadProjectSkill'].map(id=>({id,title:id,group:'文档、天气与技能',authorized:true,previouslyExposed:false,entry:id,execution:'server'})); +const report = { policy:'图片画布及非视频项目业务已授权;视频画布与分镜暂不授权;底层用户权限与服务开关仍生效。管理、密钥、支付、身份认证、系统任务和Claw不属于创作Agent工具。', + upstreamCommit:'0a1fc56d279fd1001f78387bd81aec1c26767411', rows:[...canvas,...project,...utilities], + verifiedRoutes:Object.keys(contracts).length, deploymentOnly:['smart-edit.get'] }; +await writeFile('docs/specs/zcode-canvas/authorization-audit.json',JSON.stringify(report,null,2)+'\n'); +const esc=value=>String(value??'').replace(/[&<>"']/g,char=>({'&':'&','<':'<','>':'>','"':'"',"'":'''}[char])); +const rows=report.rows.map(row=>`${esc(row.workspace||row.group||'项目')}${esc(row.title)}${row.authorized?'已授权':'暂未授权'}${esc(row.entry||row.id)}${esc(row.note||row.hint||'')}`).join(''); +await writeFile('docs/specs/zcode-canvas/authorization-audit.html',`ZCode Agent 工具授权清单

ZCode Agent 工具授权清单

${esc(report.policy)}

共 ${report.rows.length} 项能力;每一项均保留实际执行方式与限制。接口鉴权不等于业务结果已完成。

${rows}
范围能力授权工具 / 操作编号执行限制
`); +console.log(JSON.stringify({auditRows:report.rows.length, authorized:report.rows.filter(row=>row.authorized).length, paused:report.rows.filter(row=>!row.authorized).length, addedProjectOperations:project.filter(row=>row.authorized).length})); diff --git a/services/zcode-agent/README.md b/services/zcode-agent/README.md index 83e7bd134..29c582fe4 100644 --- a/services/zcode-agent/README.md +++ b/services/zcode-agent/README.md @@ -60,3 +60,5 @@ uncertain results. These fixtures do not prove a configured real provider is healthy. A release also needs a real-provider test on a private image and video canvas, authentication/ownership probes and static-resource checks before switching the active Next build. + +Current authorization: video canvas and storyboard Agent access is paused by the user. Image canvas and non-video project tools remain authorized; the real project workspace is checked server-side, so forged client mode cannot enable video. Full per-entry audit: authorization-audit.json / authorization-audit.html. diff --git a/tests/routes/agent-capability-access.test.ts b/tests/routes/agent-capability-access.test.ts index 800163755..d32dcbac3 100644 --- a/tests/routes/agent-capability-access.test.ts +++ b/tests/routes/agent-capability-access.test.ts @@ -111,7 +111,8 @@ test("every registered image capability is authorized to the Agent including loc test("access manifest covers all configured video functions and node/UI actions without granting fake backends", () => { const manifest = getCanvasAgentAccessManifest(); expect(new Set(manifest.map((item) => item.id)).size).toBe(manifest.length); - expect(manifest.every((item) => item.authorized)).toBe(true); + expect(manifest.filter(item => item.workspace === "canvas").every(item => item.authorized)).toBe(true); + expect(manifest.filter(item => item.workspace === "video").every(item => !item.authorized)).toBe(true); for (const key of Object.keys(defaultVideoCanvasFunctionConfig.functions)) expect(manifest.some((item) => item.id === `video.function.${key}`)).toBe(true); for (const [key] of VIDEO_CANVAS_EXTRA_ACTIONS) @@ -119,7 +120,7 @@ test("access manifest covers all configured video functions and node/UI actions for (const [key] of VIDEO_CANVAS_INTERACTIVE_ACTIONS) expect(manifest.some((item) => item.id === `video.ui.${key}`)).toBe(true); expect(manifest.find((item) => item.id === "video.function.audio-to-video")).toMatchObject({ - authorized: true, + authorized: false, execution: "backend_required", }); expect(manifest.find((item) => item.id === "video.ui.subtitle-erase")?.note).toContain("模拟"); diff --git a/tests/routes/canvas-agent-project-tools.test.ts b/tests/routes/canvas-agent-project-tools.test.ts new file mode 100644 index 000000000..6eed25f4f --- /dev/null +++ b/tests/routes/canvas-agent-project-tools.test.ts @@ -0,0 +1,32 @@ +import { expect, test } from "@playwright/test"; +import { readFileSync, existsSync } from "node:fs"; +import { PROJECT_AGENT_OPERATIONS, projectOperationAuthorized, projectOperationUrl, sanitizeProjectToolOutput } from "@/lib/ai/canvas-agent-runtime/project-operation-catalog"; +import { shouldUseCanvasAgentRuntime } from "@/lib/ai/canvas-agent-runtime/routing"; +import { getCanvasAgentAccessManifest } from "@/lib/ai/canvas-agent-runtime/capability-access"; + +test("business grant uses only fixed implemented route/method pairs and no management or secret endpoints", () => { + expect(new Set(PROJECT_AGENT_OPERATIONS.map(item=>item.id)).size).toBe(PROJECT_AGENT_OPERATIONS.length); + for (const op of PROJECT_AGENT_OPERATIONS) { + expect(op.path).not.toMatch(/\/admin\/|\/internal\/|\/jobs\/|\/auth\/|\/payment\/|access-keys|clawd-chat|agent-chat/); + const relative=op.path.slice('/api/'.length)+'/route.ts'; + const path=['app/api/','app/(chat)/api/'].map(base=>base+relative).find(existsSync); + if (!path) { expect(op.id).toBe('smart-edit.get'); continue; } + expect(readFileSync(path,'utf8')).toMatch(new RegExp(`export\\s+(?:async\\s+)?function\\s+${op.method}\\b`)); + } +}); +test("video canvas and storyboard permissions are explicitly paused and never admitted through a forged mode", () => { + expect(getCanvasAgentAccessManifest().filter(item=>item.workspace==='video').every(item=>!item.authorized)).toBe(true); + expect(PROJECT_AGENT_OPERATIONS.filter(item=>item.group==='分镜任务').every(item=>!projectOperationAuthorized(item))).toBe(true); + expect(shouldUseCanvasAgentRuntime({ composerMode:'agent', workspaceVariant:'video', contextPayload:{ source:'canvas',projectId:'p' }})).toBe(false); + const route=readFileSync('app/api/canvas/agent-chat/route.ts','utf8'); + expect(route).toContain('isZcodeWorkspaceAuthorized(ownedProject.workspaceType)'); +}); +test("operation URL substitution rejects path escapes and keeps query values encoded", () => { + const op=PROJECT_AGENT_OPERATIONS.find(item=>item.id==='flow-file.get')!; + expect(()=>projectOperationUrl(op,{id:'../../admin/keys'},{})).toThrow(); + expect(()=>projectOperationUrl(op,{id:'a%2Fadmin'},{})).toThrow(); + expect(projectOperationUrl(op,{id:'safe-id'},{keyword:'a&x=http://evil'})).toBe('/api/flow-board/files/safe-id?keyword=a%26x%3Dhttp%3A%2F%2Fevil'); +}); +test("nested model/storage secrets cannot be returned to the native model", () => { + expect(sanitizeProjectToolOutput({ data:[{ id:'m',apiKey:'secret', provider:{ SK:'hidden',AK:'hidden',secretAccessKey:'hidden',baseUrl:'https://safe' } }], headers:{ authorization:'secret' } })).toEqual({data:[{id:'m',provider:{baseUrl:'https://safe'}}]}); +}); diff --git a/tests/routes/canvas-agent-runtime.test.ts b/tests/routes/canvas-agent-runtime.test.ts index 90ac6f1a5..db0ff6369 100644 --- a/tests/routes/canvas-agent-runtime.test.ts +++ b/tests/routes/canvas-agent-runtime.test.ts @@ -102,10 +102,10 @@ const plan = () => step([call("plan", "planCanvasTask")]); test("all image and video canvas Agent requests use native runtime; Claw and direct modes remain separate", () => { const body = { composerMode: "agent", contextPayload: { source: "canvas", projectId: "owned-project" } }; - for (const override of [{}, { agentPresetId: "preset" }, { workspaceVariant: "video" }, + for (const override of [{}, { agentPresetId: "preset" }, { message: { parts: [{ type: "text", text: "只分析不执行" }] } }, { resumeRunId: "run" }]) expect(shouldUseCanvasAgentRuntime({ ...body, ...override })).toBe(true); - for (const override of [{ composerMode: "clawd" }, { composerMode: "image" }, { composerMode: "video" }, + for (const override of [{ workspaceVariant: "video" }, { composerMode: "clawd" }, { composerMode: "image" }, { composerMode: "video" }, { contextPayload: { source: "canvas" } }, { contextPayload: { source: "chat", projectId: "p" } }]) expect(shouldUseCanvasAgentRuntime({ ...body, ...override })).toBe(false); });