- Updated .env.example to include new configuration options for the UltiAI branding and API endpoints. - Enhanced Nginx configuration to support new API routes for the MCP and WebSocket connections. - Introduced sub-filters for branding adjustments in Nginx responses. - Added new JavaScript patch for API endpoint adjustments. - Implemented tests for new API functionalities and improved error handling in the AI gateway.
83 lines
1.9 KiB
Go
83 lines
1.9 KiB
Go
package websearch
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"net/http"
|
|
"net/url"
|
|
"strings"
|
|
)
|
|
|
|
type searxNGResponse struct {
|
|
Results []struct {
|
|
Title string `json:"title"`
|
|
URL string `json:"url"`
|
|
Content string `json:"content"`
|
|
} `json:"results"`
|
|
}
|
|
|
|
func (c *Client) searchSearXNG(ctx context.Context, provider Provider, query string, count int) ([]Result, error) {
|
|
base := strings.TrimRight(strings.TrimSpace(provider.BaseURL), "/")
|
|
if base == "" {
|
|
return nil, fmt.Errorf("searxng base url is required")
|
|
}
|
|
|
|
u, err := url.Parse(base + "/search")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
q := u.Query()
|
|
q.Set(queryParamName(provider), query)
|
|
q.Set("format", "json")
|
|
q.Set("categories", "general")
|
|
u.RawQuery = q.Encode()
|
|
|
|
req, err := http.NewRequestWithContext(ctx, http.MethodGet, u.String(), nil)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
req.Header.Set("Accept", "application/json")
|
|
if apiKey := strings.TrimSpace(provider.APIKey); apiKey != "" {
|
|
header := strings.TrimSpace(provider.AuthHeader)
|
|
if header == "" {
|
|
header = "Authorization"
|
|
}
|
|
if strings.EqualFold(header, "Authorization") {
|
|
req.Header.Set(header, "Bearer "+apiKey)
|
|
} else {
|
|
req.Header.Set(header, apiKey)
|
|
}
|
|
}
|
|
|
|
body, status, err := c.doRequest(req)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if status >= 400 {
|
|
return nil, fmt.Errorf("searxng search failed (%d): %s", status, string(body))
|
|
}
|
|
|
|
var parsed searxNGResponse
|
|
if err := json.Unmarshal(body, &parsed); err != nil {
|
|
return nil, err
|
|
}
|
|
if len(parsed.Results) == 0 {
|
|
return []Result{}, nil
|
|
}
|
|
|
|
limit := count
|
|
if len(parsed.Results) < limit {
|
|
limit = len(parsed.Results)
|
|
}
|
|
results := make([]Result, 0, limit)
|
|
for _, item := range parsed.Results[:limit] {
|
|
results = append(results, Result{
|
|
Title: strings.TrimSpace(item.Title),
|
|
URL: strings.TrimSpace(item.URL),
|
|
Description: strings.TrimSpace(item.Content),
|
|
})
|
|
}
|
|
return results, nil
|
|
}
|