Skip to main content

bamboo_agent/agent/llm/protocol/
mod.rs

1//! Protocol conversion traits and types.
2//!
3//! This module defines the hub-and-spoke conversion architecture where all provider-specific
4//! types convert to/from internal types (agent_core).
5//!
6//! # Architecture
7//!
8//! ```text
9//! Provider Types (OpenAI, Anthropic, etc.)
10//!     ↕
11//! Internal Types (crate::agent::core::Message, ToolSchema)
12//! ```
13
14mod anthropic;
15mod errors;
16pub mod gemini;
17mod openai;
18
19pub use anthropic::AnthropicProtocol;
20pub use errors::{ProtocolError, ProtocolResult};
21pub use gemini::GeminiProtocol;
22pub use openai::OpenAIProtocol;
23
24use crate::agent::core::Message;
25
26/// Trait for converting provider-specific types to internal types.
27///
28/// This is the "spoke → hub" conversion.
29pub trait FromProvider<T>: Sized {
30    /// Convert from provider-specific type to internal type.
31    fn from_provider(value: T) -> ProtocolResult<Self>;
32}
33
34/// Trait for converting internal types to provider-specific types.
35///
36/// This is the "hub → spoke" conversion.
37pub trait ToProvider<T>: Sized {
38    /// Convert from internal type to provider-specific type.
39    fn to_provider(&self) -> ProtocolResult<T>;
40}
41
42/// Batch conversion for multiple messages.
43pub trait FromProviderBatch<T>: Sized {
44    fn from_provider_batch(values: Vec<T>) -> ProtocolResult<Vec<Self>>;
45}
46
47/// Batch conversion for multiple messages.
48pub trait ToProviderBatch<T>: Sized {
49    fn to_provider_batch(&self) -> ProtocolResult<Vec<T>>;
50}
51
52// Implement batch conversion for specific types
53
54impl FromProviderBatch<crate::agent::llm::api::models::ChatMessage> for Message {
55    fn from_provider_batch(
56        values: Vec<crate::agent::llm::api::models::ChatMessage>,
57    ) -> ProtocolResult<Vec<Self>> {
58        values.into_iter().map(Self::from_provider).collect()
59    }
60}
61
62impl ToProviderBatch<crate::agent::llm::api::models::ChatMessage> for Vec<Message> {
63    fn to_provider_batch(
64        &self,
65    ) -> ProtocolResult<Vec<crate::agent::llm::api::models::ChatMessage>> {
66        self.iter().map(|msg| msg.to_provider()).collect()
67    }
68}
69
70#[cfg(test)]
71mod tests {
72    use super::*;
73
74    #[test]
75    fn test_trait_bounds() {
76        // This test just verifies the trait design compiles
77        fn assert_from_provider<T, U>()
78        where
79            T: FromProvider<U>,
80        {
81        }
82
83        fn assert_to_provider<T, U>()
84        where
85            T: ToProvider<U>,
86        {
87        }
88
89        // Ensure at least one concrete spoke type satisfies the bounds.
90        assert_from_provider::<Message, crate::agent::llm::api::models::ChatMessage>();
91        assert_to_provider::<Message, crate::agent::llm::api::models::ChatMessage>();
92    }
93}