@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.
Files changed (79) hide show
  1. package/CHANGELOG.md +73 -0
  2. package/LICENSE +13 -0
  3. package/README.md +326 -0
  4. package/SECURITY.md +26 -0
  5. package/dist/agent.d.ts +9 -0
  6. package/dist/agent.d.ts.map +1 -0
  7. package/dist/agent.js +73 -0
  8. package/dist/agent.js.map +1 -0
  9. package/dist/client.d.ts +68 -0
  10. package/dist/client.d.ts.map +1 -0
  11. package/dist/client.js +254 -0
  12. package/dist/client.js.map +1 -0
  13. package/dist/context.d.ts +4 -0
  14. package/dist/context.d.ts.map +1 -0
  15. package/dist/context.js +9 -0
  16. package/dist/context.js.map +1 -0
  17. package/dist/control-plane.d.ts +37 -0
  18. package/dist/control-plane.d.ts.map +1 -0
  19. package/dist/control-plane.js +43 -0
  20. package/dist/control-plane.js.map +1 -0
  21. package/dist/doctor.d.ts +17 -0
  22. package/dist/doctor.d.ts.map +1 -0
  23. package/dist/doctor.js +49 -0
  24. package/dist/doctor.js.map +1 -0
  25. package/dist/index.d.ts +30 -0
  26. package/dist/index.d.ts.map +1 -0
  27. package/dist/index.js +16 -0
  28. package/dist/index.js.map +1 -0
  29. package/dist/install.d.ts +42 -0
  30. package/dist/install.d.ts.map +1 -0
  31. package/dist/install.js +215 -0
  32. package/dist/install.js.map +1 -0
  33. package/dist/mcp-app.d.ts +50 -0
  34. package/dist/mcp-app.d.ts.map +1 -0
  35. package/dist/mcp-app.js +44 -0
  36. package/dist/mcp-app.js.map +1 -0
  37. package/dist/mcp.d.ts +44 -0
  38. package/dist/mcp.d.ts.map +1 -0
  39. package/dist/mcp.js +117 -0
  40. package/dist/mcp.js.map +1 -0
  41. package/dist/offer-app.d.ts +41 -0
  42. package/dist/offer-app.d.ts.map +1 -0
  43. package/dist/offer-app.js +21 -0
  44. package/dist/offer-app.js.map +1 -0
  45. package/dist/policy-app.d.ts +41 -0
  46. package/dist/policy-app.d.ts.map +1 -0
  47. package/dist/policy-app.js +49 -0
  48. package/dist/policy-app.js.map +1 -0
  49. package/dist/policy-store.d.ts +79 -0
  50. package/dist/policy-store.d.ts.map +1 -0
  51. package/dist/policy-store.js +137 -0
  52. package/dist/policy-store.js.map +1 -0
  53. package/dist/policy.d.ts +226 -0
  54. package/dist/policy.d.ts.map +1 -0
  55. package/dist/policy.js +420 -0
  56. package/dist/policy.js.map +1 -0
  57. package/dist/sanitize.d.ts +9 -0
  58. package/dist/sanitize.d.ts.map +1 -0
  59. package/dist/sanitize.js +83 -0
  60. package/dist/sanitize.js.map +1 -0
  61. package/dist/state.d.ts +31 -0
  62. package/dist/state.d.ts.map +1 -0
  63. package/dist/state.js +29 -0
  64. package/dist/state.js.map +1 -0
  65. package/dist/transport.d.ts +57 -0
  66. package/dist/transport.d.ts.map +1 -0
  67. package/dist/transport.js +132 -0
  68. package/dist/transport.js.map +1 -0
  69. package/dist/triggers.d.ts +19 -0
  70. package/dist/triggers.d.ts.map +1 -0
  71. package/dist/triggers.js +132 -0
  72. package/dist/triggers.js.map +1 -0
  73. package/dist/types.d.ts +221 -0
  74. package/dist/types.d.ts.map +1 -0
  75. package/dist/types.js +2 -0
  76. package/dist/types.js.map +1 -0
  77. package/docs/policy-engine.md +47 -0
  78. package/docs/telemetry-contract.md +29 -0
  79. 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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"}
