Conversation guardrails
Guardrails let you intercept both user inputs and assistant outputs before they reach the model or the caller. Each guardrail bundles one or more checks that return a disposition (allow, warn, block).
import {
createAgent,
createRegexGuardrail,
createCodeGuardrail,
GuardrailPhase,
} from "@cognipeer/agent-sdk";
const guardrails = [
createRegexGuardrail(/password|secret/i, {
guardrailId: "password-filter",
guardrailTitle: "Sensitive secret filter",
phases: [GuardrailPhase.Request],
rule: {
failureMessage: "Outbound request blocked: secret detected.",
},
}),
createCodeGuardrail({
guardrailId: "code-ban",
guardrailTitle: "No raw code",
phases: [GuardrailPhase.Response],
rule: { disposition: "block" },
}),
];
const agent = createAgent({
model,
guardrails,
});When a guardrail blocks a request, the agent adds an assistant message summarising the violation and stops before sending content to the model. For responses, the offending assistant turn is replaced with a guardrail notice.
Built-in checks
| Check | Factory | Description |
|---|---|---|
| Regex pattern | regexRule | Blocks (or warns) when a regular expression matches the selected message text. |
| JSON schema | jsonSchemaRule | Parses the message as JSON and validates it with either a Zod schema or JSON Schema. |
| Code detection | codePresenceRule | Flags messages containing fenced code blocks or common programming keywords. |
| Agent verdict | agentVerdictRule | Delegates the decision to another agent that returns structured output. |
| Custom callback | customCallbackRule | Runs arbitrary user logic for full control. |
Each helper returns a GuardrailRule that you can feed into createGuardrail({ checks: [...] }). For convenience, preset builders (createRegexGuardrail, createJsonGuardrail, createCodeGuardrail) wrap a single rule into a ready-to-use guardrail.
Programmatic evaluation
Every invocation stores the aggregated outcome in result.state?.guardrailResult and emits guardrail events through onEvent hooks:
const result = await agent.invoke({ messages: [...] }, {
onEvent(event) {
if (event.type === "guardrail") {
console.log(`[${event.phase}] ${event.disposition} -> ${event.reason}`);
}
},
});
console.log(result.state?.guardrailResult);GuardrailOutcome lists all incidents (warnings and blocks) so you can audit or surface them in your product.
Judge with Jev
agentVerdictRule normally asks a guardian agent for a verdict. With engine: "jev" it asks Jev, TypeSafe's decision model, a yes/no question about the latest message instead, and blocks when the probability reaches a threshold:
agentVerdictRule({
engine: "jev",
jev: {
apiKey: process.env.TYPESAFE_API_KEY, // or set TYPESAFE_API_KEY and omit it
threshold: 0.5, // block at or above this probability (default 0.5)
},
});jev option | |
|---|---|
apiKey, baseURL, model | Connection. The key falls back to TYPESAFE_API_KEY, the URL to TYPESAFE_BASE_URL. |
threshold | Probability at or above which the message fails the rule. Default 0.5. |
question, criteria | Replace the default question and the descriptions of the yes and no outcomes. |
client | A ready JevProvider (or a stub in tests). When set, the connection options are ignored. |
Without a key the rule fails with a clear error instead of passing silently, and a response without a probability fails closed. The conversation payload is sent to TypeSafe's API, so check that is acceptable for your data before turning it on.

