@kavchat/core 0.0.2 → 0.0.3

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/index.d.ts CHANGED
@@ -1,144 +1,3 @@
1
- /**
2
- * מבנה התוכן שהשרת מפרסם ושכל לקוח (ווידג'ט, React Native, Flutter, iOS, Android) מריץ
3
- * זהה ל-ClientRelease במפרט ה-OpenAPI
4
- */
5
- type BotAction = {
6
- type: 'step';
7
- stepId: string;
8
- } | {
9
- type: 'goto';
10
- stepId: string;
11
- scriptId?: string;
12
- } | {
13
- type: 'contact';
14
- } | {
15
- type: 'screen';
16
- screen: string;
17
- targetId?: string;
18
- } | {
19
- type: 'link';
20
- url: string;
21
- } | {
22
- type: 'script';
23
- scriptId: string;
24
- };
25
- interface BotButton {
26
- id: string;
27
- label: string;
28
- action: BotAction | null;
29
- }
30
- interface BotStep {
31
- id: string;
32
- text: string;
33
- imageUrl?: string;
34
- keywords: string[];
35
- buttons: BotButton[];
36
- }
37
- interface BotScriptContent {
38
- name: string;
39
- keywords: string[];
40
- contactTopicId?: string;
41
- rootStepId: string;
42
- steps: BotStep[];
43
- }
44
- interface BotScript {
45
- id: string;
46
- kind: 'opening' | 'topic';
47
- sortOrder: number;
48
- content: BotScriptContent;
49
- }
50
- interface BotSettings {
51
- botName: string;
52
- avatarText: string;
53
- avatarImageUrl: string | null;
54
- subtitle: string;
55
- primaryColor: string;
56
- position: 'start' | 'end';
57
- contactTopics: Array<{
58
- id: string;
59
- name: string;
60
- }>;
61
- /** false בתוכנית החינמית: הסמל "Powered by Kavchat" חייב להופיע */
62
- removeBranding?: boolean;
63
- /** true כשבעל סביבת העבודה הפעיל תשובות AI (פרימיום, על המפתח שלו). שואלים את /ai/answer רק כשאין התאמה */
64
- aiAnswers?: boolean;
65
- }
66
- type ClientRelease = {
67
- enabled: false;
68
- } | {
69
- enabled: true;
70
- version: number;
71
- locale: string;
72
- settings: BotSettings;
73
- openingScriptId: string;
74
- scripts: BotScript[];
75
- };
76
-
77
- /**
78
- * נרמול טקסט לכל השפות הנתמכות, בלי ביטויים עם \p{...}, כי Hermes הישן לא תומך בהם
79
- *
80
- * - אותיות קטנות, הסרת ניקוד וטעמים (עברית), תשכיל (ערבית) וסימני הטעמה לטיניים (é → e)
81
- * - אותיות סופיות בעברית (ם → מ), צורות אליף בערבית (أ → ا), ё → е, ß → ss
82
- * - מילות קישור לכל שפה, והסרת תחיליות בעברית (ו, ה, ב...) ובערבית (ال, و, ب...)
83
- * - תאית ושאר הכתבים בלי רווחים בין מילים (לאו, חמרית, בורמזית, יפנית וסינית): ראו isSpacelessScript
84
- *
85
- * הפורטים ל-Dart, Swift ו-Kotlin חייבים לעבור את test-vectors/normalize.json
86
- */
87
- declare const SUPPORTED_LOCALES: readonly ["he", "en", "ar", "ru", "es", "fr", "de", "pt", "it", "tr", "th"];
88
- type Locale = (typeof SUPPORTED_LOCALES)[number];
89
- /**
90
- * מילה שיש בה תו מכתב בלי רווחים. מילות מפתח כאלה מותאמות כתת-מחרוזת של השאלה, ולא כמילה שלמה (ראו match.ts)
91
- */
92
- declare function isSpacelessScript(word: string): boolean;
93
- /** מנקה ומחזיר רשימת מילים */
94
- declare function normalizeWords(text: string): string[];
95
- /**
96
- * מסיר תחיליות כל עוד נשארות לפחות 3 אותיות ("והתשלום" ← "תשלומ", "والدفع" ← "دفع"),
97
- * ובאותיות לטיניות מסיר s של רבים ("arrives" ← "arrive"), חוץ מ-ss, us ו-is
98
- */
99
- declare function stripPrefixes(word: string): string;
100
- /**
101
- * מילים משמעותיות: בלי מילות קישור של שפת התוכן ושל אנגלית (משתמשים מערבבים), ואחרי הסרת תחיליות
102
- */
103
- declare function keyTerms(text: string, locale?: string): string[];
104
- /** מפתח קיבוץ לשאלות דומות בדוחות */
105
- declare function groupKey(text: string, locale?: string): string;
106
- /**
107
- * שגיאת כתיב אחת לכל היותר, רק במילים של 4 אותיות ומעלה:
108
- * אות חסרה, אות מיותרת, אות מוחלפת, או שתי אותיות סמוכות שהתחלפו ("trakcing")
109
- */
110
- declare function withinOneEdit(a: string, b: string): boolean;
111
- /** טקסט של שלב, מפוצל לבועות לפי שורה ריקה */
112
- declare const toBubbles: (text: string) => string[];
113
-
114
- /**
115
- * התאמה של שאלה חופשית לשלב בתסריט
116
- * ציון: מילה מובילה = 3, שם התסריט או כפתור שמוביל לשלב = 2, שגיאת כתיב של אות אחת = 0.5.
117
- * שלב אחד עם ציון כפול מהבא = single. כמה קרובים = multi (עד 3). אין כלום = none
118
- *
119
- * כתבים בלי רווחים (תאית, לאו, חמרית, בורמזית, יפנית, סינית): "ใบเสร็จอยู่ที่ไหน" היא מילה אחת בעיני normalizeWords,
120
- * ולכן השוואת מילים שלמות לא תמצא בה את "ใบเสร็จ". מילת מפתח, שם תסריט או כפתור שיש בהם תו מכתב כזה
121
- * מותאמים כתת-מחרוזת של כל השאלה המנורמלת, אחרי חיבור המילים בלי רווחים (משתמשים מוסיפים רווחים באמצע).
122
- * המשקלות זהים (3 ו-2). בתוך שלב, מונח שמוכל במונח ארוך יותר שנמצא, עם משקל שווה או גבוה, לא נספר שוב.
123
- * אין סובלנות לשגיאות כתיב בכתבים האלה: השאלה היא רצף אחד בלי גבולות מילים, ושינוי של סימן אחד
124
- * (למשל טון: ข้าว ו-ข่าว) הוא מילה אחרת. שגיאה של אות אחת בתת-מחרוזת קצרה הייתה מתאימה כמעט לכל שאלה
125
- */
126
- type MatchReason = {
127
- kind: 'keyword' | 'title' | 'typo';
128
- term: string;
129
- };
130
- interface BotMatch {
131
- scriptId: string;
132
- stepId: string;
133
- score: number;
134
- reasons: MatchReason[];
135
- }
136
- interface BotMatchResult {
137
- kind: 'single' | 'multi' | 'none';
138
- matches: BotMatch[];
139
- }
140
- declare function matchQuestion(scripts: BotScript[], text: string, locale?: string): BotMatchResult;
141
-
142
1
  declare const _exports: {
143
2
  "chat.askAnswered": string;
144
3
  "chat.yes": string;
@@ -177,6 +36,34 @@ declare const _exports: {
177
36
  "form.contactRequired": string;
178
37
  "form.emailInvalid": string;
179
38
  "form.backToChat": string;
39
+ "live.talk": string;
40
+ "live.intro": string;
41
+ "live.department": string;
42
+ "live.message": string;
43
+ "live.start": string;
44
+ "live.connecting": string;
45
+ "live.waiting": string;
46
+ "live.waitingLeft": string;
47
+ "live.leave": string;
48
+ "live.end": string;
49
+ "live.joined": string;
50
+ "live.with": string;
51
+ "live.agent": string;
52
+ "live.typing": string;
53
+ "live.ended": string;
54
+ "live.ticket": string;
55
+ "live.timeout": string;
56
+ "live.number": string;
57
+ "live.closed": string;
58
+ "live.closedUntil": string;
59
+ "live.busy": string;
60
+ "live.failed": string;
61
+ "live.back": string;
62
+ "live.reconnecting": string;
63
+ "live.tooLong": string;
64
+ "live.elsewhere": string;
65
+ "live.replaced": string;
66
+ "live.placeholder": string;
180
67
  };
181
68
 
182
69
  /**
@@ -192,6 +79,34 @@ declare const isRtl: (locale: string) => boolean;
192
79
  declare function uiTexts(locale: string, overrides?: Partial<UiTexts>): UiTexts;
193
80
  declare const format: (template: string, params: Record<string, string | number>) => string;
194
81
 
82
+ /**
83
+ * התאמה של שאלה חופשית לשלב בתסריט
84
+ * ציון: מילה מובילה = 3, שם התסריט או כפתור שמוביל לשלב = 2, שגיאת כתיב של אות אחת = 0.5.
85
+ * שלב אחד עם ציון כפול מהבא = single. כמה קרובים = multi (עד 3). אין כלום = none
86
+ *
87
+ * כתבים בלי רווחים (תאית, לאו, חמרית, בורמזית, יפנית, סינית): "ใบเสร็จอยู่ที่ไหน" היא מילה אחת בעיני normalizeWords,
88
+ * ולכן השוואת מילים שלמות לא תמצא בה את "ใบเสร็จ". מילת מפתח, שם תסריט או כפתור שיש בהם תו מכתב כזה
89
+ * מותאמים כתת-מחרוזת של כל השאלה המנורמלת, אחרי חיבור המילים בלי רווחים (משתמשים מוסיפים רווחים באמצע).
90
+ * המשקלות זהים (3 ו-2). בתוך שלב, מונח שמוכל במונח ארוך יותר שנמצא, עם משקל שווה או גבוה, לא נספר שוב.
91
+ * אין סובלנות לשגיאות כתיב בכתבים האלה: השאלה היא רצף אחד בלי גבולות מילים, ושינוי של סימן אחד
92
+ * (למשל טון: ข้าว ו-ข่าว) הוא מילה אחרת. שגיאה של אות אחת בתת-מחרוזת קצרה הייתה מתאימה כמעט לכל שאלה
93
+ */
94
+ type MatchReason = {
95
+ kind: 'keyword' | 'title' | 'typo';
96
+ term: string;
97
+ };
98
+ interface BotMatch {
99
+ scriptId: string;
100
+ stepId: string;
101
+ score: number;
102
+ reasons: MatchReason[];
103
+ }
104
+ interface BotMatchResult {
105
+ kind: 'single' | 'multi' | 'none';
106
+ matches: BotMatch[];
107
+ }
108
+ declare function matchQuestion(scripts: BotScript[], text: string, locale?: string): BotMatchResult;
109
+
195
110
  /**
196
111
  * מנוע השיחה: פונקציות טהורות בלי ממשק
197
112
  * כל פעולה מחזירה { state, effect }. effect הוא מה שהלקוח צריך לעשות מחוץ לצ'אט:
@@ -209,7 +124,8 @@ interface BotMessage {
209
124
  /** תשובה שנוצרה ב-AI. הלקוח מציג לידה תווית, כדי שהמשתמש יידע שהיא לא מתסריט */
210
125
  ai?: boolean;
211
126
  }
