> ## Documentation Index
> Fetch the complete documentation index at: https://docs.benchspan.com/llms.txt
> Use this file to discover all available pages before exploring further.

# TypeScript SDK

> Full reference for the @benchspan/sdk package.

```bash theme={null}
npm install @benchspan/sdk
```

* Node 18+ (uses native `fetch`)
* Zero runtime dependencies beyond what you already have for your agent framework
* ESM only

## `BenchGuard`

```typescript theme={null}
import { BenchGuard } from "@benchspan/sdk";

const guard = new BenchGuard({
  apiKey: "ag_live_...",     // required
  agent: "email-agent",       // optional: tags scans in dashboard
  mode: "block",              // optional: "block" (default) or "warn"
  apiUrl: "https://api.benchspan.com",  // optional: override for self-hosted
});
```

### Config

<ResponseField name="apiKey" type="string" required>
  Bearer API key from [Dashboard → API Keys](https://benchspan.com/dashboard/api-keys). Format: `ag_live_...`.
</ResponseField>

<ResponseField name="agent" type="string">
  Optional label to tag every scan from this instance.
</ResponseField>

<ResponseField name="mode" type="&#x22;block&#x22; | &#x22;warn&#x22;" default="&#x22;block&#x22;">
  In block mode, `scanOrThrow` throws `InjectionDetectedError` on injection. Framework integrations (`asAgentHooks`, `asLangChainCallback`, `asMiddleware`, `asAdkCallback`) use `scanOrThrow` internally, so block mode aborts before the LLM call. In warn mode, those integrations fire the scan as an unawaited Promise so your LLM call proceeds with zero added latency; detections land in your dashboard asynchronously.
</ResponseField>

<ResponseField name="apiUrl" type="string" default="https://api.benchspan.com">
  Override the API host. Used for self-hosted deployments.
</ResponseField>

## Methods

### `guard.scan(input, options?) → Promise<ScanResult>`

Scan a single string. Returns the verdict; does **not** throw on injection.

```typescript theme={null}
const result = await guard.scan("some text", { role: "user" });
// result.injection      → boolean
// result.score          → number, 0–1
// result.verdict        → "block" | "warn" | "pass"
// result.model_version  → string
// result.latency_ms     → number
// result.id             → string (UUID)
```

### `guard.scanOrThrow(input, options?) → Promise<ScanResult>`

Same as `scan`, but throws `InjectionDetectedError` when the verdict is `block` (in block mode) and logs a warning when it's `warn`. Always synchronous; use the framework integrations for zero-latency warn-mode behavior.

```typescript theme={null}
try {
  await guard.scanOrThrow(toolOutput, { role: "tool" });
  // no injection, proceed
} catch (e) {
  if (e instanceof InjectionDetectedError) {
    console.log(`Blocked: ${e.result.score}`);
  }
}
```

### `guard.wrapCall(messages, fn)`

Scans an array of chat messages, then invokes `fn()`. Throws before `fn()` runs if an injection is found.

```typescript theme={null}
import OpenAI from "openai";

const client = new OpenAI();

const result = await guard.wrapCall(
  messages,
  () => client.chat.completions.create({ model: "gpt-4o", messages }),
);
```

Message objects can follow any of these shapes:

```typescript theme={null}
{ role: "user" | "tool" | "system" | "assistant", content: string, name?: string }
```

`system` and `assistant` roles are skipped.

### `guard.asAgentHooks()`

Returns an object with `onToolEnd(context, agent, tool, result)` for the OpenAI Agents SDK. See [OpenAI Agents integration](/integrations/openai-agents).

### `guard.asLangChainCallback()`

Returns a LangChain JS callback object with `handleChatModelStart` and `handleLLMStart`. See [LangChain integration](/integrations/langchain).

### `guard.asMiddleware()`

Returns a Vercel AI SDK middleware with `transformParams`. Scans the prompt before the model is invoked. See [Vercel AI SDK integration](/integrations/vercel-ai).

### `guard.asAdkCallback()`

Returns a `beforeModelCallback` for the Google ADK. Scans every part of every content before the LLM call. See [Google ADK integration](/integrations/google-adk).

## Types

### `ScanResult`

```typescript theme={null}
interface ScanResult {
  id: string;
  injection: boolean;
  score: number;
  verdict: "block" | "warn" | "pass";
  model_version: string;
  latency_ms: number;
}
```

### `BenchGuardConfig`

```typescript theme={null}
interface BenchGuardConfig {
  apiKey: string;
  agent?: string;
  mode?: "block" | "warn";
  apiUrl?: string;
}
```

### `ScanOptions`

```typescript theme={null}
interface ScanOptions {
  role?: "user" | "tool";
  source?: string;
}
```

### `InjectionDetectedError`

```typescript theme={null}
class InjectionDetectedError extends Error {
  result: ScanResult;
}
```

Thrown by `scanOrThrow`, `wrapCall`, and all framework integrations when `verdict === "block"`.
