mirror of
https://github.com/openswarm-ai/openswarm.git
synced 2026-08-25 14:02:22 +02:00
[eric] browser: arm the send-completion shortcut only for send tasks, not gathers (cookie click faked a send)
This commit is contained in:
@@ -935,7 +935,10 @@ async def run_browser_agent(
|
||||
# (measured: send done at turn ~11, then ~12 wasted perception turns). We drive
|
||||
# it to the OUTCOME and, if it keeps re-perceiving, end the run. A genuine
|
||||
# multi-send task issues its NEXT send (an action) which resets the stall, so
|
||||
# only true spinning ends here.
|
||||
# only true spinning ends here. This whole shortcut is meaningless for a
|
||||
# gather/read task (no send to confirm), and arming it there let a cookie
|
||||
# 'Accept all' click masquerade as the task's send, so we gate it on intent.
|
||||
task_is_send = not deliverable_is_informational("", task)
|
||||
send_confirmed = False
|
||||
perception_stall = 0 # consecutive turns the model only LOOKED (no action)
|
||||
_POST_SEND_STALL_LIMIT = 2 # once the send registered, finish fast
|
||||
@@ -1495,7 +1498,7 @@ async def run_browser_agent(
|
||||
# across nodes, or scrolled off, so the text-probe is unreliable, which
|
||||
# is exactly what left the model stalling to "double-check". A clean
|
||||
# send click is proof enough; drive to the OUTCOME.
|
||||
if not send_confirmed and "error" not in result and tu.name in _CONFIRM_TOOLS:
|
||||
if task_is_send and not send_confirmed and "error" not in result and tu.name in _CONFIRM_TOOLS:
|
||||
_cn = result.get("clickedName") or ""
|
||||
_send_click = browser_batch_replay.is_replay_boundary(
|
||||
{"action": "click", "name": _cn}) or any(
|
||||
|
||||
@@ -282,6 +282,27 @@ def test_run_that_never_calls_done_is_not_a_clean_success(monkeypatch):
|
||||
assert result.get("done") is False # no explicit Done -> not a clean success
|
||||
|
||||
|
||||
def test_send_shortcut_does_not_arm_on_a_gather_task(monkeypatch):
|
||||
# The Airbnb bug: a send-class click (here the index-99 sentinel = "Send", same
|
||||
# as a cookie "Accept all" tripping the detector) on a FIND/gather task must NOT
|
||||
# arm the send-completion shortcut, there is no send to confirm. If it did, the
|
||||
# run cuts at the 2-turn post-send limit and leaks the canned "message went
|
||||
# through" line. On a gather task it should run the full perception budget.
|
||||
BH._browser_history.clear(); BH._domain_notes.clear()
|
||||
primary = FakeLLM([
|
||||
Resp([_rp("dismiss the cookie banner"), _tu("BrowserClickIndex", index=99)]),
|
||||
*[Resp([_rp("keep reading the list"), _tu("BrowserScreenshot")]) for _ in range(8)],
|
||||
Resp([_tu("Done", message="Here are the top items: a, b, c")]),
|
||||
])
|
||||
aux = FakeAux()
|
||||
_install(monkeypatch, primary, aux)
|
||||
result = asyncio.run(BA.run_browser_agent(task="find me the top 10 repos", browser_id="b1", model="sonnet"))
|
||||
# the send shortcut never armed: it ran past the 2-turn post-send cutoff toward
|
||||
# the 6-turn perception budget, and no send-confirmation line leaked
|
||||
assert primary.turn >= 6, f"gather task cut short at turn {primary.turn} (send shortcut wrongly armed)"
|
||||
assert "went through" not in result["summary"]
|
||||
|
||||
|
||||
def test_early_perception_is_not_cut_short_before_any_action(monkeypatch):
|
||||
# Orienting on a cold/slow page can take several look-only turns; the stall
|
||||
# backstop must NOT fire before the agent has done anything (it only bounds a
|
||||
|
||||
Reference in New Issue
Block a user