synth-ai 0.2.6.dev5__py3-none-any.whl → 0.2.7__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.
synth_ai/cli/balance.py CHANGED
@@ -15,7 +15,9 @@ from rich import box
15
15
  from rich.console import Console
16
16
  from rich.table import Table
17
17
 
18
- PROD_BACKEND_BASE = "https://agent-learning.onrender.com/api/v1"
18
+ from synth_ai.config.base_url import get_backend_from_env, PROD_BASE_URL_DEFAULT
19
+
20
+ PROD_BACKEND_BASE = f"{PROD_BASE_URL_DEFAULT.rstrip('/')}/api/v1"
19
21
 
20
22
 
21
23
  def _get_default_base_url() -> str:
@@ -24,7 +26,11 @@ def _get_default_base_url() -> str:
24
26
  val = os.getenv(var)
25
27
  if val:
26
28
  return val
27
- return PROD_BACKEND_BASE
29
+ base, _ = get_backend_from_env()
30
+ base = base.rstrip("/")
31
+ if base.endswith("/api"):
32
+ base = base[:-len("/api")]
33
+ return f"{base}/api/v1"
28
34
 
29
35
 
30
36
  def _ensure_api_v1_prefix(base_url: str) -> str:
synth_ai/cli/demo.py CHANGED
@@ -92,7 +92,11 @@ def register(cli):
92
92
 
93
93
  # (prepare command removed; configure now prepares baseline TOML)
94
94
 
95
- @demo.command("deploy")
95
+ # Help pyright understand dynamic Click group attributes
96
+ from typing import Any, cast as _cast
97
+ _dg = _cast(Any, demo)
98
+
99
+ @_dg.command("deploy")
96
100
  @click.option("--local", is_flag=True, help="Run local FastAPI instead of Modal deploy")
97
101
  @click.option("--app", type=click.Path(), default=None, help="Path to Modal app.py for uv run modal deploy")
98
102
  @click.option("--name", type=str, default="synth-math-demo", help="Modal app name")
@@ -109,11 +113,15 @@ def register(cli):
109
113
  args.extend(["--script", script])
110
114
  _forward_to_new(args)
111
115
 
112
- @demo.command("configure")
116
+ @_dg.command("configure")
113
117
  def demo_configure():
114
118
  _forward_to_new(["rl_demo.configure"])
115
119
 
116
- @demo.command("run")
120
+ @_dg.command("setup")
121
+ def demo_setup():
122
+ _forward_to_new(["rl_demo.setup"])
123
+
124
+ @_dg.command("run")
117
125
  @click.option("--batch-size", type=int, default=None)
118
126
  @click.option("--group-size", type=int, default=None)
119
127
  @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("check")
42
- def rl_check():
43
- _forward(["rl_demo.check"]) # reuse same implementation
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) for convenience: rl_demo.check etc.
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.check"])
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)
@@ -66,6 +66,7 @@ def get_backend_from_env() -> tuple[str, str]:
66
66
  """Resolve (base_url, api_key) using a simple LOCAL/DEV/PROD override scheme.
67
67
 
68
68
  Env vars consulted:
69
+ - BACKEND_OVERRIDE = full URL (with or without /api)
69
70
  - SYNTH_BACKEND_URL_OVERRIDE = local|dev|prod (case-insensitive)
70
71
  - LOCAL_BACKEND_URL, TESTING_LOCAL_SYNTH_API_KEY
71
72
  - DEV_BACKEND_URL, DEV_SYNTH_API_KEY
@@ -74,6 +75,14 @@ def get_backend_from_env() -> tuple[str, str]:
74
75
  Base URL is normalized to end with '/api'.
75
76
  Defaults: prod base URL → https://agent-learning.onrender.com/api
76
77
  """
78
+ direct_override = (os.getenv("BACKEND_OVERRIDE") or "").strip()
79
+ if direct_override:
80
+ base = direct_override.rstrip("/")
81
+ if base.endswith("/api"):
82
+ base = base[: -len("/api")]
83
+ api_key = os.getenv("SYNTH_API_KEY", "").strip()
84
+ return base, api_key
85
+
77
86
  mode = _resolve_override_mode()
78
87
  if mode == "local":
79
88
  base = os.getenv("LOCAL_BACKEND_URL", "http://localhost:8000")