Run tool-started workflows with the script copy for that call
Why: A conversation run has no launch of its own, so a script step looked up an empty copy and refused to run. Evidence: go test ./internal/runtime/ -run TestRegisteredWorkflowUsesItsOwnScriptCopy passed. The body is taken from the launch passed into the runner. Impact: Intent-started runs still use the copy made at start. Refs: feature/agent-harness-p4 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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')"}`)
|
||||
|
||||
Reference in New Issue
Block a user