Skip to main content

bobby_browser_client/
state.rs

1//! Session and page runtime state returned by `/v1` endpoints.
2
3use chrono::{DateTime, Utc};
4use serde::{Deserialize, Serialize};
5
6use crate::{ExecutionPolicy, PageId, SessionId};
7
8/// Page rendering / interaction mode.
9#[derive(Debug, Clone, Serialize, Deserialize)]
10#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
11pub enum PageMode {
12    Document,
13    Interactive,
14    Render,
15}
16
17/// `GET /v1/runtime` body.
18#[derive(Debug, Clone, Serialize, Deserialize)]
19#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
20pub struct RuntimeInfo {
21    pub version: String,
22    pub capabilities: Vec<String>,
23    pub active_sessions: usize,
24    pub queued_jobs: usize,
25    pub uptime_ms: u64,
26    #[serde(
27        default,
28        rename = "operationalMetrics",
29        skip_serializing_if = "Option::is_none"
30    )]
31    pub operational_metrics: Option<OperationalMetricsSnapshot>,
32}
33
34#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
35#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
36#[serde(rename_all = "camelCase")]
37pub struct OperationalMetricsSnapshot {
38    pub observation_window_ms: u64,
39    pub intent: IntentMetricsSnapshot,
40    pub context: ContextMetricsSnapshot,
41    pub prefill: PrefillMetricsSnapshot,
42    pub vision: VisionMetricsSnapshot,
43    pub verification: VerificationMetricsSnapshot,
44    pub retries: RetryMetricsSnapshot,
45    pub reconciliation: ReconciliationMetricsSnapshot,
46    pub workflow_calls: WorkflowCallMetricsSnapshot,
47}
48
49macro_rules! metric_snapshot {
50    ($name:ident { $($field:ident),+ $(,)? }) => {
51        #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
52        #[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
53        #[serde(rename_all = "camelCase")]
54        pub struct $name { $(pub $field: u64,)+ }
55    };
56}
57
58metric_snapshot!(IntentMetricsSnapshot {
59    total,
60    locate,
61    fill,
62    complete_form,
63    extract,
64    submit,
65    wait_for_state,
66    follow,
67    dismiss,
68    solve_challenge,
69    deterministic,
70    context,
71    vision_prefill,
72    vision_fallback,
73});
74metric_snapshot!(ContextMetricsSnapshot {
75    hit,
76    miss,
77    ambiguous_refusal,
78    stale_rejection,
79    error,
80});
81metric_snapshot!(PrefillMetricsSnapshot {
82    hit,
83    miss,
84    dropped_entry,
85    policy_denied,
86    provider_failure,
87});
88metric_snapshot!(ConfidenceMetricsSnapshot {
89    below_acceptance,
90    accepted,
91    high,
92    unreported,
93});
94metric_snapshot!(VerificationMetricsSnapshot {
95    accepted,
96    target_not_found,
97    target_ambiguous,
98    obstruction_persisted,
99    value_mismatch,
100    other_rejected,
101});
102metric_snapshot!(RetryMetricsSnapshot {
103    transport,
104    timeout,
105    target_detached,
106    state_conflict,
107    other,
108});
109metric_snapshot!(ReconciliationMetricsSnapshot {
110    resumed,
111    restarted,
112    needs_reconciliation,
113    failed,
114});
115metric_snapshot!(WorkflowCallMetricsSnapshot {
116    lifecycle,
117    discovery,
118    read,
119    mutation,
120    composite_workflow,
121    recovery,
122    artifact,
123    job,
124});
125
126#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
127#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
128#[serde(rename_all = "camelCase")]
129pub struct VisionMetricsSnapshot {
130    pub attempted: u64,
131    pub accepted: u64,
132    pub rejected: u64,
133    pub abstained: u64,
134    pub timed_out: u64,
135    pub failed: u64,
136    pub provider_http: u64,
137    pub provider_acp: u64,
138    pub provider_direct_local: u64,
139    pub latency_ms: LatencyHistogramSnapshot,
140    pub confidence: ConfidenceMetricsSnapshot,
141}
142
143#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
144#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
145#[serde(rename_all = "camelCase")]
146pub struct LatencyHistogramSnapshot {
147    pub buckets: Vec<LatencyBucketSnapshot>,
148    pub overflow: u64,
149}
150
151#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
152#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
153#[serde(rename_all = "camelCase")]
154pub struct LatencyBucketSnapshot {
155    pub upper_bound_ms: u64,
156    pub count: u64,
157}
158
159/// Browser session returned by session create/list endpoints.
160#[derive(Debug, Clone, Serialize, Deserialize)]
161#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
162pub struct SessionState {
163    pub id: SessionId,
164    pub profile: String,
165    pub proxy: Option<String>,
166    pub page_ids: Vec<PageId>,
167    pub created_at: DateTime<Utc>,
168    pub last_used_at: DateTime<Utc>,
169    pub execution_policy: ExecutionPolicy,
170}
171
172/// Page within a session.
173#[derive(Debug, Clone, Serialize, Deserialize)]
174#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
175pub struct PageState {
176    pub id: PageId,
177    pub session_id: SessionId,
178    pub url: Option<String>,
179    pub mode: PageMode,
180    pub ready_state: String,
181    pub pending_requests: usize,
182}
183
184/// Result of a navigation command.
185#[derive(Debug, Clone, Serialize, Deserialize)]
186#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
187pub struct NavigationResult {
188    pub page_id: PageId,
189    pub url: String,
190    pub ready_state: String,
191}
192
193/// Result of a structured extract command.
194#[derive(Debug, Clone, Serialize, Deserialize)]
195#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
196pub struct ExtractResult {
197    pub page_id: PageId,
198    pub data: serde_json::Value,
199}