coworld 0.0.0__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.
Files changed (128) hide show
  1. coworld-0.0.0/.github/workflows/sync-issues-to-asana.yml +37 -0
  2. coworld-0.0.0/AGENTS.md +98 -0
  3. coworld-0.0.0/BUILD.bazel +164 -0
  4. coworld-0.0.0/CLAUDE.md +98 -0
  5. coworld-0.0.0/COOKBOOK.md +340 -0
  6. coworld-0.0.0/Dockerfile.coworld +35 -0
  7. coworld-0.0.0/LESSONS.md +27 -0
  8. coworld-0.0.0/PKG-INFO +130 -0
  9. coworld-0.0.0/README.md +94 -0
  10. coworld-0.0.0/pyproject.toml +100 -0
  11. coworld-0.0.0/scripts/generate_coworld_schemas.py +22 -0
  12. coworld-0.0.0/setup.cfg +4 -0
  13. coworld-0.0.0/src/coworld/__init__.py +63 -0
  14. coworld-0.0.0/src/coworld/__main__.py +3 -0
  15. coworld-0.0.0/src/coworld/api_client.py +581 -0
  16. coworld-0.0.0/src/coworld/bundle.py +124 -0
  17. coworld-0.0.0/src/coworld/certifier.py +406 -0
  18. coworld-0.0.0/src/coworld/cli.py +647 -0
  19. coworld-0.0.0/src/coworld/cli_support.py +13 -0
  20. coworld-0.0.0/src/coworld/commissioner/__init__.py +47 -0
  21. coworld-0.0.0/src/coworld/commissioner/protocol.py +192 -0
  22. coworld-0.0.0/src/coworld/config.py +1 -0
  23. coworld-0.0.0/src/coworld/coworld_manifest_schema.json +571 -0
  24. coworld-0.0.0/src/coworld/docs/COWORLD_MANIFEST.md +157 -0
  25. coworld-0.0.0/src/coworld/docs/LIFECYCLE.md +213 -0
  26. coworld-0.0.0/src/coworld/docs/README.md +201 -0
  27. coworld-0.0.0/src/coworld/docs/artifacts/DEBUG_ARCHIVE.md +46 -0
  28. coworld-0.0.0/src/coworld/docs/artifacts/DIAGNOSIS.md +37 -0
  29. coworld-0.0.0/src/coworld/docs/artifacts/EPISODE_BUNDLE.md +142 -0
  30. coworld-0.0.0/src/coworld/docs/artifacts/ERROR_INFO.md +41 -0
  31. coworld-0.0.0/src/coworld/docs/artifacts/EVENT_LOG.md +46 -0
  32. coworld-0.0.0/src/coworld/docs/artifacts/GAME_LOGS.md +37 -0
  33. coworld-0.0.0/src/coworld/docs/artifacts/GRADE.md +46 -0
  34. coworld-0.0.0/src/coworld/docs/artifacts/OPTIMIZER_OUTPUTS.md +39 -0
  35. coworld-0.0.0/src/coworld/docs/artifacts/PLAYER_LOGS.md +38 -0
  36. coworld-0.0.0/src/coworld/docs/artifacts/README.md +29 -0
  37. coworld-0.0.0/src/coworld/docs/artifacts/REPLAY.md +54 -0
  38. coworld-0.0.0/src/coworld/docs/artifacts/REPORT.md +50 -0
  39. coworld-0.0.0/src/coworld/docs/artifacts/RESULTS.md +43 -0
  40. coworld-0.0.0/src/coworld/docs/artifacts/ROUND_DECISIONS.md +31 -0
  41. coworld-0.0.0/src/coworld/docs/roles/COMMISSIONER.md +468 -0
  42. coworld-0.0.0/src/coworld/docs/roles/DIAGNOSER.md +93 -0
  43. coworld-0.0.0/src/coworld/docs/roles/GAME.md +96 -0
  44. coworld-0.0.0/src/coworld/docs/roles/GRADER.md +93 -0
  45. coworld-0.0.0/src/coworld/docs/roles/OPTIMIZER.md +107 -0
  46. coworld-0.0.0/src/coworld/docs/roles/PLAYER.md +130 -0
  47. coworld-0.0.0/src/coworld/docs/roles/REPORTER.md +88 -0
  48. coworld-0.0.0/src/coworld/examples/__init__.py +0 -0
  49. coworld-0.0.0/src/coworld/examples/paintarena/Dockerfile +22 -0
  50. coworld-0.0.0/src/coworld/examples/paintarena/README.md +85 -0
  51. coworld-0.0.0/src/coworld/examples/paintarena/__init__.py +0 -0
  52. coworld-0.0.0/src/coworld/examples/paintarena/compose.yaml +9 -0
  53. coworld-0.0.0/src/coworld/examples/paintarena/coworld_manifest_template.json +238 -0
  54. coworld-0.0.0/src/coworld/examples/paintarena/game/__init__.py +0 -0
  55. coworld-0.0.0/src/coworld/examples/paintarena/game/client/admin.html +60 -0
  56. coworld-0.0.0/src/coworld/examples/paintarena/game/client/global.html +250 -0
  57. coworld-0.0.0/src/coworld/examples/paintarena/game/client/player.html +271 -0
  58. coworld-0.0.0/src/coworld/examples/paintarena/game/client/replay.html +325 -0
  59. coworld-0.0.0/src/coworld/examples/paintarena/game/docs/global_protocol_spec.md +41 -0
  60. coworld-0.0.0/src/coworld/examples/paintarena/game/docs/player_protocol_spec.md +39 -0
  61. coworld-0.0.0/src/coworld/examples/paintarena/game/server.py +362 -0
  62. coworld-0.0.0/src/coworld/examples/paintarena/optimizer/README.md +17 -0
  63. coworld-0.0.0/src/coworld/examples/paintarena/optimizer/__init__.py +1 -0
  64. coworld-0.0.0/src/coworld/examples/paintarena/optimizer/paint_arena_optimizer.py +138 -0
  65. coworld-0.0.0/src/coworld/examples/paintarena/player/__init__.py +0 -0
  66. coworld-0.0.0/src/coworld/examples/paintarena/player/player.py +51 -0
  67. coworld-0.0.0/src/coworld/examples/paintarena/reporter/__init__.py +0 -0
  68. coworld-0.0.0/src/coworld/examples/paintarena/reporter/_sdk_vendored/__init__.py +76 -0
  69. coworld-0.0.0/src/coworld/examples/paintarena/reporter/_sdk_vendored/bundle.py +107 -0
  70. coworld-0.0.0/src/coworld/examples/paintarena/reporter/_sdk_vendored/event_log.py +75 -0
  71. coworld-0.0.0/src/coworld/examples/paintarena/reporter/_sdk_vendored/io.py +123 -0
  72. coworld-0.0.0/src/coworld/examples/paintarena/reporter/_sdk_vendored/output_manifest.py +100 -0
  73. coworld-0.0.0/src/coworld/examples/paintarena/reporter/_sdk_vendored/zip_writer.py +55 -0
  74. coworld-0.0.0/src/coworld/examples/paintarena/reporter/paint_arena_summarizer.py +298 -0
  75. coworld-0.0.0/src/coworld/examples/paintarena/reporter/stats_reporter.py +142 -0
  76. coworld-0.0.0/src/coworld/examples/paintarena/shared/__init__.py +0 -0
  77. coworld-0.0.0/src/coworld/examples/paintarena/shared/log_shipper.py +54 -0
  78. coworld-0.0.0/src/coworld/manifest_uri.py +142 -0
  79. coworld-0.0.0/src/coworld/manifest_validation.py +60 -0
  80. coworld-0.0.0/src/coworld/play.py +391 -0
  81. coworld-0.0.0/src/coworld/policies/__init__.py +1 -0
  82. coworld-0.0.0/src/coworld/policies/amongthemstarter/.dockerignore +6 -0
  83. coworld-0.0.0/src/coworld/policies/amongthemstarter/Dockerfile.amongthemstarter +57 -0
  84. coworld-0.0.0/src/coworld/policies/amongthemstarter/README.md +19 -0
  85. coworld-0.0.0/src/coworld/policies/amongthemstarter/amongthemstarter.nim +4581 -0
  86. coworld-0.0.0/src/coworld/policies/cogs_vs_clips/.dockerignore +5 -0
  87. coworld-0.0.0/src/coworld/policies/cogs_vs_clips/Dockerfile.cogs_vs_clips +7 -0
  88. coworld-0.0.0/src/coworld/policies/cogs_vs_clips/README.md +19 -0
  89. coworld-0.0.0/src/coworld/policies/cogs_vs_clips/player.py +55 -0
  90. coworld-0.0.0/src/coworld/py.typed +1 -0
  91. coworld-0.0.0/src/coworld/runner/KUBERNETES_RUNNER_README.md +228 -0
  92. coworld-0.0.0/src/coworld/runner/RUNNER_README.md +33 -0
  93. coworld-0.0.0/src/coworld/runner/__init__.py +1 -0
  94. coworld-0.0.0/src/coworld/runner/episode_request_schema.json +636 -0
  95. coworld-0.0.0/src/coworld/runner/io.py +78 -0
  96. coworld-0.0.0/src/coworld/runner/kubernetes_runner.py +538 -0
  97. coworld-0.0.0/src/coworld/runner/runner.py +513 -0
  98. coworld-0.0.0/src/coworld/schema_validation.py +22 -0
  99. coworld-0.0.0/src/coworld/starter_policy.py +68 -0
  100. coworld-0.0.0/src/coworld/submit.py +54 -0
  101. coworld-0.0.0/src/coworld/tournament_cli.py +988 -0
  102. coworld-0.0.0/src/coworld/types.py +387 -0
  103. coworld-0.0.0/src/coworld/upload.py +801 -0
  104. coworld-0.0.0/src/coworld.egg-info/PKG-INFO +130 -0
  105. coworld-0.0.0/src/coworld.egg-info/SOURCES.txt +126 -0
  106. coworld-0.0.0/src/coworld.egg-info/dependency_links.txt +1 -0
  107. coworld-0.0.0/src/coworld.egg-info/entry_points.txt +2 -0
  108. coworld-0.0.0/src/coworld.egg-info/requires.txt +29 -0
  109. coworld-0.0.0/src/coworld.egg-info/top_level.txt +1 -0
  110. coworld-0.0.0/tests/BUILD.bazel +43 -0
  111. coworld-0.0.0/tests/test_canonical_worlds.py +401 -0
  112. coworld-0.0.0/tests/test_commissioner_protocol.py +155 -0
  113. coworld-0.0.0/tests/test_coworld_bundle.py +431 -0
  114. coworld-0.0.0/tests/test_coworld_certifier.py +1557 -0
  115. coworld-0.0.0/tests/test_coworld_cli_manifest_uri.py +574 -0
  116. coworld-0.0.0/tests/test_coworld_kubernetes_runner.py +786 -0
  117. coworld-0.0.0/tests/test_coworld_make_policy.py +88 -0
  118. coworld-0.0.0/tests/test_coworld_manifest_uri.py +117 -0
  119. coworld-0.0.0/tests/test_coworld_runner_io.py +72 -0
  120. coworld-0.0.0/tests/test_coworld_submit_cli.py +116 -0
  121. coworld-0.0.0/tests/test_coworld_tournament_cli.py +499 -0
  122. coworld-0.0.0/tests/test_coworld_upload_cli.py +1183 -0
  123. coworld-0.0.0/tests/test_paintarena_optimizer.py +51 -0
  124. coworld-0.0.0/tests/test_paintarena_replay_loader.py +27 -0
  125. coworld-0.0.0/tests/test_paintarena_reporter.py +429 -0
  126. coworld-0.0.0/tests/test_paintarena_reporter_http_io.py +126 -0
  127. coworld-0.0.0/tests/test_paintarena_stats_reporter.py +180 -0
  128. coworld-0.0.0/tests/test_types.py +401 -0
