promptguard-sdk 1.2.0 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +226 -78
- package/dist/auto.d.ts +39 -0
- package/dist/auto.d.ts.map +1 -0
- package/dist/auto.js +105 -0
- package/dist/auto.js.map +1 -0
- package/dist/client.d.ts +219 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +198 -0
- package/dist/client.js.map +1 -0
- package/dist/guard.d.ts +80 -0
- package/dist/guard.d.ts.map +1 -0
- package/dist/guard.js +106 -0
- package/dist/guard.js.map +1 -0
- package/dist/index.d.ts +23 -146
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +42 -150
- package/dist/index.js.map +1 -1
- package/dist/integrations/langchain.d.ts +51 -0
- package/dist/integrations/langchain.d.ts.map +1 -0
- package/dist/integrations/langchain.js +193 -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 +153 -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 +146 -0
- package/dist/patches/anthropic.js.map +1 -0
- package/dist/patches/base.d.ts +20 -0
- package/dist/patches/base.d.ts.map +1 -0
- package/dist/patches/base.js +63 -0
- package/dist/patches/base.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 +205 -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 +143 -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 +127 -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 +122 -0
- package/dist/patches/openai.js.map +1 -0
- package/dist/resolve.d.ts +9 -0
- package/dist/resolve.d.ts.map +1 -0
- package/dist/resolve.js +19 -0
- package/dist/resolve.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +5 -0
- package/dist/version.js.map +1 -0
- package/package.json +84 -12
package/dist/index.d.ts
CHANGED
|
@@ -2,156 +2,33 @@
|
|
|
2
2
|
* PromptGuard Node.js SDK
|
|
3
3
|
*
|
|
4
4
|
* Drop-in security for AI applications.
|
|
5
|
-
* Just change your base URL and add an API key.
|
|
6
5
|
*
|
|
6
|
+
* **Option 1 - Auto-instrumentation (recommended)**
|
|
7
7
|
* @example
|
|
8
|
-
*
|
|
8
|
+
* ```ts
|
|
9
|
+
* import { init } from 'promptguard-sdk';
|
|
10
|
+
* init({ apiKey: 'pg_xxx' });
|
|
11
|
+
* // All LLM calls are now secured automatically.
|
|
12
|
+
* ```
|
|
9
13
|
*
|
|
14
|
+
* **Option 2 - Proxy mode**
|
|
15
|
+
* @example
|
|
16
|
+
* ```ts
|
|
17
|
+
* import { PromptGuard } from 'promptguard-sdk';
|
|
10
18
|
* const pg = new PromptGuard({ apiKey: 'pg_xxx' });
|
|
19
|
+
* const response = await pg.chat.completions.create({ ... });
|
|
20
|
+
* ```
|
|
11
21
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* }
|
|
22
|
+
* **Option 3 - Framework integrations**
|
|
23
|
+
* @example
|
|
24
|
+
* ```ts
|
|
25
|
+
* import { PromptGuardCallbackHandler } from 'promptguard-sdk/integrations/langchain';
|
|
26
|
+
* import { promptGuardMiddleware } from 'promptguard-sdk/integrations/vercel-ai';
|
|
27
|
+
* ```
|
|
16
28
|
*/
|
|
17
|
-
export
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
enableSecurityScan?: boolean;
|
|
23
|
-
}
|
|
24
|
-
export interface Message {
|
|
25
|
-
role: "system" | "user" | "assistant";
|
|
26
|
-
content: string;
|
|
27
|
-
}
|
|
28
|
-
export interface ChatCompletionRequest {
|
|
29
|
-
model: string;
|
|
30
|
-
messages: Message[];
|
|
31
|
-
temperature?: number;
|
|
32
|
-
maxTokens?: number;
|
|
33
|
-
stream?: boolean;
|
|
34
|
-
[key: string]: unknown;
|
|
35
|
-
}
|
|
36
|
-
export interface ChatCompletionResponse {
|
|
37
|
-
id: string;
|
|
38
|
-
object: string;
|
|
39
|
-
created: number;
|
|
40
|
-
model: string;
|
|
41
|
-
choices: Array<{
|
|
42
|
-
index: number;
|
|
43
|
-
message: Message;
|
|
44
|
-
finish_reason: string;
|
|
45
|
-
}>;
|
|
46
|
-
usage?: {
|
|
47
|
-
prompt_tokens: number;
|
|
48
|
-
completion_tokens: number;
|
|
49
|
-
total_tokens: number;
|
|
50
|
-
};
|
|
51
|
-
}
|
|
52
|
-
export interface SecurityScanResult {
|
|
53
|
-
blocked: boolean;
|
|
54
|
-
decision: "allow" | "block" | "redact";
|
|
55
|
-
reason?: string;
|
|
56
|
-
threatType?: string;
|
|
57
|
-
confidence?: number;
|
|
58
|
-
}
|
|
59
|
-
export interface RedactResult {
|
|
60
|
-
original: string;
|
|
61
|
-
redacted: string;
|
|
62
|
-
piiFound: string[];
|
|
63
|
-
}
|
|
64
|
-
declare class ChatCompletions {
|
|
65
|
-
private client;
|
|
66
|
-
constructor(client: PromptGuard);
|
|
67
|
-
create(params: ChatCompletionRequest): Promise<ChatCompletionResponse>;
|
|
68
|
-
}
|
|
69
|
-
declare class Chat {
|
|
70
|
-
completions: ChatCompletions;
|
|
71
|
-
constructor(client: PromptGuard);
|
|
72
|
-
}
|
|
73
|
-
declare class Security {
|
|
74
|
-
private client;
|
|
75
|
-
constructor(client: PromptGuard);
|
|
76
|
-
scan(content: string, type?: "prompt" | "response"): Promise<SecurityScanResult>;
|
|
77
|
-
redact(content: string, piiTypes?: string[]): Promise<RedactResult>;
|
|
78
|
-
}
|
|
79
|
-
export interface ScrapeResult {
|
|
80
|
-
url: string;
|
|
81
|
-
status: "safe" | "blocked";
|
|
82
|
-
content: string;
|
|
83
|
-
threats_detected: string[];
|
|
84
|
-
message?: string;
|
|
85
|
-
}
|
|
86
|
-
declare class Scrape {
|
|
87
|
-
private client;
|
|
88
|
-
constructor(client: PromptGuard);
|
|
89
|
-
url(url: string, options?: {
|
|
90
|
-
renderJs?: boolean;
|
|
91
|
-
extractText?: boolean;
|
|
92
|
-
timeout?: number;
|
|
93
|
-
}): Promise<ScrapeResult>;
|
|
94
|
-
batch(urls: string[], options?: Record<string, unknown>): Promise<{
|
|
95
|
-
job_id: string;
|
|
96
|
-
}>;
|
|
97
|
-
}
|
|
98
|
-
export interface ToolValidationResult {
|
|
99
|
-
allowed: boolean;
|
|
100
|
-
risk_score: number;
|
|
101
|
-
risk_level: string;
|
|
102
|
-
reason: string;
|
|
103
|
-
warnings: string[];
|
|
104
|
-
blocked_reasons: string[];
|
|
105
|
-
}
|
|
106
|
-
declare class Agent {
|
|
107
|
-
private client;
|
|
108
|
-
constructor(client: PromptGuard);
|
|
109
|
-
validateTool(agentId: string, toolName: string, args: Record<string, unknown>, sessionId?: string): Promise<ToolValidationResult>;
|
|
110
|
-
stats(agentId: string): Promise<Record<string, unknown>>;
|
|
111
|
-
}
|
|
112
|
-
export interface RedTeamTestResult {
|
|
113
|
-
test_name: string;
|
|
114
|
-
prompt: string;
|
|
115
|
-
decision: string;
|
|
116
|
-
reason: string;
|
|
117
|
-
threat_type?: string;
|
|
118
|
-
confidence: number;
|
|
119
|
-
blocked: boolean;
|
|
120
|
-
details: Record<string, unknown>;
|
|
121
|
-
}
|
|
122
|
-
export interface RedTeamSummary {
|
|
123
|
-
total_tests: number;
|
|
124
|
-
blocked: number;
|
|
125
|
-
allowed: number;
|
|
126
|
-
block_rate: number;
|
|
127
|
-
results: RedTeamTestResult[];
|
|
128
|
-
}
|
|
129
|
-
declare class RedTeam {
|
|
130
|
-
private client;
|
|
131
|
-
private base;
|
|
132
|
-
constructor(client: PromptGuard);
|
|
133
|
-
listTests(): Promise<{
|
|
134
|
-
total: number;
|
|
135
|
-
tests: Array<Record<string, unknown>>;
|
|
136
|
-
}>;
|
|
137
|
-
runTest(testName: string, targetPreset?: string): Promise<RedTeamTestResult>;
|
|
138
|
-
runAll(targetPreset?: string): Promise<RedTeamSummary>;
|
|
139
|
-
runCustom(prompt: string, targetPreset?: string): Promise<RedTeamTestResult>;
|
|
140
|
-
}
|
|
141
|
-
export declare class PromptGuard {
|
|
142
|
-
private config;
|
|
143
|
-
chat: Chat;
|
|
144
|
-
security: Security;
|
|
145
|
-
scrape: Scrape;
|
|
146
|
-
agent: Agent;
|
|
147
|
-
redteam: RedTeam;
|
|
148
|
-
constructor(config: PromptGuardConfig);
|
|
149
|
-
request<T>(method: string, path: string, body?: unknown): Promise<T>;
|
|
150
|
-
}
|
|
151
|
-
export declare class PromptGuardError extends Error {
|
|
152
|
-
code: string;
|
|
153
|
-
statusCode: number;
|
|
154
|
-
constructor(message: string, code: string, statusCode: number);
|
|
155
|
-
}
|
|
156
|
-
export default PromptGuard;
|
|
29
|
+
export { type InitOptions, init, shutdown } from "./auto";
|
|
30
|
+
export { default, PromptGuard, PromptGuardError } from "./client";
|
|
31
|
+
export { GuardApiError, GuardClient, type GuardClientConfig, type GuardContext, GuardDecision, type GuardMessage, type GuardRequestBody, type GuardResponseBody, PromptGuardBlockedError, type ThreatDetail, } from "./guard";
|
|
32
|
+
export { PromptGuardCallbackHandler } from "./integrations/langchain";
|
|
33
|
+
export { promptGuardMiddleware } from "./integrations/vercel-ai";
|
|
157
34
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAGH,OAAO,EAAE,KAAK,WAAW,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAA;AAEzD,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAA;AAEjE,OAAO,EACL,aAAa,EACb,WAAW,EACX,KAAK,iBAAiB,EACtB,KAAK,YAAY,EACjB,aAAa,EACb,KAAK,YAAY,EACjB,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EACtB,uBAAuB,EACvB,KAAK,YAAY,GAClB,MAAM,SAAS,CAAA;AAGhB,OAAO,EAAE,0BAA0B,EAAE,MAAM,0BAA0B,CAAA;AACrE,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -3,161 +3,53 @@
|
|
|
3
3
|
* PromptGuard Node.js SDK
|
|
4
4
|
*
|
|
5
5
|
* Drop-in security for AI applications.
|
|
6
|
-
* Just change your base URL and add an API key.
|
|
7
6
|
*
|
|
7
|
+
* **Option 1 - Auto-instrumentation (recommended)**
|
|
8
8
|
* @example
|
|
9
|
-
*
|
|
9
|
+
* ```ts
|
|
10
|
+
* import { init } from 'promptguard-sdk';
|
|
11
|
+
* init({ apiKey: 'pg_xxx' });
|
|
12
|
+
* // All LLM calls are now secured automatically.
|
|
13
|
+
* ```
|
|
10
14
|
*
|
|
15
|
+
* **Option 2 - Proxy mode**
|
|
16
|
+
* @example
|
|
17
|
+
* ```ts
|
|
18
|
+
* import { PromptGuard } from 'promptguard-sdk';
|
|
11
19
|
* const pg = new PromptGuard({ apiKey: 'pg_xxx' });
|
|
20
|
+
* const response = await pg.chat.completions.create({ ... });
|
|
21
|
+
* ```
|
|
12
22
|
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* }
|
|
23
|
+
* **Option 3 - Framework integrations**
|
|
24
|
+
* @example
|
|
25
|
+
* ```ts
|
|
26
|
+
* import { PromptGuardCallbackHandler } from 'promptguard-sdk/integrations/langchain';
|
|
27
|
+
* import { promptGuardMiddleware } from 'promptguard-sdk/integrations/vercel-ai';
|
|
28
|
+
* ```
|
|
17
29
|
*/
|
|
30
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
31
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
32
|
+
};
|
|
18
33
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
-
exports.PromptGuardError = exports.PromptGuard = void 0;
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
content,
|
|
41
|
-
type,
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
|
-
async redact(content, piiTypes) {
|
|
45
|
-
return this.client.request("POST", "/security/redact", {
|
|
46
|
-
content,
|
|
47
|
-
pii_types: piiTypes,
|
|
48
|
-
});
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
class Scrape {
|
|
52
|
-
constructor(client) {
|
|
53
|
-
this.client = client;
|
|
54
|
-
}
|
|
55
|
-
async url(url, options) {
|
|
56
|
-
return this.client.request("POST", "/scrape", {
|
|
57
|
-
url,
|
|
58
|
-
render_js: options?.renderJs ?? false,
|
|
59
|
-
extract_text: options?.extractText ?? true,
|
|
60
|
-
timeout: options?.timeout ?? 30,
|
|
61
|
-
});
|
|
62
|
-
}
|
|
63
|
-
async batch(urls, options) {
|
|
64
|
-
return this.client.request("POST", "/scrape/batch", {
|
|
65
|
-
urls,
|
|
66
|
-
...options,
|
|
67
|
-
});
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
class Agent {
|
|
71
|
-
constructor(client) {
|
|
72
|
-
this.client = client;
|
|
73
|
-
}
|
|
74
|
-
async validateTool(agentId, toolName, args, sessionId) {
|
|
75
|
-
return this.client.request("POST", "/agent/validate-tool", {
|
|
76
|
-
agent_id: agentId,
|
|
77
|
-
tool_name: toolName,
|
|
78
|
-
arguments: args,
|
|
79
|
-
session_id: sessionId,
|
|
80
|
-
});
|
|
81
|
-
}
|
|
82
|
-
async stats(agentId) {
|
|
83
|
-
return this.client.request("GET", `/agent/${agentId}/stats`);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
class RedTeam {
|
|
87
|
-
constructor(client) {
|
|
88
|
-
this.base = "/internal/redteam";
|
|
89
|
-
this.client = client;
|
|
90
|
-
}
|
|
91
|
-
async listTests() {
|
|
92
|
-
return this.client.request("GET", `${this.base}/tests`);
|
|
93
|
-
}
|
|
94
|
-
async runTest(testName, targetPreset = "default") {
|
|
95
|
-
return this.client.request("POST", `${this.base}/test/${testName}`, {
|
|
96
|
-
target_preset: targetPreset,
|
|
97
|
-
});
|
|
98
|
-
}
|
|
99
|
-
async runAll(targetPreset = "default") {
|
|
100
|
-
return this.client.request("POST", `${this.base}/test-all`, {
|
|
101
|
-
target_preset: targetPreset,
|
|
102
|
-
});
|
|
103
|
-
}
|
|
104
|
-
async runCustom(prompt, targetPreset = "default") {
|
|
105
|
-
return this.client.request("POST", `${this.base}/test-custom`, {
|
|
106
|
-
custom_prompt: prompt,
|
|
107
|
-
target_preset: targetPreset,
|
|
108
|
-
});
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
class PromptGuard {
|
|
112
|
-
constructor(config) {
|
|
113
|
-
const apiKey = config.apiKey || process.env.PROMPTGUARD_API_KEY;
|
|
114
|
-
if (!apiKey) {
|
|
115
|
-
throw new Error("API key required. Pass apiKey in config or set PROMPTGUARD_API_KEY environment variable.");
|
|
116
|
-
}
|
|
117
|
-
this.config = {
|
|
118
|
-
apiKey,
|
|
119
|
-
baseUrl: config.baseUrl || process.env.PROMPTGUARD_BASE_URL || "https://api.promptguard.co/api/v1",
|
|
120
|
-
timeout: config.timeout || 30000,
|
|
121
|
-
enableCaching: config.enableCaching ?? true,
|
|
122
|
-
enableSecurityScan: config.enableSecurityScan ?? true,
|
|
123
|
-
};
|
|
124
|
-
// OpenAI-compatible
|
|
125
|
-
this.chat = new Chat(this);
|
|
126
|
-
// PromptGuard-specific
|
|
127
|
-
this.security = new Security(this);
|
|
128
|
-
this.scrape = new Scrape(this);
|
|
129
|
-
this.agent = new Agent(this);
|
|
130
|
-
this.redteam = new RedTeam(this);
|
|
131
|
-
}
|
|
132
|
-
async request(method, path, body) {
|
|
133
|
-
const url = `${this.config.baseUrl}${path}`;
|
|
134
|
-
const response = await fetch(url, {
|
|
135
|
-
method,
|
|
136
|
-
headers: {
|
|
137
|
-
Authorization: `Bearer ${this.config.apiKey}`,
|
|
138
|
-
"Content-Type": "application/json",
|
|
139
|
-
"X-PromptGuard-SDK": "node",
|
|
140
|
-
"X-PromptGuard-Version": "1.2.0",
|
|
141
|
-
},
|
|
142
|
-
body: body ? JSON.stringify(body) : undefined,
|
|
143
|
-
signal: AbortSignal.timeout(this.config.timeout),
|
|
144
|
-
});
|
|
145
|
-
if (!response.ok) {
|
|
146
|
-
const errorBody = (await response.json().catch(() => ({})));
|
|
147
|
-
throw new PromptGuardError(errorBody.error?.message || "Request failed", errorBody.error?.code || "UNKNOWN", response.status);
|
|
148
|
-
}
|
|
149
|
-
return response.json();
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
exports.PromptGuard = PromptGuard;
|
|
153
|
-
class PromptGuardError extends Error {
|
|
154
|
-
constructor(message, code, statusCode) {
|
|
155
|
-
super(`${code}: ${message}`);
|
|
156
|
-
this.name = "PromptGuardError";
|
|
157
|
-
this.code = code;
|
|
158
|
-
this.statusCode = statusCode;
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
exports.PromptGuardError = PromptGuardError;
|
|
162
|
-
exports.default = PromptGuard;
|
|
34
|
+
exports.promptGuardMiddleware = exports.PromptGuardCallbackHandler = exports.PromptGuardBlockedError = exports.GuardDecision = exports.GuardClient = exports.GuardApiError = exports.PromptGuardError = exports.PromptGuard = exports.default = exports.shutdown = exports.init = void 0;
|
|
35
|
+
// Auto-instrumentation
|
|
36
|
+
var auto_1 = require("./auto");
|
|
37
|
+
Object.defineProperty(exports, "init", { enumerable: true, get: function () { return auto_1.init; } });
|
|
38
|
+
Object.defineProperty(exports, "shutdown", { enumerable: true, get: function () { return auto_1.shutdown; } });
|
|
39
|
+
// Proxy client
|
|
40
|
+
var client_1 = require("./client");
|
|
41
|
+
Object.defineProperty(exports, "default", { enumerable: true, get: function () { return __importDefault(client_1).default; } });
|
|
42
|
+
Object.defineProperty(exports, "PromptGuard", { enumerable: true, get: function () { return client_1.PromptGuard; } });
|
|
43
|
+
Object.defineProperty(exports, "PromptGuardError", { enumerable: true, get: function () { return client_1.PromptGuardError; } });
|
|
44
|
+
// Guard client (standalone scanning)
|
|
45
|
+
var guard_1 = require("./guard");
|
|
46
|
+
Object.defineProperty(exports, "GuardApiError", { enumerable: true, get: function () { return guard_1.GuardApiError; } });
|
|
47
|
+
Object.defineProperty(exports, "GuardClient", { enumerable: true, get: function () { return guard_1.GuardClient; } });
|
|
48
|
+
Object.defineProperty(exports, "GuardDecision", { enumerable: true, get: function () { return guard_1.GuardDecision; } });
|
|
49
|
+
Object.defineProperty(exports, "PromptGuardBlockedError", { enumerable: true, get: function () { return guard_1.PromptGuardBlockedError; } });
|
|
50
|
+
// Framework integrations (re-exported for convenience)
|
|
51
|
+
var langchain_1 = require("./integrations/langchain");
|
|
52
|
+
Object.defineProperty(exports, "PromptGuardCallbackHandler", { enumerable: true, get: function () { return langchain_1.PromptGuardCallbackHandler; } });
|
|
53
|
+
var vercel_ai_1 = require("./integrations/vercel-ai");
|
|
54
|
+
Object.defineProperty(exports, "promptGuardMiddleware", { enumerable: true, get: function () { return vercel_ai_1.promptGuardMiddleware; } });
|
|
163
55
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;;;;;;AAEH,uBAAuB;AACvB,+BAAyD;AAA9B,4FAAA,IAAI,OAAA;AAAE,gGAAA,QAAQ,OAAA;AACzC,eAAe;AACf,mCAAiE;AAAxD,kHAAA,OAAO,OAAA;AAAE,qGAAA,WAAW,OAAA;AAAE,0GAAA,gBAAgB,OAAA;AAC/C,qCAAqC;AACrC,iCAWgB;AAVd,sGAAA,aAAa,OAAA;AACb,oGAAA,WAAW,OAAA;AAGX,sGAAA,aAAa,OAAA;AAIb,gHAAA,uBAAuB,OAAA;AAIzB,uDAAuD;AACvD,sDAAqE;AAA5D,uHAAA,0BAA0B,OAAA;AACnC,sDAAgE;AAAvD,kHAAA,qBAAqB,OAAA"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LangChain.js integration - PromptGuardCallbackHandler.
|
|
3
|
+
*
|
|
4
|
+
* Implements the LangChain BaseCallbackHandler interface to scan prompts
|
|
5
|
+
* before LLM calls and responses after, with rich context about chains,
|
|
6
|
+
* tools, and agent steps.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```ts
|
|
10
|
+
* import { PromptGuardCallbackHandler } from 'promptguard-sdk/integrations/langchain';
|
|
11
|
+
*
|
|
12
|
+
* const handler = new PromptGuardCallbackHandler({ apiKey: 'pg_xxx' });
|
|
13
|
+
*
|
|
14
|
+
* const llm = new ChatOpenAI({ callbacks: [handler] });
|
|
15
|
+
* // or
|
|
16
|
+
* await chain.invoke({ input: '...' }, { callbacks: [handler] });
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
import { type GuardClientConfig } from "../guard";
|
|
20
|
+
export interface PromptGuardCallbackOptions extends GuardClientConfig {
|
|
21
|
+
mode?: "enforce" | "monitor";
|
|
22
|
+
scanResponses?: boolean;
|
|
23
|
+
failOpen?: boolean;
|
|
24
|
+
}
|
|
25
|
+
export declare class PromptGuardCallbackHandler {
|
|
26
|
+
readonly name = "promptguard";
|
|
27
|
+
private readonly guard;
|
|
28
|
+
private readonly mode;
|
|
29
|
+
private readonly scanResponses;
|
|
30
|
+
private readonly failOpen;
|
|
31
|
+
/** Chain context per run ID for richer threat detection. */
|
|
32
|
+
private chainContext;
|
|
33
|
+
constructor(options: PromptGuardCallbackOptions);
|
|
34
|
+
handleLLMStart(serialized: Record<string, unknown>, prompts: string[], runId: string, parentRunId?: string, _extraParams?: Record<string, unknown>, tags?: string[], metadata?: Record<string, unknown>): Promise<void>;
|
|
35
|
+
handleChatModelStart(serialized: Record<string, unknown>, messages: unknown[][], runId: string, parentRunId?: string, _extraParams?: Record<string, unknown>, tags?: string[], metadata?: Record<string, unknown>): Promise<void>;
|
|
36
|
+
handleLLMEnd(output: unknown, runId: string): Promise<void>;
|
|
37
|
+
handleLLMError(_error: Error, runId: string): void;
|
|
38
|
+
handleChainStart(serialized: Record<string, unknown>, _inputs: Record<string, unknown>, runId: string, parentRunId?: string, tags?: string[]): Promise<void>;
|
|
39
|
+
handleChainEnd(_outputs: Record<string, unknown>, runId: string): void;
|
|
40
|
+
handleChainError(_error: Error, runId: string): void;
|
|
41
|
+
handleToolStart(serialized: Record<string, unknown>, input: string, runId: string, parentRunId?: string, tags?: string[], metadata?: Record<string, unknown>): Promise<void>;
|
|
42
|
+
handleToolEnd(output: unknown, runId: string): Promise<void>;
|
|
43
|
+
handleToolError(_error: Error, runId: string): void;
|
|
44
|
+
private safeScan;
|
|
45
|
+
private handleDecision;
|
|
46
|
+
private buildContext;
|
|
47
|
+
private extractModel;
|
|
48
|
+
private mapRole;
|
|
49
|
+
private extractLLMResponse;
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=langchain.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"langchain.d.ts","sourceRoot":"","sources":["../../src/integrations/langchain.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAEL,KAAK,iBAAiB,EAKvB,MAAM,UAAU,CAAA;AAOjB,MAAM,WAAW,0BAA2B,SAAQ,iBAAiB;IACnE,IAAI,CAAC,EAAE,SAAS,GAAG,SAAS,CAAA;IAC5B,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB;AAMD,qBAAa,0BAA0B;IACrC,QAAQ,CAAC,IAAI,iBAAgB;IAE7B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAa;IACnC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAuB;IAC5C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAElC,4DAA4D;IAC5D,OAAO,CAAC,YAAY,CAA6C;gBAErD,OAAO,EAAE,0BAA0B;IAWzC,cAAc,CAClB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACnC,OAAO,EAAE,MAAM,EAAE,EACjB,KAAK,EAAE,MAAM,EACb,WAAW,CAAC,EAAE,MAAM,EACpB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACtC,IAAI,CAAC,EAAE,MAAM,EAAE,EACf,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACjC,OAAO,CAAC,IAAI,CAAC;IAYV,oBAAoB,CACxB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACnC,QAAQ,EAAE,OAAO,EAAE,EAAE,EACrB,KAAK,EAAE,MAAM,EACb,WAAW,CAAC,EAAE,MAAM,EACpB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACtC,IAAI,CAAC,EAAE,MAAM,EAAE,EACf,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACjC,OAAO,CAAC,IAAI,CAAC;IAmBV,YAAY,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBjE,cAAc,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAM5C,gBAAgB,CACpB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACnC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,KAAK,EAAE,MAAM,EACb,WAAW,CAAC,EAAE,MAAM,EACpB,IAAI,CAAC,EAAE,MAAM,EAAE,GACd,OAAO,CAAC,IAAI,CAAC;IAShB,cAAc,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAItE,gBAAgB,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAM9C,eAAe,CACnB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACnC,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,EACb,WAAW,CAAC,EAAE,MAAM,EACpB,IAAI,CAAC,EAAE,MAAM,EAAE,EACf,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACjC,OAAO,CAAC,IAAI,CAAC;IAoBV,aAAa,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAelE,eAAe,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;YAMrC,QAAQ;IActB,OAAO,CAAC,cAAc;IAetB,OAAO,CAAC,YAAY;IAwBpB,OAAO,CAAC,YAAY;IAUpB,OAAO,CAAC,OAAO;IASf,OAAO,CAAC,kBAAkB;CAmB3B"}
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* LangChain.js integration - PromptGuardCallbackHandler.
|
|
4
|
+
*
|
|
5
|
+
* Implements the LangChain BaseCallbackHandler interface to scan prompts
|
|
6
|
+
* before LLM calls and responses after, with rich context about chains,
|
|
7
|
+
* tools, and agent steps.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* import { PromptGuardCallbackHandler } from 'promptguard-sdk/integrations/langchain';
|
|
12
|
+
*
|
|
13
|
+
* const handler = new PromptGuardCallbackHandler({ apiKey: 'pg_xxx' });
|
|
14
|
+
*
|
|
15
|
+
* const llm = new ChatOpenAI({ callbacks: [handler] });
|
|
16
|
+
* // or
|
|
17
|
+
* await chain.invoke({ input: '...' }, { callbacks: [handler] });
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
|
+
exports.PromptGuardCallbackHandler = void 0;
|
|
22
|
+
const guard_1 = require("../guard");
|
|
23
|
+
const resolve_1 = require("../resolve");
|
|
24
|
+
// ---------------------------------------------------------------------------
|
|
25
|
+
// Handler
|
|
26
|
+
// ---------------------------------------------------------------------------
|
|
27
|
+
class PromptGuardCallbackHandler {
|
|
28
|
+
constructor(options) {
|
|
29
|
+
this.name = "promptguard";
|
|
30
|
+
/** Chain context per run ID for richer threat detection. */
|
|
31
|
+
this.chainContext = new Map();
|
|
32
|
+
const { apiKey, baseUrl } = (0, resolve_1.resolveCredentials)(options.apiKey, options.baseUrl);
|
|
33
|
+
this.guard = new guard_1.GuardClient({ apiKey, baseUrl, timeout: options.timeout });
|
|
34
|
+
this.mode = options.mode ?? "enforce";
|
|
35
|
+
this.scanResponses = options.scanResponses ?? true;
|
|
36
|
+
this.failOpen = options.failOpen ?? true;
|
|
37
|
+
}
|
|
38
|
+
// -- LLM callbacks -------------------------------------------------------
|
|
39
|
+
async handleLLMStart(serialized, prompts, runId, parentRunId, _extraParams, tags, metadata) {
|
|
40
|
+
const messages = prompts.map((p) => ({
|
|
41
|
+
role: "user",
|
|
42
|
+
content: p,
|
|
43
|
+
}));
|
|
44
|
+
const model = this.extractModel(serialized);
|
|
45
|
+
const context = this.buildContext(runId, parentRunId, "llm", tags, metadata);
|
|
46
|
+
const decision = await this.safeScan(messages, "input", model, context);
|
|
47
|
+
this.handleDecision(decision, runId);
|
|
48
|
+
}
|
|
49
|
+
async handleChatModelStart(serialized, messages, runId, parentRunId, _extraParams, tags, metadata) {
|
|
50
|
+
const guardMessages = [];
|
|
51
|
+
for (const messageList of messages) {
|
|
52
|
+
for (const raw of messageList) {
|
|
53
|
+
const msg = raw;
|
|
54
|
+
const role = this.mapRole(String(msg?.type ?? msg?.role ?? "user"));
|
|
55
|
+
const content = String(msg?.content ?? msg?.text ?? "");
|
|
56
|
+
guardMessages.push({ role, content });
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
const model = this.extractModel(serialized);
|
|
60
|
+
const context = this.buildContext(runId, parentRunId, "chat_model", tags, metadata);
|
|
61
|
+
const decision = await this.safeScan(guardMessages, "input", model, context);
|
|
62
|
+
this.handleDecision(decision, runId);
|
|
63
|
+
}
|
|
64
|
+
async handleLLMEnd(output, runId) {
|
|
65
|
+
if (!this.scanResponses)
|
|
66
|
+
return;
|
|
67
|
+
const text = this.extractLLMResponse(output);
|
|
68
|
+
if (!text)
|
|
69
|
+
return;
|
|
70
|
+
const context = this.buildContext(runId, undefined, "llm_response");
|
|
71
|
+
const decision = await this.safeScan([{ role: "assistant", content: text }], "output", undefined, context);
|
|
72
|
+
this.handleDecision(decision, runId);
|
|
73
|
+
}
|
|
74
|
+
handleLLMError(_error, runId) {
|
|
75
|
+
this.chainContext.delete(runId);
|
|
76
|
+
}
|
|
77
|
+
// -- Chain callbacks -----------------------------------------------------
|
|
78
|
+
async handleChainStart(serialized, _inputs, runId, parentRunId, tags) {
|
|
79
|
+
const chainName = serialized?.id?.slice(-1)[0] ?? "unknown";
|
|
80
|
+
this.chainContext.set(runId, {
|
|
81
|
+
chain_name: chainName,
|
|
82
|
+
parent_run_id: parentRunId,
|
|
83
|
+
tags,
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
handleChainEnd(_outputs, runId) {
|
|
87
|
+
this.chainContext.delete(runId);
|
|
88
|
+
}
|
|
89
|
+
handleChainError(_error, runId) {
|
|
90
|
+
this.chainContext.delete(runId);
|
|
91
|
+
}
|
|
92
|
+
// -- Tool callbacks ------------------------------------------------------
|
|
93
|
+
async handleToolStart(serialized, input, runId, parentRunId, tags, metadata) {
|
|
94
|
+
const toolName = serialized?.name ??
|
|
95
|
+
serialized?.id?.slice(-1)[0] ??
|
|
96
|
+
"unknown";
|
|
97
|
+
const context = this.buildContext(runId, parentRunId, "tool", tags, {
|
|
98
|
+
...(metadata ?? {}),
|
|
99
|
+
tool_name: toolName,
|
|
100
|
+
});
|
|
101
|
+
const decision = await this.safeScan([{ role: "user", content: input }], "input", "tool", context);
|
|
102
|
+
this.handleDecision(decision, runId);
|
|
103
|
+
}
|
|
104
|
+
async handleToolEnd(output, runId) {
|
|
105
|
+
if (!this.scanResponses)
|
|
106
|
+
return;
|
|
107
|
+
const text = output ? String(output) : "";
|
|
108
|
+
if (!text)
|
|
109
|
+
return;
|
|
110
|
+
const context = this.buildContext(runId, undefined, "tool_response");
|
|
111
|
+
const decision = await this.safeScan([{ role: "assistant", content: text }], "output", undefined, context);
|
|
112
|
+
this.handleDecision(decision, runId);
|
|
113
|
+
}
|
|
114
|
+
handleToolError(_error, runId) {
|
|
115
|
+
this.chainContext.delete(runId);
|
|
116
|
+
}
|
|
117
|
+
// -- Internal helpers ----------------------------------------------------
|
|
118
|
+
async safeScan(messages, direction, model, context) {
|
|
119
|
+
try {
|
|
120
|
+
return await this.guard.scan(messages, direction, model, context);
|
|
121
|
+
}
|
|
122
|
+
catch {
|
|
123
|
+
if (!this.failOpen)
|
|
124
|
+
throw new Error("Guard API unavailable");
|
|
125
|
+
return null;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
handleDecision(decision, runId) {
|
|
129
|
+
if (!decision)
|
|
130
|
+
return;
|
|
131
|
+
if (decision.blocked) {
|
|
132
|
+
if (this.mode === "enforce")
|
|
133
|
+
throw new guard_1.PromptGuardBlockedError(decision);
|
|
134
|
+
console.warn(`[promptguard][monitor] would block: ${decision.threatType} (event=${decision.eventId}, run=${runId})`);
|
|
135
|
+
}
|
|
136
|
+
if (decision.redacted) {
|
|
137
|
+
console.info(`[promptguard] redacted content (event=${decision.eventId}, run=${runId})`);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
buildContext(runId, parentRunId, component = "unknown", tags, metadata) {
|
|
141
|
+
const chainInfo = this.chainContext.get(runId) ??
|
|
142
|
+
(parentRunId ? this.chainContext.get(parentRunId) : undefined) ??
|
|
143
|
+
{};
|
|
144
|
+
return {
|
|
145
|
+
framework: "langchain",
|
|
146
|
+
chain_name: chainInfo.chain_name,
|
|
147
|
+
session_id: runId,
|
|
148
|
+
metadata: {
|
|
149
|
+
component,
|
|
150
|
+
tags: tags ?? chainInfo.tags,
|
|
151
|
+
...(metadata ?? {}),
|
|
152
|
+
},
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
extractModel(serialized) {
|
|
156
|
+
const kwargs = serialized?.kwargs;
|
|
157
|
+
return (kwargs?.model_name ??
|
|
158
|
+
kwargs?.model ??
|
|
159
|
+
(serialized?.id ?? []).slice(-1)[0] ??
|
|
160
|
+
"unknown");
|
|
161
|
+
}
|
|
162
|
+
mapRole(type) {
|
|
163
|
+
const map = {
|
|
164
|
+
human: "user",
|
|
165
|
+
ai: "assistant",
|
|
166
|
+
system: "system",
|
|
167
|
+
};
|
|
168
|
+
return map[type] ?? type;
|
|
169
|
+
}
|
|
170
|
+
extractLLMResponse(output) {
|
|
171
|
+
try {
|
|
172
|
+
const typed = output;
|
|
173
|
+
if (typed?.generations) {
|
|
174
|
+
const texts = [];
|
|
175
|
+
for (const genList of typed.generations) {
|
|
176
|
+
for (const gen of genList) {
|
|
177
|
+
if (gen?.text)
|
|
178
|
+
texts.push(gen.text);
|
|
179
|
+
else if (gen?.message?.content)
|
|
180
|
+
texts.push(String(gen.message.content));
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
return texts.length ? texts.join("\n") : null;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
catch {
|
|
187
|
+
// ignore
|
|
188
|
+
}
|
|
189
|
+
return null;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
exports.PromptGuardCallbackHandler = PromptGuardCallbackHandler;
|
|
193
|
+
//# sourceMappingURL=langchain.js.map
|