Chore: tool description update

This commit is contained in:
Grail Finder
2025-11-26 21:28:50 +03:00
parent 6cc04f4302
commit 05cf4b8749

236
tools.go
View File

@@ -6,13 +6,13 @@ import (
"fmt" "fmt"
"gf-lt/extra" "gf-lt/extra"
"gf-lt/models" "gf-lt/models"
"io"
"os"
"os/exec"
"regexp" "regexp"
"strconv" "strconv"
"strings" "strings"
"time" "time"
"os"
"io"
"os/exec"
) )
var ( var (
@@ -367,160 +367,160 @@ func fileList(args map[string]string) []byte {
// Helper functions for file operations // Helper functions for file operations
func readStringFromFile(filename string) (string, error) { func readStringFromFile(filename string) (string, error) {
data, err := os.ReadFile(filename) data, err := os.ReadFile(filename)
if err != nil { if err != nil {
return "", err return "", err
} }
return string(data), nil return string(data), nil
} }
func writeStringToFile(filename string, data string) error { func writeStringToFile(filename string, data string) error {
return os.WriteFile(filename, []byte(data), 0644) return os.WriteFile(filename, []byte(data), 0644)
} }
func appendStringToFile(filename string, data string) error { func appendStringToFile(filename string, data string) error {
file, err := os.OpenFile(filename, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) file, err := os.OpenFile(filename, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil { if err != nil {
return err return err
} }
defer file.Close() defer file.Close()
_, err = file.WriteString(data) _, err = file.WriteString(data)
return err return err
} }
func removeFile(filename string) error { func removeFile(filename string) error {
return os.Remove(filename) return os.Remove(filename)
} }
func moveFile(src, dst string) error { func moveFile(src, dst string) error {
// First try with os.Rename (works within same filesystem) // First try with os.Rename (works within same filesystem)
if err := os.Rename(src, dst); err == nil { if err := os.Rename(src, dst); err == nil {
return nil return nil
} }
// If that fails (e.g., cross-filesystem), copy and delete // If that fails (e.g., cross-filesystem), copy and delete
return copyAndRemove(src, dst) return copyAndRemove(src, dst)
} }
func copyFile(src, dst string) error { func copyFile(src, dst string) error {
srcFile, err := os.Open(src) srcFile, err := os.Open(src)
if err != nil { if err != nil {
return err return err
} }
defer srcFile.Close() defer srcFile.Close()
dstFile, err := os.Create(dst) dstFile, err := os.Create(dst)
if err != nil { if err != nil {
return err return err
} }
defer dstFile.Close() defer dstFile.Close()
_, err = io.Copy(dstFile, srcFile) _, err = io.Copy(dstFile, srcFile)
return err return err
} }
func copyAndRemove(src, dst string) error { func copyAndRemove(src, dst string) error {
// Copy the file // Copy the file
if err := copyFile(src, dst); err != nil { if err := copyFile(src, dst); err != nil {
return err return err
} }
// Remove the source file // Remove the source file
return os.Remove(src) return os.Remove(src)
} }
func listDirectory(path string) ([]string, error) { func listDirectory(path string) ([]string, error) {
entries, err := os.ReadDir(path) entries, err := os.ReadDir(path)
if err != nil { if err != nil {
return nil, err return nil, err
} }
var files []string var files []string
for _, entry := range entries { for _, entry := range entries {
if entry.IsDir() { if entry.IsDir() {
files = append(files, entry.Name()+"/") // Add "/" to indicate directory files = append(files, entry.Name()+"/") // Add "/" to indicate directory
} else { } else {
files = append(files, entry.Name()) files = append(files, entry.Name())
} }
} }
return files, nil return files, nil
} }
// Command Execution Tool // Command Execution Tool
func executeCommand(args map[string]string) []byte { func executeCommand(args map[string]string) []byte {
command, ok := args["command"] command, ok := args["command"]
if !ok || command == "" { if !ok || command == "" {
msg := "command not provided to execute_command tool" msg := "command not provided to execute_command tool"
logger.Error(msg) logger.Error(msg)
return []byte(msg) return []byte(msg)
} }
if !isCommandAllowed(command) { if !isCommandAllowed(command) {
msg := fmt.Sprintf("command '%s' is not allowed", command) msg := fmt.Sprintf("command '%s' is not allowed", command)
logger.Error(msg) logger.Error(msg)
return []byte(msg) return []byte(msg)
} }
// Get arguments - handle both single arg and multiple args // Get arguments - handle both single arg and multiple args
var cmdArgs []string var cmdArgs []string
if args["args"] != "" { if args["args"] != "" {
// If args is provided as a single string, split by spaces // If args is provided as a single string, split by spaces
cmdArgs = strings.Fields(args["args"]) cmdArgs = strings.Fields(args["args"])
} else { } else {
// If individual args are provided, collect them // If individual args are provided, collect them
argNum := 1 argNum := 1
for { for {
argKey := fmt.Sprintf("arg%d", argNum) argKey := fmt.Sprintf("arg%d", argNum)
if argValue, exists := args[argKey]; exists && argValue != "" { if argValue, exists := args[argKey]; exists && argValue != "" {
cmdArgs = append(cmdArgs, argValue) cmdArgs = append(cmdArgs, argValue)
} else { } else {
break break
} }
argNum++ argNum++
} }
} }
// Execute with timeout for safety // Execute with timeout for safety
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel() defer cancel()
cmd := exec.CommandContext(ctx, command, cmdArgs...) cmd := exec.CommandContext(ctx, command, cmdArgs...)
output, err := cmd.CombinedOutput() output, err := cmd.CombinedOutput()
if err != nil { if err != nil {
msg := fmt.Sprintf("command '%s' failed; error: %v; output: %s", command, err, string(output)) msg := fmt.Sprintf("command '%s' failed; error: %v; output: %s", command, err, string(output))
logger.Error(msg) logger.Error(msg)
return []byte(msg) return []byte(msg)
} }
return output return output
} }
// Helper functions for command execution // Helper functions for command execution
func isCommandAllowed(command string) bool { func isCommandAllowed(command string) bool {
allowedCommands := map[string]bool{ allowedCommands := map[string]bool{
"grep": true, "grep": true,
"sed": true, "sed": true,
"awk": true, "awk": true,
"find": true, "find": true,
"cat": true, "cat": true,
"head": true, "head": true,
"tail": true, "tail": true,
"sort": true, "sort": true,
"uniq": true, "uniq": true,
"wc": true, "wc": true,
"ls": true, "ls": true,
"echo": true, "echo": true,
"cut": true, "cut": true,
"tr": true, "tr": true,
"cp": true, "cp": true,
"mv": true, "mv": true,
"rm": true, "rm": true,
"mkdir": true, "mkdir": true,
"rmdir": true, "rmdir": true,
} }
return allowedCommands[command] return allowedCommands[command]
} }
type fnSig func(map[string]string) []byte type fnSig func(map[string]string) []byte
@@ -776,14 +776,14 @@ var baseTools = []models.Tool{
Type: "function", Type: "function",
Function: models.ToolFunc{ Function: models.ToolFunc{
Name: "execute_command", Name: "execute_command",
Description: "Execute a shell command safely. Use when you need to run system commands like grep, sed, awk, cat, head, tail, find, etc.", Description: "Execute a shell command safely. Use when you need to run system commands like grep sed awk find cat head tail sort uniq wc ls echo cut tr cp mv rm mkdir rmdir",
Parameters: models.ToolFuncParams{ Parameters: models.ToolFuncParams{
Type: "object", Type: "object",
Required: []string{"command"}, Required: []string{"command"},
Properties: map[string]models.ToolArgProps{ Properties: map[string]models.ToolArgProps{
"command": models.ToolArgProps{ "command": models.ToolArgProps{
Type: "string", Type: "string",
Description: "command to execute (only commands from whitelist are allowed: grep, sed, awk, cat, head, tail, find, etc.)", Description: "command to execute (only commands from whitelist are allowed: grep sed awk find cat head tail sort uniq wc ls echo cut tr cp mv rm mkdir rmdir",
}, },
"args": models.ToolArgProps{ "args": models.ToolArgProps{
Type: "string", Type: "string",