@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":"outbound.d.ts","sourceRoot":"","sources":["../../src/dal/outbound.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAGpE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAE1C,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,SAAS,GAAG,YAAY,GAAG,MAAM,GAAG,QAAQ,GAAG,WAAW,CAAC;IACnE,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,iBAAiB;IAChB,OAAO,CAAC,QAAQ,CAAC,GAAG;gBAAH,GAAG,EAAE,OAAO;IAEzC;;;;;OAKG;IACG,OAAO,CAAC,IAAI,EAAE;QAClB,SAAS,EAAE,MAAM,CAAC;QAClB,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC/B,QAAQ,EAAE,gBAAgB,CAAC;QAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,QAAQ,EAAE,MAAM,CAAC;KAClB,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAmC7B;;;;;;;;;;OAUG;IACH;;;;;;;OAOG;IACG,YAAY,CAAC,IAAI,EAAE;QACvB,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,EAAE,MAAM,CAAC;QACjB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;KAClB,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAgD/B;;;;OAIG;IACG,sBAAsB,CAAC,IAAI,EAAE;QACjC,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;KAClB,GAAG,OAAO,CAAC,MAAM,CAAC;IAab,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAchF,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAY3D"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { RepoCtx } from "./types.ts";
|
|
2
|
+
export interface SkillOutcomeRow {
|
|
3
|
+
id: number;
|
|
4
|
+
tenantId: number;
|
|
5
|
+
leadId: number;
|
|
6
|
+
conversationId: number | null;
|
|
7
|
+
messageId: number | null;
|
|
8
|
+
styleSlug: string | null;
|
|
9
|
+
skillSlug: string;
|
|
10
|
+
outcome: "won" | "lost" | "draw";
|
|
11
|
+
source: "lead_submitted" | "lead_rejected" | "lead_ghosted" | "manual" | "self_play";
|
|
12
|
+
createdAt: number;
|
|
13
|
+
}
|
|
14
|
+
export interface SkillAggregateRow {
|
|
15
|
+
skillSlug: string;
|
|
16
|
+
wins: number;
|
|
17
|
+
losses: number;
|
|
18
|
+
draws: number;
|
|
19
|
+
total: number;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Per-skill outcome tracking. После того как lead закрыт (won/lost/ghosted),
|
|
23
|
+
* coach-analyzer проходит по messages в conversation и для каждой assistant-
|
|
24
|
+
* реплики дёргает gradeSkills из @chatman-media/kb — возвращённые slugs
|
|
25
|
+
* пишутся в skill_outcomes с этим outcome'ом. Aggregate'ы дают win-rate
|
|
26
|
+
* per skill для admin-UI / coach-proposals.
|
|
27
|
+
*
|
|
28
|
+
* Дедупликация: uniq на (lead_id, skill_slug, source) гарантирует одну
|
|
29
|
+
* запись на тройку — повторный coach-batch на тот же lead = no-op.
|
|
30
|
+
*/
|
|
31
|
+
export declare class SkillOutcomesRepo {
|
|
32
|
+
private readonly ctx;
|
|
33
|
+
constructor(ctx: RepoCtx);
|
|
34
|
+
/**
|
|
35
|
+
* Idempotent insert: ON CONFLICT DO NOTHING на uq_skill_outcomes_idempotency
|
|
36
|
+
* (lead_id, skill_slug, source). Возвращает true если строка реально
|
|
37
|
+
* вставлена, false если был conflict.
|
|
38
|
+
*/
|
|
39
|
+
record(opts: {
|
|
40
|
+
leadId: number;
|
|
41
|
+
skillSlug: string;
|
|
42
|
+
outcome: "won" | "lost" | "draw";
|
|
43
|
+
source: SkillOutcomeRow["source"];
|
|
44
|
+
conversationId?: number | null;
|
|
45
|
+
messageId?: number | null;
|
|
46
|
+
styleSlug?: string | null;
|
|
47
|
+
nowEpoch: number;
|
|
48
|
+
}): Promise<boolean>;
|
|
49
|
+
/** Все outcomes по lead'у (для inspect'а в admin-UI). */
|
|
50
|
+
byLeadId(leadId: number): Promise<SkillOutcomeRow[]>;
|
|
51
|
+
/**
|
|
52
|
+
* Aggregate win/loss/draw counts per skill. Без фильтра по style_slug —
|
|
53
|
+
* стиль-specific агрегаты для shadow-evaluations считаются отдельным
|
|
54
|
+
* запросом в caller'е через дополнительный WHERE.
|
|
55
|
+
*/
|
|
56
|
+
aggregates(): Promise<SkillAggregateRow[]>;
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=skill-outcomes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skill-outcomes.d.ts","sourceRoot":"","sources":["../../src/dal/skill-outcomes.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAE1C,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,KAAK,GAAG,MAAM,GAAG,MAAM,CAAC;IACjC,MAAM,EACF,gBAAgB,GAChB,eAAe,GACf,cAAc,GACd,QAAQ,GACR,WAAW,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;GASG;AACH,qBAAa,iBAAiB;IAChB,OAAO,CAAC,QAAQ,CAAC,GAAG;gBAAH,GAAG,EAAE,OAAO;IAEzC;;;;OAIG;IACG,MAAM,CAAC,IAAI,EAAE;QACjB,MAAM,EAAE,MAAM,CAAC;QACf,SAAS,EAAE,MAAM,CAAC;QAClB,OAAO,EAAE,KAAK,GAAG,MAAM,GAAG,MAAM,CAAC;QACjC,MAAM,EAAE,eAAe,CAAC,QAAQ,CAAC,CAAC;QAClC,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC/B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC1B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC1B,QAAQ,EAAE,MAAM,CAAC;KAClB,GAAG,OAAO,CAAC,OAAO,CAAC;IAgBpB,yDAAyD;IACnD,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;IAa1D;;;;OAIG;IACG,UAAU,IAAI,OAAO,CAAC,iBAAiB,EAAE,CAAC;CA2BjD"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { RepoCtx } from "./types.ts";
|
|
2
|
+
export interface StyleRow {
|
|
3
|
+
id: number;
|
|
4
|
+
tenantId: number;
|
|
5
|
+
slug: string;
|
|
6
|
+
displayName: string;
|
|
7
|
+
configJson: string;
|
|
8
|
+
isActive: boolean;
|
|
9
|
+
version: number;
|
|
10
|
+
parentId: number | null;
|
|
11
|
+
createdAt: number;
|
|
12
|
+
deletedAt: number | null;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Sales-style repo. Стили — versioned: один slug может иметь несколько строк
|
|
16
|
+
* с разными version'ами; uniq_styles_active_slug (partial unique WHERE
|
|
17
|
+
* is_active=TRUE) гарантирует одну живую версию на slug в каждый момент.
|
|
18
|
+
*
|
|
19
|
+
* findActiveBySlug → live версия. byId → конкретная версия (для audit /
|
|
20
|
+
* shadow-evaluations / rollback'ов).
|
|
21
|
+
*/
|
|
22
|
+
export declare class StylesRepo {
|
|
23
|
+
private readonly ctx;
|
|
24
|
+
constructor(ctx: RepoCtx);
|
|
25
|
+
byId(id: number): Promise<StyleRow | null>;
|
|
26
|
+
findActiveBySlug(slug: string): Promise<StyleRow | null>;
|
|
27
|
+
/** Все active не-soft-deleted стили tenant'а (для admin-UI dropdown). */
|
|
28
|
+
listActive(): Promise<StyleRow[]>;
|
|
29
|
+
/** Все не-soft-deleted стили tenant'а (включая неактивные). */
|
|
30
|
+
listAll(): Promise<StyleRow[]>;
|
|
31
|
+
create(data: {
|
|
32
|
+
slug: string;
|
|
33
|
+
displayName: string;
|
|
34
|
+
configJson: string;
|
|
35
|
+
isActive: boolean;
|
|
36
|
+
}): Promise<StyleRow>;
|
|
37
|
+
update(id: number, data: Partial<{
|
|
38
|
+
displayName: string;
|
|
39
|
+
configJson: string;
|
|
40
|
+
isActive: boolean;
|
|
41
|
+
}>): Promise<StyleRow | null>;
|
|
42
|
+
softDelete(id: number): Promise<boolean>;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=styles.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../../src/dal/styles.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAE1C,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED;;;;;;;GAOG;AACH,qBAAa,UAAU;IACT,OAAO,CAAC,QAAQ,CAAC,GAAG;gBAAH,GAAG,EAAE,OAAO;IAEnC,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IAU1C,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IAe9D,yEAAyE;IACnE,UAAU,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;IAcvC,+DAA+D;IACzD,OAAO,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;IAa9B,MAAM,CAAC,IAAI,EAAE;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,UAAU,EAAE,MAAM,CAAC;QACnB,QAAQ,EAAE,OAAO,CAAC;KACnB,GAAG,OAAO,CAAC,QAAQ,CAAC;IAiBf,MAAM,CACV,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,OAAO,CAAC;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAA;KAAE,CAAC,GAC5E,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IAerB,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAe/C"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { schema } from "@chatman-media/storage";
|
|
2
|
+
import type { PostgresJsDatabase } from "drizzle-orm/postgres-js";
|
|
3
|
+
/**
|
|
4
|
+
* Алиас Drizzle БД-инстанса со всей schema. apps/worker / apps/api инициируют
|
|
5
|
+
* drizzle(postgres(url), { schema }) на boot и прокидывают сюда. DAL-слой
|
|
6
|
+
* conversation-engine не знает откуда драйвер взялся.
|
|
7
|
+
*
|
|
8
|
+
* NB: `schema` — это именно namespaced re-export из storage/index.ts
|
|
9
|
+
* (`export * as schema from "./schema.ts"`), а не всё содержимое модуля.
|
|
10
|
+
* Использование `import type * as schema` ловит лишние exports
|
|
11
|
+
* (applyAllMigrations и т.п.) и расходится с тем, что отдаёт `drizzle(_, { schema })`.
|
|
12
|
+
*/
|
|
13
|
+
export type Db = PostgresJsDatabase<typeof schema>;
|
|
14
|
+
/**
|
|
15
|
+
* Конструктор репозиториев — pattern для всех DAL-классов. Принимает
|
|
16
|
+
* tenant_id чтобы каждый метод репо мог автоматически добавлять
|
|
17
|
+
* WHERE tenant_id = ? без явного prop'а в API.
|
|
18
|
+
*
|
|
19
|
+
* NOTE: tenant_id фильтрация в каждом методе — это "soft multi-tenancy"
|
|
20
|
+
* пока в БД не добавлены RLS-policies. План re-design явно откладывает
|
|
21
|
+
* RLS до этапа 9+. Защита — ESLint-правило на raw SQL в репозиториях.
|
|
22
|
+
*/
|
|
23
|
+
export interface RepoCtx {
|
|
24
|
+
db: Db;
|
|
25
|
+
tenantId: number;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/dal/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAElE;;;;;;;;;GASG;AACH,MAAM,MAAM,EAAE,GAAG,kBAAkB,CAAC,OAAO,MAAM,CAAC,CAAC;AAEnD;;;;;;;;GAQG;AACH,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,EAAE,CAAC;IACP,QAAQ,EAAE,MAAM,CAAC;CAClB"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { Inbound } from "@chatman-media/channel-core";
|
|
2
|
+
import type { Db } from "./dal/types.ts";
|
|
3
|
+
import { type ReplyStrategy } from "./process-inbound.ts";
|
|
4
|
+
import type { ChannelContext, PipelineSink, ProcessInboundResult, TenantContext } from "./types.ts";
|
|
5
|
+
/**
|
|
6
|
+
* Phase 2 of split pipeline (см. `processInbound` doc по `deferReply`):
|
|
7
|
+
* вызывает `reply.generate` ВНЕ открытой Postgres-tx и затем открывает
|
|
8
|
+
* собственную короткую tx через withTenant для enqueue outbound rows.
|
|
9
|
+
*
|
|
10
|
+
* Это разделение освобождает Postgres pool connection на время LLM
|
|
11
|
+
* call'а (~1-2s) — критично для high-throughput inbound на ограниченном
|
|
12
|
+
* pool=10.
|
|
13
|
+
*
|
|
14
|
+
* Caller-pattern:
|
|
15
|
+
* const result = await withTenant(db, tenantId, (tx) =>
|
|
16
|
+
* processInbound(inbound, { ..., db: tx, deferReply: true })
|
|
17
|
+
* );
|
|
18
|
+
* if (result.replyDeferred && replyStrategy) {
|
|
19
|
+
* await generateReplyAndEnqueue({
|
|
20
|
+
* db, tenantId, channelDbId, channel, tenant,
|
|
21
|
+
* inbound, result, replyStrategy, sink,
|
|
22
|
+
* });
|
|
23
|
+
* }
|
|
24
|
+
*
|
|
25
|
+
* Когда `result.replyDeferred` is false/undefined — caller не должен
|
|
26
|
+
* вызывать эту функцию (processInbound уже отработал полностью single-tx).
|
|
27
|
+
*/
|
|
28
|
+
export interface GenerateReplyAndEnqueueDeps {
|
|
29
|
+
db: Db;
|
|
30
|
+
tenant: TenantContext;
|
|
31
|
+
channel: ChannelContext;
|
|
32
|
+
channelDbId: number;
|
|
33
|
+
inbound: Inbound;
|
|
34
|
+
/** Результат processInbound с deferReply=true. */
|
|
35
|
+
result: ProcessInboundResult;
|
|
36
|
+
replyStrategy: ReplyStrategy;
|
|
37
|
+
sink?: PipelineSink;
|
|
38
|
+
clock?: {
|
|
39
|
+
nowEpoch: () => number;
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
export interface GenerateReplyResult {
|
|
43
|
+
/** Кол-во envelope'ов поставлено в outbound_queue. 0 если reply пустой
|
|
44
|
+
* или mediaOnly или conversation.mode != 'ai' (но проверка mode не
|
|
45
|
+
* делается тут — caller сам решает по результату processInbound). */
|
|
46
|
+
outboundEnqueued: number;
|
|
47
|
+
}
|
|
48
|
+
export declare function generateReplyAndEnqueue(deps: GenerateReplyAndEnqueueDeps): Promise<GenerateReplyResult>;
|
|
49
|
+
//# sourceMappingURL=dispatch-reply.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dispatch-reply.d.ts","sourceRoot":"","sources":["../src/dispatch-reply.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAoB,MAAM,6BAA6B,CAAC;AAE7E,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,gBAAgB,CAAC;AAEzC,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE1D,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAGpG;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,WAAW,2BAA2B;IAC1C,EAAE,EAAE,EAAE,CAAC;IACP,MAAM,EAAE,aAAa,CAAC;IACtB,OAAO,EAAE,cAAc,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,kDAAkD;IAClD,MAAM,EAAE,oBAAoB,CAAC;IAC7B,aAAa,EAAE,aAAa,CAAC;IAC7B,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,KAAK,CAAC,EAAE;QAAE,QAAQ,EAAE,MAAM,MAAM,CAAA;KAAE,CAAC;CACpC;AAED,MAAM,WAAW,mBAAmB;IAClC;;0EAEsE;IACtE,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,wBAAsB,uBAAuB,CAC3C,IAAI,EAAE,2BAA2B,GAChC,OAAO,CAAC,mBAAmB,CAAC,CAoD9B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dispatch-reply.test.d.ts","sourceRoot":"","sources":["../src/dispatch-reply.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Style } from "@chatman-media/kb";
|
|
2
|
+
import type { ExperimentRow, StylesRepo } from "./dal/index.ts";
|
|
3
|
+
/**
|
|
4
|
+
* Загружает variants эксперимента: парсит allocation_json + резолвит каждый
|
|
5
|
+
* style_slug через StylesRepo + StyleSchema.parse'ом. Невалидные/missing
|
|
6
|
+
* стили skipпаются с warning'ом — эксперимент идёт на оставшихся.
|
|
7
|
+
*
|
|
8
|
+
* Возвращает null если ни одного валидного variant'а не осталось — caller
|
|
9
|
+
* fall back'нет на default style (или DEFAULT_PERSONA если style тоже нет).
|
|
10
|
+
*/
|
|
11
|
+
export declare function loadExperimentVariants(experiment: ExperimentRow, stylesRepo: StylesRepo): Promise<Array<{
|
|
12
|
+
style: Style;
|
|
13
|
+
weight: number;
|
|
14
|
+
}> | null>;
|
|
15
|
+
//# sourceMappingURL=experiment-router.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"experiment-router.d.ts","sourceRoot":"","sources":["../src/experiment-router.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAIhE;;;;;;;GAOG;AACH,wBAAsB,sBAAsB,CAC1C,UAAU,EAAE,aAAa,EACzB,UAAU,EAAE,UAAU,GACrB,OAAO,CAAC,KAAK,CAAC;IAAE,KAAK,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,GAAG,IAAI,CAAC,CAsBzD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"experiment-router.test.d.ts","sourceRoot":"","sources":["../src/experiment-router.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extract-fields.test.d.ts","sourceRoot":"","sources":["../src/extract-fields.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { FunnelStageDef, VerticalTemplate } from "@chatman-media/verticals";
|
|
2
|
+
/**
|
|
3
|
+
* Валидация state-machine переходов лида. Источник истины — template.funnelStages:
|
|
4
|
+
* stage.next[] описывает разрешённые исходящие переходы. Terminal stages
|
|
5
|
+
* (kind: 'terminal') не имеют next — попытка перейти из них в любое
|
|
6
|
+
* состояние = ошибка.
|
|
7
|
+
*
|
|
8
|
+
* Реализовано как чистая функция без зависимостей от БД — позволяет
|
|
9
|
+
* проверять переход до того, как сделать UPDATE leads.state.
|
|
10
|
+
*/
|
|
11
|
+
export declare class FunnelTransitionError extends Error {
|
|
12
|
+
readonly fromState: string;
|
|
13
|
+
readonly toState: string;
|
|
14
|
+
readonly templateSlug: string;
|
|
15
|
+
constructor(fromState: string, toState: string, templateSlug: string, reason: string);
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Initial stage воронки — первый stage из funnelStages, обычно `intake`.
|
|
19
|
+
* Если template имеет questionnaire, его stageSlug должен соответствовать
|
|
20
|
+
* этому stage.
|
|
21
|
+
*/
|
|
22
|
+
export declare function getInitialStage(template: VerticalTemplate): FunnelStageDef;
|
|
23
|
+
/**
|
|
24
|
+
* Валидирует переход. Бросает FunnelTransitionError если невалиден,
|
|
25
|
+
* иначе ничего не возвращает (void = OK).
|
|
26
|
+
*
|
|
27
|
+
* Особые случаи:
|
|
28
|
+
* - переход в тот же state allowed (idempotent retry)
|
|
29
|
+
* - terminal → * никогда не allowed (закрытые лиды не переоткрываются;
|
|
30
|
+
* для реактивации создаётся новый Lead через operator-action)
|
|
31
|
+
*/
|
|
32
|
+
export declare function validateTransition(template: VerticalTemplate, fromState: string, toState: string): void;
|
|
33
|
+
/**
|
|
34
|
+
* Все валидные следующие stages из текущего. Используется UI'ем для
|
|
35
|
+
* рендера кнопок-переходов на lead-карточке.
|
|
36
|
+
*/
|
|
37
|
+
export declare function allowedTransitions(template: VerticalTemplate, fromState: string): string[];
|
|
38
|
+
/**
|
|
39
|
+
* Является ли stage финальным (terminal). Удобно UI'ю чтобы рендерить
|
|
40
|
+
* карточку как "архивную".
|
|
41
|
+
*/
|
|
42
|
+
export declare function isTerminal(template: VerticalTemplate, state: string): boolean;
|
|
43
|
+
//# sourceMappingURL=funnel-machine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"funnel-machine.d.ts","sourceRoot":"","sources":["../src/funnel-machine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAEjF;;;;;;;;GAQG;AACH,qBAAa,qBAAsB,SAAQ,KAAK;aAE5B,SAAS,EAAE,MAAM;aACjB,OAAO,EAAE,MAAM;aACf,YAAY,EAAE,MAAM;gBAFpB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,EACpC,MAAM,EAAE,MAAM;CAQjB;AAMD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,gBAAgB,GAAG,cAAc,CAM1E;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,gBAAgB,EAC1B,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,GACd,IAAI,CAgCN;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,CAI1F;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,gBAAgB,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAE7E"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"funnel-machine.test.d.ts","sourceRoot":"","sources":["../src/funnel-machine.test.ts"],"names":[],"mappings":""}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export { resolveContact } from "./contact-resolver.ts";
|
|
2
|
+
export { resolveConversation } from "./conversation-resolver.ts";
|
|
3
|
+
export { ChannelIdentitiesRepo, type ChannelIdentityRow, ContactsRepo, type ContactRow, ConversationsRepo, type ConversationRow, type Db, DrizzleKbStore, KbSuggestionsRepo, type ExperimentAllocationEntry, ExperimentsRepo, type ExperimentRow, LeadsRepo, type LeadRow, MessagesRepo, type MessageRow, OutboundQueueRepo, type OutboundQueueRow, parseAllocation, type RepoCtx, type SkillAggregateRow, type SkillOutcomeRow, SkillOutcomesRepo, StylesRepo, type StyleRow, NotificationsRepo, type NotificationRule, type OperatorSettings, } from "./dal/index.ts";
|
|
4
|
+
export { NotificationService, type NotificationEvent } from "./notifications.ts";
|
|
5
|
+
export { OperatorBotHandler } from "./operator-bot-handler.ts";
|
|
6
|
+
export { allowedTransitions, FunnelTransitionError, getInitialStage, isTerminal, validateTransition, } from "./funnel-machine.ts";
|
|
7
|
+
export { ensureLead, type LeadHookContext, transitionLeadState, } from "./lead-lifecycle.ts";
|
|
8
|
+
export { loadExperimentVariants } from "./experiment-router.ts";
|
|
9
|
+
export { compactConversation } from "./compact-conversation.ts";
|
|
10
|
+
export { LlmMemoryExtractor, type MemoryExtractor, runMemoryExtraction, } from "./memory-extractor.ts";
|
|
11
|
+
export { applyClassifiedStage, type StageClassifier } from "./stage-classifier.ts";
|
|
12
|
+
export { decryptSecret, encryptSecret, getDecryptedSecret, SecretCryptoError, setEncryptedSecret, } from "./secrets.ts";
|
|
13
|
+
export { generateReplyAndEnqueue, type GenerateReplyAndEnqueueDeps, type GenerateReplyResult, } from "./dispatch-reply.ts";
|
|
14
|
+
export { dispatchOutbound } from "./outbound-dispatch.ts";
|
|
15
|
+
export { processInbound, type ProcessInboundDeps, type ReplyStrategy, } from "./process-inbound.ts";
|
|
16
|
+
export type { ITranscriber } from "./transcriber.ts";
|
|
17
|
+
export { LlmReplyStrategy, type LlmReplyStrategyOpts, parseStyleConfig, RagReplyStrategy, type RagReplyStrategyOpts, } from "./reply-strategy/index.ts";
|
|
18
|
+
export { type ChannelContext, type Clock, type PipelineEvent, type PipelineSink, type ProcessInboundResult, systemClock, type TenantContext, } from "./types.ts";
|
|
19
|
+
export { withTenant } from "./with-tenant.ts";
|
|
20
|
+
export { checkRlsEnforcement, type RlsRoleCheck } from "./rls-guard.ts";
|
|
21
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EACL,qBAAqB,EACrB,KAAK,kBAAkB,EACvB,YAAY,EACZ,KAAK,UAAU,EACf,iBAAiB,EACjB,KAAK,eAAe,EACpB,KAAK,EAAE,EACP,cAAc,EACd,iBAAiB,EACjB,KAAK,yBAAyB,EAC9B,eAAe,EACf,KAAK,aAAa,EAClB,SAAS,EACT,KAAK,OAAO,EACZ,YAAY,EACZ,KAAK,UAAU,EACf,iBAAiB,EACjB,KAAK,gBAAgB,EACrB,eAAe,EACf,KAAK,OAAO,EACZ,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACpB,iBAAiB,EACjB,UAAU,EACV,KAAK,QAAQ,EACb,iBAAiB,EACjB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,GACtB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,mBAAmB,EAAE,KAAK,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACjF,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAK/D,OAAO,EACL,kBAAkB,EAClB,qBAAqB,EACrB,eAAe,EACf,UAAU,EACV,kBAAkB,GACnB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,UAAU,EACV,KAAK,eAAe,EACpB,mBAAmB,GACpB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,EACL,kBAAkB,EAClB,KAAK,eAAe,EACpB,mBAAmB,GACpB,MAAM,uBAAuB,CAAC;AAI/B,OAAO,EAAE,oBAAoB,EAAE,KAAK,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACnF,OAAO,EACL,aAAa,EACb,aAAa,EACb,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,GACnB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,uBAAuB,EACvB,KAAK,2BAA2B,EAChC,KAAK,mBAAmB,GACzB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EACL,cAAc,EACd,KAAK,kBAAkB,EACvB,KAAK,aAAa,GACnB,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EACL,gBAAgB,EAChB,KAAK,oBAAoB,EACzB,gBAAgB,EAChB,gBAAgB,EAChB,KAAK,oBAAoB,GAC1B,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,KAAK,EACV,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,oBAAoB,EACzB,WAAW,EACX,KAAK,aAAa,GACnB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,mBAAmB,EAAE,KAAK,YAAY,EAAE,MAAM,gBAAgB,CAAC"}
|