mirror of
https://github.com/patriceckhart/zot.git
synced 2026-06-27 05:46:34 +02:00
66 lines
1.8 KiB
Go
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
|
|
}
|