Skip to main content

everruns_core/capabilities/
sample_data.rs

1//! Sample Data Capability
2//!
3//! A demonstration capability that shows how capabilities can mount files and
4//! directories in the session filesystem. This capability mounts sample data
5//! files that agents can read during execution.
6//!
7//! Mount points:
8//! - `/samples/users.json` - Sample user data
9//! - `/samples/config.yaml` - Sample configuration
10//! - `/samples/README.md` - Documentation about the sample files
11
12use super::{Capability, CapabilityStatus, MountDirectoryBuilder, MountPoint};
13
14/// Sample Data capability - demonstrates capability mounting
15pub struct SampleDataCapability;
16
17impl SampleDataCapability {
18    /// Sample users JSON data
19    const USERS_JSON: &'static str = r#"[
20  {
21    "id": 1,
22    "name": "Alice Johnson",
23    "email": "alice@example.com",
24    "role": "admin",
25    "active": true
26  },
27  {
28    "id": 2,
29    "name": "Bob Smith",
30    "email": "bob@example.com",
31    "role": "user",
32    "active": true
33  },
34  {
35    "id": 3,
36    "name": "Carol Davis",
37    "email": "carol@example.com",
38    "role": "user",
39    "active": false
40  }
41]"#;
42
43    /// Sample configuration YAML
44    const CONFIG_YAML: &'static str = r#"# Sample Configuration
45application:
46  name: "Sample App"
47  version: "1.0.0"
48  debug: false
49
50database:
51  host: localhost
52  port: 5432
53  name: sample_db
54  pool_size: 10
55
56features:
57  enable_notifications: true
58  enable_analytics: false
59  max_upload_size_mb: 50
60
61logging:
62  level: info
63  format: json
64"#;
65
66    /// README content
67    const README: &'static str = r#"# Sample Data Files
68
69This directory contains sample data files mounted by the Sample Data capability.
70
71## Available Files
72
73- `users.json` - A JSON array of sample user records with fields:
74  - `id`: Unique user identifier
75  - `name`: User's full name
76  - `email`: User's email address
77  - `role`: User role (admin/user)
78  - `active`: Whether the account is active
79
80- `config.yaml` - A sample YAML configuration file demonstrating:
81  - Application settings
82  - Database configuration
83  - Feature flags
84  - Logging settings
85
86## Usage
87
88These files are read-only and provided for demonstration purposes.
89You can read them using the file system tools to see examples of
90data formats commonly used in applications.
91
92## Notes
93
94- Files in this directory cannot be modified (read-only mount)
95- Use `read_file` tool to read the contents
96- Use `list_directory` to see available files
97"#;
98}
99
100impl Capability for SampleDataCapability {
101    fn id(&self) -> &str {
102        "sample_data"
103    }
104
105    fn name(&self) -> &str {
106        "Sample Data"
107    }
108
109    fn description(&self) -> &str {
110        "Mounts sample data files in the session filesystem for demonstration and testing. Includes example JSON, YAML, and documentation files."
111    }
112
113    fn status(&self) -> CapabilityStatus {
114        CapabilityStatus::Available
115    }
116
117    fn icon(&self) -> Option<&str> {
118        Some("database")
119    }
120
121    fn category(&self) -> Option<&str> {
122        Some("Data")
123    }
124
125    fn system_prompt_addition(&self) -> Option<&str> {
126        Some(
127            "Read-only sample files are mounted at `/samples` (`users.json`, `config.yaml`, `README.md`) for demos, tests, and templates.",
128        )
129    }
130
131    fn mounts(&self) -> Vec<MountPoint> {
132        let samples_dir = MountDirectoryBuilder::new()
133            .file("users.json", Self::USERS_JSON)
134            .file("config.yaml", Self::CONFIG_YAML)
135            .file("README.md", Self::README)
136            .build();
137
138        vec![MountPoint::readonly("/samples", samples_dir, self.id())]
139    }
140
141    fn dependencies(&self) -> Vec<&'static str> {
142        // Sample Data depends on Session File System for file operations
143        vec!["session_file_system"]
144    }
145
146    fn features(&self) -> Vec<&'static str> {
147        vec!["file_system"]
148    }
149}
150
151#[cfg(test)]
152mod tests {
153    use super::*;
154    use crate::capability_types::MountSource;
155
156    #[test]
157    fn test_capability_metadata() {
158        let cap = SampleDataCapability;
159        assert_eq!(cap.id(), "sample_data");
160        assert_eq!(cap.name(), "Sample Data");
161        assert_eq!(cap.status(), CapabilityStatus::Available);
162        assert_eq!(cap.icon(), Some("database"));
163        assert_eq!(cap.category(), Some("Data"));
164    }
165
166    #[test]
167    fn test_capability_has_system_prompt() {
168        let cap = SampleDataCapability;
169        let prompt = cap.system_prompt_addition().unwrap();
170        assert!(prompt.contains("/samples"));
171        assert!(prompt.contains("users.json"));
172        assert!(prompt.contains("config.yaml"));
173    }
174
175    #[test]
176    fn test_capability_has_no_tools() {
177        let cap = SampleDataCapability;
178        assert!(cap.tools().is_empty());
179    }
180
181    #[test]
182    fn test_capability_has_mounts() {
183        let cap = SampleDataCapability;
184        let mounts = cap.mounts();
185
186        assert_eq!(mounts.len(), 1);
187
188        let mount = &mounts[0];
189        assert_eq!(mount.path, "/samples");
190        assert!(mount.is_readonly());
191        assert_eq!(mount.capability_id, "sample_data");
192
193        // Check directory structure
194        match &mount.source {
195            MountSource::InlineDirectory { entries } => {
196                assert_eq!(entries.len(), 3);
197                assert!(entries.contains_key("users.json"));
198                assert!(entries.contains_key("config.yaml"));
199                assert!(entries.contains_key("README.md"));
200            }
201            _ => panic!("Expected InlineDirectory"),
202        }
203    }
204
205    #[test]
206    fn test_sample_users_json_is_valid() {
207        let json: serde_json::Value =
208            serde_json::from_str(SampleDataCapability::USERS_JSON).unwrap();
209        assert!(json.is_array());
210        let users = json.as_array().unwrap();
211        assert_eq!(users.len(), 3);
212    }
213
214    #[test]
215    fn test_sample_config_yaml_is_valid() {
216        // Just check it's not empty and looks like YAML
217        assert!(SampleDataCapability::CONFIG_YAML.contains("application:"));
218        assert!(SampleDataCapability::CONFIG_YAML.contains("database:"));
219    }
220
221    #[test]
222    fn test_capability_depends_on_file_system() {
223        let cap = SampleDataCapability;
224        let deps = cap.dependencies();
225        assert_eq!(deps.len(), 1);
226        assert_eq!(deps[0], "session_file_system");
227    }
228}