How to Take Over Control of a Task Space from the User in ego-lite
Use the takeOverTaskSpace(nameOrId) helper to reclaim exclusive browser control after the user completes manual steps, or call handOffTaskSpace(nameOrId) to transfer ownership to the user when human intervention is required.
In ego-lite, task spaces isolate browsing contexts for AI agents, allowing automated workflows to pause for human input. When agents encounter CAPTCHAs, login screens, or confirmation steps, they must transfer control to the user and later reclaim it to finish automation. This guide explains the complete control transfer cycle using the runtime helpers defined in citrolabs/ego-lite.
Understanding Task Space Ownership
Task spaces in ego-lite operate in two distinct ownership modes. When an agent owns the space, it can execute browser actions like clicks and navigation. When control transfers to the user, any attempted browser operation fails with a "user is controlling" error. The handOffTaskSpace and takeOverTaskSpace helpers in package/ego-browser/src/helpers.ts manage these transitions, as documented in skills/ego-browser/SKILL.md and the high-level overview in AGENTS.md.
Handing Off Control to the User
When workflows require manual intervention, agents must explicitly yield control using the runtime helper.
The handOffTaskSpace Helper
The handOffTaskSpace function transfers ownership from the agent to the user. According to the implementation in package/ego-browser/src/helpers.ts (lines 326-338), this helper accepts an optional nameOrId parameter and returns a promise resolving to a status object.
const result = await handOffTaskSpace(task.id)
Omit the parameter to target the currently selected task space.
Interpreting the Result Object
handOffTaskSpace returns an object indicating whether the transfer occurred:
{ done: true }— The handoff succeeded; the space was agent-owned and is now user-controlled.{ done: false, skipped: "user-owned" }— The space was already user-owned; no changes made.
The behavior is verified in the unit tests at package/ego-browser/src/helpers.test.mjs (lines 849-911):
test('handOffTaskSpace skips user‑owned spaces and reports it', async () => {
const result = await handOffTaskSpace('checkout-flow')
assert.deepStrictEqual(result, { done: false, skipped: 'user-owned' })
})
Always inspect result.done before proceeding.
Taking Over Control from the User
Once the user signals completion—via an Ask button or chat message—the agent must reclaim the space to resume automation.
Using takeOverTaskSpace
Call takeOverTaskSpace(nameOrId) to regain exclusive control. If the space was previously user-owned and you need to claim it without prior agent ownership, claimTaskSpace serves as an alternative entry point, though takeOverTaskSpace is the standard method for reclaiming after handoff.
await takeOverTaskSpace(task.id)
After this call succeeds, the agent can resume browser operations like clicking, typing, or capturing screenshots.
Complete Workflow Example
The following example demonstrates the full lifecycle: creating a space, performing initial automation, handing off for manual login, reclaiming control, and completing checkout.
// 1️⃣ Create or reuse a task space
const task = await useOrCreateTaskSpace('checkout flow')
cliLog(`Task space id: ${task.id}`)
// 2️⃣ Perform part of the flow
await openOrReuseTab('https://example.com/checkout', { wait: true })
await click('button#login')
// 3️⃣ Hand off to the user for manual login / captcha
const handoff = await handOffTaskSpace(task.id)
if (!handoff.done) {
// The space was already user‑owned; just inform the user
cliLog('Control already with the user – proceed when you finish.')
} else {
cliLog('Please complete the login and then click **Continue**.')
}
// …the user finishes the manual step, then clicks **Continue**…
// 4️⃣ Agent regains control
await takeOverTaskSpace(task.id)
// 5️⃣ Continue the automation
await click('button#confirm')
await captureScreenshot()
cliLog('Checkout completed.')
Closing the Task Space
When automation finishes, call completeTaskSpace(nameOrId, { keep }) to release resources. Set keep: true to leave the page open for the user, or keep: false to close it immediately.
Summary
- Task spaces isolate browser contexts and enforce single-controller ownership.
handOffTaskSpacetransfers control to the user; inspect the returned{ done, skipped }object to confirm the state change.takeOverTaskSpacereclaims control after manual steps conclude.completeTaskSpacecleans up the space with an optionalkeepflag to preserve the page.- Invalid operations during user control fail with explicit "user is controlling" errors rather than silent failures.
Frequently Asked Questions
What happens if I try to click while the user controls the space?
Any browser operation attempted while the user owns the space fails immediately with a "user is controlling" error. The agent must wait for the user to signal completion and successfully call takeOverTaskSpace before issuing further commands.
Can I hand off a task space that is already user-owned?
Yes, but handOffTaskSpace will return { done: false, skipped: "user-owned" } without making changes. This idempotent behavior prevents race conditions when multiple handoff requests occur.
What is the difference between takeOverTaskSpace and claimTaskSpace?
takeOverTaskSpace is the standard method for reclaiming control after a handOffTaskSpace call, designed for the post-intervention workflow. claimTaskSpace serves as an alternative when acquiring ownership of a space that was previously user-owned without a prior handoff from the current agent session.
Where are the unit tests for handoff behavior?
The expected outcomes for agent-owned versus user-owned spaces are validated in package/ego-browser/src/helpers.test.mjs at lines 849–911, which assert the exact return values of handOffTaskSpace under different ownership states.
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 →