pforge_config/
types.rs

1use serde::{Deserialize, Serialize};
2use std::collections::HashMap;
3
4/// Root configuration structure
5#[derive(Debug, Clone, Deserialize, Serialize)]
6#[serde(deny_unknown_fields)]
7pub struct ForgeConfig {
8    pub forge: ForgeMetadata,
9    #[serde(default)]
10    pub tools: Vec<ToolDef>,
11    #[serde(default)]
12    pub resources: Vec<ResourceDef>,
13    #[serde(default)]
14    pub prompts: Vec<PromptDef>,
15    #[serde(default)]
16    pub state: Option<StateDef>,
17}
18
19#[derive(Debug, Clone, Deserialize, Serialize)]
20pub struct ForgeMetadata {
21    pub name: String,
22    pub version: String,
23    #[serde(default = "default_transport")]
24    pub transport: TransportType,
25    #[serde(default)]
26    pub optimization: OptimizationLevel,
27}
28
29#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
30#[serde(rename_all = "lowercase")]
31pub enum TransportType {
32    Stdio,
33    Sse,
34    #[serde(rename = "websocket")]
35    WebSocket,
36}
37
38#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
39#[serde(rename_all = "lowercase")]
40pub enum OptimizationLevel {
41    Debug,
42    Release,
43}
44
45#[derive(Debug, Clone, Deserialize, Serialize)]
46#[serde(tag = "type", rename_all = "snake_case")]
47pub enum ToolDef {
48    Native {
49        name: String,
50        description: String,
51        handler: HandlerRef,
52        params: ParamSchema,
53        #[serde(default)]
54        timeout_ms: Option<u64>,
55    },
56    Cli {
57        name: String,
58        description: String,
59        command: String,
60        args: Vec<String>,
61        #[serde(default)]
62        cwd: Option<String>,
63        #[serde(default)]
64        env: HashMap<String, String>,
65        #[serde(default)]
66        stream: bool,
67    },
68    Http {
69        name: String,
70        description: String,
71        endpoint: String,
72        method: HttpMethod,
73        #[serde(default)]
74        auth: Option<AuthConfig>,
75        #[serde(default)]
76        headers: HashMap<String, String>,
77    },
78    Pipeline {
79        name: String,
80        description: String,
81        steps: Vec<PipelineStep>,
82    },
83}
84
85impl ToolDef {
86    pub fn name(&self) -> &str {
87        match self {
88            ToolDef::Native { name, .. } => name,
89            ToolDef::Cli { name, .. } => name,
90            ToolDef::Http { name, .. } => name,
91            ToolDef::Pipeline { name, .. } => name,
92        }
93    }
94}
95
96#[derive(Debug, Clone, Deserialize, Serialize)]
97pub struct HandlerRef {
98    pub path: String,
99    #[serde(default)]
100    pub inline: Option<String>,
101}
102
103#[derive(Debug, Clone, Deserialize, Serialize)]
104pub struct ParamSchema {
105    #[serde(flatten)]
106    pub fields: HashMap<String, ParamType>,
107}
108
109#[derive(Debug, Clone, Deserialize, Serialize)]
110#[serde(untagged)]
111pub enum ParamType {
112    Simple(SimpleType),
113    Complex {
114        #[serde(rename = "type")]
115        ty: SimpleType,
116        #[serde(default)]
117        required: bool,
118        #[serde(default)]
119        default: Option<serde_json::Value>,
120        #[serde(default)]
121        description: Option<String>,
122        #[serde(default)]
123        validation: Option<Validation>,
124    },
125}
126
127#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
128#[serde(rename_all = "lowercase")]
129pub enum SimpleType {
130    String,
131    Integer,
132    Float,
133    Boolean,
134    Array,
135    Object,
136}
137
138#[derive(Debug, Clone, Deserialize, Serialize)]
139pub struct Validation {
140    #[serde(default)]
141    pub min: Option<f64>,
142    #[serde(default)]
143    pub max: Option<f64>,
144    #[serde(default)]
145    pub pattern: Option<String>,
146    #[serde(default)]
147    pub min_length: Option<usize>,
148    #[serde(default)]
149    pub max_length: Option<usize>,
150}
151
152#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
153#[serde(rename_all = "UPPERCASE")]
154pub enum HttpMethod {
155    Get,
156    Post,
157    Put,
158    Delete,
159    Patch,
160}
161
162#[derive(Debug, Clone, Deserialize, Serialize)]
163#[serde(tag = "type", rename_all = "lowercase")]
164pub enum AuthConfig {
165    Bearer { token: String },
166    Basic { username: String, password: String },
167    ApiKey { key: String, header: String },
168}
169
170#[derive(Debug, Clone, Deserialize, Serialize)]
171pub struct PipelineStep {
172    pub tool: String,
173    #[serde(default)]
174    pub input: Option<serde_json::Value>,
175    #[serde(default)]
176    pub output_var: Option<String>,
177    #[serde(default)]
178    pub condition: Option<String>,
179    #[serde(default)]
180    pub error_policy: ErrorPolicy,
181}
182
183#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
184#[serde(rename_all = "snake_case")]
185pub enum ErrorPolicy {
186    FailFast,
187    Continue,
188}
189
190#[derive(Debug, Clone, Deserialize, Serialize)]
191pub struct ResourceDef {
192    pub uri_template: String,
193    pub handler: HandlerRef,
194    #[serde(default)]
195    pub supports: Vec<ResourceOperation>,
196}
197
198#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
199#[serde(rename_all = "lowercase")]
200pub enum ResourceOperation {
201    Read,
202    Write,
203    Subscribe,
204}
205
206#[derive(Debug, Clone, Deserialize, Serialize)]
207pub struct PromptDef {
208    pub name: String,
209    pub description: String,
210    pub template: String,
211    #[serde(default)]
212    pub arguments: HashMap<String, ParamType>,
213}
214
215#[derive(Debug, Clone, Deserialize, Serialize)]
216pub struct StateDef {
217    pub backend: StateBackend,
218    pub path: String,
219    #[serde(default)]
220    pub options: HashMap<String, serde_json::Value>,
221}
222
223#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
224#[serde(rename_all = "lowercase")]
225pub enum StateBackend {
226    Sled,
227    Memory,
228}
229
230fn default_transport() -> TransportType {
231    TransportType::Stdio
232}
233
234impl Default for OptimizationLevel {
235    fn default() -> Self {
236        Self::Debug
237    }
238}
239
240impl Default for ErrorPolicy {
241    fn default() -> Self {
242        Self::FailFast
243    }
244}