ai-sdk-guardrails 5.1.0 → 5.3.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 CHANGED
@@ -7,10 +7,10 @@ Add guardrails to your AI applications in one line of code. Block PII, prevent p
7
7
  [![npm version](https://img.shields.io/npm/v/ai-sdk-guardrails.svg?logo=npm&label=npm)](https://www.npmjs.com/package/ai-sdk-guardrails)
8
8
  [![downloads](https://img.shields.io/npm/dw/ai-sdk-guardrails.svg?label=downloads)](https://www.npmjs.com/package/ai-sdk-guardrails)
9
9
  [![bundle size](https://img.shields.io/bundlephobia/minzip/ai-sdk-guardrails.svg?label=minzipped)](https://bundlephobia.com/package/ai-sdk-guardrails)
10
- [![license](https://img.shields.io/npm/l/ai-sdk-guardrails.svg?label=license)](./LICENSE)
10
+ [![license](https://img.shields.io/npm/l/ai-sdk-guardrails.svg?label=license)](../../LICENSE)
11
11
  ![types](https://img.shields.io/badge/TypeScript-Ready-3178C6?logo=typescript&logoColor=white)
12
12
 
13
- ![Guardrails Demo](./media/guardrail-example.gif)
13
+ ![Guardrails Demo](../../media/guardrail-example.gif)
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](./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
@@ -672,9 +672,9 @@ const model = withGuardrails(openai('gpt-4o'), {
672
672
 
673
673
  See complete examples:
674
674
 
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)
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)
678
678
 
679
679
  ## Error Handling
680
680
 
@@ -744,50 +744,50 @@ See source for all built-in guardrails:
744
744
 
745
745
  ## Examples
746
746
 
747
- Browse 48+ runnable examples: [examples/README.md](./examples/README.md) |
747
+ Browse 48+ runnable examples: [examples/README.md](../examples/README.md) |
748
748
 
749
749
  ### Quick Starts
750
750
 
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) |
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) |
757
757
 
758
758
  ### Input Safety
759
759
 
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) |
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) |
766
766
 
767
767
  ### Output Safety
768
768
 
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) |
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) |
774
774
 
775
775
  ### Streaming
776
776
 
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) |
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) |
782
782
 
783
783
  ### Advanced
784
784
 
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) |
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) |
791
791
 
792
792
  ## Migration from v3.x
793
793
 
@@ -837,4 +837,4 @@ Issues and PRs are welcome.
837
837
 
838
838
  ## License
839
839
 
840
- MIT © Jag Reehal. See [LICENSE](./LICENSE) for details.
840
+ MIT © Jag Reehal. See [LICENSE](../../LICENSE) for details.
@@ -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
- () => ({ tripwireTriggered: false })
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
  }