How Ego-Lite Manages Parallel Agent Workspaces: Task Spaces and Isolation Explained
Ego-Lite isolates parallel agent workspaces through lightweight containers called task spaces, each maintaining an independent Chrome DevTools Protocol (CDP) session with strict ownership controls that prevent cross-agent interference.
The citrolabs/ego-lite repository implements a sophisticated workspace isolation system that allows multiple AI agents to operate concurrently without conflicts. Understanding how ego-lite manages parallel agent workspaces requires examining its task space architecture, which combines CDP session isolation with an ownership-based access control model defined in src/helpers.ts and src/browser-runtime.ts.
What Are Task Spaces?
Task spaces are lightweight containers that encapsulate an independent Chrome DevTools Protocol (CDP) session, snapshot state, and DOM reference map. Each task space is identified by a numeric ID and a human-readable name, carrying an ownership flag that distinguishes between agent and user ownership. This design ensures that browser state, network traffic, and DOM mutations remain strictly compartmentalized between different agents operating simultaneously.
The Ownership Model
The ownership system prevents accidental interference between agents and human users. Only task spaces owned by the agent can be directly controlled; user-owned spaces must first be claimed through an explicit ownership transfer. This validation occurs in functions like switchTaskSpace(), which checks the ownership flag before allowing context switches, ensuring agents cannot inadvertently modify user-controlled browsing sessions.
Core Workspace Management API
The primary implementation resides in src/helpers.ts, which exposes functions for the complete task space lifecycle.
Listing and Creating Workspaces
The listTaskSpaces() function (lines 107-113) queries the host runtime via ego.listTaskSpaces and normalizes the result array. To create new isolated environments, newTaskSpace(name) (lines 171-183) invokes ego.createTaskSpace, validates the response, and immediately selects the new space as the active context, attaching a fresh CDP session.
Switching and Reusing Workspaces
Agents switch contexts using switchTaskSpace(idOrName) (lines 152-163), which verifies agent ownership before calling ego.useTaskSpace. For idempotent operations, useOrCreateTaskSpace(nameOrId) (lines 193-210) either selects an existing space or creates a new one, handling optional ownership claims automatically when encountering user-owned spaces.
Ownership Transfer Operations
When agents need to access user-controlled spaces, claimTaskSpace(nameOrId) (lines 224-236) transfers ownership via ego.claimTaskSpace and then selects the space. The handOffTaskSpace() function (lines 326-338) returns control to users, continuing execution only if the space is already agent-owned. For forced transfers, takeOverTaskSpace() (lines 347-353) bypasses standard validation checks to seize immediate control.
Workspace Lifecycle Completion
The completeTaskSpace(nameOrId, {keep}) function (lines 274-314) handles cleanup. When keep is false, the space is claimed (if necessary), selected, and closed via ego.closeTaskSpace; when true, the persistent session remains available for future agent use without terminating the underlying CDP connection.
Isolation Mechanisms
Parallelism in ego-lite relies on three architectural layers working in concert:
- Separate CDP Sessions: Each task space receives its own CDP session cached with a 2-second TTL in
src/browser-runtime.ts, ensuring network traffic and page state remain isolated between workspaces. - Singleton State Management: The active space ID and reference maps reside in
src/state.ts, maintaining global mutable runtime state that scopes all DOM operations to the current workspace throughsrc/element-resolver.ts. - Explicit State API: Helper functions enforce intentional transitions, with ownership checks preventing accidental cross-space operations.
Practical Implementation Examples
// Create a dedicated workspace for an agent
const mySpace = await newTaskSpace('agent-42-workspace');
// → a new CDP session is attached and becomes the active context
// Re-use an existing workspace or create if missing
const reused = await useOrCreateTaskSpace('shared-workspace');
// Switch to another agent-owned space
await switchTaskSpace(23); // numeric ID
await switchTaskSpace('other-agent-space');
// Hand control back to the user after completing tasks
await handOffTaskSpace(); // no argument → current space
// Clean up when finished
await completeTaskSpace('agent-42-workspace', { keep: false });
Each call validates ownership, communicates with the native ego bridge, and updates the singleton runtime state so subsequent operations execute against the intended space. The driver implementations in src/driver/ (navigation, pointer, keyboard) all operate against the session attached to the active task space.
Summary
- Task spaces are lightweight containers combining CDP sessions, snapshots, and DOM reference maps identified by numeric IDs and human-readable names.
- Ownership flags (
agentvsuser) enforce access control insrc/helpers.ts, requiring explicit claims viaclaimTaskSpace()to transfer workspace control. - Isolation is achieved through separate CDP sessions cached per-space in
src/browser-runtime.tsand scoped state management insrc/state.ts. - Core API functions handle creation (
newTaskSpace), switching (switchTaskSpace), claiming (claimTaskSpace), and cleanup (completeTaskSpace). - Concurrent execution is supported by the ego-lite binary multiplexing CDP connections while maintaining strict separation between agent workspaces through the ownership model.
Frequently Asked Questions
What is a task space in ego-lite?
A task space is a lightweight container defined in the ego-lite architecture that holds an independent Chrome DevTools Protocol (CDP) session, snapshot state, and DOM reference map. It is identified by a numeric ID and human-readable name, with an ownership flag determining whether an agent or user controls the workspace.
How does ego-lite prevent agents from interfering with each other?
Ego-lite enforces isolation through separate CDP sessions per task space (cached in src/browser-runtime.ts) and an ownership model that restricts agents to manipulating only their owned spaces. The switchTaskSpace() function explicitly checks ownership before allowing context switches, while src/state.ts maintains separate reference maps for each active space.
Can an agent take over a workspace from a user?
Yes, but it requires explicit ownership transfer. The claimTaskSpace() function (lines 224-236 in src/helpers.ts) calls ego.claimTaskSpace to transfer ownership from user to agent. Alternatively, takeOverTaskSpace() (lines 347-353) forces ownership transfer without standard validation, though this should be used cautiously as it bypasses normal access controls.
What happens when an agent completes its work in a task space?
The completeTaskSpace() function handles cleanup based on the keep parameter. If keep is true, the session persists for future use; if false, the function claims the space (if not already owned), selects it, and closes it via ego.closeTaskSpace, releasing all associated CDP resources and removing the workspace from the active pool.
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 →