# Understanding Task Spaces in ego-lite: Isolated Browsing Contexts for AI Agents

> Explore task spaces in ego-lite: isolated browsing contexts for AI agents. Manage multiple workflows concurrently with separate tabs history and DOM snapshots.

- Repository: [CitroLabs/ego-lite](https://github.com/citrolabs/ego-lite)
- Tags: deep-dive
- Published: 2026-08-24

---

**Task spaces in ego-lite are isolated browsing contexts that allow AI agents to manage multiple workflows simultaneously without interference, each maintaining separate tabs, history, and DOM snapshots.**

Task spaces serve as the fundamental isolation mechanism in **citrolabs/ego-lite**, an open-source browser automation framework designed specifically for AI agent orchestration. This core abstraction enables agents to execute concurrent scripts across distinct browsing environments, ensuring that navigation history, DOM state, and tab collections remain segregated between different units of work.

## What Are Task Spaces in ego-lite?

Task spaces are containerized browsing contexts that encapsulate all browser state required for a specific workflow. Each space maintains its own set of tabs, navigation history, and DOM snapshots, preventing cross-contamination between concurrent operations. According to the source code in [`package/ego-browser/src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/helpers.ts), the runtime injects a `taskSpaces` façade into every agent script via `helperContext()`, providing a unified API for context management.

## Core Concepts and Ownership Models

### The Task Space Façade

The `taskSpaces` object exposed to agent scripts bundles all operations needed to manage isolated contexts. The façade is constructed by `createTaskSpacesFacade` in [`package/ego-browser/src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/helpers.ts) and includes methods for creation, switching, completion, and ownership transfer. This design pattern ensures that agents interact with a consistent interface regardless of underlying Chrome DevTools Protocol (CDP) complexity.

### Agent-Owned vs User-Owned Spaces

Each task space carries an **ownership** property that determines operational permissions. **Agent-owned** spaces can be switched, modified, or completed directly by the running script. **User-owned** spaces require specific transfer mechanisms before the agent can manipulate them. Ownership transitions are handled through three primary methods: `claim`, `handOff`, and `takeOver`. These checks are enforced via underlying CDP calls, with public API signatures declared in [`package/ego-browser/src/format.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/format.ts) (lines ~650-770).

## Managing Task Spaces: Key Operations

### Creating and Reusing Contexts

The `taskSpaces.useOrCreate(nameOrId)` method, implemented in [`package/ego-browser/src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/helpers.ts) (lines ~885-892), retrieves an existing space by numeric ID or name, or instantiates a new one if no match exists. This atomic operation ensures idempotent context initialization across script reruns.

Once created, `taskSpaces.switch(idOrName)` activates a specific space, directing subsequent helper calls to operate within that context's tabs and snapshots. The concrete implementation resides in `switchTaskSpace` at line ~249 of [`package/ego-browser/src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/helpers.ts).

### Transferring Control with Handoffs

Collaborative workflows require seamless transitions between automated and manual control. The `taskSpaces.handOff(idOrName)` method transfers an agent-owned space to a user, while `taskSpaces.takeOver(idOrName)` reclaims user-owned spaces for agent control. These functions map to `handOffTaskSpace` and `takeOverTaskSpace` within the façade.

For step-wise human-in-the-loop processes, `taskSpaces.waitForAgentControl(idOrName, options)` blocks execution until the agent regains ownership, defined at line ~300 of [`package/ego-browser/src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/helpers.ts). This synchronization primitive enables complex approval workflows without polling overhead.

### Completing and Cleaning Up

When a workflow terminates, `taskSpaces.complete(idOrName, { keep })` closes the task space. Setting `keep: true` preserves the space's tabs for future reference, while the default behavior removes all associated resources. This functionality is implemented in `completeTaskSpace` at line ~292 of [`package/ego-browser/src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/helpers.ts).

## Internal Architecture and CDP Integration

Internally, ego-lite represents each task space as a numeric identifier (`taskSpaceNumericId`) mapped to a dedicated CDP session. This mapping lives in the runtime's shared state ([`src/state.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/state.ts)) and refreshes automatically whenever snapshots occur. If a script references a space with an empty mapping, the runtime triggers an automatic re-snapshot via the browser runtime ([`src/browser-runtime.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/browser-runtime.ts)), ensuring reference validity across script rounds.

The CDP transport layer manages session attachment and isolation, guaranteeing that DOM operations in one task space cannot affect another's execution context. This architectural decision provides the reliability required for production AI agents handling multiple concurrent browsing tasks.

## Practical Implementation Examples

The following example demonstrates a complete workflow using task spaces in ego-lite:

```javascript
// Create or reuse a task space called "research"
const research = await taskSpaces.useOrCreate('research');
// → { id: 3, name: 'research', owner: 'agent' }

// Switch to that space so further calls operate within it
await taskSpaces.switch(research.id);

// Open a tab inside the active space
await browser.openOrReuseTab('https://news.ycombinator.com');

// Perform actions on the page
await page.waitForLoadState('networkidle');
const titles = await page.locator('a.storylink').allTextContents();
console.log(titles);

// Hand the space off to a human user for manual inspection
await taskSpaces.handOff(research.id);

// Reclaim control when ready
await taskSpaces.takeOver(research.id);
await taskSpaces.waitForAgentControl(research.id);

// Close the space but keep tabs for later reference
await taskSpaces.complete(research.id, { keep: true });

```

## Summary

- **Task spaces in ego-lite** provide isolated browsing contexts that segregate tabs, history, and DOM state between different AI agent workflows.
- **Ownership models** distinguish between agent-controlled and user-controlled spaces, with explicit transfer mechanisms via `handOff` and `takeOver`.
- **Core operations** include `useOrCreate` for idempotent initialization, `switch` for context activation, and `complete` for resource cleanup.
- **CDP integration** ensures robust isolation through numeric ID mapping and automatic session management in [`src/state.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/state.ts) and [`src/browser-runtime.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/browser-runtime.ts).
- **Human-in-the-loop support** via `waitForAgentControl` enables sophisticated collaborative automation workflows.

## Frequently Asked Questions

### How do task spaces prevent interference between concurrent AI agent scripts?

Task spaces maintain completely isolated CDP sessions and DOM snapshots for each context. When an agent switches between spaces using `taskSpaces.switch()`, the runtime directs all subsequent browser operations to that specific CDP session, ensuring that navigation, element selection, and JavaScript execution remain confined to the active space's tabs and history.

### Can multiple task spaces exist simultaneously in ego-lite?

Yes, the runtime supports multiple concurrent task spaces, each identified by a unique numeric ID stored in [`src/state.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/state.ts). Agents can create new spaces with `useOrCreate()`, switch between them dynamically, and maintain separate browsing sessions indefinitely, limited only by system resources and browser memory constraints.

### What happens if a script references a task space that no longer exists?

If the mapping between a task space reference and its CDP session becomes stale, the runtime automatically triggers a re-snapshot mechanism via [`src/browser-runtime.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/browser-runtime.ts) to rebuild the internal state map. This ensures that valid references remain functional across script reruns without manual intervention.

### How does ownership transfer work between agents and human users?

Ownership transfer utilizes two primary façade methods: `handOff()` converts an agent-owned space to user-owned status, while `takeOver()` reclaims it for the agent. The `waitForAgentControl()` function provides blocking synchronization, allowing scripts to pause until a user explicitly returns control, facilitating seamless human-in-the-loop automation workflows.