webcontent

package
v0.17.7 Latest Latest
Warning

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

Go to latest
Published: Jul 23, 2026 License: MIT Imports: 22 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func BrowseURL

func BrowseURL(url string, opts BrowseOptions) (string, error)

BrowseURL performs browser-based actions on a URL (screenshots, DOM capture, text extraction). It requires the browser build tag and a headless browser (Chromium).

func CloseGlobalBrowser

func CloseGlobalBrowser()

CloseGlobalBrowser closes the global browser renderer, releasing Chromium resources. This should be called during graceful shutdown.

func HTMLToText

func HTMLToText(htmlBody string) string

HTMLToText converts an HTML document to plain text, extracting only visible content. Block elements become newlines, list items are numbered or bulleted, and script/style/noscript content is stripped entirely. Useful <head> metadata (title, description, canonical URL) is extracted and prepended to the output. The result is post-processed to collapse whitespace, remove useless lines, and deduplicate repeated navigation links.

func NeedsRendering

func NeedsRendering(html string) bool

NeedsRendering inspects a raw HTML document and reports whether the page appears to be a single-page application (SPA) shell that needs browser rendering to produce meaningful content, as opposed to a server-rendered page whose text is already extractable from the raw HTML.

The function combines four heuristic signals:

  1. SPA shell pattern — empty mount-point divs such as <div id="root">, <div id="app">, <div id="__next">, etc.
  2. Framework markers in <script> tags (e.g. __NEXT_DATA__, __NUXT__, script src containing "react", "vue", "angular", "svelte", etc.) — only when combined with low visible text (to avoid SSR false positives).
  3. Large inline script blocks whose total content exceeds a threshold relative to the overall document length.
  4. Very low visible-text-to-HTML ratio (the catch-all signal).

It operates on raw strings with simple scanning — no DOM parsing — for efficiency on large responses.

Types

type BrowseOptions

type BrowseOptions struct {
	// Ctx carries a context for cancellation/deadlines; if nil, context.Background() is used.
	Ctx context.Context
	// ViewportWidth sets the browser viewport width in pixels (0 = default 1280)
	ViewportWidth int
	// ViewportHeight sets the browser viewport height in pixels (0 = default 720)
	ViewportHeight int
	// UserAgent overrides the browser user-agent string
	UserAgent string
	// Action determines what to do: "screenshot", "dom", "text", or "inspect" (default: "text")
	Action string
	// ScreenshotPath is the file path for screenshot output (required for action="screenshot")
	ScreenshotPath string
	// SessionID reuses or names a persistent built-in browser session for iterative debugging.
	SessionID string
	// PersistSession keeps the browser page alive after this call and returns a session_id in the result.
	PersistSession bool
	// CloseSession closes the referenced persistent session after this call completes.
	CloseSession bool
	// WaitForSelector waits for a selector to appear before capturing output or running steps.
	WaitForSelector string
	// WaitTimeoutMs overrides the wait timeout for selector-based operations (default: 10000).
	WaitTimeoutMs int
	// Steps applies a series of browser interactions after navigation.
	Steps []BrowseStep
	// CaptureSelectors captures selector state after interactions.
	CaptureSelectors []string
	// CaptureDOM includes rendered DOM in inspect results.
	CaptureDOM bool
	// CaptureText includes visible text in inspect results.
	CaptureText bool
	// IncludeConsole captures browser console messages and page errors in inspect results.
	IncludeConsole bool
	// CaptureNetwork includes fetch/XHR diagnostics in inspect results.
	CaptureNetwork bool
	// CaptureStorage includes localStorage/sessionStorage snapshots in inspect results.
	CaptureStorage bool
	// CaptureCookies includes document.cookie-visible cookies in inspect results.
	CaptureCookies bool
	// ResponseMaxChars bounds large string fields in structured inspect results (0 = defaults).
	ResponseMaxChars int
	// Cookies pre-set on the page before navigation. Each entry is a cookie name=value pair.
	// Domain defaults to the navigated URL's host; path defaults to "/".
	Cookies map[string]string
	// Headers is a flat map of HTTP request headers to inject on every request.
	// Use for Authorization: Bearer <token>, X-API-Key, etc.
	Headers map[string]string
	// AllowFileURL enables file:// URL navigation (opt-in for security).
	AllowFileURL bool
}

BrowseOptions configures browser-based URL browsing.

type BrowseResult

