后端: 1.把最后一块拼图:schedule_refine也搬迁到了agent2,此时agent已经完全解耦。但是它没融入新架构,Codex只尝试把它调整了一部分,回退了一些错误的更改,保持着现在的可运行状态。下次继续改。 2.agent目录先保留,直到refine彻底融入新架构。 3.改善Codex主导的新史山结构:node文件夹里面大量文件,转而改成了module.go+module_tool.go的双文件格局,极大提升架构整洁度和代码可读性。 前端: 1.新开了日历界面,正在保持往前推进。做了很多更改,感觉越来越好了。
201 lines
7.5 KiB
Go
201 lines
7.5 KiB
Go
package agentmodel
|
||
|
||
import (
|
||
"strings"
|
||
"time"
|
||
|
||
"github.com/LoveLosita/smartflow/backend/model"
|
||
)
|
||
|
||
const (
|
||
// SchedulePlanTimezoneName 是排程链路默认业务时区。
|
||
// 与随口记保持一致,固定东八区,避免容器运行在 UTC 导致“明天/今晚”偏移。
|
||
SchedulePlanTimezoneName = "Asia/Shanghai"
|
||
|
||
// SchedulePlanDatetimeLayout 是排程链路内部统一的分钟级时间格式。
|
||
SchedulePlanDatetimeLayout = "2006-01-02 15:04"
|
||
|
||
// SchedulePlanDefaultDailyRefineConcurrency 是日内并发优化默认并发度。
|
||
// 这里给一个保守默认值,避免未配置时直接把模型并发打满导致限流。
|
||
SchedulePlanDefaultDailyRefineConcurrency = 3
|
||
|
||
// SchedulePlanDefaultWeeklyAdjustBudget 是周级配平默认调整额度。
|
||
// 额度存在的目的:
|
||
// 1. 防止周级 ReAct 过度调整导致震荡;
|
||
// 2. 控制 token 与时延成本;
|
||
// 3. 让方案改动更可解释。
|
||
SchedulePlanDefaultWeeklyAdjustBudget = 5
|
||
|
||
// SchedulePlanDefaultWeeklyTotalBudget 是周级“总尝试次数”默认预算。
|
||
//
|
||
// 设计意图:
|
||
// 1. 总预算统计“动作尝试次数”(成功/失败都记一次);
|
||
// 2. 有效预算统计“成功动作次数”(仅成功时记一次);
|
||
// 3. 通过双预算把“探索次数”和“有效改动次数”分离,降低模型无效空转成本。
|
||
SchedulePlanDefaultWeeklyTotalBudget = 8
|
||
|
||
// SchedulePlanDefaultWeeklyRefineConcurrency 是周级“按周并发”默认并发度。
|
||
// 说明:
|
||
// 1. 周级输入规模通常比单天更大,默认并发度不宜过高,避免触发模型侧限流;
|
||
// 2. 可在运行时按请求状态覆盖。
|
||
SchedulePlanDefaultWeeklyRefineConcurrency = 2
|
||
|
||
// SchedulePlanAdjustmentScopeSmall 表示“小改动微调”。
|
||
// 语义:优先走快速路径,只做轻量周级调整。
|
||
SchedulePlanAdjustmentScopeSmall = "small"
|
||
// SchedulePlanAdjustmentScopeMedium 表示“中等改动微调”。
|
||
// 语义:跳过日内拆分,直接进入周级配平。
|
||
SchedulePlanAdjustmentScopeMedium = "medium"
|
||
// SchedulePlanAdjustmentScopeLarge 表示“大改动重排”。
|
||
// 语义:必要时重新走全量路径(日内并发 + 周级配平)。
|
||
SchedulePlanAdjustmentScopeLarge = "large"
|
||
)
|
||
|
||
const (
|
||
schedulePlanTimezoneName = SchedulePlanTimezoneName
|
||
schedulePlanDatetimeLayout = SchedulePlanDatetimeLayout
|
||
schedulePlanDefaultDailyRefineConcurrency = SchedulePlanDefaultDailyRefineConcurrency
|
||
schedulePlanDefaultWeeklyAdjustBudget = SchedulePlanDefaultWeeklyAdjustBudget
|
||
schedulePlanDefaultWeeklyTotalBudget = SchedulePlanDefaultWeeklyTotalBudget
|
||
schedulePlanDefaultWeeklyRefineConcurrency = SchedulePlanDefaultWeeklyRefineConcurrency
|
||
schedulePlanAdjustmentScopeSmall = SchedulePlanAdjustmentScopeSmall
|
||
schedulePlanAdjustmentScopeMedium = SchedulePlanAdjustmentScopeMedium
|
||
schedulePlanAdjustmentScopeLarge = SchedulePlanAdjustmentScopeLarge
|
||
)
|
||
|
||
// DayGroup 是“按天拆分后”的最小优化单元。
|
||
//
|
||
// 设计目的:
|
||
// 1. 把全量周视角数据拆成“单天小包”,降低日内 ReAct 输入规模;
|
||
// 2. 支持并发优化不同天的数据,缩短整体等待;
|
||
// 3. 通过 SkipRefine 让低收益天数直接跳过,节省模型调用成本。
|
||
type DayGroup struct {
|
||
Week int
|
||
DayOfWeek int
|
||
Entries []model.HybridScheduleEntry
|
||
SkipRefine bool
|
||
}
|
||
|
||
// SchedulePlanState 是“智能排程”链路在 graph 节点间传递的统一状态容器。
|
||
//
|
||
// 设计目标:
|
||
// 1) 收拢排程请求全生命周期的上下文,降低节点间参数散落;
|
||
// 2) 支持“粗排 -> 日内并发优化 -> 周级配平 -> 终审校验”的完整链路追踪;
|
||
// 3) 支持连续对话微调:保留上版方案 + 本次约束变更,便于增量重排。
|
||
type SchedulePlanState struct {
|
||
// ── 基础上下文 ──
|
||
TraceID string
|
||
UserID int
|
||
ConversationID string
|
||
RequestNow time.Time
|
||
RequestNowText string
|
||
|
||
// ── plan 节点输出 ──
|
||
UserIntent string
|
||
Constraints []string
|
||
TaskClassIDs []int
|
||
Strategy string
|
||
TaskTags map[int]string
|
||
TaskTagHintsByName map[string]string
|
||
|
||
// ── preview 节点输出 ──
|
||
CandidatePlans []model.UserWeekSchedule
|
||
AllocatedItems []model.TaskClassItem
|
||
HasPlanningWindow bool
|
||
PlanStartWeek int
|
||
PlanStartDay int
|
||
PlanEndWeek int
|
||
PlanEndDay int
|
||
|
||
// ── 日内并发优化阶段 ──
|
||
DailyGroups map[int]map[int]*DayGroup
|
||
DailyResults map[int]map[int][]model.HybridScheduleEntry
|
||
DailyRefineConcurrency int
|
||
|
||
// ── 周级 ReAct 精排阶段 ──
|
||
HybridEntries []model.HybridScheduleEntry
|
||
MergeSnapshot []model.HybridScheduleEntry
|
||
ReactRound int
|
||
ReactMaxRound int
|
||
ReactSummary string
|
||
ReactDone bool
|
||
WeeklyAdjustBudget int
|
||
WeeklyAdjustUsed int
|
||
WeeklyTotalBudget int
|
||
WeeklyTotalUsed int
|
||
WeeklyRefineConcurrency int
|
||
WeeklyActionLogs []string
|
||
|
||
// ── 连续对话微调 ──
|
||
PreviousPlanJSON string
|
||
IsAdjustment bool
|
||
RestartRequested bool
|
||
AdjustmentScope string
|
||
AdjustmentReason string
|
||
AdjustmentConfidence float64
|
||
HasPreviousPreview bool
|
||
PreviousTaskClassIDs []int
|
||
PreviousHybridEntries []model.HybridScheduleEntry
|
||
PreviousAllocatedItems []model.TaskClassItem
|
||
PreviousCandidatePlans []model.UserWeekSchedule
|
||
|
||
// ── 最终输出 ──
|
||
FinalSummary string
|
||
Completed bool
|
||
}
|
||
|
||
// NewSchedulePlanState 创建排程状态对象并初始化默认值。
|
||
func NewSchedulePlanState(traceID string, userID int, conversationID string) *SchedulePlanState {
|
||
now := schedulePlanNowToMinute()
|
||
return &SchedulePlanState{
|
||
TraceID: traceID,
|
||
UserID: userID,
|
||
ConversationID: conversationID,
|
||
RequestNow: now,
|
||
RequestNowText: now.In(schedulePlanLocation()).Format(schedulePlanDatetimeLayout),
|
||
Strategy: "steady",
|
||
TaskTags: make(map[int]string),
|
||
TaskTagHintsByName: make(map[string]string),
|
||
DailyRefineConcurrency: schedulePlanDefaultDailyRefineConcurrency,
|
||
WeeklyRefineConcurrency: schedulePlanDefaultWeeklyRefineConcurrency,
|
||
AdjustmentScope: schedulePlanAdjustmentScopeLarge,
|
||
ReactMaxRound: 2,
|
||
WeeklyAdjustBudget: schedulePlanDefaultWeeklyAdjustBudget,
|
||
WeeklyTotalBudget: schedulePlanDefaultWeeklyTotalBudget,
|
||
}
|
||
}
|
||
|
||
// NormalizeSchedulePlanAdjustmentScope 归一化排程微调力度字段。
|
||
//
|
||
// 兜底策略:
|
||
// 1. 只接受 small/medium/large;
|
||
// 2. 任何未知值都回退为 large,保证不会误走“过轻”路径。
|
||
func NormalizeSchedulePlanAdjustmentScope(raw string) string {
|
||
switch strings.ToLower(strings.TrimSpace(raw)) {
|
||
case schedulePlanAdjustmentScopeSmall:
|
||
return schedulePlanAdjustmentScopeSmall
|
||
case schedulePlanAdjustmentScopeMedium:
|
||
return schedulePlanAdjustmentScopeMedium
|
||
default:
|
||
return schedulePlanAdjustmentScopeLarge
|
||
}
|
||
}
|
||
|
||
// schedulePlanLocation 返回排程链路使用的业务时区。
|
||
func schedulePlanLocation() *time.Location {
|
||
loc, err := time.LoadLocation(schedulePlanTimezoneName)
|
||
if err != nil {
|
||
return time.Local
|
||
}
|
||
return loc
|
||
}
|
||
|
||
// schedulePlanNowToMinute 返回当前时间并截断到分钟级。
|
||
func schedulePlanNowToMinute() time.Time {
|
||
return time.Now().In(schedulePlanLocation()).Truncate(time.Minute)
|
||
}
|
||
|
||
func normalizeAdjustmentScope(raw string) string {
|
||
return NormalizeSchedulePlanAdjustmentScope(raw)
|
||
}
|