fleet-python 0.2.13__py3-none-any.whl → 0.2.15__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 (41) hide show
  1. examples/diff_example.py +161 -0
  2. examples/dsl_example.py +50 -1
  3. examples/example_action_log.py +28 -0
  4. examples/example_mcp_anthropic.py +77 -0
  5. examples/example_mcp_openai.py +27 -0
  6. examples/example_task.py +199 -0
  7. examples/example_verifier.py +71 -0
  8. examples/query_builder_example.py +117 -0
  9. fleet/__init__.py +51 -40
  10. fleet/_async/base.py +14 -1
  11. fleet/_async/client.py +137 -19
  12. fleet/_async/env/client.py +4 -4
  13. fleet/_async/instance/__init__.py +1 -2
  14. fleet/_async/instance/client.py +3 -2
  15. fleet/_async/playwright.py +2 -2
  16. fleet/_async/resources/sqlite.py +654 -0
  17. fleet/_async/tasks.py +44 -0
  18. fleet/_async/verifiers/__init__.py +17 -0
  19. fleet/_async/verifiers/bundler.py +699 -0
  20. fleet/_async/verifiers/verifier.py +301 -0
  21. fleet/base.py +14 -1
  22. fleet/client.py +645 -12
  23. fleet/config.py +1 -1
  24. fleet/instance/__init__.py +1 -2
  25. fleet/instance/client.py +15 -5
  26. fleet/models.py +171 -4
  27. fleet/resources/browser.py +7 -8
  28. fleet/resources/mcp.py +60 -0
  29. fleet/resources/sqlite.py +654 -0
  30. fleet/tasks.py +44 -0
  31. fleet/types.py +18 -0
  32. fleet/verifiers/__init__.py +11 -5
  33. fleet/verifiers/bundler.py +699 -0
  34. fleet/verifiers/decorator.py +103 -0
  35. fleet/verifiers/verifier.py +301 -0
  36. {fleet_python-0.2.13.dist-info → fleet_python-0.2.15.dist-info}/METADATA +3 -42
  37. fleet_python-0.2.15.dist-info/RECORD +69 -0
  38. fleet_python-0.2.13.dist-info/RECORD +0 -52
  39. {fleet_python-0.2.13.dist-info → fleet_python-0.2.15.dist-info}/WHEEL +0 -0
  40. {fleet_python-0.2.13.dist-info → fleet_python-0.2.15.dist-info}/licenses/LICENSE +0 -0
  41. {fleet_python-0.2.13.dist-info → fleet_python-0.2.15.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,117 @@
1
+ import asyncio
2
+ import fleet as flt
3
+ from dotenv import load_dotenv
4
+
5
+ load_dotenv()
6
+
7
+
8
+ async def main():
9
+ # Create a new instance
10
+ print("Creating new Hubspot instance...")
11
+ env = await flt.env.make_async("hubspot:v1.2.7")
12
+ print(f"New Instance: {env.instance_id}")
13
+
14
+ try:
15
+ # Reset the instance
16
+ response = await env.reset(seed=42)
17
+ print(f"Reset response: {response}")
18
+
19
+ # Get the database resource
20
+ db = env.db()
21
+
22
+ # Example 1: Query with the builder pattern
23
+ print("\n=== Query Builder Examples ===")
24
+
25
+ # Find all entries of type 'deal'
26
+ print("\n1. Finding all deals:")
27
+ deals = await db.table("entries").eq("type", "deal").all()
28
+ print(f"Found {len(deals)} deals")
29
+
30
+ # Count entries
31
+ print("\n2. Counting entries:")
32
+ entry_count = await db.table("entries").count()
33
+ print(f"Total entries: {entry_count}")
34
+
35
+ # Find a specific entry
36
+ print("\n3. Finding specific entry:")
37
+ entry = await db.table("entries").eq("id", 1).first()
38
+ if entry:
39
+ print(f"Found entry: {entry['name']} (type: {entry['type']})")
40
+
41
+ # Complex query with multiple conditions
42
+ print("\n4. Complex query with conditions:")
43
+ recent_deals = await (
44
+ db.table("entries")
45
+ .eq("type", "deal")
46
+ .not_null("name")
47
+ .select("id", "name", "type", "createdDate")
48
+ .sort("createdDate", desc=True)
49
+ .limit(5)
50
+ .all()
51
+ )
52
+ print(f"Recent deals: {len(recent_deals)}")
53
+ for deal in recent_deals:
54
+ print(f" - {deal['name']} (id: {deal['id']})")
55
+
56
+ # Using assertions
57
+ print("\n5. Using assertions:")
58
+ try:
59
+ # This should succeed if there are entries
60
+ await db.table("entries").assert_exists()
61
+ print("✓ Entries table has records")
62
+ except AssertionError as e:
63
+ print(f"✗ Assertion failed: {e}")
64
+
65
+ # Check for non-existent record
66
+ try:
67
+ await db.table("entries").eq("id", 999999).assert_none()
68
+ print("✓ No entry with id 999999")
69
+ except AssertionError as e:
70
+ print(f"✗ Assertion failed: {e}")
71
+
72
+ # Insert a new entry and verify with query builder
73
+ print("\n6. Insert and verify with query builder:")
74
+ insert_query = """
75
+ INSERT INTO entries (id, name, type, owner_id, createdDate, lastModifiedDate, createdAt, updatedAt, properties)
76
+ VALUES (
77
+ 99999,
78
+ 'Test Deal via Query Builder',
79
+ 'deal',
80
+ 1,
81
+ datetime('now'),
82
+ datetime('now'),
83
+ datetime('now'),
84
+ datetime('now'),
85
+ '{}'
86
+ )
87
+ """
88
+ await db.exec(insert_query)
89
+
90
+ # Verify insertion with query builder
91
+ new_deal = await db.table("entries").eq("id", 99999).first()
92
+ if new_deal:
93
+ print(f"✓ Successfully inserted: {new_deal['name']}")
94
+
95
+ # Assert specific field value
96
+ await db.table("entries").eq("id", 99999).assert_eq("name", "Test Deal via Query Builder")
97
+ print("✓ Name assertion passed")
98
+
99
+ # Using IN clause
100
+ print("\n7. Using IN clause:")
101
+ specific_entries = await db.table("entries").in_("id", [1, 2, 3]).all()
102
+ print(f"Found {len(specific_entries)} entries with ids in [1, 2, 3]")
103
+
104
+ # Pattern matching with LIKE
105
+ print("\n8. Pattern matching:")
106
+ test_entries = await db.table("entries").ilike("name", "%test%").all()
107
+ print(f"Found {len(test_entries)} entries with 'test' in name")
108
+
109
+ finally:
110
+ # Delete the instance
111
+ print("\n\nDeleting instance...")
112
+ await env.close()
113
+ print("Instance deleted.")
114
+
115
+
116
+ if __name__ == "__main__":
117
+ asyncio.run(main())
fleet/__init__.py CHANGED
@@ -23,60 +23,71 @@ from .exceptions import (
23
23
  FleetConfigurationError,
24
24
  )
25
25
  from .client import Fleet, Environment
26
- from ._async.client import AsyncFleet, AsyncEnvironment
27
- from .models import InstanceRequest
28
- from .instance import (
29
- InstanceClient,
30
- ResetRequest,
31
- ResetResponse,
32
- CDPDescribeResponse,
33
- ChromeStartRequest,
34
- ChromeStartResponse,
35
- ChromeStatusResponse,
36
- )
37
- from ._async.instance import AsyncInstanceClient
26
+ from ._async.client import AsyncFleet, AsyncEnv
27
+ from .models import InstanceRecord
28
+ from .instance.models import Resource, ResetResponse
29
+
30
+ # Import sync verifiers with explicit naming
38
31
  from .verifiers import (
32
+ verifier as verifier_sync,
33
+ SyncVerifierFunction,
39
34
  DatabaseSnapshot,
40
35
  IgnoreConfig,
41
36
  SnapshotDiff,
42
37
  TASK_SUCCESSFUL_SCORE,
43
38
  )
39
+
40
+ # Import Playwright wrapper
41
+ from .playwright import FleetPlaywrightWrapper
42
+
43
+ # Import async verifiers (default verifier is async for modern usage)
44
+ from ._async.verifiers import (
45
+ verifier,
46
+ AsyncVerifierFunction,
47
+ )
48
+
49
+ # Import async tasks (default tasks are async for modern usage)
50
+ from ._async.tasks import Task
51
+
52
+ # Import shared types
53
+ from .types import VerifierFunction
54
+
55
+ # Create a module-level env attribute for convenient access
44
56
  from . import env
45
57
 
46
- # Optional playwright integration
47
- try:
48
- from .playwright import FleetPlaywrightWrapper
49
- _PLAYWRIGHT_AVAILABLE = True
50
- except ImportError:
51
- FleetPlaywrightWrapper = None
52
- _PLAYWRIGHT_AVAILABLE = False
58
+ __version__ = "0.1.0"
53
59
 
54
- __version__ = "0.1.1"
55
60
  __all__ = [
56
- "env",
57
- "FleetError",
58
- "FleetAPIError",
59
- "FleetTimeoutError",
60
- "FleetConfigurationError",
61
+ # Core classes
61
62
  "Fleet",
62
63
  "Environment",
63
64
  "AsyncFleet",
64
- "AsyncEnvironment",
65
- "InstanceClient",
66
- "AsyncInstanceClient",
67
- "InstanceRequest",
68
- "ResetRequest",
65
+ "AsyncEnv",
66
+ # Models
67
+ "InstanceRecord",
68
+ "Resource",
69
69
  "ResetResponse",
70
- "CDPDescribeResponse",
71
- "ChromeStartRequest",
72
- "ChromeStartResponse",
73
- "ChromeStatusResponse",
70
+ # Task models
71
+ "Task",
72
+ "VerifierFunction",
73
+ # Exceptions
74
+ "FleetError",
75
+ "FleetAPIError",
76
+ "FleetTimeoutError",
77
+ "FleetConfigurationError",
78
+ # Playwright wrapper
79
+ "FleetPlaywrightWrapper",
80
+ # Verifiers (async is default)
81
+ "verifier",
82
+ "verifier_sync",
83
+ "AsyncVerifierFunction",
84
+ "SyncVerifierFunction",
74
85
  "DatabaseSnapshot",
75
- "IgnoreConfig",
86
+ "IgnoreConfig",
76
87
  "SnapshotDiff",
77
88
  "TASK_SUCCESSFUL_SCORE",
78
- ]
79
-
80
- # Add playwright wrapper to exports if available
81
- if _PLAYWRIGHT_AVAILABLE:
82
- __all__.append("FleetPlaywrightWrapper")
89
+ # Environment module
90
+ "env",
91
+ # Version
92
+ "__version__",
93
+ ]
fleet/_async/base.py CHANGED
@@ -1,8 +1,10 @@
1
1
  import httpx
