@privacyscrubber/sdk 2.3.7 → 2.4.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/README.md +86 -28
- package/benchmark.js +347 -0
- package/browser.js +2 -2
- package/cli.js +54 -2
- package/examples/python-bridge/MANIFEST.in +5 -0
- package/examples/python-bridge/README.md +265 -0
- package/examples/python-bridge/bridge_daemon.cjs +241 -0
- package/examples/python-bridge/dist/privacyscrubber-2.3.9-py3-none-any.whl +0 -0
- package/examples/python-bridge/dist/privacyscrubber-2.3.9.tar.gz +0 -0
- package/examples/python-bridge/fastapi_example.py +206 -0
- package/examples/python-bridge/langchain_adapter.py +20 -0
- package/examples/python-bridge/langchain_example.py +126 -0
- package/examples/python-bridge/llamaindex_example.py +103 -0
- package/examples/python-bridge/privacyscrubber/__init__.py +42 -0
- package/examples/python-bridge/privacyscrubber/bridge_daemon.cjs +241 -0
- package/examples/python-bridge/privacyscrubber/cli.py +138 -0
- package/examples/python-bridge/privacyscrubber/client.py +542 -0
- package/examples/python-bridge/privacyscrubber/exceptions.py +26 -0
- package/examples/python-bridge/privacyscrubber/langchain.py +161 -0
- package/examples/python-bridge/privacyscrubber/types.py +52 -0
- package/examples/python-bridge/privacyscrubber.egg-info/PKG-INFO +311 -0
- package/examples/python-bridge/privacyscrubber.egg-info/SOURCES.txt +18 -0
- package/examples/python-bridge/privacyscrubber.egg-info/dependency_links.txt +1 -0
- package/examples/python-bridge/privacyscrubber.egg-info/entry_points.txt +3 -0
- package/examples/python-bridge/privacyscrubber.egg-info/requires.txt +18 -0
- package/examples/python-bridge/privacyscrubber.egg-info/top_level.txt +1 -0
- package/examples/python-bridge/privacyscrubber.py +36 -0
- package/examples/python-bridge/pyproject.toml +62 -0
- package/examples/python-bridge/setup.py +66 -0
- package/examples/python-bridge/test_python_bridge.py +320 -0
- package/examples/vercel-ai-stream.js +195 -0
- package/fastmcp.cjs +291 -2
- package/fastmcp.d.ts +18 -0
- package/fastmcp.js +4 -0
- package/index.cjs +211 -134
- package/index.js +211 -134
- package/package.json +15 -3
- package/ps-license-manager.js +1 -1
- package/ps-pii-engine.cjs +1 -1
- package/scrubber-core.cjs +1 -1
- package/vercel-ai.cjs +400 -0
- package/vercel-ai.d.ts +156 -0
- package/vercel-ai.js +36 -0
- package/vision.cjs +13 -5
- package/vision.js +13 -5
package/fastmcp.cjs
CHANGED
|
@@ -26,6 +26,204 @@ const ZTDS_PATTERNS = {
|
|
|
26
26
|
|
|
27
27
|
const TOKEN_PATTERN = /\[([A-Z_]+)_TOKEN_([a-zA-Z0-9_-]+)\]/g;
|
|
28
28
|
|
|
29
|
+
function escapeRegex(s) {
|
|
30
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function buildStreamReplacer(tokenMap = {}, options = {}) {
|
|
34
|
+
if (!tokenMap || typeof tokenMap !== 'object' || Object.keys(tokenMap).length === 0) {
|
|
35
|
+
return (text) => text || '';
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const lookup = new Map();
|
|
39
|
+
const patterns = [];
|
|
40
|
+
const sortedKeys = Object.keys(tokenMap).sort((a, b) => b.length - a.length);
|
|
41
|
+
|
|
42
|
+
for (const k of sortedKeys) {
|
|
43
|
+
const val = tokenMap[k];
|
|
44
|
+
const inner = k.replace(/^\[|<|\{\{|__|\]|>|\}\}|__/g, '');
|
|
45
|
+
const match = inner.match(/^([A-Za-z_0-9]+?)[-_ ]?(\d+)$/);
|
|
46
|
+
|
|
47
|
+
if (match) {
|
|
48
|
+
const label = escapeRegex(match[1]);
|
|
49
|
+
const idx = match[2];
|
|
50
|
+
const patternStr = '(?:\\[\\s*' + label + '[-_\\s]*0*' + idx + '\\s*\\]|<\\s*' + label + '[-_\\s]*0*' + idx + '\\s*>|\\{\\{\\s*' + label + '[-_\\s]*0*' + idx + '\\s*\\}\\}|__\\s*' + label + '[-_\\s]*0*' + idx + '\\s*__|\\b' + label + '[-_\\s]+0*' + idx + '\\b)';
|
|
51
|
+
patterns.push(patternStr);
|
|
52
|
+
const normKey = (match[1] + '_' + parseInt(idx, 10)).toUpperCase();
|
|
53
|
+
lookup.set(normKey, val);
|
|
54
|
+
lookup.set(k, val);
|
|
55
|
+
lookup.set(k.toUpperCase(), val);
|
|
56
|
+
} else {
|
|
57
|
+
const safe = escapeRegex(k);
|
|
58
|
+
patterns.push(safe);
|
|
59
|
+
lookup.set(k, val);
|
|
60
|
+
lookup.set(k.toUpperCase(), val);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const unifiedRegex = new RegExp('(?:' + patterns.join('|') + ')(\'s|’s|s)?', 'gi');
|
|
65
|
+
|
|
66
|
+
return function replaceTokens(text) {
|
|
67
|
+
if (!text) return '';
|
|
68
|
+
unifiedRegex.lastIndex = 0;
|
|
69
|
+
return text.replace(unifiedRegex, (match, suffix) => {
|
|
70
|
+
const isPossessive = suffix && /('s|’s)$/i.test(suffix);
|
|
71
|
+
const coreMatch = suffix ? match.slice(0, match.length - suffix.length) : match;
|
|
72
|
+
let restored = null;
|
|
73
|
+
|
|
74
|
+
if (lookup.has(coreMatch)) {
|
|
75
|
+
restored = lookup.get(coreMatch);
|
|
76
|
+
} else if (lookup.has(coreMatch.toUpperCase())) {
|
|
77
|
+
restored = lookup.get(coreMatch.toUpperCase());
|
|
78
|
+
} else {
|
|
79
|
+
const inner = coreMatch.replace(/^\[|<|\{\{|__|\]|>|\}\}|__/g, '').trim();
|
|
80
|
+
const m = inner.match(/^([A-Za-z_0-9]+?)[-_ ]?(\d+)$/);
|
|
81
|
+
if (m) {
|
|
82
|
+
const normKey = (m[1] + '_' + parseInt(m[2], 10)).toUpperCase();
|
|
83
|
+
if (lookup.has(normKey)) {
|
|
84
|
+
restored = lookup.get(normKey);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (restored !== null) {
|
|
90
|
+
return restored + (isPossessive ? "'s" : '');
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (lookup.has(match)) {
|
|
94
|
+
return lookup.get(match);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return match;
|
|
98
|
+
});
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
class StreamingDetokenizer {
|
|
103
|
+
constructor(tokenMap = {}, options = {}) {
|
|
104
|
+
this.tokenMap = tokenMap && typeof tokenMap === 'object' ? tokenMap : {};
|
|
105
|
+
this.options = options || {};
|
|
106
|
+
this.replacer = buildStreamReplacer(this.tokenMap, this.options);
|
|
107
|
+
this.pendingBuffer = '';
|
|
108
|
+
this.hasTokens = Object.keys(this.tokenMap).length > 0;
|
|
109
|
+
this._lastTokenCount = Object.keys(this.tokenMap).length;
|
|
110
|
+
this.decoder = new TextDecoder('utf-8', { fatal: false });
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
get buffer() {
|
|
114
|
+
return this.pendingBuffer;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
set buffer(val) {
|
|
118
|
+
this.pendingBuffer = typeof val === 'string' ? val : '';
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
updateTokenMap(newMap) {
|
|
122
|
+
if (newMap && typeof newMap === 'object') {
|
|
123
|
+
this.tokenMap = newMap;
|
|
124
|
+
this.replacer = buildStreamReplacer(this.tokenMap, this.options);
|
|
125
|
+
this.hasTokens = Object.keys(this.tokenMap).length > 0;
|
|
126
|
+
this._lastTokenCount = Object.keys(this.tokenMap).length;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
reset() {
|
|
131
|
+
this.pendingBuffer = '';
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
feed(chunk) {
|
|
135
|
+
if (chunk === undefined || chunk === null) return '';
|
|
136
|
+
let text = '';
|
|
137
|
+
if (typeof chunk === 'string') {
|
|
138
|
+
text = chunk;
|
|
139
|
+
} else if (chunk instanceof Uint8Array || (typeof Buffer !== 'undefined' && Buffer.isBuffer(chunk))) {
|
|
140
|
+
text = this.decoder.decode(chunk, { stream: true });
|
|
141
|
+
} else {
|
|
142
|
+
text = String(chunk);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
if (!text) return '';
|
|
146
|
+
|
|
147
|
+
const currentTokenCount = Object.keys(this.tokenMap).length;
|
|
148
|
+
if (currentTokenCount !== this._lastTokenCount) {
|
|
149
|
+
this.replacer = buildStreamReplacer(this.tokenMap, this.options);
|
|
150
|
+
this.hasTokens = currentTokenCount > 0;
|
|
151
|
+
this._lastTokenCount = currentTokenCount;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
if (!this.hasTokens) return text;
|
|
155
|
+
|
|
156
|
+
this.pendingBuffer += text;
|
|
157
|
+
|
|
158
|
+
const tailLen = 160;
|
|
159
|
+
const tail = this.pendingBuffer.length > tailLen ? this.pendingBuffer.slice(-tailLen) : this.pendingBuffer;
|
|
160
|
+
const offset = this.pendingBuffer.length > tailLen ? this.pendingBuffer.length - tailLen : 0;
|
|
161
|
+
const m = tail.match(/(?:\[|<|\{\{?|__?)[A-Za-z0-9_\-А-Яа-яЁё ]{0,128}$/);
|
|
162
|
+
|
|
163
|
+
if (m) {
|
|
164
|
+
const candidate = m[0];
|
|
165
|
+
const isClosedUnderscoreToken = candidate.length >= 4 && candidate.startsWith('__') && candidate.endsWith('__');
|
|
166
|
+
if (isClosedUnderscoreToken && this.replacer(candidate) !== candidate) {
|
|
167
|
+
const toEmit = this.pendingBuffer;
|
|
168
|
+
this.pendingBuffer = '';
|
|
169
|
+
return this.replacer(toEmit);
|
|
170
|
+
}
|
|
171
|
+
const splitIdx = offset + m.index;
|
|
172
|
+
const safeToEmit = this.pendingBuffer.slice(0, splitIdx);
|
|
173
|
+
this.pendingBuffer = this.pendingBuffer.slice(splitIdx);
|
|
174
|
+
return safeToEmit ? this.replacer(safeToEmit) : '';
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
const toEmit = this.pendingBuffer;
|
|
178
|
+
this.pendingBuffer = '';
|
|
179
|
+
return this.replacer(toEmit);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
process(chunk) {
|
|
183
|
+
return this.feed(chunk);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
flush() {
|
|
187
|
+
let text = '';
|
|
188
|
+
try {
|
|
189
|
+
text = this.decoder.decode(new Uint8Array(), { stream: false });
|
|
190
|
+
} catch (_) {}
|
|
191
|
+
|
|
192
|
+
if (text) {
|
|
193
|
+
this.pendingBuffer += text;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
if (!this.pendingBuffer) return '';
|
|
197
|
+
const remaining = this.pendingBuffer;
|
|
198
|
+
this.pendingBuffer = '';
|
|
199
|
+
return this.replacer(remaining);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
async* wrapStream(asyncIterable) {
|
|
203
|
+
for await (const chunk of asyncIterable) {
|
|
204
|
+
if (chunk === null || chunk === undefined) continue;
|
|
205
|
+
let text = '';
|
|
206
|
+
if (typeof chunk === 'string') {
|
|
207
|
+
text = chunk;
|
|
208
|
+
} else if (typeof chunk?.text === 'string') {
|
|
209
|
+
text = chunk.text;
|
|
210
|
+
} else if (typeof chunk?.content === 'string') {
|
|
211
|
+
text = chunk.content;
|
|
212
|
+
} else if (chunk instanceof Uint8Array || (typeof Buffer !== 'undefined' && Buffer.isBuffer(chunk))) {
|
|
213
|
+
text = chunk;
|
|
214
|
+
} else {
|
|
215
|
+
text = String(chunk);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
const emitted = this.feed(text);
|
|
219
|
+
if (emitted) yield emitted;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
const finalChunk = this.flush();
|
|
223
|
+
if (finalChunk) yield finalChunk;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
29
227
|
class ZTDSFastMCPGuard {
|
|
30
228
|
constructor(options = {}) {
|
|
31
229
|
this.enabledEntities = options.enabledEntities || Object.keys(ZTDS_PATTERNS);
|
|
@@ -33,8 +231,10 @@ class ZTDSFastMCPGuard {
|
|
|
33
231
|
this.sanitizeOutputs = options.sanitizeOutputs !== false;
|
|
34
232
|
this.useCryptoTokens = options.useCryptoTokens !== false;
|
|
35
233
|
this.autoZeroize = options.autoZeroize !== false;
|
|
234
|
+
this.maxSessionTokens = options.maxSessionTokens || 5000;
|
|
36
235
|
this._sessionMaps = new Map();
|
|
37
236
|
this._entityMaps = new Map();
|
|
237
|
+
this._streamDetokenizers = new Map();
|
|
38
238
|
}
|
|
39
239
|
|
|
40
240
|
_generateToken(entityType, tokenMap) {
|
|
@@ -86,6 +286,14 @@ class ZTDSFastMCPGuard {
|
|
|
86
286
|
if (entityMap.has(match)) {
|
|
87
287
|
return entityMap.get(match);
|
|
88
288
|
}
|
|
289
|
+
if (tokenMap.size >= this.maxSessionTokens) {
|
|
290
|
+
const oldestToken = tokenMap.keys().next().value;
|
|
291
|
+
const oldestMatch = tokenMap.get(oldestToken);
|
|
292
|
+
tokenMap.delete(oldestToken);
|
|
293
|
+
if (oldestMatch && entityMap.has(oldestMatch)) {
|
|
294
|
+
entityMap.delete(oldestMatch);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
89
297
|
const token = this._generateToken(entityType, tokenMap);
|
|
90
298
|
tokenMap.set(token, match);
|
|
91
299
|
entityMap.set(match, token);
|
|
@@ -148,6 +356,65 @@ class ZTDSFastMCPGuard {
|
|
|
148
356
|
return val;
|
|
149
357
|
}
|
|
150
358
|
|
|
359
|
+
getStreamDetokenizer(sessionId) {
|
|
360
|
+
if (!this._streamDetokenizers.has(sessionId)) {
|
|
361
|
+
const mapProxy = this._sessionMaps.get(sessionId) || new Map();
|
|
362
|
+
const objMap = {};
|
|
363
|
+
for (const [k, v] of mapProxy.entries()) {
|
|
364
|
+
objMap[k] = v;
|
|
365
|
+
}
|
|
366
|
+
this._streamDetokenizers.set(sessionId, new StreamingDetokenizer(objMap));
|
|
367
|
+
} else {
|
|
368
|
+
const mapProxy = this._sessionMaps.get(sessionId);
|
|
369
|
+
if (mapProxy) {
|
|
370
|
+
const objMap = {};
|
|
371
|
+
for (const [k, v] of mapProxy.entries()) {
|
|
372
|
+
objMap[k] = v;
|
|
373
|
+
}
|
|
374
|
+
this._streamDetokenizers.get(sessionId).updateTokenMap(objMap);
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
return this._streamDetokenizers.get(sessionId);
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
feedStream(chunk, sessionId) {
|
|
381
|
+
return this.getStreamDetokenizer(sessionId).feed(chunk);
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
flushStream(sessionId) {
|
|
385
|
+
const detok = this._streamDetokenizers.get(sessionId);
|
|
386
|
+
return detok ? detok.flush() : "";
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
async *restoreStream(asyncIterable, sessionId) {
|
|
390
|
+
const detok = this.getStreamDetokenizer(sessionId);
|
|
391
|
+
try {
|
|
392
|
+
for await (const chunk of asyncIterable) {
|
|
393
|
+
if (chunk === null || chunk === undefined) continue;
|
|
394
|
+
let text = "";
|
|
395
|
+
if (typeof chunk === "string") {
|
|
396
|
+
text = chunk;
|
|
397
|
+
} else if (typeof chunk?.text === "string") {
|
|
398
|
+
text = chunk.text;
|
|
399
|
+
} else if (typeof chunk?.content === "string") {
|
|
400
|
+
text = chunk.content;
|
|
401
|
+
} else if (chunk instanceof Uint8Array || (typeof Buffer !== "undefined" && Buffer.isBuffer(chunk))) {
|
|
402
|
+
text = chunk;
|
|
403
|
+
} else {
|
|
404
|
+
text = String(chunk);
|
|
405
|
+
}
|
|
406
|
+
const emitted = detok.feed(text);
|
|
407
|
+
if (emitted) yield emitted;
|
|
408
|
+
}
|
|
409
|
+
const finalChunk = detok.flush();
|
|
410
|
+
if (finalChunk) yield finalChunk;
|
|
411
|
+
} finally {
|
|
412
|
+
if (this.autoZeroize) {
|
|
413
|
+
this.zeroizeSession(sessionId);
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
|
|
151
418
|
wrapTool(toolName, handler) {
|
|
152
419
|
return async (args, context = {}) => {
|
|
153
420
|
const sessionId =
|
|
@@ -160,6 +427,7 @@ class ZTDSFastMCPGuard {
|
|
|
160
427
|
unmask: (val) => this.restoreObject(val, sessionId),
|
|
161
428
|
};
|
|
162
429
|
|
|
430
|
+
let isStreaming = false;
|
|
163
431
|
try {
|
|
164
432
|
let processedArgs = args;
|
|
165
433
|
if (this.sanitizeInputs && args !== undefined && args !== null) {
|
|
@@ -168,6 +436,11 @@ class ZTDSFastMCPGuard {
|
|
|
168
436
|
|
|
169
437
|
const rawResult = await handler(processedArgs, enrichedContext);
|
|
170
438
|
|
|
439
|
+
if (rawResult && typeof rawResult[Symbol.asyncIterator] === "function") {
|
|
440
|
+
isStreaming = true;
|
|
441
|
+
return this.restoreStream(rawResult, sessionId);
|
|
442
|
+
}
|
|
443
|
+
|
|
171
444
|
let finalResult = rawResult;
|
|
172
445
|
if (this.sanitizeOutputs && rawResult !== undefined && rawResult !== null) {
|
|
173
446
|
if (typeof rawResult === "string") {
|
|
@@ -176,12 +449,22 @@ class ZTDSFastMCPGuard {
|
|
|
176
449
|
finalResult = {
|
|
177
450
|
...rawResult,
|
|
178
451
|
content: rawResult.content.map((block) => {
|
|
179
|
-
if (block
|
|
452
|
+
if (!block || typeof block !== "object") return block;
|
|
453
|
+
if (block.type === "text" && typeof block.text === "string") {
|
|
180
454
|
return {
|
|
181
455
|
...block,
|
|
182
456
|
text: this.sanitizeText(block.text, sessionId).sanitized,
|
|
183
457
|
};
|
|
184
458
|
}
|
|
459
|
+
if ((block.type === "resource" || block.type === "embeddedResource") && block.resource && typeof block.resource.text === "string") {
|
|
460
|
+
return {
|
|
461
|
+
...block,
|
|
462
|
+
resource: {
|
|
463
|
+
...block.resource,
|
|
464
|
+
text: this.sanitizeText(block.resource.text, sessionId).sanitized,
|
|
465
|
+
},
|
|
466
|
+
};
|
|
467
|
+
}
|
|
185
468
|
return block;
|
|
186
469
|
}),
|
|
187
470
|
};
|
|
@@ -215,7 +498,7 @@ class ZTDSFastMCPGuard {
|
|
|
215
498
|
_ztds: ztdsMeta,
|
|
216
499
|
};
|
|
217
500
|
} finally {
|
|
218
|
-
if (this.autoZeroize) {
|
|
501
|
+
if (!isStreaming && this.autoZeroize) {
|
|
219
502
|
this.zeroizeSession(sessionId);
|
|
220
503
|
}
|
|
221
504
|
}
|
|
@@ -231,6 +514,10 @@ class ZTDSFastMCPGuard {
|
|
|
231
514
|
this._entityMaps.get(sessionId).clear();
|
|
232
515
|
this._entityMaps.delete(sessionId);
|
|
233
516
|
}
|
|
517
|
+
if (this._streamDetokenizers.has(sessionId)) {
|
|
518
|
+
this._streamDetokenizers.get(sessionId).reset();
|
|
519
|
+
this._streamDetokenizers.delete(sessionId);
|
|
520
|
+
}
|
|
234
521
|
}
|
|
235
522
|
}
|
|
236
523
|
|
|
@@ -266,6 +553,8 @@ module.exports = {
|
|
|
266
553
|
ZTDSFastMCPGuard,
|
|
267
554
|
ZTDS_PATTERNS,
|
|
268
555
|
TOKEN_PATTERN,
|
|
556
|
+
StreamingDetokenizer,
|
|
557
|
+
createStreamTokenRestorer: (tokenMap, options) => new StreamingDetokenizer(tokenMap, options),
|
|
269
558
|
createZTDSGuard,
|
|
270
559
|
ztdsGuardTool,
|
|
271
560
|
wrapExecute,
|
package/fastmcp.d.ts
CHANGED
|
@@ -26,6 +26,19 @@ export interface ZTDSContext {
|
|
|
26
26
|
export declare const ZTDS_PATTERNS: Record<string, RegExp>;
|
|
27
27
|
export declare const TOKEN_PATTERN: RegExp;
|
|
28
28
|
|
|
29
|
+
export declare class StreamingDetokenizer {
|
|
30
|
+
constructor(tokenMap?: Record<string, string>, options?: object);
|
|
31
|
+
buffer: string;
|
|
32
|
+
feed(chunk: string | Uint8Array | Buffer): string;
|
|
33
|
+
process(chunk: string | Uint8Array | Buffer): string;
|
|
34
|
+
flush(): string;
|
|
35
|
+
reset(): void;
|
|
36
|
+
updateTokenMap(newMap: Record<string, string>): void;
|
|
37
|
+
wrapStream<T = any>(asyncIterable: AsyncIterable<T>): AsyncGenerator<T>;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export declare function createStreamTokenRestorer(tokenMap: Record<string, string>, options?: object): StreamingDetokenizer;
|
|
41
|
+
|
|
29
42
|
export declare class ZTDSFastMCPGuard {
|
|
30
43
|
constructor(options?: ZTDSGuardOptions);
|
|
31
44
|
enabledEntities: string[];
|
|
@@ -39,6 +52,11 @@ export declare class ZTDSFastMCPGuard {
|
|
|
39
52
|
sanitizeObject(val: unknown, sessionId: string): unknown;
|
|
40
53
|
restoreObject(val: unknown, sessionId: string): unknown;
|
|
41
54
|
|
|
55
|
+
getStreamDetokenizer(sessionId: string): StreamingDetokenizer;
|
|
56
|
+
feedStream(chunk: string, sessionId: string): string;
|
|
57
|
+
flushStream(sessionId: string): string;
|
|
58
|
+
restoreStream<T = any>(asyncIterable: AsyncIterable<T>, sessionId: string): AsyncGenerator<T>;
|
|
59
|
+
|
|
42
60
|
wrapTool<TArgs = unknown, TResult = unknown>(
|
|
43
61
|
toolName: string,
|
|
44
62
|
handler: (args: TArgs, context: ZTDSContext) => Promise<TResult>
|
package/fastmcp.js
CHANGED
|
@@ -11,6 +11,8 @@ const fastmcpGuard = require('./fastmcp.cjs');
|
|
|
11
11
|
export const ZTDSFastMCPGuard = fastmcpGuard.ZTDSFastMCPGuard;
|
|
12
12
|
export const ZTDS_PATTERNS = fastmcpGuard.ZTDS_PATTERNS;
|
|
13
13
|
export const TOKEN_PATTERN = fastmcpGuard.TOKEN_PATTERN;
|
|
14
|
+
export const StreamingDetokenizer = fastmcpGuard.StreamingDetokenizer;
|
|
15
|
+
export const createStreamTokenRestorer = fastmcpGuard.createStreamTokenRestorer;
|
|
14
16
|
export const createZTDSGuard = fastmcpGuard.createZTDSGuard;
|
|
15
17
|
export const ztdsGuardTool = fastmcpGuard.ztdsGuardTool;
|
|
16
18
|
export const wrapExecute = fastmcpGuard.wrapExecute;
|
|
@@ -20,6 +22,8 @@ export default {
|
|
|
20
22
|
ZTDSFastMCPGuard,
|
|
21
23
|
ZTDS_PATTERNS,
|
|
22
24
|
TOKEN_PATTERN,
|
|
25
|
+
StreamingDetokenizer,
|
|
26
|
+
createStreamTokenRestorer,
|
|
23
27
|
createZTDSGuard,
|
|
24
28
|
ztdsGuardTool,
|
|
25
29
|
wrapExecute,
|