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