synth-ai 0.2.6.dev6__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.

@@ -294,22 +294,32 @@ def load_env() -> DemoEnv:
294
294
  env.task_app_name = task_app_name
295
295
  env.task_app_secret_name = task_app_secret_name
296
296
 
297
- print("ENV:")
298
- print(f" DEV_BACKEND_URL={env.dev_backend_url}")
299
- print(f" SYNTH_API_KEY={_mask(env.synth_api_key)}")
300
- print(f" ENVIRONMENT_API_KEY={_mask(env.env_api_key)}")
301
- print(f" TASK_APP_BASE_URL={env.task_app_base_url}")
302
- if task_app_name:
303
- print(f" TASK_APP_NAME={task_app_name}")
304
- if task_app_secret_name:
305
- print(f" TASK_APP_SECRET_NAME={task_app_secret_name}")
297
+ # Suppress environment echo by default for cleaner CLI output.
298
+ # If needed for debugging, set SYNTH_CLI_VERBOSE=1 to print resolved values.
299
+ if os.getenv("SYNTH_CLI_VERBOSE", "0") == "1":
300
+ print("ENV:")
301
+ print(f" DEV_BACKEND_URL={env.dev_backend_url}")
302
+ print(f" SYNTH_API_KEY={_mask(env.synth_api_key)}")
303
+ print(f" ENVIRONMENT_API_KEY={_mask(env.env_api_key)}")
304
+ print(f" TASK_APP_BASE_URL={env.task_app_base_url}")
305
+ if task_app_name:
306
+ print(f" TASK_APP_NAME={task_app_name}")
307
+ if task_app_secret_name:
308
+ print(f" TASK_APP_SECRET_NAME={task_app_secret_name}")
306
309
  return env
307
310
 
308
311
 
309
312
  def assert_http_ok(url: str, method: str = "GET", allow_redirects: bool = True, timeout: float = 10.0) -> bool:
310
313
  try:
314
+ import ssl
315
+
311
316
  req = urllib.request.Request(url, method=method)
312
- with urllib.request.urlopen(req, timeout=timeout) as resp: # nosec - controlled URL
317
+ # Default: disable SSL verification for local/dev convenience.
318
+ # Set SYNTH_SSL_VERIFY=1 to enable verification.
319
+ ctx = ssl._create_unverified_context() # nosec: disabled by default for dev
320
+ if os.getenv("SYNTH_SSL_VERIFY", "0") == "1":
321
+ ctx = None
322
+ with urllib.request.urlopen(req, timeout=timeout, context=ctx) as resp: # nosec - controlled URL
313
323
  code = getattr(resp, "status", 200)
314
324
  return 200 <= int(code) < 400
315
325
  except Exception:
@@ -2,43 +2,128 @@
2
2
  name = "Qwen/Qwen3-0.6B"
3
3
  dtype = "bfloat16"
4
4
  seed = 42
5
+ trainer_mode = "full"
6
+
7
+ [lora]
8
+ r = 16
9
+ alpha = 32
10
+ dropout = 0.05
11
+ target_modules = [
12
+ "q_proj", "k_proj", "v_proj", "o_proj",
13
+ "gate_proj", "up_proj", "down_proj",
14
+ ]
15
+
16
+ [rdma]
17
+ enabled = false
18
+ ifname = "eth0"
19
+ ip_type = "ipv4"
20
+ p2p_disable = 0
21
+ shm_disable = 0
22
+ fast_nccl = false
23
+
24
+ gid_index = 3
25
+ cross_nic = 0
26
+ collnet_enable = 0
27
+ net_gdr_level = 2
28
+
29
+ nsocks_perthread = 4
30
+ socket_nthreads = 2
31
+
32
+ algo = "Ring"
33
+ proto = "Simple"
34
+ p2p_level = "SYS"
35
+ debug = "INFO"
5
36
 
6
37
  [reference]
7
38
  placement = "dedicated"
39
+ gpu_index = 1
8
40
  port = 8002
41
+ tp = 1
42
+ health_max_wait_s = 180
43
+ health_interval_ms = 300
9
44
 
10
45
  [topology]
11
46
  type = "single_node_split"
