primebeaker 0.4.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 (129) hide show
  1. primebeaker-0.4.0/MANIFEST.in +1 -0
  2. primebeaker-0.4.0/PKG-INFO +457 -0
  3. primebeaker-0.4.0/README.md +427 -0
  4. primebeaker-0.4.0/examples/README.md +135 -0
  5. primebeaker-0.4.0/examples/configs/eval/README.md +49 -0
  6. primebeaker-0.4.0/examples/podman-terminal/README.md +142 -0
  7. primebeaker-0.4.0/examples/podman-terminal/data/train.jsonl +512 -0
  8. primebeaker-0.4.0/examples/podman-terminal/data/validation.jsonl +32 -0
  9. primebeaker-0.4.0/examples/podman-terminal/multinode-rl.toml +173 -0
  10. primebeaker-0.4.0/examples/podman-terminal/rl.toml +161 -0
  11. primebeaker-0.4.0/examples/rl/config.toml +94 -0
  12. primebeaker-0.4.0/examples/rl/data/train.jsonl +4 -0
  13. primebeaker-0.4.0/examples/rl/data/validation.jsonl +2 -0
  14. primebeaker-0.4.0/examples/search-agent-webterminal/README.md +191 -0
  15. primebeaker-0.4.0/examples/search-agent-webterminal/multinode-rl.toml +204 -0
  16. primebeaker-0.4.0/examples/sft/config.toml +78 -0
  17. primebeaker-0.4.0/examples/sft/data/train.jsonl +4 -0
  18. primebeaker-0.4.0/examples/sft/data/validation.jsonl +2 -0
  19. primebeaker-0.4.0/pyproject.toml +56 -0
  20. primebeaker-0.4.0/setup.cfg +4 -0
  21. primebeaker-0.4.0/src/primebeaker/__init__.py +35 -0
  22. primebeaker-0.4.0/src/primebeaker/__main__.py +5 -0
  23. primebeaker-0.4.0/src/primebeaker/beaker_resources.py +116 -0
  24. primebeaker-0.4.0/src/primebeaker/cli.py +280 -0
  25. primebeaker-0.4.0/src/primebeaker/common.py +40 -0
  26. primebeaker-0.4.0/src/primebeaker/config.py +344 -0
  27. primebeaker-0.4.0/src/primebeaker/coordination.py +280 -0
  28. primebeaker-0.4.0/src/primebeaker/environments/__init__.py +9 -0
  29. primebeaker-0.4.0/src/primebeaker/environments/__main__.py +30 -0
  30. primebeaker-0.4.0/src/primebeaker/environments/articulated_harness_env.py +136 -0
  31. primebeaker-0.4.0/src/primebeaker/environments/jtc_code_tool_env.py +59 -0
  32. primebeaker-0.4.0/src/primebeaker/environments/jtc_code_tool_label_env.py +209 -0
  33. primebeaker-0.4.0/src/primebeaker/environments/jtc_label_env.py +41 -0
  34. primebeaker-0.4.0/src/primebeaker/environments/jtc_label_reward.py +134 -0
  35. primebeaker-0.4.0/src/primebeaker/environments/jtc_multiple_choice_accuracy_env.py +35 -0
  36. primebeaker-0.4.0/src/primebeaker/environments/jtc_reward_model_env.py +532 -0
  37. primebeaker-0.4.0/src/primebeaker/environments/jtc_rubrichub_judge_env.py +912 -0
  38. primebeaker-0.4.0/src/primebeaker/environments/jtc_search_agent_env.py +172 -0
  39. primebeaker-0.4.0/src/primebeaker/environments/jtc_search_agent_visit_env.py +8 -0
  40. primebeaker-0.4.0/src/primebeaker/environments/jtc_search_agent_visit_judge_env.py +9 -0
  41. primebeaker-0.4.0/src/primebeaker/environments/jtc_search_agent_webterminal_env.py +9 -0
  42. primebeaker-0.4.0/src/primebeaker/environments/jtc_search_agent_webterminal_judge_env.py +196 -0
  43. primebeaker-0.4.0/src/primebeaker/environments/jtc_search_visit_agent_env.py +49 -0
  44. primebeaker-0.4.0/src/primebeaker/environments/jtc_search_visit_agent_judge_env.py +279 -0
  45. primebeaker-0.4.0/src/primebeaker/environments/jtc_terminal_tool_env.py +130 -0
  46. primebeaker-0.4.0/src/primebeaker/environments/jtc_terminal_tool_label_env.py +428 -0
  47. primebeaker-0.4.0/src/primebeaker/environments/jtc_tool_label_env.py +1044 -0
  48. primebeaker-0.4.0/src/primebeaker/environments/podman_terminal_env.py +717 -0
  49. primebeaker-0.4.0/src/primebeaker/environments/podman_terminal_verifier_env.py +4 -0
  50. primebeaker-0.4.0/src/primebeaker/environments/registry.py +62 -0
  51. primebeaker-0.4.0/src/primebeaker/environments/search_agent_env.py +332 -0
  52. primebeaker-0.4.0/src/primebeaker/environments/search_visit_agent_env.py +110 -0
  53. primebeaker-0.4.0/src/primebeaker/environments/tool_protocol.py +161 -0
  54. primebeaker-0.4.0/src/primebeaker/evaluation.py +318 -0
  55. primebeaker-0.4.0/src/primebeaker/evaluation_assets.py +93 -0
  56. primebeaker-0.4.0/src/primebeaker/evaluation_worker.py +171 -0
  57. primebeaker-0.4.0/src/primebeaker/gateway.py +153 -0
  58. primebeaker-0.4.0/src/primebeaker/images/README.md +29 -0
  59. primebeaker-0.4.0/src/primebeaker/images/__init__.py +10 -0
  60. primebeaker-0.4.0/src/primebeaker/images/__main__.py +62 -0
  61. primebeaker-0.4.0/src/primebeaker/images/catalog.json +58 -0
  62. primebeaker-0.4.0/src/primebeaker/images/catalog.py +55 -0
  63. primebeaker-0.4.0/src/primebeaker/jtc_evaluation.py +877 -0
  64. primebeaker-0.4.0/src/primebeaker/judge_catalog.py +138 -0
  65. primebeaker-0.4.0/src/primebeaker/multinode.py +588 -0
  66. primebeaker-0.4.0/src/primebeaker/multinode_cli.py +46 -0
  67. primebeaker-0.4.0/src/primebeaker/multinode_rl_role.sh +317 -0
  68. primebeaker-0.4.0/src/primebeaker/multinode_sft_role.sh +111 -0
  69. primebeaker-0.4.0/src/primebeaker/resources/__init__.py +1 -0
  70. primebeaker-0.4.0/src/primebeaker/resources/judge_profiles/__init__.py +0 -0
  71. primebeaker-0.4.0/src/primebeaker/resources/judge_profiles/example.json +15 -0
  72. primebeaker-0.4.0/src/primebeaker/resources/judge_profiles/lion_qwen35_4b_step800.json +17 -0
  73. primebeaker-0.4.0/src/primebeaker/resources/judge_profiles/quokka_sft_qwen35_9b_rltracer_xmlv1_search25_ba8d07_step400.json +18 -0
  74. primebeaker-0.4.0/src/primebeaker/resources/judge_profiles/qwen35_4b_base_grouped_rubrics.json +15 -0
  75. primebeaker-0.4.0/src/primebeaker/resources/judge_profiles/qwen35_4b_glm52_step400.json +12 -0
  76. primebeaker-0.4.0/src/primebeaker/resources/judge_profiles/qwen36_35b_a3b_grouped_rubrics.json +15 -0
  77. primebeaker-0.4.0/src/primebeaker/resources/judge_templates/__init__.py +0 -0
  78. primebeaker-0.4.0/src/primebeaker/resources/judge_templates/jtc-io-repl-prompt-gptoss-harmony.json +19 -0
  79. primebeaker-0.4.0/src/primebeaker/resources/judge_templates/jtc-io-terminal-prompt-gptoss-harmony.json +19 -0
  80. primebeaker-0.4.0/src/primebeaker/resources/judge_templates/jtc-io-terminal-release-browse-xml-v1.json +36 -0
  81. primebeaker-0.4.0/src/primebeaker/resources/judge_templates/recordset-batch-rubric-judge.json +19 -0
  82. primebeaker-0.4.0/src/primebeaker/resources/templates/__init__.py +1 -0
  83. primebeaker-0.4.0/src/primebeaker/resources/templates/articulated_harness_gptoss.json +18 -0
  84. primebeaker-0.4.0/src/primebeaker/resources/templates/code-check-generation.json +15 -0
  85. primebeaker-0.4.0/src/primebeaker/resources/templates/code-check-label-generation-gptoss.json +35 -0
  86. primebeaker-0.4.0/src/primebeaker/resources/templates/jtc-io-complete.json +37 -0
  87. primebeaker-0.4.0/src/primebeaker/resources/templates/jtc-io-prompt.json +20 -0
  88. primebeaker-0.4.0/src/primebeaker/resources/templates/jtc-io-python-prompt-gptoss-harmony.json +20 -0
  89. primebeaker-0.4.0/src/primebeaker/resources/templates/jtc-io-repl-prompt-gptoss-harmony.json +19 -0
  90. primebeaker-0.4.0/src/primebeaker/resources/templates/jtc-io-repl-prompt-v4.json +19 -0
  91. primebeaker-0.4.0/src/primebeaker/resources/templates/jtc-io-terminal-release-browse.json +36 -0
  92. primebeaker-0.4.0/src/primebeaker/resources/templates/jtc-io-tool_response.json +31 -0
  93. primebeaker-0.4.0/src/primebeaker/resources/templates/multistep-final-warning-harmony.json +14 -0
  94. primebeaker-0.4.0/src/primebeaker/resources/templates/multistep-final-warning.json +13 -0
  95. primebeaker-0.4.0/src/primebeaker/resources/templates/multistep-tool-message.json +13 -0
  96. primebeaker-0.4.0/src/primebeaker/resources/templates/podman-terminal-submit-gptoss.json +40 -0
  97. primebeaker-0.4.0/src/primebeaker/resources/templates/search-agent-visit-judge.json +15 -0
  98. primebeaker-0.4.0/src/primebeaker/resources/templates/search-agent-visit.json +15 -0
  99. primebeaker-0.4.0/src/primebeaker/resources/templates/search-agent-webterminal-10k.json +17 -0
  100. primebeaker-0.4.0/src/primebeaker/resources/templates/search-agent.json +17 -0
  101. primebeaker-0.4.0/src/primebeaker/resources/templates/tmax-podman-trace-submit-binary-gptoss.v2.json +13 -0
  102. primebeaker-0.4.0/src/primebeaker/resources/templates/tmax-podman-trace-submit-gptoss.json +41 -0
  103. primebeaker-0.4.0/src/primebeaker/resume.py +717 -0
  104. primebeaker-0.4.0/src/primebeaker/rexs_run.py +180 -0
  105. primebeaker-0.4.0/src/primebeaker/rl.py +308 -0
  106. primebeaker-0.4.0/src/primebeaker/run.py +270 -0
  107. primebeaker-0.4.0/src/primebeaker/runtime/__init__.py +1 -0
  108. primebeaker-0.4.0/src/primebeaker/runtime/asset_store.py +7 -0
  109. primebeaker-0.4.0/src/primebeaker/runtime/code_utils.py +255 -0
  110. primebeaker-0.4.0/src/primebeaker/runtime/json_utils.py +77 -0
  111. primebeaker-0.4.0/src/primebeaker/runtime/templates.py +42 -0
  112. primebeaker-0.4.0/src/primebeaker/service_images.py +296 -0
  113. primebeaker-0.4.0/src/primebeaker/services.py +181 -0
  114. primebeaker-0.4.0/src/primebeaker/sft.py +326 -0
  115. primebeaker-0.4.0/src/primebeaker/wandb.py +28 -0
  116. primebeaker-0.4.0/src/primebeaker/watcher/README.md +132 -0
  117. primebeaker-0.4.0/src/primebeaker/watcher/__init__.py +5 -0
  118. primebeaker-0.4.0/src/primebeaker/watcher/__main__.py +7 -0
  119. primebeaker-0.4.0/src/primebeaker/watcher/app.py +458 -0
  120. primebeaker-0.4.0/src/primebeaker/watcher/cli.py +381 -0
  121. primebeaker-0.4.0/src/primebeaker/watcher/index.py +1428 -0
  122. primebeaker-0.4.0/src/primebeaker/watcher/metrics.py +240 -0
  123. primebeaker-0.4.0/src/primebeaker.egg-info/PKG-INFO +457 -0
  124. primebeaker-0.4.0/src/primebeaker.egg-info/SOURCES.txt +127 -0
  125. primebeaker-0.4.0/src/primebeaker.egg-info/dependency_links.txt +1 -0
  126. primebeaker-0.4.0/src/primebeaker.egg-info/entry_points.txt +3 -0
  127. primebeaker-0.4.0/src/primebeaker.egg-info/requires.txt +28 -0
  128. primebeaker-0.4.0/src/primebeaker.egg-info/top_level.txt +1 -0
  129. primebeaker-0.4.0/tests/test_examples.py +228 -0
