后端: 1.把最后一块拼图:schedule_refine也搬迁到了agent2,此时agent已经完全解耦。但是它没融入新架构,Codex只尝试把它调整了一部分,回退了一些错误的更改,保持着现在的可运行状态。下次继续改。 2.agent目录先保留,直到refine彻底融入新架构。 3.改善Codex主导的新史山结构:node文件夹里面大量文件,转而改成了module.go+module_tool.go的双文件格局,极大提升架构整洁度和代码可读性。 前端: 1.新开了日历界面,正在保持往前推进。做了很多更改,感觉越来越好了。
86 lines
3.4 KiB
Go
86 lines
3.4 KiB
Go
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 成功状态被记录")
|
||
}
|
||
}
|