ultisuite-backend/internal/websearch/searxng.go
R3D347HR4Y 621b0099d6
Some checks are pending
CI / Go tests (push) Waiting to run
CI / Integration tests (push) Waiting to run
CI / DB migrations (push) Waiting to run
feat(deploy): enhance Nginx configuration and API integration for UltiAI
- 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.
2026-06-15 00:22:23 +02:00

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
}