@burtson-labs/bandit-engine 2.0.158 → 2.0.160
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 +17 -0
- package/dist/{aiProviderStore-ZQ5VVVKQ.mjs → aiProviderStore-BNZGM6QU.mjs} +2 -2
- package/dist/chat-4BOIV4VP.mjs +16 -0
- package/dist/chat-provider.js +3 -3
- package/dist/chat-provider.js.map +1 -1
- package/dist/chat-provider.mjs +6 -6
- package/dist/{chunk-GWQRTUKF.mjs → chunk-B3HAQC6F.mjs} +2 -2
- package/dist/chunk-B3HAQC6F.mjs.map +1 -0
- package/dist/{chunk-7HC6ONWM.mjs → chunk-IABD4L6K.mjs} +43 -44
- package/dist/chunk-IABD4L6K.mjs.map +1 -0
- package/dist/{chunk-R45DM35B.mjs → chunk-LFQH6M6B.mjs} +3 -3
- package/dist/chunk-LFQH6M6B.mjs.map +1 -0
- package/dist/{chunk-IS2LWSBZ.mjs → chunk-LNGF2XAZ.mjs} +3 -3
- package/dist/chunk-LNGF2XAZ.mjs.map +1 -0
- package/dist/{chunk-GZDJNVAS.mjs → chunk-LTWMMHFT.mjs} +11 -9
- package/dist/chunk-LTWMMHFT.mjs.map +1 -0
- package/dist/{chunk-F5JS4W2K.mjs → chunk-MHF76C2F.mjs} +246 -127
- package/dist/chunk-MHF76C2F.mjs.map +1 -0
- package/dist/{chunk-B2TJZM4Z.mjs → chunk-P6SLB5RC.mjs} +3 -3
- package/dist/{chunk-ZW3YNAD7.mjs → chunk-PDQT564P.mjs} +5 -5
- package/dist/{chunk-ZW3YNAD7.mjs.map → chunk-PDQT564P.mjs.map} +1 -1
- package/dist/{chunk-VJVGSAKI.mjs → chunk-PXCIDXRP.mjs} +7 -7
- package/dist/{chunk-VJVGSAKI.mjs.map → chunk-PXCIDXRP.mjs.map} +1 -1
- package/dist/{chunk-2X3ZTDUW.mjs → chunk-TKSOJGHX.mjs} +5 -5
- package/dist/{chunk-ZOCXFQID.mjs → chunk-XTB6ZLUI.mjs} +2 -2
- package/dist/{chunk-ZOCXFQID.mjs.map → chunk-XTB6ZLUI.mjs.map} +1 -1
- package/dist/index.js +299 -164
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +11 -11
- package/dist/management/management.js +292 -157
- package/dist/management/management.js.map +1 -1
- package/dist/management/management.mjs +9 -9
- package/dist/modals/chat-modal/chat-modal.js +9 -7
- package/dist/modals/chat-modal/chat-modal.js.map +1 -1
- package/dist/modals/chat-modal/chat-modal.mjs +5 -5
- package/dist/{modelStore-KBUW3XAV.mjs → modelStore-NMCRL3FR.mjs} +2 -2
- package/package.json +6 -4
- package/dist/chat-HM563VOV.mjs +0 -16
- package/dist/chunk-7HC6ONWM.mjs.map +0 -1
- package/dist/chunk-F5JS4W2K.mjs.map +0 -1
- package/dist/chunk-GWQRTUKF.mjs.map +0 -1
- package/dist/chunk-GZDJNVAS.mjs.map +0 -1
- package/dist/chunk-IS2LWSBZ.mjs.map +0 -1
- package/dist/chunk-R45DM35B.mjs.map +0 -1
- /package/dist/{aiProviderStore-ZQ5VVVKQ.mjs.map → aiProviderStore-BNZGM6QU.mjs.map} +0 -0
- /package/dist/{chat-HM563VOV.mjs.map → chat-4BOIV4VP.mjs.map} +0 -0
- /package/dist/{chunk-B2TJZM4Z.mjs.map → chunk-P6SLB5RC.mjs.map} +0 -0
- /package/dist/{chunk-2X3ZTDUW.mjs.map → chunk-TKSOJGHX.mjs.map} +0 -0
- /package/dist/{modelStore-KBUW3XAV.mjs.map → modelStore-NMCRL3FR.mjs.map} +0 -0
package/dist/index.js
CHANGED
|
@@ -232,7 +232,7 @@ function emitAuthTokenChanged(token) {
|
|
|
232
232
|
detail: { token }
|
|
233
233
|
}));
|
|
234
234
|
}
|
|
235
|
-
var TOKEN_KEY2, AUTH_TOKEN_CHANGED_EVENT, AuthenticationService,
|
|
235
|
+
var TOKEN_KEY2, AUTH_TOKEN_CHANGED_EVENT, AuthenticationService, authenticationService;
|
|
236
236
|
var init_authenticationService = __esm({
|
|
237
237
|
"src/services/auth/authenticationService.ts"() {
|
|
238
238
|
"use strict";
|
|
@@ -285,7 +285,7 @@ var init_authenticationService = __esm({
|
|
|
285
285
|
}
|
|
286
286
|
}
|
|
287
287
|
};
|
|
288
|
-
|
|
288
|
+
authenticationService = new AuthenticationService();
|
|
289
289
|
}
|
|
290
290
|
});
|
|
291
291
|
|
|
@@ -2149,7 +2149,7 @@ function buildUrl(path) {
|
|
|
2149
2149
|
}
|
|
2150
2150
|
function buildHeaders() {
|
|
2151
2151
|
const headers = { "Content-Type": "application/json" };
|
|
2152
|
-
const token =
|
|
2152
|
+
const token = authenticationService.getToken();
|
|
2153
2153
|
if (token) {
|
|
2154
2154
|
headers["Authorization"] = `Bearer ${token}`;
|
|
2155
2155
|
}
|
|
@@ -2297,7 +2297,7 @@ function resolveAuthIdentity(token) {
|
|
|
2297
2297
|
if (!token) {
|
|
2298
2298
|
return null;
|
|
2299
2299
|
}
|
|
2300
|
-
const claims =
|
|
2300
|
+
const claims = authenticationService.parseJwtClaims(token);
|
|
2301
2301
|
if (claims?.sub) {
|
|
2302
2302
|
return claims.sub;
|
|
2303
2303
|
}
|
|
@@ -2830,7 +2830,7 @@ var init_conversationSyncStore = __esm({
|
|
|
2830
2830
|
async initialize() {
|
|
2831
2831
|
ensureTrackersInitialized();
|
|
2832
2832
|
const gatewayUrl = usePackageSettingsStore.getState().settings?.gatewayApiUrl;
|
|
2833
|
-
const token =
|
|
2833
|
+
const token = authenticationService.getToken();
|
|
2834
2834
|
const tokenIdentity = resolveAuthIdentity(token);
|
|
2835
2835
|
const current = get();
|
|
2836
2836
|
const storedIdentity = getStoredSyncIdentity();
|
|
@@ -2956,10 +2956,10 @@ var init_conversationSyncStore = __esm({
|
|
|
2956
2956
|
});
|
|
2957
2957
|
set({
|
|
2958
2958
|
hasLoadedPreference: true,
|
|
2959
|
-
initializedForToken:
|
|
2960
|
-
initializedForIdentity: resolveAuthIdentity(
|
|
2959
|
+
initializedForToken: authenticationService.getToken(),
|
|
2960
|
+
initializedForIdentity: resolveAuthIdentity(authenticationService.getToken())
|
|
2961
2961
|
});
|
|
2962
|
-
setStoredSyncIdentity(resolveAuthIdentity(
|
|
2962
|
+
setStoredSyncIdentity(resolveAuthIdentity(authenticationService.getToken()));
|
|
2963
2963
|
if (enabled) {
|
|
2964
2964
|
set({ hasCompletedInitialUpload: false });
|
|
2965
2965
|
}
|
|
@@ -2999,10 +2999,10 @@ var init_conversationSyncStore = __esm({
|
|
|
2999
2999
|
});
|
|
3000
3000
|
set({
|
|
3001
3001
|
hasLoadedPreference: true,
|
|
3002
|
-
initializedForToken:
|
|
3003
|
-
initializedForIdentity: resolveAuthIdentity(
|
|
3002
|
+
initializedForToken: authenticationService.getToken(),
|
|
3003
|
+
initializedForIdentity: resolveAuthIdentity(authenticationService.getToken())
|
|
3004
3004
|
});
|
|
3005
|
-
setStoredSyncIdentity(resolveAuthIdentity(
|
|
3005
|
+
setStoredSyncIdentity(resolveAuthIdentity(authenticationService.getToken()));
|
|
3006
3006
|
if (preference.syncEnabled && preference.isAdvancedVectorFeaturesEnabled) {
|
|
3007
3007
|
await get().runSync({ force: true });
|
|
3008
3008
|
}
|
|
@@ -3042,7 +3042,7 @@ var init_conversationSyncStore = __esm({
|
|
|
3042
3042
|
debugLogger.error("conversationSyncStore: runSync error - missing gateway URL");
|
|
3043
3043
|
return;
|
|
3044
3044
|
}
|
|
3045
|
-
const token =
|
|
3045
|
+
const token = authenticationService.getToken();
|
|
3046
3046
|
if (!token) {
|
|
3047
3047
|
set({ status: "error", lastError: "Authentication required to sync conversations." });
|
|
3048
3048
|
debugLogger.error("conversationSyncStore: runSync error - missing auth token");
|
|
@@ -3342,7 +3342,7 @@ var init_mcpServersService = __esm({
|
|
|
3342
3342
|
};
|
|
3343
3343
|
authHeaders = () => {
|
|
3344
3344
|
const headers = { "Content-Type": "application/json" };
|
|
3345
|
-
const token =
|
|
3345
|
+
const token = authenticationService.getToken();
|
|
3346
3346
|
if (token) headers["Authorization"] = `Bearer ${token}`;
|
|
3347
3347
|
return headers;
|
|
3348
3348
|
};
|
|
@@ -4784,7 +4784,7 @@ var init_gateway_service = __esm({
|
|
|
4784
4784
|
return;
|
|
4785
4785
|
}
|
|
4786
4786
|
try {
|
|
4787
|
-
|
|
4787
|
+
authenticationService.clearToken();
|
|
4788
4788
|
} catch {
|
|
4789
4789
|
}
|
|
4790
4790
|
if (typeof window !== "undefined" && typeof window.dispatchEvent === "function") {
|
|
@@ -6132,7 +6132,7 @@ var init_playground_provider = __esm({
|
|
|
6132
6132
|
PlaygroundProvider = class {
|
|
6133
6133
|
config;
|
|
6134
6134
|
constructor(config) {
|
|
6135
|
-
this.config = { type: "playground" /* PLAYGROUND
|
|
6135
|
+
this.config = { ...config, type: config.type ?? "playground" /* PLAYGROUND */ };
|
|
6136
6136
|
}
|
|
6137
6137
|
chat(request) {
|
|
6138
6138
|
const lastUserMessage = [...request.messages].reverse().find((m) => m.role === "user")?.content ?? "";
|
|
@@ -10570,7 +10570,7 @@ var init_useKnowledgeStore = __esm({
|
|
|
10570
10570
|
init_indexedDBService();
|
|
10571
10571
|
import_uuid5 = require("uuid");
|
|
10572
10572
|
import_mammoth = __toESM(require("mammoth"));
|
|
10573
|
-
pdfjsLib = __toESM(require("pdfjs-dist/legacy/build/pdf"));
|
|
10573
|
+
pdfjsLib = __toESM(require("pdfjs-dist/legacy/build/pdf.mjs"));
|
|
10574
10574
|
init_embeddingService();
|
|
10575
10575
|
init_debugLogger();
|
|
10576
10576
|
init_vectorDatabaseService();
|
|
@@ -11690,7 +11690,7 @@ ${listMarkdown}`;
|
|
|
11690
11690
|
children
|
|
11691
11691
|
}
|
|
11692
11692
|
);
|
|
11693
|
-
const CodeRenderer = ({
|
|
11693
|
+
const CodeRenderer = ({ node: _node, className, children, ...props }) => {
|
|
11694
11694
|
const match = /language-([\w-]+)/.exec(className || "");
|
|
11695
11695
|
const requestedLanguage = match?.[1]?.toLowerCase() ?? "";
|
|
11696
11696
|
const codeText = String(children).replace(/\n$/, "");
|
|
@@ -12862,7 +12862,7 @@ var init_knowledge_file_modal = __esm({
|
|
|
12862
12862
|
import_material9 = require("@mui/material");
|
|
12863
12863
|
init_useVectorStore();
|
|
12864
12864
|
init_packageSettingsStore();
|
|
12865
|
-
pdfjsLib2 = __toESM(require("pdfjs-dist/legacy/build/pdf"));
|
|
12865
|
+
pdfjsLib2 = __toESM(require("pdfjs-dist/legacy/build/pdf.mjs"));
|
|
12866
12866
|
init_lowlight();
|
|
12867
12867
|
init_markdownRendering();
|
|
12868
12868
|
init_debugLogger();
|
|
@@ -13613,7 +13613,7 @@ var init_voiceService = __esm({
|
|
|
13613
13613
|
debugLogger.error("Gateway API URL not configured");
|
|
13614
13614
|
throw new Error("Gateway API URL not configured");
|
|
13615
13615
|
}
|
|
13616
|
-
const token =
|
|
13616
|
+
const token = authenticationService.getToken();
|
|
13617
13617
|
if (!token) {
|
|
13618
13618
|
debugLogger.warn("No JWT token available - skipping voice models fetch");
|
|
13619
13619
|
const emptyModels = {
|
|
@@ -13623,7 +13623,7 @@ var init_voiceService = __esm({
|
|
|
13623
13623
|
};
|
|
13624
13624
|
return emptyModels;
|
|
13625
13625
|
}
|
|
13626
|
-
if (
|
|
13626
|
+
if (authenticationService.isTokenExpired(token)) {
|
|
13627
13627
|
debugLogger.warn("JWT token is expired - skipping voice models fetch");
|
|
13628
13628
|
const emptyModels = {
|
|
13629
13629
|
models: [],
|
|
@@ -13712,7 +13712,7 @@ var init_tts_client = __esm({
|
|
|
13712
13712
|
init_packageSettingsStore();
|
|
13713
13713
|
init_debugLogger();
|
|
13714
13714
|
getOrAppendAuthHeader = (existing = {}) => {
|
|
13715
|
-
const token =
|
|
13715
|
+
const token = authenticationService.getToken();
|
|
13716
13716
|
if (token) {
|
|
13717
13717
|
existing["Authorization"] = `Bearer ${token}`;
|
|
13718
13718
|
return existing;
|
|
@@ -14409,8 +14409,8 @@ var init_ai_response_action_bar = __esm({
|
|
|
14409
14409
|
const { preferences } = usePreferencesStore();
|
|
14410
14410
|
const { settings: packageSettings } = usePackageSettingsStore();
|
|
14411
14411
|
(0, import_react18.useEffect)(() => {
|
|
14412
|
-
const isAuthenticated =
|
|
14413
|
-
const token =
|
|
14412
|
+
const isAuthenticated = authenticationService.isAuthenticated();
|
|
14413
|
+
const token = authenticationService.getToken();
|
|
14414
14414
|
if (!initialized || availableVoices.length === 0) {
|
|
14415
14415
|
if (token && isAuthenticated) {
|
|
14416
14416
|
debugLogger.debug("AI Action Bar: Voices not initialized or unavailable, attempting to load from API");
|
|
@@ -15254,11 +15254,12 @@ ${sourcesMarkdownList.join("\n")}`;
|
|
|
15254
15254
|
tr({ children, node: _node, ...tableRowProps }) {
|
|
15255
15255
|
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material11.TableRow, { ...tableRowProps, children });
|
|
15256
15256
|
},
|
|
15257
|
-
th({ children, node: _node, ...tableCellProps }) {
|
|
15257
|
+
th({ children, node: _node, align, ...tableCellProps }) {
|
|
15258
15258
|
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
15259
15259
|
import_material11.TableCell,
|
|
15260
15260
|
{
|
|
15261
15261
|
...tableCellProps,
|
|
15262
|
+
align: align === "char" ? void 0 : align,
|
|
15262
15263
|
sx: {
|
|
15263
15264
|
fontWeight: "bold",
|
|
15264
15265
|
color: theme.palette.text.primary,
|
|
@@ -15271,11 +15272,12 @@ ${sourcesMarkdownList.join("\n")}`;
|
|
|
15271
15272
|
}
|
|
15272
15273
|
);
|
|
15273
15274
|
},
|
|
15274
|
-
td({ children, node: _node, ...tableCellProps }) {
|
|
15275
|
+
td({ children, node: _node, align, ...tableCellProps }) {
|
|
15275
15276
|
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
15276
15277
|
import_material11.TableCell,
|
|
15277
15278
|
{
|
|
15278
15279
|
...tableCellProps,
|
|
15280
|
+
align: align === "char" ? void 0 : align,
|
|
15279
15281
|
sx: {
|
|
15280
15282
|
color: theme.palette.text.primary,
|
|
15281
15283
|
fontSize: "0.875rem",
|
|
@@ -16073,7 +16075,7 @@ var init_engineStore = __esm({
|
|
|
16073
16075
|
}
|
|
16074
16076
|
try {
|
|
16075
16077
|
const headers = { "Content-Type": "application/json" };
|
|
16076
|
-
const token =
|
|
16078
|
+
const token = authenticationService.getToken();
|
|
16077
16079
|
if (token) headers["Authorization"] = `Bearer ${token}`;
|
|
16078
16080
|
const res = await fetch(`${base}/models`, { headers });
|
|
16079
16081
|
const data = await res.json();
|
|
@@ -16392,7 +16394,7 @@ var init_stt_client = __esm({
|
|
|
16392
16394
|
filename,
|
|
16393
16395
|
url: `${gatewayUrl}/stt/transcribe`
|
|
16394
16396
|
});
|
|
16395
|
-
const token =
|
|
16397
|
+
const token = authenticationService.getToken();
|
|
16396
16398
|
const response = await fetch(`${gatewayUrl}/stt/transcribe`, {
|
|
16397
16399
|
method: "POST",
|
|
16398
16400
|
headers: {
|
|
@@ -17336,7 +17338,7 @@ var init_memory_modal = __esm({
|
|
|
17336
17338
|
color: (0, import_styles8.alpha)(theme.palette.text.secondary, 0.7),
|
|
17337
17339
|
maxWidth: 280
|
|
17338
17340
|
}, children: selectedTab === "user" ? shouldUseVectorForMemories ? "Start by adding something you'd like me to remember. Your memories will be kept in a private workspace for quick recall." : "Start by adding something you'd like me to remember about you or your preferences." : shouldUseVectorForMemories ? "Auto memories are created automatically based on our conversations and kept in your private workspace for better answers." : "Auto memories are created automatically based on our conversations." })
|
|
17339
|
-
] }) : filteredMemories.map((memory) => {
|
|
17341
|
+
] }) : filteredMemories.map((memory, memoryIndex) => {
|
|
17340
17342
|
const isSelected = selectedIds.includes(memory.id);
|
|
17341
17343
|
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_react25.default.Fragment, { children: [
|
|
17342
17344
|
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_material16.List, { sx: { listStyle: "none", pl: 0, m: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
@@ -17536,7 +17538,7 @@ var init_memory_modal = __esm({
|
|
|
17536
17538
|
]
|
|
17537
17539
|
}
|
|
17538
17540
|
) }),
|
|
17539
|
-
|
|
17541
|
+
memoryIndex < filteredMemories.length - 1 && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_material16.Divider, { sx: { bgcolor: (0, import_styles8.alpha)(appBar.border, 0.5), my: 0.5 } })
|
|
17540
17542
|
] }, memory.id);
|
|
17541
17543
|
})
|
|
17542
17544
|
}
|
|
@@ -18000,6 +18002,109 @@ var init_memory_modal = __esm({
|
|
|
18000
18002
|
}
|
|
18001
18003
|
});
|
|
18002
18004
|
|
|
18005
|
+
// src/chat/composer-submission.ts
|
|
18006
|
+
var isPromiseLike, awaitAcceptance, buildSubmission, isImeComposing;
|
|
18007
|
+
var init_composer_submission = __esm({
|
|
18008
|
+
"src/chat/composer-submission.ts"() {
|
|
18009
|
+
"use strict";
|
|
18010
|
+
isPromiseLike = (value) => !!value && typeof value.then === "function";
|
|
18011
|
+
awaitAcceptance = async (ack) => {
|
|
18012
|
+
if (ack === false) return false;
|
|
18013
|
+
if (!isPromiseLike(ack)) return true;
|
|
18014
|
+
try {
|
|
18015
|
+
return await ack !== false;
|
|
18016
|
+
} catch {
|
|
18017
|
+
return false;
|
|
18018
|
+
}
|
|
18019
|
+
};
|
|
18020
|
+
buildSubmission = (text, images, documents) => {
|
|
18021
|
+
const typed = text.trim();
|
|
18022
|
+
const base = typed || (images.length === 1 ? "[\u{1F4F7} You attached an image]" : images.length > 1 ? `[\u{1F4F7} You attached ${images.length} images]` : "");
|
|
18023
|
+
const fileSummary = documents.length > 0 ? `[\u{1F4CE} Attached ${documents.length} file${documents.length > 1 ? "s" : ""}: ${documents.map((d) => d.fileName).join(", ")}]` : "";
|
|
18024
|
+
const displayQuestion = [base || (fileSummary ? "[\u{1F4E4} You submitted content without text]" : ""), fileSummary].filter(Boolean).join("\n\n");
|
|
18025
|
+
const prompt = [text, ...documents.map((d) => d.block)].filter(Boolean).join("\n\n");
|
|
18026
|
+
return { prompt, images: [...images], displayQuestion };
|
|
18027
|
+
};
|
|
18028
|
+
isImeComposing = (event) => event.nativeEvent?.isComposing === true || event.keyCode === 229;
|
|
18029
|
+
}
|
|
18030
|
+
});
|
|
18031
|
+
|
|
18032
|
+
// src/chat/document-import.ts
|
|
18033
|
+
var CODE_EXTENSIONS, TEXT_EXTENSIONS, isCodeFileName, isPlainTextFile, CONTROL_CHARS, INVISIBLE_FORMATTING, stripInvisible, neutralizeRoleMarkers, prepareDocumentText, formatDocumentBlock, readText, readPdfText, readDocument;
|
|
18034
|
+
var init_document_import = __esm({
|
|
18035
|
+
"src/chat/document-import.ts"() {
|
|
18036
|
+
"use strict";
|
|
18037
|
+
CODE_EXTENSIONS = [".js", ".ts", ".tsx", ".json", ".py", ".java", ".c", ".cpp", ".cs"];
|
|
18038
|
+
TEXT_EXTENSIONS = [".md", ".txt", ...CODE_EXTENSIONS];
|
|
18039
|
+
isCodeFileName = (name) => {
|
|
18040
|
+
const lower = name.toLowerCase();
|
|
18041
|
+
return CODE_EXTENSIONS.some((ext) => lower.endsWith(ext));
|
|
18042
|
+
};
|
|
18043
|
+
isPlainTextFile = (name, mimeType = "") => mimeType.startsWith("text/") || TEXT_EXTENSIONS.some((ext) => name.toLowerCase().endsWith(ext));
|
|
18044
|
+
CONTROL_CHARS = /[\u0000-\u0008\u000B\u000C\u000E-\u001F\u007F-\u009F]/g;
|
|
18045
|
+
INVISIBLE_FORMATTING = /[\u202A-\u202E\u2066-\u2069\u200B\u2060\uFEFF]/g;
|
|
18046
|
+
stripInvisible = (text) => text.normalize("NFC").replace(CONTROL_CHARS, "").replace(INVISIBLE_FORMATTING, "");
|
|
18047
|
+
neutralizeRoleMarkers = (text) => text.replace(/<\s*\/?\s*script\b[^>]*>/gi, "").replace(/(^|\n)([ \t]*)\/?(system|assistant|user)\s*:/gi, "$1$2[removed-role]");
|
|
18048
|
+
prepareDocumentText = (text, fileName) => {
|
|
18049
|
+
const visible = stripInvisible(text);
|
|
18050
|
+
return (isCodeFileName(fileName) ? visible : neutralizeRoleMarkers(visible)).trim();
|
|
18051
|
+
};
|
|
18052
|
+
formatDocumentBlock = (fileName, text) => `\u{1F4C4} ${fileName}
|
|
18053
|
+
${prepareDocumentText(text, fileName)}`;
|
|
18054
|
+
readText = (file) => typeof file.text === "function" ? file.text() : new Promise((resolve, reject) => {
|
|
18055
|
+
const reader = new FileReader();
|
|
18056
|
+
reader.onload = () => resolve(String(reader.result ?? ""));
|
|
18057
|
+
reader.onerror = () => reject(reader.error ?? new Error("It couldn't be read."));
|
|
18058
|
+
reader.readAsText(file);
|
|
18059
|
+
});
|
|
18060
|
+
readPdfText = async (file, maxPages = 10) => {
|
|
18061
|
+
const pdfjsLib3 = await import("pdfjs-dist/legacy/build/pdf.mjs");
|
|
18062
|
+
pdfjsLib3.GlobalWorkerOptions.workerSrc = "https://cdn.burtson.ai/scripts/pdf.worker.js";
|
|
18063
|
+
const pdf = await pdfjsLib3.getDocument({ data: await file.arrayBuffer() }).promise;
|
|
18064
|
+
const pages = await Promise.all(
|
|
18065
|
+
Array.from({ length: Math.min(pdf.numPages, maxPages) }, async (_, i) => {
|
|
18066
|
+
try {
|
|
18067
|
+
const page = await pdf.getPage(i + 1);
|
|
18068
|
+
const content = await page.getTextContent();
|
|
18069
|
+
return content.items.map((item) => typeof item?.str === "string" ? item.str : "").join(" ");
|
|
18070
|
+
} catch {
|
|
18071
|
+
return "";
|
|
18072
|
+
}
|
|
18073
|
+
})
|
|
18074
|
+
);
|
|
18075
|
+
return pages.join("\n\n");
|
|
18076
|
+
};
|
|
18077
|
+
readDocument = async (file) => {
|
|
18078
|
+
const name = file.name.toLowerCase();
|
|
18079
|
+
try {
|
|
18080
|
+
let text;
|
|
18081
|
+
if (isPlainTextFile(name, file.type)) {
|
|
18082
|
+
text = await readText(file);
|
|
18083
|
+
} else if (name.endsWith(".docx")) {
|
|
18084
|
+
const mammoth2 = await import("mammoth");
|
|
18085
|
+
text = (await mammoth2.extractRawText({ arrayBuffer: await file.arrayBuffer() })).value;
|
|
18086
|
+
} else if (name.endsWith(".pdf")) {
|
|
18087
|
+
text = await readPdfText(file);
|
|
18088
|
+
} else {
|
|
18089
|
+
return { ok: false, fileName: file.name, reason: "This file type can't be read yet." };
|
|
18090
|
+
}
|
|
18091
|
+
const block = formatDocumentBlock(file.name, text);
|
|
18092
|
+
if (block === `\u{1F4C4} ${file.name}
|
|
18093
|
+
`) {
|
|
18094
|
+
return { ok: false, fileName: file.name, reason: "No readable text was found in it." };
|
|
18095
|
+
}
|
|
18096
|
+
return { ok: true, fileName: file.name, block };
|
|
18097
|
+
} catch (error) {
|
|
18098
|
+
return {
|
|
18099
|
+
ok: false,
|
|
18100
|
+
fileName: file.name,
|
|
18101
|
+
reason: error instanceof Error && error.message ? error.message : "It couldn't be read."
|
|
18102
|
+
};
|
|
18103
|
+
}
|
|
18104
|
+
};
|
|
18105
|
+
}
|
|
18106
|
+
});
|
|
18107
|
+
|
|
18003
18108
|
// src/store/voiceModeStore.ts
|
|
18004
18109
|
var import_zustand16, useVoiceModeStore;
|
|
18005
18110
|
var init_voiceModeStore = __esm({
|
|
@@ -18054,6 +18159,8 @@ var init_chat_input = __esm({
|
|
|
18054
18159
|
init_packageSettingsStore();
|
|
18055
18160
|
init_transcriber();
|
|
18056
18161
|
init_memory_modal();
|
|
18162
|
+
init_composer_submission();
|
|
18163
|
+
init_document_import();
|
|
18057
18164
|
import_styles9 = require("@mui/material/styles");
|
|
18058
18165
|
init_debugLogger();
|
|
18059
18166
|
init_brandingService();
|
|
@@ -18222,102 +18329,60 @@ var init_chat_input = __esm({
|
|
|
18222
18329
|
const removeImage = (index) => {
|
|
18223
18330
|
setPastedImages((prev) => prev.filter((_, i) => i !== index));
|
|
18224
18331
|
};
|
|
18332
|
+
const latestDraftRef = (0, import_react26.useRef)({ text: inputValue, images: pastedImages, files: fileInputs });
|
|
18333
|
+
latestDraftRef.current = { text: inputValue, images: pastedImages, files: fileInputs };
|
|
18334
|
+
const submittingRef = (0, import_react26.useRef)(false);
|
|
18335
|
+
const [sendError, setSendError] = (0, import_react26.useState)(null);
|
|
18225
18336
|
const handleSubmit = async () => {
|
|
18226
|
-
if (
|
|
18227
|
-
|
|
18228
|
-
|
|
18229
|
-
const
|
|
18230
|
-
|
|
18231
|
-
|
|
18232
|
-
|
|
18233
|
-
|
|
18234
|
-
|
|
18235
|
-
|
|
18236
|
-
|
|
18237
|
-
|
|
18238
|
-
|
|
18239
|
-
|
|
18240
|
-
|
|
18241
|
-
|
|
18242
|
-
|
|
18243
|
-
|
|
18244
|
-
|
|
18245
|
-
|
|
18246
|
-
|
|
18247
|
-
|
|
18248
|
-
|
|
18249
|
-
|
|
18250
|
-
|
|
18251
|
-
|
|
18252
|
-
|
|
18253
|
-
|
|
18254
|
-
|
|
18255
|
-
|
|
18256
|
-
|
|
18257
|
-
|
|
18258
|
-
|
|
18259
|
-
|
|
18260
|
-
|
|
18261
|
-
|
|
18262
|
-
|
|
18263
|
-
|
|
18264
|
-
Array.from({ length: maxPages }, async (_, i) => {
|
|
18265
|
-
try {
|
|
18266
|
-
const page = await pdf.getPage(i + 1);
|
|
18267
|
-
const content = await page.getTextContent();
|
|
18268
|
-
return content.items.map((item) => {
|
|
18269
|
-
if (item && typeof item === "object" && "str" in item && typeof item.str === "string") {
|
|
18270
|
-
return item.str;
|
|
18271
|
-
}
|
|
18272
|
-
return "";
|
|
18273
|
-
}).join(" ");
|
|
18274
|
-
} catch (err) {
|
|
18275
|
-
debugLogger.error(`Failed to read page ${i + 1}`, { error: err });
|
|
18276
|
-
return "";
|
|
18277
|
-
}
|
|
18278
|
-
})
|
|
18279
|
-
);
|
|
18280
|
-
const joined = pages.join("\n\n");
|
|
18281
|
-
debugLogger.info("Extracted PDF content", { contentPreview: joined.slice(0, 500) });
|
|
18282
|
-
return `\u{1F4C4} ${file.name}
|
|
18283
|
-
${sanitize(
|
|
18284
|
-
escapePromptInjection(joined),
|
|
18285
|
-
file.name
|
|
18286
|
-
)}`;
|
|
18287
|
-
} catch (error) {
|
|
18288
|
-
debugLogger.error("PDF load failed", {
|
|
18289
|
-
error: error instanceof Error ? error.message : String(error),
|
|
18290
|
-
fileName: file.name
|
|
18291
|
-
});
|
|
18292
|
-
return "";
|
|
18293
|
-
}
|
|
18337
|
+
if (submittingRef.current) return;
|
|
18338
|
+
if (inputValue.trim() === "" && pastedImages.length === 0 && fileInputs.length === 0) return;
|
|
18339
|
+
submittingRef.current = true;
|
|
18340
|
+
const draft = { text: inputValue, images: [...pastedImages], files: [...fileInputs] };
|
|
18341
|
+
try {
|
|
18342
|
+
const reads = await Promise.all(draft.files.map(readDocument));
|
|
18343
|
+
const failed = reads.filter((r) => !r.ok);
|
|
18344
|
+
if (failed.length > 0) {
|
|
18345
|
+
setSendError(
|
|
18346
|
+
failed.map((f) => `Couldn't attach ${f.fileName}: ${f.reason}`).join(" ")
|
|
18347
|
+
);
|
|
18348
|
+
return;
|
|
18349
|
+
}
|
|
18350
|
+
const documents = reads.filter((r) => r.ok);
|
|
18351
|
+
const submission = buildSubmission(draft.text, draft.images, documents);
|
|
18352
|
+
debugLogger.debug("Composer submission", {
|
|
18353
|
+
documents: documents.map((d) => d.fileName),
|
|
18354
|
+
promptLength: submission.prompt.length
|
|
18355
|
+
});
|
|
18356
|
+
setSendError(null);
|
|
18357
|
+
setInputValue("");
|
|
18358
|
+
setPastedImages([]);
|
|
18359
|
+
setFileInputs([]);
|
|
18360
|
+
if (fileInputRef.current) fileInputRef.current.value = "";
|
|
18361
|
+
inputRef.current?.blur();
|
|
18362
|
+
const accepted = await awaitAcceptance(
|
|
18363
|
+
onSend(submission.prompt, submission.images, submission.displayQuestion)
|
|
18364
|
+
);
|
|
18365
|
+
if (!accepted) {
|
|
18366
|
+
const now = latestDraftRef.current;
|
|
18367
|
+
const untouched = now.text.trim() === "" && now.images.length === 0 && now.files.length === 0;
|
|
18368
|
+
if (untouched) {
|
|
18369
|
+
setInputValue(draft.text);
|
|
18370
|
+
setPastedImages(draft.images);
|
|
18371
|
+
setFileInputs(draft.files);
|
|
18372
|
+
setSendError("Your message wasn't sent. It's back in the box so you can try again.");
|
|
18373
|
+
} else {
|
|
18374
|
+
setSendError("Your last message wasn't sent.");
|
|
18294
18375
|
}
|
|
18295
|
-
return "";
|
|
18296
|
-
} catch {
|
|
18297
|
-
return "";
|
|
18298
18376
|
}
|
|
18299
|
-
}
|
|
18300
|
-
|
|
18301
|
-
|
|
18302
|
-
const fileContent = fileTexts.filter(Boolean).join("\n\n");
|
|
18303
|
-
const tempQuestionBase = inputValue.trim() || (tempImages.length === 1 ? "[\u{1F4F7} You attached an image]" : tempImages.length > 1 ? `[\u{1F4F7} You attached ${tempImages.length} images]` : "");
|
|
18304
|
-
const fileDisplaySummary = fileInputs.length > 0 ? `[\u{1F4CE} Attached ${fileInputs.length} file${fileInputs.length > 1 ? "s" : ""}: ${fileInputs.map((f) => f.name).join(", ")}]` : "";
|
|
18305
|
-
const displayQuestion = [
|
|
18306
|
-
tempQuestionBase || (fileDisplaySummary ? "[\u{1F4E4} You submitted content without text]" : ""),
|
|
18307
|
-
fileDisplaySummary
|
|
18308
|
-
].filter(Boolean).join("\n\n");
|
|
18309
|
-
const fullPrompt = [inputValue, fileContent].filter(Boolean).join("\n\n");
|
|
18310
|
-
setInputValue("");
|
|
18311
|
-
setPastedImages([]);
|
|
18312
|
-
setFileInputs([]);
|
|
18313
|
-
onSend(fullPrompt, tempImages, displayQuestion);
|
|
18314
|
-
inputRef.current?.blur();
|
|
18315
|
-
fileInputRef.current.value = "";
|
|
18377
|
+
} finally {
|
|
18378
|
+
submittingRef.current = false;
|
|
18379
|
+
}
|
|
18316
18380
|
};
|
|
18317
18381
|
const handleKeyPress = (e) => {
|
|
18382
|
+
if (isImeComposing(e)) return;
|
|
18318
18383
|
if (e.key === "Enter" && !e.shiftKey) {
|
|
18319
18384
|
e.preventDefault();
|
|
18320
|
-
handleSubmit();
|
|
18385
|
+
void handleSubmit();
|
|
18321
18386
|
}
|
|
18322
18387
|
};
|
|
18323
18388
|
const handleTranscriptionCompleted = (transcribed) => {
|
|
@@ -18435,6 +18500,15 @@ ${sanitize(
|
|
|
18435
18500
|
gap: isMobile ? compactMobile ? 0.75 : 1 : 0.5
|
|
18436
18501
|
},
|
|
18437
18502
|
children: [
|
|
18503
|
+
sendError && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
18504
|
+
import_material17.Typography,
|
|
18505
|
+
{
|
|
18506
|
+
role: "alert",
|
|
18507
|
+
variant: "caption",
|
|
18508
|
+
sx: { color: theme.palette.error.main, px: 0.5, pt: isMobile ? 0 : 0.5 },
|
|
18509
|
+
children: sendError
|
|
18510
|
+
}
|
|
18511
|
+
),
|
|
18438
18512
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
18439
18513
|
import_material17.Box,
|
|
18440
18514
|
{
|
|
@@ -18480,7 +18554,10 @@ ${sanitize(
|
|
|
18480
18554
|
import_material17.IconButton,
|
|
18481
18555
|
{
|
|
18482
18556
|
size: "small",
|
|
18483
|
-
onClick: () =>
|
|
18557
|
+
onClick: () => {
|
|
18558
|
+
setSendError(null);
|
|
18559
|
+
setFileInputs((prev) => prev.filter((_, i) => i !== idx));
|
|
18560
|
+
},
|
|
18484
18561
|
sx: { ml: 0.5, color: theme.palette.mode === "dark" ? "#aaa" : "#444" },
|
|
18485
18562
|
children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(CloseIcon, { sx: { fontSize: 14 } })
|
|
18486
18563
|
}
|
|
@@ -19488,7 +19565,7 @@ function syncTelemetry() {
|
|
|
19488
19565
|
const settings = usePackageSettingsStore.getState().settings;
|
|
19489
19566
|
const cfg = resolveTelemetryConfig({
|
|
19490
19567
|
telemetry: settings?.telemetry,
|
|
19491
|
-
banditApiKey:
|
|
19568
|
+
banditApiKey: authenticationService.getToken() ?? void 0
|
|
19492
19569
|
});
|
|
19493
19570
|
active = cfg ? new TelemetryExporter(cfg) : null;
|
|
19494
19571
|
} catch {
|
|
@@ -20139,7 +20216,7 @@ var init_mcpService = __esm({
|
|
|
20139
20216
|
}
|
|
20140
20217
|
if (tool.mcpServerId) {
|
|
20141
20218
|
const base2 = settings.gatewayApiUrl.replace(/\/$/, "");
|
|
20142
|
-
const token2 =
|
|
20219
|
+
const token2 = authenticationService.getToken();
|
|
20143
20220
|
const controller2 = new AbortController();
|
|
20144
20221
|
const timeoutId2 = setTimeout(() => controller2.abort(), 3e4);
|
|
20145
20222
|
try {
|
|
@@ -20186,7 +20263,7 @@ var init_mcpService = __esm({
|
|
|
20186
20263
|
"Content-Type": "application/json"
|
|
20187
20264
|
}
|
|
20188
20265
|
};
|
|
20189
|
-
const token =
|
|
20266
|
+
const token = authenticationService.getToken();
|
|
20190
20267
|
if (token) {
|
|
20191
20268
|
requestOptions.headers = {
|
|
20192
20269
|
...requestOptions.headers,
|
|
@@ -20286,6 +20363,7 @@ var init_useAIProvider = __esm({
|
|
|
20286
20363
|
"src/chat/hooks/useAIProvider.tsx"() {
|
|
20287
20364
|
"use strict";
|
|
20288
20365
|
init_debugLogger();
|
|
20366
|
+
init_authenticationService();
|
|
20289
20367
|
import_react31 = require("react");
|
|
20290
20368
|
init_knowledgeStore();
|
|
20291
20369
|
init_aiProviderStore();
|
|
@@ -20587,8 +20665,11 @@ var init_useAIProvider = __esm({
|
|
|
20587
20665
|
history,
|
|
20588
20666
|
addHistory,
|
|
20589
20667
|
inputRef,
|
|
20590
|
-
onError
|
|
20668
|
+
onError,
|
|
20669
|
+
onTurnOutcome
|
|
20591
20670
|
}) => {
|
|
20671
|
+
const onTurnOutcomeRef = (0, import_react31.useRef)(onTurnOutcome);
|
|
20672
|
+
onTurnOutcomeRef.current = onTurnOutcome;
|
|
20592
20673
|
const currentSubRef = (0, import_react31.useRef)(null);
|
|
20593
20674
|
const lastPartialRef = (0, import_react31.useRef)({
|
|
20594
20675
|
text: "",
|
|
@@ -20634,10 +20715,14 @@ var init_useAIProvider = __esm({
|
|
|
20634
20715
|
};
|
|
20635
20716
|
const runAIProvider = (0, import_react31.useCallback)(
|
|
20636
20717
|
async (systemPrompt, question, images) => {
|
|
20718
|
+
let turnHadOutput = false;
|
|
20719
|
+
const reportOutcome = (outcome) => onTurnOutcomeRef.current?.(outcome);
|
|
20637
20720
|
if (!provider) {
|
|
20638
20721
|
debugLogger.error("No AI provider configured");
|
|
20639
20722
|
overrideComponentStatus("Error");
|
|
20640
|
-
|
|
20723
|
+
const error = new Error("No AI provider configured");
|
|
20724
|
+
if (onError) onError(error);
|
|
20725
|
+
reportOutcome({ kind: "failed", hadOutput: false, error });
|
|
20641
20726
|
return;
|
|
20642
20727
|
}
|
|
20643
20728
|
const userPreferences = preferences;
|
|
@@ -20791,7 +20876,7 @@ Use this information to personalize your responses whenever relevant.` : "";
|
|
|
20791
20876
|
s3Url: resolvedId,
|
|
20792
20877
|
isUserContent: result.isUserContent,
|
|
20793
20878
|
isTeamContent: result.isTeamContent,
|
|
20794
|
-
contentSource: result.contentSource,
|
|
20879
|
+
contentSource: result.contentSource === "user" || result.contentSource === "team" ? result.contentSource : void 0,
|
|
20795
20880
|
originalFileName: result.originalFileName || result.filename || result.name,
|
|
20796
20881
|
// Preserve original data for downstream checks (e.g. vector modal detection)
|
|
20797
20882
|
_vectorResult: result
|
|
@@ -21146,6 +21231,10 @@ ${protocol}`;
|
|
|
21146
21231
|
const sub = stream.subscribe({
|
|
21147
21232
|
next: (data) => {
|
|
21148
21233
|
if (!data?.message?.content && !data?.message?.tool_calls) return;
|
|
21234
|
+
if (!turnHadOutput) {
|
|
21235
|
+
turnHadOutput = true;
|
|
21236
|
+
reportOutcome({ kind: "output" });
|
|
21237
|
+
}
|
|
21149
21238
|
if (Array.isArray(data.message.tool_calls) && data.message.tool_calls.length > 0) {
|
|
21150
21239
|
nativeToolCalls.push(...data.message.tool_calls);
|
|
21151
21240
|
sawToolBlock = true;
|
|
@@ -21180,13 +21269,14 @@ ${protocol}`;
|
|
|
21180
21269
|
},
|
|
21181
21270
|
error: (err) => {
|
|
21182
21271
|
debugLogger.error("Stream error:", err);
|
|
21272
|
+
reportOutcome({ kind: "failed", hadOutput: turnHadOutput, error: err });
|
|
21183
21273
|
stopWorking();
|
|
21184
21274
|
overrideComponentStatus("Idle");
|
|
21185
21275
|
setIsSubmitting(false);
|
|
21186
21276
|
setIsStreaming(false);
|
|
21187
21277
|
if (/lifetime validation|token.*(expired|invalid)|unauthorized|\b401\b/i.test(err.message || "")) {
|
|
21188
|
-
const { replaceLastAnswer:
|
|
21189
|
-
|
|
21278
|
+
const { replaceLastAnswer: replaceLastAnswer3 } = useConversationStore.getState();
|
|
21279
|
+
replaceLastAnswer3(
|
|
21190
21280
|
"_Your session ended \u2014 sign back in to continue._",
|
|
21191
21281
|
lastPartialRef.current.images,
|
|
21192
21282
|
false,
|
|
@@ -21213,8 +21303,8 @@ ${protocol}`;
|
|
|
21213
21303
|
scope: rateLimit.scope,
|
|
21214
21304
|
frontier: rateLimit.frontier
|
|
21215
21305
|
});
|
|
21216
|
-
const { replaceLastAnswer:
|
|
21217
|
-
|
|
21306
|
+
const { replaceLastAnswer: replaceLastAnswer3 } = useConversationStore.getState();
|
|
21307
|
+
replaceLastAnswer3(
|
|
21218
21308
|
rateLimit.scope === "weekly" ? "_You've reached your weekly limit. Upgrade to keep chatting._" : "_You've hit your session limit. It resets soon \u2014 or upgrade for higher limits._",
|
|
21219
21309
|
lastPartialRef.current.images,
|
|
21220
21310
|
false,
|
|
@@ -21235,10 +21325,16 @@ ${protocol}`;
|
|
|
21235
21325
|
if (partial && !partial.trim().endsWith("\u2026") && !partial.trim().endsWith("...")) {
|
|
21236
21326
|
partial = partial.trimEnd() + " \u2026";
|
|
21237
21327
|
}
|
|
21328
|
+
const { replaceLastAnswer: replaceLastAnswer2 } = useConversationStore.getState();
|
|
21238
21329
|
if (partial) {
|
|
21239
|
-
const { replaceLastAnswer: replaceLastAnswer2 } = useConversationStore.getState();
|
|
21240
21330
|
replaceLastAnswer2(partial, lastPartialRef.current.images, false, lastPartialRef.current.usedDocs, true);
|
|
21241
21331
|
setResponse(partial);
|
|
21332
|
+
} else {
|
|
21333
|
+
const { conversations: convs, currentId: convId } = useConversationStore.getState();
|
|
21334
|
+
const last = convs.find((c) => c.id === convId)?.history.at(-1);
|
|
21335
|
+
if (last?.answer === "...") {
|
|
21336
|
+
replaceLastAnswer2("_No response came back. Try sending again._", lastPartialRef.current.images, false, lastPartialRef.current.usedDocs, true);
|
|
21337
|
+
}
|
|
21242
21338
|
}
|
|
21243
21339
|
setStreamBuffer("");
|
|
21244
21340
|
setIsThinking?.(false);
|
|
@@ -21250,6 +21346,7 @@ ${protocol}`;
|
|
|
21250
21346
|
}
|
|
21251
21347
|
},
|
|
21252
21348
|
complete: async () => {
|
|
21349
|
+
reportOutcome({ kind: "completed" });
|
|
21253
21350
|
try {
|
|
21254
21351
|
setIsThinking?.(false);
|
|
21255
21352
|
telemetryEvent("tool_loop:llm_response", { responseLength: fullMessage.length });
|
|
@@ -21516,7 +21613,7 @@ _This link is temporary and expires in about ${mins} minutes._`;
|
|
|
21516
21613
|
}
|
|
21517
21614
|
} else {
|
|
21518
21615
|
const data = result.data ?? {};
|
|
21519
|
-
const informative = [data.message, data.details, data.error, result.error].map((value) => typeof value === "string" ? value.trim() :
|
|
21616
|
+
const informative = [data.message, data.details, data.error, result.error].map((value) => typeof value === "string" ? value.trim() : "").filter((value) => value.length > 0 && value.toLowerCase() !== "n/a");
|
|
21520
21617
|
resultText = informative.length ? informative.join(" \u2014 ") : `I couldn't complete that request: ${result.error || "Unknown error"}.`;
|
|
21521
21618
|
}
|
|
21522
21619
|
enhancedMessage = enhancedMessage.replace(placeholderToken, resultText);
|
|
@@ -21863,6 +21960,7 @@ ${inlineImageBlocks.join("\n\n")}` : "");
|
|
|
21863
21960
|
} catch {
|
|
21864
21961
|
}
|
|
21865
21962
|
currentSubRef.current = null;
|
|
21963
|
+
onTurnOutcomeRef.current?.({ kind: "cancelled" });
|
|
21866
21964
|
let partial = lastPartialRef.current.text;
|
|
21867
21965
|
if (partial && !partial.trim().endsWith("\u2026") && !partial.trim().endsWith("...")) {
|
|
21868
21966
|
partial = partial.trimEnd() + " \u2026";
|
|
@@ -22081,7 +22179,7 @@ var init_useNetworkStatus = __esm({
|
|
|
22081
22179
|
if (connection) {
|
|
22082
22180
|
const updateConnectionInfo = () => {
|
|
22083
22181
|
const slowConnections = ["slow-2g", "2g"];
|
|
22084
|
-
const isSlowConnection = slowConnections.includes(connection.effectiveType);
|
|
22182
|
+
const isSlowConnection = slowConnections.includes(connection.effectiveType ?? "");
|
|
22085
22183
|
setNetworkStatus((prev) => ({
|
|
22086
22184
|
...prev,
|
|
22087
22185
|
isSlowConnection,
|
|
@@ -22361,7 +22459,7 @@ var init_FeedbackModal = __esm({
|
|
|
22361
22459
|
}
|
|
22362
22460
|
const gatewayService = new GatewayService(
|
|
22363
22461
|
gatewayUrl,
|
|
22364
|
-
() =>
|
|
22462
|
+
() => authenticationService.getToken(),
|
|
22365
22463
|
feedbackEmail || settings?.feedbackEmail
|
|
22366
22464
|
);
|
|
22367
22465
|
const feedbackRequest = {
|
|
@@ -25650,7 +25748,7 @@ var init_conversation_drawer = __esm({
|
|
|
25650
25748
|
title: "Sign out",
|
|
25651
25749
|
onClick: (event) => {
|
|
25652
25750
|
event.stopPropagation();
|
|
25653
|
-
|
|
25751
|
+
authenticationService.clearToken();
|
|
25654
25752
|
window.location.href = "/login";
|
|
25655
25753
|
},
|
|
25656
25754
|
sx: {
|
|
@@ -26777,7 +26875,7 @@ var init_enhanced_mobile_conversations_modal = __esm({
|
|
|
26777
26875
|
title: "Sign out",
|
|
26778
26876
|
onClick: (event) => {
|
|
26779
26877
|
event.stopPropagation();
|
|
26780
|
-
|
|
26878
|
+
authenticationService.clearToken();
|
|
26781
26879
|
window.location.href = "/login";
|
|
26782
26880
|
},
|
|
26783
26881
|
sx: {
|
|
@@ -27597,7 +27695,8 @@ var init_query_suggestion_picker = __esm({
|
|
|
27597
27695
|
}
|
|
27598
27696
|
},
|
|
27599
27697
|
onClick: () => {
|
|
27600
|
-
onSend(prompt, [])
|
|
27698
|
+
void Promise.resolve(onSend(prompt, [])).catch(() => {
|
|
27699
|
+
});
|
|
27601
27700
|
setHasSentPrompt(true);
|
|
27602
27701
|
},
|
|
27603
27702
|
children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
@@ -30117,7 +30216,7 @@ var init_UnderReview = __esm({
|
|
|
30117
30216
|
const theme = (0, import_material31.useTheme)();
|
|
30118
30217
|
const navigate = (0, import_react_router_dom4.useNavigate)();
|
|
30119
30218
|
const handleResetSession = () => {
|
|
30120
|
-
|
|
30219
|
+
authenticationService.clearToken();
|
|
30121
30220
|
navigate("/login");
|
|
30122
30221
|
};
|
|
30123
30222
|
return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
|
|
@@ -30822,8 +30921,8 @@ var init_chat2 = __esm({
|
|
|
30822
30921
|
const notificationService2 = useNotificationService();
|
|
30823
30922
|
const [selectedTheme, setSelectedTheme] = (0, import_react55.useState)(null);
|
|
30824
30923
|
const [themeLoading, setThemeLoading] = (0, import_react55.useState)(true);
|
|
30825
|
-
const token =
|
|
30826
|
-
const claims = token ?
|
|
30924
|
+
const token = authenticationService.getToken();
|
|
30925
|
+
const claims = token ? authenticationService.parseJwtClaims(token) : null;
|
|
30827
30926
|
const baseTheme = themeMap_default[selectedTheme ?? "bandit-dark"] || banditDarkTheme;
|
|
30828
30927
|
const banditTheme = (0, import_react55.useMemo)(() => {
|
|
30829
30928
|
return (0, import_styles33.createTheme)(baseTheme, {
|
|
@@ -30896,7 +30995,7 @@ var init_chat2 = __esm({
|
|
|
30896
30995
|
} = useTTS();
|
|
30897
30996
|
(0, import_react55.useEffect)(() => {
|
|
30898
30997
|
const timer = setTimeout(() => {
|
|
30899
|
-
const isAuthenticated =
|
|
30998
|
+
const isAuthenticated = authenticationService.isAuthenticated();
|
|
30900
30999
|
if (!initialized || availableVoices.length === 0) {
|
|
30901
31000
|
if (token && isAuthenticated) {
|
|
30902
31001
|
debugLogger.debug("Chat: Voices not initialized or unavailable, attempting to load from API");
|
|
@@ -30909,7 +31008,7 @@ var init_chat2 = __esm({
|
|
|
30909
31008
|
return () => clearTimeout(timer);
|
|
30910
31009
|
}, [initialized, availableVoices.length, loadVoicesFromAPI, token]);
|
|
30911
31010
|
(0, import_react55.useEffect)(() => {
|
|
30912
|
-
const isAuthenticated =
|
|
31011
|
+
const isAuthenticated = authenticationService.isAuthenticated();
|
|
30913
31012
|
if (packageSettings?.gatewayApiUrl && availableVoices.length === 0 && !initialized) {
|
|
30914
31013
|
if (token && isAuthenticated) {
|
|
30915
31014
|
debugLogger.debug("Chat: Gateway URL available and no voices loaded, attempting to load from API");
|
|
@@ -31524,7 +31623,16 @@ var init_chat2 = __esm({
|
|
|
31524
31623
|
if (rafId) cancelAnimationFrame(rafId);
|
|
31525
31624
|
};
|
|
31526
31625
|
}, [_hasHydrated, chatContainerEl, getScrollState, history.length]);
|
|
31626
|
+
const sendAckRef = (0, import_react55.useRef)(null);
|
|
31627
|
+
const settleSendAck = (0, import_react55.useCallback)((outcome) => {
|
|
31628
|
+
const ack = sendAckRef.current;
|
|
31629
|
+
if (!ack) return;
|
|
31630
|
+
sendAckRef.current = null;
|
|
31631
|
+
if (outcome.kind === "failed" && !outcome.hadOutput) ack.reject(outcome.error);
|
|
31632
|
+
else ack.resolve();
|
|
31633
|
+
}, []);
|
|
31527
31634
|
const aiProvider = useAIProvider({
|
|
31635
|
+
onTurnOutcome: settleSendAck,
|
|
31528
31636
|
overrideComponentStatus: setComponentStatus,
|
|
31529
31637
|
setIsSubmitting,
|
|
31530
31638
|
setIsStreaming,
|
|
@@ -31575,6 +31683,26 @@ var init_chat2 = __esm({
|
|
|
31575
31683
|
}, [ttsStop, isStreaming, handleStop]);
|
|
31576
31684
|
const handleSend = (0, import_react55.useCallback)(
|
|
31577
31685
|
(question, images, displayQuestion) => {
|
|
31686
|
+
sendAckRef.current?.resolve();
|
|
31687
|
+
const acknowledged = new Promise((resolve, reject) => {
|
|
31688
|
+
sendAckRef.current = { resolve, reject };
|
|
31689
|
+
});
|
|
31690
|
+
const runProvider = (systemPrompt2, providerImages2) => {
|
|
31691
|
+
aiProvider(systemPrompt2, question, providerImages2).catch((error) => {
|
|
31692
|
+
debugLogger.error("AI provider failed before streaming", {
|
|
31693
|
+
error: error instanceof Error ? error.message : String(error)
|
|
31694
|
+
});
|
|
31695
|
+
setIsStreaming(false);
|
|
31696
|
+
setResponseStarted(false);
|
|
31697
|
+
setIsSubmitting(false);
|
|
31698
|
+
setPendingMessage(null);
|
|
31699
|
+
const { conversations: convs, currentId: convId, replaceLastAnswer } = useConversationStore.getState();
|
|
31700
|
+
if (convs.find((c) => c.id === convId)?.history.at(-1)?.answer === "...") {
|
|
31701
|
+
replaceLastAnswer("_No response came back. Try sending again._", void 0, false, void 0, true);
|
|
31702
|
+
}
|
|
31703
|
+
settleSendAck({ kind: "failed", hadOutput: false, error });
|
|
31704
|
+
});
|
|
31705
|
+
};
|
|
31578
31706
|
const requestStartTime = trackRequestStart();
|
|
31579
31707
|
const questionForDisplay = displayQuestion || question;
|
|
31580
31708
|
const pendingImages = images.length > 0 ? [...images] : void 0;
|
|
@@ -31613,10 +31741,15 @@ var init_chat2 = __esm({
|
|
|
31613
31741
|
rawQuestion: question
|
|
31614
31742
|
});
|
|
31615
31743
|
const providerImages2 = pendingImages ? [...pendingImages] : [];
|
|
31616
|
-
|
|
31744
|
+
runProvider(systemPrompt, providerImages2);
|
|
31617
31745
|
}, 0);
|
|
31746
|
+
}).catch((error) => {
|
|
31747
|
+
debugLogger.error("Starting a new conversation failed", {
|
|
31748
|
+
error: error instanceof Error ? error.message : String(error)
|
|
31749
|
+
});
|
|
31750
|
+
settleSendAck({ kind: "failed", hadOutput: false, error });
|
|
31618
31751
|
});
|
|
31619
|
-
return;
|
|
31752
|
+
return acknowledged;
|
|
31620
31753
|
}
|
|
31621
31754
|
if (existing.name === "New Conversation") {
|
|
31622
31755
|
generateName(question).then((newName) => {
|
|
@@ -31664,10 +31797,12 @@ var init_chat2 = __esm({
|
|
|
31664
31797
|
}
|
|
31665
31798
|
setResponse("");
|
|
31666
31799
|
const providerImages = pendingImages ? [...pendingImages] : [];
|
|
31667
|
-
|
|
31800
|
+
runProvider(systemPrompt, providerImages);
|
|
31801
|
+
return acknowledged;
|
|
31668
31802
|
},
|
|
31669
31803
|
[
|
|
31670
31804
|
aiProvider,
|
|
31805
|
+
settleSendAck,
|
|
31671
31806
|
chatContainerRef,
|
|
31672
31807
|
generateName,
|
|
31673
31808
|
getScrollState,
|
|
@@ -31691,7 +31826,8 @@ var init_chat2 = __esm({
|
|
|
31691
31826
|
}
|
|
31692
31827
|
setInputValue("");
|
|
31693
31828
|
setPastedImages([]);
|
|
31694
|
-
handleSend(cleaned, [], cleaned)
|
|
31829
|
+
handleSend(cleaned, [], cleaned).catch(() => {
|
|
31830
|
+
});
|
|
31695
31831
|
},
|
|
31696
31832
|
[handleSend, setInputValue, setPastedImages]
|
|
31697
31833
|
);
|
|
@@ -32269,12 +32405,12 @@ var init_chat2 = __esm({
|
|
|
32269
32405
|
ossConfigured,
|
|
32270
32406
|
isOSSMode: isOSSMode(),
|
|
32271
32407
|
tier: featureFlag.getEvaluation()?.tier,
|
|
32272
|
-
hasToken:
|
|
32408
|
+
hasToken: authenticationService.isAuthenticated(),
|
|
32273
32409
|
playgroundBypassAuth,
|
|
32274
32410
|
isPlaygroundRoute,
|
|
32275
32411
|
bypassAuth
|
|
32276
32412
|
});
|
|
32277
|
-
if (!allowUnauthenticated && !bypassAuth && !
|
|
32413
|
+
if (!allowUnauthenticated && !bypassAuth && !authenticationService.isAuthenticated()) {
|
|
32278
32414
|
debugLogger.debug("User is not authenticated, redirecting to login");
|
|
32279
32415
|
return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_react_router_dom5.Navigate, { to: "/login", replace: true });
|
|
32280
32416
|
}
|
|
@@ -32310,7 +32446,7 @@ __export(index_exports, {
|
|
|
32310
32446
|
VectorDatabaseService: () => VectorDatabaseService,
|
|
32311
32447
|
VectorMigrationService: () => VectorMigrationService,
|
|
32312
32448
|
VoiceService: () => VoiceService,
|
|
32313
|
-
authenticationService: () =>
|
|
32449
|
+
authenticationService: () => authenticationService,
|
|
32314
32450
|
debugLogger: () => debugLogger,
|
|
32315
32451
|
defineCustomElement: () => defineCustomElement,
|
|
32316
32452
|
featureFlagService: () => featureFlagService,
|
|
@@ -32457,7 +32593,7 @@ var AIProviderInitService = class _AIProviderInitService {
|
|
|
32457
32593
|
type: "ollama" /* OLLAMA */,
|
|
32458
32594
|
baseUrl: settings.ollamaUrl,
|
|
32459
32595
|
tokenFactory: () => {
|
|
32460
|
-
let token =
|
|
32596
|
+
let token = authenticationService.getToken();
|
|
32461
32597
|
if (!token) {
|
|
32462
32598
|
token = localStorage.getItem("authToken");
|
|
32463
32599
|
}
|
|
@@ -32498,7 +32634,7 @@ var AIProviderInitService = class _AIProviderInitService {
|
|
|
32498
32634
|
type: "ollama" /* OLLAMA */,
|
|
32499
32635
|
baseUrl: settings.ollamaUrl || "http://localhost:11434",
|
|
32500
32636
|
tokenFactory: () => {
|
|
32501
|
-
let token =
|
|
32637
|
+
let token = authenticationService.getToken();
|
|
32502
32638
|
if (!token) {
|
|
32503
32639
|
token = localStorage.getItem("authToken");
|
|
32504
32640
|
}
|
|
@@ -32529,7 +32665,7 @@ var AIProviderInitService = class _AIProviderInitService {
|
|
|
32529
32665
|
type: "ollama" /* OLLAMA */,
|
|
32530
32666
|
baseUrl: "http://localhost:11434",
|
|
32531
32667
|
tokenFactory: () => {
|
|
32532
|
-
let token =
|
|
32668
|
+
let token = authenticationService.getToken();
|
|
32533
32669
|
if (!token) {
|
|
32534
32670
|
token = localStorage.getItem("authToken");
|
|
32535
32671
|
}
|
|
@@ -32619,7 +32755,7 @@ var AIProviderInitService = class _AIProviderInitService {
|
|
|
32619
32755
|
return config;
|
|
32620
32756
|
}
|
|
32621
32757
|
config.tokenFactory = () => {
|
|
32622
|
-
let token =
|
|
32758
|
+
let token = authenticationService.getToken();
|
|
32623
32759
|
if (!token && typeof localStorage !== "undefined") {
|
|
32624
32760
|
try {
|
|
32625
32761
|
token = localStorage.getItem("authToken");
|
|
@@ -32654,7 +32790,7 @@ init_FeatureFlagContext();
|
|
|
32654
32790
|
|
|
32655
32791
|
// src/chat-provider.css
|
|
32656
32792
|
init_style_inject();
|
|
32657
|
-
styleInject("@layer base {\n *,\n *::before,\n *::after {\n box-sizing: border-box;\n margin: 0;\n padding: 0;\n }\n
|
|
32793
|
+
styleInject("@layer base {\n *,\n *::before,\n *::after {\n box-sizing: border-box;\n margin: 0;\n padding: 0;\n }\n a {\n color: inherit;\n text-decoration: none;\n }\n}\n:root {\n --vh: 1vh;\n --input-offset: 1.5rem;\n}\n.bandit-logo-container {\n display: flex;\n height: 50vh;\n margin: auto;\n}\n.bandit-logo {\n margin: auto;\n display: flex;\n flex: 1 1 auto;\n flex-direction: column;\n align-items: center;\n width: 90vw;\n max-width: 640px;\n height: 55vh;\n background-size: cover;\n background-position: center center;\n background-repeat: no-repeat;\n transition: opacity 0.6s ease-in-out, transform 0.6s ease-in-out;\n}\n.bandit-logo-hidden {\n opacity: 0;\n transform: translateY(-10px);\n pointer-events: none;\n}\n.bandit-logo-visible {\n opacity: 1;\n transform: translateY(0);\n}\n");
|
|
32658
32794
|
|
|
32659
32795
|
// src/chat-provider.tsx
|
|
32660
32796
|
var import_react_query = require("@tanstack/react-query");
|
|
@@ -32676,11 +32812,11 @@ var ChatProvider = (props) => {
|
|
|
32676
32812
|
} catch (error) {
|
|
32677
32813
|
debugLogger.error("Failed to initialize AI provider:", { error });
|
|
32678
32814
|
}
|
|
32679
|
-
const token =
|
|
32680
|
-
if (token && !
|
|
32681
|
-
|
|
32815
|
+
const token = authenticationService.getToken();
|
|
32816
|
+
if (token && !authenticationService.isTokenExpired(token)) {
|
|
32817
|
+
authenticationService.setToken(token);
|
|
32682
32818
|
} else {
|
|
32683
|
-
|
|
32819
|
+
authenticationService.clearToken();
|
|
32684
32820
|
}
|
|
32685
32821
|
useConversationStore.getState().hydrate();
|
|
32686
32822
|
useProjectStore.getState().hydrate();
|
|
@@ -37611,7 +37747,7 @@ var useGatewayClient = () => {
|
|
|
37611
37747
|
}
|
|
37612
37748
|
return new GatewayService(
|
|
37613
37749
|
gatewayUrl,
|
|
37614
|
-
() =>
|
|
37750
|
+
() => authenticationService.getToken(),
|
|
37615
37751
|
feedbackEmail
|
|
37616
37752
|
);
|
|
37617
37753
|
}, [gatewayUrl, feedbackEmail]);
|
|
@@ -41490,7 +41626,7 @@ var buildHeaders2 = () => {
|
|
|
41490
41626
|
const headers = {
|
|
41491
41627
|
"Content-Type": "application/json"
|
|
41492
41628
|
};
|
|
41493
|
-
const token =
|
|
41629
|
+
const token = authenticationService.getToken();
|
|
41494
41630
|
if (token) {
|
|
41495
41631
|
headers.Authorization = `Bearer ${token}`;
|
|
41496
41632
|
}
|
|
@@ -44233,7 +44369,6 @@ var ProviderTab = () => {
|
|
|
44233
44369
|
usePackageSettingsStore.setState({ settings: updatedSettings });
|
|
44234
44370
|
}
|
|
44235
44371
|
setProviderConfig(applyDefaultModel(normalizedConfig));
|
|
44236
|
-
setIsProviderConfigOpen(false);
|
|
44237
44372
|
showMessage("Provider configuration saved and switched successfully!", "success");
|
|
44238
44373
|
debugLogger.info("Provider configuration saved and switched", { type: normalizedConfig.type });
|
|
44239
44374
|
} catch (error) {
|
|
@@ -44621,7 +44756,7 @@ function buildUrl3(path) {
|
|
|
44621
44756
|
}
|
|
44622
44757
|
function authHeaders2() {
|
|
44623
44758
|
const headers = { "Content-Type": "application/json" };
|
|
44624
|
-
const token =
|
|
44759
|
+
const token = authenticationService.getToken();
|
|
44625
44760
|
if (token) headers["Authorization"] = `Bearer ${token}`;
|
|
44626
44761
|
return headers;
|
|
44627
44762
|
}
|
|
@@ -45966,7 +46101,7 @@ var Management = () => {
|
|
|
45966
46101
|
let isActive = true;
|
|
45967
46102
|
const loadCapabilities = async () => {
|
|
45968
46103
|
try {
|
|
45969
|
-
const token = authToken ??
|
|
46104
|
+
const token = authToken ?? authenticationService.getToken();
|
|
45970
46105
|
const headers = {
|
|
45971
46106
|
"Content-Type": "application/json"
|
|
45972
46107
|
};
|
|
@@ -46102,7 +46237,7 @@ var Management = () => {
|
|
|
46102
46237
|
"admin",
|
|
46103
46238
|
"platform_admin"
|
|
46104
46239
|
]);
|
|
46105
|
-
const userRoles = (
|
|
46240
|
+
const userRoles = (authenticationService.parseJwtClaims(authenticationService.getToken() ?? "")?.roles ?? []).map((r) => r.toLowerCase());
|
|
46106
46241
|
const isWorkspaceAdmin = userRoles.some(
|
|
46107
46242
|
(r) => platformAdminRoles.has(r) || r.endsWith("-admin")
|
|
46108
46243
|
);
|
|
@@ -46925,7 +47060,7 @@ var useVoices = () => {
|
|
|
46925
47060
|
const gatewayApiUrl = usePackageSettingsStore((state) => state.settings?.gatewayApiUrl);
|
|
46926
47061
|
const { token } = useAuthenticationStore();
|
|
46927
47062
|
(0, import_react85.useEffect)(() => {
|
|
46928
|
-
const isAuthenticated =
|
|
47063
|
+
const isAuthenticated = authenticationService.isAuthenticated();
|
|
46929
47064
|
if (gatewayApiUrl && token && isAuthenticated && !isServiceAvailable) {
|
|
46930
47065
|
debugLogger.debug("Gateway API URL and JWT token available, loading voice models...");
|
|
46931
47066
|
loadVoicesFromAPI();
|