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

# Content gate: reject empty or refused responses

> Block agent outputs that are empty, whitespace-only, or contain phrases where the model declines to answer instead of completing the task.

The content gate catches two failure modes that other gates cannot: an agent that returns nothing at all, and an agent that responds with a refusal rather than completing its assigned task. Both are treated as gate failures because they represent output that will not satisfy the user, even if the output is structurally valid.

Both checks are enabled by default and can be turned off independently.

## Usage

```typescript theme={null}
import { createEngine, gates } from "@pecta/core";

const engine = createEngine({
  gates: [
    gates.content(),
  ],
});

const result = await engine.evaluate({
  agent_id: "assistant",
  output: "I'm just an AI and I can't help with that.",
});
// result.passed === false
```

## Empty output detection

The gate considers `ctx.output` empty if it is any of the following:

* `undefined` or `null`
* A string containing only whitespace (or an empty string)
* An empty array (`[]`)
* An object with no own keys (`{}`)

Any other value — including `false`, `0`, or a non-empty string — is treated as non-empty.

## AI refusal phrase detection

The gate scans every string in `ctx.output` for phrases that indicate the model is declining to fulfill the request rather than producing useful output. The following patterns are matched case-insensitively:

| Pattern                                                  | Example phrase                                |
| -------------------------------------------------------- | --------------------------------------------- |
| `i don't have access` / `i do not have access`           | "I don't have access to real-time data."      |
| `i don't have the ability` / `i do not have the ability` | "I don't have the ability to browse the web." |
| `i can't do` / `i cannot do`                             | "I cannot do that."                           |
| `i can't help` / `i cannot help`                         | "I can't help with this request."             |
| `i can't provide` / `i cannot provide`                   | "I cannot provide personal advice."           |
| `i can't access` / `i cannot access`                     | "I can't access external systems."            |
| `i can't complete` / `i cannot complete`                 | "I cannot complete this task."                |
| `i can't fulfill` / `i cannot fulfill`                   | "I can't fulfill that request."               |
| `i can't assist` / `i cannot assist`                     | "I cannot assist with that."                  |
| `as an ai language model`                                | "As an AI language model, I..."               |
| `as an ai model`                                         | "As an AI model, I..."                        |
| `i'm an ai` / `i am an ai` / `i'm just an ai`            | "I'm just an AI."                             |

The gate returns `passed: false` on the first match it finds. It does not enumerate all matching phrases.

## What a failure looks like

```json theme={null}
{
  "name": "content",
  "passed": false,
  "reason": "output contains refusal/disclaimer",
  "latency_ms": 0.17
}
```

```json theme={null}
{
  "name": "content",
  "passed": false,
  "reason": "output is empty",
  "latency_ms": 0.06
}
```

## Configuration

<ParamField path="rejectEmpty" type="boolean">
  Fail evaluations where `ctx.output` is empty, whitespace-only, an empty array, or an empty object. Defaults to `true`.
</ParamField>

<ParamField path="rejectRefusals" type="boolean">
  Fail evaluations where any string in `ctx.output` matches a known AI refusal or disclaimer phrase. Defaults to `true`.
</ParamField>

<ParamField path="name" type="string">
  Override the gate name recorded in results. Defaults to `"content"`.
</ParamField>

## Disabling a check

```typescript theme={null}
import { createEngine, gates } from "@pecta/core";

const engine = createEngine({
  gates: [
    gates.content({
      rejectEmpty: true,
      rejectRefusals: false, // agent may legitimately explain its constraints
    }),
  ],
});
```

<Tip>
  Place `gates.content()` early in your gate list. With `failFast: true` (the default), detecting an empty or refused output immediately aborts the remaining gates — avoiding schema validation and PII scanning on output that you are going to reject anyway.
</Tip>
