@lockllm/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.
- package/CHANGELOG.md +81 -0
- package/CODE_OF_CONDUCT.md +130 -0
- package/CONTRIBUTING.md +259 -0
- package/LICENSE +21 -0
- package/README.md +928 -0
- package/SECURITY.md +261 -0
- package/dist/client.d.ts +39 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +65 -0
- package/dist/client.js.map +1 -0
- package/dist/client.mjs +61 -0
- package/dist/errors.d.ts +60 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +175 -0
- package/dist/errors.js.map +1 -0
- package/dist/errors.mjs +164 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +49 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +17 -0
- package/dist/scan.d.ts +32 -0
- package/dist/scan.d.ts.map +1 -0
- package/dist/scan.js +40 -0
- package/dist/scan.js.map +1 -0
- package/dist/scan.mjs +36 -0
- package/dist/types/common.d.ts +31 -0
- package/dist/types/common.d.ts.map +1 -0
- package/dist/types/common.js +6 -0
- package/dist/types/common.js.map +1 -0
- package/dist/types/common.mjs +5 -0
- package/dist/types/errors.d.ts +22 -0
- package/dist/types/errors.d.ts.map +1 -0
- package/dist/types/errors.js +6 -0
- package/dist/types/errors.js.map +1 -0
- package/dist/types/errors.mjs +5 -0
- package/dist/types/providers.d.ts +24 -0
- package/dist/types/providers.d.ts.map +1 -0
- package/dist/types/providers.js +26 -0
- package/dist/types/providers.js.map +1 -0
- package/dist/types/providers.mjs +23 -0
- package/dist/types/scan.d.ts +36 -0
- package/dist/types/scan.d.ts.map +1 -0
- package/dist/types/scan.js +6 -0
- package/dist/types/scan.js.map +1 -0
- package/dist/types/scan.mjs +5 -0
- package/dist/utils.d.ts +84 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +225 -0
- package/dist/utils.js.map +1 -0
- package/dist/utils.mjs +215 -0
- package/dist/wrappers/anthropic-wrapper.d.ts +72 -0
- package/dist/wrappers/anthropic-wrapper.d.ts.map +1 -0
- package/dist/wrappers/anthropic-wrapper.js +78 -0
- package/dist/wrappers/anthropic-wrapper.js.map +1 -0
- package/dist/wrappers/anthropic-wrapper.mjs +74 -0
- package/dist/wrappers/generic-wrapper.d.ts +180 -0
- package/dist/wrappers/generic-wrapper.d.ts.map +1 -0
- package/dist/wrappers/generic-wrapper.js +246 -0
- package/dist/wrappers/generic-wrapper.js.map +1 -0
- package/dist/wrappers/generic-wrapper.mjs +225 -0
- package/dist/wrappers/index.d.ts +27 -0
- package/dist/wrappers/index.d.ts.map +1 -0
- package/dist/wrappers/index.js +48 -0
- package/dist/wrappers/index.js.map +1 -0
- package/dist/wrappers/index.mjs +26 -0
- package/dist/wrappers/openai-wrapper.d.ts +70 -0
- package/dist/wrappers/openai-wrapper.d.ts.map +1 -0
- package/dist/wrappers/openai-wrapper.js +76 -0
- package/dist/wrappers/openai-wrapper.js.map +1 -0
- package/dist/wrappers/openai-wrapper.mjs +72 -0
- package/package.json +106 -0
package/SECURITY.md
ADDED
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
# Security Policy
|
|
2
|
+
|
|
3
|
+
## Reporting Security Vulnerabilities
|
|
4
|
+
|
|
5
|
+
LockLLM takes security seriously. We appreciate your efforts to responsibly disclose your findings and will make every effort to acknowledge your contributions.
|
|
6
|
+
|
|
7
|
+
### How to Report a Vulnerability
|
|
8
|
+
|
|
9
|
+
**DO NOT** report security vulnerabilities through public GitHub issues.
|
|
10
|
+
|
|
11
|
+
Instead, please report security vulnerabilities by emailing:
|
|
12
|
+
|
|
13
|
+
**support@lockllm.com**
|
|
14
|
+
|
|
15
|
+
### What to Include in Your Report
|
|
16
|
+
|
|
17
|
+
Please include the following information to help us better understand and address the issue:
|
|
18
|
+
|
|
19
|
+
- **Type of vulnerability** (e.g., injection, authentication bypass, data exposure)
|
|
20
|
+
- **Full paths of source file(s)** related to the vulnerability
|
|
21
|
+
- **Location of the affected source code** (tag/branch/commit or direct URL)
|
|
22
|
+
- **Step-by-step instructions** to reproduce the issue
|
|
23
|
+
- **Proof-of-concept or exploit code** (if possible)
|
|
24
|
+
- **Impact assessment** - what an attacker could achieve
|
|
25
|
+
- **Suggested remediation** (if you have ideas)
|
|
26
|
+
|
|
27
|
+
### Response Timeline
|
|
28
|
+
|
|
29
|
+
- **Initial Response**: Within 48 hours of report submission
|
|
30
|
+
- **Status Update**: Within 7 days with assessment and next steps
|
|
31
|
+
- **Resolution**: Depends on severity and complexity, typically 30-90 days
|
|
32
|
+
|
|
33
|
+
### What to Expect
|
|
34
|
+
|
|
35
|
+
1. **Acknowledgment** - We will confirm receipt of your vulnerability report
|
|
36
|
+
2. **Assessment** - We will evaluate the vulnerability and its impact
|
|
37
|
+
3. **Remediation** - We will develop and test a fix
|
|
38
|
+
4. **Disclosure** - We will coordinate the public disclosure with you
|
|
39
|
+
5. **Credit** - We will acknowledge your contribution (unless you prefer to remain anonymous)
|
|
40
|
+
|
|
41
|
+
## Supported Versions
|
|
42
|
+
|
|
43
|
+
We provide security updates for the following versions:
|
|
44
|
+
|
|
45
|
+
| Version | Supported |
|
|
46
|
+
| ------- | ------------------ |
|
|
47
|
+
| 1.1.x | :white_check_mark: |
|
|
48
|
+
| 1.0.x | :white_check_mark: |
|
|
49
|
+
| < 1.0 | :x: |
|
|
50
|
+
|
|
51
|
+
## Security Best Practices for Users
|
|
52
|
+
|
|
53
|
+
### API Key Security
|
|
54
|
+
|
|
55
|
+
**LockLLM API Keys**
|
|
56
|
+
- Never commit API keys to version control
|
|
57
|
+
- Use environment variables for storing keys
|
|
58
|
+
- Rotate keys regularly through the dashboard
|
|
59
|
+
- Revoke compromised keys immediately at https://www.lockllm.com/dashboard
|
|
60
|
+
|
|
61
|
+
**Provider API Keys**
|
|
62
|
+
- Only add provider keys through the LockLLM dashboard
|
|
63
|
+
- Never include provider keys in your application code
|
|
64
|
+
- Keys are encrypted at rest with AES-256
|
|
65
|
+
- Monitor key usage through the dashboard
|
|
66
|
+
|
|
67
|
+
### Rate Limiting
|
|
68
|
+
|
|
69
|
+
- Implement rate limiting in your application
|
|
70
|
+
- Use the SDK's built-in retry logic for transient failures
|
|
71
|
+
- Monitor `RateLimitError` exceptions and adjust as needed
|
|
72
|
+
- Contact support@lockllm.com for rate limit increases
|
|
73
|
+
|
|
74
|
+
### Error Handling
|
|
75
|
+
|
|
76
|
+
- Always handle `PromptInjectionError` gracefully
|
|
77
|
+
- Log security incidents without exposing sensitive data
|
|
78
|
+
- Use request IDs for incident investigation
|
|
79
|
+
- Implement monitoring for security events
|
|
80
|
+
|
|
81
|
+
**Secure Error Handling Example:**
|
|
82
|
+
```typescript
|
|
83
|
+
try {
|
|
84
|
+
const response = await client.chat.completions.create({
|
|
85
|
+
model: "gpt-4",
|
|
86
|
+
messages: [{ role: "user", content: userInput }]
|
|
87
|
+
});
|
|
88
|
+
} catch (error) {
|
|
89
|
+
if (error instanceof PromptInjectionError) {
|
|
90
|
+
// Log securely - don't expose user input in logs
|
|
91
|
+
logger.warn('Security threat detected', {
|
|
92
|
+
requestId: error.requestId,
|
|
93
|
+
confidence: error.scanResult.injection,
|
|
94
|
+
timestamp: new Date()
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
// Return user-friendly error
|
|
98
|
+
return res.status(400).json({
|
|
99
|
+
error: 'Invalid input detected. Please try again.'
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Input Validation
|
|
106
|
+
|
|
107
|
+
- Always scan user input before passing to LLMs
|
|
108
|
+
- Use appropriate sensitivity levels for your use case
|
|
109
|
+
- Implement additional validation for high-risk applications
|
|
110
|
+
- Consider scanning retrieved documents and external content
|
|
111
|
+
|
|
112
|
+
### Secure Configuration
|
|
113
|
+
|
|
114
|
+
```typescript
|
|
115
|
+
// Good - Use environment variables
|
|
116
|
+
const client = new LockLLM({
|
|
117
|
+
apiKey: process.env.LOCKLLM_API_KEY,
|
|
118
|
+
timeout: 30000,
|
|
119
|
+
maxRetries: 3
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
// Bad - Hardcoded keys
|
|
123
|
+
const client = new LockLLM({
|
|
124
|
+
apiKey: 'llm_abc123...' // Never do this!
|
|
125
|
+
});
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Network Security
|
|
129
|
+
|
|
130
|
+
- Always use HTTPS in production
|
|
131
|
+
- Implement request timeout protection
|
|
132
|
+
- Use the SDK's built-in retry logic
|
|
133
|
+
- Monitor network errors and patterns
|
|
134
|
+
|
|
135
|
+
### Monitoring and Logging
|
|
136
|
+
|
|
137
|
+
**What to Log:**
|
|
138
|
+
- Security incidents (blocked requests)
|
|
139
|
+
- Authentication failures
|
|
140
|
+
- Rate limit hits
|
|
141
|
+
- Request IDs for debugging
|
|
142
|
+
|
|
143
|
+
**What NOT to Log:**
|
|
144
|
+
- API keys
|
|
145
|
+
- Full user prompts (only metadata)
|
|
146
|
+
- Provider API keys
|
|
147
|
+
- Personal information
|
|
148
|
+
|
|
149
|
+
## Security Features
|
|
150
|
+
|
|
151
|
+
### Data Privacy
|
|
152
|
+
|
|
153
|
+
- **Zero Storage**: Prompts are never stored, only scanned in-memory
|
|
154
|
+
- **Metadata Only**: Only non-sensitive metadata is logged
|
|
155
|
+
- **Encryption**: All data encrypted in transit (TLS 1.3)
|
|
156
|
+
- **Compliance**: GDPR and SOC 2 compliant architecture
|
|
157
|
+
|
|
158
|
+
### Authentication
|
|
159
|
+
|
|
160
|
+
- Bearer token authentication for all API requests
|
|
161
|
+
- API keys encrypted with AES-256 at rest
|
|
162
|
+
- Keys never exposed in responses or logs
|
|
163
|
+
- Easy rotation through dashboard
|
|
164
|
+
|
|
165
|
+
### Threat Detection
|
|
166
|
+
|
|
167
|
+
- **Prompt Injection**: ML-based detection of injection attacks
|
|
168
|
+
- **Jailbreak Detection**: Identifies policy bypass attempts
|
|
169
|
+
- **System Prompt Extraction**: Prevents secret leakage
|
|
170
|
+
- **Tool Abuse**: Detects agent hijacking
|
|
171
|
+
- **RAG Injection**: Scans for poisoned context
|
|
172
|
+
- **Obfuscation**: Catches encoded attacks
|
|
173
|
+
|
|
174
|
+
## Known Limitations
|
|
175
|
+
|
|
176
|
+
### Network Security
|
|
177
|
+
- SDK relies on TLS for transport security
|
|
178
|
+
- Custom baseURL configurations are not validated
|
|
179
|
+
- Users are responsible for network-level security
|
|
180
|
+
|
|
181
|
+
### Rate Limiting
|
|
182
|
+
- Free tier: 1,000 requests per minute
|
|
183
|
+
- Aggressive retry logic may compound rate limit issues
|
|
184
|
+
- Monitor rate limit errors in production
|
|
185
|
+
|
|
186
|
+
### Input Size
|
|
187
|
+
- Maximum input size: 100,000 characters
|
|
188
|
+
- Larger inputs may be chunked (affects latency)
|
|
189
|
+
- Performance degrades with very large inputs
|
|
190
|
+
|
|
191
|
+
## Disclosure Policy
|
|
192
|
+
|
|
193
|
+
### Coordinated Disclosure
|
|
194
|
+
|
|
195
|
+
We follow responsible disclosure principles:
|
|
196
|
+
|
|
197
|
+
1. **Private Notification** - We will notify you before public disclosure
|
|
198
|
+
2. **Coordination** - We will work with you on disclosure timing
|
|
199
|
+
3. **Credit** - We will credit you in release notes (unless anonymous)
|
|
200
|
+
4. **Timeline** - Typically 90 days from report to public disclosure
|
|
201
|
+
|
|
202
|
+
### Public Disclosure
|
|
203
|
+
|
|
204
|
+
After a fix is released:
|
|
205
|
+
|
|
206
|
+
- **Security Advisory** - Published on GitHub
|
|
207
|
+
- **CVE Assignment** - For critical vulnerabilities
|
|
208
|
+
- **Release Notes** - Included in CHANGELOG.md
|
|
209
|
+
- **Blog Post** - For significant vulnerabilities
|
|
210
|
+
|
|
211
|
+
## Security Updates
|
|
212
|
+
|
|
213
|
+
### How to Stay Informed
|
|
214
|
+
|
|
215
|
+
- Watch the GitHub repository for security advisories
|
|
216
|
+
- Subscribe to security notifications at https://www.lockllm.com/security
|
|
217
|
+
- Follow @lockllm on Twitter for announcements
|
|
218
|
+
- Monitor CHANGELOG.md for security fixes
|
|
219
|
+
|
|
220
|
+
### Updating the SDK
|
|
221
|
+
|
|
222
|
+
```bash
|
|
223
|
+
# Check current version
|
|
224
|
+
npm list lockllm
|
|
225
|
+
|
|
226
|
+
# Update to latest version
|
|
227
|
+
npm update lockllm
|
|
228
|
+
|
|
229
|
+
# Or install specific version
|
|
230
|
+
npm install lockllm@1.1.0
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
## Bug Bounty Program
|
|
234
|
+
|
|
235
|
+
We currently do not have a formal bug bounty program. However, we deeply appreciate security researchers and will:
|
|
236
|
+
|
|
237
|
+
- Acknowledge your contribution publicly (unless you prefer anonymity)
|
|
238
|
+
- Provide swag and credits for significant findings
|
|
239
|
+
- Consider financial compensation for critical vulnerabilities on a case-by-case basis
|
|
240
|
+
|
|
241
|
+
## Security Audits
|
|
242
|
+
|
|
243
|
+
LockLLM undergoes regular security assessments:
|
|
244
|
+
|
|
245
|
+
- **Code Reviews**: All code changes reviewed for security implications
|
|
246
|
+
- **Dependency Audits**: Automated scanning of dependencies
|
|
247
|
+
- **Penetration Testing**: Annual third-party security assessments
|
|
248
|
+
- **Compliance Reviews**: Regular GDPR and SOC 2 compliance checks
|
|
249
|
+
|
|
250
|
+
## Questions?
|
|
251
|
+
|
|
252
|
+
For general security questions or concerns:
|
|
253
|
+
|
|
254
|
+
- **General Support**: support@lockllm.com
|
|
255
|
+
- **Documentation**: https://www.lockllm.com/docs
|
|
256
|
+
|
|
257
|
+
---
|
|
258
|
+
|
|
259
|
+
**Last Updated**: January 2026
|
|
260
|
+
|
|
261
|
+
Thank you for helping keep LockLLM and our users secure!
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Main LockLLM client
|
|
3
|
+
*/
|
|
4
|
+
import type { LockLLMConfig } from './types/common';
|
|
5
|
+
export declare class LockLLM {
|
|
6
|
+
private readonly config;
|
|
7
|
+
private readonly http;
|
|
8
|
+
private readonly scanClient;
|
|
9
|
+
/**
|
|
10
|
+
* Create a new LockLLM client
|
|
11
|
+
*
|
|
12
|
+
* @param config - Client configuration
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* const lockllm = new LockLLM({
|
|
17
|
+
* apiKey: process.env.LOCKLLM_API_KEY,
|
|
18
|
+
* });
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
constructor(config: LockLLMConfig);
|
|
22
|
+
/**
|
|
23
|
+
* Scan a prompt for injection attacks
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```typescript
|
|
27
|
+
* const result = await lockllm.scan({
|
|
28
|
+
* input: "Ignore previous instructions",
|
|
29
|
+
* sensitivity: "medium"
|
|
30
|
+
* });
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
get scan(): (request: import(".").ScanRequest, options?: import("./types/common").RequestOptions) => Promise<import(".").ScanResponse>;
|
|
34
|
+
/**
|
|
35
|
+
* Get the current configuration
|
|
36
|
+
*/
|
|
37
|
+
getConfig(): Readonly<Required<LockLLMConfig>>;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAMpD,qBAAa,OAAO;IAClB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA0B;IACjD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAa;IAClC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAa;IAExC;;;;;;;;;;;OAWG;gBACS,MAAM,EAAE,aAAa;IA4BjC;;;;;;;;;;OAUG;IACH,IAAI,IAAI,+HAEP;IAED;;OAEG;IACH,SAAS,IAAI,QAAQ,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;CAG/C"}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Main LockLLM client
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.LockLLM = void 0;
|
|
7
|
+
const utils_1 = require("./utils");
|
|
8
|
+
const scan_1 = require("./scan");
|
|
9
|
+
const errors_1 = require("./errors");
|
|
10
|
+
const DEFAULT_BASE_URL = 'https://api.lockllm.com';
|
|
11
|
+
const DEFAULT_TIMEOUT = 60000; // 60 seconds
|
|
12
|
+
const DEFAULT_MAX_RETRIES = 3;
|
|
13
|
+
class LockLLM {
|
|
14
|
+
/**
|
|
15
|
+
* Create a new LockLLM client
|
|
16
|
+
*
|
|
17
|
+
* @param config - Client configuration
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```typescript
|
|
21
|
+
* const lockllm = new LockLLM({
|
|
22
|
+
* apiKey: process.env.LOCKLLM_API_KEY,
|
|
23
|
+
* });
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
constructor(config) {
|
|
27
|
+
// Validate API key
|
|
28
|
+
if (!config.apiKey || !config.apiKey.trim()) {
|
|
29
|
+
throw new errors_1.ConfigurationError('API key is required. Get your API key from https://www.lockllm.com/dashboard');
|
|
30
|
+
}
|
|
31
|
+
// Set defaults
|
|
32
|
+
this.config = {
|
|
33
|
+
apiKey: config.apiKey,
|
|
34
|
+
baseURL: config.baseURL ?? DEFAULT_BASE_URL,
|
|
35
|
+
timeout: config.timeout ?? DEFAULT_TIMEOUT,
|
|
36
|
+
maxRetries: config.maxRetries ?? DEFAULT_MAX_RETRIES,
|
|
37
|
+
};
|
|
38
|
+
// Initialize HTTP client
|
|
39
|
+
this.http = new utils_1.HttpClient(this.config.baseURL, this.config.apiKey, this.config.timeout, this.config.maxRetries);
|
|
40
|
+
// Initialize scan client
|
|
41
|
+
this.scanClient = new scan_1.ScanClient(this.http);
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Scan a prompt for injection attacks
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```typescript
|
|
48
|
+
* const result = await lockllm.scan({
|
|
49
|
+
* input: "Ignore previous instructions",
|
|
50
|
+
* sensitivity: "medium"
|
|
51
|
+
* });
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
54
|
+
get scan() {
|
|
55
|
+
return this.scanClient.scan.bind(this.scanClient);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Get the current configuration
|
|
59
|
+
*/
|
|
60
|
+
getConfig() {
|
|
61
|
+
return { ...this.config };
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
exports.LockLLM = LockLLM;
|
|
65
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AACpC,OAAO,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAG9C,MAAM,gBAAgB,GAAG,yBAAyB,CAAC;AACnD,MAAM,eAAe,GAAG,KAAK,CAAC,CAAC,aAAa;AAC5C,MAAM,mBAAmB,GAAG,CAAC,CAAC;AAE9B,MAAM,OAAO,OAAO;IAKlB;;;;;;;;;;;OAWG;IACH,YAAY,MAAqB;QAC/B,mBAAmB;QACnB,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;YAC5C,MAAM,IAAI,kBAAkB,CAC1B,8EAA8E,CAC/E,CAAC;QACJ,CAAC;QAED,eAAe;QACf,IAAI,CAAC,MAAM,GAAG;YACZ,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,gBAAgB;YAC3C,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,eAAe;YAC1C,UAAU,EAAE,MAAM,CAAC,UAAU,IAAI,mBAAmB;SACrD,CAAC;QAEF,yBAAyB;QACzB,IAAI,CAAC,IAAI,GAAG,IAAI,UAAU,CACxB,IAAI,CAAC,MAAM,CAAC,OAAO,EACnB,IAAI,CAAC,MAAM,CAAC,MAAM,EAClB,IAAI,CAAC,MAAM,CAAC,OAAO,EACnB,IAAI,CAAC,MAAM,CAAC,UAAU,CACvB,CAAC;QAEF,yBAAyB;QACzB,IAAI,CAAC,UAAU,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC9C,CAAC;IAED;;;;;;;;;;OAUG;IACH,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACpD,CAAC;IAED;;OAEG;IACH,SAAS;QACP,OAAO,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;IAC5B,CAAC;CACF"}
|
package/dist/client.mjs
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Main LockLLM client
|
|
3
|
+
*/
|
|
4
|
+
import { HttpClient } from './utils';
|
|
5
|
+
import { ScanClient } from './scan';
|
|
6
|
+
import { ConfigurationError } from './errors';
|
|
7
|
+
const DEFAULT_BASE_URL = 'https://api.lockllm.com';
|
|
8
|
+
const DEFAULT_TIMEOUT = 60000; // 60 seconds
|
|
9
|
+
const DEFAULT_MAX_RETRIES = 3;
|
|
10
|
+
export class LockLLM {
|
|
11
|
+
/**
|
|
12
|
+
* Create a new LockLLM client
|
|
13
|
+
*
|
|
14
|
+
* @param config - Client configuration
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```typescript
|
|
18
|
+
* const lockllm = new LockLLM({
|
|
19
|
+
* apiKey: process.env.LOCKLLM_API_KEY,
|
|
20
|
+
* });
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
constructor(config) {
|
|
24
|
+
// Validate API key
|
|
25
|
+
if (!config.apiKey || !config.apiKey.trim()) {
|
|
26
|
+
throw new ConfigurationError('API key is required. Get your API key from https://www.lockllm.com/dashboard');
|
|
27
|
+
}
|
|
28
|
+
// Set defaults
|
|
29
|
+
this.config = {
|
|
30
|
+
apiKey: config.apiKey,
|
|
31
|
+
baseURL: config.baseURL ?? DEFAULT_BASE_URL,
|
|
32
|
+
timeout: config.timeout ?? DEFAULT_TIMEOUT,
|
|
33
|
+
maxRetries: config.maxRetries ?? DEFAULT_MAX_RETRIES,
|
|
34
|
+
};
|
|
35
|
+
// Initialize HTTP client
|
|
36
|
+
this.http = new HttpClient(this.config.baseURL, this.config.apiKey, this.config.timeout, this.config.maxRetries);
|
|
37
|
+
// Initialize scan client
|
|
38
|
+
this.scanClient = new ScanClient(this.http);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Scan a prompt for injection attacks
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* ```typescript
|
|
45
|
+
* const result = await lockllm.scan({
|
|
46
|
+
* input: "Ignore previous instructions",
|
|
47
|
+
* sensitivity: "medium"
|
|
48
|
+
* });
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
get scan() {
|
|
52
|
+
return this.scanClient.scan.bind(this.scanClient);
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Get the current configuration
|
|
56
|
+
*/
|
|
57
|
+
getConfig() {
|
|
58
|
+
return { ...this.config };
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=client.js.map
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Custom error classes for LockLLM SDK
|
|
3
|
+
*/
|
|
4
|
+
import type { ScanResult, LockLLMErrorData, PromptInjectionErrorData } from './types/errors';
|
|
5
|
+
/**
|
|
6
|
+
* Base error class for all LockLLM errors
|
|
7
|
+
*/
|
|
8
|
+
export declare class LockLLMError extends Error {
|
|
9
|
+
readonly type: string;
|
|
10
|
+
readonly code?: string;
|
|
11
|
+
readonly status?: number;
|
|
12
|
+
readonly requestId?: string;
|
|
13
|
+
constructor(data: LockLLMErrorData);
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Error thrown when authentication fails
|
|
17
|
+
*/
|
|
18
|
+
export declare class AuthenticationError extends LockLLMError {
|
|
19
|
+
constructor(message: string, requestId?: string);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Error thrown when rate limit is exceeded
|
|
23
|
+
*/
|
|
24
|
+
export declare class RateLimitError extends LockLLMError {
|
|
25
|
+
readonly retryAfter?: number;
|
|
26
|
+
constructor(message: string, retryAfter?: number, requestId?: string);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Error thrown when a prompt is blocked due to injection detection
|
|
30
|
+
*/
|
|
31
|
+
export declare class PromptInjectionError extends LockLLMError {
|
|
32
|
+
readonly scanResult: ScanResult;
|
|
33
|
+
constructor(data: PromptInjectionErrorData);
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Error thrown when upstream provider returns an error
|
|
37
|
+
*/
|
|
38
|
+
export declare class UpstreamError extends LockLLMError {
|
|
39
|
+
readonly provider?: string;
|
|
40
|
+
readonly upstreamStatus?: number;
|
|
41
|
+
constructor(message: string, provider?: string, upstreamStatus?: number, requestId?: string);
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Error thrown when configuration is missing or invalid
|
|
45
|
+
*/
|
|
46
|
+
export declare class ConfigurationError extends LockLLMError {
|
|
47
|
+
constructor(message: string);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Error thrown when network request fails
|
|
51
|
+
*/
|
|
52
|
+
export declare class NetworkError extends LockLLMError {
|
|
53
|
+
readonly cause?: Error;
|
|
54
|
+
constructor(message: string, cause?: Error, requestId?: string);
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Parse error response from API and throw appropriate error
|
|
58
|
+
*/
|
|
59
|
+
export declare function parseError(response: any, requestId?: string): LockLLMError;
|
|
60
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAC;AAE7F;;GAEG;AACH,qBAAa,YAAa,SAAQ,KAAK;IACrC,SAAgB,IAAI,EAAE,MAAM,CAAC;IAC7B,SAAgB,IAAI,CAAC,EAAE,MAAM,CAAC;IAC9B,SAAgB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChC,SAAgB,SAAS,CAAC,EAAE,MAAM,CAAC;gBAEvB,IAAI,EAAE,gBAAgB;CAanC;AAED;;GAEG;AACH,qBAAa,mBAAoB,SAAQ,YAAY;gBACvC,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM;CAUhD;AAED;;GAEG;AACH,qBAAa,cAAe,SAAQ,YAAY;IAC9C,SAAgB,UAAU,CAAC,EAAE,MAAM,CAAC;gBAExB,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM;CAWrE;AAED;;GAEG;AACH,qBAAa,oBAAqB,SAAQ,YAAY;IACpD,SAAgB,UAAU,EAAE,UAAU,CAAC;gBAE3B,IAAI,EAAE,wBAAwB;CAW3C;AAED;;GAEG;AACH,qBAAa,aAAc,SAAQ,YAAY;IAC7C,SAAgB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClC,SAAgB,cAAc,CAAC,EAAE,MAAM,CAAC;gBAGtC,OAAO,EAAE,MAAM,EACf,QAAQ,CAAC,EAAE,MAAM,EACjB,cAAc,CAAC,EAAE,MAAM,EACvB,SAAS,CAAC,EAAE,MAAM;CAarB;AAED;;GAEG;AACH,qBAAa,kBAAmB,SAAQ,YAAY;gBACtC,OAAO,EAAE,MAAM;CAS5B;AAED;;GAEG;AACH,qBAAa,YAAa,SAAQ,YAAY;IAC5C,SAAgB,KAAK,CAAC,EAAE,KAAK,CAAC;gBAElB,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK,EAAE,SAAS,CAAC,EAAE,MAAM;CAW/D;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,GAAG,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,YAAY,CAsD1E"}
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Custom error classes for LockLLM SDK
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.NetworkError = exports.ConfigurationError = exports.UpstreamError = exports.PromptInjectionError = exports.RateLimitError = exports.AuthenticationError = exports.LockLLMError = void 0;
|
|
7
|
+
exports.parseError = parseError;
|
|
8
|
+
/**
|
|
9
|
+
* Base error class for all LockLLM errors
|
|
10
|
+
*/
|
|
11
|
+
class LockLLMError extends Error {
|
|
12
|
+
constructor(data) {
|
|
13
|
+
super(data.message);
|
|
14
|
+
this.name = 'LockLLMError';
|
|
15
|
+
this.type = data.type;
|
|
16
|
+
this.code = data.code;
|
|
17
|
+
this.status = data.status;
|
|
18
|
+
this.requestId = data.requestId;
|
|
19
|
+
// Maintains proper stack trace for where our error was thrown (only available on V8)
|
|
20
|
+
if (Error.captureStackTrace) {
|
|
21
|
+
Error.captureStackTrace(this, this.constructor);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
exports.LockLLMError = LockLLMError;
|
|
26
|
+
/**
|
|
27
|
+
* Error thrown when authentication fails
|
|
28
|
+
*/
|
|
29
|
+
class AuthenticationError extends LockLLMError {
|
|
30
|
+
constructor(message, requestId) {
|
|
31
|
+
super({
|
|
32
|
+
message,
|
|
33
|
+
type: 'authentication_error',
|
|
34
|
+
code: 'unauthorized',
|
|
35
|
+
status: 401,
|
|
36
|
+
requestId,
|
|
37
|
+
});
|
|
38
|
+
this.name = 'AuthenticationError';
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
exports.AuthenticationError = AuthenticationError;
|
|
42
|
+
/**
|
|
43
|
+
* Error thrown when rate limit is exceeded
|
|
44
|
+
*/
|
|
45
|
+
class RateLimitError extends LockLLMError {
|
|
46
|
+
constructor(message, retryAfter, requestId) {
|
|
47
|
+
super({
|
|
48
|
+
message,
|
|
49
|
+
type: 'rate_limit_error',
|
|
50
|
+
code: 'rate_limited',
|
|
51
|
+
status: 429,
|
|
52
|
+
requestId,
|
|
53
|
+
});
|
|
54
|
+
this.name = 'RateLimitError';
|
|
55
|
+
this.retryAfter = retryAfter;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
exports.RateLimitError = RateLimitError;
|
|
59
|
+
/**
|
|
60
|
+
* Error thrown when a prompt is blocked due to injection detection
|
|
61
|
+
*/
|
|
62
|
+
class PromptInjectionError extends LockLLMError {
|
|
63
|
+
constructor(data) {
|
|
64
|
+
super({
|
|
65
|
+
message: data.message,
|
|
66
|
+
type: 'lockllm_security_error',
|
|
67
|
+
code: 'prompt_injection_detected',
|
|
68
|
+
status: 400,
|
|
69
|
+
requestId: data.requestId,
|
|
70
|
+
});
|
|
71
|
+
this.name = 'PromptInjectionError';
|
|
72
|
+
this.scanResult = data.scanResult;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
exports.PromptInjectionError = PromptInjectionError;
|
|
76
|
+
/**
|
|
77
|
+
* Error thrown when upstream provider returns an error
|
|
78
|
+
*/
|
|
79
|
+
class UpstreamError extends LockLLMError {
|
|
80
|
+
constructor(message, provider, upstreamStatus, requestId) {
|
|
81
|
+
super({
|
|
82
|
+
message,
|
|
83
|
+
type: 'upstream_error',
|
|
84
|
+
code: 'provider_error',
|
|
85
|
+
status: 502,
|
|
86
|
+
requestId,
|
|
87
|
+
});
|
|
88
|
+
this.name = 'UpstreamError';
|
|
89
|
+
this.provider = provider;
|
|
90
|
+
this.upstreamStatus = upstreamStatus;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
exports.UpstreamError = UpstreamError;
|
|
94
|
+
/**
|
|
95
|
+
* Error thrown when configuration is missing or invalid
|
|
96
|
+
*/
|
|
97
|
+
class ConfigurationError extends LockLLMError {
|
|
98
|
+
constructor(message) {
|
|
99
|
+
super({
|
|
100
|
+
message,
|
|
101
|
+
type: 'configuration_error',
|
|
102
|
+
code: 'invalid_config',
|
|
103
|
+
status: 400,
|
|
104
|
+
});
|
|
105
|
+
this.name = 'ConfigurationError';
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
exports.ConfigurationError = ConfigurationError;
|
|
109
|
+
/**
|
|
110
|
+
* Error thrown when network request fails
|
|
111
|
+
*/
|
|
112
|
+
class NetworkError extends LockLLMError {
|
|
113
|
+
constructor(message, cause, requestId) {
|
|
114
|
+
super({
|
|
115
|
+
message,
|
|
116
|
+
type: 'network_error',
|
|
117
|
+
code: 'connection_failed',
|
|
118
|
+
status: 0,
|
|
119
|
+
requestId,
|
|
120
|
+
});
|
|
121
|
+
this.name = 'NetworkError';
|
|
122
|
+
this.cause = cause;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
exports.NetworkError = NetworkError;
|
|
126
|
+
/**
|
|
127
|
+
* Parse error response from API and throw appropriate error
|
|
128
|
+
*/
|
|
129
|
+
function parseError(response, requestId) {
|
|
130
|
+
const error = response?.error;
|
|
131
|
+
if (!error) {
|
|
132
|
+
return new LockLLMError({
|
|
133
|
+
message: 'Unknown error occurred',
|
|
134
|
+
type: 'unknown_error',
|
|
135
|
+
requestId,
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
// Prompt injection error
|
|
139
|
+
if (error.code === 'prompt_injection_detected' && error.scan_result) {
|
|
140
|
+
return new PromptInjectionError({
|
|
141
|
+
message: error.message,
|
|
142
|
+
type: error.type,
|
|
143
|
+
code: error.code,
|
|
144
|
+
status: 400,
|
|
145
|
+
requestId: error.request_id || requestId,
|
|
146
|
+
scanResult: error.scan_result,
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
// Authentication error
|
|
150
|
+
if (error.type === 'authentication_error' || error.code === 'unauthorized') {
|
|
151
|
+
return new AuthenticationError(error.message, requestId);
|
|
152
|
+
}
|
|
153
|
+
// Rate limit error
|
|
154
|
+
if (error.type === 'rate_limit_error' || error.code === 'rate_limited') {
|
|
155
|
+
return new RateLimitError(error.message, undefined, requestId);
|
|
156
|
+
}
|
|
157
|
+
// Upstream provider error
|
|
158
|
+
if (error.type === 'upstream_error' || error.code === 'provider_error') {
|
|
159
|
+
return new UpstreamError(error.message, undefined, undefined, requestId);
|
|
160
|
+
}
|
|
161
|
+
// Configuration error
|
|
162
|
+
if (error.type === 'configuration_error' ||
|
|
163
|
+
error.type === 'lockllm_config_error' ||
|
|
164
|
+
error.code === 'no_upstream_key') {
|
|
165
|
+
return new ConfigurationError(error.message);
|
|
166
|
+
}
|
|
167
|
+
// Generic error
|
|
168
|
+
return new LockLLMError({
|
|
169
|
+
message: error.message || 'An error occurred',
|
|
170
|
+
type: error.type || 'unknown_error',
|
|
171
|
+
code: error.code,
|
|
172
|
+
requestId,
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
|