webtools

package
v1.4.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 20, 2026 License: Apache-2.0 Imports: 24 Imported by: 0

Documentation

Overview

Package webtools implements the research tools of the reference workflow as webhook-backed tool endpoints behind the Fenced Tool Gateway:

web.search@1.0.0     query a fixed research corpus (offline deterministic)
web.fetch@1.0.0      fetch one corpus document body (SSRF-guarded)
citation.check@1.0.0 grade report citations against evidence (design doc §7)

The v1 backend is an embedded corpus so the whole workflow runs without internet access and stays reproducible in CI; deployments swap in a real search engine by replacing the Backend while keeping the wire contract:

POST {"action":"invoke","resource":...,"args":{...}} -> 200 JSON result

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func LiveHTTPClient

func LiveHTTPClient() *http.Client

LiveHTTPClient returns the production fetch client: bounded redirects to public hosts only, request timeout, and the research user agent contract.

func SelfSignedTLSListener

func SelfSignedTLSListener(handler http.Handler) (listener net.Listener, client *http.Client, endpoint string, err error)

SelfSignedTLSListener serves handler on a loopback HTTPS listener whose certificate is trusted only by clients using the returned pool. The Tool Gateway requires https:// tool endpoints, so tests and local deployments use this helper instead of plaintext.

Types

type Backend

type Backend interface {
	Search(ctx context.Context, query string, limit int) ([]SearchHit, error)
	Fetch(ctx context.Context, target string) (*FetchResult, error)
}

Backend produces search hits and fetched documents behind the stable wire contract. The deterministic corpus implements it for CI; live deployments swap in real providers (Brave/Bing search, hardened HTTP fetch) without touching the agents or the workflow.

type BingSearch

type BingSearch struct {
	APIKey   string
	Endpoint string
	Client   *http.Client
}

BingSearch implements Backend.Search against Azure Bing Search v7.

func (*BingSearch) Search

func (b *BingSearch) Search(ctx context.Context, query string, limit int) ([]SearchHit, error)

Search queries Bing and maps results to the unified hit shape.

type BraveSearch

type BraveSearch struct {
	APIKey   string
	Endpoint string // overridable for tests; defaults to braveSearchAPI
	Client   *http.Client
}

BraveSearch implements Backend.Search against the Brave Search API.

func (*BraveSearch) Search

func (b *BraveSearch) Search(ctx context.Context, query string, limit int) ([]SearchHit, error)

Search queries Brave and maps results to the unified hit shape.

type CompositeBackend

type CompositeBackend struct {
	SearchProvider SearchProvider
	FetchProvider  FetchProvider
}

CompositeBackend pairs one search provider with one fetch provider — the standard live assembly (e.g. BraveSearch + LiveFetch).

func (*CompositeBackend) Fetch

func (c *CompositeBackend) Fetch(ctx context.Context, target string) (*FetchResult, error)

Fetch delegates to the fetch provider.

func (*CompositeBackend) Search

func (c *CompositeBackend) Search(ctx context.Context, query string, limit int) ([]SearchHit, error)

Search delegates to the search provider.

type Document

type Document struct {
	SourceID    string   `json:"sourceId"`
	Title       string   `json:"title"`
	URL         string   `json:"url"`
	PublishedAt string   `json:"publishedAt"`
	Tags        []string `json:"tags"`
	Content     string   `json:"content"`
}

Document is one corpus entry.

func Corpus

func Corpus() []Document

Corpus returns the embedded v1 research corpus: twelve public-knowledge style documents on agent runtime infrastructure (2024-2026). Content is original summary text written for this reference application, so the demo needs no network access and every E2E run is deterministic.

type DoubaoSearch

type DoubaoSearch struct {
	APIKey   string
	Endpoint string // overridable for tests; defaults to doubaoSearchAPI
	Client   *http.Client
	// contains filtered or unexported fields
}

DoubaoSearch implements Backend.Search against Volcengine Doubao Search Custom. The public tool contract remains web.search@1.0.0; only this provider adapter knows the vendor request/response envelope.

func (*DoubaoSearch) Search

func (d *DoubaoSearch) Search(ctx context.Context, query string, limit int) ([]SearchHit, error)

Search queries Doubao Search Custom using its recommended API-key access mode. Search results without an original URL are excluded because the research workflow must be able to fetch and independently ground them.

type FetchProvider

type FetchProvider interface {
	Fetch(context.Context, string) (*FetchResult, error)
}

FetchProvider downloads one target into a readable document.

type FetchResult

type FetchResult struct {
	SourceID  string `json:"sourceId"`
	Title     string `json:"title"`
	URL       string `json:"url"`
	Content   string `json:"content"`
	FetchedAt string `json:"fetchedAt"`
}

FetchResult is the payload of a web.fetch response.

type LiveFetch

type LiveFetch struct {
	Client *http.Client
	// contains filtered or unexported fields
}

LiveFetch is the hardened real-web fetcher: SSRF policy, bounded redirects to public hosts only, size cap, timeout, content-type checks, HTML→readable-text extraction, final URL preserved.

func (*LiveFetch) Fetch

func (l *LiveFetch) Fetch(ctx context.Context, target string) (*FetchResult, error)

Fetch downloads one public document and returns readable text.

type SearchHit

type SearchHit struct {
	SourceID    string `json:"sourceId"`
	Title       string `json:"title"`
	URL         string `json:"url"`
	PublishedAt string `json:"publishedAt"`
	Snippet     string `json:"snippet"`
}

SearchHit is one ranked entry of a web.search response.

type SearchProvider

type SearchProvider interface {
	Search(context.Context, string, int) ([]SearchHit, error)
}

SearchProvider produces ranked hits for one query.

type Server

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

Server serves the tool contract over HTTP(S).

func New

func New(documents []Document) *Server

New builds a Server over the given documents (deterministic backend).

func (*Server) CountFetches

func (s *Server) CountFetches(observer func(action string))

CountFetches installs an observer invoked per tool call with its action ("fetch"/"search"); the failure-injection tests assert on fetch counts.

func (*Server) InjectFetchFailures

func (s *Server) InjectFetchFailures(token string, count int)

InjectFetchFailures fails the next count fetches matching token.

func (*Server) ServeHTTP

func (s *Server) ServeHTTP(writer http.ResponseWriter, request *http.Request)

func (*Server) WithBackend

func (s *Server) WithBackend(backend Backend) *Server

WithBackend replaces the backing provider (live web, enterprise search…).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL