Files
smartmate/backend/newAgent/model/chat_contract.go
LoveLosita 21eed5af75 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
前端:无
仓库:无
2026-04-15 11:04:27 +08:00

84 lines
2.6 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package model
import (
"fmt"
"strings"
)
// ChatRoute 表示 Chat 节点路由决策的目标路径。
type ChatRoute string
const (
// ChatRouteDirectReply 简单任务Chat 节点直接输出回复,不再调用下游节点。
ChatRouteDirectReply ChatRoute = "direct_reply"
// ChatRouteExecute 中等任务:需要用工具处理,直接进 Execute ReAct 循环。
ChatRouteExecute ChatRoute = "execute"
// ChatRouteDeepAnswer 复杂问答需要深度思考但不需工具Chat 节点原地开 thinking 回答。
ChatRouteDeepAnswer ChatRoute = "deep_answer"
// ChatRoutePlan 复杂规划:需要先制定计划,进 Plan 节点。
ChatRoutePlan ChatRoute = "plan"
)
// ChatRoutingDecision 是 Chat 节点单次路由决策的结构化输出。
//
// 职责边界:
// 1. Route 决定后续处理路径;
// 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
NeedsRoughBuild bool
NeedsRefineAfterRoughBuild bool
AllowReorder bool
Thinking bool
Raw string
}
// Normalize 统一清洗路由决策中的字符串字段。
func (d *ChatRoutingDecision) Normalize() {
if d == nil {
return
}
d.Route = ChatRoute(strings.TrimSpace(string(d.Route)))
d.Raw = strings.TrimSpace(d.Raw)
}
// Validate 校验路由决策的最小合法性。
func (d *ChatRoutingDecision) Validate() error {
if d == nil {
return fmt.Errorf("chat routing decision 不能为空")
}
d.Normalize()
switch d.Route {
case ChatRouteDirectReply, ChatRouteExecute, ChatRouteDeepAnswer, ChatRoutePlan:
// ok
case "":
return fmt.Errorf("chat routing decision.route 不能为空")
default:
return fmt.Errorf("未知 route: %s", d.Route)
}
// 非 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 {
d.NeedsRefineAfterRoughBuild = false
}
return nil
}