use crate::Commands;
use async_trait::async_trait;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct ListSequencesQuery {
pub limit: Option<usize>,
pub offset: Option<usize>,
pub favourites_only: Option<bool>,
pub search: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ListSequencesResult {
pub sequences: Vec<BrowserSequence>,
pub total: usize,
}
#[async_trait]
pub trait BrowserSequenceStore: Send + Sync + std::fmt::Debug {
async fn create_sequence(&self, seq: NewBrowserSequence) -> anyhow::Result<BrowserSequence>;
async fn append_step(&self, step: NewBrowserStep) -> anyhow::Result<BrowserStep>;
async fn add_observation(
&self,
obs: NewBrowserObservation,
) -> anyhow::Result<BrowserObservation>;
async fn add_screenshot(&self, shot: NewBrowserScreenshot)
-> anyhow::Result<BrowserScreenshot>;
async fn list_steps(
&self,
sequence_id: &str,
limit: Option<usize>,
) -> anyhow::Result<Vec<BrowserStep>>;
async fn list_observations(
&self,
sequence_id: &str,
limit: Option<usize>,
) -> anyhow::Result<Vec<BrowserObservation>>;
async fn list_sequences(
&self,
query: ListSequencesQuery,
) -> anyhow::Result<ListSequencesResult>;
async fn get_sequence(&self, id: &str) -> anyhow::Result<Option<BrowserSequence>>;
async fn delete_sequence(&self, id: &str) -> anyhow::Result<()>;
async fn set_favourite(&self, id: &str, favourite: bool) -> anyhow::Result<()>;
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
pub struct BrowserSequence {
pub id: String,
pub goal: Option<String>,
pub task_id: Option<String>,
pub thread_id: Option<String>,
pub favourite: bool,
pub created_at: chrono::DateTime<chrono::Utc>,
pub updated_at: chrono::DateTime<chrono::Utc>,
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
pub struct BrowserStep {
pub id: String,
pub browser_sequence_id: String,
pub commands: Vec<Commands>,
pub reason: Option<String>,
pub thread_id: Option<String>,
pub task_id: Option<String>,
pub run_id: Option<String>,
pub success: bool,
pub thinking: Option<String>,
pub evaluation_previous_goal: Option<String>,
pub memory: Option<String>,
pub next_goal: Option<String>,
pub action_result: Option<serde_json::Value>,
pub created_at: chrono::DateTime<chrono::Utc>,
pub updated_at: chrono::DateTime<chrono::Utc>,
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
pub struct BrowserObservationData {
pub success: bool,
pub state_text: Option<String>,
pub dom_snapshot: Option<serde_json::Value>,
pub screenshot: Option<serde_json::Value>,
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
pub struct BrowserObservation {
pub id: i64,
pub thread_id: String,
pub task_id: String,
pub run_id: String,
pub sequence_id: String,
pub observation: BrowserObservationData,
pub created_at: chrono::DateTime<chrono::Utc>,
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
pub struct BrowserScreenshot {
pub id: i64,
pub thread_id: String,
pub task_id: String,
pub run_id: String,
pub sequence_id: String,
pub screenshot: serde_json::Value,
pub created_at: chrono::DateTime<chrono::Utc>,
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
pub struct NewBrowserSequence {
pub id: String,
pub goal: Option<String>,
pub task_id: Option<String>,
pub thread_id: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
pub struct NewBrowserStep {
pub id: String,
pub browser_sequence_id: String,
pub commands: Vec<Commands>,
pub reason: Option<String>,
pub thread_id: Option<String>,
pub task_id: Option<String>,
pub run_id: Option<String>,
pub thinking: Option<String>,
pub evaluation_previous_goal: Option<String>,
pub memory: Option<String>,
pub next_goal: Option<String>,
pub success: bool,
pub action_result: Option<serde_json::Value>,
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
pub struct NewBrowserObservation {
pub thread_id: String,
pub task_id: String,
pub run_id: String,
pub sequence_id: String,
pub observation: BrowserObservationData,
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
pub struct NewBrowserScreenshot {
pub thread_id: String,
pub task_id: String,
pub run_id: String,
pub sequence_id: String,
pub screenshot: serde_json::Value,
}
impl BrowserObservationData {
pub fn success(state_text: Option<String>, dom_snapshot: Option<serde_json::Value>) -> Self {
Self {
success: true,
state_text,
dom_snapshot,
screenshot: None,
}
}
}