2
2
  from typing import Dict, Any, Optional
3
3
  import json
4
+ import logging
4
5
 
5
6
  from ..models import InstanceResponse
7
+ from ..config import GLOBAL_BASE_URL
6
8
  from .exceptions import (
7
9
  FleetAPIError,
8
10
  FleetAuthenticationError,
@@ -18,6 +20,8 @@ from .exceptions import (
18
20
  FleetPermissionError,
19
21
  )
20
22
 
23
+ logger = logging.getLogger(__name__)
24
+
21
25
 
22
26
  class EnvironmentBase(InstanceResponse):
23
27
  @property
@@ -31,7 +35,7 @@ class BaseWrapper:
31
35
  raise ValueError("api_key is required")
32
36
  self.api_key = api_key
33
37
  if base_url is None:
34
- base_url = "https://orchestrator.fleetai.com"
38
+ base_url = GLOBAL_BASE_URL
35
39
  self.base_url = base_url
36
40
 
37
41
  def get_headers(self) -> Dict[str, str]:
@@ -40,6 +44,10 @@ class BaseWrapper:
40
44
  "X-Fleet-SDK-Version": "1.0.0",
41
45
  }
42
46
  headers["Authorization"] = f"Bearer {self.api_key}"
47
+ # Debug log
48
+ import logging
49
+ logger = logging.getLogger(__name__)
50
+ logger.debug(f"Headers being sent: {headers}")
43
51
  return headers
