Spaces:
Runtime error
Runtime error
Commit ·
0457b55
1
Parent(s): a0c29cf
feat(cp7): proteus run --memory {none,generate,latest,<path>}
Browse files- proteus/cli.py +49 -0
- tests/cli/test_cli_memory.py +41 -0
proteus/cli.py
CHANGED
|
@@ -43,6 +43,14 @@ def _cmd_run(args: argparse.Namespace) -> int:
|
|
| 43 |
)
|
| 44 |
return 2
|
| 45 |
agent = VanillaAgent(provider)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 46 |
runner = SessionRunner(
|
| 47 |
args.scenario,
|
| 48 |
agent,
|
|
@@ -50,6 +58,8 @@ def _cmd_run(args: argparse.Namespace) -> int:
|
|
| 50 |
seed=args.seed,
|
| 51 |
play_turns=args.play_turns,
|
| 52 |
use_probe=not args.no_probe,
|
|
|
|
|
|
|
| 53 |
)
|
| 54 |
trace = runner.run()
|
| 55 |
written = append_trace(trace, args.out)
|
|
@@ -64,6 +74,36 @@ def _cmd_run(args: argparse.Namespace) -> int:
|
|
| 64 |
return 0
|
| 65 |
|
| 66 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 67 |
def _cmd_memory(args: argparse.Namespace) -> int:
|
| 68 |
try:
|
| 69 |
provider = make_provider(args.model)
|
|
@@ -236,6 +276,15 @@ def build_parser() -> argparse.ArgumentParser:
|
|
| 236 |
run.add_argument("--play-turns", type=int, default=15, dest="play_turns")
|
| 237 |
run.add_argument("--no-probe", action="store_true", dest="no_probe")
|
| 238 |
run.add_argument("--out", required=True, help="JSONL file to append the trace to")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 239 |
run.set_defaults(func=_cmd_run)
|
| 240 |
|
| 241 |
play = sub.add_parser("play", help="play a session as a human via stdin")
|
|
|
|
| 43 |
)
|
| 44 |
return 2
|
| 45 |
agent = VanillaAgent(provider)
|
| 46 |
+
memory, memory_ref, mem_err = _resolve_memory(
|
| 47 |
+
args.memory, provider=provider, agent=agent, scenario=args.scenario,
|
| 48 |
+
difficulty=Difficulty(args.difficulty), seed=args.seed,
|
| 49 |
+
memory_turns=args.memory_turns, memory_root=args.memory_root,
|
| 50 |
+
)
|
| 51 |
+
if mem_err is not None:
|
| 52 |
+
print(mem_err, file=sys.stderr)
|
| 53 |
+
return 2
|
| 54 |
runner = SessionRunner(
|
| 55 |
args.scenario,
|
| 56 |
agent,
|
|
|
|
| 58 |
seed=args.seed,
|
| 59 |
play_turns=args.play_turns,
|
| 60 |
use_probe=not args.no_probe,
|
| 61 |
+
memory=memory,
|
| 62 |
+
memory_ref=memory_ref,
|
| 63 |
)
|
| 64 |
trace = runner.run()
|
| 65 |
written = append_trace(trace, args.out)
|
|
|
|
| 74 |
return 0
|
| 75 |
|
| 76 |
|
| 77 |
+
def _resolve_memory(
|
| 78 |
+
mode: str, *, provider, agent, scenario: str, difficulty: Difficulty,
|
| 79 |
+
seed: int | None, memory_turns: int, memory_root: str,
|
| 80 |
+
):
|
| 81 |
+
"""Resolve --memory MODE to (checkpoint | None, memory_ref | None, error | None)."""
|
| 82 |
+
if mode == "none":
|
| 83 |
+
return None, None, None
|
| 84 |
+
if mode == "generate":
|
| 85 |
+
ckpt = generate_memory(
|
| 86 |
+
scenario, agent, difficulty=difficulty, seed=seed,
|
| 87 |
+
memory_turns=memory_turns, model_name=provider.model_name,
|
| 88 |
+
)
|
| 89 |
+
path = save_checkpoint(ckpt, root=memory_root)
|
| 90 |
+
return ckpt, str(path), None
|
| 91 |
+
if mode == "latest":
|
| 92 |
+
ckpt = latest_for_model(provider.model_name, root=memory_root)
|
| 93 |
+
if ckpt is None:
|
| 94 |
+
return None, None, (
|
| 95 |
+
f"no memory checkpoint for model {provider.model_name!r} "
|
| 96 |
+
f"under {memory_root!r}"
|
| 97 |
+
)
|
| 98 |
+
return ckpt, f"{ckpt.model}@{ckpt.created_at}", None
|
| 99 |
+
# otherwise treat MODE as a checkpoint path
|
| 100 |
+
try:
|
| 101 |
+
ckpt = load_checkpoint(mode)
|
| 102 |
+
except FileNotFoundError:
|
| 103 |
+
return None, None, f"memory checkpoint not found: {mode}"
|
| 104 |
+
return ckpt, mode, None
|
| 105 |
+
|
| 106 |
+
|
| 107 |
def _cmd_memory(args: argparse.Namespace) -> int:
|
| 108 |
try:
|
| 109 |
provider = make_provider(args.model)
|
|
|
|
| 276 |
run.add_argument("--play-turns", type=int, default=15, dest="play_turns")
|
| 277 |
run.add_argument("--no-probe", action="store_true", dest="no_probe")
|
| 278 |
run.add_argument("--out", required=True, help="JSONL file to append the trace to")
|
| 279 |
+
run.add_argument(
|
| 280 |
+
"--memory", default="none",
|
| 281 |
+
help="memory pre-roll: none (default) | generate | latest | <checkpoint path>",
|
| 282 |
+
)
|
| 283 |
+
run.add_argument("--memory-turns", type=int, default=10, dest="memory_turns")
|
| 284 |
+
run.add_argument(
|
| 285 |
+
"--memory-root", default="runs/memory", dest="memory_root",
|
| 286 |
+
help="root dir for generate/latest checkpoints",
|
| 287 |
+
)
|
| 288 |
run.set_defaults(func=_cmd_run)
|
| 289 |
|
| 290 |
play = sub.add_parser("play", help="play a session as a human via stdin")
|
tests/cli/test_cli_memory.py
CHANGED
|
@@ -23,3 +23,44 @@ def test_memory_subcommand_unknown_model_exits_2(tmp_path, capsys):
|
|
| 23 |
])
|
| 24 |
assert rc == 2
|
| 25 |
assert "bogusprovider" in capsys.readouterr().err
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 23 |
])
|
| 24 |
assert rc == 2
|
| 25 |
assert "bogusprovider" in capsys.readouterr().err
|
| 26 |
+
|
| 27 |
+
|
| 28 |
+
from proteus.runtime import read_traces
|
| 29 |
+
|
| 30 |
+
|
| 31 |
+
def test_run_memory_generate_sets_memory_ref(tmp_path):
|
| 32 |
+
out = tmp_path / "t.jsonl"
|
| 33 |
+
rc = main([
|
| 34 |
+
"run", "--scenario", "predator_evade", "--model", "fake:demo",
|
| 35 |
+
"--difficulty", "easy", "--seed", "42", "--play-turns", "3",
|
| 36 |
+
"--no-probe", "--memory", "generate", "--memory-turns", "4",
|
| 37 |
+
"--memory-root", str(tmp_path / "mem"), "--out", str(out),
|
| 38 |
+
])
|
| 39 |
+
assert rc == 0
|
| 40 |
+
traces = read_traces(out)
|
| 41 |
+
assert traces[0].memory_ref is not None
|
| 42 |
+
# the turn-1 observation carries the memory block
|
| 43 |
+
assert "MEMORY" in traces[0].turns[0].observation
|
| 44 |
+
|
| 45 |
+
|
| 46 |
+
def test_run_memory_latest_missing_exits_2(tmp_path, capsys):
|
| 47 |
+
out = tmp_path / "t.jsonl"
|
| 48 |
+
rc = main([
|
| 49 |
+
"run", "--scenario", "predator_evade", "--model", "fake:demo",
|
| 50 |
+
"--difficulty", "easy", "--seed", "42", "--play-turns", "3",
|
| 51 |
+
"--no-probe", "--memory", "latest",
|
| 52 |
+
"--memory-root", str(tmp_path / "mem"), "--out", str(out),
|
| 53 |
+
])
|
| 54 |
+
assert rc == 2
|
| 55 |
+
assert "memory" in capsys.readouterr().err.lower()
|
| 56 |
+
|
| 57 |
+
|
| 58 |
+
def test_run_memory_none_is_default(tmp_path):
|
| 59 |
+
out = tmp_path / "t.jsonl"
|
| 60 |
+
rc = main([
|
| 61 |
+
"run", "--scenario", "predator_evade", "--model", "fake:demo",
|
| 62 |
+
"--difficulty", "easy", "--seed", "42", "--play-turns", "3",
|
| 63 |
+
"--no-probe", "--out", str(out),
|
| 64 |
+
])
|
| 65 |
+
assert rc == 0
|
| 66 |
+
assert read_traces(out)[0].memory_ref is None
|