云端 Agent 此前只能新建节点与连线,既不会排版也不能移动已有节点:模型只能用几十个
update_node 手算坐标,或者让用户自己拖。
- 新增 backend/internal/canvas/layout:把前端既有的画布布局算法(web/src/lib/canvas/
canvas-layout.ts,本 PR 不改该文件)按同一套常量移植到服务端,提供 Kahn 拓扑分层 flow、
媒体泳道 byType、row/column/grid、对齐与等距、分组分带、AABB 重叠检测与空位搜索。
- 新增写工具 canvas_arrange_nodes:snapshotHash 必需,mode∈{auto,flow,byType,row,column,
grid},可传 nodeIds、groups(只做横向位置分带,不建容器、不改层级)、align、gap、dryRun。
只改坐标,不改内容、不建连线、不增删节点;一次最多 50 个节点 / 12 组。锁定节点、背板等
容器、隐藏批次子节点与已归属背板的子节点保持不动并在回执里说明;整批复用现有 mutation
记录与事件管线,审批与撤销走同一条路径。
- add_node 省略坐标时不再落到 (0,0):优先贴合本批连线的对端(输入在左、输出在右),否则
追加到同泳道同类节点之后,冲突则扫描空位;只给一个轴时保留该轴。agentCanvasOp.X/Y 改为
指针以区分"没给坐标"与"坐标 0"。
- update_node 的 patch 新增 x/y(PatchField.Limit 校验 ±1e6),供模型微调单个节点。
- 系统行为策略新增「布局与整理」一节并升版到 8;docs 补工具说明与工具全集;前端同步审批
预览联合类型、面板文案与徽标。
- 工具 schema 预算按实测从 24000 上调到 25000(21 个工具 24788 字节),并改正注释里
"上游约 23.4 KB"的说法(上游 20 个工具实测 22777 字节)。
41 lines
1.3 KiB
Go
41 lines
1.3 KiB
Go
package prompts
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestLoadAgentPoliciesUsesDocumentMetadata(t *testing.T) {
|
|
system, media, err := LoadAgentPolicies()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if system.ID != "cloud-agent-system" || system.Version != 8 || media.ID != "cloud-agent-media" || media.Version != 3 {
|
|
t.Fatalf("unexpected policy metadata: system=%+v media=%+v", system, media)
|
|
}
|
|
if strings.Contains(system.Text, "id: cloud-agent-system") || !strings.HasPrefix(system.Text, "# 影策 Cloud Agent") {
|
|
t.Fatalf("metadata leaked into compiled policy body: %q", system.Text)
|
|
}
|
|
}
|
|
|
|
func TestParsePolicyDocumentRejectsInvalidMetadata(t *testing.T) {
|
|
for _, test := range []struct {
|
|
name string
|
|
raw string
|
|
}{
|
|
{"missing header", "# policy"},
|
|
{"unclosed header", "---\nid: policy\nversion: 1\n# body"},
|
|
{"missing id", "---\nversion: 1\n---\n# body"},
|
|
{"invalid version", "---\nid: policy\nversion: latest\n---\n# body"},
|
|
{"duplicate field", "---\nid: policy\nid: other\nversion: 1\n---\n# body"},
|
|
{"unknown field", "---\nid: policy\nversion: 1\nowner: app\n---\n# body"},
|
|
{"empty body", "---\nid: policy\nversion: 1\n---"},
|
|
} {
|
|
t.Run(test.name, func(t *testing.T) {
|
|
if _, _, _, err := parsePolicyDocument(test.raw); err == nil {
|
|
t.Fatal("invalid policy document was accepted")
|
|
}
|
|
})
|
|
}
|
|
}
|