fleet-python 0.2.3__py3-none-any.whl → 0.2.5__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 fleet-python might be problematic. Click here for more details.

Files changed (42) hide show
  1. examples/dsl_example.py +2 -1
  2. examples/example.py +2 -2
  3. examples/json_tasks_example.py +1 -1
  4. examples/nova_act_example.py +1 -1
  5. examples/openai_example.py +17 -24
  6. examples/openai_simple_example.py +11 -12
  7. fleet/__init__.py +18 -3
  8. fleet/_async/base.py +51 -0
  9. fleet/_async/client.py +133 -0
  10. fleet/_async/env/__init__.py +0 -0
  11. fleet/_async/env/client.py +15 -0
  12. fleet/_async/exceptions.py +73 -0
  13. fleet/_async/instance/__init__.py +24 -0
  14. fleet/_async/instance/base.py +37 -0
  15. fleet/_async/instance/client.py +278 -0
  16. fleet/_async/instance/models.py +141 -0
  17. fleet/_async/models.py +109 -0
  18. fleet/_async/playwright.py +291 -0
  19. fleet/_async/resources/__init__.py +0 -0
  20. fleet/_async/resources/base.py +26 -0
  21. fleet/_async/resources/browser.py +41 -0
  22. fleet/_async/resources/sqlite.py +41 -0
  23. fleet/base.py +1 -24
  24. fleet/client.py +31 -99
  25. fleet/env/__init__.py +13 -1
  26. fleet/env/client.py +7 -7
  27. fleet/instance/__init__.py +3 -2
  28. fleet/instance/base.py +1 -24
  29. fleet/instance/client.py +40 -57
  30. fleet/playwright.py +45 -47
  31. fleet/resources/__init__.py +0 -0
  32. fleet/resources/browser.py +14 -14
  33. fleet/resources/sqlite.py +11 -11
  34. fleet/verifiers/__init__.py +5 -10
  35. fleet/verifiers/code.py +1 -132
  36. {fleet_python-0.2.3.dist-info → fleet_python-0.2.5.dist-info}/METADATA +12 -11
  37. fleet_python-0.2.5.dist-info/RECORD +48 -0
  38. {fleet_python-0.2.3.dist-info → fleet_python-0.2.5.dist-info}/top_level.txt +1 -0
  39. scripts/unasync.py +28 -0
  40. fleet_python-0.2.3.dist-info/RECORD +0 -31
  41. {fleet_python-0.2.3.dist-info → fleet_python-0.2.5.dist-info}/WHEEL +0 -0
  42. {fleet_python-0.2.3.dist-info → fleet_python-0.2.5.dist-info}/licenses/LICENSE +0 -0
