feat(*): 云端 Agent - 增强画布上下文读取并接入 Gemini 缓存
This commit is contained in:
1 parent
2ce50bbb9d
commit
2cedc4c66b
35 files changed
+1927
-266
No files matched your search
@@ -95,6 +95,40 @@ func TestCloudAgentCanvasSummaryIsACatalogNotNodeBodies(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestCloudAgentCanvasSummaryUsesSelectedNodeNeighborhood(t *testing.T) {
|
||||
doc := map[string]any{
|
||||
"nodes": []map[string]any{
|
||||
{"id": "focus", "type": "text", "title": "主体"},
|
||||
{"id": "neighbor", "type": "image", "title": "关联素材"},
|
||||
{"id": "unrelated", "type": "text", "title": "无关内容"},
|
||||
},
|
||||
"connections": []map[string]any{{"fromNodeId": "focus", "toNodeId": "neighbor"}},
|
||||
}
|
||||
raw, err := json.Marshal(doc)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
summary, err := cloudAgentCanvasSummary(&model.CanvasProject{PayloadJSON: string(raw)}, "focus")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var result map[string]any
|
||||
if err := json.Unmarshal([]byte(summary), &result); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
encoded, _ := json.Marshal(result["nodes"])
|
||||
if strings.Contains(string(encoded), "unrelated") || !strings.Contains(string(encoded), "focus") || !strings.Contains(string(encoded), "neighbor") {
|
||||
t.Fatalf("focused catalog did not include exactly the local graph neighborhood: %s", encoded)
|
||||
}
|
||||
selection := result["selection"].(map[string]any)
|
||||
if selection["includedNeighbors"] != float64(1) || selection["nextReadDepth"] != float64(1) {
|
||||
t.Fatalf("focused catalog metadata is incorrect: %+v", selection)
|
||||
}
|
||||
if _, err := cloudAgentCanvasSummary(&model.CanvasProject{PayloadJSON: string(raw)}, "deleted"); err == nil {
|
||||
t.Fatal("stale selected node was accepted")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCloudAgentToolsFollowCanvasCapabilityRegistry(t *testing.T) {
|
||||
req := agentTestRequest()
|
||||
req.PermissionMode = "auto"
|
||||
@@ -369,3 +403,60 @@ func TestCloudAgentDurablePolicySnapshotRejectsMissingOrUnsupportedContracts(t *
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestCloudAgentCanvasStateIncludesBoundedRelatedComponent(t *testing.T) {
|
||||
doc := map[string]any{
|
||||
"nodes": []map[string]any{
|
||||
{"id": "upstream", "type": "text", "title": "上游"},
|
||||
{"id": "focus", "type": "text", "title": "焦点"},
|
||||
{"id": "downstream", "type": "text", "title": "下游"},
|
||||
{"id": "unrelated", "type": "text", "title": "无关"},
|
||||
},
|
||||
"connections": []map[string]any{
|
||||
{"id": "e1", "fromNodeId": "upstream", "toNodeId": "focus"},
|
||||
{"id": "e2", "fromNodeId": "focus", "toNodeId": "downstream"},
|
||||
},
|
||||
}
|
||||
view, err := cloudAgentCanvasStateWithRelated(nil, "user", "canvas", doc, 0, []string{"focus"}, 0)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
result := view.(map[string]any)
|
||||
selection := result["selection"].(map[string]any)
|
||||
if selection["relationMode"] != "all" || selection["truncated"] != false || selection["selectedNodes"] != 3.0 && selection["selectedNodes"] != 3 {
|
||||
t.Fatalf("unexpected related selection: %#v", selection)
|
||||
}
|
||||
ids := map[string]bool{}
|
||||
for _, raw := range result["nodes"].([]any) {
|
||||
ids[raw.(map[string]any)["id"].(string)] = true
|
||||
}
|
||||
if ids["focus"] == false || ids["upstream"] == false || ids["downstream"] == false || ids["unrelated"] {
|
||||
t.Fatalf("related component selected wrong nodes: %#v", ids)
|
||||
}
|
||||
if len(result["connections"].([]any)) != 2 {
|
||||
t.Fatalf("related component lost edges: %#v", result["connections"])
|
||||
}
|
||||
}
|
||||
|
||||
func TestCloudAgentCanvasStateRelatedComponentIsBounded(t *testing.T) {
|
||||
nodes := make([]map[string]any, 0, cloudAgentRelatedNodeLimit+32)
|
||||
edges := make([]map[string]any, 0, cloudAgentRelatedNodeLimit+32)
|
||||
nodes = append(nodes, map[string]any{"id": "focus", "type": "text", "title": "焦点"})
|
||||
for index := 0; index < cloudAgentRelatedNodeLimit+32; index++ {
|
||||
id := fmt.Sprintf("child-%d", index)
|
||||
nodes = append(nodes, map[string]any{"id": id, "type": "text", "title": id})
|
||||
edges = append(edges, map[string]any{"id": fmt.Sprintf("edge-%d", index), "fromNodeId": "focus", "toNodeId": id})
|
||||
}
|
||||
view, err := cloudAgentCanvasStateWithRelated(nil, "user", "canvas", map[string]any{"nodes": nodes, "connections": edges}, 0, []string{"focus"}, 0)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
result := view.(map[string]any)
|
||||
selection := result["selection"].(map[string]any)
|
||||
if selection["truncated"] != true || selection["selectedNodes"] != float64(cloudAgentRelatedNodeLimit) && selection["selectedNodes"] != cloudAgentRelatedNodeLimit {
|
||||
t.Fatalf("related component should be truncated at %d: %#v", cloudAgentRelatedNodeLimit, selection)
|
||||
}
|
||||
if len(result["nodes"].([]any)) != cloudAgentRelatedNodeLimit {
|
||||
t.Fatalf("related component returned too many nodes: %d", len(result["nodes"].([]any)))
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user