zot/internal/agent/tools/write.go
2026-04-17 20:36:38 +02:00

66 lines
1.8 KiB
Go

package tools
import (
"context"
"encoding/json"
"fmt"
"os"
"path/filepath"
"github.com/patriceckhart/zot/internal/core"
"github.com/patriceckhart/zot/internal/provider"
)
// WriteTool writes content to a file, creating parent directories.
type WriteTool struct {
CWD string
Sandbox *Sandbox
}
type writeArgs struct {
Path string `json:"path"`
Content string `json:"content"`
}
const writeSchema = `{
"type":"object",
"properties":{
"path":{"type":"string","description":"Path to the file to write (relative or absolute)"},
"content":{"type":"string","description":"File contents. Overwrites any existing file."}
},
"required":["path","content"],
"additionalProperties":false
}`
func (t *WriteTool) Name() string { return "write" }
func (t *WriteTool) Description() string {
return "Write content to a file. Creates parent directories. Overwrites existing files."
}
func (t *WriteTool) Schema() json.RawMessage { return json.RawMessage(writeSchema) }
func (t *WriteTool) Execute(ctx context.Context, raw json.RawMessage, progress func(string)) (core.ToolResult, error) {
var a writeArgs
if err := json.Unmarshal(raw, &a); err != nil {
return core.ToolResult{}, fmt.Errorf("invalid args: %w", err)
}
if a.Path == "" {
return core.ToolResult{}, fmt.Errorf("path is required")
}
path := resolvePath(t.CWD, a.Path)
if err := t.Sandbox.CheckPath(path); err != nil {
return core.ToolResult{}, err
}
if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {
return core.ToolResult{}, err
}
if err := os.WriteFile(path, []byte(a.Content), 0o644); err != nil {
return core.ToolResult{}, err
}
msg := fmt.Sprintf("wrote %d bytes to %s", len(a.Content), a.Path)
return core.ToolResult{
Content: []provider.Content{provider.TextBlock{Text: msg}},
Details: map[string]any{"path": path, "bytes": len(a.Content)},
}, nil
}