synth-ai 0.2.6.dev6__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/demo.py +11 -3
- 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.7.dist-info}/METADATA +26 -4
- {synth_ai-0.2.6.dev6.dist-info → synth_ai-0.2.7.dist-info}/RECORD +13 -12
- {synth_ai-0.2.6.dev6.dist-info → synth_ai-0.2.7.dist-info}/WHEEL +0 -0
- {synth_ai-0.2.6.dev6.dist-info → synth_ai-0.2.7.dist-info}/entry_points.txt +0 -0
- {synth_ai-0.2.6.dev6.dist-info → synth_ai-0.2.7.dist-info}/licenses/LICENSE +0 -0
- {synth_ai-0.2.6.dev6.dist-info → synth_ai-0.2.7.dist-info}/top_level.txt +0 -0
|
@@ -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
|
-
|
|
298
|
-
print
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
print(f"
|
|
304
|
-
|
|
305
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
18
|
-
iterations_per_epoch =
|
|
19
|
-
batch_size =
|
|
20
|
-
group_size =
|
|
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 =
|
|
80
|
+
instances = 0
|
|
31
81
|
max_concurrent_rollouts = 4
|
|
32
|
-
thinking_mode = "
|
|
33
|
-
every_n_iters =
|
|
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
|
-
|
|
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 =
|
|
42
|
-
max_concurrent_rollouts =
|
|
43
|
-
ops_per_rollout =
|
|
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
|
synth_ai/handshake.py
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
import os
|
|
5
|
+
import time
|
|
6
|
+
import webbrowser
|
|
7
|
+
from typing import Any, Dict, Tuple
|
|
8
|
+
|
|
9
|
+
import requests
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class HandshakeError(Exception):
|
|
13
|
+
pass
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def _origin() -> str:
|
|
17
|
+
# Prefer explicit env; fallback to localhost dashboard
|
|
18
|
+
return (os.getenv("SYNTH_CANONICAL_ORIGIN", "") or "http://localhost:3000").rstrip("/")
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def start_handshake_session(origin: str | None = None) -> Tuple[str, str, int, int]:
|
|
22
|
+
base = (origin or _origin()).rstrip("/")
|
|
23
|
+
url = f"{base}/api/sdk/handshake/init"
|
|
24
|
+
r = requests.post(url, timeout=10)
|
|
25
|
+
if r.status_code != 200:
|
|
26
|
+
raise HandshakeError(f"init failed: {r.status_code} {r.text}")
|
|
27
|
+
data = r.json()
|
|
28
|
+
return (
|
|
29
|
+
str(data.get("device_code")),
|
|
30
|
+
str(data.get("verification_uri")),
|
|
31
|
+
int(data.get("expires_in", 600)),
|
|
32
|
+
int(data.get("interval", 3)),
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def poll_handshake_token(device_code: str, origin: str | None = None, *, timeout_s: int | None = None) -> Dict[str, Any]:
|
|
37
|
+
base = (origin or _origin()).rstrip("/")
|
|
38
|
+
url = f"{base}/api/sdk/handshake/token"
|
|
39
|
+
deadline = time.time() + (timeout_s or 600)
|
|
40
|
+
while True:
|
|
41
|
+
if time.time() > deadline:
|
|
42
|
+
raise HandshakeError("handshake timed out")
|
|
43
|
+
try:
|
|
44
|
+
r = requests.post(url, json={"device_code": device_code}, timeout=10)
|
|
45
|
+
except Exception as e:
|
|
46
|
+
time.sleep(2)
|
|
47
|
+
continue
|
|
48
|
+
if r.status_code == 200:
|
|
49
|
+
return r.json()
|
|
50
|
+
elif r.status_code in (404, 410):
|
|
51
|
+
raise HandshakeError(f"handshake failed: {r.status_code}")
|
|
52
|
+
# 428 authorization_pending or others → wait and retry
|
|
53
|
+
time.sleep(2)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def run_handshake(origin: str | None = None) -> Dict[str, Any]:
|
|
57
|
+
device_code, verification_uri, expires_in, interval = start_handshake_session(origin)
|
|
58
|
+
try:
|
|
59
|
+
webbrowser.open(verification_uri)
|
|
60
|
+
except Exception:
|
|
61
|
+
pass
|
|
62
|
+
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.
|
|
3
|
+
Version: 0.2.7
|
|
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
|
|
@@ -97,10 +98,31 @@ 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
|
|
101
|
+
uvx synth-ai rl_demo setup
|
|
101
102
|
uvx synth-ai rl_demo deploy
|
|
102
|
-
uvx synth-ai
|
|
103
|
-
uvx synth-ai rl_demo run
|
|
103
|
+
uvx synth-ai run
|
|
104
104
|
```
|
|
105
105
|
|
|
106
106
|
To walk through kicking off your first RL run, see the [Synth‑AI Documentation](https://docs.usesynth.ai/synth-ai/introduction).
|
|
107
|
+
|
|
108
|
+
### What `rl_demo setup` does now
|
|
109
|
+
|
|
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
|
+
|
|
112
|
+
- Detect your current user and organization
|
|
113
|
+
- Ensure both API keys exist for that user+org
|
|
114
|
+
- Write the keys to your project’s `.env` file as `SYNTH_API_KEY` and `ENVIRONMENT_API_KEY`
|
|
115
|
+
|
|
116
|
+
No keys are printed or requested interactively. You’ll see a confirmation like:
|
|
117
|
+
|
|
118
|
+
```
|
|
119
|
+
Connecting SDK to your browser session…
|
|
120
|
+
Connected to Acme Labs via browser.
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
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.
|
|
124
|
+
|
|
125
|
+
Environment variables:
|
|
126
|
+
|
|
127
|
+
- `SYNTH_CANONICAL_ORIGIN` (optional): override the dashboard base URL the SDK uses for the handshake (defaults to `http://localhost:3000`).
|
|
128
|
+
- 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=AJR0GFFAkdAga8CXRLYbQl90-s0AQzTGxy5tQzPQb0E,1994
|
|
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=
|
|
10
|
+
synth_ai/cli/demo.py,sha256=YGZhmCE0XLLP31OdsdGceTL6oFHmzyOc0CO-Crl54W0,5064
|
|
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=
|
|
14
|
-
synth_ai/cli/root.py,sha256=
|
|
14
|
+
synth_ai/cli/rl_demo.py,sha256=HAZqHaGFKAu7yXtjglmmNcHp4js77wCYSpa2WTcjyUE,8050
|
|
15
|
+
synth_ai/cli/root.py,sha256=7YgAxsefqscE4QEaa3kuKqBnaHbQLa4ZyXJ5l8eVl7Y,9741
|
|
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,13 +21,13 @@ 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=
|
|
24
|
+
synth_ai/demos/core/cli.py,sha256=KkIm7nhKxHN26UQAjh-5wW-y__Z481UR23JmFl2GpM4,56329
|
|
24
25
|
synth_ai/demos/demo_task_apps/__init__.py,sha256=8aUGEGpWUw11GRb3wQXRAmQ99yjAt5qd5FCTDJpXWjI,44
|
|
25
|
-
synth_ai/demos/demo_task_apps/core.py,sha256=
|
|
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=
|
|
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
33
|
synth_ai/demos/demo_task_apps/math/modal_task_app.py,sha256=DcjhzNj6hwaY4Me-kJPiGKPoVED9eW4dHoaPeMD4vzQ,18808
|
|
@@ -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.
|
|
415
|
-
synth_ai-0.2.
|
|
416
|
-
synth_ai-0.2.
|
|
417
|
-
synth_ai-0.2.
|
|
418
|
-
synth_ai-0.2.
|
|
419
|
-
synth_ai-0.2.
|
|
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,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|