feat: add gitea agentic runtime control plane
This commit is contained in:
60
engine/devops_agent/spec.py
Normal file
60
engine/devops_agent/spec.py
Normal file
@@ -0,0 +1,60 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
import yaml
|
||||
|
||||
|
||||
class WorkflowSpecError(ValueError):
|
||||
"""Raised when a workflow spec cannot be parsed or is incomplete."""
|
||||
|
||||
|
||||
@dataclass(slots=True)
|
||||
class WorkflowSpec:
|
||||
name: str
|
||||
provider: str
|
||||
frontmatter: dict[str, Any]
|
||||
body: str
|
||||
source_path: Path
|
||||
|
||||
|
||||
def _split_frontmatter(raw_text: str) -> tuple[str, str]:
|
||||
if not raw_text.startswith("---"):
|
||||
raise WorkflowSpecError("workflow spec must start with frontmatter")
|
||||
|
||||
parts = raw_text.split("\n---", 1)
|
||||
if len(parts) != 2:
|
||||
raise WorkflowSpecError("workflow spec frontmatter is not terminated")
|
||||
|
||||
frontmatter_text = parts[0][4:]
|
||||
body = parts[1].lstrip("\r\n")
|
||||
return frontmatter_text, body
|
||||
|
||||
|
||||
def load_workflow_spec(path: str | Path) -> WorkflowSpec:
|
||||
source_path = Path(path)
|
||||
raw_text = source_path.read_text(encoding="utf-8")
|
||||
frontmatter_text, body = _split_frontmatter(raw_text)
|
||||
|
||||
payload = yaml.safe_load(frontmatter_text) or {}
|
||||
if not isinstance(payload, dict):
|
||||
raise WorkflowSpecError("workflow spec frontmatter must be a mapping")
|
||||
if True in payload and "on" not in payload:
|
||||
payload["on"] = payload.pop(True)
|
||||
|
||||
name = str(payload.get("name") or "").strip()
|
||||
provider = str(payload.get("provider") or "").strip()
|
||||
if not name:
|
||||
raise WorkflowSpecError("workflow spec is missing required field: name")
|
||||
if not provider:
|
||||
raise WorkflowSpecError("workflow spec is missing required field: provider")
|
||||
|
||||
return WorkflowSpec(
|
||||
name=name,
|
||||
provider=provider,
|
||||
frontmatter=payload,
|
||||
body=body,
|
||||
source_path=source_path,
|
||||
)
|
||||
Reference in New Issue
Block a user