mirror of
https://github.com/openswarm-ai/openswarm.git
synced 2026-09-12 04:37:44 +02:00
[eric] browser: a send task is not staged until there is somewhere to write
This commit is contained in:
@@ -388,6 +388,7 @@ async def run_prestage(
|
||||
p_total_timeout = OPENER_TOTAL_TIMEOUT_S if opener_mode() else TOTAL_TIMEOUT_S
|
||||
p_system = P_SYSTEM_OPENER if opener_mode() else P_SYSTEM
|
||||
p_results_overruled = False
|
||||
p_composer_overruled = False
|
||||
while (not staged_complete and steps < p_max_steps
|
||||
and (time.monotonic() - t0) < p_total_timeout):
|
||||
# Per-step cost, broken out. Prestage is the largest single phase of a LinkedIn write
|
||||
@@ -423,6 +424,21 @@ async def run_prestage(
|
||||
"one specific person or thing, CLICK through to its own page first; "
|
||||
"READY again only if the task really is about this list.]")
|
||||
continue
|
||||
# A send task is not staged until there is somewhere to write. Measured live: on
|
||||
# instagram the aux replies "I can see the Instagram home page is loaded" and calls
|
||||
# READY from the feed, and on tiktok it says "CLICK [1] READY" in one breath, before
|
||||
# the click it just asked for could open anything. Both then decline downstream with
|
||||
# composer=0 textboxes=0, having spent the whole stage. Same overrule shape as the
|
||||
# results-list rule above: nudge once, accept a second READY, because some surfaces
|
||||
# really do hide their box until the fill tier clicks an opener.
|
||||
if (task_is_send and not p_composer_overruled
|
||||
and not browser_send_parse.composer_index_in_state(li_text)):
|
||||
p_composer_overruled = True
|
||||
task = task + (
|
||||
"\n\n[You replied READY but no compose text box is listed in the elements. "
|
||||
"OPEN the specific item the task names, on its own page, or CLICK the "
|
||||
"control that reveals the box. READY again only once a textbox is listed.]")
|
||||
continue
|
||||
staged_complete = True
|
||||
logger.info(f"[browser-prestage] READY after {steps} step(s): {arg[:80]}")
|
||||
break
|
||||
|
||||
@@ -103,3 +103,21 @@ def test_half_an_emoji_cannot_kill_the_whole_prestage():
|
||||
# A well-formed emoji is left alone; scrubbing real content would be its own bug.
|
||||
assert strip_lone_surrogates("done \U0001f9e0 ok") == "done \U0001f9e0 ok"
|
||||
assert strip_lone_surrogates("") == ""
|
||||
|
||||
|
||||
def test_ready_on_a_page_with_nowhere_to_write_gets_one_nudge():
|
||||
"""The instagram/tiktok shape, measured live 2026-08-02 at N=5: 0/4 each, every run declining
|
||||
downstream with composer=0 textboxes=0.
|
||||
|
||||
Prestage took the aux model's word for "READY". On instagram it replied "I can see the Instagram
|
||||
home page is loaded" and called READY from the feed; on tiktok it said "CLICK [1] READY" in one
|
||||
breath, declaring done before the click it had just asked for could open anything. Both burned
|
||||
the whole stage and handed the send script a page with no box in it.
|
||||
|
||||
A send task is not staged until something can be written into. The gate is the same shape as the
|
||||
results-list overrule beside it: nudge once, accept a second READY, because some surfaces really
|
||||
do hide their box behind an opener the fill tier clicks later.
|
||||
"""
|
||||
from backend.apps.agents.browser.browser_send_parse import composer_index_in_state
|
||||
assert composer_index_in_state(NO_COMPOSER) is None, "the feed shape must read as no composer"
|
||||
assert composer_index_in_state(COMPOSER_PRESENT) is not None, "a staged page must read as one"
|
||||
|
||||
Reference in New Issue
Block a user