synth-ai 0.2.4.dev8__py3-none-any.whl → 0.2.5__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.

Files changed (112) hide show
  1. synth_ai/__init__.py +1 -1
  2. synth_ai/cli/__init__.py +6 -0
  3. synth_ai/cli/demo.py +68 -9
  4. synth_ai/cli/rl_demo.py +137 -0
  5. synth_ai/cli/root.py +65 -0
  6. synth_ai/demos/core/__init__.py +1 -0
  7. synth_ai/demos/core/cli.py +685 -0
  8. synth_ai/demos/demo_task_apps/__init__.py +1 -0
  9. synth_ai/demos/demo_task_apps/core.py +374 -0
  10. synth_ai/demos/demo_task_apps/math/__init__.py +1 -0
  11. synth_ai/demos/demo_task_apps/math/app.py +37 -0
  12. synth_ai/demos/demo_task_apps/math/config.toml +44 -0
  13. synth_ai/demos/demo_task_apps/math/deploy_modal.py +60 -0
  14. synth_ai/demos/demo_task_apps/math/deploy_task_app.sh +22 -0
  15. synth_ai/environments/examples/bandit/__init__.py +33 -0
  16. synth_ai/environments/examples/bandit/engine.py +294 -0
  17. synth_ai/environments/examples/bandit/environment.py +194 -0
  18. synth_ai/environments/examples/bandit/taskset.py +200 -0
  19. synth_ai/environments/examples/crafter_classic/agent_demos/analyze_semantic_words_markdown.py +250 -0
  20. synth_ai/environments/examples/crafter_classic/agent_demos/crafter_comprehensive_evaluation.py +59 -0
  21. synth_ai/environments/examples/crafter_classic/agent_demos/crafter_evaluation_browser.py +152 -0
  22. synth_ai/environments/examples/crafter_classic/agent_demos/crafter_evaluation_config.toml +24 -0
  23. synth_ai/environments/examples/crafter_classic/agent_demos/crafter_evaluation_framework.py +1194 -0
  24. synth_ai/environments/examples/crafter_classic/agent_demos/crafter_modal_ft/crafter_synth_config.toml +56 -0
  25. synth_ai/environments/examples/crafter_classic/agent_demos/crafter_modal_ft/filter_config_modal.toml +32 -0
  26. synth_ai/environments/examples/crafter_classic/agent_demos/crafter_modal_ft/filter_traces_sft_turso.py +724 -0
  27. synth_ai/environments/examples/crafter_classic/agent_demos/crafter_modal_ft/kick_off_ft_modal.py +384 -0
  28. synth_ai/environments/examples/crafter_classic/agent_demos/crafter_modal_ft/old/analyze_action_results.py +53 -0
  29. synth_ai/environments/examples/crafter_classic/agent_demos/crafter_modal_ft/old/analyze_agent_actions.py +178 -0
  30. synth_ai/environments/examples/crafter_classic/agent_demos/crafter_modal_ft/old/analyze_latest_run.py +222 -0
  31. synth_ai/environments/examples/crafter_classic/agent_demos/crafter_modal_ft/old/analyze_lm_traces.py +183 -0
  32. synth_ai/environments/examples/crafter_classic/agent_demos/crafter_modal_ft/old/analyze_no_rewards.py +210 -0
  33. synth_ai/environments/examples/crafter_classic/agent_demos/crafter_modal_ft/old/analyze_trace_issue.py +206 -0
  34. synth_ai/environments/examples/crafter_classic/agent_demos/crafter_modal_ft/old/check_db_schema.py +49 -0
  35. synth_ai/environments/examples/crafter_classic/agent_demos/crafter_modal_ft/old/check_latest_results.py +64 -0
  36. synth_ai/environments/examples/crafter_classic/agent_demos/crafter_modal_ft/old/debug_agent_responses.py +88 -0
  37. synth_ai/environments/examples/crafter_classic/agent_demos/crafter_modal_ft/old/quick_trace_check.py +77 -0
  38. synth_ai/environments/examples/crafter_classic/agent_demos/crafter_openai_ft/compare_experiments.py +324 -0
  39. synth_ai/environments/examples/crafter_classic/agent_demos/crafter_openai_ft/filter_traces_sft_turso.py +580 -0
  40. synth_ai/environments/examples/crafter_classic/agent_demos/crafter_openai_ft/kick_off_ft_oai.py +362 -0
  41. synth_ai/environments/examples/crafter_classic/agent_demos/crafter_openai_ft/multi_model_config.toml +49 -0
  42. synth_ai/environments/examples/crafter_classic/agent_demos/crafter_openai_ft/old/analyze_enhanced_hooks.py +332 -0
  43. synth_ai/environments/examples/crafter_classic/agent_demos/crafter_openai_ft/old/analyze_hook_events.py +97 -0
  44. synth_ai/environments/examples/crafter_classic/agent_demos/crafter_openai_ft/old/analyze_hook_results.py +217 -0
  45. synth_ai/environments/examples/crafter_classic/agent_demos/crafter_openai_ft/old/check_hook_storage.py +87 -0
  46. synth_ai/environments/examples/crafter_classic/agent_demos/crafter_openai_ft/old/check_seeds.py +88 -0
  47. synth_ai/environments/examples/crafter_classic/agent_demos/crafter_openai_ft/old/compare_seed_performance.py +195 -0
  48. synth_ai/environments/examples/crafter_classic/agent_demos/crafter_openai_ft/old/custom_eval_pipelines.py +400 -0
  49. synth_ai/environments/examples/crafter_classic/agent_demos/crafter_openai_ft/old/plot_hook_frequency.py +195 -0
  50. synth_ai/environments/examples/crafter_classic/agent_demos/crafter_openai_ft/old/seed_analysis_summary.py +56 -0
  51. synth_ai/environments/examples/crafter_classic/agent_demos/crafter_openai_ft/run_rollouts_for_models_and_compare_v3.py +858 -0
  52. synth_ai/environments/examples/crafter_classic/agent_demos/crafter_quick_evaluation.py +52 -0
  53. synth_ai/environments/examples/crafter_classic/agent_demos/crafter_react_agent.py +874 -0
  54. synth_ai/environments/examples/crafter_classic/agent_demos/crafter_trace_evaluation.py +1412 -0
  55. synth_ai/environments/examples/crafter_classic/agent_demos/example_v3_usage.py +216 -0
  56. synth_ai/environments/examples/crafter_classic/agent_demos/old/compare_traces.py +296 -0
  57. synth_ai/environments/examples/crafter_classic/agent_demos/old/crafter_comprehensive_evaluation.py +58 -0
  58. synth_ai/environments/examples/crafter_classic/agent_demos/old/crafter_env_serialization.py +464 -0
  59. synth_ai/environments/examples/crafter_classic/agent_demos/old/crafter_evaluation_browser.py +152 -0
  60. synth_ai/environments/examples/crafter_classic/agent_demos/old/crafter_quick_evaluation.py +51 -0
  61. synth_ai/environments/examples/crafter_classic/agent_demos/old/crafter_trace_evaluation.py +1412 -0
  62. synth_ai/environments/examples/crafter_classic/agent_demos/old/debug_player_loss.py +112 -0
  63. synth_ai/environments/examples/crafter_classic/agent_demos/old/diagnose_service.py +203 -0
  64. synth_ai/environments/examples/crafter_classic/agent_demos/old/diagnose_slowness.py +305 -0
  65. synth_ai/environments/examples/crafter_classic/agent_demos/old/eval_by_difficulty.py +126 -0
  66. synth_ai/environments/examples/crafter_classic/agent_demos/old/eval_example.py +94 -0
  67. synth_ai/environments/examples/crafter_classic/agent_demos/old/explore_saved_states.py +142 -0
  68. synth_ai/environments/examples/crafter_classic/agent_demos/old/filter_traces_sft.py +26 -0
  69. synth_ai/environments/examples/crafter_classic/agent_demos/old/filter_traces_sft_OLD.py +984 -0
  70. synth_ai/environments/examples/crafter_classic/agent_demos/old/generate_ft_data_gemini.py +724 -0
  71. synth_ai/environments/examples/crafter_classic/agent_demos/old/generate_ft_data_modal.py +386 -0
  72. synth_ai/environments/examples/crafter_classic/agent_demos/old/generate_ft_metadata.py +205 -0
  73. synth_ai/environments/examples/crafter_classic/agent_demos/old/kick_off_ft_gemini.py +150 -0
  74. synth_ai/environments/examples/crafter_classic/agent_demos/old/kick_off_ft_modal.py +283 -0
  75. synth_ai/environments/examples/crafter_classic/agent_demos/old/prepare_vertex_ft.py +280 -0
  76. synth_ai/environments/examples/crafter_classic/agent_demos/old/profile_env_slowness.py +456 -0
  77. synth_ai/environments/examples/crafter_classic/agent_demos/old/replicate_issue.py +166 -0
  78. synth_ai/environments/examples/crafter_classic/agent_demos/old/run_and_eval.py +102 -0
  79. synth_ai/environments/examples/crafter_classic/agent_demos/old/run_comparison.py +128 -0
  80. synth_ai/environments/examples/crafter_classic/agent_demos/old/run_qwen_rollouts.py +655 -0
  81. synth_ai/environments/examples/crafter_classic/agent_demos/old/trace_eval_OLD.py +202 -0
  82. synth_ai/environments/examples/crafter_classic/agent_demos/old/validate_openai_format.py +166 -0
  83. synth_ai/environments/examples/crafter_classic/environment.py +41 -2
  84. synth_ai/environments/examples/crafter_custom/agent_demos/__init__.py +1 -0
  85. synth_ai/environments/examples/crafter_custom/agent_demos/trace_eval.py +202 -0
  86. synth_ai/environments/examples/crafter_custom/old/analyze_diamond_issue.py +159 -0
  87. synth_ai/environments/examples/crafter_custom/old/analyze_diamond_spawning.py +158 -0
  88. synth_ai/environments/examples/crafter_custom/old/compare_worlds.py +71 -0
  89. synth_ai/environments/examples/crafter_custom/old/dataset_stats.py +105 -0
  90. synth_ai/environments/examples/crafter_custom/old/diamond_spawning_summary.py +119 -0
  91. synth_ai/environments/examples/crafter_custom/old/example_dataset_usage.py +52 -0
  92. synth_ai/environments/examples/enron/units/keyword_stats.py +112 -0
  93. synth_ai/environments/examples/minigrid/agent_demos/minigrid_evaluation_framework.py +1188 -0
  94. synth_ai/environments/examples/minigrid/agent_demos/minigrid_quick_evaluation.py +48 -0
  95. synth_ai/environments/examples/minigrid/agent_demos/minigrid_react_agent.py +562 -0
  96. synth_ai/environments/examples/minigrid/agent_demos/minigrid_trace_evaluation.py +221 -0
  97. synth_ai/environments/examples/nethack/agent_demos/nethack_evaluation_framework.py +981 -0
  98. synth_ai/environments/examples/nethack/agent_demos/nethack_quick_evaluation.py +74 -0
  99. synth_ai/environments/examples/nethack/agent_demos/nethack_react_agent.py +831 -0
  100. synth_ai/environments/examples/red/agent_demos/__init__.py +1 -0
  101. synth_ai/environments/examples/red/units/__init__.py +1 -0
  102. synth_ai/environments/examples/sokoban/agent_demos/sokoban_full_eval.py +899 -0
  103. synth_ai/environments/examples/sokoban/units/astar_common.py +95 -0
  104. synth_ai/environments/service/app.py +8 -0
  105. synth_ai/install_sqld.sh +40 -0
  106. synth_ai-0.2.5.dist-info/METADATA +106 -0
  107. {synth_ai-0.2.4.dev8.dist-info → synth_ai-0.2.5.dist-info}/RECORD +111 -12
  108. {synth_ai-0.2.4.dev8.dist-info → synth_ai-0.2.5.dist-info}/entry_points.txt +1 -0
  109. synth_ai-0.2.4.dev8.dist-info/METADATA +0 -635
  110. {synth_ai-0.2.4.dev8.dist-info → synth_ai-0.2.5.dist-info}/WHEEL +0 -0
  111. {synth_ai-0.2.4.dev8.dist-info → synth_ai-0.2.5.dist-info}/licenses/LICENSE +0 -0
  112. {synth_ai-0.2.4.dev8.dist-info → synth_ai-0.2.5.dist-info}/top_level.txt +0 -0
