@burtson-labs/bandit-engine 2.0.40 → 2.0.42

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 (43) hide show
  1. package/README.md +14 -11
  2. package/dist/{aiProviderStore-JMA5RWX7.mjs → aiProviderStore-UQI33C5E.mjs} +2 -2
  3. package/dist/{chat-JMWPOSQ4.mjs → chat-XDC4SNJF.mjs} +5 -5
  4. package/dist/chat-provider.js +156 -106
  5. package/dist/chat-provider.js.map +1 -1
  6. package/dist/chat-provider.mjs +4 -4
  7. package/dist/{chunk-7KEBNVCO.mjs → chunk-4RCAVVDN.mjs} +15 -10
  8. package/dist/{chunk-7KEBNVCO.mjs.map → chunk-4RCAVVDN.mjs.map} +1 -1
  9. package/dist/{chunk-QJYPWWA5.mjs → chunk-54ZQ3FSN.mjs} +104 -61
  10. package/dist/chunk-54ZQ3FSN.mjs.map +1 -0
  11. package/dist/{chunk-26QQ4CLA.mjs → chunk-EOEI74X4.mjs} +4 -4
  12. package/dist/{chunk-6ELNWXKC.mjs → chunk-ERV7GLY3.mjs} +4 -4
  13. package/dist/{chunk-75W5VWPV.mjs → chunk-H4PBQ5LJ.mjs} +51 -46
  14. package/dist/chunk-H4PBQ5LJ.mjs.map +1 -0
  15. package/dist/{chunk-D3AGKOM6.mjs → chunk-KBKWVG7X.mjs} +3 -3
  16. package/dist/{chunk-VIYBZO5W.mjs → chunk-SBNENBUQ.mjs} +3 -3
  17. package/dist/{chunk-2ZCR2TDY.mjs → chunk-UXE67LR7.mjs} +8 -6
  18. package/dist/{chunk-2ZCR2TDY.mjs.map → chunk-UXE67LR7.mjs.map} +1 -1
  19. package/dist/cli.js +1 -1
  20. package/dist/cli.js.map +1 -1
  21. package/dist/index.js +164 -109
  22. package/dist/index.js.map +1 -1
  23. package/dist/index.mjs +8 -8
  24. package/dist/management/management.js +164 -109
  25. package/dist/management/management.js.map +1 -1
  26. package/dist/management/management.mjs +6 -6
  27. package/dist/modals/chat-modal/chat-modal.js +108 -63
  28. package/dist/modals/chat-modal/chat-modal.js.map +1 -1
  29. package/dist/modals/chat-modal/chat-modal.mjs +4 -4
  30. package/docs/01_quickstart.md +10 -4
  31. package/docs/02_gateway_api.md +19 -3
  32. package/docs/03_provider_integration.md +5 -4
  33. package/docs/api_reference/media/02_gateway_api.md +19 -3
  34. package/docs/api_reference/media/README.md +3 -1
  35. package/package.json +1 -1
  36. package/dist/chunk-75W5VWPV.mjs.map +0 -1
  37. package/dist/chunk-QJYPWWA5.mjs.map +0 -1
  38. /package/dist/{aiProviderStore-JMA5RWX7.mjs.map → aiProviderStore-UQI33C5E.mjs.map} +0 -0
  39. /package/dist/{chat-JMWPOSQ4.mjs.map → chat-XDC4SNJF.mjs.map} +0 -0
  40. /package/dist/{chunk-26QQ4CLA.mjs.map → chunk-EOEI74X4.mjs.map} +0 -0
  41. /package/dist/{chunk-6ELNWXKC.mjs.map → chunk-ERV7GLY3.mjs.map} +0 -0
  42. /package/dist/{chunk-D3AGKOM6.mjs.map → chunk-KBKWVG7X.mjs.map} +0 -0
  43. /package/dist/{chunk-VIYBZO5W.mjs.map → chunk-SBNENBUQ.mjs.map} +0 -0
@@ -3,11 +3,11 @@ import {
3
3
  MAX_WINDOWED_HEIGHT,
4
4
  MIN_WINDOWED_HEIGHT,
5
5
  chat_modal_default
6
- } from "../../chunk-6ELNWXKC.mjs";
7
- import "../../chunk-VIYBZO5W.mjs";
8
- import "../../chunk-2ZCR2TDY.mjs";
6
+ } from "../../chunk-ERV7GLY3.mjs";
7
+ import "../../chunk-SBNENBUQ.mjs";
8
+ import "../../chunk-UXE67LR7.mjs";
9
9
  import "../../chunk-XUBYA5I7.mjs";
10
- import "../../chunk-QJYPWWA5.mjs";
10
+ import "../../chunk-54ZQ3FSN.mjs";
11
11
  import "../../chunk-KCI46M23.mjs";
12
12
  import "../../chunk-BJTO5JO5.mjs";
