Skip to main content

eoka_protocol/
agent.rs

1use crate::{Expectation, OperationRecord, PageContext};
2use serde::{Deserialize, Serialize};
3
4#[derive(Debug, Clone, Serialize, Deserialize, schemars::JsonSchema)]
5#[serde(deny_unknown_fields)]
6pub struct AgentObserveArgs {
7    #[schemars(description = "Maximum labeled controls, 1 through 200. Increase if truncated.")]
8    #[serde(default = "control_limit")]
9    #[schemars(range(min = 1, max = 200))]
10    pub max_controls: usize,
11    #[serde(default = "observe_timeout")]
12    #[schemars(range(min = 50, max = 60000))]
13    pub timeout_ms: u64,
14}
15
16fn control_limit() -> usize {
17    40
18}
19fn observe_timeout() -> u64 {
20    3000
21}
22fn step_timeout() -> u64 {
23    10000
24}
25fn action_timeout() -> u64 {
26    30000
27}
28
29impl Default for AgentObserveArgs {
30    fn default() -> Self {
31        Self {
32            max_controls: control_limit(),
33            timeout_ms: observe_timeout(),
34        }
35    }
36}
37
38#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize, schemars::JsonSchema)]
39#[serde(rename_all = "snake_case")]
40pub enum AgentMode {
41    #[default]
42    Explore,
43    Verify,
44}
45
46#[derive(Debug, Clone, Serialize, Deserialize, schemars::JsonSchema)]
47#[serde(tag = "kind", rename_all = "snake_case", deny_unknown_fields)]
48pub enum AgentAction {
49    Click { target: String },
50    Fill { target: String, text: String },
51    Type { target: String, text: String },
52    Select { target: String, value: String },
53    Hover { target: String },
54    ScrollIntoView { target: String },
55    PressKey { key: String },
56    Navigate { url: String },
57    Back,
58    Forward,
59}
60
61#[derive(Debug, Clone, Serialize, Deserialize, schemars::JsonSchema)]
62#[serde(deny_unknown_fields)]
63pub struct AgentStepArgs {
64    #[schemars(
65        description = "Optional canonical UUID. SDK/CLI allocate before sending; direct MCP callers should supply one when recovery from a lost response is required. Reuse only with identical action arguments."
66    )]
67    #[serde(default)]
68    pub operation_id: Option<String>,
69    pub action: AgentAction,
70    #[schemars(
71        description = "Explore permits input without a predicted result and reports unverified outcomes honestly. Verify requires explicit expectations for actions without intrinsic completion evidence."
72    )]
73    #[serde(default)]
74    pub mode: AgentMode,
75    #[serde(default)]
76    pub expect: Option<Expectation>,
77    #[serde(default = "step_timeout")]
78    #[schemars(range(min = 50, max = 60000))]
79    pub timeout_ms: u64,
80    #[schemars(
81        description = "Independent action deadline, 1 through 300000 milliseconds. A shorter response wait never cancels or repeats the action."
82    )]
83    #[serde(default = "action_timeout")]
84    #[schemars(range(min = 1, max = 300000))]
85    pub action_timeout_ms: u64,
86    #[serde(default = "control_limit")]
87    #[schemars(range(min = 1, max = 200))]
88    pub max_controls: usize,
89}
90
91#[derive(Debug, Clone, Serialize, Deserialize, schemars::JsonSchema)]
92pub struct AgentControl {
93    pub target: String,
94    pub role: String,
95    pub name: String,
96    pub disabled: bool,
97    pub checked: Option<bool>,
98    pub expanded: Option<bool>,
99}
100
101#[derive(Debug, Clone, Serialize, Deserialize, schemars::JsonSchema)]
102pub struct AgentTab {
103    pub id: String,
104    pub url: String,
105    pub title: String,
106    pub selected: bool,
107}
108
109#[derive(Debug, Clone, Serialize, Deserialize, schemars::JsonSchema)]
110pub struct AgentObservation {
111    pub observation_id: String,
112    pub tab_id: String,
113    pub page: Option<PageContext>,
114    pub tabs: Vec<AgentTab>,
115    pub controls: Vec<AgentControl>,
116    pub truncated: bool,
117    pub warnings: Vec<String>,
118}
119
120#[derive(Debug, Clone, Serialize, Deserialize, schemars::JsonSchema)]
121pub struct AgentStepResult {
122    pub operation_id: String,
123    pub operation: Option<OperationRecord>,
124    pub operation_error: Option<String>,
125    pub observation: Option<AgentObservation>,
126    pub observation_error: Option<String>,
127}