feat(agent): Agent 工作台 - 计划插话记忆、统一模型选择器并修复摘要与视频入库

将计划清单、运行中插话和个人记忆接入云端 Agent;全站模型选择器统一为左右二级菜单。画布摘要按预算截断不再整轮拒绝,首页视频未知宽高可入库。README 补充贡献者 morrow。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
ddCatandCursor committed 2026-09-17 20:21:25 +08:00
1 parent b6bae4f957
commit 6892732b06
80 files changed
+7361 -179

No files matched your search

@@ -2,6 +2,7 @@ package app
import (
"encoding/json"
"fmt"
"reflect"
"strings"
"testing"
@@ -53,6 +54,44 @@ func TestCloudAgentMixedCanvasReadsUnsupportedNodesWithoutGrantingCapabilities(t
}
}
func TestCloudAgentCanvasSummaryTruncatesInsteadOfRejecting(t *testing.T) {
nodes := make([]map[string]any, 0, 50)
content := strings.Repeat("镜", 600)
for index := 0; index < 50; index++ {
nodes = append(nodes, map[string]any{
"id": fmt.Sprintf("node-%d", index),
"type": "text",
"title": fmt.Sprintf("镜头 %d %s", index, strings.Repeat("标题", 40)),
"metadata": map[string]any{
"content": content,
},
})
}
raw, err := json.Marshal(map[string]any{"nodes": nodes})
if err != nil {
t.Fatal(err)
}
summary, err := cloudAgentCanvasSummary(&model.CanvasProject{Title: "大画布", PayloadJSON: string(raw)})
if err != nil {
t.Fatalf("large canvas summary rejected: %v", err)
}
var parsed map[string]any
if err := json.Unmarshal([]byte(summary), &parsed); err != nil {
t.Fatal(err)
}
if parsed["totalNodes"] != float64(50) {
t.Fatalf("totalNodes=%v", parsed["totalNodes"])
}
included, _ := parsed["includedNodes"].(float64)
omitted, _ := parsed["omittedNodes"].(float64)
if included <= 0 || omitted <= 0 || int(included+omitted) != 50 {
t.Fatalf("expected truncation, included=%v omitted=%v", included, omitted)
}
if len(summary) > 64000+4096 {
t.Fatalf("truncated summary still huge: %d", len(summary))
}
}
func TestCloudAgentToolsFollowCanvasCapabilityRegistry(t *testing.T) {
req := agentTestRequest()
req.PermissionMode = "auto"