Skip to main content

a2a_rs/port/
message_handler.rs

1//! Message handling port definitions
2
3use async_trait::async_trait;
4
5use crate::{
6    domain::{A2AError, Message, Task},
7    port::RequestContext,
8};
9
10#[async_trait]
11/// An async trait for handling message processing operations
12pub trait AsyncMessageHandler: Send + Sync {
13    /// Process a message for a specific task.
14    ///
15    /// `ctx` is what the transport knows about the request — the session id the
16    /// caller supplied and the principal it authenticated. A handler that keeps
17    /// per-caller state reads [`RequestContext::caller`]; one that does not can
18    /// ignore it.
19    async fn process_message(
20        &self,
21        task_id: &str,
22        message: &Message,
23        ctx: &RequestContext,
24    ) -> Result<Task, A2AError>;
25
26    /// Validate a message before processing
27    async fn validate_message(&self, message: &Message) -> Result<(), A2AError> {
28        // Default implementation - can be overridden
29        if message.parts.is_empty() {
30            return Err(A2AError::ValidationError {
31                field: "message.parts".to_string(),
32                message: "Message must contain at least one part".to_string(),
33            });
34        }
35        Ok(())
36    }
37
38    /// Transform a message before processing (e.g., for content filtering)
39    async fn transform_message(&self, message: Message) -> Result<Message, A2AError> {
40        // Default implementation - pass through unchanged
41        Ok(message)
42    }
43
44    /// Handle message processing with validation and transformation
45    async fn handle_message_flow(
46        &self,
47        task_id: &str,
48        message: Message,
49        ctx: &RequestContext,
50    ) -> Result<Task, A2AError> {
51        // Validate the message
52        self.validate_message(&message).await?;
53
54        // Transform the message if needed
55        let transformed_message = self.transform_message(message).await?;
56
57        // Process the message
58        self.process_message(task_id, &transformed_message, ctx)
59            .await
60    }
61}