synth-ai 0.2.6.dev1__py3-none-any.whl → 0.2.6.dev2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of synth-ai might be problematic. Click here for more details.
- synth_ai/cli/rl_demo.py +52 -4
- synth_ai/demos/core/cli.py +443 -40
- synth_ai/demos/demo_task_apps/math/_common.py +17 -0
- synth_ai/demos/demo_task_apps/math/modal_task_app.py +415 -0
- synth_ai/environments/examples/crafter_classic/agent_demos/crafter_modal_ft/filter_traces_sft_turso.py +23 -9
- synth_ai/environments/service/app.py +13 -6
- synth_ai/http.py +26 -102
- synth_ai/http_client.py +104 -0
- synth_ai/lm/core/synth_models.py +2 -2
- {synth_ai-0.2.6.dev1.dist-info → synth_ai-0.2.6.dev2.dist-info}/METADATA +1 -1
- {synth_ai-0.2.6.dev1.dist-info → synth_ai-0.2.6.dev2.dist-info}/RECORD +15 -12
- {synth_ai-0.2.6.dev1.dist-info → synth_ai-0.2.6.dev2.dist-info}/WHEEL +0 -0
- {synth_ai-0.2.6.dev1.dist-info → synth_ai-0.2.6.dev2.dist-info}/entry_points.txt +0 -0
- {synth_ai-0.2.6.dev1.dist-info → synth_ai-0.2.6.dev2.dist-info}/licenses/LICENSE +0 -0
- {synth_ai-0.2.6.dev1.dist-info → synth_ai-0.2.6.dev2.dist-info}/top_level.txt +0 -0
synth_ai/http_client.py
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import asyncio
|
|
4
|
+
from dataclasses import dataclass
|
|
5
|
+
from typing import Any, Dict, Optional
|
|
6
|
+
|
|
7
|
+
import aiohttp
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@dataclass
|
|
11
|
+
class HTTPError(Exception):
|
|
12
|
+
status: int
|
|
13
|
+
url: str
|
|
14
|
+
message: str
|
|
15
|
+
body_snippet: str | None = None
|
|
16
|
+
detail: Any | None = None
|
|
17
|
+
|
|
18
|
+
def __str__(self) -> str: # pragma: no cover - trivial
|
|
19
|
+
base = f"HTTP {self.status} for {self.url}: {self.message}"
|
|
20
|
+
if self.body_snippet:
|
|
21
|
+
base += f" | body[0:200]={self.body_snippet[:200]}"
|
|
22
|
+
return base
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class AsyncHttpClient:
|
|
26
|
+
def __init__(self, base_url: str, api_key: str, timeout: float = 30.0) -> None:
|
|
27
|
+
self._base_url = base_url.rstrip("/")
|
|
28
|
+
self._api_key = api_key
|
|
29
|
+
self._timeout = aiohttp.ClientTimeout(total=timeout)
|
|
30
|
+
self._session: Optional[aiohttp.ClientSession] = None
|
|
31
|
+
|
|
32
|
+
async def __aenter__(self) -> "AsyncHttpClient":
|
|
33
|
+
if self._session is None:
|
|
34
|
+
headers = {"authorization": f"Bearer {self._api_key}"}
|
|
35
|
+
self._session = aiohttp.ClientSession(headers=headers, timeout=self._timeout)
|
|
36
|
+
return self
|
|
37
|
+
|
|
38
|
+
async def __aexit__(self, exc_type, exc, tb) -> None: # noqa: ANN001
|
|
39
|
+
if self._session is not None:
|
|
40
|
+
await self._session.close()
|
|
41
|
+
self._session = None
|
|
42
|
+
|
|
43
|
+
def _abs(self, path: str) -> str:
|
|
44
|
+
if path.startswith("http://") or path.startswith("https://"):
|
|
45
|
+
return path
|
|
46
|
+
# If base_url already ends with /api and path starts with /api, remove duplicate
|
|
47
|
+
if self._base_url.endswith("/api") and path.startswith("/api"):
|
|
48
|
+
path = path[4:] # Remove leading /api
|
|
49
|
+
return f"{self._base_url}/{path.lstrip('/')}"
|
|
50
|
+
|
|
51
|
+
async def get(self, path: str, *, params: Optional[Dict[str, Any]] = None, headers: Optional[Dict[str, str]] = None) -> Any:
|
|
52
|
+
url = self._abs(path)
|
|
53
|
+
assert self._session is not None, "AsyncHttpClient must be used as an async context manager"
|
|
54
|
+
async with self._session.get(url, params=params, headers=headers) as resp:
|
|
55
|
+
return await self._handle_response(resp, url)
|
|
56
|
+
|
|
57
|
+
async def post_json(self, path: str, *, json: Dict[str, Any], headers: Optional[Dict[str, str]] = None) -> Any:
|
|
58
|
+
url = self._abs(path)
|
|
59
|
+
assert self._session is not None, "AsyncHttpClient must be used as an async context manager"
|
|
60
|
+
async with self._session.post(url, json=json, headers=headers) as resp:
|
|
61
|
+
return await self._handle_response(resp, url)
|
|
62
|
+
|
|
63
|
+
async def post_multipart(self, path: str, *, data: Dict[str, Any], files: Dict[str, tuple[str, bytes, str | None]], headers: Optional[Dict[str, str]] = None) -> Any:
|
|
64
|
+
url = self._abs(path)
|
|
65
|
+
assert self._session is not None, "AsyncHttpClient must be used as an async context manager"
|
|
66
|
+
form = aiohttp.FormData()
|
|
67
|
+
for k, v in data.items():
|
|
68
|
+
form.add_field(k, str(v))
|
|
69
|
+
for field, (filename, content, content_type) in files.items():
|
|
70
|
+
form.add_field(field, content, filename=filename, content_type=content_type or "application/octet-stream")
|
|
71
|
+
async with self._session.post(url, data=form, headers=headers) as resp:
|
|
72
|
+
return await self._handle_response(resp, url)
|
|
73
|
+
|
|
74
|
+
async def delete(self, path: str, *, headers: Optional[Dict[str, str]] = None) -> Any:
|
|
75
|
+
url = self._abs(path)
|
|
76
|
+
assert self._session is not None, "AsyncHttpClient must be used as an async context manager"
|
|
77
|
+
async with self._session.delete(url, headers=headers) as resp:
|
|
78
|
+
return await self._handle_response(resp, url)
|
|
79
|
+
|
|
80
|
+
async def _handle_response(self, resp: aiohttp.ClientResponse, url: str) -> Any:
|
|
81
|
+
text = await resp.text()
|
|
82
|
+
body_snippet = text[:200] if text else None
|
|
83
|
+
if 200 <= resp.status < 300:
|
|
84
|
+
ctype = resp.headers.get("content-type", "")
|
|
85
|
+
if "application/json" in ctype:
|
|
86
|
+
try:
|
|
87
|
+
return await resp.json()
|
|
88
|
+
except Exception:
|
|
89
|
+
# Fallback to text
|
|
90
|
+
return text
|
|
91
|
+
return text
|
|
92
|
+
# error
|
|
93
|
+
detail: Any | None = None
|
|
94
|
+
try:
|
|
95
|
+
detail = await resp.json()
|
|
96
|
+
except Exception:
|
|
97
|
+
detail = None
|
|
98
|
+
raise HTTPError(status=resp.status, url=url, message="request_failed", body_snippet=body_snippet, detail=detail)
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
async def sleep(seconds: float) -> None:
|
|
102
|
+
await asyncio.sleep(seconds)
|
|
103
|
+
|
|
104
|
+
|
synth_ai/lm/core/synth_models.py
CHANGED
|
@@ -29,7 +29,7 @@ QWEN3_MODELS: List[str] = [
|
|
|
29
29
|
"Qwen/Qwen3-32B",
|
|
30
30
|
|
|
31
31
|
# Qwen3 specialized variants
|
|
32
|
-
"Qwen/Qwen3-4B-
|
|
32
|
+
"Qwen/Qwen3-4B-2507",
|
|
33
33
|
"Qwen/Qwen3-4B-Thinking-2507",
|
|
34
34
|
]
|
|
35
35
|
|
|
@@ -38,7 +38,7 @@ QWEN3_MODELS: List[str] = [
|
|
|
38
38
|
FINE_TUNED_MODELS: List[str] = [
|
|
39
39
|
# Add specific fine-tuned models that are known to work with Synth
|
|
40
40
|
# Examples:
|
|
41
|
-
# "ft:Qwen/Qwen3-4B-
|
|
41
|
+
# "ft:Qwen/Qwen3-4B-2507:ftjob-22",
|
|
42
42
|
]
|
|
43
43
|
|
|
44
44
|
# Combine all Synth-supported models
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
synth_ai/__init__.py,sha256=1mIN_hDsscPcKTV1ciH5N12pONnczGV-RmR8EqroksI,1341
|
|
2
2
|
synth_ai/__main__.py,sha256=Kh1xBKkTE5Vs2qNMtDuuOXerHUptMcOiF3YziOpC6DA,146
|
|
3
|
-
synth_ai/http.py,sha256=
|
|
3
|
+
synth_ai/http.py,sha256=lqjFXDmAP_xgfywK_rDSOVxuMy4rDH9S3Rtu9k1tLmk,1028
|
|
4
|
+
synth_ai/http_client.py,sha256=_9J8rUGoItUMnJLGZw7r0uXiJeLWR939kByRkvtP1XM,4429
|
|
4
5
|
synth_ai/install_sqld.sh,sha256=AMBhlfq661PxeTTc6D4K_Nei_qwMvA84ei4NhQzmUUk,928
|
|
5
6
|
synth_ai/cli/__init__.py,sha256=ThBK5FykxAqX8Mz0E4gj94_PX9EwMEtXcmm-A8krv7E,1559
|
|
6
7
|
synth_ai/cli/balance.py,sha256=dlxGKCZ2kDeuHMZ5m8n5SHRWW-2CIWs3JcY5xpnWRVA,7798
|
|
@@ -9,7 +10,7 @@ synth_ai/cli/demo.py,sha256=GNVBxVtscxfAITFObyTOK8XPP2WGb-pv9LL4CiV_g6Q,4843
|
|
|
9
10
|
synth_ai/cli/legacy_root_backup.py,sha256=KSMADyJ2g5OVpsq_CeBzqIeDC2Um-9GyINzsJH-75uw,15872
|
|
10
11
|
synth_ai/cli/man.py,sha256=JQDon73ZkuKP9xr1_vRh5fjV9_b5xiUb7zNjny7ArB8,3765
|
|
11
12
|
synth_ai/cli/recent.py,sha256=mHhM-QrR_MfjfKSzBvvPUEC-lkXTWUZrQwqYTmb2x0Y,4173
|
|
12
|
-
synth_ai/cli/rl_demo.py,sha256=
|
|
13
|
+
synth_ai/cli/rl_demo.py,sha256=MPS5qra8kg7KdEDunI5TgckJj6lautlcskmDMx3cRu4,7316
|
|
13
14
|
synth_ai/cli/root.py,sha256=YAr7H2WYfnRt6_yxLix9O01-UnSy7OtYBVyNy4l5xIo,9614
|
|
14
15
|
synth_ai/cli/status.py,sha256=M_bt7U58Ubi-q-ZlrIpgCASKq9_k6uMjpx926f6kLLA,4591
|
|
15
16
|
synth_ai/cli/traces.py,sha256=_QBdCR92u0Gv51U4DH0Ws1d5yCrbJRpaYKe7pmcHrHs,6484
|
|
@@ -19,14 +20,16 @@ synth_ai/config/base_url.py,sha256=Bk7Bd9jKJP-LF0SW--WE01JhMfvOB6NUkFMRgPMnJuQ,3
|
|
|
19
20
|
synth_ai/core/experiment.py,sha256=hLkPtzUFA7iY3-QpeJ5K8YjvQeyfqnjab5P2CFaojys,236
|
|
20
21
|
synth_ai/core/system.py,sha256=s-Z7np2ISYmYc1r9YN-y2yb3cgRlOalrh0iaqnxeo84,206
|
|
21
22
|
synth_ai/demos/core/__init__.py,sha256=A2FjhY7KXGtyzdQXqeTPCkEhHfrH-eQg6bvP8HaYhZM,36
|
|
22
|
-
synth_ai/demos/core/cli.py,sha256=
|
|
23
|
+
synth_ai/demos/core/cli.py,sha256=Q7vgPuDRSb2V_TWsiBtzEIn8ujr3awDu3X02wBRovYk,46052
|
|
23
24
|
synth_ai/demos/demo_task_apps/__init__.py,sha256=8aUGEGpWUw11GRb3wQXRAmQ99yjAt5qd5FCTDJpXWjI,44
|
|
24
25
|
synth_ai/demos/demo_task_apps/core.py,sha256=3-C2dGdaqVqrVjnsxU2n6kGcuaprwuszBcTHePBypwo,13580
|
|
25
26
|
synth_ai/demos/demo_task_apps/math/__init__.py,sha256=WBzpZwSn7pRarBmhopQi34i9bEm05-71eM3siboOavY,43
|
|
27
|
+
synth_ai/demos/demo_task_apps/math/_common.py,sha256=SgtVW1pne4pgwGS2gYYQWkmG9BvU2sQTYzlncmUJ0NM,533
|
|
26
28
|
synth_ai/demos/demo_task_apps/math/app.py,sha256=gNopoAhwM0vzdKuCa7AwQqSwiV2xagrjMxMH9YIniv4,1160
|
|
27
29
|
synth_ai/demos/demo_task_apps/math/config.toml,sha256=atyeLq8tJsm4BST2NwlKUMum5D_gxEAWBqYsQGLQimI,757
|
|
28
30
|
synth_ai/demos/demo_task_apps/math/deploy_modal.py,sha256=O4745sFuGEZTsygl-mz6ZOFJ7mog8CquXMgMyjFKr_c,2288
|
|
29
31
|
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
|
|
30
33
|
synth_ai/environments/__init__.py,sha256=BQW0Nc_BFQq_N-pcqTyJVjW56kSEXu7XZyaSer-U95Q,1032
|
|
31
34
|
synth_ai/environments/environment/__init__.py,sha256=EBol9AKxPTIPXWcbH9Tja-l3yL-N2kB8e5atyf6F66c,31
|
|
32
35
|
synth_ai/environments/environment/core.py,sha256=0jd0CZ88_s_qqA3d1lOgVsnv-ucw_1lJDAIUj1gTSt0,2201
|
|
@@ -67,7 +70,7 @@ synth_ai/environments/examples/crafter_classic/agent_demos/crafter_trace_evaluat
|
|
|
67
70
|
synth_ai/environments/examples/crafter_classic/agent_demos/example_v3_usage.py,sha256=V0S6U_D9b-VVYkrCblylv3usA4ouV9YL3blki6vc1fs,6916
|
|
68
71
|
synth_ai/environments/examples/crafter_classic/agent_demos/crafter_modal_ft/crafter_synth_config.toml,sha256=xUAL54kT5ThnZPmMQI0eGWXoVe8Gn1_imnB0-DMOlo4,1104
|
|
69
72
|
synth_ai/environments/examples/crafter_classic/agent_demos/crafter_modal_ft/filter_config_modal.toml,sha256=Hws5eQUBSG00w825BgBgQDrUeuOq2KXwUsnDrkOC-2g,748
|
|
70
|
-
synth_ai/environments/examples/crafter_classic/agent_demos/crafter_modal_ft/filter_traces_sft_turso.py,sha256=
|
|
73
|
+
synth_ai/environments/examples/crafter_classic/agent_demos/crafter_modal_ft/filter_traces_sft_turso.py,sha256=n3UAq9LvZHpTZ7RlC0it3bPOZfOuUojHbP4abe6T9HQ,27753
|
|
71
74
|
synth_ai/environments/examples/crafter_classic/agent_demos/crafter_modal_ft/kick_off_ft_modal.py,sha256=6NXSzpAXsKw3-NdKvZXCtXFA-9tZFHOlN2QVksygHFY,15284
|
|
72
75
|
synth_ai/environments/examples/crafter_classic/agent_demos/crafter_modal_ft/old/analyze_action_results.py,sha256=6n2xKD8VBFn5EKrtFNYQgR9nSxfK6jcpavrGnUgi4Eo,1550
|
|
73
76
|
synth_ai/environments/examples/crafter_classic/agent_demos/crafter_modal_ft/old/analyze_agent_actions.py,sha256=eUoPNPE2hMUhDTOkYJyLWeJCOrpQfEc5GtcgedUczKk,6302
|
|
@@ -235,7 +238,7 @@ synth_ai/environments/examples/wordle/helpers/generate_instances_wordfreq.py,sha
|
|
|
235
238
|
synth_ai/environments/reproducibility/core.py,sha256=jDhG1EARROJH7-Y7eKuMYdjbi4-t1QUbxddHbbG1Dxc,1499
|
|
236
239
|
synth_ai/environments/reproducibility/helpers.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
237
240
|
synth_ai/environments/reproducibility/tree.py,sha256=LMVTrKpPkBDjkZOfA5ptl3_n8JPc9GCnP49itPKL8zc,13703
|
|
238
|
-
synth_ai/environments/service/app.py,sha256=
|
|
241
|
+
synth_ai/environments/service/app.py,sha256=uwLT3R9N7eYmIKiJFGroaUkCQj3hm88QKNAMETRu3Tk,3559
|
|
239
242
|
synth_ai/environments/service/core_routes.py,sha256=D3KMH6eIWxbcW0F8jIgdfYe7PF8Nb7kmKz1a9z0GwR8,38412
|
|
240
243
|
synth_ai/environments/service/external_registry.py,sha256=3PiWCsZr0PburC6K-IBjO9uHGVa-qnT0JHTFyyN4sZE,1765
|
|
241
244
|
synth_ai/environments/service/registry.py,sha256=R4bvjdEW1GtYJdZL4Vl9ogNCQc0iGCxmjs-NuzCo5f4,405
|
|
@@ -299,7 +302,7 @@ synth_ai/lm/core/all.py,sha256=sRSuXgdXMrG46DbL7LeBA2g9PcnNgMKV0RhLkWecR1o,1765
|
|
|
299
302
|
synth_ai/lm/core/exceptions.py,sha256=YZ3dgwb--ZyLoa4gI9uDGkuWoGfh-TS4yFanSwQd-CM,98
|
|
300
303
|
synth_ai/lm/core/main.py,sha256=V1b-v8aySJwcilS_uziHyIVF-RUpOj8QK2_F828pHJ8,12801
|
|
301
304
|
synth_ai/lm/core/main_v3.py,sha256=TJQHZ0kg7B1jM6deZSF21gVM-u-X-zkr-Zs4GiGfxTw,24602
|
|
302
|
-
synth_ai/lm/core/synth_models.py,sha256=
|
|
305
|
+
synth_ai/lm/core/synth_models.py,sha256=Zo5Roj7HmJC4E3kOaZju5LhiExKRV05WB2-KqMxJRY4,1628
|
|
303
306
|
synth_ai/lm/core/vendor_clients.py,sha256=yDJ4KxIP4sdxIaUkXJqF4G4_VS-47YA_OBQscj9v0B0,6890
|
|
304
307
|
synth_ai/lm/cost/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
305
308
|
synth_ai/lm/cost/monitor.py,sha256=DkeLUlrb7rGx3nZ04aADU9HXXu5mZTf_DBwT0xhzIv4,7
|
|
@@ -408,9 +411,9 @@ synth_ai/v0/tracing_v1/events/manage.py,sha256=ZDXXP-ZwLH9LCsmw7Ru9o55d7bl_diPtJ
|
|
|
408
411
|
synth_ai/v0/tracing_v1/events/scope.py,sha256=BuBkhSpVHUJt8iGT9HJZF82rbb88mQcd2vM2shg-w2I,2550
|
|
409
412
|
synth_ai/v0/tracing_v1/events/store.py,sha256=0342lvAcalyJbVEIzQFaPuMQGgwiFm7M5rE6gr-G0E8,9041
|
|
410
413
|
synth_ai/zyk/__init__.py,sha256=htVLnzTYQ5rxzYpzSYBm7_o6uNKZ3pB_PrqkBrgTRS4,771
|
|
411
|
-
synth_ai-0.2.6.
|
|
412
|
-
synth_ai-0.2.6.
|
|
413
|
-
synth_ai-0.2.6.
|
|
414
|
-
synth_ai-0.2.6.
|
|
415
|
-
synth_ai-0.2.6.
|
|
416
|
-
synth_ai-0.2.6.
|
|
414
|
+
synth_ai-0.2.6.dev2.dist-info/licenses/LICENSE,sha256=ynhjRQUfqA_RdGRATApfFA_fBAy9cno04sLtLUqxVFM,1069
|
|
415
|
+
synth_ai-0.2.6.dev2.dist-info/METADATA,sha256=WquPC-AqPKhdFS7xEywtpLnvSGwZfTAmPantP6czdl4,3980
|
|
416
|
+
synth_ai-0.2.6.dev2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
417
|
+
synth_ai-0.2.6.dev2.dist-info/entry_points.txt,sha256=Neq-3bT7TAijjgOIR77pKL-WYg6TWBDeO8pp_nL4vGY,91
|
|
418
|
+
synth_ai-0.2.6.dev2.dist-info/top_level.txt,sha256=fBmtZyVHuKaGa29oHBaaUkrUIWTqSpoVMPiVdCDP3k8,9
|
|
419
|
+
synth_ai-0.2.6.dev2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|