promptguard-sdk 1.9.0 → 1.10.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/README.md +71 -6
- package/dist/auto.d.ts +50 -0
- package/dist/auto.d.ts.map +1 -1
- package/dist/auto.js +75 -5
- package/dist/auto.js.map +1 -1
- package/dist/client.d.ts +102 -36
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +171 -22
- package/dist/client.js.map +1 -1
- package/dist/generated/api-types.d.ts +226 -27
- package/dist/generated/api-types.d.ts.map +1 -1
- package/dist/guard.d.ts +48 -1
- package/dist/guard.d.ts.map +1 -1
- package/dist/guard.js +110 -21
- package/dist/guard.js.map +1 -1
- package/dist/index.d.ts +4 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -5
- package/dist/index.js.map +1 -1
- package/dist/integrations/langchain.d.ts +41 -1
- package/dist/integrations/langchain.d.ts.map +1 -1
- package/dist/integrations/langchain.js +88 -7
- package/dist/integrations/langchain.js.map +1 -1
- package/dist/integrations/vercel-ai.d.ts +14 -1
- package/dist/integrations/vercel-ai.d.ts.map +1 -1
- package/dist/integrations/vercel-ai.js +149 -27
- package/dist/integrations/vercel-ai.js.map +1 -1
- package/dist/logger.d.ts +7 -0
- package/dist/logger.d.ts.map +1 -1
- package/dist/logger.js +7 -0
- package/dist/logger.js.map +1 -1
- package/dist/patches/anthropic.d.ts +16 -0
- package/dist/patches/anthropic.d.ts.map +1 -1
- package/dist/patches/anthropic.js +69 -32
- package/dist/patches/anthropic.js.map +1 -1
- package/dist/patches/base.d.ts +17 -1
- package/dist/patches/base.d.ts.map +1 -1
- package/dist/patches/base.js +85 -4
- package/dist/patches/base.js.map +1 -1
- package/dist/patches/bedrock.d.ts +35 -2
- package/dist/patches/bedrock.d.ts.map +1 -1
- package/dist/patches/bedrock.js +195 -23
- package/dist/patches/bedrock.js.map +1 -1
- package/dist/patches/cohere.d.ts +11 -0
- package/dist/patches/cohere.d.ts.map +1 -1
- package/dist/patches/cohere.js +76 -2
- package/dist/patches/cohere.js.map +1 -1
- package/dist/patches/google.d.ts +8 -0
- package/dist/patches/google.d.ts.map +1 -1
- package/dist/patches/google.js +54 -0
- package/dist/patches/google.js.map +1 -1
- package/dist/patches/openai.d.ts +26 -5
- package/dist/patches/openai.d.ts.map +1 -1
- package/dist/patches/openai.js +225 -21
- package/dist/patches/openai.js.map +1 -1
- package/dist/resolve.d.ts.map +1 -1
- package/dist/resolve.js +6 -2
- package/dist/resolve.js.map +1 -1
- package/dist/retry.d.ts +54 -0
- package/dist/retry.d.ts.map +1 -0
- package/dist/retry.js +99 -0
- package/dist/retry.js.map +1 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +2 -1
- package/dist/version.js.map +1 -1
- package/package.json +35 -6
package/README.md
CHANGED
|
@@ -25,6 +25,8 @@ Get a free API key at [app.promptguard.co](https://app.promptguard.co).
|
|
|
25
25
|
> **PromptGuard fails open by default** — if the Guard API is unavailable, calls proceed *unscanned* so your app stays up. Set `failOpen: false` to block (fail closed) on a Guard outage instead.
|
|
26
26
|
|
|
27
27
|
> **Module format:** the package currently ships **CommonJS** (`require`) builds. It works in ESM projects via Node's CJS interop (`import { init } from 'promptguard-sdk'` transpiles to a `require`), and in plain CommonJS via `const { init } = require('promptguard-sdk')`.
|
|
28
|
+
>
|
|
29
|
+
> **Running a native-ESM app?** Auto-instrumentation (`init()`) may not cover your LLM calls — see [Limitations: ESM apps](#limitations) before relying on enforce mode.
|
|
28
30
|
|
|
29
31
|
## Option 1: Auto-Instrumentation (Recommended)
|
|
30
32
|
|
|
@@ -50,20 +52,36 @@ const response = await client.chat.completions.create({
|
|
|
50
52
|
});
|
|
51
53
|
```
|
|
52
54
|
|
|
55
|
+
> `init()` is intentionally quiet on success (SDK logging defaults to `warn`). To confirm which provider SDKs are actually being protected, read `getAppliedPatches()` — the source of truth for what got patched:
|
|
56
|
+
> ```typescript
|
|
57
|
+
> import { init, getAppliedPatches } from 'promptguard-sdk';
|
|
58
|
+
> init({ apiKey: 'pg_live_xxx' });
|
|
59
|
+
> console.log('PromptGuard protecting:', getAppliedPatches()); // e.g. ['openai']
|
|
60
|
+
> ```
|
|
61
|
+
> If this list is empty, nothing is being scanned (see [Limitations: ESM apps](#limitations)). Set `logLevel: 'info'` on `init()` to also emit a one-line confirmation banner.
|
|
62
|
+
|
|
53
63
|
### Supported SDKs
|
|
54
64
|
|
|
55
65
|
Auto-instrumentation patches the `create` / `generateContent` / `chat` / `send` methods on:
|
|
56
66
|
|
|
57
67
|
| SDK | npm Package | What Gets Patched |
|
|
58
68
|
|-----|------------|-------------------|
|
|
59
|
-
| OpenAI | `openai` | `chat.completions.create` |
|
|
69
|
+
| OpenAI | `openai` | `chat.completions.create`, `responses.create` (string and message-item `input` forms) |
|
|
60
70
|
| Anthropic | `@anthropic-ai/sdk` | `messages.create` |
|
|
61
71
|
| Google Generative AI | `@google/generative-ai` | `generateContent` |
|
|
62
72
|
| Cohere | `cohere-ai` | `Client.chat` / `ClientV2.chat` |
|
|
63
|
-
| AWS Bedrock | `@aws-sdk/client-bedrock-runtime` | `BedrockRuntimeClient.send` (InvokeModel, Converse) |
|
|
73
|
+
| AWS Bedrock | `@aws-sdk/client-bedrock-runtime` | `BedrockRuntimeClient.send` (InvokeModel, InvokeModelWithResponseStream, Converse, ConverseStream) |
|
|
64
74
|
|
|
65
75
|
Any framework built on these SDKs is automatically covered: **LangChain.js**, **Vercel AI SDK**, **AutoGen**, **Semantic Kernel**, and more.
|
|
66
76
|
|
|
77
|
+
> Patches attach to the modules resolved via CommonJS `require()`. If `init()` finds **no** patchable SDK it logs a warning (nothing would be scanned). You can also verify at runtime with `getAppliedPatches()`:
|
|
78
|
+
> ```typescript
|
|
79
|
+
> import { init, getAppliedPatches } from 'promptguard-sdk';
|
|
80
|
+
> init({ apiKey: 'pg_live_xxx' });
|
|
81
|
+
> console.log(getAppliedPatches()); // e.g. ['openai', 'anthropic']
|
|
82
|
+
> ```
|
|
83
|
+
> Native-ESM apps: see [Limitations: ESM apps](#limitations).
|
|
84
|
+
|
|
67
85
|
### Modes
|
|
68
86
|
|
|
69
87
|
```typescript
|
|
@@ -159,6 +177,10 @@ const result = await chain.invoke(
|
|
|
159
177
|
|
|
160
178
|
The callback handler provides rich context to PromptGuard - chain names, tool calls, agent steps - for more precise threat detection.
|
|
161
179
|
|
|
180
|
+
> **Redact decisions block in enforce mode:** LangChain callbacks observe calls but cannot rewrite the inputs of the in-flight LLM call, so a `redact` decision cannot be honored — in enforce mode it is escalated to a block (`PromptGuardBlockedError`) rather than silently sending the content the Guard API asked to redact. Use auto-instrumentation or explicit `GuardClient.scan()` calls if you need actual redaction.
|
|
181
|
+
>
|
|
182
|
+
> `scanResponses` defaults to `false` (consistent with `init()` and the Vercel AI middleware) — pass `scanResponses: true` to opt in to output scanning.
|
|
183
|
+
|
|
162
184
|
### Vercel AI SDK
|
|
163
185
|
|
|
164
186
|
```typescript
|
|
@@ -215,17 +237,35 @@ const outputDecision = await guard.scan(
|
|
|
215
237
|
|
|
216
238
|
## Retry Logic
|
|
217
239
|
|
|
218
|
-
Both `PromptGuard` and `GuardClient` support configurable retry behavior for transient failures:
|
|
240
|
+
Both the proxy client (`PromptGuard`) and the Guard client (`GuardClient`) support configurable retry behavior for transient failures:
|
|
219
241
|
|
|
220
242
|
```typescript
|
|
243
|
+
// Proxy client
|
|
221
244
|
const pg = new PromptGuard({
|
|
222
245
|
apiKey: 'pg_live_xxx',
|
|
223
246
|
maxRetries: 3, // Number of retry attempts (default: 3)
|
|
224
247
|
retryDelay: 500, // Base delay in ms between retries (default: 1000)
|
|
225
248
|
});
|
|
249
|
+
|
|
250
|
+
// Guard client (standalone scanning)
|
|
251
|
+
const guard = new GuardClient({
|
|
252
|
+
apiKey: 'pg_live_xxx',
|
|
253
|
+
maxRetries: 3, // default: 3
|
|
254
|
+
retryDelay: 500, // default: 1000
|
|
255
|
+
});
|
|
226
256
|
```
|
|
227
257
|
|
|
228
|
-
|
|
258
|
+
Because auto-instrumentation (`init()`) and the framework integrations all scan through `GuardClient`, they retry transient Guard API failures too — pass `maxRetries` / `retryDelay` to `init()`, `PromptGuardCallbackHandler`, or `promptGuardMiddleware`:
|
|
259
|
+
|
|
260
|
+
```typescript
|
|
261
|
+
init({ apiKey: 'pg_live_xxx', maxRetries: 3, retryDelay: 500 });
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
Retries use exponential backoff starting from `retryDelay`, with jitter so concurrent clients don't retry in lockstep. A server-provided `Retry-After` header is honored but clamped to 60 seconds. Only transient errors (network timeouts, 429/5xx responses) are retried; client errors (4xx) fail immediately.
|
|
265
|
+
|
|
266
|
+
> **Enforcement is unchanged by retries.** Retrying only affects *transient* Guard failures (network errors, 429/5xx). A real `block` / `redact` decision is terminal and is never retried, and once retries are exhausted a `GuardApiError` is raised so your existing `failOpen` policy governs — exactly as it would with `maxRetries: 0`. Retries never turn a would-be error into an allow.
|
|
267
|
+
|
|
268
|
+
> **Idempotency caveat:** all requests — including `POST`s — are retried on transient failure. If a request reached the server but the response was lost, the retry re-submits it. Chat/completion/scan calls are safe to re-submit, but each attempt may bill separately; set `maxRetries: 0` if you need strict at-most-once semantics.
|
|
229
269
|
|
|
230
270
|
## Embeddings
|
|
231
271
|
|
|
@@ -275,11 +315,11 @@ const report = await pg.redteam.runAutonomous({
|
|
|
275
315
|
budget: 200,
|
|
276
316
|
targetPreset: 'support_bot:strict', // snake_case `target_preset` also accepted
|
|
277
317
|
});
|
|
278
|
-
console.log(`Grade: ${report.grade}, Bypass rate: ${(report.
|
|
318
|
+
console.log(`Grade: ${report.grade}, Bypass rate: ${(report.bypassRate * 100).toFixed(0)}%`);
|
|
279
319
|
|
|
280
320
|
// Get Attack Intelligence stats
|
|
281
321
|
const stats = await pg.redteam.intelligenceStats();
|
|
282
|
-
console.log(`Total patterns: ${stats.
|
|
322
|
+
console.log(`Total patterns: ${stats.totalPatterns}`);
|
|
283
323
|
```
|
|
284
324
|
|
|
285
325
|
## Configuration
|
|
@@ -298,6 +338,29 @@ console.log(`Total patterns: ${stats.total_patterns}`);
|
|
|
298
338
|
> The proxy client (`PromptGuard`) talks to the `/api/v1/proxy` endpoints. If you set `baseUrl` / `PROMPTGUARD_BASE_URL` to `.../api/v1` (without `/proxy`), the SDK appends the `/proxy` suffix for you, so requests still land on the proxy.
|
|
299
339
|
>
|
|
300
340
|
> **Security:** the SDK sends your API key (and, in proxy mode, your prompt content) to whatever `PROMPTGUARD_BASE_URL` points at. Self-hosting is supported, so only point it at a host you trust.
|
|
341
|
+
>
|
|
342
|
+
> **Logging is process-global:** `logLevel` / `silent` set a single shared log level for the whole SDK. If several integrations or `init()` calls pass different values, the most recently constructed one wins. Use `setLogLevel()` directly for fine-grained control.
|
|
343
|
+
|
|
344
|
+
## Limitations
|
|
345
|
+
|
|
346
|
+
### ESM apps (auto-instrumentation)
|
|
347
|
+
|
|
348
|
+
Auto-instrumentation (`init()`) patches the provider modules that Node resolves via **CommonJS `require()`**. If your application runs as **native ESM** (`"type": "module"` in package.json, or `.mjs` files) and a provider ships separate ESM builds, the module instances your code `import`s can be *different objects* from the ones the SDK patched — the **dual-package hazard**. In that case your LLM calls bypass the patches entirely and **enforce mode silently protects nothing**.
|
|
349
|
+
|
|
350
|
+
What to do:
|
|
351
|
+
|
|
352
|
+
- **Verify at runtime** with `getAppliedPatches()` after `init()` — and note that a patch being listed proves the CJS build was patched, not that your ESM imports go through it. `init()` also logs a warning when it applies zero patches.
|
|
353
|
+
- **Prefer the ESM-safe APIs**, which don't rely on module patching:
|
|
354
|
+
- LangChain: `PromptGuardCallbackHandler` (`promptguard-sdk/integrations/langchain`)
|
|
355
|
+
- Vercel AI SDK: `promptGuardMiddleware` (`promptguard-sdk/integrations/vercel-ai`)
|
|
356
|
+
- Any framework: explicit `GuardClient.scan()` calls around your LLM invocations
|
|
357
|
+
- Transpiled-to-CJS TypeScript apps (the common `tsc`/`ts-node` default) are **not** affected — their `import`s compile to `require()` and hit the patched modules.
|
|
358
|
+
|
|
359
|
+
### Other limitations
|
|
360
|
+
|
|
361
|
+
- **Streaming responses are not output-scanned.** With auto-instrumentation and `scanResponses: true`, streaming calls (`stream: true`, Bedrock `ConverseStreamCommand`, etc.) skip the output scan — the stream is consumed incrementally by your code and cannot be buffered without breaking stream semantics. Input scanning still applies. A `debug`-level log is emitted when the output scan is skipped. The same applies to the Vercel AI SDK middleware: `streamText()` outputs are not scanned (`wrapStream` logs the skip); `generateText()` outputs are.
|
|
362
|
+
- **OpenAI `APIPromise` helpers are not preserved by auto-instrumentation.** Patched methods return a plain `Promise`, so `.withResponse()` / `.asResponse()` on `client.chat.completions.create(...)` are unavailable while `init()` is active. `await` the call and use the plain result instead.
|
|
363
|
+
- **Proxy client streaming:** `pg.chat.completions.create({ stream: true })` is rejected with a clear error — streaming is not yet supported by the proxy client.
|
|
301
364
|
|
|
302
365
|
## Error Handling
|
|
303
366
|
|
|
@@ -338,6 +401,8 @@ import type {
|
|
|
338
401
|
} from 'promptguard-sdk';
|
|
339
402
|
```
|
|
340
403
|
|
|
404
|
+
> **Response fields are camelCase — with one deliberate exception.** The SDK's normalized response objects (the `security`, `redteam`, `agent`, `scrape`, and `guard` namespaces) use camelCase field names (e.g. `report.bypassRate`, `stats.totalPatterns`, `validation.riskScore`, `result.threatsDetected`) regardless of the snake_case wire format — consistent with `GuardDecision` and `SecurityScanResult`. The **OpenAI-compatible** responses (`chat.completions`, `completions`, `embeddings`, i.e. `ChatCompletionResponse`) are the exception: they intentionally preserve OpenAI's snake_case shape (`choices[].finish_reason`, `usage.prompt_tokens`, …) so they stay drop-in compatible with the `openai` client. Request options are camelCase throughout (`maxTokens`, `targetPreset`), including `GuardContext` (`chainName`, `agentId`, `sessionId`, `toolCalls`).
|
|
405
|
+
|
|
341
406
|
## Links
|
|
342
407
|
|
|
343
408
|
- [Documentation](https://docs.promptguard.co)
|
package/dist/auto.d.ts
CHANGED
|
@@ -30,18 +30,68 @@ export interface InitOptions {
|
|
|
30
30
|
scanResponses?: boolean;
|
|
31
31
|
/** HTTP timeout in ms for Guard API calls (default: `10000`). */
|
|
32
32
|
timeout?: number;
|
|
33
|
+
/**
|
|
34
|
+
* Retry attempts for transient Guard API failures (network errors and
|
|
35
|
+
* 429/5xx responses) before the `failOpen` policy governs. Default: `3`.
|
|
36
|
+
* Retries never change the eventual decision — see {@link GuardClientConfig}.
|
|
37
|
+
*/
|
|
38
|
+
maxRetries?: number;
|
|
39
|
+
/** Base delay in ms between Guard API retries (exponential backoff). Default: `1000`. */
|
|
40
|
+
retryDelay?: number;
|
|
33
41
|
/**
|
|
34
42
|
* SDK log verbosity (default: `"warn"`). Set to `"silent"` to suppress all
|
|
35
43
|
* SDK logging, or `"info"`/`"debug"` for the init banner and more detail.
|
|
44
|
+
* NOTE: this sets the **process-global** SDK log level (shared with the
|
|
45
|
+
* framework integrations); the most recent setter wins.
|
|
36
46
|
*/
|
|
37
47
|
logLevel?: LogLevel;
|
|
38
48
|
/** Convenience shorthand for `logLevel: "silent"`. */
|
|
39
49
|
silent?: boolean;
|
|
40
50
|
}
|
|
51
|
+
/**
|
|
52
|
+
* Initialise PromptGuard auto-instrumentation.
|
|
53
|
+
*
|
|
54
|
+
* Patches the provider SDKs (`openai`, `@anthropic-ai/sdk`,
|
|
55
|
+
* `@google/generative-ai`, `cohere-ai`, `@aws-sdk/client-bedrock-runtime`)
|
|
56
|
+
* so every LLM call they make is scanned by the Guard API.
|
|
57
|
+
*
|
|
58
|
+
* **Limitation — ESM apps (dual-package hazard):** patches are applied to the
|
|
59
|
+
* module instances resolved via CommonJS `require()`. If your application runs
|
|
60
|
+
* as native ESM (`"type": "module"` / `.mjs`) and the provider ships separate
|
|
61
|
+
* ESM builds, your `import`ed module instances can be *different objects* from
|
|
62
|
+
* the patched CJS ones — in that case auto-instrumentation silently protects
|
|
63
|
+
* nothing. Use {@link getAppliedPatches} as a runtime canary to verify the
|
|
64
|
+
* providers you use were actually patched, and prefer the ESM-safe
|
|
65
|
+
* alternatives: the LangChain callback handler
|
|
66
|
+
* (`promptguard-sdk/integrations/langchain`), the Vercel AI SDK middleware
|
|
67
|
+
* (`promptguard-sdk/integrations/vercel-ai`), or explicit `GuardClient.scan()`
|
|
68
|
+
* calls. See README "Limitations: ESM apps".
|
|
69
|
+
*
|
|
70
|
+
* When zero patches could be applied, a warning is logged so a
|
|
71
|
+
* misconfiguration never fails silently.
|
|
72
|
+
*/
|
|
41
73
|
export declare function init(options?: InitOptions): void;
|
|
42
74
|
export declare function shutdown(): void;
|
|
43
75
|
export declare function getGuardClient(): GuardClient | null;
|
|
44
76
|
export declare function getMode(): "enforce" | "monitor";
|
|
45
77
|
export declare function isFailOpen(): boolean;
|
|
46
78
|
export declare function shouldScanResponses(): boolean;
|
|
79
|
+
/**
|
|
80
|
+
* Runtime canary: the names of the auto-instrumentation patches that were
|
|
81
|
+
* actually applied by {@link init} (e.g. `["openai", "anthropic"]`).
|
|
82
|
+
*
|
|
83
|
+
* Because patches attach to the CJS-resolved provider modules, an ESM app can
|
|
84
|
+
* call `init()` successfully and still be unprotected (see the dual-package
|
|
85
|
+
* hazard note on {@link init}). Assert on this at startup when you rely on
|
|
86
|
+
* enforce mode:
|
|
87
|
+
*
|
|
88
|
+
* @example
|
|
89
|
+
* ```ts
|
|
90
|
+
* init({ apiKey: "pg_live_xxx" });
|
|
91
|
+
* if (!getAppliedPatches().includes("openai")) {
|
|
92
|
+
* throw new Error("PromptGuard did not patch the openai SDK");
|
|
93
|
+
* }
|
|
94
|
+
* ```
|
|
95
|
+
*/
|
|
96
|
+
export declare function getAppliedPatches(): string[];
|
|
47
97
|
//# sourceMappingURL=auto.d.ts.map
|
package/dist/auto.d.ts.map
CHANGED
|
@@ -1 +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;AACrC,OAAO,EAAE,KAAK,QAAQ,EAAuB,MAAM,UAAU,CAAA;AAkB7D,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;IAChB
|
|
1
|
+
{"version":3,"file":"auto.d.ts","sourceRoot":"","sources":["../src/auto.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AACrC,OAAO,EAAE,KAAK,QAAQ,EAAuB,MAAM,UAAU,CAAA;AAkB7D,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;IAChB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,yFAAyF;IACzF,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,QAAQ,CAAA;IACnB,sDAAsD;IACtD,MAAM,CAAC,EAAE,OAAO,CAAA;CACjB;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,IAAI,CAAC,OAAO,GAAE,WAAgB,GAAG,IAAI,CAqCpD;AAED,wBAAgB,QAAQ,IAAI,IAAI,CAU/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;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,EAAE,CAE5C"}
|
package/dist/auto.js
CHANGED
|
@@ -25,6 +25,7 @@ exports.getGuardClient = getGuardClient;
|
|
|
25
25
|
exports.getMode = getMode;
|
|
26
26
|
exports.isFailOpen = isFailOpen;
|
|
27
27
|
exports.shouldScanResponses = shouldScanResponses;
|
|
28
|
+
exports.getAppliedPatches = getAppliedPatches;
|
|
28
29
|
const guard_1 = require("./guard");
|
|
29
30
|
const logger_1 = require("./logger");
|
|
30
31
|
const resolve_1 = require("./resolve");
|
|
@@ -36,6 +37,28 @@ let mode = "enforce";
|
|
|
36
37
|
let failOpen = true;
|
|
37
38
|
let scanResponses = false;
|
|
38
39
|
const appliedPatches = [];
|
|
40
|
+
/**
|
|
41
|
+
* Initialise PromptGuard auto-instrumentation.
|
|
42
|
+
*
|
|
43
|
+
* Patches the provider SDKs (`openai`, `@anthropic-ai/sdk`,
|
|
44
|
+
* `@google/generative-ai`, `cohere-ai`, `@aws-sdk/client-bedrock-runtime`)
|
|
45
|
+
* so every LLM call they make is scanned by the Guard API.
|
|
46
|
+
*
|
|
47
|
+
* **Limitation — ESM apps (dual-package hazard):** patches are applied to the
|
|
48
|
+
* module instances resolved via CommonJS `require()`. If your application runs
|
|
49
|
+
* as native ESM (`"type": "module"` / `.mjs`) and the provider ships separate
|
|
50
|
+
* ESM builds, your `import`ed module instances can be *different objects* from
|
|
51
|
+
* the patched CJS ones — in that case auto-instrumentation silently protects
|
|
52
|
+
* nothing. Use {@link getAppliedPatches} as a runtime canary to verify the
|
|
53
|
+
* providers you use were actually patched, and prefer the ESM-safe
|
|
54
|
+
* alternatives: the LangChain callback handler
|
|
55
|
+
* (`promptguard-sdk/integrations/langchain`), the Vercel AI SDK middleware
|
|
56
|
+
* (`promptguard-sdk/integrations/vercel-ai`), or explicit `GuardClient.scan()`
|
|
57
|
+
* calls. See README "Limitations: ESM apps".
|
|
58
|
+
*
|
|
59
|
+
* When zero patches could be applied, a warning is logged so a
|
|
60
|
+
* misconfiguration never fails silently.
|
|
61
|
+
*/
|
|
39
62
|
function init(options = {}) {
|
|
40
63
|
if (options.silent) {
|
|
41
64
|
(0, logger_1.setLogLevel)("silent");
|
|
@@ -52,13 +75,20 @@ function init(options = {}) {
|
|
|
52
75
|
apiKey,
|
|
53
76
|
baseUrl,
|
|
54
77
|
timeout: options.timeout ?? 10000,
|
|
78
|
+
maxRetries: options.maxRetries,
|
|
79
|
+
retryDelay: options.retryDelay,
|
|
55
80
|
});
|
|
56
81
|
mode = resolvedMode;
|
|
57
82
|
failOpen = options.failOpen ?? true;
|
|
58
83
|
scanResponses = options.scanResponses ?? false;
|
|
59
84
|
applyPatches();
|
|
60
|
-
//
|
|
61
|
-
|
|
85
|
+
// One-line confirmation of which provider SDKs are actually protected.
|
|
86
|
+
// Suppressed by default (info level); set logLevel: "info" to see it, or
|
|
87
|
+
// read the same list programmatically via getAppliedPatches(). When ZERO
|
|
88
|
+
// patches applied, applyPatches() already logged a warn (visible by default).
|
|
89
|
+
const protecting = getAppliedPatches();
|
|
90
|
+
logger_1.logger.info(`auto-instrumentation initialised (mode=${mode}, fail_open=${failOpen}) — ` +
|
|
91
|
+
`protecting: ${protecting.length ? protecting.join(", ") : "none"}`);
|
|
62
92
|
}
|
|
63
93
|
function shutdown() {
|
|
64
94
|
for (const patch of appliedPatches) {
|
|
@@ -87,6 +117,26 @@ function isFailOpen() {
|
|
|
87
117
|
function shouldScanResponses() {
|
|
88
118
|
return scanResponses;
|
|
89
119
|
}
|
|
120
|
+
/**
|
|
121
|
+
* Runtime canary: the names of the auto-instrumentation patches that were
|
|
122
|
+
* actually applied by {@link init} (e.g. `["openai", "anthropic"]`).
|
|
123
|
+
*
|
|
124
|
+
* Because patches attach to the CJS-resolved provider modules, an ESM app can
|
|
125
|
+
* call `init()` successfully and still be unprotected (see the dual-package
|
|
126
|
+
* hazard note on {@link init}). Assert on this at startup when you rely on
|
|
127
|
+
* enforce mode:
|
|
128
|
+
*
|
|
129
|
+
* @example
|
|
130
|
+
* ```ts
|
|
131
|
+
* init({ apiKey: "pg_live_xxx" });
|
|
132
|
+
* if (!getAppliedPatches().includes("openai")) {
|
|
133
|
+
* throw new Error("PromptGuard did not patch the openai SDK");
|
|
134
|
+
* }
|
|
135
|
+
* ```
|
|
136
|
+
*/
|
|
137
|
+
function getAppliedPatches() {
|
|
138
|
+
return appliedPatches.map((p) => p.name);
|
|
139
|
+
}
|
|
90
140
|
// ---------------------------------------------------------------------------
|
|
91
141
|
// Patch orchestration
|
|
92
142
|
// ---------------------------------------------------------------------------
|
|
@@ -102,12 +152,32 @@ function applyPatches() {
|
|
|
102
152
|
try {
|
|
103
153
|
const patchModule = require(mod.path);
|
|
104
154
|
if (patchModule.apply()) {
|
|
105
|
-
|
|
155
|
+
// apply() is idempotent per patch module, so a second init() without
|
|
156
|
+
// shutdown() reports "already patched" success. Skip the push when
|
|
157
|
+
// the patch is already tracked — a duplicate entry would make the
|
|
158
|
+
// getAppliedPatches() canary lie and call revert() twice on
|
|
159
|
+
// shutdown().
|
|
160
|
+
if (!appliedPatches.some((p) => p.name === mod.name)) {
|
|
161
|
+
appliedPatches.push({ name: mod.name, revert: patchModule.revert });
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
logger_1.logger.debug(`${mod.name} patch not applied: SDK not resolvable via require() ` +
|
|
166
|
+
`(not installed, or only reachable as ESM)`);
|
|
106
167
|
}
|
|
107
168
|
}
|
|
108
|
-
catch {
|
|
109
|
-
|
|
169
|
+
catch (err) {
|
|
170
|
+
logger_1.logger.debug(`${mod.name} patch not applied: ${err instanceof Error ? err.message : String(err)}`);
|
|
110
171
|
}
|
|
111
172
|
}
|
|
173
|
+
if (appliedPatches.length === 0) {
|
|
174
|
+
logger_1.logger.warn("init() applied ZERO auto-instrumentation patches — no supported LLM SDK was " +
|
|
175
|
+
"resolvable via CommonJS require(), so NO calls are being scanned. If your app " +
|
|
176
|
+
'runs as native ESM ("type": "module" / .mjs), auto-instrumentation cannot see ' +
|
|
177
|
+
"the module instances your code imports (dual-package hazard). Use the ESM-safe " +
|
|
178
|
+
"integrations instead: the LangChain callback handler, the Vercel AI SDK " +
|
|
179
|
+
"middleware, or explicit GuardClient.scan() calls. " +
|
|
180
|
+
'See README "Limitations: ESM apps". Set logLevel: "debug" for per-SDK reasons.');
|
|
181
|
+
}
|
|
112
182
|
}
|
|
113
183
|
//# sourceMappingURL=auto.js.map
|
package/dist/auto.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auto.js","sourceRoot":"","sources":["../src/auto.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;GAkBG;;
|
|
1
|
+
{"version":3,"file":"auto.js","sourceRoot":"","sources":["../src/auto.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;GAkBG;;AAyEH,oBAqCC;AAED,4BAUC;AAMD,wCAEC;AAED,0BAEC;AAED,gCAEC;AAED,kDAEC;AAmBD,8CAEC;AAjKD,mCAAqC;AACrC,qCAA6D;AAC7D,uCAA8C;AAE9C,8EAA8E;AAC9E,eAAe;AACf,8EAA8E;AAE9E,IAAI,WAAW,GAAuB,IAAI,CAAA;AAC1C,IAAI,IAAI,GAA0B,SAAS,CAAA;AAC3C,IAAI,QAAQ,GAAG,IAAI,CAAA;AACnB,IAAI,aAAa,GAAG,KAAK,CAAA;AAEzB,MAAM,cAAc,GAAgD,EAAE,CAAA;AAoCtE;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,SAAgB,IAAI,CAAC,UAAuB,EAAE;IAC5C,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACnB,IAAA,oBAAW,EAAC,QAAQ,CAAC,CAAA;IACvB,CAAC;SAAM,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;QAC5B,IAAA,oBAAW,EAAC,OAAO,CAAC,QAAQ,CAAC,CAAA;IAC/B,CAAC;IAED,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,IAAA,4BAAkB,EAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,OAAO,CAAC,CAAA;IAE/E,MAAM,YAAY,GAAG,OAAO,CAAC,IAAI,IAAI,SAAS,CAAA;IAC9C,IAAI,YAAY,KAAK,SAAS,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;QAC7D,MAAM,IAAI,KAAK,CAAC,6CAA6C,YAAY,GAAG,CAAC,CAAA;IAC/E,CAAC;IAED,WAAW,GAAG,IAAI,mBAAW,CAAC;QAC5B,MAAM;QACN,OAAO;QACP,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,KAAM;QAClC,UAAU,EAAE,OAAO,CAAC,UAAU;QAC9B,UAAU,EAAE,OAAO,CAAC,UAAU;KAC/B,CAAC,CAAA;IAEF,IAAI,GAAG,YAAY,CAAA;IACnB,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,IAAI,CAAA;IACnC,aAAa,GAAG,OAAO,CAAC,aAAa,IAAI,KAAK,CAAA;IAE9C,YAAY,EAAE,CAAA;IAEd,uEAAuE;IACvE,yEAAyE;IACzE,yEAAyE;IACzE,8EAA8E;IAC9E,MAAM,UAAU,GAAG,iBAAiB,EAAE,CAAA;IACtC,eAAM,CAAC,IAAI,CACT,0CAA0C,IAAI,eAAe,QAAQ,MAAM;QACzE,eAAe,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CACtE,CAAA;AACH,CAAC;AAED,SAAgB,QAAQ;IACtB,KAAK,MAAM,KAAK,IAAI,cAAc,EAAE,CAAC;QACnC,IAAI,CAAC;YACH,KAAK,CAAC,MAAM,EAAE,CAAA;QAChB,CAAC;QAAC,MAAM,CAAC;YACP,cAAc;QAChB,CAAC;IACH,CAAC;IACD,cAAc,CAAC,MAAM,GAAG,CAAC,CAAA;IACzB,WAAW,GAAG,IAAI,CAAA;AACpB,CAAC;AAED,8EAA8E;AAC9E,8BAA8B;AAC9B,8EAA8E;AAE9E,SAAgB,cAAc;IAC5B,OAAO,WAAW,CAAA;AACpB,CAAC;AAED,SAAgB,OAAO;IACrB,OAAO,IAAI,CAAA;AACb,CAAC;AAED,SAAgB,UAAU;IACxB,OAAO,QAAQ,CAAA;AACjB,CAAC;AAED,SAAgB,mBAAmB;IACjC,OAAO,aAAa,CAAA;AACtB,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,SAAgB,iBAAiB;IAC/B,OAAO,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA;AAC1C,CAAC;AAED,8EAA8E;AAC9E,sBAAsB;AACtB,8EAA8E;AAE9E,SAAS,YAAY;IACnB,MAAM,YAAY,GAAG;QACnB,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,kBAAkB,EAAE;QAC5C,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,qBAAqB,EAAE;QAClD,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,kBAAkB,EAAE;QAC5C,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,kBAAkB,EAAE;QAC5C,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,mBAAmB,EAAE;KAC/C,CAAA;IAED,KAAK,MAAM,GAAG,IAAI,YAAY,EAAE,CAAC;QAC/B,IAAI,CAAC;YACH,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAGnC,CAAA;YACD,IAAI,WAAW,CAAC,KAAK,EAAE,EAAE,CAAC;gBACxB,qEAAqE;gBACrE,mEAAmE;gBACnE,kEAAkE;gBAClE,4DAA4D;gBAC5D,cAAc;gBACd,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;oBACrD,cAAc,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,CAAC,CAAA;gBACrE,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,eAAM,CAAC,KAAK,CACV,GAAG,GAAG,CAAC,IAAI,uDAAuD;oBAChE,2CAA2C,CAC9C,CAAA;YACH,CAAC;QACH,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,eAAM,CAAC,KAAK,CACV,GAAG,GAAG,CAAC,IAAI,uBAAuB,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CACrF,CAAA;QACH,CAAC;IACH,CAAC;IAED,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAChC,eAAM,CAAC,IAAI,CACT,8EAA8E;YAC5E,gFAAgF;YAChF,gFAAgF;YAChF,iFAAiF;YACjF,0EAA0E;YAC1E,oDAAoD;YACpD,gFAAgF,CACnF,CAAA;IACH,CAAC;AACH,CAAC"}
|
package/dist/client.d.ts
CHANGED
|
@@ -2,26 +2,47 @@
|
|
|
2
2
|
* PromptGuard proxy client — OpenAI-compatible API with built-in
|
|
3
3
|
* security scanning, retry logic, and namespace helpers.
|
|
4
4
|
*/
|
|
5
|
-
interface PromptGuardConfig {
|
|
5
|
+
export interface PromptGuardConfig {
|
|
6
6
|
apiKey: string;
|
|
7
|
+
/**
|
|
8
|
+
* API base URL. Defaults to the public PromptGuard proxy
|
|
9
|
+
* (`https://api.promptguard.co/api/v1/proxy`) or `PROMPTGUARD_BASE_URL`.
|
|
10
|
+
* The `/proxy` suffix is appended automatically when missing.
|
|
11
|
+
*/
|
|
7
12
|
baseUrl?: string;
|
|
13
|
+
/** HTTP timeout in milliseconds for each request attempt. Default: `30000`. */
|
|
8
14
|
timeout?: number;
|
|
15
|
+
/**
|
|
16
|
+
* Number of retry attempts for transient failures (network errors and
|
|
17
|
+
* 429/5xx responses). Default: `3`. Set to `0` for strict at-most-once
|
|
18
|
+
* semantics. Negative values are clamped to `0`.
|
|
19
|
+
*/
|
|
9
20
|
maxRetries?: number;
|
|
21
|
+
/** Base delay in ms between retries (exponential backoff). Default: `1000`. */
|
|
10
22
|
retryDelay?: number;
|
|
11
23
|
}
|
|
12
|
-
interface Message {
|
|
13
|
-
role: "system" | "user" | "assistant";
|
|
24
|
+
export interface Message {
|
|
25
|
+
role: "system" | "user" | "assistant" | "tool" | "function";
|
|
14
26
|
content: string;
|
|
15
27
|
}
|
|
16
|
-
interface ChatCompletionRequest {
|
|
28
|
+
export interface ChatCompletionRequest {
|
|
17
29
|
model: string;
|
|
18
30
|
messages: Message[];
|
|
19
31
|
temperature?: number;
|
|
32
|
+
/** Maximum tokens to generate. Serialized to the wire as `max_tokens`. */
|
|
20
33
|
maxTokens?: number;
|
|
21
|
-
|
|
34
|
+
/**
|
|
35
|
+
* OpenAI-compatible escape hatch: any additional keys (e.g. `top_p`,
|
|
36
|
+
* `frequency_penalty`, `stop`, `tools`) are forwarded verbatim to the proxy.
|
|
37
|
+
* Because these keys are not type-checked, a misspelled parameter is silently
|
|
38
|
+
* passed through rather than flagged at compile time — double-check the
|
|
39
|
+
* spelling of options not listed above. (`stream: true` is the one key
|
|
40
|
+
* rejected: the client parses a single JSON response body, so it throws at
|
|
41
|
+
* runtime instead of forwarding.)
|
|
42
|
+
*/
|
|
22
43
|
[key: string]: unknown;
|
|
23
44
|
}
|
|
24
|
-
interface ChatCompletionResponse {
|
|
45
|
+
export interface ChatCompletionResponse {
|
|
25
46
|
id: string;
|
|
26
47
|
object: string;
|
|
27
48
|
created: number;
|
|
@@ -37,14 +58,22 @@ interface ChatCompletionResponse {
|
|
|
37
58
|
total_tokens: number;
|
|
38
59
|
};
|
|
39
60
|
}
|
|
40
|
-
interface CompletionRequest {
|
|
61
|
+
export interface CompletionRequest {
|
|
41
62
|
model: string;
|
|
42
63
|
prompt: string;
|
|
43
64
|
temperature?: number;
|
|
65
|
+
/** Maximum tokens to generate. Serialized to the wire as `max_tokens`. */
|
|
44
66
|
maxTokens?: number;
|
|
67
|
+
/**
|
|
68
|
+
* OpenAI-compatible escape hatch: any additional keys are forwarded verbatim
|
|
69
|
+
* to the proxy. Because these keys are not type-checked, a misspelled
|
|
70
|
+
* parameter is silently passed through rather than flagged at compile time.
|
|
71
|
+
* (`stream: true` is rejected at runtime — the client parses a single JSON
|
|
72
|
+
* response body.)
|
|
73
|
+
*/
|
|
45
74
|
[key: string]: unknown;
|
|
46
75
|
}
|
|
47
|
-
interface CompletionResponse {
|
|
76
|
+
export interface CompletionResponse {
|
|
48
77
|
id: string;
|
|
49
78
|
object: string;
|
|
50
79
|
created: number;
|
|
@@ -60,12 +89,18 @@ interface CompletionResponse {
|
|
|
60
89
|
total_tokens: number;
|
|
61
90
|
};
|
|
62
91
|
}
|
|
63
|
-
interface EmbeddingRequest {
|
|
92
|
+
export interface EmbeddingRequest {
|
|
64
93
|
model: string;
|
|
65
94
|
input: string | string[];
|
|
95
|
+
/**
|
|
96
|
+
* OpenAI-compatible escape hatch: any additional keys (e.g. `dimensions`,
|
|
97
|
+
* `encoding_format`, `user`) are forwarded verbatim to the proxy. Because
|
|
98
|
+
* these keys are not type-checked, a misspelled parameter is silently passed
|
|
99
|
+
* through rather than flagged at compile time.
|
|
100
|
+
*/
|
|
66
101
|
[key: string]: unknown;
|
|
67
102
|
}
|
|
68
|
-
interface EmbeddingResponse {
|
|
103
|
+
export interface EmbeddingResponse {
|
|
69
104
|
object: string;
|
|
70
105
|
data: Array<{
|
|
71
106
|
object: string;
|
|
@@ -78,51 +113,59 @@ interface EmbeddingResponse {
|
|
|
78
113
|
total_tokens: number;
|
|
79
114
|
};
|
|
80
115
|
}
|
|
81
|
-
interface SecurityScanResult {
|
|
116
|
+
export interface SecurityScanResult {
|
|
82
117
|
blocked: boolean;
|
|
83
118
|
decision: "allow" | "block" | "redact";
|
|
84
119
|
reason?: string;
|
|
85
120
|
threatType?: string;
|
|
86
121
|
confidence?: number;
|
|
87
122
|
}
|
|
88
|
-
interface RedactResult {
|
|
123
|
+
export interface RedactResult {
|
|
89
124
|
original: string;
|
|
90
125
|
redacted: string;
|
|
91
126
|
piiFound: string[];
|
|
92
127
|
}
|
|
93
|
-
interface ScrapeResult {
|
|
128
|
+
export interface ScrapeResult {
|
|
94
129
|
url: string;
|
|
95
130
|
status: "safe" | "blocked";
|
|
96
131
|
content: string;
|
|
97
|
-
threats_detected
|
|
132
|
+
/** Normalized from the wire field `threats_detected`. */
|
|
133
|
+
threatsDetected: string[];
|
|
98
134
|
message?: string;
|
|
99
135
|
}
|
|
100
|
-
interface ToolValidationResult {
|
|
136
|
+
export interface ToolValidationResult {
|
|
101
137
|
allowed: boolean;
|
|
102
|
-
risk_score
|
|
103
|
-
|
|
138
|
+
/** Normalized from the wire field `risk_score`. */
|
|
139
|
+
riskScore: number;
|
|
140
|
+
/** Normalized from the wire field `risk_level`. */
|
|
141
|
+
riskLevel: string;
|
|
104
142
|
reason: string;
|
|
105
143
|
warnings: string[];
|
|
106
|
-
blocked_reasons
|
|
144
|
+
/** Normalized from the wire field `blocked_reasons`. */
|
|
145
|
+
blockedReasons: string[];
|
|
107
146
|
}
|
|
108
|
-
interface RedTeamTestResult {
|
|
109
|
-
test_name
|
|
147
|
+
export interface RedTeamTestResult {
|
|
148
|
+
/** Normalized from the wire field `test_name`. */
|
|
149
|
+
testName: string;
|
|
110
150
|
prompt: string;
|
|
111
151
|
decision: string;
|
|
112
152
|
reason: string;
|
|
113
|
-
threat_type
|
|
153
|
+
/** Normalized from the wire field `threat_type`. */
|
|
154
|
+
threatType?: string;
|
|
114
155
|
confidence: number;
|
|
115
156
|
blocked: boolean;
|
|
116
157
|
details: Record<string, unknown>;
|
|
117
158
|
}
|
|
118
|
-
interface RedTeamSummary {
|
|
119
|
-
total_tests
|
|
159
|
+
export interface RedTeamSummary {
|
|
160
|
+
/** Normalized from the wire field `total_tests`. */
|
|
161
|
+
totalTests: number;
|
|
120
162
|
blocked: number;
|
|
121
163
|
allowed: number;
|
|
122
|
-
block_rate
|
|
164
|
+
/** Normalized from the wire field `block_rate`. */
|
|
165
|
+
blockRate: number;
|
|
123
166
|
results: RedTeamTestResult[];
|
|
124
167
|
}
|
|
125
|
-
interface AutonomousRedTeamRequest {
|
|
168
|
+
export interface AutonomousRedTeamRequest {
|
|
126
169
|
budget?: number;
|
|
127
170
|
/** Target preset to attack (camelCase, preferred). */
|
|
128
171
|
targetPreset?: string;
|
|
@@ -133,19 +176,26 @@ interface AutonomousRedTeamRequest {
|
|
|
133
176
|
/** @deprecated snake_case alias for `enabledDetectors`; kept for back-compat. */
|
|
134
177
|
enabled_detectors?: string[];
|
|
135
178
|
}
|
|
136
|
-
interface AutonomousRedTeamReport {
|
|
179
|
+
export interface AutonomousRedTeamReport {
|
|
137
180
|
grade: string;
|
|
138
|
-
bypass_rate
|
|
139
|
-
|
|
140
|
-
|
|
181
|
+
/** Normalized from the wire field `bypass_rate`. */
|
|
182
|
+
bypassRate: number;
|
|
183
|
+
/** Normalized from the wire field `total_attempts`. */
|
|
184
|
+
totalAttempts: number;
|
|
185
|
+
/** Normalized from the wire field `bypasses_found`. */
|
|
186
|
+
bypassesFound: number;
|
|
141
187
|
bypasses: Array<Record<string, unknown>>;
|
|
142
188
|
recommendations: string[];
|
|
143
189
|
}
|
|
144
|
-
interface IntelligenceStats {
|
|
145
|
-
total_patterns
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
190
|
+
export interface IntelligenceStats {
|
|
191
|
+
/** Normalized from the wire field `total_patterns`. */
|
|
192
|
+
totalPatterns: number;
|
|
193
|
+
/** Normalized from the wire field `by_category`. */
|
|
194
|
+
byCategory: Record<string, number>;
|
|
195
|
+
/** Normalized from the wire field `by_severity`. */
|
|
196
|
+
bySeverity: Record<string, number>;
|
|
197
|
+
/** Normalized from the wire field `recent_discoveries`. */
|
|
198
|
+
recentDiscoveries: number;
|
|
149
199
|
}
|
|
150
200
|
/**
|
|
151
201
|
* Ensure the proxy base URL's path ends with `/proxy`.
|
|
@@ -159,6 +209,16 @@ interface IntelligenceStats {
|
|
|
159
209
|
* correctly and the scheme/host/port/query/fragment are preserved exactly.
|
|
160
210
|
*/
|
|
161
211
|
export declare function ensureProxySuffix(baseUrl: string): string;
|
|
212
|
+
/**
|
|
213
|
+
* Join an endpoint path onto the configured base URL.
|
|
214
|
+
*
|
|
215
|
+
* Plain string concatenation broke base URLs carrying a query string or
|
|
216
|
+
* fragment (which `ensureProxySuffix` deliberately preserves): the endpoint
|
|
217
|
+
* path landed inside the query/fragment value and every namespaced call
|
|
218
|
+
* routed to the wrong endpoint. Splice the path onto the URL's pathname so
|
|
219
|
+
* the query/fragment stay where they belong.
|
|
220
|
+
*/
|
|
221
|
+
export declare function buildRequestUrl(baseUrl: string, path: string): string;
|
|
162
222
|
declare class ChatCompletions {
|
|
163
223
|
private client;
|
|
164
224
|
constructor(client: PromptGuard);
|
|
@@ -193,7 +253,7 @@ declare class Scrape {
|
|
|
193
253
|
timeout?: number;
|
|
194
254
|
}): Promise<ScrapeResult>;
|
|
195
255
|
batch(urls: string[], options?: Record<string, unknown>): Promise<{
|
|
196
|
-
|
|
256
|
+
jobId: string;
|
|
197
257
|
}>;
|
|
198
258
|
}
|
|
199
259
|
declare class Agent {
|
|
@@ -229,6 +289,12 @@ export declare class PromptGuard {
|
|
|
229
289
|
request<T>(method: string, path: string, body?: unknown): Promise<T>;
|
|
230
290
|
}
|
|
231
291
|
export declare class PromptGuardError extends Error {
|
|
292
|
+
/**
|
|
293
|
+
* Machine-readable error code. Server-forwarded codes pass through verbatim
|
|
294
|
+
* (their own casing). Codes minted by the SDK itself use lower_snake_case:
|
|
295
|
+
* `missing_api_key`, `streaming_not_supported`, `invalid_response_body`,
|
|
296
|
+
* `max_retries`, and the fallback `unknown`.
|
|
297
|
+
*/
|
|
232
298
|
code: string;
|
|
233
299
|
statusCode: number;
|
|
234
300
|
errorType?: string;
|
|
@@ -244,5 +310,5 @@ export declare class PromptGuardError extends Error {
|
|
|
244
310
|
requestsLimit?: number;
|
|
245
311
|
});
|
|
246
312
|
}
|
|
247
|
-
export
|
|
313
|
+
export {};
|
|
248
314
|
//# sourceMappingURL=client.d.ts.map
|