synth-ai 0.2.9.dev5__py3-none-any.whl → 0.2.9.dev7__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 (155) hide show
  1. examples/common_old/backend.py +0 -1
  2. examples/crafter_debug_render.py +15 -6
  3. examples/evals_old/compare_models.py +1 -0
  4. examples/finetuning_old/_backup_synth_qwen/filter_traces_achievements.py +6 -2
  5. examples/finetuning_old/_backup_synth_qwen/react_agent_lm.py +4 -4
  6. examples/finetuning_old/_backup_synth_qwen/sft_kickoff.py +4 -3
  7. examples/finetuning_old/synth_qwen_v1/filter_traces_achievements.py +6 -2
  8. examples/finetuning_old/synth_qwen_v1/finetune.py +1 -1
  9. examples/finetuning_old/synth_qwen_v1/hello_ft_model.py +4 -4
  10. examples/finetuning_old/synth_qwen_v1/infer.py +1 -2
  11. examples/finetuning_old/synth_qwen_v1/poll.py +4 -2
  12. examples/finetuning_old/synth_qwen_v1/prepare_data.py +8 -8
  13. examples/finetuning_old/synth_qwen_v1/react_agent_lm.py +5 -4
  14. examples/finetuning_old/synth_qwen_v1/run_crafter_sft_job.py +11 -8
  15. examples/finetuning_old/synth_qwen_v1/run_ft_job.py +17 -12
  16. examples/finetuning_old/synth_qwen_v1/upload_data.py +1 -1
  17. examples/finetuning_old/synth_qwen_v1/util.py +7 -2
  18. examples/rl/configs/eval_base_qwen.toml +1 -1
  19. examples/rl/configs/rl_from_base_qwen17.toml +1 -1
  20. examples/rl/download_dataset.py +26 -10
  21. examples/rl/run_eval.py +17 -15
  22. examples/rl/run_rl_and_save.py +24 -7
  23. examples/rl/task_app/math_single_step.py +128 -11
  24. examples/rl/task_app/math_task_app.py +11 -3
  25. examples/rl_old/task_app.py +222 -53
  26. examples/warming_up_to_rl/analyze_trace_db.py +7 -5
  27. examples/warming_up_to_rl/export_trace_sft.py +141 -16
  28. examples/warming_up_to_rl/groq_test.py +11 -4
  29. examples/warming_up_to_rl/manage_secrets.py +15 -6
  30. examples/warming_up_to_rl/readme.md +9 -2
  31. examples/warming_up_to_rl/run_eval.py +108 -30
  32. examples/warming_up_to_rl/run_fft_and_save.py +128 -52
  33. examples/warming_up_to_rl/run_local_rollout.py +87 -36
  34. examples/warming_up_to_rl/run_local_rollout_modal.py +113 -25
  35. examples/warming_up_to_rl/run_local_rollout_parallel.py +80 -16
  36. examples/warming_up_to_rl/run_local_rollout_traced.py +125 -20
  37. examples/warming_up_to_rl/run_rl_and_save.py +31 -7
  38. examples/warming_up_to_rl/run_rollout_remote.py +37 -10
  39. examples/warming_up_to_rl/task_app/grpo_crafter.py +90 -27
  40. examples/warming_up_to_rl/task_app/grpo_crafter_task_app.py +9 -27
  41. examples/warming_up_to_rl/task_app/synth_envs_hosted/environment_routes.py +46 -108
  42. examples/warming_up_to_rl/task_app/synth_envs_hosted/envs/__init__.py +1 -1
  43. examples/warming_up_to_rl/task_app/synth_envs_hosted/envs/crafter/__init__.py +1 -1
  44. examples/warming_up_to_rl/task_app/synth_envs_hosted/envs/crafter/app.py +1 -1
  45. examples/warming_up_to_rl/task_app/synth_envs_hosted/envs/crafter/environment.py +50 -17
  46. examples/warming_up_to_rl/task_app/synth_envs_hosted/envs/crafter/policy.py +35 -21
  47. examples/warming_up_to_rl/task_app/synth_envs_hosted/envs/crafter/react_agent.py +8 -4
  48. examples/warming_up_to_rl/task_app/synth_envs_hosted/envs/crafter/shared.py +29 -26
  49. examples/warming_up_to_rl/task_app/synth_envs_hosted/envs/crafter/tools.py +1 -1
  50. examples/warming_up_to_rl/task_app/synth_envs_hosted/hosted_app.py +17 -13
  51. examples/warming_up_to_rl/task_app/synth_envs_hosted/inference/__init__.py +1 -1
  52. examples/warming_up_to_rl/task_app/synth_envs_hosted/inference/openai_client.py +106 -63
  53. examples/warming_up_to_rl/task_app/synth_envs_hosted/policy_routes.py +82 -84
  54. examples/warming_up_to_rl/task_app/synth_envs_hosted/rollout.py +76 -59
  55. examples/warming_up_to_rl/task_app/synth_envs_hosted/storage/__init__.py +1 -1
  56. examples/warming_up_to_rl/task_app/synth_envs_hosted/storage/volume.py +43 -49
  57. examples/warming_up_to_rl/task_app/synth_envs_hosted/test_service.py +5 -15
  58. synth_ai/__init__.py +1 -0
  59. synth_ai/api/train/builders.py +34 -10
  60. synth_ai/api/train/cli.py +172 -32
  61. synth_ai/api/train/config_finder.py +59 -4
  62. synth_ai/api/train/env_resolver.py +32 -14
  63. synth_ai/api/train/pollers.py +11 -3
  64. synth_ai/api/train/task_app.py +4 -1
  65. synth_ai/api/train/utils.py +20 -4
  66. synth_ai/cli/__init__.py +11 -4
  67. synth_ai/cli/balance.py +1 -1
  68. synth_ai/cli/demo.py +19 -5
  69. synth_ai/cli/rl_demo.py +75 -16
  70. synth_ai/cli/root.py +116 -37
  71. synth_ai/cli/task_apps.py +1276 -186
  72. synth_ai/cli/traces.py +1 -0
  73. synth_ai/cli/turso.py +73 -0
  74. synth_ai/core/experiment.py +0 -2
  75. synth_ai/demo_registry.py +67 -30
  76. synth_ai/demos/core/cli.py +493 -164
  77. synth_ai/demos/demo_task_apps/core.py +50 -6
  78. synth_ai/demos/demo_task_apps/crafter/configs/crafter_fft_4b.toml +2 -3
  79. synth_ai/demos/demo_task_apps/crafter/grpo_crafter_task_app.py +36 -28
  80. synth_ai/demos/demo_task_apps/math/_common.py +1 -2
  81. synth_ai/demos/demo_task_apps/math/deploy_modal.py +0 -2
  82. synth_ai/demos/demo_task_apps/math/modal_task_app.py +168 -65
  83. synth_ai/demos/demo_task_apps/math/task_app_entry.py +0 -1
  84. synth_ai/environments/examples/bandit/engine.py +12 -4
  85. synth_ai/environments/examples/bandit/taskset.py +4 -4
  86. synth_ai/environments/reproducibility/tree.py +3 -1
  87. synth_ai/environments/service/core_routes.py +6 -2
  88. synth_ai/evals/base.py +0 -2
  89. synth_ai/experimental/synth_oss.py +11 -12
  90. synth_ai/handshake.py +3 -1
  91. synth_ai/http_client.py +31 -7
  92. synth_ai/inference/__init__.py +0 -2
  93. synth_ai/inference/client.py +8 -4
  94. synth_ai/jobs/client.py +40 -10
  95. synth_ai/learning/client.py +33 -8
  96. synth_ai/learning/config.py +0 -2
  97. synth_ai/learning/constants.py +0 -2
  98. synth_ai/learning/ft_client.py +6 -3
  99. synth_ai/learning/health.py +9 -2
  100. synth_ai/learning/jobs.py +17 -5
  101. synth_ai/learning/prompts/hello_world_in_context_injection_ex.py +1 -3
  102. synth_ai/learning/prompts/random_search.py +4 -1
  103. synth_ai/learning/prompts/run_random_search_banking77.py +6 -1
  104. synth_ai/learning/rl_client.py +42 -14
  105. synth_ai/learning/sse.py +0 -2
  106. synth_ai/learning/validators.py +6 -2
  107. synth_ai/lm/caching/ephemeral.py +1 -3
  108. synth_ai/lm/core/exceptions.py +0 -2
  109. synth_ai/lm/core/main.py +13 -1
  110. synth_ai/lm/core/synth_models.py +0 -1
  111. synth_ai/lm/core/vendor_clients.py +4 -2
  112. synth_ai/lm/overrides.py +2 -2
  113. synth_ai/lm/vendors/core/anthropic_api.py +7 -7
  114. synth_ai/lm/vendors/core/openai_api.py +2 -0
  115. synth_ai/lm/vendors/openai_standard.py +3 -1
  116. synth_ai/lm/vendors/openai_standard_responses.py +6 -3
  117. synth_ai/lm/vendors/supported/custom_endpoint.py +1 -3
  118. synth_ai/lm/vendors/synth_client.py +37 -10
  119. synth_ai/rl/__init__.py +0 -1
  120. synth_ai/rl/contracts.py +0 -2
  121. synth_ai/rl/env_keys.py +6 -1
  122. synth_ai/task/__init__.py +1 -0
  123. synth_ai/task/apps/__init__.py +11 -11
  124. synth_ai/task/auth.py +29 -17
  125. synth_ai/task/client.py +3 -1
  126. synth_ai/task/contracts.py +1 -0
  127. synth_ai/task/datasets.py +3 -1
  128. synth_ai/task/errors.py +3 -2
  129. synth_ai/task/health.py +0 -2
  130. synth_ai/task/json.py +0 -1
  131. synth_ai/task/proxy.py +2 -5
  132. synth_ai/task/rubrics.py +9 -3
  133. synth_ai/task/server.py +31 -5
  134. synth_ai/task/tracing_utils.py +8 -3
  135. synth_ai/task/validators.py +0 -1
  136. synth_ai/task/vendors.py +0 -1
  137. synth_ai/tracing_v3/db_config.py +26 -1
  138. synth_ai/tracing_v3/decorators.py +1 -0
  139. synth_ai/tracing_v3/examples/basic_usage.py +3 -2
  140. synth_ai/tracing_v3/hooks.py +2 -0
  141. synth_ai/tracing_v3/replica_sync.py +1 -0
  142. synth_ai/tracing_v3/session_tracer.py +24 -3
  143. synth_ai/tracing_v3/storage/base.py +4 -1
  144. synth_ai/tracing_v3/storage/factory.py +0 -1
  145. synth_ai/tracing_v3/turso/manager.py +102 -38
  146. synth_ai/tracing_v3/turso/models.py +4 -1
  147. synth_ai/tracing_v3/utils.py +1 -0
  148. synth_ai/v0/tracing/upload.py +32 -135
  149. {synth_ai-0.2.9.dev5.dist-info → synth_ai-0.2.9.dev7.dist-info}/METADATA +1 -1
  150. {synth_ai-0.2.9.dev5.dist-info → synth_ai-0.2.9.dev7.dist-info}/RECORD +154 -154
  151. synth_ai/install_sqld.sh +0 -40
  152. {synth_ai-0.2.9.dev5.dist-info → synth_ai-0.2.9.dev7.dist-info}/WHEEL +0 -0
  153. {synth_ai-0.2.9.dev5.dist-info → synth_ai-0.2.9.dev7.dist-info}/entry_points.txt +0 -0
  154. {synth_ai-0.2.9.dev5.dist-info → synth_ai-0.2.9.dev7.dist-info}/licenses/LICENSE +0 -0
  155. {synth_ai-0.2.9.dev5.dist-info → synth_ai-0.2.9.dev7.dist-info}/top_level.txt +0 -0
