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:
Losita
2026-04-27 01:09:37 +08:00
parent 04b5836b39
commit 66c06eed0a
60 changed files with 9163 additions and 1819 deletions

View File

@@ -0,0 +1,124 @@
package schedule
import "strings"
// buildAnalyzeHealthDecisionV2 生成 analyze_health 在主动优化场景下的最终裁决。
//
// 职责边界:
// 1. 先尊重 base 层的判断:只有 base 明确允许继续优化时,才进入候选枚举。
// 2. 候选只来自后端已经验证合法、并且复诊后确实变好的 move/swap 方案。
// 3. 若没有真正改善的候选,则明确返回 close避免把 LLM 推回开放式全窗搜索。
func buildAnalyzeHealthDecisionV2(
state *ScheduleState,
snapshot analyzeHealthSnapshot,
) analyzeHealthDecision {
base := buildAnalyzeHealthDecisionBase(state, snapshot)
decision := analyzeHealthDecision{
ShouldContinueOptimize: base.ShouldContinueOptimize,
PrimaryProblem: base.PrimaryProblem,
ProblemScope: base.ProblemScope,
IsForcedImperfection: base.IsForcedImperfection,
RecommendedOperation: base.RecommendedOperation,
ImprovementSignal: buildHealthImprovementSignal(
snapshot.Rhythm,
snapshot.Tightness,
base.ProblemScope,
base.RecommendedOperation,
snapshot.Profile,
snapshot.Feasibility,
),
}
if !shouldEnterHealthCandidateLoop(base) {
decision.Candidates = []analyzeHealthCandidate{
buildHealthCloseCandidate("保持当前安排并收口:当前不需要再进入主动优化候选。", snapshot, base),
}
decision.ShouldContinueOptimize = false
return decision
}
bestScan, ok := findBestHealthProblemScanResult(state, snapshot)
if !ok || bestScan.Problem.Kind != healthProblemHeavyAdjacent || bestScan.Problem.Pair == nil {
decision.Candidates = []analyzeHealthCandidate{
buildHealthCloseCandidate("保持当前安排并收口:当前没有值得继续处理的局部认知问题。", snapshot, base),
}
decision.ShouldContinueOptimize = false
decision.PrimaryProblem = "当前没有发现值得继续处理的局部认知问题"
decision.ProblemScope = nil
decision.RecommendedOperation = "close"
if snapshot.Tightness.TightnessLevel == "locked" || snapshot.Tightness.TightnessLevel == "tight" {
decision.IsForcedImperfection = true
}
decision.ImprovementSignal = buildHealthImprovementSignal(
snapshot.Rhythm,
snapshot.Tightness,
decision.ProblemScope,
decision.RecommendedOperation,
snapshot.Profile,
snapshot.Feasibility,
)
return decision
}
decision.PrimaryProblem = bestScan.Problem.Summary
decision.ProblemScope = bestScan.Problem.Scope
decision.Candidates = append(decision.Candidates, bestScan.Candidates...)
decision.Candidates = append(decision.Candidates,
buildHealthCloseCandidate("如果不想继续挪动,也可以保持当前安排并直接收口。", snapshot, base),
)
decision.ShouldContinueOptimize = true
decision.RecommendedOperation = strings.TrimSpace(bestScan.Candidates[0].Tool)
decision.ImprovementSignal = buildHealthImprovementSignal(
snapshot.Rhythm,
snapshot.Tightness,
decision.ProblemScope,
decision.RecommendedOperation,
snapshot.Profile,
snapshot.Feasibility,
)
return decision
}
// findBestHealthProblemScanResult 每轮重扫所有 heavy_adjacent 天,并选出当前收益最高的一天。
//
// 步骤化说明:
// 1. 先收集所有仍需关注的 heavy_adjacent 天;这里只扫描问题天,不改候选类型。
// 2. 再对每一天复用现有单天候选试算逻辑,保持“合法且复诊后确实变好”这一过滤语义不变。
// 3. 最后只返回收益最高且达到最小阈值的一天;最终 decision.candidates 仍只来自这一天天然候选集。
func findBestHealthProblemScanResult(
state *ScheduleState,
snapshot analyzeHealthSnapshot,
) (analyzeHealthProblemScanResult, bool) {
problems := collectRepairableHeavyAdjacentProblems(state, snapshot)
if len(problems) == 0 {
return analyzeHealthProblemScanResult{}, false
}
results := make([]analyzeHealthProblemScanResult, 0, len(problems))
for _, problem := range problems {
scan, ok := buildHealthProblemScanResult(state, snapshot, problem)
if !ok {
continue
}
results = append(results, scan)
}
return selectBestHealthProblemScanResult(results)
}
// shouldEnterHealthCandidateLoop 判断本轮是否应进入“候选式主动优化”。
//
// 说明:
// 1. 只有 base 已判定“值得继续优化”时才放行。
// 2. 当前主动优化闭环只接受 move / swap 两类操作,其它动作不进入候选生成。
// 3. 这样可以挡住 “ask_user / close / forced imperfection” 被后续枚举误覆盖的问题。
func shouldEnterHealthCandidateLoop(base analyzeHealthDecisionBase) bool {
if !base.ShouldContinueOptimize {
return false
}
switch strings.TrimSpace(base.RecommendedOperation) {
case "move", "swap":
return true
default:
return false
}
}