44
52
 
45
53
 
@@ -81,6 +89,11 @@ class AsyncWrapper(BaseWrapper):
81
89
  def _handle_error_response(self, response: httpx.Response) -> None:
82
90
  """Handle HTTP error responses and convert to appropriate Fleet exceptions."""
83
91
  status_code = response.status_code
92
+
93
+ # Debug log 500 errors
94
+ if status_code == 500:
95
+ logger.error(f"Got 500 error from {response.url}")
96
+ logger.error(f"Response text: {response.text}")
84
97
 
85
98
  # Try to parse error response as JSON
86
99
  try:
fleet/_async/client.py CHANGED
@@ -14,23 +14,32 @@
14
14
 
15
15
  """Fleet API Client for making HTTP requests to Fleet services."""
16
16
 
17
- import os
17
+ import base64
18
+ import cloudpickle
18
19
  import httpx
19
20
  import logging
20
- from typing import Optional, List
21
+ import os
22
+ from typing import List, Optional
21
23
 
22
24
  from .base import EnvironmentBase, AsyncWrapper
23
- from ..models import InstanceRequest, InstanceRecord, Environment as EnvironmentModel
25
+ from ..models import (
26
+ InstanceRequest,
27
+ InstanceRecord,
28
+ Environment as EnvironmentModel,
29
+ VerifiersCheckResponse,
30
+ VerificationResponse,
31
+ VerifiersExecuteResponse,
32
+ )
24
33
 
