@chatman-media/conversation-engine 1.2.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/LICENSE +21 -0
- package/README.md +22 -0
- package/dist/compact-conversation.d.ts +16 -0
- package/dist/compact-conversation.d.ts.map +1 -0
- package/dist/compact-conversation.test.d.ts +2 -0
- package/dist/compact-conversation.test.d.ts.map +1 -0
- package/dist/contact-resolver.d.ts +16 -0
- package/dist/contact-resolver.d.ts.map +1 -0
- package/dist/conversation-resolver.d.ts +17 -0
- package/dist/conversation-resolver.d.ts.map +1 -0
- package/dist/dal/channel-identities.d.ts +26 -0
- package/dist/dal/channel-identities.d.ts.map +1 -0
- package/dist/dal/contacts.d.ts +30 -0
- package/dist/dal/contacts.d.ts.map +1 -0
- package/dist/dal/conversations.d.ts +67 -0
- package/dist/dal/conversations.d.ts.map +1 -0
- package/dist/dal/experiments.d.ts +47 -0
- package/dist/dal/experiments.d.ts.map +1 -0
- package/dist/dal/index.d.ts +14 -0
- package/dist/dal/index.d.ts.map +1 -0
- package/dist/dal/kb-store.d.ts +58 -0
- package/dist/dal/kb-store.d.ts.map +1 -0
- package/dist/dal/kb-suggestions.d.ts +26 -0
- package/dist/dal/kb-suggestions.d.ts.map +1 -0
- package/dist/dal/leads.d.ts +38 -0
- package/dist/dal/leads.d.ts.map +1 -0
- package/dist/dal/messages.d.ts +48 -0
- package/dist/dal/messages.d.ts.map +1 -0
- package/dist/dal/notifications.d.ts +32 -0
- package/dist/dal/notifications.d.ts.map +1 -0
- package/dist/dal/outbound.d.ts +70 -0
- package/dist/dal/outbound.d.ts.map +1 -0
- package/dist/dal/skill-outcomes.d.ts +58 -0
- package/dist/dal/skill-outcomes.d.ts.map +1 -0
- package/dist/dal/styles.d.ts +44 -0
- package/dist/dal/styles.d.ts.map +1 -0
- package/dist/dal/types.d.ts +27 -0
- package/dist/dal/types.d.ts.map +1 -0
- package/dist/dispatch-reply.d.ts +49 -0
- package/dist/dispatch-reply.d.ts.map +1 -0
- package/dist/dispatch-reply.test.d.ts +2 -0
- package/dist/dispatch-reply.test.d.ts.map +1 -0
- package/dist/experiment-router.d.ts +15 -0
- package/dist/experiment-router.d.ts.map +1 -0
- package/dist/experiment-router.test.d.ts +2 -0
- package/dist/experiment-router.test.d.ts.map +1 -0
- package/dist/extract-fields.test.d.ts +2 -0
- package/dist/extract-fields.test.d.ts.map +1 -0
- package/dist/funnel-machine.d.ts +43 -0
- package/dist/funnel-machine.d.ts.map +1 -0
- package/dist/funnel-machine.test.d.ts +2 -0
- package/dist/funnel-machine.test.d.ts.map +1 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2024 -0
- package/dist/lead-lifecycle.d.ts +46 -0
- package/dist/lead-lifecycle.d.ts.map +1 -0
- package/dist/lead-lifecycle.test.d.ts +2 -0
- package/dist/lead-lifecycle.test.d.ts.map +1 -0
- package/dist/memory-extractor.d.ts +62 -0
- package/dist/memory-extractor.d.ts.map +1 -0
- package/dist/memory-extractor.test.d.ts +2 -0
- package/dist/memory-extractor.test.d.ts.map +1 -0
- package/dist/notifications.d.ts +32 -0
- package/dist/notifications.d.ts.map +1 -0
- package/dist/notifications.test.d.ts +2 -0
- package/dist/notifications.test.d.ts.map +1 -0
- package/dist/operator-bot-handler.d.ts +13 -0
- package/dist/operator-bot-handler.d.ts.map +1 -0
- package/dist/operator-bot-handler.test.d.ts +2 -0
- package/dist/operator-bot-handler.test.d.ts.map +1 -0
- package/dist/outbound-dispatch.d.ts +17 -0
- package/dist/outbound-dispatch.d.ts.map +1 -0
- package/dist/process-inbound.d.ts +126 -0
- package/dist/process-inbound.d.ts.map +1 -0
- package/dist/process-inbound.test.d.ts +2 -0
- package/dist/process-inbound.test.d.ts.map +1 -0
- package/dist/reply-strategy/index.d.ts +3 -0
- package/dist/reply-strategy/index.d.ts.map +1 -0
- package/dist/reply-strategy/llm-reply.d.ts +69 -0
- package/dist/reply-strategy/llm-reply.d.ts.map +1 -0
- package/dist/reply-strategy/llm-reply.test.d.ts +2 -0
- package/dist/reply-strategy/llm-reply.test.d.ts.map +1 -0
- package/dist/reply-strategy/rag-reply.d.ts +175 -0
- package/dist/reply-strategy/rag-reply.d.ts.map +1 -0
- package/dist/rls-guard.d.ts +23 -0
- package/dist/rls-guard.d.ts.map +1 -0
- package/dist/rls-guard.integration.test.d.ts +2 -0
- package/dist/rls-guard.integration.test.d.ts.map +1 -0
- package/dist/secrets.d.ts +27 -0
- package/dist/secrets.d.ts.map +1 -0
- package/dist/secrets.test.d.ts +2 -0
- package/dist/secrets.test.d.ts.map +1 -0
- package/dist/stage-classifier.d.ts +48 -0
- package/dist/stage-classifier.d.ts.map +1 -0
- package/dist/testkit.d.ts +82 -0
- package/dist/testkit.d.ts.map +1 -0
- package/dist/transcriber.d.ts +15 -0
- package/dist/transcriber.d.ts.map +1 -0
- package/dist/types.d.ts +98 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/with-tenant.d.ts +25 -0
- package/dist/with-tenant.d.ts.map +1 -0
- package/package.json +66 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rag-reply.d.ts","sourceRoot":"","sources":["../../src/reply-strategy/rag-reply.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { Db } from "./dal/types.ts";
|
|
2
|
+
export interface RlsRoleCheck {
|
|
3
|
+
/** current_user в этом connection'е. */
|
|
4
|
+
role: string;
|
|
5
|
+
/** rolsuper — superuser bypass'ит RLS всегда. */
|
|
6
|
+
isSuperuser: boolean;
|
|
7
|
+
/** rolbypassrls — explicit BYPASSRLS attribute. */
|
|
8
|
+
hasBypassRls: boolean;
|
|
9
|
+
/** Resultant: будет ли RLS реально enforce'иться для этой роли. */
|
|
10
|
+
isEnforced: boolean;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Возвращает информацию о том, enforce'ится ли RLS на текущем connection'е.
|
|
14
|
+
* apps/api / apps/worker зовут это в boot и логируют warning если RLS
|
|
15
|
+
* по факту выключен (superuser / BYPASSRLS).
|
|
16
|
+
*
|
|
17
|
+
* Миграция 0004 включает FORCE ROW LEVEL SECURITY на всех tenant-scoped
|
|
18
|
+
* таблицах, но Postgres exempt'ит superuser-роли и роли с BYPASSRLS=true.
|
|
19
|
+
* Production deploy ДОЛЖЕН использовать ordinary role'ью (NOSUPERUSER
|
|
20
|
+
* NOBYPASSRLS) — иначе RLS бесполезен как defense-in-depth.
|
|
21
|
+
*/
|
|
22
|
+
export declare function checkRlsEnforcement(db: Db): Promise<RlsRoleCheck>;
|
|
23
|
+
//# sourceMappingURL=rls-guard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rls-guard.d.ts","sourceRoot":"","sources":["../src/rls-guard.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,gBAAgB,CAAC;AAEzC,MAAM,WAAW,YAAY;IAC3B,wCAAwC;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,iDAAiD;IACjD,WAAW,EAAE,OAAO,CAAC;IACrB,mDAAmD;IACnD,YAAY,EAAE,OAAO,CAAC;IACtB,mEAAmE;IACnE,UAAU,EAAE,OAAO,CAAC;CACrB;AAED;;;;;;;;;GASG;AACH,wBAAsB,mBAAmB,CAAC,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,YAAY,CAAC,CAyBvE"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rls-guard.integration.test.d.ts","sourceRoot":"","sources":["../src/rls-guard.integration.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { Db } from "./dal/types.ts";
|
|
2
|
+
export declare class SecretCryptoError extends Error {
|
|
3
|
+
constructor(reason: string);
|
|
4
|
+
}
|
|
5
|
+
export declare function encryptSecret(masterKeyHex: string, plaintext: string): string;
|
|
6
|
+
export declare function decryptSecret(masterKeyHex: string, ciphertext: string): string;
|
|
7
|
+
/**
|
|
8
|
+
* Прочитать и расшифровать secret. Возвращает null если ключ не существует
|
|
9
|
+
* для данного tenant'а. Бросает SecretCryptoError если ciphertext битый или
|
|
10
|
+
* master-key неверный (auth tag mismatch).
|
|
11
|
+
*/
|
|
12
|
+
export declare function getDecryptedSecret(opts: {
|
|
13
|
+
db: Db;
|
|
14
|
+
tenantId: number;
|
|
15
|
+
key: string;
|
|
16
|
+
masterKeyHex: string;
|
|
17
|
+
}): Promise<string | null>;
|
|
18
|
+
/** Upsert зашифрованного secret'а. */
|
|
19
|
+
export declare function setEncryptedSecret(opts: {
|
|
20
|
+
db: Db;
|
|
21
|
+
tenantId: number;
|
|
22
|
+
key: string;
|
|
23
|
+
value: string;
|
|
24
|
+
masterKeyHex: string;
|
|
25
|
+
nowEpoch: number;
|
|
26
|
+
}): Promise<void>;
|
|
27
|
+
//# sourceMappingURL=secrets.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secrets.d.ts","sourceRoot":"","sources":["../src/secrets.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,gBAAgB,CAAC;AAkBzC,qBAAa,iBAAkB,SAAQ,KAAK;gBAC9B,MAAM,EAAE,MAAM;CAI3B;AAeD,wBAAgB,aAAa,CAAC,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAc7E;AAED,wBAAgB,aAAa,CAAC,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAoB9E;AAID;;;;GAIG;AACH,wBAAsB,kBAAkB,CAAC,IAAI,EAAE;IAC7C,EAAE,EAAE,EAAE,CAAC;IACP,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,EAAE,MAAM,CAAC;CACtB,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAOzB;AAED,sCAAsC;AACtC,wBAAsB,kBAAkB,CAAC,IAAI,EAAE;IAC7C,EAAE,EAAE,EAAE,CAAC;IACP,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;CAClB,GAAG,OAAO,CAAC,IAAI,CAAC,CAehB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secrets.test.d.ts","sourceRoot":"","sources":["../src/secrets.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { FunnelStage } from "@chatman-media/kb";
|
|
2
|
+
import type { Db } from "./dal/types.ts";
|
|
3
|
+
/**
|
|
4
|
+
* Pipeline contract: что pipeline ожидает от любого stage-classifier
|
|
5
|
+
* (regex/LLM/external). Implementations живут в `@chatman-media/sales`
|
|
6
|
+
* как sales-domain logic — sales имеет access к ChatClient и регекспам
|
|
7
|
+
* для русских sales-cues.
|
|
8
|
+
*
|
|
9
|
+
* Здесь только TYPE — чтобы processInbound и apps/api могли референсить
|
|
10
|
+
* без создания circular dep (sales → conv-engine для Db типов).
|
|
11
|
+
*
|
|
12
|
+
* НЕ путать с vertical-template'овским lead.state (intake_pending → docs →
|
|
13
|
+
* visa) — это разные оси:
|
|
14
|
+
* - lead.state: операционный pipeline найма (один на лида)
|
|
15
|
+
* - conversation.current_stage: micro-state диалога продажи (per turn)
|
|
16
|
+
*/
|
|
17
|
+
export interface StageClassifier {
|
|
18
|
+
/**
|
|
19
|
+
* Классифицирует stage по тексту user-message + опц. контексту.
|
|
20
|
+
* Возвращает FunnelStage или null если уверенности нет.
|
|
21
|
+
*/
|
|
22
|
+
classify(input: {
|
|
23
|
+
/**
|
|
24
|
+
* Tenant контекст — нужен LLM-based реализациям для resolveChat
|
|
25
|
+
* (per-tenant LLM-config). Regex-impl игнорирует, но в interface
|
|
26
|
+
* required чтобы pipeline call-site всегда передавал реальный
|
|
27
|
+
* tenantId из processInbound deps.
|
|
28
|
+
*/
|
|
29
|
+
tenantId: number;
|
|
30
|
+
userMessageText: string;
|
|
31
|
+
previousStage: string | null;
|
|
32
|
+
isFirstUserMessage: boolean;
|
|
33
|
+
}): Promise<FunnelStage | null> | FunnelStage | null;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Обновляет `conversations.current_stage` если new стадия отличается от
|
|
37
|
+
* существующей. Idempotent: same-stage → no UPDATE. Pipeline-side persistence
|
|
38
|
+
* step — живёт в conv-engine (где DAL), а не в sales (где stage classifier
|
|
39
|
+
* impls). Чтобы избежать circular dep, sales-impl'ы возвращают FunnelStage,
|
|
40
|
+
* conv-engine берёт результат и применяет через applyClassifiedStage.
|
|
41
|
+
*/
|
|
42
|
+
export declare function applyClassifiedStage(opts: {
|
|
43
|
+
db: Db;
|
|
44
|
+
tenantId: number;
|
|
45
|
+
conversationId: number;
|
|
46
|
+
newStage: FunnelStage | null;
|
|
47
|
+
}): Promise<boolean>;
|
|
48
|
+
//# sourceMappingURL=stage-classifier.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stage-classifier.d.ts","sourceRoot":"","sources":["../src/stage-classifier.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,gBAAgB,CAAC;AAEzC;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,QAAQ,CAAC,KAAK,EAAE;QACd;;;;;WAKG;QACH,QAAQ,EAAE,MAAM,CAAC;QACjB,eAAe,EAAE,MAAM,CAAC;QACxB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;QAC7B,kBAAkB,EAAE,OAAO,CAAC;KAC7B,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,WAAW,GAAG,IAAI,CAAC;CACtD;AAID;;;;;;GAMG;AACH,wBAAsB,oBAAoB,CAAC,IAAI,EAAE;IAC/C,EAAE,EAAE,EAAE,CAAC;IACP,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,WAAW,GAAG,IAAI,CAAC;CAC9B,GAAG,OAAO,CAAC,OAAO,CAAC,CAsBnB"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import type { ChannelIdentityRow, ContactRow, ConversationRow, MessageRow, OutboundQueueRow } from "./dal/index.ts";
|
|
2
|
+
export declare class FakeContactsRepo {
|
|
3
|
+
readonly tenantId: number;
|
|
4
|
+
private nextId;
|
|
5
|
+
private readonly rows;
|
|
6
|
+
constructor(tenantId: number);
|
|
7
|
+
byId(id: number): Promise<ContactRow | null>;
|
|
8
|
+
create(opts: {
|
|
9
|
+
displayName?: string;
|
|
10
|
+
attributesJson?: string;
|
|
11
|
+
}): Promise<ContactRow>;
|
|
12
|
+
mergeAttributes(contactId: number, partial: Record<string, unknown>, nowEpoch: number): Promise<ContactRow | null>;
|
|
13
|
+
all(): ContactRow[];
|
|
14
|
+
}
|
|
15
|
+
export declare class FakeChannelIdentitiesRepo {
|
|
16
|
+
private nextId;
|
|
17
|
+
private readonly rows;
|
|
18
|
+
find(channelId: number, externalUserId: string): Promise<ChannelIdentityRow | null>;
|
|
19
|
+
create(opts: {
|
|
20
|
+
contactId: number;
|
|
21
|
+
channelId: number;
|
|
22
|
+
externalUserId: string;
|
|
23
|
+
}): Promise<ChannelIdentityRow>;
|
|
24
|
+
all(): ChannelIdentityRow[];
|
|
25
|
+
}
|
|
26
|
+
export declare class FakeConversationsRepo {
|
|
27
|
+
readonly tenantId: number;
|
|
28
|
+
private nextId;
|
|
29
|
+
private readonly rows;
|
|
30
|
+
constructor(tenantId: number);
|
|
31
|
+
findByContactAndSource(contactId: number, source: string): Promise<ConversationRow | null>;
|
|
32
|
+
create(opts: {
|
|
33
|
+
contactId: number;
|
|
34
|
+
source: string;
|
|
35
|
+
mode?: "ai" | "queued" | "human";
|
|
36
|
+
nowEpoch: number;
|
|
37
|
+
}): Promise<ConversationRow>;
|
|
38
|
+
touchLastMessageAt(conversationId: number, nowEpoch: number): Promise<void>;
|
|
39
|
+
updateInboxMetadata(conversationId: number, opts: {
|
|
40
|
+
lastMessageText?: string;
|
|
41
|
+
lastMessageAt?: number;
|
|
42
|
+
incrementUnread?: boolean;
|
|
43
|
+
status?: "open" | "pending" | "resolved";
|
|
44
|
+
}): Promise<void>;
|
|
45
|
+
markAsRead(conversationId: number): Promise<void>;
|
|
46
|
+
setAssignee(conversationId: number, adminId: number | null): Promise<void>;
|
|
47
|
+
all(): ConversationRow[];
|
|
48
|
+
}
|
|
49
|
+
export declare class FakeMessagesRepo {
|
|
50
|
+
readonly tenantId: number;
|
|
51
|
+
private nextId;
|
|
52
|
+
private readonly rows;
|
|
53
|
+
constructor(tenantId: number);
|
|
54
|
+
insert(opts: {
|
|
55
|
+
conversationId: number;
|
|
56
|
+
role: "user" | "assistant" | "human" | "system";
|
|
57
|
+
text: string;
|
|
58
|
+
externalMessageId?: string;
|
|
59
|
+
metaJson?: string;
|
|
60
|
+
stage?: string;
|
|
61
|
+
nowEpoch: number;
|
|
62
|
+
}): Promise<MessageRow>;
|
|
63
|
+
findUserByExternalId(conversationId: number, externalMessageId: string): Promise<MessageRow | null>;
|
|
64
|
+
all(): MessageRow[];
|
|
65
|
+
}
|
|
66
|
+
export declare class FakeOutboundQueueRepo {
|
|
67
|
+
readonly tenantId: number;
|
|
68
|
+
private nextId;
|
|
69
|
+
private readonly rows;
|
|
70
|
+
constructor(tenantId: number);
|
|
71
|
+
enqueue(opts: {
|
|
72
|
+
channelId: number;
|
|
73
|
+
conversationId?: number | null;
|
|
74
|
+
envelope: {
|
|
75
|
+
idempotencyKey?: string;
|
|
76
|
+
};
|
|
77
|
+
scheduledAt?: number;
|
|
78
|
+
nowEpoch: number;
|
|
79
|
+
}): Promise<OutboundQueueRow>;
|
|
80
|
+
all(): OutboundQueueRow[];
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=testkit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"testkit.d.ts","sourceRoot":"","sources":["../src/testkit.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Интерфейс для STT-транскрибации голосовых сообщений.
|
|
3
|
+
* Pipeline инжектит реализацию через ProcessInboundDeps.transcriber.
|
|
4
|
+
* Реализация живёт в apps/api (WhisperTranscriber).
|
|
5
|
+
*/
|
|
6
|
+
export interface ITranscriber {
|
|
7
|
+
/**
|
|
8
|
+
* Транскрибирует аудиофайл в текст.
|
|
9
|
+
* @param audio Raw bytes аудиофайла (OGG, MP3, WAV, …)
|
|
10
|
+
* @param filename Имя файла с расширением — провайдер определяет по нему формат
|
|
11
|
+
* @returns Текст транскрипции, или null если транскрипция не удалась
|
|
12
|
+
*/
|
|
13
|
+
transcribe(audio: Uint8Array, filename: string): Promise<string | null>;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=transcriber.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transcriber.d.ts","sourceRoot":"","sources":["../src/transcriber.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B;;;;;OAKG;IACH,UAAU,CAAC,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CACzE"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import type { Inbound, OutboundEnvelope } from "@chatman-media/channel-core";
|
|
2
|
+
/**
|
|
3
|
+
* Минимальный snapshot tenant'а нужный для pipeline. Резолвится по
|
|
4
|
+
* channels.tenant_id один раз на inbound и прокидывается через context.
|
|
5
|
+
*/
|
|
6
|
+
export interface TenantContext {
|
|
7
|
+
tenantId: number;
|
|
8
|
+
slug: string;
|
|
9
|
+
llmBillingMode: "byok" | "managed";
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Канал-уровневый контекст. channelId стабильный — соответствует
|
|
13
|
+
* channels.id в БД, использовать его, не external_id.
|
|
14
|
+
*/
|
|
15
|
+
export interface ChannelContext {
|
|
16
|
+
channelId: number;
|
|
17
|
+
kind: "telegram_bot" | "telegram_userbot" | "whatsapp" | "web";
|
|
18
|
+
/** External id канала у провайдера (bot username, phone). Для логов. */
|
|
19
|
+
externalId: string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Решение pipeline по входящему: что было сделано и нужны ли downstream
|
|
23
|
+
* действия. Возвращается из processInbound() так чтобы apps/worker мог
|
|
24
|
+
* dispatch'ить telemetry / WebSocket events без дёрганья БД.
|
|
25
|
+
*/
|
|
26
|
+
export interface ProcessInboundResult {
|
|
27
|
+
contactId: number;
|
|
28
|
+
conversationId: number;
|
|
29
|
+
/**
|
|
30
|
+
* Сообщение записано в messages? Может быть false если inbound полностью
|
|
31
|
+
* проигнорирован (например, callback_query без матча на функционал).
|
|
32
|
+
*/
|
|
33
|
+
persisted: boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Сколько OutboundEnvelope'ов было поставлено в outbound_queue в этом
|
|
36
|
+
* pipeline-проходе. 0 = бот ничего не отвечает (mediaOnly / handover-mode).
|
|
37
|
+
*/
|
|
38
|
+
outboundEnqueued: number;
|
|
39
|
+
/**
|
|
40
|
+
* Текст user-сообщения (после inboundText() свёртки). Заполняется когда
|
|
41
|
+
* pipeline вызван с `deferReply: true` — `generateReplyAndEnqueue` потом
|
|
42
|
+
* использует это значение для reply.generate БЕЗ нового read'а из БД.
|
|
43
|
+
* Когда deferReply=false (default) — поле не выставляется.
|
|
44
|
+
*/
|
|
45
|
+
userMessageText?: string;
|
|
46
|
+
/** True если только media без caption (бот не должен отвечать). */
|
|
47
|
+
mediaOnly?: boolean;
|
|
48
|
+
/**
|
|
49
|
+
* True если processInbound пропустил reply.generate (deferReply=true) —
|
|
50
|
+
* caller должен вызвать `generateReplyAndEnqueue` чтобы завершить
|
|
51
|
+
* pipeline. False (или undefined) = pipeline отработал полностью.
|
|
52
|
+
*/
|
|
53
|
+
replyDeferred?: boolean;
|
|
54
|
+
/** Если конверсация переключилась в режим оператора — сюда попадает причина. */
|
|
55
|
+
escalatedReason?: string;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Дешёвый side-effect sink. Тонкая обёртка чтобы pipeline не зависел от
|
|
59
|
+
* конкретного логгера/EventBus'а. apps/worker подсоединяет реальный sink
|
|
60
|
+
* на boot. Все поля опциональные — testkit-fake может не реализовывать
|
|
61
|
+
* ничего и pipeline всё равно работает.
|
|
62
|
+
*/
|
|
63
|
+
export interface PipelineSink {
|
|
64
|
+
log?: (level: "debug" | "info" | "warn" | "error", msg: string, meta?: Record<string, unknown>) => void;
|
|
65
|
+
emit?: (event: PipelineEvent) => void;
|
|
66
|
+
}
|
|
67
|
+
export type PipelineEvent = {
|
|
68
|
+
type: "inbound-received";
|
|
69
|
+
tenantId: number;
|
|
70
|
+
conversationId: number;
|
|
71
|
+
inbound: Inbound;
|
|
72
|
+
} | {
|
|
73
|
+
type: "message-persisted";
|
|
74
|
+
tenantId: number;
|
|
75
|
+
conversationId: number;
|
|
76
|
+
messageId: number;
|
|
77
|
+
role: "user" | "assistant";
|
|
78
|
+
} | {
|
|
79
|
+
type: "outbound-enqueued";
|
|
80
|
+
tenantId: number;
|
|
81
|
+
conversationId: number;
|
|
82
|
+
queueItemId: number;
|
|
83
|
+
envelope: OutboundEnvelope;
|
|
84
|
+
} | {
|
|
85
|
+
type: "conversation-escalated";
|
|
86
|
+
tenantId: number;
|
|
87
|
+
conversationId: number;
|
|
88
|
+
reason: string;
|
|
89
|
+
};
|
|
90
|
+
/**
|
|
91
|
+
* Стандартный clock — для тестирования (replace на fake clock в unit-тестах).
|
|
92
|
+
* `nowEpoch()` возвращает unix-seconds — формат, в котором БД хранит timestamps.
|
|
93
|
+
*/
|
|
94
|
+
export interface Clock {
|
|
95
|
+
nowEpoch(): number;
|
|
96
|
+
}
|
|
97
|
+
export declare const systemClock: Clock;
|
|
98
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAE7E;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,MAAM,GAAG,SAAS,CAAC;CACpC;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,cAAc,GAAG,kBAAkB,GAAG,UAAU,GAAG,KAAK,CAAC;IAC/D,wEAAwE;IACxE,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,SAAS,EAAE,OAAO,CAAC;IACnB;;;OAGG;IACH,gBAAgB,EAAE,MAAM,CAAC;IACzB;;;;;OAKG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,mEAAmE;IACnE,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;;OAIG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,gFAAgF;IAChF,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IAC3B,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;IACxG,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;CACvC;AAED,MAAM,MAAM,aAAa,GACrB;IAAE,IAAI,EAAE,kBAAkB,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,GACxF;IAAE,IAAI,EAAE,mBAAmB,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAAA;CAAE,GACtH;IAAE,IAAI,EAAE,mBAAmB,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,gBAAgB,CAAA;CAAE,GACxH;IAAE,IAAI,EAAE,wBAAwB,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEjG;;;GAGG;AACH,MAAM,WAAW,KAAK;IACpB,QAAQ,IAAI,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,WAAW,EAAE,KAEzB,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { Db } from "./dal/types.ts";
|
|
2
|
+
/**
|
|
3
|
+
* Открывает транзакцию, выставляет `SET LOCAL app.tenant_id = <id>` (для
|
|
4
|
+
* Postgres RLS-policy `tenant_isolation`), потом вызывает `fn(tx)`.
|
|
5
|
+
*
|
|
6
|
+
* RLS-policies в миграции 0004 сравнивают `tenant_id` колонку с
|
|
7
|
+
* `current_setting('app.tenant_id', true)::int`. Без SET LOCAL var = NULL
|
|
8
|
+
* → policy всегда false → 0 видимых строк (fail-safe).
|
|
9
|
+
*
|
|
10
|
+
* Использование в apps/api / apps/worker:
|
|
11
|
+
* const result = await withTenant(db, tenantId, async (tx) => {
|
|
12
|
+
* const repo = new ContactsRepo({ db: tx, tenantId });
|
|
13
|
+
* return repo.byId(42);
|
|
14
|
+
* });
|
|
15
|
+
*
|
|
16
|
+
* `tx` имеет тот же тип что `Db` (Drizzle PostgresJsDatabase) — repo-методы
|
|
17
|
+
* принимают его без изменений. SET LOCAL scoped в транзакцию: после COMMIT
|
|
18
|
+
* setting сбрасывается, connection возвращается в pool clean.
|
|
19
|
+
*
|
|
20
|
+
* Idempotent при nested-вызовах: вложенный withTenant с тем же tenantId
|
|
21
|
+
* просто переоткроет SET LOCAL (no-op effectively); с разным — переопределит
|
|
22
|
+
* (caller responsibility — не делать так без чёткого понимания).
|
|
23
|
+
*/
|
|
24
|
+
export declare function withTenant<T>(db: Db, tenantId: number, fn: (tx: Db) => Promise<T>): Promise<T>;
|
|
25
|
+
//# sourceMappingURL=with-tenant.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"with-tenant.d.ts","sourceRoot":"","sources":["../src/with-tenant.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,gBAAgB,CAAC;AAEzC;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAsB,UAAU,CAAC,CAAC,EAChC,EAAE,EAAE,EAAE,EACN,QAAQ,EAAE,MAAM,EAChB,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,KAAK,OAAO,CAAC,CAAC,CAAC,GACzB,OAAO,CAAC,CAAC,CAAC,CAOZ"}
|
package/package.json
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@chatman-media/conversation-engine",
|
|
3
|
+
"version": "1.2.0",
|
|
4
|
+
"description": "Channel-agnostic pipeline обработки inbound сообщений: contact-resolve → conversation lookup → mode routing → AI-reply / queued / human → outbound. Сердце data plane.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"module": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"import": "./dist/index.js",
|
|
12
|
+
"types": "./dist/index.d.ts"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist",
|
|
17
|
+
"README.md",
|
|
18
|
+
"LICENSE"
|
|
19
|
+
],
|
|
20
|
+
"scripts": {
|
|
21
|
+
"build": "bun build ./src/index.ts --outdir ./dist --target node --format esm --external '@chatman-media/*' --external drizzle-orm && tsc -p tsconfig.build.json",
|
|
22
|
+
"typecheck": "tsc --noEmit",
|
|
23
|
+
"check": "biome check ./src",
|
|
24
|
+
"format": "biome format --write ./src",
|
|
25
|
+
"test": "bun test",
|
|
26
|
+
"prepublishOnly": "bun run build"
|
|
27
|
+
},
|
|
28
|
+
"keywords": [
|
|
29
|
+
"lead-engine",
|
|
30
|
+
"conversation",
|
|
31
|
+
"pipeline",
|
|
32
|
+
"multi-tenant"
|
|
33
|
+
],
|
|
34
|
+
"author": "Alexander Kireev",
|
|
35
|
+
"license": "MIT",
|
|
36
|
+
"dependencies": {
|
|
37
|
+
"@chatman-media/channel-core": "1.0.0",
|
|
38
|
+
"@chatman-media/channel-telegram": "1.0.0",
|
|
39
|
+
"@chatman-media/llm-router": "1.0.0",
|
|
40
|
+
"@chatman-media/kb": "1.2.0",
|
|
41
|
+
"@chatman-media/storage": "1.3.0",
|
|
42
|
+
"@chatman-media/verticals": "1.1.0"
|
|
43
|
+
},
|
|
44
|
+
"peerDependencies": {
|
|
45
|
+
"drizzle-orm": ">=0.36.0"
|
|
46
|
+
},
|
|
47
|
+
"devDependencies": {
|
|
48
|
+
"@biomejs/biome": "^2.4.14",
|
|
49
|
+
"@types/bun": "1.3.14",
|
|
50
|
+
"drizzle-orm": "^0.36.0",
|
|
51
|
+
"postgres": "^3.4.5",
|
|
52
|
+
"typescript": "^6.0.3"
|
|
53
|
+
},
|
|
54
|
+
"repository": {
|
|
55
|
+
"type": "git",
|
|
56
|
+
"url": "git+https://github.com/chatman-media/lead-engine.git",
|
|
57
|
+
"directory": "packages/conversation-engine"
|
|
58
|
+
},
|
|
59
|
+
"homepage": "https://github.com/chatman-media/lead-engine/tree/main/packages/conversation-engine#readme",
|
|
60
|
+
"bugs": {
|
|
61
|
+
"url": "https://github.com/chatman-media/lead-engine/issues"
|
|
62
|
+
},
|
|
63
|
+
"publishConfig": {
|
|
64
|
+
"access": "public"
|
|
65
|
+
}
|
|
66
|
+
}
|