@dream-craft/canvas-agent 0.6.3 → 0.6.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/agent-instructions.md +2 -2
- package/dist/agent/codex-history.js +10 -1
- package/dist/canvas/schemas.d.ts +75 -2
- package/dist/canvas/schemas.js +15 -3
- package/dist/canvas/session.js +6 -1
- package/package.json +1 -1
package/agent-instructions.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
- 修改当前画布时根据任务使用已配置的 infinite-canvas MCP 工具;复杂批量改动使用 `canvas_apply_ops`。
|
|
8
8
|
- 用户要求把上传附件放入画布或作为生成参考图时,必须先用 `canvas_create_attachment_nodes` 创建真实图片节点,再把节点 ID 传给生成流程,不要创建空图片占位节点。
|
|
9
9
|
- 生图与视频工作台分别使用 `workbench_image_*`、`workbench_video_*` 工具;提示词和素材分别使用 `prompts_search`、`assets_*` 工具。
|
|
10
|
-
- 用户要求生成图片、视频、音频或文本时,默认调用对应的 `canvas_generate_image`、`canvas_generate_video`、`canvas_generate_audio`、`canvas_generate_text
|
|
10
|
+
- 用户要求生成图片、视频、音频或文本时,默认调用对应的 `canvas_generate_image`、`canvas_generate_video`、`canvas_generate_audio`、`canvas_generate_text`,通过当前画布的生成节点完成任务。**优先级(最高)例外**:开放式/高成本创作任务(如"生成一个某某主题的视频短片"、搭完整生成链、批量产出,特征是含多个未指定的自由决策点)必须先按 `task-briefing` 技能发对齐问卷并结束本轮,用户确认口径前禁止调用任何生成、建链或触发工具——本条与下一条的"直接调用生成工具"默认指令都让位于该技能。
|
|
11
11
|
- 只有用户明确要求使用“Codex 内置生图”“ImageGen 技能”或意思明确相同的能力时,才使用 Codex 自带的 `imagegen`;不要因为用户只说“生成图片”就自行改用内置生图。内置生图完成后,其结果会由 Canvas Agent 自动展示到对话并插入当前画布,无需再创建空节点或重复生成。
|
|
12
12
|
- 只有用户明确说要在生图/视频工作台生成时,才使用 `workbench_image_*`、`workbench_video_*`。生成任务提交后应说明已经在画布或工作台开始生成,不要在实际没有结果时声称“已生成”。
|
|
13
13
|
- 需要生成内容时直接调用对应生成工具,不要绑定特定业务场景,不要模拟鼠标点击,不要要求用户手动复制 JSON。
|
|
@@ -15,6 +15,6 @@
|
|
|
15
15
|
|
|
16
16
|
## Windows shell 与工具缺失行为
|
|
17
17
|
|
|
18
|
-
- 沙箱环境是 Windows PowerShell 5.1。shell 只用于三类用途:读取文件(`Get-Content`)、等待(`Start-Sleep`)、文件搜索(`Get-ChildItem` / `Select-String`)。不要使用 bash/Unix 语法(`ls -la`、`head`、`grep`、`/dev/null` 等);`
|
|
18
|
+
- 沙箱环境是 Windows PowerShell 5.1。shell 只用于三类用途:读取文件(`Get-Content`)、等待(`Start-Sleep`)、文件搜索(`Get-ChildItem` / `Select-String`)。不要使用 bash/Unix 语法(`ls -la`、`head`、`grep`、`/dev/null` 等);`python3`、`pwsh` 在本机不存在,python 在沙箱 shell 的 PATH 里调不到——不要用脚本语言生成 JSON 参数,直接把 JSON 写进工具参数。
|
|
19
19
|
- 当工具清单中没有 `canvas_*` 前缀工具(infinite-canvas MCP 未注册或未连接)时,立即向用户报告「画布工具不可用,请检查 Canvas Agent 连接」并停止执行任务;不要把工具名当命令执行,不要在文件系统里搜索画布状态或 MCP 配置。
|
|
20
20
|
- 同一 shell 命令因环境类错误(命令不存在、语法错误、权限拒绝)连续失败 2 次后,停止更换写法,向用户说明具体缺口;不要继续用其他脚本语言或管道方式重试。画布工具返回的业务错误(如「当前没有已连接画布」)按前文切换画布的规则处理,不属于此类。
|
|
@@ -526,7 +526,12 @@ function commandDetail(item) {
|
|
|
526
526
|
}
|
|
527
527
|
/** 生成 MCP 工具的用户可读详情。 */
|
|
528
528
|
function toolHistoryDetail(tool, item, input, error) {
|
|
529
|
-
|
|
529
|
+
const status = itemStatus(item, error);
|
|
530
|
+
// 问卷卡片:前端按 detail.kind === "survey" 渲染可交互表单。历史快照在轮次结束后会成为权威消息,
|
|
531
|
+
// 因此这一支必须原样透传入参——否则历史同步会把已渲染的问卷卡片替换成一行普通工具卡。
|
|
532
|
+
if (tool === "canvas_present_survey" && status === "completed" && !error)
|
|
533
|
+
return { kind: "survey", status, survey: input };
|
|
534
|
+
return { kind: "tool", status, rows: toolInputRows(tool, input), ...(error ? { output: error } : {}) };
|
|
530
535
|
}
|
|
531
536
|
function itemErrorMessage(item) {
|
|
532
537
|
return String(field(field(item, "error"), "message") || "");
|
|
@@ -558,6 +563,8 @@ function toolHistorySummary(tool, item, input) {
|
|
|
558
563
|
}
|
|
559
564
|
if (tool === "canvas_get_selection")
|
|
560
565
|
return "已读取当前选中内容";
|
|
566
|
+
if (tool === "canvas_present_survey")
|
|
567
|
+
return "已呈现对齐问卷";
|
|
561
568
|
if (tool === "prompts_search")
|
|
562
569
|
return `找到 ${numberValue(field(result, "total"))} 条提示词`;
|
|
563
570
|
if (tool === "assets_list")
|
|
@@ -760,6 +767,8 @@ function toolName(name) {
|
|
|
760
767
|
return "读取画布";
|
|
761
768
|
if (name === "canvas_get_selection")
|
|
762
769
|
return "读取选区";
|
|
770
|
+
if (name === "canvas_present_survey")
|
|
771
|
+
return "发起对齐问卷";
|
|
763
772
|
if (name === "canvas_export_snapshot")
|
|
764
773
|
return "导出快照";
|
|
765
774
|
if (name === "canvas_create_node")
|
package/dist/canvas/schemas.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
/** Canvas Agent 对外提供的工具名称。 */
|
|
3
|
-
export declare const toolNames: readonly ["site_navigate", "canvas_list_projects", "canvas_get_state", "canvas_get_selection", "canvas_export_snapshot", "canvas_apply_ops", "canvas_create_node", "canvas_create_attachment_nodes", "canvas_create_text_node", "canvas_create_text_nodes", "canvas_create_config_node", "canvas_create_image_prompt_flow", "canvas_create_generation_flow", "canvas_generate_text", "canvas_generate_image", "canvas_generate_video", "canvas_generate_audio", "canvas_update_node", "canvas_update_node_text", "canvas_move_nodes", "canvas_resize_node", "canvas_delete_nodes", "canvas_connect_nodes", "canvas_select_nodes", "
|
|
3
|
+
export declare const toolNames: readonly ["site_navigate", "canvas_list_projects", "canvas_get_state", "canvas_get_selection", "canvas_export_snapshot", "canvas_apply_ops", "canvas_create_node", "canvas_create_attachment_nodes", "canvas_create_text_node", "canvas_create_text_nodes", "canvas_create_config_node", "canvas_create_image_prompt_flow", "canvas_create_generation_flow", "canvas_generate_text", "canvas_generate_image", "canvas_generate_video", "canvas_generate_audio", "canvas_update_node", "canvas_update_node_text", "canvas_move_nodes", "canvas_resize_node", "canvas_delete_nodes", "canvas_connect_nodes", "canvas_set_viewport", "canvas_select_nodes", "canvas_present_survey", "canvas_run_generation", "generation_get_status", "workbench_image_get_config", "workbench_image_generate", "workbench_video_get_config", "workbench_video_generate", "prompts_search", "assets_list", "assets_add"];
|
|
4
4
|
export type ToolName = (typeof toolNames)[number];
|
|
5
5
|
export declare const canvasOpSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
|
|
6
6
|
type: z.ZodLiteral<"add_node">;
|
|
@@ -234,7 +234,13 @@ export declare const toolInputSchemas: {
|
|
|
234
234
|
page?: number | undefined;
|
|
235
235
|
pageSize?: number | undefined;
|
|
236
236
|
}>;
|
|
237
|
-
canvas_get_state: z.ZodObject<{
|
|
237
|
+
canvas_get_state: z.ZodObject<{
|
|
238
|
+
full: z.ZodOptional<z.ZodBoolean>;
|
|
239
|
+
}, "passthrough", z.ZodTypeAny, z.objectOutputType<{
|
|
240
|
+
full: z.ZodOptional<z.ZodBoolean>;
|
|
241
|
+
}, z.ZodTypeAny, "passthrough">, z.objectInputType<{
|
|
242
|
+
full: z.ZodOptional<z.ZodBoolean>;
|
|
243
|
+
}, z.ZodTypeAny, "passthrough">>;
|
|
238
244
|
canvas_get_selection: z.ZodObject<{}, "passthrough", z.ZodTypeAny, z.objectOutputType<{}, z.ZodTypeAny, "passthrough">, z.objectInputType<{}, z.ZodTypeAny, "passthrough">>;
|
|
239
245
|
canvas_export_snapshot: z.ZodObject<{}, "passthrough", z.ZodTypeAny, z.objectOutputType<{}, z.ZodTypeAny, "passthrough">, z.objectInputType<{}, z.ZodTypeAny, "passthrough">>;
|
|
240
246
|
canvas_apply_ops: z.ZodObject<{
|
|
@@ -792,6 +798,73 @@ export declare const toolInputSchemas: {
|
|
|
792
798
|
}, {
|
|
793
799
|
ids: string[];
|
|
794
800
|
}>;
|
|
801
|
+
canvas_present_survey: z.ZodObject<{
|
|
802
|
+
title: z.ZodOptional<z.ZodString>;
|
|
803
|
+
contextText: z.ZodOptional<z.ZodString>;
|
|
804
|
+
groups: z.ZodType<{
|
|
805
|
+
title: string;
|
|
806
|
+
options: {
|
|
807
|
+
label: string;
|
|
808
|
+
description?: string | undefined;
|
|
809
|
+
recommended?: boolean | undefined;
|
|
810
|
+
}[];
|
|
811
|
+
mode?: "single" | "multi" | undefined;
|
|
812
|
+
allowCustom?: boolean | undefined;
|
|
813
|
+
}[], z.ZodTypeDef, {
|
|
814
|
+
title: string;
|
|
815
|
+
options: {
|
|
816
|
+
label: string;
|
|
817
|
+
description?: string | undefined;
|
|
818
|
+
recommended?: boolean | undefined;
|
|
819
|
+
}[];
|
|
820
|
+
mode?: "single" | "multi" | undefined;
|
|
821
|
+
allowCustom?: boolean | undefined;
|
|
822
|
+
}[]>;
|
|
823
|
+
}, "passthrough", z.ZodTypeAny, z.objectOutputType<{
|
|
824
|
+
title: z.ZodOptional<z.ZodString>;
|
|
825
|
+
contextText: z.ZodOptional<z.ZodString>;
|
|
826
|
+
groups: z.ZodType<{
|
|
827
|
+
title: string;
|
|
828
|
+
options: {
|
|
829
|
+
label: string;
|
|
830
|
+
description?: string | undefined;
|
|
831
|
+
recommended?: boolean | undefined;
|
|
832
|
+
}[];
|
|
833
|
+
mode?: "single" | "multi" | undefined;
|
|
834
|
+
allowCustom?: boolean | undefined;
|
|
835
|
+
}[], z.ZodTypeDef, {
|
|
836
|
+
title: string;
|
|
837
|
+
options: {
|
|
838
|
+
label: string;
|
|
839
|
+
description?: string | undefined;
|
|
840
|
+
recommended?: boolean | undefined;
|
|
841
|
+
}[];
|
|
842
|
+
mode?: "single" | "multi" | undefined;
|
|
843
|
+
allowCustom?: boolean | undefined;
|
|
844
|
+
}[]>;
|
|
845
|
+
}, z.ZodTypeAny, "passthrough">, z.objectInputType<{
|
|
846
|
+
title: z.ZodOptional<z.ZodString>;
|
|
847
|
+
contextText: z.ZodOptional<z.ZodString>;
|
|
848
|
+
groups: z.ZodType<{
|
|
849
|
+
title: string;
|
|
850
|
+
options: {
|
|
851
|
+
label: string;
|
|
852
|
+
description?: string | undefined;
|
|
853
|
+
recommended?: boolean | undefined;
|
|
854
|
+
}[];
|
|
855
|
+
mode?: "single" | "multi" | undefined;
|
|
856
|
+
allowCustom?: boolean | undefined;
|
|
857
|
+
}[], z.ZodTypeDef, {
|
|
858
|
+
title: string;
|
|
859
|
+
options: {
|
|
860
|
+
label: string;
|
|
861
|
+
description?: string | undefined;
|
|
862
|
+
recommended?: boolean | undefined;
|
|
863
|
+
}[];
|
|
864
|
+
mode?: "single" | "multi" | undefined;
|
|
865
|
+
allowCustom?: boolean | undefined;
|
|
866
|
+
}[]>;
|
|
867
|
+
}, z.ZodTypeAny, "passthrough">>;
|
|
795
868
|
canvas_set_viewport: z.ZodObject<{
|
|
796
869
|
viewport: z.ZodObject<{
|
|
797
870
|
x: z.ZodNumber;
|
package/dist/canvas/schemas.js
CHANGED
|
@@ -46,8 +46,9 @@ export const toolNames = [
|
|
|
46
46
|
"canvas_resize_node",
|
|
47
47
|
"canvas_delete_nodes",
|
|
48
48
|
"canvas_connect_nodes",
|
|
49
|
-
"canvas_select_nodes",
|
|
50
49
|
"canvas_set_viewport",
|
|
50
|
+
"canvas_select_nodes",
|
|
51
|
+
"canvas_present_survey",
|
|
51
52
|
"canvas_run_generation",
|
|
52
53
|
"generation_get_status",
|
|
53
54
|
"workbench_image_get_config",
|
|
@@ -110,7 +111,7 @@ const generationFlowSchema = z.object({
|
|
|
110
111
|
export const toolInputSchemas = {
|
|
111
112
|
site_navigate: z.object({ path: z.string() }),
|
|
112
113
|
canvas_list_projects: z.object({ keyword: z.string().optional(), page: z.number().optional(), pageSize: z.number().optional() }),
|
|
113
|
-
canvas_get_state: z.object({}).passthrough(),
|
|
114
|
+
canvas_get_state: z.object({ full: z.boolean().optional() }).passthrough(),
|
|
114
115
|
canvas_get_selection: z.object({}).passthrough(),
|
|
115
116
|
canvas_export_snapshot: z.object({}).passthrough(),
|
|
116
117
|
canvas_apply_ops: z.object({ ops: jsonArraySchema(canvasOpSchema) }),
|
|
@@ -132,6 +133,16 @@ export const toolInputSchemas = {
|
|
|
132
133
|
canvas_delete_nodes: z.object({ ids: jsonArraySchema(z.string(), 1) }),
|
|
133
134
|
canvas_connect_nodes: z.object({ connections: jsonArraySchema(z.object({ fromNodeId: z.string(), toNodeId: z.string() }), 1) }),
|
|
134
135
|
canvas_select_nodes: z.object({ ids: jsonArraySchema(z.string()) }),
|
|
136
|
+
canvas_present_survey: z.object({
|
|
137
|
+
title: z.string().optional(),
|
|
138
|
+
contextText: z.string().optional(),
|
|
139
|
+
groups: jsonArraySchema(z.object({
|
|
140
|
+
title: z.string(),
|
|
141
|
+
mode: z.enum(["single", "multi"]).optional(),
|
|
142
|
+
options: jsonArraySchema(z.object({ label: z.string(), description: z.string().optional(), recommended: z.boolean().optional() }), 1),
|
|
143
|
+
allowCustom: z.boolean().optional(),
|
|
144
|
+
}), 1),
|
|
145
|
+
}).passthrough(),
|
|
135
146
|
canvas_set_viewport: z.object({ viewport: viewportSchema }),
|
|
136
147
|
canvas_run_generation: z.object({ nodeId: z.string(), mode: generationModeSchema.optional(), prompt: z.string().optional() }),
|
|
137
148
|
generation_get_status: z.object({ scope: z.enum(["all", "canvas", "image", "video"]).optional(), taskId: z.string().optional(), nodeIds: jsonArraySchema(z.string()).optional(), limit: z.number().optional() }),
|
|
@@ -146,7 +157,7 @@ export const toolInputSchemas = {
|
|
|
146
157
|
export const toolDescriptions = {
|
|
147
158
|
site_navigate: "跳转网站页面。path 可为 / (首页)、/canvas (我的画布)、/canvas/:id (指定画布)、/image (生图工作台)、/video (视频创作台)、/prompts (提示词库)、/assets (我的素材)、/config (配置)。操作画布前若不在画布页,先用本工具打开画布。",
|
|
148
159
|
canvas_list_projects: "列出用户全部画布(仅标题、创建/更新时间、节点数、连线数,不含完整数据),支持 keyword 搜索和 page/pageSize 分页。返回的 id 可配合 site_navigate 跳转到 /canvas/:id 打开对应画布。",
|
|
149
|
-
canvas_get_state: "
|
|
160
|
+
canvas_get_state: "读取当前网页画布的节点、连线、选区和视口。默认节点 metadata.content 超过 240 字符会被截断;full: true 返回未截断内容,做提示词/种子与生成参数(如画幅比例)的一致性分析时必须带 full: true,避免漏看长文本里的画幅假设。",
|
|
150
161
|
canvas_get_selection: "读取当前网页画布选中的节点。",
|
|
151
162
|
canvas_export_snapshot: "导出当前画布快照,用于理解布局。",
|
|
152
163
|
canvas_apply_ops: "批量操作当前网页画布。ops 支持 add_node(nodeType 可为内置类型或已启用插件的 \"<pluginId>:<name>\" 类型)、update_node、delete_node、delete_connections、connect_nodes、set_viewport、select_nodes、arrange_nodes、run_generation。ops 最小示例:[{\"type\":\"add_node\",\"id\":\"main\",\"nodeType\":\"text\",\"title\":\"主提示词\",\"metadata\":{\"content\":\"提示词内容\"}}],连接节点用 {\"type\":\"connect_nodes\",\"fromNodeId\":\"main\",\"toNodeId\":\"target\"},connect_nodes 必须同时提供 fromNodeId 与 toNodeId。arrange_nodes 只带意图(ids 或 all 二选一 + mode/axis/side),坐标由网页端排版算法计算并在整理后聚焦结果,不要自己算坐标或预判结果。mode=auto/flow/by_media/row/column/grid/spread 为防重叠整理,结果不重叠;mode=align/distribute 是对齐/等距工具,按定义会让节点在一条线上重叠或贴合,这是预期行为,不要据此判定整理失败。",
|
|
@@ -168,6 +179,7 @@ export const toolDescriptions = {
|
|
|
168
179
|
canvas_delete_nodes: "删除指定节点及相关连线。",
|
|
169
180
|
canvas_connect_nodes: "批量连接节点。",
|
|
170
181
|
canvas_select_nodes: "设置当前选中节点。",
|
|
182
|
+
canvas_present_survey: "向用户呈现一张可交互的对齐问卷卡片(分组单选/多选 + 自定义输入),用于开放式创作任务动手前确认需求口径。调用后立即返回,本轮结束等待用户在卡片中提交选择;不要在无用户回复时继续执行任务,也不要用纯文本列表代替本工具。groups 每组含 title、mode(single 默认/multi)、options(label/description/recommended 标注推荐项)、allowCustom(是否允许自定义输入);title/contextText 为卡片标题与现状说明。",
|
|
171
183
|
canvas_set_viewport: "调整画布视口。",
|
|
172
184
|
canvas_run_generation: "触发指定节点生成,通常用于配置节点或文本/图片/视频/音频节点。",
|
|
173
185
|
generation_get_status: "查询当前活动网页的生成任务状态。默认返回画布、生图工作台和视频工作台最近任务;可用 scope 过滤来源,用 taskId 查询工作台任务,用 nodeIds 查询画布节点。",
|
package/dist/canvas/session.js
CHANGED
|
@@ -415,6 +415,9 @@ export class CanvasSession {
|
|
|
415
415
|
throw new Error(`未知工具:${String(name)}`);
|
|
416
416
|
logger.info("MCP tool called", { name, input: rawInput, targetClientId: this.targetClientId });
|
|
417
417
|
const input = parseToolInput(name, rawInput);
|
|
418
|
+
// 问卷呈现是 agent 本地动作:不依赖画布连接,返回即结束本轮等用户在卡片中提交。
|
|
419
|
+
if (name === "canvas_present_survey")
|
|
420
|
+
return { presented: true };
|
|
418
421
|
if (SITE_TOOLS.has(name)) {
|
|
419
422
|
if (!this.clients.size)
|
|
420
423
|
throw new Error("当前没有已连接网页");
|
|
@@ -423,7 +426,9 @@ export class CanvasSession {
|
|
|
423
426
|
const readTool = ["canvas_get_state", "canvas_get_selection", "canvas_export_snapshot"].includes(name);
|
|
424
427
|
if (readTool && (!this.clients.size || !this.canvasState))
|
|
425
428
|
throw new Error("当前没有已连接画布");
|
|
426
|
-
if (name === "canvas_get_state"
|
|
429
|
+
if (name === "canvas_get_state")
|
|
430
|
+
return input.full === true ? this.canvasState : compactCanvasState(this.canvasState);
|
|
431
|
+
if (name === "canvas_export_snapshot")
|
|
427
432
|
return compactCanvasState(this.canvasState);
|
|
428
433
|
if (name === "canvas_get_selection") {
|
|
429
434
|
const ids = new Set(this.canvasState?.selectedNodeIds || []);
|