promptguard-sdk 1.1.16 → 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.
Files changed (43) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +226 -78
  3. package/dist/auto.d.ts +40 -0
  4. package/dist/auto.d.ts.map +1 -0
  5. package/dist/auto.js +118 -0
  6. package/dist/auto.js.map +1 -0
  7. package/dist/guard.d.ts +80 -0
  8. package/dist/guard.d.ts.map +1 -0
  9. package/dist/guard.js +104 -0
  10. package/dist/guard.js.map +1 -0
  11. package/dist/index.d.ts +102 -45
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/index.js +111 -67
  14. package/dist/index.js.map +1 -1
  15. package/dist/integrations/langchain.d.ts +55 -0
  16. package/dist/integrations/langchain.d.ts.map +1 -0
  17. package/dist/integrations/langchain.js +212 -0
  18. package/dist/integrations/langchain.js.map +1 -0
  19. package/dist/integrations/vercel-ai.d.ts +49 -0
  20. package/dist/integrations/vercel-ai.d.ts.map +1 -0
  21. package/dist/integrations/vercel-ai.js +170 -0
  22. package/dist/integrations/vercel-ai.js.map +1 -0
  23. package/dist/patches/anthropic.d.ts +13 -0
  24. package/dist/patches/anthropic.d.ts.map +1 -0
  25. package/dist/patches/anthropic.js +188 -0
  26. package/dist/patches/anthropic.js.map +1 -0
  27. package/dist/patches/bedrock.d.ts +14 -0
  28. package/dist/patches/bedrock.d.ts.map +1 -0
  29. package/dist/patches/bedrock.js +246 -0
  30. package/dist/patches/bedrock.js.map +1 -0
  31. package/dist/patches/cohere.d.ts +14 -0
  32. package/dist/patches/cohere.d.ts.map +1 -0
  33. package/dist/patches/cohere.js +183 -0
  34. package/dist/patches/cohere.js.map +1 -0
  35. package/dist/patches/google.d.ts +13 -0
  36. package/dist/patches/google.d.ts.map +1 -0
  37. package/dist/patches/google.js +163 -0
  38. package/dist/patches/google.js.map +1 -0
  39. package/dist/patches/openai.d.ts +14 -0
  40. package/dist/patches/openai.d.ts.map +1 -0
  41. package/dist/patches/openai.js +165 -0
  42. package/dist/patches/openai.js.map +1 -0
  43. 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. No code changes required.
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
- ## Quick Start
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 { PromptGuard } from 'promptguard-sdk';
16
+ import { init } from 'promptguard-sdk';
19
17
 
20
- // Initialize client
21
- const pg = new PromptGuard({ apiKey: 'pg_xxx' });
18
+ // Call once at startup — before any LLM SDK usage.
19
+ init({ apiKey: 'pg_xxx' });
22
20
 
23
- // Use exactly like OpenAI client
24
- const response = await pg.chat.completions.create({
25
- model: 'gpt-4',
26
- messages: [{ role: 'user', content: 'Hello!' }]
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
- console.log(response.choices[0].message.content);
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
- ## Drop-in Replacement
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
- If you're already using OpenAI's Node.js client, just change the import:
69
+ ### Shutdown
35
70
 
36
71
  ```typescript
37
- // Before
38
- import OpenAI from 'openai';
39
- const client = new OpenAI();
72
+ import { shutdown } from 'promptguard-sdk';
40
73
 
41
- // After
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
- // Your existing code works unchanged!
46
- ```
85
+ const pg = new PromptGuard({ apiKey: 'pg_xxx' });
47
86
 
48
- ## Features
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
- ### Secure Web Scraping
112
+ ## Framework Integrations
113
+
114
+ ### LangChain.js
74
115
 
75
116
  ```typescript
76
- // Scan scraped content for indirect prompt injection
77
- const result = await pg.scrape.scanUrl('https://example.com/article');
117
+ import { PromptGuardCallbackHandler } from 'promptguard-sdk/integrations/langchain';
118
+ import { ChatOpenAI } from '@langchain/openai';
78
119
 
79
- if (result.isSafe) {
80
- // Use content safely
81
- console.log(result.content);
82
- } else {
83
- console.log('Threats detected:', result.threats);
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
- ### AI Agent Security
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
- // Validate tool calls before execution
91
- const validation = await pg.agent.validateTool({
92
- agentId: 'agent-123',
93
- toolName: 'execute_shell',
94
- arguments: { command: 'ls -la' }
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
- if (validation.action === 'block') {
98
- console.log(`Blocked: ${validation.reason}`);
99
- }
157
+ const { text } = await generateText({
158
+ model,
159
+ prompt: 'Hello!',
160
+ });
100
161
  ```
101
162
 
102
- ## Configuration
163
+ ### Standalone Guard API
164
+
165
+ Use the Guard client directly for maximum control:
103
166
 
104
167
  ```typescript
105
- import { PromptGuard, Config } from '@promptguard/sdk';
168
+ import { GuardClient } from 'promptguard-sdk';
169
+
170
+ const guard = new GuardClient({ apiKey: 'pg_xxx' });
106
171
 
107
- const config: Config = {
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
- baseUrl: 'https://api.promptguard.co/api/v1',
110
- timeout: 30000,
111
- enableCaching: true,
112
- enableSecurityScan: true,
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
- const pg = new PromptGuard(config);
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
- ## Environment Variables
219
+ Batch embedding requests are also supported:
119
220
 
120
- ```bash
121
- export PROMPTGUARD_API_KEY="pg_xxx"
122
- export PROMPTGUARD_BASE_URL="https://api.promptguard.co/api/v1"
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
- Then just:
231
+ ## AI Agent Security
126
232
 
127
233
  ```typescript
128
- import { PromptGuard } from 'promptguard-sdk';
234
+ const validation = await pg.agent.validateTool(
235
+ 'agent-123',
236
+ 'execute_shell',
237
+ { command: 'ls -la' },
238
+ );
129
239
 
130
- const pg = new PromptGuard(); // Uses env vars automatically
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 { PromptGuard, PromptGuardError } from '@promptguard/sdk';
276
+ import { PromptGuardBlockedError, GuardApiError } from 'promptguard-sdk';
137
277
 
138
278
  try {
139
- const response = await pg.chat.completions.create({...});
279
+ await client.chat.completions.create({ ... });
140
280
  } catch (error) {
141
- if (error instanceof PromptGuardError) {
142
- if (error.code === 'BLOCKED') {
143
- console.log(`Request blocked: ${error.message}`);
144
- } else if (error.code === 'RATE_LIMITED') {
145
- console.log('Rate limited, try again later');
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 included.
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
- } from '@promptguard/sdk';
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
- - [GitHub](https://github.com/acebot712/promptguard)
168
- - [Issues](https://github.com/acebot712/promptguard/issues)
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
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auto.js","sourceRoot":"","sources":["../src/auto.ts"],"names":[],"mappings":"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"}
@@ -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"}