MCPcopy Create free account
hub / github.com/c4pt0r/pie / execute

Method execute

crates/coding-agent/src/tools/edit.rs:23–90  ·  view source on GitHub ↗
(
        &self,
        _id: &str,
        params: Value,
        _cancel: CancellationToken,
        _on_update: Option<AgentToolUpdate>,
    )

Source from the content-addressed store, hash-verified

21 }
22
23 async fn execute(
24 &self,
25 _id: &str,
26 params: Value,
27 _cancel: CancellationToken,
28 _on_update: Option<AgentToolUpdate>,
29 ) -> Result<AgentToolResult, AgentToolError> {
30 let path = params
31 .get("path")
32 .and_then(|v| v.as_str())
33 .ok_or_else(|| AgentToolError::from("missing `path`"))?;
34 let old = params
35 .get("old_string")
36 .and_then(|v| v.as_str())
37 .ok_or_else(|| AgentToolError::from("missing `old_string`"))?;
38 let new_ = params
39 .get("new_string")
40 .and_then(|v| v.as_str())
41 .ok_or_else(|| AgentToolError::from("missing `new_string`"))?;
42 let replace_all = params
43 .get("replace_all")
44 .and_then(|v| v.as_bool())
45 .unwrap_or(false);
46 if old == new_ {
47 return Err(AgentToolError::from(
48 "old_string must differ from new_string",
49 ));
50 }
51
52 // Serialize the whole read-modify-write per file so a concurrent `edit`/`write` on the
53 // same path cannot read a stale body and clobber the other's change. See
54 // `tools::fs_guard`.
55 let occurrences = crate::tools::fs_guard::with_file_lock(
56 std::path::Path::new(path),
57 || async {
58 let body = tokio::fs::read_to_string(path)
59 .await
60 .map_err(|e| AgentToolError::from(format!("read {path}: {e}")))?;
61
62 let occurrences = body.matches(old).count();
63 if occurrences == 0 {
64 return Err(AgentToolError::from(format!(
65 "old_string not found in {path}"
66 )));
67 }
68 if occurrences > 1 && !replace_all {
69 return Err(AgentToolError::from(format!(
70 "old_string matched {occurrences} times in {path}; pass replace_all=true to replace every occurrence, or include more surrounding context to make it unique"
71 )));
72 }
73
74 let new_body = if replace_all {
75 body.replace(old, new_)
76 } else {
77 body.replacen(old, new_, 1)
78 };
79 tokio::fs::write(path, new_body.as_bytes())
80 .await

Callers 3

rejects_ambiguous_matchFunction · 0.45

Calls 6

writeFunction · 0.85
render_diff_previewFunction · 0.85
countMethod · 0.80
getMethod · 0.65
as_strMethod · 0.45
matchesMethod · 0.45

Tested by

no test coverage detected