fleet-python 0.2.121__tar.gz → 0.2.123__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.
Files changed (137) hide show
  1. {fleet_python-0.2.121/fleet_python.egg-info → fleet_python-0.2.123}/PKG-INFO +1 -1
  2. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/__init__.py +1 -1
  3. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/_async/__init__.py +1 -1
  4. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/_async/base.py +1 -1
  5. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/base.py +1 -1
  6. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/track/cli.py +9 -2
  7. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/track/daemon.py +15 -1
  8. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/track/queue.py +14 -0
  9. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/track/uploader.py +4 -2
  10. {fleet_python-0.2.121 → fleet_python-0.2.123/fleet_python.egg-info}/PKG-INFO +1 -1
  11. {fleet_python-0.2.121 → fleet_python-0.2.123}/pyproject.toml +1 -1
  12. {fleet_python-0.2.121 → fleet_python-0.2.123}/LICENSE +0 -0
  13. {fleet_python-0.2.121 → fleet_python-0.2.123}/README.md +0 -0
  14. {fleet_python-0.2.121 → fleet_python-0.2.123}/examples/diff_example.py +0 -0
  15. {fleet_python-0.2.121 → fleet_python-0.2.123}/examples/dsl_example.py +0 -0
  16. {fleet_python-0.2.121 → fleet_python-0.2.123}/examples/example.py +0 -0
  17. {fleet_python-0.2.121 → fleet_python-0.2.123}/examples/exampleResume.py +0 -0
  18. {fleet_python-0.2.121 → fleet_python-0.2.123}/examples/example_account.py +0 -0
  19. {fleet_python-0.2.121 → fleet_python-0.2.123}/examples/example_action_log.py +0 -0
  20. {fleet_python-0.2.121 → fleet_python-0.2.123}/examples/example_client.py +0 -0
  21. {fleet_python-0.2.121 → fleet_python-0.2.123}/examples/example_mcp_anthropic.py +0 -0
  22. {fleet_python-0.2.121 → fleet_python-0.2.123}/examples/example_mcp_openai.py +0 -0
  23. {fleet_python-0.2.121 → fleet_python-0.2.123}/examples/example_sync.py +0 -0
  24. {fleet_python-0.2.121 → fleet_python-0.2.123}/examples/example_task.py +0 -0
  25. {fleet_python-0.2.121 → fleet_python-0.2.123}/examples/example_tasks.py +0 -0
  26. {fleet_python-0.2.121 → fleet_python-0.2.123}/examples/example_verifier.py +0 -0
  27. {fleet_python-0.2.121 → fleet_python-0.2.123}/examples/export_tasks.py +0 -0
  28. {fleet_python-0.2.121 → fleet_python-0.2.123}/examples/fetch_tasks.py +0 -0
  29. {fleet_python-0.2.121 → fleet_python-0.2.123}/examples/gemini_example.py +0 -0
  30. {fleet_python-0.2.121 → fleet_python-0.2.123}/examples/import_tasks.py +0 -0
  31. {fleet_python-0.2.121 → fleet_python-0.2.123}/examples/iterate_verifiers.py +0 -0
  32. {fleet_python-0.2.121 → fleet_python-0.2.123}/examples/json_tasks_example.py +0 -0
  33. {fleet_python-0.2.121 → fleet_python-0.2.123}/examples/nova_act_example.py +0 -0
  34. {fleet_python-0.2.121 → fleet_python-0.2.123}/examples/openai_example.py +0 -0
  35. {fleet_python-0.2.121 → fleet_python-0.2.123}/examples/openai_simple_example.py +0 -0
  36. {fleet_python-0.2.121 → fleet_python-0.2.123}/examples/query_builder_example.py +0 -0
  37. {fleet_python-0.2.121 → fleet_python-0.2.123}/examples/quickstart.py +0 -0
  38. {fleet_python-0.2.121 → fleet_python-0.2.123}/examples/task_bundle_editing/download_task.py +0 -0
  39. {fleet_python-0.2.121 → fleet_python-0.2.123}/examples/task_bundle_editing/launch_job.py +0 -0
  40. {fleet_python-0.2.121 → fleet_python-0.2.123}/examples/task_bundle_editing/upload_task.py +0 -0
  41. {fleet_python-0.2.121 → fleet_python-0.2.123}/examples/task_bundle_editing/validate_task.py +0 -0
  42. {fleet_python-0.2.121 → fleet_python-0.2.123}/examples/test_cdp_logging.py +0 -0
  43. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/_async/client.py +0 -0
  44. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/_async/env/__init__.py +0 -0
  45. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/_async/env/client.py +0 -0
  46. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/_async/exceptions.py +0 -0
  47. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/_async/global_client.py +0 -0
  48. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/_async/instance/__init__.py +0 -0
  49. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/_async/instance/base.py +0 -0
  50. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/_async/instance/client.py +0 -0
  51. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/_async/models.py +0 -0
  52. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/_async/resources/__init__.py +0 -0
  53. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/_async/resources/api.py +0 -0
  54. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/_async/resources/base.py +0 -0
  55. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/_async/resources/browser.py +0 -0
  56. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/_async/resources/mcp.py +0 -0
  57. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/_async/resources/sqlite.py +0 -0
  58. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/_async/tasks.py +0 -0
  59. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/_async/verifiers/__init__.py +0 -0
  60. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/_async/verifiers/bundler.py +0 -0
  61. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/_async/verifiers/verifier.py +0 -0
  62. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/_supabase.py +0 -0
  63. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/agent/__init__.py +0 -0
  64. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/agent/gemini_cua/Dockerfile +0 -0
  65. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/agent/gemini_cua/__init__.py +0 -0
  66. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/agent/gemini_cua/agent.py +0 -0
  67. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/agent/gemini_cua/mcp/main.py +0 -0
  68. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/agent/gemini_cua/mcp_server/__init__.py +0 -0
  69. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/agent/gemini_cua/mcp_server/main.py +0 -0
  70. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/agent/gemini_cua/mcp_server/tools.py +0 -0
  71. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/agent/gemini_cua/requirements.txt +0 -0
  72. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/agent/gemini_cua/start.sh +0 -0
  73. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/agent/orchestrator.py +0 -0
  74. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/agent/types.py +0 -0
  75. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/agent/utils.py +0 -0
  76. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/auth.py +0 -0
  77. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/cli.py +0 -0
  78. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/client.py +0 -0
  79. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/config.py +0 -0
  80. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/env/__init__.py +0 -0
  81. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/env/client.py +0 -0
  82. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/eval/__init__.py +0 -0
  83. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/eval/uploader.py +0 -0
  84. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/exceptions.py +0 -0
  85. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/global_client.py +0 -0
  86. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/instance/__init__.py +0 -0
  87. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/instance/base.py +0 -0
  88. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/instance/client.py +0 -0
  89. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/instance/models.py +0 -0
  90. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/models.py +0 -0
  91. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/proxy/__init__.py +0 -0
  92. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/proxy/proxy.py +0 -0
  93. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/proxy/whitelist.py +0 -0
  94. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/resources/__init__.py +0 -0
  95. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/resources/api.py +0 -0
  96. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/resources/base.py +0 -0
  97. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/resources/browser.py +0 -0
  98. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/resources/mcp.py +0 -0
  99. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/resources/sqlite.py +0 -0
  100. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/tasks.py +0 -0
  101. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/track/__init__.py +0 -0
  102. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/track/api.py +0 -0
  103. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/track/install.py +0 -0
  104. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/track/merkle.py +0 -0
  105. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/track/scrubber.py +0 -0
  106. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/track/sources.py +0 -0
  107. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/track/status.py +0 -0
  108. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/track/watcher.py +0 -0
  109. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/types.py +0 -0
  110. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/utils/__init__.py +0 -0
  111. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/utils/http_logging.py +0 -0
  112. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/utils/logging.py +0 -0
  113. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/utils/playwright.py +0 -0
  114. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/verifiers/__init__.py +0 -0
  115. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/verifiers/bundler.py +0 -0
  116. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/verifiers/code.py +0 -0
  117. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/verifiers/db.py +0 -0
  118. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/verifiers/decorator.py +0 -0
  119. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/verifiers/parse.py +0 -0
  120. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/verifiers/sql_differ.py +0 -0
  121. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet/verifiers/verifier.py +0 -0
  122. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet_python.egg-info/SOURCES.txt +0 -0
  123. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet_python.egg-info/dependency_links.txt +0 -0
  124. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet_python.egg-info/entry_points.txt +0 -0
  125. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet_python.egg-info/requires.txt +0 -0
  126. {fleet_python-0.2.121 → fleet_python-0.2.123}/fleet_python.egg-info/top_level.txt +0 -0
  127. {fleet_python-0.2.121 → fleet_python-0.2.123}/scripts/fix_sync_imports.py +0 -0
  128. {fleet_python-0.2.121 → fleet_python-0.2.123}/scripts/unasync.py +0 -0
  129. {fleet_python-0.2.121 → fleet_python-0.2.123}/setup.cfg +0 -0
  130. {fleet_python-0.2.121 → fleet_python-0.2.123}/tests/__init__.py +0 -0
  131. {fleet_python-0.2.121 → fleet_python-0.2.123}/tests/test_app_method.py +0 -0
  132. {fleet_python-0.2.121 → fleet_python-0.2.123}/tests/test_expect_exactly.py +0 -0
  133. {fleet_python-0.2.121 → fleet_python-0.2.123}/tests/test_expect_only.py +0 -0
  134. {fleet_python-0.2.121 → fleet_python-0.2.123}/tests/test_instance_dispatch.py +0 -0
  135. {fleet_python-0.2.121 → fleet_python-0.2.123}/tests/test_sqlite_resource_dual_mode.py +0 -0
  136. {fleet_python-0.2.121 → fleet_python-0.2.123}/tests/test_sqlite_shared_memory_behavior.py +0 -0
  137. {fleet_python-0.2.121 → fleet_python-0.2.123}/tests/test_verifier_from_string.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fleet-python
