@supportbridge/sdk 0.8.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/CHANGELOG.md +73 -0
- package/LICENSE +13 -0
- package/README.md +326 -0
- package/SECURITY.md +26 -0
- package/dist/agent.d.ts +9 -0
- package/dist/agent.d.ts.map +1 -0
- package/dist/agent.js +73 -0
- package/dist/agent.js.map +1 -0
- package/dist/client.d.ts +68 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +254 -0
- package/dist/client.js.map +1 -0
- package/dist/context.d.ts +4 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +9 -0
- package/dist/context.js.map +1 -0
- package/dist/control-plane.d.ts +37 -0
- package/dist/control-plane.d.ts.map +1 -0
- package/dist/control-plane.js +43 -0
- package/dist/control-plane.js.map +1 -0
- package/dist/doctor.d.ts +17 -0
- package/dist/doctor.d.ts.map +1 -0
- package/dist/doctor.js +49 -0
- package/dist/doctor.js.map +1 -0
- package/dist/index.d.ts +30 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -0
- package/dist/install.d.ts +42 -0
- package/dist/install.d.ts.map +1 -0
- package/dist/install.js +215 -0
- package/dist/install.js.map +1 -0
- package/dist/mcp-app.d.ts +50 -0
- package/dist/mcp-app.d.ts.map +1 -0
- package/dist/mcp-app.js +44 -0
- package/dist/mcp-app.js.map +1 -0
- package/dist/mcp.d.ts +44 -0
- package/dist/mcp.d.ts.map +1 -0
- package/dist/mcp.js +117 -0
- package/dist/mcp.js.map +1 -0
- package/dist/offer-app.d.ts +41 -0
- package/dist/offer-app.d.ts.map +1 -0
- package/dist/offer-app.js +21 -0
- package/dist/offer-app.js.map +1 -0
- package/dist/policy-app.d.ts +41 -0
- package/dist/policy-app.d.ts.map +1 -0
- package/dist/policy-app.js +49 -0
- package/dist/policy-app.js.map +1 -0
- package/dist/policy-store.d.ts +79 -0
- package/dist/policy-store.d.ts.map +1 -0
- package/dist/policy-store.js +137 -0
- package/dist/policy-store.js.map +1 -0
- package/dist/policy.d.ts +226 -0
- package/dist/policy.d.ts.map +1 -0
- package/dist/policy.js +420 -0
- package/dist/policy.js.map +1 -0
- package/dist/sanitize.d.ts +9 -0
- package/dist/sanitize.d.ts.map +1 -0
- package/dist/sanitize.js +83 -0
- package/dist/sanitize.js.map +1 -0
- package/dist/state.d.ts +31 -0
- package/dist/state.d.ts.map +1 -0
- package/dist/state.js +29 -0
- package/dist/state.js.map +1 -0
- package/dist/transport.d.ts +57 -0
- package/dist/transport.d.ts.map +1 -0
- package/dist/transport.js +132 -0
- package/dist/transport.js.map +1 -0
- package/dist/triggers.d.ts +19 -0
- package/dist/triggers.d.ts.map +1 -0
- package/dist/triggers.js +132 -0
- package/dist/triggers.js.map +1 -0
- package/dist/types.d.ts +221 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/docs/policy-engine.md +47 -0
- package/docs/telemetry-contract.md +29 -0
- package/package.json +53 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sanitize.js","sourceRoot":"","sources":["../src/sanitize.ts"],"names":[],"mappings":"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"}
|
package/dist/state.d.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { SupportDecision, SupportIdentity } from "./types.js";
|
|
2
|
+
export interface TriggerState {
|
|
3
|
+
triggerId: string;
|
|
4
|
+
scopeKey: string;
|
|
5
|
+
status: "pending" | SupportDecision;
|
|
6
|
+
updatedAt: string;
|
|
7
|
+
reason?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface FailureRecord {
|
|
10
|
+
toolName: string;
|
|
11
|
+
errorCode?: string;
|
|
12
|
+
at: number;
|
|
13
|
+
}
|
|
14
|
+
export interface TriggerStateStore {
|
|
15
|
+
get(triggerId: string, scopeKey: string): Promise<TriggerState | undefined>;
|
|
16
|
+
set(state: TriggerState): Promise<void>;
|
|
17
|
+
delete(triggerId: string, scopeKey: string): Promise<void>;
|
|
18
|
+
addFailure(scopeKey: string, failure: FailureRecord): Promise<void>;
|
|
19
|
+
failures(scopeKey: string, since: number): Promise<FailureRecord[]>;
|
|
20
|
+
}
|
|
21
|
+
export declare class MemoryTriggerStateStore implements TriggerStateStore {
|
|
22
|
+
private readonly states;
|
|
23
|
+
private readonly failureMap;
|
|
24
|
+
get(triggerId: string, scopeKey: string): Promise<TriggerState | undefined>;
|
|
25
|
+
set(state: TriggerState): Promise<void>;
|
|
26
|
+
delete(triggerId: string, scopeKey: string): Promise<void>;
|
|
27
|
+
addFailure(scopeKey: string, failure: FailureRecord): Promise<void>;
|
|
28
|
+
failures(scopeKey: string, since: number): Promise<FailureRecord[]>;
|
|
29
|
+
}
|
|
30
|
+
export declare function identityKey(identity: SupportIdentity | undefined): string;
|
|
31
|
+
//# sourceMappingURL=state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAEnE,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,SAAS,GAAG,eAAe,CAAC;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,iBAAiB;IAChC,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC,CAAC;IAC5E,GAAG,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxC,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3D,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpE,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC;CACrE;AAED,qBAAa,uBAAwB,YAAW,iBAAiB;IAC/D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAmC;IAC1D,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAsC;IAE3D,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC;IAK3E,GAAG,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAIvC,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI1D,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAOnE,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;CAG1E;AAED,wBAAgB,WAAW,CAAC,QAAQ,EAAE,eAAe,GAAG,SAAS,GAAG,MAAM,CAGzE"}
|
package/dist/state.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export class MemoryTriggerStateStore {
|
|
2
|
+
states = new Map();
|
|
3
|
+
failureMap = new Map();
|
|
4
|
+
async get(triggerId, scopeKey) {
|
|
5
|
+
const state = this.states.get(`${triggerId}:${scopeKey}`);
|
|
6
|
+
return state ? structuredClone(state) : undefined;
|
|
7
|
+
}
|
|
8
|
+
async set(state) {
|
|
9
|
+
this.states.set(`${state.triggerId}:${state.scopeKey}`, structuredClone(state));
|
|
10
|
+
}
|
|
11
|
+
async delete(triggerId, scopeKey) {
|
|
12
|
+
this.states.delete(`${triggerId}:${scopeKey}`);
|
|
13
|
+
}
|
|
14
|
+
async addFailure(scopeKey, failure) {
|
|
15
|
+
const list = this.failureMap.get(scopeKey) ?? [];
|
|
16
|
+
list.push(structuredClone(failure));
|
|
17
|
+
const cutoff = Date.now() - 24 * 60 * 60_000;
|
|
18
|
+
this.failureMap.set(scopeKey, list.filter(item => item.at >= cutoff));
|
|
19
|
+
}
|
|
20
|
+
async failures(scopeKey, since) {
|
|
21
|
+
return (this.failureMap.get(scopeKey) ?? []).filter(item => item.at >= since).map(item => structuredClone(item));
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
export function identityKey(identity) {
|
|
25
|
+
if (!identity?.userId)
|
|
26
|
+
return "anonymous";
|
|
27
|
+
return `${identity.tenantId ?? "-"}:${identity.workspaceId ?? "-"}:${identity.userId}`;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.js","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"AAwBA,MAAM,OAAO,uBAAuB;IACjB,MAAM,GAAG,IAAI,GAAG,EAAwB,CAAC;IACzC,UAAU,GAAG,IAAI,GAAG,EAA2B,CAAC;IAEjE,KAAK,CAAC,GAAG,CAAC,SAAiB,EAAE,QAAgB;QAC3C,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,SAAS,IAAI,QAAQ,EAAE,CAAC,CAAC;QAC1D,OAAO,KAAK,CAAC,CAAC,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACpD,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,KAAmB;QAC3B,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,SAAS,IAAI,KAAK,CAAC,QAAQ,EAAE,EAAE,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC;IAClF,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,SAAiB,EAAE,QAAgB;QAC9C,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,SAAS,IAAI,QAAQ,EAAE,CAAC,CAAC;IACjD,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,QAAgB,EAAE,OAAsB;QACvD,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;QACjD,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC;QACpC,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,MAAM,CAAC;QAC7C,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,IAAI,MAAM,CAAC,CAAC,CAAC;IACxE,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,QAAgB,EAAE,KAAa;QAC5C,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,IAAI,KAAK,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC;IACnH,CAAC;CACF;AAED,MAAM,UAAU,WAAW,CAAC,QAAqC;IAC/D,IAAI,CAAC,QAAQ,EAAE,MAAM;QAAE,OAAO,WAAW,CAAC;IAC1C,OAAO,GAAG,QAAQ,CAAC,QAAQ,IAAI,GAAG,IAAI,QAAQ,CAAC,WAAW,IAAI,GAAG,IAAI,QAAQ,CAAC,MAAM,EAAE,CAAC;AACzF,CAAC"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type { TelemetryEvent } from "./types.js";
|
|
2
|
+
export interface TelemetryTransport {
|
|
3
|
+
send(events: readonly TelemetryEvent[], signal?: AbortSignal): Promise<void>;
|
|
4
|
+
close?(): Promise<void>;
|
|
5
|
+
}
|
|
6
|
+
export interface HttpTransportOptions {
|
|
7
|
+
endpoint: string;
|
|
8
|
+
apiKey: string;
|
|
9
|
+
headers?: Record<string, string>;
|
|
10
|
+
timeoutMs?: number;
|
|
11
|
+
fetch?: typeof globalThis.fetch;
|
|
12
|
+
}
|
|
13
|
+
export declare class HttpTelemetryTransport implements TelemetryTransport {
|
|
14
|
+
private readonly options;
|
|
15
|
+
private readonly endpoint;
|
|
16
|
+
private readonly timeoutMs;
|
|
17
|
+
private readonly fetchImpl;
|
|
18
|
+
constructor(options: HttpTransportOptions);
|
|
19
|
+
send(events: readonly TelemetryEvent[], signal?: AbortSignal): Promise<void>;
|
|
20
|
+
}
|
|
21
|
+
export declare class MemoryTelemetryTransport implements TelemetryTransport {
|
|
22
|
+
readonly batches: TelemetryEvent[][];
|
|
23
|
+
failWith?: Error;
|
|
24
|
+
send(events: readonly TelemetryEvent[]): Promise<void>;
|
|
25
|
+
get events(): TelemetryEvent[];
|
|
26
|
+
}
|
|
27
|
+
export interface BufferedTransportOptions {
|
|
28
|
+
batchSize?: number;
|
|
29
|
+
flushIntervalMs?: number;
|
|
30
|
+
maxQueueSize?: number;
|
|
31
|
+
maxRetries?: number;
|
|
32
|
+
retryBaseMs?: number;
|
|
33
|
+
onDrop?: (count: number) => void;
|
|
34
|
+
onError?: (error: unknown) => void;
|
|
35
|
+
}
|
|
36
|
+
export declare class BufferedTelemetryTransport {
|
|
37
|
+
private readonly transport;
|
|
38
|
+
private readonly options;
|
|
39
|
+
private queue;
|
|
40
|
+
private timer;
|
|
41
|
+
private flushing;
|
|
42
|
+
private closed;
|
|
43
|
+
private readonly batchSize;
|
|
44
|
+
private readonly flushIntervalMs;
|
|
45
|
+
private readonly maxQueueSize;
|
|
46
|
+
private readonly maxRetries;
|
|
47
|
+
private readonly retryBaseMs;
|
|
48
|
+
constructor(transport: TelemetryTransport, options?: BufferedTransportOptions);
|
|
49
|
+
enqueue(event: TelemetryEvent): void;
|
|
50
|
+
flush(): Promise<void>;
|
|
51
|
+
close(): Promise<void>;
|
|
52
|
+
get pendingCount(): number;
|
|
53
|
+
private drain;
|
|
54
|
+
private schedule;
|
|
55
|
+
private clearTimer;
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=transport.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,MAAM,WAAW,kBAAkB;IACjC,IAAI,CAAC,MAAM,EAAE,SAAS,cAAc,EAAE,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7E,KAAK,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACzB;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;CACjC;AAED,qBAAa,sBAAuB,YAAW,kBAAkB;IAKnD,OAAO,CAAC,QAAQ,CAAC,OAAO;IAJpC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA0B;gBAEvB,OAAO,EAAE,oBAAoB;IAOpD,IAAI,CAAC,MAAM,EAAE,SAAS,cAAc,EAAE,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;CAiBnF;AAED,qBAAa,wBAAyB,YAAW,kBAAkB;IACjE,QAAQ,CAAC,OAAO,EAAE,cAAc,EAAE,EAAE,CAAM;IAC1C,QAAQ,CAAC,EAAE,KAAK,CAAC;IAEX,IAAI,CAAC,MAAM,EAAE,SAAS,cAAc,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAK5D,IAAI,MAAM,IAAI,cAAc,EAAE,CAAgC;CAC/D;AAED,MAAM,WAAW,wBAAwB;IACvC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;CACpC;AAED,qBAAa,0BAA0B;IAWzB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAAsB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAVpF,OAAO,CAAC,KAAK,CAAwB;IACrC,OAAO,CAAC,KAAK,CAA4C;IACzD,OAAO,CAAC,QAAQ,CAA4B;IAC5C,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IACzC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;gBAER,SAAS,EAAE,kBAAkB,EAAmB,OAAO,GAAE,wBAA6B;IAQnH,OAAO,CAAC,KAAK,EAAE,cAAc,GAAG,IAAI;IAY9B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAUtB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAO5B,IAAI,YAAY,IAAI,MAAM,CAA8B;YAE1C,KAAK;IAmBnB,OAAO,CAAC,QAAQ;IAKhB,OAAO,CAAC,UAAU;CAInB"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
export class HttpTelemetryTransport {
|
|
2
|
+
options;
|
|
3
|
+
endpoint;
|
|
4
|
+
timeoutMs;
|
|
5
|
+
fetchImpl;
|
|
6
|
+
constructor(options) {
|
|
7
|
+
this.options = options;
|
|
8
|
+
this.endpoint = options.endpoint.replace(/\/$/, "");
|
|
9
|
+
this.timeoutMs = options.timeoutMs ?? 5_000;
|
|
10
|
+
this.fetchImpl = options.fetch ?? globalThis.fetch;
|
|
11
|
+
if (!this.fetchImpl)
|
|
12
|
+
throw new Error("A fetch implementation is required");
|
|
13
|
+
}
|
|
14
|
+
async send(events, signal) {
|
|
15
|
+
if (!events.length)
|
|
16
|
+
return;
|
|
17
|
+
const timeout = AbortSignal.timeout(this.timeoutMs);
|
|
18
|
+
const combined = signal ? AbortSignal.any([signal, timeout]) : timeout;
|
|
19
|
+
const response = await this.fetchImpl(`${this.endpoint}/v1/telemetry/batch`, {
|
|
20
|
+
method: "POST",
|
|
21
|
+
headers: {
|
|
22
|
+
"content-type": "application/json",
|
|
23
|
+
authorization: `Bearer ${this.options.apiKey}`,
|
|
24
|
+
"user-agent": "supportbridge-sdk/0.1.0",
|
|
25
|
+
...this.options.headers
|
|
26
|
+
},
|
|
27
|
+
body: JSON.stringify({ events }),
|
|
28
|
+
signal: combined
|
|
29
|
+
});
|
|
30
|
+
if (!response.ok)
|
|
31
|
+
throw new Error(`SupportBridge telemetry delivery failed (${response.status})`);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
export class MemoryTelemetryTransport {
|
|
35
|
+
batches = [];
|
|
36
|
+
failWith;
|
|
37
|
+
async send(events) {
|
|
38
|
+
if (this.failWith)
|
|
39
|
+
throw this.failWith;
|
|
40
|
+
this.batches.push(events.map(event => structuredClone(event)));
|
|
41
|
+
}
|
|
42
|
+
get events() { return this.batches.flat(); }
|
|
43
|
+
}
|
|
44
|
+
export class BufferedTelemetryTransport {
|
|
45
|
+
transport;
|
|
46
|
+
options;
|
|
47
|
+
queue = [];
|
|
48
|
+
timer;
|
|
49
|
+
flushing;
|
|
50
|
+
closed = false;
|
|
51
|
+
batchSize;
|
|
52
|
+
flushIntervalMs;
|
|
53
|
+
maxQueueSize;
|
|
54
|
+
maxRetries;
|
|
55
|
+
retryBaseMs;
|
|
56
|
+
constructor(transport, options = {}) {
|
|
57
|
+
this.transport = transport;
|
|
58
|
+
this.options = options;
|
|
59
|
+
this.batchSize = options.batchSize ?? 20;
|
|
60
|
+
this.flushIntervalMs = options.flushIntervalMs ?? 1_000;
|
|
61
|
+
this.maxQueueSize = options.maxQueueSize ?? 1_000;
|
|
62
|
+
this.maxRetries = options.maxRetries ?? 2;
|
|
63
|
+
this.retryBaseMs = options.retryBaseMs ?? 100;
|
|
64
|
+
}
|
|
65
|
+
enqueue(event) {
|
|
66
|
+
if (this.closed)
|
|
67
|
+
return;
|
|
68
|
+
this.queue.push(event);
|
|
69
|
+
if (this.queue.length > this.maxQueueSize) {
|
|
70
|
+
const dropped = this.queue.length - this.maxQueueSize;
|
|
71
|
+
this.queue.splice(0, dropped);
|
|
72
|
+
this.options.onDrop?.(dropped);
|
|
73
|
+
}
|
|
74
|
+
if (this.queue.length >= this.batchSize)
|
|
75
|
+
void this.flush();
|
|
76
|
+
else
|
|
77
|
+
this.schedule();
|
|
78
|
+
}
|
|
79
|
+
async flush() {
|
|
80
|
+
if (this.flushing)
|
|
81
|
+
return this.flushing;
|
|
82
|
+
this.clearTimer();
|
|
83
|
+
this.flushing = this.drain().finally(() => {
|
|
84
|
+
this.flushing = undefined;
|
|
85
|
+
if (this.queue.length && !this.closed)
|
|
86
|
+
this.schedule();
|
|
87
|
+
});
|
|
88
|
+
return this.flushing;
|
|
89
|
+
}
|
|
90
|
+
async close() {
|
|
91
|
+
this.closed = true;
|
|
92
|
+
this.clearTimer();
|
|
93
|
+
await this.flush();
|
|
94
|
+
await this.transport.close?.();
|
|
95
|
+
}
|
|
96
|
+
get pendingCount() { return this.queue.length; }
|
|
97
|
+
async drain() {
|
|
98
|
+
while (this.queue.length) {
|
|
99
|
+
const batch = this.queue.splice(0, this.batchSize);
|
|
100
|
+
let delivered = false;
|
|
101
|
+
for (let attempt = 0; attempt <= this.maxRetries; attempt += 1) {
|
|
102
|
+
try {
|
|
103
|
+
await this.transport.send(batch);
|
|
104
|
+
delivered = true;
|
|
105
|
+
break;
|
|
106
|
+
}
|
|
107
|
+
catch (error) {
|
|
108
|
+
this.options.onError?.(error);
|
|
109
|
+
if (attempt < this.maxRetries)
|
|
110
|
+
await delay(this.retryBaseMs * 2 ** attempt);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
// Fail open: telemetry is discarded after bounded retries and never blocks the vendor tool path.
|
|
114
|
+
if (!delivered)
|
|
115
|
+
this.options.onDrop?.(batch.length);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
schedule() {
|
|
119
|
+
if (!this.timer)
|
|
120
|
+
this.timer = setTimeout(() => void this.flush(), this.flushIntervalMs);
|
|
121
|
+
this.timer.unref?.();
|
|
122
|
+
}
|
|
123
|
+
clearTimer() {
|
|
124
|
+
if (this.timer)
|
|
125
|
+
clearTimeout(this.timer);
|
|
126
|
+
this.timer = undefined;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
function delay(ms) {
|
|
130
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=transport.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transport.js","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type TriggerStateStore } from "./state.js";
|
|
2
|
+
import type { SupportIdentity, SupportOffer, SupportTrigger, ToolInvocation } from "./types.js";
|
|
3
|
+
export interface TriggerEvaluation {
|
|
4
|
+
trigger: SupportTrigger;
|
|
5
|
+
offer: SupportOffer;
|
|
6
|
+
scopeKey: string;
|
|
7
|
+
}
|
|
8
|
+
export declare class TriggerEngine {
|
|
9
|
+
private triggers;
|
|
10
|
+
private readonly state;
|
|
11
|
+
constructor(triggers: readonly SupportTrigger[], state: TriggerStateStore);
|
|
12
|
+
replaceTriggers(triggers: readonly SupportTrigger[]): void;
|
|
13
|
+
beforeTool(invocation: ToolInvocation): Promise<TriggerEvaluation | undefined>;
|
|
14
|
+
afterFailure(invocation: ToolInvocation, errorCode?: string): Promise<TriggerEvaluation | undefined>;
|
|
15
|
+
decide(triggerId: string, identity: SupportIdentity | undefined, decision: "accepted" | "dismissed", traceId?: string): Promise<void>;
|
|
16
|
+
reset(triggerId: string, identity: SupportIdentity | undefined, traceId?: string): Promise<void>;
|
|
17
|
+
private isSuppressed;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=triggers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"triggers.d.ts","sourceRoot":"","sources":["../src/triggers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,iBAAiB,EAAE,MAAM,YAAY,CAAC;AACjE,OAAO,KAAK,EAC+B,eAAe,EAAE,YAAY,EAAE,cAAc,EAAE,cAAc,EACvG,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,cAAc,CAAC;IACxB,KAAK,EAAE,YAAY,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,aAAa;IACZ,OAAO,CAAC,QAAQ;IAA6B,OAAO,CAAC,QAAQ,CAAC,KAAK;gBAA3D,QAAQ,EAAE,SAAS,cAAc,EAAE,EAAmB,KAAK,EAAE,iBAAiB;IAElG,eAAe,CAAC,QAAQ,EAAE,SAAS,cAAc,EAAE,GAAG,IAAI;IAEpD,UAAU,CAAC,UAAU,EAAE,cAAc,GAAG,OAAO,CAAC,iBAAiB,GAAG,SAAS,CAAC;IAe9E,YAAY,CAAC,UAAU,EAAE,cAAc,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,GAAG,SAAS,CAAC;IAuBpG,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,eAAe,GAAG,SAAS,EAAE,QAAQ,EAAE,UAAU,GAAG,WAAW,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAYrI,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,eAAe,GAAG,SAAS,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YAOxF,YAAY;CAI3B"}
|
package/dist/triggers.js
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { identityKey } from "./state.js";
|
|
2
|
+
export class TriggerEngine {
|
|
3
|
+
triggers;
|
|
4
|
+
state;
|
|
5
|
+
constructor(triggers, state) {
|
|
6
|
+
this.triggers = triggers;
|
|
7
|
+
this.state = state;
|
|
8
|
+
}
|
|
9
|
+
replaceTriggers(triggers) { this.triggers = [...triggers]; }
|
|
10
|
+
async beforeTool(invocation) {
|
|
11
|
+
for (const trigger of this.triggers) {
|
|
12
|
+
if (trigger.kind !== "argument_match" || !toolMatches(trigger.toolName, invocation.toolName))
|
|
13
|
+
continue;
|
|
14
|
+
if (!argumentMatches(trigger, invocation.arguments))
|
|
15
|
+
continue;
|
|
16
|
+
const scopeKey = scopeFor(trigger, invocation.identity, invocation.traceId);
|
|
17
|
+
if (await this.isSuppressed(trigger, scopeKey))
|
|
18
|
+
continue;
|
|
19
|
+
const reason = trigger.reason ?? `Tool arguments matched trigger ${trigger.id}`;
|
|
20
|
+
if ((trigger.oncePer ?? "user") !== "always") {
|
|
21
|
+
await this.state.set({ triggerId: trigger.id, scopeKey, status: "pending", updatedAt: new Date().toISOString(), reason });
|
|
22
|
+
}
|
|
23
|
+
return { trigger, scopeKey, offer: offerFor(trigger, reason) };
|
|
24
|
+
}
|
|
25
|
+
return undefined;
|
|
26
|
+
}
|
|
27
|
+
async afterFailure(invocation, errorCode) {
|
|
28
|
+
const failureScope = identityKey(invocation.identity);
|
|
29
|
+
await this.state.addFailure(failureScope, { toolName: invocation.toolName, ...(errorCode ? { errorCode } : {}), at: Date.now() });
|
|
30
|
+
for (const trigger of this.triggers) {
|
|
31
|
+
if (trigger.kind !== "repeated_failure")
|
|
32
|
+
continue;
|
|
33
|
+
if (trigger.toolName && !toolMatches(trigger.toolName, invocation.toolName))
|
|
34
|
+
continue;
|
|
35
|
+
const scopeKey = scopeFor(trigger, invocation.identity, invocation.traceId);
|
|
36
|
+
if (await this.isSuppressed(trigger, scopeKey))
|
|
37
|
+
continue;
|
|
38
|
+
const failures = (await this.state.failures(failureScope, Date.now() - trigger.windowMs))
|
|
39
|
+
.filter(item => !trigger.toolName || toolMatches(trigger.toolName, item.toolName));
|
|
40
|
+
const comparable = trigger.sameErrorCode && errorCode
|
|
41
|
+
? failures.filter(item => item.errorCode === errorCode)
|
|
42
|
+
: failures;
|
|
43
|
+
if (comparable.length < trigger.threshold)
|
|
44
|
+
continue;
|
|
45
|
+
const reason = trigger.reason ?? `${comparable.length} tool failures in ${trigger.windowMs}ms`;
|
|
46
|
+
if ((trigger.oncePer ?? "user") !== "always") {
|
|
47
|
+
await this.state.set({ triggerId: trigger.id, scopeKey, status: "pending", updatedAt: new Date().toISOString(), reason });
|
|
48
|
+
}
|
|
49
|
+
return { trigger, scopeKey, offer: offerFor(trigger, reason) };
|
|
50
|
+
}
|
|
51
|
+
return undefined;
|
|
52
|
+
}
|
|
53
|
+
async decide(triggerId, identity, decision, traceId) {
|
|
54
|
+
const trigger = this.triggers.find(item => item.id === triggerId);
|
|
55
|
+
if (!trigger)
|
|
56
|
+
throw new Error(`Unknown SupportBridge trigger: ${triggerId}`);
|
|
57
|
+
if ((trigger.oncePer ?? "user") === "always")
|
|
58
|
+
return;
|
|
59
|
+
const scopeKey = scopeFor(trigger, identity, traceId);
|
|
60
|
+
const existing = await this.state.get(triggerId, scopeKey);
|
|
61
|
+
await this.state.set({
|
|
62
|
+
triggerId, scopeKey, status: decision, updatedAt: new Date().toISOString(),
|
|
63
|
+
...(existing?.reason ? { reason: existing.reason } : {})
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
async reset(triggerId, identity, traceId) {
|
|
67
|
+
const trigger = this.triggers.find(item => item.id === triggerId);
|
|
68
|
+
if (!trigger)
|
|
69
|
+
throw new Error(`Unknown SupportBridge trigger: ${triggerId}`);
|
|
70
|
+
if ((trigger.oncePer ?? "user") === "always")
|
|
71
|
+
return;
|
|
72
|
+
await this.state.delete(triggerId, scopeFor(trigger, identity, traceId));
|
|
73
|
+
}
|
|
74
|
+
async isSuppressed(trigger, scopeKey) {
|
|
75
|
+
if ((trigger.oncePer ?? "user") === "always")
|
|
76
|
+
return false;
|
|
77
|
+
return Boolean(await this.state.get(trigger.id, scopeKey));
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
function argumentMatches(trigger, args) {
|
|
81
|
+
const candidate = valueAtPath(args, trigger.path);
|
|
82
|
+
if (candidate === undefined || candidate === null)
|
|
83
|
+
return false;
|
|
84
|
+
const actual = String(candidate);
|
|
85
|
+
if (trigger.operator === "equals")
|
|
86
|
+
return actual.localeCompare(trigger.value, undefined, { sensitivity: "accent" }) === 0;
|
|
87
|
+
if (trigger.operator === "contains")
|
|
88
|
+
return actual.toLocaleLowerCase().includes(trigger.value.toLocaleLowerCase());
|
|
89
|
+
try {
|
|
90
|
+
return new RegExp(trigger.value, "i").test(actual);
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
return false;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
function valueAtPath(value, path) {
|
|
97
|
+
let current = value;
|
|
98
|
+
for (const part of path.split(".").filter(Boolean)) {
|
|
99
|
+
if (!current || typeof current !== "object")
|
|
100
|
+
return undefined;
|
|
101
|
+
current = current[part];
|
|
102
|
+
}
|
|
103
|
+
return current;
|
|
104
|
+
}
|
|
105
|
+
function toolMatches(matcher, toolName) {
|
|
106
|
+
if (typeof matcher === "string")
|
|
107
|
+
return matcher === toolName;
|
|
108
|
+
matcher.lastIndex = 0;
|
|
109
|
+
return matcher.test(toolName);
|
|
110
|
+
}
|
|
111
|
+
function scopeFor(trigger, identity, traceId) {
|
|
112
|
+
switch (trigger.oncePer ?? "user") {
|
|
113
|
+
case "always": return "always";
|
|
114
|
+
case "trace": return traceId ?? identityKey(identity);
|
|
115
|
+
case "workspace": return `${identity?.tenantId ?? "-"}:${identity?.workspaceId ?? identity?.userId ?? "anonymous"}`;
|
|
116
|
+
default: return identityKey(identity);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
function offerFor(trigger, reason) {
|
|
120
|
+
const assistance = trigger.motion === "assistance";
|
|
121
|
+
return {
|
|
122
|
+
triggerId: trigger.id,
|
|
123
|
+
reason,
|
|
124
|
+
blocking: trigger.action === "block_and_offer",
|
|
125
|
+
requiresAcknowledgement: trigger.action === "require_acknowledgement" || trigger.action === "block_and_offer",
|
|
126
|
+
message: assistance && trigger.assignedRep ? `${trigger.assignedRep.name} is available to help right now. Would you like to open a live conversation?` : "Human support is available. Would you like to open a support chat?",
|
|
127
|
+
retryOriginalRequestAfterDecision: trigger.action === "block_and_offer",
|
|
128
|
+
...(trigger.motion ? { motion: trigger.motion } : {}),
|
|
129
|
+
...(trigger.assignedRep ? { assignedRep: trigger.assignedRep } : {})
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=triggers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"triggers.js","sourceRoot":"","sources":["../src/triggers.ts"],"names":[],"mappings":"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"}
|