Version: 0.7.0.dev.260319

 feat(agent): 新增智能排程 Agent 全链路 + ReAct 精排引擎

  🏗️ 智能排程 Graph 编排(阶段 1 基础链路)
  - 新增 scheduleplan 包:state / tool / prompt / nodes / runner / graph 六件套
  - 实现 plan → preview → materialize → apply → reflect → finalize 完整图编排
  - 通过函数注入解耦 agent 层与 service 层,避免循环依赖
  - 路由层新增 schedule_plan 动作,复用现有 SSE + 持久化链路

  🧠 ReAct 精排引擎(阶段 1.5 语义化微调)
  - 粗排后构建"混合日程"(既有课程 + 建议任务),统一为 HybridScheduleEntry
  - LLM 开启深度思考,通过 Swap / Move / TimeAvailable / GetAvailableSlots 四个 Tool 在内存中优化任务时间
  - reasoning_content 实时流式推送前端,用户可见 AI 思考过程
  - 精排结果仅预览不落库,向后兼容(未注入依赖时走原有 materialize 路径)

  📝 文档
  - 新增 ReAct 精排引擎决策记录

  ⚠️ 已知问题:深度思考模式耗时较长,超时策略待优化
This commit is contained in:
Losita
2026-03-19 23:16:35 +08:00
parent cd95aeeaaa
commit d3cec2a5b9
24 changed files with 2737 additions and 24 deletions

View File

@@ -1,9 +1,12 @@
package service
import (
"context"
"github.com/LoveLosita/smartflow/backend/dao"
outboxinfra "github.com/LoveLosita/smartflow/backend/infra/outbox"
"github.com/LoveLosita/smartflow/backend/inits"
"github.com/LoveLosita/smartflow/backend/model"
"github.com/LoveLosita/smartflow/backend/service/agentsvc"
)
@@ -14,9 +17,43 @@ import (
type AgentService = agentsvc.AgentService
// NewAgentService 是迁移期兼容构造函数。
//
// 说明:
// 1) 外部调用签名保持不变;
// 1) 外部调用签名不变,新增排程依赖通过可选方式注入(见 NewAgentServiceWithSchedule
// 2) 真实构造逻辑已下沉到 service/agentsvc 包。
func NewAgentService(aiHub *inits.AIHub, repo *dao.AgentDAO, taskRepo *dao.TaskDAO, agentRedis *dao.AgentCache, eventPublisher outboxinfra.EventPublisher) *AgentService {
return agentsvc.NewAgentService(aiHub, repo, taskRepo, agentRedis, eventPublisher)
}
// NewAgentServiceWithSchedule 在基础 AgentService 上注入排程依赖。
//
// 设计目的:
// 1) 通过函数注入避免 agentsvc 包直接依赖 service 层的 ScheduleService / TaskClassService
// 2) 排程依赖为可选:未注入时排程路由自动回退到普通聊天;
// 3) 保持 NewAgentService 签名不变,向下兼容。
func NewAgentServiceWithSchedule(
aiHub *inits.AIHub,
repo *dao.AgentDAO,
taskRepo *dao.TaskDAO,
agentRedis *dao.AgentCache,
eventPublisher outboxinfra.EventPublisher,
scheduleSvc *ScheduleService,
taskClassSvc *TaskClassService,
) *AgentService {
svc := agentsvc.NewAgentService(aiHub, repo, taskRepo, agentRedis, eventPublisher)
// 注入排程依赖:将 service 层方法包装为函数闭包,避免循环依赖。
if scheduleSvc != nil {
svc.SmartPlanningRawFunc = scheduleSvc.SmartPlanningRaw
svc.HybridScheduleWithPlanFunc = scheduleSvc.HybridScheduleWithPlan
}
if taskClassSvc != nil {
svc.BatchApplyPlansFunc = taskClassSvc.BatchApplyPlans
// GetTaskClassByID 复用 TaskClassService 内部的 DAO 调用。
svc.GetTaskClassByIDFunc = func(ctx context.Context, taskClassID, userID int) (*model.TaskClass, error) {
return taskClassSvc.GetCompleteTaskClassByID(ctx, taskClassID, userID)
}
}
return svc
}