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    /// Declarative cron schedules synced on deploy
102    #[serde(default, skip_serializing_if = "Vec::is_empty")]
103    pub crons: Vec<CronDefinition>,
104}
105
106#[derive(Debug, Clone, Serialize, Deserialize)]
107#[serde(rename_all = "camelCase")]
108pub struct CronDefinition {
109    pub name: String,
110    pub schedule: String,
111    #[serde(default, skip_serializing_if = "Option::is_none")]
112    pub timezone: Option<String>,
113    #[serde(default, skip_serializing_if = "Option::is_none")]
114    pub method: Option<String>,
115    #[serde(default, skip_serializing_if = "Option::is_none")]
116    pub payload: Option<JsonValue>,
117    #[serde(default = "default_overlap_policy")]
118    pub overlap_policy: String,
119}
120
121fn default_overlap_policy() -> String { "skip".into() }
122
123#[derive(Debug, Clone, Serialize, Deserialize)]
124#[serde(rename_all = "camelCase")]
125pub struct TriggerConfig {
126    pub app_id: String,
127    pub entity: String,
128    pub on: Vec<String>,
129}
130
131fn default_version() -> String {
132    "0.0.1".to_string()
133}
134
135#[derive(Debug, Clone, Serialize, Deserialize)]
136#[serde(rename_all = "camelCase")]
137pub struct EntityContract {
138    pub entity_name: String,
139    pub fields: Vec<FieldContract>,
140    #[serde(default, skip_serializing_if = "Option::is_none")]
141    pub identity_kind: Option<String>,
142    #[serde(default, skip_serializing_if = "Option::is_none")]
143    pub identity_key: Option<String>,
144}
145
146#[derive(Debug, Clone, Serialize, Deserialize)]
147#[serde(rename_all = "camelCase")]
148pub struct FieldContract {
149    pub name: String,
150    #[serde(rename = "type")]
151    pub field_type: String,
152    #[serde(default)]
153    pub required: bool,
154    #[serde(default)]
155    pub default_value: Option<JsonValue>,
156    #[serde(default)]
157    pub enum_values: Option<Vec<String>>,
158    #[serde(default)]
159    pub references: Option<FieldReference>,
160    #[serde(default)]
161    pub is_primary_key: Option<bool>,
162    #[serde(default, skip_serializing_if = "Option::is_none")]
163    pub on_delete: Option<OnDeletePolicy>,
164}
165
166#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
167#[serde(rename_all = "snake_case")]
168pub enum OnDeletePolicy {
169    Cascade,
170    Restrict,
171    SetNull,
172}
173
174#[derive(Debug, Clone, Serialize, Deserialize)]
175pub struct FieldReference {
176    pub entity: String,
177    pub field: String,
178}
179
180#[derive(Debug, Clone, Serialize, Deserialize)]
181#[serde(rename_all = "camelCase")]
182pub struct InstalledApp {
183    pub id: String,
184    pub name: String,
185    pub version: String,
186    pub status: String,
187    #[serde(rename = "type", default)]
188    pub app_type: AppType,
189    pub entities: Vec<String>,
190    #[serde(default)]
191    pub has_frontend: bool,
192}
193
194#[derive(Debug, Clone, Serialize, Deserialize)]
195#[serde(rename_all = "camelCase")]
196pub struct PermissionsContract {
197    #[serde(default)]
198    pub permissions: Vec<PermissionDeclaration>,
199}
200
201#[derive(Debug, Clone, Serialize, Deserialize)]
202pub struct PermissionDeclaration {
203    pub key: String,
204    #[serde(default)]
205    pub description: String,
206}
207
208#[derive(Debug, Clone, Serialize, Deserialize)]
209pub struct SchemaChange {
210    pub entity: String,
211    pub change_type: String,
212    pub column: String,
213    pub detail: Option<String>,
214}
215
216#[derive(Debug, Clone, Serialize, Deserialize)]
217pub struct SchemaVerification {
218    pub compliant: bool,
219    pub changes: Vec<SchemaChange>,
220}
221
222#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
223#[serde(rename_all = "lowercase")]
224pub enum ProviderType {
225    Anthropic,
226    OpenAI,
227    Bedrock,
228}
229
230#[derive(Debug, Clone, Serialize, Deserialize)]
231#[serde(rename_all = "camelCase")]
232pub struct AgentDefinition {
233    pub name: String,
234    #[serde(default)]
235    pub description: Option<String>,
236    #[serde(default)]
237    pub system_prompt: Option<String>,
238    #[serde(default)]
239    pub memory: Option<AgentMemory>,
240    #[serde(default)]
241    pub limits: Option<AgentLimits>,
242    #[serde(default)]
243    pub supervision: Option<SupervisionConfig>,
244}
245
246#[derive(Debug, Clone, Serialize, Deserialize)]
247pub struct AgentMemory {
248    pub enabled: bool,
249}
250
251#[derive(Debug, Clone, Serialize, Deserialize)]
252#[serde(rename_all = "camelCase")]
253pub struct AgentLimits {
254    #[serde(default)]
255    pub max_turns: Option<u32>,
256    #[serde(default)]
257    pub max_context_tokens: Option<u64>,
258    #[serde(default)]
259    pub keep_recent_messages: Option<u32>,
260}
261
262#[derive(Debug, Clone, Serialize, Deserialize)]
263#[serde(rename_all = "camelCase")]
264pub struct SupervisionConfig {
265    pub mode: SupervisionMode,
266    #[serde(default)]
267    pub policies: Vec<SupervisionPolicy>,
268}
269
270#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
271#[serde(rename_all = "lowercase")]
272pub enum SupervisionMode {
273    Autonomous,
274    Supervised,
275    Strict,
276}
277
278#[derive(Debug, Clone, Serialize, Deserialize)]
279#[serde(rename_all = "camelCase")]
280pub struct SupervisionPolicy {
281    pub action: String,
282    #[serde(default)]
283    pub entity: Option<String>,
284    #[serde(default)]
285    pub requires: Option<String>,
286    #[serde(default)]
287    pub rate_limit: Option<RateLimit>,
288}
289
290#[derive(Debug, Clone, Serialize, Deserialize)]
291pub struct RateLimit {
292    pub max: u32,
293    pub window: String,
294}
295
296#[derive(Debug, Clone, Serialize, Deserialize)]
297#[serde(rename_all = "camelCase")]
298pub struct McpServerConfig {
299    pub name: String,
300    pub transport: McpTransport,
301}
302
303#[derive(Debug, Clone, Serialize, Deserialize)]
304#[serde(tag = "type", rename_all = "lowercase")]
305pub enum McpTransport {
306    Stdio { command: String, #[serde(default)] args: Vec<String> },
307    Http { url: String, #[serde(default)] headers: std::collections::HashMap<String, String> },
308    #[deprecated = "use Http"]
309    Sse { url: String, #[serde(default)] headers: std::collections::HashMap<String, String> },
310    Cli { install: String },
311}
312
313#[derive(Debug, Clone, Serialize, Deserialize)]
314#[serde(rename_all = "camelCase")]
315pub struct ToolDescriptor {
316    pub name: String,
317    pub description: String,
318    pub input_schema: serde_json::Value,
319}
320
321#[derive(Debug, Clone, Serialize, Deserialize)]
322#[serde(rename_all = "lowercase")]
323pub enum Role {
324    User,
325    Assistant,
326}
327
328#[derive(Debug, Clone, Serialize, Deserialize)]
329#[serde(tag = "type", rename_all = "snake_case")]
330pub enum ContentBlock {
331    Text { text: String },
332    ToolUse { id: String, name: String, input: serde_json::Value },
333    ToolResult { tool_use_id: String, content: String, #[serde(default)] is_error: bool },
334}
335
336#[derive(Debug, Clone, Serialize, Deserialize)]
337pub struct ChatMessage {
338    pub role: Role,
339    pub content: Vec<ContentBlock>,
340}
341
342#[derive(Debug, Clone, Serialize, Deserialize)]
343pub struct ToolDef {
344    pub name: String,
345    pub description: String,
346    pub input_schema: serde_json::Value,
347}
348