avantgate 1.5.0 → 1.6.1
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 +47 -4
- package/dist/client/browser-exporter.d.ts +32 -0
- package/dist/client/browser-exporter.d.ts.map +1 -0
- package/dist/client/client.d.ts +37 -0
- package/dist/client/client.d.ts.map +1 -0
- package/dist/client/index.d.ts +5 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +259 -0
- package/dist/client/index.mjs +230 -0
- package/dist/client/types.d.ts +59 -0
- package/dist/client/types.d.ts.map +1 -0
- package/dist/client/useAvantGateTelemetry.d.ts +14 -0
- package/dist/client/useAvantGateTelemetry.d.ts.map +1 -0
- package/package.json +35 -4
package/README.md
CHANGED
|
@@ -33,13 +33,54 @@ flowchart LR
|
|
|
33
33
|
|
|
34
34
|
---
|
|
35
35
|
|
|
36
|
-
##
|
|
36
|
+
## 🖥️ GateWall Cockpit — Self-Hosted AI-WAF & Governance Console (`gatewall/`)
|
|
37
37
|
|
|
38
|
-
While the
|
|
38
|
+
While the **AvantGate SDK** provides zero-infrastructure, in-process control inside your application runtime, the included **GateWall Cockpit** (`gatewall/`) provides a full-featured, self-hosted visual control plane, real-time audit inspector, and Human-in-the-Loop approval.
|
|
39
39
|
|
|
40
|
-
|
|
40
|
+
```mermaid
|
|
41
|
+
flowchart LR
|
|
42
|
+
Agent[🤖 AvantGate Agent / SDK] -- "POST /api/v1/ingest/events<br/>(Async Telemetry)" --> GateWall["🛡️ GateWall Cockpit<br/>(Next.js + SQLite)"]
|
|
43
|
+
GateWall -- "SSE /api/v1/realtime" --> Browser["💻 Web Dashboard<br/>(http://localhost:3000)"]
|
|
44
|
+
Browser -- "POST /api/v1/approvals<br/>(Approve / Reject)" --> GateWall
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### 🚀 Quickstart: Run GateWall Cockpit
|
|
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
|
+
```
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
### 🛡️ Cockpit Capabilities & Modules
|
|
66
|
+
|
|
67
|
+
| Module | Description |
|
|
68
|
+
|---|---|
|
|
69
|
+
| **🔒 Dual-Channel PII Inspector** | Visually compare the sequestered local escrow (`rawPayload`) against the redacted summary dispatched to the model (`llmSummary`). Highlights detected PII (emails, API keys, IBANs, phone numbers). |
|
|
70
|
+
| **🧑⚖️ Human-in-the-Loop (HITL) Queue** | Real-time queue intercepting high-impact tool executions (`WAITING_APPROVAL`) with an interactive dashboard to inspect parameters and click **Approve** or **Reject**. |
|
|
71
|
+
| **⚡ Real-Time Streaming (SSE)** | Low-latency Server-Sent Events (`/api/v1/realtime`) updating session trees, metrics, and alerts dynamically without manual page refresh. |
|
|
72
|
+
| **💰 FinOps & Token Tracking** | Automated token cost estimation and USD burn tracking across providers (GPT-4o, Claude 3.5 Sonnet, DeepSeek, etc.). |
|
|
73
|
+
| **🛡️ Loop Shield (Anti-Cycle Guard)** | Early visual detection of recursive agent loops and aberrant repetitive tool execution cycles. |
|
|
74
|
+
| **💾 Zero-External-DB SQLite Storage** | Zero setup overhead: persistent storage uses embedded SQLite (`gatewall/data/gatewall.db`) without requiring PostgreSQL, Redis, or ClickHouse. |
|
|
75
|
+
|
|
76
|
+
> 💡 **Agent Integration Recipes:** See [Connecting an Agent to GateWall Cockpit](docs/examples.md#12-connecting-an-agent-to-gatewall-cockpit-gatewall) in `docs/examples.md` for complete code recipes using `HttpTelemetryExporter` (`avantgate/agent`), direct HTTP ingestion, and React front-end streaming (`avantgate/client`).
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
### ☁️ Enterprise & Managed Cloud
|
|
41
81
|
|
|
42
|
-
|
|
82
|
+
Looking for enterprise multi-tenant RBAC, SSO/SAML, managed VPC sidecars, or on-premise air-gapped compliance?
|
|
83
|
+
Contact our team at [contact@gatewall.fr](mailto:contact@gatewall.fr) for private previews and enterprise deployment options.
|
|
43
84
|
|
|
44
85
|
---
|
|
45
86
|
|
|
@@ -54,6 +95,7 @@ Available as a **Managed Cloud Control Plane** or an **Out-of-Process High-Avail
|
|
|
54
95
|
- 🔀 **Zero-Downtime Multi-Model Failover**: Seamless client-side failover to fallback providers (or local zero-cost Ollama) when upstream APIs return HTTP 429/500 errors.
|
|
55
96
|
- 🔧 **Self-Repairing Structured Outputs**: Strict Zod schema compliance with automated heuristic markdown/JSON repair if the model hallucinates formatting.
|
|
56
97
|
- 📡 **Zero-Dependency Telemetry Bridge (`HttpTelemetryExporter`, `PlatformStorageAdapter`)**: Mirror execution audits and hierarchical tool traces asynchronously without adding heavy external dependencies.
|
|
98
|
+
- 🌐 **Lightweight Front-End SDK & React Hook (`avantgate/client`)**: Micro-bundle (< 1.7 KB gzipped) for browser UIs. Captures client-side security alerts (blocked API keys, prompt injection attempts), UI render metrics, and user feedback, streaming them directly to gateWall via `fetch(keepalive)` without loading backend infrastructure.
|
|
57
99
|
- 📦 **100% Framework Agnostic**: Works seamlessly in Next.js, Express, Fastify, NestJS, Cloudflare Workers, AWS Lambda, or CLI scripts.
|
|
58
100
|
|
|
59
101
|
---
|
|
@@ -93,6 +135,7 @@ yarn add avantgate zod
|
|
|
93
135
|
| `avantgate/finance` | Financial data normalizer (accounting parentheses, EU/US/UK/CH currencies & magnitudes). |
|
|
94
136
|
| `avantgate/agent` | *(Preview / Experimental)* Durable step runner, Human-in-the-Loop, dual-channel PII tool isolation & storage adapters. |
|
|
95
137
|
| `avantgate/workflow` | Deterministic sequential state machine, automatic reverse Saga rollback, durable HITL checkpoints & agent tool conversion. |
|
|
138
|
+
| `avantgate/client` | Lightweight front-end SDK (< 1.7 KB) & React hook to stream browser security alerts & metrics directly to GateWall. |
|
|
96
139
|
|
|
97
140
|
---
|
|
98
141
|
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { BrowserTelemetryExporterConfig, ClientTelemetryEvent } from "./types";
|
|
2
|
+
export declare class BrowserTelemetryExporter {
|
|
3
|
+
private readonly publicKey;
|
|
4
|
+
private readonly endpoint;
|
|
5
|
+
private agentName?;
|
|
6
|
+
private runId?;
|
|
7
|
+
private readonly batchIntervalMs;
|
|
8
|
+
private readonly maxBatchSize;
|
|
9
|
+
private readonly fetchFn?;
|
|
10
|
+
private readonly onError?;
|
|
11
|
+
private buffer;
|
|
12
|
+
private timer;
|
|
13
|
+
private isFlushing;
|
|
14
|
+
private isDestroyed;
|
|
15
|
+
private readonly handleVisibilityChange;
|
|
16
|
+
private readonly handleBeforeUnload;
|
|
17
|
+
constructor(config: BrowserTelemetryExporterConfig);
|
|
18
|
+
updateContext: (context: {
|
|
19
|
+
runId?: string;
|
|
20
|
+
agentName?: string;
|
|
21
|
+
}) => void;
|
|
22
|
+
getRunId: () => string | undefined;
|
|
23
|
+
getAgentName: () => string | undefined;
|
|
24
|
+
private startTimer;
|
|
25
|
+
private setupBrowserListeners;
|
|
26
|
+
emit: (event: ClientTelemetryEvent) => void;
|
|
27
|
+
flush: () => Promise<void>;
|
|
28
|
+
private dispatchPayload;
|
|
29
|
+
private handleFlushError;
|
|
30
|
+
destroy: () => void;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=browser-exporter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser-exporter.d.ts","sourceRoot":"","sources":["../../src/client/browser-exporter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,8BAA8B,EAC9B,oBAAoB,EAErB,MAAM,SAAS,CAAC;AAMjB,qBAAa,wBAAwB;IACnC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,SAAS,CAAC,CAAS;IAC3B,OAAO,CAAC,KAAK,CAAC,CAAS;IACvB,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IACzC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAe;IACxC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAyB;IAElD,OAAO,CAAC,MAAM,CAA8B;IAC5C,OAAO,CAAC,KAAK,CAA+C;IAC5D,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,WAAW,CAAS;IAE5B,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAIrC;IAEF,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAEjC;gBAEU,MAAM,EAAE,8BAA8B;IAc3C,aAAa,GAAI,SAAS;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,KAAG,IAAI,CAO5E;IAEK,QAAQ,QAAO,MAAM,GAAG,SAAS,CAAe;IAEhD,YAAY,QAAO,MAAM,GAAG,SAAS,CAAmB;IAE/D,OAAO,CAAC,UAAU;IASlB,OAAO,CAAC,qBAAqB;IAStB,IAAI,GAAI,OAAO,oBAAoB,KAAG,IAAI,CAQ/C;IAEK,KAAK,QAAa,OAAO,CAAC,IAAI,CAAC,CAuBpC;IAEF,OAAO,CAAC,eAAe,CAkBrB;IAEF,OAAO,CAAC,gBAAgB,CAStB;IAEK,OAAO,QAAO,IAAI,CAavB;CACH"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { BrowserTelemetryExporter } from "./browser-exporter";
|
|
2
|
+
import type { BrowserTelemetryExporterConfig, ClientSecurityAlertEvent } from "./types";
|
|
3
|
+
export interface TrackSecurityAlertDetails {
|
|
4
|
+
inputLength: number;
|
|
5
|
+
snippet?: string;
|
|
6
|
+
matchedPatternSnippet?: string;
|
|
7
|
+
}
|
|
8
|
+
export interface TrackDataRenderedOptions {
|
|
9
|
+
renderedItemCount?: number;
|
|
10
|
+
channel?: "SOCKET" | "STREAM" | "HTTP";
|
|
11
|
+
}
|
|
12
|
+
export interface TrackFeedbackOptions {
|
|
13
|
+
rating: "POSITIVE" | "NEGATIVE";
|
|
14
|
+
tag?: "HELPFUL" | "INACCURATE" | "UNSAFE" | "OFF_TOPIC";
|
|
15
|
+
comment?: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Public interface for the universal (framework-agnostic) avantGate telemetry client.
|
|
19
|
+
*/
|
|
20
|
+
export interface AvantGateClient {
|
|
21
|
+
trackSecurityAlert: (alertType: ClientSecurityAlertEvent["alertType"], details: TrackSecurityAlertDetails) => void;
|
|
22
|
+
trackClientDataRendered: (toolId: string, options?: TrackDataRenderedOptions) => void;
|
|
23
|
+
trackFeedback: (feedback: TrackFeedbackOptions) => void;
|
|
24
|
+
updateContext: (context: {
|
|
25
|
+
runId?: string;
|
|
26
|
+
agentName?: string;
|
|
27
|
+
}) => void;
|
|
28
|
+
flush: () => Promise<void>;
|
|
29
|
+
destroy: () => void;
|
|
30
|
+
exporter: BrowserTelemetryExporter;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Creates a universal, framework-agnostic avantGate client instance.
|
|
34
|
+
* Works seamlessly in Vite (Vanilla JS, Vue, Svelte, SolidJS), Next.js, or browser scripts.
|
|
35
|
+
*/
|
|
36
|
+
export declare const createAvantGateClient: (config: BrowserTelemetryExporterConfig) => AvantGateClient;
|
|
37
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/client/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,KAAK,EACV,8BAA8B,EAC9B,wBAAwB,EACzB,MAAM,SAAS,CAAC;AAEjB,MAAM,WAAW,yBAAyB;IACxC,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,WAAW,wBAAwB;IACvC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,OAAO,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAAC;CACxC;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,UAAU,GAAG,UAAU,CAAC;IAChC,GAAG,CAAC,EAAE,SAAS,GAAG,YAAY,GAAG,QAAQ,GAAG,WAAW,CAAC;IACxD,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,kBAAkB,EAAE,CAClB,SAAS,EAAE,wBAAwB,CAAC,WAAW,CAAC,EAChD,OAAO,EAAE,yBAAyB,KAC/B,IAAI,CAAC;IACV,uBAAuB,EAAE,CACvB,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,wBAAwB,KAC/B,IAAI,CAAC;IACV,aAAa,EAAE,CAAC,QAAQ,EAAE,oBAAoB,KAAK,IAAI,CAAC;IACxD,aAAa,EAAE,CAAC,OAAO,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IACzE,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3B,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,QAAQ,EAAE,wBAAwB,CAAC;CACpC;AAED;;;GAGG;AACH,eAAO,MAAM,qBAAqB,GAChC,QAAQ,8BAA8B,KACrC,eAkDF,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { BrowserTelemetryExporter } from "./browser-exporter";
|
|
2
|
+
export { createAvantGateClient, type AvantGateClient, type TrackSecurityAlertDetails, type TrackDataRenderedOptions, type TrackFeedbackOptions, } from "./client";
|
|
3
|
+
export { useAvantGateTelemetry } from "./useAvantGateTelemetry";
|
|
4
|
+
export type { ClientSecurityAlertEvent, ClientDataRenderedEvent, UserFeedbackEvent, ClientTelemetryEvent, BrowserTelemetryExporterConfig, ClientTelemetryIngestPayload, } from "./types";
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EACL,qBAAqB,EACrB,KAAK,eAAe,EACpB,KAAK,yBAAyB,EAC9B,KAAK,wBAAwB,EAC7B,KAAK,oBAAoB,GAC1B,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,YAAY,EACV,wBAAwB,EACxB,uBAAuB,EACvB,iBAAiB,EACjB,oBAAoB,EACpB,8BAA8B,EAC9B,4BAA4B,GAC7B,MAAM,SAAS,CAAC"}
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/client/index.ts
|
|
21
|
+
var client_exports = {};
|
|
22
|
+
__export(client_exports, {
|
|
23
|
+
BrowserTelemetryExporter: () => BrowserTelemetryExporter,
|
|
24
|
+
createAvantGateClient: () => createAvantGateClient,
|
|
25
|
+
useAvantGateTelemetry: () => useAvantGateTelemetry
|
|
26
|
+
});
|
|
27
|
+
module.exports = __toCommonJS(client_exports);
|
|
28
|
+
|
|
29
|
+
// src/client/browser-exporter.ts
|
|
30
|
+
var DEFAULT_ENDPOINT = "http://localhost:3000/api/v1/ingest/events";
|
|
31
|
+
var DEFAULT_INTERVAL_MS = 3e3;
|
|
32
|
+
var DEFAULT_MAX_BATCH_SIZE = 20;
|
|
33
|
+
var BrowserTelemetryExporter = class {
|
|
34
|
+
publicKey;
|
|
35
|
+
endpoint;
|
|
36
|
+
agentName;
|
|
37
|
+
runId;
|
|
38
|
+
batchIntervalMs;
|
|
39
|
+
maxBatchSize;
|
|
40
|
+
fetchFn;
|
|
41
|
+
onError;
|
|
42
|
+
buffer = [];
|
|
43
|
+
timer = null;
|
|
44
|
+
isFlushing = false;
|
|
45
|
+
isDestroyed = false;
|
|
46
|
+
handleVisibilityChange = () => {
|
|
47
|
+
if (typeof document !== "undefined" && document.visibilityState === "hidden") {
|
|
48
|
+
void this.flush();
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
handleBeforeUnload = () => {
|
|
52
|
+
void this.flush();
|
|
53
|
+
};
|
|
54
|
+
constructor(config) {
|
|
55
|
+
this.publicKey = config.publicKey;
|
|
56
|
+
this.endpoint = config.endpoint ?? DEFAULT_ENDPOINT;
|
|
57
|
+
this.agentName = config.agentName;
|
|
58
|
+
this.runId = config.runId;
|
|
59
|
+
this.batchIntervalMs = config.batchIntervalMs ?? DEFAULT_INTERVAL_MS;
|
|
60
|
+
this.maxBatchSize = config.maxBatchSize ?? DEFAULT_MAX_BATCH_SIZE;
|
|
61
|
+
this.fetchFn = config.fetchFn ?? (typeof fetch !== "undefined" ? fetch.bind(globalThis) : void 0);
|
|
62
|
+
this.onError = config.onError;
|
|
63
|
+
this.startTimer();
|
|
64
|
+
this.setupBrowserListeners();
|
|
65
|
+
}
|
|
66
|
+
updateContext = (context) => {
|
|
67
|
+
if (context.runId !== void 0) {
|
|
68
|
+
this.runId = context.runId;
|
|
69
|
+
}
|
|
70
|
+
if (context.agentName !== void 0) {
|
|
71
|
+
this.agentName = context.agentName;
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
getRunId = () => this.runId;
|
|
75
|
+
getAgentName = () => this.agentName;
|
|
76
|
+
startTimer() {
|
|
77
|
+
if (this.batchIntervalMs <= 0 || typeof setInterval === "undefined") {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
this.timer = setInterval(() => {
|
|
81
|
+
void this.flush();
|
|
82
|
+
}, this.batchIntervalMs);
|
|
83
|
+
}
|
|
84
|
+
setupBrowserListeners() {
|
|
85
|
+
if (typeof document !== "undefined" && typeof document.addEventListener === "function") {
|
|
86
|
+
document.addEventListener("visibilitychange", this.handleVisibilityChange);
|
|
87
|
+
}
|
|
88
|
+
if (typeof window !== "undefined" && typeof window.addEventListener === "function") {
|
|
89
|
+
window.addEventListener("beforeunload", this.handleBeforeUnload);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
emit = (event) => {
|
|
93
|
+
if (this.isDestroyed) {
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
this.buffer.push(event);
|
|
97
|
+
if (this.buffer.length >= this.maxBatchSize) {
|
|
98
|
+
void this.flush();
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
flush = async () => {
|
|
102
|
+
if (this.isFlushing || this.buffer.length === 0 || !this.fetchFn) {
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
this.isFlushing = true;
|
|
106
|
+
const batch = [...this.buffer];
|
|
107
|
+
this.buffer = [];
|
|
108
|
+
const payload = {
|
|
109
|
+
runId: this.runId,
|
|
110
|
+
agentName: this.agentName,
|
|
111
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
112
|
+
events: batch
|
|
113
|
+
};
|
|
114
|
+
try {
|
|
115
|
+
await this.dispatchPayload(payload);
|
|
116
|
+
} catch (err) {
|
|
117
|
+
this.handleFlushError(err, batch);
|
|
118
|
+
} finally {
|
|
119
|
+
this.isFlushing = false;
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
dispatchPayload = async (payload) => {
|
|
123
|
+
if (!this.fetchFn) {
|
|
124
|
+
throw new Error("No fetch implementation available in current environment");
|
|
125
|
+
}
|
|
126
|
+
const response = await this.fetchFn(this.endpoint, {
|
|
127
|
+
method: "POST",
|
|
128
|
+
headers: {
|
|
129
|
+
"Content-Type": "application/json",
|
|
130
|
+
Authorization: `Bearer ${this.publicKey}`
|
|
131
|
+
},
|
|
132
|
+
body: JSON.stringify(payload),
|
|
133
|
+
keepalive: true
|
|
134
|
+
});
|
|
135
|
+
if (!response.ok) {
|
|
136
|
+
throw new Error(`Browser telemetry ingestion failed: ${response.status} ${response.statusText}`);
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
handleFlushError = (err, failedBatch) => {
|
|
140
|
+
if (!this.isDestroyed && this.buffer.length < this.maxBatchSize * 2) {
|
|
141
|
+
this.buffer.unshift(...failedBatch);
|
|
142
|
+
}
|
|
143
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
144
|
+
if (this.onError) {
|
|
145
|
+
this.onError(error);
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
destroy = () => {
|
|
149
|
+
this.isDestroyed = true;
|
|
150
|
+
if (this.timer) {
|
|
151
|
+
clearInterval(this.timer);
|
|
152
|
+
this.timer = null;
|
|
153
|
+
}
|
|
154
|
+
if (typeof document !== "undefined" && typeof document.removeEventListener === "function") {
|
|
155
|
+
document.removeEventListener("visibilitychange", this.handleVisibilityChange);
|
|
156
|
+
}
|
|
157
|
+
if (typeof window !== "undefined" && typeof window.removeEventListener === "function") {
|
|
158
|
+
window.removeEventListener("beforeunload", this.handleBeforeUnload);
|
|
159
|
+
}
|
|
160
|
+
void this.flush();
|
|
161
|
+
};
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
// src/client/client.ts
|
|
165
|
+
var createAvantGateClient = (config) => {
|
|
166
|
+
const exporter = new BrowserTelemetryExporter(config);
|
|
167
|
+
const trackSecurityAlert = (alertType, details) => {
|
|
168
|
+
const snippet = details.snippet ?? details.matchedPatternSnippet;
|
|
169
|
+
exporter.emit({
|
|
170
|
+
type: "CLIENT_SECURITY_ALERT",
|
|
171
|
+
alertType,
|
|
172
|
+
inputLength: details.inputLength,
|
|
173
|
+
snippet,
|
|
174
|
+
matchedPatternSnippet: snippet,
|
|
175
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
176
|
+
});
|
|
177
|
+
};
|
|
178
|
+
const trackClientDataRendered = (toolId, options) => {
|
|
179
|
+
exporter.emit({
|
|
180
|
+
type: "CLIENT_DATA_RENDERED",
|
|
181
|
+
toolId,
|
|
182
|
+
channel: options?.channel,
|
|
183
|
+
renderedItemCount: options?.renderedItemCount,
|
|
184
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
185
|
+
});
|
|
186
|
+
};
|
|
187
|
+
const trackFeedback = (feedback) => {
|
|
188
|
+
exporter.emit({
|
|
189
|
+
type: "USER_FEEDBACK",
|
|
190
|
+
rating: feedback.rating,
|
|
191
|
+
feedbackTag: feedback.tag,
|
|
192
|
+
userComment: feedback.comment,
|
|
193
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
194
|
+
});
|
|
195
|
+
};
|
|
196
|
+
return {
|
|
197
|
+
trackSecurityAlert,
|
|
198
|
+
trackClientDataRendered,
|
|
199
|
+
trackFeedback,
|
|
200
|
+
updateContext: exporter.updateContext,
|
|
201
|
+
flush: exporter.flush,
|
|
202
|
+
destroy: exporter.destroy,
|
|
203
|
+
exporter
|
|
204
|
+
};
|
|
205
|
+
};
|
|
206
|
+
|
|
207
|
+
// src/client/useAvantGateTelemetry.ts
|
|
208
|
+
var import_react = require("react");
|
|
209
|
+
var useAvantGateTelemetry = (config) => {
|
|
210
|
+
const clientRef = (0, import_react.useRef)(null);
|
|
211
|
+
if (!clientRef.current) {
|
|
212
|
+
clientRef.current = createAvantGateClient(config);
|
|
213
|
+
}
|
|
214
|
+
(0, import_react.useEffect)(() => {
|
|
215
|
+
clientRef.current?.updateContext({
|
|
216
|
+
runId: config.runId,
|
|
217
|
+
agentName: config.agentName
|
|
218
|
+
});
|
|
219
|
+
}, [config.runId, config.agentName]);
|
|
220
|
+
(0, import_react.useEffect)(() => {
|
|
221
|
+
return () => {
|
|
222
|
+
clientRef.current?.destroy();
|
|
223
|
+
clientRef.current = null;
|
|
224
|
+
};
|
|
225
|
+
}, []);
|
|
226
|
+
const trackSecurityAlert = (0, import_react.useCallback)(
|
|
227
|
+
(alertType, details) => {
|
|
228
|
+
clientRef.current?.trackSecurityAlert(alertType, details);
|
|
229
|
+
},
|
|
230
|
+
[]
|
|
231
|
+
);
|
|
232
|
+
const trackClientDataRendered = (0, import_react.useCallback)(
|
|
233
|
+
(toolId, options) => {
|
|
234
|
+
clientRef.current?.trackClientDataRendered(toolId, options);
|
|
235
|
+
},
|
|
236
|
+
[]
|
|
237
|
+
);
|
|
238
|
+
const trackFeedback = (0, import_react.useCallback)(
|
|
239
|
+
(feedback) => {
|
|
240
|
+
clientRef.current?.trackFeedback(feedback);
|
|
241
|
+
},
|
|
242
|
+
[]
|
|
243
|
+
);
|
|
244
|
+
return (0, import_react.useMemo)(
|
|
245
|
+
() => ({
|
|
246
|
+
trackSecurityAlert,
|
|
247
|
+
trackClientDataRendered,
|
|
248
|
+
trackFeedback,
|
|
249
|
+
exporter: clientRef.current?.exporter
|
|
250
|
+
}),
|
|
251
|
+
[trackSecurityAlert, trackClientDataRendered, trackFeedback]
|
|
252
|
+
);
|
|
253
|
+
};
|
|
254
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
255
|
+
0 && (module.exports = {
|
|
256
|
+
BrowserTelemetryExporter,
|
|
257
|
+
createAvantGateClient,
|
|
258
|
+
useAvantGateTelemetry
|
|
259
|
+
});
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
// src/client/browser-exporter.ts
|
|
2
|
+
var DEFAULT_ENDPOINT = "http://localhost:3000/api/v1/ingest/events";
|
|
3
|
+
var DEFAULT_INTERVAL_MS = 3e3;
|
|
4
|
+
var DEFAULT_MAX_BATCH_SIZE = 20;
|
|
5
|
+
var BrowserTelemetryExporter = class {
|
|
6
|
+
publicKey;
|
|
7
|
+
endpoint;
|
|
8
|
+
agentName;
|
|
9
|
+
runId;
|
|
10
|
+
batchIntervalMs;
|
|
11
|
+
maxBatchSize;
|
|
12
|
+
fetchFn;
|
|
13
|
+
onError;
|
|
14
|
+
buffer = [];
|
|
15
|
+
timer = null;
|
|
16
|
+
isFlushing = false;
|
|
17
|
+
isDestroyed = false;
|
|
18
|
+
handleVisibilityChange = () => {
|
|
19
|
+
if (typeof document !== "undefined" && document.visibilityState === "hidden") {
|
|
20
|
+
void this.flush();
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
handleBeforeUnload = () => {
|
|
24
|
+
void this.flush();
|
|
25
|
+
};
|
|
26
|
+
constructor(config) {
|
|
27
|
+
this.publicKey = config.publicKey;
|
|
28
|
+
this.endpoint = config.endpoint ?? DEFAULT_ENDPOINT;
|
|
29
|
+
this.agentName = config.agentName;
|
|
30
|
+
this.runId = config.runId;
|
|
31
|
+
this.batchIntervalMs = config.batchIntervalMs ?? DEFAULT_INTERVAL_MS;
|
|
32
|
+
this.maxBatchSize = config.maxBatchSize ?? DEFAULT_MAX_BATCH_SIZE;
|
|
33
|
+
this.fetchFn = config.fetchFn ?? (typeof fetch !== "undefined" ? fetch.bind(globalThis) : void 0);
|
|
34
|
+
this.onError = config.onError;
|
|
35
|
+
this.startTimer();
|
|
36
|
+
this.setupBrowserListeners();
|
|
37
|
+
}
|
|
38
|
+
updateContext = (context) => {
|
|
39
|
+
if (context.runId !== void 0) {
|
|
40
|
+
this.runId = context.runId;
|
|
41
|
+
}
|
|
42
|
+
if (context.agentName !== void 0) {
|
|
43
|
+
this.agentName = context.agentName;
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
getRunId = () => this.runId;
|
|
47
|
+
getAgentName = () => this.agentName;
|
|
48
|
+
startTimer() {
|
|
49
|
+
if (this.batchIntervalMs <= 0 || typeof setInterval === "undefined") {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
this.timer = setInterval(() => {
|
|
53
|
+
void this.flush();
|
|
54
|
+
}, this.batchIntervalMs);
|
|
55
|
+
}
|
|
56
|
+
setupBrowserListeners() {
|
|
57
|
+
if (typeof document !== "undefined" && typeof document.addEventListener === "function") {
|
|
58
|
+
document.addEventListener("visibilitychange", this.handleVisibilityChange);
|
|
59
|
+
}
|
|
60
|
+
if (typeof window !== "undefined" && typeof window.addEventListener === "function") {
|
|
61
|
+
window.addEventListener("beforeunload", this.handleBeforeUnload);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
emit = (event) => {
|
|
65
|
+
if (this.isDestroyed) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
this.buffer.push(event);
|
|
69
|
+
if (this.buffer.length >= this.maxBatchSize) {
|
|
70
|
+
void this.flush();
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
flush = async () => {
|
|
74
|
+
if (this.isFlushing || this.buffer.length === 0 || !this.fetchFn) {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
this.isFlushing = true;
|
|
78
|
+
const batch = [...this.buffer];
|
|
79
|
+
this.buffer = [];
|
|
80
|
+
const payload = {
|
|
81
|
+
runId: this.runId,
|
|
82
|
+
agentName: this.agentName,
|
|
83
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
84
|
+
events: batch
|
|
85
|
+
};
|
|
86
|
+
try {
|
|
87
|
+
await this.dispatchPayload(payload);
|
|
88
|
+
} catch (err) {
|
|
89
|
+
this.handleFlushError(err, batch);
|
|
90
|
+
} finally {
|
|
91
|
+
this.isFlushing = false;
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
dispatchPayload = async (payload) => {
|
|
95
|
+
if (!this.fetchFn) {
|
|
96
|
+
throw new Error("No fetch implementation available in current environment");
|
|
97
|
+
}
|
|
98
|
+
const response = await this.fetchFn(this.endpoint, {
|
|
99
|
+
method: "POST",
|
|
100
|
+
headers: {
|
|
101
|
+
"Content-Type": "application/json",
|
|
102
|
+
Authorization: `Bearer ${this.publicKey}`
|
|
103
|
+
},
|
|
104
|
+
body: JSON.stringify(payload),
|
|
105
|
+
keepalive: true
|
|
106
|
+
});
|
|
107
|
+
if (!response.ok) {
|
|
108
|
+
throw new Error(`Browser telemetry ingestion failed: ${response.status} ${response.statusText}`);
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
handleFlushError = (err, failedBatch) => {
|
|
112
|
+
if (!this.isDestroyed && this.buffer.length < this.maxBatchSize * 2) {
|
|
113
|
+
this.buffer.unshift(...failedBatch);
|
|
114
|
+
}
|
|
115
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
116
|
+
if (this.onError) {
|
|
117
|
+
this.onError(error);
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
destroy = () => {
|
|
121
|
+
this.isDestroyed = true;
|
|
122
|
+
if (this.timer) {
|
|
123
|
+
clearInterval(this.timer);
|
|
124
|
+
this.timer = null;
|
|
125
|
+
}
|
|
126
|
+
if (typeof document !== "undefined" && typeof document.removeEventListener === "function") {
|
|
127
|
+
document.removeEventListener("visibilitychange", this.handleVisibilityChange);
|
|
128
|
+
}
|
|
129
|
+
if (typeof window !== "undefined" && typeof window.removeEventListener === "function") {
|
|
130
|
+
window.removeEventListener("beforeunload", this.handleBeforeUnload);
|
|
131
|
+
}
|
|
132
|
+
void this.flush();
|
|
133
|
+
};
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
// src/client/client.ts
|
|
137
|
+
var createAvantGateClient = (config) => {
|
|
138
|
+
const exporter = new BrowserTelemetryExporter(config);
|
|
139
|
+
const trackSecurityAlert = (alertType, details) => {
|
|
140
|
+
const snippet = details.snippet ?? details.matchedPatternSnippet;
|
|
141
|
+
exporter.emit({
|
|
142
|
+
type: "CLIENT_SECURITY_ALERT",
|
|
143
|
+
alertType,
|
|
144
|
+
inputLength: details.inputLength,
|
|
145
|
+
snippet,
|
|
146
|
+
matchedPatternSnippet: snippet,
|
|
147
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
148
|
+
});
|
|
149
|
+
};
|
|
150
|
+
const trackClientDataRendered = (toolId, options) => {
|
|
151
|
+
exporter.emit({
|
|
152
|
+
type: "CLIENT_DATA_RENDERED",
|
|
153
|
+
toolId,
|
|
154
|
+
channel: options?.channel,
|
|
155
|
+
renderedItemCount: options?.renderedItemCount,
|
|
156
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
157
|
+
});
|
|
158
|
+
};
|
|
159
|
+
const trackFeedback = (feedback) => {
|
|
160
|
+
exporter.emit({
|
|
161
|
+
type: "USER_FEEDBACK",
|
|
162
|
+
rating: feedback.rating,
|
|
163
|
+
feedbackTag: feedback.tag,
|
|
164
|
+
userComment: feedback.comment,
|
|
165
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
166
|
+
});
|
|
167
|
+
};
|
|
168
|
+
return {
|
|
169
|
+
trackSecurityAlert,
|
|
170
|
+
trackClientDataRendered,
|
|
171
|
+
trackFeedback,
|
|
172
|
+
updateContext: exporter.updateContext,
|
|
173
|
+
flush: exporter.flush,
|
|
174
|
+
destroy: exporter.destroy,
|
|
175
|
+
exporter
|
|
176
|
+
};
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
// src/client/useAvantGateTelemetry.ts
|
|
180
|
+
import { useRef, useEffect, useCallback, useMemo } from "react";
|
|
181
|
+
var useAvantGateTelemetry = (config) => {
|
|
182
|
+
const clientRef = useRef(null);
|
|
183
|
+
if (!clientRef.current) {
|
|
184
|
+
clientRef.current = createAvantGateClient(config);
|
|
185
|
+
}
|
|
186
|
+
useEffect(() => {
|
|
187
|
+
clientRef.current?.updateContext({
|
|
188
|
+
runId: config.runId,
|
|
189
|
+
agentName: config.agentName
|
|
190
|
+
});
|
|
191
|
+
}, [config.runId, config.agentName]);
|
|
192
|
+
useEffect(() => {
|
|
193
|
+
return () => {
|
|
194
|
+
clientRef.current?.destroy();
|
|
195
|
+
clientRef.current = null;
|
|
196
|
+
};
|
|
197
|
+
}, []);
|
|
198
|
+
const trackSecurityAlert = useCallback(
|
|
199
|
+
(alertType, details) => {
|
|
200
|
+
clientRef.current?.trackSecurityAlert(alertType, details);
|
|
201
|
+
},
|
|
202
|
+
[]
|
|
203
|
+
);
|
|
204
|
+
const trackClientDataRendered = useCallback(
|
|
205
|
+
(toolId, options) => {
|
|
206
|
+
clientRef.current?.trackClientDataRendered(toolId, options);
|
|
207
|
+
},
|
|
208
|
+
[]
|
|
209
|
+
);
|
|
210
|
+
const trackFeedback = useCallback(
|
|
211
|
+
(feedback) => {
|
|
212
|
+
clientRef.current?.trackFeedback(feedback);
|
|
213
|
+
},
|
|
214
|
+
[]
|
|
215
|
+
);
|
|
216
|
+
return useMemo(
|
|
217
|
+
() => ({
|
|
218
|
+
trackSecurityAlert,
|
|
219
|
+
trackClientDataRendered,
|
|
220
|
+
trackFeedback,
|
|
221
|
+
exporter: clientRef.current?.exporter
|
|
222
|
+
}),
|
|
223
|
+
[trackSecurityAlert, trackClientDataRendered, trackFeedback]
|
|
224
|
+
);
|
|
225
|
+
};
|
|
226
|
+
export {
|
|
227
|
+
BrowserTelemetryExporter,
|
|
228
|
+
createAvantGateClient,
|
|
229
|
+
useAvantGateTelemetry
|
|
230
|
+
};
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Client Security Alert Event emitted when a local pre-flight guardrail detects an anomaly
|
|
3
|
+
* (prompt injection attempt, hardcoded API key, unredacted PII) before network egress.
|
|
4
|
+
*/
|
|
5
|
+
export interface ClientSecurityAlertEvent {
|
|
6
|
+
type: "CLIENT_SECURITY_ALERT";
|
|
7
|
+
alertType: "POTENTIAL_PROMPT_INJECTION" | "SUSPECTED_SECRET_INPUT" | "SUSPECTED_PII_INPUT";
|
|
8
|
+
inputLength: number;
|
|
9
|
+
snippet?: string;
|
|
10
|
+
matchedPatternSnippet?: string;
|
|
11
|
+
timestamp: string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Client Data Rendered Event emitted when tool output or stream chunks are rendered in UI.
|
|
15
|
+
*/
|
|
16
|
+
export interface ClientDataRenderedEvent {
|
|
17
|
+
type: "CLIENT_DATA_RENDERED";
|
|
18
|
+
toolId: string;
|
|
19
|
+
channel?: "SOCKET" | "STREAM" | "HTTP";
|
|
20
|
+
renderedItemCount?: number;
|
|
21
|
+
timestamp: string;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* User Feedback Event emitted when a user rates or comments on an agent response.
|
|
25
|
+
*/
|
|
26
|
+
export interface UserFeedbackEvent {
|
|
27
|
+
type: "USER_FEEDBACK";
|
|
28
|
+
rating: "POSITIVE" | "NEGATIVE";
|
|
29
|
+
feedbackTag?: "HELPFUL" | "INACCURATE" | "UNSAFE" | "OFF_TOPIC";
|
|
30
|
+
userComment?: string;
|
|
31
|
+
timestamp: string;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Union of all supported front-end client telemetry events.
|
|
35
|
+
*/
|
|
36
|
+
export type ClientTelemetryEvent = ClientSecurityAlertEvent | ClientDataRenderedEvent | UserFeedbackEvent;
|
|
37
|
+
/**
|
|
38
|
+
* Configuration options for BrowserTelemetryExporter.
|
|
39
|
+
*/
|
|
40
|
+
export interface BrowserTelemetryExporterConfig {
|
|
41
|
+
publicKey: string;
|
|
42
|
+
endpoint?: string;
|
|
43
|
+
agentName?: string;
|
|
44
|
+
runId?: string;
|
|
45
|
+
batchIntervalMs?: number;
|
|
46
|
+
maxBatchSize?: number;
|
|
47
|
+
fetchFn?: typeof fetch;
|
|
48
|
+
onError?: (error: Error) => void;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Ingest payload format expected by POST /api/v1/ingest/events according to DESIGN-019.
|
|
52
|
+
*/
|
|
53
|
+
export interface ClientTelemetryIngestPayload {
|
|
54
|
+
runId?: string;
|
|
55
|
+
agentName?: string;
|
|
56
|
+
timestamp: string;
|
|
57
|
+
events: ClientTelemetryEvent[];
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/client/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,uBAAuB,CAAC;IAC9B,SAAS,EAAE,4BAA4B,GAAG,wBAAwB,GAAG,qBAAqB,CAAC;IAC3F,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,sBAAsB,CAAC;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAAC;IACvC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,eAAe,CAAC;IACtB,MAAM,EAAE,UAAU,GAAG,UAAU,CAAC;IAChC,WAAW,CAAC,EAAE,SAAS,GAAG,YAAY,GAAG,QAAQ,GAAG,WAAW,CAAC;IAChE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAC5B,wBAAwB,GACxB,uBAAuB,GACvB,iBAAiB,CAAC;AAEtB;;GAEG;AACH,MAAM,WAAW,8BAA8B;IAC7C,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,OAAO,KAAK,CAAC;IACvB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAClC;AAED;;GAEG;AACH,MAAM,WAAW,4BAA4B;IAC3C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,oBAAoB,EAAE,CAAC;CAChC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type TrackSecurityAlertDetails, type TrackDataRenderedOptions, type TrackFeedbackOptions } from "./client";
|
|
2
|
+
import type { BrowserTelemetryExporterConfig, ClientSecurityAlertEvent } from "./types";
|
|
3
|
+
export type { TrackSecurityAlertDetails, TrackDataRenderedOptions, TrackFeedbackOptions, };
|
|
4
|
+
/**
|
|
5
|
+
* Lightweight React Hook for front-end telemetry and client-side security event tracking.
|
|
6
|
+
* Encapsulates lifecycle management, useRef persistence, useCallback and useMemo optimization.
|
|
7
|
+
*/
|
|
8
|
+
export declare const useAvantGateTelemetry: (config: BrowserTelemetryExporterConfig) => {
|
|
9
|
+
trackSecurityAlert: (alertType: ClientSecurityAlertEvent["alertType"], details: TrackSecurityAlertDetails) => void;
|
|
10
|
+
trackClientDataRendered: (toolId: string, options?: TrackDataRenderedOptions) => void;
|
|
11
|
+
trackFeedback: (feedback: TrackFeedbackOptions) => void;
|
|
12
|
+
exporter: import("./browser-exporter").BrowserTelemetryExporter | undefined;
|
|
13
|
+
};
|
|
14
|
+
//# sourceMappingURL=useAvantGateTelemetry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useAvantGateTelemetry.d.ts","sourceRoot":"","sources":["../../src/client/useAvantGateTelemetry.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,KAAK,yBAAyB,EAC9B,KAAK,wBAAwB,EAC7B,KAAK,oBAAoB,EAC1B,MAAM,UAAU,CAAC;AAClB,OAAO,KAAK,EACV,8BAA8B,EAC9B,wBAAwB,EACzB,MAAM,SAAS,CAAC;AAEjB,YAAY,EACV,yBAAyB,EACzB,wBAAwB,EACxB,oBAAoB,GACrB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,qBAAqB,GAAI,QAAQ,8BAA8B;oCAuB3D,wBAAwB,CAAC,WAAW,CAAC,WACvC,yBAAyB,KACjC,IAAI;sCAQG,MAAM,YACJ,wBAAwB,KACjC,IAAI;8BAOI,oBAAoB,KAAG,IAAI;;CAezC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "avantgate",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.1",
|
|
4
4
|
"description": "Zero-infrastructure, in-process AI Application Firewall (AI-WAF) & privacy control plane for TypeScript: real-time prompt guardrails, zero-egress PII redaction, agent tool isolation, anti-IDOR defense, pre-flight token budgets, and multi-model failover.",
|
|
5
|
-
"author": "
|
|
5
|
+
"author": "Gatewall Team",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"keywords": [
|
|
8
8
|
"avantgate",
|
|
9
|
+
"gatewall",
|
|
9
10
|
"ai-waf",
|
|
10
11
|
"guardrails",
|
|
11
12
|
"prompt-injection",
|
|
@@ -59,21 +60,41 @@
|
|
|
59
60
|
"import": "./dist/workflow/index.mjs",
|
|
60
61
|
"require": "./dist/workflow/index.js"
|
|
61
62
|
},
|
|
63
|
+
"./client": {
|
|
64
|
+
"types": "./dist/client/index.d.ts",
|
|
65
|
+
"import": "./dist/client/index.mjs",
|
|
66
|
+
"require": "./dist/client/index.js"
|
|
67
|
+
},
|
|
62
68
|
"./package.json": "./package.json"
|
|
63
69
|
},
|
|
70
|
+
"peerDependencies": {
|
|
71
|
+
"react": ">=18.0.0"
|
|
72
|
+
},
|
|
73
|
+
"peerDependenciesMeta": {
|
|
74
|
+
"react": {
|
|
75
|
+
"optional": true
|
|
76
|
+
}
|
|
77
|
+
},
|
|
64
78
|
"files": [
|
|
65
79
|
"dist",
|
|
66
80
|
"README.md",
|
|
67
81
|
"LICENSE"
|
|
68
82
|
],
|
|
69
83
|
"scripts": {
|
|
70
|
-
"build": "tsup src/index.ts src/finance/index.ts src/agent/index.ts src/workflow/index.ts --format cjs --format esm --clean && tsc --emitDeclarationOnly --outDir dist",
|
|
71
|
-
"test": "tsx tests/avantgate.test.ts && tsx tests/preflight-budget.test.ts && tsx tests/financial-normalizer.test.ts && tsx tests/prompt-builder.test.ts && tsx tests/pii-extended.test.ts && npm run test:agent && npm run test:workflow",
|
|
84
|
+
"build": "tsup src/index.ts src/finance/index.ts src/agent/index.ts src/workflow/index.ts src/client/index.ts --format cjs --format esm --clean && tsc --emitDeclarationOnly --outDir dist",
|
|
85
|
+
"test": "tsx tests/avantgate.test.ts && tsx tests/preflight-budget.test.ts && tsx tests/financial-normalizer.test.ts && tsx tests/prompt-builder.test.ts && tsx tests/pii-extended.test.ts && npm run test:agent && npm run test:workflow && npm run test:client",
|
|
72
86
|
"test:finance": "tsx tests/financial-normalizer.test.ts",
|
|
73
87
|
"test:prompts": "tsx tests/prompt-builder.test.ts",
|
|
74
88
|
"test:pii": "tsx tests/pii-extended.test.ts",
|
|
75
89
|
"test:agent": "tsx tests/agent/step-runner.test.ts && tsx tests/agent/isolated-tool.test.ts && tsx tests/agent/dto-pattern.test.ts && tsx tests/agent/tool-patterns.test.ts && tsx tests/agent/storage-adapters.test.ts && tsx tests/agent/tool-aliasing.test.ts && tsx tests/agent/tool-chaining.test.ts && tsx tests/agent/tool-storage.test.ts && tsx tests/agent/telemetry-exporter.test.ts && tsx tests/agent/platform-adapter.test.ts && tsx tests/agent/tool-governance.test.ts && tsx tests/agent/tool-impact.test.ts",
|
|
76
90
|
"test:workflow": "tsx tests/workflow/workflow-saga.test.ts && tsx tests/workflow/workflow-abort.test.ts",
|
|
91
|
+
"test:client": "tsx tests/client/browser-exporter.test.ts",
|
|
92
|
+
"test:demo": "tsx tests/agent/prospect-ai-demo-scenario.test.ts",
|
|
93
|
+
"gatewall": "npm --prefix gatewall run dev",
|
|
94
|
+
"gatewall:dev": "npm --prefix gatewall run dev",
|
|
95
|
+
"gatewall:build": "npm --prefix gatewall run build",
|
|
96
|
+
"gatewall:start": "npm --prefix gatewall run start",
|
|
97
|
+
"gatewall:docker": "docker compose up -d",
|
|
77
98
|
"lint": "tsc --noEmit",
|
|
78
99
|
"prepublishOnly": "npm run build && npm test"
|
|
79
100
|
},
|
|
@@ -81,11 +102,21 @@
|
|
|
81
102
|
"zod": "^3.23.0 || ^4.0.0"
|
|
82
103
|
},
|
|
83
104
|
"devDependencies": {
|
|
105
|
+
"@types/react": "^18.3.18",
|
|
106
|
+
"react": "^18.3.1",
|
|
84
107
|
"tsup": "^8.3.5",
|
|
85
108
|
"tsx": "^4.19.0",
|
|
86
109
|
"typescript": "^5.4.0"
|
|
87
110
|
},
|
|
88
111
|
"publishConfig": {
|
|
89
112
|
"access": "public"
|
|
113
|
+
},
|
|
114
|
+
"repository": {
|
|
115
|
+
"type": "git",
|
|
116
|
+
"url": "git+https://github.com/thienban/avantGate.git"
|
|
117
|
+
},
|
|
118
|
+
"homepage": "https://github.com/thienban/avantGate#readme",
|
|
119
|
+
"bugs": {
|
|
120
|
+
"url": "https://github.com/thienban/avantGate/issues"
|
|
90
121
|
}
|
|
91
122
|
}
|