@sapia-ai/chatbot-v3 1.5.0 → 1.6.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-Dn-boxdp.js → EmbeddedVideoPlayer-Bhz8DKO8.js} +14 -14
- package/dist/{Preview-CtMz5fNh.js → Preview-B1ZmYM9V.js} +3 -3
- package/dist/api/client.d.ts +8 -1
- package/dist/api/types/messages.d.ts +8 -1
- package/dist/api/types/responses.d.ts +54 -12
- package/dist/api.js +2 -2
- package/dist/{client-DfRBtXIE.js → client-C2MWNOYf.js} +552 -545
- package/dist/core/bubbles/cards.d.ts +3 -1
- package/dist/core/bubbles/demographicRun.d.ts +57 -0
- package/dist/core/bubbles/selection.d.ts +3 -1
- package/dist/core/bubbles/types.d.ts +11 -0
- package/dist/core/interview/engine.d.ts +33 -2
- package/dist/core/interview/reveal.d.ts +5 -2
- package/dist/core/store.d.ts +10 -2
- package/dist/core/theme/branding.d.ts +5 -2
- package/dist/{dist-Cl2Oi3Sl.js → dist-CoO0i-y0.js} +3 -3
- package/dist/embed/createChatbot.d.ts +0 -2
- package/dist/{fix-webm-duration-CVQSf7rp.js → fix-webm-duration-CXijcUXq.js} +2 -2
- package/dist/index.js +5987 -5684
- package/dist/{jsx-runtime-CdNykazB.js → jsx-runtime-BcXxfixh.js} +2 -2
- package/dist/react/SapiaChatbot.d.ts +1 -3
- package/dist/react/strings.d.ts +5 -4
- package/dist/react/useDemographicForm.d.ts +14 -0
- package/dist/{react-BIgNJUOD.js → react-Cp-K_L89.js} +3 -3
- package/dist/{react-DlJlpUiG.js → react-D3tMg8u4.js} +3 -3
- package/dist/{react-DEJ3NRa3.js → react-D8jZKei2.js} +3 -3
- package/dist/{react-BKViU2cv.js → react-DtGzNzM1.js} +3 -3
- package/dist/{react-BC7MhdYE.js → react-LDcTld2q.js} +3 -3
- package/dist/{react-78ZA32q8.js → react-g5b2mM7w.js} +3 -3
- package/dist/{react-BSaO3Elx.js → react-hklchtwF.js} +3 -3
- package/dist/{react-eOBKoj54.js → react-vc8uDric.js} +3 -3
- package/dist/{react-D4Z0N-x7.js → react-wrZMUHWq.js} +2 -2
- package/dist/ui/chat/ActionDock/ActionDock.d.ts +5 -0
- package/dist/ui/chat/ChatLog/ChatLog.d.ts +3 -7
- package/dist/ui/chat/DemographicDetailsCard/DemographicDetailsCard.d.ts +14 -0
- package/dist/ui/chat/TypingIndicator/TypingIndicator.d.ts +9 -25
- package/dist/ui/chat/types.d.ts +8 -1
- package/dist/ui/inputs/DemographicForm/DemographicForm.d.ts +35 -0
- package/dist/ui/inputs/LocationAnswerInput/LocationCombobox.d.ts +4 -2
- package/dist/ui/inputs/OptionList/OptionList.d.ts +4 -0
- package/dist/ui/inputs/formCard.d.ts +12 -0
- package/dist/ui/shell/LogoTile/LogoTile.d.ts +6 -1
- package/dist-umd/sapia-chatbot.umd.js +274 -274
- package/package.json +1 -1
|
@@ -8,7 +8,9 @@ export declare enum BubbleCard {
|
|
|
8
8
|
PII_FORM_INTRO = "PII_FORM_INTRO",
|
|
9
9
|
PII_DETAILS = "PII_DETAILS",
|
|
10
10
|
CUSTOMER_SATISFACTION_FORM = "CUSTOMER_SATISFACTION_FORM",
|
|
11
|
-
CUSTOMER_SATISFACTION_INTRO = "CUSTOMER_SATISFACTION_INTRO"
|
|
11
|
+
CUSTOMER_SATISFACTION_INTRO = "CUSTOMER_SATISFACTION_INTRO",
|
|
12
|
+
DEMOGRAPHIC_FORM = "DEMOGRAPHIC_FORM",
|
|
13
|
+
DEMOGRAPHIC_DETAILS = "DEMOGRAPHIC_DETAILS"
|
|
12
14
|
}
|
|
13
15
|
/**
|
|
14
16
|
* The card this content bubble stands for, or undefined for ordinary text. The backend's
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { MCQQuestionOption } from '../../api/types/messages';
|
|
2
|
+
import { ChatLog, DemographicFormField } from '../../api/types/responses';
|
|
3
|
+
import { BubbleStatus, MessageBubble } from './types';
|
|
4
|
+
/** Id prefix of the synthetic candidate turn the card is answered in. */
|
|
5
|
+
export declare const DEI_FORM_BUBBLE_ID_PREFIX = "dei-form";
|
|
6
|
+
/** Id prefix of the candidate turn standing in for an answered run. */
|
|
7
|
+
export declare const DEI_DETAILS_BUBBLE_ID_PREFIX = "dei-details";
|
|
8
|
+
/** The option ids ticked on the card, keyed by questionId, before it is posted. */
|
|
9
|
+
export type DemographicAnswers = Record<string, string[]>;
|
|
10
|
+
/**
|
|
11
|
+
* Replace the prompt the diversity run opens on — and the inline option list it would have drawn —
|
|
12
|
+
* with the card's placeholder turn. The run's own prompts are the card's field labels, so none of
|
|
13
|
+
* them reaches the transcript as a message; the template's intro hints above stay as they are and
|
|
14
|
+
* the card reads as the reply to them.
|
|
15
|
+
*
|
|
16
|
+
* Applied on the live stream. A transcript that does not hold the run's opening prompt is returned
|
|
17
|
+
* unchanged, which also makes re-marking after the prompt is gone a no-op.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```js
|
|
21
|
+
* // bubbles: [...hints, agent(gender), candidateInline(gender)]; fields start at gender
|
|
22
|
+
* markDemographicFormBubble(bubbles, fields) // [...hints, formBubble(candidate)]
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export declare const markDemographicFormBubble: (bubbles: MessageBubble[], fields?: DemographicFormField[]) => MessageBubble[];
|
|
26
|
+
/**
|
|
27
|
+
* The options ticked for each question, in dialogue order. A question with nothing ticked is
|
|
28
|
+
* absent, and an id the question never offered is dropped rather than posted.
|
|
29
|
+
*/
|
|
30
|
+
export declare const demographicSelections: (fields: DemographicFormField[], answers: DemographicAnswers) => {
|
|
31
|
+
field: DemographicFormField;
|
|
32
|
+
options: MCQQuestionOption[];
|
|
33
|
+
}[];
|
|
34
|
+
/**
|
|
35
|
+
* Draw the halves of a diversity run the backend folded a reloaded transcript into. The form
|
|
36
|
+
* message becomes the card while the run is still open, and nothing once it has been answered; the
|
|
37
|
+
* responses message becomes the answered card.
|
|
38
|
+
*
|
|
39
|
+
* @returns the bubbles for a folded half, or undefined for any other turn
|
|
40
|
+
* @example
|
|
41
|
+
* ```js
|
|
42
|
+
* // chatLogs: [{formType, fields}, {formType, responses: [{prompt: "Gender", answer: "Woman"}]}]
|
|
43
|
+
* demographicRunBubbles(chatLogs[0], chatLogs[1]) // []
|
|
44
|
+
* demographicRunBubbles(chatLogs[1]) // [answered card: Gender — Woman]
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
export declare const demographicRunBubbles: (chatLog: ChatLog, nextChatLog?: ChatLog) => MessageBubble[] | undefined;
|
|
48
|
+
/**
|
|
49
|
+
* The diversity run a reloaded transcript is still waiting on, so the engine can redraw the card.
|
|
50
|
+
* A run that has been posted comes back with its responses beside it and needs no card.
|
|
51
|
+
*/
|
|
52
|
+
export declare const openDemographicForm: (chatLogs: ChatLog[]) => DemographicFormField[] | undefined;
|
|
53
|
+
/** Swap the card's placeholder turn for the answered card, built from the same answers. */
|
|
54
|
+
export declare const swapFormForDemographicDetails: (bubbles: MessageBubble[], fields: DemographicFormField[], answers: DemographicAnswers, status: BubbleStatus) => {
|
|
55
|
+
bubbles: MessageBubble[];
|
|
56
|
+
detailsBubbleId: string;
|
|
57
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { QuestionRule } from '../../api/types/messages';
|
|
1
|
+
import { QuestionType, QuestionRule } from '../../api/types/messages';
|
|
2
2
|
import { MessageBubble } from './types';
|
|
3
3
|
/** Which instruction a multi-select question shows above its options. */
|
|
4
4
|
export declare enum SelectionInstruction {
|
|
@@ -32,6 +32,8 @@ export declare const usesSelectionAnswer: (bubble: MessageBubble) => boolean;
|
|
|
32
32
|
* multi-select path, even though its answer still goes over the wire as a set of one.
|
|
33
33
|
*/
|
|
34
34
|
export declare const isMultiSelectBubble: (bubble: MessageBubble) => boolean;
|
|
35
|
+
/** @see isMultiSelectBubble — the same rule for a question described outside a bubble. */
|
|
36
|
+
export declare const isMultiSelectQuestion: (types: QuestionType[], rules?: QuestionRule[]) => boolean;
|
|
35
37
|
/**
|
|
36
38
|
* Which instruction the question shows. A cap equal to the number of options on offer states
|
|
37
39
|
* nothing "any number" does not already allow, so it reads as open-ended — the builder never offers
|
|
@@ -83,6 +83,15 @@ export type CustomerSatisfactionResponse = {
|
|
|
83
83
|
rating?: number;
|
|
84
84
|
comment?: string;
|
|
85
85
|
};
|
|
86
|
+
/**
|
|
87
|
+
* One answered diversity question as the answered card draws it: the template's question and what
|
|
88
|
+
* the candidate chose, already joined for display.
|
|
89
|
+
*/
|
|
90
|
+
export type DemographicDetailEntry = {
|
|
91
|
+
questionId: string;
|
|
92
|
+
prompt: string;
|
|
93
|
+
answer: string;
|
|
94
|
+
};
|
|
86
95
|
export type MessageBubbleData = {
|
|
87
96
|
messageItems: MessageItem[];
|
|
88
97
|
answer?: AnswerContent | null;
|
|
@@ -92,6 +101,8 @@ export type MessageBubbleData = {
|
|
|
92
101
|
piiDetails?: PiiDetailEntry[];
|
|
93
102
|
/** Present only on the bubble standing in for an answered feedback run. */
|
|
94
103
|
customerSatisfaction?: CustomerSatisfactionResponse;
|
|
104
|
+
/** Present only on the bubble standing in for an answered diversity run. */
|
|
105
|
+
demographicDetails?: DemographicDetailEntry[];
|
|
95
106
|
};
|
|
96
107
|
export type MessageBubble = {
|
|
97
108
|
status: BubbleStatus;
|
|
@@ -3,6 +3,7 @@ import { PiiSubmitOutcome } from '../validation/piiAnswer';
|
|
|
3
3
|
import { PiiFormAnswer } from '../validation/piiForm';
|
|
4
4
|
import { LocationAnswer } from '../../api/places';
|
|
5
5
|
import { CustomerSatisfactionAnswer } from '../bubbles/customerSatisfactionRun';
|
|
6
|
+
import { DemographicAnswers } from '../bubbles/demographicRun';
|
|
6
7
|
import { ChatbotEventEmitter } from '../events';
|
|
7
8
|
import { InterviewStore } from '../store';
|
|
8
9
|
export type InterviewEngineDeps = {
|
|
@@ -18,6 +19,12 @@ export type InterviewEngineDeps = {
|
|
|
18
19
|
welcomeGate?: boolean;
|
|
19
20
|
/** Reveal cadence (ms per character) while streaming; 0 reveals each chunk wholesale (reduced-motion). */
|
|
20
21
|
streamRevealMs?: number;
|
|
22
|
+
/**
|
|
23
|
+
* Stream agent text word by word (true), or have the backend send each message whole and paint
|
|
24
|
+
* it whole (false, the default). Questions are predefined and the same for every candidate, so
|
|
25
|
+
* by default they must not look generated as they arrive.
|
|
26
|
+
*/
|
|
27
|
+
streamText?: boolean;
|
|
21
28
|
};
|
|
22
29
|
export declare class InterviewEngine {
|
|
23
30
|
private readonly client;
|
|
@@ -29,6 +36,7 @@ export declare class InterviewEngine {
|
|
|
29
36
|
private language;
|
|
30
37
|
private readonly welcomeGate;
|
|
31
38
|
private readonly streamRevealMs;
|
|
39
|
+
private readonly streamText;
|
|
32
40
|
/** Aborts the in-flight stream when a new load starts. */
|
|
33
41
|
private streamAbort?;
|
|
34
42
|
/** Monotonic counter for unique live-bubble ids (avoids Date.now in core). */
|
|
@@ -134,6 +142,12 @@ export declare class InterviewEngine {
|
|
|
134
142
|
private submitResolved;
|
|
135
143
|
/** Submit the name value the candidate confirmed in the extraction modal. */
|
|
136
144
|
submitNameConfirmed(text: string): Promise<void>;
|
|
145
|
+
/**
|
|
146
|
+
* Keeps the name the candidate just gave so the done screen can greet them without another
|
|
147
|
+
* /start/ats. Shown exactly as typed — a full name is never split. A first name wins: a full
|
|
148
|
+
* name only fills the slot when nothing better is known yet.
|
|
149
|
+
*/
|
|
150
|
+
private rememberCandidateName;
|
|
137
151
|
/**
|
|
138
152
|
* Submit a location PII answer (legacy handleSelectLocation). The value must be JSON: the backend
|
|
139
153
|
* parses it before reading `address`/`coordinate`, so a bare address string fails the request.
|
|
@@ -173,6 +187,23 @@ export declare class InterviewEngine {
|
|
|
173
187
|
* ```
|
|
174
188
|
*/
|
|
175
189
|
submitCustomerSatisfactionForm(answer: CustomerSatisfactionAnswer): Promise<void>;
|
|
190
|
+
/**
|
|
191
|
+
* Post the diversity card. Answers go in dialogue order because the backend replays them one at a
|
|
192
|
+
* time against the prompt it has open. A multi-select answer travels as its selections whatever
|
|
193
|
+
* its cap, as it does everywhere else. The card is only sendable once every question carries an
|
|
194
|
+
* answer; that is checked again here so a stale click can never post a partial card.
|
|
195
|
+
*
|
|
196
|
+
* The card becomes the answered card before the request goes out; a failed send leaves it FAILED
|
|
197
|
+
* and retryLastAnswer re-posts the same answers.
|
|
198
|
+
*
|
|
199
|
+
* @example
|
|
200
|
+
* ```js
|
|
201
|
+
* // fields: [gender(MCQ), ethnicity(MSQ)]
|
|
202
|
+
* submitDemographicForm({ gender: ['woman'], ethnicity: ['asian', 'pacific'] })
|
|
203
|
+
* // posts [{ text: 'Woman' }, { text: 'Asian | Pacific', selections: [...] }]
|
|
204
|
+
* ```
|
|
205
|
+
*/
|
|
206
|
+
submitDemographicForm(answers: DemographicAnswers): Promise<void>;
|
|
176
207
|
/**
|
|
177
208
|
* Re-edit a previously answered question (legacy EDIT_MODE_ENTER): mark its
|
|
178
209
|
* candidate bubble EDITING so the input/options re-appear; the next submit
|
|
@@ -270,8 +301,8 @@ export declare class InterviewEngine {
|
|
|
270
301
|
private replacePendingBubble;
|
|
271
302
|
/**
|
|
272
303
|
* Loads the next message via /next/stream (the sole load path): consumes the
|
|
273
|
-
* AG-UI stream
|
|
274
|
-
* then swaps it for the authoritative bubble from the terminal RUN_FINISHED
|
|
304
|
+
* AG-UI stream into a transient live bubble (painted whole, or word by word when streamText
|
|
305
|
+
* is on), then swaps it for the authoritative bubble from the terminal RUN_FINISHED
|
|
275
306
|
* frame. Shares the candidate-settle and agent-append tails with the answer flow.
|
|
276
307
|
*/
|
|
277
308
|
private loadNext;
|
|
@@ -20,9 +20,10 @@ export type StreamPaint = {
|
|
|
20
20
|
/**
|
|
21
21
|
* A run can bundle several messages: each carries its own message id, and a new id means the
|
|
22
22
|
* previous one is finished and must be frozen as a hint — only the final message is echoed
|
|
23
|
-
* authoritatively in RUN_FINISHED. This owns that segmentation and
|
|
23
|
+
* authoritatively in RUN_FINISHED. This owns that segmentation and how each message is revealed: whole, or word by word.
|
|
24
24
|
*/
|
|
25
25
|
export declare class StreamAssembler {
|
|
26
|
+
/** Ms per character for the word-by-word reveal; undefined paints each message whole. */
|
|
26
27
|
private readonly revealMs;
|
|
27
28
|
private readonly nextSyntheticId;
|
|
28
29
|
private readonly paint;
|
|
@@ -46,7 +47,9 @@ export declare class StreamAssembler {
|
|
|
46
47
|
private readonly metaById;
|
|
47
48
|
private networkDone;
|
|
48
49
|
private placed;
|
|
49
|
-
constructor(
|
|
50
|
+
constructor(
|
|
51
|
+
/** Ms per character for the word-by-word reveal; undefined paints each message whole. */
|
|
52
|
+
revealMs: number | undefined, nextSyntheticId: () => string, paint: StreamPaint);
|
|
50
53
|
/** Id the live bubble is painted under — the backend's own once a delta has named it. */
|
|
51
54
|
get liveId(): string;
|
|
52
55
|
/** Backend message id of the message currently streaming; undefined before the first delta. */
|
package/dist/core/store.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { StoreApi } from 'zustand/vanilla';
|
|
2
2
|
import { AssessmentStatus } from '../api/types/messages';
|
|
3
3
|
import { Branding } from '../api/types/branding';
|
|
4
|
-
import { AssessmentSummary, CustomerSatisfactionFormField, PiiFormField, ResolvedFeatureFlags } from '../api/types/responses';
|
|
4
|
+
import { AssessmentSummary, CustomerSatisfactionFormField, DemographicFormField, PiiFormField, ResolvedFeatureFlags } from '../api/types/responses';
|
|
5
5
|
import { PiiFormAnswer } from './validation/piiForm';
|
|
6
6
|
import { MessageBubble } from './bubbles/types';
|
|
7
7
|
export declare enum InterviewPhase {
|
|
@@ -62,8 +62,16 @@ export type InterviewState = {
|
|
|
62
62
|
* CUSTOMER_SATISFACTION_FORM frame and from /start on reload; cleared once the card is posted.
|
|
63
63
|
*/
|
|
64
64
|
csatForm?: CustomerSatisfactionFormField[];
|
|
65
|
+
/**
|
|
66
|
+
* The diversity questions the interview is paused on, in dialogue order. Set from the
|
|
67
|
+
* DEMOGRAPHIC_FORM frame and from /start on reload; cleared once the card is posted.
|
|
68
|
+
*/
|
|
69
|
+
deiForm?: DemographicFormField[];
|
|
65
70
|
branding?: Branding;
|
|
66
|
-
/**
|
|
71
|
+
/**
|
|
72
|
+
* Name the welcome and done screens greet the candidate by: /start/ats's first name, or the
|
|
73
|
+
* name given in this session's PII step. Absent → generic copy.
|
|
74
|
+
*/
|
|
67
75
|
candidateName?: string;
|
|
68
76
|
/** Cohort title from /start/ats, shown as the role in the header and welcome. */
|
|
69
77
|
jobTitle?: string;
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { Branding } from '../../api/types/branding';
|
|
2
2
|
import { Theme } from './types';
|
|
3
|
-
/**
|
|
4
|
-
|
|
3
|
+
/**
|
|
4
|
+
* Converts the branding payload (theme array + font) into a Theme object. `assessmentId` only
|
|
5
|
+
* identifies the assessment in contrast warnings, since newer BEs no longer send `customerId`.
|
|
6
|
+
*/
|
|
7
|
+
export declare const brandingToTheme: (branding?: Branding, assessmentId?: string) => Theme;
|
|
5
8
|
/** Merge two themes; `override` (host setTheme) wins per field over `base` (branding). */
|
|
6
9
|
export declare const mergeThemes: (base: Theme | undefined, override: Theme | undefined) => Theme;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { t } from "./react-
|
|
1
|
+
import { H as e } from "./client-C2MWNOYf.js";
|
|
2
|
+
import { t } from "./react-wrZMUHWq.js";
|
|
3
3
|
import { t as n } from "./defineProperty-DiFpLzd2.js";
|
|
4
4
|
import { n as r, t as i } from "./hls-mBncGwsE.js";
|
|
5
5
|
import { a, i as o, n as s, r as c, t as l } from "./classPrivateFieldSet2-DtQPURVD.js";
|
|
@@ -14324,4 +14324,4 @@ var Kw = Object.prototype.hasOwnProperty, qw = (e, t) => {
|
|
|
14324
14324
|
//#endregion
|
|
14325
14325
|
export { Or as MaxResolution, C as MediaError, kr as MinResolution, Ar as RenditionOrder, rT as default, ha as generatePlayerInitTime, nT as playerSoftwareName, tT as playerSoftwareVersion };
|
|
14326
14326
|
|
|
14327
|
-
//# sourceMappingURL=dist-
|
|
14327
|
+
//# sourceMappingURL=dist-CoO0i-y0.js.map
|
|
@@ -19,8 +19,6 @@ export type CreateChatbotOptions = {
|
|
|
19
19
|
placesApiKey?: string;
|
|
20
20
|
/** Custom fetch (e.g. a mocked SSE stream for demos/tests). */
|
|
21
21
|
fetchImpl?: typeof fetch;
|
|
22
|
-
/** @internal Holds the typing indicator's "reading" phrase open (demos/tests). */
|
|
23
|
-
readingPhaseMs?: number;
|
|
24
22
|
};
|
|
25
23
|
export type Chatbot = {
|
|
26
24
|
mount: (target?: string | HTMLElement) => void;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { B as e } from "./client-C2MWNOYf.js";
|
|
2
2
|
//#region ../../node_modules/.pnpm/fix-webm-duration@1.0.6/node_modules/fix-webm-duration/fix-webm-duration.js
|
|
3
3
|
var t = /* @__PURE__ */ e(((e, t) => {
|
|
4
4
|
(function(e, n) {
|
|
@@ -1054,4 +1054,4 @@ var t = /* @__PURE__ */ e(((e, t) => {
|
|
|
1054
1054
|
//#endregion
|
|
1055
1055
|
export default t();
|
|
1056
1056
|
|
|
1057
|
-
//# sourceMappingURL=fix-webm-duration-
|
|
1057
|
+
//# sourceMappingURL=fix-webm-duration-CXijcUXq.js.map
|