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
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
"""Type definitions for context learning data structures.
|
|
2
|
+
|
|
3
|
+
Context Learning optimizes environment setup scripts (pre-flight/post-flight bash)
|
|
4
|
+
for terminal/coding agents, similar to how prompt learning optimizes prompts.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from dataclasses import dataclass, field
|
|
10
|
+
from typing import Any, Dict, List, Optional
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@dataclass
|
|
14
|
+
class EnvironmentConfig:
|
|
15
|
+
"""Environment configuration with pre-flight and post-flight scripts."""
|
|
16
|
+
|
|
17
|
+
preflight_script: Optional[str] = None
|
|
18
|
+
postflight_script: Optional[str] = None
|
|
19
|
+
|
|
20
|
+
@classmethod
|
|
21
|
+
def from_dict(cls, data: Dict[str, Any]) -> EnvironmentConfig:
|
|
22
|
+
"""Create an EnvironmentConfig from a dictionary."""
|
|
23
|
+
return cls(
|
|
24
|
+
preflight_script=data.get("preflight_script"),
|
|
25
|
+
postflight_script=data.get("postflight_script"),
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
29
|
+
"""Convert to dictionary for API requests."""
|
|
30
|
+
return {
|
|
31
|
+
"preflight_script": self.preflight_script,
|
|
32
|
+
"postflight_script": self.postflight_script,
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
@dataclass
|
|
37
|
+
class AlgorithmConfig:
|
|
38
|
+
"""Algorithm configuration for context learning optimization."""
|
|
39
|
+
|
|
40
|
+
initial_population_size: int = 10
|
|
41
|
+
num_generations: int = 5
|
|
42
|
+
children_per_generation: int = 5
|
|
43
|
+
mutation_llm_model: Optional[str] = None
|
|
44
|
+
mutation_llm_provider: str = "openai"
|
|
45
|
+
policy_config: Optional[Dict[str, Any]] = None
|
|
46
|
+
|
|
47
|
+
@classmethod
|
|
48
|
+
def from_dict(cls, data: Dict[str, Any]) -> AlgorithmConfig:
|
|
49
|
+
"""Create an AlgorithmConfig from a dictionary."""
|
|
50
|
+
return cls(
|
|
51
|
+
initial_population_size=data.get("initial_population_size", 10),
|
|
52
|
+
num_generations=data.get("num_generations", 5),
|
|
53
|
+
children_per_generation=data.get("children_per_generation", 5),
|
|
54
|
+
mutation_llm_model=data.get("mutation_llm_model"),
|
|
55
|
+
mutation_llm_provider=data.get("mutation_llm_provider", "openai"),
|
|
56
|
+
policy_config=data.get("policy_config"),
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
60
|
+
"""Convert to dictionary for API requests."""
|
|
61
|
+
result: Dict[str, Any] = {
|
|
62
|
+
"initial_population_size": self.initial_population_size,
|
|
63
|
+
"num_generations": self.num_generations,
|
|
64
|
+
"children_per_generation": self.children_per_generation,
|
|
65
|
+
"mutation_llm_provider": self.mutation_llm_provider,
|
|
66
|
+
}
|
|
67
|
+
if self.mutation_llm_model:
|
|
68
|
+
result["mutation_llm_model"] = self.mutation_llm_model
|
|
69
|
+
if self.policy_config:
|
|
70
|
+
result["policy_config"] = self.policy_config
|
|
71
|
+
return result
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
@dataclass
|
|
75
|
+
class ContextLearningJobConfig:
|
|
76
|
+
"""Configuration for creating a context learning job."""
|
|
77
|
+
|
|
78
|
+
task_app_url: str
|
|
79
|
+
evaluation_seeds: List[int]
|
|
80
|
+
task_app_api_key: Optional[str] = None
|
|
81
|
+
environment: Optional[EnvironmentConfig] = None
|
|
82
|
+
algorithm_config: Optional[AlgorithmConfig] = None
|
|
83
|
+
metadata: Optional[Dict[str, Any]] = None
|
|
84
|
+
org_id: Optional[str] = None
|
|
85
|
+
max_concurrent_rollouts: int = 10
|
|
86
|
+
verifier_base_url: Optional[str] = None
|
|
87
|
+
verifier_job_id: str = "zero_shot_verifier_rubric_mapreduce"
|
|
88
|
+
verifier_model: str = "gpt-4.1-mini"
|
|
89
|
+
require_agent_trace_log: bool = True
|
|
90
|
+
auto_start: bool = True
|
|
91
|
+
|
|
92
|
+
@classmethod
|
|
93
|
+
def from_dict(cls, data: Dict[str, Any]) -> ContextLearningJobConfig:
|
|
94
|
+
"""Create a ContextLearningJobConfig from a dictionary."""
|
|
95
|
+
env_data = data.get("environment")
|
|
96
|
+
env = EnvironmentConfig.from_dict(env_data) if isinstance(env_data, dict) else None
|
|
97
|
+
|
|
98
|
+
algo_data = data.get("algorithm_config")
|
|
99
|
+
algo = AlgorithmConfig.from_dict(algo_data) if isinstance(algo_data, dict) else None
|
|
100
|
+
|
|
101
|
+
return cls(
|
|
102
|
+
task_app_url=data["task_app_url"],
|
|
103
|
+
evaluation_seeds=data.get("evaluation_seeds", []),
|
|
104
|
+
task_app_api_key=data.get("task_app_api_key"),
|
|
105
|
+
environment=env,
|
|
106
|
+
algorithm_config=algo,
|
|
107
|
+
metadata=data.get("metadata"),
|
|
108
|
+
org_id=data.get("org_id"),
|
|
109
|
+
max_concurrent_rollouts=data.get("max_concurrent_rollouts", 10),
|
|
110
|
+
verifier_base_url=data.get("verifier_base_url"),
|
|
111
|
+
verifier_job_id=data.get("verifier_job_id", "zero_shot_verifier_rubric_mapreduce"),
|
|
112
|
+
verifier_model=data.get("verifier_model", "gpt-4.1-mini"),
|
|
113
|
+
require_agent_trace_log=data.get("require_agent_trace_log", True),
|
|
114
|
+
auto_start=data.get("auto_start", True),
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
118
|
+
"""Convert to dictionary for API requests."""
|
|
119
|
+
result: Dict[str, Any] = {
|
|
120
|
+
"task_app_url": self.task_app_url,
|
|
121
|
+
"evaluation_seeds": self.evaluation_seeds,
|
|
122
|
+
"max_concurrent_rollouts": self.max_concurrent_rollouts,
|
|
123
|
+
"verifier_job_id": self.verifier_job_id,
|
|
124
|
+
"verifier_model": self.verifier_model,
|
|
125
|
+
"require_agent_trace_log": self.require_agent_trace_log,
|
|
126
|
+
"auto_start": self.auto_start,
|
|
127
|
+
}
|
|
128
|
+
if self.task_app_api_key:
|
|
129
|
+
result["task_app_api_key"] = self.task_app_api_key
|
|
130
|
+
if self.environment:
|
|
131
|
+
result["environment"] = self.environment.to_dict()
|
|
132
|
+
if self.algorithm_config:
|
|
133
|
+
result["algorithm_config"] = self.algorithm_config.to_dict()
|
|
134
|
+
if self.metadata:
|
|
135
|
+
result["metadata"] = self.metadata
|
|
136
|
+
if self.org_id:
|
|
137
|
+
result["org_id"] = self.org_id
|
|
138
|
+
if self.verifier_base_url:
|
|
139
|
+
result["verifier_base_url"] = self.verifier_base_url
|
|
140
|
+
return result
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
@dataclass
|
|
144
|
+
class ContextLearningJobStatus:
|
|
145
|
+
"""Status of a context learning job."""
|
|
146
|
+
|
|
147
|
+
job_id: str
|
|
148
|
+
status: str
|
|
149
|
+
created_at: str
|
|
150
|
+
started_at: Optional[str] = None
|
|
151
|
+
finished_at: Optional[str] = None
|
|
152
|
+
best_score: Optional[float] = None
|
|
153
|
+
best_preflight_script: Optional[str] = None
|
|
154
|
+
environment: Optional[Dict[str, Any]] = None
|
|
155
|
+
metadata: Optional[Dict[str, Any]] = None
|
|
156
|
+
recent_events: List[Dict[str, Any]] = field(default_factory=list)
|
|
157
|
+
error: Optional[str] = None
|
|
158
|
+
|
|
159
|
+
@classmethod
|
|
160
|
+
def from_dict(cls, data: Dict[str, Any]) -> ContextLearningJobStatus:
|
|
161
|
+
"""Create a ContextLearningJobStatus from a dictionary."""
|
|
162
|
+
return cls(
|
|
163
|
+
job_id=data["job_id"],
|
|
164
|
+
status=data.get("status", "unknown"),
|
|
165
|
+
created_at=data.get("created_at", ""),
|
|
166
|
+
started_at=data.get("started_at"),
|
|
167
|
+
finished_at=data.get("finished_at"),
|
|
168
|
+
best_score=data.get("best_score"),
|
|
169
|
+
best_preflight_script=data.get("best_preflight_script"),
|
|
170
|
+
environment=data.get("environment"),
|
|
171
|
+
metadata=data.get("metadata"),
|
|
172
|
+
recent_events=data.get("recent_events", []),
|
|
173
|
+
error=data.get("error"),
|
|
174
|
+
)
|
|
175
|
+
|
|
176
|
+
@property
|
|
177
|
+
def is_terminal(self) -> bool:
|
|
178
|
+
"""Check if the job is in a terminal state."""
|
|
179
|
+
return self.status in {"completed", "succeeded", "failed", "cancelled"}
|
|
180
|
+
|
|
181
|
+
@property
|
|
182
|
+
def is_successful(self) -> bool:
|
|
183
|
+
"""Check if the job completed successfully."""
|
|
184
|
+
return self.status in {"completed", "succeeded"}
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
@dataclass
|
|
188
|
+
class ContextLearningEvent:
|
|
189
|
+
"""An event from a context learning job."""
|
|
190
|
+
|
|
191
|
+
event_type: str
|
|
192
|
+
message: str
|
|
193
|
+
timestamp: str
|
|
194
|
+
metadata: Dict[str, Any] = field(default_factory=dict)
|
|
195
|
+
seq: Optional[int] = None
|
|
196
|
+
|
|
197
|
+
@classmethod
|
|
198
|
+
def from_dict(cls, data: Dict[str, Any]) -> ContextLearningEvent:
|
|
199
|
+
"""Create a ContextLearningEvent from a dictionary."""
|
|
200
|
+
return cls(
|
|
201
|
+
event_type=data.get("event_type", data.get("type", "")),
|
|
202
|
+
message=data.get("message", ""),
|
|
203
|
+
timestamp=data.get("timestamp", data.get("created_at", "")),
|
|
204
|
+
metadata=data.get("metadata", data.get("data", {})),
|
|
205
|
+
seq=data.get("seq"),
|
|
206
|
+
)
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
@dataclass
|
|
210
|
+
class BestScriptResult:
|
|
211
|
+
"""Result containing the best performing pre-flight script."""
|
|
212
|
+
|
|
213
|
+
job_id: str
|
|
214
|
+
best_score: float
|
|
215
|
+
preflight_script: str
|
|
216
|
+
generation: int
|
|
217
|
+
variation_id: str
|
|
218
|
+
metadata: Dict[str, Any] = field(default_factory=dict)
|
|
219
|
+
|
|
220
|
+
@classmethod
|
|
221
|
+
def from_dict(cls, data: Dict[str, Any]) -> BestScriptResult:
|
|
222
|
+
"""Create a BestScriptResult from a dictionary."""
|
|
223
|
+
return cls(
|
|
224
|
+
job_id=data.get("job_id", ""),
|
|
225
|
+
best_score=float(data.get("best_score", 0.0)),
|
|
226
|
+
preflight_script=str(data.get("preflight_script", "")),
|
|
227
|
+
generation=int(data.get("generation", 0)),
|
|
228
|
+
variation_id=str(data.get("variation_id", "")),
|
|
229
|
+
metadata=data.get("metadata", {}),
|
|
230
|
+
)
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
@dataclass
|
|
234
|
+
class ContextLearningMetric:
|
|
235
|
+
"""A metric point from context learning optimization."""
|
|
236
|
+
|
|
237
|
+
name: str
|
|
238
|
+
value: float
|
|
239
|
+
step: int
|
|
240
|
+
timestamp: str
|
|
241
|
+
data: Dict[str, Any] = field(default_factory=dict)
|
|
242
|
+
|
|
243
|
+
@classmethod
|
|
244
|
+
def from_dict(cls, data: Dict[str, Any]) -> ContextLearningMetric:
|
|
245
|
+
"""Create a ContextLearningMetric from a dictionary."""
|
|
246
|
+
return cls(
|
|
247
|
+
name=data.get("name", ""),
|
|
248
|
+
value=float(data.get("value", 0.0)),
|
|
249
|
+
step=int(data.get("step", 0)),
|
|
250
|
+
timestamp=data.get("timestamp", data.get("created_at", "")),
|
|
251
|
+
data=data.get("data", {}),
|
|
252
|
+
)
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
@dataclass
|
|
256
|
+
class ContextLearningResults:
|
|
257
|
+
"""Complete results from a context learning job."""
|
|
258
|
+
|
|
259
|
+
job_id: str
|
|
260
|
+
status: str
|
|
261
|
+
best_score: Optional[float] = None
|
|
262
|
+
best_script: Optional[BestScriptResult] = None
|
|
263
|
+
generations_completed: int = 0
|
|
264
|
+
events: List[ContextLearningEvent] = field(default_factory=list)
|
|
265
|
+
metrics: List[ContextLearningMetric] = field(default_factory=list)
|
|
266
|
+
|
|
267
|
+
@classmethod
|
|
268
|
+
def from_status_and_events(
|
|
269
|
+
cls,
|
|
270
|
+
status: ContextLearningJobStatus,
|
|
271
|
+
events: List[ContextLearningEvent],
|
|
272
|
+
best_script: Optional[BestScriptResult] = None,
|
|
273
|
+
) -> ContextLearningResults:
|
|
274
|
+
"""Create results from status and events."""
|
|
275
|
+
# Extract generation count from events
|
|
276
|
+
generations_completed = 0
|
|
277
|
+
for event in events:
|
|
278
|
+
if event.event_type == "context.learning.generation.completed":
|
|
279
|
+
gen = event.metadata.get("generation", 0)
|
|
280
|
+
if isinstance(gen, int) and gen > generations_completed:
|
|
281
|
+
generations_completed = gen
|
|
282
|
+
|
|
283
|
+
return cls(
|
|
284
|
+
job_id=status.job_id,
|
|
285
|
+
status=status.status,
|
|
286
|
+
best_score=status.best_score,
|
|
287
|
+
best_script=best_script,
|
|
288
|
+
generations_completed=generations_completed,
|
|
289
|
+
events=events,
|
|
290
|
+
)
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
|
|
@@ -214,6 +214,7 @@ class PromptLearningClient:
|
|
|
214
214
|
elif event_type == "prompt.learning.final.results":
|
|
215
215
|
result.optimized_candidates = event_data.get("optimized_candidates", [])
|
|
216
216
|
result.attempted_candidates = event_data.get("attempted_candidates", [])
|
|
217
|
+
result.version_tree = event_data.get("version_tree")
|
|
217
218
|
# Also extract best_prompt from final.results if not already set
|
|
218
219
|
if result.best_prompt is None:
|
|
219
220
|
result.best_prompt = event_data.get("best_prompt")
|
|
@@ -452,4 +453,3 @@ def get_scoring_summary(job_id: str, base_url: str, api_key: str) -> Dict[str, A
|
|
|
452
453
|
|
|
453
454
|
client = PromptLearningClient(base_url, api_key)
|
|
454
455
|
return asyncio.run(client.get_scoring_summary(job_id))
|
|
455
|
-
|
|
@@ -165,6 +165,7 @@ class PromptResults:
|
|
|
165
165
|
|
|
166
166
|
best_prompt: Optional[Dict[str, Any]] = None
|
|
167
167
|
best_score: Optional[float] = None
|
|
168
|
+
version_tree: Optional[Dict[str, Any]] = None
|
|
168
169
|
top_prompts: List[Dict[str, Any]] = field(default_factory=list)
|
|
169
170
|
optimized_candidates: List[Dict[str, Any]] = field(default_factory=list)
|
|
170
171
|
attempted_candidates: List[Dict[str, Any]] = field(default_factory=list)
|
|
@@ -176,10 +177,10 @@ class PromptResults:
|
|
|
176
177
|
return cls(
|
|
177
178
|
best_prompt=data.get("best_prompt"),
|
|
178
179
|
best_score=data.get("best_score"),
|
|
180
|
+
version_tree=data.get("version_tree"),
|
|
179
181
|
top_prompts=data.get("top_prompts", []),
|
|
180
182
|
optimized_candidates=data.get("optimized_candidates", []),
|
|
181
183
|
attempted_candidates=data.get("attempted_candidates", []),
|
|
182
184
|
validation_results=data.get("validation_results", []),
|
|
183
185
|
)
|
|
184
186
|
|
|
185
|
-
|
|
@@ -10,8 +10,6 @@ from .contracts import (
|
|
|
10
10
|
RolloutRequest,
|
|
11
11
|
RolloutResponse,
|
|
12
12
|
RolloutSafetyConfig,
|
|
13
|
-
RolloutStep,
|
|
14
|
-
RolloutTrajectory,
|
|
15
13
|
)
|
|
16
14
|
from .env_keys import (
|
|
17
15
|
MAX_ENVIRONMENT_API_KEY_BYTES,
|
|
@@ -28,8 +26,6 @@ __all__ = [
|
|
|
28
26
|
"RolloutRecordConfig",
|
|
29
27
|
"RolloutSafetyConfig",
|
|
30
28
|
"RolloutRequest",
|
|
31
|
-
"RolloutStep",
|
|
32
|
-
"RolloutTrajectory",
|
|
33
29
|
"RolloutMetrics",
|
|
34
30
|
"RolloutResponse",
|
|
35
31
|
"encrypt_for_backend",
|
|
@@ -10,8 +10,6 @@ from synth_ai.sdk.task.contracts import (
|
|
|
10
10
|
RolloutRequest,
|
|
11
11
|
RolloutResponse,
|
|
12
12
|
RolloutSafetyConfig,
|
|
13
|
-
RolloutStep,
|
|
14
|
-
RolloutTrajectory,
|
|
15
13
|
)
|
|
16
14
|
|
|
17
15
|
__all__ = [
|
|
@@ -20,8 +18,6 @@ __all__ = [
|
|
|
20
18
|
"RolloutRecordConfig",
|
|
21
19
|
"RolloutSafetyConfig",
|
|
22
20
|
"RolloutRequest",
|
|
23
|
-
"RolloutStep",
|
|
24
|
-
"RolloutTrajectory",
|
|
25
21
|
"RolloutMetrics",
|
|
26
22
|
"RolloutResponse",
|
|
27
23
|
]
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"""LocalAPI SDK surface.
|
|
2
|
+
|
|
3
|
+
Prefer this module over synth_ai.sdk.task.* moving forward. The task namespace
|
|
4
|
+
remains for backward compatibility while the naming transition completes.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from synth_ai.sdk.api.train.local_api import LocalAPIHealth, check_local_api_health
|
|
10
|
+
from synth_ai.sdk.task import (
|
|
11
|
+
InProcessTaskApp,
|
|
12
|
+
LocalAPIClient,
|
|
13
|
+
LocalAPIConfig,
|
|
14
|
+
LocalAPIEndpoints,
|
|
15
|
+
TaskInfo,
|
|
16
|
+
create_task_app,
|
|
17
|
+
run_task_app,
|
|
18
|
+
)
|
|
19
|
+
from .rollouts import RolloutResponseBuilder
|
|
20
|
+
|
|
21
|
+
create_local_api = create_task_app
|
|
22
|
+
run_local_api = run_task_app
|
|
23
|
+
from .template import build_template_config, create_template_app
|
|
24
|
+
|
|
25
|
+
__all__ = [
|
|
26
|
+
"LocalAPIClient",
|
|
27
|
+
"LocalAPIConfig",
|
|
28
|
+
"LocalAPIEndpoints",
|
|
29
|
+
"LocalAPIHealth",
|
|
30
|
+
"check_local_api_health",
|
|
31
|
+
"InProcessTaskApp",
|
|
32
|
+
"TaskInfo",
|
|
33
|
+
"create_task_app",
|
|
34
|
+
"create_local_api",
|
|
35
|
+
"run_task_app",
|
|
36
|
+
"run_local_api",
|
|
37
|
+
"RolloutResponseBuilder",
|
|
38
|
+
"build_template_config",
|
|
39
|
+
"create_template_app",
|
|
40
|
+
]
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"""LocalAPI app registry re-exports.
|
|
2
|
+
|
|
3
|
+
Prefer this module over synth_ai.sdk.task.apps.* moving forward.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
from synth_ai.sdk.task.apps import (
|
|
9
|
+
LocalAPIEntry,
|
|
10
|
+
ModalDeploymentConfig,
|
|
11
|
+
TaskAppEntry,
|
|
12
|
+
TaskAppRegistry,
|
|
13
|
+
discover_task_apps_from_cwd,
|
|
14
|
+
register_local_api,
|
|
15
|
+
register_task_app,
|
|
16
|
+
registry,
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
__all__ = [
|
|
20
|
+
"LocalAPIEntry",
|
|
21
|
+
"ModalDeploymentConfig",
|
|
22
|
+
"TaskAppEntry",
|
|
23
|
+
"TaskAppRegistry",
|
|
24
|
+
"discover_task_apps_from_cwd",
|
|
25
|
+
"register_local_api",
|
|
26
|
+
"register_task_app",
|
|
27
|
+
"registry",
|
|
28
|
+
]
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"""LocalAPI client re-exports.
|
|
2
|
+
|
|
3
|
+
Prefer this module over synth_ai.sdk.task.client.* moving forward.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
from synth_ai.sdk.task.client import LocalAPIClient, TaskAppClient
|
|
9
|
+
|
|
10
|
+
__all__ = ["LocalAPIClient", "TaskAppClient"]
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"""LocalAPI contract re-exports.
|
|
2
|
+
|
|
3
|
+
Prefer this module over synth_ai.sdk.task.contracts.* moving forward.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
from synth_ai.sdk.task.contracts import LocalAPIEndpoints, TaskAppEndpoints
|
|
9
|
+
|
|
10
|
+
__all__ = ["LocalAPIEndpoints", "TaskAppEndpoints"]
|