monoloop_contracts/
encoder.rs1use crate::config::EffectiveConfig;
4use crate::dialect::DialectDescriptor;
5use crate::id::{ExchangeId, TransactionId};
6use crate::input::CanonicalInput;
7use crate::input::CanonicalMessage;
8use crate::tool::{CanonicalToolResult, ToolSpec};
9use bytes::Bytes;
10use thiserror::Error;
11
12#[derive(Clone, Copy, Debug, PartialEq, Eq)]
14pub enum ExchangeInputPolicy {
15 SendAndFinish,
17 SendAndRetain,
19}
20
21#[derive(Clone, Debug, PartialEq, Eq)]
23pub struct EncodedExchange {
24 pub bytes: Bytes,
26 pub required_input_dialect: DialectDescriptor,
28 pub input_policy: ExchangeInputPolicy,
30}
31
32#[derive(Clone, Debug)]
34pub struct InitialEncodeRequest<'a> {
35 pub transaction_id: &'a TransactionId,
37 pub exchange_id: &'a ExchangeId,
39 pub input: &'a CanonicalInput,
41 pub config: &'a EffectiveConfig,
43 pub tools: &'a [ToolSpec],
45}
46
47#[derive(Clone, Debug, PartialEq)]
49pub struct ContinuationContext {
50 messages: Vec<CanonicalMessage>,
51}
52
53impl ContinuationContext {
54 pub fn try_new(messages: Vec<CanonicalMessage>) -> Result<Self, EncodingError> {
56 if messages.is_empty() {
57 return Err(EncodingError::EmptyContinuationContext);
58 }
59 Ok(Self { messages })
60 }
61
62 pub fn messages(&self) -> &[CanonicalMessage] {
64 &self.messages
65 }
66}
67
68#[derive(Clone, Debug)]
70pub struct ToolContinuationEncodeRequest<'a> {
71 pub transaction_id: &'a TransactionId,
73 pub exchange_id: &'a ExchangeId,
75 pub context: &'a ContinuationContext,
77 pub results: &'a [CanonicalToolResult],
79 pub config: &'a EffectiveConfig,
81 pub tools: &'a [ToolSpec],
83}
84
85pub trait OutboundDialectEncoder: Send + Sync {
87 fn encode_initial(
89 &self,
90 request: InitialEncodeRequest<'_>,
91 ) -> Result<EncodedExchange, EncodingError>;
92
93 fn encode_tool_continuation(
95 &self,
96 request: ToolContinuationEncodeRequest<'_>,
97 ) -> Result<EncodedExchange, EncodingError>;
98}
99
100#[derive(Clone, Debug, Error, PartialEq, Eq)]
102pub enum EncodingError {
103 #[error("continuation context must be non-empty")]
105 EmptyContinuationContext,
106 #[error("unsupported encode option: {0}")]
108 Unsupported(&'static str),
109 #[error("encoded exchange exceeds bound")]
111 LimitExceeded,
112 #[error("invalid configuration for encoder")]
114 InvalidConfiguration,
115 #[error("input not representable in dialect")]
117 UnrepresentableInput,
118}