@framers/agentos 0.1.55 → 0.1.56
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/extensions/ExtensionManager.d.ts +1 -0
- package/dist/extensions/ExtensionManager.d.ts.map +1 -1
- package/dist/extensions/ExtensionManager.js +8 -0
- package/dist/extensions/ExtensionManager.js.map +1 -1
- package/dist/extensions/ISharedServiceRegistry.d.ts +35 -0
- package/dist/extensions/ISharedServiceRegistry.d.ts.map +1 -0
- package/dist/extensions/ISharedServiceRegistry.js +2 -0
- package/dist/extensions/ISharedServiceRegistry.js.map +1 -0
- package/dist/extensions/SharedServiceRegistry.d.ts +15 -0
- package/dist/extensions/SharedServiceRegistry.d.ts.map +1 -0
- package/dist/extensions/SharedServiceRegistry.js +63 -0
- package/dist/extensions/SharedServiceRegistry.js.map +1 -0
- package/dist/extensions/index.d.ts +3 -0
- package/dist/extensions/index.d.ts.map +1 -1
- package/dist/extensions/index.js +4 -0
- package/dist/extensions/index.js.map +1 -1
- package/dist/extensions/manifest.d.ts +2 -0
- package/dist/extensions/manifest.d.ts.map +1 -1
- package/dist/extensions/packs/pii-redaction/EntityMerger.d.ts +127 -0
- package/dist/extensions/packs/pii-redaction/EntityMerger.d.ts.map +1 -0
- package/dist/extensions/packs/pii-redaction/EntityMerger.js +263 -0
- package/dist/extensions/packs/pii-redaction/EntityMerger.js.map +1 -0
- package/dist/extensions/packs/pii-redaction/PiiDetectionPipeline.d.ts +199 -0
- package/dist/extensions/packs/pii-redaction/PiiDetectionPipeline.d.ts.map +1 -0
- package/dist/extensions/packs/pii-redaction/PiiDetectionPipeline.js +456 -0
- package/dist/extensions/packs/pii-redaction/PiiDetectionPipeline.js.map +1 -0
- package/dist/extensions/packs/pii-redaction/PiiRedactionGuardrail.d.ts +121 -0
- package/dist/extensions/packs/pii-redaction/PiiRedactionGuardrail.d.ts.map +1 -0
- package/dist/extensions/packs/pii-redaction/PiiRedactionGuardrail.js +271 -0
- package/dist/extensions/packs/pii-redaction/PiiRedactionGuardrail.js.map +1 -0
- package/dist/extensions/packs/pii-redaction/RedactionEngine.d.ts +61 -0
- package/dist/extensions/packs/pii-redaction/RedactionEngine.d.ts.map +1 -0
- package/dist/extensions/packs/pii-redaction/RedactionEngine.js +207 -0
- package/dist/extensions/packs/pii-redaction/RedactionEngine.js.map +1 -0
- package/dist/extensions/packs/pii-redaction/index.d.ts +90 -0
- package/dist/extensions/packs/pii-redaction/index.d.ts.map +1 -0
- package/dist/extensions/packs/pii-redaction/index.js +195 -0
- package/dist/extensions/packs/pii-redaction/index.js.map +1 -0
- package/dist/extensions/packs/pii-redaction/recognizers/IEntityRecognizer.d.ts +151 -0
- package/dist/extensions/packs/pii-redaction/recognizers/IEntityRecognizer.d.ts.map +1 -0
- package/dist/extensions/packs/pii-redaction/recognizers/IEntityRecognizer.js +14 -0
- package/dist/extensions/packs/pii-redaction/recognizers/IEntityRecognizer.js.map +1 -0
- package/dist/extensions/packs/pii-redaction/recognizers/LlmJudgeRecognizer.d.ts +177 -0
- package/dist/extensions/packs/pii-redaction/recognizers/LlmJudgeRecognizer.d.ts.map +1 -0
- package/dist/extensions/packs/pii-redaction/recognizers/LlmJudgeRecognizer.js +420 -0
- package/dist/extensions/packs/pii-redaction/recognizers/LlmJudgeRecognizer.js.map +1 -0
- package/dist/extensions/packs/pii-redaction/recognizers/NerModelRecognizer.d.ts +145 -0
- package/dist/extensions/packs/pii-redaction/recognizers/NerModelRecognizer.d.ts.map +1 -0
- package/dist/extensions/packs/pii-redaction/recognizers/NerModelRecognizer.js +299 -0
- package/dist/extensions/packs/pii-redaction/recognizers/NerModelRecognizer.js.map +1 -0
- package/dist/extensions/packs/pii-redaction/recognizers/NlpPrefilterRecognizer.d.ts +102 -0
- package/dist/extensions/packs/pii-redaction/recognizers/NlpPrefilterRecognizer.d.ts.map +1 -0
- package/dist/extensions/packs/pii-redaction/recognizers/NlpPrefilterRecognizer.js +228 -0
- package/dist/extensions/packs/pii-redaction/recognizers/NlpPrefilterRecognizer.js.map +1 -0
- package/dist/extensions/packs/pii-redaction/recognizers/RegexRecognizer.d.ts +103 -0
- package/dist/extensions/packs/pii-redaction/recognizers/RegexRecognizer.d.ts.map +1 -0
- package/dist/extensions/packs/pii-redaction/recognizers/RegexRecognizer.js +275 -0
- package/dist/extensions/packs/pii-redaction/recognizers/RegexRecognizer.js.map +1 -0
- package/dist/extensions/packs/pii-redaction/tools/PiiRedactTool.d.ts +118 -0
- package/dist/extensions/packs/pii-redaction/tools/PiiRedactTool.d.ts.map +1 -0
- package/dist/extensions/packs/pii-redaction/tools/PiiRedactTool.js +152 -0
- package/dist/extensions/packs/pii-redaction/tools/PiiRedactTool.js.map +1 -0
- package/dist/extensions/packs/pii-redaction/tools/PiiScanTool.d.ts +98 -0
- package/dist/extensions/packs/pii-redaction/tools/PiiScanTool.d.ts.map +1 -0
- package/dist/extensions/packs/pii-redaction/tools/PiiScanTool.js +153 -0
- package/dist/extensions/packs/pii-redaction/tools/PiiScanTool.js.map +1 -0
- package/dist/extensions/packs/pii-redaction/types.d.ts +332 -0
- package/dist/extensions/packs/pii-redaction/types.d.ts.map +1 -0
- package/dist/extensions/packs/pii-redaction/types.js +83 -0
- package/dist/extensions/packs/pii-redaction/types.js.map +1 -0
- package/dist/extensions/types.d.ts +5 -0
- package/dist/extensions/types.d.ts.map +1 -1
- package/dist/extensions/types.js.map +1 -1
- package/package.json +11 -1
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file RegexRecognizer.ts
|
|
3
|
+
* @description Tier 1 PII recogniser that delegates pattern matching to the
|
|
4
|
+
* `openredaction` library.
|
|
5
|
+
*
|
|
6
|
+
* OpenRedaction ships with 500+ curated regex patterns covering emails, SSNs,
|
|
7
|
+
* credit cards, phone numbers, IP addresses, IBANs, passports, API keys, and
|
|
8
|
+
* many more. This recogniser wraps its `OpenRedaction.detect()` method,
|
|
9
|
+
* normalises the results into the pipeline's {@link PiiEntity} shape, and
|
|
10
|
+
* applies entity-type filtering so only the categories requested by the caller
|
|
11
|
+
* are evaluated.
|
|
12
|
+
*
|
|
13
|
+
* @module pii-redaction/recognizers
|
|
14
|
+
*/
|
|
15
|
+
import type { PiiEntity, PiiEntityType } from '../types';
|
|
16
|
+
import type { IEntityRecognizer, RecognizeOptions } from './IEntityRecognizer';
|
|
17
|
+
/**
|
|
18
|
+
* Tier 1 entity recogniser backed by the `openredaction` library.
|
|
19
|
+
*
|
|
20
|
+
* ### How it works
|
|
21
|
+
* 1. On construction an {@link OpenRedaction} instance is created with the
|
|
22
|
+
* full set of mapped patterns pre-loaded and pre-compiled.
|
|
23
|
+
* 2. When {@link recognize} is called, pattern names are optionally filtered
|
|
24
|
+
* to the requested {@link PiiEntityType} subset.
|
|
25
|
+
* 3. `OpenRedaction.detect()` runs all active patterns against the input and
|
|
26
|
+
* returns raw detections with position offsets.
|
|
27
|
+
* 4. Results are mapped to {@link PiiEntity} objects with a fixed high score
|
|
28
|
+
* (>= 0.85) because regex matches are deterministic.
|
|
29
|
+
*
|
|
30
|
+
* ### Thread safety
|
|
31
|
+
* Each call to `recognize` creates a fresh `OpenRedaction` instance with
|
|
32
|
+
* only the needed patterns so there is no shared mutable state between
|
|
33
|
+
* concurrent invocations.
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```ts
|
|
37
|
+
* const recognizer = new RegexRecognizer();
|
|
38
|
+
* const entities = await recognizer.recognize(
|
|
39
|
+
* 'Email me at alice@example.com',
|
|
40
|
+
* { entityTypes: ['EMAIL'] },
|
|
41
|
+
* );
|
|
42
|
+
* // entities[0].entityType === 'EMAIL'
|
|
43
|
+
* // entities[0].score >= 0.85
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
export declare class RegexRecognizer implements IEntityRecognizer {
|
|
47
|
+
/** @inheritdoc */
|
|
48
|
+
readonly name = "RegexRecognizer";
|
|
49
|
+
/** @inheritdoc */
|
|
50
|
+
readonly supportedEntities: PiiEntityType[];
|
|
51
|
+
/**
|
|
52
|
+
* Minimum confidence score assigned to regex-based detections.
|
|
53
|
+
* Regex matches are deterministic so they receive a high baseline; the
|
|
54
|
+
* openredaction library may report its own `confidence` which we bump
|
|
55
|
+
* to at least this floor value.
|
|
56
|
+
*/
|
|
57
|
+
private static readonly MIN_SCORE;
|
|
58
|
+
/**
|
|
59
|
+
* Lazily-resolved reference to the `OpenRedaction` constructor from the
|
|
60
|
+
* `openredaction` package. Stored after first successful dynamic import
|
|
61
|
+
* to avoid repeated module resolution on subsequent calls.
|
|
62
|
+
*/
|
|
63
|
+
private OpenRedactionCtor;
|
|
64
|
+
/**
|
|
65
|
+
* Scan the input text for PII entities using openredaction regex patterns.
|
|
66
|
+
*
|
|
67
|
+
* @param input - Raw text to analyse.
|
|
68
|
+
* @param options - Optional filtering and context hints.
|
|
69
|
+
* @returns Array of detected {@link PiiEntity} objects, possibly empty.
|
|
70
|
+
*/
|
|
71
|
+
recognize(input: string, options?: RecognizeOptions): Promise<PiiEntity[]>;
|
|
72
|
+
/** @inheritdoc */
|
|
73
|
+
dispose(): Promise<void>;
|
|
74
|
+
/**
|
|
75
|
+
* Lazily imports the `openredaction` module and caches its constructor.
|
|
76
|
+
*
|
|
77
|
+
* @returns The `OpenRedaction` class constructor.
|
|
78
|
+
* @throws If the `openredaction` package is not installed.
|
|
79
|
+
*/
|
|
80
|
+
private ensureOpenRedaction;
|
|
81
|
+
/**
|
|
82
|
+
* Resolves the list of openredaction pattern names to activate for the
|
|
83
|
+
* given entity-type filter.
|
|
84
|
+
*
|
|
85
|
+
* When no filter is provided, all mapped patterns are returned.
|
|
86
|
+
*
|
|
87
|
+
* @param entityTypes - Optional subset of {@link PiiEntityType} to detect.
|
|
88
|
+
* @returns Array of openredaction pattern name strings.
|
|
89
|
+
*/
|
|
90
|
+
private resolvePatternNames;
|
|
91
|
+
/**
|
|
92
|
+
* Converts raw openredaction detection objects into {@link PiiEntity}
|
|
93
|
+
* instances, filtering out any that don't map to a requested entity type.
|
|
94
|
+
*
|
|
95
|
+
* @param detections - Raw detections from `OpenRedaction.detect()`.
|
|
96
|
+
* @param input - The original input text (used to extract `text`
|
|
97
|
+
* from positional offsets when needed).
|
|
98
|
+
* @param entityTypes - Optional entity-type filter for post-filtering.
|
|
99
|
+
* @returns Mapped and filtered array of {@link PiiEntity}.
|
|
100
|
+
*/
|
|
101
|
+
private mapDetections;
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=RegexRecognizer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RegexRecognizer.d.ts","sourceRoot":"","sources":["../../../../../src/extensions/packs/pii-redaction/recognizers/RegexRecognizer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzD,OAAO,KAAK,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AA2F/E;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,qBAAa,eAAgB,YAAW,iBAAiB;IACvD,kBAAkB;IAClB,SAAgB,IAAI,qBAAqB;IAEzC,kBAAkB;IAClB,SAAgB,iBAAiB,EAAE,aAAa,EAAE,CAehD;IAEF;;;;;OAKG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAQ;IAEzC;;;;OAIG;IACH,OAAO,CAAC,iBAAiB,CAA+E;IAExG;;;;;;OAMG;IACU,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAsBvF,kBAAkB;IACL,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAUrC;;;;;OAKG;YACW,mBAAmB;IAajC;;;;;;;;OAQG;IACH,OAAO,CAAC,mBAAmB;IAe3B;;;;;;;;;OASG;IACH,OAAO,CAAC,aAAa;CA2CtB"}
|
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file RegexRecognizer.ts
|
|
3
|
+
* @description Tier 1 PII recogniser that delegates pattern matching to the
|
|
4
|
+
* `openredaction` library.
|
|
5
|
+
*
|
|
6
|
+
* OpenRedaction ships with 500+ curated regex patterns covering emails, SSNs,
|
|
7
|
+
* credit cards, phone numbers, IP addresses, IBANs, passports, API keys, and
|
|
8
|
+
* many more. This recogniser wraps its `OpenRedaction.detect()` method,
|
|
9
|
+
* normalises the results into the pipeline's {@link PiiEntity} shape, and
|
|
10
|
+
* applies entity-type filtering so only the categories requested by the caller
|
|
11
|
+
* are evaluated.
|
|
12
|
+
*
|
|
13
|
+
* @module pii-redaction/recognizers
|
|
14
|
+
*/
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
16
|
+
// Mapping from openredaction pattern type strings to PiiEntityType
|
|
17
|
+
// ---------------------------------------------------------------------------
|
|
18
|
+
/**
|
|
19
|
+
* Maps openredaction's built-in pattern `type` strings to our canonical
|
|
20
|
+
* {@link PiiEntityType} values.
|
|
21
|
+
*
|
|
22
|
+
* Only types that have a direct or near-direct counterpart are listed.
|
|
23
|
+
* Unmapped openredaction types are silently dropped so that we don't pollute
|
|
24
|
+
* downstream consumers with categories they can't act on.
|
|
25
|
+
*/
|
|
26
|
+
const OPENREDACTION_TYPE_MAP = {
|
|
27
|
+
EMAIL: 'EMAIL',
|
|
28
|
+
SSN: 'SSN',
|
|
29
|
+
CREDIT_CARD: 'CREDIT_CARD',
|
|
30
|
+
PHONE_US: 'PHONE',
|
|
31
|
+
PHONE_UK: 'PHONE',
|
|
32
|
+
PHONE_UK_MOBILE: 'PHONE',
|
|
33
|
+
PHONE_INTERNATIONAL: 'PHONE',
|
|
34
|
+
IPV4: 'IP_ADDRESS',
|
|
35
|
+
IPV6: 'IP_ADDRESS',
|
|
36
|
+
IBAN: 'IBAN',
|
|
37
|
+
PASSPORT_US: 'PASSPORT',
|
|
38
|
+
PASSPORT_UK: 'PASSPORT',
|
|
39
|
+
PASSPORT_MRZ_TD3: 'PASSPORT',
|
|
40
|
+
PASSPORT_MRZ_TD1: 'PASSPORT',
|
|
41
|
+
DRIVING_LICENSE_US: 'DRIVERS_LICENSE',
|
|
42
|
+
DRIVING_LICENSE_UK: 'DRIVERS_LICENSE',
|
|
43
|
+
DATE_OF_BIRTH: 'DATE_OF_BIRTH',
|
|
44
|
+
GENERIC_API_KEY: 'API_KEY',
|
|
45
|
+
OPENAI_API_KEY: 'API_KEY',
|
|
46
|
+
GOOGLE_API_KEY: 'API_KEY',
|
|
47
|
+
STRIPE_API_KEY: 'API_KEY',
|
|
48
|
+
GITHUB_TOKEN: 'API_KEY',
|
|
49
|
+
BEARER_TOKEN: 'API_KEY',
|
|
50
|
+
AWS_ACCESS_KEY: 'AWS_KEY',
|
|
51
|
+
AWS_SECRET_KEY: 'AWS_KEY',
|
|
52
|
+
BITCOIN_ADDRESS: 'CRYPTO_ADDRESS',
|
|
53
|
+
ETHEREUM_ADDRESS: 'CRYPTO_ADDRESS',
|
|
54
|
+
LITECOIN_ADDRESS: 'CRYPTO_ADDRESS',
|
|
55
|
+
MONERO_ADDRESS: 'CRYPTO_ADDRESS',
|
|
56
|
+
RIPPLE_ADDRESS: 'CRYPTO_ADDRESS',
|
|
57
|
+
CARDANO_ADDRESS: 'CRYPTO_ADDRESS',
|
|
58
|
+
SOLANA_ADDRESS: 'CRYPTO_ADDRESS',
|
|
59
|
+
NAME: 'PERSON',
|
|
60
|
+
TAX_ID: 'GOV_ID',
|
|
61
|
+
NATIONAL_INSURANCE_UK: 'GOV_ID',
|
|
62
|
+
NHS_NUMBER: 'GOV_ID',
|
|
63
|
+
ITIN: 'GOV_ID',
|
|
64
|
+
SIN_CA: 'GOV_ID',
|
|
65
|
+
};
|
|
66
|
+
/**
|
|
67
|
+
* Inverse map: for a given {@link PiiEntityType}, lists all openredaction
|
|
68
|
+
* pattern type strings that map to it. Built lazily on first access.
|
|
69
|
+
*/
|
|
70
|
+
let piiTypeToPatternNames = null;
|
|
71
|
+
/**
|
|
72
|
+
* Builds (or returns the cached) inverse mapping from {@link PiiEntityType}
|
|
73
|
+
* to openredaction pattern names.
|
|
74
|
+
*/
|
|
75
|
+
function getPiiTypeToPatternNames() {
|
|
76
|
+
if (piiTypeToPatternNames)
|
|
77
|
+
return piiTypeToPatternNames;
|
|
78
|
+
piiTypeToPatternNames = new Map();
|
|
79
|
+
for (const [patternName, piiType] of Object.entries(OPENREDACTION_TYPE_MAP)) {
|
|
80
|
+
const existing = piiTypeToPatternNames.get(piiType) ?? [];
|
|
81
|
+
existing.push(patternName);
|
|
82
|
+
piiTypeToPatternNames.set(piiType, existing);
|
|
83
|
+
}
|
|
84
|
+
return piiTypeToPatternNames;
|
|
85
|
+
}
|
|
86
|
+
// ---------------------------------------------------------------------------
|
|
87
|
+
// Default patterns to load when no entity-type filter is applied
|
|
88
|
+
// ---------------------------------------------------------------------------
|
|
89
|
+
/**
|
|
90
|
+
* The full list of openredaction pattern names we want available by default.
|
|
91
|
+
* This is the union of all values in {@link OPENREDACTION_TYPE_MAP}.
|
|
92
|
+
*/
|
|
93
|
+
const DEFAULT_PATTERN_NAMES = Object.keys(OPENREDACTION_TYPE_MAP);
|
|
94
|
+
// ---------------------------------------------------------------------------
|
|
95
|
+
// RegexRecognizer
|
|
96
|
+
// ---------------------------------------------------------------------------
|
|
97
|
+
/**
|
|
98
|
+
* Tier 1 entity recogniser backed by the `openredaction` library.
|
|
99
|
+
*
|
|
100
|
+
* ### How it works
|
|
101
|
+
* 1. On construction an {@link OpenRedaction} instance is created with the
|
|
102
|
+
* full set of mapped patterns pre-loaded and pre-compiled.
|
|
103
|
+
* 2. When {@link recognize} is called, pattern names are optionally filtered
|
|
104
|
+
* to the requested {@link PiiEntityType} subset.
|
|
105
|
+
* 3. `OpenRedaction.detect()` runs all active patterns against the input and
|
|
106
|
+
* returns raw detections with position offsets.
|
|
107
|
+
* 4. Results are mapped to {@link PiiEntity} objects with a fixed high score
|
|
108
|
+
* (>= 0.85) because regex matches are deterministic.
|
|
109
|
+
*
|
|
110
|
+
* ### Thread safety
|
|
111
|
+
* Each call to `recognize` creates a fresh `OpenRedaction` instance with
|
|
112
|
+
* only the needed patterns so there is no shared mutable state between
|
|
113
|
+
* concurrent invocations.
|
|
114
|
+
*
|
|
115
|
+
* @example
|
|
116
|
+
* ```ts
|
|
117
|
+
* const recognizer = new RegexRecognizer();
|
|
118
|
+
* const entities = await recognizer.recognize(
|
|
119
|
+
* 'Email me at alice@example.com',
|
|
120
|
+
* { entityTypes: ['EMAIL'] },
|
|
121
|
+
* );
|
|
122
|
+
* // entities[0].entityType === 'EMAIL'
|
|
123
|
+
* // entities[0].score >= 0.85
|
|
124
|
+
* ```
|
|
125
|
+
*/
|
|
126
|
+
export class RegexRecognizer {
|
|
127
|
+
constructor() {
|
|
128
|
+
/** @inheritdoc */
|
|
129
|
+
this.name = 'RegexRecognizer';
|
|
130
|
+
/** @inheritdoc */
|
|
131
|
+
this.supportedEntities = [
|
|
132
|
+
'SSN',
|
|
133
|
+
'CREDIT_CARD',
|
|
134
|
+
'EMAIL',
|
|
135
|
+
'PHONE',
|
|
136
|
+
'IP_ADDRESS',
|
|
137
|
+
'IBAN',
|
|
138
|
+
'PASSPORT',
|
|
139
|
+
'DRIVERS_LICENSE',
|
|
140
|
+
'DATE_OF_BIRTH',
|
|
141
|
+
'API_KEY',
|
|
142
|
+
'AWS_KEY',
|
|
143
|
+
'CRYPTO_ADDRESS',
|
|
144
|
+
'PERSON',
|
|
145
|
+
'GOV_ID',
|
|
146
|
+
];
|
|
147
|
+
/**
|
|
148
|
+
* Lazily-resolved reference to the `OpenRedaction` constructor from the
|
|
149
|
+
* `openredaction` package. Stored after first successful dynamic import
|
|
150
|
+
* to avoid repeated module resolution on subsequent calls.
|
|
151
|
+
*/
|
|
152
|
+
this.OpenRedactionCtor = null;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Scan the input text for PII entities using openredaction regex patterns.
|
|
156
|
+
*
|
|
157
|
+
* @param input - Raw text to analyse.
|
|
158
|
+
* @param options - Optional filtering and context hints.
|
|
159
|
+
* @returns Array of detected {@link PiiEntity} objects, possibly empty.
|
|
160
|
+
*/
|
|
161
|
+
async recognize(input, options) {
|
|
162
|
+
// Determine which openredaction patterns to activate based on the
|
|
163
|
+
// caller's entity-type filter.
|
|
164
|
+
const patternNames = this.resolvePatternNames(options?.entityTypes);
|
|
165
|
+
// Nothing to do if no patterns map to the requested entity types.
|
|
166
|
+
if (patternNames.length === 0)
|
|
167
|
+
return [];
|
|
168
|
+
// Lazily import openredaction (avoids top-level side effects and keeps
|
|
169
|
+
// the module optional for environments that don't need regex detection).
|
|
170
|
+
const Ctor = await this.ensureOpenRedaction();
|
|
171
|
+
// Create a scoped instance with only the relevant patterns loaded.
|
|
172
|
+
const instance = new Ctor({ patterns: patternNames });
|
|
173
|
+
// Run detection — openredaction returns a promise.
|
|
174
|
+
const result = await instance.detect(input);
|
|
175
|
+
// Map openredaction detections to our PiiEntity shape.
|
|
176
|
+
return this.mapDetections(result.detections, input, options?.entityTypes);
|
|
177
|
+
}
|
|
178
|
+
/** @inheritdoc */
|
|
179
|
+
async dispose() {
|
|
180
|
+
// No long-lived resources to release; each `recognize` call creates its
|
|
181
|
+
// own scoped OpenRedaction instance.
|
|
182
|
+
this.OpenRedactionCtor = null;
|
|
183
|
+
}
|
|
184
|
+
// -----------------------------------------------------------------------
|
|
185
|
+
// Private helpers
|
|
186
|
+
// -----------------------------------------------------------------------
|
|
187
|
+
/**
|
|
188
|
+
* Lazily imports the `openredaction` module and caches its constructor.
|
|
189
|
+
*
|
|
190
|
+
* @returns The `OpenRedaction` class constructor.
|
|
191
|
+
* @throws If the `openredaction` package is not installed.
|
|
192
|
+
*/
|
|
193
|
+
async ensureOpenRedaction() {
|
|
194
|
+
if (this.OpenRedactionCtor)
|
|
195
|
+
return this.OpenRedactionCtor;
|
|
196
|
+
// Dynamic import so the dependency is optional at the module level.
|
|
197
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
198
|
+
const mod = await import('openredaction');
|
|
199
|
+
this.OpenRedactionCtor = mod.OpenRedaction;
|
|
200
|
+
return this.OpenRedactionCtor;
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Resolves the list of openredaction pattern names to activate for the
|
|
204
|
+
* given entity-type filter.
|
|
205
|
+
*
|
|
206
|
+
* When no filter is provided, all mapped patterns are returned.
|
|
207
|
+
*
|
|
208
|
+
* @param entityTypes - Optional subset of {@link PiiEntityType} to detect.
|
|
209
|
+
* @returns Array of openredaction pattern name strings.
|
|
210
|
+
*/
|
|
211
|
+
resolvePatternNames(entityTypes) {
|
|
212
|
+
// No filter → use everything we have mapped.
|
|
213
|
+
if (!entityTypes || entityTypes.length === 0)
|
|
214
|
+
return DEFAULT_PATTERN_NAMES;
|
|
215
|
+
const inverse = getPiiTypeToPatternNames();
|
|
216
|
+
const names = [];
|
|
217
|
+
for (const piiType of entityTypes) {
|
|
218
|
+
const mapped = inverse.get(piiType);
|
|
219
|
+
if (mapped)
|
|
220
|
+
names.push(...mapped);
|
|
221
|
+
}
|
|
222
|
+
return names;
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Converts raw openredaction detection objects into {@link PiiEntity}
|
|
226
|
+
* instances, filtering out any that don't map to a requested entity type.
|
|
227
|
+
*
|
|
228
|
+
* @param detections - Raw detections from `OpenRedaction.detect()`.
|
|
229
|
+
* @param input - The original input text (used to extract `text`
|
|
230
|
+
* from positional offsets when needed).
|
|
231
|
+
* @param entityTypes - Optional entity-type filter for post-filtering.
|
|
232
|
+
* @returns Mapped and filtered array of {@link PiiEntity}.
|
|
233
|
+
*/
|
|
234
|
+
mapDetections(detections, input, entityTypes) {
|
|
235
|
+
const entities = [];
|
|
236
|
+
const allowedTypes = entityTypes ? new Set(entityTypes) : null;
|
|
237
|
+
for (const det of detections) {
|
|
238
|
+
const mappedType = OPENREDACTION_TYPE_MAP[det.type];
|
|
239
|
+
// Skip detections whose openredaction type has no mapping.
|
|
240
|
+
if (!mappedType)
|
|
241
|
+
continue;
|
|
242
|
+
// Skip if the mapped type isn't in the caller's requested set.
|
|
243
|
+
if (allowedTypes && !allowedTypes.has(mappedType))
|
|
244
|
+
continue;
|
|
245
|
+
// Compute start/end offsets from the position tuple.
|
|
246
|
+
const [start, end] = det.position;
|
|
247
|
+
// Extract the matched text span from the input for consistency.
|
|
248
|
+
const text = det.value ?? input.slice(start, end);
|
|
249
|
+
// Confidence: take the higher of openredaction's score and our floor.
|
|
250
|
+
const score = Math.max(det.confidence ?? RegexRecognizer.MIN_SCORE, RegexRecognizer.MIN_SCORE);
|
|
251
|
+
entities.push({
|
|
252
|
+
entityType: mappedType,
|
|
253
|
+
text,
|
|
254
|
+
start,
|
|
255
|
+
end,
|
|
256
|
+
score,
|
|
257
|
+
source: 'regex',
|
|
258
|
+
metadata: {
|
|
259
|
+
openredactionType: det.type,
|
|
260
|
+
placeholder: det.placeholder,
|
|
261
|
+
severity: det.severity,
|
|
262
|
+
},
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
return entities;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Minimum confidence score assigned to regex-based detections.
|
|
270
|
+
* Regex matches are deterministic so they receive a high baseline; the
|
|
271
|
+
* openredaction library may report its own `confidence` which we bump
|
|
272
|
+
* to at least this floor value.
|
|
273
|
+
*/
|
|
274
|
+
RegexRecognizer.MIN_SCORE = 0.85;
|
|
275
|
+
//# sourceMappingURL=RegexRecognizer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RegexRecognizer.js","sourceRoot":"","sources":["../../../../../src/extensions/packs/pii-redaction/recognizers/RegexRecognizer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file PiiRedactTool.ts
|
|
3
|
+
* @description AgentOS tool that detects and redacts PII (Personally
|
|
4
|
+
* Identifiable Information) from text, returning both the redacted output
|
|
5
|
+
* and the detection metadata.
|
|
6
|
+
*
|
|
7
|
+
* This tool wraps both the {@link PiiDetectionPipeline} and the
|
|
8
|
+
* {@link redactText} engine, providing a single-step "detect then redact"
|
|
9
|
+
* operation. Agents invoke it when they need sanitised text output, for
|
|
10
|
+
* example before storing user-provided content in a database or forwarding
|
|
11
|
+
* it to an external API.
|
|
12
|
+
*
|
|
13
|
+
* @module pii-redaction/tools/PiiRedactTool
|
|
14
|
+
*/
|
|
15
|
+
import type { ISharedServiceRegistry } from '../../../ISharedServiceRegistry';
|
|
16
|
+
import type { ITool, ToolExecutionContext, ToolExecutionResult, JSONSchemaObject } from '../../../../core/tools/ITool';
|
|
17
|
+
import type { PiiRedactionPackOptions, PiiDetectionResult, RedactionStyle } from '../types';
|
|
18
|
+
/**
|
|
19
|
+
* Input arguments accepted by the {@link PiiRedactTool}.
|
|
20
|
+
*
|
|
21
|
+
* Only `text` is required. The optional `redactionStyle` allows the caller
|
|
22
|
+
* to override the pack-level default for this single invocation.
|
|
23
|
+
*/
|
|
24
|
+
export interface PiiRedactInput {
|
|
25
|
+
/** The text from which PII should be redacted. */
|
|
26
|
+
text: string;
|
|
27
|
+
/**
|
|
28
|
+
* Optional override for the redaction style.
|
|
29
|
+
* When omitted the tool uses the pack-level redaction style configuration.
|
|
30
|
+
*/
|
|
31
|
+
redactionStyle?: RedactionStyle;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Output returned by the {@link PiiRedactTool} on successful execution.
|
|
35
|
+
*
|
|
36
|
+
* Contains both the redacted text and the full detection result so callers
|
|
37
|
+
* can inspect what was found and how confident the detections were.
|
|
38
|
+
*/
|
|
39
|
+
export interface PiiRedactOutput {
|
|
40
|
+
/** The text with all detected PII spans replaced. */
|
|
41
|
+
redactedText: string;
|
|
42
|
+
/** The original input text (for reference / diff comparison). */
|
|
43
|
+
originalText: string;
|
|
44
|
+
/**
|
|
45
|
+
* Whether any PII was detected and redacted.
|
|
46
|
+
* When `false`, `redactedText` is identical to `originalText`.
|
|
47
|
+
*/
|
|
48
|
+
wasRedacted: boolean;
|
|
49
|
+
/** Full detection result including entities, timing, and summary. */
|
|
50
|
+
detectionResult: PiiDetectionResult;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* AgentOS tool that detects PII in text and returns a redacted version.
|
|
54
|
+
*
|
|
55
|
+
* ### Usage by agents
|
|
56
|
+
* ```json
|
|
57
|
+
* {
|
|
58
|
+
* "tool": "pii_redact",
|
|
59
|
+
* "arguments": {
|
|
60
|
+
* "text": "My SSN is 123-45-6789",
|
|
61
|
+
* "redactionStyle": "mask"
|
|
62
|
+
* }
|
|
63
|
+
* }
|
|
64
|
+
* ```
|
|
65
|
+
*
|
|
66
|
+
* ### Return value
|
|
67
|
+
* A {@link PiiRedactOutput} containing the redacted text, the original text,
|
|
68
|
+
* a boolean flag indicating whether any PII was found, and the full
|
|
69
|
+
* {@link PiiDetectionResult} for audit / observability.
|
|
70
|
+
*
|
|
71
|
+
* @implements {ITool<PiiRedactInput, PiiRedactOutput>}
|
|
72
|
+
*/
|
|
73
|
+
export declare class PiiRedactTool implements ITool<PiiRedactInput, PiiRedactOutput> {
|
|
74
|
+
/** Globally unique identifier for the tool. */
|
|
75
|
+
readonly id = "pii_redact";
|
|
76
|
+
/** Functional name used by LLMs in tool call requests. */
|
|
77
|
+
readonly name = "pii_redact";
|
|
78
|
+
/** Human-readable display name for UIs and logs. */
|
|
79
|
+
readonly displayName = "PII Redactor";
|
|
80
|
+
/** Detailed description for LLM tool selection. */
|
|
81
|
+
readonly description: string;
|
|
82
|
+
/** Tool category for filtering and grouping. */
|
|
83
|
+
readonly category = "security";
|
|
84
|
+
/** This tool is read-only and has no side effects. */
|
|
85
|
+
readonly hasSideEffects = false;
|
|
86
|
+
/** JSON Schema describing the expected input arguments. */
|
|
87
|
+
readonly inputSchema: JSONSchemaObject;
|
|
88
|
+
/** Detection pipeline instance shared across invocations. */
|
|
89
|
+
private readonly pipeline;
|
|
90
|
+
/** Default redaction style from pack-level configuration. */
|
|
91
|
+
private readonly defaultRedactionStyle;
|
|
92
|
+
/**
|
|
93
|
+
* Construct a new PiiRedactTool.
|
|
94
|
+
*
|
|
95
|
+
* @param services - Shared service registry forwarded to the detection
|
|
96
|
+
* pipeline for lazy-loading NLP/NER models.
|
|
97
|
+
* @param options - Pack-level configuration controlling entity types,
|
|
98
|
+
* confidence threshold, redaction style, and detection
|
|
99
|
+
* tier flags.
|
|
100
|
+
*/
|
|
101
|
+
constructor(services: ISharedServiceRegistry, options: PiiRedactionPackOptions);
|
|
102
|
+
/**
|
|
103
|
+
* Execute the PII redaction on the provided text.
|
|
104
|
+
*
|
|
105
|
+
* Runs the full detection pipeline, then applies the configured (or
|
|
106
|
+
* overridden) redaction style to all detected PII spans. Returns both
|
|
107
|
+
* the sanitised text and the raw detection result for audit purposes.
|
|
108
|
+
*
|
|
109
|
+
* @param args - Input arguments containing the text to redact and an
|
|
110
|
+
* optional redaction style override.
|
|
111
|
+
* @param context - Tool execution context (unused by this tool but required
|
|
112
|
+
* by the ITool interface).
|
|
113
|
+
* @returns A promise resolving to the tool execution result containing the
|
|
114
|
+
* {@link PiiRedactOutput}.
|
|
115
|
+
*/
|
|
116
|
+
execute(args: PiiRedactInput, context: ToolExecutionContext): Promise<ToolExecutionResult<PiiRedactOutput>>;
|
|
117
|
+
}
|
|
118
|
+
//# sourceMappingURL=PiiRedactTool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PiiRedactTool.d.ts","sourceRoot":"","sources":["../../../../../src/extensions/packs/pii-redaction/tools/PiiRedactTool.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AAC9E,OAAO,KAAK,EACV,KAAK,EACL,oBAAoB,EACpB,mBAAmB,EACnB,gBAAgB,EACjB,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EACV,uBAAuB,EACvB,kBAAkB,EAClB,cAAc,EACf,MAAM,UAAU,CAAC;AAQlB;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC7B,kDAAkD;IAClD,IAAI,EAAE,MAAM,CAAC;IAEb;;;OAGG;IACH,cAAc,CAAC,EAAE,cAAc,CAAC;CACjC;AAED;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B,qDAAqD;IACrD,YAAY,EAAE,MAAM,CAAC;IAErB,iEAAiE;IACjE,YAAY,EAAE,MAAM,CAAC;IAErB;;;OAGG;IACH,WAAW,EAAE,OAAO,CAAC;IAErB,qEAAqE;IACrE,eAAe,EAAE,kBAAkB,CAAC;CACrC;AAMD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,qBAAa,aAAc,YAAW,KAAK,CAAC,cAAc,EAAE,eAAe,CAAC;IAK1E,+CAA+C;IAC/C,QAAQ,CAAC,EAAE,gBAAgB;IAE3B,0DAA0D;IAC1D,QAAQ,CAAC,IAAI,gBAAgB;IAE7B,oDAAoD;IACpD,QAAQ,CAAC,WAAW,kBAAkB;IAEtC,mDAAmD;IACnD,QAAQ,CAAC,WAAW,SAI+B;IAEnD,gDAAgD;IAChD,QAAQ,CAAC,QAAQ,cAAc;IAE/B,sDAAsD;IACtD,QAAQ,CAAC,cAAc,SAAS;IAEhC,2DAA2D;IAC3D,QAAQ,CAAC,WAAW,EAAE,gBAAgB,CAiBpC;IAMF,6DAA6D;IAC7D,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAuB;IAEhD,6DAA6D;IAC7D,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAiB;IAMvD;;;;;;;;OAQG;gBAED,QAAQ,EAAE,sBAAsB,EAChC,OAAO,EAAE,uBAAuB;IAUlC;;;;;;;;;;;;;OAaG;IACG,OAAO,CACX,IAAI,EAAE,cAAc,EACpB,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,mBAAmB,CAAC,eAAe,CAAC,CAAC;CA6CjD"}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file PiiRedactTool.ts
|
|
3
|
+
* @description AgentOS tool that detects and redacts PII (Personally
|
|
4
|
+
* Identifiable Information) from text, returning both the redacted output
|
|
5
|
+
* and the detection metadata.
|
|
6
|
+
*
|
|
7
|
+
* This tool wraps both the {@link PiiDetectionPipeline} and the
|
|
8
|
+
* {@link redactText} engine, providing a single-step "detect then redact"
|
|
9
|
+
* operation. Agents invoke it when they need sanitised text output, for
|
|
10
|
+
* example before storing user-provided content in a database or forwarding
|
|
11
|
+
* it to an external API.
|
|
12
|
+
*
|
|
13
|
+
* @module pii-redaction/tools/PiiRedactTool
|
|
14
|
+
*/
|
|
15
|
+
import { PiiDetectionPipeline } from '../PiiDetectionPipeline.js';
|
|
16
|
+
import { redactText } from '../RedactionEngine.js';
|
|
17
|
+
// ---------------------------------------------------------------------------
|
|
18
|
+
// PiiRedactTool
|
|
19
|
+
// ---------------------------------------------------------------------------
|
|
20
|
+
/**
|
|
21
|
+
* AgentOS tool that detects PII in text and returns a redacted version.
|
|
22
|
+
*
|
|
23
|
+
* ### Usage by agents
|
|
24
|
+
* ```json
|
|
25
|
+
* {
|
|
26
|
+
* "tool": "pii_redact",
|
|
27
|
+
* "arguments": {
|
|
28
|
+
* "text": "My SSN is 123-45-6789",
|
|
29
|
+
* "redactionStyle": "mask"
|
|
30
|
+
* }
|
|
31
|
+
* }
|
|
32
|
+
* ```
|
|
33
|
+
*
|
|
34
|
+
* ### Return value
|
|
35
|
+
* A {@link PiiRedactOutput} containing the redacted text, the original text,
|
|
36
|
+
* a boolean flag indicating whether any PII was found, and the full
|
|
37
|
+
* {@link PiiDetectionResult} for audit / observability.
|
|
38
|
+
*
|
|
39
|
+
* @implements {ITool<PiiRedactInput, PiiRedactOutput>}
|
|
40
|
+
*/
|
|
41
|
+
export class PiiRedactTool {
|
|
42
|
+
// -----------------------------------------------------------------------
|
|
43
|
+
// Constructor
|
|
44
|
+
// -----------------------------------------------------------------------
|
|
45
|
+
/**
|
|
46
|
+
* Construct a new PiiRedactTool.
|
|
47
|
+
*
|
|
48
|
+
* @param services - Shared service registry forwarded to the detection
|
|
49
|
+
* pipeline for lazy-loading NLP/NER models.
|
|
50
|
+
* @param options - Pack-level configuration controlling entity types,
|
|
51
|
+
* confidence threshold, redaction style, and detection
|
|
52
|
+
* tier flags.
|
|
53
|
+
*/
|
|
54
|
+
constructor(services, options) {
|
|
55
|
+
// -----------------------------------------------------------------------
|
|
56
|
+
// ITool metadata
|
|
57
|
+
// -----------------------------------------------------------------------
|
|
58
|
+
/** Globally unique identifier for the tool. */
|
|
59
|
+
this.id = 'pii_redact';
|
|
60
|
+
/** Functional name used by LLMs in tool call requests. */
|
|
61
|
+
this.name = 'pii_redact';
|
|
62
|
+
/** Human-readable display name for UIs and logs. */
|
|
63
|
+
this.displayName = 'PII Redactor';
|
|
64
|
+
/** Detailed description for LLM tool selection. */
|
|
65
|
+
this.description = 'Detect and redact Personally Identifiable Information (PII) from text. ' +
|
|
66
|
+
'Returns both the redacted text and detection metadata including entity types, ' +
|
|
67
|
+
'positions, and confidence scores. Use this to sanitise text before storing, ' +
|
|
68
|
+
'logging, or forwarding it to external systems.';
|
|
69
|
+
/** Tool category for filtering and grouping. */
|
|
70
|
+
this.category = 'security';
|
|
71
|
+
/** This tool is read-only and has no side effects. */
|
|
72
|
+
this.hasSideEffects = false;
|
|
73
|
+
/** JSON Schema describing the expected input arguments. */
|
|
74
|
+
this.inputSchema = {
|
|
75
|
+
type: 'object',
|
|
76
|
+
properties: {
|
|
77
|
+
text: {
|
|
78
|
+
type: 'string',
|
|
79
|
+
description: 'The text from which PII should be redacted.',
|
|
80
|
+
},
|
|
81
|
+
redactionStyle: {
|
|
82
|
+
type: 'string',
|
|
83
|
+
enum: ['placeholder', 'mask', 'hash', 'category-tag'],
|
|
84
|
+
description: 'How detected PII should be replaced. Defaults to the pack-level setting ' +
|
|
85
|
+
'(typically "placeholder"). Options: "placeholder" ([EMAIL]), "mask" (j***@*****), ' +
|
|
86
|
+
'"hash" ([EMAIL:a1b2c3d4e5]), "category-tag" (<PII type="EMAIL">REDACTED</PII>).',
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
required: ['text'],
|
|
90
|
+
};
|
|
91
|
+
this.pipeline = new PiiDetectionPipeline(services, options);
|
|
92
|
+
this.defaultRedactionStyle = options.redactionStyle ?? 'placeholder';
|
|
93
|
+
}
|
|
94
|
+
// -----------------------------------------------------------------------
|
|
95
|
+
// ITool — execute
|
|
96
|
+
// -----------------------------------------------------------------------
|
|
97
|
+
/**
|
|
98
|
+
* Execute the PII redaction on the provided text.
|
|
99
|
+
*
|
|
100
|
+
* Runs the full detection pipeline, then applies the configured (or
|
|
101
|
+
* overridden) redaction style to all detected PII spans. Returns both
|
|
102
|
+
* the sanitised text and the raw detection result for audit purposes.
|
|
103
|
+
*
|
|
104
|
+
* @param args - Input arguments containing the text to redact and an
|
|
105
|
+
* optional redaction style override.
|
|
106
|
+
* @param context - Tool execution context (unused by this tool but required
|
|
107
|
+
* by the ITool interface).
|
|
108
|
+
* @returns A promise resolving to the tool execution result containing the
|
|
109
|
+
* {@link PiiRedactOutput}.
|
|
110
|
+
*/
|
|
111
|
+
async execute(args, context) {
|
|
112
|
+
try {
|
|
113
|
+
// Validate that the required `text` argument is present and non-empty.
|
|
114
|
+
if (!args.text || typeof args.text !== 'string') {
|
|
115
|
+
return {
|
|
116
|
+
success: false,
|
|
117
|
+
error: 'The "text" argument is required and must be a non-empty string.',
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
// Run the detection pipeline.
|
|
121
|
+
const detectionResult = await this.pipeline.detect(args.text);
|
|
122
|
+
// Determine which redaction style to use (per-call override or default).
|
|
123
|
+
const style = args.redactionStyle ?? this.defaultRedactionStyle;
|
|
124
|
+
// Apply redaction to detected entity spans.
|
|
125
|
+
const redacted = redactText(args.text, detectionResult.entities, style);
|
|
126
|
+
// Build the output payload.
|
|
127
|
+
const output = {
|
|
128
|
+
redactedText: redacted,
|
|
129
|
+
originalText: args.text,
|
|
130
|
+
wasRedacted: detectionResult.entities.length > 0,
|
|
131
|
+
detectionResult,
|
|
132
|
+
};
|
|
133
|
+
return {
|
|
134
|
+
success: true,
|
|
135
|
+
output,
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
catch (error) {
|
|
139
|
+
// Wrap unexpected errors in a failed ToolExecutionResult rather than
|
|
140
|
+
// letting them propagate as unhandled exceptions.
|
|
141
|
+
const message = error instanceof Error
|
|
142
|
+
? error.message
|
|
143
|
+
: 'Unknown error during PII redaction';
|
|
144
|
+
return {
|
|
145
|
+
success: false,
|
|
146
|
+
error: message,
|
|
147
|
+
details: { stack: error instanceof Error ? error.stack : undefined },
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
//# sourceMappingURL=PiiRedactTool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PiiRedactTool.js","sourceRoot":"","sources":["../../../../../src/extensions/packs/pii-redaction/tools/PiiRedactTool.ts"],"names":[],"mappings":"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"}
|