# Stealth

URL: https://cogitator.app/docs/browser/stealth

> Anti-detection evasions, fingerprint randomization, and human-like behavior for browser automation.

## Overview

Many websites detect and block automated browsers. The stealth system counters this with browser fingerprint evasions, user agent rotation, and human-like input simulation.

Enable stealth with `stealth: true` for defaults, or pass a `StealthConfig` for fine-grained control.

```typescript
import { BrowserSession, browserTools } from '@cogitator-ai/browser';

const session = new BrowserSession({
  headless: true,
  stealth: true,
});

await session.start();
```

## StealthConfig

```typescript
interface StealthConfig {
  humanLikeTyping?: boolean; // default: true
  humanLikeMouse?: boolean; // default: true
  fingerprintRandomization?: boolean; // default: true
  blockWebDriver?: boolean; // default: true
  evasionScripts?: string[]; // custom init scripts
}
```

When `stealth: true` is passed, all boolean options default to `true`. With an object, any option you omit also falls back to its default, so you only list what you want to change:

```typescript
const session = new BrowserSession({
  stealth: {
    humanLikeTyping: true,
    humanLikeMouse: false,
    fingerprintRandomization: true,
    blockWebDriver: true,
  },
});
```

## Evasion Scripts

When stealth is enabled, the following evasion scripts run automatically on every new page via `context.addInitScript`. `blockWebDriver: false` drops the WebDriver and Permissions evasions; `fingerprintRandomization: false` drops the rest and the random user agent.

| Evasion     | Gated by                   | What it does                                                                                                                    |
| ----------- | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
| WebDriver   | `blockWebDriver`           | Sets `navigator.webdriver` to `false` on `Navigator.prototype` (no detectable own property)                                     |
| Plugins     | `fingerprintRandomization` | Fakes `navigator.plugins` with Chrome PDF Plugin, PDF Viewer, Native Client                                                     |
| Languages   | `fingerprintRandomization` | Derives `navigator.languages` from `locale` (`de-DE` → `['de-DE', 'de']`, default `['en-US', 'en']`)                            |
| Platform    | `fingerprintRandomization` | Aligns `navigator.platform` and `navigator.userAgentData.platform` with the user agent (`Win32`, `MacIntel`, `Linux x86_64`, …) |
| Canvas      | `fingerprintRandomization` | `toDataURL` returns a copy with ±1 per-channel noise from a seeded PRNG; the original canvas is untouched                       |
| WebGL       | `fingerprintRandomization` | Overrides WebGL vendor/renderer to report Intel Iris OpenGL Engine                                                              |
| Chrome      | `fingerprintRandomization` | Adds `window.chrome` object with `runtime`, `loadTimes`, `csi` stubs                                                            |
| Permissions | `blockWebDriver`           | Overrides `Permissions.query` to return `denied` for notifications                                                              |

### Custom Evasion Scripts

Add your own init scripts that run before any page content:

```typescript
const session = new BrowserSession({
  stealth: {
    evasionScripts: [
      `Object.defineProperty(navigator, 'hardwareConcurrency', { get: () => 8 });`,
      `Object.defineProperty(navigator, 'deviceMemory', { get: () => 8 });`,
    ],
  },
});
```

## Human-Like Behavior

With `humanLikeTyping`, the `browser_type` and `browser_fill_form` tools clear the field and type it key by key with a random 50-150ms per-key delay (picked once per call), so the result matches the instant `fill()` used without stealth. An explicit `delay` on `browser_type` takes precedence.

With `humanLikeMouse`, `browser_click`, `browser_click_by_description` and `browser_hover` move the mouse along a Bezier curve from its last position before acting, and `browser_scroll` hovers the target (if a selector is given) and scrolls with several small wheel steps.

For direct use without tools, the package exports four human-like action helpers:

### `humanLikeType(page, selector, text)`

Clicks the element, then types each character with a random delay between 50-150ms.

