synth-ai 0.2.7__py3-none-any.whl → 0.2.8__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 CHANGED
@@ -35,60 +35,65 @@ 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
- - Legacy mode (no subcommand): find and run examples/*/run_demo.sh
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" - {p.relative_to(repo_root)}")
64
- return
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
65
77
 
66
- click.echo("Available demos:")
67
- for idx, p in enumerate(demos, start=1):
68
- click.echo(f" {idx}. {p.relative_to(repo_root)}")
69
- click.echo("")
78
+ choice = click.prompt("Select a demo to run", value_proc=_validate_choice)
79
+ script = demos[choice - 1]
80
+
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
- i = int(val)
74
- except Exception as err:
75
- raise click.BadParameter("Enter a number from the list") from err
76
- if i < 1 or i > len(demos):
77
- raise click.BadParameter(f"Choose a number between 1 and {len(demos)}")
78
- return i
79
-
80
- choice = click.prompt("Select a demo to run", value_proc=_validate_choice)
81
- script = demos[choice - 1]
82
-
83
- click.echo("")
84
- click.echo(f"🚀 Running {script.relative_to(repo_root)}\n")
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
 
synth_ai/cli/root.py CHANGED
@@ -142,6 +142,12 @@ def run(batch_size: int | None, group_size: int | None, model: str | None, timeo
142
142
  _forward_to_demo(args)
143
143
 
144
144
 
145
+ @cli.command()
146
+ def setup():
147
+ """Perform SDK handshake and write keys to .env."""
148
+ _forward_to_demo(["rl_demo.setup"])
149
+
150
+
145
151
  @cli.command()
146
152
  @click.option("--db-file", default="traces/v3/synth_ai.db", help="Database file path")
147
153
  @click.option("--sqld-port", default=8080, type=int, help="Port for sqld HTTP interface")
@@ -66,15 +66,6 @@ def cmd_setup(_args: argparse.Namespace) -> int:
66
66
  env = demo_core.load_env()
67
67
  local_env = demo_core.load_dotenv_file(cwd_env_path)
68
68
 
69
- def _is_modal_public_url(u: str) -> bool:
70
- try:
71
- s = (u or "").strip().lower()
72
- if not (s.startswith("http://") or s.startswith("https://")):
73
- return False
74
- return (".modal.run" in s) and ("modal.local" not in s) and ("pypi-mirror" not in s)
75
- except Exception:
76
- return False
77
-
78
69
  def _maybe_fix_task_url() -> None:
79
70
  if not env.task_app_name:
80
71
  return
@@ -772,7 +763,10 @@ def cmd_deploy(args: argparse.Namespace) -> int:
772
763
  raise FileNotFoundError(f"App file not found: {app_path}")
773
764
  # Surface the app path before asking for the name
774
765
  print(f"Using task app: {app_path}")
775
- suggested_name = args.name or f"synth-{os.path.splitext(os.path.basename(app_path))[0]}"
766
+ existing_name = (args.name or env.task_app_name or "").strip()
767
+ if not existing_name:
768
+ existing_name = f"synth-{os.path.splitext(os.path.basename(app_path))[0]}"
769
+ suggested_name = existing_name
776
770
  name_in = input(f"Modal app name [{suggested_name}]: ").strip() or suggested_name
777
771
  app_name = name_in
778
772
  print("\nAbout to deploy with:")
@@ -783,7 +777,11 @@ def cmd_deploy(args: argparse.Namespace) -> int:
783
777
  print("Aborted by user.")
784
778
  return 1
785
779
 
786
- secret_name = (env.task_app_secret_name or "").strip() or f"{name_in}-secret"
780
+ prev_secret = (env.task_app_secret_name or "").strip()
781
+ default_secret = f"{name_in}-secret"
782
+ secret_name = default_secret if not prev_secret else prev_secret
783
+ if prev_secret and prev_secret != default_secret:
784
+ secret_name = default_secret
787
785
  existing_env_key = (env.env_api_key or "").strip()
788
786
  env_key: str | None = existing_env_key or None
789
787
  if existing_env_key:
@@ -808,24 +806,24 @@ def cmd_deploy(args: argparse.Namespace) -> int:
808
806
  print("[deploy] Minted new ENVIRONMENT_API_KEY")
809
807
 
810
808
  # Optionally upload the new key to the backend using sealed box helper
811
- backend_base = env.dev_backend_url or ""
809
+ backend_base = (env.dev_backend_url or "").rstrip("/")
812
810
  synth_key = (env.synth_api_key or os.environ.get("SYNTH_API_KEY") or local_env.get("SYNTH_API_KEY") or "").strip()
813
811
  if backend_base and synth_key:
814
- backend_base = backend_base.rstrip("/")
815
- if not backend_base.endswith("/api"):
816
- backend_base = f"{backend_base}/api"
812
+ # Pass a base WITHOUT trailing /api to setup_environment_api_key,
813
+ # since it appends /api/v1/... internally.
814
+ non_api_base = backend_base[:-4] if backend_base.endswith("/api") else backend_base
817
815
  try:
818
816
  choice = input(
819
- f"Upload ENVIRONMENT_API_KEY to backend {backend_base}? [Y/n]: "
817
+ f"Upload ENVIRONMENT_API_KEY to backend {non_api_base}? [Y/n]: "
820
818
  ).strip().lower() or "y"
821
819
  except Exception:
822
820
  choice = "y"
823
821
  if choice.startswith("y"):
824
822
  try:
825
- print(f"[deploy] Uploading ENVIRONMENT_API_KEY to {backend_base} …")
823
+ print(f"[deploy] Uploading ENVIRONMENT_API_KEY to {non_api_base} …")
826
824
  from synth_ai.rl.env_keys import setup_environment_api_key
827
825
 
828
- setup_environment_api_key(backend_base.rstrip("/"), synth_key, token=env_key)
826
+ setup_environment_api_key(non_api_base, synth_key, token=env_key)
829
827
  print("[deploy] Backend sealed-box upload complete.")
830
828
  except Exception as upload_err:
831
829
  print(f"[deploy] Failed to upload ENVIRONMENT_API_KEY: {upload_err}")
@@ -926,7 +924,7 @@ def cmd_deploy(args: argparse.Namespace) -> int:
926
924
  print(f" export TASK_APP_NAME={app_name}")
927
925
  print(f" export TASK_APP_SECRET_NAME={app_name}-secret")
928
926
  print(f"Persisted to {dotenv_path}")
929
- print("Next: uvx synth-ai run")
927
+ print("\nNext step:\n$ uvx synth-ai run")
930
928
  return 0
931
929
  except Exception as e:
932
930
  print(f"Deploy error: {e}")
@@ -1079,11 +1077,7 @@ fi
1079
1077
  if os.path.exists(dst_cfg):
1080
1078
  print(f" - {dst_cfg} (seeded)")
1081
1079
  print("")
1082
- print("Next steps:")
1083
- print(" 1) cd synth_demo && put your ENVIRONMENT_API_KEY in ./.env")
1084
- print(" 2) Deploy to Modal:")
1085
- print(" uvx bash ./deploy_task_app.sh")
1086
- print(" 3) From project root, run: uvx synth-ai run")
1080
+ print("\nNext step:\n$ uvx synth-ai setup")
1087
1081
  return 0
1088
1082
  except Exception as e:
1089
1083
  print(f"Init error: {e}")
@@ -1372,7 +1366,7 @@ def main(argv: list[str] | None = None) -> int:
1372
1366
  def _deploy_opts(parser):
1373
1367
  parser.add_argument("--local", action="store_true", help="Run local FastAPI instead of Modal deploy")
1374
1368
  parser.add_argument("--app", type=str, default=None, help="Path to Modal app.py for uv run modal deploy")
1375
- parser.add_argument("--name", type=str, default="synth-math-demo", help="Modal app name")
1369
+ parser.add_argument("--name", type=str, default=None, help="Modal app name")
1376
1370
  parser.add_argument("--script", type=str, default=None, help="Path to deploy_task_app.sh (optional legacy)")
1377
1371
  parser.set_defaults(func=cmd_deploy)
1378
1372
 
@@ -43,7 +43,15 @@ if _SYNTH_HOSTED is not None:
43
43
  # No extra local dirs required; app is self-contained
44
44
 
45
45
  app = App("hendrycks-math-task-app")
46
- _SECRET_NAME = os.getenv("MATH_TASK_APP_SECRET", "crafter-environment-sdk")
46
+ _SECRET_NAME = (
47
+ os.getenv("TASK_APP_SECRET_NAME")
48
+ or os.getenv("MATH_TASK_APP_SECRET")
49
+ or os.getenv("TASK_APP_NAME", "").strip()
50
+ )
51
+ if not _SECRET_NAME:
52
+ _SECRET_NAME = "synth-math-demo-secret"
53
+ elif not _SECRET_NAME.endswith("-secret"):
54
+ _SECRET_NAME = f"{_SECRET_NAME}-secret"
47
55
 
48
56
 
49
57
  @app.function(
@@ -411,5 +419,3 @@ def fastapi_app():
411
419
  }
412
420
 
413
421
  return api
414
-
415
-
synth_ai/handshake.py CHANGED
@@ -1,10 +1,9 @@
1
1
  from __future__ import annotations
2
-
3
- import json
4
2
  import os
5
3
  import time
6
4
  import webbrowser
7
5
  from typing import Any, Dict, Tuple
6
+ from urllib.parse import urljoin, urlsplit, urlunsplit
8
7
 
9
8
  import requests
10
9
 
@@ -13,18 +12,58 @@ class HandshakeError(Exception):
13
12
  pass
14
13
 
15
14
 
15
+ _TRUTHY = {"1", "true", "yes", "on"}
16
+
17
+
16
18
  def _origin() -> str:
17
- # Prefer explicit env; fallback to localhost dashboard
18
- return (os.getenv("SYNTH_CANONICAL_ORIGIN", "") or "http://localhost:3000").rstrip("/")
19
+ """Resolve the dashboard origin for the browser handshake.
20
+
21
+ Priority order:
22
+ 1. Explicit ``SYNTH_CANONICAL_ORIGIN`` override.
23
+ 2. Development flag ``SYNTH_CANONICAL_DEV`` (case-insensitive truthy) → localhost.
24
+ 3. Production dashboard at ``https://www.usesynth.ai/dashboard``.
25
+ """
26
+
27
+ override = (os.getenv("SYNTH_CANONICAL_ORIGIN") or "").strip()
28
+ if override:
29
+ return override.rstrip("/")
30
+
31
+ dev_flag = (os.getenv("SYNTH_CANONICAL_DEV") or "").strip().lower()
32
+ if dev_flag in _TRUTHY:
33
+ print("USING DEV ORIGIN")
34
+ return "http://localhost:3000"
35
+
36
+ return "https://www.usesynth.ai/dashboard"
37
+
38
+
39
+ def _split_origin(origin: str) -> tuple[str, str]:
40
+ parsed = urlsplit(origin)
41
+ bare = urlunsplit((parsed.scheme, parsed.netloc, "", "", ""))
42
+ path = parsed.path.rstrip("/")
43
+ return bare, path
44
+
45
+
46
+ def _ensure_verification_uri(data: Dict[str, Any], base_with_path: str) -> None:
47
+ uri = data.get("verification_uri")
48
+ if not isinstance(uri, str) or not uri:
49
+ return
50
+ if uri.startswith("http://") or uri.startswith("https://"):
51
+ return
52
+ data["verification_uri"] = urljoin(base_with_path.rstrip("/") + "/", uri.lstrip("/"))
19
53
 
20
54
 
21
55
  def start_handshake_session(origin: str | None = None) -> Tuple[str, str, int, int]:
22
56
  base = (origin or _origin()).rstrip("/")
23
- url = f"{base}/api/sdk/handshake/init"
57
+ api_origin, _ = _split_origin(base)
58
+ url = urljoin(api_origin.rstrip("/") + "/", "api/sdk/handshake/init")
24
59
  r = requests.post(url, timeout=10)
25
60
  if r.status_code != 200:
26
61
  raise HandshakeError(f"init failed: {r.status_code} {r.text}")
27
- data = r.json()
62
+ try:
63
+ data = r.json()
64
+ except ValueError as exc: # pragma: no cover - network dependent
65
+ raise HandshakeError(f"init returned malformed JSON: {exc}") from exc
66
+ _ensure_verification_uri(data, base)
28
67
  return (
29
68
  str(data.get("device_code")),
30
69
  str(data.get("verification_uri")),
@@ -35,7 +74,8 @@ def start_handshake_session(origin: str | None = None) -> Tuple[str, str, int, i
35
74
 
36
75
  def poll_handshake_token(device_code: str, origin: str | None = None, *, timeout_s: int | None = None) -> Dict[str, Any]:
37
76
  base = (origin or _origin()).rstrip("/")
38
- url = f"{base}/api/sdk/handshake/token"
77
+ api_origin, _ = _split_origin(base)
78
+ url = urljoin(api_origin.rstrip("/") + "/", "api/sdk/handshake/token")
39
79
  deadline = time.time() + (timeout_s or 600)
40
80
  while True:
41
81
  if time.time() > deadline:
@@ -46,7 +86,12 @@ def poll_handshake_token(device_code: str, origin: str | None = None, *, timeout
46
86
  time.sleep(2)
47
87
  continue
48
88
  if r.status_code == 200:
49
- return r.json()
89
+ try:
90
+ data = r.json()
91
+ except ValueError as exc: # pragma: no cover - network dependent
92
+ raise HandshakeError(f"token returned malformed JSON: {exc}") from exc
93
+ _ensure_verification_uri(data, base)
94
+ return data
50
95
  elif r.status_code in (404, 410):
51
96
  raise HandshakeError(f"handshake failed: {r.status_code}")
52
97
  # 428 authorization_pending or others → wait and retry
@@ -60,4 +105,3 @@ def run_handshake(origin: str | None = None) -> Dict[str, Any]:
60
105
  except Exception:
61
106
  pass
62
107
  return poll_handshake_token(device_code, origin, timeout_s=expires_in)
63
-
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: synth-ai
3
- Version: 0.2.7
3
+ Version: 0.2.8
4
4
  Summary: RL as a service SDK - Core AI functionality and tracing
5
5
  Author-email: Synth AI <josh@usesynth.ai>
6
6
  License-Expression: MIT
@@ -53,7 +53,7 @@ Requires-Dist: asyncpg>=0.30.0
53
53
  Requires-Dist: aiohttp>=3.8.0
54
54
  Requires-Dist: datasets>=4.0.0
55
55
  Requires-Dist: transformers>=4.56.1
56
- Requires-Dist: modal>=1.1.4
56
+ Requires-Dist: modal>=1.1.0
57
57
  Provides-Extra: dev
58
58
  Requires-Dist: build>=1.2.2.post1; extra == "dev"
59
59
  Requires-Dist: twine>=4.0.0; extra == "dev"
@@ -98,16 +98,17 @@ synth-ai comes with a built-in RL example tailored for training Qwen/Qwen3-0.6B
98
98
  Please create an account at [Synth](https://usesynth.ai) and [Modal](https://modal.com) for the Math hello‑world test run. Then run:
99
99
 
100
100
  ```bash
101
- uvx synth-ai rl_demo setup
102
- uvx synth-ai rl_demo deploy
101
+ uvx synth-ai demo
102
+ uvx synth-ai setup
103
+ uvx synth-ai deploy
103
104
  uvx synth-ai run
104
105
  ```
105
106
 
106
107
  To walk through kicking off your first RL run, see the [Synth‑AI Documentation](https://docs.usesynth.ai/synth-ai/introduction).
107
108
 
108
- ### What `rl_demo setup` does now
109
+ ### What `setup` does now
109
110
 
110
- When you run `uvx synth-ai rl_demo setup`, the SDK opens your browser to the Synth dashboard for a one‑time pairing (handshake) with your signed‑in session. The SDK will automatically:
111
+ When you run `uvx synth-ai setup` (or the legacy `uvx synth-ai rl_demo setup`), the SDK opens your browser to the Synth dashboard for a one‑time pairing (handshake) with your signed‑in session. The SDK will automatically:
111
112
 
112
113
  - Detect your current user and organization
113
114
  - Ensure both API keys exist for that user+org
@@ -124,5 +125,6 @@ If your browser isn’t already signed in, sign in when prompted and the pairing
124
125
 
125
126
  Environment variables:
126
127
 
127
- - `SYNTH_CANONICAL_ORIGIN` (optional): override the dashboard base URL the SDK uses for the handshake (defaults to `http://localhost:3000`).
128
+ - `SYNTH_CANONICAL_ORIGIN` (optional): override the dashboard base URL the SDK uses for the handshake (defaults to `https://www.usesynth.ai/dashboard`).
129
+ - `SYNTH_CANONICAL_DEV` (optional): set to `1`, `true`, `yes`, or `on` to target the local dashboard at `http://localhost:3000`.
128
130
  - Keys are stored only in your project’s `.env` file, not exported to your shell.
@@ -1,18 +1,18 @@
1
1
  synth_ai/__init__.py,sha256=NixuXddy4lS2Wmj0F8eMt0HS_oYCTnq3iVVq5VYwWIc,1341
2
2
  synth_ai/__main__.py,sha256=Kh1xBKkTE5Vs2qNMtDuuOXerHUptMcOiF3YziOpC6DA,146
3
- synth_ai/handshake.py,sha256=AJR0GFFAkdAga8CXRLYbQl90-s0AQzTGxy5tQzPQb0E,1994
3
+ synth_ai/handshake.py,sha256=uzoTOpkf9JQgsyKWrlx8gjfQmK3HpqFQAZY1gZDtiIo,3735
4
4
  synth_ai/http.py,sha256=lqjFXDmAP_xgfywK_rDSOVxuMy4rDH9S3Rtu9k1tLmk,1028
5
5
  synth_ai/http_client.py,sha256=_9J8rUGoItUMnJLGZw7r0uXiJeLWR939kByRkvtP1XM,4429
6
6
  synth_ai/install_sqld.sh,sha256=AMBhlfq661PxeTTc6D4K_Nei_qwMvA84ei4NhQzmUUk,928
7
7
  synth_ai/cli/__init__.py,sha256=ThBK5FykxAqX8Mz0E4gj94_PX9EwMEtXcmm-A8krv7E,1559
8
8
  synth_ai/cli/balance.py,sha256=z4h1MQSyFX60k-13L9IT0rtOCI16iKNGJeNjFMZuv_k,8010
9
9
  synth_ai/cli/calc.py,sha256=RJyQJ41e02xn-V0vRRCAVkL59UHDqyz8XpYGsenfdm4,2085
10
- synth_ai/cli/demo.py,sha256=YGZhmCE0XLLP31OdsdGceTL6oFHmzyOc0CO-Crl54W0,5064
10
+ synth_ai/cli/demo.py,sha256=NeRiLv9ZQyX9tVxvZ6uV5YmucQ8fu5gyL5qZE0GfBZY,5496
11
11
  synth_ai/cli/legacy_root_backup.py,sha256=KSMADyJ2g5OVpsq_CeBzqIeDC2Um-9GyINzsJH-75uw,15872
12
12
  synth_ai/cli/man.py,sha256=JQDon73ZkuKP9xr1_vRh5fjV9_b5xiUb7zNjny7ArB8,3765
13
13
  synth_ai/cli/recent.py,sha256=mHhM-QrR_MfjfKSzBvvPUEC-lkXTWUZrQwqYTmb2x0Y,4173
14
14
  synth_ai/cli/rl_demo.py,sha256=HAZqHaGFKAu7yXtjglmmNcHp4js77wCYSpa2WTcjyUE,8050
15
- synth_ai/cli/root.py,sha256=7YgAxsefqscE4QEaa3kuKqBnaHbQLa4ZyXJ5l8eVl7Y,9741
15
+ synth_ai/cli/root.py,sha256=C5eA3fuzyL6fpSDT7pRk4kT0BOAmdfS6SkaH3LgYTAY,9867
16
16
  synth_ai/cli/status.py,sha256=M_bt7U58Ubi-q-ZlrIpgCASKq9_k6uMjpx926f6kLLA,4591
17
17
  synth_ai/cli/traces.py,sha256=_QBdCR92u0Gv51U4DH0Ws1d5yCrbJRpaYKe7pmcHrHs,6484
18
18
  synth_ai/cli/watch.py,sha256=HBKbAcpUkkPhGvsPRofckbu8oILiVqp35NXHkIEpTTc,17808
@@ -21,7 +21,7 @@ synth_ai/config/base_url.py,sha256=c85LaABBrvsl8Fp8KH0LNtJJrpnUwlzA5Ywbuth8fHE,3
21
21
  synth_ai/core/experiment.py,sha256=hLkPtzUFA7iY3-QpeJ5K8YjvQeyfqnjab5P2CFaojys,236
22
22
  synth_ai/core/system.py,sha256=s-Z7np2ISYmYc1r9YN-y2yb3cgRlOalrh0iaqnxeo84,206
23
23
  synth_ai/demos/core/__init__.py,sha256=A2FjhY7KXGtyzdQXqeTPCkEhHfrH-eQg6bvP8HaYhZM,36
24
- synth_ai/demos/core/cli.py,sha256=KkIm7nhKxHN26UQAjh-5wW-y__Z481UR23JmFl2GpM4,56329
24
+ synth_ai/demos/core/cli.py,sha256=lwkW1j638pOaLpmo6vPtDvEjsWdtLDCTwjbHoSHOdA8,56220
25
25
  synth_ai/demos/demo_task_apps/__init__.py,sha256=8aUGEGpWUw11GRb3wQXRAmQ99yjAt5qd5FCTDJpXWjI,44
26
26
  synth_ai/demos/demo_task_apps/core.py,sha256=ifKxxRKqC-y43MaqLHNuerXAlBHO8MI8ZBo2CzYcOoU,14563
27
27
  synth_ai/demos/demo_task_apps/math/__init__.py,sha256=WBzpZwSn7pRarBmhopQi34i9bEm05-71eM3siboOavY,43
@@ -30,7 +30,7 @@ synth_ai/demos/demo_task_apps/math/app.py,sha256=gNopoAhwM0vzdKuCa7AwQqSwiV2xagr
30
30
  synth_ai/demos/demo_task_apps/math/config.toml,sha256=Kxrzuyj7Az5mvzXaipPIyngKTDqphohf6uSWOHCF5cw,2105
31
31
  synth_ai/demos/demo_task_apps/math/deploy_modal.py,sha256=O4745sFuGEZTsygl-mz6ZOFJ7mog8CquXMgMyjFKr_c,2288
32
32
  synth_ai/demos/demo_task_apps/math/deploy_task_app.sh,sha256=qVffbAmsiCAxzFDzcxNVF4f7yyLWnmqPc1cNydHT5BQ,791
33
- synth_ai/demos/demo_task_apps/math/modal_task_app.py,sha256=DcjhzNj6hwaY4Me-kJPiGKPoVED9eW4dHoaPeMD4vzQ,18808
33
+ synth_ai/demos/demo_task_apps/math/modal_task_app.py,sha256=PE6LtRmz-56nbMT0tCInSr5IRUIpq-jVOrhZMTmMna4,19026
34
34
  synth_ai/environments/__init__.py,sha256=BQW0Nc_BFQq_N-pcqTyJVjW56kSEXu7XZyaSer-U95Q,1032
35
35
  synth_ai/environments/environment/__init__.py,sha256=EBol9AKxPTIPXWcbH9Tja-l3yL-N2kB8e5atyf6F66c,31
36
36
  synth_ai/environments/environment/core.py,sha256=0jd0CZ88_s_qqA3d1lOgVsnv-ucw_1lJDAIUj1gTSt0,2201
@@ -412,9 +412,9 @@ synth_ai/v0/tracing_v1/events/manage.py,sha256=ZDXXP-ZwLH9LCsmw7Ru9o55d7bl_diPtJ
412
412
  synth_ai/v0/tracing_v1/events/scope.py,sha256=BuBkhSpVHUJt8iGT9HJZF82rbb88mQcd2vM2shg-w2I,2550
413
413
  synth_ai/v0/tracing_v1/events/store.py,sha256=0342lvAcalyJbVEIzQFaPuMQGgwiFm7M5rE6gr-G0E8,9041
414
414
  synth_ai/zyk/__init__.py,sha256=htVLnzTYQ5rxzYpzSYBm7_o6uNKZ3pB_PrqkBrgTRS4,771
415
- synth_ai-0.2.7.dist-info/licenses/LICENSE,sha256=ynhjRQUfqA_RdGRATApfFA_fBAy9cno04sLtLUqxVFM,1069
416
- synth_ai-0.2.7.dist-info/METADATA,sha256=o6GogGqKFEH-uw0VOTIm-8crmH3udRYY8PdRpJA02ko,4975
417
- synth_ai-0.2.7.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
418
- synth_ai-0.2.7.dist-info/entry_points.txt,sha256=Neq-3bT7TAijjgOIR77pKL-WYg6TWBDeO8pp_nL4vGY,91
419
- synth_ai-0.2.7.dist-info/top_level.txt,sha256=fBmtZyVHuKaGa29oHBaaUkrUIWTqSpoVMPiVdCDP3k8,9
420
- synth_ai-0.2.7.dist-info/RECORD,,
415
+ synth_ai-0.2.8.dist-info/licenses/LICENSE,sha256=ynhjRQUfqA_RdGRATApfFA_fBAy9cno04sLtLUqxVFM,1069
416
+ synth_ai-0.2.8.dist-info/METADATA,sha256=CONkZBD93vN0PXM1Kua4b6cDFa8tV8sFg3VYGe-TAHo,5147
417
+ synth_ai-0.2.8.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
418
+ synth_ai-0.2.8.dist-info/entry_points.txt,sha256=Neq-3bT7TAijjgOIR77pKL-WYg6TWBDeO8pp_nL4vGY,91
419
+ synth_ai-0.2.8.dist-info/top_level.txt,sha256=fBmtZyVHuKaGa29oHBaaUkrUIWTqSpoVMPiVdCDP3k8,9
420
+ synth_ai-0.2.8.dist-info/RECORD,,