mcp-chat-ui 1.0.3 → 1.0.6

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/README.md CHANGED
@@ -78,6 +78,7 @@ const initConfig = {
78
78
  initializeChat: false,
79
79
  showInitPanel: true,
80
80
  contextWindow: "ComposeRequest",
81
+ initializeMessage: "",
81
82
  };
82
83
 
83
84
  Init(initConfig);
@@ -115,19 +116,10 @@ import { FinalizeSession } from "mcp-chat-ui";
115
116
  await FinalizeSession({
116
117
  domain: "dab.ae",
117
118
  token: "Bearer <token>",
119
+ sessionId: "<session-id>",
118
120
  });
119
121
  ```
120
-
121
- Initialize a session with service/request IDs (one-time per session):
122
-
123
- ```ts
124
- import { InitializeChatSession } from "mcp-chat-ui";
125
-
126
- await InitializeChatSession({
127
- initServiceId: 1001,
128
- initRequestStepId: 2001,
129
- });
130
- ```
122
+ If `sessionId` is omitted, the SDK uses the stored session ID.
131
123
 
132
124
  ## Service Base URL
133
125
 
@@ -141,13 +133,11 @@ await InitializeChatSession({
141
133
  - `apiSubscriptionKey` is sent to the login endpoint (or override with `loginSubscriptionKey`).
142
134
  - `token` is required in `Init` (use an empty string if you plan to sign in via the
143
135
  panel and let it set the token).
144
- - `initializeChat: true` triggers the init flow on load and calls
145
- `initializeChatClients` only (cache setup).
146
- - `InitializeChatSession` calls `initializeChat` only. Messages are blocked until
147
- it runs once per session.
148
- - The login panel runs `initializeChatClients` followed by `InitializeChatSession`.
149
- - If `initializeChat` is `false`, call `InitializeChatSession` manually after
150
- login (or before rendering the view) to enable messaging.
136
+ - `initializeChat: true` triggers `initializeChat` in `ChatUI` before the chat
137
+ renders (shows a loading state with retry).
138
+ - The login panel runs `initializeChatClients` followed by `initializeChat`.
139
+ - If `initializeChat` is `false`, the chat waits until the user initializes from
140
+ the login panel.
151
141
 
152
142
  ## Login From The UI
153
143
 
@@ -179,9 +169,11 @@ Init (global):
179
169
  - `showInitPanel` (optional, default `true`)
180
170
  - `initializeChat` (required)
181
171
  - `contextWindow` (required)
172
+ - `initializeMessage` (optional): initial message passed to `initializeChat`.
182
173
 
183
174
  ChatUI props (view):
184
175
  - `initServiceId`, `initRequestStepId`
176
+ - `contextWindow`, `domain`, `token`, `initializeMessage`
185
177
  - `initPresets`: optional `{ requester, provider }` credentials used to prefill the preset buttons.
186
178
  - `speechRegion`, `speechKey`
187
179
  - `speechLanguage` (transcription)
@@ -191,6 +183,8 @@ ChatUI props (view):
191
183
  - `fonts`: `{ base, heading, mono }`.
192
184
  - `text`: UI strings (login panel text is fixed and not configurable).
193
185
  - `taskCardSize`: `{ width?: number; height?: number }` for task cards in the chat list.
186
+ - `onRequestAdded`: called when `AddRequestToolResult` is a non-empty object.
187
+ - `onRequestProcessed`: called when `ProcessRequestToolResult` is a non-empty object.
194
188
 
195
189
  ## Theme Tokens
196
190
 
package/dist/ChatUI.js CHANGED
@@ -87,6 +87,11 @@ const formatText = (template, values) => template.replace(/\{(\w+)\}/g, (_, key)
87
87
  const value = values[key];
88
88
  return value === undefined ? "" : String(value);
89
89
  });
90
+ const isNonEmptyObject = (value) => {
91
+ if (!value || typeof value !== "object" || Array.isArray(value))
92
+ return false;
93
+ return Object.keys(value).length > 0;
94
+ };
90
95
  function normalizeTheme(theme) {
91
96
  var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9;
92
97
  return {
@@ -130,7 +135,7 @@ function normalizeTheme(theme) {
130
135
  };
131
136
  }
132
137
  function ChatUI(props) {
133
- var _a, _b, _c, _d, _e, _f, _g, _h, _j;
138
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
134
139
  const sdkConfig = (0, sdkUtilities_1.GetConfig)();
135
140
  const theme = (0, react_1.useMemo)(() => {
136
141
  var _a;
@@ -199,7 +204,7 @@ function ChatUI(props) {
199
204
  const normalizeServiceBaseUrl = (value) => (value !== null && value !== void 0 ? value : "").trim().replace(/\/+$/, "");
200
205
  const [isDab, setIsDab] = (0, react_1.useState)(() => { var _a; return (_a = sdkConfig.isDab) !== null && _a !== void 0 ? _a : false; });
201
206
  const defaultDomain = isDab ? chatDefaults_1.DEFAULT_DOMAIN : "";
202
- const [domain, setDomain] = (0, react_1.useState)(() => defaultDomain);
207
+ const [domain, setDomain] = (0, react_1.useState)(() => { var _a; return ((_a = props.domain) !== null && _a !== void 0 ? _a : localStorage_1.ls.get(storageKeys_1.STORAGE_KEYS.domain, defaultDomain)).trim(); });
203
208
  const [serviceBaseUrl, setServiceBaseUrl] = (0, react_1.useState)(() => {
204
209
  var _a;
205
210
  return normalizeServiceBaseUrl((_a = sdkConfig.baseUrl) !== null && _a !== void 0 ? _a : localStorage_1.ls.get(storageKeys_1.STORAGE_KEYS.serviceBaseUrl, chatDefaults_1.DEFAULT_SERVICE_BASE_URL));
@@ -248,22 +253,41 @@ function ChatUI(props) {
248
253
  const speechRegion = (_a = props.speechRegion) !== null && _a !== void 0 ? _a : chatDefaults_1.DEFAULT_SPEECH_REGION;
249
254
  const speechKey = (_b = props.speechKey) !== null && _b !== void 0 ? _b : chatDefaults_1.DEFAULT_SPEECH_KEY;
250
255
  const initializeChatOnLoad = (_c = sdkConfig.initializeChat) !== null && _c !== void 0 ? _c : false;
251
- const initPanelEnabled = (_d = sdkConfig.showInitPanel) !== null && _d !== void 0 ? _d : true;
256
+ const initializeLanguage = ((_d = sdkConfig.initializeLanguage) !== null && _d !== void 0 ? _d : "").trim() || "ar-JO";
257
+ const initializeMessage = ((_f = (_e = props.initializeMessage) !== null && _e !== void 0 ? _e : sdkConfig.initializeMessage) !== null && _f !== void 0 ? _f : "")
258
+ .trim();
259
+ const initPanelEnabled = (_g = sdkConfig.showInitPanel) !== null && _g !== void 0 ? _g : true;
252
260
  // Connection / auth
253
261
  const apiBase = chatDefaults_1.DEFAULT_API_BASE;
254
262
  const apiKey = chatDefaults_1.DEFAULT_API_KEY;
255
- const [authToken, setAuthToken] = (0, react_1.useState)(() => { var _a; return normalizeAuthToken((_a = sdkConfig.token) !== null && _a !== void 0 ? _a : localStorage_1.ls.get(storageKeys_1.STORAGE_KEYS.authToken, "")); });
263
+ const [authToken, setAuthToken] = (0, react_1.useState)(() => {
264
+ var _a, _b;
265
+ return normalizeAuthToken((_b = (_a = props.token) !== null && _a !== void 0 ? _a : sdkConfig.token) !== null && _b !== void 0 ? _b : localStorage_1.ls.get(storageKeys_1.STORAGE_KEYS.authToken, ""));
266
+ });
267
+ const lastStoredAuthTokenRef = (0, react_1.useRef)(normalizeAuthToken(localStorage_1.ls.get(storageKeys_1.STORAGE_KEYS.authToken, "")));
268
+ const tokenChangedRef = (0, react_1.useRef)(false);
256
269
  const [sessionId, setSessionId] = (0, react_1.useState)(() => localStorage_1.ls.get(storageKeys_1.STORAGE_KEYS.sessionId, (0, generateGuid_1.generateGuid)()));
257
270
  const [initCompleted, setInitCompleted] = (0, react_1.useState)(() => localStorage_1.ls.get((0, storageKeys_1.getInitCompletedKey)(sessionId), false));
258
- (0, react_1.useEffect)(() => localStorage_1.ls.set(storageKeys_1.STORAGE_KEYS.authToken, authToken), [authToken]);
271
+ (0, react_1.useEffect)(() => {
272
+ if (props.token !== undefined) {
273
+ setAuthToken(normalizeAuthToken(props.token));
274
+ }
275
+ }, [props.token]);
276
+ (0, react_1.useEffect)(() => {
277
+ const normalized = normalizeAuthToken(authToken);
278
+ const prevStored = lastStoredAuthTokenRef.current;
279
+ tokenChangedRef.current = !!normalized && normalized !== prevStored;
280
+ localStorage_1.ls.set(storageKeys_1.STORAGE_KEYS.authToken, normalized);
281
+ lastStoredAuthTokenRef.current = normalized;
282
+ }, [authToken]);
259
283
  (0, react_1.useEffect)(() => localStorage_1.ls.set(storageKeys_1.STORAGE_KEYS.sessionId, sessionId), [sessionId]);
260
284
  (0, react_1.useEffect)(() => {
261
285
  setInitCompleted(localStorage_1.ls.get((0, storageKeys_1.getInitCompletedKey)(sessionId), false));
262
286
  }, [sessionId]);
263
287
  // context window selection (used for initializeChat and WS messages)
264
288
  const [contextWindow, setContextWindow] = (0, react_1.useState)(() => {
265
- var _a;
266
- return (_a = sdkConfig.contextWindow) !== null && _a !== void 0 ? _a : localStorage_1.ls.get(storageKeys_1.STORAGE_KEYS.contextWindow, chatDefaults_1.DEFAULT_CONTEXT_WINDOW);
289
+ var _a, _b;
290
+ return (_b = (_a = props.contextWindow) !== null && _a !== void 0 ? _a : sdkConfig.contextWindow) !== null && _b !== void 0 ? _b : localStorage_1.ls.get(storageKeys_1.STORAGE_KEYS.contextWindow, chatDefaults_1.DEFAULT_CONTEXT_WINDOW);
267
291
  });
268
292
  (0, react_1.useEffect)(() => localStorage_1.ls.set(storageKeys_1.STORAGE_KEYS.contextWindow, contextWindow), [contextWindow]);
269
293
  // Real-time speech language (for transcription)
@@ -311,13 +335,15 @@ function ChatUI(props) {
311
335
  const [selectedFiles, setSelectedFiles] = (0, react_1.useState)([]);
312
336
  // init panel
313
337
  const resolvedInitUsername = localStorage_1.ls.get(storageKeys_1.STORAGE_KEYS.initUsername, "");
314
- const resolvedInitServiceId = (_e = props.initServiceId) !== null && _e !== void 0 ? _e : "";
315
- const resolvedInitRequestStepId = (_f = props.initRequestStepId) !== null && _f !== void 0 ? _f : "";
338
+ const resolvedInitServiceId = (_h = props.initServiceId) !== null && _h !== void 0 ? _h : "";
339
+ const resolvedInitRequestStepId = (_j = props.initRequestStepId) !== null && _j !== void 0 ? _j : "";
316
340
  const [showInitPanel, setShowInitPanel] = (0, react_1.useState)(false);
317
- const [initPreset, setInitPreset] = (0, react_1.useState)((_g = props.initialInitPreset) !== null && _g !== void 0 ? _g : "custom");
341
+ const [initPreset, setInitPreset] = (0, react_1.useState)((_k = props.initialInitPreset) !== null && _k !== void 0 ? _k : "custom");
318
342
  const [initUsername, setInitUsername] = (0, react_1.useState)(resolvedInitUsername);
319
343
  const [initPassword, setInitPassword] = (0, react_1.useState)("");
320
344
  const [initLoading, setInitLoading] = (0, react_1.useState)(false);
345
+ const [initGateLoading, setInitGateLoading] = (0, react_1.useState)(false);
346
+ const [initGateError, setInitGateError] = (0, react_1.useState)(null);
321
347
  // Init panel extra fields per new API
322
348
  const [initContextWindow, setInitContextWindow] = (0, react_1.useState)(contextWindow);
323
349
  const [initServiceId, setInitServiceId] = (0, react_1.useState)(resolvedInitServiceId === undefined || resolvedInitServiceId === null
@@ -326,12 +352,21 @@ function ChatUI(props) {
326
352
  const [initRequestStepId, setInitRequestStepId] = (0, react_1.useState)(resolvedInitRequestStepId === undefined || resolvedInitRequestStepId === null
327
353
  ? ""
328
354
  : String(resolvedInitRequestStepId));
329
- // Initializing message was removed from the backend (kept only for chat + speech features).
330
355
  (0, react_1.useEffect)(() => localStorage_1.ls.set(storageKeys_1.STORAGE_KEYS.initUsername, initUsername), [initUsername]);
331
356
  (0, react_1.useEffect)(() => localStorage_1.ls.set(storageKeys_1.STORAGE_KEYS.domain, domain), [domain]);
332
357
  (0, react_1.useEffect)(() => {
358
+ if (props.domain !== undefined) {
359
+ setDomain(props.domain);
360
+ return;
361
+ }
333
362
  setDomain(isDab ? chatDefaults_1.DEFAULT_DOMAIN : "");
334
- }, [isDab]);
363
+ }, [isDab, props.domain]);
364
+ (0, react_1.useEffect)(() => {
365
+ if (props.contextWindow !== undefined) {
366
+ setContextWindow(props.contextWindow);
367
+ setInitContextWindow(props.contextWindow);
368
+ }
369
+ }, [props.contextWindow]);
335
370
  (0, react_1.useEffect)(() => {
336
371
  if (props.initServiceId !== undefined) {
337
372
  setInitServiceId(String(props.initServiceId));
@@ -511,20 +546,24 @@ function ChatUI(props) {
511
546
  const autoInitAttemptedRef = (0, react_1.useRef)(false);
512
547
  const autoInitConfigKey = (0, react_1.useMemo)(() => [
513
548
  initializeChatOnLoad ? "1" : "0",
549
+ authToken,
514
550
  initUsername,
515
551
  initPassword,
516
552
  domain,
517
553
  initContextWindow,
518
554
  initServiceId,
519
555
  initRequestStepId,
556
+ initializeMessage,
520
557
  ].join("|"), [
521
558
  initializeChatOnLoad,
559
+ authToken,
522
560
  initUsername,
523
561
  initPassword,
524
562
  domain,
525
563
  initContextWindow,
526
564
  initServiceId,
527
565
  initRequestStepId,
566
+ initializeMessage,
528
567
  ]);
529
568
  // TTS state
530
569
  const ttsSynthRef = (0, react_1.useRef)(null);
@@ -544,25 +583,58 @@ function ChatUI(props) {
544
583
  (0, react_1.useEffect)(() => {
545
584
  autoInitAttemptedRef.current = false;
546
585
  }, [autoInitConfigKey]);
586
+ const runAutoInitialize = () => __awaiter(this, void 0, void 0, function* () {
587
+ var _a;
588
+ setInitGateError(null);
589
+ setInitGateLoading(true);
590
+ try {
591
+ const authHeader = authToken === null || authToken === void 0 ? void 0 : authToken.trim();
592
+ if (!authHeader) {
593
+ setInitGateError(text.alerts.initMissingCredentials);
594
+ return;
595
+ }
596
+ const tokenChanged = tokenChangedRef.current;
597
+ const sessionIdOverride = tokenChanged
598
+ ? resetLocalStateForNewToken(authHeader)
599
+ : undefined;
600
+ yield initializeChatClients(authHeader);
601
+ if (tokenChanged) {
602
+ const initResult = yield initializeChatWithParams(authHeader, {
603
+ silent: true,
604
+ sessionIdOverride,
605
+ });
606
+ if (!initResult.ok) {
607
+ setInitGateError((_a = initResult.error) !== null && _a !== void 0 ? _a : text.alerts.initFailed);
608
+ }
609
+ }
610
+ else if (!initCompleted) {
611
+ localStorage_1.ls.set((0, storageKeys_1.getInitCompletedKey)(sessionId), true);
612
+ setInitCompleted(true);
613
+ }
614
+ }
615
+ finally {
616
+ setInitGateLoading(false);
617
+ }
618
+ });
547
619
  (0, react_1.useEffect)(() => {
548
- const shouldAutoInit = initializeChatOnLoad;
549
- if (!shouldAutoInit || initLoading || initCompleted)
550
- return;
551
- if (!authToken && (!initUsername.trim() || !initPassword))
620
+ const shouldAutoInit = initializeChatOnLoad && !!authToken;
621
+ if (!shouldAutoInit || initLoading)
552
622
  return;
553
623
  if (autoInitAttemptedRef.current)
554
624
  return;
555
625
  autoInitAttemptedRef.current = true;
556
- void initializeSession({ runInitializeChatClients: true });
626
+ void runAutoInitialize();
557
627
  }, [
558
628
  initializeChatOnLoad,
559
629
  authToken,
560
630
  initLoading,
561
631
  initCompleted,
562
- initUsername,
563
- initPassword,
564
632
  autoInitConfigKey,
565
633
  ]);
634
+ const handleInitRetry = () => {
635
+ autoInitAttemptedRef.current = false;
636
+ void runAutoInitialize();
637
+ };
566
638
  // auto scroll
567
639
  (0, react_1.useEffect)(() => {
568
640
  var _a;
@@ -663,6 +735,8 @@ function ChatUI(props) {
663
735
  !!apiBase &&
664
736
  !!apiKey &&
665
737
  !pending, [input, selectedFiles, sessionId, apiBase, apiKey, pending]);
738
+ const shouldDockComposer = pending || messages.length > 0;
739
+ const isEmptyState = messages.length === 0 && !pending;
666
740
  function autosizeTextarea(el) {
667
741
  if (!el)
668
742
  return;
@@ -672,7 +746,7 @@ function ChatUI(props) {
672
746
  (0, react_1.useEffect)(() => {
673
747
  autosizeTextarea(composerRef.current);
674
748
  }, [input]);
675
- const signatureAlias = (_j = (_h = activeTaskCard === null || activeTaskCard === void 0 ? void 0 : activeTaskCard.MetaData) === null || _h === void 0 ? void 0 : _h.SignatureAttributeAlias) !== null && _j !== void 0 ? _j : null;
749
+ const signatureAlias = (_m = (_l = activeTaskCard === null || activeTaskCard === void 0 ? void 0 : activeTaskCard.MetaData) === null || _l === void 0 ? void 0 : _l.SignatureAttributeAlias) !== null && _m !== void 0 ? _m : null;
676
750
  const visibleTakeActionAttributes = (0, react_1.useMemo)(() => {
677
751
  return takeActionAttributes
678
752
  .filter((attr) => attr.IsProviderVisible)
@@ -980,7 +1054,7 @@ function ChatUI(props) {
980
1054
  // send message via HTTP (no streaming)
981
1055
  function sendMessage() {
982
1056
  return __awaiter(this, void 0, void 0, function* () {
983
- var _a, _b;
1057
+ var _a, _b, _c, _d;
984
1058
  const selectedTask = selectedTaskCard;
985
1059
  if (selectedTask) {
986
1060
  setSelectedTaskCard(null);
@@ -1048,7 +1122,7 @@ function ChatUI(props) {
1048
1122
  try {
1049
1123
  details = yield sasRes.text();
1050
1124
  }
1051
- catch (_c) { }
1125
+ catch (_e) { }
1052
1126
  throw new Error(formatText(text.errors.sasRequestFailedTemplate, {
1053
1127
  status: sasRes.status,
1054
1128
  statusText: sasRes.statusText,
@@ -1105,7 +1179,7 @@ function ChatUI(props) {
1105
1179
  try {
1106
1180
  msg = yield chatRes.text();
1107
1181
  }
1108
- catch (_d) { }
1182
+ catch (_f) { }
1109
1183
  throw new Error(formatText(text.errors.chatFailedTemplate, {
1110
1184
  status: chatRes.status,
1111
1185
  statusText: chatRes.statusText,
@@ -1117,11 +1191,11 @@ function ChatUI(props) {
1117
1191
  try {
1118
1192
  raw = yield chatRes.json();
1119
1193
  }
1120
- catch (_e) {
1194
+ catch (_g) {
1121
1195
  try {
1122
1196
  rawText = yield chatRes.text();
1123
1197
  }
1124
- catch (_f) { }
1198
+ catch (_h) { }
1125
1199
  }
1126
1200
  const assistantText = (typeof (raw === null || raw === void 0 ? void 0 : raw.AIMessage) === "string" && raw.AIMessage) ||
1127
1201
  (typeof (raw === null || raw === void 0 ? void 0 : raw.AssistantMessage) === "string" && raw.AssistantMessage) ||
@@ -1143,6 +1217,16 @@ function ChatUI(props) {
1143
1217
  ? raw.Profile.UserSignatures
1144
1218
  : [];
1145
1219
  setUserSignatures(signatures);
1220
+ const addRequestResult = raw === null || raw === void 0 ? void 0 : raw.AddRequestToolResult;
1221
+ const processRequestResult = raw === null || raw === void 0 ? void 0 : raw.ProcessRequestToolResult;
1222
+ const hasAddRequest = isNonEmptyObject(addRequestResult);
1223
+ const hasProcessRequest = isNonEmptyObject(processRequestResult);
1224
+ if (hasAddRequest) {
1225
+ (_c = props.onRequestAdded) === null || _c === void 0 ? void 0 : _c.call(props, addRequestResult);
1226
+ }
1227
+ if (hasProcessRequest) {
1228
+ (_d = props.onRequestProcessed) === null || _d === void 0 ? void 0 : _d.call(props, processRequestResult);
1229
+ }
1146
1230
  if (typeof (raw === null || raw === void 0 ? void 0 : raw.ToolResult) !== "undefined" && (raw === null || raw === void 0 ? void 0 : raw.ToolResult) !== null) {
1147
1231
  setLastToolResult(raw.ToolResult);
1148
1232
  }
@@ -1569,31 +1653,117 @@ function ChatUI(props) {
1569
1653
  console.warn("Download failed:", e);
1570
1654
  }
1571
1655
  };
1656
+ const getInitChatErrorMessage = (err) => {
1657
+ var _a, _b;
1658
+ const msg = ((_a = err === null || err === void 0 ? void 0 : err.message) === null || _a === void 0 ? void 0 : _a.includes("Failed to fetch")) || ((_b = err === null || err === void 0 ? void 0 : err.message) === null || _b === void 0 ? void 0 : _b.includes("Network"))
1659
+ ? text.alerts.initChatNetworkError
1660
+ : (err === null || err === void 0 ? void 0 : err.message) || String(err);
1661
+ return formatText(text.alerts.initChatErrorTemplate, { error: msg });
1662
+ };
1663
+ const resetLocalStateForNewToken = (nextToken) => {
1664
+ const normalized = normalizeAuthToken(nextToken);
1665
+ localStorage_1.ls.removeByPrefix(storageKeys_1.STORAGE_KEYS.messagesPrefix);
1666
+ localStorage_1.ls.removeByPrefix(storageKeys_1.STORAGE_KEYS.initCompletedPrefix);
1667
+ localStorage_1.ls.remove(storageKeys_1.STORAGE_KEYS.serviceBaseUrl);
1668
+ localStorage_1.ls.remove(storageKeys_1.STORAGE_KEYS.apiSubscriptionKey);
1669
+ localStorage_1.ls.remove(storageKeys_1.STORAGE_KEYS.loginSubscriptionKey);
1670
+ localStorage_1.ls.remove(storageKeys_1.STORAGE_KEYS.sessionId);
1671
+ localStorage_1.ls.remove(storageKeys_1.STORAGE_KEYS.authToken);
1672
+ localStorage_1.ls.remove(storageKeys_1.STORAGE_KEYS.contextWindow);
1673
+ localStorage_1.ls.remove(storageKeys_1.STORAGE_KEYS.initUsername);
1674
+ localStorage_1.ls.remove(storageKeys_1.STORAGE_KEYS.domain);
1675
+ localStorage_1.ls.remove(storageKeys_1.STORAGE_KEYS.speechLang);
1676
+ localStorage_1.ls.remove(storageKeys_1.STORAGE_KEYS.ttsLang);
1677
+ setMessages([]);
1678
+ setInput("");
1679
+ setSelectedFiles([]);
1680
+ setLastToolResult(null);
1681
+ setShowToolOverlay(false);
1682
+ setPending(false);
1683
+ const newSessionId = (0, generateGuid_1.generateGuid)();
1684
+ setSessionId(newSessionId);
1685
+ localStorage_1.ls.set(storageKeys_1.STORAGE_KEYS.sessionId, newSessionId);
1686
+ localStorage_1.ls.set(storageKeys_1.STORAGE_KEYS.authToken, normalized);
1687
+ localStorage_1.ls.set((0, storageKeys_1.getInitCompletedKey)(newSessionId), false);
1688
+ setInitCompleted(false);
1689
+ lastStoredAuthTokenRef.current = normalized;
1690
+ tokenChangedRef.current = false;
1691
+ return newSessionId;
1692
+ };
1572
1693
  // Initialize session (login), initializeChatClients, and optionally initializeChat
1573
- function initializeChatWithParams(tokenOverride) {
1574
- return __awaiter(this, void 0, void 0, function* () {
1575
- var _a, _b;
1694
+ function initializeChatWithParams(tokenOverride_1) {
1695
+ return __awaiter(this, arguments, void 0, function* (tokenOverride, options = {}) {
1696
+ var _a, _b, _c;
1576
1697
  try {
1577
- const result = yield (0, sdkUtilities_1.InitializeChatSession)({
1578
- initServiceId: initServiceId || undefined,
1579
- initRequestStepId: initRequestStepId || undefined,
1580
- contextWindow: initContextWindow || contextWindow,
1581
- domain,
1582
- token: tokenOverride !== null && tokenOverride !== void 0 ? tokenOverride : authToken,
1698
+ const normalizedToken = normalizeAuthToken(tokenOverride !== null && tokenOverride !== void 0 ? tokenOverride : authToken);
1699
+ if (!normalizedToken) {
1700
+ throw new Error("Auth token is required to initialize chat.");
1701
+ }
1702
+ if (normalizedToken !== authToken) {
1703
+ setAuthToken(normalizedToken);
1704
+ localStorage_1.ls.set(storageKeys_1.STORAGE_KEYS.authToken, normalizedToken);
1705
+ }
1706
+ const activeSessionId = (_a = options.sessionIdOverride) !== null && _a !== void 0 ? _a : sessionId;
1707
+ const existingInit = localStorage_1.ls.get((0, storageKeys_1.getInitCompletedKey)(activeSessionId), false);
1708
+ if (existingInit) {
1709
+ setInitCompleted(true);
1710
+ return { ok: true };
1711
+ }
1712
+ const sessionDomain = ((_b = props.domain) !== null && _b !== void 0 ? _b : domain).trim();
1713
+ const resolvedContextWindow = (initContextWindow || contextWindow || chatDefaults_1.DEFAULT_CONTEXT_WINDOW).trim() ||
1714
+ "ComposeRequest";
1715
+ const payload = {
1716
+ Domain: sessionDomain,
1717
+ ContextWindow: resolvedContextWindow,
1718
+ InitializeLangauge: initializeLanguage,
1719
+ };
1720
+ if (initializeMessage) {
1721
+ payload.InitializeMessage = initializeMessage;
1722
+ }
1723
+ if (initServiceId && initServiceId.trim() !== "") {
1724
+ const n = Number(initServiceId);
1725
+ if (!Number.isNaN(n))
1726
+ payload.ServiceId = n;
1727
+ }
1728
+ if (initRequestStepId && initRequestStepId.trim() !== "") {
1729
+ const n = Number(initRequestStepId);
1730
+ if (!Number.isNaN(n))
1731
+ payload.RequestStepId = n;
1732
+ }
1733
+ const initRes = yield fetch(new URL("/api/initializeChat", apiBase).toString(), {
1734
+ method: "POST",
1735
+ headers: {
1736
+ "Content-Type": "application/json",
1737
+ "api-key": apiKey,
1738
+ Authorization: normalizedToken,
1739
+ },
1740
+ credentials: "include",
1741
+ body: JSON.stringify(payload),
1583
1742
  });
1584
- if (result.initialized) {
1585
- if (result.sessionId && result.sessionId !== sessionId) {
1586
- setSessionId(result.sessionId);
1743
+ if (!initRes.ok) {
1744
+ let msg = "";
1745
+ try {
1746
+ msg = yield initRes.text();
1587
1747
  }
1588
- setInitCompleted(true);
1589
- localStorage_1.ls.set((0, storageKeys_1.getInitCompletedKey)(result.sessionId), true);
1748
+ catch (_d) { }
1749
+ throw new Error(`initializeChat failed: ${initRes.status} ${initRes.statusText}${msg ? ` - ${msg}` : ""}`);
1590
1750
  }
1751
+ const initPayload = yield initRes.json().catch(() => ({}));
1752
+ const resolvedSessionId = (_c = initPayload === null || initPayload === void 0 ? void 0 : initPayload.SessionId) !== null && _c !== void 0 ? _c : activeSessionId;
1753
+ if (resolvedSessionId && resolvedSessionId !== sessionId) {
1754
+ setSessionId(resolvedSessionId);
1755
+ localStorage_1.ls.set(storageKeys_1.STORAGE_KEYS.sessionId, resolvedSessionId);
1756
+ }
1757
+ localStorage_1.ls.set((0, storageKeys_1.getInitCompletedKey)(resolvedSessionId), true);
1758
+ setInitCompleted(true);
1759
+ return { ok: true, payload: initPayload };
1591
1760
  }
1592
1761
  catch (err) {
1593
- const msg = ((_a = err === null || err === void 0 ? void 0 : err.message) === null || _a === void 0 ? void 0 : _a.includes("Failed to fetch")) || ((_b = err === null || err === void 0 ? void 0 : err.message) === null || _b === void 0 ? void 0 : _b.includes("Network"))
1594
- ? text.alerts.initChatNetworkError
1595
- : (err === null || err === void 0 ? void 0 : err.message) || String(err);
1596
- alert(formatText(text.alerts.initChatErrorTemplate, { error: msg }));
1762
+ const formatted = getInitChatErrorMessage(err);
1763
+ if (!options.silent) {
1764
+ alert(formatted);
1765
+ }
1766
+ return { ok: false, error: formatted };
1597
1767
  }
1598
1768
  });
1599
1769
  }
@@ -1631,36 +1801,50 @@ function ChatUI(props) {
1631
1801
  return;
1632
1802
  const requestDomain = domain.trim();
1633
1803
  const authFromState = authToken === null || authToken === void 0 ? void 0 : authToken.trim();
1804
+ const storedToken = normalizeAuthToken(localStorage_1.ls.get(storageKeys_1.STORAGE_KEYS.authToken, ""));
1634
1805
  const hasCredentials = !!initUsername.trim() && !!initPassword;
1635
1806
  const shouldUseLogin = hasCredentials && !authFromState;
1807
+ const shouldAlert = !(options === null || options === void 0 ? void 0 : options.silent);
1636
1808
  if (!serviceBaseUrl) {
1637
- alert(text.alerts.initMissingBaseUrl);
1638
- return;
1809
+ if (shouldAlert) {
1810
+ alert(text.alerts.initMissingBaseUrl);
1811
+ }
1812
+ return { ok: false, error: text.alerts.initMissingBaseUrl };
1639
1813
  }
1640
1814
  if (!apiSubscriptionKey) {
1641
- alert(text.alerts.initMissingSubscriptionKey);
1642
- return;
1815
+ if (shouldAlert) {
1816
+ alert(text.alerts.initMissingSubscriptionKey);
1817
+ }
1818
+ return { ok: false, error: text.alerts.initMissingSubscriptionKey };
1643
1819
  }
1644
1820
  const resolvedLoginSubscriptionKey = loginSubscriptionKey || apiSubscriptionKey;
1645
1821
  if (!hasCredentials && !authFromState) {
1646
- alert(text.alerts.initMissingCredentials);
1647
- return;
1822
+ if (shouldAlert) {
1823
+ alert(text.alerts.initMissingCredentials);
1824
+ }
1825
+ return { ok: false, error: text.alerts.initMissingCredentials };
1648
1826
  }
1649
1827
  if (shouldUseLogin) {
1650
1828
  const username = initUsername.trim();
1651
1829
  const password = initPassword;
1652
1830
  if (!username || !password) {
1653
- alert(text.alerts.initMissingCredentials);
1654
- return;
1831
+ if (shouldAlert) {
1832
+ alert(text.alerts.initMissingCredentials);
1833
+ }
1834
+ return { ok: false, error: text.alerts.initMissingCredentials };
1655
1835
  }
1656
1836
  if (!initEndpoint) {
1657
- alert(text.alerts.initMissingEndpoint);
1658
- return;
1837
+ if (shouldAlert) {
1838
+ alert(text.alerts.initMissingEndpoint);
1839
+ }
1840
+ return { ok: false, error: text.alerts.initMissingEndpoint };
1659
1841
  }
1660
1842
  }
1661
1843
  setInitLoading(true);
1662
1844
  try {
1663
1845
  let authHeader = authFromState;
1846
+ let tokenChanged = false;
1847
+ let sessionIdOverride;
1664
1848
  if (shouldUseLogin) {
1665
1849
  const res = yield fetch(initEndpoint, {
1666
1850
  method: "POST",
@@ -1681,34 +1865,65 @@ function ChatUI(props) {
1681
1865
  }
1682
1866
  catch (_c) { }
1683
1867
  if (!res.ok) {
1684
- alert(text.alerts.initFailed);
1685
- return;
1868
+ if (shouldAlert) {
1869
+ alert(text.alerts.initFailed);
1870
+ }
1871
+ return { ok: false, error: text.alerts.initFailed };
1686
1872
  }
1687
1873
  const access = (_a = payload === null || payload === void 0 ? void 0 : payload.Result) === null || _a === void 0 ? void 0 : _a.Token;
1688
1874
  if (!access) {
1689
- alert(text.alerts.initNoToken);
1690
- return;
1875
+ if (shouldAlert) {
1876
+ alert(text.alerts.initNoToken);
1877
+ }
1878
+ return { ok: false, error: text.alerts.initNoToken };
1691
1879
  }
1692
1880
  authHeader = `Bearer ${access}`.trim();
1693
- setAuthToken(normalizeAuthToken(authHeader));
1694
- localStorage_1.ls.set(storageKeys_1.STORAGE_KEYS.authToken, authHeader);
1881
+ const normalized = normalizeAuthToken(authHeader);
1882
+ setAuthToken(normalized);
1695
1883
  localStorage_1.ls.set(storageKeys_1.STORAGE_KEYS.initUsername, initUsername.trim());
1884
+ authHeader = normalized;
1696
1885
  }
1697
1886
  setContextWindow(initContextWindow || "ComposeRequest");
1887
+ authHeader = normalizeAuthToken(authHeader);
1888
+ tokenChanged =
1889
+ !!authHeader && (authHeader !== storedToken || tokenChangedRef.current);
1890
+ if (tokenChanged) {
1891
+ sessionIdOverride = resetLocalStateForNewToken(authHeader);
1892
+ }
1893
+ else if (authHeader) {
1894
+ localStorage_1.ls.set(storageKeys_1.STORAGE_KEYS.authToken, authHeader);
1895
+ lastStoredAuthTokenRef.current = authHeader;
1896
+ tokenChangedRef.current = false;
1897
+ }
1698
1898
  if (options === null || options === void 0 ? void 0 : options.runInitializeChatClients) {
1699
1899
  yield initializeChatClients(authHeader);
1700
1900
  }
1701
- if (options === null || options === void 0 ? void 0 : options.runInitializeChat) {
1702
- yield initializeChatWithParams(authHeader);
1901
+ if ((options === null || options === void 0 ? void 0 : options.runInitializeChat) && tokenChanged) {
1902
+ const initResult = yield initializeChatWithParams(authHeader, {
1903
+ silent: options === null || options === void 0 ? void 0 : options.silent,
1904
+ sessionIdOverride,
1905
+ });
1906
+ if (!initResult.ok) {
1907
+ return { ok: false, error: initResult.error };
1908
+ }
1909
+ }
1910
+ else if ((options === null || options === void 0 ? void 0 : options.runInitializeChat) && !tokenChanged && !initCompleted) {
1911
+ localStorage_1.ls.set((0, storageKeys_1.getInitCompletedKey)(sessionId), true);
1912
+ setInitCompleted(true);
1703
1913
  }
1704
1914
  setShowInitPanel(false);
1705
1915
  setInitPassword("");
1916
+ return { ok: true };
1706
1917
  }
1707
1918
  catch (err) {
1708
1919
  const msg = ((_b = err === null || err === void 0 ? void 0 : err.message) === null || _b === void 0 ? void 0 : _b.includes("Failed to fetch"))
1709
1920
  ? text.alerts.initNetworkError
1710
1921
  : (err === null || err === void 0 ? void 0 : err.message) || String(err);
1711
- alert(formatText(text.alerts.initErrorTemplate, { error: msg }));
1922
+ const formatted = formatText(text.alerts.initErrorTemplate, { error: msg });
1923
+ if (shouldAlert) {
1924
+ alert(formatted);
1925
+ }
1926
+ return { ok: false, error: formatted };
1712
1927
  }
1713
1928
  finally {
1714
1929
  setInitLoading(false);
@@ -1743,7 +1958,13 @@ function ChatUI(props) {
1743
1958
  localStorage_1.ls.set((0, storageKeys_1.getInitCompletedKey)(newSessionId), false);
1744
1959
  });
1745
1960
  }
1746
- return ((0, jsx_runtime_1.jsxs)("div", { className: "chatui-root flex h-full w-full flex-col", style: themeVars, children: [(0, jsx_runtime_1.jsx)("style", { children: chatDefaults_1.CHATUI_THEME_CSS }), (0, jsx_runtime_1.jsx)(TopBar_1.default, { sessionId: sessionId, authToken: authToken, onClearChat: clearChat, onLogout: doLogout, onInitOpen: () => {
1961
+ const shouldGateView = initializeChatOnLoad && !!authToken && !initCompleted;
1962
+ if (shouldGateView) {
1963
+ return ((0, jsx_runtime_1.jsxs)("div", { className: "chatui-root flex h-full w-full flex-col", style: themeVars, children: [(0, jsx_runtime_1.jsx)("style", { children: chatDefaults_1.CHATUI_THEME_CSS }), (0, jsx_runtime_1.jsx)("div", { className: "flex flex-1 items-center justify-center px-6", children: (0, jsx_runtime_1.jsxs)("div", { className: "max-w-md text-center", children: [(0, jsx_runtime_1.jsx)("div", { className: "text-sm text-gray-600", children: initGateLoading
1964
+ ? "Initializing chat..."
1965
+ : initGateError || "Initializing chat..." }), !initGateLoading && initGateError && ((0, jsx_runtime_1.jsx)("button", { type: "button", className: `mt-4 inline-flex items-center justify-center rounded-full px-4 py-2 text-sm font-medium ${textButtonTheme}`, onClick: handleInitRetry, children: "Retry" }))] }) })] }));
1966
+ }
1967
+ return ((0, jsx_runtime_1.jsxs)("div", { className: "chatui-root flex min-h-screen min-h-[100dvh] w-full flex-col", style: themeVars, children: [(0, jsx_runtime_1.jsx)("style", { children: chatDefaults_1.CHATUI_THEME_CSS }), (0, jsx_runtime_1.jsx)(TopBar_1.default, { sessionId: sessionId, authToken: authToken, onClearChat: clearChat, onLogout: doLogout, onInitOpen: () => {
1747
1968
  if (initPanelEnabled) {
1748
1969
  setShowInitPanel(true);
1749
1970
  }
@@ -1778,10 +1999,15 @@ function ChatUI(props) {
1778
1999
  setViewerLoading(true);
1779
2000
  setViewerUrl(blobUrl);
1780
2001
  setViewerKey((k) => k + 1);
1781
- }, takeActionProceedOpen: takeActionProceedOpen, takeActionSubmitting: takeActionSubmitting, takeActionError: takeActionError, onProceedTakeAction: proceedTakeAction, textButtonTheme: textButtonTheme, text: text.documentViewer }), (0, jsx_runtime_1.jsx)(MessageList_1.default, { messages: messages, pending: pending, openOverlay: openOverlay, onOpenTaskCard: openTaskCardModal, onSelectTaskCard: toggleTaskCardSelection, selectedTaskCardId: selectedTaskCard === null || selectedTaskCard === void 0 ? void 0 : selectedTaskCard.RequestId, isRtl: chatIsRtl, speakingMessageIndex: speakingMessageIndex, onSpeak: speakMessage, onStopSpeak: stopSpeaking, textButtonTheme: textButtonTheme, listEndRef: listEndRef, text: text.emptyState, messageItemText: text.messageItem, taskCardSize: taskCardSize }), (0, jsx_runtime_1.jsx)(Composer_1.default, { fileInputRef: fileInputRef, composerRef: composerRef, selectedTaskCard: selectedTaskCard, selectedFiles: selectedFiles, onClearSelected: clearSelected, onUpload: handleUpload, input: input, onInputChange: (value) => {
1782
- setInput(value);
1783
- if (composerRef.current) {
1784
- autosizeTextarea(composerRef.current);
1785
- }
1786
- }, onInputKeyDown: onKeyDown, onInputFocus: detectKeyboardDirection, inputIsRtl: inputIsRtl, inputLocale: inputLocale, authToken: authToken, sessionId: sessionId, pending: pending, voiceMode: voiceMode, voiceUploading: voiceUploading, waveData: waveData, onToggleVoice: () => (voiceMode ? cancelVoice() : startSpeechRecognition()), onSendMessage: sendMessage, voiceError: voiceError, canSend: canSend, onCancelVoice: cancelVoice, onConfirmVoice: confirmVoice, onAttachClick: () => { var _a; return (_a = fileInputRef.current) === null || _a === void 0 ? void 0 : _a.click(); }, onClearSelectedTask: () => setSelectedTaskCard(null), text: text.composer, voiceOverlayText: text.voiceOverlay })] }));
2002
+ }, takeActionProceedOpen: takeActionProceedOpen, takeActionSubmitting: takeActionSubmitting, takeActionError: takeActionError, onProceedTakeAction: proceedTakeAction, textButtonTheme: textButtonTheme, text: text.documentViewer }), isEmptyState ? ((0, jsx_runtime_1.jsx)("div", { className: "flex flex-1 items-center justify-center px-2 py-6 sm:px-4", children: (0, jsx_runtime_1.jsxs)("div", { className: "w-full max-w-3xl -translate-y-[23vh]", children: [(0, jsx_runtime_1.jsx)("div", { className: "mb-6 text-center text-[2.43rem] font-semibold leading-tight text-gray-800", children: text.emptyState.title }), (0, jsx_runtime_1.jsx)(Composer_1.default, { fileInputRef: fileInputRef, composerRef: composerRef, selectedTaskCard: selectedTaskCard, selectedFiles: selectedFiles, onClearSelected: clearSelected, onUpload: handleUpload, input: input, onInputChange: (value) => {
2003
+ setInput(value);
2004
+ if (composerRef.current) {
2005
+ autosizeTextarea(composerRef.current);
2006
+ }
2007
+ }, onInputKeyDown: onKeyDown, onInputFocus: detectKeyboardDirection, inputIsRtl: inputIsRtl, inputLocale: inputLocale, authToken: authToken, sessionId: sessionId, pending: pending, voiceMode: voiceMode, voiceUploading: voiceUploading, waveData: waveData, onToggleVoice: () => (voiceMode ? cancelVoice() : startSpeechRecognition()), onSendMessage: sendMessage, voiceError: voiceError, canSend: canSend, onCancelVoice: cancelVoice, onConfirmVoice: confirmVoice, onAttachClick: () => { var _a; return (_a = fileInputRef.current) === null || _a === void 0 ? void 0 : _a.click(); }, onClearSelectedTask: () => setSelectedTaskCard(null), dockToBottom: false, text: text.composer, voiceOverlayText: text.voiceOverlay })] }) })) : ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(MessageList_1.default, { messages: messages, pending: pending, openOverlay: openOverlay, onOpenTaskCard: openTaskCardModal, onSelectTaskCard: toggleTaskCardSelection, selectedTaskCardId: selectedTaskCard === null || selectedTaskCard === void 0 ? void 0 : selectedTaskCard.RequestId, isRtl: chatIsRtl, speakingMessageIndex: speakingMessageIndex, onSpeak: speakMessage, onStopSpeak: stopSpeaking, textButtonTheme: textButtonTheme, listEndRef: listEndRef, text: text.emptyState, messageItemText: text.messageItem, taskCardSize: taskCardSize, dockComposer: shouldDockComposer }), (0, jsx_runtime_1.jsx)(Composer_1.default, { fileInputRef: fileInputRef, composerRef: composerRef, selectedTaskCard: selectedTaskCard, selectedFiles: selectedFiles, onClearSelected: clearSelected, onUpload: handleUpload, input: input, onInputChange: (value) => {
2008
+ setInput(value);
2009
+ if (composerRef.current) {
2010
+ autosizeTextarea(composerRef.current);
2011
+ }
2012
+ }, onInputKeyDown: onKeyDown, onInputFocus: detectKeyboardDirection, inputIsRtl: inputIsRtl, inputLocale: inputLocale, authToken: authToken, sessionId: sessionId, pending: pending, voiceMode: voiceMode, voiceUploading: voiceUploading, waveData: waveData, onToggleVoice: () => (voiceMode ? cancelVoice() : startSpeechRecognition()), onSendMessage: sendMessage, voiceError: voiceError, canSend: canSend, onCancelVoice: cancelVoice, onConfirmVoice: confirmVoice, onAttachClick: () => { var _a; return (_a = fileInputRef.current) === null || _a === void 0 ? void 0 : _a.click(); }, onClearSelectedTask: () => setSelectedTaskCard(null), dockToBottom: shouldDockComposer, text: text.composer, voiceOverlayText: text.voiceOverlay })] }))] }));
1787
2013
  }
@@ -28,8 +28,9 @@ type ComposerProps = {
28
28
  onConfirmVoice: () => void;
29
29
  onAttachClick: () => void;
30
30
  onClearSelectedTask: () => void;
31
+ dockToBottom?: boolean;
31
32
  text: ChatUITextConfig["composer"];
32
33
  voiceOverlayText: ChatUITextConfig["voiceOverlay"];
33
34
  };
34
- export default function Composer({ fileInputRef, composerRef, selectedTaskCard, selectedFiles, onClearSelected, onUpload, input, onInputChange, onInputKeyDown, onInputFocus, inputIsRtl, inputLocale, authToken, sessionId, pending, voiceMode, voiceUploading, waveData, onToggleVoice, onSendMessage, voiceError, canSend, onCancelVoice, onConfirmVoice, onAttachClick, onClearSelectedTask, text, voiceOverlayText, }: ComposerProps): import("react/jsx-runtime").JSX.Element;
35
+ export default function Composer({ fileInputRef, composerRef, selectedTaskCard, selectedFiles, onClearSelected, onUpload, input, onInputChange, onInputKeyDown, onInputFocus, inputIsRtl, inputLocale, authToken, sessionId, pending, voiceMode, voiceUploading, waveData, onToggleVoice, onSendMessage, voiceError, canSend, onCancelVoice, onConfirmVoice, onAttachClick, onClearSelectedTask, dockToBottom, text, voiceOverlayText, }: ComposerProps): import("react/jsx-runtime").JSX.Element;
35
36
  export {};
@@ -8,9 +8,12 @@ const jsx_runtime_1 = require("react/jsx-runtime");
8
8
  const lu_1 = require("react-icons/lu");
9
9
  const classNames_1 = require("../utils/classNames");
10
10
  const VoiceOverlay_1 = __importDefault(require("./VoiceOverlay"));
11
- function Composer({ fileInputRef, composerRef, selectedTaskCard, selectedFiles, onClearSelected, onUpload, input, onInputChange, onInputKeyDown, onInputFocus, inputIsRtl, inputLocale, authToken, sessionId, pending, voiceMode, voiceUploading, waveData, onToggleVoice, onSendMessage, voiceError, canSend, onCancelVoice, onConfirmVoice, onAttachClick, onClearSelectedTask, text, voiceOverlayText, }) {
11
+ function Composer({ fileInputRef, composerRef, selectedTaskCard, selectedFiles, onClearSelected, onUpload, input, onInputChange, onInputKeyDown, onInputFocus, inputIsRtl, inputLocale, authToken, sessionId, pending, voiceMode, voiceUploading, waveData, onToggleVoice, onSendMessage, voiceError, canSend, onCancelVoice, onConfirmVoice, onAttachClick, onClearSelectedTask, dockToBottom = false, text, voiceOverlayText, }) {
12
12
  var _a;
13
- return ((0, jsx_runtime_1.jsx)("div", { className: "sticky bottom-0 bg-white/95 px-2 py-4 backdrop-blur sm:px-4", children: (0, jsx_runtime_1.jsx)("div", { className: "mx-auto w-full max-w-3xl", children: (0, jsx_runtime_1.jsxs)("div", { className: "relative", children: [(0, jsx_runtime_1.jsx)(VoiceOverlay_1.default, { voiceMode: voiceMode, waveData: waveData, voiceUploading: voiceUploading, onCancel: onCancelVoice, onConfirm: onConfirmVoice, text: voiceOverlayText }), (0, jsx_runtime_1.jsxs)("div", { className: "flex flex-wrap items-end gap-2 rounded-full bg-white px-3 py-2 shadow-[0_10px_40px_rgba(0,0,0,0.08)] ring-1 ring-[#252525]/5 sm:flex-nowrap", children: [(0, jsx_runtime_1.jsx)("input", { ref: fileInputRef, type: "file", multiple: true, className: "hidden", onChange: (e) => onUpload(e.target.files) }), (0, jsx_runtime_1.jsx)("button", { onClick: onAttachClick, disabled: !sessionId, className: (0, classNames_1.classNames)("inline-flex h-9 w-9 items-center justify-center bg-transparent text-gray-700 transition", !sessionId && "opacity-60"), title: text.attachTitle, children: (0, jsx_runtime_1.jsx)(lu_1.LuPlus, { className: "h-5 w-5" }) }), (0, jsx_runtime_1.jsxs)("div", { className: "relative flex-1", children: [selectedTaskCard && ((0, jsx_runtime_1.jsx)("div", { className: "mb-2 flex items-center gap-2", children: (0, jsx_runtime_1.jsxs)("span", { className: "inline-flex items-center gap-2 rounded-full bg-blue-100 px-3 py-1 text-xs font-semibold text-blue-700 shadow-sm", children: [(0, jsx_runtime_1.jsxs)("span", { children: [text.selectedTaskPrefix, String((_a = selectedTaskCard.RequestId) !== null && _a !== void 0 ? _a : "")] }), (0, jsx_runtime_1.jsx)("button", { type: "button", className: "inline-flex h-4 w-4 items-center justify-center rounded-full bg-blue-700 text-blue-100 transition hover:bg-blue-800", onClick: onClearSelectedTask, title: text.selectedTaskClearTitle, "aria-label": text.selectedTaskClearTitle, children: (0, jsx_runtime_1.jsx)(lu_1.LuX, { className: "h-3 w-3" }) })] }) })), selectedFiles.length > 0 && ((0, jsx_runtime_1.jsx)("div", { className: "mb-2 flex flex-wrap gap-2", children: selectedFiles.map((f, i) => ((0, jsx_runtime_1.jsxs)("span", { className: "inline-flex items-center gap-2 rounded-2xl border bg-white px-3 py-1 text-xs shadow-sm", children: [(0, jsx_runtime_1.jsx)(lu_1.LuPaperclip, { className: "h-3.5 w-3.5" }), " ", f.name, (0, jsx_runtime_1.jsx)("button", { className: "rounded-full p-0.5 hover:bg-gray-100", onClick: () => onClearSelected(i), children: (0, jsx_runtime_1.jsx)(lu_1.LuX, { className: "h-3.5 w-3.5" }) })] }, i))) })), (0, jsx_runtime_1.jsx)("textarea", { ref: composerRef, value: input, onChange: (e) => onInputChange(e.target.value), onFocus: onInputFocus, onKeyDown: onInputKeyDown, rows: 1, disabled: !authToken, dir: inputIsRtl ? "rtl" : "ltr", lang: inputLocale, placeholder: !authToken
13
+ const containerClass = dockToBottom
14
+ ? "sticky bottom-0 bg-white/95 px-2 py-4 backdrop-blur sm:px-4"
15
+ : "relative bg-white/95 px-2 py-4 backdrop-blur sm:px-4";
16
+ return ((0, jsx_runtime_1.jsx)("div", { className: containerClass, children: (0, jsx_runtime_1.jsx)("div", { className: "mx-auto w-full max-w-3xl", children: (0, jsx_runtime_1.jsxs)("div", { className: "relative", children: [(0, jsx_runtime_1.jsx)(VoiceOverlay_1.default, { voiceMode: voiceMode, waveData: waveData, voiceUploading: voiceUploading, onCancel: onCancelVoice, onConfirm: onConfirmVoice, text: voiceOverlayText }), (0, jsx_runtime_1.jsxs)("div", { className: "flex flex-wrap items-end gap-2 rounded-full bg-white px-3 py-2 shadow-[0_10px_40px_rgba(0,0,0,0.08)] ring-1 ring-[#252525]/5 sm:flex-nowrap", children: [(0, jsx_runtime_1.jsx)("input", { ref: fileInputRef, type: "file", multiple: true, className: "hidden", onChange: (e) => onUpload(e.target.files) }), (0, jsx_runtime_1.jsx)("button", { onClick: onAttachClick, disabled: !sessionId, className: (0, classNames_1.classNames)("inline-flex h-9 w-9 items-center justify-center bg-transparent text-gray-700 transition", !sessionId && "opacity-60"), title: text.attachTitle, children: (0, jsx_runtime_1.jsx)(lu_1.LuPlus, { className: "h-5 w-5" }) }), (0, jsx_runtime_1.jsxs)("div", { className: "relative flex-1", children: [selectedTaskCard && ((0, jsx_runtime_1.jsx)("div", { className: "mb-2 flex items-center gap-2", children: (0, jsx_runtime_1.jsxs)("span", { className: "inline-flex items-center gap-2 rounded-full bg-blue-100 px-3 py-1 text-xs font-semibold text-blue-700 shadow-sm", children: [(0, jsx_runtime_1.jsxs)("span", { children: [text.selectedTaskPrefix, String((_a = selectedTaskCard.RequestId) !== null && _a !== void 0 ? _a : "")] }), (0, jsx_runtime_1.jsx)("button", { type: "button", className: "inline-flex h-4 w-4 items-center justify-center rounded-full bg-blue-700 text-blue-100 transition hover:bg-blue-800", onClick: onClearSelectedTask, title: text.selectedTaskClearTitle, "aria-label": text.selectedTaskClearTitle, children: (0, jsx_runtime_1.jsx)(lu_1.LuX, { className: "h-3 w-3" }) })] }) })), selectedFiles.length > 0 && ((0, jsx_runtime_1.jsx)("div", { className: "mb-2 flex flex-wrap gap-2", children: selectedFiles.map((f, i) => ((0, jsx_runtime_1.jsxs)("span", { className: "inline-flex items-center gap-2 rounded-2xl border bg-white px-3 py-1 text-xs shadow-sm", children: [(0, jsx_runtime_1.jsx)(lu_1.LuPaperclip, { className: "h-3.5 w-3.5" }), " ", f.name, (0, jsx_runtime_1.jsx)("button", { className: "rounded-full p-0.5 hover:bg-gray-100", onClick: () => onClearSelected(i), children: (0, jsx_runtime_1.jsx)(lu_1.LuX, { className: "h-3.5 w-3.5" }) })] }, i))) })), (0, jsx_runtime_1.jsx)("textarea", { ref: composerRef, value: input, onChange: (e) => onInputChange(e.target.value), onFocus: onInputFocus, onKeyDown: onInputKeyDown, rows: 1, disabled: !authToken, dir: inputIsRtl ? "rtl" : "ltr", lang: inputLocale, placeholder: !authToken
14
17
  ? text.placeholderAuthRequired
15
18
  : text.placeholderDefault, className: "max-h-80 w-full resize-none bg-transparent px-1 py-1 outline-none", style: {
16
19
  direction: inputIsRtl ? "rtl" : "ltr",
@@ -17,6 +17,7 @@ type MessageListProps = {
17
17
  text: ChatUITextConfig["emptyState"];
18
18
  messageItemText: ChatUITextConfig["messageItem"];
19
19
  taskCardSize: ChatUITaskCardSize;
20
+ dockComposer?: boolean;
20
21
  };
21
- export default function MessageList({ messages, pending, openOverlay, onOpenTaskCard, onSelectTaskCard, selectedTaskCardId, isRtl, speakingMessageIndex, onSpeak, onStopSpeak, textButtonTheme, listEndRef, text, messageItemText, taskCardSize, }: MessageListProps): import("react/jsx-runtime").JSX.Element;
22
+ export default function MessageList({ messages, pending, openOverlay, onOpenTaskCard, onSelectTaskCard, selectedTaskCardId, isRtl, speakingMessageIndex, onSpeak, onStopSpeak, textButtonTheme, listEndRef, text, messageItemText, taskCardSize, dockComposer, }: MessageListProps): import("react/jsx-runtime").JSX.Element;
22
23
  export {};
@@ -8,8 +8,9 @@ const jsx_runtime_1 = require("react/jsx-runtime");
8
8
  const framer_motion_1 = require("framer-motion");
9
9
  const MessageItem_1 = __importDefault(require("./MessageItem"));
10
10
  const TypingDots_1 = __importDefault(require("./TypingDots"));
11
- function MessageList({ messages, pending, openOverlay, onOpenTaskCard, onSelectTaskCard, selectedTaskCardId, isRtl, speakingMessageIndex, onSpeak, onStopSpeak, textButtonTheme, listEndRef, text, messageItemText, taskCardSize, }) {
12
- return ((0, jsx_runtime_1.jsx)("div", { className: "flex-1 overflow-y-auto px-2 py-6 sm:px-4", children: (0, jsx_runtime_1.jsxs)("div", { className: "mx-auto w-full max-w-3xl", children: [messages.length === 0 && ((0, jsx_runtime_1.jsx)("div", { className: "mb-4 pt-24 text-center text-[2.43rem] font-semibold leading-tight text-gray-800", children: text.title })), (0, jsx_runtime_1.jsx)("div", { className: "space-y-5", children: (0, jsx_runtime_1.jsxs)(framer_motion_1.AnimatePresence, { initial: false, children: [messages.map((m, i) => {
11
+ function MessageList({ messages, pending, openOverlay, onOpenTaskCard, onSelectTaskCard, selectedTaskCardId, isRtl, speakingMessageIndex, onSpeak, onStopSpeak, textButtonTheme, listEndRef, text, messageItemText, taskCardSize, dockComposer = false, }) {
12
+ const listPadding = dockComposer ? "pb-28" : "pb-6";
13
+ return ((0, jsx_runtime_1.jsx)("div", { className: `flex-1 min-h-0 overflow-y-auto px-2 pt-6 ${listPadding} sm:px-4`, children: (0, jsx_runtime_1.jsxs)("div", { className: "mx-auto w-full max-w-3xl", children: [messages.length === 0 && ((0, jsx_runtime_1.jsx)("div", { className: "mb-4 pt-24 text-center text-[2.43rem] font-semibold leading-tight text-gray-800", children: text.title })), (0, jsx_runtime_1.jsx)("div", { className: "space-y-5", children: (0, jsx_runtime_1.jsxs)(framer_motion_1.AnimatePresence, { initial: false, children: [messages.map((m, i) => {
13
14
  var _a;
14
15
  const canSpeak = m.role === "Assistant" &&
15
16
  !!m.content &&
package/dist/config.d.ts CHANGED
@@ -169,6 +169,7 @@ export type ChatUISDKConfig = {
169
169
  initializeChat: boolean;
170
170
  contextWindow: string;
171
171
  initializeLanguage?: string;
172
+ initializeMessage?: string;
172
173
  };
173
174
  declare class SDKConfigStore {
174
175
  private settings;
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export { default as ChatUI } from "./ChatUI";
2
- export type { ChatMessage, ChatUIProps, Role } from "./models/chat.types";
3
- export { Init, GetConfig, FinalizeSession, InitializeChatClients, InitializeChatSession, } from "./sdkUtilities";
4
- export type { InitializeChatClientsOptions, FinalizeSessionOptions, InitializeChatOptions, InitializeChatResult, } from "./sdkUtilities";
2
+ export type { AddRequestToolResult, ChatMessage, ChatUIProps, ProcessRequestToolResult, Role, } from "./models/chat.types";
3
+ export { Init, GetConfig, FinalizeSession, InitializeChatClients, } from "./sdkUtilities";
4
+ export type { InitializeChatClientsOptions, FinalizeSessionOptions, } from "./sdkUtilities";
5
5
  export type { ChatUIFontConfig, ChatUIInitPreset, ChatUIInitPresets, ChatUISDKConfig, ChatUITheme, ChatUITaskCardSize, ChatUITextConfig, ChatUITextConfigInput, } from "./config";
package/dist/index.js CHANGED
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.InitializeChatSession = exports.InitializeChatClients = exports.FinalizeSession = exports.GetConfig = exports.Init = exports.ChatUI = void 0;
6
+ exports.InitializeChatClients = exports.FinalizeSession = exports.GetConfig = exports.Init = exports.ChatUI = void 0;
7
7
  var ChatUI_1 = require("./ChatUI");
8
8
  Object.defineProperty(exports, "ChatUI", { enumerable: true, get: function () { return __importDefault(ChatUI_1).default; } });
9
9
  var sdkUtilities_1 = require("./sdkUtilities");
@@ -11,4 +11,3 @@ Object.defineProperty(exports, "Init", { enumerable: true, get: function () { re
11
11
  Object.defineProperty(exports, "GetConfig", { enumerable: true, get: function () { return sdkUtilities_1.GetConfig; } });
12
12
  Object.defineProperty(exports, "FinalizeSession", { enumerable: true, get: function () { return sdkUtilities_1.FinalizeSession; } });
13
13
  Object.defineProperty(exports, "InitializeChatClients", { enumerable: true, get: function () { return sdkUtilities_1.InitializeChatClients; } });
14
- Object.defineProperty(exports, "InitializeChatSession", { enumerable: true, get: function () { return sdkUtilities_1.InitializeChatSession; } });
@@ -9,6 +9,20 @@ export interface ChatMessage {
9
9
  }>;
10
10
  availableTasksCards?: AvailableTasksCard[];
11
11
  }
12
+ export type AddRequestToolResult = {
13
+ Message?: string;
14
+ StatusCode?: number;
15
+ Result?: {
16
+ RequestGuid?: string;
17
+ RequestId?: string | number;
18
+ BatchId?: string | number;
19
+ };
20
+ };
21
+ export type ProcessRequestToolResult = {
22
+ Message?: string;
23
+ StatusCode?: number;
24
+ Result?: boolean;
25
+ };
12
26
  export interface UploadAttachmentItem {
13
27
  AttachmentName: string;
14
28
  AttachmentSAS: string;
@@ -56,6 +70,10 @@ export interface AvailableTasksCard {
56
70
  export type ChatUIProps = {
57
71
  initServiceId?: string | number;
58
72
  initRequestStepId?: string | number;
73
+ contextWindow?: string;
74
+ domain?: string;
75
+ token?: string;
76
+ initializeMessage?: string;
59
77
  initPresets?: ChatUIInitPresets;
60
78
  initialInitPreset?: "requester" | "provider" | "custom";
61
79
  speechRegion?: string;
@@ -69,4 +87,6 @@ export type ChatUIProps = {
69
87
  fonts?: ChatUIFontConfig;
70
88
  text?: ChatUITextConfigInput;
71
89
  taskCardSize?: ChatUITaskCardSize;
90
+ onRequestAdded?: (result: AddRequestToolResult) => void;
91
+ onRequestProcessed?: (result: ProcessRequestToolResult) => void;
72
92
  };
@@ -2,26 +2,14 @@ import { ChatUISDKConfig } from "./config";
2
2
  export declare function Init(config: ChatUISDKConfig): void;
3
3
  export declare function GetConfig(): ChatUISDKConfig;
4
4
  export declare function GetConfigValue<Key extends keyof ChatUISDKConfig>(key: Key): ChatUISDKConfig[Key];
5
- export type InitializeChatOptions = {
6
- initServiceId?: string | number;
7
- initRequestStepId?: string | number;
8
- contextWindow?: string;
9
- domain?: string;
10
- token?: string;
11
- };
12
5
  export type InitializeChatClientsOptions = {
13
6
  domain?: string;
14
7
  token?: string;
15
8
  };
16
- export type InitializeChatResult = {
17
- initialized: boolean;
18
- sessionId: string;
19
- payload?: any;
20
- };
21
- export declare function InitializeChatSession(options?: InitializeChatOptions): Promise<InitializeChatResult>;
22
9
  export declare function InitializeChatClients(options?: InitializeChatClientsOptions): Promise<boolean>;
23
10
  export type FinalizeSessionOptions = {
24
11
  token?: string;
25
12
  domain?: string;
13
+ sessionId?: string;
26
14
  };
27
15
  export declare function FinalizeSession(options?: FinalizeSessionOptions): Promise<boolean>;
@@ -12,12 +12,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.Init = Init;
13
13
  exports.GetConfig = GetConfig;
14
14
  exports.GetConfigValue = GetConfigValue;
15
- exports.InitializeChatSession = InitializeChatSession;
16
15
  exports.InitializeChatClients = InitializeChatClients;
17
16
  exports.FinalizeSession = FinalizeSession;
18
17
  const config_1 = require("./config");
19
18
  const chatDefaults_1 = require("./constants/chatDefaults");
20
- const generateGuid_1 = require("./utils/generateGuid");
21
19
  const localStorage_1 = require("./utils/localStorage");
22
20
  const storageKeys_1 = require("./utils/storageKeys");
23
21
  const normalizeAuthToken = (value) => {
@@ -53,76 +51,6 @@ function GetConfig() {
53
51
  function GetConfigValue(key) {
54
52
  return config_1.ChatUISDKConfigStoreInstance.getValue(key);
55
53
  }
56
- function InitializeChatSession() {
57
- return __awaiter(this, arguments, void 0, function* (options = {}) {
58
- var _a, _b, _c, _d, _e, _f;
59
- const config = GetConfig();
60
- const apiBase = chatDefaults_1.DEFAULT_API_BASE;
61
- const apiKey = chatDefaults_1.DEFAULT_API_KEY;
62
- let sessionId = localStorage_1.ls.get(storageKeys_1.STORAGE_KEYS.sessionId, "");
63
- if (!sessionId) {
64
- sessionId = (0, generateGuid_1.generateGuid)();
65
- localStorage_1.ls.set(storageKeys_1.STORAGE_KEYS.sessionId, sessionId);
66
- }
67
- if (!apiBase || !apiKey || !sessionId) {
68
- throw new Error("Missing chat API configuration or session ID.");
69
- }
70
- const existingInit = localStorage_1.ls.get((0, storageKeys_1.getInitCompletedKey)(sessionId), false);
71
- if (existingInit) {
72
- return { initialized: false, sessionId };
73
- }
74
- const authToken = normalizeAuthToken((_b = (_a = options.token) !== null && _a !== void 0 ? _a : config.token) !== null && _b !== void 0 ? _b : localStorage_1.ls.get(storageKeys_1.STORAGE_KEYS.authToken, ""));
75
- if (!authToken) {
76
- throw new Error("Auth token is required to initialize chat.");
77
- }
78
- localStorage_1.ls.set(storageKeys_1.STORAGE_KEYS.authToken, authToken);
79
- const defaultDomain = config.isDab ? chatDefaults_1.DEFAULT_DOMAIN : "";
80
- const domain = ((_c = options.domain) !== null && _c !== void 0 ? _c : localStorage_1.ls.get(storageKeys_1.STORAGE_KEYS.domain, defaultDomain)).trim();
81
- const contextWindow = (_d = options.contextWindow) !== null && _d !== void 0 ? _d : config.contextWindow;
82
- const initializeLanguage = ((_e = config.initializeLanguage) !== null && _e !== void 0 ? _e : "").trim() || "ar-JO";
83
- const bodyPayload = {
84
- Domain: domain,
85
- ContextWindow: contextWindow || "ComposeRequest",
86
- InitializeLangauge: initializeLanguage,
87
- };
88
- if (options.initServiceId !== undefined && options.initServiceId !== null) {
89
- const n = Number(options.initServiceId);
90
- if (!Number.isNaN(n))
91
- bodyPayload.ServiceId = n;
92
- }
93
- if (options.initRequestStepId !== undefined &&
94
- options.initRequestStepId !== null) {
95
- const n = Number(options.initRequestStepId);
96
- if (!Number.isNaN(n))
97
- bodyPayload.RequestStepId = n;
98
- }
99
- const initRes = yield fetch(new URL("/api/initializeChat", apiBase).toString(), {
100
- method: "POST",
101
- headers: {
102
- "Content-Type": "application/json",
103
- "api-key": apiKey,
104
- Authorization: authToken,
105
- },
106
- credentials: "include",
107
- body: JSON.stringify(bodyPayload),
108
- });
109
- if (!initRes.ok) {
110
- let msg = "";
111
- try {
112
- msg = yield initRes.text();
113
- }
114
- catch (_g) { }
115
- throw new Error(`initializeChat failed: ${initRes.status} ${initRes.statusText}${msg ? ` - ${msg}` : ""}`);
116
- }
117
- const initPayload = yield initRes.json().catch(() => ({}));
118
- const resolvedSessionId = (_f = initPayload === null || initPayload === void 0 ? void 0 : initPayload.SessionId) !== null && _f !== void 0 ? _f : sessionId;
119
- if (initPayload === null || initPayload === void 0 ? void 0 : initPayload.SessionId) {
120
- localStorage_1.ls.set(storageKeys_1.STORAGE_KEYS.sessionId, initPayload.SessionId);
121
- }
122
- localStorage_1.ls.set((0, storageKeys_1.getInitCompletedKey)(resolvedSessionId), true);
123
- return { initialized: true, sessionId: resolvedSessionId, payload: initPayload };
124
- });
125
- }
126
54
  function InitializeChatClients() {
127
55
  return __awaiter(this, arguments, void 0, function* (options = {}) {
128
56
  var _a, _b, _c;
@@ -158,13 +86,14 @@ function InitializeChatClients() {
158
86
  }
159
87
  function FinalizeSession() {
160
88
  return __awaiter(this, arguments, void 0, function* (options = {}) {
161
- var _a, _b, _c;
89
+ var _a, _b, _c, _d;
162
90
  const config = GetConfig();
163
91
  const apiBase = chatDefaults_1.DEFAULT_API_BASE;
164
92
  const apiKey = chatDefaults_1.DEFAULT_API_KEY;
165
- const sessionId = localStorage_1.ls.get(storageKeys_1.STORAGE_KEYS.sessionId, "");
166
- const domain = ((_a = options.domain) !== null && _a !== void 0 ? _a : localStorage_1.ls.get(storageKeys_1.STORAGE_KEYS.domain, "")).trim();
167
- const authToken = normalizeAuthToken((_c = (_b = options.token) !== null && _b !== void 0 ? _b : config.token) !== null && _c !== void 0 ? _c : localStorage_1.ls.get(storageKeys_1.STORAGE_KEYS.authToken, ""));
93
+ const sessionId = (_a = options.sessionId) !== null && _a !== void 0 ? _a : localStorage_1.ls.get(storageKeys_1.STORAGE_KEYS.sessionId, "");
94
+ const defaultDomain = config.isDab ? chatDefaults_1.DEFAULT_DOMAIN : "";
95
+ const domain = ((_b = options.domain) !== null && _b !== void 0 ? _b : localStorage_1.ls.get(storageKeys_1.STORAGE_KEYS.domain, defaultDomain)).trim();
96
+ const authToken = normalizeAuthToken((_d = (_c = options.token) !== null && _c !== void 0 ? _c : config.token) !== null && _d !== void 0 ? _d : localStorage_1.ls.get(storageKeys_1.STORAGE_KEYS.authToken, ""));
168
97
  if (!apiBase || !apiKey || !sessionId)
169
98
  return false;
170
99
  try {
@@ -176,13 +105,21 @@ function FinalizeSession() {
176
105
  SessionId: sessionId,
177
106
  }),
178
107
  });
179
- localStorage_1.ls.remove((0, storageKeys_1.getMessagesKey)(sessionId));
180
- localStorage_1.ls.remove((0, storageKeys_1.getInitCompletedKey)(sessionId));
181
- localStorage_1.ls.set(storageKeys_1.STORAGE_KEYS.authToken, "");
182
- localStorage_1.ls.set(storageKeys_1.STORAGE_KEYS.initUsername, "");
108
+ localStorage_1.ls.removeByPrefix(storageKeys_1.STORAGE_KEYS.messagesPrefix);
109
+ localStorage_1.ls.removeByPrefix(storageKeys_1.STORAGE_KEYS.initCompletedPrefix);
110
+ localStorage_1.ls.remove(storageKeys_1.STORAGE_KEYS.serviceBaseUrl);
111
+ localStorage_1.ls.remove(storageKeys_1.STORAGE_KEYS.apiSubscriptionKey);
112
+ localStorage_1.ls.remove(storageKeys_1.STORAGE_KEYS.loginSubscriptionKey);
113
+ localStorage_1.ls.remove(storageKeys_1.STORAGE_KEYS.authToken);
114
+ localStorage_1.ls.remove(storageKeys_1.STORAGE_KEYS.sessionId);
115
+ localStorage_1.ls.remove(storageKeys_1.STORAGE_KEYS.contextWindow);
116
+ localStorage_1.ls.remove(storageKeys_1.STORAGE_KEYS.initUsername);
117
+ localStorage_1.ls.remove(storageKeys_1.STORAGE_KEYS.domain);
118
+ localStorage_1.ls.remove(storageKeys_1.STORAGE_KEYS.speechLang);
119
+ localStorage_1.ls.remove(storageKeys_1.STORAGE_KEYS.ttsLang);
183
120
  return true;
184
121
  }
185
- catch (_d) {
122
+ catch (_e) {
186
123
  return false;
187
124
  }
188
125
  });
package/dist/styles.css CHANGED
@@ -625,6 +625,9 @@ video {
625
625
  .mb-4 {
626
626
  margin-bottom: 1rem;
627
627
  }
628
+ .mb-6 {
629
+ margin-bottom: 1.5rem;
630
+ }
628
631
  .ml-1 {
629
632
  margin-left: 0.25rem;
630
633
  }
@@ -706,9 +709,15 @@ video {
706
709
  .min-h-0 {
707
710
  min-height: 0px;
708
711
  }
712
+ .min-h-\[100dvh\] {
713
+ min-height: 100dvh;
714
+ }
709
715
  .min-h-\[110px\] {
710
716
  min-height: 110px;
711
717
  }
718
+ .min-h-screen {
719
+ min-height: 100vh;
720
+ }
712
721
  .w-1\.5 {
713
722
  width: 0.375rem;
714
723
  }
@@ -757,6 +766,9 @@ video {
757
766
  .max-w-\[85\%\] {
758
767
  max-width: 85%;
759
768
  }
769
+ .max-w-md {
770
+ max-width: 28rem;
771
+ }
760
772
  .max-w-xl {
761
773
  max-width: 36rem;
762
774
  }
@@ -770,6 +782,10 @@ video {
770
782
  --tw-translate-y: -50%;
771
783
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
772
784
  }
785
+ .-translate-y-\[23vh\] {
786
+ --tw-translate-y: -23vh;
787
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
788
+ }
773
789
  .transform {
774
790
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
775
791
  }
@@ -1083,6 +1099,12 @@ video {
1083
1099
  .pb-2 {
1084
1100
  padding-bottom: 0.5rem;
1085
1101
  }
1102
+ .pb-28 {
1103
+ padding-bottom: 7rem;
1104
+ }
1105
+ .pb-6 {
1106
+ padding-bottom: 1.5rem;
1107
+ }
1086
1108
  .pl-6 {
1087
1109
  padding-left: 1.5rem;
1088
1110
  }
@@ -1098,6 +1120,9 @@ video {
1098
1120
  .pt-24 {
1099
1121
  padding-top: 6rem;
1100
1122
  }
1123
+ .pt-6 {
1124
+ padding-top: 1.5rem;
1125
+ }
1101
1126
  .text-left {
1102
1127
  text-align: left;
1103
1128
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mcp-chat-ui",
3
- "version": "1.0.3",
3
+ "version": "1.0.6",
4
4
  "description": "React Chat UI SDK with speech, file upload, and task actions.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",