ai-sdk-guardrails 5.0.2 → 5.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +185 -0
- package/dist/{chunk-VKJ5EAS7.js → chunk-CB2WX5S7.js} +0 -4
- package/dist/{chunk-CSUDFTRH.js → chunk-OP5XB2DJ.js} +1 -1
- package/dist/{chunk-ND2ICBTR.js → chunk-XWDH2NCM.js} +1 -1
- package/dist/{chunk-LVXHWHZC.js → chunk-ZZFNRQAT.js} +2 -2
- package/dist/guardrails/input.d.cts +1 -1
- package/dist/guardrails/input.d.ts +1 -1
- package/dist/guardrails/input.js +2 -2
- package/dist/guardrails/output.d.cts +1 -1
- package/dist/guardrails/output.d.ts +1 -1
- package/dist/guardrails/output.js +2 -2
- package/dist/guardrails/tools.d.cts +1 -1
- package/dist/guardrails/tools.d.ts +1 -1
- package/dist/guardrails/tools.js +3 -3
- package/dist/index.cjs +715 -6
- package/dist/index.d.cts +855 -11
- package/dist/index.d.ts +855 -11
- package/dist/index.js +705 -8
- package/dist/{types-CeZi2BBN.d.cts → types-WcM_8Gvq.d.cts} +17 -1
- package/dist/{types-CeZi2BBN.d.ts → types-WcM_8Gvq.d.ts} +17 -1
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -386,6 +386,191 @@ const agent = withAgentGuardrails(
|
|
|
386
386
|
const result = await agent.generate({ prompt: '...' });
|
|
387
387
|
```
|
|
388
388
|
|
|
389
|
+
## Advanced Stopping Mechanisms
|
|
390
|
+
|
|
391
|
+
Control exactly **when and how** guardrails stop execution with powerful, composable stopping mechanisms:
|
|
392
|
+
|
|
393
|
+
### 1. AbortSignal-Based Stopping
|
|
394
|
+
|
|
395
|
+
Clean, standard API for canceling AI operations:
|
|
396
|
+
|
|
397
|
+
```ts
|
|
398
|
+
import { createGuardrailAbortController } from 'ai-sdk-guardrails';
|
|
399
|
+
|
|
400
|
+
const { signal, abortOnViolation } = createGuardrailAbortController();
|
|
401
|
+
|
|
402
|
+
const model = withGuardrails(openai('gpt-4o'), {
|
|
403
|
+
outputGuardrails: [toxicityFilter()],
|
|
404
|
+
onOutputBlocked: abortOnViolation('critical'), // Abort on critical violations
|
|
405
|
+
});
|
|
406
|
+
|
|
407
|
+
// Signal will be aborted if critical violation detected
|
|
408
|
+
await streamText({ model, prompt: '...', abortSignal: signal });
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
**Features:**
|
|
412
|
+
|
|
413
|
+
- Standard AbortController API
|
|
414
|
+
- Severity-based abortion (`'low' | 'medium' | 'high' | 'critical'`)
|
|
415
|
+
- Custom abort conditions
|
|
416
|
+
- Manual abortion support
|
|
417
|
+
|
|
418
|
+
### 2. Stream Transform with Source-Level Stopping
|
|
419
|
+
|
|
420
|
+
Stop streaming at the **source** (most efficient):
|
|
421
|
+
|
|
422
|
+
```ts
|
|
423
|
+
import { createGuardrailStreamTransform } from 'ai-sdk-guardrails';
|
|
424
|
+
|
|
425
|
+
const result = streamText({
|
|
426
|
+
model,
|
|
427
|
+
prompt: 'Tell me a story',
|
|
428
|
+
experimental_transform: createGuardrailStreamTransform(
|
|
429
|
+
[toxicityFilter(), piiDetector()],
|
|
430
|
+
{
|
|
431
|
+
stopOnSeverity: 'high', // Stop on high/critical
|
|
432
|
+
checkInterval: 1, // Check every chunk
|
|
433
|
+
onViolation: (summary) => {
|
|
434
|
+
// Violation callback
|
|
435
|
+
console.log('Stopped:', summary);
|
|
436
|
+
},
|
|
437
|
+
},
|
|
438
|
+
),
|
|
439
|
+
});
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
**Modes:**
|
|
443
|
+
|
|
444
|
+
- `createGuardrailStreamTransform` - Progressive checking (each chunk)
|
|
445
|
+
- `createGuardrailStreamTransformBuffered` - Buffered checking (on flush)
|
|
446
|
+
|
|
447
|
+
### 3. Token-Level Control
|
|
448
|
+
|
|
449
|
+
Reduce overhead with smart token-based checking:
|
|
450
|
+
|
|
451
|
+
```ts
|
|
452
|
+
import {
|
|
453
|
+
createTokenBudgetTransform,
|
|
454
|
+
createTokenAwareGuardrailTransform,
|
|
455
|
+
} from 'ai-sdk-guardrails';
|
|
456
|
+
|
|
457
|
+
experimental_transform: [
|
|
458
|
+
// Hard token limit
|
|
459
|
+
createTokenBudgetTransform({
|
|
460
|
+
maxTokens: 1000,
|
|
461
|
+
onBudgetExceeded: (info) => console.log(info),
|
|
462
|
+
}),
|
|
463
|
+
|
|
464
|
+
// Check guardrails every N tokens (not every chunk!)
|
|
465
|
+
createTokenAwareGuardrailTransform([toxicityFilter()], {
|
|
466
|
+
checkEveryTokens: 50, // Check every 50 tokens
|
|
467
|
+
maxTokens: 1000, // Combined with budget
|
|
468
|
+
stopOnSeverity: 'high',
|
|
469
|
+
}),
|
|
470
|
+
];
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
**Benefits:**
|
|
474
|
+
|
|
475
|
+
- Reduce guardrail overhead by 80%+
|
|
476
|
+
- Cost control with token budgets
|
|
477
|
+
- Custom tokenizer support
|
|
478
|
+
|
|
479
|
+
### 4. Adaptive Multi-Step Execution
|
|
480
|
+
|
|
481
|
+
Self-correcting behavior across multi-step agent execution:
|
|
482
|
+
|
|
483
|
+
```ts
|
|
484
|
+
import {
|
|
485
|
+
createAdaptivePrepareStep,
|
|
486
|
+
type GuardrailViolation,
|
|
487
|
+
} from 'ai-sdk-guardrails';
|
|
488
|
+
|
|
489
|
+
const violations: GuardrailViolation[] = [];
|
|
490
|
+
|
|
491
|
+
const agent = new Agent({
|
|
492
|
+
model,
|
|
493
|
+
tools: { search: searchTool },
|
|
494
|
+
prepareStep: createAdaptivePrepareStep({
|
|
495
|
+
violations,
|
|
496
|
+
escalateAfter: 3, // Stop after 3 violations
|
|
497
|
+
strategy: (violations) => ({
|
|
498
|
+
temperature: Math.max(0.1, 0.7 - violations.length * 0.1),
|
|
499
|
+
system: `${violations.length} violations detected. Be careful.`,
|
|
500
|
+
}),
|
|
501
|
+
}),
|
|
502
|
+
});
|
|
503
|
+
|
|
504
|
+
// Track violations
|
|
505
|
+
withAgentGuardrails(agent, {
|
|
506
|
+
outputGuardrails: [toxicityFilter()],
|
|
507
|
+
onOutputBlocked: (summary, context, step) => {
|
|
508
|
+
violations.push({ step, summary });
|
|
509
|
+
},
|
|
510
|
+
});
|
|
511
|
+
```
|
|
512
|
+
|
|
513
|
+
**Features:**
|
|
514
|
+
|
|
515
|
+
- Progressive temperature reduction
|
|
516
|
+
- Custom adaptive strategies
|
|
517
|
+
- Escalation to auto-stop
|
|
518
|
+
- Lookback window configuration
|
|
519
|
+
|
|
520
|
+
### 5. Tool Execution Abortion
|
|
521
|
+
|
|
522
|
+
Prevent dangerous tool execution before or during execution:
|
|
523
|
+
|
|
524
|
+
```ts
|
|
525
|
+
import { wrapToolWithAbortion } from 'ai-sdk-guardrails';
|
|
526
|
+
|
|
527
|
+
const safeTool = wrapToolWithAbortion(
|
|
528
|
+
dangerousApiTool,
|
|
529
|
+
[urlValidator, paramValidator],
|
|
530
|
+
{
|
|
531
|
+
checkBefore: true, // Validate before execution
|
|
532
|
+
monitorDuring: true, // Monitor during execution
|
|
533
|
+
monitorInterval: 1000, // Check every second
|
|
534
|
+
checkInputDelta: true, // Monitor streaming inputs
|
|
535
|
+
abortOnSeverity: 'critical',
|
|
536
|
+
},
|
|
537
|
+
);
|
|
538
|
+
```
|
|
539
|
+
|
|
540
|
+
**Protection:**
|
|
541
|
+
|
|
542
|
+
- Pre-execution validation
|
|
543
|
+
- Real-time monitoring
|
|
544
|
+
- Streaming input checking
|
|
545
|
+
- Manual abortion control
|
|
546
|
+
|
|
547
|
+
### 6. Finish Reason & Metadata
|
|
548
|
+
|
|
549
|
+
Better observability with proper finish reasons and metadata:
|
|
550
|
+
|
|
551
|
+
```ts
|
|
552
|
+
import { createFinishReasonEnhancement } from 'ai-sdk-guardrails';
|
|
553
|
+
|
|
554
|
+
// Automatically set in middleware, or manually:
|
|
555
|
+
const enhanced = createFinishReasonEnhancement(summary, result);
|
|
556
|
+
|
|
557
|
+
console.log(enhanced.finishReason); // 'content_filter' for blocks
|
|
558
|
+
console.log(enhanced.providerMetadata.guardrails);
|
|
559
|
+
// {
|
|
560
|
+
// blocked: true,
|
|
561
|
+
// violations: [{ message: '...', severity: 'high', ... }],
|
|
562
|
+
// executionTime: 50,
|
|
563
|
+
// stats: { passed: 2, blocked: 1, failed: 0 }
|
|
564
|
+
// }
|
|
565
|
+
```
|
|
566
|
+
|
|
567
|
+
**Features:**
|
|
568
|
+
|
|
569
|
+
- Standard `content_filter` finish reason
|
|
570
|
+
- Structured violation metadata
|
|
571
|
+
- Execution statistics
|
|
572
|
+
- Custom metadata preservation
|
|
573
|
+
|
|
389
574
|
## MCP Security Guardrails (Advanced)
|
|
390
575
|
|
|
391
576
|
**Production-Ready**: Protect against the ["lethal trifecta" vulnerability](https://simonwillison.net/2025/Jun/16/the-lethal-trifecta/) when using Model Context Protocol (MCP) tools.
|
|
@@ -151,8 +151,6 @@ function extractErrorInfo(error) {
|
|
|
151
151
|
message: String(error)
|
|
152
152
|
};
|
|
153
153
|
}
|
|
154
|
-
var InputBlockedError = GuardrailsInputError;
|
|
155
|
-
var OutputBlockedError = GuardrailsOutputError;
|
|
156
154
|
|
|
157
155
|
// src/core.ts
|
|
158
156
|
function createInputGuardrail(name, description, execute) {
|
|
@@ -388,8 +386,6 @@ export {
|
|
|
388
386
|
MiddlewareError,
|
|
389
387
|
isGuardrailsError,
|
|
390
388
|
extractErrorInfo,
|
|
391
|
-
InputBlockedError,
|
|
392
|
-
OutputBlockedError,
|
|
393
389
|
createInputGuardrail,
|
|
394
390
|
createOutputGuardrail,
|
|
395
391
|
retry,
|
package/dist/guardrails/input.js
CHANGED
|
@@ -15,8 +15,8 @@ import {
|
|
|
15
15
|
promptInjectionDetector,
|
|
16
16
|
rateLimiting,
|
|
17
17
|
toxicityDetector
|
|
18
|
-
} from "../chunk-
|
|
19
|
-
import "../chunk-
|
|
18
|
+
} from "../chunk-OP5XB2DJ.js";
|
|
19
|
+
import "../chunk-CB2WX5S7.js";
|
|
20
20
|
export {
|
|
21
21
|
allowedToolsGuardrail,
|
|
22
22
|
blockedKeywords,
|
|
@@ -24,8 +24,8 @@ import {
|
|
|
24
24
|
tokenUsageLimit,
|
|
25
25
|
toxicityFilter,
|
|
26
26
|
unsafeContentDetector
|
|
27
|
-
} from "../chunk-
|
|
28
|
-
import "../chunk-
|
|
27
|
+
} from "../chunk-XWDH2NCM.js";
|
|
28
|
+
import "../chunk-CB2WX5S7.js";
|
|
29
29
|
export {
|
|
30
30
|
biasDetector,
|
|
31
31
|
blockedContent,
|
package/dist/guardrails/tools.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
expectedToolUse,
|
|
3
3
|
toolEgressPolicy
|
|
4
|
-
} from "../chunk-
|
|
5
|
-
import "../chunk-
|
|
6
|
-
import "../chunk-
|
|
4
|
+
} from "../chunk-ZZFNRQAT.js";
|
|
5
|
+
import "../chunk-XWDH2NCM.js";
|
|
6
|
+
import "../chunk-CB2WX5S7.js";
|
|
7
7
|
export {
|
|
8
8
|
expectedToolUse,
|
|
9
9
|
toolEgressPolicy
|