"""Read-only training dashboard and paired native Asterix simulator.""" import json import os from pathlib import Path from functools import lru_cache from fastapi import FastAPI,HTTPException from fastapi.responses import HTMLResponse from huggingface_hub import hf_hub_download import uvicorn from crossgame.asterix import Policy,play CONFIG=json.loads(Path(__file__).with_name('config.json').read_text()) app=FastAPI() @app.get('/health') def health():return {'ok':True,'source_commit':os.environ.get('SOURCE_COMMIT'),'game':'asterix'} @app.get('/api/status') def status(): try:return json.loads(Path(hf_hub_download(CONFIG['dataset'],'latest.json',repo_type='dataset')).read_text()) except Exception:return {'status':'waiting','curve':[],'releases':{}} @lru_cache(maxsize=4) def model(repo,revision):return Policy.load(hf_hub_download(repo,'policy_weights.npz',revision=revision)) @app.get('/api/episode') def episode(seed:int=5,variant:str='base'): if not 0<=seed<2**31 or variant not in ('base','improved'):raise HTTPException(400,'Invalid seed or policy') if variant=='base': policy=Policy.load(Path(__file__).with_name('assets')/CONFIG.get('initial_checkpoint','asterix-base.npz'));revision=CONFIG.get('continuation',{}).get('revision','upstream-pinned') else: release=status().get('releases',{}).get('improved') if not release:raise HTTPException(409,'No published candidate is available yet') policy=model(release['repo'],release['revision']);revision=release['revision'] if policy.fingerprint()!=release['policy_hash']:raise HTTPException(503,'Checkpoint identity mismatch') ep=play(policy,seed,CONFIG['horizon'],trace=True) # Compact public frames omit the large internal RNG state; raw dataset keeps it. frames=[{k:s[k] for k in ['step','total','dead','player','entities']} for s in ep['worlds']+[ep['final']]] return dict(seed=seed,total=ep['total'],steps=ep['steps'],reason=ep['reason'],actions=ep['actions'], frames=frames,policy_hash=policy.fingerprint(),revision=revision) PAGE='''
FAILURE IS ALL YOU NEED · CROSS-GAME EXPERIMENT
Asterix: collect gold, avoid enemies. Original MinAtar rules and native sticky actions remain intact. Run 03 improves measured average return over run 02. It was released under a revised average-return rule despite individual regressions; the original strict audit result remains visible below.
Green is the player, gold is treasure, red is danger. Each game uses the same starting seed. Published inference uses the declared average-return criterion; some games may score worse or end earlier.
Development and selection gate seeds are reused. The final audit is separate and runs after selection ends. This is a 1,000-step greedy-policy pilot, not a reproduction of the upstream 10,000-step sampled-action score. Base weights: Rikiya Takehi and collaborators, CC BY 4.0. Game: Kenny Young and Tian Tian, MinAtar 1.0.15, GPL-3.0.
'''.replace('__DATASET__',CONFIG['dataset']) @app.get('/',response_class=HTMLResponse) def home():return PAGE if __name__=='__main__':uvicorn.run(app,host='0.0.0.0',port=7860)