fleet/verifiers/code.py CHANGED
@@ -1,132 +1 @@
1
- import traceback
2
- import logging
3
- from typing import Any, Dict
4
- from .db import DatabaseSnapshot, IgnoreConfig
5
-
6
-
7
- logger = logging.getLogger(__name__)
8
-
9
-
10
- TASK_SUCCESSFUL_SCORE = 1
11
-
12
-
13
- def extract_last_assistant_message(transcript: str) -> str:
14
- """
15
- Extract only the last assistant message from the transcript, filtering out tool calls.
16
-
17
- Args:
18
- transcript: The full conversation transcript
19
-
20
- Returns:
21
- The content of the last assistant message with tool calls filtered out
22
- """
23
- if not transcript:
24
- return ""
25
-
26
- # Split transcript into sections by "Assistant:" markers
27
- sections = transcript.split("Assistant:")
28
- if len(sections) < 2:
29
- # No "Assistant:" markers found, treat entire transcript as assistant message
30
- last_assistant_section = transcript
31
- else:
32
- # Get the last assistant section
33
- last_assistant_section = sections[-1]
34
-
35
- # Filter out specific content blocks using regex-like approach
36
- import re
37
-
38
- # Remove image blocks: <img src="data:..."/>
39
- last_assistant_section = re.sub(
40
- r'<img src="data:[^"]*"[^>]*/?>', "", last_assistant_section
41
- )
42
-
43
- # Remove tool call blocks: .../>
44
- last_assistant_section = re.sub(
45
- r'<tool_call[^>]*>.*?"/>', "", last_assistant_section, flags=re.DOTALL
46
- )
47
-
48
- # Remove tool result blocks: <tool_result>...</tool_result>
49
- last_assistant_section = re.sub(
50
- r"<tool_result>.*?</tool_result>", "", last_assistant_section, flags=re.DOTALL
51
- )
52
-
53
- # Clean up extra whitespace
54
- filtered_transcript = last_assistant_section.strip()
55
-
56
- return filtered_transcript
57
-
58
-
59
- async def execute_validation_function(
60
- function_code: str,
61
- function_name: str,
62
- before_snapshot_path: str,
63
- after_snapshot_path: str,
64
- transcript: str | None = None,
65
- ) -> Dict[str, Any]:
66
- """
67
- Execute arbitrary validation function code with database snapshots.
68
-
69
- Args:
70
- function_code: The Python code containing the function definition
71
- function_name: Name of the function to call after executing the code
72
- before_snapshot_path: Path to the before database snapshot
73
- after_snapshot_path: Path to the after database snapshot
74
-
75
- Returns:
76
- Dict containing success status, result, and any error message
77
- """
78
- try:
79
- # Create database snapshots
80
- before = DatabaseSnapshot(before_snapshot_path)
81
- after = DatabaseSnapshot(after_snapshot_path)
82
-
83
- # Create a namespace with the required imports and constants
84
- namespace = {
85
- "DatabaseSnapshot": DatabaseSnapshot,
86
- "IgnoreConfig": IgnoreConfig,
87
- "TASK_SUCCESSFUL_SCORE": TASK_SUCCESSFUL_SCORE,
88
- "extract_last_assistant_message": extract_last_assistant_message,
89
- "__builtins__": __builtins__,
90
- }
91
-
92
- # Execute the provided code in the namespace
93
- exec(function_code, namespace)
94
-
95
- # Check if the function exists in the namespace
96
- if function_name not in namespace:
97
- return {
98
- "success": False,
99
- "error": f"Function '{function_name}' not found in the provided code",
100
- "result": None,
101
- }
102
-
103
- # Get the function from the namespace
104
- func = namespace[function_name]
105
-
106
- # Call the function with before/after snapshots
107
- # Support both sync and async functions
108
- import inspect
109
-
110
- # Check the function signature to determine how many arguments it accepts
111
- sig = inspect.signature(func)
112
- param_count = len(sig.parameters)
113
-
114
- if inspect.iscoroutinefunction(func):
115
- # Handle async function - we can await it since we're now async
116
- if param_count >= 3:
117
- result = await func(before, after, transcript)
118
- else:
119
- result = await func(before, after)
120
- else:
121
- # Handle sync function
122
- if param_count >= 3:
123
- result = func(before, after, transcript)
124
- else:
125
- result = func(before, after)
126
-
127
- return {"success": True, "result": result, "error": None}
128
-
129
- except Exception as e:
130
- error_msg = f"Error executing function: {str(e)}\n{traceback.format_exc()}"
131
- logger.error(error_msg)
132
- return {"success": False, "error": error_msg, "result": None}
1
+ TASK_SUCCESSFUL_SCORE = 1
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fleet-python
3
- Version: 0.2.3
3
+ Version: 0.2.5
4
4
  Summary: Python SDK for Fleet environments
5
5
  Author-email: Fleet AI <nic@fleet.so>
6
6
  License: Apache-2.0
@@ -31,6 +31,7 @@ Requires-Dist: black>=22.0.0; extra == "dev"
31
31
  Requires-Dist: isort>=5.0.0; extra == "dev"
32
32
  Requires-Dist: mypy>=1.0.0; extra == "dev"