25
34
  from .instance import (
26
35
  AsyncInstanceClient,
27
36
  ResetRequest,
28
37
  ResetResponse,
29
- ValidatorType,
30
38
  ExecuteFunctionResponse,
31
39
  )
32
40
  from ..config import DEFAULT_MAX_RETRIES, DEFAULT_TIMEOUT, REGION_BASE_URL
33
41
  from .instance.base import default_httpx_client
42
+ from .instance.client import ValidatorType
34
43
  from .resources.base import Resource
35
44
  from .resources.sqlite import AsyncSQLiteResource
36
45
  from .resources.browser import AsyncBrowserResource
@@ -38,13 +47,8 @@ from .resources.browser import AsyncBrowserResource
38
47
  logger = logging.getLogger(__name__)
39
48
 
40
49
 
41
- async def _delete_instance(client: AsyncWrapper, instance_id: str) -> InstanceRecord:
42
- response = await client.request("DELETE", f"/v1/env/instances/{instance_id}")
43
- return InstanceRecord(**response.json())
44
-
45
-
46
- class AsyncEnvironment(EnvironmentBase):
47
- def __init__(self, client: AsyncWrapper, **kwargs):
50
+ class AsyncEnv(EnvironmentBase):
51
+ def __init__(self, client: Optional[AsyncWrapper], **kwargs):
48
52
  super().__init__(**kwargs)
49
53
  self._client = client
50
54
  self._instance: Optional[AsyncInstanceClient] = None
@@ -53,10 +57,16 @@ class AsyncEnvironment(EnvironmentBase):
53
57
  def instance(self) -> AsyncInstanceClient:
