@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.
@@ -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":"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"}
1
+ {"version":3,"file":"notifications.d.ts","sourceRoot":"","sources":["../../src/dal/notifications.ts"],"names":[],"mappings":"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"}
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 reply = await chat.complete([{ role: "system", content: systemPrompt }, ...historyMessages], {
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;IAYrB,OAAO,CAAC,aAAa;IAYrB,OAAO,CAAC,SAAS;CAUlB"}
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;AACxB,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,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,CA6T/B"}
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;CACzF;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;CAqCvC"}
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.8.0",
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",