type BrowseResult struct {
	SessionID        string            `json:"session_id,omitempty"`
	FinalURL         string            `json:"final_url"`
	Title            string            `json:"title,omitempty"`
	ReadyState       string            `json:"ready_state,omitempty"`
	VisibleText      string            `json:"visible_text,omitempty"`
	DOM              string            `json:"dom,omitempty"`
	ScreenshotPath   string            `json:"screenshot_path,omitempty"`
	SelectorCaptures []SelectorCapture `json:"selector_captures,omitempty"`
	ConsoleMessages  []string          `json:"console_messages,omitempty"`
	PageErrors       []string          `json:"page_errors,omitempty"`
	NetworkRequests  []NetworkRequest  `json:"network_requests,omitempty"`
	CORSIssues       []string          `json:"cors_issues,omitempty"`
	Cookies          map[string]string `json:"cookies,omitempty"`
	LocalStorage     map[string]string `json:"local_storage,omitempty"`
	SessionStorage   map[string]string `json:"session_storage,omitempty"`
	EvalResults      []EvalResult      `json:"eval_results,omitempty"`
	Actions          []string          `json:"actions,omitempty"`
}

BrowseResult contains structured browser inspection output.

type BrowseStep

type BrowseStep struct {
	Action   string `json:"action"`
	Selector string `json:"selector,omitempty"`
	Value    string `json:"value,omitempty"`
	Key      string `json:"key,omitempty"`
	Millis   int    `json:"millis,omitempty"`
	Script   string `json:"script,omitempty"`
	Expect   string `json:"expect,omitempty"`
	// ScreenshotPath (for screenshot_selector action) — file path for the cropped element screenshot.
	ScreenshotPath string `json:"screenshot_path,omitempty"`
}

BrowseStep describes a single browser interaction step.

type BrowserRenderer

type BrowserRenderer interface {
	// RenderPage navigates to the given URL using a headless browser,
	// waits for JavaScript to execute, and returns the fully rendered HTML.
	RenderPage(ctx context.Context, url string) (string, error)

	// Screenshot captures a screenshot of the given URL and writes it to outputPath.
	// viewportWidth and viewportHeight set the browser viewport dimensions (0 = use defaults 1280x720).
	// userAgent overrides the browser user-agent string ("" = use default).
	Screenshot(ctx context.Context, url string, outputPath string, viewportWidth, viewportHeight int, userAgent string) error

	// CaptureDOM returns the rendered HTML of the page (similar to RenderPage but specifically
	// for capturing the DOM state after JS execution). Use this when you need the full HTML
	// rather than text-extracted content.
	CaptureDOM(ctx context.Context, url string, viewportWidth, viewportHeight int, userAgent string) (string, error)

	// Run executes an interactive browser workflow against the given URL and returns
	// a structured result suitable for debugging, testing, and JS-rendered scraping.
	Run(ctx context.Context, url string, opts BrowseOptions) (*BrowseResult, error)

	// Close releases any resources held by the renderer (browsers, pages, etc.)
	Close()
}

BrowserRenderer renders HTML pages using a headless browser. Implementations may require external dependencies (e.g., rod/Chromium) and are loaded via build tags.

func GetGlobalBrowser

func GetGlobalBrowser() BrowserRenderer

func NewBrowserRenderer

func NewBrowserRenderer() BrowserRenderer

NewBrowserRenderer returns a BrowserRenderer backed by go-rod. The browser is launched lazily on the first call to RenderPage.

type DuckDuckGoSearchProvider

type DuckDuckGoSearchProvider struct{}

DuckDuckGoSearchProvider implements SearchProvider for DuckDuckGo

func (*DuckDuckGoSearchProvider) Name

func (d *DuckDuckGoSearchProvider) Name() string

func (*DuckDuckGoSearchProvider) Search

func (d *DuckDuckGoSearchProvider) Search(query string, logger *utils.Logger) ([]SearchResult, error)

type ElementBox

type ElementBox struct {
	X      float64 `json:"x"`
	Y      float64 `json:"y"`
	Width  float64 `json:"width"`
	Height float64 `json:"height"`
}

type EvalResult

type EvalResult struct {
	Script string `json:"script"`
	Value  string `json:"value,omitempty"`
	Error  string `json:"error,omitempty"`
}

EvalResult captures the result of a script evaluation step.

type GitHubURLInfo