54
58
  if self._instance is None:
55
59
  self._instance = AsyncInstanceClient(
56
- self.manager_url, self._client.httpx_client
60
+ self.manager_url, self._client.httpx_client if self._client else None
57
61
  )
58
62
  return self._instance
59
63
 
64
+ @property
65
+ def _load_client(self) -> AsyncWrapper:
66
+ if self._client is None:
67
+ raise ValueError("Client not initialized")
68
+ return self._client
69
+
60
70
  async def reset(
61
71
  self, seed: Optional[int] = None, timestamp: Optional[int] = None
62
72
  ) -> ResetResponse:
@@ -75,7 +85,7 @@ class AsyncEnvironment(EnvironmentBase):
75
85
  return await self.instance.resources()
76
86
 
77
87
  async def close(self) -> InstanceRecord:
78
- return await _delete_instance(self._client, self.instance_id)
88
+ return await _delete_instance(self._load_client, self.instance_id)
79
89
 
80
90
  async def verify(self, validator: ValidatorType) -> ExecuteFunctionResponse:
81
91
  return await self.instance.verify(validator)
@@ -85,6 +95,41 @@ class AsyncEnvironment(EnvironmentBase):
85
95
  ) -> ExecuteFunctionResponse:
86
96
  return await self.instance.verify_raw(function_code, function_name)
87
97
 
98
+ async def check_bundle_exists(self, bundle_hash: str) -> VerifiersCheckResponse:
99
+ return await _check_bundle_exists(self._load_client, bundle_hash)
100
+
101
+ async def execute_verifier_remote(
102
+ self,
103
+ bundle_data: bytes,
104
+ bundle_sha: str,
105
+ key: str,
106
+ function_name: str,
107
+ args: tuple,
108
+ kwargs: dict,
109
+ timeout: Optional[int] = 30,
110
+ needs_upload: bool = True,
111
+ ) -> VerifiersExecuteResponse:
112
+ return await _execute_verifier_remote(
113
+ self._load_client,
114
+ bundle_data,
115
+ bundle_sha,
116
+ key,
117
+ function_name,
118
+ args,
119
+ kwargs,
120
+ timeout,
121
+ needs_upload
122
+ )
123
+
124
+ def __getstate__(self):
125
+ state = self.__dict__.copy()
126
+ state.pop("_client", None)
127
+ state.pop("_instance", None)
128
+ return state
129
+
130
+ def __setstate__(self, state):
131
+ self.__dict__.update(state)
132
+
88
133
 
89
134
  class AsyncFleet:
90
135
  def __init__(
@@ -116,7 +161,7 @@ class AsyncFleet:
116
161
 
117
162
  async def make(
118
163
  self, env_key: str, region: Optional[str] = None
119
- ) -> AsyncEnvironment:
164
+ ) -> AsyncEnv:
120
165
  if ":" in env_key:
121
166
  env_key_part, version = env_key.split(":", 1)
122
167
  if not version.startswith("v"):
@@ -133,13 +178,13 @@ class AsyncFleet:
133
178
  json=request.model_dump(),
134
179
  base_url=region_base_url,
135
180
  )
136
- instance = AsyncEnvironment(client=self.client, **response.json())
181
+ instance = AsyncEnv(client=self.client, **response.json())
137
182
  await instance.instance.load()
138
183
  return instance
139
184
 
140
185
  async def instances(
141
186
  self, status: Optional[str] = None, region: Optional[str] = None
142
- ) -> List[AsyncEnvironment]:
187
+ ) -> List[AsyncEnv]:
143
188
  params = {}
144
189
  if status:
145
190
  params["status"] = status
@@ -148,15 +193,88 @@ class AsyncFleet:
148
193
 
149
194
  response = await self.client.request("GET", "/v1/env/instances", params=params)
