1use chrono::{DateTime, Utc};
4use serde::{Deserialize, Serialize};
5
6use crate::{ExecutionPolicy, PageId, SessionId};
7
8#[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#[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 detect_challenge,
70 deterministic,
71 context,
72 vision_prefill,
73 vision_fallback,
74});
75metric_snapshot!(ContextMetricsSnapshot {
76 hit,
77 miss,
78 ambiguous_refusal,
79 stale_rejection,
80 error,
81});
82metric_snapshot!(PrefillMetricsSnapshot {
83 hit,
84 miss,
85 dropped_entry,
86 policy_denied,
87 provider_failure,
88});
89metric_snapshot!(ConfidenceMetricsSnapshot {
90 below_acceptance,
91 accepted,
92 high,
93 unreported,
94});
95metric_snapshot!(VerificationMetricsSnapshot {
96 accepted,
97 target_not_found,
98 target_ambiguous,
99 obstruction_persisted,
100 value_mismatch,
101 other_rejected,
102});
103metric_snapshot!(RetryMetricsSnapshot {
104 transport,
105 timeout,
106 target_detached,
107 state_conflict,
108 other,
109});
110metric_snapshot!(ReconciliationMetricsSnapshot {
111 resumed,
112 restarted,
113 needs_reconciliation,
114 failed,
115});
116metric_snapshot!(WorkflowCallMetricsSnapshot {
117 lifecycle,
118 discovery,
119 read,
120 mutation,
121 composite_workflow,
122 recovery,
123 artifact,
124 job,
125});
126
127#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
128#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
129#[serde(rename_all = "camelCase")]
130pub struct VisionMetricsSnapshot {
131 pub attempted: u64,
132 pub accepted: u64,
133 pub rejected: u64,
134 pub abstained: u64,
135 pub timed_out: u64,
136 pub failed: u64,
137 pub provider_http: u64,
138 pub provider_acp: u64,
139 pub provider_direct_local: u64,
140 pub latency_ms: LatencyHistogramSnapshot,
141 pub confidence: ConfidenceMetricsSnapshot,
142}
143
144#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
145#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
146#[serde(rename_all = "camelCase")]
147pub struct LatencyHistogramSnapshot {
148 pub buckets: Vec<LatencyBucketSnapshot>,
149 pub overflow: u64,
150}
151
152#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
153#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
154#[serde(rename_all = "camelCase")]
155pub struct LatencyBucketSnapshot {
156 pub upper_bound_ms: u64,
157 pub count: u64,
158}
159
160#[derive(Debug, Clone, Serialize, Deserialize)]
162#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
163pub struct SessionState {
164 pub id: SessionId,
165 pub profile: String,
166 pub proxy: Option<String>,
167 pub page_ids: Vec<PageId>,
168 pub created_at: DateTime<Utc>,
169 pub last_used_at: DateTime<Utc>,
170 pub execution_policy: ExecutionPolicy,
171 #[serde(default, skip_serializing_if = "std::ops::Not::not")]
177 pub zigzagzig: bool,
178}
179
180#[derive(Debug, Clone, Serialize, Deserialize)]
182#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
183pub struct PageState {
184 pub id: PageId,
185 pub session_id: SessionId,
186 pub url: Option<String>,
187 pub mode: PageMode,
188 pub ready_state: String,
189 pub pending_requests: usize,
190}
191
192#[derive(Debug, Clone, Serialize, Deserialize)]
194#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
195pub struct NavigationResult {
196 pub page_id: PageId,
197 pub url: String,
198 pub ready_state: String,
199}
200
201#[derive(Debug, Clone, Serialize, Deserialize)]
203#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
204pub struct ExtractResult {
205 pub page_id: PageId,
206 pub data: serde_json::Value,
207}