@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
|
@@ -1585,7 +1585,7 @@ function emitAuthTokenChanged(token) {
|
|
|
1585
1585
|
detail: { token }
|
|
1586
1586
|
}));
|
|
1587
1587
|
}
|
|
1588
|
-
var TOKEN_KEY2, AUTH_TOKEN_CHANGED_EVENT, AuthenticationService,
|
|
1588
|
+
var TOKEN_KEY2, AUTH_TOKEN_CHANGED_EVENT, AuthenticationService, authenticationService;
|
|
1589
1589
|
var init_authenticationService = __esm({
|
|
1590
1590
|
"src/services/auth/authenticationService.ts"() {
|
|
1591
1591
|
"use strict";
|
|
@@ -1638,7 +1638,7 @@ var init_authenticationService = __esm({
|
|
|
1638
1638
|
}
|
|
1639
1639
|
}
|
|
1640
1640
|
};
|
|
1641
|
-
|
|
1641
|
+
authenticationService = new AuthenticationService();
|
|
1642
1642
|
}
|
|
1643
1643
|
});
|
|
1644
1644
|
|
|
@@ -1729,7 +1729,7 @@ var init_gateway_service = __esm({
|
|
|
1729
1729
|
return;
|
|
1730
1730
|
}
|
|
1731
1731
|
try {
|
|
1732
|
-
|
|
1732
|
+
authenticationService.clearToken();
|
|
1733
1733
|
} catch {
|
|
1734
1734
|
}
|
|
1735
1735
|
if (typeof window !== "undefined" && typeof window.dispatchEvent === "function") {
|
|
@@ -3077,7 +3077,7 @@ var init_playground_provider = __esm({
|
|
|
3077
3077
|
PlaygroundProvider = class {
|
|
3078
3078
|
config;
|
|
3079
3079
|
constructor(config) {
|
|
3080
|
-
this.config = { type: "playground" /* PLAYGROUND
|
|
3080
|
+
this.config = { ...config, type: config.type ?? "playground" /* PLAYGROUND */ };
|
|
3081
3081
|
}
|
|
3082
3082
|
chat(request) {
|
|
3083
3083
|
const lastUserMessage = [...request.messages].reverse().find((m) => m.role === "user")?.content ?? "";
|
|
@@ -8140,7 +8140,7 @@ function buildUrl(path) {
|
|
|
8140
8140
|
}
|
|
8141
8141
|
function buildHeaders() {
|
|
8142
8142
|
const headers = { "Content-Type": "application/json" };
|
|
8143
|
-
const token =
|
|
8143
|
+
const token = authenticationService.getToken();
|
|
8144
8144
|
if (token) {
|
|
8145
8145
|
headers["Authorization"] = `Bearer ${token}`;
|
|
8146
8146
|
}
|
|
@@ -8288,7 +8288,7 @@ function resolveAuthIdentity(token) {
|
|
|
8288
8288
|
if (!token) {
|
|
8289
8289
|
return null;
|
|
8290
8290
|
}
|
|
8291
|
-
const claims =
|
|
8291
|
+
const claims = authenticationService.parseJwtClaims(token);
|
|
8292
8292
|
if (claims?.sub) {
|
|
8293
8293
|
return claims.sub;
|
|
8294
8294
|
}
|
|
@@ -8821,7 +8821,7 @@ var init_conversationSyncStore = __esm({
|
|
|
8821
8821
|
async initialize() {
|
|
8822
8822
|
ensureTrackersInitialized();
|
|
8823
8823
|
const gatewayUrl = usePackageSettingsStore.getState().settings?.gatewayApiUrl;
|
|
8824
|
-
const token =
|
|
8824
|
+
const token = authenticationService.getToken();
|
|
8825
8825
|
const tokenIdentity = resolveAuthIdentity(token);
|
|
8826
8826
|
const current = get();
|
|
8827
8827
|
const storedIdentity = getStoredSyncIdentity();
|
|
@@ -8947,10 +8947,10 @@ var init_conversationSyncStore = __esm({
|
|
|
8947
8947
|
});
|
|
8948
8948
|
set({
|
|
8949
8949
|
hasLoadedPreference: true,
|
|
8950
|
-
initializedForToken:
|
|
8951
|
-
initializedForIdentity: resolveAuthIdentity(
|
|
8950
|
+
initializedForToken: authenticationService.getToken(),
|
|
8951
|
+
initializedForIdentity: resolveAuthIdentity(authenticationService.getToken())
|
|
8952
8952
|
});
|
|
8953
|
-
setStoredSyncIdentity(resolveAuthIdentity(
|
|
8953
|
+
setStoredSyncIdentity(resolveAuthIdentity(authenticationService.getToken()));
|
|
8954
8954
|
if (enabled) {
|
|
8955
8955
|
set({ hasCompletedInitialUpload: false });
|
|
8956
8956
|
}
|
|
@@ -8990,10 +8990,10 @@ var init_conversationSyncStore = __esm({
|
|
|
8990
8990
|
});
|
|
8991
8991
|
set({
|
|
8992
8992
|
hasLoadedPreference: true,
|
|
8993
|
-
initializedForToken:
|
|
8994
|
-
initializedForIdentity: resolveAuthIdentity(
|
|
8993
|
+
initializedForToken: authenticationService.getToken(),
|
|
8994
|
+
initializedForIdentity: resolveAuthIdentity(authenticationService.getToken())
|
|
8995
8995
|
});
|
|
8996
|
-
setStoredSyncIdentity(resolveAuthIdentity(
|
|
8996
|
+
setStoredSyncIdentity(resolveAuthIdentity(authenticationService.getToken()));
|
|
8997
8997
|
if (preference.syncEnabled && preference.isAdvancedVectorFeaturesEnabled) {
|
|
8998
8998
|
await get().runSync({ force: true });
|
|
8999
8999
|
}
|
|
@@ -9033,7 +9033,7 @@ var init_conversationSyncStore = __esm({
|
|
|
9033
9033
|
debugLogger.error("conversationSyncStore: runSync error - missing gateway URL");
|
|
9034
9034
|
return;
|
|
9035
9035
|
}
|
|
9036
|
-
const token =
|
|
9036
|
+
const token = authenticationService.getToken();
|
|
9037
9037
|
if (!token) {
|
|
9038
9038
|
set({ status: "error", lastError: "Authentication required to sync conversations." });
|
|
9039
9039
|
debugLogger.error("conversationSyncStore: runSync error - missing auth token");
|
|
@@ -9966,7 +9966,7 @@ var init_useKnowledgeStore = __esm({
|
|
|
9966
9966
|
init_indexedDBService();
|
|
9967
9967
|
import_uuid5 = require("uuid");
|
|
9968
9968
|
import_mammoth = __toESM(require("mammoth"));
|
|
9969
|
-
pdfjsLib = __toESM(require("pdfjs-dist/legacy/build/pdf"));
|
|
9969
|
+
pdfjsLib = __toESM(require("pdfjs-dist/legacy/build/pdf.mjs"));
|
|
9970
9970
|
init_embeddingService();
|
|
9971
9971
|
init_debugLogger();
|
|
9972
9972
|
init_vectorDatabaseService();
|
|
@@ -11177,7 +11177,7 @@ var init_knowledge_file_modal = __esm({
|
|
|
11177
11177
|
import_material7 = require("@mui/material");
|
|
11178
11178
|
init_useVectorStore();
|
|
11179
11179
|
init_packageSettingsStore();
|
|
11180
|
-
pdfjsLib2 = __toESM(require("pdfjs-dist/legacy/build/pdf"));
|
|
11180
|
+
pdfjsLib2 = __toESM(require("pdfjs-dist/legacy/build/pdf.mjs"));
|
|
11181
11181
|
init_lowlight();
|
|
11182
11182
|
init_markdownRendering();
|
|
11183
11183
|
init_debugLogger();
|
|
@@ -11968,7 +11968,7 @@ var init_voiceService = __esm({
|
|
|
11968
11968
|
debugLogger.error("Gateway API URL not configured");
|
|
11969
11969
|
throw new Error("Gateway API URL not configured");
|
|
11970
11970
|
}
|
|
11971
|
-
const token =
|
|
11971
|
+
const token = authenticationService.getToken();
|
|
11972
11972
|
if (!token) {
|
|
11973
11973
|
debugLogger.warn("No JWT token available - skipping voice models fetch");
|
|
11974
11974
|
const emptyModels = {
|
|
@@ -11978,7 +11978,7 @@ var init_voiceService = __esm({
|
|
|
11978
11978
|
};
|
|
11979
11979
|
return emptyModels;
|
|
11980
11980
|
}
|
|
11981
|
-
if (
|
|
11981
|
+
if (authenticationService.isTokenExpired(token)) {
|
|
11982
11982
|
debugLogger.warn("JWT token is expired - skipping voice models fetch");
|
|
11983
11983
|
const emptyModels = {
|
|
11984
11984
|
models: [],
|
|
@@ -12067,7 +12067,7 @@ var init_tts_client = __esm({
|
|
|
12067
12067
|
init_packageSettingsStore();
|
|
12068
12068
|
init_debugLogger();
|
|
12069
12069
|
getOrAppendAuthHeader = (existing = {}) => {
|
|
12070
|
-
const token =
|
|
12070
|
+
const token = authenticationService.getToken();
|
|
12071
12071
|
if (token) {
|
|
12072
12072
|
existing["Authorization"] = `Bearer ${token}`;
|
|
12073
12073
|
return existing;
|
|
@@ -12758,8 +12758,8 @@ var init_ai_response_action_bar = __esm({
|
|
|
12758
12758
|
const { preferences } = usePreferencesStore();
|
|
12759
12759
|
const { settings: packageSettings } = usePackageSettingsStore();
|
|
12760
12760
|
(0, import_react14.useEffect)(() => {
|
|
12761
|
-
const isAuthenticated =
|
|
12762
|
-
const token =
|
|
12761
|
+
const isAuthenticated = authenticationService.isAuthenticated();
|
|
12762
|
+
const token = authenticationService.getToken();
|
|
12763
12763
|
if (!initialized || availableVoices.length === 0) {
|
|
12764
12764
|
if (token && isAuthenticated) {
|
|
12765
12765
|
debugLogger.debug("AI Action Bar: Voices not initialized or unavailable, attempting to load from API");
|
|
@@ -13603,11 +13603,12 @@ ${sourcesMarkdownList.join("\n")}`;
|
|
|
13603
13603
|
tr({ children, node: _node, ...tableRowProps }) {
|
|
13604
13604
|
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_material9.TableRow, { ...tableRowProps, children });
|
|
13605
13605
|
},
|
|
13606
|
-
th({ children, node: _node, ...tableCellProps }) {
|
|
13606
|
+
th({ children, node: _node, align, ...tableCellProps }) {
|
|
13607
13607
|
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
13608
13608
|
import_material9.TableCell,
|
|
13609
13609
|
{
|
|
13610
13610
|
...tableCellProps,
|
|
13611
|
+
align: align === "char" ? void 0 : align,
|
|
13611
13612
|
sx: {
|
|
13612
13613
|
fontWeight: "bold",
|
|
13613
13614
|
color: theme.palette.text.primary,
|
|
@@ -13620,11 +13621,12 @@ ${sourcesMarkdownList.join("\n")}`;
|
|
|
13620
13621
|
}
|
|
13621
13622
|
);
|
|
13622
13623
|
},
|
|
13623
|
-
td({ children, node: _node, ...tableCellProps }) {
|
|
13624
|
+
td({ children, node: _node, align, ...tableCellProps }) {
|
|
13624
13625
|
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
13625
13626
|
import_material9.TableCell,
|
|
13626
13627
|
{
|
|
13627
13628
|
...tableCellProps,
|
|
13629
|
+
align: align === "char" ? void 0 : align,
|
|
13628
13630
|
sx: {
|
|
13629
13631
|
color: theme.palette.text.primary,
|
|
13630
13632
|
fontSize: "0.875rem",
|
|
@@ -14701,7 +14703,7 @@ var init_memory_modal = __esm({
|
|
|
14701
14703
|
color: (0, import_styles3.alpha)(theme.palette.text.secondary, 0.7),
|
|
14702
14704
|
maxWidth: 280
|
|
14703
14705
|
}, 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." })
|
|
14704
|
-
] }) : filteredMemories.map((memory) => {
|
|
14706
|
+
] }) : filteredMemories.map((memory, memoryIndex) => {
|
|
14705
14707
|
const isSelected = selectedIds.includes(memory.id);
|
|
14706
14708
|
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_react17.default.Fragment, { children: [
|
|
14707
14709
|
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_material10.List, { sx: { listStyle: "none", pl: 0, m: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
@@ -14901,7 +14903,7 @@ var init_memory_modal = __esm({
|
|
|
14901
14903
|
]
|
|
14902
14904
|
}
|
|
14903
14905
|
) }),
|
|
14904
|
-
|
|
14906
|
+
memoryIndex < filteredMemories.length - 1 && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_material10.Divider, { sx: { bgcolor: (0, import_styles3.alpha)(appBar.border, 0.5), my: 0.5 } })
|
|
14905
14907
|
] }, memory.id);
|
|
14906
14908
|
})
|
|
14907
14909
|
}
|
|
@@ -15613,7 +15615,7 @@ var init_FeedbackModal = __esm({
|
|
|
15613
15615
|
}
|
|
15614
15616
|
const gatewayService = new GatewayService(
|
|
15615
15617
|
gatewayUrl,
|
|
15616
|
-
() =>
|
|
15618
|
+
() => authenticationService.getToken(),
|
|
15617
15619
|
feedbackEmail || settings?.feedbackEmail
|
|
15618
15620
|
);
|
|
15619
15621
|
const feedbackRequest = {
|
|
@@ -19242,7 +19244,7 @@ ${listMarkdown}`;
|
|
|
19242
19244
|
children
|
|
19243
19245
|
}
|
|
19244
19246
|
);
|
|
19245
|
-
const CodeRenderer = ({
|
|
19247
|
+
const CodeRenderer = ({ node: _node, className, children, ...props }) => {
|
|
19246
19248
|
const match = /language-([\w-]+)/.exec(className || "");
|
|
19247
19249
|
const requestedLanguage = match?.[1]?.toLowerCase() ?? "";
|
|
19248
19250
|
const codeText = String(children).replace(/\n$/, "");
|
|
@@ -19576,7 +19578,7 @@ var init_mcpServersService = __esm({
|
|
|
19576
19578
|
};
|
|
19577
19579
|
authHeaders2 = () => {
|
|
19578
19580
|
const headers = { "Content-Type": "application/json" };
|
|
19579
|
-
const token =
|
|
19581
|
+
const token = authenticationService.getToken();
|
|
19580
19582
|
if (token) headers["Authorization"] = `Bearer ${token}`;
|
|
19581
19583
|
return headers;
|
|
19582
19584
|
};
|
|
@@ -20773,7 +20775,7 @@ var init_engineStore = __esm({
|
|
|
20773
20775
|
}
|
|
20774
20776
|
try {
|
|
20775
20777
|
const headers = { "Content-Type": "application/json" };
|
|
20776
|
-
const token =
|
|
20778
|
+
const token = authenticationService.getToken();
|
|
20777
20779
|
if (token) headers["Authorization"] = `Bearer ${token}`;
|
|
20778
20780
|
const res = await fetch(`${base}/models`, { headers });
|
|
20779
20781
|
const data = await res.json();
|
|
@@ -21092,7 +21094,7 @@ var init_stt_client = __esm({
|
|
|
21092
21094
|
filename,
|
|
21093
21095
|
url: `${gatewayUrl}/stt/transcribe`
|
|
21094
21096
|
});
|
|
21095
|
-
const token =
|
|
21097
|
+
const token = authenticationService.getToken();
|
|
21096
21098
|
const response = await fetch(`${gatewayUrl}/stt/transcribe`, {
|
|
21097
21099
|
method: "POST",
|
|
21098
21100
|
headers: {
|
|
@@ -21212,6 +21214,109 @@ var init_transcriber = __esm({
|
|
|
21212
21214
|
}
|
|
21213
21215
|
});
|
|
21214
21216
|
|
|
21217
|
+
// src/chat/composer-submission.ts
|
|
21218
|
+
var isPromiseLike, awaitAcceptance, buildSubmission, isImeComposing;
|
|
21219
|
+
var init_composer_submission = __esm({
|
|
21220
|
+
"src/chat/composer-submission.ts"() {
|
|
21221
|
+
"use strict";
|
|
21222
|
+
isPromiseLike = (value) => !!value && typeof value.then === "function";
|
|
21223
|
+
awaitAcceptance = async (ack) => {
|
|
21224
|
+
if (ack === false) return false;
|
|
21225
|
+
if (!isPromiseLike(ack)) return true;
|
|
21226
|
+
try {
|
|
21227
|
+
return await ack !== false;
|
|
21228
|
+
} catch {
|
|
21229
|
+
return false;
|
|
21230
|
+
}
|
|
21231
|
+
};
|
|
21232
|
+
buildSubmission = (text, images, documents) => {
|
|
21233
|
+
const typed = text.trim();
|
|
21234
|
+
const base = typed || (images.length === 1 ? "[\u{1F4F7} You attached an image]" : images.length > 1 ? `[\u{1F4F7} You attached ${images.length} images]` : "");
|
|
21235
|
+
const fileSummary = documents.length > 0 ? `[\u{1F4CE} Attached ${documents.length} file${documents.length > 1 ? "s" : ""}: ${documents.map((d) => d.fileName).join(", ")}]` : "";
|
|
21236
|
+
const displayQuestion = [base || (fileSummary ? "[\u{1F4E4} You submitted content without text]" : ""), fileSummary].filter(Boolean).join("\n\n");
|
|
21237
|
+
const prompt = [text, ...documents.map((d) => d.block)].filter(Boolean).join("\n\n");
|
|
21238
|
+
return { prompt, images: [...images], displayQuestion };
|
|
21239
|
+
};
|
|
21240
|
+
isImeComposing = (event) => event.nativeEvent?.isComposing === true || event.keyCode === 229;
|
|
21241
|
+
}
|
|
21242
|
+
});
|
|
21243
|
+
|
|
21244
|
+
// src/chat/document-import.ts
|
|
21245
|
+
var CODE_EXTENSIONS, TEXT_EXTENSIONS, isCodeFileName, isPlainTextFile, CONTROL_CHARS, INVISIBLE_FORMATTING, stripInvisible, neutralizeRoleMarkers, prepareDocumentText, formatDocumentBlock, readText, readPdfText, readDocument;
|
|
21246
|
+
var init_document_import = __esm({
|
|
21247
|
+
"src/chat/document-import.ts"() {
|
|
21248
|
+
"use strict";
|
|
21249
|
+
CODE_EXTENSIONS = [".js", ".ts", ".tsx", ".json", ".py", ".java", ".c", ".cpp", ".cs"];
|
|
21250
|
+
TEXT_EXTENSIONS = [".md", ".txt", ...CODE_EXTENSIONS];
|
|
21251
|
+
isCodeFileName = (name) => {
|
|
21252
|
+
const lower = name.toLowerCase();
|
|
21253
|
+
return CODE_EXTENSIONS.some((ext) => lower.endsWith(ext));
|
|
21254
|
+
};
|
|
21255
|
+
isPlainTextFile = (name, mimeType = "") => mimeType.startsWith("text/") || TEXT_EXTENSIONS.some((ext) => name.toLowerCase().endsWith(ext));
|
|
21256
|
+
CONTROL_CHARS = /[\u0000-\u0008\u000B\u000C\u000E-\u001F\u007F-\u009F]/g;
|
|
21257
|
+
INVISIBLE_FORMATTING = /[\u202A-\u202E\u2066-\u2069\u200B\u2060\uFEFF]/g;
|
|
21258
|
+
stripInvisible = (text) => text.normalize("NFC").replace(CONTROL_CHARS, "").replace(INVISIBLE_FORMATTING, "");
|
|
21259
|
+
neutralizeRoleMarkers = (text) => text.replace(/<\s*\/?\s*script\b[^>]*>/gi, "").replace(/(^|\n)([ \t]*)\/?(system|assistant|user)\s*:/gi, "$1$2[removed-role]");
|
|
21260
|
+
prepareDocumentText = (text, fileName) => {
|
|
21261
|
+
const visible = stripInvisible(text);
|
|
21262
|
+
return (isCodeFileName(fileName) ? visible : neutralizeRoleMarkers(visible)).trim();
|
|
21263
|
+
};
|
|
21264
|
+
formatDocumentBlock = (fileName, text) => `\u{1F4C4} ${fileName}
|
|
21265
|
+
${prepareDocumentText(text, fileName)}`;
|
|
21266
|
+
readText = (file) => typeof file.text === "function" ? file.text() : new Promise((resolve, reject) => {
|
|
21267
|
+
const reader = new FileReader();
|
|
21268
|
+
reader.onload = () => resolve(String(reader.result ?? ""));
|
|
21269
|
+
reader.onerror = () => reject(reader.error ?? new Error("It couldn't be read."));
|
|
21270
|
+
reader.readAsText(file);
|
|
21271
|
+
});
|
|
21272
|
+
readPdfText = async (file, maxPages = 10) => {
|
|
21273
|
+
const pdfjsLib3 = await import("pdfjs-dist/legacy/build/pdf.mjs");
|
|
21274
|
+
pdfjsLib3.GlobalWorkerOptions.workerSrc = "https://cdn.burtson.ai/scripts/pdf.worker.js";
|
|
21275
|
+
const pdf = await pdfjsLib3.getDocument({ data: await file.arrayBuffer() }).promise;
|
|
21276
|
+
const pages = await Promise.all(
|
|
21277
|
+
Array.from({ length: Math.min(pdf.numPages, maxPages) }, async (_, i) => {
|
|
21278
|
+
try {
|
|
21279
|
+
const page = await pdf.getPage(i + 1);
|
|
21280
|
+
const content = await page.getTextContent();
|
|
21281
|
+
return content.items.map((item) => typeof item?.str === "string" ? item.str : "").join(" ");
|
|
21282
|
+
} catch {
|
|
21283
|
+
return "";
|
|
21284
|
+
}
|
|
21285
|
+
})
|
|
21286
|
+
);
|
|
21287
|
+
return pages.join("\n\n");
|
|
21288
|
+
};
|
|
21289
|
+
readDocument = async (file) => {
|
|
21290
|
+
const name = file.name.toLowerCase();
|
|
21291
|
+
try {
|
|
21292
|
+
let text;
|
|
21293
|
+
if (isPlainTextFile(name, file.type)) {
|
|
21294
|
+
text = await readText(file);
|
|
21295
|
+
} else if (name.endsWith(".docx")) {
|
|
21296
|
+
const mammoth2 = await import("mammoth");
|
|
21297
|
+
text = (await mammoth2.extractRawText({ arrayBuffer: await file.arrayBuffer() })).value;
|
|
21298
|
+
} else if (name.endsWith(".pdf")) {
|
|
21299
|
+
text = await readPdfText(file);
|
|
21300
|
+
} else {
|
|
21301
|
+
return { ok: false, fileName: file.name, reason: "This file type can't be read yet." };
|
|
21302
|
+
}
|
|
21303
|
+
const block = formatDocumentBlock(file.name, text);
|
|
21304
|
+
if (block === `\u{1F4C4} ${file.name}
|
|
21305
|
+
`) {
|
|
21306
|
+
return { ok: false, fileName: file.name, reason: "No readable text was found in it." };
|
|
21307
|
+
}
|
|
21308
|
+
return { ok: true, fileName: file.name, block };
|
|
21309
|
+
} catch (error) {
|
|
21310
|
+
return {
|
|
21311
|
+
ok: false,
|
|
21312
|
+
fileName: file.name,
|
|
21313
|
+
reason: error instanceof Error && error.message ? error.message : "It couldn't be read."
|
|
21314
|
+
};
|
|
21315
|
+
}
|
|
21316
|
+
};
|
|
21317
|
+
}
|
|
21318
|
+
});
|
|
21319
|
+
|
|
21215
21320
|
// src/store/voiceModeStore.ts
|
|
21216
21321
|
var import_zustand16, useVoiceModeStore;
|
|
21217
21322
|
var init_voiceModeStore = __esm({
|
|
@@ -21266,6 +21371,8 @@ var init_chat_input = __esm({
|
|
|
21266
21371
|
init_packageSettingsStore();
|
|
21267
21372
|
init_transcriber();
|
|
21268
21373
|
init_memory_modal();
|
|
21374
|
+
init_composer_submission();
|
|
21375
|
+
init_document_import();
|
|
21269
21376
|
import_styles24 = require("@mui/material/styles");
|
|
21270
21377
|
init_debugLogger();
|
|
21271
21378
|
init_brandingService();
|
|
@@ -21434,102 +21541,60 @@ var init_chat_input = __esm({
|
|
|
21434
21541
|
const removeImage = (index) => {
|
|
21435
21542
|
setPastedImages((prev) => prev.filter((_, i) => i !== index));
|
|
21436
21543
|
};
|
|
21544
|
+
const latestDraftRef = (0, import_react53.useRef)({ text: inputValue, images: pastedImages, files: fileInputs });
|
|
21545
|
+
latestDraftRef.current = { text: inputValue, images: pastedImages, files: fileInputs };
|
|
21546
|
+
const submittingRef = (0, import_react53.useRef)(false);
|
|
21547
|
+
const [sendError, setSendError] = (0, import_react53.useState)(null);
|
|
21437
21548
|
const handleSubmit = async () => {
|
|
21438
|
-
if (
|
|
21439
|
-
|
|
21440
|
-
|
|
21441
|
-
const
|
|
21442
|
-
|
|
21443
|
-
|
|
21444
|
-
|
|
21445
|
-
|
|
21446
|
-
|
|
21447
|
-
|
|
21448
|
-
|
|
21449
|
-
|
|
21450
|
-
|
|
21451
|
-
|
|
21452
|
-
|
|
21453
|
-
|
|
21454
|
-
|
|
21455
|
-
|
|
21456
|
-
|
|
21457
|
-
|
|
21458
|
-
|
|
21459
|
-
|
|
21460
|
-
|
|
21461
|
-
|
|
21462
|
-
|
|
21463
|
-
|
|
21464
|
-
|
|
21465
|
-
|
|
21466
|
-
|
|
21467
|
-
|
|
21468
|
-
|
|
21469
|
-
|
|
21470
|
-
|
|
21471
|
-
|
|
21472
|
-
|
|
21473
|
-
|
|
21474
|
-
|
|
21475
|
-
|
|
21476
|
-
Array.from({ length: maxPages }, async (_, i) => {
|
|
21477
|
-
try {
|
|
21478
|
-
const page = await pdf.getPage(i + 1);
|
|
21479
|
-
const content = await page.getTextContent();
|
|
21480
|
-
return content.items.map((item) => {
|
|
21481
|
-
if (item && typeof item === "object" && "str" in item && typeof item.str === "string") {
|
|
21482
|
-
return item.str;
|
|
21483
|
-
}
|
|
21484
|
-
return "";
|
|
21485
|
-
}).join(" ");
|
|
21486
|
-
} catch (err) {
|
|
21487
|
-
debugLogger.error(`Failed to read page ${i + 1}`, { error: err });
|
|
21488
|
-
return "";
|
|
21489
|
-
}
|
|
21490
|
-
})
|
|
21491
|
-
);
|
|
21492
|
-
const joined = pages.join("\n\n");
|
|
21493
|
-
debugLogger.info("Extracted PDF content", { contentPreview: joined.slice(0, 500) });
|
|
21494
|
-
return `\u{1F4C4} ${file.name}
|
|
21495
|
-
${sanitize(
|
|
21496
|
-
escapePromptInjection(joined),
|
|
21497
|
-
file.name
|
|
21498
|
-
)}`;
|
|
21499
|
-
} catch (error) {
|
|
21500
|
-
debugLogger.error("PDF load failed", {
|
|
21501
|
-
error: error instanceof Error ? error.message : String(error),
|
|
21502
|
-
fileName: file.name
|
|
21503
|
-
});
|
|
21504
|
-
return "";
|
|
21505
|
-
}
|
|
21549
|
+
if (submittingRef.current) return;
|
|
21550
|
+
if (inputValue.trim() === "" && pastedImages.length === 0 && fileInputs.length === 0) return;
|
|
21551
|
+
submittingRef.current = true;
|
|
21552
|
+
const draft = { text: inputValue, images: [...pastedImages], files: [...fileInputs] };
|
|
21553
|
+
try {
|
|
21554
|
+
const reads = await Promise.all(draft.files.map(readDocument));
|
|
21555
|
+
const failed = reads.filter((r) => !r.ok);
|
|
21556
|
+
if (failed.length > 0) {
|
|
21557
|
+
setSendError(
|
|
21558
|
+
failed.map((f) => `Couldn't attach ${f.fileName}: ${f.reason}`).join(" ")
|
|
21559
|
+
);
|
|
21560
|
+
return;
|
|
21561
|
+
}
|
|
21562
|
+
const documents = reads.filter((r) => r.ok);
|
|
21563
|
+
const submission = buildSubmission(draft.text, draft.images, documents);
|
|
21564
|
+
debugLogger.debug("Composer submission", {
|
|
21565
|
+
documents: documents.map((d) => d.fileName),
|
|
21566
|
+
promptLength: submission.prompt.length
|
|
21567
|
+
});
|
|
21568
|
+
setSendError(null);
|
|
21569
|
+
setInputValue("");
|
|
21570
|
+
setPastedImages([]);
|
|
21571
|
+
setFileInputs([]);
|
|
21572
|
+
if (fileInputRef.current) fileInputRef.current.value = "";
|
|
21573
|
+
inputRef.current?.blur();
|
|
21574
|
+
const accepted = await awaitAcceptance(
|
|
21575
|
+
onSend(submission.prompt, submission.images, submission.displayQuestion)
|
|
21576
|
+
);
|
|
21577
|
+
if (!accepted) {
|
|
21578
|
+
const now = latestDraftRef.current;
|
|
21579
|
+
const untouched = now.text.trim() === "" && now.images.length === 0 && now.files.length === 0;
|
|
21580
|
+
if (untouched) {
|
|
21581
|
+
setInputValue(draft.text);
|
|
21582
|
+
setPastedImages(draft.images);
|
|
21583
|
+
setFileInputs(draft.files);
|
|
21584
|
+
setSendError("Your message wasn't sent. It's back in the box so you can try again.");
|
|
21585
|
+
} else {
|
|
21586
|
+
setSendError("Your last message wasn't sent.");
|
|
21506
21587
|
}
|
|
21507
|
-
return "";
|
|
21508
|
-
} catch {
|
|
21509
|
-
return "";
|
|
21510
21588
|
}
|
|
21511
|
-
}
|
|
21512
|
-
|
|
21513
|
-
|
|
21514
|
-
const fileContent = fileTexts.filter(Boolean).join("\n\n");
|
|
21515
|
-
const tempQuestionBase = inputValue.trim() || (tempImages.length === 1 ? "[\u{1F4F7} You attached an image]" : tempImages.length > 1 ? `[\u{1F4F7} You attached ${tempImages.length} images]` : "");
|
|
21516
|
-
const fileDisplaySummary = fileInputs.length > 0 ? `[\u{1F4CE} Attached ${fileInputs.length} file${fileInputs.length > 1 ? "s" : ""}: ${fileInputs.map((f) => f.name).join(", ")}]` : "";
|
|
21517
|
-
const displayQuestion = [
|
|
21518
|
-
tempQuestionBase || (fileDisplaySummary ? "[\u{1F4E4} You submitted content without text]" : ""),
|
|
21519
|
-
fileDisplaySummary
|
|
21520
|
-
].filter(Boolean).join("\n\n");
|
|
21521
|
-
const fullPrompt = [inputValue, fileContent].filter(Boolean).join("\n\n");
|
|
21522
|
-
setInputValue("");
|
|
21523
|
-
setPastedImages([]);
|
|
21524
|
-
setFileInputs([]);
|
|
21525
|
-
onSend(fullPrompt, tempImages, displayQuestion);
|
|
21526
|
-
inputRef.current?.blur();
|
|
21527
|
-
fileInputRef.current.value = "";
|
|
21589
|
+
} finally {
|
|
21590
|
+
submittingRef.current = false;
|
|
21591
|
+
}
|
|
21528
21592
|
};
|
|
21529
21593
|
const handleKeyPress = (e) => {
|
|
21594
|
+
if (isImeComposing(e)) return;
|
|
21530
21595
|
if (e.key === "Enter" && !e.shiftKey) {
|
|
21531
21596
|
e.preventDefault();
|
|
21532
|
-
handleSubmit();
|
|
21597
|
+
void handleSubmit();
|
|
21533
21598
|
}
|
|
21534
21599
|
};
|
|
21535
21600
|
const handleTranscriptionCompleted = (transcribed) => {
|
|
@@ -21647,6 +21712,15 @@ ${sanitize(
|
|
|
21647
21712
|
gap: isMobile ? compactMobile ? 0.75 : 1 : 0.5
|
|
21648
21713
|
},
|
|
21649
21714
|
children: [
|
|
21715
|
+
sendError && /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
21716
|
+
import_material40.Typography,
|
|
21717
|
+
{
|
|
21718
|
+
role: "alert",
|
|
21719
|
+
variant: "caption",
|
|
21720
|
+
sx: { color: theme.palette.error.main, px: 0.5, pt: isMobile ? 0 : 0.5 },
|
|
21721
|
+
children: sendError
|
|
21722
|
+
}
|
|
21723
|
+
),
|
|
21650
21724
|
/* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(
|
|
21651
21725
|
import_material40.Box,
|
|
21652
21726
|
{
|
|
@@ -21692,7 +21766,10 @@ ${sanitize(
|
|
|
21692
21766
|
import_material40.IconButton,
|
|
21693
21767
|
{
|
|
21694
21768
|
size: "small",
|
|
21695
|
-
onClick: () =>
|
|
21769
|
+
onClick: () => {
|
|
21770
|
+
setSendError(null);
|
|
21771
|
+
setFileInputs((prev) => prev.filter((_, i) => i !== idx));
|
|
21772
|
+
},
|
|
21696
21773
|
sx: { ml: 0.5, color: theme.palette.mode === "dark" ? "#aaa" : "#444" },
|
|
21697
21774
|
children: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(CloseIcon, { sx: { fontSize: 14 } })
|
|
21698
21775
|
}
|
|
@@ -22700,7 +22777,7 @@ function syncTelemetry() {
|
|
|
22700
22777
|
const settings = usePackageSettingsStore.getState().settings;
|
|
22701
22778
|
const cfg = resolveTelemetryConfig({
|
|
22702
22779
|
telemetry: settings?.telemetry,
|
|
22703
|
-
banditApiKey:
|
|
22780
|
+
banditApiKey: authenticationService.getToken() ?? void 0
|
|
22704
22781
|
});
|
|
22705
22782
|
active = cfg ? new TelemetryExporter(cfg) : null;
|
|
22706
22783
|
} catch {
|
|
@@ -23351,7 +23428,7 @@ var init_mcpService = __esm({
|
|
|
23351
23428
|
}
|
|
23352
23429
|
if (tool.mcpServerId) {
|
|
23353
23430
|
const base2 = settings.gatewayApiUrl.replace(/\/$/, "");
|
|
23354
|
-
const token2 =
|
|
23431
|
+
const token2 = authenticationService.getToken();
|
|
23355
23432
|
const controller2 = new AbortController();
|
|
23356
23433
|
const timeoutId2 = setTimeout(() => controller2.abort(), 3e4);
|
|
23357
23434
|
try {
|
|
@@ -23398,7 +23475,7 @@ var init_mcpService = __esm({
|
|
|
23398
23475
|
"Content-Type": "application/json"
|
|
23399
23476
|
}
|
|
23400
23477
|
};
|
|
23401
|
-
const token =
|
|
23478
|
+
const token = authenticationService.getToken();
|
|
23402
23479
|
if (token) {
|
|
23403
23480
|
requestOptions.headers = {
|
|
23404
23481
|
...requestOptions.headers,
|
|
@@ -23498,6 +23575,7 @@ var init_useAIProvider = __esm({
|
|
|
23498
23575
|
"src/chat/hooks/useAIProvider.tsx"() {
|
|
23499
23576
|
"use strict";
|
|
23500
23577
|
init_debugLogger();
|
|
23578
|
+
init_authenticationService();
|
|
23501
23579
|
import_react58 = require("react");
|
|
23502
23580
|
init_knowledgeStore();
|
|
23503
23581
|
init_aiProviderStore();
|
|
@@ -23799,8 +23877,11 @@ var init_useAIProvider = __esm({
|
|
|
23799
23877
|
history,
|
|
23800
23878
|
addHistory,
|
|
23801
23879
|
inputRef,
|
|
23802
|
-
onError
|
|
23880
|
+
onError,
|
|
23881
|
+
onTurnOutcome
|
|
23803
23882
|
}) => {
|
|
23883
|
+
const onTurnOutcomeRef = (0, import_react58.useRef)(onTurnOutcome);
|
|
23884
|
+
onTurnOutcomeRef.current = onTurnOutcome;
|
|
23804
23885
|
const currentSubRef = (0, import_react58.useRef)(null);
|
|
23805
23886
|
const lastPartialRef = (0, import_react58.useRef)({
|
|
23806
23887
|
text: "",
|
|
@@ -23846,10 +23927,14 @@ var init_useAIProvider = __esm({
|
|
|
23846
23927
|
};
|
|
23847
23928
|
const runAIProvider = (0, import_react58.useCallback)(
|
|
23848
23929
|
async (systemPrompt, question, images) => {
|
|
23930
|
+
let turnHadOutput = false;
|
|
23931
|
+
const reportOutcome = (outcome) => onTurnOutcomeRef.current?.(outcome);
|
|
23849
23932
|
if (!provider) {
|
|
23850
23933
|
debugLogger.error("No AI provider configured");
|
|
23851
23934
|
overrideComponentStatus("Error");
|
|
23852
|
-
|
|
23935
|
+
const error = new Error("No AI provider configured");
|
|
23936
|
+
if (onError) onError(error);
|
|
23937
|
+
reportOutcome({ kind: "failed", hadOutput: false, error });
|
|
23853
23938
|
return;
|
|
23854
23939
|
}
|
|
23855
23940
|
const userPreferences = preferences;
|
|
@@ -24003,7 +24088,7 @@ Use this information to personalize your responses whenever relevant.` : "";
|
|
|
24003
24088
|
s3Url: resolvedId,
|
|
24004
24089
|
isUserContent: result.isUserContent,
|
|
24005
24090
|
isTeamContent: result.isTeamContent,
|
|
24006
|
-
contentSource: result.contentSource,
|
|
24091
|
+
contentSource: result.contentSource === "user" || result.contentSource === "team" ? result.contentSource : void 0,
|
|
24007
24092
|
originalFileName: result.originalFileName || result.filename || result.name,
|
|
24008
24093
|
// Preserve original data for downstream checks (e.g. vector modal detection)
|
|
24009
24094
|
_vectorResult: result
|
|
@@ -24358,6 +24443,10 @@ ${protocol}`;
|
|
|
24358
24443
|
const sub = stream.subscribe({
|
|
24359
24444
|
next: (data) => {
|
|
24360
24445
|
if (!data?.message?.content && !data?.message?.tool_calls) return;
|
|
24446
|
+
if (!turnHadOutput) {
|
|
24447
|
+
turnHadOutput = true;
|
|
24448
|
+
reportOutcome({ kind: "output" });
|
|
24449
|
+
}
|
|
24361
24450
|
if (Array.isArray(data.message.tool_calls) && data.message.tool_calls.length > 0) {
|
|
24362
24451
|
nativeToolCalls.push(...data.message.tool_calls);
|
|
24363
24452
|
sawToolBlock = true;
|
|
@@ -24392,13 +24481,14 @@ ${protocol}`;
|
|
|
24392
24481
|
},
|
|
24393
24482
|
error: (err) => {
|
|
24394
24483
|
debugLogger.error("Stream error:", err);
|
|
24484
|
+
reportOutcome({ kind: "failed", hadOutput: turnHadOutput, error: err });
|
|
24395
24485
|
stopWorking();
|
|
24396
24486
|
overrideComponentStatus("Idle");
|
|
24397
24487
|
setIsSubmitting(false);
|
|
24398
24488
|
setIsStreaming(false);
|
|
24399
24489
|
if (/lifetime validation|token.*(expired|invalid)|unauthorized|\b401\b/i.test(err.message || "")) {
|
|
24400
|
-
const { replaceLastAnswer:
|
|
24401
|
-
|
|
24490
|
+
const { replaceLastAnswer: replaceLastAnswer3 } = useConversationStore.getState();
|
|
24491
|
+
replaceLastAnswer3(
|
|
24402
24492
|
"_Your session ended \u2014 sign back in to continue._",
|
|
24403
24493
|
lastPartialRef.current.images,
|
|
24404
24494
|
false,
|
|
@@ -24425,8 +24515,8 @@ ${protocol}`;
|
|
|
24425
24515
|
scope: rateLimit.scope,
|
|
24426
24516
|
frontier: rateLimit.frontier
|
|
24427
24517
|
});
|
|
24428
|
-
const { replaceLastAnswer:
|
|
24429
|
-
|
|
24518
|
+
const { replaceLastAnswer: replaceLastAnswer3 } = useConversationStore.getState();
|
|
24519
|
+
replaceLastAnswer3(
|
|
24430
24520
|
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._",
|
|
24431
24521
|
lastPartialRef.current.images,
|
|
24432
24522
|
false,
|
|
@@ -24447,10 +24537,16 @@ ${protocol}`;
|
|
|
24447
24537
|
if (partial && !partial.trim().endsWith("\u2026") && !partial.trim().endsWith("...")) {
|
|
24448
24538
|
partial = partial.trimEnd() + " \u2026";
|
|
24449
24539
|
}
|
|
24540
|
+
const { replaceLastAnswer: replaceLastAnswer2 } = useConversationStore.getState();
|
|
24450
24541
|
if (partial) {
|
|
24451
|
-
const { replaceLastAnswer: replaceLastAnswer2 } = useConversationStore.getState();
|
|
24452
24542
|
replaceLastAnswer2(partial, lastPartialRef.current.images, false, lastPartialRef.current.usedDocs, true);
|
|
24453
24543
|
setResponse(partial);
|
|
24544
|
+
} else {
|
|
24545
|
+
const { conversations: convs, currentId: convId } = useConversationStore.getState();
|
|
24546
|
+
const last = convs.find((c) => c.id === convId)?.history.at(-1);
|
|
24547
|
+
if (last?.answer === "...") {
|
|
24548
|
+
replaceLastAnswer2("_No response came back. Try sending again._", lastPartialRef.current.images, false, lastPartialRef.current.usedDocs, true);
|
|
24549
|
+
}
|
|
24454
24550
|
}
|
|
24455
24551
|
setStreamBuffer("");
|
|
24456
24552
|
setIsThinking?.(false);
|
|
@@ -24462,6 +24558,7 @@ ${protocol}`;
|
|
|
24462
24558
|
}
|
|
24463
24559
|
},
|
|
24464
24560
|
complete: async () => {
|
|
24561
|
+
reportOutcome({ kind: "completed" });
|
|
24465
24562
|
try {
|
|
24466
24563
|
setIsThinking?.(false);
|
|
24467
24564
|
telemetryEvent("tool_loop:llm_response", { responseLength: fullMessage.length });
|
|
@@ -24728,7 +24825,7 @@ _This link is temporary and expires in about ${mins} minutes._`;
|
|
|
24728
24825
|
}
|
|
24729
24826
|
} else {
|
|
24730
24827
|
const data = result.data ?? {};
|
|
24731
|
-
const informative = [data.message, data.details, data.error, result.error].map((value) => typeof value === "string" ? value.trim() :
|
|
24828
|
+
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");
|
|
24732
24829
|
resultText = informative.length ? informative.join(" \u2014 ") : `I couldn't complete that request: ${result.error || "Unknown error"}.`;
|
|
24733
24830
|
}
|
|
24734
24831
|
enhancedMessage = enhancedMessage.replace(placeholderToken, resultText);
|
|
@@ -25075,6 +25172,7 @@ ${inlineImageBlocks.join("\n\n")}` : "");
|
|
|
25075
25172
|
} catch {
|
|
25076
25173
|
}
|
|
25077
25174
|
currentSubRef.current = null;
|
|
25175
|
+
onTurnOutcomeRef.current?.({ kind: "cancelled" });
|
|
25078
25176
|
let partial = lastPartialRef.current.text;
|
|
25079
25177
|
if (partial && !partial.trim().endsWith("\u2026") && !partial.trim().endsWith("...")) {
|
|
25080
25178
|
partial = partial.trimEnd() + " \u2026";
|
|
@@ -25293,7 +25391,7 @@ var init_useNetworkStatus = __esm({
|
|
|
25293
25391
|
if (connection) {
|
|
25294
25392
|
const updateConnectionInfo = () => {
|
|
25295
25393
|
const slowConnections = ["slow-2g", "2g"];
|
|
25296
|
-
const isSlowConnection = slowConnections.includes(connection.effectiveType);
|
|
25394
|
+
const isSlowConnection = slowConnections.includes(connection.effectiveType ?? "");
|
|
25297
25395
|
setNetworkStatus((prev) => ({
|
|
25298
25396
|
...prev,
|
|
25299
25397
|
isSlowConnection,
|
|
@@ -27743,7 +27841,7 @@ var init_conversation_drawer = __esm({
|
|
|
27743
27841
|
title: "Sign out",
|
|
27744
27842
|
onClick: (event) => {
|
|
27745
27843
|
event.stopPropagation();
|
|
27746
|
-
|
|
27844
|
+
authenticationService.clearToken();
|
|
27747
27845
|
window.location.href = "/login";
|
|
27748
27846
|
},
|
|
27749
27847
|
sx: {
|
|
@@ -28870,7 +28968,7 @@ var init_enhanced_mobile_conversations_modal = __esm({
|
|
|
28870
28968
|
title: "Sign out",
|
|
28871
28969
|
onClick: (event) => {
|
|
28872
28970
|
event.stopPropagation();
|
|
28873
|
-
|
|
28971
|
+
authenticationService.clearToken();
|
|
28874
28972
|
window.location.href = "/login";
|
|
28875
28973
|
},
|
|
28876
28974
|
sx: {
|
|
@@ -29690,7 +29788,8 @@ var init_query_suggestion_picker = __esm({
|
|
|
29690
29788
|
}
|
|
29691
29789
|
},
|
|
29692
29790
|
onClick: () => {
|
|
29693
|
-
onSend(prompt, [])
|
|
29791
|
+
void Promise.resolve(onSend(prompt, [])).catch(() => {
|
|
29792
|
+
});
|
|
29694
29793
|
setHasSentPrompt(true);
|
|
29695
29794
|
},
|
|
29696
29795
|
children: /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
|
|
@@ -29751,7 +29850,7 @@ var init_UnderReview = __esm({
|
|
|
29751
29850
|
const theme = (0, import_material52.useTheme)();
|
|
29752
29851
|
const navigate = (0, import_react_router_dom5.useNavigate)();
|
|
29753
29852
|
const handleResetSession = () => {
|
|
29754
|
-
|
|
29853
|
+
authenticationService.clearToken();
|
|
29755
29854
|
navigate("/login");
|
|
29756
29855
|
};
|
|
29757
29856
|
return /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(
|
|
@@ -30432,8 +30531,8 @@ var init_chat2 = __esm({
|
|
|
30432
30531
|
const notificationService2 = useNotificationService();
|
|
30433
30532
|
const [selectedTheme, setSelectedTheme] = (0, import_react79.useState)(null);
|
|
30434
30533
|
const [themeLoading, setThemeLoading] = (0, import_react79.useState)(true);
|
|
30435
|
-
const token =
|
|
30436
|
-
const claims = token ?
|
|
30534
|
+
const token = authenticationService.getToken();
|
|
30535
|
+
const claims = token ? authenticationService.parseJwtClaims(token) : null;
|
|
30437
30536
|
const baseTheme = themeMap_default[selectedTheme ?? "bandit-dark"] || banditDarkTheme;
|
|
30438
30537
|
const banditTheme = (0, import_react79.useMemo)(() => {
|
|
30439
30538
|
return (0, import_styles34.createTheme)(baseTheme, {
|
|
@@ -30506,7 +30605,7 @@ var init_chat2 = __esm({
|
|
|
30506
30605
|
} = useTTS();
|
|
30507
30606
|
(0, import_react79.useEffect)(() => {
|
|
30508
30607
|
const timer = setTimeout(() => {
|
|
30509
|
-
const isAuthenticated =
|
|
30608
|
+
const isAuthenticated = authenticationService.isAuthenticated();
|
|
30510
30609
|
if (!initialized || availableVoices.length === 0) {
|
|
30511
30610
|
if (token && isAuthenticated) {
|
|
30512
30611
|
debugLogger.debug("Chat: Voices not initialized or unavailable, attempting to load from API");
|
|
@@ -30519,7 +30618,7 @@ var init_chat2 = __esm({
|
|
|
30519
30618
|
return () => clearTimeout(timer);
|
|
30520
30619
|
}, [initialized, availableVoices.length, loadVoicesFromAPI, token]);
|
|
30521
30620
|
(0, import_react79.useEffect)(() => {
|
|
30522
|
-
const isAuthenticated =
|
|
30621
|
+
const isAuthenticated = authenticationService.isAuthenticated();
|
|
30523
30622
|
if (packageSettings?.gatewayApiUrl && availableVoices.length === 0 && !initialized) {
|
|
30524
30623
|
if (token && isAuthenticated) {
|
|
30525
30624
|
debugLogger.debug("Chat: Gateway URL available and no voices loaded, attempting to load from API");
|
|
@@ -31134,7 +31233,16 @@ var init_chat2 = __esm({
|
|
|
31134
31233
|
if (rafId) cancelAnimationFrame(rafId);
|
|
31135
31234
|
};
|
|
31136
31235
|
}, [_hasHydrated, chatContainerEl, getScrollState, history.length]);
|
|
31236
|
+
const sendAckRef = (0, import_react79.useRef)(null);
|
|
31237
|
+
const settleSendAck = (0, import_react79.useCallback)((outcome) => {
|
|
31238
|
+
const ack = sendAckRef.current;
|
|
31239
|
+
if (!ack) return;
|
|
31240
|
+
sendAckRef.current = null;
|
|
31241
|
+
if (outcome.kind === "failed" && !outcome.hadOutput) ack.reject(outcome.error);
|
|
31242
|
+
else ack.resolve();
|
|
31243
|
+
}, []);
|
|
31137
31244
|
const aiProvider = useAIProvider({
|
|
31245
|
+
onTurnOutcome: settleSendAck,
|
|
31138
31246
|
overrideComponentStatus: setComponentStatus,
|
|
31139
31247
|
setIsSubmitting,
|
|
31140
31248
|
setIsStreaming,
|
|
@@ -31185,6 +31293,26 @@ var init_chat2 = __esm({
|
|
|
31185
31293
|
}, [ttsStop, isStreaming, handleStop]);
|
|
31186
31294
|
const handleSend = (0, import_react79.useCallback)(
|
|
31187
31295
|
(question, images, displayQuestion) => {
|
|
31296
|
+
sendAckRef.current?.resolve();
|
|
31297
|
+
const acknowledged = new Promise((resolve, reject) => {
|
|
31298
|
+
sendAckRef.current = { resolve, reject };
|
|
31299
|
+
});
|
|
31300
|
+
const runProvider = (systemPrompt2, providerImages2) => {
|
|
31301
|
+
aiProvider(systemPrompt2, question, providerImages2).catch((error) => {
|
|
31302
|
+
debugLogger.error("AI provider failed before streaming", {
|
|
31303
|
+
error: error instanceof Error ? error.message : String(error)
|
|
31304
|
+
});
|
|
31305
|
+
setIsStreaming(false);
|
|
31306
|
+
setResponseStarted(false);
|
|
31307
|
+
setIsSubmitting(false);
|
|
31308
|
+
setPendingMessage(null);
|
|
31309
|
+
const { conversations: convs, currentId: convId, replaceLastAnswer } = useConversationStore.getState();
|
|
31310
|
+
if (convs.find((c) => c.id === convId)?.history.at(-1)?.answer === "...") {
|
|
31311
|
+
replaceLastAnswer("_No response came back. Try sending again._", void 0, false, void 0, true);
|
|
31312
|
+
}
|
|
31313
|
+
settleSendAck({ kind: "failed", hadOutput: false, error });
|
|
31314
|
+
});
|
|
31315
|
+
};
|
|
31188
31316
|
const requestStartTime = trackRequestStart();
|
|
31189
31317
|
const questionForDisplay = displayQuestion || question;
|
|
31190
31318
|
const pendingImages = images.length > 0 ? [...images] : void 0;
|
|
@@ -31223,10 +31351,15 @@ var init_chat2 = __esm({
|
|
|
31223
31351
|
rawQuestion: question
|
|
31224
31352
|
});
|
|
31225
31353
|
const providerImages2 = pendingImages ? [...pendingImages] : [];
|
|
31226
|
-
|
|
31354
|
+
runProvider(systemPrompt, providerImages2);
|
|
31227
31355
|
}, 0);
|
|
31356
|
+
}).catch((error) => {
|
|
31357
|
+
debugLogger.error("Starting a new conversation failed", {
|
|
31358
|
+
error: error instanceof Error ? error.message : String(error)
|
|
31359
|
+
});
|
|
31360
|
+
settleSendAck({ kind: "failed", hadOutput: false, error });
|
|
31228
31361
|
});
|
|
31229
|
-
return;
|
|
31362
|
+
return acknowledged;
|
|
31230
31363
|
}
|
|
31231
31364
|
if (existing.name === "New Conversation") {
|
|
31232
31365
|
generateName(question).then((newName) => {
|
|
@@ -31274,10 +31407,12 @@ var init_chat2 = __esm({
|
|
|
31274
31407
|
}
|
|
31275
31408
|
setResponse("");
|
|
31276
31409
|
const providerImages = pendingImages ? [...pendingImages] : [];
|
|
31277
|
-
|
|
31410
|
+
runProvider(systemPrompt, providerImages);
|
|
31411
|
+
return acknowledged;
|
|
31278
31412
|
},
|
|
31279
31413
|
[
|
|
31280
31414
|
aiProvider,
|
|
31415
|
+
settleSendAck,
|
|
31281
31416
|
chatContainerRef,
|
|
31282
31417
|
generateName,
|
|
31283
31418
|
getScrollState,
|
|
@@ -31301,7 +31436,8 @@ var init_chat2 = __esm({
|
|
|
31301
31436
|
}
|
|
31302
31437
|
setInputValue("");
|
|
31303
31438
|
setPastedImages([]);
|
|
31304
|
-
handleSend(cleaned, [], cleaned)
|
|
31439
|
+
handleSend(cleaned, [], cleaned).catch(() => {
|
|
31440
|
+
});
|
|
31305
31441
|
},
|
|
31306
31442
|
[handleSend, setInputValue, setPastedImages]
|
|
31307
31443
|
);
|
|
@@ -31879,12 +32015,12 @@ var init_chat2 = __esm({
|
|
|
31879
32015
|
ossConfigured,
|
|
31880
32016
|
isOSSMode: isOSSMode(),
|
|
31881
32017
|
tier: featureFlag.getEvaluation()?.tier,
|
|
31882
|
-
hasToken:
|
|
32018
|
+
hasToken: authenticationService.isAuthenticated(),
|
|
31883
32019
|
playgroundBypassAuth,
|
|
31884
32020
|
isPlaygroundRoute,
|
|
31885
32021
|
bypassAuth
|
|
31886
32022
|
});
|
|
31887
|
-
if (!allowUnauthenticated && !bypassAuth && !
|
|
32023
|
+
if (!allowUnauthenticated && !bypassAuth && !authenticationService.isAuthenticated()) {
|
|
31888
32024
|
debugLogger.debug("User is not authenticated, redirecting to login");
|
|
31889
32025
|
return /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_react_router_dom6.Navigate, { to: "/login", replace: true });
|
|
31890
32026
|
}
|
|
@@ -36704,7 +36840,7 @@ var useGatewayClient = () => {
|
|
|
36704
36840
|
}
|
|
36705
36841
|
return new GatewayService(
|
|
36706
36842
|
gatewayUrl,
|
|
36707
|
-
() =>
|
|
36843
|
+
() => authenticationService.getToken(),
|
|
36708
36844
|
feedbackEmail
|
|
36709
36845
|
);
|
|
36710
36846
|
}, [gatewayUrl, feedbackEmail]);
|
|
@@ -40553,7 +40689,7 @@ var buildHeaders2 = () => {
|
|
|
40553
40689
|
const headers = {
|
|
40554
40690
|
"Content-Type": "application/json"
|
|
40555
40691
|
};
|
|
40556
|
-
const token =
|
|
40692
|
+
const token = authenticationService.getToken();
|
|
40557
40693
|
if (token) {
|
|
40558
40694
|
headers.Authorization = `Bearer ${token}`;
|
|
40559
40695
|
}
|
|
@@ -43152,7 +43288,7 @@ var AIProviderInitService = class _AIProviderInitService {
|
|
|
43152
43288
|
type: "ollama" /* OLLAMA */,
|
|
43153
43289
|
baseUrl: settings.ollamaUrl,
|
|
43154
43290
|
tokenFactory: () => {
|
|
43155
|
-
let token =
|
|
43291
|
+
let token = authenticationService.getToken();
|
|
43156
43292
|
if (!token) {
|
|
43157
43293
|
token = localStorage.getItem("authToken");
|
|
43158
43294
|
}
|
|
@@ -43193,7 +43329,7 @@ var AIProviderInitService = class _AIProviderInitService {
|
|
|
43193
43329
|
type: "ollama" /* OLLAMA */,
|
|
43194
43330
|
baseUrl: settings.ollamaUrl || "http://localhost:11434",
|
|
43195
43331
|
tokenFactory: () => {
|
|
43196
|
-
let token =
|
|
43332
|
+
let token = authenticationService.getToken();
|
|
43197
43333
|
if (!token) {
|
|
43198
43334
|
token = localStorage.getItem("authToken");
|
|
43199
43335
|
}
|
|
@@ -43224,7 +43360,7 @@ var AIProviderInitService = class _AIProviderInitService {
|
|
|
43224
43360
|
type: "ollama" /* OLLAMA */,
|
|
43225
43361
|
baseUrl: "http://localhost:11434",
|
|
43226
43362
|
tokenFactory: () => {
|
|
43227
|
-
let token =
|
|
43363
|
+
let token = authenticationService.getToken();
|
|
43228
43364
|
if (!token) {
|
|
43229
43365
|
token = localStorage.getItem("authToken");
|
|
43230
43366
|
}
|
|
@@ -43314,7 +43450,7 @@ var AIProviderInitService = class _AIProviderInitService {
|
|
|
43314
43450
|
return config;
|
|
43315
43451
|
}
|
|
43316
43452
|
config.tokenFactory = () => {
|
|
43317
|
-
let token =
|
|
43453
|
+
let token = authenticationService.getToken();
|
|
43318
43454
|
if (!token && typeof localStorage !== "undefined") {
|
|
43319
43455
|
try {
|
|
43320
43456
|
token = localStorage.getItem("authToken");
|
|
@@ -43573,7 +43709,6 @@ var ProviderTab = () => {
|
|
|
43573
43709
|
usePackageSettingsStore.setState({ settings: updatedSettings });
|
|
43574
43710
|
}
|
|
43575
43711
|
setProviderConfig(applyDefaultModel(normalizedConfig));
|
|
43576
|
-
setIsProviderConfigOpen(false);
|
|
43577
43712
|
showMessage("Provider configuration saved and switched successfully!", "success");
|
|
43578
43713
|
debugLogger.info("Provider configuration saved and switched", { type: normalizedConfig.type });
|
|
43579
43714
|
} catch (error) {
|
|
@@ -43961,7 +44096,7 @@ function buildUrl3(path) {
|
|
|
43961
44096
|
}
|
|
43962
44097
|
function authHeaders() {
|
|
43963
44098
|
const headers = { "Content-Type": "application/json" };
|
|
43964
|
-
const token =
|
|
44099
|
+
const token = authenticationService.getToken();
|
|
43965
44100
|
if (token) headers["Authorization"] = `Bearer ${token}`;
|
|
43966
44101
|
return headers;
|
|
43967
44102
|
}
|
|
@@ -45306,7 +45441,7 @@ var Management = () => {
|
|
|
45306
45441
|
let isActive = true;
|
|
45307
45442
|
const loadCapabilities = async () => {
|
|
45308
45443
|
try {
|
|
45309
|
-
const token = authToken ??
|
|
45444
|
+
const token = authToken ?? authenticationService.getToken();
|
|
45310
45445
|
const headers = {
|
|
45311
45446
|
"Content-Type": "application/json"
|
|
45312
45447
|
};
|
|
@@ -45442,7 +45577,7 @@ var Management = () => {
|
|
|
45442
45577
|
"admin",
|
|
45443
45578
|
"platform_admin"
|
|
45444
45579
|
]);
|
|
45445
|
-
const userRoles = (
|
|
45580
|
+
const userRoles = (authenticationService.parseJwtClaims(authenticationService.getToken() ?? "")?.roles ?? []).map((r) => r.toLowerCase());
|
|
45446
45581
|
const isWorkspaceAdmin = userRoles.some(
|
|
45447
45582
|
(r) => platformAdminRoles.has(r) || r.endsWith("-admin")
|
|
45448
45583
|
);
|