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.
@@ -10,6 +10,8 @@ from typing import Any, Dict, Optional, Tuple
10
10
 
11
11
  import urllib.request
12
12
 
13
+ from synth_ai.config.base_url import PROD_BASE_URL_DEFAULT
14
+
13
15
 
14
16
  @dataclass
15
17
  class DemoEnv:
@@ -169,7 +171,7 @@ def load_env() -> DemoEnv:
169
171
  Backend URL:
170
172
  - Use BACKEND_OVERRIDE (any) from CWD .env if set
171
173
  - Else use DEV_BACKEND_URL from CWD .env ONLY if it's localhost/127.0.0.1 or :8000
172
- - Else default to prod https://agent-learning.onrender.com/api
174
+ - Else default to production backend (PROD_BASE_URL_DEFAULT)
173
175
 
174
176
  API keys:
175
177
  - SYNTH_API_KEY from OS -> CWD .env -> repo .env -> pkg demo .env -> state
@@ -194,9 +196,25 @@ def load_env() -> DemoEnv:
194
196
 
195
197
  state = _read_state()
196
198
 
199
+ default_root = PROD_BASE_URL_DEFAULT.rstrip("/")
200
+ prod_default = f"{default_root}/api"
201
+
197
202
  # Backend URL resolution
198
- backend_override = (cwd_env.get("BACKEND_OVERRIDE") or "").strip()
199
- dev_env = (cwd_env.get("DEV_BACKEND_URL") or "").strip()
203
+ backend_override = (
204
+ os_env.get("BACKEND_OVERRIDE")
205
+ or cwd_env.get("BACKEND_OVERRIDE")
206
+ or repo_env.get("BACKEND_OVERRIDE")
207
+ or pkg_env.get("BACKEND_OVERRIDE")
208
+ or examples_env.get("BACKEND_OVERRIDE")
209
+ or ""
210
+ ).strip()
211
+ dev_env = (
212
+ os_env.get("DEV_BACKEND_URL")
213
+ or cwd_env.get("DEV_BACKEND_URL")
214
+ or repo_env.get("DEV_BACKEND_URL")
215
+ or pkg_env.get("DEV_BACKEND_URL")
216
+ or ""
217
+ ).strip()
200
218
  use_dev = False
201
219
  if backend_override:
202
220
  dev_url = backend_override
@@ -207,9 +225,9 @@ def load_env() -> DemoEnv:
207
225
  dev_url = dev_env
208
226
  use_dev = True
209
227
  else:
210
- dev_url = "https://agent-learning.onrender.com/api"
228
+ dev_url = prod_default
211
229
  else:
212
- dev_url = "https://agent-learning.onrender.com/api"
230
+ dev_url = prod_default
213
231
  if not dev_url.endswith("/api"):
214
232
  dev_url = dev_url.rstrip("/") + "/api"
215
233
 
@@ -222,7 +240,7 @@ def load_env() -> DemoEnv:
222
240
  or str(state.get("SYNTH_API_KEY") or "")
223
241
  )
224
242
  if not synth_api_key:
225
- mode = "prod" if "agent-learning.onrender.com" in dev_url else ("local" if ("localhost" in dev_url or "127.0.0.1" in dev_url) else "dev")
243
+ mode = "prod" if default_root in dev_url else ("local" if ("localhost" in dev_url or "127.0.0.1" in dev_url) else "dev")
226
244
  if mode == "prod":
227
245
  synth_api_key = (
228
246
  os_env.get("PROD_SYNTH_API_KEY")
@@ -276,22 +294,32 @@ def load_env() -> DemoEnv:
276
294
  env.task_app_name = task_app_name
277
295
  env.task_app_secret_name = task_app_secret_name
278
296
 
279
- print("ENV:")
280
- print(f" DEV_BACKEND_URL={env.dev_backend_url}")
281
- print(f" SYNTH_API_KEY={_mask(env.synth_api_key)}")
282
- print(f" ENVIRONMENT_API_KEY={_mask(env.env_api_key)}")
283
- print(f" TASK_APP_BASE_URL={env.task_app_base_url}")
284
- if task_app_name:
285
- print(f" TASK_APP_NAME={task_app_name}")
286
- if task_app_secret_name:
287
- 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}")
288
309
  return env
289
310
 
290
311
 
291
312
  def assert_http_ok(url: str, method: str = "GET", allow_redirects: bool = True, timeout: float = 10.0) -> bool:
292
313
  try:
314
+ import ssl
315
+
293
316
  req = urllib.request.Request(url, method=method)
