@agentlensai/server 0.6.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/dist/db/benchmark-store.d.ts +74 -0
  2. package/dist/db/benchmark-store.d.ts.map +1 -0
  3. package/dist/db/benchmark-store.js +268 -0
  4. package/dist/db/benchmark-store.js.map +1 -0
  5. package/dist/db/guardrail-store.d.ts +34 -0
  6. package/dist/db/guardrail-store.d.ts.map +1 -0
  7. package/dist/db/guardrail-store.js +221 -0
  8. package/dist/db/guardrail-store.js.map +1 -0
  9. package/dist/db/migrate.d.ts.map +1 -1
  10. package/dist/db/migrate.js +112 -0
  11. package/dist/db/migrate.js.map +1 -1
  12. package/dist/db/schema.sqlite.d.ts +58 -1
  13. package/dist/db/schema.sqlite.d.ts.map +1 -1
  14. package/dist/db/schema.sqlite.js +6 -0
  15. package/dist/db/schema.sqlite.js.map +1 -1
  16. package/dist/db/sqlite-store.d.ts +12 -0
  17. package/dist/db/sqlite-store.d.ts.map +1 -1
  18. package/dist/db/sqlite-store.js +47 -0
  19. package/dist/db/sqlite-store.js.map +1 -1
  20. package/dist/db/tenant-scoped-store.d.ts +1 -0
  21. package/dist/db/tenant-scoped-store.d.ts.map +1 -1
  22. package/dist/db/tenant-scoped-store.js +3 -0
  23. package/dist/db/tenant-scoped-store.js.map +1 -1
  24. package/dist/index.d.ts +4 -0
  25. package/dist/index.d.ts.map +1 -1
  26. package/dist/index.js +32 -0
  27. package/dist/index.js.map +1 -1
  28. package/dist/lib/benchmark/engine.d.ts +24 -0
  29. package/dist/lib/benchmark/engine.d.ts.map +1 -0
  30. package/dist/lib/benchmark/engine.js +159 -0
  31. package/dist/lib/benchmark/engine.js.map +1 -0
  32. package/dist/lib/benchmark/metric-aggregator.d.ts +38 -0
  33. package/dist/lib/benchmark/metric-aggregator.d.ts.map +1 -0
  34. package/dist/lib/benchmark/metric-aggregator.js +159 -0
  35. package/dist/lib/benchmark/metric-aggregator.js.map +1 -0
  36. package/dist/lib/benchmark/statistical.d.ts +51 -0
  37. package/dist/lib/benchmark/statistical.d.ts.map +1 -0
  38. package/dist/lib/benchmark/statistical.js +381 -0
  39. package/dist/lib/benchmark/statistical.js.map +1 -0
  40. package/dist/lib/guardrails/actions.d.ts +28 -0
  41. package/dist/lib/guardrails/actions.d.ts.map +1 -0
  42. package/dist/lib/guardrails/actions.js +126 -0
  43. package/dist/lib/guardrails/actions.js.map +1 -0
  44. package/dist/lib/guardrails/conditions.d.ts +13 -0
  45. package/dist/lib/guardrails/conditions.d.ts.map +1 -0
  46. package/dist/lib/guardrails/conditions.js +188 -0
  47. package/dist/lib/guardrails/conditions.js.map +1 -0
  48. package/dist/lib/guardrails/engine.d.ts +24 -0
  49. package/dist/lib/guardrails/engine.d.ts.map +1 -0
  50. package/dist/lib/guardrails/engine.js +122 -0
  51. package/dist/lib/guardrails/engine.js.map +1 -0
  52. package/dist/lib/replay/builder.d.ts +28 -0
  53. package/dist/lib/replay/builder.d.ts.map +1 -0
  54. package/dist/lib/replay/builder.js +482 -0
  55. package/dist/lib/replay/builder.js.map +1 -0
  56. package/dist/routes/agents.d.ts +4 -3
  57. package/dist/routes/agents.d.ts.map +1 -1
  58. package/dist/routes/agents.js +37 -12
  59. package/dist/routes/agents.js.map +1 -1
  60. package/dist/routes/benchmarks.d.ts +18 -0
  61. package/dist/routes/benchmarks.d.ts.map +1 -0
  62. package/dist/routes/benchmarks.js +312 -0
  63. package/dist/routes/benchmarks.js.map +1 -0
  64. package/dist/routes/guardrails.d.ts +18 -0
  65. package/dist/routes/guardrails.d.ts.map +1 -0
  66. package/dist/routes/guardrails.js +184 -0
  67. package/dist/routes/guardrails.js.map +1 -0
  68. package/dist/routes/replay.d.ts +28 -0
  69. package/dist/routes/replay.d.ts.map +1 -0
  70. package/dist/routes/replay.js +140 -0
  71. package/dist/routes/replay.js.map +1 -0
  72. package/package.json +2 -2