3
- Version: 0.2.121
3
+ Version: 0.2.123
4
4
  Summary: Python SDK for Fleet environments
5
5
  Author-email: Fleet AI <nic@fleet.so>
6
6
  License: Apache-2.0
@@ -73,7 +73,7 @@ from . import env
73
73
  from . import global_client as _global_client
74
74
  from ._async import global_client as _async_global_client
75
75
 
76
- __version__ = "0.2.120"
76
+ __version__ = "0.2.122"
77
77
 
78
78
  __all__ = [
79
79
  # Core classes
@@ -44,7 +44,7 @@ from ..types import VerifierFunction
44
44
  from .. import env
45
45
  from . import global_client as _async_global_client
46
46
 
47
- __version__ = "0.2.120"
47
+ __version__ = "0.2.122"
48
48
 
49
49
  __all__ = [
50
50
  # Core classes
@@ -26,7 +26,7 @@ from .exceptions import (
26
26
  try:
27
27
  from .. import __version__
28
28
  except ImportError:
29
- __version__ = "0.2.120"
29
+ __version__ = "0.2.122"
30
30
 
31
31
  logger = logging.getLogger(__name__)
32
32
 
@@ -27,7 +27,7 @@ from .exceptions import (
27
27
  try:
28
28
  from . import __version__
29
29
  except ImportError:
30
- __version__ = "0.2.120"
30
+ __version__ = "0.2.122"
31
31
 
32
32
  logger = logging.getLogger(__name__)
33
33
 
@@ -10,6 +10,7 @@ import typer
10
10
  from rich.console import Console
11
11
  from rich.table import Table
12
12
 
13
+ from ..auth import load_credentials
13
14
  from .api import TrackAPIClient, TrackAPIError
14
15
  from .daemon import main as daemon_main
15
16
  from .install import install, is_installed, uninstall
@@ -55,10 +56,16 @@ def enable() -> None:
55
56
  try:
56
57
  api = TrackAPIClient()
57
58
  result = api.provision(device_id)
58
- config["s3_prefix"] = result.get("s3_prefix", "")
59
- config["s3_bucket"] = result.get("s3_bucket", "fleet-track-sessions")
60
59
  config["team_id"] = result.get("team_id", "")
61
60
  config["user_id"] = result.get("user_id", "")
61
+ # Pull email + team_name from stored credentials so the daemon can
62
+ # embed them in manifest.json for device → user association.
63
+ creds = load_credentials() or {}
64
+ config["email"] = creds.get("email", "")
65
+ config["team_name"] = creds.get("team_name", "")
66
+ import platform, socket
67
+ config["hostname"] = socket.gethostname()
68
+ config["platform"] = platform.system().lower()
62
69
  CONFIG_FILE.write_text(json.dumps(config, indent=2))
63
70
  except TrackAPIError as e:
64
71
  console.print(f"[red]Provision failed:[/red] {e}")
@@ -92,6 +92,7 @@ class Daemon:
92
92
  self._bytes_uploaded = 0
93
93
  self._run_id = str(uuid.uuid4())[:8]
94
94
  self._device_id: str = ""
95
+ self._identity: dict = {}
95
96
  # confirmed_map: path → sha256 for every file we KNOW is on S3.
96
97
  # Populated from the remote manifest at startup and updated only on
97
98
  # successful upload callbacks. Used to build an honest manifest.json.
@@ -108,6 +109,15 @@ class Daemon:
108
109
  write_pid()
109
110
  cfg = _load_config()
110
111
  self._device_id = cfg["device_id"]
112
+ self._identity = {
113
+ "user_id": cfg.get("user_id", ""),
114
+ "email": cfg.get("email", ""),
115
+ "team_id": cfg.get("team_id", ""),
116
+ "team_name": cfg.get("team_name", ""),
117
+ "device_id": self._device_id,
118
+ "hostname": cfg.get("hostname", ""),
119
+ "platform": cfg.get("platform", ""),
120
+ }
111
121
  log.info("daemon starting run_id=%s pid=%s device=%s", self._run_id, os.getpid(), self._device_id)
112
122
 
113
123
  signal.signal(signal.SIGTERM, self._handle_sigterm)
@@ -247,7 +257,11 @@ class Daemon:
247
257
  confirmed = dict(self._confirmed_map)
248
258
 
249
259
  root = MerkleTree.compute_root(confirmed)
250
- manifest = json.dumps({"root_hash": root, "files": confirmed}, separators=(",", ":"))
260
+ manifest = json.dumps({
261
+ "root_hash": root,
262
+ **self._identity,
263
+ "files": confirmed,
264
+ }, separators=(",", ":"))
251
265
  try:
252
266
  url_map = self._api.get_upload_urls(self._device_id, ["manifest.json"])
253
267
  url = url_map.get("manifest.json")
@@ -141,6 +141,20 @@ class UploadQueue:
141
141
  "UPDATE queue SET status = 'done', updated_at = ? WHERE path = ? AND sha256 = ?",
142
142
  (now, path, sha256),
143
143
  )
144
+ # Prune rows for the same path that were enqueued *before* this one —
145
+ # they are older versions superseded by this upload.
146
+ # Rows enqueued *after* (newer file content) are preserved so they
147
+ # upload without waiting for the next reconcile.
148
+ self._conn.execute(
149
+ """
150
+ DELETE FROM queue
151
+ WHERE path = ? AND sha256 != ? AND status IN ('failed', 'pending')
152
+ AND enqueued_at <= (
153
+ SELECT enqueued_at FROM queue WHERE path = ? AND sha256 = ?
154
+ )
155
+ """,
156
+ (path, sha256, path, sha256),
157
+ )
144
158
  self._conn.commit()
145
159
 
146
160
  def mark_failed(self, path: str, sha256: str, error: str) -> None:
@@ -19,7 +19,9 @@ from .scrubber import scrub_bytes
19
19
  log = logging.getLogger("fleet.track.uploader")
20
20
 
21
21
  WORKERS = 8
22
- UPLOAD_TIMEOUT_SECS = 120
22
+ # Per-phase timeouts: connect/read can be short, write needs to be generous
23
+ # for large JSONL files on slow connections.
24
+ UPLOAD_TIMEOUT = httpx.Timeout(connect=10.0, read=30.0, write=300.0, pool=10.0)
23
25
 
24
26
 
25
27
  def _read_safe(path: Path) -> Optional[bytes]:
@@ -55,7 +57,7 @@ def upload_one(path: Path, presigned_url: str) -> bool:
55
57
  presigned_url,
56
58
  content=scrubbed,
57
59
  headers={"Content-Type": "application/octet-stream"},
58
- timeout=UPLOAD_TIMEOUT_SECS,
60
+ timeout=UPLOAD_TIMEOUT,
59
61
  )
60
62
  if resp.status_code not in (200, 204):
61
63
  log.warning("upload %s → HTTP %s", path.name, resp.status_code)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fleet-python
3
- Version: 0.2.121
3
+ Version: 0.2.123
4
4
  Summary: Python SDK for Fleet environments
5
5
  Author-email: Fleet AI <nic@fleet.so>
6
6
  License: Apache-2.0
@@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"
5
5
  [project]
6
6
  name = "fleet-python"
7
7
 
8
- version = "0.2.121"
8
+ version = "0.2.123"
9
9
  description = "Python SDK for Fleet environments"
10
10
  authors = [
11
11
  {name = "Fleet AI", email = "nic@fleet.so"},
File without changes
File without changes
File without changes