diff --git a/internal/runtime/workflow.go b/internal/runtime/workflow.go index 155be1e..1a3bde3 100644 --- a/internal/runtime/workflow.go +++ b/internal/runtime/workflow.go @@ -177,7 +177,7 @@ func (w WorkflowRunner) run(rc RunCtx, launch workflow.Launch) (workflowOutcome, if err != nil { return outcome(def, statuses, arts, drops, err.Error()), err } - output, stepArts, reason, err := w.runStepWithCritic(rc, def, rendered, vars, prev, &wholeLeft, &drops) + output, stepArts, reason, err := w.runStepWithCritic(rc, def, rendered, vars, prev, launch.Scripts, &wholeLeft, &drops) arts = append(arts, stepArts...) if err != nil { statuses[i] = "failed" @@ -198,7 +198,7 @@ func (w WorkflowRunner) run(rc RunCtx, launch workflow.Launch) (workflowOutcome, return res, nil } -func (w WorkflowRunner) runStepWithCritic(rc RunCtx, def core.WorkflowDef, step core.WorkflowStep, vars workflow.Vars, prev string, wholeLeft *int, drops *[]string) (string, []*core.ArtifactRef, string, error) { +func (w WorkflowRunner) runStepWithCritic(rc RunCtx, def core.WorkflowDef, step core.WorkflowStep, vars workflow.Vars, prev string, scripts map[string]string, wholeLeft *int, drops *[]string) (string, []*core.ArtifactRef, string, error) { stepRetries := 1 if step.Critic != nil && step.Critic.MaxRetries > 0 { stepRetries = step.Critic.MaxRetries @@ -216,7 +216,7 @@ func (w WorkflowRunner) runStepWithCritic(rc RunCtx, def core.WorkflowDef, step } else if note != "" { current.Prompt = "未通过验收:" + note } - output, got, err := w.runWorkflowStep(rc, current, vars, prev) + output, got, err := w.runWorkflowStep(rc, current, vars, prev, scripts) arts = append(arts, got...) if err != nil { return output, arts, err.Error(), err @@ -242,7 +242,7 @@ func (w WorkflowRunner) runStepWithCritic(rc RunCtx, def core.WorkflowDef, step } } -func (w WorkflowRunner) runWorkflowStep(rc RunCtx, step core.WorkflowStep, vars workflow.Vars, prev string) (string, []*core.ArtifactRef, error) { +func (w WorkflowRunner) runWorkflowStep(rc RunCtx, step core.WorkflowStep, vars workflow.Vars, prev string, scripts map[string]string) (string, []*core.ArtifactRef, error) { switch step.Kind { case "prompt": return runPromptStep(rc, step) @@ -302,7 +302,7 @@ func (w WorkflowRunner) runWorkflowStep(rc RunCtx, step core.WorkflowStep, vars } return string(created.ID), nil, nil case "script": - return executeScriptStep(rc, w, step) + return executeScriptStep(rc, w, step, scripts) default: return "", nil, fmt.Errorf("workflow: 未知步骤类型 %s", step.Kind) } diff --git a/internal/runtime/workflow_script.go b/internal/runtime/workflow_script.go index 78cc7b3..0e126fa 100644 --- a/internal/runtime/workflow_script.go +++ b/internal/runtime/workflow_script.go @@ -63,10 +63,14 @@ func scriptSandbox(rc RunCtx) (string, error) { return sandbox, nil } -func executeScriptStep(rc RunCtx, runner WorkflowRunner, step core.WorkflowStep) (string, []*core.ArtifactRef, error) { - body, err := scriptBody(rc, step.Script) - if err != nil { - return "", nil, err +func executeScriptStep(rc RunCtx, runner WorkflowRunner, step core.WorkflowStep, scripts map[string]string) (string, []*core.ArtifactRef, error) { + body := scripts[step.Script] + if strings.TrimSpace(body) == "" { + var err error + body, err = scriptBody(rc, step.Script) + if err != nil { + return "", nil, err + } } sandbox, err := scriptSandbox(rc) if err != nil { diff --git a/internal/runtime/workflow_script_test.go b/internal/runtime/workflow_script_test.go index d14a456..c26ac10 100644 --- a/internal/runtime/workflow_script_test.go +++ b/internal/runtime/workflow_script_test.go @@ -209,6 +209,19 @@ f.flush() } } +func TestRegisteredWorkflowUsesItsOwnScriptCopy(t *testing.T) { + f := &wfFake{sandbox: t.TempDir(), settings: scriptSettings()} + res, err := (WorkflowRunner{}).run(f, workflow.Launch{ + Def: core.WorkflowDef{ID: "demo.script", Title: "脚本", Steps: []core.WorkflowStep{{ + ID: "run", Title: "跑", Kind: "script", Script: "workflows/scripts/demo.py", + }}}, + Scripts: map[string]string{"workflows/scripts/demo.py": "print('from-launch')\n"}, + }) + if err != nil || !strings.Contains(res.Summary, "完成") { + t.Fatalf("err %v summary %s", err, res.Summary) + } +} + func TestModelScriptNeedsSwitchAndConfirm(t *testing.T) { f := &wfFake{sandbox: t.TempDir()} out := (&directRun{rc: f}).runRegisteredWorkflow(`{"script":"print('pong')"}`)