@burtson-labs/bandit-engine 2.0.37 → 2.0.39

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 (44) hide show
  1. package/dist/{aiProviderStore-UJRDUYOF.mjs → aiProviderStore-XN7GCBHJ.mjs} +2 -2
  2. package/dist/{chat-SZK3EBDO.mjs → chat-5QJNWB7I.mjs} +5 -5
  3. package/dist/chat-provider.js +29 -3
  4. package/dist/chat-provider.js.map +1 -1
  5. package/dist/chat-provider.mjs +4 -4
  6. package/dist/{chunk-2ZZA2IFL.mjs → chunk-3A2527TE.mjs} +3 -3
  7. package/dist/{chunk-FJO5ZWYU.mjs → chunk-CDQYBO3Q.mjs} +26 -8
  8. package/dist/chunk-CDQYBO3Q.mjs.map +1 -0
  9. package/dist/{chunk-PLNFTIGX.mjs → chunk-ECRNIAG6.mjs} +4 -4
  10. package/dist/{chunk-S635Q6OQ.mjs → chunk-EOKIE5HZ.mjs} +24 -3
  11. package/dist/chunk-EOKIE5HZ.mjs.map +1 -0
  12. package/dist/{chunk-G4OXOTNJ.mjs → chunk-JRCDANLN.mjs} +154 -61
  13. package/dist/{chunk-G4OXOTNJ.mjs.map → chunk-JRCDANLN.mjs.map} +1 -1
  14. package/dist/{chunk-ZNNOTDRD.mjs → chunk-QU5S5QQP.mjs} +9 -4
  15. package/dist/chunk-QU5S5QQP.mjs.map +1 -0
  16. package/dist/{chunk-ED5NNDKO.mjs → chunk-QYH2T4L5.mjs} +3 -3
  17. package/dist/{chunk-ZAVV2AT5.mjs → chunk-WO5KFNNW.mjs} +4 -4
  18. package/dist/cli/cli.js +2 -3
  19. package/dist/cli/cli.js.map +1 -1
  20. package/dist/{gateway-Ckf_KusF.d.ts → gateway-B0LJ3-jT.d.mts} +3 -0
  21. package/dist/{gateway-Ckf_KusF.d.mts → gateway-B0LJ3-jT.d.ts} +3 -0
  22. package/dist/index.d.mts +2 -2
  23. package/dist/index.d.ts +2 -2
  24. package/dist/index.js +196 -59
  25. package/dist/index.js.map +1 -1
  26. package/dist/index.mjs +8 -8
  27. package/dist/management/management.js +196 -59
  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 +8 -3
  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 +2 -3
  36. package/dist/chunk-FJO5ZWYU.mjs.map +0 -1
  37. package/dist/chunk-S635Q6OQ.mjs.map +0 -1
  38. package/dist/chunk-ZNNOTDRD.mjs.map +0 -1
  39. /package/dist/{aiProviderStore-UJRDUYOF.mjs.map → aiProviderStore-XN7GCBHJ.mjs.map} +0 -0
  40. /package/dist/{chat-SZK3EBDO.mjs.map → chat-5QJNWB7I.mjs.map} +0 -0
  41. /package/dist/{chunk-2ZZA2IFL.mjs.map → chunk-3A2527TE.mjs.map} +0 -0
  42. /package/dist/{chunk-PLNFTIGX.mjs.map → chunk-ECRNIAG6.mjs.map} +0 -0
  43. /package/dist/{chunk-ED5NNDKO.mjs.map → chunk-QYH2T4L5.mjs.map} +0 -0
  44. /package/dist/{chunk-ZAVV2AT5.mjs.map → chunk-WO5KFNNW.mjs.map} +0 -0
