Stream messages as the agent works — reasoning, tool calls, browser actions, and results. Each message has role, type, summary, data, and screenshot_url. See List session messages for all fields.
from browser_use_sdk.v3 import AsyncBrowserUse
client = AsyncBrowserUse()
run = client.run("Find the top story on Hacker News")
async for msg in run:
print(f"[{msg.role}] {msg.summary}")
print(run.result.output)
[user] Find the top story on Hacker News
[assistant] Navigating to https://news.ycombinator.com/
[tool] Browser Navigate: Navigated
[assistant] Analyzing browser state
[tool] Browser Analyze State: The top story is "Coding Agents Could Make Free Software Matter Again"
[tool] Done Autonomous: The top story on Hacker News is "Coding Agents Could Make Free Software Matter Again"
Cancel a running task
Use stop(strategy="task") to cancel the current task without destroying the session. The session goes back to idle and can accept a new task.
run = client.run("Find the top story on Hacker News")
async for msg in run:
if should_cancel():
await client.sessions.stop(run.session_id, strategy="task")
break
# Session is now idle — send a different task or close it
run.result is only available after the iterator finishes (all messages consumed or task completes). If you break early from async for / for await, the task may still be running — call stop(strategy="task") to cancel it before sending a follow-up.
Manual polling
If you need full control over the polling loop (e.g. custom interval, filtering):
import asyncio
from browser_use_sdk.v3 import AsyncBrowserUse
client = AsyncBrowserUse()
session = await client.sessions.create(task="Find the top story on Hacker News")
cursor = None
while True:
msgs = await client.sessions.messages(session.id, after=cursor, limit=100)
for m in msgs.messages:
print(f"[{m.role}] {m.summary}")
cursor = m.id
s = await client.sessions.get(session.id)
if s.status.value in ("idle", "stopped", "error", "timed_out"):
break
await asyncio.sleep(2)
print(s.output)