synth-ai 0.2.9.dev5__py3-none-any.whl → 0.2.10__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.

Files changed (349) hide show
  1. examples/__init__.py +16 -0
  2. examples/crafter_debug_render.py +23 -17
  3. examples/dev/qwen3_32b_qlora_4xh100.toml +40 -0
  4. examples/multi_step/crafter_rl_lora.md +29 -0
  5. examples/qwen_coder/README.md +102 -0
  6. examples/qwen_coder/_shared.py +113 -0
  7. examples/qwen_coder/configs/coder_lora_30b.toml +61 -0
  8. examples/qwen_coder/configs/coder_lora_4b.toml +57 -0
  9. examples/qwen_coder/configs/coder_lora_small.toml +58 -0
  10. examples/qwen_coder/generate_dataset.py +98 -0
  11. examples/qwen_coder/infer_ft_smoke.py +65 -0
  12. examples/qwen_coder/infer_prod_proxy.py +73 -0
  13. examples/qwen_coder/infer_via_synth.py +87 -0
  14. examples/qwen_coder/scripts/infer_coder.sh +19 -0
  15. examples/qwen_coder/scripts/train_coder_30b.sh +22 -0
  16. examples/qwen_coder/sft_full_17b.py +103 -0
  17. examples/qwen_coder/sft_lora_30b.py +110 -0
  18. examples/qwen_coder/subset_jsonl.py +39 -0
  19. examples/qwen_coder/todos.md +38 -0
  20. examples/qwen_coder/validate_jsonl.py +60 -0
  21. examples/rl/configs/eval_base_qwen.toml +1 -1
  22. examples/rl/configs/rl_from_base_qwen17.toml +1 -1
  23. examples/rl/download_dataset.py +26 -10
  24. examples/rl/run_eval.py +53 -52
  25. examples/rl/run_rl_and_save.py +29 -12
  26. examples/rl/task_app/math_single_step.py +180 -41
  27. examples/rl/task_app/math_task_app.py +14 -6
  28. examples/sft/README.md +139 -0
  29. examples/sft/configs/crafter_fft_qwen0p6b.toml +44 -0
  30. examples/sft/configs/crafter_lora_qwen0p6b.toml +45 -0
  31. examples/sft/evaluate.py +117 -0
  32. examples/sft/export_dataset.py +117 -0
  33. examples/sft/generate_traces.py +162 -0
  34. examples/swe/__init__.py +12 -0
  35. examples/swe/task_app/README.md +105 -0
  36. examples/swe/task_app/__init__.py +2 -0
  37. examples/swe/task_app/grpo_swe_mini.py +571 -0
  38. examples/swe/task_app/grpo_swe_mini_task_app.py +136 -0
  39. examples/swe/task_app/hosted/README.md +173 -0
  40. examples/swe/task_app/hosted/__init__.py +5 -0
  41. examples/swe/task_app/hosted/branching.py +143 -0
  42. examples/swe/task_app/hosted/environment_routes.py +1289 -0
  43. examples/swe/task_app/hosted/envs/__init__.py +1 -0
  44. examples/swe/task_app/hosted/envs/crafter/__init__.py +6 -0
  45. examples/swe/task_app/hosted/envs/crafter/app.py +1 -0
  46. examples/swe/task_app/hosted/envs/crafter/environment.py +522 -0
  47. examples/swe/task_app/hosted/envs/crafter/policy.py +478 -0
  48. examples/swe/task_app/hosted/envs/crafter/react_agent.py +108 -0
  49. examples/swe/task_app/hosted/envs/crafter/shared.py +305 -0
  50. examples/swe/task_app/hosted/envs/crafter/tools.py +47 -0
  51. examples/swe/task_app/hosted/envs/mini_swe/__init__.py +8 -0
  52. examples/swe/task_app/hosted/envs/mini_swe/environment.py +1164 -0
  53. examples/swe/task_app/hosted/envs/mini_swe/policy.py +355 -0
  54. examples/swe/task_app/hosted/envs/mini_swe/shared.py +83 -0
  55. examples/swe/task_app/hosted/envs/mini_swe/tools.py +96 -0
  56. examples/swe/task_app/hosted/hosted_app.py +204 -0
  57. examples/swe/task_app/hosted/inference/__init__.py +5 -0
  58. examples/swe/task_app/hosted/inference/openai_client.py +618 -0
  59. examples/swe/task_app/hosted/main.py +100 -0
  60. examples/swe/task_app/hosted/policy_routes.py +1079 -0
  61. examples/swe/task_app/hosted/registry.py +195 -0
  62. examples/swe/task_app/hosted/rollout.py +1869 -0
  63. examples/swe/task_app/hosted/storage/__init__.py +5 -0
  64. examples/swe/task_app/hosted/storage/volume.py +211 -0
  65. examples/swe/task_app/hosted/test_agents.py +161 -0
  66. examples/swe/task_app/hosted/test_service.py +137 -0
  67. examples/swe/task_app/hosted/utils.py +62 -0
  68. examples/vlm/PROPOSAL.md +53 -0
  69. examples/vlm/README.md +68 -0
  70. examples/vlm/configs/crafter_vlm_gpt4o.toml +44 -0
  71. examples/vlm/crafter_image_only_agent.py +207 -0
  72. examples/vlm/crafter_openai_vlm_agent.py +277 -0
  73. examples/vlm/filter_image_rows.py +63 -0
  74. examples/vlm/run_crafter_vlm_benchmark.py +316 -0
  75. examples/warming_up_to_rl/analyze_trace_db.py +12 -10
  76. examples/warming_up_to_rl/configs/rl_from_base_qwen4b.toml +11 -1
  77. examples/warming_up_to_rl/export_trace_sft.py +218 -36
  78. examples/warming_up_to_rl/groq_test.py +15 -8
  79. examples/warming_up_to_rl/manage_secrets.py +29 -25
  80. examples/warming_up_to_rl/readme.md +9 -2
  81. examples/warming_up_to_rl/run_eval.py +137 -61
  82. examples/warming_up_to_rl/run_fft_and_save.py +131 -60
  83. examples/warming_up_to_rl/run_local_rollout.py +88 -39
  84. examples/warming_up_to_rl/run_local_rollout_modal.py +114 -28
  85. examples/warming_up_to_rl/run_local_rollout_parallel.py +81 -20
  86. examples/warming_up_to_rl/run_local_rollout_traced.py +126 -23
  87. examples/warming_up_to_rl/run_rl_and_save.py +35 -12
  88. examples/warming_up_to_rl/run_rollout_remote.py +44 -19
  89. examples/warming_up_to_rl/task_app/README.md +6 -2
  90. examples/warming_up_to_rl/task_app/grpo_crafter.py +319 -57
  91. examples/warming_up_to_rl/task_app/grpo_crafter_task_app.py +11 -30
  92. examples/warming_up_to_rl/task_app/synth_envs_hosted/__init__.py +1 -1
  93. examples/warming_up_to_rl/task_app/synth_envs_hosted/branching.py +9 -11
  94. examples/warming_up_to_rl/task_app/synth_envs_hosted/environment_routes.py +137 -182
  95. examples/warming_up_to_rl/task_app/synth_envs_hosted/envs/__init__.py +1 -1
  96. examples/warming_up_to_rl/task_app/synth_envs_hosted/envs/crafter/__init__.py +1 -1
  97. examples/warming_up_to_rl/task_app/synth_envs_hosted/envs/crafter/app.py +1 -1
  98. examples/warming_up_to_rl/task_app/synth_envs_hosted/envs/crafter/environment.py +150 -57
  99. examples/warming_up_to_rl/task_app/synth_envs_hosted/envs/crafter/policy.py +105 -69
  100. examples/warming_up_to_rl/task_app/synth_envs_hosted/envs/crafter/react_agent.py +19 -7
  101. examples/warming_up_to_rl/task_app/synth_envs_hosted/envs/crafter/shared.py +45 -42
  102. examples/warming_up_to_rl/task_app/synth_envs_hosted/envs/crafter/tools.py +1 -1
  103. examples/warming_up_to_rl/task_app/synth_envs_hosted/hosted_app.py +47 -45
  104. examples/warming_up_to_rl/task_app/synth_envs_hosted/inference/__init__.py +1 -1
  105. examples/warming_up_to_rl/task_app/synth_envs_hosted/inference/openai_client.py +198 -92
  106. examples/warming_up_to_rl/task_app/synth_envs_hosted/main.py +0 -2
  107. examples/warming_up_to_rl/task_app/synth_envs_hosted/policy_routes.py +361 -263
  108. examples/warming_up_to_rl/task_app/synth_envs_hosted/registry.py +21 -23
  109. examples/warming_up_to_rl/task_app/synth_envs_hosted/rollout.py +394 -274
  110. examples/warming_up_to_rl/task_app/synth_envs_hosted/storage/__init__.py +1 -1
  111. examples/warming_up_to_rl/task_app/synth_envs_hosted/storage/volume.py +56 -62
  112. examples/warming_up_to_rl/task_app/synth_envs_hosted/test_agents.py +1 -0
  113. examples/warming_up_to_rl/task_app/synth_envs_hosted/test_service.py +6 -15
  114. examples/warming_up_to_rl/task_app/synth_envs_hosted/utils.py +4 -3
  115. synth_ai/__init__.py +1 -0
  116. synth_ai/api/models/supported.py +376 -0
  117. synth_ai/api/train/builders.py +157 -26
  118. synth_ai/api/train/cli.py +213 -57
  119. synth_ai/api/train/config_finder.py +65 -5
  120. synth_ai/api/train/env_resolver.py +33 -15
  121. synth_ai/api/train/pollers.py +13 -4
  122. synth_ai/api/train/supported_algos.py +139 -0
  123. synth_ai/api/train/task_app.py +5 -3
  124. synth_ai/api/train/utils.py +33 -48
  125. synth_ai/cli/__init__.py +19 -4
  126. synth_ai/cli/_modal_wrapper.py +28 -0
  127. synth_ai/cli/_typer_patch.py +49 -0
  128. synth_ai/cli/balance.py +2 -3
  129. synth_ai/cli/calc.py +1 -1
  130. synth_ai/cli/demo.py +21 -6
  131. synth_ai/cli/recent.py +2 -2
  132. synth_ai/cli/rl_demo.py +77 -17
  133. synth_ai/cli/root.py +116 -39
  134. synth_ai/cli/status.py +2 -2
  135. synth_ai/cli/task_apps.py +1699 -259
  136. synth_ai/cli/traces.py +7 -4
  137. synth_ai/cli/turso.py +73 -0
  138. synth_ai/cli/watch.py +12 -18
  139. synth_ai/core/experiment.py +0 -2
  140. synth_ai/demo_registry.py +68 -31
  141. synth_ai/demos/core/cli.py +516 -194
  142. synth_ai/demos/demo_task_apps/__init__.py +3 -3
  143. synth_ai/demos/demo_task_apps/core.py +64 -28
  144. synth_ai/demos/demo_task_apps/crafter/configs/crafter_fft_4b.toml +2 -3
  145. synth_ai/demos/demo_task_apps/crafter/grpo_crafter_task_app.py +37 -30
  146. synth_ai/demos/demo_task_apps/math/_common.py +1 -2
  147. synth_ai/demos/demo_task_apps/math/app.py +2 -1
  148. synth_ai/demos/demo_task_apps/math/deploy_modal.py +3 -6
  149. synth_ai/demos/demo_task_apps/math/modal_task_app.py +183 -82
  150. synth_ai/demos/demo_task_apps/math/task_app_entry.py +0 -2
  151. synth_ai/environments/examples/bandit/engine.py +12 -4
  152. synth_ai/environments/examples/bandit/taskset.py +4 -4
  153. synth_ai/environments/examples/crafter_classic/environment.py +76 -1
  154. synth_ai/environments/reproducibility/tree.py +5 -6
  155. synth_ai/environments/service/app.py +11 -12
  156. synth_ai/environments/service/core_routes.py +10 -9
  157. synth_ai/environments/stateful/engine.py +1 -1
  158. synth_ai/environments/tasks/core.py +1 -0
  159. synth_ai/environments/tasks/filters.py +5 -6
  160. synth_ai/environments/tasks/utils.py +4 -5
  161. synth_ai/evals/base.py +0 -2
  162. synth_ai/handshake.py +11 -9
  163. synth_ai/http.py +1 -1
  164. synth_ai/http_client.py +43 -11
  165. synth_ai/inference/__init__.py +0 -2
  166. synth_ai/inference/client.py +20 -6
  167. synth_ai/jobs/client.py +103 -78
  168. synth_ai/learning/__init__.py +41 -6
  169. synth_ai/learning/algorithms.py +14 -0
  170. synth_ai/learning/client.py +121 -29
  171. synth_ai/learning/config.py +2 -40
  172. synth_ai/learning/constants.py +0 -2
  173. synth_ai/learning/ft_client.py +4 -56
  174. synth_ai/learning/health.py +13 -7
  175. synth_ai/learning/jobs.py +43 -47
  176. synth_ai/{rl → learning/rl}/__init__.py +14 -5
  177. synth_ai/learning/rl/client.py +267 -0
  178. synth_ai/learning/rl/config.py +31 -0
  179. synth_ai/{rl → learning/rl}/contracts.py +5 -10
  180. synth_ai/{rl → learning/rl}/env_keys.py +45 -16
  181. synth_ai/learning/rl/secrets.py +13 -0
  182. synth_ai/learning/rl_client.py +2 -253
  183. synth_ai/learning/sft/__init__.py +29 -0
  184. synth_ai/learning/sft/client.py +68 -0
  185. synth_ai/learning/sft/config.py +270 -0
  186. synth_ai/learning/sft/data.py +295 -0
  187. synth_ai/learning/sse.py +25 -26
  188. synth_ai/learning/validators.py +25 -24
  189. synth_ai/lm/__init__.py +21 -47
  190. synth_ai/task/__init__.py +26 -27
  191. synth_ai/task/apps/__init__.py +18 -19
  192. synth_ai/task/auth.py +35 -23
  193. synth_ai/task/client.py +15 -13
  194. synth_ai/task/contracts.py +37 -35
  195. synth_ai/task/datasets.py +9 -6
  196. synth_ai/task/errors.py +11 -10
  197. synth_ai/task/health.py +17 -11
  198. synth_ai/task/json.py +58 -24
  199. synth_ai/task/proxy.py +15 -14
  200. synth_ai/task/rubrics.py +22 -15
  201. synth_ai/task/server.py +43 -17
  202. synth_ai/task/tracing_utils.py +12 -7
  203. synth_ai/task/validators.py +0 -1
  204. synth_ai/task/vendors.py +5 -7
  205. synth_ai/tracing_v3/__init__.py +2 -0
  206. synth_ai/tracing_v3/abstractions.py +21 -4
  207. synth_ai/tracing_v3/db_config.py +26 -1
  208. synth_ai/tracing_v3/decorators.py +18 -15
  209. synth_ai/tracing_v3/examples/basic_usage.py +3 -2
  210. synth_ai/tracing_v3/hooks.py +6 -4
  211. synth_ai/tracing_v3/llm_call_record_helpers.py +6 -6
  212. synth_ai/tracing_v3/replica_sync.py +1 -0
  213. synth_ai/tracing_v3/session_tracer.py +63 -16
  214. synth_ai/tracing_v3/storage/base.py +89 -1
  215. synth_ai/tracing_v3/storage/config.py +21 -8
  216. synth_ai/tracing_v3/storage/factory.py +10 -8
  217. synth_ai/tracing_v3/storage/utils.py +4 -2
  218. synth_ai/tracing_v3/turso/daemon.py +7 -2
  219. synth_ai/tracing_v3/turso/models.py +5 -2
  220. synth_ai/tracing_v3/turso/native_manager.py +1173 -0
  221. synth_ai/tracing_v3/utils.py +4 -3
  222. synth_ai/v0/api/__init__.py +8 -0
  223. synth_ai/v0/api/models/__init__.py +8 -0
  224. synth_ai/v0/api/models/supported.py +8 -0
  225. synth_ai/v0/config/__init__.py +15 -0
  226. synth_ai/v0/config/base_url.py +12 -0
  227. synth_ai/v0/lm/__init__.py +51 -0
  228. synth_ai/{lm → v0/lm}/caching/ephemeral.py +3 -5
  229. synth_ai/{lm → v0/lm}/caching/handler.py +4 -4
  230. synth_ai/{lm → v0/lm}/caching/initialize.py +1 -1
  231. synth_ai/{lm → v0/lm}/caching/persistent.py +1 -1
  232. synth_ai/{lm → v0/lm}/config.py +6 -1
  233. synth_ai/{lm → v0/lm}/core/all.py +9 -9
  234. synth_ai/{lm → v0/lm}/core/exceptions.py +0 -2
  235. synth_ai/{lm → v0/lm}/core/main.py +19 -7
  236. synth_ai/{lm → v0/lm}/core/main_v3.py +10 -10
  237. synth_ai/{lm → v0/lm}/core/synth_models.py +2 -15
  238. synth_ai/{lm → v0/lm}/core/vendor_clients.py +6 -4
  239. synth_ai/{lm → v0/lm}/overrides.py +4 -4
  240. synth_ai/{lm → v0/lm}/provider_support/anthropic.py +4 -4
  241. synth_ai/{lm → v0/lm}/provider_support/openai.py +5 -5
  242. synth_ai/{lm → v0/lm}/structured_outputs/handler.py +5 -5
  243. synth_ai/{lm → v0/lm}/structured_outputs/rehabilitate.py +1 -1
  244. synth_ai/{lm → v0/lm}/vendors/core/anthropic_api.py +16 -16
  245. synth_ai/{lm → v0/lm}/vendors/core/gemini_api.py +5 -5
  246. synth_ai/{lm → v0/lm}/vendors/core/mistral_api.py +5 -5
  247. synth_ai/{lm → v0/lm}/vendors/core/openai_api.py +12 -10
  248. synth_ai/{lm → v0/lm}/vendors/openai_standard.py +11 -9
  249. synth_ai/{lm → v0/lm}/vendors/openai_standard_responses.py +8 -5
  250. synth_ai/{lm → v0/lm}/vendors/supported/custom_endpoint.py +4 -6
  251. synth_ai/{lm → v0/lm}/vendors/supported/deepseek.py +2 -2
  252. synth_ai/{lm → v0/lm}/vendors/supported/grok.py +2 -2
  253. synth_ai/{lm → v0/lm}/vendors/supported/groq.py +1 -1
  254. synth_ai/{lm → v0/lm}/vendors/supported/ollama.py +1 -1
  255. synth_ai/{lm → v0/lm}/vendors/supported/openrouter.py +3 -3
  256. synth_ai/{lm → v0/lm}/vendors/supported/together.py +1 -1
  257. synth_ai/{lm → v0/lm}/vendors/synth_client.py +38 -11
  258. synth_ai/v0/tracing/upload.py +32 -135
  259. synth_ai/v0/tracing_v3/__init__.py +10 -0
  260. synth_ai/v0/tracing_v3/abstractions.py +3 -0
  261. synth_ai/v0/tracing_v3/decorators.py +3 -0
  262. synth_ai/v0/tracing_v3/llm_call_record_helpers.py +3 -0
  263. synth_ai/v0/tracing_v3/session_tracer.py +3 -0
  264. {synth_ai-0.2.9.dev5.dist-info → synth_ai-0.2.10.dist-info}/METADATA +10 -7
  265. {synth_ai-0.2.9.dev5.dist-info → synth_ai-0.2.10.dist-info}/RECORD +294 -258
  266. examples/common_old/backend.py +0 -21
  267. examples/evals_old/README.md +0 -98
  268. examples/evals_old/__init__.py +0 -6
  269. examples/evals_old/compare_models.py +0 -1037
  270. examples/evals_old/example_log.md +0 -145
  271. examples/evals_old/run_demo.sh +0 -126
  272. examples/evals_old/trace_analysis.py +0 -270
  273. examples/finetuning_old/_backup_synth_qwen/config.toml +0 -29
  274. examples/finetuning_old/_backup_synth_qwen/example_log.md +0 -324
  275. examples/finetuning_old/_backup_synth_qwen/filter_traces.py +0 -60
  276. examples/finetuning_old/_backup_synth_qwen/filter_traces_achievements.py +0 -239
  277. examples/finetuning_old/_backup_synth_qwen/purge_v3_traces.py +0 -109
  278. examples/finetuning_old/_backup_synth_qwen/react_agent_lm.py +0 -1924
  279. examples/finetuning_old/_backup_synth_qwen/readme.md +0 -49
  280. examples/finetuning_old/_backup_synth_qwen/run_crafter_qwen4b.py +0 -114
  281. examples/finetuning_old/_backup_synth_qwen/run_demo.sh +0 -195
  282. examples/finetuning_old/_backup_synth_qwen/sft_kickoff.py +0 -118
  283. examples/finetuning_old/synth_qwen_v1/README.md +0 -68
  284. examples/finetuning_old/synth_qwen_v1/filter_traces.py +0 -60
  285. examples/finetuning_old/synth_qwen_v1/filter_traces_achievements.py +0 -239
  286. examples/finetuning_old/synth_qwen_v1/finetune.py +0 -46
  287. examples/finetuning_old/synth_qwen_v1/hello_ft_model.py +0 -71
  288. examples/finetuning_old/synth_qwen_v1/infer.py +0 -37
  289. examples/finetuning_old/synth_qwen_v1/poll.py +0 -44
  290. examples/finetuning_old/synth_qwen_v1/prepare_data.py +0 -35
  291. examples/finetuning_old/synth_qwen_v1/purge_v3_traces.py +0 -109
  292. examples/finetuning_old/synth_qwen_v1/react_agent_lm.py +0 -1932
  293. examples/finetuning_old/synth_qwen_v1/run_crafter_sft_job.py +0 -207
  294. examples/finetuning_old/synth_qwen_v1/run_ft_job.py +0 -232
  295. examples/finetuning_old/synth_qwen_v1/upload_data.py +0 -34
  296. examples/finetuning_old/synth_qwen_v1/util.py +0 -147
  297. examples/rl_old/task_app.py +0 -962
  298. synth_ai/experimental/synth_oss.py +0 -446
  299. synth_ai/install_sqld.sh +0 -40
  300. synth_ai/learning/filtering.py +0 -0
  301. synth_ai/learning/offline/dpo.py +0 -0
  302. synth_ai/learning/offline/providers.py +0 -7
  303. synth_ai/learning/offline/sft.py +0 -0
  304. synth_ai/learning/offline/shared.py +0 -0
  305. synth_ai/learning/online/grpo.py +0 -0
  306. synth_ai/learning/online/irft.py +0 -0
  307. synth_ai/learning/prompts/banking77_injection_eval.py +0 -168
  308. synth_ai/learning/prompts/gepa.py +0 -0
  309. synth_ai/learning/prompts/hello_world_in_context_injection_ex.py +0 -213
  310. synth_ai/learning/prompts/mipro.py +0 -289
  311. synth_ai/learning/prompts/random_search.py +0 -246
  312. synth_ai/learning/prompts/run_mipro_banking77.py +0 -172
  313. synth_ai/learning/prompts/run_random_search_banking77.py +0 -324
  314. synth_ai/rl/secrets.py +0 -19
  315. synth_ai/scripts/verify_rewards.py +0 -100
  316. synth_ai/tracing/__init__.py +0 -30
  317. synth_ai/tracing_v1/__init__.py +0 -33
  318. synth_ai/tracing_v3/turso/__init__.py +0 -25
  319. synth_ai/tracing_v3/turso/manager.py +0 -774
  320. synth_ai/zyk/__init__.py +0 -30
  321. /synth_ai/{lm → v0/lm}/caching/__init__.py +0 -0
  322. /synth_ai/{lm → v0/lm}/caching/constants.py +0 -0
  323. /synth_ai/{lm → v0/lm}/caching/dbs.py +0 -0
  324. /synth_ai/{lm → v0/lm}/constants.py +0 -0
  325. /synth_ai/{lm → v0/lm}/core/__init__.py +0 -0
  326. /synth_ai/{lm → v0/lm}/cost/__init__.py +0 -0
  327. /synth_ai/{lm → v0/lm}/cost/monitor.py +0 -0
  328. /synth_ai/{lm → v0/lm}/cost/statefulness.py +0 -0
  329. /synth_ai/{lm → v0/lm}/injection.py +0 -0
  330. /synth_ai/{lm → v0/lm}/provider_support/__init__.py +0 -0
  331. /synth_ai/{lm → v0/lm}/provider_support/suppress_logging.py +0 -0
  332. /synth_ai/{lm → v0/lm}/structured_outputs/__init__.py +0 -0
  333. /synth_ai/{lm → v0/lm}/structured_outputs/inject.py +0 -0
  334. /synth_ai/{lm → v0/lm}/tools/__init__.py +0 -0
  335. /synth_ai/{lm → v0/lm}/tools/base.py +0 -0
  336. /synth_ai/{lm → v0/lm}/unified_interface.py +0 -0
  337. /synth_ai/{lm → v0/lm}/vendors/__init__.py +0 -0
  338. /synth_ai/{lm → v0/lm}/vendors/base.py +0 -0
  339. /synth_ai/{lm → v0/lm}/vendors/core/__init__.py +0 -0
  340. /synth_ai/{lm → v0/lm}/vendors/core/synth_dev_api.py +0 -0
  341. /synth_ai/{lm → v0/lm}/vendors/local/__init__.py +0 -0
  342. /synth_ai/{lm → v0/lm}/vendors/local/ollama.py +0 -0
  343. /synth_ai/{lm → v0/lm}/vendors/retries.py +0 -0
  344. /synth_ai/{lm → v0/lm}/vendors/supported/__init__.py +0 -0
  345. /synth_ai/{lm → v0/lm}/warmup.py +0 -0
  346. {synth_ai-0.2.9.dev5.dist-info → synth_ai-0.2.10.dist-info}/WHEEL +0 -0
  347. {synth_ai-0.2.9.dev5.dist-info → synth_ai-0.2.10.dist-info}/entry_points.txt +0 -0
  348. {synth_ai-0.2.9.dev5.dist-info → synth_ai-0.2.10.dist-info}/licenses/LICENSE +0 -0
  349. {synth_ai-0.2.9.dev5.dist-info → synth_ai-0.2.10.dist-info}/top_level.txt +0 -0
