mirror of
https://github.com/sipeed/picoclaw.git
synced 2026-07-28 01:27:58 +00:00
fix(tools): stop write_file from coaching destructive overwrite (#3150)
The overwrite guard error ("Set overwrite=true to replace") steered the
model to clobber files like MEMORY.md. Reword write_file's description,
overwrite param, and guard error to prefer append_file/edit_file.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -882,7 +882,7 @@ func (t *WriteFileTool) Name() string {
|
||||
}
|
||||
|
||||
func (t *WriteFileTool) Description() string {
|
||||
return "Write content to a file. Content is written byte-for-byte after argument decoding. Standard JSON escaping applies: \\n for newline and \\\\n for a literal backslash-n sequence. If the file already exists, you must set overwrite=true to replace it."
|
||||
return "Write content to a file, replacing any existing content. Content is written byte-for-byte after argument decoding. Standard JSON escaping applies: \\n for newline and \\\\n for a literal backslash-n sequence. If the file already exists you must set overwrite=true, which replaces the ENTIRE file. To add to or change part of an existing file without losing its current contents, use append_file or edit_file instead."
|
||||
}
|
||||
|
||||
func (t *WriteFileTool) Parameters() map[string]any {
|
||||
@@ -899,7 +899,7 @@ func (t *WriteFileTool) Parameters() map[string]any {
|
||||
},
|
||||
"overwrite": map[string]any{
|
||||
"type": "boolean",
|
||||
"description": "Must be set to true to overwrite an existing file.",
|
||||
"description": "Set to true to replace an existing file in full. This discards the file's current contents — to preserve them, use append_file or edit_file instead of write_file.",
|
||||
"default": false,
|
||||
},
|
||||
},
|
||||
@@ -923,7 +923,10 @@ func (t *WriteFileTool) Execute(ctx context.Context, args map[string]any) *ToolR
|
||||
if !overwrite {
|
||||
if _, err := t.fs.Open(path); err == nil {
|
||||
return ErrorResult(
|
||||
fmt.Sprintf("file: %s already exists. Set overwrite=true to replace.", path),
|
||||
fmt.Sprintf(
|
||||
"file: %s already exists. To add to it or change part of it without losing the current contents, use append_file or edit_file. Only set overwrite=true if you intend to replace the entire file.",
|
||||
path,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -250,6 +250,9 @@ func TestFilesystemTool_WriteFile_OverwriteDefaultBlocked(t *testing.T) {
|
||||
assert.True(t, result.IsError, "expected error when overwriting without overwrite=true")
|
||||
assert.Contains(t, result.ForLLM, "already exists")
|
||||
assert.Contains(t, result.ForLLM, "overwrite=true")
|
||||
// The guard must steer toward non-destructive tools rather than only coaching overwrite.
|
||||
assert.Contains(t, result.ForLLM, "append_file")
|
||||
assert.Contains(t, result.ForLLM, "edit_file")
|
||||
|
||||
// Original content must be untouched
|
||||
data, err := os.ReadFile(testFile)
|
||||
|
||||
Reference in New Issue
Block a user