Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ jobs:
steps:
- uses: actions/checkout@v7

- uses: actions/setup-node@v6
with:
node-version: 24

- uses: oven-sh/setup-bun@v2
with:
bun-version: latest
Expand All @@ -31,6 +35,9 @@ jobs:
- name: Build
run: bun run build

- name: Match npm publishing environment
run: npm install --global npm@latest

- name: Validate package contents
run: npm pack --dry-run

Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Changelog

## [2.1.1] - 2026-10-04

- Fixed release verification for npm 12's package metadata format while retaining compatibility with earlier npm versions. Packed package names and versions are checked against the manifest, and publish dry runs still create and install real test artifacts.
- First npm release of the AI SDK inspection tool. The 2.1.0 publication stopped during verification before uploading a package; this version includes all changes below.

## [2.1.0] - 2026-10-04

- Added `shieldCheck` at `@zeroleaks/shield/ai-sdk/tools` for AI SDK 5, 6, and 7. It uses local detection by default, supports explicit hosted detection and async local detectors, and returns detection metadata without repeating input text or matching patterns.
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ Pass `detect: shield.options()` to the other wrappers in the same way. Omitting

## AI SDK inspection tool

Shield 2.1.0 adds an inspection tool for AI SDK 5, 6, and 7:
Shield 2.1.1 adds an inspection tool for AI SDK 5, 6, and 7:

```typescript
import { shieldCheck } from "@zeroleaks/shield/ai-sdk/tools";
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@zeroleaks/shield",
"version": "2.1.0",
"version": "2.1.1",
"description": "Runtime security for LLM apps and agents: prompt injection detection for user input and tool results, and leak, credential, PII, and exfiltration checks on model output",
"main": "dist/index.js",
"module": "dist/index.mjs",
Expand Down
13 changes: 11 additions & 2 deletions registry/README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# AI SDK registry submission

`entry.ts` contains the proposed object for `vercel/ai`'s `content/tools-registry/registry.ts`. `issue.md` is a ready-to-submit documentation-addition request. Neither file submits anything upstream.
`entry.ts` contains the proposed object for `vercel/ai`'s `content/tools-registry/registry.ts`. `vercel-ai.patch` adds that object to the registry; it was formatted and type-checked against upstream commit `7c41e416b6d5ca630cc5f72b330e6c4743f82265`. `pr.md` contains the PR title and description, and `issue.md` is an optional documentation-addition request. These files do not submit anything upstream.

The public integration guide is `https://zeroleaks.ai/docs/shield-sdk/providers/ai-sdk-tools`. Its main example must match `entry.ts` exactly. The ZeroLeaks app's package verifier checks that parity; Shield's isolated package verifier type-checks and executes the registry snippet.

Before submitting, confirm that npm serves `@zeroleaks/shield@2.1.0` and the integration guide is live. The source repository, README, public docs, and published package must describe the same exports and supported SDK versions.
Before submitting, confirm that npm serves `@zeroleaks/shield@2.1.1` and the integration guide is live. The source repository, README, public docs, and published package must describe the same exports and supported SDK versions.

Run the release checks from the Shield repository:

Expand All @@ -21,3 +21,12 @@ The package verifier uses isolated npm installations and mocked model/API respon
The published entry should keep local detection as the default example and link directly to the AI SDK tool guide. An optional ZeroLeaks API key is documented on that page; it is not a prerequisite for the local tool. The model example requires `AI_GATEWAY_API_KEY`.

