cogames 0.3.68__tar.gz → 0.3.69__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {cogames-0.3.68/src/cogames.egg-info → cogames-0.3.69}/PKG-INFO +2 -2
- {cogames-0.3.68 → cogames-0.3.69}/pyproject.toml +1 -1
- cogames-0.3.69/src/cogames/cli/submit.py +331 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/main.py +79 -49
- {cogames-0.3.68 → cogames-0.3.69/src/cogames.egg-info}/PKG-INFO +2 -2
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames.egg-info/requires.txt +1 -1
- {cogames-0.3.68 → cogames-0.3.69}/tests/test_upload_cli.py +42 -36
- {cogames-0.3.68 → cogames-0.3.69}/tests/test_upload_policy_bundles.py +13 -24
- cogames-0.3.68/src/cogames/cli/submit.py +0 -611
- {cogames-0.3.68 → cogames-0.3.69}/CHANGELOG.md +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/LICENSE +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/MISSION.md +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/README.ipynb +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/README.md +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/README.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/TECHNICAL_MANUAL.md +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/assets/charger.png +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/assets/cvc-reel.gif +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/assets/cvc-snap.png +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/assets/extractor.png +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/assets/hub.png +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/assets/showoff.gif +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/setup.cfg +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/__init__.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/auth.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/cli/base.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/cli/client.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/cli/docsync/__init__.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/cli/docsync/_nb_md_directive_processing.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/cli/docsync/_nb_md_sync.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/cli/docsync/_nb_py_sync.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/cli/docsync/_three_way_sync.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/cli/docsync/_utils.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/cli/docsync/docsync.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/cli/leaderboard.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/cli/login.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/cli/mission.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/cli/policy.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/cli/utils.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/cogs_vs_clips/__init__.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/cogs_vs_clips/clip_difficulty.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/cogs_vs_clips/clips.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/cogs_vs_clips/cog.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/cogs_vs_clips/cogsguard_curriculum.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/cogs_vs_clips/cogsguard_tutorial.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/cogs_vs_clips/config.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/cogs_vs_clips/docs/cogs_vs_clips_mapgen.md +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/cogs_vs_clips/evals/README.md +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/cogs_vs_clips/evals/cogsguard_evals.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/cogs_vs_clips/evals/diagnostic_evals.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/cogs_vs_clips/evals/difficulty_variants.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/cogs_vs_clips/evals/integrated_evals.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/cogs_vs_clips/evals/spanning_evals.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/cogs_vs_clips/mission.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/cogs_vs_clips/missions.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/cogs_vs_clips/reward_variants.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/cogs_vs_clips/sites.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/cogs_vs_clips/stations.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/cogs_vs_clips/team.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/cogs_vs_clips/terrain.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/cogs_vs_clips/variants.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/cogs_vs_clips/weather.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/core.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/curricula.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/device.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/docs/SCRIPTED_AGENT.md +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/evaluate.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/game.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/canidate1_1000.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/canidate1_1000_stations.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/canidate1_500.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/canidate1_500_stations.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/canidate2_1000.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/canidate2_1000_stations.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/canidate2_500.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/canidate2_500_stations.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/canidate3_1000.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/canidate3_1000_stations.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/canidate3_500.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/canidate3_500_stations.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/canidate4_500.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/canidate4_500_stations.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/cave_base_50.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/diagnostic_evals/diagnostic_agile.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/diagnostic_evals/diagnostic_agile_hard.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/diagnostic_evals/diagnostic_charge_up.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/diagnostic_evals/diagnostic_charge_up_hard.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/diagnostic_evals/diagnostic_chest_navigation1.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/diagnostic_evals/diagnostic_chest_navigation1_hard.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/diagnostic_evals/diagnostic_chest_navigation2.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/diagnostic_evals/diagnostic_chest_navigation2_hard.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/diagnostic_evals/diagnostic_chest_navigation3.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/diagnostic_evals/diagnostic_chest_navigation3_hard.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/diagnostic_evals/diagnostic_chest_near.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/diagnostic_evals/diagnostic_chest_search.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/diagnostic_evals/diagnostic_chest_search_hard.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/diagnostic_evals/diagnostic_extract_lab.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/diagnostic_evals/diagnostic_extract_lab_hard.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/diagnostic_evals/diagnostic_memory.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/diagnostic_evals/diagnostic_memory_hard.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/diagnostic_evals/diagnostic_radial.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/diagnostic_evals/diagnostic_radial_hard.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/diagnostic_evals/diagnostic_resource_lab.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/diagnostic_evals/diagnostic_unclip.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/evals/eval_balanced_spread.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/evals/eval_clip_oxygen.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/evals/eval_collect_resources.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/evals/eval_collect_resources_hard.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/evals/eval_collect_resources_medium.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/evals/eval_divide_and_conquer.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/evals/eval_energy_starved.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/evals/eval_multi_coordinated_collect_hard.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/evals/eval_oxygen_bottleneck.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/evals/eval_single_use_world.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/evals/extractor_hub_100x100.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/evals/extractor_hub_30x30.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/evals/extractor_hub_50x50.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/evals/extractor_hub_70x70.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/evals/extractor_hub_80x80.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/machina_100_stations.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/machina_200_stations.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/machina_200_stations_small.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/machina_eval_exp01.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/machina_eval_template_large.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/machinatrainer4agents.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/machinatrainer4agentsbase.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/machinatrainerbig.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/machinatrainersmall.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/planky_evals/aligner_avoid_aoe.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/planky_evals/aligner_full_cycle.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/planky_evals/aligner_gear.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/planky_evals/aligner_hearts.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/planky_evals/aligner_junction.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/planky_evals/exploration_distant.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/planky_evals/maze.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/planky_evals/miner_best_resource.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/planky_evals/miner_deposit.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/planky_evals/miner_extract.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/planky_evals/miner_full_cycle.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/planky_evals/miner_gear.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/planky_evals/multi_role.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/planky_evals/resource_chain.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/planky_evals/scout_explore.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/planky_evals/scout_gear.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/planky_evals/scrambler_full_cycle.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/planky_evals/scrambler_gear.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/planky_evals/scrambler_target.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/planky_evals/stuck_corridor.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/planky_evals/survive_retreat.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/training_facility_clipped.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/training_facility_open_1.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/training_facility_open_2.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/training_facility_open_3.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/training_facility_tight_4.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/training_facility_tight_5.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/vanilla_large.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/vanilla_small.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/maps/zelda.map +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/pickup.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/play.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/policy/__init__.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/policy/chaos_monkey.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/policy/nim_agents/__init__.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/policy/nim_agents/agents.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/policy/nim_agents/thinky_eval.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/policy/pufferlib_policy.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/policy/signal_handler.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/policy/starter_agent.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/policy/trainable_policy_template.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/py.typed +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/train.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames/verbose.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames.egg-info/SOURCES.txt +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames.egg-info/dependency_links.txt +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames.egg-info/entry_points.txt +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/cogames.egg-info/top_level.txt +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/metta_alo/__init__.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/metta_alo/py.typed +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/src/metta_alo/scoring.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/tests/docsync/conftest.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/tests/docsync/helpers.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/tests/docsync/test_docsync_all.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/tests/docsync/test_docsync_check.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/tests/docsync/test_docsync_nb_to_md.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/tests/docsync/test_docsync_nb_to_py.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/tests/docsync/test_docsync_py_to_nb.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/tests/metta_alo/test_scoring.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/tests/test_all_games_describe.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/tests/test_all_games_eval.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/tests/test_all_games_play.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/tests/test_chaos_monkey.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/tests/test_cli.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/tests/test_cogs_vs_clips.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/tests/test_cogsguard_eval_missions.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/tests/test_policy_cli_parsing.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/tests/test_procedural_maps.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/tests/test_train_integration.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/tests/test_train_vector_alignment.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/tutorials/01_MAKE_POLICY.ipynb +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/tutorials/01_MAKE_POLICY.md +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/tutorials/01_MAKE_POLICY.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/tutorials/02_TRAIN.ipynb +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/tutorials/02_TRAIN.md +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/tutorials/02_TRAIN.py +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/tutorials/03_SUBMIT.ipynb +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/tutorials/03_SUBMIT.md +0 -0
- {cogames-0.3.68 → cogames-0.3.69}/tutorials/03_SUBMIT.py +0 -0
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cogames
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.69
|
|
4
4
|
Summary: Multi-agent cooperative games
|
|
5
5
|
Classifier: Programming Language :: Python :: 3
|
|
6
6
|
Classifier: Programming Language :: Python :: 3.12
|
|
7
7
|
Requires-Python: <3.13,>=3.12
|
|
8
8
|
Description-Content-Type: text/markdown
|
|
9
9
|
License-File: LICENSE
|
|
10
|
-
Requires-Dist: mettagrid==0.2.0.
|
|
10
|
+
Requires-Dist: mettagrid==0.2.0.83
|
|
11
11
|
Requires-Dist: packaging>=24.0.0
|
|
12
12
|
Requires-Dist: pufferlib-core
|
|
13
13
|
Requires-Dist: pydantic>=2.11.5
|
|
@@ -9,7 +9,7 @@ readme = "README.md"
|
|
|
9
9
|
requires-python = ">=3.12,<3.13"
|
|
10
10
|
classifiers = ["Programming Language :: Python :: 3", "Programming Language :: Python :: 3.12"]
|
|
11
11
|
dependencies = [
|
|
12
|
-
"mettagrid==0.2.0.
|
|
12
|
+
"mettagrid==0.2.0.83",
|
|
13
13
|
"packaging>=24.0.0",
|
|
14
14
|
"pufferlib-core",
|
|
15
15
|
"pydantic>=2.11.5",
|
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
"""Policy submission command for CoGames."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import os
|
|
6
|
+
import shutil
|
|
7
|
+
import subprocess
|
|
8
|
+
import sys
|
|
9
|
+
import tempfile
|
|
10
|
+
import uuid
|
|
11
|
+
import zipfile
|
|
12
|
+
from dataclasses import dataclass
|
|
13
|
+
from pathlib import Path
|
|
14
|
+
|
|
15
|
+
import httpx
|
|
16
|
+
import typer
|
|
17
|
+
|
|
18
|
+
from cogames.cli.base import console
|
|
19
|
+
from cogames.cli.client import TournamentServerClient
|
|
20
|
+
from cogames.cli.login import DEFAULT_COGAMES_SERVER
|
|
21
|
+
from cogames.cli.policy import PolicySpec, get_policy_spec
|
|
22
|
+
from mettagrid.config.mettagrid_config import MettaGridConfig
|
|
23
|
+
from mettagrid.policy.submission import POLICY_SPEC_FILENAME, SubmissionPolicySpec
|
|
24
|
+
from mettagrid.runner.episode_runner import run_episode_isolated
|
|
25
|
+
from mettagrid.runner.types import EpisodeSpec
|
|
26
|
+
from mettagrid.util.uri_resolvers.schemes import localize_uri, parse_uri
|
|
27
|
+
|
|
28
|
+
DEFAULT_SUBMIT_SERVER = "https://api.observatory.softmax-research.net"
|
|
29
|
+
RESULTS_URL = "https://www.softmax.com/alignmentleague"
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
@dataclass
|
|
33
|
+
class UploadResult:
|
|
34
|
+
policy_version_id: uuid.UUID
|
|
35
|
+
name: str
|
|
36
|
+
version: int
|
|
37
|
+
pools: list[str] | None = None
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def _resolve_path_within_cwd(path_str: str, cwd: Path) -> Path:
|
|
41
|
+
"""Resolve a path and return it relative to CWD. Raises if path escapes CWD."""
|
|
42
|
+
raw_path = Path(path_str).expanduser()
|
|
43
|
+
resolved = raw_path.resolve() if raw_path.is_absolute() else (cwd / raw_path).resolve()
|
|
44
|
+
if not resolved.is_relative_to(cwd):
|
|
45
|
+
console.print(f"[red]Error:[/red] Path must be within the current directory: {path_str}")
|
|
46
|
+
raise ValueError(f"Path escapes CWD: {path_str}")
|
|
47
|
+
return resolved.relative_to(cwd)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def validate_paths(paths: list[str]) -> list[Path]:
|
|
51
|
+
"""Validate paths exist and are within CWD, return them as relative paths."""
|
|
52
|
+
cwd = Path.cwd().resolve()
|
|
53
|
+
validated_paths = []
|
|
54
|
+
for path_str in paths:
|
|
55
|
+
relative = _resolve_path_within_cwd(path_str, cwd)
|
|
56
|
+
resolved = cwd / relative
|
|
57
|
+
if not resolved.exists():
|
|
58
|
+
console.print(f"[red]Error:[/red] Path does not exist: {path_str}")
|
|
59
|
+
raise FileNotFoundError(f"Path not found: {path_str}")
|
|
60
|
+
validated_paths.append(relative)
|
|
61
|
+
return validated_paths
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def _zip_directory_to(src: Path, dest: Path) -> None:
|
|
65
|
+
with zipfile.ZipFile(dest, "w", zipfile.ZIP_DEFLATED) as zipf:
|
|
66
|
+
for file_path in src.rglob("*"):
|
|
67
|
+
if file_path.is_file():
|
|
68
|
+
zipf.write(file_path, arcname=file_path.relative_to(src))
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def _collect_ancestor_init_files(include_files: list[Path]) -> list[Path]:
|
|
72
|
+
found: set[Path] = set()
|
|
73
|
+
for path in include_files:
|
|
74
|
+
parent = path.parent
|
|
75
|
+
while parent != Path(".") and parent != parent.parent:
|
|
76
|
+
init = parent / "__init__.py"
|
|
77
|
+
if init.is_file():
|
|
78
|
+
found.add(init)
|
|
79
|
+
parent = parent.parent
|
|
80
|
+
return sorted(found)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def create_submission_zip(
|
|
84
|
+
include_files: list[Path],
|
|
85
|
+
policy_spec: PolicySpec,
|
|
86
|
+
setup_script: str | None = None,
|
|
87
|
+
) -> Path:
|
|
88
|
+
"""Create a zip file containing all include-files.
|
|
89
|
+
|
|
90
|
+
Maintains directory structure exactly as provided.
|
|
91
|
+
Returns path to created zip file.
|
|
92
|
+
"""
|
|
93
|
+
zip_fd, zip_path = tempfile.mkstemp(suffix=".zip", prefix="cogames_submission_")
|
|
94
|
+
os.close(zip_fd)
|
|
95
|
+
|
|
96
|
+
submission_spec = SubmissionPolicySpec(
|
|
97
|
+
class_path=policy_spec.class_path,
|
|
98
|
+
data_path=policy_spec.data_path,
|
|
99
|
+
init_kwargs=policy_spec.init_kwargs,
|
|
100
|
+
setup_script=setup_script,
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
all_files: dict[str, Path] = {}
|
|
104
|
+
for init_path in _collect_ancestor_init_files(include_files):
|
|
105
|
+
all_files[str(init_path)] = init_path
|
|
106
|
+
for file_path in include_files:
|
|
107
|
+
if file_path.is_dir():
|
|
108
|
+
for root, _, files in os.walk(file_path):
|
|
109
|
+
for file in files:
|
|
110
|
+
full = Path(root) / file
|
|
111
|
+
all_files[str(full)] = full
|
|
112
|
+
else:
|
|
113
|
+
all_files[str(file_path)] = file_path
|
|
114
|
+
|
|
115
|
+
with zipfile.ZipFile(zip_path, "w", zipfile.ZIP_DEFLATED) as zipf:
|
|
116
|
+
zipf.writestr(data=submission_spec.model_dump_json(), zinfo_or_arcname=POLICY_SPEC_FILENAME)
|
|
117
|
+
for arcname, path in all_files.items():
|
|
118
|
+
zipf.write(path, arcname=arcname)
|
|
119
|
+
|
|
120
|
+
return Path(zip_path)
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def create_bundle(
|
|
124
|
+
ctx: typer.Context,
|
|
125
|
+
policy: str,
|
|
126
|
+
output: Path,
|
|
127
|
+
include_files: list[str] | None = None,
|
|
128
|
+
init_kwargs: dict[str, str] | None = None,
|
|
129
|
+
setup_script: str | None = None,
|
|
130
|
+
) -> Path:
|
|
131
|
+
# TODO: Unify the two paths below. For URI inputs, extract the PolicySpec from the
|
|
132
|
+
# bundle so we can apply init_kwargs/include_files/setup_script, then re-zip.
|
|
133
|
+
local = localize_uri(policy) if parse_uri(policy, allow_none=True, default_scheme=None) else None
|
|
134
|
+
if local is not None:
|
|
135
|
+
if init_kwargs or include_files or setup_script:
|
|
136
|
+
console.print("[red]Error:[/red] Extra files/kwargs are not supported with bundle URIs.")
|
|
137
|
+
raise typer.Exit(1)
|
|
138
|
+
console.print(f"[dim]Packaging existing bundle: {local}[/dim]")
|
|
139
|
+
if local.is_dir():
|
|
140
|
+
_zip_directory_to(local, output)
|
|
141
|
+
else:
|
|
142
|
+
shutil.copy2(local, output)
|
|
143
|
+
console.print(f"[dim]Bundle size: {output.stat().st_size / 1024:.0f} KB[/dim]")
|
|
144
|
+
return output
|
|
145
|
+
|
|
146
|
+
policy_spec = get_policy_spec(ctx, policy)
|
|
147
|
+
console.print(f"[dim]Policy class: {policy_spec.class_path}[/dim]")
|
|
148
|
+
|
|
149
|
+
if init_kwargs:
|
|
150
|
+
merged_kwargs = {**policy_spec.init_kwargs, **init_kwargs}
|
|
151
|
+
policy_spec = PolicySpec(
|
|
152
|
+
class_path=policy_spec.class_path,
|
|
153
|
+
data_path=policy_spec.data_path,
|
|
154
|
+
init_kwargs=merged_kwargs,
|
|
155
|
+
)
|
|
156
|
+
|
|
157
|
+
if policy_spec.init_kwargs:
|
|
158
|
+
console.print(f"[dim]Init kwargs: {policy_spec.init_kwargs}[/dim]")
|
|
159
|
+
|
|
160
|
+
cwd = Path.cwd().resolve()
|
|
161
|
+
if policy_spec.data_path:
|
|
162
|
+
data_rel = str(_resolve_path_within_cwd(policy_spec.data_path, cwd))
|
|
163
|
+
policy_spec = PolicySpec(
|
|
164
|
+
class_path=policy_spec.class_path,
|
|
165
|
+
data_path=data_rel,
|
|
166
|
+
init_kwargs=policy_spec.init_kwargs,
|
|
167
|
+
)
|
|
168
|
+
console.print(f"[dim]Data path: {data_rel}[/dim]")
|
|
169
|
+
|
|
170
|
+
setup_script_rel: str | None = None
|
|
171
|
+
if setup_script:
|
|
172
|
+
setup_script_rel = str(_resolve_path_within_cwd(setup_script, cwd))
|
|
173
|
+
console.print(f"[dim]Setup script: {setup_script_rel}[/dim]")
|
|
174
|
+
|
|
175
|
+
files_to_include = []
|
|
176
|
+
if policy_spec.data_path:
|
|
177
|
+
files_to_include.append(policy_spec.data_path)
|
|
178
|
+
if setup_script_rel:
|
|
179
|
+
files_to_include.append(setup_script_rel)
|
|
180
|
+
if include_files:
|
|
181
|
+
files_to_include.extend(include_files)
|
|
182
|
+
|
|
183
|
+
validated_paths: list[Path] = []
|
|
184
|
+
if files_to_include:
|
|
185
|
+
validated_paths = validate_paths(files_to_include)
|
|
186
|
+
console.print(f"[dim]Including {len(validated_paths)} file(s)[/dim]")
|
|
187
|
+
|
|
188
|
+
tmp_zip = create_submission_zip(validated_paths, policy_spec, setup_script=setup_script_rel)
|
|
189
|
+
shutil.move(str(tmp_zip), str(output))
|
|
190
|
+
console.print(f"[dim]Bundle size: {output.stat().st_size / 1024:.0f} KB[/dim]")
|
|
191
|
+
return output
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
def validate_bundle(policy_uri: str, env_cfg: MettaGridConfig) -> None:
|
|
195
|
+
"""Validate a policy bundle by running a short episode in process isolation."""
|
|
196
|
+
env_cfg.game.max_steps = 10
|
|
197
|
+
|
|
198
|
+
spec = EpisodeSpec(
|
|
199
|
+
policy_uris=[policy_uri],
|
|
200
|
+
assignments=[0] * env_cfg.game.num_agents,
|
|
201
|
+
env=env_cfg,
|
|
202
|
+
seed=42,
|
|
203
|
+
max_action_time_ms=10000,
|
|
204
|
+
)
|
|
205
|
+
|
|
206
|
+
with tempfile.NamedTemporaryFile(suffix=".json", delete=True) as results_file:
|
|
207
|
+
res = run_episode_isolated(spec, Path(results_file.name))
|
|
208
|
+
console.print(f"[dim]Ran for {res.steps} steps[/dim]")
|
|
209
|
+
|
|
210
|
+
non_noop_actions = sum(
|
|
211
|
+
v for k, v in res.stats["agent"][0].items() if k.startswith("action.") and ".noop." not in k
|
|
212
|
+
)
|
|
213
|
+
if non_noop_actions == 0:
|
|
214
|
+
console.print("[yellow]Warning: Policy took no actions (all no-ops)[/yellow]")
|
|
215
|
+
raise typer.Exit(1)
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
def upload_submission(
|
|
219
|
+
client: TournamentServerClient,
|
|
220
|
+
zip_path: Path,
|
|
221
|
+
submission_name: str,
|
|
222
|
+
season: str | None = None,
|
|
223
|
+
) -> UploadResult | None:
|
|
224
|
+
"""Upload submission to CoGames backend using a presigned S3 URL."""
|
|
225
|
+
console.print("[bold]Uploading[/bold]")
|
|
226
|
+
|
|
227
|
+
presigned_data = client.get_presigned_upload_url()
|
|
228
|
+
upload_url = presigned_data.get("upload_url")
|
|
229
|
+
upload_id = presigned_data.get("upload_id")
|
|
230
|
+
|
|
231
|
+
if not upload_url or not upload_id:
|
|
232
|
+
raise ValueError("Upload URL missing from response")
|
|
233
|
+
|
|
234
|
+
console.print("[dim]Uploading to storage...[/dim]")
|
|
235
|
+
|
|
236
|
+
with open(zip_path, "rb") as f:
|
|
237
|
+
upload_response = httpx.put(
|
|
238
|
+
upload_url,
|
|
239
|
+
content=f,
|
|
240
|
+
headers={"Content-Type": "application/zip"},
|
|
241
|
+
timeout=600.0,
|
|
242
|
+
)
|
|
243
|
+
upload_response.raise_for_status()
|
|
244
|
+
|
|
245
|
+
if not season:
|
|
246
|
+
console.print("[dim]Uploading policy...[/dim]")
|
|
247
|
+
else:
|
|
248
|
+
console.print(f"[dim]Uploading policy and submitting to season {season}...[/dim]")
|
|
249
|
+
|
|
250
|
+
result = client.complete_policy_upload(upload_id, submission_name, season=season)
|
|
251
|
+
submission_id = result.get("id")
|
|
252
|
+
name = result.get("name")
|
|
253
|
+
version = result.get("version")
|
|
254
|
+
pools = result.get("pools")
|
|
255
|
+
if submission_id is None or name is None or version is None:
|
|
256
|
+
raise ValueError("Missing fields in response")
|
|
257
|
+
try:
|
|
258
|
+
return UploadResult(
|
|
259
|
+
policy_version_id=uuid.UUID(str(submission_id)),
|
|
260
|
+
name=name,
|
|
261
|
+
version=version,
|
|
262
|
+
pools=pools,
|
|
263
|
+
)
|
|
264
|
+
except ValueError as exc:
|
|
265
|
+
raise ValueError(f"Invalid submission ID returned: {submission_id}") from exc
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
def upload_policy(
|
|
269
|
+
ctx: typer.Context,
|
|
270
|
+
policy: str,
|
|
271
|
+
name: str,
|
|
272
|
+
include_files: list[str] | None = None,
|
|
273
|
+
login_server: str = DEFAULT_COGAMES_SERVER,
|
|
274
|
+
server: str = DEFAULT_SUBMIT_SERVER,
|
|
275
|
+
init_kwargs: dict[str, str] | None = None,
|
|
276
|
+
dry_run: bool = False,
|
|
277
|
+
skip_validation: bool = False,
|
|
278
|
+
setup_script: str | None = None,
|
|
279
|
+
season: str | None = None,
|
|
280
|
+
) -> UploadResult | None:
|
|
281
|
+
if dry_run:
|
|
282
|
+
console.print("[dim]Dry run mode - no upload[/dim]\n")
|
|
283
|
+
|
|
284
|
+
client = TournamentServerClient.from_login(server_url=server, login_server=login_server)
|
|
285
|
+
if not client:
|
|
286
|
+
return None
|
|
287
|
+
|
|
288
|
+
with tempfile.TemporaryDirectory(prefix="cogames_bundle_") as tmp_dir:
|
|
289
|
+
zip_path = Path(tmp_dir) / "bundle.zip"
|
|
290
|
+
|
|
291
|
+
create_bundle(
|
|
292
|
+
ctx=ctx,
|
|
293
|
+
policy=policy,
|
|
294
|
+
output=zip_path,
|
|
295
|
+
include_files=include_files,
|
|
296
|
+
init_kwargs=init_kwargs,
|
|
297
|
+
setup_script=setup_script,
|
|
298
|
+
)
|
|
299
|
+
|
|
300
|
+
if not skip_validation:
|
|
301
|
+
cmd = [
|
|
302
|
+
sys.executable,
|
|
303
|
+
"-m",
|
|
304
|
+
"cogames",
|
|
305
|
+
"validate-bundle",
|
|
306
|
+
"--policy",
|
|
307
|
+
zip_path.as_uri(),
|
|
308
|
+
"--server",
|
|
309
|
+
server,
|
|
310
|
+
]
|
|
311
|
+
if season:
|
|
312
|
+
cmd.extend(["--season", season])
|
|
313
|
+
result = subprocess.run(cmd, text=True, timeout=300)
|
|
314
|
+
if result.returncode != 0:
|
|
315
|
+
console.print("[red]Validation failed[/red]")
|
|
316
|
+
return None
|
|
317
|
+
console.print("[green]Validation passed[/green]")
|
|
318
|
+
else:
|
|
319
|
+
console.print("[dim]Skipping validation[/dim]")
|
|
320
|
+
|
|
321
|
+
if dry_run:
|
|
322
|
+
console.print("[green]Dry run complete[/green]")
|
|
323
|
+
return None
|
|
324
|
+
|
|
325
|
+
with client:
|
|
326
|
+
result = upload_submission(client, zip_path, name, season=season)
|
|
327
|
+
if not result:
|
|
328
|
+
console.print("\n[red]Upload failed.[/red]")
|
|
329
|
+
return None
|
|
330
|
+
|
|
331
|
+
return result
|
|
@@ -63,7 +63,13 @@ from cogames.cli.policy import (
|
|
|
63
63
|
policy_arg_example,
|
|
64
64
|
policy_arg_w_proportion_example,
|
|
65
65
|
)
|
|
66
|
-
from cogames.cli.submit import
|
|
66
|
+
from cogames.cli.submit import (
|
|
67
|
+
DEFAULT_SUBMIT_SERVER,
|
|
68
|
+
RESULTS_URL,
|
|
69
|
+
create_bundle,
|
|
70
|
+
upload_policy,
|
|
71
|
+
validate_bundle,
|
|
72
|
+
)
|
|
67
73
|
from cogames.cogs_vs_clips.mission import CvCMission, NumCogsVariant
|
|
68
74
|
from cogames.curricula import make_rotation
|
|
69
75
|
from cogames.device import resolve_training_device
|
|
@@ -2228,12 +2234,12 @@ def _resolve_season(server: str, season_name: str | None = None) -> SeasonInfo:
|
|
|
2228
2234
|
|
|
2229
2235
|
|
|
2230
2236
|
@app.command(
|
|
2231
|
-
name="
|
|
2232
|
-
help="
|
|
2237
|
+
name="create-bundle",
|
|
2238
|
+
help="Create a submission bundle zip from a policy",
|
|
2233
2239
|
rich_help_panel="Policies",
|
|
2234
2240
|
add_help_option=False,
|
|
2235
2241
|
)
|
|
2236
|
-
def
|
|
2242
|
+
def create_bundle_cmd(
|
|
2237
2243
|
ctx: typer.Context,
|
|
2238
2244
|
policy: str = typer.Option(
|
|
2239
2245
|
...,
|
|
@@ -2243,18 +2249,77 @@ def validate_policy_cmd(
|
|
|
2243
2249
|
help=f"Policy specification: {policy_arg_example}",
|
|
2244
2250
|
rich_help_panel="Policy",
|
|
2245
2251
|
),
|
|
2246
|
-
|
|
2247
|
-
"
|
|
2248
|
-
"--
|
|
2249
|
-
|
|
2250
|
-
|
|
2252
|
+
output: Path = typer.Option( # noqa: B008
|
|
2253
|
+
Path("submission.zip"),
|
|
2254
|
+
"--output",
|
|
2255
|
+
"-o",
|
|
2256
|
+
metavar="PATH",
|
|
2257
|
+
help="Output path for the bundle zip",
|
|
2258
|
+
rich_help_panel="Output",
|
|
2259
|
+
),
|
|
2260
|
+
init_kwarg: Optional[list[str]] = typer.Option( # noqa: B008
|
|
2261
|
+
None,
|
|
2262
|
+
"--init-kwarg",
|
|
2263
|
+
"-k",
|
|
2264
|
+
metavar="KEY=VAL",
|
|
2265
|
+
help="Policy init kwargs (can be repeated)",
|
|
2251
2266
|
rich_help_panel="Policy",
|
|
2252
2267
|
),
|
|
2268
|
+
include_files: Optional[list[str]] = typer.Option( # noqa: B008
|
|
2269
|
+
None,
|
|
2270
|
+
"--include-files",
|
|
2271
|
+
"-f",
|
|
2272
|
+
metavar="PATH",
|
|
2273
|
+
help="Files or directories to include (can be repeated)",
|
|
2274
|
+
rich_help_panel="Files",
|
|
2275
|
+
),
|
|
2253
2276
|
setup_script: Optional[str] = typer.Option(
|
|
2254
2277
|
None,
|
|
2255
2278
|
"--setup-script",
|
|
2256
|
-
|
|
2257
|
-
|
|
2279
|
+
metavar="PATH",
|
|
2280
|
+
help="Python setup script to include in the bundle",
|
|
2281
|
+
rich_help_panel="Files",
|
|
2282
|
+
),
|
|
2283
|
+
_help: bool = typer.Option(
|
|
2284
|
+
False,
|
|
2285
|
+
"--help",
|
|
2286
|
+
"-h",
|
|
2287
|
+
help="Show this message and exit",
|
|
2288
|
+
is_eager=True,
|
|
2289
|
+
callback=_help_callback,
|
|
2290
|
+
rich_help_panel="Other",
|
|
2291
|
+
),
|
|
2292
|
+
) -> None:
|
|
2293
|
+
init_kwargs: dict[str, str] = {}
|
|
2294
|
+
if init_kwarg:
|
|
2295
|
+
for kv in init_kwarg:
|
|
2296
|
+
key, val = _parse_init_kwarg(kv)
|
|
2297
|
+
init_kwargs[key] = val
|
|
2298
|
+
|
|
2299
|
+
result_path = create_bundle(
|
|
2300
|
+
ctx=ctx,
|
|
2301
|
+
policy=policy,
|
|
2302
|
+
output=output.resolve(),
|
|
2303
|
+
include_files=include_files,
|
|
2304
|
+
init_kwargs=init_kwargs if init_kwargs else None,
|
|
2305
|
+
setup_script=setup_script,
|
|
2306
|
+
)
|
|
2307
|
+
console.print(f"[green]Bundle created:[/green] {result_path}")
|
|
2308
|
+
|
|
2309
|
+
|
|
2310
|
+
@app.command(
|
|
2311
|
+
name="validate-bundle",
|
|
2312
|
+
help="Validate a policy bundle runs correctly in process isolation",
|
|
2313
|
+
rich_help_panel="Policies",
|
|
2314
|
+
add_help_option=False,
|
|
2315
|
+
)
|
|
2316
|
+
def validate_bundle_cmd(
|
|
2317
|
+
policy: str = typer.Option(
|
|
2318
|
+
...,
|
|
2319
|
+
"--policy",
|
|
2320
|
+
"-p",
|
|
2321
|
+
metavar="URI",
|
|
2322
|
+
help="Bundle URI (file://, s3://, or local path to .zip or directory)",
|
|
2258
2323
|
),
|
|
2259
2324
|
season: Optional[str] = typer.Option(
|
|
2260
2325
|
None,
|
|
@@ -2289,37 +2354,8 @@ def validate_policy_cmd(
|
|
|
2289
2354
|
with TournamentServerClient(server_url=server) as client:
|
|
2290
2355
|
config_data = client.get_config(entry_pool_info.config_id)
|
|
2291
2356
|
env_cfg = MettaGridConfig.model_validate(config_data)
|
|
2357
|
+
validate_bundle(policy, env_cfg)
|
|
2292
2358
|
|
|
2293
|
-
if setup_script:
|
|
2294
|
-
import subprocess # noqa: PLC0415
|
|
2295
|
-
import sys # noqa: PLC0415
|
|
2296
|
-
from pathlib import Path # noqa: PLC0415
|
|
2297
|
-
|
|
2298
|
-
script_path = Path(setup_script)
|
|
2299
|
-
if not script_path.exists():
|
|
2300
|
-
console.print(f"[red]Setup script not found: {setup_script}[/red]")
|
|
2301
|
-
raise typer.Exit(1)
|
|
2302
|
-
console.print(f"[yellow]Running setup script: {setup_script}[/yellow]")
|
|
2303
|
-
result = subprocess.run(
|
|
2304
|
-
[sys.executable, str(script_path)],
|
|
2305
|
-
cwd=Path.cwd(),
|
|
2306
|
-
capture_output=True,
|
|
2307
|
-
text=True,
|
|
2308
|
-
timeout=300,
|
|
2309
|
-
)
|
|
2310
|
-
if result.returncode != 0:
|
|
2311
|
-
console.print(f"[red]Setup script failed:[/red]\n{result.stderr}")
|
|
2312
|
-
raise typer.Exit(1)
|
|
2313
|
-
console.print("[green]Setup script completed[/green]")
|
|
2314
|
-
|
|
2315
|
-
resolved_device = resolve_training_device(console, device)
|
|
2316
|
-
policy_spec = get_policy_spec(ctx, policy, device=str(resolved_device))
|
|
2317
|
-
validate_policy_spec(
|
|
2318
|
-
policy_spec,
|
|
2319
|
-
env_cfg,
|
|
2320
|
-
device=str(resolved_device),
|
|
2321
|
-
season=season_info.name,
|
|
2322
|
-
)
|
|
2323
2359
|
console.print("[green]Policy validated successfully[/green]")
|
|
2324
2360
|
raise typer.Exit(0)
|
|
2325
2361
|
|
|
@@ -2446,11 +2482,6 @@ def upload_cmd(
|
|
|
2446
2482
|
) -> None:
|
|
2447
2483
|
season_info = _resolve_season(server, season)
|
|
2448
2484
|
|
|
2449
|
-
has_entry_config = any(p.config_id for p in season_info.pools if p.name == season_info.entry_pool)
|
|
2450
|
-
if not has_entry_config and not skip_validation:
|
|
2451
|
-
console.print("[yellow]Warning: No entry config found for season. Skipping validation.[/yellow]")
|
|
2452
|
-
skip_validation = True
|
|
2453
|
-
|
|
2454
2485
|
init_kwargs: dict[str, str] = {}
|
|
2455
2486
|
if init_kwarg:
|
|
2456
2487
|
for kv in init_kwarg:
|
|
@@ -2468,7 +2499,6 @@ def upload_cmd(
|
|
|
2468
2499
|
skip_validation=skip_validation,
|
|
2469
2500
|
init_kwargs=init_kwargs if init_kwargs else None,
|
|
2470
2501
|
setup_script=setup_script,
|
|
2471
|
-
validation_season=season_info.name,
|
|
2472
2502
|
season=season_info.name if not no_submit else None,
|
|
2473
2503
|
)
|
|
2474
2504
|
|
|
@@ -2476,7 +2506,7 @@ def upload_cmd(
|
|
|
2476
2506
|
console.print(f"[green]Upload complete: {result.name}:v{result.version}[/green]")
|
|
2477
2507
|
if result.pools:
|
|
2478
2508
|
console.print(f"[dim]Added to pools: {', '.join(result.pools)}[/dim]")
|
|
2479
|
-
console.print(f"[dim]Results:[/dim] {
|
|
2509
|
+
console.print(f"[dim]Results:[/dim] {RESULTS_URL}")
|
|
2480
2510
|
elif no_submit:
|
|
2481
2511
|
console.print(f"\nTo submit to a tournament: cogames submit {result.name}:v{result.version}")
|
|
2482
2512
|
|
|
@@ -2574,7 +2604,7 @@ def submit_cmd(
|
|
|
2574
2604
|
console.print(f"\n[bold green]Submitted to season '{season_name}'[/bold green]")
|
|
2575
2605
|
if result.pools:
|
|
2576
2606
|
console.print(f"[dim]Added to pools: {', '.join(result.pools)}[/dim]")
|
|
2577
|
-
console.print(f"[dim]Results:[/dim] {
|
|
2607
|
+
console.print(f"[dim]Results:[/dim] {RESULTS_URL}")
|
|
2578
2608
|
console.print(f"[dim]CLI:[/dim] cogames leaderboard --season {season_name}")
|
|
2579
2609
|
|
|
2580
2610
|
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cogames
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.69
|
|
4
4
|
Summary: Multi-agent cooperative games
|
|
5
5
|
Classifier: Programming Language :: Python :: 3
|
|
6
6
|
Classifier: Programming Language :: Python :: 3.12
|
|
7
7
|
Requires-Python: <3.13,>=3.12
|
|
8
8
|
Description-Content-Type: text/markdown
|
|
9
9
|
License-File: LICENSE
|
|
10
|
-
Requires-Dist: mettagrid==0.2.0.
|
|
10
|
+
Requires-Dist: mettagrid==0.2.0.83
|
|
11
11
|
Requires-Dist: packaging>=24.0.0
|
|
12
12
|
Requires-Dist: pufferlib-core
|
|
13
13
|
Requires-Dist: pydantic>=2.11.5
|