@safekeylab/sdk 1.0.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.
Files changed (34) hide show
  1. package/README.md +212 -0
  2. package/dist/index.d.mts +100 -0
  3. package/dist/index.d.ts +100 -0
  4. package/dist/index.js +241 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/index.mjs +231 -0
  7. package/dist/index.mjs.map +1 -0
  8. package/dist/integrations/anthropic.d.mts +65 -0
  9. package/dist/integrations/anthropic.d.ts +65 -0
  10. package/dist/integrations/anthropic.js +347 -0
  11. package/dist/integrations/anthropic.js.map +1 -0
  12. package/dist/integrations/anthropic.mjs +341 -0
  13. package/dist/integrations/anthropic.mjs.map +1 -0
  14. package/dist/integrations/langchain.d.mts +106 -0
  15. package/dist/integrations/langchain.d.ts +106 -0
  16. package/dist/integrations/langchain.js +415 -0
  17. package/dist/integrations/langchain.js.map +1 -0
  18. package/dist/integrations/langchain.mjs +406 -0
  19. package/dist/integrations/langchain.mjs.map +1 -0
  20. package/dist/integrations/openai.d.mts +72 -0
  21. package/dist/integrations/openai.d.ts +72 -0
  22. package/dist/integrations/openai.js +327 -0
  23. package/dist/integrations/openai.js.map +1 -0
  24. package/dist/integrations/openai.mjs +321 -0
  25. package/dist/integrations/openai.mjs.map +1 -0
  26. package/dist/integrations/vercel-ai.d.mts +80 -0
  27. package/dist/integrations/vercel-ai.d.ts +80 -0
  28. package/dist/integrations/vercel-ai.js +377 -0
  29. package/dist/integrations/vercel-ai.js.map +1 -0
  30. package/dist/integrations/vercel-ai.mjs +371 -0
  31. package/dist/integrations/vercel-ai.mjs.map +1 -0
  32. package/dist/types-CtDYLaOX.d.mts +129 -0
  33. package/dist/types-CtDYLaOX.d.ts +129 -0
  34. package/package.json +106 -0
