browserhost

package
v2.18.2 Latest Latest
Warning

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

Go to latest
Published: Oct 4, 2026 License: GPL-3.0 Imports: 19 Imported by: 0

Documentation

Overview

Package browserhost manages Chrome processes that browser steps keep alive between step executions: their durable records, reachability probes, and cleanup.

Index

Constants

View Source
const (
	// AgentProvider identifies browser steps in agent sessions.
	AgentProvider = "browser"
	// DataDirName is the directory under the Dagu data directory that holds
	// browser state.
	DataDirName = "browser"
)
View Source
const (

	// ReapInterval is how often a long-lived process sweeps browser sessions.
	ReapInterval = time.Minute
)
View Source
const StagehandExtensionName = "Stagehand Runtime"

StagehandExtensionName is the name the Stagehand runtime extension reports to Chrome.

Variables

View Source
var ErrExtensionNotFound = errors.New("stagehand runtime extension is not loaded")

ErrExtensionNotFound reports that the connected browser has no enabled Stagehand runtime extension.

View Source
var ErrUnreachable = errors.New("browser is not running")

ErrUnreachable reports that nothing accepts connections at a browser's DevTools address, so the browser is no longer running.

Functions

func BrowserProcessID

func BrowserProcessID(ctx context.Context, cdpURL string) (int, error)

BrowserProcessID returns the process ID of the browser at cdpURL.

func CloseBrowser

func CloseBrowser(ctx context.Context, cdpURL string) error

CloseBrowser asks the browser at cdpURL to exit. A browser that no longer answers is treated as already closed.

func DenyDownloads

func DenyDownloads(ctx context.Context, cdpURL string) error

DenyDownloads makes the browser at cdpURL refuse every download.

func Probe

func Probe(ctx context.Context, cdpURL string) error

Probe reports whether a browser answers on its DevTools endpoint.

func RecordID

func RecordID(dagRunID, stepName string) string

RecordID returns the record identifier for a step of a DAG run.

func Release

func Release(ctx context.Context, store *Store, record Record) error

Release closes the browser described by record, deletes the files it owns, and removes the record.

func RunReaper

func RunReaper(ctx context.Context, store *Store, resumable ResumableFunc)

RunReaper sweeps the store until ctx is cancelled.

func Sweep

func Sweep(ctx context.Context, store *Store, now time.Time, resumable ResumableFunc) error

Sweep closes browsers that no step can resume and removes their records: running sessions whose owner process is gone, detached sessions past their deadline, and detached sessions whose step can no longer resume.

func UsesProfile added in v2.18.2

func UsesProfile(ctx context.Context, cdpURL, dir string) (bool, error)

UsesProfile reports whether the browser at cdpURL was started with dir as its user data directory. Each launch uses its own directory, so a match identifies the browser that launch started.

Types

type BlockedRequestWatcher added in v2.17.2

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

BlockedRequestWatcher counts the requests of a browser's pages and frames that a DevTools client blocked, by host.

func WatchBlockedRequests added in v2.17.2

func WatchBlockedRequests(ctx context.Context, cdpURL string) (*BlockedRequestWatcher, error)

WatchBlockedRequests counts blocked requests in the pages of the browser at cdpURL, including pages and frames opened later, until the watcher is closed.

func (*BlockedRequestWatcher) Close added in v2.17.2

func (w *BlockedRequestWatcher) Close() error

Close stops watching.

func (*BlockedRequestWatcher) Take added in v2.17.2

func (w *BlockedRequestWatcher) Take() (map[string]int, error)

Take returns the number of requests blocked per host since the previous call, or nil when none were. Its error reports that the watcher lost its connection and counts no further requests.

type Dialog

type Dialog struct {
	// Type is alert, confirm, prompt, or beforeunload.
	Type    string
	Message string
}

Dialog is a JavaScript dialog a page opened and the watcher accepted.

type DialogWatcher

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

DialogWatcher accepts the JavaScript dialogs a browser's pages open. An open dialog blocks its page until it is answered.

func WatchDialogs

func WatchDialogs(ctx context.Context, cdpURL string) (*DialogWatcher, error)

WatchDialogs accepts every dialog in the pages of the browser at cdpURL, including pages opened later, until the watcher is closed. A prompt is answered with its default text.

func (*DialogWatcher) Close

func (w *DialogWatcher) Close() error

Close stops watching. Dialogs opened afterwards stay open.

func (*DialogWatcher) Take

func (w *DialogWatcher) Take() []Dialog

Take returns the dialogs accepted since the previous call.

