Documentation
¶
Index ¶
Constants ¶
const ( ProviderTavily = "tavily" ProviderNative = "native" ProviderSafari = "safari" )
Provider names, shared by the backends' Name methods and the stamps they leave on results and pages.
Variables ¶
This section is empty.
Functions ¶
func ValidateTavilyKey ¶ added in v0.32.0
ValidateTavilyKey reports whether apiKey is accepted by Tavily. It performs a single minimal search — Tavily has no dedicated auth-check endpoint — so a success confirms both that the key is valid and that the account can serve requests. Used by the settings "Test key" action before the user restarts.
Types ¶
type Backend ¶ added in v0.29.0
type Backend interface {
// Name reports the provider name this backend stamps on its answers. A
// fallback chain reports its primary's name: which backend answered a given
// call travels on the results themselves, because a chain has no single
// answer of its own.
Name() string
// Search returns up to limit results for query, best first.
Search(ctx context.Context, query string, limit int) ([]SearchResult, error)
// FetchPage returns the readable text content of a single URL.
FetchPage(ctx context.Context, url string) (PageContent, error)
}
Backend is the web-search capability behind the web_search and fetch_page tools and the deep-research pipeline. Implementations are NativeBackend (the HTTP engine chain), TavilyBackend, and SafariBackend, composed into chains with SwitchableBackend and NewFallbackBackend; the interface is what the tools and the pipeline depend on, and what a test substitutes a fake for to stay off the network.
func NewFallbackBackend ¶ added in v0.29.0
NewFallbackBackend returns a Backend that answers from primary and only reaches for secondary when primary comes back with nothing usable.
Composition lives here rather than inside either backend so the order is a wiring decision, stated once at the call site, instead of a property baked into one of them. That matters because the order has changed once already and the arguments for it are not permanent: the browser path was the default while the HTTP path was easy to block, and became the fallback once the HTTP path stopped being.
A nil secondary yields primary unchanged, which is what the non-darwin build of NewSafariBackend produces — so callers wire the chain unconditionally and the platform question stays in one place.
func NewSafariBackend ¶ added in v0.29.0
func NewSafariBackend() Backend
Safari automation is macOS-only. On every other platform there is no browser fallback to offer, so this returns nil — which NewFallbackBackend reads as "no fallback" and collapses to the primary. Callers therefore wire the chain the same way everywhere, and the platform question is answered here rather than behind a build tag at every call site.
type NativeBackend ¶ added in v0.29.0
type NativeBackend struct {
// contains filtered or unexported fields
}
NativeBackend is ogcode's web-search backend: plain HTTP against JS-free search endpoints, plus Readability text extraction. It is compiled into the binary and needs no Node.js, no npm packages and no Chromium download.
It cannot read pages that only exist after JavaScript runs, nor hosts that bot-block plain HTTP clients (Cloudflare interstitials). Those fetches fail cleanly: the deep-research pipeline drops them and synthesises from the pages it did get.
func NewNativeBackend ¶ added in v0.29.0
func NewNativeBackend() *NativeBackend
NewNativeBackend builds a native backend with its own connection pool.
func (*NativeBackend) FetchPage ¶ added in v0.29.0
func (n *NativeBackend) FetchPage(ctx context.Context, rawURL string) (PageContent, error)
FetchPage retrieves a URL over plain HTTP and extracts its readable text.
func (*NativeBackend) Name ¶ added in v0.32.0
func (n *NativeBackend) Name() string
Name reports the provider name stamped on this backend's results.
func (*NativeBackend) Search ¶ added in v0.29.0
func (n *NativeBackend) Search(ctx context.Context, query string, limit int) ([]SearchResult, error)
Search queries each engine in turn and returns the first non-empty result set.
type PageContent ¶
type PageContent struct {
URL string `json:"url"`
Title string `json:"title"`
Text string `json:"text"`
Truncated bool `json:"truncated"`
// Provider carries the same attribution as SearchResult.Provider.
Provider string `json:"provider,omitempty"`
}
PageContent is the extracted text of a single fetched page.
type SearchResult ¶
type SearchResult struct {
Title string `json:"title"`
URL string `json:"url"`
Snippet string `json:"snippet"`
// Provider names the backend that produced this result. A fallback
// overwrites the stamp when its secondary answers, so it always names the
// backend that actually answered — the web_search and fetch_page tools show
// it, which is how "did Tavily answer, or did the native chain rescue the
// call?" stopped being a guess.
Provider string `json:"provider,omitempty"`
}
SearchResult is one entry returned by a Backend's Search.
type SwitchableBackend ¶ added in v0.32.0
type SwitchableBackend struct {
// contains filtered or unexported fields
}
SwitchableBackend is a Backend whose underlying implementation can be replaced at runtime. The web_search / fetch_page tools and the deep-research pipeline hold this stable wrapper, so changing the search provider in settings takes effect on the next call — no restart, no re-registering tools.
Swaps are guarded by a read-write mutex: searches take the read lock (many can run at once), a Set takes the write lock briefly. A search already in flight keeps running on the backend it captured; only calls that start after the swap see the new one.
func NewSwitchableBackend ¶ added in v0.32.0
func NewSwitchableBackend(b Backend) *SwitchableBackend
NewSwitchableBackend returns a switchable wrapper around b.
func (*SwitchableBackend) FetchPage ¶ added in v0.32.0
func (s *SwitchableBackend) FetchPage(ctx context.Context, url string) (PageContent, error)
func (*SwitchableBackend) Name ¶ added in v0.32.0
func (s *SwitchableBackend) Name() string
Name reports the active backend's name, or "none" before one is configured. A live swap changes what this returns on the next call, in step with what Search and FetchPage then answer.
func (*SwitchableBackend) Search ¶ added in v0.32.0
func (s *SwitchableBackend) Search(ctx context.Context, query string, limit int) ([]SearchResult, error)
func (*SwitchableBackend) Set ¶ added in v0.32.0
func (s *SwitchableBackend) Set(b Backend)
Set replaces the active backend. Safe to call concurrently with Search and FetchPage.
type TavilyBackend ¶ added in v0.32.0
type TavilyBackend struct {
// contains filtered or unexported fields
}
TavilyBackend answers web_search and fetch_page through the Tavily API (https://tavily.com) using the user's own API key. It implements the same Backend interface as NativeBackend, so once constructed it is indistinguishable to the tools and the deep-research pipeline.
Tavily authenticates with a static bearer key (tvly-…); there is no OAuth or token refresh to manage. When a call fails — a bad key, an exhausted quota, a network blip — the caller wraps this backend with NewFallbackBackend(tavily, native) so search transparently falls back to the built-in engine rather than going dark.
func NewTavilyBackend ¶ added in v0.32.0
func NewTavilyBackend(apiKey string) *TavilyBackend
NewTavilyBackend returns a backend that talks to the Tavily API with apiKey. The key is not validated here; a bad key surfaces as an error on the first call (and, via the settings "Test key" action, before that).
func (*TavilyBackend) FetchPage ¶ added in v0.32.0
func (t *TavilyBackend) FetchPage(ctx context.Context, rawURL string) (PageContent, error)
FetchPage returns the readable content of url via POST /extract.
func (*TavilyBackend) Name ¶ added in v0.32.0
func (t *TavilyBackend) Name() string
Name reports the provider name stamped on this backend's results.
func (*TavilyBackend) Search ¶ added in v0.32.0
func (t *TavilyBackend) Search(ctx context.Context, query string, limit int) ([]SearchResult, error)
Search returns up to limit results for query via POST /search.