use async_trait::async_trait;
use serde::{Deserialize, Serialize};
use super::types::SessionId;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SessionSummary {
pub id: SessionId,
pub channel: String,
pub peer: String,
pub created_at: chrono::DateTime<chrono::Utc>,
pub last_active: chrono::DateTime<chrono::Utc>,
pub message_count: usize,
#[serde(skip_serializing_if = "Option::is_none")]
pub parent: Option<SessionId>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SessionMessage {
pub role: String,
pub content: String,
pub timestamp: chrono::DateTime<chrono::Utc>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SpawnRequest {
pub prompt: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub model: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub system: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub tools: Option<Vec<String>>,
#[serde(default)]
pub wait_for_first_reply: bool,
#[serde(default = "default_wait_timeout_secs")]
pub wait_timeout_secs: u64,
}
fn default_wait_timeout_secs() -> u64 {
60
}
impl Default for SpawnRequest {
fn default() -> Self {
Self {
prompt: String::new(),
model: None,
system: None,
tools: None,
wait_for_first_reply: false,
wait_timeout_secs: default_wait_timeout_secs(),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SpawnedSession {
pub id: SessionId,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub first_reply: Option<SessionMessage>,
}
#[async_trait]
pub trait SessionBroker: Send + Sync {
async fn list(&self) -> anyhow::Result<Vec<SessionSummary>>;
async fn history(
&self,
id: &SessionId,
limit: Option<usize>,
) -> anyhow::Result<Vec<SessionMessage>>;
async fn send(&self, id: &SessionId, text: String) -> anyhow::Result<()>;
async fn spawn(&self, parent: &SessionId, req: SpawnRequest) -> anyhow::Result<SpawnedSession>;
}