-
Notifications
You must be signed in to change notification settings - Fork 357
Expand file tree
/
Copy pathevaluate-agent.py
More file actions
108 lines (84 loc) · 3.23 KB
/
Copy pathevaluate-agent.py
File metadata and controls
108 lines (84 loc) · 3.23 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
import argparse
import importlib
import json
import sys
import tempfile
from dataclasses import asdict
from pathlib import Path
SOURCE_ROOT = Path(__file__).resolve().parent / "src"
def build_parser() -> argparse.ArgumentParser:
"""Define the inert Week 4 evaluation inspection commands."""
parser = argparse.ArgumentParser(
description=(
"Inspect or statically grade an inert Week 4 task package without "
"running an agent or candidate code."
)
)
parser.add_argument(
"--solution",
choices=["tiny_llm", "tiny_llm_ref", "ref"],
default="tiny_llm_ref",
help="evaluation implementation to use (default: tiny_llm_ref)",
)
commands = parser.add_subparsers(dest="command", required=True)
inspect = commands.add_parser(
"inspect",
help="validate a package and print only its public manifest",
)
inspect.add_argument("package", type=Path)
grade = commands.add_parser(
"grade",
help="statically grade a freshly staged, unchanged package workspace",
)
grade.add_argument("package", type=Path)
return parser
def load_evaluation_api(solution: str):
"""Load course evaluation types without importing any candidate module."""
source = str(SOURCE_ROOT)
if source not in sys.path:
sys.path.insert(0, source)
package = "tiny_llm_ref" if solution == "ref" else solution
return importlib.import_module(f"{package}.agent.evaluation")
def print_json(value) -> None:
"""Render stable machine-readable CLI output."""
print(json.dumps(value, ensure_ascii=True, indent=2, sort_keys=True))
def inspect_package(api, package_path: Path) -> int:
"""Validate a package while keeping held-out expected values private."""
package = api.TaskPackage.load(package_path)
print_json(asdict(package.manifest))
return 0
def grade_unchanged_package(api, package_path: Path) -> int:
"""Grade an untouched frozen stage using declarative checks only."""
package = api.TaskPackage.load(package_path)
with tempfile.TemporaryDirectory(prefix="tiny-llm-static-eval-") as temporary:
scratch = Path(temporary)
staged = package.stage(scratch / "stage")
candidate = staged.freeze(scratch / "candidate")
report = api.StaticHeldOutGrader().grade(staged, candidate)
print_json(
{
"grade": asdict(report),
"task_id": package.manifest.id,
}
)
if report.status == "passed":
return 0
if report.status == "failed":
return 1
return 2
def main(argv: list[str] | None = None) -> int:
"""Run a non-executing package inspection or baseline grade."""
parser = build_parser()
args = parser.parse_args(argv)
try:
api = load_evaluation_api(args.solution)
if args.command == "inspect":
return inspect_package(api, args.package)
if args.command == "grade":
return grade_unchanged_package(api, args.package)
except (AttributeError, ImportError, OSError, ValueError) as error:
print(f"error: {error}", file=sys.stderr)
return 2
parser.error(f"unsupported command: {args.command}")
if __name__ == "__main__":
raise SystemExit(main())