@lssm/example.ai-support-bot 0.0.0-canary-20251217060834 → 0.0.0-canary-20251217072406
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/.turbo/turbo-build$colon$bundle.log +66 -13
- package/.turbo/turbo-build.log +65 -12
- package/CHANGELOG.md +6 -5
- package/dist/docs/ai-support-bot.docblock.js +27 -12
- package/dist/docs/index.js +1 -1
- package/dist/example.js +38 -1
- package/dist/index.js +5 -1
- package/dist/libs/contracts/dist/docs/PUBLISHING.docblock.js +16 -0
- package/dist/libs/contracts/dist/docs/accessibility_wcag_compliance_specs.docblock.js +16 -0
- package/dist/libs/contracts/dist/docs/index.js +29 -0
- package/dist/libs/contracts/dist/docs/presentations.js +71 -0
- package/dist/libs/contracts/dist/docs/registry.js +44 -0
- package/dist/libs/contracts/dist/docs/tech/PHASE_1_QUICKSTART.docblock.js +16 -0
- package/dist/libs/contracts/dist/docs/tech/PHASE_2_AI_NATIVE_OPERATIONS.docblock.js +16 -0
- package/dist/libs/contracts/dist/docs/tech/PHASE_3_AUTO_EVOLUTION.docblock.js +16 -0
- package/dist/libs/contracts/dist/docs/tech/PHASE_4_PERSONALIZATION_ENGINE.docblock.js +16 -0
- package/dist/libs/contracts/dist/docs/tech/PHASE_5_ZERO_TOUCH_OPERATIONS.docblock.js +16 -0
- package/dist/libs/contracts/dist/docs/tech/auth/better-auth-nextjs.docblock.js +80 -0
- package/dist/libs/contracts/dist/docs/tech/contracts/openapi-export.docblock.js +57 -0
- package/dist/libs/contracts/dist/docs/tech/lifecycle-stage-system.docblock.js +16 -0
- package/dist/libs/contracts/dist/docs/tech/llm/llm-integration.docblock.js +357 -0
- package/dist/libs/contracts/dist/docs/tech/mcp-endpoints.docblock.js +37 -0
- package/dist/libs/contracts/dist/docs/tech/presentation-runtime.docblock.js +16 -0
- package/dist/libs/contracts/dist/docs/tech/schema/README.docblock.js +20 -0
- package/dist/libs/contracts/dist/docs/tech/studio/learning-events.docblock.js +48 -0
- package/dist/libs/contracts/dist/docs/tech/studio/learning-journeys.docblock.js +79 -0
- package/dist/libs/contracts/dist/docs/tech/studio/platform-admin-panel.docblock.js +84 -0
- package/dist/libs/contracts/dist/docs/tech/studio/project-access-teams.docblock.js +45 -0
- package/dist/libs/contracts/dist/docs/tech/studio/project-routing.docblock.js +67 -0
- package/dist/libs/contracts/dist/docs/tech/studio/sandbox-unlogged.docblock.js +40 -0
- package/dist/libs/contracts/dist/docs/tech/studio/team-invitations.docblock.js +69 -0
- package/dist/libs/contracts/dist/docs/tech/studio/workspace-ops.docblock.js +47 -0
- package/dist/libs/contracts/dist/docs/tech/studio/workspaces.docblock.js +62 -0
- package/dist/libs/contracts/dist/docs/tech/telemetry-ingest.docblock.js +155 -0
- package/dist/libs/contracts/dist/docs/tech/templates/runtime.docblock.js +20 -0
- package/dist/libs/contracts/dist/docs/tech/vscode-extension.docblock.js +101 -0
- package/dist/libs/contracts/dist/docs/tech/workflows/overview.docblock.js +20 -0
- package/dist/libs/logger/dist/context.node.js +78 -0
- package/dist/libs/logger/dist/elysia-plugin.js +3 -0
- package/dist/libs/logger/dist/formatters.js +163 -0
- package/dist/libs/logger/dist/index.js +7 -0
- package/dist/libs/logger/dist/logger.node.js +189 -0
- package/dist/libs/logger/dist/timer.js +126 -0
- package/dist/libs/logger/dist/tracer.node.js +115 -0
- package/dist/libs/logger/dist/types.js +13 -0
- package/dist/libs/support-bot/dist/bot/auto-responder.js +83 -0
- package/dist/libs/support-bot/dist/bot/index.js +2 -0
- package/dist/libs/support-bot/dist/bot/tools.js +71 -0
- package/dist/libs/support-bot/dist/rag/ticket-resolver.js +63 -0
- package/dist/libs/support-bot/dist/tickets/classifier.js +198 -0
- package/dist/setup.js +47 -1
- package/package.json +8 -7
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
//#region ../../libs/support-bot/dist/tickets/classifier.js
|
|
2
|
+
const CATEGORY_KEYWORDS = {
|
|
3
|
+
billing: [
|
|
4
|
+
"invoice",
|
|
5
|
+
"payout",
|
|
6
|
+
"refund",
|
|
7
|
+
"charge",
|
|
8
|
+
"billing",
|
|
9
|
+
"payment"
|
|
10
|
+
],
|
|
11
|
+
technical: [
|
|
12
|
+
"bug",
|
|
13
|
+
"error",
|
|
14
|
+
"crash",
|
|
15
|
+
"issue",
|
|
16
|
+
"failed",
|
|
17
|
+
"timeout"
|
|
18
|
+
],
|
|
19
|
+
product: [
|
|
20
|
+
"feature",
|
|
21
|
+
"roadmap",
|
|
22
|
+
"idea",
|
|
23
|
+
"request",
|
|
24
|
+
"feedback"
|
|
25
|
+
],
|
|
26
|
+
account: [
|
|
27
|
+
"login",
|
|
28
|
+
"password",
|
|
29
|
+
"2fa",
|
|
30
|
+
"account",
|
|
31
|
+
"profile",
|
|
32
|
+
"email change"
|
|
33
|
+
],
|
|
34
|
+
compliance: [
|
|
35
|
+
"kyc",
|
|
36
|
+
"aml",
|
|
37
|
+
"compliance",
|
|
38
|
+
"regulation",
|
|
39
|
+
"gdpr"
|
|
40
|
+
],
|
|
41
|
+
other: []
|
|
42
|
+
};
|
|
43
|
+
const PRIORITY_HINTS = {
|
|
44
|
+
urgent: [
|
|
45
|
+
"urgent",
|
|
46
|
+
"asap",
|
|
47
|
+
"immediately",
|
|
48
|
+
"today",
|
|
49
|
+
"right away"
|
|
50
|
+
],
|
|
51
|
+
high: [
|
|
52
|
+
"high priority",
|
|
53
|
+
"blocking",
|
|
54
|
+
"major",
|
|
55
|
+
"critical"
|
|
56
|
+
],
|
|
57
|
+
medium: ["soon", "next few days"],
|
|
58
|
+
low: [
|
|
59
|
+
"nice to have",
|
|
60
|
+
"when possible",
|
|
61
|
+
"later"
|
|
62
|
+
]
|
|
63
|
+
};
|
|
64
|
+
const SENTIMENT_HINTS = {
|
|
65
|
+
positive: [
|
|
66
|
+
"love",
|
|
67
|
+
"great",
|
|
68
|
+
"awesome",
|
|
69
|
+
"thank you"
|
|
70
|
+
],
|
|
71
|
+
neutral: [
|
|
72
|
+
"question",
|
|
73
|
+
"wonder",
|
|
74
|
+
"curious"
|
|
75
|
+
],
|
|
76
|
+
negative: [
|
|
77
|
+
"unhappy",
|
|
78
|
+
"bad",
|
|
79
|
+
"terrible",
|
|
80
|
+
"awful",
|
|
81
|
+
"angry"
|
|
82
|
+
],
|
|
83
|
+
frustrated: [
|
|
84
|
+
"furious",
|
|
85
|
+
"frustrated",
|
|
86
|
+
"fed up",
|
|
87
|
+
"ridiculous"
|
|
88
|
+
]
|
|
89
|
+
};
|
|
90
|
+
var TicketClassifier = class {
|
|
91
|
+
keywords;
|
|
92
|
+
llm;
|
|
93
|
+
llmModel;
|
|
94
|
+
constructor(options) {
|
|
95
|
+
this.keywords = {
|
|
96
|
+
...CATEGORY_KEYWORDS,
|
|
97
|
+
...options?.keywords ?? {}
|
|
98
|
+
};
|
|
99
|
+
this.llm = options?.llm;
|
|
100
|
+
this.llmModel = options?.llmModel;
|
|
101
|
+
}
|
|
102
|
+
async classify(ticket) {
|
|
103
|
+
const heuristics = this.heuristicClassification(ticket);
|
|
104
|
+
if (!this.llm) return heuristics;
|
|
105
|
+
try {
|
|
106
|
+
const content = (await this.llm.chat([{
|
|
107
|
+
role: "system",
|
|
108
|
+
content: [{
|
|
109
|
+
type: "text",
|
|
110
|
+
text: "Classify the support ticket."
|
|
111
|
+
}]
|
|
112
|
+
}, {
|
|
113
|
+
role: "user",
|
|
114
|
+
content: [{
|
|
115
|
+
type: "text",
|
|
116
|
+
text: JSON.stringify({
|
|
117
|
+
subject: ticket.subject,
|
|
118
|
+
body: ticket.body,
|
|
119
|
+
channel: ticket.channel
|
|
120
|
+
})
|
|
121
|
+
}]
|
|
122
|
+
}], {
|
|
123
|
+
responseFormat: "json",
|
|
124
|
+
model: this.llmModel
|
|
125
|
+
})).message.content.find((part) => "text" in part);
|
|
126
|
+
if (content && "text" in content) {
|
|
127
|
+
const parsed = JSON.parse(content.text);
|
|
128
|
+
return {
|
|
129
|
+
...heuristics,
|
|
130
|
+
...parsed,
|
|
131
|
+
intents: parsed.intents ?? heuristics.intents,
|
|
132
|
+
tags: parsed.tags ?? heuristics.tags
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
} catch {}
|
|
136
|
+
return heuristics;
|
|
137
|
+
}
|
|
138
|
+
heuristicClassification(ticket) {
|
|
139
|
+
const text = `${ticket.subject}\n${ticket.body}`.toLowerCase();
|
|
140
|
+
const category = this.detectCategory(text);
|
|
141
|
+
const priority = this.detectPriority(text);
|
|
142
|
+
const sentiment = this.detectSentiment(text);
|
|
143
|
+
const intents = this.extractIntents(text);
|
|
144
|
+
const tags = intents.slice(0, 3);
|
|
145
|
+
const confidence = this.estimateConfidence(category, priority, sentiment);
|
|
146
|
+
return {
|
|
147
|
+
ticketId: ticket.id,
|
|
148
|
+
category,
|
|
149
|
+
priority,
|
|
150
|
+
sentiment,
|
|
151
|
+
intents,
|
|
152
|
+
tags,
|
|
153
|
+
confidence,
|
|
154
|
+
escalationRequired: priority === "urgent" || category === "compliance"
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
detectCategory(text) {
|
|
158
|
+
for (const [category, keywords] of Object.entries(this.keywords)) if (keywords.some((keyword) => text.includes(keyword))) return category;
|
|
159
|
+
return "other";
|
|
160
|
+
}
|
|
161
|
+
detectPriority(text) {
|
|
162
|
+
for (const priority of [
|
|
163
|
+
"urgent",
|
|
164
|
+
"high",
|
|
165
|
+
"medium",
|
|
166
|
+
"low"
|
|
167
|
+
]) if (PRIORITY_HINTS[priority].some((word) => text.includes(word))) return priority;
|
|
168
|
+
return "medium";
|
|
169
|
+
}
|
|
170
|
+
detectSentiment(text) {
|
|
171
|
+
for (const sentiment of [
|
|
172
|
+
"frustrated",
|
|
173
|
+
"negative",
|
|
174
|
+
"neutral",
|
|
175
|
+
"positive"
|
|
176
|
+
]) if (SENTIMENT_HINTS[sentiment].some((word) => text.includes(word))) return sentiment;
|
|
177
|
+
return "neutral";
|
|
178
|
+
}
|
|
179
|
+
extractIntents(text) {
|
|
180
|
+
const intents = [];
|
|
181
|
+
if (text.includes("refund") || text.includes("chargeback")) intents.push("refund");
|
|
182
|
+
if (text.includes("payout")) intents.push("payout");
|
|
183
|
+
if (text.includes("login")) intents.push("login-help");
|
|
184
|
+
if (text.includes("feature")) intents.push("feature-request");
|
|
185
|
+
if (text.includes("bug") || text.includes("error")) intents.push("bug-report");
|
|
186
|
+
return intents.length ? intents : ["general"];
|
|
187
|
+
}
|
|
188
|
+
estimateConfidence(category, priority, sentiment) {
|
|
189
|
+
let base = .6;
|
|
190
|
+
if (category !== "other") base += .1;
|
|
191
|
+
if (priority === "urgent" || priority === "low") base += .05;
|
|
192
|
+
if (sentiment === "frustrated") base -= .05;
|
|
193
|
+
return Math.min(.95, Math.max(.4, Number(base.toFixed(2))));
|
|
194
|
+
}
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
//#endregion
|
|
198
|
+
export { TicketClassifier };
|
package/dist/setup.js
CHANGED
|
@@ -1 +1,47 @@
|
|
|
1
|
-
import{TicketResolver
|
|
1
|
+
import { TicketResolver } from "./libs/support-bot/dist/rag/ticket-resolver.js";
|
|
2
|
+
import { TicketClassifier } from "./libs/support-bot/dist/tickets/classifier.js";
|
|
3
|
+
import { AutoResponder } from "./libs/support-bot/dist/bot/auto-responder.js";
|
|
4
|
+
import "./libs/support-bot/dist/bot/index.js";
|
|
5
|
+
import { LogLevel } from "./libs/logger/dist/types.js";
|
|
6
|
+
import { Logger } from "./libs/logger/dist/logger.node.js";
|
|
7
|
+
import "./libs/logger/dist/index.js";
|
|
8
|
+
|
|
9
|
+
//#region src/setup.ts
|
|
10
|
+
const logger = new Logger({
|
|
11
|
+
level: process.env.NODE_ENV === "production" ? LogLevel.INFO : LogLevel.DEBUG,
|
|
12
|
+
environment: process.env.NODE_ENV || "development",
|
|
13
|
+
enableColors: process.env.NODE_ENV !== "production"
|
|
14
|
+
});
|
|
15
|
+
async function runAiSupportBotExample() {
|
|
16
|
+
const resolver = new TicketResolver({ knowledge: { async query(question) {
|
|
17
|
+
return {
|
|
18
|
+
answer: `The payout will retrigger automatically. (${question.slice(0, 40)}…)`,
|
|
19
|
+
references: []
|
|
20
|
+
};
|
|
21
|
+
} } });
|
|
22
|
+
const classifier = new TicketClassifier();
|
|
23
|
+
const responder = new AutoResponder();
|
|
24
|
+
const ticket = {
|
|
25
|
+
id: "TIC-42",
|
|
26
|
+
subject: "Payout failed",
|
|
27
|
+
body: "Hello, our supplier payout failed twice yesterday. Can you confirm status? It is urgent.",
|
|
28
|
+
channel: "email",
|
|
29
|
+
customerName: "Ivy",
|
|
30
|
+
metadata: { accountId: "acct_789" }
|
|
31
|
+
};
|
|
32
|
+
const classification = await classifier.classify(ticket);
|
|
33
|
+
const resolution = await resolver.resolve(ticket);
|
|
34
|
+
const draft = await responder.draft(ticket, resolution, classification);
|
|
35
|
+
logger.info("Support bot run completed", {
|
|
36
|
+
ticketId: ticket.id,
|
|
37
|
+
classification,
|
|
38
|
+
resolution,
|
|
39
|
+
emailDraft: {
|
|
40
|
+
subject: draft.subject,
|
|
41
|
+
body: draft.body
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
//#endregion
|
|
47
|
+
export { runAiSupportBotExample };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lssm/example.ai-support-bot",
|
|
3
|
-
"version": "0.0.0-canary-
|
|
3
|
+
"version": "0.0.0-canary-20251217072406",
|
|
4
4
|
"description": "AI support bot example: classify and resolve a support ticket using @lssm/lib.support-bot.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -27,14 +27,15 @@
|
|
|
27
27
|
"test": "bun test"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@lssm/lib.support-bot": "0.0.0-canary-
|
|
31
|
-
"@lssm/lib.knowledge": "0.0.0-canary-
|
|
32
|
-
"@lssm/lib.
|
|
33
|
-
"@lssm/lib.
|
|
30
|
+
"@lssm/lib.support-bot": "0.0.0-canary-20251217072406",
|
|
31
|
+
"@lssm/lib.knowledge": "0.0.0-canary-20251217072406",
|
|
32
|
+
"@lssm/lib.schema": "0.0.0-canary-20251217072406",
|
|
33
|
+
"@lssm/lib.contracts": "0.0.0-canary-20251217072406",
|
|
34
|
+
"@lssm/lib.logger": "0.0.0-canary-20251217072406"
|
|
34
35
|
},
|
|
35
36
|
"devDependencies": {
|
|
36
|
-
"@lssm/tool.tsdown": "0.0.0-canary-
|
|
37
|
-
"@lssm/tool.typescript": "0.0.0-canary-
|
|
37
|
+
"@lssm/tool.tsdown": "0.0.0-canary-20251217072406",
|
|
38
|
+
"@lssm/tool.typescript": "0.0.0-canary-20251217072406",
|
|
38
39
|
"tsdown": "^0.17.4",
|
|
39
40
|
"typescript": "^5.9.3"
|
|
40
41
|
},
|