212
- type ChipKind = 'button' | 'back' | 'home' | 'yes' | 'no' | 'contact' | 'pick';
127
+ /** live: "שיחה עם נציג". המנוע לא יוצר אותו בעצמו; הלקוח מוסיף אותו עם withLiveChip כשיש נציג זמין */
128
+ type ChipKind = 'button' | 'back' | 'home' | 'yes' | 'no' | 'contact' | 'pick' | 'live';
213
129
  interface BotChip {
214
130
  id: string;
215
131
  label: string;
@@ -260,7 +176,7 @@ interface TranscriptEntry {
260
176
  at: string;
261
177
  }
262
178
  type BotEffect = {
263
- type: 'contact';
179
+ type: 'contact' | 'live';
264
180
  contactTopicId: string | null;
265
181
  scriptId: string | null;
266
182
  prefill: string;
@@ -319,5 +235,256 @@ declare function eventsPayload(state: BotState, sessionId: string, releaseVersio
319
235
  }[];
320
236
  };
321
237
 
322
- export { AI_ANSWER_MAX, AI_QUESTION_MAX, RTL_LOCALES, SUPPORTED_LOCALES, UI_TEXTS, aiQuestion, answerWithAi, configureEngine, eventsPayload, format, groupKey, isRtl, isSpacelessScript, keyTerms, matchQuestion, normalizeWords, pendingQuestion, pressChip, sendText, startConversation, stripPrefixes, toBubbles, transcriptOf, uiTexts, withinOneEdit };
323
- export type { BotAction, BotButton, BotChip, BotEffect, BotMatch, BotMatchResult, BotMessage, BotOutcome, BotPathEntry, BotPosition, BotResult, BotScript, BotScriptContent, BotSettings, BotState, BotStep, ChipKind, ClientRelease, EngineOptions, Locale, MatchReason, TranscriptEntry, UiKey, UiTexts };
238
+ /**
239
+ * צד המבקר בצ'אט עם נציג: פונקציות טהורות בלי רשת ובלי ממשק.
240
+ * החוזה המלא: docs/live-chat-protocol.md. הרשת (SSE, סנכרון, ניסיונות חוזרים) נשארת בכל לקוח,
241
+ * אבל הסדר, הסינון הכפול, ההודעות שבדרך והטקסטים שמוצגים נקבעים כאן, כדי שכל הפורטים יתנהגו אותו דבר.
242
+ * הפורטים ל-Dart, Swift ו-Kotlin חייבים לעבור את test-vectors/live.json
243
+ */
244
+ type LiveState = 'queued' | 'active' | 'closed' | 'ticket';
245
+ type LiveUnavailableReason = 'disabled' | 'closed' | 'no_agents' | 'quota';
246
+ /** liveChat בגרסה שפורסמה. open הוא רק רמז מרגע הטעינה */
247
+ interface LiveChatRelease {
248
+ enabled: boolean;
249
+ open: boolean;
250
+ departments: Array<{
251
+ id: string;
252
+ name: string;
253
+ }>;
254
+ }
255
+ interface LiveAvailability {
256
+ enabled: boolean;
257
+ open: boolean;
258
+ reason: LiveUnavailableReason | null;
259
+ waitSeconds: number;
260
+ departments: Array<{
261
+ id: string;
262
+ name: string;
263
+ open: boolean;
264
+ reason: LiveUnavailableReason | null;
265
+ nextOpenAt?: string | null;
266
+ }>;
267
+ }
268
+ interface LiveConversation {
269
+ id: string;
270
+ state: LiveState;
271
+ departmentId?: string;
272
+ agent?: {
273
+ name?: string;
274
+ } | null;
275
+ queueDeadline?: string | null;
276
+ closeReason?: 'agent' | 'visitor' | 'expired' | null;
277
+ ticket?: {
278
+ number: number | null;
279
+ reason?: string;
280
+ } | null;
281
+ lastSeq: number;
282
+ credentialExpiresAt: string;
283
+ }
284
+ interface LiveEvent {
285
+ seq: number;
286
+ type: string;
287
+ author: {
288
+ kind: 'visitor' | 'agent' | 'system';
289
+ name?: string;
290
+ };
291
+ text?: string | null;
292
+ data?: Record<string, unknown> | null;
293
+ clientId?: string | null;
294
+ at: string;
295
+ }
296
+ /** הודעה של המבקר שעוד לא אושרה בשרת */
297
+ interface LivePending {
298
+ clientId: string;
299
+ text: string;
300
+ at: string;
301
+ status: 'sending' | 'failed';
302
+ }
303
+ interface LiveChat {
304
+ conversation: LiveConversation;
305
+ /** ממוינים לפי seq, בלי כפילויות */
306
+ events: LiveEvent[];
307
+ /** ה-seq הגבוה ביותר שהוחל. נשלח כ-after בסנכרון ובחיבור מחדש */
308
+ lastSeq: number;
309
+ pending: LivePending[];
310
+ }
311
+ /** שורה אחת לתצוגה */
312
+ interface LiveLine {
313
+ key: string;
314
+ kind: 'visitor' | 'agent' | 'system';
315
+ text: string;
316
+ name?: string;
317
+ status?: 'sending' | 'failed';
318
+ clientId?: string;
319
+ }
320
+ declare const LIVE_MESSAGE_MAX = 2000;
321
+ /** שליחת "מקליד" לכל היותר פעם ב-3 שניות */
322
+ declare const LIVE_TYPING_INTERVAL_MS = 3000;
323
+ /** "מקליד" של הנציג נעלם אחרי 6 שניות בלי עדכון */
324
+ declare const LIVE_TYPING_HIDE_MS = 6000;
325
+ /** כמה זמן תשובת /live/availability תקפה */
326
+ declare const LIVE_AVAILABILITY_TTL_MS = 30000;
327
+ declare const isLiveFinal: (state: LiveState | undefined) => state is "closed" | "ticket";
328
+ declare const isLiveClientId: (id: unknown) => id is string;
329
+ /**
330
+ * השהיה לפני ניסיון מספר attempt (מ-0): 1, 2, 4, 8, 16, 30 שניות, ועוד רעש אקראי של 30% לכל כיוון.
331
+ * random מוזרק כדי שהבדיקות יהיו דטרמיניסטיות
332
+ */
333
+ declare function liveBackoff(attempt: number, random?: () => number): number;
334
+ declare function liveStart(conversation: LiveConversation): LiveChat;
335
+ /**
336
+ * אובייקט השיחה הוא מקור האמת למצב. היחיד שלא מקבלים: חזרה ממצב סופי למצב פתוח,
337
+ * או אובייקט של שיחה אחרת
338
+ */
339
+ declare function liveApplyConversation(chat: LiveChat, conversation: LiveConversation | null | undefined): LiveChat;
340
+ /**
341
+ * אירוע מהזרם, מסנכרון או מתשובה לפקודה: מתעלמים מ-seq שכבר ידוע, מכניסים לפי seq,
342
+ * ולא מחכים ל-seq חסר. הודעה עם clientId מחליפה את הבועה "נשלח" שלה.
343
+ * אירועי מעבר (agent.joined, conversation.closed, conversation.ticket) מעדכנים גם את המצב,
344
+ * למקרה שאובייקט השיחה המעודכן עוד לא הגיע
345
+ */
346
+ declare function liveApplyEvent(chat: LiveChat, event: LiveEvent | null | undefined): LiveChat;
347
+ /** תשובה של POST /live/sync: קודם אובייקט השיחה, אחר כך האירועים לפי הסדר */
348
+ declare function liveApplySync(chat: LiveChat, sync: {
349
+ conversation?: LiveConversation | null;
350
+ events?: LiveEvent[] | null;
351
+ }): LiveChat;
352
+ /** הודעה חדשה של המבקר מוצגת מיד כ"נשלח". אותו clientId פעמיים, או כזה שכבר אושר, לא נוסף */
353
+ declare function liveAddPending(chat: LiveChat, clientId: string, text: string, at: string): LiveChat;
354
+ declare function liveSetPending(chat: LiveChat, clientId: string, status: LivePending['status'] | null): LiveChat;
355
+ /** מה מציגים: האירועים שהמבקר רואה, ואחריהם ההודעות שבדרך. סוגים לא מוכרים לא מוצגים */
356
+ declare function liveLines(chat: LiveChat, t: UiTexts): LiveLine[];
357
+ /** שניות שנשארו עד שהשיחה בתור הופכת לפנייה. null כשאין מועד או שהשיחה לא בתור */
358
+ declare function liveWaitLeft(conversation: LiveConversation, now: number): number | null;
359
+ /** 105 -> "1:45" */
360
+ declare const liveClock: (seconds: number) => string;
361
+ /** שורת המצב שמעל השיחה */
362
+ declare function liveStatus(conversation: LiveConversation, t: UiTexts, now: number): string;
363
+ /**
364
+ * למה אין נציג, לשורה שמעל טופס הפנייה. closed ו-no_agents מקבלים הסבר; quota ו-disabled לא (הטופס מוצג בלי הסבר).
365
+ * time: מתי חוזרים, כבר מעוצב בשפת הממשק (אם ידוע)
366
+ */
367
+ declare function liveUnavailableText(reason: LiveUnavailableReason | null | undefined, t: UiTexts, time?: string | null): string;
368
+ /**
369
+ * מוסיף "שיחה עם נציג" לפני "פנייה לצוות", עם אותו טקסט מוכן. הלקוח קורא לזה רק כש-liveChat.enabled
370
+ * ו-/live/availability אמר open
371
+ */
372
+ declare function withLiveChip(chips: BotChip[], label: string): BotChip[];
373
+
374
+ /**
375
+ * מבנה התוכן שהשרת מפרסם ושכל לקוח (ווידג'ט, React Native, Flutter, iOS, Android) מריץ
376
+ * זהה ל-ClientRelease במפרט ה-OpenAPI
377
+ */
378
+ type BotAction = {
379
+ type: 'step';
380
+ stepId: string;
381
+ } | {
382
+ type: 'goto';
383
+ stepId: string;
384
+ scriptId?: string;
385
+ } | {
386
+ type: 'contact';
387
+ } | {
388
+ type: 'screen';
389
+ screen: string;
390
+ targetId?: string;
391
+ } | {
392
+ type: 'link';
393
+ url: string;
394
+ } | {
395
+ type: 'script';
396
+ scriptId: string;
397
+ };
398
+ interface BotButton {
399
+ id: string;
400
+ label: string;
401
+ action: BotAction | null;
402
+ }
403
+ interface BotStep {
404
+ id: string;
405
+ text: string;
406
+ imageUrl?: string;
407
+ keywords: string[];
408
+ buttons: BotButton[];
409
+ }
410
+ interface BotScriptContent {
411
+ name: string;
412
+ keywords: string[];
413
+ contactTopicId?: string;
414
+ rootStepId: string;
415
+ steps: BotStep[];
416
+ }
417
+ interface BotScript {
418
+ id: string;
419
+ kind: 'opening' | 'topic';
420
+ sortOrder: number;
421
+ content: BotScriptContent;
422
+ }
423
+ interface BotSettings {
424
+ botName: string;
425
+ avatarText: string;
426
+ avatarImageUrl: string | null;
427
+ subtitle: string;
428
+ primaryColor: string;
429
+ position: 'start' | 'end';
430
+ contactTopics: Array<{
431
+ id: string;
432
+ name: string;
433
+ }>;
434
+ /** false בתוכנית החינמית: הסמל "Powered by Kavchat" חייב להופיע */
435
+ removeBranding?: boolean;
436
+ /** true כשבעל סביבת העבודה הפעיל תשובות AI (פרימיום, על המפתח שלו). שואלים את /ai/answer רק כשאין התאמה */
437
+ aiAnswers?: boolean;
438
+ }
439
+ type ClientRelease = {
440
+ enabled: false;
441
+ } | {
442
+ enabled: true;
443
+ version: number;
444
+ locale: string;
445
+ settings: BotSettings;
446
+ openingScriptId: string;
447
+ scripts: BotScript[];
448
+ /** חסר בשרת ישן: אז אין "שיחה עם נציג" */
449
+ liveChat?: LiveChatRelease;
450
+ };
451
+
452
+ /**
453
+ * נרמול טקסט לכל השפות הנתמכות, בלי ביטויים עם \p{...}, כי Hermes הישן לא תומך בהם
454
+ *
455
+ * - אותיות קטנות, הסרת ניקוד וטעמים (עברית), תשכיל (ערבית) וסימני הטעמה לטיניים (é → e)
456
+ * - אותיות סופיות בעברית (ם → מ), צורות אליף בערבית (أ → ا), ё → е, ß → ss
457
+ * - מילות קישור לכל שפה, והסרת תחיליות בעברית (ו, ה, ב...) ובערבית (ال, و, ب...)
458
+ * - תאית ושאר הכתבים בלי רווחים בין מילים (לאו, חמרית, בורמזית, יפנית וסינית): ראו isSpacelessScript
459
+ *
460
+ * הפורטים ל-Dart, Swift ו-Kotlin חייבים לעבור את test-vectors/normalize.json
461
+ */
462
+ declare const SUPPORTED_LOCALES: readonly ["he", "en", "ar", "ru", "es", "fr", "de", "pt", "it", "tr", "th"];
463
+ type Locale = (typeof SUPPORTED_LOCALES)[number];
464
+ /**
465
+ * מילה שיש בה תו מכתב בלי רווחים. מילות מפתח כאלה מותאמות כתת-מחרוזת של השאלה, ולא כמילה שלמה (ראו match.ts)
466
+ */
467
+ declare function isSpacelessScript(word: string): boolean;
468
+ /** מנקה ומחזיר רשימת מילים */
469
+ declare function normalizeWords(text: string): string[];
470
+ /**
471
+ * מסיר תחיליות כל עוד נשארות לפחות 3 אותיות ("והתשלום" ← "תשלומ", "والدفع" ← "دفع"),
472
+ * ובאותיות לטיניות מסיר s של רבים ("arrives" ← "arrive"), חוץ מ-ss, us ו-is
473
+ */
474
+ declare function stripPrefixes(word: string): string;
475
+ /**
476
+ * מילים משמעותיות: בלי מילות קישור של שפת התוכן ושל אנגלית (משתמשים מערבבים), ואחרי הסרת תחיליות
477
+ */
478
+ declare function keyTerms(text: string, locale?: string): string[];
479
+ /** מפתח קיבוץ לשאלות דומות בדוחות */
480
+ declare function groupKey(text: string, locale?: string): string;
481
+ /**
482
+ * שגיאת כתיב אחת לכל היותר, רק במילים של 4 אותיות ומעלה:
483
+ * אות חסרה, אות מיותרת, אות מוחלפת, או שתי אותיות סמוכות שהתחלפו ("trakcing")
484
+ */
485
+ declare function withinOneEdit(a: string, b: string): boolean;
486
+ /** טקסט של שלב, מפוצל לבועות לפי שורה ריקה */
487
+ declare const toBubbles: (text: string) => string[];
488
+
489
+ export { AI_ANSWER_MAX, AI_QUESTION_MAX, LIVE_AVAILABILITY_TTL_MS, LIVE_MESSAGE_MAX, LIVE_TYPING_HIDE_MS, LIVE_TYPING_INTERVAL_MS, RTL_LOCALES, SUPPORTED_LOCALES, UI_TEXTS, aiQuestion, answerWithAi, configureEngine, eventsPayload, format, groupKey, isLiveClientId, isLiveFinal, isRtl, isSpacelessScript, keyTerms, liveAddPending, liveApplyConversation, liveApplyEvent, liveApplySync, liveBackoff, liveClock, liveLines, liveSetPending, liveStart, liveStatus, liveUnavailableText, liveWaitLeft, matchQuestion, normalizeWords, pendingQuestion, pressChip, sendText, startConversation, stripPrefixes, toBubbles, transcriptOf, uiTexts, withLiveChip, withinOneEdit };
490
+ export type { BotAction, BotButton, BotChip, BotEffect, BotMatch, BotMatchResult, BotMessage, BotOutcome, BotPathEntry, BotPosition, BotResult, BotScript, BotScriptContent, BotSettings, BotState, BotStep, ChipKind, ClientRelease, EngineOptions, LiveAvailability, LiveChat, LiveChatRelease, LiveConversation, LiveEvent, LiveLine, LivePending, LiveState, LiveUnavailableReason, Locale, MatchReason, TranscriptEntry, UiKey, UiTexts };