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
synth_ai/cli/rl_demo.py CHANGED
@@ -20,6 +20,7 @@ import click
20
20
 
21
21
  def _forward(args: list[str]) -> None:
22
22
  import sys
23
+
23
24
  try:
24
25
  from synth_ai.demos.core import cli as demo_cli # type: ignore
25
26
  except Exception as e: # pragma: no cover
@@ -36,7 +37,9 @@ def register(cli):
36
37
  """RL Demo commands (separate from legacy demo)."""
37
38
 
38
39
  # Help pyright understand dynamic Click group attributes
39
- from typing import Any, cast as _cast
40
+ from typing import Any
41
+ from typing import cast as _cast
42
+
40
43
  _rlg = _cast(Any, rl_demo)
41
44
 
42
45
  @_rlg.command("setup")
@@ -47,9 +50,19 @@ def register(cli):
47
50
 
48
51
  @_rlg.command("deploy")
49
52
  @click.option("--local", is_flag=True, help="Run local FastAPI instead of Modal deploy")
50
- @click.option("--app", type=click.Path(), default=None, help="Path to Modal app.py for uv run modal deploy")
53
+ @click.option(
54
+ "--app",
55
+ type=click.Path(),
56
+ default=None,
57
+ help="Path to Modal app.py for uv run modal deploy",
58
+ )
51
59
  @click.option("--name", type=str, default="synth-math-demo", help="Modal app name")
52
- @click.option("--script", type=click.Path(), default=None, help="Path to deploy_task_app.sh (optional legacy)")
60
+ @click.option(
61
+ "--script",
62
+ type=click.Path(),
63
+ default=None,
64
+ help="Path to deploy_task_app.sh (optional legacy)",
65
+ )
53
66
  def rl_deploy(local: bool, app: str | None, name: str, script: str | None):
54
67
  args: list[str] = ["rl_demo.deploy"]
55
68
  if local:
@@ -64,7 +77,7 @@ def register(cli):
64
77
 
65
78
  @_rlg.command("configure")
66
79
  def rl_configure():
67
- _forward(["rl_demo.configure"])
80
+ _forward(["rl_demo.configure"])
68
81
 
69
82
  @_rlg.command("init")
70
83
  @click.option("--template", type=str, default=None, help="Template id to instantiate")
@@ -81,13 +94,22 @@ def register(cli):
81
94
  _forward(args)
82
95
 
83
96
  @_rlg.command("run")
84
- @click.option("--config", type=click.Path(), default=None, help="Path to TOML config (skip prompt)")
97
+ @click.option(
98
+ "--config", type=click.Path(), default=None, help="Path to TOML config (skip prompt)"
99
+ )
85
100
  @click.option("--batch-size", type=int, default=None)
86
101
  @click.option("--group-size", type=int, default=None)
87
102
  @click.option("--model", type=str, default=None)
88
103
  @click.option("--timeout", type=int, default=600)
89
104
  @click.option("--dry-run", is_flag=True, help="Print request body and exit")
90
- def rl_run(config: str | None, batch_size: int | None, group_size: int | None, model: str | None, timeout: int, dry_run: bool):
105
+ def rl_run(
106
+ config: str | None,
107
+ batch_size: int | None,
108
+ group_size: int | None,
109
+ model: str | None,
110
+ timeout: int,
111
+ dry_run: bool,
112
+ ):
91
113
  args = ["rl_demo.run"]
92
114
  if config:
93
115
  args.extend(["--config", config])
@@ -106,19 +128,29 @@ def register(cli):
106
128
  # Dotted aliases (top-level): legacy check → setup
107
129
  @cli.command("rl_demo.check")
108
130
  def rl_check_alias():
109
- _forward(["rl_demo.setup"])
131
+ _forward(["rl_demo.setup"])
110
132
 
111
133
  @cli.command("rl_demo.setup")
112
134
  def rl_setup_alias():
