ai-sdk-guardrails 5.0.2 → 5.2.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 +221 -36
- package/dist/{chunk-CSUDFTRH.js → chunk-2QL3CFHU.js} +116 -14
- package/dist/{chunk-VKJ5EAS7.js → chunk-CB2WX5S7.js} +0 -4
- package/dist/{chunk-ND2ICBTR.js → chunk-RNMFT62H.js} +239 -23
- package/dist/{chunk-LVXHWHZC.js → chunk-XMHEI3T4.js} +57 -9
- package/dist/guardrails/input.cjs +115 -13
- 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.cjs +238 -22
- 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.cjs +81 -11
- package/dist/guardrails/tools.d.cts +54 -3
- package/dist/guardrails/tools.d.ts +54 -3
- package/dist/guardrails/tools.js +3 -3
- package/dist/index.cjs +2250 -400
- package/dist/index.d.cts +1134 -116
- package/dist/index.d.ts +1134 -116
- package/dist/index.js +1806 -357
- package/dist/{types-CeZi2BBN.d.cts → types-bXg_qgtZ.d.cts} +245 -68
- package/dist/{types-CeZi2BBN.d.ts → types-bXg_qgtZ.d.ts} +245 -68
- package/package.json +17 -29
package/README.md
CHANGED
|
@@ -7,10 +7,10 @@ Add guardrails to your AI applications in one line of code. Block PII, prevent p
|
|
|
7
7
|
[](https://www.npmjs.com/package/ai-sdk-guardrails)
|
|
8
8
|
[](https://www.npmjs.com/package/ai-sdk-guardrails)
|
|
9
9
|
[](https://bundlephobia.com/package/ai-sdk-guardrails)
|
|
10
|
-
[](
|
|
10
|
+
[](../../LICENSE)
|
|
11
11
|

|
|
12
12
|
|
|
13
|
-

|
|
14
14
|
|
|
15
15
|
## Drop-in Guardrails for any AI model
|
|
16
16
|
|
|
@@ -39,7 +39,7 @@ npm install ai-sdk-guardrails
|
|
|
39
39
|
|
|
40
40
|
**Don't want to write code?** Use our visual wizard to configure guardrails:
|
|
41
41
|
|
|
42
|
-
1. **Open the wizard**: [wizard-prototype/index.html](
|
|
42
|
+
1. **Open the wizard**: [wizard-prototype/index.html](../../wizard-prototype/index.html)
|
|
43
43
|
2. **Choose your use case**: Content moderation, data protection, quality assurance, or security
|
|
44
44
|
3. **Select guardrails**: Pick from 40+ built-in guardrails
|
|
45
45
|
4. **Configure settings**: Adjust thresholds and parameters with sliders and toggles
|
|
@@ -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.
|
|
@@ -487,9 +672,9 @@ const model = withGuardrails(openai('gpt-4o'), {
|
|
|
487
672
|
|
|
488
673
|
See complete examples:
|
|
489
674
|
|
|
490
|
-
- [Production MCP Configuration](
|
|
491
|
-
- [MCP Security Test Suite](
|
|
492
|
-
- [Enhanced Security Testing](
|
|
675
|
+
- [Production MCP Configuration](../examples/44-production-mcp-config.ts)
|
|
676
|
+
- [MCP Security Test Suite](../examples/41-mcp-security-test.ts)
|
|
677
|
+
- [Enhanced Security Testing](../examples/43-enhanced-mcp-security-test.ts)
|
|
493
678
|
|
|
494
679
|
## Error Handling
|
|
495
680
|
|
|
@@ -559,50 +744,50 @@ See source for all built-in guardrails:
|
|
|
559
744
|
|
|
560
745
|
## Examples
|
|
561
746
|
|
|
562
|
-
Browse 48+ runnable examples: [examples/README.md](
|
|
747
|
+
Browse 48+ runnable examples: [examples/README.md](../examples/README.md) |
|
|
563
748
|
|
|
564
749
|
### Quick Starts
|
|
565
750
|
|
|
566
|
-
| Example | Description | File
|
|
567
|
-
| -------------------------- | ------------------------------- |
|
|
568
|
-
| Simple combined protection | Minimal input and output setup | [07a-simple-combined-protection.ts](
|
|
569
|
-
| Auto retry on output | Retry until output meets a rule | [32-auto-retry-output.ts](
|
|
570
|
-
| LLM judge auto-retry | Judge feedback drives retry | [35-judge-auto-retry.ts](
|
|
571
|
-
| Weather assistant | End-to-end input/output + retry | [33-blog-post-weather-assistant.ts](
|
|
751
|
+
| Example | Description | File |
|
|
752
|
+
| -------------------------- | ------------------------------- | ---------------------------------------------------------------------------------- |
|
|
753
|
+
| Simple combined protection | Minimal input and output setup | [07a-simple-combined-protection.ts](../examples/07a-simple-combined-protection.ts) |
|
|
754
|
+
| Auto retry on output | Retry until output meets a rule | [32-auto-retry-output.ts](../examples/32-auto-retry-output.ts) |
|
|
755
|
+
| LLM judge auto-retry | Judge feedback drives retry | [35-judge-auto-retry.ts](../examples/35-judge-auto-retry.ts) |
|
|
756
|
+
| Weather assistant | End-to-end input/output + retry | [33-blog-post-weather-assistant.ts](../examples/33-blog-post-weather-assistant.ts) |
|
|
572
757
|
|
|
573
758
|
### Input Safety
|
|
574
759
|
|
|
575
|
-
| Example | Description | File
|
|
576
|
-
| ------------------ | ----------------------------------- |
|
|
577
|
-
| Input length limit | Enforce max input length | [01-input-length-limit.ts](
|
|
578
|
-
| Blocked keywords | Block specific terms | [02-blocked-keywords.ts](
|
|
579
|
-
| PII detection | Detect PII before calling the model | [03-pii-detection.ts](
|
|
580
|
-
| Rate limiting | Simple per-user rate limit | [13-rate-limiting.ts](
|
|
760
|
+
| Example | Description | File |
|
|
761
|
+
| ------------------ | ----------------------------------- | ---------------------------------------------------------------- |
|
|
762
|
+
| Input length limit | Enforce max input length | [01-input-length-limit.ts](../examples/01-input-length-limit.ts) |
|
|
763
|
+
| Blocked keywords | Block specific terms | [02-blocked-keywords.ts](../examples/02-blocked-keywords.ts) |
|
|
764
|
+
| PII detection | Detect PII before calling the model | [03-pii-detection.ts](../examples/03-pii-detection.ts) |
|
|
765
|
+
| Rate limiting | Simple per-user rate limit | [13-rate-limiting.ts](../examples/13-rate-limiting.ts) |
|
|
581
766
|
|
|
582
767
|
### Output Safety
|
|
583
768
|
|
|
584
|
-
| Example | Description | File
|
|
585
|
-
| ----------------------- | ----------------------------------- |
|
|
586
|
-
| Output length check | Require min/max output length | [04-output-length-check.ts](
|
|
587
|
-
| Sensitive output filter | Filter secrets and PII in responses | [05-sensitive-output-filter.ts](
|
|
588
|
-
| Hallucination detection | Flag uncertain factual claims | [19-hallucination-detection.ts](
|
|
769
|
+
| Example | Description | File |
|
|
770
|
+
| ----------------------- | ----------------------------------- | -------------------------------------------------------------------------- |
|
|
771
|
+
| Output length check | Require min/max output length | [04-output-length-check.ts](../examples/04-output-length-check.ts) |
|
|
772
|
+
| Sensitive output filter | Filter secrets and PII in responses | [05-sensitive-output-filter.ts](../examples/05-sensitive-output-filter.ts) |
|
|
773
|
+
| Hallucination detection | Flag uncertain factual claims | [19-hallucination-detection.ts](../examples/19-hallucination-detection.ts) |
|
|
589
774
|
|
|
590
775
|
### Streaming
|
|
591
776
|
|
|
592
|
-
| Example | Description | File
|
|
593
|
-
| ----------------- | ---------------------------------- |
|
|
594
|
-
| Streaming limits | Apply limits in buffered streaming | [11-streaming-limits.ts](
|
|
595
|
-
| Streaming quality | Quality checks with streaming | [12-streaming-quality.ts](
|
|
596
|
-
| Early termination | Stop streams early when blocked | [28-streaming-early-termination.ts](
|
|
777
|
+
| Example | Description | File |
|
|
778
|
+
| ----------------- | ---------------------------------- | ---------------------------------------------------------------------------------- |
|
|
779
|
+
| Streaming limits | Apply limits in buffered streaming | [11-streaming-limits.ts](../examples/11-streaming-limits.ts) |
|
|
780
|
+
| Streaming quality | Quality checks with streaming | [12-streaming-quality.ts](../examples/12-streaming-quality.ts) |
|
|
781
|
+
| Early termination | Stop streams early when blocked | [28-streaming-early-termination.ts](../examples/28-streaming-early-termination.ts) |
|
|
597
782
|
|
|
598
783
|
### Advanced
|
|
599
784
|
|
|
600
|
-
| Example | Description | File
|
|
601
|
-
| -------------------------- | ----------------------------- |
|
|
602
|
-
| Simple quality judge | Cheaper model judges quality | [15a-simple-quality-judge.ts](
|
|
603
|
-
| Secret leakage scan | Scan responses for secrets | [18-secret-leakage-scan.ts](
|
|
604
|
-
| SQL code safety | Basic SQL safety checks | [24-sql-code-safety.ts](
|
|
605
|
-
| Role hierarchy enforcement | Enforce role rules in prompts | [23-role-hierarchy-enforcement.ts](
|
|
785
|
+
| Example | Description | File |
|
|
786
|
+
| -------------------------- | ----------------------------- | -------------------------------------------------------------------------------- |
|
|
787
|
+
| Simple quality judge | Cheaper model judges quality | [15a-simple-quality-judge.ts](../examples/15a-simple-quality-judge.ts) |
|
|
788
|
+
| Secret leakage scan | Scan responses for secrets | [18-secret-leakage-scan.ts](../examples/18-secret-leakage-scan.ts) |
|
|
789
|
+
| SQL code safety | Basic SQL safety checks | [24-sql-code-safety.ts](../examples/24-sql-code-safety.ts) |
|
|
790
|
+
| Role hierarchy enforcement | Enforce role rules in prompts | [23-role-hierarchy-enforcement.ts](../examples/23-role-hierarchy-enforcement.ts) |
|
|
606
791
|
|
|
607
792
|
## Migration from v3.x
|
|
608
793
|
|
|
@@ -652,4 +837,4 @@ Issues and PRs are welcome.
|
|
|
652
837
|
|
|
653
838
|
## License
|
|
654
839
|
|
|
655
|
-
MIT © Jag Reehal. See [LICENSE](
|
|
840
|
+
MIT © Jag Reehal. See [LICENSE](../../LICENSE) for details.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createInputGuardrail
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-CB2WX5S7.js";
|
|
4
4
|
|
|
5
5
|
// src/guardrails/input.ts
|
|
6
6
|
var SEVERITY_LEVELS = {
|
|
@@ -141,7 +141,14 @@ var inputLengthLimit = (options) => {
|
|
|
141
141
|
tripwireTriggered: currentLength > opts.maxLength,
|
|
142
142
|
message: currentLength > opts.maxLength ? `Input ${unit} count ${currentLength} exceeds limit of ${opts.maxLength}` : void 0,
|
|
143
143
|
severity: opts.severity,
|
|
144
|
-
metadata
|
|
144
|
+
metadata,
|
|
145
|
+
info: {
|
|
146
|
+
guardrailName: "input-length-limit",
|
|
147
|
+
currentLength,
|
|
148
|
+
maxLength: opts.maxLength,
|
|
149
|
+
countMethod: opts.countMethod,
|
|
150
|
+
unit
|
|
151
|
+
}
|
|
145
152
|
};
|
|
146
153
|
}
|
|
147
154
|
);
|
|
@@ -179,7 +186,12 @@ var blockedWords = (options) => {
|
|
|
179
186
|
metadata: createStandardMetadata("GR-IN-002", context, {
|
|
180
187
|
allowlistMatched: true,
|
|
181
188
|
blockedWords: opts.words
|
|
182
|
-
})
|
|
189
|
+
}),
|
|
190
|
+
info: {
|
|
191
|
+
guardrailName: "blocked-words",
|
|
192
|
+
allowlistMatched: true,
|
|
193
|
+
blockedWords: opts.words
|
|
194
|
+
}
|
|
183
195
|
};
|
|
184
196
|
}
|
|
185
197
|
}
|
|
@@ -196,7 +208,13 @@ var blockedWords = (options) => {
|
|
|
196
208
|
tripwireTriggered: !!blockedWord,
|
|
197
209
|
message: blockedWord ? `Blocked word detected: ${blockedWord.word}` : void 0,
|
|
198
210
|
severity: opts.severity,
|
|
199
|
-
metadata
|
|
211
|
+
metadata,
|
|
212
|
+
info: {
|
|
213
|
+
guardrailName: "blocked-words",
|
|
214
|
+
blockedWord: blockedWord?.word,
|
|
215
|
+
allWords: opts.words,
|
|
216
|
+
allowlist: opts.allowlist
|
|
217
|
+
}
|
|
200
218
|
};
|
|
201
219
|
}
|
|
202
220
|
);
|
|
@@ -278,7 +296,14 @@ var rateLimiting = (options) => {
|
|
|
278
296
|
...metadata,
|
|
279
297
|
...opts.includeServerHints && { serverHints }
|
|
280
298
|
},
|
|
281
|
-
suggestion: isRateLimited ? `Please wait ${Math.ceil(recommendedBackoff / 1e3)} seconds before making another request` : void 0
|
|
299
|
+
suggestion: isRateLimited ? `Please wait ${Math.ceil(recommendedBackoff / 1e3)} seconds before making another request` : void 0,
|
|
300
|
+
info: {
|
|
301
|
+
guardrailName: "rate-limiting",
|
|
302
|
+
currentCount: current.count,
|
|
303
|
+
maxRequests: opts.maxRequestsPerMinute,
|
|
304
|
+
isRateLimited,
|
|
305
|
+
timeUntilReset
|
|
306
|
+
}
|
|
282
307
|
};
|
|
283
308
|
}
|
|
284
309
|
);
|
|
@@ -352,7 +377,13 @@ var profanityFilter = (options = {}) => {
|
|
|
352
377
|
message: detectedProfanity ? `Profanity detected (${detectedProfanity.category}): ${detectedProfanity.word}` : void 0,
|
|
353
378
|
severity: detectedProfanity?.severity || SEVERITY_LEVELS.HIGH,
|
|
354
379
|
metadata,
|
|
355
|
-
suggestion: "Please use respectful and appropriate language"
|
|
380
|
+
suggestion: "Please use respectful and appropriate language",
|
|
381
|
+
info: {
|
|
382
|
+
guardrailName: "profanity-filter",
|
|
383
|
+
profaneWord: detectedProfanity?.word,
|
|
384
|
+
category: detectedProfanity?.category,
|
|
385
|
+
locale: opts.locale
|
|
386
|
+
}
|
|
356
387
|
};
|
|
357
388
|
}
|
|
358
389
|
);
|
|
@@ -394,7 +425,12 @@ var customValidation = (options) => {
|
|
|
394
425
|
tripwireTriggered: !isValid,
|
|
395
426
|
message: isValid ? void 0 : opts.message || `Custom validation failed: ${reasonCode || "unknown reason"}`,
|
|
396
427
|
severity: opts.severity,
|
|
397
|
-
metadata
|
|
428
|
+
metadata,
|
|
429
|
+
info: {
|
|
430
|
+
guardrailName: opts.name,
|
|
431
|
+
isValid,
|
|
432
|
+
reasonCode
|
|
433
|
+
}
|
|
398
434
|
};
|
|
399
435
|
});
|
|
400
436
|
};
|
|
@@ -537,7 +573,13 @@ var promptInjectionDetector = (options = {}) => {
|
|
|
537
573
|
message: confidence > threshold ? `Potential prompt injection detected (confidence: ${(confidence * 100).toFixed(1)}%): ${detectedPatterns.length} suspicious patterns found` : void 0,
|
|
538
574
|
severity: confidence > 0.8 ? SEVERITY_LEVELS.CRITICAL : SEVERITY_LEVELS.HIGH,
|
|
539
575
|
metadata,
|
|
540
|
-
suggestion: "Please rephrase your request without system instructions or role-playing elements"
|
|
576
|
+
suggestion: "Please rephrase your request without system instructions or role-playing elements",
|
|
577
|
+
info: {
|
|
578
|
+
guardrailName: "prompt-injection-detector",
|
|
579
|
+
confidence,
|
|
580
|
+
threshold,
|
|
581
|
+
detectedPatternsCount: detectedPatterns.length
|
|
582
|
+
}
|
|
541
583
|
};
|
|
542
584
|
}
|
|
543
585
|
);
|
|
@@ -622,7 +664,12 @@ var piiDetector = () => createInputGuardrail(
|
|
|
622
664
|
message: detectedPII.length > 0 ? `PII detected: ${detectedPII.map((pii) => `${pii.type} (${pii.matches.length})`).join(", ")}` : void 0,
|
|
623
665
|
severity: SEVERITY_LEVELS.CRITICAL,
|
|
624
666
|
metadata,
|
|
625
|
-
suggestion: "Please remove any personal information (emails, phone numbers, SSNs, etc.) from your input"
|
|
667
|
+
suggestion: "Please remove any personal information (emails, phone numbers, SSNs, etc.) from your input",
|
|
668
|
+
info: {
|
|
669
|
+
guardrailName: "pii-detector",
|
|
670
|
+
piiTypes: detectedPII.map((pii) => pii.type),
|
|
671
|
+
totalMatches
|
|
672
|
+
}
|
|
626
673
|
};
|
|
627
674
|
}
|
|
628
675
|
);
|
|
@@ -658,7 +705,14 @@ var toxicityDetector = (threshold = 0.7) => createInputGuardrail(
|
|
|
658
705
|
detectedWords,
|
|
659
706
|
textLength: allText.length
|
|
660
707
|
},
|
|
661
|
-
suggestion: "Please use respectful and constructive language"
|
|
708
|
+
suggestion: "Please use respectful and constructive language",
|
|
709
|
+
info: {
|
|
710
|
+
guardrailName: "toxicity-detector",
|
|
711
|
+
toxicityScore,
|
|
712
|
+
threshold,
|
|
713
|
+
detectedWords,
|
|
714
|
+
textLength: allText.length
|
|
715
|
+
}
|
|
662
716
|
};
|
|
663
717
|
}
|
|
664
718
|
);
|
|
@@ -673,7 +727,12 @@ var mathHomeworkDetector = (options = {}) => {
|
|
|
673
727
|
return createInputGuardrail(
|
|
674
728
|
"math-homework-detector",
|
|
675
729
|
"Math homework detection (disabled)",
|
|
676
|
-
() => ({
|
|
730
|
+
() => ({
|
|
731
|
+
tripwireTriggered: false,
|
|
732
|
+
info: {
|
|
733
|
+
guardrailName: "math-homework-detector"
|
|
734
|
+
}
|
|
735
|
+
})
|
|
677
736
|
);
|
|
678
737
|
}
|
|
679
738
|
const mathKeywords = [
|
|
@@ -720,7 +779,13 @@ var mathHomeworkDetector = (options = {}) => {
|
|
|
720
779
|
educationalContext: hasEducationalContext,
|
|
721
780
|
allowedContext: hasAllowedContext,
|
|
722
781
|
policy: "educational-use-allowed"
|
|
723
|
-
})
|
|
782
|
+
}),
|
|
783
|
+
info: {
|
|
784
|
+
guardrailName: "math-homework-detector",
|
|
785
|
+
educationalContext: hasEducationalContext,
|
|
786
|
+
allowedContext: hasAllowedContext,
|
|
787
|
+
policy: "educational-use-allowed"
|
|
788
|
+
}
|
|
724
789
|
};
|
|
725
790
|
}
|
|
726
791
|
const keywordMatches = mathKeywords.filter(
|
|
@@ -742,6 +807,13 @@ var mathHomeworkDetector = (options = {}) => {
|
|
|
742
807
|
message: isMathHomework ? "Math homework request detected" : void 0,
|
|
743
808
|
severity,
|
|
744
809
|
metadata,
|
|
810
|
+
info: {
|
|
811
|
+
guardrailName: "math-homework-detector",
|
|
812
|
+
isMathHomework,
|
|
813
|
+
keywordMatches: keywordMatches.length,
|
|
814
|
+
patternMatches: patternMatches.length,
|
|
815
|
+
strictMode
|
|
816
|
+
},
|
|
745
817
|
suggestion: "Try asking about learning concepts instead of solving specific problems"
|
|
746
818
|
};
|
|
747
819
|
}
|
|
@@ -844,7 +916,12 @@ var codeGenerationLimiter = (options = {}) => {
|
|
|
844
916
|
metadata: createStandardMetadata("GR-IN-008", context, {
|
|
845
917
|
hasCodeRequest: false,
|
|
846
918
|
mode: opts.mode
|
|
847
|
-
})
|
|
919
|
+
}),
|
|
920
|
+
info: {
|
|
921
|
+
guardrailName: "code-generation-limiter",
|
|
922
|
+
hasCodeRequest: false,
|
|
923
|
+
mode: opts.mode
|
|
924
|
+
}
|
|
848
925
|
};
|
|
849
926
|
}
|
|
850
927
|
const detectedLanguages = [];
|
|
@@ -880,6 +957,13 @@ var codeGenerationLimiter = (options = {}) => {
|
|
|
880
957
|
message: isBlocked ? `Code generation blocked for language(s): ${blockedLanguages.join(", ")}` : void 0,
|
|
881
958
|
severity: opts.severity,
|
|
882
959
|
metadata,
|
|
960
|
+
info: {
|
|
961
|
+
guardrailName: "code-generation-blocker",
|
|
962
|
+
isBlocked,
|
|
963
|
+
detectedLanguages: uniqueLanguages,
|
|
964
|
+
blockedLanguages,
|
|
965
|
+
mode: opts.mode
|
|
966
|
+
},
|
|
883
967
|
suggestion: opts.mode === "deny" ? `Please avoid requesting code in these languages: ${opts.deniedLanguages?.join(", ")}` : `Please request code only in allowed languages: ${opts.allowedLanguages?.join(", ")}`
|
|
884
968
|
};
|
|
885
969
|
}
|
|
@@ -990,6 +1074,11 @@ var allowedToolsGuardrail = (options) => {
|
|
|
990
1074
|
allowedTools,
|
|
991
1075
|
deniedTools,
|
|
992
1076
|
detectionMethod: "none"
|
|
1077
|
+
},
|
|
1078
|
+
info: {
|
|
1079
|
+
guardrailName: "allowed-tools-guardrail",
|
|
1080
|
+
detectedTools: [],
|
|
1081
|
+
detectionMethod: "none"
|
|
993
1082
|
}
|
|
994
1083
|
};
|
|
995
1084
|
}
|
|
@@ -1029,7 +1118,15 @@ var allowedToolsGuardrail = (options) => {
|
|
|
1029
1118
|
naturalLanguageTools,
|
|
1030
1119
|
textLength: allText.length
|
|
1031
1120
|
},
|
|
1032
|
-
suggestion: "Remove unauthorized tool calls or update the allowed tools configuration"
|
|
1121
|
+
suggestion: "Remove unauthorized tool calls or update the allowed tools configuration",
|
|
1122
|
+
info: {
|
|
1123
|
+
guardrailName: "allowed-tools-guardrail",
|
|
1124
|
+
detectedTools: allDetectedTools,
|
|
1125
|
+
blockedTools,
|
|
1126
|
+
violations,
|
|
1127
|
+
allowedTools,
|
|
1128
|
+
deniedTools
|
|
1129
|
+
}
|
|
1033
1130
|
};
|
|
1034
1131
|
}
|
|
1035
1132
|
return {
|
|
@@ -1041,6 +1138,11 @@ var allowedToolsGuardrail = (options) => {
|
|
|
1041
1138
|
deniedTools,
|
|
1042
1139
|
contextToolCalls,
|
|
1043
1140
|
naturalLanguageTools
|
|
1141
|
+
},
|
|
1142
|
+
info: {
|
|
1143
|
+
guardrailName: "allowed-tools-guardrail",
|
|
1144
|
+
detectedTools: allDetectedTools,
|
|
1145
|
+
allToolsAllowed: true
|
|
1044
1146
|
}
|
|
1045
1147
|
};
|
|
1046
1148
|
}
|
|
@@ -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,
|