13
13
  export {
@@ -7,6 +7,7 @@ The quickstart gateway exposes the contract Bandit expects out of the box:
7
7
  - `GET /api/health` — confirm connectivity and list configured providers.
8
8
  - `GET /api/models` and `GET /api/models/:provider` — populate the model switcher and provider tabs.
9
9
  - `POST /api/chat/completions` and `POST /api/generate` — default OpenAI-style chat/generation when no provider override is supplied.
10
+ - `POST /api/bandit/chat/completions` — Bandit AI chat completions (OpenAI-compatible).
10
11
  - `POST /api/openai|azure-openai|anthropic/chat/completions` — provider-scoped chat completions.
11
12
  - `POST /api/openai|azure-openai|anthropic/generate` — provider-scoped text generation.
12
13
  - `POST /api/ollama/chat` and `POST /api/ollama/generate` — native Ollama streaming routes.
@@ -23,16 +24,21 @@ The quickstart gateway exposes the contract Bandit expects out of the box:
23
24
  npm install
24
25
  npm run dev
25
26
  ```
26
- The example server listens on `http://localhost:8080` and proxies to OpenAI, Azure OpenAI, Anthropic, or Ollama using provider-scoped endpoints. Providers without credentials respond with `501` until you wire them up.
27
+ The example server listens on `http://localhost:8080` and proxies to Bandit AI, OpenAI, Azure OpenAI, Anthropic, or Ollama using provider-scoped endpoints. Providers without credentials respond with `501` until you wire them up.
27
28
  3. **Wrap your app with `ChatProvider`**:
28
29
  ```tsx
29
30
  import { ChatProvider } from "@burtson-labs/bandit-engine";
30
31
 
31
32
  <ChatProvider
32
33
  packageSettings={{
33
- gatewayApiUrl: "http://localhost:8080",
34
- defaultModel: "gpt-4.1-mini",
35
- brandingConfigUrl: "/config.json"
34
+ gatewayApiUrl: "http://localhost:8080/api",
35
+ defaultModel: "bandit-core-1",
36
+ brandingConfigUrl: "/config.json",
37
+ aiProvider: {
38
+ type: "gateway",
39
+ gatewayUrl: "http://localhost:8080/api",
40
+ provider: "bandit"
41
+ }
36
42
  }}
37
43
  >
38
44
  {/* your routes */}
@@ -18,16 +18,18 @@ Every request must include `Authorization: Bearer <token>`. Tokens are injected
18
18
  | `/api/tts`, `/api/stt`, `/api/tts/available-models` | POST/GET | Optional voice endpoints for advanced deployments. |
19
19
 
20
20
  ### Provider-specific chat/generation routes
21
- When the UI specifies a provider (OpenAI, Azure OpenAI, Anthropic, Ollama), Bandit Engine switches to provider-scoped endpoints automatically. Implement these routes alongside the core ones above:
21
+ When the UI specifies a provider (Bandit AI, OpenAI, Azure OpenAI, Anthropic, Ollama), Bandit Engine switches to provider-scoped endpoints automatically. Implement these routes alongside the core ones above:
22
22
 
23
23
  | Provider | Chat endpoint | Generation endpoint |
24
24
  | --- | --- | --- |
25
+ | Bandit AI | `POST /api/bandit/chat/completions` | `POST /api/bandit/generate`* |
25
26
  | OpenAI | `POST /api/openai/chat/completions` | `POST /api/openai/generate` |
26
27
  | Azure OpenAI | `POST /api/azure-openai/chat/completions` | `POST /api/azure-openai/generate` |
27
28
  | Anthropic | `POST /api/anthropic/chat/completions` | `POST /api/anthropic/generate` |
28
29
  | Ollama | `POST /api/ollama/chat` | `POST /api/ollama/generate` |
29
30
 
30
- > ℹ️ Bandit still includes the `provider` field in the request body for convenience, but the URL itself determines which upstream integration should run. Ollama uses `/chat` (not `/chat/completions`) to match its native API.
31
+ > ℹ️ Bandit still includes the `provider` field in the request body for convenience, but the URL itself determines which upstream integration should run. Ollama uses `/chat` (not `/chat/completions`) to match its native API.
32
+ > \* `POST /api/bandit/generate` is optional today but mirrors the shape of `/api/chat/completions` for parity with other providers.
31
33
 
32
34
  If you only support a single upstream provider you may implement the matching provider-specific endpoints and omit the others. The `/api/chat/completions` and `/api/generate` routes remain useful as a “default” path when the frontend has no explicit provider preference.
33
35
 
@@ -42,11 +44,25 @@ app.use(express.json());
42
44
  app.get("/api/health", (req, res) => {
43
45
  res.json({
44
46
  status: "healthy",
45
- providers: ["openai", "ollama"],
47
+ providers: ["bandit", "openai", "ollama"],
46
48
  version: "1.0.0"
47
49
  });
48
50
  });
49
51
 
52
+ app.post("/api/bandit/chat/completions", async (req, res) => {
53
+ const response = await fetch(`${process.env.GATEWAY_URL}/completions`, {
54
+ method: "POST",
55
+ headers: {
56
+ "Content-Type": "application/json",
57
+ Authorization: `Bearer ${process.env.BANDIT_API_KEY}`
58
+ },
59
+ body: JSON.stringify(req.body)
60
+ });
61
+
62
+ res.status(response.status);
63
+ response.body?.pipe(res);
64
+ });
65
+
50
66
  app.post("/api/openai/chat/completions", async (req, res) => {
51
67
  const { model, messages, stream = true } = req.body;
52
68
 
@@ -3,7 +3,7 @@
3
3
  Bandit Engine routes every model invocation through your gateway but preserves provider-specific capabilities such as multimodal prompts, Azure deployment parameters, and local Ollama streaming. This guide summarizes the nuances for each supported provider and how to combine them with Bandit's feature flag system.
4
4
 
5
5
  ## Endpoints / API Usage
6
- - `POST /api/{provider}/chat/completions` — automatically selected when `provider` is set to `openai`, `azure-openai`, or `anthropic`.
6
+ - `POST /api/{provider}/chat/completions` — automatically selected when `provider` is set to `bandit`, `openai`, `azure-openai`, `anthropic`, or `xai`.
7
7
  - `POST /api/{provider}/generate` — optional non-chat endpoint for custom workloads.
8
8
  - `GET /api/models/{provider}` — provider-specific model listing exposed in the management UI.
9
9
 
@@ -12,17 +12,18 @@ Bandit Engine routes every model invocation through your gateway but preserves p
12
12
  import { GatewayProvider } from "@burtson-labs/bandit-engine";
13
13
 
14
14
  const provider = new GatewayProvider({
15
- provider: "openai",
15
+ provider: "bandit",
16
16
  gatewayUrl: "https://gateway.example.com",
17
17
  tokenFactory: () => localStorage.getItem("authToken") ?? ""
18
18
  });
19
19
 
20
- provider.listModelsByProvider("openai").subscribe(models => {
21
- console.log("OpenAI models", models.map(model => model.name));
20
+ provider.listModelsByProvider("bandit").subscribe(models => {
21
+ console.log("Bandit models", models.map(model => model.name));
22
22
  });
23
23
  ```
24
24
 
25
25
  ### Provider Notes
26
+ - **Bandit AI**: Accepts OpenAI-format requests and automatically normalizes aliases such as `bandit-core-1`. Supports both auth tokens (UI) and API keys (CLI/partner usage) through the gateway.
26
27
  - **OpenAI & Azure OpenAI**: Send images as `image_url` entries alongside text segments. Azure requires `deploymentName` and `apiVersion` within the gateway configuration.
27
28
  - **Anthropic**: Supports the same streaming pipeline with Claude models and structured responses.
28
29
  - **Ollama**: Keeps images on the final user message through the `images` array and exposes `/api/ollama/chat` plus `/api/ollama/generate` endpoints.
@@ -18,16 +18,18 @@ Every request must include `Authorization: Bearer <token>`. Tokens are injected
18
18
  | `/api/tts`, `/api/stt`, `/api/tts/available-models` | POST/GET | Optional voice endpoints for advanced deployments. |
19
19
 
20
20
  ### Provider-specific chat/generation routes
21
- When the UI specifies a provider (OpenAI, Azure OpenAI, Anthropic, Ollama), Bandit Engine switches to provider-scoped endpoints automatically. Implement these routes alongside the core ones above:
21
+ When the UI specifies a provider (Bandit AI, OpenAI, Azure OpenAI, Anthropic, Ollama), Bandit Engine switches to provider-scoped endpoints automatically. Implement these routes alongside the core ones above:
22
22
 
23
23
  | Provider | Chat endpoint | Generation endpoint |
24
24
  | --- | --- | --- |
25
+ | Bandit AI | `POST /api/bandit/chat/completions` | `POST /api/bandit/generate`* |
25
26
  | OpenAI | `POST /api/openai/chat/completions` | `POST /api/openai/generate` |
26
27
  | Azure OpenAI | `POST /api/azure-openai/chat/completions` | `POST /api/azure-openai/generate` |
27
28
  | Anthropic | `POST /api/anthropic/chat/completions` | `POST /api/anthropic/generate` |
28
29
  | Ollama | `POST /api/ollama/chat` | `POST /api/ollama/generate` |
29
30
 
30
- > ℹ️ Bandit still includes the `provider` field in the request body for convenience, but the URL itself determines which upstream integration should run. Ollama uses `/chat` (not `/chat/completions`) to match its native API.
31
+ > ℹ️ Bandit still includes the `provider` field in the request body for convenience, but the URL itself determines which upstream integration should run. Ollama uses `/chat` (not `/chat/completions`) to match its native API.
32
+ > \* `POST /api/bandit/generate` is optional today but mirrors the shape of `/api/chat/completions` for parity with other providers.
31
33
 
32
34
  If you only support a single upstream provider you may implement the matching provider-specific endpoints and omit the others. The `/api/chat/completions` and `/api/generate` routes remain useful as a “default” path when the frontend has no explicit provider preference.
33
35
 
@@ -42,11 +44,25 @@ app.use(express.json());
42
44
  app.get("/api/health", (req, res) => {
43
45
  res.json({
44
46
  status: "healthy",
45
- providers: ["openai", "ollama"],
47
+ providers: ["bandit", "openai", "ollama"],
46
48
  version: "1.0.0"
47
49
  });
48
50
  });
49
51
 
52
+ app.post("/api/bandit/chat/completions", async (req, res) => {
53
+ const response = await fetch(`${process.env.GATEWAY_URL}/completions`, {
54
+ method: "POST",
55
+ headers: {
56
+ "Content-Type": "application/json",
57
+ Authorization: `Bearer ${process.env.BANDIT_API_KEY}`
58
+ },
59
+ body: JSON.stringify(req.body)
60
+ });
61
+
62
+ res.status(response.status);
63
+ response.body?.pipe(res);
64
+ });
65
+
50
66
  app.post("/api/openai/chat/completions", async (req, res) => {
51
67
  const { model, messages, stream = true } = req.body;
52
68
 
@@ -1,6 +1,6 @@
1
1
  # Bandit Gateway Node Example
2
2
 
3
- This example demonstrates a minimal HTTP gateway that proxies chat and generation requests to OpenAI, Azure OpenAI, Anthropic, or Ollama via provider-specific endpoints. Use it to validate your Bandit Engine integration before wiring up your production infrastructure.
3
+ This example demonstrates a minimal HTTP gateway that proxies chat and generation requests to Bandit AI, OpenAI, Azure OpenAI, Anthropic, or Ollama via provider-specific endpoints. Use it to validate your Bandit Engine integration before wiring up your production infrastructure.
4
4
 
5
5
  ## Getting Started
6
6
  ```bash
@@ -10,6 +10,7 @@ npm run dev
10
10
 
11
11
  The server listens on `http://localhost:8080`. Configure the following environment variables as needed:
12
12
 
13
+ - `BANDIT_API_KEY` – Optional; required when proxying to the Bandit API-key endpoint.
13
14
  - `OPENAI_API_KEY` – Optional; required when proxying to OpenAI.
14
15
  - `OLLAMA_URL` – Optional; defaults to `http://localhost:11434`.
15
16
  - `AZURE_OPENAI_CHAT_URL` / `AZURE_OPENAI_RESPONSES_URL` – Optional; set to your Azure deployment REST URLs when using Azure OpenAI.
@@ -33,5 +34,6 @@ The server listens on `http://localhost:8080`. Configure the following environme
33
34
  | `POST /api/anthropic/generate` | Anthropic text generation proxy. |
34
35
  | `POST /api/ollama/chat` | Native Ollama chat streaming proxy. |
35
36
  | `POST /api/ollama/generate` | Native Ollama generate proxy. |
37
+ | `POST /api/bandit/chat/completions` | Bandit AI chat completions proxy. |
36
38
 
37
39
  These map directly to the requirements described in [`docs/02_gateway_api.md`](../../docs/02_gateway_api.md). Providers without credentials or URLs return `501 Not Implemented` responses so you can enable them incrementally.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@burtson-labs/bandit-engine",
3
- "version": "2.0.40",
3
+ "version": "2.0.42",
4
4
  "license": "BUSL-1.1",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/services/ai-provider-init.service.ts"],"sourcesContent":["/*\n © 2025 Burtson Labs — Licensed under Business Source License 1.1\n https://burtson.ai/license\n\n This file is protected intellectual property.\n Do NOT use in commercial software, prompts, AI training data, or derivative works without a valid commercial license.\n\n 🚫 AI NOTICE: This file contains visible and invisible watermarks.\n ⚖️ VIOLATION NOTICE: Removing, modifying, or obscuring these watermarks is a license violation.\n 🔒 LICENSE TERMINATION: Upon license termination, ALL forks, copies, and derivatives must be permanently deleted.\n 📋 AUDIT TRAIL: File usage is logged and monitored for compliance verification.\n*/\n\n// Bandit Engine Watermark: BL-WM-BFD5-C74863\nconst __banditFingerprint_services_aiproviderinitservicets = 'BL-FP-DDF978-53AF';\nconst __auditTrail_services_aiproviderinitservicets = 'BL-AU-MGOIKVVR-WP87';\n// File: ai-provider-init.service.ts | Path: src/services/ai-provider-init.service.ts | Hash: bfd553af\n\nimport { useAIProviderStore } from \"../store/aiProviderStore\";\nimport { usePackageSettingsStore } from \"../store/packageSettingsStore\";\nimport { AIProviderConfig, AIProviderType } from \"./ai-provider/types/common.types\";\nimport { authenticationService } from \"./auth/authenticationService\";\nimport { debugLogger } from \"./logging/debugLogger\";\nimport indexedDBService from \"./indexedDB/indexedDBService\";\n\ntype StoredAIProviderConfig = AIProviderConfig & { id?: string };\n\n/**\n * Service to initialize AI providers based on package settings\n */\nexport class AIProviderInitService {\n private static instance: AIProviderInitService;\n\n private constructor() {}\n\n static getInstance(): AIProviderInitService {\n if (!AIProviderInitService.instance) {\n AIProviderInitService.instance = new AIProviderInitService();\n }\n return AIProviderInitService.instance;\n }\n\n /**\n * Initialize AI provider from package settings\n * Provides backward compatibility with existing Ollama settings\n */\n async initializeFromSettings(): Promise<void> {\n const settings = usePackageSettingsStore.getState().settings;\n if (!settings) {\n debugLogger.warn(\"No package settings found, cannot initialize AI provider\");\n return;\n }\n\n let providerConfig: AIProviderConfig;\n\n debugLogger.info(\"AI Provider Init: Starting initialization\", { \n hasSettings: !!settings,\n hasAiProvider: !!settings.aiProvider,\n ollamaUrl: settings.ollamaUrl\n });\n\n const isPlaygroundEnvironment =\n settings.playgroundMode === true ||\n settings.aiProvider?.type === AIProviderType.PLAYGROUND ||\n (settings.gatewayApiUrl?.toLowerCase()?.startsWith(\"playground://\") ?? false) ||\n (typeof window !== \"undefined\" && window.location.pathname.includes(\"/playground\"));\n\n // First, try to load provider configuration from IndexedDB\n if (isPlaygroundEnvironment) {\n debugLogger.info(\"AI Provider Init: Playground environment detected, bypassing saved provider config\");\n } else {\n try {\n const savedConfig = await indexedDBService.get<StoredAIProviderConfig>(\n 'banditConfig', \n 1, \n 'config', \n 'aiProvider',\n [{ name: 'config', keyPath: 'id' }]\n );\n \n if (savedConfig) {\n debugLogger.info('AI Provider Init: Found saved config in IndexedDB', { type: savedConfig.type });\n \n // Filter out the 'id' property that was added for IndexedDB storage\n const { id: _id, ...configWithoutId } = savedConfig;\n providerConfig = { ...configWithoutId };\n if (providerConfig.type === AIProviderType.ANTHROPIC) {\n providerConfig = this.convertAnthropicConfig(providerConfig, settings?.gatewayApiUrl);\n }\n\n // Ensure tokenFactory is present for providers that need it\n if ((providerConfig.type === AIProviderType.OLLAMA || providerConfig.type === AIProviderType.GATEWAY) && !providerConfig.tokenFactory) {\n providerConfig.tokenFactory = () => {\n // Try multiple sources for the token\n let token = authenticationService.getToken();\n \n // If the bandit-engine's service doesn't have a token, try direct localStorage access\n if (!token) {\n token = localStorage.getItem(\"authToken\");\n }\n \n // Also try the authentication store if available\n if (!token) {\n try {\n const { useAuthenticationStore } = require(\"../../store/authenticationStore\");\n const authStore = useAuthenticationStore.getState();\n token = authStore.token;\n } catch (e) {\n // Store might not be available, that's ok\n }\n }\n \n debugLogger.info(\"AI Provider Init: IndexedDB config token factory\", { \n hasToken: !!token\n });\n return token;\n };\n }\n \n // Initialize the provider with saved config\n try {\n const { createProvider } = useAIProviderStore.getState();\n createProvider(providerConfig);\n \n const provider = useAIProviderStore.getState().provider;\n if (provider) {\n try {\n await provider.validateServiceAvailability({ timeoutMs: 5000 });\n debugLogger.info(`AI Provider initialized and validated from IndexedDB: ${providerConfig.type}`);\n } catch (validationError) {\n debugLogger.warn(`AI Provider created but validation failed`, { error: validationError });\n }\n }\n return; // Successfully initialized from IndexedDB\n } catch (error) {\n debugLogger.error(\"Failed to initialize saved provider config, falling back to package settings\", { error });\n }\n }\n \n debugLogger.info('AI Provider Init: No saved config found, using package settings');\n } catch (error) {\n debugLogger.warn('AI Provider Init: Failed to load from IndexedDB, using package settings', { error });\n }\n }\n\n // Fallback to package settings if no saved config found\n if (settings.aiProvider) {\n providerConfig = { ...settings.aiProvider };\n if (providerConfig.type === AIProviderType.ANTHROPIC) {\n providerConfig = this.convertAnthropicConfig(providerConfig, settings.gatewayApiUrl);\n }\n \n // Ensure tokenFactory is present for Ollama providers\n if (providerConfig.type === AIProviderType.OLLAMA && !providerConfig.tokenFactory) {\n providerConfig.tokenFactory = () => {\n // Try multiple sources for the token\n let token = authenticationService.getToken();\n \n // If the bandit-engine's service doesn't have a token, try direct localStorage access\n if (!token) {\n token = localStorage.getItem(\"authToken\");\n }\n \n // Also try the authentication store if available\n if (!token) {\n try {\n const { useAuthenticationStore } = require(\"../../store/authenticationStore\");\n const authStore = useAuthenticationStore.getState();\n token = authStore.token;\n } catch (e) {\n // Store might not be available, that's ok\n }\n }\n \n debugLogger.info(\"AIProviderInit: Explicit config tokenFactory\", { \n hasToken: !!token,\n localStorage: !!localStorage.getItem(\"authToken\")\n });\n return token;\n };\n }\n \n debugLogger.info(\"Using explicit AI provider config\", providerConfig);\n } else {\n // Fall back to legacy Ollama settings for backward compatibility\n providerConfig = {\n type: AIProviderType.OLLAMA,\n baseUrl: settings.ollamaUrl,\n tokenFactory: () => {\n // Try multiple sources for the token\n let token = authenticationService.getToken();\n \n // If the bandit-engine's service doesn't have a token, try direct localStorage access\n if (!token) {\n token = localStorage.getItem(\"authToken\");\n }\n \n // Also try the authentication store if available\n if (!token) {\n try {\n const { useAuthenticationStore } = require(\"../../store/authenticationStore\");\n const authStore = useAuthenticationStore.getState();\n token = authStore.token;\n } catch (e) {\n // Store might not be available, that's ok\n }\n }\n \n debugLogger.info(\"AIProviderInit: Token factory called\", { \n hasToken: !!token,\n localStorage: !!localStorage.getItem(\"authToken\")\n });\n return token;\n }\n };\n debugLogger.info(\"Using legacy Ollama config\", providerConfig);\n }\n\n try {\n // First validate if the service is available\n const { createProvider } = useAIProviderStore.getState();\n \n // Try to create and validate the provider\n createProvider(providerConfig);\n \n // Test provider availability\n const provider = useAIProviderStore.getState().provider;\n if (provider) {\n try {\n await provider.validateServiceAvailability({ timeoutMs: 5000 });\n debugLogger.info(`AI Provider initialized and validated: ${providerConfig.type}`);\n } catch (validationError) {\n debugLogger.warn(`AI Provider created but validation failed:`, { error: validationError });\n // Provider is created but may not be fully available - this is ok for offline scenarios\n }\n }\n } catch (error) {\n debugLogger.error(\"Failed to initialize AI provider:\", { error });\n \n // Try to fall back to default Ollama if initial provider fails\n if (providerConfig.type !== AIProviderType.OLLAMA) {\n try {\n const fallbackConfig: AIProviderConfig = {\n type: AIProviderType.OLLAMA,\n baseUrl: settings.ollamaUrl || 'http://localhost:11434',\n tokenFactory: () => {\n // Try multiple sources for the token\n let token = authenticationService.getToken();\n \n // If the bandit-engine's service doesn't have a token, try direct localStorage access\n if (!token) {\n token = localStorage.getItem(\"authToken\");\n }\n \n // Also try the authentication store if available\n if (!token) {\n try {\n const { useAuthenticationStore } = require(\"../../store/authenticationStore\");\n const authStore = useAuthenticationStore.getState();\n token = authStore.token;\n } catch (e) {\n // Store might not be available, that's ok\n }\n }\n \n debugLogger.info(\"AIProviderInit: Fallback tokenFactory\", { \n hasToken: !!token,\n localStorage: !!localStorage.getItem(\"authToken\")\n });\n return token;\n }\n };\n const { createProvider } = useAIProviderStore.getState();\n createProvider(fallbackConfig);\n debugLogger.info(\"Fallback to Ollama provider successful\");\n } catch (fallbackError) {\n debugLogger.error(\"Failed to initialize fallback Ollama provider:\", { error: fallbackError });\n }\n } else {\n // If Ollama provider fails, try localhost as ultimate fallback\n try {\n const localFallbackConfig: AIProviderConfig = {\n type: AIProviderType.OLLAMA,\n baseUrl: 'http://localhost:11434',\n tokenFactory: () => {\n // Try multiple sources for the token\n let token = authenticationService.getToken();\n \n // If the bandit-engine's service doesn't have a token, try direct localStorage access\n if (!token) {\n token = localStorage.getItem(\"authToken\");\n }\n \n // Also try the authentication store if available\n if (!token) {\n try {\n const { useAuthenticationStore } = require(\"../../store/authenticationStore\");\n const authStore = useAuthenticationStore.getState();\n token = authStore.token;\n } catch (e) {\n // Store might not be available, that's ok\n }\n }\n \n debugLogger.info(\"AIProviderInit: Local fallback tokenFactory\", { \n hasToken: !!token,\n localStorage: !!localStorage.getItem(\"authToken\")\n });\n return token;\n }\n };\n const { createProvider } = useAIProviderStore.getState();\n createProvider(localFallbackConfig);\n debugLogger.info(\"Fallback to localhost Ollama provider successful\");\n } catch (localFallbackError) {\n debugLogger.error(\"All provider initialization attempts failed:\", { error: localFallbackError });\n }\n }\n }\n }\n\n /**\n * Switch to a different AI provider\n */\n switchProvider(config: AIProviderConfig): void {\n try {\n const { switchProvider } = useAIProviderStore.getState();\n switchProvider(config);\n debugLogger.info(`Switched to AI provider: ${config.type}`);\n } catch (error) {\n debugLogger.error(\"Failed to switch AI provider:\", { error });\n throw error;\n }\n }\n\n /**\n * Get the current provider type\n */\n getCurrentProviderType(): string | null {\n const provider = useAIProviderStore.getState().provider;\n return provider ? provider.getProviderType() : null;\n }\n\n /**\n * Check if a provider is initialized\n */\n isProviderInitialized(): boolean {\n return useAIProviderStore.getState().provider !== null;\n }\n\n private convertAnthropicConfig(config: AIProviderConfig, gatewayUrl?: string | null): AIProviderConfig {\n if (config.type !== AIProviderType.ANTHROPIC) {\n return config;\n }\n\n const defaultModel = typeof config.defaultModel === 'string' && config.defaultModel.trim()\n ? config.defaultModel.trim()\n : 'claude-3-5-sonnet-latest';\n\n const normalized: AIProviderConfig = {\n type: AIProviderType.GATEWAY,\n gatewayUrl: gatewayUrl || config.gatewayUrl || '',\n provider: 'anthropic',\n defaultModel,\n tokenFactory: config.tokenFactory\n };\n\n debugLogger.info('AI Provider Init: Converted direct Anthropic provider to gateway configuration');\n return normalized;\n }\n}\n\nexport const aiProviderInitService = AIProviderInitService.getInstance();\n"],"mappings":";;;;;;;;;;;;;;;;;;AA8BO,IAAM,wBAAN,MAAM,uBAAsB;AAAA,EACjC,OAAe;AAAA,EAEP,cAAc;AAAA,EAAC;AAAA,EAEvB,OAAO,cAAqC;AAC1C,QAAI,CAAC,uBAAsB,UAAU;AACnC,6BAAsB,WAAW,IAAI,uBAAsB;AAAA,IAC7D;AACA,WAAO,uBAAsB;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,yBAAwC;AAC5C,UAAM,WAAW,wBAAwB,SAAS,EAAE;AACpD,QAAI,CAAC,UAAU;AACb,kBAAY,KAAK,0DAA0D;AAC3E;AAAA,IACF;AAEA,QAAI;AAEJ,gBAAY,KAAK,6CAA6C;AAAA,MAC5D,aAAa,CAAC,CAAC;AAAA,MACf,eAAe,CAAC,CAAC,SAAS;AAAA,MAC1B,WAAW,SAAS;AAAA,IACtB,CAAC;AAED,UAAM,0BACJ,SAAS,mBAAmB,QAC5B,SAAS,YAAY,2CACpB,SAAS,eAAe,YAAY,GAAG,WAAW,eAAe,KAAK,UACtE,OAAO,WAAW,eAAe,OAAO,SAAS,SAAS,SAAS,aAAa;AAGnF,QAAI,yBAAyB;AAC3B,kBAAY,KAAK,oFAAoF;AAAA,IACvG,OAAO;AACL,UAAI;AACF,cAAM,cAAc,MAAM,yBAAiB;AAAA,UACzC;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA,CAAC,EAAE,MAAM,UAAU,SAAS,KAAK,CAAC;AAAA,QACpC;AAEA,YAAI,aAAa;AACf,sBAAY,KAAK,qDAAqD,EAAE,MAAM,YAAY,KAAK,CAAC;AAGhG,gBAAM,EAAE,IAAI,KAAK,GAAG,gBAAgB,IAAI;AACxC,2BAAiB,EAAE,GAAG,gBAAgB;AACtC,cAAI,eAAe,sCAAmC;AACpD,6BAAiB,KAAK,uBAAuB,gBAAgB,UAAU,aAAa;AAAA,UACtF;AAGA,eAAK,eAAe,kCAAkC,eAAe,qCAAoC,CAAC,eAAe,cAAc;AACrI,2BAAe,eAAe,MAAM;AAElC,kBAAI,QAAQ,sBAAsB,SAAS;AAG3C,kBAAI,CAAC,OAAO;AACV,wBAAQ,aAAa,QAAQ,WAAW;AAAA,cAC1C;AAGA,kBAAI,CAAC,OAAO;AACV,oBAAI;AACF,wBAAM,EAAE,uBAAuB,IAAI,UAAQ,iCAAiC;AAC5E,wBAAM,YAAY,uBAAuB,SAAS;AAClD,0BAAQ,UAAU;AAAA,gBACpB,SAAS,GAAG;AAAA,gBAEZ;AAAA,cACF;AAEA,0BAAY,KAAK,oDAAoD;AAAA,gBACnE,UAAU,CAAC,CAAC;AAAA,cACd,CAAC;AACD,qBAAO;AAAA,YACT;AAAA,UACF;AAGA,cAAI;AACF,kBAAM,EAAE,eAAe,IAAI,mBAAmB,SAAS;AACvD,2BAAe,cAAc;AAE7B,kBAAM,WAAW,mBAAmB,SAAS,EAAE;AAC/C,gBAAI,UAAU;AACZ,kBAAI;AACF,sBAAM,SAAS,4BAA4B,EAAE,WAAW,IAAK,CAAC;AAC9D,4BAAY,KAAK,yDAAyD,eAAe,IAAI,EAAE;AAAA,cACjG,SAAS,iBAAiB;AACxB,4BAAY,KAAK,6CAA6C,EAAE,OAAO,gBAAgB,CAAC;AAAA,cAC1F;AAAA,YACF;AACA;AAAA,UACF,SAAS,OAAO;AACd,wBAAY,MAAM,gFAAgF,EAAE,MAAM,CAAC;AAAA,UAC7G;AAAA,QACF;AAEA,oBAAY,KAAK,iEAAiE;AAAA,MACpF,SAAS,OAAO;AACd,oBAAY,KAAK,2EAA2E,EAAE,MAAM,CAAC;AAAA,MACvG;AAAA,IACF;AAGA,QAAI,SAAS,YAAY;AACvB,uBAAiB,EAAE,GAAG,SAAS,WAAW;AAC1C,UAAI,eAAe,sCAAmC;AACpD,yBAAiB,KAAK,uBAAuB,gBAAgB,SAAS,aAAa;AAAA,MACrF;AAGA,UAAI,eAAe,kCAAkC,CAAC,eAAe,cAAc;AACjF,uBAAe,eAAe,MAAM;AAElC,cAAI,QAAQ,sBAAsB,SAAS;AAG3C,cAAI,CAAC,OAAO;AACV,oBAAQ,aAAa,QAAQ,WAAW;AAAA,UAC1C;AAGA,cAAI,CAAC,OAAO;AACV,gBAAI;AACF,oBAAM,EAAE,uBAAuB,IAAI,UAAQ,iCAAiC;AAC5E,oBAAM,YAAY,uBAAuB,SAAS;AAClD,sBAAQ,UAAU;AAAA,YACpB,SAAS,GAAG;AAAA,YAEZ;AAAA,UACF;AAEA,sBAAY,KAAK,gDAAgD;AAAA,YAC/D,UAAU,CAAC,CAAC;AAAA,YACZ,cAAc,CAAC,CAAC,aAAa,QAAQ,WAAW;AAAA,UAClD,CAAC;AACD,iBAAO;AAAA,QACT;AAAA,MACF;AAEA,kBAAY,KAAK,qCAAqC,cAAc;AAAA,IACtE,OAAO;AAEL,uBAAiB;AAAA,QACf;AAAA,QACA,SAAS,SAAS;AAAA,QAClB,cAAc,MAAM;AAElB,cAAI,QAAQ,sBAAsB,SAAS;AAG3C,cAAI,CAAC,OAAO;AACV,oBAAQ,aAAa,QAAQ,WAAW;AAAA,UAC1C;AAGA,cAAI,CAAC,OAAO;AACV,gBAAI;AACF,oBAAM,EAAE,uBAAuB,IAAI,UAAQ,iCAAiC;AAC5E,oBAAM,YAAY,uBAAuB,SAAS;AAClD,sBAAQ,UAAU;AAAA,YACpB,SAAS,GAAG;AAAA,YAEZ;AAAA,UACF;AAEA,sBAAY,KAAK,wCAAwC;AAAA,YACvD,UAAU,CAAC,CAAC;AAAA,YACZ,cAAc,CAAC,CAAC,aAAa,QAAQ,WAAW;AAAA,UAClD,CAAC;AACD,iBAAO;AAAA,QACT;AAAA,MACF;AACA,kBAAY,KAAK,8BAA8B,cAAc;AAAA,IAC/D;AAEA,QAAI;AAEF,YAAM,EAAE,eAAe,IAAI,mBAAmB,SAAS;AAGvD,qBAAe,cAAc;AAG7B,YAAM,WAAW,mBAAmB,SAAS,EAAE;AAC/C,UAAI,UAAU;AACZ,YAAI;AACF,gBAAM,SAAS,4BAA4B,EAAE,WAAW,IAAK,CAAC;AAC9D,sBAAY,KAAK,0CAA0C,eAAe,IAAI,EAAE;AAAA,QAClF,SAAS,iBAAiB;AACxB,sBAAY,KAAK,8CAA8C,EAAE,OAAO,gBAAgB,CAAC;AAAA,QAE3F;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AACd,kBAAY,MAAM,qCAAqC,EAAE,MAAM,CAAC;AAGhE,UAAI,eAAe,gCAAgC;AACjD,YAAI;AACF,gBAAM,iBAAmC;AAAA,YACvC;AAAA,YACA,SAAS,SAAS,aAAa;AAAA,YAC/B,cAAc,MAAM;AAElB,kBAAI,QAAQ,sBAAsB,SAAS;AAG3C,kBAAI,CAAC,OAAO;AACV,wBAAQ,aAAa,QAAQ,WAAW;AAAA,cAC1C;AAGA,kBAAI,CAAC,OAAO;AACV,oBAAI;AACF,wBAAM,EAAE,uBAAuB,IAAI,UAAQ,iCAAiC;AAC5E,wBAAM,YAAY,uBAAuB,SAAS;AAClD,0BAAQ,UAAU;AAAA,gBACpB,SAAS,GAAG;AAAA,gBAEZ;AAAA,cACF;AAEA,0BAAY,KAAK,yCAAyC;AAAA,gBACxD,UAAU,CAAC,CAAC;AAAA,gBACZ,cAAc,CAAC,CAAC,aAAa,QAAQ,WAAW;AAAA,cAClD,CAAC;AACD,qBAAO;AAAA,YACT;AAAA,UACF;AACA,gBAAM,EAAE,eAAe,IAAI,mBAAmB,SAAS;AACvD,yBAAe,cAAc;AAC7B,sBAAY,KAAK,wCAAwC;AAAA,QAC3D,SAAS,eAAe;AACtB,sBAAY,MAAM,kDAAkD,EAAE,OAAO,cAAc,CAAC;AAAA,QAC9F;AAAA,MACF,OAAO;AAEL,YAAI;AACF,gBAAM,sBAAwC;AAAA,YAC5C;AAAA,YACA,SAAS;AAAA,YACT,cAAc,MAAM;AAElB,kBAAI,QAAQ,sBAAsB,SAAS;AAG3C,kBAAI,CAAC,OAAO;AACV,wBAAQ,aAAa,QAAQ,WAAW;AAAA,cAC1C;AAGA,kBAAI,CAAC,OAAO;AACV,oBAAI;AACF,wBAAM,EAAE,uBAAuB,IAAI,UAAQ,iCAAiC;AAC5E,wBAAM,YAAY,uBAAuB,SAAS;AAClD,0BAAQ,UAAU;AAAA,gBACpB,SAAS,GAAG;AAAA,gBAEZ;AAAA,cACF;AAEA,0BAAY,KAAK,+CAA+C;AAAA,gBAC9D,UAAU,CAAC,CAAC;AAAA,gBACZ,cAAc,CAAC,CAAC,aAAa,QAAQ,WAAW;AAAA,cAClD,CAAC;AACD,qBAAO;AAAA,YACT;AAAA,UACF;AACA,gBAAM,EAAE,eAAe,IAAI,mBAAmB,SAAS;AACvD,yBAAe,mBAAmB;AAClC,sBAAY,KAAK,kDAAkD;AAAA,QACrE,SAAS,oBAAoB;AAC3B,sBAAY,MAAM,gDAAgD,EAAE,OAAO,mBAAmB,CAAC;AAAA,QACjG;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,eAAe,QAAgC;AAC7C,QAAI;AACF,YAAM,EAAE,eAAe,IAAI,mBAAmB,SAAS;AACvD,qBAAe,MAAM;AACrB,kBAAY,KAAK,4BAA4B,OAAO,IAAI,EAAE;AAAA,IAC5D,SAAS,OAAO;AACd,kBAAY,MAAM,iCAAiC,EAAE,MAAM,CAAC;AAC5D,YAAM;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,yBAAwC;AACtC,UAAM,WAAW,mBAAmB,SAAS,EAAE;AAC/C,WAAO,WAAW,SAAS,gBAAgB,IAAI;AAAA,EACjD;AAAA;AAAA;AAAA;AAAA,EAKA,wBAAiC;AAC/B,WAAO,mBAAmB,SAAS,EAAE,aAAa;AAAA,EACpD;AAAA,EAEQ,uBAAuB,QAA0B,YAA8C;AACrG,QAAI,OAAO,sCAAmC;AAC5C,aAAO;AAAA,IACT;AAEA,UAAM,eAAe,OAAO,OAAO,iBAAiB,YAAY,OAAO,aAAa,KAAK,IACrF,OAAO,aAAa,KAAK,IACzB;AAEJ,UAAM,aAA+B;AAAA,MACnC;AAAA,MACA,YAAY,cAAc,OAAO,cAAc;AAAA,MAC/C,UAAU;AAAA,MACV;AAAA,MACA,cAAc,OAAO;AAAA,IACvB;AAEA,gBAAY,KAAK,gFAAgF;AACjG,WAAO;AAAA,EACT;AACF;AAEO,IAAM,wBAAwB,sBAAsB,YAAY;","names":[]}