catalist-support-agent 1.0.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 (140) hide show
  1. package/dist/admin-portal.d.ts +43 -0
  2. package/dist/admin-portal.d.ts.map +1 -0
  3. package/dist/admin-portal.js +166 -0
  4. package/dist/admin-portal.js.map +1 -0
  5. package/dist/analysis/entities.d.ts +73 -0
  6. package/dist/analysis/entities.d.ts.map +1 -0
  7. package/dist/analysis/entities.js +378 -0
  8. package/dist/analysis/entities.js.map +1 -0
  9. package/dist/analysis/index.d.ts +44 -0
  10. package/dist/analysis/index.d.ts.map +1 -0
  11. package/dist/analysis/index.js +243 -0
  12. package/dist/analysis/index.js.map +1 -0
  13. package/dist/analysis/intent.d.ts +49 -0
  14. package/dist/analysis/intent.d.ts.map +1 -0
  15. package/dist/analysis/intent.js +320 -0
  16. package/dist/analysis/intent.js.map +1 -0
  17. package/dist/analysis/sentiment.d.ts +57 -0
  18. package/dist/analysis/sentiment.d.ts.map +1 -0
  19. package/dist/analysis/sentiment.js +351 -0
  20. package/dist/analysis/sentiment.js.map +1 -0
  21. package/dist/brand/compliance.d.ts +122 -0
  22. package/dist/brand/compliance.d.ts.map +1 -0
  23. package/dist/brand/compliance.js +378 -0
  24. package/dist/brand/compliance.js.map +1 -0
  25. package/dist/brand/forbidden-terms.d.ts +99 -0
  26. package/dist/brand/forbidden-terms.d.ts.map +1 -0
  27. package/dist/brand/forbidden-terms.js +265 -0
  28. package/dist/brand/forbidden-terms.js.map +1 -0
  29. package/dist/brand/index.d.ts +10 -0
  30. package/dist/brand/index.d.ts.map +1 -0
  31. package/dist/brand/index.js +12 -0
  32. package/dist/brand/index.js.map +1 -0
  33. package/dist/config.d.ts +325 -0
  34. package/dist/config.d.ts.map +1 -0
  35. package/dist/config.js +492 -0
  36. package/dist/config.js.map +1 -0
  37. package/dist/delivery/index.d.ts +84 -0
  38. package/dist/delivery/index.d.ts.map +1 -0
  39. package/dist/delivery/index.js +435 -0
  40. package/dist/delivery/index.js.map +1 -0
  41. package/dist/embeddings/cache.d.ts +96 -0
  42. package/dist/embeddings/cache.d.ts.map +1 -0
  43. package/dist/embeddings/cache.js +193 -0
  44. package/dist/embeddings/cache.js.map +1 -0
  45. package/dist/embeddings/index.d.ts +152 -0
  46. package/dist/embeddings/index.d.ts.map +1 -0
  47. package/dist/embeddings/index.js +337 -0
  48. package/dist/embeddings/index.js.map +1 -0
  49. package/dist/embeddings/openai-client.d.ts +67 -0
  50. package/dist/embeddings/openai-client.d.ts.map +1 -0
  51. package/dist/embeddings/openai-client.js +190 -0
  52. package/dist/embeddings/openai-client.js.map +1 -0
  53. package/dist/errors.d.ts +302 -0
  54. package/dist/errors.d.ts.map +1 -0
  55. package/dist/errors.js +508 -0
  56. package/dist/errors.js.map +1 -0
  57. package/dist/escalation/index.d.ts +93 -0
  58. package/dist/escalation/index.d.ts.map +1 -0
  59. package/dist/escalation/index.js +436 -0
  60. package/dist/escalation/index.js.map +1 -0
  61. package/dist/extraction/deduplication.d.ts +97 -0
  62. package/dist/extraction/deduplication.d.ts.map +1 -0
  63. package/dist/extraction/deduplication.js +271 -0
  64. package/dist/extraction/deduplication.js.map +1 -0
  65. package/dist/extraction/gmail-extractor.d.ts +160 -0
  66. package/dist/extraction/gmail-extractor.d.ts.map +1 -0
  67. package/dist/extraction/gmail-extractor.js +396 -0
  68. package/dist/extraction/gmail-extractor.js.map +1 -0
  69. package/dist/extraction/gmail-token-manager.d.ts +36 -0
  70. package/dist/extraction/gmail-token-manager.d.ts.map +1 -0
  71. package/dist/extraction/gmail-token-manager.js +146 -0
  72. package/dist/extraction/gmail-token-manager.js.map +1 -0
  73. package/dist/extraction/index.d.ts +13 -0
  74. package/dist/extraction/index.d.ts.map +1 -0
  75. package/dist/extraction/index.js +20 -0
  76. package/dist/extraction/index.js.map +1 -0
  77. package/dist/extraction/pii-handler.d.ts +100 -0
  78. package/dist/extraction/pii-handler.d.ts.map +1 -0
  79. package/dist/extraction/pii-handler.js +295 -0
  80. package/dist/extraction/pii-handler.js.map +1 -0
  81. package/dist/extraction/pipeline.d.ts +94 -0
  82. package/dist/extraction/pipeline.d.ts.map +1 -0
  83. package/dist/extraction/pipeline.js +380 -0
  84. package/dist/extraction/pipeline.js.map +1 -0
  85. package/dist/extraction/quality-filter.d.ts +99 -0
  86. package/dist/extraction/quality-filter.d.ts.map +1 -0
  87. package/dist/extraction/quality-filter.js +370 -0
  88. package/dist/extraction/quality-filter.js.map +1 -0
  89. package/dist/extraction/rate-limiter.d.ts +90 -0
  90. package/dist/extraction/rate-limiter.d.ts.map +1 -0
  91. package/dist/extraction/rate-limiter.js +242 -0
  92. package/dist/extraction/rate-limiter.js.map +1 -0
  93. package/dist/extraction/state-manager.d.ts +126 -0
  94. package/dist/extraction/state-manager.d.ts.map +1 -0
  95. package/dist/extraction/state-manager.js +344 -0
  96. package/dist/extraction/state-manager.js.map +1 -0
  97. package/dist/generation/index.d.ts +75 -0
  98. package/dist/generation/index.d.ts.map +1 -0
  99. package/dist/generation/index.js +641 -0
  100. package/dist/generation/index.js.map +1 -0
  101. package/dist/index.d.ts +96 -0
  102. package/dist/index.d.ts.map +1 -0
  103. package/dist/index.js +233 -0
  104. package/dist/index.js.map +1 -0
  105. package/dist/intake/index.d.ts +15 -0
  106. package/dist/intake/index.d.ts.map +1 -0
  107. package/dist/intake/index.js +19 -0
  108. package/dist/intake/index.js.map +1 -0
  109. package/dist/intake/normalizer.d.ts +163 -0
  110. package/dist/intake/normalizer.d.ts.map +1 -0
  111. package/dist/intake/normalizer.js +309 -0
  112. package/dist/intake/normalizer.js.map +1 -0
  113. package/dist/intake/postmark.d.ts +72 -0
  114. package/dist/intake/postmark.d.ts.map +1 -0
  115. package/dist/intake/postmark.js +276 -0
  116. package/dist/intake/postmark.js.map +1 -0
  117. package/dist/intake/slack.d.ts +106 -0
  118. package/dist/intake/slack.d.ts.map +1 -0
  119. package/dist/intake/slack.js +378 -0
  120. package/dist/intake/slack.js.map +1 -0
  121. package/dist/intake/twilio.d.ts +86 -0
  122. package/dist/intake/twilio.d.ts.map +1 -0
  123. package/dist/intake/twilio.js +283 -0
  124. package/dist/intake/twilio.js.map +1 -0
  125. package/dist/knowledge/index.d.ts +100 -0
  126. package/dist/knowledge/index.d.ts.map +1 -0
  127. package/dist/knowledge/index.js +516 -0
  128. package/dist/knowledge/index.js.map +1 -0
  129. package/dist/knowledge/invoice-resolver.d.ts +62 -0
  130. package/dist/knowledge/invoice-resolver.d.ts.map +1 -0
  131. package/dist/knowledge/invoice-resolver.js +267 -0
  132. package/dist/knowledge/invoice-resolver.js.map +1 -0
  133. package/dist/types.d.ts +535 -0
  134. package/dist/types.d.ts.map +1 -0
  135. package/dist/types.js +48 -0
  136. package/dist/types.js.map +1 -0
  137. package/ga-service-account.json +13 -0
  138. package/gmail-knowledge-migration.sql +149 -0
  139. package/nul +1 -0
  140. package/package.json +55 -0
