From a3a5a202d4c2fc867f37951b2fe99cce1272b57a Mon Sep 17 00:00:00 2001 From: Les Orchard Date: Tue, 9 Jun 2026 17:15:07 -0700 Subject: [PATCH] feat(core): allow done() for actions completed without confirmation The done/abort guidance treated a form submit that produced no error and no explicit success message as 'unverified', pushing the agent to abort. Refine it so a performed action with no error but no confirmation is reported via done() with a caveat, while abort remains for unverified data and blocked core steps. --- packages/core/src/prompts.ts | 6 ++++-- packages/core/test/prompts.test.ts | 9 +++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/packages/core/src/prompts.ts b/packages/core/src/prompts.ts index 0ef1f6fd..7729d6f3 100644 --- a/packages/core/src/prompts.ts +++ b/packages/core/src/prompts.ts @@ -379,11 +379,13 @@ Analyze the current page state and determine your next action based on previous - Did all specified filters/criteria apply (price range, date, location, format)? - Does your answer match the requested format? 3. Verify actions actually completed by checking the most recent page state: - - If you submitted a form, did the next page confirm success? + - If you submitted a form, look for a success message or a validation error: + - A validation error means it did NOT submit — fix and retry. + - Neither a confirmation nor an error is a normal outcome on many sites: treat the submission as completed and report it with done(), stating explicitly that no confirmation was shown. - If you extracted data, did you actually find it in the page snapshot or extract() output? 4. Data grounding: every value in your answer must appear in a page snapshot, a tool result, or the task input. Do NOT use general knowledge to fill gaps. If a value was not found during this session, say so explicitly rather than inventing it. 5. Blockers vs. obstacles: if you hit an unrecoverable block (paywall, login wall, access denied, payment declined) that prevented completing a core requirement, call abort() with the reason. Temporary obstacles you handled (dismissed popups, retried errors) don't change the outcome. -6. If anything is unverified, incomplete, or uncertain — call abort() with the reason rather than done() with an overclaiming answer. +6. If the information or data the task asks you to return is unverified, or a core step was blocked outright, call abort() with the reason rather than done() with an overclaiming answer. But an action you actually performed — e.g. a form submit that returned no error and showed no validation error — is NOT "unverified" merely because the site displayed no explicit success message; report that with done() and the caveat, don't abort. **When using done():** Provide your final answer: diff --git a/packages/core/test/prompts.test.ts b/packages/core/test/prompts.test.ts index 458a37c5..84fa94a3 100644 --- a/packages/core/test/prompts.test.ts +++ b/packages/core/test/prompts.test.ts @@ -287,6 +287,15 @@ describe("prompts", () => { expect(prompt).toContain("GUARDRAIL COMPLIANCE"); }); + it("guides done() for an action that completed without error but showed no confirmation", () => { + const prompt = buildActionLoopSystemPrompt(false, false); + + // A submitted form with neither confirmation nor error should be reported + // with done() (caveated), not aborted as "unverified". + expect(prompt).toContain("no confirmation was shown"); + expect(prompt).toContain('is NOT "unverified"'); + }); + it("should support both guardrails and webSearch", () => { const prompt = buildActionLoopSystemPrompt(true, true);