Execute 执行计划
(ctx context.Context, plan *ExecutionPlan, toolCtx *tools.ToolContext)
| 69 | |
| 70 | // Execute 执行计划 |
| 71 | func (e *Executor) Execute(ctx context.Context, plan *ExecutionPlan, toolCtx *tools.ToolContext) error { |
| 72 | // 检查计划是否可以执行 |
| 73 | if !plan.CanExecute() { |
| 74 | if plan.Options != nil && plan.Options.RequireApproval && !plan.IsApproved() { |
| 75 | return errors.New("plan requires user approval before execution") |
| 76 | } |
| 77 | if plan.Status == StatusExecuting { |
| 78 | return errors.New("plan is already executing") |
| 79 | } |
| 80 | if plan.IsCompleted() { |
| 81 | return fmt.Errorf("plan has already completed with status: %s", plan.Status) |
| 82 | } |
| 83 | return fmt.Errorf("plan cannot be executed in current state: %s", plan.Status) |
| 84 | } |
| 85 | |
| 86 | // 更新计划状态 |
| 87 | now := time.Now() |
| 88 | plan.Status = StatusExecuting |
| 89 | plan.StartedAt = &now |
| 90 | plan.UpdatedAt = now |
| 91 | |
| 92 | // 根据配置选择执行方式 |
| 93 | var err error |
| 94 | if plan.Options != nil && plan.Options.AllowParallel { |
| 95 | err = e.executeParallel(ctx, plan, toolCtx) |
| 96 | } else { |
| 97 | err = e.executeSequential(ctx, plan, toolCtx) |
| 98 | } |
| 99 | |
| 100 | // 更新计划完成状态 |
| 101 | completedAt := time.Now() |
| 102 | plan.CompletedAt = &completedAt |
| 103 | plan.TotalDurationMs = completedAt.Sub(*plan.StartedAt).Milliseconds() |
| 104 | plan.UpdatedAt = completedAt |
| 105 | |
| 106 | // 确定最终状态 |
| 107 | summary := plan.Summary() |
| 108 | if summary.Failed > 0 { |
| 109 | if summary.Completed > 0 { |
| 110 | plan.Status = StatusPartial |
| 111 | } else { |
| 112 | plan.Status = StatusFailed |
| 113 | } |
| 114 | } else if summary.Completed == summary.TotalSteps { |
| 115 | plan.Status = StatusCompleted |
| 116 | } |
| 117 | |
| 118 | // 触发计划完成回调 |
| 119 | if e.onPlanComplete != nil { |
| 120 | e.onPlanComplete(plan) |
| 121 | } |
| 122 | |
| 123 | return err |
| 124 | } |
| 125 | |
| 126 | // executeSequential 顺序执行步骤 |
| 127 | func (e *Executor) executeSequential(ctx context.Context, plan *ExecutionPlan, toolCtx *tools.ToolContext) error { |