use a2a_protocol_types::message::Message;
use a2a_protocol_types::task::{Task, TaskId};
use super::super::RequestHandler;
use crate::error::{ServerError, ServerResult};
impl RequestHandler {
pub(super) async fn resolve_context_id(&self, message: &Message) -> ServerResult<String> {
if let Some(ref ctx) = message.context_id {
Ok(ctx.0.clone())
} else if let Some(ref msg_task_id) = message.task_id {
match self.task_store.get(msg_task_id).await? {
Some(task) => Ok(task.context_id.0),
None => Err(ServerError::TaskNotFound(msg_task_id.clone())),
}
} else {
Ok(uuid::Uuid::new_v4().to_string())
}
}
pub(super) async fn resolve_task_id(
&self,
message: &Message,
stored_task: Option<&Task>,
) -> ServerResult<TaskId> {
let Some(ref msg_task_id) = message.task_id else {
return Ok(TaskId::new(uuid::Uuid::new_v4().to_string()));
};
let Some(stored) = stored_task else {
let exists = self.task_store.get(msg_task_id).await?.is_some();
if !exists {
return Err(ServerError::TaskNotFound(msg_task_id.clone()));
}
return Err(ServerError::InvalidParams(
"task_id exists but belongs to a different context".into(),
));
};
if msg_task_id != &stored.id {
return Err(ServerError::InvalidParams(
"message task_id does not match task found for context".into(),
));
}
if stored.status.state.is_terminal() {
return Err(ServerError::UnsupportedOperation(format!(
"task {} is in terminal state '{}' and cannot accept new messages",
stored.id, stored.status.state
)));
}
Ok(msg_task_id.clone())
}
}