mirror of
https://github.com/YspCoder/clawgo.git
synced 2026-04-13 16:47:34 +08:00
92 lines
2.1 KiB
Go
92 lines
2.1 KiB
Go
package tools
|
||
|
||
import (
|
||
"context"
|
||
"fmt"
|
||
"os/exec"
|
||
"time"
|
||
)
|
||
|
||
type BrowserTool struct {
|
||
chromePath string
|
||
timeout time.Duration
|
||
}
|
||
|
||
func NewBrowserTool() *BrowserTool {
|
||
return &BrowserTool{
|
||
timeout: 30 * time.Second,
|
||
}
|
||
}
|
||
|
||
func (t *BrowserTool) Name() string {
|
||
return "browser"
|
||
}
|
||
|
||
func (t *BrowserTool) Description() string {
|
||
return "Control a headless browser to capture screenshots or fetch dynamic content using Chromium."
|
||
}
|
||
|
||
func (t *BrowserTool) Parameters() map[string]interface{} {
|
||
return map[string]interface{}{
|
||
"type": "object",
|
||
"properties": map[string]interface{}{
|
||
"action": map[string]interface{}{
|
||
"type": "string",
|
||
"enum": []string{"screenshot", "content"},
|
||
},
|
||
"url": map[string]interface{}{
|
||
"type": "string",
|
||
},
|
||
},
|
||
"required": []string{"action", "url"},
|
||
}
|
||
}
|
||
|
||
func (t *BrowserTool) Execute(ctx context.Context, args map[string]interface{}) (string, error) {
|
||
action, _ := args["action"].(string)
|
||
url, _ := args["url"].(string)
|
||
|
||
switch action {
|
||
case "screenshot":
|
||
return t.takeScreenshot(ctx, url)
|
||
case "content":
|
||
return t.fetchDynamicContent(ctx, url)
|
||
default:
|
||
return "", fmt.Errorf("unknown browser action: %s", action)
|
||
}
|
||
}
|
||
|
||
func (t *BrowserTool) takeScreenshot(ctx context.Context, url string) (string, error) {
|
||
// 基于 CLI 的简单实现:使用 chromium-browser --headless
|
||
outputPath := fmt.Sprintf("/tmp/screenshot_%d.png", time.Now().UnixNano())
|
||
cmd := exec.CommandContext(ctx, "chromium-browser",
|
||
"--headless",
|
||
"--disable-gpu",
|
||
"--no-sandbox",
|
||
"--screenshot="+outputPath,
|
||
url)
|
||
|
||
if err := cmd.Run(); err != nil {
|
||
return "", fmt.Errorf("failed to take screenshot: %w (ensure chromium-browser is installed)", err)
|
||
}
|
||
|
||
return fmt.Sprintf("Screenshot saved to: %s", outputPath), nil
|
||
}
|
||
|
||
func (t *BrowserTool) fetchDynamicContent(ctx context.Context, url string) (string, error) {
|
||
// 简单实现:dump-dom
|
||
cmd := exec.CommandContext(ctx, "chromium-browser",
|
||
"--headless",
|
||
"--disable-gpu",
|
||
"--no-sandbox",
|
||
"--dump-dom",
|
||
url)
|
||
|
||
output, err := cmd.Output()
|
||
if err != nil {
|
||
return "", fmt.Errorf("failed to fetch content: %w", err)
|
||
}
|
||
|
||
return string(output), nil
|
||
}
|