synth-ai 0.2.14__py3-none-any.whl → 0.2.17__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 (354) hide show
  1. examples/README.md +1 -0
  2. examples/analyze_semantic_words.sh +2 -2
  3. examples/blog_posts/pokemon_vl/README.md +98 -0
  4. examples/blog_posts/pokemon_vl/configs/eval_qwen3_vl.toml +25 -0
  5. examples/blog_posts/pokemon_vl/configs/eval_rl_final.toml +24 -0
  6. examples/blog_posts/pokemon_vl/configs/filter_high_reward.toml +10 -0
  7. examples/blog_posts/pokemon_vl/configs/train_rl_from_sft.toml +42 -0
  8. examples/blog_posts/pokemon_vl/configs/train_sft_qwen4b_vl.toml +40 -0
  9. examples/blog_posts/warming_up_to_rl/README.md +158 -0
  10. examples/blog_posts/warming_up_to_rl/configs/eval_ft_qwen4b.toml +25 -0
  11. examples/blog_posts/warming_up_to_rl/configs/eval_groq_qwen32b.toml +25 -0
  12. examples/blog_posts/warming_up_to_rl/configs/eval_openai_gpt_oss_120b.toml +29 -0
  13. examples/blog_posts/warming_up_to_rl/configs/filter_high_reward_dataset.toml +10 -0
  14. examples/blog_posts/warming_up_to_rl/configs/train_rl_from_sft.toml +41 -0
  15. examples/blog_posts/warming_up_to_rl/configs/train_sft_qwen4b.toml +40 -0
  16. examples/dev/qwen3_32b_qlora_4xh100.toml +5 -0
  17. examples/multi_step/SFT_README.md +147 -0
  18. examples/multi_step/configs/crafter_rl_outcome.toml +1 -1
  19. examples/multi_step/configs/crafter_rl_stepwise_hosted_judge.toml +73 -115
  20. examples/multi_step/configs/crafter_rl_stepwise_shaped.toml +1 -1
  21. examples/multi_step/configs/crafter_rl_stepwise_simple.toml +1 -1
  22. examples/multi_step/configs/crafter_rl_stepwise_simple_NEW_FORMAT.toml +105 -0
  23. examples/multi_step/configs/crafter_sft_qwen30b_lora.toml +62 -0
  24. examples/multi_step/configs/verilog_rl_lora.toml +80 -123
  25. examples/multi_step/convert_traces_to_sft.py +84 -0
  26. examples/multi_step/run_sft_qwen30b.sh +45 -0
  27. examples/qwen_coder/configs/coder_lora_30b.toml +1 -2
  28. examples/qwen_coder/configs/coder_lora_4b.toml +5 -1
  29. examples/qwen_coder/configs/coder_lora_small.toml +1 -2
  30. examples/qwen_vl/BUGS_AND_FIXES.md +232 -0
  31. examples/qwen_vl/IMAGE_VALIDATION_COMPLETE.md +271 -0
  32. examples/qwen_vl/IMAGE_VALIDATION_SUMMARY.md +260 -0
  33. examples/qwen_vl/INFERENCE_SFT_TESTS.md +412 -0
  34. examples/qwen_vl/NEXT_STEPS_2B.md +325 -0
  35. examples/qwen_vl/QUICKSTART.md +327 -0
  36. examples/qwen_vl/QUICKSTART_RL_VISION.md +110 -0
  37. examples/qwen_vl/README.md +152 -0
  38. examples/qwen_vl/RL_VISION_COMPLETE.md +475 -0
  39. examples/qwen_vl/RL_VISION_TESTING.md +333 -0
  40. examples/qwen_vl/SDK_VISION_INTEGRATION.md +328 -0
  41. examples/qwen_vl/SETUP_COMPLETE.md +274 -0
  42. examples/qwen_vl/VISION_TESTS_COMPLETE.md +489 -0
  43. examples/qwen_vl/VLM_PIPELINE_COMPLETE.md +242 -0
  44. examples/qwen_vl/__init__.py +2 -0
  45. examples/qwen_vl/collect_data_via_cli.md +415 -0
  46. examples/qwen_vl/collect_vision_traces.py +368 -0
  47. examples/qwen_vl/configs/crafter_rl_vision_qwen3vl4b.toml +110 -0
  48. examples/qwen_vl/configs/crafter_vlm_sft_example.toml +59 -0
  49. examples/qwen_vl/configs/eval_gpt4o_mini_vision.toml +26 -0
  50. examples/qwen_vl/configs/eval_gpt4o_vision_proper.toml +29 -0
  51. examples/qwen_vl/configs/eval_gpt5nano_vision.toml +26 -0
  52. examples/qwen_vl/configs/eval_qwen3vl_vision.toml +26 -0
  53. examples/qwen_vl/configs/filter_qwen3vl_sft.toml +49 -0
  54. examples/qwen_vl/configs/filter_vision_sft.toml +52 -0
  55. examples/qwen_vl/configs/filter_vision_test.toml +8 -0
  56. examples/qwen_vl/configs/sft_qwen3_vl_2b_test.toml +54 -0
  57. examples/qwen_vl/crafter_gpt5nano_agent.py +308 -0
  58. examples/qwen_vl/crafter_qwen_vl_agent.py +300 -0
  59. examples/qwen_vl/run_vision_comparison.sh +61 -0
  60. examples/qwen_vl/run_vision_sft_pipeline.sh +175 -0
  61. examples/qwen_vl/test_image_validation.py +201 -0
  62. examples/qwen_vl/test_sft_vision_data.py +110 -0
  63. examples/rl/README.md +6 -6
  64. examples/rl/configs/eval_base_qwen.toml +17 -0
  65. examples/rl/configs/eval_rl_qwen.toml +13 -0
  66. examples/rl/configs/rl_from_base_qwen.toml +62 -0
  67. examples/rl/configs/rl_from_base_qwen17.toml +79 -0
  68. examples/rl/configs/rl_from_ft_qwen.toml +37 -0
  69. examples/rl/run_eval.py +436 -0
  70. examples/rl/run_rl_and_save.py +111 -0
  71. examples/rl/task_app/README.md +21 -0
  72. examples/rl/task_app/math_single_step.py +990 -0
  73. examples/rl/task_app/math_task_app.py +111 -0
  74. examples/run_crafter_demo.sh +2 -2
  75. examples/sft/README.md +6 -6
  76. examples/sft/configs/crafter_fft_qwen0p6b.toml +7 -2
  77. examples/sft/configs/crafter_lora_qwen0p6b.toml +7 -3
  78. examples/sft/evaluate.py +2 -4
  79. examples/sft/export_dataset.py +7 -4
  80. examples/swe/task_app/README.md +33 -3
  81. examples/swe/task_app/grpo_swe_mini.py +4 -1
  82. examples/swe/task_app/grpo_swe_mini_task_app.py +0 -12
  83. examples/swe/task_app/hosted/envs/crafter/react_agent.py +1 -1
  84. examples/swe/task_app/hosted/envs/mini_swe/environment.py +50 -23
  85. examples/swe/task_app/hosted/inference/openai_client.py +4 -4
  86. examples/swe/task_app/hosted/policy_routes.py +0 -2
  87. examples/swe/task_app/hosted/rollout.py +0 -8
  88. examples/swe/task_app/morph_backend.py +178 -0
  89. examples/task_apps/crafter/task_app/README.md +1 -1
  90. examples/task_apps/crafter/task_app/grpo_crafter.py +70 -10
  91. examples/task_apps/crafter/task_app/grpo_crafter_task_app.py +1 -1
  92. examples/task_apps/crafter/task_app/synth_envs_hosted/envs/crafter/policy.py +63 -27
  93. examples/task_apps/crafter/task_app/synth_envs_hosted/envs/crafter/react_agent.py +1 -2
  94. examples/task_apps/crafter/task_app/synth_envs_hosted/inference/openai_client.py +48 -50
  95. examples/task_apps/crafter/task_app/synth_envs_hosted/policy_routes.py +75 -36
  96. examples/task_apps/crafter/task_app/synth_envs_hosted/rollout.py +31 -15
  97. examples/task_apps/enron/__init__.py +1 -0
  98. examples/task_apps/enron/task_app/grpo_enron_task_app.py +1 -1
  99. examples/task_apps/math/README.md +1 -2
  100. examples/task_apps/pokemon_red/README.md +3 -4
  101. examples/task_apps/pokemon_red/eval_image_only_gpt4o.toml +6 -5
  102. examples/task_apps/pokemon_red/eval_pokemon_red_policy.py +1 -2
  103. examples/task_apps/pokemon_red/task_app.py +36 -5
  104. examples/task_apps/sokoban/README.md +2 -3
  105. examples/task_apps/verilog/eval_groq_qwen32b.toml +12 -14
  106. examples/task_apps/verilog/task_app/grpo_verilog_task_app.py +1 -1
  107. examples/vlm/README.md +3 -3
  108. examples/vlm/configs/crafter_vlm_gpt4o.toml +5 -0
  109. examples/vlm/crafter_openai_vlm_agent.py +3 -5
  110. examples/vlm/filter_image_rows.py +1 -1
  111. examples/vlm/run_crafter_vlm_benchmark.py +2 -2
  112. examples/warming_up_to_rl/_utils.py +92 -0
  113. examples/warming_up_to_rl/analyze_trace_db.py +1 -1
  114. examples/warming_up_to_rl/configs/crafter_fft.toml +5 -0
  115. examples/warming_up_to_rl/configs/eval_fft_qwen4b.toml +2 -0
  116. examples/warming_up_to_rl/configs/eval_groq_qwen32b.toml +2 -0
  117. examples/warming_up_to_rl/configs/eval_modal_qwen4b.toml +2 -1
  118. examples/warming_up_to_rl/configs/rl_from_base_qwen4b.toml +2 -1
  119. examples/warming_up_to_rl/configs/rl_from_ft.toml +2 -0
  120. examples/warming_up_to_rl/export_trace_sft.py +174 -60
  121. examples/warming_up_to_rl/readme.md +63 -132
  122. examples/warming_up_to_rl/run_fft_and_save.py +1 -1
  123. examples/warming_up_to_rl/run_local_rollout_traced.py +1 -1
  124. examples/warming_up_to_rl/run_rl_and_save.py +1 -1
  125. examples/warming_up_to_rl/task_app/README.md +42 -0
  126. examples/warming_up_to_rl/task_app/grpo_crafter.py +827 -0
  127. examples/warming_up_to_rl/task_app/grpo_crafter_task_app.py +135 -0
  128. examples/warming_up_to_rl/task_app/synth_envs_hosted/README.md +173 -0
  129. examples/warming_up_to_rl/task_app/synth_envs_hosted/__init__.py +5 -0
  130. examples/warming_up_to_rl/task_app/synth_envs_hosted/branching.py +143 -0
  131. examples/warming_up_to_rl/task_app/synth_envs_hosted/environment_routes.py +1226 -0
  132. examples/warming_up_to_rl/task_app/synth_envs_hosted/envs/__init__.py +1 -0
  133. examples/warming_up_to_rl/task_app/synth_envs_hosted/envs/crafter/__init__.py +6 -0
  134. examples/warming_up_to_rl/task_app/synth_envs_hosted/envs/crafter/app.py +1 -0
  135. examples/warming_up_to_rl/task_app/synth_envs_hosted/envs/crafter/environment.py +522 -0
  136. examples/warming_up_to_rl/task_app/synth_envs_hosted/envs/crafter/policy.py +454 -0
  137. examples/warming_up_to_rl/task_app/synth_envs_hosted/envs/crafter/react_agent.py +108 -0
  138. examples/warming_up_to_rl/task_app/synth_envs_hosted/envs/crafter/shared.py +305 -0
  139. examples/warming_up_to_rl/task_app/synth_envs_hosted/envs/crafter/tools.py +47 -0
  140. examples/warming_up_to_rl/task_app/synth_envs_hosted/hosted_app.py +204 -0
  141. examples/warming_up_to_rl/task_app/synth_envs_hosted/inference/__init__.py +5 -0
  142. examples/warming_up_to_rl/task_app/synth_envs_hosted/inference/openai_client.py +618 -0
  143. examples/warming_up_to_rl/task_app/synth_envs_hosted/main.py +100 -0
  144. examples/warming_up_to_rl/task_app/synth_envs_hosted/policy_routes.py +1084 -0
  145. examples/warming_up_to_rl/task_app/synth_envs_hosted/registry.py +195 -0
  146. examples/warming_up_to_rl/task_app/synth_envs_hosted/rollout.py +1861 -0
  147. examples/warming_up_to_rl/task_app/synth_envs_hosted/storage/__init__.py +5 -0
  148. examples/warming_up_to_rl/task_app/synth_envs_hosted/storage/volume.py +211 -0
  149. examples/warming_up_to_rl/task_app/synth_envs_hosted/test_agents.py +161 -0
  150. examples/warming_up_to_rl/task_app/synth_envs_hosted/test_service.py +137 -0
  151. examples/warming_up_to_rl/task_app/synth_envs_hosted/utils.py +62 -0
  152. examples/workflows/math_rl/configs/rl_from_base_qwen.toml +27 -0
  153. examples/workflows/math_rl/configs/rl_from_base_qwen17.toml +5 -0
  154. synth_ai/__init__.py +44 -30
  155. synth_ai/_utils/__init__.py +47 -0
  156. synth_ai/_utils/base_url.py +10 -0
  157. synth_ai/_utils/http.py +10 -0
  158. synth_ai/_utils/prompts.py +10 -0
  159. synth_ai/_utils/task_app_state.py +12 -0
  160. synth_ai/_utils/user_config.py +10 -0
  161. synth_ai/api/models/supported.py +144 -7
  162. synth_ai/api/train/__init__.py +13 -1
  163. synth_ai/api/train/builders.py +9 -3
  164. synth_ai/api/train/cli.py +155 -17
  165. synth_ai/api/train/config_finder.py +18 -11
  166. synth_ai/api/train/configs/__init__.py +8 -1
  167. synth_ai/api/train/configs/rl.py +32 -7
  168. synth_ai/api/train/configs/sft.py +6 -2
  169. synth_ai/api/train/configs/shared.py +59 -2
  170. synth_ai/api/train/env_resolver.py +13 -10
  171. synth_ai/auth/credentials.py +119 -0
  172. synth_ai/cli/__init__.py +61 -69
  173. synth_ai/cli/_modal_wrapper.py +7 -5
  174. synth_ai/cli/_typer_patch.py +0 -2
  175. synth_ai/cli/_validate_task_app.py +22 -4
  176. synth_ai/cli/commands/__init__.py +17 -0
  177. synth_ai/cli/commands/demo/__init__.py +6 -0
  178. synth_ai/cli/commands/demo/core.py +163 -0
  179. synth_ai/cli/commands/deploy/__init__.py +23 -0
  180. synth_ai/cli/commands/deploy/core.py +614 -0
  181. synth_ai/cli/commands/deploy/errors.py +72 -0
  182. synth_ai/cli/commands/deploy/validation.py +11 -0
  183. synth_ai/cli/commands/eval/__init__.py +19 -0
  184. synth_ai/cli/commands/eval/core.py +1109 -0
  185. synth_ai/cli/commands/eval/errors.py +81 -0
  186. synth_ai/cli/commands/eval/validation.py +133 -0
  187. synth_ai/cli/commands/filter/__init__.py +12 -0
  188. synth_ai/cli/commands/filter/core.py +388 -0
  189. synth_ai/cli/commands/filter/errors.py +55 -0
  190. synth_ai/cli/commands/filter/validation.py +77 -0
  191. synth_ai/cli/commands/help/__init__.py +177 -0
  192. synth_ai/cli/commands/help/core.py +73 -0
  193. synth_ai/cli/commands/status/__init__.py +64 -0
  194. synth_ai/cli/commands/status/client.py +192 -0
  195. synth_ai/cli/commands/status/config.py +92 -0
  196. synth_ai/cli/commands/status/errors.py +20 -0
  197. synth_ai/cli/commands/status/formatters.py +164 -0
  198. synth_ai/cli/commands/status/subcommands/__init__.py +9 -0
  199. synth_ai/cli/commands/status/subcommands/files.py +79 -0
  200. synth_ai/cli/commands/status/subcommands/jobs.py +334 -0
  201. synth_ai/cli/commands/status/subcommands/models.py +79 -0
  202. synth_ai/cli/commands/status/subcommands/runs.py +81 -0
  203. synth_ai/cli/commands/status/subcommands/summary.py +47 -0
  204. synth_ai/cli/commands/status/utils.py +114 -0
  205. synth_ai/cli/commands/train/__init__.py +53 -0
  206. synth_ai/cli/commands/train/core.py +21 -0
  207. synth_ai/cli/commands/train/errors.py +117 -0
  208. synth_ai/cli/commands/train/judge_schemas.py +199 -0
  209. synth_ai/cli/commands/train/judge_validation.py +304 -0
  210. synth_ai/cli/commands/train/validation.py +443 -0
  211. synth_ai/cli/demo.py +2 -162
  212. synth_ai/cli/deploy/__init__.py +28 -0
  213. synth_ai/cli/deploy/core.py +5 -0
  214. synth_ai/cli/deploy/errors.py +23 -0
  215. synth_ai/cli/deploy/validation.py +5 -0
  216. synth_ai/cli/eval/__init__.py +36 -0
  217. synth_ai/cli/eval/core.py +5 -0
  218. synth_ai/cli/eval/errors.py +31 -0
  219. synth_ai/cli/eval/validation.py +5 -0
  220. synth_ai/cli/filter/__init__.py +28 -0
  221. synth_ai/cli/filter/core.py +5 -0
  222. synth_ai/cli/filter/errors.py +23 -0
  223. synth_ai/cli/filter/validation.py +5 -0
  224. synth_ai/cli/legacy_root_backup.py +3 -1
  225. synth_ai/cli/lib/__init__.py +10 -0
  226. synth_ai/cli/lib/task_app_discovery.py +7 -0
  227. synth_ai/cli/lib/task_app_env.py +518 -0
  228. synth_ai/cli/modal_serve/__init__.py +12 -0
  229. synth_ai/cli/modal_serve/core.py +14 -0
  230. synth_ai/cli/modal_serve/errors.py +8 -0
  231. synth_ai/cli/modal_serve/validation.py +11 -0
  232. synth_ai/cli/recent.py +2 -1
  233. synth_ai/cli/serve/__init__.py +12 -0
  234. synth_ai/cli/serve/core.py +14 -0
  235. synth_ai/cli/serve/errors.py +8 -0
  236. synth_ai/cli/serve/validation.py +11 -0
  237. synth_ai/cli/setup.py +21 -0
  238. synth_ai/cli/status.py +7 -126
  239. synth_ai/cli/task_app_deploy.py +7 -0
  240. synth_ai/cli/task_app_list.py +25 -0
  241. synth_ai/cli/task_app_modal_serve.py +11 -0
  242. synth_ai/cli/task_app_serve.py +11 -0
  243. synth_ai/cli/task_apps.py +110 -1499
  244. synth_ai/cli/traces.py +1 -1
  245. synth_ai/cli/train/__init__.py +12 -0
  246. synth_ai/cli/train/core.py +21 -0
  247. synth_ai/cli/train/errors.py +8 -0
  248. synth_ai/cli/train/validation.py +24 -0
  249. synth_ai/cli/train.py +5 -0
  250. synth_ai/cli/turso.py +1 -1
  251. synth_ai/cli/watch.py +1 -1
  252. synth_ai/demos/__init__.py +10 -0
  253. synth_ai/demos/core/__init__.py +28 -1
  254. synth_ai/demos/crafter/__init__.py +1 -0
  255. synth_ai/demos/crafter/crafter_fft_4b.toml +55 -0
  256. synth_ai/demos/crafter/grpo_crafter_task_app.py +185 -0
  257. synth_ai/demos/crafter/rl_from_base_qwen4b.toml +74 -0
  258. synth_ai/demos/demo_registry.py +176 -0
  259. synth_ai/demos/demo_task_apps/crafter/grpo_crafter_task_app.py +1 -1
  260. synth_ai/demos/math/__init__.py +1 -0
  261. synth_ai/demos/math/_common.py +16 -0
  262. synth_ai/demos/math/app.py +38 -0
  263. synth_ai/demos/math/config.toml +76 -0
  264. synth_ai/demos/math/deploy_modal.py +54 -0
  265. synth_ai/demos/math/modal_task_app.py +702 -0
  266. synth_ai/demos/math/task_app_entry.py +51 -0
  267. synth_ai/environments/environment/core.py +7 -1
  268. synth_ai/environments/examples/bandit/engine.py +0 -1
  269. synth_ai/environments/examples/bandit/environment.py +0 -1
  270. synth_ai/environments/examples/red/engine.py +33 -12
  271. synth_ai/environments/examples/red/engine_helpers/reward_components.py +151 -179
  272. synth_ai/environments/examples/red/environment.py +26 -0
  273. synth_ai/environments/examples/red/trace_hooks_v3.py +168 -0
  274. synth_ai/environments/examples/wordle/environment.py +0 -1
  275. synth_ai/evals/base.py +16 -5
  276. synth_ai/evals/client.py +1 -1
  277. synth_ai/http.py +8 -22
  278. synth_ai/inference/client.py +1 -1
  279. synth_ai/judge_schemas.py +4 -5
  280. synth_ai/learning/client.py +1 -1
  281. synth_ai/learning/health.py +1 -1
  282. synth_ai/learning/jobs.py +1 -1
  283. synth_ai/learning/rl/client.py +4 -2
  284. synth_ai/learning/rl/env_keys.py +1 -1
  285. synth_ai/learning/rl/secrets.py +1 -1
  286. synth_ai/learning/sft/client.py +1 -1
  287. synth_ai/learning/sft/data.py +407 -4
  288. synth_ai/learning/validators.py +4 -1
  289. synth_ai/streaming/__init__.py +29 -0
  290. synth_ai/streaming/config.py +94 -0
  291. synth_ai/streaming/handlers.py +469 -0
  292. synth_ai/streaming/streamer.py +301 -0
  293. synth_ai/streaming/types.py +95 -0
  294. synth_ai/task/apps/__init__.py +4 -2
  295. synth_ai/task/config.py +6 -4
  296. synth_ai/task/rubrics/__init__.py +1 -2
  297. synth_ai/task/rubrics/loaders.py +14 -10
  298. synth_ai/task/rubrics.py +219 -0
  299. synth_ai/task/trace_correlation_helpers.py +24 -11
  300. synth_ai/task/tracing_utils.py +14 -3
  301. synth_ai/task/validators.py +0 -1
  302. synth_ai/tracing_v3/abstractions.py +3 -3
  303. synth_ai/tracing_v3/config.py +15 -13
  304. synth_ai/tracing_v3/constants.py +21 -0
  305. synth_ai/tracing_v3/db_config.py +3 -1
  306. synth_ai/tracing_v3/decorators.py +10 -7
  307. synth_ai/tracing_v3/llm_call_record_helpers.py +5 -5
  308. synth_ai/tracing_v3/migration_helper.py +1 -2
  309. synth_ai/tracing_v3/session_tracer.py +7 -7
  310. synth_ai/tracing_v3/storage/base.py +29 -29
  311. synth_ai/tracing_v3/storage/config.py +3 -3
  312. synth_ai/tracing_v3/turso/daemon.py +8 -9
  313. synth_ai/tracing_v3/turso/native_manager.py +80 -72
  314. synth_ai/tracing_v3/utils.py +2 -2
  315. synth_ai/utils/__init__.py +101 -0
  316. synth_ai/utils/base_url.py +94 -0
  317. synth_ai/utils/cli.py +131 -0
  318. synth_ai/utils/env.py +294 -0
  319. synth_ai/utils/http.py +172 -0
  320. synth_ai/utils/modal.py +308 -0
  321. synth_ai/utils/process.py +212 -0
  322. synth_ai/utils/prompts.py +39 -0
  323. synth_ai/utils/sqld.py +122 -0
  324. synth_ai/utils/task_app_discovery.py +882 -0
  325. synth_ai/utils/task_app_env.py +186 -0
  326. synth_ai/utils/task_app_state.py +318 -0
  327. synth_ai/utils/user_config.py +137 -0
  328. synth_ai/v0/config/__init__.py +1 -5
  329. synth_ai/v0/config/base_url.py +1 -7
  330. synth_ai/v0/tracing/config.py +1 -1
  331. synth_ai/v0/tracing/decorators.py +1 -1
  332. synth_ai/v0/tracing/upload.py +1 -1
  333. synth_ai/v0/tracing_v1/config.py +1 -1
  334. synth_ai/v0/tracing_v1/decorators.py +1 -1
  335. synth_ai/v0/tracing_v1/upload.py +1 -1
  336. {synth_ai-0.2.14.dist-info → synth_ai-0.2.17.dist-info}/METADATA +91 -32
  337. {synth_ai-0.2.14.dist-info → synth_ai-0.2.17.dist-info}/RECORD +341 -154
  338. synth_ai/cli/man.py +0 -106
  339. synth_ai/cli/tui.py +0 -57
  340. synth_ai/compound/cais.py +0 -0
  341. synth_ai/core/experiment.py +0 -13
  342. synth_ai/core/system.py +0 -15
  343. synth_ai/demo_registry.py +0 -295
  344. synth_ai/handshake.py +0 -109
  345. synth_ai/tui/__init__.py +0 -5
  346. synth_ai/tui/__main__.py +0 -13
  347. synth_ai/tui/cli/__init__.py +0 -1
  348. synth_ai/tui/cli/query_experiments.py +0 -164
  349. synth_ai/tui/cli/query_experiments_v3.py +0 -164
  350. synth_ai/tui/dashboard.py +0 -906
  351. {synth_ai-0.2.14.dist-info → synth_ai-0.2.17.dist-info}/WHEEL +0 -0
  352. {synth_ai-0.2.14.dist-info → synth_ai-0.2.17.dist-info}/entry_points.txt +0 -0
  353. {synth_ai-0.2.14.dist-info → synth_ai-0.2.17.dist-info}/licenses/LICENSE +0 -0
  354. {synth_ai-0.2.14.dist-info → synth_ai-0.2.17.dist-info}/top_level.txt +0 -0
