fleet-python 0.2.122__tar.gz → 0.2.124__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.
- fleet_python-0.2.124/PKG-INFO +145 -0
- fleet_python-0.2.124/README.md +95 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/examples/example_task.py +1 -1
- {fleet_python-0.2.122 → fleet_python-0.2.124}/examples/export_tasks.py +10 -32
- fleet_python-0.2.124/examples/export_tasks_filtered.py +245 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/examples/import_tasks.py +49 -1
- {fleet_python-0.2.122 → fleet_python-0.2.124}/examples/iterate_verifiers.py +2 -2
- fleet_python-0.2.124/examples/task_bundle_editing/download_task.py +276 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/examples/task_bundle_editing/upload_task.py +159 -86
- {fleet_python-0.2.122 → fleet_python-0.2.124}/examples/task_bundle_editing/validate_task.py +124 -55
- {fleet_python-0.2.122 → fleet_python-0.2.124}/fleet/__init__.py +16 -1
- {fleet_python-0.2.122 → fleet_python-0.2.124}/fleet/_async/__init__.py +2 -2
- {fleet_python-0.2.122 → fleet_python-0.2.124}/fleet/_async/base.py +8 -3
- {fleet_python-0.2.122 → fleet_python-0.2.124}/fleet/_async/client.py +111 -128
- {fleet_python-0.2.122 → fleet_python-0.2.124}/fleet/_async/instance/client.py +14 -0
- fleet_python-0.2.124/fleet/_async/judge.py +159 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/fleet/_async/models.py +3 -55
- fleet_python-0.2.124/fleet/_async/resources/filesystem.py +378 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/fleet/_async/resources/sqlite.py +9 -4
- {fleet_python-0.2.122 → fleet_python-0.2.124}/fleet/_async/tasks.py +21 -74
- {fleet_python-0.2.122 → fleet_python-0.2.124}/fleet/agent/gemini_cua/agent.py +159 -377
- {fleet_python-0.2.122 → fleet_python-0.2.124}/fleet/base.py +13 -21
- {fleet_python-0.2.122 → fleet_python-0.2.124}/fleet/cli.py +9 -160
- {fleet_python-0.2.122 → fleet_python-0.2.124}/fleet/client.py +105 -126
- {fleet_python-0.2.122 → fleet_python-0.2.124}/fleet/instance/client.py +14 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/fleet/instance/models.py +75 -0
- fleet_python-0.2.124/fleet/judge.py +1020 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/fleet/models.py +4 -69
- fleet_python-0.2.124/fleet/resources/filesystem.py +378 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/fleet/resources/sqlite.py +12 -7
- {fleet_python-0.2.122 → fleet_python-0.2.124}/fleet/tasks.py +17 -66
- {fleet_python-0.2.122 → fleet_python-0.2.124}/fleet/verifiers/__init__.py +4 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/fleet/verifiers/db.py +429 -0
- fleet_python-0.2.124/fleet/verifiers/local_executor.py +371 -0
- fleet_python-0.2.124/fleet_python.egg-info/PKG-INFO +145 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/fleet_python.egg-info/SOURCES.txt +7 -14
- {fleet_python-0.2.122 → fleet_python-0.2.124}/fleet_python.egg-info/requires.txt +0 -1
- {fleet_python-0.2.122 → fleet_python-0.2.124}/pyproject.toml +1 -7
- {fleet_python-0.2.122 → fleet_python-0.2.124}/tests/test_expect_only.py +15 -15
- fleet_python-0.2.124/tests/test_judge_criteria_markers.py +192 -0
- fleet_python-0.2.122/PKG-INFO +0 -336
- fleet_python-0.2.122/README.md +0 -285
- fleet_python-0.2.122/examples/task_bundle_editing/download_task.py +0 -178
- fleet_python-0.2.122/fleet/_supabase.py +0 -6
- fleet_python-0.2.122/fleet/auth.py +0 -101
- fleet_python-0.2.122/fleet/track/__init__.py +0 -1
- fleet_python-0.2.122/fleet/track/api.py +0 -101
- fleet_python-0.2.122/fleet/track/cli.py +0 -171
- fleet_python-0.2.122/fleet/track/daemon.py +0 -338
- fleet_python-0.2.122/fleet/track/install.py +0 -157
- fleet_python-0.2.122/fleet/track/merkle.py +0 -167
- fleet_python-0.2.122/fleet/track/queue.py +0 -206
- fleet_python-0.2.122/fleet/track/scrubber.py +0 -60
- fleet_python-0.2.122/fleet/track/sources.py +0 -95
- fleet_python-0.2.122/fleet/track/status.py +0 -83
- fleet_python-0.2.122/fleet/track/uploader.py +0 -121
- fleet_python-0.2.122/fleet/track/watcher.py +0 -108
- fleet_python-0.2.122/fleet_python.egg-info/PKG-INFO +0 -336
- {fleet_python-0.2.122 → fleet_python-0.2.124}/LICENSE +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/examples/diff_example.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/examples/dsl_example.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/examples/example.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/examples/exampleResume.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/examples/example_account.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/examples/example_action_log.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/examples/example_client.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/examples/example_mcp_anthropic.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/examples/example_mcp_openai.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/examples/example_sync.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/examples/example_tasks.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/examples/example_verifier.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/examples/fetch_tasks.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/examples/gemini_example.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/examples/json_tasks_example.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/examples/nova_act_example.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/examples/openai_example.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/examples/openai_simple_example.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/examples/query_builder_example.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/examples/quickstart.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/examples/task_bundle_editing/launch_job.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/examples/test_cdp_logging.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/fleet/_async/env/__init__.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/fleet/_async/env/client.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/fleet/_async/exceptions.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/fleet/_async/global_client.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/fleet/_async/instance/__init__.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/fleet/_async/instance/base.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/fleet/_async/resources/__init__.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/fleet/_async/resources/api.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/fleet/_async/resources/base.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/fleet/_async/resources/browser.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/fleet/_async/resources/mcp.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/fleet/_async/verifiers/__init__.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/fleet/_async/verifiers/bundler.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/fleet/_async/verifiers/verifier.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/fleet/agent/__init__.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/fleet/agent/gemini_cua/Dockerfile +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/fleet/agent/gemini_cua/__init__.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/fleet/agent/gemini_cua/mcp/main.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/fleet/agent/gemini_cua/mcp_server/__init__.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/fleet/agent/gemini_cua/mcp_server/main.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/fleet/agent/gemini_cua/mcp_server/tools.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/fleet/agent/gemini_cua/requirements.txt +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/fleet/agent/gemini_cua/start.sh +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/fleet/agent/orchestrator.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/fleet/agent/types.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/fleet/agent/utils.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/fleet/config.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/fleet/env/__init__.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/fleet/env/client.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/fleet/eval/__init__.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/fleet/eval/uploader.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/fleet/exceptions.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/fleet/global_client.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/fleet/instance/__init__.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/fleet/instance/base.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/fleet/proxy/__init__.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/fleet/proxy/proxy.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/fleet/proxy/whitelist.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/fleet/resources/__init__.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/fleet/resources/api.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/fleet/resources/base.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/fleet/resources/browser.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/fleet/resources/mcp.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/fleet/types.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/fleet/utils/__init__.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/fleet/utils/http_logging.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/fleet/utils/logging.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/fleet/utils/playwright.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/fleet/verifiers/bundler.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/fleet/verifiers/code.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/fleet/verifiers/decorator.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/fleet/verifiers/parse.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/fleet/verifiers/sql_differ.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/fleet/verifiers/verifier.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/fleet_python.egg-info/dependency_links.txt +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/fleet_python.egg-info/entry_points.txt +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/fleet_python.egg-info/top_level.txt +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/scripts/fix_sync_imports.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/scripts/unasync.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/setup.cfg +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/tests/__init__.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/tests/test_app_method.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/tests/test_expect_exactly.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/tests/test_instance_dispatch.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/tests/test_sqlite_resource_dual_mode.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/tests/test_sqlite_shared_memory_behavior.py +0 -0
- {fleet_python-0.2.122 → fleet_python-0.2.124}/tests/test_verifier_from_string.py +0 -0
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: fleet-python
|
|
3
|
+
Version: 0.2.124
|
|
4
|
+
Summary: Python SDK for Fleet environments
|
|
5
|
+
Author-email: Fleet AI <nic@fleet.so>
|
|
6
|
+
License: Apache-2.0
|
|
7
|
+
Project-URL: Homepage, https://fleetai.com
|
|
8
|
+
Project-URL: Documentation, https://docs.fleetai.com
|
|
9
|
+
Project-URL: Repository, https://github.com/fleet-ai/fleet-sdk
|
|
10
|
+
Project-URL: Issues, https://github.com/fleet-ai/fleet-sdk/issues
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Requires-Python: >=3.9
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
License-File: LICENSE
|
|
22
|
+
Requires-Dist: aiohttp>=3.8.0
|
|
23
|
+
Requires-Dist: pydantic>=2.0.0
|
|
24
|
+
Requires-Dist: httpx>=0.27.0
|
|
25
|
+
Requires-Dist: httpx-retries>=0.4.0
|
|
26
|
+
Requires-Dist: typing-extensions>=4.0.0
|
|
27
|
+
Requires-Dist: modulegraph2>=0.2.0
|
|
28
|
+
Requires-Dist: cloudpickle==3.1.1
|
|
29
|
+
Provides-Extra: cli
|
|
30
|
+
Requires-Dist: typer>=0.9.0; extra == "cli"
|
|
31
|
+
Requires-Dist: rich>=10.0.0; extra == "cli"
|
|
32
|
+
Provides-Extra: dev
|
|
33
|
+
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
34
|
+
Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
|
|
35
|
+
Requires-Dist: black>=22.0.0; extra == "dev"
|
|
36
|
+
Requires-Dist: isort>=5.0.0; extra == "dev"
|
|
37
|
+
Requires-Dist: mypy>=1.0.0; extra == "dev"
|
|
38
|
+
Requires-Dist: ruff>=0.1.0; extra == "dev"
|
|
39
|
+
Requires-Dist: unasync>=0.6.0; extra == "dev"
|
|
40
|
+
Requires-Dist: python-dotenv>=1.1.1; extra == "dev"
|
|
41
|
+
Requires-Dist: typer>=0.9.0; extra == "dev"
|
|
42
|
+
Requires-Dist: rich>=10.0.0; extra == "dev"
|
|
43
|
+
Provides-Extra: playwright
|
|
44
|
+
Requires-Dist: playwright>=1.40.0; extra == "playwright"
|
|
45
|
+
Provides-Extra: eval
|
|
46
|
+
Requires-Dist: aiohttp>=3.9.0; extra == "eval"
|
|
47
|
+
Requires-Dist: google-genai>=1.0.0; extra == "eval"
|
|
48
|
+
Requires-Dist: mcp==1.24.0; python_version >= "3.10" and extra == "eval"
|
|
49
|
+
Dynamic: license-file
|
|
50
|
+
|
|
51
|
+
# Fleet SDK
|
|
52
|
+
|
|
53
|
+
[](https://pypi.org/project/fleet-python/)
|
|
54
|
+
[](https://pypi.org/project/fleet-python/)
|
|
55
|
+
[](https://pypi.org/project/fleet-python/)
|
|
56
|
+
|
|
57
|
+
The Fleet Python SDK provides programmatic access to Fleet's environment infrastructure.
|
|
58
|
+
|
|
59
|
+
## Installation
|
|
60
|
+
|
|
61
|
+
Install the Fleet SDK using pip:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
pip install fleet-python
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Alpha/Pre-release Versions
|
|
68
|
+
|
|
69
|
+
To install the latest alpha or pre-release version:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
pip install --pre fleet-python
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
To install a specific alpha version:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
pip install fleet-python==0.2.64-alpha1
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## API Key Setup
|
|
82
|
+
|
|
83
|
+
Fleet requires an API key for authentication. You can obtain one from the [Fleet Platform](https://fleetai.com/dashboard/api-keys).
|
|
84
|
+
|
|
85
|
+
Set your API key as an environment variable:
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
export FLEET_API_KEY="sk_your_key_here"
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Basic Usage
|
|
92
|
+
|
|
93
|
+
```python
|
|
94
|
+
import fleet
|
|
95
|
+
import datetime
|
|
96
|
+
|
|
97
|
+
# Create environment by key
|
|
98
|
+
env = fleet.env.make("fira")
|
|
99
|
+
|
|
100
|
+
# Reset environment with seed and options
|
|
101
|
+
env.reset(
|
|
102
|
+
seed=42,
|
|
103
|
+
timestamp=int(datetime.datetime.now().timestamp())
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
# Access environment state ('current' is the resource id for a sqlite database)
|
|
107
|
+
sql = env.state("sqlite://current")
|
|
108
|
+
sql.exec("UPDATE customers SET status = 'active' WHERE id = 123")
|
|
109
|
+
|
|
110
|
+
# Clean up
|
|
111
|
+
env.close()
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## Environment Management
|
|
115
|
+
|
|
116
|
+
### Creating Instances
|
|
117
|
+
|
|
118
|
+
```python
|
|
119
|
+
# Create environment instance with explicit version
|
|
120
|
+
env = fleet.env.make("fira:v1.2.5")
|
|
121
|
+
|
|
122
|
+
# Create environment instance with default (latest) version
|
|
123
|
+
env = fleet.env.make("fira")
|
|
124
|
+
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### Connecting to Existing Instances
|
|
128
|
+
|
|
129
|
+
```python
|
|
130
|
+
# Connect to a running instance
|
|
131
|
+
env = fleet.env.get("env_instance_id")
|
|
132
|
+
|
|
133
|
+
# List all running instances
|
|
134
|
+
instances = fleet.env.list_instances()
|
|
135
|
+
for instance in instances:
|
|
136
|
+
print(f"Instance: {instance.instance_id}")
|
|
137
|
+
print(f"Type: {instance.environment_type}")
|
|
138
|
+
print(f"Status: {instance.status}")
|
|
139
|
+
|
|
140
|
+
# Filter instances by status (running, pending, stopped, error)
|
|
141
|
+
running_instances = fleet.env.list_instances(status_filter="running")
|
|
142
|
+
|
|
143
|
+
# List available environment types
|
|
144
|
+
available_envs = fleet.env.list_envs()
|
|
145
|
+
```
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# Fleet SDK
|
|
2
|
+
|
|
3
|
+
[](https://pypi.org/project/fleet-python/)
|
|
4
|
+
[](https://pypi.org/project/fleet-python/)
|
|
5
|
+
[](https://pypi.org/project/fleet-python/)
|
|
6
|
+
|
|
7
|
+
The Fleet Python SDK provides programmatic access to Fleet's environment infrastructure.
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
Install the Fleet SDK using pip:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
pip install fleet-python
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
### Alpha/Pre-release Versions
|
|
18
|
+
|
|
19
|
+
To install the latest alpha or pre-release version:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
pip install --pre fleet-python
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
To install a specific alpha version:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
pip install fleet-python==0.2.64-alpha1
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## API Key Setup
|
|
32
|
+
|
|
33
|
+
Fleet requires an API key for authentication. You can obtain one from the [Fleet Platform](https://fleetai.com/dashboard/api-keys).
|
|
34
|
+
|
|
35
|
+
Set your API key as an environment variable:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
export FLEET_API_KEY="sk_your_key_here"
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Basic Usage
|
|
42
|
+
|
|
43
|
+
```python
|
|
44
|
+
import fleet
|
|
45
|
+
import datetime
|
|
46
|
+
|
|
47
|
+
# Create environment by key
|
|
48
|
+
env = fleet.env.make("fira")
|
|
49
|
+
|
|
50
|
+
# Reset environment with seed and options
|
|
51
|
+
env.reset(
|
|
52
|
+
seed=42,
|
|
53
|
+
timestamp=int(datetime.datetime.now().timestamp())
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
# Access environment state ('current' is the resource id for a sqlite database)
|
|
57
|
+
sql = env.state("sqlite://current")
|
|
58
|
+
sql.exec("UPDATE customers SET status = 'active' WHERE id = 123")
|
|
59
|
+
|
|
60
|
+
# Clean up
|
|
61
|
+
env.close()
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Environment Management
|
|
65
|
+
|
|
66
|
+
### Creating Instances
|
|
67
|
+
|
|
68
|
+
```python
|
|
69
|
+
# Create environment instance with explicit version
|
|
70
|
+
env = fleet.env.make("fira:v1.2.5")
|
|
71
|
+
|
|
72
|
+
# Create environment instance with default (latest) version
|
|
73
|
+
env = fleet.env.make("fira")
|
|
74
|
+
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Connecting to Existing Instances
|
|
78
|
+
|
|
79
|
+
```python
|
|
80
|
+
# Connect to a running instance
|
|
81
|
+
env = fleet.env.get("env_instance_id")
|
|
82
|
+
|
|
83
|
+
# List all running instances
|
|
84
|
+
instances = fleet.env.list_instances()
|
|
85
|
+
for instance in instances:
|
|
86
|
+
print(f"Instance: {instance.instance_id}")
|
|
87
|
+
print(f"Type: {instance.environment_type}")
|
|
88
|
+
print(f"Status: {instance.status}")
|
|
89
|
+
|
|
90
|
+
# Filter instances by status (running, pending, stopped, error)
|
|
91
|
+
running_instances = fleet.env.list_instances(status_filter="running")
|
|
92
|
+
|
|
93
|
+
# List available environment types
|
|
94
|
+
available_envs = fleet.env.list_envs()
|
|
95
|
+
```
|
|
@@ -112,7 +112,7 @@ async def main():
|
|
|
112
112
|
print(f"Task definition:")
|
|
113
113
|
print(f" Key: {task.key}")
|
|
114
114
|
print(f" Prompt: {task.prompt}")
|
|
115
|
-
print(f" Environment: {task.
|
|
115
|
+
print(f" Environment: {task.env_id}")
|
|
116
116
|
print(
|
|
117
117
|
f" Verifier: {task.verifier.key if hasattr(task.verifier, 'key') else 'create_bug_issue'}"
|
|
118
118
|
)
|
|
@@ -38,12 +38,6 @@ def main():
|
|
|
38
38
|
help="Output JSON filename (defaults to {team_id}.json)",
|
|
39
39
|
default=None,
|
|
40
40
|
)
|
|
41
|
-
parser.add_argument(
|
|
42
|
-
"--skip-missing-verifiers",
|
|
43
|
-
"-s",
|
|
44
|
-
action="store_true",
|
|
45
|
-
help="Skip tasks missing verifier_func instead of erroring",
|
|
46
|
-
)
|
|
47
41
|
|
|
48
42
|
args = parser.parse_args()
|
|
49
43
|
|
|
@@ -97,32 +91,16 @@ def main():
|
|
|
97
91
|
missing_verifier.append(task.key)
|
|
98
92
|
|
|
99
93
|
if missing_verifier:
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
print(f"\n{len(tasks)} task(s) remaining after filtering")
|
|
111
|
-
if not tasks:
|
|
112
|
-
raise ValueError(
|
|
113
|
-
"No tasks remaining after filtering. Nothing to export."
|
|
114
|
-
)
|
|
115
|
-
else:
|
|
116
|
-
print(f"\n✗ Error: {len(missing_verifier)} task(s) missing verifier_func:")
|
|
117
|
-
for key in missing_verifier[:10]: # Show first 10
|
|
118
|
-
print(f" - {key}")
|
|
119
|
-
if len(missing_verifier) > 10:
|
|
120
|
-
print(f" ... and {len(missing_verifier) - 10} more")
|
|
121
|
-
raise ValueError(
|
|
122
|
-
"All tasks must have a verifier_func. Cannot export tasks without verifiers."
|
|
123
|
-
)
|
|
124
|
-
else:
|
|
125
|
-
print("✓ All tasks have verifier_func")
|
|
94
|
+
print(f"\n✗ Error: {len(missing_verifier)} task(s) missing verifier_func:")
|
|
95
|
+
for key in missing_verifier[:10]: # Show first 10
|
|
96
|
+
print(f" - {key}")
|
|
97
|
+
if len(missing_verifier) > 10:
|
|
98
|
+
print(f" ... and {len(missing_verifier) - 10} more")
|
|
99
|
+
raise ValueError(
|
|
100
|
+
"All tasks must have a verifier_func. Cannot export tasks without verifiers."
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
print("✓ All tasks have verifier_func")
|
|
126
104
|
|
|
127
105
|
# Determine output filename
|
|
128
106
|
output_file = args.output or f"{account.team_id}.json"
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Export tasks to JSON, excluding tasks from targets marked as 'unused'.
|
|
3
|
+
|
|
4
|
+
This script filters out tasks whose task_project_target has status='unused',
|
|
5
|
+
ensuring that broken/invalid targets don't pollute exports.
|
|
6
|
+
|
|
7
|
+
Usage:
|
|
8
|
+
python export_tasks_filtered.py --task-project-key my-project
|
|
9
|
+
python export_tasks_filtered.py --project-key my-project --output tasks.json
|
|
10
|
+
python export_tasks_filtered.py --env-key my-env
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
import argparse
|
|
14
|
+
import json
|
|
15
|
+
import os
|
|
16
|
+
from typing import List, Set
|
|
17
|
+
|
|
18
|
+
import fleet
|
|
19
|
+
from dotenv import load_dotenv
|
|
20
|
+
from supabase import create_client, Client
|
|
21
|
+
|
|
22
|
+
load_dotenv()
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def get_unused_target_ids(supabase: Client, team_id: str) -> Set[str]:
|
|
26
|
+
"""Fetch all target IDs that have status='unused' for the given team."""
|
|
27
|
+
# Get all task_projects for this team first
|
|
28
|
+
projects_response = (
|
|
29
|
+
supabase.table("task_projects")
|
|
30
|
+
.select("id")
|
|
31
|
+
.eq("team_id", team_id)
|
|
32
|
+
.execute()
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
if not projects_response.data:
|
|
36
|
+
return set()
|
|
37
|
+
|
|
38
|
+
project_ids = [p["id"] for p in projects_response.data]
|
|
39
|
+
|
|
40
|
+
# Get all targets with status='unused' for these projects
|
|
41
|
+
targets_response = (
|
|
42
|
+
supabase.table("task_project_targets")
|
|
43
|
+
.select("id")
|
|
44
|
+
.in_("project_id", project_ids)
|
|
45
|
+
.eq("status", "unused")
|
|
46
|
+
.execute()
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
if not targets_response.data:
|
|
50
|
+
return set()
|
|
51
|
+
|
|
52
|
+
return {t["id"] for t in targets_response.data}
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def get_task_target_mapping(supabase: Client, task_keys: List[str], team_id: str) -> dict:
|
|
56
|
+
"""Fetch task_project_target_id for each task key."""
|
|
57
|
+
if not task_keys:
|
|
58
|
+
return {}
|
|
59
|
+
|
|
60
|
+
# Batch the queries to avoid hitting limits
|
|
61
|
+
BATCH_SIZE = 100
|
|
62
|
+
mapping = {}
|
|
63
|
+
|
|
64
|
+
for i in range(0, len(task_keys), BATCH_SIZE):
|
|
65
|
+
batch_keys = task_keys[i:i + BATCH_SIZE]
|
|
66
|
+
response = (
|
|
67
|
+
supabase.table("eval_tasks")
|
|
68
|
+
.select("key, task_project_target_id")
|
|
69
|
+
.in_("key", batch_keys)
|
|
70
|
+
.eq("team_id", team_id)
|
|
71
|
+
.execute()
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
for row in response.data or []:
|
|
75
|
+
mapping[row["key"]] = row.get("task_project_target_id")
|
|
76
|
+
|
|
77
|
+
return mapping
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def main():
|
|
81
|
+
parser = argparse.ArgumentParser(
|
|
82
|
+
description="Export tasks to JSON, excluding tasks from 'unused' targets"
|
|
83
|
+
)
|
|
84
|
+
parser.add_argument(
|
|
85
|
+
"--project-key",
|
|
86
|
+
"-p",
|
|
87
|
+
help="Optional project key to filter tasks",
|
|
88
|
+
default=None,
|
|
89
|
+
)
|
|
90
|
+
parser.add_argument(
|
|
91
|
+
"--task-keys",
|
|
92
|
+
"-t",
|
|
93
|
+
nargs="+",
|
|
94
|
+
help="Optional list of task keys to export (space-separated)",
|
|
95
|
+
default=None,
|
|
96
|
+
)
|
|
97
|
+
parser.add_argument(
|
|
98
|
+
"--task-project-key",
|
|
99
|
+
"-tpk",
|
|
100
|
+
help="Optional task project key to filter tasks",
|
|
101
|
+
default=None,
|
|
102
|
+
)
|
|
103
|
+
parser.add_argument(
|
|
104
|
+
"--env-key",
|
|
105
|
+
"-e",
|
|
106
|
+
help="Optional environment key to filter tasks",
|
|
107
|
+
default=None,
|
|
108
|
+
)
|
|
109
|
+
parser.add_argument(
|
|
110
|
+
"--output",
|
|
111
|
+
"-o",
|
|
112
|
+
help="Output JSON filename (defaults to {team_id}_filtered.json)",
|
|
113
|
+
default=None,
|
|
114
|
+
)
|
|
115
|
+
parser.add_argument(
|
|
116
|
+
"--include-unused",
|
|
117
|
+
action="store_true",
|
|
118
|
+
help="Include tasks from 'unused' targets (disables filtering)",
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
args = parser.parse_args()
|
|
122
|
+
|
|
123
|
+
# Validate that only one filter is specified
|
|
124
|
+
filters_specified = sum(
|
|
125
|
+
[
|
|
126
|
+
args.project_key is not None,
|
|
127
|
+
args.task_keys is not None,
|
|
128
|
+
args.task_project_key is not None,
|
|
129
|
+
args.env_key is not None,
|
|
130
|
+
]
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
if filters_specified > 1:
|
|
134
|
+
parser.error(
|
|
135
|
+
"Cannot specify multiple filters. Use only one of --project-key, --task-keys, --task-project-key, or --env-key."
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
# Get account info
|
|
139
|
+
account = fleet.env.account()
|
|
140
|
+
print(f"Exporting from team: {account.team_name}")
|
|
141
|
+
|
|
142
|
+
# Initialize Supabase client for filtering
|
|
143
|
+
supabase_url = os.getenv("SUPABASE_URL") or os.getenv("NEXT_PUBLIC_SUPABASE_URL")
|
|
144
|
+
supabase_key = os.getenv("SUPABASE_SERVICE_ROLE_KEY") or os.getenv("SUPABASE_KEY")
|
|
145
|
+
|
|
146
|
+
if not supabase_url or not supabase_key:
|
|
147
|
+
print("⚠ Warning: SUPABASE_URL/SUPABASE_KEY not set - cannot filter by target status")
|
|
148
|
+
print(" Falling back to unfiltered export")
|
|
149
|
+
supabase = None
|
|
150
|
+
else:
|
|
151
|
+
supabase = create_client(supabase_url, supabase_key)
|
|
152
|
+
|
|
153
|
+
# Load tasks
|
|
154
|
+
if args.project_key:
|
|
155
|
+
print(f"Loading tasks from project: {args.project_key}")
|
|
156
|
+
tasks = fleet.load_tasks(project_key=args.project_key)
|
|
157
|
+
elif args.task_keys:
|
|
158
|
+
print(f"Loading {len(args.task_keys)} specific task(s): {', '.join(args.task_keys)}")
|
|
159
|
+
tasks = fleet.load_tasks(keys=args.task_keys)
|
|
160
|
+
elif args.task_project_key:
|
|
161
|
+
print(f"Loading tasks from task project: {args.task_project_key}")
|
|
162
|
+
tasks = fleet.load_tasks(task_project_key=args.task_project_key)
|
|
163
|
+
elif args.env_key:
|
|
164
|
+
print(f"Loading tasks from environment: {args.env_key}")
|
|
165
|
+
tasks = fleet.load_tasks(env_key=args.env_key)
|
|
166
|
+
else:
|
|
167
|
+
print("Loading all tasks")
|
|
168
|
+
tasks = fleet.load_tasks()
|
|
169
|
+
|
|
170
|
+
print(f"\nFound {len(tasks)} task(s) before filtering")
|
|
171
|
+
|
|
172
|
+
# Filter out tasks from unused targets
|
|
173
|
+
filtered_tasks = tasks
|
|
174
|
+
excluded_count = 0
|
|
175
|
+
|
|
176
|
+
if supabase and not args.include_unused:
|
|
177
|
+
print("\nFiltering out tasks from 'unused' targets...")
|
|
178
|
+
|
|
179
|
+
# Get unused target IDs
|
|
180
|
+
unused_target_ids = get_unused_target_ids(supabase, account.team_id)
|
|
181
|
+
|
|
182
|
+
if unused_target_ids:
|
|
183
|
+
print(f" Found {len(unused_target_ids)} unused target(s)")
|
|
184
|
+
|
|
185
|
+
# Get task -> target mapping
|
|
186
|
+
task_keys = [t.key for t in tasks]
|
|
187
|
+
task_target_map = get_task_target_mapping(supabase, task_keys, account.team_id)
|
|
188
|
+
|
|
189
|
+
# Filter tasks
|
|
190
|
+
filtered_tasks = []
|
|
191
|
+
for task in tasks:
|
|
192
|
+
target_id = task_target_map.get(task.key)
|
|
193
|
+
if target_id in unused_target_ids:
|
|
194
|
+
excluded_count += 1
|
|
195
|
+
else:
|
|
196
|
+
filtered_tasks.append(task)
|
|
197
|
+
|
|
198
|
+
print(f" Excluded {excluded_count} task(s) from unused targets")
|
|
199
|
+
else:
|
|
200
|
+
print(" No unused targets found - all tasks included")
|
|
201
|
+
|
|
202
|
+
tasks = filtered_tasks
|
|
203
|
+
print(f"\n{len(tasks)} task(s) after filtering")
|
|
204
|
+
|
|
205
|
+
# Validate that all tasks have verifier_func
|
|
206
|
+
print("\nValidating tasks have verifier_func...")
|
|
207
|
+
missing_verifier = []
|
|
208
|
+
for task in tasks:
|
|
209
|
+
if not task.verifier_func:
|
|
210
|
+
missing_verifier.append(task.key)
|
|
211
|
+
|
|
212
|
+
if missing_verifier:
|
|
213
|
+
print(f"\n✗ Error: {len(missing_verifier)} task(s) missing verifier_func:")
|
|
214
|
+
for key in missing_verifier[:10]: # Show first 10
|
|
215
|
+
print(f" - {key}")
|
|
216
|
+
if len(missing_verifier) > 10:
|
|
217
|
+
print(f" ... and {len(missing_verifier) - 10} more")
|
|
218
|
+
raise ValueError(
|
|
219
|
+
"All tasks must have a verifier_func. Cannot export tasks without verifiers."
|
|
220
|
+
)
|
|
221
|
+
|
|
222
|
+
print("✓ All tasks have verifier_func")
|
|
223
|
+
|
|
224
|
+
# Determine output filename
|
|
225
|
+
output_file = args.output or f"{account.team_id}_filtered.json"
|
|
226
|
+
|
|
227
|
+
# Export to JSON
|
|
228
|
+
print(f"\nExporting to: {output_file}")
|
|
229
|
+
with open(output_file, "w", encoding="utf-8") as f:
|
|
230
|
+
json.dump(
|
|
231
|
+
[task.model_dump() for task in tasks],
|
|
232
|
+
f,
|
|
233
|
+
indent=2,
|
|
234
|
+
ensure_ascii=False,
|
|
235
|
+
)
|
|
236
|
+
|
|
237
|
+
print(f"✓ Successfully exported {len(tasks)} task(s) to {output_file}")
|
|
238
|
+
if excluded_count > 0:
|
|
239
|
+
print(f" ({excluded_count} task(s) excluded from unused targets)")
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
if __name__ == "__main__":
|
|
243
|
+
main()
|
|
244
|
+
|
|
245
|
+
|
|
@@ -35,7 +35,7 @@ async def run_verifier_sanity_check(
|
|
|
35
35
|
instance_groups = defaultdict(list)
|
|
36
36
|
for task in tasks:
|
|
37
37
|
# Build the instance key
|
|
38
|
-
env_key = task.
|
|
38
|
+
env_key = task.env_id or ""
|
|
39
39
|
env_version = task.version or ""
|
|
40
40
|
data_key = task.data_id or ""
|
|
41
41
|
data_version = task.data_version or ""
|
|
@@ -238,6 +238,7 @@ async def main():
|
|
|
238
238
|
task_count = len(tasks_data)
|
|
239
239
|
task_keys = []
|
|
240
240
|
missing_verifier = []
|
|
241
|
+
tasks_with_output_schema = []
|
|
241
242
|
for task_data in tasks_data:
|
|
242
243
|
task_key = task_data.get("key") or task_data.get("id")
|
|
243
244
|
if task_key:
|
|
@@ -250,6 +251,10 @@ async def main():
|
|
|
250
251
|
if not verifier_code:
|
|
251
252
|
missing_verifier.append(task_key or "(no key)")
|
|
252
253
|
|
|
254
|
+
# Check for output_json_schema
|
|
255
|
+
if task_data.get("output_json_schema"):
|
|
256
|
+
tasks_with_output_schema.append(task_key or "(no key)")
|
|
257
|
+
|
|
253
258
|
# Validate all tasks have verifier_func
|
|
254
259
|
if missing_verifier:
|
|
255
260
|
print(f"✗ Error: {len(missing_verifier)} task(s) missing verifier_func:")
|
|
@@ -339,6 +344,10 @@ async def main():
|
|
|
339
344
|
tasks = passed_tasks
|
|
340
345
|
passed_keys = {t.key for t in passed_tasks}
|
|
341
346
|
tasks_data = [td for td in tasks_data if td.get("key") in passed_keys]
|
|
347
|
+
# Also filter tasks_with_output_schema
|
|
348
|
+
tasks_with_output_schema = [
|
|
349
|
+
k for k in tasks_with_output_schema if k in passed_keys
|
|
350
|
+
]
|
|
342
351
|
|
|
343
352
|
print(f"\nProceeding with {len(tasks)} tasks that passed sanity check")
|
|
344
353
|
else:
|
|
@@ -388,6 +397,45 @@ async def main():
|
|
|
388
397
|
|
|
389
398
|
print(f"✓ Team: {account.team_name}")
|
|
390
399
|
|
|
400
|
+
# Print HUGE warning if any tasks have output_json_schema
|
|
401
|
+
if tasks_with_output_schema:
|
|
402
|
+
print("\n")
|
|
403
|
+
print("!" * 80)
|
|
404
|
+
print("!" * 80)
|
|
405
|
+
print("!" * 80)
|
|
406
|
+
print(
|
|
407
|
+
"!!! !!!"
|
|
408
|
+
)
|
|
409
|
+
print(
|
|
410
|
+
"!!! ⚠️ WARNING WARNING WARNING ⚠️ !!!"
|
|
411
|
+
)
|
|
412
|
+
print(
|
|
413
|
+
"!!! !!!"
|
|
414
|
+
)
|
|
415
|
+
print(
|
|
416
|
+
f"!!! {len(tasks_with_output_schema)} TASK(S) HAVE OUTPUT_JSON_SCHEMA THAT NEED MANUAL COPYING! !!!"
|
|
417
|
+
)
|
|
418
|
+
print(
|
|
419
|
+
"!!! !!!"
|
|
420
|
+
)
|
|
421
|
+
print(
|
|
422
|
+
"!!! The output_json_schema field is NOT automatically imported! !!!"
|
|
423
|
+
)
|
|
424
|
+
print(
|
|
425
|
+
"!!! You MUST manually copy the output schemas to each task! !!!"
|
|
426
|
+
)
|
|
427
|
+
print(
|
|
428
|
+
"!!! !!!"
|
|
429
|
+
)
|
|
430
|
+
print("!" * 80)
|
|
431
|
+
print("!" * 80)
|
|
432
|
+
print("!" * 80)
|
|
433
|
+
print("\nTasks with output_json_schema:")
|
|
434
|
+
for i, key in enumerate(tasks_with_output_schema[:20], 1):
|
|
435
|
+
print(f" {i}. {key}")
|
|
436
|
+
if len(tasks_with_output_schema) > 20:
|
|
437
|
+
print(f" ... and {len(tasks_with_output_schema) - 20} more")
|
|
438
|
+
print("\n⚠️ REMEMBER TO MANUALLY COPY OUTPUT SCHEMAS! ⚠️\n")
|
|
391
439
|
except Exception as e:
|
|
392
440
|
print(f"\n✗ Error importing tasks: {e}")
|
|
393
441
|
sys.exit(1)
|
|
@@ -677,12 +677,12 @@ def main():
|
|
|
677
677
|
epilog="""
|
|
678
678
|
Examples:
|
|
679
679
|
# Extract verifiers from JSON to Python file
|
|
680
|
-
%(prog)s extract batch.json verifiers.py
|
|
680
|
+
%(prog)s extract xai-day-10-batch.json verifiers.py
|
|
681
681
|
|
|
682
682
|
# Edit verifiers.py...
|
|
683
683
|
|
|
684
684
|
# Apply changes back to JSON file (updates in-place)
|
|
685
|
-
%(prog)s apply batch.json verifiers.py
|
|
685
|
+
%(prog)s apply xai-day-10-batch.json verifiers.py
|
|
686
686
|
|
|
687
687
|
# Validate verifiers file
|
|
688
688
|
%(prog)s validate verifiers.py
|