omnifeed

tinyfish

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.

Index

Constants

DefaultEndpoint is the public TinyFish Search API.

const DefaultEndpoint = "https://api.search.tinyfish.ai"

type Config

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
}

type Searcher

Searcher queries the TinyFish Search API.

type Searcher struct {
    // contains filtered or unexported fields
}

func New

func New(cfg Config) *Searcher

New returns a Searcher wired with the given config.

func (*Searcher) Name

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