```typescript
import { humanLikeType } from '@cogitator-ai/browser';

await humanLikeType(page, '#search', 'cogitator ai');
```

### `humanLikeClick(page, target, options?)`

Scrolls the element into view, moves the mouse to it along a Bezier curve with random control points (starting from the last known mouse position), then clicks near the element center. `target` is a selector (first match) or a Playwright `Locator`. Options: `from`, `button`, `clickCount`, `position` (relative to the element).

```typescript
import { humanLikeClick } from '@cogitator-ai/browser';

await humanLikeClick(page, '#submit-button');
await humanLikeClick(page, page.getByRole('row').nth(2), { clickCount: 2 });
```

### `humanLikeHover(page, target, options?)`

Same mouse path as `humanLikeClick`, without clicking.

```typescript
import { humanLikeHover } from '@cogitator-ai/browser';

await humanLikeHover(page, '#menu');
```

### `humanLikeScroll(page, direction, amount)`

Scrolls `up`, `down`, `left` or `right` in multiple small increments with random pauses and slight variation in scroll distance per step.

```typescript
import { humanLikeScroll } from '@cogitator-ai/browser';

await humanLikeScroll(page, 'down', 500);
```

## User Agent Rotation

When stealth is enabled and no custom `userAgent` is set, a random user agent is selected from a curated pool that matches the browser type. The pool includes recent desktop Chrome, Edge, Firefox, and Safari user agents across Windows, macOS, and Linux, matching the desktop viewport the session uses. The platform evasion keeps `navigator.platform` consistent with the chosen user agent.

```typescript
import { getRandomUserAgent, getAllUserAgents } from '@cogitator-ai/browser';

const ua = getRandomUserAgent('chromium');
const all = getAllUserAgents(); // { chromium: [...], firefox: [...], webkit: [...] }
```

## Stealth for Your Own Playwright Context

The building blocks are exported, so you can apply the same evasions to a context you manage yourself:

```typescript
import { chromium } from 'playwright';
import { applyStealthToContext, getStealthLaunchOptions } from '@cogitator-ai/browser';

const stealth = { blockWebDriver: true, fingerprintRandomization: true };
const launchOptions = getStealthLaunchOptions(stealth, 'chromium'); // { userAgent }

const browser = await chromium.launch();
const context = await browser.newContext(launchOptions);
await applyStealthToContext(context, stealth, {
  userAgent: typeof launchOptions.userAgent === 'string' ? launchOptions.userAgent : undefined,
  locale: 'en-US',
});
```

`getEvasionScripts({ blockWebDriver, fingerprintRandomization, userAgent, locale })` returns the raw init scripts if you want to inject them another way.

## Full Stealth Example

```typescript
import { Cogitator, Agent } from '@cogitator-ai/core';
import { BrowserSession, browserTools } from '@cogitator-ai/browser';

const session = new BrowserSession({
  headless: true,
  browser: 'chromium',
  stealth: {
    humanLikeTyping: true,
    humanLikeMouse: true,
    fingerprintRandomization: true,
    blockWebDriver: true,
  },
  viewport: { width: 1920, height: 1080 },
  locale: 'en-US',
  timezone: 'America/New_York',
});

await session.start();

const agent = new Agent({
  name: 'stealth-scraper',
  model: 'openai/gpt-6.1-sol',
  tools: browserTools(session),
  instructions: 'Browse websites naturally. Extract the requested data.',
});

const cogitator = new Cogitator({
  llm: {
    defaultModel: 'openai/gpt-6.1-sol',
    providers: { openai: { apiKey: process.env.OPENAI_API_KEY! } },
  },
});

const result = await cogitator.run(agent, {
  input: 'Search for "AI agent frameworks" and summarize the top results',
});

console.log(result.output);
await session.close();
```

## Next Steps

* [BrowserSession](/docs/browser/session) — session configuration reference
* [Vision](/docs/browser/vision) — screenshot and accessibility-based tools