150
195
  return [
151
- AsyncEnvironment(client=self.client, **instance_data)
196
+ AsyncEnv(client=self.client, **instance_data)
152
197
  for instance_data in response.json()
153
198
  ]
154
199
 
155
- async def instance(self, instance_id: str) -> AsyncEnvironment:
200
+ async def instance(self, instance_id: str) -> AsyncEnv:
156
201
  response = await self.client.request("GET", f"/v1/env/instances/{instance_id}")
157
- instance = AsyncEnvironment(client=self.client, **response.json())
202
+ instance = AsyncEnv(client=self.client, **response.json())
158
203
  await instance.instance.load()
159
204
  return instance
160
205
 
206
+ async def check_bundle_exists(self, bundle_hash: str) -> VerifiersCheckResponse:
207
+ return await _check_bundle_exists(self.client, bundle_hash)
208
+
209
+ async def execute_verifier_remote(
210
+ self, bundle_data: bytes, args: tuple, kwargs: dict, timeout: Optional[int] = 30
211
+ ) -> VerifiersExecuteResponse:
212
+ return await _execute_verifier_remote(
213
+ self.client, bundle_data, args, kwargs, timeout
214
+ )
215
+
161
216
  async def delete(self, instance_id: str) -> InstanceRecord:
162
217
  return await _delete_instance(self.client, instance_id)
218
+
219
+
220
+ # Shared
221
+ async def _delete_instance(client: AsyncWrapper, instance_id: str) -> InstanceRecord:
222
+ response = await client.request("DELETE", f"/v1/env/instances/{instance_id}")
223
+ return InstanceRecord(**response.json())
224
+
225
+
226
+ async def _check_bundle_exists(
227
+ client: AsyncWrapper, bundle_hash: str
228
+ ) -> VerifiersCheckResponse:
229
+ response = await client.request("GET", f"/v1/verifiers/check?sha256={bundle_hash}")
230
+ return VerifiersCheckResponse(**response.json())
231
+
232
+
233
+ async def _execute_verifier_remote(
234
+ client: AsyncWrapper,
235
+ bundle_data: bytes,
236
+ bundle_sha: str,
237
+ key: str,
238
+ function_name: str,
239
+ args: tuple,
240
+ kwargs: dict,
241
+ timeout: Optional[int] = 30,
242
+ needs_upload: bool = True,
243
+ ) -> VerificationResponse:
244
+ # Pickle args and kwargs together
245
+ # The first arg should be None as a placeholder for env
246
+ args_with_none = (None,) + args
247
+ args_kwargs_pickled = cloudpickle.dumps({"args": args_with_none, "kwargs": kwargs})
248
+ args_kwargs_b64 = base64.b64encode(args_kwargs_pickled).decode("utf-8")
249
+
250
+ # Build request data
251
+ request_data = {
252
+ "key": key,
253
+ "sha256": bundle_sha,
254
+ "args": args_kwargs_b64,
255
+ "function_name": function_name,
256
+ "timeout": timeout,
257
+ "region": "us-west-1", # TODO: make configurable
258
+ }
259
+
260
+ # Add bundle data only if upload is needed
261
+ if needs_upload:
262
+ bundle_b64 = base64.b64encode(bundle_data).decode("utf-8")
263
+ request_data["bundle"] = bundle_b64
264
+
265
+ # Debug logging
266
+ logger.debug(f"Sending verifier execute request: key={key}, sha256={bundle_sha[:8]}..., function_name={function_name}")
267
+ logger.debug(f"Request has bundle: {needs_upload}")
268
+ logger.debug(f"Using client with base_url: {client.base_url}")
269
+ logger.debug(f"Request data keys: {list(request_data.keys())}")
270
+ logger.debug(f"Bundle size: {len(request_data.get('bundle', ''))} chars" if 'bundle' in request_data else "No bundle")
271
+
272
+ # Note: This should be called on the instance URL, not the orchestrator
273
+ # The instance has manager URLs for verifier execution
274
+ response = await client.request("POST", "/v1/verifiers/execute", json=request_data)
275
+
276
+ # Debug the response
277
+ response_json = response.json()
278
+ logger.debug(f"Verifier execute response: {response_json}")
279
+
280
+ return VerifiersExecuteResponse(**response_json)
@@ -1,9 +1,9 @@
1
- from ..client import AsyncFleet, AsyncEnvironment
1
+ from ..client import AsyncFleet, AsyncEnv
2
2
  from ...models import Environment as EnvironmentModel
