Version: 0.9.45.dev.260427
后端: 1. execute 主链路重构为“上下文工具域 + 主动优化候选闭环”——移除 order_guard,粗排后默认进入主动微调,先诊断再从后端候选中选择 move/swap,避免 LLM 自由全局乱搜 2. 工具体系升级为动态注入协议——新增 context_tools_add / remove、工具域与二级包映射、主动优化白名单;schedule / taskclass / web 工具按域按包暴露,msg0 规则包与 execute 上下文同步重写 3. analyze_health 升级为主动优化唯一裁判入口——补齐 rhythm / tightness / profile / feasibility 指标、候选扫描与复诊打分、停滞信号、forced imperfection 判定,并把连续优化状态写回运行态 4. 任务类能力并入新 Agent 执行链——新增 upsert_task_class 写工具与启动注入事务写入;任务类模型补充学科画像与整天屏蔽配置,粗排支持 excluded_days_of_week,steady 策略改为基于目标位置/单日负载/分散度/缓冲的候选打分 5. 运行态与路由补齐优化模式语义——新增 active tool domain/packs、pending context hook、active optimize only、taskclass 写入回盘快照;区分 first_full / global_reopt / local_adjust,并完善首次粗排后默认 refine 的判定 前端: 6. 助手时间线渲染细化——推理内容改为独立 reasoning block,支持与工具/状态/正文按时序交错展示,自动收口折叠,修正 confirm reject 恢复动作 仓库: 7. newAgent 文档整体迁入 docs/backend,补充主动优化执行规划与顺序约束拆解文档,删除旧调试日志文件 PS:这次科研了2天,总算是有些进展了——LLM永远只适合做选择题、判断题,不适合做开放创新题。
This commit is contained in:
@@ -17,6 +17,10 @@ var (
|
||||
// 非贪婪 (.*?) 避免匹配到多个标签时过度消耗。
|
||||
decisionTagRegex = regexp.MustCompile(
|
||||
`(?s)<\s*SMARTFLOW_DECISION\s*>(.*?)</\s*SMARTFLOW_DECISION\s*>`)
|
||||
// decisionTagHeadRegex 仅用于识别“起始标签是否已经出现”。
|
||||
// 目的:避免模型已经输出了 <SMARTFLOW_DECISION 开头但尚未输出闭合标签时,
|
||||
// 被长度阈值误判为 fallback(即“假截断”)。
|
||||
decisionTagHeadRegex = regexp.MustCompile(`(?i)<\s*SMARTFLOW_DECISION\b`)
|
||||
)
|
||||
|
||||
// StreamDecisionResult 描述解析器的最终输出状态。
|
||||
@@ -25,6 +29,14 @@ type StreamDecisionResult struct {
|
||||
// 调用方应使用 infrallm.ParseJSONObject[T] 将其解析为具体决策类型。
|
||||
DecisionJSON string
|
||||
|
||||
// BeforeText 是 <SMARTFLOW_DECISION> 标签之前的自然语言前言。
|
||||
// 仅用于“标签后正文为空”时的兜底展示,不参与 JSON 解析。
|
||||
BeforeText string
|
||||
|
||||
// AfterText 是 </SMARTFLOW_DECISION> 标签之后的自然语言正文。
|
||||
// 这是主协议约定的用户可见文本来源。
|
||||
AfterText string
|
||||
|
||||
// Fallback=true 表示流中未找到决策标签(超过 500 字符阈值),
|
||||
// RawBuffer 包含全部累积文本,调用方应走 correction 路径。
|
||||
Fallback bool
|
||||
@@ -51,6 +63,8 @@ type StreamDecisionParser struct {
|
||||
buf strings.Builder
|
||||
decisionFound bool
|
||||
decisionJSON string
|
||||
beforeText string
|
||||
afterText string
|
||||
rawBuf string // 用于 fallback/correction
|
||||
}
|
||||
|
||||
@@ -81,8 +95,13 @@ func (p *StreamDecisionParser) Feed(content string) (visible string, ready bool,
|
||||
text := p.buf.String()
|
||||
match := decisionTagRegex.FindStringSubmatchIndex(text)
|
||||
if match == nil {
|
||||
// 标签尚未完整,检查 fallback 阈值。
|
||||
// 1. 标签尚未完整,检查 fallback 阈值。
|
||||
// 2. 仅当“完全没有出现起始标签”时才允许 fallback。
|
||||
// 3. 若已经出现起始标签但还没闭合,则继续等待后续 chunk,避免早退。
|
||||
if len(text) > 500 {
|
||||
if decisionTagHeadRegex.MatchString(text) {
|
||||
return "", false, nil
|
||||
}
|
||||
p.decisionFound = true
|
||||
p.rawBuf = text
|
||||
return text, true, fmt.Errorf("决策标签解析超时,未找到 SMARTFLOW_DECISION 标签")
|
||||
@@ -110,13 +129,18 @@ func (p *StreamDecisionParser) Feed(content string) (visible string, ready bool,
|
||||
p.decisionJSON = jsonStr
|
||||
p.rawBuf = text
|
||||
|
||||
// 提取标签之后的文本作为 visible。
|
||||
// 1. 同时提取标签前/标签后的自然语言片段。
|
||||
// 2. 标签后正文仍然作为主协议 visible 返回,保持现有流式链路不变。
|
||||
// 3. 标签前前言只记入 Result,供 execute 在“后文为空”时兜底补发。
|
||||
fullMatch := groups[0]
|
||||
tagEndIdx := strings.Index(text, fullMatch)
|
||||
if tagEndIdx >= 0 {
|
||||
beforeTag := strings.TrimSpace(text[:tagEndIdx])
|
||||
afterTag := text[tagEndIdx+len(fullMatch):]
|
||||
afterTag = strings.TrimPrefix(afterTag, "\r\n")
|
||||
afterTag = strings.TrimPrefix(afterTag, "\n")
|
||||
p.beforeText = beforeTag
|
||||
p.afterText = afterTag
|
||||
return afterTag, true, nil
|
||||
}
|
||||
|
||||
@@ -138,6 +162,8 @@ func (p *StreamDecisionParser) DecisionJSON() string {
|
||||
func (p *StreamDecisionParser) Result() *StreamDecisionResult {
|
||||
r := &StreamDecisionResult{
|
||||
DecisionJSON: p.decisionJSON,
|
||||
BeforeText: p.beforeText,
|
||||
AfterText: p.afterText,
|
||||
RawBuffer: p.rawBuf,
|
||||
}
|
||||
if p.rawBuf != "" && p.decisionJSON == "" {
|
||||
|
||||
Reference in New Issue
Block a user