Add cookbook: pausing agents for captcha telemetry - #547
Conversation
Shows how to use browser-loop's abort/resume pattern with the captcha_solve_started / captcha_solve_result / captcha_challenge_result telemetry events, so an agent stops acting while Kernel's solver is working and resumes once it reports a terminal outcome.
|
Preview deployment for your docs. Learn more about Mintlify Previews.
💡 Tip: Enable Automations to automatically generate PRs for you. |
Buffers a terminal telemetry event that arrives before waitForOutcome is called, clears tracked IDs on timeout so the next captcha still triggers a pause, stops a same-challenge task from overwriting the tracked task_id, and distinguishes a task-level success from a challenge actually clearing.
There was a problem hiding this comment.
Stale comment
Risk assessment: Very Low
Verdict: Risk did not increase. Prior approval stands (not re-approving).
Re-evaluated HEAD
3712d40against the previously approved commit8e9d21efrom the file diffs only (not the PR description).Current scope (3 files, +252 / -1 vs
main):
File Change browsers/telemetry/pausing-for-captcha-solves.mdxNew Mintlify cookbook (example TypeScript + setup notes) docs.jsonAdds that page under the existing Telemetry nav group browsers/playwright-computer-use-fallback.mdxOne Next-steps cross-link What changed after approval:
3712d40only edits the cookbook example — outcome buffering, distinctchallenge_solvedvstask_success, same-episode ID handling, and timeout ID reset. Same files, still documentation and nav config.Why still Very Low
- Documentation and Mintlify nav only. No application, API, auth, billing, or infrastructure code.
- No CODEOWNERS file in this repo, so no required owner review.
- Example
systemPrompt/ cookbook text lives in user-facing docs, not in model-instruction or production prompt files.- Incremental commit narrows example-code correctness; it does not expand blast radius.
Approval from the prior Very Low assessment remains in effect.
Sent by Cursor Automation: Assign PR reviewers
If an episode's outcome buffers before waitForOutcome is called and a new episode starts before the driver gets back to it, the buffer is now cleared so the driver waits on the current episode instead of resuming on the stale one. Also breaks the dense gate-behavior paragraph into bullets for scannability.
There was a problem hiding this comment.
Stale comment
Risk assessment: Very Low
Verdict: Risk did not increase. Prior approval stands (not re-approving).
Re-evaluated HEAD
9df87e2against the previously approved commit8e9d21efrom the file diffs only (not the PR description).Current scope (3 files, +261 / -1 vs
main):
File Change browsers/telemetry/pausing-for-captcha-solves.mdxNew Mintlify cookbook (example TypeScript + setup notes) docs.jsonAdds that page under the existing Telemetry nav group browsers/playwright-computer-use-fallback.mdxOne Next-steps cross-link What changed after the last assessment:
9df87e2only edits the cookbook — clears a stale buffered outcome when a new captcha episode opens, and splits the gate-behavior paragraph into bullets. Same files, still documentation and nav config.Why still Very Low
- Documentation and Mintlify nav only. No application, API, auth, billing, or infrastructure code.
- No CODEOWNERS file in this repo, so no required owner review.
- Example
systemPrompt/ cookbook text lives in user-facing docs, not in model-instruction or production prompt files.- Incremental commit tightens example-code correctness; it does not expand blast radius.
Approval from the prior Very Low assessment remains in effect.
Sent by Cursor Automation: Assign PR reviewers
Delivery is unordered, so a captcha_solve_started for an episode can arrive after that episode's own terminal result already buffered. The gate now remembers which task_id/challenge_id a buffered outcome belongs to, so a late duplicate for that same episode is recognized and left alone instead of being mistaken for a new episode (which previously discarded the buffer and re-triggered a spurious pause).
There was a problem hiding this comment.
Stale comment
Risk assessment: Very Low
Verdict: Risk did not increase. Prior approval stands (not re-approving).
Re-evaluated HEAD
d7f6e03against the previously approved commit8e9d21efrom the file diffs only (not the PR description).Current scope (3 files, +286 / -1 vs
main):
File Change browsers/telemetry/pausing-for-captcha-solves.mdxNew Mintlify cookbook (example TypeScript + setup notes) docs.jsonAdds that page under the existing Telemetry nav group browsers/playwright-computer-use-fallback.mdxOne Next-steps cross-link What changed after the last assessment:
d7f6e03only edits the cookbook example — keeps the buffered outcome'stask_id/challenge_idso a late duplicatecaptcha_solve_startedis ignored instead of clearing the buffer. Same files, still documentation and nav config.Why still Very Low
- Documentation and Mintlify nav only. No application, API, auth, billing, or infrastructure code.
- No CODEOWNERS file in this repo, so no required owner review.
- Example
systemPrompt/ cookbook text lives in user-facing docs, not in model-instruction or production prompt files.- Incremental commit tightens example-code correctness; it does not expand blast radius.
Approval from the prior Very Low assessment remains in effect.
Sent by Cursor Automation: Assign PR reviewers
Starts on duckduckgo.com, navigates to 2captcha.com's public Cloudflare Turnstile demo, and has the agent summarize the page's explanation of how Turnstile is solved once the challenge clears.
There was a problem hiding this comment.
Stale comment
Risk assessment: Very Low
Verdict: Risk did not increase. Prior approval stands (not re-approving).
Re-evaluated HEAD
0ed73ccagainst the previously approved commit8e9d21efrom the file diffs only (not the PR description).Current scope (3 files, +290 / -1 vs
main):
File Change browsers/telemetry/pausing-for-captcha-solves.mdxNew Mintlify cookbook (example TypeScript + setup notes) docs.jsonAdds that page under the existing Telemetry nav group browsers/playwright-computer-use-fallback.mdxOne Next-steps cross-link What changed after the last assessment:
0ed73cconly edits cookbook demo text — switches the example target from the public Google reCAPTCHA v2 demo to duckduckgo.com → 2captcha.com's Cloudflare Turnstile demo, and updates the exampleTASK_PROMPT/ comment to match. Same files, still documentation and nav config.Why still Very Low
- Documentation and Mintlify nav only. No application, API, auth, billing, or infrastructure code.
- No CODEOWNERS file in this repo, so no required owner review.
- Example
TASK_PROMPT/systemPrompttext lives in user-facing docs, not in model-instruction or production prompt files.- Incremental commit is demo-URL and example-prompt wording only; it does not expand blast radius.
Approval from the prior Very Low assessment remains in effect.
Sent by Cursor Automation: Assign PR reviewers
Removes inline references to the Playwright/computer-use fallback cookbook from the body text (kept only in Next Steps), and replaces the concrete duckduckgo/2captcha demo task with a placeholder the reader fills in with their own task.
There was a problem hiding this comment.
Stale comment
Risk assessment: Very Low
Verdict: Risk did not increase. Prior approval stands (not re-approving).
Re-evaluated HEAD
911955eagainst the previously approved commit8e9d21efrom the file diffs only (not the PR description).Current scope (3 files, +287 / -1 vs
main):
File Change browsers/telemetry/pausing-for-captcha-solves.mdxNew Mintlify cookbook (example TypeScript + setup notes) docs.jsonAdds that page under the existing Telemetry nav group browsers/playwright-computer-use-fallback.mdxOne Next-steps cross-link What changed after the last assessment:
911955eonly edits cookbook copy — drops inline links to the Playwright/computer-use fallback page from the body (kept in Next Steps) and replaces the concrete duckduckgo/2captcha demoTASK_PROMPTwith a placeholder. Same files, still documentation and nav config.Why still Very Low
- Documentation and Mintlify nav only. No application, API, auth, billing, or infrastructure code.
- No CODEOWNERS file in this repo, so no required owner review.
- Example
TASK_PROMPT/systemPrompttext lives in user-facing docs, not in model-instruction or production prompt files.- Incremental commit is wording and a placeholder prompt; it does not expand blast radius.
Approval from the prior Very Low assessment remains in effect.
Sent by Cursor Automation: Assign PR reviewers
Quick-reference table of the three captcha events and their possible terminal outcomes, right after they're introduced in prose.
There was a problem hiding this comment.
Stale comment
Risk assessment: Very Low
Verdict: Risk did not increase. Prior approval stands (not re-approving).
Re-evaluated HEAD
924f68aagainst the previously approved commit8e9d21efrom the file diffs only (not the PR description).Current scope (3 files, +293 / -1 vs
main):
File Change browsers/telemetry/pausing-for-captcha-solves.mdxNew Mintlify cookbook (example TypeScript + setup notes) docs.jsonAdds that page under the existing Telemetry nav group browsers/playwright-computer-use-fallback.mdxOne Next-steps cross-link What changed after the last assessment:
924f68aonly adds a markdown table in the cookbook intro listing the three captcha event types and their outcomes. Same files, still documentation and nav config.Why still Very Low
- Documentation and Mintlify nav only. No application, API, auth, billing, or infrastructure code.
- No CODEOWNERS file in this repo, so no required owner review.
- Example
TASK_PROMPT/systemPrompttext lives in user-facing docs, not in model-instruction or production prompt files.- Incremental commit is a reference table; it does not expand blast radius.
Approval from the prior Very Low assessment remains in effect.
Sent by Cursor Automation: Assign PR reviewers
browser-loop's exact @onkernel/sdk pin is relaxed to a caret range (kernel/browser-loop#94), matching the same removal already done for the Playwright/computer-use fallback cookbook (#548).
There was a problem hiding this comment.
Stale comment
Risk assessment: Very Low
Verdict: Risk did not increase. Prior approval stands (not re-approving).
Re-evaluated HEAD
738ec65against the previously approved commit8e9d21efrom the file diffs only (not the PR description).Current scope (3 files, +279 / -1 vs
main):
File Change browsers/telemetry/pausing-for-captcha-solves.mdxNew Mintlify cookbook (example TypeScript + setup notes) docs.jsonAdds that page under the existing Telemetry nav group browsers/playwright-computer-use-fallback.mdxOne Next-steps cross-link What changed after the last assessment:
738ec65only deletes a<Warning>callout about a stale@onkernel/sdkversion-pin /overridesworkaround. Same files, still documentation and nav config. Surface area shrank slightly.Why still Very Low
- Documentation and Mintlify nav only. No application, API, auth, billing, or infrastructure code.
- No CODEOWNERS file in this repo, so no required owner review.
- Example
TASK_PROMPT/systemPrompttext lives in user-facing docs, not in model-instruction or production prompt files.- Incremental commit is copy removal only; it does not expand blast radius.
Approval from the prior Very Low assessment remains in effect.
Sent by Cursor Automation: Assign PR reviewers
The previous gate paused on captcha_solve_started, joined challenge results only when a start had carried a challenge_id, and had no fallback when an event never arrived. On a real reCAPTCHA that dropped the challenge-level outcome entirely and re-prompted the agent once per solver task. The gate now pairs tasks on task_id only, records every challenge result and marks whether it can be attributed, bounds every wait, and falls back to a read-only page probe. It holds at the tool_call hook instead of aborting the turn, so an action is stopped before it reaches the page and no re-prompt is needed. Split into four named steps with the complete file in an accordion, and pin pi-agent-core to the version browser-loop depends on -- the previous install line resolved a newer one that the script doesn't compile against.
There was a problem hiding this comment.
Risk assessment: Very Low
Verdict: Risk did not increase. Prior approval stands (not re-approving).
Re-evaluated HEAD 4d7645f against the previously approved commit 8e9d21e from the file diffs only (not the PR description).
Current scope (3 files, +522 / -1 vs main):
| File | Change |
|---|---|
browsers/telemetry/pausing-for-captcha-solves.mdx |
New Mintlify cookbook (example TypeScript + setup notes) |
docs.json |
Adds that page under the existing Telemetry nav group |
browsers/playwright-computer-use-fallback.mdx |
One Next-steps cross-link |
What changed after the last assessment: 4d7645f rewrites the cookbook around captcha correlation rules — task-id joins, bounded waits, a read-only page probe, and a tool_call hold instead of abort-and-resume. Same three files; still documentation and nav config. No new paths, CI, or runtime code.
Why still Very Low
- Documentation and Mintlify nav only. No application, API, auth, billing, or infrastructure code.
- No CODEOWNERS file in this repo, so no required owner review.
- Example
systemPrompt/ cookbook text lives in user-facing docs, not in model-instruction or production prompt files. - Incremental rewrite enlarges the example but does not expand blast radius beyond this docs site.
Approval from the prior Very Low assessment remains in effect.
Sent by Cursor Automation: Assign PR reviewers
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 2 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 4d7645f. Configure here.
| /** A task the solver accepted has no terminal result yet. */ | ||
| holding: () => openTasks().length > 0, | ||
| /** A terminal outcome is recorded that the agent hasn't been told about. */ | ||
| pending: () => challenges.size > 0 || [...tasks.values()].some((t) => t.status && t.status !== "success"), |
There was a problem hiding this comment.
Success outcomes skipped between turns
High Severity
pending treats only non-success task statuses as a terminal outcome, so a captcha_solve_result of success that lands between tool calls never enters resolve or reset. Those closed tasks stay in the maps and can be reused as the verdict for a later captcha, and the documented Turnstile task-success message never fires on this path.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 4d7645f. Configure here.
| async function resolve(): Promise<Verdict> { | ||
| // A challenge result covers every task under it, so stop waiting once one lands. | ||
| await until(() => openTasks().length === 0 || Boolean(joinedResult()), TASK_SETTLE_MS); | ||
| if (joinable.size > 0 && !joinedResult()) await until(() => Boolean(joinedResult()), CHALLENGE_GRACE_MS); |
There was a problem hiding this comment.
Follow-up solver tasks get discarded
High Severity
resolve ends its wait when the tasks it already knows about finish, then watches only for captcha_challenge_result during the grace period. A later solver task that starts in that window is not waited on, and reset drops it, so the agent can act while Kernel’s solver is still working.
Additional Locations (2)
Reviewed by Cursor Bugbot for commit 4d7645f. Configure here.




Summary
browsers/telemetry/pausing-for-captcha-solves.mdx— pauses abrowser-loopagent whencaptcha_solve_startedfires and resumes oncecaptcha_solve_result/captcha_challenge_resultreports a terminal outcome, reusing the abort-and-resume pattern from the existing Playwright/computer-use fallback cookbook.docs.jsonunder Telemetry, and cross-linked from the fallback cookbook's Next Steps.@onkernel/sdkversion conflict betweenbrowser-loop's pinned dependency (predates the telemetry API) and the SDK version the script needs, with a verifiedoverridesfix.Test plan
docs.jsonand the doc's JSON snippet parse as valid JSON@onkernel/browser-loop,@onkernel/sdk, and@earendil-works/pi-agent-corepackages (installed at the exact versionsbrowser-loopdepends on, with theoverridesfix applied) — caught and fixed a real API mismatch (InMemorySessionRepo/AgentHarnessEventfrom a newerpi-agent-corethanbrowser-looppins) and a missing-telemetry-on-old-SDK issue before they shippedNote
Low Risk
Documentation-only changes (new MDX page, nav entry, and cross-link); no runtime or API code in the repo is modified.
Overview
Adds a Telemetry cookbook that shows how to pause a
@onkernel/browser-loopagent while Kernel’s stealth captcha solver runs, using captcha telemetry instead of prompt-only “wait for solve” behavior.The guide walks through a
captcha-gate.tspattern: streamcaptcha_*events with order-agnostic joins and bounded waits, resolve a verdict that separates solver tasks from challenge outcomes, probe the live page for visible widgets, and hookAgentHarnesstool_callto hold actions and optionally block with a structured message when widgets remain. It also documents limits, example agent messages, and setup (including pinning@earendil-works/pi-agent-core).Navigation: registers
browsers/telemetry/pausing-for-captcha-solvesindocs.jsonunder Telemetry, and links it from the Playwright computer-use fallback doc’s Next steps as an alternative mid-run hold strategy.Reviewed by Cursor Bugbot for commit 4d7645f. Bugbot is set up for automated code reviews on this repo. Configure here.