@chatman-media/conversation-engine 1.8.0 → 1.10.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-informer.d.ts +6 -0
- package/dist/admin-informer.d.ts.map +1 -1
- package/dist/dal/notifications.d.ts +1 -1
- package/dist/dal/notifications.d.ts.map +1 -1
- package/dist/index.js +154 -8
- package/dist/lead-advance.d.ts +26 -0
- package/dist/lead-advance.d.ts.map +1 -0
- package/dist/notifications.d.ts.map +1 -1
- package/dist/process-inbound.d.ts +8 -1
- package/dist/process-inbound.d.ts.map +1 -1
- package/dist/reply-strategy/llm-reply.d.ts +11 -0
- package/dist/reply-strategy/llm-reply.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/admin-informer.d.ts
CHANGED
|
@@ -47,6 +47,12 @@ export interface InformerEvent {
|
|
|
47
47
|
}
|
|
48
48
|
export declare function passesThreshold(severity: InformerSeverity, level: InformerLevel): boolean;
|
|
49
49
|
export declare function isMuted(settings: OperatorSettings | undefined, nowEpoch: number): boolean;
|
|
50
|
+
/**
|
|
51
|
+
* Тихие часы (DND): true, если текущий локальный час (в informerTz) попадает в
|
|
52
|
+
* окно [quietFrom, quietTo). Окно может переходить через полночь (22→8).
|
|
53
|
+
* Выключено, если границы NULL или равны.
|
|
54
|
+
*/
|
|
55
|
+
export declare function inQuietHours(settings: OperatorSettings | undefined, nowEpoch: number): boolean;
|
|
50
56
|
/** Тема включена, если карты нет (NULL = все включены) или ключ != false. */
|
|
51
57
|
export declare function topicEnabled(settings: OperatorSettings | undefined, topic: InformerTopic): boolean;
|
|
52
58
|
export declare function opsAlertToInformer(alert: OpsAlert): InformerEvent;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"admin-informer.d.ts","sourceRoot":"","sources":["../src/admin-informer.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"admin-informer.d.ts","sourceRoot":"","sources":["../src/admin-informer.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,7 +6,7 @@ export type NotificationTemplate = typeof ntTable.$inferSelect;
|
|
|
6
6
|
export type AdminNotificationRow = typeof anTable.$inferSelect;
|
|
7
7
|
export type NewAdminNotification = typeof anTable.$inferInsert;
|
|
8
8
|
/** Частичный апдейт informer-настроек владельца (см. миграцию 0032). */
|
|
9
|
-
export type InformerPrefs = Partial<Pick<OperatorSettings, "informerLevel" | "informerTopics" | "informerDigest" | "informerDigestHour" | "informerTz" | "informerMutedUntil" | "informerLastDigestAt">>;
|
|
9
|
+
export type InformerPrefs = Partial<Pick<OperatorSettings, "informerLevel" | "informerTopics" | "informerDigest" | "informerDigestHour" | "informerTz" | "informerMutedUntil" | "informerLastDigestAt" | "informerQuietFrom" | "informerQuietTo">>;
|
|
10
10
|
/** Владелец тенанта (superadmin) + его operator_settings. */
|
|
11
11
|
export interface OwnerSettings {
|
|
12
12
|
adminId: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notifications.d.ts","sourceRoot":"","sources":["../../src/dal/notifications.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,EAAmH,KAAK,kBAAkB,IAAI,OAAO,EAAE,KAAK,iBAAiB,IAAI,OAAO,EAAE,KAAK,gBAAgB,IAAI,OAAO,EAAE,KAAK,qBAAqB,IAAI,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAEzS,MAAM,MAAM,gBAAgB,GAAG,OAAO,OAAO,CAAC,YAAY,CAAC;AAC3D,MAAM,MAAM,gBAAgB,GAAG,OAAO,OAAO,CAAC,YAAY,CAAC;AAC3D,MAAM,MAAM,oBAAoB,GAAG,OAAO,OAAO,CAAC,YAAY,CAAC;AAC/D,MAAM,MAAM,oBAAoB,GAAG,OAAO,OAAO,CAAC,YAAY,CAAC;AAC/D,MAAM,MAAM,oBAAoB,GAAG,OAAO,OAAO,CAAC,YAAY,CAAC;AAE/D,wEAAwE;AACxE,MAAM,MAAM,aAAa,GAAG,OAAO,CACjC,IAAI,CACF,gBAAgB,EACd,eAAe,GACf,gBAAgB,GAChB,gBAAgB,GAChB,oBAAoB,GACpB,YAAY,GACZ,oBAAoB,GACpB,sBAAsB,
|
|
1
|
+
{"version":3,"file":"notifications.d.ts","sourceRoot":"","sources":["../../src/dal/notifications.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,EAAmH,KAAK,kBAAkB,IAAI,OAAO,EAAE,KAAK,iBAAiB,IAAI,OAAO,EAAE,KAAK,gBAAgB,IAAI,OAAO,EAAE,KAAK,qBAAqB,IAAI,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAEzS,MAAM,MAAM,gBAAgB,GAAG,OAAO,OAAO,CAAC,YAAY,CAAC;AAC3D,MAAM,MAAM,gBAAgB,GAAG,OAAO,OAAO,CAAC,YAAY,CAAC;AAC3D,MAAM,MAAM,oBAAoB,GAAG,OAAO,OAAO,CAAC,YAAY,CAAC;AAC/D,MAAM,MAAM,oBAAoB,GAAG,OAAO,OAAO,CAAC,YAAY,CAAC;AAC/D,MAAM,MAAM,oBAAoB,GAAG,OAAO,OAAO,CAAC,YAAY,CAAC;AAE/D,wEAAwE;AACxE,MAAM,MAAM,aAAa,GAAG,OAAO,CACjC,IAAI,CACF,gBAAgB,EACd,eAAe,GACf,gBAAgB,GAChB,gBAAgB,GAChB,oBAAoB,GACpB,YAAY,GACZ,oBAAoB,GACpB,sBAAsB,GACtB,mBAAmB,GACnB,iBAAiB,CACpB,CACF,CAAC;AAEF,6DAA6D;AAC7D,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,gBAAgB,GAAG,SAAS,CAAC;CACxC;AAED,qBAAa,iBAAiB;IAChB,OAAO,CAAC,QAAQ,CAAC,EAAE;gBAAF,EAAE,EAAE,kBAAkB;IAE7C,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAalF,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC;IAS5E,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC;IAerE,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAwBrE,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAYhE,4BAA4B,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAO3E,qBAAqB,CACzB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,gBAAgB,EAAE,gBAAgB,GAAG,sBAAsB,CAAC,CAAC,GACjF,OAAO,CAAC,IAAI,CAAC;IAWV,sBAAsB,CAAC,QAAQ,EAAE,IAAI,CAAC,gBAAgB,EAAE,IAAI,GAAG,WAAW,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAc3F,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,gBAAgB,EAAE,IAAI,GAAG,WAAW,GAAG,WAAW,CAAC,GAAG,OAAO,CAAC,gBAAgB,CAAC;IASrG,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAOxD,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQvD,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,GAAG,SAAS,CAAC;IASvF,cAAc,CAAC,GAAG,EAAE,IAAI,CAAC,oBAAoB,EAAE,IAAI,GAAG,WAAW,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAalF,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,EAAE,CAAC;IAOhE,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAM7D,sBAAsB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAc7F,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAAC;IAUhH,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMxD;;;OAGG;IACG,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAY3E,6EAA6E;IACvE,4BAA4B,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC;IASzF;;;;OAIG;IACG,mBAAmB,CACvB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,aAAa,EACpB,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC;IAqBhB,yCAAyC;IACnC,uBAAuB,CAAC,GAAG,EAAE,oBAAoB,GAAG,OAAO,CAAC,MAAM,CAAC;IASzE,yEAAyE;IACnE,yBAAyB,CAAC,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAO/E;;;OAGG;IACG,iBAAiB,CACrB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,oBAAoB,GAAG,SAAS,CAAC;IAgB5C,uDAAuD;IACjD,uBAAuB,CAC3B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,KAAK,SAAK,GACT,OAAO,CAAC,oBAAoB,EAAE,CAAC;IAWlC,4EAA4E;IACtE,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,EAAE,CAAC;IAe3F,kDAAkD;IAC5C,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAOlE"}
|
package/dist/index.js
CHANGED
|
@@ -1020,7 +1020,8 @@ class NotificationService {
|
|
|
1020
1020
|
human_takeover: "\uD83C\uDD98",
|
|
1021
1021
|
document_uploaded: "\uD83D\uDCF8",
|
|
1022
1022
|
high_value_deal: "\uD83D\uDC8E",
|
|
1023
|
-
lead_stale: "⏰"
|
|
1023
|
+
lead_stale: "⏰",
|
|
1024
|
+
operator_confirm_needed: "✋"
|
|
1024
1025
|
};
|
|
1025
1026
|
return map[type] ?? "\uD83D\uDD14";
|
|
1026
1027
|
}
|
|
@@ -1031,7 +1032,8 @@ class NotificationService {
|
|
|
1031
1032
|
human_takeover: "Нужна помощь оператора",
|
|
1032
1033
|
document_uploaded: "Загружен документ",
|
|
1033
1034
|
high_value_deal: "Крупная сделка",
|
|
1034
|
-
lead_stale: "Лид завис"
|
|
1035
|
+
lead_stale: "Лид завис",
|
|
1036
|
+
operator_confirm_needed: "Нужно подтверждение оператора"
|
|
1035
1037
|
};
|
|
1036
1038
|
return map[type] ?? "Уведомление";
|
|
1037
1039
|
}
|
|
@@ -1214,6 +1216,25 @@ function isMuted(settings, nowEpoch) {
|
|
|
1214
1216
|
const until = settings?.informerMutedUntil;
|
|
1215
1217
|
return typeof until === "number" && until > nowEpoch;
|
|
1216
1218
|
}
|
|
1219
|
+
function inQuietHours(settings, nowEpoch) {
|
|
1220
|
+
const from = settings?.informerQuietFrom;
|
|
1221
|
+
const to = settings?.informerQuietTo;
|
|
1222
|
+
if (from == null || to == null || from === to)
|
|
1223
|
+
return false;
|
|
1224
|
+
let hour;
|
|
1225
|
+
try {
|
|
1226
|
+
const tz = settings?.informerTz || "UTC";
|
|
1227
|
+
const s = new Intl.DateTimeFormat("en-US", {
|
|
1228
|
+
timeZone: tz,
|
|
1229
|
+
hour: "2-digit",
|
|
1230
|
+
hour12: false
|
|
1231
|
+
}).format(new Date(nowEpoch * 1000));
|
|
1232
|
+
hour = Number.parseInt(s, 10) % 24;
|
|
1233
|
+
} catch {
|
|
1234
|
+
hour = new Date(nowEpoch * 1000).getUTCHours();
|
|
1235
|
+
}
|
|
1236
|
+
return from < to ? hour >= from && hour < to : hour >= from || hour < to;
|
|
1237
|
+
}
|
|
1217
1238
|
function topicEnabled(settings, topic) {
|
|
1218
1239
|
const raw = settings?.informerTopics;
|
|
1219
1240
|
if (!raw)
|
|
@@ -1352,7 +1373,7 @@ class AdminInformer {
|
|
|
1352
1373
|
if (recent)
|
|
1353
1374
|
return null;
|
|
1354
1375
|
const level = owner.settings?.informerLevel ?? "important";
|
|
1355
|
-
const realtime = !isMuted(owner.settings, now) && passesThreshold(event.severity, level);
|
|
1376
|
+
const realtime = !isMuted(owner.settings, now) && !inQuietHours(owner.settings, now) && passesThreshold(event.severity, level);
|
|
1356
1377
|
const rowId = await repo.insertAdminNotification({
|
|
1357
1378
|
tenantId: event.tenantId,
|
|
1358
1379
|
adminId: owner.adminId,
|
|
@@ -2333,6 +2354,70 @@ async function generateReplyAndEnqueue(deps) {
|
|
|
2333
2354
|
});
|
|
2334
2355
|
return { outboundEnqueued: count };
|
|
2335
2356
|
}
|
|
2357
|
+
// src/lead-advance.ts
|
|
2358
|
+
import { funnels, leads as leadsTable2, stageDefinitions } from "@chatman-media/storage";
|
|
2359
|
+
import { and as and14, asc, eq as eq14 } from "drizzle-orm";
|
|
2360
|
+
var SALES_STAGE_TO_PHASE = {
|
|
2361
|
+
qualify: "qualify",
|
|
2362
|
+
pitch: "offer",
|
|
2363
|
+
objection: "clear",
|
|
2364
|
+
close: "fulfill"
|
|
2365
|
+
};
|
|
2366
|
+
async function ensureAndAdvanceLeadByPhase(opts) {
|
|
2367
|
+
const { db, tenantId, contactId, salesStage, nowEpoch } = opts;
|
|
2368
|
+
const stages = await db.select({
|
|
2369
|
+
id: stageDefinitions.id,
|
|
2370
|
+
slug: stageDefinitions.slug,
|
|
2371
|
+
phase: stageDefinitions.phase,
|
|
2372
|
+
kind: stageDefinitions.kind,
|
|
2373
|
+
position: stageDefinitions.position
|
|
2374
|
+
}).from(stageDefinitions).innerJoin(funnels, eq14(stageDefinitions.funnelId, funnels.id)).where(and14(eq14(funnels.tenantId, tenantId), eq14(funnels.isActive, true))).orderBy(asc(stageDefinitions.position));
|
|
2375
|
+
if (stages.length === 0)
|
|
2376
|
+
return null;
|
|
2377
|
+
const initial = stages.find((s) => s.kind === "intake") ?? stages[0];
|
|
2378
|
+
const [existing] = await db.select({ id: leadsTable2.id, state: leadsTable2.state, stageDefinitionId: leadsTable2.stageDefinitionId }).from(leadsTable2).where(and14(eq14(leadsTable2.tenantId, tenantId), eq14(leadsTable2.userId, contactId))).limit(1);
|
|
2379
|
+
let leadId;
|
|
2380
|
+
let curStageId;
|
|
2381
|
+
let curSlug;
|
|
2382
|
+
let created = false;
|
|
2383
|
+
if (existing) {
|
|
2384
|
+
leadId = existing.id;
|
|
2385
|
+
curStageId = existing.stageDefinitionId ?? null;
|
|
2386
|
+
curSlug = existing.state;
|
|
2387
|
+
} else {
|
|
2388
|
+
const [row] = await db.insert(leadsTable2).values({
|
|
2389
|
+
tenantId,
|
|
2390
|
+
userId: contactId,
|
|
2391
|
+
state: initial.slug,
|
|
2392
|
+
stageDefinitionId: initial.id,
|
|
2393
|
+
createdAt: nowEpoch,
|
|
2394
|
+
updatedAt: nowEpoch
|
|
2395
|
+
}).returning({ id: leadsTable2.id });
|
|
2396
|
+
if (!row)
|
|
2397
|
+
return null;
|
|
2398
|
+
leadId = row.id;
|
|
2399
|
+
curStageId = initial.id;
|
|
2400
|
+
curSlug = initial.slug;
|
|
2401
|
+
created = true;
|
|
2402
|
+
}
|
|
2403
|
+
const targetPhase = SALES_STAGE_TO_PHASE[salesStage];
|
|
2404
|
+
if (!targetPhase)
|
|
2405
|
+
return { leadId, stageSlug: curSlug, created, advanced: false };
|
|
2406
|
+
const curStage = curStageId != null ? stages.find((s) => s.id === curStageId) : undefined;
|
|
2407
|
+
const curPos = curStage?.position ?? -1;
|
|
2408
|
+
let target = salesStage === "close" && curStage?.phase === "fulfill" ? stages.find((s) => s.kind === "terminal_won") : undefined;
|
|
2409
|
+
if (!target) {
|
|
2410
|
+
target = stages.find((s) => s.phase === targetPhase && s.kind !== "terminal_won" && s.kind !== "terminal_lost");
|
|
2411
|
+
}
|
|
2412
|
+
if (!target)
|
|
2413
|
+
return { leadId, stageSlug: curSlug, created, advanced: false };
|
|
2414
|
+
if (target.position > curPos) {
|
|
2415
|
+
await db.update(leadsTable2).set({ stageDefinitionId: target.id, state: target.slug, updatedAt: nowEpoch }).where(and14(eq14(leadsTable2.id, leadId), eq14(leadsTable2.tenantId, tenantId)));
|
|
2416
|
+
return { leadId, stageSlug: target.slug, created, advanced: true };
|
|
2417
|
+
}
|
|
2418
|
+
return { leadId, stageSlug: curSlug, created, advanced: false };
|
|
2419
|
+
}
|
|
2420
|
+
|
|
2336
2421
|
// src/process-inbound.ts
|
|
2337
2422
|
function inboundText(inbound) {
|
|
2338
2423
|
const textParts = [];
|
|
@@ -2518,6 +2603,33 @@ async function processInbound(inbound, deps) {
|
|
|
2518
2603
|
to: newStage
|
|
2519
2604
|
});
|
|
2520
2605
|
}
|
|
2606
|
+
if (newStage && newStage !== "opener" && deps.leads && deps.db) {
|
|
2607
|
+
try {
|
|
2608
|
+
const res = await ensureAndAdvanceLeadByPhase({
|
|
2609
|
+
db: deps.db,
|
|
2610
|
+
tenantId: deps.tenant.tenantId,
|
|
2611
|
+
contactId: contact.id,
|
|
2612
|
+
salesStage: newStage,
|
|
2613
|
+
nowEpoch: now
|
|
2614
|
+
});
|
|
2615
|
+
if (res && (res.created || res.advanced)) {
|
|
2616
|
+
deps.sink?.log?.("info", res.created ? "lead auto-created" : "lead advanced", {
|
|
2617
|
+
tenantId: deps.tenant.tenantId,
|
|
2618
|
+
conversationId: conversation.id,
|
|
2619
|
+
contactId: contact.id,
|
|
2620
|
+
leadId: res.leadId,
|
|
2621
|
+
stage: res.stageSlug,
|
|
2622
|
+
salesStage: newStage
|
|
2623
|
+
});
|
|
2624
|
+
}
|
|
2625
|
+
} catch (err) {
|
|
2626
|
+
deps.sink?.log?.("warn", "lead auto-advance failed", {
|
|
2627
|
+
tenantId: deps.tenant.tenantId,
|
|
2628
|
+
conversationId: conversation.id,
|
|
2629
|
+
error: err instanceof Error ? err.message : String(err)
|
|
2630
|
+
});
|
|
2631
|
+
}
|
|
2632
|
+
}
|
|
2521
2633
|
} catch (err) {
|
|
2522
2634
|
deps.sink?.log?.("warn", "stage classifier failed", {
|
|
2523
2635
|
tenantId: deps.tenant.tenantId,
|
|
@@ -2609,6 +2721,7 @@ async function processInbound(inbound, deps) {
|
|
|
2609
2721
|
};
|
|
2610
2722
|
}
|
|
2611
2723
|
// src/reply-strategy/llm-reply.ts
|
|
2724
|
+
import { DEFAULT_MAX_TOOL_CYCLES, runToolLoop } from "@chatman-media/kb";
|
|
2612
2725
|
var BASE_SYSTEM_PROMPT = "Ты — операционный бот платформы lead-engine. Отвечай кратко, " + "уважительно, по делу. Никогда не выдумывай факты которых нет в " + "контексте — лучше скажи «уточню у партнёра» и поставь сообщение в очередь оператора.";
|
|
2613
2726
|
function messagesToChatHistory2(history) {
|
|
2614
2727
|
const out = [];
|
|
@@ -2642,14 +2755,47 @@ class LlmReplyStrategy {
|
|
|
2642
2755
|
const messages = this.messagesRepoFor(input.tenant.tenantId);
|
|
2643
2756
|
const history = await messages.recent(input.conversationId, this.opts.historyLimit ?? 20);
|
|
2644
2757
|
const historyMessages = messagesToChatHistory2(history);
|
|
2645
|
-
const systemPrompt = [BASE_SYSTEM_PROMPT, this.opts.template.systemPromptFragment].filter(Boolean).join(`
|
|
2646
|
-
|
|
2647
|
-
`);
|
|
2648
2758
|
const chat = this.opts.resolveChat(input.tenant.tenantId);
|
|
2649
|
-
const
|
|
2759
|
+
const llmOpts = {
|
|
2650
2760
|
temperature: this.opts.temperature ?? 0.7,
|
|
2651
2761
|
numPredict: this.opts.maxOutputTokens ?? 600
|
|
2652
|
-
}
|
|
2762
|
+
};
|
|
2763
|
+
let tools = [];
|
|
2764
|
+
if (this.opts.resolveTools) {
|
|
2765
|
+
try {
|
|
2766
|
+
tools = await this.opts.resolveTools({
|
|
2767
|
+
tenantId: input.tenant.tenantId,
|
|
2768
|
+
conversationId: input.conversationId
|
|
2769
|
+
});
|
|
2770
|
+
} catch {
|
|
2771
|
+
tools = [];
|
|
2772
|
+
}
|
|
2773
|
+
}
|
|
2774
|
+
const toolsActive = tools.length > 0 && typeof chat.completeWithTools === "function";
|
|
2775
|
+
const systemPrompt = [
|
|
2776
|
+
BASE_SYSTEM_PROMPT,
|
|
2777
|
+
toolsActive ? "Если для ответа есть подходящий инструмент (например, расчёт курса обмена) — " + "ОБЯЗАТЕЛЬНО вызови его и дай конкретные числа. Не отсылай к оператору, если можешь " + "ответить инструментом." : "",
|
|
2778
|
+
this.opts.template.systemPromptFragment
|
|
2779
|
+
].filter(Boolean).join(`
|
|
2780
|
+
|
|
2781
|
+
`);
|
|
2782
|
+
const msgs = [
|
|
2783
|
+
{ role: "system", content: systemPrompt },
|
|
2784
|
+
...historyMessages
|
|
2785
|
+
];
|
|
2786
|
+
let reply;
|
|
2787
|
+
if (toolsActive) {
|
|
2788
|
+
const loop = await runToolLoop({
|
|
2789
|
+
chat,
|
|
2790
|
+
messages: msgs,
|
|
2791
|
+
tools,
|
|
2792
|
+
llmOpts,
|
|
2793
|
+
maxCycles: DEFAULT_MAX_TOOL_CYCLES
|
|
2794
|
+
});
|
|
2795
|
+
reply = loop.content ?? await chat.complete(msgs, llmOpts);
|
|
2796
|
+
} else {
|
|
2797
|
+
reply = await chat.complete(msgs, llmOpts);
|
|
2798
|
+
}
|
|
2653
2799
|
if (reply.trim().length === 0)
|
|
2654
2800
|
return null;
|
|
2655
2801
|
return [
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { Db } from "./dal/types.ts";
|
|
2
|
+
/**
|
|
3
|
+
* Find-or-create лид для (tenant, contact) на активной воронке тенанта и
|
|
4
|
+
* продвигает его вперёд до фазы, соответствующей текущей sales-стадии диалога.
|
|
5
|
+
* Двигает ТОЛЬКО вперёд (по position); назад не откатывает.
|
|
6
|
+
*
|
|
7
|
+
* Обновляет lead.state + lead.stageDefinitionId синхронно (как admin-leads /
|
|
8
|
+
* field-extractor). Работает поверх DB-воронки (stage_definitions), а не
|
|
9
|
+
* template.funnelStages — это «живая» позиция в кастомной воронке тенанта.
|
|
10
|
+
*
|
|
11
|
+
* Возвращает null если у тенанта нет активной воронки со стадиями.
|
|
12
|
+
*/
|
|
13
|
+
export declare function ensureAndAdvanceLeadByPhase(opts: {
|
|
14
|
+
db: Db;
|
|
15
|
+
tenantId: number;
|
|
16
|
+
contactId: number;
|
|
17
|
+
/** sales-стадия из stage-classifier (opener|qualify|pitch|objection|close). */
|
|
18
|
+
salesStage: string;
|
|
19
|
+
nowEpoch: number;
|
|
20
|
+
}): Promise<{
|
|
21
|
+
leadId: number;
|
|
22
|
+
stageSlug: string;
|
|
23
|
+
created: boolean;
|
|
24
|
+
advanced: boolean;
|
|
25
|
+
} | null>;
|
|
26
|
+
//# sourceMappingURL=lead-advance.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lead-advance.d.ts","sourceRoot":"","sources":["../src/lead-advance.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,gBAAgB,CAAC;AAoBzC;;;;;;;;;;GAUG;AACH,wBAAsB,2BAA2B,CAAC,IAAI,EAAE;IACtD,EAAE,EAAE,EAAE,CAAC;IACP,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,+EAA+E;IAC/E,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAClB,GAAG,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,GAAG,IAAI,CAAC,CAmF7F"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notifications.d.ts","sourceRoot":"","sources":["../src/notifications.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAElF,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qEAAqE;IACrE,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/B;AAED,qBAAa,mBAAmB;IAI5B,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB;;;;OAIG;IACH,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC;IAX5B,OAAO,CAAC,MAAM,CAA+B;gBAG1B,IAAI,EAAE,iBAAiB,EACvB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM;IAC/B;;;;OAIG;IACc,QAAQ,CAAC,EAAE,aAAa,YAAA;IAOrC,MAAM,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAmD/C,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;YAcjE,WAAW;IAazB,gBAAgB,CAAC,IAAI,EAAE,gBAAgB,EAAE,KAAK,EAAE,iBAAiB,GAAG,OAAO;IAa3E,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,iBAAiB,GAAG,MAAM;IAc9D,aAAa,CAAC,KAAK,EAAE,iBAAiB,GAAG,MAAM;IAsB/C,OAAO,CAAC,aAAa;IAUrB,OAAO,CAAC,aAAa;
|
|
1
|
+
{"version":3,"file":"notifications.d.ts","sourceRoot":"","sources":["../src/notifications.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAElF,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qEAAqE;IACrE,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/B;AAED,qBAAa,mBAAmB;IAI5B,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB;;;;OAIG;IACH,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC;IAX5B,OAAO,CAAC,MAAM,CAA+B;gBAG1B,IAAI,EAAE,iBAAiB,EACvB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM;IAC/B;;;;OAIG;IACc,QAAQ,CAAC,EAAE,aAAa,YAAA;IAOrC,MAAM,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAmD/C,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;YAcjE,WAAW;IAazB,gBAAgB,CAAC,IAAI,EAAE,gBAAgB,EAAE,KAAK,EAAE,iBAAiB,GAAG,OAAO;IAa3E,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,iBAAiB,GAAG,MAAM;IAc9D,aAAa,CAAC,KAAK,EAAE,iBAAiB,GAAG,MAAM;IAsB/C,OAAO,CAAC,aAAa;IAUrB,OAAO,CAAC,aAAa;IAarB,OAAO,CAAC,aAAa;IAarB,OAAO,CAAC,SAAS;CAUlB"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Inbound, OutboundEnvelope } from "@chatman-media/channel-core";
|
|
2
2
|
import type { VerticalTemplate } from "@chatman-media/verticals";
|
|
3
|
-
import type { ChannelIdentitiesRepo, ContactsRepo, ConversationsRepo, MessagesRepo, OutboundQueueRepo } from "./dal/index.ts";
|
|
3
|
+
import type { ChannelIdentitiesRepo, ContactsRepo, ConversationsRepo, LeadsRepo, MessagesRepo, OutboundQueueRepo } from "./dal/index.ts";
|
|
4
4
|
import { type MemoryExtractor } from "./memory-extractor.ts";
|
|
5
5
|
import { type StageClassifier } from "./stage-classifier.ts";
|
|
6
6
|
import type { ITranscriber } from "./transcriber.ts";
|
|
@@ -37,6 +37,13 @@ export interface ProcessInboundDeps {
|
|
|
37
37
|
conversations: ConversationsRepo;
|
|
38
38
|
messages: MessagesRepo;
|
|
39
39
|
outbound: OutboundQueueRepo;
|
|
40
|
+
/**
|
|
41
|
+
* Опциональный LeadsRepo. Если задан вместе с `template` и `stageClassifier`,
|
|
42
|
+
* pipeline авто-создаёт Lead, как только цель/интент клиента определён
|
|
43
|
+
* (stage classifier вернул стадию ≠ "opener"). Без него лиды не создаются
|
|
44
|
+
* из диалога (legacy-поведение).
|
|
45
|
+
*/
|
|
46
|
+
leads?: LeadsRepo;
|
|
40
47
|
/** Стратегия ответа. null = pipeline сохраняет inbound и не отвечает. */
|
|
41
48
|
reply?: ReplyStrategy | null;
|
|
42
49
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"process-inbound.d.ts","sourceRoot":"","sources":["../src/process-inbound.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC7E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAGjE,OAAO,KAAK,EACV,qBAAqB,EACrB,YAAY,EACZ,iBAAiB,EACjB,YAAY,EACZ,iBAAiB,EAClB,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"process-inbound.d.ts","sourceRoot":"","sources":["../src/process-inbound.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC7E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAGjE,OAAO,KAAK,EACV,qBAAqB,EACrB,YAAY,EACZ,iBAAiB,EACjB,SAAS,EACT,YAAY,EACZ,iBAAiB,EAClB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,KAAK,eAAe,EAAuB,MAAM,uBAAuB,CAAC;AAElF,OAAO,EAAwB,KAAK,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACnF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EACL,cAAc,EACd,KAAK,KAAK,EACV,KAAK,YAAY,EACjB,KAAK,oBAAoB,EAEzB,KAAK,aAAa,EACnB,MAAM,YAAY,CAAC;AAEpB;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE;QACb,MAAM,EAAE,aAAa,CAAC;QACtB,OAAO,EAAE,cAAc,CAAC;QACxB,cAAc,EAAE,MAAM,CAAC;QACvB,SAAS,EAAE,MAAM,CAAC;QAClB,OAAO,EAAE,OAAO,CAAC;QACjB,eAAe,EAAE,MAAM,CAAC;KACzB,GAAG,OAAO,CAAC,gBAAgB,EAAE,GAAG,IAAI,CAAC,CAAC;CACxC;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,aAAa,CAAC;IACtB,OAAO,EAAE,cAAc,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,YAAY,CAAC;IACvB,UAAU,EAAE,qBAAqB,CAAC;IAClC,aAAa,EAAE,iBAAiB,CAAC;IACjC,QAAQ,EAAE,YAAY,CAAC;IACvB,QAAQ,EAAE,iBAAiB,CAAC;IAC5B;;;;;OAKG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,yEAAyE;IACzE,KAAK,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;IAC7B;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IAC5B;;;;;OAKG;IACH,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC;;;;;;;;OAQG;IACH,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC;;;OAGG;IACH,EAAE,CAAC,EAAE,OAAO,gBAAgB,EAAE,EAAE,CAAC;IACjC;;;;;;;;;;;;OAYG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,aAAa,CAAC,EAAE,mBAAmB,CAAC;IACpC;;;;;OAKG;IACH,WAAW,CAAC,EAAE,YAAY,GAAG,IAAI,CAAC;IAClC,yFAAyF;IACzF,aAAa,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE,OAAO,6BAA6B,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC,GAAG,IAAI,CAAC;CAClI;AAwBD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,kBAAkB,GACvB,OAAO,CAAC,oBAAoB,CAAC,CA4V/B"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { OutboundEnvelope } from "@chatman-media/channel-core";
|
|
2
|
+
import { type AnyRagTool } from "@chatman-media/kb";
|
|
2
3
|
import type { ChatClient } from "@chatman-media/llm-router";
|
|
3
4
|
import type { VerticalTemplate } from "@chatman-media/verticals";
|
|
4
5
|
import type { MessagesRepo } from "../dal/messages.ts";
|
|
@@ -46,6 +47,16 @@ export interface LlmReplyStrategyOpts {
|
|
|
46
47
|
tenantId: number;
|
|
47
48
|
contactId: number;
|
|
48
49
|
}) => Promise<boolean>;
|
|
50
|
+
/**
|
|
51
|
+
* Опциональный резолвер agentic-инструментов (напр. расчёт курса обмена).
|
|
52
|
+
* Если задан и вернул непустой список, а ChatClient умеет completeWithTools —
|
|
53
|
+
* strategy прогоняет tool-loop, чтобы бот мог дать конкретный ответ
|
|
54
|
+
* (курс/сумму) даже без RAG/эмбеддингов, а не уходить в «уточню у партнёра».
|
|
55
|
+
*/
|
|
56
|
+
resolveTools?: (input: {
|
|
57
|
+
tenantId: number;
|
|
58
|
+
conversationId: number;
|
|
59
|
+
}) => Promise<AnyRagTool[]> | AnyRagTool[];
|
|
49
60
|
}
|
|
50
61
|
export declare class LlmReplyStrategy implements ReplyStrategy {
|
|
51
62
|
private readonly opts;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"llm-reply.d.ts","sourceRoot":"","sources":["../../src/reply-strategy/llm-reply.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AACpE,OAAO,KAAK,EAAE,UAAU,EAAe,MAAM,2BAA2B,CAAC;AACzE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,KAAK,EAAc,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACnE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAE3D;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,gBAAgB,CAAC;IAC3B;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,yCAAyC;IACzC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,qCAAqC;IACrC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;;OAMG;IACH,WAAW,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,UAAU,CAAC;IAC9C,2EAA2E;IAC3E,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"llm-reply.d.ts","sourceRoot":"","sources":["../../src/reply-strategy/llm-reply.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AACpE,OAAO,EAAE,KAAK,UAAU,EAAwC,MAAM,mBAAmB,CAAC;AAC1F,OAAO,KAAK,EAAE,UAAU,EAAe,MAAM,2BAA2B,CAAC;AACzE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,KAAK,EAAc,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACnE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAE3D;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,gBAAgB,CAAC;IAC3B;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,yCAAyC;IACzC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,qCAAqC;IACrC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;;OAMG;IACH,WAAW,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,UAAU,CAAC;IAC9C,2EAA2E;IAC3E,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACxF;;;;;OAKG;IACH,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE;QACrB,QAAQ,EAAE,MAAM,CAAC;QACjB,cAAc,EAAE,MAAM,CAAC;KACxB,KAAK,OAAO,CAAC,UAAU,EAAE,CAAC,GAAG,UAAU,EAAE,CAAC;CAC5C;AAkBD,qBAAa,gBAAiB,YAAW,aAAa;IAElD,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,eAAe;gBADf,IAAI,EAAE,oBAAoB,EAC1B,eAAe,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,YAAY;IAGhE,QAAQ,CAAC,KAAK,EAAE;QACpB,MAAM,EAAE;YAAE,QAAQ,EAAE,MAAM,CAAA;SAAE,CAAC;QAC7B,OAAO,EAAE;YAAE,SAAS,EAAE,MAAM,CAAA;SAAE,CAAC;QAC/B,cAAc,EAAE,MAAM,CAAC;QACvB,SAAS,EAAE,MAAM,CAAC;QAClB,OAAO,EAAE;YAAE,cAAc,EAAE,MAAM,CAAA;SAAE,CAAC;QACpC,eAAe,EAAE,MAAM,CAAC;KACzB,GAAG,OAAO,CAAC,gBAAgB,EAAE,GAAG,IAAI,CAAC;CA8EvC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@chatman-media/conversation-engine",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.10.0",
|
|
4
4
|
"description": "Channel-agnostic pipeline обработки inbound сообщений: contact-resolve → conversation lookup → mode routing → AI-reply / queued / human → outbound. Сердце data plane.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|