promptguard-sdk 1.2.0 → 1.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +226 -78
- package/dist/auto.d.ts +40 -0
- package/dist/auto.d.ts.map +1 -0
- package/dist/auto.js +118 -0
- package/dist/auto.js.map +1 -0
- package/dist/guard.d.ts +80 -0
- package/dist/guard.d.ts.map +1 -0
- package/dist/guard.js +104 -0
- package/dist/guard.js.map +1 -0
- package/dist/index.d.ts +105 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +111 -29
- package/dist/index.js.map +1 -1
- package/dist/integrations/langchain.d.ts +55 -0
- package/dist/integrations/langchain.d.ts.map +1 -0
- package/dist/integrations/langchain.js +212 -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 +170 -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 +188 -0
- package/dist/patches/anthropic.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 +246 -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 +183 -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 +163 -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 +165 -0
- package/dist/patches/openai.js.map +1 -0
- package/package.json +83 -11
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Google Generative AI SDK patch — wraps
|
|
4
|
+
* `GenerativeModel.prototype.generateContent` from `@google/generative-ai`.
|
|
5
|
+
*
|
|
6
|
+
* Covers direct Google AI usage and frameworks built on top (LangChain.js
|
|
7
|
+
* ChatGoogleGenerativeAI, etc.).
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.contentToGuardFormat = contentToGuardFormat;
|
|
11
|
+
exports.extractResponseText = extractResponseText;
|
|
12
|
+
exports.apply = apply;
|
|
13
|
+
exports.revert = revert;
|
|
14
|
+
const guard_1 = require("../guard");
|
|
15
|
+
let originalGenerate = null;
|
|
16
|
+
let patched = false;
|
|
17
|
+
// ---------------------------------------------------------------------------
|
|
18
|
+
// Message conversion
|
|
19
|
+
// ---------------------------------------------------------------------------
|
|
20
|
+
function contentToGuardFormat(contents) {
|
|
21
|
+
if (typeof contents === "string") {
|
|
22
|
+
return [{ role: "user", content: contents }];
|
|
23
|
+
}
|
|
24
|
+
if (!Array.isArray(contents)) {
|
|
25
|
+
return [{ role: "user", content: String(contents ?? "") }];
|
|
26
|
+
}
|
|
27
|
+
const result = [];
|
|
28
|
+
for (const item of contents) {
|
|
29
|
+
if (typeof item === "string") {
|
|
30
|
+
result.push({ role: "user", content: item });
|
|
31
|
+
}
|
|
32
|
+
else if (item?.role && item?.parts) {
|
|
33
|
+
const text = extractTextFromParts(item.parts);
|
|
34
|
+
result.push({ role: item.role ?? "user", content: text });
|
|
35
|
+
}
|
|
36
|
+
else if (item?.parts) {
|
|
37
|
+
result.push({ role: "user", content: extractTextFromParts(item.parts) });
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
result.push({ role: "user", content: String(item) });
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return result;
|
|
44
|
+
}
|
|
45
|
+
function extractTextFromParts(parts) {
|
|
46
|
+
if (typeof parts === "string")
|
|
47
|
+
return parts;
|
|
48
|
+
if (!Array.isArray(parts))
|
|
49
|
+
return String(parts ?? "");
|
|
50
|
+
const texts = [];
|
|
51
|
+
for (const part of parts) {
|
|
52
|
+
if (typeof part === "string")
|
|
53
|
+
texts.push(part);
|
|
54
|
+
else if (part?.text != null)
|
|
55
|
+
texts.push(String(part.text));
|
|
56
|
+
}
|
|
57
|
+
return texts.join("\n");
|
|
58
|
+
}
|
|
59
|
+
function extractResponseText(response) {
|
|
60
|
+
try {
|
|
61
|
+
const r = response;
|
|
62
|
+
if (typeof r?.text === "function")
|
|
63
|
+
return r.text();
|
|
64
|
+
if (typeof r?.text === "string")
|
|
65
|
+
return r.text;
|
|
66
|
+
const candidates = r?.candidates;
|
|
67
|
+
if (candidates?.[0]?.content) {
|
|
68
|
+
const content = candidates[0].content;
|
|
69
|
+
if (content?.parts)
|
|
70
|
+
return extractTextFromParts(content.parts);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
// ignore
|
|
75
|
+
}
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
// ---------------------------------------------------------------------------
|
|
79
|
+
// Apply / revert
|
|
80
|
+
// ---------------------------------------------------------------------------
|
|
81
|
+
function apply() {
|
|
82
|
+
if (patched)
|
|
83
|
+
return true;
|
|
84
|
+
let GenerativeModel;
|
|
85
|
+
try {
|
|
86
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
87
|
+
const mod = require("@google/generative-ai");
|
|
88
|
+
GenerativeModel = mod.GenerativeModel;
|
|
89
|
+
if (!GenerativeModel?.prototype?.generateContent)
|
|
90
|
+
return false;
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
return false;
|
|
94
|
+
}
|
|
95
|
+
originalGenerate = GenerativeModel.prototype.generateContent;
|
|
96
|
+
GenerativeModel.prototype.generateContent = async function patchedGenerate(...args) {
|
|
97
|
+
const { getGuardClient, getMode, isFailOpen, shouldScanResponses } = require("../auto");
|
|
98
|
+
const guard = getGuardClient();
|
|
99
|
+
if (!guard)
|
|
100
|
+
return originalGenerate?.apply(this, args);
|
|
101
|
+
const contents = args[0];
|
|
102
|
+
const modelName = String(this.model ?? this.modelName ?? "gemini");
|
|
103
|
+
// -- Pre-call scan ---------------------------------------------------
|
|
104
|
+
if (contents) {
|
|
105
|
+
const guardMessages = contentToGuardFormat(contents);
|
|
106
|
+
let decision = null;
|
|
107
|
+
try {
|
|
108
|
+
decision = await guard.scan(guardMessages, "input", modelName, {
|
|
109
|
+
framework: "google-generativeai",
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
catch (err) {
|
|
113
|
+
if (err instanceof guard_1.GuardApiError && !isFailOpen())
|
|
114
|
+
throw err;
|
|
115
|
+
}
|
|
116
|
+
if (decision?.blocked) {
|
|
117
|
+
if (getMode() === "enforce")
|
|
118
|
+
throw new guard_1.PromptGuardBlockedError(decision);
|
|
119
|
+
console.warn(`[promptguard][monitor] would block: ${decision.threatType} (event=${decision.eventId})`);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
// -- Original call ---------------------------------------------------
|
|
123
|
+
const response = await originalGenerate?.apply(this, args);
|
|
124
|
+
// -- Post-call scan --------------------------------------------------
|
|
125
|
+
if (shouldScanResponses() && response && guard) {
|
|
126
|
+
try {
|
|
127
|
+
const text = extractResponseText(response);
|
|
128
|
+
if (text) {
|
|
129
|
+
const respDecision = await guard.scan([{ role: "assistant", content: text }], "output", modelName);
|
|
130
|
+
if (respDecision.blocked && getMode() === "enforce") {
|
|
131
|
+
throw new guard_1.PromptGuardBlockedError(respDecision);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
catch (err) {
|
|
136
|
+
if (err instanceof guard_1.PromptGuardBlockedError)
|
|
137
|
+
throw err;
|
|
138
|
+
if (err instanceof guard_1.GuardApiError && !isFailOpen())
|
|
139
|
+
throw err;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return response;
|
|
143
|
+
};
|
|
144
|
+
patched = true;
|
|
145
|
+
return true;
|
|
146
|
+
}
|
|
147
|
+
function revert() {
|
|
148
|
+
if (!patched || !originalGenerate)
|
|
149
|
+
return;
|
|
150
|
+
try {
|
|
151
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
152
|
+
const mod = require("@google/generative-ai");
|
|
153
|
+
if (mod.GenerativeModel) {
|
|
154
|
+
mod.GenerativeModel.prototype.generateContent = originalGenerate;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
catch {
|
|
158
|
+
// ignore
|
|
159
|
+
}
|
|
160
|
+
originalGenerate = null;
|
|
161
|
+
patched = false;
|
|
162
|
+
}
|
|
163
|
+
//# sourceMappingURL=google.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"google.js","sourceRoot":"","sources":["../../src/patches/google.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenAI SDK patch — wraps the `create` method on the Chat Completions
|
|
3
|
+
* prototype (sync and async).
|
|
4
|
+
*
|
|
5
|
+
* This single patch covers every framework built on the `openai` npm
|
|
6
|
+
* package: LangChain.js (ChatOpenAI), Vercel AI SDK (openai provider),
|
|
7
|
+
* AutoGen.js, CrewAI.js, and direct usage.
|
|
8
|
+
*/
|
|
9
|
+
import { type GuardMessage } from "../guard";
|
|
10
|
+
export declare function messagesToGuardFormat(messages: unknown[]): GuardMessage[];
|
|
11
|
+
export declare function extractResponseContent(response: unknown): string | null;
|
|
12
|
+
export declare function apply(): boolean;
|
|
13
|
+
export declare function revert(): void;
|
|
14
|
+
//# sourceMappingURL=openai.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai.d.ts","sourceRoot":"","sources":["../../src/patches/openai.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAiB,KAAK,YAAY,EAA2B,MAAM,UAAU,CAAA;AASpF,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,YAAY,EAAE,CA2BzE;AAED,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAUvE;AAeD,wBAAgB,KAAK,IAAI,OAAO,CAqF/B;AAED,wBAAgB,MAAM,IAAI,IAAI,CAa7B"}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* OpenAI SDK patch — wraps the `create` method on the Chat Completions
|
|
4
|
+
* prototype (sync and async).
|
|
5
|
+
*
|
|
6
|
+
* This single patch covers every framework built on the `openai` npm
|
|
7
|
+
* package: LangChain.js (ChatOpenAI), Vercel AI SDK (openai provider),
|
|
8
|
+
* AutoGen.js, CrewAI.js, and direct usage.
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.messagesToGuardFormat = messagesToGuardFormat;
|
|
12
|
+
exports.extractResponseContent = extractResponseContent;
|
|
13
|
+
exports.apply = apply;
|
|
14
|
+
exports.revert = revert;
|
|
15
|
+
const guard_1 = require("../guard");
|
|
16
|
+
let originalCreate = null;
|
|
17
|
+
let patched = false;
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
// Message conversion
|
|
20
|
+
// ---------------------------------------------------------------------------
|
|
21
|
+
function messagesToGuardFormat(messages) {
|
|
22
|
+
if (!messages)
|
|
23
|
+
return [];
|
|
24
|
+
const result = [];
|
|
25
|
+
for (const raw of messages) {
|
|
26
|
+
if (!raw)
|
|
27
|
+
continue;
|
|
28
|
+
const msg = raw;
|
|
29
|
+
const role = String(msg.role ?? "user");
|
|
30
|
+
let content;
|
|
31
|
+
if (typeof msg.content === "string") {
|
|
32
|
+
content = msg.content;
|
|
33
|
+
}
|
|
34
|
+
else if (Array.isArray(msg.content)) {
|
|
35
|
+
const textParts = [];
|
|
36
|
+
for (const part of msg.content) {
|
|
37
|
+
if (typeof part === "string")
|
|
38
|
+
textParts.push(part);
|
|
39
|
+
else if (part?.type === "text")
|
|
40
|
+
textParts.push(part.text ?? "");
|
|
41
|
+
}
|
|
42
|
+
content = textParts.join("\n");
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
content = String(msg.content ?? "");
|
|
46
|
+
}
|
|
47
|
+
result.push({ role, content });
|
|
48
|
+
}
|
|
49
|
+
return result;
|
|
50
|
+
}
|
|
51
|
+
function extractResponseContent(response) {
|
|
52
|
+
try {
|
|
53
|
+
const r = response;
|
|
54
|
+
if (r?.choices?.[0]?.message?.content) {
|
|
55
|
+
return r.choices[0].message.content;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
// ignore
|
|
60
|
+
}
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
function applyRedaction(messages, redacted) {
|
|
64
|
+
return messages.map((msg, i) => {
|
|
65
|
+
if (i < redacted.length && typeof msg === "object" && msg !== null) {
|
|
66
|
+
return { ...msg, content: redacted[i].content };
|
|
67
|
+
}
|
|
68
|
+
return msg;
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
// ---------------------------------------------------------------------------
|
|
72
|
+
// Apply / revert
|
|
73
|
+
// ---------------------------------------------------------------------------
|
|
74
|
+
function apply() {
|
|
75
|
+
if (patched)
|
|
76
|
+
return true;
|
|
77
|
+
let Completions;
|
|
78
|
+
try {
|
|
79
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
80
|
+
const mod = require("openai/resources/chat/completions");
|
|
81
|
+
Completions = mod.Completions;
|
|
82
|
+
if (!Completions?.prototype?.create)
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
originalCreate = Completions.prototype.create;
|
|
89
|
+
Completions.prototype.create = async function patchedCreate(...args) {
|
|
90
|
+
const { getGuardClient, getMode, isFailOpen, shouldScanResponses } = require("../auto");
|
|
91
|
+
const guard = getGuardClient();
|
|
92
|
+
if (!guard)
|
|
93
|
+
return originalCreate?.apply(this, args);
|
|
94
|
+
const params = (args[0] ?? {});
|
|
95
|
+
const messages = params.messages;
|
|
96
|
+
const model = params.model;
|
|
97
|
+
// -- Pre-call scan ---------------------------------------------------
|
|
98
|
+
if (messages) {
|
|
99
|
+
const guardMessages = messagesToGuardFormat(messages);
|
|
100
|
+
let decision = null;
|
|
101
|
+
try {
|
|
102
|
+
decision = await guard.scan(guardMessages, "input", model ? String(model) : undefined, {
|
|
103
|
+
framework: "openai",
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
catch (err) {
|
|
107
|
+
if (err instanceof guard_1.GuardApiError && !isFailOpen())
|
|
108
|
+
throw err;
|
|
109
|
+
// fail-open: continue
|
|
110
|
+
}
|
|
111
|
+
if (decision?.blocked) {
|
|
112
|
+
if (getMode() === "enforce")
|
|
113
|
+
throw new guard_1.PromptGuardBlockedError(decision);
|
|
114
|
+
console.warn(`[promptguard][monitor] would block: ${decision.threatType} (event=${decision.eventId})`);
|
|
115
|
+
}
|
|
116
|
+
if (decision?.redacted && decision.redactedMessages) {
|
|
117
|
+
if (getMode() === "enforce") {
|
|
118
|
+
args[0] = {
|
|
119
|
+
...params,
|
|
120
|
+
messages: applyRedaction(messages, decision.redactedMessages),
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
// -- Original call ---------------------------------------------------
|
|
126
|
+
const response = await originalCreate?.apply(this, args);
|
|
127
|
+
// -- Post-call scan --------------------------------------------------
|
|
128
|
+
if (shouldScanResponses() && response && guard) {
|
|
129
|
+
try {
|
|
130
|
+
const text = extractResponseContent(response);
|
|
131
|
+
if (text) {
|
|
132
|
+
const respDecision = await guard.scan([{ role: "assistant", content: text }], "output", model ? String(model) : undefined);
|
|
133
|
+
if (respDecision.blocked && getMode() === "enforce") {
|
|
134
|
+
throw new guard_1.PromptGuardBlockedError(respDecision);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
catch (err) {
|
|
139
|
+
if (err instanceof guard_1.PromptGuardBlockedError)
|
|
140
|
+
throw err;
|
|
141
|
+
if (err instanceof guard_1.GuardApiError && !isFailOpen())
|
|
142
|
+
throw err;
|
|
143
|
+
// fail-open
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
return response;
|
|
147
|
+
};
|
|
148
|
+
patched = true;
|
|
149
|
+
return true;
|
|
150
|
+
}
|
|
151
|
+
function revert() {
|
|
152
|
+
if (!patched || !originalCreate)
|
|
153
|
+
return;
|
|
154
|
+
try {
|
|
155
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
156
|
+
const mod = require("openai/resources/chat/completions");
|
|
157
|
+
mod.Completions.prototype.create = originalCreate;
|
|
158
|
+
}
|
|
159
|
+
catch {
|
|
160
|
+
// ignore
|
|
161
|
+
}
|
|
162
|
+
originalCreate = null;
|
|
163
|
+
patched = false;
|
|
164
|
+
}
|
|
165
|
+
//# sourceMappingURL=openai.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai.js","sourceRoot":"","sources":["../../src/patches/openai.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,13 +1,38 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "promptguard-sdk",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "Drop-in security for AI applications - AI Firewall SDK",
|
|
3
|
+
"version": "1.5.1",
|
|
4
|
+
"description": "Drop-in security for AI applications - AI Firewall SDK with auto-instrumentation",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"require": "./dist/index.js",
|
|
10
|
+
"types": "./dist/index.d.ts"
|
|
11
|
+
},
|
|
12
|
+
"./auto": {
|
|
13
|
+
"require": "./dist/auto.js",
|
|
14
|
+
"types": "./dist/auto.d.ts"
|
|
15
|
+
},
|
|
16
|
+
"./guard": {
|
|
17
|
+
"require": "./dist/guard.js",
|
|
18
|
+
"types": "./dist/guard.d.ts"
|
|
19
|
+
},
|
|
20
|
+
"./integrations/langchain": {
|
|
21
|
+
"require": "./dist/integrations/langchain.js",
|
|
22
|
+
"types": "./dist/integrations/langchain.d.ts"
|
|
23
|
+
},
|
|
24
|
+
"./integrations/vercel-ai": {
|
|
25
|
+
"require": "./dist/integrations/vercel-ai.js",
|
|
26
|
+
"types": "./dist/integrations/vercel-ai.d.ts"
|
|
27
|
+
}
|
|
28
|
+
},
|
|
7
29
|
"scripts": {
|
|
8
30
|
"build": "tsc",
|
|
9
|
-
"test": "jest",
|
|
10
|
-
"lint": "
|
|
31
|
+
"test": "node --experimental-vm-modules node_modules/.bin/jest",
|
|
32
|
+
"lint": "tsc --noEmit && npx biome check .",
|
|
33
|
+
"format": "npx biome format --write .",
|
|
34
|
+
"format:check": "npx biome format .",
|
|
35
|
+
"check": "npx biome check .",
|
|
11
36
|
"prepublishOnly": "npm run build"
|
|
12
37
|
},
|
|
13
38
|
"keywords": [
|
|
@@ -17,31 +42,78 @@
|
|
|
17
42
|
"prompt-injection",
|
|
18
43
|
"openai",
|
|
19
44
|
"anthropic",
|
|
45
|
+
"google-generativeai",
|
|
20
46
|
"ai-firewall",
|
|
21
47
|
"pii-detection",
|
|
22
|
-
"llm-security"
|
|
48
|
+
"llm-security",
|
|
49
|
+
"ai-security",
|
|
50
|
+
"langchain",
|
|
51
|
+
"vercel-ai",
|
|
52
|
+
"auto-instrumentation",
|
|
53
|
+
"genai-security",
|
|
54
|
+
"cohere",
|
|
55
|
+
"aws-bedrock"
|
|
23
56
|
],
|
|
24
57
|
"author": "PromptGuard <support@promptguard.co>",
|
|
25
58
|
"license": "MIT",
|
|
26
59
|
"repository": {
|
|
27
60
|
"type": "git",
|
|
28
|
-
"url": "https://github.com/acebot712/promptguard.git"
|
|
29
|
-
"directory": "packages/sdk-node"
|
|
61
|
+
"url": "https://github.com/acebot712/promptguard-node.git"
|
|
30
62
|
},
|
|
31
63
|
"homepage": "https://promptguard.co",
|
|
32
64
|
"bugs": {
|
|
33
|
-
"url": "https://github.com/acebot712/promptguard/issues"
|
|
65
|
+
"url": "https://github.com/acebot712/promptguard-node/issues"
|
|
34
66
|
},
|
|
35
67
|
"engines": {
|
|
36
|
-
"node": ">=
|
|
68
|
+
"node": ">=20.0.0"
|
|
37
69
|
},
|
|
38
70
|
"publishConfig": {
|
|
39
71
|
"access": "public"
|
|
40
72
|
},
|
|
41
|
-
"files": [
|
|
42
|
-
|
|
73
|
+
"files": [
|
|
74
|
+
"dist",
|
|
75
|
+
"README.md",
|
|
76
|
+
"LICENSE"
|
|
77
|
+
],
|
|
43
78
|
"devDependencies": {
|
|
79
|
+
"@biomejs/biome": "^2.4.4",
|
|
80
|
+
"@types/jest": "^29.5.14",
|
|
44
81
|
"@types/node": "^20.0.0",
|
|
82
|
+
"jest": "^29.7.0",
|
|
83
|
+
"ts-jest": "^29.4.6",
|
|
84
|
+
"ts-node": "^10.9.2",
|
|
45
85
|
"typescript": "^5.0.0"
|
|
86
|
+
},
|
|
87
|
+
"peerDependencies": {
|
|
88
|
+
"@anthropic-ai/sdk": ">=0.20.0",
|
|
89
|
+
"@aws-sdk/client-bedrock-runtime": ">=3.0.0",
|
|
90
|
+
"@google/generative-ai": ">=0.5.0",
|
|
91
|
+
"@langchain/core": ">=0.1.0",
|
|
92
|
+
"ai": ">=3.0.0",
|
|
93
|
+
"cohere-ai": ">=7.0.0",
|
|
94
|
+
"openai": ">=4.0.0"
|
|
95
|
+
},
|
|
96
|
+
"peerDependenciesMeta": {
|
|
97
|
+
"openai": {
|
|
98
|
+
"optional": true
|
|
99
|
+
},
|
|
100
|
+
"@anthropic-ai/sdk": {
|
|
101
|
+
"optional": true
|
|
102
|
+
},
|
|
103
|
+
"@aws-sdk/client-bedrock-runtime": {
|
|
104
|
+
"optional": true
|
|
105
|
+
},
|
|
106
|
+
"@google/generative-ai": {
|
|
107
|
+
"optional": true
|
|
108
|
+
},
|
|
109
|
+
"@langchain/core": {
|
|
110
|
+
"optional": true
|
|
111
|
+
},
|
|
112
|
+
"ai": {
|
|
113
|
+
"optional": true
|
|
114
|
+
},
|
|
115
|
+
"cohere-ai": {
|
|
116
|
+
"optional": true
|
|
117
|
+
}
|
|
46
118
|
}
|
|
47
119
|
}
|