@burtson-labs/bandit-engine 2.0.39 → 2.0.41
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 +14 -11
- package/dist/{aiProviderStore-XN7GCBHJ.mjs → aiProviderStore-UQI33C5E.mjs} +2 -2
- package/dist/{chat-5QJNWB7I.mjs → chat-T5ANWWYQ.mjs} +5 -5
- package/dist/chat-provider.js +571 -122
- package/dist/chat-provider.js.map +1 -1
- package/dist/chat-provider.mjs +4 -4
- package/dist/{chunk-3A2527TE.mjs → chunk-22EY3ZDC.mjs} +3 -3
- package/dist/{chunk-ECRNIAG6.mjs → chunk-3E57HLDV.mjs} +4 -4
- package/dist/{chunk-QU5S5QQP.mjs → chunk-54ZQ3FSN.mjs} +481 -77
- package/dist/chunk-54ZQ3FSN.mjs.map +1 -0
- package/dist/{chunk-JRCDANLN.mjs → chunk-A6OBEF72.mjs} +75 -12
- package/dist/{chunk-JRCDANLN.mjs.map → chunk-A6OBEF72.mjs.map} +1 -1
- package/dist/{chunk-CDQYBO3Q.mjs → chunk-CX3INLYJ.mjs} +27 -5
- package/dist/chunk-CX3INLYJ.mjs.map +1 -0
- package/dist/{chunk-QYH2T4L5.mjs → chunk-LYWVYBKU.mjs} +3 -3
- package/dist/{chunk-WO5KFNNW.mjs → chunk-QFNEHSY4.mjs} +62 -24
- package/dist/chunk-QFNEHSY4.mjs.map +1 -0
- package/dist/{chunk-EOKIE5HZ.mjs → chunk-WPWWWUD7.mjs} +51 -46
- package/dist/chunk-WPWWWUD7.mjs.map +1 -0
- package/dist/{cli/cli.js → cli.js} +423 -10
- package/dist/cli.js.map +1 -0
- package/dist/{gateway-B0LJ3-jT.d.ts → gateway-5yt_3QDP.d.mts} +4 -4
- package/dist/{gateway-B0LJ3-jT.d.mts → gateway-5yt_3QDP.d.ts} +4 -4
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +756 -206
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +8 -8
- package/dist/management/management.js +754 -204
- package/dist/management/management.js.map +1 -1
- package/dist/management/management.mjs +6 -6
- package/dist/modals/chat-modal/chat-modal.js +532 -88
- package/dist/modals/chat-modal/chat-modal.js.map +1 -1
- package/dist/modals/chat-modal/chat-modal.mjs +4 -4
- package/dist/public-types.d.mts +1 -1
- package/dist/public-types.d.ts +1 -1
- package/docs/01_quickstart.md +10 -4
- package/docs/02_gateway_api.md +19 -3
- package/docs/03_provider_integration.md +5 -4
- package/docs/api_reference/media/02_gateway_api.md +19 -3
- package/docs/api_reference/media/README.md +3 -1
- package/package.json +1 -1
- package/dist/chunk-CDQYBO3Q.mjs.map +0 -1
- package/dist/chunk-EOKIE5HZ.mjs.map +0 -1
- package/dist/chunk-QU5S5QQP.mjs.map +0 -1
- package/dist/chunk-WO5KFNNW.mjs.map +0 -1
- package/dist/cli/cli.js.map +0 -1
- /package/dist/{aiProviderStore-XN7GCBHJ.mjs.map → aiProviderStore-UQI33C5E.mjs.map} +0 -0
- /package/dist/{chat-5QJNWB7I.mjs.map → chat-T5ANWWYQ.mjs.map} +0 -0
- /package/dist/{chunk-3A2527TE.mjs.map → chunk-22EY3ZDC.mjs.map} +0 -0
- /package/dist/{chunk-ECRNIAG6.mjs.map → chunk-3E57HLDV.mjs.map} +0 -0
- /package/dist/{chunk-QYH2T4L5.mjs.map → chunk-LYWVYBKU.mjs.map} +0 -0
|
@@ -12,11 +12,11 @@ var __export = (target, all) => {
|
|
|
12
12
|
for (var name in all)
|
|
13
13
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
14
14
|
};
|
|
15
|
-
var __copyProps = (to,
|
|
16
|
-
if (
|
|
17
|
-
for (let key of __getOwnPropNames(
|
|
15
|
+
var __copyProps = (to, from10, except, desc) => {
|
|
16
|
+
if (from10 && typeof from10 === "object" || typeof from10 === "function") {
|
|
17
|
+
for (let key of __getOwnPropNames(from10))
|
|
18
18
|
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
19
|
-
__defProp(to, key, { get: () =>
|
|
19
|
+
__defProp(to, key, { get: () => from10[key], enumerable: !(desc = __getOwnPropDesc(from10, key)) || desc.enumerable });
|
|
20
20
|
}
|
|
21
21
|
return to;
|
|
22
22
|
};
|
|
@@ -1656,57 +1656,15 @@ var init_gateway_service = __esm({
|
|
|
1656
1656
|
*/
|
|
1657
1657
|
chat(request) {
|
|
1658
1658
|
const endpoint = request.provider === "ollama" ? `/api/${request.provider}/chat` : request.provider ? `/api/${request.provider}/chat/completions` : "/api/chat/completions";
|
|
1659
|
-
const
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
});
|
|
1666
|
-
const requestBody = { ...request, stream: request.stream !== false };
|
|
1659
|
+
const fallbackEndpoint = request.provider === "bandit" ? "/completions" : null;
|
|
1660
|
+
const normalizedModel = request.provider === "bandit" ? (() => {
|
|
1661
|
+
const trimmed = (request.model ?? "").replace(/^bandit:/, "").trim();
|
|
1662
|
+
return trimmed !== "" ? trimmed : "bandit-core-1";
|
|
1663
|
+
})() : request.model;
|
|
1664
|
+
const requestBody = { ...request, model: normalizedModel, stream: request.stream !== false };
|
|
1667
1665
|
return new import_rxjs6.Observable((observer) => {
|
|
1668
1666
|
const controller = new AbortController();
|
|
1669
|
-
const
|
|
1670
|
-
method: "POST",
|
|
1671
|
-
headers: this._getHeaders(),
|
|
1672
|
-
body: JSON.stringify(requestBody),
|
|
1673
|
-
signal: controller.signal
|
|
1674
|
-
});
|
|
1675
|
-
task.then(async (response) => {
|
|
1676
|
-
debugLogger.debug(`Gateway chat response status: ${response.status} for provider: ${request.provider || "default"}`);
|
|
1677
|
-
if (!response.ok) {
|
|
1678
|
-
let errorText = "";
|
|
1679
|
-
let errorData = null;
|
|
1680
|
-
try {
|
|
1681
|
-
errorText = await response.text();
|
|
1682
|
-
debugLogger.error("GatewayService chat error response body", {
|
|
1683
|
-
status: response.status,
|
|
1684
|
-
statusText: response.statusText,
|
|
1685
|
-
url: response.url,
|
|
1686
|
-
body: errorText
|
|
1687
|
-
});
|
|
1688
|
-
} catch (readError) {
|
|
1689
|
-
debugLogger.error("GatewayService chat failed to read error response body", { error: readError });
|
|
1690
|
-
errorText = `Request failed with status ${response.status}`;
|
|
1691
|
-
}
|
|
1692
|
-
try {
|
|
1693
|
-
errorData = JSON.parse(errorText);
|
|
1694
|
-
debugLogger.error("GatewayService chat parsed error payload", errorData);
|
|
1695
|
-
} catch (parseError) {
|
|
1696
|
-
debugLogger.error("GatewayService chat error payload was not valid JSON");
|
|
1697
|
-
errorData = { message: errorText };
|
|
1698
|
-
}
|
|
1699
|
-
const error = this._createHttpError(
|
|
1700
|
-
`POST ${url} failed: ${response.status} ${response.statusText ?? ""}`,
|
|
1701
|
-
{
|
|
1702
|
-
status: response.status,
|
|
1703
|
-
statusText: response.statusText ?? "",
|
|
1704
|
-
data: errorData,
|
|
1705
|
-
url
|
|
1706
|
-
}
|
|
1707
|
-
);
|
|
1708
|
-
throw error;
|
|
1709
|
-
}
|
|
1667
|
+
const handleStreamingResponse = async (response) => {
|
|
1710
1668
|
const reader = response.body?.getReader();
|
|
1711
1669
|
const decoder = new TextDecoder();
|
|
1712
1670
|
let buffer = "";
|
|
@@ -1781,14 +1739,75 @@ var init_gateway_service = __esm({
|
|
|
1781
1739
|
}).catch((err) => observer.error(err));
|
|
1782
1740
|
};
|
|
1783
1741
|
read();
|
|
1784
|
-
}
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1742
|
+
};
|
|
1743
|
+
const sendRequest = (targetEndpoint, allowFallback) => {
|
|
1744
|
+
const url = `${this._baseUrl}${targetEndpoint}`;
|
|
1745
|
+
debugLogger.debug(`Gateway chat request to ${url} with provider: ${request.provider || "default"}`, {
|
|
1746
|
+
model: normalizedModel,
|
|
1747
|
+
messageCount: request.messages.length,
|
|
1748
|
+
hasImages: !!(request.images && request.images.length > 0),
|
|
1749
|
+
imageCount: request.images?.length || 0
|
|
1789
1750
|
});
|
|
1790
|
-
|
|
1791
|
-
|
|
1751
|
+
fetch(url, {
|
|
1752
|
+
method: "POST",
|
|
1753
|
+
headers: this._getHeaders(),
|
|
1754
|
+
body: JSON.stringify(requestBody),
|
|
1755
|
+
signal: controller.signal
|
|
1756
|
+
}).then(async (response) => {
|
|
1757
|
+
debugLogger.debug(`Gateway chat response status: ${response.status} for provider: ${request.provider || "default"}`);
|
|
1758
|
+
if (response.status === 404 && allowFallback && fallbackEndpoint) {
|
|
1759
|
+
debugLogger.warn("GatewayService chat endpoint returned 404, attempting fallback route", {
|
|
1760
|
+
provider: request.provider,
|
|
1761
|
+
attemptedEndpoint: targetEndpoint,
|
|
1762
|
+
fallbackEndpoint
|
|
1763
|
+
});
|
|
1764
|
+
sendRequest(fallbackEndpoint, false);
|
|
1765
|
+
return;
|
|
1766
|
+
}
|
|
1767
|
+
if (!response.ok) {
|
|
1768
|
+
let errorText = "";
|
|
1769
|
+
let errorData = null;
|
|
1770
|
+
try {
|
|
1771
|
+
errorText = await response.text();
|
|
1772
|
+
debugLogger.error("GatewayService chat error response body", {
|
|
1773
|
+
status: response.status,
|
|
1774
|
+
statusText: response.statusText,
|
|
1775
|
+
url: response.url,
|
|
1776
|
+
body: errorText
|
|
1777
|
+
});
|
|
1778
|
+
} catch (readError) {
|
|
1779
|
+
debugLogger.error("GatewayService chat failed to read error response body", { error: readError });
|
|
1780
|
+
errorText = `Request failed with status ${response.status}`;
|
|
1781
|
+
}
|
|
1782
|
+
try {
|
|
1783
|
+
errorData = JSON.parse(errorText);
|
|
1784
|
+
debugLogger.error("GatewayService chat parsed error payload", errorData);
|
|
1785
|
+
} catch (parseError) {
|
|
1786
|
+
debugLogger.error("GatewayService chat error payload was not valid JSON");
|
|
1787
|
+
errorData = { message: errorText };
|
|
1788
|
+
}
|
|
1789
|
+
const error = this._createHttpError(
|
|
1790
|
+
`POST ${url} failed: ${response.status} ${response.statusText ?? ""}`,
|
|
1791
|
+
{
|
|
1792
|
+
status: response.status,
|
|
1793
|
+
statusText: response.statusText ?? "",
|
|
1794
|
+
data: errorData,
|
|
1795
|
+
url
|
|
1796
|
+
}
|
|
1797
|
+
);
|
|
1798
|
+
throw error;
|
|
1799
|
+
}
|
|
1800
|
+
await handleStreamingResponse(response);
|
|
1801
|
+
}).catch((err) => {
|
|
1802
|
+
debugLogger.error("GatewayService chat fetch error", {
|
|
1803
|
+
error: err,
|
|
1804
|
+
url,
|
|
1805
|
+
provider: request.provider
|
|
1806
|
+
});
|
|
1807
|
+
observer.error(err);
|
|
1808
|
+
});
|
|
1809
|
+
};
|
|
1810
|
+
sendRequest(endpoint, true);
|
|
1792
1811
|
return () => {
|
|
1793
1812
|
try {
|
|
1794
1813
|
controller.abort();
|
|
@@ -1803,12 +1822,18 @@ var init_gateway_service = __esm({
|
|
|
1803
1822
|
generate(request) {
|
|
1804
1823
|
const endpoint = request.provider ? `/api/${request.provider}/generate` : "/api/generate";
|
|
1805
1824
|
const url = `${this._baseUrl}${endpoint}`;
|
|
1806
|
-
|
|
1825
|
+
const normalizedModel = request.provider === "bandit" ? (() => {
|
|
1826
|
+
const trimmed = (request.model ?? "").replace(/^bandit:/, "").trim();
|
|
1827
|
+
return trimmed !== "" ? trimmed : "bandit-core-1";
|
|
1828
|
+
})() : request.model;
|
|
1829
|
+
debugLogger.debug(`Gateway generate request to ${url} with provider: ${request.provider || "default"}`, {
|
|
1830
|
+
model: normalizedModel
|
|
1831
|
+
});
|
|
1807
1832
|
return new import_rxjs6.Observable((observer) => {
|
|
1808
1833
|
const task = fetch(url, {
|
|
1809
1834
|
method: "POST",
|
|
1810
1835
|
headers: this._getHeaders(),
|
|
1811
|
-
body: JSON.stringify({ ...request, stream: request.stream !== false })
|
|
1836
|
+
body: JSON.stringify({ ...request, model: normalizedModel, stream: request.stream !== false })
|
|
1812
1837
|
});
|
|
1813
1838
|
task.then(async (response) => {
|
|
1814
1839
|
if (!response.ok) {
|
|
@@ -1915,18 +1940,46 @@ var init_gateway_service = __esm({
|
|
|
1915
1940
|
);
|
|
1916
1941
|
}
|
|
1917
1942
|
_getHeaders() {
|
|
1918
|
-
const
|
|
1943
|
+
const rawToken2 = this._tokenFactory();
|
|
1919
1944
|
const headers = {
|
|
1920
1945
|
"Content-Type": "application/json"
|
|
1921
1946
|
};
|
|
1922
|
-
if (
|
|
1923
|
-
headers["Authorization"] = `Bearer ${token}`;
|
|
1924
|
-
debugLogger.debug("Authorization header set with token");
|
|
1925
|
-
} else {
|
|
1947
|
+
if (!rawToken2) {
|
|
1926
1948
|
debugLogger.warn("GatewayService: No token found, skipping Authorization header");
|
|
1949
|
+
return headers;
|
|
1950
|
+
}
|
|
1951
|
+
const token = rawToken2.trim();
|
|
1952
|
+
if (token === "") {
|
|
1953
|
+
debugLogger.warn("GatewayService: Token factory returned empty string");
|
|
1954
|
+
return headers;
|
|
1955
|
+
}
|
|
1956
|
+
if (/^(Bearer|ApiKey)\s+/i.test(token)) {
|
|
1957
|
+
headers["Authorization"] = token;
|
|
1958
|
+
debugLogger.debug("GatewayService: Authorization header set with explicit scheme");
|
|
1959
|
+
return headers;
|
|
1927
1960
|
}
|
|
1961
|
+
if (this._isLikelyBanditApiKey(token)) {
|
|
1962
|
+
headers["Authorization"] = `ApiKey ${token}`;
|
|
1963
|
+
headers["X-Burtson-Api-Key"] = token;
|
|
1964
|
+
debugLogger.debug("GatewayService: Authorization header set using API key");
|
|
1965
|
+
return headers;
|
|
1966
|
+
}
|
|
1967
|
+
if (this._isLikelyJwt(token)) {
|
|
1968
|
+
headers["Authorization"] = `Bearer ${token}`;
|
|
1969
|
+
debugLogger.debug("GatewayService: Authorization header set using bearer token");
|
|
1970
|
+
return headers;
|
|
1971
|
+
}
|
|
1972
|
+
headers["Authorization"] = `Bearer ${token}`;
|
|
1973
|
+
debugLogger.debug("GatewayService: Authorization header defaulted to bearer scheme");
|
|
1928
1974
|
return headers;
|
|
1929
1975
|
}
|
|
1976
|
+
_isLikelyJwt(token) {
|
|
1977
|
+
const segments = token.split(".");
|
|
1978
|
+
return segments.length === 3 && segments.every((segment) => segment.length > 0);
|
|
1979
|
+
}
|
|
1980
|
+
_isLikelyBanditApiKey(value) {
|
|
1981
|
+
return /^bai_[a-z0-9]{10,}$/i.test(value);
|
|
1982
|
+
}
|
|
1930
1983
|
/**
|
|
1931
1984
|
* Submit feedback to the gateway API
|
|
1932
1985
|
*/
|
|
@@ -2406,6 +2459,112 @@ var init_ollama_gateway_service = __esm({
|
|
|
2406
2459
|
}
|
|
2407
2460
|
});
|
|
2408
2461
|
|
|
2462
|
+
// src/services/gateway/bandit-gateway.service.ts
|
|
2463
|
+
var import_operators5, normalizeBanditModel, isGatewayMessageContent, normalizeBanditMessages, BanditAIGatewayService;
|
|
2464
|
+
var init_bandit_gateway_service = __esm({
|
|
2465
|
+
"src/services/gateway/bandit-gateway.service.ts"() {
|
|
2466
|
+
"use strict";
|
|
2467
|
+
init_gateway_service();
|
|
2468
|
+
import_operators5 = require("rxjs/operators");
|
|
2469
|
+
init_debugLogger();
|
|
2470
|
+
normalizeBanditModel = (model) => {
|
|
2471
|
+
if (typeof model !== "string" || model.trim() === "") {
|
|
2472
|
+
return "bandit-core-1";
|
|
2473
|
+
}
|
|
2474
|
+
const normalized = model.replace(/^bandit:/, "").trim();
|
|
2475
|
+
return normalized === "" ? "bandit-core-1" : normalized;
|
|
2476
|
+
};
|
|
2477
|
+
isGatewayMessageContent = (value) => {
|
|
2478
|
+
if (!value || typeof value !== "object") return false;
|
|
2479
|
+
const candidate = value;
|
|
2480
|
+
if (candidate.type !== "text" && candidate.type !== "image_url") {
|
|
2481
|
+
return false;
|
|
2482
|
+
}
|
|
2483
|
+
if (candidate.type === "text") {
|
|
2484
|
+
return typeof candidate.text === "string";
|
|
2485
|
+
}
|
|
2486
|
+
if (candidate.type === "image_url") {
|
|
2487
|
+
return !!candidate.image_url && typeof candidate.image_url.url === "string";
|
|
2488
|
+
}
|
|
2489
|
+
return false;
|
|
2490
|
+
};
|
|
2491
|
+
normalizeBanditMessages = (messages) => messages.map((message) => {
|
|
2492
|
+
const content = message.content;
|
|
2493
|
+
if (typeof content === "string") {
|
|
2494
|
+
return { role: message.role, content };
|
|
2495
|
+
}
|
|
2496
|
+
if (Array.isArray(content)) {
|
|
2497
|
+
const filtered = content.filter(isGatewayMessageContent);
|
|
2498
|
+
if (filtered.length === 0) {
|
|
2499
|
+
return { role: message.role, content: JSON.stringify(content) };
|
|
2500
|
+
}
|
|
2501
|
+
return {
|
|
2502
|
+
role: message.role,
|
|
2503
|
+
content: filtered
|
|
2504
|
+
};
|
|
2505
|
+
}
|
|
2506
|
+
return { role: message.role, content: content != null ? String(content) : "" };
|
|
2507
|
+
});
|
|
2508
|
+
BanditAIGatewayService = class {
|
|
2509
|
+
_gatewayService;
|
|
2510
|
+
constructor(gatewayUrl, tokenFactory) {
|
|
2511
|
+
this._gatewayService = new GatewayService(gatewayUrl, tokenFactory);
|
|
2512
|
+
debugLogger.info("BanditAIGatewayService initialized", { gatewayUrl });
|
|
2513
|
+
}
|
|
2514
|
+
async validateServiceAvailability(args) {
|
|
2515
|
+
return this._gatewayService.validateServiceAvailability(args);
|
|
2516
|
+
}
|
|
2517
|
+
chat(request) {
|
|
2518
|
+
const model = normalizeBanditModel(request.model);
|
|
2519
|
+
const messages = normalizeBanditMessages(request.messages);
|
|
2520
|
+
const gatewayRequest = {
|
|
2521
|
+
...request,
|
|
2522
|
+
messages,
|
|
2523
|
+
model,
|
|
2524
|
+
provider: "bandit",
|
|
2525
|
+
stream: request.stream
|
|
2526
|
+
};
|
|
2527
|
+
debugLogger.debug("Bandit Gateway chat request", {
|
|
2528
|
+
model,
|
|
2529
|
+
messageCount: request.messages.length,
|
|
2530
|
+
stream: request.stream
|
|
2531
|
+
});
|
|
2532
|
+
return this._gatewayService.chat(gatewayRequest);
|
|
2533
|
+
}
|
|
2534
|
+
complete(prompt, options) {
|
|
2535
|
+
const model = normalizeBanditModel(options.model);
|
|
2536
|
+
const gatewayRequest = {
|
|
2537
|
+
model,
|
|
2538
|
+
prompt,
|
|
2539
|
+
temperature: options.temperature,
|
|
2540
|
+
max_tokens: options.max_tokens,
|
|
2541
|
+
stream: options.stream,
|
|
2542
|
+
stop: options.stop,
|
|
2543
|
+
provider: "bandit"
|
|
2544
|
+
};
|
|
2545
|
+
debugLogger.debug("Bandit Gateway generate request", {
|
|
2546
|
+
model,
|
|
2547
|
+
promptLength: prompt.length,
|
|
2548
|
+
stream: options.stream
|
|
2549
|
+
});
|
|
2550
|
+
return this._gatewayService.generate(gatewayRequest);
|
|
2551
|
+
}
|
|
2552
|
+
listModels() {
|
|
2553
|
+
debugLogger.debug("Fetching Bandit models through gateway");
|
|
2554
|
+
return this._gatewayService.listModelsByProvider("bandit");
|
|
2555
|
+
}
|
|
2556
|
+
getHealth() {
|
|
2557
|
+
return this._gatewayService.getHealth().pipe(
|
|
2558
|
+
(0, import_operators5.map)((health) => ({
|
|
2559
|
+
...health,
|
|
2560
|
+
bandit_status: health.providers.find((p) => p.name === "bandit")?.status || "unavailable"
|
|
2561
|
+
}))
|
|
2562
|
+
);
|
|
2563
|
+
}
|
|
2564
|
+
};
|
|
2565
|
+
}
|
|
2566
|
+
});
|
|
2567
|
+
|
|
2409
2568
|
// src/services/ai-provider/providers/gateway.provider.ts
|
|
2410
2569
|
var import_rxjs7, GatewayProvider;
|
|
2411
2570
|
var init_gateway_provider = __esm({
|
|
@@ -2419,6 +2578,7 @@ var init_gateway_provider = __esm({
|
|
|
2419
2578
|
init_azure_openai_gateway_service();
|
|
2420
2579
|
init_anthropic_gateway_service();
|
|
2421
2580
|
init_ollama_gateway_service();
|
|
2581
|
+
init_bandit_gateway_service();
|
|
2422
2582
|
GatewayProvider = class {
|
|
2423
2583
|
config;
|
|
2424
2584
|
gatewayService;
|
|
@@ -2460,6 +2620,9 @@ var init_gateway_provider = __esm({
|
|
|
2460
2620
|
case "anthropic":
|
|
2461
2621
|
this.providerSpecificService = new AnthropicGatewayService(gatewayUrl, tokenFactory);
|
|
2462
2622
|
break;
|
|
2623
|
+
case "bandit":
|
|
2624
|
+
this.providerSpecificService = new BanditAIGatewayService(gatewayUrl, tokenFactory);
|
|
2625
|
+
break;
|
|
2463
2626
|
case "ollama":
|
|
2464
2627
|
this.providerSpecificService = new OllamaGatewayService(gatewayUrl, tokenFactory);
|
|
2465
2628
|
break;
|
|
@@ -2474,6 +2637,16 @@ var init_gateway_provider = __esm({
|
|
|
2474
2637
|
role: msg.role,
|
|
2475
2638
|
content: msg.content
|
|
2476
2639
|
}));
|
|
2640
|
+
const normalizeImageUrl2 = (value) => {
|
|
2641
|
+
if (!value) {
|
|
2642
|
+
return value;
|
|
2643
|
+
}
|
|
2644
|
+
const trimmed = value.trim();
|
|
2645
|
+
if (/^data:/i.test(trimmed) || /^https?:\/\//i.test(trimmed)) {
|
|
2646
|
+
return trimmed;
|
|
2647
|
+
}
|
|
2648
|
+
return `data:image/jpeg;base64,${trimmed}`;
|
|
2649
|
+
};
|
|
2477
2650
|
if (request.images && request.images.length > 0) {
|
|
2478
2651
|
const lastUserMessageIndex = messages.map((m) => m.role).lastIndexOf("user");
|
|
2479
2652
|
if (this.config.provider === "ollama") {
|
|
@@ -2483,7 +2656,7 @@ var init_gateway_provider = __esm({
|
|
|
2483
2656
|
images: request.images
|
|
2484
2657
|
};
|
|
2485
2658
|
}
|
|
2486
|
-
} else if (["openai", "azure-openai", "anthropic"].includes(this.config.provider || "")) {
|
|
2659
|
+
} else if (["openai", "azure-openai", "anthropic", "bandit"].includes(this.config.provider || "")) {
|
|
2487
2660
|
if (lastUserMessageIndex !== -1) {
|
|
2488
2661
|
const currentMessage = messages[lastUserMessageIndex];
|
|
2489
2662
|
const contentArray = [
|
|
@@ -2492,11 +2665,11 @@ var init_gateway_provider = __esm({
|
|
|
2492
2665
|
text: currentMessage.content
|
|
2493
2666
|
}
|
|
2494
2667
|
];
|
|
2495
|
-
request.images.forEach((
|
|
2668
|
+
request.images.forEach((imageRef) => {
|
|
2496
2669
|
contentArray.push({
|
|
2497
2670
|
type: "image_url",
|
|
2498
2671
|
image_url: {
|
|
2499
|
-
url:
|
|
2672
|
+
url: normalizeImageUrl2(imageRef),
|
|
2500
2673
|
detail: "auto"
|
|
2501
2674
|
}
|
|
2502
2675
|
});
|
|
@@ -2505,6 +2678,11 @@ var init_gateway_provider = __esm({
|
|
|
2505
2678
|
...messages[lastUserMessageIndex],
|
|
2506
2679
|
content: contentArray
|
|
2507
2680
|
};
|
|
2681
|
+
debugLogger.debug("Gateway provider injected image attachments", {
|
|
2682
|
+
provider: this.config.provider,
|
|
2683
|
+
imageCount: request.images.length,
|
|
2684
|
+
messageIndex: lastUserMessageIndex
|
|
2685
|
+
});
|
|
2508
2686
|
}
|
|
2509
2687
|
}
|
|
2510
2688
|
}
|
|
@@ -3013,6 +3191,244 @@ var init_xai_provider = __esm({
|
|
|
3013
3191
|
}
|
|
3014
3192
|
});
|
|
3015
3193
|
|
|
3194
|
+
// src/services/ai-provider/providers/bandit-ai.provider.ts
|
|
3195
|
+
var import_rxjs10, DEFAULT_BANDIT_BASE, normalizeImageUrl, injectImagesIntoMessages, BanditAIProvider;
|
|
3196
|
+
var init_bandit_ai_provider = __esm({
|
|
3197
|
+
"src/services/ai-provider/providers/bandit-ai.provider.ts"() {
|
|
3198
|
+
"use strict";
|
|
3199
|
+
import_rxjs10 = require("rxjs");
|
|
3200
|
+
init_common_types();
|
|
3201
|
+
init_debugLogger();
|
|
3202
|
+
DEFAULT_BANDIT_BASE = "https://api.burtson.ai";
|
|
3203
|
+
normalizeImageUrl = (value) => {
|
|
3204
|
+
if (!value) {
|
|
3205
|
+
return null;
|
|
3206
|
+
}
|
|
3207
|
+
const trimmed = value.trim();
|
|
3208
|
+
if (!trimmed) {
|
|
3209
|
+
return null;
|
|
3210
|
+
}
|
|
3211
|
+
if (/^data:/i.test(trimmed) || /^https?:\/\//i.test(trimmed)) {
|
|
3212
|
+
return trimmed;
|
|
3213
|
+
}
|
|
3214
|
+
return `data:image/jpeg;base64,${trimmed}`;
|
|
3215
|
+
};
|
|
3216
|
+
injectImagesIntoMessages = (messages, images) => {
|
|
3217
|
+
const normalized = messages.map((message) => ({
|
|
3218
|
+
role: message.role,
|
|
3219
|
+
content: message.content
|
|
3220
|
+
}));
|
|
3221
|
+
if (!images || images.length === 0) {
|
|
3222
|
+
return normalized;
|
|
3223
|
+
}
|
|
3224
|
+
const normalizedImages = images.map(normalizeImageUrl).filter((url) => Boolean(url));
|
|
3225
|
+
if (normalizedImages.length === 0) {
|
|
3226
|
+
return normalized;
|
|
3227
|
+
}
|
|
3228
|
+
const lastUserIndex = normalized.map((msg) => msg.role).lastIndexOf("user");
|
|
3229
|
+
if (lastUserIndex === -1) {
|
|
3230
|
+
return normalized;
|
|
3231
|
+
}
|
|
3232
|
+
const target = normalized[lastUserIndex];
|
|
3233
|
+
const baseContent = typeof target.content === "string" && target.content.trim().length > 0 ? [
|
|
3234
|
+
{
|
|
3235
|
+
type: "text",
|
|
3236
|
+
text: target.content
|
|
3237
|
+
}
|
|
3238
|
+
] : [];
|
|
3239
|
+
const imageContent = normalizedImages.map((url) => ({
|
|
3240
|
+
type: "image_url",
|
|
3241
|
+
image_url: { url, detail: "auto" }
|
|
3242
|
+
}));
|
|
3243
|
+
normalized[lastUserIndex] = {
|
|
3244
|
+
role: target.role,
|
|
3245
|
+
content: [...baseContent, ...imageContent]
|
|
3246
|
+
};
|
|
3247
|
+
return normalized;
|
|
3248
|
+
};
|
|
3249
|
+
BanditAIProvider = class {
|
|
3250
|
+
config;
|
|
3251
|
+
baseUrl;
|
|
3252
|
+
constructor(config) {
|
|
3253
|
+
this.config = config;
|
|
3254
|
+
this.baseUrl = (config.baseUrl || DEFAULT_BANDIT_BASE).replace(/\/$/, "");
|
|
3255
|
+
}
|
|
3256
|
+
chat(request) {
|
|
3257
|
+
const url = `${this.baseUrl}/chat/completions`;
|
|
3258
|
+
const messages = injectImagesIntoMessages(request.messages, request.images);
|
|
3259
|
+
const payload = {
|
|
3260
|
+
model: request.model,
|
|
3261
|
+
messages,
|
|
3262
|
+
stream: Boolean(request.stream),
|
|
3263
|
+
temperature: request.temperature,
|
|
3264
|
+
max_tokens: request.maxTokens
|
|
3265
|
+
};
|
|
3266
|
+
if (request.stream) {
|
|
3267
|
+
return this.streamChatRequest(url, payload);
|
|
3268
|
+
}
|
|
3269
|
+
return this.nonStreamChatRequest(url, payload);
|
|
3270
|
+
}
|
|
3271
|
+
generate(request) {
|
|
3272
|
+
const chatRequest = {
|
|
3273
|
+
model: request.model,
|
|
3274
|
+
messages: [{ role: "user", content: request.prompt }],
|
|
3275
|
+
stream: request.stream,
|
|
3276
|
+
options: request.options
|
|
3277
|
+
};
|
|
3278
|
+
return this.chat(chatRequest).pipe(
|
|
3279
|
+
(0, import_rxjs10.map)((response) => ({
|
|
3280
|
+
response: response.message.content,
|
|
3281
|
+
done: response.done
|
|
3282
|
+
}))
|
|
3283
|
+
);
|
|
3284
|
+
}
|
|
3285
|
+
listModels() {
|
|
3286
|
+
const url = `${this.baseUrl}/models`;
|
|
3287
|
+
return (0, import_rxjs10.from)(fetch(url, { headers: this.getHeaders() })).pipe(
|
|
3288
|
+
(0, import_rxjs10.switchMap)((response) => {
|
|
3289
|
+
if (!response.ok) {
|
|
3290
|
+
debugLogger.error("BanditAI listModels failed", { status: response.status, url });
|
|
3291
|
+
return (0, import_rxjs10.throwError)(() => new Error(`Failed to list Bandit models: ${response.status}`));
|
|
3292
|
+
}
|
|
3293
|
+
return (0, import_rxjs10.from)(response.json());
|
|
3294
|
+
}),
|
|
3295
|
+
(0, import_rxjs10.map)(
|
|
3296
|
+
(data) => data.data.map((model) => ({
|
|
3297
|
+
name: model.id,
|
|
3298
|
+
details: {
|
|
3299
|
+
format: "bandit",
|
|
3300
|
+
family: model.object
|
|
3301
|
+
}
|
|
3302
|
+
}))
|
|
3303
|
+
)
|
|
3304
|
+
);
|
|
3305
|
+
}
|
|
3306
|
+
async validateServiceAvailability(args) {
|
|
3307
|
+
const attempt = async (url) => {
|
|
3308
|
+
try {
|
|
3309
|
+
const controller = new AbortController();
|
|
3310
|
+
const timeoutId = setTimeout(() => controller.abort(), args.timeoutMs);
|
|
3311
|
+
const response = await fetch(`${url}/models`, {
|
|
3312
|
+
headers: this.getHeaders(),
|
|
3313
|
+
signal: controller.signal
|
|
3314
|
+
});
|
|
3315
|
+
clearTimeout(timeoutId);
|
|
3316
|
+
return response.ok;
|
|
3317
|
+
} catch (error) {
|
|
3318
|
+
debugLogger.warn("BanditAI availability check failed", { url, error });
|
|
3319
|
+
return false;
|
|
3320
|
+
}
|
|
3321
|
+
};
|
|
3322
|
+
const primary = await attempt(this.baseUrl);
|
|
3323
|
+
if (primary) {
|
|
3324
|
+
return { url: this.baseUrl, isAvailable: true };
|
|
3325
|
+
}
|
|
3326
|
+
if (args.fallbackUrl) {
|
|
3327
|
+
const fallback = args.fallbackUrl.replace(/\/$/, "");
|
|
3328
|
+
if (await attempt(fallback)) {
|
|
3329
|
+
this.baseUrl = fallback;
|
|
3330
|
+
return { url: fallback, isAvailable: true };
|
|
3331
|
+
}
|
|
3332
|
+
}
|
|
3333
|
+
return { url: this.baseUrl, isAvailable: false };
|
|
3334
|
+
}
|
|
3335
|
+
getProviderType() {
|
|
3336
|
+
return "bandit" /* BANDIT */;
|
|
3337
|
+
}
|
|
3338
|
+
getConfig() {
|
|
3339
|
+
return this.config;
|
|
3340
|
+
}
|
|
3341
|
+
streamChatRequest(url, payload) {
|
|
3342
|
+
return new import_rxjs10.Observable((observer) => {
|
|
3343
|
+
const task = fetch(url, {
|
|
3344
|
+
method: "POST",
|
|
3345
|
+
headers: {
|
|
3346
|
+
...this.getHeaders(),
|
|
3347
|
+
"Content-Type": "application/json"
|
|
3348
|
+
},
|
|
3349
|
+
body: JSON.stringify(payload)
|
|
3350
|
+
});
|
|
3351
|
+
task.then((response) => {
|
|
3352
|
+
if (!response.ok) {
|
|
3353
|
+
observer.error(new Error(`BanditAI request failed: ${response.status}`));
|
|
3354
|
+
return;
|
|
3355
|
+
}
|
|
3356
|
+
const reader = response.body?.getReader();
|
|
3357
|
+
const decoder = new TextDecoder();
|
|
3358
|
+
let buffer = "";
|
|
3359
|
+
const read = () => {
|
|
3360
|
+
reader?.read().then(({ done, value }) => {
|
|
3361
|
+
if (done) {
|
|
3362
|
+
observer.next({ message: { content: "", role: "assistant" }, done: true });
|
|
3363
|
+
observer.complete();
|
|
3364
|
+
return;
|
|
3365
|
+
}
|
|
3366
|
+
buffer += decoder.decode(value, { stream: true });
|
|
3367
|
+
const lines = buffer.split("\n");
|
|
3368
|
+
buffer = lines.pop() ?? "";
|
|
3369
|
+
for (const rawLine of lines) {
|
|
3370
|
+
const line = rawLine.trim();
|
|
3371
|
+
if (!line.startsWith("data: ")) {
|
|
3372
|
+
continue;
|
|
3373
|
+
}
|
|
3374
|
+
const data = line.slice(6).trim();
|
|
3375
|
+
if (data === "[DONE]") {
|
|
3376
|
+
observer.next({ message: { content: "", role: "assistant" }, done: true });
|
|
3377
|
+
observer.complete();
|
|
3378
|
+
return;
|
|
3379
|
+
}
|
|
3380
|
+
try {
|
|
3381
|
+
const parsed = JSON.parse(data);
|
|
3382
|
+
const content = parsed.choices?.[0]?.delta?.content ?? "";
|
|
3383
|
+
if (content) {
|
|
3384
|
+
observer.next({ message: { content, role: "assistant" }, done: false });
|
|
3385
|
+
}
|
|
3386
|
+
} catch (error) {
|
|
3387
|
+
debugLogger.error("BanditAI stream chunk parse failure", { data, error });
|
|
3388
|
+
}
|
|
3389
|
+
}
|
|
3390
|
+
read();
|
|
3391
|
+
}).catch((err) => observer.error(err));
|
|
3392
|
+
};
|
|
3393
|
+
read();
|
|
3394
|
+
}).catch((err) => observer.error(err));
|
|
3395
|
+
});
|
|
3396
|
+
}
|
|
3397
|
+
nonStreamChatRequest(url, payload) {
|
|
3398
|
+
return (0, import_rxjs10.from)(fetch(url, {
|
|
3399
|
+
method: "POST",
|
|
3400
|
+
headers: {
|
|
3401
|
+
...this.getHeaders(),
|
|
3402
|
+
"Content-Type": "application/json"
|
|
3403
|
+
},
|
|
3404
|
+
body: JSON.stringify(payload)
|
|
3405
|
+
})).pipe(
|
|
3406
|
+
(0, import_rxjs10.switchMap)((response) => {
|
|
3407
|
+
if (!response.ok) {
|
|
3408
|
+
return (0, import_rxjs10.throwError)(() => new Error(`BanditAI request failed: ${response.status}`));
|
|
3409
|
+
}
|
|
3410
|
+
return (0, import_rxjs10.from)(response.json());
|
|
3411
|
+
}),
|
|
3412
|
+
(0, import_rxjs10.map)((data) => ({
|
|
3413
|
+
message: {
|
|
3414
|
+
content: data.choices?.[0]?.message?.content ?? "",
|
|
3415
|
+
role: "assistant"
|
|
3416
|
+
},
|
|
3417
|
+
done: true
|
|
3418
|
+
}))
|
|
3419
|
+
);
|
|
3420
|
+
}
|
|
3421
|
+
getHeaders() {
|
|
3422
|
+
const headers = {};
|
|
3423
|
+
if (this.config.apiKey) {
|
|
3424
|
+
headers["Authorization"] = `Bearer ${this.config.apiKey}`;
|
|
3425
|
+
}
|
|
3426
|
+
return headers;
|
|
3427
|
+
}
|
|
3428
|
+
};
|
|
3429
|
+
}
|
|
3430
|
+
});
|
|
3431
|
+
|
|
3016
3432
|
// src/services/ai-provider/ai-provider.factory.ts
|
|
3017
3433
|
var AIProviderFactory;
|
|
3018
3434
|
var init_ai_provider_factory = __esm({
|
|
@@ -3026,6 +3442,7 @@ var init_ai_provider_factory = __esm({
|
|
|
3026
3442
|
init_gateway_provider();
|
|
3027
3443
|
init_playground_provider();
|
|
3028
3444
|
init_xai_provider();
|
|
3445
|
+
init_bandit_ai_provider();
|
|
3029
3446
|
AIProviderFactory = class {
|
|
3030
3447
|
static createProvider(config) {
|
|
3031
3448
|
switch (config.type) {
|
|
@@ -3039,6 +3456,8 @@ var init_ai_provider_factory = __esm({
|
|
|
3039
3456
|
return new AnthropicProvider(config);
|
|
3040
3457
|
case "xai" /* XAI */:
|
|
3041
3458
|
return new XAIProvider(config);
|
|
3459
|
+
case "bandit" /* BANDIT */:
|
|
3460
|
+
return new BanditAIProvider(config);
|
|
3042
3461
|
case "gateway" /* GATEWAY */:
|
|
3043
3462
|
return new GatewayProvider(config);
|
|
3044
3463
|
case "playground" /* PLAYGROUND */:
|
|
@@ -3053,6 +3472,7 @@ var init_ai_provider_factory = __esm({
|
|
|
3053
3472
|
"openai" /* OPENAI */,
|
|
3054
3473
|
"azure-openai" /* AZURE_OPENAI */,
|
|
3055
3474
|
"xai" /* XAI */,
|
|
3475
|
+
"bandit" /* BANDIT */,
|
|
3056
3476
|
"gateway" /* GATEWAY */,
|
|
3057
3477
|
"playground" /* PLAYGROUND */
|
|
3058
3478
|
];
|
|
@@ -3070,6 +3490,8 @@ var init_ai_provider_factory = __esm({
|
|
|
3070
3490
|
return !!config.apiKey;
|
|
3071
3491
|
case "xai" /* XAI */:
|
|
3072
3492
|
return !!config.apiKey;
|
|
3493
|
+
case "bandit" /* BANDIT */:
|
|
3494
|
+
return !!config.apiKey;
|
|
3073
3495
|
case "gateway" /* GATEWAY */:
|
|
3074
3496
|
return !!(config.gatewayUrl && config.provider);
|
|
3075
3497
|
case "playground" /* PLAYGROUND */:
|
|
@@ -3445,11 +3867,11 @@ var init_notificationService = __esm({
|
|
|
3445
3867
|
});
|
|
3446
3868
|
|
|
3447
3869
|
// src/services/prompts/conversationStarters.ts
|
|
3448
|
-
var
|
|
3870
|
+
var import_rxjs11, generateConversationStarters;
|
|
3449
3871
|
var init_conversationStarters = __esm({
|
|
3450
3872
|
"src/services/prompts/conversationStarters.ts"() {
|
|
3451
3873
|
"use strict";
|
|
3452
|
-
|
|
3874
|
+
import_rxjs11 = require("rxjs");
|
|
3453
3875
|
init_aiProviderStore();
|
|
3454
3876
|
init_packageSettingsStore();
|
|
3455
3877
|
init_getStableQuestionPrompt();
|
|
@@ -3470,7 +3892,7 @@ var init_conversationStarters = __esm({
|
|
|
3470
3892
|
stream: false,
|
|
3471
3893
|
options: { temperature: 1.5, num_predict: 250 }
|
|
3472
3894
|
});
|
|
3473
|
-
const questions$ = data$.pipe((0,
|
|
3895
|
+
const questions$ = data$.pipe((0, import_rxjs11.map)((d) => {
|
|
3474
3896
|
const sanitizeLine = (line) => {
|
|
3475
3897
|
const withoutNumbering = line.replace(/^[0-9]+[.)\-\s:]+/, "").replace(/^[•*+-]\s+/, "");
|
|
3476
3898
|
const withoutQuotes = withoutNumbering.replace(/^[“"']+/, "").replace(/[”"']+$/, "");
|
|
@@ -3492,7 +3914,7 @@ var init_conversationStarters = __esm({
|
|
|
3492
3914
|
});
|
|
3493
3915
|
return unique;
|
|
3494
3916
|
}));
|
|
3495
|
-
const starters = await (0,
|
|
3917
|
+
const starters = await (0, import_rxjs11.lastValueFrom)(questions$);
|
|
3496
3918
|
if (starters.length === 0) {
|
|
3497
3919
|
debugLogger.warn("No meaningful conversation starters generated");
|
|
3498
3920
|
return [];
|
|
@@ -3508,11 +3930,11 @@ var init_conversationStarters = __esm({
|
|
|
3508
3930
|
});
|
|
3509
3931
|
|
|
3510
3932
|
// src/services/prompts/moodDetection.ts
|
|
3511
|
-
var
|
|
3933
|
+
var import_rxjs12, detectMessageMood;
|
|
3512
3934
|
var init_moodDetection = __esm({
|
|
3513
3935
|
"src/services/prompts/moodDetection.ts"() {
|
|
3514
3936
|
"use strict";
|
|
3515
|
-
|
|
3937
|
+
import_rxjs12 = require("rxjs");
|
|
3516
3938
|
init_aiProviderStore();
|
|
3517
3939
|
init_packageSettingsStore();
|
|
3518
3940
|
init_debugLogger();
|
|
@@ -3543,8 +3965,8 @@ Response:`;
|
|
|
3543
3965
|
options: { temperature: 0.3, num_predict: 10 }
|
|
3544
3966
|
});
|
|
3545
3967
|
const chunks$ = response$.pipe(
|
|
3546
|
-
(0,
|
|
3547
|
-
(0,
|
|
3968
|
+
(0, import_rxjs12.map)((chunk) => chunk.response.trim().toLowerCase()),
|
|
3969
|
+
(0, import_rxjs12.toArray)()
|
|
3548
3970
|
);
|
|
3549
3971
|
const result = await chunks$.toPromise();
|
|
3550
3972
|
const finalResult = (result || []).join("").trim();
|
|
@@ -3561,11 +3983,11 @@ Response:`;
|
|
|
3561
3983
|
});
|
|
3562
3984
|
|
|
3563
3985
|
// src/services/prompts/detectUserInterestAndExcitement.ts
|
|
3564
|
-
var
|
|
3986
|
+
var import_rxjs13, detectUserInterestAndExcitement;
|
|
3565
3987
|
var init_detectUserInterestAndExcitement = __esm({
|
|
3566
3988
|
"src/services/prompts/detectUserInterestAndExcitement.ts"() {
|
|
3567
3989
|
"use strict";
|
|
3568
|
-
|
|
3990
|
+
import_rxjs13 = require("rxjs");
|
|
3569
3991
|
init_aiProviderStore();
|
|
3570
3992
|
init_packageSettingsStore();
|
|
3571
3993
|
init_debugLogger();
|
|
@@ -3612,10 +4034,10 @@ var init_detectUserInterestAndExcitement = __esm({
|
|
|
3612
4034
|
options: { temperature: 0.1, num_predict: 5 }
|
|
3613
4035
|
});
|
|
3614
4036
|
const chunks$ = response$.pipe(
|
|
3615
|
-
(0,
|
|
3616
|
-
(0,
|
|
4037
|
+
(0, import_rxjs13.map)((chunk) => chunk.response.trim().toUpperCase()),
|
|
4038
|
+
(0, import_rxjs13.toArray)()
|
|
3617
4039
|
);
|
|
3618
|
-
const result = await (0,
|
|
4040
|
+
const result = await (0, import_rxjs13.lastValueFrom)(chunks$);
|
|
3619
4041
|
const decision = result.join("").trim();
|
|
3620
4042
|
debugLogger.llmDebug("detectUserInterestAndExcitement result", { decision });
|
|
3621
4043
|
return decision.includes("YES");
|
|
@@ -3628,11 +4050,11 @@ var init_detectUserInterestAndExcitement = __esm({
|
|
|
3628
4050
|
});
|
|
3629
4051
|
|
|
3630
4052
|
// src/services/prompts/documentSummarization.ts
|
|
3631
|
-
var
|
|
4053
|
+
var import_rxjs14, summarizeDocument;
|
|
3632
4054
|
var init_documentSummarization = __esm({
|
|
3633
4055
|
"src/services/prompts/documentSummarization.ts"() {
|
|
3634
4056
|
"use strict";
|
|
3635
|
-
|
|
4057
|
+
import_rxjs14 = require("rxjs");
|
|
3636
4058
|
init_aiProviderStore();
|
|
3637
4059
|
init_packageSettingsStore();
|
|
3638
4060
|
init_debugLogger();
|
|
@@ -3660,8 +4082,8 @@ ${content.slice(0, 4e3)}
|
|
|
3660
4082
|
stream: false,
|
|
3661
4083
|
options: { temperature: 0.3, num_predict: 100 }
|
|
3662
4084
|
});
|
|
3663
|
-
const summary$ = data$.pipe((0,
|
|
3664
|
-
const summary = await (0,
|
|
4085
|
+
const summary$ = data$.pipe((0, import_rxjs14.map)((d) => d.response.trim()));
|
|
4086
|
+
const summary = await (0, import_rxjs14.lastValueFrom)(summary$);
|
|
3665
4087
|
debugLogger.ragDebug("summarizeDocument result", { name, summary });
|
|
3666
4088
|
return summary || `Document summary for ${name}`;
|
|
3667
4089
|
} catch (error) {
|
|
@@ -3673,11 +4095,11 @@ ${content.slice(0, 4e3)}
|
|
|
3673
4095
|
});
|
|
3674
4096
|
|
|
3675
4097
|
// src/services/prompts/documentRelevance.ts
|
|
3676
|
-
var
|
|
4098
|
+
var import_rxjs15, determineRelevantDocuments;
|
|
3677
4099
|
var init_documentRelevance = __esm({
|
|
3678
4100
|
"src/services/prompts/documentRelevance.ts"() {
|
|
3679
4101
|
"use strict";
|
|
3680
|
-
|
|
4102
|
+
import_rxjs15 = require("rxjs");
|
|
3681
4103
|
init_aiProviderStore();
|
|
3682
4104
|
init_packageSettingsStore();
|
|
3683
4105
|
init_debugLogger();
|
|
@@ -3718,10 +4140,10 @@ Response:`;
|
|
|
3718
4140
|
options: { temperature: 0.2, num_predict: 50 }
|
|
3719
4141
|
});
|
|
3720
4142
|
const chunks$ = response$.pipe(
|
|
3721
|
-
(0,
|
|
3722
|
-
(0,
|
|
4143
|
+
(0, import_rxjs15.map)((chunk) => chunk.response.trim()),
|
|
4144
|
+
(0, import_rxjs15.toArray)()
|
|
3723
4145
|
);
|
|
3724
|
-
const result = await (0,
|
|
4146
|
+
const result = await (0, import_rxjs15.lastValueFrom)(chunks$);
|
|
3725
4147
|
const vetResult = result.join("").trim().toLowerCase();
|
|
3726
4148
|
debugLogger.ragDebug("determineRelevantDocuments result", { vetResult });
|
|
3727
4149
|
if (vetResult.includes("none") || !vetResult) {
|
|
@@ -7106,13 +7528,17 @@ var init_conversationStore = __esm({
|
|
|
7106
7528
|
const updatedConversations = conversations.map((c) => {
|
|
7107
7529
|
if (c.id === currentId && c.history.length > 0) {
|
|
7108
7530
|
const updatedHistory = [...c.history];
|
|
7531
|
+
const existingImages = updatedHistory[updatedHistory.length - 1].images;
|
|
7532
|
+
const nextImages = Array.isArray(images) && images.length > 0 ? [...images] : Array.isArray(existingImages) && existingImages.length > 0 ? [...existingImages] : existingImages;
|
|
7109
7533
|
updatedHistory[updatedHistory.length - 1] = {
|
|
7110
7534
|
...updatedHistory[updatedHistory.length - 1],
|
|
7111
7535
|
answer,
|
|
7112
7536
|
memoryUpdated,
|
|
7113
|
-
images:
|
|
7537
|
+
images: nextImages,
|
|
7114
7538
|
sourceFiles: sourceFiles ?? updatedHistory[updatedHistory.length - 1].sourceFiles,
|
|
7115
|
-
cancelled: cancelled ?? updatedHistory[updatedHistory.length - 1].cancelled
|
|
7539
|
+
cancelled: cancelled ?? updatedHistory[updatedHistory.length - 1].cancelled,
|
|
7540
|
+
placeholder: false,
|
|
7541
|
+
rawQuestion: void 0
|
|
7116
7542
|
};
|
|
7117
7543
|
return normalizeConversation({ ...c, history: updatedHistory, updatedAt: /* @__PURE__ */ new Date() });
|
|
7118
7544
|
}
|
|
@@ -7193,6 +7619,24 @@ var init_conversationStore = __esm({
|
|
|
7193
7619
|
});
|
|
7194
7620
|
continue;
|
|
7195
7621
|
}
|
|
7622
|
+
if (Array.isArray(existing.history) && Array.isArray(conversation.history)) {
|
|
7623
|
+
const mergedHistory = conversation.history.map((incomingEntry, index) => {
|
|
7624
|
+
const existingEntry = existing.history[index];
|
|
7625
|
+
if (!existingEntry) {
|
|
7626
|
+
return incomingEntry;
|
|
7627
|
+
}
|
|
7628
|
+
const mergedImagesSource = Array.isArray(incomingEntry.images) && incomingEntry.images.length > 0 ? incomingEntry.images : existingEntry.images;
|
|
7629
|
+
const mergedImages = Array.isArray(mergedImagesSource) && mergedImagesSource.length > 0 ? [...mergedImagesSource] : mergedImagesSource;
|
|
7630
|
+
return {
|
|
7631
|
+
...existingEntry,
|
|
7632
|
+
...incomingEntry,
|
|
7633
|
+
images: mergedImages,
|
|
7634
|
+
placeholder: incomingEntry.placeholder ?? existingEntry.placeholder,
|
|
7635
|
+
rawQuestion: incomingEntry.rawQuestion ?? existingEntry.rawQuestion
|
|
7636
|
+
};
|
|
7637
|
+
});
|
|
7638
|
+
conversation.history = mergedHistory;
|
|
7639
|
+
}
|
|
7196
7640
|
}
|
|
7197
7641
|
next.set(conversation.id, conversation);
|
|
7198
7642
|
toPersist.push(conversation);
|
|
@@ -11005,11 +11449,11 @@ var init_ttsSanitizer = __esm({
|
|
|
11005
11449
|
});
|
|
11006
11450
|
|
|
11007
11451
|
// src/services/tts/tts-client.ts
|
|
11008
|
-
var
|
|
11452
|
+
var import_rxjs16, getOrAppendAuthHeader;
|
|
11009
11453
|
var init_tts_client = __esm({
|
|
11010
11454
|
"src/services/tts/tts-client.ts"() {
|
|
11011
11455
|
"use strict";
|
|
11012
|
-
|
|
11456
|
+
import_rxjs16 = require("rxjs");
|
|
11013
11457
|
init_authenticationService();
|
|
11014
11458
|
init_voiceStore();
|
|
11015
11459
|
init_ttsSanitizer();
|
|
@@ -11029,11 +11473,11 @@ var init_tts_client = __esm({
|
|
|
11029
11473
|
});
|
|
11030
11474
|
|
|
11031
11475
|
// src/services/tts/streaming-tts.ts
|
|
11032
|
-
var
|
|
11476
|
+
var import_rxjs17, StreamingTTSClient, getStreamingTTSClient, speakStream, stopTTS;
|
|
11033
11477
|
var init_streaming_tts = __esm({
|
|
11034
11478
|
"src/services/tts/streaming-tts.ts"() {
|
|
11035
11479
|
"use strict";
|
|
11036
|
-
|
|
11480
|
+
import_rxjs17 = require("rxjs");
|
|
11037
11481
|
init_debugLogger();
|
|
11038
11482
|
init_packageSettingsStore();
|
|
11039
11483
|
init_tts_client();
|
|
@@ -11045,8 +11489,8 @@ var init_streaming_tts = __esm({
|
|
|
11045
11489
|
// Store event handler references for proper cleanup
|
|
11046
11490
|
audioHandlers = /* @__PURE__ */ new Map();
|
|
11047
11491
|
// State management
|
|
11048
|
-
stateSubject = new
|
|
11049
|
-
progressSubject = new
|
|
11492
|
+
stateSubject = new import_rxjs17.BehaviorSubject("IDLE" /* IDLE */);
|
|
11493
|
+
progressSubject = new import_rxjs17.Subject();
|
|
11050
11494
|
constructor() {
|
|
11051
11495
|
}
|
|
11052
11496
|
static getInstance() {
|
|
@@ -11077,7 +11521,7 @@ var init_streaming_tts = __esm({
|
|
|
11077
11521
|
* Speak text with simple streaming
|
|
11078
11522
|
*/
|
|
11079
11523
|
speakStream(text, voice, options = {}) {
|
|
11080
|
-
return new
|
|
11524
|
+
return new import_rxjs17.Observable((subscriber) => {
|
|
11081
11525
|
this.performSimpleStreaming(text, voice, options, subscriber);
|
|
11082
11526
|
});
|
|
11083
11527
|
}
|
|
@@ -18799,6 +19243,8 @@ var init_chat_scroll_to_bottom_button = __esm({
|
|
|
18799
19243
|
drawerOpen = false,
|
|
18800
19244
|
isMobile = false
|
|
18801
19245
|
}) => {
|
|
19246
|
+
const verticalBuffer = isMobile ? 36 : 56;
|
|
19247
|
+
const bottomOffset = Math.max(inputHeight + verticalBuffer, verticalBuffer + 72);
|
|
18802
19248
|
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
18803
19249
|
import_material28.IconButton,
|
|
18804
19250
|
{
|
|
@@ -18807,12 +19253,12 @@ var init_chat_scroll_to_bottom_button = __esm({
|
|
|
18807
19253
|
position: "fixed",
|
|
18808
19254
|
left: drawerOpen && !isMobile ? "calc(50% + 170px)" : "50%",
|
|
18809
19255
|
transform: "translateX(-50%)",
|
|
18810
|
-
bottom:
|
|
19256
|
+
bottom: bottomOffset,
|
|
18811
19257
|
bgcolor: (theme) => theme.palette.background.paper,
|
|
18812
19258
|
color: (theme) => theme.palette.text.primary,
|
|
18813
19259
|
border: "1px solid",
|
|
18814
19260
|
borderColor: (theme) => theme.palette.divider,
|
|
18815
|
-
zIndex:
|
|
19261
|
+
zIndex: (theme) => Math.max(theme.zIndex.modal + 1, 1400),
|
|
18816
19262
|
boxShadow: 3,
|
|
18817
19263
|
transition: "bottom 0.3s ease, left 0.3s ease-in-out",
|
|
18818
19264
|
"&:hover": {
|
|
@@ -19474,28 +19920,28 @@ var init_create_audio_blob = __esm({
|
|
|
19474
19920
|
});
|
|
19475
19921
|
|
|
19476
19922
|
// src/services/stt/sound-recorder.service.ts
|
|
19477
|
-
var
|
|
19923
|
+
var import_rxjs21, SoundRecorderService;
|
|
19478
19924
|
var init_sound_recorder_service = __esm({
|
|
19479
19925
|
"src/services/stt/sound-recorder.service.ts"() {
|
|
19480
19926
|
"use strict";
|
|
19481
|
-
|
|
19927
|
+
import_rxjs21 = require("rxjs");
|
|
19482
19928
|
init_create_audio_blob();
|
|
19483
19929
|
SoundRecorderService = class {
|
|
19484
19930
|
_mediaRecorder;
|
|
19485
19931
|
start() {
|
|
19486
|
-
const mediaStream = (0,
|
|
19487
|
-
this._mediaRecorder = mediaStream.pipe((0,
|
|
19932
|
+
const mediaStream = (0, import_rxjs21.from)(navigator.mediaDevices.getUserMedia({ audio: true }));
|
|
19933
|
+
this._mediaRecorder = mediaStream.pipe((0, import_rxjs21.map)((stream) => {
|
|
19488
19934
|
const rec = new MediaRecorder(stream);
|
|
19489
19935
|
rec.start();
|
|
19490
19936
|
return rec;
|
|
19491
|
-
}), (0,
|
|
19937
|
+
}), (0, import_rxjs21.shareReplay)(1));
|
|
19492
19938
|
const dataAvailableEvent = this._mediaRecorder.pipe(
|
|
19493
|
-
(0,
|
|
19939
|
+
(0, import_rxjs21.switchMap)((recorder) => (0, import_rxjs21.fromEvent)(recorder, "dataavailable"))
|
|
19494
19940
|
);
|
|
19495
19941
|
const blob = dataAvailableEvent.pipe(
|
|
19496
|
-
(0,
|
|
19497
|
-
(0,
|
|
19498
|
-
(0,
|
|
19942
|
+
(0, import_rxjs21.first)(),
|
|
19943
|
+
(0, import_rxjs21.map)((event) => createAudioBlob(event.data)),
|
|
19944
|
+
(0, import_rxjs21.shareReplay)(1)
|
|
19499
19945
|
);
|
|
19500
19946
|
return blob;
|
|
19501
19947
|
}
|
|
@@ -19503,7 +19949,7 @@ var init_sound_recorder_service = __esm({
|
|
|
19503
19949
|
if (!this._mediaRecorder) {
|
|
19504
19950
|
return;
|
|
19505
19951
|
}
|
|
19506
|
-
this._mediaRecorder.pipe((0,
|
|
19952
|
+
this._mediaRecorder.pipe((0, import_rxjs21.first)()).subscribe((recorder) => {
|
|
19507
19953
|
recorder.stop();
|
|
19508
19954
|
});
|
|
19509
19955
|
}
|
|
@@ -19623,7 +20069,7 @@ var init_stt_client = __esm({
|
|
|
19623
20069
|
});
|
|
19624
20070
|
|
|
19625
20071
|
// src/services/stt/transcriber.tsx
|
|
19626
|
-
var import_react38, import_Mic, import_Check6, import_Close7, import_material31,
|
|
20072
|
+
var import_react38, import_Mic, import_Check6, import_Close7, import_material31, import_rxjs22, import_jsx_runtime31, initialButtonStyles, Transcriber, transcriber_default;
|
|
19627
20073
|
var init_transcriber = __esm({
|
|
19628
20074
|
"src/services/stt/transcriber.tsx"() {
|
|
19629
20075
|
"use strict";
|
|
@@ -19634,7 +20080,7 @@ var init_transcriber = __esm({
|
|
|
19634
20080
|
init_sound_recorder_service();
|
|
19635
20081
|
init_stt_client();
|
|
19636
20082
|
import_material31 = require("@mui/material");
|
|
19637
|
-
|
|
20083
|
+
import_rxjs22 = require("rxjs");
|
|
19638
20084
|
init_debugLogger();
|
|
19639
20085
|
import_jsx_runtime31 = require("react/jsx-runtime");
|
|
19640
20086
|
initialButtonStyles = (badgeBackground, fileText, hoverBadgeBackground) => ({
|
|
@@ -19653,14 +20099,14 @@ var init_transcriber = __esm({
|
|
|
19653
20099
|
const [status, setStatus] = (0, import_react38.useState)("IDLE");
|
|
19654
20100
|
const recorderRef = (0, import_react38.useRef)(new SoundRecorderService());
|
|
19655
20101
|
const [iconButtonStyles] = (0, import_react38.useState)(() => initialButtonStyles(badgeBackground, fileText, hoverBadgeBackground));
|
|
19656
|
-
const [recordingSub, setRecordingSub] = (0, import_react38.useState)(() => new
|
|
20102
|
+
const [recordingSub, setRecordingSub] = (0, import_react38.useState)(() => new import_rxjs22.Subscription());
|
|
19657
20103
|
const start = () => {
|
|
19658
20104
|
recordingSub.unsubscribe();
|
|
19659
20105
|
const recording = recorderRef.current.start();
|
|
19660
20106
|
const text = recording.pipe(
|
|
19661
|
-
(0,
|
|
20107
|
+
(0, import_rxjs22.switchMap)((blob) => {
|
|
19662
20108
|
debugLogger.debug("Processing audio blob for transcription");
|
|
19663
|
-
return (0,
|
|
20109
|
+
return (0, import_rxjs22.from)(STTClient.transcribe(blob));
|
|
19664
20110
|
})
|
|
19665
20111
|
);
|
|
19666
20112
|
const sub = text.subscribe({
|
|
@@ -20532,11 +20978,11 @@ ${sanitize(
|
|
|
20532
20978
|
});
|
|
20533
20979
|
|
|
20534
20980
|
// src/chat/hooks/useMemoryEnhancer.tsx
|
|
20535
|
-
var
|
|
20981
|
+
var import_rxjs23, MEMORY_LIMIT, MIN_MEMORY_WORDS, MERGE_THRESHOLD, REJECT_ECHO_THRESHOLD, REJECT_DUPLICATE_THRESHOLD, CONTEXTUAL_DIVERGENCE_THRESHOLD, normalizeText, isStructurallyDuplicate, isAboutBandit, hasEngagementValue, isMemoryTooShortOrGeneric, isPersonalText, mergeMemory, isVoiceShifted, sanitizeMemory, sanitizeMemoryText, shouldAcceptMemory, isContextuallyDivergent, useMemoryEnhancer;
|
|
20536
20982
|
var init_useMemoryEnhancer = __esm({
|
|
20537
20983
|
"src/chat/hooks/useMemoryEnhancer.tsx"() {
|
|
20538
20984
|
"use strict";
|
|
20539
|
-
|
|
20985
|
+
import_rxjs23 = require("rxjs");
|
|
20540
20986
|
init_memoryStore();
|
|
20541
20987
|
init_aiProviderStore();
|
|
20542
20988
|
init_packageSettingsStore();
|
|
@@ -20928,8 +21374,8 @@ var init_useMemoryEnhancer = __esm({
|
|
|
20928
21374
|
stream: false,
|
|
20929
21375
|
options: { temperature: 0.1, num_predict: 150 }
|
|
20930
21376
|
});
|
|
20931
|
-
const suggestion = await (0,
|
|
20932
|
-
result$.pipe((0,
|
|
21377
|
+
const suggestion = await (0, import_rxjs23.lastValueFrom)(
|
|
21378
|
+
result$.pipe((0, import_rxjs23.map)((chunk) => chunk.response))
|
|
20933
21379
|
);
|
|
20934
21380
|
debugLogger.memoryDebug(`LLM memory suggestion received (${attempt})`, {
|
|
20935
21381
|
suggestion: typeof suggestion === "string" ? suggestion.slice(0, 200) : suggestion,
|
|
@@ -21620,10 +22066,22 @@ var init_useAIProvider = __esm({
|
|
|
21620
22066
|
setResponse("");
|
|
21621
22067
|
setStreamBuffer("");
|
|
21622
22068
|
clearFlushTimer();
|
|
21623
|
-
|
|
22069
|
+
const imageList = Array.isArray(images) ? [...images] : [];
|
|
22070
|
+
const conversationStoreState = useConversationStore.getState();
|
|
22071
|
+
const { addToCurrent, replaceLastAnswer, conversations, currentId } = conversationStoreState;
|
|
22072
|
+
const currentConv = conversations.find((c) => c.id === currentId);
|
|
22073
|
+
const lastEntry = currentConv?.history.at(-1);
|
|
22074
|
+
const lastWasPlaceholder = !!lastEntry && lastEntry.answer === "..." && (lastEntry.placeholder === true || lastEntry.rawQuestion === question || lastEntry.question === question);
|
|
22075
|
+
const pendingQuestion = lastWasPlaceholder ? lastEntry?.question ?? question : question;
|
|
22076
|
+
const pendingImagesRaw = lastWasPlaceholder && Array.isArray(lastEntry?.images) && lastEntry.images.length > 0 ? lastEntry.images : imageList;
|
|
22077
|
+
const pendingImages = Array.isArray(pendingImagesRaw) && pendingImagesRaw.length > 0 ? [...pendingImagesRaw] : void 0;
|
|
22078
|
+
setPendingMessage({
|
|
22079
|
+
question: pendingQuestion,
|
|
22080
|
+
images: pendingImages
|
|
22081
|
+
});
|
|
21624
22082
|
const modelName = usePackageSettingsStore.getState().settings?.defaultModel || "bandit-core:4b-it-qat";
|
|
21625
22083
|
const CONFIG = modelConfigs[modelName] ?? modelConfigs["bandit-core:4b-it-qat"];
|
|
21626
|
-
const base64Images =
|
|
22084
|
+
const base64Images = imageList.map((img) => img.split(",")[1]);
|
|
21627
22085
|
const latestEntries = history.slice(-CONFIG.historyMessages);
|
|
21628
22086
|
const contextMessages = latestEntries.flatMap((entry) => [
|
|
21629
22087
|
{ role: "user", content: entry.question },
|
|
@@ -22009,11 +22467,8 @@ ${protocol}`;
|
|
|
22009
22467
|
}, delay);
|
|
22010
22468
|
};
|
|
22011
22469
|
const stream = provider.chat(request);
|
|
22012
|
-
const
|
|
22013
|
-
|
|
22014
|
-
const lastEntry = currentConv?.history.at(-1);
|
|
22015
|
-
const isPlaceholder = lastEntry?.question === question && lastEntry?.answer === "...";
|
|
22016
|
-
lastPartialRef.current = { text: "", images, usedDocs, question };
|
|
22470
|
+
const initialPlaceholderQuestion = lastEntry?.question;
|
|
22471
|
+
lastPartialRef.current = { text: "", images: [...imageList], usedDocs, question };
|
|
22017
22472
|
if (currentSubRef.current) {
|
|
22018
22473
|
try {
|
|
22019
22474
|
currentSubRef.current.unsubscribe();
|
|
@@ -22272,14 +22727,24 @@ ${items.map((item, index) => {
|
|
|
22272
22727
|
} else {
|
|
22273
22728
|
debugLogger.info("Memory scan skipped - disabled in preferences");
|
|
22274
22729
|
}
|
|
22275
|
-
const
|
|
22276
|
-
const
|
|
22277
|
-
const conv = current.conversations.find((c) => c.id === current.currentId);
|
|
22730
|
+
const currentState = useConversationStore.getState();
|
|
22731
|
+
const conv = currentState.conversations.find((c) => c.id === currentState.currentId);
|
|
22278
22732
|
const last = conv?.history.at(-1);
|
|
22279
|
-
|
|
22280
|
-
|
|
22733
|
+
const lastIsPlaceholder = !!last && last.answer === "..." && last.placeholder !== false;
|
|
22734
|
+
const preservedImagesSource = imageList.length > 0 ? imageList : lastPartialRef.current.images.length > 0 ? lastPartialRef.current.images : last?.images;
|
|
22735
|
+
const preservedImages = Array.isArray(preservedImagesSource) && preservedImagesSource.length > 0 ? [...preservedImagesSource] : void 0;
|
|
22736
|
+
if (lastIsPlaceholder) {
|
|
22737
|
+
replaceLastAnswer(enhancedMessage, preservedImages, memoryUpdated, usedDocs);
|
|
22281
22738
|
} else {
|
|
22282
|
-
|
|
22739
|
+
const historyQuestion = last && last.answer === "..." && last.question || initialPlaceholderQuestion || question;
|
|
22740
|
+
addToCurrent({
|
|
22741
|
+
question: historyQuestion,
|
|
22742
|
+
answer: enhancedMessage,
|
|
22743
|
+
images: preservedImages,
|
|
22744
|
+
memoryUpdated,
|
|
22745
|
+
sourceFiles: usedDocs,
|
|
22746
|
+
rawQuestion: question
|
|
22747
|
+
});
|
|
22283
22748
|
}
|
|
22284
22749
|
setInputValue("");
|
|
22285
22750
|
setPastedImages([]);
|
|
@@ -26522,15 +26987,15 @@ var init_chat_app_bar = __esm({
|
|
|
26522
26987
|
});
|
|
26523
26988
|
|
|
26524
26989
|
// src/chat/hooks/useConversationNameGenerator.tsx
|
|
26525
|
-
var
|
|
26990
|
+
var import_rxjs24, import_operators6, useConversationNameGenerator;
|
|
26526
26991
|
var init_useConversationNameGenerator = __esm({
|
|
26527
26992
|
"src/chat/hooks/useConversationNameGenerator.tsx"() {
|
|
26528
26993
|
"use strict";
|
|
26529
26994
|
init_aiProviderStore();
|
|
26530
26995
|
init_packageSettingsStore();
|
|
26531
26996
|
init_debugLogger();
|
|
26532
|
-
|
|
26533
|
-
|
|
26997
|
+
import_rxjs24 = require("rxjs");
|
|
26998
|
+
import_operators6 = require("rxjs/operators");
|
|
26534
26999
|
init_conversationStore();
|
|
26535
27000
|
useConversationNameGenerator = () => {
|
|
26536
27001
|
const generateName = async (userMessage) => {
|
|
@@ -26565,8 +27030,8 @@ Respond with just the title and nothing else.
|
|
|
26565
27030
|
num_predict: 20
|
|
26566
27031
|
}
|
|
26567
27032
|
});
|
|
26568
|
-
const title = await (0,
|
|
26569
|
-
result$.pipe((0,
|
|
27033
|
+
const title = await (0, import_rxjs24.lastValueFrom)(
|
|
27034
|
+
result$.pipe((0, import_operators6.map)((d) => d.response?.trim().replace(/["']/g, "")))
|
|
26570
27035
|
);
|
|
26571
27036
|
if (title && title.length > 0) {
|
|
26572
27037
|
const sanitizedTitle = sanitizeConversationName(title, 60);
|
|
@@ -27846,12 +28311,20 @@ var init_chat2 = __esm({
|
|
|
27846
28311
|
(question, images, displayQuestion) => {
|
|
27847
28312
|
const requestStartTime = trackRequestStart();
|
|
27848
28313
|
const questionForDisplay = displayQuestion || question;
|
|
27849
|
-
|
|
28314
|
+
const pendingImages = images.length > 0 ? [...images] : void 0;
|
|
28315
|
+
setPendingMessage({ question: questionForDisplay, images: pendingImages });
|
|
27850
28316
|
setIsStreaming(true);
|
|
27851
28317
|
setResponseStarted(true);
|
|
27852
28318
|
setStreamBuffer("");
|
|
27853
28319
|
const { addToCurrent } = useConversationStore.getState();
|
|
27854
|
-
|
|
28320
|
+
const placeholderImages = pendingImages ? [...pendingImages] : void 0;
|
|
28321
|
+
addToCurrent({
|
|
28322
|
+
question: questionForDisplay,
|
|
28323
|
+
answer: "...",
|
|
28324
|
+
images: placeholderImages,
|
|
28325
|
+
placeholder: true,
|
|
28326
|
+
rawQuestion: question
|
|
28327
|
+
});
|
|
27855
28328
|
const getCurrentModel = useModelStore.getState().getCurrentModel;
|
|
27856
28329
|
const systemPrompt = getCurrentModel()?.systemPrompt ?? "You are a helpful assistant.";
|
|
27857
28330
|
const { currentId: currentId2, conversations: conversations2, createConversation, renameConversation } = useConversationStore.getState();
|
|
@@ -27865,8 +28338,16 @@ var init_chat2 = __esm({
|
|
|
27865
28338
|
if (!newCurrentId) return;
|
|
27866
28339
|
setResponse("");
|
|
27867
28340
|
const { addToCurrent: addToNew } = useConversationStore.getState();
|
|
27868
|
-
|
|
27869
|
-
|
|
28341
|
+
const newPlaceholderImages = pendingImages ? [...pendingImages] : void 0;
|
|
28342
|
+
addToNew({
|
|
28343
|
+
question: questionForDisplay,
|
|
28344
|
+
answer: "...",
|
|
28345
|
+
images: newPlaceholderImages,
|
|
28346
|
+
placeholder: true,
|
|
28347
|
+
rawQuestion: question
|
|
28348
|
+
});
|
|
28349
|
+
const providerImages2 = pendingImages ? [...pendingImages] : [];
|
|
28350
|
+
aiProvider(systemPrompt, question, providerImages2);
|
|
27870
28351
|
}, 0);
|
|
27871
28352
|
});
|
|
27872
28353
|
return;
|
|
@@ -27916,7 +28397,8 @@ var init_chat2 = __esm({
|
|
|
27916
28397
|
}, 50);
|
|
27917
28398
|
}
|
|
27918
28399
|
setResponse("");
|
|
27919
|
-
|
|
28400
|
+
const providerImages = pendingImages ? [...pendingImages] : [];
|
|
28401
|
+
aiProvider(systemPrompt, question, providerImages);
|
|
27920
28402
|
},
|
|
27921
28403
|
[
|
|
27922
28404
|
aiProvider,
|
|
@@ -28750,7 +29232,7 @@ init_modelStore();
|
|
|
28750
29232
|
init_ai_response_text_field();
|
|
28751
29233
|
init_memory_modal();
|
|
28752
29234
|
init_streaming_tts();
|
|
28753
|
-
var
|
|
29235
|
+
var import_rxjs18 = require("rxjs");
|
|
28754
29236
|
init_debugLogger();
|
|
28755
29237
|
init_util();
|
|
28756
29238
|
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
@@ -28779,7 +29261,7 @@ var AIQueriesDrawer = ({ drawerOpen, onClose, onClearComplete, onNavigateToMain
|
|
|
28779
29261
|
const [memoryModalOpen, setMemoryModalOpen] = (0, import_react15.useState)(false);
|
|
28780
29262
|
const [contextMode, setContextMode] = (0, import_react15.useState)("local");
|
|
28781
29263
|
const [expandedSections, setExpandedSections] = (0, import_react15.useState)(/* @__PURE__ */ new Set(["history", "voice"]));
|
|
28782
|
-
const [audioSub, setAudioSub] = (0, import_react15.useState)(new
|
|
29264
|
+
const [audioSub, setAudioSub] = (0, import_react15.useState)(new import_rxjs18.Subscription());
|
|
28783
29265
|
const [isContextSwitching, setIsContextSwitching] = (0, import_react15.useState)(false);
|
|
28784
29266
|
const [isDrawerLoading, setIsDrawerLoading] = (0, import_react15.useState)(false);
|
|
28785
29267
|
(0, import_react15.useEffect)(() => {
|
|
@@ -30442,7 +30924,7 @@ init_debugLogger();
|
|
|
30442
30924
|
init_banditTheme();
|
|
30443
30925
|
init_themeMap();
|
|
30444
30926
|
init_useTTS();
|
|
30445
|
-
var
|
|
30927
|
+
var import_rxjs19 = require("rxjs");
|
|
30446
30928
|
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
30447
30929
|
var FULL_SCREEN_THRESHOLD = 100;
|
|
30448
30930
|
var CDN_BASE = "https://cdn.burtson.ai/";
|
|
@@ -30509,7 +30991,7 @@ var ChatModal = ({
|
|
|
30509
30991
|
const [modalLogo, setModalLogo] = (0, import_react22.useState)("https://cdn.burtson.ai/logos/bandit-ai-logo.png");
|
|
30510
30992
|
const [modelAnchorEl, setModelAnchorEl] = (0, import_react22.useState)(null);
|
|
30511
30993
|
const [voiceAnchorEl, setVoiceAnchorEl] = (0, import_react22.useState)(null);
|
|
30512
|
-
const [audioSub, setAudioSub] = (0, import_react22.useState)(new
|
|
30994
|
+
const [audioSub, setAudioSub] = (0, import_react22.useState)(new import_rxjs19.Subscription());
|
|
30513
30995
|
const [selectedTheme, setSelectedTheme] = (0, import_react22.useState)(null);
|
|
30514
30996
|
const [themeLoading, setThemeLoading] = (0, import_react22.useState)(true);
|
|
30515
30997
|
const [autoFullscreenTriggered, setAutoFullscreenTriggered] = (0, import_react22.useState)(false);
|
|
@@ -33050,7 +33532,7 @@ init_conversationSyncStore();
|
|
|
33050
33532
|
|
|
33051
33533
|
// src/hooks/useGatewayQueries.ts
|
|
33052
33534
|
var import_react25 = require("react");
|
|
33053
|
-
var
|
|
33535
|
+
var import_rxjs20 = require("rxjs");
|
|
33054
33536
|
var import_react_query = require("@tanstack/react-query");
|
|
33055
33537
|
init_packageSettingsStore();
|
|
33056
33538
|
init_gateway_service();
|
|
@@ -33081,7 +33563,7 @@ var useGatewayHealth = (options) => {
|
|
|
33081
33563
|
if (!service) {
|
|
33082
33564
|
throw new Error("Gateway service is not configured");
|
|
33083
33565
|
}
|
|
33084
|
-
return (0,
|
|
33566
|
+
return (0, import_rxjs20.lastValueFrom)(service.getHealth());
|
|
33085
33567
|
},
|
|
33086
33568
|
enabled
|
|
33087
33569
|
});
|
|
@@ -37849,26 +38331,7 @@ var AIProviderInitService = class _AIProviderInitService {
|
|
|
37849
38331
|
if (providerConfig.type === "anthropic" /* ANTHROPIC */) {
|
|
37850
38332
|
providerConfig = this.convertAnthropicConfig(providerConfig, settings?.gatewayApiUrl);
|
|
37851
38333
|
}
|
|
37852
|
-
|
|
37853
|
-
providerConfig.tokenFactory = () => {
|
|
37854
|
-
let token = authenticationService.getToken();
|
|
37855
|
-
if (!token) {
|
|
37856
|
-
token = localStorage.getItem("authToken");
|
|
37857
|
-
}
|
|
37858
|
-
if (!token) {
|
|
37859
|
-
try {
|
|
37860
|
-
const { useAuthenticationStore: useAuthenticationStore2 } = require("../../store/authenticationStore");
|
|
37861
|
-
const authStore = useAuthenticationStore2.getState();
|
|
37862
|
-
token = authStore.token;
|
|
37863
|
-
} catch (e) {
|
|
37864
|
-
}
|
|
37865
|
-
}
|
|
37866
|
-
debugLogger.info("AI Provider Init: IndexedDB config token factory", {
|
|
37867
|
-
hasToken: !!token
|
|
37868
|
-
});
|
|
37869
|
-
return token;
|
|
37870
|
-
};
|
|
37871
|
-
}
|
|
38334
|
+
providerConfig = this.ensureTokenFactory(providerConfig);
|
|
37872
38335
|
try {
|
|
37873
38336
|
const { createProvider } = useAIProviderStore.getState();
|
|
37874
38337
|
createProvider(providerConfig);
|
|
@@ -37896,27 +38359,7 @@ var AIProviderInitService = class _AIProviderInitService {
|
|
|
37896
38359
|
if (providerConfig.type === "anthropic" /* ANTHROPIC */) {
|
|
37897
38360
|
providerConfig = this.convertAnthropicConfig(providerConfig, settings.gatewayApiUrl);
|
|
37898
38361
|
}
|
|
37899
|
-
|
|
37900
|
-
providerConfig.tokenFactory = () => {
|
|
37901
|
-
let token = authenticationService.getToken();
|
|
37902
|
-
if (!token) {
|
|
37903
|
-
token = localStorage.getItem("authToken");
|
|
37904
|
-
}
|
|
37905
|
-
if (!token) {
|
|
37906
|
-
try {
|
|
37907
|
-
const { useAuthenticationStore: useAuthenticationStore2 } = require("../../store/authenticationStore");
|
|
37908
|
-
const authStore = useAuthenticationStore2.getState();
|
|
37909
|
-
token = authStore.token;
|
|
37910
|
-
} catch (e) {
|
|
37911
|
-
}
|
|
37912
|
-
}
|
|
37913
|
-
debugLogger.info("AIProviderInit: Explicit config tokenFactory", {
|
|
37914
|
-
hasToken: !!token,
|
|
37915
|
-
localStorage: !!localStorage.getItem("authToken")
|
|
37916
|
-
});
|
|
37917
|
-
return token;
|
|
37918
|
-
};
|
|
37919
|
-
}
|
|
38362
|
+
providerConfig = this.ensureTokenFactory(providerConfig);
|
|
37920
38363
|
debugLogger.info("Using explicit AI provider config", providerConfig);
|
|
37921
38364
|
} else {
|
|
37922
38365
|
providerConfig = {
|
|
@@ -38028,9 +38471,10 @@ var AIProviderInitService = class _AIProviderInitService {
|
|
|
38028
38471
|
*/
|
|
38029
38472
|
switchProvider(config) {
|
|
38030
38473
|
try {
|
|
38474
|
+
const normalizedConfig = this.ensureTokenFactory({ ...config });
|
|
38031
38475
|
const { switchProvider } = useAIProviderStore.getState();
|
|
38032
|
-
switchProvider(
|
|
38033
|
-
debugLogger.info(`Switched to AI provider: ${
|
|
38476
|
+
switchProvider(normalizedConfig);
|
|
38477
|
+
debugLogger.info(`Switched to AI provider: ${normalizedConfig.type}`);
|
|
38034
38478
|
} catch (error) {
|
|
38035
38479
|
debugLogger.error("Failed to switch AI provider:", { error });
|
|
38036
38480
|
throw error;
|
|
@@ -38064,6 +38508,49 @@ var AIProviderInitService = class _AIProviderInitService {
|
|
|
38064
38508
|
debugLogger.info("AI Provider Init: Converted direct Anthropic provider to gateway configuration");
|
|
38065
38509
|
return normalized;
|
|
38066
38510
|
}
|
|
38511
|
+
/**
|
|
38512
|
+
* Ensure providers that require auth have a token factory configured.
|
|
38513
|
+
* Handles both UI auth tokens and API key scenarios.
|
|
38514
|
+
*/
|
|
38515
|
+
ensureTokenFactory(config) {
|
|
38516
|
+
if (config.type === "ollama" /* OLLAMA */ || config.type === "gateway" /* GATEWAY */) {
|
|
38517
|
+
const existingFactory = config.tokenFactory;
|
|
38518
|
+
if (existingFactory) {
|
|
38519
|
+
return config;
|
|
38520
|
+
}
|
|
38521
|
+
if (typeof config.apiKey === "string" && config.apiKey.trim() !== "") {
|
|
38522
|
+
const key = config.apiKey.trim();
|
|
38523
|
+
config.tokenFactory = () => key;
|
|
38524
|
+
debugLogger.info("AIProviderInit: Using API key for token factory", {
|
|
38525
|
+
type: config.type,
|
|
38526
|
+
hasKey: true
|
|
38527
|
+
});
|
|
38528
|
+
return config;
|
|
38529
|
+
}
|
|
38530
|
+
config.tokenFactory = () => {
|
|
38531
|
+
let token = authenticationService.getToken();
|
|
38532
|
+
if (!token && typeof localStorage !== "undefined") {
|
|
38533
|
+
try {
|
|
38534
|
+
token = localStorage.getItem("authToken");
|
|
38535
|
+
} catch {
|
|
38536
|
+
}
|
|
38537
|
+
}
|
|
38538
|
+
if (!token) {
|
|
38539
|
+
try {
|
|
38540
|
+
const { useAuthenticationStore: useAuthenticationStore2 } = require("../../store/authenticationStore");
|
|
38541
|
+
const authStore = useAuthenticationStore2.getState();
|
|
38542
|
+
token = authStore.token;
|
|
38543
|
+
} catch {
|
|
38544
|
+
}
|
|
38545
|
+
}
|
|
38546
|
+
debugLogger.info("AIProviderInit: Token factory resolved auth token", {
|
|
38547
|
+
hasToken: !!token
|
|
38548
|
+
});
|
|
38549
|
+
return token;
|
|
38550
|
+
};
|
|
38551
|
+
}
|
|
38552
|
+
return config;
|
|
38553
|
+
}
|
|
38067
38554
|
};
|
|
38068
38555
|
var aiProviderInitService = AIProviderInitService.getInstance();
|
|
38069
38556
|
|
|
@@ -38087,6 +38574,8 @@ var ProviderTab = () => {
|
|
|
38087
38574
|
return "gpt-4o-mini";
|
|
38088
38575
|
case "xai" /* XAI */:
|
|
38089
38576
|
return "grok-beta";
|
|
38577
|
+
case "bandit" /* BANDIT */:
|
|
38578
|
+
return "bandit-core-1";
|
|
38090
38579
|
default:
|
|
38091
38580
|
return "";
|
|
38092
38581
|
}
|
|
@@ -38094,7 +38583,7 @@ var ProviderTab = () => {
|
|
|
38094
38583
|
const applyDefaultModel = (0, import_react33.useCallback)((config) => {
|
|
38095
38584
|
const normalized = { ...config };
|
|
38096
38585
|
const trimmed = typeof normalized.defaultModel === "string" ? normalized.defaultModel.trim() : void 0;
|
|
38097
|
-
const requiresModel = normalized.type === "openai" /* OPENAI */ || normalized.type === "xai" /* XAI */;
|
|
38586
|
+
const requiresModel = normalized.type === "openai" /* OPENAI */ || normalized.type === "xai" /* XAI */ || normalized.type === "bandit" /* BANDIT */;
|
|
38098
38587
|
if (trimmed) {
|
|
38099
38588
|
normalized.defaultModel = trimmed;
|
|
38100
38589
|
return normalized;
|
|
@@ -38117,11 +38606,16 @@ var ProviderTab = () => {
|
|
|
38117
38606
|
const trimmed = sanitized.defaultModel.trim();
|
|
38118
38607
|
sanitized.defaultModel = trimmed || void 0;
|
|
38119
38608
|
}
|
|
38609
|
+
if (typeof sanitized.apiKey === "string") {
|
|
38610
|
+
const trimmedKey = sanitized.apiKey.trim();
|
|
38611
|
+
sanitized.apiKey = trimmedKey || void 0;
|
|
38612
|
+
}
|
|
38120
38613
|
return sanitized;
|
|
38121
38614
|
}, []);
|
|
38122
38615
|
const [providerConfig, setProviderConfig] = (0, import_react33.useState)({
|
|
38123
|
-
type: "
|
|
38124
|
-
|
|
38616
|
+
type: "gateway",
|
|
38617
|
+
gatewayUrl: packageSettings?.gatewayApiUrl || "",
|
|
38618
|
+
provider: "bandit"
|
|
38125
38619
|
});
|
|
38126
38620
|
const [isProviderConfigOpen, setIsProviderConfigOpen] = (0, import_react33.useState)(false);
|
|
38127
38621
|
const [snackbarMessage, setSnackbarMessage] = (0, import_react33.useState)("");
|
|
@@ -38245,11 +38739,19 @@ var ProviderTab = () => {
|
|
|
38245
38739
|
apiKey: ""
|
|
38246
38740
|
}));
|
|
38247
38741
|
break;
|
|
38742
|
+
case "bandit" /* BANDIT */:
|
|
38743
|
+
setProviderConfig(applyDefaultModel({
|
|
38744
|
+
...baseConfig,
|
|
38745
|
+
baseUrl: "https://api.burtson.ai",
|
|
38746
|
+
apiKey: "",
|
|
38747
|
+
defaultModel: "bandit-core-1"
|
|
38748
|
+
}));
|
|
38749
|
+
break;
|
|
38248
38750
|
case "gateway" /* GATEWAY */:
|
|
38249
38751
|
setProviderConfig(applyDefaultModel({
|
|
38250
38752
|
...baseConfig,
|
|
38251
38753
|
gatewayUrl: packageSettings?.gatewayApiUrl || "",
|
|
38252
|
-
provider: "
|
|
38754
|
+
provider: "bandit"
|
|
38253
38755
|
}));
|
|
38254
38756
|
break;
|
|
38255
38757
|
case "playground" /* PLAYGROUND */:
|
|
@@ -38263,7 +38765,7 @@ var ProviderTab = () => {
|
|
|
38263
38765
|
try {
|
|
38264
38766
|
const normalizedConfigIntermediate = sanitizeConfigForSave(providerConfig);
|
|
38265
38767
|
const normalizedConfig = convertAnthropicConfig(normalizedConfigIntermediate) || normalizedConfigIntermediate;
|
|
38266
|
-
const requiresModel = normalizedConfig.type === "openai" /* OPENAI */ || normalizedConfig.type === "xai" /* XAI */;
|
|
38768
|
+
const requiresModel = normalizedConfig.type === "openai" /* OPENAI */ || normalizedConfig.type === "xai" /* XAI */ || normalizedConfig.type === "bandit" /* BANDIT */;
|
|
38267
38769
|
if (requiresModel && !normalizedConfig.defaultModel) {
|
|
38268
38770
|
showMessage("Please provide a default model ID for the selected provider.", "error");
|
|
38269
38771
|
return;
|
|
@@ -38388,6 +38890,7 @@ var ProviderTab = () => {
|
|
|
38388
38890
|
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_material25.MenuItem, { value: "ollama", children: "Ollama" }),
|
|
38389
38891
|
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_material25.MenuItem, { value: "openai", children: "OpenAI" }),
|
|
38390
38892
|
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_material25.MenuItem, { value: "azure-openai", children: "Azure OpenAI" }),
|
|
38893
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_material25.MenuItem, { value: "bandit", children: "Bandit AI" }),
|
|
38391
38894
|
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_material25.MenuItem, { value: "xai", children: "xAI" }),
|
|
38392
38895
|
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_material25.MenuItem, { value: "playground", children: "Playground (Mock Demo)" })
|
|
38393
38896
|
]
|
|
@@ -38422,6 +38925,7 @@ var ProviderTab = () => {
|
|
|
38422
38925
|
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_material25.MenuItem, { value: "azure-openai", children: "Azure OpenAI" }),
|
|
38423
38926
|
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_material25.MenuItem, { value: "anthropic", children: "Anthropic" }),
|
|
38424
38927
|
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_material25.MenuItem, { value: "ollama", children: "Ollama" }),
|
|
38928
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_material25.MenuItem, { value: "bandit", children: "Bandit AI" }),
|
|
38425
38929
|
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_material25.MenuItem, { value: "xai", children: "xAI" })
|
|
38426
38930
|
]
|
|
38427
38931
|
}
|
|
@@ -38437,6 +38941,52 @@ var ProviderTab = () => {
|
|
|
38437
38941
|
placeholder: "http://localhost:11434"
|
|
38438
38942
|
}
|
|
38439
38943
|
),
|
|
38944
|
+
providerConfig.type === "bandit" && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_material25.Box, { children: [
|
|
38945
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
38946
|
+
import_material25.TextField,
|
|
38947
|
+
{
|
|
38948
|
+
label: "API Base URL",
|
|
38949
|
+
value: providerConfig.baseUrl || "",
|
|
38950
|
+
onChange: (e) => setProviderConfig((prev) => ({
|
|
38951
|
+
...prev,
|
|
38952
|
+
baseUrl: e.target.value
|
|
38953
|
+
})),
|
|
38954
|
+
fullWidth: true,
|
|
38955
|
+
sx: { mb: 2 },
|
|
38956
|
+
placeholder: "https://api.burtson.ai",
|
|
38957
|
+
helperText: "Defaults to https://api.burtson.ai"
|
|
38958
|
+
}
|
|
38959
|
+
),
|
|
38960
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
38961
|
+
import_material25.TextField,
|
|
38962
|
+
{
|
|
38963
|
+
label: "API Key",
|
|
38964
|
+
type: "password",
|
|
38965
|
+
value: providerConfig.apiKey || "",
|
|
38966
|
+
onChange: (e) => setProviderConfig((prev) => ({
|
|
38967
|
+
...prev,
|
|
38968
|
+
apiKey: e.target.value
|
|
38969
|
+
})),
|
|
38970
|
+
fullWidth: true,
|
|
38971
|
+
sx: { mb: 2 },
|
|
38972
|
+
placeholder: "bai_..."
|
|
38973
|
+
}
|
|
38974
|
+
),
|
|
38975
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
38976
|
+
import_material25.TextField,
|
|
38977
|
+
{
|
|
38978
|
+
label: "Default Model ID",
|
|
38979
|
+
value: providerConfig.defaultModel || "",
|
|
38980
|
+
onChange: (e) => setProviderConfig((prev) => ({
|
|
38981
|
+
...prev,
|
|
38982
|
+
defaultModel: e.target.value
|
|
38983
|
+
})),
|
|
38984
|
+
fullWidth: true,
|
|
38985
|
+
placeholder: "bandit-core-1",
|
|
38986
|
+
helperText: "Example: bandit-core-1 (Bandit Core canonical alias)."
|
|
38987
|
+
}
|
|
38988
|
+
)
|
|
38989
|
+
] }),
|
|
38440
38990
|
providerConfig.type === "openai" && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_material25.Box, { children: [
|
|
38441
38991
|
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
38442
38992
|
import_material25.TextField,
|
|
@@ -38777,20 +39327,20 @@ var MCPToolsTabV2 = () => {
|
|
|
38777
39327
|
}
|
|
38778
39328
|
}, [isLoaded]);
|
|
38779
39329
|
const localEnabledMap = (0, import_react34.useMemo)(() => {
|
|
38780
|
-
const
|
|
39330
|
+
const map23 = /* @__PURE__ */ new Map();
|
|
38781
39331
|
const sortedTools = [...localTools].sort((a, b) => {
|
|
38782
39332
|
if (a.isBuiltIn && !b.isBuiltIn) return -1;
|
|
38783
39333
|
if (!a.isBuiltIn && b.isBuiltIn) return 1;
|
|
38784
39334
|
return a.id.length - b.id.length;
|
|
38785
39335
|
});
|
|
38786
39336
|
sortedTools.forEach((t) => {
|
|
38787
|
-
|
|
38788
|
-
|
|
39337
|
+
map23.set(t.function.name, t.enabled);
|
|
39338
|
+
map23.set(t.id, t.enabled);
|
|
38789
39339
|
if (t.name) {
|
|
38790
|
-
|
|
39340
|
+
map23.set(t.name, t.enabled);
|
|
38791
39341
|
}
|
|
38792
39342
|
});
|
|
38793
|
-
return
|
|
39343
|
+
return map23;
|
|
38794
39344
|
}, [localTools]);
|
|
38795
39345
|
return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_material26.Box, { children: [
|
|
38796
39346
|
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_material26.Box, { sx: { display: "flex", alignItems: "center", justifyContent: "space-between", mb: 2 }, children: [
|