type GitHubURLInfo struct {
	Type   string // "repo", "file", "directory", "issue", "pull_request", "gist", "commit", "discussion", "actions_run", "release", "unknown"
	Owner  string
	Repo   string
	Ref    string
	Path   string
	Number int    // for issues/pulls/discussions/actions runs
	GistID string // for gists
}

GitHubURLInfo holds structured information about a GitHub URL.

func ParseGitHubURL

func ParseGitHubURL(rawURL string) GitHubURLInfo

ParseGitHubURL parses a GitHub URL into structured information about the resource it points to. For unrecognised patterns, Type is "unknown" and the remaining fields may be zero-valued.

type JinaSearchProvider

type JinaSearchProvider struct{}

JinaSearchProvider implements SearchProvider for Jina AI

func (*JinaSearchProvider) Name

func (j *JinaSearchProvider) Name() string

func (*JinaSearchProvider) Search

func (j *JinaSearchProvider) Search(query string, logger *utils.Logger) ([]SearchResult, error)

type JinaSearchResult

type JinaSearchResult struct {
	Title       string `json:"title"`
	URL         string `json:"url"`
	Description string `json:"description"` // This will be the snippet/description from search, not full content
}

JinaSearchResult represents a single search result from Jina AI Search API. Deprecated: Use SearchResult instead

type NetworkRequest

type NetworkRequest struct {
	Type        string `json:"type,omitempty"`
	URL         string `json:"url,omitempty"`
	Method      string `json:"method,omitempty"`
	Status      int    `json:"status,omitempty"`
	OK          bool   `json:"ok,omitempty"`
	Initiator   string `json:"initiator,omitempty"`
	Error       string `json:"error,omitempty"`
	CORSBlocked bool   `json:"cors_blocked,omitempty"`
}

type ReferenceCacheEntry

type ReferenceCacheEntry struct {
	Query          string            `json:"query"`
	SearchResults  []SearchResult    `json:"search_results"`  // Initial search results (snippets)
	SelectedURLs   []string          `json:"selected_urls"`   // URLs chosen by LLM
	FinalContent   string            `json:"final_content"`   // Full content fetched from selected URLs
	FetchedContent map[string]string `json:"fetched_content"` // Full content for each selected URL
	Timestamp      time.Time         `json:"timestamp"`       // When this entry was cached
}

ReferenceCacheEntry stores cached search results and fetched content.

type SearchProvider

type SearchProvider interface {
	Name() string
	Search(query string, logger *utils.Logger) ([]SearchResult, error)
}

SearchProvider defines the interface for search providers

type SearchResult

type SearchResult struct {
	Title       string `json:"title"`
	URL         string `json:"url"`
	Description string `json:"description"` // This will be the snippet/description from search, not full content
}

SearchResult represents a single search result from any search provider.

func GetSearchResults

func GetSearchResults(query string, cfg *configuration.Manager) ([]SearchResult, error)

GetSearchResults performs a web search and returns search results It tries Jina AI first, then falls back to DuckDuckGo if Jina is not available

type SelectorCapture

type SelectorCapture struct {
	Selector    string            `json:"selector"`
	Found       bool              `json:"found"`
	Count       int               `json:"count"`
	Visible     bool              `json:"visible,omitempty"`
	Enabled     bool              `json:"enabled,omitempty"`
	BoundingBox *ElementBox       `json:"bounding_box,omitempty"`
	Text        string            `json:"text,omitempty"`
	HTML        string            `json:"html,omitempty"`
	Value       string            `json:"value,omitempty"`
	Attributes  map[string]string `json:"attributes,omitempty"`
}

SelectorCapture describes the captured state of a selector after page interactions.

type URLCacheEntry

type URLCacheEntry struct {
	URL       string    `json:"url"`
	Content   string    `json:"content"`
	Timestamp time.Time `json:"timestamp"` // When this entry was cached
}

URLCacheEntry stores cached content for individual URLs

type WebContentFetcher

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

WebContentFetcher handles fetching content from URLs.

func NewWebContentFetcher

func NewWebContentFetcher() *WebContentFetcher

NewWebContentFetcher creates a new WebContentFetcher instance.

func (*WebContentFetcher) FetchWebContent

func (w *WebContentFetcher) FetchWebContent(url string, cfg *configuration.Manager) (string, error)

FetchWebContent fetches content from a given URL, using a cache to avoid refetching. It uses Jina Reader for external URLs if available, otherwise falls back to a direct HTTP GET. Content is always returned wrapped in URL banners.

Jump to

Keyboard shortcuts

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