Skip to main content

rootcx_types/
lib.rs

1use serde::{Deserialize, Serialize};
2use serde_json::Value as JsonValue;
3
4#[derive(Debug, Clone, Serialize, Deserialize)]
5pub struct OsStatus {
6    pub runtime: RuntimeStatus,
7    pub postgres: PostgresStatus,
8    pub forge: ForgeStatus,
9}
10
11impl OsStatus {
12    pub fn offline() -> Self {
13        Self {
14            runtime: RuntimeStatus { version: String::new(), state: ServiceState::Offline },
15            postgres: PostgresStatus { state: ServiceState::Offline, port: None, data_dir: None },
16            forge: ForgeStatus { state: ServiceState::Offline, port: None },
17        }
18    }
19}
20
21#[derive(Debug, Clone, Serialize, Deserialize)]
22pub struct ForgeStatus {
23    pub state: ServiceState,
24    pub port: Option<u16>,
25}
26
27#[derive(Debug, Clone, Serialize, Deserialize)]
28pub struct RuntimeStatus {
29    pub version: String,
30    pub state: ServiceState,
31}
32
33#[derive(Debug, Clone, Serialize, Deserialize)]
34pub struct PostgresStatus {
35    pub state: ServiceState,
36    pub port: Option<u16>,
37    pub data_dir: Option<String>,
38}
39
40#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
41#[serde(rename_all = "lowercase")]
42pub enum ServiceState {
43    Online,
44    Offline,
45    Starting,
46    Stopping,
47    Error,
48}
49
50#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
51#[serde(rename_all = "lowercase")]
52pub enum AppType {
53    #[default]
54    App,
55    Integration,
56    Agent,
57}
58
59#[derive(Debug, Clone, Serialize, Deserialize)]
60#[serde(rename_all = "camelCase")]
61pub struct ActionDefinition {
62    pub id: String,
63    pub name: String,
64    #[serde(default)]
65    pub description: String,
66    #[serde(default)]
67    pub input_schema: Option<JsonValue>,
68    #[serde(default)]
69    pub output_schema: Option<JsonValue>,
70}
71
72#[derive(Debug, Clone, Serialize, Deserialize)]
73#[serde(rename_all = "camelCase")]
74pub struct AppManifest {
75    pub app_id: String,
76    pub name: String,
77    #[serde(default = "default_version")]
78    pub version: String,
79    #[serde(default)]
80    pub description: String,
81    #[serde(default, rename = "type")]
82    pub app_type: AppType,
83    #[serde(default)]
84    pub permissions: Option<PermissionsContract>,
85    #[serde(default)]
86    pub data_contract: Vec<EntityContract>,
87    #[serde(default, skip_serializing_if = "Vec::is_empty")]
88    pub actions: Vec<ActionDefinition>,
89    #[serde(default, skip_serializing_if = "Option::is_none")]
90    pub config_schema: Option<JsonValue>,
91    #[serde(default, skip_serializing_if = "Option::is_none")]
92    pub user_auth: Option<JsonValue>,
93    #[serde(default, skip_serializing_if = "Vec::is_empty")]
94    pub webhooks: Vec<String>,
95    /// Free-form usage instructions surfaced to AI via list_integrations tool
96    #[serde(default, skip_serializing_if = "Option::is_none")]
97    pub instructions: Option<String>,
98    /// Trigger: auto-invoke this agent on entity events
99    #[serde(default, skip_serializing_if = "Option::is_none")]
100    pub trigger: Option<TriggerConfig>,
101}
102
103#[derive(Debug, Clone, Serialize, Deserialize)]
104#[serde(rename_all = "camelCase")]
105pub struct TriggerConfig {
106    pub app_id: String,
107    pub entity: String,
108    pub on: Vec<String>,
109}
110
111fn default_version() -> String {
112    "0.0.1".to_string()
113}
114
115#[derive(Debug, Clone, Serialize, Deserialize)]
116#[serde(rename_all = "camelCase")]
117pub struct EntityContract {
118    pub entity_name: String,
119    pub fields: Vec<FieldContract>,
120    #[serde(default, skip_serializing_if = "Option::is_none")]
121    pub identity_kind: Option<String>,
122    #[serde(default, skip_serializing_if = "Option::is_none")]
123    pub identity_key: Option<String>,
124}
125
126#[derive(Debug, Clone, Serialize, Deserialize)]
127#[serde(rename_all = "camelCase")]
128pub struct FieldContract {
129    pub name: String,
130    #[serde(rename = "type")]
131    pub field_type: String,
132    #[serde(default)]
133    pub required: bool,
134    #[serde(default)]
135    pub default_value: Option<JsonValue>,
136    #[serde(default)]
137    pub enum_values: Option<Vec<String>>,
138    #[serde(default)]
139    pub references: Option<FieldReference>,
140    #[serde(default)]
141    pub is_primary_key: Option<bool>,
142}
143
144#[derive(Debug, Clone, Serialize, Deserialize)]
145pub struct FieldReference {
146    pub entity: String,
147    pub field: String,
148}
149
150#[derive(Debug, Clone, Serialize, Deserialize)]
151#[serde(rename_all = "camelCase")]
152pub struct InstalledApp {
153    pub id: String,
154    pub name: String,
155    pub version: String,
156    pub status: String,
157    #[serde(rename = "type", default)]
158    pub app_type: AppType,
159    pub entities: Vec<String>,
160    #[serde(default)]
161    pub has_frontend: bool,
162}
163
164#[derive(Debug, Clone, Serialize, Deserialize)]
165#[serde(rename_all = "camelCase")]
166pub struct PermissionsContract {
167    #[serde(default)]
168    pub permissions: Vec<PermissionDeclaration>,
169}
170
171#[derive(Debug, Clone, Serialize, Deserialize)]
172pub struct PermissionDeclaration {
173    pub key: String,
174    #[serde(default)]
175    pub description: String,
176}
177
178#[derive(Debug, Clone, Serialize, Deserialize)]
179pub struct SchemaChange {
180    pub entity: String,
181    pub change_type: String,
182    pub column: String,
183    pub detail: Option<String>,
184    #[serde(default)]
185    pub safe: bool,
186}
187
188#[derive(Debug, Clone, Serialize, Deserialize)]
189pub struct SchemaVerification {
190    pub compliant: bool,
191    pub changes: Vec<SchemaChange>,
192}
193
194#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
195#[serde(rename_all = "lowercase")]
196pub enum ProviderType {
197    Anthropic,
198    OpenAI,
199    Bedrock,
200}
201
202#[derive(Debug, Clone, Serialize, Deserialize)]
203#[serde(rename_all = "camelCase")]
204pub struct AgentDefinition {
205    pub name: String,
206    #[serde(default)]
207    pub description: Option<String>,
208    #[serde(default)]
209    pub system_prompt: Option<String>,
210    #[serde(default)]
211    pub memory: Option<AgentMemory>,
212    #[serde(default)]
213    pub limits: Option<AgentLimits>,
214    #[serde(default)]
215    pub supervision: Option<SupervisionConfig>,
216}
217
218#[derive(Debug, Clone, Serialize, Deserialize)]
219pub struct AgentMemory {
220    pub enabled: bool,
221}
222
223#[derive(Debug, Clone, Serialize, Deserialize)]
224#[serde(rename_all = "camelCase")]
225pub struct AgentLimits {
226    #[serde(default)]
227    pub max_turns: Option<u32>,
228    #[serde(default)]
229    pub max_context_tokens: Option<u64>,
230    #[serde(default)]
231    pub keep_recent_messages: Option<u32>,
232}
233
234#[derive(Debug, Clone, Serialize, Deserialize)]
235#[serde(rename_all = "camelCase")]
236pub struct SupervisionConfig {
237    pub mode: SupervisionMode,
238    #[serde(default)]
239    pub policies: Vec<SupervisionPolicy>,
240}
241
242#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
243#[serde(rename_all = "lowercase")]
244pub enum SupervisionMode {
245    Autonomous,
246    Supervised,
247    Strict,
248}
249
250#[derive(Debug, Clone, Serialize, Deserialize)]
251#[serde(rename_all = "camelCase")]
252pub struct SupervisionPolicy {
253    pub action: String,
254    #[serde(default)]
255    pub entity: Option<String>,
256    #[serde(default)]
257    pub requires: Option<String>,
258    #[serde(default)]
259    pub rate_limit: Option<RateLimit>,
260}
261
262#[derive(Debug, Clone, Serialize, Deserialize)]
263pub struct RateLimit {
264    pub max: u32,
265    pub window: String,
266}
267
268#[derive(Debug, Clone, Serialize, Deserialize)]
269#[serde(rename_all = "camelCase")]
270pub struct McpServerConfig {
271    pub name: String,
272    pub transport: McpTransport,
273}
274
275#[derive(Debug, Clone, Serialize, Deserialize)]
276#[serde(tag = "type", rename_all = "lowercase")]
277pub enum McpTransport {
278    Stdio { command: String, #[serde(default)] args: Vec<String> },
279    Http { url: String, #[serde(default)] headers: std::collections::HashMap<String, String> },
280    #[deprecated = "use Http"]
281    Sse { url: String, #[serde(default)] headers: std::collections::HashMap<String, String> },
282    Cli { install: String },
283}
284
285#[derive(Debug, Clone, Serialize, Deserialize)]
286#[serde(rename_all = "camelCase")]
287pub struct ToolDescriptor {
288    pub name: String,
289    pub description: String,
290    pub input_schema: serde_json::Value,
291}
292
293#[derive(Debug, Clone, Serialize, Deserialize)]
294#[serde(rename_all = "lowercase")]
295pub enum Role {
296    User,
297    Assistant,
298}
299
300#[derive(Debug, Clone, Serialize, Deserialize)]
301#[serde(tag = "type", rename_all = "snake_case")]
302pub enum ContentBlock {
303    Text { text: String },
304    ToolUse { id: String, name: String, input: serde_json::Value },
305    ToolResult { tool_use_id: String, content: String, #[serde(default)] is_error: bool },
306}
307
308#[derive(Debug, Clone, Serialize, Deserialize)]
309pub struct ChatMessage {
310    pub role: Role,
311    pub content: Vec<ContentBlock>,
312}
313
314#[derive(Debug, Clone, Serialize, Deserialize)]
315pub struct ToolDef {
316    pub name: String,
317    pub description: String,
318    pub input_schema: serde_json::Value,
319}
320