3
3
  from typing import List, Optional
4
4
 
5
5
 
6
- async def make_async(env_key: str, region: Optional[str] = None) -> AsyncEnvironment:
6
+ async def make_async(env_key: str, region: Optional[str] = None) -> AsyncEnv:
7
7
  return await AsyncFleet().make(env_key, region=region)
8
8
 
9
9
 
@@ -17,9 +17,9 @@ async def list_regions_async() -> List[str]:
17
17
 
18
18
  async def list_instances_async(
19
19
  status: Optional[str] = None, region: Optional[str] = None
20
- ) -> List[AsyncEnvironment]:
20
+ ) -> List[AsyncEnv]:
21
21
  return await AsyncFleet().instances(status=status, region=region)
22
22
 
23
23
 
24
- async def get_async(instance_id: str) -> AsyncEnvironment:
24
+ async def get_async(instance_id: str) -> AsyncEnv:
25
25
  return await AsyncFleet().instance(instance_id)
@@ -12,7 +12,6 @@ from ...instance.models import (
12
12
  )
13
13
 
14
14
  __all__ = [
15
- "ValidatorType",
16
15
  "AsyncInstanceClient",
17
16
  "ResetRequest",
18
17
  "ResetResponse",
@@ -20,5 +19,5 @@ __all__ = [
20
19
  "ChromeStartRequest",
21
20
  "ChromeStartResponse",
22
21
  "ChromeStatusResponse",
23
- "ExecuteFunctionResponse"
22
+ "ExecuteFunctionResponse",
24
23
  ]
@@ -51,7 +51,8 @@ class AsyncInstanceClient:
51
51
  self.base_url = url
52
52
  self.client = AsyncWrapper(
53
53
  url=self.base_url,
54
- httpx_client=httpx_client or default_httpx_client(DEFAULT_MAX_RETRIES, DEFAULT_TIMEOUT),
54
+ httpx_client=httpx_client
55
+ or default_httpx_client(DEFAULT_MAX_RETRIES, DEFAULT_TIMEOUT),
55
56
  )
56
57
  self._resources: Optional[List[ResourceModel]] = None
57
58
  self._resources_state: Dict[str, Dict[str, Resource]] = {
@@ -136,7 +137,7 @@ class AsyncInstanceClient:
136
137
 
137
138
  self._resources = [ResourceModel(**resource) for resource in resources_list]
138
139
  for resource in self._resources:
139
- if resource.type not in self._resources_state:
140
+ if resource.type.value not in self._resources_state:
140
141
  self._resources_state[resource.type.value] = {}
141
142
  self._resources_state[resource.type.value][resource.name] = (
142
143
  RESOURCE_TYPES[resource.type](resource, self.client)
@@ -1,7 +1,7 @@
1
1
  import base64
2
2
  from typing import List, Dict, Any
3
3
  from playwright.async_api import async_playwright, Browser, Page
4
- from .client import AsyncEnvironment
4
+ from .client import AsyncEnv
5
5
 
6
6
 
7
7
  # Key mapping for computer use actions
@@ -65,7 +65,7 @@ class AsyncFleetPlaywrightWrapper:
65
65
 
66
66
  def __init__(
67
67
  self,
68
- env: AsyncEnvironment,
68
+ env: AsyncEnv,
69
69
  display_width: int = 1920,
70
70
  display_height: int = 1080,
71
71
  ):