Skip to main content

rune_framework/
config.rs

1//! Configuration types for the Rune SDK.
2
3use std::collections::HashMap;
4
5/// Gate routing configuration for exposing a Rune as an HTTP endpoint.
6#[derive(Debug, Clone)]
7pub struct GateConfig {
8    /// HTTP path, e.g. "/translate".
9    pub path: String,
10    /// HTTP method. Defaults to "POST".
11    pub method: String,
12}
13
14impl GateConfig {
15    /// Create a new GateConfig with the given path and default method "POST".
16    pub fn new(path: impl Into<String>) -> Self {
17        Self {
18            path: path.into(),
19            method: "POST".into(),
20        }
21    }
22
23    /// Create a new GateConfig with path and method.
24    pub fn with_method(path: impl Into<String>, method: impl Into<String>) -> Self {
25        Self {
26            path: path.into(),
27            method: method.into(),
28        }
29    }
30}
31
32/// Configuration for declaring a Rune.
33#[derive(Debug, Clone)]
34pub struct RuneConfig {
35    /// Unique name of this Rune.
36    pub name: String,
37    /// Semantic version string. Defaults to "0.0.0".
38    pub version: String,
39    /// Human-readable description.
40    pub description: String,
41    /// JSON Schema for validating input (as serde_json::Value).
42    pub input_schema: Option<serde_json::Value>,
43    /// JSON Schema for validating output (as serde_json::Value).
44    pub output_schema: Option<serde_json::Value>,
45    /// Whether this Rune supports streaming responses.
46    pub supports_stream: bool,
47    /// Gate HTTP endpoint configuration.
48    pub gate: Option<GateConfig>,
49    /// Priority for load balancing (higher = preferred).
50    pub priority: i32,
51}
52
53impl Default for RuneConfig {
54    fn default() -> Self {
55        Self {
56            name: String::new(),
57            version: "0.0.0".into(),
58            description: String::new(),
59            input_schema: None,
60            output_schema: None,
61            supports_stream: false,
62            gate: None,
63            priority: 0,
64        }
65    }
66}
67
68impl RuneConfig {
69    /// Create a RuneConfig with the given name and defaults for all other fields.
70    pub fn new(name: impl Into<String>) -> Self {
71        Self {
72            name: name.into(),
73            ..Default::default()
74        }
75    }
76}
77
78/// A file attachment carried with a request or response.
79#[derive(Debug, Clone)]
80pub struct FileAttachment {
81    /// Original filename.
82    pub filename: String,
83    /// Raw file data.
84    pub data: bytes::Bytes,
85    /// MIME type string.
86    pub mime_type: String,
87}
88
89/// Configuration for the Caster instance.
90#[derive(Debug, Clone)]
91pub struct CasterConfig {
92    /// gRPC endpoint of the Rune Runtime. Default: "localhost:50070".
93    pub runtime: String,
94    /// API key for authentication.
95    pub key: Option<String>,
96    /// Unique identifier for this Caster instance. Auto-generated if None.
97    pub caster_id: Option<String>,
98    /// Maximum concurrent request handling. Default: 10.
99    pub max_concurrent: u32,
100    /// Heartbeat interval in seconds. Default: 10.0.
101    pub heartbeat_interval_secs: f64,
102    /// Initial reconnect delay in seconds. Default: 1.0.
103    pub reconnect_base_delay_secs: f64,
104    /// Maximum reconnect delay in seconds. Default: 30.0.
105    pub reconnect_max_delay_secs: f64,
106    /// Caster labels for metadata.
107    pub labels: HashMap<String, String>,
108    /// Optional auto-scaling policy for Pilot discovery and scaling metadata.
109    pub scale_policy: Option<ScalePolicy>,
110    /// Optional load report metadata included with health updates.
111    pub load_report: Option<LoadReport>,
112}
113
114impl Default for CasterConfig {
115    fn default() -> Self {
116        Self {
117            runtime: "localhost:50070".into(),
118            key: None,
119            caster_id: None,
120            max_concurrent: 10,
121            heartbeat_interval_secs: 10.0,
122            reconnect_base_delay_secs: 1.0,
123            reconnect_max_delay_secs: 30.0,
124            labels: HashMap::new(),
125            scale_policy: None,
126            load_report: None,
127        }
128    }
129}
130
131/// Scaling metadata advertised to the Runtime and local Pilot.
132#[derive(Debug, Clone)]
133pub struct ScalePolicy {
134    pub group: String,
135    pub scale_up_threshold: f64,
136    pub scale_down_threshold: f64,
137    pub sustained_secs: u64,
138    pub min_replicas: u32,
139    pub max_replicas: u32,
140    pub spawn_command: String,
141    pub shutdown_signal: String,
142}
143
144impl ScalePolicy {
145    pub fn new(group: impl Into<String>, spawn_command: impl Into<String>) -> Self {
146        Self {
147            group: group.into(),
148            spawn_command: spawn_command.into(),
149            ..Default::default()
150        }
151    }
152}
153
154impl Default for ScalePolicy {
155    fn default() -> Self {
156        Self {
157            group: String::new(),
158            scale_up_threshold: 0.8,
159            scale_down_threshold: 0.2,
160            sustained_secs: 30,
161            min_replicas: 1,
162            max_replicas: 1,
163            spawn_command: String::new(),
164            shutdown_signal: "SIGTERM".into(),
165        }
166    }
167}
168
169/// Additional load telemetry sent with health reports.
170#[derive(Debug, Clone, Default)]
171pub struct LoadReport {
172    /// Explicit pressure override. When `None`, computed automatically
173    /// from `active_requests / max_concurrent`.
174    pub pressure: Option<f64>,
175    pub metrics: HashMap<String, f64>,
176}