Refactor: deal with unused code

This commit is contained in:
Grail Finder
2026-03-15 10:55:07 +03:00
parent 1396b3eb05
commit 7e346b5e19
9 changed files with 641 additions and 884 deletions

View File

@@ -32,10 +32,8 @@ func ParseChain(input string) []Segment {
var current strings.Builder
runes := []rune(input)
n := len(runes)
for i := 0; i < n; i++ {
ch := runes[i]
// handle quotes
if ch == '\'' || ch == '"' {
quote := ch
@@ -50,7 +48,6 @@ func ParseChain(input string) []Segment {
}
continue
}
// &&
if ch == '&' && i+1 < n && runes[i+1] == '&' {
segments = append(segments, Segment{
@@ -61,7 +58,6 @@ func ParseChain(input string) []Segment {
i++ // skip second &
continue
}
// ;
if ch == ';' {
segments = append(segments, Segment{
@@ -71,7 +67,6 @@ func ParseChain(input string) []Segment {
current.Reset()
continue
}
// ||
if ch == '|' && i+1 < n && runes[i+1] == '|' {
segments = append(segments, Segment{
@@ -82,7 +77,6 @@ func ParseChain(input string) []Segment {
i++ // skip second |
continue
}
// | (single pipe)
if ch == '|' {
segments = append(segments, Segment{
@@ -92,16 +86,13 @@ func ParseChain(input string) []Segment {
current.Reset()
continue
}
current.WriteRune(ch)
}
// last segment
last := strings.TrimSpace(current.String())
if last != "" {
segments = append(segments, Segment{Raw: last, Op: OpNone})
}
return segments
}
@@ -112,12 +103,10 @@ func ExecChain(command string) string {
if len(segments) == 0 {
return "[error] empty command"
}
var collected []string
var lastOutput string
var lastErr error
pipeInput := ""
for i, seg := range segments {
if i > 0 {
prevOp := segments[i-1].Op
@@ -130,7 +119,6 @@ func ExecChain(command string) string {
continue
}
}
// determine stdin for this segment
segStdin := ""
if i == 0 {
@@ -138,9 +126,7 @@ func ExecChain(command string) string {
} else if segments[i-1].Op == OpPipe {
segStdin = lastOutput
}
lastOutput, lastErr = execSingle(seg.Raw, segStdin)
// pipe: output flows to next command's stdin
// && or ;: collect output
if i < len(segments)-1 && seg.Op == OpPipe {
@@ -150,7 +136,6 @@ func ExecChain(command string) string {
collected = append(collected, lastOutput)
}
}
return strings.Join(collected, "\n")
}
@@ -160,15 +145,12 @@ func execSingle(command, stdin string) (string, error) {
if len(parts) == 0 {
return "", fmt.Errorf("empty command")
}
name := parts[0]
args := parts[1:]
// Check if it's a built-in Go command
if result := execBuiltin(name, args, stdin); result != "" {
return result, nil
}
// Otherwise execute as system command
cmd := exec.Command(name, args...)
if stdin != "" {
@@ -187,7 +169,6 @@ func tokenize(input string) []string {
var current strings.Builder
inQuote := false
var quoteChar rune
for _, ch := range input {
if inQuote {
if ch == quoteChar {
@@ -197,13 +178,11 @@ func tokenize(input string) []string {
}
continue
}
if ch == '\'' || ch == '"' {
inQuote = true
quoteChar = ch
continue
}
if ch == ' ' || ch == '\t' {
if current.Len() > 0 {
tokens = append(tokens, current.String())
@@ -211,14 +190,11 @@ func tokenize(input string) []string {
}
continue
}
current.WriteRune(ch)
}
if current.Len() > 0 {
tokens = append(tokens, current.String())
}
return tokens
}
@@ -242,7 +218,7 @@ func execBuiltin(name string, args []string, stdin string) string {
path := args[0]
abs := path
if !filepath.IsAbs(path) {
abs = filepath.Join(fsRootDir, path)
abs = filepath.Join(cfg.FilePickerDir, path)
}
data, err := os.ReadFile(abs)
if err != nil {
@@ -250,16 +226,16 @@ func execBuiltin(name string, args []string, stdin string) string {
}
return string(data)
case "pwd":
return fsRootDir
return cfg.FilePickerDir
case "cd":
if len(args) == 0 {
return "[error] usage: cd <dir>"
}
dir := args[0]
// Resolve relative to fsRootDir
// Resolve relative to cfg.FilePickerDir
abs := dir
if !filepath.IsAbs(dir) {
abs = filepath.Join(fsRootDir, dir)
abs = filepath.Join(cfg.FilePickerDir, dir)
}
abs = filepath.Clean(abs)
info, err := os.Stat(abs)
@@ -269,8 +245,8 @@ func execBuiltin(name string, args []string, stdin string) string {
if !info.IsDir() {
return fmt.Sprintf("[error] cd: not a directory: %s", dir)
}
fsRootDir = abs
return fmt.Sprintf("Changed directory to: %s", fsRootDir)
cfg.FilePickerDir = abs
return fmt.Sprintf("Changed directory to: %s", cfg.FilePickerDir)
case "mkdir":
if len(args) == 0 {
return "[error] usage: mkdir [-p] <dir>"
@@ -289,7 +265,7 @@ func execBuiltin(name string, args []string, stdin string) string {
}
abs := dirPath
if !filepath.IsAbs(dirPath) {
abs = filepath.Join(fsRootDir, dirPath)
abs = filepath.Join(cfg.FilePickerDir, dirPath)
}
abs = filepath.Clean(abs)
var mkdirFunc func(string, os.FileMode) error
@@ -315,7 +291,7 @@ func execBuiltin(name string, args []string, stdin string) string {
}
abs := dir
if !filepath.IsAbs(dir) {
abs = filepath.Join(fsRootDir, dir)
abs = filepath.Join(cfg.FilePickerDir, dir)
}
entries, err := os.ReadDir(abs)
if err != nil {
@@ -347,7 +323,7 @@ func execBuiltin(name string, args []string, stdin string) string {
return "[error] usage: go <subcommand> [options]"
}
cmd := exec.Command("go", args...)
cmd.Dir = fsRootDir
cmd.Dir = cfg.FilePickerDir
output, err := cmd.CombinedOutput()
if err != nil {
return fmt.Sprintf("[error] go %s: %v\n%s", args[0], err, string(output))

View File

@@ -14,7 +14,6 @@ import (
"time"
)
var fsRootDir string
var memoryStore MemoryStore
var agentRole string
@@ -31,11 +30,11 @@ func SetMemoryStore(store MemoryStore, role string) {
}
func SetFSRoot(dir string) {
fsRootDir = dir
cfg.FilePickerDir = dir
}
func GetFSRoot() string {
return fsRootDir
return cfg.FilePickerDir
}
func SetFSCwd(dir string) error {
@@ -50,26 +49,24 @@ func SetFSCwd(dir string) error {
if !info.IsDir() {
return fmt.Errorf("not a directory: %s", dir)
}
fsRootDir = abs
cfg.FilePickerDir = abs
return nil
}
func resolvePath(rel string) (string, error) {
if fsRootDir == "" {
if cfg.FilePickerDir == "" {
return "", fmt.Errorf("fs root not set")
}
if filepath.IsAbs(rel) {
abs := filepath.Clean(rel)
if !strings.HasPrefix(abs, fsRootDir+string(os.PathSeparator)) && abs != fsRootDir {
if !strings.HasPrefix(abs, cfg.FilePickerDir+string(os.PathSeparator)) && abs != cfg.FilePickerDir {
return "", fmt.Errorf("path escapes fs root: %s", rel)
}
return abs, nil
}
abs := filepath.Join(fsRootDir, rel)
abs := filepath.Join(cfg.FilePickerDir, rel)
abs = filepath.Clean(abs)
if !strings.HasPrefix(abs, fsRootDir+string(os.PathSeparator)) && abs != fsRootDir {
if !strings.HasPrefix(abs, cfg.FilePickerDir+string(os.PathSeparator)) && abs != cfg.FilePickerDir {
return "", fmt.Errorf("path escapes fs root: %s", rel)
}
return abs, nil
@@ -100,12 +97,10 @@ func FsLs(args []string, stdin string) string {
if err != nil {
return fmt.Sprintf("[error] %v", err)
}
entries, err := os.ReadDir(abs)
if err != nil {
return fmt.Sprintf("[error] ls: %v", err)
}
var out strings.Builder
for _, e := range entries {
info, _ := e.Info()
@@ -136,17 +131,14 @@ func FsCat(args []string, stdin string) string {
if path == "" {
return "[error] usage: cat <path>"
}
abs, err := resolvePath(path)
if err != nil {
return fmt.Sprintf("[error] %v", err)
}
data, err := os.ReadFile(abs)
if err != nil {
return fmt.Sprintf("[error] cat: %v", err)
}
if b64 {
result := base64.StdEncoding.EncodeToString(data)
if IsImageFile(path) {
@@ -162,7 +154,6 @@ func FsViewImg(args []string, stdin string) string {
return "[error] usage: view_img <image-path>"
}
path := args[0]
var abs string
if filepath.IsAbs(path) {
abs = path
@@ -173,20 +164,16 @@ func FsViewImg(args []string, stdin string) string {
return fmt.Sprintf("[error] %v", err)
}
}
if _, err := os.Stat(abs); err != nil {
return fmt.Sprintf("[error] view_img: %v", err)
}
if !IsImageFile(path) {
return fmt.Sprintf("[error] not an image file: %s (use cat to read text files)", path)
}
dataURL, err := models.CreateImageURLFromPath(abs)
if err != nil {
return fmt.Sprintf("[error] view_img: %v", err)
}
result := models.MultimodalToolResp{
Type: "multimodal_content",
Parts: []map[string]string{
@@ -222,16 +209,13 @@ func FsWrite(args []string, stdin string) string {
if path == "" {
return "[error] usage: write <path> [content] or pipe stdin"
}
abs, err := resolvePath(path)
if err != nil {
return fmt.Sprintf("[error] %v", err)
}
if err := os.MkdirAll(filepath.Dir(abs), 0o755); err != nil {
return fmt.Sprintf("[error] mkdir: %v", err)
}
var data []byte
if b64 {
src := stdin
@@ -251,18 +235,14 @@ func FsWrite(args []string, stdin string) string {
data = []byte(stdin)
}
}
if err := os.WriteFile(abs, data, 0o644); err != nil {
return fmt.Sprintf("[error] write: %v", err)
}
size := humanSize(int64(len(data)))
result := fmt.Sprintf("Written %s → %s", size, path)
if IsImageFile(path) {
result += fmt.Sprintf("\n![image](file://%s)", abs)
}
return result
}
@@ -270,17 +250,14 @@ func FsStat(args []string, stdin string) string {
if len(args) == 0 {
return "[error] usage: stat <path>"
}
abs, err := resolvePath(args[0])
if err != nil {
return fmt.Sprintf("[error] %v", err)
}
info, err := os.Stat(abs)
if err != nil {
return fmt.Sprintf("[error] stat: %v", err)
}
mime := "application/octet-stream"
if IsImageFile(args[0]) {
ext := strings.ToLower(filepath.Ext(args[0]))
@@ -297,7 +274,6 @@ func FsStat(args []string, stdin string) string {
mime = "image/svg+xml"
}
}
var out strings.Builder
fmt.Fprintf(&out, "File: %s\n", args[0])
fmt.Fprintf(&out, "Size: %s (%d bytes)\n", humanSize(info.Size()), info.Size())
@@ -313,12 +289,10 @@ func FsRm(args []string, stdin string) string {
if len(args) == 0 {
return "[error] usage: rm <path>"
}
abs, err := resolvePath(args[0])
if err != nil {
return fmt.Sprintf("[error] %v", err)
}
if err := os.RemoveAll(abs); err != nil {
return fmt.Sprintf("[error] rm: %v", err)
}
@@ -329,7 +303,6 @@ func FsCp(args []string, stdin string) string {
if len(args) < 2 {
return "[error] usage: cp <src> <dst>"
}
srcAbs, err := resolvePath(args[0])
if err != nil {
return fmt.Sprintf("[error] %v", err)
@@ -338,16 +311,13 @@ func FsCp(args []string, stdin string) string {
if err != nil {
return fmt.Sprintf("[error] %v", err)
}
data, err := os.ReadFile(srcAbs)
if err != nil {
return fmt.Sprintf("[error] cp read: %v", err)
}
if err := os.MkdirAll(filepath.Dir(dstAbs), 0o755); err != nil {
return fmt.Sprintf("[error] cp mkdir: %v", err)
}
if err := os.WriteFile(dstAbs, data, 0o644); err != nil {
return fmt.Sprintf("[error] cp write: %v", err)
}
@@ -358,7 +328,6 @@ func FsMv(args []string, stdin string) string {
if len(args) < 2 {
return "[error] usage: mv <src> <dst>"
}
srcAbs, err := resolvePath(args[0])
if err != nil {
return fmt.Sprintf("[error] %v", err)
@@ -367,11 +336,9 @@ func FsMv(args []string, stdin string) string {
if err != nil {
return fmt.Sprintf("[error] %v", err)
}
if err := os.MkdirAll(filepath.Dir(dstAbs), 0o755); err != nil {
return fmt.Sprintf("[error] mv mkdir: %v", err)
}
if err := os.Rename(srcAbs, dstAbs); err != nil {
return fmt.Sprintf("[error] mv: %v", err)
}
@@ -382,10 +349,8 @@ func FsMkdir(args []string, stdin string) string {
if len(args) == 0 {
return "[error] usage: mkdir [-p] <dir>"
}
createParents := false
var dirPath string
for _, a := range args {
if a == "-p" || a == "--parents" {
createParents = true
@@ -393,27 +358,22 @@ func FsMkdir(args []string, stdin string) string {
dirPath = a
}
}
if dirPath == "" {
return "[error] usage: mkdir [-p] <dir>"
}
abs, err := resolvePath(dirPath)
if err != nil {
return fmt.Sprintf("[error] %v", err)
}
var mkdirFunc func(string, os.FileMode) error
if createParents {
mkdirFunc = os.MkdirAll
} else {
mkdirFunc = os.Mkdir
}
if err := mkdirFunc(abs, 0o755); err != nil {
return fmt.Sprintf("[error] mkdir: %v", err)
}
if createParents {
return fmt.Sprintf("Created %s (with parents)", dirPath)
}
@@ -459,7 +419,6 @@ func FsGrep(args []string, stdin string) string {
if ignoreCase {
pattern = strings.ToLower(pattern)
}
lines := strings.Split(stdin, "\n")
var matched []string
for _, line := range lines {
@@ -549,7 +508,6 @@ func FsSort(args []string, stdin string) string {
numeric = true
}
}
sortFunc := func(i, j int) bool {
if numeric {
ni, _ := strconv.Atoi(lines[i])
@@ -564,7 +522,6 @@ func FsSort(args []string, stdin string) string {
}
return lines[i] < lines[j]
}
sort.Slice(lines, sortFunc)
return strings.Join(lines, "\n")
}
@@ -577,7 +534,6 @@ func FsUniq(args []string, stdin string) string {
showCount = true
}
}
var result []string
var prev string
first := true
@@ -623,17 +579,14 @@ func FsGit(args []string, stdin string) string {
if len(args) == 0 {
return "[error] usage: git <subcommand> [options]"
}
subcmd := args[0]
if !allowedGitSubcommands[subcmd] {
return fmt.Sprintf("[error] git: '%s' is not an allowed git command. Allowed: status, log, diff, show, branch, reflog, rev-parse, shortlog, describe, rev-list", subcmd)
}
abs, err := resolvePath(".")
if err != nil {
return fmt.Sprintf("[error] git: %v", err)
}
// Pass all args to git (first arg is subcommand, rest are options)
cmd := exec.Command("git", args...)
cmd.Dir = abs
@@ -645,7 +598,7 @@ func FsGit(args []string, stdin string) string {
}
func FsPwd(args []string, stdin string) string {
return fsRootDir
return cfg.FilePickerDir
}
func FsCd(args []string, stdin string) string {
@@ -664,19 +617,17 @@ func FsCd(args []string, stdin string) string {
if !info.IsDir() {
return fmt.Sprintf("[error] cd: not a directory: %s", dir)
}
fsRootDir = abs
return fmt.Sprintf("Changed directory to: %s", fsRootDir)
cfg.FilePickerDir = abs
return fmt.Sprintf("Changed directory to: %s", cfg.FilePickerDir)
}
func FsSed(args []string, stdin string) string {
if len(args) == 0 {
return "[error] usage: sed 's/old/new/[g]' [file]"
}
inPlace := false
var filePath string
var pattern string
for _, a := range args {
if a == "-i" || a == "--in-place" {
inPlace = true
@@ -687,21 +638,17 @@ func FsSed(args []string, stdin string) string {
filePath = a
}
}
if pattern == "" {
return "[error] usage: sed 's/old/new/[g]' [file]"
}
// Parse pattern: s/old/new/flags
parts := strings.Split(pattern[1:], "/")
if len(parts) < 2 {
return "[error] invalid sed pattern. Use: s/old/new/[g]"
}
oldStr := parts[0]
newStr := parts[1]
global := len(parts) >= 3 && strings.Contains(parts[2], "g")
var content string
if filePath != "" && stdin == "" {
// Read from file
@@ -720,14 +667,12 @@ func FsSed(args []string, stdin string) string {
} else {
return "[error] sed: no input (use file path or pipe from stdin)"
}
// Apply sed replacement
if global {
content = strings.ReplaceAll(content, oldStr, newStr)
} else {
content = strings.Replace(content, oldStr, newStr, 1)
}
if inPlace && filePath != "" {
abs, err := resolvePath(filePath)
if err != nil {
@@ -738,7 +683,6 @@ func FsSed(args []string, stdin string) string {
}
return fmt.Sprintf("Modified %s", filePath)
}
return content
}
@@ -746,11 +690,9 @@ func FsMemory(args []string, stdin string) string {
if len(args) == 0 {
return "[error] usage: memory store <topic> <data> | memory get <topic> | memory list | memory forget <topic>"
}
if memoryStore == nil {
return "[error] memory store not initialized"
}
switch args[0] {
case "store":
if len(args) < 3 && stdin == "" {
@@ -768,7 +710,6 @@ func FsMemory(args []string, stdin string) string {
return fmt.Sprintf("[error] failed to store: %v", err)
}
return fmt.Sprintf("Stored under topic: %s", topic)
case "get":
if len(args) < 2 {
return "[error] usage: memory get <topic>"
@@ -779,7 +720,6 @@ func FsMemory(args []string, stdin string) string {
return fmt.Sprintf("[error] failed to recall: %v", err)
}
return fmt.Sprintf("Topic: %s\n%s", topic, data)
case "list", "topics":
topics, err := memoryStore.RecallTopics(agentRole)
if err != nil {
@@ -789,7 +729,6 @@ func FsMemory(args []string, stdin string) string {
return "No topics stored."
}
return "Topics: " + strings.Join(topics, ", ")
case "forget", "delete":
if len(args) < 2 {
return "[error] usage: memory forget <topic>"
@@ -800,7 +739,6 @@ func FsMemory(args []string, stdin string) string {
return fmt.Sprintf("[error] failed to forget: %v", err)
}
return fmt.Sprintf("Deleted topic: %s", topic)
default:
return fmt.Sprintf("[error] unknown subcommand: %s. Use: store, get, list, topics, forget, delete", args[0])
}

View File

@@ -12,87 +12,6 @@ import (
"github.com/playwright-community/playwright-go"
)
var browserToolSysMsg = `
Additional browser automation tools (Playwright):
[
{
"name": "pw_start",
"args": [],
"when_to_use": "start a browser instance before doing any browser automation. Must be called first."
},
{
"name": "pw_stop",
"args": [],
"when_to_use": "stop the browser instance when done with automation."
},
{
"name": "pw_is_running",
"args": [],
"when_to_use": "check if browser is currently running."
},
{
"name": "pw_navigate",
"args": ["url"],
"when_to_use": "open a specific URL in the web browser."
},
{
"name": "pw_click",
"args": ["selector", "index"],
"when_to_use": "click on an element on the current webpage. Use 'index' for multiple matches (default 0)."
},
{
"name": "pw_fill",
"args": ["selector", "text", "index"],
"when_to_use": "type text into an input field. Use 'index' for multiple matches (default 0)."
},
{
"name": "pw_extract_text",
"args": ["selector"],
"when_to_use": "extract text content from the page or specific elements. Use selector 'body' for all page text."
},
{
"name": "pw_screenshot",
"args": ["selector", "full_page"],
"when_to_use": "take a screenshot of the page or a specific element. Returns a file path to the image. Use to verify actions or inspect visual state."
},
{
"name": "pw_screenshot_and_view",
"args": ["selector", "full_page"],
"when_to_use": "take a screenshot and return the image for viewing. Use to visually verify page state."
},
{
"name": "pw_wait_for_selector",
"args": ["selector", "timeout"],
"when_to_use": "wait for an element to appear on the page before proceeding with further actions."
},
{
"name": "pw_drag",
"args": ["x1", "y1", "x2", "y2"],
"when_to_use": "drag the mouse from point (x1,y1) to (x2,y2)."
},
{
"name": "pw_click_at",
"args": ["x", "y"],
"when_to_use": "click at specific X,Y coordinates on the page. Use when you know the exact position."
},
{
"name": "pw_get_html",
"args": ["selector"],
"when_to_use": "get the HTML content of the page or a specific element. Use to understand page structure or extract raw HTML."
},
{
"name": "pw_get_dom",
"args": ["selector"],
"when_to_use": "get a structured DOM representation with tag, attributes, text, and children. Use to inspect element hierarchy and properties."
},
{
"name": "pw_search_elements",
"args": ["text", "selector"],
"when_to_use": "search for elements by text content or CSS selector. Returns matching elements with their tags, text, and HTML."
}
]
`
var (
pw *playwright.Playwright
browser playwright.Browser
@@ -532,6 +451,7 @@ func pwDragBySelector(args map[string]string) []byte {
return []byte(fmt.Sprintf(`{"success": true, "message": "%s"}`, msg))
}
// nolint:unused
func pwClickAt(args map[string]string) []byte {
x, ok := args["x"]
if !ok {
@@ -682,6 +602,7 @@ func pwGetDOM(args map[string]string) []byte {
return []byte(fmt.Sprintf(`{"dom": %s}`, string(data)))
}
// nolint:unused
func pwSearchElements(args map[string]string) []byte {
text := args["text"]
selector := args["selector"]

File diff suppressed because it is too large Load Diff