@burtson-labs/bandit-engine 2.0.39 → 2.0.40

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/dist/{aiProviderStore-XN7GCBHJ.mjs → aiProviderStore-JMA5RWX7.mjs} +2 -2
  2. package/dist/{chat-5QJNWB7I.mjs → chat-JMWPOSQ4.mjs} +5 -5
  3. package/dist/chat-provider.js +421 -20
  4. package/dist/chat-provider.js.map +1 -1
  5. package/dist/chat-provider.mjs +4 -4
  6. package/dist/{chunk-WO5KFNNW.mjs → chunk-26QQ4CLA.mjs} +62 -24
  7. package/dist/chunk-26QQ4CLA.mjs.map +1 -0
  8. package/dist/{chunk-CDQYBO3Q.mjs → chunk-2ZCR2TDY.mjs} +27 -5
  9. package/dist/chunk-2ZCR2TDY.mjs.map +1 -0
  10. package/dist/{chunk-ECRNIAG6.mjs → chunk-6ELNWXKC.mjs} +4 -4
  11. package/dist/{chunk-EOKIE5HZ.mjs → chunk-75W5VWPV.mjs} +3 -3
  12. package/dist/{chunk-JRCDANLN.mjs → chunk-7KEBNVCO.mjs} +67 -9
  13. package/dist/{chunk-JRCDANLN.mjs.map → chunk-7KEBNVCO.mjs.map} +1 -1
  14. package/dist/{chunk-3A2527TE.mjs → chunk-D3AGKOM6.mjs} +3 -3
  15. package/dist/{chunk-QU5S5QQP.mjs → chunk-QJYPWWA5.mjs} +379 -18
  16. package/dist/chunk-QJYPWWA5.mjs.map +1 -0
  17. package/dist/{chunk-QYH2T4L5.mjs → chunk-VIYBZO5W.mjs} +3 -3
  18. package/dist/{cli/cli.js → cli.js} +423 -10
  19. package/dist/cli.js.map +1 -0
  20. package/dist/{gateway-B0LJ3-jT.d.ts → gateway-5yt_3QDP.d.mts} +4 -4
  21. package/dist/{gateway-B0LJ3-jT.d.mts → gateway-5yt_3QDP.d.ts} +4 -4
  22. package/dist/index.d.mts +2 -2
  23. package/dist/index.d.ts +2 -2
  24. package/dist/index.js +598 -101
  25. package/dist/index.js.map +1 -1
  26. package/dist/index.mjs +8 -8
  27. package/dist/management/management.js +596 -99
  28. package/dist/management/management.js.map +1 -1
  29. package/dist/management/management.mjs +6 -6
  30. package/dist/modals/chat-modal/chat-modal.js +430 -29
  31. package/dist/modals/chat-modal/chat-modal.js.map +1 -1
  32. package/dist/modals/chat-modal/chat-modal.mjs +4 -4
  33. package/dist/public-types.d.mts +1 -1
  34. package/dist/public-types.d.ts +1 -1
  35. package/package.json +1 -1
  36. package/dist/chunk-CDQYBO3Q.mjs.map +0 -1
  37. package/dist/chunk-QU5S5QQP.mjs.map +0 -1
  38. package/dist/chunk-WO5KFNNW.mjs.map +0 -1
  39. package/dist/cli/cli.js.map +0 -1
  40. /package/dist/{aiProviderStore-XN7GCBHJ.mjs.map → aiProviderStore-JMA5RWX7.mjs.map} +0 -0
  41. /package/dist/{chat-5QJNWB7I.mjs.map → chat-JMWPOSQ4.mjs.map} +0 -0
  42. /package/dist/{chunk-ECRNIAG6.mjs.map → chunk-6ELNWXKC.mjs.map} +0 -0
  43. /package/dist/{chunk-EOKIE5HZ.mjs.map → chunk-75W5VWPV.mjs.map} +0 -0
  44. /package/dist/{chunk-3A2527TE.mjs.map → chunk-D3AGKOM6.mjs.map} +0 -0
  45. /package/dist/{chunk-QYH2T4L5.mjs.map → chunk-VIYBZO5W.mjs.map} +0 -0
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-ONQMRE2G.mjs";
4
4
  import {
5
5
  aiProviderInitService
6
- } from "./chunk-EOKIE5HZ.mjs";
6
+ } from "./chunk-75W5VWPV.mjs";
7
7
  import {
8
8
  useMCPToolsStore
9
9
  } from "./chunk-RTQDQ6TC.mjs";