@@ -0,0 +1,341 @@
1
+ // src/types.ts
2
+ var SafeKeyLabError = class extends Error {
3
+ constructor(message, code, statusCode) {
4
+ super(message);
5
+ this.code = code;
6
+ this.statusCode = statusCode;
7
+ this.name = "SafeKeyLabError";
8
+ }
9
+ };
10
+ var PIIBlockedError = class extends SafeKeyLabError {
11
+ constructor(detections) {
12
+ super(
13
+ `Request blocked: PII detected (${detections.map((d) => d.type).join(", ")})`,
14
+ "PII_BLOCKED"
15
+ );
16
+ this.detections = detections;
17
+ this.name = "PIIBlockedError";
18
+ }
19
+ };
20
+ var ThreatBlockedError = class extends SafeKeyLabError {
21
+ constructor(threats) {
22
+ super(
23
+ `Request blocked: Threat detected (${threats.map((t) => t.type).join(", ")})`,
24
+ "THREAT_BLOCKED"
25
+ );
26
+ this.threats = threats;
27
+ this.name = "ThreatBlockedError";
28
+ }
29
+ };
30
+
31
+ // src/client.ts
32
+ var DEFAULT_BASE_URL = "https://api.safekeylab.com";
33
+ var DEFAULT_TIMEOUT = 3e4;
34
+ var SafeKeyLab = class {
35
+ constructor(config) {
36
+ if (!config.apiKey) {
37
+ throw new SafeKeyLabError("API key is required", "MISSING_API_KEY");
38
+ }
39
+ this.apiKey = config.apiKey;
40
+ this.baseUrl = config.baseUrl || DEFAULT_BASE_URL;
41
+ this.timeout = config.timeout || DEFAULT_TIMEOUT;
42
+ this.debug = config.debug || false;
43
+ }
44
+ log(...args) {
45
+ if (this.debug) {
46
+ console.log("[SafeKeyLab]", ...args);
47
+ }
48
+ }
49
+ async request(method, endpoint, body) {
50
+ const url = `${this.baseUrl}${endpoint}`;
51
+ const controller = new AbortController();
52
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
53
+ this.log(`${method} ${url}`, body);
54
+ try {
55
+ const response = await fetch(url, {
56
+ method,
57
+ headers: {
58
+ "Authorization": `Bearer ${this.apiKey}`,
59
+ "Content-Type": "application/json",
60
+ "User-Agent": "@safekeylab/sdk/1.0.0"
61
+ },
62
+ body: body ? JSON.stringify(body) : void 0,
63
+ signal: controller.signal
64
+ });
65
+ clearTimeout(timeoutId);
66
+ const data = await response.json();
67
+ if (!response.ok) {
68
+ throw new SafeKeyLabError(
69
+ data.error || data.message || "Request failed",
70
+ data.code || "API_ERROR",
71
+ response.status
72
+ );
73
+ }
74
+ this.log("Response:", data);
75
+ return data;
76
+ } catch (error) {
77
+ clearTimeout(timeoutId);
78
+ if (error instanceof SafeKeyLabError) {
79
+ throw error;
80
+ }
81
+ if (error instanceof Error) {
82
+ if (error.name === "AbortError") {
83
+ throw new SafeKeyLabError("Request timeout", "TIMEOUT");
84
+ }
85
+ throw new SafeKeyLabError(error.message, "NETWORK_ERROR");
86
+ }
87
+ throw new SafeKeyLabError("Unknown error", "UNKNOWN_ERROR");
88
+ }
89
+ }
90
+ /**
91
+ * Detect PII in text
92
+ */
93
+ async detect(request) {
94
+ return this.request("POST", "/v1/detect", request);
95
+ }
96
+ /**
97
+ * Detect PII in text (convenience method)
98
+ */
99
+ async detectPII(text, options) {
100
+ return this.detect({ text, ...options });
101
+ }
102
+ /**
103
+ * Redact/protect PII in text
104
+ */
105
+ async protect(request) {
106
+ return this.request("POST", "/v1/protect", request);
107
+ }
108
+ /**
109
+ * Redact PII from text (convenience method)
110
+ */
111
+ async redact(text, options) {
112
+ const response = await this.protect({ text, ...options });
113
+ return response.redacted_text;
114
+ }
115
+ /**
116
+ * Validate a prompt for security threats
117
+ */
118
+ async validatePrompt(request) {
119
+ return this.request("POST", "/v1/validate-prompt", request);
120
+ }
121
+ /**
122
+ * Check if a prompt is safe (convenience method)
123
+ */
124
+ async isPromptSafe(prompt, context) {
125
+ const response = await this.validatePrompt({ prompt, context });
126
+ return response.is_safe;
127
+ }
128
+ /**
129
+ * Scan LLM output for issues
130
+ */
131
+ async scanOutput(request) {
132
+ return this.request("POST", "/v1/scan-output", request);
133
+ }
134
+ /**
135
+ * Full protection pipeline: validate input, redact PII, return protected text
136
+ */
137
+ async protectInput(text) {
138
+ const [detectResult, validateResult] = await Promise.all([
139
+ this.detect({ text }),
140
+ this.validatePrompt({ prompt: text })
141
+ ]);
142
+ let protectedText = text;
143
+ let wasModified = false;
144
+ if (detectResult.count > 0) {
145
+ const protectResult = await this.protect({ text });
146
+ protectedText = protectResult.redacted_text;
147
+ wasModified = true;
148
+ }
149
+ return {
150
+ text: protectedText,
151
+ wasModified,
152
+ detections: detectResult.detections,
153
+ threats: validateResult.threats
154
+ };
155
+ }
156
+ /**
157
+ * Create a sandbox client (no API key required, rate limited)
158
+ */
159
+ static sandbox(options) {
160
+ return new SafeKeyLabSandbox(options);
161
+ }
162
+ };
163
+ var SafeKeyLabSandbox = class {
164
+ constructor(config) {
165
+ this.baseUrl = config?.baseUrl || DEFAULT_BASE_URL;
166
+ this.timeout = config?.timeout || DEFAULT_TIMEOUT;
167
+ this.debug = config?.debug || false;
168
+ }
169
+ log(...args) {
170
+ if (this.debug) {
171
+ console.log("[SafeKeyLab:Sandbox]", ...args);
172
+ }
173
+ }
174
+ async request(method, endpoint, body) {
175
+ const url = `${this.baseUrl}${endpoint}`;
176
+ const controller = new AbortController();
177
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
178
+ this.log(`${method} ${url}`, body);
179
+ try {
180
+ const response = await fetch(url, {
181
+ method,
182
+ headers: {
183
+ "Content-Type": "application/json",
184
+ "User-Agent": "@safekeylab/sdk/1.0.0"
185
+ },
186
+ body: body ? JSON.stringify(body) : void 0,
187
+ signal: controller.signal
188
+ });
189
+ clearTimeout(timeoutId);
190
+ const data = await response.json();
191
+ if (!response.ok) {
192
+ throw new SafeKeyLabError(
193
+ data.error || data.message || "Request failed",
194
+ data.code || "API_ERROR",
195
+ response.status
196
+ );
197
+ }
198
+ this.log("Response:", data);
199
+ return data;
200
+ } catch (error) {
201
+ clearTimeout(timeoutId);
202
+ if (error instanceof SafeKeyLabError) {
203
+ throw error;
204
+ }
205
+ if (error instanceof Error) {
206
+ if (error.name === "AbortError") {
207
+ throw new SafeKeyLabError("Request timeout", "TIMEOUT");
208
+ }
209
+ throw new SafeKeyLabError(error.message, "NETWORK_ERROR");
210
+ }
211
+ throw new SafeKeyLabError("Unknown error", "UNKNOWN_ERROR");
212
+ }
213
+ }
214
+ async detect(request) {
215
+ return this.request("POST", "/sandbox/v1/detect", request);
216
+ }
217
+ async protect(request) {
218
+ return this.request("POST", "/sandbox/v1/protect", request);
219
+ }
220
+ async validatePrompt(request) {
221
+ return this.request("POST", "/sandbox/v1/validate-prompt", request);
222
+ }
223
+ };
224
+
225
+ // src/integrations/anthropic.ts
226
+ function wrapAnthropic(anthropic, options) {
227
+ const safekeylab = new SafeKeyLab({
228
+ apiKey: options.apiKey,
229
+ baseUrl: options.baseUrl,
230
+ timeout: options.timeout,
231
+ debug: options.debug
232
+ });
233
+ const config = {
234
+ blockOnPII: options.blockOnPII ?? false,
235
+ blockOnThreat: options.blockOnThreat ?? true,
236
+ piiTypes: options.piiTypes,
237
+ scanOutputs: options.scanOutputs ?? true,
238
+ onError: options.onError,
239
+ onPIIDetected: options.onPIIDetected,
240
+ onThreatDetected: options.onThreatDetected
241
+ };
242
+ const originalCreate = anthropic.messages.create.bind(anthropic.messages);
243
+ const protectedCreate = async (params) => {
244
+ const allDetections = [];
245
+ const allThreats = [];
246
+ let protectedSystem = params.system;
247
+ if (params.system) {
248
+ const [detectResult, validateResult] = await Promise.all([
249
+ safekeylab.detect({ text: params.system, types: config.piiTypes }),
250
+ safekeylab.validatePrompt({ prompt: params.system })
251
+ ]);
252
+ if (detectResult.detections.length > 0) {
253
+ allDetections.push(...detectResult.detections);
254
+ config.onPIIDetected?.(detectResult.detections);
255
+ if (config.blockOnPII) {
256
+ throw new PIIBlockedError(detectResult.detections);
257
+ }
258
+ const protectResult = await safekeylab.protect({ text: params.system });
259
+ protectedSystem = protectResult.redacted_text;
260
+ }
261
+ if (validateResult.threats.length > 0) {
262
+ allThreats.push(...validateResult.threats);
263
+ config.onThreatDetected?.(validateResult.threats);
264
+ if (config.blockOnThreat) {
265
+ throw new ThreatBlockedError(validateResult.threats);
266
+ }
267
+ }
268
+ }
269
+ const protectedMessages = await Promise.all(
270
+ params.messages.map(async (message) => {
271
+ const content = extractContent(message.content);
272
+ if (!content) return message;
273
+ const [detectResult, validateResult] = await Promise.all([
274
+ safekeylab.detect({ text: content, types: config.piiTypes }),
275
+ safekeylab.validatePrompt({ prompt: content })
276
+ ]);
277
+ if (detectResult.detections.length > 0) {
278
+ allDetections.push(...detectResult.detections);
279
+ config.onPIIDetected?.(detectResult.detections);
280
+ if (config.blockOnPII) {
281
+ throw new PIIBlockedError(detectResult.detections);
282
+ }
283
+ }
284
+ if (validateResult.threats.length > 0) {
285
+ allThreats.push(...validateResult.threats);
286
+ config.onThreatDetected?.(validateResult.threats);
287
+ if (config.blockOnThreat) {
288
+ throw new ThreatBlockedError(validateResult.threats);
289
+ }
290
+ }
291
+ if (detectResult.detections.length > 0) {
292
+ const protectResult = await safekeylab.protect({ text: content });
293
+ return {
294
+ ...message,
295
+ content: protectResult.redacted_text
296
+ };
297
+ }
298
+ return message;
299
+ })
300
+ );
301
+ const response = await originalCreate({
302
+ ...params,
303
+ system: protectedSystem,
304
+ messages: protectedMessages
305
+ });
306
+ if (config.scanOutputs) {
307
+ const outputText = response.content.filter((block) => block.type === "text" && block.text).map((block) => block.text).join("\n");
308
+ if (outputText) {
309
+ const scanResult = await safekeylab.scanOutput({ output: outputText });
310
+ if (!scanResult.is_safe) {
311
+ response._safekeylab_output_issues = scanResult.issues;
312
+ }
313
+ }
314
+ }
315
+ response._safekeylab = {
316
+ pii_detected: allDetections,
317
+ threats_detected: allThreats,
318
+ inputs_modified: allDetections.length > 0
319
+ };
320
+ return response;
321
+ };
322
+ anthropic.messages.create = protectedCreate;
323
+ return anthropic;
324
+ }
325
+ function extractContent(content) {
326
+ if (typeof content === "string") {
327
+ return content;
328
+ }
329
+ if (Array.isArray(content)) {
330
+ return content.filter((block) => block.type === "text" && block.text).map((block) => block.text).join("\n");
331
+ }
332
+ return null;
333
+ }
334
+ function createProtectedAnthropic(options) {
335
+ return (anthropic) => wrapAnthropic(anthropic, options);
336
+ }
337
+ var anthropic_default = wrapAnthropic;
338
+
339
+ export { createProtectedAnthropic, anthropic_default as default, wrapAnthropic };
340
+ //# sourceMappingURL=anthropic.mjs.map
341
+ //# sourceMappingURL=anthropic.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/types.ts","../../src/client.ts","../../src/integrations/anthropic.ts"],"names":[],"mappings":"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","file":"anthropic.mjs","sourcesContent":["/**\n * SafeKeyLab SDK Types\n */\n\nexport interface SafeKeyLabConfig {\n /** API key for authentication */\n apiKey: string;\n /** Base URL for the API (default: https://api.safekeylab.com) */\n baseUrl?: string;\n /** Request timeout in milliseconds (default: 30000) */\n timeout?: number;\n /** Enable debug logging (default: false) */\n debug?: boolean;\n}\n\nexport interface PIIDetection {\n /** Type of PII detected (EMAIL, PHONE, SSN, etc.) */\n type: string;\n /** The detected value */\n value: string;\n /** Start position in text */\n start: number;\n /** End position in text */\n end: number;\n /** Confidence score (0-1) */\n confidence: number;\n}\n\nexport interface DetectRequest {\n /** Text to scan for PII */\n text: string;\n /** Types of PII to detect (default: all) */\n types?: string[];\n /** Minimum confidence threshold (default: 0.5) */\n minConfidence?: number;\n}\n\nexport interface DetectResponse {\n success: boolean;\n detections: PIIDetection[];\n count: number;\n processing_time_ms: number;\n}\n\nexport interface ProtectRequest {\n /** Text to redact PII from */\n text: string;\n /** Types of PII to redact (default: all) */\n types?: string[];\n /** Redaction style: 'placeholder' | 'mask' | 'hash' (default: placeholder) */\n style?: 'placeholder' | 'mask' | 'hash';\n}\n\nexport interface Redaction {\n type: string;\n original: string;\n start: number;\n end: number;\n}\n\nexport interface ProtectResponse {\n success: boolean;\n redacted_text: string;\n redactions: Redaction[];\n redactions_count: number;\n original_length: number;\n redacted_length: number;\n processing_time_ms: number;\n}\n\nexport interface ValidatePromptRequest {\n /** Prompt to validate */\n prompt: string;\n /** Additional context for validation */\n context?: string;\n}\n\nexport interface Threat {\n type: string;\n severity: 'low' | 'medium' | 'high' | 'critical';\n description: string;\n matched?: string;\n}\n\nexport interface ValidatePromptResponse {\n success: boolean;\n is_safe: boolean;\n threats: Threat[];\n threats_detected: number;\n recommendation: 'allow' | 'review' | 'block';\n processing_time_ms: number;\n}\n\nexport interface ScanOutputRequest {\n /** LLM output to scan */\n output: string;\n /** Original prompt for context */\n prompt?: string;\n}\n\nexport interface ScanOutputResponse {\n success: boolean;\n is_safe: boolean;\n issues: Array<{\n type: string;\n severity: string;\n description: string;\n }>;\n processing_time_ms: number;\n}\n\nexport interface WrapperConfig {\n /** Block requests containing PII (default: false, will redact instead) */\n blockOnPII?: boolean;\n /** Block requests with detected threats (default: true) */\n blockOnThreat?: boolean;\n /** Types of PII to detect/redact */\n piiTypes?: string[];\n /** Scan LLM outputs for issues (default: true) */\n scanOutputs?: boolean;\n /** Custom error handler */\n onError?: (error: Error) => void;\n /** Callback when PII is detected */\n onPIIDetected?: (detections: PIIDetection[]) => void;\n /** Callback when threat is detected */\n onThreatDetected?: (threats: Threat[]) => void;\n}\n\nexport class SafeKeyLabError extends Error {\n constructor(\n message: string,\n public code: string,\n public statusCode?: number\n ) {\n super(message);\n this.name = 'SafeKeyLabError';\n }\n}\n\nexport class PIIBlockedError extends SafeKeyLabError {\n constructor(\n public detections: PIIDetection[]\n ) {\n super(\n `Request blocked: PII detected (${detections.map(d => d.type).join(', ')})`,\n 'PII_BLOCKED'\n );\n this.name = 'PIIBlockedError';\n }\n}\n\nexport class ThreatBlockedError extends SafeKeyLabError {\n constructor(\n public threats: Threat[]\n ) {\n super(\n `Request blocked: Threat detected (${threats.map(t => t.type).join(', ')})`,\n 'THREAT_BLOCKED'\n );\n this.name = 'ThreatBlockedError';\n }\n}\n","/**\n * SafeKeyLab API Client\n */\n\nimport {\n SafeKeyLabConfig,\n DetectRequest,\n DetectResponse,\n ProtectRequest,\n ProtectResponse,\n ValidatePromptRequest,\n ValidatePromptResponse,\n ScanOutputRequest,\n ScanOutputResponse,\n SafeKeyLabError,\n} from './types';\n\nconst DEFAULT_BASE_URL = 'https://api.safekeylab.com';\nconst DEFAULT_TIMEOUT = 30000;\n\nexport class SafeKeyLab {\n private apiKey: string;\n private baseUrl: string;\n private timeout: number;\n private debug: boolean;\n\n constructor(config: SafeKeyLabConfig) {\n if (!config.apiKey) {\n throw new SafeKeyLabError('API key is required', 'MISSING_API_KEY');\n }\n this.apiKey = config.apiKey;\n this.baseUrl = config.baseUrl || DEFAULT_BASE_URL;\n this.timeout = config.timeout || DEFAULT_TIMEOUT;\n this.debug = config.debug || false;\n }\n\n private log(...args: unknown[]): void {\n if (this.debug) {\n console.log('[SafeKeyLab]', ...args);\n }\n }\n\n private async request<T>(\n method: string,\n endpoint: string,\n body?: unknown\n ): Promise<T> {\n const url = `${this.baseUrl}${endpoint}`;\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n this.log(`${method} ${url}`, body);\n\n try {\n const response = await fetch(url, {\n method,\n headers: {\n 'Authorization': `Bearer ${this.apiKey}`,\n 'Content-Type': 'application/json',\n 'User-Agent': '@safekeylab/sdk/1.0.0',\n },\n body: body ? JSON.stringify(body) : undefined,\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n const data = await response.json() as Record<string, unknown>;\n\n if (!response.ok) {\n throw new SafeKeyLabError(\n (data.error as string) || (data.message as string) || 'Request failed',\n (data.code as string) || 'API_ERROR',\n response.status\n );\n }\n\n this.log('Response:', data);\n return data as T;\n } catch (error) {\n clearTimeout(timeoutId);\n if (error instanceof SafeKeyLabError) {\n throw error;\n }\n if (error instanceof Error) {\n if (error.name === 'AbortError') {\n throw new SafeKeyLabError('Request timeout', 'TIMEOUT');\n }\n throw new SafeKeyLabError(error.message, 'NETWORK_ERROR');\n }\n throw new SafeKeyLabError('Unknown error', 'UNKNOWN_ERROR');\n }\n }\n\n /**\n * Detect PII in text\n */\n async detect(request: DetectRequest): Promise<DetectResponse> {\n return this.request<DetectResponse>('POST', '/v1/detect', request);\n }\n\n /**\n * Detect PII in text (convenience method)\n */\n async detectPII(text: string, options?: Omit<DetectRequest, 'text'>): Promise<DetectResponse> {\n return this.detect({ text, ...options });\n }\n\n /**\n * Redact/protect PII in text\n */\n async protect(request: ProtectRequest): Promise<ProtectResponse> {\n return this.request<ProtectResponse>('POST', '/v1/protect', request);\n }\n\n /**\n * Redact PII from text (convenience method)\n */\n async redact(text: string, options?: Omit<ProtectRequest, 'text'>): Promise<string> {\n const response = await this.protect({ text, ...options });\n return response.redacted_text;\n }\n\n /**\n * Validate a prompt for security threats\n */\n async validatePrompt(request: ValidatePromptRequest): Promise<ValidatePromptResponse> {\n return this.request<ValidatePromptResponse>('POST', '/v1/validate-prompt', request);\n }\n\n /**\n * Check if a prompt is safe (convenience method)\n */\n async isPromptSafe(prompt: string, context?: string): Promise<boolean> {\n const response = await this.validatePrompt({ prompt, context });\n return response.is_safe;\n }\n\n /**\n * Scan LLM output for issues\n */\n async scanOutput(request: ScanOutputRequest): Promise<ScanOutputResponse> {\n return this.request<ScanOutputResponse>('POST', '/v1/scan-output', request);\n }\n\n /**\n * Full protection pipeline: validate input, redact PII, return protected text\n */\n async protectInput(text: string): Promise<{\n text: string;\n wasModified: boolean;\n detections: DetectResponse['detections'];\n threats: ValidatePromptResponse['threats'];\n }> {\n // Run detection and validation in parallel\n const [detectResult, validateResult] = await Promise.all([\n this.detect({ text }),\n this.validatePrompt({ prompt: text }),\n ]);\n\n let protectedText = text;\n let wasModified = false;\n\n // Redact if PII found\n if (detectResult.count > 0) {\n const protectResult = await this.protect({ text });\n protectedText = protectResult.redacted_text;\n wasModified = true;\n }\n\n return {\n text: protectedText,\n wasModified,\n detections: detectResult.detections,\n threats: validateResult.threats,\n };\n }\n\n /**\n * Create a sandbox client (no API key required, rate limited)\n */\n static sandbox(options?: Omit<SafeKeyLabConfig, 'apiKey'>): SafeKeyLabSandbox {\n return new SafeKeyLabSandbox(options);\n }\n}\n\n/**\n * Sandbox client for testing (no API key required)\n */\nexport class SafeKeyLabSandbox {\n private baseUrl: string;\n private timeout: number;\n private debug: boolean;\n\n constructor(config?: Omit<SafeKeyLabConfig, 'apiKey'>) {\n this.baseUrl = config?.baseUrl || DEFAULT_BASE_URL;\n this.timeout = config?.timeout || DEFAULT_TIMEOUT;\n this.debug = config?.debug || false;\n }\n\n private log(...args: unknown[]): void {\n if (this.debug) {\n console.log('[SafeKeyLab:Sandbox]', ...args);\n }\n }\n\n private async request<T>(\n method: string,\n endpoint: string,\n body?: unknown\n ): Promise<T> {\n const url = `${this.baseUrl}${endpoint}`;\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n this.log(`${method} ${url}`, body);\n\n try {\n const response = await fetch(url, {\n method,\n headers: {\n 'Content-Type': 'application/json',\n 'User-Agent': '@safekeylab/sdk/1.0.0',\n },\n body: body ? JSON.stringify(body) : undefined,\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n const data = await response.json() as Record<string, unknown>;\n\n if (!response.ok) {\n throw new SafeKeyLabError(\n (data.error as string) || (data.message as string) || 'Request failed',\n (data.code as string) || 'API_ERROR',\n response.status\n );\n }\n\n this.log('Response:', data);\n return data as T;\n } catch (error) {\n clearTimeout(timeoutId);\n if (error instanceof SafeKeyLabError) {\n throw error;\n }\n if (error instanceof Error) {\n if (error.name === 'AbortError') {\n throw new SafeKeyLabError('Request timeout', 'TIMEOUT');\n }\n throw new SafeKeyLabError(error.message, 'NETWORK_ERROR');\n }\n throw new SafeKeyLabError('Unknown error', 'UNKNOWN_ERROR');\n }\n }\n\n async detect(request: DetectRequest): Promise<DetectResponse> {\n return this.request<DetectResponse>('POST', '/sandbox/v1/detect', request);\n }\n\n async protect(request: ProtectRequest): Promise<ProtectResponse> {\n return this.request<ProtectResponse>('POST', '/sandbox/v1/protect', request);\n }\n\n async validatePrompt(request: ValidatePromptRequest): Promise<ValidatePromptResponse> {\n return this.request<ValidatePromptResponse>('POST', '/sandbox/v1/validate-prompt', request);\n }\n}\n\nexport default SafeKeyLab;\n","/**\n * SafeKeyLab Anthropic Integration\n *\n * Wraps the Anthropic client to automatically protect inputs and scan outputs\n *\n * @example\n * ```typescript\n * import Anthropic from '@anthropic-ai/sdk';\n * import { wrapAnthropic } from '@safekeylab/sdk/anthropic';\n *\n * const anthropic = wrapAnthropic(new Anthropic(), {\n * apiKey: 'sk_live_...',\n * });\n *\n * // All calls are now protected\n * const response = await anthropic.messages.create({\n * model: 'claude-3-opus-20240229',\n * max_tokens: 1024,\n * messages: [{ role: 'user', content: 'My SSN is 123-45-6789' }],\n * });\n * // Input is automatically redacted to: \"My SSN is [SSN]\"\n * ```\n */\n\nimport { SafeKeyLab } from '../client';\nimport {\n SafeKeyLabConfig,\n WrapperConfig,\n PIIDetection,\n Threat,\n PIIBlockedError,\n ThreatBlockedError,\n} from '../types';\n\n// Type definitions for Anthropic SDK\ninterface AnthropicContentBlock {\n type: string;\n text?: string;\n [key: string]: unknown;\n}\n\ninterface AnthropicMessage {\n role: 'user' | 'assistant';\n content: string | AnthropicContentBlock[];\n}\n\ninterface AnthropicMessageParams {\n model: string;\n max_tokens: number;\n messages: AnthropicMessage[];\n system?: string;\n [key: string]: unknown;\n}\n\ninterface AnthropicMessageResponse {\n content: AnthropicContentBlock[];\n [key: string]: unknown;\n}\n\ninterface AnthropicMessages {\n create(params: AnthropicMessageParams): Promise<AnthropicMessageResponse>;\n}\n\ninterface AnthropicClient {\n messages: AnthropicMessages;\n [key: string]: unknown;\n}\n\nexport interface AnthropicWrapperOptions extends Partial<SafeKeyLabConfig>, WrapperConfig {}\n\n/**\n * Wrap an Anthropic client with SafeKeyLab protection\n */\nexport function wrapAnthropic<T extends AnthropicClient>(\n anthropic: T,\n options: AnthropicWrapperOptions\n): T {\n const safekeylab = new SafeKeyLab({\n apiKey: options.apiKey!,\n baseUrl: options.baseUrl,\n timeout: options.timeout,\n debug: options.debug,\n });\n\n const config: WrapperConfig = {\n blockOnPII: options.blockOnPII ?? false,\n blockOnThreat: options.blockOnThreat ?? true,\n piiTypes: options.piiTypes,\n scanOutputs: options.scanOutputs ?? true,\n onError: options.onError,\n onPIIDetected: options.onPIIDetected,\n onThreatDetected: options.onThreatDetected,\n };\n\n const originalCreate = anthropic.messages.create.bind(anthropic.messages);\n\n const protectedCreate = async (\n params: AnthropicMessageParams\n ): Promise<AnthropicMessageResponse> => {\n const allDetections: PIIDetection[] = [];\n const allThreats: Threat[] = [];\n\n // Process system prompt if present\n let protectedSystem = params.system;\n if (params.system) {\n const [detectResult, validateResult] = await Promise.all([\n safekeylab.detect({ text: params.system, types: config.piiTypes }),\n safekeylab.validatePrompt({ prompt: params.system }),\n ]);\n\n if (detectResult.detections.length > 0) {\n allDetections.push(...detectResult.detections);\n config.onPIIDetected?.(detectResult.detections);\n\n if (config.blockOnPII) {\n throw new PIIBlockedError(detectResult.detections);\n }\n\n const protectResult = await safekeylab.protect({ text: params.system });\n protectedSystem = protectResult.redacted_text;\n }\n\n if (validateResult.threats.length > 0) {\n allThreats.push(...validateResult.threats);\n config.onThreatDetected?.(validateResult.threats);\n\n if (config.blockOnThreat) {\n throw new ThreatBlockedError(validateResult.threats);\n }\n }\n }\n\n // Process each message\n const protectedMessages = await Promise.all(\n params.messages.map(async (message) => {\n const content = extractContent(message.content);\n if (!content) return message;\n\n const [detectResult, validateResult] = await Promise.all([\n safekeylab.detect({ text: content, types: config.piiTypes }),\n safekeylab.validatePrompt({ prompt: content }),\n ]);\n\n if (detectResult.detections.length > 0) {\n allDetections.push(...detectResult.detections);\n config.onPIIDetected?.(detectResult.detections);\n\n if (config.blockOnPII) {\n throw new PIIBlockedError(detectResult.detections);\n }\n }\n\n if (validateResult.threats.length > 0) {\n allThreats.push(...validateResult.threats);\n config.onThreatDetected?.(validateResult.threats);\n\n if (config.blockOnThreat) {\n throw new ThreatBlockedError(validateResult.threats);\n }\n }\n\n if (detectResult.detections.length > 0) {\n const protectResult = await safekeylab.protect({ text: content });\n return {\n ...message,\n content: protectResult.redacted_text,\n };\n }\n\n return message;\n })\n );\n\n // Make the API call with protected messages\n const response = await originalCreate({\n ...params,\n system: protectedSystem,\n messages: protectedMessages,\n });\n\n // Scan outputs if enabled\n if (config.scanOutputs) {\n const outputText = response.content\n .filter((block) => block.type === 'text' && block.text)\n .map((block) => block.text)\n .join('\\n');\n\n if (outputText) {\n const scanResult = await safekeylab.scanOutput({ output: outputText });\n if (!scanResult.is_safe) {\n (response as Record<string, unknown>)._safekeylab_output_issues = scanResult.issues;\n }\n }\n }\n\n // Attach metadata\n (response as Record<string, unknown>)._safekeylab = {\n pii_detected: allDetections,\n threats_detected: allThreats,\n inputs_modified: allDetections.length > 0,\n };\n\n return response;\n };\n\n anthropic.messages.create = protectedCreate as typeof anthropic.messages.create;\n\n return anthropic;\n}\n\n/**\n * Extract text content from Anthropic message content\n */\nfunction extractContent(content: string | AnthropicContentBlock[]): string | null {\n if (typeof content === 'string') {\n return content;\n }\n if (Array.isArray(content)) {\n return content\n .filter((block) => block.type === 'text' && block.text)\n .map((block) => block.text)\n .join('\\n');\n }\n return null;\n}\n\n/**\n * Create a protected Anthropic client factory\n */\nexport function createProtectedAnthropic(options: AnthropicWrapperOptions) {\n return <T extends AnthropicClient>(anthropic: T): T => wrapAnthropic(anthropic, options);\n}\n\nexport default wrapAnthropic;\n"]}
@@ -0,0 +1,106 @@
1
+ import { S as SafeKeyLabConfig, f as PIIDetection, T as Threat } from '../types-CtDYLaOX.mjs';
2
+
3
+ /**
4
+ * SafeKeyLab LangChain Integration
5
+ *
6
+ * Provides callbacks and tools for LangChain/LangChain.js
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * import { ChatOpenAI } from '@langchain/openai';
11
+ * import { SafeKeyLabCallbackHandler, createPIIProtectionTool } from '@safekeylab/sdk/langchain';
12
+ *
13
+ * const handler = new SafeKeyLabCallbackHandler({ apiKey: 'sk_live_...' });
14
+ * const model = new ChatOpenAI({ callbacks: [handler] });
15
+ *
16
+ * // Or use tools in an agent
17
+ * const tools = [createPIIProtectionTool({ apiKey: 'sk_live_...' })];
18
+ * ```
19
+ */
20
+
21
+ interface Serialized {
22
+ [key: string]: unknown;
23
+ }
24
+ interface LLMResult {
25
+ generations: Array<Array<{
26
+ text: string;
27
+ [key: string]: unknown;
28
+ }>>;
29
+ [key: string]: unknown;
30
+ }
31
+ interface SafeKeyLabCallbackConfig extends Partial<SafeKeyLabConfig> {
32
+ /** Block on PII detection (default: false, will log instead) */
33
+ blockOnPII?: boolean;
34
+ /** Block on threat detection (default: true) */
35
+ blockOnThreat?: boolean;
36
+ /** Types of PII to detect */
37
+ piiTypes?: string[];
38
+ }
39
+ /**
40
+ * LangChain callback handler for SafeKeyLab protection
41
+ */
42
+ declare class SafeKeyLabCallbackHandler {
43
+ private client;
44
+ private config;
45
+ private detections;
46
+ private threats;
47
+ name: string;
48
+ ignoreLLM: boolean;
49
+ ignoreChain: boolean;
50
+ ignoreAgent: boolean;
51
+ ignoreRetriever: boolean;
52
+ constructor(config: SafeKeyLabCallbackConfig);
53
+ /**
54
+ * Called when LLM starts processing
55
+ */
56
+ handleLLMStart(llm: Serialized, prompts: string[], runId: string): Promise<void>;
57
+ /**
58
+ * Called when chat model starts
59
+ */
60
+ handleChatModelStart(llm: Serialized, messages: Array<Array<{
61
+ content: string;
62
+ [key: string]: unknown;
63
+ }>>, runId: string): Promise<void>;
64
+ /**
65
+ * Called when LLM ends
66
+ */
67
+ handleLLMEnd(output: LLMResult, runId: string): Promise<void>;
68
+ /**
69
+ * Get all detections from this session
70
+ */
71
+ getDetections(): PIIDetection[];
72
+ /**
73
+ * Get all threats from this session
74
+ */
75
+ getThreats(): Threat[];
76
+ /**
77
+ * Clear detection history
78
+ */
79
+ clearHistory(): void;
80
+ }
81
+ /**
82
+ * LangChain tool interface
83
+ */
84
+ interface ToolConfig {
85
+ name: string;
86
+ description: string;
87
+ func: (input: string) => Promise<string>;
88
+ }
89
+ /**
90
+ * Create a PII protection tool for LangChain agents
91
+ */
92
+ declare function createPIIProtectionTool(config: Partial<SafeKeyLabConfig>): ToolConfig;
93
+ /**
94
+ * Create a PII detection tool for LangChain agents
95
+ */
96
+ declare function createPIIDetectionTool(config: Partial<SafeKeyLabConfig>): ToolConfig;
97
+ /**
98
+ * Create a prompt validation tool for LangChain agents
99
+ */
100
+ declare function createPromptValidationTool(config: Partial<SafeKeyLabConfig>): ToolConfig;
101
+ /**
102
+ * Get all SafeKeyLab tools for use in LangChain agents
103
+ */
104
+ declare function getSafeKeyLabTools(config: Partial<SafeKeyLabConfig>): ToolConfig[];
105
+
106
+ export { type SafeKeyLabCallbackConfig, SafeKeyLabCallbackHandler, createPIIDetectionTool, createPIIProtectionTool, createPromptValidationTool, SafeKeyLabCallbackHandler as default, getSafeKeyLabTools };
@@ -0,0 +1,106 @@
1
+ import { S as SafeKeyLabConfig, f as PIIDetection, T as Threat } from '../types-CtDYLaOX.js';
2
+
3
+ /**
4
+ * SafeKeyLab LangChain Integration
5
+ *
6
+ * Provides callbacks and tools for LangChain/LangChain.js
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * import { ChatOpenAI } from '@langchain/openai';
11
+ * import { SafeKeyLabCallbackHandler, createPIIProtectionTool } from '@safekeylab/sdk/langchain';
12
+ *
13
+ * const handler = new SafeKeyLabCallbackHandler({ apiKey: 'sk_live_...' });
14
+ * const model = new ChatOpenAI({ callbacks: [handler] });
15
+ *
16
+ * // Or use tools in an agent
17
+ * const tools = [createPIIProtectionTool({ apiKey: 'sk_live_...' })];
18
+ * ```
19
+ */
20
+
21
+ interface Serialized {
22
+ [key: string]: unknown;
23
+ }
24
+ interface LLMResult {
25
+ generations: Array<Array<{
26
+ text: string;
27
+ [key: string]: unknown;
28
+ }>>;
29
+ [key: string]: unknown;
30
+ }
31
+ interface SafeKeyLabCallbackConfig extends Partial<SafeKeyLabConfig> {
32
+ /** Block on PII detection (default: false, will log instead) */
33
+ blockOnPII?: boolean;
34
+ /** Block on threat detection (default: true) */
35
+ blockOnThreat?: boolean;
36
+ /** Types of PII to detect */
37
+ piiTypes?: string[];
38
+ }
39
+ /**
40
+ * LangChain callback handler for SafeKeyLab protection
41
+ */
42
+ declare class SafeKeyLabCallbackHandler {
43
+ private client;
44
+ private config;
45
+ private detections;
46
+ private threats;
47
+ name: string;
48
+ ignoreLLM: boolean;
49
+ ignoreChain: boolean;
50
+ ignoreAgent: boolean;
51
+ ignoreRetriever: boolean;
52
+ constructor(config: SafeKeyLabCallbackConfig);
53
+ /**
54
+ * Called when LLM starts processing
55
+ */
56
+ handleLLMStart(llm: Serialized, prompts: string[], runId: string): Promise<void>;
57
+ /**
58
+ * Called when chat model starts
59
+ */
60
+ handleChatModelStart(llm: Serialized, messages: Array<Array<{
61
+ content: string;
62
+ [key: string]: unknown;
63
+ }>>, runId: string): Promise<void>;
64
+ /**
65
+ * Called when LLM ends
66
+ */
67
+ handleLLMEnd(output: LLMResult, runId: string): Promise<void>;
68
+ /**
69
+ * Get all detections from this session
70
+ */
71
+ getDetections(): PIIDetection[];
72
+ /**
73
+ * Get all threats from this session
74
+ */
75
+ getThreats(): Threat[];
76
+ /**
77
+ * Clear detection history
78
+ */
79
+ clearHistory(): void;
80
+ }
81
+ /**
82
+ * LangChain tool interface
83
+ */
84
+ interface ToolConfig {
85
+ name: string;
86
+ description: string;
87
+ func: (input: string) => Promise<string>;
88
+ }
89
+ /**
90
+ * Create a PII protection tool for LangChain agents
91
+ */
92
+ declare function createPIIProtectionTool(config: Partial<SafeKeyLabConfig>): ToolConfig;
93
+ /**
94
+ * Create a PII detection tool for LangChain agents
95
+ */
96
+ declare function createPIIDetectionTool(config: Partial<SafeKeyLabConfig>): ToolConfig;
97
+ /**
98
+ * Create a prompt validation tool for LangChain agents
99
+ */
100
+ declare function createPromptValidationTool(config: Partial<SafeKeyLabConfig>): ToolConfig;
101
+ /**
102
+ * Get all SafeKeyLab tools for use in LangChain agents
103
+ */
104
+ declare function getSafeKeyLabTools(config: Partial<SafeKeyLabConfig>): ToolConfig[];
105
+
106
+ export { type SafeKeyLabCallbackConfig, SafeKeyLabCallbackHandler, createPIIDetectionTool, createPIIProtectionTool, createPromptValidationTool, SafeKeyLabCallbackHandler as default, getSafeKeyLabTools };