@@ -0,0 +1,188 @@
1
+ /**
2
+ * Guardrail Condition Evaluators (v0.8.0 — Story 1.4)
3
+ *
4
+ * Each condition type has an evaluator that queries the store
5
+ * and returns whether the condition is triggered.
6
+ */
7
+ import { DEFAULT_HEALTH_WEIGHTS } from '@agentlensai/core';
8
+ import { HealthComputer } from '../health/computer.js';
9
+ export async function evaluateErrorRateThreshold(store, rule, agentId) {
10
+ const config = rule.conditionConfig;
11
+ const threshold = config.threshold ?? 30;
12
+ const windowMinutes = config.windowMinutes ?? 5;
13
+ const now = new Date();
14
+ const from = new Date(now.getTime() - windowMinutes * 60 * 1000).toISOString();
15
+ const totalCount = await store.countEvents({ agentId, from, to: now.toISOString() });
16
+ if (totalCount === 0) {
17
+ return { triggered: false, currentValue: 0, threshold, message: 'No events in window' };
18
+ }
19
+ // Architecture §3.4: count error, critical severity AND tool_error event types
20
+ const errorCount = await store.countEvents({ agentId, from, to: now.toISOString(), severity: 'error' });
21
+ const criticalCount = await store.countEvents({ agentId, from, to: now.toISOString(), severity: 'critical' });
22
+ const toolErrorCount = await store.countEvents({ agentId, from, to: now.toISOString(), eventType: 'tool_error' });
23
+ // Deduplicate: tool_error events with error/critical severity are already counted above,
24
+ // but store.countEvents filters by a single field, so we take the max of the combined count and totalCount
25
+ const combinedErrors = Math.min(errorCount + criticalCount + toolErrorCount, totalCount);
26
+ const errorRate = (combinedErrors / totalCount) * 100;
27
+ return {
28
+ triggered: errorRate >= threshold,
29
+ currentValue: Math.round(errorRate * 100) / 100,
30
+ threshold,
31
+ message: errorRate >= threshold
32
+ ? `Error rate ${errorRate.toFixed(1)}% exceeds threshold ${threshold}%`
33
+ : `Error rate ${errorRate.toFixed(1)}% within threshold ${threshold}%`,
34
+ };
35
+ }
36
+ export async function evaluateCostLimit(store, rule, agentId, sessionId) {
37
+ const config = rule.conditionConfig;
38
+ const maxCostUsd = config.maxCostUsd ?? 10;
39
+ const scope = config.scope ?? 'daily';
40
+ if (scope === 'session' && sessionId) {
41
+ const session = await store.getSession(sessionId);
42
+ const currentCost = session?.totalCostUsd ?? 0;
43
+ return {
44
+ triggered: currentCost >= maxCostUsd,
45
+ currentValue: Math.round(currentCost * 10000) / 10000,
46
+ threshold: maxCostUsd,
47
+ message: currentCost >= maxCostUsd
48
+ ? `Session cost $${currentCost.toFixed(4)} exceeds limit $${maxCostUsd}`
49
+ : `Session cost $${currentCost.toFixed(4)} within limit $${maxCostUsd}`,
50
+ };
51
+ }
52
+ const todayStart = new Date();
53
+ todayStart.setUTCHours(0, 0, 0, 0);
54
+ const { sessions } = await store.querySessions({ agentId, from: todayStart.toISOString(), limit: 10000 });
55
+ const dailyCost = sessions.reduce((sum, s) => sum + (s.totalCostUsd || 0), 0);
56
+ return {
57
+ triggered: dailyCost >= maxCostUsd,
58
+ currentValue: Math.round(dailyCost * 10000) / 10000,
59
+ threshold: maxCostUsd,
60
+ message: dailyCost >= maxCostUsd
61
+ ? `Daily cost $${dailyCost.toFixed(4)} exceeds limit $${maxCostUsd}`
62
+ : `Daily cost $${dailyCost.toFixed(4)} within limit $${maxCostUsd}`,
63
+ };
64
+ }
65
+ export async function evaluateHealthScoreThreshold(store, rule, agentId) {
66
+ const config = rule.conditionConfig;
67
+ const minScore = config.minScore ?? 50;
68
+ const windowDays = config.windowDays ?? 7;
69
+ try {
70
+ const computer = new HealthComputer(DEFAULT_HEALTH_WEIGHTS);
71
+ const score = await computer.compute(store, agentId, windowDays);
72
+ if (!score) {
73
+ return { triggered: false, currentValue: 0, threshold: minScore, message: 'No sessions found for health computation' };
74
+ }
75
+ return {
76
+ triggered: score.overallScore < minScore,
77
+ currentValue: Math.round(score.overallScore * 100) / 100,
78
+ threshold: minScore,
79
+ message: score.overallScore < minScore
80
+ ? `Health score ${score.overallScore.toFixed(0)} below minimum ${minScore}`
81
+ : `Health score ${score.overallScore.toFixed(0)} above minimum ${minScore}`,
82
+ };
83
+ }
84
+ catch {
85
+ return { triggered: false, currentValue: 0, threshold: minScore, message: 'Failed to compute health score' };
86
+ }
87
+ }
88
+ /**
89
+ * Extract a value from a nested object using dot-notation key path.
90
+ * e.g. getByKeyPath({ a: { b: 3 } }, 'a.b') → 3
91
+ */
92
+ function getByKeyPath(obj, keyPath) {
93
+ const parts = keyPath.split('.');
94
+ let current = obj;
95
+ for (const part of parts) {
96
+ if (current == null || typeof current !== 'object')
97
+ return undefined;
98
+ current = current[part];
99
+ }
100
+ return current;
101
+ }
102
+ function compareMetric(currentValue, operator, targetValue) {
103
+ switch (operator) {
104
+ case 'gt': return currentValue > targetValue;
105
+ case 'gte': return currentValue >= targetValue;
106
+ case 'lt': return currentValue < targetValue;
107
+ case 'lte': return currentValue <= targetValue;
108
+ case 'eq': return currentValue === targetValue;
109
+ default: return false;
110
+ }
111
+ }
112
+ export async function evaluateCustomMetric(store, rule, agentId) {
113
+ const config = rule.conditionConfig;
114
+ const metricKeyPath = config.metricKeyPath;
115
+ const operator = config.operator ?? 'gt';
116
+ const targetValue = config.value ?? 0;
117
+ const windowMinutes = config.windowMinutes ?? 60;
118
+ const now = new Date();
119
+ const from = new Date(now.getTime() - windowMinutes * 60 * 1000).toISOString();
120
+ // Architecture §3.4: Use metricKeyPath to extract values from event metadata
121
+ if (metricKeyPath) {
122
+ const eventsResult = await store.queryEvents({ agentId, from, to: now.toISOString(), limit: 10000 });
123
+ const values = [];
124
+ for (const event of eventsResult.events) {
125
+ const md = (event.metadata ?? {});
126
+ const raw = getByKeyPath(md, metricKeyPath);
127
+ if (typeof raw === 'number')
128
+ values.push(raw);
129
+ }
130
+ // (events returned newest-first by default query order)
131
+ if (values.length === 0) {
132
+ return {
133
+ triggered: false,
134
+ currentValue: 0,
135
+ threshold: targetValue,
136
+ message: `No events with metadata key "${metricKeyPath}" in window`,
137
+ };
138
+ }
139
+ // Use the latest value for comparison (events are returned newest-first, so first element is latest)
140
+ const currentValue = values[0];
141
+ const triggered = compareMetric(currentValue, operator, targetValue);
142
+ return {
143
+ triggered,
144
+ currentValue,
145
+ threshold: targetValue,
146
+ message: triggered
147
+ ? `${metricKeyPath} (${currentValue}) ${operator} ${targetValue} = triggered`
148
+ : `${metricKeyPath} (${currentValue}) ${operator} ${targetValue} = not triggered`,
149
+ };
150
+ }
151
+ // Legacy fallback: metricName-based evaluation for backward compatibility
152
+ const metricName = config.metricName ?? 'event_count';
153
+ let currentValue = 0;
154
+ switch (metricName) {
155
+ case 'event_count':
156
+ currentValue = await store.countEvents({ agentId, from, to: now.toISOString() });
157
+ break;
158
+ case 'error_count':
159
+ currentValue = await store.countEvents({ agentId, from, to: now.toISOString(), severity: 'error' });
160
+ break;
161
+ case 'session_count': {
162
+ const { total } = await store.querySessions({ agentId, from });
163
+ currentValue = total;
164
+ break;
165
+ }
166
+ default:
167
+ return { triggered: false, currentValue: 0, threshold: targetValue, message: `Unknown metric: ${metricName}` };
168
+ }
169
+ const triggered = compareMetric(currentValue, operator, targetValue);
170
+ return {
171
+ triggered,
172
+ currentValue,
173
+ threshold: targetValue,
174
+ message: triggered
175
+ ? `${metricName} (${currentValue}) ${operator} ${targetValue} = triggered`
176
+ : `${metricName} (${currentValue}) ${operator} ${targetValue} = not triggered`,
177
+ };
178
+ }
179
+ export async function evaluateCondition(store, rule, agentId, sessionId) {
180
+ switch (rule.conditionType) {
181
+ case 'error_rate_threshold': return evaluateErrorRateThreshold(store, rule, agentId);
182
+ case 'cost_limit': return evaluateCostLimit(store, rule, agentId, sessionId);
183
+ case 'health_score_threshold': return evaluateHealthScoreThreshold(store, rule, agentId);
184
+ case 'custom_metric': return evaluateCustomMetric(store, rule, agentId);
185
+ default: return { triggered: false, currentValue: 0, threshold: 0, message: `Unknown condition type: ${rule.conditionType}` };
186
+ }
187
+ }
188
+ //# sourceMappingURL=conditions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conditions.js","sourceRoot":"","sources":["../../../src/lib/guardrails/conditions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Guardrail Evaluation Engine (v0.8.0 — Story 1.3)
3
+ *
4
+ * Subscribes to EventBus and evaluates guardrail rules asynchronously.
5
+ * Never blocks the event POST response.
6
+ */
7
+ import type { AgentLensEvent } from '@agentlensai/core';
8
+ import type { IEventStore } from '@agentlensai/core';
9
+ import type { SqliteDb } from '../../db/index.js';
10
+ import { GuardrailStore } from '../../db/guardrail-store.js';
11
+ export declare class GuardrailEngine {
12
+ private store;
13
+ private eventStore;
14
+ private listener;
15
+ private started;
16
+ constructor(eventStore: IEventStore, db: SqliteDb);
17
+ start(): void;
18
+ stop(): void;
19
+ getStore(): GuardrailStore;
20
+ evaluateEvent(event: AgentLensEvent): Promise<void>;
21
+ private evaluateRule;
22
+ private isInCooldown;
23
+ }
24
+ //# sourceMappingURL=engine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../../src/lib/guardrails/engine.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAiC,MAAM,mBAAmB,CAAC;AACvF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAK7D,qBAAa,eAAe;IAC1B,OAAO,CAAC,KAAK,CAAiB;IAC9B,OAAO,CAAC,UAAU,CAAc;IAChC,OAAO,CAAC,QAAQ,CAA4C;IAC5D,OAAO,CAAC,OAAO,CAAS;gBAEZ,UAAU,EAAE,WAAW,EAAE,EAAE,EAAE,QAAQ;IAKjD,KAAK,IAAI,IAAI;IAab,IAAI,IAAI,IAAI;IAQZ,QAAQ,IAAI,cAAc;IAIpB,aAAa,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;YAa3C,YAAY;IA+D1B,OAAO,CAAC,YAAY;CAOrB"}
@@ -0,0 +1,122 @@
1
+ /**
2
+ * Guardrail Evaluation Engine (v0.8.0 — Story 1.3)
3
+ *
4
+ * Subscribes to EventBus and evaluates guardrail rules asynchronously.
5
+ * Never blocks the event POST response.
6
+ */
7
+ import { ulid } from 'ulid';
8
+ import { GuardrailStore } from '../../db/guardrail-store.js';
9
+ import { evaluateCondition } from './conditions.js';
10
+ import { executeAction } from './actions.js';
11
+ import { eventBus } from '../event-bus.js';
12
+ export class GuardrailEngine {
13
+ store;
14
+ eventStore;
15
+ listener = null;
16
+ started = false;
17
+ constructor(eventStore, db) {
18
+ this.eventStore = eventStore;
19
+ this.store = new GuardrailStore(db);
20
+ }
21
+ start() {
22
+ if (this.started)
23
+ return;
24
+ this.listener = (busEvent) => {
25
+ if (busEvent.type === 'event_ingested') {
26
+ this.evaluateEvent(busEvent.event).catch((err) => {
27
+ console.error('[guardrail-engine] evaluation error:', err instanceof Error ? err.message : err);
28
+ });
29
+ }
30
+ };
31
+ eventBus.on('event_ingested', this.listener);
32
+ this.started = true;
33
+ }
34
+ stop() {
35
+ if (this.listener) {
36
+ eventBus.off('event_ingested', this.listener);
37
+ this.listener = null;
38
+ }
39
+ this.started = false;
40
+ }
41
+ getStore() {
42
+ return this.store;
43
+ }
44
+ async evaluateEvent(event) {
45
+ const rules = this.store.listEnabledRules(event.tenantId, event.agentId);
46
+ if (rules.length === 0)
47
+ return;
48
+ for (const rule of rules) {
49
+ try {
50
+ await this.evaluateRule(rule, event);
51
+ }
52
+ catch (err) {
53
+ console.error(`[guardrail-engine] rule ${rule.id} error:`, err instanceof Error ? err.message : err);
54
+ }
55
+ }
56
+ }
57
+ async evaluateRule(rule, event) {
58
+ const now = new Date();
59
+ // 0. Check enabled (defense-in-depth — listEnabledRules already filters, but verify)
60
+ if (!rule.enabled)
61
+ return;
62
+ // 1. Check cooldown
63
+ if (this.isInCooldown(rule, now))
64
+ return;
65
+ // 2. Evaluate condition
66
+ const conditionResult = await evaluateCondition(this.eventStore, rule, event.agentId, event.sessionId);
67
+ // 3. Update state
68
+ const existingState = this.store.getState(rule.tenantId, rule.id);
69
+ const newState = {
70
+ ruleId: rule.id,
71
+ tenantId: rule.tenantId,
72
+ lastEvaluatedAt: now.toISOString(),
73
+ currentValue: conditionResult.currentValue,
74
+ triggerCount: existingState?.triggerCount ?? 0,
75
+ lastTriggeredAt: existingState?.lastTriggeredAt,
76
+ };
77
+ if (!conditionResult.triggered) {
78
+ this.store.upsertState(newState);
79
+ return;
80
+ }
81
+ // 4. Execute action (or dry-run)
82
+ let actionResult = 'dry_run';
83
+ let actionExecuted = false;
84
+ if (!rule.dryRun) {
85
+ const result = await executeAction(rule, conditionResult, event.agentId);
86
+ actionResult = result.result;
87
+ actionExecuted = result.success;
88
+ }
89
+ // 5. Record trigger history
90
+ this.store.insertTrigger({
91
+ id: ulid(),
92
+ ruleId: rule.id,
93
+ tenantId: rule.tenantId,
94
+ triggeredAt: now.toISOString(),
95
+ conditionValue: conditionResult.currentValue,
96
+ conditionThreshold: conditionResult.threshold,
97
+ actionExecuted,
98
+ actionResult,
99
+ metadata: {
100
+ agentId: event.agentId,
101
+ sessionId: event.sessionId,
102
+ eventId: event.id,
103
+ dryRun: rule.dryRun,
104
+ message: conditionResult.message,
105
+ },
106
+ });
107
+ // 6. Update state
108
+ newState.triggerCount = (existingState?.triggerCount ?? 0) + 1;
109
+ newState.lastTriggeredAt = now.toISOString();
110
+ this.store.upsertState(newState);
111
+ }
112
+ isInCooldown(rule, now) {
113
+ if (rule.cooldownMinutes <= 0)
114
+ return false;
115
+ const state = this.store.getState(rule.tenantId, rule.id);
116
+ if (!state?.lastTriggeredAt)
117
+ return false;
118
+ const lastTriggered = new Date(state.lastTriggeredAt);
119
+ return now.getTime() - lastTriggered.getTime() < rule.cooldownMinutes * 60 * 1000;
120
+ }
121
+ }
122
+ //# sourceMappingURL=engine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.js","sourceRoot":"","sources":["../../../src/lib/guardrails/engine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * ReplayBuilder — Core Replay Logic (Stories 2.1, 2.4)
3
+ *
4
+ * Constructs a ReplayState from raw events for a given session.
5
+ * Handles event pairing, cumulative context tracking, pagination,
6
+ * filtering, and redaction of sensitive LLM content.
7
+ */
8
+ import type { IEventStore, EventType, ReplayState } from '@agentlensai/core';
9
+ export interface ReplayBuildOptions {
10
+ /** Skip N steps (default 0) */
11
+ offset?: number;
12
+ /** Max steps to return (default 1000) */
13
+ limit?: number;
14
+ /** Only include these event types */
15
+ eventTypes?: EventType[];
16
+ /** If false, skip cumulative context computation (default true) */
17
+ includeContext?: boolean;
18
+ }
19
+ export declare class ReplayBuilder {
20
+ private readonly store;
21
+ constructor(store: IEventStore);
22
+ /**
23
+ * Build a ReplayState for the given session.
24
+ * Returns null when the session does not exist.
25
+ */
26
+ build(sessionId: string, options?: ReplayBuildOptions): Promise<ReplayState | null>;
27
+ }
28
+ //# sourceMappingURL=builder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../../../src/lib/replay/builder.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EACV,WAAW,EAEX,SAAS,EAGT,WAAW,EAWZ,MAAM,mBAAmB,CAAC;AAK3B,MAAM,WAAW,kBAAkB;IACjC,+BAA+B;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,yCAAyC;IACzC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qCAAqC;IACrC,UAAU,CAAC,EAAE,SAAS,EAAE,CAAC;IACzB,mEAAmE;IACnE,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAID,qBAAa,aAAa;IACZ,OAAO,CAAC,QAAQ,CAAC,KAAK;gBAAL,KAAK,EAAE,WAAW;IAE/C;;;OAGG;IACG,KAAK,CACT,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;CA2G/B"}