@xapp/stentor-service-generative-ai 1.80.3 → 1.83.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.
|
@@ -31,6 +31,13 @@ export interface EmailAnalysisInput {
|
|
|
31
31
|
* context when the current email is a reply in an ongoing thread.
|
|
32
32
|
*/
|
|
33
33
|
threadHistory?: EmailThreadMessage[];
|
|
34
|
+
/**
|
|
35
|
+
* Raw email headers (e.g., Reply-To, X-Mailer). Provides additional context
|
|
36
|
+
* for the LLM to disambiguate the actual contact from template senders
|
|
37
|
+
* (e.g., Jobber, ServiceTitan). Values must be strings; if a header has
|
|
38
|
+
* multiple values, join them before passing.
|
|
39
|
+
*/
|
|
40
|
+
headers?: Record<string, string>;
|
|
34
41
|
}
|
|
35
42
|
/**
|
|
36
43
|
* Structured contact information extracted from an email body, particularly useful
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/*! Copyright (c) 2026, XAPP AI */
|
|
2
2
|
import type { CompletionPrompt, PromptGenerator, ResponseParser } from "../models";
|
|
3
3
|
import type { EmailAnalysisInput, EmailLeadAnalysis } from "../models/EmailAnalysis";
|
|
4
|
-
export declare const ANALYZE_EMAIL_VERSION = "1.
|
|
4
|
+
export declare const ANALYZE_EMAIL_VERSION = "1.1.0";
|
|
5
5
|
export interface AnalyzeEmailProps {
|
|
6
6
|
businessDescription?: string;
|
|
7
7
|
highValueLeadDescription?: string;
|
|
@@ -5,7 +5,9 @@ exports.analyzeEmailResponseParse = exports.generateAnalyzeEmail = exports.ANALY
|
|
|
5
5
|
exports.emailThreadToMessages = emailThreadToMessages;
|
|
6
6
|
const AnalyzeLead_1 = require("./AnalyzeLead");
|
|
7
7
|
const extractJSON_1 = require("../utils/extractJSON");
|
|
8
|
-
exports.ANALYZE_EMAIL_VERSION = "1.
|
|
8
|
+
exports.ANALYZE_EMAIL_VERSION = "1.1.0";
|
|
9
|
+
/** Headers forwarded to the LLM to help disambiguate the actual contact from template senders. */
|
|
10
|
+
const RELEVANT_HEADERS = ["reply-to", "x-mailer", "x-original-sender", "x-source"];
|
|
9
11
|
/**
|
|
10
12
|
* Converts an email (with optional thread history) into the messages array for an LLM completion prompt.
|
|
11
13
|
*
|
|
@@ -32,6 +34,24 @@ function emailThreadToMessages(system, email) {
|
|
|
32
34
|
const fromStr = email.from.name ? `${email.from.name} <${email.from.email}>` : email.from.email;
|
|
33
35
|
currentEmailContent += `\nFrom: ${fromStr}`;
|
|
34
36
|
}
|
|
37
|
+
// Include relevant headers that help disambiguate the actual contact
|
|
38
|
+
if (email.headers) {
|
|
39
|
+
// Build a lowercase-key lookup for case-insensitive matching.
|
|
40
|
+
// Duplicate keys (e.g. "Reply-To" and "reply-to") resolve to last-write-wins.
|
|
41
|
+
const lowerHeaders = {};
|
|
42
|
+
for (const [k, v] of Object.entries(email.headers)) {
|
|
43
|
+
lowerHeaders[k.toLowerCase()] = v;
|
|
44
|
+
}
|
|
45
|
+
for (const key of RELEVANT_HEADERS) {
|
|
46
|
+
if (lowerHeaders[key] != null) {
|
|
47
|
+
// Sanitize: strip newlines and cap length to limit prompt injection surface
|
|
48
|
+
const safeValue = lowerHeaders[key].replace(/[\r\n]+/g, " ").trim().slice(0, 200);
|
|
49
|
+
if (safeValue) {
|
|
50
|
+
currentEmailContent += `\n${key}: ${safeValue}`;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
35
55
|
currentEmailContent += `\n\n${email.body}`;
|
|
36
56
|
messages.push({ role: "user", content: currentEmailContent });
|
|
37
57
|
return messages;
|
|
@@ -74,7 +94,8 @@ Your job is to analyze the following inbound email received by the business and
|
|
|
74
94
|
IMPORTANT INSTRUCTIONS:
|
|
75
95
|
- Focus on the most recent/primary email content only. Ignore quoted reply chains (lines starting with ">"), forwarded content, and blocks beginning with "On ... wrote:" or "---Original Message---".
|
|
76
96
|
- Ignore email signatures, unsubscribe footers, physical address blocks, and legal disclaimers — unless the address or phone is the only contact info present.
|
|
77
|
-
- Some emails are system notifications from FSM/CRM tools (e.g., Jobber, ServiceTitan, Housecall Pro). These often embed lead data in a structured text format like "Contact name: X", "Phone: Y", "Email: Z". Extract that contact data and treat the embedded customer as the actual lead.
|
|
97
|
+
- Some emails are system notifications from FSM/CRM tools (e.g., Jobber, ServiceTitan, Housecall Pro). These often embed lead data in a structured text format like "Contact name: X", "Phone: Y", "Email: Z". Extract that contact data and treat the embedded customer as the actual lead. The From header on these emails is typically the system name (e.g., "The Jobber Team"), NOT the actual customer — always prefer names found in the email body over the From header display name.
|
|
98
|
+
- Additional email headers (reply-to, x-mailer, etc.) may be included when available. Use these as context clues — for example, a reply-to address different from the From address often indicates the actual customer contact.
|
|
78
99
|
|
|
79
100
|
You will return your analysis as a JSON object with the following properties:
|
|
80
101
|
|
|
@@ -182,7 +203,7 @@ Examples:
|
|
|
182
203
|
- Body: "scorpion and cricket issues" → "scorpion cricket issues"
|
|
183
204
|
- Body: "Contact name: John Smith, Service: Plumbing repair" → "plumbing repair"
|
|
184
205
|
|
|
185
|
-
For "extractedContact", extract any structured contact information found in the email body (especially from FSM/CRM notification formats like "Contact name: X", "Phone: Y"). Set "confidence" between 0.0 and 1.0 based on how confident you are in the extracted data. Return null for extractedContact if no meaningful contact information is present.
|
|
206
|
+
For "extractedContact", extract any structured contact information found in the email body (especially from FSM/CRM notification formats like "Contact name: X", "Phone: Y"). For fullName, always prefer a name extracted from the email body over the From header display name — the From header on FSM/CRM notifications is the system name, not the customer. Also consider the reply-to header if present. Set "confidence" between 0.0 and 1.0 based on how confident you are in the extracted data. Return null for extractedContact if no meaningful contact information is present.
|
|
186
207
|
`;
|
|
187
208
|
const messages = emailThreadToMessages(system, email);
|
|
188
209
|
const max_tokens = 768;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AnalyzeEmail.js","sourceRoot":"","sources":["../../src/prompts/AnalyzeEmail.ts"],"names":[],"mappings":";AAAA,kCAAkC;;;
|
|
1
|
+
{"version":3,"file":"AnalyzeEmail.js","sourceRoot":"","sources":["../../src/prompts/AnalyzeEmail.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
7
|
-
"version": "1.
|
|
7
|
+
"version": "1.83.0",
|
|
8
8
|
"description": "Generative AI Service",
|
|
9
9
|
"types": "lib/index",
|
|
10
10
|
"main": "lib/index",
|
|
@@ -46,5 +46,5 @@
|
|
|
46
46
|
"test": "mocha --recursive -r ts-node/register \"./src/**/*.test.ts\"",
|
|
47
47
|
"ftest": "mocha --recursive -r ts-node/register \"./src/**/*.ftest.ts\""
|
|
48
48
|
},
|
|
49
|
-
"gitHead": "
|
|
49
|
+
"gitHead": "4dd9119dad390f9859ec41ec39e1135816e160d1"
|
|
50
50
|
}
|