79 lines
3.6 KiB
Python
79 lines
3.6 KiB
Python
#!/usr/bin/env python3
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
import os
|
|
import subprocess
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
REPO_ROOT = Path(__file__).resolve().parents[2]
|
|
if str(REPO_ROOT) not in sys.path:
|
|
sys.path.insert(0, str(REPO_ROOT))
|
|
|
|
from evennia_tools.training import WORLD_BASICS_STEPS, example_eval_path
|
|
from scripts.evennia import evennia_mcp_server as bridge
|
|
|
|
EVENNIA_BIN = Path.home() / '.timmy' / 'evennia' / 'venv' / 'bin' / 'evennia'
|
|
GAME_DIR = Path.home() / '.timmy' / 'evennia' / 'timmy_world'
|
|
EVAL_USERNAME = os.environ.get("TIMMY_EVENNIA_EVAL_USERNAME", "TimmyEval")
|
|
EVAL_PASSWORD = os.environ.get("TIMMY_EVENNIA_EVAL_PASSWORD", "timmy-eval-world-dev")
|
|
|
|
|
|
def reset_timmy_to_gate():
|
|
env = dict(**os.environ)
|
|
env['PYTHONPATH'] = str(REPO_ROOT) + ':' + env.get('PYTHONPATH', '')
|
|
code = f"from evennia.accounts.models import AccountDB; from evennia.accounts.accounts import DefaultAccount; from evennia.utils.search import search_object; acc=AccountDB.objects.filter(username='{EVAL_USERNAME}').first(); acc = acc or DefaultAccount.create(username='{EVAL_USERNAME}', password='{EVAL_PASSWORD}')[0]; char=list(acc.characters)[0]; gate=search_object('Gate', exact=True)[0]; char.home=gate; char.move_to(gate, quiet=True, move_hooks=False); char.save(); print('RESET_OK')"
|
|
subprocess.run([str(EVENNIA_BIN), 'shell', '-c', code], cwd=GAME_DIR, env=env, check=True, capture_output=True, text=True, timeout=120)
|
|
|
|
|
|
def normalize_to_gate() -> None:
|
|
output = bridge._observe("timmy").get("output", "")
|
|
if not output:
|
|
output = bridge._command("look", name="timmy", wait_ms=400).get("output", "")
|
|
for _ in range(6):
|
|
if "Gate" in output:
|
|
return
|
|
if "Courtyard" in output:
|
|
output = bridge._command("gate", name="timmy", wait_ms=400).get("output", "")
|
|
continue
|
|
if any(room in output for room in ("Workshop", "Archive", "Chapel")):
|
|
output = bridge._command("courtyard", name="timmy", wait_ms=400).get("output", "")
|
|
continue
|
|
output = bridge._command("look", name="timmy", wait_ms=400).get("output", "")
|
|
|
|
|
|
def main():
|
|
try:
|
|
bridge._disconnect("timmy")
|
|
except Exception:
|
|
pass
|
|
reset_timmy_to_gate()
|
|
bridge._save_bound_session_id(os.environ.get("TIMMY_EVENNIA_EVAL_SESSION_ID", "eval-evennia-world-basics"))
|
|
bridge._connect(name="timmy", username=EVAL_USERNAME, password=EVAL_PASSWORD)
|
|
normalize_to_gate()
|
|
results = []
|
|
for step in WORLD_BASICS_STEPS:
|
|
command = step["command"]
|
|
expected = step["expected"]
|
|
res = bridge._command(command, name="timmy", wait_ms=400)
|
|
output = res.get("output", "")
|
|
passed = all(token in output for token in expected)
|
|
results.append({"command": command, "expected": expected, "passed": passed, "output_excerpt": output[:300]})
|
|
bridge._disconnect("timmy")
|
|
summary = {
|
|
"passed": all(item["passed"] for item in results),
|
|
"checks": results,
|
|
"orientation": next((item["passed"] for item in results if item["command"] == "look"), False),
|
|
"navigation": all(item["passed"] for item in results if item["command"] in ("enter", "workshop", "courtyard", "chapel")),
|
|
"object_inspection": next((item["passed"] for item in results if item["command"] == "look Book of the Soul"), False),
|
|
}
|
|
out = example_eval_path(REPO_ROOT)
|
|
out.parent.mkdir(parents=True, exist_ok=True)
|
|
out.write_text(json.dumps(summary, indent=2), encoding="utf-8")
|
|
print(json.dumps({"eval_path": str(out), **summary}, indent=2))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|