avantgate 2.1.0 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -21
- package/dist/chunk-Z6QOMLZ2.mjs +55 -0
- package/dist/control-layer.d.ts.map +1 -1
- package/dist/custom-terms.d.ts +8 -0
- package/dist/custom-terms.d.ts.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +84 -5
- package/dist/index.mjs +83 -5
- package/dist/secret-guard.d.ts +5 -0
- package/dist/secret-guard.d.ts.map +1 -1
- package/dist/types.d.ts +9 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/ui/index.d.ts +1 -0
- package/dist/ui/index.d.ts.map +1 -1
- package/dist/ui/index.js +65 -0
- package/dist/ui/index.mjs +6 -0
- package/dist/ui/react/index.mjs +4 -51
- package/package.json +7 -12
package/README.md
CHANGED
|
@@ -33,32 +33,17 @@ flowchart LR
|
|
|
33
33
|
|
|
34
34
|
---
|
|
35
35
|
|
|
36
|
-
## 🖥️
|
|
36
|
+
## 🖥️ Optional Visual Cockpit — GateWall (`gatewall`)
|
|
37
37
|
|
|
38
|
-
While the **AvantGate SDK**
|
|
38
|
+
While the **AvantGate SDK (`avantgate`)** runs **100% headless and in-process** inside your application runtime (zero servers, zero network latency), an optional visual control plane, **GateWall**, is available as a standalone repository for teams requiring a visual dashboard, real-time audit inspector, and Human-in-the-Loop approval interface.
|
|
39
39
|
|
|
40
40
|
```mermaid
|
|
41
41
|
flowchart LR
|
|
42
|
-
Agent[🤖 AvantGate Agent
|
|
43
|
-
GateWall -- "SSE
|
|
44
|
-
Browser -- "POST /api/v1/approvals<br/>(Approve / Reject)" --> GateWall
|
|
42
|
+
Agent[🤖 AvantGate In-Process Agent] -- "Optional HTTP Telemetry" --> GateWall["🛡️ Standalone GateWall Cockpit<br/>(Dedicated Repository)"]
|
|
43
|
+
GateWall -- "SSE Real-Time Stream" --> Browser["💻 Web Dashboard<br/>(localhost:3000)"]
|
|
45
44
|
```
|
|
46
45
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
#### Option 1: One-Line Docker Compose (Recommended)
|
|
50
|
-
```bash
|
|
51
|
-
docker compose up -d
|
|
52
|
-
# or: npm run gatewall:docker
|
|
53
|
-
```
|
|
54
|
-
Open **`http://localhost:3000`** in your browser 🎉. Traces and audit sessions are automatically persisted.
|
|
55
|
-
|
|
56
|
-
#### Option 2: Run with Bun or Node.js
|
|
57
|
-
```bash
|
|
58
|
-
cd gatewall
|
|
59
|
-
bun install # or npm install
|
|
60
|
-
bun run dev # or npm run dev
|
|
61
|
-
```
|
|
46
|
+
> 💡 **Standalone Repository:** GateWall Cockpit is maintained independently at `../gatewall`. If your application runs headless, you do **not** need to deploy or run GateWall — all guardrails, PII redactions, and token budgets execute directly within your Node.js process.
|
|
62
47
|
|
|
63
48
|
---
|
|
64
49
|
|
|
@@ -71,7 +56,8 @@ bun run dev # or npm run dev
|
|
|
71
56
|
| **⚡ Real-Time Streaming (SSE)** | Low-latency Server-Sent Events (`/api/v1/realtime`) updating session trees, metrics, and alerts dynamically without manual page refresh. |
|
|
72
57
|
| **💰 FinOps & Token Tracking** | Automated token cost estimation and USD burn tracking across providers (GPT-4o, Claude 3.5 Sonnet, DeepSeek, etc.). |
|
|
73
58
|
| **🛡️ Loop Shield (Anti-Cycle Guard)** | Early visual detection of recursive agent loops and aberrant repetitive tool execution cycles. |
|
|
74
|
-
| **💾
|
|
59
|
+
| **💾 Pluggable Hexagonal Storage** | Zero setup overhead by default with embedded SQLite (`gatewall/data/gatewall.db`), zero-disk in-memory storage for CI tests, and production-ready PostgreSQL/Prisma adapter (`STORAGE_DRIVER=prisma`). |
|
|
60
|
+
| **🔏 Custom Redaction Terms Manager** | Interactive visual manager in the Security Cockpit to register, categorize (Project, Company, Infra), and redact proprietary secrets and NDA keywords in-flight. |
|
|
75
61
|
|
|
76
62
|
> 💡 **Agent Integration Recipes:** See [GateWall Telemetry Recipe](examples/observability/10-gatewall-telemetry.ts) and [Integration Cookbook](examples/README.md) for complete code recipes using `HttpTelemetryExporter` (`avantgate/agent`), direct HTTP ingestion, and React front-end streaming (`avantgate/client`).
|
|
77
63
|
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
// src/ui/react/create-view-registry.ts
|
|
2
|
+
import React from "react";
|
|
3
|
+
var createViewRegistry = (registry) => {
|
|
4
|
+
const CanvasRenderer = ({
|
|
5
|
+
state,
|
|
6
|
+
context = {}
|
|
7
|
+
}) => {
|
|
8
|
+
if (!state?.content) {
|
|
9
|
+
return null;
|
|
10
|
+
}
|
|
11
|
+
const kind = state.content.kind;
|
|
12
|
+
const Component = registry[kind];
|
|
13
|
+
if (!Component) {
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
return React.createElement(Component, {
|
|
17
|
+
data: state.content,
|
|
18
|
+
context,
|
|
19
|
+
activeIntent: state.activeIntent
|
|
20
|
+
});
|
|
21
|
+
};
|
|
22
|
+
return {
|
|
23
|
+
registry,
|
|
24
|
+
CanvasRenderer
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
// src/ui/react/sanitize.ts
|
|
29
|
+
var ALLOWED_PROTOCOLS = /* @__PURE__ */ new Set(["http:", "https:"]);
|
|
30
|
+
var isValidSafeUrl = (rawUrl) => {
|
|
31
|
+
if (!rawUrl || typeof rawUrl !== "string") {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
const trimmed = rawUrl.trim();
|
|
35
|
+
if (!trimmed) {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
if (trimmed.startsWith("#")) {
|
|
39
|
+
return true;
|
|
40
|
+
}
|
|
41
|
+
if (trimmed.startsWith("/") && !trimmed.startsWith("//")) {
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
try {
|
|
45
|
+
const parsed = new URL(trimmed);
|
|
46
|
+
return ALLOWED_PROTOCOLS.has(parsed.protocol);
|
|
47
|
+
} catch {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export {
|
|
53
|
+
createViewRegistry,
|
|
54
|
+
isValidSafeUrl
|
|
55
|
+
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"control-layer.d.ts","sourceRoot":"","sources":["../src/control-layer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EACV,kBAAkB,EAClB,eAAe,EACf,yBAAyB,EACzB,+BAA+B,EAC/B,eAAe,EAIhB,MAAM,SAAS,CAAC;AAiBjB,qBAAa,qBAAqB;IAChC,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,oBAAoB,CAAC,CAAuB;gBAExC,MAAM,EAAE,kBAAkB;IAgBtC,OAAO,CAAC,qBAAqB,CAU3B;IAEF,OAAO,CAAC,kBAAkB,CAaxB;IAEF,OAAO,CAAC,aAAa,CAcnB;IAEF,OAAO,CAAC,mBAAmB,
|
|
1
|
+
{"version":3,"file":"control-layer.d.ts","sourceRoot":"","sources":["../src/control-layer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EACV,kBAAkB,EAClB,eAAe,EACf,yBAAyB,EACzB,+BAA+B,EAC/B,eAAe,EAIhB,MAAM,SAAS,CAAC;AAiBjB,qBAAa,qBAAqB;IAChC,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,oBAAoB,CAAC,CAAuB;gBAExC,MAAM,EAAE,kBAAkB;IAgBtC,OAAO,CAAC,qBAAqB,CAU3B;IAEF,OAAO,CAAC,kBAAkB,CAaxB;IAEF,OAAO,CAAC,aAAa,CAcnB;IAEF,OAAO,CAAC,mBAAmB,CAqBzB;IAEF,OAAO,CAAC,yBAAyB,CAiB/B;IAEF,OAAO,CAAC,oBAAoB,CAkC1B;IAEF,OAAO,CAAC,wBAAwB,CAW9B;IAEF,OAAO,CAAC,aAAa,CAOnB;IAEF,OAAO,CAAC,aAAa,CAUnB;IAEF,OAAO,CAAC,gBAAgB,CAMtB;IAEF,OAAO,CAAC,iBAAiB,CAsBvB;IAEF,OAAO,CAAC,uBAAuB,CAmB7B;IAEF,OAAO,CAAC,uBAAuB,CA+B7B;IAEF,OAAO,CAAC,cAAc,CAqBpB;IAEF,OAAO,CAAC,eAAe,CAarB;IAEF,OAAO,GAAU,SAAS;QACxB,SAAS,EAAE,MAAM,CAAC;QAClB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,gBAAgB,CAAC,EAAE,eAAe,CAAC;KACpC,KAAG,OAAO,CAAC,eAAe,CAAC,CA2B1B;IAGF,iBAAiB,GAAU,CAAC,EAAE,SAAS;QACrC,SAAS,EAAE,MAAM,CAAC;QAClB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QACrB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,gBAAgB,CAAC,EAAE,eAAe,CAAC;KACpC,KAAG,OAAO,CAAC,yBAAyB,CAAC,CAAC,CAAC,CAAC,CAyBvC;IAEF,OAAO,CAAC,wBAAwB,CAO9B;IAEF,OAAO,CAAC,kBAAkB,CAIxB;IAEF,OAAO,CAAC,uBAAuB,CAe7B;IAEF,OAAO,CAAC,wBAAwB,CAqB9B;IAEF,OAAO,CAAC,uBAAuB,CAkB7B;IAEF,OAAO,CAAC,uBAAuB,CAY7B;IAEF,OAAO,CAAC,gCAAgC,CAiBtC;IAEF,OAAO,CAAC,qBAAqB,CAwB3B;IAEF,OAAO,CAAC,mBAAmB,CAazB;IAEF,OAAO,CAAC,gBAAgB,CAQtB;IAEF,wBAAwB,GAAU,CAAC,EACjC,SAAS,+BAA+B,CAAC,CAAC,CAAC,KAC1C,OAAO,CAAC,yBAAyB,CAAC,CAAC,CAAC,CAAC,CAwCtC;CACH;AAED,eAAO,MAAM,qBAAqB,GAAI,QAAQ,kBAAkB,KAAG,qBAElE,CAAC;AAEF,eAAO,MAAM,eAAe,WAJkB,kBAAkB,KAAG,qBAIf,CAAC;AACrD,OAAO,EAAE,qBAAqB,IAAI,kBAAkB,EAAE,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { CustomRedactionTermDef } from "./types";
|
|
2
|
+
export interface CustomTermsSanitizationResult {
|
|
3
|
+
text: string;
|
|
4
|
+
maskedCount: number;
|
|
5
|
+
matchedTerms: string[];
|
|
6
|
+
}
|
|
7
|
+
export declare const sanitizeCustomTerms: (input: string, terms?: Array<string | CustomRedactionTermDef>) => CustomTermsSanitizationResult;
|
|
8
|
+
//# sourceMappingURL=custom-terms.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"custom-terms.d.ts","sourceRoot":"","sources":["../src/custom-terms.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAgB,MAAM,SAAS,CAAC;AAEpE,MAAM,WAAW,6BAA6B;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAsED,eAAO,MAAM,mBAAmB,GAC9B,OAAO,MAAM,EACb,QAAQ,KAAK,CAAC,MAAM,GAAG,sBAAsB,CAAC,KAC7C,6BAeF,CAAC"}
|
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,WAAW,CAAC;AAC1B,cAAc,0BAA0B,CAAC;AACzC,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,sBAAsB,CAAC;AACrC,cAAc,iBAAiB,CAAC;AAChC,cAAc,WAAW,CAAC;AAC1B,cAAc,yBAAyB,CAAC;AACxC,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,WAAW,CAAC;AAC1B,cAAc,0BAA0B,CAAC;AACzC,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,sBAAsB,CAAC;AACrC,cAAc,iBAAiB,CAAC;AAChC,cAAc,WAAW,CAAC;AAC1B,cAAc,yBAAyB,CAAC;AACxC,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -61,6 +61,7 @@ __export(index_exports, {
|
|
|
61
61
|
isWorkflowAbortSignal: () => isWorkflowAbortSignal,
|
|
62
62
|
resolveModelPrice: () => resolveModelPrice,
|
|
63
63
|
resolveModelPriceAsync: () => resolveModelPriceAsync,
|
|
64
|
+
sanitizeCustomTerms: () => sanitizeCustomTerms,
|
|
64
65
|
sanitizePII: () => sanitizePII,
|
|
65
66
|
sanitizeSecrets: () => sanitizeSecrets,
|
|
66
67
|
validateUserInput: () => validateUserInput,
|
|
@@ -1172,6 +1173,70 @@ var createHttpProviderClient = (config) => {
|
|
|
1172
1173
|
return new HttpProviderClient(config);
|
|
1173
1174
|
};
|
|
1174
1175
|
|
|
1176
|
+
// src/custom-terms.ts
|
|
1177
|
+
var DEFAULT_MASKS = {
|
|
1178
|
+
PROJECT: "[REDACTED_PROJECT]",
|
|
1179
|
+
COMPANY: "[REDACTED_COMPANY]",
|
|
1180
|
+
INFRA: "[REDACTED_INFRA]",
|
|
1181
|
+
CUSTOM: "[REDACTED_CUSTOM]"
|
|
1182
|
+
};
|
|
1183
|
+
var escapeRegex = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
1184
|
+
var resolveTermDefinition = (entry) => {
|
|
1185
|
+
if (typeof entry === "string") {
|
|
1186
|
+
return {
|
|
1187
|
+
term: entry.trim(),
|
|
1188
|
+
mask: DEFAULT_MASKS.CUSTOM,
|
|
1189
|
+
category: "CUSTOM",
|
|
1190
|
+
caseSensitive: false
|
|
1191
|
+
};
|
|
1192
|
+
}
|
|
1193
|
+
const category = entry.category ?? "CUSTOM";
|
|
1194
|
+
return {
|
|
1195
|
+
term: entry.term.trim(),
|
|
1196
|
+
mask: entry.mask ?? (DEFAULT_MASKS[category] ?? DEFAULT_MASKS.CUSTOM),
|
|
1197
|
+
category,
|
|
1198
|
+
caseSensitive: Boolean(entry.caseSensitive)
|
|
1199
|
+
};
|
|
1200
|
+
};
|
|
1201
|
+
var buildTermRegex = (def) => {
|
|
1202
|
+
const escaped = escapeRegex(def.term);
|
|
1203
|
+
const leadingBoundary = /^\w/.test(def.term) ? "\\b" : "";
|
|
1204
|
+
const trailingBoundary = /\w$/.test(def.term) ? "\\b" : "";
|
|
1205
|
+
return new RegExp(`${leadingBoundary}${escaped}${trailingBoundary}`, def.caseSensitive ? "g" : "gi");
|
|
1206
|
+
};
|
|
1207
|
+
var replaceTermsInText = (initialText, definitions) => {
|
|
1208
|
+
let currentText = initialText;
|
|
1209
|
+
let totalMaskedCount = 0;
|
|
1210
|
+
const matchedTermsSet = /* @__PURE__ */ new Set();
|
|
1211
|
+
for (const item of definitions) {
|
|
1212
|
+
const regex = buildTermRegex(item);
|
|
1213
|
+
let matchCount = 0;
|
|
1214
|
+
currentText = currentText.replace(regex, () => {
|
|
1215
|
+
matchCount++;
|
|
1216
|
+
return item.mask;
|
|
1217
|
+
});
|
|
1218
|
+
if (matchCount > 0) {
|
|
1219
|
+
totalMaskedCount += matchCount;
|
|
1220
|
+
matchedTermsSet.add(item.term);
|
|
1221
|
+
}
|
|
1222
|
+
}
|
|
1223
|
+
return {
|
|
1224
|
+
text: currentText,
|
|
1225
|
+
maskedCount: totalMaskedCount,
|
|
1226
|
+
matchedTerms: Array.from(matchedTermsSet)
|
|
1227
|
+
};
|
|
1228
|
+
};
|
|
1229
|
+
var sanitizeCustomTerms = (input, terms) => {
|
|
1230
|
+
if (!input || !terms || terms.length === 0) {
|
|
1231
|
+
return { text: input, maskedCount: 0, matchedTerms: [] };
|
|
1232
|
+
}
|
|
1233
|
+
const normalized = terms.map(resolveTermDefinition).filter((t) => t.term.length > 0).sort((a, b) => b.term.length - a.term.length);
|
|
1234
|
+
if (normalized.length === 0) {
|
|
1235
|
+
return { text: input, maskedCount: 0, matchedTerms: [] };
|
|
1236
|
+
}
|
|
1237
|
+
return replaceTermsInText(input, normalized);
|
|
1238
|
+
};
|
|
1239
|
+
|
|
1175
1240
|
// src/secret-guard.ts
|
|
1176
1241
|
var SECRET_PATTERNS = [
|
|
1177
1242
|
// 1. Clés privées (RSA, OpenSSH, EC, DSA)
|
|
@@ -1252,6 +1317,7 @@ var sanitizeSecrets = (input) => {
|
|
|
1252
1317
|
var applyOutputGuards = (rawOutput, options) => {
|
|
1253
1318
|
let currentText = rawOutput;
|
|
1254
1319
|
let piiCount = 0;
|
|
1320
|
+
let customTermsCount = 0;
|
|
1255
1321
|
if (options?.maskPII) {
|
|
1256
1322
|
const piiResult = sanitizePII(currentText);
|
|
1257
1323
|
currentText = piiResult.text;
|
|
@@ -1259,6 +1325,11 @@ var applyOutputGuards = (rawOutput, options) => {
|
|
|
1259
1325
|
}
|
|
1260
1326
|
const secretResult = sanitizeSecrets(currentText);
|
|
1261
1327
|
currentText = secretResult.text;
|
|
1328
|
+
if (options?.customRedactionTerms && options.customRedactionTerms.length > 0) {
|
|
1329
|
+
const customResult = sanitizeCustomTerms(currentText, options.customRedactionTerms);
|
|
1330
|
+
currentText = customResult.text;
|
|
1331
|
+
customTermsCount = customResult.maskedCount;
|
|
1332
|
+
}
|
|
1262
1333
|
if (secretResult.hasSecrets && options?.secretLeakAction === "BLOCK") {
|
|
1263
1334
|
const types = secretResult.detections.map((d) => d.type).join(", ");
|
|
1264
1335
|
throw new SecretLeakBlockedError(
|
|
@@ -1268,9 +1339,10 @@ var applyOutputGuards = (rawOutput, options) => {
|
|
|
1268
1339
|
}
|
|
1269
1340
|
return {
|
|
1270
1341
|
text: currentText,
|
|
1271
|
-
sanitized: piiCount > 0 || secretResult.hasSecrets,
|
|
1342
|
+
sanitized: piiCount > 0 || secretResult.hasSecrets || customTermsCount > 0,
|
|
1272
1343
|
secretDetected: secretResult.hasSecrets,
|
|
1273
1344
|
piiMaskedCount: piiCount,
|
|
1345
|
+
customTermsMaskedCount: customTermsCount,
|
|
1274
1346
|
detections: secretResult.detections
|
|
1275
1347
|
};
|
|
1276
1348
|
};
|
|
@@ -1335,21 +1407,27 @@ var AvantGateControlLayer = class {
|
|
|
1335
1407
|
if (!guard.valid) {
|
|
1336
1408
|
throw new Error(`[AvantGate Security Guard] Request blocked: ${guard.blockedReason}`);
|
|
1337
1409
|
}
|
|
1410
|
+
let processed = userQuery;
|
|
1411
|
+
if (this.config.security?.customRedactionTerms && this.config.security.customRedactionTerms.length > 0) {
|
|
1412
|
+
processed = sanitizeCustomTerms(processed, this.config.security.customRedactionTerms).text;
|
|
1413
|
+
}
|
|
1338
1414
|
if (this.config.security?.maskPII) {
|
|
1339
|
-
return sanitizePII(
|
|
1415
|
+
return sanitizePII(processed).text;
|
|
1340
1416
|
}
|
|
1341
|
-
return
|
|
1417
|
+
return processed;
|
|
1342
1418
|
};
|
|
1343
1419
|
applyOutputSecurityGuards = (rawOutput) => {
|
|
1344
1420
|
const isDlpEnabled = this.config.security?.outputDLP ?? this.config.security?.maskPII ?? false;
|
|
1345
1421
|
const shouldCheckSecrets = this.config.security?.blockSecretLeaks ?? true;
|
|
1346
|
-
|
|
1422
|
+
const customTerms = this.config.security?.customRedactionTerms;
|
|
1423
|
+
if (!isDlpEnabled && !shouldCheckSecrets && (!customTerms || customTerms.length === 0)) {
|
|
1347
1424
|
return rawOutput;
|
|
1348
1425
|
}
|
|
1349
1426
|
const guardResult = applyOutputGuards(rawOutput, {
|
|
1350
1427
|
maskPII: isDlpEnabled,
|
|
1351
1428
|
blockSecretLeaks: shouldCheckSecrets,
|
|
1352
|
-
secretLeakAction: this.config.security?.secretLeakAction ?? "REDACT"
|
|
1429
|
+
secretLeakAction: this.config.security?.secretLeakAction ?? "REDACT",
|
|
1430
|
+
customRedactionTerms: customTerms
|
|
1353
1431
|
});
|
|
1354
1432
|
return guardResult.text;
|
|
1355
1433
|
};
|
|
@@ -2642,6 +2720,7 @@ var defineWorkflow = (config) => {
|
|
|
2642
2720
|
isWorkflowAbortSignal,
|
|
2643
2721
|
resolveModelPrice,
|
|
2644
2722
|
resolveModelPriceAsync,
|
|
2723
|
+
sanitizeCustomTerms,
|
|
2645
2724
|
sanitizePII,
|
|
2646
2725
|
sanitizeSecrets,
|
|
2647
2726
|
validateUserInput,
|
package/dist/index.mjs
CHANGED
|
@@ -562,6 +562,70 @@ var createHttpProviderClient = (config) => {
|
|
|
562
562
|
return new HttpProviderClient(config);
|
|
563
563
|
};
|
|
564
564
|
|
|
565
|
+
// src/custom-terms.ts
|
|
566
|
+
var DEFAULT_MASKS = {
|
|
567
|
+
PROJECT: "[REDACTED_PROJECT]",
|
|
568
|
+
COMPANY: "[REDACTED_COMPANY]",
|
|
569
|
+
INFRA: "[REDACTED_INFRA]",
|
|
570
|
+
CUSTOM: "[REDACTED_CUSTOM]"
|
|
571
|
+
};
|
|
572
|
+
var escapeRegex = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
573
|
+
var resolveTermDefinition = (entry) => {
|
|
574
|
+
if (typeof entry === "string") {
|
|
575
|
+
return {
|
|
576
|
+
term: entry.trim(),
|
|
577
|
+
mask: DEFAULT_MASKS.CUSTOM,
|
|
578
|
+
category: "CUSTOM",
|
|
579
|
+
caseSensitive: false
|
|
580
|
+
};
|
|
581
|
+
}
|
|
582
|
+
const category = entry.category ?? "CUSTOM";
|
|
583
|
+
return {
|
|
584
|
+
term: entry.term.trim(),
|
|
585
|
+
mask: entry.mask ?? (DEFAULT_MASKS[category] ?? DEFAULT_MASKS.CUSTOM),
|
|
586
|
+
category,
|
|
587
|
+
caseSensitive: Boolean(entry.caseSensitive)
|
|
588
|
+
};
|
|
589
|
+
};
|
|
590
|
+
var buildTermRegex = (def) => {
|
|
591
|
+
const escaped = escapeRegex(def.term);
|
|
592
|
+
const leadingBoundary = /^\w/.test(def.term) ? "\\b" : "";
|
|
593
|
+
const trailingBoundary = /\w$/.test(def.term) ? "\\b" : "";
|
|
594
|
+
return new RegExp(`${leadingBoundary}${escaped}${trailingBoundary}`, def.caseSensitive ? "g" : "gi");
|
|
595
|
+
};
|
|
596
|
+
var replaceTermsInText = (initialText, definitions) => {
|
|
597
|
+
let currentText = initialText;
|
|
598
|
+
let totalMaskedCount = 0;
|
|
599
|
+
const matchedTermsSet = /* @__PURE__ */ new Set();
|
|
600
|
+
for (const item of definitions) {
|
|
601
|
+
const regex = buildTermRegex(item);
|
|
602
|
+
let matchCount = 0;
|
|
603
|
+
currentText = currentText.replace(regex, () => {
|
|
604
|
+
matchCount++;
|
|
605
|
+
return item.mask;
|
|
606
|
+
});
|
|
607
|
+
if (matchCount > 0) {
|
|
608
|
+
totalMaskedCount += matchCount;
|
|
609
|
+
matchedTermsSet.add(item.term);
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
return {
|
|
613
|
+
text: currentText,
|
|
614
|
+
maskedCount: totalMaskedCount,
|
|
615
|
+
matchedTerms: Array.from(matchedTermsSet)
|
|
616
|
+
};
|
|
617
|
+
};
|
|
618
|
+
var sanitizeCustomTerms = (input, terms) => {
|
|
619
|
+
if (!input || !terms || terms.length === 0) {
|
|
620
|
+
return { text: input, maskedCount: 0, matchedTerms: [] };
|
|
621
|
+
}
|
|
622
|
+
const normalized = terms.map(resolveTermDefinition).filter((t) => t.term.length > 0).sort((a, b) => b.term.length - a.term.length);
|
|
623
|
+
if (normalized.length === 0) {
|
|
624
|
+
return { text: input, maskedCount: 0, matchedTerms: [] };
|
|
625
|
+
}
|
|
626
|
+
return replaceTermsInText(input, normalized);
|
|
627
|
+
};
|
|
628
|
+
|
|
565
629
|
// src/secret-guard.ts
|
|
566
630
|
var SECRET_PATTERNS = [
|
|
567
631
|
// 1. Clés privées (RSA, OpenSSH, EC, DSA)
|
|
@@ -642,6 +706,7 @@ var sanitizeSecrets = (input) => {
|
|
|
642
706
|
var applyOutputGuards = (rawOutput, options) => {
|
|
643
707
|
let currentText = rawOutput;
|
|
644
708
|
let piiCount = 0;
|
|
709
|
+
let customTermsCount = 0;
|
|
645
710
|
if (options?.maskPII) {
|
|
646
711
|
const piiResult = sanitizePII(currentText);
|
|
647
712
|
currentText = piiResult.text;
|
|
@@ -649,6 +714,11 @@ var applyOutputGuards = (rawOutput, options) => {
|
|
|
649
714
|
}
|
|
650
715
|
const secretResult = sanitizeSecrets(currentText);
|
|
651
716
|
currentText = secretResult.text;
|
|
717
|
+
if (options?.customRedactionTerms && options.customRedactionTerms.length > 0) {
|
|
718
|
+
const customResult = sanitizeCustomTerms(currentText, options.customRedactionTerms);
|
|
719
|
+
currentText = customResult.text;
|
|
720
|
+
customTermsCount = customResult.maskedCount;
|
|
721
|
+
}
|
|
652
722
|
if (secretResult.hasSecrets && options?.secretLeakAction === "BLOCK") {
|
|
653
723
|
const types = secretResult.detections.map((d) => d.type).join(", ");
|
|
654
724
|
throw new SecretLeakBlockedError(
|
|
@@ -658,9 +728,10 @@ var applyOutputGuards = (rawOutput, options) => {
|
|
|
658
728
|
}
|
|
659
729
|
return {
|
|
660
730
|
text: currentText,
|
|
661
|
-
sanitized: piiCount > 0 || secretResult.hasSecrets,
|
|
731
|
+
sanitized: piiCount > 0 || secretResult.hasSecrets || customTermsCount > 0,
|
|
662
732
|
secretDetected: secretResult.hasSecrets,
|
|
663
733
|
piiMaskedCount: piiCount,
|
|
734
|
+
customTermsMaskedCount: customTermsCount,
|
|
664
735
|
detections: secretResult.detections
|
|
665
736
|
};
|
|
666
737
|
};
|
|
@@ -725,21 +796,27 @@ var AvantGateControlLayer = class {
|
|
|
725
796
|
if (!guard.valid) {
|
|
726
797
|
throw new Error(`[AvantGate Security Guard] Request blocked: ${guard.blockedReason}`);
|
|
727
798
|
}
|
|
799
|
+
let processed = userQuery;
|
|
800
|
+
if (this.config.security?.customRedactionTerms && this.config.security.customRedactionTerms.length > 0) {
|
|
801
|
+
processed = sanitizeCustomTerms(processed, this.config.security.customRedactionTerms).text;
|
|
802
|
+
}
|
|
728
803
|
if (this.config.security?.maskPII) {
|
|
729
|
-
return sanitizePII(
|
|
804
|
+
return sanitizePII(processed).text;
|
|
730
805
|
}
|
|
731
|
-
return
|
|
806
|
+
return processed;
|
|
732
807
|
};
|
|
733
808
|
applyOutputSecurityGuards = (rawOutput) => {
|
|
734
809
|
const isDlpEnabled = this.config.security?.outputDLP ?? this.config.security?.maskPII ?? false;
|
|
735
810
|
const shouldCheckSecrets = this.config.security?.blockSecretLeaks ?? true;
|
|
736
|
-
|
|
811
|
+
const customTerms = this.config.security?.customRedactionTerms;
|
|
812
|
+
if (!isDlpEnabled && !shouldCheckSecrets && (!customTerms || customTerms.length === 0)) {
|
|
737
813
|
return rawOutput;
|
|
738
814
|
}
|
|
739
815
|
const guardResult = applyOutputGuards(rawOutput, {
|
|
740
816
|
maskPII: isDlpEnabled,
|
|
741
817
|
blockSecretLeaks: shouldCheckSecrets,
|
|
742
|
-
secretLeakAction: this.config.security?.secretLeakAction ?? "REDACT"
|
|
818
|
+
secretLeakAction: this.config.security?.secretLeakAction ?? "REDACT",
|
|
819
|
+
customRedactionTerms: customTerms
|
|
743
820
|
});
|
|
744
821
|
return guardResult.text;
|
|
745
822
|
};
|
|
@@ -1444,6 +1521,7 @@ export {
|
|
|
1444
1521
|
isWorkflowAbortSignal,
|
|
1445
1522
|
resolveModelPrice,
|
|
1446
1523
|
resolveModelPriceAsync,
|
|
1524
|
+
sanitizeCustomTerms,
|
|
1447
1525
|
sanitizePII,
|
|
1448
1526
|
sanitizeSecrets,
|
|
1449
1527
|
validateUserInput,
|
package/dist/secret-guard.d.ts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { CustomRedactionTermDef } from "./types";
|
|
2
|
+
import { sanitizeCustomTerms, CustomTermsSanitizationResult } from "./custom-terms";
|
|
3
|
+
export { sanitizeCustomTerms, CustomTermsSanitizationResult };
|
|
1
4
|
export interface SecretPatternDef {
|
|
2
5
|
type: string;
|
|
3
6
|
regex: RegExp;
|
|
@@ -17,12 +20,14 @@ export interface OutputGuardOptions {
|
|
|
17
20
|
maskPII?: boolean;
|
|
18
21
|
blockSecretLeaks?: boolean;
|
|
19
22
|
secretLeakAction?: "REDACT" | "BLOCK";
|
|
23
|
+
customRedactionTerms?: Array<string | CustomRedactionTermDef>;
|
|
20
24
|
}
|
|
21
25
|
export interface OutputGuardResult {
|
|
22
26
|
text: string;
|
|
23
27
|
sanitized: boolean;
|
|
24
28
|
secretDetected: boolean;
|
|
25
29
|
piiMaskedCount: number;
|
|
30
|
+
customTermsMaskedCount: number;
|
|
26
31
|
detections: SecretDetection[];
|
|
27
32
|
}
|
|
28
33
|
export declare const applyOutputGuards: (rawOutput: string, options?: OutputGuardOptions) => OutputGuardResult;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"secret-guard.d.ts","sourceRoot":"","sources":["../src/secret-guard.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"secret-guard.d.ts","sourceRoot":"","sources":["../src/secret-guard.ts"],"names":[],"mappings":"AAAA,OAAO,EAA0B,sBAAsB,EAAE,MAAM,SAAS,CAAC;AAEzE,OAAO,EAAE,mBAAmB,EAAE,6BAA6B,EAAE,MAAM,gBAAgB,CAAC;AAEpF,OAAO,EAAE,mBAAmB,EAAE,6BAA6B,EAAE,CAAC;AAE9D,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAqDD,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE,eAAe,EAAE,CAAC;CAC/B;AAED,eAAO,MAAM,eAAe,GAAI,OAAO,MAAM,KAAG,qBA4B/C,CAAC;AAEF,MAAM,WAAW,kBAAkB;IACjC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,gBAAgB,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC;IACtC,oBAAoB,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,sBAAsB,CAAC,CAAC;CAC/D;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,OAAO,CAAC;IACnB,cAAc,EAAE,OAAO,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,sBAAsB,EAAE,MAAM,CAAC;IAC/B,UAAU,EAAE,eAAe,EAAE,CAAC;CAC/B;AAED,eAAO,MAAM,iBAAiB,GAC5B,WAAW,MAAM,EACjB,UAAU,kBAAkB,KAC3B,iBAwCF,CAAC"}
|
package/dist/types.d.ts
CHANGED
|
@@ -67,6 +67,14 @@ export interface ProviderConfig {
|
|
|
67
67
|
client?: LLMProviderPort;
|
|
68
68
|
pricing?: ModelPrice;
|
|
69
69
|
}
|
|
70
|
+
export type TermCategory = "PROJECT" | "COMPANY" | "INFRA" | "CUSTOM";
|
|
71
|
+
export interface CustomRedactionTermDef {
|
|
72
|
+
id?: string;
|
|
73
|
+
term: string;
|
|
74
|
+
mask?: string;
|
|
75
|
+
category?: TermCategory;
|
|
76
|
+
caseSensitive?: boolean;
|
|
77
|
+
}
|
|
70
78
|
export interface SecurityConfig {
|
|
71
79
|
detectPromptInjection?: boolean;
|
|
72
80
|
maskPII?: boolean;
|
|
@@ -74,6 +82,7 @@ export interface SecurityConfig {
|
|
|
74
82
|
outputDLP?: boolean;
|
|
75
83
|
blockSecretLeaks?: boolean;
|
|
76
84
|
secretLeakAction?: "REDACT" | "BLOCK";
|
|
85
|
+
customRedactionTerms?: Array<string | CustomRedactionTermDef>;
|
|
77
86
|
}
|
|
78
87
|
export interface RetryConfig {
|
|
79
88
|
maxRetries?: number;
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,WAAW,GAAG,MAAM,CAAC;IAC/C,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,QAAQ;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC1C;AAED,MAAM,WAAW,0BAA0B,CAAC,CAAC;IAC3C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,QAAQ,CAAA;KAAE,CAAC,CAAC;IACrF,MAAM,CAAC,CAAC,OAAO,EAAE,oBAAoB,GAAG,cAAc,CAAC,MAAM,EAAE,QAAQ,GAAG,SAAS,CAAC,CAAC;IACrF,wBAAwB,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,0BAA0B,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;CAClF;AAED,MAAM,WAAW,UAAU;IACzB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,uBAAuB,EAAE,MAAM,CAAC;IAChC,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,WAAW,cAAc;IAC7B,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,GAAG,UAAU,GAAG,SAAS,CAAC;CACxG;AAED,qBAAa,kBAAmB,SAAQ,KAAK;gBAC/B,OAAO,EAAE,MAAM;CAI5B;AAED,qBAAa,mBAAoB,SAAQ,KAAK;gBAChC,OAAO,EAAE,MAAM;CAI5B;AAED,qBAAa,sBAAuB,SAAQ,KAAK;IAC/C,QAAQ,CAAC,UAAU,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;gBAExD,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,CAAC;CAKxF;AAED,OAAO,EAAE,kBAAkB,IAAI,2BAA2B,EAAE,CAAC;AAC7D,OAAO,EAAE,mBAAmB,IAAI,4BAA4B,EAAE,CAAC;AAC/D,OAAO,EAAE,sBAAsB,IAAI,+BAA+B,EAAE,CAAC;AAErE,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,UAAU,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,YAAY,GAAG,QAAQ,CAAC;IACjF,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB,OAAO,CAAC,EAAE,UAAU,CAAC;CACtB;AAED,MAAM,WAAW,cAAc;IAC7B,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,gBAAgB,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,WAAW,GAAG,MAAM,CAAC;IAC/C,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,QAAQ;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC1C;AAED,MAAM,WAAW,0BAA0B,CAAC,CAAC;IAC3C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,QAAQ,CAAA;KAAE,CAAC,CAAC;IACrF,MAAM,CAAC,CAAC,OAAO,EAAE,oBAAoB,GAAG,cAAc,CAAC,MAAM,EAAE,QAAQ,GAAG,SAAS,CAAC,CAAC;IACrF,wBAAwB,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,0BAA0B,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;CAClF;AAED,MAAM,WAAW,UAAU;IACzB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,uBAAuB,EAAE,MAAM,CAAC;IAChC,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,WAAW,cAAc;IAC7B,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,GAAG,UAAU,GAAG,SAAS,CAAC;CACxG;AAED,qBAAa,kBAAmB,SAAQ,KAAK;gBAC/B,OAAO,EAAE,MAAM;CAI5B;AAED,qBAAa,mBAAoB,SAAQ,KAAK;gBAChC,OAAO,EAAE,MAAM;CAI5B;AAED,qBAAa,sBAAuB,SAAQ,KAAK;IAC/C,QAAQ,CAAC,UAAU,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;gBAExD,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,CAAC;CAKxF;AAED,OAAO,EAAE,kBAAkB,IAAI,2BAA2B,EAAE,CAAC;AAC7D,OAAO,EAAE,mBAAmB,IAAI,4BAA4B,EAAE,CAAC;AAC/D,OAAO,EAAE,sBAAsB,IAAI,+BAA+B,EAAE,CAAC;AAErE,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,UAAU,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,YAAY,GAAG,QAAQ,CAAC;IACjF,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB,OAAO,CAAC,EAAE,UAAU,CAAC;CACtB;AAED,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,QAAQ,CAAC;AAEtE,MAAM,WAAW,sBAAsB;IACrC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,cAAc;IAC7B,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,gBAAgB,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC;IACtC,oBAAoB,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,sBAAsB,CAAC,CAAC;CAC/D;AAED,MAAM,WAAW,WAAW;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,IAAI,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE;QACN,MAAM,EAAE,MAAM,CAAC;QACf,UAAU,EAAE,MAAM,CAAC;QACnB,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;IACF,OAAO,EAAE,MAAM,CAAC;IAChB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,GAAG,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CAChD;AAED,MAAM,WAAW,qBAAqB;IACpC,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,YAAY,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,eAAe,CAAC;IAC3D,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,CAAC,EAAE,qBAAqB,CAAC;CACjC;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,cAAc,CAAC;IACxB,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,iBAAiB,CAAC,EAAE,cAAc,CAAC;IACnC,YAAY,CAAC,EAAE,WAAW,CAAC;IAC3B,SAAS,CAAC,EAAE,aAAa,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAC3C,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE;QACN,MAAM,EAAE,MAAM,CAAC;QACf,UAAU,EAAE,MAAM,CAAC;QACnB,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;IACF,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,yBAAyB,CAAC,CAAC;IAC1C,IAAI,EAAE,CAAC,CAAC;IACR,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE;QACN,MAAM,EAAE,MAAM,CAAC;QACf,UAAU,EAAE,MAAM,CAAC;QACnB,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;IACF,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,OAAO,CAAC;CAC3B;AAED,MAAM,WAAW,+BAA+B,CAAC,CAAC;IAChD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gBAAgB,CAAC,EAAE,eAAe,CAAC;IACnC,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B"}
|
package/dist/ui/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { createToolEnvelope, type ToolExecutionEnvelope, type ToolMergeStrategy, type UIIntent, type UIIntentAction, } from "./envelope";
|
|
2
2
|
export { createCanvasReducer, isSafeKey, mergeUniqueEntities, updateEntityInPlace, type CanvasContentState, type CanvasState, } from "./reducer";
|
|
3
3
|
export { defineCanvas } from "./define-canvas";
|
|
4
|
+
export { createViewRegistry, type CanvasRendererProps, type CanvasViewComponent, type CanvasViewContext, isValidSafeUrl, } from "./react";
|
|
4
5
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/ui/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ui/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,KAAK,qBAAqB,EAC1B,KAAK,iBAAiB,EACtB,KAAK,QAAQ,EACb,KAAK,cAAc,GACpB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,mBAAmB,EACnB,SAAS,EACT,mBAAmB,EACnB,mBAAmB,EACnB,KAAK,kBAAkB,EACvB,KAAK,WAAW,GACjB,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ui/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,KAAK,qBAAqB,EAC1B,KAAK,iBAAiB,EACtB,KAAK,QAAQ,EACb,KAAK,cAAc,GACpB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,mBAAmB,EACnB,SAAS,EACT,mBAAmB,EACnB,mBAAmB,EACnB,KAAK,kBAAkB,EACvB,KAAK,WAAW,GACjB,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE/C,OAAO,EACL,kBAAkB,EAClB,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,EACtB,cAAc,GACf,MAAM,SAAS,CAAC"}
|
package/dist/ui/index.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
2
3
|
var __defProp = Object.defineProperty;
|
|
3
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
5
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
8
|
var __export = (target, all) => {
|
|
7
9
|
for (var name in all)
|
|
@@ -15,6 +17,14 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
15
17
|
}
|
|
16
18
|
return to;
|
|
17
19
|
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
18
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
29
|
|
|
20
30
|
// src/ui/index.ts
|
|
@@ -22,8 +32,10 @@ var ui_exports = {};
|
|
|
22
32
|
__export(ui_exports, {
|
|
23
33
|
createCanvasReducer: () => createCanvasReducer,
|
|
24
34
|
createToolEnvelope: () => createToolEnvelope,
|
|
35
|
+
createViewRegistry: () => createViewRegistry,
|
|
25
36
|
defineCanvas: () => defineCanvas,
|
|
26
37
|
isSafeKey: () => isSafeKey,
|
|
38
|
+
isValidSafeUrl: () => isValidSafeUrl,
|
|
27
39
|
mergeUniqueEntities: () => mergeUniqueEntities,
|
|
28
40
|
updateEntityInPlace: () => updateEntityInPlace
|
|
29
41
|
});
|
|
@@ -159,12 +171,65 @@ var defineCanvas = () => {
|
|
|
159
171
|
canvasReducer: createCanvasReducer()
|
|
160
172
|
};
|
|
161
173
|
};
|
|
174
|
+
|
|
175
|
+
// src/ui/react/create-view-registry.ts
|
|
176
|
+
var import_react = __toESM(require("react"));
|
|
177
|
+
var createViewRegistry = (registry) => {
|
|
178
|
+
const CanvasRenderer = ({
|
|
179
|
+
state,
|
|
180
|
+
context = {}
|
|
181
|
+
}) => {
|
|
182
|
+
if (!state?.content) {
|
|
183
|
+
return null;
|
|
184
|
+
}
|
|
185
|
+
const kind = state.content.kind;
|
|
186
|
+
const Component = registry[kind];
|
|
187
|
+
if (!Component) {
|
|
188
|
+
return null;
|
|
189
|
+
}
|
|
190
|
+
return import_react.default.createElement(Component, {
|
|
191
|
+
data: state.content,
|
|
192
|
+
context,
|
|
193
|
+
activeIntent: state.activeIntent
|
|
194
|
+
});
|
|
195
|
+
};
|
|
196
|
+
return {
|
|
197
|
+
registry,
|
|
198
|
+
CanvasRenderer
|
|
199
|
+
};
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
// src/ui/react/sanitize.ts
|
|
203
|
+
var ALLOWED_PROTOCOLS = /* @__PURE__ */ new Set(["http:", "https:"]);
|
|
204
|
+
var isValidSafeUrl = (rawUrl) => {
|
|
205
|
+
if (!rawUrl || typeof rawUrl !== "string") {
|
|
206
|
+
return false;
|
|
207
|
+
}
|
|
208
|
+
const trimmed = rawUrl.trim();
|
|
209
|
+
if (!trimmed) {
|
|
210
|
+
return false;
|
|
211
|
+
}
|
|
212
|
+
if (trimmed.startsWith("#")) {
|
|
213
|
+
return true;
|
|
214
|
+
}
|
|
215
|
+
if (trimmed.startsWith("/") && !trimmed.startsWith("//")) {
|
|
216
|
+
return true;
|
|
217
|
+
}
|
|
218
|
+
try {
|
|
219
|
+
const parsed = new URL(trimmed);
|
|
220
|
+
return ALLOWED_PROTOCOLS.has(parsed.protocol);
|
|
221
|
+
} catch {
|
|
222
|
+
return false;
|
|
223
|
+
}
|
|
224
|
+
};
|
|
162
225
|
// Annotate the CommonJS export names for ESM import in node:
|
|
163
226
|
0 && (module.exports = {
|
|
164
227
|
createCanvasReducer,
|
|
165
228
|
createToolEnvelope,
|
|
229
|
+
createViewRegistry,
|
|
166
230
|
defineCanvas,
|
|
167
231
|
isSafeKey,
|
|
232
|
+
isValidSafeUrl,
|
|
168
233
|
mergeUniqueEntities,
|
|
169
234
|
updateEntityInPlace
|
|
170
235
|
});
|
package/dist/ui/index.mjs
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createViewRegistry,
|
|
3
|
+
isValidSafeUrl
|
|
4
|
+
} from "../chunk-Z6QOMLZ2.mjs";
|
|
1
5
|
import "../chunk-Y6FXYEAI.mjs";
|
|
2
6
|
|
|
3
7
|
// src/ui/envelope.ts
|
|
@@ -133,8 +137,10 @@ var defineCanvas = () => {
|
|
|
133
137
|
export {
|
|
134
138
|
createCanvasReducer,
|
|
135
139
|
createToolEnvelope,
|
|
140
|
+
createViewRegistry,
|
|
136
141
|
defineCanvas,
|
|
137
142
|
isSafeKey,
|
|
143
|
+
isValidSafeUrl,
|
|
138
144
|
mergeUniqueEntities,
|
|
139
145
|
updateEntityInPlace
|
|
140
146
|
};
|
package/dist/ui/react/index.mjs
CHANGED
|
@@ -1,55 +1,8 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createViewRegistry,
|
|
3
|
+
isValidSafeUrl
|
|
4
|
+
} from "../../chunk-Z6QOMLZ2.mjs";
|
|
1
5
|
import "../../chunk-Y6FXYEAI.mjs";
|
|
2
|
-
|
|
3
|
-
// src/ui/react/create-view-registry.ts
|
|
4
|
-
import React from "react";
|
|
5
|
-
var createViewRegistry = (registry) => {
|
|
6
|
-
const CanvasRenderer = ({
|
|
7
|
-
state,
|
|
8
|
-
context = {}
|
|
9
|
-
}) => {
|
|
10
|
-
if (!state?.content) {
|
|
11
|
-
return null;
|
|
12
|
-
}
|
|
13
|
-
const kind = state.content.kind;
|
|
14
|
-
const Component = registry[kind];
|
|
15
|
-
if (!Component) {
|
|
16
|
-
return null;
|
|
17
|
-
}
|
|
18
|
-
return React.createElement(Component, {
|
|
19
|
-
data: state.content,
|
|
20
|
-
context,
|
|
21
|
-
activeIntent: state.activeIntent
|
|
22
|
-
});
|
|
23
|
-
};
|
|
24
|
-
return {
|
|
25
|
-
registry,
|
|
26
|
-
CanvasRenderer
|
|
27
|
-
};
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
// src/ui/react/sanitize.ts
|
|
31
|
-
var ALLOWED_PROTOCOLS = /* @__PURE__ */ new Set(["http:", "https:"]);
|
|
32
|
-
var isValidSafeUrl = (rawUrl) => {
|
|
33
|
-
if (!rawUrl || typeof rawUrl !== "string") {
|
|
34
|
-
return false;
|
|
35
|
-
}
|
|
36
|
-
const trimmed = rawUrl.trim();
|
|
37
|
-
if (!trimmed) {
|
|
38
|
-
return false;
|
|
39
|
-
}
|
|
40
|
-
if (trimmed.startsWith("#")) {
|
|
41
|
-
return true;
|
|
42
|
-
}
|
|
43
|
-
if (trimmed.startsWith("/") && !trimmed.startsWith("//")) {
|
|
44
|
-
return true;
|
|
45
|
-
}
|
|
46
|
-
try {
|
|
47
|
-
const parsed = new URL(trimmed);
|
|
48
|
-
return ALLOWED_PROTOCOLS.has(parsed.protocol);
|
|
49
|
-
} catch {
|
|
50
|
-
return false;
|
|
51
|
-
}
|
|
52
|
-
};
|
|
53
6
|
export {
|
|
54
7
|
createViewRegistry,
|
|
55
8
|
isValidSafeUrl
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "avantgate",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"description": "Zero-infrastructure, in-process AI Application Firewall (AI-WAF), privacy control plane & headless UI canvas for TypeScript: real-time prompt guardrails, zero-egress PII redaction, deterministic tool envelopes, anti-IDOR defense, pre-flight token budgets, and multi-model failover.",
|
|
5
5
|
"author": "Gatewall Team",
|
|
6
6
|
"license": "MIT",
|
|
@@ -69,16 +69,16 @@
|
|
|
69
69
|
"import": "./dist/client/index.mjs",
|
|
70
70
|
"require": "./dist/client/index.js"
|
|
71
71
|
},
|
|
72
|
-
"./ui": {
|
|
73
|
-
"types": "./dist/ui/index.d.ts",
|
|
74
|
-
"import": "./dist/ui/index.mjs",
|
|
75
|
-
"require": "./dist/ui/index.js"
|
|
76
|
-
},
|
|
77
72
|
"./ui/react": {
|
|
78
73
|
"types": "./dist/ui/react/index.d.ts",
|
|
79
74
|
"import": "./dist/ui/react/index.mjs",
|
|
80
75
|
"require": "./dist/ui/react/index.js"
|
|
81
76
|
},
|
|
77
|
+
"./ui": {
|
|
78
|
+
"types": "./dist/ui/index.d.ts",
|
|
79
|
+
"import": "./dist/ui/index.mjs",
|
|
80
|
+
"require": "./dist/ui/index.js"
|
|
81
|
+
},
|
|
82
82
|
"./package.json": "./package.json"
|
|
83
83
|
},
|
|
84
84
|
"peerDependencies": {
|
|
@@ -107,12 +107,6 @@
|
|
|
107
107
|
"test:workflow": "tsx tests/workflow/workflow-saga.test.ts && tsx tests/workflow/workflow-abort.test.ts",
|
|
108
108
|
"test:client": "tsx tests/client/browser-exporter.test.ts && tsx tests/client/use-avantgate-task.test.ts && tsx tests/client/task-runner.test.ts",
|
|
109
109
|
"test:demo": "tsx tests/agent/prospect-ai-demo-scenario.test.ts",
|
|
110
|
-
"gatewall": "npm --prefix gatewall run dev",
|
|
111
|
-
"gatewall:dev": "npm --prefix gatewall run dev",
|
|
112
|
-
"gatewall:build": "npm --prefix gatewall run build",
|
|
113
|
-
"gatewall:seed": "npm --prefix gatewall run seed:mock",
|
|
114
|
-
"gatewall:start": "npm --prefix gatewall run start",
|
|
115
|
-
"gatewall:docker": "docker compose up -d",
|
|
116
110
|
"lint": "tsc --noEmit",
|
|
117
111
|
"prepublishOnly": "npm run build && npm test"
|
|
118
112
|
},
|
|
@@ -139,3 +133,4 @@
|
|
|
139
133
|
"url": "https://github.com/thienban/avantGate/issues"
|
|
140
134
|
}
|
|
141
135
|
}
|
|
136
|
+
|