safetygates 0.1.0 → 0.2.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/package.json +1 -1
- package/src/index.d.ts +32 -45
- package/src/index.js +42 -67
package/package.json
CHANGED
package/src/index.d.ts
CHANGED
|
@@ -5,37 +5,41 @@
|
|
|
5
5
|
* Licensed under the MIT License
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
export
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
export type StrictnessLevel = 'strict' | 'balanced' | 'permissive';
|
|
9
|
+
|
|
10
|
+
export interface ClassifyOptions {
|
|
11
|
+
/** Moderation strictness: 'strict', 'balanced' (default), or 'permissive'. Paid tiers only. */
|
|
12
|
+
strictness?: StrictnessLevel;
|
|
11
13
|
}
|
|
12
14
|
|
|
13
15
|
export interface ClassifyResult {
|
|
14
|
-
|
|
16
|
+
request_id: string;
|
|
17
|
+
safe: boolean;
|
|
18
|
+
confidence: number;
|
|
19
|
+
categories: Record<string, number>;
|
|
20
|
+
lang: string | null;
|
|
21
|
+
strictness: StrictnessLevel;
|
|
15
22
|
latency_us: number;
|
|
23
|
+
watermark: string | null;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface BatchItemResult {
|
|
27
|
+
safe: boolean;
|
|
28
|
+
categories: Record<string, number>;
|
|
29
|
+
lang: string | null;
|
|
16
30
|
}
|
|
17
31
|
|
|
18
32
|
export interface BatchClassifyResult {
|
|
19
|
-
|
|
33
|
+
request_id: string;
|
|
34
|
+
results: BatchItemResult[];
|
|
20
35
|
total_latency_us: number;
|
|
21
36
|
items_per_second: number;
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
export interface GateInfo {
|
|
25
|
-
id: string;
|
|
26
|
-
category: string;
|
|
27
|
-
description: string;
|
|
28
|
-
threshold: number;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export interface GatesListResult {
|
|
32
|
-
gates: GateInfo[];
|
|
37
|
+
watermark: string | null;
|
|
33
38
|
}
|
|
34
39
|
|
|
35
40
|
export interface HealthResult {
|
|
36
41
|
status: string;
|
|
37
42
|
gates_loaded: number;
|
|
38
|
-
available_gates: string[];
|
|
39
43
|
}
|
|
40
44
|
|
|
41
45
|
export interface SafetyGatesOptions {
|
|
@@ -43,19 +47,6 @@ export interface SafetyGatesOptions {
|
|
|
43
47
|
timeout?: number;
|
|
44
48
|
}
|
|
45
49
|
|
|
46
|
-
export declare const GATES: {
|
|
47
|
-
TOXIC: 'toxic';
|
|
48
|
-
SPAM: 'spam';
|
|
49
|
-
HATE: 'hate';
|
|
50
|
-
NSFW: 'nsfw';
|
|
51
|
-
HARASSMENT: 'harassment';
|
|
52
|
-
TOXIC_ES: 'toxic_es';
|
|
53
|
-
SPAM_ES: 'spam_es';
|
|
54
|
-
HATE_ES: 'hate_es';
|
|
55
|
-
TOXIC_PT: 'toxic_pt';
|
|
56
|
-
TOXIC_FR: 'toxic_fr';
|
|
57
|
-
};
|
|
58
|
-
|
|
59
50
|
export declare class SafetyGatesError extends Error {
|
|
60
51
|
statusCode: number;
|
|
61
52
|
detail: any;
|
|
@@ -66,29 +57,25 @@ export declare class SafetyGates {
|
|
|
66
57
|
constructor(apiKey: string, options?: SafetyGatesOptions);
|
|
67
58
|
|
|
68
59
|
/**
|
|
69
|
-
* Classify
|
|
60
|
+
* Classify text for safety
|
|
61
|
+
* @param text - Text to classify
|
|
62
|
+
* @param options - Classification options including strictness
|
|
70
63
|
*/
|
|
71
|
-
classify(text: string,
|
|
64
|
+
classify(text: string, options?: ClassifyOptions): Promise<ClassifyResult>;
|
|
72
65
|
|
|
73
66
|
/**
|
|
74
67
|
* Classify multiple texts in batch
|
|
68
|
+
* @param texts - Array of texts to classify (max 10,000)
|
|
69
|
+
* @param options - Classification options including strictness
|
|
75
70
|
*/
|
|
76
|
-
classifyBatch(texts: string[],
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* Check if text is toxic (convenience method)
|
|
80
|
-
*/
|
|
81
|
-
isToxic(text: string, threshold?: number): Promise<boolean>;
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* Check if text is spam (convenience method)
|
|
85
|
-
*/
|
|
86
|
-
isSpam(text: string, threshold?: number): Promise<boolean>;
|
|
71
|
+
classifyBatch(texts: string[], options?: ClassifyOptions): Promise<BatchClassifyResult>;
|
|
87
72
|
|
|
88
73
|
/**
|
|
89
|
-
*
|
|
74
|
+
* Check if text is safe (convenience method)
|
|
75
|
+
* @param text - Text to check
|
|
76
|
+
* @param options - Classification options including strictness
|
|
90
77
|
*/
|
|
91
|
-
|
|
78
|
+
isSafe(text: string, options?: ClassifyOptions): Promise<boolean>;
|
|
92
79
|
|
|
93
80
|
/**
|
|
94
81
|
* Health check
|
package/src/index.js
CHANGED
|
@@ -20,26 +20,6 @@ const http = require('http');
|
|
|
20
20
|
const DEFAULT_BASE_URL = 'https://sg-api.cyclecore.ai';
|
|
21
21
|
const DEFAULT_TIMEOUT = 10000;
|
|
22
22
|
|
|
23
|
-
/**
|
|
24
|
-
* Available classification gates
|
|
25
|
-
*/
|
|
26
|
-
const GATES = {
|
|
27
|
-
// English
|
|
28
|
-
TOXIC: 'toxic',
|
|
29
|
-
SPAM: 'spam',
|
|
30
|
-
HATE: 'hate',
|
|
31
|
-
NSFW: 'nsfw',
|
|
32
|
-
HARASSMENT: 'harassment',
|
|
33
|
-
// Spanish
|
|
34
|
-
TOXIC_ES: 'toxic_es',
|
|
35
|
-
SPAM_ES: 'spam_es',
|
|
36
|
-
HATE_ES: 'hate_es',
|
|
37
|
-
// Portuguese
|
|
38
|
-
TOXIC_PT: 'toxic_pt',
|
|
39
|
-
// French
|
|
40
|
-
TOXIC_FR: 'toxic_fr',
|
|
41
|
-
};
|
|
42
|
-
|
|
43
23
|
class SafetyGatesError extends Error {
|
|
44
24
|
constructor(message, statusCode, detail) {
|
|
45
25
|
super(message);
|
|
@@ -84,7 +64,7 @@ class SafetyGates {
|
|
|
84
64
|
headers: {
|
|
85
65
|
'Content-Type': 'application/json',
|
|
86
66
|
'X-API-Key': this.apiKey,
|
|
87
|
-
'User-Agent': 'safetygates-node/1.
|
|
67
|
+
'User-Agent': 'safetygates-node/1.1.0',
|
|
88
68
|
},
|
|
89
69
|
timeout: this.timeout,
|
|
90
70
|
};
|
|
@@ -129,87 +109,83 @@ class SafetyGates {
|
|
|
129
109
|
/**
|
|
130
110
|
* Classify a single text
|
|
131
111
|
* @param {string} text - Text to classify
|
|
132
|
-
* @param {
|
|
112
|
+
* @param {Object} options - Classification options
|
|
113
|
+
* @param {string} options.strictness - 'strict', 'balanced' (default), or 'permissive' (paid tiers only)
|
|
133
114
|
* @returns {Promise<ClassifyResult>}
|
|
134
115
|
*
|
|
135
116
|
* @example
|
|
136
|
-
* const result = await client.classify('you suck'
|
|
137
|
-
* console.log(result.
|
|
138
|
-
* console.log(result.
|
|
117
|
+
* const result = await client.classify('you suck');
|
|
118
|
+
* console.log(result.safe); // false
|
|
119
|
+
* console.log(result.confidence); // 0.92
|
|
120
|
+
*
|
|
121
|
+
* // With strictness (paid tiers only)
|
|
122
|
+
* const strict = await client.classify('borderline content', { strictness: 'strict' });
|
|
139
123
|
*/
|
|
140
|
-
async classify(text,
|
|
124
|
+
async classify(text, options = {}) {
|
|
141
125
|
if (!text || typeof text !== 'string') {
|
|
142
126
|
throw new Error('Text must be a non-empty string');
|
|
143
127
|
}
|
|
144
|
-
|
|
145
|
-
|
|
128
|
+
|
|
129
|
+
const body = { text };
|
|
130
|
+
if (options.strictness) {
|
|
131
|
+
body.strictness = options.strictness;
|
|
146
132
|
}
|
|
147
133
|
|
|
148
|
-
return this._request('POST', '/v1/classify',
|
|
134
|
+
return this._request('POST', '/v1/classify', body);
|
|
149
135
|
}
|
|
150
136
|
|
|
151
137
|
/**
|
|
152
138
|
* Classify multiple texts in batch
|
|
153
139
|
* @param {string[]} texts - Array of texts to classify (max 10,000)
|
|
154
|
-
* @param {
|
|
140
|
+
* @param {Object} options - Classification options
|
|
141
|
+
* @param {string} options.strictness - 'strict', 'balanced' (default), or 'permissive' (paid tiers only)
|
|
155
142
|
* @returns {Promise<BatchClassifyResult>}
|
|
156
143
|
*
|
|
157
144
|
* @example
|
|
158
|
-
* const result = await client.classifyBatch(
|
|
159
|
-
* ['hello', 'you suck', 'nice game'],
|
|
160
|
-
* ['toxic']
|
|
161
|
-
* );
|
|
145
|
+
* const result = await client.classifyBatch(['hello', 'you suck', 'nice game']);
|
|
162
146
|
* result.results.forEach((r, i) => {
|
|
163
|
-
* console.log(`Text ${i}:
|
|
147
|
+
* console.log(`Text ${i}: safe=${r.safe}`);
|
|
164
148
|
* });
|
|
149
|
+
*
|
|
150
|
+
* // With strictness (paid tiers only)
|
|
151
|
+
* const strict = await client.classifyBatch(texts, { strictness: 'strict' });
|
|
165
152
|
*/
|
|
166
|
-
async classifyBatch(texts,
|
|
153
|
+
async classifyBatch(texts, options = {}) {
|
|
167
154
|
if (!Array.isArray(texts) || texts.length === 0) {
|
|
168
155
|
throw new Error('Texts must be a non-empty array');
|
|
169
156
|
}
|
|
170
157
|
if (texts.length > 10000) {
|
|
171
158
|
throw new Error('Batch size cannot exceed 10,000');
|
|
172
159
|
}
|
|
173
|
-
|
|
174
|
-
|
|
160
|
+
|
|
161
|
+
const body = { texts };
|
|
162
|
+
if (options.strictness) {
|
|
163
|
+
body.strictness = options.strictness;
|
|
175
164
|
}
|
|
176
165
|
|
|
177
|
-
return this._request('POST', '/v1/classify/batch',
|
|
166
|
+
return this._request('POST', '/v1/classify/batch', body);
|
|
178
167
|
}
|
|
179
168
|
|
|
180
169
|
/**
|
|
181
|
-
* Check if text is
|
|
170
|
+
* Check if text is safe (convenience method)
|
|
182
171
|
* @param {string} text - Text to check
|
|
183
|
-
* @param {
|
|
172
|
+
* @param {Object} options - Classification options
|
|
173
|
+
* @param {string} options.strictness - 'strict', 'balanced' (default), or 'permissive' (paid tiers only)
|
|
184
174
|
* @returns {Promise<boolean>}
|
|
185
175
|
*
|
|
186
176
|
* @example
|
|
187
|
-
* if (await client.
|
|
188
|
-
* console.log('
|
|
177
|
+
* if (await client.isSafe('hello world')) {
|
|
178
|
+
* console.log('Content is safe');
|
|
179
|
+
* }
|
|
180
|
+
*
|
|
181
|
+
* // With strict moderation
|
|
182
|
+
* if (await client.isSafe(userInput, { strictness: 'strict' })) {
|
|
183
|
+
* // Allow content
|
|
189
184
|
* }
|
|
190
185
|
*/
|
|
191
|
-
async
|
|
192
|
-
const result = await this.classify(text,
|
|
193
|
-
return result.
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
/**
|
|
197
|
-
* Check if text is spam (convenience method)
|
|
198
|
-
* @param {string} text - Text to check
|
|
199
|
-
* @param {number} threshold - Confidence threshold (default: 0.5)
|
|
200
|
-
* @returns {Promise<boolean>}
|
|
201
|
-
*/
|
|
202
|
-
async isSpam(text, threshold = 0.5) {
|
|
203
|
-
const result = await this.classify(text, ['spam']);
|
|
204
|
-
return result.results.spam.confidence >= threshold;
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
/**
|
|
208
|
-
* Get available gates
|
|
209
|
-
* @returns {Promise<GatesListResult>}
|
|
210
|
-
*/
|
|
211
|
-
async listGates() {
|
|
212
|
-
return this._request('GET', '/v1/gates');
|
|
186
|
+
async isSafe(text, options = {}) {
|
|
187
|
+
const result = await this.classify(text, options);
|
|
188
|
+
return result.safe;
|
|
213
189
|
}
|
|
214
190
|
|
|
215
191
|
/**
|
|
@@ -221,8 +197,7 @@ class SafetyGates {
|
|
|
221
197
|
}
|
|
222
198
|
}
|
|
223
199
|
|
|
224
|
-
// Export class
|
|
200
|
+
// Export class
|
|
225
201
|
module.exports = SafetyGates;
|
|
226
202
|
module.exports.SafetyGates = SafetyGates;
|
|
227
203
|
module.exports.SafetyGatesError = SafetyGatesError;
|
|
228
|
-
module.exports.GATES = GATES;
|