diff --git a/pkg/agent/loop_init.go b/pkg/agent/loop_init.go index 283ead868..a1fd3f873 100644 --- a/pkg/agent/loop_init.go +++ b/pkg/agent/loop_init.go @@ -22,6 +22,7 @@ import ( "jane/pkg/skills" "jane/pkg/state" "jane/pkg/tools" + "jane/pkg/tools/web" "jane/pkg/voice" ) @@ -74,7 +75,7 @@ func registerSharedTools( } if cfg.Tools.IsToolEnabled("web") { - searchTool, err := tools.NewWebSearchTool(tools.WebSearchToolOptions{ + searchTool, err := web.NewWebSearchTool(web.WebSearchToolOptions{ BraveAPIKeys: config.MergeAPIKeys(cfg.Tools.Web.Brave.APIKey, cfg.Tools.Web.Brave.APIKeys), BraveMaxResults: cfg.Tools.Web.Brave.MaxResults, BraveEnabled: cfg.Tools.Web.Brave.Enabled, @@ -107,7 +108,7 @@ func registerSharedTools( } } if cfg.Tools.IsToolEnabled("web_fetch") { - fetchTool, err := tools.NewWebFetchToolWithProxy(50000, cfg.Tools.Web.Proxy, cfg.Tools.Web.FetchLimitBytes) + fetchTool, err := web.NewWebFetchToolWithProxy(50000, cfg.Tools.Web.Proxy, cfg.Tools.Web.FetchLimitBytes) if err != nil { logger.ErrorCF("agent", "Failed to create web fetch tool", map[string]any{"error": err.Error()}) } else { diff --git a/pkg/tools/web_common.go b/pkg/tools/web/common.go similarity index 99% rename from pkg/tools/web_common.go rename to pkg/tools/web/common.go index 2c2fb007a..7a769bcc8 100644 --- a/pkg/tools/web_common.go +++ b/pkg/tools/web/common.go @@ -1,4 +1,4 @@ -package tools +package web import ( "fmt" diff --git a/pkg/tools/web_common_test.go b/pkg/tools/web/common_test.go similarity index 99% rename from pkg/tools/web_common_test.go rename to pkg/tools/web/common_test.go index 11db8624f..efad6ae3b 100644 --- a/pkg/tools/web_common_test.go +++ b/pkg/tools/web/common_test.go @@ -1,4 +1,4 @@ -package tools +package web import ( "net/http" diff --git a/pkg/tools/web_fetch_tool.go b/pkg/tools/web/fetch.go similarity index 87% rename from pkg/tools/web_fetch_tool.go rename to pkg/tools/web/fetch.go index 8a3a6b974..44d836f18 100644 --- a/pkg/tools/web_fetch_tool.go +++ b/pkg/tools/web/fetch.go @@ -1,6 +1,7 @@ -package tools +package web import ( + "jane/pkg/tools" "context" "encoding/json" "errors" @@ -86,30 +87,30 @@ func (t *WebFetchTool) Parameters() map[string]any { } } -func (t *WebFetchTool) Execute(ctx context.Context, args map[string]any) *ToolResult { +func (t *WebFetchTool) Execute(ctx context.Context, args map[string]any) *tools.ToolResult { urlStr, ok := args["url"].(string) if !ok { - return ErrorResult("url is required") + return tools.ErrorResult("url is required") } parsedURL, err := url.Parse(urlStr) if err != nil { - return ErrorResult(fmt.Sprintf("invalid URL: %v", err)) + return tools.ErrorResult(fmt.Sprintf("invalid URL: %v", err)) } if parsedURL.Scheme != "http" && parsedURL.Scheme != "https" { - return ErrorResult("only http/https URLs are allowed") + return tools.ErrorResult("only http/https URLs are allowed") } if parsedURL.Host == "" { - return ErrorResult("missing domain in URL") + return tools.ErrorResult("missing domain in URL") } // Lightweight pre-flight: block obvious localhost/literal-IP without DNS resolution. // The real SSRF guard is newSafeDialContext at connect time. hostname := parsedURL.Hostname() if isObviousPrivateHost(hostname) { - return ErrorResult("fetching private or local network hosts is not allowed") + return tools.ErrorResult("fetching private or local network hosts is not allowed") } maxChars := t.maxChars @@ -121,13 +122,13 @@ func (t *WebFetchTool) Execute(ctx context.Context, args map[string]any) *ToolRe req, err := http.NewRequestWithContext(ctx, "GET", urlStr, nil) if err != nil { - return ErrorResult(fmt.Sprintf("failed to create request: %v", err)) + return tools.ErrorResult(fmt.Sprintf("failed to create request: %v", err)) } req.Header.Set("User-Agent", userAgent) resp, err := t.client.Do(req) if err != nil { - return ErrorResult(fmt.Sprintf("request failed: %v", err)) + return tools.ErrorResult(fmt.Sprintf("request failed: %v", err)) } resp.Body = http.MaxBytesReader(nil, resp.Body, t.fetchLimitBytes) @@ -138,9 +139,9 @@ func (t *WebFetchTool) Execute(ctx context.Context, args map[string]any) *ToolRe if err != nil { var maxBytesErr *http.MaxBytesError if errors.As(err, &maxBytesErr) { - return ErrorResult(fmt.Sprintf("failed to read response: size exceeded %d bytes limit", t.fetchLimitBytes)) + return tools.ErrorResult(fmt.Sprintf("failed to read response: size exceeded %d bytes limit", t.fetchLimitBytes)) } - return ErrorResult(fmt.Sprintf("failed to read response: %v", err)) + return tools.ErrorResult(fmt.Sprintf("failed to read response: %v", err)) } contentType := resp.Header.Get("Content-Type") @@ -182,7 +183,7 @@ func (t *WebFetchTool) Execute(ctx context.Context, args map[string]any) *ToolRe resultJSON, _ := json.MarshalIndent(result, "", " ") - return &ToolResult{ + return &tools.ToolResult{ ForLLM: string(resultJSON), ForUser: fmt.Sprintf( "Fetched %d bytes from %s (extractor: %s, truncated: %v)", diff --git a/pkg/tools/web_fetch_tool_test.go b/pkg/tools/web/fetch_test.go similarity index 99% rename from pkg/tools/web_fetch_tool_test.go rename to pkg/tools/web/fetch_test.go index 9e8ae3a6b..db993e512 100644 --- a/pkg/tools/web_fetch_tool_test.go +++ b/pkg/tools/web/fetch_test.go @@ -1,4 +1,4 @@ -package tools +package web import ( "bytes" @@ -213,7 +213,7 @@ func TestWebFetchTool_PayloadTooLarge(t *testing.T) { result := tool.Execute(ctx, args) if result == nil { - t.Fatal("expected a ToolResult, got nil") + t.Fatal("expected a tools.ToolResult, got nil") } expectedErrorMsg := fmt.Sprintf("size exceeded %d bytes limit", testFetchLimit) diff --git a/pkg/tools/web_keys.go b/pkg/tools/web/keys.go similarity index 98% rename from pkg/tools/web_keys.go rename to pkg/tools/web/keys.go index 248333d20..28066eab7 100644 --- a/pkg/tools/web_keys.go +++ b/pkg/tools/web/keys.go @@ -1,4 +1,4 @@ -package tools +package web import ( "sync/atomic" diff --git a/pkg/tools/web_keys_test.go b/pkg/tools/web/keys_test.go similarity index 99% rename from pkg/tools/web_keys_test.go rename to pkg/tools/web/keys_test.go index 2609b8fa4..39a3e852d 100644 --- a/pkg/tools/web_keys_test.go +++ b/pkg/tools/web/keys_test.go @@ -1,4 +1,4 @@ -package tools +package web import ( "testing" diff --git a/pkg/tools/web_search_providers.go b/pkg/tools/web/providers.go similarity index 99% rename from pkg/tools/web_search_providers.go rename to pkg/tools/web/providers.go index 02c64ea32..c08282579 100644 --- a/pkg/tools/web_search_providers.go +++ b/pkg/tools/web/providers.go @@ -1,4 +1,4 @@ -package tools +package web import ( "bytes" diff --git a/pkg/tools/web_search_tool.go b/pkg/tools/web/search.go similarity index 95% rename from pkg/tools/web_search_tool.go rename to pkg/tools/web/search.go index 53e29da72..d23b7d619 100644 --- a/pkg/tools/web_search_tool.go +++ b/pkg/tools/web/search.go @@ -1,6 +1,7 @@ -package tools +package web import ( + "jane/pkg/tools" "context" "fmt" ) @@ -144,10 +145,10 @@ func (t *WebSearchTool) Parameters() map[string]any { } } -func (t *WebSearchTool) Execute(ctx context.Context, args map[string]any) *ToolResult { +func (t *WebSearchTool) Execute(ctx context.Context, args map[string]any) *tools.ToolResult { query, ok := args["query"].(string) if !ok { - return ErrorResult("query is required") + return tools.ErrorResult("query is required") } count := t.maxResults @@ -159,10 +160,10 @@ func (t *WebSearchTool) Execute(ctx context.Context, args map[string]any) *ToolR result, err := t.provider.Search(ctx, query, count) if err != nil { - return ErrorResult(fmt.Sprintf("search failed: %v", err)) + return tools.ErrorResult(fmt.Sprintf("search failed: %v", err)) } - return &ToolResult{ + return &tools.ToolResult{ ForLLM: result, ForUser: result, } diff --git a/pkg/tools/web_search_tool_test.go b/pkg/tools/web/search_test.go similarity index 99% rename from pkg/tools/web_search_tool_test.go rename to pkg/tools/web/search_test.go index b622121d9..9f9224c15 100644 --- a/pkg/tools/web_search_tool_test.go +++ b/pkg/tools/web/search_test.go @@ -1,4 +1,4 @@ -package tools +package web import ( "context" diff --git a/pkg/tools/web_ssrf.go b/pkg/tools/web/ssrf.go similarity index 99% rename from pkg/tools/web_ssrf.go rename to pkg/tools/web/ssrf.go index c0fbb079b..865e6d98a 100644 --- a/pkg/tools/web_ssrf.go +++ b/pkg/tools/web/ssrf.go @@ -1,4 +1,4 @@ -package tools +package web import ( "context" diff --git a/pkg/tools/web_ssrf_test.go b/pkg/tools/web/ssrf_test.go similarity index 99% rename from pkg/tools/web_ssrf_test.go rename to pkg/tools/web/ssrf_test.go index 12ec84af8..56f2d8a00 100644 --- a/pkg/tools/web_ssrf_test.go +++ b/pkg/tools/web/ssrf_test.go @@ -1,4 +1,4 @@ -package tools +package web import ( "context"