pub mod client;
pub mod server;
use serde::{Deserialize, Serialize};
use serde_json::Value;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct JsonRpcRequest {
pub jsonrpc: String,
pub id: Value,
pub method: String,
pub params: Value,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct JsonRpcResponse {
pub jsonrpc: String,
pub id: Value,
#[serde(skip_serializing_if = "Option::is_none")]
pub result: Option<Value>,
#[serde(skip_serializing_if = "Option::is_none")]
pub error: Option<JsonRpcError>,
}
impl JsonRpcResponse {
pub fn ok(id: Value, result: Value) -> Self {
Self {
jsonrpc: "2.0".to_owned(),
id,
result: Some(result),
error: None,
}
}
pub fn err(id: Value, code: i32, message: impl Into<String>) -> Self {
Self {
jsonrpc: "2.0".to_owned(),
id,
result: None,
error: Some(JsonRpcError {
code,
message: message.into(),
data: None,
}),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct JsonRpcError {
pub code: i32,
pub message: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub data: Option<Value>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct AgentCard {
pub protocol_version: String,
pub name: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
pub url: String,
pub capabilities: AgentCapabilities,
pub default_input_modes: Vec<String>,
pub default_output_modes: Vec<String>,
pub skills: Vec<AgentSkill>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct AgentCapabilities {
pub streaming: bool,
pub push_notifications: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct AgentSkill {
pub id: String,
pub name: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
pub input_modes: Vec<String>,
pub output_modes: Vec<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct A2aTask {
pub id: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub session_id: Option<String>,
pub status: A2aTaskStatus,
pub message: A2aMessage,
#[serde(skip_serializing_if = "Option::is_none")]
pub artifacts: Option<Vec<A2aArtifact>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub metadata: Option<Value>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct A2aTaskStatus {
pub state: TaskState,
#[serde(skip_serializing_if = "Option::is_none")]
pub message: Option<A2aMessage>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "lowercase")]
pub enum TaskState {
Submitted,
Working,
Completed,
Failed,
Canceled,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct A2aMessage {
pub role: String, pub parts: Vec<A2aPart>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "lowercase")]
pub enum A2aPart {
Text { text: String },
Data { data: Value },
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct A2aArtifact {
pub parts: Vec<A2aPart>,
#[serde(skip_serializing_if = "Option::is_none")]
pub index: Option<u32>,
}
#[derive(Debug, Clone, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct TaskSendParams {
pub id: String,
pub message: A2aMessage,
#[serde(skip_serializing_if = "Option::is_none")]
pub session_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub metadata: Option<Value>,
}