Version: 0.7.9.dev.260326

后端:
1.把最后一块拼图:schedule_refine也搬迁到了agent2,此时agent已经完全解耦。但是它没融入新架构,Codex只尝试把它调整了一部分,回退了一些错误的更改,保持着现在的可运行状态。下次继续改。
2.agent目录先保留,直到refine彻底融入新架构。
3.改善Codex主导的新史山结构:node文件夹里面大量文件,转而改成了module.go+module_tool.go的双文件格局,极大提升架构整洁度和代码可读性。
前端:
1.新开了日历界面,正在保持往前推进。做了很多更改,感觉越来越好了。
This commit is contained in:
Losita
2026-03-26 00:38:17 +08:00
parent aa04bfb452
commit a243154e23
32 changed files with 11481 additions and 1239 deletions

View File

@@ -0,0 +1,85 @@
package schedulerefine
import (
"context"
"testing"
"github.com/LoveLosita/smartflow/backend/model"
)
func TestRefineToolSpreadEvenRespectsCanonicalRouteFilters(t *testing.T) {
entries := []model.HybridScheduleEntry{
{TaskItemID: 1, Name: "任务1", Type: "task", Status: "suggested", Week: 16, DayOfWeek: 1, SectionFrom: 1, SectionTo: 2, ContextTag: "A"},
// 1. 这里放一个更早周次的 existing 条目,用来把可查询窗口拉到 W11
// 2. 若复合工具内部丢了 week_filter/day_of_week就会优先落到更早的 W11D1而不是目标 W12D3。
{TaskItemID: 99, Name: "课程", Type: "course", Status: "existing", Week: 11, DayOfWeek: 5, SectionFrom: 11, SectionTo: 12, BlockForSuggested: true},
}
params := map[string]any{
"task_item_ids": []int{1},
"week_filter": []int{12},
"day_of_week": []int{3},
"allow_embed": false,
}
nextEntries, result := refineToolSpreadEven(entries, params, planningWindow{Enabled: false}, refineToolPolicy{
OriginOrderMap: map[int]int{1: 1},
})
if !result.Success {
t.Fatalf("SpreadEven 执行失败: %s", result.Result)
}
idx := findSuggestedByID(nextEntries, 1)
if idx < 0 {
t.Fatalf("未找到 task_item_id=1")
}
got := nextEntries[idx]
if got.Week != 12 || got.DayOfWeek != 3 {
t.Fatalf("期望复合工具严格遵守 week_filter/day_of_week实际落点=W%dD%d", got.Week, got.DayOfWeek)
}
}
func TestRunCompositeRouteNodeAllowsHandoffWithoutDeterministicObjective(t *testing.T) {
entries := []model.HybridScheduleEntry{
{TaskItemID: 11, Name: "任务11", Type: "task", Status: "suggested", Week: 16, DayOfWeek: 1, SectionFrom: 1, SectionTo: 2, ContextTag: "数学"},
{TaskItemID: 12, Name: "任务12", Type: "task", Status: "suggested", Week: 16, DayOfWeek: 1, SectionFrom: 3, SectionTo: 4, ContextTag: "算法"},
{TaskItemID: 13, Name: "任务13", Type: "task", Status: "suggested", Week: 16, DayOfWeek: 1, SectionFrom: 5, SectionTo: 6, ContextTag: "数学"},
}
st := &ScheduleRefineState{
UserMessage: "把这些任务按最少上下文切换整理一下",
HybridEntries: cloneHybridEntries(entries),
InitialHybridEntries: cloneHybridEntries(entries),
WorksetTaskIDs: []int{11, 12, 13},
RequiredCompositeTool: "MinContextSwitch",
CompositeRetryMax: 0,
ExecuteMax: 4,
OriginOrderMap: map[int]int{11: 1, 12: 2, 13: 3},
CompositeToolCalled: map[string]bool{
"SpreadEven": false,
"MinContextSwitch": false,
},
CompositeToolSuccess: map[string]bool{
"SpreadEven": false,
"MinContextSwitch": false,
},
}
stageLogs := make([]string, 0, 8)
nextState, err := runCompositeRouteNode(context.Background(), st, func(stage, detail string) {
stageLogs = append(stageLogs, stage+"|"+detail)
})
if err != nil {
t.Fatalf("runCompositeRouteNode 返回错误: %v", err)
}
if nextState == nil {
t.Fatalf("runCompositeRouteNode 返回 nil state")
}
if !nextState.CompositeRouteSucceeded {
t.Fatalf("期望复合分支在缺少 deterministic objective 时直接出站,实际 CompositeRouteSucceeded=false, stages=%v, action_logs=%v", stageLogs, nextState.ActionLogs)
}
if nextState.DisableCompositeTools {
t.Fatalf("期望复合分支直接进入终审,不应降级为禁复合 ReAct")
}
if !nextState.CompositeToolSuccess["MinContextSwitch"] {
t.Fatalf("期望 MinContextSwitch 成功状态被记录")
}
}