A message can already be entered while its send button appears or enables later. Repeating input risks duplication, while a brief generic lookup can misread normal preparation as failure. Northstar's Gemini path adds a distinct read-only readiness wait after validating the input.
Input completion and send readiness are not simultaneous
Send first locates the current field and requires nonempty content. After browser.fill it uses a fresh composer reference and verifyField to compare the exact value, requiring both checked and matches. An enabled button cannot justify skipping value verification or assuming earlier text survived.
Conversely, a correct field does not prove send readiness. The service may still process attachments, tool mode or input state. I keep those conditions separate instead of compressing them into one input-success flag. The distinction narrows diagnosis between delivering the value and the site being ready for the next operation.
The dedicated wait repeats reads only
After field verification, until observes whether an enabled send control exists. Its bound is the smaller of the current timeout and sixty seconds. Clicking send follows that successful check. The loop does not repeat fill or click send while waiting. This accommodates a dedicated video composer that can become ready later than generic lookup.
Sixty seconds is neither a mandatory delay nor a guarantee of success. Earlier readiness proceeds immediately; failure to become ready within the bound produces GEMINI_SEND_NOT_READY. The purpose is an explicit place to observe readiness, rather than waiting longer unconditionally and hoping the interface is ready afterward.
Preparation and post-send waiting observe different evidence
Before sending, the procedure reads current input and button state. After sending, it reads a new response group, busy state and text/media stability. Calling a preparation failure slow generation leads to the wrong diagnosis. A request that could not reach its send control should not be reported as an AI failure to generate output.
Refilling the composer because a new answer is delayed repeats the same confusion. The record of how far delivery reached should determine the next observation. Naming what is being awaited, rather than using one waiting state for everything, gives the next operator a concrete reason to avoid unnecessary input.
Distinguish dispatched state from an observed click count
The current code saves mark(dispatched) before fill. A readiness failure can therefore leave a conservative dispatched receipt even when send was never clicked. That name must not be interpreted as proof that the service definitely received the question. It protects the path once external input preparation began.
A later call encountering unresolved state stops with OUTCOME_UNCERTAIN. It needs inspection of the original situation rather than a fresh key to bypass the protection. This account does not claim automatic recovery from every pre-send failure. It states both the conservative choice made by the implementation and the remaining reconciliation responsibility.
Tests check one input followed by waiting
An existing test reveals send only after thirty reads following input. Even when the whole flow completes, fill and send click must each occur once. A readiness condition that never arrives leaves one fill and zero clicks. Checking absence of repeated effects matters more than seeing a success message alone.
These tests use fake timers and owned synthetic page responses, not measurements of thirty actual service observations or network timing. This content task read the test code without sending a new AI request. A delay fixture and real-service experience remain different evidence and are not reported interchangeably.
The shared observer also contains no sending capability
The shared module compares declared snapshots of new answers, media and timeout. It does not fill a composer or implement the original UI readiness connection. That is why results retain request_sent=False. Running the example creates no external request.
Separating readiness observation from the actual external action makes reuse across programs easier. Integration still needs a real target, authorization and current input checks. A read-only wait must not quietly become a resubmission button. That boundary belongs in the design alongside the waiting behavior itself.