Files
2026-06-22 08:55:57 +08:00

57 lines
1.9 KiB
Go

package orchestrator
import (
"context"
"time"
"github.com/google/uuid"
"github.com/yan1h/agent-coding-workflow/internal/project"
)
// StepEnqueuer 是建好 step 后入队其 orchestrator.step job 的窄接口(service 实现,
// 包装 jobs.Repository.Enqueue)。导出以便 app.go 在启动恢复时直接调用 EnqueueStep。
type StepEnqueuer interface {
EnqueueStep(ctx context.Context, runID, stepID uuid.UUID, scheduledAt time.Time) error
}
// AuditRecorder 是编排器写审计的窄接口(app 层用 audit.Recorder 适配)。导出以便
// 外部包(app)的适配器可实现(unexported 方法的接口无法被跨包实现)。
type AuditRecorder interface {
Record(ctx context.Context, userID uuid.UUID, action, targetID string, meta map[string]any)
}
// buildPhaseStep 为 run 在指定 phase 建一个新 step(pending 状态),解析 agent-kind
// 与 prompt 后落库。parent 非 nil 时记录 parent_step_id(request_subtask fan-out)。
// 解析失败(如缺 agent-kind)返回 error,调用方据此处理(标 run 失败 / 拒绝 subtask)。
func buildPhaseStep(ctx context.Context, repo Repository, pm PMAccess, run *Run,
phase project.Phase, parentStepID *uuid.UUID, depth int,
defaults map[project.Phase]uuid.UUID) (*Step, error) {
akID, err := PhaseAgentKind(run.Config, phase, defaults)
if err != nil {
return nil, err
}
req, err := pm.GetRequirementByID(ctx, run.RequirementID)
if err != nil {
return nil, err
}
artifacts, _ := pm.ListLatestArtifacts(ctx, run.RequirementID)
override := run.Config.PromptOverrides[phase]
prompt := BuildPrompt(phase, req, artifacts, override)
step := &Step{
ID: uuid.New(),
RunID: run.ID,
Phase: phase,
Attempt: 1,
ParentStepID: parentStepID,
Depth: depth,
Status: StepPending,
AgentKindID: akID,
Prompt: prompt,
}
return repo.InsertStep(ctx, step)
}