Perplexed.Search.Fallback (Perplexed v0.2.0)

Copy Markdown View Source

Opt-in provider fallback: a list of provider specs, tried in order until one answers, such as free first and paid last:

Perplexed.search("zoning setbacks", provider: [:searxng, :ceramic, :firecrawl])

Perplexed.Search.run/3 comes here whenever the provider spec is a list, so the same list works in Perplexed.search/2, Perplexed.answer/2 (its :provider) and the provider setting. A single provider behaves as it always has.

A provider's answer moves the chain on when its outcome is in :fallback_on: :error (it failed or timed out) and :empty (it answered with no hits, often how a quiet block looks) by default. Each provider runs in a task under Perplexed.TaskSupervisor and gets :provider_timeout_ms, capped by what is left of the chain's :deadline_ms; one that overruns is shut down and counts as an error. Once the deadline passes, the providers left are recorded as :deadline and not called.

The Perplexed.Search.Result names the provider that answered, carries every attempt in attempts, and costs what all of them cost (a paid provider that answered empty still bills). When every provider fails, an empty answer from one of them is still returned as the result; with no answer at all the chain is {:error, {:upstream, %{reason: :all_providers_failed, attempts: attempts}}}. Each provider's call still emits its own [:perplexed, :search, ...] span. Every attempt also emits [:perplexed, :search, :attempt] with duration (ms) and cost, and metadata provider, outcome and billable.

Summary

Functions

Runs query down chain.

Types

attempt()

@type attempt() :: %{
  provider: Perplexed.Search.spec(),
  outcome: outcome(),
  cost: float(),
  duration_ms: non_neg_integer()
}

outcome()

@type outcome() :: :ok | :empty | :timeout | :deadline | {:error, term()}

Functions

run(chain, query, opts)

@spec run([Perplexed.Search.spec(), ...], String.t(), keyword()) ::
  {:ok, Perplexed.Search.Result.t()} | {:error, Perplexed.error()}

Runs query down chain.

Options

  • :provider_timeout_ms - each provider's limit, default 15000.
  • :deadline_ms - the whole chain's limit, default 30000.
  • :fallback_on - outcomes that move on to the next provider, any of :error and :empty, default [:error, :empty].

Other options go to every provider.