synth-ai 0.4.1__py3-none-any.whl → 0.4.4__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.
- synth_ai/__init__.py +13 -13
- synth_ai/cli/__init__.py +6 -15
- synth_ai/cli/commands/eval/__init__.py +6 -15
- synth_ai/cli/commands/eval/config.py +338 -0
- synth_ai/cli/commands/eval/core.py +236 -1091
- synth_ai/cli/commands/eval/runner.py +704 -0
- synth_ai/cli/commands/eval/validation.py +44 -117
- synth_ai/cli/commands/filter/core.py +7 -7
- synth_ai/cli/commands/filter/validation.py +2 -2
- synth_ai/cli/commands/smoke/core.py +7 -17
- synth_ai/cli/commands/status/__init__.py +1 -64
- synth_ai/cli/commands/status/client.py +50 -151
- synth_ai/cli/commands/status/config.py +3 -83
- synth_ai/cli/commands/status/errors.py +4 -13
- synth_ai/cli/commands/status/subcommands/__init__.py +2 -8
- synth_ai/cli/commands/status/subcommands/config.py +13 -0
- synth_ai/cli/commands/status/subcommands/files.py +18 -63
- synth_ai/cli/commands/status/subcommands/jobs.py +28 -311
- synth_ai/cli/commands/status/subcommands/models.py +18 -62
- synth_ai/cli/commands/status/subcommands/runs.py +16 -63
- synth_ai/cli/commands/status/subcommands/session.py +67 -172
- synth_ai/cli/commands/status/subcommands/summary.py +24 -32
- synth_ai/cli/commands/status/subcommands/utils.py +41 -0
- synth_ai/cli/commands/status/utils.py +16 -107
- synth_ai/cli/commands/train/__init__.py +18 -20
- synth_ai/cli/commands/train/errors.py +3 -3
- synth_ai/cli/commands/train/prompt_learning_validation.py +15 -16
- synth_ai/cli/commands/train/validation.py +7 -7
- synth_ai/cli/commands/train/{judge_schemas.py → verifier_schemas.py} +33 -34
- synth_ai/cli/commands/train/verifier_validation.py +235 -0
- synth_ai/cli/demo_apps/demo_task_apps/math/config.toml +0 -1
- synth_ai/cli/demo_apps/demo_task_apps/math/modal_task_app.py +2 -6
- synth_ai/cli/demo_apps/math/config.toml +0 -1
- synth_ai/cli/demo_apps/math/modal_task_app.py +2 -6
- synth_ai/cli/demo_apps/mipro/task_app.py +25 -47
- synth_ai/cli/lib/apps/task_app.py +12 -13
- synth_ai/cli/lib/task_app_discovery.py +6 -6
- synth_ai/cli/lib/train_cfgs.py +10 -10
- synth_ai/cli/task_apps/__init__.py +11 -0
- synth_ai/cli/task_apps/commands.py +7 -15
- synth_ai/core/env.py +12 -1
- synth_ai/core/errors.py +1 -2
- synth_ai/core/integrations/cloudflare.py +209 -33
- synth_ai/core/tracing_v3/abstractions.py +46 -0
- synth_ai/data/__init__.py +3 -30
- synth_ai/data/enums.py +1 -20
- synth_ai/data/rewards.py +100 -3
- synth_ai/products/graph_evolve/__init__.py +1 -2
- synth_ai/products/graph_evolve/config.py +16 -16
- synth_ai/products/graph_evolve/converters/__init__.py +3 -3
- synth_ai/products/graph_evolve/converters/openai_sft.py +7 -7
- synth_ai/products/graph_evolve/examples/hotpotqa/config.toml +1 -1
- synth_ai/products/graph_gepa/__init__.py +23 -0
- synth_ai/products/graph_gepa/converters/__init__.py +19 -0
- synth_ai/products/graph_gepa/converters/openai_sft.py +29 -0
- synth_ai/sdk/__init__.py +45 -35
- synth_ai/sdk/api/eval/__init__.py +33 -0
- synth_ai/sdk/api/eval/job.py +732 -0
- synth_ai/sdk/api/research_agent/__init__.py +276 -66
- synth_ai/sdk/api/train/builders.py +181 -0
- synth_ai/sdk/api/train/cli.py +41 -33
- synth_ai/sdk/api/train/configs/__init__.py +6 -4
- synth_ai/sdk/api/train/configs/prompt_learning.py +127 -33
- synth_ai/sdk/api/train/configs/rl.py +264 -16
- synth_ai/sdk/api/train/configs/sft.py +165 -1
- synth_ai/sdk/api/train/graph_validators.py +12 -12
- synth_ai/sdk/api/train/graphgen.py +169 -51
- synth_ai/sdk/api/train/graphgen_models.py +95 -45
- synth_ai/sdk/api/train/local_api.py +10 -0
- synth_ai/sdk/api/train/pollers.py +36 -0
- synth_ai/sdk/api/train/prompt_learning.py +390 -60
- synth_ai/sdk/api/train/rl.py +41 -5
- synth_ai/sdk/api/train/sft.py +2 -0
- synth_ai/sdk/api/train/task_app.py +20 -0
- synth_ai/sdk/api/train/validators.py +17 -17
- synth_ai/sdk/graphs/completions.py +239 -33
- synth_ai/sdk/{judging/schemas.py → graphs/verifier_schemas.py} +23 -23
- synth_ai/sdk/learning/__init__.py +35 -5
- synth_ai/sdk/learning/context_learning_client.py +531 -0
- synth_ai/sdk/learning/context_learning_types.py +294 -0
- synth_ai/sdk/learning/prompt_learning_client.py +1 -1
- synth_ai/sdk/learning/prompt_learning_types.py +2 -1
- synth_ai/sdk/learning/rl/__init__.py +0 -4
- synth_ai/sdk/learning/rl/contracts.py +0 -4
- synth_ai/sdk/localapi/__init__.py +40 -0
- synth_ai/sdk/localapi/apps/__init__.py +28 -0
- synth_ai/sdk/localapi/client.py +10 -0
- synth_ai/sdk/localapi/contracts.py +10 -0
- synth_ai/sdk/localapi/helpers.py +519 -0
- synth_ai/sdk/localapi/rollouts.py +93 -0
- synth_ai/sdk/localapi/server.py +29 -0
- synth_ai/sdk/localapi/template.py +49 -0
- synth_ai/sdk/streaming/handlers.py +6 -6
- synth_ai/sdk/streaming/streamer.py +10 -6
- synth_ai/sdk/task/__init__.py +18 -5
- synth_ai/sdk/task/apps/__init__.py +37 -1
- synth_ai/sdk/task/client.py +9 -1
- synth_ai/sdk/task/config.py +6 -11
- synth_ai/sdk/task/contracts.py +137 -95
- synth_ai/sdk/task/in_process.py +32 -22
- synth_ai/sdk/task/in_process_runner.py +9 -4
- synth_ai/sdk/task/rubrics/__init__.py +2 -3
- synth_ai/sdk/task/rubrics/loaders.py +4 -4
- synth_ai/sdk/task/rubrics/strict.py +3 -4
- synth_ai/sdk/task/server.py +76 -16
- synth_ai/sdk/task/trace_correlation_helpers.py +190 -139
- synth_ai/sdk/task/validators.py +34 -49
- synth_ai/sdk/training/__init__.py +7 -16
- synth_ai/sdk/tunnels/__init__.py +118 -0
- synth_ai/sdk/tunnels/cleanup.py +83 -0
- synth_ai/sdk/tunnels/ports.py +120 -0
- synth_ai/sdk/tunnels/tunneled_api.py +363 -0
- {synth_ai-0.4.1.dist-info → synth_ai-0.4.4.dist-info}/METADATA +71 -4
- {synth_ai-0.4.1.dist-info → synth_ai-0.4.4.dist-info}/RECORD +118 -128
- synth_ai/cli/commands/baseline/__init__.py +0 -12
- synth_ai/cli/commands/baseline/core.py +0 -636
- synth_ai/cli/commands/baseline/list.py +0 -94
- synth_ai/cli/commands/eval/errors.py +0 -81
- synth_ai/cli/commands/status/formatters.py +0 -164
- synth_ai/cli/commands/status/subcommands/pricing.py +0 -23
- synth_ai/cli/commands/status/subcommands/usage.py +0 -203
- synth_ai/cli/commands/train/judge_validation.py +0 -305
- synth_ai/cli/usage.py +0 -159
- synth_ai/data/specs.py +0 -36
- synth_ai/sdk/api/research_agent/cli.py +0 -428
- synth_ai/sdk/api/research_agent/config.py +0 -357
- synth_ai/sdk/api/research_agent/job.py +0 -717
- synth_ai/sdk/baseline/__init__.py +0 -25
- synth_ai/sdk/baseline/config.py +0 -209
- synth_ai/sdk/baseline/discovery.py +0 -216
- synth_ai/sdk/baseline/execution.py +0 -154
- synth_ai/sdk/judging/__init__.py +0 -15
- synth_ai/sdk/judging/base.py +0 -24
- synth_ai/sdk/judging/client.py +0 -191
- synth_ai/sdk/judging/types.py +0 -42
- synth_ai/sdk/research_agent/__init__.py +0 -34
- synth_ai/sdk/research_agent/container_builder.py +0 -328
- synth_ai/sdk/research_agent/container_spec.py +0 -198
- synth_ai/sdk/research_agent/defaults.py +0 -34
- synth_ai/sdk/research_agent/results_collector.py +0 -69
- synth_ai/sdk/specs/__init__.py +0 -46
- synth_ai/sdk/specs/dataclasses.py +0 -149
- synth_ai/sdk/specs/loader.py +0 -144
- synth_ai/sdk/specs/serializer.py +0 -199
- synth_ai/sdk/specs/validation.py +0 -250
- synth_ai/sdk/tracing/__init__.py +0 -39
- synth_ai/sdk/usage/__init__.py +0 -37
- synth_ai/sdk/usage/client.py +0 -171
- synth_ai/sdk/usage/models.py +0 -261
- {synth_ai-0.4.1.dist-info → synth_ai-0.4.4.dist-info}/WHEEL +0 -0
- {synth_ai-0.4.1.dist-info → synth_ai-0.4.4.dist-info}/entry_points.txt +0 -0
- {synth_ai-0.4.1.dist-info → synth_ai-0.4.4.dist-info}/licenses/LICENSE +0 -0
- {synth_ai-0.4.1.dist-info → synth_ai-0.4.4.dist-info}/top_level.txt +0 -0
|
@@ -1,305 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Validation logic for judge/rubric configuration from TOML.
|
|
3
|
-
|
|
4
|
-
This module validates and normalizes judge/rubric config, removing all dead fields
|
|
5
|
-
and ensuring only the fields actually used by the backend are present.
|
|
6
|
-
"""
|
|
7
|
-
|
|
8
|
-
from __future__ import annotations
|
|
9
|
-
|
|
10
|
-
import warnings
|
|
11
|
-
from collections.abc import MutableMapping
|
|
12
|
-
from typing import Any, Optional, Tuple
|
|
13
|
-
|
|
14
|
-
from pydantic import ValidationError
|
|
15
|
-
|
|
16
|
-
from .errors import InvalidJudgeConfigError, InvalidRubricConfigError
|
|
17
|
-
from .judge_schemas import JudgeConfig, JudgeOptionsConfig, RubricConfig, RubricWeightsConfig
|
|
18
|
-
|
|
19
|
-
__all__ = [
|
|
20
|
-
"validate_judge_config",
|
|
21
|
-
"validate_rubric_config",
|
|
22
|
-
"extract_and_validate_judge_rubric",
|
|
23
|
-
]
|
|
24
|
-
|
|
25
|
-
# Dead fields that should trigger deprecation warnings
|
|
26
|
-
DEPRECATED_RUBRIC_FIELDS = {
|
|
27
|
-
"model",
|
|
28
|
-
"api_base",
|
|
29
|
-
"api_key_env",
|
|
30
|
-
"event",
|
|
31
|
-
"outcome",
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
DEPRECATED_JUDGE_FIELDS = {
|
|
35
|
-
"type",
|
|
36
|
-
"timeout_s", # Moved to judge.options.timeout_s
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
DEPRECATED_JUDGE_OPTIONS_FIELDS = {
|
|
40
|
-
"max_concurrency",
|
|
41
|
-
"tracks",
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
def _warn_deprecated_fields(section: str, fields: set[str], present_fields: set[str]) -> None:
|
|
46
|
-
"""Emit deprecation warnings for dead fields that are present in config."""
|
|
47
|
-
deprecated_present = fields & present_fields
|
|
48
|
-
if deprecated_present:
|
|
49
|
-
field_list = ", ".join(sorted(deprecated_present))
|
|
50
|
-
warnings.warn(
|
|
51
|
-
f"[{section}] contains deprecated fields that are no longer used: {field_list}. "
|
|
52
|
-
f"These fields will be ignored and should be removed from your config. "
|
|
53
|
-
f"See judge/rubric cleanup guide for details.",
|
|
54
|
-
DeprecationWarning,
|
|
55
|
-
stacklevel=3,
|
|
56
|
-
)
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
def validate_rubric_config(config: MutableMapping[str, Any]) -> RubricConfig:
|
|
60
|
-
"""
|
|
61
|
-
Validate and normalize rubric configuration from TOML.
|
|
62
|
-
|
|
63
|
-
Args:
|
|
64
|
-
config: Raw [rubric] section from TOML
|
|
65
|
-
|
|
66
|
-
Returns:
|
|
67
|
-
Validated RubricConfig instance
|
|
68
|
-
|
|
69
|
-
Raises:
|
|
70
|
-
InvalidRubricConfigError: If validation fails
|
|
71
|
-
"""
|
|
72
|
-
if not config:
|
|
73
|
-
# Default: rubric disabled
|
|
74
|
-
return RubricConfig(enabled=False)
|
|
75
|
-
|
|
76
|
-
config_dict = dict(config)
|
|
77
|
-
|
|
78
|
-
# Warn about deprecated fields
|
|
79
|
-
_warn_deprecated_fields("rubric", DEPRECATED_RUBRIC_FIELDS, set(config_dict.keys()))
|
|
80
|
-
|
|
81
|
-
# Warn about deprecated subsections
|
|
82
|
-
if "event" in config_dict:
|
|
83
|
-
warnings.warn(
|
|
84
|
-
"[rubric.event] section is deprecated and no longer used. "
|
|
85
|
-
"Criteria are now fetched dynamically from TaskInfo or specified in "
|
|
86
|
-
"[judge.options.rubric_overrides]. This section will be ignored.",
|
|
87
|
-
DeprecationWarning,
|
|
88
|
-
stacklevel=2,
|
|
89
|
-
)
|
|
90
|
-
|
|
91
|
-
if "outcome" in config_dict:
|
|
92
|
-
warnings.warn(
|
|
93
|
-
"[rubric.outcome] section is deprecated and no longer used. "
|
|
94
|
-
"Criteria are now fetched dynamically from TaskInfo or specified in "
|
|
95
|
-
"[judge.options.rubric_overrides]. This section will be ignored.",
|
|
96
|
-
DeprecationWarning,
|
|
97
|
-
stacklevel=2,
|
|
98
|
-
)
|
|
99
|
-
|
|
100
|
-
# Extract only valid fields
|
|
101
|
-
enabled = config_dict.get("enabled", False)
|
|
102
|
-
weights_dict = config_dict.get("weights", {})
|
|
103
|
-
|
|
104
|
-
# Validate using Pydantic
|
|
105
|
-
try:
|
|
106
|
-
if not isinstance(weights_dict, dict):
|
|
107
|
-
raise ValueError("[rubric.weights] must be a dictionary")
|
|
108
|
-
|
|
109
|
-
weights = RubricWeightsConfig(**weights_dict)
|
|
110
|
-
return RubricConfig(enabled=enabled, weights=weights)
|
|
111
|
-
|
|
112
|
-
except ValidationError as exc:
|
|
113
|
-
errors = []
|
|
114
|
-
for error in exc.errors():
|
|
115
|
-
loc = ".".join(str(x) for x in error["loc"])
|
|
116
|
-
msg = error["msg"]
|
|
117
|
-
errors.append(f" • rubric.{loc}: {msg}")
|
|
118
|
-
raise InvalidRubricConfigError(
|
|
119
|
-
detail="Rubric validation failed:\n" + "\n".join(errors)
|
|
120
|
-
) from exc
|
|
121
|
-
except Exception as exc:
|
|
122
|
-
raise InvalidRubricConfigError(
|
|
123
|
-
detail=f"Rubric validation failed: {exc}"
|
|
124
|
-
) from exc
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
def validate_judge_config(config: MutableMapping[str, Any]) -> Optional[JudgeConfig]:
|
|
128
|
-
"""
|
|
129
|
-
Validate and normalize judge configuration from TOML.
|
|
130
|
-
|
|
131
|
-
Args:
|
|
132
|
-
config: Raw [judge] section from TOML
|
|
133
|
-
|
|
134
|
-
Returns:
|
|
135
|
-
Validated JudgeConfig instance, or None if not present
|
|
136
|
-
|
|
137
|
-
Raises:
|
|
138
|
-
InvalidJudgeConfigError: If validation fails
|
|
139
|
-
"""
|
|
140
|
-
if not config:
|
|
141
|
-
return None
|
|
142
|
-
|
|
143
|
-
config_dict = dict(config)
|
|
144
|
-
|
|
145
|
-
# Warn about deprecated top-level fields
|
|
146
|
-
_warn_deprecated_fields("judge", DEPRECATED_JUDGE_FIELDS, set(config_dict.keys()))
|
|
147
|
-
|
|
148
|
-
# Extract judge.options (required)
|
|
149
|
-
options_dict = config_dict.get("options")
|
|
150
|
-
if not options_dict:
|
|
151
|
-
raise InvalidJudgeConfigError(
|
|
152
|
-
detail="[judge.options] section is required when [judge] is present"
|
|
153
|
-
)
|
|
154
|
-
|
|
155
|
-
if not isinstance(options_dict, dict):
|
|
156
|
-
raise InvalidJudgeConfigError(
|
|
157
|
-
detail="[judge.options] must be a dictionary"
|
|
158
|
-
)
|
|
159
|
-
|
|
160
|
-
# Warn about deprecated options fields
|
|
161
|
-
_warn_deprecated_fields(
|
|
162
|
-
"judge.options",
|
|
163
|
-
DEPRECATED_JUDGE_OPTIONS_FIELDS,
|
|
164
|
-
set(options_dict.keys()),
|
|
165
|
-
)
|
|
166
|
-
|
|
167
|
-
# Remove deprecated fields from options
|
|
168
|
-
options_dict = {
|
|
169
|
-
k: v for k, v in options_dict.items()
|
|
170
|
-
if k not in DEPRECATED_JUDGE_OPTIONS_FIELDS
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
# Migrate judge.timeout_s to judge.options.timeout_s if present
|
|
174
|
-
if "timeout_s" in config_dict and "timeout_s" not in options_dict:
|
|
175
|
-
warnings.warn(
|
|
176
|
-
"[judge].timeout_s is deprecated. Use [judge.options].timeout_s instead. "
|
|
177
|
-
"Auto-migrating for now.",
|
|
178
|
-
DeprecationWarning,
|
|
179
|
-
stacklevel=2,
|
|
180
|
-
)
|
|
181
|
-
options_dict["timeout_s"] = config_dict["timeout_s"]
|
|
182
|
-
|
|
183
|
-
# Validate using Pydantic
|
|
184
|
-
try:
|
|
185
|
-
options = JudgeOptionsConfig(**options_dict)
|
|
186
|
-
return JudgeConfig(options=options)
|
|
187
|
-
|
|
188
|
-
except ValidationError as exc:
|
|
189
|
-
errors = []
|
|
190
|
-
for error in exc.errors():
|
|
191
|
-
loc = ".".join(str(x) for x in error["loc"])
|
|
192
|
-
msg = error["msg"]
|
|
193
|
-
errors.append(f" • judge.options.{loc}: {msg}")
|
|
194
|
-
raise InvalidJudgeConfigError(
|
|
195
|
-
detail="Judge validation failed:\n" + "\n".join(errors)
|
|
196
|
-
) from exc
|
|
197
|
-
except Exception as exc:
|
|
198
|
-
raise InvalidJudgeConfigError(
|
|
199
|
-
detail=f"Judge validation failed: {exc}"
|
|
200
|
-
) from exc
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
def extract_and_validate_judge_rubric(
|
|
204
|
-
toml_config: MutableMapping[str, Any]
|
|
205
|
-
) -> Tuple[RubricConfig, Optional[JudgeConfig]]:
|
|
206
|
-
"""
|
|
207
|
-
Extract and validate judge/rubric config from full TOML config.
|
|
208
|
-
|
|
209
|
-
Args:
|
|
210
|
-
toml_config: Full TOML configuration dict
|
|
211
|
-
|
|
212
|
-
Returns:
|
|
213
|
-
Tuple of (validated_rubric, validated_judge_or_none)
|
|
214
|
-
|
|
215
|
-
Raises:
|
|
216
|
-
InvalidRubricConfigError: If rubric validation fails
|
|
217
|
-
InvalidJudgeConfigError: If judge validation fails
|
|
218
|
-
"""
|
|
219
|
-
rubric_dict = toml_config.get("rubric", {})
|
|
220
|
-
judge_dict = toml_config.get("judge", {})
|
|
221
|
-
|
|
222
|
-
# Validate rubric
|
|
223
|
-
rubric_config = validate_rubric_config(rubric_dict)
|
|
224
|
-
|
|
225
|
-
# Validate judge (if present)
|
|
226
|
-
judge_config = validate_judge_config(judge_dict) if judge_dict else None
|
|
227
|
-
|
|
228
|
-
# Cross-validation: If rubric is enabled, judge options should be present
|
|
229
|
-
if rubric_config.enabled and not judge_config:
|
|
230
|
-
warnings.warn(
|
|
231
|
-
"[rubric].enabled=true but [judge] section is missing. "
|
|
232
|
-
"Rubric-based judging requires judge configuration. "
|
|
233
|
-
"Rubric scoring will be disabled.",
|
|
234
|
-
UserWarning,
|
|
235
|
-
stacklevel=2,
|
|
236
|
-
)
|
|
237
|
-
rubric_config.enabled = False
|
|
238
|
-
|
|
239
|
-
# Cross-validation: Warn if weights don't align with enabled judging types
|
|
240
|
-
if rubric_config.enabled and judge_config:
|
|
241
|
-
weights = rubric_config.weights
|
|
242
|
-
options = judge_config.options
|
|
243
|
-
|
|
244
|
-
if weights.event > 0 and not options.event:
|
|
245
|
-
warnings.warn(
|
|
246
|
-
"[rubric.weights].event > 0 but [judge.options].event=false. "
|
|
247
|
-
"Event-level judge scores will be 0 (no event judging enabled).",
|
|
248
|
-
UserWarning,
|
|
249
|
-
stacklevel=2,
|
|
250
|
-
)
|
|
251
|
-
|
|
252
|
-
if weights.outcome > 0 and not options.outcome:
|
|
253
|
-
warnings.warn(
|
|
254
|
-
"[rubric.weights].outcome > 0 but [judge.options].outcome=false. "
|
|
255
|
-
"Outcome judge score will be 0 (no outcome judging enabled).",
|
|
256
|
-
UserWarning,
|
|
257
|
-
stacklevel=2,
|
|
258
|
-
)
|
|
259
|
-
|
|
260
|
-
return rubric_config, judge_config
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
# Helper to check if config has any deprecated fields (for testing/migration)
|
|
264
|
-
|
|
265
|
-
def check_for_deprecated_fields(toml_config: MutableMapping[str, Any]) -> dict[str, list[str]]:
|
|
266
|
-
"""
|
|
267
|
-
Check TOML config for deprecated fields without validation.
|
|
268
|
-
|
|
269
|
-
Returns dict of {section: [deprecated_field_names]} for reporting.
|
|
270
|
-
"""
|
|
271
|
-
deprecated: dict[str, list[str]] = {}
|
|
272
|
-
|
|
273
|
-
rubric_dict = toml_config.get("rubric", {})
|
|
274
|
-
if rubric_dict:
|
|
275
|
-
found = [
|
|
276
|
-
field for field in DEPRECATED_RUBRIC_FIELDS
|
|
277
|
-
if field in rubric_dict
|
|
278
|
-
]
|
|
279
|
-
if "event" in rubric_dict:
|
|
280
|
-
found.append("event (entire section)")
|
|
281
|
-
if "outcome" in rubric_dict:
|
|
282
|
-
found.append("outcome (entire section)")
|
|
283
|
-
if found:
|
|
284
|
-
deprecated["rubric"] = found
|
|
285
|
-
|
|
286
|
-
judge_dict = toml_config.get("judge", {})
|
|
287
|
-
if judge_dict:
|
|
288
|
-
found = [
|
|
289
|
-
field for field in DEPRECATED_JUDGE_FIELDS
|
|
290
|
-
if field in judge_dict
|
|
291
|
-
]
|
|
292
|
-
if found:
|
|
293
|
-
deprecated["judge"] = found
|
|
294
|
-
|
|
295
|
-
options_dict = judge_dict.get("options", {})
|
|
296
|
-
if options_dict:
|
|
297
|
-
options_found = [
|
|
298
|
-
field for field in DEPRECATED_JUDGE_OPTIONS_FIELDS
|
|
299
|
-
if field in options_dict
|
|
300
|
-
]
|
|
301
|
-
if options_found:
|
|
302
|
-
deprecated["judge.options"] = options_found
|
|
303
|
-
|
|
304
|
-
return deprecated
|
|
305
|
-
|
synth_ai/cli/usage.py
DELETED
|
@@ -1,159 +0,0 @@
|
|
|
1
|
-
"""CLI command for displaying org usage and limits.
|
|
2
|
-
|
|
3
|
-
Usage:
|
|
4
|
-
synth-ai usage # Show usage summary
|
|
5
|
-
synth-ai usage --json # Output as JSON
|
|
6
|
-
"""
|
|
7
|
-
|
|
8
|
-
from __future__ import annotations
|
|
9
|
-
|
|
10
|
-
import json
|
|
11
|
-
import sys
|
|
12
|
-
from dataclasses import asdict
|
|
13
|
-
|
|
14
|
-
import click
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
def _format_number(n: int | float) -> str:
|
|
18
|
-
"""Format a number for display (e.g., 1000 -> 1K)."""
|
|
19
|
-
if n >= 1_000_000:
|
|
20
|
-
return f"{n / 1_000_000:.1f}M"
|
|
21
|
-
if n >= 1_000:
|
|
22
|
-
return f"{n / 1_000:.1f}K"
|
|
23
|
-
if isinstance(n, float):
|
|
24
|
-
return f"{n:.1f}"
|
|
25
|
-
return str(n)
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
def _progress_bar(percent: float, width: int = 20) -> str:
|
|
29
|
-
"""Create a text-based progress bar."""
|
|
30
|
-
filled = int(width * min(percent, 100) / 100)
|
|
31
|
-
bar = "=" * filled + "-" * (width - filled)
|
|
32
|
-
return f"[{bar}]"
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
def _format_metric(name: str, metric, indent: str = " ") -> str:
|
|
36
|
-
"""Format a single usage metric for display."""
|
|
37
|
-
percent = metric.percent_used
|
|
38
|
-
bar = _progress_bar(percent)
|
|
39
|
-
used_str = _format_number(metric.used)
|
|
40
|
-
limit_str = _format_number(metric.limit)
|
|
41
|
-
return f"{indent}{name}: {bar} {used_str} / {limit_str} ({percent:.1f}%)"
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
@click.command()
|
|
45
|
-
@click.option(
|
|
46
|
-
"--json",
|
|
47
|
-
"as_json",
|
|
48
|
-
is_flag=True,
|
|
49
|
-
default=False,
|
|
50
|
-
help="Output as JSON",
|
|
51
|
-
)
|
|
52
|
-
def usage_cmd(as_json: bool) -> None:
|
|
53
|
-
"""Display org usage and rate limits.
|
|
54
|
-
|
|
55
|
-
Shows current usage across all Synth APIs with progress bars
|
|
56
|
-
indicating how much of each limit has been consumed.
|
|
57
|
-
"""
|
|
58
|
-
try:
|
|
59
|
-
from synth_ai.sdk.usage import UsageClient
|
|
60
|
-
except ImportError as e:
|
|
61
|
-
click.echo(f"Error importing usage client: {e}", err=True)
|
|
62
|
-
sys.exit(1)
|
|
63
|
-
|
|
64
|
-
try:
|
|
65
|
-
client = UsageClient()
|
|
66
|
-
usage = client.get()
|
|
67
|
-
except Exception as e:
|
|
68
|
-
click.echo(f"Error fetching usage: {e}", err=True)
|
|
69
|
-
sys.exit(1)
|
|
70
|
-
|
|
71
|
-
if as_json:
|
|
72
|
-
# Convert to dict and output as JSON
|
|
73
|
-
output = {
|
|
74
|
-
"org_id": usage.org_id,
|
|
75
|
-
"tier": usage.tier,
|
|
76
|
-
"period": {
|
|
77
|
-
"daily_start": usage.period.daily_start.isoformat(),
|
|
78
|
-
"monthly_start": usage.period.monthly_start.isoformat(),
|
|
79
|
-
},
|
|
80
|
-
"apis": {
|
|
81
|
-
"inference": {
|
|
82
|
-
"requests_per_min": asdict(usage.apis.inference.requests_per_min),
|
|
83
|
-
"tokens_per_day": asdict(usage.apis.inference.tokens_per_day),
|
|
84
|
-
"spend_cents_per_month": asdict(usage.apis.inference.spend_cents_per_month),
|
|
85
|
-
},
|
|
86
|
-
"judges": {
|
|
87
|
-
"evaluations_per_day": asdict(usage.apis.judges.evaluations_per_day),
|
|
88
|
-
},
|
|
89
|
-
"prompt_opt": {
|
|
90
|
-
"jobs_per_day": asdict(usage.apis.prompt_opt.jobs_per_day),
|
|
91
|
-
"rollouts_per_day": asdict(usage.apis.prompt_opt.rollouts_per_day),
|
|
92
|
-
"spend_cents_per_day": asdict(usage.apis.prompt_opt.spend_cents_per_day),
|
|
93
|
-
},
|
|
94
|
-
"rl": {
|
|
95
|
-
"jobs_per_month": asdict(usage.apis.rl.jobs_per_month),
|
|
96
|
-
"gpu_hours_per_month": asdict(usage.apis.rl.gpu_hours_per_month),
|
|
97
|
-
},
|
|
98
|
-
"sft": {
|
|
99
|
-
"jobs_per_month": asdict(usage.apis.sft.jobs_per_month),
|
|
100
|
-
"gpu_hours_per_month": asdict(usage.apis.sft.gpu_hours_per_month),
|
|
101
|
-
},
|
|
102
|
-
"research": {
|
|
103
|
-
"jobs_per_month": asdict(usage.apis.research.jobs_per_month),
|
|
104
|
-
"agent_spend_cents_per_month": asdict(usage.apis.research.agent_spend_cents_per_month),
|
|
105
|
-
},
|
|
106
|
-
},
|
|
107
|
-
"totals": {
|
|
108
|
-
"spend_cents_per_month": asdict(usage.totals.spend_cents_per_month),
|
|
109
|
-
},
|
|
110
|
-
}
|
|
111
|
-
click.echo(json.dumps(output, indent=2))
|
|
112
|
-
return
|
|
113
|
-
|
|
114
|
-
# Pretty print format
|
|
115
|
-
click.echo("")
|
|
116
|
-
click.echo(f"Org: {usage.org_id} ({usage.tier} tier)")
|
|
117
|
-
click.echo("")
|
|
118
|
-
|
|
119
|
-
# Inference
|
|
120
|
-
click.echo("Inference")
|
|
121
|
-
click.echo(_format_metric("requests/min", usage.apis.inference.requests_per_min))
|
|
122
|
-
click.echo(_format_metric("tokens/day", usage.apis.inference.tokens_per_day))
|
|
123
|
-
click.echo(_format_metric("spend/month", usage.apis.inference.spend_cents_per_month))
|
|
124
|
-
click.echo("")
|
|
125
|
-
|
|
126
|
-
# Judges
|
|
127
|
-
click.echo("Judges")
|
|
128
|
-
click.echo(_format_metric("evaluations/day", usage.apis.judges.evaluations_per_day))
|
|
129
|
-
click.echo("")
|
|
130
|
-
|
|
131
|
-
# Prompt Optimization
|
|
132
|
-
click.echo("Prompt Optimization")
|
|
133
|
-
click.echo(_format_metric("jobs/day", usage.apis.prompt_opt.jobs_per_day))
|
|
134
|
-
click.echo(_format_metric("rollouts/day", usage.apis.prompt_opt.rollouts_per_day))
|
|
135
|
-
click.echo(_format_metric("spend/day", usage.apis.prompt_opt.spend_cents_per_day))
|
|
136
|
-
click.echo("")
|
|
137
|
-
|
|
138
|
-
# RL Training
|
|
139
|
-
click.echo("RL Training")
|
|
140
|
-
click.echo(_format_metric("jobs/month", usage.apis.rl.jobs_per_month))
|
|
141
|
-
click.echo(_format_metric("gpu_hours/month", usage.apis.rl.gpu_hours_per_month))
|
|
142
|
-
click.echo("")
|
|
143
|
-
|
|
144
|
-
# SFT Training
|
|
145
|
-
click.echo("SFT Training")
|
|
146
|
-
click.echo(_format_metric("jobs/month", usage.apis.sft.jobs_per_month))
|
|
147
|
-
click.echo(_format_metric("gpu_hours/month", usage.apis.sft.gpu_hours_per_month))
|
|
148
|
-
click.echo("")
|
|
149
|
-
|
|
150
|
-
# Research Agents
|
|
151
|
-
click.echo("Research Agents")
|
|
152
|
-
click.echo(_format_metric("jobs/month", usage.apis.research.jobs_per_month))
|
|
153
|
-
click.echo(_format_metric("agent_spend/month", usage.apis.research.agent_spend_cents_per_month))
|
|
154
|
-
click.echo("")
|
|
155
|
-
|
|
156
|
-
# Totals
|
|
157
|
-
click.echo("Total Spend")
|
|
158
|
-
click.echo(_format_metric("spend/month", usage.totals.spend_cents_per_month))
|
|
159
|
-
click.echo("")
|
synth_ai/data/specs.py
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
"""System specification data types.
|
|
2
|
-
|
|
3
|
-
This module re-exports spec dataclasses from their original location
|
|
4
|
-
to provide a cleaner import path: `from synth_ai.data.specs import Spec`
|
|
5
|
-
|
|
6
|
-
Based on Sean Grove's "spec as code" pattern from AI Engineer World's Fair.
|
|
7
|
-
Specs are the source of truth that encode intent, policies, and rules.
|
|
8
|
-
"""
|
|
9
|
-
|
|
10
|
-
from __future__ import annotations
|
|
11
|
-
|
|
12
|
-
from synth_ai.sdk.specs.dataclasses import (
|
|
13
|
-
Constraints,
|
|
14
|
-
Example,
|
|
15
|
-
GlossaryItem,
|
|
16
|
-
Interfaces,
|
|
17
|
-
Metadata,
|
|
18
|
-
Principle,
|
|
19
|
-
Rule,
|
|
20
|
-
Spec,
|
|
21
|
-
TestCase,
|
|
22
|
-
)
|
|
23
|
-
|
|
24
|
-
__all__ = [
|
|
25
|
-
"Spec",
|
|
26
|
-
"Metadata",
|
|
27
|
-
"Principle",
|
|
28
|
-
"Rule",
|
|
29
|
-
"Constraints",
|
|
30
|
-
"Example",
|
|
31
|
-
"TestCase",
|
|
32
|
-
"Interfaces",
|
|
33
|
-
"GlossaryItem",
|
|
34
|
-
]
|
|
35
|
-
|
|
36
|
-
|