@kavchat/core 0.0.1 → 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 -133
- package/dist/index.d.ts +312 -133
- package/dist/index.js +633 -22
- package/dist/index.mjs +613 -22
- 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 +67 -0
- package/i18n/tr.json +30 -2
- package/package.json +1 -1
- package/test-vectors/conversation.json +364 -0
- package/test-vectors/fixtures.json +124 -0
- package/test-vectors/live.json +1308 -0
- package/test-vectors/match.json +131 -0
- package/test-vectors/normalize.json +123 -0
package/dist/index.d.mts
CHANGED
|
@@ -1,132 +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
|
-
*
|
|
84
|
-
* הפורטים ל-Dart, Swift ו-Kotlin חייבים לעבור את test-vectors/normalize.json
|
|
85
|
-
*/
|
|
86
|
-
declare const SUPPORTED_LOCALES: readonly ["he", "en", "ar", "ru", "es", "fr", "de", "pt", "it", "tr"];
|
|
87
|
-
type Locale = (typeof SUPPORTED_LOCALES)[number];
|
|
88
|
-
/** מנקה ומחזיר רשימת מילים */
|
|
89
|
-
declare function normalizeWords(text: string): string[];
|
|
90
|
-
/**
|
|
91
|
-
* מסיר תחיליות כל עוד נשארות לפחות 3 אותיות ("והתשלום" ← "תשלומ", "والدفع" ← "دفع"),
|
|
92
|
-
* ובאותיות לטיניות מסיר s של רבים ("arrives" ← "arrive"), חוץ מ-ss, us ו-is
|
|
93
|
-
*/
|
|
94
|
-
declare function stripPrefixes(word: string): string;
|
|
95
|
-
/**
|
|
96
|
-
* מילים משמעותיות: בלי מילות קישור של שפת התוכן ושל אנגלית (משתמשים מערבבים), ואחרי הסרת תחיליות
|
|
97
|
-
*/
|
|
98
|
-
declare function keyTerms(text: string, locale?: string): string[];
|
|
99
|
-
/** מפתח קיבוץ לשאלות דומות בדוחות */
|
|
100
|
-
declare function groupKey(text: string, locale?: string): string;
|
|
101
|
-
/**
|
|
102
|
-
* שגיאת כתיב אחת לכל היותר, רק במילים של 4 אותיות ומעלה:
|
|
103
|
-
* אות חסרה, אות מיותרת, אות מוחלפת, או שתי אותיות סמוכות שהתחלפו ("trakcing")
|
|
104
|
-
*/
|
|
105
|
-
declare function withinOneEdit(a: string, b: string): boolean;
|
|
106
|
-
/** טקסט של שלב, מפוצל לבועות לפי שורה ריקה */
|
|
107
|
-
declare const toBubbles: (text: string) => string[];
|
|
108
|
-
|
|
109
|
-
/**
|
|
110
|
-
* התאמה של שאלה חופשית לשלב בתסריט
|
|
111
|
-
* ציון: מילה מובילה = 3, שם התסריט או כפתור שמוביל לשלב = 2, שגיאת כתיב של אות אחת = 0.5.
|
|
112
|
-
* שלב אחד עם ציון כפול מהבא = single. כמה קרובים = multi (עד 3). אין כלום = none
|
|
113
|
-
*/
|
|
114
|
-
type MatchReason = {
|
|
115
|
-
kind: 'keyword' | 'title' | 'typo';
|
|
116
|
-
term: string;
|
|
117
|
-
};
|
|
118
|
-
interface BotMatch {
|
|
119
|
-
scriptId: string;
|
|
120
|
-
stepId: string;
|
|
121
|
-
score: number;
|
|
122
|
-
reasons: MatchReason[];
|
|
123
|
-
}
|
|
124
|
-
interface BotMatchResult {
|
|
125
|
-
kind: 'single' | 'multi' | 'none';
|
|
126
|
-
matches: BotMatch[];
|
|
127
|
-
}
|
|
128
|
-
declare function matchQuestion(scripts: BotScript[], text: string, locale?: string): BotMatchResult;
|
|
129
|
-
|
|
130
1
|
declare const _exports: {
|
|
131
2
|
"chat.askAnswered": string;
|
|
132
3
|
"chat.yes": string;
|
|
@@ -165,6 +36,34 @@ declare const _exports: {
|
|
|
165
36
|
"form.contactRequired": string;
|
|
166
37
|
"form.emailInvalid": string;
|
|
167
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;
|
|
168
67
|
};
|
|
169
68
|
|
|
170
69
|
/**
|
|
@@ -180,6 +79,34 @@ declare const isRtl: (locale: string) => boolean;
|
|
|
180
79
|
declare function uiTexts(locale: string, overrides?: Partial<UiTexts>): UiTexts;
|
|
181
80
|
declare const format: (template: string, params: Record<string, string | number>) => string;
|
|
182
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
|
+
|
|
183
110
|
/**
|
|
184
111
|
* מנוע השיחה: פונקציות טהורות בלי ממשק
|
|
185
112
|
* כל פעולה מחזירה { state, effect }. effect הוא מה שהלקוח צריך לעשות מחוץ לצ'אט:
|
|
@@ -197,7 +124,8 @@ interface BotMessage {
|
|
|
197
124
|
/** תשובה שנוצרה ב-AI. הלקוח מציג לידה תווית, כדי שהמשתמש יידע שהיא לא מתסריט */
|
|
198
125
|
ai?: boolean;
|
|
199
126
|
}
|
|
200
|
-
|
|
127
|
+
/** live: "שיחה עם נציג". המנוע לא יוצר אותו בעצמו; הלקוח מוסיף אותו עם withLiveChip כשיש נציג זמין */
|
|
128
|
+
type ChipKind = 'button' | 'back' | 'home' | 'yes' | 'no' | 'contact' | 'pick' | 'live';
|
|
201
129
|
interface BotChip {
|
|
202
130
|
id: string;
|
|
203
131
|
label: string;
|
|
@@ -248,7 +176,7 @@ interface TranscriptEntry {
|
|
|
248
176
|
at: string;
|
|
249
177
|
}
|
|
250
178
|
type BotEffect = {
|
|
251
|
-
type: 'contact';
|
|
179
|
+
type: 'contact' | 'live';
|
|
252
180
|
contactTopicId: string | null;
|
|
253
181
|
scriptId: string | null;
|
|
254
182
|
prefill: string;
|
|
@@ -307,5 +235,256 @@ declare function eventsPayload(state: BotState, sessionId: string, releaseVersio
|
|
|
307
235
|
}[];
|
|
308
236
|
};
|
|
309
237
|
|
|
310
|
-
|
|
311
|
-
|
|
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 };
|