Version: 0.9.75.dev.260505
后端: 1.收口阶段 6 agent 结构迁移,将 newAgent 内核与 agentsvc 编排层迁入 services/agent - 切换 Agent 启动装配与 HTTP handler 直连 agent sv,移除旧 service agent bridge - 补齐 Agent 对 memory、task、task-class、schedule 的 RPC 适配与契约字段 - 扩展 schedule、task、task-class RPC/contract 支撑 Agent 查询、写入与 provider 切流 - 更新迁移文档、README 与相关注释,明确 agent 当前切流点和剩余 memory 迁移面
This commit is contained in:
121
backend/services/agent/sv/task_class_rpc_adapter.go
Normal file
121
backend/services/agent/sv/task_class_rpc_adapter.go
Normal file
@@ -0,0 +1,121 @@
|
||||
package sv
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/LoveLosita/smartflow/backend/model"
|
||||
agenttools "github.com/LoveLosita/smartflow/backend/services/agent/tools"
|
||||
taskclasscontracts "github.com/LoveLosita/smartflow/backend/shared/contracts/taskclass"
|
||||
)
|
||||
|
||||
const taskClassUpsertRPCTimeout = 6 * time.Second
|
||||
|
||||
// TaskClassUpsertRPCClient 描述 agent 写入任务类时依赖的 task-class RPC 最小能力。
|
||||
//
|
||||
// 职责边界:
|
||||
// 1. 只覆盖 upsert_task_class 工具需要的新增/更新能力;
|
||||
// 2. 不暴露 task-class DAO、事务细节或 schedule 迁移期直写语义;
|
||||
// 3. 读取型能力由 schedule provider 的独立接口承载,避免接口膨胀。
|
||||
type TaskClassUpsertRPCClient interface {
|
||||
AddTaskClass(ctx context.Context, req taskclasscontracts.UpsertTaskClassRequest) (json.RawMessage, error)
|
||||
UpdateTaskClass(ctx context.Context, req taskclasscontracts.UpsertTaskClassRequest) (json.RawMessage, error)
|
||||
}
|
||||
|
||||
type taskClassRPCUpsertAdapter struct {
|
||||
client TaskClassUpsertRPCClient
|
||||
}
|
||||
|
||||
// NewTaskClassRPCUpsertFunc 把 task-class zrpc client 适配成 agent 工具写入函数。
|
||||
//
|
||||
// 职责边界:
|
||||
// 1. 只替换 agent upsert_task_class 的 DAO 直连路径;
|
||||
// 2. 入参仍复用 agent 工具层已标准化的 UserAddTaskClassRequest;
|
||||
// 3. client 为空时返回会失败的闭包,让工具层保留既有错误包装语义。
|
||||
func NewTaskClassRPCUpsertFunc(client TaskClassUpsertRPCClient) func(userID int, input agenttools.TaskClassUpsertInput) (agenttools.TaskClassUpsertPersistResult, error) {
|
||||
adapter := &taskClassRPCUpsertAdapter{client: client}
|
||||
return adapter.UpsertTaskClass
|
||||
}
|
||||
|
||||
// UpsertTaskClass 通过 task-class zrpc 新增或更新任务类,并返回稳定 task_class_id。
|
||||
func (a *taskClassRPCUpsertAdapter) UpsertTaskClass(userID int, input agenttools.TaskClassUpsertInput) (agenttools.TaskClassUpsertPersistResult, error) {
|
||||
if a == nil || a.client == nil {
|
||||
return agenttools.TaskClassUpsertPersistResult{}, errors.New("task-class rpc client is nil")
|
||||
}
|
||||
req := taskClassUpsertInputToContract(userID, input)
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), taskClassUpsertRPCTimeout)
|
||||
defer cancel()
|
||||
|
||||
var raw json.RawMessage
|
||||
var err error
|
||||
created := input.ID == 0
|
||||
// 调用目的:把 agent 工具产出的任务类写入 task-class 服务,避免 agent 继续直连 task_classes/task_items。
|
||||
if created {
|
||||
raw, err = a.client.AddTaskClass(ctx, req)
|
||||
} else {
|
||||
raw, err = a.client.UpdateTaskClass(ctx, req)
|
||||
}
|
||||
if err != nil {
|
||||
return agenttools.TaskClassUpsertPersistResult{}, err
|
||||
}
|
||||
|
||||
var resp taskclasscontracts.UpsertTaskClassResponse
|
||||
if err := json.Unmarshal(raw, &resp); err != nil {
|
||||
return agenttools.TaskClassUpsertPersistResult{}, err
|
||||
}
|
||||
if resp.TaskClassID <= 0 {
|
||||
return agenttools.TaskClassUpsertPersistResult{}, errors.New("task-class rpc upsert returned invalid task_class_id")
|
||||
}
|
||||
return agenttools.TaskClassUpsertPersistResult{
|
||||
TaskClassID: resp.TaskClassID,
|
||||
Created: resp.Created,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func taskClassUpsertInputToContract(userID int, input agenttools.TaskClassUpsertInput) taskclasscontracts.UpsertTaskClassRequest {
|
||||
req := input.Request
|
||||
items := make([]taskclasscontracts.UpsertTaskClassItemConfig, 0, len(req.Items))
|
||||
for _, item := range req.Items {
|
||||
items = append(items, taskclasscontracts.UpsertTaskClassItemConfig{
|
||||
ID: item.ID,
|
||||
Order: item.Order,
|
||||
Content: strings.TrimSpace(item.Content),
|
||||
EmbeddedTime: toTaskClassContractTargetTime(item.EmbeddedTime),
|
||||
})
|
||||
}
|
||||
return taskclasscontracts.UpsertTaskClassRequest{
|
||||
UserID: userID,
|
||||
TaskClassID: input.ID,
|
||||
Name: strings.TrimSpace(req.Name),
|
||||
StartDate: strings.TrimSpace(req.StartDate),
|
||||
EndDate: strings.TrimSpace(req.EndDate),
|
||||
Mode: strings.TrimSpace(req.Mode),
|
||||
SubjectType: strings.TrimSpace(req.SubjectType),
|
||||
DifficultyLevel: strings.TrimSpace(req.DifficultyLevel),
|
||||
CognitiveIntensity: strings.TrimSpace(req.CognitiveIntensity),
|
||||
Config: taskclasscontracts.UpsertTaskClassConfig{
|
||||
TotalSlots: req.Config.TotalSlots,
|
||||
AllowFillerCourse: req.Config.AllowFillerCourse,
|
||||
Strategy: strings.TrimSpace(req.Config.Strategy),
|
||||
ExcludedSlots: append([]int(nil), req.Config.ExcludedSlots...),
|
||||
ExcludedDaysOfWeek: append([]int(nil), req.Config.ExcludedDaysOfWeek...),
|
||||
},
|
||||
Items: items,
|
||||
}
|
||||
}
|
||||
|
||||
func toTaskClassContractTargetTime(value *model.TargetTime) *taskclasscontracts.TargetTime {
|
||||
if value == nil {
|
||||
return nil
|
||||
}
|
||||
return &taskclasscontracts.TargetTime{
|
||||
Week: value.Week,
|
||||
DayOfWeek: value.DayOfWeek,
|
||||
SectionFrom: value.SectionFrom,
|
||||
SectionTo: value.SectionTo,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user