113
- _forward(["rl_demo.setup"])
135
+ _forward(["rl_demo.setup"])
114
136
 
115
137
  # (prepare alias removed)
116
138
 
117
139
  @cli.command("rl_demo.deploy")
118
140
  @click.option("--local", is_flag=True, help="Run local FastAPI instead of Modal deploy")
119
- @click.option("--app", type=click.Path(), default=None, help="Path to Modal app.py for uv run modal deploy")
141
+ @click.option(
142
+ "--app",
143
+ type=click.Path(),
144
+ default=None,
145
+ help="Path to Modal app.py for uv run modal deploy",
146
+ )
120
147
  @click.option("--name", type=str, default="synth-math-demo", help="Modal app name")
121
- @click.option("--script", type=click.Path(), default=None, help="Path to deploy_task_app.sh (optional legacy)")
148
+ @click.option(
149
+ "--script",
150
+ type=click.Path(),
151
+ default=None,
152
+ help="Path to deploy_task_app.sh (optional legacy)",
153
+ )
122
154
  def rl_deploy_alias(local: bool, app: str | None, name: str, script: str | None):
123
155
  args: list[str] = ["rl_demo.deploy"]
124
156
  if local:
@@ -133,7 +165,7 @@ def register(cli):
133
165
 
134
166
  @cli.command("rl_demo.configure")
135
167
  def rl_configure_alias():
136
- _forward(["rl_demo.configure"])
168
+ _forward(["rl_demo.configure"])
137
169
 
138
170
  @cli.command("rl_demo.init")
139
171
  @click.option("--template", type=str, default=None, help="Template id to instantiate")
@@ -150,13 +182,22 @@ def register(cli):
150
182
  _forward(args)
151
183
 
152
184
  @cli.command("rl_demo.run")
153
- @click.option("--config", type=click.Path(), default=None, help="Path to TOML config (skip prompt)")
185
+ @click.option(
186
+ "--config", type=click.Path(), default=None, help="Path to TOML config (skip prompt)"
187
+ )
154
188
  @click.option("--batch-size", type=int, default=None)
155
189
  @click.option("--group-size", type=int, default=None)
156
190
  @click.option("--model", type=str, default=None)
157
191
  @click.option("--timeout", type=int, default=600)
158
192
  @click.option("--dry-run", is_flag=True, help="Print request body and exit")
159
- def rl_run_alias(config: str | None, batch_size: int | None, group_size: int | None, model: str | None, timeout: int, dry_run: bool):
193
+ def rl_run_alias(
194
+ config: str | None,
195
+ batch_size: int | None,
196
+ group_size: int | None,
197
+ model: str | None,
198
+ timeout: int,
199
+ dry_run: bool,
200
+ ):
160
201
  args = ["rl_demo.run"]
161
202
  if config:
162
203
  args.extend(["--config", config])
@@ -175,9 +216,19 @@ def register(cli):
175
216
  # Top-level convenience alias: `synth-ai deploy`
176
217
  @cli.command("demo-deploy")
177
218
  @click.option("--local", is_flag=True, help="Run local FastAPI instead of Modal deploy")
178
- @click.option("--app", type=click.Path(), default=None, help="Path to Modal app.py for uv run modal deploy")
219
+ @click.option(
220
+ "--app",
221
+ type=click.Path(),
222
+ default=None,
223
+ help="Path to Modal app.py for uv run modal deploy",
224
+ )
179
225
  @click.option("--name", type=str, default="synth-math-demo", help="Modal app name")
180
- @click.option("--script", type=click.Path(), default=None, help="Path to deploy_task_app.sh (optional legacy)")
226
+ @click.option(
227
+ "--script",
228
+ type=click.Path(),
229
+ default=None,
230
+ help="Path to deploy_task_app.sh (optional legacy)",
231
+ )
181
232
  def deploy_demo(local: bool, app: str | None, name: str, script: str | None):
182
233
  args: list[str] = ["rl_demo.deploy"]
