@junando/core 0.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.
@@ -0,0 +1,720 @@
1
+ import { z } from 'zod';
2
+ import pino from 'pino';
3
+ import { Redis } from 'ioredis';
4
+ import { Gauge, Counter, Histogram, Registry } from 'prom-client';
5
+
6
+ declare enum AlertType {
7
+ Error = "http_500",
8
+ Warning = "latency_spike",
9
+ Success = "recovery"
10
+ }
11
+ interface AlertTypeConfig {
12
+ readonly alertName: string;
13
+ readonly severity: string;
14
+ readonly summary: (service: string, i: number, count: number) => string;
15
+ }
16
+ declare const _alertTypeConfigs: Record<AlertType, AlertTypeConfig>;
17
+ declare const ALERT_TYPE_LABELS: Readonly<typeof _alertTypeConfigs>;
18
+ declare enum LLMProviderType {
19
+ Gemini = "gemini",
20
+ Claude = "claude",
21
+ OpenRouter = "openrouter",
22
+ Qwen = "qwen"
23
+ }
24
+ declare const HTTP_TIMEOUT_MS: Readonly<{
25
+ Default: 5000;
26
+ LLM: 30000;
27
+ }>;
28
+ declare const CIRCUIT_BREAKER: Readonly<{
29
+ Timeout: 10000;
30
+ ErrorThresholdPercentage: 70;
31
+ ResetTimeoutMs: 30000;
32
+ }>;
33
+ declare const LLM_MAX_TOKENS = 1024;
34
+ declare const RATE_LIMITER: Readonly<{
35
+ MinTimeMs: 100;
36
+ MaxConcurrent: 5;
37
+ }>;
38
+ declare const DEV_SERVER_PORT = 4000;
39
+ declare const DEDUP_TTL_MS_MULTIPLIER = 1000;
40
+ declare const HOUR_MS = 3600000;
41
+ declare const LLM_FALLBACK_DEFAULTS: Readonly<{
42
+ TimeoutMs: 60000;
43
+ Models: string[];
44
+ }>;
45
+ declare const LLM_MODELS: Readonly<{
46
+ Gemini: "gemini-2.0-flash";
47
+ Claude: "claude-haiku-4-5";
48
+ OpenRouter: "qwen/qwen-2.5-72b-instruct";
49
+ }>;
50
+ declare const SLACK_API_URL = "https://slack.com/api/chat.postMessage";
51
+ declare const TEAMS_WEBHOOK_TIMEOUT_MS = 10000;
52
+ declare const _urgencyEmoji: Record<string, string>;
53
+ declare const URGENCY_EMOJI: Readonly<typeof _urgencyEmoji>;
54
+ declare const REDIS_KEY_PREFIX = "junando:dedup:";
55
+ declare const WEBHOOK_DEFAULTS: Readonly<{
56
+ AlertmanagerUrl: "http://localhost:9093";
57
+ WebhookUrl: "http://localhost:4000/webhook/alert";
58
+ }>;
59
+ declare const PAYLOAD_DEFAULTS: Readonly<{
60
+ Version: "4";
61
+ TruncatedAlerts: 0;
62
+ Receiver: "junando";
63
+ }>;
64
+
65
+ declare const AlertStatusSchema: z.ZodEnum<["firing", "resolved"]>;
66
+ declare const NormalizedAlertSchema: z.ZodObject<{
67
+ fingerprint: z.ZodString;
68
+ alertName: z.ZodString;
69
+ status: z.ZodEnum<["firing", "resolved"]>;
70
+ serviceName: z.ZodString;
71
+ alertType: z.ZodNativeEnum<typeof AlertType>;
72
+ endpointPath: z.ZodString;
73
+ traceId: z.ZodOptional<z.ZodString>;
74
+ startsAt: z.ZodString;
75
+ latencyMs: z.ZodOptional<z.ZodNumber>;
76
+ labels: z.ZodRecord<z.ZodString, z.ZodString>;
77
+ annotations: z.ZodRecord<z.ZodString, z.ZodString>;
78
+ }, "strip", z.ZodTypeAny, {
79
+ fingerprint: string;
80
+ alertName: string;
81
+ status: "firing" | "resolved";
82
+ serviceName: string;
83
+ alertType: AlertType;
84
+ endpointPath: string;
85
+ startsAt: string;
86
+ labels: Record<string, string>;
87
+ annotations: Record<string, string>;
88
+ traceId?: string | undefined;
89
+ latencyMs?: number | undefined;
90
+ }, {
91
+ fingerprint: string;
92
+ alertName: string;
93
+ status: "firing" | "resolved";
94
+ serviceName: string;
95
+ alertType: AlertType;
96
+ endpointPath: string;
97
+ startsAt: string;
98
+ labels: Record<string, string>;
99
+ annotations: Record<string, string>;
100
+ traceId?: string | undefined;
101
+ latencyMs?: number | undefined;
102
+ }>;
103
+ declare const AlertmanagerPayloadSchema: z.ZodObject<{
104
+ version: z.ZodDefault<z.ZodString>;
105
+ groupKey: z.ZodString;
106
+ truncatedAlerts: z.ZodDefault<z.ZodNumber>;
107
+ status: z.ZodEnum<["firing", "resolved"]>;
108
+ receiver: z.ZodString;
109
+ groupLabels: z.ZodRecord<z.ZodString, z.ZodString>;
110
+ commonLabels: z.ZodRecord<z.ZodString, z.ZodString>;
111
+ commonAnnotations: z.ZodRecord<z.ZodString, z.ZodString>;
112
+ externalURL: z.ZodString;
113
+ alerts: z.ZodArray<z.ZodObject<{
114
+ status: z.ZodEnum<["firing", "resolved"]>;
115
+ labels: z.ZodRecord<z.ZodString, z.ZodString>;
116
+ annotations: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodString>>;
117
+ startsAt: z.ZodString;
118
+ endsAt: z.ZodString;
119
+ fingerprint: z.ZodOptional<z.ZodString>;
120
+ }, "strip", z.ZodTypeAny, {
121
+ status: "firing" | "resolved";
122
+ startsAt: string;
123
+ labels: Record<string, string>;
124
+ annotations: Record<string, string>;
125
+ endsAt: string;
126
+ fingerprint?: string | undefined;
127
+ }, {
128
+ status: "firing" | "resolved";
129
+ startsAt: string;
130
+ labels: Record<string, string>;
131
+ endsAt: string;
132
+ fingerprint?: string | undefined;
133
+ annotations?: Record<string, string> | undefined;
134
+ }>, "many">;
135
+ }, "strip", z.ZodTypeAny, {
136
+ status: "firing" | "resolved";
137
+ version: string;
138
+ groupKey: string;
139
+ truncatedAlerts: number;
140
+ receiver: string;
141
+ groupLabels: Record<string, string>;
142
+ commonLabels: Record<string, string>;
143
+ commonAnnotations: Record<string, string>;
144
+ externalURL: string;
145
+ alerts: {
146
+ status: "firing" | "resolved";
147
+ startsAt: string;
148
+ labels: Record<string, string>;
149
+ annotations: Record<string, string>;
150
+ endsAt: string;
151
+ fingerprint?: string | undefined;
152
+ }[];
153
+ }, {
154
+ status: "firing" | "resolved";
155
+ groupKey: string;
156
+ receiver: string;
157
+ groupLabels: Record<string, string>;
158
+ commonLabels: Record<string, string>;
159
+ commonAnnotations: Record<string, string>;
160
+ externalURL: string;
161
+ alerts: {
162
+ status: "firing" | "resolved";
163
+ startsAt: string;
164
+ labels: Record<string, string>;
165
+ endsAt: string;
166
+ fingerprint?: string | undefined;
167
+ annotations?: Record<string, string> | undefined;
168
+ }[];
169
+ version?: string | undefined;
170
+ truncatedAlerts?: number | undefined;
171
+ }>;
172
+ type AlertStatus = z.infer<typeof AlertStatusSchema>;
173
+ type NormalizedAlert = z.infer<typeof NormalizedAlertSchema>;
174
+ type AlertmanagerPayload = z.infer<typeof AlertmanagerPayloadSchema>;
175
+ type AlertErrorType = NormalizedAlert['alertType'];
176
+
177
+ declare const AlertClusterSchema: z.ZodObject<{
178
+ fingerprint: z.ZodString;
179
+ serviceName: z.ZodString;
180
+ alertType: z.ZodNativeEnum<typeof AlertType>;
181
+ endpointPath: z.ZodString;
182
+ alertCount: z.ZodNumber;
183
+ representativeTraceIds: z.ZodArray<z.ZodString, "many">;
184
+ firstSeenAt: z.ZodString;
185
+ latencyP99Ms: z.ZodOptional<z.ZodNumber>;
186
+ }, "strip", z.ZodTypeAny, {
187
+ fingerprint: string;
188
+ serviceName: string;
189
+ alertType: AlertType;
190
+ endpointPath: string;
191
+ alertCount: number;
192
+ representativeTraceIds: string[];
193
+ firstSeenAt: string;
194
+ latencyP99Ms?: number | undefined;
195
+ }, {
196
+ fingerprint: string;
197
+ serviceName: string;
198
+ alertType: AlertType;
199
+ endpointPath: string;
200
+ alertCount: number;
201
+ representativeTraceIds: string[];
202
+ firstSeenAt: string;
203
+ latencyP99Ms?: number | undefined;
204
+ }>;
205
+ type AlertCluster = z.infer<typeof AlertClusterSchema>;
206
+
207
+ declare const UrgencyLevelSchema: z.ZodEnum<["low", "medium", "high", "critical"]>;
208
+ declare const LLMAnalysisSchema: z.ZodObject<{
209
+ probable_cause: z.ZodString;
210
+ impacted_services: z.ZodArray<z.ZodString, "many">;
211
+ recommended_steps: z.ZodArray<z.ZodString, "many">;
212
+ urgency_level: z.ZodEnum<["low", "medium", "high", "critical"]>;
213
+ requires_rollback: z.ZodBoolean;
214
+ }, "strip", z.ZodTypeAny, {
215
+ probable_cause: string;
216
+ impacted_services: string[];
217
+ recommended_steps: string[];
218
+ urgency_level: "critical" | "high" | "medium" | "low";
219
+ requires_rollback: boolean;
220
+ }, {
221
+ probable_cause: string;
222
+ impacted_services: string[];
223
+ recommended_steps: string[];
224
+ urgency_level: "critical" | "high" | "medium" | "low";
225
+ requires_rollback: boolean;
226
+ }>;
227
+ declare const IncidentSchema: z.ZodObject<{
228
+ cluster: z.ZodObject<{
229
+ fingerprint: z.ZodString;
230
+ serviceName: z.ZodString;
231
+ alertType: z.ZodNativeEnum<typeof AlertType>;
232
+ endpointPath: z.ZodString;
233
+ alertCount: z.ZodNumber;
234
+ representativeTraceIds: z.ZodArray<z.ZodString, "many">;
235
+ firstSeenAt: z.ZodString;
236
+ latencyP99Ms: z.ZodOptional<z.ZodNumber>;
237
+ }, "strip", z.ZodTypeAny, {
238
+ fingerprint: string;
239
+ serviceName: string;
240
+ alertType: AlertType;
241
+ endpointPath: string;
242
+ alertCount: number;
243
+ representativeTraceIds: string[];
244
+ firstSeenAt: string;
245
+ latencyP99Ms?: number | undefined;
246
+ }, {
247
+ fingerprint: string;
248
+ serviceName: string;
249
+ alertType: AlertType;
250
+ endpointPath: string;
251
+ alertCount: number;
252
+ representativeTraceIds: string[];
253
+ firstSeenAt: string;
254
+ latencyP99Ms?: number | undefined;
255
+ }>;
256
+ traces: z.ZodOptional<z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>, "many">>;
257
+ analysis: z.ZodOptional<z.ZodObject<{
258
+ probable_cause: z.ZodString;
259
+ impacted_services: z.ZodArray<z.ZodString, "many">;
260
+ recommended_steps: z.ZodArray<z.ZodString, "many">;
261
+ urgency_level: z.ZodEnum<["low", "medium", "high", "critical"]>;
262
+ requires_rollback: z.ZodBoolean;
263
+ }, "strip", z.ZodTypeAny, {
264
+ probable_cause: string;
265
+ impacted_services: string[];
266
+ recommended_steps: string[];
267
+ urgency_level: "critical" | "high" | "medium" | "low";
268
+ requires_rollback: boolean;
269
+ }, {
270
+ probable_cause: string;
271
+ impacted_services: string[];
272
+ recommended_steps: string[];
273
+ urgency_level: "critical" | "high" | "medium" | "low";
274
+ requires_rollback: boolean;
275
+ }>>;
276
+ processedAt: z.ZodString;
277
+ }, "strip", z.ZodTypeAny, {
278
+ cluster: {
279
+ fingerprint: string;
280
+ serviceName: string;
281
+ alertType: AlertType;
282
+ endpointPath: string;
283
+ alertCount: number;
284
+ representativeTraceIds: string[];
285
+ firstSeenAt: string;
286
+ latencyP99Ms?: number | undefined;
287
+ };
288
+ processedAt: string;
289
+ traces?: Record<string, unknown>[] | undefined;
290
+ analysis?: {
291
+ probable_cause: string;
292
+ impacted_services: string[];
293
+ recommended_steps: string[];
294
+ urgency_level: "critical" | "high" | "medium" | "low";
295
+ requires_rollback: boolean;
296
+ } | undefined;
297
+ }, {
298
+ cluster: {
299
+ fingerprint: string;
300
+ serviceName: string;
301
+ alertType: AlertType;
302
+ endpointPath: string;
303
+ alertCount: number;
304
+ representativeTraceIds: string[];
305
+ firstSeenAt: string;
306
+ latencyP99Ms?: number | undefined;
307
+ };
308
+ processedAt: string;
309
+ traces?: Record<string, unknown>[] | undefined;
310
+ analysis?: {
311
+ probable_cause: string;
312
+ impacted_services: string[];
313
+ recommended_steps: string[];
314
+ urgency_level: "critical" | "high" | "medium" | "low";
315
+ requires_rollback: boolean;
316
+ } | undefined;
317
+ }>;
318
+ type UrgencyLevel = z.infer<typeof UrgencyLevelSchema>;
319
+ type LLMAnalysis = z.infer<typeof LLMAnalysisSchema>;
320
+ type Incident = z.infer<typeof IncidentSchema>;
321
+
322
+ interface TraceabilityDocument {
323
+ '@timestamp': string;
324
+ uploadId?: string;
325
+ channel: string;
326
+ application: string;
327
+ messageType: string;
328
+ message: string;
329
+ originFlow?: string;
330
+ refId?: string;
331
+ fingerprint: string;
332
+ correlationId: string;
333
+ }
334
+
335
+ declare class Fingerprint {
336
+ readonly value: string;
337
+ private constructor();
338
+ static fromAlert(alert: NormalizedAlert): Fingerprint;
339
+ equals(other: Fingerprint): boolean;
340
+ toString(): string;
341
+ }
342
+
343
+ /**
344
+ * Deduplication store.
345
+ * Determines whether an alert fingerprint is new within a rolling TTL window.
346
+ * Implementations: RedisDeduplicationStore, InMemoryDeduplicationStore (tests)
347
+ */
348
+ interface IDeduplicationStore {
349
+ isNew(fingerprint: string, ttlSeconds: number): Promise<boolean>;
350
+ reset(fingerprint: string): Promise<void>;
351
+ }
352
+ /**
353
+ * Alert queue.
354
+ * Publishes normalized alerts for async processing.
355
+ * Implementations: SQSAlertQueue, BullMQAlertQueue, InMemoryAlertQueue (tests)
356
+ */
357
+ interface IAlertQueue {
358
+ publish(alert: NormalizedAlert): Promise<void>;
359
+ }
360
+ /**
361
+ * Trace repository.
362
+ * Fetches distributed trace context by trace ID.
363
+ * Implementations: LokiTraceRepository, DatadogTraceRepository, MockTraceRepository (tests)
364
+ */
365
+ interface ITraceRepository {
366
+ findByTraceId(traceId: string): Promise<Record<string, unknown>[]>;
367
+ }
368
+ /**
369
+ * LLM provider.
370
+ * Analyzes an incident cluster and returns a structured diagnosis.
371
+ * Implementations: GeminiProvider, ClaudeProvider, OpenAIProvider, MockLLMProvider (tests)
372
+ */
373
+ interface ILLMProvider {
374
+ analyze(cluster: AlertCluster, traces: Record<string, unknown>[]): Promise<LLMAnalysis>;
375
+ }
376
+ /**
377
+ * Notifier.
378
+ * Delivers incident diagnoses to a ChatOps channel.
379
+ * Implementations: SlackNotifier, TeamsNotifier, ConsoleNotifier (local dev/tests)
380
+ */
381
+ interface INotifier {
382
+ send(cluster: AlertCluster, analysis: LLMAnalysis | null): Promise<void>;
383
+ }
384
+ /**
385
+ * Indexer.
386
+ * Persists a typed document into a searchable index/store.
387
+ * Implementations: OpenSearchIndexer, InMemoryIndexer (tests)
388
+ */
389
+ interface IIndexer<TDocument> {
390
+ index(doc: TDocument): Promise<void>;
391
+ }
392
+
393
+ declare class ClusteringService {
394
+ /**
395
+ * Groups alerts by fingerprint and builds AlertCluster objects.
396
+ * 300 alerts with the same root cause → 1 cluster with 2 representative traces.
397
+ */
398
+ buildClusters(alerts: NormalizedAlert[]): AlertCluster[];
399
+ private buildCluster;
400
+ private sampleTraceIds;
401
+ }
402
+
403
+ declare function normalizePayload(payload: AlertmanagerPayload): NormalizedAlert[];
404
+
405
+ type Logger = pino.Logger;
406
+ interface LoggerOptions {
407
+ level?: string;
408
+ name?: string;
409
+ }
410
+ /**
411
+ * Returns a Proxy logger that always delegates to the current root logger.
412
+ * Module-level callers get a proxy that automatically starts writing to Loki
413
+ * once reinitLogger() is called inside the handler after loadConfig().
414
+ */
415
+ declare function createLogger(levelOrOptions?: string | LoggerOptions): Logger;
416
+ /**
417
+ * Re-creates the root logger with current env vars (including LOKI_URL).
418
+ * Call this inside your Lambda handler immediately after loadConfig():
419
+ *
420
+ * @example
421
+ * const config = await loadConfig();
422
+ * reinitLogger(); // all module-level proxy loggers now write to Loki
423
+ */
424
+ declare function reinitLogger(opts?: LoggerOptions): void;
425
+
426
+ interface Dependencies {
427
+ dedup: IDeduplicationStore;
428
+ traces: ITraceRepository;
429
+ llm: ILLMProvider;
430
+ notifier: INotifier;
431
+ logger: Logger;
432
+ dedupTtlSeconds: number;
433
+ clustering?: ClusteringService;
434
+ onClustersBuilt?: (count: number) => void;
435
+ }
436
+ declare class ProcessIncidentUseCase {
437
+ private readonly deps;
438
+ private readonly clustering;
439
+ constructor(deps: Dependencies);
440
+ execute(alerts: NormalizedAlert[], correlationId: string): Promise<void>;
441
+ }
442
+
443
+ declare class RedisDeduplicationStore implements IDeduplicationStore {
444
+ private readonly redis;
445
+ private readonly keyPrefix;
446
+ constructor(redis: Redis);
447
+ isNew(fingerprint: string, ttlSeconds: number): Promise<boolean>;
448
+ reset(fingerprint: string): Promise<void>;
449
+ }
450
+ declare class InMemoryDeduplicationStore implements IDeduplicationStore {
451
+ private readonly store;
452
+ isNew(fingerprint: string, ttlSeconds: number): Promise<boolean>;
453
+ reset(fingerprint: string): Promise<void>;
454
+ clear(): void;
455
+ }
456
+
457
+ interface SignedHttpRequest {
458
+ method: string;
459
+ url: string;
460
+ headers: Record<string, string>;
461
+ body: string;
462
+ }
463
+ interface OpenSearchHttpResponse {
464
+ status: number;
465
+ body: string;
466
+ }
467
+ type OpenSearchHttpFetcher = (request: SignedHttpRequest) => Promise<OpenSearchHttpResponse>;
468
+ interface OpenSearchIndexerDeps {
469
+ endpoint: string;
470
+ indexName: string;
471
+ region: string;
472
+ fetcher: OpenSearchHttpFetcher;
473
+ }
474
+ declare class OpenSearchIndexer implements IIndexer<TraceabilityDocument> {
475
+ private readonly endpoint;
476
+ private readonly indexName;
477
+ private readonly region;
478
+ private readonly fetcher;
479
+ constructor(deps: OpenSearchIndexerDeps);
480
+ index(doc: TraceabilityDocument): Promise<void>;
481
+ }
482
+ declare class InMemoryIndexer implements IIndexer<TraceabilityDocument> {
483
+ readonly indexed: TraceabilityDocument[];
484
+ index(doc: TraceabilityDocument): Promise<void>;
485
+ }
486
+
487
+ /**
488
+ * Gemini LLM provider using Google Generative AI SDK.
489
+ * Wrapped with circuit breaker for resilience.
490
+ */
491
+ declare class GeminiProvider implements ILLMProvider {
492
+ private readonly apiKey;
493
+ private readonly model;
494
+ private readonly breaker;
495
+ constructor(apiKey: string, model?: string);
496
+ analyze(cluster: AlertCluster, traces: Record<string, unknown>[]): Promise<LLMAnalysis>;
497
+ private analyzeRaw;
498
+ }
499
+ /**
500
+ * Claude LLM provider using Anthropic SDK.
501
+ * Supports Claude Haiku and other models.
502
+ */
503
+ declare class ClaudeProvider implements ILLMProvider {
504
+ private readonly apiKey;
505
+ private readonly model;
506
+ constructor(apiKey: string, model?: string);
507
+ analyze(cluster: AlertCluster, traces: Record<string, unknown>[]): Promise<LLMAnalysis>;
508
+ }
509
+ /**
510
+ * Mock LLM provider for testing and local development.
511
+ * Returns deterministic responses without external API calls.
512
+ */
513
+ declare class MockLLMProvider implements ILLMProvider {
514
+ readonly callLog: Array<{
515
+ cluster: AlertCluster;
516
+ }>;
517
+ analyze(cluster: AlertCluster, _traces: Record<string, unknown>[]): Promise<LLMAnalysis>;
518
+ }
519
+ /**
520
+ * Options for configuring the OpenRouter fallback chain.
521
+ * Infra-internal — not exported.
522
+ */
523
+ interface FallbackOptions {
524
+ fallbackModels?: string[];
525
+ fallbackTimeoutMs?: number;
526
+ }
527
+ declare function createLLMProvider(provider: string, apiKey: string, model?: string, options?: FallbackOptions): ILLMProvider;
528
+
529
+ declare const ConfigSchema: z.ZodEffects<z.ZodObject<{
530
+ llmProvider: z.ZodEnum<["gemini", "claude", "openrouter", "qwen"]>;
531
+ llmApiKey: z.ZodString;
532
+ llmModel: z.ZodEffects<z.ZodOptional<z.ZodString>, string | undefined, string | undefined>;
533
+ notifierType: z.ZodDefault<z.ZodEnum<["slack", "teams"]>>;
534
+ slackBotToken: z.ZodOptional<z.ZodString>;
535
+ slackSigningSecret: z.ZodOptional<z.ZodString>;
536
+ slackChannel: z.ZodOptional<z.ZodString>;
537
+ teamsWebhookUrl: z.ZodOptional<z.ZodString>;
538
+ lokiUrl: z.ZodEffects<z.ZodOptional<z.ZodString>, string | undefined, string | undefined>;
539
+ redisUrl: z.ZodString;
540
+ sqsQueueUrl: z.ZodUnion<[z.ZodOptional<z.ZodString>, z.ZodLiteral<"">]>;
541
+ dedupTtlSeconds: z.ZodDefault<z.ZodNumber>;
542
+ clusterWindowMs: z.ZodDefault<z.ZodNumber>;
543
+ logLevel: z.ZodDefault<z.ZodEnum<["trace", "debug", "info", "warn", "error"]>>;
544
+ nodeEnv: z.ZodDefault<z.ZodEnum<["development", "test", "production"]>>;
545
+ llmFallbackModels: z.ZodEffects<z.ZodOptional<z.ZodString>, string[], string | undefined>;
546
+ llmFallbackTimeoutMs: z.ZodDefault<z.ZodNumber>;
547
+ }, "strip", z.ZodTypeAny, {
548
+ dedupTtlSeconds: number;
549
+ llmProvider: "gemini" | "claude" | "openrouter" | "qwen";
550
+ llmApiKey: string;
551
+ notifierType: "slack" | "teams";
552
+ redisUrl: string;
553
+ clusterWindowMs: number;
554
+ logLevel: "info" | "error" | "warn" | "debug" | "trace";
555
+ nodeEnv: "production" | "development" | "test";
556
+ llmFallbackModels: string[];
557
+ llmFallbackTimeoutMs: number;
558
+ llmModel?: string | undefined;
559
+ slackBotToken?: string | undefined;
560
+ slackSigningSecret?: string | undefined;
561
+ slackChannel?: string | undefined;
562
+ teamsWebhookUrl?: string | undefined;
563
+ lokiUrl?: string | undefined;
564
+ sqsQueueUrl?: string | undefined;
565
+ }, {
566
+ llmProvider: "gemini" | "claude" | "openrouter" | "qwen";
567
+ llmApiKey: string;
568
+ redisUrl: string;
569
+ dedupTtlSeconds?: number | undefined;
570
+ llmModel?: string | undefined;
571
+ notifierType?: "slack" | "teams" | undefined;
572
+ slackBotToken?: string | undefined;
573
+ slackSigningSecret?: string | undefined;
574
+ slackChannel?: string | undefined;
575
+ teamsWebhookUrl?: string | undefined;
576
+ lokiUrl?: string | undefined;
577
+ sqsQueueUrl?: string | undefined;
578
+ clusterWindowMs?: number | undefined;
579
+ logLevel?: "info" | "error" | "warn" | "debug" | "trace" | undefined;
580
+ nodeEnv?: "production" | "development" | "test" | undefined;
581
+ llmFallbackModels?: string | undefined;
582
+ llmFallbackTimeoutMs?: number | undefined;
583
+ }>, {
584
+ dedupTtlSeconds: number;
585
+ llmProvider: "gemini" | "claude" | "openrouter" | "qwen";
586
+ llmApiKey: string;
587
+ notifierType: "slack" | "teams";
588
+ redisUrl: string;
589
+ clusterWindowMs: number;
590
+ logLevel: "info" | "error" | "warn" | "debug" | "trace";
591
+ nodeEnv: "production" | "development" | "test";
592
+ llmFallbackModels: string[];
593
+ llmFallbackTimeoutMs: number;
594
+ llmModel?: string | undefined;
595
+ slackBotToken?: string | undefined;
596
+ slackSigningSecret?: string | undefined;
597
+ slackChannel?: string | undefined;
598
+ teamsWebhookUrl?: string | undefined;
599
+ lokiUrl?: string | undefined;
600
+ sqsQueueUrl?: string | undefined;
601
+ }, {
602
+ llmProvider: "gemini" | "claude" | "openrouter" | "qwen";
603
+ llmApiKey: string;
604
+ redisUrl: string;
605
+ dedupTtlSeconds?: number | undefined;
606
+ llmModel?: string | undefined;
607
+ notifierType?: "slack" | "teams" | undefined;
608
+ slackBotToken?: string | undefined;
609
+ slackSigningSecret?: string | undefined;
610
+ slackChannel?: string | undefined;
611
+ teamsWebhookUrl?: string | undefined;
612
+ lokiUrl?: string | undefined;
613
+ sqsQueueUrl?: string | undefined;
614
+ clusterWindowMs?: number | undefined;
615
+ logLevel?: "info" | "error" | "warn" | "debug" | "trace" | undefined;
616
+ nodeEnv?: "production" | "development" | "test" | undefined;
617
+ llmFallbackModels?: string | undefined;
618
+ llmFallbackTimeoutMs?: number | undefined;
619
+ }>;
620
+ type Config = z.infer<typeof ConfigSchema>;
621
+ declare function loadConfig(): Promise<Config>;
622
+
623
+ declare function createNotifier(config: Config): INotifier;
624
+
625
+ declare class SlackNotifier implements INotifier {
626
+ private readonly botToken;
627
+ private readonly channel;
628
+ constructor(botToken: string, channel: string);
629
+ send(cluster: AlertCluster, analysis: LLMAnalysis | null): Promise<void>;
630
+ private buildAnalysisMessage;
631
+ private buildFallbackMessage;
632
+ }
633
+ declare class ConsoleNotifier implements INotifier {
634
+ readonly sent: Array<{
635
+ cluster: AlertCluster;
636
+ analysis: LLMAnalysis | null;
637
+ }>;
638
+ send(cluster: AlertCluster, analysis: LLMAnalysis | null): Promise<void>;
639
+ }
640
+
641
+ declare class TeamsNotifierError extends Error {
642
+ constructor(message: string);
643
+ }
644
+ declare class TeamsNotifier implements INotifier {
645
+ private readonly webhookUrl;
646
+ private readonly timeoutMs;
647
+ private readonly hostForErrors;
648
+ constructor(webhookUrl: string, timeoutMs?: number);
649
+ send(cluster: AlertCluster, analysis: LLMAnalysis | null): Promise<void>;
650
+ }
651
+
652
+ interface SendMessageParams {
653
+ messageBody: string;
654
+ messageGroupId: string;
655
+ messageDeduplicationId: string;
656
+ }
657
+ declare class SQSAlertQueue implements IAlertQueue {
658
+ private readonly queueUrl;
659
+ private readonly region?;
660
+ private sqsClient;
661
+ constructor(queueUrl: string, region?: string | undefined);
662
+ private getClient;
663
+ sendMessage(params: SendMessageParams): Promise<void>;
664
+ publish(alert: NormalizedAlert): Promise<void>;
665
+ }
666
+ declare class InMemoryAlertQueue implements IAlertQueue {
667
+ readonly published: NormalizedAlert[];
668
+ publish(alert: NormalizedAlert): Promise<void>;
669
+ }
670
+
671
+ declare class LokiTraceRepository implements ITraceRepository {
672
+ private readonly lokiUrl;
673
+ private readonly apiKey?;
674
+ constructor(lokiUrl: string, apiKey?: string | undefined);
675
+ findByTraceId(traceId: string): Promise<Record<string, unknown>[]>;
676
+ private parseResponse;
677
+ private tryParseJSON;
678
+ }
679
+ declare class MockTraceRepository implements ITraceRepository {
680
+ private readonly fixtures;
681
+ constructor(fixtures?: Map<string, Record<string, unknown>[]>);
682
+ findByTraceId(traceId: string): Promise<Record<string, unknown>[]>;
683
+ addFixture(traceId: string, spans: Record<string, unknown>[]): void;
684
+ }
685
+
686
+ /**
687
+ * Flush all buffered log entries to Loki in a single HTTP request.
688
+ * Call this at the END of the Lambda handler, after all business logic completes.
689
+ * Errors are swallowed — Loki is best-effort; CloudWatch is the primary sink.
690
+ */
691
+ declare function flushLoki(): Promise<void>;
692
+
693
+ declare const registry: Registry<"text/plain; version=0.0.4; charset=utf-8">;
694
+ declare const alertsReceived: Counter<"status">;
695
+ declare const webhookRequestsTotal: Counter<"status" | "endpoint">;
696
+ declare const alertsProcessed: Counter<string>;
697
+ declare const alertClusters: Gauge<string>;
698
+ declare const latency: Histogram<string>;
699
+ declare const llmInferenceDuration: Histogram<"model">;
700
+ declare const llmInferenceTotal: Counter<"status">;
701
+ /** Tracks inline pipeline failures in local dev mode. */
702
+ declare const pipelineInlineFailuresTotal: Counter<"reason">;
703
+ /** Tracks Redis dedup fallback activations. */
704
+ declare const dedupRedisFailoverTotal: Counter<string>;
705
+
706
+ declare const index_alertClusters: typeof alertClusters;
707
+ declare const index_alertsProcessed: typeof alertsProcessed;
708
+ declare const index_alertsReceived: typeof alertsReceived;
709
+ declare const index_dedupRedisFailoverTotal: typeof dedupRedisFailoverTotal;
710
+ declare const index_latency: typeof latency;
711
+ declare const index_llmInferenceDuration: typeof llmInferenceDuration;
712
+ declare const index_llmInferenceTotal: typeof llmInferenceTotal;
713
+ declare const index_pipelineInlineFailuresTotal: typeof pipelineInlineFailuresTotal;
714
+ declare const index_registry: typeof registry;
715
+ declare const index_webhookRequestsTotal: typeof webhookRequestsTotal;
716
+ declare namespace index {
717
+ export { index_alertClusters as alertClusters, index_alertsProcessed as alertsProcessed, index_alertsReceived as alertsReceived, index_dedupRedisFailoverTotal as dedupRedisFailoverTotal, index_latency as latency, index_llmInferenceDuration as llmInferenceDuration, index_llmInferenceTotal as llmInferenceTotal, index_pipelineInlineFailuresTotal as pipelineInlineFailuresTotal, index_registry as registry, index_webhookRequestsTotal as webhookRequestsTotal };
718
+ }
719
+
720
+ export { ALERT_TYPE_LABELS, type AlertCluster, AlertClusterSchema, type AlertErrorType, type AlertStatus, AlertStatusSchema, AlertType, type AlertmanagerPayload, AlertmanagerPayloadSchema, CIRCUIT_BREAKER, ClaudeProvider, ClusteringService, type Config, ConsoleNotifier, DEDUP_TTL_MS_MULTIPLIER, DEV_SERVER_PORT, Fingerprint, GeminiProvider, HOUR_MS, HTTP_TIMEOUT_MS, type IAlertQueue, type IDeduplicationStore, type IIndexer, type ILLMProvider, type INotifier, type ITraceRepository, InMemoryAlertQueue, InMemoryDeduplicationStore, InMemoryIndexer, type Incident, IncidentSchema, type LLMAnalysis, LLMAnalysisSchema, LLMProviderType, LLM_FALLBACK_DEFAULTS, LLM_MAX_TOKENS, LLM_MODELS, type Logger, type LoggerOptions, LokiTraceRepository, MockLLMProvider, MockTraceRepository, type NormalizedAlert, NormalizedAlertSchema, type OpenSearchHttpFetcher, type OpenSearchHttpResponse, OpenSearchIndexer, type OpenSearchIndexerDeps, PAYLOAD_DEFAULTS, ProcessIncidentUseCase, RATE_LIMITER, REDIS_KEY_PREFIX, RedisDeduplicationStore, SLACK_API_URL, SQSAlertQueue, type SignedHttpRequest, SlackNotifier, TEAMS_WEBHOOK_TIMEOUT_MS, TeamsNotifier, TeamsNotifierError, type TraceabilityDocument, URGENCY_EMOJI, type UrgencyLevel, UrgencyLevelSchema, WEBHOOK_DEFAULTS, createLLMProvider, createLogger, createNotifier, flushLoki, loadConfig, index as metrics, normalizePayload, reinitLogger };