@@ -2,4 +2,4 @@
2
2
 
3
3
  from .volume import VolumeStorage, storage
4
4
 
5
- __all__ = ["VolumeStorage", "storage"]
5
+ __all__ = ["VolumeStorage", "storage"]
@@ -8,15 +8,15 @@ import tarfile
8
8
  import tempfile
9
9
  from datetime import datetime
10
10
  from pathlib import Path
11
- from typing import Any, Dict, Optional
11
+ from typing import Any
12
12
 
13
13
 
14
14
  class VolumeStorage:
15
15
  """Helpers for Modal Volume storage operations."""
16
-
16
+
17
17
  def __init__(self, base_path: str = "/data/state") -> None:
18
18
  self.base_path = Path(base_path)
19
-
19
+
20
20
  def get_snapshot_path(
21
21
  self,
22
22
  rl_run_id: str,
@@ -27,21 +27,15 @@ class VolumeStorage:
27
27
  # Use first 2 chars of snapshot_id for sharding
28
28
  shard1 = snapshot_id[:2] if len(snapshot_id) >= 2 else "00"
29
29
  shard2 = snapshot_id[2:4] if len(snapshot_id) >= 4 else "00"
30
-
30
+
31
31
  return (
32
- self.base_path
33
- / "runs"
34
- / rl_run_id
35
- / kind
36
- / shard1
37
- / shard2
38
- / f"{snapshot_id}.tar.gz"
32
+ self.base_path / "runs" / rl_run_id / kind / shard1 / shard2 / f"{snapshot_id}.tar.gz"
39
33
  )
40
-
34
+
41
35
  def get_index_path(self, rl_run_id: str) -> Path:
42
36
  """Get the index file path for a run."""
43
37
  return self.base_path / "runs" / rl_run_id / "index" / "meta.jsonl"
44
-
38
+
45
39
  def write_snapshot_atomic(
46
40
  self,
47
41
  path: Path,
@@ -50,87 +44,87 @@ class VolumeStorage:
50
44
  """Atomically write a snapshot archive to disk."""
51
45
  # Ensure parent directory exists
52
46
  path.parent.mkdir(parents=True, exist_ok=True)
53
-
47
+
54
48
  # Write to temp file first
55
49
  tmp_path = path.with_suffix(".tmp")
56
50
  with open(tmp_path, "wb") as f:
57
51
  f.write(archive_bytes)
58
52
  f.flush()
59
53
  os.fsync(f.fileno())
60
-
54
+
61
55
  # Atomic rename
62
56
  os.replace(tmp_path, path)
63
-
57
+
64
58
  def create_archive(
65
59
  self,
66
- state_dict: Dict[str, Any],
67
- meta: Dict[str, Any],
60
+ state_dict: dict[str, Any],
61
+ meta: dict[str, Any],
68
62
  ) -> bytes:
69
63
  """Create a tar.gz archive with state and metadata."""
70
64
  with tempfile.TemporaryDirectory() as tmpdir:
71
65
  tmppath = Path(tmpdir)
72
-
66
+
73
67
  # Write state.json
74
68
  state_path = tmppath / "state.json"
75
69
  with open(state_path, "w") as f:
76
70
  json.dump(state_dict, f, sort_keys=True, indent=2)
77
-
71
+
78
72
  # Write meta.json
79
73
  meta_path = tmppath / "meta.json"
80
74
  with open(meta_path, "w") as f:
81
75
  json.dump(meta, f, sort_keys=True, indent=2)
82
-
76
+
83
77
  # Create tar archive
84
78
  tar_path = tmppath / "archive.tar"
85
79
  with tarfile.open(tar_path, "w") as tar:
86
80
  tar.add(state_path, arcname="state.json")
87
81
  tar.add(meta_path, arcname="meta.json")
88
-
82
+
89
83
  # Compress with gzip
90
84
  with open(tar_path, "rb") as f:
91
85
  tar_bytes = f.read()
92
-
86
+
93
87
  compressed = gzip.compress(tar_bytes, compresslevel=6)
94
-
88
+
95
89
  return compressed
96
-
97
- def extract_archive(self, archive_bytes: bytes) -> tuple[Dict[str, Any], Dict[str, Any]]:
90
+
91
+ def extract_archive(self, archive_bytes: bytes) -> tuple[dict[str, Any], dict[str, Any]]:
98
92
  """Extract state and metadata from a tar.gz archive."""
99
93
  # Decompress
100
94
  tar_bytes = gzip.decompress(archive_bytes)
101
-
95
+
102
96
  with tempfile.TemporaryDirectory() as tmpdir:
103
97
  tmppath = Path(tmpdir)
104
-
98
+
105
99
  # Write tar bytes to temp file
106
100
  tar_path = tmppath / "archive.tar"
107
101
  with open(tar_path, "wb") as f:
108
102
  f.write(tar_bytes)
109
-
103
+
110
104
  # Extract tar
111
105
  with tarfile.open(tar_path, "r") as tar:
112
106
  tar.extractall(tmppath)
113
-
107
+
114
108
  # Read state and meta
115
- with open(tmppath / "state.json", "r") as f:
109
+ with open(tmppath / "state.json") as f:
116
110
  state = json.load(f)
117
-
118
- with open(tmppath / "meta.json", "r") as f:
111
+
112
+ with open(tmppath / "meta.json") as f:
119
113
  meta = json.load(f)
120
-
114
+
121
115
  return state, meta
122
-
116
+
123
117
  def compute_snapshot_id(self, archive_bytes: bytes) -> str:
124
118
  """Compute content-addressed snapshot ID."""
125
119
  return hashlib.sha256(archive_bytes).hexdigest()
126
-
120
+
127
121
  def save_snapshot(
128
122
  self,
129
123
  rl_run_id: str,
130
124
  kind: str,
131
- state_dict: Dict[str, Any],
132
- config: Optional[Dict[str, Any]] = None,
133
- parent_snapshot_id: Optional[str] = None,
125
+ state_dict: dict[str, Any],
126
+ config: dict[str, Any] | None = None,
127
+ parent_snapshot_id: str | None = None,
134
128
  ) -> tuple[str, str, int]:
135
129
  """Save a snapshot and return (snapshot_id, path, size)."""
136
130
  # Build metadata
@@ -140,78 +134,78 @@ class VolumeStorage:
140
134
  "schema_version": "1.0",
141
135
  "created_at": datetime.utcnow().isoformat(),
142
136
  }
143
-
137
+
144
138
  if parent_snapshot_id:
145
139
  meta["parent_snapshot_id"] = parent_snapshot_id
146
-
140
+
147
141
  if config:
148
142
  config_str = json.dumps(config, sort_keys=True)
149
143
  meta["config_hash"] = hashlib.sha256(config_str.encode()).hexdigest()
150
-
144
+
151
145
  # Create archive
152
146
  archive_bytes = self.create_archive(state_dict, meta)
153
-
147
+
154
148
  # Compute snapshot ID
155
149
  snapshot_id = self.compute_snapshot_id(archive_bytes)
156
150
  meta["snapshot_id"] = snapshot_id
157
-
151
+
158
152
  # Recreate archive with snapshot_id in metadata
159
153
  archive_bytes = self.create_archive(state_dict, meta)
160
-
154
+
161
155
  # Get path and write
162
156
  path = self.get_snapshot_path(rl_run_id, kind, snapshot_id)
163
157
  self.write_snapshot_atomic(path, archive_bytes)
164
-
158
+
165
159
  # Append to index
166
160
  self.append_to_index(rl_run_id, meta)
167
-
161
+
168
162
  return snapshot_id, str(path), len(archive_bytes)
169
-
163
+
170
164
  def load_snapshot(
171
165
  self,
172
166
  rl_run_id: str,
173
167
  kind: str,
174
168
  snapshot_id: str,
175
- ) -> tuple[Dict[str, Any], Dict[str, Any]]:
169
+ ) -> tuple[dict[str, Any], dict[str, Any]]:
176
170
  """Load a snapshot and return (state_dict, meta)."""