183
234
  if local:
@@ -191,13 +242,22 @@ def register(cli):
191
242
  _forward(args)
192
243
 
193
244
  @cli.command("run")
194
- @click.option("--config", type=click.Path(), default=None, help="Path to TOML config (skip prompt)")
245
+ @click.option(
246
+ "--config", type=click.Path(), default=None, help="Path to TOML config (skip prompt)"
247
+ )
195
248
  @click.option("--batch-size", type=int, default=None)
196
249
  @click.option("--group-size", type=int, default=None)
197
250
  @click.option("--model", type=str, default=None)
198
251
  @click.option("--timeout", type=int, default=600)
199
252
  @click.option("--dry-run", is_flag=True, help="Print request body and exit")
200
- def run_top(config: str | None, batch_size: int | None, group_size: int | None, model: str | None, timeout: int, dry_run: bool):
253
+ def run_top(
254
+ config: str | None,
255
+ batch_size: int | None,
256
+ group_size: int | None,
257
+ model: str | None,
258
+ timeout: int,
259
+ dry_run: bool,
260
+ ):
201
261
  args = ["run"]
202
262
  if config:
203
263
  args.extend(["--config", config])
synth_ai/cli/root.py CHANGED
@@ -5,17 +5,23 @@ Canonical CLI entrypoint for Synth AI (moved from synth_ai/cli.py).
5
5
 
6
6
  from __future__ import annotations
7
7
 
8
+ import contextlib
8
9
  import logging
9
10
  import os
10
11
  import shutil
11
12
  import signal
13
+ import socket
12
14
  import subprocess
13
15
  import sys
16
+ import tempfile
14
17
  import time
15
18
 
16
19
  import click
20
+
17
21
  try:
18
- from importlib.metadata import PackageNotFoundError, version as _pkg_version
22
+ from importlib.metadata import PackageNotFoundError
23
+ from importlib.metadata import version as _pkg_version
24
+
19
25
  try:
20
26
  __pkg_version__ = _pkg_version("synth-ai")
21
27
  except PackageNotFoundError:
@@ -30,6 +36,9 @@ except Exception:
30
36
  __pkg_version__ = "unknown"
31
37
 
32
38
 
39
+ SQLD_VERSION = "v0.26.2"
40
+
41
+
33
42
  def find_sqld_binary() -> str | None:
34
43
  sqld_path = shutil.which("sqld")
35
44
  if sqld_path:
@@ -39,6 +48,7 @@ def find_sqld_binary() -> str | None:
39
48
  "/usr/bin/sqld",
40
49
  os.path.expanduser("~/.local/bin/sqld"),
41
50
  os.path.expanduser("~/bin/sqld"),
51
+ os.path.expanduser("~/.turso/bin/sqld"),
42
52
  ]
43
53
  for path in common_paths:
44
54
  if os.path.exists(path) and os.access(path, os.X_OK):
@@ -47,40 +57,100 @@ def find_sqld_binary() -> str | None:
47
57
 
48
58
 
49
59
  def install_sqld() -> str:
50
- click.echo("🔧 sqld not found. Installing...")
51
- script = """#!/bin/bash
52
- set -e
53
- SQLD_VERSION="v0.26.2"
54
- OS=$(uname -s | tr '[:upper:]' '[:lower:]')
55
- ARCH=$(uname -m)
56
- case "$ARCH" in
57
- x86_64) ARCH="x86_64" ;;
58
- aarch64|arm64) ARCH="aarch64" ;;
59
- *) echo "Unsupported architecture: $ARCH"; exit 1 ;;
60
- esac
61
- URL="https://github.com/tursodatabase/libsql/releases/download/libsql-server-${SQLD_VERSION}/sqld-${OS}-${ARCH}.tar.xz"
62
- TMP_DIR=$(mktemp -d)
63
- cd "$TMP_DIR"
64
- curl -L -o sqld.tar.xz "$URL"
65
- tar -xf sqld.tar.xz
66
- mkdir -p ~/.local/bin
67
- mv sqld ~/.local/bin/
68
- chmod +x ~/.local/bin/sqld
69
- cd -
70
- rm -rf "$TMP_DIR"
71
- """
72
- path = "/tmp/install_sqld.sh"
73
- with open(path, "w") as f:
74
- f.write(script)
75
- subprocess.run(["bash", path], check=True)
76
- os.unlink(path)
77
- local_bin = os.path.expanduser("~/.local/bin")
78
- if local_bin not in os.environ.get("PATH", ""):
79
- os.environ["PATH"] = f"{local_bin}:{os.environ.get('PATH', '')}"
80
- return os.path.expanduser("~/.local/bin/sqld")
81
-
82
-
83
- @click.group(help=f"Synth AI v{__pkg_version__} - Software for aiding the best and multiplying the will.")
60
+ """Install sqld via the Turso CLI, installing the CLI via Homebrew if needed."""
61
+
62
+ click.echo("🔧 sqld not found. Attempting automatic install...")
63
+
64
+ turso_cli_path = shutil.which("turso")
65
+ brew_path = shutil.which("brew")
66
+
67
+ if not turso_cli_path:
68
+ if not brew_path:
69
+ raise click.ClickException(
70
+ "Automatic install requires either Homebrew or an existing Turso CLI.\n"
71
+ "Install manually using one of:\n"
72
+ " • brew install tursodatabase/tap/turso\n"
73
+ " • curl -sSfL https://get.tur.so/install.sh | bash\n"
74
+ "Then run 'turso dev' once and re-run this command."
75
+ )
76
+
77
+ click.echo("🧰 Installing Turso CLI via Homebrew (tursodatabase/tap/turso)…")
78
+ try:
79
+ subprocess.run(
80
+ [brew_path, "install", "tursodatabase/tap/turso"],
81
+ check=True,
82
+ )
83
+ except subprocess.CalledProcessError as exc:
84
+ raise click.ClickException(
85
+ "Homebrew install failed. Please resolve brew errors and retry."
86
+ ) from exc
87
+
88
+ turso_cli_path = shutil.which("turso")
89
+ if not turso_cli_path:
90
+ raise click.ClickException(
91
+ "Homebrew reported success but the 'turso' binary is not on PATH."
92
+ )
93
+
94
+ click.echo("📥 Downloading sqld via 'turso dev' (this may take a few seconds)…")
95
+
96
+ with tempfile.NamedTemporaryFile(prefix="synth_sqld_", suffix=".db", delete=False) as temp_db:
97
+ temp_db_path = temp_db.name
98
+
99
+ env = os.environ.copy()
100
+ env.setdefault("TURSO_NONINTERACTIVE", "1")
101
+
102
+ with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
103
+ sock.bind(("127.0.0.1", 0))
104
+ port = sock.getsockname()[1]
105
+
106
+ cmd = [
107
+ turso_cli_path,
108
+ "dev",
109
+ f"--db-file={temp_db_path}",
110
+ f"--port={port}",
111
+ ]
112
+ proc: subprocess.Popen[str] | None = None
113
+ stdout_data = ""
114
+ stderr_data = ""
115
+ try:
116
+ proc = subprocess.Popen(
117
+ cmd,
118
+ stdout=subprocess.PIPE,
119
+ stderr=subprocess.PIPE,
120
+ text=True,
121
+ env=env,
122
+ )
123
+ try:
124
+ stdout_data, stderr_data = proc.communicate(timeout=10)
125
+ except subprocess.TimeoutExpired:
126
+ proc.terminate()
127
+ try:
128
+ stdout_data, stderr_data = proc.communicate(timeout=5)
129
+ except subprocess.TimeoutExpired:
130
+ proc.kill()
131
+ stdout_data, stderr_data = proc.communicate()
132
+ finally:
133
+ if proc and proc.returncode not in (0, None) and (stdout_data or stderr_data):
134
+ logging.getLogger(__name__).debug(
135
+ "turso dev stdout: %s\nstderr: %s", stdout_data, stderr_data
136
+ )
137
+ with contextlib.suppress(OSError):
138
+ os.unlink(temp_db_path)
139
+
140
+ sqld_path = find_sqld_binary()
141
+ if sqld_path:
142
+ click.echo(f"✅ sqld available at {sqld_path}")
143
+ return sqld_path
144
+
145
+ raise click.ClickException(
146
+ "sqld download did not succeed. Run 'turso dev' manually once, "
147
+ "ensure it downloads sqld, and try again."
148
+ )
149
+
150
+
151
+ @click.group(
152
+ help=f"Synth AI v{__pkg_version__} - Software for aiding the best and multiplying the will."
153
+ )
84
154
  @click.version_option(version=__pkg_version__, prog_name="synth-ai")