12
- gpus_for_vllm = 1
47
+ gpu_type = "H100:4"
48
+ use_rdma = false
49
+ gpus_for_vllm = 2
13
50
  gpus_for_training = 1
14
51
  gpus_for_ref = 1
52
+ tensor_parallel = 2
15
53
 
16
54
  [training]
17
- num_epochs = 5
18
- iterations_per_epoch = 1
19
- batch_size = 4
20
- group_size = 16
55
+ num_epochs = 1
56
+ iterations_per_epoch = 2
57
+ batch_size = 1
58
+ group_size = 8
21
59
  learning_rate = 5e-6
22
60
  max_grad_norm = 0.5
23
61
  log_interval = 1
24
62
  update_reference_interval = 0
25
63
  weight_sync_interval = 1
26
64
 
65
+ [training.weight_sync]
66
+ enable = true
67
+ targets = ["policy"]
68
+
69
+ [vllm]
70
+ tensor_parallel_size = 2
71
+ gpu_memory_utilization = 0.9
72
+ max_model_len = 8192
73
+ max_num_seqs = 32
74
+ enforce_eager = false
75
+ max_parallel_generations = 4
76
+
27
77
  [evaluation]
28
- seeds = [0, 1, 2, 3]
78
+ seeds = [0, 1, 2, 3, 4, 5, 6, 7]
29
79
  rollouts_per_seed = 1
30
- instances = 1
80
+ instances = 0
31
81
  max_concurrent_rollouts = 4
32
- thinking_mode = "none"
33
- every_n_iters = 2
82
+ thinking_mode = "think"
83
+ every_n_iters = 5
34
84
 
35
85
  [rollout]
36
86
  env_name = "math"
37
87
  policy_name = "math-react"
38
- max_steps_per_episode = 1
88
+ env_config = {}
89
+ max_steps_per_episode = 5
39
90
  sampling_temperature = 0.3
40
91
  sampling_top_p = 0.95
41
- max_tokens = 256
42
- max_concurrent_rollouts = 8
43
- ops_per_rollout = 2
92
+ max_tokens = 1024
93
+ max_concurrent_rollouts = 4
94
+ ops_per_rollout = 14
44
95
  on_done = "reset"
96
+ thinking_mode = "think"
97
+ thinking_budget = 512
98
+
99
+ [policy]
100
+ config = {}
101
+
102
+ [hyperparams]
103
+ epsilon_low = 0.1
104
+ epsilon_high = 0.3
105
+ delta = 5.0
106
+ beta = 0.01
107
+ kl_penalty = 0.01
108
+ advantage_normalization = true
109
+ group_normalization = true
110
+ num_inner_steps = 1
111
+ clip_epsilon = 0.2
112
+ completion_only = false
113
+
114
+ [step_rewards]
115
+ enabled = false
116
+ mode = "off"
117
+ step_beta = 0.0
118
+ indicator_lambda = 0.0
119
+
120
+ [trainer]
121
+ allow_ref_fallback = false
122
+
123
+ [checkpoint]
124
+ interval = 10
125
+ directory = "/checkpoints"
126
+ keep_last_n = 3
127
+ save_optimizer = true
128
+ save_scheduler = true
129
+ enabled = true
@@ -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 ADDED
@@ -0,0 +1,107 @@
1
+ from __future__ import annotations
2
+ import os
3
+ import time
4
+ import webbrowser
5
+ from typing import Any, Dict, Tuple
6
+ from urllib.parse import urljoin, urlsplit, urlunsplit
7
+
8
+ import requests
9
+
10
+
11
+ class HandshakeError(Exception):
12
+ pass
13
+
14
+
15
+ _TRUTHY = {"1", "true", "yes", "on"}
16
+
17
+
18
+ def _origin() -> str:
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("/"))
53
+
54
+
55
+ def start_handshake_session(origin: str | None = None) -> Tuple[str, str, int, int]:
56
+ base = (origin or _origin()).rstrip("/")
57
+ api_origin, _ = _split_origin(base)
58
+ url = urljoin(api_origin.rstrip("/") + "/", "api/sdk/handshake/init")
59
+ r = requests.post(url, timeout=10)
60
+ if r.status_code != 200:
61
+ raise HandshakeError(f"init failed: {r.status_code} {r.text}")
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)
67
+ return (
68
+ str(data.get("device_code")),
69
+ str(data.get("verification_uri")),
70
+ int(data.get("expires_in", 600)),
71
+ int(data.get("interval", 3)),
72
+ )
73
+
74
+
75
+ def poll_handshake_token(device_code: str, origin: str | None = None, *, timeout_s: int | None = None) -> Dict[str, Any]:
76
+ base = (origin or _origin()).rstrip("/")
77
+ api_origin, _ = _split_origin(base)
78
+ url = urljoin(api_origin.rstrip("/") + "/", "api/sdk/handshake/token")
79
+ deadline = time.time() + (timeout_s or 600)
80
+ while True:
81
+ if time.time() > deadline:
82
+ raise HandshakeError("handshake timed out")
83
+ try:
84
+ r = requests.post(url, json={"device_code": device_code}, timeout=10)
85
+ except Exception as e:
86
+ time.sleep(2)
87
+ continue
88
+ if r.status_code == 200:
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
95
+ elif r.status_code in (404, 410):
96
+ raise HandshakeError(f"handshake failed: {r.status_code}")
97
+ # 428 authorization_pending or others → wait and retry
98
+ time.sleep(2)
99
+
100
+
101
+ def run_handshake(origin: str | None = None) -> Dict[str, Any]:
102
+ device_code, verification_uri, expires_in, interval = start_handshake_session(origin)
103
+ try:
104
+ webbrowser.open(verification_uri)
105
+ except Exception:
106
+ pass
107
+ return poll_handshake_token(device_code, origin, timeout_s=expires_in)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: synth-ai
3
- Version: 0.2.6.dev6
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
@@ -14,6 +14,7 @@ Requires-Dist: pydantic>=2.0.0
14
14
  Requires-Dist: python-dotenv>=1.0.1