@@ -52,6 +52,9 @@ interface AIProviderConfig {
52
52
  apiKey?: string;
53
53
  apiVersion?: string;
54
54
  deploymentName?: string;
55
+ defaultModel?: string;
56
+ anthropicVersion?: string;
57
+ anthropicMaxTokens?: number;
55
58
  gatewayUrl?: string;
56
59
  provider?: 'openai' | 'azure-openai' | 'anthropic' | 'ollama' | 'xai';
57
60
  tokenFactory?: () => string | null;
@@ -52,6 +52,9 @@ interface AIProviderConfig {
52
52
  apiKey?: string;
53
53
  apiVersion?: string;
54
54
  deploymentName?: string;
55
+ defaultModel?: string;
56
+ anthropicVersion?: string;
57
+ anthropicMaxTokens?: number;
55
58
  gatewayUrl?: string;
56
59
  provider?: 'openai' | 'azure-openai' | 'anthropic' | 'ollama' | 'xai';
57
60
  tokenFactory?: () => string | null;
package/dist/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
- import { F as FeatureFlagConfig, a as FeatureKey, b as FeatureEvaluation, S as SubscriptionTier, T as TrialUsage, G as GatewayHealthResponse, c as GatewayModel, d as GatewayMemoryResponse } from './gateway-Ckf_KusF.mjs';
2
- export { t as AIChatRequest, u as AIChatResponse, w as AIGenerateRequest, x as AIGenerateResponse, y as AIMessage, s as AIModel, A as AIProviderConfig, g as ChatConfig, e as ChatModal, h as ChatModalProps, C as ChatProvider, D as DEFAULT_TIER_FEATURES, f as FeatureMatrix, m as GatewayChatRequest, n as GatewayChatResponse, j as GatewayContract, o as GatewayGenerateRequest, p as GatewayGenerateResponse, r as GatewayMemoryRecord, l as GatewayMessage, k as GatewayMessageContent, q as GatewayModelsResponse, O as OSS_DEFAULT_FEATURES, P as PackageSettings, i as VoiceModelsResponse, V as VoiceService, v as voiceService } from './gateway-Ckf_KusF.mjs';
1
+ import { F as FeatureFlagConfig, a as FeatureKey, b as FeatureEvaluation, S as SubscriptionTier, T as TrialUsage, G as GatewayHealthResponse, c as GatewayModel, d as GatewayMemoryResponse } from './gateway-B0LJ3-jT.mjs';
2
+ export { t as AIChatRequest, u as AIChatResponse, w as AIGenerateRequest, x as AIGenerateResponse, y as AIMessage, s as AIModel, A as AIProviderConfig, g as ChatConfig, e as ChatModal, h as ChatModalProps, C as ChatProvider, D as DEFAULT_TIER_FEATURES, f as FeatureMatrix, m as GatewayChatRequest, n as GatewayChatResponse, j as GatewayContract, o as GatewayGenerateRequest, p as GatewayGenerateResponse, r as GatewayMemoryRecord, l as GatewayMessage, k as GatewayMessageContent, q as GatewayModelsResponse, O as OSS_DEFAULT_FEATURES, P as PackageSettings, i as VoiceModelsResponse, V as VoiceService, v as voiceService } from './gateway-B0LJ3-jT.mjs';
3
3
  import * as react_jsx_runtime from 'react/jsx-runtime';
4
4
  import React, { ReactNode } from 'react';
5
5
  import * as zustand from 'zustand';
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { F as FeatureFlagConfig, a as FeatureKey, b as FeatureEvaluation, S as SubscriptionTier, T as TrialUsage, G as GatewayHealthResponse, c as GatewayModel, d as GatewayMemoryResponse } from './gateway-Ckf_KusF.js';
2
- export { t as AIChatRequest, u as AIChatResponse, w as AIGenerateRequest, x as AIGenerateResponse, y as AIMessage, s as AIModel, A as AIProviderConfig, g as ChatConfig, e as ChatModal, h as ChatModalProps, C as ChatProvider, D as DEFAULT_TIER_FEATURES, f as FeatureMatrix, m as GatewayChatRequest, n as GatewayChatResponse, j as GatewayContract, o as GatewayGenerateRequest, p as GatewayGenerateResponse, r as GatewayMemoryRecord, l as GatewayMessage, k as GatewayMessageContent, q as GatewayModelsResponse, O as OSS_DEFAULT_FEATURES, P as PackageSettings, i as VoiceModelsResponse, V as VoiceService, v as voiceService } from './gateway-Ckf_KusF.js';
1
+ import { F as FeatureFlagConfig, a as FeatureKey, b as FeatureEvaluation, S as SubscriptionTier, T as TrialUsage, G as GatewayHealthResponse, c as GatewayModel, d as GatewayMemoryResponse } from './gateway-B0LJ3-jT.js';
2
+ export { t as AIChatRequest, u as AIChatResponse, w as AIGenerateRequest, x as AIGenerateResponse, y as AIMessage, s as AIModel, A as AIProviderConfig, g as ChatConfig, e as ChatModal, h as ChatModalProps, C as ChatProvider, D as DEFAULT_TIER_FEATURES, f as FeatureMatrix, m as GatewayChatRequest, n as GatewayChatResponse, j as GatewayContract, o as GatewayGenerateRequest, p as GatewayGenerateResponse, r as GatewayMemoryRecord, l as GatewayMessage, k as GatewayMessageContent, q as GatewayModelsResponse, O as OSS_DEFAULT_FEATURES, P as PackageSettings, i as VoiceModelsResponse, V as VoiceService, v as voiceService } from './gateway-B0LJ3-jT.js';
3
3
  import * as react_jsx_runtime from 'react/jsx-runtime';
4
4
  import React, { ReactNode } from 'react';
5
5
  import * as zustand from 'zustand';
package/dist/index.js CHANGED
@@ -4023,10 +4023,16 @@ var init_anthropic_provider = __esm({
4023
4023
  AnthropicProvider = class {
4024
4024
  config;
4025
4025
  baseUrl;
4026
+ version;
4027
+ defaultMaxTokens;
4026
4028
  constructor(config) {
4027
4029
  deprecatedAnthropicProvider();
4028
4030
  this.config = config;
4029
4031
  this.baseUrl = config.baseUrl || "https://api.anthropic.com/v1";
4032
+ this.version = typeof config.anthropicVersion === "string" && config.anthropicVersion.trim() ? config.anthropicVersion.trim() : "2023-06-01";
4033
+ this.defaultMaxTokens = typeof config.anthropicMaxTokens === "number" && config.anthropicMaxTokens > 0 ? config.anthropicMaxTokens : 1024;
4034
+ this.config.anthropicVersion = this.version;
4035
+ this.config.anthropicMaxTokens = this.defaultMaxTokens;
4030
4036
  }
4031
4037
  chat(request) {
4032
4038
  const url = `${this.baseUrl}/messages`;
@@ -4041,7 +4047,7 @@ var init_anthropic_provider = __esm({
4041
4047
  system: systemMessage?.content,
4042
4048
  stream: Boolean(request.stream),
4043
4049
  temperature: request.temperature,
4044
- max_tokens: request.maxTokens ?? 1e3
4050
+ max_tokens: request.maxTokens ?? this.defaultMaxTokens
4045
4051
  };
4046
4052
  if (request.stream) {
4047
4053
  return this.streamChatRequest(url, payload);
@@ -4278,7 +4284,7 @@ var init_anthropic_provider = __esm({
4278
4284
  }
4279
4285
  getHeaders() {
4280
4286
  const headers = {
4281
- "anthropic-version": "2023-06-01"
4287
+ "anthropic-version": this.version
4282
4288
  };
4283
4289
  if (this.config.apiKey) {
4284
4290
  headers["x-api-key"] = this.config.apiKey;
@@ -5836,7 +5842,6 @@ var init_ai_provider_factory = __esm({
5836
5842
  "ollama" /* OLLAMA */,
5837
5843
  "openai" /* OPENAI */,
5838
5844
  "azure-openai" /* AZURE_OPENAI */,
5839
- "anthropic" /* ANTHROPIC */,
5840
5845
  "xai" /* XAI */,
5841
5846
  "gateway" /* GATEWAY */,
5842
5847
  "playground" /* PLAYGROUND */
@@ -6017,8 +6022,10 @@ Do not:
6017
6022
  - Refer to yourself or use phrases like "As an AI..."
6018
6023
  - Include greetings, explanations, or personality
6019
6024
  - Include jokes, fiction, or quotes
6025
+ - Number, bullet, or otherwise prefix the questions with extra characters
6026
+ - Repeat the same idea phrased differently \u2014 each question must explore a distinct angle or subtopic
6020
6027
 
6021
- Output only ${limit} questions \u2014 one per line.`;
6028
+ Output only ${limit} questions \u2014 one per line, with no leading numbers, bullets, or prefixes.`;
6022
6029
  return prompt.trim();
6023
6030
  };
6024
6031
  }
@@ -6239,17 +6246,33 @@ var init_conversationStarters = __esm({
6239
6246
  options: { temperature: 1.5, num_predict: 250 }
6240
6247
  });
6241
6248
  const questions$ = data$.pipe((0, import_rxjs10.map)((d) => {
6242
- const lines = d.response.split("\n").map((line) => line.trim()).filter((line) => {
6243
- return line.length > 10 && !line.toLowerCase().includes("sorry") && !line.toLowerCase().includes("i cannot") && !line.toLowerCase().includes("i can't") && !line.toLowerCase().includes("unable to") && !line.toLowerCase().startsWith("as an ai") && line.includes("?");
6249
+ const sanitizeLine = (line) => {
6250
+ const withoutNumbering = line.replace(/^[0-9]+[.)\-\s:]+/, "").replace(/^[•*+-]\s+/, "");
6251
+ const withoutQuotes = withoutNumbering.replace(/^[“"']+/, "").replace(/[”"']+$/, "");
6252
+ const withoutEmoji = withoutQuotes.replace(/\p{Extended_Pictographic}/gu, "");
6253
+ return withoutEmoji.trim().replace(/\s+/g, " ");
6254
+ };
6255
+ const sanitized = d.response.split("\n").map((line) => sanitizeLine(line.trim())).filter((line) => {
6256
+ const lower = line.toLowerCase();
6257
+ return line.length > 10 && line.includes("?") && !lower.includes("sorry") && !lower.includes("i cannot") && !lower.includes("i can't") && !lower.includes("unable to") && !lower.startsWith("as an ai");
6258
+ }).filter((line) => line.length > 0);
6259
+ const unique = [];
6260
+ const seen = /* @__PURE__ */ new Set();
6261
+ sanitized.forEach((line) => {
6262
+ const key = line.toLowerCase().replace(/[^\p{L}\p{N}]+/gu, " ").trim();
6263
+ if (key && !seen.has(key)) {
6264
+ seen.add(key);
6265
+ unique.push(line);
6266
+ }
6244
6267
  });
6245
- return lines;
6268
+ return unique;
6246
6269
  }));
6247
6270
  const starters = await (0, import_rxjs10.lastValueFrom)(questions$);
6248
6271
  if (starters.length === 0) {
6249
6272
  debugLogger.warn("No meaningful conversation starters generated");
6250
6273
  return [];
6251
6274
  }
6252
- return starters;
6275
+ return starters.slice(0, args.limit);
6253
6276
  } catch (err) {
6254
6277
  debugLogger.error("\u274C Failed to generate conversation starters:", { error: err });
6255
6278
  notificationService.handleHttpError(err);
@@ -28803,6 +28826,9 @@ var AIProviderInitService = class _AIProviderInitService {
28803
28826
  debugLogger.info("AI Provider Init: Found saved config in IndexedDB", { type: savedConfig.type });
28804
28827
  const { id: _id, ...configWithoutId } = savedConfig;
28805
28828
  providerConfig = { ...configWithoutId };
28829
+ if (providerConfig.type === "anthropic" /* ANTHROPIC */) {
28830
+ providerConfig = this.convertAnthropicConfig(providerConfig, settings?.gatewayApiUrl);
28831
+ }
28806
28832
  if ((providerConfig.type === "ollama" /* OLLAMA */ || providerConfig.type === "gateway" /* GATEWAY */) && !providerConfig.tokenFactory) {
28807
28833
  providerConfig.tokenFactory = () => {
28808
28834
  let token = authenticationService.getToken();
@@ -28847,6 +28873,9 @@ var AIProviderInitService = class _AIProviderInitService {
28847
28873
  }
28848
28874
  if (settings.aiProvider) {
28849
28875
  providerConfig = { ...settings.aiProvider };
28876
+ if (providerConfig.type === "anthropic" /* ANTHROPIC */) {
28877
+ providerConfig = this.convertAnthropicConfig(providerConfig, settings.gatewayApiUrl);
28878
+ }
28850
28879
  if (providerConfig.type === "ollama" /* OLLAMA */ && !providerConfig.tokenFactory) {
28851
28880
  providerConfig.tokenFactory = () => {
28852
28881
  let token = authenticationService.getToken();
@@ -29000,6 +29029,21 @@ var AIProviderInitService = class _AIProviderInitService {
29000
29029
  isProviderInitialized() {
29001
29030
  return useAIProviderStore.getState().provider !== null;
29002
29031
  }
29032
+ convertAnthropicConfig(config, gatewayUrl) {
29033
+ if (config.type !== "anthropic" /* ANTHROPIC */) {
29034
+ return config;
29035
+ }
29036
+ const defaultModel = typeof config.defaultModel === "string" && config.defaultModel.trim() ? config.defaultModel.trim() : "claude-3-5-sonnet-latest";
29037
+ const normalized = {
29038
+ type: "gateway" /* GATEWAY */,
29039
+ gatewayUrl: gatewayUrl || config.gatewayUrl || "",
29040
+ provider: "anthropic",
29041
+ defaultModel,
29042
+ tokenFactory: config.tokenFactory
29043
+ };
29044
+ debugLogger.info("AI Provider Init: Converted direct Anthropic provider to gateway configuration");
29045
+ return normalized;
29046
+ }
29003
29047
  };
29004
29048
  var aiProviderInitService = AIProviderInitService.getInstance();
29005
29049
 
@@ -38661,6 +38705,48 @@ var ProviderTab = () => {
38661
38705
  const { settings: packageSettings } = usePackageSettingsStore();
38662
38706
  const theme = (0, import_material43.useTheme)();
38663
38707
  const isMobile = (0, import_material43.useMediaQuery)(theme.breakpoints.down("sm"));
38708
+ const getSuggestedModel = (0, import_react53.useCallback)((type) => {
38709
+ const configuredDefault = packageSettings?.defaultModel?.trim();
38710
+ if (configuredDefault) {
38711
+ return configuredDefault;
38712
+ }
38713
+ switch (type) {
38714
+ case "openai" /* OPENAI */:
38715
+ return "gpt-4o-mini";
38716
+ case "xai" /* XAI */:
38717
+ return "grok-beta";
38718
+ default:
38719
+ return "";
38720
+ }
38721
+ }, [packageSettings?.defaultModel]);
38722
+ const applyDefaultModel = (0, import_react53.useCallback)((config) => {
38723
+ const normalized = { ...config };
38724
+ const trimmed = typeof normalized.defaultModel === "string" ? normalized.defaultModel.trim() : void 0;
38725
+ const requiresModel = normalized.type === "openai" /* OPENAI */ || normalized.type === "xai" /* XAI */;
38726
+ if (trimmed) {
38727
+ normalized.defaultModel = trimmed;
38728
+ return normalized;
38729
+ }
38730
+ if (!requiresModel) {
38731
+ delete normalized.defaultModel;
38732
+ return normalized;
38733
+ }
38734
+ const suggestion = getSuggestedModel(normalized.type);
38735
+ if (suggestion) {
38736
+ normalized.defaultModel = suggestion;
38737
+ } else {
38738
+ delete normalized.defaultModel;
38739
+ }
38740
+ return normalized;
38741
+ }, [getSuggestedModel]);
38742
+ const sanitizeConfigForSave = (0, import_react53.useCallback)((config) => {
38743
+ const sanitized = { ...config };
38744
+ if (typeof sanitized.defaultModel === "string") {
38745
+ const trimmed = sanitized.defaultModel.trim();
38746
+ sanitized.defaultModel = trimmed || void 0;
38747
+ }
38748
+ return sanitized;
38749
+ }, []);
38664
38750
  const [providerConfig, setProviderConfig] = (0, import_react53.useState)({
38665
38751
  type: "ollama",
38666
38752
  baseUrl: "http://localhost:11434"
@@ -38709,19 +38795,38 @@ var ProviderTab = () => {
38709
38795
  }
38710
38796
  return null;
38711
38797
  };
38798
+ const convertAnthropicConfig = (0, import_react53.useCallback)((config) => {
38799
+ if (!config) return null;
38800
+ if (config.type !== "anthropic" /* ANTHROPIC */) {
38801
+ return config;
38802
+ }
38803
+ const gatewayUrl = config.gatewayUrl || packageSettings?.gatewayApiUrl || "";
38804
+ const defaultModel = typeof config.defaultModel === "string" && config.defaultModel.trim() ? config.defaultModel.trim() : "claude-3-5-sonnet-latest";
38805
+ const converted = {
38806
+ type: "gateway" /* GATEWAY */,
38807
+ gatewayUrl,
38808
+ provider: "anthropic",
38809
+ defaultModel,
38810
+ tokenFactory: config.tokenFactory
38811
+ };
38812
+ return converted;
38813
+ }, [packageSettings?.gatewayApiUrl]);
38712
38814
  (0, import_react53.useEffect)(() => {
38713
38815
  const initializeProviderConfig = async () => {
38714
38816
  const savedConfig = await loadProviderConfigFromDB();
38715
38817
  if (savedConfig) {
38716
- setProviderConfig(savedConfig);
38818
+ const normalized = convertAnthropicConfig(savedConfig) || savedConfig;
38819
+ setProviderConfig(applyDefaultModel(normalized));
38717
38820
  } else if (currentProviderConfig) {
38718
- setProviderConfig(currentProviderConfig);
38821
+ const normalized = convertAnthropicConfig(currentProviderConfig) || currentProviderConfig;
38822
+ setProviderConfig(applyDefaultModel(normalized));
38719
38823
  } else if (packageSettings?.aiProvider) {
38720
- setProviderConfig(packageSettings.aiProvider);
38824
+ const normalized = convertAnthropicConfig(packageSettings.aiProvider) || packageSettings.aiProvider;
38825
+ setProviderConfig(applyDefaultModel(normalized));
38721
38826
  }
38722
38827
  };
38723
38828
  initializeProviderConfig();
38724
- }, [currentProviderConfig, packageSettings]);
38829
+ }, [applyDefaultModel, convertAnthropicConfig, currentProviderConfig, packageSettings]);
38725
38830
  const showMessage = (message, severity) => {
38726
38831
  setSnackbarMessage(message);
38727
38832
  setSnackbarSeverity(severity);
@@ -38731,74 +38836,87 @@ var ProviderTab = () => {
38731
38836
  const baseConfig = { type };
38732
38837
  switch (type) {
38733
38838
  case "ollama" /* OLLAMA */:
38734
- setProviderConfig({
38839
+ setProviderConfig(applyDefaultModel({
38735
38840
  ...baseConfig,
38736
38841
  baseUrl: "http://localhost:11434"
38737
- });
38842
+ }));
38738
38843
  break;
38739
38844
  case "openai" /* OPENAI */:
38740
- setProviderConfig({
38845
+ setProviderConfig(applyDefaultModel({
38741
38846
  ...baseConfig,
38742
38847
  baseUrl: "https://api.openai.com/v1",
38743
38848
  apiKey: ""
38744
- });
38849
+ }));
38745
38850
  break;
38746
38851
  case "azure-openai" /* AZURE_OPENAI */:
38747
- setProviderConfig({
38852
+ setProviderConfig(applyDefaultModel({
38748
38853
  ...baseConfig,
38749
38854
  baseUrl: "",
38750
38855
  apiKey: "",
38751
38856
  apiVersion: "2024-02-01",
38752
38857
  deploymentName: ""
38753
- });
38858
+ }));
38754
38859
  break;
38755
38860
  case "anthropic" /* ANTHROPIC */:
38756
- setProviderConfig({
38757
- ...baseConfig,
38758
- baseUrl: "https://api.anthropic.com",
38759
- apiKey: ""
38760
- });
38861
+ showMessage("Anthropic is only available via the Gateway provider. Please configure Gateway and choose Anthropic as the backend.", "error");
38862
+ setProviderConfig(applyDefaultModel({
38863
+ type: "gateway" /* GATEWAY */,
38864
+ gatewayUrl: packageSettings?.gatewayApiUrl || "",
38865
+ provider: "anthropic",
38866
+ defaultModel: "claude-3-5-sonnet-latest"
38867
+ }));
38761
38868
  break;
38762
38869
  case "xai" /* XAI */:
38763
- setProviderConfig({
38870
+ setProviderConfig(applyDefaultModel({
38764
38871
  ...baseConfig,
38765
38872
  baseUrl: "https://api.x.ai/v1",
38766
38873
  apiKey: ""
38767
- });
38874
+ }));
38768
38875
  break;
38769
38876
  case "gateway" /* GATEWAY */:
38770
- setProviderConfig({
38877
+ setProviderConfig(applyDefaultModel({
38771
38878
  ...baseConfig,
38772
38879
  gatewayUrl: packageSettings?.gatewayApiUrl || "",
38773
38880
  provider: "openai"
38774
- });
38881
+ }));
38775
38882
  break;
38776
38883
  case "playground" /* PLAYGROUND */:
38777
- setProviderConfig({
38884
+ setProviderConfig(applyDefaultModel({
38778
38885
  ...baseConfig
38779
- });
38886
+ }));
38780
38887
  break;
38781
38888
  }
38782
38889
  };
38783
38890
  const handleSaveProviderConfig = async () => {
38784
38891
  try {
38785
- const isValid = AIProviderFactory.validateConfig(providerConfig);
38892
+ const normalizedConfigIntermediate = sanitizeConfigForSave(providerConfig);
38893
+ const normalizedConfig = convertAnthropicConfig(normalizedConfigIntermediate) || normalizedConfigIntermediate;
38894
+ const requiresModel = normalizedConfig.type === "openai" /* OPENAI */ || normalizedConfig.type === "xai" /* XAI */;
38895
+ if (requiresModel && !normalizedConfig.defaultModel) {
38896
+ showMessage("Please provide a default model ID for the selected provider.", "error");
38897
+ return;
38898
+ }
38899
+ const isValid = AIProviderFactory.validateConfig(normalizedConfig);
38786
38900
  if (!isValid) {
38787
38901
  showMessage("Invalid provider configuration. Please check all required fields.", "error");
38788
38902
  return;
38789
38903
  }
38790
- await saveProviderConfigToDB(providerConfig);
38791
- await aiProviderInitService.switchProvider(providerConfig);
38904
+ await saveProviderConfigToDB(normalizedConfig);
38905
+ await aiProviderInitService.switchProvider(normalizedConfig);
38792
38906
  if (packageSettings) {
38793
38907
  const updatedSettings = {
38794
38908
  ...packageSettings,
38795
- aiProvider: providerConfig
38909
+ aiProvider: normalizedConfig
38796
38910
  };
38911
+ if (normalizedConfig.defaultModel) {
38912
+ updatedSettings.defaultModel = normalizedConfig.defaultModel;
38913
+ }
38797
38914
  usePackageSettingsStore.setState({ settings: updatedSettings });
38798
38915
  }
38916
+ setProviderConfig(applyDefaultModel(normalizedConfig));
38799
38917
  setIsProviderConfigOpen(false);
38800
38918
  showMessage("Provider configuration saved and switched successfully!", "success");
38801
- debugLogger.info("Provider configuration saved and switched", { type: providerConfig.type });
38919
+ debugLogger.info("Provider configuration saved and switched", { type: normalizedConfig.type });
38802
38920
  } catch (error) {
38803
38921
  debugLogger.error("Failed to save provider configuration:", { error });
38804
38922
  showMessage(`Failed to save provider configuration: ${error instanceof Error ? error.message : "Unknown error"}`, "error");
@@ -38806,8 +38924,9 @@ var ProviderTab = () => {
38806
38924
  };
38807
38925
  const handleTestProviderConnection = async () => {
38808
38926
  try {
38809
- const testConfig = { ...providerConfig };
38810
- const testProvider = AIProviderFactory.createProvider(testConfig);
38927
+ const testConfig = sanitizeConfigForSave(providerConfig);
38928
+ const normalizedTestConfig = convertAnthropicConfig(testConfig) || testConfig;
38929
+ const testProvider = AIProviderFactory.createProvider(normalizedTestConfig);
38811
38930
  const result = await testProvider.validateServiceAvailability({ timeoutMs: 1e4 });
38812
38931
  if (result.isAvailable) {
38813
38932
  showMessage("Connection successful! Provider is available.", "success");
@@ -38897,7 +39016,6 @@ var ProviderTab = () => {
38897
39016
  /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_material43.MenuItem, { value: "ollama", children: "Ollama" }),
38898
39017
  /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_material43.MenuItem, { value: "openai", children: "OpenAI" }),
38899
39018
  /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_material43.MenuItem, { value: "azure-openai", children: "Azure OpenAI" }),
38900
- /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_material43.MenuItem, { value: "anthropic", children: "Anthropic" }),
38901
39019
  /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_material43.MenuItem, { value: "xai", children: "xAI" }),
38902
39020
  /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_material43.MenuItem, { value: "playground", children: "Playground (Mock Demo)" })
38903
39021
  ]
@@ -38953,7 +39071,10 @@ var ProviderTab = () => {
38953
39071
  {
38954
39072
  label: "API Base URL",
38955
39073
  value: providerConfig.baseUrl || "",
38956
- onChange: (e) => setProviderConfig({ ...providerConfig, baseUrl: e.target.value }),
39074
+ onChange: (e) => setProviderConfig((prev) => ({
39075
+ ...prev,
39076
+ baseUrl: e.target.value
39077
+ })),
38957
39078
  fullWidth: true,
38958
39079
  sx: { mb: 2 },
38959
39080
  placeholder: "https://api.openai.com/v1"
@@ -38965,10 +39086,28 @@ var ProviderTab = () => {
38965
39086
  label: "API Key",
38966
39087
  type: "password",
38967
39088
  value: providerConfig.apiKey || "",
38968
- onChange: (e) => setProviderConfig({ ...providerConfig, apiKey: e.target.value }),
39089
+ onChange: (e) => setProviderConfig((prev) => ({
39090
+ ...prev,
39091
+ apiKey: e.target.value
39092
+ })),
38969
39093
  fullWidth: true,
39094
+ sx: { mb: 2 },
38970
39095
  placeholder: "sk-..."
38971
39096
  }
39097
+ ),
39098
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
39099
+ import_material43.TextField,
39100
+ {
39101
+ label: "Default Model ID",
39102
+ value: providerConfig.defaultModel || "",
39103
+ onChange: (e) => setProviderConfig((prev) => ({
39104
+ ...prev,
39105
+ defaultModel: e.target.value
39106
+ })),
39107
+ fullWidth: true,
39108
+ placeholder: "gpt-4o-mini",
39109
+ helperText: "Example: gpt-4o-mini, gpt-4.1, gpt-3.5-turbo"
39110
+ }
38972
39111
  )
38973
39112
  ] }),
38974
39113
  providerConfig.type === "azure-openai" && /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(import_material43.Box, { children: [
@@ -39022,7 +39161,10 @@ var ProviderTab = () => {
39022
39161
  {
39023
39162
  label: "API Base URL",
39024
39163
  value: providerConfig.baseUrl || "",
39025
- onChange: (e) => setProviderConfig({ ...providerConfig, baseUrl: e.target.value }),
39164
+ onChange: (e) => setProviderConfig((prev) => ({
39165
+ ...prev,
39166
+ baseUrl: e.target.value
39167
+ })),
39026
39168
  fullWidth: true,
39027
39169
  sx: { mb: 2 },
39028
39170
  placeholder: "https://api.x.ai/v1"
@@ -39034,36 +39176,31 @@ var ProviderTab = () => {
39034
39176
  label: "API Key",
39035
39177
  type: "password",
39036
39178
  value: providerConfig.apiKey || "",
39037
- onChange: (e) => setProviderConfig({ ...providerConfig, apiKey: e.target.value }),
39038
- fullWidth: true,
39039
- placeholder: "xai-..."
39040
- }
39041
- )
39042
- ] }),
39043
- providerConfig.type === "anthropic" && /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(import_material43.Box, { children: [
39044
- /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
39045
- import_material43.TextField,
39046
- {
39047
- label: "API Base URL",
39048
- value: providerConfig.baseUrl || "",
39049
- onChange: (e) => setProviderConfig({ ...providerConfig, baseUrl: e.target.value }),
39179
+ onChange: (e) => setProviderConfig((prev) => ({
39180
+ ...prev,
39181
+ apiKey: e.target.value
39182
+ })),
39050
39183
  fullWidth: true,
39051
39184
  sx: { mb: 2 },
39052
- placeholder: "https://api.anthropic.com"
39185
+ placeholder: "xai-..."
39053
39186
  }
39054
39187
  ),
39055
39188
  /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
39056
39189
  import_material43.TextField,
39057
39190
  {
39058
- label: "API Key",
39059
- type: "password",
39060
- value: providerConfig.apiKey || "",
39061
- onChange: (e) => setProviderConfig({ ...providerConfig, apiKey: e.target.value }),
39191
+ label: "Default Model ID",
39192
+ value: providerConfig.defaultModel || "",
39193
+ onChange: (e) => setProviderConfig((prev) => ({
39194
+ ...prev,
39195
+ defaultModel: e.target.value
39196
+ })),
39062
39197
  fullWidth: true,
39063
- placeholder: "sk-ant-..."
39198
+ placeholder: "grok-beta",
39199
+ helperText: "Example: grok-beta, grok-2, grok-vision-beta"
39064
39200
  }
39065
39201
  )
39066
39202
  ] }),
39203
+ providerConfig.type === "anthropic" && /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_material43.Alert, { severity: "warning", sx: { mt: 2 }, children: "Anthropic is only supported through the Bandit Gateway provider. Please switch to Gateway and select Anthropic as the backend service." }),
39067
39204
  /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(import_material43.Box, { sx: { display: "flex", gap: 2, mt: 3 }, children: [
39068
39205
  /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
39069
39206
  import_material43.Button,