@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
package/dist/chat-provider.js
CHANGED
|
@@ -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, from8, except, desc) => {
|
|
16
|
+
if (from8 && typeof from8 === "object" || typeof from8 === "function") {
|
|
17
|
+
for (let key of __getOwnPropNames(from8))
|
|
18
18
|
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
19
|
-
__defProp(to, key, { get: () =>
|
|
19
|
+
__defProp(to, key, { get: () => from8[key], enumerable: !(desc = __getOwnPropDesc(from8, key)) || desc.enumerable });
|
|
20
20
|
}
|
|
21
21
|
return to;
|
|
22
22
|
};
|
|
@@ -2222,57 +2222,15 @@ var init_gateway_service = __esm({
|
|
|
2222
2222
|
*/
|
|
2223
2223
|
chat(request) {
|
|
2224
2224
|
const endpoint = request.provider === "ollama" ? `/api/${request.provider}/chat` : request.provider ? `/api/${request.provider}/chat/completions` : "/api/chat/completions";
|
|
2225
|
-
const
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
});
|
|
2232
|
-
const requestBody = { ...request, stream: request.stream !== false };
|
|
2225
|
+
const fallbackEndpoint = request.provider === "bandit" ? "/completions" : null;
|
|
2226
|
+
const normalizedModel = request.provider === "bandit" ? (() => {
|
|
2227
|
+
const trimmed = (request.model ?? "").replace(/^bandit:/, "").trim();
|
|
2228
|
+
return trimmed !== "" ? trimmed : "bandit-core-1";
|
|
2229
|
+
})() : request.model;
|
|
2230
|
+
const requestBody = { ...request, model: normalizedModel, stream: request.stream !== false };
|
|
2233
2231
|
return new import_rxjs6.Observable((observer) => {
|
|
2234
2232
|
const controller = new AbortController();
|
|
2235
|
-
const
|
|
2236
|
-
method: "POST",
|
|
2237
|
-
headers: this._getHeaders(),
|
|
2238
|
-
body: JSON.stringify(requestBody),
|
|
2239
|
-
signal: controller.signal
|
|
2240
|
-
});
|
|
2241
|
-
task.then(async (response) => {
|
|
2242
|
-
debugLogger.debug(`Gateway chat response status: ${response.status} for provider: ${request.provider || "default"}`);
|
|
2243
|
-
if (!response.ok) {
|
|
2244
|
-
let errorText = "";
|
|
2245
|
-
let errorData = null;
|
|
2246
|
-
try {
|
|
2247
|
-
errorText = await response.text();
|
|
2248
|
-
debugLogger.error("GatewayService chat error response body", {
|
|
2249
|
-
status: response.status,
|
|
2250
|
-
statusText: response.statusText,
|
|
2251
|
-
url: response.url,
|
|
2252
|
-
body: errorText
|
|
2253
|
-
});
|
|
2254
|
-
} catch (readError) {
|
|
2255
|
-
debugLogger.error("GatewayService chat failed to read error response body", { error: readError });
|
|
2256
|
-
errorText = `Request failed with status ${response.status}`;
|
|
2257
|
-
}
|
|
2258
|
-
try {
|
|
2259
|
-
errorData = JSON.parse(errorText);
|
|
2260
|
-
debugLogger.error("GatewayService chat parsed error payload", errorData);
|
|
2261
|
-
} catch (parseError) {
|
|
2262
|
-
debugLogger.error("GatewayService chat error payload was not valid JSON");
|
|
2263
|
-
errorData = { message: errorText };
|
|
2264
|
-
}
|
|
2265
|
-
const error = this._createHttpError(
|
|
2266
|
-
`POST ${url} failed: ${response.status} ${response.statusText ?? ""}`,
|
|
2267
|
-
{
|
|
2268
|
-
status: response.status,
|
|
2269
|
-
statusText: response.statusText ?? "",
|
|
2270
|
-
data: errorData,
|
|
2271
|
-
url
|
|
2272
|
-
}
|
|
2273
|
-
);
|
|
2274
|
-
throw error;
|
|
2275
|
-
}
|
|
2233
|
+
const handleStreamingResponse = async (response) => {
|
|
2276
2234
|
const reader = response.body?.getReader();
|
|
2277
2235
|
const decoder = new TextDecoder();
|
|
2278
2236
|
let buffer = "";
|
|
@@ -2347,14 +2305,75 @@ var init_gateway_service = __esm({
|
|
|
2347
2305
|
}).catch((err) => observer.error(err));
|
|
2348
2306
|
};
|
|
2349
2307
|
read();
|
|
2350
|
-
}
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2308
|
+
};
|
|
2309
|
+
const sendRequest = (targetEndpoint, allowFallback) => {
|
|
2310
|
+
const url = `${this._baseUrl}${targetEndpoint}`;
|
|
2311
|
+
debugLogger.debug(`Gateway chat request to ${url} with provider: ${request.provider || "default"}`, {
|
|
2312
|
+
model: normalizedModel,
|
|
2313
|
+
messageCount: request.messages.length,
|
|
2314
|
+
hasImages: !!(request.images && request.images.length > 0),
|
|
2315
|
+
imageCount: request.images?.length || 0
|
|
2355
2316
|
});
|
|
2356
|
-
|
|
2357
|
-
|
|
2317
|
+
fetch(url, {
|
|
2318
|
+
method: "POST",
|
|
2319
|
+
headers: this._getHeaders(),
|
|
2320
|
+
body: JSON.stringify(requestBody),
|
|
2321
|
+
signal: controller.signal
|
|
2322
|
+
}).then(async (response) => {
|
|
2323
|
+
debugLogger.debug(`Gateway chat response status: ${response.status} for provider: ${request.provider || "default"}`);
|
|
2324
|
+
if (response.status === 404 && allowFallback && fallbackEndpoint) {
|
|
2325
|
+
debugLogger.warn("GatewayService chat endpoint returned 404, attempting fallback route", {
|
|
2326
|
+
provider: request.provider,
|
|
2327
|
+
attemptedEndpoint: targetEndpoint,
|
|
2328
|
+
fallbackEndpoint
|
|
2329
|
+
});
|
|
2330
|
+
sendRequest(fallbackEndpoint, false);
|
|
2331
|
+
return;
|
|
2332
|
+
}
|
|
2333
|
+
if (!response.ok) {
|
|
2334
|
+
let errorText = "";
|
|
2335
|
+
let errorData = null;
|
|
2336
|
+
try {
|
|
2337
|
+
errorText = await response.text();
|
|
2338
|
+
debugLogger.error("GatewayService chat error response body", {
|
|
2339
|
+
status: response.status,
|
|
2340
|
+
statusText: response.statusText,
|
|
2341
|
+
url: response.url,
|
|
2342
|
+
body: errorText
|
|
2343
|
+
});
|
|
2344
|
+
} catch (readError) {
|
|
2345
|
+
debugLogger.error("GatewayService chat failed to read error response body", { error: readError });
|
|
2346
|
+
errorText = `Request failed with status ${response.status}`;
|
|
2347
|
+
}
|
|
2348
|
+
try {
|
|
2349
|
+
errorData = JSON.parse(errorText);
|
|
2350
|
+
debugLogger.error("GatewayService chat parsed error payload", errorData);
|
|
2351
|
+
} catch (parseError) {
|
|
2352
|
+
debugLogger.error("GatewayService chat error payload was not valid JSON");
|
|
2353
|
+
errorData = { message: errorText };
|
|
2354
|
+
}
|
|
2355
|
+
const error = this._createHttpError(
|
|
2356
|
+
`POST ${url} failed: ${response.status} ${response.statusText ?? ""}`,
|
|
2357
|
+
{
|
|
2358
|
+
status: response.status,
|
|
2359
|
+
statusText: response.statusText ?? "",
|
|
2360
|
+
data: errorData,
|
|
2361
|
+
url
|
|
2362
|
+
}
|
|
2363
|
+
);
|
|
2364
|
+
throw error;
|
|
2365
|
+
}
|
|
2366
|
+
await handleStreamingResponse(response);
|
|
2367
|
+
}).catch((err) => {
|
|
2368
|
+
debugLogger.error("GatewayService chat fetch error", {
|
|
2369
|
+
error: err,
|
|
2370
|
+
url,
|
|
2371
|
+
provider: request.provider
|
|
2372
|
+
});
|
|
2373
|
+
observer.error(err);
|
|
2374
|
+
});
|
|
2375
|
+
};
|
|
2376
|
+
sendRequest(endpoint, true);
|
|
2358
2377
|
return () => {
|
|
2359
2378
|
try {
|
|
2360
2379
|
controller.abort();
|
|
@@ -2369,12 +2388,18 @@ var init_gateway_service = __esm({
|
|
|
2369
2388
|
generate(request) {
|
|
2370
2389
|
const endpoint = request.provider ? `/api/${request.provider}/generate` : "/api/generate";
|
|
2371
2390
|
const url = `${this._baseUrl}${endpoint}`;
|
|
2372
|
-
|
|
2391
|
+
const normalizedModel = request.provider === "bandit" ? (() => {
|
|
2392
|
+
const trimmed = (request.model ?? "").replace(/^bandit:/, "").trim();
|
|
2393
|
+
return trimmed !== "" ? trimmed : "bandit-core-1";
|
|
2394
|
+
})() : request.model;
|
|
2395
|
+
debugLogger.debug(`Gateway generate request to ${url} with provider: ${request.provider || "default"}`, {
|
|
2396
|
+
model: normalizedModel
|
|
2397
|
+
});
|
|
2373
2398
|
return new import_rxjs6.Observable((observer) => {
|
|
2374
2399
|
const task = fetch(url, {
|
|
2375
2400
|
method: "POST",
|
|
2376
2401
|
headers: this._getHeaders(),
|
|
2377
|
-
body: JSON.stringify({ ...request, stream: request.stream !== false })
|
|
2402
|
+
body: JSON.stringify({ ...request, model: normalizedModel, stream: request.stream !== false })
|
|
2378
2403
|
});
|
|
2379
2404
|
task.then(async (response) => {
|
|
2380
2405
|
if (!response.ok) {
|
|
@@ -2481,18 +2506,46 @@ var init_gateway_service = __esm({
|
|
|
2481
2506
|
);
|
|
2482
2507
|
}
|
|
2483
2508
|
_getHeaders() {
|
|
2484
|
-
const
|
|
2509
|
+
const rawToken2 = this._tokenFactory();
|
|
2485
2510
|
const headers = {
|
|
2486
2511
|
"Content-Type": "application/json"
|
|
2487
2512
|
};
|
|
2488
|
-
if (
|
|
2489
|
-
headers["Authorization"] = `Bearer ${token}`;
|
|
2490
|
-
debugLogger.debug("Authorization header set with token");
|
|
2491
|
-
} else {
|
|
2513
|
+
if (!rawToken2) {
|
|
2492
2514
|
debugLogger.warn("GatewayService: No token found, skipping Authorization header");
|
|
2515
|
+
return headers;
|
|
2516
|
+
}
|
|
2517
|
+
const token = rawToken2.trim();
|
|
2518
|
+
if (token === "") {
|
|
2519
|
+
debugLogger.warn("GatewayService: Token factory returned empty string");
|
|
2520
|
+
return headers;
|
|
2521
|
+
}
|
|
2522
|
+
if (/^(Bearer|ApiKey)\s+/i.test(token)) {
|
|
2523
|
+
headers["Authorization"] = token;
|
|
2524
|
+
debugLogger.debug("GatewayService: Authorization header set with explicit scheme");
|
|
2525
|
+
return headers;
|
|
2526
|
+
}
|
|
2527
|
+
if (this._isLikelyBanditApiKey(token)) {
|
|
2528
|
+
headers["Authorization"] = `ApiKey ${token}`;
|
|
2529
|
+
headers["X-Burtson-Api-Key"] = token;
|
|
2530
|
+
debugLogger.debug("GatewayService: Authorization header set using API key");
|
|
2531
|
+
return headers;
|
|
2493
2532
|
}
|
|
2533
|
+
if (this._isLikelyJwt(token)) {
|
|
2534
|
+
headers["Authorization"] = `Bearer ${token}`;
|
|
2535
|
+
debugLogger.debug("GatewayService: Authorization header set using bearer token");
|
|
2536
|
+
return headers;
|
|
2537
|
+
}
|
|
2538
|
+
headers["Authorization"] = `Bearer ${token}`;
|
|
2539
|
+
debugLogger.debug("GatewayService: Authorization header defaulted to bearer scheme");
|
|
2494
2540
|
return headers;
|
|
2495
2541
|
}
|
|
2542
|
+
_isLikelyJwt(token) {
|
|
2543
|
+
const segments = token.split(".");
|
|
2544
|
+
return segments.length === 3 && segments.every((segment) => segment.length > 0);
|
|
2545
|
+
}
|
|
2546
|
+
_isLikelyBanditApiKey(value) {
|
|
2547
|
+
return /^bai_[a-z0-9]{10,}$/i.test(value);
|
|
2548
|
+
}
|
|
2496
2549
|
/**
|
|
2497
2550
|
* Submit feedback to the gateway API
|
|
2498
2551
|
*/
|
|
@@ -2972,6 +3025,112 @@ var init_ollama_gateway_service = __esm({
|
|
|
2972
3025
|
}
|
|
2973
3026
|
});
|
|
2974
3027
|
|
|
3028
|
+
// src/services/gateway/bandit-gateway.service.ts
|
|
3029
|
+
var import_operators5, normalizeBanditModel, isGatewayMessageContent, normalizeBanditMessages, BanditAIGatewayService;
|
|
3030
|
+
var init_bandit_gateway_service = __esm({
|
|
3031
|
+
"src/services/gateway/bandit-gateway.service.ts"() {
|
|
3032
|
+
"use strict";
|
|
3033
|
+
init_gateway_service();
|
|
3034
|
+
import_operators5 = require("rxjs/operators");
|
|
3035
|
+
init_debugLogger();
|
|
3036
|
+
normalizeBanditModel = (model) => {
|
|
3037
|
+
if (typeof model !== "string" || model.trim() === "") {
|
|
3038
|
+
return "bandit-core-1";
|
|
3039
|
+
}
|
|
3040
|
+
const normalized = model.replace(/^bandit:/, "").trim();
|
|
3041
|
+
return normalized === "" ? "bandit-core-1" : normalized;
|
|
3042
|
+
};
|
|
3043
|
+
isGatewayMessageContent = (value) => {
|
|
3044
|
+
if (!value || typeof value !== "object") return false;
|
|
3045
|
+
const candidate = value;
|
|
3046
|
+
if (candidate.type !== "text" && candidate.type !== "image_url") {
|
|
3047
|
+
return false;
|
|
3048
|
+
}
|
|
3049
|
+
if (candidate.type === "text") {
|
|
3050
|
+
return typeof candidate.text === "string";
|
|
3051
|
+
}
|
|
3052
|
+
if (candidate.type === "image_url") {
|
|
3053
|
+
return !!candidate.image_url && typeof candidate.image_url.url === "string";
|
|
3054
|
+
}
|
|
3055
|
+
return false;
|
|
3056
|
+
};
|
|
3057
|
+
normalizeBanditMessages = (messages) => messages.map((message) => {
|
|
3058
|
+
const content = message.content;
|
|
3059
|
+
if (typeof content === "string") {
|
|
3060
|
+
return { role: message.role, content };
|
|
3061
|
+
}
|
|
3062
|
+
if (Array.isArray(content)) {
|
|
3063
|
+
const filtered = content.filter(isGatewayMessageContent);
|
|
3064
|
+
if (filtered.length === 0) {
|
|
3065
|
+
return { role: message.role, content: JSON.stringify(content) };
|
|
3066
|
+
}
|
|
3067
|
+
return {
|
|
3068
|
+
role: message.role,
|
|
3069
|
+
content: filtered
|
|
3070
|
+
};
|
|
3071
|
+
}
|
|
3072
|
+
return { role: message.role, content: content != null ? String(content) : "" };
|
|
3073
|
+
});
|
|
3074
|
+
BanditAIGatewayService = class {
|
|
3075
|
+
_gatewayService;
|
|
3076
|
+
constructor(gatewayUrl, tokenFactory) {
|
|
3077
|
+
this._gatewayService = new GatewayService(gatewayUrl, tokenFactory);
|
|
3078
|
+
debugLogger.info("BanditAIGatewayService initialized", { gatewayUrl });
|
|
3079
|
+
}
|
|
3080
|
+
async validateServiceAvailability(args) {
|
|
3081
|
+
return this._gatewayService.validateServiceAvailability(args);
|
|
3082
|
+
}
|
|
3083
|
+
chat(request) {
|
|
3084
|
+
const model = normalizeBanditModel(request.model);
|
|
3085
|
+
const messages = normalizeBanditMessages(request.messages);
|
|
3086
|
+
const gatewayRequest = {
|
|
3087
|
+
...request,
|
|
3088
|
+
messages,
|
|
3089
|
+
model,
|
|
3090
|
+
provider: "bandit",
|
|
3091
|
+
stream: request.stream
|
|
3092
|
+
};
|
|
3093
|
+
debugLogger.debug("Bandit Gateway chat request", {
|
|
3094
|
+
model,
|
|
3095
|
+
messageCount: request.messages.length,
|
|
3096
|
+
stream: request.stream
|
|
3097
|
+
});
|
|
3098
|
+
return this._gatewayService.chat(gatewayRequest);
|
|
3099
|
+
}
|
|
3100
|
+
complete(prompt, options) {
|
|
3101
|
+
const model = normalizeBanditModel(options.model);
|
|
3102
|
+
const gatewayRequest = {
|
|
3103
|
+
model,
|
|
3104
|
+
prompt,
|
|
3105
|
+
temperature: options.temperature,
|
|
3106
|
+
max_tokens: options.max_tokens,
|
|
3107
|
+
stream: options.stream,
|
|
3108
|
+
stop: options.stop,
|
|
3109
|
+
provider: "bandit"
|
|
3110
|
+
};
|
|
3111
|
+
debugLogger.debug("Bandit Gateway generate request", {
|
|
3112
|
+
model,
|
|
3113
|
+
promptLength: prompt.length,
|
|
3114
|
+
stream: options.stream
|
|
3115
|
+
});
|
|
3116
|
+
return this._gatewayService.generate(gatewayRequest);
|
|
3117
|
+
}
|
|
3118
|
+
listModels() {
|
|
3119
|
+
debugLogger.debug("Fetching Bandit models through gateway");
|
|
3120
|
+
return this._gatewayService.listModelsByProvider("bandit");
|
|
3121
|
+
}
|
|
3122
|
+
getHealth() {
|
|
3123
|
+
return this._gatewayService.getHealth().pipe(
|
|
3124
|
+
(0, import_operators5.map)((health) => ({
|
|
3125
|
+
...health,
|
|
3126
|
+
bandit_status: health.providers.find((p) => p.name === "bandit")?.status || "unavailable"
|
|
3127
|
+
}))
|
|
3128
|
+
);
|
|
3129
|
+
}
|
|
3130
|
+
};
|
|
3131
|
+
}
|
|
3132
|
+
});
|
|
3133
|
+
|
|
2975
3134
|
// src/services/ai-provider/providers/gateway.provider.ts
|
|
2976
3135
|
var import_rxjs7, GatewayProvider;
|
|
2977
3136
|
var init_gateway_provider = __esm({
|
|
@@ -2985,6 +3144,7 @@ var init_gateway_provider = __esm({
|
|
|
2985
3144
|
init_azure_openai_gateway_service();
|
|
2986
3145
|
init_anthropic_gateway_service();
|
|
2987
3146
|
init_ollama_gateway_service();
|
|
3147
|
+
init_bandit_gateway_service();
|
|
2988
3148
|
GatewayProvider = class {
|
|
2989
3149
|
config;
|
|
2990
3150
|
gatewayService;
|
|
@@ -3026,6 +3186,9 @@ var init_gateway_provider = __esm({
|
|
|
3026
3186
|
case "anthropic":
|
|
3027
3187
|
this.providerSpecificService = new AnthropicGatewayService(gatewayUrl, tokenFactory);
|
|
3028
3188
|
break;
|
|
3189
|
+
case "bandit":
|
|
3190
|
+
this.providerSpecificService = new BanditAIGatewayService(gatewayUrl, tokenFactory);
|
|
3191
|
+
break;
|
|
3029
3192
|
case "ollama":
|
|
3030
3193
|
this.providerSpecificService = new OllamaGatewayService(gatewayUrl, tokenFactory);
|
|
3031
3194
|
break;
|
|
@@ -3040,6 +3203,16 @@ var init_gateway_provider = __esm({
|
|
|
3040
3203
|
role: msg.role,
|
|
3041
3204
|
content: msg.content
|
|
3042
3205
|
}));
|
|
3206
|
+
const normalizeImageUrl2 = (value) => {
|
|
3207
|
+
if (!value) {
|
|
3208
|
+
return value;
|
|
3209
|
+
}
|
|
3210
|
+
const trimmed = value.trim();
|
|
3211
|
+
if (/^data:/i.test(trimmed) || /^https?:\/\//i.test(trimmed)) {
|
|
3212
|
+
return trimmed;
|
|
3213
|
+
}
|
|
3214
|
+
return `data:image/jpeg;base64,${trimmed}`;
|
|
3215
|
+
};
|
|
3043
3216
|
if (request.images && request.images.length > 0) {
|
|
3044
3217
|
const lastUserMessageIndex = messages.map((m) => m.role).lastIndexOf("user");
|
|
3045
3218
|
if (this.config.provider === "ollama") {
|
|
@@ -3049,7 +3222,7 @@ var init_gateway_provider = __esm({
|
|
|
3049
3222
|
images: request.images
|
|
3050
3223
|
};
|
|
3051
3224
|
}
|
|
3052
|
-
} else if (["openai", "azure-openai", "anthropic"].includes(this.config.provider || "")) {
|
|
3225
|
+
} else if (["openai", "azure-openai", "anthropic", "bandit"].includes(this.config.provider || "")) {
|
|
3053
3226
|
if (lastUserMessageIndex !== -1) {
|
|
3054
3227
|
const currentMessage = messages[lastUserMessageIndex];
|
|
3055
3228
|
const contentArray = [
|
|
@@ -3058,11 +3231,11 @@ var init_gateway_provider = __esm({
|
|
|
3058
3231
|
text: currentMessage.content
|
|
3059
3232
|
}
|
|
3060
3233
|
];
|
|
3061
|
-
request.images.forEach((
|
|
3234
|
+
request.images.forEach((imageRef) => {
|
|
3062
3235
|
contentArray.push({
|
|
3063
3236
|
type: "image_url",
|
|
3064
3237
|
image_url: {
|
|
3065
|
-
url:
|
|
3238
|
+
url: normalizeImageUrl2(imageRef),
|
|
3066
3239
|
detail: "auto"
|
|
3067
3240
|
}
|
|
3068
3241
|
});
|
|
@@ -3071,6 +3244,11 @@ var init_gateway_provider = __esm({
|
|
|
3071
3244
|
...messages[lastUserMessageIndex],
|
|
3072
3245
|
content: contentArray
|
|
3073
3246
|
};
|
|
3247
|
+
debugLogger.debug("Gateway provider injected image attachments", {
|
|
3248
|
+
provider: this.config.provider,
|
|
3249
|
+
imageCount: request.images.length,
|
|
3250
|
+
messageIndex: lastUserMessageIndex
|
|
3251
|
+
});
|
|
3074
3252
|
}
|
|
3075
3253
|
}
|
|
3076
3254
|
}
|
|
@@ -3579,6 +3757,244 @@ var init_xai_provider = __esm({
|
|
|
3579
3757
|
}
|
|
3580
3758
|
});
|
|
3581
3759
|
|
|
3760
|
+
// src/services/ai-provider/providers/bandit-ai.provider.ts
|
|
3761
|
+
var import_rxjs10, DEFAULT_BANDIT_BASE, normalizeImageUrl, injectImagesIntoMessages, BanditAIProvider;
|
|
3762
|
+
var init_bandit_ai_provider = __esm({
|
|
3763
|
+
"src/services/ai-provider/providers/bandit-ai.provider.ts"() {
|
|
3764
|
+
"use strict";
|
|
3765
|
+
import_rxjs10 = require("rxjs");
|
|
3766
|
+
init_common_types();
|
|
3767
|
+
init_debugLogger();
|
|
3768
|
+
DEFAULT_BANDIT_BASE = "https://api.burtson.ai";
|
|
3769
|
+
normalizeImageUrl = (value) => {
|
|
3770
|
+
if (!value) {
|
|
3771
|
+
return null;
|
|
3772
|
+
}
|
|
3773
|
+
const trimmed = value.trim();
|
|
3774
|
+
if (!trimmed) {
|
|
3775
|
+
return null;
|
|
3776
|
+
}
|
|
3777
|
+
if (/^data:/i.test(trimmed) || /^https?:\/\//i.test(trimmed)) {
|
|
3778
|
+
return trimmed;
|
|
3779
|
+
}
|
|
3780
|
+
return `data:image/jpeg;base64,${trimmed}`;
|
|
3781
|
+
};
|
|
3782
|
+
injectImagesIntoMessages = (messages, images) => {
|
|
3783
|
+
const normalized = messages.map((message) => ({
|
|
3784
|
+
role: message.role,
|
|
3785
|
+
content: message.content
|
|
3786
|
+
}));
|
|
3787
|
+
if (!images || images.length === 0) {
|
|
3788
|
+
return normalized;
|
|
3789
|
+
}
|
|
3790
|
+
const normalizedImages = images.map(normalizeImageUrl).filter((url) => Boolean(url));
|
|
3791
|
+
if (normalizedImages.length === 0) {
|
|
3792
|
+
return normalized;
|
|
3793
|
+
}
|
|
3794
|
+
const lastUserIndex = normalized.map((msg) => msg.role).lastIndexOf("user");
|
|
3795
|
+
if (lastUserIndex === -1) {
|
|
3796
|
+
return normalized;
|
|
3797
|
+
}
|
|
3798
|
+
const target = normalized[lastUserIndex];
|
|
3799
|
+
const baseContent = typeof target.content === "string" && target.content.trim().length > 0 ? [
|
|
3800
|
+
{
|
|
3801
|
+
type: "text",
|
|
3802
|
+
text: target.content
|
|
3803
|
+
}
|
|
3804
|
+
] : [];
|
|
3805
|
+
const imageContent = normalizedImages.map((url) => ({
|
|
3806
|
+
type: "image_url",
|
|
3807
|
+
image_url: { url, detail: "auto" }
|
|
3808
|
+
}));
|
|
3809
|
+
normalized[lastUserIndex] = {
|
|
3810
|
+
role: target.role,
|
|
3811
|
+
content: [...baseContent, ...imageContent]
|
|
3812
|
+
};
|
|
3813
|
+
return normalized;
|
|
3814
|
+
};
|
|
3815
|
+
BanditAIProvider = class {
|
|
3816
|
+
config;
|
|
3817
|
+
baseUrl;
|
|
3818
|
+
constructor(config) {
|
|
3819
|
+
this.config = config;
|
|
3820
|
+
this.baseUrl = (config.baseUrl || DEFAULT_BANDIT_BASE).replace(/\/$/, "");
|
|
3821
|
+
}
|
|
3822
|
+
chat(request) {
|
|
3823
|
+
const url = `${this.baseUrl}/chat/completions`;
|
|
3824
|
+
const messages = injectImagesIntoMessages(request.messages, request.images);
|
|
3825
|
+
const payload = {
|
|
3826
|
+
model: request.model,
|
|
3827
|
+
messages,
|
|
3828
|
+
stream: Boolean(request.stream),
|
|
3829
|
+
temperature: request.temperature,
|
|
3830
|
+
max_tokens: request.maxTokens
|
|
3831
|
+
};
|
|
3832
|
+
if (request.stream) {
|
|
3833
|
+
return this.streamChatRequest(url, payload);
|
|
3834
|
+
}
|
|
3835
|
+
return this.nonStreamChatRequest(url, payload);
|
|
3836
|
+
}
|
|
3837
|
+
generate(request) {
|
|
3838
|
+
const chatRequest = {
|
|
3839
|
+
model: request.model,
|
|
3840
|
+
messages: [{ role: "user", content: request.prompt }],
|
|
3841
|
+
stream: request.stream,
|
|
3842
|
+
options: request.options
|
|
3843
|
+
};
|
|
3844
|
+
return this.chat(chatRequest).pipe(
|
|
3845
|
+
(0, import_rxjs10.map)((response) => ({
|
|
3846
|
+
response: response.message.content,
|
|
3847
|
+
done: response.done
|
|
3848
|
+
}))
|
|
3849
|
+
);
|
|
3850
|
+
}
|
|
3851
|
+
listModels() {
|
|
3852
|
+
const url = `${this.baseUrl}/models`;
|
|
3853
|
+
return (0, import_rxjs10.from)(fetch(url, { headers: this.getHeaders() })).pipe(
|
|
3854
|
+
(0, import_rxjs10.switchMap)((response) => {
|
|
3855
|
+
if (!response.ok) {
|
|
3856
|
+
debugLogger.error("BanditAI listModels failed", { status: response.status, url });
|
|
3857
|
+
return (0, import_rxjs10.throwError)(() => new Error(`Failed to list Bandit models: ${response.status}`));
|
|
3858
|
+
}
|
|
3859
|
+
return (0, import_rxjs10.from)(response.json());
|
|
3860
|
+
}),
|
|
3861
|
+
(0, import_rxjs10.map)(
|
|
3862
|
+
(data) => data.data.map((model) => ({
|
|
3863
|
+
name: model.id,
|
|
3864
|
+
details: {
|
|
3865
|
+
format: "bandit",
|
|
3866
|
+
family: model.object
|
|
3867
|
+
}
|
|
3868
|
+
}))
|
|
3869
|
+
)
|
|
3870
|
+
);
|
|
3871
|
+
}
|
|
3872
|
+
async validateServiceAvailability(args) {
|
|
3873
|
+
const attempt = async (url) => {
|
|
3874
|
+
try {
|
|
3875
|
+
const controller = new AbortController();
|
|
3876
|
+
const timeoutId = setTimeout(() => controller.abort(), args.timeoutMs);
|
|
3877
|
+
const response = await fetch(`${url}/models`, {
|
|
3878
|
+
headers: this.getHeaders(),
|
|
3879
|
+
signal: controller.signal
|
|
3880
|
+
});
|
|
3881
|
+
clearTimeout(timeoutId);
|
|
3882
|
+
return response.ok;
|
|
3883
|
+
} catch (error) {
|
|
3884
|
+
debugLogger.warn("BanditAI availability check failed", { url, error });
|
|
3885
|
+
return false;
|
|
3886
|
+
}
|
|
3887
|
+
};
|
|
3888
|
+
const primary = await attempt(this.baseUrl);
|
|
3889
|
+
if (primary) {
|
|
3890
|
+
return { url: this.baseUrl, isAvailable: true };
|
|
3891
|
+
}
|
|
3892
|
+
if (args.fallbackUrl) {
|
|
3893
|
+
const fallback = args.fallbackUrl.replace(/\/$/, "");
|
|
3894
|
+
if (await attempt(fallback)) {
|
|
3895
|
+
this.baseUrl = fallback;
|
|
3896
|
+
return { url: fallback, isAvailable: true };
|
|
3897
|
+
}
|
|
3898
|
+
}
|
|
3899
|
+
return { url: this.baseUrl, isAvailable: false };
|
|
3900
|
+
}
|
|
3901
|
+
getProviderType() {
|
|
3902
|
+
return "bandit" /* BANDIT */;
|
|
3903
|
+
}
|
|
3904
|
+
getConfig() {
|
|
3905
|
+
return this.config;
|
|
3906
|
+
}
|
|
3907
|
+
streamChatRequest(url, payload) {
|
|
3908
|
+
return new import_rxjs10.Observable((observer) => {
|
|
3909
|
+
const task = fetch(url, {
|
|
3910
|
+
method: "POST",
|
|
3911
|
+
headers: {
|
|
3912
|
+
...this.getHeaders(),
|
|
3913
|
+
"Content-Type": "application/json"
|
|
3914
|
+
},
|
|
3915
|
+
body: JSON.stringify(payload)
|
|
3916
|
+
});
|
|
3917
|
+
task.then((response) => {
|
|
3918
|
+
if (!response.ok) {
|
|
3919
|
+
observer.error(new Error(`BanditAI request failed: ${response.status}`));
|
|
3920
|
+
return;
|
|
3921
|
+
}
|
|
3922
|
+
const reader = response.body?.getReader();
|
|
3923
|
+
const decoder = new TextDecoder();
|
|
3924
|
+
let buffer = "";
|
|
3925
|
+
const read = () => {
|
|
3926
|
+
reader?.read().then(({ done, value }) => {
|
|
3927
|
+
if (done) {
|
|
3928
|
+
observer.next({ message: { content: "", role: "assistant" }, done: true });
|
|
3929
|
+
observer.complete();
|
|
3930
|
+
return;
|
|
3931
|
+
}
|
|
3932
|
+
buffer += decoder.decode(value, { stream: true });
|
|
3933
|
+
const lines = buffer.split("\n");
|
|
3934
|
+
buffer = lines.pop() ?? "";
|
|
3935
|
+
for (const rawLine of lines) {
|
|
3936
|
+
const line = rawLine.trim();
|
|
3937
|
+
if (!line.startsWith("data: ")) {
|
|
3938
|
+
continue;
|
|
3939
|
+
}
|
|
3940
|
+
const data = line.slice(6).trim();
|
|
3941
|
+
if (data === "[DONE]") {
|
|
3942
|
+
observer.next({ message: { content: "", role: "assistant" }, done: true });
|
|
3943
|
+
observer.complete();
|
|
3944
|
+
return;
|
|
3945
|
+
}
|
|
3946
|
+
try {
|
|
3947
|
+
const parsed = JSON.parse(data);
|
|
3948
|
+
const content = parsed.choices?.[0]?.delta?.content ?? "";
|
|
3949
|
+
if (content) {
|
|
3950
|
+
observer.next({ message: { content, role: "assistant" }, done: false });
|
|
3951
|
+
}
|
|
3952
|
+
} catch (error) {
|
|
3953
|
+
debugLogger.error("BanditAI stream chunk parse failure", { data, error });
|
|
3954
|
+
}
|
|
3955
|
+
}
|
|
3956
|
+
read();
|
|
3957
|
+
}).catch((err) => observer.error(err));
|
|
3958
|
+
};
|
|
3959
|
+
read();
|
|
3960
|
+
}).catch((err) => observer.error(err));
|
|
3961
|
+
});
|
|
3962
|
+
}
|
|
3963
|
+
nonStreamChatRequest(url, payload) {
|
|
3964
|
+
return (0, import_rxjs10.from)(fetch(url, {
|
|
3965
|
+
method: "POST",
|
|
3966
|
+
headers: {
|
|
3967
|
+
...this.getHeaders(),
|
|
3968
|
+
"Content-Type": "application/json"
|
|
3969
|
+
},
|
|
3970
|
+
body: JSON.stringify(payload)
|
|
3971
|
+
})).pipe(
|
|
3972
|
+
(0, import_rxjs10.switchMap)((response) => {
|
|
3973
|
+
if (!response.ok) {
|
|
3974
|
+
return (0, import_rxjs10.throwError)(() => new Error(`BanditAI request failed: ${response.status}`));
|
|
3975
|
+
}
|
|
3976
|
+
return (0, import_rxjs10.from)(response.json());
|
|
3977
|
+
}),
|
|
3978
|
+
(0, import_rxjs10.map)((data) => ({
|
|
3979
|
+
message: {
|
|
3980
|
+
content: data.choices?.[0]?.message?.content ?? "",
|
|
3981
|
+
role: "assistant"
|
|
3982
|
+
},
|
|
3983
|
+
done: true
|
|
3984
|
+
}))
|
|
3985
|
+
);
|
|
3986
|
+
}
|
|
3987
|
+
getHeaders() {
|
|
3988
|
+
const headers = {};
|
|
3989
|
+
if (this.config.apiKey) {
|
|
3990
|
+
headers["Authorization"] = `Bearer ${this.config.apiKey}`;
|
|
3991
|
+
}
|
|
3992
|
+
return headers;
|
|
3993
|
+
}
|
|
3994
|
+
};
|
|
3995
|
+
}
|
|
3996
|
+
});
|
|
3997
|
+
|
|
3582
3998
|
// src/services/ai-provider/ai-provider.factory.ts
|
|
3583
3999
|
var AIProviderFactory;
|
|
3584
4000
|
var init_ai_provider_factory = __esm({
|
|
@@ -3592,6 +4008,7 @@ var init_ai_provider_factory = __esm({
|
|
|
3592
4008
|
init_gateway_provider();
|
|
3593
4009
|
init_playground_provider();
|
|
3594
4010
|
init_xai_provider();
|
|
4011
|
+
init_bandit_ai_provider();
|
|
3595
4012
|
AIProviderFactory = class {
|
|
3596
4013
|
static createProvider(config) {
|
|
3597
4014
|
switch (config.type) {
|
|
@@ -3605,6 +4022,8 @@ var init_ai_provider_factory = __esm({
|
|
|
3605
4022
|
return new AnthropicProvider(config);
|
|
3606
4023
|
case "xai" /* XAI */:
|
|
3607
4024
|
return new XAIProvider(config);
|
|
4025
|
+
case "bandit" /* BANDIT */:
|
|
4026
|
+
return new BanditAIProvider(config);
|
|
3608
4027
|
case "gateway" /* GATEWAY */:
|
|
3609
4028
|
return new GatewayProvider(config);
|
|
3610
4029
|
case "playground" /* PLAYGROUND */:
|
|
@@ -3619,6 +4038,7 @@ var init_ai_provider_factory = __esm({
|
|
|
3619
4038
|
"openai" /* OPENAI */,
|
|
3620
4039
|
"azure-openai" /* AZURE_OPENAI */,
|
|
3621
4040
|
"xai" /* XAI */,
|
|
4041
|
+
"bandit" /* BANDIT */,
|
|
3622
4042
|
"gateway" /* GATEWAY */,
|
|
3623
4043
|
"playground" /* PLAYGROUND */
|
|
3624
4044
|
];
|
|
@@ -3636,6 +4056,8 @@ var init_ai_provider_factory = __esm({
|
|
|
3636
4056
|
return !!config.apiKey;
|
|
3637
4057
|
case "xai" /* XAI */:
|
|
3638
4058
|
return !!config.apiKey;
|
|
4059
|
+
case "bandit" /* BANDIT */:
|
|
4060
|
+
return !!config.apiKey;
|
|
3639
4061
|
case "gateway" /* GATEWAY */:
|
|
3640
4062
|
return !!(config.gatewayUrl && config.provider);
|
|
3641
4063
|
case "playground" /* PLAYGROUND */:
|
|
@@ -4427,13 +4849,17 @@ var useConversationStore = (0, import_zustand6.create)((set, get) => ({
|
|
|
4427
4849
|
const updatedConversations = conversations.map((c) => {
|
|
4428
4850
|
if (c.id === currentId && c.history.length > 0) {
|
|
4429
4851
|
const updatedHistory = [...c.history];
|
|
4852
|
+
const existingImages = updatedHistory[updatedHistory.length - 1].images;
|
|
4853
|
+
const nextImages = Array.isArray(images) && images.length > 0 ? [...images] : Array.isArray(existingImages) && existingImages.length > 0 ? [...existingImages] : existingImages;
|
|
4430
4854
|
updatedHistory[updatedHistory.length - 1] = {
|
|
4431
4855
|
...updatedHistory[updatedHistory.length - 1],
|
|
4432
4856
|
answer,
|
|
4433
4857
|
memoryUpdated,
|
|
4434
|
-
images:
|
|
4858
|
+
images: nextImages,
|
|
4435
4859
|
sourceFiles: sourceFiles ?? updatedHistory[updatedHistory.length - 1].sourceFiles,
|
|
4436
|
-
cancelled: cancelled ?? updatedHistory[updatedHistory.length - 1].cancelled
|
|
4860
|
+
cancelled: cancelled ?? updatedHistory[updatedHistory.length - 1].cancelled,
|
|
4861
|
+
placeholder: false,
|
|
4862
|
+
rawQuestion: void 0
|
|
4437
4863
|
};
|
|
4438
4864
|
return normalizeConversation({ ...c, history: updatedHistory, updatedAt: /* @__PURE__ */ new Date() });
|
|
4439
4865
|
}
|
|
@@ -4514,6 +4940,24 @@ var useConversationStore = (0, import_zustand6.create)((set, get) => ({
|
|
|
4514
4940
|
});
|
|
4515
4941
|
continue;
|
|
4516
4942
|
}
|
|
4943
|
+
if (Array.isArray(existing.history) && Array.isArray(conversation.history)) {
|
|
4944
|
+
const mergedHistory = conversation.history.map((incomingEntry, index) => {
|
|
4945
|
+
const existingEntry = existing.history[index];
|
|
4946
|
+
if (!existingEntry) {
|
|
4947
|
+
return incomingEntry;
|
|
4948
|
+
}
|
|
4949
|
+
const mergedImagesSource = Array.isArray(incomingEntry.images) && incomingEntry.images.length > 0 ? incomingEntry.images : existingEntry.images;
|
|
4950
|
+
const mergedImages = Array.isArray(mergedImagesSource) && mergedImagesSource.length > 0 ? [...mergedImagesSource] : mergedImagesSource;
|
|
4951
|
+
return {
|
|
4952
|
+
...existingEntry,
|
|
4953
|
+
...incomingEntry,
|
|
4954
|
+
images: mergedImages,
|
|
4955
|
+
placeholder: incomingEntry.placeholder ?? existingEntry.placeholder,
|
|
4956
|
+
rawQuestion: incomingEntry.rawQuestion ?? existingEntry.rawQuestion
|
|
4957
|
+
};
|
|
4958
|
+
});
|
|
4959
|
+
conversation.history = mergedHistory;
|
|
4960
|
+
}
|
|
4517
4961
|
}
|
|
4518
4962
|
next.set(conversation.id, conversation);
|
|
4519
4963
|
toPersist.push(conversation);
|
|
@@ -6086,7 +6530,7 @@ var import_mammoth = __toESM(require("mammoth"));
|
|
|
6086
6530
|
var pdfjsLib = __toESM(require("pdfjs-dist/legacy/build/pdf"));
|
|
6087
6531
|
|
|
6088
6532
|
// src/services/prompts/conversationStarters.ts
|
|
6089
|
-
var
|
|
6533
|
+
var import_rxjs11 = require("rxjs");
|
|
6090
6534
|
init_aiProviderStore();
|
|
6091
6535
|
init_packageSettingsStore();
|
|
6092
6536
|
|
|
@@ -6244,19 +6688,19 @@ var NotificationService = class {
|
|
|
6244
6688
|
var notificationService = new NotificationService();
|
|
6245
6689
|
|
|
6246
6690
|
// src/services/prompts/moodDetection.ts
|
|
6247
|
-
var
|
|
6691
|
+
var import_rxjs12 = require("rxjs");
|
|
6248
6692
|
init_aiProviderStore();
|
|
6249
6693
|
init_packageSettingsStore();
|
|
6250
6694
|
init_debugLogger();
|
|
6251
6695
|
|
|
6252
6696
|
// src/services/prompts/detectUserInterestAndExcitement.ts
|
|
6253
|
-
var
|
|
6697
|
+
var import_rxjs13 = require("rxjs");
|
|
6254
6698
|
init_aiProviderStore();
|
|
6255
6699
|
init_packageSettingsStore();
|
|
6256
6700
|
init_debugLogger();
|
|
6257
6701
|
|
|
6258
6702
|
// src/services/prompts/documentSummarization.ts
|
|
6259
|
-
var
|
|
6703
|
+
var import_rxjs14 = require("rxjs");
|
|
6260
6704
|
init_aiProviderStore();
|
|
6261
6705
|
init_packageSettingsStore();
|
|
6262
6706
|
init_debugLogger();
|
|
@@ -6284,8 +6728,8 @@ ${content.slice(0, 4e3)}
|
|
|
6284
6728
|
stream: false,
|
|
6285
6729
|
options: { temperature: 0.3, num_predict: 100 }
|
|
6286
6730
|
});
|
|
6287
|
-
const summary$ = data$.pipe((0,
|
|
6288
|
-
const summary = await (0,
|
|
6731
|
+
const summary$ = data$.pipe((0, import_rxjs14.map)((d) => d.response.trim()));
|
|
6732
|
+
const summary = await (0, import_rxjs14.lastValueFrom)(summary$);
|
|
6289
6733
|
debugLogger.ragDebug("summarizeDocument result", { name, summary });
|
|
6290
6734
|
return summary || `Document summary for ${name}`;
|
|
6291
6735
|
} catch (error) {
|
|
@@ -6295,7 +6739,7 @@ ${content.slice(0, 4e3)}
|
|
|
6295
6739
|
};
|
|
6296
6740
|
|
|
6297
6741
|
// src/services/prompts/documentRelevance.ts
|
|
6298
|
-
var
|
|
6742
|
+
var import_rxjs15 = require("rxjs");
|
|
6299
6743
|
init_aiProviderStore();
|
|
6300
6744
|
init_packageSettingsStore();
|
|
6301
6745
|
init_debugLogger();
|
|
@@ -9363,26 +9807,7 @@ var AIProviderInitService = class _AIProviderInitService {
|
|
|
9363
9807
|
if (providerConfig.type === "anthropic" /* ANTHROPIC */) {
|
|
9364
9808
|
providerConfig = this.convertAnthropicConfig(providerConfig, settings?.gatewayApiUrl);
|
|
9365
9809
|
}
|
|
9366
|
-
|
|
9367
|
-
providerConfig.tokenFactory = () => {
|
|
9368
|
-
let token = authenticationService.getToken();
|
|
9369
|
-
if (!token) {
|
|
9370
|
-
token = localStorage.getItem("authToken");
|
|
9371
|
-
}
|
|
9372
|
-
if (!token) {
|
|
9373
|
-
try {
|
|
9374
|
-
const { useAuthenticationStore: useAuthenticationStore2 } = require("../../store/authenticationStore");
|
|
9375
|
-
const authStore = useAuthenticationStore2.getState();
|
|
9376
|
-
token = authStore.token;
|
|
9377
|
-
} catch (e) {
|
|
9378
|
-
}
|
|
9379
|
-
}
|
|
9380
|
-
debugLogger.info("AI Provider Init: IndexedDB config token factory", {
|
|
9381
|
-
hasToken: !!token
|
|
9382
|
-
});
|
|
9383
|
-
return token;
|
|
9384
|
-
};
|
|
9385
|
-
}
|
|
9810
|
+
providerConfig = this.ensureTokenFactory(providerConfig);
|
|
9386
9811
|
try {
|
|
9387
9812
|
const { createProvider } = useAIProviderStore.getState();
|
|
9388
9813
|
createProvider(providerConfig);
|
|
@@ -9410,27 +9835,7 @@ var AIProviderInitService = class _AIProviderInitService {
|
|
|
9410
9835
|
if (providerConfig.type === "anthropic" /* ANTHROPIC */) {
|
|
9411
9836
|
providerConfig = this.convertAnthropicConfig(providerConfig, settings.gatewayApiUrl);
|
|
9412
9837
|
}
|
|
9413
|
-
|
|
9414
|
-
providerConfig.tokenFactory = () => {
|
|
9415
|
-
let token = authenticationService.getToken();
|
|
9416
|
-
if (!token) {
|
|
9417
|
-
token = localStorage.getItem("authToken");
|
|
9418
|
-
}
|
|
9419
|
-
if (!token) {
|
|
9420
|
-
try {
|
|
9421
|
-
const { useAuthenticationStore: useAuthenticationStore2 } = require("../../store/authenticationStore");
|
|
9422
|
-
const authStore = useAuthenticationStore2.getState();
|
|
9423
|
-
token = authStore.token;
|
|
9424
|
-
} catch (e) {
|
|
9425
|
-
}
|
|
9426
|
-
}
|
|
9427
|
-
debugLogger.info("AIProviderInit: Explicit config tokenFactory", {
|
|
9428
|
-
hasToken: !!token,
|
|
9429
|
-
localStorage: !!localStorage.getItem("authToken")
|
|
9430
|
-
});
|
|
9431
|
-
return token;
|
|
9432
|
-
};
|
|
9433
|
-
}
|
|
9838
|
+
providerConfig = this.ensureTokenFactory(providerConfig);
|
|
9434
9839
|
debugLogger.info("Using explicit AI provider config", providerConfig);
|
|
9435
9840
|
} else {
|
|
9436
9841
|
providerConfig = {
|
|
@@ -9542,9 +9947,10 @@ var AIProviderInitService = class _AIProviderInitService {
|
|
|
9542
9947
|
*/
|
|
9543
9948
|
switchProvider(config) {
|
|
9544
9949
|
try {
|
|
9950
|
+
const normalizedConfig = this.ensureTokenFactory({ ...config });
|
|
9545
9951
|
const { switchProvider } = useAIProviderStore.getState();
|
|
9546
|
-
switchProvider(
|
|
9547
|
-
debugLogger.info(`Switched to AI provider: ${
|
|
9952
|
+
switchProvider(normalizedConfig);
|
|
9953
|
+
debugLogger.info(`Switched to AI provider: ${normalizedConfig.type}`);
|
|
9548
9954
|
} catch (error) {
|
|
9549
9955
|
debugLogger.error("Failed to switch AI provider:", { error });
|
|
9550
9956
|
throw error;
|
|
@@ -9578,6 +9984,49 @@ var AIProviderInitService = class _AIProviderInitService {
|
|
|
9578
9984
|
debugLogger.info("AI Provider Init: Converted direct Anthropic provider to gateway configuration");
|
|
9579
9985
|
return normalized;
|
|
9580
9986
|
}
|
|
9987
|
+
/**
|
|
9988
|
+
* Ensure providers that require auth have a token factory configured.
|
|
9989
|
+
* Handles both UI auth tokens and API key scenarios.
|
|
9990
|
+
*/
|
|
9991
|
+
ensureTokenFactory(config) {
|
|
9992
|
+
if (config.type === "ollama" /* OLLAMA */ || config.type === "gateway" /* GATEWAY */) {
|
|
9993
|
+
const existingFactory = config.tokenFactory;
|
|
9994
|
+
if (existingFactory) {
|
|
9995
|
+
return config;
|
|
9996
|
+
}
|
|
9997
|
+
if (typeof config.apiKey === "string" && config.apiKey.trim() !== "") {
|
|
9998
|
+
const key = config.apiKey.trim();
|
|
9999
|
+
config.tokenFactory = () => key;
|
|
10000
|
+
debugLogger.info("AIProviderInit: Using API key for token factory", {
|
|
10001
|
+
type: config.type,
|
|
10002
|
+
hasKey: true
|
|
10003
|
+
});
|
|
10004
|
+
return config;
|
|
10005
|
+
}
|
|
10006
|
+
config.tokenFactory = () => {
|
|
10007
|
+
let token = authenticationService.getToken();
|
|
10008
|
+
if (!token && typeof localStorage !== "undefined") {
|
|
10009
|
+
try {
|
|
10010
|
+
token = localStorage.getItem("authToken");
|
|
10011
|
+
} catch {
|
|
10012
|
+
}
|
|
10013
|
+
}
|
|
10014
|
+
if (!token) {
|
|
10015
|
+
try {
|
|
10016
|
+
const { useAuthenticationStore: useAuthenticationStore2 } = require("../../store/authenticationStore");
|
|
10017
|
+
const authStore = useAuthenticationStore2.getState();
|
|
10018
|
+
token = authStore.token;
|
|
10019
|
+
} catch {
|
|
10020
|
+
}
|
|
10021
|
+
}
|
|
10022
|
+
debugLogger.info("AIProviderInit: Token factory resolved auth token", {
|
|
10023
|
+
hasToken: !!token
|
|
10024
|
+
});
|
|
10025
|
+
return token;
|
|
10026
|
+
};
|
|
10027
|
+
}
|
|
10028
|
+
return config;
|
|
10029
|
+
}
|
|
9581
10030
|
};
|
|
9582
10031
|
var aiProviderInitService = AIProviderInitService.getInstance();
|
|
9583
10032
|
|