@@ -20,7 +20,7 @@ import {
20
20
  useKnowledgeStore2,
21
21
  useMemoryStore,
22
22
  useProjectStore
23
- } from "./chunk-CDQYBO3Q.mjs";
23
+ } from "./chunk-2ZCR2TDY.mjs";
24
24
  import {
25
25
  indexedDBService_default,
26
26
  useModelStore,
@@ -157,4 +157,4 @@ export {
157
157
  ChatProvider,
158
158
  chat_provider_default
159
159
  };
160
- //# sourceMappingURL=chunk-3A2527TE.mjs.map
160
+ //# sourceMappingURL=chunk-D3AGKOM6.mjs.map
@@ -1015,7 +1015,7 @@ var AnthropicProvider = class {
1015
1015
  };
1016
1016
 
1017
1017
  // src/services/ai-provider/providers/gateway.provider.ts
1018
- import { map as map11 } from "rxjs";
1018
+ import { map as map12 } from "rxjs";
1019
1019
 
1020
1020
  // src/services/gateway/gateway.service.ts
1021
1021
  import axios, { AxiosHeaders } from "axios";
@@ -1164,13 +1164,17 @@ var GatewayService = class {
1164
1164
  chat(request) {
1165
1165
  const endpoint = request.provider === "ollama" ? `/api/${request.provider}/chat` : request.provider ? `/api/${request.provider}/chat/completions` : "/api/chat/completions";
1166
1166
  const url = `${this._baseUrl}${endpoint}`;
1167
+ const normalizedModel = request.provider === "bandit" ? (() => {
1168
+ const trimmed = (request.model ?? "").replace(/^bandit:/, "").trim();
1169
+ return trimmed !== "" ? trimmed : "bandit-core-1";
1170
+ })() : request.model;
1167
1171
  debugLogger.debug(`Gateway chat request to ${url} with provider: ${request.provider || "default"}`, {
1168
- model: request.model,
1172
+ model: normalizedModel,
1169
1173
  messageCount: request.messages.length,
1170
1174
  hasImages: !!(request.images && request.images.length > 0),
1171
1175
  imageCount: request.images?.length || 0
1172
1176
  });
1173
- const requestBody = { ...request, stream: request.stream !== false };
1177
+ const requestBody = { ...request, model: normalizedModel, stream: request.stream !== false };
1174
1178
  return new Observable6((observer) => {
1175
1179
  const controller = new AbortController();
1176
1180
  const task = fetch(url, {
@@ -1310,12 +1314,18 @@ var GatewayService = class {
1310
1314
  generate(request) {
1311
1315
  const endpoint = request.provider ? `/api/${request.provider}/generate` : "/api/generate";
1312
1316
  const url = `${this._baseUrl}${endpoint}`;
1313
- debugLogger.debug(`Gateway generate request to ${url} with provider: ${request.provider || "default"}`);
1317
+ const normalizedModel = request.provider === "bandit" ? (() => {
1318
+ const trimmed = (request.model ?? "").replace(/^bandit:/, "").trim();
1319
+ return trimmed !== "" ? trimmed : "bandit-core-1";
1320
+ })() : request.model;
1321
+ debugLogger.debug(`Gateway generate request to ${url} with provider: ${request.provider || "default"}`, {
1322
+ model: normalizedModel
1323
+ });
1314
1324
  return new Observable6((observer) => {
1315
1325
  const task = fetch(url, {
1316
1326
  method: "POST",
1317
1327
  headers: this._getHeaders(),
1318
- body: JSON.stringify({ ...request, stream: request.stream !== false })
1328
+ body: JSON.stringify({ ...request, model: normalizedModel, stream: request.stream !== false })
1319
1329
  });
1320
1330
  task.then(async (response) => {
1321
1331
  if (!response.ok) {
@@ -1879,6 +1889,104 @@ var OllamaGatewayService = class {
1879
1889
  }
1880
1890
  };
1881
1891
 
1892
+ // src/services/gateway/bandit-gateway.service.ts
1893
+ import { map as map11 } from "rxjs/operators";
1894
+ var normalizeBanditModel = (model) => {
1895
+ if (typeof model !== "string" || model.trim() === "") {
1896
+ return "bandit-core-1";
1897
+ }
1898
+ const normalized = model.replace(/^bandit:/, "").trim();
1899
+ return normalized === "" ? "bandit-core-1" : normalized;
1900
+ };
1901
+ var isGatewayMessageContent = (value) => {
1902
+ if (!value || typeof value !== "object") return false;
1903
+ const candidate = value;
1904
+ if (candidate.type !== "text" && candidate.type !== "image_url") {
1905
+ return false;
1906
+ }
1907
+ if (candidate.type === "text") {
1908
+ return typeof candidate.text === "string";
1909
+ }
1910
+ if (candidate.type === "image_url") {
1911
+ return !!candidate.image_url && typeof candidate.image_url.url === "string";
1912
+ }
1913
+ return false;
1914
+ };
1915
+ var normalizeBanditMessages = (messages) => messages.map((message) => {
1916
+ const content = message.content;
1917
+ if (typeof content === "string") {
1918
+ return { role: message.role, content };
1919
+ }
1920
+ if (Array.isArray(content)) {
1921
+ const filtered = content.filter(isGatewayMessageContent);
1922
+ if (filtered.length === 0) {
1923
+ return { role: message.role, content: JSON.stringify(content) };
1924
+ }
1925
+ return {
1926
+ role: message.role,
1927
+ content: filtered
1928
+ };
1929
+ }
1930
+ return { role: message.role, content: content != null ? String(content) : "" };
1931
+ });
1932
+ var BanditAIGatewayService = class {
1933
+ _gatewayService;
1934
+ constructor(gatewayUrl, tokenFactory) {
1935
+ this._gatewayService = new GatewayService(gatewayUrl, tokenFactory);
1936
+ debugLogger.info("BanditAIGatewayService initialized", { gatewayUrl });
1937
+ }
1938
+ async validateServiceAvailability(args) {
1939
+ return this._gatewayService.validateServiceAvailability(args);
1940
+ }
1941
+ chat(request) {
1942
+ const model = normalizeBanditModel(request.model);
1943
+ const messages = normalizeBanditMessages(request.messages);
1944
+ const gatewayRequest = {
1945
+ ...request,
1946
+ messages,
1947
+ model,
1948
+ provider: "bandit",
1949
+ stream: request.stream
1950
+ };
1951
+ debugLogger.debug("Bandit Gateway chat request", {
1952
+ model,
1953
+ messageCount: request.messages.length,
1954
+ stream: request.stream
1955
+ });
1956
+ return this._gatewayService.chat(gatewayRequest);
1957
+ }
1958
+ complete(prompt, options) {
1959
+ const model = normalizeBanditModel(options.model);
1960
+ const gatewayRequest = {
1961
+ model,
1962
+ prompt,
1963
+ temperature: options.temperature,
1964
+ max_tokens: options.max_tokens,
1965
+ stream: options.stream,
1966
+ stop: options.stop,
1967
+ provider: "bandit"
1968
+ };
1969
+ debugLogger.debug("Bandit Gateway generate request", {
1970
+ model,
1971
+ promptLength: prompt.length,
1972
+ stream: options.stream
1973
+ });
1974
+ return this._gatewayService.generate(gatewayRequest);
1975
+ }
1976
+ listModels() {
1977
+ debugLogger.debug("Fetching Bandit models through gateway");
1978
+ return this._gatewayService.listModelsByProvider("bandit");
1979
+ }
1980
+ getHealth() {
1981
+ return this._gatewayService.getHealth().pipe(
1982
+ map11((health) => ({
1983
+ ...health,
1984
+ bandit_status: health.providers.find((p) => p.name === "bandit")?.status || "unavailable"
1985
+ }))
1986
+ );
1987
+ }
1988
+ };
1989
+
1882
1990
  // src/services/ai-provider/providers/gateway.provider.ts
1883
1991
  var GatewayProvider = class {
1884
1992
  config;
@@ -1921,6 +2029,9 @@ var GatewayProvider = class {
1921
2029
  case "anthropic":
1922
2030
  this.providerSpecificService = new AnthropicGatewayService(gatewayUrl, tokenFactory);
1923
2031
  break;
2032
+ case "bandit":
2033
+ this.providerSpecificService = new BanditAIGatewayService(gatewayUrl, tokenFactory);
2034
+ break;
1924
2035
  case "ollama":
1925
2036
  this.providerSpecificService = new OllamaGatewayService(gatewayUrl, tokenFactory);
1926
2037
  break;
@@ -1935,6 +2046,16 @@ var GatewayProvider = class {
1935
2046
  role: msg.role,
1936
2047
  content: msg.content
1937
2048
  }));
2049
+ const normalizeImageUrl2 = (value) => {
2050
+ if (!value) {
2051
+ return value;
2052
+ }
2053
+ const trimmed = value.trim();
2054
+ if (/^data:/i.test(trimmed) || /^https?:\/\//i.test(trimmed)) {
2055
+ return trimmed;
2056
+ }
2057
+ return `data:image/jpeg;base64,${trimmed}`;
2058
+ };
1938
2059
  if (request.images && request.images.length > 0) {
1939
2060
  const lastUserMessageIndex = messages.map((m) => m.role).lastIndexOf("user");
1940
2061
  if (this.config.provider === "ollama") {
@@ -1944,7 +2065,7 @@ var GatewayProvider = class {
1944
2065
  images: request.images
1945
2066
  };
1946
2067
  }
1947
- } else if (["openai", "azure-openai", "anthropic"].includes(this.config.provider || "")) {
2068
+ } else if (["openai", "azure-openai", "anthropic", "bandit"].includes(this.config.provider || "")) {
1948
2069
  if (lastUserMessageIndex !== -1) {
1949
2070
  const currentMessage = messages[lastUserMessageIndex];
1950
2071
  const contentArray = [
@@ -1953,11 +2074,11 @@ var GatewayProvider = class {
1953
2074
  text: currentMessage.content
1954
2075
  }
1955
2076
  ];
1956
- request.images.forEach((base64Image) => {
2077
+ request.images.forEach((imageRef) => {
1957
2078
  contentArray.push({
1958
2079
  type: "image_url",
1959
2080
  image_url: {
1960
- url: base64Image.startsWith("data:") ? base64Image : `data:image/jpeg;base64,${base64Image}`,
2081
+ url: normalizeImageUrl2(imageRef),
1961
2082
  detail: "auto"
1962
2083
  }
1963
2084
  });
@@ -1966,6 +2087,11 @@ var GatewayProvider = class {
1966
2087
  ...messages[lastUserMessageIndex],
1967
2088
  content: contentArray
1968
2089
  };
2090
+ debugLogger.debug("Gateway provider injected image attachments", {
2091
+ provider: this.config.provider,
2092
+ imageCount: request.images.length,
2093
+ messageIndex: lastUserMessageIndex
2094
+ });
1969
2095
  }
1970
2096
  }
1971
2097
  }
@@ -1994,7 +2120,7 @@ var GatewayProvider = class {
1994
2120
  }))
1995
2121
  });
1996
2122
  return this.gatewayService.chat(gatewayRequest).pipe(
1997
- map11((response) => ({
2123
+ map12((response) => ({
1998
2124
  message: {
1999
2125
  content: response.choices?.[0]?.message?.content || response.choices?.[0]?.delta?.content || "",
2000
2126
  role: "assistant"
@@ -2017,7 +2143,7 @@ var GatewayProvider = class {
2017
2143
  stream: request.stream
2018
2144
  });
2019
2145
  return this.gatewayService.generate(gatewayRequest).pipe(
2020
- map11((response) => ({
2146
+ map12((response) => ({
2021
2147
  response: response.response || "",
2022
2148
  done: response.done || false
2023
2149
  }))
@@ -2027,7 +2153,7 @@ var GatewayProvider = class {
2027
2153
  debugLogger.debug("Gateway provider listing models", { provider: this.config.provider });
2028
2154
  if (this.config.provider) {
2029
2155
  return this.gatewayService.listModelsByProvider(this.config.provider).pipe(
2030
- map11((models) => models.map((model) => ({
2156
+ map12((models) => models.map((model) => ({
2031
2157
  name: model.id || model.name,
2032
2158
  size: model.size,
2033
2159
  details: model.details,
@@ -2037,7 +2163,7 @@ var GatewayProvider = class {
2037
2163
  );
2038
2164
  } else {
2039
2165
  return this.gatewayService.listModels().pipe(
2040
- map11((models) => models.map((model) => ({
2166
+ map12((models) => models.map((model) => ({
2041
2167
  name: model.id || model.name,
2042
2168
  size: model.size,
2043
2169
  details: model.details,
@@ -2068,7 +2194,7 @@ var GatewayProvider = class {
2068
2194
  */
2069
2195
  getHealth() {
2070
2196
  return this.gatewayService.getHealth().pipe(
2071
- map11((health) => ({
2197
+ map12((health) => ({
2072
2198
  ...health,
2073
2199
  backend_provider: this.config.provider,
2074
2200
  backend_provider_status: health.providers.find((p) => p.name === this.config.provider)?.status || "unavailable"
@@ -2256,7 +2382,7 @@ var PlaygroundProvider = class {
2256
2382
  };
2257
2383
 
2258
2384
  // src/services/ai-provider/providers/xai.provider.ts
2259
- import { Observable as Observable9, from as from6, switchMap as switchMap5, map as map12, throwError as throwError5 } from "rxjs";
2385
+ import { Observable as Observable9, from as from6, switchMap as switchMap5, map as map13, throwError as throwError5 } from "rxjs";
2260
2386
  var XAIProvider = class {
2261
2387
  config;
2262
2388
  baseUrl;
@@ -2287,7 +2413,7 @@ var XAIProvider = class {
2287
2413
  options: request.options
2288
2414
  };
2289
2415
  return this.chat(chatRequest).pipe(
2290
- map12((response) => ({
2416
+ map13((response) => ({
2291
2417
  response: response.message.content,
2292
2418
  done: response.done
2293
2419
  }))
@@ -2304,7 +2430,7 @@ var XAIProvider = class {
2304
2430
  }
2305
2431
  return from6(response.json());
2306
2432
  }),
2307
- map12(
2433
+ map13(
2308
2434
  (data) => data.data.map((model) => ({
2309
2435
  name: model.id,
2310
2436
  details: {
@@ -2439,7 +2565,237 @@ var XAIProvider = class {
2439
2565
  }
2440
2566
  return from6(response.json());
2441
2567
  }),
2442
- map12((data) => ({
2568
+ map13((data) => ({
2569
+ message: {
2570
+ content: data.choices?.[0]?.message?.content ?? "",
2571
+ role: "assistant"
2572
+ },
2573
+ done: true
2574
+ }))
2575
+ );
2576
+ }
2577
+ getHeaders() {
2578
+ const headers = {};
2579
+ if (this.config.apiKey) {
2580
+ headers["Authorization"] = `Bearer ${this.config.apiKey}`;
2581
+ }
2582
+ return headers;
2583
+ }
2584
+ };
2585
+
2586
+ // src/services/ai-provider/providers/bandit-ai.provider.ts
2587
+ import { Observable as Observable10, from as from7, switchMap as switchMap6, map as map14, throwError as throwError6 } from "rxjs";
2588
+ var DEFAULT_BANDIT_BASE = "https://api.burtson.ai";
2589
+ var normalizeImageUrl = (value) => {
2590
+ if (!value) {
2591
+ return null;
2592
+ }
2593
+ const trimmed = value.trim();
2594
+ if (!trimmed) {
2595
+ return null;
2596
+ }
2597
+ if (/^data:/i.test(trimmed) || /^https?:\/\//i.test(trimmed)) {
2598
+ return trimmed;
2599
+ }
2600
+ return `data:image/jpeg;base64,${trimmed}`;
2601
+ };
2602
+ var injectImagesIntoMessages = (messages, images) => {
2603
+ const normalized = messages.map((message) => ({
2604
+ role: message.role,
2605
+ content: message.content
2606
+ }));
2607
+ if (!images || images.length === 0) {
2608
+ return normalized;
2609
+ }
2610
+ const normalizedImages = images.map(normalizeImageUrl).filter((url) => Boolean(url));
2611
+ if (normalizedImages.length === 0) {
2612
+ return normalized;
2613
+ }
2614
+ const lastUserIndex = normalized.map((msg) => msg.role).lastIndexOf("user");
2615
+ if (lastUserIndex === -1) {
2616
+ return normalized;
2617
+ }
2618
+ const target = normalized[lastUserIndex];
2619
+ const baseContent = typeof target.content === "string" && target.content.trim().length > 0 ? [
2620
+ {
2621
+ type: "text",
2622
+ text: target.content
2623
+ }
2624
+ ] : [];
2625
+ const imageContent = normalizedImages.map((url) => ({
2626
+ type: "image_url",
2627
+ image_url: { url, detail: "auto" }
2628
+ }));
2629
+ normalized[lastUserIndex] = {
2630
+ role: target.role,
2631
+ content: [...baseContent, ...imageContent]
2632
+ };
2633
+ return normalized;
2634
+ };
2635
+ var BanditAIProvider = class {
2636
+ config;
2637
+ baseUrl;
2638
+ constructor(config) {
2639
+ this.config = config;
2640
+ this.baseUrl = (config.baseUrl || DEFAULT_BANDIT_BASE).replace(/\/$/, "");
2641
+ }
2642
+ chat(request) {
2643
+ const url = `${this.baseUrl}/chat/completions`;
2644
+ const messages = injectImagesIntoMessages(request.messages, request.images);
2645
+ const payload = {
2646
+ model: request.model,
2647
+ messages,
2648
+ stream: Boolean(request.stream),
2649
+ temperature: request.temperature,
2650
+ max_tokens: request.maxTokens
2651
+ };
2652
+ if (request.stream) {
2653
+ return this.streamChatRequest(url, payload);
2654
+ }
2655
+ return this.nonStreamChatRequest(url, payload);
2656
+ }
2657
+ generate(request) {
2658
+ const chatRequest = {
2659
+ model: request.model,
2660
+ messages: [{ role: "user", content: request.prompt }],
2661
+ stream: request.stream,
2662
+ options: request.options
2663
+ };
2664
+ return this.chat(chatRequest).pipe(
2665
+ map14((response) => ({
2666
+ response: response.message.content,
2667
+ done: response.done
2668
+ }))
2669
+ );
2670
+ }
2671
+ listModels() {
2672
+ const url = `${this.baseUrl}/models`;
2673
+ return from7(fetch(url, { headers: this.getHeaders() })).pipe(
2674
+ switchMap6((response) => {
2675
+ if (!response.ok) {
2676
+ debugLogger.error("BanditAI listModels failed", { status: response.status, url });
2677
+ return throwError6(() => new Error(`Failed to list Bandit models: ${response.status}`));
2678
+ }
2679
+ return from7(response.json());
2680
+ }),
2681
+ map14(
2682
+ (data) => data.data.map((model) => ({
2683
+ name: model.id,
2684
+ details: {
2685
+ format: "bandit",
2686
+ family: model.object
2687
+ }
2688
+ }))
2689
+ )
2690
+ );
2691
+ }
2692
+ async validateServiceAvailability(args) {
2693
+ const attempt = async (url) => {
2694
+ try {
2695
+ const controller = new AbortController();
2696
+ const timeoutId = setTimeout(() => controller.abort(), args.timeoutMs);
2697
+ const response = await fetch(`${url}/models`, {
2698
+ headers: this.getHeaders(),
2699
+ signal: controller.signal
2700
+ });
2701
+ clearTimeout(timeoutId);
2702
+ return response.ok;
2703
+ } catch (error) {
2704
+ debugLogger.warn("BanditAI availability check failed", { url, error });
2705
+ return false;
2706
+ }
2707
+ };
2708
+ const primary = await attempt(this.baseUrl);
2709
+ if (primary) {
2710
+ return { url: this.baseUrl, isAvailable: true };
2711
+ }
2712
+ if (args.fallbackUrl) {
2713
+ const fallback = args.fallbackUrl.replace(/\/$/, "");
2714
+ if (await attempt(fallback)) {
2715
+ this.baseUrl = fallback;
2716
+ return { url: fallback, isAvailable: true };
2717
+ }
2718
+ }
2719
+ return { url: this.baseUrl, isAvailable: false };
2720
+ }
2721
+ getProviderType() {
2722
+ return "bandit" /* BANDIT */;
2723
+ }
2724
+ getConfig() {
2725
+ return this.config;
2726
+ }
2727
+ streamChatRequest(url, payload) {
2728
+ return new Observable10((observer) => {
2729
+ const task = fetch(url, {
2730
+ method: "POST",
2731
+ headers: {
2732
+ ...this.getHeaders(),
2733
+ "Content-Type": "application/json"
2734
+ },
2735
+ body: JSON.stringify(payload)
2736
+ });
2737
+ task.then((response) => {
2738
+ if (!response.ok) {
2739
+ observer.error(new Error(`BanditAI request failed: ${response.status}`));
2740
+ return;
2741
+ }
2742
+ const reader = response.body?.getReader();
2743
+ const decoder = new TextDecoder();
2744
+ let buffer = "";
2745
+ const read = () => {
2746
+ reader?.read().then(({ done, value }) => {
2747
+ if (done) {
2748
+ observer.next({ message: { content: "", role: "assistant" }, done: true });
2749
+ observer.complete();
2750
+ return;
2751
+ }
2752
+ buffer += decoder.decode(value, { stream: true });
2753
+ const lines = buffer.split("\n");
2754
+ buffer = lines.pop() ?? "";
2755
+ for (const rawLine of lines) {
2756
+ const line = rawLine.trim();
2757
+ if (!line.startsWith("data: ")) {
2758
+ continue;
2759
+ }
2760
+ const data = line.slice(6).trim();
2761
+ if (data === "[DONE]") {
2762
+ observer.next({ message: { content: "", role: "assistant" }, done: true });
2763
+ observer.complete();
2764
+ return;
2765
+ }
2766
+ try {
2767
+ const parsed = JSON.parse(data);
2768
+ const content = parsed.choices?.[0]?.delta?.content ?? "";
2769
+ if (content) {
2770
+ observer.next({ message: { content, role: "assistant" }, done: false });
2771
+ }
2772
+ } catch (error) {
2773
+ debugLogger.error("BanditAI stream chunk parse failure", { data, error });
2774
+ }
2775
+ }
2776
+ read();
2777
+ }).catch((err) => observer.error(err));
2778
+ };
2779
+ read();
2780
+ }).catch((err) => observer.error(err));
2781
+ });
2782
+ }
2783
+ nonStreamChatRequest(url, payload) {
2784
+ return from7(fetch(url, {
2785
+ method: "POST",
2786
+ headers: {
2787
+ ...this.getHeaders(),
2788
+ "Content-Type": "application/json"
2789
+ },
2790
+ body: JSON.stringify(payload)
2791
+ })).pipe(
2792
+ switchMap6((response) => {
2793
+ if (!response.ok) {
2794
+ return throwError6(() => new Error(`BanditAI request failed: ${response.status}`));
2795
+ }
2796
+ return from7(response.json());
2797
+ }),
2798
+ map14((data) => ({
2443
2799
  message: {
2444
2800
  content: data.choices?.[0]?.message?.content ?? "",
2445
2801
  role: "assistant"
@@ -2471,6 +2827,8 @@ var AIProviderFactory = class {
2471
2827
  return new AnthropicProvider(config);
2472
2828
  case "xai" /* XAI */:
2473
2829
  return new XAIProvider(config);
2830
+ case "bandit" /* BANDIT */:
2831
+ return new BanditAIProvider(config);
2474
2832
  case "gateway" /* GATEWAY */:
2475
2833
  return new GatewayProvider(config);
2476
2834
  case "playground" /* PLAYGROUND */:
@@ -2485,6 +2843,7 @@ var AIProviderFactory = class {
2485
2843
  "openai" /* OPENAI */,
2486
2844
  "azure-openai" /* AZURE_OPENAI */,
2487
2845
  "xai" /* XAI */,
2846
+ "bandit" /* BANDIT */,
2488
2847
  "gateway" /* GATEWAY */,
2489
2848
  "playground" /* PLAYGROUND */
2490
2849
  ];
@@ -2502,6 +2861,8 @@ var AIProviderFactory = class {
2502
2861
  return !!config.apiKey;
2503
2862
  case "xai" /* XAI */:
2504
2863
  return !!config.apiKey;
2864
+ case "bandit" /* BANDIT */:
2865
+ return !!config.apiKey;
2505
2866
  case "gateway" /* GATEWAY */:
2506
2867
  return !!(config.gatewayUrl && config.provider);
2507
2868
  case "playground" /* PLAYGROUND */:
@@ -2543,4 +2904,4 @@ export {
2543
2904
  AIProviderFactory,
2544
2905
  useAIProviderStore
2545
2906
  };
2546
- //# sourceMappingURL=chunk-QU5S5QQP.mjs.map
2907
+ //# sourceMappingURL=chunk-QJYPWWA5.mjs.map