Files
yao-meta-skill/scripts/run_output_execution.py
T
YAO 31ce04c655 Split meta skill CLI and review gates
Merge the beta-ready Yao Meta Skill architecture, report, evidence gate, and release-boundary updates.\n\nRelease boundary: beta/public testing is allowed; formal world-class, fully reviewed, or superiority claims remain blocked until the pending evidence gates are accepted.
2026-06-17 18:43:02 +08:00

383 lines
16 KiB
Python

#!/usr/bin/env python3
import argparse
import hashlib
import json
import shlex
import subprocess
import time
from pathlib import Path
from typing import Any
from run_output_eval import DEFAULT_CASES, display_path, grade_output, load_cases, validate_case
ROOT = Path(__file__).resolve().parent.parent
DEFAULT_OUTPUT_JSON = ROOT / "reports" / "output_execution_runs.json"
DEFAULT_OUTPUT_MD = ROOT / "reports" / "output_execution_runs.md"
VARIANTS = ("baseline", "with_skill")
def output_for_variant(case: dict[str, Any], variant: str) -> str:
return str(case.get("baseline_output" if variant == "baseline" else "with_skill_output", ""))
def output_key(variant: str) -> str:
return "baseline_output" if variant == "baseline" else "with_skill_output"
def parse_runner_command(value: str | None) -> list[str]:
if not value:
return []
stripped = value.strip()
if stripped.startswith("["):
payload = json.loads(stripped)
if not isinstance(payload, list) or not all(isinstance(item, str) and item for item in payload):
raise ValueError("--runner-command JSON must be a non-empty string list")
return payload
return shlex.split(stripped)
def display_command(command: list[str]) -> list[str]:
displayed: list[str] = []
for item in command:
path = Path(item)
if path.is_absolute() and path.exists():
displayed.append(display_path(path))
else:
displayed.append(item)
return displayed
def estimate_tokens(text: str) -> int:
if not text:
return 0
return max(1, round(len(text) / 4))
def parse_runner_stdout(stdout: str) -> tuple[str, dict[str, Any]]:
stripped = stdout.strip()
if not stripped:
return "", {}
try:
payload = json.loads(stripped)
except json.JSONDecodeError:
return stdout, {}
if not isinstance(payload, dict):
return stdout, {}
return str(payload.get("output", "")), payload
def usage_payload(payload: dict[str, Any], prompt: str, output: str) -> dict[str, Any]:
usage = payload.get("usage", {}) if isinstance(payload.get("usage"), dict) else {}
input_tokens = usage.get("input_tokens", usage.get("prompt_tokens"))
output_tokens = usage.get("output_tokens", usage.get("completion_tokens"))
total_tokens = usage.get("total_tokens")
estimated = bool(usage.get("estimated", False))
if input_tokens is None:
input_tokens = estimate_tokens(prompt)
estimated = True
if output_tokens is None:
output_tokens = estimate_tokens(output)
estimated = True
if total_tokens is None:
total_tokens = int(input_tokens or 0) + int(output_tokens or 0)
estimated = True
return {
"input_tokens": int(input_tokens or 0),
"output_tokens": int(output_tokens or 0),
"total_tokens": int(total_tokens or 0),
"estimated": estimated,
}
def recorded_fixture_run(case: dict[str, Any], variant: str, assertions: list[dict[str, Any]]) -> dict[str, Any]:
output = output_for_variant(case, variant)
grade = grade_output(output, assertions)
return {
"case_id": str(case.get("id", "")),
"variant": variant,
"status": "pass",
"execution_mode": "recorded_fixture",
"model_executed": False,
"command_executed": False,
"duration_ms": None,
"provider": "",
"model": "",
"usage": usage_payload({}, str(case.get("prompt", "")), output),
"score": grade["score"],
"passed_count": grade["passed_count"],
"failed_count": grade["failed_count"],
"failed_assertions": [item["id"] for item in grade["failed"]],
"output_sha256": hashlib.sha256(output.encode("utf-8")).hexdigest(),
"failure": "",
}
def command_run(
case: dict[str, Any],
variant: str,
assertions: list[dict[str, Any]],
command: list[str],
timeout_seconds: float,
) -> dict[str, Any]:
request = {
"case_id": str(case.get("id", "")),
"variant": variant,
"prompt": str(case.get("prompt", "")),
"input_files": case.get("input_files", []),
"metadata": case.get("metadata", {}),
"fixture_output": output_for_variant(case, variant),
"output_key": output_key(variant),
}
started = time.perf_counter()
try:
proc = subprocess.run(
command,
input=json.dumps(request, ensure_ascii=False),
capture_output=True,
text=True,
timeout=timeout_seconds,
check=False,
)
duration_ms = round((time.perf_counter() - started) * 1000, 2)
except subprocess.TimeoutExpired as exc:
return {
"case_id": request["case_id"],
"variant": variant,
"status": "fail",
"execution_mode": "command",
"model_executed": False,
"command_executed": True,
"duration_ms": round(timeout_seconds * 1000, 2),
"provider": "",
"model": "",
"usage": usage_payload({}, request["prompt"], ""),
"score": 0,
"passed_count": 0,
"failed_count": len(assertions),
"failed_assertions": [str(item.get("id", "assertion")) for item in assertions],
"output_sha256": "",
"failure": f"runner timed out after {timeout_seconds}s: {exc}",
}
output, payload = parse_runner_stdout(proc.stdout)
grade = grade_output(output, assertions)
execution_kind = str(payload.get("execution_kind", "command"))
provider = str(payload.get("provider", ""))
model = str(payload.get("model", ""))
model_executed = execution_kind == "model" and bool(model and provider)
return {
"case_id": request["case_id"],
"variant": variant,
"status": "pass" if proc.returncode == 0 and output else "fail",
"execution_mode": execution_kind if execution_kind in {"command", "model"} else "command",
"model_executed": model_executed,
"command_executed": True,
"duration_ms": duration_ms,
"provider": provider,
"model": model,
"usage": usage_payload(payload, request["prompt"], output),
"score": grade["score"] if output else 0,
"passed_count": grade["passed_count"] if output else 0,
"failed_count": grade["failed_count"] if output else len(assertions),
"failed_assertions": [item["id"] for item in grade["failed"]] if output else [str(item.get("id", "assertion")) for item in assertions],
"output_sha256": hashlib.sha256(output.encode("utf-8")).hexdigest() if output else "",
"failure": "" if proc.returncode == 0 and output else (proc.stderr.strip() or "runner returned no output"),
}
def build_summary(runs: list[dict[str, Any]]) -> dict[str, Any]:
variant_run_count = len(runs)
case_ids = sorted({item["case_id"] for item in runs})
baseline = [item for item in runs if item["variant"] == "baseline"]
with_skill = [item for item in runs if item["variant"] == "with_skill"]
baseline_average = sum(item["score"] for item in baseline) / len(baseline) if baseline else 0
with_skill_average = sum(item["score"] for item in with_skill) / len(with_skill) if with_skill else 0
regression_count = sum(
1
for case_id in case_ids
if max((item["score"] for item in with_skill if item["case_id"] == case_id), default=0)
< max((item["score"] for item in baseline if item["case_id"] == case_id), default=0)
)
failure_count = sum(1 for item in runs if item["status"] != "pass")
command_executed_count = sum(1 for item in runs if item.get("command_executed"))
model_executed_count = sum(1 for item in runs if item.get("model_executed"))
recorded_fixture_count = sum(1 for item in runs if item.get("execution_mode") == "recorded_fixture")
timing_observed_count = sum(1 for item in runs if item.get("duration_ms") is not None)
token_estimated_count = sum(1 for item in runs if item.get("usage", {}).get("estimated"))
token_observed_count = variant_run_count - token_estimated_count
return {
"case_count": len(case_ids),
"variant_run_count": variant_run_count,
"command_executed_count": command_executed_count,
"model_executed_count": model_executed_count,
"recorded_fixture_count": recorded_fixture_count,
"timing_observed_count": timing_observed_count,
"token_observed_count": token_observed_count,
"token_estimated_count": token_estimated_count,
"baseline_pass_rate": round(baseline_average, 2),
"with_skill_pass_rate": round(with_skill_average, 2),
"delta": round(with_skill_average - baseline_average, 2),
"regression_count": regression_count,
"failure_count": failure_count,
"gate_pass": failure_count == 0 and with_skill_average >= baseline_average and regression_count == 0,
}
def render_markdown(payload: dict[str, Any]) -> str:
summary = payload["summary"]
lines = [
"# Output Execution Runs",
"",
"This report records how output-eval variants were produced and whether timing or token evidence is observed or estimated.",
"",
f"- Cases: `{summary['case_count']}`",
f"- Variant runs: `{summary['variant_run_count']}`",
f"- Command executed: `{summary['command_executed_count']}`",
f"- Model executed: `{summary['model_executed_count']}`",
f"- Recorded fixtures: `{summary['recorded_fixture_count']}`",
f"- Timing observed: `{summary['timing_observed_count']}`",
f"- Token observed: `{summary['token_observed_count']}`",
f"- Token estimated: `{summary['token_estimated_count']}`",
f"- Delta: `{summary['delta']}`",
f"- Gate pass: `{summary['gate_pass']}`",
"",
]
if summary["model_executed_count"] == 0:
lines.extend(
[
"No model-executed runs are recorded yet.",
"",
"Use `python3 scripts/yao.py output-exec --provider-runner openai` or `--runner-command` with a reviewed provider-backed runner to replace recorded fixtures with real model output evidence.",
"",
]
)
if summary["command_executed_count"] > 0:
lines.extend(
[
"Command runner evidence is present. This proves the eval harness executed an external command, but it is not provider-backed model evidence unless the runner reports model metadata.",
"",
]
)
lines.extend(
[
"## Runs",
"",
"| Case | Variant | Mode | Model | Duration ms | Tokens | Score | Status |",
"| --- | --- | --- | --- | ---: | ---: | ---: | --- |",
]
)
for item in payload["runs"]:
usage = item.get("usage", {})
duration = "" if item.get("duration_ms") is None else str(item["duration_ms"])
model = item.get("model") or item.get("provider") or ""
lines.append(
f"| {item['case_id']} | {item['variant']} | {item['execution_mode']} | {model} | "
f"{duration} | {usage.get('total_tokens', 0)} | {item['score']} | {item['status']} |"
)
failures = [item for item in payload["runs"] if item.get("failure")]
if failures:
lines.extend(["", "## Failures", ""])
for item in failures:
lines.append(f"- `{item['case_id']}` `{item['variant']}`: {item['failure']}")
lines.extend(
[
"",
"## Next Fixes",
"",
"- Keep recorded fixtures as reproducible baselines, but do not describe them as model-executed evidence.",
"- Use `scripts/provider_output_eval_runner.py` for provider-backed holdout cases when release confidence depends on real generation behavior.",
"- Compare timing, token cost, and assertion deltas before promoting a skill to governed reuse.",
]
)
return "\n".join(lines).strip() + "\n"
def run_output_execution(
cases_path: Path,
output_json: Path,
output_md: Path,
runner_command: list[str],
timeout_seconds: float,
) -> dict[str, Any]:
cases = load_cases(cases_path)
validation_failures = [failure for case in cases for failure in validate_case(case, cases_path.parent)]
runs: list[dict[str, Any]] = []
if not validation_failures:
for case in cases:
assertions = case.get("assertions", []) if isinstance(case.get("assertions"), list) else []
for variant in VARIANTS:
if runner_command:
runs.append(command_run(case, variant, assertions, runner_command, timeout_seconds))
else:
runs.append(recorded_fixture_run(case, variant, assertions))
summary = build_summary(runs)
failures = validation_failures + [f"{item['case_id']} {item['variant']}: {item['failure']}" for item in runs if item.get("failure")]
payload = {
"schema_version": "1.0",
"ok": not failures and summary["gate_pass"],
"cases": display_path(cases_path),
"runner": {
"mode": "command" if runner_command else "recorded_fixture",
"command": display_command(runner_command),
"timeout_seconds": timeout_seconds if runner_command else None,
},
"summary": summary,
"runs": runs,
"failures": failures,
"artifacts": {
"json": display_path(output_json),
"markdown": display_path(output_md),
},
}
output_json.parent.mkdir(parents=True, exist_ok=True)
output_md.parent.mkdir(parents=True, exist_ok=True)
output_json.write_text(json.dumps(payload, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
output_md.write_text(render_markdown(payload), encoding="utf-8")
return payload
def main() -> None:
parser = argparse.ArgumentParser(description="Record output-eval execution evidence for static, command, or model-backed runs.")
parser.add_argument("--cases", default=str(DEFAULT_CASES))
parser.add_argument("--output-json", default=str(DEFAULT_OUTPUT_JSON))
parser.add_argument("--output-md", default=str(DEFAULT_OUTPUT_MD))
parser.add_argument("--runner-command", help="Command string or JSON string list. Receives a JSON request on stdin.")
parser.add_argument("--timeout-seconds", type=float, default=30.0)
args = parser.parse_args()
try:
runner_command = parse_runner_command(args.runner_command)
except (json.JSONDecodeError, ValueError) as exc:
payload = {
"schema_version": "1.0",
"ok": False,
"cases": display_path(Path(args.cases).resolve()),
"runner": {"mode": "invalid", "command": [], "timeout_seconds": args.timeout_seconds},
"summary": build_summary([]),
"runs": [],
"failures": [str(exc)],
"artifacts": {"json": display_path(Path(args.output_json).resolve()), "markdown": display_path(Path(args.output_md).resolve())},
}
output_json = Path(args.output_json).resolve()
output_md = Path(args.output_md).resolve()
output_json.parent.mkdir(parents=True, exist_ok=True)
output_md.parent.mkdir(parents=True, exist_ok=True)
output_json.write_text(json.dumps(payload, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
output_md.write_text(render_markdown(payload), encoding="utf-8")
print(json.dumps(payload, ensure_ascii=False, indent=2))
raise SystemExit(2)
payload = run_output_execution(
Path(args.cases).resolve(),
Path(args.output_json).resolve(),
Path(args.output_md).resolve(),
runner_command,
args.timeout_seconds,
)
print(json.dumps(payload, ensure_ascii=False, indent=2))
raise SystemExit(0 if payload["ok"] else 2)
if __name__ == "__main__":
main()