How ego-lite Manages CDP Sessions and Automatic Re-attachment
ego-lite maintains a 2-second TTL-based CDP session that automatically re-attaches to the browser when connections are lost, using centralized state management and transparent retry logic.
The citrolabs/ego-lite browser automation framework communicates with Chromium through the Chrome DevTools Protocol (CDP) using a resilient session management architecture. This article examines how ego-lite handles CDP session lifecycle, implements automatic re-attachment, and maintains connection state to ensure uninterrupted browser automation.
Session TTL and Validation
ego-lite considers a CDP session valid for 2 seconds after creation, defined by the SESSION_TTL_MS = 2000 constant in src/browser-runtime.ts (line 5). After this period, the runtime treats the session as expired and requests a new one.
Every helper function that requires a page-level CDP call first invokes ensureSession() (lines 7-44). This function checks state.sessionId and validates whether the session has exceeded the TTL using the sessionAt timestamp. If the session is missing or stale, ensureSession() automatically creates a fresh session.
Session Creation and Target Attachment
When ensureSession() determines a new session is needed, it executes the following sequence (lines 16-36 in src/browser-runtime.ts):
- Lists all available tabs using
browserEgo().listTabs() - Selects the target tab based on priority:
state.preferredTargetIdif set, otherwise the active tab, or the last tab - Calls
Target.attachToTargetwith flattened mode to obtain a new session ID - Stores the session ID in
state.sessionIdand updatesstate.sessionAtwith the current timestamp - Invokes
enablePageEvents(state.sessionId)to buffer page events likePage.loadEventFired
Developers can force attachment to a specific tab by setting state.preferredTargetId via the setPreferredTarget() function (lines 56-58).
Automatic Re-attachment Mechanism
Session loss is handled transparently through the browserCdp function's error handling logic (lines 95-103). When a CDP request fails with a "session not found" or "Target closed" error (matched against the SESSION_LOST regex), the runtime:
- Checks if the call was explicitly bound to a session
- If not bound, calls
invalidateSession()(lines 46-54) to clearstate.sessionIdand associated caches (pageEnabledSessions,pendingDialogs) - Retries the original request with a newly created session via
ensureSession()
This automatic retry mechanism ensures that transient connection failures do not interrupt automation scripts.
Central State Management
All session-related state lives in the exported state object defined in src/state.ts (lines 24-38):
sessionId: Current CDP session identifiersessionTargetId: The target (tab) to which the session is attachedsessionAt: Timestamp of last successful session acquisition (used for TTL validation)sessionInflight: Promise tracking ongoing session creation to prevent duplicate workpreferredTargetId: Optional override specifying which tab to attach todefaultTimeout: Default CDP request timeout (10 seconds)
Practical Implementation Examples
The following examples demonstrate how to interact with ego-lite's session management:
// Force the runtime to use a specific tab
import { browserCdp, setPreferredTarget } from "ego-browser";
setPreferredTarget("target-id-123");
// Page-level CDP commands automatically ensure a valid session
const result = await browserCdp("Page.navigate", { url: "https://example.com" });
console.log(result);
// Manual session invalidation for advanced error handling
import { browserCdp, invalidateSession } from "ego-browser";
try {
await browserCdp("Runtime.evaluate", { expression: "document.title" });
} catch (err) {
if (/Session.*not found/.test(err.message)) {
invalidateSession(); // Force fresh attachment
const title = await browserCdp("Runtime.evaluate", { expression: "document.title" });
console.log("Recovered title:", title);
} else {
throw err;
}
}
Summary
- Session TTL: CDP sessions remain valid for 2 seconds (
SESSION_TTL_MS = 2000) before requiring renewal - Automatic Creation: The
ensureSession()function insrc/browser-runtime.tshandles lazy session initialization and tab selection - Transparent Recovery: The
browserCdpfunction automatically retries failed requests after callinginvalidateSession()when session loss is detected - Centralized State: Session metadata is stored in the mutable
stateobject fromsrc/state.ts, including IDs, timestamps, and configuration - Tab Targeting: Use
setPreferredTarget()to force attachment to specific tabs viastate.preferredTargetId
Frequently Asked Questions
How long does ego-lite keep a CDP session active?
ego-lite maintains a CDP session for 2 seconds after creation. The SESSION_TTL_MS constant in src/browser-runtime.ts defines this duration, after which ensureSession() automatically creates a new session on the next page-level CDP call.
What happens when a CDP session is lost during execution?
When a request fails with a session error, browserCdp catches the exception using the SESSION_LOST regex, calls invalidateSession() to clear the cached ID, and transparently retries the request with a fresh session. This occurs in lines 95-103 of src/browser-runtime.ts.
Can I force ego-lite to use a specific browser tab?
Yes. Call setPreferredTarget(targetId) to set state.preferredTargetId. During the next session creation, ensureSession() will prioritize this target ID when calling Target.attachToTarget, ensuring attachment to your specified tab.
Where is session state stored in ego-lite?
Session state resides in the exported state object defined in src/state.ts (lines 24-38). This includes sessionId, sessionTargetId, sessionAt timestamps, and the sessionInflight promise used to prevent duplicate session creation requests.
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 →