1use crate::Commands;
2use async_trait::async_trait;
3use schemars::JsonSchema;
4use serde::{Deserialize, Serialize};
5
6#[derive(Debug, Clone, Default, Serialize, Deserialize)]
7pub struct ListSequencesQuery {
8 pub limit: Option<usize>,
9 pub offset: Option<usize>,
10 pub favourites_only: Option<bool>,
11 pub search: Option<String>,
12}
13
14#[derive(Debug, Clone, Serialize, Deserialize)]
15pub struct ListSequencesResult {
16 pub sequences: Vec<BrowserSequence>,
17 pub total: usize,
18}
19
20#[async_trait]
21pub trait BrowserSequenceStore: Send + Sync + std::fmt::Debug {
22 async fn create_sequence(&self, seq: NewBrowserSequence) -> anyhow::Result<BrowserSequence>;
23 async fn append_step(&self, step: NewBrowserStep) -> anyhow::Result<BrowserStep>;
24 async fn add_observation(
25 &self,
26 obs: NewBrowserObservation,
27 ) -> anyhow::Result<BrowserObservation>;
28 async fn add_screenshot(&self, shot: NewBrowserScreenshot)
29 -> anyhow::Result<BrowserScreenshot>;
30 async fn list_steps(
31 &self,
32 sequence_id: &str,
33 limit: Option<usize>,
34 ) -> anyhow::Result<Vec<BrowserStep>>;
35 async fn list_observations(
36 &self,
37 sequence_id: &str,
38 limit: Option<usize>,
39 ) -> anyhow::Result<Vec<BrowserObservation>>;
40 async fn list_sequences(&self, query: ListSequencesQuery) -> anyhow::Result<ListSequencesResult>;
41 async fn get_sequence(&self, id: &str) -> anyhow::Result<Option<BrowserSequence>>;
42 async fn delete_sequence(&self, id: &str) -> anyhow::Result<()>;
43 async fn set_favourite(&self, id: &str, favourite: bool) -> anyhow::Result<()>;
44}
45
46#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
47pub struct BrowserSequence {
48 pub id: String,
49 pub goal: Option<String>,
50 pub task_id: Option<String>,
51 pub thread_id: Option<String>,
52 pub favourite: bool,
53 pub created_at: chrono::DateTime<chrono::Utc>,
54 pub updated_at: chrono::DateTime<chrono::Utc>,
55}
56
57#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
58pub struct BrowserStep {
59 pub id: String,
60 pub browser_sequence_id: String,
61 pub commands: Vec<Commands>,
62 pub reason: Option<String>,
63 pub thread_id: Option<String>,
64 pub task_id: Option<String>,
65 pub run_id: Option<String>,
66 pub success: bool,
67 pub thinking: Option<String>,
68 pub evaluation_previous_goal: Option<String>,
69 pub memory: Option<String>,
70 pub next_goal: Option<String>,
71 pub action_result: Option<serde_json::Value>,
72 pub created_at: chrono::DateTime<chrono::Utc>,
73 pub updated_at: chrono::DateTime<chrono::Utc>,
74}
75
76#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
77pub struct BrowserObservationData {
78 pub success: bool,
79 pub state_text: Option<String>,
80 pub dom_snapshot: Option<serde_json::Value>,
81 pub screenshot: Option<serde_json::Value>,
82}
83
84#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
85pub struct BrowserObservation {
86 pub id: i64,
87 pub thread_id: String,
88 pub task_id: String,
89 pub run_id: String,
90 pub sequence_id: String,
91 pub observation: BrowserObservationData,
92 pub created_at: chrono::DateTime<chrono::Utc>,
93}
94
95#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
96pub struct BrowserScreenshot {
97 pub id: i64,
98 pub thread_id: String,
99 pub task_id: String,
100 pub run_id: String,
101 pub sequence_id: String,
102 pub screenshot: serde_json::Value,
103 pub created_at: chrono::DateTime<chrono::Utc>,
104}
105
106#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
107pub struct NewBrowserSequence {
108 pub id: String,
109 pub goal: Option<String>,
110 pub task_id: Option<String>,
111 pub thread_id: Option<String>,
112}
113
114#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
115pub struct NewBrowserStep {
116 pub id: String,
117 pub browser_sequence_id: String,
118 pub commands: Vec<Commands>,
119 pub reason: Option<String>,
120 pub thread_id: Option<String>,
121 pub task_id: Option<String>,
122 pub run_id: Option<String>,
123 pub thinking: Option<String>,
124 pub evaluation_previous_goal: Option<String>,
125 pub memory: Option<String>,
126 pub next_goal: Option<String>,
127 pub success: bool,
128 pub action_result: Option<serde_json::Value>,
129}
130
131#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
132pub struct NewBrowserObservation {
133 pub thread_id: String,
134 pub task_id: String,
135 pub run_id: String,
136 pub sequence_id: String,
137 pub observation: BrowserObservationData,
138}
139
140#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
141pub struct NewBrowserScreenshot {
142 pub thread_id: String,
143 pub task_id: String,
144 pub run_id: String,
145 pub sequence_id: String,
146 pub screenshot: serde_json::Value,
147}
148
149impl BrowserObservationData {
150 pub fn success(state_text: Option<String>, dom_snapshot: Option<serde_json::Value>) -> Self {
151 Self {
152 success: true,
153 state_text,
154 dom_snapshot,
155 screenshot: None,
156 }
157 }
158}