type Download

type Download struct {
	Name string
	Path string
}

Download is a file the browser finished saving.

type DownloadWatcher

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

DownloadWatcher saves the browser's downloads into a directory and tracks which are still in progress.

func WatchDownloads

func WatchDownloads(ctx context.Context, cdpURL, dir string) (*DownloadWatcher, error)

WatchDownloads saves downloads from the browser at cdpURL into dir until the watcher is closed.

func (*DownloadWatcher) Close

func (w *DownloadWatcher) Close() error

Close stops watching. Downloads still in progress are left to the browser.

func (*DownloadWatcher) Wait

func (w *DownloadWatcher) Wait(ctx context.Context, grace, timeout time.Duration) ([]Download, error)

Wait returns the downloads completed since the previous call. It first allows grace for a download to begin, then waits until none is in progress. It fails when a download was canceled or is still running when timeout passes.

type Extension

type Extension struct {
	ID      string `json:"id"`
	Name    string `json:"name"`
	Path    string `json:"path"`
	Enabled bool   `json:"enabled"`
}

Extension describes an unpacked extension loaded into a browser.

func StagehandExtension

func StagehandExtension(ctx context.Context, cdpURL string) (Extension, error)

StagehandExtension returns the enabled Stagehand runtime extension loaded into the browser at cdpURL.

type Record

type Record struct {
	ID       string `json:"id"`
	DAGName  string `json:"dagName"`
	DAGRunID string `json:"dagRunId"`
	StepName string `json:"stepName"`
	// Generation is the agent-session generation that owns the browser.
	Generation int   `json:"generation"`
	State      State `json:"state"`
	// Deadline bounds how long a detached browser waits to be resumed.
	Deadline time.Time `json:"deadline,omitzero"`

	CDPURL          string `json:"cdpUrl"`
	ExtensionID     string `json:"extensionId,omitempty"`
	ExtensionDir    string `json:"extensionDir,omitempty"`
	UserDataDir     string `json:"userDataDir,omitempty"`
	OwnsUserDataDir bool   `json:"ownsUserDataDir,omitempty"`
	Profile         string `json:"profile,omitempty"`
	DownloadsDir    string `json:"downloadsDir,omitempty"`

	// BrowserPID and BrowserStartedAt identify the browser process, so it can
	// be ended when it no longer answers on its DevTools address.
	BrowserPID       int   `json:"browserPid,omitempty"`
	BrowserStartedAt int64 `json:"browserStartedAt,omitempty"`

	// OwnerPID and OwnerStartedAt identify the process driving a running
	// browser, so a crashed owner can be detected even after PID reuse.
	OwnerPID       int   `json:"ownerPid,omitempty"`
	OwnerStartedAt int64 `json:"ownerStartedAt,omitempty"`

	// Cursor is the index of the next operation a resumed step runs.
	Cursor int `json:"cursor"`
	// Outputs holds values extracted before the step detached.
	Outputs map[string]any `json:"outputs,omitempty"`
	// ReplayPending and ReplayUsed carry the step's replay cache changes
	// across the wait: the act operations it recorded or dropped, applied
	// only if the step succeeds, and the recordings it replayed, as they
	// were read.
	ReplayPending map[string]json.RawMessage `json:"replayPending,omitempty"`
	ReplayUsed    map[string]json.RawMessage `json:"replayUsed,omitempty"`
}

Record is the durable description of one browser session kept by a step.

type ResumableFunc

type ResumableFunc func(context.Context, Record) bool

ResumableFunc reports whether a detached session still belongs to a step that can resume it. A nil ResumableFunc treats every unexpired session as resumable.

type State

type State string

State describes who currently holds a browser session.

const (
	// StateRunning means a step execution is driving the browser.
	StateRunning State = "running"
	// StateDetached means the browser waits for a step to resume it.
	StateDetached State = "detached"
)

type Store

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

Store persists browser session records as private files.

func NewStore

func NewStore(browserDataDir string) *Store

NewStore returns a store rooted under the browser data directory.

func (*Store) Delete

func (s *Store) Delete(id string) error

Delete removes the record with id. A missing record is not an error.

func (*Store) List

func (s *Store) List() ([]Record, error)

List returns every readable record.

func (*Store) Load

func (s *Store) Load(id string) (Record, error)

Load returns the record with id. A missing record reports os.ErrNotExist.

func (*Store) Save

func (s *Store) Save(record Record) error

Save writes the record, replacing any previous version.

Jump to

Keyboard shortcuts

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