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,320 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Intent Classification Service
|
|
3
|
+
*
|
|
4
|
+
* Categorizes support messages into intent categories using Claude.
|
|
5
|
+
* Determines what the customer is asking about or trying to accomplish.
|
|
6
|
+
*/
|
|
7
|
+
import Anthropic from '@anthropic-ai/sdk';
|
|
8
|
+
import { config } from '../config.js';
|
|
9
|
+
import { AnalysisError, IntentClassificationError } from '../errors.js';
|
|
10
|
+
// =============================================================================
|
|
11
|
+
// Intent Categories and Descriptions
|
|
12
|
+
// =============================================================================
|
|
13
|
+
const INTENT_DESCRIPTIONS = {
|
|
14
|
+
order_status: 'Inquiries about order status, tracking, delivery, or shipment updates',
|
|
15
|
+
pricing_inquiry: 'Questions about product pricing, discounts, MOQ, or price quotes',
|
|
16
|
+
availability_check: 'Questions about product availability, stock levels, or restocking dates',
|
|
17
|
+
documentation_request: 'Requests for invoices, receipts, certificates, or other documentation',
|
|
18
|
+
returns_damages: 'Issues with damaged products, returns, refunds, or exchanges',
|
|
19
|
+
account_inquiry: 'Questions about account settings, login issues, or account status',
|
|
20
|
+
product_sourcing: 'Requests to find specific products, brands, or alternatives',
|
|
21
|
+
onboarding_help: 'New customer setup, getting started questions, or platform guidance',
|
|
22
|
+
complaint: 'Explicit complaints, frustrations, or negative feedback about service',
|
|
23
|
+
feedback: 'General feedback, suggestions, or positive comments',
|
|
24
|
+
general_question: 'General questions about Catalist, policies, or how things work',
|
|
25
|
+
other: 'Messages that do not fit into any other category',
|
|
26
|
+
};
|
|
27
|
+
// =============================================================================
|
|
28
|
+
// Intent Classification Prompt
|
|
29
|
+
// =============================================================================
|
|
30
|
+
const INTENT_CLASSIFICATION_PROMPT = `You are an intent classification system for Catalist, a B2B marketplace platform.
|
|
31
|
+
|
|
32
|
+
Your task is to classify customer support messages into one of the following intent categories:
|
|
33
|
+
|
|
34
|
+
${Object.entries(INTENT_DESCRIPTIONS)
|
|
35
|
+
.map(([category, description]) => `- **${category}**: ${description}`)
|
|
36
|
+
.join('\n')}
|
|
37
|
+
|
|
38
|
+
## Instructions
|
|
39
|
+
|
|
40
|
+
1. Read the customer message carefully
|
|
41
|
+
2. Consider the primary intent (what they MOST want)
|
|
42
|
+
3. Consider if there's a secondary intent
|
|
43
|
+
4. Provide a confidence score from 0.0 to 1.0
|
|
44
|
+
5. Briefly explain your reasoning
|
|
45
|
+
|
|
46
|
+
## Response Format
|
|
47
|
+
|
|
48
|
+
Respond with a JSON object in this exact format:
|
|
49
|
+
{
|
|
50
|
+
"primary": "intent_category",
|
|
51
|
+
"secondary": "intent_category or null",
|
|
52
|
+
"confidence": 0.85,
|
|
53
|
+
"reasoning": "Brief explanation of classification"
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
## Important Notes
|
|
57
|
+
|
|
58
|
+
- Be conservative with confidence scores. Use 0.9+ only when intent is unmistakable.
|
|
59
|
+
- If message mentions multiple topics, choose the most actionable as primary.
|
|
60
|
+
- "complaint" takes precedence if there's explicit frustration, even with another intent.
|
|
61
|
+
- "other" is a last resort when no category fits reasonably.
|
|
62
|
+
`;
|
|
63
|
+
// =============================================================================
|
|
64
|
+
// Intent Classification Service
|
|
65
|
+
// =============================================================================
|
|
66
|
+
export class IntentClassificationService {
|
|
67
|
+
client = null;
|
|
68
|
+
getClient() {
|
|
69
|
+
if (!this.client) {
|
|
70
|
+
// Use API key if available
|
|
71
|
+
if (config.claude.apiKey) {
|
|
72
|
+
this.client = new Anthropic({
|
|
73
|
+
apiKey: config.claude.apiKey,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
throw new AnalysisError('Claude API key not configured', 'intent', {
|
|
78
|
+
context: { reason: 'Missing ANTHROPIC_API_KEY' },
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return this.client;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Classify the intent of a message
|
|
86
|
+
*/
|
|
87
|
+
async classify(message, conversationContext) {
|
|
88
|
+
const startTime = Date.now();
|
|
89
|
+
try {
|
|
90
|
+
const client = this.getClient();
|
|
91
|
+
// Build the message content
|
|
92
|
+
let content = message.content.text;
|
|
93
|
+
if (message.content.subject) {
|
|
94
|
+
content = `Subject: ${message.content.subject}\n\n${content}`;
|
|
95
|
+
}
|
|
96
|
+
// Add conversation context if available
|
|
97
|
+
let systemPrompt = INTENT_CLASSIFICATION_PROMPT;
|
|
98
|
+
if (conversationContext) {
|
|
99
|
+
systemPrompt += `\n\n## Previous Conversation Context\n${conversationContext}`;
|
|
100
|
+
}
|
|
101
|
+
const response = await client.messages.create({
|
|
102
|
+
model: config.claude.model,
|
|
103
|
+
max_tokens: 256,
|
|
104
|
+
system: systemPrompt,
|
|
105
|
+
messages: [
|
|
106
|
+
{
|
|
107
|
+
role: 'user',
|
|
108
|
+
content: `Classify the intent of this customer message:\n\n${content}`,
|
|
109
|
+
},
|
|
110
|
+
],
|
|
111
|
+
});
|
|
112
|
+
// Extract the text response
|
|
113
|
+
const textContent = response.content.find((c) => c.type === 'text');
|
|
114
|
+
if (!textContent || textContent.type !== 'text') {
|
|
115
|
+
throw new AnalysisError('No text response from Claude', 'intent');
|
|
116
|
+
}
|
|
117
|
+
// Parse the JSON response
|
|
118
|
+
const result = this.parseClassificationResponse(textContent.text);
|
|
119
|
+
// Validate the classification
|
|
120
|
+
if (!this.isValidIntentCategory(result.primary)) {
|
|
121
|
+
throw new IntentClassificationError(`Invalid primary intent: ${result.primary}`, result.confidence, {
|
|
122
|
+
messageId: message.id,
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
return {
|
|
126
|
+
primary: result.primary,
|
|
127
|
+
secondary: result.secondary,
|
|
128
|
+
confidence: result.confidence,
|
|
129
|
+
reasoning: result.reasoning,
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
catch (error) {
|
|
133
|
+
if (error instanceof AnalysisError || error instanceof IntentClassificationError) {
|
|
134
|
+
throw error;
|
|
135
|
+
}
|
|
136
|
+
throw new AnalysisError(`Intent classification failed: ${error instanceof Error ? error.message : 'Unknown error'}`, 'intent', {
|
|
137
|
+
cause: error instanceof Error ? error : undefined,
|
|
138
|
+
messageId: message.id,
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Parse the classification response from Claude
|
|
144
|
+
*/
|
|
145
|
+
parseClassificationResponse(text) {
|
|
146
|
+
// Try to extract JSON from the response
|
|
147
|
+
const jsonMatch = text.match(/\{[\s\S]*\}/);
|
|
148
|
+
if (!jsonMatch) {
|
|
149
|
+
throw new AnalysisError('Could not parse intent classification JSON', 'intent', {
|
|
150
|
+
context: { response: text.substring(0, 200) },
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
try {
|
|
154
|
+
const parsed = JSON.parse(jsonMatch[0]);
|
|
155
|
+
return {
|
|
156
|
+
primary: parsed.primary ?? 'other',
|
|
157
|
+
secondary: parsed.secondary ?? null,
|
|
158
|
+
confidence: Math.min(1, Math.max(0, parsed.confidence ?? 0.5)),
|
|
159
|
+
reasoning: parsed.reasoning ?? '',
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
catch {
|
|
163
|
+
throw new AnalysisError('Invalid JSON in intent classification response', 'intent', {
|
|
164
|
+
context: { response: text.substring(0, 200) },
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Validate that a string is a valid intent category
|
|
170
|
+
*/
|
|
171
|
+
isValidIntentCategory(category) {
|
|
172
|
+
return Object.keys(INTENT_DESCRIPTIONS).includes(category);
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Classify intent using heuristics (fallback when Claude is unavailable)
|
|
176
|
+
*/
|
|
177
|
+
classifyWithHeuristics(message) {
|
|
178
|
+
const text = (message.content.text + ' ' + (message.content.subject ?? '')).toLowerCase();
|
|
179
|
+
// Define keyword patterns for each intent
|
|
180
|
+
const patterns = [
|
|
181
|
+
{
|
|
182
|
+
intent: 'order_status',
|
|
183
|
+
keywords: ['order', 'tracking', 'shipment', 'delivery', 'shipped', 'status', 'where is'],
|
|
184
|
+
weight: 1.0,
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
intent: 'pricing_inquiry',
|
|
188
|
+
keywords: ['price', 'pricing', 'cost', 'discount', 'moq', 'quote', 'how much'],
|
|
189
|
+
weight: 1.0,
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
intent: 'availability_check',
|
|
193
|
+
keywords: ['available', 'in stock', 'stock', 'inventory', 'restock', 'when will'],
|
|
194
|
+
weight: 1.0,
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
intent: 'documentation_request',
|
|
198
|
+
keywords: ['invoice', 'receipt', 'certificate', 'documentation', 'document', 'coa', 'coc'],
|
|
199
|
+
weight: 1.0,
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
intent: 'returns_damages',
|
|
203
|
+
keywords: ['return', 'refund', 'damaged', 'broken', 'exchange', 'wrong item', 'defective'],
|
|
204
|
+
weight: 1.2,
|
|
205
|
+
},
|
|
206
|
+
{
|
|
207
|
+
intent: 'account_inquiry',
|
|
208
|
+
keywords: ['account', 'login', 'password', 'sign in', 'access', 'profile'],
|
|
209
|
+
weight: 1.0,
|
|
210
|
+
},
|
|
211
|
+
{
|
|
212
|
+
intent: 'product_sourcing',
|
|
213
|
+
keywords: ['looking for', 'source', 'find', 'alternative', 'do you have', 'can you get'],
|
|
214
|
+
weight: 0.9,
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
intent: 'onboarding_help',
|
|
218
|
+
keywords: ['get started', 'new account', 'how do i', 'first order', 'setup', 'register'],
|
|
219
|
+
weight: 1.0,
|
|
220
|
+
},
|
|
221
|
+
{
|
|
222
|
+
intent: 'complaint',
|
|
223
|
+
keywords: [
|
|
224
|
+
'disappointed',
|
|
225
|
+
'frustrated',
|
|
226
|
+
'unacceptable',
|
|
227
|
+
'terrible',
|
|
228
|
+
'worst',
|
|
229
|
+
'complaint',
|
|
230
|
+
'upset',
|
|
231
|
+
],
|
|
232
|
+
weight: 1.5,
|
|
233
|
+
},
|
|
234
|
+
{
|
|
235
|
+
intent: 'feedback',
|
|
236
|
+
keywords: ['suggestion', 'feedback', 'love', 'great', 'awesome', 'recommend'],
|
|
237
|
+
weight: 0.8,
|
|
238
|
+
},
|
|
239
|
+
];
|
|
240
|
+
// Score each intent
|
|
241
|
+
let bestMatch = {
|
|
242
|
+
intent: 'general_question',
|
|
243
|
+
score: 0,
|
|
244
|
+
};
|
|
245
|
+
let secondBest = null;
|
|
246
|
+
for (const pattern of patterns) {
|
|
247
|
+
let score = 0;
|
|
248
|
+
for (const keyword of pattern.keywords) {
|
|
249
|
+
if (text.includes(keyword)) {
|
|
250
|
+
score += pattern.weight;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
if (score > bestMatch.score) {
|
|
254
|
+
secondBest = { ...bestMatch };
|
|
255
|
+
bestMatch = { intent: pattern.intent, score };
|
|
256
|
+
}
|
|
257
|
+
else if (!secondBest || score > secondBest.score) {
|
|
258
|
+
secondBest = { intent: pattern.intent, score };
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
// Calculate confidence based on match strength
|
|
262
|
+
const confidence = Math.min(0.75, bestMatch.score * 0.15);
|
|
263
|
+
return {
|
|
264
|
+
primary: bestMatch.intent,
|
|
265
|
+
secondary: secondBest && secondBest.score > 0.5 ? secondBest.intent : undefined,
|
|
266
|
+
confidence,
|
|
267
|
+
reasoning: 'Classified using keyword heuristics (Claude unavailable)',
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
// =============================================================================
|
|
272
|
+
// Singleton and Utility Functions
|
|
273
|
+
// =============================================================================
|
|
274
|
+
let intentService = null;
|
|
275
|
+
export function getIntentClassificationService() {
|
|
276
|
+
if (!intentService) {
|
|
277
|
+
intentService = new IntentClassificationService();
|
|
278
|
+
}
|
|
279
|
+
return intentService;
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* Classify message intent
|
|
283
|
+
*/
|
|
284
|
+
export async function classifyIntent(message, conversationContext) {
|
|
285
|
+
return getIntentClassificationService().classify(message, conversationContext);
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* Classify intent using heuristics (fallback)
|
|
289
|
+
*/
|
|
290
|
+
export function classifyIntentHeuristic(message) {
|
|
291
|
+
return getIntentClassificationService().classifyWithHeuristics(message);
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Get intent description
|
|
295
|
+
*/
|
|
296
|
+
export function getIntentDescription(intent) {
|
|
297
|
+
return INTENT_DESCRIPTIONS[intent];
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* Check if intent requires immediate attention
|
|
301
|
+
*/
|
|
302
|
+
export function isHighPriorityIntent(intent) {
|
|
303
|
+
const highPriority = ['complaint', 'returns_damages'];
|
|
304
|
+
return highPriority.includes(intent);
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Check if intent can likely be handled autonomously
|
|
308
|
+
*/
|
|
309
|
+
export function isAutonomouslyHandleableIntent(intent) {
|
|
310
|
+
const autonomous = [
|
|
311
|
+
'order_status',
|
|
312
|
+
'pricing_inquiry',
|
|
313
|
+
'availability_check',
|
|
314
|
+
'documentation_request',
|
|
315
|
+
'general_question',
|
|
316
|
+
'onboarding_help',
|
|
317
|
+
];
|
|
318
|
+
return autonomous.includes(intent);
|
|
319
|
+
}
|
|
320
|
+
//# sourceMappingURL=intent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"intent.js","sourceRoot":"","sources":["../../src/analysis/intent.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sentiment Analysis Service
|
|
3
|
+
*
|
|
4
|
+
* Analyzes message sentiment and urgency using Claude.
|
|
5
|
+
* Determines customer emotional state and time-sensitivity of request.
|
|
6
|
+
*/
|
|
7
|
+
import type { SentimentAnalysis, UrgencyLevel, InboundMessage } from '../types.js';
|
|
8
|
+
export declare class SentimentAnalysisService {
|
|
9
|
+
private client;
|
|
10
|
+
private getClient;
|
|
11
|
+
/**
|
|
12
|
+
* Analyze sentiment and urgency of a message
|
|
13
|
+
*/
|
|
14
|
+
analyze(message: InboundMessage): Promise<SentimentAnalysis>;
|
|
15
|
+
/**
|
|
16
|
+
* Parse the sentiment response from Claude
|
|
17
|
+
*/
|
|
18
|
+
private parseSentimentResponse;
|
|
19
|
+
/**
|
|
20
|
+
* Validate sentiment category
|
|
21
|
+
*/
|
|
22
|
+
private validateSentimentCategory;
|
|
23
|
+
/**
|
|
24
|
+
* Validate urgency level
|
|
25
|
+
*/
|
|
26
|
+
private validateUrgencyLevel;
|
|
27
|
+
/**
|
|
28
|
+
* Normalize score to expected range
|
|
29
|
+
*/
|
|
30
|
+
private normalizeScore;
|
|
31
|
+
/**
|
|
32
|
+
* Analyze sentiment using heuristics (fallback)
|
|
33
|
+
*/
|
|
34
|
+
analyzeWithHeuristics(message: InboundMessage): SentimentAnalysis;
|
|
35
|
+
}
|
|
36
|
+
export declare function getSentimentAnalysisService(): SentimentAnalysisService;
|
|
37
|
+
/**
|
|
38
|
+
* Analyze message sentiment
|
|
39
|
+
*/
|
|
40
|
+
export declare function analyzeSentiment(message: InboundMessage): Promise<SentimentAnalysis>;
|
|
41
|
+
/**
|
|
42
|
+
* Analyze sentiment using heuristics (fallback)
|
|
43
|
+
*/
|
|
44
|
+
export declare function analyzeSentimentHeuristic(message: InboundMessage): SentimentAnalysis;
|
|
45
|
+
/**
|
|
46
|
+
* Check if sentiment indicates escalation should be considered
|
|
47
|
+
*/
|
|
48
|
+
export declare function shouldConsiderEscalationBySentiment(sentiment: SentimentAnalysis): boolean;
|
|
49
|
+
/**
|
|
50
|
+
* Get urgency score (0-1) for ranking
|
|
51
|
+
*/
|
|
52
|
+
export declare function getUrgencyScore(urgency: UrgencyLevel): number;
|
|
53
|
+
/**
|
|
54
|
+
* Combine urgency from multiple sources
|
|
55
|
+
*/
|
|
56
|
+
export declare function combineUrgency(levels: UrgencyLevel[]): UrgencyLevel;
|
|
57
|
+
//# sourceMappingURL=sentiment.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sentiment.d.ts","sourceRoot":"","sources":["../../src/analysis/sentiment.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,KAAK,EAEV,iBAAiB,EACjB,YAAY,EACZ,cAAc,EACf,MAAM,aAAa,CAAC;AA2ErB,qBAAa,wBAAwB;IACnC,OAAO,CAAC,MAAM,CAA0B;IAExC,OAAO,CAAC,SAAS;IAejB;;OAEG;IACG,OAAO,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAwClE;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAkC9B;;OAEG;IACH,OAAO,CAAC,yBAAyB;IAOjC;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAY5B;;OAEG;IACH,OAAO,CAAC,cAAc;IAetB;;OAEG;IACH,qBAAqB,CAAC,OAAO,EAAE,cAAc,GAAG,iBAAiB;CA8FlE;AAQD,wBAAgB,2BAA2B,IAAI,wBAAwB,CAKtE;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAE1F;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,cAAc,GAAG,iBAAiB,CAEpF;AAED;;GAEG;AACH,wBAAgB,mCAAmC,CAAC,SAAS,EAAE,iBAAiB,GAAG,OAAO,CAmBzF;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,YAAY,GAAG,MAAM,CAa7D;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,YAAY,CAKnE"}
|