@@ -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":"AAeA,MAAM,OAAO,sBAAsB;IAKJ;IAJZ,QAAQ,CAAS;IACjB,SAAS,CAAS;IAClB,SAAS,CAA0B;IAEpD,YAA6B,OAA6B;QAA7B,YAAO,GAAP,OAAO,CAAsB;QACxD,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QACpD,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,KAAK,CAAC;QAC5C,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,KAAK,IAAI,UAAU,CAAC,KAAK,CAAC;QACnD,IAAI,CAAC,IAAI,CAAC,SAAS;YAAE,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;IAC7E,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,MAAiC,EAAE,MAAoB;QAChE,IAAI,CAAC,MAAM,CAAC,MAAM;YAAE,OAAO;QAC3B,MAAM,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACpD,MAAM,QAAQ,GAAG,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;QACvE,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC,QAAQ,qBAAqB,EAAE;YAC3E,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,cAAc,EAAE,kBAAkB;gBAClC,aAAa,EAAE,UAAU,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE;gBAC9C,YAAY,EAAE,yBAAyB;gBACvC,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO;aACxB;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;YAChC,MAAM,EAAE,QAAQ;SACjB,CAAC,CAAC;QACH,IAAI,CAAC,QAAQ,CAAC,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,4CAA4C,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC;IACpG,CAAC;CACF;AAED,MAAM,OAAO,wBAAwB;IAC1B,OAAO,GAAuB,EAAE,CAAC;IAC1C,QAAQ,CAAS;IAEjB,KAAK,CAAC,IAAI,CAAC,MAAiC;QAC1C,IAAI,IAAI,CAAC,QAAQ;YAAE,MAAM,IAAI,CAAC,QAAQ,CAAC;QACvC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACjE,CAAC;IAED,IAAI,MAAM,KAAuB,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;CAC/D;AAYD,MAAM,OAAO,0BAA0B;IAWR;IAAgD;IAVrE,KAAK,GAAqB,EAAE,CAAC;IAC7B,KAAK,CAA4C;IACjD,QAAQ,CAA4B;IACpC,MAAM,GAAG,KAAK,CAAC;IACN,SAAS,CAAS;IAClB,eAAe,CAAS;IACxB,YAAY,CAAS;IACrB,UAAU,CAAS;IACnB,WAAW,CAAS;IAErC,YAA6B,SAA6B,EAAmB,UAAoC,EAAE;QAAtF,cAAS,GAAT,SAAS,CAAoB;QAAmB,YAAO,GAAP,OAAO,CAA+B;QACjH,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,EAAE,CAAC;QACzC,IAAI,CAAC,eAAe,GAAG,OAAO,CAAC,eAAe,IAAI,KAAK,CAAC;QACxD,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,YAAY,IAAI,KAAK,CAAC;QAClD,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,CAAC,CAAC;QAC1C,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,GAAG,CAAC;IAChD,CAAC;IAED,OAAO,CAAC,KAAqB;QAC3B,IAAI,IAAI,CAAC,MAAM;YAAE,OAAO;QACxB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACvB,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;YAC1C,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC;YACtD,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;YAC9B,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,CAAC;QACjC,CAAC;QACD,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,IAAI,CAAC,SAAS;YAAE,KAAK,IAAI,CAAC,KAAK,EAAE,CAAC;;YACtD,IAAI,CAAC,QAAQ,EAAE,CAAC;IACvB,CAAC;IAED,KAAK,CAAC,KAAK;QACT,IAAI,IAAI,CAAC,QAAQ;YAAE,OAAO,IAAI,CAAC,QAAQ,CAAC;QACxC,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE;YACxC,IAAI,CAAC,QAAQ,GAAG,SAAS,CAAC;YAC1B,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM;gBAAE,IAAI,CAAC,QAAQ,EAAE,CAAC;QACzD,CAAC,CAAC,CAAC;QACH,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;IAED,KAAK,CAAC,KAAK;QACT,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACnB,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;QACnB,MAAM,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,EAAE,CAAC;IACjC,CAAC;IAED,IAAI,YAAY,KAAa,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;IAEhD,KAAK,CAAC,KAAK;QACjB,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;YACzB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;YACnD,IAAI,SAAS,GAAG,KAAK,CAAC;YACtB,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,IAAI,IAAI,CAAC,UAAU,EAAE,OAAO,IAAI,CAAC,EAAE,CAAC;gBAC/D,IAAI,CAAC;oBACH,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;oBACjC,SAAS,GAAG,IAAI,CAAC;oBACjB,MAAM;gBACR,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,CAAC;oBAC9B,IAAI,OAAO,GAAG,IAAI,CAAC,UAAU;wBAAE,MAAM,KAAK,CAAC,IAAI,CAAC,WAAW,GAAG,CAAC,IAAI,OAAO,CAAC,CAAC;gBAC9E,CAAC;YACH,CAAC;YACD,iGAAiG;YACjG,IAAI,CAAC,SAAS;gBAAE,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QACtD,CAAC;IACH,CAAC;IAEO,QAAQ;QACd,IAAI,CAAC,IAAI,CAAC,KAAK;YAAE,IAAI,CAAC,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,KAAK,IAAI,CAAC,KAAK,EAAE,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC;QACxF,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC;IACvB,CAAC;IAEO,UAAU;QAChB,IAAI,IAAI,CAAC,KAAK;YAAE,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACzC,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC;IACzB,CAAC;CACF;AAED,SAAS,KAAK,CAAC,EAAU;IACvB,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AACzD,CAAC"}
@@ -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"}
@@ -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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"}