@@ -0,0 +1,37 @@
1
+ name: Sync GitHub issues to Asana
2
+
3
+ on:
4
+ issues:
5
+ types: [opened]
6
+
7
+ jobs:
8
+ create-asana-task:
9
+ runs-on: ubuntu-latest
10
+ steps:
11
+ - name: Create Asana task
12
+ env:
13
+ ASANA_TOKEN: ${{ secrets.ASANA_TOKEN }}
14
+ ASANA_PROJECT_GID: "1210062854657778"
15
+ ISSUE_TITLE: ${{ github.event.issue.title }}
16
+ ISSUE_URL: ${{ github.event.issue.html_url }}
17
+ ISSUE_AUTHOR: ${{ github.event.issue.user.login }}
18
+ ISSUE_BODY: ${{ github.event.issue.body }}
19
+ run: |
20
+ NOTES=$(printf "GitHub Issue: %s\n\nFiled by: %s\n\n%s" "$ISSUE_URL" "$ISSUE_AUTHOR" "$ISSUE_BODY")
21
+ BODY=$(jq -n \
22
+ --arg name "$ISSUE_TITLE" \
23
+ --arg notes "$NOTES" \
24
+ --arg project "$ASANA_PROJECT_GID" \
25
+ '{data: {name: $name, notes: $notes, projects: [$project]}}')
26
+
27
+ RESPONSE=$(curl -s -w "\n%{http_code}" -X POST "https://app.asana.com/api/1.0/tasks" \
28
+ -H "Authorization: Bearer $ASANA_TOKEN" \
29
+ -H "Content-Type: application/json" \
30
+ -d "$BODY")
31
+
32
+ HTTP_CODE=$(echo "$RESPONSE" | tail -1)
33
+
34
+ if [ "$HTTP_CODE" -lt 200 ] || [ "$HTTP_CODE" -ge 300 ]; then
35
+ echo "Asana API returned HTTP $HTTP_CODE"
36
+ exit 1
37
+ fi
@@ -0,0 +1,98 @@
1
+ # AGENTS.md - coworld
2
+
3
+ Public CLI and Python package for Softmax v2 tournaments ("Coworlds"). This package owns the user-facing `coworld`
4
+ entrypoint, local episode/play tooling, Coworld uploads, policy uploads/submission helpers, the Paint Arena reference
5
+ Coworld, and the public Coworld docs shipped with the package. It depends on `softmax-cli` for auth-backed commands.
6
+
7
+ ## Before Editing
8
+
9
+ - Read this file, `LESSONS.md`, the package [README](README.md), and the [Coworld docs map](src/coworld/docs/README.md)
10
+ before changing user-facing Coworld behavior or docs.
11
+ - Keep package docs public-package-facing. Avoid private Metta backend paths unless the document is intentionally
12
+ explaining a platform integration boundary.
13
+ - Treat Paint Arena under `src/coworld/examples/paintarena/` as the canonical in-tree example.
14
+
15
+ ## CLI
16
+
17
+ The package installs the Typer app at `coworld.cli:app`:
18
+
19
+ ```bash
20
+ uv run coworld --help
21
+ uv run coworld leagues
22
+ uv run coworld download <coworld-name-or-id> --output-dir ./coworld
23
+ uv run coworld run-episode <manifest.json> <image:tag>
24
+ uv run coworld play <manifest.json> [image|request.json]
25
+ uv run coworld build / certify / upload-coworld
26
+ uv run coworld upload-policy / submit
27
+ ```
28
+
29
+ Auth-backed commands require `uv run softmax login` first. The `auth` extra pulls in `softmax-cli`.
30
+
31
+ ## Validation
32
+
33
+ Use the narrowest check that covers the touched surface, then broaden when changing shared contracts:
34
+
35
+ ```bash
36
+ uv run metta pytest packages/coworld/tests/test_types.py -v
37
+ uv run metta pytest packages/coworld/tests -v
38
+ uv run metta pytest --changed
39
+ uv run metta lint --fix
40
+ ```
41
+
42
+ When changing manifest Pydantic models or generated schema files, update `types.py` first and regenerate the checked-in
43
+ schema JSON:
44
+
45
+ ```bash
46
+ uv run --project packages/coworld python packages/coworld/scripts/generate_coworld_schemas.py
47
+ uv run metta pytest packages/coworld/tests/test_types.py -v
48
+ ```
49
+
50
+ Do not hand-edit `src/coworld/coworld_manifest_schema.json` or `src/coworld/runner/episode_request_schema.json` as the
51
+ source of truth. They are generated docs and `$schema` targets; `test_types.py` checks that they match `types.py`.
52
+
53
+ ## Source Layout
54
+
55
+ - `src/coworld/cli.py`, `tournament_cli.py` - Typer command surface for local episodes, uploads, leagues, and hosted
56
+ tournament inspection.
57
+ - `src/coworld/cli_support.py`, `api_client.py` - shared CLI helpers and the Softmax/Coworld API client.
58
+ - `src/coworld/certifier.py` - `coworld certify` smoke-test pipeline.
59
+ - `src/coworld/manifest_validation.py`, `schema_validation.py`, `manifest_uri.py` - manifest and schema validation.
60
+ - `src/coworld/bundle.py` - episode-bundle assembly around `COGAME_EPISODE_BUNDLE_URI`.
61
+ - `src/coworld/play.py`, `src/coworld/runner/` - local play, local episode runner, and hosted-runner contracts.
62
+ - `src/coworld/starter_policy.py`, `src/coworld/policies/` - packaged starter policy templates.
63
+ - `src/coworld/commissioner/`, `submit.py`, `upload.py` - league round-running, submission, and upload support.
64
+ - `src/coworld/examples/paintarena/` - smallest complete Coworld and reference implementation.
65
+
66
+ ## Documentation Map
67
+
68
+ - [README.md](README.md) - package landing page, player-first orientation, and navigation.
69
+ - [COOKBOOK.md](COOKBOOK.md) - task recipes for local play, policy upload/submission, tournament results, and
70
+ Coworld upload.
71
+ - [src/coworld/docs/README.md](src/coworld/docs/README.md) - Coworld concept map, role statuses, artifact flow, and
72
+ cross-links.
73
+ - [src/coworld/docs/COWORLD_MANIFEST.md](src/coworld/docs/COWORLD_MANIFEST.md) - manifest semantics and schema source
74
+ of truth.
75
+ - [src/coworld/docs/LIFECYCLE.md](src/coworld/docs/LIFECYCLE.md) - local and hosted episode lifecycle.
76
+ - `src/coworld/docs/roles/*.md` - per-role contracts.
77
+ - `src/coworld/docs/artifacts/*.md` - artifact contracts.
78
+ - `src/coworld/runner/RUNNER_README.md` and `src/coworld/runner/KUBERNETES_RUNNER_README.md` - runner-specific
79
+ behavior.
80
+
81
+ ## Manifest And Role Contracts
82
+
83
+ - The schema currently requires `game`, `player`, and `reporter`. `commissioner`, `grader`, `diagnoser`, and
84
+ `optimizer` are optional today and marked future-required in generated schema metadata.
85
+ - Role semantics belong in `src/coworld/docs/roles/`. Field-level manifest shape belongs in `src/coworld/types.py` and
86
+ the generated schema JSON, not in duplicated Markdown tables.
87
+ - Manifest role changes usually need matching updates to role docs, Paint Arena templates, generated schemas,
88
+ certifier/runner tests, and any README links that name the role.
89
+ - Do not describe `coworld hosted-game` as a supported player workflow unless product/runtime support is restored.
90
+ Current hosted execution means tournament jobs where the platform runs the game and every player container.
91
+
92
+ ## Package Data Gotchas
93
+
94
+ - Versioning uses `setuptools_scm` from `coworld-v*` git tags (`fallback_version = "0.0.0"`).
95
+ - `pyproject.toml` deliberately excludes Dockerfiles and example READMEs from wheel package data. Non-runtime example
96
+ edits should not change wheel content or Bazel action keys for downstream `@pyenv` consumers.
97
+ - Antfarm hosts Coworld game containers; keep `packages/antfarm/README.md` aligned when the game-container contract
98
+ changes.
@@ -0,0 +1,164 @@
1
+ load("@rules_python//python:defs.bzl", "py_binary", "py_library")
2
+
3
+ # Build the paintarena example image via the host docker daemon. Tags the
4
+ # image `coworld-paintarena:latest` in the local docker store and writes a
5
+ # digest-pinned reference (`coworld-paintarena@sha256:<digest>`) to the
6
+ # output file so downstream consumers can address the exact build.
7
+ #
8
+ # Tagged `manual` so it stays out of `//...` wildcard builds — CI runners
9
+ # without a docker daemon would otherwise fail the wildcard.
10
+ genrule(
11
+ name = "paintarena_image",
12
+ srcs = [
13
+ "src/coworld/examples/paintarena/Dockerfile",
14
+ "src/coworld/examples/paintarena/__init__.py",
15
+ ] + glob([
16
+ "src/coworld/examples/paintarena/game/**",
17
+ "src/coworld/examples/paintarena/optimizer/**",
18
+ "src/coworld/examples/paintarena/player/**",
19
+ "src/coworld/examples/paintarena/reporter/**",
20
+ "src/coworld/examples/paintarena/shared/**",
21
+ ]),
22
+ outs = ["paintarena_image.ref"],
23
+ cmd = """
24
+ set -euo pipefail
25
+ # Bazel sanitizes PATH for actions; ensure standard host locations are
26
+ # searched so the host docker (or podman shimming docker) is reachable.
27
+ export PATH="/run/current-system/sw/bin:/usr/local/bin:/usr/bin:/bin$${PATH:+:$$PATH}"
28
+ ctx=$$(dirname $(location src/coworld/examples/paintarena/Dockerfile))
29
+ iidfile=$$(mktemp)
30
+ trap 'rm -f "$$iidfile"' EXIT
31
+ # Cloudflare Containers run amd64; build for that arch so the image is
32
+ # pullable there even when built on an arm64 (Apple Silicon) dev machine.
33
+ docker build --platform linux/amd64 --iidfile "$$iidfile" --tag coworld-paintarena:latest "$$ctx" >&2
34
+ iid=$$(cat "$$iidfile")
35
+ echo "coworld-paintarena@$$iid" > $@
36
+ """,
37
+ local = 1,
38
+ tags = ["manual"],
39
+ visibility = ["//visibility:public"],
40
+ )
41
+
42
+ # `:coworld_core` is the import-surface every external library consumer
43
+ # (//app_backend, //metta:metta_obs, //worlds) actually needs:
44
+ #
45
+ # coworld.types, coworld.certifier, coworld.manifest_validation,
46
+ # coworld.schema_validation, coworld.commissioner.protocol,
47
+ # coworld.runner.io, coworld.runner.runner — plus the transitive
48
+ # imports of `coworld.__init__`'s eager facade (certifier, play,
49
+ # runner.runner, types).
50
+ #
51
+ # Everything else — the CLI (`cli.py`, `tournament_cli.py`,
52
+ # `bundle.py`, `submit.py`, `upload.py`, `starter_policy.py`,
53
+ # `manifest_uri.py`, `__main__.py`), the example servers under
54
+ # `examples/**`, the policy templates under `policies/**`, and the
55
+ # kubernetes runner that only the CLI and tests load — stays in
56
+ # `:coworld`. Action keys for downstream tests that only hit the
57
+ # library surface no longer flip when CLI / example / policy files
58
+ # change.
59
+ #
60
+ # `coworld_manifest_schema.json` and `runner/episode_request_schema.json`
61
+ # are NOT in `data` on either target: nothing reads them at runtime
62
+ # (they're generated dynamically from pydantic via
63
+ # `coworld.types.coworld_manifest_schema()` /
64
+ # `coworld.types.coworld_episode_request_schema()`). The on-disk
65
+ # copies exist only as docs / `$schema` URLs referenced from READMEs.
66
+ _CORE_SRCS = [
67
+ "src/coworld/__init__.py",
68
+ "src/coworld/certifier.py",
69
+ "src/coworld/commissioner/__init__.py",
70
+ "src/coworld/commissioner/protocol.py",
71
+ "src/coworld/manifest_validation.py",
72
+ "src/coworld/play.py",
73
+ "src/coworld/runner/__init__.py",
74
+ "src/coworld/runner/io.py",
75
+ "src/coworld/runner/runner.py",
76
+ "src/coworld/schema_validation.py",
77
+ "src/coworld/types.py",
78
+ ]
79
+
80
+ # Test-only runfiles for validating checked-in generated schemas against
81
+ # coworld.types' dynamic Pydantic schema output.
82
+ filegroup(
83
+ name = "generated_schema_files",
84
+ srcs = [
85
+ "src/coworld/coworld_manifest_schema.json",
86
+ "src/coworld/runner/episode_request_schema.json",
87
+ ],
88
+ visibility = ["//packages/coworld/tests:__pkg__"],
89
+ )
90
+
91
+ py_library(
92
+ name = "coworld_core",
93
+ srcs = _CORE_SRCS,
94
+ data = ["src/coworld/py.typed"],
95
+ imports = ["src"],
96
+ visibility = ["//visibility:public"],
97
+ deps = [
98
+ "@pypi//httpx",
99
+ "@pypi//jsonschema",
100
+ "@pypi//packaging",
101
+ "@pypi//pydantic",
102
+ "@pypi//referencing",
103
+ "@pypi//websockets",
104
+ ],
105
+ )
106
+
107
+ py_library(
108
+ name = "coworld",
109
+ srcs = glob(
110
+ ["src/coworld/**/*.py"],
111
+ exclude = _CORE_SRCS,
112
+ ),
113
+ # Runtime data for the CLI and the example servers. Library
114
+ # consumers don't need any of this; they get `py.typed` via
115
+ # `:coworld_core` and nothing else.
116
+ data = glob(
117
+ [
118
+ "src/coworld/examples/**/*.py",
119
+ "src/coworld/examples/**/*.json",
120
+ "src/coworld/examples/**/*.html",
121
+ "src/coworld/policies/amongthemstarter/**/*",
122
+ "src/coworld/policies/amongthemstarter/.dockerignore",
123
+ "src/coworld/policies/cogs_vs_clips/**/*",
124
+ "src/coworld/policies/cogs_vs_clips/.dockerignore",
125
+ ],
126
+ allow_empty = True,
127
+ ),
128
+ imports = ["src"],
129
+ visibility = ["//visibility:public"],
130
+ deps = [
131
+ ":coworld_core",
132
+ "//packages/softmax-cli:softmax",
133
+ # cogsguard's wheel METADATA used to declare `Requires-Dist: cogames`
134
+ # but our patch strips that to dodge the @pypi//cogames ghost
135
+ # reference. cogsguard.missions.machina_1 imports cogames at module
136
+ # load, so we add cogames explicitly for any consumer of
137
+ # //packages/coworld:coworld that transits cogsguard.
138
+ "//packages/cogames:cogames",
139
+ "@pypi//cogsguard",
140
+ "@pypi//fastapi",
141
+ "@pypi//httpx",
142
+ "@pypi//jsonschema",
143
+ "@pypi//kubernetes",
144
+ "//packages/mettagrid/python/src/mettagrid:mettagrid",
145
+ "@pypi//numpy",
146
+ "@pypi//pyarrow",
147
+ "@pypi//pydantic",
148
+ "@pypi//referencing",
149
+ "@pypi//requests",
150
+ "@pypi//rich",
151
+ "@pypi//typer",
152
+ "@pypi//uvicorn",
153
+ "@pypi//websockets",
154
+ ],
155
+ )
156
+
157
+ py_binary(
158
+ name = "coworld_bin",
159
+ srcs = ["src/coworld/cli.py"],
160
+ main = "src/coworld/cli.py",
161
+ imports = ["src"],
162
+ visibility = ["//visibility:public"],
163
+ deps = [":coworld"],
164
+ )
@@ -0,0 +1,98 @@
1
+ # AGENTS.md - coworld
2
+
3
+ Public CLI and Python package for Softmax v2 tournaments ("Coworlds"). This package owns the user-facing `coworld`
4
+ entrypoint, local episode/play tooling, Coworld uploads, policy uploads/submission helpers, the Paint Arena reference
5
+ Coworld, and the public Coworld docs shipped with the package. It depends on `softmax-cli` for auth-backed commands.
6
+
7
+ ## Before Editing
8
+
9
+ - Read this file, `LESSONS.md`, the package [README](README.md), and the [Coworld docs map](src/coworld/docs/README.md)
10
+ before changing user-facing Coworld behavior or docs.
11
+ - Keep package docs public-package-facing. Avoid private Metta backend paths unless the document is intentionally
12
+ explaining a platform integration boundary.
13
+ - Treat Paint Arena under `src/coworld/examples/paintarena/` as the canonical in-tree example.
14
+
15
+ ## CLI
16
+
17
+ The package installs the Typer app at `coworld.cli:app`:
18
+
19
+ ```bash
20
+ uv run coworld --help
21
+ uv run coworld leagues
22
+ uv run coworld download <coworld-name-or-id> --output-dir ./coworld
23
+ uv run coworld run-episode <manifest.json> <image:tag>
24
+ uv run coworld play <manifest.json> [image|request.json]
25
+ uv run coworld build / certify / upload-coworld
26
+ uv run coworld upload-policy / submit
27
+ ```
28
+
29
+ Auth-backed commands require `uv run softmax login` first. The `auth` extra pulls in `softmax-cli`.
30
+
31
+ ## Validation
32
+
33
+ Use the narrowest check that covers the touched surface, then broaden when changing shared contracts:
34
+
35
+ ```bash
36
+ uv run metta pytest packages/coworld/tests/test_types.py -v
37
+ uv run metta pytest packages/coworld/tests -v
38
+ uv run metta pytest --changed
39
+ uv run metta lint --fix
40
+ ```
41
+
42
+ When changing manifest Pydantic models or generated schema files, update `types.py` first and regenerate the checked-in
43
+ schema JSON:
44
+
45
+ ```bash
46
+ uv run --project packages/coworld python packages/coworld/scripts/generate_coworld_schemas.py
47
+ uv run metta pytest packages/coworld/tests/test_types.py -v
48
+ ```
49
+
50
+ Do not hand-edit `src/coworld/coworld_manifest_schema.json` or `src/coworld/runner/episode_request_schema.json` as the
51
+ source of truth. They are generated docs and `$schema` targets; `test_types.py` checks that they match `types.py`.
52
+
53
+ ## Source Layout
54
+
55
+ - `src/coworld/cli.py`, `tournament_cli.py` - Typer command surface for local episodes, uploads, leagues, and hosted
56
+ tournament inspection.
57
+ - `src/coworld/cli_support.py`, `api_client.py` - shared CLI helpers and the Softmax/Coworld API client.
58
+ - `src/coworld/certifier.py` - `coworld certify` smoke-test pipeline.
59
+ - `src/coworld/manifest_validation.py`, `schema_validation.py`, `manifest_uri.py` - manifest and schema validation.
60
+ - `src/coworld/bundle.py` - episode-bundle assembly around `COGAME_EPISODE_BUNDLE_URI`.
61
+ - `src/coworld/play.py`, `src/coworld/runner/` - local play, local episode runner, and hosted-runner contracts.
62
+ - `src/coworld/starter_policy.py`, `src/coworld/policies/` - packaged starter policy templates.
63
+ - `src/coworld/commissioner/`, `submit.py`, `upload.py` - league round-running, submission, and upload support.
64
+ - `src/coworld/examples/paintarena/` - smallest complete Coworld and reference implementation.
65
+
66
+ ## Documentation Map
67
+
68
+ - [README.md](README.md) - package landing page, player-first orientation, and navigation.
69
+ - [COOKBOOK.md](COOKBOOK.md) - task recipes for local play, policy upload/submission, tournament results, and
70
+ Coworld upload.
71
+ - [src/coworld/docs/README.md](src/coworld/docs/README.md) - Coworld concept map, role statuses, artifact flow, and
72
+ cross-links.
73
+ - [src/coworld/docs/COWORLD_MANIFEST.md](src/coworld/docs/COWORLD_MANIFEST.md) - manifest semantics and schema source
74
+ of truth.
75
+ - [src/coworld/docs/LIFECYCLE.md](src/coworld/docs/LIFECYCLE.md) - local and hosted episode lifecycle.
76
+ - `src/coworld/docs/roles/*.md` - per-role contracts.
77
+ - `src/coworld/docs/artifacts/*.md` - artifact contracts.
78
+ - `src/coworld/runner/RUNNER_README.md` and `src/coworld/runner/KUBERNETES_RUNNER_README.md` - runner-specific
79
+ behavior.
80
+
81
+ ## Manifest And Role Contracts
82
+
83
+ - The schema currently requires `game`, `player`, and `reporter`. `commissioner`, `grader`, `diagnoser`, and
84
+ `optimizer` are optional today and marked future-required in generated schema metadata.
85
+ - Role semantics belong in `src/coworld/docs/roles/`. Field-level manifest shape belongs in `src/coworld/types.py` and
86
+ the generated schema JSON, not in duplicated Markdown tables.
87
+ - Manifest role changes usually need matching updates to role docs, Paint Arena templates, generated schemas,
88
+ certifier/runner tests, and any README links that name the role.
89
+ - Do not describe `coworld hosted-game` as a supported player workflow unless product/runtime support is restored.
90
+ Current hosted execution means tournament jobs where the platform runs the game and every player container.
91
+
92
+ ## Package Data Gotchas
93
+
94
+ - Versioning uses `setuptools_scm` from `coworld-v*` git tags (`fallback_version = "0.0.0"`).
95
+ - `pyproject.toml` deliberately excludes Dockerfiles and example READMEs from wheel package data. Non-runtime example
96
+ edits should not change wheel content or Bazel action keys for downstream `@pyenv` consumers.
97
+ - Antfarm hosts Coworld game containers; keep `packages/antfarm/README.md` aligned when the game-container contract
98
+ changes.