@artemiskit/sdk 0.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/CHANGELOG.md +134 -0
- package/README.md +173 -0
- package/adapters/openai/dist/index.js +5625 -0
- package/dist/index.js +42577 -0
- package/dist/matchers/index.js +224 -0
- package/dist/matchers/jest.js +257 -0
- package/dist/matchers/vitest.js +257 -0
- package/package.json +78 -0
- package/src/__tests__/artemiskit.test.ts +425 -0
- package/src/__tests__/matchers.test.ts +450 -0
- package/src/artemiskit.ts +791 -0
- package/src/guardian/action-validator.ts +585 -0
- package/src/guardian/circuit-breaker.ts +655 -0
- package/src/guardian/guardian.ts +497 -0
- package/src/guardian/guardrails.ts +536 -0
- package/src/guardian/index.ts +142 -0
- package/src/guardian/intent-classifier.ts +378 -0
- package/src/guardian/interceptor.ts +381 -0
- package/src/guardian/policy.ts +446 -0
- package/src/guardian/types.ts +436 -0
- package/src/index.ts +164 -0
- package/src/matchers/core.ts +315 -0
- package/src/matchers/index.ts +26 -0
- package/src/matchers/jest.ts +112 -0
- package/src/matchers/vitest.ts +84 -0
- package/src/types.ts +259 -0
- package/tsconfig.json +11 -0
|
@@ -0,0 +1,446 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Policy Loader
|
|
3
|
+
*
|
|
4
|
+
* Loads and validates guardian policies from YAML files.
|
|
5
|
+
* Policies define the guardrails, rules, and configurations for the guardian.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
9
|
+
import { resolve } from 'node:path';
|
|
10
|
+
import YAML from 'yaml';
|
|
11
|
+
import { z } from 'zod';
|
|
12
|
+
import type {
|
|
13
|
+
CircuitBreakerConfig,
|
|
14
|
+
CostLimitConfig,
|
|
15
|
+
GuardianMode,
|
|
16
|
+
GuardianPolicy,
|
|
17
|
+
GuardrailType,
|
|
18
|
+
PolicyRule,
|
|
19
|
+
RateLimitConfig,
|
|
20
|
+
ViolationAction,
|
|
21
|
+
ViolationSeverity,
|
|
22
|
+
} from './types';
|
|
23
|
+
|
|
24
|
+
// =============================================================================
|
|
25
|
+
// Schema Definitions
|
|
26
|
+
// =============================================================================
|
|
27
|
+
|
|
28
|
+
const ViolationSeveritySchema = z.enum(['low', 'medium', 'high', 'critical']);
|
|
29
|
+
const ViolationActionSchema = z.enum(['allow', 'warn', 'block', 'transform']);
|
|
30
|
+
const GuardianModeSchema = z.enum(['testing', 'guardian', 'hybrid']);
|
|
31
|
+
const GuardrailTypeSchema = z.enum([
|
|
32
|
+
'input_validation',
|
|
33
|
+
'output_validation',
|
|
34
|
+
'action_validation',
|
|
35
|
+
'intent_classification',
|
|
36
|
+
'pii_detection',
|
|
37
|
+
'injection_detection',
|
|
38
|
+
'content_filter',
|
|
39
|
+
'hallucination_check',
|
|
40
|
+
'rate_limit',
|
|
41
|
+
'cost_limit',
|
|
42
|
+
]);
|
|
43
|
+
|
|
44
|
+
const PolicyConditionSchema = z.object({
|
|
45
|
+
field: z.string(),
|
|
46
|
+
operator: z.enum([
|
|
47
|
+
'equals',
|
|
48
|
+
'contains',
|
|
49
|
+
'matches',
|
|
50
|
+
'not_equals',
|
|
51
|
+
'not_contains',
|
|
52
|
+
'greater_than',
|
|
53
|
+
'less_than',
|
|
54
|
+
]),
|
|
55
|
+
value: z.union([z.string(), z.number(), z.boolean()]),
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
const PolicyRuleSchema = z.object({
|
|
59
|
+
id: z.string(),
|
|
60
|
+
name: z.string(),
|
|
61
|
+
description: z.string().optional(),
|
|
62
|
+
type: GuardrailTypeSchema,
|
|
63
|
+
enabled: z.boolean().default(true),
|
|
64
|
+
severity: ViolationSeveritySchema,
|
|
65
|
+
action: ViolationActionSchema,
|
|
66
|
+
config: z.record(z.unknown()).optional(),
|
|
67
|
+
conditions: z.array(PolicyConditionSchema).optional(),
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
const CircuitBreakerConfigSchema = z.object({
|
|
71
|
+
enabled: z.boolean().default(false),
|
|
72
|
+
threshold: z.number().min(1).default(5),
|
|
73
|
+
windowMs: z.number().min(1000).default(60000),
|
|
74
|
+
cooldownMs: z.number().min(1000).default(300000),
|
|
75
|
+
halfOpenRequests: z.number().min(1).default(3),
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
const RateLimitConfigSchema = z.object({
|
|
79
|
+
enabled: z.boolean().default(false),
|
|
80
|
+
requestsPerMinute: z.number().optional(),
|
|
81
|
+
requestsPerHour: z.number().optional(),
|
|
82
|
+
requestsPerDay: z.number().optional(),
|
|
83
|
+
burstLimit: z.number().optional(),
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
const CostLimitConfigSchema = z.object({
|
|
87
|
+
enabled: z.boolean().default(false),
|
|
88
|
+
maxCostPerRequest: z.number().optional(),
|
|
89
|
+
maxCostPerMinute: z.number().optional(),
|
|
90
|
+
maxCostPerHour: z.number().optional(),
|
|
91
|
+
maxCostPerDay: z.number().optional(),
|
|
92
|
+
currency: z.string().default('USD'),
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
const GuardianPolicySchema = z.object({
|
|
96
|
+
name: z.string(),
|
|
97
|
+
version: z.string().default('1.0'),
|
|
98
|
+
description: z.string().optional(),
|
|
99
|
+
mode: GuardianModeSchema.default('guardian'),
|
|
100
|
+
rules: z.array(PolicyRuleSchema).min(1),
|
|
101
|
+
defaults: z
|
|
102
|
+
.object({
|
|
103
|
+
severity: ViolationSeveritySchema.optional(),
|
|
104
|
+
action: ViolationActionSchema.optional(),
|
|
105
|
+
})
|
|
106
|
+
.optional(),
|
|
107
|
+
circuitBreaker: CircuitBreakerConfigSchema.optional(),
|
|
108
|
+
rateLimits: RateLimitConfigSchema.optional(),
|
|
109
|
+
costLimits: CostLimitConfigSchema.optional(),
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
// =============================================================================
|
|
113
|
+
// Policy Loader
|
|
114
|
+
// =============================================================================
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Load a guardian policy from a YAML file
|
|
118
|
+
*/
|
|
119
|
+
export function loadPolicy(filePath: string): GuardianPolicy {
|
|
120
|
+
const absolutePath = resolve(filePath);
|
|
121
|
+
|
|
122
|
+
if (!existsSync(absolutePath)) {
|
|
123
|
+
throw new PolicyLoadError(`Policy file not found: ${absolutePath}`);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
try {
|
|
127
|
+
const content = readFileSync(absolutePath, 'utf-8');
|
|
128
|
+
return parsePolicy(content);
|
|
129
|
+
} catch (error) {
|
|
130
|
+
if (error instanceof PolicyLoadError) {
|
|
131
|
+
throw error;
|
|
132
|
+
}
|
|
133
|
+
throw new PolicyLoadError(`Failed to read policy file: ${(error as Error).message}`);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Parse a guardian policy from YAML string
|
|
139
|
+
*/
|
|
140
|
+
export function parsePolicy(yamlContent: string): GuardianPolicy {
|
|
141
|
+
let parsed: unknown;
|
|
142
|
+
|
|
143
|
+
try {
|
|
144
|
+
parsed = YAML.parse(yamlContent);
|
|
145
|
+
} catch (error) {
|
|
146
|
+
throw new PolicyLoadError(`Invalid YAML: ${(error as Error).message}`);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
const result = GuardianPolicySchema.safeParse(parsed);
|
|
150
|
+
|
|
151
|
+
if (!result.success) {
|
|
152
|
+
const errors = result.error.errors.map((e) => `${e.path.join('.')}: ${e.message}`).join(', ');
|
|
153
|
+
throw new PolicyValidationError(`Policy validation failed: ${errors}`);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
return result.data as GuardianPolicy;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Validate a guardian policy object
|
|
161
|
+
*/
|
|
162
|
+
export function validatePolicy(policy: unknown): GuardianPolicy {
|
|
163
|
+
const result = GuardianPolicySchema.safeParse(policy);
|
|
164
|
+
|
|
165
|
+
if (!result.success) {
|
|
166
|
+
const errors = result.error.errors.map((e) => `${e.path.join('.')}: ${e.message}`).join(', ');
|
|
167
|
+
throw new PolicyValidationError(`Policy validation failed: ${errors}`);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
return result.data as GuardianPolicy;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Create a default guardian policy
|
|
175
|
+
*/
|
|
176
|
+
export function createDefaultPolicy(): GuardianPolicy {
|
|
177
|
+
return {
|
|
178
|
+
name: 'default-guardian-policy',
|
|
179
|
+
version: '1.0',
|
|
180
|
+
description: 'Default guardian policy with standard security rules',
|
|
181
|
+
mode: 'guardian' as GuardianMode,
|
|
182
|
+
rules: [
|
|
183
|
+
{
|
|
184
|
+
id: 'injection-detection',
|
|
185
|
+
name: 'Prompt Injection Detection',
|
|
186
|
+
description: 'Detect and block prompt injection attempts',
|
|
187
|
+
type: 'injection_detection' as GuardrailType,
|
|
188
|
+
enabled: true,
|
|
189
|
+
severity: 'critical' as ViolationSeverity,
|
|
190
|
+
action: 'block' as ViolationAction,
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
id: 'pii-detection',
|
|
194
|
+
name: 'PII Detection',
|
|
195
|
+
description: 'Detect and redact personally identifiable information',
|
|
196
|
+
type: 'pii_detection' as GuardrailType,
|
|
197
|
+
enabled: true,
|
|
198
|
+
severity: 'high' as ViolationSeverity,
|
|
199
|
+
action: 'transform' as ViolationAction,
|
|
200
|
+
config: {
|
|
201
|
+
redact: true,
|
|
202
|
+
allowedTypes: [],
|
|
203
|
+
},
|
|
204
|
+
},
|
|
205
|
+
{
|
|
206
|
+
id: 'content-filter',
|
|
207
|
+
name: 'Content Filter',
|
|
208
|
+
description: 'Filter harmful content categories',
|
|
209
|
+
type: 'content_filter' as GuardrailType,
|
|
210
|
+
enabled: true,
|
|
211
|
+
severity: 'high' as ViolationSeverity,
|
|
212
|
+
action: 'block' as ViolationAction,
|
|
213
|
+
config: {
|
|
214
|
+
blockedCategories: ['violence', 'hate_speech', 'self_harm', 'dangerous', 'illegal'],
|
|
215
|
+
warnCategories: ['harassment', 'misinformation'],
|
|
216
|
+
},
|
|
217
|
+
},
|
|
218
|
+
{
|
|
219
|
+
id: 'intent-classification',
|
|
220
|
+
name: 'Intent Classification',
|
|
221
|
+
description: 'Classify and assess risky intents',
|
|
222
|
+
type: 'intent_classification' as GuardrailType,
|
|
223
|
+
enabled: true,
|
|
224
|
+
severity: 'medium' as ViolationSeverity,
|
|
225
|
+
action: 'warn' as ViolationAction,
|
|
226
|
+
config: {
|
|
227
|
+
blockHighRisk: true,
|
|
228
|
+
confidenceThreshold: 0.7,
|
|
229
|
+
},
|
|
230
|
+
},
|
|
231
|
+
{
|
|
232
|
+
id: 'action-validation',
|
|
233
|
+
name: 'Action Validation',
|
|
234
|
+
description: 'Validate agent tool/function calls',
|
|
235
|
+
type: 'action_validation' as GuardrailType,
|
|
236
|
+
enabled: true,
|
|
237
|
+
severity: 'high' as ViolationSeverity,
|
|
238
|
+
action: 'block' as ViolationAction,
|
|
239
|
+
config: {
|
|
240
|
+
defaultAllow: false,
|
|
241
|
+
blockHighRisk: true,
|
|
242
|
+
},
|
|
243
|
+
},
|
|
244
|
+
],
|
|
245
|
+
defaults: {
|
|
246
|
+
severity: 'medium' as ViolationSeverity,
|
|
247
|
+
action: 'warn' as ViolationAction,
|
|
248
|
+
},
|
|
249
|
+
circuitBreaker: {
|
|
250
|
+
enabled: true,
|
|
251
|
+
threshold: 5,
|
|
252
|
+
windowMs: 60000,
|
|
253
|
+
cooldownMs: 300000,
|
|
254
|
+
halfOpenRequests: 3,
|
|
255
|
+
} as CircuitBreakerConfig,
|
|
256
|
+
rateLimits: {
|
|
257
|
+
enabled: true,
|
|
258
|
+
requestsPerMinute: 100,
|
|
259
|
+
requestsPerHour: 1000,
|
|
260
|
+
burstLimit: 20,
|
|
261
|
+
} as RateLimitConfig,
|
|
262
|
+
costLimits: {
|
|
263
|
+
enabled: false,
|
|
264
|
+
currency: 'USD',
|
|
265
|
+
} as CostLimitConfig,
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* Merge two policies (second overrides first)
|
|
271
|
+
*/
|
|
272
|
+
export function mergePolicies(
|
|
273
|
+
base: GuardianPolicy,
|
|
274
|
+
override: Partial<GuardianPolicy>
|
|
275
|
+
): GuardianPolicy {
|
|
276
|
+
const merged: GuardianPolicy = {
|
|
277
|
+
...base,
|
|
278
|
+
...override,
|
|
279
|
+
name: override.name ?? base.name,
|
|
280
|
+
version: override.version ?? base.version,
|
|
281
|
+
mode: override.mode ?? base.mode,
|
|
282
|
+
rules: override.rules ?? base.rules,
|
|
283
|
+
defaults: {
|
|
284
|
+
...base.defaults,
|
|
285
|
+
...override.defaults,
|
|
286
|
+
},
|
|
287
|
+
circuitBreaker: override.circuitBreaker ?? base.circuitBreaker,
|
|
288
|
+
rateLimits: override.rateLimits ?? base.rateLimits,
|
|
289
|
+
costLimits: override.costLimits ?? base.costLimits,
|
|
290
|
+
};
|
|
291
|
+
|
|
292
|
+
return merged;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
/**
|
|
296
|
+
* Get rules by type from a policy
|
|
297
|
+
*/
|
|
298
|
+
export function getRulesByType(policy: GuardianPolicy, type: GuardrailType): PolicyRule[] {
|
|
299
|
+
return policy.rules.filter((rule) => rule.type === type && rule.enabled);
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
* Check if a rule is enabled in the policy
|
|
304
|
+
*/
|
|
305
|
+
export function isRuleEnabled(policy: GuardianPolicy, ruleId: string): boolean {
|
|
306
|
+
const rule = policy.rules.find((r) => r.id === ruleId);
|
|
307
|
+
return rule?.enabled ?? false;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
// =============================================================================
|
|
311
|
+
// Error Classes
|
|
312
|
+
// =============================================================================
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* Error thrown when policy loading fails
|
|
316
|
+
*/
|
|
317
|
+
export class PolicyLoadError extends Error {
|
|
318
|
+
constructor(message: string) {
|
|
319
|
+
super(message);
|
|
320
|
+
this.name = 'PolicyLoadError';
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
/**
|
|
325
|
+
* Error thrown when policy validation fails
|
|
326
|
+
*/
|
|
327
|
+
export class PolicyValidationError extends Error {
|
|
328
|
+
constructor(message: string) {
|
|
329
|
+
super(message);
|
|
330
|
+
this.name = 'PolicyValidationError';
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
// =============================================================================
|
|
335
|
+
// Policy Template Generator
|
|
336
|
+
// =============================================================================
|
|
337
|
+
|
|
338
|
+
/**
|
|
339
|
+
* Generate a YAML policy template
|
|
340
|
+
*/
|
|
341
|
+
export function generatePolicyTemplate(): string {
|
|
342
|
+
return `# Guardian Policy Configuration
|
|
343
|
+
# This file defines the guardrails and security rules for your AI/LLM application.
|
|
344
|
+
|
|
345
|
+
name: my-guardian-policy
|
|
346
|
+
version: "1.0"
|
|
347
|
+
description: Custom guardian policy
|
|
348
|
+
|
|
349
|
+
# Operating mode: 'testing', 'guardian', or 'hybrid'
|
|
350
|
+
mode: guardian
|
|
351
|
+
|
|
352
|
+
# Default settings for all rules
|
|
353
|
+
defaults:
|
|
354
|
+
severity: medium
|
|
355
|
+
action: warn
|
|
356
|
+
|
|
357
|
+
# Guardrail rules
|
|
358
|
+
rules:
|
|
359
|
+
# Prompt injection detection
|
|
360
|
+
- id: injection-detection
|
|
361
|
+
name: Prompt Injection Detection
|
|
362
|
+
description: Detect and block prompt injection attempts
|
|
363
|
+
type: injection_detection
|
|
364
|
+
enabled: true
|
|
365
|
+
severity: critical
|
|
366
|
+
action: block
|
|
367
|
+
|
|
368
|
+
# PII detection and redaction
|
|
369
|
+
- id: pii-detection
|
|
370
|
+
name: PII Detection
|
|
371
|
+
description: Detect and redact personally identifiable information
|
|
372
|
+
type: pii_detection
|
|
373
|
+
enabled: true
|
|
374
|
+
severity: high
|
|
375
|
+
action: transform
|
|
376
|
+
config:
|
|
377
|
+
redact: true
|
|
378
|
+
allowedTypes: []
|
|
379
|
+
|
|
380
|
+
# Content filtering
|
|
381
|
+
- id: content-filter
|
|
382
|
+
name: Content Filter
|
|
383
|
+
description: Filter harmful content categories
|
|
384
|
+
type: content_filter
|
|
385
|
+
enabled: true
|
|
386
|
+
severity: high
|
|
387
|
+
action: block
|
|
388
|
+
config:
|
|
389
|
+
blockedCategories:
|
|
390
|
+
- violence
|
|
391
|
+
- hate_speech
|
|
392
|
+
- self_harm
|
|
393
|
+
- dangerous
|
|
394
|
+
- illegal
|
|
395
|
+
warnCategories:
|
|
396
|
+
- harassment
|
|
397
|
+
- misinformation
|
|
398
|
+
|
|
399
|
+
# Intent classification
|
|
400
|
+
- id: intent-classification
|
|
401
|
+
name: Intent Classification
|
|
402
|
+
description: Classify and assess risky intents
|
|
403
|
+
type: intent_classification
|
|
404
|
+
enabled: true
|
|
405
|
+
severity: medium
|
|
406
|
+
action: warn
|
|
407
|
+
config:
|
|
408
|
+
blockHighRisk: true
|
|
409
|
+
confidenceThreshold: 0.7
|
|
410
|
+
|
|
411
|
+
# Action/tool validation
|
|
412
|
+
- id: action-validation
|
|
413
|
+
name: Action Validation
|
|
414
|
+
description: Validate agent tool and function calls
|
|
415
|
+
type: action_validation
|
|
416
|
+
enabled: true
|
|
417
|
+
severity: high
|
|
418
|
+
action: block
|
|
419
|
+
config:
|
|
420
|
+
defaultAllow: false
|
|
421
|
+
blockHighRisk: true
|
|
422
|
+
|
|
423
|
+
# Circuit breaker configuration
|
|
424
|
+
circuitBreaker:
|
|
425
|
+
enabled: true
|
|
426
|
+
threshold: 5 # Number of violations to trigger
|
|
427
|
+
windowMs: 60000 # Time window in milliseconds (1 minute)
|
|
428
|
+
cooldownMs: 300000 # Cooldown period (5 minutes)
|
|
429
|
+
halfOpenRequests: 3 # Requests to allow in half-open state
|
|
430
|
+
|
|
431
|
+
# Rate limiting configuration
|
|
432
|
+
rateLimits:
|
|
433
|
+
enabled: true
|
|
434
|
+
requestsPerMinute: 100
|
|
435
|
+
requestsPerHour: 1000
|
|
436
|
+
burstLimit: 20
|
|
437
|
+
|
|
438
|
+
# Cost limiting configuration (optional)
|
|
439
|
+
costLimits:
|
|
440
|
+
enabled: false
|
|
441
|
+
maxCostPerRequest: 0.10
|
|
442
|
+
maxCostPerHour: 10.00
|
|
443
|
+
maxCostPerDay: 100.00
|
|
444
|
+
currency: USD
|
|
445
|
+
`;
|
|
446
|
+
}
|