synth_ai/cli/traces.py CHANGED
@@ -51,6 +51,7 @@ def register(cli):
51
51
  for fn in files:
52
52
  fp = os.path.join(dp, fn)
53
53
  import contextlib
54
+
54
55
  with contextlib.suppress(OSError):
55
56
  total += os.path.getsize(fp)
56
57
  return total
synth_ai/cli/turso.py ADDED
@@ -0,0 +1,73 @@
1
+ """Utility CLI command for managing Turso sqld binaries."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import subprocess
6
+
7
+ import click
8
+
9
+ from .root import SQLD_VERSION, find_sqld_binary, install_sqld
10
+
11
+
12
+ def register(cli: click.Group) -> None:
13
+ """Register the turso command on the main CLI group."""
14
+
15
+ cli.add_command(turso)
16
+
17
+
18
+ def _get_sqld_version(binary: str) -> str | None:
19
+ """Return the version string reported by the sqld binary."""
20
+
21
+ try:
22
+ result = subprocess.run(
23
+ [binary, "--version"],
24
+ capture_output=True,
25
+ text=True,
26
+ check=True,
27
+ timeout=5,
28
+ )
29
+ except (OSError, subprocess.CalledProcessError, ValueError):
30
+ return None
31
+
32
+ output = result.stdout.strip() or result.stderr.strip()
33
+ return output or None
34
+
35
+
36
+ @click.command()
37
+ @click.option(
38
+ "--force",
39
+ is_flag=True,
40
+ help="Reinstall the pinned sqld build even if one is already available.",
41
+ )
42
+ def turso(force: bool) -> None:
43
+ """Ensure the Turso sqld binary required for tracing v3 is installed."""
44
+
45
+ existing_path = find_sqld_binary()
46
+
47
+ if existing_path and not force:
48
+ version_info = _get_sqld_version(existing_path)
49
+ click.echo(f"✅ Turso sqld detected at {existing_path}.")
50
+ if version_info:
51
+ click.echo(f" Reported version: {version_info}")
52
+ if version_info and SQLD_VERSION not in version_info:
53
+ click.echo(
54
+ f"⚠️ Pinned version is {SQLD_VERSION}. Run with --force to install the supported build."
55
+ )
56
+ else:
57
+ click.echo("No action taken. Use --force to reinstall the pinned build.")
58
+ return
59
+
60
+ if existing_path and force:
61
+ click.echo(f"♻️ Reinstalling Turso sqld {SQLD_VERSION} (previously at {existing_path}).")
62
+ else:
63
+ click.echo(f"📦 Installing Turso sqld {SQLD_VERSION}…")
64
+
65
+ try:
66
+ installed_path = install_sqld()
67
+ except subprocess.CalledProcessError as exc: # pragma: no cover - surfaced as Click error
68
+ raise click.ClickException(
69
+ f"sqld installation failed (exit code {exc.returncode})."
70
+ ) from exc
71
+
72
+ click.echo(f"✅ sqld installed to {installed_path}")
73
+ click.echo("Ensure ~/.local/bin is on your PATH before running Synth AI services.")
@@ -1,5 +1,3 @@
1
-
2
-
3
1
  class ExperimentalSystem:
4
2
  system_id: str
5
3
  system_version_id: str
synth_ai/demo_registry.py CHANGED
@@ -85,7 +85,7 @@ DEMO_TEMPLATES: tuple[DemoTemplate, ...] = (
85
85
  DemoTemplate(
86
86
  template_id="crafter-local",
87
87
  name="Crafter GRPO (local FastAPI)",
88
- description="Lightweight wrapper around synth_ai.task.apps.grpo_crafter for local experimentation.",
88
+ description="Lightweight wrapper around examples/warming_up_to_rl/task_app/grpo_crafter for local experimentation.",
89
89
  copy_specs=(
90
90
  CopySpec(
91
91
  "synth_ai/demos/demo_task_apps/crafter/grpo_crafter_task_app.py",
@@ -103,6 +103,34 @@ DEMO_TEMPLATES: tuple[DemoTemplate, ...] = (
103
103
  "synth_ai/demos/demo_task_apps/crafter/configs/crafter_fft_4b.toml",
104
104
  "configs/crafter_fft_4b.toml",
105
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
+ ),
106
134
  ),
107
135
  default_subdir="crafter_demo",
108
136
  env_lines=(
@@ -137,12 +165,16 @@ def _postprocess_math_modal(root: Path) -> None:
137
165
  return
138
166
  text = task_path.read_text(encoding="utf-8")
139
167
  text = text.replace('App("hendrycks-math-task-app")', 'App("hendrycks-math-task-app-demo")')
140
- text = text.replace('DEFAULT_TASK_APP_SECRET_NAME = "hendrycks-math-task-app-secret"', 'DEFAULT_TASK_APP_SECRET_NAME = "hendrycks-math-task-app-demo-secret"')
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
+ )
141
172
  task_path.write_text(text, encoding="utf-8")
142
173
 
143
174
 
144
- CRAFT_DEMO_TEMPLATE = textwrap.dedent(
145
- '''
175
+ CRAFT_DEMO_TEMPLATE = (
176
+ textwrap.dedent(
177
+ '''
146
178
  """Demo-friendly wrapper for the GRPO Crafter task app."""
147
179
 
148
180
  from __future__ import annotations
@@ -151,7 +183,12 @@ import argparse
151
183
  from pathlib import Path
152
184
 
153
185
  from synth_ai.task.apps import ModalDeploymentConfig, registry
154
- from synth_ai.task.apps.grpo_crafter import build_config
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
155
192
  from synth_ai.task.server import TaskAppConfig, create_task_app, run_task_app
156
193
 
157
194
 
@@ -159,28 +196,6 @@ APP_ID = "grpo-crafter-demo"
159
196
  BASE_APP_ID = "grpo-crafter"
160
197
 
161
198
 
162
- _BASE_CONFIG = build_config()
163
- TASK_APP_CONFIG = TaskAppConfig(
164
- app_id="grpo-crafter-demo",
165
- name=_BASE_CONFIG.name,
166
- description=_BASE_CONFIG.description,
167
- base_task_info=_BASE_CONFIG.base_task_info,
168
- describe_taskset=_BASE_CONFIG.describe_taskset,
169
- provide_task_instances=_BASE_CONFIG.provide_task_instances,
170
- rollout=_BASE_CONFIG.rollout,
171
- dataset_registry=_BASE_CONFIG.dataset_registry,
172
- rubrics=_BASE_CONFIG.rubrics,
173
- proxy=_BASE_CONFIG.proxy,
174
- routers=_BASE_CONFIG.routers,
175
- middleware=_BASE_CONFIG.middleware,
176
- app_state=_BASE_CONFIG.app_state,
177
- require_api_key=_BASE_CONFIG.require_api_key,
178
- expose_debug_env=_BASE_CONFIG.expose_debug_env,
179
- cors_origins=_BASE_CONFIG.cors_origins,
180
- startup_hooks=_BASE_CONFIG.startup_hooks,
181
- shutdown_hooks=_BASE_CONFIG.shutdown_hooks,
182
- )
183
-
184
199
  try:
185
200
  _BASE_ENTRY = registry.get(BASE_APP_ID)
186
201
  except Exception: # pragma: no cover - registry may be unavailable
@@ -213,7 +228,28 @@ ENV_FILES: tuple[str, ...] = ()
213
228
  def build_task_app_config() -> TaskAppConfig:
214
229
  """Return a fresh TaskAppConfig for the demo wrapper."""
215
230
 
216
- return TASK_APP_CONFIG.clone()
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
+ )
217
253
 
218
254
 
219
255
  def fastapi_app():
@@ -247,7 +283,9 @@ if __name__ == "__main__":
247
283
  env_files=env_files,
248
284
  )
249
285
  '''
250
- ).strip() + "\n"
286
+ ).strip()
287
+ + "\n"
288
+ )
251
289
 
252
290
 
253
291
  def _postprocess_crafter_local(root: Path) -> None:
@@ -255,4 +293,3 @@ def _postprocess_crafter_local(root: Path) -> None:
255
293
  if not task_path.exists():
256
294
  return
257
295
  task_path.write_text(CRAFT_DEMO_TEMPLATE, encoding="utf-8")
258
-