Skip to main content

feagi_api/v1/
agent_dtos.rs

1// Copyright 2025 Neuraville Inc.
2// Licensed under the Apache License, Version 2.0
3
4//! Agent API DTOs - Exact port from Python schemas
5
6use serde::{Deserialize, Serialize};
7use std::collections::HashMap;
8use utoipa::ToSchema;
9
10/// Agent registration request
11#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
12pub struct AgentRegistrationRequest {
13    /// Type of agent (e.g., "brain_visualizer", "video_agent")
14    pub agent_type: String,
15
16    /// Unique identifier for the agent
17    pub agent_id: String,
18
19    /// Port the agent is listening on for data
20    pub agent_data_port: u16,
21
22    /// Version of the agent software
23    pub agent_version: String,
24
25    /// Version of the controller
26    pub controller_version: String,
27
28    /// Agent capabilities (sensory, motor, visualization, etc.)
29    pub capabilities: HashMap<String, serde_json::Value>,
30
31    /// Optional: Agent IP address (extracted from request if not provided)
32    #[serde(skip_serializing_if = "Option::is_none")]
33    pub agent_ip: Option<String>,
34
35    /// Optional: Additional metadata
36    #[serde(skip_serializing_if = "Option::is_none")]
37    pub metadata: Option<HashMap<String, serde_json::Value>>,
38
39    /// Optional: Transport the agent chose to use ("zmq", "websocket", "shm", etc.)
40    #[serde(skip_serializing_if = "Option::is_none")]
41    pub chosen_transport: Option<String>,
42}
43
44/// Transport configuration for an agent (from PNS)
45#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
46pub struct TransportConfig {
47    pub transport_type: String,
48    pub enabled: bool,
49    pub ports: HashMap<String, u16>,
50    pub host: String,
51}
52
53/// Agent registration response
54#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
55pub struct AgentRegistrationResponse {
56    pub status: String,
57    pub message: String,
58    pub success: bool,
59
60    #[serde(skip_serializing_if = "Option::is_none")]
61    pub transport: Option<HashMap<String, serde_json::Value>>,
62
63    #[serde(skip_serializing_if = "Option::is_none")]
64    pub rates: Option<HashMap<String, HashMap<String, f64>>>,
65
66    // FEAGI 2.0: Multi-transport support
67    #[serde(skip_serializing_if = "Option::is_none")]
68    pub transports: Option<Vec<TransportConfig>>,
69
70    #[serde(skip_serializing_if = "Option::is_none")]
71    pub recommended_transport: Option<String>,
72
73    #[serde(skip_serializing_if = "Option::is_none")]
74    pub shm_paths: Option<HashMap<String, String>>,
75
76    /// Cortical area availability status for agent operations
77    pub cortical_areas: serde_json::Value,
78}
79
80/// Heartbeat request
81#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
82pub struct HeartbeatRequest {
83    pub agent_id: String,
84}
85
86/// Heartbeat response
87#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
88pub struct HeartbeatResponse {
89    pub message: String,
90    pub success: bool,
91}
92
93/// Agent list response
94#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
95pub struct AgentListResponse {
96    /// List of agent IDs
97    #[serde(flatten)]
98    pub agent_ids: Vec<String>,
99}
100
101/// Agent properties response
102#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
103pub struct AgentPropertiesResponse {
104    pub agent_name: String,
105    pub agent_type: String,
106    pub agent_ip: String,
107    pub agent_data_port: u16,
108    pub agent_router_address: String,
109    pub agent_version: String,
110    pub controller_version: String,
111    pub capabilities: HashMap<String, serde_json::Value>,
112    #[serde(skip_serializing_if = "Option::is_none")]
113    pub chosen_transport: Option<String>,
114}
115
116/// Agent capabilities summary (optionally includes device registrations)
117#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
118pub struct AgentCapabilitiesSummary {
119    pub agent_name: String,
120    pub capabilities: HashMap<String, serde_json::Value>,
121    #[serde(skip_serializing_if = "Option::is_none")]
122    pub device_registrations: Option<serde_json::Value>,
123}
124
125/// Query parameters for bulk agent capabilities lookup
126#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
127pub struct AgentCapabilitiesAllQuery {
128    /// Filter by agent type (exact match)
129    #[serde(skip_serializing_if = "Option::is_none")]
130    pub agent_type: Option<String>,
131    /// Filter by capability key(s), comma-separated
132    #[serde(skip_serializing_if = "Option::is_none")]
133    pub capability: Option<String>,
134    /// Include device registration payloads per agent
135    #[serde(skip_serializing_if = "Option::is_none")]
136    pub include_device_registrations: Option<bool>,
137}
138
139/// Agent deregistration request
140#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
141pub struct AgentDeregistrationRequest {
142    pub agent_id: String,
143}
144
145/// Success response
146#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
147pub struct SuccessResponse {
148    pub message: String,
149    #[serde(skip_serializing_if = "Option::is_none")]
150    pub success: Option<bool>,
151}
152
153/// Manual stimulation request
154#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
155pub struct ManualStimulationRequest {
156    /// Map of cortical area IDs to lists of coordinates [[x, y, z], ...]
157    pub stimulation_payload: HashMap<String, Vec<Vec<i32>>>,
158}
159
160/// Manual stimulation response
161#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
162pub struct ManualStimulationResponse {
163    pub success: bool,
164    pub total_coordinates: usize,
165    pub successful_areas: usize,
166    pub failed_areas: Vec<String>,
167    #[serde(skip_serializing_if = "Option::is_none")]
168    pub error: Option<String>,
169}
170
171/// Device registration export response
172///
173/// Contains the complete device registration configuration including
174/// sensor and motor device registrations, encoder/decoder properties,
175/// and feedback configurations.
176#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
177pub struct DeviceRegistrationExportResponse {
178    /// Device registration configuration as JSON
179    /// This matches the format from ConnectorAgent::get_device_registration_json
180    pub device_registrations: serde_json::Value,
181    /// Agent ID this configuration belongs to
182    pub agent_id: String,
183}
184
185/// Device registration import request
186///
187/// Contains the device registration configuration to import.
188/// This will replace all existing device registrations for the agent.
189#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
190pub struct DeviceRegistrationImportRequest {
191    /// Device registration configuration as JSON
192    /// This matches the format expected by ConnectorAgent::set_device_registrations_from_json
193    pub device_registrations: serde_json::Value,
194}
195
196/// Device registration import response
197#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
198pub struct DeviceRegistrationImportResponse {
199    pub success: bool,
200    pub message: String,
201    pub agent_id: String,
202}