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 #[serde(default, skip_serializing_if = "Option::is_none")]
97 pub instructions: Option<String>,
98 #[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}
185
186#[derive(Debug, Clone, Serialize, Deserialize)]
187pub struct SchemaVerification {
188 pub compliant: bool,
189 pub changes: Vec<SchemaChange>,
190}
191
192#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
193#[serde(rename_all = "lowercase")]
194pub enum ProviderType {
195 Anthropic,
196 OpenAI,
197 Bedrock,
198}
199
200#[derive(Debug, Clone, Serialize, Deserialize)]
201#[serde(rename_all = "camelCase")]
202pub struct AgentDefinition {
203 pub name: String,
204 #[serde(default)]
205 pub description: Option<String>,
206 #[serde(default)]
207 pub system_prompt: Option<String>,
208 #[serde(default)]
209 pub memory: Option<AgentMemory>,
210 #[serde(default)]
211 pub limits: Option<AgentLimits>,
212 #[serde(default)]
213 pub supervision: Option<SupervisionConfig>,
214}
215
216#[derive(Debug, Clone, Serialize, Deserialize)]
217pub struct AgentMemory {
218 pub enabled: bool,
219}
220
221#[derive(Debug, Clone, Serialize, Deserialize)]
222#[serde(rename_all = "camelCase")]
223pub struct AgentLimits {
224 #[serde(default)]
225 pub max_turns: Option<u32>,
226 #[serde(default)]
227 pub max_context_tokens: Option<u64>,
228 #[serde(default)]
229 pub keep_recent_messages: Option<u32>,
230}
231
232#[derive(Debug, Clone, Serialize, Deserialize)]
233#[serde(rename_all = "camelCase")]
234pub struct SupervisionConfig {
235 pub mode: SupervisionMode,
236 #[serde(default)]
237 pub policies: Vec<SupervisionPolicy>,
238}
239
240#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
241#[serde(rename_all = "lowercase")]
242pub enum SupervisionMode {
243 Autonomous,
244 Supervised,
245 Strict,
246}
247
248#[derive(Debug, Clone, Serialize, Deserialize)]
249#[serde(rename_all = "camelCase")]
250pub struct SupervisionPolicy {
251 pub action: String,
252 #[serde(default)]
253 pub entity: Option<String>,
254 #[serde(default)]
255 pub requires: Option<String>,
256 #[serde(default)]
257 pub rate_limit: Option<RateLimit>,
258}
259
260#[derive(Debug, Clone, Serialize, Deserialize)]
261pub struct RateLimit {
262 pub max: u32,
263 pub window: String,
264}
265
266#[derive(Debug, Clone, Serialize, Deserialize)]
267#[serde(rename_all = "camelCase")]
268pub struct McpServerConfig {
269 pub name: String,
270 pub transport: McpTransport,
271}
272
273#[derive(Debug, Clone, Serialize, Deserialize)]
274#[serde(tag = "type", rename_all = "lowercase")]
275pub enum McpTransport {
276 Stdio { command: String, #[serde(default)] args: Vec<String> },
277 Http { url: String, #[serde(default)] headers: std::collections::HashMap<String, String> },
278 #[deprecated = "use Http"]
279 Sse { url: String, #[serde(default)] headers: std::collections::HashMap<String, String> },
280 Cli { install: String },
281}
282
283#[derive(Debug, Clone, Serialize, Deserialize)]
284#[serde(rename_all = "camelCase")]
285pub struct ToolDescriptor {
286 pub name: String,
287 pub description: String,
288 pub input_schema: serde_json::Value,
289}
290
291#[derive(Debug, Clone, Serialize, Deserialize)]
292#[serde(rename_all = "lowercase")]
293pub enum Role {
294 User,
295 Assistant,
296}
297
298#[derive(Debug, Clone, Serialize, Deserialize)]
299#[serde(tag = "type", rename_all = "snake_case")]
300pub enum ContentBlock {
301 Text { text: String },
302 ToolUse { id: String, name: String, input: serde_json::Value },
303 ToolResult { tool_use_id: String, content: String, #[serde(default)] is_error: bool },
304}
305
306#[derive(Debug, Clone, Serialize, Deserialize)]
307pub struct ChatMessage {
308 pub role: Role,
309 pub content: Vec<ContentBlock>,
310}
311
312#[derive(Debug, Clone, Serialize, Deserialize)]
313pub struct ToolDef {
314 pub name: String,
315 pub description: String,
316 pub input_schema: serde_json::Value,
317}
318