mcp-chat-ui 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/README.md +327 -0
  2. package/dist/ChatUI.d.ts +2 -0
  3. package/dist/ChatUI.js +1781 -0
  4. package/dist/components/Composer.d.ts +35 -0
  5. package/dist/components/Composer.js +19 -0
  6. package/dist/components/DocumentViewer.d.ts +24 -0
  7. package/dist/components/DocumentViewer.js +16 -0
  8. package/dist/components/FormattedText.d.ts +9 -0
  9. package/dist/components/FormattedText.js +98 -0
  10. package/dist/components/InitPanel.d.ts +41 -0
  11. package/dist/components/InitPanel.js +20 -0
  12. package/dist/components/MessageItem.d.ts +19 -0
  13. package/dist/components/MessageItem.js +50 -0
  14. package/dist/components/MessageList.d.ts +22 -0
  15. package/dist/components/MessageList.js +19 -0
  16. package/dist/components/TakeActionModal.d.ts +26 -0
  17. package/dist/components/TakeActionModal.js +26 -0
  18. package/dist/components/TaskCardsModal.d.ts +13 -0
  19. package/dist/components/TaskCardsModal.js +17 -0
  20. package/dist/components/ToolResultOverlay.d.ts +9 -0
  21. package/dist/components/ToolResultOverlay.js +14 -0
  22. package/dist/components/TopBar.d.ts +13 -0
  23. package/dist/components/TopBar.js +9 -0
  24. package/dist/components/TypingDots.d.ts +1 -0
  25. package/dist/components/TypingDots.js +8 -0
  26. package/dist/components/VoiceOverlay.d.ts +11 -0
  27. package/dist/components/VoiceOverlay.js +9 -0
  28. package/dist/config.d.ts +179 -0
  29. package/dist/config.js +24 -0
  30. package/dist/constants/chatDefaults.d.ts +19 -0
  31. package/dist/constants/chatDefaults.js +234 -0
  32. package/dist/helpers/api.d.ts +12 -0
  33. package/dist/helpers/api.js +104 -0
  34. package/dist/helpers/taskAttributes.d.ts +11 -0
  35. package/dist/helpers/taskAttributes.js +41 -0
  36. package/dist/index.d.ts +5 -0
  37. package/dist/index.js +14 -0
  38. package/dist/models/chat.types.d.ts +72 -0
  39. package/dist/models/chat.types.js +2 -0
  40. package/dist/sdkUtilities.d.ts +27 -0
  41. package/dist/sdkUtilities.js +188 -0
  42. package/dist/styles.css +1412 -0
  43. package/dist/utils/classNames.d.ts +1 -0
  44. package/dist/utils/classNames.js +6 -0
  45. package/dist/utils/format.d.ts +2 -0
  46. package/dist/utils/format.js +18 -0
  47. package/dist/utils/generateGuid.d.ts +1 -0
  48. package/dist/utils/generateGuid.js +10 -0
  49. package/dist/utils/localStorage.d.ts +6 -0
  50. package/dist/utils/localStorage.js +39 -0
  51. package/dist/utils/storageKeys.d.ts +16 -0
  52. package/dist/utils/storageKeys.js +25 -0
  53. package/dist/utils/textDirection.d.ts +2 -0
  54. package/dist/utils/textDirection.js +20 -0
  55. package/package.json +52 -0
