How to Implement Custom Agent Helpers Using the agent_helpers.js Extension System in ego-browser
In ego-browser, custom agent helpers are implemented by creating an agent_helpers.js file in the agent's workspace directory, which the helperContext() function in src/helpers.ts automatically imports and merges into the helper surface.
The citrolabs/ego-lite repository provides an extension system that allows developers to augment the agent's capabilities without modifying core source code. By leveraging the agent_helpers.js extension system, you can inject bespoke JavaScript functions directly into the helper context, making them available to agent scripts alongside built-in methods like click() and navigate().
How the Extension System Works
According to the source code in src/helpers.ts (around line 853), the helperContext() function automatically checks for an agent_helpers.js file within the current agent workspace before executing user scripts. If present, it dynamically imports the module and assigns its exported members to the helpers object.
The loading logic implements this pattern:
// src/helpers.ts (excerpt)
const path = join(state.agentWorkspace(), "agent_helpers.js");
if (await exists(path)) {
const mod = await import(path);
Object.assign(helpers, mod);
}
This evaluation occurs once per agent session, executing before any user-provided script code runs. The custom helpers become first-class citizens in the agent environment, accessible with the same await helperName() syntax used for native helpers.
Creating the agent_helpers.js File
To implement custom agent helpers, create a file named exactly agent_helpers.js in the root of the agent's workspace directory (the path returned by state.agentWorkspace()).
You can structure your exports using either named exports or a default export:
- Named exports: Each exported function becomes available as a standalone helper callable by name.
- Default export: An object containing helper methods is merged into the context, exposing all its properties as helpers.
Practical Implementation Examples
Example 1: Named Export Helpers
Create <workspace>/agent_helpers.js with asynchronous helper functions:
// agent_helpers.js
/**
* Returns the title of the current page in uppercase.
*/
export async function pageTitleUpper() {
const title = await ego.eval(`document.title`);
return String(title).toUpperCase();
}
/**
* Clicks the first element matching a CSS selector, waiting for navigation.
*/
export async function clickAndWait(selector) {
await ego.click(selector);
await ego.waitForNavigation({ timeout: 30 });
}
Use these custom helpers in your agent script exactly like built-in methods:
// Agent script
await clickAndWait('a.login');
const title = await pageTitleUpper();
console.log('PAGE TITLE:', title);
Example 2: Default Export Pattern
Alternatively, export an object containing multiple utility functions:
// agent_helpers.js
export default {
/** Returns the current URL without query parameters. */
async cleanUrl() {
const url = await ego.eval('window.location.href');
return url.split('?')[0];
},
/** Checks if an element exists on the page. */
async exists(selector) {
return await ego.eval(`!!document.querySelector('${selector}')`);
}
};
After loading, both await cleanUrl() and await exists() are available throughout the agent session.
Technical Reference and Key Constraints
When implementing custom agent helpers according to the src/helpers.ts implementation, observe the following technical details:
- File Location: The file must reside at the workspace root as
agent_helpers.js, resolved viastate.agentWorkspace(). - Sandbox Environment: Code executes in the same sandbox as built-in helpers with no host filesystem access beyond the workspace directory.
- Reload Behavior: Changes take effect only on the next session initialization; the file loads once per agent lifecycle and is not hot-reloaded during execution.
- API Access: Custom helpers can invoke built-in helpers like
ego.click(),ego.navigate(), andego.cdp(), composing high-level automation primitives from existing methods.
Key files in the repository:
src/helpers.ts: ContainshelperContext()and the dynamic import logic for extensions.AGENTS.md: Documents the helper surface architecture and extension system integration.src/helpers.test.mjs: Provides test coverage verifying the loading behavior of custom helpers.
Summary
- Create an
agent_helpers.jsfile in the agent workspace directory to extend functionality without core modifications. - Export functions using named exports (
export function) or default exports (export default). - The
helperContext()function insrc/helpers.tsautomatically loads and merges these helpers before script execution begins. - Custom helpers run in the same secure sandbox as built-in methods and are accessed identically in agent scripts.
- Changes require a session restart to take effect, as the extension system evaluates
agent_helpers.jsonce per agent lifecycle.
Frequently Asked Questions
Where must the agent_helpers.js file be located?
The file must be placed in the agent's workspace directory, specifically at the path constructed by join(state.agentWorkspace(), "agent_helpers.js") as implemented in src/helpers.ts. The system checks for existence at this exact location before attempting to import the module.
Can I use TypeScript instead of JavaScript for custom helpers?
The extension system specifically searches for agent_helpers.js. While the ego-browser source uses TypeScript, the dynamic import in helperContext() expects a JavaScript module. You must compile TypeScript to JavaScript before the agent session starts, ensuring the output is named agent_helpers.js and placed in the workspace root.
Do custom helper changes take effect immediately during debugging?
No. The agent_helpers.js file is evaluated once per agent session during the initialization phase within helperContext(). To see modifications reflected, you must restart the agent workspace or trigger a new session, which reloads the module from disk.
Are there limitations on what APIs can be used inside custom helpers?
Custom helpers execute within the same sandbox constraints as built-in helpers, meaning they cannot access the host filesystem beyond the workspace directory. However, they have full access to the ego object and other built-in helpers, allowing you to compose complex automation logic using ego.eval(), ego.click(), ego.waitForNavigation(), and similar methods.
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 →