177
171
  path = self.get_snapshot_path(rl_run_id, kind, snapshot_id)
178
-
172
+
179
173
  if not path.exists():
180
174
  raise FileNotFoundError(f"Snapshot not found: {path}")
181
-
175
+
182
176
  with open(path, "rb") as f:
183
177
  archive_bytes = f.read()
184
-
178
+
185
179
  state, meta = self.extract_archive(archive_bytes)
186
180
  return state, meta
187
-
181
+
188
182
  def append_to_index(
189
183
  self,
190
184
  rl_run_id: str,
191
- meta: Dict[str, Any],
185
+ meta: dict[str, Any],
192
186
  ) -> None:
193
187
  """Append metadata to the run's index file."""
194
188
  index_path = self.get_index_path(rl_run_id)
195
189
  index_path.parent.mkdir(parents=True, exist_ok=True)
196
-
190
+
197
191
  with open(index_path, "a") as f:
198
192
  f.write(json.dumps(meta) + "\n")
199
-
200
- def read_index(self, rl_run_id: str) -> list[Dict[str, Any]]:
193
+
194
+ def read_index(self, rl_run_id: str) -> list[dict[str, Any]]:
201
195
  """Read all entries from a run's index file."""
202
196
  index_path = self.get_index_path(rl_run_id)