synth_ai/cli/man.py DELETED
@@ -1,106 +0,0 @@
1
- #!/usr/bin/env python3
2
- """
3
- CLI: human-friendly manual for Synth AI commands and options.
4
- """
5
-
6
- from __future__ import annotations
7
-
8
- from rich import box
9
- from rich.console import Console
10
- from rich.panel import Panel
11
- from rich.table import Table
12
-
13
-
14
- def _commands_table() -> Table:
15
- t = Table(title="Commands", box=box.SIMPLE, header_style="bold")
16
- t.add_column("Command")
17
- t.add_column("Summary")
18
- t.add_row(
19
- "balance",
20
- "Show remaining credit balance (USD) and a compact spend summary for last 24h and 7d.\n"
21
- "Options: --base-url, --api-key, --usage",
22
- )
23
- t.add_row(
24
- "traces",
25
- "List local trace DBs, trace counts, experiments, and per-system counts.\nOptions: --root",
26
- )
27
- t.add_row(
28
- "experiments",
29
- "Snapshot table of experiments from the local traces DB.\nOptions: --url, --limit",
30
- )
31
- t.add_row(
32
- "experiment <id>",
33
- "Details and sessions for an experiment (accepts partial ID).\nOptions: --url",
34
- )
35
- t.add_row(
36
- "usage",
37
- "Model usage statistics (tokens, cost).\nOptions: --url, --model",
38
- )
39
- t.add_row(
40
- "status",
41
- "DB stats, systems, and environment service health.\nOptions: --url, --service-url",
42
- )
43
- t.add_row(
44
- "calc '<expr>'",
45
- "Evaluate a simple arithmetic expression (e.g., 2*(3+4)).",
46
- )
47
- t.add_row(
48
- "env list | env register | env unregister",
49
- "Manage environment registry via the service.\nOptions vary; see examples.",
50
- )
51
- return t
52
-
53
-
54
- def _env_table() -> Table:
55
- t = Table(title="Environment Variables", box=box.SIMPLE, header_style="bold")
56
- t.add_column("Variable")
57
- t.add_column("Used By")
58
- t.add_column("Purpose")
59
- t.add_row(
60
- "SYNTH_BACKEND_BASE_URL",
61
- "balance",
62
- "Backend base URL (preferred) e.g. http://localhost:8000/api/v1",
63
- )
64
- t.add_row("BACKEND_BASE_URL", "balance", "Fallback backend base URL")
65
- t.add_row("LOCAL_BACKEND_URL", "balance", "Another fallback backend base URL")
66
- t.add_row("SYNTH_BASE_URL", "balance", "Generic base URL (may point to Modal, guarded)")
67
- t.add_row("SYNTH_BACKEND_API_KEY", "balance", "Backend API key (preferred)")
68
- t.add_row("SYNTH_API_KEY", "balance, env*", "API key used if backend-specific key not set")
69
- t.add_row("DEFAULT_DEV_API_KEY", "balance", "Dev fallback key for local testing")
70
- t.add_row(
71
- "SYNTH_TRACES_ROOT",
72
- "traces",
73
- "Root directory of local trace DBs (default ./synth_ai.db/dbs)",
74
- )
75
- return t
76
-
77
-
78
- def _examples_table() -> Table:
79
- t = Table(title="Examples", box=box.SIMPLE, header_style="bold")
80
- t.add_column("Command")
81
- t.add_column("Example")
82
- t.add_row("Balance (local backend)", "uvx . balance")
83
- t.add_row(
84
- "Balance with URL+key",
85
- "uvx . balance --base-url http://localhost:8000 --api-key $SYNTH_API_KEY",
86
- )
87
- t.add_row("Traces (default root)", "uvx . traces")
88
- t.add_row("Traces (custom root)", "uvx . traces --root /path/to/dbs")
89
- t.add_row("Experiments", "uvx . experiments --limit 20")
90
- t.add_row("Experiment detail", "uvx . experiment abcd1234")
91
- t.add_row("Usage by model", "uvx . usage --model gpt-4o-mini")
92
- t.add_row("Status", "uvx . status")
93
- t.add_row("Calc", "uvx . calc '2*(3+4)'")
94
- t.add_row("Env list", "uvx . env list --service-url http://localhost:8901")
95
- return t
96
-
97
-
98
- def register(cli):
99
- @cli.command(name="man")
100
- def man():
101
- """Show Synth AI CLI manual with commands, options, env vars, and examples."""
102
- console = Console()
103
- console.print(Panel("Synth AI CLI Manual", border_style="cyan"))
104
- console.print(_commands_table())
105
- console.print(_env_table())
106
- console.print(_examples_table())
synth_ai/cli/tui.py DELETED
@@ -1,57 +0,0 @@
1
- #!/usr/bin/env python3
2
- """
3
- CLI: Interactive TUI dashboard for Synth AI.
4
- """
5
-
6
- import os
7
-
8
- import click
9
- from rich.console import Console
10
-
11
-
12
- def register(cli):
13
- @cli.command()
14
- @click.option(
15
- "--url",
16
- "db_url",
17
- default="sqlite+libsql://http://127.0.0.1:8080",
18
- help="Database URL (default: sqlite+libsql://http://127.0.0.1:8080)",
19
- )
20
- @click.option("--debug", is_flag=True, help="Enable debug logging")
21
- def tui(db_url: str, debug: bool):
22
- """Launch interactive TUI dashboard showing experiments, balance, and active runs."""
23
- console = Console()
24
-
25
- # Import here to avoid circular imports and handle optional dependencies
26
- try:
27
- from synth_ai.tui.dashboard import main as tui_main
28
- except (ImportError, ModuleNotFoundError) as e:
29
- console.print("[red]Error:[/red] TUI dashboard not available.")
30
- console.print(f"Missing dependencies: {e}")
31
- console.print("Install with: pip install textual")
32
- return
33
- except Exception as e:
34
- # Handle other import errors (like missing libsql, type annotation issues, etc.)
35
- console.print("[red]Error:[/red] TUI dashboard not available.")
36
- console.print("This may be due to missing dependencies or Python version compatibility.")
37
- console.print("Try: pip install textual libsql")
38
- console.print("If using Python < 3.10, you may need to update Python or install eval_type_backport.")
39
- return
40
-
41
- # Set environment variables for the TUI to use
42
- os.environ.setdefault("TUI_DB_URL", db_url)
43
- if debug:
44
- os.environ["TUI_DEBUG"] = "1"
45
-
46
- # Run the TUI by calling the module directly with sanitized argv
47
- try:
48
- tui_args = ["--url", db_url]
49
- if debug:
50
- tui_args.append("--debug")
51
- tui_main(tui_args)
52
- except KeyboardInterrupt:
53
- console.print("\n[blue]TUI closed.[/blue]")
54
- except Exception as e:
55
- console.print(f"\n[red]Error running TUI:[/red] {e}")
56
- if debug:
57
- raise
synth_ai/compound/cais.py DELETED
File without changes
@@ -1,13 +0,0 @@
1
- class ExperimentalSystem:
2
- system_id: str
3
- system_version_id: str
4
- pass
5
-
6
-
7
- class Experiment:
8
- id: str
9
- name: str
10
- description: str
11
- created_at: str
12
- updated_at: str
13
- related_systems: list[ExperimentalSystem]
synth_ai/core/system.py DELETED
@@ -1,15 +0,0 @@
1
- class System:
2
- id: str
3
- name: str
4
- description: str
5
- pass
6
-
7
-
8
- class SystemVersion:
9
- id: str
10
- system_id: str
11
- branch: str
12
- commit: str
13
- created_at: str
14
- description: str
15
- pass
synth_ai/demo_registry.py DELETED
@@ -1,295 +0,0 @@
1
- """Registry of demo task app templates for `uvx synth-ai demo init`."""
2
-
3
- from __future__ import annotations
4
-
5
- import textwrap
6
- from collections.abc import Callable, Iterable
7
- from dataclasses import dataclass
8
- from pathlib import Path
9
-
10
- REPO_ROOT = Path(__file__).resolve().parents[1]
11
-
12
-
13
- @dataclass(frozen=True)
14
- class CopySpec:
15
- """File copy specification from repo-relative source to template-relative destination."""
16
-
17
- source: str
18
- destination: str
19
- make_executable: bool = False
20
-
21
- def absolute_source(self) -> Path:
22
- return (REPO_ROOT / self.source).resolve()
23
-
24
-
25
- @dataclass(frozen=True)
26
- class DemoTemplate:
27
- """Describes a demo task app template that can be materialised into the CWD."""
28
-
29
- template_id: str
30
- name: str
31
- description: str
32
- copy_specs: tuple[CopySpec, ...]
33
- default_subdir: str | None = None
34
- env_lines: tuple[str, ...] = ()
35
- config_source: str | None = None
36
- config_destination: str = "demo_config.toml"
37
- requires_modal: bool = False
38
- post_copy: Callable[[Path], None] | None = None
39
-
40
- def iter_copy_specs(self) -> Iterable[CopySpec]:
41
- return self.copy_specs
42
-
43
- def config_source_path(self) -> Path | None:
44
- if not self.config_source:
45
- return None
46
- return (REPO_ROOT / self.config_source).resolve()
47
-
48
-
49
- DEMO_TEMPLATES: tuple[DemoTemplate, ...] = (
50
- DemoTemplate(
51
- template_id="math-modal",
52
- name="Math Single-Step (Modal deployment)",
53
- description="Packaged modal task app matching examples/rl math environment.",
54
- copy_specs=(
55
- CopySpec(
56
- "synth_ai/demos/demo_task_apps/math/modal_task_app.py",
57
- "task_app.py",
58
- ),
59
- CopySpec(
60
- "synth_ai/demos/demo_task_apps/math/deploy_task_app.sh",
61
- "deploy_task_app.sh",
62
- make_executable=True,
63
- ),
64
- CopySpec(
65
- "synth_ai/demos/demo_task_apps/math/config.toml",
66
- "configs/rl_from_base_qwen17.toml",
67
- ),
68
- ),
69
- default_subdir="math_demo",
70
- env_lines=(
71
- "# Required for task app auth to environment service",
72
- "ENVIRONMENT_API_KEY=",
73
- "",
74
- "# Optional: for CLI job submission and proxying OpenAI models",
75
- "SYNTH_API_KEY=",
76
- "OPENAI_API_KEY=",
77
- "",
78
- "# Optional: set to 'prod' to use production names",
79
- "ENVIRONMENT=",
80
- ),
81
- config_source="synth_ai/demos/demo_task_apps/math/config.toml",
82
- requires_modal=True,
83
- post_copy=lambda root: _postprocess_math_modal(root),
84
- ),
85
- DemoTemplate(
86
- template_id="crafter-local",
87
- name="Crafter GRPO (local FastAPI)",
88
- description="Lightweight wrapper around examples/warming_up_to_rl/task_app/grpo_crafter for local experimentation.",
89
- copy_specs=(
90
- CopySpec(
91
- "synth_ai/demos/demo_task_apps/crafter/grpo_crafter_task_app.py",
92
- "task_app.py",
93
- ),
94
- CopySpec(
95
- "synth_ai/demos/demo_task_apps/crafter/README.md",
96
- "README.md",
97
- ),
98
- CopySpec(
99
- "synth_ai/demos/demo_task_apps/crafter/configs/rl_from_base_qwen4b.toml",
100
- "configs/rl_from_base_qwen4b.toml",
101
- ),
102
- CopySpec(
103
- "synth_ai/demos/demo_task_apps/crafter/configs/crafter_fft_4b.toml",
104
- "configs/crafter_fft_4b.toml",
105
- ),
106
- CopySpec(
107
- "examples/warming_up_to_rl/task_app/grpo_crafter.py",
108
- "grpo_crafter.py",
109
- ),
110
- CopySpec(
111
- "examples/warming_up_to_rl/task_app/synth_envs_hosted",
112
- "synth_envs_hosted",
113
- ),
114
- CopySpec(
115
- "examples/warming_up_to_rl/run_local_rollout.py",
116
- "run_local_rollout.py",
117
- ),
118
- CopySpec(
119
- "examples/warming_up_to_rl/run_local_rollout_traced.py",
120
- "run_local_rollout_traced.py",
121
- ),
122
- CopySpec(
123
- "examples/warming_up_to_rl/export_trace_sft.py",
124
- "export_trace_sft.py",
125
- ),
126
- CopySpec(
127
- "examples/warming_up_to_rl/run_fft_and_save.py",
128
- "run_fft_and_save.py",
129
- ),
130
- CopySpec(
131
- "examples/warming_up_to_rl/run_local_rollout_modal.py",
132
- "run_local_rollout_modal.py",
133
- ),
134
- ),
135
- default_subdir="crafter_demo",
136
- env_lines=(
137
- "ENVIRONMENT_API_KEY=",
138
- "SYNTH_API_KEY=",
139
- "",
140
- "# Optional: URL for existing Crafter task app",
141
- "TASK_APP_BASE_URL=",
142
- ),
143
- config_source="synth_ai/demos/demo_task_apps/crafter/configs/rl_from_base_qwen4b.toml",
144
- config_destination="demo_config.toml",
145
- requires_modal=False,
146
- post_copy=lambda root: _postprocess_crafter_local(root),
147
- ),
148
- )
149
-
150
-
151
- def get_demo_template(template_id: str) -> DemoTemplate | None:
152
- for template in DEMO_TEMPLATES:
153
- if template.template_id == template_id:
154
- return template
155
- return None
156
-
157
-
158
- def list_demo_templates() -> tuple[DemoTemplate, ...]:
159
- return DEMO_TEMPLATES
160
-
161
-
162
- def _postprocess_math_modal(root: Path) -> None:
163
- task_path = (root / "task_app.py").resolve()
164
- if not task_path.exists():
165
- return
166
- text = task_path.read_text(encoding="utf-8")
167
- text = text.replace('App("hendrycks-math-task-app")', 'App("hendrycks-math-task-app-demo")')
168
- text = text.replace(
169
- 'DEFAULT_TASK_APP_SECRET_NAME = "hendrycks-math-task-app-secret"',
170
- 'DEFAULT_TASK_APP_SECRET_NAME = "hendrycks-math-task-app-demo-secret"',
171
- )
172
- task_path.write_text(text, encoding="utf-8")
173
-
174
-
175
- CRAFT_DEMO_TEMPLATE = (
176
- textwrap.dedent(
177
- '''
178
- """Demo-friendly wrapper for the GRPO Crafter task app."""
179
-
180
- from __future__ import annotations
181
-
182
- import argparse
183
- from pathlib import Path
184
-
185
- from synth_ai.task.apps import ModalDeploymentConfig, registry
186
- import sys
187
- from pathlib import Path
188
- _EXAMPLES_TASK_APP = Path(__file__).resolve().parents[4] / "examples" / "warming_up_to_rl" / "task_app"
189
- if str(_EXAMPLES_TASK_APP) not in sys.path:
190
- sys.path.insert(0, str(_EXAMPLES_TASK_APP))
191
- from grpo_crafter import build_config
192
- from synth_ai.task.server import TaskAppConfig, create_task_app, run_task_app
193
-
194
-
195
- APP_ID = "grpo-crafter-demo"
196
- BASE_APP_ID = "grpo-crafter"
197
-
198
-
199
- try:
200
- _BASE_ENTRY = registry.get(BASE_APP_ID)
201
- except Exception: # pragma: no cover - registry may be unavailable
202
- MODAL_DEPLOYMENT: ModalDeploymentConfig | None = None
203
- else:
204
- base_modal = _BASE_ENTRY.modal
205
- if base_modal is None:
206
- MODAL_DEPLOYMENT = None
207
- else:
208
- modal_app_name = base_modal.app_name
209
- if not modal_app_name.endswith("-demo"):
210
- modal_app_name = f"{modal_app_name}-demo"
211
- MODAL_DEPLOYMENT = ModalDeploymentConfig(
212
- app_name=modal_app_name,
213
- python_version=base_modal.python_version,
214
- pip_packages=tuple(base_modal.pip_packages),
215
- extra_local_dirs=tuple(base_modal.extra_local_dirs),
216
- secret_names=tuple(base_modal.secret_names),
217
- volume_mounts=tuple(base_modal.volume_mounts),
218
- timeout=base_modal.timeout,
219
- memory=base_modal.memory,
220
- cpu=base_modal.cpu,
221
- min_containers=base_modal.min_containers,
222
- max_containers=base_modal.max_containers,
223
- )
224
-
225
- ENV_FILES: tuple[str, ...] = ()
226
-
227
-
228
- def build_task_app_config() -> TaskAppConfig:
229
- """Return a fresh TaskAppConfig for the demo wrapper."""
230
-
231
- # Build config dynamically so environment variables are read at runtime
232
- _base_config = build_config()
233
- return TaskAppConfig(
234
- app_id="grpo-crafter-demo",
235
- name=_base_config.name,
236
- description=_base_config.description,
237
- base_task_info=_base_config.base_task_info,
238
- describe_taskset=_base_config.describe_taskset,
239
- provide_task_instances=_base_config.provide_task_instances,
240
- rollout=_base_config.rollout,
241
- dataset_registry=_base_config.dataset_registry,
242
- rubrics=_base_config.rubrics,
243
- proxy=_base_config.proxy,
244
- routers=_base_config.routers,
245
- middleware=_base_config.middleware,
246
- app_state=_base_config.app_state,
247
- require_api_key=_base_config.require_api_key,
248
- expose_debug_env=_base_config.expose_debug_env,
249
- cors_origins=_base_config.cors_origins,
250
- startup_hooks=_base_config.startup_hooks,
251
- shutdown_hooks=_base_config.shutdown_hooks,
252
- )
253
-
254
-
255
- def fastapi_app():
256
- """Return the FastAPI application for Modal or other ASGI hosts."""
257
-
258
- return create_task_app(build_task_app_config())
259
-
260
-
261
- if __name__ == "__main__":
262
- parser = argparse.ArgumentParser(description="Run the Crafter task app locally")
263
- parser.add_argument("--host", default="0.0.0.0")
264
- parser.add_argument("--port", type=int, default=8001)
265
- parser.add_argument("--reload", action="store_true", help="Enable uvicorn autoreload")
266
- parser.add_argument(
267
- "--env-file",
268
- action="append",
269
- default=[],
270
- help="Additional .env files to load before startup",
271
- )
272
- args = parser.parse_args()
273
-
274
- default_env = Path(__file__).resolve().parents[4] / "backend" / ".env.dev"
275
- env_files = [str(default_env)] if default_env.exists() else []
276
- env_files.extend(args.env_file or [])
277
-
278
- run_task_app(
279
- build_task_app_config,
280
- host=args.host,
281
- port=args.port,
282
- reload=args.reload,
283
- env_files=env_files,
284
- )
285
- '''
286
- ).strip()
287
- + "\n"
288
- )
289
-
290
-
291
- def _postprocess_crafter_local(root: Path) -> None:
292
- task_path = (root / "task_app.py").resolve()
293
- if not task_path.exists():
294
- return
295
- task_path.write_text(CRAFT_DEMO_TEMPLATE, encoding="utf-8")
synth_ai/handshake.py DELETED
@@ -1,109 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import contextlib
4
- import os
5
- import time
6
- import webbrowser
7
- from typing import Any
8
- from urllib.parse import urljoin, urlsplit, urlunsplit
9
-
10
- import requests
11
-
12
-
13
- class HandshakeError(Exception):
14
- pass
15
-
16
-
17
- _TRUTHY = {"1", "true", "yes", "on"}
18
-
19
-
20
- def _origin() -> str:
21
- """Resolve the dashboard origin for the browser handshake.
22
-
23
- Priority order:
24
- 1. Explicit ``SYNTH_CANONICAL_ORIGIN`` override.
25
- 2. Development flag ``SYNTH_CANONICAL_DEV`` (case-insensitive truthy) → localhost.
26
- 3. Production dashboard at ``https://www.usesynth.ai/dashboard``.
27
- """
28
-
29
- override = (os.getenv("SYNTH_CANONICAL_ORIGIN") or "").strip()
30
- if override:
31
- return override.rstrip("/")
32
-
33
- dev_flag = (os.getenv("SYNTH_CANONICAL_DEV") or "").strip().lower()
34
- if dev_flag in _TRUTHY:
35
- print("USING DEV ORIGIN")
36
- return "http://localhost:3000"
37
-
38
- return "https://www.usesynth.ai/dashboard"
39
-
40
-
41
- def _split_origin(origin: str) -> tuple[str, str]:
42
- parsed = urlsplit(origin)
43
- bare = urlunsplit((parsed.scheme, parsed.netloc, "", "", ""))
44
- path = parsed.path.rstrip("/")
45
- return bare, path
46
-
47
-
48
- def _ensure_verification_uri(data: dict[str, Any], base_with_path: str) -> None:
49
- uri = data.get("verification_uri")
50
- if not isinstance(uri, str) or not uri:
51
- return
52
- if uri.startswith("http://") or uri.startswith("https://"):
53
- return
54
- data["verification_uri"] = urljoin(base_with_path.rstrip("/") + "/", uri.lstrip("/"))
55
-
56
-
57
- def start_handshake_session(origin: str | None = None) -> tuple[str, str, int, int]:
58
- base = (origin or _origin()).rstrip("/")
59
- api_origin, _ = _split_origin(base)
60
- url = urljoin(api_origin.rstrip("/") + "/", "api/sdk/handshake/init")
61
- r = requests.post(url, timeout=10)
62
- if r.status_code != 200:
63
- raise HandshakeError(f"init failed: {r.status_code} {r.text}")
64
- try:
65
- data = r.json()
66
- except ValueError as exc: # pragma: no cover - network dependent
67
- raise HandshakeError(f"init returned malformed JSON: {exc}") from exc
68
- _ensure_verification_uri(data, base)
69
- return (
70
- str(data.get("device_code")),
71
- str(data.get("verification_uri")),
72
- int(data.get("expires_in", 600)),
73
- int(data.get("interval", 3)),
74
- )
75
-
76
-
77
- def poll_handshake_token(
78
- device_code: str, origin: str | None = None, *, timeout_s: int | None = None
79
- ) -> dict[str, Any]:
80
- base = (origin or _origin()).rstrip("/")
81
- api_origin, _ = _split_origin(base)
82
- url = urljoin(api_origin.rstrip("/") + "/", "api/sdk/handshake/token")
83
- deadline = time.time() + (timeout_s or 600)
84
- while True:
85
- if time.time() > deadline:
86
- raise HandshakeError("handshake timed out")
87
- try:
88
- r = requests.post(url, json={"device_code": device_code}, timeout=10)
89
- except Exception:
90
- time.sleep(2)
91
- continue
92
- if r.status_code == 200:
93
- try:
94
- data = r.json()
95
- except ValueError as exc: # pragma: no cover - network dependent
96
- raise HandshakeError(f"token returned malformed JSON: {exc}") from exc
97
- _ensure_verification_uri(data, base)
98
- return data
99
- elif r.status_code in (404, 410):
100
- raise HandshakeError(f"handshake failed: {r.status_code}")
101
- # 428 authorization_pending or others → wait and retry
102
- time.sleep(2)
103
-
104
-
105
- def run_handshake(origin: str | None = None) -> dict[str, Any]:
106
- device_code, verification_uri, expires_in, interval = start_handshake_session(origin)
107
- with contextlib.suppress(Exception):
108
- webbrowser.open(verification_uri)
109
- return poll_handshake_token(device_code, origin, timeout_s=expires_in)
synth_ai/tui/__init__.py DELETED
@@ -1,5 +0,0 @@
1
- """Text User Interface utilities for synth-ai."""
2
-
3
- from .dashboard import main
4
-
5
- __all__ = ["main"]
synth_ai/tui/__main__.py DELETED
@@ -1,13 +0,0 @@
1
- #!/usr/bin/env python3
2
- """
3
- Entry point for Synth AI TUI dashboard.
4
-
5
- Usage:
6
- python -m synth_ai.tui
7
- python -m synth_ai.tui --url sqlite+aiosqlite:///path/to/db
8
- """
9
-
10
- from .dashboard import main
11
-
12
- if __name__ == "__main__":
13
- main()
@@ -1 +0,0 @@
1
- """Command Line Interface tools for synth-ai."""