fleet-python 0.2.66b2__py3-none-any.whl → 0.2.105__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.
Files changed (70) hide show
  1. examples/export_tasks.py +16 -5
  2. examples/export_tasks_filtered.py +245 -0
  3. examples/fetch_tasks.py +230 -0
  4. examples/import_tasks.py +140 -8
  5. examples/iterate_verifiers.py +725 -0
  6. fleet/__init__.py +128 -5
  7. fleet/_async/__init__.py +27 -3
  8. fleet/_async/base.py +24 -9
  9. fleet/_async/client.py +938 -41
  10. fleet/_async/env/client.py +60 -3
  11. fleet/_async/instance/client.py +52 -7
  12. fleet/_async/models.py +15 -0
  13. fleet/_async/resources/api.py +200 -0
  14. fleet/_async/resources/sqlite.py +1801 -46
  15. fleet/_async/tasks.py +122 -25
  16. fleet/_async/verifiers/bundler.py +22 -21
  17. fleet/_async/verifiers/verifier.py +25 -19
  18. fleet/agent/__init__.py +32 -0
  19. fleet/agent/gemini_cua/Dockerfile +45 -0
  20. fleet/agent/gemini_cua/__init__.py +10 -0
  21. fleet/agent/gemini_cua/agent.py +759 -0
  22. fleet/agent/gemini_cua/mcp/main.py +108 -0
  23. fleet/agent/gemini_cua/mcp_server/__init__.py +5 -0
  24. fleet/agent/gemini_cua/mcp_server/main.py +105 -0
  25. fleet/agent/gemini_cua/mcp_server/tools.py +178 -0
  26. fleet/agent/gemini_cua/requirements.txt +5 -0
  27. fleet/agent/gemini_cua/start.sh +30 -0
  28. fleet/agent/orchestrator.py +854 -0
  29. fleet/agent/types.py +49 -0
  30. fleet/agent/utils.py +34 -0
  31. fleet/base.py +34 -9
  32. fleet/cli.py +1061 -0
  33. fleet/client.py +1060 -48
  34. fleet/config.py +1 -1
  35. fleet/env/__init__.py +16 -0
  36. fleet/env/client.py +60 -3
  37. fleet/eval/__init__.py +15 -0
  38. fleet/eval/uploader.py +231 -0
  39. fleet/exceptions.py +8 -0
  40. fleet/instance/client.py +53 -8
  41. fleet/instance/models.py +1 -0
  42. fleet/models.py +303 -0
  43. fleet/proxy/__init__.py +25 -0
  44. fleet/proxy/proxy.py +453 -0
  45. fleet/proxy/whitelist.py +244 -0
  46. fleet/resources/api.py +200 -0
  47. fleet/resources/sqlite.py +1845 -46
  48. fleet/tasks.py +113 -20
  49. fleet/utils/__init__.py +7 -0
  50. fleet/utils/http_logging.py +178 -0
  51. fleet/utils/logging.py +13 -0
  52. fleet/utils/playwright.py +440 -0
  53. fleet/verifiers/bundler.py +22 -21
  54. fleet/verifiers/db.py +985 -1
  55. fleet/verifiers/decorator.py +1 -1
  56. fleet/verifiers/verifier.py +25 -19
  57. {fleet_python-0.2.66b2.dist-info → fleet_python-0.2.105.dist-info}/METADATA +28 -1
  58. fleet_python-0.2.105.dist-info/RECORD +115 -0
  59. {fleet_python-0.2.66b2.dist-info → fleet_python-0.2.105.dist-info}/WHEEL +1 -1
  60. fleet_python-0.2.105.dist-info/entry_points.txt +2 -0
  61. tests/test_app_method.py +85 -0
  62. tests/test_expect_exactly.py +4148 -0
  63. tests/test_expect_only.py +2593 -0
  64. tests/test_instance_dispatch.py +607 -0
  65. tests/test_sqlite_resource_dual_mode.py +263 -0
  66. tests/test_sqlite_shared_memory_behavior.py +117 -0
  67. fleet_python-0.2.66b2.dist-info/RECORD +0 -81
  68. tests/test_verifier_security.py +0 -427
  69. {fleet_python-0.2.66b2.dist-info → fleet_python-0.2.105.dist-info}/licenses/LICENSE +0 -0
  70. {fleet_python-0.2.66b2.dist-info → fleet_python-0.2.105.dist-info}/top_level.txt +0 -0
fleet/models.py CHANGED
@@ -51,6 +51,7 @@ class Instance(BaseModel):
51
51
  team_id: str = Field(..., title="Team Id")
52
52
  region: str = Field(..., title="Region")
