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.
- package/dist/admin-portal.d.ts +43 -0
- package/dist/admin-portal.d.ts.map +1 -0
- package/dist/admin-portal.js +166 -0
- package/dist/admin-portal.js.map +1 -0
- package/dist/analysis/entities.d.ts +73 -0
- package/dist/analysis/entities.d.ts.map +1 -0
- package/dist/analysis/entities.js +378 -0
- package/dist/analysis/entities.js.map +1 -0
- package/dist/analysis/index.d.ts +44 -0
- package/dist/analysis/index.d.ts.map +1 -0
- package/dist/analysis/index.js +243 -0
- package/dist/analysis/index.js.map +1 -0
- package/dist/analysis/intent.d.ts +49 -0
- package/dist/analysis/intent.d.ts.map +1 -0
- package/dist/analysis/intent.js +320 -0
- package/dist/analysis/intent.js.map +1 -0
- package/dist/analysis/sentiment.d.ts +57 -0
- package/dist/analysis/sentiment.d.ts.map +1 -0
- package/dist/analysis/sentiment.js +351 -0
- package/dist/analysis/sentiment.js.map +1 -0
- package/dist/brand/compliance.d.ts +122 -0
- package/dist/brand/compliance.d.ts.map +1 -0
- package/dist/brand/compliance.js +378 -0
- package/dist/brand/compliance.js.map +1 -0
- package/dist/brand/forbidden-terms.d.ts +99 -0
- package/dist/brand/forbidden-terms.d.ts.map +1 -0
- package/dist/brand/forbidden-terms.js +265 -0
- package/dist/brand/forbidden-terms.js.map +1 -0
- package/dist/brand/index.d.ts +10 -0
- package/dist/brand/index.d.ts.map +1 -0
- package/dist/brand/index.js +12 -0
- package/dist/brand/index.js.map +1 -0
- package/dist/config.d.ts +325 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +492 -0
- package/dist/config.js.map +1 -0
- package/dist/delivery/index.d.ts +84 -0
- package/dist/delivery/index.d.ts.map +1 -0
- package/dist/delivery/index.js +435 -0
- package/dist/delivery/index.js.map +1 -0
- package/dist/embeddings/cache.d.ts +96 -0
- package/dist/embeddings/cache.d.ts.map +1 -0
- package/dist/embeddings/cache.js +193 -0
- package/dist/embeddings/cache.js.map +1 -0
- package/dist/embeddings/index.d.ts +152 -0
- package/dist/embeddings/index.d.ts.map +1 -0
- package/dist/embeddings/index.js +337 -0
- package/dist/embeddings/index.js.map +1 -0
- package/dist/embeddings/openai-client.d.ts +67 -0
- package/dist/embeddings/openai-client.d.ts.map +1 -0
- package/dist/embeddings/openai-client.js +190 -0
- package/dist/embeddings/openai-client.js.map +1 -0
- package/dist/errors.d.ts +302 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +508 -0
- package/dist/errors.js.map +1 -0
- package/dist/escalation/index.d.ts +93 -0
- package/dist/escalation/index.d.ts.map +1 -0
- package/dist/escalation/index.js +436 -0
- package/dist/escalation/index.js.map +1 -0
- package/dist/extraction/deduplication.d.ts +97 -0
- package/dist/extraction/deduplication.d.ts.map +1 -0
- package/dist/extraction/deduplication.js +271 -0
- package/dist/extraction/deduplication.js.map +1 -0
- package/dist/extraction/gmail-extractor.d.ts +160 -0
- package/dist/extraction/gmail-extractor.d.ts.map +1 -0
- package/dist/extraction/gmail-extractor.js +396 -0
- package/dist/extraction/gmail-extractor.js.map +1 -0
- package/dist/extraction/gmail-token-manager.d.ts +36 -0
- package/dist/extraction/gmail-token-manager.d.ts.map +1 -0
- package/dist/extraction/gmail-token-manager.js +146 -0
- package/dist/extraction/gmail-token-manager.js.map +1 -0
- package/dist/extraction/index.d.ts +13 -0
- package/dist/extraction/index.d.ts.map +1 -0
- package/dist/extraction/index.js +20 -0
- package/dist/extraction/index.js.map +1 -0
- package/dist/extraction/pii-handler.d.ts +100 -0
- package/dist/extraction/pii-handler.d.ts.map +1 -0
- package/dist/extraction/pii-handler.js +295 -0
- package/dist/extraction/pii-handler.js.map +1 -0
- package/dist/extraction/pipeline.d.ts +94 -0
- package/dist/extraction/pipeline.d.ts.map +1 -0
- package/dist/extraction/pipeline.js +380 -0
- package/dist/extraction/pipeline.js.map +1 -0
- package/dist/extraction/quality-filter.d.ts +99 -0
- package/dist/extraction/quality-filter.d.ts.map +1 -0
- package/dist/extraction/quality-filter.js +370 -0
- package/dist/extraction/quality-filter.js.map +1 -0
- package/dist/extraction/rate-limiter.d.ts +90 -0
- package/dist/extraction/rate-limiter.d.ts.map +1 -0
- package/dist/extraction/rate-limiter.js +242 -0
- package/dist/extraction/rate-limiter.js.map +1 -0
- package/dist/extraction/state-manager.d.ts +126 -0
- package/dist/extraction/state-manager.d.ts.map +1 -0
- package/dist/extraction/state-manager.js +344 -0
- package/dist/extraction/state-manager.js.map +1 -0
- package/dist/generation/index.d.ts +75 -0
- package/dist/generation/index.d.ts.map +1 -0
- package/dist/generation/index.js +641 -0
- package/dist/generation/index.js.map +1 -0
- package/dist/index.d.ts +96 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +233 -0
- package/dist/index.js.map +1 -0
- package/dist/intake/index.d.ts +15 -0
- package/dist/intake/index.d.ts.map +1 -0
- package/dist/intake/index.js +19 -0
- package/dist/intake/index.js.map +1 -0
- package/dist/intake/normalizer.d.ts +163 -0
- package/dist/intake/normalizer.d.ts.map +1 -0
- package/dist/intake/normalizer.js +309 -0
- package/dist/intake/normalizer.js.map +1 -0
- package/dist/intake/postmark.d.ts +72 -0
- package/dist/intake/postmark.d.ts.map +1 -0
- package/dist/intake/postmark.js +276 -0
- package/dist/intake/postmark.js.map +1 -0
- package/dist/intake/slack.d.ts +106 -0
- package/dist/intake/slack.d.ts.map +1 -0
- package/dist/intake/slack.js +378 -0
- package/dist/intake/slack.js.map +1 -0
- package/dist/intake/twilio.d.ts +86 -0
- package/dist/intake/twilio.d.ts.map +1 -0
- package/dist/intake/twilio.js +283 -0
- package/dist/intake/twilio.js.map +1 -0
- package/dist/knowledge/index.d.ts +100 -0
- package/dist/knowledge/index.d.ts.map +1 -0
- package/dist/knowledge/index.js +516 -0
- package/dist/knowledge/index.js.map +1 -0
- package/dist/knowledge/invoice-resolver.d.ts +62 -0
- package/dist/knowledge/invoice-resolver.d.ts.map +1 -0
- package/dist/knowledge/invoice-resolver.js +267 -0
- package/dist/knowledge/invoice-resolver.js.map +1 -0
- package/dist/types.d.ts +535 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +48 -0
- package/dist/types.js.map +1 -0
- package/ga-service-account.json +13 -0
- package/gmail-knowledge-migration.sql +149 -0
- package/nul +1 -0
- package/package.json +55 -0
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Twilio SMS Webhook Handler
|
|
3
|
+
*
|
|
4
|
+
* Receives incoming SMS messages via Twilio webhook, validates signatures,
|
|
5
|
+
* and normalizes SMS content into the standard message format.
|
|
6
|
+
*/
|
|
7
|
+
import { createHmac, timingSafeEqual } from 'crypto';
|
|
8
|
+
import { config } from '../config.js';
|
|
9
|
+
import { IntakeError, WebhookValidationError } from '../errors.js';
|
|
10
|
+
import { normalizeTwilioSms, generateContentHash, validateMessageContent, scanAndAnnotateMessage, normalizePhoneNumber, } from './normalizer.js';
|
|
11
|
+
// =============================================================================
|
|
12
|
+
// Signature Validation
|
|
13
|
+
// =============================================================================
|
|
14
|
+
/**
|
|
15
|
+
* Validate Twilio webhook signature using HMAC-SHA1
|
|
16
|
+
*
|
|
17
|
+
* Twilio signs webhooks using the auth token and the full URL + params
|
|
18
|
+
*/
|
|
19
|
+
export function validateTwilioSignature(signature, url, params, authToken) {
|
|
20
|
+
if (!signature || !authToken) {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
// Build the string to sign
|
|
24
|
+
// Twilio sorts the params alphabetically and concatenates
|
|
25
|
+
const sortedKeys = Object.keys(params).sort();
|
|
26
|
+
const paramString = sortedKeys.map((key) => `${key}${params[key]}`).join('');
|
|
27
|
+
const stringToSign = url + paramString;
|
|
28
|
+
// Generate expected signature
|
|
29
|
+
const expectedSignature = createHmac('sha1', authToken)
|
|
30
|
+
.update(stringToSign, 'utf-8')
|
|
31
|
+
.digest('base64');
|
|
32
|
+
// Timing-safe comparison
|
|
33
|
+
try {
|
|
34
|
+
const sig1 = Buffer.from(signature);
|
|
35
|
+
const sig2 = Buffer.from(expectedSignature);
|
|
36
|
+
if (sig1.length !== sig2.length) {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
return timingSafeEqual(sig1, sig2);
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Validate Twilio webhook request
|
|
47
|
+
*/
|
|
48
|
+
export function validateTwilioWebhook(signature, url, params) {
|
|
49
|
+
const authToken = config.twilio.authToken;
|
|
50
|
+
if (!authToken) {
|
|
51
|
+
// If no auth token configured, skip signature validation but check required fields
|
|
52
|
+
return !!(params.MessageSid && params.From && params.To);
|
|
53
|
+
}
|
|
54
|
+
return validateTwilioSignature(signature, url, params, authToken);
|
|
55
|
+
}
|
|
56
|
+
// =============================================================================
|
|
57
|
+
// SMS Processing
|
|
58
|
+
// =============================================================================
|
|
59
|
+
/**
|
|
60
|
+
* Parse Twilio webhook body (URL-encoded)
|
|
61
|
+
*/
|
|
62
|
+
export function parseTwilioBody(body) {
|
|
63
|
+
const params = new URLSearchParams(body);
|
|
64
|
+
const result = {};
|
|
65
|
+
for (const [key, value] of params.entries()) {
|
|
66
|
+
result[key] = value;
|
|
67
|
+
}
|
|
68
|
+
return result;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Process an inbound Twilio SMS
|
|
72
|
+
*/
|
|
73
|
+
export async function processTwilioSms(payload) {
|
|
74
|
+
try {
|
|
75
|
+
// Normalize the SMS into standard message format
|
|
76
|
+
const message = normalizeTwilioSms(payload);
|
|
77
|
+
// Validate content exists
|
|
78
|
+
validateMessageContent(message);
|
|
79
|
+
// Generate content hash for deduplication
|
|
80
|
+
const contentHash = generateContentHash(message);
|
|
81
|
+
// Scan for forbidden terms
|
|
82
|
+
const { hasForbiddenTerms, detectedTerms } = scanAndAnnotateMessage(message);
|
|
83
|
+
return {
|
|
84
|
+
success: true,
|
|
85
|
+
message,
|
|
86
|
+
contentHash,
|
|
87
|
+
hasForbiddenTerms,
|
|
88
|
+
detectedTerms,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
catch (error) {
|
|
92
|
+
if (error instanceof IntakeError) {
|
|
93
|
+
return {
|
|
94
|
+
success: false,
|
|
95
|
+
hasForbiddenTerms: false,
|
|
96
|
+
detectedTerms: [],
|
|
97
|
+
error: error.message,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
return {
|
|
101
|
+
success: false,
|
|
102
|
+
hasForbiddenTerms: false,
|
|
103
|
+
detectedTerms: [],
|
|
104
|
+
error: error instanceof Error ? error.message : 'Unknown error processing SMS',
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Full webhook handler for Twilio inbound SMS
|
|
110
|
+
*/
|
|
111
|
+
export async function handleTwilioInbound(rawBody, signature, webhookUrl) {
|
|
112
|
+
// Parse URL-encoded body
|
|
113
|
+
const payload = parseTwilioBody(rawBody);
|
|
114
|
+
// Convert to params object for signature validation
|
|
115
|
+
const params = {};
|
|
116
|
+
for (const [key, value] of Object.entries(payload)) {
|
|
117
|
+
if (typeof value === 'string') {
|
|
118
|
+
params[key] = value;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
// Validate webhook signature
|
|
122
|
+
if (!validateTwilioWebhook(signature, webhookUrl, params)) {
|
|
123
|
+
throw new WebhookValidationError('sms', {
|
|
124
|
+
context: { reason: 'Invalid Twilio signature' },
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
// Process the SMS
|
|
128
|
+
return processTwilioSms(payload);
|
|
129
|
+
}
|
|
130
|
+
// =============================================================================
|
|
131
|
+
// SMS Utilities
|
|
132
|
+
// =============================================================================
|
|
133
|
+
/**
|
|
134
|
+
* Check if message is a STOP/unsubscribe request
|
|
135
|
+
*/
|
|
136
|
+
export function isOptOutMessage(body) {
|
|
137
|
+
const normalized = body.trim().toLowerCase();
|
|
138
|
+
const optOutKeywords = [
|
|
139
|
+
'stop',
|
|
140
|
+
'unsubscribe',
|
|
141
|
+
'cancel',
|
|
142
|
+
'end',
|
|
143
|
+
'quit',
|
|
144
|
+
'optout',
|
|
145
|
+
'opt out',
|
|
146
|
+
'stopall',
|
|
147
|
+
'stop all',
|
|
148
|
+
];
|
|
149
|
+
return optOutKeywords.includes(normalized);
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Check if message is a help request
|
|
153
|
+
*/
|
|
154
|
+
export function isHelpRequest(body) {
|
|
155
|
+
const normalized = body.trim().toLowerCase();
|
|
156
|
+
const helpKeywords = ['help', 'info', 'support'];
|
|
157
|
+
return helpKeywords.includes(normalized);
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Classify SMS message type
|
|
161
|
+
*/
|
|
162
|
+
export function classifySms(sms) {
|
|
163
|
+
const body = sms.Body?.trim() ?? '';
|
|
164
|
+
if (!body) {
|
|
165
|
+
return {
|
|
166
|
+
shouldProcess: false,
|
|
167
|
+
reason: 'Empty message',
|
|
168
|
+
classification: 'empty',
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
if (isOptOutMessage(body)) {
|
|
172
|
+
return {
|
|
173
|
+
shouldProcess: false,
|
|
174
|
+
reason: 'Opt-out request',
|
|
175
|
+
classification: 'opt_out',
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
if (isHelpRequest(body)) {
|
|
179
|
+
return {
|
|
180
|
+
shouldProcess: true,
|
|
181
|
+
classification: 'help',
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
return {
|
|
185
|
+
shouldProcess: true,
|
|
186
|
+
classification: 'support',
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
// =============================================================================
|
|
190
|
+
// MMS Handling
|
|
191
|
+
// =============================================================================
|
|
192
|
+
/**
|
|
193
|
+
* Check if SMS includes media attachments (MMS)
|
|
194
|
+
*/
|
|
195
|
+
export function hasMmsAttachments(sms) {
|
|
196
|
+
const numMedia = parseInt(sms.NumMedia || '0', 10);
|
|
197
|
+
return numMedia > 0;
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Extract MMS media URLs
|
|
201
|
+
*/
|
|
202
|
+
export function extractMmsMedia(sms) {
|
|
203
|
+
const numMedia = parseInt(sms.NumMedia || '0', 10);
|
|
204
|
+
const media = [];
|
|
205
|
+
for (let i = 0; i < numMedia; i++) {
|
|
206
|
+
const urlKey = `MediaUrl${i}`;
|
|
207
|
+
const typeKey = `MediaContentType${i}`;
|
|
208
|
+
const url = sms[urlKey];
|
|
209
|
+
const contentType = sms[typeKey] || 'application/octet-stream';
|
|
210
|
+
if (url) {
|
|
211
|
+
media.push({ url, contentType });
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
return media;
|
|
215
|
+
}
|
|
216
|
+
// =============================================================================
|
|
217
|
+
// Phone Number Utilities
|
|
218
|
+
// =============================================================================
|
|
219
|
+
/**
|
|
220
|
+
* Extract country code from phone number
|
|
221
|
+
*/
|
|
222
|
+
export function extractCountryCode(phone) {
|
|
223
|
+
const normalized = normalizePhoneNumber(phone);
|
|
224
|
+
// Common country codes
|
|
225
|
+
const countryCodes = {
|
|
226
|
+
'+1': 'US/CA',
|
|
227
|
+
'+44': 'UK',
|
|
228
|
+
'+61': 'AU',
|
|
229
|
+
'+49': 'DE',
|
|
230
|
+
'+33': 'FR',
|
|
231
|
+
'+34': 'ES',
|
|
232
|
+
'+39': 'IT',
|
|
233
|
+
'+81': 'JP',
|
|
234
|
+
'+86': 'CN',
|
|
235
|
+
'+91': 'IN',
|
|
236
|
+
};
|
|
237
|
+
for (const [code, country] of Object.entries(countryCodes)) {
|
|
238
|
+
if (normalized.startsWith(code)) {
|
|
239
|
+
return country;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
return undefined;
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Determine if phone number is US/Canada
|
|
246
|
+
*/
|
|
247
|
+
export function isNorthAmericanNumber(phone) {
|
|
248
|
+
const normalized = normalizePhoneNumber(phone);
|
|
249
|
+
return normalized.startsWith('+1');
|
|
250
|
+
}
|
|
251
|
+
// =============================================================================
|
|
252
|
+
// Response Generation for Twilio
|
|
253
|
+
// =============================================================================
|
|
254
|
+
/**
|
|
255
|
+
* Generate TwiML response for immediate reply
|
|
256
|
+
*/
|
|
257
|
+
export function generateTwimlResponse(message) {
|
|
258
|
+
if (!message) {
|
|
259
|
+
// Empty response - no auto-reply
|
|
260
|
+
return '<?xml version="1.0" encoding="UTF-8"?><Response></Response>';
|
|
261
|
+
}
|
|
262
|
+
// Escape XML entities
|
|
263
|
+
const escaped = message
|
|
264
|
+
.replace(/&/g, '&')
|
|
265
|
+
.replace(/</g, '<')
|
|
266
|
+
.replace(/>/g, '>')
|
|
267
|
+
.replace(/"/g, '"')
|
|
268
|
+
.replace(/'/g, ''');
|
|
269
|
+
return `<?xml version="1.0" encoding="UTF-8"?><Response><Message>${escaped}</Message></Response>`;
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Generate TwiML for opt-out confirmation
|
|
273
|
+
*/
|
|
274
|
+
export function generateOptOutResponse() {
|
|
275
|
+
return generateTwimlResponse("You've been unsubscribed from Catalist support messages. Reply HELP if you need assistance.");
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Generate TwiML for help response
|
|
279
|
+
*/
|
|
280
|
+
export function generateHelpResponse() {
|
|
281
|
+
return generateTwimlResponse('Catalist Support: Reply with your question and we\'ll get back to you. For urgent matters, email support@catalist.deals');
|
|
282
|
+
}
|
|
283
|
+
//# sourceMappingURL=twilio.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"twilio.js","sourceRoot":"","sources":["../../src/intake/twilio.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Knowledge Retrieval Module
|
|
3
|
+
*
|
|
4
|
+
* Retrieves relevant context for response generation:
|
|
5
|
+
* - Customer data from clients table
|
|
6
|
+
* - Product information from catalog
|
|
7
|
+
* - Order history and status
|
|
8
|
+
* - Policy and FAQ content
|
|
9
|
+
* - Similar historical conversations
|
|
10
|
+
* - Pre-approved response templates
|
|
11
|
+
*/
|
|
12
|
+
import { type Config } from '../config.js';
|
|
13
|
+
import type { KnowledgeContext, CustomerContext, ProductContext, OrderContext, SimilarConversation, ResponseTemplate, InboundMessage, AnalysisResult, IntentCategory, CustomerId } from '../types.js';
|
|
14
|
+
export declare class KnowledgeRetrievalService {
|
|
15
|
+
private supabase;
|
|
16
|
+
private embeddingService;
|
|
17
|
+
private effectiveConfig;
|
|
18
|
+
constructor(configOverride?: Config);
|
|
19
|
+
/**
|
|
20
|
+
* Retrieve complete knowledge context for a message
|
|
21
|
+
*/
|
|
22
|
+
retrieveContext(message: InboundMessage, analysis: AnalysisResult): Promise<KnowledgeContext>;
|
|
23
|
+
/**
|
|
24
|
+
* Retrieve customer data by sender identifiers
|
|
25
|
+
*
|
|
26
|
+
* Note: Uses the "User" table (not "Client") per actual Catalist schema
|
|
27
|
+
*/
|
|
28
|
+
retrieveCustomerData(message: InboundMessage): Promise<CustomerContext | undefined>;
|
|
29
|
+
/**
|
|
30
|
+
* Map database User record to CustomerContext
|
|
31
|
+
*/
|
|
32
|
+
private mapUserToCustomerContext;
|
|
33
|
+
/**
|
|
34
|
+
* Retrieve order history for a customer with associated Invoice data
|
|
35
|
+
*
|
|
36
|
+
* Note: Uses "PurchaseOrder" table (not "Order") per actual Catalist schema
|
|
37
|
+
* Also fetches Invoice data for each order via the Invoice table
|
|
38
|
+
*/
|
|
39
|
+
retrieveOrderHistory(customerId: CustomerId, specificOrderNumbers?: string[]): Promise<OrderContext[]>;
|
|
40
|
+
/**
|
|
41
|
+
* Retrieve product information by name or SKU
|
|
42
|
+
*
|
|
43
|
+
* Note: Uses actual Catalist Catalog schema with selling_price, selling_status
|
|
44
|
+
*/
|
|
45
|
+
retrieveProductInfo(productNames?: string[], productSkus?: string[]): Promise<ProductContext[]>;
|
|
46
|
+
/**
|
|
47
|
+
* Map Catalog record to ProductContext
|
|
48
|
+
*
|
|
49
|
+
* Note: Catalist uses selling_status (boolean) not quantity
|
|
50
|
+
*/
|
|
51
|
+
private mapCatalogToProductContext;
|
|
52
|
+
/**
|
|
53
|
+
* Retrieve response templates/knowledge for an intent
|
|
54
|
+
*
|
|
55
|
+
* Note: Uses support_knowledge table which stores Q&A pairs
|
|
56
|
+
*/
|
|
57
|
+
retrieveTemplates(intent: IntentCategory): Promise<ResponseTemplate[]>;
|
|
58
|
+
/**
|
|
59
|
+
* Retrieve similar historical conversations using semantic search
|
|
60
|
+
*
|
|
61
|
+
* Uses pgvector for embedding similarity search against gmail_knowledge_entries.
|
|
62
|
+
* Falls back to full-text search if embedding service is unavailable.
|
|
63
|
+
*/
|
|
64
|
+
retrieveSimilarConversations(messageText: string, intent: IntentCategory): Promise<SimilarConversation[]>;
|
|
65
|
+
/**
|
|
66
|
+
* Map resolution indicator string to ResolutionType enum
|
|
67
|
+
*/
|
|
68
|
+
private mapResolutionIndicator;
|
|
69
|
+
/**
|
|
70
|
+
* Build a summary string from question subject and text
|
|
71
|
+
*/
|
|
72
|
+
private buildConversationSummary;
|
|
73
|
+
}
|
|
74
|
+
export declare function getKnowledgeRetrievalService(configOverride?: Config): KnowledgeRetrievalService;
|
|
75
|
+
/**
|
|
76
|
+
* Retrieve knowledge context for a message
|
|
77
|
+
*/
|
|
78
|
+
export declare function retrieveKnowledgeContext(message: InboundMessage, analysis: AnalysisResult): Promise<KnowledgeContext>;
|
|
79
|
+
/**
|
|
80
|
+
* Quick customer lookup
|
|
81
|
+
*/
|
|
82
|
+
export declare function lookupCustomer(message: InboundMessage): Promise<CustomerContext | undefined>;
|
|
83
|
+
/**
|
|
84
|
+
* Check if knowledge context has sufficient data for autonomous response
|
|
85
|
+
*/
|
|
86
|
+
export declare function hassufficientContext(context: KnowledgeContext): boolean;
|
|
87
|
+
/**
|
|
88
|
+
* Calculate overall context confidence
|
|
89
|
+
*/
|
|
90
|
+
export declare function calculateContextConfidence(context: KnowledgeContext): number;
|
|
91
|
+
export { InvoiceResolverService, getInvoiceResolverService, resolveInvoice, isInvoiceRelatedQuery, } from './invoice-resolver.js';
|
|
92
|
+
/**
|
|
93
|
+
* Alias for getKnowledgeRetrievalService (used by main index.ts)
|
|
94
|
+
*/
|
|
95
|
+
export declare const getKnowledgeService: typeof getKnowledgeRetrievalService;
|
|
96
|
+
/**
|
|
97
|
+
* Alias for retrieveKnowledgeContext (used by main index.ts)
|
|
98
|
+
*/
|
|
99
|
+
export declare const retrieveKnowledge: typeof retrieveKnowledgeContext;
|
|
100
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/knowledge/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,EAAU,KAAK,MAAM,EAAE,MAAM,cAAc,CAAC;AAInD,OAAO,KAAK,EACV,gBAAgB,EAChB,eAAe,EACf,cAAc,EACd,YAAY,EAGZ,mBAAmB,EACnB,gBAAgB,EAEhB,cAAc,EACd,cAAc,EACd,cAAc,EACd,UAAU,EACX,MAAM,aAAa,CAAC;AAOrB,qBAAa,yBAAyB;IACpC,OAAO,CAAC,QAAQ,CAAiB;IACjC,OAAO,CAAC,gBAAgB,CAAiC;IACzD,OAAO,CAAC,eAAe,CAAS;gBAEpB,cAAc,CAAC,EAAE,MAAM;IAmBnC;;OAEG;IACG,eAAe,CACnB,OAAO,EAAE,cAAc,EACvB,QAAQ,EAAE,cAAc,GACvB,OAAO,CAAC,gBAAgB,CAAC;IAsG5B;;;;OAIG;IACG,oBAAoB,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,GAAG,SAAS,CAAC;IAsCzF;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAoBhC;;;;;OAKG;IACG,oBAAoB,CACxB,UAAU,EAAE,UAAU,EACtB,oBAAoB,CAAC,EAAE,MAAM,EAAE,GAC9B,OAAO,CAAC,YAAY,EAAE,CAAC;IAsE1B;;;;OAIG;IACG,mBAAmB,CACvB,YAAY,CAAC,EAAE,MAAM,EAAE,EACvB,WAAW,CAAC,EAAE,MAAM,EAAE,GACrB,OAAO,CAAC,cAAc,EAAE,CAAC;IAsC5B;;;;OAIG;IACH,OAAO,CAAC,0BAA0B;IAgClC;;;;OAIG;IACG,iBAAiB,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAwC5E;;;;;OAKG;IACG,4BAA4B,CAChC,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,cAAc,GACrB,OAAO,CAAC,mBAAmB,EAAE,CAAC;IAkEjC;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAuB9B;;OAEG;IACH,OAAO,CAAC,wBAAwB;CAiBjC;AAQD,wBAAgB,4BAA4B,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,yBAAyB,CAU/F;AAED;;GAEG;AACH,wBAAsB,wBAAwB,CAC5C,OAAO,EAAE,cAAc,EACvB,QAAQ,EAAE,cAAc,GACvB,OAAO,CAAC,gBAAgB,CAAC,CAE3B;AAED;;GAEG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,eAAe,GAAG,SAAS,CAAC,CAEtC;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAUvE;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,gBAAgB,GAAG,MAAM,CAe5E;AAMD,OAAO,EACL,sBAAsB,EACtB,yBAAyB,EACzB,cAAc,EACd,qBAAqB,GACtB,MAAM,uBAAuB,CAAC;AAM/B;;GAEG;AACH,eAAO,MAAM,mBAAmB,qCAA+B,CAAC;AAEhE;;GAEG;AACH,eAAO,MAAM,iBAAiB,iCAA2B,CAAC"}
|