Follow the current [contribution guide](https://github.com/vercel/ai/blob/main/contributing/add-new-tool-to-registry.md). An issue-first documentation request has recent precedent, but may cause their automation to open a PR. Hold both the issue and PR until submission is authorized.

Once the prerequisites above are live and submission is authorized, apply the patch in a current `vercel/ai` checkout:

```bash
git apply --check /path/to/shield/registry/vercel-ai.patch
git apply /path/to/shield/registry/vercel-ai.patch
```

Rebase the entry if upstream has changed, then use the repository's current formatting and validation commands before submitting.
2 changes: 1 addition & 1 deletion registry/issue.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ The package also provides `shieldLanguageModelMiddleware` to check user messages
- Canonical repository: https://github.com/ZeroLeaks/shield
- AI SDK integration guide: https://zeroleaks.ai/docs/shield-sdk/providers/ai-sdk-tools
- Website: https://zeroleaks.ai/shield
- Version prepared and tested: `@zeroleaks/shield@2.1.0`
- Version prepared and tested: `@zeroleaks/shield@2.1.1`
- Current SDK tested: `ai@7.0.127`
- Additional supported SDKs tested: `ai@5.0.267`, `ai@6.0.292`

Expand Down
13 changes: 13 additions & 0 deletions registry/pr.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Title: feat(tools-registry): add zeroleaks-shield

Adds [ZeroLeaks Shield](https://zeroleaks.ai/shield) to the tools registry with `shieldCheck` from [`@zeroleaks/shield`](https://www.npmjs.com/package/@zeroleaks/shield). It inspects text for prompt injection and jailbreaks locally by default, with hosted detection available on explicit opt-in. The example combines the tool with language model middleware that blocks detected injections before model calls. Model-invoked inspection is advisory; detection results do not authorize agent actions.

The entry links directly to the [AI SDK integration guide](https://zeroleaks.ai/docs/shield-sdk/providers/ai-sdk-tools). Its example uses current AI SDK imports, AI Gateway, and `isStepCount`. Local detection needs no ZeroLeaks key; the Gateway model needs `AI_GATEWAY_API_KEY`.

Validation for Shield 2.1.1:

- 1,263 passing tests, with two optional model tests skipped.
- Isolated packed-package consumers on AI SDK 5.0.267, 6.0.292, and 7.0.127, covering generation, streaming, malformed inputs, hosted errors, and middleware blocking.
- Strict ESM and CommonJS consumer types; root and middleware imports without optional provider SDKs installed.
- Exact registry example type-checked and executed against a mocked Gateway for a two-step tool roundtrip, without live inference calls.
- Registry entry formatted and type-checked against the upstream `Tool` interface.
45 changes: 45 additions & 0 deletions registry/vercel-ai.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
diff --git a/content/tools-registry/registry.ts b/content/tools-registry/registry.ts
index 7ba3c15..5c80363 100644
--- a/content/tools-registry/registry.ts
+++ b/content/tools-registry/registry.ts
@@ -689,4 +689,40 @@ console.log(text);`,
websiteUrl: 'https://pushary.com/human-in-the-loop',
npmUrl: 'https://www.npmjs.com/package/@pushary/ai-sdk',
},
+ {
+ slug: 'zeroleaks-shield',
+ name: 'ZeroLeaks Shield',
+ description:
+ 'Prompt injection and jailbreak detection for user messages, retrieved documents, web pages, and tool results. Inspect text with shieldCheck locally without an API key, or opt into the hosted Shield API. Pair it with Shield language model middleware to block detected injections before model calls.',
+ packageName: '@zeroleaks/shield',
+ tags: ['security', 'guardrails', 'prompt-injection', 'jailbreak'],
+ installCommand: {
+ pnpm: 'pnpm add @zeroleaks/shield ai zod',
+ npm: 'npm install @zeroleaks/shield ai zod',
+ yarn: 'yarn add @zeroleaks/shield ai zod',
+ bun: 'bun add @zeroleaks/shield ai zod',
+ },
+ codeExample: `import { gateway, generateText, isStepCount, wrapLanguageModel } from 'ai';
+import { shieldLanguageModelMiddleware } from '@zeroleaks/shield/ai-sdk';
+import { shieldCheck } from '@zeroleaks/shield/ai-sdk/tools';
+
+const model = wrapLanguageModel({
+ model: gateway('openai/gpt-5-mini'),
+ middleware: shieldLanguageModelMiddleware(),
+});
+
+const { text } = await generateText({
+ model,
+ tools: { shieldCheck: shieldCheck() },
+ stopWhen: isStepCount(3),
+ prompt:
+ 'Check this support note with shieldCheck, then summarize it: Our support desk opens at nine on Monday.',
+});
+
+console.info(text);`,
+ docsUrl: 'https://zeroleaks.ai/docs/shield-sdk/providers/ai-sdk-tools',
+ apiKeyUrl: 'https://zeroleaks.ai/dashboard/shield',
+ websiteUrl: 'https://zeroleaks.ai/shield',
+ npmUrl: 'https://www.npmjs.com/package/@zeroleaks/shield',
+ },
];
23 changes: 18 additions & 5 deletions scripts/verify-package.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,20 @@ import { join, resolve } from "node:path";
import { promisify } from "node:util";
import { shieldRegistryEntry } from "../registry/entry";

interface PackMetadata {
filename: string;
name: string;
version: string;
files: { path: string }[];
}

const execute = promisify(execFile);
const directory = resolve(import.meta.dirname, "..");
const temporary = await mkdtemp(join(tmpdir(), "shield-package-"));
const manifest = JSON.parse(
await readFile(join(directory, "package.json"), "utf8")
) as {
name: string;
version: string;
exports: Record<string, Record<"types" | "import" | "require", string>>;
};
Expand All @@ -24,6 +32,8 @@ async function run(
): Promise<string> {
const { stdout } = await execute(command, args, {
cwd,
// npm publish --dry-run must still pack and install real test artifacts.
env: { ...process.env, npm_config_dry_run: "false" },
timeout: 120_000,
maxBuffer: 8 * 1024 * 1024,
});
Expand Down Expand Up @@ -138,19 +148,22 @@ process.on('exit', () => assert.equal(calls, 2));
`;

try {
const packed = JSON.parse(
const packOutput = JSON.parse(
await run(
"npm",
["pack", "--json", "--pack-destination", temporary],
directory
)
) as {
filename: string;
files: { path: string }[];
}[];
) as PackMetadata[] | Record<string, PackMetadata>;
// npm 12 keys pack metadata by package name; earlier versions return an array.
const packed = Array.isArray(packOutput)
? packOutput
: Object.values(packOutput);
assert.equal(packed.length, 1);
const artifact = packed[0];
assert.ok(artifact);
assert.equal(artifact.name, manifest.name);
assert.equal(artifact.version, manifest.version);
const files = new Set(artifact.files.map((file) => file.path));
for (const [name, targets] of Object.entries(manifest.exports)) {
for (const target of Object.values(targets)) {
Expand Down
Loading