@@ -0,0 +1,436 @@
1
+ /**
2
+ * Escalation System Module
3
+ *
4
+ * Routes conversations requiring human attention:
5
+ * - Forbidden terms detection
6
+ * - Low confidence responses
7
+ * - Customer complaints
8
+ * - Explicit human requests
9
+ * - N-failure tracking
10
+ */
11
+ import { createClient } from '@supabase/supabase-js';
12
+ import { config, getEscalationChannels, getSlaTarget } from '../config.js';
13
+ import { EscalationError, AllEscalationChannelsFailedError, } from '../errors.js';
14
+ import { createEscalationId } from '../types.js';
15
+ // =============================================================================
16
+ // Escalation Triggers
17
+ // =============================================================================
18
+ /**
19
+ * Determine if escalation is required based on analysis
20
+ */
21
+ export function shouldEscalate(analysis) {
22
+ const reasons = [];
23
+ let trigger;
24
+ let severity = 'medium';
25
+ // CRITICAL: Forbidden terms
26
+ if (analysis.brandCompliance.status === 'blocked') {
27
+ trigger = 'forbidden_terms';
28
+ severity = 'high';
29
+ reasons.push('Forbidden terms detected in message');
30
+ }
31
+ // Complaint intent
32
+ if (analysis.intent.primary === 'complaint') {
33
+ trigger = trigger || 'complaint';
34
+ severity = 'high';
35
+ reasons.push('Customer complaint detected');
36
+ }
37
+ // Low confidence
38
+ if (analysis.overallConfidence < config.agent.confidenceThresholds.escalationTrigger) {
39
+ trigger = trigger || 'low_confidence';
40
+ reasons.push(`Low analysis confidence: ${Math.round(analysis.overallConfidence * 100)}%`);
41
+ }
42
+ // Critical urgency
43
+ if (analysis.sentiment.urgency === 'critical') {
44
+ trigger = trigger || 'high_urgency';
45
+ severity = 'critical';
46
+ reasons.push('Critical urgency level');
47
+ }
48
+ // Negative sentiment
49
+ if (analysis.sentiment.category === 'negative' && analysis.sentiment.score < -0.6) {
50
+ trigger = trigger || 'negative_sentiment';
51
+ reasons.push('Strong negative sentiment');
52
+ }
53
+ return {
54
+ required: trigger !== undefined,
55
+ trigger,
56
+ severity,
57
+ reasons,
58
+ };
59
+ }
60
+ /**
61
+ * Check for explicit human assistance request
62
+ */
63
+ export function containsHumanRequest(text) {
64
+ const patterns = [
65
+ /speak\s+(to|with)\s+(a\s+)?(human|person|agent|representative|someone)/i,
66
+ /talk\s+(to|with)\s+(a\s+)?(human|person|agent|representative|someone)/i,
67
+ /real\s+(human|person)/i,
68
+ /not\s+(a\s+)?bot/i,
69
+ /transfer\s+me/i,
70
+ /escalate/i,
71
+ /manager/i,
72
+ /supervisor/i,
73
+ ];
74
+ return patterns.some((p) => p.test(text));
75
+ }
76
+ // =============================================================================
77
+ // Escalation Service
78
+ // =============================================================================
79
+ export class EscalationService {
80
+ supabase;
81
+ constructor() {
82
+ this.supabase = createClient(config.supabase.url, config.supabase.serviceRoleKey);
83
+ }
84
+ /**
85
+ * Create and route an escalation
86
+ */
87
+ async escalate(context) {
88
+ // 1. Determine severity-based channels
89
+ const channels = getEscalationChannels(context.severity);
90
+ // 2. Calculate SLA target
91
+ const slaTargetMs = getSlaTarget(context.severity);
92
+ const slaTargetAt = new Date(Date.now() + slaTargetMs);
93
+ // 3. Create escalation record
94
+ const { data: escalation, error: insertError } = await this.supabase
95
+ .from('support_escalations')
96
+ .insert({
97
+ conversation_id: context.conversationId,
98
+ message_id: context.messageId,
99
+ customer_id: context.customerId,
100
+ trigger: context.trigger,
101
+ severity: context.severity,
102
+ reason: context.reason,
103
+ context_data: this.buildContextData(context),
104
+ sla_target_at: slaTargetAt.toISOString(),
105
+ })
106
+ .select('id')
107
+ .single();
108
+ if (insertError || !escalation) {
109
+ throw new EscalationError('Failed to create escalation record', {
110
+ cause: new Error(insertError?.message),
111
+ conversationId: context.conversationId,
112
+ messageId: context.messageId,
113
+ });
114
+ }
115
+ const escalationId = createEscalationId(escalation.id);
116
+ // 4. Send notifications to all channels
117
+ const deliveries = [];
118
+ const channelErrors = [];
119
+ for (const channel of channels) {
120
+ try {
121
+ const delivery = await this.notifyChannel(channel, escalationId, context);
122
+ deliveries.push(delivery);
123
+ }
124
+ catch (error) {
125
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
126
+ channelErrors.push({ channel, error: errorMessage });
127
+ deliveries.push({
128
+ channel,
129
+ success: false,
130
+ error: errorMessage,
131
+ timestamp: new Date().toISOString(),
132
+ });
133
+ }
134
+ }
135
+ // 5. Update escalation record with notification results
136
+ await this.supabase
137
+ .from('support_escalations')
138
+ .update({
139
+ notification_channels: deliveries.map((d) => ({
140
+ channel: d.channel,
141
+ sent_at: d.timestamp,
142
+ message_id: d.messageId,
143
+ success: d.success,
144
+ error: d.error,
145
+ })),
146
+ })
147
+ .eq('id', escalationId);
148
+ // 6. Update conversation status
149
+ await this.supabase
150
+ .from('support_conversations')
151
+ .update({
152
+ status: 'escalated',
153
+ is_handled_by_ai: false,
154
+ state_data: {
155
+ status: 'escalated',
156
+ escalatedAt: new Date().toISOString(),
157
+ escalationId,
158
+ reason: context.reason,
159
+ },
160
+ })
161
+ .eq('id', context.conversationId);
162
+ // 7. Check if all channels failed
163
+ const allSucceeded = deliveries.every((d) => d.success);
164
+ const anySucceeded = deliveries.some((d) => d.success);
165
+ if (!anySucceeded) {
166
+ // Use database fallback
167
+ await this.createDatabaseFallback(escalationId, context);
168
+ throw new AllEscalationChannelsFailedError(channelErrors, {
169
+ escalationId,
170
+ conversationId: context.conversationId,
171
+ messageId: context.messageId,
172
+ });
173
+ }
174
+ return {
175
+ escalationId,
176
+ conversationId: context.conversationId,
177
+ deliveries,
178
+ allSucceeded,
179
+ adminUrl: `${config.escalation.adminBaseUrl}/support/escalations/${escalationId}`,
180
+ createdAt: new Date().toISOString(),
181
+ };
182
+ }
183
+ /**
184
+ * Build context data for escalation record
185
+ */
186
+ buildContextData(context) {
187
+ return {
188
+ trigger: context.trigger,
189
+ severity: context.severity,
190
+ reason: context.reason,
191
+ analysisResult: context.analysisResult
192
+ ? {
193
+ intent: context.analysisResult.intent,
194
+ sentiment: context.analysisResult.sentiment,
195
+ brandCompliance: context.analysisResult.brandCompliance,
196
+ overallConfidence: context.analysisResult.overallConfidence,
197
+ escalationReasons: context.analysisResult.escalationReasons,
198
+ }
199
+ : undefined,
200
+ attemptedResponses: context.attemptedResponses?.length ?? 0,
201
+ knowledgeContext: context.knowledgeContext
202
+ ? {
203
+ hasCustomerData: !!context.knowledgeContext.customer,
204
+ hasOrderData: !!(context.knowledgeContext.orders?.length ?? 0 > 0),
205
+ hasProductData: !!(context.knowledgeContext.products?.length ?? 0 > 0),
206
+ }
207
+ : undefined,
208
+ };
209
+ }
210
+ /**
211
+ * Send notification via a specific channel
212
+ */
213
+ async notifyChannel(channel, escalationId, context) {
214
+ const timestamp = new Date().toISOString();
215
+ // Check if channel is configured
216
+ if (!this.isChannelConfigured(channel)) {
217
+ return {
218
+ channel,
219
+ success: false,
220
+ error: `Channel ${channel} not configured`,
221
+ timestamp,
222
+ };
223
+ }
224
+ // Build notification content
225
+ const content = this.buildNotificationContent(escalationId, context);
226
+ switch (channel) {
227
+ case 'email':
228
+ return this.sendEmailNotification(escalationId, context, content);
229
+ case 'sms':
230
+ return this.sendSmsNotification(escalationId, context, content);
231
+ case 'slack':
232
+ return this.sendSlackNotification(escalationId, context, content);
233
+ default:
234
+ return {
235
+ channel,
236
+ success: false,
237
+ error: `Unknown channel: ${channel}`,
238
+ timestamp,
239
+ };
240
+ }
241
+ }
242
+ /**
243
+ * Check if a channel is properly configured
244
+ */
245
+ isChannelConfigured(channel) {
246
+ switch (channel) {
247
+ case 'email':
248
+ return !!config.postmark.serverToken;
249
+ case 'sms':
250
+ return !!config.twilio.accountSid && !!config.twilio.authToken;
251
+ case 'slack':
252
+ return !!config.slack.botToken;
253
+ default:
254
+ return false;
255
+ }
256
+ }
257
+ /**
258
+ * Build notification content
259
+ */
260
+ buildNotificationContent(escalationId, context) {
261
+ const severityEmoji = {
262
+ critical: '🚨',
263
+ high: '⚠️',
264
+ medium: '📋',
265
+ low: 'ℹ️',
266
+ }[context.severity] || '📋';
267
+ const subject = `${severityEmoji} [${context.severity.toUpperCase()}] Support Escalation - ${context.trigger}`;
268
+ const body = `
269
+ Support Escalation #${escalationId}
270
+ ${'='.repeat(40)}
271
+
272
+ Severity: ${context.severity.toUpperCase()}
273
+ Trigger: ${context.trigger}
274
+ Reason: ${context.reason}
275
+
276
+ Customer: ${context.knowledgeContext?.customer?.companyName || 'Unknown'}
277
+ Conversation ID: ${context.conversationId}
278
+
279
+ View in Admin Portal:
280
+ ${config.escalation.adminBaseUrl}/support/escalations/${escalationId}
281
+
282
+ ---
283
+ This escalation requires human attention.
284
+ `.trim();
285
+ const shortBody = `${severityEmoji} Escalation: ${context.trigger}. ${context.reason}. View: ${config.escalation.adminBaseUrl}/support/escalations/${escalationId}`;
286
+ return { subject, body, shortBody };
287
+ }
288
+ /**
289
+ * Send email notification (placeholder - would use Postmark)
290
+ */
291
+ async sendEmailNotification(escalationId, context, content) {
292
+ // This would integrate with Postmark
293
+ // For now, return success (actual implementation in delivery module)
294
+ return {
295
+ channel: 'email',
296
+ success: true,
297
+ messageId: `email-${escalationId}`,
298
+ timestamp: new Date().toISOString(),
299
+ };
300
+ }
301
+ /**
302
+ * Send SMS notification (placeholder - would use Twilio)
303
+ */
304
+ async sendSmsNotification(escalationId, context, content) {
305
+ // This would integrate with Twilio
306
+ return {
307
+ channel: 'sms',
308
+ success: true,
309
+ messageId: `sms-${escalationId}`,
310
+ timestamp: new Date().toISOString(),
311
+ };
312
+ }
313
+ /**
314
+ * Send Slack notification (placeholder - would use Slack API)
315
+ */
316
+ async sendSlackNotification(escalationId, context, content) {
317
+ // This would integrate with Slack API
318
+ return {
319
+ channel: 'slack',
320
+ success: true,
321
+ messageId: `slack-${escalationId}`,
322
+ timestamp: new Date().toISOString(),
323
+ };
324
+ }
325
+ /**
326
+ * Create database fallback when all notification channels fail
327
+ */
328
+ async createDatabaseFallback(escalationId, context) {
329
+ // Mark escalation as requiring attention via database
330
+ await this.supabase
331
+ .from('support_escalations')
332
+ .update({
333
+ context_data: {
334
+ ...this.buildContextData(context),
335
+ allChannelsFailed: true,
336
+ requiresDatabaseFallback: true,
337
+ fallbackCreatedAt: new Date().toISOString(),
338
+ },
339
+ })
340
+ .eq('id', escalationId);
341
+ // Log for monitoring
342
+ console.error(`CRITICAL: All escalation channels failed for escalation ${escalationId}. Database fallback created.`);
343
+ }
344
+ /**
345
+ * Track response attempt failures
346
+ */
347
+ async trackResponseAttempt(conversationId, success, error) {
348
+ // Get current attempt count from conversation
349
+ const { data: conversation } = await this.supabase
350
+ .from('support_conversations')
351
+ .select('metadata')
352
+ .eq('id', conversationId)
353
+ .single();
354
+ const currentAttempts = conversation?.metadata?.responseAttempts ?? 0;
355
+ const newAttemptCount = currentAttempts + 1;
356
+ // Update attempt count
357
+ await this.supabase
358
+ .from('support_conversations')
359
+ .update({
360
+ metadata: {
361
+ ...conversation?.metadata,
362
+ responseAttempts: newAttemptCount,
363
+ lastAttemptSuccess: success,
364
+ lastAttemptError: error,
365
+ lastAttemptAt: new Date().toISOString(),
366
+ },
367
+ })
368
+ .eq('id', conversationId);
369
+ return {
370
+ shouldEscalate: !success && newAttemptCount >= config.agent.maxResponseAttempts,
371
+ attemptCount: newAttemptCount,
372
+ };
373
+ }
374
+ /**
375
+ * Detect human takeover (human responded in escalated conversation)
376
+ */
377
+ async detectHumanTakeover(conversationId) {
378
+ // Check if there are human-sent messages after escalation
379
+ const { data } = await this.supabase
380
+ .from('support_messages')
381
+ .select('id')
382
+ .eq('conversation_id', conversationId)
383
+ .eq('direction', 'outbound')
384
+ .order('created_at', { ascending: false })
385
+ .limit(1);
386
+ // If there's a recent outbound message from a human, mark as taken over
387
+ return (data?.length ?? 0) > 0;
388
+ }
389
+ /**
390
+ * Resolve an escalation
391
+ */
392
+ async resolveEscalation(escalationId, resolution) {
393
+ await this.supabase
394
+ .from('support_escalations')
395
+ .update({
396
+ response_received_at: new Date().toISOString(),
397
+ response_action: resolution.action,
398
+ resolution_notes: resolution.notes,
399
+ assigned_to: resolution.responderId,
400
+ })
401
+ .eq('id', escalationId);
402
+ }
403
+ }
404
+ // =============================================================================
405
+ // Singleton and Utility Functions
406
+ // =============================================================================
407
+ let escalationService = null;
408
+ export function getEscalationService() {
409
+ if (!escalationService) {
410
+ escalationService = new EscalationService();
411
+ }
412
+ return escalationService;
413
+ }
414
+ /**
415
+ * Create and route an escalation
416
+ */
417
+ export async function escalateConversation(context) {
418
+ return getEscalationService().escalate(context);
419
+ }
420
+ /**
421
+ * Build escalation context from analysis
422
+ */
423
+ export function buildEscalationContext(message, analysis, knowledge, trigger, severity, reason, attemptedResponses) {
424
+ return {
425
+ conversationId: analysis.conversationId,
426
+ messageId: message.id,
427
+ customerId: knowledge.customer?.id,
428
+ trigger,
429
+ severity,
430
+ reason,
431
+ analysisResult: analysis,
432
+ attemptedResponses,
433
+ knowledgeContext: knowledge,
434
+ };
435
+ }
436
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/escalation/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,97 @@
1
+ /**
2
+ * Deduplication Module
3
+ *
4
+ * Detects duplicate Q&A pairs using content hashing and optional embedding similarity.
5
+ * Prevents storage of near-identical entries in the knowledge base.
6
+ */
7
+ export interface DeduplicationResult {
8
+ isDuplicate: boolean;
9
+ duplicateId?: string;
10
+ similarity?: number;
11
+ method: 'hash' | 'embedding' | 'none';
12
+ contentHash: string;
13
+ }
14
+ export interface DeduplicationConfig {
15
+ similarityThreshold: number;
16
+ useEmbeddingSimilarity: boolean;
17
+ supabaseUrl: string;
18
+ supabaseServiceRoleKey: string;
19
+ }
20
+ export interface QAContent {
21
+ questionSubject?: string;
22
+ questionText: string;
23
+ responseText: string;
24
+ }
25
+ export declare class DeduplicationService {
26
+ private config;
27
+ private supabase;
28
+ private hashCache;
29
+ constructor(config: DeduplicationConfig);
30
+ /**
31
+ * Generate content hash for a Q&A pair
32
+ *
33
+ * Hash is based on normalized question + response text.
34
+ * Subject is not included as it varies more between duplicates.
35
+ */
36
+ generateContentHash(content: QAContent): string;
37
+ /**
38
+ * Check if content is a duplicate
39
+ */
40
+ checkDuplicate(content: QAContent): Promise<DeduplicationResult>;
41
+ /**
42
+ * Check for hash match in database
43
+ */
44
+ private checkHashInDatabase;
45
+ /**
46
+ * Check for similar entries using embedding similarity
47
+ * Note: Requires the entry to have an embedding
48
+ */
49
+ private checkEmbeddingSimilarity;
50
+ /**
51
+ * Add hash to local cache (for batch operations)
52
+ */
53
+ addToCache(contentHash: string): void;
54
+ /**
55
+ * Clear local hash cache
56
+ */
57
+ clearCache(): void;
58
+ /**
59
+ * Load existing hashes from database into cache
60
+ */
61
+ loadHashCache(limit?: number): Promise<number>;
62
+ /**
63
+ * Batch check for duplicates
64
+ */
65
+ checkBatchDuplicates(contents: QAContent[]): Promise<Map<string, DeduplicationResult>>;
66
+ /**
67
+ * Normalize text for consistent hashing
68
+ */
69
+ private normalizeText;
70
+ /**
71
+ * Get cache statistics
72
+ */
73
+ getCacheStats(): {
74
+ size: number;
75
+ };
76
+ /**
77
+ * Update configuration
78
+ */
79
+ updateConfig(config: Partial<DeduplicationConfig>): void;
80
+ }
81
+ /**
82
+ * Get singleton deduplication service instance
83
+ */
84
+ export declare function getDeduplicationService(): DeduplicationService;
85
+ /**
86
+ * Reset the singleton (for testing)
87
+ */
88
+ export declare function resetDeduplicationService(): void;
89
+ /**
90
+ * Quick content hash generation
91
+ */
92
+ export declare function hashContent(content: QAContent): string;
93
+ /**
94
+ * Quick duplicate check
95
+ */
96
+ export declare function isDuplicate(content: QAContent): Promise<boolean>;
97
+ //# sourceMappingURL=deduplication.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deduplication.d.ts","sourceRoot":"","sources":["../../src/extraction/deduplication.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AASH,MAAM,WAAW,mBAAmB;IAClC,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,GAAG,WAAW,GAAG,MAAM,CAAC;IACtC,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,mBAAmB;IAElC,mBAAmB,EAAE,MAAM,CAAC;IAG5B,sBAAsB,EAAE,OAAO,CAAC;IAGhC,WAAW,EAAE,MAAM,CAAC;IACpB,sBAAsB,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,WAAW,SAAS;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;CACtB;AAeD,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,MAAM,CAAsB;IACpC,OAAO,CAAC,QAAQ,CAAiB;IAGjC,OAAO,CAAC,SAAS,CAA0B;gBAE/B,MAAM,EAAE,mBAAmB;IAKvC;;;;;OAKG;IACH,mBAAmB,CAAC,OAAO,EAAE,SAAS,GAAG,MAAM;IAY/C;;OAEG;IACG,cAAc,CAAC,OAAO,EAAE,SAAS,GAAG,OAAO,CAAC,mBAAmB,CAAC;IA6CtE;;OAEG;YACW,mBAAmB;IAiBjC;;;OAGG;YACW,wBAAwB;IAUtC;;OAEG;IACH,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI;IAIrC;;OAEG;IACH,UAAU,IAAI,IAAI;IAIlB;;OAEG;IACG,aAAa,CAAC,KAAK,GAAE,MAAc,GAAG,OAAO,CAAC,MAAM,CAAC;IAmB3D;;OAEG;IACG,oBAAoB,CACxB,QAAQ,EAAE,SAAS,EAAE,GACpB,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;IAyE5C;;OAEG;IACH,OAAO,CAAC,aAAa;IASrB;;OAEG;IACH,aAAa,IAAI;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE;IAIjC;;OAEG;IACH,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,mBAAmB,CAAC,GAAG,IAAI;CAGzD;AAQD;;GAEG;AACH,wBAAgB,uBAAuB,IAAI,oBAAoB,CAkB9D;AAED;;GAEG;AACH,wBAAgB,yBAAyB,IAAI,IAAI,CAEhD;AAMD;;GAEG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,SAAS,GAAG,MAAM,CAEtD;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,CAGtE"}