The write_file tool
Reading is easy. Writing is where coding agents start to feel real. The model can now emit a path and a content string, and your Go function creates or overwrites the file. We will keep the spec as narrow as possible on purpose.
{
Spec: ToolSpec{
Type: "function",
Function: FunctionSpec{
Name: "write_file",
Description: "Create or overwrite a file with the given text content.",
Parameters: map[string]any{
"type": "object",
"properties": map[string]any{
"path": map[string]any{"type": "string", "description": "Relative path."},
"content": map[string]any{"type": "string", "description": "Full file content."},
},
"required": []string{"path", "content"},
},
},
},
Run: runWriteFile,
},Narrow surface area. Two fields, both required. No append mode, no binary, no partial patches. A smaller spec is a safer spec.
func runWriteFile(args string) (string, error) {
var in struct {
Path string `json:"path"`
Content string `json:"content"`
}
if err := json.Unmarshal([]byte(args), &in); err != nil {
return "", fmt.Errorf("write_file: invalid args: %w", err)
}
if in.Path == "" {
return "", fmt.Errorf("write_file: path is required")
}
clean := filepath.Clean(in.Path)
if err := os.MkdirAll(filepath.Dir(clean), 0o755); err != nil {
return "", fmt.Errorf("write_file mkdir: %w", err)
}
if err := os.WriteFile(clean, []byte(in.Content), 0o644); err != nil {
return "", fmt.Errorf("write_file: %w", err)
}
return fmt.Sprintf("wrote %d bytes to %s", len(in.Content), clean), nil
}os.MkdirAll creates missing parent directories so the model can create new folders. Permissions stay sane at 0755 for dirs and 0644 for files.
Quiz: Quiz
Loading practice…