Skip to main content

ggen_transport/
lib.rs

1pub mod a2a;
2pub mod error;
3pub mod origin;
4pub mod session;
5pub mod streaming;
6
7use async_trait::async_trait;
8use bytes::Bytes;
9use serde::{Deserialize, Serialize};
10
11pub use error::{Result, TransportError};
12pub use origin::{Origin, OriginValidator};
13pub use session::{ResumeCursor, Session, SessionId, SessionManager};
14pub use streaming::{MessageStream, StreamBuilder, StreamControl, StreamMessage, StreamSender};
15
16#[derive(Debug, Clone, Serialize, Deserialize)]
17pub struct TransportConfig {
18    pub session_ttl_seconds: i64,
19    pub stream_buffer_size: usize,
20    pub max_message_size: usize,
21    pub allowed_origins: Vec<String>,
22    pub enable_compression: bool,
23}
24
25impl Default for TransportConfig {
26    fn default() -> Self {
27        Self {
28            session_ttl_seconds: 3600,
29            stream_buffer_size: 100,
30            max_message_size: 1024 * 1024,
31            allowed_origins: vec![],
32            enable_compression: false,
33        }
34    }
35}
36
37#[async_trait]
38pub trait Transport: Send + Sync {
39    async fn connect(&mut self, endpoint: &str) -> Result<()>;
40    async fn disconnect(&mut self) -> Result<()>;
41    async fn send(&mut self, data: Bytes) -> Result<()>;
42    async fn receive(&mut self) -> Result<Bytes>;
43    async fn is_connected(&self) -> bool;
44}
45
46#[async_trait]
47pub trait StreamingTransport: Transport {
48    async fn create_stream(
49        &mut self, session_id: SessionId,
50    ) -> Result<(StreamSender, MessageStream)>;
51    async fn resume_stream(
52        &mut self, cursor: ResumeCursor,
53    ) -> Result<(StreamSender, MessageStream)>;
54    async fn close_stream(&mut self, session_id: &SessionId) -> Result<()>;
55}
56
57pub struct TransportBuilder {
58    config: TransportConfig,
59}
60
61impl TransportBuilder {
62    pub fn new() -> Self {
63        Self {
64            config: TransportConfig::default(),
65        }
66    }
67
68    pub fn with_config(mut self, config: TransportConfig) -> Self {
69        self.config = config;
70        self
71    }
72
73    pub fn with_session_ttl(mut self, seconds: i64) -> Self {
74        self.config.session_ttl_seconds = seconds;
75        self
76    }
77
78    pub fn with_buffer_size(mut self, size: usize) -> Self {
79        self.config.stream_buffer_size = size;
80        self
81    }
82
83    pub fn with_allowed_origins(mut self, origins: Vec<String>) -> Self {
84        self.config.allowed_origins = origins;
85        self
86    }
87
88    pub fn enable_compression(mut self) -> Self {
89        self.config.enable_compression = true;
90        self
91    }
92
93    pub fn build_a2a(self, agent_id: String) -> a2a::A2aTransport {
94        let session_manager = SessionManager::new(self.config.session_ttl_seconds);
95        let origin_validator = if self.config.allowed_origins.is_empty() {
96            OriginValidator::allow_all()
97        } else {
98            OriginValidator::new(self.config.allowed_origins)
99        };
100        a2a::A2aTransport::new(agent_id, session_manager, origin_validator)
101    }
102}
103
104impl Default for TransportBuilder {
105    fn default() -> Self {
106        Self::new()
107    }
108}
109
110#[cfg(test)]
111mod tests {
112    use super::*;
113
114    #[test]
115    fn test_transport_config_default() {
116        let config = TransportConfig::default();
117        assert_eq!(config.session_ttl_seconds, 3600);
118        assert_eq!(config.stream_buffer_size, 100);
119        assert!(!config.enable_compression);
120    }
121
122    #[test]
123    fn test_transport_builder() {
124        let builder = TransportBuilder::new()
125            .with_session_ttl(7200)
126            .with_buffer_size(200)
127            .enable_compression();
128
129        assert_eq!(builder.config.session_ttl_seconds, 7200);
130        assert_eq!(builder.config.stream_buffer_size, 200);
131        assert!(builder.config.enable_compression);
132    }
133
134    #[test]
135    fn test_a2a_transport_creation() {
136        let builder = TransportBuilder::new();
137        let _transport = builder.build_a2a("test-agent".to_string());
138    }
139}