import "github.com/kinorai/omnifeed/internal/search/tinyfish"
Package tinyfish implements domain.Searcher against the TinyFish Search API (GET https://api.search.tinyfish.ai, X-API-Key header). TinyFish answers with live Google-grade results and returns structured filters SearXNG has to emulate: a domain allow-list instead of a `site:` operator, a recency window in minutes, and a per-result date.
Free tier, as of 2026-10: 30 requests/minute and 12,000/day per key; past the daily allowance the API answers 402 until 00:00 UTC.
DefaultEndpoint is the public TinyFish Search API.
const DefaultEndpoint = "https://api.search.tinyfish.ai"
Config configures the Searcher.
type Config struct {
Endpoint string // defaults to DefaultEndpoint
APIKey string // required; sent as X-API-Key and never logged
Client *httpx.Client
Logger *slog.Logger
// Limiter, when non-nil, paces queries to stay under the key's
// requests-per-minute limit. Nil sends unpaced.
Limiter httpx.Limiter
// MaxWait caps how long a query may sit in the Limiter before it gives up.
// Ignored when Limiter is nil. Defaults to defaultMaxWait.
MaxWait time.Duration
// Now is the clock relative dates ("5 hours ago") resolve against.
// Defaults to time.Now; tests pin it.
Now func() time.Time
}
Searcher queries the TinyFish Search API.
type Searcher struct {
// contains filtered or unexported fields
}
func New(cfg Config) *Searcher
New returns a Searcher wired with the given config.
func (*Searcher) Name() string
Name returns the searcher identifier (“tinyfish”).
func (s *Searcher) Search(ctx context.Context, query string, opts domain.SearchOptions) (domain.SearchReport, error)
Search runs the query against TinyFish and returns up to opts.Limit results. TinyFish is a single source, so its report is never Degraded: when it answers, it answered at full strength.
Generated by gomarkdoc