
Security News
Deno Goes the Way of the Dinosaur
Cloudflare is acquiring Deno’s team, which will provide another year of bug fixes and security updates before ending support for the runtime.
@tangle-network/agent-browser-driver
Advanced tools
LLM-driven browser agent for UI automation, testing, and evaluation
LLM-driven browser automation agent. Observe page state via accessibility tree, decide actions via LLM, execute in a loop until the goal is achieved.
agent-browser-driver.config.ts with defineConfig() for IDE autocompletenpm install @tangle-network/agent-browser-driver
npm install -D playwright # peer dependency
Automated npm publishing is configured in:
.github/workflows/publish-npm.ymlTriggers:
vX.Y.Z)workflow_dispatchRelease flow:
package.json version.main.v<same-version>.npm publish --provenance --access public).In npm package settings for @tangle-network/agent-browser-driver:
tangle-network.agent-browser-driver.publish-npm.yml.After this is configured, no long-lived npm token is required.
import { chromium } from 'playwright';
import { PlaywrightDriver, AgentRunner } from '@tangle-network/agent-browser-driver';
const browser = await chromium.launch();
const page = await browser.newPage();
const driver = new PlaywrightDriver(page, {
captureScreenshots: true,
});
const runner = new AgentRunner({
driver,
config: {
model: 'gpt-4o',
debug: true,
maxHistoryTurns: 15,
retries: 3,
},
onTurn: (turn) => {
console.log(`Turn ${turn.turn}: ${turn.action.action}`);
if (turn.reasoning) console.log(` Reasoning: ${turn.reasoning}`);
},
});
const result = await runner.run({
goal: 'Sign in and navigate to settings',
startUrl: 'https://app.example.com',
maxTurns: 50,
});
console.log(result.success ? 'Success' : `Failed: ${result.reason}`);
console.log(`Completed in ${result.turns.length} turns, ${result.totalMs}ms`);
await browser.close();
Create agent-browser-driver.config.ts in your project root:
import { defineConfig } from '@tangle-network/agent-browser-driver';
export default defineConfig({
provider: 'anthropic',
model: 'claude-sonnet-4-20250514',
headless: true,
concurrency: 4,
maxTurns: 30,
timeoutMs: 300_000,
outputDir: './test-results',
reporters: ['junit', 'html'],
memory: { enabled: true },
});
The CLI and programmatic API both auto-detect this file. CLI flags override config values. Supports .ts, .js, .mjs.
| Key | Type | Default | Description |
|---|---|---|---|
provider | 'openai' | 'anthropic' | 'google' | 'openai' | LLM provider |
model | string | 'gpt-4o' | Model name |
apiKey | string | env var | API key |
baseUrl | string | — | Custom endpoint (LiteLLM, etc.) |
headless | boolean | true | Browser headless mode |
viewport | { width, height } | 1920x1080 | Browser viewport |
browserArgs | string[] | [] | Extra Chromium launch args |
wallet | { enabled?, extensionPaths?, userDataDir? } | — | Persistent Chromium profile + extension mode |
maxTurns | number | 30 | Max turns per test |
timeoutMs | number | 600000 | Per-test timeout |
concurrency | number | 1 | Parallel workers |
screenshotInterval | number | 5 | Capture every N turns |
vision | boolean | true | Send screenshots to LLM |
goalVerification | boolean | true | Verify goal completion |
qualityThreshold | number | 0 | Min quality 1-10 (0=skip) |
outputDir | string | './agent-results' | Artifact output dir |
reporters | ('json' | 'markdown' | 'html' | 'junit')[] | ['json'] | Report formats |
sinks | ArtifactSink[] | — | Custom artifact sinks |
resourceBlocking | ResourceBlockingOptions | — | Block analytics/images/media for faster tests |
memory | { enabled, dir } | disabled | Trajectory memory |
projects | Array<{ name, config, testDir, testMatch }> | — | Named project configs |
For wallet flows (MetaMask, Rabby, etc.), use persistent Chromium context mode.
import { defineConfig } from '@tangle-network/agent-browser-driver';
export default defineConfig({
headless: false,
concurrency: 1,
wallet: {
enabled: true,
extensionPaths: ['./extensions/metamask'],
userDataDir: './.agent-wallet-profile',
},
});
CLI equivalent:
agent-driver run \
--cases ./wallet-cases.json \
--wallet \
--extension ./extensions/metamask \
--user-data-dir ./.agent-wallet-profile \
--no-headless
Notes:
chromium.launchPersistentContext(...).1 in wallet mode.The LLM can choose from:
| Action | Description |
|---|---|
click | Click element by @ref selector |
type | Type text into input |
press | Press a key (Enter, Tab, Escape, etc.) |
hover | Hover over element |
select | Select dropdown option |
scroll | Scroll up/down |
navigate | Go to URL |
wait | Wait for ms |
evaluate | Assess visual quality |
verifyPreview | Check preview iframe for errors |
complete | Goal achieved |
abort | Cannot continue |
Run structured test suites with ground-truth verification:
import { TestRunner } from '@tangle-network/agent-browser-driver';
const runner = new TestRunner({
driver,
config: { model: 'gpt-4o', vision: true },
enableMemory: true,
});
const suite = await runner.runSuite([
{
id: 'login',
name: 'User login flow',
startUrl: 'https://app.example.com/login',
goal: 'Log in with test credentials',
successCriteria: [
{ type: 'url-contains', value: '/dashboard' },
{ type: 'element-visible', selector: '[data-testid="user-menu"]' },
],
},
]);
console.log(`Pass rate: ${(suite.summary.passRate * 100).toFixed(0)}%`);
# Single task
agent-driver run --goal "Sign up for account" --url http://localhost:3000
# Test suite with config file
agent-driver run --cases ./cases.json
# Override config with CLI flags
agent-driver run --cases ./cases.json --model claude-sonnet-4-20250514 --concurrency 4
# Explicit config path
agent-driver run --config ./ci.config.ts --cases ./cases.json
# Wallet mode with extension
agent-driver run --cases ./wallet-cases.json --wallet --extension ./extensions/metamask --no-headless
import { generateReport } from '@tangle-network/agent-browser-driver';
const xml = generateReport(suiteResult, { format: 'junit' });
fs.writeFileSync('results.xml', xml);
Or use it directly:
import { generateJUnitXml } from '@tangle-network/agent-browser-driver';
const xml = generateJUnitXml(suiteResult);
Produces standard JUnit XML that GitHub Actions, Jenkins, and GitLab parse natively. Tests grouped by testCase.category, failures include verdict + last actions.
generateReport(suite, { format: 'json' }); // Full TestSuiteResult JSON
generateReport(suite, { format: 'markdown' }); // Summary + per-test table
generateReport(suite, { format: 'html' }); // Styled dashboard
import { FilesystemSink } from '@tangle-network/agent-browser-driver';
const sink = new FilesystemSink('./results');
// Writes: results/{testId}/turn-05.jpg, results/manifest.json
POST artifact events to any URL (Slack, Discord, CI dashboard):
import { WebhookSink } from '@tangle-network/agent-browser-driver';
const sink = new WebhookSink({
url: 'https://hooks.slack.com/services/...',
headers: { Authorization: 'Bearer token' },
events: ['screenshot', 'report-json'], // filter artifact types
includeData: false, // skip base64 payload
retries: 3, // exponential backoff
});
On put(), POSTs:
{ "event": "artifact", "testId": "signup", "type": "screenshot", "name": "turn-05.jpg", "sizeBytes": 45230 }
On close(), POSTs:
{ "event": "suite:complete", "manifest": [...], "summary": { "total": 5, "passed": 4, "failed": 1 } }
Never throws — webhook failures are logged, not fatal.
Chain multiple sinks (write locally + POST to webhook):
import { CompositeSink, FilesystemSink, WebhookSink } from '@tangle-network/agent-browser-driver';
const sink = new CompositeSink([
new FilesystemSink('./results'), // primary — URIs come from this one
new WebhookSink({ url: '...' }), // secondary
]);
Implement the Driver interface:
import type { Driver, ActionResult } from '@tangle-network/agent-browser-driver';
class MyDriver implements Driver {
async observe(): Promise<PageState> { /* ... */ }
async execute(action: Action): Promise<ActionResult> { /* ... */ }
getPage?(): Page | undefined { /* ... */ }
async screenshot?(): Promise<Buffer> { /* ... */ }
async close?(): Promise<void> { /* ... */ }
}
pnpm build # TypeScript → dist/
pnpm test # vitest (49 unit tests, ~130ms)
pnpm test:watch # vitest watch mode
Dual-licensed under MIT and Apache 2.0. See LICENSE for details.
FAQs
LLM-driven browser agent for UI automation, testing, and evaluation
The npm package @tangle-network/agent-browser-driver receives a total of 0 weekly downloads. As such, @tangle-network/agent-browser-driver popularity was classified as not popular.
We found that @tangle-network/agent-browser-driver demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 4 open source maintainers collaborating on the project.

Security News
Cloudflare is acquiring Deno’s team, which will provide another year of bug fixes and security updates before ending support for the runtime.

Security News
Anthropic’s free OSS Scanner uses Mythos and other Claude models to find open source vulnerabilities and send maintainers reports with proposed fixes.

Security News
On Front Lines’ Early Adopters: CISO podcast, Andrew Becherer shares lessons from Datadog, weighs the long-term costs of AI-built tools, and explains how founders can actually gain a CISO’s trust.