(
self,
run_id: str | None = None,
workflow_id: str = "",
project_root: Path | None = None,
)
| 395 | ) |
| 396 | |
| 397 | def __init__( |
| 398 | self, |
| 399 | run_id: str | None = None, |
| 400 | workflow_id: str = "", |
| 401 | project_root: Path | None = None, |
| 402 | ) -> None: |
| 403 | # ``run_id is None`` (omitted) → auto-generate. An explicit empty |
| 404 | # string is *not* the same as "omitted" and must be validated like |
| 405 | # any other caller-provided value — otherwise ``__init__("")`` |
| 406 | # would silently substitute a UUID while ``load("")`` rejects, and |
| 407 | # the two entry points would diverge on the empty-string vector. |
| 408 | if run_id is None: |
| 409 | self.run_id = str(uuid.uuid4())[:8] |
| 410 | else: |
| 411 | self.run_id = run_id |
| 412 | self._validate_run_id(self.run_id) |
| 413 | self.workflow_id = workflow_id |
| 414 | self.project_root = project_root or Path(".") |
| 415 | self.status = RunStatus.CREATED |
| 416 | self.current_step_index = 0 |
| 417 | self.current_step_id: str | None = None |
| 418 | self.step_results: dict[str, dict[str, Any]] = {} |
| 419 | # Guards step_results mutation and save() so a concurrent fan-out cannot |
| 420 | # mutate the dict while save() is serializing it (which would raise |
| 421 | # "dictionary changed size during iteration"). |
| 422 | self._lock = threading.Lock() |
| 423 | # Serializes append_log's list append + log.jsonl write so concurrent |
| 424 | # fan-out workers cannot interleave or corrupt log lines. Kept separate |
| 425 | # from _lock so frequent logging never contends with state saves; since |
| 426 | # append_log is never called while _lock is held, the two never nest. |
| 427 | self._log_lock = threading.Lock() |
| 428 | self.inputs: dict[str, Any] = {} |
| 429 | self.created_at = datetime.now(timezone.utc).isoformat() |
| 430 | self.updated_at = self.created_at |
| 431 | self.log_entries: list[dict[str, Any]] = [] |
| 432 | |
| 433 | @property |
| 434 | def runs_dir(self) -> Path: |
nothing calls this directly
no test coverage detected