use serde::Serialize;
use tokio::sync::broadcast;
use crate::ids::{ChannelId, PeerId, ThreadId};
use crate::spec::ProviderKind;
#[derive(Debug, Clone, Serialize)]
#[serde(tag = "kind", rename_all = "snake_case")]
pub enum ChannelEvent {
ProviderConnected {
provider: ProviderKind,
channel_id: ChannelId,
},
ProviderDisconnected {
provider: ProviderKind,
channel_id: ChannelId,
reason: String,
},
ThreadOpened {
thread_id: ThreadId,
channel_id: ChannelId,
peer: PeerId,
},
ThreadClosed {
thread_id: ThreadId,
reason: String,
},
MessageReceived {
thread_id: ThreadId,
message_id: String,
peer: PeerId,
summary: String,
},
MessageDuplicate {
thread_id: ThreadId,
provider_msg_id: String,
},
TurnStarted {
thread_id: ThreadId,
message_id: String,
},
TurnCompleted {
thread_id: ThreadId,
message_id: String,
output_summary: String,
},
MessageSent {
thread_id: ThreadId,
message_id: String,
provider_msg_id: String,
},
Error {
#[serde(skip_serializing_if = "Option::is_none")]
thread_id: Option<ThreadId>,
#[serde(skip_serializing_if = "Option::is_none")]
message_id: Option<String>,
reason: String,
},
}
pub struct ChannelEventStream {
rx: broadcast::Receiver<ChannelEvent>,
}
impl ChannelEventStream {
pub fn new(rx: broadcast::Receiver<ChannelEvent>) -> Self {
Self { rx }
}
pub async fn recv(&mut self) -> Option<ChannelEvent> {
loop {
match self.rx.recv().await {
Ok(ev) => return Some(ev),
Err(broadcast::error::RecvError::Lagged(_)) => continue,
Err(broadcast::error::RecvError::Closed) => return None,
}
}
}
}