85
155
  def cli():
86
156
  """Top-level command group for Synth AI."""
@@ -99,7 +169,7 @@ def _forward_to_demo(args: list[str]) -> None:
99
169
  except Exception as e: # pragma: no cover
100
170
  click.echo(f"Failed to import demo CLI: {e}")
101
171
  sys.exit(1)
102
- rc = int(getattr(demo_cli, "main")(args) or 0) # type: ignore[attr-defined]
172
+ rc = int(demo_cli.main(args) or 0) # type: ignore[attr-defined]
103
173
  if rc != 0:
104
174
  sys.exit(rc)
105
175
 
@@ -109,9 +179,13 @@ def _forward_to_demo(args: list[str]) -> None:
109
179
 
110
180
  @demo.command()
111
181
  @click.option("--local", is_flag=True, help="Run local FastAPI instead of Modal deploy")
112
- @click.option("--app", type=click.Path(), default=None, help="Path to Modal app.py for uv run modal deploy")
182
+ @click.option(
183
+ "--app", type=click.Path(), default=None, help="Path to Modal app.py for uv run modal deploy"
184
+ )
113
185
  @click.option("--name", type=str, default="synth-math-demo", help="Modal app name")
114
- @click.option("--script", type=click.Path(), default=None, help="Path to deploy_task_app.sh (optional legacy)")
186
+ @click.option(
187
+ "--script", type=click.Path(), default=None, help="Path to deploy_task_app.sh (optional legacy)"
188
+ )
115
189
  def deploy(local: bool, app: str | None, name: str, script: str | None):
116
190
  """Deploy the Math Task App (Modal by default)."""
117
191
  args: list[str] = ["rl_demo.deploy"]
@@ -205,7 +279,10 @@ def serve_deprecated(
205
279
  force: bool,
206
280
  ):
207
281
  logging.basicConfig(level=logging.INFO, format="%(message)s")
208
- click.echo("⚠️ 'synth-ai serve' now targets task apps; use 'synth-ai serve' for task apps or 'synth-ai serve-deprecated' for this legacy service.", err=True)
282
+ click.echo(
283
+ "⚠️ 'synth-ai serve' now targets task apps; use 'synth-ai serve' for task apps or 'synth-ai serve-deprecated' for this legacy service.",
284
+ err=True,
285
+ )
209
286
  processes = []
210
287
 
211
288
  def signal_handler(sig, frame):
synth_ai/cli/status.py CHANGED
@@ -14,9 +14,9 @@ from rich.table import Table
14
14
 
15
15
 
16
16
  async def _db_stats(db_url: str) -> dict:
17
- from synth_ai.tracing_v3.turso.manager import AsyncSQLTraceManager
17
+ from synth_ai.tracing_v3.storage.factory import StorageConfig, create_storage
18
18
 
19
- db = AsyncSQLTraceManager(db_url)
19
+ db = create_storage(StorageConfig(connection_string=db_url))
20
20
  await db.initialize()
21
21
  try:
22
22
  out: dict = {}