cogames 0.3.49__py3-none-any.whl → 0.3.64__py3-none-any.whl

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.
Files changed (169) hide show
  1. cogames/cli/client.py +60 -6
  2. cogames/cli/docsync/__init__.py +0 -0
  3. cogames/cli/docsync/_nb_md_directive_processing.py +180 -0
  4. cogames/cli/docsync/_nb_md_sync.py +103 -0
  5. cogames/cli/docsync/_nb_py_sync.py +122 -0
  6. cogames/cli/docsync/_three_way_sync.py +115 -0
  7. cogames/cli/docsync/_utils.py +76 -0
  8. cogames/cli/docsync/docsync.py +156 -0
  9. cogames/cli/leaderboard.py +112 -28
  10. cogames/cli/mission.py +64 -53
  11. cogames/cli/policy.py +46 -10
  12. cogames/cli/submit.py +268 -67
  13. cogames/cogs_vs_clips/cog.py +79 -0
  14. cogames/cogs_vs_clips/cogs_vs_clips_mapgen.md +19 -16
  15. cogames/cogs_vs_clips/cogsguard_reward_variants.py +153 -0
  16. cogames/cogs_vs_clips/cogsguard_tutorial.py +56 -0
  17. cogames/cogs_vs_clips/evals/README.md +10 -16
  18. cogames/cogs_vs_clips/evals/cogsguard_evals.py +81 -0
  19. cogames/cogs_vs_clips/evals/diagnostic_evals.py +49 -444
  20. cogames/cogs_vs_clips/evals/difficulty_variants.py +13 -326
  21. cogames/cogs_vs_clips/evals/integrated_evals.py +5 -45
  22. cogames/cogs_vs_clips/evals/spanning_evals.py +9 -180
  23. cogames/cogs_vs_clips/mission.py +187 -146
  24. cogames/cogs_vs_clips/missions.py +46 -137
  25. cogames/cogs_vs_clips/procedural.py +8 -8
  26. cogames/cogs_vs_clips/sites.py +107 -3
  27. cogames/cogs_vs_clips/stations.py +198 -186
  28. cogames/cogs_vs_clips/tutorial_missions.py +1 -1
  29. cogames/cogs_vs_clips/variants.py +25 -476
  30. cogames/device.py +13 -1
  31. cogames/{policy/scripted_agent/README.md → docs/SCRIPTED_AGENT.md} +82 -58
  32. cogames/evaluate.py +18 -30
  33. cogames/main.py +1434 -243
  34. cogames/maps/canidate1_1000.map +1 -1
  35. cogames/maps/canidate1_1000_stations.map +2 -2
  36. cogames/maps/canidate1_500.map +1 -1
  37. cogames/maps/canidate1_500_stations.map +2 -2
  38. cogames/maps/canidate2_1000.map +1 -1
  39. cogames/maps/canidate2_1000_stations.map +2 -2
  40. cogames/maps/canidate2_500.map +1 -1
  41. cogames/maps/canidate2_500_stations.map +2 -2
  42. cogames/maps/canidate3_1000.map +1 -1
  43. cogames/maps/canidate3_1000_stations.map +2 -2
  44. cogames/maps/canidate3_500.map +1 -1
  45. cogames/maps/canidate3_500_stations.map +2 -2
  46. cogames/maps/canidate4_500.map +1 -1
  47. cogames/maps/canidate4_500_stations.map +2 -2
  48. cogames/maps/cave_base_50.map +2 -2
  49. cogames/maps/diagnostic_evals/diagnostic_agile.map +2 -2
  50. cogames/maps/diagnostic_evals/diagnostic_agile_hard.map +2 -2
  51. cogames/maps/diagnostic_evals/diagnostic_charge_up.map +2 -2
  52. cogames/maps/diagnostic_evals/diagnostic_charge_up_hard.map +2 -2
  53. cogames/maps/diagnostic_evals/diagnostic_chest_navigation1.map +2 -2
  54. cogames/maps/diagnostic_evals/diagnostic_chest_navigation1_hard.map +2 -2
  55. cogames/maps/diagnostic_evals/diagnostic_chest_navigation2.map +2 -2
  56. cogames/maps/diagnostic_evals/diagnostic_chest_navigation2_hard.map +2 -2
  57. cogames/maps/diagnostic_evals/diagnostic_chest_navigation3.map +2 -2
  58. cogames/maps/diagnostic_evals/diagnostic_chest_navigation3_hard.map +2 -2
  59. cogames/maps/diagnostic_evals/diagnostic_chest_near.map +2 -2
  60. cogames/maps/diagnostic_evals/diagnostic_chest_search.map +2 -2
  61. cogames/maps/diagnostic_evals/diagnostic_chest_search_hard.map +2 -2
  62. cogames/maps/diagnostic_evals/diagnostic_extract_lab.map +2 -2
  63. cogames/maps/diagnostic_evals/diagnostic_extract_lab_hard.map +2 -2
  64. cogames/maps/diagnostic_evals/diagnostic_memory.map +2 -2
  65. cogames/maps/diagnostic_evals/diagnostic_memory_hard.map +2 -2
  66. cogames/maps/diagnostic_evals/diagnostic_radial.map +2 -2
  67. cogames/maps/diagnostic_evals/diagnostic_radial_hard.map +2 -2
  68. cogames/maps/diagnostic_evals/diagnostic_resource_lab.map +2 -2
  69. cogames/maps/diagnostic_evals/diagnostic_unclip.map +2 -2
  70. cogames/maps/evals/eval_balanced_spread.map +9 -5
  71. cogames/maps/evals/eval_clip_oxygen.map +9 -5
  72. cogames/maps/evals/eval_collect_resources.map +9 -5
  73. cogames/maps/evals/eval_collect_resources_hard.map +9 -5
  74. cogames/maps/evals/eval_collect_resources_medium.map +9 -5
  75. cogames/maps/evals/eval_divide_and_conquer.map +9 -5
  76. cogames/maps/evals/eval_energy_starved.map +9 -5
  77. cogames/maps/evals/eval_multi_coordinated_collect_hard.map +9 -5
  78. cogames/maps/evals/eval_oxygen_bottleneck.map +9 -5
  79. cogames/maps/evals/eval_single_use_world.map +9 -5
  80. cogames/maps/evals/extractor_hub_100x100.map +9 -5
  81. cogames/maps/evals/extractor_hub_30x30.map +9 -5
  82. cogames/maps/evals/extractor_hub_50x50.map +9 -5
  83. cogames/maps/evals/extractor_hub_70x70.map +9 -5
  84. cogames/maps/evals/extractor_hub_80x80.map +9 -5
  85. cogames/maps/machina_100_stations.map +2 -2
  86. cogames/maps/machina_200_stations.map +2 -2
  87. cogames/maps/machina_200_stations_small.map +2 -2
  88. cogames/maps/machina_eval_exp01.map +2 -2
  89. cogames/maps/machina_eval_template_large.map +2 -2
  90. cogames/maps/machinatrainer4agents.map +2 -2
  91. cogames/maps/machinatrainer4agentsbase.map +2 -2
  92. cogames/maps/machinatrainerbig.map +2 -2
  93. cogames/maps/machinatrainersmall.map +2 -2
  94. cogames/maps/planky_evals/aligner_avoid_aoe.map +28 -0
  95. cogames/maps/planky_evals/aligner_full_cycle.map +28 -0
  96. cogames/maps/planky_evals/aligner_gear.map +24 -0
  97. cogames/maps/planky_evals/aligner_hearts.map +24 -0
  98. cogames/maps/planky_evals/aligner_junction.map +26 -0
  99. cogames/maps/planky_evals/exploration_distant.map +28 -0
  100. cogames/maps/planky_evals/maze.map +32 -0
  101. cogames/maps/planky_evals/miner_best_resource.map +26 -0
  102. cogames/maps/planky_evals/miner_deposit.map +24 -0
  103. cogames/maps/planky_evals/miner_extract.map +26 -0
  104. cogames/maps/planky_evals/miner_full_cycle.map +28 -0
  105. cogames/maps/planky_evals/miner_gear.map +24 -0
  106. cogames/maps/planky_evals/multi_role.map +28 -0
  107. cogames/maps/planky_evals/resource_chain.map +30 -0
  108. cogames/maps/planky_evals/scout_explore.map +32 -0
  109. cogames/maps/planky_evals/scout_gear.map +24 -0
  110. cogames/maps/planky_evals/scrambler_full_cycle.map +28 -0
  111. cogames/maps/planky_evals/scrambler_gear.map +24 -0
  112. cogames/maps/planky_evals/scrambler_target.map +26 -0
  113. cogames/maps/planky_evals/stuck_corridor.map +32 -0
  114. cogames/maps/planky_evals/survive_retreat.map +26 -0
  115. cogames/maps/training_facility_clipped.map +2 -2
  116. cogames/maps/training_facility_open_1.map +2 -2
  117. cogames/maps/training_facility_open_2.map +2 -2
  118. cogames/maps/training_facility_open_3.map +2 -2
  119. cogames/maps/training_facility_tight_4.map +2 -2
  120. cogames/maps/training_facility_tight_5.map +2 -2
  121. cogames/maps/vanilla_large.map +2 -2
  122. cogames/maps/vanilla_small.map +2 -2
  123. cogames/pickup.py +183 -0
  124. cogames/play.py +166 -33
  125. cogames/policy/chaos_monkey.py +54 -0
  126. cogames/policy/nim_agents/__init__.py +27 -10
  127. cogames/policy/nim_agents/agents.py +121 -60
  128. cogames/policy/nim_agents/thinky_eval.py +35 -222
  129. cogames/policy/pufferlib_policy.py +67 -32
  130. cogames/policy/starter_agent.py +184 -0
  131. cogames/policy/trainable_policy_template.py +4 -1
  132. cogames/train.py +51 -13
  133. cogames/verbose.py +2 -2
  134. cogames-0.3.64.dist-info/METADATA +1842 -0
  135. cogames-0.3.64.dist-info/RECORD +159 -0
  136. cogames-0.3.64.dist-info/licenses/LICENSE +21 -0
  137. cogames-0.3.64.dist-info/top_level.txt +2 -0
  138. metta_alo/__init__.py +0 -0
  139. metta_alo/job_specs.py +17 -0
  140. metta_alo/policy.py +16 -0
  141. metta_alo/pure_single_episode_runner.py +75 -0
  142. metta_alo/py.typed +0 -0
  143. metta_alo/rollout.py +322 -0
  144. metta_alo/scoring.py +168 -0
  145. cogames/maps/diagnostic_evals/diagnostic_assembler_near.map +0 -49
  146. cogames/maps/diagnostic_evals/diagnostic_assembler_search.map +0 -49
  147. cogames/maps/diagnostic_evals/diagnostic_assembler_search_hard.map +0 -89
  148. cogames/policy/nim_agents/common.nim +0 -887
  149. cogames/policy/nim_agents/install.sh +0 -1
  150. cogames/policy/nim_agents/ladybug_agent.nim +0 -984
  151. cogames/policy/nim_agents/nim_agents.nim +0 -55
  152. cogames/policy/nim_agents/nim_agents.nims +0 -14
  153. cogames/policy/nim_agents/nimby.lock +0 -3
  154. cogames/policy/nim_agents/racecar_agents.nim +0 -884
  155. cogames/policy/nim_agents/random_agents.nim +0 -68
  156. cogames/policy/nim_agents/test_agents.py +0 -53
  157. cogames/policy/nim_agents/thinky_agents.nim +0 -717
  158. cogames/policy/scripted_agent/baseline_agent.py +0 -1049
  159. cogames/policy/scripted_agent/demo_policy.py +0 -244
  160. cogames/policy/scripted_agent/pathfinding.py +0 -126
  161. cogames/policy/scripted_agent/starter_agent.py +0 -136
  162. cogames/policy/scripted_agent/types.py +0 -235
  163. cogames/policy/scripted_agent/unclipping_agent.py +0 -476
  164. cogames/policy/scripted_agent/utils.py +0 -385
  165. cogames-0.3.49.dist-info/METADATA +0 -406
  166. cogames-0.3.49.dist-info/RECORD +0 -136
  167. cogames-0.3.49.dist-info/top_level.txt +0 -1
  168. {cogames-0.3.49.dist-info → cogames-0.3.64.dist-info}/WHEEL +0 -0
  169. {cogames-0.3.49.dist-info → cogames-0.3.64.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,159 @@
1
+ cogames/__init__.py,sha256=Loao4kW7AqCRVKcQuA7lKEsyKl9k_Zf1oVlPXvgqjbw,23
2
+ cogames/auth.py,sha256=W7BgRhrCTKob68p6HHTKVFjPayySaBG03eIgcGjw_jI,15852
3
+ cogames/curricula.py,sha256=a7Nd-av4epAjmoqlefyU4q5eAitpYjCEGDCF_tS_iaY,825
4
+ cogames/device.py,sha256=GVC7g4tNVySn_rSbHJB0jGKvpYBL8-VmeYEQXWXtvy0,1680
5
+ cogames/evaluate.py,sha256=xm4dCLAXZFhfygDeC_617QXRa5DQYB_6EENEeeDAiWQ,9287
6
+ cogames/game.py,sha256=Qpyd4UOv97S-PCcEb422XFVbuXk46qhEx7_FlAr8ayA,3331
7
+ cogames/main.py,sha256=zYiY_cB0kiRproN4-Xa6MSwlff3-9hpFZLOZ-YfSwEg,79367
8
+ cogames/pickup.py,sha256=gCm-BLMSKN4iflyn2EdsxE7ywKYzMgjozep5o_306yE,6545
9
+ cogames/play.py,sha256=SV_gKg5kNj68m7bavmEYomLmmWxVGbc50ZhwAEMDy5E,8014
10
+ cogames/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
+ cogames/train.py,sha256=C4ZP00fxHspiQK-p00EPXyfcwiFKNIBUF1iBe2EE0GE,17894
12
+ cogames/verbose.py,sha256=WcbVMpB43YpNJxZcwEkFtIqiIIxPLMZMu_3XQmeY59w,2916
13
+ cogames/cli/base.py,sha256=UpMqeJ0C8i0pkue1AHnnyyX0bFJ9zZeJ7HBR6yhuA8A,54
14
+ cogames/cli/client.py,sha256=UFWn6Kjbp6nCYjeC5wMwIJAM5o_hngNdZ_yv24aeiOI,9025
15
+ cogames/cli/leaderboard.py,sha256=eIbiSBOkvoi5IL2weiKBOJAjWGHquDk1PWoHKA8uu3g,13941
16
+ cogames/cli/login.py,sha256=_i1Hdbp_wAMsX0NLbCTSr7GmOFbzSqwyNP79OqLOg40,1237
17
+ cogames/cli/mission.py,sha256=Shd7wivVdRbWTZ02yH334QZfwAqNy6mvRzLvU01iJrA,21674
18
+ cogames/cli/policy.py,sha256=JI_aX0lcY-kaZWl-RhUfFu0vknF2mXHS8y0CQRRhpao,8743
19
+ cogames/cli/submit.py,sha256=vB8EhB1z-SOUIdRhIkMEm_sbjFXbarVUn5BuiPa7SMI,20927
20
+ cogames/cli/utils.py,sha256=K4eb-RL73HtavNGxZjn_SVDLAwfFamLCEQNTCNVdmPU,895
21
+ cogames/cli/docsync/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
22
+ cogames/cli/docsync/_nb_md_directive_processing.py,sha256=A920oS21mw9ZU2vp-cILzq5Sa-AMtmwMSayZKcQwX9M,6365
23
+ cogames/cli/docsync/_nb_md_sync.py,sha256=oa7P-7OOPUtkKFX6C7SD4fk8ufGDNFvi__zKfhkw4rw,3942
24
+ cogames/cli/docsync/_nb_py_sync.py,sha256=BfnfJ-1cRjmpzvggiR8E4vQkTak7AHm36pIK6xJVy-s,4578
25
+ cogames/cli/docsync/_three_way_sync.py,sha256=fug-HXNYqJhJvusWHnGmLQewtiAUKhCBOd1Tuu7__sA,4877
26
+ cogames/cli/docsync/_utils.py,sha256=zPfXzVa0XbqZReGvMUvxl4yLWc2oFeJJiefOBjOHaCA,2616
27
+ cogames/cli/docsync/docsync.py,sha256=dtGG91Co89VdiwRwKk57kYd-qnHiFIgIkS1OI12AYyQ,5664
28
+ cogames/cogs_vs_clips/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
29
+ cogames/cogs_vs_clips/cog.py,sha256=P6T9y6iZ4aAXATqmQ3ooRLvP5K60r3o-viX4eoiaZq4,3201
30
+ cogames/cogs_vs_clips/cogs_vs_clips_mapgen.md,sha256=Tof8NFILYAj4nTYXFXgbGlLaryHj0Zvjdm-lBGKP5dE,13378
31
+ cogames/cogs_vs_clips/cogsguard_reward_variants.py,sha256=V54Ly7T84cRfBoHv7Am7tv2OpL43Ksm95Fqkwy_TWAk,5819
32
+ cogames/cogs_vs_clips/cogsguard_tutorial.py,sha256=_J4yCpf4783Cp4Z0dV6aRY0DCWDxQ4P4PBVhePRMQIw,1623
33
+ cogames/cogs_vs_clips/mission.py,sha256=KTpfBPiwzAxobmnQ-WqPn0dLiAR4goFeHUAeyO4ahgA,12480
34
+ cogames/cogs_vs_clips/mission_utils.py,sha256=-tB8JclTaq8Zfh8V5DPor1A3Ncuq8ndsTjgVnIxUV7s,671
35
+ cogames/cogs_vs_clips/missions.py,sha256=ZAmS7qYViKwF4XazyqE7BE5HEhgBhwWhWCCYBfUCU7Y,2430
36
+ cogames/cogs_vs_clips/procedural.py,sha256=M_a6uRsHzatVSW8PrVTAupv2u1M_ehOgM6XnEB3_Gbk,25947
37
+ cogames/cogs_vs_clips/sites.py,sha256=Mq10ammCu49-xngQtJy8UwfRR6d78FN2dzxxi7HZy04,4916
38
+ cogames/cogs_vs_clips/stations.py,sha256=HxTPQnY2Y8kqK42OnaSAg8S69yO7g2pr-WkGiaL967I,9174
39
+ cogames/cogs_vs_clips/tutorial_missions.py,sha256=p2ds5t_cfD9xyFLSq8A9xw-zO4-OHi9LSGdocl4JDC4,712
40
+ cogames/cogs_vs_clips/variants.py,sha256=zU32g8Hy2GEBgOMjf6VU6Phn4X7wVvfV4_shjtddOc0,11783
41
+ cogames/cogs_vs_clips/evals/README.md,sha256=aglXp04_1AXwxk-zfYsqOi3qbVpSRvOVJY3j5I_yCSA,7048
42
+ cogames/cogs_vs_clips/evals/cogsguard_evals.py,sha256=OgIFjQIUbEbjyWxalr4_eRPYoi3bkgvFNsZfW9kKu7I,2510
43
+ cogames/cogs_vs_clips/evals/diagnostic_evals.py,sha256=RakNmoy8I5lgYqlUT38sctIszaLWLQmnekaNjg---Ck,13626
44
+ cogames/cogs_vs_clips/evals/difficulty_variants.py,sha256=SCUAbbOCCYuK2gEcuJMWA-qAlQfme9AjEOIESFj6DBY,4319
45
+ cogames/cogs_vs_clips/evals/integrated_evals.py,sha256=wTq2JOeF4pxU59TFn0VLs7atNiVG4VFfmF-z8sFuERY,2784
46
+ cogames/cogs_vs_clips/evals/spanning_evals.py,sha256=CWa0HtG6LkxVP-SDDeWCSOC9Tw_20fFoAtQurZHJzTo,7516
47
+ cogames/docs/SCRIPTED_AGENT.md,sha256=MDvYQ1Xccexnr_HjCnF5hNsZtqGAy2s0VA3tdgZHego,10918
48
+ cogames/maps/canidate1_1000.map,sha256=DjLOgWDX9e9bmnA7oXcyIR-yilpoWufW0tsU12wSMmI,1023273
49
+ cogames/maps/canidate1_1000_stations.map,sha256=RXqSceZiEf6TmEfeFO8vsNiAnyhox4zCLp77xPwSO7g,1023402
50
+ cogames/maps/canidate1_500.map,sha256=FEhoftpEy9m4tgPwKKK6aZZp_gsgAbxZpMGWYMdtdls,261773
51
+ cogames/maps/canidate1_500_stations.map,sha256=IdmnGb0djh9XzwCalJJ51sa5dXsyC5_T7r12w8t_nEo,261902
52
+ cogames/maps/canidate2_1000.map,sha256=g6l7lnXEtg0TCEsLzY3WZ2opAa7nZSGUqnQdy8IpZGo,1023273
53
+ cogames/maps/canidate2_1000_stations.map,sha256=t6pCH0EZ75VRPTOgtNbIfQ0AmSaxhjRpiXMbCCsnk0M,1023402
54
+ cogames/maps/canidate2_500.map,sha256=zLOu4--t8BTDawScdt9eTDHnVugUBRp-6FBn0RtvCoU,261773
55
+ cogames/maps/canidate2_500_stations.map,sha256=jyL7DKfmxrogybxa6abJa7ClM_xWq30hvRMmsyvDUK8,261889
56
+ cogames/maps/canidate3_1000.map,sha256=AMNljeavU6z15Q4Ts4w9QtgCnPj3S0AcEncEaHKL_0o,1023273
57
+ cogames/maps/canidate3_1000_stations.map,sha256=AENVFj_oQ2UBNiWeBWUKkM3QR-9M_vRO-TdxBh3KDoQ,1023402
58
+ cogames/maps/canidate3_500.map,sha256=Tu_cTJWz1KRso48wtLHAa7-6M5PAltOCMGwnNDSK8co,261773
59
+ cogames/maps/canidate3_500_stations.map,sha256=99QB-4o4jh8SKTkNryh7QuK7X71iIX7DeRYgQ8MMA38,261902
60
+ cogames/maps/canidate4_500.map,sha256=Jn0CBxX5iwGHBlV7u-xyAQAuIdlUSzMYCSN1F_BvpLk,261773
61
+ cogames/maps/canidate4_500_stations.map,sha256=GBXWYYjEVk2N2JDeRs_cowfXRTjEG2m18PQYILLJ-pQ,261902
62
+ cogames/maps/cave_base_50.map,sha256=jHZyZfEJ9awJS2cwK5sWjTN23irhhyDeb4gWirClvzw,4052
63
+ cogames/maps/machina_100_stations.map,sha256=oJqPvGVpLyqm35YFgJ2qLfdA2PW1ww-4a-m6JlDdshY,12702
64
+ cogames/maps/machina_200_stations.map,sha256=svhatiFmKPq08u1_xeiCuBhkJKq3ucTSn8k06_yMWik,45002
65
+ cogames/maps/machina_200_stations_small.map,sha256=7OVVBCOCWCIpJkaCG1uxDQUDn1aFrrImNX92wOMLukE,5927
66
+ cogames/maps/machina_eval_exp01.map,sha256=ep5_8N8JyDMVRK2YrAPFbrqiR5WsVKkJPkhTxYxtOqE,2073
67
+ cogames/maps/machina_eval_template_large.map,sha256=gZVIICxthSDnzEa8rT5EHR63XapT1-4xa6sQcsYl1mw,4823
68
+ cogames/maps/machinatrainer4agents.map,sha256=O3dzwawhcXf72CPlDY4u0aN2M9sZ2W_vgte-hIKoA8g,5382
69
+ cogames/maps/machinatrainer4agentsbase.map,sha256=7dUwTtCJK4Nz5rEgXVKzEx3xiZb8X3euXYZNj55nw0E,5382
70
+ cogames/maps/machinatrainerbig.map,sha256=X5DkcUflf8mAt9X_rtatsixekwX2H1JClLGCG2Xp9iQ,51348
71
+ cogames/maps/machinatrainersmall.map,sha256=F8ndClYV6lw5p0XMe8hFp_ip_zzPE2-ynCX7oeSwQKA,12476
72
+ cogames/maps/training_facility_clipped.map,sha256=3xMzGq085cPBOmlSig8OTCOsWXKJ7c667k3wEj2gaHc,1358
73
+ cogames/maps/training_facility_open_1.map,sha256=y48S99f5YiVNbvTfuSlfAImloH7IsAMi5LxwircClKI,776
74
+ cogames/maps/training_facility_open_2.map,sha256=FMYqOC9ayQyOID6b6-ZgKHyKBuEyhhkfbEHo0MlYv5A,1326
75
+ cogames/maps/training_facility_open_3.map,sha256=cc_whap2-U6zvxGGOXeUIYw4_tCR_0V4mMd1YmfMeJI,776
76
+ cogames/maps/training_facility_tight_4.map,sha256=xH1RvLFt6XWdeAaWjyVQdSr-KkThAvQO47kaXhg5DkU,776
77
+ cogames/maps/training_facility_tight_5.map,sha256=aVF66xgV0Df-NYFkXopabn30mPt_ZRQVER4v5ycm9F0,776
78
+ cogames/maps/vanilla_large.map,sha256=hnlo1w8mAnPTl_LT1h-MW66_bplNiJ4OSFw13zG0yu4,2062
79
+ cogames/maps/vanilla_small.map,sha256=P1l1tNL68Z8U3gFSwAIYsJzgx7kWz0O_UxfCfeeMFOs,590
80
+ cogames/maps/zelda.map,sha256=1_rwezA27n5V9R3JY7WXniFVm8d31_Y1kyr9vn_gPjg,22387
81
+ cogames/maps/diagnostic_evals/diagnostic_agile.map,sha256=tFRCId6FyEPCuaVEeSYySHcDH3rq29KLiAz2a1vANHM,812
82
+ cogames/maps/diagnostic_evals/diagnostic_agile_hard.map,sha256=sW019536JKJBeVKT5T1mWaeqaOBttlRJ2IpEQjO5jc8,1540
83
+ cogames/maps/diagnostic_evals/diagnostic_charge_up.map,sha256=g9Nvtgb7kCGcKr7b387NmVOLWbEeGJTyizRzx-MEfBc,831
84
+ cogames/maps/diagnostic_evals/diagnostic_charge_up_hard.map,sha256=wj0vlpDQETSmYpcw0bmJDDqcQ5QbPNnoWBqBZibZKlc,1701
85
+ cogames/maps/diagnostic_evals/diagnostic_chest_navigation1.map,sha256=T12a6zUgVfsJhQyvL0kNCx8vWU_FdJCoa75ZVXCi3xU,1763
86
+ cogames/maps/diagnostic_evals/diagnostic_chest_navigation1_hard.map,sha256=1PzBOT1j5R0eT1glOXop01UdIZtMOTEHTaL28cjKmKU,3096
87
+ cogames/maps/diagnostic_evals/diagnostic_chest_navigation2.map,sha256=17GVIQs5mJEywC0tLV1y3uyEwIpVomnkhEFeNebCAl4,1041
88
+ cogames/maps/diagnostic_evals/diagnostic_chest_navigation2_hard.map,sha256=NmLbVM90xRpHJLiPPSeU8puFXUZ7eQougPnjsVse_3g,2770
89
+ cogames/maps/diagnostic_evals/diagnostic_chest_navigation3.map,sha256=66zB8rAv85ZiPDq6dYto54g2XCaBIV6m1qqAFS2yWKM,1123
90
+ cogames/maps/diagnostic_evals/diagnostic_chest_navigation3_hard.map,sha256=hGJUVN7igzbuPoD9tRu8GCAsn3ea6T2CAwcFPrjIW7w,2636
91
+ cogames/maps/diagnostic_evals/diagnostic_chest_near.map,sha256=FN7nA1QpIkg454buDSuIhYTrKJ1zmS_0S_cs--jTf6c,1798
92
+ cogames/maps/diagnostic_evals/diagnostic_chest_search.map,sha256=NgWr6ZZ6z5caOdZAxAIXuNwLKnbShKUcC4J7adm0xxc,1798
93
+ cogames/maps/diagnostic_evals/diagnostic_chest_search_hard.map,sha256=rgn6kw3-pYWS586UK7ecuSWcU-tNCsC63gPHg51PAlE,14378
94
+ cogames/maps/diagnostic_evals/diagnostic_extract_lab.map,sha256=w6k0Srm1Z3P7oAHzIab1uUlVNUTrxi99VDA1rjgYZMk,642
95
+ cogames/maps/diagnostic_evals/diagnostic_extract_lab_hard.map,sha256=IWwi5emOlfR2h3aX4lzNVBlIlcWFlsktUMYiws71cdE,1512
96
+ cogames/maps/diagnostic_evals/diagnostic_memory.map,sha256=TWMLViQT9b4pYlWgpZUlO-7Z1CGkNfFIg4Y7vboBng8,1210
97
+ cogames/maps/diagnostic_evals/diagnostic_memory_hard.map,sha256=pY4KyQ56YYWFkAWVHmegoO9KdGL5WjsMFPYy6rhF2s4,1992
98
+ cogames/maps/diagnostic_evals/diagnostic_radial.map,sha256=RxVoYmm6U_qUwmmgXZqB2ck3q6fk0al7P5CwU41wdas,3045
99
+ cogames/maps/diagnostic_evals/diagnostic_radial_hard.map,sha256=PPAxa97Eb5LQaDlKaPhJoWxnw31ADLh_soXhOTJ-zlA,24525
100
+ cogames/maps/diagnostic_evals/diagnostic_resource_lab.map,sha256=CEZlD1OGnOP9VEksGbxnfSWAZ-JV1hrGF16FtDJTRY0,1798
101
+ cogames/maps/diagnostic_evals/diagnostic_unclip.map,sha256=Qj3Slpl7hCP5Xa84A1Ek6wWl0dI_8U7Etm1DMitDyxs,1798
102
+ cogames/maps/evals/eval_balanced_spread.map,sha256=Ix-NFCndwvJds3JTSam7HtYJjiuXJRoR8c33SDwUdZc,2162
103
+ cogames/maps/evals/eval_clip_oxygen.map,sha256=a3RqOglzbNScOhsN-WDBuZY0CgmgFwKgSwTginmpbT4,2164
104
+ cogames/maps/evals/eval_collect_resources.map,sha256=6rQpYwqDHR-bmA3sW-XHBDP9n09uorv8yQLTaBUWmfA,2164
105
+ cogames/maps/evals/eval_collect_resources_hard.map,sha256=6LLWYSvdByGqqi-x9-w-akbpz_I--upLTTfmy7uXRvU,2164
106
+ cogames/maps/evals/eval_collect_resources_medium.map,sha256=avNWaX3TfSxyKveRb6dfymUKq390PXzGvP1D0c4GlN8,2164
107
+ cogames/maps/evals/eval_divide_and_conquer.map,sha256=p_Aw_g2GoAD1zlf45FR4fNjvBAdngpaqV6KZmEiFxxk,2162
108
+ cogames/maps/evals/eval_energy_starved.map,sha256=1R5K0XHFHG_sJF3jgDQt5vkEd2S0Xoqc5H3iSq_4QVQ,2162
109
+ cogames/maps/evals/eval_multi_coordinated_collect_hard.map,sha256=2ED8sqV9RHPdFEo5F3DBUwC9T0DqcGNTmJbF9iprMLY,2165
110
+ cogames/maps/evals/eval_oxygen_bottleneck.map,sha256=XlUTquPT4V3YpbVc5sLpQBm8HVTeeq0W6pRX-dTpXEU,2164
111
+ cogames/maps/evals/eval_single_use_world.map,sha256=Hj1KX5Fa4FAmhI8wIR2opRXqn5uUFbDLRthkiZA0ie4,2164
112
+ cogames/maps/evals/extractor_hub_100x100.map,sha256=knCtQaQjHV5hwOn95JEfXbusB9NvODGG2u6lIHKZmSY,12792
113
+ cogames/maps/evals/extractor_hub_30x30.map,sha256=RM4ZDkThW1emXOPwyKBr_3TB1JsQ0_NVSr7Ma8AHLdQ,2082
114
+ cogames/maps/evals/extractor_hub_50x50.map,sha256=Y3BhaSqUNXmas-5ESWVmceeKIX4tbHdbCHG5UkWLvy0,4142
115
+ cogames/maps/evals/extractor_hub_70x70.map,sha256=nB-GV-DDDZcUZLciCga5WJJYh932M8xgL7aZiU1OwmI,7002
116
+ cogames/maps/evals/extractor_hub_80x80.map,sha256=hPL2bjISsayK7slBPQkGyQBvkDkWFrxd7jbNSNupXE8,8732
117
+ cogames/maps/planky_evals/aligner_avoid_aoe.map,sha256=9C2pJsASv7rVUfqpLdoMTA1K01wGRJrBXBvbRRXaGqE,648
118
+ cogames/maps/planky_evals/aligner_full_cycle.map,sha256=0ONRKlUI7XSI3L6PhglzNHup_SuNHzsHxl9bNYdmxUw,604
119
+ cogames/maps/planky_evals/aligner_gear.map,sha256=5bK9MwJ3HGzB1sWmRol5AdxZ9rwjPp6-OsfFPPQSdDw,460
120
+ cogames/maps/planky_evals/aligner_hearts.map,sha256=oCF8DpmxyqpIARzlQRwAEZs3mMvy-KMPmVnVAYn---E,474
121
+ cogames/maps/planky_evals/aligner_junction.map,sha256=NzkDOi9lGOpR2avkEPaK2jZcq3x1OBnM-AWc_hTzwUI,542
122
+ cogames/maps/planky_evals/exploration_distant.map,sha256=CMk3M5uzrCUZjdow9_DErD2vJzdLe1e9idsFKkMcxZo,648
123
+ cogames/maps/planky_evals/maze.map,sha256=cJDGu2b9JHOxWQgeXQsGWKO9xN_CGjbeOeypAehPfUY,662
124
+ cogames/maps/planky_evals/miner_best_resource.map,sha256=I5MT8ChAlFu6fXWnD3yqQvqFax9KRjRnCYDTd0hyAAY,542
125
+ cogames/maps/planky_evals/miner_deposit.map,sha256=8DgTMdxpvJ4QAbNyu90twhFKLjnxav0k7sRzTNTEf5c,474
126
+ cogames/maps/planky_evals/miner_extract.map,sha256=XUgtZaXsnA6rcE2W7DBPjQxS4eUsYC3ZnX6IjzY6Ljk,488
127
+ cogames/maps/planky_evals/miner_full_cycle.map,sha256=38nPZ8TujgWIUFzBlZgwDq_Ylr2jlglczgxV53joa7o,560
128
+ cogames/maps/planky_evals/miner_gear.map,sha256=PVh6xU8gNKy2XwDv9Vv4ZaX_-0UtGO3cDQg4EQLVWH4,446
129
+ cogames/maps/planky_evals/multi_role.map,sha256=8HTHlWxWvsXSbpSU9U0Polq08MOdgKLZMkwndXmsqmU,604
130
+ cogames/maps/planky_evals/resource_chain.map,sha256=NWrOKQkcezvZ9LK4Fz26LOYTlLJD2e6AyKk_gxQdNP0,622
131
+ cogames/maps/planky_evals/scout_explore.map,sha256=AiYUNrRBZpI6t-ObSx3yZLAIV1ofdNe9gXzn07U9AF8,662
132
+ cogames/maps/planky_evals/scout_gear.map,sha256=DoC3Dulxih20js67PuE9mXEiLy3kFafZNuHVWaKzjB4,460
133
+ cogames/maps/planky_evals/scrambler_full_cycle.map,sha256=fkmuibPalfsUUMXtawMLt3FquWmJEPb6JdLlTUuDn98,604
134
+ cogames/maps/planky_evals/scrambler_gear.map,sha256=WwUCa_kKUQqPdsS_UG2KgPtZIlBd9sUejo0ls8u7lL4,460
135
+ cogames/maps/planky_evals/scrambler_target.map,sha256=HwwSIvQvGuEmge3MrzLViPZRuWHNcwY6ZFp134GIN30,524
136
+ cogames/maps/planky_evals/stuck_corridor.map,sha256=8wMEjZkZQXevtl2uYKUjFZnln5PWzuePqYRCAooyc_I,572
137
+ cogames/maps/planky_evals/survive_retreat.map,sha256=bf2bWTZQ6ZY1RPMrRQC2lyMufCfGiJ-VvDI_A2aiS4s,542
138
+ cogames/policy/__init__.py,sha256=JFjmvqYzj_j_mQ4Bmqmc60KU49HF63i0s8lIEu1G_b4,116
139
+ cogames/policy/chaos_monkey.py,sha256=FBUK5kZj5Kzgeo8VJ61iFk59AHLLE7Y0bvE7ffPIiHE,1825
140
+ cogames/policy/pufferlib_policy.py,sha256=5JaPTLSsicWNCNWYSiJnbijOCKpjkyie4KKvw0-awYE,5617
141
+ cogames/policy/signal_handler.py,sha256=19_i72AlYZmMifBDvZuaqLVrFIbWLa8mW-7In7nbG3c,2060
142
+ cogames/policy/starter_agent.py,sha256=7jRPOiNLHsR6Nrz6zy09YP02zH87PTQ9ogQadCczd68,7680
143
+ cogames/policy/trainable_policy_template.py,sha256=GbB4vi0wsIiuh_APtfjnavvh9ZVUx4SBmBDhU6Msx7s,7337
144
+ cogames/policy/nim_agents/__init__.py,sha256=q22rmDMKHMO2A4Cqt0P-kuH3f6yaldlaBaRuGydeEKM,1247
145
+ cogames/policy/nim_agents/agents.py,sha256=2uxzs8yxcz3obdA_gaWf0qgojFbXSIU0W3cS-9XD0AI,5038
146
+ cogames/policy/nim_agents/thinky_eval.py,sha256=NqIZng30MpyZD5hF03uoje4potd873hWyHOb3AZdeZk,1154
147
+ cogames-0.3.64.dist-info/licenses/LICENSE,sha256=NG4hf0NHdGZhkabVCK1MKX8RAJmWaEm4eaGcUsONZ_E,1065
148
+ metta_alo/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
149
+ metta_alo/job_specs.py,sha256=_QT23tGb7V8W1jqiUijeQUQh6ZvKfW5-KYiYSuNTdVI,450
150
+ metta_alo/policy.py,sha256=RnBwDzQ7abFiQSJe6MYr_JtsyHlKBES1CkDN6mZuvQI,613
151
+ metta_alo/pure_single_episode_runner.py,sha256=VsSBEn2BVWWHtiZ0SdL9_QMTom_vbbIyPohRVa9rjTc,2720
152
+ metta_alo/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
153
+ metta_alo/rollout.py,sha256=hc7JRQD4ilfqTO57BvKav2v_JW1Vbcc-oYcEmoWVlB4,10192
154
+ metta_alo/scoring.py,sha256=7ikuP6Vnvv57bAc_ARbTadDSf6wm5dCY49xX9QjD_fs,5809
155
+ cogames-0.3.64.dist-info/METADATA,sha256=Vnhu2_9kNcq7ALn4VF4VFMP8j25Mj6ZE1f-d1p7zBU4,234991
156
+ cogames-0.3.64.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
157
+ cogames-0.3.64.dist-info/entry_points.txt,sha256=GTHdgj-RC2hQYmjUMSp9RHX8kbru19k0LS2lAj8DnLE,45
158
+ cogames-0.3.64.dist-info/top_level.txt,sha256=YErBkYWJd3-eksLpbgbMrETni1MPBNL4mqEyhZUa0UE,18
159
+ cogames-0.3.64.dist-info/RECORD,,
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Metta AI
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,2 @@
1
+ cogames
2
+ metta_alo
metta_alo/__init__.py ADDED
File without changes
metta_alo/job_specs.py ADDED
@@ -0,0 +1,17 @@
1
+ from typing import Optional
2
+
3
+ from pydantic import BaseModel, Field
4
+
5
+ from mettagrid import MettaGridConfig
6
+
7
+
8
+ class SingleEpisodeJob(BaseModel):
9
+ policy_uris: list[str]
10
+ assignments: list[int]
11
+ env: MettaGridConfig
12
+ results_uri: Optional[str] = None
13
+ replay_uri: Optional[str] = None
14
+ debug_uri: Optional[str] = None
15
+ seed: int = 0
16
+ max_action_time_ms: int = 10000
17
+ episode_tags: dict[str, str] = Field(default_factory=dict)
metta_alo/policy.py ADDED
@@ -0,0 +1,16 @@
1
+ from typing import Optional
2
+
3
+
4
+ def parse_policy_identifier(identifier: str) -> tuple[str, Optional[int]]:
5
+ """Parse a policy identifier into (name, version)."""
6
+ if identifier.endswith(":latest"):
7
+ return identifier[:-7], None
8
+ if ":" not in identifier:
9
+ return identifier, None
10
+ name, version_str = identifier.rsplit(":", 1)
11
+ if not name:
12
+ raise ValueError(f"Invalid policy identifier: {identifier}")
13
+ version_str = version_str.lstrip("v")
14
+ if not version_str.isdigit():
15
+ raise ValueError(f"Invalid version format: {identifier}")
16
+ return name, int(version_str)
@@ -0,0 +1,75 @@
1
+ import json
2
+ import sys
3
+ from typing import Sequence
4
+
5
+ from pydantic import BaseModel, Field, model_validator
6
+
7
+ from mettagrid import MettaGridConfig
8
+ from mettagrid.types import EpisodeStats
9
+ from mettagrid.util.uri_resolvers.schemes import parse_uri
10
+
11
+
12
+ def _validate_output_uri(uri: str) -> None:
13
+ parsed = parse_uri(uri, allow_none=False)
14
+ if parsed.scheme != "file" or not parsed.local_path.parent.exists():
15
+ raise ValueError(f"URI {uri} must be a file:// URI with an existing parent directory")
16
+
17
+
18
+ def _validate_assignments(assignments: Sequence[int], num_agents: int, num_policies: int) -> None:
19
+ if len(assignments) != num_agents or not all(0 <= assignment < num_policies for assignment in assignments):
20
+ raise ValueError("Assignments must match agent count and be within policy range")
21
+
22
+
23
+ class PureSingleEpisodeJob(BaseModel):
24
+ policy_uris: list[str]
25
+
26
+ # It is important that this is explicit, else the results will have to include the choices we made
27
+ # when randomizing
28
+ assignments: list[int]
29
+
30
+ env: MettaGridConfig
31
+
32
+ # For now, this only supports file:// scheme. Will eventually support https:// to send to s3
33
+ results_uri: str | None # Contains EpisodeRolloutResult
34
+ replay_uri: str | None # Where to place replay file. If missing, do not generate a replay
35
+ debug_dir: str | None = None # Directory for observability outputs (trace.json, etc.)
36
+
37
+ # There's no way to ask us to generate a seed; the caller has to pick one
38
+ seed: int = 0
39
+
40
+ max_action_time_ms: int = 10000
41
+ episode_tags: dict[str, str] = Field(default_factory=dict)
42
+
43
+ @model_validator(mode="after")
44
+ def validate_output_uris(self) -> "PureSingleEpisodeJob":
45
+ for uri in (self.replay_uri, self.results_uri):
46
+ if uri is None:
47
+ continue
48
+ _validate_output_uri(uri)
49
+
50
+ if self.replay_uri is not None and not self.replay_uri.endswith((".json.z", ".json.gz")):
51
+ raise ValueError("Replay URI must end with .json.z or .json.gz")
52
+
53
+ _validate_assignments(self.assignments, self.env.game.num_agents, len(self.policy_uris))
54
+
55
+ return self
56
+
57
+
58
+ class PureSingleEpisodeResult(BaseModel):
59
+ rewards: list[float]
60
+ action_timeouts: list[int]
61
+ stats: EpisodeStats
62
+ steps: int
63
+
64
+
65
+ if __name__ == "__main__":
66
+ from metta_alo.rollout import run_sandboxed_episode
67
+
68
+ with open(sys.argv[1]) as f:
69
+ args = json.load(f)
70
+ job = PureSingleEpisodeJob.model_validate(args["job"])
71
+ allow_network = args.get("allow_network", False)
72
+ if allow_network:
73
+ raise ValueError("allow_network is not supported by the sandboxed runner")
74
+ device = args.get("device")
75
+ run_sandboxed_episode(job, device=device)
metta_alo/py.typed ADDED
File without changes
metta_alo/rollout.py ADDED
@@ -0,0 +1,322 @@
1
+ import json
2
+ import socket
3
+ import sys
4
+ import uuid
5
+ from contextlib import contextmanager, nullcontext
6
+ from pathlib import Path
7
+ from typing import Callable, Optional, Protocol, Sequence
8
+
9
+ import numpy as np
10
+
11
+ from metta_alo.pure_single_episode_runner import (
12
+ PureSingleEpisodeJob,
13
+ PureSingleEpisodeResult,
14
+ _validate_assignments,
15
+ _validate_output_uri,
16
+ )
17
+ from mettagrid import MettaGridConfig
18
+ from mettagrid.policy.loader import AgentPolicy, PolicyEnvInterface, initialize_or_load_policy
19
+ from mettagrid.policy.policy import PolicySpec
20
+ from mettagrid.renderer.renderer import RenderMode
21
+ from mettagrid.simulator.multi_episode.rollout import EpisodeRolloutResult, MultiEpisodeRolloutResult
22
+ from mettagrid.simulator.replay_log_writer import EpisodeReplay, InMemoryReplayWriter
23
+ from mettagrid.simulator.rollout import Rollout
24
+ from mettagrid.util.file import write_data
25
+ from mettagrid.util.tracer import Tracer
26
+ from mettagrid.util.uri_resolvers.schemes import parse_uri, policy_spec_from_uri
27
+
28
+
29
+ class ReplayLike(Protocol):
30
+ def set_compression(self, compression: str) -> None: ...
31
+
32
+ def write_replay(self, path: str) -> None: ...
33
+
34
+
35
+ def write_replay(replay: ReplayLike, path: str) -> None:
36
+ if path.endswith(".gz"):
37
+ replay.set_compression("gzip")
38
+ elif path.endswith(".z"):
39
+ replay.set_compression("zlib")
40
+ replay.write_replay(path)
41
+
42
+
43
+ @contextmanager
44
+ def _no_python_sockets():
45
+ _real_socket = socket.socket
46
+ _real_getaddrinfo = socket.getaddrinfo
47
+
48
+ def _blocked(*args: object, **kwargs: object):
49
+ raise RuntimeError("Network access disabled")
50
+
51
+ socket.socket = _blocked
52
+ socket.getaddrinfo = _blocked
53
+
54
+ try:
55
+ yield
56
+ finally:
57
+ socket.socket = _real_socket
58
+ socket.getaddrinfo = _real_getaddrinfo
59
+
60
+
61
+ def _policy_specs_from_uris(
62
+ policy_uris: Sequence[str],
63
+ *,
64
+ device: Optional[str],
65
+ allow_network: bool,
66
+ ) -> list[PolicySpec]:
67
+ policy_specs: list[PolicySpec] = []
68
+ for uri in policy_uris:
69
+ parsed = parse_uri(uri, allow_none=False)
70
+ if parsed.scheme != "file" and not allow_network:
71
+ raise ValueError("Sandboxed runner requires file:// policy URIs")
72
+ policy_specs.append(
73
+ policy_spec_from_uri(
74
+ uri,
75
+ device=device or "cpu",
76
+ remove_downloaded_copy_on_exit=True,
77
+ )
78
+ )
79
+ return policy_specs
80
+
81
+
82
+ def _write_outputs(
83
+ results: PureSingleEpisodeResult,
84
+ replay: Optional[EpisodeReplay],
85
+ *,
86
+ results_uri: Optional[str],
87
+ replay_uri: Optional[str],
88
+ ) -> None:
89
+ if replay_uri is not None:
90
+ if replay is None:
91
+ raise ValueError("No replay was generated")
92
+ write_replay(replay, replay_uri)
93
+ if results_uri is not None:
94
+ write_data(results_uri, results.model_dump_json(), content_type="application/json")
95
+
96
+
97
+ def _run_pure_episode(
98
+ policy_specs: Sequence[PolicySpec],
99
+ assignments: Sequence[int],
100
+ env: MettaGridConfig,
101
+ *,
102
+ seed: int,
103
+ max_action_time_ms: int,
104
+ device: Optional[str],
105
+ render_mode: RenderMode,
106
+ autostart: bool,
107
+ capture_replay: bool,
108
+ trace_path: Optional[Path] = None,
109
+ ) -> tuple[PureSingleEpisodeResult, Optional[EpisodeReplay]]:
110
+ env_interface = PolicyEnvInterface.from_mg_cfg(env)
111
+ agent_policies: list[AgentPolicy] = [
112
+ initialize_or_load_policy(
113
+ env_interface,
114
+ policy_specs[assignment],
115
+ device_override=device,
116
+ ).agent_policy(agent_id)
117
+ for agent_id, assignment in enumerate(assignments)
118
+ ]
119
+ replay_writer: Optional[InMemoryReplayWriter] = None
120
+ if capture_replay:
121
+ replay_writer = InMemoryReplayWriter()
122
+
123
+ tracer: Optional[Tracer] = None
124
+ if trace_path:
125
+ tracer = Tracer(trace_path)
126
+
127
+ rollout = Rollout(
128
+ env,
129
+ agent_policies,
130
+ max_action_time_ms=max_action_time_ms,
131
+ render_mode=render_mode,
132
+ autostart=autostart,
133
+ seed=seed,
134
+ event_handlers=[replay_writer] if replay_writer is not None else None,
135
+ tracer=tracer,
136
+ )
137
+ rollout.run_until_done()
138
+
139
+ results = PureSingleEpisodeResult(
140
+ rewards=list(rollout._sim.episode_rewards),
141
+ action_timeouts=list(rollout.timeout_counts),
142
+ stats=rollout._sim.episode_stats,
143
+ steps=rollout._sim.current_step,
144
+ )
145
+ replay: Optional[EpisodeReplay] = None
146
+ if replay_writer is not None:
147
+ replays = replay_writer.get_completed_replays()
148
+ if len(replays) != 1:
149
+ raise ValueError(f"Expected 1 replay, got {len(replays)}")
150
+ replay = replays[0]
151
+
152
+ return results, replay
153
+
154
+
155
+ def run_single_episode(
156
+ *,
157
+ policy_specs: Sequence[PolicySpec],
158
+ assignments: Sequence[int],
159
+ env: MettaGridConfig,
160
+ results_uri: Optional[str] = None,
161
+ replay_uri: Optional[str] = None,
162
+ debug_dir: Optional[str] = None,
163
+ seed: int = 0,
164
+ max_action_time_ms: int = 10000,
165
+ device: Optional[str] = None,
166
+ render_mode: Optional[RenderMode] = None,
167
+ autostart: bool = False,
168
+ allow_network: bool = True,
169
+ ) -> tuple[PureSingleEpisodeResult, Optional[EpisodeReplay]]:
170
+ _validate_assignments(assignments, env.game.num_agents, len(policy_specs))
171
+
172
+ for uri in (replay_uri, results_uri):
173
+ if uri is None:
174
+ continue
175
+ _validate_output_uri(uri)
176
+
177
+ if replay_uri is not None and not replay_uri.endswith((".json.z", ".json.gz")):
178
+ raise ValueError("Replay URI must end with .json.z or .json.gz")
179
+
180
+ trace_path: Optional[Path] = None
181
+ if debug_dir is not None:
182
+ debug_path = Path(debug_dir)
183
+ debug_path.mkdir(parents=True, exist_ok=True)
184
+ trace_path = debug_path / "trace.json"
185
+
186
+ with (_no_python_sockets if not allow_network else nullcontext)():
187
+ results, replay = _run_pure_episode(
188
+ policy_specs,
189
+ assignments,
190
+ env,
191
+ seed=seed,
192
+ max_action_time_ms=max_action_time_ms,
193
+ device=device,
194
+ render_mode=render_mode or "none",
195
+ autostart=autostart,
196
+ capture_replay=replay_uri is not None,
197
+ trace_path=trace_path,
198
+ )
199
+
200
+ _write_outputs(results, replay, results_uri=results_uri, replay_uri=replay_uri)
201
+ return results, replay
202
+
203
+
204
+ def run_sandboxed_episode(
205
+ job: PureSingleEpisodeJob,
206
+ *,
207
+ device: Optional[str] = None,
208
+ render_mode: Optional[RenderMode] = None,
209
+ ) -> tuple[PureSingleEpisodeResult, Optional[EpisodeReplay]]:
210
+ policy_specs = _policy_specs_from_uris(job.policy_uris, device=device, allow_network=False)
211
+ return run_single_episode(
212
+ policy_specs=policy_specs,
213
+ assignments=job.assignments,
214
+ env=job.env,
215
+ results_uri=job.results_uri,
216
+ replay_uri=job.replay_uri,
217
+ debug_dir=job.debug_dir,
218
+ seed=job.seed,
219
+ max_action_time_ms=job.max_action_time_ms,
220
+ device=device,
221
+ render_mode=render_mode,
222
+ allow_network=False,
223
+ )
224
+
225
+
226
+ def run_single_episode_rollout(
227
+ *,
228
+ policy_specs: Sequence[PolicySpec],
229
+ assignments: np.ndarray,
230
+ env_cfg: MettaGridConfig,
231
+ seed: int,
232
+ max_action_time_ms: int,
233
+ replay_path: Optional[str] = None,
234
+ device: Optional[str] = None,
235
+ ) -> EpisodeRolloutResult:
236
+ results, _replay = run_single_episode(
237
+ policy_specs=policy_specs,
238
+ assignments=assignments.tolist(),
239
+ env=env_cfg,
240
+ results_uri=None,
241
+ replay_uri=replay_path,
242
+ seed=seed,
243
+ max_action_time_ms=max_action_time_ms,
244
+ device=device,
245
+ )
246
+
247
+ return EpisodeRolloutResult(
248
+ assignments=assignments.copy(),
249
+ rewards=np.array(results.rewards, dtype=float),
250
+ action_timeouts=np.array(results.action_timeouts, dtype=float),
251
+ stats=results.stats,
252
+ replay_path=replay_path,
253
+ steps=results.steps,
254
+ max_steps=env_cfg.game.max_steps,
255
+ )
256
+
257
+
258
+ def run_multi_episode_rollout(
259
+ *,
260
+ policy_specs: Sequence[PolicySpec],
261
+ assignments: np.ndarray,
262
+ env_cfg: MettaGridConfig,
263
+ episodes: int,
264
+ seed: int,
265
+ max_action_time_ms: int,
266
+ replay_dir: Optional[str | Path] = None,
267
+ create_replay_dir: bool = False,
268
+ rng: Optional[np.random.Generator] = None,
269
+ device: Optional[str] = None,
270
+ on_progress: Optional[Callable[[int, EpisodeRolloutResult], None]] = None,
271
+ ) -> tuple[MultiEpisodeRolloutResult, list[str]]:
272
+ if replay_dir is not None and create_replay_dir:
273
+ Path(replay_dir).mkdir(parents=True, exist_ok=True)
274
+
275
+ assignments = np.array(assignments, dtype=int, copy=True)
276
+ rng = rng or np.random.default_rng(seed)
277
+ episode_results: list[EpisodeRolloutResult] = []
278
+ replay_paths: list[str] = []
279
+
280
+ for episode_idx in range(episodes):
281
+ rng.shuffle(assignments)
282
+ replay_path = None
283
+ if replay_dir is not None:
284
+ replay_path = str(Path(replay_dir) / f"{uuid.uuid4()}.json.z")
285
+
286
+ result = run_single_episode_rollout(
287
+ policy_specs=policy_specs,
288
+ assignments=assignments,
289
+ env_cfg=env_cfg,
290
+ seed=seed + episode_idx,
291
+ max_action_time_ms=max_action_time_ms,
292
+ replay_path=replay_path,
293
+ device=device,
294
+ )
295
+ episode_results.append(result)
296
+ if on_progress:
297
+ on_progress(episode_idx, result)
298
+ if replay_path is not None:
299
+ replay_paths.append(replay_path)
300
+
301
+ return MultiEpisodeRolloutResult(episodes=episode_results), replay_paths
302
+
303
+
304
+ if __name__ == "__main__":
305
+ with open(sys.argv[1]) as f:
306
+ args = json.load(f)
307
+ job = PureSingleEpisodeJob.model_validate(args["job"])
308
+ device = args.get("device")
309
+ allow_network = args.get("allow_network", False)
310
+ policy_specs = _policy_specs_from_uris(job.policy_uris, device=device, allow_network=allow_network)
311
+ run_single_episode(
312
+ policy_specs=policy_specs,
313
+ assignments=job.assignments,
314
+ env=job.env,
315
+ results_uri=job.results_uri,
316
+ replay_uri=job.replay_uri,
317
+ debug_dir=job.debug_dir,
318
+ seed=job.seed,
319
+ max_action_time_ms=job.max_action_time_ms,
320
+ device=device,
321
+ allow_network=allow_network,
322
+ )