203
-
197
+
204
198
  if not index_path.exists():
205
199
  return []
206
-
200
+
207
201
  entries = []
208
- with open(index_path, "r") as f:
202
+ with open(index_path) as f:
209
203
  for line in f:
210
204
  if line.strip():
211
205
  entries.append(json.loads(line))
212
-
206
+
213
207
  return entries
214
208
 
215
209
 
216
210
  # Global storage instance
217
- storage = VolumeStorage()
211
+ storage = VolumeStorage()
@@ -16,6 +16,7 @@ This script will:
16
16
 
17
17
  import asyncio
18
18
  import os
19
+
19
20
  import httpx
20
21
 
21
22
  BASE_URL = os.environ.get("SYNTH_ENVS_HOSTED_URL", "http://localhost:8000")
@@ -8,6 +8,7 @@ Run this after starting the service with:
8
8
 
9
9
  import asyncio
10
10
  import json
11
+
11
12
  import httpx
12
13
 
13
14
 
@@ -82,15 +83,11 @@ async def test_service():
82
83
  print(f" Error: {response.status_code} - {response.text}")
83
84
  else:
84
85
  step_data = response.json()
85
- print(
86
- f" Step result - done: {step_data['done']}, reward: {step_data.get('reward')}"
87
- )
86
+ print(f" Step result - done: {step_data['done']}, reward: {step_data.get('reward')}")
88
87
 
