guardrail-plug-sdk 1.0.2 → 1.0.3
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/dist/Guardrail.d.ts +9 -0
- package/dist/Guardrail.d.ts.map +1 -1
- package/dist/Guardrail.js +72 -1
- package/dist/Guardrail.js.map +1 -1
- package/package.json +1 -1
- package/src/Guardrail.ts +81 -1
package/dist/Guardrail.d.ts
CHANGED
|
@@ -18,4 +18,13 @@ export declare class Guardrail {
|
|
|
18
18
|
*/
|
|
19
19
|
chat(request: SDKChatRequest): Promise<SDKChatResponse>;
|
|
20
20
|
}
|
|
21
|
+
/**
|
|
22
|
+
* Wraps an OpenAI client instance so its chat completions are automatically
|
|
23
|
+
* audited and secured by the Guardrail Middleware Gateway.
|
|
24
|
+
*/
|
|
25
|
+
export declare function wrapOpenAI(openaiClient: any, options: GuardrailOptions): any;
|
|
26
|
+
/**
|
|
27
|
+
* Express Middleware to intercept, scan, and secure incoming chatbot routes.
|
|
28
|
+
*/
|
|
29
|
+
export declare function guardrailExpress(options: GuardrailOptions): (req: any, res: any, next: any) => Promise<any>;
|
|
21
30
|
//# sourceMappingURL=Guardrail.d.ts.map
|
package/dist/Guardrail.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Guardrail.d.ts","sourceRoot":"","sources":["../src/Guardrail.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAE7D,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,GAAG,MAAM,CAAC;IAC5D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,eAAe,CAAS;gBAEpB,OAAO,EAAE,gBAAgB;IAYrC;;OAEG;IACG,IAAI,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"Guardrail.d.ts","sourceRoot":"","sources":["../src/Guardrail.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAE7D,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,GAAG,MAAM,CAAC;IAC5D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,eAAe,CAAS;gBAEpB,OAAO,EAAE,gBAAgB;IAYrC;;OAEG;IACG,IAAI,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,CAAC;CA+B9D;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,YAAY,EAAE,GAAG,EAAE,OAAO,EAAE,gBAAgB,OAkCtE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,gBAAgB,IAG1C,KAAK,GAAG,EAAE,KAAK,GAAG,EAAE,MAAM,GAAG,kBA+B5C"}
|
package/dist/Guardrail.js
CHANGED
|
@@ -32,7 +32,8 @@ export class Guardrail {
|
|
|
32
32
|
provider: request.provider || this.provider,
|
|
33
33
|
model: request.model || this.model,
|
|
34
34
|
applicationName: request.applicationName || this.applicationName,
|
|
35
|
-
metadata: request.metadata || {}
|
|
35
|
+
metadata: request.metadata || {},
|
|
36
|
+
groundingSource: request.groundingSource || 'kb'
|
|
36
37
|
})
|
|
37
38
|
});
|
|
38
39
|
if (!response.ok) {
|
|
@@ -47,4 +48,74 @@ export class Guardrail {
|
|
|
47
48
|
}
|
|
48
49
|
}
|
|
49
50
|
}
|
|
51
|
+
/**
|
|
52
|
+
* Wraps an OpenAI client instance so its chat completions are automatically
|
|
53
|
+
* audited and secured by the Guardrail Middleware Gateway.
|
|
54
|
+
*/
|
|
55
|
+
export function wrapOpenAI(openaiClient, options) {
|
|
56
|
+
const guardrail = new Guardrail(options);
|
|
57
|
+
if (openaiClient?.chat?.completions) {
|
|
58
|
+
const originalCreate = openaiClient.chat.completions.create.bind(openaiClient.chat.completions);
|
|
59
|
+
openaiClient.chat.completions.create = async function (params, requestOptions) {
|
|
60
|
+
const res = await guardrail.chat({
|
|
61
|
+
messages: params.messages,
|
|
62
|
+
model: params.model || options.model,
|
|
63
|
+
provider: 'openai',
|
|
64
|
+
applicationName: options.applicationName,
|
|
65
|
+
metadata: { originalParams: params }
|
|
66
|
+
});
|
|
67
|
+
return {
|
|
68
|
+
id: res.auditId,
|
|
69
|
+
object: 'chat.completion',
|
|
70
|
+
created: Math.floor(Date.now() / 1000),
|
|
71
|
+
model: params.model,
|
|
72
|
+
choices: [{
|
|
73
|
+
index: 0,
|
|
74
|
+
message: { role: 'assistant', content: res.text },
|
|
75
|
+
finish_reason: res.decision === 'BLOCKED' ? 'content_filter' : 'stop'
|
|
76
|
+
}],
|
|
77
|
+
usage: {
|
|
78
|
+
prompt_tokens: res.metrics?.tokenUsage?.promptTokens || 0,
|
|
79
|
+
completion_tokens: res.metrics?.tokenUsage?.completionTokens || 0,
|
|
80
|
+
total_tokens: res.metrics?.tokenUsage?.totalTokens || 0
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
return openaiClient;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Express Middleware to intercept, scan, and secure incoming chatbot routes.
|
|
89
|
+
*/
|
|
90
|
+
export function guardrailExpress(options) {
|
|
91
|
+
const guardrail = new Guardrail(options);
|
|
92
|
+
return async (req, res, next) => {
|
|
93
|
+
try {
|
|
94
|
+
const messages = req.body.messages;
|
|
95
|
+
if (!messages || !Array.isArray(messages)) {
|
|
96
|
+
return next();
|
|
97
|
+
}
|
|
98
|
+
const auditRes = await guardrail.chat({
|
|
99
|
+
messages,
|
|
100
|
+
userId: req.body.userId || 'express_user',
|
|
101
|
+
sessionId: req.body.sessionId || 'express_session',
|
|
102
|
+
groundingSource: req.body.groundingSource || 'kb'
|
|
103
|
+
});
|
|
104
|
+
req.guardrail = auditRes;
|
|
105
|
+
if (auditRes.decision === 'BLOCKED') {
|
|
106
|
+
return res.status(400).json({
|
|
107
|
+
error: 'Blocked by Guardrail Security Policy',
|
|
108
|
+
explanation: auditRes.policyExplanation,
|
|
109
|
+
fallbackText: auditRes.text,
|
|
110
|
+
auditId: auditRes.auditId
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
next();
|
|
114
|
+
}
|
|
115
|
+
catch (err) {
|
|
116
|
+
console.error('[Guardrail Middleware] Audit scan failed:', err.message);
|
|
117
|
+
next();
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
}
|
|
50
121
|
//# sourceMappingURL=Guardrail.js.map
|
package/dist/Guardrail.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Guardrail.js","sourceRoot":"","sources":["../src/Guardrail.ts"],"names":[],"mappings":"AAUA,MAAM,OAAO,SAAS;IACZ,QAAQ,CAAS;IACjB,MAAM,CAAS;IACf,QAAQ,CAAS;IACjB,KAAK,CAAS;IACd,eAAe,CAAS;IAEhC,YAAY,OAAyB;QACnC,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,uBAAuB,CAAC;QAC5D,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;QAC7B,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,QAAQ,CAAC;QAC7C,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,aAAa,CAAC;QAC5C,IAAI,CAAC,eAAe,GAAG,OAAO,CAAC,eAAe,IAAI,iBAAiB,CAAC;QAEpE,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,qEAAqE,CAAC,CAAC;QACzF,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,IAAI,CAAC,OAAuB;QAChC,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,QAAQ,WAAW,EAAE;gBACxD,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE;oBACP,cAAc,EAAE,kBAAkB;oBAClC,eAAe,EAAE,UAAU,IAAI,CAAC,MAAM,EAAE;iBACzC;gBACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;oBACnB,QAAQ,EAAE,OAAO,CAAC,QAAQ;oBAC1B,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,UAAU;oBACpC,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,aAAa;oBAC7C,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,IAAI,CAAC,QAAQ;oBAC3C,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK;oBAClC,eAAe,EAAE,OAAO,CAAC,eAAe,IAAI,IAAI,CAAC,eAAe;oBAChE,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,EAAE;
|
|
1
|
+
{"version":3,"file":"Guardrail.js","sourceRoot":"","sources":["../src/Guardrail.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "guardrail-plug-sdk",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"description": "A plug-and-play AI Auditing & Hallucination Detection SDK. Intercepts LLM inputs/outputs, verifies factual grounding against your knowledge base, and blocks or flags unverified responses.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
package/src/Guardrail.ts
CHANGED
|
@@ -45,7 +45,8 @@ export class Guardrail {
|
|
|
45
45
|
provider: request.provider || this.provider,
|
|
46
46
|
model: request.model || this.model,
|
|
47
47
|
applicationName: request.applicationName || this.applicationName,
|
|
48
|
-
metadata: request.metadata || {}
|
|
48
|
+
metadata: request.metadata || {},
|
|
49
|
+
groundingSource: request.groundingSource || 'kb'
|
|
49
50
|
})
|
|
50
51
|
});
|
|
51
52
|
|
|
@@ -61,3 +62,82 @@ export class Guardrail {
|
|
|
61
62
|
}
|
|
62
63
|
}
|
|
63
64
|
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Wraps an OpenAI client instance so its chat completions are automatically
|
|
68
|
+
* audited and secured by the Guardrail Middleware Gateway.
|
|
69
|
+
*/
|
|
70
|
+
export function wrapOpenAI(openaiClient: any, options: GuardrailOptions) {
|
|
71
|
+
const guardrail = new Guardrail(options);
|
|
72
|
+
|
|
73
|
+
if (openaiClient?.chat?.completions) {
|
|
74
|
+
const originalCreate = openaiClient.chat.completions.create.bind(openaiClient.chat.completions);
|
|
75
|
+
|
|
76
|
+
openaiClient.chat.completions.create = async function(params: any, requestOptions?: any) {
|
|
77
|
+
const res = await guardrail.chat({
|
|
78
|
+
messages: params.messages,
|
|
79
|
+
model: params.model || options.model,
|
|
80
|
+
provider: 'openai',
|
|
81
|
+
applicationName: options.applicationName,
|
|
82
|
+
metadata: { originalParams: params }
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
return {
|
|
86
|
+
id: res.auditId,
|
|
87
|
+
object: 'chat.completion',
|
|
88
|
+
created: Math.floor(Date.now() / 1000),
|
|
89
|
+
model: params.model,
|
|
90
|
+
choices: [{
|
|
91
|
+
index: 0,
|
|
92
|
+
message: { role: 'assistant', content: res.text },
|
|
93
|
+
finish_reason: res.decision === 'BLOCKED' ? 'content_filter' : 'stop'
|
|
94
|
+
}],
|
|
95
|
+
usage: {
|
|
96
|
+
prompt_tokens: res.metrics?.tokenUsage?.promptTokens || 0,
|
|
97
|
+
completion_tokens: res.metrics?.tokenUsage?.completionTokens || 0,
|
|
98
|
+
total_tokens: res.metrics?.tokenUsage?.totalTokens || 0
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
return openaiClient;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Express Middleware to intercept, scan, and secure incoming chatbot routes.
|
|
108
|
+
*/
|
|
109
|
+
export function guardrailExpress(options: GuardrailOptions) {
|
|
110
|
+
const guardrail = new Guardrail(options);
|
|
111
|
+
|
|
112
|
+
return async (req: any, res: any, next: any) => {
|
|
113
|
+
try {
|
|
114
|
+
const messages = req.body.messages;
|
|
115
|
+
if (!messages || !Array.isArray(messages)) {
|
|
116
|
+
return next();
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const auditRes = await guardrail.chat({
|
|
120
|
+
messages,
|
|
121
|
+
userId: req.body.userId || 'express_user',
|
|
122
|
+
sessionId: req.body.sessionId || 'express_session',
|
|
123
|
+
groundingSource: req.body.groundingSource || 'kb'
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
req.guardrail = auditRes;
|
|
127
|
+
|
|
128
|
+
if (auditRes.decision === 'BLOCKED') {
|
|
129
|
+
return res.status(400).json({
|
|
130
|
+
error: 'Blocked by Guardrail Security Policy',
|
|
131
|
+
explanation: auditRes.policyExplanation,
|
|
132
|
+
fallbackText: auditRes.text,
|
|
133
|
+
auditId: auditRes.auditId
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
next();
|
|
138
|
+
} catch (err: any) {
|
|
139
|
+
console.error('[Guardrail Middleware] Audit scan failed:', err.message);
|
|
140
|
+
next();
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
}
|