53
53
  env_variables: Optional[Dict[str, Any]] = Field(None, title="Env Variables")
54
+ run_id: Optional[str] = Field(None, title="Run Id")
54
55
 
55
56
 
56
57
  class InstanceRequest(BaseModel):
@@ -70,6 +71,7 @@ class InstanceRequest(BaseModel):
70
71
  image_type: Optional[str] = Field(None, title="Image Type")
71
72
  created_from: Optional[str] = Field(None, title="Created From")
72
73
  ttl_seconds: Optional[int] = Field(None, title="TTL Seconds")
74
+ heartbeat_interval: Optional[int] = Field(None, title="Heartbeat Interval")
73
75
 
74
76
 
75
77
  class InstanceStatus(Enum):
@@ -158,6 +160,10 @@ class TaskRequest(BaseModel):
158
160
  verifier_id: Optional[str] = Field(None, title="Verifier Id")
159
161
  version: Optional[str] = Field(None, title="Version")
160
162
  env_variables: Optional[Dict[str, Any]] = Field(None, title="Env Variables")
163
+ metadata: Optional[Dict[str, Any]] = Field(None, title="Metadata")
164
+ writer_metadata: Optional[Dict[str, Any]] = Field(
165
+ None, title="Writer Metadata", description="Metadata filled by task writer"
166
+ )
161
167
  output_json_schema: Optional[Dict[str, Any]] = Field(
162
168
  None, title="Output Json Schema"
163
169
  )
@@ -166,6 +172,13 @@ class TaskRequest(BaseModel):
166
172
  class TaskUpdateRequest(BaseModel):
167
173
  prompt: Optional[str] = Field(None, title="Prompt")
168
174
  verifier_code: Optional[str] = Field(None, title="Verifier Code")
175
+ metadata: Optional[Dict[str, Any]] = Field(None, title="Metadata")
176
+ writer_metadata: Optional[Dict[str, Any]] = Field(
177
+ None, title="Writer Metadata", description="Metadata filled by task writer"
178
+ )
179
+ qa_metadata: Optional[Dict[str, Any]] = Field(
180
+ None, title="QA Metadata", description="Metadata filled by QA reviewer"
181
+ )
169
182
 
170
183
 
171
184
  class VerifierData(BaseModel):
@@ -191,6 +204,9 @@ class TaskResponse(BaseModel):
191
204
  data_version: Optional[str] = Field(None, title="Data Version")
192
205
  env_variables: Optional[Dict[str, Any]] = Field(None, title="Env Variables")
193
206
  verifier: Optional[VerifierData] = Field(None, title="Verifier")
207
+ metadata: Optional[Dict[str, Any]] = Field(None, title="Metadata")
208
+ writer_metadata: Optional[Dict[str, Any]] = Field(None, title="Writer Metadata")
209
+ qa_metadata: Optional[Dict[str, Any]] = Field(None, title="QA Metadata")
194
210
  output_json_schema: Optional[Dict[str, Any]] = Field(
195
211
  None, title="Output Json Schema"
196
212
  )
@@ -360,6 +376,37 @@ class InstanceResponse(BaseModel):
360
376
  data_version: Optional[str] = Field(None, title="Data Version")
361
377
  urls: Optional[InstanceURLs] = Field(None, title="Urls")
362
378
  health: Optional[bool] = Field(None, title="Health")
379
+ run_id: Optional[str] = Field(None, title="Run Id")
380
+ profile_id: Optional[str] = Field(None, title="Profile Id")
381
+ heartbeat_interval: Optional[int] = Field(None, title="Heartbeat Interval")
382
+ heartbeat_region: Optional[str] = Field(None, title="Heartbeat Region")
383
+
384
+
385
+ class Run(BaseModel):
386
+ run_id: str = Field(..., title="Run Id")
387
+ running_count: int = Field(..., title="Running Count")
388
+ total_count: int = Field(..., title="Total Count")
389
+ first_created_at: str = Field(..., title="First Created At")
390
+ last_created_at: str = Field(..., title="Last Created At")
391
+ profile_id: Optional[str] = Field(None, title="Profile Id")
392
+
393
+
394
+ class HeartbeatResponse(BaseModel):
395
+ """Response from bumping an instance heartbeat."""
396
+
397
+ success: bool = Field(..., description="Whether the heartbeat was successfully updated")
398
+ instance_id: str = Field(..., description="The instance ID")
399
+ last_heartbeat: Optional[str] = Field(
400
+ None,
401
+ description="ISO 8601 UTC timestamp of the heartbeat (None if not enabled)",
402
+ )
403
+ deadline_timestamp: Optional[float] = Field(
404
+ None,
405
+ description="Unix timestamp when next heartbeat is due (None if not enabled)",
406
+ )
407
+ interval_seconds: Optional[int] = Field(
408
+ None, description="Heartbeat interval in seconds (None if not enabled)"
409
+ )
363
410
 
