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.
- coworld-0.0.0/.github/workflows/sync-issues-to-asana.yml +37 -0
- coworld-0.0.0/AGENTS.md +98 -0
- coworld-0.0.0/BUILD.bazel +164 -0
- coworld-0.0.0/CLAUDE.md +98 -0
- coworld-0.0.0/COOKBOOK.md +340 -0
- coworld-0.0.0/Dockerfile.coworld +35 -0
- coworld-0.0.0/LESSONS.md +27 -0
- coworld-0.0.0/PKG-INFO +130 -0
- coworld-0.0.0/README.md +94 -0
- coworld-0.0.0/pyproject.toml +100 -0
- coworld-0.0.0/scripts/generate_coworld_schemas.py +22 -0
- coworld-0.0.0/setup.cfg +4 -0
- coworld-0.0.0/src/coworld/__init__.py +63 -0
- coworld-0.0.0/src/coworld/__main__.py +3 -0
- coworld-0.0.0/src/coworld/api_client.py +581 -0
- coworld-0.0.0/src/coworld/bundle.py +124 -0
- coworld-0.0.0/src/coworld/certifier.py +406 -0
- coworld-0.0.0/src/coworld/cli.py +647 -0
- coworld-0.0.0/src/coworld/cli_support.py +13 -0
- coworld-0.0.0/src/coworld/commissioner/__init__.py +47 -0
- coworld-0.0.0/src/coworld/commissioner/protocol.py +192 -0
- coworld-0.0.0/src/coworld/config.py +1 -0
- coworld-0.0.0/src/coworld/coworld_manifest_schema.json +571 -0
- coworld-0.0.0/src/coworld/docs/COWORLD_MANIFEST.md +157 -0
- coworld-0.0.0/src/coworld/docs/LIFECYCLE.md +213 -0
- coworld-0.0.0/src/coworld/docs/README.md +201 -0
- coworld-0.0.0/src/coworld/docs/artifacts/DEBUG_ARCHIVE.md +46 -0
- coworld-0.0.0/src/coworld/docs/artifacts/DIAGNOSIS.md +37 -0
- coworld-0.0.0/src/coworld/docs/artifacts/EPISODE_BUNDLE.md +142 -0
- coworld-0.0.0/src/coworld/docs/artifacts/ERROR_INFO.md +41 -0
- coworld-0.0.0/src/coworld/docs/artifacts/EVENT_LOG.md +46 -0
- coworld-0.0.0/src/coworld/docs/artifacts/GAME_LOGS.md +37 -0
- coworld-0.0.0/src/coworld/docs/artifacts/GRADE.md +46 -0
- coworld-0.0.0/src/coworld/docs/artifacts/OPTIMIZER_OUTPUTS.md +39 -0
- coworld-0.0.0/src/coworld/docs/artifacts/PLAYER_LOGS.md +38 -0
- coworld-0.0.0/src/coworld/docs/artifacts/README.md +29 -0
- coworld-0.0.0/src/coworld/docs/artifacts/REPLAY.md +54 -0
- coworld-0.0.0/src/coworld/docs/artifacts/REPORT.md +50 -0
- coworld-0.0.0/src/coworld/docs/artifacts/RESULTS.md +43 -0
- coworld-0.0.0/src/coworld/docs/artifacts/ROUND_DECISIONS.md +31 -0
- coworld-0.0.0/src/coworld/docs/roles/COMMISSIONER.md +468 -0
- coworld-0.0.0/src/coworld/docs/roles/DIAGNOSER.md +93 -0
- coworld-0.0.0/src/coworld/docs/roles/GAME.md +96 -0
- coworld-0.0.0/src/coworld/docs/roles/GRADER.md +93 -0
- coworld-0.0.0/src/coworld/docs/roles/OPTIMIZER.md +107 -0
- coworld-0.0.0/src/coworld/docs/roles/PLAYER.md +130 -0
- coworld-0.0.0/src/coworld/docs/roles/REPORTER.md +88 -0
- coworld-0.0.0/src/coworld/examples/__init__.py +0 -0
- coworld-0.0.0/src/coworld/examples/paintarena/Dockerfile +22 -0
- coworld-0.0.0/src/coworld/examples/paintarena/README.md +85 -0
- coworld-0.0.0/src/coworld/examples/paintarena/__init__.py +0 -0
- coworld-0.0.0/src/coworld/examples/paintarena/compose.yaml +9 -0
- coworld-0.0.0/src/coworld/examples/paintarena/coworld_manifest_template.json +238 -0
- coworld-0.0.0/src/coworld/examples/paintarena/game/__init__.py +0 -0
- coworld-0.0.0/src/coworld/examples/paintarena/game/client/admin.html +60 -0
- coworld-0.0.0/src/coworld/examples/paintarena/game/client/global.html +250 -0
- coworld-0.0.0/src/coworld/examples/paintarena/game/client/player.html +271 -0
- coworld-0.0.0/src/coworld/examples/paintarena/game/client/replay.html +325 -0
- coworld-0.0.0/src/coworld/examples/paintarena/game/docs/global_protocol_spec.md +41 -0
- coworld-0.0.0/src/coworld/examples/paintarena/game/docs/player_protocol_spec.md +39 -0
- coworld-0.0.0/src/coworld/examples/paintarena/game/server.py +362 -0
- coworld-0.0.0/src/coworld/examples/paintarena/optimizer/README.md +17 -0
- coworld-0.0.0/src/coworld/examples/paintarena/optimizer/__init__.py +1 -0
- coworld-0.0.0/src/coworld/examples/paintarena/optimizer/paint_arena_optimizer.py +138 -0
- coworld-0.0.0/src/coworld/examples/paintarena/player/__init__.py +0 -0
- coworld-0.0.0/src/coworld/examples/paintarena/player/player.py +51 -0
- coworld-0.0.0/src/coworld/examples/paintarena/reporter/__init__.py +0 -0
- coworld-0.0.0/src/coworld/examples/paintarena/reporter/_sdk_vendored/__init__.py +76 -0
- coworld-0.0.0/src/coworld/examples/paintarena/reporter/_sdk_vendored/bundle.py +107 -0
- coworld-0.0.0/src/coworld/examples/paintarena/reporter/_sdk_vendored/event_log.py +75 -0
- coworld-0.0.0/src/coworld/examples/paintarena/reporter/_sdk_vendored/io.py +123 -0
- coworld-0.0.0/src/coworld/examples/paintarena/reporter/_sdk_vendored/output_manifest.py +100 -0
- coworld-0.0.0/src/coworld/examples/paintarena/reporter/_sdk_vendored/zip_writer.py +55 -0
- coworld-0.0.0/src/coworld/examples/paintarena/reporter/paint_arena_summarizer.py +298 -0
- coworld-0.0.0/src/coworld/examples/paintarena/reporter/stats_reporter.py +142 -0
- coworld-0.0.0/src/coworld/examples/paintarena/shared/__init__.py +0 -0
- coworld-0.0.0/src/coworld/examples/paintarena/shared/log_shipper.py +54 -0
- coworld-0.0.0/src/coworld/manifest_uri.py +142 -0
- coworld-0.0.0/src/coworld/manifest_validation.py +60 -0
- coworld-0.0.0/src/coworld/play.py +391 -0
- coworld-0.0.0/src/coworld/policies/__init__.py +1 -0
- coworld-0.0.0/src/coworld/policies/amongthemstarter/.dockerignore +6 -0
- coworld-0.0.0/src/coworld/policies/amongthemstarter/Dockerfile.amongthemstarter +57 -0
- coworld-0.0.0/src/coworld/policies/amongthemstarter/README.md +19 -0
- coworld-0.0.0/src/coworld/policies/amongthemstarter/amongthemstarter.nim +4581 -0
- coworld-0.0.0/src/coworld/policies/cogs_vs_clips/.dockerignore +5 -0
- coworld-0.0.0/src/coworld/policies/cogs_vs_clips/Dockerfile.cogs_vs_clips +7 -0
- coworld-0.0.0/src/coworld/policies/cogs_vs_clips/README.md +19 -0
- coworld-0.0.0/src/coworld/policies/cogs_vs_clips/player.py +55 -0
- coworld-0.0.0/src/coworld/py.typed +1 -0
- coworld-0.0.0/src/coworld/runner/KUBERNETES_RUNNER_README.md +228 -0
- coworld-0.0.0/src/coworld/runner/RUNNER_README.md +33 -0
- coworld-0.0.0/src/coworld/runner/__init__.py +1 -0
- coworld-0.0.0/src/coworld/runner/episode_request_schema.json +636 -0
- coworld-0.0.0/src/coworld/runner/io.py +78 -0
- coworld-0.0.0/src/coworld/runner/kubernetes_runner.py +538 -0
- coworld-0.0.0/src/coworld/runner/runner.py +513 -0
- coworld-0.0.0/src/coworld/schema_validation.py +22 -0
- coworld-0.0.0/src/coworld/starter_policy.py +68 -0
- coworld-0.0.0/src/coworld/submit.py +54 -0
- coworld-0.0.0/src/coworld/tournament_cli.py +988 -0
- coworld-0.0.0/src/coworld/types.py +387 -0
- coworld-0.0.0/src/coworld/upload.py +801 -0
- coworld-0.0.0/src/coworld.egg-info/PKG-INFO +130 -0
- coworld-0.0.0/src/coworld.egg-info/SOURCES.txt +126 -0
- coworld-0.0.0/src/coworld.egg-info/dependency_links.txt +1 -0
- coworld-0.0.0/src/coworld.egg-info/entry_points.txt +2 -0
- coworld-0.0.0/src/coworld.egg-info/requires.txt +29 -0
- coworld-0.0.0/src/coworld.egg-info/top_level.txt +1 -0
- coworld-0.0.0/tests/BUILD.bazel +43 -0
- coworld-0.0.0/tests/test_canonical_worlds.py +401 -0
- coworld-0.0.0/tests/test_commissioner_protocol.py +155 -0
- coworld-0.0.0/tests/test_coworld_bundle.py +431 -0
- coworld-0.0.0/tests/test_coworld_certifier.py +1557 -0
- coworld-0.0.0/tests/test_coworld_cli_manifest_uri.py +574 -0
- coworld-0.0.0/tests/test_coworld_kubernetes_runner.py +786 -0
- coworld-0.0.0/tests/test_coworld_make_policy.py +88 -0
- coworld-0.0.0/tests/test_coworld_manifest_uri.py +117 -0
- coworld-0.0.0/tests/test_coworld_runner_io.py +72 -0
- coworld-0.0.0/tests/test_coworld_submit_cli.py +116 -0
- coworld-0.0.0/tests/test_coworld_tournament_cli.py +499 -0
- coworld-0.0.0/tests/test_coworld_upload_cli.py +1183 -0
- coworld-0.0.0/tests/test_paintarena_optimizer.py +51 -0
- coworld-0.0.0/tests/test_paintarena_replay_loader.py +27 -0
- coworld-0.0.0/tests/test_paintarena_reporter.py +429 -0
- coworld-0.0.0/tests/test_paintarena_reporter_http_io.py +126 -0
- coworld-0.0.0/tests/test_paintarena_stats_reporter.py +180 -0
- 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
|
coworld-0.0.0/AGENTS.md
ADDED
|
@@ -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
|
+
)
|
coworld-0.0.0/CLAUDE.md
ADDED
|
@@ -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.
|