fleet-python 0.2.42__tar.gz → 0.2.44__tar.gz
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 fleet-python might be problematic. Click here for more details.
- {fleet_python-0.2.42 → fleet_python-0.2.44}/PKG-INFO +1 -1
- {fleet_python-0.2.42 → fleet_python-0.2.44}/fleet/__init__.py +9 -7
- {fleet_python-0.2.42 → fleet_python-0.2.44}/fleet/_async/__init__.py +28 -16
- {fleet_python-0.2.42 → fleet_python-0.2.44}/fleet/_async/client.py +161 -69
- {fleet_python-0.2.42 → fleet_python-0.2.44}/fleet/_async/env/client.py +9 -2
- {fleet_python-0.2.42 → fleet_python-0.2.44}/fleet/_async/instance/client.py +1 -1
- {fleet_python-0.2.42 → fleet_python-0.2.44}/fleet/_async/resources/sqlite.py +34 -34
- {fleet_python-0.2.42 → fleet_python-0.2.44}/fleet/_async/tasks.py +42 -41
- {fleet_python-0.2.42 → fleet_python-0.2.44}/fleet/_async/verifiers/verifier.py +3 -3
- {fleet_python-0.2.42 → fleet_python-0.2.44}/fleet/client.py +164 -61
- {fleet_python-0.2.42 → fleet_python-0.2.44}/fleet/env/client.py +9 -2
- {fleet_python-0.2.42 → fleet_python-0.2.44}/fleet/instance/client.py +2 -4
- {fleet_python-0.2.42 → fleet_python-0.2.44}/fleet/models.py +3 -1
- {fleet_python-0.2.42 → fleet_python-0.2.44}/fleet/resources/sqlite.py +37 -43
- {fleet_python-0.2.42 → fleet_python-0.2.44}/fleet/tasks.py +49 -65
- {fleet_python-0.2.42 → fleet_python-0.2.44}/fleet/verifiers/__init__.py +1 -1
- {fleet_python-0.2.42 → fleet_python-0.2.44}/fleet/verifiers/db.py +41 -36
- {fleet_python-0.2.42 → fleet_python-0.2.44}/fleet/verifiers/parse.py +4 -1
- {fleet_python-0.2.42 → fleet_python-0.2.44}/fleet/verifiers/sql_differ.py +8 -8
- {fleet_python-0.2.42 → fleet_python-0.2.44}/fleet/verifiers/verifier.py +19 -7
- {fleet_python-0.2.42 → fleet_python-0.2.44}/fleet_python.egg-info/PKG-INFO +1 -1
- {fleet_python-0.2.42 → fleet_python-0.2.44}/pyproject.toml +1 -1
- {fleet_python-0.2.42 → fleet_python-0.2.44}/LICENSE +0 -0
- {fleet_python-0.2.42 → fleet_python-0.2.44}/README.md +0 -0
- {fleet_python-0.2.42 → fleet_python-0.2.44}/examples/diff_example.py +0 -0
- {fleet_python-0.2.42 → fleet_python-0.2.44}/examples/dsl_example.py +0 -0
- {fleet_python-0.2.42 → fleet_python-0.2.44}/examples/example.py +0 -0
- {fleet_python-0.2.42 → fleet_python-0.2.44}/examples/exampleResume.py +0 -0
- {fleet_python-0.2.42 → fleet_python-0.2.44}/examples/example_account.py +0 -0
- {fleet_python-0.2.42 → fleet_python-0.2.44}/examples/example_action_log.py +0 -0
- {fleet_python-0.2.42 → fleet_python-0.2.44}/examples/example_client.py +0 -0
- {fleet_python-0.2.42 → fleet_python-0.2.44}/examples/example_mcp_anthropic.py +0 -0
- {fleet_python-0.2.42 → fleet_python-0.2.44}/examples/example_mcp_openai.py +0 -0
- {fleet_python-0.2.42 → fleet_python-0.2.44}/examples/example_sync.py +0 -0
- {fleet_python-0.2.42 → fleet_python-0.2.44}/examples/example_task.py +0 -0
- {fleet_python-0.2.42 → fleet_python-0.2.44}/examples/example_tasks.py +0 -0
- {fleet_python-0.2.42 → fleet_python-0.2.44}/examples/example_verifier.py +0 -0
- {fleet_python-0.2.42 → fleet_python-0.2.44}/examples/gemini_example.py +0 -0
- {fleet_python-0.2.42 → fleet_python-0.2.44}/examples/json_tasks_example.py +0 -0
- {fleet_python-0.2.42 → fleet_python-0.2.44}/examples/nova_act_example.py +0 -0
- {fleet_python-0.2.42 → fleet_python-0.2.44}/examples/openai_example.py +0 -0
- {fleet_python-0.2.42 → fleet_python-0.2.44}/examples/openai_simple_example.py +0 -0
- {fleet_python-0.2.42 → fleet_python-0.2.44}/examples/query_builder_example.py +0 -0
- {fleet_python-0.2.42 → fleet_python-0.2.44}/examples/quickstart.py +0 -0
- {fleet_python-0.2.42 → fleet_python-0.2.44}/examples/test_cdp_logging.py +0 -0
- {fleet_python-0.2.42 → fleet_python-0.2.44}/fleet/_async/base.py +0 -0
- {fleet_python-0.2.42 → fleet_python-0.2.44}/fleet/_async/env/__init__.py +0 -0
- {fleet_python-0.2.42 → fleet_python-0.2.44}/fleet/_async/exceptions.py +0 -0
- {fleet_python-0.2.42 → fleet_python-0.2.44}/fleet/_async/global_client.py +0 -0
- {fleet_python-0.2.42 → fleet_python-0.2.44}/fleet/_async/instance/__init__.py +0 -0
- {fleet_python-0.2.42 → fleet_python-0.2.44}/fleet/_async/instance/base.py +0 -0
- {fleet_python-0.2.42 → fleet_python-0.2.44}/fleet/_async/models.py +0 -0
- {fleet_python-0.2.42 → fleet_python-0.2.44}/fleet/_async/resources/__init__.py +0 -0
- {fleet_python-0.2.42 → fleet_python-0.2.44}/fleet/_async/resources/base.py +0 -0
- {fleet_python-0.2.42 → fleet_python-0.2.44}/fleet/_async/resources/browser.py +0 -0
- {fleet_python-0.2.42 → fleet_python-0.2.44}/fleet/_async/resources/mcp.py +0 -0
- {fleet_python-0.2.42 → fleet_python-0.2.44}/fleet/_async/verifiers/__init__.py +0 -0
- {fleet_python-0.2.42 → fleet_python-0.2.44}/fleet/_async/verifiers/bundler.py +0 -0
- {fleet_python-0.2.42 → fleet_python-0.2.44}/fleet/base.py +0 -0
- {fleet_python-0.2.42 → fleet_python-0.2.44}/fleet/config.py +0 -0
- {fleet_python-0.2.42 → fleet_python-0.2.44}/fleet/env/__init__.py +0 -0
- {fleet_python-0.2.42 → fleet_python-0.2.44}/fleet/exceptions.py +0 -0
- {fleet_python-0.2.42 → fleet_python-0.2.44}/fleet/global_client.py +0 -0
- {fleet_python-0.2.42 → fleet_python-0.2.44}/fleet/instance/__init__.py +0 -0
- {fleet_python-0.2.42 → fleet_python-0.2.44}/fleet/instance/base.py +0 -0
- {fleet_python-0.2.42 → fleet_python-0.2.44}/fleet/instance/models.py +0 -0
- {fleet_python-0.2.42 → fleet_python-0.2.44}/fleet/resources/__init__.py +0 -0
- {fleet_python-0.2.42 → fleet_python-0.2.44}/fleet/resources/base.py +0 -0
- {fleet_python-0.2.42 → fleet_python-0.2.44}/fleet/resources/browser.py +0 -0
- {fleet_python-0.2.42 → fleet_python-0.2.44}/fleet/resources/mcp.py +0 -0
- {fleet_python-0.2.42 → fleet_python-0.2.44}/fleet/types.py +0 -0
- {fleet_python-0.2.42 → fleet_python-0.2.44}/fleet/verifiers/bundler.py +0 -0
- {fleet_python-0.2.42 → fleet_python-0.2.44}/fleet/verifiers/code.py +0 -0
- {fleet_python-0.2.42 → fleet_python-0.2.44}/fleet/verifiers/decorator.py +0 -0
- {fleet_python-0.2.42 → fleet_python-0.2.44}/fleet_python.egg-info/SOURCES.txt +0 -0
- {fleet_python-0.2.42 → fleet_python-0.2.44}/fleet_python.egg-info/dependency_links.txt +0 -0
- {fleet_python-0.2.42 → fleet_python-0.2.44}/fleet_python.egg-info/requires.txt +0 -0
- {fleet_python-0.2.42 → fleet_python-0.2.44}/fleet_python.egg-info/top_level.txt +0 -0
- {fleet_python-0.2.42 → fleet_python-0.2.44}/scripts/fix_sync_imports.py +0 -0
- {fleet_python-0.2.42 → fleet_python-0.2.44}/scripts/unasync.py +0 -0
- {fleet_python-0.2.42 → fleet_python-0.2.44}/setup.cfg +0 -0
|
@@ -46,11 +46,15 @@ from ._async.verifiers import (
|
|
|
46
46
|
AsyncVerifierFunction,
|
|
47
47
|
)
|
|
48
48
|
|
|
49
|
-
# Import async tasks (default tasks are async for modern usage)
|
|
50
|
-
from ._async.tasks import
|
|
49
|
+
# Import async tasks (default tasks are async for modern usage)
|
|
50
|
+
from ._async.tasks import (
|
|
51
|
+
Task,
|
|
52
|
+
load_tasks as load_tasks_async,
|
|
53
|
+
load_tasks_from_file as load_tasks_from_file_async,
|
|
54
|
+
)
|
|
51
55
|
|
|
52
56
|
# Import sync load_tasks function
|
|
53
|
-
from .tasks import load_tasks
|
|
57
|
+
from .tasks import load_tasks, load_tasks_from_file
|
|
54
58
|
|
|
55
59
|
# Import shared types
|
|
56
60
|
from .types import VerifierFunction
|
|
@@ -105,13 +109,11 @@ __all__ = [
|
|
|
105
109
|
]
|
|
106
110
|
|
|
107
111
|
|
|
108
|
-
|
|
109
|
-
|
|
110
112
|
def configure(
|
|
111
113
|
api_key: Optional[str] = None,
|
|
112
114
|
base_url: Optional[str] = None,
|
|
113
|
-
max_retries: int
|
|
114
|
-
timeout: float
|
|
115
|
+
max_retries: Optional[int] = None,
|
|
116
|
+
timeout: Optional[float] = None,
|
|
115
117
|
):
|
|
116
118
|
"""Configure global clients (sync and async) once per process.
|
|
117
119
|
|
|
@@ -73,17 +73,17 @@ __all__ = [
|
|
|
73
73
|
"reset_client",
|
|
74
74
|
# Module-level functions
|
|
75
75
|
"load_tasks",
|
|
76
|
-
"list_envs",
|
|
76
|
+
"list_envs",
|
|
77
77
|
"list_regions",
|
|
78
78
|
"environment",
|
|
79
79
|
"make",
|
|
80
80
|
"make_for_task",
|
|
81
81
|
"instances",
|
|
82
|
-
"instance",
|
|
82
|
+
"instance",
|
|
83
83
|
"delete",
|
|
84
84
|
"load_tasks_from_file",
|
|
85
85
|
"load_task_array_from_string",
|
|
86
|
-
"load_task_from_string",
|
|
86
|
+
"load_task_from_string",
|
|
87
87
|
"load_task_from_json",
|
|
88
88
|
"export_tasks",
|
|
89
89
|
"import_tasks",
|
|
@@ -108,9 +108,13 @@ async def environment(env_key: str) -> Environment:
|
|
|
108
108
|
return await _async_global_client.get_client().environment(env_key)
|
|
109
109
|
|
|
110
110
|
|
|
111
|
-
async def make(
|
|
111
|
+
async def make(
|
|
112
|
+
env_key: str,
|
|
113
|
+
region: Optional[str] = None,
|
|
114
|
+
env_variables: Optional[Dict[str, Any]] = None,
|
|
115
|
+
) -> AsyncEnv:
|
|
112
116
|
"""Create a new environment instance.
|
|
113
|
-
|
|
117
|
+
|
|
114
118
|
Example:
|
|
115
119
|
env = await fleet.make("fira")
|
|
116
120
|
env_with_vars = await fleet.make("fira", env_variables={"LOGGED_IN_NAME": "Alice"})
|
|
@@ -123,7 +127,9 @@ async def make_for_task(task: Task) -> AsyncEnv:
|
|
|
123
127
|
return await _async_global_client.get_client().make_for_task(task)
|
|
124
128
|
|
|
125
129
|
|
|
126
|
-
async def instances(
|
|
130
|
+
async def instances(
|
|
131
|
+
status: Optional[str] = None, region: Optional[str] = None
|
|
132
|
+
) -> List[AsyncEnv]:
|
|
127
133
|
"""List existing environment instances."""
|
|
128
134
|
return await _async_global_client.get_client().instances(status, region)
|
|
129
135
|
|
|
@@ -140,7 +146,7 @@ async def delete(instance_id: str) -> InstanceResponse:
|
|
|
140
146
|
|
|
141
147
|
async def load_tasks_from_file(filename: str) -> List[Task]:
|
|
142
148
|
"""Load tasks from a JSON file.
|
|
143
|
-
|
|
149
|
+
|
|
144
150
|
Example:
|
|
145
151
|
tasks = await fleet.load_tasks_from_file("my_tasks.json")
|
|
146
152
|
"""
|
|
@@ -149,16 +155,18 @@ async def load_tasks_from_file(filename: str) -> List[Task]:
|
|
|
149
155
|
|
|
150
156
|
async def load_task_array_from_string(serialized_tasks: str) -> List[Task]:
|
|
151
157
|
"""Load tasks from a JSON string containing an array of tasks.
|
|
152
|
-
|
|
158
|
+
|
|
153
159
|
Example:
|
|
154
160
|
tasks = await fleet.load_task_array_from_string(json_string)
|
|
155
161
|
"""
|
|
156
|
-
return await _async_global_client.get_client().load_task_array_from_string(
|
|
162
|
+
return await _async_global_client.get_client().load_task_array_from_string(
|
|
163
|
+
serialized_tasks
|
|
164
|
+
)
|
|
157
165
|
|
|
158
166
|
|
|
159
167
|
async def load_task_from_string(task_string: str) -> Task:
|
|
160
168
|
"""Load a single task from a JSON string.
|
|
161
|
-
|
|
169
|
+
|
|
162
170
|
Example:
|
|
163
171
|
task = await fleet.load_task_from_string(task_json_string)
|
|
164
172
|
"""
|
|
@@ -167,16 +175,18 @@ async def load_task_from_string(task_string: str) -> Task:
|
|
|
167
175
|
|
|
168
176
|
async def load_task_from_json(task_json: dict) -> Task:
|
|
169
177
|
"""Load a single task from a dictionary.
|
|
170
|
-
|
|
178
|
+
|
|
171
179
|
Example:
|
|
172
180
|
task = await fleet.load_task_from_json(task_dict)
|
|
173
181
|
"""
|
|
174
182
|
return await _async_global_client.get_client().load_task_from_json(task_json)
|
|
175
183
|
|
|
176
184
|
|
|
177
|
-
async def export_tasks(
|
|
185
|
+
async def export_tasks(
|
|
186
|
+
env_key: Optional[str] = None, filename: Optional[str] = None
|
|
187
|
+
) -> Optional[str]:
|
|
178
188
|
"""Export tasks to a JSON file.
|
|
179
|
-
|
|
189
|
+
|
|
180
190
|
Example:
|
|
181
191
|
await fleet.export_tasks("fira", "fira_tasks.json")
|
|
182
192
|
"""
|
|
@@ -185,7 +195,7 @@ async def export_tasks(env_key: Optional[str] = None, filename: Optional[str] =
|
|
|
185
195
|
|
|
186
196
|
async def import_tasks(filename: str):
|
|
187
197
|
"""Import tasks from a JSON file.
|
|
188
|
-
|
|
198
|
+
|
|
189
199
|
Example:
|
|
190
200
|
await fleet.import_tasks("tasks.json")
|
|
191
201
|
"""
|
|
@@ -200,8 +210,8 @@ async def account() -> AccountResponse:
|
|
|
200
210
|
def configure(
|
|
201
211
|
api_key: Optional[str] = None,
|
|
202
212
|
base_url: Optional[str] = None,
|
|
203
|
-
max_retries: int
|
|
204
|
-
timeout: float
|
|
213
|
+
max_retries: Optional[int] = None,
|
|
214
|
+
timeout: Optional[float] = None,
|
|
205
215
|
):
|
|
206
216
|
"""Configure global async client once per process.
|
|
207
217
|
|
|
@@ -213,9 +223,11 @@ def configure(
|
|
|
213
223
|
"""
|
|
214
224
|
if max_retries is None:
|
|
215
225
|
from ..config import DEFAULT_MAX_RETRIES as _MR
|
|
226
|
+
|
|
216
227
|
max_retries = _MR
|
|
217
228
|
if timeout is None:
|
|
218
229
|
from ..config import DEFAULT_TIMEOUT as _TO
|
|
230
|
+
|
|
219
231
|
timeout = _TO
|
|
220
232
|
_async_global_client.configure(
|
|
221
233
|
api_key=api_key, base_url=base_url, max_retries=max_retries, timeout=timeout
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
"""Fleet API Client for making HTTP requests to Fleet services."""
|
|
16
16
|
|
|
17
|
+
import asyncio
|
|
17
18
|
import base64
|
|
18
19
|
import cloudpickle
|
|
19
20
|
import httpx
|
|
@@ -129,7 +130,7 @@ class AsyncEnv(EnvironmentBase):
|
|
|
129
130
|
return await self.instance.verify(validator)
|
|
130
131
|
|
|
131
132
|
async def verify_raw(
|
|
132
|
-
self, function_code: str, function_name: str
|
|
133
|
+
self, function_code: str, function_name: Optional[str] = None
|
|
133
134
|
) -> ExecuteFunctionResponse:
|
|
134
135
|
return await self.instance.verify_raw(function_code, function_name)
|
|
135
136
|
|
|
@@ -206,24 +207,39 @@ class AsyncFleet:
|
|
|
206
207
|
async def make(
|
|
207
208
|
self,
|
|
208
209
|
env_key: str,
|
|
210
|
+
data_key: Optional[str] = None,
|
|
209
211
|
region: Optional[str] = None,
|
|
210
212
|
env_variables: Optional[Dict[str, Any]] = None,
|
|
211
213
|
) -> AsyncEnv:
|
|
212
214
|
if ":" in env_key:
|
|
213
|
-
env_key_part,
|
|
215
|
+
env_key_part, env_version = env_key.split(":", 1)
|
|
214
216
|
if (
|
|
215
|
-
not
|
|
216
|
-
and len(
|
|
217
|
-
and
|
|
217
|
+
not env_version.startswith("v")
|
|
218
|
+
and len(env_version) != 0
|
|
219
|
+
and env_version[0].isdigit()
|
|
218
220
|
):
|
|
219
|
-
|
|
221
|
+
env_version = f"v{env_version}"
|
|
220
222
|
else:
|
|
221
223
|
env_key_part = env_key
|
|
222
|
-
|
|
224
|
+
env_version = None
|
|
225
|
+
|
|
226
|
+
if data_key is not None and ":" in data_key:
|
|
227
|
+
data_key_part, data_version = data_key.split(":", 1)
|
|
228
|
+
if (
|
|
229
|
+
not data_version.startswith("v")
|
|
230
|
+
and len(data_version) != 0
|
|
231
|
+
and data_version[0].isdigit()
|
|
232
|
+
):
|
|
233
|
+
data_version = f"v{data_version}"
|
|
234
|
+
else:
|
|
235
|
+
data_key_part = data_key
|
|
236
|
+
data_version = None
|
|
223
237
|
|
|
224
238
|
request = InstanceRequest(
|
|
225
239
|
env_key=env_key_part,
|
|
226
|
-
|
|
240
|
+
env_version=env_version,
|
|
241
|
+
data_key=data_key_part,
|
|
242
|
+
data_version=data_version,
|
|
227
243
|
region=region,
|
|
228
244
|
env_variables=env_variables,
|
|
229
245
|
created_from="sdk",
|
|
@@ -286,43 +302,72 @@ class AsyncFleet:
|
|
|
286
302
|
with open(filename, "r", encoding="utf-8") as f:
|
|
287
303
|
tasks_data = f.read()
|
|
288
304
|
|
|
289
|
-
return self.load_task_array_from_string(tasks_data)
|
|
305
|
+
return await self.load_task_array_from_string(tasks_data)
|
|
290
306
|
|
|
291
|
-
async def load_task_array_from_string(
|
|
292
|
-
self, serialized_tasks: List[Dict]
|
|
293
|
-
) -> List[Task]:
|
|
307
|
+
async def load_task_array_from_string(self, serialized_tasks: str) -> List[Task]:
|
|
294
308
|
tasks = []
|
|
295
309
|
|
|
296
|
-
|
|
310
|
+
parsed_data = json.loads(serialized_tasks)
|
|
311
|
+
if isinstance(parsed_data, list):
|
|
312
|
+
json_tasks = parsed_data
|
|
313
|
+
elif isinstance(parsed_data, dict) and "tasks" in parsed_data:
|
|
314
|
+
json_tasks = parsed_data["tasks"]
|
|
315
|
+
else:
|
|
316
|
+
raise ValueError(
|
|
317
|
+
"Invalid JSON structure: expected array or object with 'tasks' key"
|
|
318
|
+
)
|
|
319
|
+
|
|
297
320
|
for json_task in json_tasks:
|
|
298
|
-
parsed_task = self.load_task_from_json(json_task)
|
|
321
|
+
parsed_task = await self.load_task_from_json(json_task)
|
|
299
322
|
tasks.append(parsed_task)
|
|
300
323
|
return tasks
|
|
301
324
|
|
|
302
325
|
async def load_task_from_string(self, task_string: str) -> Task:
|
|
303
326
|
task_json = json.loads(task_string)
|
|
304
|
-
return self.load_task_from_json(task_json)
|
|
327
|
+
return await self.load_task_from_json(task_json)
|
|
305
328
|
|
|
306
329
|
async def load_task_from_json(self, task_json: Dict) -> Task:
|
|
330
|
+
verifier = None
|
|
331
|
+
verifier_code = task_json.get("verifier_func") or task_json.get("verifier_code")
|
|
332
|
+
|
|
333
|
+
# Try to find verifier_id in multiple locations
|
|
334
|
+
verifier_id = task_json.get("verifier_id")
|
|
335
|
+
if (
|
|
336
|
+
not verifier_id
|
|
337
|
+
and "metadata" in task_json
|
|
338
|
+
and isinstance(task_json["metadata"], dict)
|
|
339
|
+
):
|
|
340
|
+
verifier_metadata = task_json["metadata"].get("verifier", {})
|
|
341
|
+
if isinstance(verifier_metadata, dict):
|
|
342
|
+
verifier_id = verifier_metadata.get("verifier_id")
|
|
343
|
+
|
|
344
|
+
# If no verifier_id found, use the task key/id as fallback
|
|
345
|
+
if not verifier_id:
|
|
346
|
+
verifier_id = task_json.get("key", task_json.get("id"))
|
|
347
|
+
|
|
307
348
|
try:
|
|
308
|
-
if
|
|
309
|
-
verifier = self._create_verifier_from_data(
|
|
310
|
-
verifier_id=
|
|
311
|
-
verifier_key=task_json
|
|
312
|
-
verifier_code=
|
|
349
|
+
if verifier_id and verifier_code:
|
|
350
|
+
verifier = await self._create_verifier_from_data(
|
|
351
|
+
verifier_id=verifier_id,
|
|
352
|
+
verifier_key=task_json.get("key", task_json.get("id")),
|
|
353
|
+
verifier_code=verifier_code,
|
|
313
354
|
verifier_sha=task_json.get("verifier_sha", ""),
|
|
314
355
|
)
|
|
315
356
|
except Exception as e:
|
|
316
|
-
logger.warning(
|
|
357
|
+
logger.warning(
|
|
358
|
+
f"Failed to create verifier {task_json.get('key', task_json.get('id'))}: {e}"
|
|
359
|
+
)
|
|
317
360
|
|
|
318
361
|
task = Task(
|
|
319
|
-
key=task_json
|
|
362
|
+
key=task_json.get("key", task_json.get("id")),
|
|
320
363
|
prompt=task_json["prompt"],
|
|
321
|
-
env_id=task_json
|
|
322
|
-
|
|
364
|
+
env_id=task_json.get(
|
|
365
|
+
"env_id", task_json.get("env_key")
|
|
366
|
+
), # Use env_id or fallback to env_key
|
|
367
|
+
created_at=task_json.get("created_at"),
|
|
323
368
|
version=task_json.get("version"),
|
|
324
369
|
env_variables=task_json.get("env_variables", {}),
|
|
325
|
-
verifier_func=
|
|
370
|
+
verifier_func=verifier_code, # Set verifier code
|
|
326
371
|
verifier=verifier, # Use created verifier or None
|
|
327
372
|
metadata=task_json.get("metadata", {}), # Default empty metadata
|
|
328
373
|
)
|
|
@@ -357,48 +402,99 @@ class AsyncFleet:
|
|
|
357
402
|
response = await self.client.request("GET", "/v1/tasks", params=params)
|
|
358
403
|
task_list_response = TaskListResponse(**response.json())
|
|
359
404
|
|
|
360
|
-
#
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
verifier = None
|
|
365
|
-
verifier_func = task_response.verifier_func
|
|
405
|
+
# Prepare verifier loading coroutines with concurrency limit
|
|
406
|
+
verifier_coroutines = []
|
|
407
|
+
task_responses_with_indices = []
|
|
408
|
+
semaphore = asyncio.Semaphore(100) # Limit to 10 concurrent operations
|
|
366
409
|
|
|
410
|
+
for idx, task_response in enumerate(task_list_response.tasks):
|
|
367
411
|
if task_response.verifier:
|
|
368
412
|
embedded_code = task_response.verifier.code or ""
|
|
369
413
|
is_embedded_error = embedded_code.strip().startswith(
|
|
370
414
|
"<error loading code:"
|
|
371
415
|
)
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
416
|
+
|
|
417
|
+
async def create_verifier_with_fallback(tr, emb_code, is_error):
|
|
418
|
+
"""Create verifier with fallback logic."""
|
|
419
|
+
async with semaphore: # Acquire semaphore before operation
|
|
420
|
+
if not is_error:
|
|
421
|
+
# Try to create from embedded data
|
|
422
|
+
try:
|
|
423
|
+
return await self._create_verifier_from_data(
|
|
424
|
+
verifier_id=tr.verifier.verifier_id,
|
|
425
|
+
verifier_key=tr.verifier.key,
|
|
426
|
+
verifier_code=emb_code,
|
|
427
|
+
verifier_sha=tr.verifier.sha256,
|
|
428
|
+
)
|
|
429
|
+
except Exception as e:
|
|
430
|
+
logger.warning(
|
|
431
|
+
f"Failed to create verifier {tr.verifier.key}: {e}"
|
|
432
|
+
)
|
|
433
|
+
return None
|
|
434
|
+
else:
|
|
435
|
+
# Fallback: try fetching by ID
|
|
436
|
+
try:
|
|
437
|
+
logger.warning(
|
|
438
|
+
f"Embedded verifier code missing for {tr.verifier.key} (NoSuchKey). "
|
|
439
|
+
f"Attempting to refetch by id {tr.verifier.verifier_id}"
|
|
440
|
+
)
|
|
441
|
+
return await self._load_verifier(
|
|
442
|
+
tr.verifier.verifier_id
|
|
443
|
+
)
|
|
444
|
+
except Exception as e:
|
|
445
|
+
logger.warning(
|
|
446
|
+
f"Refetch by verifier id failed for {tr.verifier.key}: {e}. "
|
|
447
|
+
"Leaving verifier unset."
|
|
448
|
+
)
|
|
449
|
+
return None
|
|
450
|
+
|
|
451
|
+
# Add the coroutine for parallel execution
|
|
452
|
+
verifier_coroutines.append(
|
|
453
|
+
create_verifier_with_fallback(
|
|
454
|
+
task_response, embedded_code, is_embedded_error
|
|
455
|
+
)
|
|
456
|
+
)
|
|
457
|
+
task_responses_with_indices.append((idx, task_response))
|
|
458
|
+
else:
|
|
459
|
+
# No verifier needed
|
|
460
|
+
verifier_coroutines.append(None)
|
|
461
|
+
task_responses_with_indices.append((idx, task_response))
|
|
462
|
+
|
|
463
|
+
# Execute all verifier loading in parallel
|
|
464
|
+
if verifier_coroutines:
|
|
465
|
+
verifier_results = await asyncio.gather(
|
|
466
|
+
*[
|
|
467
|
+
coro if coro is not None else asyncio.sleep(0)
|
|
468
|
+
for coro in verifier_coroutines
|
|
469
|
+
],
|
|
470
|
+
return_exceptions=True,
|
|
471
|
+
)
|
|
472
|
+
else:
|
|
473
|
+
verifier_results = []
|
|
474
|
+
|
|
475
|
+
# Build tasks with results
|
|
476
|
+
tasks = []
|
|
477
|
+
for (idx, task_response), verifier_result in zip(
|
|
478
|
+
task_responses_with_indices, verifier_results
|
|
479
|
+
):
|
|
480
|
+
# Handle verifier result
|
|
481
|
+
verifier = None
|
|
482
|
+
verifier_func = task_response.verifier_func
|
|
483
|
+
|
|
484
|
+
if task_response.verifier:
|
|
485
|
+
# Process verifier result
|
|
486
|
+
if isinstance(verifier_result, Exception):
|
|
487
|
+
logger.warning(
|
|
488
|
+
f"Verifier loading failed for {task_response.key}: {verifier_result}"
|
|
489
|
+
)
|
|
490
|
+
elif verifier_result is not None:
|
|
491
|
+
verifier = verifier_result
|
|
492
|
+
embedded_code = task_response.verifier.code or ""
|
|
493
|
+
is_embedded_error = embedded_code.strip().startswith(
|
|
494
|
+
"<error loading code:"
|
|
495
|
+
)
|
|
496
|
+
if not is_embedded_error:
|
|
497
|
+
verifier_func = embedded_code
|
|
402
498
|
|
|
403
499
|
task = Task(
|
|
404
500
|
key=task_response.key,
|
|
@@ -507,7 +603,7 @@ class AsyncFleet:
|
|
|
507
603
|
self,
|
|
508
604
|
task_key: str,
|
|
509
605
|
prompt: Optional[str] = None,
|
|
510
|
-
verifier_code: Optional[str] = None
|
|
606
|
+
verifier_code: Optional[str] = None,
|
|
511
607
|
) -> TaskResponse:
|
|
512
608
|
"""Update an existing task.
|
|
513
609
|
|
|
@@ -519,10 +615,7 @@ class AsyncFleet:
|
|
|
519
615
|
Returns:
|
|
520
616
|
TaskResponse containing the updated task details
|
|
521
617
|
"""
|
|
522
|
-
payload = TaskUpdateRequest(
|
|
523
|
-
prompt=prompt,
|
|
524
|
-
verifier_code=verifier_code
|
|
525
|
-
)
|
|
618
|
+
payload = TaskUpdateRequest(prompt=prompt, verifier_code=verifier_code)
|
|
526
619
|
response = await self.client.request(
|
|
527
620
|
"PUT", f"/v1/tasks/{task_key}", json=payload.model_dump(exclude_none=True)
|
|
528
621
|
)
|
|
@@ -542,8 +635,7 @@ class AsyncFleet:
|
|
|
542
635
|
Returns:
|
|
543
636
|
AsyncVerifierFunction created from the verifier code
|
|
544
637
|
"""
|
|
545
|
-
from
|
|
546
|
-
from .verifiers.verifier import AsyncVerifierFunction
|
|
638
|
+
from .tasks import verifier_from_string
|
|
547
639
|
|
|
548
640
|
# Use verifier_from_string to create the verifier
|
|
549
641
|
verifier_func = verifier_from_string(
|
|
@@ -568,7 +660,7 @@ class AsyncFleet:
|
|
|
568
660
|
AsyncVerifierFunction created from the verifier code
|
|
569
661
|
"""
|
|
570
662
|
# Fetch verifier from API
|
|
571
|
-
response = await self.client.request("GET", f"/v1/
|
|
663
|
+
response = await self.client.request("GET", f"/v1/verifiers/{verifier_id}")
|
|
572
664
|
verifier_data = response.json()
|
|
573
665
|
|
|
574
666
|
# Use the common method to create verifier
|
|
@@ -3,8 +3,15 @@ from ...models import Environment as EnvironmentModel, AccountResponse
|
|
|
3
3
|
from typing import List, Optional, Dict, Any
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
async def make_async(
|
|
7
|
-
|
|
6
|
+
async def make_async(
|
|
7
|
+
env_key: str,
|
|
8
|
+
data_key: Optional[str] = None,
|
|
9
|
+
region: Optional[str] = None,
|
|
10
|
+
env_variables: Optional[Dict[str, Any]] = None,
|
|
11
|
+
) -> AsyncEnv:
|
|
12
|
+
return await AsyncFleet().make(
|
|
13
|
+
env_key, data_key=data_key, region=region, env_variables=env_variables
|
|
14
|
+
)
|
|
8
15
|
|
|
9
16
|
|
|
10
17
|
async def make_for_task_async(task: Task) -> AsyncEnv:
|
|
@@ -108,7 +108,7 @@ class AsyncInstanceClient:
|
|
|
108
108
|
return await self.verify_raw(function_code, function_name)
|
|
109
109
|
|
|
110
110
|
async def verify_raw(
|
|
111
|
-
self, function_code: str, function_name: str
|
|
111
|
+
self, function_code: str, function_name: Optional[str] = None
|
|
112
112
|
) -> ExecuteFunctionResponse:
|
|
113
113
|
try:
|
|
114
114
|
function_code = convert_verifier_string(function_code)
|