@@ -0,0 +1 @@
1
+ recursive-include examples *.md *.toml *.jsonl
@@ -0,0 +1,457 @@
1
+ Metadata-Version: 2.4
2
+ Name: primebeaker
3
+ Version: 0.4.0
4
+ Summary: Self-contained Prime-RL environments, TOML tooling, and Beaker launchers.
5
+ Requires-Python: ~=3.12.0
6
+ Description-Content-Type: text/markdown
7
+ Requires-Dist: fire>=0.7.1
8
+ Requires-Dist: pydantic>=2.7
9
+ Requires-Dist: literegistry-tool-client<0.2,>=0.1.0
10
+ Provides-Extra: evaluation
11
+ Requires-Dist: jtc[evals,harness]==0.3.0; extra == "evaluation"
12
+ Provides-Extra: watcher
13
+ Requires-Dist: fastapi; extra == "watcher"
14
+ Requires-Dist: jtc==0.3.0; extra == "watcher"
15
+ Requires-Dist: PyYAML>=6.0; extra == "watcher"
16
+ Requires-Dist: uvicorn; extra == "watcher"
17
+ Requires-Dist: wandb; extra == "watcher"
18
+ Provides-Extra: runtime
19
+ Requires-Dist: aiohttp; extra == "runtime"
20
+ Requires-Dist: datasets; extra == "runtime"
21
+ Requires-Dist: httpx; extra == "runtime"
22
+ Requires-Dist: literegistry[base_deployment,podman_beaker]==1.0.48; extra == "runtime"
23
+ Requires-Dist: PyYAML>=6.0; extra == "runtime"
24
+ Requires-Dist: uvicorn; extra == "runtime"
25
+ Requires-Dist: verifiers[harbor]==0.2.1; extra == "runtime"
26
+ Provides-Extra: test
27
+ Requires-Dist: pytest>=8; extra == "test"
28
+ Provides-Extra: full
29
+ Requires-Dist: primebeaker[evaluation,runtime,watcher]; extra == "full"
30
+
31
+ # PrimeBeaker
32
+
33
+ PrimeBeaker is a standalone package for running Prime-RL SFT and RL on Beaker.
34
+ It includes:
35
+
36
+ - lossless SFT/RL TOML loading and editing;
37
+ - single-node and multi-node Beaker preview/submission;
38
+ - heterogeneous RL placement (mixed trainer/inference node plus dedicated inference nodes);
39
+ - distributed multi-node SFT through torchrun/FSDP;
40
+ - all 16 runnable Verifiers environments, using LiteRegistry tool clients;
41
+ - package-local prompt templates, tool-call wire parsing, and tool schemas;
42
+ - an immutable Prime-RL image catalog and reproducible Dockerfiles.
43
+ - safe whole-topology checkpoint discovery and resume;
44
+ - a thin CLI adapter over LiteRegistry's native Beaker service deployment.
45
+ - managed Python evaluation scheduling, readiness, signal forwarding, and cleanup.
46
+ - managed iterative rejection-sampling scheduling and resume, with JTC owning
47
+ only the judge/filter/compile loop.
48
+ - typed standard, search-agent, and rubric-audit YAML lifecycle descriptions,
49
+ plus registry-backed scheduling for every packaged JTC workflow—including
50
+ all verifier, TMAX/Podman, inference, and rubric-generation variants.
51
+
52
+ ## Install
53
+
54
+ Tool clients are provided exclusively by the standalone
55
+ `literegistry-tool-client` package. Import them directly from
56
+ `literegistry_tool_client`; PrimeBeaker does not re-export that API.
57
+ Normal installation resolves the dependency from PyPI.
58
+
59
+ For TOML and launch tooling:
60
+
61
+ ```bash
62
+ pip install -e .
63
+ ```
64
+
65
+ For environments, the LiteRegistry gateway, and multi-node RL:
66
+
67
+ ```bash
68
+ pip install -e '.[runtime]'
69
+ ```
70
+
71
+ For JTC evaluation scheduling as well:
72
+
73
+ ```bash
74
+ pip install -e '.[runtime,evaluation]'
75
+ primebeaker evaluation preview --config examples/configs/eval/python_only_smoke.yaml
76
+ primebeaker evaluation submit --config examples/configs/eval/python_only_smoke.yaml
77
+ ```
78
+
79
+ For the training/evaluation provenance watcher:
80
+
81
+ ```bash
82
+ pip install -e '.[watcher]'
83
+ primebeaker watcher status --database=watcher.sqlite3
84
+ primebeaker watcher serve --database=watcher.sqlite3 --port=8790
85
+ ```
86
+
87
+ The watcher implementation and lifecycle live in PrimeBeaker. It reads JTC
88
+ training configs and evaluation outcomes but JTC never imports or launches it.
89
+
90
+ PrimeBeaker owns these YAMLs and the complete service/Beaker lifecycle. JTC is
91
+ the one-way application dependency: it supplies the workload contracts and
92
+ Python workers in the evaluation image. Evaluation image construction lives in
93
+ JTC at `docker/Dockerfile.eval` and installs released PyPI wheels only.
94
+
95
+ The runtime extra installs LiteRegistry's Python launchers, but service stacks
96
+ also require their separate container images in Beaker. Complete the runtime
97
+ installation by building the official Dockerfiles from the exact installed
98
+ LiteRegistry companion versions and importing the images into your workspace:
99
+
100
+ ```bash
101
+ beaker account whoami
102
+ docker version
103
+ primebeaker services images install --workspace=ai2/oe-agents
104
+ ```
105
+
106
+ The command downloads the matching source distributions, builds both the base
107
+ services and Podman/mirror stacks, uploads every image, and prints the immutable
108
+ Beaker IDs as `launcher_args`. Use those values for `services launch` or
109
+ `services podman launch`. To install only the images required by the Podman
110
+ terminal verifier, pass `--stack=podman`. A local LiteRegistry checkout can be
111
+ used without downloading sources via `--source-root=/path/to/literegistry`.
112
+ If the base deployment will run local search, also pass
113
+ `--build-local-search --jtc-build-context=/path/to/jtc`; that image needs JTC's
114
+ Lucene build assets and is therefore not part of the default build.
115
+
116
+ This is an explicit post-install step because Python package installation must
117
+ not silently mutate Docker or a remote Beaker workspace. It requires a running
118
+ Docker daemon, an authenticated `beaker` CLI, network access to the configured
119
+ Python and container indexes, and write access to the selected workspace.
120
+
121
+ PrimeBeaker targets Python 3.12, matching the cataloged Prime-RL runtime. The
122
+ `runtime` extra pins `verifiers[harbor]==0.2.1`, whose released PyPI wheel
123
+ contains the client and environment APIs used by PrimeBeaker. No Git checkout is
124
+ required for the runtime extra.
125
+
126
+ The authenticated `beaker` executable, Docker, and a Prime-RL GPU image are
127
+ external requirements. See [`src/primebeaker/images/README.md`](src/primebeaker/images/README.md) for immutable
128
+ training-image locations and exact rebuild/publish instructions.
129
+
130
+ ## Tiny runnable examples
131
+
132
+ [`examples/`](examples/README.md) contains two-step SFT and RL setups. Each
133
+ uses four complete training records and two complete validation records, preserving
134
+ the existing data format without bundling a corpus. Both are ready for the
135
+ Fire-based `preview` and `submit` commands documented there.
136
+
137
+ ## Environments
138
+
139
+ ```bash
140
+ python -m primebeaker.environments
141
+ python -m primebeaker.environments tool-label
142
+ ```
143
+
144
+ TOMLs use normal module paths such as:
145
+
146
+ ```text
147
+ primebeaker.environments.jtc_tool_label_env:load_environment
148
+ primebeaker.environments.jtc_reward_model_env:load_environment
149
+ primebeaker.environments.jtc_search_agent_env:load_environment
150
+ primebeaker.environments.podman_terminal_env:load_environment
151
+ ```
152
+
153
+ The Podman terminal solver expects each dataset row to contain a prompt and an
154
+ initial image under `original_image`, `image`, or `container_image`. It starts a
155
+ fresh container directly from that image; saved trace fields are neither required
156
+ nor read. The model solves the task in that live container using exactly two
157
+ model-facing tools, `bash` and `submit`, and must finish with:
158
+
159
+ ```text
160
+ echo TERMINAL_COMPLETE
161
+ ```
162
+
163
+ Only after that marker succeeds, the environment uses the same Podman client to
164
+ clear any stale or model-written reward file, execute the configured unit-test
165
+ command against the model's final filesystem, capture its structured
166
+ stdout/stderr/exit status, and read `/logs/verifier/reward.txt`. Its numeric
167
+ value is clamped to `[0, 1]`; a missing or invalid file contributes exactly zero.
168
+ Four independent rubric weights are configured directly in the Prime-RL TOML:
169
+
170
+ ```toml
171
+ [orchestrator.train.source.legacy.args]
172
+ reward_file_path = "/logs/verifier/reward.txt"
173
+ test_command = "bash /tests/test.sh"
174
+ test_timeout = 600
175
+ reward_file_weight = 1.0
176
+ termination_reward_weight = 0.1
177
+ podman_failure_penalty_weight = 1.0
178
+ fake_tool_penalty_weight = 0.1
179
+ ```
180
+
181
+ The raw rubric values are respectively the captured unit-test score, `1` for a
182
+ successful standalone completion command, `-1` for a Podman setup or execution
183
+ failure, and `-1` per attempted tool name that the environment does not provide. A rollout that merely fails to terminate gets no
184
+ termination credit rather than a separate missing-marker penalty. Failure phase, type,
185
+ message, and an OOM indicator are retained in rollout state for diagnosis.
186
+
187
+ The launcher rewrites copied legacy environment paths to the `primebeaker`
188
+ namespace in a temporary runtime TOML; it never edits the source TOML.
189
+
190
+ ## Single-node launch
191
+
192
+ ```bash
193
+ primebeaker sft preview --toml /weka/path/sft.toml
194
+
195
+ primebeaker rl preview --toml /weka/path/rl.toml \
196
+ --env TERMINAL_SERVER_URL=http://service/terminal
197
+
198
+ primebeaker rl submit --toml /weka/path/rl.toml \
199
+ --image beaker://IMMUTABLE_PRIMEBEAKER_IMAGE \
200
+ --workspace ai2/oe-agents \
201
+ --cluster ai2/holmes
202
+ ```
203
+
204
+ ## Multi-node RL
205
+
206
+ The same command automatically selects the multi-node backend when the TOML
207
+ contains `deployment.type = "multi_node"`:
208
+
209
+ ```bash
210
+ primebeaker rl preview \
211
+ --toml /weka/path/multinode-rl.toml \
212
+ --image beaker://IMMUTABLE_PRIMEBEAKER_IMAGE \
213
+ --registry redis://registry-host:6379 \
214
+ --required-service terminal=8 \
215
+ --required-service localsearch:corpus=8
216
+ ```
217
+
218
+ The generated Beaker task uses replicas, leader selection, synchronized start,
219
+ host networking, and failure/preemption propagation. Replica 0 runs the
220
+ trainer, orchestrator, global vLLM router, and local tool gateway. It may also
221
+ run an inference GPU slice. Later replicas run the dedicated inference slices.
222
+ All replicas share rendezvous state through the mounted Weka dataset and use
223
+ one W&B run ID.
224
+
225
+ The retained heterogeneous layout matches the extracted production launcher:
226
+ exactly one trainer node and one Prime-RL inference replica, with any number of
227
+ configured inference nodes. The TOML's `inference.parallel.tp`, `.dp`, and
228
+ `api_server_count` must describe every exposed inference rank.
229
+
230
+ Tool workers and Redis remain external services. `--required-service NAME=N`
231
+ adds an exact startup barrier without bundling service deployment into the
232
+ training package.
233
+
234
+ ## Joint service + RL runs
235
+
236
+ The standalone `services`, `rl`, and `sft` commands remain available. For
237
+ an RL run that owns its service stack, put both launch descriptions in one
238
+ `primebeaker.run/v1` YAML and submit them together:
239
+
240
+ ```bash
241
+ primebeaker run preview --config /weka/path/run.yaml
242
+ primebeaker run launch --config /weka/path/run.yaml
243
+ ```
244
+
245
+ The top-level `service` object is passed to LiteRegistry's native
246
+ `BaseDeploymentConfig`. The `rl` object accepts the same launch settings as
247
+ the standalone RL command: `toml`, `image`, `workspace`, `clusters`,
248
+ `priority`, `min_runtime_hours`, `mount_path`, `dataset`,
249
+ `working_dir`, `scratch_dir`, `home_dir`, `wandb_secret`, `hf_secret`,
250
+ `wandb_run_id`, `wandb_entity`, `environment`, `secrets`,
251
+ `setup_command`, `budget`, `description`,
252
+ `rendezvous_timeout_seconds`, `registry`, `gateway_port`,
253
+ `gateway_workers`, and `required_services`. YAML uses objects for
254
+ `environment`, `secrets`, and `required_services`, and a list for
255
+ `clusters`. A relative `toml` path is resolved relative to the run YAML.
256
+
257
+ When `rl.registry` is omitted, it is derived from `service.registry` or
258
+ `service.head_registry`; for example, `sqlite:///weka/run.sqlite3` becomes
259
+ `head+sqlite:///weka/run.sqlite3`. This allows both experiments to be
260
+ submitted immediately. Training retains its existing registry/service startup
261
+ barriers.
262
+
263
+ By default, `lifecycle.cleanup_service_on_training_exit` is true. The joint
264
+ launcher injects the service experiment ID and a `BEAKER_TOKEN` secret into
265
+ trainer replica 0, which stops the owned service experiment during trainer
266
+ shutdown. Set `lifecycle.beaker_token_secret` when the Beaker workspace secret
267
+ has a different name. If RL submission fails, the local launcher rolls the
268
+ service experiment back immediately. See the
269
+ [WebTerminal search-agent example](examples/search-agent-webterminal/README.md)
270
+ for complete joint and independent launch forms.
271
+
272
+ The independent SFT and RL commands share these placement/runtime flags:
273
+ `image`, `workspace`, `cluster`, `priority`, `min_runtime_hours`,
274
+ `mount_path`, `dataset`, `working_dir`, `scratch_dir`, `home_dir`,
275
+ `wandb_secret`, `hf_secret`, `wandb_run_id`, `env`, `secret`,
276
+ `setup_command`, `budget`, and `description`. Multi-node launches also
277
+ accept `rendezvous_timeout_seconds`; RL additionally accepts `registry`,
278
+ `wandb_entity`, `gateway_port`, `gateway_workers`, and
279
+ `required_service`.
280
+
281
+ ## LiteRegistry services
282
+
283
+ PrimeBeaker does not maintain a second service-stack implementation. The
284
+ `services` command delegates directly to LiteRegistry's
285
+ `literegistry-base-deployment` package, which owns gateway, Redis, Python,
286
+ terminal, web search/fetch, cache, local-search, and vLLM deployment:
287
+
288
+ ```bash
289
+ primebeaker services preview \
290
+ --head-registry=/weka/gfaria/registries/example \
291
+ --service-cluster=ai2/jupiter \
292
+ --python-replicas=2 \
293
+ --terminal-replicas=2 \
294
+ --web-search-replicas=2
295
+
296
+ primebeaker services launch \
297
+ --head-registry=/weka/gfaria/registries/example \
298
+ --service-cluster=ai2/jupiter
299
+
300
+ REGISTRY=redis://YOUR_REDIS_HOST:6379 primebeaker services podman preview \
301
+ --registry=redis://YOUR_REDIS_HOST:6379 \
302
+ --service-cluster=ai2/jupiter \
303
+ --podman-replicas=4 \
304
+ --docker-mirror-replicas=2
305
+
306
+ REGISTRY=redis://YOUR_REDIS_HOST:6379 primebeaker services podman yaml preview \
307
+ --config=examples/podman-terminal/services.yaml
308
+ ```
309
+
310
+ All service flags are passed into LiteRegistry's native
311
+ `BaseDeploymentConfig`; PrimeBeaker adds no stack rendering or coordination
312
+ logic. The `podman` subgroup similarly delegates to the native
313
+ `literegistry-podman-beaker` package. Its YAML form is `services podman yaml`:
314
+ it uses the same strict `primebeaker.services/v1` schema as `services yaml` but
315
+ passes the `services` object to the Podman launcher. The same operations remain
316
+ available through those two upstream executables.
317
+
318
+ Both native launchers use `literegistry.coop.ports` for collision-safe
319
+ dynamic ports and child supervision, plus `literegistry.coop.endpoints` for
320
+ healthy endpoint publication and shutdown cleanup. The base launcher can publish through a `head+file://`, `head+sqlite://`, or
321
+ `head+redis://` registry URI. The native Podman launcher instead requires a
322
+ direct, persistent `redis://` or `rediss://` endpoint shared with training.
323
+ Pass the applicable URI to `primebeaker rl preview|submit|resume --registry=...`.
324
+
325
+ ## Managed Python evaluations
326
+
327
+ PrimeBeaker owns the infrastructure half of an evaluation lifecycle: it starts
328
+ LiteRegistry's native service deployment, waits for its published Redis and
329
+ gateway endpoints, checks the required service roster, runs one Python module
330
+ inside a separate Beaker evaluation task, forwards termination signals, and
331
+ stops the owned service experiment in a `finally`/process-exit cleanup path.
332
+
333
+ The evaluation task command is always:
334
+
335
+ ```text
336
+ python3 -m primebeaker.evaluation_worker
337
+ ```
338
+
339
+ The application module and its arguments are validated data in a
340
+ `PythonEvaluationRequest`; arbitrary commands and shell launchers are not
341
+ accepted. JTC uses this API with its standard, search, audit, or generic
342
+ `jtc.eval.workflow_worker` entry point, so JTC retains benchmark/workflow logic
343
+ while PrimeBeaker owns scheduling and lifetime. The generic worker resolves a
344
+ stable name from JTC's packaged workflow registry; it does not execute an
345
+ arbitrary module or shell command. The image must contain released
346
+ `primebeaker` and `jtc`
347
+ wheels. The supported image build installs only exact versions from public
348
+ PyPI; see
349
+ [`src/primebeaker/images/README.md`](src/primebeaker/images/README.md).
350
+
351
+ The generic Fire CLI accepts either an inline JSON object or a JSON file:
352
+
353
+ ```bash
354
+ primebeaker evaluation preview --request-json=/weka/path/evaluation-request.json
355
+ primebeaker evaluation submit --request-json=/weka/path/evaluation-request.json
356
+ ```
357
+
358
+ Most users should use `primebeaker evaluation preview|submit --config=...` with
359
+ a PrimeBeaker-owned YAML. A top-level registered JTC workflow name selects the
360
+ generic worker, while `arguments` contains only that workflow's Python keyword
361
+ arguments and `services`/`required_services` describe the managed topology.
362
+
363
+ ## Resume a multi-node RL experiment
364
+
365
+ Resume always creates a fresh complete topology. It first requires one step
366
+ to have every trainer rank shard, trainer `.metadata`, and the orchestrator's
367
+ `progress.pt`. It refuses to submit while any source job is active, preserves
368
+ the W&B run ID, moves stale broadcast handshakes aside, and writes an attempt
369
+ manifest under `<output_dir>/primebeaker_resume/`.
370
+
371
+ With no `--resume-step`, the latest complete common checkpoint is selected:
372
+
373
+ ```bash
374
+ primebeaker rl resume \
375
+ --from-experiment=01SOURCE \
376
+ --dry-run
377
+
378
+ primebeaker rl resume \
379
+ --from-experiment=01SOURCE \
380
+ --resume-step=220 \
381
+ --registry=head+file:///weka/gfaria/registries/example
382
+ ```
383
+
384
+ The source Beaker experiment supplies the image, workspace, clusters, Weka
385
+ mount, output directory, gateway settings, and training TOML. Any corresponding
386
+ resume flag is an explicit override. A source without an external registry
387
+ must be given `--registry`; `primebeaker services launch` can create that stack.
388
+
389
+ ## Multi-node SFT
390
+
391
+ PrimeBeaker also translates Prime-RL's SLURM-oriented multi-node SFT topology
392
+ to Beaker:
393
+
394
+ ```toml
395
+ [deployment]
396
+ type = "multi_node"
397
+ num_nodes = 4
398
+ gpus_per_node = 8
399
+ ```
400
+
401
+ ```bash
402
+ primebeaker sft preview \
403
+ --toml /weka/path/multinode-sft.toml \
404
+ --image beaker://IMMUTABLE_PRIMEBEAKER_IMAGE
405
+ ```
406
+
407
+ Each Beaker replica starts one torchrun node. Replica 0 publishes the rendezvous
408
+ address and materializes the validated Prime-RL trainer config; all nodes join
409
+ the same distributed job.
410
+
411
+ ## Output and clients
412
+
413
+ Preview is non-mutating. `--write-spec` writes under
414
+ `<scratch-dir>/primebeaker/beaker_experiments/`; submit writes the same spec and
415
+ invokes `beaker experiment create`.
416
+
417
+ `literegistry_tool_client` is the canonical API for terminal, Python, Podman,
418
+ search, fetch, judge, reward-model, web-terminal, and submit clients. Service
419
+ URLs and credentials remain explicit rather than being tied to JTC
420
+ infrastructure.
421
+
422
+ ## Publishing to PyPI
423
+
424
+ The `Publish to PyPI` GitHub Actions workflow builds and validates a source
425
+ distribution and wheel with Python 3.12, then publishes them when a GitHub
426
+ release is published. Running the workflow manually only builds and validates
427
+ artifacts, so it can be used to check packaging before a release.
428
+
429
+ First release (the project does not exist on PyPI yet):
430
+
431
+ 1. Create the `pypi` environment in the repository's GitHub Settings →
432
+ Environments.
433
+ 2. Sign in to PyPI and open [account publishing](https://pypi.org/manage/account/publishing/).
434
+ Add a pending GitHub publisher with these exact values:
435
+
436
+ | Field | Value |
437
+ | --- | --- |
438
+ | PyPI project name | `primebeaker` |
439
+ | Owner | `goncalorafaria` |
440
+ | Repository | `primebeaker` |
441
+ | Workflow filename | `publish.yml` |
442
+ | Environment | `pypi` |
443
+
444
+ 3. Commit and push the workflow and package source, then publish a GitHub
445
+ release tagged `v0.4.0` at that commit (matching the current package version).
446
+
447
+ The first successful workflow upload creates the PyPI project automatically
448
+ and converts the pending publisher into a permanent Trusted Publisher. No
449
+ manual initial upload, PyPI API token, or GitHub secret is required. See
450
+ [PyPI's first-project instructions](https://docs.pypi.org/trusted-publishers/creating-a-project-through-oidc/).
451
+
452
+ For each release, update `[project].version` in `pyproject.toml`, commit and push
453
+ it together with the workflow, then publish a GitHub release tagged `v<version>`
454
+ (or `<version>`) at that commit. The workflow rejects a tag that does not match
455
+ the package version. Choose a version that has not already been uploaded to
456
+ PyPI; existing releases cannot be overwritten. Draft releases and tag pushes
457
+ alone do not publish a package.