294
- 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
295
323
  code = getattr(resp, "status", 200)
296
324
  return 200 <= int(code) < 400
297
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
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
+
@@ -15,6 +15,7 @@ import pydantic_core
15
15
  # from openai import AsyncOpenAI, OpenAI
16
16
  from pydantic import BaseModel
17
17
 
18
+ from synth_ai.config.base_url import PROD_BASE_URL_DEFAULT
18
19
  from synth_ai.lm.caching.initialize import get_cache_handler
19
20
  from synth_ai.lm.constants import OPENAI_REASONING_MODELS, SPECIAL_BASE_TEMPS
20
21
  from synth_ai.lm.tools.base import BaseTool
@@ -45,9 +46,13 @@ class OpenAIStructuredOutputClient(OpenAIStandard):
45
46
  def __init__(self, synth_logging: bool = True):
46
47
  # Check if we should use Synth clients instead of OpenAI
47
48
  openai_base = os.getenv("OPENAI_API_BASE", "")
48
- use_synth = (openai_base.startswith("https://synth") or
49
- openai_base.startswith("https://agent-learning") or
50
- os.getenv("SYNTH_BASE_URL") or os.getenv("MODAL_BASE_URL"))
49
+ prod_prefix = PROD_BASE_URL_DEFAULT.rstrip("/")
50
+ use_synth = (
51
+ openai_base.startswith("https://synth")
52
+ or (prod_prefix and openai_base.startswith(prod_prefix))
53
+ or os.getenv("SYNTH_BASE_URL")
54
+ or os.getenv("MODAL_BASE_URL")
55
+ )
51
56
 
52
57
  if use_synth:
53
58
  # Use Synth clients for Synth endpoints
@@ -12,6 +12,8 @@ from opentelemetry.sdk.trace.export import (
12
12
  )
13
13
  from pydantic import BaseModel, ConfigDict, Field
14
14
 
15
+ from synth_ai.config.base_url import PROD_BASE_URL_DEFAULT
16
+
15
17
 
16
18
  class InMemoryExporter(SpanExporter):
17
19
  def __init__(self):
@@ -101,7 +103,7 @@ class EventManagement(str, Enum):
101
103
  class TracingConfig(BaseModel):
102
104
  mode: LoggingMode = Field(default=LoggingMode.DEFERRED)
103
105
  api_key: str
104
- base_url: str = Field(default="https://agent-learning.onrender.com")
106
+ base_url: str = Field(default=PROD_BASE_URL_DEFAULT)
105
107
  max_retries: int = Field(default=3)
106
108
  retry_backoff: float = Field(default=1.5) # exponential backoff multiplier
107
109
  batch_size: int = Field(default=1) # for future batching support
@@ -10,6 +10,8 @@ from typing import TYPE_CHECKING, Any, Literal, ParamSpec, TypeVar, Union
10
10
  if TYPE_CHECKING:
11
11
  from .trackers import SynthTrackerAsync, SynthTrackerSync
12
12
 
13
+ from synth_ai.config.base_url import PROD_BASE_URL_DEFAULT
14
+
13
15
  from .abstractions import (
14
16
  AgentComputeStep,
15
17
  ArbitraryInputs,
@@ -77,7 +79,7 @@ def get_tracing_config() -> TracingConfig:
77
79
  if os.getenv("SYNTH_LOGGING_MODE") == "instant"
78
80
  else LoggingMode.DEFERRED,
79
81
  api_key=os.getenv("SYNTH_API_KEY", ""),
80
- base_url=os.getenv("SYNTH_ENDPOINT_OVERRIDE", "https://agent-learning.onrender.com"),
82
+ base_url=os.getenv("SYNTH_ENDPOINT_OVERRIDE", PROD_BASE_URL_DEFAULT),
81
83
  )
82
84
  # Initialize retry queue with config if needed
83
85
  initialize_retry_queue(config)
@@ -13,6 +13,8 @@ from pydantic import BaseModel, ConfigDict, field_validator
13
13
  from requests.adapters import HTTPAdapter
14
14
  from urllib3.poolmanager import PoolManager
15
15
 
16
+ from synth_ai.config.base_url import PROD_BASE_URL_DEFAULT
17
+
16
18
  from .abstractions import Dataset, SystemTrace
17
19
  from .events.store import event_store
18
20
 
