Documentation
¶
Overview ¶
Package browserhost manages Chrome processes that browser steps keep alive between step executions: their durable records, reachability probes, and cleanup.
Index ¶
- Constants
- Variables
- func BrowserID(ctx context.Context, cdpURL string) (string, error)
- func BrowserProcessID(ctx context.Context, cdpURL string) (int, error)
- func CloseBrowser(ctx context.Context, cdpURL string) error
- func DenyDownloads(ctx context.Context, cdpURL string) error
- func Probe(ctx context.Context, cdpURL string) error
- func RecordID(dagRunID, stepName string) string
- func Release(ctx context.Context, store *Store, record Record) error
- func RetireAbandoned(ctx context.Context, store *Store, id string, now time.Time) (bool, error)
- func RunReaper(ctx context.Context, browserDataDir string, resumable ResumableFunc)
- func Sweep(ctx context.Context, store *Store, now time.Time, resumable ResumableFunc) error
- func SweepAll(ctx context.Context, browserDataDir string, now time.Time, ...) error
- func UsesProfile(ctx context.Context, cdpURL, dir string) (bool, error)
- type BlockedRequestWatcher
- type Dialog
- type DialogWatcher
- type Download
- type DownloadWatcher
- type Extension
- type Record
- type ResumableFunc
- type State
- type Store
- func (s *Store) Delete(id string) error
- func (s *Store) List() ([]Record, error)
- func (s *Store) Load(id string) (Record, error)
- func (s *Store) Purge(id string) error
- func (s *Store) Save(record Record) error
- func (s *Store) SessionLock(id string) dirlock.DirLock
- func (s *Store) WorkDir(id string) string
Constants ¶
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" )
const ( // ReapInterval is how often a long-lived process sweeps browser sessions. ReapInterval = time.Minute )
const SessionRetention = 24 * time.Hour
SessionRetention is how long a browser session's history is kept after its browser closed on its own.
const StagehandExtensionName = "Stagehand Runtime"
StagehandExtensionName is the name the Stagehand runtime extension reports to Chrome.
Variables ¶
var ErrExtensionNotFound = errors.New("stagehand runtime extension is not loaded")
ErrExtensionNotFound reports that the connected browser has no enabled Stagehand runtime extension.
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 BrowserID ¶
BrowserID identifies the browser answering at cdpURL. A browser started later on the same address has another identity. The error wraps ErrUnreachable when nothing accepts connections there.
func BrowserProcessID ¶
BrowserProcessID returns the process ID of the browser at cdpURL.
func CloseBrowser ¶
CloseBrowser asks the browser at cdpURL to exit. A browser that no longer answers is treated as already closed.
func DenyDownloads ¶
DenyDownloads makes the browser at cdpURL refuse every download.
func Release ¶
Release closes the browser described by record, deletes the files it owns, and removes the record.
func RetireAbandoned ¶
RetireAbandoned retires the browser session id when nothing will use its browser again, unless one of its commands holds it. It reports whether the session was retired.
func RunReaper ¶
func RunReaper(ctx context.Context, browserDataDir string, resumable ResumableFunc)
RunReaper sweeps the browsers steps keep and the browser sessions under the browser data directory until ctx is cancelled.
func Sweep ¶
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.
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 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.
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"`
// CertProxyURL locates the proxy presenting the browser's client
// certificates, which runs while the browser does; CertProxyPID and
// CertProxyStartedAt identify its process, so it can be ended with the
// browser.
CertProxyURL string `json:"certProxyUrl,omitempty"`
CertProxyPID int `json:"certProxyPid,omitempty"`
CertProxyStartedAt int64 `json:"certProxyStartedAt,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"`
// WorkDir holds the files a browser session owns, such as its
// screenshots and downloads. It is removed with the browser.
WorkDir string `json:"workDir,omitempty"`
// Interactive is a browser session's own state, which the browser
// runtime defines.
Interactive json.RawMessage `json:"interactive,omitempty"`
}
Record is the durable description of one browser session kept by a step.
type ResumableFunc ¶
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, or a browser session command, is // driving the browser. StateRunning State = "running" // StateDetached means the browser waits for a step to resume it. StateDetached State = "detached" // StateInteractive means a browser session's browser waits for the // session's next command. StateInteractive State = "interactive" // StateEnded means a browser session's browser is closed. Its record // keeps the session's history until its deadline. StateEnded State = "ended" )
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
Store persists browser session records as private files.
func NewInteractiveStore ¶
NewInteractiveStore returns the store of browser sessions, rooted under the browser data directory. It is kept apart from the steps' store, whose sweeps release records in states they do not know.
func NewStore ¶
NewStore returns the store of the browsers steps keep, rooted under the browser data directory.
func (*Store) SessionLock ¶
SessionLock returns the lock held by whatever uses the browser of the session id: one of its commands, or a sweep closing it.