synth-ai 0.2.14__py3-none-any.whl → 0.2.16__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.
- examples/README.md +1 -0
- examples/multi_step/SFT_README.md +147 -0
- examples/multi_step/configs/crafter_rl_stepwise_hosted_judge.toml +9 -9
- examples/multi_step/configs/crafter_sft_qwen30b_lora.toml +62 -0
- examples/multi_step/convert_traces_to_sft.py +84 -0
- examples/multi_step/run_sft_qwen30b.sh +45 -0
- examples/qwen_coder/configs/coder_lora_30b.toml +2 -1
- examples/qwen_coder/configs/coder_lora_4b.toml +2 -1
- examples/qwen_coder/configs/coder_lora_small.toml +2 -1
- examples/qwen_vl/BUGS_AND_FIXES.md +232 -0
- examples/qwen_vl/IMAGE_VALIDATION_COMPLETE.md +271 -0
- examples/qwen_vl/IMAGE_VALIDATION_SUMMARY.md +260 -0
- examples/qwen_vl/INFERENCE_SFT_TESTS.md +412 -0
- examples/qwen_vl/NEXT_STEPS_2B.md +325 -0
- examples/qwen_vl/QUICKSTART.md +327 -0
- examples/qwen_vl/QUICKSTART_RL_VISION.md +110 -0
- examples/qwen_vl/README.md +154 -0
- examples/qwen_vl/RL_VISION_COMPLETE.md +475 -0
- examples/qwen_vl/RL_VISION_TESTING.md +333 -0
- examples/qwen_vl/SDK_VISION_INTEGRATION.md +328 -0
- examples/qwen_vl/SETUP_COMPLETE.md +275 -0
- examples/qwen_vl/VISION_TESTS_COMPLETE.md +490 -0
- examples/qwen_vl/VLM_PIPELINE_COMPLETE.md +242 -0
- examples/qwen_vl/__init__.py +2 -0
- examples/qwen_vl/collect_data_via_cli.md +423 -0
- examples/qwen_vl/collect_vision_traces.py +368 -0
- examples/qwen_vl/configs/crafter_rl_vision_qwen3vl4b.toml +127 -0
- examples/qwen_vl/configs/crafter_vlm_sft_example.toml +60 -0
- examples/qwen_vl/configs/eval_gpt4o_mini_vision.toml +43 -0
- examples/qwen_vl/configs/eval_gpt4o_vision_proper.toml +29 -0
- examples/qwen_vl/configs/eval_gpt5nano_vision.toml +45 -0
- examples/qwen_vl/configs/eval_qwen2vl_vision.toml +44 -0
- examples/qwen_vl/configs/filter_qwen2vl_sft.toml +50 -0
- examples/qwen_vl/configs/filter_vision_sft.toml +53 -0
- examples/qwen_vl/configs/filter_vision_test.toml +8 -0
- examples/qwen_vl/configs/sft_qwen3_vl_2b_test.toml +54 -0
- examples/qwen_vl/crafter_gpt5nano_agent.py +308 -0
- examples/qwen_vl/crafter_qwen_vl_agent.py +300 -0
- examples/qwen_vl/run_vision_comparison.sh +62 -0
- examples/qwen_vl/run_vision_sft_pipeline.sh +175 -0
- examples/qwen_vl/test_image_validation.py +201 -0
- examples/qwen_vl/test_sft_vision_data.py +110 -0
- examples/rl/README.md +1 -1
- examples/rl/configs/eval_base_qwen.toml +17 -0
- examples/rl/configs/eval_rl_qwen.toml +13 -0
- examples/rl/configs/rl_from_base_qwen.toml +37 -0
- examples/rl/configs/rl_from_base_qwen17.toml +76 -0
- examples/rl/configs/rl_from_ft_qwen.toml +37 -0
- examples/rl/run_eval.py +436 -0
- examples/rl/run_rl_and_save.py +111 -0
- examples/rl/task_app/README.md +22 -0
- examples/rl/task_app/math_single_step.py +990 -0
- examples/rl/task_app/math_task_app.py +111 -0
- examples/sft/README.md +5 -5
- examples/sft/configs/crafter_fft_qwen0p6b.toml +4 -2
- examples/sft/configs/crafter_lora_qwen0p6b.toml +4 -3
- examples/sft/evaluate.py +2 -4
- examples/sft/export_dataset.py +7 -4
- examples/swe/task_app/README.md +1 -1
- examples/swe/task_app/grpo_swe_mini.py +0 -1
- examples/swe/task_app/grpo_swe_mini_task_app.py +0 -12
- examples/swe/task_app/hosted/envs/mini_swe/environment.py +13 -13
- examples/swe/task_app/hosted/policy_routes.py +0 -2
- examples/swe/task_app/hosted/rollout.py +0 -8
- examples/task_apps/crafter/task_app/grpo_crafter.py +4 -7
- examples/task_apps/crafter/task_app/synth_envs_hosted/envs/crafter/policy.py +59 -1
- examples/task_apps/crafter/task_app/synth_envs_hosted/inference/openai_client.py +30 -0
- examples/task_apps/crafter/task_app/synth_envs_hosted/policy_routes.py +62 -31
- examples/task_apps/crafter/task_app/synth_envs_hosted/rollout.py +16 -14
- examples/task_apps/enron/__init__.py +1 -0
- examples/vlm/README.md +3 -3
- examples/vlm/configs/crafter_vlm_gpt4o.toml +2 -0
- examples/vlm/crafter_openai_vlm_agent.py +3 -5
- examples/vlm/filter_image_rows.py +1 -1
- examples/vlm/run_crafter_vlm_benchmark.py +2 -2
- examples/warming_up_to_rl/_utils.py +92 -0
- examples/warming_up_to_rl/analyze_trace_db.py +1 -1
- examples/warming_up_to_rl/configs/crafter_fft.toml +2 -0
- examples/warming_up_to_rl/configs/crafter_fft_4b.toml +2 -0
- examples/warming_up_to_rl/configs/eval_fft_qwen4b.toml +2 -0
- examples/warming_up_to_rl/configs/eval_groq_qwen32b.toml +2 -0
- examples/warming_up_to_rl/configs/eval_modal_qwen4b.toml +2 -1
- examples/warming_up_to_rl/configs/rl_from_base_qwen4b.toml +2 -1
- examples/warming_up_to_rl/configs/rl_from_ft.toml +2 -0
- examples/warming_up_to_rl/export_trace_sft.py +174 -60
- examples/warming_up_to_rl/readme.md +63 -132
- examples/warming_up_to_rl/run_fft_and_save.py +1 -1
- examples/warming_up_to_rl/run_rl_and_save.py +1 -1
- examples/warming_up_to_rl/task_app/README.md +42 -0
- examples/warming_up_to_rl/task_app/grpo_crafter.py +696 -0
- examples/warming_up_to_rl/task_app/grpo_crafter_task_app.py +135 -0
- examples/warming_up_to_rl/task_app/synth_envs_hosted/README.md +173 -0
- examples/warming_up_to_rl/task_app/synth_envs_hosted/__init__.py +5 -0
- examples/warming_up_to_rl/task_app/synth_envs_hosted/branching.py +143 -0
- examples/warming_up_to_rl/task_app/synth_envs_hosted/environment_routes.py +1226 -0
- examples/warming_up_to_rl/task_app/synth_envs_hosted/envs/__init__.py +1 -0
- examples/warming_up_to_rl/task_app/synth_envs_hosted/envs/crafter/__init__.py +6 -0
- examples/warming_up_to_rl/task_app/synth_envs_hosted/envs/crafter/app.py +1 -0
- examples/warming_up_to_rl/task_app/synth_envs_hosted/envs/crafter/environment.py +522 -0
- examples/warming_up_to_rl/task_app/synth_envs_hosted/envs/crafter/policy.py +478 -0
- examples/warming_up_to_rl/task_app/synth_envs_hosted/envs/crafter/react_agent.py +108 -0
- examples/warming_up_to_rl/task_app/synth_envs_hosted/envs/crafter/shared.py +305 -0
- examples/warming_up_to_rl/task_app/synth_envs_hosted/envs/crafter/tools.py +47 -0
- examples/warming_up_to_rl/task_app/synth_envs_hosted/hosted_app.py +204 -0
- examples/warming_up_to_rl/task_app/synth_envs_hosted/inference/__init__.py +5 -0
- examples/warming_up_to_rl/task_app/synth_envs_hosted/inference/openai_client.py +618 -0
- examples/warming_up_to_rl/task_app/synth_envs_hosted/main.py +100 -0
- examples/warming_up_to_rl/task_app/synth_envs_hosted/policy_routes.py +1081 -0
- examples/warming_up_to_rl/task_app/synth_envs_hosted/registry.py +195 -0
- examples/warming_up_to_rl/task_app/synth_envs_hosted/rollout.py +1861 -0
- examples/warming_up_to_rl/task_app/synth_envs_hosted/storage/__init__.py +5 -0
- examples/warming_up_to_rl/task_app/synth_envs_hosted/storage/volume.py +211 -0
- examples/warming_up_to_rl/task_app/synth_envs_hosted/test_agents.py +161 -0
- examples/warming_up_to_rl/task_app/synth_envs_hosted/test_service.py +137 -0
- examples/warming_up_to_rl/task_app/synth_envs_hosted/utils.py +62 -0
- synth_ai/__init__.py +44 -30
- synth_ai/_utils/__init__.py +47 -0
- synth_ai/_utils/base_url.py +10 -0
- synth_ai/_utils/http.py +10 -0
- synth_ai/_utils/prompts.py +10 -0
- synth_ai/_utils/task_app_state.py +12 -0
- synth_ai/_utils/user_config.py +10 -0
- synth_ai/api/models/supported.py +144 -7
- synth_ai/api/train/__init__.py +13 -1
- synth_ai/api/train/cli.py +30 -7
- synth_ai/api/train/config_finder.py +18 -11
- synth_ai/api/train/env_resolver.py +13 -10
- synth_ai/cli/__init__.py +62 -78
- synth_ai/cli/_modal_wrapper.py +7 -5
- synth_ai/cli/_typer_patch.py +0 -2
- synth_ai/cli/_validate_task_app.py +22 -4
- synth_ai/cli/legacy_root_backup.py +3 -1
- synth_ai/cli/lib/__init__.py +10 -0
- synth_ai/cli/lib/task_app_discovery.py +7 -0
- synth_ai/cli/lib/task_app_env.py +518 -0
- synth_ai/cli/recent.py +2 -1
- synth_ai/cli/setup.py +266 -0
- synth_ai/cli/status.py +1 -1
- synth_ai/cli/task_app_deploy.py +16 -0
- synth_ai/cli/task_app_list.py +25 -0
- synth_ai/cli/task_app_modal_serve.py +16 -0
- synth_ai/cli/task_app_serve.py +18 -0
- synth_ai/cli/task_apps.py +71 -31
- synth_ai/cli/traces.py +1 -1
- synth_ai/cli/train.py +18 -0
- synth_ai/cli/tui.py +7 -2
- synth_ai/cli/turso.py +1 -1
- synth_ai/cli/watch.py +1 -1
- synth_ai/demos/__init__.py +10 -0
- synth_ai/demos/core/__init__.py +28 -1
- synth_ai/demos/crafter/__init__.py +1 -0
- synth_ai/demos/crafter/crafter_fft_4b.toml +55 -0
- synth_ai/demos/crafter/grpo_crafter_task_app.py +185 -0
- synth_ai/demos/crafter/rl_from_base_qwen4b.toml +74 -0
- synth_ai/demos/demo_registry.py +176 -0
- synth_ai/demos/math/__init__.py +1 -0
- synth_ai/demos/math/_common.py +16 -0
- synth_ai/demos/math/app.py +38 -0
- synth_ai/demos/math/config.toml +76 -0
- synth_ai/demos/math/deploy_modal.py +54 -0
- synth_ai/demos/math/modal_task_app.py +702 -0
- synth_ai/demos/math/task_app_entry.py +51 -0
- synth_ai/environments/environment/core.py +7 -1
- synth_ai/environments/examples/bandit/engine.py +0 -1
- synth_ai/environments/examples/bandit/environment.py +0 -1
- synth_ai/environments/examples/wordle/environment.py +0 -1
- synth_ai/evals/base.py +16 -5
- synth_ai/evals/client.py +1 -1
- synth_ai/inference/client.py +1 -1
- synth_ai/judge_schemas.py +8 -8
- synth_ai/learning/client.py +1 -1
- synth_ai/learning/health.py +1 -1
- synth_ai/learning/jobs.py +1 -1
- synth_ai/learning/rl/client.py +1 -1
- synth_ai/learning/rl/env_keys.py +1 -1
- synth_ai/learning/rl/secrets.py +1 -1
- synth_ai/learning/sft/client.py +1 -1
- synth_ai/learning/sft/data.py +407 -4
- synth_ai/learning/validators.py +4 -1
- synth_ai/task/apps/__init__.py +4 -2
- synth_ai/task/config.py +6 -4
- synth_ai/task/rubrics/__init__.py +1 -2
- synth_ai/task/rubrics/loaders.py +14 -10
- synth_ai/task/rubrics.py +219 -0
- synth_ai/task/trace_correlation_helpers.py +24 -11
- synth_ai/task/tracing_utils.py +14 -3
- synth_ai/task/validators.py +2 -3
- synth_ai/tracing_v3/abstractions.py +3 -3
- synth_ai/tracing_v3/config.py +15 -13
- synth_ai/tracing_v3/constants.py +21 -0
- synth_ai/tracing_v3/db_config.py +3 -1
- synth_ai/tracing_v3/decorators.py +10 -7
- synth_ai/tracing_v3/llm_call_record_helpers.py +5 -5
- synth_ai/tracing_v3/session_tracer.py +7 -7
- synth_ai/tracing_v3/storage/base.py +29 -29
- synth_ai/tracing_v3/storage/config.py +3 -3
- synth_ai/tracing_v3/turso/daemon.py +8 -9
- synth_ai/tracing_v3/turso/native_manager.py +80 -72
- synth_ai/tracing_v3/utils.py +2 -2
- synth_ai/tui/cli/query_experiments.py +4 -4
- synth_ai/tui/cli/query_experiments_v3.py +4 -4
- synth_ai/tui/dashboard.py +14 -9
- synth_ai/utils/__init__.py +101 -0
- synth_ai/utils/base_url.py +94 -0
- synth_ai/utils/cli.py +131 -0
- synth_ai/utils/env.py +287 -0
- synth_ai/utils/http.py +169 -0
- synth_ai/utils/modal.py +308 -0
- synth_ai/utils/process.py +212 -0
- synth_ai/utils/prompts.py +39 -0
- synth_ai/utils/sqld.py +122 -0
- synth_ai/utils/task_app_discovery.py +882 -0
- synth_ai/utils/task_app_env.py +186 -0
- synth_ai/utils/task_app_state.py +318 -0
- synth_ai/utils/user_config.py +137 -0
- synth_ai/v0/config/__init__.py +1 -5
- synth_ai/v0/config/base_url.py +1 -7
- synth_ai/v0/tracing/config.py +1 -1
- synth_ai/v0/tracing/decorators.py +1 -1
- synth_ai/v0/tracing/upload.py +1 -1
- synth_ai/v0/tracing_v1/config.py +1 -1
- synth_ai/v0/tracing_v1/decorators.py +1 -1
- synth_ai/v0/tracing_v1/upload.py +1 -1
- {synth_ai-0.2.14.dist-info → synth_ai-0.2.16.dist-info}/METADATA +85 -31
- {synth_ai-0.2.14.dist-info → synth_ai-0.2.16.dist-info}/RECORD +229 -117
- synth_ai/cli/man.py +0 -106
- synth_ai/compound/cais.py +0 -0
- synth_ai/core/experiment.py +0 -13
- synth_ai/core/system.py +0 -15
- synth_ai/demo_registry.py +0 -295
- synth_ai/handshake.py +0 -109
- synth_ai/http.py +0 -26
- {synth_ai-0.2.14.dist-info → synth_ai-0.2.16.dist-info}/WHEEL +0 -0
- {synth_ai-0.2.14.dist-info → synth_ai-0.2.16.dist-info}/entry_points.txt +0 -0
- {synth_ai-0.2.14.dist-info → synth_ai-0.2.16.dist-info}/licenses/LICENSE +0 -0
- {synth_ai-0.2.14.dist-info → synth_ai-0.2.16.dist-info}/top_level.txt +0 -0
synth_ai/cli/__init__.py
CHANGED
|
@@ -8,8 +8,9 @@ pyproject entry point `synth_ai.cli:cli`.
|
|
|
8
8
|
from __future__ import annotations
|
|
9
9
|
|
|
10
10
|
import importlib
|
|
11
|
+
import sys
|
|
11
12
|
from collections.abc import Callable
|
|
12
|
-
from typing import Any
|
|
13
|
+
from typing import Any
|
|
13
14
|
|
|
14
15
|
# Load environment variables from a local .env if present (repo root)
|
|
15
16
|
try:
|
|
@@ -21,86 +22,69 @@ except Exception:
|
|
|
21
22
|
# dotenv is optional at runtime; proceed if unavailable
|
|
22
23
|
pass
|
|
23
24
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
patch_typer_make_metavar()
|
|
28
|
-
except Exception:
|
|
29
|
-
pass
|
|
30
|
-
|
|
25
|
+
def _callable_from(module: Any, attr: str) -> Callable[..., Any] | None:
|
|
26
|
+
candidate = getattr(module, attr, None)
|
|
27
|
+
return candidate if callable(candidate) else None
|
|
31
28
|
|
|
32
|
-
from synth_ai.cli.root import cli # new canonical CLI entrypoint
|
|
33
|
-
|
|
34
|
-
# Register subcommands from this package onto the group
|
|
35
|
-
# Deprecated/legacy commands intentionally not registered: watch/experiments, balance, calc,
|
|
36
|
-
# man, recent, status, traces
|
|
37
|
-
try:
|
|
38
|
-
from synth_ai.cli import demo as _demo
|
|
39
|
-
|
|
40
|
-
_demo.register(cli)
|
|
41
|
-
except Exception:
|
|
42
|
-
pass
|
|
43
|
-
try:
|
|
44
|
-
from synth_ai.cli import turso as _turso
|
|
45
|
-
|
|
46
|
-
_turso.register(cli)
|
|
47
|
-
except Exception:
|
|
48
|
-
pass
|
|
49
|
-
try:
|
|
50
|
-
_train_module = cast(Any, importlib.import_module("synth_ai.api.train"))
|
|
51
|
-
_train_register = cast(Callable[[Any], None], _train_module.register)
|
|
52
|
-
_train_register(cli)
|
|
53
|
-
except Exception:
|
|
54
|
-
pass
|
|
55
29
|
|
|
56
|
-
|
|
57
|
-
# Import task_app_group conditionally
|
|
58
|
-
try:
|
|
59
|
-
from synth_ai.cli.task_apps import task_app_group
|
|
60
|
-
cli.add_command(task_app_group, name="task-app")
|
|
61
|
-
except Exception:
|
|
62
|
-
# Task app functionality not available
|
|
63
|
-
pass
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
try:
|
|
67
|
-
# Make task_apps import more robust to handle missing optional dependencies
|
|
68
|
-
import importlib
|
|
69
|
-
task_apps_module = importlib.import_module('synth_ai.cli.task_apps')
|
|
70
|
-
task_apps_module.register(cli)
|
|
71
|
-
except (ImportError, ModuleNotFoundError, TypeError, RuntimeError) as e:
|
|
72
|
-
# Task apps module not available (missing optional dependencies)
|
|
73
|
-
# This is expected - silently skip
|
|
74
|
-
pass
|
|
75
|
-
|
|
76
|
-
# Register TUI command - make import completely isolated
|
|
77
|
-
def _register_tui_command():
|
|
78
|
-
"""Register TUI command only when called, not during CLI startup."""
|
|
30
|
+
def _maybe_import(module_path: str) -> Any | None:
|
|
79
31
|
try:
|
|
80
|
-
|
|
81
|
-
from synth_ai.cli.tui import register as tui_register
|
|
82
|
-
tui_register(cli)
|
|
32
|
+
return importlib.import_module(module_path)
|
|
83
33
|
except Exception:
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
34
|
+
return None
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def _maybe_call(module_path: str, attr: str, *args: Any, **kwargs: Any) -> None:
|
|
38
|
+
module = _maybe_import(module_path)
|
|
39
|
+
if not module:
|
|
40
|
+
return
|
|
41
|
+
fn = _callable_from(module, attr)
|
|
42
|
+
if fn:
|
|
43
|
+
fn(*args, **kwargs)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
# Apply Typer patch if available
|
|
47
|
+
_maybe_call("synth_ai.cli._typer_patch", "patch_typer_make_metavar")
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
_cli_module = _maybe_import("synth_ai.cli.root")
|
|
51
|
+
if not _cli_module:
|
|
52
|
+
raise ImportError("synth_ai.cli.root is required for CLI entrypoint")
|
|
53
|
+
cli = _cli_module.cli # type: ignore[attr-defined]
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
# Register optional subcommands packaged under synth_ai.cli.*
|
|
57
|
+
for _module_path in ("synth_ai.cli.demo", "synth_ai.cli.turso"):
|
|
58
|
+
module = _maybe_import(_module_path)
|
|
59
|
+
if not module:
|
|
60
|
+
continue
|
|
61
|
+
sub_name = _module_path.rsplit(".", 1)[-1]
|
|
62
|
+
setattr(sys.modules[__name__], sub_name, module)
|
|
63
|
+
fn = _callable_from(module, "register")
|
|
64
|
+
if fn:
|
|
65
|
+
fn(cli)
|
|
66
|
+
|
|
67
|
+
# Train CLI lives under synth_ai.api.train
|
|
68
|
+
_maybe_call("synth_ai.api.train", "register", cli)
|
|
69
|
+
|
|
70
|
+
# Task app group/commands are optional and have richer API surface
|
|
71
|
+
_task_apps_module = _maybe_import("synth_ai.cli.task_apps")
|
|
72
|
+
if _task_apps_module:
|
|
73
|
+
task_app_group = getattr(_task_apps_module, "task_app_group", None)
|
|
74
|
+
if task_app_group is not None:
|
|
75
|
+
cli.add_command(task_app_group, name="task-app")
|
|
76
|
+
# Expose common aliases when present
|
|
77
|
+
commands = getattr(task_app_group, "commands", None)
|
|
78
|
+
if isinstance(commands, dict):
|
|
79
|
+
for alias, name in (("serve", "serve"), ("deploy", "deploy"), ("modal-serve", "modal-serve")):
|
|
80
|
+
command = commands.get(name)
|
|
81
|
+
if command is not None:
|
|
82
|
+
cli.add_command(command, name=alias)
|
|
83
|
+
register_task_apps = _callable_from(_task_apps_module, "register")
|
|
84
|
+
if register_task_apps:
|
|
85
|
+
register_task_apps(cli)
|
|
86
|
+
|
|
87
|
+
# Register TUI command if dependencies allow
|
|
88
|
+
_maybe_call("synth_ai.cli.tui", "register", cli)
|
|
96
89
|
|
|
97
|
-
# Add task app commands if available
|
|
98
|
-
try:
|
|
99
|
-
if 'task_app_group' in locals() and hasattr(task_app_group, 'commands'):
|
|
100
|
-
cli.add_command(task_app_group.commands["serve"], name="serve")
|
|
101
|
-
cli.add_command(task_app_group.commands["deploy"], name="deploy")
|
|
102
|
-
cli.add_command(task_app_group.commands["modal-serve"], name="modal-serve")
|
|
103
|
-
except Exception:
|
|
104
|
-
# Task app commands not available
|
|
105
|
-
pass
|
|
106
90
|
# Top-level 'info' alias removed; use `synth-ai task-app info` instead
|
synth_ai/cli/_modal_wrapper.py
CHANGED
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
import importlib
|
|
3
4
|
import sys
|
|
4
5
|
|
|
5
6
|
|
|
6
7
|
def main() -> int:
|
|
7
8
|
# Apply Typer compatibility patch before Modal CLI bootstraps Click/Typer internals.
|
|
8
9
|
try:
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
patch_typer_make_metavar()
|
|
10
|
+
module = importlib.import_module("synth_ai.cli._typer_patch")
|
|
12
11
|
except Exception:
|
|
13
|
-
|
|
12
|
+
module = None
|
|
13
|
+
if module is not None:
|
|
14
|
+
patch = getattr(module, "patch_typer_make_metavar", None)
|
|
15
|
+
if callable(patch):
|
|
16
|
+
patch()
|
|
14
17
|
|
|
15
18
|
from modal.__main__ import main as modal_main
|
|
16
19
|
|
|
@@ -26,4 +29,3 @@ def main() -> int:
|
|
|
26
29
|
|
|
27
30
|
if __name__ == "__main__":
|
|
28
31
|
sys.exit(main())
|
|
29
|
-
|
synth_ai/cli/_typer_patch.py
CHANGED
|
@@ -3,9 +3,27 @@
|
|
|
3
3
|
# This module provides the validate_task_app function for CLI use
|
|
4
4
|
# The actual implementation is imported from the task module
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
import importlib
|
|
7
|
+
from collections.abc import Callable
|
|
8
|
+
from typing import Any
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
_validators_module: Any | None = None
|
|
11
|
+
validate_task_app: Callable[..., Any] | None = None
|
|
12
|
+
|
|
13
|
+
try:
|
|
14
|
+
_validators_module = importlib.import_module("synth_ai.task.validators")
|
|
15
|
+
except Exception:
|
|
16
|
+
_validators_module = None
|
|
17
|
+
|
|
18
|
+
if _validators_module is not None:
|
|
19
|
+
candidate = getattr(_validators_module, "validate_task_app_endpoint", None)
|
|
20
|
+
if callable(candidate):
|
|
21
|
+
validate_task_app = candidate
|
|
11
22
|
|
|
23
|
+
if validate_task_app is None:
|
|
24
|
+
def _missing_validate_task_app(*_args: Any, **_kwargs: Any) -> None:
|
|
25
|
+
raise RuntimeError("task validation utilities are unavailable in this environment")
|
|
26
|
+
|
|
27
|
+
validate_task_app = _missing_validate_task_app
|
|
28
|
+
|
|
29
|
+
__all__ = ["validate_task_app"]
|
|
@@ -235,7 +235,9 @@ def view(url: str):
|
|
|
235
235
|
"""Launch the interactive TUI dashboard."""
|
|
236
236
|
try:
|
|
237
237
|
module = importlib.import_module(".tui.dashboard", __package__)
|
|
238
|
-
synth_dashboard_cls = getattr(module, "SynthDashboard")
|
|
238
|
+
synth_dashboard_cls = getattr(module, "SynthDashboard", None)
|
|
239
|
+
if synth_dashboard_cls is None:
|
|
240
|
+
raise RuntimeError("SynthDashboard class not available")
|
|
239
241
|
app = synth_dashboard_cls(db_url=url)
|
|
240
242
|
app.run()
|
|
241
243
|
except ImportError:
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Support utilities reused across CLI subcommands.
|
|
3
|
+
|
|
4
|
+
This module currently exposes helpers for env handling and discovery by
|
|
5
|
+
re-exporting the maintained implementations under ``synth_ai.utils``.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
from .task_app_env import * # noqa: F401,F403
|