gheim 0.1.5 → 0.1.7
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 +6 -2
- package/dist/cjs/index.cjs +49 -13
- package/dist/cjs/openai/index.cjs +48 -12
- package/dist/esm/index.js +49 -13
- package/dist/esm/openai/index.js +48 -12
- package/dist/types/core/session.d.ts.map +1 -1
- package/dist/types/detectors/calibrated.d.ts +29 -19
- package/dist/types/detectors/calibrated.d.ts.map +1 -1
- package/dist/types/detectors/index.d.ts +3 -3
- package/dist/types/detectors/index.d.ts.map +1 -1
- package/dist/types/detectors/local.d.ts +29 -2
- package/dist/types/detectors/local.d.ts.map +1 -1
- package/dist/types/index.d.ts +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -41,14 +41,15 @@ The core package itself has no runtime dependencies.
|
|
|
41
41
|
(transformers.js). The package's default model is
|
|
42
42
|
[`joelbarmettler/gheim-ch-560m`](https://huggingface.co/joelbarmettler/gheim-ch-560m)
|
|
43
43
|
— a 560M xlm-roberta-large fine-tune optimised for Swiss-market PII
|
|
44
|
-
(strict
|
|
44
|
+
(test strict F1 0.910, char F1 0.946 on Swiss text, see
|
|
45
45
|
[MODEL_CARD.md](https://github.com/joelbarmettlerUZH/gheim/blob/main/MODEL_CARD.md)).
|
|
46
46
|
Any HuggingFace token-classification model that emits the same 33-class
|
|
47
47
|
BIOES schema can be substituted via `model:`.
|
|
48
48
|
|
|
49
49
|
| Model | Best for | Parameters | Notes |
|
|
50
50
|
|---|---|---:|---|
|
|
51
|
-
| [`joelbarmettler/gheim-ch-560m`](https://huggingface.co/joelbarmettler/gheim-ch-560m) **(default)** | Swiss
|
|
51
|
+
| [`joelbarmettler/gheim-ch-560m`](https://huggingface.co/joelbarmettler/gheim-ch-560m) **(default)** | Production / commercial. Swiss court / parliament / web text with CH-format account numbers (IBAN, AHV, VAT-CHE) | 560M | Apache 2.0. Test strict F1 0.910, char F1 0.946. Hub repo ships both fp32 and `onnx/model_quantized.onnx` — load with `dtype: "q8"` for browser deployment. |
|
|
52
|
+
| [`joelbarmettler/gheim-ch-560m-research`](https://huggingface.co/joelbarmettler/gheim-ch-560m-research) | Research / non-commercial. Stronger cross-domain transfer on Swiss-news text (swissner PER char F1 0.90 vs 0.70 on the default) | 560M | **CC BY-NC-SA 4.0 + Reuters research-only rider.** safetensors only — no browser-targeted ONNX. |
|
|
52
53
|
| [`openai/privacy-filter`](https://huggingface.co/openai/privacy-filter) | English-first or general use, long-context (up to 128k tokens) | 1.4B (50M active, MoE) | Apache 2.0. Wider language coverage, larger weights. |
|
|
53
54
|
|
|
54
55
|
```ts
|
|
@@ -58,6 +59,9 @@ import { LocalDetector } from "gheim";
|
|
|
58
59
|
// the browser and falls back to WASM; in Node it's WASM directly.
|
|
59
60
|
const det = new LocalDetector({ dtype: "q8" });
|
|
60
61
|
|
|
62
|
+
// Stronger cross-domain transfer (research, non-commercial; safetensors only):
|
|
63
|
+
const detResearch = new LocalDetector({ model: "joelbarmettler/gheim-ch-560m-research" });
|
|
64
|
+
|
|
61
65
|
// Alternative for English or general use:
|
|
62
66
|
const detEn = new LocalDetector({ model: "openai/privacy-filter" });
|
|
63
67
|
```
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -157,8 +157,8 @@ class Session {
|
|
|
157
157
|
}
|
|
158
158
|
out.push(text.slice(cursor));
|
|
159
159
|
let redacted = out.join("");
|
|
160
|
-
|
|
161
|
-
return { redacted, merged };
|
|
160
|
+
const recovered = recoverDuplicateOccurrences(text, redacted, merged, this.mapping);
|
|
161
|
+
return { redacted: recovered.redacted, merged: recovered.merged };
|
|
162
162
|
}
|
|
163
163
|
restore(text) {
|
|
164
164
|
if (Object.keys(this.mapping).length === 0)
|
|
@@ -217,14 +217,36 @@ function mergeAdjacent(text, spans) {
|
|
|
217
217
|
function escapeRegex(s) {
|
|
218
218
|
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
219
219
|
}
|
|
220
|
-
function recoverDuplicateOccurrences(redacted, mapping) {
|
|
220
|
+
function recoverDuplicateOccurrences(text, redacted, merged, mapping) {
|
|
221
|
+
const surfaceToLabel = new Map;
|
|
222
|
+
for (const m of merged)
|
|
223
|
+
surfaceToLabel.set(text.slice(m.start, m.end), m.label);
|
|
224
|
+
const covered = merged.map((m) => [m.start, m.end]);
|
|
225
|
+
const overlaps = (s, e) => covered.some(([cs, ce]) => s < ce && e > cs);
|
|
221
226
|
const entries = Object.entries(mapping).filter(([, surface]) => surface && surface.length > 0).sort((a, b) => b[1].length - a[1].length);
|
|
222
227
|
let result = redacted;
|
|
228
|
+
const additional = [];
|
|
223
229
|
for (const [sentinel, surface] of entries) {
|
|
224
|
-
const
|
|
225
|
-
result = result.replace(
|
|
230
|
+
const boundaryPattern = `(?<![\\p{L}\\p{N}_])${escapeRegex(surface)}(?![\\p{L}\\p{N}_])`;
|
|
231
|
+
result = result.replace(new RegExp(boundaryPattern, "gu"), sentinel);
|
|
232
|
+
const label = surfaceToLabel.get(surface);
|
|
233
|
+
if (!label)
|
|
234
|
+
continue;
|
|
235
|
+
const origRe = new RegExp(boundaryPattern, "gu");
|
|
236
|
+
let match;
|
|
237
|
+
while ((match = origRe.exec(text)) !== null) {
|
|
238
|
+
const start = match.index;
|
|
239
|
+
const end = start + surface.length;
|
|
240
|
+
if (overlaps(start, end))
|
|
241
|
+
continue;
|
|
242
|
+
additional.push({ start, end, label });
|
|
243
|
+
covered.push([start, end]);
|
|
244
|
+
}
|
|
226
245
|
}
|
|
227
|
-
|
|
246
|
+
if (additional.length === 0)
|
|
247
|
+
return { redacted: result, merged };
|
|
248
|
+
const augmented = [...merged, ...additional].sort((a, b) => a.start - b.start);
|
|
249
|
+
return { redacted: result, merged: augmented };
|
|
228
250
|
}
|
|
229
251
|
// src/core/stream.ts
|
|
230
252
|
var SENTINEL_AT = /<([A-Z][A-Z0-9_]*)_(\d+)>/y;
|
|
@@ -369,13 +391,14 @@ class LocalDetector {
|
|
|
369
391
|
chunkOverlapTokens;
|
|
370
392
|
batchSize;
|
|
371
393
|
actualDevice = null;
|
|
394
|
+
actualDtype = null;
|
|
372
395
|
_pipeline = null;
|
|
373
396
|
_loadPromise = null;
|
|
374
397
|
_onProgress;
|
|
375
398
|
constructor(opts = {}) {
|
|
376
399
|
this.model = opts.model ?? DEFAULT_MODEL2;
|
|
377
400
|
this.device = opts.device ?? "auto";
|
|
378
|
-
this.dtype = opts.dtype ?? "
|
|
401
|
+
this.dtype = opts.dtype ?? "auto";
|
|
379
402
|
this.aggregationStrategy = opts.aggregationStrategy ?? "simple";
|
|
380
403
|
this.chunkTokens = opts.chunkTokens ?? DEFAULT_CHUNK_TOKENS;
|
|
381
404
|
this.chunkOverlapTokens = opts.chunkOverlapTokens ?? DEFAULT_OVERLAP_TOKENS;
|
|
@@ -387,8 +410,14 @@ class LocalDetector {
|
|
|
387
410
|
if (opts.pipelineInstance) {
|
|
388
411
|
this._pipeline = opts.pipelineInstance;
|
|
389
412
|
this.actualDevice = this.device === "auto" ? null : this.device;
|
|
413
|
+
this.actualDtype = this.dtype === "auto" ? null : this.dtype;
|
|
390
414
|
}
|
|
391
415
|
}
|
|
416
|
+
_resolveDtype(device) {
|
|
417
|
+
if (this.dtype !== "auto")
|
|
418
|
+
return this.dtype;
|
|
419
|
+
return device === "webgpu" ? "fp16" : "q8";
|
|
420
|
+
}
|
|
392
421
|
async load() {
|
|
393
422
|
if (this._pipeline)
|
|
394
423
|
return this._pipeline;
|
|
@@ -400,14 +429,16 @@ class LocalDetector {
|
|
|
400
429
|
let lastErr;
|
|
401
430
|
for (let i = 0;i < sequence.length; i++) {
|
|
402
431
|
const dev = sequence[i] ?? "wasm";
|
|
432
|
+
const resolvedDtype = this._resolveDtype(dev);
|
|
403
433
|
try {
|
|
404
434
|
const pipe = await mod.pipeline("token-classification", this.model, {
|
|
405
435
|
device: dev,
|
|
406
|
-
dtype:
|
|
436
|
+
dtype: resolvedDtype,
|
|
407
437
|
progress_callback: this._onProgress ? (raw) => this._emitProgress(raw, dev) : undefined
|
|
408
438
|
});
|
|
409
439
|
this._pipeline = pipe;
|
|
410
440
|
this.actualDevice = dev;
|
|
441
|
+
this.actualDtype = resolvedDtype;
|
|
411
442
|
return pipe;
|
|
412
443
|
} catch (e) {
|
|
413
444
|
lastErr = e;
|
|
@@ -423,6 +454,7 @@ class LocalDetector {
|
|
|
423
454
|
async _planDeviceSequence() {
|
|
424
455
|
if (this.device !== "auto")
|
|
425
456
|
return [this.device];
|
|
457
|
+
const isBrowser = typeof globalThis.window !== "undefined";
|
|
426
458
|
const seq = [];
|
|
427
459
|
const nav = typeof navigator !== "undefined" ? navigator : null;
|
|
428
460
|
if (nav?.gpu?.requestAdapter) {
|
|
@@ -432,7 +464,7 @@ class LocalDetector {
|
|
|
432
464
|
seq.push("webgpu");
|
|
433
465
|
} catch {}
|
|
434
466
|
}
|
|
435
|
-
seq.push("wasm");
|
|
467
|
+
seq.push(isBrowser ? "wasm" : "cpu");
|
|
436
468
|
return seq;
|
|
437
469
|
}
|
|
438
470
|
_emitProgress(raw, device) {
|
|
@@ -864,6 +896,7 @@ class CalibratedDetector {
|
|
|
864
896
|
chunkOverlapTokens;
|
|
865
897
|
trimWhitespace;
|
|
866
898
|
actualDevice = null;
|
|
899
|
+
actualDtype = null;
|
|
867
900
|
_model = null;
|
|
868
901
|
_tokenizer = null;
|
|
869
902
|
_id2label = {};
|
|
@@ -874,7 +907,7 @@ class CalibratedDetector {
|
|
|
874
907
|
this.model = opts.model ?? DEFAULT_MODEL3;
|
|
875
908
|
this.oBias = opts.oBias ?? 0.5;
|
|
876
909
|
this.device = opts.device ?? "auto";
|
|
877
|
-
this.dtype = opts.dtype ?? "
|
|
910
|
+
this.dtype = opts.dtype ?? "auto";
|
|
878
911
|
this.chunkTokens = opts.chunkTokens ?? DEFAULT_CHUNK_TOKENS2;
|
|
879
912
|
this.chunkOverlapTokens = opts.chunkOverlapTokens ?? DEFAULT_OVERLAP_TOKENS2;
|
|
880
913
|
this.trimWhitespace = opts.trimWhitespace ?? true;
|
|
@@ -892,8 +925,9 @@ class CalibratedDetector {
|
|
|
892
925
|
const mod = await loadTransformersJs2();
|
|
893
926
|
let preferredDevice = this.device;
|
|
894
927
|
if (this.device === "auto") {
|
|
928
|
+
const isBrowser = typeof globalThis.window !== "undefined";
|
|
895
929
|
const nav = typeof navigator !== "undefined" ? navigator : null;
|
|
896
|
-
preferredDevice = "wasm";
|
|
930
|
+
preferredDevice = isBrowser ? "wasm" : "cpu";
|
|
897
931
|
if (nav?.gpu?.requestAdapter) {
|
|
898
932
|
try {
|
|
899
933
|
const adapter = await nav.gpu.requestAdapter();
|
|
@@ -902,14 +936,16 @@ class CalibratedDetector {
|
|
|
902
936
|
} catch {}
|
|
903
937
|
}
|
|
904
938
|
}
|
|
939
|
+
const resolvedDtype = this.dtype === "auto" ? preferredDevice === "webgpu" ? "fp16" : "q8" : this.dtype;
|
|
905
940
|
const tokenizer = await mod.AutoTokenizer.from_pretrained(this.model);
|
|
906
941
|
const model = await mod.AutoModelForTokenClassification.from_pretrained(this.model, {
|
|
907
942
|
device: preferredDevice,
|
|
908
|
-
dtype:
|
|
943
|
+
dtype: resolvedDtype,
|
|
909
944
|
progress_callback: this._onProgress ? (raw) => this._emitProgress(raw, preferredDevice) : undefined
|
|
910
945
|
});
|
|
911
946
|
this._tokenizer = tokenizer;
|
|
912
947
|
this._model = model;
|
|
948
|
+
this.actualDtype = resolvedDtype;
|
|
913
949
|
this._id2label = model.config.id2label;
|
|
914
950
|
const label2id = model.config.label2id;
|
|
915
951
|
this._oId = label2id?.["O"] ?? 0;
|
|
@@ -1168,4 +1204,4 @@ async function* deanonymizeStream(chunks, session) {
|
|
|
1168
1204
|
}
|
|
1169
1205
|
|
|
1170
1206
|
// src/index.ts
|
|
1171
|
-
var VERSION = "0.1.
|
|
1207
|
+
var VERSION = "0.1.6";
|
|
@@ -277,13 +277,14 @@ class LocalDetector {
|
|
|
277
277
|
chunkOverlapTokens;
|
|
278
278
|
batchSize;
|
|
279
279
|
actualDevice = null;
|
|
280
|
+
actualDtype = null;
|
|
280
281
|
_pipeline = null;
|
|
281
282
|
_loadPromise = null;
|
|
282
283
|
_onProgress;
|
|
283
284
|
constructor(opts = {}) {
|
|
284
285
|
this.model = opts.model ?? DEFAULT_MODEL2;
|
|
285
286
|
this.device = opts.device ?? "auto";
|
|
286
|
-
this.dtype = opts.dtype ?? "
|
|
287
|
+
this.dtype = opts.dtype ?? "auto";
|
|
287
288
|
this.aggregationStrategy = opts.aggregationStrategy ?? "simple";
|
|
288
289
|
this.chunkTokens = opts.chunkTokens ?? DEFAULT_CHUNK_TOKENS;
|
|
289
290
|
this.chunkOverlapTokens = opts.chunkOverlapTokens ?? DEFAULT_OVERLAP_TOKENS;
|
|
@@ -295,8 +296,14 @@ class LocalDetector {
|
|
|
295
296
|
if (opts.pipelineInstance) {
|
|
296
297
|
this._pipeline = opts.pipelineInstance;
|
|
297
298
|
this.actualDevice = this.device === "auto" ? null : this.device;
|
|
299
|
+
this.actualDtype = this.dtype === "auto" ? null : this.dtype;
|
|
298
300
|
}
|
|
299
301
|
}
|
|
302
|
+
_resolveDtype(device) {
|
|
303
|
+
if (this.dtype !== "auto")
|
|
304
|
+
return this.dtype;
|
|
305
|
+
return device === "webgpu" ? "fp16" : "q8";
|
|
306
|
+
}
|
|
300
307
|
async load() {
|
|
301
308
|
if (this._pipeline)
|
|
302
309
|
return this._pipeline;
|
|
@@ -308,14 +315,16 @@ class LocalDetector {
|
|
|
308
315
|
let lastErr;
|
|
309
316
|
for (let i = 0;i < sequence.length; i++) {
|
|
310
317
|
const dev = sequence[i] ?? "wasm";
|
|
318
|
+
const resolvedDtype = this._resolveDtype(dev);
|
|
311
319
|
try {
|
|
312
320
|
const pipe = await mod.pipeline("token-classification", this.model, {
|
|
313
321
|
device: dev,
|
|
314
|
-
dtype:
|
|
322
|
+
dtype: resolvedDtype,
|
|
315
323
|
progress_callback: this._onProgress ? (raw) => this._emitProgress(raw, dev) : undefined
|
|
316
324
|
});
|
|
317
325
|
this._pipeline = pipe;
|
|
318
326
|
this.actualDevice = dev;
|
|
327
|
+
this.actualDtype = resolvedDtype;
|
|
319
328
|
return pipe;
|
|
320
329
|
} catch (e) {
|
|
321
330
|
lastErr = e;
|
|
@@ -331,6 +340,7 @@ class LocalDetector {
|
|
|
331
340
|
async _planDeviceSequence() {
|
|
332
341
|
if (this.device !== "auto")
|
|
333
342
|
return [this.device];
|
|
343
|
+
const isBrowser = typeof globalThis.window !== "undefined";
|
|
334
344
|
const seq = [];
|
|
335
345
|
const nav = typeof navigator !== "undefined" ? navigator : null;
|
|
336
346
|
if (nav?.gpu?.requestAdapter) {
|
|
@@ -340,7 +350,7 @@ class LocalDetector {
|
|
|
340
350
|
seq.push("webgpu");
|
|
341
351
|
} catch {}
|
|
342
352
|
}
|
|
343
|
-
seq.push("wasm");
|
|
353
|
+
seq.push(isBrowser ? "wasm" : "cpu");
|
|
344
354
|
return seq;
|
|
345
355
|
}
|
|
346
356
|
_emitProgress(raw, device) {
|
|
@@ -772,6 +782,7 @@ class CalibratedDetector {
|
|
|
772
782
|
chunkOverlapTokens;
|
|
773
783
|
trimWhitespace;
|
|
774
784
|
actualDevice = null;
|
|
785
|
+
actualDtype = null;
|
|
775
786
|
_model = null;
|
|
776
787
|
_tokenizer = null;
|
|
777
788
|
_id2label = {};
|
|
@@ -782,7 +793,7 @@ class CalibratedDetector {
|
|
|
782
793
|
this.model = opts.model ?? DEFAULT_MODEL3;
|
|
783
794
|
this.oBias = opts.oBias ?? 0.5;
|
|
784
795
|
this.device = opts.device ?? "auto";
|
|
785
|
-
this.dtype = opts.dtype ?? "
|
|
796
|
+
this.dtype = opts.dtype ?? "auto";
|
|
786
797
|
this.chunkTokens = opts.chunkTokens ?? DEFAULT_CHUNK_TOKENS2;
|
|
787
798
|
this.chunkOverlapTokens = opts.chunkOverlapTokens ?? DEFAULT_OVERLAP_TOKENS2;
|
|
788
799
|
this.trimWhitespace = opts.trimWhitespace ?? true;
|
|
@@ -800,8 +811,9 @@ class CalibratedDetector {
|
|
|
800
811
|
const mod = await loadTransformersJs2();
|
|
801
812
|
let preferredDevice = this.device;
|
|
802
813
|
if (this.device === "auto") {
|
|
814
|
+
const isBrowser = typeof globalThis.window !== "undefined";
|
|
803
815
|
const nav = typeof navigator !== "undefined" ? navigator : null;
|
|
804
|
-
preferredDevice = "wasm";
|
|
816
|
+
preferredDevice = isBrowser ? "wasm" : "cpu";
|
|
805
817
|
if (nav?.gpu?.requestAdapter) {
|
|
806
818
|
try {
|
|
807
819
|
const adapter = await nav.gpu.requestAdapter();
|
|
@@ -810,14 +822,16 @@ class CalibratedDetector {
|
|
|
810
822
|
} catch {}
|
|
811
823
|
}
|
|
812
824
|
}
|
|
825
|
+
const resolvedDtype = this.dtype === "auto" ? preferredDevice === "webgpu" ? "fp16" : "q8" : this.dtype;
|
|
813
826
|
const tokenizer = await mod.AutoTokenizer.from_pretrained(this.model);
|
|
814
827
|
const model = await mod.AutoModelForTokenClassification.from_pretrained(this.model, {
|
|
815
828
|
device: preferredDevice,
|
|
816
|
-
dtype:
|
|
829
|
+
dtype: resolvedDtype,
|
|
817
830
|
progress_callback: this._onProgress ? (raw) => this._emitProgress(raw, preferredDevice) : undefined
|
|
818
831
|
});
|
|
819
832
|
this._tokenizer = tokenizer;
|
|
820
833
|
this._model = model;
|
|
834
|
+
this.actualDtype = resolvedDtype;
|
|
821
835
|
this._id2label = model.config.id2label;
|
|
822
836
|
const label2id = model.config.label2id;
|
|
823
837
|
this._oId = label2id?.["O"] ?? 0;
|
|
@@ -1086,8 +1100,8 @@ class Session {
|
|
|
1086
1100
|
}
|
|
1087
1101
|
out.push(text.slice(cursor));
|
|
1088
1102
|
let redacted = out.join("");
|
|
1089
|
-
|
|
1090
|
-
return { redacted, merged };
|
|
1103
|
+
const recovered = recoverDuplicateOccurrences(text, redacted, merged, this.mapping);
|
|
1104
|
+
return { redacted: recovered.redacted, merged: recovered.merged };
|
|
1091
1105
|
}
|
|
1092
1106
|
restore(text) {
|
|
1093
1107
|
if (Object.keys(this.mapping).length === 0)
|
|
@@ -1146,14 +1160,36 @@ function mergeAdjacent(text, spans) {
|
|
|
1146
1160
|
function escapeRegex(s) {
|
|
1147
1161
|
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
1148
1162
|
}
|
|
1149
|
-
function recoverDuplicateOccurrences(redacted, mapping) {
|
|
1163
|
+
function recoverDuplicateOccurrences(text, redacted, merged, mapping) {
|
|
1164
|
+
const surfaceToLabel = new Map;
|
|
1165
|
+
for (const m of merged)
|
|
1166
|
+
surfaceToLabel.set(text.slice(m.start, m.end), m.label);
|
|
1167
|
+
const covered = merged.map((m) => [m.start, m.end]);
|
|
1168
|
+
const overlaps = (s, e) => covered.some(([cs, ce]) => s < ce && e > cs);
|
|
1150
1169
|
const entries = Object.entries(mapping).filter(([, surface]) => surface && surface.length > 0).sort((a, b) => b[1].length - a[1].length);
|
|
1151
1170
|
let result = redacted;
|
|
1171
|
+
const additional = [];
|
|
1152
1172
|
for (const [sentinel, surface] of entries) {
|
|
1153
|
-
const
|
|
1154
|
-
result = result.replace(
|
|
1173
|
+
const boundaryPattern = `(?<![\\p{L}\\p{N}_])${escapeRegex(surface)}(?![\\p{L}\\p{N}_])`;
|
|
1174
|
+
result = result.replace(new RegExp(boundaryPattern, "gu"), sentinel);
|
|
1175
|
+
const label = surfaceToLabel.get(surface);
|
|
1176
|
+
if (!label)
|
|
1177
|
+
continue;
|
|
1178
|
+
const origRe = new RegExp(boundaryPattern, "gu");
|
|
1179
|
+
let match;
|
|
1180
|
+
while ((match = origRe.exec(text)) !== null) {
|
|
1181
|
+
const start = match.index;
|
|
1182
|
+
const end = start + surface.length;
|
|
1183
|
+
if (overlaps(start, end))
|
|
1184
|
+
continue;
|
|
1185
|
+
additional.push({ start, end, label });
|
|
1186
|
+
covered.push([start, end]);
|
|
1187
|
+
}
|
|
1155
1188
|
}
|
|
1156
|
-
|
|
1189
|
+
if (additional.length === 0)
|
|
1190
|
+
return { redacted: result, merged };
|
|
1191
|
+
const augmented = [...merged, ...additional].sort((a, b) => a.start - b.start);
|
|
1192
|
+
return { redacted: result, merged: augmented };
|
|
1157
1193
|
}
|
|
1158
1194
|
|
|
1159
1195
|
// src/openai/_base.ts
|
package/dist/esm/index.js
CHANGED
|
@@ -100,8 +100,8 @@ class Session {
|
|
|
100
100
|
}
|
|
101
101
|
out.push(text.slice(cursor));
|
|
102
102
|
let redacted = out.join("");
|
|
103
|
-
|
|
104
|
-
return { redacted, merged };
|
|
103
|
+
const recovered = recoverDuplicateOccurrences(text, redacted, merged, this.mapping);
|
|
104
|
+
return { redacted: recovered.redacted, merged: recovered.merged };
|
|
105
105
|
}
|
|
106
106
|
restore(text) {
|
|
107
107
|
if (Object.keys(this.mapping).length === 0)
|
|
@@ -160,14 +160,36 @@ function mergeAdjacent(text, spans) {
|
|
|
160
160
|
function escapeRegex(s) {
|
|
161
161
|
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
162
162
|
}
|
|
163
|
-
function recoverDuplicateOccurrences(redacted, mapping) {
|
|
163
|
+
function recoverDuplicateOccurrences(text, redacted, merged, mapping) {
|
|
164
|
+
const surfaceToLabel = new Map;
|
|
165
|
+
for (const m of merged)
|
|
166
|
+
surfaceToLabel.set(text.slice(m.start, m.end), m.label);
|
|
167
|
+
const covered = merged.map((m) => [m.start, m.end]);
|
|
168
|
+
const overlaps = (s, e) => covered.some(([cs, ce]) => s < ce && e > cs);
|
|
164
169
|
const entries = Object.entries(mapping).filter(([, surface]) => surface && surface.length > 0).sort((a, b) => b[1].length - a[1].length);
|
|
165
170
|
let result = redacted;
|
|
171
|
+
const additional = [];
|
|
166
172
|
for (const [sentinel, surface] of entries) {
|
|
167
|
-
const
|
|
168
|
-
result = result.replace(
|
|
173
|
+
const boundaryPattern = `(?<![\\p{L}\\p{N}_])${escapeRegex(surface)}(?![\\p{L}\\p{N}_])`;
|
|
174
|
+
result = result.replace(new RegExp(boundaryPattern, "gu"), sentinel);
|
|
175
|
+
const label = surfaceToLabel.get(surface);
|
|
176
|
+
if (!label)
|
|
177
|
+
continue;
|
|
178
|
+
const origRe = new RegExp(boundaryPattern, "gu");
|
|
179
|
+
let match;
|
|
180
|
+
while ((match = origRe.exec(text)) !== null) {
|
|
181
|
+
const start = match.index;
|
|
182
|
+
const end = start + surface.length;
|
|
183
|
+
if (overlaps(start, end))
|
|
184
|
+
continue;
|
|
185
|
+
additional.push({ start, end, label });
|
|
186
|
+
covered.push([start, end]);
|
|
187
|
+
}
|
|
169
188
|
}
|
|
170
|
-
|
|
189
|
+
if (additional.length === 0)
|
|
190
|
+
return { redacted: result, merged };
|
|
191
|
+
const augmented = [...merged, ...additional].sort((a, b) => a.start - b.start);
|
|
192
|
+
return { redacted: result, merged: augmented };
|
|
171
193
|
}
|
|
172
194
|
// src/core/stream.ts
|
|
173
195
|
var SENTINEL_AT = /<([A-Z][A-Z0-9_]*)_(\d+)>/y;
|
|
@@ -312,13 +334,14 @@ class LocalDetector {
|
|
|
312
334
|
chunkOverlapTokens;
|
|
313
335
|
batchSize;
|
|
314
336
|
actualDevice = null;
|
|
337
|
+
actualDtype = null;
|
|
315
338
|
_pipeline = null;
|
|
316
339
|
_loadPromise = null;
|
|
317
340
|
_onProgress;
|
|
318
341
|
constructor(opts = {}) {
|
|
319
342
|
this.model = opts.model ?? DEFAULT_MODEL2;
|
|
320
343
|
this.device = opts.device ?? "auto";
|
|
321
|
-
this.dtype = opts.dtype ?? "
|
|
344
|
+
this.dtype = opts.dtype ?? "auto";
|
|
322
345
|
this.aggregationStrategy = opts.aggregationStrategy ?? "simple";
|
|
323
346
|
this.chunkTokens = opts.chunkTokens ?? DEFAULT_CHUNK_TOKENS;
|
|
324
347
|
this.chunkOverlapTokens = opts.chunkOverlapTokens ?? DEFAULT_OVERLAP_TOKENS;
|
|
@@ -330,8 +353,14 @@ class LocalDetector {
|
|
|
330
353
|
if (opts.pipelineInstance) {
|
|
331
354
|
this._pipeline = opts.pipelineInstance;
|
|
332
355
|
this.actualDevice = this.device === "auto" ? null : this.device;
|
|
356
|
+
this.actualDtype = this.dtype === "auto" ? null : this.dtype;
|
|
333
357
|
}
|
|
334
358
|
}
|
|
359
|
+
_resolveDtype(device) {
|
|
360
|
+
if (this.dtype !== "auto")
|
|
361
|
+
return this.dtype;
|
|
362
|
+
return device === "webgpu" ? "fp16" : "q8";
|
|
363
|
+
}
|
|
335
364
|
async load() {
|
|
336
365
|
if (this._pipeline)
|
|
337
366
|
return this._pipeline;
|
|
@@ -343,14 +372,16 @@ class LocalDetector {
|
|
|
343
372
|
let lastErr;
|
|
344
373
|
for (let i = 0;i < sequence.length; i++) {
|
|
345
374
|
const dev = sequence[i] ?? "wasm";
|
|
375
|
+
const resolvedDtype = this._resolveDtype(dev);
|
|
346
376
|
try {
|
|
347
377
|
const pipe = await mod.pipeline("token-classification", this.model, {
|
|
348
378
|
device: dev,
|
|
349
|
-
dtype:
|
|
379
|
+
dtype: resolvedDtype,
|
|
350
380
|
progress_callback: this._onProgress ? (raw) => this._emitProgress(raw, dev) : undefined
|
|
351
381
|
});
|
|
352
382
|
this._pipeline = pipe;
|
|
353
383
|
this.actualDevice = dev;
|
|
384
|
+
this.actualDtype = resolvedDtype;
|
|
354
385
|
return pipe;
|
|
355
386
|
} catch (e) {
|
|
356
387
|
lastErr = e;
|
|
@@ -366,6 +397,7 @@ class LocalDetector {
|
|
|
366
397
|
async _planDeviceSequence() {
|
|
367
398
|
if (this.device !== "auto")
|
|
368
399
|
return [this.device];
|
|
400
|
+
const isBrowser = typeof globalThis.window !== "undefined";
|
|
369
401
|
const seq = [];
|
|
370
402
|
const nav = typeof navigator !== "undefined" ? navigator : null;
|
|
371
403
|
if (nav?.gpu?.requestAdapter) {
|
|
@@ -375,7 +407,7 @@ class LocalDetector {
|
|
|
375
407
|
seq.push("webgpu");
|
|
376
408
|
} catch {}
|
|
377
409
|
}
|
|
378
|
-
seq.push("wasm");
|
|
410
|
+
seq.push(isBrowser ? "wasm" : "cpu");
|
|
379
411
|
return seq;
|
|
380
412
|
}
|
|
381
413
|
_emitProgress(raw, device) {
|
|
@@ -807,6 +839,7 @@ class CalibratedDetector {
|
|
|
807
839
|
chunkOverlapTokens;
|
|
808
840
|
trimWhitespace;
|
|
809
841
|
actualDevice = null;
|
|
842
|
+
actualDtype = null;
|
|
810
843
|
_model = null;
|
|
811
844
|
_tokenizer = null;
|
|
812
845
|
_id2label = {};
|
|
@@ -817,7 +850,7 @@ class CalibratedDetector {
|
|
|
817
850
|
this.model = opts.model ?? DEFAULT_MODEL3;
|
|
818
851
|
this.oBias = opts.oBias ?? 0.5;
|
|
819
852
|
this.device = opts.device ?? "auto";
|
|
820
|
-
this.dtype = opts.dtype ?? "
|
|
853
|
+
this.dtype = opts.dtype ?? "auto";
|
|
821
854
|
this.chunkTokens = opts.chunkTokens ?? DEFAULT_CHUNK_TOKENS2;
|
|
822
855
|
this.chunkOverlapTokens = opts.chunkOverlapTokens ?? DEFAULT_OVERLAP_TOKENS2;
|
|
823
856
|
this.trimWhitespace = opts.trimWhitespace ?? true;
|
|
@@ -835,8 +868,9 @@ class CalibratedDetector {
|
|
|
835
868
|
const mod = await loadTransformersJs2();
|
|
836
869
|
let preferredDevice = this.device;
|
|
837
870
|
if (this.device === "auto") {
|
|
871
|
+
const isBrowser = typeof globalThis.window !== "undefined";
|
|
838
872
|
const nav = typeof navigator !== "undefined" ? navigator : null;
|
|
839
|
-
preferredDevice = "wasm";
|
|
873
|
+
preferredDevice = isBrowser ? "wasm" : "cpu";
|
|
840
874
|
if (nav?.gpu?.requestAdapter) {
|
|
841
875
|
try {
|
|
842
876
|
const adapter = await nav.gpu.requestAdapter();
|
|
@@ -845,14 +879,16 @@ class CalibratedDetector {
|
|
|
845
879
|
} catch {}
|
|
846
880
|
}
|
|
847
881
|
}
|
|
882
|
+
const resolvedDtype = this.dtype === "auto" ? preferredDevice === "webgpu" ? "fp16" : "q8" : this.dtype;
|
|
848
883
|
const tokenizer = await mod.AutoTokenizer.from_pretrained(this.model);
|
|
849
884
|
const model = await mod.AutoModelForTokenClassification.from_pretrained(this.model, {
|
|
850
885
|
device: preferredDevice,
|
|
851
|
-
dtype:
|
|
886
|
+
dtype: resolvedDtype,
|
|
852
887
|
progress_callback: this._onProgress ? (raw) => this._emitProgress(raw, preferredDevice) : undefined
|
|
853
888
|
});
|
|
854
889
|
this._tokenizer = tokenizer;
|
|
855
890
|
this._model = model;
|
|
891
|
+
this.actualDtype = resolvedDtype;
|
|
856
892
|
this._id2label = model.config.id2label;
|
|
857
893
|
const label2id = model.config.label2id;
|
|
858
894
|
this._oId = label2id?.["O"] ?? 0;
|
|
@@ -1111,7 +1147,7 @@ async function* deanonymizeStream(chunks, session) {
|
|
|
1111
1147
|
}
|
|
1112
1148
|
|
|
1113
1149
|
// src/index.ts
|
|
1114
|
-
var VERSION = "0.1.
|
|
1150
|
+
var VERSION = "0.1.6";
|
|
1115
1151
|
export {
|
|
1116
1152
|
renderSentinel,
|
|
1117
1153
|
parseSentinel,
|
package/dist/esm/openai/index.js
CHANGED
|
@@ -234,13 +234,14 @@ class LocalDetector {
|
|
|
234
234
|
chunkOverlapTokens;
|
|
235
235
|
batchSize;
|
|
236
236
|
actualDevice = null;
|
|
237
|
+
actualDtype = null;
|
|
237
238
|
_pipeline = null;
|
|
238
239
|
_loadPromise = null;
|
|
239
240
|
_onProgress;
|
|
240
241
|
constructor(opts = {}) {
|
|
241
242
|
this.model = opts.model ?? DEFAULT_MODEL2;
|
|
242
243
|
this.device = opts.device ?? "auto";
|
|
243
|
-
this.dtype = opts.dtype ?? "
|
|
244
|
+
this.dtype = opts.dtype ?? "auto";
|
|
244
245
|
this.aggregationStrategy = opts.aggregationStrategy ?? "simple";
|
|
245
246
|
this.chunkTokens = opts.chunkTokens ?? DEFAULT_CHUNK_TOKENS;
|
|
246
247
|
this.chunkOverlapTokens = opts.chunkOverlapTokens ?? DEFAULT_OVERLAP_TOKENS;
|
|
@@ -252,8 +253,14 @@ class LocalDetector {
|
|
|
252
253
|
if (opts.pipelineInstance) {
|
|
253
254
|
this._pipeline = opts.pipelineInstance;
|
|
254
255
|
this.actualDevice = this.device === "auto" ? null : this.device;
|
|
256
|
+
this.actualDtype = this.dtype === "auto" ? null : this.dtype;
|
|
255
257
|
}
|
|
256
258
|
}
|
|
259
|
+
_resolveDtype(device) {
|
|
260
|
+
if (this.dtype !== "auto")
|
|
261
|
+
return this.dtype;
|
|
262
|
+
return device === "webgpu" ? "fp16" : "q8";
|
|
263
|
+
}
|
|
257
264
|
async load() {
|
|
258
265
|
if (this._pipeline)
|
|
259
266
|
return this._pipeline;
|
|
@@ -265,14 +272,16 @@ class LocalDetector {
|
|
|
265
272
|
let lastErr;
|
|
266
273
|
for (let i = 0;i < sequence.length; i++) {
|
|
267
274
|
const dev = sequence[i] ?? "wasm";
|
|
275
|
+
const resolvedDtype = this._resolveDtype(dev);
|
|
268
276
|
try {
|
|
269
277
|
const pipe = await mod.pipeline("token-classification", this.model, {
|
|
270
278
|
device: dev,
|
|
271
|
-
dtype:
|
|
279
|
+
dtype: resolvedDtype,
|
|
272
280
|
progress_callback: this._onProgress ? (raw) => this._emitProgress(raw, dev) : undefined
|
|
273
281
|
});
|
|
274
282
|
this._pipeline = pipe;
|
|
275
283
|
this.actualDevice = dev;
|
|
284
|
+
this.actualDtype = resolvedDtype;
|
|
276
285
|
return pipe;
|
|
277
286
|
} catch (e) {
|
|
278
287
|
lastErr = e;
|
|
@@ -288,6 +297,7 @@ class LocalDetector {
|
|
|
288
297
|
async _planDeviceSequence() {
|
|
289
298
|
if (this.device !== "auto")
|
|
290
299
|
return [this.device];
|
|
300
|
+
const isBrowser = typeof globalThis.window !== "undefined";
|
|
291
301
|
const seq = [];
|
|
292
302
|
const nav = typeof navigator !== "undefined" ? navigator : null;
|
|
293
303
|
if (nav?.gpu?.requestAdapter) {
|
|
@@ -297,7 +307,7 @@ class LocalDetector {
|
|
|
297
307
|
seq.push("webgpu");
|
|
298
308
|
} catch {}
|
|
299
309
|
}
|
|
300
|
-
seq.push("wasm");
|
|
310
|
+
seq.push(isBrowser ? "wasm" : "cpu");
|
|
301
311
|
return seq;
|
|
302
312
|
}
|
|
303
313
|
_emitProgress(raw, device) {
|
|
@@ -729,6 +739,7 @@ class CalibratedDetector {
|
|
|
729
739
|
chunkOverlapTokens;
|
|
730
740
|
trimWhitespace;
|
|
731
741
|
actualDevice = null;
|
|
742
|
+
actualDtype = null;
|
|
732
743
|
_model = null;
|
|
733
744
|
_tokenizer = null;
|
|
734
745
|
_id2label = {};
|
|
@@ -739,7 +750,7 @@ class CalibratedDetector {
|
|
|
739
750
|
this.model = opts.model ?? DEFAULT_MODEL3;
|
|
740
751
|
this.oBias = opts.oBias ?? 0.5;
|
|
741
752
|
this.device = opts.device ?? "auto";
|
|
742
|
-
this.dtype = opts.dtype ?? "
|
|
753
|
+
this.dtype = opts.dtype ?? "auto";
|
|
743
754
|
this.chunkTokens = opts.chunkTokens ?? DEFAULT_CHUNK_TOKENS2;
|
|
744
755
|
this.chunkOverlapTokens = opts.chunkOverlapTokens ?? DEFAULT_OVERLAP_TOKENS2;
|
|
745
756
|
this.trimWhitespace = opts.trimWhitespace ?? true;
|
|
@@ -757,8 +768,9 @@ class CalibratedDetector {
|
|
|
757
768
|
const mod = await loadTransformersJs2();
|
|
758
769
|
let preferredDevice = this.device;
|
|
759
770
|
if (this.device === "auto") {
|
|
771
|
+
const isBrowser = typeof globalThis.window !== "undefined";
|
|
760
772
|
const nav = typeof navigator !== "undefined" ? navigator : null;
|
|
761
|
-
preferredDevice = "wasm";
|
|
773
|
+
preferredDevice = isBrowser ? "wasm" : "cpu";
|
|
762
774
|
if (nav?.gpu?.requestAdapter) {
|
|
763
775
|
try {
|
|
764
776
|
const adapter = await nav.gpu.requestAdapter();
|
|
@@ -767,14 +779,16 @@ class CalibratedDetector {
|
|
|
767
779
|
} catch {}
|
|
768
780
|
}
|
|
769
781
|
}
|
|
782
|
+
const resolvedDtype = this.dtype === "auto" ? preferredDevice === "webgpu" ? "fp16" : "q8" : this.dtype;
|
|
770
783
|
const tokenizer = await mod.AutoTokenizer.from_pretrained(this.model);
|
|
771
784
|
const model = await mod.AutoModelForTokenClassification.from_pretrained(this.model, {
|
|
772
785
|
device: preferredDevice,
|
|
773
|
-
dtype:
|
|
786
|
+
dtype: resolvedDtype,
|
|
774
787
|
progress_callback: this._onProgress ? (raw) => this._emitProgress(raw, preferredDevice) : undefined
|
|
775
788
|
});
|
|
776
789
|
this._tokenizer = tokenizer;
|
|
777
790
|
this._model = model;
|
|
791
|
+
this.actualDtype = resolvedDtype;
|
|
778
792
|
this._id2label = model.config.id2label;
|
|
779
793
|
const label2id = model.config.label2id;
|
|
780
794
|
this._oId = label2id?.["O"] ?? 0;
|
|
@@ -1043,8 +1057,8 @@ class Session {
|
|
|
1043
1057
|
}
|
|
1044
1058
|
out.push(text.slice(cursor));
|
|
1045
1059
|
let redacted = out.join("");
|
|
1046
|
-
|
|
1047
|
-
return { redacted, merged };
|
|
1060
|
+
const recovered = recoverDuplicateOccurrences(text, redacted, merged, this.mapping);
|
|
1061
|
+
return { redacted: recovered.redacted, merged: recovered.merged };
|
|
1048
1062
|
}
|
|
1049
1063
|
restore(text) {
|
|
1050
1064
|
if (Object.keys(this.mapping).length === 0)
|
|
@@ -1103,14 +1117,36 @@ function mergeAdjacent(text, spans) {
|
|
|
1103
1117
|
function escapeRegex(s) {
|
|
1104
1118
|
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
1105
1119
|
}
|
|
1106
|
-
function recoverDuplicateOccurrences(redacted, mapping) {
|
|
1120
|
+
function recoverDuplicateOccurrences(text, redacted, merged, mapping) {
|
|
1121
|
+
const surfaceToLabel = new Map;
|
|
1122
|
+
for (const m of merged)
|
|
1123
|
+
surfaceToLabel.set(text.slice(m.start, m.end), m.label);
|
|
1124
|
+
const covered = merged.map((m) => [m.start, m.end]);
|
|
1125
|
+
const overlaps = (s, e) => covered.some(([cs, ce]) => s < ce && e > cs);
|
|
1107
1126
|
const entries = Object.entries(mapping).filter(([, surface]) => surface && surface.length > 0).sort((a, b) => b[1].length - a[1].length);
|
|
1108
1127
|
let result = redacted;
|
|
1128
|
+
const additional = [];
|
|
1109
1129
|
for (const [sentinel, surface] of entries) {
|
|
1110
|
-
const
|
|
1111
|
-
result = result.replace(
|
|
1130
|
+
const boundaryPattern = `(?<![\\p{L}\\p{N}_])${escapeRegex(surface)}(?![\\p{L}\\p{N}_])`;
|
|
1131
|
+
result = result.replace(new RegExp(boundaryPattern, "gu"), sentinel);
|
|
1132
|
+
const label = surfaceToLabel.get(surface);
|
|
1133
|
+
if (!label)
|
|
1134
|
+
continue;
|
|
1135
|
+
const origRe = new RegExp(boundaryPattern, "gu");
|
|
1136
|
+
let match;
|
|
1137
|
+
while ((match = origRe.exec(text)) !== null) {
|
|
1138
|
+
const start = match.index;
|
|
1139
|
+
const end = start + surface.length;
|
|
1140
|
+
if (overlaps(start, end))
|
|
1141
|
+
continue;
|
|
1142
|
+
additional.push({ start, end, label });
|
|
1143
|
+
covered.push([start, end]);
|
|
1144
|
+
}
|
|
1112
1145
|
}
|
|
1113
|
-
|
|
1146
|
+
if (additional.length === 0)
|
|
1147
|
+
return { redacted: result, merged };
|
|
1148
|
+
const augmented = [...merged, ...additional].sort((a, b) => a.start - b.start);
|
|
1149
|
+
return { redacted: result, merged: augmented };
|
|
1114
1150
|
}
|
|
1115
1151
|
|
|
1116
1152
|
// src/openai/_base.ts
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../../src/core/session.ts"],"names":[],"mappings":"AAAA,kDAAkD;AAClD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAGjD;;;gEAGgE;AAChE,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;AAkBtD,uCAAuC;AACvC,MAAM,WAAW,cAAc;IAC7B;;;;;;;;;;OAUG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;CAC1C;AAED,qBAAa,OAAO;IAClB,8DAA8D;IAC9D,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAM;IACrC,OAAO,CAAC,QAAQ,CAAkC;IAClD,OAAO,CAAC,QAAQ,CAAkC;IAClD,OAAO,CAAC,mBAAmB,CAAkC;gBAEjD,IAAI,GAAE,cAAmB;IAQrC,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM;IAiBhD,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,CAAC,IAAI,GAAG,UAAU,CAAC,EAAE,GAAG,MAAM;IAIvE;;;;;;;OAOG;IACH,kBAAkB,CAChB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,SAAS,CAAC,IAAI,GAAG,UAAU,CAAC,EAAE,GACpC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,UAAU,EAAE,CAAA;KAAE;
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../../src/core/session.ts"],"names":[],"mappings":"AAAA,kDAAkD;AAClD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAGjD;;;gEAGgE;AAChE,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;AAkBtD,uCAAuC;AACvC,MAAM,WAAW,cAAc;IAC7B;;;;;;;;;;OAUG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;CAC1C;AAED,qBAAa,OAAO;IAClB,8DAA8D;IAC9D,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAM;IACrC,OAAO,CAAC,QAAQ,CAAkC;IAClD,OAAO,CAAC,QAAQ,CAAkC;IAClD,OAAO,CAAC,mBAAmB,CAAkC;gBAEjD,IAAI,GAAE,cAAmB;IAQrC,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM;IAiBhD,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,CAAC,IAAI,GAAG,UAAU,CAAC,EAAE,GAAG,MAAM;IAIvE;;;;;;;OAOG;IACH,kBAAkB,CAChB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,SAAS,CAAC,IAAI,GAAG,UAAU,CAAC,EAAE,GACpC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,UAAU,EAAE,CAAA;KAAE;IA8B7C,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAK7B,MAAM,IAAI;QAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE;IAI7C,MAAM,CAAC,QAAQ,CACb,GAAG,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE,EACxC,IAAI,GAAE,cAAmB,GACxB,OAAO;CAqBX;AAID,8EAA8E;AAC9E,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,SAAS,CAAC,IAAI,GAAG,UAAU,CAAC,EAAE,GACpC,UAAU,EAAE,CAqBd"}
|
|
@@ -1,19 +1,27 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Calibrated detector —
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* Calibrated detector — subtracts a constant `oBias` from the O-class
|
|
3
|
+
* logit before argmax. Originally introduced to recover the v1 model's
|
|
4
|
+
* "single-category mode" pathology (Müller + IBAN co-occurrence flipped
|
|
5
|
+
* the person prediction to O); the v3 / gheim-ch-560m training pipeline
|
|
6
|
+
* largely resolved that pathology, but the calibration still buys a
|
|
7
|
+
* small precision/recall improvement and remains the default.
|
|
5
8
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* additive bias on O flips those marginal cases without inducing false
|
|
11
|
-
* positives on PII-free text.
|
|
9
|
+
* Sweep on gheim-ch-560m (see eval/calibration_sweep.json):
|
|
10
|
+
* `oBias=0.5` is the Pareto-clean default — probe perfect-rate is flat
|
|
11
|
+
* at 91.5% across bias 0.0 and 0.5, and test char-F1 lifts by 0.27pp.
|
|
12
|
+
* Higher biases (1.0–1.5) trade test F1 for marginal probe gains.
|
|
12
13
|
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
14
|
+
* A separate sweep on the int8 ONNX path via `transformers.js`
|
|
15
|
+
* (eval/calibration_sweep_q8.json) showed a much larger calibration
|
|
16
|
+
* effect (+1.4pp probe, +0.43pp char-F1 at 0.5). That gap is not a
|
|
17
|
+
* property of the int8 quantisation — Python `onnxruntime` on the same
|
|
18
|
+
* int8 file gives 91.0% probe perfect-rate, essentially fp32-equivalent
|
|
19
|
+
* — but of a runtime divergence inside `onnxruntime-web` / WASM that
|
|
20
|
+
* the calibration partially papers over. The reliable fix is to use the
|
|
21
|
+
* `model_fp16.onnx` variant when WebGPU is available (which is what
|
|
22
|
+
* LocalDetector's default `dtype: "auto"` does); int8 should be treated
|
|
23
|
+
* as a low-RAM fallback. See eval/q8_quality_report.md for the
|
|
24
|
+
* diagnostic.
|
|
17
25
|
*
|
|
18
26
|
* `defaultDetector()` returns this with oBias=0.5, so users get the
|
|
19
27
|
* better behavior automatically.
|
|
@@ -26,14 +34,13 @@ export interface CalibratedDetectorOptions {
|
|
|
26
34
|
model?: string;
|
|
27
35
|
/**
|
|
28
36
|
* Constant subtracted from the O-class logit before argmax. Default
|
|
29
|
-
* `0.5` is the Pareto-clean point
|
|
30
|
-
* (eval/calibration_sweep.json):
|
|
37
|
+
* `0.5` is the Pareto-clean point on the reference (fp32/fp16) path:
|
|
31
38
|
*
|
|
32
39
|
* - oBias=0.0 uncalibrated (matches the raw model)
|
|
33
|
-
* - oBias=0.5
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
40
|
+
* - oBias=0.5 +0.27pp test char-F1, no probe cost (91.5% perfect)
|
|
41
|
+
* - oBias=1.0+ marginal probe gains, test F1 starts to fall off
|
|
42
|
+
*
|
|
43
|
+
* See eval/calibration_sweep.json.
|
|
37
44
|
*/
|
|
38
45
|
oBias?: number;
|
|
39
46
|
/** Backend selector. See {@link LocalDetectorOptions.device}. */
|
|
@@ -60,6 +67,9 @@ export declare class CalibratedDetector implements Detector {
|
|
|
60
67
|
readonly trimWhitespace: boolean;
|
|
61
68
|
/** Backend actually used after `load()` resolves; `null` before. */
|
|
62
69
|
actualDevice: string | null;
|
|
70
|
+
/** Dtype actually used after `load()` resolves; `null` before. Differs
|
|
71
|
+
* from {@link dtype} only when `dtype: "auto"` was requested. */
|
|
72
|
+
actualDtype: string | null;
|
|
63
73
|
private _model;
|
|
64
74
|
private _tokenizer;
|
|
65
75
|
private _id2label;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"calibrated.d.ts","sourceRoot":"","sources":["../../../src/detectors/calibrated.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"calibrated.d.ts","sourceRoot":"","sources":["../../../src/detectors/calibrated.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAChD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAMzD,0DAA0D;AAC1D,MAAM,WAAW,yBAAyB;IACxC,kEAAkE;IAClE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;;;;;OASG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iEAAiE;IACjE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,kEAAkE;IAClE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,yDAAyD;IACzD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,wDAAwD;IACxD,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,8EAA8E;IAC9E,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,4EAA4E;IAC5E,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,sBAAsB,KAAK,IAAI,CAAC;CACtD;AA4CD,uDAAuD;AACvD,qBAAa,kBAAmB,YAAW,QAAQ;IACjD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;IACjC,oEAAoE;IACpE,YAAY,EAAE,MAAM,GAAG,IAAI,CAAQ;IACnC;sEACkE;IAClE,WAAW,EAAE,MAAM,GAAG,IAAI,CAAQ;IAClC,OAAO,CAAC,MAAM,CAA8B;IAC5C,OAAO,CAAC,UAAU,CAAkC;IACpD,OAAO,CAAC,SAAS,CAA8B;IAC/C,OAAO,CAAC,IAAI,CAAK;IACjB,OAAO,CAAC,YAAY,CAA8B;IAClD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,CAA0C;gBAE3D,IAAI,GAAE,yBAA8B;IAiB1C,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAoDrB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;YAYxD,cAAc;YA0Bd,aAAa;IA6F3B,OAAO,CAAC,aAAa;CAiBtB"}
|
|
@@ -11,8 +11,8 @@ import type { Detector } from "./base.ts";
|
|
|
11
11
|
/** Pick a reasonable default: remote when `GHEIM_API_KEY` is set in env,
|
|
12
12
|
* else a calibrated local model.
|
|
13
13
|
*
|
|
14
|
-
* The calibrated default (`oBias=0.5`)
|
|
15
|
-
*
|
|
16
|
-
*
|
|
14
|
+
* The calibrated default (`oBias=0.5`) is Pareto-clean on gheim-ch-560m:
|
|
15
|
+
* +0.27pp test char-F1 with no probe cost (91.5% perfect at both 0.0
|
|
16
|
+
* and 0.5). See eval/calibration_sweep.json. */
|
|
17
17
|
export declare function defaultDetector(): Detector;
|
|
18
18
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/detectors/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAChD,OAAO,EACL,gBAAgB,EAChB,aAAa,IAAI,oBAAoB,EACrC,cAAc,GACf,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,YAAY,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAC/E,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,YAAY,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACrD,YAAY,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AAEjE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAI1C;;;;;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/detectors/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAChD,OAAO,EACL,gBAAgB,EAChB,aAAa,IAAI,oBAAoB,EACrC,cAAc,GACf,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,YAAY,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAC/E,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,YAAY,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACrD,YAAY,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AAEjE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAI1C;;;;;iDAKiD;AACjD,wBAAgB,eAAe,IAAI,QAAQ,CAI1C"}
|
|
@@ -29,7 +29,15 @@ export interface LocalDetectorOptions {
|
|
|
29
29
|
* (no probe, no fallback — your choice is respected and may throw).
|
|
30
30
|
*/
|
|
31
31
|
device?: string;
|
|
32
|
-
/**
|
|
32
|
+
/**
|
|
33
|
+
* Quantization dtype: `"fp32" | "fp16" | "q8" | "q4" | "auto"`. Defaults
|
|
34
|
+
* to `"auto"`, which picks based on the resolved backend: `"fp16"` when
|
|
35
|
+
* WebGPU was selected (large but byte-equivalent to fp32 on the forensic
|
|
36
|
+
* probe), `"q8"` otherwise (~550 MB; safe everywhere, but degrades on
|
|
37
|
+
* the `onnxruntime-web` WASM kernel on Swiss edge cases — see
|
|
38
|
+
* eval/q8_quality_report.md). Set explicitly to opt out of this
|
|
39
|
+
* trade-off.
|
|
40
|
+
*/
|
|
33
41
|
dtype?: string;
|
|
34
42
|
/** Aggregation strategy passed to the pipeline call. */
|
|
35
43
|
aggregationStrategy?: string;
|
|
@@ -98,10 +106,21 @@ export declare class LocalDetector implements Detector {
|
|
|
98
106
|
* the model is loaded. Different from {@link device} only when
|
|
99
107
|
* `device: "auto"` was requested. */
|
|
100
108
|
actualDevice: string | null;
|
|
109
|
+
/** Dtype that ended up being used after `load()` resolves. `null` until
|
|
110
|
+
* the model is loaded. Different from {@link dtype} only when
|
|
111
|
+
* `dtype: "auto"` was requested — in that case it resolves to `"fp16"`
|
|
112
|
+
* on WebGPU and `"q8"` everywhere else. */
|
|
113
|
+
actualDtype: string | null;
|
|
101
114
|
private _pipeline;
|
|
102
115
|
private _loadPromise;
|
|
103
116
|
private readonly _onProgress?;
|
|
104
117
|
constructor(opts?: LocalDetectorOptions);
|
|
118
|
+
/** Resolve `dtype: "auto"` for a concrete device: fp16 on WebGPU (byte-
|
|
119
|
+
* equivalent to fp32 on the forensic probe), q8 on WASM/CPU. The
|
|
120
|
+
* WASM-q8 path is known to degrade on Swiss edge cases via
|
|
121
|
+
* `onnxruntime-web`, but it's the small-file fallback for low-RAM
|
|
122
|
+
* contexts where WebGPU isn't available. Explicit dtype passes through. */
|
|
123
|
+
private _resolveDtype;
|
|
105
124
|
/**
|
|
106
125
|
* Load the model. Idempotent; concurrent calls share a single load.
|
|
107
126
|
* With `device: "auto"`, probes `navigator.gpu.requestAdapter()` and
|
|
@@ -109,7 +128,15 @@ export declare class LocalDetector implements Detector {
|
|
|
109
128
|
* if construction throws (and reporting both attempts via `onProgress`).
|
|
110
129
|
*/
|
|
111
130
|
load(): Promise<PipelineCallable>;
|
|
112
|
-
/** Build the ordered list of backends to attempt.
|
|
131
|
+
/** Build the ordered list of backends to attempt.
|
|
132
|
+
*
|
|
133
|
+
* In a browser we try WebGPU (if a real adapter is reachable) and fall
|
|
134
|
+
* back to WASM. In Node, transformers.js uses onnxruntime-node, which
|
|
135
|
+
* speaks "cpu" / "cuda" / "webgpu" — never "wasm" — so the fallback
|
|
136
|
+
* has to be "cpu" instead. We detect "browser-ness" via `typeof window`;
|
|
137
|
+
* Node 21+ now ships a global `navigator`, so that's no longer a
|
|
138
|
+
* reliable discriminator on its own.
|
|
139
|
+
*/
|
|
113
140
|
private _planDeviceSequence;
|
|
114
141
|
/** Translate a raw transformers.js progress callback into our normalized event. */
|
|
115
142
|
private _emitProgress;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"local.d.ts","sourceRoot":"","sources":["../../../src/detectors/local.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEhD,eAAO,MAAM,aAAa,iCAAiC,CAAC;AAQ5D,0EAA0E;AAC1E,MAAM,WAAW,oBAAoB;IACnC,mEAAmE;IACnE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;;;;;OASG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB
|
|
1
|
+
{"version":3,"file":"local.d.ts","sourceRoot":"","sources":["../../../src/detectors/local.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEhD,eAAO,MAAM,aAAa,iCAAiC,CAAC;AAQ5D,0EAA0E;AAC1E,MAAM,WAAW,oBAAoB;IACnC,mEAAmE;IACnE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;;;;;OASG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;;;;OAQG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wDAAwD;IACxD,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,+EAA+E;IAC/E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,6DAA6D;IAC7D,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B;;;;;OAKG;IACH,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,sBAAsB,KAAK,IAAI,CAAC;CACtD;AAED,uFAAuF;AACvF,MAAM,WAAW,sBAAsB;IACrC,yBAAyB;IACzB,KAAK,EAAE,UAAU,GAAG,UAAU,GAAG,UAAU,GAAG,OAAO,GAAG,MAAM,CAAC;IAC/D,6CAA6C;IAC7C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,6DAA6D;IAC7D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,4DAA4D;IAC5D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;wEACoE;IACpE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;+EAE2E;IAC3E,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,UAAU,aAAa;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,KAAK,gBAAgB,GAAG,CACtB,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,EACvB,IAAI,CAAC,EAAE;IAAE,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,KAC1D,OAAO,CAAC,aAAa,EAAE,GAAG,aAAa,EAAE,EAAE,CAAC,CAAC;AAwBlD,qBAAa,aAAc,YAAW,QAAQ;IAC5C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,kFAAkF;IAClF,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAC;IACrC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B;;0CAEsC;IACtC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAQ;IACnC;;;gDAG4C;IAC5C,WAAW,EAAE,MAAM,GAAG,IAAI,CAAQ;IAClC,OAAO,CAAC,SAAS,CAAiC;IAClD,OAAO,CAAC,YAAY,CAA0C;IAC9D,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,CAA0C;gBAE3D,IAAI,GAAE,oBAAyB;IAuB3C;;;;gFAI4E;IAC5E,OAAO,CAAC,aAAa;IAKrB;;;;;OAKG;IACG,IAAI,IAAI,OAAO,CAAC,gBAAgB,CAAC;IAoCvC;;;;;;;;OAQG;YACW,mBAAmB;IAsBjC,mFAAmF;IACnF,OAAO,CAAC,aAAa;IAqBf,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;IAYtE;;;;;OAKG;IACG,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,IAAI,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;YAyFlE,SAAS;CAkBxB"}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -17,7 +17,7 @@ export { DEFAULT_BASE_URL, REMOTE_DEFAULT_MODEL, RemoteDetector, LocalDetector,
|
|
|
17
17
|
export type { RemoteDetectorOptions, LocalDetectorOptions, LocalDetectorLoadEvent, CompositeDetectorOptions, CalibratedDetectorOptions, } from "./detectors/index.ts";
|
|
18
18
|
export { anonymizeMessages, anonymizeText, deanonymizeStream, deanonymizeText, } from "./plain.ts";
|
|
19
19
|
export type { ChatMessage } from "./plain.ts";
|
|
20
|
-
export declare const VERSION = "0.1.
|
|
20
|
+
export declare const VERSION = "0.1.6";
|
|
21
21
|
export { mergeAdjacent } from "./core/session.ts";
|
|
22
22
|
export type { MergedSpan } from "./core/session.ts";
|
|
23
23
|
//# sourceMappingURL=index.d.ts.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gheim",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.7",
|
|
4
4
|
"description": "PII round-trip for LLM APIs: anonymize before the request, de-anonymize the stream on the way back.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Joel Barmettler <joel.barmettler@gmail.com>",
|