feat(dispatcher,gateway): Eino 采纳 Phase D —— 任务生命周期状态机
submitted → running → done / failed / timeout 显式状态机,根治"卡运行中 看不出来"(此前 Task.Status 只写死 submitted、从不流转)。 - contract:新增 SubjectTaskStatus 主题 + TaskStatusEvent + 状态常量 - shared/bus:PublishTaskStatus / SubscribeTaskStatus(core NATS pub-sub) - dispatcher:StatusSink 接口 + Orchestrator.Handle 状态钩子——进入执行 →running、收尾 finishStatus→done/failed、整体超时上限 taskExecTimeout =3min→timeout;经 sub 回写 - gateway:SubscribeTaskStatus 落 PG(Task 增 Detail 字段,AutoMigrate); 新增 GET /api/v1/tasks/:id 供 UI 轮询状态 验收:实测 submitted→running→done 流转 + PG 持久化 + 端点查询闭环; make test-go 全绿。HITL 中断恢复 / 多智能体仍按场景待做。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -237,6 +237,31 @@ func (b *Bus) Ping(ctx context.Context, subject string) ([]byte, error) {
|
||||
return msg.Data, nil
|
||||
}
|
||||
|
||||
// ---- 任务生命周期状态回写(core NATS pub-sub)----
|
||||
|
||||
// PublishTaskStatus 广播一次任务状态流转(dispatcher 调用)。
|
||||
func (b *Bus) PublishTaskStatus(ev *contract.TaskStatusEvent) error {
|
||||
data, err := json.Marshal(ev)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return b.nc.Publish(contract.SubjectTaskStatus, data)
|
||||
}
|
||||
|
||||
// SubscribeTaskStatus 订阅任务状态流转(网关调用,落 PG + 推 UI)。
|
||||
func (b *Bus) SubscribeTaskStatus(onEvent func(*contract.TaskStatusEvent)) (unsub func() error, err error) {
|
||||
sub, err := b.nc.Subscribe(contract.SubjectTaskStatus, func(m *nats.Msg) {
|
||||
var ev contract.TaskStatusEvent
|
||||
if json.Unmarshal(m.Data, &ev) == nil {
|
||||
onEvent(&ev)
|
||||
}
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("subscribe task status: %w", err)
|
||||
}
|
||||
return sub.Unsubscribe, nil
|
||||
}
|
||||
|
||||
// ---- 配置控制面(core NATS request-reply + broadcast)----
|
||||
|
||||
// RequestConfig 向控制面(Gateway)请求某 kind 当前激活配置(chat/embedding)。
|
||||
|
||||
@@ -29,6 +29,30 @@ const (
|
||||
// request-reply 心跳主题让控制面(管理端「服务状态」)能判定它在不在线。
|
||||
SubjectHealthDispatcher = "sundynix.health.dispatcher"
|
||||
|
||||
// 任务生命周期状态回写:dispatcher 开跑/跑完/出错经此主题广播,网关订阅落 PG 并推 UI。
|
||||
// core NATS pub-sub(状态是幂等覆盖,丢一条由下一条纠正,无需持久化)。
|
||||
SubjectTaskStatus = "sundynix.tasks.status"
|
||||
)
|
||||
|
||||
// 任务生命周期状态机:submitted(网关建任务)→ running(dispatcher 开跑)
|
||||
// → done / failed / timeout(dispatcher 收尾)。
|
||||
const (
|
||||
TaskSubmitted = "submitted"
|
||||
TaskRunning = "running"
|
||||
TaskDone = "done"
|
||||
TaskFailed = "failed"
|
||||
TaskTimeout = "timeout"
|
||||
)
|
||||
|
||||
// TaskStatusEvent 是一次任务状态流转事件(经 SubjectTaskStatus 回流给网关)。
|
||||
type TaskStatusEvent struct {
|
||||
TaskID string `json:"task_id"`
|
||||
Status string `json:"status"` // running / done / failed / timeout
|
||||
Detail string `json:"detail,omitempty"` // 失败原因等
|
||||
TS int64 `json:"ts"` // unix 毫秒
|
||||
}
|
||||
|
||||
const (
|
||||
// MetaUserID 是 Task.Meta 中承载已登录用户标识的键(用于偏好记忆召回)。
|
||||
MetaUserID = "user_id"
|
||||
// MetaSessionID 是 Task.Meta 中承载会话标识的键(用于短期多轮历史)。
|
||||
|
||||
Reference in New Issue
Block a user