fix(cua): remove send action — LLM taps send button via coordinates from screenshot instead

This commit is contained in:
Dennis V
2026-06-22 21:19:24 +00:00
parent b7ddaa1350
commit c002313ea0

View File

@@ -378,27 +378,7 @@ def execute_action(action: dict) -> str:
return f"swiped ({x1},{y1})->({x2},{y2})"
elif act == "send":
# First dismiss keyboard if visible (ESCAPE=111 is safe, unlike BACK which navigates)
adb("shell", "input", "keyevent", "111")
time.sleep(0.5)
# Auto-locate send button: rightmost clickable button in the bottom input bar.
_, screen_h = get_screen_size()
bottom_threshold = int(screen_h * 0.60)
xml = ui_dump()
matches = re.findall(r'clickable="true"[^>]*bounds="\[(\d+),(\d+)\]\[(\d+),(\d+)\]"', xml)
bottom_buttons = [(int(x1), int(y1), int(x2), int(y2)) for x1, y1, x2, y2 in matches if int(y1) > bottom_threshold]
if bottom_buttons:
send_btn = max(bottom_buttons, key=lambda b: (b[0] + b[2]) // 2)
cx = (send_btn[0] + send_btn[2]) // 2
cy = (send_btn[1] + send_btn[3]) // 2
adb("shell", "input", "tap", str(cx), str(cy))
return f"send button tapped ({cx}, {cy})"
# Fallback: tap bottom-right area
screen_w, _ = get_screen_size()
fx = screen_w - 32
fy = screen_h - 48
adb("shell", "input", "tap", str(fx), str(fy))
return f"send button tapped (fallback {fx}, {fy})"
return "`send` action is deprecated — use tap with coordinates instead"
elif act == "wait":
secs = float(action.get("seconds", 2))
@@ -436,7 +416,6 @@ Available actions:
{"type": "type", "text": "<string>"}
{"type": "key", "key": "enter|back|home|delete|tab"}
{"type": "swipe", "x1": <int>, "y1": <int>, "x2": <int>, "y2": <int>, "duration": <ms>}
{"type": "send"} -- tap the send/submit button (auto-locates via UI hierarchy)
{"type": "wait", "seconds": <float>}
{"type": "screenshot", "label": "<tag>"} -- observe current state without acting
{"type": "done", "summary": "<what was accomplished>"}
@@ -444,13 +423,15 @@ Available actions:
Rules:
- Issue exactly ONE action per turn as a JSON object. No markdown, no explanation outside JSON.
- Coordinates are in pixels relative to the screenshot dimensions.
- Coordinates are in pixels relative to the screenshot dimensions. YOU provide the coordinates.
- IMPORTANT: In this app, pressing "enter" inserts a newline — it does NOT send the message.
To send a message use {"type": "send"} which auto-locates and taps the send/arrow button.
Do NOT press "back" after typing — it will navigate away.
The "send" action handles keyboard dismissal internally, so you don't need to dismiss it manually.
If the text input is already focused (cursor visible), type directly without tapping it first.
Only tap the input if you see no cursor/blinking indicator.
There is NO "send" action. To send a message, use {"type": "tap", "x": ..., "y": ...}
with coordinates from the screenshot pointing at the send/submit button (usually bottom-right).
- Do NOT press "back" after typing — it will navigate away from the session.
- If the keyboard appears after tapping the text input and blocks the send button,
first tap a blank area above the keyboard (not on the keyboard) to dismiss it,
THEN tap the send button. Or: tap the send button from memory if it was visible before the keyboard appeared.
- If the text input is already focused (cursor visible), type directly without tapping it first.
- Be efficient: skip unnecessary waits, tap directly on visible targets.
- When the goal is fully achieved respond with {"type": "done", "summary": "..."}.
- If genuinely stuck after 5+ attempts on the same element respond with {"type": "fail", ...}.
@@ -727,7 +708,7 @@ def run_onboarding_showcase(
f"Tap the text input field. "
f"Type this exact message: {TYPESCRIPT_TASK!r} "
"Do NOT press back (it navigates away). "
"Use the send action to submit. "
"Tap the send/arrow button (bottom-right) to submit. "
"After sending, wait and watch — opencode will show tool calls and file writes as it works. "
"Wait up to 90 seconds total for the session to go idle/complete "
"(no new activity for at least 5 seconds, or a completion indicator appears). "
@@ -794,10 +775,11 @@ SMOKE_SCENARIOS = [
"name": "coding_task",
"goal": (
"You see the OpenCode mobile app. Tap the '+' button (top-right) to create a new session. "
"Wait 3 seconds for the new session/chat screen to fully load. "
"Tap the text input at the bottom. "
f"Type this exact task: {PYTHON_CODING_TASK!r} "
"Do NOT press back (it navigates away). "
"Use the send action to submit the task. "
"Tap the send/arrow button (bottom-right) to submit the task. "
"After sending, wait and watch — opencode will think and then produce code. "
"Wait up to 120 seconds total for the session to complete "
"(look for file creation messages, a summary from assistant, or 'idle' status). "