synth-ai 0.2.6.dev6__py3-none-any.whl → 0.2.8.dev1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of synth-ai might be problematic. Click here for more details.
- synth_ai/cli/demo.py +55 -42
- synth_ai/cli/rl_demo.py +51 -5
- synth_ai/cli/root.py +6 -0
- synth_ai/demos/core/cli.py +625 -278
- synth_ai/demos/demo_task_apps/core.py +20 -10
- synth_ai/demos/demo_task_apps/math/config.toml +98 -13
- synth_ai/handshake.py +63 -0
- {synth_ai-0.2.6.dev6.dist-info → synth_ai-0.2.8.dev1.dist-info}/METADATA +26 -4
- {synth_ai-0.2.6.dev6.dist-info → synth_ai-0.2.8.dev1.dist-info}/RECORD +13 -12
- {synth_ai-0.2.6.dev6.dist-info → synth_ai-0.2.8.dev1.dist-info}/WHEEL +0 -0
- {synth_ai-0.2.6.dev6.dist-info → synth_ai-0.2.8.dev1.dist-info}/entry_points.txt +0 -0
- {synth_ai-0.2.6.dev6.dist-info → synth_ai-0.2.8.dev1.dist-info}/licenses/LICENSE +0 -0
- {synth_ai-0.2.6.dev6.dist-info → synth_ai-0.2.8.dev1.dist-info}/top_level.txt +0 -0
synth_ai/cli/demo.py
CHANGED
|
@@ -35,64 +35,73 @@ def _forward_to_new(args: list[str]) -> None:
|
|
|
35
35
|
|
|
36
36
|
def register(cli):
|
|
37
37
|
@cli.group("demo", invoke_without_command=True)
|
|
38
|
+
@click.option("--force", is_flag=True, help="Overwrite existing files in CWD when initializing demo")
|
|
38
39
|
@click.option("--list", "list_only", is_flag=True, help="List available legacy demos and exit")
|
|
39
40
|
@click.option("-f", "filter_term", default="", help="Filter legacy demos by substring")
|
|
40
41
|
@click.pass_context
|
|
41
|
-
def demo(ctx: click.Context, list_only: bool, filter_term: str):
|
|
42
|
+
def demo(ctx: click.Context, force: bool, list_only: bool, filter_term: str):
|
|
42
43
|
"""Demo helpers.
|
|
43
44
|
|
|
44
|
-
-
|
|
45
|
+
- Default (no subcommand): initialize RL demo files into ./synth_demo/ (alias of rl_demo init)
|
|
46
|
+
- Legacy mode: with --list, find and run examples/*/run_demo.sh
|
|
45
47
|
- New RL demo subcommands: deploy, configure, run
|
|
46
48
|
"""
|
|
47
49
|
if ctx.invoked_subcommand is not None:
|
|
48
50
|
return
|
|
49
|
-
# Legacy behavior: interactive examples runner
|
|
50
|
-
repo_root = Path(os.getcwd())
|
|
51
|
-
examples_dir = repo_root / "examples"
|
|
52
|
-
demos = _find_demo_scripts(examples_dir)
|
|
53
|
-
if filter_term:
|
|
54
|
-
demos = [p for p in demos if filter_term.lower() in str(p).lower()]
|
|
55
|
-
|
|
56
|
-
if not demos:
|
|
57
|
-
click.echo("No run_demo.sh scripts found under examples/.")
|
|
58
|
-
return
|
|
59
51
|
|
|
52
|
+
# If explicitly asked to list legacy demos, show interactive picker
|
|
60
53
|
if list_only:
|
|
54
|
+
repo_root = Path(os.getcwd())
|
|
55
|
+
examples_dir = repo_root / "examples"
|
|
56
|
+
demos = _find_demo_scripts(examples_dir)
|
|
57
|
+
if filter_term:
|
|
58
|
+
demos = [p for p in demos if filter_term.lower() in str(p).lower()]
|
|
59
|
+
|
|
60
|
+
if not demos:
|
|
61
|
+
click.echo("No run_demo.sh scripts found under examples/.")
|
|
62
|
+
return
|
|
63
|
+
|
|
61
64
|
click.echo("Available demos:")
|
|
62
|
-
for p in demos:
|
|
63
|
-
click.echo(f"
|
|
64
|
-
|
|
65
|
+
for idx, p in enumerate(demos, start=1):
|
|
66
|
+
click.echo(f" {idx}. {p.relative_to(repo_root)}")
|
|
67
|
+
click.echo("")
|
|
68
|
+
|
|
69
|
+
def _validate_choice(val: str) -> int:
|
|
70
|
+
try:
|
|
71
|
+
i = int(val)
|
|
72
|
+
except Exception as err:
|
|
73
|
+
raise click.BadParameter("Enter a number from the list") from err
|
|
74
|
+
if i < 1 or i > len(demos):
|
|
75
|
+
raise click.BadParameter(f"Choose a number between 1 and {len(demos)}")
|
|
76
|
+
return i
|
|
77
|
+
|
|
78
|
+
choice = click.prompt("Select a demo to run", value_proc=_validate_choice)
|
|
79
|
+
script = demos[choice - 1]
|
|
65
80
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
click.echo(f" {idx}. {p.relative_to(repo_root)}")
|
|
69
|
-
click.echo("")
|
|
81
|
+
click.echo("")
|
|
82
|
+
click.echo(f"🚀 Running {script.relative_to(repo_root)}\n")
|
|
70
83
|
|
|
71
|
-
def _validate_choice(val: str) -> int:
|
|
72
84
|
try:
|
|
73
|
-
|
|
74
|
-
except
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
return
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
try:
|
|
87
|
-
subprocess.run(["bash", str(script)], check=True)
|
|
88
|
-
except subprocess.CalledProcessError as e:
|
|
89
|
-
click.echo(f"❌ Demo exited with non-zero status: {e.returncode}")
|
|
90
|
-
except KeyboardInterrupt:
|
|
91
|
-
click.echo("\n🛑 Demo interrupted by user")
|
|
85
|
+
subprocess.run(["bash", str(script)], check=True)
|
|
86
|
+
except subprocess.CalledProcessError as e:
|
|
87
|
+
click.echo(f"❌ Demo exited with non-zero status: {e.returncode}")
|
|
88
|
+
except KeyboardInterrupt:
|
|
89
|
+
click.echo("\n🛑 Demo interrupted by user")
|
|
90
|
+
return
|
|
91
|
+
|
|
92
|
+
# Default: forward to RL demo init behavior, optionally with --force
|
|
93
|
+
args: list[str] = ["rl_demo.init"]
|
|
94
|
+
if force:
|
|
95
|
+
args.append("--force")
|
|
96
|
+
_forward_to_new(args)
|
|
92
97
|
|
|
93
98
|
# (prepare command removed; configure now prepares baseline TOML)
|
|
94
99
|
|
|
95
|
-
|
|
100
|
+
# Help pyright understand dynamic Click group attributes
|
|
101
|
+
from typing import Any, cast as _cast
|
|
102
|
+
_dg = _cast(Any, demo)
|
|
103
|
+
|
|
104
|
+
@_dg.command("deploy")
|
|
96
105
|
@click.option("--local", is_flag=True, help="Run local FastAPI instead of Modal deploy")
|
|
97
106
|
@click.option("--app", type=click.Path(), default=None, help="Path to Modal app.py for uv run modal deploy")
|
|
98
107
|
@click.option("--name", type=str, default="synth-math-demo", help="Modal app name")
|
|
@@ -109,11 +118,15 @@ def register(cli):
|
|
|
109
118
|
args.extend(["--script", script])
|
|
110
119
|
_forward_to_new(args)
|
|
111
120
|
|
|
112
|
-
@
|
|
121
|
+
@_dg.command("configure")
|
|
113
122
|
def demo_configure():
|
|
114
123
|
_forward_to_new(["rl_demo.configure"])
|
|
115
124
|
|
|
116
|
-
@
|
|
125
|
+
@_dg.command("setup")
|
|
126
|
+
def demo_setup():
|
|
127
|
+
_forward_to_new(["rl_demo.setup"])
|
|
128
|
+
|
|
129
|
+
@_dg.command("run")
|
|
117
130
|
@click.option("--batch-size", type=int, default=None)
|
|
118
131
|
@click.option("--group-size", type=int, default=None)
|
|
119
132
|
@click.option("--model", type=str, default=None)
|
synth_ai/cli/rl_demo.py
CHANGED
|
@@ -7,6 +7,7 @@ Usage examples:
|
|
|
7
7
|
uvx synth-ai rl_demo deploy --app /path/to/math_task_app.py --name synth-math-demo
|
|
8
8
|
uvx synth-ai rl_demo configure
|
|
9
9
|
uvx synth-ai rl_demo run --batch-size 4 --group-size 16 --model Qwen/Qwen3-0.6B
|
|
10
|
+
uvx synth-ai run --config demo_config.toml
|
|
10
11
|
|
|
11
12
|
For convenience, dotted aliases are also exposed:
|
|
12
13
|
uvx synth-ai rl_demo.check
|
|
@@ -38,9 +39,9 @@ def register(cli):
|
|
|
38
39
|
from typing import Any, cast as _cast
|
|
39
40
|
_rlg = _cast(Any, rl_demo)
|
|
40
41
|
|
|
41
|
-
@_rlg.command("
|
|
42
|
-
def
|
|
43
|
-
_forward(["rl_demo.
|
|
42
|
+
@_rlg.command("setup")
|
|
43
|
+
def rl_setup():
|
|
44
|
+
_forward(["rl_demo.setup"]) # primary setup command
|
|
44
45
|
|
|
45
46
|
# (prepare command removed; consolidated into configure)
|
|
46
47
|
|
|
@@ -96,10 +97,14 @@ def register(cli):
|
|
|
96
97
|
args.append("--dry-run")
|
|
97
98
|
_forward(args)
|
|
98
99
|
|
|
99
|
-
# Dotted aliases (top-level)
|
|
100
|
+
# Dotted aliases (top-level): legacy check → setup
|
|
100
101
|
@cli.command("rl_demo.check")
|
|
101
102
|
def rl_check_alias():
|
|
102
|
-
_forward(["rl_demo.
|
|
103
|
+
_forward(["rl_demo.setup"])
|
|
104
|
+
|
|
105
|
+
@cli.command("rl_demo.setup")
|
|
106
|
+
def rl_setup_alias():
|
|
107
|
+
_forward(["rl_demo.setup"])
|
|
103
108
|
|
|
104
109
|
# (prepare alias removed)
|
|
105
110
|
|
|
@@ -154,3 +159,44 @@ def register(cli):
|
|
|
154
159
|
if dry_run:
|
|
155
160
|
args.append("--dry-run")
|
|
156
161
|
_forward(args)
|
|
162
|
+
|
|
163
|
+
# Top-level convenience alias: `synth-ai deploy`
|
|
164
|
+
@cli.command("deploy")
|
|
165
|
+
@click.option("--local", is_flag=True, help="Run local FastAPI instead of Modal deploy")
|
|
166
|
+
@click.option("--app", type=click.Path(), default=None, help="Path to Modal app.py for uv run modal deploy")
|
|
167
|
+
@click.option("--name", type=str, default="synth-math-demo", help="Modal app name")
|
|
168
|
+
@click.option("--script", type=click.Path(), default=None, help="Path to deploy_task_app.sh (optional legacy)")
|
|
169
|
+
def deploy_top(local: bool, app: str | None, name: str, script: str | None):
|
|
170
|
+
args: list[str] = ["rl_demo.deploy"]
|
|
171
|
+
if local:
|
|
172
|
+
args.append("--local")
|
|
173
|
+
if app:
|
|
174
|
+
args.extend(["--app", app])
|
|
175
|
+
if name:
|
|
176
|
+
args.extend(["--name", name])
|
|
177
|
+
if script:
|
|
178
|
+
args.extend(["--script", script])
|
|
179
|
+
_forward(args)
|
|
180
|
+
|
|
181
|
+
@cli.command("run")
|
|
182
|
+
@click.option("--config", type=click.Path(), default=None, help="Path to TOML config (skip prompt)")
|
|
183
|
+
@click.option("--batch-size", type=int, default=None)
|
|
184
|
+
@click.option("--group-size", type=int, default=None)
|
|
185
|
+
@click.option("--model", type=str, default=None)
|
|
186
|
+
@click.option("--timeout", type=int, default=600)
|
|
187
|
+
@click.option("--dry-run", is_flag=True, help="Print request body and exit")
|
|
188
|
+
def run_top(config: str | None, batch_size: int | None, group_size: int | None, model: str | None, timeout: int, dry_run: bool):
|
|
189
|
+
args = ["run"]
|
|
190
|
+
if config:
|
|
191
|
+
args.extend(["--config", config])
|
|
192
|
+
if batch_size is not None:
|
|
193
|
+
args.extend(["--batch-size", str(batch_size)])
|
|
194
|
+
if group_size is not None:
|
|
195
|
+
args.extend(["--group-size", str(group_size)])
|
|
196
|
+
if model:
|
|
197
|
+
args.extend(["--model", model])
|
|
198
|
+
if timeout is not None:
|
|
199
|
+
args.extend(["--timeout", str(timeout)])
|
|
200
|
+
if dry_run:
|
|
201
|
+
args.append("--dry-run")
|
|
202
|
+
_forward(args)
|
synth_ai/cli/root.py
CHANGED
|
@@ -117,6 +117,12 @@ def configure():
|
|
|
117
117
|
_forward_to_demo(["rl_demo.configure"])
|
|
118
118
|
|
|
119
119
|
|
|
120
|
+
@demo.command()
|
|
121
|
+
def setup():
|
|
122
|
+
"""Perform SDK handshake and write keys to .env."""
|
|
123
|
+
_forward_to_demo(["rl_demo.setup"])
|
|
124
|
+
|
|
125
|
+
|
|
120
126
|
@demo.command()
|
|
121
127
|
@click.option("--batch-size", type=int, default=None)
|
|
122
128
|
@click.option("--group-size", type=int, default=None)
|