use crate::config::EffectiveConfig;
use crate::dialect::DialectDescriptor;
use crate::id::{ExchangeId, TransactionId};
use crate::input::CanonicalInput;
use crate::input::CanonicalMessage;
use crate::tool::{CanonicalToolResult, ToolSpec};
use bytes::Bytes;
use thiserror::Error;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum ExchangeInputPolicy {
SendAndFinish,
SendAndRetain,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct EncodedExchange {
pub bytes: Bytes,
pub required_input_dialect: DialectDescriptor,
pub input_policy: ExchangeInputPolicy,
}
#[derive(Clone, Debug)]
pub struct InitialEncodeRequest<'a> {
pub transaction_id: &'a TransactionId,
pub exchange_id: &'a ExchangeId,
pub input: &'a CanonicalInput,
pub config: &'a EffectiveConfig,
pub tools: &'a [ToolSpec],
}
#[derive(Clone, Debug, PartialEq)]
pub struct ContinuationContext {
messages: Vec<CanonicalMessage>,
}
impl ContinuationContext {
pub fn try_new(messages: Vec<CanonicalMessage>) -> Result<Self, EncodingError> {
if messages.is_empty() {
return Err(EncodingError::EmptyContinuationContext);
}
Ok(Self { messages })
}
pub fn messages(&self) -> &[CanonicalMessage] {
&self.messages
}
}
#[derive(Clone, Debug)]
pub struct ToolContinuationEncodeRequest<'a> {
pub transaction_id: &'a TransactionId,
pub exchange_id: &'a ExchangeId,
pub context: &'a ContinuationContext,
pub results: &'a [CanonicalToolResult],
pub config: &'a EffectiveConfig,
pub tools: &'a [ToolSpec],
}
pub trait OutboundDialectEncoder: Send + Sync {
fn encode_initial(
&self,
request: InitialEncodeRequest<'_>,
) -> Result<EncodedExchange, EncodingError>;
fn encode_tool_continuation(
&self,
request: ToolContinuationEncodeRequest<'_>,
) -> Result<EncodedExchange, EncodingError>;
}
#[derive(Clone, Debug, Error, PartialEq, Eq)]
pub enum EncodingError {
#[error("continuation context must be non-empty")]
EmptyContinuationContext,
#[error("unsupported encode option: {0}")]
Unsupported(&'static str),
#[error("encoded exchange exceeds bound")]
LimitExceeded,
#[error("invalid configuration for encoder")]
InvalidConfiguration,
#[error("input not representable in dialect")]
UnrepresentableInput,
}