agent_kernel/registry_wire.rs
1//! Wire-level structures for communicating with the MXP Nexus registry over MXP.
2
3use std::collections::HashMap;
4use std::net::SocketAddr;
5
6use chrono::{DateTime, Utc};
7use serde::{Deserialize, Serialize};
8
9/// Registration payload emitted by agents.
10#[derive(Debug, Clone, Serialize, Deserialize)]
11pub struct RegisterRequest {
12 /// Unique identifier for the agent (UUID string representation).
13 pub id: String,
14 /// Human readable agent name.
15 pub name: String,
16 /// Capabilities advertised by the agent.
17 pub capabilities: Vec<String>,
18 /// MXP endpoint where the agent is reachable.
19 pub address: SocketAddr,
20 /// Additional metadata such as version, description, tags, etc.
21 #[serde(default)]
22 pub metadata: HashMap<String, String>,
23}
24
25/// Successful registration acknowledgement.
26#[derive(Debug, Clone, Serialize, Deserialize)]
27pub struct RegisterResponse {
28 /// Indicates whether the registration succeeded.
29 pub success: bool,
30 /// Agent identifier acknowledged by the registry.
31 pub agent_id: String,
32 /// Informational message.
33 pub message: String,
34}
35
36/// Agent discovery request payload.
37#[derive(Debug, Clone, Serialize, Deserialize)]
38pub struct DiscoverRequest {
39 /// Capability filter.
40 pub capability: String,
41}
42
43/// Snapshot of an agent returned by discovery calls.
44#[derive(Debug, Clone, Serialize, Deserialize)]
45pub struct AgentRecord {
46 /// Agent identifier.
47 pub id: String,
48 /// Human readable name.
49 pub name: String,
50 /// Semantic version string.
51 pub version: String,
52 /// Optional description.
53 #[serde(default, skip_serializing_if = "Option::is_none")]
54 pub description: Option<String>,
55 /// Capability identifiers.
56 pub capabilities: Vec<String>,
57 /// Optional tags associated with the agent.
58 #[serde(default, skip_serializing_if = "Vec::is_empty")]
59 pub tags: Vec<String>,
60 /// MXP endpoint address.
61 pub address: SocketAddr,
62 /// Reported health status.
63 pub status: AgentStatus,
64 /// Timestamp of the last heartbeat observed by the registry.
65 pub last_heartbeat: DateTime<Utc>,
66 /// Timestamp the agent was first registered.
67 pub registered_at: DateTime<Utc>,
68}
69
70/// Discovery response payload.
71#[derive(Debug, Clone, Serialize, Deserialize)]
72pub struct DiscoverResponse {
73 /// Capability that was queried.
74 pub capability: String,
75 /// Matching agents.
76 pub agents: Vec<AgentRecord>,
77 /// Count of returned agents.
78 pub count: usize,
79}
80
81/// Heartbeat request emitted by agents.
82#[derive(Debug, Clone, Serialize, Deserialize)]
83pub struct HeartbeatRequest {
84 /// Identifier of the agent sending the heartbeat.
85 pub agent_id: String,
86}
87
88/// Heartbeat acknowledgement returned to agents.
89#[derive(Debug, Clone, Serialize, Deserialize)]
90pub struct HeartbeatResponse {
91 /// Indicates whether the heartbeat succeeded.
92 pub success: bool,
93 /// Signals that the agent must re-register.
94 pub needs_register: bool,
95 /// Agent identifier associated with the heartbeat.
96 pub agent_id: String,
97 /// Registry timestamp recorded for the heartbeat.
98 pub timestamp: DateTime<Utc>,
99 /// Optional informational message.
100 #[serde(default, skip_serializing_if = "Option::is_none")]
101 pub message: Option<String>,
102}
103
104/// Error payload used for protocol error responses.
105#[derive(Debug, Clone, Serialize, Deserialize)]
106pub struct ErrorResponse {
107 /// Human readable error message.
108 pub error: String,
109 /// Machine readable error code.
110 pub code: String,
111}
112
113/// Simplified agent status representation.
114#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
115pub enum AgentStatus {
116 /// Agent is healthy and online.
117 Online,
118 /// Agent missed heartbeats and is considered offline.
119 Offline,
120 /// Agent is online but reporting degraded health.
121 Degraded,
122}