promptguard-sdk 1.2.0 → 1.5.1
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 +226 -78
- package/dist/auto.d.ts +40 -0
- package/dist/auto.d.ts.map +1 -0
- package/dist/auto.js +118 -0
- package/dist/auto.js.map +1 -0
- package/dist/guard.d.ts +80 -0
- package/dist/guard.d.ts.map +1 -0
- package/dist/guard.js +104 -0
- package/dist/guard.js.map +1 -0
- package/dist/index.d.ts +105 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +111 -29
- package/dist/index.js.map +1 -1
- package/dist/integrations/langchain.d.ts +55 -0
- package/dist/integrations/langchain.d.ts.map +1 -0
- package/dist/integrations/langchain.js +212 -0
- package/dist/integrations/langchain.js.map +1 -0
- package/dist/integrations/vercel-ai.d.ts +49 -0
- package/dist/integrations/vercel-ai.d.ts.map +1 -0
- package/dist/integrations/vercel-ai.js +170 -0
- package/dist/integrations/vercel-ai.js.map +1 -0
- package/dist/patches/anthropic.d.ts +13 -0
- package/dist/patches/anthropic.d.ts.map +1 -0
- package/dist/patches/anthropic.js +188 -0
- package/dist/patches/anthropic.js.map +1 -0
- package/dist/patches/bedrock.d.ts +14 -0
- package/dist/patches/bedrock.d.ts.map +1 -0
- package/dist/patches/bedrock.js +246 -0
- package/dist/patches/bedrock.js.map +1 -0
- package/dist/patches/cohere.d.ts +14 -0
- package/dist/patches/cohere.d.ts.map +1 -0
- package/dist/patches/cohere.js +183 -0
- package/dist/patches/cohere.js.map +1 -0
- package/dist/patches/google.d.ts +13 -0
- package/dist/patches/google.d.ts.map +1 -0
- package/dist/patches/google.js +163 -0
- package/dist/patches/google.js.map +1 -0
- package/dist/patches/openai.d.ts +14 -0
- package/dist/patches/openai.d.ts.map +1 -0
- package/dist/patches/openai.js +165 -0
- package/dist/patches/openai.js.map +1 -0
- package/package.json +83 -11
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024-2026 PromptGuard
|
|
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
CHANGED
|
@@ -1,58 +1,100 @@
|
|
|
1
1
|
# PromptGuard Node.js SDK
|
|
2
2
|
|
|
3
|
-
Drop-in security for AI applications.
|
|
3
|
+
Drop-in security for AI applications. Secure any GenAI app — regardless of framework or LLM provider.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
8
|
npm install promptguard-sdk
|
|
9
|
-
# or
|
|
10
|
-
yarn add promptguard-sdk
|
|
11
|
-
# or
|
|
12
|
-
pnpm add promptguard-sdk
|
|
13
9
|
```
|
|
14
10
|
|
|
15
|
-
##
|
|
11
|
+
## Option 1: Auto-Instrumentation (Recommended)
|
|
12
|
+
|
|
13
|
+
One line secures **every** LLM call in your application — no matter which framework you use.
|
|
16
14
|
|
|
17
15
|
```typescript
|
|
18
|
-
import {
|
|
16
|
+
import { init } from 'promptguard-sdk';
|
|
19
17
|
|
|
20
|
-
//
|
|
21
|
-
|
|
18
|
+
// Call once at startup — before any LLM SDK usage.
|
|
19
|
+
init({ apiKey: 'pg_xxx' });
|
|
22
20
|
|
|
23
|
-
//
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
21
|
+
// Everything below is now secured transparently.
|
|
22
|
+
import OpenAI from 'openai';
|
|
23
|
+
const client = new OpenAI();
|
|
24
|
+
|
|
25
|
+
// This call is automatically scanned by PromptGuard.
|
|
26
|
+
const response = await client.chat.completions.create({
|
|
27
|
+
model: 'gpt-4o',
|
|
28
|
+
messages: [{ role: 'user', content: 'Hello!' }],
|
|
27
29
|
});
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### Supported SDKs
|
|
33
|
+
|
|
34
|
+
Auto-instrumentation patches the `create` / `generateContent` / `chat` / `send` methods on:
|
|
35
|
+
|
|
36
|
+
| SDK | npm Package | What Gets Patched |
|
|
37
|
+
|-----|------------|-------------------|
|
|
38
|
+
| OpenAI | `openai` | `chat.completions.create` |
|
|
39
|
+
| Anthropic | `@anthropic-ai/sdk` | `messages.create` |
|
|
40
|
+
| Google Generative AI | `@google/generative-ai` | `generateContent` |
|
|
41
|
+
| Cohere | `cohere-ai` | `Client.chat` / `ClientV2.chat` |
|
|
42
|
+
| AWS Bedrock | `@aws-sdk/client-bedrock-runtime` | `BedrockRuntimeClient.send` (InvokeModel, Converse) |
|
|
28
43
|
|
|
29
|
-
|
|
44
|
+
Any framework built on these SDKs is automatically covered: **LangChain.js**, **Vercel AI SDK**, **AutoGen**, **Semantic Kernel**, and more.
|
|
45
|
+
|
|
46
|
+
### Modes
|
|
47
|
+
|
|
48
|
+
```typescript
|
|
49
|
+
// Enforce mode (default) — blocks policy violations.
|
|
50
|
+
init({ apiKey: 'pg_xxx', mode: 'enforce' });
|
|
51
|
+
|
|
52
|
+
// Monitor mode — logs threats but never blocks. Good for shadow deployment.
|
|
53
|
+
init({ apiKey: 'pg_xxx', mode: 'monitor' });
|
|
30
54
|
```
|
|
31
55
|
|
|
32
|
-
|
|
56
|
+
### Options
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
init({
|
|
60
|
+
apiKey: 'pg_xxx', // or set PROMPTGUARD_API_KEY env var
|
|
61
|
+
baseUrl: 'https://...', // or set PROMPTGUARD_BASE_URL env var
|
|
62
|
+
mode: 'enforce', // 'enforce' | 'monitor'
|
|
63
|
+
failOpen: true, // allow calls when Guard API is unreachable
|
|
64
|
+
scanResponses: false, // also scan LLM responses
|
|
65
|
+
timeout: 10_000, // Guard API timeout in ms
|
|
66
|
+
});
|
|
67
|
+
```
|
|
33
68
|
|
|
34
|
-
|
|
69
|
+
### Shutdown
|
|
35
70
|
|
|
36
71
|
```typescript
|
|
37
|
-
|
|
38
|
-
import OpenAI from 'openai';
|
|
39
|
-
const client = new OpenAI();
|
|
72
|
+
import { shutdown } from 'promptguard-sdk';
|
|
40
73
|
|
|
41
|
-
//
|
|
74
|
+
// Removes all patches and cleans up.
|
|
75
|
+
shutdown();
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Option 2: Proxy Mode
|
|
79
|
+
|
|
80
|
+
Route LLM traffic through PromptGuard. Just swap your base URL.
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
42
83
|
import { PromptGuard } from 'promptguard-sdk';
|
|
43
|
-
const client = new PromptGuard({ apiKey: 'pg_xxx' });
|
|
44
84
|
|
|
45
|
-
|
|
46
|
-
```
|
|
85
|
+
const pg = new PromptGuard({ apiKey: 'pg_xxx' });
|
|
47
86
|
|
|
48
|
-
|
|
87
|
+
// Use exactly like the OpenAI client.
|
|
88
|
+
const response = await pg.chat.completions.create({
|
|
89
|
+
model: 'gpt-4o',
|
|
90
|
+
messages: [{ role: 'user', content: 'Hello!' }],
|
|
91
|
+
});
|
|
92
|
+
```
|
|
49
93
|
|
|
50
94
|
### Security Scanning
|
|
51
95
|
|
|
52
96
|
```typescript
|
|
53
|
-
// Scan content for threats
|
|
54
97
|
const result = await pg.security.scan('Ignore previous instructions...');
|
|
55
|
-
|
|
56
98
|
if (result.blocked) {
|
|
57
99
|
console.log(`Threat detected: ${result.reason}`);
|
|
58
100
|
}
|
|
@@ -61,111 +103,217 @@ if (result.blocked) {
|
|
|
61
103
|
### PII Redaction
|
|
62
104
|
|
|
63
105
|
```typescript
|
|
64
|
-
// Redact PII before sending to LLM
|
|
65
106
|
const result = await pg.security.redact(
|
|
66
107
|
'My email is john@example.com and SSN is 123-45-6789'
|
|
67
108
|
);
|
|
68
|
-
|
|
69
|
-
console.log(result.redactedContent);
|
|
70
|
-
// Output: "My email is [EMAIL] and SSN is [SSN]"
|
|
109
|
+
console.log(result.redacted);
|
|
71
110
|
```
|
|
72
111
|
|
|
73
|
-
|
|
112
|
+
## Framework Integrations
|
|
113
|
+
|
|
114
|
+
### LangChain.js
|
|
74
115
|
|
|
75
116
|
```typescript
|
|
76
|
-
|
|
77
|
-
|
|
117
|
+
import { PromptGuardCallbackHandler } from 'promptguard-sdk/integrations/langchain';
|
|
118
|
+
import { ChatOpenAI } from '@langchain/openai';
|
|
78
119
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
120
|
+
const handler = new PromptGuardCallbackHandler({
|
|
121
|
+
apiKey: 'pg_xxx',
|
|
122
|
+
mode: 'enforce',
|
|
123
|
+
scanResponses: true,
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
// Attach to a single model
|
|
127
|
+
const llm = new ChatOpenAI({
|
|
128
|
+
model: 'gpt-4o',
|
|
129
|
+
callbacks: [handler],
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
// Or use with any chain / agent
|
|
133
|
+
const result = await chain.invoke(
|
|
134
|
+
{ input: 'Hello' },
|
|
135
|
+
{ callbacks: [handler] },
|
|
136
|
+
);
|
|
85
137
|
```
|
|
86
138
|
|
|
87
|
-
|
|
139
|
+
The callback handler provides rich context to PromptGuard — chain names, tool calls, agent steps — for more precise threat detection.
|
|
140
|
+
|
|
141
|
+
### Vercel AI SDK
|
|
88
142
|
|
|
89
143
|
```typescript
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
144
|
+
import { openai } from '@ai-sdk/openai';
|
|
145
|
+
import { wrapLanguageModel, generateText } from 'ai';
|
|
146
|
+
import { promptGuardMiddleware } from 'promptguard-sdk/integrations/vercel-ai';
|
|
147
|
+
|
|
148
|
+
const model = wrapLanguageModel({
|
|
149
|
+
model: openai('gpt-4o'),
|
|
150
|
+
middleware: promptGuardMiddleware({
|
|
151
|
+
apiKey: 'pg_xxx',
|
|
152
|
+
mode: 'enforce',
|
|
153
|
+
scanResponses: true,
|
|
154
|
+
}),
|
|
95
155
|
});
|
|
96
156
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
157
|
+
const { text } = await generateText({
|
|
158
|
+
model,
|
|
159
|
+
prompt: 'Hello!',
|
|
160
|
+
});
|
|
100
161
|
```
|
|
101
162
|
|
|
102
|
-
|
|
163
|
+
### Standalone Guard API
|
|
164
|
+
|
|
165
|
+
Use the Guard client directly for maximum control:
|
|
103
166
|
|
|
104
167
|
```typescript
|
|
105
|
-
import {
|
|
168
|
+
import { GuardClient } from 'promptguard-sdk';
|
|
169
|
+
|
|
170
|
+
const guard = new GuardClient({ apiKey: 'pg_xxx' });
|
|
106
171
|
|
|
107
|
-
|
|
172
|
+
// Scan before sending to LLM
|
|
173
|
+
const decision = await guard.scan(
|
|
174
|
+
[{ role: 'user', content: userInput }],
|
|
175
|
+
'input',
|
|
176
|
+
'gpt-4o',
|
|
177
|
+
);
|
|
178
|
+
|
|
179
|
+
if (decision.blocked) {
|
|
180
|
+
console.log(`Blocked: ${decision.threatType}`);
|
|
181
|
+
} else if (decision.redacted && decision.redactedMessages) {
|
|
182
|
+
// Use redacted messages instead
|
|
183
|
+
messages = decision.redactedMessages;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// Scan LLM response
|
|
187
|
+
const outputDecision = await guard.scan(
|
|
188
|
+
[{ role: 'assistant', content: llmOutput }],
|
|
189
|
+
'output',
|
|
190
|
+
);
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
## Retry Logic
|
|
194
|
+
|
|
195
|
+
Both `PromptGuard` and `GuardClient` support configurable retry behavior for transient failures:
|
|
196
|
+
|
|
197
|
+
```typescript
|
|
198
|
+
const pg = new PromptGuard({
|
|
108
199
|
apiKey: 'pg_xxx',
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
200
|
+
maxRetries: 3, // Number of retry attempts (default: 2)
|
|
201
|
+
retryDelay: 500, // Base delay in ms between retries (default: 250)
|
|
202
|
+
});
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
Retries use exponential backoff starting from `retryDelay`. Only transient errors (network timeouts, 5xx responses) are retried — client errors (4xx) fail immediately.
|
|
206
|
+
|
|
207
|
+
## Embeddings
|
|
208
|
+
|
|
209
|
+
Scan and secure embedding requests through the proxy:
|
|
114
210
|
|
|
115
|
-
|
|
211
|
+
```typescript
|
|
212
|
+
const response = await pg.embeddings.create({
|
|
213
|
+
model: 'text-embedding-3-small',
|
|
214
|
+
input: 'The quick brown fox jumps over the lazy dog',
|
|
215
|
+
});
|
|
216
|
+
console.log(response.data[0].embedding.slice(0, 5));
|
|
116
217
|
```
|
|
117
218
|
|
|
118
|
-
|
|
219
|
+
Batch embedding requests are also supported:
|
|
119
220
|
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
|
|
221
|
+
```typescript
|
|
222
|
+
const response = await pg.embeddings.create({
|
|
223
|
+
model: 'text-embedding-3-small',
|
|
224
|
+
input: ['First document', 'Second document', 'Third document'],
|
|
225
|
+
});
|
|
226
|
+
for (const item of response.data) {
|
|
227
|
+
console.log(`Index ${item.index}: ${item.embedding.length} dimensions`);
|
|
228
|
+
}
|
|
123
229
|
```
|
|
124
230
|
|
|
125
|
-
|
|
231
|
+
## AI Agent Security
|
|
126
232
|
|
|
127
233
|
```typescript
|
|
128
|
-
|
|
234
|
+
const validation = await pg.agent.validateTool(
|
|
235
|
+
'agent-123',
|
|
236
|
+
'execute_shell',
|
|
237
|
+
{ command: 'ls -la' },
|
|
238
|
+
);
|
|
129
239
|
|
|
130
|
-
|
|
240
|
+
if (!validation.allowed) {
|
|
241
|
+
console.log(`Blocked: ${validation.reason}`);
|
|
242
|
+
}
|
|
131
243
|
```
|
|
132
244
|
|
|
245
|
+
## Red Team Testing
|
|
246
|
+
|
|
247
|
+
```typescript
|
|
248
|
+
const pg = new PromptGuard({ apiKey: 'pg_xxx' });
|
|
249
|
+
|
|
250
|
+
// Run the autonomous red team agent (LLM-powered mutation)
|
|
251
|
+
const report = await pg.redteam.runAutonomous({
|
|
252
|
+
budget: 200,
|
|
253
|
+
target_preset: 'support_bot:strict',
|
|
254
|
+
});
|
|
255
|
+
console.log(`Grade: ${report.grade}, Bypass rate: ${(report.bypass_rate * 100).toFixed(0)}%`);
|
|
256
|
+
|
|
257
|
+
// Get Attack Intelligence stats
|
|
258
|
+
const stats = await pg.redteam.intelligenceStats();
|
|
259
|
+
console.log(`Total patterns: ${stats.total_patterns}`);
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
## Configuration
|
|
263
|
+
|
|
264
|
+
| Option | Environment Variable | Default | Description |
|
|
265
|
+
|--------|---------------------|---------|-------------|
|
|
266
|
+
| `apiKey` | `PROMPTGUARD_API_KEY` | — | PromptGuard API key (required) |
|
|
267
|
+
| `baseUrl` | `PROMPTGUARD_BASE_URL` | `https://api.promptguard.co/api/v1` | API base URL |
|
|
268
|
+
| `mode` | — | `"enforce"` | `"enforce"` or `"monitor"` |
|
|
269
|
+
| `failOpen` | — | `true` | Allow calls when Guard API is unreachable |
|
|
270
|
+
| `scanResponses` | — | `false` | Also scan LLM responses |
|
|
271
|
+
| `timeout` | — | `10000` | HTTP timeout in milliseconds |
|
|
272
|
+
|
|
133
273
|
## Error Handling
|
|
134
274
|
|
|
135
275
|
```typescript
|
|
136
|
-
import {
|
|
276
|
+
import { PromptGuardBlockedError, GuardApiError } from 'promptguard-sdk';
|
|
137
277
|
|
|
138
278
|
try {
|
|
139
|
-
|
|
279
|
+
await client.chat.completions.create({ ... });
|
|
140
280
|
} catch (error) {
|
|
141
|
-
if (error instanceof
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
281
|
+
if (error instanceof PromptGuardBlockedError) {
|
|
282
|
+
// Request was blocked by policy
|
|
283
|
+
console.log(error.decision.threatType);
|
|
284
|
+
console.log(error.decision.confidence);
|
|
285
|
+
console.log(error.decision.eventId);
|
|
286
|
+
} else if (error instanceof GuardApiError) {
|
|
287
|
+
// Guard API is unreachable (only when failOpen=false)
|
|
288
|
+
console.log(error.statusCode);
|
|
147
289
|
}
|
|
148
|
-
throw error;
|
|
149
290
|
}
|
|
150
291
|
```
|
|
151
292
|
|
|
152
293
|
## TypeScript Support
|
|
153
294
|
|
|
154
|
-
Full TypeScript support with type definitions
|
|
295
|
+
Full TypeScript support with type definitions for all exports:
|
|
155
296
|
|
|
156
297
|
```typescript
|
|
157
298
|
import type {
|
|
299
|
+
GuardDecision,
|
|
300
|
+
GuardMessage,
|
|
301
|
+
GuardContext,
|
|
302
|
+
InitOptions,
|
|
158
303
|
ChatCompletionRequest,
|
|
159
304
|
ChatCompletionResponse,
|
|
160
|
-
SecurityScanResult
|
|
161
|
-
|
|
305
|
+
SecurityScanResult,
|
|
306
|
+
AutonomousRedTeamRequest,
|
|
307
|
+
AutonomousRedTeamReport,
|
|
308
|
+
IntelligenceStats,
|
|
309
|
+
} from 'promptguard-sdk';
|
|
162
310
|
```
|
|
163
311
|
|
|
164
312
|
## Links
|
|
165
313
|
|
|
166
314
|
- [Documentation](https://docs.promptguard.co)
|
|
167
|
-
- [
|
|
168
|
-
- [
|
|
315
|
+
- [SDK Reference](https://docs.promptguard.co/sdks/node)
|
|
316
|
+
- [Support](mailto:support@promptguard.co)
|
|
169
317
|
|
|
170
318
|
## License
|
|
171
319
|
|
package/dist/auto.d.ts
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auto-instrumentation for PromptGuard (Node.js).
|
|
3
|
+
*
|
|
4
|
+
* Call {@link init} once at application startup to automatically
|
|
5
|
+
* secure **all** LLM calls made through popular SDKs — regardless of
|
|
6
|
+
* which framework (LangChain.js, Vercel AI SDK, etc.) sits on top.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```ts
|
|
10
|
+
* import { init } from 'promptguard-sdk/auto';
|
|
11
|
+
*
|
|
12
|
+
* init({ apiKey: 'pg_xxx' });
|
|
13
|
+
*
|
|
14
|
+
* // Everything below is now secured transparently.
|
|
15
|
+
* import OpenAI from 'openai';
|
|
16
|
+
* const client = new OpenAI();
|
|
17
|
+
* await client.chat.completions.create({ ... }); // ← scanned by PromptGuard
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
import { GuardClient } from "./guard";
|
|
21
|
+
export interface InitOptions {
|
|
22
|
+
apiKey?: string;
|
|
23
|
+
baseUrl?: string;
|
|
24
|
+
/** `"enforce"` blocks violations, `"monitor"` logs only (default: `"enforce"`). */
|
|
25
|
+
mode?: "enforce" | "monitor";
|
|
26
|
+
/** Allow LLM calls when Guard API is unreachable (default: `true`). */
|
|
27
|
+
failOpen?: boolean;
|
|
28
|
+
/** Also scan LLM responses (default: `false`). */
|
|
29
|
+
scanResponses?: boolean;
|
|
30
|
+
/** HTTP timeout in ms for Guard API calls (default: `10000`). */
|
|
31
|
+
timeout?: number;
|
|
32
|
+
}
|
|
33
|
+
export declare function init(options?: InitOptions): void;
|
|
34
|
+
export declare function shutdown(): void;
|
|
35
|
+
export declare function getGuardClient(): GuardClient | null;
|
|
36
|
+
export declare function getMode(): "enforce" | "monitor";
|
|
37
|
+
export declare function isFailOpen(): boolean;
|
|
38
|
+
export declare function shouldScanResponses(): boolean;
|
|
39
|
+
export declare function isInitialized(): boolean;
|
|
40
|
+
//# sourceMappingURL=auto.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auto.d.ts","sourceRoot":"","sources":["../src/auto.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AAkBrC,MAAM,WAAW,WAAW;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,mFAAmF;IACnF,IAAI,CAAC,EAAE,SAAS,GAAG,SAAS,CAAA;IAC5B,uEAAuE;IACvE,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,kDAAkD;IAClD,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,iEAAiE;IACjE,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,wBAAgB,IAAI,CAAC,OAAO,GAAE,WAAgB,GAAG,IAAI,CAkCpD;AAED,wBAAgB,QAAQ,IAAI,IAAI,CAY/B;AAMD,wBAAgB,cAAc,IAAI,WAAW,GAAG,IAAI,CAEnD;AAED,wBAAgB,OAAO,IAAI,SAAS,GAAG,SAAS,CAE/C;AAED,wBAAgB,UAAU,IAAI,OAAO,CAEpC;AAED,wBAAgB,mBAAmB,IAAI,OAAO,CAE7C;AAED,wBAAgB,aAAa,IAAI,OAAO,CAEvC"}
|
package/dist/auto.js
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Auto-instrumentation for PromptGuard (Node.js).
|
|
4
|
+
*
|
|
5
|
+
* Call {@link init} once at application startup to automatically
|
|
6
|
+
* secure **all** LLM calls made through popular SDKs — regardless of
|
|
7
|
+
* which framework (LangChain.js, Vercel AI SDK, etc.) sits on top.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* import { init } from 'promptguard-sdk/auto';
|
|
12
|
+
*
|
|
13
|
+
* init({ apiKey: 'pg_xxx' });
|
|
14
|
+
*
|
|
15
|
+
* // Everything below is now secured transparently.
|
|
16
|
+
* import OpenAI from 'openai';
|
|
17
|
+
* const client = new OpenAI();
|
|
18
|
+
* await client.chat.completions.create({ ... }); // ← scanned by PromptGuard
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
+
exports.init = init;
|
|
23
|
+
exports.shutdown = shutdown;
|
|
24
|
+
exports.getGuardClient = getGuardClient;
|
|
25
|
+
exports.getMode = getMode;
|
|
26
|
+
exports.isFailOpen = isFailOpen;
|
|
27
|
+
exports.shouldScanResponses = shouldScanResponses;
|
|
28
|
+
exports.isInitialized = isInitialized;
|
|
29
|
+
const guard_1 = require("./guard");
|
|
30
|
+
// ---------------------------------------------------------------------------
|
|
31
|
+
// Global state
|
|
32
|
+
// ---------------------------------------------------------------------------
|
|
33
|
+
let guardClient = null;
|
|
34
|
+
let mode = "enforce";
|
|
35
|
+
let failOpen = true;
|
|
36
|
+
let scanResponses = false;
|
|
37
|
+
let initialized = false;
|
|
38
|
+
const appliedPatches = [];
|
|
39
|
+
function init(options = {}) {
|
|
40
|
+
const resolvedKey = options.apiKey ?? process.env.PROMPTGUARD_API_KEY ?? "";
|
|
41
|
+
if (!resolvedKey) {
|
|
42
|
+
throw new Error("PromptGuard API key required. Pass apiKey or set the " +
|
|
43
|
+
"PROMPTGUARD_API_KEY environment variable.");
|
|
44
|
+
}
|
|
45
|
+
const resolvedUrl = options.baseUrl ?? process.env.PROMPTGUARD_BASE_URL ?? "https://api.promptguard.co/api/v1";
|
|
46
|
+
const resolvedMode = options.mode ?? "enforce";
|
|
47
|
+
if (resolvedMode !== "enforce" && resolvedMode !== "monitor") {
|
|
48
|
+
throw new Error("mode must be 'enforce' or 'monitor'");
|
|
49
|
+
}
|
|
50
|
+
guardClient = new guard_1.GuardClient({
|
|
51
|
+
apiKey: resolvedKey,
|
|
52
|
+
baseUrl: resolvedUrl,
|
|
53
|
+
timeout: options.timeout ?? 10000,
|
|
54
|
+
});
|
|
55
|
+
mode = resolvedMode;
|
|
56
|
+
failOpen = options.failOpen ?? true;
|
|
57
|
+
scanResponses = options.scanResponses ?? false;
|
|
58
|
+
initialized = true;
|
|
59
|
+
applyPatches();
|
|
60
|
+
// eslint-disable-next-line no-console
|
|
61
|
+
console.log(`[promptguard] auto-instrumentation initialised (mode=${mode}, fail_open=${failOpen})`);
|
|
62
|
+
}
|
|
63
|
+
function shutdown() {
|
|
64
|
+
for (const patch of appliedPatches) {
|
|
65
|
+
try {
|
|
66
|
+
patch.revert();
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
// best-effort
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
appliedPatches.length = 0;
|
|
73
|
+
guardClient = null;
|
|
74
|
+
initialized = false;
|
|
75
|
+
}
|
|
76
|
+
// ---------------------------------------------------------------------------
|
|
77
|
+
// Accessors (used by patches)
|
|
78
|
+
// ---------------------------------------------------------------------------
|
|
79
|
+
function getGuardClient() {
|
|
80
|
+
return guardClient;
|
|
81
|
+
}
|
|
82
|
+
function getMode() {
|
|
83
|
+
return mode;
|
|
84
|
+
}
|
|
85
|
+
function isFailOpen() {
|
|
86
|
+
return failOpen;
|
|
87
|
+
}
|
|
88
|
+
function shouldScanResponses() {
|
|
89
|
+
return scanResponses;
|
|
90
|
+
}
|
|
91
|
+
function isInitialized() {
|
|
92
|
+
return initialized;
|
|
93
|
+
}
|
|
94
|
+
// ---------------------------------------------------------------------------
|
|
95
|
+
// Patch orchestration
|
|
96
|
+
// ---------------------------------------------------------------------------
|
|
97
|
+
function applyPatches() {
|
|
98
|
+
const patchModules = [
|
|
99
|
+
{ name: "openai", path: "./patches/openai" },
|
|
100
|
+
{ name: "anthropic", path: "./patches/anthropic" },
|
|
101
|
+
{ name: "google", path: "./patches/google" },
|
|
102
|
+
{ name: "cohere", path: "./patches/cohere" },
|
|
103
|
+
{ name: "bedrock", path: "./patches/bedrock" },
|
|
104
|
+
];
|
|
105
|
+
for (const mod of patchModules) {
|
|
106
|
+
try {
|
|
107
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
108
|
+
const patchModule = require(mod.path);
|
|
109
|
+
if (patchModule.apply()) {
|
|
110
|
+
appliedPatches.push({ name: mod.name, revert: patchModule.revert });
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
// SDK not installed or incompatible — skip silently
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
//# sourceMappingURL=auto.js.map
|
package/dist/auto.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auto.js","sourceRoot":"","sources":["../src/auto.ts"],"names":[],"mappings":"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"}
|
package/dist/guard.d.ts
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Guard client — calls the PromptGuard Guard API for content scanning.
|
|
3
|
+
*
|
|
4
|
+
* Used internally by auto-instrumentation patches and framework
|
|
5
|
+
* integrations. Sends messages to POST /api/v1/guard and returns
|
|
6
|
+
* the decision (allow / block / redact).
|
|
7
|
+
*/
|
|
8
|
+
export interface GuardMessage {
|
|
9
|
+
role: string;
|
|
10
|
+
content: string;
|
|
11
|
+
}
|
|
12
|
+
export interface GuardContext {
|
|
13
|
+
framework?: string;
|
|
14
|
+
chain_name?: string;
|
|
15
|
+
agent_id?: string;
|
|
16
|
+
session_id?: string;
|
|
17
|
+
tool_calls?: Array<Record<string, unknown>>;
|
|
18
|
+
metadata?: Record<string, unknown>;
|
|
19
|
+
}
|
|
20
|
+
export interface GuardRequestBody {
|
|
21
|
+
messages: GuardMessage[];
|
|
22
|
+
direction: "input" | "output";
|
|
23
|
+
model?: string;
|
|
24
|
+
context?: GuardContext;
|
|
25
|
+
}
|
|
26
|
+
export interface ThreatDetail {
|
|
27
|
+
type: string;
|
|
28
|
+
confidence: number;
|
|
29
|
+
details: string;
|
|
30
|
+
}
|
|
31
|
+
export interface GuardResponseBody {
|
|
32
|
+
decision: "allow" | "block" | "redact";
|
|
33
|
+
event_id: string;
|
|
34
|
+
confidence: number;
|
|
35
|
+
threat_type?: string;
|
|
36
|
+
redacted_messages?: GuardMessage[];
|
|
37
|
+
threats: ThreatDetail[];
|
|
38
|
+
latency_ms: number;
|
|
39
|
+
}
|
|
40
|
+
export declare class GuardDecision {
|
|
41
|
+
readonly decision: string;
|
|
42
|
+
readonly eventId: string;
|
|
43
|
+
readonly confidence: number;
|
|
44
|
+
readonly threatType?: string;
|
|
45
|
+
readonly redactedMessages?: GuardMessage[];
|
|
46
|
+
readonly threats: ThreatDetail[];
|
|
47
|
+
readonly latencyMs: number;
|
|
48
|
+
constructor(data: Partial<GuardResponseBody>);
|
|
49
|
+
get blocked(): boolean;
|
|
50
|
+
get redacted(): boolean;
|
|
51
|
+
get allowed(): boolean;
|
|
52
|
+
}
|
|
53
|
+
export declare class GuardApiError extends Error {
|
|
54
|
+
readonly statusCode?: number;
|
|
55
|
+
constructor(message: string, statusCode?: number);
|
|
56
|
+
}
|
|
57
|
+
export declare class PromptGuardBlockedError extends Error {
|
|
58
|
+
readonly decision: GuardDecision;
|
|
59
|
+
constructor(decision: GuardDecision);
|
|
60
|
+
}
|
|
61
|
+
export interface GuardClientConfig {
|
|
62
|
+
apiKey: string;
|
|
63
|
+
baseUrl?: string;
|
|
64
|
+
timeout?: number;
|
|
65
|
+
}
|
|
66
|
+
export declare class GuardClient {
|
|
67
|
+
private readonly apiKey;
|
|
68
|
+
private readonly guardUrl;
|
|
69
|
+
private readonly timeout;
|
|
70
|
+
constructor(config: GuardClientConfig);
|
|
71
|
+
private headers;
|
|
72
|
+
/**
|
|
73
|
+
* Scan messages via the Guard API.
|
|
74
|
+
*
|
|
75
|
+
* Throws {@link GuardApiError} on network/API errors so the caller
|
|
76
|
+
* can decide whether to fail open or closed.
|
|
77
|
+
*/
|
|
78
|
+
scan(messages: GuardMessage[], direction?: "input" | "output", model?: string, context?: GuardContext): Promise<GuardDecision>;
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=guard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guard.d.ts","sourceRoot":"","sources":["../src/guard.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,YAAY;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,UAAU,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;IAC3C,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACnC;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,YAAY,EAAE,CAAA;IACxB,SAAS,EAAE,OAAO,GAAG,QAAQ,CAAA;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,YAAY,CAAA;CACvB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,OAAO,GAAG,OAAO,GAAG,QAAQ,CAAA;IACtC,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,MAAM,CAAA;IAClB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,iBAAiB,CAAC,EAAE,YAAY,EAAE,CAAA;IAClC,OAAO,EAAE,YAAY,EAAE,CAAA;IACvB,UAAU,EAAE,MAAM,CAAA;CACnB;AAMD,qBAAa,aAAa;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,gBAAgB,CAAC,EAAE,YAAY,EAAE,CAAA;IAC1C,QAAQ,CAAC,OAAO,EAAE,YAAY,EAAE,CAAA;IAChC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;gBAEd,IAAI,EAAE,OAAO,CAAC,iBAAiB,CAAC;IAU5C,IAAI,OAAO,IAAI,OAAO,CAErB;IACD,IAAI,QAAQ,IAAI,OAAO,CAEtB;IACD,IAAI,OAAO,IAAI,OAAO,CAErB;CACF;AAMD,qBAAa,aAAc,SAAQ,KAAK;IACtC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;gBAEhB,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM;CAKjD;AAED,qBAAa,uBAAwB,SAAQ,KAAK;IAChD,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAA;gBAEpB,QAAQ,EAAE,aAAa;CASpC;AAMD,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAQ;IAC/B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAQ;IACjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAQ;gBAEpB,MAAM,EAAE,iBAAiB;IAOrC,OAAO,CAAC,OAAO;IASf;;;;;OAKG;IACG,IAAI,CACR,QAAQ,EAAE,YAAY,EAAE,EACxB,SAAS,GAAE,OAAO,GAAG,QAAkB,EACvC,KAAK,CAAC,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,aAAa,CAAC;CA8B1B"}
|