@@ -369,7 +371,7 @@ def upload_helper(
369
371
  api_key = os.getenv("SYNTH_API_KEY")
370
372
  if not api_key:
371
373
  raise ValueError("SYNTH_API_KEY environment variable not set")
372
- base_url = os.getenv("SYNTH_ENDPOINT_OVERRIDE", "https://agent-learning.onrender.com")
374
+ base_url = os.getenv("SYNTH_ENDPOINT_OVERRIDE", PROD_BASE_URL_DEFAULT)
373
375
 
374
376
  """Legacy block below retained for reference and disabled for linting/parsing.
375
377
  Start disabled block.
@@ -12,6 +12,8 @@ from opentelemetry.sdk.trace.export import (
12
12
  )
13
13
  from pydantic import BaseModel, ConfigDict, Field
14
14
 
15
+ from synth_ai.config.base_url import PROD_BASE_URL_DEFAULT
16
+
15
17
 
16
18
  class InMemoryExporter(SpanExporter):
17
19
  def __init__(self):
@@ -101,7 +103,7 @@ class EventManagement(str, Enum):
101
103
  class TracingConfig(BaseModel):
102
104
  mode: LoggingMode = Field(default=LoggingMode.DEFERRED)
103
105
  api_key: str
104
- base_url: str = Field(default="https://agent-learning.onrender.com")
106
+ base_url: str = Field(default=PROD_BASE_URL_DEFAULT)
105
107
  max_retries: int = Field(default=3)
106
108
  retry_backoff: float = Field(default=1.5) # exponential backoff multiplier
107
109
  batch_size: int = Field(default=1) # for future batching support
@@ -11,6 +11,8 @@ from typing import TYPE_CHECKING, Any, Literal, ParamSpec, TypeVar, Union
11
11
  if TYPE_CHECKING:
12
12
  from .trackers import SynthTrackerAsync, SynthTrackerSync
13
13
 
14
+ from synth_ai.config.base_url import PROD_BASE_URL_DEFAULT
15
+
14
16
  from .abstractions import (
15
17
  AgentComputeStep,
16
18
  ArbitraryInputs,
@@ -78,7 +80,7 @@ def get_tracing_config() -> TracingConfig:
78
80
  if os.getenv("SYNTH_LOGGING_MODE") == "instant"
79
81
  else LoggingMode.DEFERRED,
80
82
  api_key=os.getenv("SYNTH_API_KEY", ""),
81
- base_url=os.getenv("SYNTH_ENDPOINT_OVERRIDE", "https://agent-learning.onrender.com"),
83
+ base_url=os.getenv("SYNTH_ENDPOINT_OVERRIDE", PROD_BASE_URL_DEFAULT),
82
84
  )
83
85
  # Initialize retry queue with config if needed
84
86
  initialize_retry_queue(config)
@@ -13,6 +13,8 @@ from pydantic import BaseModel, ConfigDict, field_validator
13
13
  from requests.adapters import HTTPAdapter
14
14
  from urllib3.poolmanager import PoolManager
15
15
 
16
+ from synth_ai.config.base_url import PROD_BASE_URL_DEFAULT
17
+
16
18
  from .abstractions import Dataset, SystemTrace
17
19
  from .events.store import event_store
18
20
 
@@ -388,7 +390,7 @@ def upload_helper(
388
390
  api_key = os.getenv("SYNTH_API_KEY")
389
391
  if not api_key:
390
392
  raise ValueError("SYNTH_API_KEY environment variable not set")
391
- base_url = os.getenv("SYNTH_ENDPOINT_OVERRIDE", "https://agent-learning.onrender.com")
393
+ base_url = os.getenv("SYNTH_ENDPOINT_OVERRIDE", PROD_BASE_URL_DEFAULT)
392
394
 
393
395
  from .decorators import _local, active_events_var
394
396
  from .trackers import synth_tracker_async
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: synth-ai
3
- Version: 0.2.6.dev5
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 check
101
+ uvx synth-ai rl_demo setup
101
102
  uvx synth-ai rl_demo deploy
102
- uvx synth-ai rl_demo configure
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,32 +1,33 @@
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
- synth_ai/cli/balance.py,sha256=dlxGKCZ2kDeuHMZ5m8n5SHRWW-2CIWs3JcY5xpnWRVA,7798
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=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=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=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
18
19
  synth_ai/compound/cais.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
19
- synth_ai/config/base_url.py,sha256=Bk7Bd9jKJP-LF0SW--WE01JhMfvOB6NUkFMRgPMnJuQ,3101
20
+ synth_ai/config/base_url.py,sha256=c85LaABBrvsl8Fp8KH0LNtJJrpnUwlzA5Ywbuth8fHE,3454
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=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=3-C2dGdaqVqrVjnsxU2n6kGcuaprwuszBcTHePBypwo,13580
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
33
  synth_ai/demos/demo_task_apps/math/modal_task_app.py,sha256=DcjhzNj6hwaY4Me-kJPiGKPoVED9eW4dHoaPeMD4vzQ,18808
@@ -327,7 +328,7 @@ synth_ai/lm/vendors/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZ
327
328
  synth_ai/lm/vendors/core/anthropic_api.py,sha256=mxJVF-uvSUOdbBRMmVfwBFCc7ntV5i_LNE5tQ2AxAbU,14986
328
329
  synth_ai/lm/vendors/core/gemini_api.py,sha256=mHvQtRqoymuzsQDxNFgTDt4HsrgvIuVBSAE29QpRa34,11082
329
330
  synth_ai/lm/vendors/core/mistral_api.py,sha256=4ggRg_4ajzZMBCb-0mHMX_ZTg10tteSfnIPE2NULFag,11875
330
- synth_ai/lm/vendors/core/openai_api.py,sha256=7znI4-yFc0sI5z6eOckd-Ks-IJU66v9gCBzoLjSzY7A,8416
331
+ synth_ai/lm/vendors/core/openai_api.py,sha256=qVl6ZxKrcPwMMEsumFinIPML1I6UO0pt870nsBg64nw,8554
331
332
  synth_ai/lm/vendors/core/synth_dev_api.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
332
333
  synth_ai/lm/vendors/local/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
333
334
  synth_ai/lm/vendors/local/ollama.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -378,15 +379,15 @@ synth_ai/v0/tracing/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSu
378
379
  synth_ai/v0/tracing/abstractions.py,sha256=pL9XCf9UEWdX4IRizzRK9XUNBtDeBYfkVD51F8UOB0s,6898
379
380
  synth_ai/v0/tracing/base_client.py,sha256=IZpyuM-GIClvBBFA9iv4tpOjzY1QHF1m7vkNCYk7xLo,2931
380
381
  synth_ai/v0/tracing/client_manager.py,sha256=rDHpOClkf1t0_6cJecQtr9IaaRmEJOCQ8StaiHyXq1E,4512
381
- synth_ai/v0/tracing/config.py,sha256=Rv_NWeYBFqxNdj_Pp7_EifdZUgFU00d81iE9MPqWU8k,3998
382
+ synth_ai/v0/tracing/config.py,sha256=ZjfJV1jMoJ6srdGMPtSaaOX7gz9KiyyxGn5p9QMrwHE,4042
382
383
  synth_ai/v0/tracing/context.py,sha256=QZRgMgSWMcmZtQ4WDA7eCJdIAKbgU85vWDM-aiRUpCE,5113
383
- synth_ai/v0/tracing/decorators.py,sha256=WlpU6qfFBqg5W7uc6_l_sK0LKae4CJdcxXSlHUIr3po,30807
384
+ synth_ai/v0/tracing/decorators.py,sha256=vAGItKhcdcCMenfFrnXoczl0iAki_uUvvT5n42pnAKk,30851
384
385
  synth_ai/v0/tracing/immediate_client.py,sha256=M1J1zY9dC2u0Ta-xa6kK32mSa9g-va2Avu7hnB88tbo,6203
385
386
  synth_ai/v0/tracing/local.py,sha256=sDNQ6ECVwZZkRlCC0_F33VOXuUUzZ1B0UVFBMKtN5R0,722
386
387
  synth_ai/v0/tracing/log_client_base.py,sha256=Zl-dOknLd47xa-fh_3UBJkw1wF67uN1-4sm8N0Wl7CU,2297
387
388
  synth_ai/v0/tracing/retry_queue.py,sha256=Crpt8ugbuxKfau3ioWt0jMJzsCafaxKPSC1X3gfPU34,6647
388
389
  synth_ai/v0/tracing/trackers.py,sha256=I_5M9vAzFAsR_xKPGq_55yq2NkwztBZreMX8JhCK9UA,19005
389
- synth_ai/v0/tracing/upload.py,sha256=orzoqYjfkBblTOE9lUIsSvCCDkM1hmVfVV9xRBNOdII,17343
390
+ synth_ai/v0/tracing/upload.py,sha256=RdylTi_Hpjv3JdscY2Mwc0jU0Ldz7Mig7z6ltIkQRws,17387
390
391
  synth_ai/v0/tracing/utils.py,sha256=FXoMW9qOIk8-2qv_7WpVK2UG3_0AAGwi6fQQJ5Eldqk,306
391
392
  synth_ai/v0/tracing/events/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
392
393
  synth_ai/v0/tracing/events/manage.py,sha256=ZDXXP-ZwLH9LCsmw7Ru9o55d7bl_diPtJV78_p7hhxQ,5956
@@ -396,24 +397,24 @@ synth_ai/v0/tracing_v1/__init__.py,sha256=AHaSAzOMVAML9T_E4OrO2K9BheZDiKBUU3uyfG
396
397
  synth_ai/v0/tracing_v1/abstractions.py,sha256=pL9XCf9UEWdX4IRizzRK9XUNBtDeBYfkVD51F8UOB0s,6898
397
398
  synth_ai/v0/tracing_v1/base_client.py,sha256=IZpyuM-GIClvBBFA9iv4tpOjzY1QHF1m7vkNCYk7xLo,2931
398
399
  synth_ai/v0/tracing_v1/client_manager.py,sha256=rDHpOClkf1t0_6cJecQtr9IaaRmEJOCQ8StaiHyXq1E,4512
399
- synth_ai/v0/tracing_v1/config.py,sha256=Rv_NWeYBFqxNdj_Pp7_EifdZUgFU00d81iE9MPqWU8k,3998
400
+ synth_ai/v0/tracing_v1/config.py,sha256=ZjfJV1jMoJ6srdGMPtSaaOX7gz9KiyyxGn5p9QMrwHE,4042
400
401
  synth_ai/v0/tracing_v1/context.py,sha256=QZRgMgSWMcmZtQ4WDA7eCJdIAKbgU85vWDM-aiRUpCE,5113
401
- synth_ai/v0/tracing_v1/decorators.py,sha256=iOTISzwBS9VT_leGzMroy_Et7ybHKRzlO-0_V0NBFT0,31660
402
+ synth_ai/v0/tracing_v1/decorators.py,sha256=Hy_CqumvZxvyDoeLuZPB8_FE8BWKKwxtPtiino0JAIo,31704
402
403
  synth_ai/v0/tracing_v1/immediate_client.py,sha256=M1J1zY9dC2u0Ta-xa6kK32mSa9g-va2Avu7hnB88tbo,6203
403
404
  synth_ai/v0/tracing_v1/local.py,sha256=sDNQ6ECVwZZkRlCC0_F33VOXuUUzZ1B0UVFBMKtN5R0,722
404
405
  synth_ai/v0/tracing_v1/log_client_base.py,sha256=Zl-dOknLd47xa-fh_3UBJkw1wF67uN1-4sm8N0Wl7CU,2297
405
406
  synth_ai/v0/tracing_v1/retry_queue.py,sha256=P1XxTzZHBBPeFTHWSh_1oP5Byn4X3bNsXZqPc1rsu5U,6650
406
407
  synth_ai/v0/tracing_v1/trackers.py,sha256=I_5M9vAzFAsR_xKPGq_55yq2NkwztBZreMX8JhCK9UA,19005
407
- synth_ai/v0/tracing_v1/upload.py,sha256=_QvCvgNEUmxIpWik9C2y_7f_FBhY9XpgFPLO6zM-b3w,17980
408
+ synth_ai/v0/tracing_v1/upload.py,sha256=gRMx0aRQHvO1-MEJAEvdTYH9cBvcPp_Z8r2nHADrBFM,18024
408
409
  synth_ai/v0/tracing_v1/utils.py,sha256=FXoMW9qOIk8-2qv_7WpVK2UG3_0AAGwi6fQQJ5Eldqk,306
409
410
  synth_ai/v0/tracing_v1/events/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
410
411
  synth_ai/v0/tracing_v1/events/manage.py,sha256=ZDXXP-ZwLH9LCsmw7Ru9o55d7bl_diPtJV78_p7hhxQ,5956
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.dev5.dist-info/licenses/LICENSE,sha256=ynhjRQUfqA_RdGRATApfFA_fBAy9cno04sLtLUqxVFM,1069
415
- synth_ai-0.2.6.dev5.dist-info/METADATA,sha256=zOL3OaxOqOJIBabHtKPJqdEvEoAEYalzrOFHTxHu3N8,3980
416
- synth_ai-0.2.6.dev5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
417
- synth_ai-0.2.6.dev5.dist-info/entry_points.txt,sha256=Neq-3bT7TAijjgOIR77pKL-WYg6TWBDeO8pp_nL4vGY,91
418
- synth_ai-0.2.6.dev5.dist-info/top_level.txt,sha256=fBmtZyVHuKaGa29oHBaaUkrUIWTqSpoVMPiVdCDP3k8,9
419
- synth_ai-0.2.6.dev5.dist-info/RECORD,,
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,,