botguard 0.1.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/dist/client.d.ts +40 -0
- package/dist/client.js +152 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +5 -0
- package/dist/types.d.ts +27 -0
- package/dist/types.js +2 -0
- package/package.json +24 -0
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import OpenAI from 'openai';
|
|
2
|
+
import { BotGuardConfig, ShieldResult } from './types';
|
|
3
|
+
export declare class BotGuard {
|
|
4
|
+
private client;
|
|
5
|
+
private config;
|
|
6
|
+
chat: ChatNamespace;
|
|
7
|
+
constructor(config: BotGuardConfig);
|
|
8
|
+
get openai(): OpenAI;
|
|
9
|
+
get baseURL(): string;
|
|
10
|
+
get apiKey(): string;
|
|
11
|
+
get timeout(): number;
|
|
12
|
+
}
|
|
13
|
+
declare class ChatNamespace {
|
|
14
|
+
completions: Completions;
|
|
15
|
+
constructor(guard: BotGuard);
|
|
16
|
+
}
|
|
17
|
+
declare class Completions {
|
|
18
|
+
private guard;
|
|
19
|
+
constructor(guard: BotGuard);
|
|
20
|
+
create(params: {
|
|
21
|
+
model: string;
|
|
22
|
+
messages: Array<{
|
|
23
|
+
role: string;
|
|
24
|
+
content: string;
|
|
25
|
+
}>;
|
|
26
|
+
stream?: false;
|
|
27
|
+
[key: string]: any;
|
|
28
|
+
}): Promise<ShieldResult<OpenAI.Chat.ChatCompletion>>;
|
|
29
|
+
create(params: {
|
|
30
|
+
model: string;
|
|
31
|
+
messages: Array<{
|
|
32
|
+
role: string;
|
|
33
|
+
content: string;
|
|
34
|
+
}>;
|
|
35
|
+
stream: true;
|
|
36
|
+
[key: string]: any;
|
|
37
|
+
}): Promise<AsyncIterable<ShieldResult>>;
|
|
38
|
+
private createStream;
|
|
39
|
+
}
|
|
40
|
+
export {};
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.BotGuard = void 0;
|
|
7
|
+
const openai_1 = __importDefault(require("openai"));
|
|
8
|
+
const DEFAULT_API_URL = 'https://agentguard-api-8ae872ce8db9.herokuapp.com';
|
|
9
|
+
function extractShield(data) {
|
|
10
|
+
const meta = data?._shield || {};
|
|
11
|
+
return {
|
|
12
|
+
action: meta.action || 'allowed',
|
|
13
|
+
reason: meta.reason,
|
|
14
|
+
confidence: meta.confidence,
|
|
15
|
+
analysisPath: meta.analysisPath,
|
|
16
|
+
matchedPatterns: meta.matchedPatterns,
|
|
17
|
+
piiDetections: meta.piiDetections,
|
|
18
|
+
guardrailViolation: meta.guardrailViolation,
|
|
19
|
+
policyViolation: meta.policyViolation,
|
|
20
|
+
latencyMs: meta.responseTimeMs,
|
|
21
|
+
blocked: (meta.action || 'allowed') !== 'allowed',
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
class BotGuard {
|
|
25
|
+
constructor(config) {
|
|
26
|
+
this.config = {
|
|
27
|
+
shieldId: config.shieldId,
|
|
28
|
+
apiKey: config.apiKey,
|
|
29
|
+
apiUrl: (config.apiUrl || DEFAULT_API_URL).replace(/\/$/, ''),
|
|
30
|
+
timeout: config.timeout || 120000,
|
|
31
|
+
};
|
|
32
|
+
const baseURL = `${this.config.apiUrl}/api/gateway/${this.config.shieldId}/v1`;
|
|
33
|
+
this.client = new openai_1.default({
|
|
34
|
+
apiKey: this.config.apiKey,
|
|
35
|
+
baseURL,
|
|
36
|
+
timeout: this.config.timeout,
|
|
37
|
+
});
|
|
38
|
+
this.chat = new ChatNamespace(this);
|
|
39
|
+
}
|
|
40
|
+
get openai() {
|
|
41
|
+
return this.client;
|
|
42
|
+
}
|
|
43
|
+
get baseURL() {
|
|
44
|
+
return `${this.config.apiUrl}/api/gateway/${this.config.shieldId}/v1`;
|
|
45
|
+
}
|
|
46
|
+
get apiKey() {
|
|
47
|
+
return this.config.apiKey;
|
|
48
|
+
}
|
|
49
|
+
get timeout() {
|
|
50
|
+
return this.config.timeout;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
exports.BotGuard = BotGuard;
|
|
54
|
+
class ChatNamespace {
|
|
55
|
+
constructor(guard) {
|
|
56
|
+
this.completions = new Completions(guard);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
class Completions {
|
|
60
|
+
constructor(guard) {
|
|
61
|
+
this.guard = guard;
|
|
62
|
+
}
|
|
63
|
+
async create(params) {
|
|
64
|
+
if (params.stream) {
|
|
65
|
+
return this.createStream(params);
|
|
66
|
+
}
|
|
67
|
+
const url = `${this.guard.baseURL}/chat/completions`;
|
|
68
|
+
const { stream: _, ...body } = params;
|
|
69
|
+
const resp = await fetch(url, {
|
|
70
|
+
method: 'POST',
|
|
71
|
+
headers: {
|
|
72
|
+
'Authorization': `Bearer ${this.guard.apiKey}`,
|
|
73
|
+
'Content-Type': 'application/json',
|
|
74
|
+
},
|
|
75
|
+
body: JSON.stringify({ ...body, stream: false }),
|
|
76
|
+
signal: AbortSignal.timeout(this.guard.timeout),
|
|
77
|
+
});
|
|
78
|
+
if (!resp.ok) {
|
|
79
|
+
const errBody = await resp.text();
|
|
80
|
+
throw new Error(`BotGuard API error (${resp.status}): ${errBody}`);
|
|
81
|
+
}
|
|
82
|
+
const data = await resp.json();
|
|
83
|
+
const shield = extractShield(data);
|
|
84
|
+
return {
|
|
85
|
+
response: data,
|
|
86
|
+
shield,
|
|
87
|
+
blocked: shield.blocked,
|
|
88
|
+
content: data?.choices?.[0]?.message?.content || null,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
async createStream(params) {
|
|
92
|
+
const url = `${this.guard.baseURL}/chat/completions`;
|
|
93
|
+
const { stream: _, ...body } = params;
|
|
94
|
+
const resp = await fetch(url, {
|
|
95
|
+
method: 'POST',
|
|
96
|
+
headers: {
|
|
97
|
+
'Authorization': `Bearer ${this.guard.apiKey}`,
|
|
98
|
+
'Content-Type': 'application/json',
|
|
99
|
+
},
|
|
100
|
+
body: JSON.stringify({ ...body, stream: true }),
|
|
101
|
+
signal: AbortSignal.timeout(this.guard.timeout),
|
|
102
|
+
});
|
|
103
|
+
if (!resp.ok) {
|
|
104
|
+
const errBody = await resp.text();
|
|
105
|
+
throw new Error(`BotGuard API error (${resp.status}): ${errBody}`);
|
|
106
|
+
}
|
|
107
|
+
const reader = resp.body?.getReader();
|
|
108
|
+
if (!reader) {
|
|
109
|
+
throw new Error('No response body');
|
|
110
|
+
}
|
|
111
|
+
const decoder = new TextDecoder();
|
|
112
|
+
async function* iterate() {
|
|
113
|
+
let buffer = '';
|
|
114
|
+
let shieldVerdict = {
|
|
115
|
+
action: 'allowed',
|
|
116
|
+
blocked: false,
|
|
117
|
+
};
|
|
118
|
+
while (true) {
|
|
119
|
+
const { done, value } = await reader.read();
|
|
120
|
+
if (done)
|
|
121
|
+
break;
|
|
122
|
+
buffer += decoder.decode(value, { stream: true });
|
|
123
|
+
const lines = buffer.split('\n');
|
|
124
|
+
buffer = lines.pop() || '';
|
|
125
|
+
for (const line of lines) {
|
|
126
|
+
if (!line.startsWith('data: '))
|
|
127
|
+
continue;
|
|
128
|
+
const payload = line.slice(6).trim();
|
|
129
|
+
if (payload === '[DONE]')
|
|
130
|
+
return;
|
|
131
|
+
try {
|
|
132
|
+
const chunkData = JSON.parse(payload);
|
|
133
|
+
if (chunkData._shield) {
|
|
134
|
+
shieldVerdict = extractShield(chunkData);
|
|
135
|
+
}
|
|
136
|
+
const content = chunkData?.choices?.[0]?.delta?.content || null;
|
|
137
|
+
yield {
|
|
138
|
+
response: chunkData,
|
|
139
|
+
shield: shieldVerdict,
|
|
140
|
+
blocked: shieldVerdict.blocked,
|
|
141
|
+
content,
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
catch {
|
|
145
|
+
continue;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
return iterate();
|
|
151
|
+
}
|
|
152
|
+
}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export interface ShieldVerdict {
|
|
2
|
+
action: string;
|
|
3
|
+
reason?: string;
|
|
4
|
+
confidence?: number;
|
|
5
|
+
analysisPath?: string;
|
|
6
|
+
matchedPatterns?: string[];
|
|
7
|
+
piiDetections?: Array<{
|
|
8
|
+
type: string;
|
|
9
|
+
value: string;
|
|
10
|
+
}>;
|
|
11
|
+
guardrailViolation?: string;
|
|
12
|
+
policyViolation?: string;
|
|
13
|
+
latencyMs?: number;
|
|
14
|
+
blocked: boolean;
|
|
15
|
+
}
|
|
16
|
+
export interface ShieldResult<T = any> {
|
|
17
|
+
response: T;
|
|
18
|
+
shield: ShieldVerdict;
|
|
19
|
+
blocked: boolean;
|
|
20
|
+
content: string | null;
|
|
21
|
+
}
|
|
22
|
+
export interface BotGuardConfig {
|
|
23
|
+
shieldId: string;
|
|
24
|
+
apiKey: string;
|
|
25
|
+
apiUrl?: string;
|
|
26
|
+
timeout?: number;
|
|
27
|
+
}
|
package/dist/types.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "botguard",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "BotGuard SDK — secure your LLM applications with multi-tier threat detection",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"files": ["dist"],
|
|
8
|
+
"scripts": {
|
|
9
|
+
"build": "tsc",
|
|
10
|
+
"prepublishOnly": "npm run build"
|
|
11
|
+
},
|
|
12
|
+
"keywords": ["llm", "security", "guardrails", "ai-safety", "prompt-injection", "openai"],
|
|
13
|
+
"license": "MIT",
|
|
14
|
+
"peerDependencies": {
|
|
15
|
+
"openai": ">=4.0.0"
|
|
16
|
+
},
|
|
17
|
+
"devDependencies": {
|
|
18
|
+
"openai": "^4.77.0",
|
|
19
|
+
"typescript": "^5.3.0"
|
|
20
|
+
},
|
|
21
|
+
"engines": {
|
|
22
|
+
"node": ">=18.0.0"
|
|
23
|
+
}
|
|
24
|
+
}
|