fleet-python 0.2.67__tar.gz → 0.2.69__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.67/fleet_python.egg-info → fleet_python-0.2.69}/PKG-INFO +1 -1
- {fleet_python-0.2.67 → fleet_python-0.2.69}/fleet/_async/base.py +4 -3
- {fleet_python-0.2.67 → fleet_python-0.2.69}/fleet/_async/client.py +64 -32
- {fleet_python-0.2.67 → fleet_python-0.2.69}/fleet/_async/env/client.py +29 -3
- {fleet_python-0.2.67 → fleet_python-0.2.69}/fleet/_async/tasks.py +7 -2
- {fleet_python-0.2.67 → fleet_python-0.2.69}/fleet/_async/verifiers/bundler.py +22 -21
- {fleet_python-0.2.67 → fleet_python-0.2.69}/fleet/_async/verifiers/verifier.py +20 -19
- {fleet_python-0.2.67 → fleet_python-0.2.69}/fleet/base.py +4 -3
- {fleet_python-0.2.67 → fleet_python-0.2.69}/fleet/client.py +61 -30
- {fleet_python-0.2.67 → fleet_python-0.2.69}/fleet/env/__init__.py +8 -0
- {fleet_python-0.2.67 → fleet_python-0.2.69}/fleet/env/client.py +29 -3
- {fleet_python-0.2.67 → fleet_python-0.2.69}/fleet/models.py +2 -0
- {fleet_python-0.2.67 → fleet_python-0.2.69}/fleet/tasks.py +7 -2
- {fleet_python-0.2.67 → fleet_python-0.2.69}/fleet/verifiers/bundler.py +22 -21
- {fleet_python-0.2.67 → fleet_python-0.2.69}/fleet/verifiers/decorator.py +1 -1
- {fleet_python-0.2.67 → fleet_python-0.2.69}/fleet/verifiers/verifier.py +20 -19
- {fleet_python-0.2.67 → fleet_python-0.2.69/fleet_python.egg-info}/PKG-INFO +1 -1
- {fleet_python-0.2.67 → fleet_python-0.2.69}/pyproject.toml +1 -1
- {fleet_python-0.2.67 → fleet_python-0.2.69}/LICENSE +0 -0
- {fleet_python-0.2.67 → fleet_python-0.2.69}/README.md +0 -0
- {fleet_python-0.2.67 → fleet_python-0.2.69}/examples/diff_example.py +0 -0
- {fleet_python-0.2.67 → fleet_python-0.2.69}/examples/dsl_example.py +0 -0
- {fleet_python-0.2.67 → fleet_python-0.2.69}/examples/example.py +0 -0
- {fleet_python-0.2.67 → fleet_python-0.2.69}/examples/exampleResume.py +0 -0
- {fleet_python-0.2.67 → fleet_python-0.2.69}/examples/example_account.py +0 -0
- {fleet_python-0.2.67 → fleet_python-0.2.69}/examples/example_action_log.py +0 -0
- {fleet_python-0.2.67 → fleet_python-0.2.69}/examples/example_client.py +0 -0
- {fleet_python-0.2.67 → fleet_python-0.2.69}/examples/example_mcp_anthropic.py +0 -0
- {fleet_python-0.2.67 → fleet_python-0.2.69}/examples/example_mcp_openai.py +0 -0
- {fleet_python-0.2.67 → fleet_python-0.2.69}/examples/example_sync.py +0 -0
- {fleet_python-0.2.67 → fleet_python-0.2.69}/examples/example_task.py +0 -0
- {fleet_python-0.2.67 → fleet_python-0.2.69}/examples/example_tasks.py +0 -0
- {fleet_python-0.2.67 → fleet_python-0.2.69}/examples/example_verifier.py +0 -0
- {fleet_python-0.2.67 → fleet_python-0.2.69}/examples/export_tasks.py +0 -0
- {fleet_python-0.2.67 → fleet_python-0.2.69}/examples/gemini_example.py +0 -0
- {fleet_python-0.2.67 → fleet_python-0.2.69}/examples/import_tasks.py +0 -0
- {fleet_python-0.2.67 → fleet_python-0.2.69}/examples/json_tasks_example.py +0 -0
- {fleet_python-0.2.67 → fleet_python-0.2.69}/examples/nova_act_example.py +0 -0
- {fleet_python-0.2.67 → fleet_python-0.2.69}/examples/openai_example.py +0 -0
- {fleet_python-0.2.67 → fleet_python-0.2.69}/examples/openai_simple_example.py +0 -0
- {fleet_python-0.2.67 → fleet_python-0.2.69}/examples/query_builder_example.py +0 -0
- {fleet_python-0.2.67 → fleet_python-0.2.69}/examples/quickstart.py +0 -0
- {fleet_python-0.2.67 → fleet_python-0.2.69}/examples/test_cdp_logging.py +0 -0
- {fleet_python-0.2.67 → fleet_python-0.2.69}/fleet/__init__.py +0 -0
- {fleet_python-0.2.67 → fleet_python-0.2.69}/fleet/_async/__init__.py +0 -0
- {fleet_python-0.2.67 → fleet_python-0.2.69}/fleet/_async/env/__init__.py +0 -0
- {fleet_python-0.2.67 → fleet_python-0.2.69}/fleet/_async/exceptions.py +0 -0
- {fleet_python-0.2.67 → fleet_python-0.2.69}/fleet/_async/global_client.py +0 -0
- {fleet_python-0.2.67 → fleet_python-0.2.69}/fleet/_async/instance/__init__.py +0 -0
- {fleet_python-0.2.67 → fleet_python-0.2.69}/fleet/_async/instance/base.py +0 -0
- {fleet_python-0.2.67 → fleet_python-0.2.69}/fleet/_async/instance/client.py +0 -0
- {fleet_python-0.2.67 → fleet_python-0.2.69}/fleet/_async/models.py +0 -0
- {fleet_python-0.2.67 → fleet_python-0.2.69}/fleet/_async/resources/__init__.py +0 -0
- {fleet_python-0.2.67 → fleet_python-0.2.69}/fleet/_async/resources/base.py +0 -0
- {fleet_python-0.2.67 → fleet_python-0.2.69}/fleet/_async/resources/browser.py +0 -0
- {fleet_python-0.2.67 → fleet_python-0.2.69}/fleet/_async/resources/mcp.py +0 -0
- {fleet_python-0.2.67 → fleet_python-0.2.69}/fleet/_async/resources/sqlite.py +0 -0
- {fleet_python-0.2.67 → fleet_python-0.2.69}/fleet/_async/verifiers/__init__.py +0 -0
- {fleet_python-0.2.67 → fleet_python-0.2.69}/fleet/config.py +0 -0
- {fleet_python-0.2.67 → fleet_python-0.2.69}/fleet/exceptions.py +0 -0
- {fleet_python-0.2.67 → fleet_python-0.2.69}/fleet/global_client.py +0 -0
- {fleet_python-0.2.67 → fleet_python-0.2.69}/fleet/instance/__init__.py +0 -0
- {fleet_python-0.2.67 → fleet_python-0.2.69}/fleet/instance/base.py +0 -0
- {fleet_python-0.2.67 → fleet_python-0.2.69}/fleet/instance/client.py +0 -0
- {fleet_python-0.2.67 → fleet_python-0.2.69}/fleet/instance/models.py +0 -0
- {fleet_python-0.2.67 → fleet_python-0.2.69}/fleet/resources/__init__.py +0 -0
- {fleet_python-0.2.67 → fleet_python-0.2.69}/fleet/resources/base.py +0 -0
- {fleet_python-0.2.67 → fleet_python-0.2.69}/fleet/resources/browser.py +0 -0
- {fleet_python-0.2.67 → fleet_python-0.2.69}/fleet/resources/mcp.py +0 -0
- {fleet_python-0.2.67 → fleet_python-0.2.69}/fleet/resources/sqlite.py +0 -0
- {fleet_python-0.2.67 → fleet_python-0.2.69}/fleet/types.py +0 -0
- {fleet_python-0.2.67 → fleet_python-0.2.69}/fleet/verifiers/__init__.py +0 -0
- {fleet_python-0.2.67 → fleet_python-0.2.69}/fleet/verifiers/code.py +0 -0
- {fleet_python-0.2.67 → fleet_python-0.2.69}/fleet/verifiers/db.py +0 -0
- {fleet_python-0.2.67 → fleet_python-0.2.69}/fleet/verifiers/parse.py +0 -0
- {fleet_python-0.2.67 → fleet_python-0.2.69}/fleet/verifiers/sql_differ.py +0 -0
- {fleet_python-0.2.67 → fleet_python-0.2.69}/fleet_python.egg-info/SOURCES.txt +0 -0
- {fleet_python-0.2.67 → fleet_python-0.2.69}/fleet_python.egg-info/dependency_links.txt +0 -0
- {fleet_python-0.2.67 → fleet_python-0.2.69}/fleet_python.egg-info/requires.txt +0 -0
- {fleet_python-0.2.67 → fleet_python-0.2.69}/fleet_python.egg-info/top_level.txt +0 -0
- {fleet_python-0.2.67 → fleet_python-0.2.69}/scripts/fix_sync_imports.py +0 -0
- {fleet_python-0.2.67 → fleet_python-0.2.69}/scripts/unasync.py +0 -0
- {fleet_python-0.2.67 → fleet_python-0.2.69}/setup.cfg +0 -0
- {fleet_python-0.2.67 → fleet_python-0.2.69}/tests/__init__.py +0 -0
- {fleet_python-0.2.67 → fleet_python-0.2.69}/tests/test_verifier_from_string.py +0 -0
|
@@ -48,7 +48,7 @@ class BaseWrapper:
|
|
|
48
48
|
import logging
|
|
49
49
|
|
|
50
50
|
logger = logging.getLogger(__name__)
|
|
51
|
-
logger.debug(f"Headers being sent: {headers}")
|
|
51
|
+
# logger.debug(f"Headers being sent: {headers}")
|
|
52
52
|
return headers
|
|
53
53
|
|
|
54
54
|
|
|
@@ -93,8 +93,9 @@ class AsyncWrapper(BaseWrapper):
|
|
|
93
93
|
|
|
94
94
|
# Debug log 500 errors
|
|
95
95
|
if status_code == 500:
|
|
96
|
-
logger.error(f"Got 500 error from {response.url}")
|
|
97
|
-
logger.error(f"Response text: {response.text}")
|
|
96
|
+
# logger.error(f"Got 500 error from {response.url}")
|
|
97
|
+
# logger.error(f"Response text: {response.text}")
|
|
98
|
+
pass
|
|
98
99
|
|
|
99
100
|
# Try to parse error response as JSON
|
|
100
101
|
try:
|
|
@@ -212,6 +212,7 @@ class AsyncFleet:
|
|
|
212
212
|
env_variables: Optional[Dict[str, Any]] = None,
|
|
213
213
|
image_type: Optional[str] = None,
|
|
214
214
|
ttl_seconds: Optional[int] = None,
|
|
215
|
+
run_id: Optional[str] = None,
|
|
215
216
|
) -> AsyncEnv:
|
|
216
217
|
if ":" in env_key:
|
|
217
218
|
env_key_part, env_version = env_key.split(":", 1)
|
|
@@ -247,6 +248,7 @@ class AsyncFleet:
|
|
|
247
248
|
image_type=image_type,
|
|
248
249
|
created_from="sdk",
|
|
249
250
|
ttl_seconds=ttl_seconds,
|
|
251
|
+
run_id=run_id,
|
|
250
252
|
)
|
|
251
253
|
|
|
252
254
|
# Only use region-specific base URL if no custom base URL is set
|
|
@@ -269,13 +271,15 @@ class AsyncFleet:
|
|
|
269
271
|
return await self.make(env_key=f"{task.env_id}:{task.version}")
|
|
270
272
|
|
|
271
273
|
async def instances(
|
|
272
|
-
self, status: Optional[str] = None, region: Optional[str] = None
|
|
274
|
+
self, status: Optional[str] = None, region: Optional[str] = None, run_id: Optional[str] = None
|
|
273
275
|
) -> List[AsyncEnv]:
|
|
274
276
|
params = {}
|
|
275
277
|
if status:
|
|
276
278
|
params["status"] = status
|
|
277
279
|
if region:
|
|
278
280
|
params["region"] = region
|
|
281
|
+
if run_id:
|
|
282
|
+
params["run_id"] = run_id
|
|
279
283
|
|
|
280
284
|
response = await self.client.request("GET", "/v1/env/instances", params=params)
|
|
281
285
|
return [
|
|
@@ -302,6 +306,28 @@ class AsyncFleet:
|
|
|
302
306
|
async def delete(self, instance_id: str) -> InstanceResponse:
|
|
303
307
|
return await _delete_instance(self.client, instance_id)
|
|
304
308
|
|
|
309
|
+
async def close(self, instance_id: str) -> InstanceResponse:
|
|
310
|
+
"""Close (delete) a specific instance by ID.
|
|
311
|
+
|
|
312
|
+
Args:
|
|
313
|
+
instance_id: The instance ID to close
|
|
314
|
+
|
|
315
|
+
Returns:
|
|
316
|
+
InstanceResponse containing the deleted instance details
|
|
317
|
+
"""
|
|
318
|
+
return await _delete_instance(self.client, instance_id)
|
|
319
|
+
|
|
320
|
+
async def close_all(self, run_id: str) -> List[InstanceResponse]:
|
|
321
|
+
"""Close (delete) all instances associated with a run_id.
|
|
322
|
+
|
|
323
|
+
Args:
|
|
324
|
+
run_id: The run ID whose instances should be closed
|
|
325
|
+
|
|
326
|
+
Returns:
|
|
327
|
+
List[InstanceResponse] containing the deleted instances
|
|
328
|
+
"""
|
|
329
|
+
return await _delete_instances_by_run_id(self.client, run_id)
|
|
330
|
+
|
|
305
331
|
async def load_tasks_from_file(self, filename: str) -> List[Task]:
|
|
306
332
|
with open(filename, "r", encoding="utf-8") as f:
|
|
307
333
|
tasks_data = f.read()
|
|
@@ -380,8 +406,8 @@ class AsyncFleet:
|
|
|
380
406
|
error_msg = f"Failed to create verifier {task_json.get('key', task_json.get('id'))}: {e}"
|
|
381
407
|
if raise_on_verifier_error:
|
|
382
408
|
raise ValueError(error_msg) from e
|
|
383
|
-
else:
|
|
384
|
-
|
|
409
|
+
# else:
|
|
410
|
+
# logger.warning(error_msg)
|
|
385
411
|
|
|
386
412
|
task = Task(
|
|
387
413
|
key=task_json.get("key", task_json.get("id")),
|
|
@@ -473,25 +499,25 @@ class AsyncFleet:
|
|
|
473
499
|
verifier_sha=tr.verifier.sha256,
|
|
474
500
|
)
|
|
475
501
|
except Exception as e:
|
|
476
|
-
logger.warning(
|
|
477
|
-
|
|
478
|
-
)
|
|
502
|
+
# logger.warning(
|
|
503
|
+
# f"Failed to create verifier {tr.verifier.key}: {e}"
|
|
504
|
+
# )
|
|
479
505
|
return None
|
|
480
506
|
else:
|
|
481
507
|
# Fallback: try fetching by ID
|
|
482
508
|
try:
|
|
483
|
-
logger.warning(
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
)
|
|
509
|
+
# logger.warning(
|
|
510
|
+
# f"Embedded verifier code missing for {tr.verifier.key} (NoSuchKey). "
|
|
511
|
+
# f"Attempting to refetch by id {tr.verifier.verifier_id}"
|
|
512
|
+
# )
|
|
487
513
|
return await self._load_verifier(
|
|
488
514
|
tr.verifier.verifier_id
|
|
489
515
|
)
|
|
490
516
|
except Exception as e:
|
|
491
|
-
logger.warning(
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
)
|
|
517
|
+
# logger.warning(
|
|
518
|
+
# f"Refetch by verifier id failed for {tr.verifier.key}: {e}. "
|
|
519
|
+
# "Leaving verifier unset."
|
|
520
|
+
# )
|
|
495
521
|
return None
|
|
496
522
|
|
|
497
523
|
# Add the coroutine for parallel execution
|
|
@@ -530,9 +556,10 @@ class AsyncFleet:
|
|
|
530
556
|
if task_response.verifier:
|
|
531
557
|
# Process verifier result
|
|
532
558
|
if isinstance(verifier_result, Exception):
|
|
533
|
-
logger.warning(
|
|
534
|
-
|
|
535
|
-
)
|
|
559
|
+
# logger.warning(
|
|
560
|
+
# f"Verifier loading failed for {task_response.key}: {verifier_result}"
|
|
561
|
+
# )
|
|
562
|
+
pass
|
|
536
563
|
elif verifier_result is not None:
|
|
537
564
|
verifier = verifier_result
|
|
538
565
|
embedded_code = task_response.verifier.code or ""
|
|
@@ -606,10 +633,10 @@ class AsyncFleet:
|
|
|
606
633
|
with open(filename, "w", encoding="utf-8") as f:
|
|
607
634
|
json.dump(tasks_data, f, indent=2, default=str)
|
|
608
635
|
|
|
609
|
-
logger.info(f"Exported {len(tasks)} tasks to {filename}")
|
|
636
|
+
# logger.info(f"Exported {len(tasks)} tasks to {filename}")
|
|
610
637
|
return filename
|
|
611
638
|
else:
|
|
612
|
-
logger.info("No tasks found to export")
|
|
639
|
+
# logger.info("No tasks found to export")
|
|
613
640
|
return None
|
|
614
641
|
|
|
615
642
|
async def import_single_task(self, task: Task, project_key: Optional[str] = None):
|
|
@@ -638,7 +665,7 @@ class AsyncFleet:
|
|
|
638
665
|
)
|
|
639
666
|
return response
|
|
640
667
|
except Exception as e:
|
|
641
|
-
logger.error(f"Failed to import task {task.key}: {e}")
|
|
668
|
+
# logger.error(f"Failed to import task {task.key}: {e}")
|
|
642
669
|
return None
|
|
643
670
|
|
|
644
671
|
async def import_tasks(self, filename: str, project_key: Optional[str] = None):
|
|
@@ -811,6 +838,11 @@ async def _delete_instance(client: AsyncWrapper, instance_id: str) -> InstanceRe
|
|
|
811
838
|
return InstanceResponse(**response.json())
|
|
812
839
|
|
|
813
840
|
|
|
841
|
+
async def _delete_instances_by_run_id(client: AsyncWrapper, run_id: str) -> List[InstanceResponse]:
|
|
842
|
+
response = await client.request("DELETE", f"/v1/env/instances/run/{run_id}")
|
|
843
|
+
return [InstanceResponse(**instance_data) for instance_data in response.json()]
|
|
844
|
+
|
|
845
|
+
|
|
814
846
|
async def _check_bundle_exists(
|
|
815
847
|
client: AsyncWrapper, bundle_hash: str
|
|
816
848
|
) -> VerifiersCheckResponse:
|
|
@@ -853,17 +885,17 @@ async def _execute_verifier_remote(
|
|
|
853
885
|
request_data["bundle"] = bundle_b64
|
|
854
886
|
|
|
855
887
|
# Debug logging
|
|
856
|
-
logger.debug(
|
|
857
|
-
|
|
858
|
-
)
|
|
859
|
-
logger.debug(f"Request has bundle: {needs_upload}")
|
|
860
|
-
logger.debug(f"Using client with base_url: {client.base_url}")
|
|
861
|
-
logger.debug(f"Request data keys: {list(request_data.keys())}")
|
|
862
|
-
logger.debug(
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
)
|
|
888
|
+
# logger.debug(
|
|
889
|
+
# f"Sending verifier execute request: key={key}, sha256={bundle_sha[:8]}..., function_name={function_name}"
|
|
890
|
+
# )
|
|
891
|
+
# logger.debug(f"Request has bundle: {needs_upload}")
|
|
892
|
+
# logger.debug(f"Using client with base_url: {client.base_url}")
|
|
893
|
+
# logger.debug(f"Request data keys: {list(request_data.keys())}")
|
|
894
|
+
# logger.debug(
|
|
895
|
+
# f"Bundle size: {len(request_data.get('bundle', ''))} chars"
|
|
896
|
+
# if "bundle" in request_data
|
|
897
|
+
# else "No bundle"
|
|
898
|
+
# )
|
|
867
899
|
|
|
868
900
|
# Note: This should be called on the instance URL, not the orchestrator
|
|
869
901
|
# The instance has manager URLs for verifier execution
|
|
@@ -871,6 +903,6 @@ async def _execute_verifier_remote(
|
|
|
871
903
|
|
|
872
904
|
# Debug the response
|
|
873
905
|
response_json = response.json()
|
|
874
|
-
logger.debug(f"Verifier execute response: {response_json}")
|
|
906
|
+
# logger.debug(f"Verifier execute response: {response_json}")
|
|
875
907
|
|
|
876
908
|
return VerifiersExecuteResponse(**response_json)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from ..client import AsyncFleet, AsyncEnv, Task
|
|
2
|
-
from ...models import Environment as EnvironmentModel, AccountResponse
|
|
2
|
+
from ...models import Environment as EnvironmentModel, AccountResponse, InstanceResponse
|
|
3
3
|
from typing import List, Optional, Dict, Any
|
|
4
4
|
|
|
5
5
|
|
|
@@ -10,6 +10,7 @@ async def make_async(
|
|
|
10
10
|
env_variables: Optional[Dict[str, Any]] = None,
|
|
11
11
|
image_type: Optional[str] = None,
|
|
12
12
|
ttl_seconds: Optional[int] = None,
|
|
13
|
+
run_id: Optional[str] = None,
|
|
13
14
|
) -> AsyncEnv:
|
|
14
15
|
return await AsyncFleet().make(
|
|
15
16
|
env_key,
|
|
@@ -18,6 +19,7 @@ async def make_async(
|
|
|
18
19
|
env_variables=env_variables,
|
|
19
20
|
image_type=image_type,
|
|
20
21
|
ttl_seconds=ttl_seconds,
|
|
22
|
+
run_id=run_id,
|
|
21
23
|
)
|
|
22
24
|
|
|
23
25
|
|
|
@@ -34,14 +36,38 @@ async def list_regions_async() -> List[str]:
|
|
|
34
36
|
|
|
35
37
|
|
|
36
38
|
async def list_instances_async(
|
|
37
|
-
status: Optional[str] = None, region: Optional[str] = None
|
|
39
|
+
status: Optional[str] = None, region: Optional[str] = None, run_id: Optional[str] = None
|
|
38
40
|
) -> List[AsyncEnv]:
|
|
39
|
-
return await AsyncFleet().instances(status=status, region=region)
|
|
41
|
+
return await AsyncFleet().instances(status=status, region=region, run_id=run_id)
|
|
40
42
|
|
|
41
43
|
|
|
42
44
|
async def get_async(instance_id: str) -> AsyncEnv:
|
|
43
45
|
return await AsyncFleet().instance(instance_id)
|
|
44
46
|
|
|
45
47
|
|
|
48
|
+
async def close_async(instance_id: str) -> InstanceResponse:
|
|
49
|
+
"""Close (delete) a specific instance by ID.
|
|
50
|
+
|
|
51
|
+
Args:
|
|
52
|
+
instance_id: The instance ID to close
|
|
53
|
+
|
|
54
|
+
Returns:
|
|
55
|
+
InstanceResponse containing the deleted instance details
|
|
56
|
+
"""
|
|
57
|
+
return await AsyncFleet().close(instance_id)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
async def close_all_async(run_id: str) -> List[InstanceResponse]:
|
|
61
|
+
"""Close (delete) all instances associated with a run_id.
|
|
62
|
+
|
|
63
|
+
Args:
|
|
64
|
+
run_id: The run ID whose instances should be closed
|
|
65
|
+
|
|
66
|
+
Returns:
|
|
67
|
+
List[InstanceResponse] containing the deleted instances
|
|
68
|
+
"""
|
|
69
|
+
return await AsyncFleet().close_all(run_id)
|
|
70
|
+
|
|
71
|
+
|
|
46
72
|
async def account_async() -> AccountResponse:
|
|
47
73
|
return await AsyncFleet().account()
|
|
@@ -214,13 +214,14 @@ class Task(BaseModel):
|
|
|
214
214
|
region: Optional[str] = None,
|
|
215
215
|
image_type: Optional[str] = None,
|
|
216
216
|
ttl_seconds: Optional[int] = None,
|
|
217
|
+
run_id: Optional[str] = None,
|
|
217
218
|
):
|
|
218
219
|
"""Create an environment instance for this task's environment.
|
|
219
220
|
|
|
220
221
|
Alias for make() method. Uses the task's env_id (and version if present) to create the env.
|
|
221
222
|
"""
|
|
222
223
|
return await self.make(
|
|
223
|
-
region=region, image_type=image_type, ttl_seconds=ttl_seconds
|
|
224
|
+
region=region, image_type=image_type, ttl_seconds=ttl_seconds, run_id=run_id
|
|
224
225
|
)
|
|
225
226
|
|
|
226
227
|
async def make(
|
|
@@ -228,6 +229,7 @@ class Task(BaseModel):
|
|
|
228
229
|
region: Optional[str] = None,
|
|
229
230
|
image_type: Optional[str] = None,
|
|
230
231
|
ttl_seconds: Optional[int] = None,
|
|
232
|
+
run_id: Optional[str] = None,
|
|
231
233
|
):
|
|
232
234
|
"""Create an environment instance with task's configuration.
|
|
233
235
|
|
|
@@ -235,11 +237,13 @@ class Task(BaseModel):
|
|
|
235
237
|
- env_key (env_id + version)
|
|
236
238
|
- data_key (data_id + data_version, if present)
|
|
237
239
|
- env_variables (if present)
|
|
240
|
+
- run_id (if present)
|
|
238
241
|
|
|
239
242
|
Args:
|
|
240
243
|
region: Optional AWS region for the environment
|
|
241
244
|
image_type: Optional image type for the environment
|
|
242
245
|
ttl_seconds: Optional TTL in seconds for the instance
|
|
246
|
+
run_id: Optional run ID to group instances
|
|
243
247
|
|
|
244
248
|
Returns:
|
|
245
249
|
Environment instance configured for this task
|
|
@@ -247,7 +251,7 @@ class Task(BaseModel):
|
|
|
247
251
|
Example:
|
|
248
252
|
task = fleet.Task(key="my-task", prompt="...", env_id="my-env",
|
|
249
253
|
data_id="my-data", data_version="v1.0")
|
|
250
|
-
env = await task.make(region="us-west-2")
|
|
254
|
+
env = await task.make(region="us-west-2", run_id="my-batch-123")
|
|
251
255
|
"""
|
|
252
256
|
if not self.env_id:
|
|
253
257
|
raise ValueError("Task has no env_id defined")
|
|
@@ -262,6 +266,7 @@ class Task(BaseModel):
|
|
|
262
266
|
env_variables=self.env_variables if self.env_variables else None,
|
|
263
267
|
image_type=image_type,
|
|
264
268
|
ttl_seconds=ttl_seconds,
|
|
269
|
+
run_id=run_id,
|
|
265
270
|
)
|
|
266
271
|
|
|
267
272
|
|
|
@@ -37,7 +37,7 @@ class FunctionBundler:
|
|
|
37
37
|
) -> bytes:
|
|
38
38
|
"""Create a function bundle with statically extracted code."""
|
|
39
39
|
|
|
40
|
-
logger.info(f"Creating function bundle for {func.__name__}")
|
|
40
|
+
# logger.info(f"Creating function bundle for {func.__name__}")
|
|
41
41
|
|
|
42
42
|
# 1. Parse the main function and find dependencies
|
|
43
43
|
mod_file = Path(func.__code__.co_filename)
|
|
@@ -115,7 +115,7 @@ class FunctionBundler:
|
|
|
115
115
|
|
|
116
116
|
# Find function calls within the verifier function
|
|
117
117
|
called_functions = self._extract_function_calls(main_func_ast)
|
|
118
|
-
logger.debug(f"Functions called in verifier: {called_functions}")
|
|
118
|
+
# logger.debug(f"Functions called in verifier: {called_functions}")
|
|
119
119
|
|
|
120
120
|
# Find all functions defined in the module
|
|
121
121
|
module_functions = {}
|
|
@@ -128,7 +128,7 @@ class FunctionBundler:
|
|
|
128
128
|
for func_name in called_functions:
|
|
129
129
|
if func_name in module_functions and func_name != func.__name__:
|
|
130
130
|
same_module_deps.append(func_name)
|
|
131
|
-
logger.debug(f"Found same-module dependency: {func_name}")
|
|
131
|
+
# logger.debug(f"Found same-module dependency: {func_name}")
|
|
132
132
|
|
|
133
133
|
# Separate local and external imports
|
|
134
134
|
local_imports = {}
|
|
@@ -292,7 +292,7 @@ class FunctionBundler:
|
|
|
292
292
|
code = ast.unparse(node)
|
|
293
293
|
extracted_code.append(code)
|
|
294
294
|
except Exception as e:
|
|
295
|
-
logger.warning(f"Could not unparse AST node: {e}")
|
|
295
|
+
# logger.warning(f"Could not unparse AST node: {e}")
|
|
296
296
|
# Fallback to original source extraction
|
|
297
297
|
lines = content.split("\n")
|
|
298
298
|
start_line = node.lineno - 1
|
|
@@ -305,11 +305,11 @@ class FunctionBundler:
|
|
|
305
305
|
extracted_code.append(code)
|
|
306
306
|
|
|
307
307
|
result = "\n\n".join(extracted_code)
|
|
308
|
-
logger.debug(f"Extracted {len(extracted_code)} items from {file_path}")
|
|
308
|
+
# logger.debug(f"Extracted {len(extracted_code)} items from {file_path}")
|
|
309
309
|
return result
|
|
310
310
|
|
|
311
311
|
except Exception as e:
|
|
312
|
-
logger.warning(f"Failed to extract functions from {file_path}: {e}")
|
|
312
|
+
# logger.warning(f"Failed to extract functions from {file_path}: {e}")
|
|
313
313
|
# Fallback to including the entire file
|
|
314
314
|
with open(file_path, "r", encoding="utf-8") as f:
|
|
315
315
|
return f.read()
|
|
@@ -464,14 +464,14 @@ class FunctionBundler:
|
|
|
464
464
|
version = dist.version # Get the installed version
|
|
465
465
|
package_with_version = f"{package_name}=={version}"
|
|
466
466
|
packages.add(package_with_version)
|
|
467
|
-
logger.debug(f"Mapped {mod} -> {package_with_version}")
|
|
467
|
+
# logger.debug(f"Mapped {mod} -> {package_with_version}")
|
|
468
468
|
except imd.PackageNotFoundError:
|
|
469
469
|
# Skip stdlib or local modules
|
|
470
|
-
logger.debug(f"Skipping {mod} (stdlib or local)")
|
|
470
|
+
# logger.debug(f"Skipping {mod} (stdlib or local)")
|
|
471
471
|
continue
|
|
472
472
|
|
|
473
473
|
package_list = list(packages)
|
|
474
|
-
logger.debug(f"Final package list: {package_list}")
|
|
474
|
+
# logger.debug(f"Final package list: {package_list}")
|
|
475
475
|
return package_list
|
|
476
476
|
|
|
477
477
|
def _merge_requirements(
|
|
@@ -511,10 +511,10 @@ class FunctionBundler:
|
|
|
511
511
|
if pkg_name not in seen_packages:
|
|
512
512
|
final_requirements.append(req)
|
|
513
513
|
seen_packages.add(pkg_name)
|
|
514
|
-
else:
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
514
|
+
# else:
|
|
515
|
+
# logger.debug(
|
|
516
|
+
# f"Skipping auto-detected {req}, using explicit version instead"
|
|
517
|
+
# )
|
|
518
518
|
|
|
519
519
|
# Always ensure fleet-python is included
|
|
520
520
|
if "fleet-python" not in seen_packages:
|
|
@@ -565,9 +565,9 @@ class FunctionBundler:
|
|
|
565
565
|
)
|
|
566
566
|
if dep_src:
|
|
567
567
|
same_module_code += f"\n{dep_src}\n"
|
|
568
|
-
logger.debug(
|
|
569
|
-
|
|
570
|
-
)
|
|
568
|
+
# logger.debug(
|
|
569
|
+
# f"Extracted same-module dependency: {dep_name}"
|
|
570
|
+
# )
|
|
571
571
|
|
|
572
572
|
# Create verifier.py with the main function
|
|
573
573
|
verifier_file = build_dir / "verifier.py"
|
|
@@ -586,7 +586,7 @@ class FunctionBundler:
|
|
|
586
586
|
{code}
|
|
587
587
|
"""
|
|
588
588
|
dest_path.write_text(extracted_content)
|
|
589
|
-
logger.debug(f"Created extracted file: {relative_path}")
|
|
589
|
+
# logger.debug(f"Created extracted file: {relative_path}")
|
|
590
590
|
|
|
591
591
|
# Ensure __init__.py files exist
|
|
592
592
|
self._ensure_init_files(Path(relative_path), build_dir)
|
|
@@ -595,7 +595,7 @@ class FunctionBundler:
|
|
|
595
595
|
return self._create_zip_bundle(build_dir)
|
|
596
596
|
|
|
597
597
|
except Exception as e:
|
|
598
|
-
logger.error(f"Failed to build function bundle: {e}")
|
|
598
|
+
# logger.error(f"Failed to build function bundle: {e}")
|
|
599
599
|
raise RuntimeError(f"Function bundle creation failed: {e}")
|
|
600
600
|
|
|
601
601
|
def _ensure_init_files(self, rel_path: Path, build_dir: Path):
|
|
@@ -607,7 +607,7 @@ class FunctionBundler:
|
|
|
607
607
|
if not init_file.exists():
|
|
608
608
|
init_file.parent.mkdir(parents=True, exist_ok=True)
|
|
609
609
|
init_file.write_text("# Auto-generated __init__.py")
|
|
610
|
-
logger.debug(f"Created __init__.py: {current}")
|
|
610
|
+
# logger.debug(f"Created __init__.py: {current}")
|
|
611
611
|
current = current.parent
|
|
612
612
|
|
|
613
613
|
def _create_zip_bundle(self, build_dir: Path) -> bytes:
|
|
@@ -621,7 +621,7 @@ class FunctionBundler:
|
|
|
621
621
|
zf.write(file_path, arcname)
|
|
622
622
|
|
|
623
623
|
bundle_size = len(zip_buffer.getvalue())
|
|
624
|
-
logger.debug(f"Created function bundle ({bundle_size:,} bytes)")
|
|
624
|
+
# logger.debug(f"Created function bundle ({bundle_size:,} bytes)")
|
|
625
625
|
return zip_buffer.getvalue()
|
|
626
626
|
|
|
627
627
|
def _extract_function_source(
|
|
@@ -662,7 +662,8 @@ class FunctionBundler:
|
|
|
662
662
|
return "\n".join(func_lines)
|
|
663
663
|
|
|
664
664
|
except Exception as e:
|
|
665
|
-
logger.warning(f"Failed to extract function {function_name}: {e}")
|
|
665
|
+
# logger.warning(f"Failed to extract function {function_name}: {e}")
|
|
666
|
+
pass
|
|
666
667
|
|
|
667
668
|
return None
|
|
668
669
|
|
|
@@ -79,9 +79,9 @@ class AsyncVerifierFunction:
|
|
|
79
79
|
|
|
80
80
|
self._bundle_data = zip_buffer.getvalue()
|
|
81
81
|
self._bundle_sha = _get_bundle_sha(self._bundle_data)
|
|
82
|
-
logger.debug(
|
|
83
|
-
|
|
84
|
-
)
|
|
82
|
+
# logger.debug(
|
|
83
|
+
# f"Created bundle from raw code for {self.key} with SHA: {self._bundle_sha}"
|
|
84
|
+
# )
|
|
85
85
|
else:
|
|
86
86
|
# Try to create bundle from function source
|
|
87
87
|
try:
|
|
@@ -89,9 +89,9 @@ class AsyncVerifierFunction:
|
|
|
89
89
|
self.func, self.extra_requirements, self.verifier_id
|
|
90
90
|
)
|
|
91
91
|
self._bundle_sha = _get_bundle_sha(self._bundle_data)
|
|
92
|
-
logger.debug(
|
|
93
|
-
|
|
94
|
-
)
|
|
92
|
+
# logger.debug(
|
|
93
|
+
# f"Created bundle for {self.key} with SHA: {self._bundle_sha}"
|
|
94
|
+
# )
|
|
95
95
|
except OSError as e:
|
|
96
96
|
# Can't create bundle - no source and no raw code
|
|
97
97
|
raise OSError(f"Cannot create bundle for {self.key}: {e}")
|
|
@@ -104,20 +104,21 @@ class AsyncVerifierFunction:
|
|
|
104
104
|
|
|
105
105
|
# If bundle_data is empty, we're using server-side bundle
|
|
106
106
|
if not bundle_data:
|
|
107
|
-
logger.debug(f"Using server-side bundle {bundle_sha[:8]}...")
|
|
107
|
+
# logger.debug(f"Using server-side bundle {bundle_sha[:8]}...")
|
|
108
108
|
return bundle_sha, False # No upload needed, server has it
|
|
109
109
|
|
|
110
110
|
# Always check if bundle exists on server
|
|
111
111
|
try:
|
|
112
112
|
exists = await env.check_bundle_exists(bundle_sha)
|
|
113
113
|
if exists.success:
|
|
114
|
-
logger.info(f"Bundle {bundle_sha[:8]}... found on server")
|
|
114
|
+
# logger.info(f"Bundle {bundle_sha[:8]}... found on server")
|
|
115
115
|
return bundle_sha, False # Found on server, no upload needed
|
|
116
116
|
except Exception as e:
|
|
117
|
-
logger.warning(f"Failed to check bundle existence: {e}")
|
|
117
|
+
# logger.warning(f"Failed to check bundle existence: {e}")
|
|
118
|
+
pass
|
|
118
119
|
|
|
119
120
|
# Bundle not found on server - upload needed
|
|
120
|
-
logger.info(f"Bundle {bundle_sha[:8]}... needs to be uploaded")
|
|
121
|
+
# logger.info(f"Bundle {bundle_sha[:8]}... needs to be uploaded")
|
|
121
122
|
return bundle_sha, True # Upload needed
|
|
122
123
|
|
|
123
124
|
async def __call__(self, env: AsyncEnv, *args, **kwargs) -> float:
|
|
@@ -147,7 +148,7 @@ class AsyncVerifierFunction:
|
|
|
147
148
|
)
|
|
148
149
|
|
|
149
150
|
except Exception as e:
|
|
150
|
-
logger.error(f"Error in verifier {self.key}: {e}")
|
|
151
|
+
# logger.error(f"Error in verifier {self.key}: {e}")
|
|
151
152
|
# Return error score 0
|
|
152
153
|
return 0.0
|
|
153
154
|
|
|
@@ -179,7 +180,7 @@ class AsyncVerifierFunction:
|
|
|
179
180
|
try:
|
|
180
181
|
return float(result)
|
|
181
182
|
except (ValueError, TypeError):
|
|
182
|
-
logger.warning(f"Could not convert result to float: {result}")
|
|
183
|
+
# logger.warning(f"Could not convert result to float: {result}")
|
|
183
184
|
return 0.0
|
|
184
185
|
|
|
185
186
|
def _raise_remote_error(self, error_info: Dict[str, Any]):
|
|
@@ -238,7 +239,7 @@ Remote traceback:
|
|
|
238
239
|
|
|
239
240
|
if needs_upload:
|
|
240
241
|
# Need to upload bundle to S3
|
|
241
|
-
logger.info(f"Uploading bundle {bundle_sha[:8]}... for {self.key}")
|
|
242
|
+
# logger.info(f"Uploading bundle {bundle_sha[:8]}... for {self.key}")
|
|
242
243
|
bundle_data, _ = self._get_or_create_bundle()
|
|
243
244
|
|
|
244
245
|
response = await env.execute_verifier_remote(
|
|
@@ -252,11 +253,11 @@ Remote traceback:
|
|
|
252
253
|
needs_upload=True,
|
|
253
254
|
)
|
|
254
255
|
|
|
255
|
-
logger.debug(f"Bundle {bundle_sha[:8]}... uploaded successfully")
|
|
256
|
+
# logger.debug(f"Bundle {bundle_sha[:8]}... uploaded successfully")
|
|
256
257
|
|
|
257
258
|
else:
|
|
258
259
|
# Bundle already available - execute without upload
|
|
259
|
-
logger.info(f"Bundle {bundle_sha[:8]}... already cached for {self.key}")
|
|
260
|
+
# logger.info(f"Bundle {bundle_sha[:8]}... already cached for {self.key}")
|
|
260
261
|
response = await env.execute_verifier_remote(
|
|
261
262
|
bundle_data=b"", # Empty bundle since it's cached
|
|
262
263
|
bundle_sha=bundle_sha,
|
|
@@ -273,9 +274,9 @@ Remote traceback:
|
|
|
273
274
|
except Exception as e:
|
|
274
275
|
# Check if error indicates bundle not found and retry with upload
|
|
275
276
|
if self._is_bundle_not_found_error(e) and not needs_upload:
|
|
276
|
-
logger.info(
|
|
277
|
-
|
|
278
|
-
)
|
|
277
|
+
# logger.info(
|
|
278
|
+
# f"Bundle {bundle_sha[:8]}... not found on server, uploading..."
|
|
279
|
+
# )
|
|
279
280
|
bundle_data, _ = self._get_or_create_bundle()
|
|
280
281
|
response = await env.execute_verifier_remote(
|
|
281
282
|
bundle_data=bundle_data,
|
|
@@ -289,7 +290,7 @@ Remote traceback:
|
|
|
289
290
|
)
|
|
290
291
|
return response
|
|
291
292
|
else:
|
|
292
|
-
logger.error(f"Error in remote execution of {self.key}: {e}")
|
|
293
|
+
# logger.error(f"Error in remote execution of {self.key}: {e}")
|
|
293
294
|
raise
|
|
294
295
|
|
|
295
296
|
|
|
@@ -48,7 +48,7 @@ class BaseWrapper:
|
|
|
48
48
|
import logging
|
|
49
49
|
|
|
50
50
|
logger = logging.getLogger(__name__)
|
|
51
|
-
logger.debug(f"Headers being sent: {headers}")
|
|
51
|
+
# logger.debug(f"Headers being sent: {headers}")
|
|
52
52
|
return headers
|
|
53
53
|
|
|
54
54
|
|
|
@@ -93,8 +93,9 @@ class SyncWrapper(BaseWrapper):
|
|
|
93
93
|
|
|
94
94
|
# Debug log 500 errors
|
|
95
95
|
if status_code == 500:
|
|
96
|
-
logger.error(f"Got 500 error from {response.url}")
|
|
97
|
-
logger.error(f"Response text: {response.text}")
|
|
96
|
+
# logger.error(f"Got 500 error from {response.url}")
|
|
97
|
+
# logger.error(f"Response text: {response.text}")
|
|
98
|
+
pass
|
|
98
99
|
|
|
99
100
|
# Try to parse error response as JSON
|
|
100
101
|
try:
|