synth_ai/__init__.py CHANGED
@@ -23,7 +23,7 @@ from synth_ai.tracing_v1.abstractions import (
23
23
  from synth_ai.tracing_v1.decorators import trace_event_async, trace_event_sync
24
24
  from synth_ai.tracing_v1.upload import upload
25
25
 
26
- __version__ = "0.2.4.dev8"
26
+ __version__ = "0.2.5"
27
27
  __all__ = [
28
28
  "LM",
29
29
  "tracing",
synth_ai/cli/__init__.py CHANGED
@@ -69,3 +69,9 @@ try:
69
69
  _demo.register(cli)
70
70
  except Exception:
71
71
  pass
72
+ try:
73
+ from . import rl_demo as _rl_demo
74
+
75
+ _rl_demo.register(cli)
76
+ except Exception:
77
+ pass
synth_ai/cli/demo.py CHANGED
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env python3
2
2
  """
3
- CLI: interactive launcher for example demos.
3
+ CLI: interactive launcher for example demos and forwarders for new RL demo.
4
4
 
5
- Finds all `run_demo.sh` scripts under `examples/` and lets the user pick one
6
- to run. Intended to be used as: `uvx synth-ai demo` or `synth-ai demo`.
5
+ - `synth-ai demo` (no subcommand) -> legacy examples/ runner (run_demo.sh picker)
6
+ - `synth-ai demo deploy|configure|run` -> forwards to synth_ai.demos.core.cli
7
7
  """
8
8
 
9
9
  from __future__ import annotations
@@ -21,12 +21,32 @@ def _find_demo_scripts(root: Path) -> list[Path]:
21
21
  return sorted([p for p in root.rglob("run_demo.sh") if p.is_file()])
22
22
 
23
23
 
24
+ def _forward_to_new(args: list[str]) -> None:
25
+ import sys
26
+ try:
27
+ from synth_ai.demos.core import cli as demo_cli # type: ignore
28
+ except Exception as e: # pragma: no cover
29
+ click.echo(f"Failed to import demo CLI: {e}")
30
+ sys.exit(1)
31
+ rc = int(demo_cli.main(args) or 0)
32
+ if rc != 0:
33
+ sys.exit(rc)
34
+
35
+
24
36
  def register(cli):
25
- @cli.command()
26
- @click.option("--list", "list_only", is_flag=True, help="List available demos and exit")
27
- @click.option("-f", "filter_term", default="", help="Filter demos by substring")
28
- def demo(list_only: bool, filter_term: str):
29
- """Launch an interactive demo from examples/"""
37
+ @cli.group("demo", invoke_without_command=True)
38
+ @click.option("--list", "list_only", is_flag=True, help="List available legacy demos and exit")
39
+ @click.option("-f", "filter_term", default="", help="Filter legacy demos by substring")
40
+ @click.pass_context
41
+ def demo(ctx: click.Context, list_only: bool, filter_term: str):
42
+ """Demo helpers.
43
+
44
+ - Legacy mode (no subcommand): find and run examples/*/run_demo.sh
45
+ - New RL demo subcommands: deploy, configure, run
46
+ """
47
+ if ctx.invoked_subcommand is not None:
48
+ return
49
+ # Legacy behavior: interactive examples runner
30
50
  repo_root = Path(os.getcwd())
31
51
  examples_dir = repo_root / "examples"
32
52
  demos = _find_demo_scripts(examples_dir)
@@ -63,10 +83,49 @@ def register(cli):
63
83
  click.echo("")
64
84
  click.echo(f"🚀 Running {script.relative_to(repo_root)}\n")
65
85
 
66
- # Run via bash to avoid relying on executable bit; inherit environment
67
86
  try:
68
87
  subprocess.run(["bash", str(script)], check=True)
69
88
  except subprocess.CalledProcessError as e:
70
89
  click.echo(f"❌ Demo exited with non-zero status: {e.returncode}")
71
90
  except KeyboardInterrupt:
72
91
  click.echo("\n🛑 Demo interrupted by user")
92
+
93
+ # (prepare command removed; configure now prepares baseline TOML)
94
+
95
+ @demo.command("deploy")
96
+ @click.option("--local", is_flag=True, help="Run local FastAPI instead of Modal deploy")
97
+ @click.option("--app", type=click.Path(), default=None, help="Path to Modal app.py for uv run modal deploy")
98
+ @click.option("--name", type=str, default="synth-math-demo", help="Modal app name")
99
+ @click.option("--script", type=click.Path(), default=None, help="Path to deploy_task_app.sh (optional legacy)")
100
+ def demo_deploy(local: bool, app: str | None, name: str, script: str | None):
101
+ args: list[str] = ["rl_demo.deploy"]
102
+ if local:
103
+ args.append("--local")
104
+ if app:
105
+ args.extend(["--app", app])
106
+ if name:
107
+ args.extend(["--name", name])
108
+ if script:
109
+ args.extend(["--script", script])
110
+ _forward_to_new(args)
111
+
112
+ @demo.command("configure")
113
+ def demo_configure():
114
+ _forward_to_new(["rl_demo.configure"])
115
+
116
+ @demo.command("run")
117
+ @click.option("--batch-size", type=int, default=None)
118
+ @click.option("--group-size", type=int, default=None)
119
+ @click.option("--model", type=str, default=None)
120
+ @click.option("--timeout", type=int, default=600)
121
+ def demo_run(batch_size: int | None, group_size: int | None, model: str | None, timeout: int):
122
+ args = ["rl_demo.run"]
123
+ if batch_size is not None:
124
+ args.extend(["--batch-size", str(batch_size)])
125
+ if group_size is not None:
126
+ args.extend(["--group-size", str(group_size)])
127
+ if model:
128
+ args.extend(["--model", model])
129
+ if timeout:
130
+ args.extend(["--timeout", str(timeout)])
131
+ _forward_to_new(args)
@@ -0,0 +1,137 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ New RL demo command group kept fully separate from legacy demo.
4
+
5
+ Usage examples:
6
+ uvx synth-ai rl_demo check
7
+ uvx synth-ai rl_demo deploy --app /path/to/math_task_app.py --name synth-math-demo
8
+ uvx synth-ai rl_demo configure
9
+ uvx synth-ai rl_demo run --batch-size 4 --group-size 16 --model Qwen/Qwen3-0.6B
10
+
11
+ For convenience, dotted aliases are also exposed:
12
+ uvx synth-ai rl_demo.check
13
+ """
14
+
15
+ from __future__ import annotations
16
+
17
+ import click
18
+
19
+
20
+ def _forward(args: list[str]) -> None:
21
+ import sys
22
+ try:
23
+ from synth_ai.demos.core import cli as demo_cli # type: ignore
24
+ except Exception as e: # pragma: no cover
25
+ click.echo(f"Failed to import RL demo CLI: {e}")
26
+ sys.exit(1)
27
+ rc = int(demo_cli.main(args) or 0)
28
+ if rc != 0:
29
+ sys.exit(rc)
30
+
31
+
32
+ def register(cli):
33
+ @cli.group("rl_demo")
34
+ def rl_demo():
35
+ """RL Demo commands (separate from legacy demo)."""
36
+
37
+ @rl_demo.command("check")
38
+ def rl_check():
39
+ _forward(["rl_demo.check"]) # reuse same implementation
40
+
41
+ # (prepare command removed; consolidated into configure)
42
+
43
+ @rl_demo.command("deploy")
44
+ @click.option("--local", is_flag=True, help="Run local FastAPI instead of Modal deploy")
45
+ @click.option("--app", type=click.Path(), default=None, help="Path to Modal app.py for uv run modal deploy")
46
+ @click.option("--name", type=str, default="synth-math-demo", help="Modal app name")
47
+ @click.option("--script", type=click.Path(), default=None, help="Path to deploy_task_app.sh (optional legacy)")
48
+ def rl_deploy(local: bool, app: str | None, name: str, script: str | None):
49
+ args: list[str] = ["rl_demo.deploy"]
50
+ if local:
51
+ args.append("--local")
52
+ if app:
53
+ args.extend(["--app", app])
54
+ if name:
55
+ args.extend(["--name", name])
56
+ if script:
57
+ args.extend(["--script", script])
58
+ _forward(args)
59
+
60
+ @rl_demo.command("configure")
61
+ def rl_configure():
62
+ _forward(["rl_demo.configure"])
63
+
64
+ @rl_demo.command("run")
65
+ @click.option("--config", type=click.Path(), default=None, help="Path to TOML config (skip prompt)")
66
+ @click.option("--batch-size", type=int, default=None)
67
+ @click.option("--group-size", type=int, default=None)
68
+ @click.option("--model", type=str, default=None)
69
+ @click.option("--timeout", type=int, default=600)
70
+ @click.option("--dry-run", is_flag=True, help="Print request body and exit")
71
+ def rl_run(config: str | None, batch_size: int | None, group_size: int | None, model: str | None, timeout: int, dry_run: bool):
72
+ args = ["rl_demo.run"]
73
+ if config:
74
+ args.extend(["--config", config])
75
+ if batch_size is not None:
76
+ args.extend(["--batch-size", str(batch_size)])
77
+ if group_size is not None:
78
+ args.extend(["--group-size", str(group_size)])
79
+ if model:
80
+ args.extend(["--model", model])
81
+ if timeout is not None:
82
+ args.extend(["--timeout", str(timeout)])
83
+ if dry_run:
84
+ args.append("--dry-run")
85
+ _forward(args)
86
+
87
+ # Dotted aliases (top-level) for convenience: rl_demo.check etc.
88
+ @cli.command("rl_demo.check")
89
+ def rl_check_alias():
90
+ _forward(["rl_demo.check"])
91
+
92
+ # (prepare alias removed)
93
+
94
+ @cli.command("rl_demo.deploy")
95
+ @click.option("--local", is_flag=True, help="Run local FastAPI instead of Modal deploy")
96
+ @click.option("--app", type=click.Path(), default=None, help="Path to Modal app.py for uv run modal deploy")
97
+ @click.option("--name", type=str, default="synth-math-demo", help="Modal app name")
98
+ @click.option("--script", type=click.Path(), default=None, help="Path to deploy_task_app.sh (optional legacy)")
99
+ def rl_deploy_alias(local: bool, app: str | None, name: str, script: str | None):
100
+ args: list[str] = ["rl_demo.deploy"]
101
+ if local:
102
+ args.append("--local")
103
+ if app:
104
+ args.extend(["--app", app])
105
+ if name:
106
+ args.extend(["--name", name])
107
+ if script:
108
+ args.extend(["--script", script])
109
+ _forward(args)
110
+
111
+ @cli.command("rl_demo.configure")
112
+ def rl_configure_alias():
113
+ _forward(["rl_demo.configure"])
114
+
115
+ @cli.command("rl_demo.run")
116
+ @click.option("--config", type=click.Path(), default=None, help="Path to TOML config (skip prompt)")
117
+ @click.option("--batch-size", type=int, default=None)
118
+ @click.option("--group-size", type=int, default=None)
119
+ @click.option("--model", type=str, default=None)
120
+ @click.option("--timeout", type=int, default=600)
121
+ @click.option("--dry-run", is_flag=True, help="Print request body and exit")
122
+ def rl_run_alias(config: str | None, batch_size: int | None, group_size: int | None, model: str | None, timeout: int, dry_run: bool):
123
+ args = ["rl_demo.run"]
124
+ if config:
125
+ args.extend(["--config", config])
126
+ if batch_size is not None:
127
+ args.extend(["--batch-size", str(batch_size)])
128
+ if group_size is not None:
129
+ args.extend(["--group-size", str(group_size)])
130
+ if model:
131
+ args.extend(["--model", model])
132
+ if timeout is not None:
133
+ args.extend(["--timeout", str(timeout)])
134
+ if dry_run:
135
+ args.append("--dry-run")
136
+ _forward(args)
137
+
synth_ai/cli/root.py CHANGED
@@ -71,6 +71,71 @@ def cli():
71
71
  """Synth AI - Software for aiding the best and multiplying the will."""
72
72
 
73
73
 
74
+ # === Legacy demo command group (aliases new rl_demo implementation) ===
75
+ @cli.group()
76
+ def demo():
77
+ """Demo helpers (deploy, configure, run)."""
78
+
79
+
80
+ def _forward_to_demo(args: list[str]) -> None:
81
+ # Lazy import to avoid loading demo deps unless needed
82
+ try:
83
+ from synth_ai.demos.core import cli as demo_cli # type: ignore
84
+ except Exception as e: # pragma: no cover
85
+ click.echo(f"Failed to import demo CLI: {e}")
86
+ sys.exit(1)
87
+ rc = int(demo_cli.main(args) or 0)
88
+ if rc != 0:
89
+ sys.exit(rc)
90
+
91
+
92
+ # (prepare command removed; handled by configure)
93
+
94
+
95
+ @demo.command()
96
+ @click.option("--local", is_flag=True, help="Run local FastAPI instead of Modal deploy")
97
+ @click.option("--app", type=click.Path(), default=None, help="Path to Modal app.py for uv run modal deploy")
98
+ @click.option("--name", type=str, default="synth-math-demo", help="Modal app name")
99
+ @click.option("--script", type=click.Path(), default=None, help="Path to deploy_task_app.sh (optional legacy)")
100
+ def deploy(local: bool, app: str | None, name: str, script: str | None):
101
+ """Deploy the Math Task App (Modal by default)."""
102
+ args: list[str] = ["rl_demo.deploy"]
103
+ if local:
104
+ args.append("--local")
105
+ if app:
106
+ args.extend(["--app", app])
107
+ if name:
108
+ args.extend(["--name", name])
109
+ if script:
110
+ args.extend(["--script", script])
111
+ _forward_to_demo(args)
112
+
113
+
114
+ @demo.command()
115
+ def configure():
116
+ """Print resolved environment and config path."""
117
+ _forward_to_demo(["rl_demo.configure"])
118
+
119
+
120
+ @demo.command()
121
+ @click.option("--batch-size", type=int, default=None)
122
+ @click.option("--group-size", type=int, default=None)
123
+ @click.option("--model", type=str, default=None)
124
+ @click.option("--timeout", type=int, default=600)
125
+ def run(batch_size: int | None, group_size: int | None, model: str | None, timeout: int):
126
+ """Kick off a short RL job using the prepared TOML."""
127
+ args = ["rl_demo.run"]
128
+ if batch_size is not None:
129
+ args.extend(["--batch-size", str(batch_size)])
130
+ if group_size is not None:
131
+ args.extend(["--group-size", str(group_size)])
132
+ if model:
133
+ args.extend(["--model", model])
134
+ if timeout:
135
+ args.extend(["--timeout", str(timeout)])
136
+ _forward_to_demo(args)
137
+
138
+
74
139
  @cli.command()
75
140
  @click.option("--db-file", default="traces/v3/synth_ai.db", help="Database file path")
76
141
  @click.option("--sqld-port", default=8080, type=int, help="Port for sqld HTTP interface")
@@ -0,0 +1 @@
1
+ # Core demo CLI and helpers package