use monoloop_connector::{ConnectorFactory, ConnectorInstance};
use monoloop_contracts::{
ChannelCapabilities, ChannelDefaults, ChannelDescriptor, ChannelId, ChannelKind, ChannelLimits,
OutboundDialectEncoder, ToolExecutionMode,
};
use monoloop_interpreter::InterpreterFactory;
use std::collections::HashMap;
use std::sync::Arc;
pub struct ChannelBinding {
pub id: ChannelId,
pub kind: ChannelKind,
pub tool_mode: ToolExecutionMode,
pub connector_factory: Arc<dyn ConnectorFactory>,
pub encoder: Arc<dyn OutboundDialectEncoder>,
pub interpreter: Arc<dyn InterpreterFactory>,
pub endpoint_ref: String,
pub credential_ref: Option<String>,
pub defaults: ChannelDefaults,
pub capabilities: ChannelCapabilities,
pub limits: ChannelLimits,
}
impl ChannelBinding {
pub fn descriptor(&self) -> ChannelDescriptor {
ChannelDescriptor {
kind: self.kind,
tool_mode: self.tool_mode,
capabilities: self.capabilities.clone(),
limits: self.limits.clone(),
}
}
}
pub struct ChannelRegistry {
channels: HashMap<ChannelId, ChannelBinding>,
}
impl ChannelRegistry {
pub fn build(bindings: Vec<ChannelBinding>) -> Result<Self, super::StartupError> {
if bindings.is_empty() {
return Err(super::StartupError::ChannelRegistry(
"at least one Channel is required",
));
}
let mut channels = HashMap::with_capacity(bindings.len());
for b in bindings {
b.descriptor().validate()?;
if channels.contains_key(&b.id) {
return Err(super::StartupError::ChannelRegistry("duplicate ChannelId"));
}
channels.insert(b.id.clone(), b);
}
Ok(Self { channels })
}
pub fn iter(&self) -> impl Iterator<Item = (&ChannelId, &ChannelBinding)> {
self.channels.iter()
}
pub fn get(&self, id: &ChannelId) -> Option<&ChannelBinding> {
self.channels.get(id)
}
pub fn len(&self) -> usize {
self.channels.len()
}
pub fn is_empty(&self) -> bool {
self.channels.is_empty()
}
}
pub struct LiveChannel {
pub binding: ChannelBinding,
pub instance: ConnectorInstance,
}