89
88
  # Test 6: Environment snapshot
90
89
  print("\n6. Creating environment snapshot...")
91
- response = await client.post(
92
- f"{base_url}/env/snapshot", json={"env_id": env_id}
93
- )
90
+ response = await client.post(f"{base_url}/env/snapshot", json={"env_id": env_id})
94
91
  if response.status_code != 200:
95
92
  print(f" Error: {response.status_code} - {response.text}")
96
93
  else:
@@ -100,9 +97,7 @@ async def test_service():
100
97
 
101
98
  # Test 7: Policy snapshot
102
99
  print("\n7. Creating policy snapshot...")
103
- response = await client.post(
104
- f"{base_url}/policy/snapshot", json={"policy_id": policy_id}
105
- )
100
+ response = await client.post(f"{base_url}/policy/snapshot", json={"policy_id": policy_id})
106
101
  if response.status_code != 200:
107
102
  print(f" Error: {response.status_code} - {response.text}")
108
103
  else:
@@ -121,9 +116,7 @@ async def test_service():
121
116
 
122
117
  # Test 9: Terminate environment
123
118
  print("\n9. Terminating environment...")
124
- response = await client.post(
125
- f"{base_url}/env/terminate", json={"env_id": env_id}
126
- )
119
+ response = await client.post(f"{base_url}/env/terminate", json={"env_id": env_id})
127
120
  if response.status_code != 200:
