How to Hand Off Control of a Task Space to the User in ego-lite
Use the handOffTaskSpace() helper in ego-lite to transfer ownership of a browsing context from the AI agent to the user when manual intervention is required for CAPTCHAs, logins, or confirmations.
In the citrolabs/ego-lite framework, task spaces isolate browsing contexts for AI agents performing automated workflows. When a workflow encounters a step that requires human intervention—such as solving a CAPTCHA or completing multi-factor authentication—you must hand off control of the task space to the user to prevent automation errors and enable secure manual interaction.
Why Task Space Handoff Matters
Task spaces in ego-lite enforce strict ownership rules. While the user controls the space, any browser operation initiated by the agent fails with a "user is controlling" error. Properly implementing the handoff protocol, as documented in the "Control handoff" section of SKILL.md, ensures smooth collaboration between automated scripts and human users.
Implementing Control Handoff with handOffTaskSpace
The handOffTaskSpace function, implemented in package/ego-browser/src/helpers.ts (lines 326-338), manages the transfer of ownership from agent to user according to the runtime protocol defined in the ego backend.
Step 1: Initiate the Handoff
Call handOffTaskSpace with an optional task space identifier. Omit the parameter to use the currently selected space.
const result = await handOffTaskSpace(task.id);
// Or use the default selected space:
// const result = await handOffTaskSpace();
Step 2: Inspect the Result Object
The function returns a promise that resolves to an object indicating the handoff status:
{ done: true }– The transfer succeeded; the space was previously agent-owned.{ done: false, skipped: "user-owned" }– The space was already user-owned; no changes occurred.
Always check result.done before proceeding, as shown in helpers.test.mjs (lines 849-911):
if (!result.done) {
cliLog('Space already controlled by user');
} else {
cliLog('Control transferred successfully');
}
Step 3: Communicate with the User
After a successful handoff, explicitly inform the user of required actions. The agent must pause all browser automation until the user signals completion via an "Ask" button or chat message. Do not issue further browser commands during this period.
Step 4: Reclaim Control with takeOverTaskSpace
Once the user confirms completion, reacquire ownership using takeOverTaskSpace (or claimTaskSpace if reclaiming a previously user-owned space):
await takeOverTaskSpace(task.id);
// Resume automation...
await click('button#continue');
Complete Workflow Example
The following pattern demonstrates a full checkout flow with manual login intervention, combining useOrCreateTaskSpace, handOffTaskSpace, and cleanup:
// Create or select task space
const task = await useOrCreateTaskSpace('checkout flow');
cliLog(`Task space id: ${task.id}`);
// Automated steps
await openOrReuseTab('https://example.com/checkout', { wait: true });
await click('button#login');
// Hand off for manual authentication
const handoff = await handOffTaskSpace(task.id);
if (handoff.done) {
cliLog('Please complete the login and click **Continue**.');
} else {
cliLog('Control already with user – proceed when ready.');
}
// ... Wait for user signal ...
// Regain control and complete
await takeOverTaskSpace(task.id);
await click('button#confirm');
await captureScreenshot();
cliLog('Checkout completed.');
Cleaning Up Task Spaces
When the workflow completes, close the space using completeTaskSpace. The keep option controls whether the browser page remains open for the user:
await completeTaskSpace(task.id, { keep: true });
Summary
- Call
handOffTaskSpace(nameOrId?)inpackage/ego-browser/src/helpers.tsto transfer control from agent to user. - Check the returned object's
doneproperty to confirm successful transfer or detect pre-existing user ownership. - Pause all automation after handoff; any agent browser actions while the user controls the space will fail with a "user is controlling" error.
- Use
takeOverTaskSpace()to resume automation after user completion, orclaimTaskSpace()for spaces created as user-owned. - Reference the "Control handoff" sections in
SKILL.mdandAGENTS.mdfor protocol details and ownership rules.
Frequently Asked Questions
What happens if I try to perform browser actions after handing off control?
Any browser operation attempted by the agent while the user controls the task space fails immediately with a "user is controlling" error. The handOffTaskSpace implementation in helpers.ts ensures the runtime enforces this ownership boundary to prevent automation conflicts.
How do I know if the handoff was successful?
Inspect the done property of the object returned by handOffTaskSpace. A value of true confirms the space transitioned from agent to user ownership, while false with skipped: "user-owned" indicates the space was already under user control, as verified in the unit tests at helpers.test.mjs lines 849-911.
Can I hand off a task space without specifying an ID?
Yes. Call handOffTaskSpace() without arguments to target the currently selected task space. The helper defaults to the active context, simplifying workflows where you maintain a single primary space, according to the implementation signature in package/ego-browser/src/helpers.ts.
What is the difference between takeOverTaskSpace and claimTaskSpace?
Use takeOverTaskSpace to reclaim a space you previously handed off to the user during the current session. Use claimTaskSpace when taking ownership of a space that was created as user-owned or abandoned by another agent. Both functions restore agent control but target different ownership states, as outlined in AGENTS.md.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →