@alxxsck/ai-assistant 2.14.0 → 2.16.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.
@@ -7,16 +7,26 @@ export type CursorPage<T> = {
7
7
  items: T[];
8
8
  nextCursor: string | null;
9
9
  };
10
- type ConversationsResponse = CursorPage<ConversationData>;
10
+ type VersionedCursorPage<T> = CursorPage<T> & {
11
+ contractVersion?: unknown;
12
+ };
13
+ type ConversationsResponse = VersionedCursorPage<ConversationData>;
11
14
  export declare class ChatApiError extends Error {
12
15
  readonly status: number;
13
16
  constructor(status: number, message: string);
14
17
  }
18
+ export declare class ChatContractError extends Error {
19
+ constructor();
20
+ }
15
21
  export declare const isConversationClosedError: (error: unknown) => boolean;
22
+ export declare const requestChatJson: <T>(config: WidgetConfig, api: AppApi, path: string, init?: RequestInit) => Promise<T>;
23
+ export declare const normalizeConversation: (conversation: ConversationData) => ConversationData;
16
24
  export declare const normalizeMessage: (message: RawMessageData, config: WidgetConfig) => MessageData;
25
+ export declare const normalizeMessageForSession: (message: RawMessageData, interactionSessionId: string) => MessageData;
17
26
  export declare const listConversations: (config: WidgetConfig, api: AppApi, cursor?: string, signal?: AbortSignal) => Promise<ConversationsResponse>;
18
27
  export declare const listConversationMessages: (config: WidgetConfig, api: AppApi, conversationId: string, cursor?: string, signal?: AbortSignal) => Promise<CursorPage<MessageData>>;
19
28
  export declare const createConversation: (config: WidgetConfig, api: AppApi) => Promise<ConversationData>;
20
29
  export declare const selectConversation: (config: WidgetConfig, api: AppApi, conversationId: string, signal?: AbortSignal) => Promise<ConversationData>;
30
+ export declare const getConversation: (config: WidgetConfig, api: AppApi, conversationId: string, signal?: AbortSignal) => Promise<ConversationData>;
21
31
  export declare function sendMessage(config: WidgetConfig, api: AppApi, messageText: string, conversationId?: string, clientMessageId?: `${string}-${string}-${string}-${string}-${string}`, attachments?: readonly ChatAttachment[]): Promise<SendMessageResult>;
22
32
  export {};
@@ -17,6 +17,8 @@ export type ChatParticipant = {
17
17
  type: ParticipantType;
18
18
  displayName?: string;
19
19
  avatarUrl?: string | null;
20
+ role?: MessageRole;
21
+ presentation?: import("@/domain/support-presentation/support-presentation.types").MessageAuthorPresentation | null;
20
22
  };
21
23
  export type MessageDelivery = {
22
24
  id: string;
@@ -99,21 +101,20 @@ export type ConversationData = {
99
101
  };
100
102
  messages?: RawMessageData[];
101
103
  aiSuspension?: ConversationAISuspension;
104
+ responderPresentation?: import("@/domain/support-presentation/support-presentation.types").SafeResponderPresentation;
102
105
  };
106
+ export type MessageRole = "USER" | "ASSISTANT" | "ADMIN" | "SCENARIO" | "SYSTEM";
103
107
  export type RawMessageData = {
104
108
  id: string;
105
109
  threadId: string;
106
- role: "USER" | "ASSISTANT" | "ADMIN" | "SCENARIO" | "SYSTEM";
107
- status: "COMPLETED" | "WRITING" | "FAILED";
110
+ role: MessageRole;
111
+ status: "COMPLETED" | "WRITING" | "FAILED" | "CANCELLED";
108
112
  text: string;
109
113
  content: JSONContent | null;
110
114
  commands: unknown[];
111
115
  ordinal?: number;
112
116
  clientMessageId?: string | null;
113
- author?: {
114
- displayName?: string;
115
- avatarUrl?: string | null;
116
- } | null;
117
+ author?: unknown;
117
118
  attachments?: ChatAttachment[];
118
119
  delivery?: MessageDelivery;
119
120
  createdAt: string;
@@ -128,6 +129,8 @@ export type AgenticStepsAppendedData = {
128
129
  };
129
130
  export type ChatMessageDeltaData = {
130
131
  messageId: string;
132
+ conversationId?: string;
133
+ requestId?: string;
131
134
  sequence: number;
132
135
  text: string;
133
136
  done: boolean;
@@ -1,4 +1,4 @@
1
- import { S as A, T as e, W as s, x as n, U as r } from "./index-mn1rW9m7.js";
1
+ import { Z as A, _ as e, a0 as s, D as n, $ as r } from "./index-TodLTFY_.js";
2
2
  export {
3
3
  A as ChatWidgetInstance,
4
4
  e as EXTERNALLY_AVAILABLE_ACTIONS,
@@ -3,7 +3,7 @@ import type { CommandAck } from "@/domain/command/command.types";
3
3
  import type { CommandRuntime } from "@/domain/command/CommandRuntime";
4
4
  import type { MessageStoreActions } from "@/domain/message/message.store";
5
5
  type WidgetFrameDependencies = {
6
- messageActions: Pick<MessageStoreActions, "handleConversationCreated" | "handleMessageDelta" | "handleMessagesAgenticSteps" | "handleMessage" | "handleChatTyping" | "handleSupportPresence">;
6
+ messageActions: Pick<MessageStoreActions, "handleConversationCreated" | "handleScenarioChoiceLifecycleChanged" | "handleScenarioChoiceSubmissionResult" | "handleMessageDelta" | "handleMessagesAgenticSteps" | "handleMessage" | "handleChatTyping" | "handleSupportPresence" | "handleResponderPresentationChanged">;
7
7
  commandRuntime: CommandRuntime;
8
8
  session: CustomerInteractionSession;
9
9
  sendAck: (ack: CommandAck) => Promise<unknown>;
@@ -1,5 +1,20 @@
1
1
  import type { AgenticStepsAppendedData, ChatMessageDeltaData, ConversationData, MessageData } from "@/api/messages.api.types";
2
- export declare const getConversationCreatedFromFrame: (frame: unknown) => ConversationData | null;
3
- export declare const getMessageFromFrame: (frame: unknown) => MessageData | null;
2
+ import { type ScenarioChoiceLifecycleChanged, type ScenarioChoiceSubmissionResult } from "@/domain/scenario/scenario-choice";
3
+ export type ScenarioConversationCreated = ConversationData & {
4
+ navigationEventId?: string;
5
+ };
6
+ export type ResponderPresentationChanged = Readonly<{
7
+ contractVersion: 1;
8
+ type: "conversation.responder_presentation.changed.v1";
9
+ eventId: string;
10
+ conversationId: string;
11
+ revision: string;
12
+ serverTime: string;
13
+ }>;
14
+ export declare const getConversationCreatedFromFrame: (frame: unknown) => ScenarioConversationCreated | null;
15
+ export declare const getMessageFromFrame: (frame: unknown, interactionSessionId?: string) => MessageData | null;
4
16
  export declare const getMessageDeltaFromFrame: (frame: unknown) => ChatMessageDeltaData | null;
17
+ export declare const getResponderPresentationChangedFromFrame: (frame: unknown) => ResponderPresentationChanged | null;
18
+ export declare const getScenarioChoiceLifecycleChangedFromFrame: (frame: unknown) => ScenarioChoiceLifecycleChanged | null;
19
+ export declare const getScenarioChoiceSubmissionResultFromFrame: (frame: unknown) => ScenarioChoiceSubmissionResult | null;
5
20
  export declare const getAgenticStepsFromFrame: (frame: unknown) => AgenticStepsAppendedData | null;
@@ -3,11 +3,17 @@ import type { AppApi } from "@/App";
3
3
  import type { WidgetConfig } from "@/index.types";
4
4
  import { type MessageStreamState } from "./message-stream";
5
5
  import type { ChatAttachment, ChatTypingState, SupportPresenceState } from "./chat-experience";
6
+ import type { ResponderPresentationChanged, ScenarioConversationCreated } from "./cable/widget-message";
7
+ import { type ScenarioChoiceLifecycleChanged, type ScenarioChoiceSubmissionResult } from "@/domain/scenario/scenario-choice";
6
8
  export interface ThreadSummary {
7
9
  threadId: string;
8
10
  lastMessage: MessageData;
9
11
  }
10
12
  export type AgentResponsePhase = "idle" | "awaiting-first-token" | "streaming";
13
+ export type ConversationNavigationRequest = {
14
+ conversationId: string;
15
+ sequence: number;
16
+ };
11
17
  export type PendingCustomerMessage = {
12
18
  id: string;
13
19
  text: string;
@@ -38,6 +44,10 @@ export type MessageStore = {
38
44
  api: AppApi | null;
39
45
  latestReadMessageDate: string | null;
40
46
  latestMessageDate: string | null;
47
+ conversationNavigationRequest: ConversationNavigationRequest | null;
48
+ scenarioChoiceLifecycleEvents: Map<string, ScenarioChoiceLifecycleChanged>;
49
+ scenarioChoiceSubmissionResults: Map<string, ScenarioChoiceSubmissionResult>;
50
+ handledConversationNavigationEventIds: Set<string>;
41
51
  messageStreams: Map<string, MessageStreamState>;
42
52
  pendingMessageDeltas: Map<string, ChatMessageDeltaData>;
43
53
  pendingCustomerMessage: PendingCustomerMessage | null;
@@ -50,10 +60,14 @@ export type MessageStore = {
50
60
  };
51
61
  export type MessageStoreActions = {
52
62
  initMessageStore: (config: WidgetConfig, api: AppApi) => Promise<void>;
63
+ disposeMessageStore: () => void;
53
64
  setCurrentThread: (conversationId: string) => Promise<void>;
54
65
  createNewConversation: () => Promise<string>;
55
- handleConversationCreated: (conversation: ConversationData) => void;
66
+ handleConversationCreated: (conversation: ScenarioConversationCreated) => void;
67
+ handleScenarioChoiceLifecycleChanged: (event: ScenarioChoiceLifecycleChanged) => void;
68
+ handleScenarioChoiceSubmissionResult: (result: ScenarioChoiceSubmissionResult) => void;
56
69
  handleMessage: (message: MessageData) => void;
70
+ handleResponderPresentationChanged: (hint: ResponderPresentationChanged) => void;
57
71
  handleMessageDelta: (delta: ChatMessageDeltaData) => void;
58
72
  settleMessageStream: (messageId: string) => void;
59
73
  sendMessage: (message: string, attachments?: ChatAttachment[]) => Promise<SendMessageResult | undefined>;
@@ -83,10 +97,25 @@ export declare const useSelectThreadsPreviews: () => ThreadSummary[];
83
97
  export declare const useHasMoreConversations: () => boolean;
84
98
  export declare const useIsLoadingMoreConversations: () => boolean;
85
99
  export declare const useCurrentThreadId: () => string | undefined;
100
+ export declare const useCurrentResponderPresentation: () => Readonly<{
101
+ contractState: "CURRENT" | "LEGACY" | "INCOMPATIBLE";
102
+ schemaVersion: 0 | 1;
103
+ mode: import("@/domain/support-presentation/support-presentation.types").ResponderMode | "UNKNOWN";
104
+ identity: import("@/domain/support-presentation/support-presentation.types").ResponderIdentity;
105
+ displayName: string | null;
106
+ avatarAsset: import("@/domain/support-presentation/support-presentation.types").PresentationAvatarAsset | null;
107
+ presentationVersion: number | null;
108
+ revision: string;
109
+ sourceRevisions: import("@/domain/support-presentation/support-presentation.types").ResponderSourceRevisions | null;
110
+ refreshAt: string | null;
111
+ serverTime: string | null;
112
+ }>;
86
113
  export declare const useCurrentThreadHasOlderMessages: () => boolean;
87
114
  export declare const useIsLoadingOlderCurrentThread: () => boolean;
88
115
  export declare const useLatestReadMessageDate: () => string | null;
89
116
  export declare const useLatestMessageDate: () => string | null;
117
+ export declare const useConversationNavigationRequest: () => ConversationNavigationRequest | null;
118
+ export declare const useScenarioChoiceSubmissionResult: (clientEventId?: string) => ScenarioChoiceSubmissionResult | undefined;
90
119
  export declare const useSendError: () => string | null;
91
120
  export declare const selectIsCurrentThreadLoading: (state: MessageStore) => boolean;
92
121
  export declare const useIsCurrentThreadLoading: () => boolean;
@@ -3,15 +3,59 @@ export type ScenarioChoiceOption = {
3
3
  id: string;
4
4
  label: string;
5
5
  };
6
+ export declare const SCENARIO_CHOICE_LIFECYCLE_STATUSES: readonly ["PENDING", "ANSWERED", "TIMED_OUT", "CANCELLED"];
7
+ export type ScenarioChoiceLifecycleStatus = (typeof SCENARIO_CHOICE_LIFECYCLE_STATUSES)[number];
8
+ export type ScenarioChoiceLifecycle = {
9
+ contractVersion: 1;
10
+ status: ScenarioChoiceLifecycleStatus;
11
+ serverTime: string;
12
+ expiresAt: string | null;
13
+ resolvedAt: string | null;
14
+ selectedOptionId: string | null;
15
+ };
16
+ export type ScenarioChoiceLifecycleChanged = {
17
+ contractVersion: 1;
18
+ type: "scenario.choice.lifecycle.changed.v1";
19
+ eventId: string;
20
+ revision: number;
21
+ inputRequestId: string;
22
+ conversationId: string;
23
+ messageId: string;
24
+ occurredAt: string;
25
+ serverTime: string;
26
+ lifecycle: ScenarioChoiceLifecycle;
27
+ };
28
+ export declare const SCENARIO_CHOICE_SUBMISSION_OUTCOMES: readonly ["ACCEPTED", "DUPLICATE", "TERMINAL", "NOT_READY", "REJECTED", "UNAVAILABLE"];
29
+ export type ScenarioChoiceSubmissionResult = {
30
+ contractVersion: 1;
31
+ type: "scenario.choice.submission.result.v1";
32
+ clientEventId: string;
33
+ inputRequestId: string;
34
+ outcome: (typeof SCENARIO_CHOICE_SUBMISSION_OUTCOMES)[number];
35
+ ok: boolean;
36
+ accepted: boolean | null;
37
+ duplicate: boolean;
38
+ retryable: boolean;
39
+ errorCode: "SUBMISSION_HANDLER_FAILED" | null;
40
+ serverTime: string;
41
+ };
6
42
  export type ScenarioChoiceCommand = {
7
43
  type: "ask_choice";
8
44
  inputRequestId: string;
9
45
  options: ScenarioChoiceOption[];
46
+ lifecycle?: ScenarioChoiceLifecycle;
10
47
  };
11
48
  export type ScenarioChoiceInput = {
12
49
  inputRequestId: string;
13
50
  optionId: string;
14
51
  clientEventId: string;
15
52
  };
53
+ export declare const parseScenarioChoiceLifecycle: (value: unknown) => ScenarioChoiceLifecycle | null;
54
+ export declare const parseScenarioChoiceLifecycleChanged: (value: unknown) => ScenarioChoiceLifecycleChanged | null;
55
+ export declare const parseScenarioChoiceSubmissionResult: (value: unknown) => ScenarioChoiceSubmissionResult | null;
56
+ export declare const applyScenarioChoiceLifecycle: (message: MessageData, event: ScenarioChoiceLifecycleChanged) => MessageData;
57
+ export declare const projectScenarioChoiceLifecycle: (message: MessageData, inputRequestId: string, lifecycle: ScenarioChoiceLifecycle) => MessageData;
58
+ export declare const isScenarioChoiceAvailable: (choice: ScenarioChoiceCommand, now?: number) => boolean;
59
+ export declare const getScenarioChoiceRemainingMs: (choice: ScenarioChoiceCommand, now?: number) => number | null;
16
60
  export declare const getScenarioChoice: (message: MessageData) => ScenarioChoiceCommand | null;
17
- export declare const getLatestScenarioChoice: (messages: MessageData[]) => ScenarioChoiceCommand | null;
61
+ export declare const getLatestScenarioChoice: (messages: MessageData[], now?: number) => ScenarioChoiceCommand | null;
@@ -0,0 +1,55 @@
1
+ import type { AppApi } from "@/App";
2
+ import type { WidgetConfig } from "@/index.types";
3
+ import { type PresentationAvatarGrant } from "./support-presentation-avatar.api";
4
+ import type { PresentationAvatarAsset } from "./support-presentation.types";
5
+ export type PresentationAvatarRequest = Readonly<{
6
+ conversationId: string;
7
+ asset: PresentationAvatarAsset;
8
+ }>;
9
+ export type ResolvedPresentationAvatar = Readonly<{
10
+ url: string;
11
+ expiresAt: string;
12
+ }>;
13
+ type FetchGrant = (config: WidgetConfig, api: AppApi, conversationId: string, asset: PresentationAvatarAsset, signal?: AbortSignal) => Promise<PresentationAvatarGrant>;
14
+ type ResolverOptions = Readonly<{
15
+ fetchGrant?: FetchGrant;
16
+ now?: () => number;
17
+ sleep?: (milliseconds: number) => Promise<void>;
18
+ maxConcurrent?: number;
19
+ maxEntries?: number;
20
+ maxQueued?: number;
21
+ }>;
22
+ export declare class PresentationAvatarResolver {
23
+ private config;
24
+ private api;
25
+ private readonly fetchGrant;
26
+ private readonly now;
27
+ private readonly sleep;
28
+ private readonly maxConcurrent;
29
+ private readonly maxEntries;
30
+ private readonly maxQueued;
31
+ private readonly cache;
32
+ private readonly inFlight;
33
+ private readonly controllers;
34
+ private readonly queue;
35
+ private readonly authorityListeners;
36
+ private readonly conversationEpochs;
37
+ private activeCount;
38
+ private generation;
39
+ constructor(config: WidgetConfig, api: AppApi, options?: ResolverOptions);
40
+ resolve(request: PresentationAvatarRequest): Promise<ResolvedPresentationAvatar | null>;
41
+ private drainQueue;
42
+ private trimCache;
43
+ private loadGrant;
44
+ replaceSession(config: WidgetConfig, api: AppApi): void;
45
+ destroy(): void;
46
+ invalidate(request: PresentationAvatarRequest): void;
47
+ purgeConversation(conversationId: string): void;
48
+ subscribeAuthority: (listener: () => void) => (() => void);
49
+ getAuthoritySnapshot(conversationId: string): string;
50
+ private purgeKey;
51
+ private resetAuthority;
52
+ private notifyAuthorityChange;
53
+ private key;
54
+ }
55
+ export {};
@@ -0,0 +1,12 @@
1
+ import type { AppApi } from "@/App";
2
+ import type { WidgetConfig } from "@/index.types";
3
+ import { type PropsWithChildren } from "react";
4
+ import { PresentationAvatarResolver } from "./PresentationAvatarResolver";
5
+ type SupportPresentationProviderProps = PropsWithChildren<{
6
+ config: WidgetConfig;
7
+ api: AppApi;
8
+ authorizedConversationIds?: readonly string[];
9
+ resolver?: PresentationAvatarResolver;
10
+ }>;
11
+ export declare function SupportPresentationProvider({ children, config, api, authorizedConversationIds, resolver: suppliedResolver, }: SupportPresentationProviderProps): import("react/jsx-runtime").JSX.Element;
12
+ export {};
@@ -0,0 +1 @@
1
+ export declare function presentationInitials(displayName: string): string;
@@ -0,0 +1,13 @@
1
+ import type { AppApi } from "@/App";
2
+ import type { WidgetConfig } from "@/index.types";
3
+ import type { PresentationAvatarAsset } from "./support-presentation.types";
4
+ export type PresentationAvatarGrant = Readonly<{
5
+ assetId: string;
6
+ assetVersion: number;
7
+ url: string;
8
+ expiresAt: string;
9
+ }>;
10
+ export declare class PresentationAvatarContractError extends Error {
11
+ constructor();
12
+ }
13
+ export declare function getPresentationAvatarGrant(config: WidgetConfig, api: AppApi, conversationId: string, asset: PresentationAvatarAsset, signal?: AbortSignal): Promise<PresentationAvatarGrant>;
@@ -0,0 +1,9 @@
1
+ import type { PresentationAvatarResolver } from "./PresentationAvatarResolver";
2
+ type SupportPresentationContextValue = {
3
+ resolver: PresentationAvatarResolver;
4
+ authorizedConversationIds: ReadonlySet<string> | null;
5
+ };
6
+ export declare const SupportPresentationContext: import("react").Context<SupportPresentationContextValue | null>;
7
+ export declare const usePresentationAvatarResolver: () => PresentationAvatarResolver | null;
8
+ export declare const usePresentationAvatarAuthorization: (conversationId: string) => boolean;
9
+ export {};
@@ -0,0 +1,8 @@
1
+ export type SupportPresentationObservation = Readonly<{
2
+ contractVersion: 1;
3
+ signal: "GRANT" | "RESOLVER" | "PROJECTION";
4
+ outcome: "CACHE_HIT" | "EXPIRED" | "REFRESHED" | "FALLBACK" | "REST_REALTIME_MISMATCH" | "REST_RECONCILED";
5
+ }>;
6
+ export declare const SUPPORT_PRESENTATION_OBSERVATION_EVENT = "lola:support-presentation-observation";
7
+ /** Emits a bounded, identifier-free operational signal for the host telemetry bridge. */
8
+ export declare function reportSupportPresentationObservation(observation: SupportPresentationObservation): void;
@@ -0,0 +1,54 @@
1
+ export type PresentationAvatarAsset = Readonly<{
2
+ id: string;
3
+ version: number;
4
+ }>;
5
+ export type MessageAuthorPresentation = Readonly<{
6
+ displayName: string;
7
+ avatarAsset: PresentationAvatarAsset | null;
8
+ presentationVersion: number | null;
9
+ legacyAvatarUrl: string | null;
10
+ }>;
11
+ export declare const RESPONDER_MODES: readonly ["LOLA", "SUPPORT_REQUESTED", "SUPPORT_LIVE", "SUPPORT_AWAY", "LOLA_SUSPENDED"];
12
+ export type ResponderMode = (typeof RESPONDER_MODES)[number];
13
+ export type ResponderIdentity = "LOLA" | "SUPPORT";
14
+ export type ResponderSourceRevisions = Readonly<{
15
+ conversationUpdatedAt: string;
16
+ escalationVersionSum: string;
17
+ escalationUpdatedAt: string | null;
18
+ aiSuspensionVersion: string | null;
19
+ aiSuspensionUpdatedAt: string | null;
20
+ lolaPresentationVersion: number | null;
21
+ operatorPresentationVersion: number | null;
22
+ avatarAssetUpdatedAt: string | null;
23
+ }>;
24
+ export type ResponderPresentation = Readonly<{
25
+ schemaVersion: 1;
26
+ mode: ResponderMode;
27
+ identity: ResponderIdentity;
28
+ displayName: string;
29
+ avatarAsset: PresentationAvatarAsset | null;
30
+ presentationVersion: number | null;
31
+ revision: string;
32
+ sourceRevisions: ResponderSourceRevisions;
33
+ refreshAt: string | null;
34
+ serverTime: string;
35
+ }>;
36
+ export type SafeResponderPresentation = Readonly<{
37
+ contractState: "CURRENT" | "LEGACY" | "INCOMPATIBLE";
38
+ schemaVersion: 0 | 1;
39
+ mode: ResponderMode | "UNKNOWN";
40
+ identity: ResponderIdentity;
41
+ displayName: string | null;
42
+ avatarAsset: PresentationAvatarAsset | null;
43
+ presentationVersion: number | null;
44
+ revision: string;
45
+ sourceRevisions: ResponderSourceRevisions | null;
46
+ refreshAt: string | null;
47
+ serverTime: string | null;
48
+ }>;
49
+ export declare const LEGACY_RESPONDER_PRESENTATION: SafeResponderPresentation;
50
+ export declare const INCOMPATIBLE_RESPONDER_PRESENTATION: SafeResponderPresentation;
51
+ export declare function parseMessageAuthorPresentation(value: unknown): MessageAuthorPresentation | null;
52
+ export declare function parseResponderPresentation(value: unknown): ResponderPresentation | null;
53
+ export declare function normalizeResponderPresentation(value: unknown): SafeResponderPresentation;
54
+ export declare function getResponderRefreshDelay(presentation: SafeResponderPresentation): number | null;
@@ -22,6 +22,16 @@ declare const en: {
22
22
  readonly avatar: {
23
23
  readonly gettingReady: "Lola is getting ready…";
24
24
  };
25
+ readonly identity: {
26
+ readonly support: "Support";
27
+ readonly system: "System";
28
+ readonly aiAssistant: "AI assistant";
29
+ readonly waiting: "Waiting for a specialist";
30
+ readonly live: "Specialist is here";
31
+ readonly away: "We’ll reply here";
32
+ readonly paused: "AI is paused";
33
+ readonly unavailable: "Support status unavailable";
34
+ };
25
35
  readonly chat: {
26
36
  readonly back: "Back to chat";
27
37
  readonly listTitle: "Chats";