synth-ai 0.2.6.dev4__py3-none-any.whl → 0.2.6.dev6__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 +8 -2
- synth_ai/config/base_url.py +9 -0
- synth_ai/demos/core/cli.py +108 -43
- synth_ai/demos/demo_task_apps/core.py +24 -6
- synth_ai/lm/vendors/core/openai_api.py +8 -3
- synth_ai/v0/tracing/config.py +3 -1
- synth_ai/v0/tracing/decorators.py +3 -1
- synth_ai/v0/tracing/upload.py +3 -1
- synth_ai/v0/tracing_v1/config.py +3 -1
- synth_ai/v0/tracing_v1/decorators.py +3 -1
- synth_ai/v0/tracing_v1/upload.py +3 -1
- {synth_ai-0.2.6.dev4.dist-info → synth_ai-0.2.6.dev6.dist-info}/METADATA +1 -1
- {synth_ai-0.2.6.dev4.dist-info → synth_ai-0.2.6.dev6.dist-info}/RECORD +17 -17
- {synth_ai-0.2.6.dev4.dist-info → synth_ai-0.2.6.dev6.dist-info}/WHEEL +0 -0
- {synth_ai-0.2.6.dev4.dist-info → synth_ai-0.2.6.dev6.dist-info}/entry_points.txt +0 -0
- {synth_ai-0.2.6.dev4.dist-info → synth_ai-0.2.6.dev6.dist-info}/licenses/LICENSE +0 -0
- {synth_ai-0.2.6.dev4.dist-info → synth_ai-0.2.6.dev6.dist-info}/top_level.txt +0 -0
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
|
-
|
|
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
|
-
|
|
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/config/base_url.py
CHANGED
|
@@ -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")
|
synth_ai/demos/core/cli.py
CHANGED
|
@@ -224,8 +224,59 @@ def _popen_stream_capture(cmd: list[str], cwd: str | None = None, env: dict | No
|
|
|
224
224
|
return int(proc.returncode or 0), "\n".join(buf_lines)
|
|
225
225
|
|
|
226
226
|
|
|
227
|
+
def _mask_secret_args(args: list[str]) -> list[str]:
|
|
228
|
+
masked: list[str] = []
|
|
229
|
+
for a in args:
|
|
230
|
+
if "=" in a and any(a.startswith(prefix) for prefix in ("ENVIRONMENT_API_KEY=", "OPENAI_API_KEY=", "SYNTH_API_KEY=")):
|
|
231
|
+
try:
|
|
232
|
+
key, value = a.split("=", 1)
|
|
233
|
+
tail = value[-5:] if len(value) >= 5 else value
|
|
234
|
+
masked.append(f"{key}=***{tail}")
|
|
235
|
+
except Exception:
|
|
236
|
+
masked.append("<masked>")
|
|
237
|
+
else:
|
|
238
|
+
masked.append(a)
|
|
239
|
+
return masked
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
def _ensure_modal_secret(
|
|
243
|
+
secret_name: str,
|
|
244
|
+
*,
|
|
245
|
+
values: dict[str, str],
|
|
246
|
+
label: str = "deploy",
|
|
247
|
+
replace: bool = False,
|
|
248
|
+
) -> bool:
|
|
249
|
+
prefix = f"[{label}]"
|
|
250
|
+
if not secret_name.strip():
|
|
251
|
+
raise RuntimeError("Secret name is required")
|
|
252
|
+
|
|
253
|
+
if not values:
|
|
254
|
+
raise RuntimeError("No values provided to create Modal secret")
|
|
255
|
+
|
|
256
|
+
create_args = [f"{k}={v}" for k, v in values.items()]
|
|
257
|
+
create_cmd = ["uv", "run", "modal", "secret", "create", secret_name, *create_args]
|
|
258
|
+
|
|
259
|
+
if replace:
|
|
260
|
+
print(f"{prefix} Removing Modal secret '{secret_name}' (if present)…")
|
|
261
|
+
delete_cmd = ["bash", "-lc", f"printf 'y\\n' | uv run modal secret delete {secret_name}"]
|
|
262
|
+
print(f"{prefix} Command:", " ".join(delete_cmd))
|
|
263
|
+
delete_code = _popen_stream(delete_cmd)
|
|
264
|
+
if delete_code != 0:
|
|
265
|
+
print(f"{prefix} Warning: delete command exited with {delete_code}; continuing to create")
|
|
266
|
+
|
|
267
|
+
print(f"\n{prefix} Creating Modal secret '{secret_name}'…")
|
|
268
|
+
print(f"{prefix} Command:", " ".join(_mask_secret_args(create_cmd)))
|
|
269
|
+
code = _popen_stream(create_cmd)
|
|
270
|
+
if code != 0:
|
|
271
|
+
raise RuntimeError("Failed to provision Modal secret (see logs above)")
|
|
272
|
+
|
|
273
|
+
return True
|
|
274
|
+
|
|
275
|
+
|
|
227
276
|
def cmd_deploy(args: argparse.Namespace) -> int:
|
|
228
277
|
env = demo_core.load_env()
|
|
278
|
+
cwd_env_path = os.path.join(os.getcwd(), ".env")
|
|
279
|
+
local_env = demo_core.load_dotenv_file(cwd_env_path)
|
|
229
280
|
url = ""
|
|
230
281
|
app_name = env.task_app_name or ""
|
|
231
282
|
try:
|
|
@@ -279,6 +330,51 @@ def cmd_deploy(args: argparse.Namespace) -> int:
|
|
|
279
330
|
if not proceed:
|
|
280
331
|
print("Aborted by user.")
|
|
281
332
|
return 1
|
|
333
|
+
|
|
334
|
+
secret_name = (env.task_app_secret_name or "").strip() or f"{name_in}-secret"
|
|
335
|
+
env_key = (env.env_api_key or "").strip() or None
|
|
336
|
+
if env_key is None:
|
|
337
|
+
from synth_ai.rl.secrets import mint_environment_api_key
|
|
338
|
+
|
|
339
|
+
env_key = mint_environment_api_key()
|
|
340
|
+
demo_core.persist_env_api_key(env_key)
|
|
341
|
+
demo_core.persist_dotenv_values({"ENVIRONMENT_API_KEY": env_key})
|
|
342
|
+
os.environ["ENVIRONMENT_API_KEY"] = env_key
|
|
343
|
+
env.env_api_key = env_key
|
|
344
|
+
local_env["ENVIRONMENT_API_KEY"] = env_key
|
|
345
|
+
print("[deploy] Minted new ENVIRONMENT_API_KEY")
|
|
346
|
+
|
|
347
|
+
synth_key = (env.synth_api_key or os.environ.get("SYNTH_API_KEY") or local_env.get("SYNTH_API_KEY") or "").strip()
|
|
348
|
+
if not synth_key:
|
|
349
|
+
synth_key = input("Enter SYNTH_API_KEY for Modal secret (required): ").strip()
|
|
350
|
+
if not synth_key:
|
|
351
|
+
print("SYNTH_API_KEY is required to create the Modal secret.")
|
|
352
|
+
return 1
|
|
353
|
+
demo_core.persist_api_key(synth_key)
|
|
354
|
+
demo_core.persist_dotenv_values({"SYNTH_API_KEY": synth_key})
|
|
355
|
+
env.synth_api_key = synth_key
|
|
356
|
+
|
|
357
|
+
openai_key = (os.environ.get("OPENAI_API_KEY") or local_env.get("OPENAI_API_KEY") or "").strip()
|
|
358
|
+
if not openai_key:
|
|
359
|
+
openai_key = input("Enter OPENAI_API_KEY for Modal secret (required): ").strip()
|
|
360
|
+
if not openai_key:
|
|
361
|
+
print("OPENAI_API_KEY is required to create the Modal secret.")
|
|
362
|
+
return 1
|
|
363
|
+
demo_core.persist_dotenv_values({"OPENAI_API_KEY": openai_key})
|
|
364
|
+
local_env["OPENAI_API_KEY"] = openai_key
|
|
365
|
+
|
|
366
|
+
values = {"SYNTH_API_KEY": synth_key, "OPENAI_API_KEY": openai_key}
|
|
367
|
+
if env_key:
|
|
368
|
+
values["ENVIRONMENT_API_KEY"] = env_key
|
|
369
|
+
|
|
370
|
+
try:
|
|
371
|
+
created = _ensure_modal_secret(secret_name, values=values, label="deploy", replace=True)
|
|
372
|
+
except RuntimeError as secret_err:
|
|
373
|
+
print(f"Failed to prepare Modal secret '{secret_name}': {secret_err}")
|
|
374
|
+
return 2
|
|
375
|
+
if created:
|
|
376
|
+
print(f"[deploy] Modal secret '{secret_name}' provisioned.")
|
|
377
|
+
|
|
282
378
|
deploy_cmd = ["uv", "run", "python", "-m", "modal", "deploy", "--name", name_in, app_path]
|
|
283
379
|
print("\nStreaming Modal build/deploy logs (this can take several minutes on first run)…\n")
|
|
284
380
|
code, deploy_logs = _popen_stream_capture(deploy_cmd)
|
|
@@ -346,8 +442,6 @@ def cmd_deploy(args: argparse.Namespace) -> int:
|
|
|
346
442
|
|
|
347
443
|
|
|
348
444
|
def cmd_configure(args: argparse.Namespace) -> int:
|
|
349
|
-
from synth_ai.rl.secrets import mint_environment_api_key
|
|
350
|
-
|
|
351
445
|
env = demo_core.load_env()
|
|
352
446
|
cwd_env_path = os.path.join(os.getcwd(), ".env")
|
|
353
447
|
local_env = demo_core.load_dotenv_file(cwd_env_path)
|
|
@@ -362,13 +456,9 @@ def cmd_configure(args: argparse.Namespace) -> int:
|
|
|
362
456
|
demo_core.persist_dotenv_values({"SYNTH_API_KEY": synth_key})
|
|
363
457
|
|
|
364
458
|
env_key = env.env_api_key.strip()
|
|
365
|
-
minted_env_key = False
|
|
366
459
|
if not env_key:
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
print("Minted new ENVIRONMENT_API_KEY")
|
|
370
|
-
demo_core.persist_env_api_key(env_key)
|
|
371
|
-
demo_core.persist_dotenv_values({"ENVIRONMENT_API_KEY": env_key})
|
|
460
|
+
print("ENVIRONMENT_API_KEY missing; run `uvx synth-ai rl_demo deploy` to mint and store one.")
|
|
461
|
+
return 1
|
|
372
462
|
|
|
373
463
|
task_url = env.task_app_base_url
|
|
374
464
|
if not task_url or not _is_modal_public_url(task_url):
|
|
@@ -418,43 +508,20 @@ def cmd_configure(args: argparse.Namespace) -> int:
|
|
|
418
508
|
})
|
|
419
509
|
|
|
420
510
|
# Ensure Modal secret has the environment API key (and optional extras).
|
|
421
|
-
secret_args = [f"ENVIRONMENT_API_KEY={env_key}"]
|
|
422
511
|
openai_key = (os.environ.get("OPENAI_API_KEY") or local_env.get("OPENAI_API_KEY") or "").strip()
|
|
423
|
-
if openai_key:
|
|
424
|
-
secret_args.append(f"OPENAI_API_KEY={openai_key}")
|
|
425
512
|
synth_for_secret = synth_key
|
|
426
|
-
if synth_for_secret:
|
|
427
|
-
secret_args.append(f"SYNTH_API_KEY={synth_for_secret}")
|
|
428
513
|
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
try:
|
|
435
|
-
k, v = a.split("=", 1)
|
|
436
|
-
suf = v[-5:] if len(v) >= 5 else ""
|
|
437
|
-
masked.append(f"{k}=***{suf}")
|
|
438
|
-
except Exception:
|
|
439
|
-
masked.append("<masked>")
|
|
440
|
-
else:
|
|
441
|
-
masked.append(a)
|
|
442
|
-
return masked
|
|
514
|
+
secret_values: dict[str, str] = {"ENVIRONMENT_API_KEY": env_key}
|
|
515
|
+
if openai_key:
|
|
516
|
+
secret_values["OPENAI_API_KEY"] = openai_key
|
|
517
|
+
if synth_for_secret:
|
|
518
|
+
secret_values["SYNTH_API_KEY"] = synth_for_secret
|
|
443
519
|
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
delete_cmd = ["bash", "-lc", f"printf 'y\\n' | uv run modal secret delete {secret_name}"]
|
|
450
|
-
print("[configure] Command:", " ".join(delete_cmd))
|
|
451
|
-
_popen_stream(delete_cmd)
|
|
452
|
-
print("[configure] Retrying secret create…")
|
|
453
|
-
print("[configure] Command:", " ".join(_mask_args(create_cmd)))
|
|
454
|
-
code = _popen_stream(create_cmd)
|
|
455
|
-
if code != 0:
|
|
456
|
-
print("[configure] Failed to provision Modal secret.")
|
|
457
|
-
return 2
|
|
520
|
+
try:
|
|
521
|
+
_ensure_modal_secret(secret_name, values=secret_values, label="configure", replace=True)
|
|
522
|
+
except RuntimeError as err:
|
|
523
|
+
print(f"[configure] Failed to provision Modal secret: {err}")
|
|
524
|
+
return 2
|
|
458
525
|
|
|
459
526
|
# Verify task app can read the secret by hitting rollout health with X-API-Key.
|
|
460
527
|
rollout_url = task_url.rstrip("/") + "/health/rollout"
|
|
@@ -557,8 +624,6 @@ def cmd_configure(args: argparse.Namespace) -> int:
|
|
|
557
624
|
"TASK_APP_NAME": app_name,
|
|
558
625
|
"TASK_APP_SECRET_NAME": secret_name,
|
|
559
626
|
}, indent=2))
|
|
560
|
-
if minted_env_key:
|
|
561
|
-
print(f"Stored minted ENVIRONMENT_API_KEY in {cwd_env_path}")
|
|
562
627
|
print("Next: uvx synth-ai rl_demo run")
|
|
563
628
|
return 0
|
|
564
629
|
|
|
@@ -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
|
|
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 = (
|
|
199
|
-
|
|
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 =
|
|
228
|
+
dev_url = prod_default
|
|
211
229
|
else:
|
|
212
|
-
dev_url =
|
|
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
|
|
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")
|
|
@@ -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
|
-
|
|
49
|
-
|
|
50
|
-
|
|
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
|
synth_ai/v0/tracing/config.py
CHANGED
|
@@ -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=
|
|
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",
|
|
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)
|
synth_ai/v0/tracing/upload.py
CHANGED
|
@@ -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",
|
|
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.
|
synth_ai/v0/tracing_v1/config.py
CHANGED
|
@@ -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=
|
|
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",
|
|
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)
|
synth_ai/v0/tracing_v1/upload.py
CHANGED
|
@@ -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",
|
|
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
|
|
@@ -4,7 +4,7 @@ synth_ai/http.py,sha256=lqjFXDmAP_xgfywK_rDSOVxuMy4rDH9S3Rtu9k1tLmk,1028
|
|
|
4
4
|
synth_ai/http_client.py,sha256=_9J8rUGoItUMnJLGZw7r0uXiJeLWR939kByRkvtP1XM,4429
|
|
5
5
|
synth_ai/install_sqld.sh,sha256=AMBhlfq661PxeTTc6D4K_Nei_qwMvA84ei4NhQzmUUk,928
|
|
6
6
|
synth_ai/cli/__init__.py,sha256=ThBK5FykxAqX8Mz0E4gj94_PX9EwMEtXcmm-A8krv7E,1559
|
|
7
|
-
synth_ai/cli/balance.py,sha256=
|
|
7
|
+
synth_ai/cli/balance.py,sha256=z4h1MQSyFX60k-13L9IT0rtOCI16iKNGJeNjFMZuv_k,8010
|
|
8
8
|
synth_ai/cli/calc.py,sha256=RJyQJ41e02xn-V0vRRCAVkL59UHDqyz8XpYGsenfdm4,2085
|
|
9
9
|
synth_ai/cli/demo.py,sha256=GNVBxVtscxfAITFObyTOK8XPP2WGb-pv9LL4CiV_g6Q,4843
|
|
10
10
|
synth_ai/cli/legacy_root_backup.py,sha256=KSMADyJ2g5OVpsq_CeBzqIeDC2Um-9GyINzsJH-75uw,15872
|
|
@@ -16,13 +16,13 @@ synth_ai/cli/status.py,sha256=M_bt7U58Ubi-q-ZlrIpgCASKq9_k6uMjpx926f6kLLA,4591
|
|
|
16
16
|
synth_ai/cli/traces.py,sha256=_QBdCR92u0Gv51U4DH0Ws1d5yCrbJRpaYKe7pmcHrHs,6484
|
|
17
17
|
synth_ai/cli/watch.py,sha256=HBKbAcpUkkPhGvsPRofckbu8oILiVqp35NXHkIEpTTc,17808
|
|
18
18
|
synth_ai/compound/cais.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
19
|
-
synth_ai/config/base_url.py,sha256=
|
|
19
|
+
synth_ai/config/base_url.py,sha256=c85LaABBrvsl8Fp8KH0LNtJJrpnUwlzA5Ywbuth8fHE,3454
|
|
20
20
|
synth_ai/core/experiment.py,sha256=hLkPtzUFA7iY3-QpeJ5K8YjvQeyfqnjab5P2CFaojys,236
|
|
21
21
|
synth_ai/core/system.py,sha256=s-Z7np2ISYmYc1r9YN-y2yb3cgRlOalrh0iaqnxeo84,206
|
|
22
22
|
synth_ai/demos/core/__init__.py,sha256=A2FjhY7KXGtyzdQXqeTPCkEhHfrH-eQg6bvP8HaYhZM,36
|
|
23
|
-
synth_ai/demos/core/cli.py,sha256=
|
|
23
|
+
synth_ai/demos/core/cli.py,sha256=MuJELXFRxtyucek9b05Oo54pmJs5QGo45SV3hDZTFO0,44729
|
|
24
24
|
synth_ai/demos/demo_task_apps/__init__.py,sha256=8aUGEGpWUw11GRb3wQXRAmQ99yjAt5qd5FCTDJpXWjI,44
|
|
25
|
-
synth_ai/demos/demo_task_apps/core.py,sha256=
|
|
25
|
+
synth_ai/demos/demo_task_apps/core.py,sha256=RsPRA_4p97_h0im33C-eJr2hryRFNdj54Zd9bdBcDsw,14005
|
|
26
26
|
synth_ai/demos/demo_task_apps/math/__init__.py,sha256=WBzpZwSn7pRarBmhopQi34i9bEm05-71eM3siboOavY,43
|
|
27
27
|
synth_ai/demos/demo_task_apps/math/_common.py,sha256=SgtVW1pne4pgwGS2gYYQWkmG9BvU2sQTYzlncmUJ0NM,533
|
|
28
28
|
synth_ai/demos/demo_task_apps/math/app.py,sha256=gNopoAhwM0vzdKuCa7AwQqSwiV2xagrjMxMH9YIniv4,1160
|
|
@@ -327,7 +327,7 @@ synth_ai/lm/vendors/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZ
|
|
|
327
327
|
synth_ai/lm/vendors/core/anthropic_api.py,sha256=mxJVF-uvSUOdbBRMmVfwBFCc7ntV5i_LNE5tQ2AxAbU,14986
|
|
328
328
|
synth_ai/lm/vendors/core/gemini_api.py,sha256=mHvQtRqoymuzsQDxNFgTDt4HsrgvIuVBSAE29QpRa34,11082
|
|
329
329
|
synth_ai/lm/vendors/core/mistral_api.py,sha256=4ggRg_4ajzZMBCb-0mHMX_ZTg10tteSfnIPE2NULFag,11875
|
|
330
|
-
synth_ai/lm/vendors/core/openai_api.py,sha256=
|
|
330
|
+
synth_ai/lm/vendors/core/openai_api.py,sha256=qVl6ZxKrcPwMMEsumFinIPML1I6UO0pt870nsBg64nw,8554
|
|
331
331
|
synth_ai/lm/vendors/core/synth_dev_api.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
332
332
|
synth_ai/lm/vendors/local/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
333
333
|
synth_ai/lm/vendors/local/ollama.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -378,15 +378,15 @@ synth_ai/v0/tracing/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSu
|
|
|
378
378
|
synth_ai/v0/tracing/abstractions.py,sha256=pL9XCf9UEWdX4IRizzRK9XUNBtDeBYfkVD51F8UOB0s,6898
|
|
379
379
|
synth_ai/v0/tracing/base_client.py,sha256=IZpyuM-GIClvBBFA9iv4tpOjzY1QHF1m7vkNCYk7xLo,2931
|
|
380
380
|
synth_ai/v0/tracing/client_manager.py,sha256=rDHpOClkf1t0_6cJecQtr9IaaRmEJOCQ8StaiHyXq1E,4512
|
|
381
|
-
synth_ai/v0/tracing/config.py,sha256=
|
|
381
|
+
synth_ai/v0/tracing/config.py,sha256=ZjfJV1jMoJ6srdGMPtSaaOX7gz9KiyyxGn5p9QMrwHE,4042
|
|
382
382
|
synth_ai/v0/tracing/context.py,sha256=QZRgMgSWMcmZtQ4WDA7eCJdIAKbgU85vWDM-aiRUpCE,5113
|
|
383
|
-
synth_ai/v0/tracing/decorators.py,sha256=
|
|
383
|
+
synth_ai/v0/tracing/decorators.py,sha256=vAGItKhcdcCMenfFrnXoczl0iAki_uUvvT5n42pnAKk,30851
|
|
384
384
|
synth_ai/v0/tracing/immediate_client.py,sha256=M1J1zY9dC2u0Ta-xa6kK32mSa9g-va2Avu7hnB88tbo,6203
|
|
385
385
|
synth_ai/v0/tracing/local.py,sha256=sDNQ6ECVwZZkRlCC0_F33VOXuUUzZ1B0UVFBMKtN5R0,722
|
|
386
386
|
synth_ai/v0/tracing/log_client_base.py,sha256=Zl-dOknLd47xa-fh_3UBJkw1wF67uN1-4sm8N0Wl7CU,2297
|
|
387
387
|
synth_ai/v0/tracing/retry_queue.py,sha256=Crpt8ugbuxKfau3ioWt0jMJzsCafaxKPSC1X3gfPU34,6647
|
|
388
388
|
synth_ai/v0/tracing/trackers.py,sha256=I_5M9vAzFAsR_xKPGq_55yq2NkwztBZreMX8JhCK9UA,19005
|
|
389
|
-
synth_ai/v0/tracing/upload.py,sha256=
|
|
389
|
+
synth_ai/v0/tracing/upload.py,sha256=RdylTi_Hpjv3JdscY2Mwc0jU0Ldz7Mig7z6ltIkQRws,17387
|
|
390
390
|
synth_ai/v0/tracing/utils.py,sha256=FXoMW9qOIk8-2qv_7WpVK2UG3_0AAGwi6fQQJ5Eldqk,306
|
|
391
391
|
synth_ai/v0/tracing/events/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
392
392
|
synth_ai/v0/tracing/events/manage.py,sha256=ZDXXP-ZwLH9LCsmw7Ru9o55d7bl_diPtJV78_p7hhxQ,5956
|
|
@@ -396,24 +396,24 @@ synth_ai/v0/tracing_v1/__init__.py,sha256=AHaSAzOMVAML9T_E4OrO2K9BheZDiKBUU3uyfG
|
|
|
396
396
|
synth_ai/v0/tracing_v1/abstractions.py,sha256=pL9XCf9UEWdX4IRizzRK9XUNBtDeBYfkVD51F8UOB0s,6898
|
|
397
397
|
synth_ai/v0/tracing_v1/base_client.py,sha256=IZpyuM-GIClvBBFA9iv4tpOjzY1QHF1m7vkNCYk7xLo,2931
|
|
398
398
|
synth_ai/v0/tracing_v1/client_manager.py,sha256=rDHpOClkf1t0_6cJecQtr9IaaRmEJOCQ8StaiHyXq1E,4512
|
|
399
|
-
synth_ai/v0/tracing_v1/config.py,sha256=
|
|
399
|
+
synth_ai/v0/tracing_v1/config.py,sha256=ZjfJV1jMoJ6srdGMPtSaaOX7gz9KiyyxGn5p9QMrwHE,4042
|
|
400
400
|
synth_ai/v0/tracing_v1/context.py,sha256=QZRgMgSWMcmZtQ4WDA7eCJdIAKbgU85vWDM-aiRUpCE,5113
|
|
401
|
-
synth_ai/v0/tracing_v1/decorators.py,sha256=
|
|
401
|
+
synth_ai/v0/tracing_v1/decorators.py,sha256=Hy_CqumvZxvyDoeLuZPB8_FE8BWKKwxtPtiino0JAIo,31704
|
|
402
402
|
synth_ai/v0/tracing_v1/immediate_client.py,sha256=M1J1zY9dC2u0Ta-xa6kK32mSa9g-va2Avu7hnB88tbo,6203
|
|
403
403
|
synth_ai/v0/tracing_v1/local.py,sha256=sDNQ6ECVwZZkRlCC0_F33VOXuUUzZ1B0UVFBMKtN5R0,722
|
|
404
404
|
synth_ai/v0/tracing_v1/log_client_base.py,sha256=Zl-dOknLd47xa-fh_3UBJkw1wF67uN1-4sm8N0Wl7CU,2297
|
|
405
405
|
synth_ai/v0/tracing_v1/retry_queue.py,sha256=P1XxTzZHBBPeFTHWSh_1oP5Byn4X3bNsXZqPc1rsu5U,6650
|
|
406
406
|
synth_ai/v0/tracing_v1/trackers.py,sha256=I_5M9vAzFAsR_xKPGq_55yq2NkwztBZreMX8JhCK9UA,19005
|
|
407
|
-
synth_ai/v0/tracing_v1/upload.py,sha256=
|
|
407
|
+
synth_ai/v0/tracing_v1/upload.py,sha256=gRMx0aRQHvO1-MEJAEvdTYH9cBvcPp_Z8r2nHADrBFM,18024
|
|
408
408
|
synth_ai/v0/tracing_v1/utils.py,sha256=FXoMW9qOIk8-2qv_7WpVK2UG3_0AAGwi6fQQJ5Eldqk,306
|
|
409
409
|
synth_ai/v0/tracing_v1/events/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
410
410
|
synth_ai/v0/tracing_v1/events/manage.py,sha256=ZDXXP-ZwLH9LCsmw7Ru9o55d7bl_diPtJV78_p7hhxQ,5956
|
|
411
411
|
synth_ai/v0/tracing_v1/events/scope.py,sha256=BuBkhSpVHUJt8iGT9HJZF82rbb88mQcd2vM2shg-w2I,2550
|
|
412
412
|
synth_ai/v0/tracing_v1/events/store.py,sha256=0342lvAcalyJbVEIzQFaPuMQGgwiFm7M5rE6gr-G0E8,9041
|
|
413
413
|
synth_ai/zyk/__init__.py,sha256=htVLnzTYQ5rxzYpzSYBm7_o6uNKZ3pB_PrqkBrgTRS4,771
|
|
414
|
-
synth_ai-0.2.6.
|
|
415
|
-
synth_ai-0.2.6.
|
|
416
|
-
synth_ai-0.2.6.
|
|
417
|
-
synth_ai-0.2.6.
|
|
418
|
-
synth_ai-0.2.6.
|
|
419
|
-
synth_ai-0.2.6.
|
|
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,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|