feat(cli): 终端支持动态阶段状态流式输出与低认知负荷摘要呈现
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
committed by
weichen
co-authored by
Cursor
parent
810eb26be3
commit
75494cbd75
+79
-3
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user