diff --git a/example/webui/actions.go b/example/webui/actions.go index 10ddb04..fc58fe9 100644 --- a/example/webui/actions.go +++ b/example/webui/actions.go @@ -18,6 +18,7 @@ const ( ActionGithubIssueSearcher = "github-issue-searcher" ActionScraper = "scraper" ActionWikipedia = "wikipedia" + ActionBrowse = "browse" ) var AvailableActions = []string{ @@ -27,6 +28,7 @@ var AvailableActions = []string{ ActionGithubIssueCloser, ActionGithubIssueSearcher, ActionScraper, + ActionBrowse, ActionWikipedia, } @@ -58,6 +60,8 @@ func (a *AgentConfig) availableActions(ctx context.Context) []Action { actions = append(actions, external.NewScraper(config)) case ActionWikipedia: actions = append(actions, external.NewWikipedia(config)) + case ActionBrowse: + actions = append(actions, external.NewBrowse(config)) } } diff --git a/external/browse.go b/external/browse.go new file mode 100644 index 0000000..e17598b --- /dev/null +++ b/external/browse.go @@ -0,0 +1,68 @@ +package external + +import ( + "context" + "fmt" + "io" + "net/http" + + "github.com/mudler/local-agent-framework/action" + "github.com/sashabaranov/go-openai/jsonschema" + "jaytaylor.com/html2text" +) + +func NewBrowse(config map[string]string) *BrowseAction { + + return &BrowseAction{} +} + +type BrowseAction struct{} + +func (a *BrowseAction) Run(ctx context.Context, params action.ActionParams) (string, error) { + result := struct { + URL string `json:"url"` + }{} + err := params.Unmarshal(&result) + if err != nil { + fmt.Printf("error: %v", err) + + return "", err + } + // download page with http.Client + client := &http.Client{} + req, err := http.NewRequest("GET", result.URL, nil) + if err != nil { + return "", err + } + resp, err := client.Do(req) + if err != nil { + return "", err + } + defer resp.Body.Close() + pagebyte, err := io.ReadAll(resp.Body) + if err != nil { + return "", err + } + + rendered, err := html2text.FromString(string(pagebyte), html2text.Options{PrettyTables: true}) + + if err != nil { + return "", err + } + + return fmt.Sprintf("The webpage '%s' content is:\n%s", result.URL, rendered), nil +} + +func (a *BrowseAction) Definition() action.ActionDefinition { + return action.ActionDefinition{ + Name: "browse", + Description: "Use this tool to visit an URL. It browse a website page and return the text content.", + Properties: map[string]jsonschema.Definition{ + "url": { + Type: jsonschema.String, + Description: "The website URL.", + }, + }, + Required: []string{"url"}, + } +} diff --git a/external/scraper.go b/external/scrape.go similarity index 92% rename from external/scraper.go rename to external/scrape.go index d0f0a30..ce001be 100644 --- a/external/scraper.go +++ b/external/scrape.go @@ -38,7 +38,7 @@ func (a *ScraperAction) Run(ctx context.Context, params action.ActionParams) (st func (a *ScraperAction) Definition() action.ActionDefinition { return action.ActionDefinition{ Name: "scrape", - Description: "Scrapes a website and returns the site data.", + Description: "Scrapes a full website content and returns the entire site data.", Properties: map[string]jsonschema.Definition{ "url": { Type: jsonschema.String,