Skip to content

Commit b5df258

Browse files
authored
Clarify agent skill handling (#886)
1 parent 315f66b commit b5df258

6 files changed

Lines changed: 458 additions & 10 deletions

File tree

docs/training.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ This will clone and install the `prime-rl` trainer and its dependencies, and set
9999

100100
Then, you can start training with:
101101
```bash
102-
uv run prime-rl @ configs/prime-rl/wiki-search.toml
102+
uv run prime-rl configs/prime-rl/wiki-search.toml
103103
```
104104

105105
This will launch a tmux session with separate panes for the trainer, orchestrator, and inference server. For further configuration options, see the [prime-rl documentation](https://docs.primeintellect.ai/prime-rl).

skills/create-environments/SKILL.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,13 @@ prime env push --path ./environments/my_env --visibility PRIVATE
9999
prime eval run owner/my-env -m gpt-4.1-mini -n 200 -r 3 -s
100100
```
101101

102+
## Synthetic Data
103+
1. Ask users for preferences on which LLMs to use for synthetic data generation and curation before implementation.
104+
2. Prefer generating synthetic data from raw source documents whenever possible instead of relying only on hand-authored prompts.
105+
3. Use LLM orchestration (planner/generator/validator loops) to improve sample quality and diversity.
106+
4. Use back-translation: start from complete materials and decompose them into incomplete tasks, criteria, or partial artifacts that the model must reconstruct.
107+
5. Use fan-out subtopic sampling from LLMs to expand coverage and avoid overfitting to a narrow slice of the domain.
108+
102109
## Deliverable Format
103110
Report:
104111
1. Environment ID and path.

skills/train-with-environments/SKILL.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,18 @@ description: Train models with verifiers environments using hosted RL or prime-r
99
Run stable RL training loops with environment-aware hyperparameter choices and clear diagnostics.
1010

1111
## Preferred Training Paths
12-
1. Hosted Training service path from lab setup:
12+
1. By default, assume users intend to use Hosted Training unless they explicitly ask for self-managed training.
13+
2. Hosted Training service path from lab setup:
1314
```bash
1415
prime lab setup
1516
```
16-
2. Self-managed `prime-rl` workflow:
17+
3. Self-managed `prime-rl` workflow:
1718
```bash
1819
prime lab setup --prime-rl
19-
uv run prime-rl @ configs/prime-rl/wiki-search.toml
20+
uv run prime-rl configs/prime-rl/wiki-search.toml
2021
```
21-
3. Runtime expectation:
22+
4. Treat `prime-rl` as a power-user path and assume users are comfortable working with GPU infrastructure and troubleshooting.
23+
5. Runtime expectation:
2224
- Hosted Training is intended to be launched from a CPU machine.
2325
- Local `prime-rl` training requires local GPU access.
2426

tests/test_setup_script.py

Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
from __future__ import annotations
22

3+
import json
4+
import os
35
from pathlib import Path
46

57
from verifiers.scripts import setup
@@ -101,3 +103,186 @@ def test_sync_prime_skills_creates_dot_prime_tree(tmp_path: Path, monkeypatch) -
101103
".prime/skills/brainstorm/SKILL.md",
102104
),
103105
]
106+
107+
108+
def test_prepare_agent_skill_dirs_materializes_skills_from_prime(
109+
tmp_path: Path, monkeypatch
110+
) -> None:
111+
monkeypatch.chdir(tmp_path)
112+
monkeypatch.setattr(setup, "LAB_SKILLS", ["create-environments", "brainstorm"])
113+
114+
for skill_name in setup.LAB_SKILLS:
115+
skill_dir = tmp_path / ".prime" / "skills" / skill_name
116+
skill_dir.mkdir(parents=True, exist_ok=True)
117+
(skill_dir / "SKILL.md").write_text(f"{skill_name}\n")
118+
119+
setup._prepare_agent_skill_dirs(["codex"])
120+
121+
for skill_name in setup.LAB_SKILLS:
122+
source = tmp_path / ".prime" / "skills" / skill_name
123+
target = tmp_path / ".codex" / "skills" / skill_name
124+
assert target.exists()
125+
assert (target / "SKILL.md").exists()
126+
if target.is_symlink():
127+
assert target.resolve() == source.resolve()
128+
129+
130+
def test_prepare_agent_skill_dirs_is_safe_with_existing_links(
131+
tmp_path: Path, monkeypatch
132+
) -> None:
133+
monkeypatch.chdir(tmp_path)
134+
monkeypatch.setattr(setup, "LAB_SKILLS", ["create-environments"])
135+
136+
source = tmp_path / ".prime" / "skills" / "create-environments"
137+
source.mkdir(parents=True, exist_ok=True)
138+
(source / "SKILL.md").write_text("create-environments\n")
139+
140+
target = tmp_path / ".codex" / "skills" / "create-environments"
141+
target.parent.mkdir(parents=True, exist_ok=True)
142+
target.symlink_to(
143+
os.path.relpath(source, start=target.parent),
144+
target_is_directory=True,
145+
)
146+
147+
setup._prepare_agent_skill_dirs(["codex"])
148+
149+
assert target.is_symlink()
150+
assert target.resolve() == source.resolve()
151+
assert (target / "SKILL.md").exists()
152+
153+
154+
def test_prepare_agent_skill_dirs_uses_mapped_root_for_amp(
155+
tmp_path: Path, monkeypatch
156+
) -> None:
157+
monkeypatch.chdir(tmp_path)
158+
monkeypatch.setattr(setup, "LAB_SKILLS", ["create-environments"])
159+
160+
source = tmp_path / ".prime" / "skills" / "create-environments"
161+
source.mkdir(parents=True, exist_ok=True)
162+
(source / "SKILL.md").write_text("create-environments\n")
163+
164+
setup._prepare_agent_skill_dirs(["amp"])
165+
166+
assert (
167+
tmp_path / ".agents" / "skills" / "create-environments" / "SKILL.md"
168+
).exists()
169+
assert not (tmp_path / ".amp" / "skills").exists()
170+
171+
172+
def test_prepare_agent_skill_dirs_supports_skill_name_mapping(
173+
tmp_path: Path, monkeypatch
174+
) -> None:
175+
monkeypatch.chdir(tmp_path)
176+
monkeypatch.setattr(setup, "LAB_SKILLS", ["create-environments"])
177+
monkeypatch.setattr(
178+
setup,
179+
"AGENT_SKILL_NAME_MAP",
180+
{"amp": {"create-environments": "create-envs"}},
181+
)
182+
183+
source = tmp_path / ".prime" / "skills" / "create-environments"
184+
source.mkdir(parents=True, exist_ok=True)
185+
(source / "SKILL.md").write_text("create-environments\n")
186+
187+
setup._prepare_agent_skill_dirs(["amp"])
188+
189+
assert (tmp_path / ".agents" / "skills" / "create-envs" / "SKILL.md").exists()
190+
assert not (tmp_path / ".agents" / "skills" / "create-environments").exists()
191+
192+
193+
def test_run_setup_prints_post_setup_call_to_action(
194+
tmp_path: Path, monkeypatch, capsys
195+
) -> None:
196+
monkeypatch.chdir(tmp_path)
197+
198+
monkeypatch.setattr(setup.wget, "download", _fake_download_factory([]))
199+
monkeypatch.setattr(setup, "download_configs", lambda *_: None)
200+
monkeypatch.setattr(setup, "sync_prime_skills", lambda: None)
201+
202+
setup.run_setup(skip_install=True, skip_agents_md=True)
203+
204+
output = capsys.readouterr().out
205+
assert "Prepared .codex/skills" in output
206+
assert output.index("Prepared .codex/skills") < output.index("get started")
207+
assert "get started" in output
208+
assert "quick commands" in output
209+
assert "ask codex" in output
210+
assert "example prompt" not in output
211+
assert 'ask codex: "I want to train a model for my task domain.' not in output
212+
assert "idea -> environment -> eval -> training" in output
213+
assert "prime env init my-env" in output
214+
assert "prime env install my-env" not in output
215+
assert "prime eval run my-env -m gpt-5-nano -n 5" in output
216+
assert "prime eval tui" in output
217+
assert "prime rl run configs/rl/wiki-search.toml" in output
218+
assert "prime gepa run my-env -m gpt-5-nano" in output
219+
220+
221+
def test_run_setup_prints_prime_rl_post_setup_call_to_action(
222+
tmp_path: Path, monkeypatch, capsys
223+
) -> None:
224+
monkeypatch.chdir(tmp_path)
225+
226+
monkeypatch.setattr(setup.wget, "download", _fake_download_factory([]))
227+
monkeypatch.setattr(setup, "download_configs", lambda *_: None)
228+
monkeypatch.setattr(setup, "sync_prime_skills", lambda: None)
229+
monkeypatch.setattr(setup, "install_prime_rl", lambda: None)
230+
monkeypatch.setattr(setup, "install_environments_to_prime_rl", lambda: None)
231+
232+
setup.run_setup(skip_install=True, skip_agents_md=True, prime_rl=True)
233+
234+
output = capsys.readouterr().out
235+
assert "get started" in output
236+
assert "quick commands" in output
237+
assert "ask codex" in output
238+
assert "example prompt" not in output
239+
assert "prime env install my-env" not in output
240+
assert "uv run prime-rl configs/prime-rl/wiki-search.toml" in output
241+
assert "prime rl run configs/rl/wiki-search.toml" not in output
242+
243+
244+
def test_run_setup_persists_lab_choices_metadata(tmp_path: Path, monkeypatch) -> None:
245+
monkeypatch.chdir(tmp_path)
246+
247+
monkeypatch.setattr(setup.wget, "download", _fake_download_factory([]))
248+
monkeypatch.setattr(setup, "download_configs", lambda *_: None)
249+
monkeypatch.setattr(setup, "sync_prime_skills", lambda: None)
250+
251+
setup.run_setup(
252+
skip_install=True,
253+
skip_agents_md=True,
254+
agents="codex,cursor,codex",
255+
no_interactive=True,
256+
)
257+
258+
metadata_path = tmp_path / ".prime" / "lab.json"
259+
assert metadata_path.exists()
260+
metadata = json.loads(metadata_path.read_text())
261+
assert metadata["setup_source"] == "prime lab setup"
262+
assert metadata["choices"] == {
263+
"agents": ["codex", "cursor"],
264+
"primary_agent": "codex",
265+
"use_multiple_agents": True,
266+
}
267+
268+
269+
def test_run_setup_persists_default_lab_choices_metadata(
270+
tmp_path: Path, monkeypatch
271+
) -> None:
272+
monkeypatch.chdir(tmp_path)
273+
274+
monkeypatch.setattr(setup.wget, "download", _fake_download_factory([]))
275+
monkeypatch.setattr(setup, "download_configs", lambda *_: None)
276+
monkeypatch.setattr(setup, "sync_prime_skills", lambda: None)
277+
278+
setup.run_setup(skip_install=True, skip_agents_md=True, no_interactive=True)
279+
280+
metadata_path = tmp_path / ".prime" / "lab.json"
281+
assert metadata_path.exists()
282+
metadata = json.loads(metadata_path.read_text())
283+
assert metadata["setup_source"] == "prime lab setup"
284+
assert metadata["choices"] == {
285+
"agents": ["codex"],
286+
"primary_agent": "codex",
287+
"use_multiple_agents": False,
288+
}

verifiers/scripts/prime_rl.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
Wrapper script to run prime-rl rl command from the current working directory.
44
55
Usage:
6-
uv run prime-rl @ configs/prime-rl/config.toml
6+
uv run prime-rl configs/prime-rl/config.toml
77
"""
88

99
import argparse
@@ -147,7 +147,6 @@ def main():
147147
parser = argparse.ArgumentParser(
148148
description="Create a tmux session and run prime-rl rl command from a TOML config."
149149
)
150-
parser.add_argument("at", type=str)
151150
parser.add_argument("config_path", type=str)
152151
parser.add_argument(
153152
"--session",
@@ -168,9 +167,6 @@ def main():
168167
if not tmux_exists():
169168
raise SystemExit("tmux not found in PATH. Please install tmux.")
170169

171-
if args.at != "@":
172-
raise SystemExit("Usage: prime-rl @ path/to/file.toml")
173-
174170
cwd = Path.cwd()
175171
prime_rl_dir = cwd / "prime-rl"
176172
if not prime_rl_dir.exists():

0 commit comments

Comments
 (0)