33
33
  Requires-Dist: ruff>=0.1.0; extra == "dev"
34
+ Requires-Dist: unasync>=0.6.0; extra == "dev"
34
35
  Provides-Extra: playwright
35
36
  Requires-Dist: playwright>=1.40.0; extra == "playwright"
36
37
  Dynamic: license-file
@@ -63,20 +64,20 @@ export FLEET_API_KEY="sk_your_key_here"
63
64
  import fleet as flt
64
65
 
65
66
  # Create environment by key
66
- env = await flt.env.make("fira")
67
+ env = flt.env.make("fira")
67
68
 
68
69
  # Reset environment with seed and options
69
- await env.reset(
70
+ env.reset(
70
71
  seed=42,
71
72
  timestamp=datetime.now()
72
73
  )
73
74
 
74
75
  # Access environment state ('crm' is the resource id for a sqlite database)
75
76
  sql = env.state("sqlite://crm")
76
- await sql.exec("UPDATE customers SET status = 'active' WHERE id = 123")
77
+ sql.exec("UPDATE customers SET status = 'active' WHERE id = 123")
77
78
 
78
79
  # Clean up
79
- await env.close()
80
+ env.close()
80
81
  ```
81
82
 
82
83
  ## Environment Management
@@ -85,10 +86,10 @@ await env.close()
85
86
 
86
87
  ```python
87
88
  # Create environment instance with explicit version
88
- env = await flt.env.make("fira:v1.2.5")
89
+ env = flt.env.make("fira:v1.2.5")
89
90
 
90
91
  # Create environment instance with default (latest) version
91
- env = await flt.env.make("fira")
92
+ env = flt.env.make("fira")
92
93
 
93
94
  ```
94
95
 
@@ -96,18 +97,18 @@ env = await flt.env.make("fira")
96
97
 
97
98
  ```python
98
99
  # Connect to a running instance
99
- env = await flt.env.get("env_instance_id")
100
+ env = flt.env.get("env_instance_id")
100
101
 
101
102
  # List all running instances
102
- instances = await flt.env.list_instances()
103
+ instances = flt.env.list_instances()
103
104
  for instance in instances:
104
105
  print(f"Instance: {instance.instance_id}")
105
106
  print(f"Type: {instance.environment_type}")
106
107
  print(f"Status: {instance.status}")
107
108
 
108
109
  # Filter instances by status (running, pending, stopped, error)
109
- running_instances = await flt.env.list_instances(status_filter="running")
110
+ running_instances = flt.env.list_instances(status_filter="running")
110
111
 
111
112
  # List available environment types
112
- available_envs = await flt.env.list_envs()
113
+ available_envs = flt.env.list_envs()
113
114
  ```
@@ -0,0 +1,48 @@
1
+ examples/dsl_example.py,sha256=nBfKdv4u6XuM97TG-ugfVStPdtoYq86ildFzLcQqGIk,5315
2
+ examples/example.py,sha256=B1ERVudPsPx1D1od3gCQU8MnG4FxuSBm0p7otkvIaLw,945
3
+ examples/json_tasks_example.py,sha256=_y4w94FfAaMBGgIqhVlrDU0PXbinNDWrT28DsUMvd9Y,2354
4
+ examples/nova_act_example.py,sha256=YMfx_7O1_6pqsy0Rf6Yabyqyg4_kI3cgMBlMJjAQXW4,790
5
+ examples/openai_example.py,sha256=5ZvBC0dcw8gPHoC6Gn-1KZx3CmUQBlBmPJgOrcgMSVM,8188
6
+ examples/openai_simple_example.py,sha256=pS2z7Q3s7tml5hbahc1NGgMXoF0mWwhi7VeLDTA4sE4,1702
7
+ examples/quickstart.py,sha256=lVRzbnWIweU9ioe7uk6R2Rm7oSpt4mt8Jq_VUUp1zKg,4696
8
+ fleet/__init__.py,sha256=CxDokocjQsv_JUNwhSqnijpQVXhQx73CXLu2Cp-rtgk,2087
9
+ fleet/base.py,sha256=t4xkgazl8kEP05JFjNByyf39RvvASRP0GsvxuoqKPY0,1395
10
+ fleet/client.py,sha256=SQEUoj4DMuXa4m5wfPPCkBEhQc7f6941K9V8Qk6ZF0U,4675
11
+ fleet/exceptions.py,sha256=yG3QWprCw1OnF-vdFBFJWE4m3ftBLBng31Dr__VbjI4,2249
12
+ fleet/models.py,sha256=Jf6Zmk689TPXhTSnVENK_VCw0VsujWzEWsN3T29MQ0k,3713
13
+ fleet/playwright.py,sha256=LWx_1UlNZPo117Lf7qnBlWT4RJA0OcwqRVRdFE98bSQ,8627
14
+ fleet/_async/base.py,sha256=hUch1I5oUPgaCXR3IpJ8f_PjigifAZg2-LR7BJdZSo8,1413
15
+ fleet/_async/client.py,sha256=pL0csdrAJKltA9km6DHDRogPpTEzi8AH32mS1efxNgg,4920
16
+ fleet/_async/exceptions.py,sha256=yG3QWprCw1OnF-vdFBFJWE4m3ftBLBng31Dr__VbjI4,2249
17
+ fleet/_async/models.py,sha256=Jf6Zmk689TPXhTSnVENK_VCw0VsujWzEWsN3T29MQ0k,3713
18
+ fleet/_async/playwright.py,sha256=5MLFPE5P_-MpzAQ3EJ6GsLthuJiWwYkNuvhPE_rwe_E,8914
19
+ fleet/_async/env/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
20
+ fleet/_async/env/client.py,sha256=Gft6pNkUK4PYMV8VE3KyS5R_-HuqGO5HEjAUuCPObiw,440
21
+ fleet/_async/instance/__init__.py,sha256=jIt-7EEJ0WM_ipheT_s0lniCbLei6yUdN0qQv1bMJ3E,524
22
+ fleet/_async/instance/base.py,sha256=QgcCTHdcqhi5VQi6_a1uuR-uO2_2Z19-RwVPp1k266A,947
23
+ fleet/_async/instance/client.py,sha256=Llc-yefnbL3fkBsayU4ANEqy_fFB2Uy6jNhTkfGj1mU,9362
24
+ fleet/_async/instance/models.py,sha256=ZTiue0YOuhuwX8jYfJAoCzGfqjLqqXRLqK1LVFhq6rQ,4183
25
+ fleet/_async/resources/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
26
+ fleet/_async/resources/base.py,sha256=203gD54NP1IvjuSqFo-f7FvrkhtjChggtzrxJK7xf2E,667
27
+ fleet/_async/resources/browser.py,sha256=x11y4aKHogIEv83FByHtExerjV-cDWI3U62349Guq_Q,1368
28
+ fleet/_async/resources/sqlite.py,sha256=sRiII_qJ8X6-FSemlBsXThz4ZPjkNy9wDT8g5UAz2XM,1501
29
+ fleet/env/__init__.py,sha256=_lvYBqieXWmvU_dyPi2seSpLO3AZh5kdprdqFeefkzk,338
30
+ fleet/env/client.py,sha256=UGPrRlu89NM2RFdY7m6cGwUjOHJdtiPe4vkz-f2ByRg,351
31
+ fleet/instance/__init__.py,sha256=cdVC50HLLp2y7yf1Ga5wpLiy-hmamxmyibH0NDG7xI4,597
32
+ fleet/instance/base.py,sha256=U-qW1EQVBo6yvMpP1JeKiPRhCjZ3y3aTsYFhLPNOTtQ,929
33
+ fleet/instance/client.py,sha256=RFp5R703pP3tjKd_HBozJJ2qNie7LpMUx9NYjyPnPOI,9128
34
+ fleet/instance/models.py,sha256=ZTiue0YOuhuwX8jYfJAoCzGfqjLqqXRLqK1LVFhq6rQ,4183
35
+ fleet/resources/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
36
+ fleet/resources/base.py,sha256=203gD54NP1IvjuSqFo-f7FvrkhtjChggtzrxJK7xf2E,667
37
+ fleet/resources/browser.py,sha256=hRNM0YMsVQUAraZGNi_B-KXxLpuddy4ntoEDFSw7czU,1295
38
+ fleet/resources/sqlite.py,sha256=sZVWsuq46ger-ta6PSlqcXGJG8iWpNQVj0CPmDNBXv8,1446
39
+ fleet/verifiers/__init__.py,sha256=mRMN8x0gDWFJ1MRLqdBtQw0gn_q8kDV3lMLyoiEf1yY,281
40
+ fleet/verifiers/code.py,sha256=NJ4OLZnpqLkI1lXY7-5m2GuZklLxMzHUCnRMVyN2_OI,25
41
+ fleet/verifiers/db.py,sha256=tssmvJjDHuBIy8qlL_P5-UdmEFUw2DZcqLsWZ8ot3Xw,27766
42
+ fleet/verifiers/sql_differ.py,sha256=dmiGCFXVMEMbAX519OjhVqgA8ZvhnvdmC1BVpL7QCF0,6490
43
+ fleet_python-0.2.5.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
44
+ scripts/unasync.py,sha256=--Fmaae47o-dZ1HYgX1c3Nvi-rMjcFymTRlJcWWnmpw,725
45
+ fleet_python-0.2.5.dist-info/METADATA,sha256=MqmuFENsTkHkP2gU9_UQB35NQH4hL5POBYGpYCASRIY,3139
46
+ fleet_python-0.2.5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
47
+ fleet_python-0.2.5.dist-info/top_level.txt,sha256=_3DSmTohvSDf3AIP_BYfGzhwO1ECFwuzg83X-wHCx3Y,23
48
+ fleet_python-0.2.5.dist-info/RECORD,,
@@ -1,2 +1,3 @@
1
1
  examples
2
2
  fleet
3
+ scripts
scripts/unasync.py ADDED
@@ -0,0 +1,28 @@
1
+ #!/usr/bin/env python3
2
+ """Run unasync to generate sync versions of async code."""
3
+
4
+ import subprocess
5
+ import sys
6
+ from pathlib import Path
7
+
8
+ def run_unasync():
9
+ """Run unasync on the fleet/_async directory."""
10
+ print("Running unasync to generate sync code...")
11
+
12
+ try:
13
+ # Run unasync
14
+ subprocess.run([
15
+ sys.executable, "-m", "unasync",
16
+ "fleet/_async", "fleet",
17
+ "--no-cache"
18
+ ], check=True)
19
+
20
+ print("Successfully generated sync code from async sources.")
21
+ return 0
22
+
23
+ except subprocess.CalledProcessError as e:
24
+ print(f"Error running unasync: {e}")
25
+ return 1
26
+
27
+ if __name__ == "__main__":
28
+ sys.exit(run_unasync())
@@ -1,31 +0,0 @@
1
- examples/dsl_example.py,sha256=W-g0RR7qOTGUSHYiFhcwL3MsrHB-C6t3UHQg6XTxxss,5259
2
- examples/example.py,sha256=G_UC4fD55QKPPMAKINtsJs0U6b0wg-GbpaeIGwLnhWw,933
3
- examples/json_tasks_example.py,sha256=fz1hGaJ_VukH2gwJFvhQmyWRO8ocN9ptFnplTJSOrbA,2348
4
- examples/nova_act_example.py,sha256=EwTivGRpJ4ZGicJw0eK46lvjgjN0_x3FJavafzdVkfc,777
5
- examples/openai_example.py,sha256=ebaGIs1OFhohUdtQ0fHcMUqvmCd0vJa45_FUo58eTh4,8486
6
- examples/openai_simple_example.py,sha256=16u_g9vD8mHNTZhta6Qdq_qAQs-wU6FaPVkhGUPnSIs,1788
7
- examples/quickstart.py,sha256=lVRzbnWIweU9ioe7uk6R2Rm7oSpt4mt8Jq_VUUp1zKg,4696
8
- fleet/__init__.py,sha256=AjkbRVYzfIUYEw1PvCceGhHBCPOu_c6Qx5KweoNmAQM,1747
9
- fleet/base.py,sha256=5JnzMMyT1Ey8SrYs4Ydka3bUoYRRA-wxHx1yCURAM48,2009
10
- fleet/client.py,sha256=RFOEhxJa_de3N6JP48p8xMYhsGVRv5V4U4OWINKpQ8Y,7392
11
- fleet/exceptions.py,sha256=yG3QWprCw1OnF-vdFBFJWE4m3ftBLBng31Dr__VbjI4,2249
12
- fleet/models.py,sha256=Jf6Zmk689TPXhTSnVENK_VCw0VsujWzEWsN3T29MQ0k,3713
13
- fleet/playwright.py,sha256=5MLFPE5P_-MpzAQ3EJ6GsLthuJiWwYkNuvhPE_rwe_E,8914
14
- fleet/env/__init__.py,sha256=_zcEf-sukzVblsTfzQbc9ixDC47bsTts2fHlKyu3OMc,81
15
- fleet/env/client.py,sha256=I2ja8upwdRcBnehn4GRtkRgWPCLz0cJpbSvQmSuKVrc,423
16
- fleet/instance/__init__.py,sha256=pKuX6zPpTKmJD0c-Qg_hRdnQuiWNohQdYhlHElxilQE,562
17
- fleet/instance/base.py,sha256=bm6BGd81TnTDqE_qG6S50Xhikf9DwNqEEk1uKFY7dEk,1540
18
- fleet/instance/client.py,sha256=Tybjm0jbxM_lnTvQ-Gtm2e8u2qvk9vjDfBwns-DpQhw,9872
19
- fleet/instance/models.py,sha256=ZTiue0YOuhuwX8jYfJAoCzGfqjLqqXRLqK1LVFhq6rQ,4183
20
- fleet/resources/base.py,sha256=203gD54NP1IvjuSqFo-f7FvrkhtjChggtzrxJK7xf2E,667
21
- fleet/resources/browser.py,sha256=x11y4aKHogIEv83FByHtExerjV-cDWI3U62349Guq_Q,1368
22
- fleet/resources/sqlite.py,sha256=sRiII_qJ8X6-FSemlBsXThz4ZPjkNy9wDT8g5UAz2XM,1501
23
- fleet/verifiers/__init__.py,sha256=sNlURjry8FYFa-0qFy6boRCcNjXAtMPFaAfpaRqpOPk,394
24
- fleet/verifiers/code.py,sha256=YB96SPncu9emO-udQh7zYf_UR1aPz7nBjPtKf5O6fD8,4356
25
- fleet/verifiers/db.py,sha256=tssmvJjDHuBIy8qlL_P5-UdmEFUw2DZcqLsWZ8ot3Xw,27766
26
- fleet/verifiers/sql_differ.py,sha256=dmiGCFXVMEMbAX519OjhVqgA8ZvhnvdmC1BVpL7QCF0,6490
27
- fleet_python-0.2.3.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
28
- fleet_python-0.2.3.dist-info/METADATA,sha256=jdYK3MqjugV1mQ4Bl0Uw-ZH1HQL6Vzr0vTFcnP2xATw,3153
29
- fleet_python-0.2.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
30
- fleet_python-0.2.3.dist-info/top_level.txt,sha256=AOyXOrBXUjPcH4BumElz_D95kiWKNIpUbUPFP_9gCLk,15
31
- fleet_python-0.2.3.dist-info/RECORD,,