Version: 0.9.18.dev.260415

后端:
1. ChatNode 路由从 GenerateJSON 重构为流式控制码路由
- 新建 backend/newAgent/router/chat_route.go:流式增量控制码解析器 StreamRouteParser,复用 agent 的 <SMARTFLOW_ROUTE> 正则模式
- 更新 backend/newAgent/node/chat.go:RunChatNode 从 GenerateJSON(阻塞等完整 JSON)改为 Stream + 控制码解析 + 分支流式处理
- streamAndDispatch 核心循环:逐 chunk 喂解析器,控制码解析后按 route 分发
- handleDirectReplyStream:thinking=false 同一流续传,thinking=true 关流后二次 thinking 调用
- handleDeepAnswerStream:移除"让我想想"过渡语,直接关流后发起第二次流式调用(thinking 由 effectiveThinking 控制)
- handleRouteExecuteStream / handleRoutePlanStream:关流 → 推送 status → 设 Phase
- 更新 backend/newAgent/prompt/chat.go:路由 prompt 从 JSON 格式改为控制码标签格式
- 更新 backend/newAgent/model/chat_contract.go:ChatRoutingDecision 新增 Thinking / Raw 字段,移除 Speak / Reason
2. Thinking 参数从 bool 扩展为 string 三态
- 更新 backend/model/agent.go:UserSendMessageRequest.Thinking 从 bool 改为 string
- 更新 backend/service/agentsvc/agent.go:AgentChat / runNormalChatFlow 适配 string 类型,新增 thinkingModeToBool 兼容旧链路
- 更新 backend/service/agentsvc/agent_newagent.go:runNewAgentGraph 接收 thinkingMode string 并注入 CommonState
3. CommonState 新增 ThinkingMode / ExecuteThinking 字段
- 更新 backend/newAgent/model/common_state.go:ThinkingMode 控制下游 thinking 行为("true" 强开 / "false" 强关 / "auto"交路由决策)
- ChatNode 通过 resolveEffectiveThinking 合并前端偏好与路由决策,传递给所有下游处理函数
4. 新增真流式推送方法
- 更新 backend/newAgent/stream/emitter.go:新增 EmitStreamAssistantText / EmitStreamReasoningText,桥接 StreamReader → SSE chunk
前端:无
仓库:无
This commit is contained in:
LoveLosita
2026-04-15 11:04:27 +08:00
parent b72e202822
commit 21eed5af75
9 changed files with 658 additions and 234 deletions

View File

@@ -26,18 +26,19 @@ const (
//
// 职责边界:
// 1. Route 决定后续处理路径;
// 2. Speak 始终填写:给用户看的话
// 3. NeedsRoughBuild 仅在 route=execute 且满足粗排条件时为 true
// 4. NeedsRefineAfterRoughBuild 仅在 needs_rough_build=true 时有效
// 5. AllowReorder 表示是否允许打乱 suggested 任务顺序,仅用户明确授权时应为 true
// 6. Reason 给后端和日志看。
// 2. NeedsRoughBuild 仅在 route=execute 且满足粗排条件时为 true
// 3. NeedsRefineAfterRoughBuild 仅在 needs_rough_build=true 时有效
// 4. AllowReorder 表示是否允许打乱 suggested 任务顺序,仅用户明确授权时应为 true
// 5. Thinking 表示下游 Execute 节点是否应开启深度思考
// 6. Raw 保留控制码原文,供日志排查;
// 7. 用户可见内容speak由流式输出自然产出不由本结构承载。
type ChatRoutingDecision struct {
Route ChatRoute `json:"route"`
Speak string `json:"speak,omitempty"`
NeedsRoughBuild bool `json:"needs_rough_build,omitempty"`
NeedsRefineAfterRoughBuild bool `json:"needs_refine_after_rough_build,omitempty"`
AllowReorder bool `json:"allow_reorder,omitempty"`
Reason string `json:"reason,omitempty"`
Route ChatRoute
NeedsRoughBuild bool
NeedsRefineAfterRoughBuild bool
AllowReorder bool
Thinking bool
Raw string
}
// Normalize 统一清洗路由决策中的字符串字段。
@@ -46,8 +47,7 @@ func (d *ChatRoutingDecision) Normalize() {
return
}
d.Route = ChatRoute(strings.TrimSpace(string(d.Route)))
d.Speak = strings.TrimSpace(d.Speak)
d.Reason = strings.TrimSpace(d.Reason)
d.Raw = strings.TrimSpace(d.Raw)
}
// Validate 校验路由决策的最小合法性。
@@ -67,16 +67,12 @@ func (d *ChatRoutingDecision) Validate() error {
return fmt.Errorf("未知 route: %s", d.Route)
}
// direct_reply 必须有 speak。
if d.Route == ChatRouteDirectReply && d.Speak == "" {
return fmt.Errorf("direct_reply 必须携带 speak")
}
// 非 execute 路由不应携带粗排和粗排后微调标记,统一归一化为 false。
if d.Route != ChatRouteExecute {
d.NeedsRoughBuild = false
d.NeedsRefineAfterRoughBuild = false
d.AllowReorder = false
d.Thinking = false
}
// 只有 needs_rough_build=true 时needs_refine_after_rough_build 才有语义。
if !d.NeedsRoughBuild {