Lovely Routerドキュメント
キーを取得
ブラウザエージェント

ライブイベントと画面

結果を待たずに、エージェントがいま行っていること、完了した各ステップ、ブラウザ画面を実行中にストリーミングで受け取ります。

1 回の実行には数秒から数分かかります。終わるまで待つ代わりに、ストリーミングで受け取りましょう。エージェントがいま何をしているか、各ステップの完了、実行状態の変化、そして必要ならブラウザ画面がわかります。ストリームは終了した実行で締めくくられ、answer、data、charge_usd が含まれます。

ストリームには Server-Sent Events(text/event-stream)を使います。LLM API のストリーミングと同じ形式です。実行の視聴は無料です。

新しい実行をストリーミングする#

実行を作成するときに "stream": true を追加します。レスポンスは 202 の JSON ではなく、ステータス 200 のイベントストリームになります。ブラウザ画面も受け取るには "screen": true を追加します。

curl -N https://lovelyrouter.com/v1/browser/runs \
  -H "Authorization: Bearer $LOVELY_API_KEY" \
  -H "content-type: application/json" \
  -d '{
    "goal": "Find the price of the book \"A Light in the Attic\" and whether it is in stock.",
    "start_url": "https://books.toscrape.com/",
    "stream": true
  }'

ストリームはおおよそ次のようになります(抜粋):

SSE
event: run
data: {"id":"brun_3f9a1c7e0b2d4e6f8a9b0c1d","object":"browser_run","status":"running","steps":0,"trace":[],"poll":"/v1/browser/runs/brun_3f9a1c7e0b2d4e6f8a9b0c1d?wait=30","events":"/v1/browser/runs/brun_3f9a1c7e0b2d4e6f8a9b0c1d/events","charge_usd":null,"reserved_usd":0.445,…}

event: activity
data: {"step":0,"kind":"starting","text":"Opening https://books.toscrape.com/"}

event: activity
data: {"step":1,"kind":"reading","text":"Reading the page"}

event: activity
data: {"step":1,"kind":"acting","text":"click link \"A Light in the ...\" → https://books.toscrape.com/catalogue/a-light-in-the-attic_1000/index.html"}

event: step
data: {"step":1,"url":"https://books.toscrape.com/","action":"click:e54","description":"click link \"A Light in the ...\" → https://books.toscrape.com/catalogue/a-light-in-the-attic_1000/index.html","ms":2140,"error":null}

event: run
data: {"id":"brun_3f9a1c7e0b2d4e6f8a9b0c1d","status":"running","steps":1,…}

event: activity
data: {"step":2,"kind":"answering","text":"Reading the result and writing the answer"}

event: step
data: {"step":2,"url":"https://books.toscrape.com/catalogue/a-light-in-the-attic_1000/index.html","action":"done","description":"Read the result and wrote the answer","ms":2875,"error":null}

event: run
data: {"id":"brun_3f9a1c7e0b2d4e6f8a9b0c1d","status":"succeeded","answer":"\"A Light in the Attic\" costs £51.77 and is in stock (22 available).","charge_usd":0.012,"reserved_usd":0,…}

event: end
data: {"id":"brun_3f9a1c7e0b2d4e6f8a9b0c1d"}

最初の run イベントには、202 レスポンスに含まれる内容(poll、events、webhook を渡した場合は webhook_secret)が入っています。実行開始前のエラー(400、402、429 など)は、stream なしの場合と同じく、そのステータスの JSON で返ります。

進行中の実行を追跡する#

GET /v1/browser/runs/{id}/events はいつでも開けます。別のプロセスから、接続が切れた後に、あるいは stream なしで開始した実行に対しても使えます。画面を受け取るには ?screen=1 を追加します。複数のストリームで同じ実行を見ることもできます。

cURL
curl -N "https://lovelyrouter.com/v1/browser/runs/brun_3f9a1c7e0b2d4e6f8a9b0c1d/events?screen=1" \
  -H "Authorization: Bearer $LOVELY_API_KEY"

どのストリームも、完全な trace を含む run イベントから始まるため、再接続しても何も失われません。終了済みの実行では、その run イベント(screen 指定時は最後の画面も)に続いて end が送られます。

イベント#

イベントタイミングdata
run最初、各ステップの後、一時停止の開始・終了時、そして最後charge_usd と reserved_usd 付きの実行オブジェクト。最初のものには trace が含まれます。
activityエージェントが何かを始めたときstep(進行中のステップ)、kind、text
stepステップが完了したときtrace の 1 件:step、url、action、description、ms、error
framescreen 指定時:接続時と、ページが変わるたびdata(ブラウザの base64 JPEG)と at(ISO 8601)
end実行が終わり、続いてストリームが閉じられるときid

アクティビティの種類:

kindエージェントが行っていること
startingブラウザを起動する、または start_url を開く
readingページを読み取る
waitingまだ読み込まれていないページを待つ、または再読み込みする
deciding次のアクションを選ぶ
thinking決める前によく確認する(高精度モードではスクリーンショットを使うことがあります)
checking送信前にフォームの値を確認する
actingtext が示すアクションを行う:クリック、入力、選択、アップロード
answering結果を読み取り、回答を書く
extracting読み取った内容を data にまとめる

: で始まる行はキープアライブのコメントで、ほかに何も起きていない間は 15 秒ごとに送られます。無視してください。

画面を見る#

"screen": true(または ?screen=1)を指定すると、frame イベントがブラウザ画面を base64 JPEG で運びます。1 枚あたり通常 20〜60 KB です。接続時に 1 枚、その後はページが変わるたびに、最大で毎秒約 4 枚届きます。静止しているページでは新しいフレームは送られません。読み取りが追いつかない場合はフレームがスキップされますが、ほかのイベントがスキップされることはありません。

Web ページに表示するには、フレームを画像に入れます:

JavaScript
img.src = `data:image/jpeg;base64,${frame.data}`;

ストリームを使わずに 1 枚だけ欲しい場合は、GET /v1/browser/runs/{id}/screenshot が現在の画面を返します。

人の対応待ち#

実行が waiting_for_human の間も、ストリームは開いたままです。一時停止を始める run イベントには needs が含まれます。どこからでも POST /v1/browser/runs/{id}/reply で返信すると、ストリームは running に戻った run イベントとともに続きます。screen を指定していれば、引き継ぎ中に人がブラウザで行う操作も見えます。人による確認を参照してください。

Web アプリでのストリーム#

API キーはサーバーに置いてください。ブラウザの EventSource は Authorization ヘッダーを送れないため、サーバーでストリームを開き、content-type: text/event-stream のまま手を加えずにページへ中継します。ページからは自分の URL に対して EventSource を使えます。

再接続#

ストリームは切れることがあります。ネットワークの瞬断、プロキシのタイムアウト、こちら側のデプロイなどです。実行は続いています。GET /v1/browser/runs/{id}/events を開き直し、最初の run イベントで状態を置き換えてください。EventSource は 3 秒後に自動で再接続します。end か、最終ステータスの run を受け取ったら終了してください。