364
411
 
365
412
  class AccountResponse(BaseModel):
@@ -367,3 +414,259 @@ class AccountResponse(BaseModel):
367
414
  team_name: str = Field(..., title="Team Name")
368
415
  instance_limit: int = Field(..., title="Instance Limit")
369
416
  instance_count: int = Field(..., title="Instance Count")
417
+ profile_id: Optional[str] = Field(None, title="Profile Id")
418
+ profile_name: Optional[str] = Field(None, title="Profile Name")
419
+
420
+
421
+ # Jobs and Sessions models
422
+
423
+
424
+ class JobCreateRequest(BaseModel):
425
+ """Request payload for creating a new job.
426
+
427
+ The name field supports placeholders:
428
+ - {id}: Replaced with a full UUID
429
+ - {sid}: Replaced with the first 8 characters of a UUID (short ID)
430
+ - {i}: Replaced with auto-incrementing number (must be a suffix, e.g., "job-{i}")
431
+ """
432
+
433
+ name: Optional[str] = Field(None, title="Name", max_length=255)
434
+ models: List[str] = Field(..., title="Models", min_length=1)
435
+ pass_k: int = Field(1, title="Pass K", ge=1)
436
+ env_key: Optional[str] = Field(None, title="Env Key")
437
+ project_key: Optional[str] = Field(None, title="Project Key")
438
+ task_keys: Optional[List[str]] = Field(None, title="Task Keys", min_length=1)
439
+ excluded_task_keys: Optional[List[str]] = Field(None, title="Excluded Task Keys")
440
+ max_steps: Optional[int] = Field(None, title="Max Steps", ge=1)
441
+ max_duration_minutes: int = Field(60, title="Max Duration Minutes", ge=1)
442
+ max_concurrent_per_model: int = Field(30, title="Max Concurrent Per Model", ge=1)
443
+ mode: Optional[str] = Field(None, title="Mode")
444
+ system_prompt: Optional[str] = Field(None, title="System Prompt")
445
+ model_prompts: Optional[Dict[str, str]] = Field(None, title="Model Prompts")
446
+ byok_keys: Optional[Dict[str, str]] = Field(None, title="BYOK Keys")
447
+ byok_ttl_minutes: Optional[int] = Field(None, title="BYOK TTL Minutes", ge=1)
448
+ harness: Optional[str] = Field(None, title="Harness")
449
+
450
+
451
+ class JobResponse(BaseModel):
452
+ """Response for a single job."""
453
+
454
+ id: str = Field(..., title="Id")
455
+ name: Optional[str] = Field(None, title="Name")
456
+ created_at: Optional[str] = Field(None, title="Created At")
457
+ status: Optional[str] = Field(None, title="Status")
458
+
459
+
460
+ class JobListResponse(BaseModel):
461
+ """Response for listing jobs."""
462
+
463
+ jobs: List[JobResponse] = Field(..., title="Jobs")
464
+ total: int = Field(..., title="Total")
465
+
466
+
467
+ class JobCreateResponse(BaseModel):
468
+ """Response from creating a job."""
469
+
470
+ job_id: str = Field(..., title="Job Id")
471
+ workflow_job_id: Optional[str] = Field(None, title="Workflow Job Id")
472
+ status: str = Field(..., title="Status")
473
+ name: Optional[str] = Field(None, title="Name")
474
+
475
+
476
+ class VerifierExecutionResult(BaseModel):
477
+ """Verifier execution result for a session."""
478
+
479
+ success: bool = Field(..., title="Success")
480
+ score: Optional[float] = Field(None, title="Score")
481
+ stdout: Optional[str] = Field(None, title="Stdout")
482
+ execution_time_ms: int = Field(..., title="Execution Time Ms")
483
+ result: Optional[Any] = Field(None, title="Result")
484
+
485
+
486
+ class SessionInfo(BaseModel):
487
+ """Session information within a job."""
488
+
489
+ session_id: str = Field(..., title="Session Id")
490
+ instance: Optional[Instance] = Field(None, title="Instance")
491
+ model: str = Field(..., title="Model")
492
+ status: str = Field(..., title="Status")
493
+ created_at: str = Field(..., title="Created At")
494
+ started_at: Optional[str] = Field(None, title="Started At")
495
+ ended_at: Optional[str] = Field(None, title="Ended At")
496
+ step_count: int = Field(..., title="Step Count")
497
+ verifier_execution: Optional[VerifierExecutionResult] = Field(
498
+ None, title="Verifier Execution"
499
+ )
500
+
501
+
502
+ class TaskInfo(BaseModel):
503
+ """Task information for session transcript."""
504
+
505
+ key: str = Field(..., title="Key")
506
+ prompt: str = Field(..., title="Prompt")
507
+ env_id: str = Field(..., title="Env Id")
508
+ env_variables: Optional[Dict[str, Any]] = Field(None, title="Env Variables")
509
+ created_at: Optional[str] = Field(None, title="Created At")
510
+ version: Optional[str] = Field(None, title="Version")
511
+ verifier_func: Optional[str] = Field(None, title="Verifier Func")
512
+ verifier_id: Optional[str] = Field(None, title="Verifier Id")
513
+ metadata: Optional[Dict[str, Any]] = Field(None, title="Metadata")
514
+ writer_metadata: Optional[Dict[str, Any]] = Field(None, title="Writer Metadata")
515
+ qa_metadata: Optional[Dict[str, Any]] = Field(None, title="QA Metadata")
516
+
517
+
518
+ class TaskSessionGroup(BaseModel):
519
+ """Sessions grouped by task."""
520
+
521
+ task_id: Optional[str] = Field(None, title="Task Id")
522
+ task: Optional[TaskInfo] = Field(None, title="Task")
523
+ total_sessions: int = Field(..., title="Total Sessions")
524
+ passed_sessions: int = Field(..., title="Passed Sessions")
525
+ pass_rate: float = Field(..., title="Pass Rate")
526
+ average_score: Optional[float] = Field(None, title="Average Score")
527
+ sessions: List[SessionInfo] = Field(..., title="Sessions")
528
+
529
+
530
+ class JobSessionsResponse(BaseModel):
531
+ """Response for listing sessions for a job."""
532
+
533
+ job_id: str = Field(..., title="Job Id")
534
+ total_sessions: int = Field(..., title="Total Sessions")
535
+ tasks: List[TaskSessionGroup] = Field(..., title="Tasks")
536
+
537
+
538
+ class TranscriptMessage(BaseModel):
539
+ """A message in the session transcript."""
540
+
541
+ role: str = Field(..., title="Role")
542
+ content: Any = Field(..., title="Content")
543
+ tool_calls: Optional[List[Any]] = Field(None, title="Tool Calls")
544
+ tool_call_id: Optional[str] = Field(None, title="Tool Call Id")
545
+
546
+
547
+ class SessionTranscriptResponse(BaseModel):
548
+ """Response for a session transcript."""
549
+
550
+ task: Optional[TaskInfo] = Field(None, title="Task")
551
+ instance: Optional[Instance] = Field(None, title="Instance")
552
+ verifier_execution: Optional[VerifierExecutionResult] = Field(
553
+ None, title="Verifier Execution"
554
+ )
555
+ transcript: List[TranscriptMessage] = Field(..., title="Transcript")
556
+
557
+
558
+ # Eval Job models (for local CLI runs with remote logging)
559
+
560
+
561
+ class EvalJobCreateRequest(BaseModel):
562
+ """Request to create an eval job for local CLI runs."""
563
+
564
+ project_key: Optional[str] = Field(None, title="Project Key")
565
+ task_keys: Optional[List[str]] = Field(None, title="Task Keys")
566
+ model: str = Field(..., title="Model")
567
+ agent: str = Field(..., title="Agent")
568
+ source: str = Field("local_cli", title="Source")
569
+ metadata: Optional[Dict[str, Any]] = Field(None, title="Metadata")
570
+
571
+
572
+ class EvalJobCreateResponse(BaseModel):
573
+ """Response from creating an eval job."""
574
+
575
+ job_id: str = Field(..., title="Job Id")
576
+ status: str = Field(..., title="Status")
577
+
578
+
579
+ class EvalEvent(BaseModel):
580
+ """A single eval event."""
581
+
582
+ type: str = Field(..., title="Event Type")
583
+ timestamp: str = Field(..., title="Timestamp")
584
+ task_key: Optional[str] = Field(None, title="Task Key")
585
+ session_id: Optional[str] = Field(None, title="Session Id")
586
+ data: Dict[str, Any] = Field(default_factory=dict, title="Data")
587
+ duration_ms: Optional[int] = Field(None, title="Duration Ms")
588
+
589
+
590
+ class EvalEventsRequest(BaseModel):
591
+ """Request to upload eval events."""
592
+
593
+ job_id: str = Field(..., title="Job Id")
594
+ events: List[EvalEvent] = Field(..., title="Events")
595
+
596
+
597
+ class EvalEventsResponse(BaseModel):
598
+ """Response from uploading eval events."""
599
+
600
+ received: int = Field(..., title="Received Count")
601
+ status: str = Field(..., title="Status")
602
+
603
+
604
+ # Session Ingest models
605
+
606
+
607
+ class SessionStatus(str, Enum):
608
+ """Status of a session."""
609
+
610
+ pending = "pending"
611
+ running = "running"
612
+ completed = "completed"
613
+ failed = "failed"
614
+ cancelled = "cancelled"
615
+
616
+
617
+ class SessionIngestMessage(BaseModel):
618
+ """A message to ingest into a session."""
619
+
620
+ role: str = Field(..., title="Role", description="Message role (user, assistant, tool, etc.)")
621
+ content: Optional[Any] = Field(None, title="Content", description="Message content (string or structured)")
622
+ thinking: Optional[str] = Field(None, title="Thinking", description="Model reasoning/thinking trace")
623
+ tool_calls: Optional[List[Dict[str, Any]]] = Field(None, title="Tool Calls")
624
+ tool_call_id: Optional[str] = Field(None, title="Tool Call Id")
625
+ timestamp: Optional[str] = Field(None, title="Timestamp")
626
+ tokens: Optional[int] = Field(None, title="Tokens")
627
+ metadata: Optional[Dict[str, Any]] = Field(None, title="Metadata")
628
+
629
+
630
+ class SessionIngestRequest(BaseModel):
631
+ """Request to ingest session data.
632
+
633
+ Can be used to:
634
+ - Create a new session (omit session_id)
635
+ - Append to an existing session (provide session_id)
636
+ """
637
+
638
+ messages: List[SessionIngestMessage] = Field(..., title="Messages", min_length=1)
639
+ session_id: Optional[str] = Field(None, title="Session Id", description="Existing session ID to append to")
640
+ team_id: Optional[str] = Field(None, title="Team Id")
641
+ model: Optional[str] = Field(None, title="Model", description="Model identifier (e.g., anthropic/claude-sonnet-4)")
642
+ task_key: Optional[str] = Field(None, title="Task Key")
643
+ job_id: Optional[str] = Field(None, title="Job Id")
644
+ instance_id: Optional[str] = Field(None, title="Instance Id")
645
+ status: Optional[SessionStatus] = Field(None, title="Status")
646
+ metadata: Optional[Dict[str, Any]] = Field(None, title="Metadata")
647
+ started_at: Optional[str] = Field(None, title="Started At")
648
+ ended_at: Optional[str] = Field(None, title="Ended At")
649
+ verifier_execution_id: Optional[str] = Field(None, title="Verifier Execution Id", description="ID of the verifier execution record")
650
+
651
+
652
+ class SessionIngestResponse(BaseModel):
653
+ """Response from ingesting session data."""
654
+
655
+ success: bool = Field(..., title="Success")
656
+ session_id: str = Field(..., title="Session Id")
657
+ message_count: int = Field(..., title="Message Count", description="Total messages in session")
658
+ created_new_session: bool = Field(..., title="Created New Session", description="True if a new session was created")
659
+
660
+
661
+ class TraceJobRequest(BaseModel):
662
+ """Request to create a new trace job."""
663
+
664
+ name: Optional[str] = Field(None, title="Name", description="Name of the job (generated server-side if not provided)")
665
+
666
+
667
+ class TraceJobResponse(BaseModel):
668
+ """Response from creating a trace job."""
669
+
670
+ job_id: str = Field(..., title="Job Id")
671
+ name: str = Field(..., title="Name")
672
+ status: str = Field(..., title="Status")
@@ -0,0 +1,25 @@
1
+ # Fleet HTTP Proxy for capturing API traffic
2
+
3
+ from .proxy import ProxyManager, run_proxy_server
4
+ from .whitelist import (
5
+ register_endpoint,
6
+ install_hooks,
7
+ is_whitelisted,
8
+ get_full_whitelist,
9
+ get_runtime_whitelist,
10
+ clear_runtime_whitelist,
11
+ STATIC_WHITELIST,
12
+ )
13
+
14
+ __all__ = [
15
+ "ProxyManager",
16
+ "run_proxy_server",
17
+ # Whitelist management
18
+ "register_endpoint",
19
+ "install_hooks",
20
+ "is_whitelisted",
21
+ "get_full_whitelist",
22
+ "get_runtime_whitelist",
23
+ "clear_runtime_whitelist",
24
+ "STATIC_WHITELIST",
25
+ ]