ブラウザー自動化は、Playwrightの上にゼロから構築されたbrowser-flowの代表的なTool種別です。これはプロジェクトの中核思想を映す2つの半分から成り立っています。オーサリング時に一度だけ賢く、実行時にはずっと決定論的に。 ブラウザーツールは、解決済みの操作リストを正規のRecordingへキャプチャして作成します。出荷される成果物は、モデルもエージェントも実行ごとの推論も持たない、素のリプレイ可能なToolです。 std/browser Packは2つのToolを提供し、browsernet のcapabilityを宣言します。
Tool半分役割
browser.record一度だけ作成Chromiumセッションを一度だけ操作し、content-addressedなRecordingをキャプチャします。
browser.toolずっと実行記録済みのPlaywright操作を、モデルなしで決定論的にリプレイします。
どちらも browser capabilityの下で実行されます。エンジンが ctx.browser にこれを提供するのは、Toolのcontractがそのcapabilityを宣言している場合だけです。つまり、構造上のcapability-gatingです(原則 T2)。このページ全体で使う実行例は、daily-price-watch Flowで使われる search-price@1.2.0 ブラウザーツールです(価格を調べるブラウザーツール、transform、そしてシークレットwebhookへの条件付き http.post)。

browser.record — 一度だけ作成

browser.record は、解決済みの操作リストからブラウザーツールを生成します。これは、順序付きPlaywright操作とDOM evidenceからなる正規のcontent-addressed JSON構造である Recording を受け取り、決定論的なToolを返します。RecordingのdigestはToolの provenance.source_digest になります。 Recordingには次が含まれます。
  • 順序付きで解決済みのPlaywright操作。ナビゲーション、role/textベースのlocator、入力、クリック、抽出です。
  • 安定したlocatorを選ぶために使われる DOM evidencegetByRole/getByText を優先し、構造セレクタへフォールバックします)。
1

解決済み操作リストを渡す

解決済みの Operation[](navigate、fill、click、select、drag、upload、extract)のJSON(またはYAML)リストを作成し、--opsbrowserflow record に渡します。
browserflow record search-price \
  --task "Search for a product and read the first result's price" \
  --ops ./ops/search-price.ops.json \
  --input query
このコマンドは、操作を(スクリプト化された RecordDriver 経由で)record() ファクトリへ渡し、正規化して、Recordingを recordings/search-price.json に書き込みます。
2

正規化してcontent-addressedにする

順序付き操作とlocator evidenceは正規化(JCS/RFC 8785)され、ハッシュ化されます。そのdigestが provenance.source_digest になり、Toolのピン留め可能で監査可能なidentityになります。
これは厳密にオーサリング時の操作です。出荷されるのはRecordingであり、実行時にdriverや賢さが呼び出されることはありません。
ライブのインタラクティブPlaywrightキャプチャ(実際のChromiumセッションを開き、クリックして進め、自動キャプチャする機能)は、将来のリリースで予定されています。@browserflow/browserrecord() 関数は、注入された RecordDriver を受け取ります。ライブPlaywright driverは、throwするstubです。テストではスクリプト化されたdriverを使います。上記のops-from-fileの経路が、現在の本番用エントリポイントです。--secret で宣言されたシークレット入力は、Recordingに決して書き込まれません。下のブラウザー内のシークレットを参照してください。

browser.tool — ずっと実行

コンパイル済みのブラウザーツールは、素の決定論的Playwrightです。これは記録済みの操作を、モデルなし、エージェントなし、実行ごとの推論なしでリプレイします。使用するlocatorはすべて記録時にDOM evidenceから選ばれているため、このToolは適応的ではないが、回復力があります。ページに対して再計画や再推論をするのではなく、記録した正確なシーケンスを実行します。 Flowでは、ピン留めされたToolを kind:name@version で参照し、その入力をコンテキストから配線します。
// daily-price-watch flow 内
.step(
  "lookup",
  browser.tool("search-price@1.2.0").with((c) => ({ query: c.input.query }))
)
steps:
  - id: lookup
    use: browser:search-price@1.2.0
    with:
      query: ${{ input.query }}
手順は search-price@^1.2 のような範囲でToolを参照できますが、コンパイラは保存されるFlowSpec内でそれを正確なversionへ解決して書き換えるため、Flowは常に完全にピン留めされます。ToolとPackを参照してください。

