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