15
15
  Requires-Dist: requests>=2.32.3
16
16
  Requires-Dist: urllib3>=2.3.0
17
+ Requires-Dist: certifi>=2024.8.30
17
18
  Requires-Dist: tqdm>=4.66.4
18
19
  Requires-Dist: jsonschema>=4.23.0
19
20
  Requires-Dist: backoff>=2.0.0
@@ -52,7 +53,7 @@ Requires-Dist: asyncpg>=0.30.0
52
53
  Requires-Dist: aiohttp>=3.8.0
53
54
  Requires-Dist: datasets>=4.0.0
54
55
  Requires-Dist: transformers>=4.56.1
55
- Requires-Dist: modal>=1.1.4
56
+ Requires-Dist: modal>=1.1.0
56
57
  Provides-Extra: dev
57
58
  Requires-Dist: build>=1.2.2.post1; extra == "dev"
58
59
  Requires-Dist: twine>=4.0.0; extra == "dev"
@@ -97,10 +98,33 @@ synth-ai comes with a built-in RL example tailored for training Qwen/Qwen3-0.6B
97
98
  Please create an account at [Synth](https://usesynth.ai) and [Modal](https://modal.com) for the Math hello‑world test run. Then run:
98
99
 
99
100
  ```bash
100
- uvx synth-ai rl_demo check
101
- uvx synth-ai rl_demo deploy
102
- uvx synth-ai rl_demo configure
103
- uvx synth-ai rl_demo run
101
+ uvx synth-ai demo
102
+ uvx synth-ai setup
103
+ uvx synth-ai deploy
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).
108
+
109
+ ### What `setup` does now
110
+
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:
112
+
113
+ - Detect your current user and organization
114
+ - Ensure both API keys exist for that user+org
115
+ - Write the keys to your project’s `.env` file as `SYNTH_API_KEY` and `ENVIRONMENT_API_KEY`
116
+
117
+ No keys are printed or requested interactively. You’ll see a confirmation like:
118
+
119
+ ```
120
+ Connecting SDK to your browser session…
121
+ Connected to Acme Labs via browser.
122
+ ```
123
+
124
+ If your browser isn’t already signed in, sign in when prompted and the pairing completes automatically. The dashboard’s welcome modal will reflect a successful pairing.
125
+
126
+ Environment variables:
127
+
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`.
130
+ - Keys are stored only in your project’s `.env` file, not exported to your shell.
@@ -1,17 +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=uzoTOpkf9JQgsyKWrlx8gjfQmK3HpqFQAZY1gZDtiIo,3735
3
4
  synth_ai/http.py,sha256=lqjFXDmAP_xgfywK_rDSOVxuMy4rDH9S3Rtu9k1tLmk,1028
4
5
  synth_ai/http_client.py,sha256=_9J8rUGoItUMnJLGZw7r0uXiJeLWR939kByRkvtP1XM,4429
5
6
  synth_ai/install_sqld.sh,sha256=AMBhlfq661PxeTTc6D4K_Nei_qwMvA84ei4NhQzmUUk,928
6
7
  synth_ai/cli/__init__.py,sha256=ThBK5FykxAqX8Mz0E4gj94_PX9EwMEtXcmm-A8krv7E,1559
7
8
  synth_ai/cli/balance.py,sha256=z4h1MQSyFX60k-13L9IT0rtOCI16iKNGJeNjFMZuv_k,8010
8
9
  synth_ai/cli/calc.py,sha256=RJyQJ41e02xn-V0vRRCAVkL59UHDqyz8XpYGsenfdm4,2085
9
- synth_ai/cli/demo.py,sha256=GNVBxVtscxfAITFObyTOK8XPP2WGb-pv9LL4CiV_g6Q,4843
10
+ synth_ai/cli/demo.py,sha256=NeRiLv9ZQyX9tVxvZ6uV5YmucQ8fu5gyL5qZE0GfBZY,5496
10
11
  synth_ai/cli/legacy_root_backup.py,sha256=KSMADyJ2g5OVpsq_CeBzqIeDC2Um-9GyINzsJH-75uw,15872
11
12
  synth_ai/cli/man.py,sha256=JQDon73ZkuKP9xr1_vRh5fjV9_b5xiUb7zNjny7ArB8,3765
12
13
  synth_ai/cli/recent.py,sha256=mHhM-QrR_MfjfKSzBvvPUEC-lkXTWUZrQwqYTmb2x0Y,4173
13
- synth_ai/cli/rl_demo.py,sha256=thFzIlOIXqJ_kFwaek0JMjaCH_Jq5Lpp2nOZ3A3t-3k,5980
14
- synth_ai/cli/root.py,sha256=YAr7H2WYfnRt6_yxLix9O01-UnSy7OtYBVyNy4l5xIo,9614
14
+ synth_ai/cli/rl_demo.py,sha256=HAZqHaGFKAu7yXtjglmmNcHp4js77wCYSpa2WTcjyUE,8050
15
+ synth_ai/cli/root.py,sha256=C5eA3fuzyL6fpSDT7pRk4kT0BOAmdfS6SkaH3LgYTAY,9867
15
16
  synth_ai/cli/status.py,sha256=M_bt7U58Ubi-q-ZlrIpgCASKq9_k6uMjpx926f6kLLA,4591
16
17
  synth_ai/cli/traces.py,sha256=_QBdCR92u0Gv51U4DH0Ws1d5yCrbJRpaYKe7pmcHrHs,6484
17
18
  synth_ai/cli/watch.py,sha256=HBKbAcpUkkPhGvsPRofckbu8oILiVqp35NXHkIEpTTc,17808
@@ -20,16 +21,16 @@ synth_ai/config/base_url.py,sha256=c85LaABBrvsl8Fp8KH0LNtJJrpnUwlzA5Ywbuth8fHE,3
20
21
  synth_ai/core/experiment.py,sha256=hLkPtzUFA7iY3-QpeJ5K8YjvQeyfqnjab5P2CFaojys,236
21
22
  synth_ai/core/system.py,sha256=s-Z7np2ISYmYc1r9YN-y2yb3cgRlOalrh0iaqnxeo84,206
22
23
  synth_ai/demos/core/__init__.py,sha256=A2FjhY7KXGtyzdQXqeTPCkEhHfrH-eQg6bvP8HaYhZM,36
23
- synth_ai/demos/core/cli.py,sha256=MuJELXFRxtyucek9b05Oo54pmJs5QGo45SV3hDZTFO0,44729
24
+ synth_ai/demos/core/cli.py,sha256=lwkW1j638pOaLpmo6vPtDvEjsWdtLDCTwjbHoSHOdA8,56220
24
25
  synth_ai/demos/demo_task_apps/__init__.py,sha256=8aUGEGpWUw11GRb3wQXRAmQ99yjAt5qd5FCTDJpXWjI,44
25
- synth_ai/demos/demo_task_apps/core.py,sha256=RsPRA_4p97_h0im33C-eJr2hryRFNdj54Zd9bdBcDsw,14005
26
+ synth_ai/demos/demo_task_apps/core.py,sha256=ifKxxRKqC-y43MaqLHNuerXAlBHO8MI8ZBo2CzYcOoU,14563
26
27
  synth_ai/demos/demo_task_apps/math/__init__.py,sha256=WBzpZwSn7pRarBmhopQi34i9bEm05-71eM3siboOavY,43
27
28
  synth_ai/demos/demo_task_apps/math/_common.py,sha256=SgtVW1pne4pgwGS2gYYQWkmG9BvU2sQTYzlncmUJ0NM,533
28
29
  synth_ai/demos/demo_task_apps/math/app.py,sha256=gNopoAhwM0vzdKuCa7AwQqSwiV2xagrjMxMH9YIniv4,1160
29
- synth_ai/demos/demo_task_apps/math/config.toml,sha256=atyeLq8tJsm4BST2NwlKUMum5D_gxEAWBqYsQGLQimI,757
30
+ synth_ai/demos/demo_task_apps/math/config.toml,sha256=Kxrzuyj7Az5mvzXaipPIyngKTDqphohf6uSWOHCF5cw,2105
30
31
  synth_ai/demos/demo_task_apps/math/deploy_modal.py,sha256=O4745sFuGEZTsygl-mz6ZOFJ7mog8CquXMgMyjFKr_c,2288
31
32
  synth_ai/demos/demo_task_apps/math/deploy_task_app.sh,sha256=qVffbAmsiCAxzFDzcxNVF4f7yyLWnmqPc1cNydHT5BQ,791
32
- 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
33
34
  synth_ai/environments/__init__.py,sha256=BQW0Nc_BFQq_N-pcqTyJVjW56kSEXu7XZyaSer-U95Q,1032
34
35
  synth_ai/environments/environment/__init__.py,sha256=EBol9AKxPTIPXWcbH9Tja-l3yL-N2kB8e5atyf6F66c,31
35
36
  synth_ai/environments/environment/core.py,sha256=0jd0CZ88_s_qqA3d1lOgVsnv-ucw_1lJDAIUj1gTSt0,2201
@@ -411,9 +412,9 @@ synth_ai/v0/tracing_v1/events/manage.py,sha256=ZDXXP-ZwLH9LCsmw7Ru9o55d7bl_diPtJ
411
412
  synth_ai/v0/tracing_v1/events/scope.py,sha256=BuBkhSpVHUJt8iGT9HJZF82rbb88mQcd2vM2shg-w2I,2550
412
413
  synth_ai/v0/tracing_v1/events/store.py,sha256=0342lvAcalyJbVEIzQFaPuMQGgwiFm7M5rE6gr-G0E8,9041
413
414
  synth_ai/zyk/__init__.py,sha256=htVLnzTYQ5rxzYpzSYBm7_o6uNKZ3pB_PrqkBrgTRS4,771
414
- synth_ai-0.2.6.dev6.dist-info/licenses/LICENSE,sha256=ynhjRQUfqA_RdGRATApfFA_fBAy9cno04sLtLUqxVFM,1069
415
- synth_ai-0.2.6.dev6.dist-info/METADATA,sha256=DTrV1I4ushAH4IrpGgfn1qCvmsqEAXlZbxdHjT1lHFw,3980
416
- synth_ai-0.2.6.dev6.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
417
- synth_ai-0.2.6.dev6.dist-info/entry_points.txt,sha256=Neq-3bT7TAijjgOIR77pKL-WYg6TWBDeO8pp_nL4vGY,91
418
- synth_ai-0.2.6.dev6.dist-info/top_level.txt,sha256=fBmtZyVHuKaGa29oHBaaUkrUIWTqSpoVMPiVdCDP3k8,9
419
- synth_ai-0.2.6.dev6.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,,