管理されたコンテキスト

browser capabilityの下で、RiderはToolに管理されたブラウザーコンテキストを渡します。これはローカルChromium、またはLauncherがpool経由で提供するremote/cloud browserです。Toolがambient browserへ手を伸ばすことはありません。他のすべてのcapabilityが注入されるのとまったく同じように、ctx.browser に注入されたコンテキストだけを使います(原則 T2実行を参照)。

読み取りは記録されるため、オフラインでリプレイできる

ブラウザーツールの読み取り、つまりページから抽出した値は、他のeffectと同じようにJournalへ記録されます。これにより、ブラウザー手順は他の手順と同じようにオフラインでリプレイできます。determinism modelで規定されているとおり、browser capability自体が決定論的(記録済みlocator)であり、その読み取りは記録されます。
SourceCapability再現可能に保たれる仕組み
browserbrowserブラウザーツール自体が決定論的(記録済みlocator)であり、その読み取りは記録されます
hermeticな browserflow replay では、browser capabilityは完全にJournalによってbackされます。Chromiumは起動されず、どのサイトにも接続されません。記録済みの読み取りは、記録された値を返します。テストとリプレイを参照してください。

ブラウザー内のシークレット

Cookie、token、credentialは secret: true 入力です。これらは実行時secrets capabilityを通じてブラウザーコンテキストへ注入され、Recording、FlowSpec、Journal、ログには決して書き込まれません。これが境界の不変条件です(シークレットを参照)。 これにより、credentialを永続化することなくログインをリプレイ可能にできます。ログインFlowを一度記録し、実行ごとに提供される新鮮なsession cookieでリプレイします。
1

ログインを一度だけ記録する

browserflow record 中にログインを実演します。操作の(navigate、fill、submit)はキャプチャされますが、シークレット値はキャプチャされません。
2

シークレット入力を宣言する

Cookie/tokenをシークレット入力としてマークします(例: --secret apiToken)。それらはTool contract上の secret: true 入力になります。
3

実行ごとに新鮮なシークレットを注入する

実行時にRiderがシークレットを新しく解決し、secrets capabilityを通じてブラウザーコンテキストへ注入します。シークレットはすべての実行と再開でライブに再解決され、Journalから読み取られることはありません。
シークレットはライブに再解決されるため、hermeticな browserflow replay にはシークレットがまったく不要です。これは記録済みの読み取りだけを返します。effectをライブに再実行する browserflow replay --rerun だけが、実行時にシークレットを再解決する必要があります。実行を参照してください。

DOMリプレイ成果物がinspectorを支える

Recordingは順序付き操作とともにDOM evidenceをキャプチャするため、決定論的リプレイを駆動する同じ成果物がinspectorにも供給されます。どの操作が実行され、各locatorの選択をどのDOM evidenceが裏付けたかを正確に確認できます。リプレイはJournalからRunを再現し、DOMリプレイ成果物はそのRunを後から検査可能にします。解決できなくなったブラウザーlocatorは、安定した診断コード(仕様どおり tool.browser.locator_missing)として表面化するため、failureに対処できます。可観測性を参照してください。

2つの半分に分ける理由

実行ごとにモデルがactionを決めると、同じFlowが実行ごとに異なる振る舞いをすることになります。これは決定論性(原則 T2)と再現性(原則 T3)を壊します。browserflowはすべての賢さをオーサリング時に閉じ込めます。実行時には、エンジンはいかなるコードパスでもモデルを実行しません
locatorは記録時にDOM evidenceから選ばれ、壊れやすい構造セレクタより getByRole/getByText が優先されます。その回復力は、実行時に再推論することではなく、一度だけ良い選択をすることから生まれます。
taint ruleは、シークレット値をexpression layerの外に保ちます。シークレット値は、解決するToolの内側でだけ実体化します。Recordingは操作の形をキャプチャし、シークレットのbytesは決してキャプチャしません。そのため、Recording、FlowSpec、Journal、ログはすべてシークレットなしです。

関連

カスタムTool

同じcontent-addressed contractに対して独自のToolを作成します。

実行とリプレイ

読み取りがどのように記録され、hermetic replayがどのようにRunを再現するか。

可観測性

DOMリプレイ成果物と手順診断でRunを検査します。