From c05b93299c670f7c54c165d08899fc75ec4c80c1 Mon Sep 17 00:00:00 2001 From: Grail Finder Date: Tue, 3 Mar 2026 07:38:57 +0300 Subject: [PATCH] Chore: linter complaints --- browser.go | 130 ++++++++++++++++++++--------------------------------- 1 file changed, 48 insertions(+), 82 deletions(-) diff --git a/browser.go b/browser.go index 1ff0408..7b2ffe4 100644 --- a/browser.go +++ b/browser.go @@ -3,8 +3,9 @@ package main import ( "encoding/json" "fmt" - "log/slog" "os" + "strconv" + "strings" "sync" "github.com/playwright-community/playwright-go" @@ -13,7 +14,6 @@ import ( ) var ( - browserLogger *slog.Logger pw *playwright.Playwright browser playwright.Browser browserStarted bool @@ -26,30 +26,20 @@ func checkPlaywright() { var err error pw, err = playwright.Run() if err != nil { - if browserLogger != nil { - browserLogger.Warn("playwright not available", "error", err) - } + logger.Warn("playwright not available", "error", err) return } browserAvailable = true - if browserLogger != nil { - browserLogger.Info("playwright tools available") - } + logger.Info("playwright tools available") } func pwStart(args map[string]string) []byte { browserStartMu.Lock() defer browserStartMu.Unlock() - if browserStarted { return []byte(`{"error": "Browser already started"}`) } - - headless := true - if cfg != nil && !cfg.PlaywrightHeadless { - headless = false - } - + headless := cfg == nil || cfg.PlaywrightHeadless var err error browser, err = pw.Chromium.Launch(playwright.BrowserTypeLaunchOptions{ Headless: playwright.Bool(headless), @@ -57,13 +47,11 @@ func pwStart(args map[string]string) []byte { if err != nil { return []byte(fmt.Sprintf(`{"error": "failed to launch browser: %s"}`, err.Error())) } - page, err = browser.NewPage() if err != nil { browser.Close() return []byte(fmt.Sprintf(`{"error": "failed to create page: %s"}`, err.Error())) } - browserStarted = true return []byte(`{"success": true, "message": "Browser started"}`) } @@ -71,11 +59,9 @@ func pwStart(args map[string]string) []byte { func pwStop(args map[string]string) []byte { browserStartMu.Lock() defer browserStartMu.Unlock() - if !browserStarted { return []byte(`{"success": true, "message": "Browser was not running"}`) } - if page != nil { page.Close() page = nil @@ -84,7 +70,6 @@ func pwStop(args map[string]string) []byte { browser.Close() browser = nil } - browserStarted = false return []byte(`{"success": true, "message": "Browser stopped"}`) } @@ -101,16 +86,13 @@ func pwNavigate(args map[string]string) []byte { if !ok || url == "" { return []byte(`{"error": "url not provided"}`) } - if !browserStarted || page == nil { return []byte(`{"error": "Browser not started. Call pw_start first."}`) } - _, err := page.Goto(url) if err != nil { return []byte(fmt.Sprintf(`{"error": "failed to navigate: %s"}`, err.Error())) } - title, _ := page.Title() pageURL := page.URL() return []byte(fmt.Sprintf(`{"success": true, "title": "%s", "url": "%s"}`, title, pageURL)) @@ -121,31 +103,29 @@ func pwClick(args map[string]string) []byte { if !ok || selector == "" { return []byte(`{"error": "selector not provided"}`) } - if !browserStarted || page == nil { return []byte(`{"error": "Browser not started. Call pw_start first."}`) } - index := 0 if args["index"] != "" { - fmt.Sscanf(args["index"], "%d", &index) + if i, err := strconv.Atoi(args["index"]); err != nil { + logger.Warn("failed to parse index", "value", args["index"], "error", err) + } else { + index = i + } } - locator := page.Locator(selector) count, err := locator.Count() if err != nil { return []byte(fmt.Sprintf(`{"error": "failed to find elements: %s"}`, err.Error())) } - if index >= count { return []byte(fmt.Sprintf(`{"error": "Element not found at index %d (found %d elements)"}`, index, count)) } - err = locator.Nth(index).Click() if err != nil { return []byte(fmt.Sprintf(`{"error": "failed to click: %s"}`, err.Error())) } - return []byte(`{"success": true, "message": "Clicked element"}`) } @@ -154,36 +134,33 @@ func pwFill(args map[string]string) []byte { if !ok || selector == "" { return []byte(`{"error": "selector not provided"}`) } - text := args["text"] if text == "" { text = "" } - if !browserStarted || page == nil { return []byte(`{"error": "Browser not started. Call pw_start first."}`) } - index := 0 if args["index"] != "" { - fmt.Sscanf(args["index"], "%d", &index) + if i, err := strconv.Atoi(args["index"]); err != nil { + logger.Warn("failed to parse index", "value", args["index"], "error", err) + } else { + index = i + } } - locator := page.Locator(selector) count, err := locator.Count() if err != nil { return []byte(fmt.Sprintf(`{"error": "failed to find elements: %s"}`, err.Error())) } - if index >= count { return []byte(fmt.Sprintf(`{"error": "Element not found at index %d"}`, index)) } - err = locator.Nth(index).Fill(text) if err != nil { return []byte(fmt.Sprintf(`{"error": "failed to fill: %s"}`, err.Error())) } - return []byte(`{"success": true, "message": "Filled input"}`) } @@ -192,29 +169,24 @@ func pwExtractText(args map[string]string) []byte { if selector == "" { selector = "body" } - if !browserStarted || page == nil { return []byte(`{"error": "Browser not started. Call pw_start first."}`) } - locator := page.Locator(selector) count, err := locator.Count() if err != nil { return []byte(fmt.Sprintf(`{"error": "failed to find elements: %s"}`, err.Error())) } - if count == 0 { return []byte(`{"error": "No elements found"}`) } - if selector == "body" { - text, err := page.TextContent("body") + text, err := page.Locator("body").TextContent() if err != nil { return []byte(fmt.Sprintf(`{"error": "failed to get text: %s"}`, err.Error())) } return []byte(fmt.Sprintf(`{"text": "%s"}`, text)) } - var texts []string for i := 0; i < count; i++ { text, err := locator.Nth(i).TextContent() @@ -223,31 +195,27 @@ func pwExtractText(args map[string]string) []byte { } texts = append(texts, text) } - return []byte(fmt.Sprintf(`{"text": "%s"}`, joinLines(texts))) } func joinLines(lines []string) string { - result := "" + var sb strings.Builder for i, line := range lines { if i > 0 { - result += "\n" + sb.WriteString("\n") } - result += line + sb.WriteString(line) } - return result + return sb.String() } func pwScreenshot(args map[string]string) []byte { selector := args["selector"] fullPage := args["full_page"] == "true" - if !browserStarted || page == nil { return []byte(`{"error": "Browser not started. Call pw_start first."}`) } - path := fmt.Sprintf("/tmp/pw_screenshot_%d.png", os.Getpid()) - var err error if selector != "" && selector != "body" { locator := page.Locator(selector) @@ -260,24 +228,19 @@ func pwScreenshot(args map[string]string) []byte { FullPage: playwright.Bool(fullPage), }) } - if err != nil { return []byte(fmt.Sprintf(`{"error": "failed to take screenshot: %s"}`, err.Error())) } - return []byte(fmt.Sprintf(`{"path": "%s"}`, path)) } func pwScreenshotAndView(args map[string]string) []byte { selector := args["selector"] fullPage := args["full_page"] == "true" - if !browserStarted || page == nil { return []byte(`{"error": "Browser not started. Call pw_start first."}`) } - path := fmt.Sprintf("/tmp/pw_screenshot_%d.png", os.Getpid()) - var err error if selector != "" && selector != "body" { locator := page.Locator(selector) @@ -290,16 +253,13 @@ func pwScreenshotAndView(args map[string]string) []byte { FullPage: playwright.Bool(fullPage), }) } - if err != nil { return []byte(fmt.Sprintf(`{"error": "failed to take screenshot: %s"}`, err.Error())) } - dataURL, err := models.CreateImageURLFromPath(path) if err != nil { return []byte(fmt.Sprintf(`{"error": "failed to create image URL: %s"}`, err.Error())) } - resp := models.MultimodalToolResp{ Type: "multimodal_content", Parts: []map[string]string{ @@ -319,23 +279,24 @@ func pwWaitForSelector(args map[string]string) []byte { if !ok || selector == "" { return []byte(`{"error": "selector not provided"}`) } - if !browserStarted || page == nil { return []byte(`{"error": "Browser not started. Call pw_start first."}`) } - timeout := 30000 if args["timeout"] != "" { - fmt.Sscanf(args["timeout"], "%d", &timeout) + if t, err := strconv.Atoi(args["timeout"]); err != nil { + logger.Warn("failed to parse timeout", "value", args["timeout"], "error", err) + } else { + timeout = t + } } - - _, err := page.WaitForSelector(selector, playwright.PageWaitForSelectorOptions{ + locator := page.Locator(selector) + err := locator.WaitFor(playwright.LocatorWaitForOptions{ Timeout: playwright.Float(float64(timeout)), }) if err != nil { return []byte(fmt.Sprintf(`{"error": "element not found: %s"}`, err.Error())) } - return []byte(`{"success": true, "message": "Element found"}`) } @@ -344,58 +305,63 @@ func pwDrag(args map[string]string) []byte { if !ok { return []byte(`{"error": "x1 not provided"}`) } - y1, ok := args["y1"] if !ok { return []byte(`{"error": "y1 not provided"}`) } - x2, ok := args["x2"] if !ok { return []byte(`{"error": "x2 not provided"}`) } - y2, ok := args["y2"] if !ok { return []byte(`{"error": "y2 not provided"}`) } - if !browserStarted || page == nil { return []byte(`{"error": "Browser not started. Call pw_start first."}`) } - var fx1, fy1, fx2, fy2 float64 - fmt.Sscanf(x1, "%f", &fx1) - fmt.Sscanf(y1, "%f", &fy1) - fmt.Sscanf(x2, "%f", &fx2) - fmt.Sscanf(y2, "%f", &fy2) - + if parsedX1, err := strconv.ParseFloat(x1, 64); err != nil { + logger.Warn("failed to parse x1", "value", x1, "error", err) + } else { + fx1 = parsedX1 + } + if parsedY1, err := strconv.ParseFloat(y1, 64); err != nil { + logger.Warn("failed to parse y1", "value", y1, "error", err) + } else { + fy1 = parsedY1 + } + if parsedX2, err := strconv.ParseFloat(x2, 64); err != nil { + logger.Warn("failed to parse x2", "value", x2, "error", err) + } else { + fx2 = parsedX2 + } + if parsedY2, err := strconv.ParseFloat(y2, 64); err != nil { + logger.Warn("failed to parse y2", "value", y2, "error", err) + } else { + fy2 = parsedY2 + } mouse := page.Mouse() - err := mouse.Move(fx1, fy1) if err != nil { return []byte(fmt.Sprintf(`{"error": "failed to move mouse: %s"}`, err.Error())) } - err = mouse.Down() if err != nil { return []byte(fmt.Sprintf(`{"error": "failed to mouse down: %s"}`, err.Error())) } - err = mouse.Move(fx2, fy2) if err != nil { return []byte(fmt.Sprintf(`{"error": "failed to move mouse: %s"}`, err.Error())) } - err = mouse.Up() if err != nil { return []byte(fmt.Sprintf(`{"error": "failed to mouse up: %s"}`, err.Error())) } - return []byte(fmt.Sprintf(`{"success": true, "message": "Dragged from (%s,%s) to (%s,%s)"}`, x1, y1, x2, y2)) } func init() { - browserLogger = logger.With("component", "browser") + logger = logger.With("component", "browser") checkPlaywright() }