package/dist/ChatUI.js ADDED
@@ -0,0 +1,1781 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
36
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
37
+ return new (P || (P = Promise))(function (resolve, reject) {
38
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
39
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
40
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
41
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
42
+ });
43
+ };
44
+ var __rest = (this && this.__rest) || function (s, e) {
45
+ var t = {};
46
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
47
+ t[p] = s[p];
48
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
49
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
50
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
51
+ t[p[i]] = s[p[i]];
52
+ }
53
+ return t;
54
+ };
55
+ var __importDefault = (this && this.__importDefault) || function (mod) {
56
+ return (mod && mod.__esModule) ? mod : { "default": mod };
57
+ };
58
+ Object.defineProperty(exports, "__esModule", { value: true });
59
+ exports.default = ChatUI;
60
+ const jsx_runtime_1 = require("react/jsx-runtime");
61
+ // ChatUI.tsx — Azure Speech (STT/TTS) + document overlay + modern chat UI (HTTP chat, no WS/streaming)
62
+ const react_1 = require("react");
63
+ const sdkUtilities_1 = require("./sdkUtilities");
64
+ const Composer_1 = __importDefault(require("./components/Composer"));
65
+ const DocumentViewer_1 = __importDefault(require("./components/DocumentViewer"));
66
+ const InitPanel_1 = __importDefault(require("./components/InitPanel"));
67
+ const MessageList_1 = __importDefault(require("./components/MessageList"));
68
+ const TakeActionModal_1 = __importDefault(require("./components/TakeActionModal"));
69
+ const TaskCardsModal_1 = __importDefault(require("./components/TaskCardsModal"));
70
+ const ToolResultOverlay_1 = __importDefault(require("./components/ToolResultOverlay"));
71
+ const TopBar_1 = __importDefault(require("./components/TopBar"));
72
+ const api_1 = require("./helpers/api");
73
+ const taskAttributes_1 = require("./helpers/taskAttributes");
74
+ const generateGuid_1 = require("./utils/generateGuid");
75
+ const localStorage_1 = require("./utils/localStorage");
76
+ const storageKeys_1 = require("./utils/storageKeys");
77
+ const textDirection_1 = require("./utils/textDirection");
78
+ const chatDefaults_1 = require("./constants/chatDefaults");
79
+ const textButtonTheme = "bg-[#252525] text-white hover:bg-white hover:text-[#252525] hover:shadow-[0_0_0_1px_rgba(71,72,72,0.12)] disabled:pointer-events-none disabled:opacity-50";
80
+ const normalizeAuthToken = (value) => {
81
+ const trimmed = (value !== null && value !== void 0 ? value : "").trim();
82
+ if (!trimmed)
83
+ return "";
84
+ return /^bearer\s+/i.test(trimmed) ? trimmed : `Bearer ${trimmed}`;
85
+ };
86
+ const formatText = (template, values) => template.replace(/\{(\w+)\}/g, (_, key) => {
87
+ const value = values[key];
88
+ return value === undefined ? "" : String(value);
89
+ });
90
+ function normalizeTheme(theme) {
91
+ 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
+ return {
93
+ appBackground: (_a = theme.appBackground) !== null && _a !== void 0 ? _a : theme.background,
94
+ panelBackground: (_b = theme.panelBackground) !== null && _b !== void 0 ? _b : theme.surface,
95
+ panelBackgroundMuted: (_c = theme.panelBackgroundMuted) !== null && _c !== void 0 ? _c : theme.surfaceMuted,
96
+ panelBackgroundSubtle: (_d = theme.panelBackgroundSubtle) !== null && _d !== void 0 ? _d : theme.surfaceSubtle,
97
+ brand: (_e = theme.brand) !== null && _e !== void 0 ? _e : theme.primary,
98
+ brandHover: (_f = theme.brandHover) !== null && _f !== void 0 ? _f : theme.primaryHover,
99
+ brandAlpha30: (_g = theme.brandAlpha30) !== null && _g !== void 0 ? _g : theme.primary30,
100
+ brandAlpha40: (_h = theme.brandAlpha40) !== null && _h !== void 0 ? _h : theme.primary40,
101
+ brandAlpha50: (_j = theme.brandAlpha50) !== null && _j !== void 0 ? _j : theme.primary50,
102
+ textMain: (_k = theme.textMain) !== null && _k !== void 0 ? _k : theme.textPrimary,
103
+ textEmphasis: (_l = theme.textEmphasis) !== null && _l !== void 0 ? _l : theme.textStrong,
104
+ textSupporting: (_m = theme.textSupporting) !== null && _m !== void 0 ? _m : theme.textSecondary,
105
+ textMuted: (_o = theme.textMuted) !== null && _o !== void 0 ? _o : theme.textMuted,
106
+ textSubtle: (_p = theme.textSubtle) !== null && _p !== void 0 ? _p : theme.textSubtle,
107
+ textDisabled: (_q = theme.textDisabled) !== null && _q !== void 0 ? _q : theme.textFaint,
108
+ textOnBrand: (_r = theme.textOnBrand) !== null && _r !== void 0 ? _r : theme.textInverse,
109
+ userMessageBackground: theme.userMessageBackground,
110
+ userMessageText: theme.userMessageText,
111
+ neutralLightest: (_t = theme.neutralLightest) !== null && _t !== void 0 ? _t : theme.neutral50,
112
+ neutralLighter: (_u = theme.neutralLighter) !== null && _u !== void 0 ? _u : theme.neutral100,
113
+ neutralMedium: (_v = theme.neutralMedium) !== null && _v !== void 0 ? _v : theme.neutral400,
114
+ neutralDark: (_w = theme.neutralDark) !== null && _w !== void 0 ? _w : theme.neutral800,
115
+ neutralDarker: (_x = theme.neutralDarker) !== null && _x !== void 0 ? _x : theme.neutral900,
116
+ neutralDarker80: (_y = theme.neutralDarker80) !== null && _y !== void 0 ? _y : theme.neutral900_80,
117
+ borderDefault: (_z = theme.borderDefault) !== null && _z !== void 0 ? _z : theme.border,
118
+ accentBackground: (_0 = theme.accentBackground) !== null && _0 !== void 0 ? _0 : theme.accentBg,
119
+ accentText: (_1 = theme.accentText) !== null && _1 !== void 0 ? _1 : theme.accentText,
120
+ warningBackground: (_2 = theme.warningBackground) !== null && _2 !== void 0 ? _2 : theme.warningBg,
121
+ warningText: (_3 = theme.warningText) !== null && _3 !== void 0 ? _3 : theme.warningText,
122
+ errorBackground: (_4 = theme.errorBackground) !== null && _4 !== void 0 ? _4 : theme.errorBg,
123
+ errorText: (_5 = theme.errorText) !== null && _5 !== void 0 ? _5 : theme.errorText,
124
+ focusRing: (_6 = theme.focusRing) !== null && _6 !== void 0 ? _6 : theme.ring,
125
+ focusRingStrong: (_7 = theme.focusRingStrong) !== null && _7 !== void 0 ? _7 : theme.ringStrong,
126
+ outlineShadow: (_8 = theme.outlineShadow) !== null && _8 !== void 0 ? _8 : theme.shadowOutline,
127
+ elevatedShadow: (_9 = theme.elevatedShadow) !== null && _9 !== void 0 ? _9 : theme.shadowElevated,
128
+ selectOptionHover: theme.selectOptionHover,
129
+ cardSelectedBackground: theme.cardSelectedBackground,
130
+ };
131
+ }
132
+ function ChatUI(props) {
133
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
134
+ const sdkConfig = (0, sdkUtilities_1.GetConfig)();
135
+ const theme = (0, react_1.useMemo)(() => {
136
+ var _a;
137
+ return normalizeTheme(Object.assign(Object.assign({}, chatDefaults_1.DEFAULT_THEME), ((_a = props.theme) !== null && _a !== void 0 ? _a : {})));
138
+ }, [props.theme]);
139
+ const fonts = (0, react_1.useMemo)(() => (Object.assign(Object.assign({}, chatDefaults_1.DEFAULT_FONTS), props.fonts)), [props.fonts]);
140
+ const ttsVoiceMap = (0, react_1.useMemo)(() => {
141
+ var _a;
142
+ return (Object.assign(Object.assign({}, chatDefaults_1.DEFAULT_TTS_VOICE_MAP), ((_a = props.ttsVoiceMap) !== null && _a !== void 0 ? _a : {})));
143
+ }, [props.ttsVoiceMap]);
144
+ const text = (0, react_1.useMemo)(() => {
145
+ var _a;
146
+ const propText = (_a = props.text) !== null && _a !== void 0 ? _a : {};
147
+ return Object.assign(Object.assign({}, chatDefaults_1.DEFAULT_TEXT), { topBar: Object.assign(Object.assign({}, chatDefaults_1.DEFAULT_TEXT.topBar), propText.topBar), emptyState: Object.assign(Object.assign({}, chatDefaults_1.DEFAULT_TEXT.emptyState), propText.emptyState), composer: Object.assign(Object.assign({}, chatDefaults_1.DEFAULT_TEXT.composer), propText.composer), voiceOverlay: Object.assign(Object.assign({}, chatDefaults_1.DEFAULT_TEXT.voiceOverlay), propText.voiceOverlay), messageItem: Object.assign(Object.assign({}, chatDefaults_1.DEFAULT_TEXT.messageItem), propText.messageItem), taskCards: Object.assign(Object.assign({}, chatDefaults_1.DEFAULT_TEXT.taskCards), propText.taskCards), documentViewer: Object.assign(Object.assign({}, chatDefaults_1.DEFAULT_TEXT.documentViewer), propText.documentViewer), takeAction: Object.assign(Object.assign({}, chatDefaults_1.DEFAULT_TEXT.takeAction), propText.takeAction), toolResult: Object.assign(Object.assign({}, chatDefaults_1.DEFAULT_TEXT.toolResult), propText.toolResult), alerts: Object.assign(Object.assign({}, chatDefaults_1.DEFAULT_TEXT.alerts), propText.alerts), errors: Object.assign(Object.assign({}, chatDefaults_1.DEFAULT_TEXT.errors), propText.errors) });
148
+ }, [props.text]);
149
+ const taskCardSize = (0, react_1.useMemo)(() => {
150
+ var _a;
151
+ return (Object.assign(Object.assign({}, chatDefaults_1.DEFAULT_TASK_CARD_SIZE), ((_a = props.taskCardSize) !== null && _a !== void 0 ? _a : {})));
152
+ }, [props.taskCardSize]);
153
+ const initPresets = (0, react_1.useMemo)(() => {
154
+ var _a;
155
+ return (Object.assign(Object.assign({}, chatDefaults_1.DEFAULT_INIT_PRESETS), ((_a = props.initPresets) !== null && _a !== void 0 ? _a : {})));
156
+ }, [props.initPresets]);
157
+ const themeVars = (0, react_1.useMemo)(() => ({
158
+ "--chat-background": theme.appBackground,
159
+ "--chat-surface": theme.panelBackground,
160
+ "--chat-surface-muted": theme.panelBackgroundMuted,
161
+ "--chat-surface-subtle": theme.panelBackgroundSubtle,
162
+ "--chat-primary": theme.brand,
163
+ "--chat-primary-hover": theme.brandHover,
164
+ "--chat-primary-30": theme.brandAlpha30,
165
+ "--chat-primary-40": theme.brandAlpha40,
166
+ "--chat-primary-50": theme.brandAlpha50,
167
+ "--chat-text-primary": theme.textMain,
168
+ "--chat-text-strong": theme.textEmphasis,
169
+ "--chat-text-secondary": theme.textSupporting,
170
+ "--chat-text-muted": theme.textMuted,
171
+ "--chat-text-subtle": theme.textSubtle,
172
+ "--chat-text-faint": theme.textDisabled,
173
+ "--chat-text-inverse": theme.textOnBrand,
174
+ "--chat-user-message-bg": theme.userMessageBackground,
175
+ "--chat-user-message-text": theme.userMessageText,
176
+ "--chat-neutral-50": theme.neutralLightest,
177
+ "--chat-neutral-100": theme.neutralLighter,
178
+ "--chat-neutral-400": theme.neutralMedium,
179
+ "--chat-neutral-800": theme.neutralDark,
180
+ "--chat-neutral-900": theme.neutralDarker,
181
+ "--chat-neutral-900-80": theme.neutralDarker80,
182
+ "--chat-border": theme.borderDefault,
183
+ "--chat-accent-bg": theme.accentBackground,
184
+ "--chat-accent-text": theme.accentText,
185
+ "--chat-warning-bg": theme.warningBackground,
186
+ "--chat-warning-text": theme.warningText,
187
+ "--chat-error-bg": theme.errorBackground,
188
+ "--chat-error-text": theme.errorText,
189
+ "--chat-ring": theme.focusRing,
190
+ "--chat-ring-strong": theme.focusRingStrong,
191
+ "--chat-shadow-outline": theme.outlineShadow,
192
+ "--chat-shadow-elevated": theme.elevatedShadow,
193
+ "--chat-select-option-hover": theme.selectOptionHover,
194
+ "--chat-card-selected-bg": theme.cardSelectedBackground,
195
+ "--chat-font-base": fonts.base || "inherit",
196
+ "--chat-font-heading": fonts.heading || fonts.base || "inherit",
197
+ "--chat-font-mono": fonts.mono || chatDefaults_1.DEFAULT_FONTS.mono,
198
+ }), [theme, fonts]);
199
+ const normalizeServiceBaseUrl = (value) => (value !== null && value !== void 0 ? value : "").trim().replace(/\/+$/, "");
200
+ const [isDab, setIsDab] = (0, react_1.useState)(() => { var _a; return (_a = sdkConfig.isDab) !== null && _a !== void 0 ? _a : false; });
201
+ const defaultDomain = isDab ? chatDefaults_1.DEFAULT_DOMAIN : "";
202
+ const [domain, setDomain] = (0, react_1.useState)(() => defaultDomain);
203
+ const [serviceBaseUrl, setServiceBaseUrl] = (0, react_1.useState)(() => {
204
+ var _a;
205
+ 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));
206
+ });
207
+ (0, react_1.useEffect)(() => {
208
+ if (serviceBaseUrl) {
209
+ localStorage_1.ls.set(storageKeys_1.STORAGE_KEYS.serviceBaseUrl, serviceBaseUrl);
210
+ }
211
+ else {
212
+ localStorage_1.ls.remove(storageKeys_1.STORAGE_KEYS.serviceBaseUrl);
213
+ }
214
+ }, [serviceBaseUrl]);
215
+ const [apiSubscriptionKey, setApiSubscriptionKey] = (0, react_1.useState)(() => {
216
+ var _a;
217
+ return (_a = sdkConfig.apiSubscriptionKey) !== null && _a !== void 0 ? _a : localStorage_1.ls.get(storageKeys_1.STORAGE_KEYS.apiSubscriptionKey, chatDefaults_1.DEFAULT_API_SUBSCRIPTION_KEY);
218
+ });
219
+ (0, react_1.useEffect)(() => {
220
+ if (apiSubscriptionKey) {
221
+ localStorage_1.ls.set(storageKeys_1.STORAGE_KEYS.apiSubscriptionKey, apiSubscriptionKey);
222
+ }
223
+ else {
224
+ localStorage_1.ls.remove(storageKeys_1.STORAGE_KEYS.apiSubscriptionKey);
225
+ }
226
+ }, [apiSubscriptionKey]);
227
+ const [loginSubscriptionKey, setLoginSubscriptionKey] = (0, react_1.useState)(() => { var _a; return (_a = sdkConfig.loginSubscriptionKey) !== null && _a !== void 0 ? _a : localStorage_1.ls.get(storageKeys_1.STORAGE_KEYS.loginSubscriptionKey, ""); });
228
+ (0, react_1.useEffect)(() => {
229
+ if (loginSubscriptionKey) {
230
+ localStorage_1.ls.set(storageKeys_1.STORAGE_KEYS.loginSubscriptionKey, loginSubscriptionKey);
231
+ }
232
+ else {
233
+ localStorage_1.ls.remove(storageKeys_1.STORAGE_KEYS.loginSubscriptionKey);
234
+ }
235
+ }, [loginSubscriptionKey]);
236
+ const requestStepBaseUrl = serviceBaseUrl
237
+ ? `${serviceBaseUrl}/RequestStep`
238
+ : "";
239
+ const transactionCatalogBaseUrl = serviceBaseUrl
240
+ ? `${serviceBaseUrl}/TransactionCatalog`
241
+ : "";
242
+ const storageBaseUrl = serviceBaseUrl ? `${serviceBaseUrl}/Storage` : "";
243
+ const signatureBaseUrl = serviceBaseUrl ? `${serviceBaseUrl}/Signature` : "";
244
+ const initEndpoint = serviceBaseUrl
245
+ ? `${serviceBaseUrl}/Transactionauthentication/api/CorrespondenceAuthentication/Login`
246
+ : "";
247
+ const initClientType = chatDefaults_1.DEFAULT_INIT_CLIENT_TYPE;
248
+ const speechRegion = (_a = props.speechRegion) !== null && _a !== void 0 ? _a : chatDefaults_1.DEFAULT_SPEECH_REGION;
249
+ const speechKey = (_b = props.speechKey) !== null && _b !== void 0 ? _b : chatDefaults_1.DEFAULT_SPEECH_KEY;
250
+ const initializeChatOnLoad = (_c = sdkConfig.initializeChat) !== null && _c !== void 0 ? _c : false;
251
+ const initPanelEnabled = (_d = sdkConfig.showInitPanel) !== null && _d !== void 0 ? _d : true;
252
+ // Connection / auth
253
+ const apiBase = chatDefaults_1.DEFAULT_API_BASE;
254
+ 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, "")); });
256
+ const [sessionId, setSessionId] = (0, react_1.useState)(() => localStorage_1.ls.get(storageKeys_1.STORAGE_KEYS.sessionId, (0, generateGuid_1.generateGuid)()));
257
+ 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]);
259
+ (0, react_1.useEffect)(() => localStorage_1.ls.set(storageKeys_1.STORAGE_KEYS.sessionId, sessionId), [sessionId]);
260
+ (0, react_1.useEffect)(() => {
261
+ setInitCompleted(localStorage_1.ls.get((0, storageKeys_1.getInitCompletedKey)(sessionId), false));
262
+ }, [sessionId]);
263
+ // context window selection (used for initializeChat and WS messages)
264
+ 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);
267
+ });
268
+ (0, react_1.useEffect)(() => localStorage_1.ls.set(storageKeys_1.STORAGE_KEYS.contextWindow, contextWindow), [contextWindow]);
269
+ // Real-time speech language (for transcription)
270
+ const [speechLang, setSpeechLang] = (0, react_1.useState)(() => {
271
+ var _a, _b;
272
+ return (_b = (_a = props.speechLanguage) !== null && _a !== void 0 ? _a : props.speechLang) !== null && _b !== void 0 ? _b : localStorage_1.ls.get(storageKeys_1.STORAGE_KEYS.speechLang, chatDefaults_1.DEFAULT_SPEECH_LANG);
273
+ });
274
+ (0, react_1.useEffect)(() => localStorage_1.ls.set(storageKeys_1.STORAGE_KEYS.speechLang, speechLang), [speechLang]);
275
+ const [inputLocale, setInputLocale] = (0, react_1.useState)(() => typeof navigator !== "undefined" && navigator.language
276
+ ? navigator.language
277
+ : "en-US");
278
+ const [keyboardDirection, setKeyboardDirection] = (0, react_1.useState)(null);
279
+ (0, react_1.useEffect)(() => {
280
+ if (typeof window === "undefined")
281
+ return;
282
+ const handleLanguageChange = () => setInputLocale(navigator.language || "en-US");
283
+ window.addEventListener("languagechange", handleLanguageChange);
284
+ return () => window.removeEventListener("languagechange", handleLanguageChange);
285
+ }, []);
286
+ // TTS language (separate from transcription)
287
+ const [ttsLang, setTtsLang] = (0, react_1.useState)(() => {
288
+ var _a, _b;
289
+ return (_b = (_a = props.ttsLanguage) !== null && _a !== void 0 ? _a : props.ttsLang) !== null && _b !== void 0 ? _b : localStorage_1.ls.get(storageKeys_1.STORAGE_KEYS.ttsLang, chatDefaults_1.DEFAULT_TTS_LANG);
290
+ });
291
+ (0, react_1.useEffect)(() => localStorage_1.ls.set(storageKeys_1.STORAGE_KEYS.ttsLang, ttsLang), [ttsLang]);
292
+ // favicon
293
+ (0, react_1.useEffect)(() => {
294
+ const svg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">` +
295
+ `<circle cx="32" cy="32" r="28" fill="#252525"/></svg>`;
296
+ const url = `data:image/svg+xml;utf8,${encodeURIComponent(svg)}`;
297
+ let link = document.querySelector("link[rel='icon']");
298
+ if (!link) {
299
+ link = document.createElement("link");
300
+ link.rel = "icon";
301
+ document.head.appendChild(link);
302
+ }
303
+ link.href = url;
304
+ }, []);
305
+ // chat state
306
+ const [messages, setMessages] = (0, react_1.useState)(() => localStorage_1.ls.get((0, storageKeys_1.getMessagesKey)(sessionId), []));
307
+ const [lastToolResult, setLastToolResult] = (0, react_1.useState)(null);
308
+ const [showToolOverlay, setShowToolOverlay] = (0, react_1.useState)(false);
309
+ const [input, setInput] = (0, react_1.useState)("");
310
+ const [pending, setPending] = (0, react_1.useState)(false);
311
+ const [selectedFiles, setSelectedFiles] = (0, react_1.useState)([]);
312
+ // init panel
313
+ 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 : "";
316
+ 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");
318
+ const [initUsername, setInitUsername] = (0, react_1.useState)(resolvedInitUsername);
319
+ const [initPassword, setInitPassword] = (0, react_1.useState)("");
320
+ const [initLoading, setInitLoading] = (0, react_1.useState)(false);
321
+ // Init panel extra fields per new API
322
+ const [initContextWindow, setInitContextWindow] = (0, react_1.useState)(contextWindow);
323
+ const [initServiceId, setInitServiceId] = (0, react_1.useState)(resolvedInitServiceId === undefined || resolvedInitServiceId === null
324
+ ? ""
325
+ : String(resolvedInitServiceId));
326
+ const [initRequestStepId, setInitRequestStepId] = (0, react_1.useState)(resolvedInitRequestStepId === undefined || resolvedInitRequestStepId === null
327
+ ? ""
328
+ : String(resolvedInitRequestStepId));
329
+ // Initializing message was removed from the backend (kept only for chat + speech features).
330
+ (0, react_1.useEffect)(() => localStorage_1.ls.set(storageKeys_1.STORAGE_KEYS.initUsername, initUsername), [initUsername]);
331
+ (0, react_1.useEffect)(() => localStorage_1.ls.set(storageKeys_1.STORAGE_KEYS.domain, domain), [domain]);
332
+ (0, react_1.useEffect)(() => {
333
+ setDomain(isDab ? chatDefaults_1.DEFAULT_DOMAIN : "");
334
+ }, [isDab]);
335
+ (0, react_1.useEffect)(() => {
336
+ if (props.initServiceId !== undefined) {
337
+ setInitServiceId(String(props.initServiceId));
338
+ }
339
+ }, [props.initServiceId]);
340
+ (0, react_1.useEffect)(() => {
341
+ if (props.initRequestStepId !== undefined) {
342
+ setInitRequestStepId(String(props.initRequestStepId));
343
+ }
344
+ }, [props.initRequestStepId]);
345
+ (0, react_1.useEffect)(() => {
346
+ if (!initPanelEnabled && showInitPanel) {
347
+ setShowInitPanel(false);
348
+ }
349
+ }, [initPanelEnabled, showInitPanel]);
350
+ const applyInitPreset = (preset) => {
351
+ setInitPreset(preset);
352
+ if (preset === "custom") {
353
+ setInitUsername("");
354
+ setInitPassword("");
355
+ return;
356
+ }
357
+ const presetValues = initPresets[preset];
358
+ if (presetValues === null || presetValues === void 0 ? void 0 : presetValues.username) {
359
+ setInitUsername(presetValues.username);
360
+ }
361
+ if (presetValues === null || presetValues === void 0 ? void 0 : presetValues.password) {
362
+ setInitPassword(presetValues.password);
363
+ }
364
+ };
365
+ (0, react_1.useEffect)(() => {
366
+ if (!props.initialInitPreset)
367
+ return;
368
+ applyInitPreset(props.initialInitPreset);
369
+ }, [props.initialInitPreset, initPresets]);
370
+ // doc viewer
371
+ const [overlayUrl, setOverlayUrl] = (0, react_1.useState)(null);
372
+ const [viewerUrl, setViewerUrl] = (0, react_1.useState)(null);
373
+ const [gdocUrl, setGdocUrl] = (0, react_1.useState)(null);
374
+ const [blobUrl, setBlobUrl] = (0, react_1.useState)(null);
375
+ const [viewerLoading, setViewerLoading] = (0, react_1.useState)(false);
376
+ const [viewerError, setViewerError] = (0, react_1.useState)(null);
377
+ const [viewerKey, setViewerKey] = (0, react_1.useState)(0);
378
+ const [viewerBlob, setViewerBlob] = (0, react_1.useState)(null);
379
+ const [viewerFilename, setViewerFilename] = (0, react_1.useState)(text.documentViewer.iframeTitle);
380
+ const gdocFallbackTimer = (0, react_1.useRef)(undefined);
381
+ // AvailableTasksCards popup
382
+ const [taskCardModalOpen, setTaskCardModalOpen] = (0, react_1.useState)(false);
383
+ const [activeTaskCard, setActiveTaskCard] = (0, react_1.useState)(null);
384
+ const [selectedTaskCard, setSelectedTaskCard] = (0, react_1.useState)(null);
385
+ const [takeActionOpen, setTakeActionOpen] = (0, react_1.useState)(false);
386
+ const [takeActionStep, setTakeActionStep] = (0, react_1.useState)(1);
387
+ const [takeActionChoice, setTakeActionChoice] = (0, react_1.useState)("");
388
+ const [takeActionComments, setTakeActionComments] = (0, react_1.useState)("");
389
+ const [takeActionAttributes, setTakeActionAttributes] = (0, react_1.useState)([]);
390
+ const [takeActionSubmitting, setTakeActionSubmitting] = (0, react_1.useState)(false);
391
+ const [takeActionError, setTakeActionError] = (0, react_1.useState)(null);
392
+ const [takeActionProceedOpen, setTakeActionProceedOpen] = (0, react_1.useState)(false);
393
+ const [takeActionProceedData, setTakeActionProceedData] = (0, react_1.useState)(null);
394
+ const [userSignatures, setUserSignatures] = (0, react_1.useState)([]);
395
+ const openTaskCardModal = (card) => {
396
+ setActiveTaskCard(card);
397
+ setTaskCardModalOpen(true);
398
+ };
399
+ const closeTaskCardModal = () => {
400
+ setTaskCardModalOpen(false);
401
+ setActiveTaskCard(null);
402
+ };
403
+ const resetTakeActionState = () => {
404
+ setTakeActionStep(1);
405
+ setTakeActionChoice("");
406
+ setTakeActionComments("");
407
+ setTakeActionAttributes([]);
408
+ setTakeActionError(null);
409
+ };
410
+ const openTakeActionModal = (card) => {
411
+ var _a;
412
+ setActiveTaskCard(card);
413
+ const attrs = Array.isArray(card.RequestAttributeList)
414
+ ? card.RequestAttributeList.map((attr) => (Object.assign(Object.assign({}, attr), { Value: attr.Value === undefined || attr.Value === null ? "" : attr.Value })))
415
+ : [];
416
+ const signatureAliasFromCard = (_a = card.MetaData) === null || _a === void 0 ? void 0 : _a.SignatureAttributeAlias;
417
+ const mergedAttrs = attrs.map((attr) => {
418
+ if (signatureAliasFromCard &&
419
+ attr.Alias === signatureAliasFromCard &&
420
+ (!Array.isArray(attr.Options) || attr.Options.length === 0)) {
421
+ return Object.assign(Object.assign({}, attr), { Options: userSignatures });
422
+ }
423
+ return attr;
424
+ });
425
+ setTakeActionAttributes(mergedAttrs);
426
+ setTakeActionOpen(true);
427
+ setTakeActionStep(1);
428
+ setTakeActionChoice("");
429
+ setTakeActionComments("");
430
+ setTakeActionError(null);
431
+ setTakeActionProceedOpen(false);
432
+ setTakeActionProceedData(null);
433
+ };
434
+ const closeTakeActionModal = (keepProceedState = false) => {
435
+ setTakeActionOpen(false);
436
+ resetTakeActionState();
437
+ if (!keepProceedState) {
438
+ setTakeActionProceedOpen(false);
439
+ setTakeActionProceedData(null);
440
+ }
441
+ };
442
+ const handleTakeActionBack = () => {
443
+ if (takeActionStep === 2) {
444
+ setTakeActionStep(1);
445
+ return;
446
+ }
447
+ closeTakeActionModal();
448
+ if (activeTaskCard) {
449
+ setTaskCardModalOpen(true);
450
+ }
451
+ };
452
+ const toggleTaskCardSelection = (card) => {
453
+ const currentId = selectedTaskCard === null || selectedTaskCard === void 0 ? void 0 : selectedTaskCard.RequestId;
454
+ if (currentId !== undefined && String(currentId) === String(card.RequestId)) {
455
+ setSelectedTaskCard(null);
456
+ return;
457
+ }
458
+ setSelectedTaskCard(card);
459
+ };
460
+ const removeTaskCardFromMessages = (requestStepId) => {
461
+ setMessages((prev) => prev.map((m) => {
462
+ if (!m.availableTasksCards || m.availableTasksCards.length === 0)
463
+ return m;
464
+ const filtered = m.availableTasksCards.filter((card) => {
465
+ var _a;
466
+ const cardStepId = (_a = card.RequestStepId) !== null && _a !== void 0 ? _a : card.RequestId;
467
+ return String(cardStepId) !== String(requestStepId);
468
+ });
469
+ if (filtered.length === m.availableTasksCards.length)
470
+ return m;
471
+ if (filtered.length === 0) {
472
+ const { availableTasksCards } = m, rest = __rest(m, ["availableTasksCards"]);
473
+ return rest;
474
+ }
475
+ return Object.assign(Object.assign({}, m), { availableTasksCards: filtered });
476
+ }));
477
+ setSelectedTaskCard((prev) => {
478
+ var _a;
479
+ if (!prev)
480
+ return prev;
481
+ const prevId = (_a = prev.RequestStepId) !== null && _a !== void 0 ? _a : prev.RequestId;
482
+ return String(prevId) === String(requestStepId) ? null : prev;
483
+ });
484
+ setActiveTaskCard((prev) => {
485
+ var _a;
486
+ if (!prev)
487
+ return prev;
488
+ const prevId = (_a = prev.RequestStepId) !== null && _a !== void 0 ? _a : prev.RequestId;
489
+ return String(prevId) === String(requestStepId) ? null : prev;
490
+ });
491
+ };
492
+ // Note: We no longer pin an "initializing" banner. Cards are attached to assistant messages as returned.
493
+ // voice (transcription)
494
+ const [voiceMode, setVoiceMode] = (0, react_1.useState)(false);
495
+ const [voiceError, setVoiceError] = (0, react_1.useState)(null);
496
+ const [voiceUploading, setVoiceUploading] = (0, react_1.useState)(false); // kept as "busy" flag for UX
497
+ const mediaStreamRef = (0, react_1.useRef)(null);
498
+ const audioCtxRef = (0, react_1.useRef)(null);
499
+ const analyserRef = (0, react_1.useRef)(null);
500
+ const rafRef = (0, react_1.useRef)(null);
501
+ const [waveData, setWaveData] = (0, react_1.useState)(() => Array(40).fill(4));
502
+ // Azure Speech SDK
503
+ const sdkRef = (0, react_1.useRef)(null);
504
+ const recognizerRef = (0, react_1.useRef)(null);
505
+ // Speech text refs for composing input
506
+ const speechBaseInputRef = (0, react_1.useRef)(null);
507
+ const speechFinalRef = (0, react_1.useRef)(""); // final recognized segments
508
+ const speechLiveRef = (0, react_1.useRef)(""); // current partial
509
+ // We'll use inputRef to always have the latest input string (mainly if you extend logic later)
510
+ const inputRef = (0, react_1.useRef)("");
511
+ const autoInitAttemptedRef = (0, react_1.useRef)(false);
512
+ const autoInitConfigKey = (0, react_1.useMemo)(() => [
513
+ initializeChatOnLoad ? "1" : "0",
514
+ initUsername,
515
+ initPassword,
516
+ domain,
517
+ initContextWindow,
518
+ initServiceId,
519
+ initRequestStepId,
520
+ ].join("|"), [
521
+ initializeChatOnLoad,
522
+ initUsername,
523
+ initPassword,
524
+ domain,
525
+ initContextWindow,
526
+ initServiceId,
527
+ initRequestStepId,
528
+ ]);
529
+ // TTS state
530
+ const ttsSynthRef = (0, react_1.useRef)(null);
531
+ const [speakingMessageIndex, setSpeakingMessageIndex] = (0, react_1.useState)(null);
532
+ // refs
533
+ const fileInputRef = (0, react_1.useRef)(null);
534
+ const listEndRef = (0, react_1.useRef)(null);
535
+ const composerRef = (0, react_1.useRef)(null);
536
+ // persist messages
537
+ (0, react_1.useEffect)(() => {
538
+ localStorage_1.ls.set((0, storageKeys_1.getMessagesKey)(sessionId), messages);
539
+ }, [messages, sessionId]);
540
+ // keep inputRef in sync
541
+ (0, react_1.useEffect)(() => {
542
+ inputRef.current = input;
543
+ }, [input]);
544
+ (0, react_1.useEffect)(() => {
545
+ autoInitAttemptedRef.current = false;
546
+ }, [autoInitConfigKey]);
547
+ (0, react_1.useEffect)(() => {
548
+ const shouldAutoInit = initializeChatOnLoad;
549
+ if (!shouldAutoInit || initLoading || initCompleted)
550
+ return;
551
+ if (!authToken && (!initUsername.trim() || !initPassword))
552
+ return;
553
+ if (autoInitAttemptedRef.current)
554
+ return;
555
+ autoInitAttemptedRef.current = true;
556
+ void initializeSession({ runInitializeChatClients: true });
557
+ }, [
558
+ initializeChatOnLoad,
559
+ authToken,
560
+ initLoading,
561
+ initCompleted,
562
+ initUsername,
563
+ initPassword,
564
+ autoInitConfigKey,
565
+ ]);
566
+ // auto scroll
567
+ (0, react_1.useEffect)(() => {
568
+ var _a;
569
+ (_a = listEndRef.current) === null || _a === void 0 ? void 0 : _a.scrollIntoView({ behavior: "smooth" });
570
+ }, [messages, pending]);
571
+ const chatIsRtl = (0, textDirection_1.isRtlLocale)(speechLang);
572
+ const localeDirection = (0, textDirection_1.isRtlLocale)(inputLocale) ? "rtl" : "ltr";
573
+ const inputDirection = (0, react_1.useMemo)(() => { var _a, _b; return (_b = (_a = (0, textDirection_1.getTextDirection)(input)) !== null && _a !== void 0 ? _a : keyboardDirection) !== null && _b !== void 0 ? _b : localeDirection; }, [input, keyboardDirection, localeDirection]);
574
+ const inputIsRtl = inputDirection === "rtl";
575
+ // hydrate from server
576
+ (0, react_1.useEffect)(() => {
577
+ if (!apiBase || !apiKey || !sessionId)
578
+ return;
579
+ const controller = new AbortController();
580
+ let cancelled = false;
581
+ (() => __awaiter(this, void 0, void 0, function* () {
582
+ var _a;
583
+ try {
584
+ const res = yield fetch(new URL(`/api/getSessionConversation`, apiBase).toString(), {
585
+ method: "POST",
586
+ signal: controller.signal,
587
+ headers: Object.assign({ "Content-Type": "application/json", "api-key": apiKey }, (authToken ? { Authorization: authToken } : {})),
588
+ body: JSON.stringify({
589
+ Domain: domain.trim(),
590
+ SessionId: sessionId,
591
+ }),
592
+ });
593
+ if (!res.ok) {
594
+ if (res.status === 401) {
595
+ return;
596
+ }
597
+ throw new Error(`${res.status} ${res.statusText}`);
598
+ }
599
+ const raw = yield res.json();
600
+ if (cancelled)
601
+ return;
602
+ const serverConvoRaw = Array.isArray(raw === null || raw === void 0 ? void 0 : raw.SessionConversation)
603
+ ? raw.SessionConversation
604
+ : Array.isArray(raw)
605
+ ? raw
606
+ : [];
607
+ const serverConvo = (serverConvoRaw || []).map((m) => {
608
+ var _a, _b;
609
+ const cards = Array.isArray(m === null || m === void 0 ? void 0 : m.SelectedTasksCards)
610
+ ? m.SelectedTasksCards
611
+ : Array.isArray(m === null || m === void 0 ? void 0 : m.SelectedTaskCards)
612
+ ? m.SelectedTaskCards
613
+ : Array.isArray(m === null || m === void 0 ? void 0 : m.AvailableTasksCards)
614
+ ? m.AvailableTasksCards
615
+ : Array.isArray(m === null || m === void 0 ? void 0 : m.Cards)
616
+ ? m.Cards
617
+ : Array.isArray(m === null || m === void 0 ? void 0 : m.AvailableTasks)
618
+ ? m.AvailableTasks
619
+ : [];
620
+ return Object.assign({ role: m.role, content: (_a = m.content) !== null && _a !== void 0 ? _a : "", ts: (_b = m.ts) !== null && _b !== void 0 ? _b : Date.now() }, (cards.length ? { availableTasksCards: cards } : {}));
621
+ });
622
+ if (Array.isArray((_a = raw === null || raw === void 0 ? void 0 : raw.Profile) === null || _a === void 0 ? void 0 : _a.UserSignatures)) {
623
+ setUserSignatures(raw.Profile.UserSignatures);
624
+ }
625
+ const topCards = Array.isArray(raw === null || raw === void 0 ? void 0 : raw.SelectedTasksCards)
626
+ ? raw.SelectedTasksCards
627
+ : Array.isArray(raw === null || raw === void 0 ? void 0 : raw.SelectedTaskCards)
628
+ ? raw.SelectedTaskCards
629
+ : [];
630
+ if (topCards.length && serverConvo.length) {
631
+ for (let i = serverConvo.length - 1; i >= 0; i--) {
632
+ if (serverConvo[i].role === "Assistant") {
633
+ serverConvo[i] = Object.assign(Object.assign({}, serverConvo[i]), { availableTasksCards: topCards });
634
+ break;
635
+ }
636
+ }
637
+ }
638
+ setMessages(serverConvo);
639
+ }
640
+ catch (err) {
641
+ if ((err === null || err === void 0 ? void 0 : err.name) === "AbortError")
642
+ return;
643
+ setMessages((prev) => prev.length
644
+ ? prev
645
+ : [
646
+ {
647
+ role: "Assistant",
648
+ content: text.alerts.fetchHistoryFailed,
649
+ ts: Date.now(),
650
+ },
651
+ ]);
652
+ }
653
+ }))();
654
+ return () => {
655
+ cancelled = true;
656
+ controller.abort();
657
+ };
658
+ }, [apiBase, apiKey, authToken, sessionId, domain]);
659
+ const canSend = (0, react_1.useMemo)(() => (!!input.trim() || selectedFiles.length > 0 || !!selectedTaskCard) &&
660
+ !!sessionId &&
661
+ !!apiBase &&
662
+ !!apiKey &&
663
+ !pending, [input, selectedFiles, sessionId, apiBase, apiKey, pending]);
664
+ function autosizeTextarea(el) {
665
+ if (!el)
666
+ return;
667
+ el.style.height = "0px";
668
+ el.style.height = Math.min(el.scrollHeight, 320) + "px";
669
+ }
670
+ (0, react_1.useEffect)(() => {
671
+ autosizeTextarea(composerRef.current);
672
+ }, [input]);
673
+ 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;
674
+ const visibleTakeActionAttributes = (0, react_1.useMemo)(() => {
675
+ return takeActionAttributes
676
+ .filter((attr) => attr.IsProviderVisible)
677
+ .slice()
678
+ .sort((a, b) => a.SequenceNo - b.SequenceNo);
679
+ }, [takeActionAttributes]);
680
+ const updateTakeActionAttributeValue = (attr, nextValue) => {
681
+ setTakeActionAttributes((prev) => prev.map((item) => {
682
+ const same = (item.Alias && item.Alias === attr.Alias) ||
683
+ (item.Name && item.Name === attr.Name) ||
684
+ item.AttributeTypeId === attr.AttributeTypeId;
685
+ if (!same)
686
+ return item;
687
+ return Object.assign(Object.assign({}, item), { Value: nextValue });
688
+ }));
689
+ };
690
+ const requestHeaders = (0, react_1.useMemo)(() => (0, api_1.buildRequestHeaders)({ authToken, apiSubscriptionKey }), [authToken, apiSubscriptionKey]);
691
+ function stopVisualizer() {
692
+ if (rafRef.current) {
693
+ cancelAnimationFrame(rafRef.current);
694
+ rafRef.current = null;
695
+ }
696
+ if (audioCtxRef.current) {
697
+ audioCtxRef.current.close().catch(() => { });
698
+ audioCtxRef.current = null;
699
+ }
700
+ analyserRef.current = null;
701
+ setWaveData(Array(40).fill(4));
702
+ }
703
+ function teardownSpeechRecognition() {
704
+ try {
705
+ if (recognizerRef.current) {
706
+ recognizerRef.current.stopContinuousRecognitionAsync(() => {
707
+ recognizerRef.current.close();
708
+ recognizerRef.current = null;
709
+ }, () => {
710
+ try {
711
+ recognizerRef.current.close();
712
+ }
713
+ catch (_a) { }
714
+ recognizerRef.current = null;
715
+ });
716
+ }
717
+ }
718
+ catch (_a) { }
719
+ if (mediaStreamRef.current) {
720
+ mediaStreamRef.current.getTracks().forEach((t) => t.stop());
721
+ mediaStreamRef.current = null;
722
+ }
723
+ stopVisualizer();
724
+ }
725
+ // Compose input from base + speechFinal + speechLive
726
+ function updateInputFromSpeech() {
727
+ var _a;
728
+ const base = ((_a = speechBaseInputRef.current) !== null && _a !== void 0 ? _a : "").trimEnd();
729
+ const seg = `${speechFinalRef.current} ${speechLiveRef.current}`.trim();
730
+ const combined = base ? (seg ? `${base} ${seg}` : base) : seg;
731
+ setInput(combined);
732
+ requestAnimationFrame(() => autosizeTextarea(composerRef.current));
733
+ }
734
+ function startSpeechRecognition() {
735
+ return __awaiter(this, void 0, void 0, function* () {
736
+ var _a, _b;
737
+ setVoiceError(null);
738
+ setVoiceUploading(false);
739
+ // store base input (so cancel restores it)
740
+ speechBaseInputRef.current = input;
741
+ speechFinalRef.current = "";
742
+ speechLiveRef.current = "";
743
+ // 1) mic + visualizer
744
+ try {
745
+ const stream = yield navigator.mediaDevices.getUserMedia({
746
+ audio: true,
747
+ });
748
+ mediaStreamRef.current = stream;
749
+ const AC = window.AudioContext || window.webkitAudioContext;
750
+ const audioCtx = new AC();
751
+ yield audioCtx.resume();
752
+ const source = audioCtx.createMediaStreamSource(stream);
753
+ const analyser = audioCtx.createAnalyser();
754
+ analyser.fftSize = 256;
755
+ analyser.smoothingTimeConstant = 0.6;
756
+ source.connect(analyser);
757
+ audioCtxRef.current = audioCtx;
758
+ analyserRef.current = analyser;
759
+ const bufferLength = analyser.frequencyBinCount;
760
+ const dataArray = new Uint8Array(bufferLength);
761
+ const tick = () => {
762
+ if (!analyserRef.current)
763
+ return;
764
+ analyserRef.current.getByteTimeDomainData(dataArray);
765
+ let sum = 0;
766
+ for (let i = 0; i < dataArray.length; i++) {
767
+ const v = dataArray[i] - 128;
768
+ sum += Math.abs(v);
769
+ }
770
+ const avg = sum / dataArray.length;
771
+ const normalized = Math.min(1, avg / 30);
772
+ const base = 4;
773
+ const max = 26;
774
+ const bars = Array.from({ length: 40 }, (_, i) => {
775
+ const factor = 0.75 + (i % 5) * 0.05;
776
+ return base + normalized * max * factor;
777
+ });
778
+ setWaveData(bars);
779
+ rafRef.current = requestAnimationFrame(tick);
780
+ };
781
+ tick();
782
+ }
783
+ catch (err) {
784
+ setVoiceError((_a = err === null || err === void 0 ? void 0 : err.message) !== null && _a !== void 0 ? _a : text.errors.microphoneAccess);
785
+ }
786
+ // 2) Speech SDK continuous recognition
787
+ try {
788
+ if (!sdkRef.current) {
789
+ sdkRef.current = yield Promise.resolve().then(() => __importStar(require("microsoft-cognitiveservices-speech-sdk")));
790
+ }
791
+ const sdk = sdkRef.current;
792
+ const config = sdk.SpeechConfig.fromSubscription(speechKey, speechRegion);
793
+ // language from init panel (English(US) / Arabic(JO))
794
+ config.speechRecognitionLanguage = speechLang; // "en-US" or "ar-JO"
795
+ const audioCfg = sdk.AudioConfig.fromDefaultMicrophoneInput();
796
+ const recognizer = new sdk.SpeechRecognizer(config, audioCfg);
797
+ recognizerRef.current = recognizer;
798
+ recognizer.recognizing = (_s, e) => {
799
+ var _a;
800
+ speechLiveRef.current = ((_a = e === null || e === void 0 ? void 0 : e.result) === null || _a === void 0 ? void 0 : _a.text) || "";
801
+ updateInputFromSpeech();
802
+ };
803
+ recognizer.recognized = (_s, e) => {
804
+ var _a;
805
+ const t = (_a = e === null || e === void 0 ? void 0 : e.result) === null || _a === void 0 ? void 0 : _a.text;
806
+ if (t) {
807
+ speechFinalRef.current = speechFinalRef.current
808
+ ? `${speechFinalRef.current} ${t}`
809
+ : t;
810
+ speechLiveRef.current = "";
811
+ updateInputFromSpeech();
812
+ }
813
+ };
814
+ recognizer.canceled = (_s, e) => {
815
+ if (e === null || e === void 0 ? void 0 : e.errorDetails) {
816
+ setVoiceError(e.errorDetails);
817
+ }
818
+ };
819
+ recognizer.sessionStopped = () => {
820
+ // no-op; we'll clean up explicitly
821
+ };
822
+ yield new Promise((resolve, reject) => {
823
+ recognizer.startContinuousRecognitionAsync(resolve, reject);
824
+ });
825
+ setVoiceMode(true);
826
+ }
827
+ catch (err) {
828
+ setVoiceError((_b = err === null || err === void 0 ? void 0 : err.message) !== null && _b !== void 0 ? _b : text.errors.transcriptionStart);
829
+ stopVisualizer();
830
+ if (mediaStreamRef.current) {
831
+ mediaStreamRef.current.getTracks().forEach((t) => t.stop());
832
+ mediaStreamRef.current = null;
833
+ }
834
+ try {
835
+ if (recognizerRef.current) {
836
+ recognizerRef.current.stopContinuousRecognitionAsync(() => { }, () => { });
837
+ recognizerRef.current.close();
838
+ recognizerRef.current = null;
839
+ }
840
+ }
841
+ catch (_c) { }
842
+ }
843
+ });
844
+ }
845
+ function cancelVoice() {
846
+ var _a;
847
+ // restore base (value before starting speech)
848
+ const base = (_a = speechBaseInputRef.current) !== null && _a !== void 0 ? _a : "";
849
+ setInput(base);
850
+ requestAnimationFrame(() => autosizeTextarea(composerRef.current));
851
+ speechBaseInputRef.current = null;
852
+ speechFinalRef.current = "";
853
+ speechLiveRef.current = "";
854
+ teardownSpeechRecognition();
855
+ setVoiceMode(false);
856
+ }
857
+ function confirmVoice() {
858
+ // Keep whatever is currently in input (base + speech text)
859
+ speechBaseInputRef.current = null;
860
+ speechFinalRef.current = "";
861
+ speechLiveRef.current = "";
862
+ teardownSpeechRecognition();
863
+ setVoiceMode(false);
864
+ }
865
+ // TTS stop
866
+ function stopSpeaking() {
867
+ if (ttsSynthRef.current) {
868
+ const inst = ttsSynthRef.current;
869
+ // If it's a synthesizer
870
+ if (inst.stopSpeakingAsync) {
871
+ try {
872
+ inst.stopSpeakingAsync(() => { }, () => { });
873
+ }
874
+ catch (_a) { }
875
+ try {
876
+ inst.close();
877
+ }
878
+ catch (_b) { }
879
+ }
880
+ // If it's an HTMLAudioElement
881
+ if (inst instanceof HTMLAudioElement) {
882
+ try {
883
+ inst.pause();
884
+ }
885
+ catch (_c) { }
886
+ try {
887
+ inst.currentTime = 0;
888
+ }
889
+ catch (_d) { }
890
+ }
891
+ }
892
+ ttsSynthRef.current = null;
893
+ setSpeakingMessageIndex(null);
894
+ }
895
+ // TTS: speak assistant message content using Alloy MultilingualNeuralHD
896
+ function speakMessage(text, index) {
897
+ return __awaiter(this, void 0, void 0, function* () {
898
+ var _a;
899
+ // 1) Clean markdown & special characters
900
+ const cleaned = text
901
+ .replace(/\*\*/g, " ")
902
+ .replace(/\*/g, " ")
903
+ .replace(/#/g, " ")
904
+ .replace(/\//g, " ")
905
+ .replace(/_/g, " ")
906
+ .replace(/`/g, " ")
907
+ .replace(/\|/g, " ")
908
+ .replace(/~/g, " ")
909
+ .replace(/>/g, " ")
910
+ .replace(/</g, " ")
911
+ .replace(/\r/g, "")
912
+ .replace(/\n+/g, "\n")
913
+ .trim();
914
+ if (!cleaned)
915
+ return;
916
+ const finalText = cleaned.replace(/\n/g, "\n");
917
+ // Stop anything already speaking
918
+ stopSpeaking();
919
+ try {
920
+ if (!sdkRef.current) {
921
+ sdkRef.current = yield Promise.resolve().then(() => __importStar(require("microsoft-cognitiveservices-speech-sdk")));
922
+ }
923
+ const sdk = sdkRef.current;
924
+ const speechConfig = sdk.SpeechConfig.fromSubscription(speechKey, speechRegion);
925
+ const voiceName = (_a = ttsVoiceMap[ttsLang]) !== null && _a !== void 0 ? _a : "en-US-RyanMultilingualNeural";
926
+ speechConfig.speechSynthesisVoiceName = voiceName;
927
+ // ❗ We do NOT use AudioConfig.fromDefaultSpeakerOutput()
928
+ const audioConfig = null;
929
+ const synthesizer = new sdk.SpeechSynthesizer(speechConfig, audioConfig);
930
+ ttsSynthRef.current = synthesizer;
931
+ setSpeakingMessageIndex(index); // show “X”
932
+ synthesizer.speakTextAsync(finalText, (result) => {
933
+ if (result.reason === sdk.ResultReason.SynthesizingAudioCompleted) {
934
+ // Convert binary data to audio blob
935
+ const audioBuffer = result.audioData;
936
+ const blob = new Blob([audioBuffer], { type: "audio/wav" });
937
+ // Create HTMLAudioElement
938
+ const audio = new Audio();
939
+ audio.src = URL.createObjectURL(blob);
940
+ // Save player so stopSpeaking() works
941
+ ttsSynthRef.current = audio;
942
+ // Handle ending of playback
943
+ audio.onended = () => {
944
+ setSpeakingMessageIndex(null);
945
+ ttsSynthRef.current = null;
946
+ };
947
+ // Start playback
948
+ audio.play().catch((err) => {
949
+ console.error("Audio play failed:", err);
950
+ setSpeakingMessageIndex(null);
951
+ });
952
+ }
953
+ }, (err) => {
954
+ console.error("TTS synthesis error:", err);
955
+ try {
956
+ synthesizer.close();
957
+ }
958
+ catch (_a) { }
959
+ ttsSynthRef.current = null;
960
+ setSpeakingMessageIndex(null);
961
+ });
962
+ }
963
+ catch (err) {
964
+ console.error("TTS start error:", err);
965
+ ttsSynthRef.current = null;
966
+ setSpeakingMessageIndex(null);
967
+ }
968
+ });
969
+ }
970
+ // cleanup on unmount
971
+ (0, react_1.useEffect)(() => {
972
+ return () => {
973
+ teardownSpeechRecognition();
974
+ stopSpeaking();
975
+ };
976
+ // eslint-disable-next-line react-hooks/exhaustive-deps
977
+ }, []);
978
+ // send message via HTTP (no streaming)
979
+ function sendMessage() {
980
+ return __awaiter(this, void 0, void 0, function* () {
981
+ var _a, _b;
982
+ if (!sessionId)
983
+ return;
984
+ if (!initCompleted) {
985
+ if (initPanelEnabled) {
986
+ setShowInitPanel(true);
987
+ }
988
+ alert(text.alerts.initRequired);
989
+ return;
990
+ }
991
+ const promptText = input.trim();
992
+ const hasText = !!promptText;
993
+ const hasFiles = selectedFiles.length > 0;
994
+ const hasSelectedCard = !!selectedTaskCard;
995
+ if (!hasText && !hasFiles && !hasSelectedCard)
996
+ return;
997
+ const filesToUpload = selectedFiles;
998
+ const attachmentsForMessage = filesToUpload.map((f) => ({
999
+ name: f.name,
1000
+ }));
1001
+ const selectionLine = hasSelectedCard
1002
+ ? formatText(text.composer.selectionLineTemplate, {
1003
+ id: String((_a = selectedTaskCard === null || selectedTaskCard === void 0 ? void 0 : selectedTaskCard.RequestId) !== null && _a !== void 0 ? _a : ""),
1004
+ })
1005
+ : "";
1006
+ const userContent = selectionLine
1007
+ ? promptText
1008
+ ? `${selectionLine}\n${promptText}`
1009
+ : selectionLine
1010
+ : promptText;
1011
+ const userMsg = {
1012
+ role: "User",
1013
+ content: userContent,
1014
+ attachments: attachmentsForMessage.length ? attachmentsForMessage : undefined,
1015
+ ts: Date.now(),
1016
+ };
1017
+ setMessages((prev) => [...(prev || []), userMsg]);
1018
+ // clear composer + files
1019
+ setInput("");
1020
+ setSelectedFiles([]);
1021
+ if (fileInputRef.current)
1022
+ fileInputRef.current.value = "";
1023
+ requestAnimationFrame(() => autosizeTextarea(composerRef.current));
1024
+ setPending(true);
1025
+ try {
1026
+ // 1) attachments upload (if any)
1027
+ if (filesToUpload.length > 0) {
1028
+ const fd = new FormData();
1029
+ const sessionDomain = domain.trim();
1030
+ fd.append("Domain", sessionDomain);
1031
+ fd.append("SessionId", sessionId);
1032
+ for (const f of filesToUpload)
1033
+ fd.append("files", f);
1034
+ const uploadUrl = new URL("/api/uploadChatAttachments", apiBase);
1035
+ const sasRes = yield fetch(uploadUrl.toString(), {
1036
+ method: "POST",
1037
+ headers: Object.assign({ "api-key": apiKey }, (authToken ? { Authorization: authToken } : {})),
1038
+ body: fd,
1039
+ });
1040
+ if (!sasRes.ok) {
1041
+ let details = "";
1042
+ try {
1043
+ details = yield sasRes.text();
1044
+ }
1045
+ catch (_c) { }
1046
+ throw new Error(formatText(text.errors.sasRequestFailedTemplate, {
1047
+ status: sasRes.status,
1048
+ statusText: sasRes.statusText,
1049
+ details: details ? ` - ${details}` : "",
1050
+ }));
1051
+ }
1052
+ const sasJson = yield sasRes.json();
1053
+ const sasList = Array.isArray(sasJson)
1054
+ ? sasJson
1055
+ : Array.isArray(sasJson === null || sasJson === void 0 ? void 0 : sasJson.Attachments)
1056
+ ? sasJson.Attachments
1057
+ : [];
1058
+ if (!Array.isArray(sasList) || sasList.length === 0) {
1059
+ throw new Error(text.errors.noSasEntries);
1060
+ }
1061
+ for (let i = 0; i < filesToUpload.length; i++) {
1062
+ const file = filesToUpload[i];
1063
+ const entry = sasList[i] || sasList[0];
1064
+ if (!(entry === null || entry === void 0 ? void 0 : entry.AttachmentName) || !(entry === null || entry === void 0 ? void 0 : entry.AttachmentSAS)) {
1065
+ throw new Error(text.errors.invalidSasEntry);
1066
+ }
1067
+ yield (0, api_1.uploadFileWithSAS)(entry.AttachmentSAS, entry.AttachmentName, file);
1068
+ }
1069
+ }
1070
+ // 2) HTTP chat call (backend returns assistant response + list of cards)
1071
+ const sessionDomain = domain.trim();
1072
+ const payload = {
1073
+ Domain: sessionDomain,
1074
+ ContextWindow: contextWindow,
1075
+ SessionId: sessionId,
1076
+ UserMessage: userContent,
1077
+ };
1078
+ if ((selectedTaskCard === null || selectedTaskCard === void 0 ? void 0 : selectedTaskCard.RequestId) !== undefined && (selectedTaskCard === null || selectedTaskCard === void 0 ? void 0 : selectedTaskCard.RequestId) !== null) {
1079
+ payload.RequestId = selectedTaskCard.RequestId;
1080
+ }
1081
+ if (initServiceId && initServiceId.trim() !== "") {
1082
+ const n = Number(initServiceId);
1083
+ if (!Number.isNaN(n))
1084
+ payload.ServiceId = n;
1085
+ }
1086
+ if (initRequestStepId && initRequestStepId.trim() !== "") {
1087
+ const n = Number(initRequestStepId);
1088
+ if (!Number.isNaN(n))
1089
+ payload.RequestStepId = n;
1090
+ }
1091
+ const chatRes = yield fetch(new URL("/api/chat", apiBase).toString(), {
1092
+ method: "POST",
1093
+ headers: Object.assign({ "Content-Type": "application/json", "api-key": apiKey }, (authToken ? { Authorization: authToken } : {})),
1094
+ credentials: "include",
1095
+ body: JSON.stringify(payload),
1096
+ });
1097
+ if (!chatRes.ok) {
1098
+ let msg = "";
1099
+ try {
1100
+ msg = yield chatRes.text();
1101
+ }
1102
+ catch (_d) { }
1103
+ throw new Error(formatText(text.errors.chatFailedTemplate, {
1104
+ status: chatRes.status,
1105
+ statusText: chatRes.statusText,
1106
+ details: msg ? ` - ${msg}` : "",
1107
+ }));
1108
+ }
1109
+ let raw = {};
1110
+ let rawText = null;
1111
+ try {
1112
+ raw = yield chatRes.json();
1113
+ }
1114
+ catch (_e) {
1115
+ try {
1116
+ rawText = yield chatRes.text();
1117
+ }
1118
+ catch (_f) { }
1119
+ }
1120
+ const assistantText = (typeof (raw === null || raw === void 0 ? void 0 : raw.AIMessage) === "string" && raw.AIMessage) ||
1121
+ (typeof (raw === null || raw === void 0 ? void 0 : raw.AssistantMessage) === "string" && raw.AssistantMessage) ||
1122
+ (typeof (raw === null || raw === void 0 ? void 0 : raw.assistantMessage) === "string" && raw.assistantMessage) ||
1123
+ (typeof rawText === "string" && rawText) ||
1124
+ "";
1125
+ const cards = Array.isArray(raw === null || raw === void 0 ? void 0 : raw.SelectedTasksCards)
1126
+ ? raw.SelectedTasksCards
1127
+ : Array.isArray(raw === null || raw === void 0 ? void 0 : raw.SelectedTaskCards)
1128
+ ? raw.SelectedTaskCards
1129
+ : Array.isArray(raw === null || raw === void 0 ? void 0 : raw.Cards)
1130
+ ? raw.Cards
1131
+ : Array.isArray(raw === null || raw === void 0 ? void 0 : raw.AvailableTasksCards)
1132
+ ? raw.AvailableTasksCards
1133
+ : Array.isArray(raw === null || raw === void 0 ? void 0 : raw.AvailableTasks)
1134
+ ? raw.AvailableTasks
1135
+ : [];
1136
+ const signatures = Array.isArray((_b = raw === null || raw === void 0 ? void 0 : raw.Profile) === null || _b === void 0 ? void 0 : _b.UserSignatures)
1137
+ ? raw.Profile.UserSignatures
1138
+ : [];
1139
+ setUserSignatures(signatures);
1140
+ if (typeof (raw === null || raw === void 0 ? void 0 : raw.ToolResult) !== "undefined" && (raw === null || raw === void 0 ? void 0 : raw.ToolResult) !== null) {
1141
+ setLastToolResult(raw.ToolResult);
1142
+ }
1143
+ // If backend returns the full conversation, prefer it (prevents drift)
1144
+ if (Array.isArray(raw === null || raw === void 0 ? void 0 : raw.SessionConversation)) {
1145
+ const serverConvo = raw.SessionConversation.map((m) => {
1146
+ var _a, _b;
1147
+ const mCards = Array.isArray(m === null || m === void 0 ? void 0 : m.AvailableTasksCards)
1148
+ ? m.AvailableTasksCards
1149
+ : Array.isArray(m === null || m === void 0 ? void 0 : m.Cards)
1150
+ ? m.Cards
1151
+ : Array.isArray(m === null || m === void 0 ? void 0 : m.AvailableTasks)
1152
+ ? m.AvailableTasks
1153
+ : [];
1154
+ return Object.assign({ role: m.role, content: (_a = m.content) !== null && _a !== void 0 ? _a : "", ts: (_b = m.ts) !== null && _b !== void 0 ? _b : Date.now() }, (mCards.length ? { availableTasksCards: mCards } : {}));
1155
+ });
1156
+ if (cards.length && serverConvo.length) {
1157
+ for (let i = serverConvo.length - 1; i >= 0; i--) {
1158
+ if (serverConvo[i].role === "Assistant") {
1159
+ serverConvo[i] = Object.assign(Object.assign({}, serverConvo[i]), { availableTasksCards: cards });
1160
+ break;
1161
+ }
1162
+ }
1163
+ }
1164
+ setMessages(serverConvo);
1165
+ }
1166
+ else {
1167
+ const assistantMsg = Object.assign({ role: "Assistant", content: assistantText !== null && assistantText !== void 0 ? assistantText : "", ts: Date.now() }, (cards.length ? { availableTasksCards: cards } : {}));
1168
+ setMessages((prev) => [...(prev || []), assistantMsg]);
1169
+ }
1170
+ }
1171
+ catch (err) {
1172
+ setMessages((prev) => {
1173
+ var _a;
1174
+ return [
1175
+ ...prev,
1176
+ {
1177
+ role: "Assistant",
1178
+ content: formatText(text.errors.assistantMessageTemplate, {
1179
+ error: (_a = err === null || err === void 0 ? void 0 : err.message) !== null && _a !== void 0 ? _a : String(err),
1180
+ }),
1181
+ ts: Date.now(),
1182
+ },
1183
+ ];
1184
+ });
1185
+ }
1186
+ finally {
1187
+ setPending(false);
1188
+ }
1189
+ });
1190
+ }
1191
+ function handleUpload(files) {
1192
+ if (!files || files.length === 0)
1193
+ return;
1194
+ setSelectedFiles((prev) => [...prev, ...Array.from(files)]);
1195
+ }
1196
+ function clearSelected(i) {
1197
+ if (typeof i === "number") {
1198
+ setSelectedFiles((xs) => xs.filter((_, idx) => idx !== i));
1199
+ }
1200
+ else {
1201
+ setSelectedFiles([]);
1202
+ }
1203
+ if (fileInputRef.current)
1204
+ fileInputRef.current.value = "";
1205
+ }
1206
+ function submitTakeAction() {
1207
+ return __awaiter(this, void 0, void 0, function* () {
1208
+ var _a;
1209
+ if (!activeTaskCard)
1210
+ return;
1211
+ if (!authToken) {
1212
+ setTakeActionError(text.errors.takeActionAuthRequired);
1213
+ return;
1214
+ }
1215
+ const requestStepIdRaw = activeTaskCard.RequestStepId !== undefined &&
1216
+ activeTaskCard.RequestStepId !== null
1217
+ ? activeTaskCard.RequestStepId
1218
+ : activeTaskCard.RequestId;
1219
+ const requestStepId = Number(requestStepIdRaw);
1220
+ if (Number.isNaN(requestStepId)) {
1221
+ setTakeActionError(text.errors.takeActionMissingRequestStep);
1222
+ return;
1223
+ }
1224
+ setTakeActionSubmitting(true);
1225
+ setTakeActionError(null);
1226
+ try {
1227
+ yield (0, api_1.postJson)(`${requestStepBaseUrl}/api/DarAlBerProvider/CheckoutRequestStepList`, { RequestStepID: [requestStepId] }, requestHeaders);
1228
+ const meta = activeTaskCard.MetaData || {};
1229
+ const isSignDocument = !!meta.IsSignDocument;
1230
+ let documentId = null;
1231
+ let updatedAttributes = [...takeActionAttributes];
1232
+ let documentUrl = "";
1233
+ if (meta.DocumentTemplate) {
1234
+ const attrsForGeneration = updatedAttributes
1235
+ .map((attr) => {
1236
+ if ((0, taskAttributes_1.isDocumentAttribute)(attr, meta.DocumentAttributeName)) {
1237
+ return Object.assign(Object.assign({}, attr), { Value: "" });
1238
+ }
1239
+ return attr;
1240
+ })
1241
+ .filter((attr) => !(0, taskAttributes_1.isDocumentAttribute)(attr, meta.DocumentAttributeName));
1242
+ const genPayload = {
1243
+ RequestStepId: requestStepId,
1244
+ templateAttributeAlias: meta.DocumentTemplate,
1245
+ ClientRequestAttributes: (0, taskAttributes_1.buildAttributePayload)(attrsForGeneration),
1246
+ IsGeneratedWord: isSignDocument,
1247
+ };
1248
+ const genRes = yield (0, api_1.postJson)(`${transactionCatalogBaseUrl}/api/TransactionCommon/GenerateStepDocument`, genPayload, requestHeaders);
1249
+ documentId = (_a = genRes === null || genRes === void 0 ? void 0 : genRes.Result) !== null && _a !== void 0 ? _a : null;
1250
+ if (documentId !== null && documentId !== undefined) {
1251
+ updatedAttributes = (0, taskAttributes_1.applyDocumentIdToAttributes)(updatedAttributes, meta.DocumentAttributeName || null, documentId);
1252
+ }
1253
+ }
1254
+ if (documentId !== null && documentId !== undefined) {
1255
+ const signatureIdRaw = (0, taskAttributes_1.getAttributeValueByAlias)(takeActionAttributes, signatureAlias);
1256
+ const signatureId = Number(signatureIdRaw);
1257
+ if (isSignDocument) {
1258
+ if (Number.isNaN(signatureId)) {
1259
+ throw new Error(text.errors.takeActionMissingSignature);
1260
+ }
1261
+ yield (0, api_1.postJson)(`${signatureBaseUrl}/api/SignDocument`, {
1262
+ documentPath: String(documentId),
1263
+ alias: signatureAlias || "",
1264
+ interactorSignatureId: signatureId,
1265
+ }, requestHeaders);
1266
+ }
1267
+ documentUrl = yield (0, api_1.getDocumentUrl)(storageBaseUrl, documentId, requestHeaders);
1268
+ }
1269
+ if (!documentUrl) {
1270
+ throw new Error(text.errors.takeActionNoDocument);
1271
+ }
1272
+ setTakeActionProceedData({
1273
+ requestStepId,
1274
+ status: takeActionChoice === "Approve" ? 1 : 0,
1275
+ attributes: updatedAttributes,
1276
+ comment: takeActionComments || "",
1277
+ });
1278
+ setTakeActionProceedOpen(true);
1279
+ yield openOverlay(documentUrl);
1280
+ closeTakeActionModal(true);
1281
+ }
1282
+ catch (err) {
1283
+ setTakeActionError((err === null || err === void 0 ? void 0 : err.message) || String(err));
1284
+ }
1285
+ finally {
1286
+ setTakeActionSubmitting(false);
1287
+ }
1288
+ });
1289
+ }
1290
+ function proceedTakeAction() {
1291
+ return __awaiter(this, void 0, void 0, function* () {
1292
+ if (!takeActionProceedData)
1293
+ return;
1294
+ setTakeActionSubmitting(true);
1295
+ try {
1296
+ const processPayload = {
1297
+ RequestStepIdList: [takeActionProceedData.requestStepId],
1298
+ Status: takeActionProceedData.status,
1299
+ RequestStepAttributeDtos: (0, taskAttributes_1.buildAttributePayload)(takeActionProceedData.attributes),
1300
+ ProviderComment: takeActionProceedData.comment || null,
1301
+ };
1302
+ yield (0, api_1.postJson)(`${requestStepBaseUrl}/api/DarAlBerProvider/ProcessCheckedOutRequestStepList`, processPayload, requestHeaders);
1303
+ removeTaskCardFromMessages(takeActionProceedData.requestStepId);
1304
+ setTakeActionProceedOpen(false);
1305
+ setTakeActionProceedData(null);
1306
+ closeOverlay();
1307
+ }
1308
+ catch (err) {
1309
+ setTakeActionError((err === null || err === void 0 ? void 0 : err.message) || String(err));
1310
+ }
1311
+ finally {
1312
+ setTakeActionSubmitting(false);
1313
+ }
1314
+ });
1315
+ }
1316
+ function clearChat() {
1317
+ return __awaiter(this, void 0, void 0, function* () {
1318
+ if (!sessionId)
1319
+ return;
1320
+ const ok = window.confirm(text.alerts.clearConfirm);
1321
+ if (!ok)
1322
+ return;
1323
+ const sessionDomain = domain.trim();
1324
+ try {
1325
+ const res = yield fetch(new URL(`/api/clearChat`, apiBase).toString(), {
1326
+ method: "POST",
1327
+ headers: Object.assign({ "Content-Type": "application/json", "api-key": apiKey }, (authToken ? { Authorization: authToken } : {})),
1328
+ body: JSON.stringify({ Domain: sessionDomain, SessionId: sessionId }),
1329
+ });
1330
+ if (!res.ok)
1331
+ throw new Error(`${res.status} ${res.statusText}`);
1332
+ let raw = {};
1333
+ try {
1334
+ raw = yield res.json();
1335
+ }
1336
+ catch (_a) { }
1337
+ const returnedConvoRaw = Array.isArray(raw === null || raw === void 0 ? void 0 : raw.SessionConversation)
1338
+ ? raw.SessionConversation
1339
+ : [];
1340
+ const returnedConvo = returnedConvoRaw.map((m) => {
1341
+ var _a, _b;
1342
+ return ({
1343
+ role: m.role,
1344
+ content: (_a = m.content) !== null && _a !== void 0 ? _a : "",
1345
+ ts: (_b = m.ts) !== null && _b !== void 0 ? _b : Date.now(),
1346
+ });
1347
+ });
1348
+ const topCards = Array.isArray(raw === null || raw === void 0 ? void 0 : raw.SelectedTasksCards)
1349
+ ? raw.SelectedTasksCards
1350
+ : Array.isArray(raw === null || raw === void 0 ? void 0 : raw.SelectedTaskCards)
1351
+ ? raw.SelectedTaskCards
1352
+ : [];
1353
+ if (topCards.length && returnedConvo.length) {
1354
+ for (let i = returnedConvo.length - 1; i >= 0; i--) {
1355
+ if (returnedConvo[i].role === "Assistant") {
1356
+ returnedConvo[i] = Object.assign(Object.assign({}, returnedConvo[i]), { availableTasksCards: topCards });
1357
+ break;
1358
+ }
1359
+ }
1360
+ }
1361
+ setMessages(returnedConvo);
1362
+ }
1363
+ catch (err) {
1364
+ setMessages((prev) => {
1365
+ var _a;
1366
+ return [
1367
+ ...(prev || []),
1368
+ {
1369
+ role: "Assistant",
1370
+ content: formatText(text.alerts.clearFailedTemplate, {
1371
+ error: (_a = err === null || err === void 0 ? void 0 : err.message) !== null && _a !== void 0 ? _a : String(err),
1372
+ }),
1373
+ ts: Date.now(),
1374
+ },
1375
+ ];
1376
+ });
1377
+ }
1378
+ });
1379
+ }
1380
+ function onKeyDown(e) {
1381
+ var _a;
1382
+ if (e.key === "Enter" && !e.shiftKey) {
1383
+ e.preventDefault();
1384
+ sendMessage();
1385
+ }
1386
+ if (e.key === "/" && (e.ctrlKey || e.metaKey)) {
1387
+ e.preventDefault();
1388
+ (_a = composerRef.current) === null || _a === void 0 ? void 0 : _a.focus();
1389
+ }
1390
+ }
1391
+ function detectKeyboardDirection() {
1392
+ return __awaiter(this, void 0, void 0, function* () {
1393
+ if (typeof navigator === "undefined")
1394
+ return;
1395
+ const keyboard = navigator.keyboard;
1396
+ if (!(keyboard === null || keyboard === void 0 ? void 0 : keyboard.getLayoutMap))
1397
+ return;
1398
+ try {
1399
+ const map = yield keyboard.getLayoutMap();
1400
+ for (const value of map.values()) {
1401
+ if (typeof value === "string" && (0, textDirection_1.getTextDirection)(value) === "rtl") {
1402
+ setKeyboardDirection("rtl");
1403
+ return;
1404
+ }
1405
+ }
1406
+ setKeyboardDirection("ltr");
1407
+ }
1408
+ catch (_a) { }
1409
+ });
1410
+ }
1411
+ // doc viewer helpers
1412
+ function guessExtensionFromType(type) {
1413
+ if (!type)
1414
+ return "";
1415
+ const t = type.toLowerCase();
1416
+ if (t.includes("pdf"))
1417
+ return ".pdf";
1418
+ if (t.includes("json"))
1419
+ return ".json";
1420
+ if (t.includes("xml"))
1421
+ return ".xml";
1422
+ if (t.includes("csv"))
1423
+ return ".csv";
1424
+ if (t.includes("png"))
1425
+ return ".png";
1426
+ if (t.includes("jpeg") || t.includes("jpg"))
1427
+ return ".jpg";
1428
+ if (t.includes("webp"))
1429
+ return ".webp";
1430
+ if (t.includes("plain"))
1431
+ return ".txt";
1432
+ return "";
1433
+ }
1434
+ function deriveFilenameFromUrl(url) {
1435
+ try {
1436
+ const u = new URL(url);
1437
+ const path = u.pathname.split("/").filter(Boolean);
1438
+ const last = path[path.length - 1] || text.documentViewer.iframeTitle;
1439
+ return decodeURIComponent(last);
1440
+ }
1441
+ catch (_a) {
1442
+ const m = url.split("?")[0].split("/").filter(Boolean);
1443
+ return decodeURIComponent(m[m.length - 1] || text.documentViewer.iframeTitle);
1444
+ }
1445
+ }
1446
+ function parseContentDispositionFilename(cd) {
1447
+ if (!cd)
1448
+ return null;
1449
+ const star = /filename\*\s*=\s*([^']*)'[^']*'([^;]+)/i.exec(cd);
1450
+ if (star && star[2]) {
1451
+ return decodeURIComponent(star[2].trim().replace(/^"(.*)"$/, "$1"));
1452
+ }
1453
+ const reg = /filename\s*=\s*("?)([^";]+)\1/i.exec(cd);
1454
+ if (reg && reg[2])
1455
+ return reg[2].trim();
1456
+ return null;
1457
+ }
1458
+ function buildGoogleViewerUrl(rawHref) {
1459
+ let normalized = rawHref.trim();
1460
+ try {
1461
+ if (/%[0-9a-f]{2}/i.test(normalized)) {
1462
+ normalized = decodeURIComponent(normalized);
1463
+ }
1464
+ }
1465
+ catch (_a) { }
1466
+ const nonce = Date.now();
1467
+ return `https://docs.google.com/viewer?url=${encodeURIComponent(normalized)}&embedded=true&r=${nonce}`;
1468
+ }
1469
+ const openOverlay = (href) => __awaiter(this, void 0, void 0, function* () {
1470
+ if (blobUrl) {
1471
+ URL.revokeObjectURL(blobUrl);
1472
+ setBlobUrl(null);
1473
+ }
1474
+ setOverlayUrl(href);
1475
+ setViewerError(null);
1476
+ setViewerBlob(null);
1477
+ setViewerLoading(true);
1478
+ setViewerFilename(text.documentViewer.iframeTitle);
1479
+ const gv = buildGoogleViewerUrl(href);
1480
+ setGdocUrl(gv);
1481
+ setViewerUrl(gv);
1482
+ setViewerKey((k) => k + 1);
1483
+ try {
1484
+ const resp = yield fetch(href, { mode: "cors" });
1485
+ const ok = resp.ok;
1486
+ const type = resp.headers.get("content-type") || "";
1487
+ const cd = resp.headers.get("content-disposition");
1488
+ const cdName = parseContentDispositionFilename(cd);
1489
+ let blob = null;
1490
+ if (ok) {
1491
+ try {
1492
+ blob = yield resp.blob();
1493
+ }
1494
+ catch (_a) { }
1495
+ }
1496
+ let name = cdName || deriveFilenameFromUrl(href) || text.documentViewer.iframeTitle;
1497
+ if (!/\.[a-z0-9]{2,6}$/i.test(name)) {
1498
+ const ext = guessExtensionFromType(type);
1499
+ if (ext)
1500
+ name += ext;
1501
+ }
1502
+ setViewerFilename(name);
1503
+ const cdIsAttachment = (cd || "").toLowerCase().includes("attachment");
1504
+ const looksPdf = type.toLowerCase().includes("pdf");
1505
+ if (blob && (looksPdf || cdIsAttachment)) {
1506
+ const u = URL.createObjectURL(blob);
1507
+ setViewerBlob(blob);
1508
+ setBlobUrl(u);
1509
+ if (typeof window !== "undefined") {
1510
+ gdocFallbackTimer.current = window.setTimeout(() => {
1511
+ setViewerUrl((cur) => (cur === gv && u ? u : cur));
1512
+ }, 2200);
1513
+ }
1514
+ }
1515
+ }
1516
+ catch (_b) { }
1517
+ });
1518
+ const closeOverlay = () => {
1519
+ if (gdocFallbackTimer.current) {
1520
+ clearTimeout(gdocFallbackTimer.current);
1521
+ gdocFallbackTimer.current = undefined;
1522
+ }
1523
+ setOverlayUrl(null);
1524
+ setViewerUrl(null);
1525
+ setGdocUrl(null);
1526
+ setViewerError(null);
1527
+ setViewerLoading(false);
1528
+ setViewerBlob(null);
1529
+ if (blobUrl)
1530
+ URL.revokeObjectURL(blobUrl);
1531
+ setBlobUrl(null);
1532
+ setViewerFilename(text.documentViewer.iframeTitle);
1533
+ setViewerKey((k) => k + 1);
1534
+ if (takeActionProceedOpen) {
1535
+ setTakeActionProceedOpen(false);
1536
+ setTakeActionProceedData(null);
1537
+ }
1538
+ };
1539
+ const downloadCurrent = () => {
1540
+ try {
1541
+ if (viewerBlob) {
1542
+ const dlUrl = URL.createObjectURL(viewerBlob);
1543
+ const a = document.createElement("a");
1544
+ a.href = dlUrl;
1545
+ a.download = viewerFilename || text.documentViewer.iframeTitle;
1546
+ document.body.appendChild(a);
1547
+ a.click();
1548
+ a.remove();
1549
+ URL.revokeObjectURL(dlUrl);
1550
+ }
1551
+ else if (overlayUrl) {
1552
+ const a = document.createElement("a");
1553
+ a.href = overlayUrl;
1554
+ a.target = "_blank";
1555
+ a.rel = "noopener";
1556
+ a.download = viewerFilename || text.documentViewer.iframeTitle;
1557
+ document.body.appendChild(a);
1558
+ a.click();
1559
+ a.remove();
1560
+ }
1561
+ }
1562
+ catch (e) {
1563
+ console.warn("Download failed:", e);
1564
+ }
1565
+ };
1566
+ // Initialize session (login), initializeChatClients, and optionally initializeChat
1567
+ function initializeChatWithParams(tokenOverride) {
1568
+ return __awaiter(this, void 0, void 0, function* () {
1569
+ var _a, _b;
1570
+ try {
1571
+ const result = yield (0, sdkUtilities_1.InitializeChatSession)({
1572
+ initServiceId: initServiceId || undefined,
1573
+ initRequestStepId: initRequestStepId || undefined,
1574
+ contextWindow: initContextWindow || contextWindow,
1575
+ domain,
1576
+ token: tokenOverride !== null && tokenOverride !== void 0 ? tokenOverride : authToken,
1577
+ });
1578
+ if (result.initialized) {
1579
+ if (result.sessionId && result.sessionId !== sessionId) {
1580
+ setSessionId(result.sessionId);
1581
+ }
1582
+ setInitCompleted(true);
1583
+ localStorage_1.ls.set((0, storageKeys_1.getInitCompletedKey)(result.sessionId), true);
1584
+ }
1585
+ }
1586
+ catch (err) {
1587
+ 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"))
1588
+ ? text.alerts.initChatNetworkError
1589
+ : (err === null || err === void 0 ? void 0 : err.message) || String(err);
1590
+ alert(formatText(text.alerts.initChatErrorTemplate, { error: msg }));
1591
+ }
1592
+ });
1593
+ }
1594
+ function initializeChatClients(authHeader) {
1595
+ return __awaiter(this, void 0, void 0, function* () {
1596
+ try {
1597
+ const apiBase = chatDefaults_1.DEFAULT_API_BASE;
1598
+ const initClientsRes = yield fetch(new URL("/api/initializeChatClients", apiBase).toString(), {
1599
+ method: "POST",
1600
+ headers: {
1601
+ "Content-Type": "application/json",
1602
+ "api-key": apiKey,
1603
+ Authorization: authHeader,
1604
+ },
1605
+ body: JSON.stringify({ Domain: domain.trim() }),
1606
+ });
1607
+ if (!initClientsRes.ok) {
1608
+ let msg = "";
1609
+ try {
1610
+ msg = yield initClientsRes.text();
1611
+ }
1612
+ catch (_a) { }
1613
+ console.warn(`initializeChatClients: ${initClientsRes.status} ${initClientsRes.statusText} ${msg}`);
1614
+ }
1615
+ }
1616
+ catch (err) {
1617
+ console.warn("initializeChatClients network error:", err);
1618
+ }
1619
+ });
1620
+ }
1621
+ function initializeSession(options) {
1622
+ return __awaiter(this, void 0, void 0, function* () {
1623
+ var _a, _b;
1624
+ if (initLoading)
1625
+ return;
1626
+ const requestDomain = domain.trim();
1627
+ const authFromState = authToken === null || authToken === void 0 ? void 0 : authToken.trim();
1628
+ const hasCredentials = !!initUsername.trim() && !!initPassword;
1629
+ const shouldUseLogin = hasCredentials && !authFromState;
1630
+ if (!serviceBaseUrl) {
1631
+ alert(text.alerts.initMissingBaseUrl);
1632
+ return;
1633
+ }
1634
+ if (!apiSubscriptionKey) {
1635
+ alert(text.alerts.initMissingSubscriptionKey);
1636
+ return;
1637
+ }
1638
+ const resolvedLoginSubscriptionKey = loginSubscriptionKey || apiSubscriptionKey;
1639
+ if (!hasCredentials && !authFromState) {
1640
+ alert(text.alerts.initMissingCredentials);
1641
+ return;
1642
+ }
1643
+ if (shouldUseLogin) {
1644
+ const username = initUsername.trim();
1645
+ const password = initPassword;
1646
+ if (!username || !password) {
1647
+ alert(text.alerts.initMissingCredentials);
1648
+ return;
1649
+ }
1650
+ if (!initEndpoint) {
1651
+ alert(text.alerts.initMissingEndpoint);
1652
+ return;
1653
+ }
1654
+ }
1655
+ setInitLoading(true);
1656
+ try {
1657
+ let authHeader = authFromState;
1658
+ if (shouldUseLogin) {
1659
+ const res = yield fetch(initEndpoint, {
1660
+ method: "POST",
1661
+ headers: {
1662
+ "Content-Type": "application/json",
1663
+ "ocp-apim-subscription-key": resolvedLoginSubscriptionKey,
1664
+ },
1665
+ body: JSON.stringify({
1666
+ domainName: requestDomain,
1667
+ clientType: initClientType,
1668
+ username: initUsername.trim(),
1669
+ password: initPassword,
1670
+ }),
1671
+ });
1672
+ let payload = {};
1673
+ try {
1674
+ payload = yield res.json();
1675
+ }
1676
+ catch (_c) { }
1677
+ if (!res.ok) {
1678
+ alert(text.alerts.initFailed);
1679
+ return;
1680
+ }
1681
+ const access = (_a = payload === null || payload === void 0 ? void 0 : payload.Result) === null || _a === void 0 ? void 0 : _a.Token;
1682
+ if (!access) {
1683
+ alert(text.alerts.initNoToken);
1684
+ return;
1685
+ }
1686
+ authHeader = `Bearer ${access}`.trim();
1687
+ setAuthToken(normalizeAuthToken(authHeader));
1688
+ localStorage_1.ls.set(storageKeys_1.STORAGE_KEYS.authToken, authHeader);
1689
+ localStorage_1.ls.set(storageKeys_1.STORAGE_KEYS.initUsername, initUsername.trim());
1690
+ }
1691
+ setContextWindow(initContextWindow || "ComposeRequest");
1692
+ if (options === null || options === void 0 ? void 0 : options.runInitializeChatClients) {
1693
+ yield initializeChatClients(authHeader);
1694
+ }
1695
+ if (options === null || options === void 0 ? void 0 : options.runInitializeChat) {
1696
+ yield initializeChatWithParams(authHeader);
1697
+ }
1698
+ setShowInitPanel(false);
1699
+ setInitPassword("");
1700
+ }
1701
+ catch (err) {
1702
+ const msg = ((_b = err === null || err === void 0 ? void 0 : err.message) === null || _b === void 0 ? void 0 : _b.includes("Failed to fetch"))
1703
+ ? text.alerts.initNetworkError
1704
+ : (err === null || err === void 0 ? void 0 : err.message) || String(err);
1705
+ alert(formatText(text.alerts.initErrorTemplate, { error: msg }));
1706
+ }
1707
+ finally {
1708
+ setInitLoading(false);
1709
+ }
1710
+ });
1711
+ }
1712
+ function doLogout() {
1713
+ return __awaiter(this, void 0, void 0, function* () {
1714
+ // Server-side cleanup (only on logout)
1715
+ const prevSessionId = sessionId;
1716
+ try {
1717
+ yield (0, sdkUtilities_1.FinalizeSession)({
1718
+ domain,
1719
+ token: authToken,
1720
+ });
1721
+ }
1722
+ catch (_a) { }
1723
+ // Local reset
1724
+ setMessages([]);
1725
+ setAuthToken("");
1726
+ setInitPassword("");
1727
+ setInitUsername("");
1728
+ setInitPreset("custom");
1729
+ if (prevSessionId) {
1730
+ localStorage_1.ls.remove((0, storageKeys_1.getMessagesKey)(prevSessionId));
1731
+ localStorage_1.ls.remove((0, storageKeys_1.getInitCompletedKey)(prevSessionId));
1732
+ }
1733
+ const newSessionId = (0, generateGuid_1.generateGuid)();
1734
+ setSessionId(newSessionId);
1735
+ localStorage_1.ls.set(storageKeys_1.STORAGE_KEYS.sessionId, newSessionId);
1736
+ setInitCompleted(false);
1737
+ localStorage_1.ls.set((0, storageKeys_1.getInitCompletedKey)(newSessionId), false);
1738
+ });
1739
+ }
1740
+ return ((0, jsx_runtime_1.jsxs)("div", { className: "chatui-root flex h-screen 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: () => {
1741
+ if (initPanelEnabled) {
1742
+ setShowInitPanel(true);
1743
+ }
1744
+ }, textButtonTheme: textButtonTheme, showInitButton: initPanelEnabled, text: text.topBar }), initPanelEnabled && ((0, jsx_runtime_1.jsx)(InitPanel_1.default, { show: showInitPanel, onClose: () => setShowInitPanel(false), requiredConfig: {
1745
+ baseUrl: serviceBaseUrl,
1746
+ apiSubscriptionKey,
1747
+ loginSubscriptionKey,
1748
+ token: authToken,
1749
+ isDab,
1750
+ setBaseUrl: (value) => setServiceBaseUrl(normalizeServiceBaseUrl(value)),
1751
+ setApiSubscriptionKey,
1752
+ setLoginSubscriptionKey,
1753
+ setToken: (value) => setAuthToken(normalizeAuthToken(value)),
1754
+ setIsDab,
1755
+ }, initPreset: initPreset, setInitPreset: applyInitPreset, initUsername: initUsername, setInitUsername: setInitUsername, initPassword: initPassword, setInitPassword: setInitPassword, domain: domain, setDomain: setDomain, initContextWindow: initContextWindow, setInitContextWindow: setInitContextWindow, initServiceId: initServiceId, setInitServiceId: setInitServiceId, initRequestStepId: initRequestStepId, setInitRequestStepId: setInitRequestStepId, sessionId: sessionId, setSessionId: setSessionId, speechLang: speechLang, setSpeechLang: setSpeechLang, ttsLang: ttsLang, setTtsLang: setTtsLang, initLoading: initLoading, onInitialize: () => __awaiter(this, void 0, void 0, function* () {
1756
+ setContextWindow(initContextWindow || contextWindow);
1757
+ yield initializeSession({
1758
+ runInitializeChatClients: true,
1759
+ runInitializeChat: true,
1760
+ });
1761
+ }), textButtonTheme: textButtonTheme })), (0, jsx_runtime_1.jsx)(ToolResultOverlay_1.default, { show: showToolOverlay, onClose: () => setShowToolOverlay(false), lastToolResult: lastToolResult, text: text.toolResult }), (0, jsx_runtime_1.jsx)(TaskCardsModal_1.default, { open: taskCardModalOpen, card: activeTaskCard, onClose: closeTaskCardModal, onTakeAction: (card) => {
1762
+ closeTaskCardModal();
1763
+ openTakeActionModal(card);
1764
+ }, onShowDocument: (url) => {
1765
+ closeTaskCardModal();
1766
+ openOverlay(url);
1767
+ }, textButtonTheme: textButtonTheme, text: text.taskCards }), (0, jsx_runtime_1.jsx)(TakeActionModal_1.default, { open: takeActionOpen, activeTaskCard: activeTaskCard, takeActionStep: takeActionStep, takeActionChoice: takeActionChoice, takeActionComments: takeActionComments, takeActionSubmitting: takeActionSubmitting, takeActionError: takeActionError, visibleAttributes: visibleTakeActionAttributes, signatureAlias: signatureAlias, userSignatures: userSignatures, onBack: handleTakeActionBack, onClose: () => closeTakeActionModal(), onChoiceChange: setTakeActionChoice, onCommentsChange: setTakeActionComments, onStepChange: setTakeActionStep, onSubmit: submitTakeAction, onUpdateAttribute: updateTakeActionAttributeValue, getSignatureLabel: taskAttributes_1.getSignatureLabel, textButtonTheme: textButtonTheme, text: text.takeAction }), (0, jsx_runtime_1.jsx)(DocumentViewer_1.default, { overlayUrl: overlayUrl, viewerLoading: viewerLoading, viewerUrl: viewerUrl, viewerKey: viewerKey, viewerFilename: viewerFilename, gdocUrl: gdocUrl, blobUrl: blobUrl, viewerError: viewerError, onClose: closeOverlay, onDownload: downloadCurrent, onIframeLoad: () => setViewerLoading(false), onUseGoogleViewer: () => {
1768
+ setViewerLoading(true);
1769
+ setViewerUrl(gdocUrl);
1770
+ setViewerKey((k) => k + 1);
1771
+ }, onUseDirectViewer: () => {
1772
+ setViewerLoading(true);
1773
+ setViewerUrl(blobUrl);
1774
+ setViewerKey((k) => k + 1);
1775
+ }, 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) => {
1776
+ setInput(value);
1777
+ if (composerRef.current) {
1778
+ autosizeTextarea(composerRef.current);
1779
+ }
1780
+ }, 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 })] }));
1781
+ }