Why: Plugin scripts and model-written scripts need the same step runner, without giving the script a way to call interpreters or start another workflow. Evidence: go test ./... passed. Callbacks, denied tools, the 50-call cap, a 1MB line, and cancel-kills-the-process are covered. A model script does not run until the switch is on and the user confirms. Impact: runtime.workflowScripts stays off by default. Plugin script bodies are copied into the launch. Squad entry still has no run_workflow. Refs: feature/agent-harness-p4 Co-authored-by: Cursor <cursoragent@cursor.com>
52 lines
1.3 KiB
Python
52 lines
1.3 KiB
Python
"""工作流脚本回调。用法:import agentwf as wf。
|
|
|
|
请求写到 fd 3,响应从 fd 4 按行读回。宿主一次只处理一条。
|
|
"""
|
|
|
|
import json
|
|
import os
|
|
|
|
_seq = 0
|
|
_out = os.fdopen(3, "w", encoding="utf-8", buffering=1)
|
|
_inp = os.fdopen(4, "r", encoding="utf-8", buffering=1)
|
|
|
|
|
|
def _rpc(op, **fields):
|
|
global _seq
|
|
_seq += 1
|
|
msg = {"id": str(_seq), "op": op}
|
|
msg.update(fields)
|
|
_out.write(json.dumps(msg, ensure_ascii=False) + "\n")
|
|
_out.flush()
|
|
line = _inp.readline()
|
|
if not line:
|
|
raise RuntimeError("workflow host closed")
|
|
resp = json.loads(line)
|
|
if not resp.get("ok"):
|
|
raise RuntimeError(resp.get("error") or "workflow call failed")
|
|
return resp.get("output", "")
|
|
|
|
|
|
def tool(name, args=None):
|
|
return _rpc("tool.call", name=name, args=args or {})
|
|
|
|
|
|
def ask(question, choices=None):
|
|
return _rpc("hitl.ask", question=question, choices=choices or [])
|
|
|
|
|
|
def agent(name, task):
|
|
return _rpc("agent.spawn", agent=name, task=task)
|
|
|
|
|
|
def artifact(name, content):
|
|
return _rpc("artifact.register", name=name, content=content)
|
|
|
|
|
|
def card(title, kind="result"):
|
|
return _rpc("card.create", title=title, kind=kind)
|
|
|
|
|
|
def step(step_id, title, status):
|
|
return _rpc("step", stepId=step_id, title=title, status=status)
|