MCPcopy Create free account
hub / github.com/atomicdotdev/atomic / exec_read_file

Method exec_read_file

atomic-repository/src/ai/tools.rs:881–942  ·  view source on GitHub ↗
(&self, args: &serde_json::Value)

Source from the content-addressed store, hash-verified

879 }
880
881 fn exec_read_file(&self, args: &serde_json::Value) -> Result<String, String> {
882 let path_str = args["path"]
883 .as_str()
884 .ok_or("missing required parameter: path")?;
885
886 // Prevent path traversal.
887 if path_str.contains("..") {
888 return Err("path must not contain '..'".into());
889 }
890
891 let full_path = self.root.join(path_str);
892 let content = std::fs::read_to_string(&full_path)
893 .map_err(|e| format!("cannot read {path_str}: {e}"))?;
894
895 // Optionally slice by line range.
896 let start_line = args["start_line"].as_u64().map(|n| n as usize);
897 let end_line = args["end_line"].as_u64().map(|n| n as usize);
898
899 let has_line_range = start_line.is_some() || end_line.is_some();
900 let total_lines = content.lines().count();
901
902 // If no line range and file is large, return a structured outline.
903 // The LLM should use list_entities or code_search to find the
904 // right line range first.
905 if !has_line_range && content.len() > READ_FILE_PREVIEW_THRESHOLD {
906 return Ok(build_file_outline(path_str, &content, total_lines));
907 }
908
909 let output = match (start_line, end_line) {
910 (Some(s), Some(e)) => {
911 let s = s.saturating_sub(1); // 1-based to 0-based
912 content
913 .lines()
914 .skip(s)
915 .take(e.saturating_sub(s))
916 .collect::<Vec<_>>()
917 .join("\n")
918 }
919 (Some(s), None) => {
920 let s = s.saturating_sub(1);
921 content
922 .lines()
923 .skip(s)
924 .take(200) // cap open-ended reads at 200 lines
925 .collect::<Vec<_>>()
926 .join("\n")
927 }
928 (None, Some(e)) => content.lines().take(e).collect::<Vec<_>>().join("\n"),
929 (None, None) => content,
930 };
931
932 // Final cap on output size.
933 if output.len() > MAX_READ_FILE_BYTES {
934 Ok(format!(
935 "{}\n\n... truncated ({} bytes total)",
936 &output[..MAX_READ_FILE_BYTES],
937 output.len()
938 ))

Callers 1

executeMethod · 0.80

Calls 8

build_file_outlineFunction · 0.85
as_u64Method · 0.80
skipMethod · 0.80
as_strMethod · 0.45
containsMethod · 0.45
countMethod · 0.45
linesMethod · 0.45
lenMethod · 0.45

Tested by

no test coverage detected