@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.mts +312 -145
- package/dist/index.d.ts +312 -145
- package/dist/index.js +487 -13
- package/dist/index.mjs +468 -13
- package/i18n/ar.json +30 -2
- package/i18n/de.json +30 -2
- package/i18n/en.json +30 -2
- package/i18n/es.json +30 -2
- package/i18n/fr.json +30 -2
- package/i18n/he.json +30 -2
- package/i18n/it.json +30 -2
- package/i18n/pt.json +30 -2
- package/i18n/ru.json +30 -2
- package/i18n/th.json +29 -1
- package/i18n/tr.json +30 -2
- package/package.json +1 -1
- package/test-vectors/live.json +1308 -0
package/dist/index.d.mts
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
|
-
|
|
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
|
-
|
|
323
|
-
|
|
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 };
|