128
121
  print(f" Error: {response.status_code} - {response.text}")
129
122
  else:
@@ -131,9 +124,7 @@ async def test_service():
131
124
 
132
125
  # Test 10: Terminate policy
133
126
  print("\n10. Terminating policy...")
134
- response = await client.post(
135
- f"{base_url}/policy/terminate", json={"policy_id": policy_id}
136
- )
127
+ response = await client.post(f"{base_url}/policy/terminate", json={"policy_id": policy_id})
137
128
  if response.status_code != 200:
138
129
  print(f" Error: {response.status_code} - {response.text}")
139
130
  else:
@@ -1,7 +1,8 @@
1
1
  """Utility functions for the task service."""
2
2
 
3
+ from typing import Any
4
+
3
5
  import numpy as np
4
- from typing import Any, Dict, List, Union
5
6
 
6
7
 
7
8
  def convert_numpy_to_python(obj: Any) -> Any:
@@ -22,13 +23,13 @@ def convert_numpy_to_python(obj: Any) -> Any:
22
23
  return obj.tolist()
23
24
  elif isinstance(obj, dict):
24
25
  return {key: convert_numpy_to_python(value) for key, value in obj.items()}
25
- elif isinstance(obj, (list, tuple)):
26
+ elif isinstance(obj, list | tuple):
26
27
  return [convert_numpy_to_python(item) for item in obj]
27
28
  else:
28
29
  return obj
29
30
 
30
31
 
31
- def sanitize_observation(observation: Dict[str, Any]) -> Dict[str, Any]:
32
+ def sanitize_observation(observation: dict[str, Any]) -> dict[str, Any]:
32
33
  """
33
34
  Sanitize observation data for JSON serialization.
34
35
 
synth_ai/__init__.py CHANGED
@@ -5,6 +5,7 @@ Synth AI - Software for aiding the best and multiplying the will.
5
5
  # Environment exports - moved from synth-env
6
6
  from synth_ai.environments import * # noqa
7
7
  import synth_ai.environments as environments # expose module name for __all__
8
+
8
9
  try:
9
10
  from synth_ai.lm.core.main import LM # Moved from zyk to lm for better organization
10
11
  except Exception: # allow minimal imports (e.g., tracing) without LM stack