@sapia-ai/chatbot-v3 1.0.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/dist/EmbeddedVideoPlayer-SaMMfDIW.js +1277 -0
- package/dist/EmbeddedVideoPlayer-SaMMfDIW.js.map +1 -0
- package/dist/Preview-Db-hgkTh.js +83 -0
- package/dist/Preview-Db-hgkTh.js.map +1 -0
- package/dist/api/client.d.ts +60 -0
- package/dist/api/config.d.ts +18 -0
- package/dist/api/constants.d.ts +5 -0
- package/dist/api/index.d.ts +5 -0
- package/dist/api/sse.d.ts +12 -0
- package/dist/api/types/branding.d.ts +17 -0
- package/dist/api/types/messages.d.ts +148 -0
- package/dist/api/types/responses.d.ts +106 -0
- package/dist/api.js +2 -0
- package/dist/classPrivateFieldSet2-DtQPURVD.js +32 -0
- package/dist/core/bubbles/convert.d.ts +18 -0
- package/dist/core/bubbles/types.d.ts +55 -0
- package/dist/core/constants.d.ts +14 -0
- package/dist/core/events.d.ts +44 -0
- package/dist/core/i18n/fallback.d.ts +2 -0
- package/dist/core/i18n/languages.d.ts +11 -0
- package/dist/core/i18n/translator.d.ts +13 -0
- package/dist/core/interview.d.ts +207 -0
- package/dist/core/media/mimeTypes.d.ts +10 -0
- package/dist/core/media/recorder.d.ts +61 -0
- package/dist/core/persistence.d.ts +4 -0
- package/dist/core/store.d.ts +49 -0
- package/dist/core/theme/branding.d.ts +6 -0
- package/dist/core/theme/cssVariables.d.ts +16 -0
- package/dist/core/theme/types.d.ts +11 -0
- package/dist/core/validation/phoneCountries.d.ts +21 -0
- package/dist/core/validation/pii.d.ts +30 -0
- package/dist/dash.all.min-DZ1yEcJk.js +27302 -0
- package/dist/dash.all.min-DZ1yEcJk.js.map +1 -0
- package/dist/defineProperty-DiFpLzd2.js +39 -0
- package/dist/dist-BSi28_cP.js +702 -0
- package/dist/dist-BSi28_cP.js.map +1 -0
- package/dist/dist-DGBYKC8c.js +14327 -0
- package/dist/dist-DGBYKC8c.js.map +1 -0
- package/dist/dist-FvHBWiRa.js +76 -0
- package/dist/dist-FvHBWiRa.js.map +1 -0
- package/dist/embed/compat.d.ts +82 -0
- package/dist/embed/constants.d.ts +2 -0
- package/dist/embed/createChatbot.d.ts +22 -0
- package/dist/fix-webm-duration-BW9Fbdzt.js +1057 -0
- package/dist/fix-webm-duration-BW9Fbdzt.js.map +1 -0
- package/dist/hls-mBncGwsE.js +18657 -0
- package/dist/hls-mBncGwsE.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +4428 -0
- package/dist/index.js.map +1 -0
- package/dist/max-Btet1snX.js +12212 -0
- package/dist/max-Btet1snX.js.map +1 -0
- package/dist/messages-C4jqrtSG.js +187 -0
- package/dist/messages-C4jqrtSG.js.map +1 -0
- package/dist/react/AnswerInput.d.ts +21 -0
- package/dist/react/SapiaChatbot.d.ts +23 -0
- package/dist/react/bubbleViewModel.d.ts +50 -0
- package/dist/react/strings.d.ts +98 -0
- package/dist/react/useBeforeUnload.d.ts +5 -0
- package/dist/react/useVideoRecorder.d.ts +24 -0
- package/dist/react-BGJ7Szvq.js +216 -0
- package/dist/react-BGJ7Szvq.js.map +1 -0
- package/dist/react-BMxM8TWJ.js +192 -0
- package/dist/react-BMxM8TWJ.js.map +1 -0
- package/dist/react-BVzcquey.js +457 -0
- package/dist/react-BVzcquey.js.map +1 -0
- package/dist/react-BrCGR7Ca.js +2208 -0
- package/dist/react-BrCGR7Ca.js.map +1 -0
- package/dist/react-Bujo1aK5.js +334 -0
- package/dist/react-Bujo1aK5.js.map +1 -0
- package/dist/react-CRTg4gz8.js +367 -0
- package/dist/react-CRTg4gz8.js.map +1 -0
- package/dist/react-GXf8sbzf.js +311 -0
- package/dist/react-GXf8sbzf.js.map +1 -0
- package/dist/react-lp7yfM94.js +371 -0
- package/dist/react-lp7yfM94.js.map +1 -0
- package/dist/sapia-chatbot.css +3 -0
- package/dist/sapia.d.ts +4 -0
- package/dist/ui/chat/ChatBubble/ChatBubble.d.ts +47 -0
- package/dist/ui/chat/ChatLog/ChatLog.d.ts +33 -0
- package/dist/ui/chat/TypingIndicator/TypingIndicator.d.ts +17 -0
- package/dist/ui/chat/types.d.ts +71 -0
- package/dist/ui/constants.d.ts +2 -0
- package/dist/ui/inputs/DropdownInput/DropdownInput.d.ts +18 -0
- package/dist/ui/inputs/OptionList/OptionList.d.ts +18 -0
- package/dist/ui/inputs/PhoneAnswerInput/PhoneAnswerInput.d.ts +19 -0
- package/dist/ui/inputs/SliderInput/SliderInput.d.ts +19 -0
- package/dist/ui/inputs/TextAnswerInput/TextAnswerInput.d.ts +32 -0
- package/dist/ui/inputs/VideoRecorder/VideoRecorder.d.ts +54 -0
- package/dist/ui/media/EmbeddedVideo/EmbeddedVideo.d.ts +11 -0
- package/dist/ui/media/EmbeddedVideo/EmbeddedVideoPlayer.d.ts +16 -0
- package/dist/ui/media/EmbeddedVideo/VimeoPlayer.d.ts +20 -0
- package/dist/ui/media/UploadProgress/UploadProgress.d.ts +7 -0
- package/dist/ui/media/VideoPlayer/VideoPlayer.d.ts +13 -0
- package/dist/ui/primitives/Button/Button.d.ts +6 -0
- package/dist/ui/primitives/Dialog/Dialog.d.ts +16 -0
- package/dist/ui/richText.d.ts +6 -0
- package/dist/ui/shell/AccessVerificationForm/AccessVerificationForm.d.ts +21 -0
- package/dist/ui/shell/CopyLinkButton/CopyLinkButton.d.ts +11 -0
- package/dist/ui/shell/DoneScreen/DoneScreen.d.ts +15 -0
- package/dist/ui/shell/Header/Header.d.ts +13 -0
- package/dist/ui/shell/PreparingScreen/PreparingScreen.d.ts +9 -0
- package/dist/ui/shell/ProgressBar/ProgressBar.d.ts +9 -0
- package/dist/ui/shell/WelcomeScreen/WelcomeScreen.d.ts +22 -0
- package/dist/ui/shell/WidgetRoot/WidgetRoot.d.ts +12 -0
- package/dist-umd/sapia-chatbot.umd.js +3655 -0
- package/dist-umd/sapia-chatbot.umd.js.map +1 -0
- package/package.json +94 -0
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
export declare enum RuleName {
|
|
2
|
+
MAX_TEXT_LENGTH = "maxTextLength",
|
|
3
|
+
MIN_TEXT_LENGTH = "minTextLength",
|
|
4
|
+
RECOMMENDED_TEXT_LENGTH = "recommendedTextLength",
|
|
5
|
+
MAX_VOICE_SECONDS = "maxVoiceSeconds",
|
|
6
|
+
MIN_VOICE_SECONDS = "minVoiceSeconds",
|
|
7
|
+
RECOMMENDED_VOICE_SECONDS = "recommendedVoiceSeconds"
|
|
8
|
+
}
|
|
9
|
+
export declare enum MessageSender {
|
|
10
|
+
AGENT = "AGENT",
|
|
11
|
+
CANDIDATE = "CANDIDATE"
|
|
12
|
+
}
|
|
13
|
+
export declare enum QuestionType {
|
|
14
|
+
HINT = "HINT",
|
|
15
|
+
FTQ = "FTQ",
|
|
16
|
+
MCQ = "MCQ",
|
|
17
|
+
VOICE = "VOICE",
|
|
18
|
+
VIDEO = "VIDEO",
|
|
19
|
+
SLIDER = "SLIDER",
|
|
20
|
+
DROPDOWN = "DROPDOWN",
|
|
21
|
+
BGQ = "BUTTON_GROUP_QUESTION"
|
|
22
|
+
}
|
|
23
|
+
export declare enum ContentType {
|
|
24
|
+
TEXT = "TEXT",
|
|
25
|
+
VOICE = "VOICE",
|
|
26
|
+
VIDEO = "VIDEO",
|
|
27
|
+
SLIDER = "SLIDER"
|
|
28
|
+
}
|
|
29
|
+
export declare enum PHService {
|
|
30
|
+
GENERAL_PY = "GENERAL_PY",
|
|
31
|
+
CUSTOMER_SATISFACTION = "CUSTOMER_SATISFACTION",
|
|
32
|
+
PII = "PII",
|
|
33
|
+
SENSITIVE = "SENSITIVE",
|
|
34
|
+
DISPLAY_IN_TI = "DISPLAY_IN_TI",
|
|
35
|
+
HEXACO_PERSONALITY_TEST = "HEXACO_PERSONALITY_TEST"
|
|
36
|
+
}
|
|
37
|
+
/** Identified via question tag { name: "PII_TYPE", value: <PiiQuestionType> } */
|
|
38
|
+
export declare enum PiiQuestionType {
|
|
39
|
+
FULL_NAME = "fullName",
|
|
40
|
+
FIRST_NAME = "first_name",
|
|
41
|
+
LAST_NAME = "last_name",
|
|
42
|
+
EMAIL = "email",
|
|
43
|
+
PHONE_NUMBER = "phoneNumber",
|
|
44
|
+
LOCATION = "location"
|
|
45
|
+
}
|
|
46
|
+
/** Identified via question tag { name: "VIDEO_TYPE", value: <VideoQuestionType> } */
|
|
47
|
+
export declare enum VideoQuestionType {
|
|
48
|
+
TEST_CAMERA = "test_camera"
|
|
49
|
+
}
|
|
50
|
+
export declare enum ButtonType {
|
|
51
|
+
PRIMARY = "PRIMARY",
|
|
52
|
+
SECONDARY = "SECONDARY",
|
|
53
|
+
DEFAULT = "DEFAULT"
|
|
54
|
+
}
|
|
55
|
+
export declare enum AssessmentStatus {
|
|
56
|
+
FI_ATS_ASSESSMENT_ORDER_COMPLETED = "FI_ATS_ASSESSMENT_ORDER_COMPLETED",
|
|
57
|
+
FI_ASSESSMENT_STARTED = "FI_ASSESSMENT_STARTED",
|
|
58
|
+
FI_ASSESSMENT_PII_SAVED = "FI_ASSESSMENT_PII_SAVED",
|
|
59
|
+
FI_ASSESSMENT_PII_COMPLETED = "FI_ASSESSMENT_PII_COMPLETED",
|
|
60
|
+
FI_ASSESSMENT_INPROGRESS = "FI_ASSESSMENT_INPROGRESS",
|
|
61
|
+
FI_ASSESSMENT_COMPLETED = "FI_ASSESSMENT_COMPLETED",
|
|
62
|
+
FI_ASSESSMENT_ENDED = "FI_ASSESSMENT_ENDED",
|
|
63
|
+
FI_ASSESSMENT_DROPPED_OUT = "FI_ASSESSMENT_DROPPED_OUT",
|
|
64
|
+
FI_PREDICTION_STARTED = "FI_PREDICTION_STARTED",
|
|
65
|
+
FI_PREDICTION_COMPLETED = "FI_PREDICTION_COMPLETED",
|
|
66
|
+
FI_ASSESSMENT_DUPLICATED = "FI_ASSESSMENT_DUPLICATED"
|
|
67
|
+
}
|
|
68
|
+
export type MessageIdentifier = string;
|
|
69
|
+
export type Trigger = {
|
|
70
|
+
action: string;
|
|
71
|
+
};
|
|
72
|
+
export type Style = {
|
|
73
|
+
buttonType: ButtonType;
|
|
74
|
+
};
|
|
75
|
+
export type Content = {
|
|
76
|
+
value: string;
|
|
77
|
+
text: string;
|
|
78
|
+
id: string;
|
|
79
|
+
};
|
|
80
|
+
export type ButtonGroupContent = Content & {
|
|
81
|
+
triggers: Trigger[];
|
|
82
|
+
style: Style;
|
|
83
|
+
};
|
|
84
|
+
export type AnswerContent = {
|
|
85
|
+
text: string;
|
|
86
|
+
value: string;
|
|
87
|
+
/** Sanitized rich-text HTML for re-display; `text` stays the plain-text source for scoring. */
|
|
88
|
+
html?: string;
|
|
89
|
+
triggers?: Trigger[];
|
|
90
|
+
style?: Style;
|
|
91
|
+
};
|
|
92
|
+
export type Tag = {
|
|
93
|
+
name: string;
|
|
94
|
+
value: string;
|
|
95
|
+
};
|
|
96
|
+
export type QuestionRule = {
|
|
97
|
+
name: RuleName;
|
|
98
|
+
type: string;
|
|
99
|
+
value: number | string;
|
|
100
|
+
};
|
|
101
|
+
export type BubbleContent = {
|
|
102
|
+
value: string;
|
|
103
|
+
types: ContentType[];
|
|
104
|
+
/** BE A2UI-style render component (streaming STATE_SNAPSHOT / loaded chatLogs only). */
|
|
105
|
+
component?: 'Text' | 'VoicePlayer' | 'VideoPlayer' | 'Slider';
|
|
106
|
+
};
|
|
107
|
+
export type MCQQuestionOption = {
|
|
108
|
+
id: string;
|
|
109
|
+
text: string;
|
|
110
|
+
value: string;
|
|
111
|
+
};
|
|
112
|
+
export type DropdownOption = MCQQuestionOption;
|
|
113
|
+
export type BGQButton = MCQQuestionOption & {
|
|
114
|
+
triggers: Trigger[];
|
|
115
|
+
style: Style;
|
|
116
|
+
};
|
|
117
|
+
export type Question = {
|
|
118
|
+
masterId?: string;
|
|
119
|
+
types: QuestionType[];
|
|
120
|
+
rules?: QuestionRule[];
|
|
121
|
+
contents: BubbleContent[];
|
|
122
|
+
options?: MCQQuestionOption[] | BGQButton[];
|
|
123
|
+
usageWhitelist?: PHService[];
|
|
124
|
+
_id: string;
|
|
125
|
+
tags?: Tag[];
|
|
126
|
+
/** BE message kind (streaming STATE_SNAPSHOT / loaded chatLogs only); "Hint" | "Question". */
|
|
127
|
+
kind?: 'Hint' | 'Question';
|
|
128
|
+
};
|
|
129
|
+
export type Answer = {
|
|
130
|
+
_id: string;
|
|
131
|
+
question: Question;
|
|
132
|
+
text: string;
|
|
133
|
+
value: string;
|
|
134
|
+
};
|
|
135
|
+
export interface Message<T> {
|
|
136
|
+
id: string;
|
|
137
|
+
sender: MessageSender;
|
|
138
|
+
messageIdentifier?: MessageIdentifier;
|
|
139
|
+
data: T;
|
|
140
|
+
}
|
|
141
|
+
export type CandidateResponse = Message<Answer>;
|
|
142
|
+
export type AgentResponse = Message<Question>;
|
|
143
|
+
export type CandidateResponseInput = {
|
|
144
|
+
userAgent: string;
|
|
145
|
+
questionId: string;
|
|
146
|
+
answer?: AnswerContent;
|
|
147
|
+
};
|
|
148
|
+
export type EditCandidateResponseInput = Required<Omit<CandidateResponseInput, 'userAgent'>>;
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { Branding } from './branding';
|
|
2
|
+
import { AgentResponse, AssessmentStatus, BGQButton, CandidateResponse, ContentType, MCQQuestionOption, PHService, QuestionRule, QuestionType, Tag } from './messages';
|
|
3
|
+
/** Session token returned by /start/ats; sent as a dynamic header on subsequent calls. */
|
|
4
|
+
export type FiToken = {
|
|
5
|
+
name: string;
|
|
6
|
+
value: string;
|
|
7
|
+
};
|
|
8
|
+
export type StartAtsResponse = {
|
|
9
|
+
assessmentId: string;
|
|
10
|
+
chatLogs: (CandidateResponse | AgentResponse)[];
|
|
11
|
+
branding?: Branding;
|
|
12
|
+
hasVideoQuestion?: boolean;
|
|
13
|
+
assessmentStatus: AssessmentStatus;
|
|
14
|
+
isCohortClosed?: boolean;
|
|
15
|
+
cohortIsArchivedMessage?: AgentResponse;
|
|
16
|
+
numOfNormalQuestion: number;
|
|
17
|
+
numOfNormalAnswer: number;
|
|
18
|
+
fiToken: FiToken;
|
|
19
|
+
language: string;
|
|
20
|
+
agcDetectionAttempt: number;
|
|
21
|
+
allowNextAgcDetection: boolean;
|
|
22
|
+
isTermsAndConditionsAccepted: boolean;
|
|
23
|
+
candidateCountryCode?: string;
|
|
24
|
+
assessmentIsReusedMessage?: AgentResponse;
|
|
25
|
+
/** Candidate display name for the pre-interview welcome (optional; absent → generic greeting). */
|
|
26
|
+
candidateName?: string;
|
|
27
|
+
/** Role/position title for the welcome + header (optional; falls back to branding.title). */
|
|
28
|
+
roleTitle?: string;
|
|
29
|
+
};
|
|
30
|
+
export type NextResponse = {
|
|
31
|
+
nextResponse: AgentResponse;
|
|
32
|
+
candidateResponse?: CandidateResponse;
|
|
33
|
+
assessmentStatus: AssessmentStatus;
|
|
34
|
+
duplicatedWithAssessmentLink?: string;
|
|
35
|
+
cohortIsArchivedMessage?: AgentResponse;
|
|
36
|
+
assessmentIsReusedMessage?: AgentResponse;
|
|
37
|
+
numOfNormalAnswer: number;
|
|
38
|
+
isTermsAndConditionsAccepted: boolean;
|
|
39
|
+
fiToken?: FiToken;
|
|
40
|
+
};
|
|
41
|
+
export type EditAnswerResponse = {
|
|
42
|
+
updatedCandidateResponse: CandidateResponse;
|
|
43
|
+
cohortIsArchivedMessage?: AgentResponse;
|
|
44
|
+
};
|
|
45
|
+
export type TranslationResponse = Record<string, string>;
|
|
46
|
+
/** POST /:assessmentId/extract-human-name — extracts name parts from free text. */
|
|
47
|
+
export type ExtractHumanNameType = 'firstName' | 'lastName' | 'fullName';
|
|
48
|
+
export type ExtractHumanNameResponse = {
|
|
49
|
+
firstName?: string;
|
|
50
|
+
lastName?: string;
|
|
51
|
+
fullName?: string;
|
|
52
|
+
};
|
|
53
|
+
/** GET video-upload-signed-url / video-access-signed-url — S3 signed URL + filename. */
|
|
54
|
+
export type VideoSignedUrlResponse = {
|
|
55
|
+
url: string;
|
|
56
|
+
videoFileName: string;
|
|
57
|
+
};
|
|
58
|
+
/** GET access-management — whether an email gate is required before the interview. */
|
|
59
|
+
export type AccessManagementResponse = {
|
|
60
|
+
shouldAuthenticate: boolean;
|
|
61
|
+
emailHint?: string;
|
|
62
|
+
language?: string;
|
|
63
|
+
};
|
|
64
|
+
/** POST verify-access — whether the candidate email matches. */
|
|
65
|
+
export type VerifyAccessResponse = {
|
|
66
|
+
allowToAccess: boolean;
|
|
67
|
+
};
|
|
68
|
+
/** POST detect-agc — automated-content detection on submit. */
|
|
69
|
+
export type DetectAgcResponse = {
|
|
70
|
+
attempt: number;
|
|
71
|
+
isAgc: boolean;
|
|
72
|
+
allowNextAgcDetection: boolean;
|
|
73
|
+
};
|
|
74
|
+
export type AgUiEventType = 'RUN_STARTED' | 'STATE_SNAPSHOT' | 'TEXT_MESSAGE_START' | 'TEXT_MESSAGE_CONTENT' | 'TEXT_MESSAGE_END' | 'CUSTOM' | 'RUN_FINISHED' | 'RUN_ERROR';
|
|
75
|
+
/** A2UI-style render component for a content bubble (STATE_SNAPSHOT contents[].component). */
|
|
76
|
+
export type ContentComponentName = 'Text' | 'VoicePlayer' | 'VideoPlayer' | 'Slider';
|
|
77
|
+
/** STATE_SNAPSHOT.snapshot.question — same data as our Question, but `types` is `questionTypes`. */
|
|
78
|
+
export type SnapshotQuestion = {
|
|
79
|
+
_id: string;
|
|
80
|
+
masterId?: string;
|
|
81
|
+
/** Bubble template: "Hint" (agent context, unanswerable) vs "Question". */
|
|
82
|
+
kind?: 'Hint' | 'Question';
|
|
83
|
+
/** Answer-input component (ignored — response stays questionType-driven). */
|
|
84
|
+
component?: string | null;
|
|
85
|
+
questionTypes: QuestionType[];
|
|
86
|
+
options?: MCQQuestionOption[] | BGQButton[];
|
|
87
|
+
rules?: QuestionRule[];
|
|
88
|
+
tags?: Tag[];
|
|
89
|
+
usageWhitelist?: PHService[];
|
|
90
|
+
contents?: {
|
|
91
|
+
component: ContentComponentName;
|
|
92
|
+
types: ContentType[];
|
|
93
|
+
}[];
|
|
94
|
+
};
|
|
95
|
+
/** One parsed AG-UI frame (only the fields our client reads are typed). */
|
|
96
|
+
export type AgUiFrame = {
|
|
97
|
+
type: AgUiEventType;
|
|
98
|
+
snapshot?: {
|
|
99
|
+
question?: SnapshotQuestion;
|
|
100
|
+
};
|
|
101
|
+
/** TEXT_MESSAGE_* message id, shape "<baseId>:<contentIndex>"; segments bundled messages. */
|
|
102
|
+
messageId?: string;
|
|
103
|
+
delta?: string;
|
|
104
|
+
result?: NextResponse;
|
|
105
|
+
message?: string;
|
|
106
|
+
};
|
package/dist/api.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { _ as e, a as t, c as n, d as r, f as i, g as a, h as o, i as s, l as c, m as l, n as u, o as d, p as f, r as p, s as m, t as h, u as g } from "./messages-C4jqrtSG.js";
|
|
2
|
+
export { r as API_ORIGIN_BY_ENV, h as AssessmentStatus, u as ButtonType, i as CHATBOT_API_PATH, g as ChatbotApiClient, p as ContentType, f as DEFAULT_LOCAL_API_ORIGIN, l as ENVIRONMENTS, s as MessageSender, t as PHService, d as PiiQuestionType, m as QuestionType, o as REGIONS, n as RuleName, c as VideoQuestionType, a as buildChatbotBaseUrl, e as resolveApiOrigin };
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
//#region \0@oxc-project+runtime@0.133.0/helpers/esm/checkPrivateRedeclaration.js
|
|
2
|
+
function e(e, t) {
|
|
3
|
+
if (t.has(e)) throw TypeError("Cannot initialize the same private elements twice on an object");
|
|
4
|
+
}
|
|
5
|
+
//#endregion
|
|
6
|
+
//#region \0@oxc-project+runtime@0.133.0/helpers/esm/classPrivateMethodInitSpec.js
|
|
7
|
+
function t(t, n) {
|
|
8
|
+
e(t, n), n.add(t);
|
|
9
|
+
}
|
|
10
|
+
//#endregion
|
|
11
|
+
//#region \0@oxc-project+runtime@0.133.0/helpers/esm/classPrivateFieldInitSpec.js
|
|
12
|
+
function n(t, n, r) {
|
|
13
|
+
e(t, n), n.set(t, r);
|
|
14
|
+
}
|
|
15
|
+
//#endregion
|
|
16
|
+
//#region \0@oxc-project+runtime@0.133.0/helpers/esm/assertClassBrand.js
|
|
17
|
+
function r(e, t, n) {
|
|
18
|
+
if (typeof e == "function" ? e === t : e.has(t)) return arguments.length < 3 ? t : n;
|
|
19
|
+
throw TypeError("Private element is not present on this object");
|
|
20
|
+
}
|
|
21
|
+
//#endregion
|
|
22
|
+
//#region \0@oxc-project+runtime@0.133.0/helpers/esm/classPrivateFieldGet2.js
|
|
23
|
+
function i(e, t) {
|
|
24
|
+
return e.get(r(e, t));
|
|
25
|
+
}
|
|
26
|
+
//#endregion
|
|
27
|
+
//#region \0@oxc-project+runtime@0.133.0/helpers/esm/classPrivateFieldSet2.js
|
|
28
|
+
function a(e, t, n) {
|
|
29
|
+
return e.set(r(e, t), n), n;
|
|
30
|
+
}
|
|
31
|
+
//#endregion
|
|
32
|
+
export { t as a, n as i, i as n, r, a as t };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { PiiQuestionType, VideoQuestionType, AgentResponse, CandidateResponse, Tag } from '../../api/types/messages';
|
|
2
|
+
import { MessageBubble } from './types';
|
|
3
|
+
export declare const piiQuestionTypeFromQuestionTags: (tags?: Tag[]) => PiiQuestionType | undefined;
|
|
4
|
+
export declare const videoQuestionTypeFromQuestionTags: (tags?: Tag[]) => VideoQuestionType | undefined;
|
|
5
|
+
export declare const convertRawCandidateResponseToMessageBubble: (response: CandidateResponse) => MessageBubble;
|
|
6
|
+
export declare const convertRawAgentResponseToMessageBubble: (response: AgentResponse, hasNext?: boolean) => MessageBubble;
|
|
7
|
+
export declare const convertRawResponseToMessageBubble: (response: CandidateResponse | AgentResponse, hasNext?: boolean) => MessageBubble | undefined;
|
|
8
|
+
/**
|
|
9
|
+
* For option/slider questions the candidate "answers inline", so a synthetic
|
|
10
|
+
* candidate bubble is appended right after the agent question bubble.
|
|
11
|
+
*/
|
|
12
|
+
export declare const addCandidateResponseMessageBubble: (response: AgentResponse) => MessageBubble | undefined;
|
|
13
|
+
export declare const convertMessageBubbles: (chatLogs: (CandidateResponse | AgentResponse)[]) => MessageBubble[];
|
|
14
|
+
/** Only load the next message when the answered question is the last agent bubble. */
|
|
15
|
+
export declare const checkShouldLoadNext: ({ messageBubbleList, questionId, }: {
|
|
16
|
+
messageBubbleList: MessageBubble[];
|
|
17
|
+
questionId: string;
|
|
18
|
+
}) => boolean;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { AnswerContent, ContentType, MessageIdentifier, MessageSender, PHService, PiiQuestionType, QuestionRule, QuestionType, Style, Tag, Trigger, VideoQuestionType } from '../../api/types/messages';
|
|
2
|
+
export declare enum BubbleStatus {
|
|
3
|
+
ANSWERED = "ANSWERED",
|
|
4
|
+
ANSWERING = "ANSWERING",
|
|
5
|
+
EDITING = "EDITING",
|
|
6
|
+
PENDING = "PENDING",
|
|
7
|
+
FAILED = "FAILED"
|
|
8
|
+
}
|
|
9
|
+
/** A bubble content entry; for MCQ/DROPDOWN options and BGQ buttons it carries
|
|
10
|
+
* the selectable option (BGQ adds triggers/style, echoed back in the answer). */
|
|
11
|
+
export type OptionContent = {
|
|
12
|
+
id: string;
|
|
13
|
+
text: string;
|
|
14
|
+
value: string;
|
|
15
|
+
triggers?: Trigger[];
|
|
16
|
+
style?: Style;
|
|
17
|
+
};
|
|
18
|
+
/** BE A2UI-style content render component (STATE_SNAPSHOT / loaded chatLogs contents[].component). */
|
|
19
|
+
export type ContentComponent = 'Text' | 'VoicePlayer' | 'VideoPlayer' | 'Slider';
|
|
20
|
+
/** BE message kind (STATE_SNAPSHOT / loaded chatLogs question.kind). */
|
|
21
|
+
export type MessageKind = 'Hint' | 'Question';
|
|
22
|
+
export type MessageItem = {
|
|
23
|
+
id: string;
|
|
24
|
+
types: ContentType[];
|
|
25
|
+
contents: OptionContent[];
|
|
26
|
+
/** BE-provided render component for this content; falls back to `types` when absent. */
|
|
27
|
+
component?: ContentComponent;
|
|
28
|
+
};
|
|
29
|
+
export type MessageBubbleData = {
|
|
30
|
+
messageItems: MessageItem[];
|
|
31
|
+
answer?: AnswerContent | null;
|
|
32
|
+
rules?: QuestionRule[];
|
|
33
|
+
tags?: Tag[];
|
|
34
|
+
};
|
|
35
|
+
export type MessageBubble = {
|
|
36
|
+
status: BubbleStatus;
|
|
37
|
+
sender: MessageSender;
|
|
38
|
+
messageIdentifier?: MessageIdentifier;
|
|
39
|
+
id: string;
|
|
40
|
+
types: QuestionType[];
|
|
41
|
+
usageWhitelist?: PHService[];
|
|
42
|
+
questionId: string;
|
|
43
|
+
data: MessageBubbleData;
|
|
44
|
+
masterId?: string;
|
|
45
|
+
/** BE-provided message kind; falls back to `types` when absent. */
|
|
46
|
+
messageKind?: MessageKind;
|
|
47
|
+
piiQuestionType?: PiiQuestionType;
|
|
48
|
+
videoQuestionType?: VideoQuestionType;
|
|
49
|
+
/** Video answer in flight: upload progress 0–1 (PENDING video bubbles). */
|
|
50
|
+
uploadProgress?: number;
|
|
51
|
+
/** Locally-recorded blob for immediate playback before/without a signed URL. */
|
|
52
|
+
videoBlob?: Blob;
|
|
53
|
+
/** Recorded file extension (webm/mp4), needed to fetch the playback access URL. */
|
|
54
|
+
videoExtension?: string;
|
|
55
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/** Streaming reveal cadence: ms per char-step (React passes 0 under prefers-reduced-motion). */
|
|
2
|
+
export declare const STREAM_REVEAL_MS = 12;
|
|
3
|
+
/** Chars revealed per reveal tick — bounds store writes to ~60/s at the default cadence. */
|
|
4
|
+
export declare const STREAM_CHARS_PER_TICK = 2;
|
|
5
|
+
/** Id prefix for the transient live agent bubble shown while a message streams in. */
|
|
6
|
+
export declare const STREAM_BUBBLE_ID_PREFIX = "stream-live";
|
|
7
|
+
export declare const QUESTION_TAG_PII_TYPE = "PII_TYPE";
|
|
8
|
+
export declare const QUESTION_TAG_VIDEO_TYPE = "VIDEO_TYPE";
|
|
9
|
+
/** Experience-rating slider range and starting position (legacy defaultSliderValue). */
|
|
10
|
+
export declare const SLIDER_MIN = 1;
|
|
11
|
+
export declare const SLIDER_MAX = 10;
|
|
12
|
+
export declare const SLIDER_DEFAULT_VALUE = 8;
|
|
13
|
+
/** Default video answer length when the question carries no max-seconds rule. */
|
|
14
|
+
export declare const MAX_VIDEO_SECONDS_DEFAULT = 60;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export declare const CHATBOT_EVENTS: {
|
|
2
|
+
readonly ASSESSMENT_STARTED: "assessment:started";
|
|
3
|
+
readonly ASSESSMENT_ENDED: "assessment:ended";
|
|
4
|
+
readonly ASSESSMENT_DUPLICATED: "assessment:duplicated";
|
|
5
|
+
readonly ANSWER_SAVED: "answer:saved";
|
|
6
|
+
readonly ANSWER_EDITED: "answer:edited";
|
|
7
|
+
readonly ERROR: "error";
|
|
8
|
+
readonly LOG: "log";
|
|
9
|
+
};
|
|
10
|
+
export type ChatbotEventName = (typeof CHATBOT_EVENTS)[keyof typeof CHATBOT_EVENTS];
|
|
11
|
+
export type ChatbotEventMap = {
|
|
12
|
+
[CHATBOT_EVENTS.ASSESSMENT_STARTED]: {
|
|
13
|
+
assessmentId: string;
|
|
14
|
+
};
|
|
15
|
+
[CHATBOT_EVENTS.ASSESSMENT_ENDED]: {
|
|
16
|
+
assessmentId: string;
|
|
17
|
+
};
|
|
18
|
+
[CHATBOT_EVENTS.ASSESSMENT_DUPLICATED]: {
|
|
19
|
+
assessmentId: string;
|
|
20
|
+
duplicatedWithAssessmentLink?: string;
|
|
21
|
+
};
|
|
22
|
+
[CHATBOT_EVENTS.ANSWER_SAVED]: {
|
|
23
|
+
questionId: string;
|
|
24
|
+
};
|
|
25
|
+
[CHATBOT_EVENTS.ANSWER_EDITED]: {
|
|
26
|
+
questionId: string;
|
|
27
|
+
};
|
|
28
|
+
[CHATBOT_EVENTS.ERROR]: {
|
|
29
|
+
type: string;
|
|
30
|
+
message: string;
|
|
31
|
+
};
|
|
32
|
+
[CHATBOT_EVENTS.LOG]: {
|
|
33
|
+
type: string;
|
|
34
|
+
message: string;
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
type Handler<E extends ChatbotEventName> = (payload: ChatbotEventMap[E]) => void;
|
|
38
|
+
export declare class ChatbotEventEmitter {
|
|
39
|
+
private handlers;
|
|
40
|
+
on<E extends ChatbotEventName>(event: E, handler: Handler<E>): () => void;
|
|
41
|
+
off<E extends ChatbotEventName>(event: E, handler: Handler<E>): void;
|
|
42
|
+
emit<E extends ChatbotEventName>(event: E, payload: ChatbotEventMap[E]): void;
|
|
43
|
+
}
|
|
44
|
+
export {};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare const SUPPORTED_LANGUAGES: readonly ["en-GB", "en-US", "fr", "es", "de", "fi", "da", "nl", "it", "sv", "nb", "pl", "ar"];
|
|
2
|
+
export type SupportedLanguage = (typeof SUPPORTED_LANGUAGES)[number];
|
|
3
|
+
export declare const FALLBACK_LANGUAGE: SupportedLanguage;
|
|
4
|
+
/** Right-to-left languages (base code). */
|
|
5
|
+
export declare const RTL_LANGUAGES: readonly ["ar"];
|
|
6
|
+
/** Map a browser language tag to a supported language (any en-* → en-US). */
|
|
7
|
+
export declare const normalizeLanguage: (browserLanguage?: string) => SupportedLanguage;
|
|
8
|
+
/** Resolve the interview language: explicit override, else the browser default. */
|
|
9
|
+
export declare const resolveLanguage: (override?: string, browserLanguage?: string) => SupportedLanguage;
|
|
10
|
+
export declare const isRtlLanguage: (language: string) => boolean;
|
|
11
|
+
export declare const directionForLanguage: (language: string) => "rtl" | "ltr";
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export type TranslationFile = Record<string, string>;
|
|
2
|
+
/** Replaces {{name}} placeholders with params; missing params become ''. */
|
|
3
|
+
export declare const interpolate: (template: string, params?: Record<string, string | number>) => string;
|
|
4
|
+
export type TranslateOptions = {
|
|
5
|
+
count?: number;
|
|
6
|
+
} & Record<string, string | number>;
|
|
7
|
+
export type Translator = (key: string, options?: TranslateOptions) => string;
|
|
8
|
+
/**
|
|
9
|
+
* Builds a translator that looks up the fetched file, then the bundled
|
|
10
|
+
* fallback, then returns the key itself (so missing keys are visible, never
|
|
11
|
+
* throw — unlike the legacy translator which threw on missing keys).
|
|
12
|
+
*/
|
|
13
|
+
export declare const createTranslator: (file: TranslationFile | undefined, fallback: TranslationFile) => Translator;
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import { ChatbotApiClient } from '../api/client';
|
|
2
|
+
import { PiiErrorKey } from './validation/pii';
|
|
3
|
+
import { ChatbotEventEmitter } from './events';
|
|
4
|
+
import { InterviewStore } from './store';
|
|
5
|
+
export declare const ERROR_TYPE_START_FAILED = "FI_START_ASSESSMENT_FAILED";
|
|
6
|
+
export declare const ERROR_TYPE_LOAD_NEXT_FAILED = "FI_LOAD_NEXT_FAILED";
|
|
7
|
+
export declare const ERROR_TYPE_EXTRACT_NAME_FAILED = "FI_EXTRACT_HUMAN_NAME_FAILED";
|
|
8
|
+
export declare const ERROR_TYPE_EDIT_ANSWER_FAILED = "FI_EDIT_ANSWER_FAILED";
|
|
9
|
+
export declare const ERROR_TYPE_UPLOAD_VIDEO_FAILED = "FI_SUBMIT_VIDEO_ANSWER_FAILED";
|
|
10
|
+
export declare const ERROR_TYPE_TRANSLATION_FAILED = "FI_GET_TRANSLATION_FAILED";
|
|
11
|
+
export declare const ERROR_TYPE_VERIFY_ACCESS_FAILED = "FI_VERIFY_ACCESS_FAILED";
|
|
12
|
+
export declare const ERROR_TYPE_DETECT_AGC_FAILED = "FI_DETECT_AGC_FAILED";
|
|
13
|
+
export declare const LOG_TYPE_INVALID_PHONE_NUMBER = "INVALID_PHONE_NUMBER";
|
|
14
|
+
export declare const LOG_TYPE_INVALID_PASTE_ANSWER_ACTION = "INVALID_PASTE_ANSWER_ACTION";
|
|
15
|
+
/** Result of a validated PII submission (drives the UI error/confirm modals). */
|
|
16
|
+
export type PiiSubmitOutcome = {
|
|
17
|
+
status: 'submitted';
|
|
18
|
+
} | {
|
|
19
|
+
status: 'invalid';
|
|
20
|
+
errorKey: PiiErrorKey;
|
|
21
|
+
} | {
|
|
22
|
+
status: 'confirm-name';
|
|
23
|
+
suggested: string;
|
|
24
|
+
original: string;
|
|
25
|
+
};
|
|
26
|
+
export type InterviewEngineDeps = {
|
|
27
|
+
client: ChatbotApiClient;
|
|
28
|
+
store: InterviewStore;
|
|
29
|
+
emitter: ChatbotEventEmitter;
|
|
30
|
+
assessmentId: string;
|
|
31
|
+
/** Resolved interview language; translations are fetched for it on start. */
|
|
32
|
+
language?: string;
|
|
33
|
+
/** Injectable for tests; defaults to the browser UA. */
|
|
34
|
+
userAgent?: string;
|
|
35
|
+
/** Show the pre-interview welcome gate on a fresh start (off by default). */
|
|
36
|
+
welcomeGate?: boolean;
|
|
37
|
+
/** Per-char reveal cadence (ms) while streaming; 0 reveals each chunk wholesale (reduced-motion). */
|
|
38
|
+
streamRevealMs?: number;
|
|
39
|
+
};
|
|
40
|
+
export declare class InterviewEngine {
|
|
41
|
+
private readonly client;
|
|
42
|
+
private readonly store;
|
|
43
|
+
private readonly emitter;
|
|
44
|
+
private readonly assessmentId;
|
|
45
|
+
private readonly userAgent;
|
|
46
|
+
private readonly language;
|
|
47
|
+
private readonly welcomeGate;
|
|
48
|
+
private readonly streamRevealMs;
|
|
49
|
+
/** Aborts the in-flight stream when a new load starts. */
|
|
50
|
+
private streamAbort?;
|
|
51
|
+
/** Monotonic counter for unique live-bubble ids (avoids Date.now in core). */
|
|
52
|
+
private streamSeq;
|
|
53
|
+
private lastFailedInput?;
|
|
54
|
+
/** Bubble whose answer submission is in flight (optimistic FTQ or inline option bubble). */
|
|
55
|
+
private pendingBubbleId?;
|
|
56
|
+
/** Retained recorded video for retry after an upload failure. */
|
|
57
|
+
private lastVideoAnswer?;
|
|
58
|
+
/** Option id held back pending the AGC warning resolution. */
|
|
59
|
+
private pendingAgcOptionId?;
|
|
60
|
+
constructor(deps: InterviewEngineDeps);
|
|
61
|
+
/** Fetch the translation file; on failure the bundled fallback is used. */
|
|
62
|
+
private loadTranslations;
|
|
63
|
+
/**
|
|
64
|
+
* Entry point: gate the interview on email access verification when the
|
|
65
|
+
* assessment requires it (legacy AccessVerification), else start directly.
|
|
66
|
+
* A still-valid cached email is re-verified silently.
|
|
67
|
+
*/
|
|
68
|
+
begin(): Promise<void>;
|
|
69
|
+
/** Verify a candidate email against the gate; on success cache it and start. */
|
|
70
|
+
verifyAccessEmail(email: string): Promise<void>;
|
|
71
|
+
start(): Promise<void>;
|
|
72
|
+
/** Raw chatLogs captured at start, replayed by firstLoad once the welcome gate clears. */
|
|
73
|
+
private welcomeChatLogs;
|
|
74
|
+
/**
|
|
75
|
+
* Candidate clicked "Next" on the welcome screen — reveal the chat and play
|
|
76
|
+
* the agent's opening message(s). No-op unless we're holding at the gate.
|
|
77
|
+
*/
|
|
78
|
+
confirmWelcome(): Promise<void>;
|
|
79
|
+
/**
|
|
80
|
+
* Ported from legacy firstLoadMessageBasedOnChatLogs: empty history → fetch the
|
|
81
|
+
* first message; history ending in a HINT (either the agent's question or the
|
|
82
|
+
* candidate's ack of it) → acknowledge it to fetch the next one. On a finished
|
|
83
|
+
* assessment the re-ack returns no nextResponse, which ends the interview.
|
|
84
|
+
*/
|
|
85
|
+
private firstLoad;
|
|
86
|
+
/**
|
|
87
|
+
* Submit a free-text answer to the current (last agent) question. `html` is
|
|
88
|
+
* the optional sanitized rich-text rendering; `text` remains the plain-text
|
|
89
|
+
* source the backend scores against.
|
|
90
|
+
*/
|
|
91
|
+
submitTextAnswer(text: string, html?: string): Promise<void>;
|
|
92
|
+
/** Validate then submit an email PII answer (legacy FTQResponse email branch). */
|
|
93
|
+
submitEmailAnswer(text: string): Promise<PiiSubmitOutcome>;
|
|
94
|
+
/**
|
|
95
|
+
* Validate + normalize a phone PII answer to E.164 then submit. On a
|
|
96
|
+
* possible-but-invalid number, emits the legacy INVALID_PHONE_NUMBER log event.
|
|
97
|
+
*/
|
|
98
|
+
submitPhoneAnswer(text: string, countryCode: string): Promise<PiiSubmitOutcome>;
|
|
99
|
+
/**
|
|
100
|
+
* Validate a name PII answer. If it likely contains more than the asked-for
|
|
101
|
+
* name part, call extract-human-name; when the extracted value differs, return
|
|
102
|
+
* a confirm outcome for the UI (legacy NameExtractionConfirmModal). Otherwise
|
|
103
|
+
* submit directly. Confirm via submitNameConfirmed.
|
|
104
|
+
*/
|
|
105
|
+
submitNameAnswer(text: string): Promise<PiiSubmitOutcome>;
|
|
106
|
+
/** Submit the name value the candidate confirmed in the extraction modal. */
|
|
107
|
+
submitNameConfirmed(text: string): Promise<void>;
|
|
108
|
+
/** Submit a location PII answer (address text + serialized place; legacy handleSelectLocation). */
|
|
109
|
+
submitLocationAnswer(location: {
|
|
110
|
+
address: string;
|
|
111
|
+
[key: string]: unknown;
|
|
112
|
+
}): Promise<void>;
|
|
113
|
+
/**
|
|
114
|
+
* Re-edit a previously answered question (legacy EDIT_MODE_ENTER): mark its
|
|
115
|
+
* candidate bubble EDITING so the input/options re-appear; the next submit
|
|
116
|
+
* routes to edit-answer instead of next.
|
|
117
|
+
*/
|
|
118
|
+
enterEditMode(questionId: string): void;
|
|
119
|
+
/** Cancel an in-progress edit, restoring the answered bubble (legacy EDIT_MODE_EXIT). */
|
|
120
|
+
cancelEditMode(): void;
|
|
121
|
+
/**
|
|
122
|
+
* Upload a recorded video answer then submit its server filename (legacy
|
|
123
|
+
* useUploadVideo + ChatbotStateContext video answer): append a PENDING video
|
|
124
|
+
* bubble showing upload progress, get the S3 signed URL, PUT the blob, then
|
|
125
|
+
* POST the returned videoFileName to /next. On failure the bubble goes FAILED
|
|
126
|
+
* and the blob is retained for retry.
|
|
127
|
+
*/
|
|
128
|
+
submitVideoAnswer(blob: Blob, extension: string): Promise<void>;
|
|
129
|
+
/** Retry a failed video upload with the retained blob. */
|
|
130
|
+
retryVideoAnswer(): Promise<void>;
|
|
131
|
+
/** Fetch a signed playback URL for a recorded video answer (legacy getVideoAccessUrl). */
|
|
132
|
+
getVideoPlaybackUrl(questionId: string, extension: string): Promise<string>;
|
|
133
|
+
private upsertVideoBubble;
|
|
134
|
+
private removeBubble;
|
|
135
|
+
private submitFreeText;
|
|
136
|
+
/** Routes an answer to edit-answer when re-editing, else to the next-question flow. */
|
|
137
|
+
private dispatchFreshOrEdit;
|
|
138
|
+
/** Submit an edited answer (legacy useSubmitEditedAnswer + EDIT_ANSWER_REQUEST_COMPLETED). */
|
|
139
|
+
private editExistingAnswer;
|
|
140
|
+
/** Question being answered: the one under edit if editing, else the last agent bubble. */
|
|
141
|
+
private currentEditableQuestionId;
|
|
142
|
+
private currentPiiType;
|
|
143
|
+
/**
|
|
144
|
+
* Submit the selected option (MCQ/DROPDOWN/BGQ, incl. the terms-accept MCQ) of the
|
|
145
|
+
* current question. The option lives in the inline candidate bubble appended by
|
|
146
|
+
* bubble conversion; BGQ buttons echo their triggers/style back in the answer
|
|
147
|
+
* (ported from legacy handleSelectOption / handleSelectBGQButton).
|
|
148
|
+
*/
|
|
149
|
+
submitOptionAnswer(optionId: string, skipAgcDetection?: boolean): Promise<void>;
|
|
150
|
+
/**
|
|
151
|
+
* Calls detect-agc when submitting the SUBMIT_QUESTION_MESSAGE and a check is
|
|
152
|
+
* allowed; returns true (→ show warning) when automated content is suspected.
|
|
153
|
+
*/
|
|
154
|
+
private detectedAgc;
|
|
155
|
+
/** Continue submitting after the AGC warning (legacy "Continue" — skips re-detection). */
|
|
156
|
+
continueAfterAgcWarning(): Promise<void>;
|
|
157
|
+
/** Dismiss the AGC warning to edit the answer (legacy "Edit"). */
|
|
158
|
+
dismissAgcWarning(): void;
|
|
159
|
+
/** Emits the legacy INVALID_PASTE_ANSWER_ACTION log when paste is disallowed. */
|
|
160
|
+
reportPaste(): void;
|
|
161
|
+
/** Submit the experience-rating slider score (legacy handleSubmitRating). */
|
|
162
|
+
submitSliderAnswer(score: number): Promise<void>;
|
|
163
|
+
/** Stamp the inline candidate bubble with the chosen answer and send it (or edit it). */
|
|
164
|
+
private submitInlineAnswer;
|
|
165
|
+
/** Re-submit the answer whose bubble is in FAILED state. */
|
|
166
|
+
retryLastAnswer(): Promise<void>;
|
|
167
|
+
private currentQuestionId;
|
|
168
|
+
/** The synthetic candidate bubble holding the question's selectable options. */
|
|
169
|
+
private inlineCandidateBubble;
|
|
170
|
+
private appendOptimisticCandidateBubble;
|
|
171
|
+
private setPendingBubbleStatus;
|
|
172
|
+
/** Swap the in-flight bubble for the server-confirmed candidate response. */
|
|
173
|
+
private replacePendingBubble;
|
|
174
|
+
/**
|
|
175
|
+
* Loads the next message via /next/stream (the sole load path): consumes the
|
|
176
|
+
* AG-UI stream, revealing agent text char-by-char into a transient live bubble,
|
|
177
|
+
* then swaps it for the authoritative bubble from the terminal RUN_FINISHED
|
|
178
|
+
* frame. Shares the candidate-settle and agent-append tails with the answer flow.
|
|
179
|
+
*/
|
|
180
|
+
private loadNext;
|
|
181
|
+
/** Minimal agent bubble for the streaming text (mirrors convertRawAgentResponseToMessageBubble
|
|
182
|
+
* for a single TEXT content); meta, when present, seeds types/rules/tags so the live bubble
|
|
183
|
+
* can render as the question card from the first character. While revealing, the content is
|
|
184
|
+
* typed out as plain TEXT; once `committed`, the snapshot content's BE render indicators
|
|
185
|
+
* (types/component) are applied so a bundled video hint settles to the embedded player
|
|
186
|
+
* instead of leaking its URL as text. */
|
|
187
|
+
private buildLiveBubble;
|
|
188
|
+
/**
|
|
189
|
+
* Handle terminal/duplicate signals on a response (legacy
|
|
190
|
+
* chatbotStateReducer): emit assessment:duplicated and render a terminal
|
|
191
|
+
* agent message (archived cohort / reused assessment), ending the interview.
|
|
192
|
+
* Returns true when the interview has been terminated.
|
|
193
|
+
*/
|
|
194
|
+
private handleTerminalSignals;
|
|
195
|
+
/**
|
|
196
|
+
* Settle the in-flight candidate bubble with the server-confirmed response and
|
|
197
|
+
* update the meta fields, then handle terminal/duplicate signals.
|
|
198
|
+
* Returns true when the interview has been terminated (caller stops).
|
|
199
|
+
*/
|
|
200
|
+
private settleAnswerAndStatus;
|
|
201
|
+
/**
|
|
202
|
+
* Append the authoritative next agent bubble (plus any inline option/slider
|
|
203
|
+
* candidate bubble), recurse on HINTs, and end the interview when there is no
|
|
204
|
+
* next question. Assumes the answer is already settled and the live bubble removed.
|
|
205
|
+
*/
|
|
206
|
+
private appendAgentAndContinue;
|
|
207
|
+
}
|