WriteFile writes content to path, creating parent dirs. Errors return as part of the output string (bash convention), never as a Go error, so the model sees a write failure the way it sees a non-zero bash exit.
(path, content string)
| 10 | // part of the output string (bash convention), never as a Go error, so the |
| 11 | // model sees a write failure the way it sees a non-zero bash exit. |
| 12 | func WriteFile(path, content string) string { |
| 13 | if path == "" { |
| 14 | return "(empty path)" |
| 15 | } |
| 16 | // Refuse an existing non-regular target: open(2) with O_WRONLY on a FIFO |
| 17 | // with no reader blocks forever, leaking the tool goroutine past Ctrl+C |
| 18 | // (which cancels the turn but can't unblock the open). Stat never blocks; |
| 19 | // directories fall through to os.WriteFile's immediate EISDIR. |
| 20 | if info, err := os.Stat(path); err == nil && !info.Mode().IsRegular() && !info.IsDir() { |
| 21 | return fmt.Sprintf("(write error: %s is not a regular file)", path) |
| 22 | } |
| 23 | if dir := filepath.Dir(path); dir != "." { |
| 24 | if err := os.MkdirAll(dir, 0o755); err != nil { |
| 25 | return fmt.Sprintf("(mkdir error: %v)", err) |
| 26 | } |
| 27 | } |
| 28 | if err := os.WriteFile(path, []byte(content), 0o644); err != nil { |
| 29 | return fmt.Sprintf("(write error: %v)", err) |
| 30 | } |
| 31 | return fmt.Sprintf("wrote %d bytes to %s", len(content), path) |
| 32 | } |
| 33 | |
| 34 | // WriteFileSchema is the OpenAI tool definition for write_file. The description |
| 35 | // steers the model away from bash heredocs (shell-quoting failure mode) for |
no outgoing calls