elizaos_plugin_code/actions/
read_file.rs1use 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}