Skip to main content

elizaos_plugin_code/actions/
read_file.rs

1use async_trait::async_trait;
2use serde_json::Value;
3
4use crate::service::CoderService;
5use crate::{Action, ActionExample, ActionResult};
6
7pub struct ReadFileAction;
8
9#[async_trait]
10impl Action for ReadFileAction {
11    fn name(&self) -> &str {
12        "READ_FILE"
13    }
14
15    fn similes(&self) -> Vec<&str> {
16        vec![
17            "VIEW_FILE",
18            "OPEN_FILE",
19            "CAT_FILE",
20            "SHOW_FILE",
21            "GET_FILE",
22        ]
23    }
24
25    fn description(&self) -> &str {
26        "Read and return a file's contents."
27    }
28
29    async fn validate(&self, _message: &Value, _state: &Value) -> bool {
30        true
31    }
32
33    async fn handler(
34        &self,
35        message: &Value,
36        state: &Value,
37        service: Option<&mut CoderService>,
38    ) -> ActionResult {
39        let Some(svc) = service else {
40            return ActionResult {
41                success: false,
42                text: "Coder service is not available.".to_string(),
43                data: None,
44                error: Some("missing_service".to_string()),
45            };
46        };
47
48        let filepath = state
49            .get("filepath")
50            .and_then(|v| v.as_str())
51            .unwrap_or("")
52            .to_string();
53        if filepath.trim().is_empty() {
54            return ActionResult {
55                success: false,
56                text: "Missing filepath.".to_string(),
57                data: None,
58                error: Some("missing_filepath".to_string()),
59            };
60        }
61
62        let conv = message
63            .get("room_id")
64            .and_then(|v| v.as_str())
65            .or_else(|| message.get("agent_id").and_then(|v| v.as_str()))
66            .unwrap_or("default");
67
68        match svc.read_file(conv, &filepath).await {
69            Ok(content) => ActionResult {
70                success: true,
71                text: content,
72                data: None,
73                error: None,
74            },
75            Err(err) => ActionResult {
76                success: false,
77                text: err,
78                data: None,
79                error: Some("read_failed".to_string()),
80            },
81        }
82    }
83
84    fn examples(&self) -> Vec<ActionExample> {
85        vec![ActionExample {
86            user_message: "read src/lib.rs".to_string(),
87            agent_response: "Reading file…".to_string(),
88        }]
89    }
90}