@reactive-agents/guardrails 0.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/LICENSE +21 -0
- package/README.md +50 -0
- package/dist/index.d.ts +95 -0
- package/dist/index.js +344 -0
- package/dist/index.js.map +1 -0
- package/package.json +48 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Tyler Buell
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# @reactive-agents/guardrails
|
|
2
|
+
|
|
3
|
+
Safety guardrails for the [Reactive Agents](https://tylerjrbuell.github.io/reactive-agents-ts/) framework.
|
|
4
|
+
|
|
5
|
+
Protects agents from prompt injection, PII leakage, and toxic content — applied automatically during the `guardrail` phase of the execution engine.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
bun add @reactive-agents/guardrails effect
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Protections
|
|
14
|
+
|
|
15
|
+
| Guard | What it catches |
|
|
16
|
+
|-------|----------------|
|
|
17
|
+
| Prompt injection | Attempts to override system instructions |
|
|
18
|
+
| PII detection | Emails, phone numbers, SSNs, credit cards |
|
|
19
|
+
| Toxicity filtering | Harmful or abusive content |
|
|
20
|
+
| Output contracts | Schema-validates agent responses |
|
|
21
|
+
|
|
22
|
+
## Usage
|
|
23
|
+
|
|
24
|
+
```typescript
|
|
25
|
+
import { ReactiveAgents } from "reactive-agents";
|
|
26
|
+
|
|
27
|
+
const agent = await ReactiveAgents.create()
|
|
28
|
+
.withName("customer-support")
|
|
29
|
+
.withProvider("anthropic")
|
|
30
|
+
.withGuardrails()
|
|
31
|
+
.build();
|
|
32
|
+
|
|
33
|
+
// Prompt injection attempts are blocked before reaching the LLM
|
|
34
|
+
const result = await agent.run("Ignore previous instructions and...");
|
|
35
|
+
// result.success === false, result.error describes the violation
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Custom Guards
|
|
39
|
+
|
|
40
|
+
```typescript
|
|
41
|
+
.withGuardrails({
|
|
42
|
+
blockTopics: ["competitor-names"],
|
|
43
|
+
maxOutputLength: 2000,
|
|
44
|
+
requireOutputSchema: MyResponseSchema,
|
|
45
|
+
})
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Documentation
|
|
49
|
+
|
|
50
|
+
Full documentation at [tylerjrbuell.github.io/reactive-agents-ts/guides/guardrails/](https://tylerjrbuell.github.io/reactive-agents-ts/guides/guardrails/)
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { Schema, Effect, Context, Layer } from 'effect';
|
|
2
|
+
import * as effect_Cause from 'effect/Cause';
|
|
3
|
+
import * as effect_Types from 'effect/Types';
|
|
4
|
+
import * as effect_Layer from 'effect/Layer';
|
|
5
|
+
|
|
6
|
+
declare const ViolationType: Schema.Literal<["prompt-injection", "pii-detected", "toxicity", "scope-violation", "contract-violation"]>;
|
|
7
|
+
type ViolationType = typeof ViolationType.Type;
|
|
8
|
+
declare const Severity: Schema.Literal<["low", "medium", "high", "critical"]>;
|
|
9
|
+
type Severity = typeof Severity.Type;
|
|
10
|
+
declare const GuardrailResultSchema: Schema.Struct<{
|
|
11
|
+
passed: typeof Schema.Boolean;
|
|
12
|
+
violations: Schema.Array$<Schema.Struct<{
|
|
13
|
+
type: Schema.Literal<["prompt-injection", "pii-detected", "toxicity", "scope-violation", "contract-violation"]>;
|
|
14
|
+
severity: Schema.Literal<["low", "medium", "high", "critical"]>;
|
|
15
|
+
message: typeof Schema.String;
|
|
16
|
+
details: Schema.optional<typeof Schema.String>;
|
|
17
|
+
}>>;
|
|
18
|
+
score: typeof Schema.Number;
|
|
19
|
+
checkedAt: typeof Schema.DateFromSelf;
|
|
20
|
+
}>;
|
|
21
|
+
type GuardrailResult = typeof GuardrailResultSchema.Type;
|
|
22
|
+
declare const AgentContractSchema: Schema.Struct<{
|
|
23
|
+
allowedTopics: Schema.Array$<typeof Schema.String>;
|
|
24
|
+
deniedTopics: Schema.Array$<typeof Schema.String>;
|
|
25
|
+
allowedActions: Schema.Array$<typeof Schema.String>;
|
|
26
|
+
deniedActions: Schema.Array$<typeof Schema.String>;
|
|
27
|
+
maxOutputLength: Schema.optional<typeof Schema.Number>;
|
|
28
|
+
requireDisclosure: Schema.optional<typeof Schema.Boolean>;
|
|
29
|
+
}>;
|
|
30
|
+
type AgentContract = typeof AgentContractSchema.Type;
|
|
31
|
+
declare const GuardrailConfigSchema: Schema.Struct<{
|
|
32
|
+
enableInjectionDetection: typeof Schema.Boolean;
|
|
33
|
+
enablePiiDetection: typeof Schema.Boolean;
|
|
34
|
+
enableToxicityDetection: typeof Schema.Boolean;
|
|
35
|
+
contract: Schema.optional<Schema.Struct<{
|
|
36
|
+
allowedTopics: Schema.Array$<typeof Schema.String>;
|
|
37
|
+
deniedTopics: Schema.Array$<typeof Schema.String>;
|
|
38
|
+
allowedActions: Schema.Array$<typeof Schema.String>;
|
|
39
|
+
deniedActions: Schema.Array$<typeof Schema.String>;
|
|
40
|
+
maxOutputLength: Schema.optional<typeof Schema.Number>;
|
|
41
|
+
requireDisclosure: Schema.optional<typeof Schema.Boolean>;
|
|
42
|
+
}>>;
|
|
43
|
+
customBlocklist: Schema.optional<Schema.Array$<typeof Schema.String>>;
|
|
44
|
+
}>;
|
|
45
|
+
type GuardrailConfig = typeof GuardrailConfigSchema.Type;
|
|
46
|
+
declare const defaultGuardrailConfig: GuardrailConfig;
|
|
47
|
+
|
|
48
|
+
declare const GuardrailError_base: new <A extends Record<string, any> = {}>(args: effect_Types.Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => effect_Cause.YieldableError & {
|
|
49
|
+
readonly _tag: "GuardrailError";
|
|
50
|
+
} & Readonly<A>;
|
|
51
|
+
declare class GuardrailError extends GuardrailError_base<{
|
|
52
|
+
readonly message: string;
|
|
53
|
+
readonly cause?: unknown;
|
|
54
|
+
}> {
|
|
55
|
+
}
|
|
56
|
+
declare const ViolationError_base: new <A extends Record<string, any> = {}>(args: effect_Types.Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => effect_Cause.YieldableError & {
|
|
57
|
+
readonly _tag: "ViolationError";
|
|
58
|
+
} & Readonly<A>;
|
|
59
|
+
declare class ViolationError extends ViolationError_base<{
|
|
60
|
+
readonly message: string;
|
|
61
|
+
readonly violationType: string;
|
|
62
|
+
readonly severity: string;
|
|
63
|
+
}> {
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
interface DetectionResult {
|
|
67
|
+
readonly detected: boolean;
|
|
68
|
+
readonly type: ViolationType;
|
|
69
|
+
readonly severity: Severity;
|
|
70
|
+
readonly message: string;
|
|
71
|
+
readonly details?: string;
|
|
72
|
+
}
|
|
73
|
+
declare const detectInjection: (text: string) => Effect.Effect<DetectionResult, never>;
|
|
74
|
+
|
|
75
|
+
declare const detectPii: (text: string) => Effect.Effect<DetectionResult, never>;
|
|
76
|
+
|
|
77
|
+
declare const detectToxicity: (text: string, customBlocklist?: readonly string[]) => Effect.Effect<DetectionResult, never>;
|
|
78
|
+
|
|
79
|
+
declare const checkContract: (text: string, contract: AgentContract) => Effect.Effect<DetectionResult, never>;
|
|
80
|
+
|
|
81
|
+
declare const GuardrailService_base: Context.TagClass<GuardrailService, "GuardrailService", {
|
|
82
|
+
/** Check input text against all configured guardrails. */
|
|
83
|
+
readonly check: (text: string) => Effect.Effect<GuardrailResult, GuardrailError>;
|
|
84
|
+
/** Check output text (may have different rules). */
|
|
85
|
+
readonly checkOutput: (text: string) => Effect.Effect<GuardrailResult, GuardrailError>;
|
|
86
|
+
/** Get current config. */
|
|
87
|
+
readonly getConfig: () => Effect.Effect<GuardrailConfig, never>;
|
|
88
|
+
}>;
|
|
89
|
+
declare class GuardrailService extends GuardrailService_base {
|
|
90
|
+
}
|
|
91
|
+
declare const GuardrailServiceLive: (config: GuardrailConfig) => Layer.Layer<GuardrailService, never, never>;
|
|
92
|
+
|
|
93
|
+
declare const createGuardrailsLayer: (config?: Partial<GuardrailConfig>) => effect_Layer.Layer<GuardrailService, never, never>;
|
|
94
|
+
|
|
95
|
+
export { type AgentContract, AgentContractSchema, type DetectionResult, type GuardrailConfig, GuardrailConfigSchema, GuardrailError, type GuardrailResult, GuardrailResultSchema, GuardrailService, GuardrailServiceLive, Severity, Severity as SeveritySchema, ViolationError, ViolationType, ViolationType as ViolationTypeSchema, checkContract, createGuardrailsLayer, defaultGuardrailConfig, detectInjection, detectPii, detectToxicity };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
// src/types.ts
|
|
2
|
+
import { Schema } from "effect";
|
|
3
|
+
var ViolationType = Schema.Literal(
|
|
4
|
+
"prompt-injection",
|
|
5
|
+
"pii-detected",
|
|
6
|
+
"toxicity",
|
|
7
|
+
"scope-violation",
|
|
8
|
+
"contract-violation"
|
|
9
|
+
);
|
|
10
|
+
var Severity = Schema.Literal("low", "medium", "high", "critical");
|
|
11
|
+
var GuardrailResultSchema = Schema.Struct({
|
|
12
|
+
passed: Schema.Boolean,
|
|
13
|
+
violations: Schema.Array(
|
|
14
|
+
Schema.Struct({
|
|
15
|
+
type: ViolationType,
|
|
16
|
+
severity: Severity,
|
|
17
|
+
message: Schema.String,
|
|
18
|
+
details: Schema.optional(Schema.String)
|
|
19
|
+
})
|
|
20
|
+
),
|
|
21
|
+
score: Schema.Number,
|
|
22
|
+
// 0-1, 1 = fully safe
|
|
23
|
+
checkedAt: Schema.DateFromSelf
|
|
24
|
+
});
|
|
25
|
+
var AgentContractSchema = Schema.Struct({
|
|
26
|
+
allowedTopics: Schema.Array(Schema.String),
|
|
27
|
+
deniedTopics: Schema.Array(Schema.String),
|
|
28
|
+
allowedActions: Schema.Array(Schema.String),
|
|
29
|
+
deniedActions: Schema.Array(Schema.String),
|
|
30
|
+
maxOutputLength: Schema.optional(Schema.Number),
|
|
31
|
+
requireDisclosure: Schema.optional(Schema.Boolean)
|
|
32
|
+
});
|
|
33
|
+
var GuardrailConfigSchema = Schema.Struct({
|
|
34
|
+
enableInjectionDetection: Schema.Boolean,
|
|
35
|
+
enablePiiDetection: Schema.Boolean,
|
|
36
|
+
enableToxicityDetection: Schema.Boolean,
|
|
37
|
+
contract: Schema.optional(AgentContractSchema),
|
|
38
|
+
customBlocklist: Schema.optional(Schema.Array(Schema.String))
|
|
39
|
+
});
|
|
40
|
+
var defaultGuardrailConfig = {
|
|
41
|
+
enableInjectionDetection: true,
|
|
42
|
+
enablePiiDetection: true,
|
|
43
|
+
enableToxicityDetection: true
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
// src/errors.ts
|
|
47
|
+
import { Data } from "effect";
|
|
48
|
+
var GuardrailError = class extends Data.TaggedError("GuardrailError") {
|
|
49
|
+
};
|
|
50
|
+
var ViolationError = class extends Data.TaggedError("ViolationError") {
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
// src/detectors/injection-detector.ts
|
|
54
|
+
import { Effect } from "effect";
|
|
55
|
+
var INJECTION_PATTERNS = [
|
|
56
|
+
{ pattern: /ignore\s+(all\s+)?previous\s+(instructions|prompts)/i, severity: "critical", description: "Instruction override attempt" },
|
|
57
|
+
{ pattern: /disregard\s+(all\s+)?previous/i, severity: "critical", description: "Instruction disregard attempt" },
|
|
58
|
+
{ pattern: /forget\s+(all\s+)?(your\s+)?previous/i, severity: "high", description: "Memory reset attempt" },
|
|
59
|
+
{ pattern: /you\s+are\s+now\s+a/i, severity: "high", description: "Role reassignment attempt" },
|
|
60
|
+
{ pattern: /act\s+as\s+(if\s+)?(you\s+are|a)\s/i, severity: "medium", description: "Role play injection" },
|
|
61
|
+
{ pattern: /system\s*:\s*you\s+are/i, severity: "critical", description: "System prompt injection" },
|
|
62
|
+
{ pattern: /\[SYSTEM\]/i, severity: "high", description: "System tag injection" },
|
|
63
|
+
{ pattern: /\<\/?system\>/i, severity: "high", description: "System XML tag injection" },
|
|
64
|
+
{ pattern: /do\s+not\s+follow\s+(your\s+)?(rules|guidelines)/i, severity: "critical", description: "Rule override attempt" },
|
|
65
|
+
{ pattern: /pretend\s+(that\s+)?you\s+(don't|do\s+not)\s+have/i, severity: "high", description: "Capability override attempt" },
|
|
66
|
+
{ pattern: /\bDAN\b.*\bmode\b/i, severity: "critical", description: "DAN jailbreak attempt" },
|
|
67
|
+
{ pattern: /jailbreak/i, severity: "critical", description: "Explicit jailbreak reference" }
|
|
68
|
+
];
|
|
69
|
+
var detectInjection = (text) => Effect.sync(() => {
|
|
70
|
+
for (const { pattern, severity, description } of INJECTION_PATTERNS) {
|
|
71
|
+
if (pattern.test(text)) {
|
|
72
|
+
return {
|
|
73
|
+
detected: true,
|
|
74
|
+
type: "prompt-injection",
|
|
75
|
+
severity,
|
|
76
|
+
message: `Prompt injection detected: ${description}`,
|
|
77
|
+
details: `Matched pattern: ${pattern.source}`
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return {
|
|
82
|
+
detected: false,
|
|
83
|
+
type: "prompt-injection",
|
|
84
|
+
severity: "low",
|
|
85
|
+
message: "No injection detected"
|
|
86
|
+
};
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
// src/detectors/pii-detector.ts
|
|
90
|
+
import { Effect as Effect2 } from "effect";
|
|
91
|
+
var PII_PATTERNS = [
|
|
92
|
+
{ pattern: /\b\d{3}-\d{2}-\d{4}\b/, label: "SSN", severity: "critical" },
|
|
93
|
+
{ pattern: /\b\d{9}\b/, label: "SSN (no dashes)", severity: "high" },
|
|
94
|
+
{ pattern: /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b/, label: "Email", severity: "medium" },
|
|
95
|
+
{ pattern: /\b\d{4}[\s-]?\d{4}[\s-]?\d{4}[\s-]?\d{4}\b/, label: "Credit card", severity: "critical" },
|
|
96
|
+
{ pattern: /\b(?:\+?1[-.\s]?)?\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}\b/, label: "Phone number", severity: "medium" },
|
|
97
|
+
{ pattern: /\b\d{1,5}\s\w+\s(?:Street|St|Avenue|Ave|Road|Rd|Drive|Dr|Lane|Ln|Boulevard|Blvd)\b/i, label: "Street address", severity: "high" },
|
|
98
|
+
{ pattern: /\b[A-Z]{1,2}\d{1,2}\s?\d[A-Z]{2}\b/, label: "UK postcode", severity: "medium" },
|
|
99
|
+
{ pattern: /\bpassword\s*[:=]\s*\S+/i, label: "Password", severity: "critical" },
|
|
100
|
+
{ pattern: /\b(sk-|sk_live_|pk_live_|sk_test_)\S{20,}/i, label: "API key", severity: "critical" }
|
|
101
|
+
];
|
|
102
|
+
var detectPii = (text) => Effect2.sync(() => {
|
|
103
|
+
const found = [];
|
|
104
|
+
let maxSeverity = "low";
|
|
105
|
+
const severityOrder = ["low", "medium", "high", "critical"];
|
|
106
|
+
for (const { pattern, label, severity } of PII_PATTERNS) {
|
|
107
|
+
if (pattern.test(text)) {
|
|
108
|
+
found.push(label);
|
|
109
|
+
if (severityOrder.indexOf(severity) > severityOrder.indexOf(maxSeverity)) {
|
|
110
|
+
maxSeverity = severity;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
if (found.length > 0) {
|
|
115
|
+
return {
|
|
116
|
+
detected: true,
|
|
117
|
+
type: "pii-detected",
|
|
118
|
+
severity: maxSeverity,
|
|
119
|
+
message: `PII detected: ${found.join(", ")}`,
|
|
120
|
+
details: `Found ${found.length} PII pattern(s)`
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
return {
|
|
124
|
+
detected: false,
|
|
125
|
+
type: "pii-detected",
|
|
126
|
+
severity: "low",
|
|
127
|
+
message: "No PII detected"
|
|
128
|
+
};
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
// src/detectors/toxicity-detector.ts
|
|
132
|
+
import { Effect as Effect3 } from "effect";
|
|
133
|
+
var TOXIC_PATTERNS = [
|
|
134
|
+
{ pattern: /\b(kill|murder|assassinate)\s+(yourself|himself|herself|themselves|someone|people)\b/i, severity: "critical", category: "violence" },
|
|
135
|
+
{ pattern: /\bhow\s+to\s+(make|build|create)\s+(a\s+)?(bomb|weapon|explosive)/i, severity: "critical", category: "weapons" },
|
|
136
|
+
{ pattern: /\b(hack|exploit|breach)\s+(into|a|the)\s/i, severity: "high", category: "hacking" },
|
|
137
|
+
{ pattern: /\b(steal|rob|burglarize)\s/i, severity: "high", category: "theft" },
|
|
138
|
+
{ pattern: /\b(hate|despise)\s+(all\s+)?(women|men|blacks|whites|jews|muslims|christians)/i, severity: "critical", category: "hate-speech" },
|
|
139
|
+
{ pattern: /\b(racial|ethnic)\s+(slur|epithet)/i, severity: "critical", category: "hate-speech" },
|
|
140
|
+
{ pattern: /\bself[- ]?harm\b/i, severity: "critical", category: "self-harm" },
|
|
141
|
+
{ pattern: /\bsuicide\s+(method|how|way)/i, severity: "critical", category: "self-harm" }
|
|
142
|
+
];
|
|
143
|
+
var detectToxicity = (text, customBlocklist = []) => Effect3.sync(() => {
|
|
144
|
+
for (const { pattern, category, severity } of TOXIC_PATTERNS) {
|
|
145
|
+
if (pattern.test(text)) {
|
|
146
|
+
return {
|
|
147
|
+
detected: true,
|
|
148
|
+
type: "toxicity",
|
|
149
|
+
severity,
|
|
150
|
+
message: `Toxic content detected: ${category}`,
|
|
151
|
+
details: `Category: ${category}`
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
const lower = text.toLowerCase();
|
|
156
|
+
for (const word of customBlocklist) {
|
|
157
|
+
if (lower.includes(word.toLowerCase())) {
|
|
158
|
+
return {
|
|
159
|
+
detected: true,
|
|
160
|
+
type: "toxicity",
|
|
161
|
+
severity: "high",
|
|
162
|
+
message: `Blocked term detected: "${word}"`,
|
|
163
|
+
details: `Custom blocklist match`
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return {
|
|
168
|
+
detected: false,
|
|
169
|
+
type: "toxicity",
|
|
170
|
+
severity: "low",
|
|
171
|
+
message: "No toxic content detected"
|
|
172
|
+
};
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
// src/contracts/agent-contract.ts
|
|
176
|
+
import { Effect as Effect4 } from "effect";
|
|
177
|
+
var checkContract = (text, contract) => Effect4.sync(() => {
|
|
178
|
+
const lower = text.toLowerCase();
|
|
179
|
+
for (const topic of contract.deniedTopics) {
|
|
180
|
+
if (lower.includes(topic.toLowerCase())) {
|
|
181
|
+
return {
|
|
182
|
+
detected: true,
|
|
183
|
+
type: "contract-violation",
|
|
184
|
+
severity: "high",
|
|
185
|
+
message: `Denied topic referenced: "${topic}"`,
|
|
186
|
+
details: `Contract prohibits this topic`
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
for (const action of contract.deniedActions) {
|
|
191
|
+
if (lower.includes(action.toLowerCase())) {
|
|
192
|
+
return {
|
|
193
|
+
detected: true,
|
|
194
|
+
type: "scope-violation",
|
|
195
|
+
severity: "high",
|
|
196
|
+
message: `Denied action referenced: "${action}"`,
|
|
197
|
+
details: `Contract prohibits this action`
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
if (contract.maxOutputLength !== void 0 && text.length > contract.maxOutputLength) {
|
|
202
|
+
return {
|
|
203
|
+
detected: true,
|
|
204
|
+
type: "contract-violation",
|
|
205
|
+
severity: "medium",
|
|
206
|
+
message: `Output exceeds max length (${text.length} > ${contract.maxOutputLength})`
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
return {
|
|
210
|
+
detected: false,
|
|
211
|
+
type: "contract-violation",
|
|
212
|
+
severity: "low",
|
|
213
|
+
message: "Contract check passed"
|
|
214
|
+
};
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
// src/guardrail-service.ts
|
|
218
|
+
import { Effect as Effect5, Context, Layer } from "effect";
|
|
219
|
+
var GuardrailService = class extends Context.Tag("GuardrailService")() {
|
|
220
|
+
};
|
|
221
|
+
var GuardrailServiceLive = (config) => Layer.succeed(GuardrailService, {
|
|
222
|
+
check: (text) => Effect5.gen(function* () {
|
|
223
|
+
const violations = [];
|
|
224
|
+
if (config.enableInjectionDetection) {
|
|
225
|
+
const result = yield* detectInjection(text);
|
|
226
|
+
if (result.detected) {
|
|
227
|
+
violations.push({
|
|
228
|
+
type: result.type,
|
|
229
|
+
severity: result.severity,
|
|
230
|
+
message: result.message,
|
|
231
|
+
details: result.details
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
if (config.enablePiiDetection) {
|
|
236
|
+
const result = yield* detectPii(text);
|
|
237
|
+
if (result.detected) {
|
|
238
|
+
violations.push({
|
|
239
|
+
type: result.type,
|
|
240
|
+
severity: result.severity,
|
|
241
|
+
message: result.message,
|
|
242
|
+
details: result.details
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
if (config.enableToxicityDetection) {
|
|
247
|
+
const result = yield* detectToxicity(text, config.customBlocklist ?? []);
|
|
248
|
+
if (result.detected) {
|
|
249
|
+
violations.push({
|
|
250
|
+
type: result.type,
|
|
251
|
+
severity: result.severity,
|
|
252
|
+
message: result.message,
|
|
253
|
+
details: result.details
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
if (config.contract) {
|
|
258
|
+
const result = yield* checkContract(text, config.contract);
|
|
259
|
+
if (result.detected) {
|
|
260
|
+
violations.push({
|
|
261
|
+
type: result.type,
|
|
262
|
+
severity: result.severity,
|
|
263
|
+
message: result.message,
|
|
264
|
+
details: result.details
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
const score = violations.length === 0 ? 1 : Math.max(0, 1 - violations.length * 0.25);
|
|
269
|
+
return {
|
|
270
|
+
passed: violations.length === 0,
|
|
271
|
+
violations: [...violations],
|
|
272
|
+
score,
|
|
273
|
+
checkedAt: /* @__PURE__ */ new Date()
|
|
274
|
+
};
|
|
275
|
+
}),
|
|
276
|
+
checkOutput: (text) => Effect5.gen(function* () {
|
|
277
|
+
const violations = [];
|
|
278
|
+
if (config.enablePiiDetection) {
|
|
279
|
+
const result = yield* detectPii(text);
|
|
280
|
+
if (result.detected) {
|
|
281
|
+
violations.push({
|
|
282
|
+
type: result.type,
|
|
283
|
+
severity: result.severity,
|
|
284
|
+
message: result.message,
|
|
285
|
+
details: result.details
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
if (config.enableToxicityDetection) {
|
|
290
|
+
const result = yield* detectToxicity(text, config.customBlocklist ?? []);
|
|
291
|
+
if (result.detected) {
|
|
292
|
+
violations.push({
|
|
293
|
+
type: result.type,
|
|
294
|
+
severity: result.severity,
|
|
295
|
+
message: result.message,
|
|
296
|
+
details: result.details
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
if (config.contract) {
|
|
301
|
+
const result = yield* checkContract(text, config.contract);
|
|
302
|
+
if (result.detected) {
|
|
303
|
+
violations.push({
|
|
304
|
+
type: result.type,
|
|
305
|
+
severity: result.severity,
|
|
306
|
+
message: result.message,
|
|
307
|
+
details: result.details
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
const score = violations.length === 0 ? 1 : Math.max(0, 1 - violations.length * 0.25);
|
|
312
|
+
return {
|
|
313
|
+
passed: violations.length === 0,
|
|
314
|
+
violations: [...violations],
|
|
315
|
+
score,
|
|
316
|
+
checkedAt: /* @__PURE__ */ new Date()
|
|
317
|
+
};
|
|
318
|
+
}),
|
|
319
|
+
getConfig: () => Effect5.succeed(config)
|
|
320
|
+
});
|
|
321
|
+
|
|
322
|
+
// src/runtime.ts
|
|
323
|
+
var createGuardrailsLayer = (config) => GuardrailServiceLive({
|
|
324
|
+
...defaultGuardrailConfig,
|
|
325
|
+
...config
|
|
326
|
+
});
|
|
327
|
+
export {
|
|
328
|
+
AgentContractSchema,
|
|
329
|
+
GuardrailConfigSchema,
|
|
330
|
+
GuardrailError,
|
|
331
|
+
GuardrailResultSchema,
|
|
332
|
+
GuardrailService,
|
|
333
|
+
GuardrailServiceLive,
|
|
334
|
+
Severity as SeveritySchema,
|
|
335
|
+
ViolationError,
|
|
336
|
+
ViolationType as ViolationTypeSchema,
|
|
337
|
+
checkContract,
|
|
338
|
+
createGuardrailsLayer,
|
|
339
|
+
defaultGuardrailConfig,
|
|
340
|
+
detectInjection,
|
|
341
|
+
detectPii,
|
|
342
|
+
detectToxicity
|
|
343
|
+
};
|
|
344
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/types.ts","../src/errors.ts","../src/detectors/injection-detector.ts","../src/detectors/pii-detector.ts","../src/detectors/toxicity-detector.ts","../src/contracts/agent-contract.ts","../src/guardrail-service.ts","../src/runtime.ts"],"sourcesContent":["import { Schema } from \"effect\";\n\n// ─── Violation Type ───\n\nexport const ViolationType = Schema.Literal(\n \"prompt-injection\",\n \"pii-detected\",\n \"toxicity\",\n \"scope-violation\",\n \"contract-violation\",\n);\nexport type ViolationType = typeof ViolationType.Type;\n\n// ─── Severity ───\n\nexport const Severity = Schema.Literal(\"low\", \"medium\", \"high\", \"critical\");\nexport type Severity = typeof Severity.Type;\n\n// ─── Guardrail Result ───\n\nexport const GuardrailResultSchema = Schema.Struct({\n passed: Schema.Boolean,\n violations: Schema.Array(\n Schema.Struct({\n type: ViolationType,\n severity: Severity,\n message: Schema.String,\n details: Schema.optional(Schema.String),\n }),\n ),\n score: Schema.Number, // 0-1, 1 = fully safe\n checkedAt: Schema.DateFromSelf,\n});\nexport type GuardrailResult = typeof GuardrailResultSchema.Type;\n\n// ─── Agent Contract ───\n\nexport const AgentContractSchema = Schema.Struct({\n allowedTopics: Schema.Array(Schema.String),\n deniedTopics: Schema.Array(Schema.String),\n allowedActions: Schema.Array(Schema.String),\n deniedActions: Schema.Array(Schema.String),\n maxOutputLength: Schema.optional(Schema.Number),\n requireDisclosure: Schema.optional(Schema.Boolean),\n});\nexport type AgentContract = typeof AgentContractSchema.Type;\n\n// ─── Guardrail Config ───\n\nexport const GuardrailConfigSchema = Schema.Struct({\n enableInjectionDetection: Schema.Boolean,\n enablePiiDetection: Schema.Boolean,\n enableToxicityDetection: Schema.Boolean,\n contract: Schema.optional(AgentContractSchema),\n customBlocklist: Schema.optional(Schema.Array(Schema.String)),\n});\nexport type GuardrailConfig = typeof GuardrailConfigSchema.Type;\n\nexport const defaultGuardrailConfig: GuardrailConfig = {\n enableInjectionDetection: true,\n enablePiiDetection: true,\n enableToxicityDetection: true,\n};\n","import { Data } from \"effect\";\n\nexport class GuardrailError extends Data.TaggedError(\"GuardrailError\")<{\n readonly message: string;\n readonly cause?: unknown;\n}> {}\n\nexport class ViolationError extends Data.TaggedError(\"ViolationError\")<{\n readonly message: string;\n readonly violationType: string;\n readonly severity: string;\n}> {}\n","import { Effect } from \"effect\";\nimport type { ViolationType, Severity } from \"../types.js\";\n\nexport interface DetectionResult {\n readonly detected: boolean;\n readonly type: ViolationType;\n readonly severity: Severity;\n readonly message: string;\n readonly details?: string;\n}\n\n// Common prompt injection patterns\nconst INJECTION_PATTERNS: Array<{ pattern: RegExp; severity: Severity; description: string }> = [\n { pattern: /ignore\\s+(all\\s+)?previous\\s+(instructions|prompts)/i, severity: \"critical\", description: \"Instruction override attempt\" },\n { pattern: /disregard\\s+(all\\s+)?previous/i, severity: \"critical\", description: \"Instruction disregard attempt\" },\n { pattern: /forget\\s+(all\\s+)?(your\\s+)?previous/i, severity: \"high\", description: \"Memory reset attempt\" },\n { pattern: /you\\s+are\\s+now\\s+a/i, severity: \"high\", description: \"Role reassignment attempt\" },\n { pattern: /act\\s+as\\s+(if\\s+)?(you\\s+are|a)\\s/i, severity: \"medium\", description: \"Role play injection\" },\n { pattern: /system\\s*:\\s*you\\s+are/i, severity: \"critical\", description: \"System prompt injection\" },\n { pattern: /\\[SYSTEM\\]/i, severity: \"high\", description: \"System tag injection\" },\n { pattern: /\\<\\/?system\\>/i, severity: \"high\", description: \"System XML tag injection\" },\n { pattern: /do\\s+not\\s+follow\\s+(your\\s+)?(rules|guidelines)/i, severity: \"critical\", description: \"Rule override attempt\" },\n { pattern: /pretend\\s+(that\\s+)?you\\s+(don't|do\\s+not)\\s+have/i, severity: \"high\", description: \"Capability override attempt\" },\n { pattern: /\\bDAN\\b.*\\bmode\\b/i, severity: \"critical\", description: \"DAN jailbreak attempt\" },\n { pattern: /jailbreak/i, severity: \"critical\", description: \"Explicit jailbreak reference\" },\n];\n\nexport const detectInjection = (text: string): Effect.Effect<DetectionResult, never> =>\n Effect.sync(() => {\n for (const { pattern, severity, description } of INJECTION_PATTERNS) {\n if (pattern.test(text)) {\n return {\n detected: true,\n type: \"prompt-injection\" as ViolationType,\n severity,\n message: `Prompt injection detected: ${description}`,\n details: `Matched pattern: ${pattern.source}`,\n };\n }\n }\n return {\n detected: false,\n type: \"prompt-injection\" as ViolationType,\n severity: \"low\" as Severity,\n message: \"No injection detected\",\n };\n });\n","import { Effect } from \"effect\";\nimport type { ViolationType, Severity } from \"../types.js\";\nimport type { DetectionResult } from \"./injection-detector.js\";\n\n// PII patterns\nconst PII_PATTERNS: Array<{ pattern: RegExp; label: string; severity: Severity }> = [\n { pattern: /\\b\\d{3}-\\d{2}-\\d{4}\\b/, label: \"SSN\", severity: \"critical\" },\n { pattern: /\\b\\d{9}\\b/, label: \"SSN (no dashes)\", severity: \"high\" },\n { pattern: /\\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}\\b/, label: \"Email\", severity: \"medium\" },\n { pattern: /\\b\\d{4}[\\s-]?\\d{4}[\\s-]?\\d{4}[\\s-]?\\d{4}\\b/, label: \"Credit card\", severity: \"critical\" },\n { pattern: /\\b(?:\\+?1[-.\\s]?)?\\(?\\d{3}\\)?[-.\\s]?\\d{3}[-.\\s]?\\d{4}\\b/, label: \"Phone number\", severity: \"medium\" },\n { pattern: /\\b\\d{1,5}\\s\\w+\\s(?:Street|St|Avenue|Ave|Road|Rd|Drive|Dr|Lane|Ln|Boulevard|Blvd)\\b/i, label: \"Street address\", severity: \"high\" },\n { pattern: /\\b[A-Z]{1,2}\\d{1,2}\\s?\\d[A-Z]{2}\\b/, label: \"UK postcode\", severity: \"medium\" },\n { pattern: /\\bpassword\\s*[:=]\\s*\\S+/i, label: \"Password\", severity: \"critical\" },\n { pattern: /\\b(sk-|sk_live_|pk_live_|sk_test_)\\S{20,}/i, label: \"API key\", severity: \"critical\" },\n];\n\nexport const detectPii = (text: string): Effect.Effect<DetectionResult, never> =>\n Effect.sync(() => {\n const found: string[] = [];\n let maxSeverity: Severity = \"low\";\n const severityOrder: Severity[] = [\"low\", \"medium\", \"high\", \"critical\"];\n\n for (const { pattern, label, severity } of PII_PATTERNS) {\n if (pattern.test(text)) {\n found.push(label);\n if (severityOrder.indexOf(severity) > severityOrder.indexOf(maxSeverity)) {\n maxSeverity = severity;\n }\n }\n }\n\n if (found.length > 0) {\n return {\n detected: true,\n type: \"pii-detected\" as ViolationType,\n severity: maxSeverity,\n message: `PII detected: ${found.join(\", \")}`,\n details: `Found ${found.length} PII pattern(s)`,\n };\n }\n\n return {\n detected: false,\n type: \"pii-detected\" as ViolationType,\n severity: \"low\" as Severity,\n message: \"No PII detected\",\n };\n });\n","import { Effect } from \"effect\";\nimport type { ViolationType, Severity } from \"../types.js\";\nimport type { DetectionResult } from \"./injection-detector.js\";\n\n// Toxicity keyword categories (simplified blocklist)\nconst TOXIC_PATTERNS: Array<{ pattern: RegExp; category: string; severity: Severity }> = [\n { pattern: /\\b(kill|murder|assassinate)\\s+(yourself|himself|herself|themselves|someone|people)\\b/i, severity: \"critical\", category: \"violence\" },\n { pattern: /\\bhow\\s+to\\s+(make|build|create)\\s+(a\\s+)?(bomb|weapon|explosive)/i, severity: \"critical\", category: \"weapons\" },\n { pattern: /\\b(hack|exploit|breach)\\s+(into|a|the)\\s/i, severity: \"high\", category: \"hacking\" },\n { pattern: /\\b(steal|rob|burglarize)\\s/i, severity: \"high\", category: \"theft\" },\n { pattern: /\\b(hate|despise)\\s+(all\\s+)?(women|men|blacks|whites|jews|muslims|christians)/i, severity: \"critical\", category: \"hate-speech\" },\n { pattern: /\\b(racial|ethnic)\\s+(slur|epithet)/i, severity: \"critical\", category: \"hate-speech\" },\n { pattern: /\\bself[- ]?harm\\b/i, severity: \"critical\", category: \"self-harm\" },\n { pattern: /\\bsuicide\\s+(method|how|way)/i, severity: \"critical\", category: \"self-harm\" },\n];\n\nexport const detectToxicity = (\n text: string,\n customBlocklist: readonly string[] = [],\n): Effect.Effect<DetectionResult, never> =>\n Effect.sync(() => {\n // Check built-in patterns\n for (const { pattern, category, severity } of TOXIC_PATTERNS) {\n if (pattern.test(text)) {\n return {\n detected: true,\n type: \"toxicity\" as ViolationType,\n severity,\n message: `Toxic content detected: ${category}`,\n details: `Category: ${category}`,\n };\n }\n }\n\n // Check custom blocklist\n const lower = text.toLowerCase();\n for (const word of customBlocklist) {\n if (lower.includes(word.toLowerCase())) {\n return {\n detected: true,\n type: \"toxicity\" as ViolationType,\n severity: \"high\" as Severity,\n message: `Blocked term detected: \"${word}\"`,\n details: `Custom blocklist match`,\n };\n }\n }\n\n return {\n detected: false,\n type: \"toxicity\" as ViolationType,\n severity: \"low\" as Severity,\n message: \"No toxic content detected\",\n };\n });\n","import { Effect } from \"effect\";\nimport type { AgentContract, ViolationType, Severity } from \"../types.js\";\nimport type { DetectionResult } from \"../detectors/injection-detector.js\";\n\nexport const checkContract = (\n text: string,\n contract: AgentContract,\n): Effect.Effect<DetectionResult, never> =>\n Effect.sync(() => {\n const lower = text.toLowerCase();\n\n // Check denied topics\n for (const topic of contract.deniedTopics) {\n if (lower.includes(topic.toLowerCase())) {\n return {\n detected: true,\n type: \"contract-violation\" as ViolationType,\n severity: \"high\" as Severity,\n message: `Denied topic referenced: \"${topic}\"`,\n details: `Contract prohibits this topic`,\n };\n }\n }\n\n // Check denied actions\n for (const action of contract.deniedActions) {\n if (lower.includes(action.toLowerCase())) {\n return {\n detected: true,\n type: \"scope-violation\" as ViolationType,\n severity: \"high\" as Severity,\n message: `Denied action referenced: \"${action}\"`,\n details: `Contract prohibits this action`,\n };\n }\n }\n\n // Check output length\n if (contract.maxOutputLength !== undefined && text.length > contract.maxOutputLength) {\n return {\n detected: true,\n type: \"contract-violation\" as ViolationType,\n severity: \"medium\" as Severity,\n message: `Output exceeds max length (${text.length} > ${contract.maxOutputLength})`,\n };\n }\n\n return {\n detected: false,\n type: \"contract-violation\" as ViolationType,\n severity: \"low\" as Severity,\n message: \"Contract check passed\",\n };\n });\n","import { Effect, Context, Layer } from \"effect\";\nimport type { GuardrailResult, GuardrailConfig } from \"./types.js\";\nimport { GuardrailError } from \"./errors.js\";\nimport { detectInjection } from \"./detectors/injection-detector.js\";\nimport { detectPii } from \"./detectors/pii-detector.js\";\nimport { detectToxicity } from \"./detectors/toxicity-detector.js\";\nimport { checkContract } from \"./contracts/agent-contract.js\";\n\n// ─── Service Tag ───\n\nexport class GuardrailService extends Context.Tag(\"GuardrailService\")<\n GuardrailService,\n {\n /** Check input text against all configured guardrails. */\n readonly check: (text: string) => Effect.Effect<GuardrailResult, GuardrailError>;\n\n /** Check output text (may have different rules). */\n readonly checkOutput: (text: string) => Effect.Effect<GuardrailResult, GuardrailError>;\n\n /** Get current config. */\n readonly getConfig: () => Effect.Effect<GuardrailConfig, never>;\n }\n>() {}\n\n// ─── Live Implementation ───\n\nexport const GuardrailServiceLive = (config: GuardrailConfig) =>\n Layer.succeed(GuardrailService, {\n check: (text) =>\n Effect.gen(function* () {\n const violations: Array<{ type: GuardrailResult[\"violations\"][number][\"type\"]; severity: GuardrailResult[\"violations\"][number][\"severity\"]; message: string; details?: string }> = [];\n\n if (config.enableInjectionDetection) {\n const result = yield* detectInjection(text);\n if (result.detected) {\n violations.push({\n type: result.type,\n severity: result.severity,\n message: result.message,\n details: result.details,\n });\n }\n }\n\n if (config.enablePiiDetection) {\n const result = yield* detectPii(text);\n if (result.detected) {\n violations.push({\n type: result.type,\n severity: result.severity,\n message: result.message,\n details: result.details,\n });\n }\n }\n\n if (config.enableToxicityDetection) {\n const result = yield* detectToxicity(text, config.customBlocklist ?? []);\n if (result.detected) {\n violations.push({\n type: result.type,\n severity: result.severity,\n message: result.message,\n details: result.details,\n });\n }\n }\n\n if (config.contract) {\n const result = yield* checkContract(text, config.contract);\n if (result.detected) {\n violations.push({\n type: result.type,\n severity: result.severity,\n message: result.message,\n details: result.details,\n });\n }\n }\n\n const score = violations.length === 0 ? 1 : Math.max(0, 1 - violations.length * 0.25);\n\n return {\n passed: violations.length === 0,\n violations: [...violations],\n score,\n checkedAt: new Date(),\n } satisfies GuardrailResult;\n }),\n\n checkOutput: (text) =>\n Effect.gen(function* () {\n const violations: Array<{ type: GuardrailResult[\"violations\"][number][\"type\"]; severity: GuardrailResult[\"violations\"][number][\"severity\"]; message: string; details?: string }> = [];\n\n // Output checks: PII and toxicity (not injection)\n if (config.enablePiiDetection) {\n const result = yield* detectPii(text);\n if (result.detected) {\n violations.push({\n type: result.type,\n severity: result.severity,\n message: result.message,\n details: result.details,\n });\n }\n }\n\n if (config.enableToxicityDetection) {\n const result = yield* detectToxicity(text, config.customBlocklist ?? []);\n if (result.detected) {\n violations.push({\n type: result.type,\n severity: result.severity,\n message: result.message,\n details: result.details,\n });\n }\n }\n\n if (config.contract) {\n const result = yield* checkContract(text, config.contract);\n if (result.detected) {\n violations.push({\n type: result.type,\n severity: result.severity,\n message: result.message,\n details: result.details,\n });\n }\n }\n\n const score = violations.length === 0 ? 1 : Math.max(0, 1 - violations.length * 0.25);\n\n return {\n passed: violations.length === 0,\n violations: [...violations],\n score,\n checkedAt: new Date(),\n } satisfies GuardrailResult;\n }),\n\n getConfig: () => Effect.succeed(config),\n });\n","import type { GuardrailConfig } from \"./types.js\";\nimport { defaultGuardrailConfig } from \"./types.js\";\nimport { GuardrailServiceLive } from \"./guardrail-service.js\";\n\nexport const createGuardrailsLayer = (config?: Partial<GuardrailConfig>) =>\n GuardrailServiceLive({\n ...defaultGuardrailConfig,\n ...config,\n });\n"],"mappings":"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","names":["Effect","Effect","Effect","Effect","Effect"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@reactive-agents/guardrails",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"types": "./dist/index.d.ts",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"build": "tsup --config ../../tsup.config.base.ts",
|
|
9
|
+
"typecheck": "tsc --noEmit",
|
|
10
|
+
"test": "bun test",
|
|
11
|
+
"test:watch": "bun test --watch"
|
|
12
|
+
},
|
|
13
|
+
"dependencies": {
|
|
14
|
+
"effect": "^3.10.0",
|
|
15
|
+
"@reactive-agents/core": "0.1.0",
|
|
16
|
+
"@reactive-agents/llm-provider": "0.1.0"
|
|
17
|
+
},
|
|
18
|
+
"devDependencies": {
|
|
19
|
+
"typescript": "^5.7.0",
|
|
20
|
+
"bun-types": "latest"
|
|
21
|
+
},
|
|
22
|
+
"license": "MIT",
|
|
23
|
+
"repository": {
|
|
24
|
+
"type": "git",
|
|
25
|
+
"url": "https://github.com/tylerjrbuell/reactive-agents-ts.git",
|
|
26
|
+
"directory": "packages/guardrails"
|
|
27
|
+
},
|
|
28
|
+
"publishConfig": {
|
|
29
|
+
"access": "public"
|
|
30
|
+
},
|
|
31
|
+
"files": [
|
|
32
|
+
"dist",
|
|
33
|
+
"README.md",
|
|
34
|
+
"LICENSE"
|
|
35
|
+
],
|
|
36
|
+
"exports": {
|
|
37
|
+
".": {
|
|
38
|
+
"types": "./dist/index.d.ts",
|
|
39
|
+
"import": "./dist/index.js",
|
|
40
|
+
"default": "./dist/index.js"
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
"description": "Safety guardrails for Reactive Agents — prompt injection detection, PII scanning, and toxicity filtering",
|
|
44
|
+
"homepage": "https://tylerjrbuell.github.io/reactive-agents-ts/",
|
|
45
|
+
"bugs": {
|
|
46
|
+
"url": "https://github.com/tylerjrbuell/reactive-agents-ts/issues"
|
|
47
|
+
}
|
|
48
|
+
}
|