Vision Targets
VisionTarget is the class that describes your page: where it is and how to get it ready. Configure it by subclassing, with class attributes, or with constructor arguments; an argument wins over the attribute.
from okareo_vision import VisionTarget, click_selector
class SupportChat(VisionTarget):
url = "https://support.example.com/"
target = SupportChat(headless=False, max_parallel=3)
# the same page, no subclass
target = VisionTarget(url="https://support.example.com/", prepare=click_selector("#help-button"))
Settings
The settings that matter most:
| Setting | Default | What it does |
|---|---|---|
url | required | The page every conversation opens. {session_index} (1, 2, … in start order) and {scenario_input.KEY} (a field of the row's input) are filled per conversation. |
prepare(page) | does nothing | Gets the page ready; see Prepare the Page. A method on the subclass, or prepare= on the constructor. |
max_parallel | 10 | How many conversations Okareo may hold open at once. They share one browser, each in its own context (its own cookies and storage). |
settle_timeout_s | 30.0 | The longest a wait for the screen to settle lasts. |
headless | True | False shows the browser. |
channel | None | Which browser to launch. None is Playwright's Chromium; "chrome" or "msedge" is a browser installed on the machine. |
screen_selector | None | A CSS selector for the one element Okareo is shown as the screen, for a chat panel docked over a busy page. None is the whole window. |
debug | off | Records each frame Okareo saw, a video and the page's network traffic under okareo_runs/. |
The other settings (a saved sign-in, the message box and send button by selector, the window size, extra browser flags) are described in the VisionTarget docstring.
VisionTarget.preflight() launches and closes the browser once, so a missing browser fails in your terminal instead of once per conversation inside a Run.
Prepare the Page
prepare(page) runs once per conversation, after the page loads and before Okareo's first look. The Playwright Page is yours: close a banner, sign in, open the chat, and wait for the message box so the first frame has the chat in it. Raising ends that conversation with the error on its row; the Run goes on.
from okareo_vision import VisionTarget
from playwright.async_api import Page
class StoreHelper(VisionTarget):
url = "https://shop.example.com/"
async def prepare(self, page: Page) -> None:
# A cookie notice can cover the page on first load; its X closes it.
notice = page.get_by_role("dialog", name="Cookies")
if await notice.count() and await notice.is_visible():
await notice.get_by_role("button", name="Close", exact=True).click()
await notice.wait_for(state="hidden", timeout=5000)
# The helper opens from "Ask", or from the round button in the corner.
pill = page.get_by_role("button", name="Ask")
if await pill.count() and await pill.is_visible():
await pill.click()
else:
await page.locator('[data-testid="chat-bubble"]').click(force=True)
await page.get_by_role("textbox", name="Ask anything").wait_for(state="visible", timeout=10000)
When one click is all it takes, click_selector("#help-button") is a ready prepare: it clicks the control, and carries on with a warning when the control is not there.
Common Problems
The Page Never Shows a Chat
Watch it with headless=False, or set debug=True and open okareo_runs/<run>/shots/turn00-*.jpg, the first frame Okareo saw. Open the chat in prepare and end it by waiting for the message box. For a chat panel over a busy page, screen_selector shows Okareo the panel alone.
The Site Refuses Headless Chrome
The browser already presents itself as a normal Chrome. When the site still refuses, show the browser and use the real Chrome: headless=False and channel="chrome" (run playwright install chrome if it is not on the machine). A headed browser needs a display; on a Linux server, run under xvfb-run.
Sign-In Needs MFA
A scripted sign-in cannot answer an MFA prompt. Sign in by hand once with ensure_session from okareo_vision.auth, which saves the session to a file, and set storage_state to that file so every conversation starts signed in. The file is a signed-in session, so keep it out of version control.