Parse parsed_task.json → WorkflowIR.
(json_path: str)
| 386 | |
| 387 | |
| 388 | def parse_task_json(json_path: str) -> WorkflowIR: |
| 389 | """Parse parsed_task.json → WorkflowIR.""" |
| 390 | with open(json_path) as f: |
| 391 | data = json.load(f) |
| 392 | |
| 393 | wf_name = data["name"] |
| 394 | wf_goal = data.get("goal", "") |
| 395 | |
| 396 | # ---- Parameters ---- |
| 397 | params: list[TypedVar] = [] |
| 398 | raw_params = data.get("parameters", {}) or {} |
| 399 | for pname, pval in raw_params.items(): |
| 400 | pval = _resolve_env_vars(pval) |
| 401 | ptype = _infer_param_type(pval) |
| 402 | params.append(TypedVar(pname, ptype, value=pval)) |
| 403 | |
| 404 | type_ctx: dict[str, str] = {p.name: p.base_type for p in params} |
| 405 | nodes: list[NodeIR] = [] |
| 406 | edges: list[EdgeIR] = [] |
| 407 | nid = 0 |
| 408 | loop_patches: list[dict] = [] |
| 409 | |
| 410 | def alloc_id() -> int: |
| 411 | nonlocal nid |
| 412 | cur = nid |
| 413 | nid += 1 |
| 414 | return cur |
| 415 | |
| 416 | def resolve_type(v: str) -> str: |
| 417 | return type_ctx.get(v, "TString") |
| 418 | |
| 419 | def build_reads(vs: list[str]) -> list[TypedVar]: |
| 420 | return [TypedVar(v, resolve_type(v)) for v in vs] |
| 421 | |
| 422 | def add_seq(f: Optional[int], t: int): |
| 423 | if f is not None: |
| 424 | edges.append(EdgeIR("seq", from_node=f, to_node=t)) |
| 425 | |
| 426 | # ---------- Recursive body-step parser ---------- |
| 427 | def parse_body_steps(body_steps: list, body_prev: Optional[int]) -> tuple: |
| 428 | bf: Optional[int] = None |
| 429 | extra_tails: list[int] = [] |
| 430 | |
| 431 | def link_to(new_id: int) -> None: |
| 432 | nonlocal extra_tails |
| 433 | add_seq(body_prev, new_id) |
| 434 | if extra_tails: |
| 435 | for tail_id in list(dict.fromkeys(extra_tails)): |
| 436 | add_seq(tail_id, new_id) |
| 437 | extra_tails = [] |
| 438 | |
| 439 | for bs in body_steps: |
| 440 | bk = list(bs.keys())[0] |
| 441 | bd = bs[bk] |
| 442 | |
| 443 | if bk in ("step", "task", "synthesize", "discover"): |
| 444 | bid = alloc_id() |
| 445 | bname = bd.get("name", f"{bk}_{bid}") |
no test coverage detected