refactor(tools): extract timeout consts and deduplicate WebFetchTool constructors
Address PR review feedback from xiaket: - Define searchTimeout, perplexityTimeout, fetchTimeout, defaultMaxChars, and maxRedirects as package-level consts instead of magic numbers. - Remove misleading "No proxy" comment in NewWebFetchTool. - Deduplicate NewWebFetchTool by delegating to NewWebFetchToolWithProxy.
This commit is contained in:
parent
ad8abe6c3d
commit
53bf8bdbd0
1 changed files with 19 additions and 23 deletions
|
|
@ -15,6 +15,14 @@ import (
|
||||||
|
|
||||||
const (
|
const (
|
||||||
userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
|
userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
|
||||||
|
|
||||||
|
// HTTP client timeouts for web tool providers.
|
||||||
|
searchTimeout = 10 * time.Second // Brave, Tavily, DuckDuckGo
|
||||||
|
perplexityTimeout = 30 * time.Second // Perplexity (LLM-based, slower)
|
||||||
|
fetchTimeout = 60 * time.Second // WebFetchTool
|
||||||
|
|
||||||
|
defaultMaxChars = 50000
|
||||||
|
maxRedirects = 5
|
||||||
)
|
)
|
||||||
|
|
||||||
// Pre-compiled regexes for HTML text extraction
|
// Pre-compiled regexes for HTML text extraction
|
||||||
|
|
@ -409,7 +417,7 @@ func NewWebSearchTool(opts WebSearchToolOptions) (*WebSearchTool, error) {
|
||||||
|
|
||||||
// Priority: Perplexity > Brave > Tavily > DuckDuckGo
|
// Priority: Perplexity > Brave > Tavily > DuckDuckGo
|
||||||
if opts.PerplexityEnabled && opts.PerplexityAPIKey != "" {
|
if opts.PerplexityEnabled && opts.PerplexityAPIKey != "" {
|
||||||
client, err := createHTTPClient(opts.Proxy, 30*time.Second)
|
client, err := createHTTPClient(opts.Proxy, perplexityTimeout)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to create HTTP client for Perplexity: %w", err)
|
return nil, fmt.Errorf("failed to create HTTP client for Perplexity: %w", err)
|
||||||
}
|
}
|
||||||
|
|
@ -418,7 +426,7 @@ func NewWebSearchTool(opts WebSearchToolOptions) (*WebSearchTool, error) {
|
||||||
maxResults = opts.PerplexityMaxResults
|
maxResults = opts.PerplexityMaxResults
|
||||||
}
|
}
|
||||||
} else if opts.BraveEnabled && opts.BraveAPIKey != "" {
|
} else if opts.BraveEnabled && opts.BraveAPIKey != "" {
|
||||||
client, err := createHTTPClient(opts.Proxy, 10*time.Second)
|
client, err := createHTTPClient(opts.Proxy, searchTimeout)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to create HTTP client for Brave: %w", err)
|
return nil, fmt.Errorf("failed to create HTTP client for Brave: %w", err)
|
||||||
}
|
}
|
||||||
|
|
@ -427,7 +435,7 @@ func NewWebSearchTool(opts WebSearchToolOptions) (*WebSearchTool, error) {
|
||||||
maxResults = opts.BraveMaxResults
|
maxResults = opts.BraveMaxResults
|
||||||
}
|
}
|
||||||
} else if opts.TavilyEnabled && opts.TavilyAPIKey != "" {
|
} else if opts.TavilyEnabled && opts.TavilyAPIKey != "" {
|
||||||
client, err := createHTTPClient(opts.Proxy, 10*time.Second)
|
client, err := createHTTPClient(opts.Proxy, searchTimeout)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to create HTTP client for Tavily: %w", err)
|
return nil, fmt.Errorf("failed to create HTTP client for Tavily: %w", err)
|
||||||
}
|
}
|
||||||
|
|
@ -441,7 +449,7 @@ func NewWebSearchTool(opts WebSearchToolOptions) (*WebSearchTool, error) {
|
||||||
maxResults = opts.TavilyMaxResults
|
maxResults = opts.TavilyMaxResults
|
||||||
}
|
}
|
||||||
} else if opts.DuckDuckGoEnabled {
|
} else if opts.DuckDuckGoEnabled {
|
||||||
client, err := createHTTPClient(opts.Proxy, 10*time.Second)
|
client, err := createHTTPClient(opts.Proxy, searchTimeout)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to create HTTP client for DuckDuckGo: %w", err)
|
return nil, fmt.Errorf("failed to create HTTP client for DuckDuckGo: %w", err)
|
||||||
}
|
}
|
||||||
|
|
@ -517,34 +525,22 @@ type WebFetchTool struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewWebFetchTool(maxChars int) *WebFetchTool {
|
func NewWebFetchTool(maxChars int) *WebFetchTool {
|
||||||
if maxChars <= 0 {
|
// createHTTPClient cannot fail with an empty proxy string.
|
||||||
maxChars = 50000
|
tool, _ := NewWebFetchToolWithProxy(maxChars, "")
|
||||||
}
|
return tool
|
||||||
// No proxy — createHTTPClient cannot fail with an empty proxy string.
|
|
||||||
client, _ := createHTTPClient("", 60*time.Second)
|
|
||||||
client.CheckRedirect = func(req *http.Request, via []*http.Request) error {
|
|
||||||
if len(via) >= 5 {
|
|
||||||
return fmt.Errorf("stopped after 5 redirects")
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return &WebFetchTool{
|
|
||||||
maxChars: maxChars,
|
|
||||||
client: client,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewWebFetchToolWithProxy(maxChars int, proxy string) (*WebFetchTool, error) {
|
func NewWebFetchToolWithProxy(maxChars int, proxy string) (*WebFetchTool, error) {
|
||||||
if maxChars <= 0 {
|
if maxChars <= 0 {
|
||||||
maxChars = 50000
|
maxChars = defaultMaxChars
|
||||||
}
|
}
|
||||||
client, err := createHTTPClient(proxy, 60*time.Second)
|
client, err := createHTTPClient(proxy, fetchTimeout)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to create HTTP client for web fetch: %w", err)
|
return nil, fmt.Errorf("failed to create HTTP client for web fetch: %w", err)
|
||||||
}
|
}
|
||||||
client.CheckRedirect = func(req *http.Request, via []*http.Request) error {
|
client.CheckRedirect = func(req *http.Request, via []*http.Request) error {
|
||||||
if len(via) >= 5 {
|
if len(via) >= maxRedirects {
|
||||||
return fmt.Errorf("stopped after 5 redirects")
|
return fmt.Errorf("stopped after %d redirects", maxRedirects)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue