feat(cli): 终端支持动态阶段状态流式输出与低认知负荷摘要呈现

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
WeiCHEN
2026-09-13 02:50:19 +00:00
committed by weichen
co-authored by Cursor
parent 810eb26be3
commit 75494cbd75
+79 -3
View File
@@ -16,6 +16,7 @@ import (
"chat-agent-system/internal/coordinator"
"chat-agent-system/internal/intent"
"chat-agent-system/internal/squad"
"chat-agent-system/internal/stream"
)
func main() {
@@ -42,6 +43,8 @@ func main() {
workDirFlag := flag.String("work-dir", "", "关联现有工作区目录 (如 sandbox/intake_xxx)")
userName := flag.String("user", "张工", "用户姓名")
userRole := flag.String("role", "engineer", "用户角色")
streamMode := flag.Bool("stream", true, "启用实时流式阶段状态指示 (默认开启)")
verboseMode := flag.Bool("verbose", false, "展开打印底层专员详细推演草稿与思考链 (默认隐藏)")
flag.Parse()
cfg, err := config.Load(*envPath)
@@ -99,6 +102,8 @@ func main() {
*market,
*userName,
*userRole,
*streamMode,
*verboseMode,
)
return
}
@@ -343,6 +348,64 @@ func handleInspect(ctx context.Context, svc bizdev.BizdevService, workDir string
}
}
func createCLIStreamListener(verbose bool) stream.Listener {
return func(ev stream.StreamEvent) {
switch ev.Type {
case stream.EventPhase:
if ev.Phase != nil {
icon := "⏳"
switch ev.Phase.PhaseID {
case "squad_assembly":
icon = "👥"
case "knowledge_retrieval", "knowledge_retrieved":
icon = "📚"
case "step_executing":
icon = "⚙️ "
case "step_completed":
icon = "✅"
case "quality_gate":
icon = "🛡️ "
case "advisor_briefing":
icon = "💡"
case "stage_transition", "stage_started":
icon = "🚀"
case "stage_completed":
icon = "🎉"
}
fmt.Printf("%s [%s] %s\n", icon, ev.Phase.PhaseID, ev.Phase.Message)
}
case stream.EventStatus:
if ev.Status != nil && ev.Status.Message != "" {
fmt.Printf("🎯 [意图状态] %s\n", ev.Status.Message)
}
case stream.EventSummary:
if ev.Summary != nil {
fmt.Println("\n------------------------------------------------------------------")
fmt.Println("📌【核心进展与诊断摘要】")
fmt.Printf("标 题: %s\n", ev.Summary.Title)
fmt.Printf("诊 断: %s\n", ev.Summary.Content)
if ev.Summary.MaturityScore > 0 {
fmt.Printf("成熟度: %s (%d / 100)\n", ev.Summary.MaturityLevel, ev.Summary.MaturityScore)
}
fmt.Println("------------------------------------------------------------------")
}
case stream.EventDeliverable:
if ev.Deliverable != nil {
fmt.Printf("📄【A轨合规文档生成】%s (评分: %.1f) -> %s\n", ev.Deliverable.Title, ev.Deliverable.QualityScore, ev.Deliverable.FilePath)
if !verbose {
fmt.Println("💡 [提示: 底层专员思考过程与推演草稿已在沙箱归档,可使用 --verbose 参数在控制台展开查看]")
}
}
case stream.EventDetail:
if verbose && ev.Detail != nil {
fmt.Printf("\n--- 🔍 [底层推演详情: %s - %s] ---\n%s\n------------------------------------------------------------------\n", ev.Detail.Role, ev.Detail.Title, ev.Detail.Content)
}
case stream.EventError:
fmt.Printf("⚠️ [执行告警] %s\n", ev.Error)
}
}
}
func handleChatMode(
ctx context.Context,
svc bizdev.BizdevService,
@@ -355,6 +418,8 @@ func handleChatMode(
market string,
userName string,
userRole string,
streamMode bool,
verboseMode bool,
) {
u := coordinator.UserInfo{
ID: "u_local",
@@ -405,13 +470,18 @@ func handleChatMode(
// 单次提问模式 (支持脚本与自动化测试)
if chatQuery != "" {
resp, err := session.SendMessage(ctx, chatQuery)
var resp *chat.ChatResponse
if streamMode {
resp, err = session.SendMessageStream(ctx, chatQuery, createCLIStreamListener(verboseMode), verboseMode)
} else {
resp, err = session.SendMessage(ctx, chatQuery)
}
if err != nil {
fmt.Fprintf(os.Stderr, "对话处理失败: %v\n", err)
os.Exit(1)
}
top := resp.IntentResult.TopIntent
fmt.Printf("[意图识别: %s (置信度: %.0f%%) | 消解分支: %s] - %s\n", top.Intent, top.Confidence*100, resp.Branch, top.Reasoning)
fmt.Printf("\n[意图识别: %s (置信度: %.0f%%) | 消解分支: %s] - %s\n", top.Intent, top.Confidence*100, resp.Branch, top.Reasoning)
fmt.Printf("\n%s\n", resp.ReplyText)
if resp.AdvisorBrief != nil && (top.Intent == intent.IntentAdvanceStage || top.Intent == intent.IntentQueryProgress) {
printAdvisorBrief(resp.AdvisorBrief)
@@ -426,6 +496,7 @@ func handleChatMode(
fmt.Printf("项目名称: %s | 客户单位: %s\n", userCtx.Project.Name, userCtx.Project.CustomerName)
fmt.Printf("当前阶段: %s | 用户身份: %s (%s)\n", userCtx.Project.CurrentStage, userCtx.User.Name, userCtx.User.Role)
fmt.Printf("可用动作: %v\n", userCtx.AvailableActions)
fmt.Printf("流式反馈: %v | 详细推演模式: %v\n", streamMode, verboseMode)
fmt.Println("------------------------------------------------------------------")
fmt.Println("💡 参谋互动小贴士(三分支柔性消解):")
fmt.Println(" • 极速兑现(分支 1):当参谋给出下一步建议时,回复“好”、“行”或“1”直接推进")
@@ -451,7 +522,12 @@ func handleChatMode(
break
}
resp, err := session.SendMessage(ctx, input)
var resp *chat.ChatResponse
if streamMode {
resp, err = session.SendMessageStream(ctx, input, createCLIStreamListener(verboseMode), verboseMode)
} else {
resp, err = session.SendMessage(ctx, input)
}
if err != nil {
fmt.Fprintf(os.Stderr, "处理异常: %v\n", err)
continue