@burtson-labs/bandit-engine 2.0.160 → 2.0.161
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 +78 -77
- package/dist/chat-3JAV77HO.mjs +16 -0
- package/dist/chat-provider.js +195 -111
- package/dist/chat-provider.js.map +1 -1
- package/dist/chat-provider.mjs +5 -5
- package/dist/{chunk-LTWMMHFT.mjs → chunk-EOMOOMUC.mjs} +1819 -3259
- package/dist/chunk-EOMOOMUC.mjs.map +1 -0
- package/dist/{chunk-TKSOJGHX.mjs → chunk-FSRMNQRN.mjs} +61 -60
- package/dist/chunk-FSRMNQRN.mjs.map +1 -0
- package/dist/{chunk-PDQT564P.mjs → chunk-MIDYEQOS.mjs} +2 -2
- package/dist/chunk-PFKKGJAQ.mjs +390 -0
- package/dist/chunk-PFKKGJAQ.mjs.map +1 -0
- package/dist/{chunk-LFQH6M6B.mjs → chunk-QPXG4A5C.mjs} +5 -5
- package/dist/chunk-QPXG4A5C.mjs.map +1 -0
- package/dist/{chunk-P6SLB5RC.mjs → chunk-QXITTH2X.mjs} +2 -2
- package/dist/{chunk-MHF76C2F.mjs → chunk-TTAORNWI.mjs} +1342 -1221
- package/dist/chunk-TTAORNWI.mjs.map +1 -0
- package/dist/{chunk-XTB6ZLUI.mjs → chunk-WQEBTH2R.mjs} +7 -2
- package/dist/{chunk-XTB6ZLUI.mjs.map → chunk-WQEBTH2R.mjs.map} +1 -1
- package/dist/{chunk-PXCIDXRP.mjs → chunk-X65A3NED.mjs} +5 -5
- package/dist/{chunk-IABD4L6K.mjs → chunk-XC7HDKFW.mjs} +3840 -4456
- package/dist/chunk-XC7HDKFW.mjs.map +1 -0
- package/dist/index.d.mts +85 -2
- package/dist/index.d.ts +85 -2
- package/dist/index.js +7994 -9837
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +23 -14
- package/dist/index.mjs.map +1 -1
- package/dist/management/management.js +7595 -9447
- package/dist/management/management.js.map +1 -1
- package/dist/management/management.mjs +8 -8
- package/dist/modals/chat-modal/chat-modal.js +1656 -3299
- package/dist/modals/chat-modal/chat-modal.js.map +1 -1
- package/dist/modals/chat-modal/chat-modal.mjs +4 -4
- package/dist/{modelStore-NMCRL3FR.mjs → modelStore-FGUGOWTL.mjs} +2 -2
- package/package.json +4 -2
- package/dist/chat-4BOIV4VP.mjs +0 -16
- package/dist/chunk-IABD4L6K.mjs.map +0 -1
- package/dist/chunk-LFQH6M6B.mjs.map +0 -1
- package/dist/chunk-LNGF2XAZ.mjs +0 -311
- package/dist/chunk-LNGF2XAZ.mjs.map +0 -1
- package/dist/chunk-LTWMMHFT.mjs.map +0 -1
- package/dist/chunk-MHF76C2F.mjs.map +0 -1
- package/dist/chunk-TKSOJGHX.mjs.map +0 -1
- /package/dist/{chat-4BOIV4VP.mjs.map → chat-3JAV77HO.mjs.map} +0 -0
- /package/dist/{chunk-PDQT564P.mjs.map → chunk-MIDYEQOS.mjs.map} +0 -0
- /package/dist/{chunk-P6SLB5RC.mjs.map → chunk-QXITTH2X.mjs.map} +0 -0
- /package/dist/{chunk-PXCIDXRP.mjs.map → chunk-X65A3NED.mjs.map} +0 -0
- /package/dist/{modelStore-NMCRL3FR.mjs.map → modelStore-FGUGOWTL.mjs.map} +0 -0
package/dist/chat-provider.js
CHANGED
|
@@ -619,6 +619,8 @@ var init_preferencesStore = __esm({
|
|
|
619
619
|
usePreferencesStore = (0, import_zustand4.create)((set, get) => ({
|
|
620
620
|
preferences: defaultPreferences,
|
|
621
621
|
isLoaded: false,
|
|
622
|
+
saveState: "idle",
|
|
623
|
+
lastSavedAt: null,
|
|
622
624
|
setPreferences: (newPreferences) => {
|
|
623
625
|
const sanitized = sanitizePreferences(newPreferences);
|
|
624
626
|
set((state) => ({
|
|
@@ -661,6 +663,7 @@ var init_preferencesStore = __esm({
|
|
|
661
663
|
}
|
|
662
664
|
},
|
|
663
665
|
savePreferences: async () => {
|
|
666
|
+
set({ saveState: "saving" });
|
|
664
667
|
try {
|
|
665
668
|
const { preferences } = get();
|
|
666
669
|
const storeConfigs6 = [{ name: "config", keyPath: "id" }];
|
|
@@ -669,8 +672,10 @@ var init_preferencesStore = __esm({
|
|
|
669
672
|
preferences
|
|
670
673
|
}, storeConfigs6);
|
|
671
674
|
debugLogger.debug("Preferences saved to IndexedDB");
|
|
675
|
+
set({ saveState: "saved", lastSavedAt: Date.now() });
|
|
672
676
|
} catch (error) {
|
|
673
677
|
debugLogger.error("Failed to save preferences to IndexedDB", { error });
|
|
678
|
+
set({ saveState: "error" });
|
|
674
679
|
}
|
|
675
680
|
},
|
|
676
681
|
exportPreferences: () => {
|
|
@@ -6674,6 +6679,16 @@ var discoverMcpTools = async (id) => parse(await fetch(`${gatewayBase()}/mcp/ser
|
|
|
6674
6679
|
|
|
6675
6680
|
// src/store/mcpToolsStore.ts
|
|
6676
6681
|
var sanitizeMcpToolName = (raw) => raw.replace(/[^a-zA-Z0-9_]/g, "_").replace(/_+/g, "_").replace(/^_|_$/g, "").slice(0, 60);
|
|
6682
|
+
var STORE_CONFIGS = [{ name: "config", keyPath: "id" }];
|
|
6683
|
+
var readChoices = (value) => {
|
|
6684
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return {};
|
|
6685
|
+
const out = {};
|
|
6686
|
+
for (const [id, on] of Object.entries(value)) {
|
|
6687
|
+
if (typeof on === "boolean") out[id] = on;
|
|
6688
|
+
}
|
|
6689
|
+
return out;
|
|
6690
|
+
};
|
|
6691
|
+
var withChoice = (tool, choices) => Object.prototype.hasOwnProperty.call(choices, tool.id) && tool.enabled !== choices[tool.id] ? { ...tool, enabled: choices[tool.id] } : tool;
|
|
6677
6692
|
var healthCheckTool = {
|
|
6678
6693
|
id: "health-check",
|
|
6679
6694
|
name: "check_gateway_health",
|
|
@@ -6787,130 +6802,199 @@ var createFileTool = {
|
|
|
6787
6802
|
isBuiltIn: true
|
|
6788
6803
|
};
|
|
6789
6804
|
var defaultTools = [healthCheckTool, webSearchTool, webFetchTool, imageGenerationTool, createFileTool];
|
|
6790
|
-
var useMCPToolsStore = (0, import_zustand11.create)((set, get) =>
|
|
6791
|
-
|
|
6792
|
-
|
|
6793
|
-
|
|
6794
|
-
|
|
6795
|
-
|
|
6796
|
-
|
|
6797
|
-
|
|
6798
|
-
|
|
6799
|
-
|
|
6800
|
-
|
|
6801
|
-
|
|
6802
|
-
},
|
|
6803
|
-
updateTool: (id, updates) => {
|
|
6804
|
-
set((state) => ({
|
|
6805
|
-
tools: state.tools.map(
|
|
6806
|
-
(tool) => tool.id === id ? { ...tool, ...updates } : tool
|
|
6807
|
-
)
|
|
6808
|
-
}));
|
|
6809
|
-
get().saveTools();
|
|
6810
|
-
},
|
|
6811
|
-
deleteTool: (id) => {
|
|
6812
|
-
set((state) => ({
|
|
6813
|
-
tools: state.tools.filter((tool) => tool.id !== id || tool.isBuiltIn)
|
|
6814
|
-
}));
|
|
6815
|
-
get().saveTools();
|
|
6816
|
-
},
|
|
6817
|
-
toggleTool: (id) => {
|
|
6818
|
-
set((state) => ({
|
|
6819
|
-
tools: state.tools.map(
|
|
6820
|
-
(tool) => tool.id === id ? { ...tool, enabled: !tool.enabled } : tool
|
|
6821
|
-
)
|
|
6822
|
-
}));
|
|
6823
|
-
get().saveTools();
|
|
6824
|
-
},
|
|
6825
|
-
getEnabledTools: () => {
|
|
6826
|
-
return get().tools.filter((tool) => tool.enabled);
|
|
6827
|
-
},
|
|
6828
|
-
loadTools: async () => {
|
|
6829
|
-
try {
|
|
6830
|
-
const storeConfigs6 = [{ name: "config", keyPath: "id" }];
|
|
6831
|
-
const data = await indexedDBService_default.get("banditConfig", 1, "config", "mcpTools", storeConfigs6);
|
|
6832
|
-
if (data?.tools && Array.isArray(data.tools)) {
|
|
6833
|
-
const savedTools = data.tools;
|
|
6834
|
-
const builtInIds = defaultTools.map((t) => t.id);
|
|
6835
|
-
const customTools = savedTools.filter(
|
|
6836
|
-
(tool) => !tool.isBuiltIn && !builtInIds.includes(tool.id)
|
|
6837
|
-
);
|
|
6838
|
-
set({
|
|
6839
|
-
tools: [...defaultTools, ...customTools],
|
|
6840
|
-
isLoaded: true
|
|
6841
|
-
});
|
|
6842
|
-
debugLogger.info("MCP tools loaded from IndexedDB", {
|
|
6843
|
-
totalTools: defaultTools.length + customTools.length,
|
|
6844
|
-
builtInTools: defaultTools.length,
|
|
6845
|
-
customTools: customTools.length
|
|
6846
|
-
});
|
|
6847
|
-
} else {
|
|
6848
|
-
set({ isLoaded: true });
|
|
6849
|
-
await get().saveTools();
|
|
6850
|
-
debugLogger.info("Default MCP tools initialized");
|
|
6851
|
-
}
|
|
6852
|
-
} catch (error) {
|
|
6853
|
-
debugLogger.error("Failed to load MCP tools from IndexedDB", { error });
|
|
6854
|
-
set({ isLoaded: true });
|
|
6855
|
-
}
|
|
6856
|
-
},
|
|
6857
|
-
saveTools: async () => {
|
|
6805
|
+
var useMCPToolsStore = (0, import_zustand11.create)((set, get) => {
|
|
6806
|
+
const persist = async () => {
|
|
6807
|
+
const { tools, choices } = get();
|
|
6808
|
+
const customTools = tools.filter((tool) => !tool.isBuiltIn && !tool.mcpServerId);
|
|
6809
|
+
await indexedDBService_default.put("banditConfig", 1, "config", {
|
|
6810
|
+
id: "mcpTools",
|
|
6811
|
+
tools: customTools,
|
|
6812
|
+
choices
|
|
6813
|
+
}, STORE_CONFIGS);
|
|
6814
|
+
debugLogger.debug("MCP tools saved to IndexedDB", { toolCount: customTools.length, choices: Object.keys(choices).length });
|
|
6815
|
+
};
|
|
6816
|
+
const persistQuietly = async () => {
|
|
6858
6817
|
try {
|
|
6859
|
-
|
|
6860
|
-
const storeConfigs6 = [{ name: "config", keyPath: "id" }];
|
|
6861
|
-
const customTools = tools.filter((tool) => !tool.isBuiltIn && !tool.mcpServerId);
|
|
6862
|
-
await indexedDBService_default.put("banditConfig", 1, "config", {
|
|
6863
|
-
id: "mcpTools",
|
|
6864
|
-
tools: customTools
|
|
6865
|
-
}, storeConfigs6);
|
|
6866
|
-
debugLogger.debug("MCP tools saved to IndexedDB", { toolCount: customTools.length });
|
|
6818
|
+
await persist();
|
|
6867
6819
|
} catch (error) {
|
|
6868
6820
|
debugLogger.error("Failed to save MCP tools to IndexedDB", { error });
|
|
6869
6821
|
}
|
|
6870
|
-
}
|
|
6871
|
-
|
|
6872
|
-
|
|
6873
|
-
|
|
6874
|
-
|
|
6875
|
-
|
|
6876
|
-
|
|
6877
|
-
|
|
6878
|
-
|
|
6879
|
-
|
|
6880
|
-
|
|
6881
|
-
|
|
6882
|
-
|
|
6883
|
-
|
|
6822
|
+
};
|
|
6823
|
+
return {
|
|
6824
|
+
tools: defaultTools,
|
|
6825
|
+
isLoaded: false,
|
|
6826
|
+
choices: {},
|
|
6827
|
+
saveState: "idle",
|
|
6828
|
+
lastSavedAt: null,
|
|
6829
|
+
addTool: (toolData) => {
|
|
6830
|
+
const newTool = {
|
|
6831
|
+
...toolData,
|
|
6832
|
+
id: `tool-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`
|
|
6833
|
+
};
|
|
6834
|
+
set((state) => ({
|
|
6835
|
+
tools: [...state.tools, newTool]
|
|
6836
|
+
}));
|
|
6837
|
+
get().saveTools();
|
|
6838
|
+
},
|
|
6839
|
+
updateTool: (id, updates) => {
|
|
6840
|
+
set((state) => ({
|
|
6841
|
+
tools: state.tools.map(
|
|
6842
|
+
(tool) => tool.id === id ? { ...tool, ...updates } : tool
|
|
6843
|
+
)
|
|
6844
|
+
}));
|
|
6845
|
+
get().saveTools();
|
|
6846
|
+
},
|
|
6847
|
+
deleteTool: (id) => {
|
|
6848
|
+
set((state) => ({
|
|
6849
|
+
tools: state.tools.filter((tool) => tool.id !== id || tool.isBuiltIn)
|
|
6850
|
+
}));
|
|
6851
|
+
get().saveTools();
|
|
6852
|
+
},
|
|
6853
|
+
toggleTool: async (id) => {
|
|
6854
|
+
const tool = get().tools.find((t) => t.id === id);
|
|
6855
|
+
if (!tool) return false;
|
|
6856
|
+
const enabled = !tool.enabled;
|
|
6857
|
+
set((state) => ({
|
|
6858
|
+
tools: state.tools.map((t) => t.id === id ? { ...t, enabled } : t),
|
|
6859
|
+
choices: { ...state.choices, [id]: enabled }
|
|
6860
|
+
}));
|
|
6861
|
+
return get().saveTools();
|
|
6862
|
+
},
|
|
6863
|
+
getEnabledTools: () => {
|
|
6864
|
+
return get().tools.filter((tool) => tool.enabled);
|
|
6865
|
+
},
|
|
6866
|
+
loadTools: async () => {
|
|
6867
|
+
try {
|
|
6868
|
+
const data = await indexedDBService_default.get("banditConfig", 1, "config", "mcpTools", STORE_CONFIGS);
|
|
6869
|
+
if (data?.tools && Array.isArray(data.tools)) {
|
|
6870
|
+
const choices = { ...readChoices(data.choices), ...get().choices };
|
|
6871
|
+
const savedTools = data.tools;
|
|
6872
|
+
const builtInIds = defaultTools.map((t) => t.id);
|
|
6873
|
+
const customTools = savedTools.filter(
|
|
6874
|
+
(tool) => !tool.isBuiltIn && !builtInIds.includes(tool.id)
|
|
6875
|
+
);
|
|
6876
|
+
const discovered = get().tools.filter((t) => t.mcpServerId);
|
|
6877
|
+
set({
|
|
6878
|
+
tools: [...defaultTools, ...customTools, ...discovered].map((t) => withChoice(t, choices)),
|
|
6879
|
+
choices,
|
|
6880
|
+
isLoaded: true
|
|
6881
|
+
});
|
|
6882
|
+
debugLogger.info("MCP tools loaded from IndexedDB", {
|
|
6883
|
+
totalTools: defaultTools.length + customTools.length,
|
|
6884
|
+
builtInTools: defaultTools.length,
|
|
6885
|
+
customTools: customTools.length,
|
|
6886
|
+
choices: Object.keys(choices).length
|
|
6887
|
+
});
|
|
6888
|
+
} else {
|
|
6889
|
+
set({ isLoaded: true });
|
|
6890
|
+
await persistQuietly();
|
|
6891
|
+
debugLogger.info("Default MCP tools initialized");
|
|
6892
|
+
}
|
|
6893
|
+
} catch (error) {
|
|
6894
|
+
debugLogger.error("Failed to load MCP tools from IndexedDB", { error });
|
|
6895
|
+
set({ isLoaded: true });
|
|
6896
|
+
}
|
|
6897
|
+
},
|
|
6898
|
+
saveTools: async () => {
|
|
6899
|
+
set({ saveState: "saving" });
|
|
6884
6900
|
try {
|
|
6885
|
-
|
|
6886
|
-
|
|
6887
|
-
|
|
6888
|
-
|
|
6889
|
-
|
|
6890
|
-
|
|
6891
|
-
|
|
6892
|
-
|
|
6893
|
-
|
|
6901
|
+
await persist();
|
|
6902
|
+
set({ saveState: "saved", lastSavedAt: Date.now() });
|
|
6903
|
+
return true;
|
|
6904
|
+
} catch (error) {
|
|
6905
|
+
debugLogger.error("Failed to save MCP tools to IndexedDB", { error });
|
|
6906
|
+
set({ saveState: "error" });
|
|
6907
|
+
return false;
|
|
6908
|
+
}
|
|
6909
|
+
},
|
|
6910
|
+
syncControllerTools: (controllerTools) => {
|
|
6911
|
+
const { choices } = get();
|
|
6912
|
+
const next = [...get().tools];
|
|
6913
|
+
let changed = false;
|
|
6914
|
+
for (const ct of controllerTools) {
|
|
6915
|
+
const functionName = (ct.id || ct.name).replace(/[^a-zA-Z0-9_]/g, "_");
|
|
6916
|
+
const index = [
|
|
6917
|
+
next.findIndex((lt) => lt.function.name === functionName),
|
|
6918
|
+
next.findIndex((lt) => lt.function.name === ct.id),
|
|
6919
|
+
next.findIndex((lt) => lt.id === ct.id)
|
|
6920
|
+
].find((i) => i >= 0) ?? -1;
|
|
6921
|
+
if (index < 0) {
|
|
6922
|
+
next.push({
|
|
6923
|
+
id: `tool-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
|
|
6924
|
+
name: functionName,
|
|
6925
|
+
description: ct.description,
|
|
6926
|
+
enabled: ct.isEnabled,
|
|
6894
6927
|
type: "function",
|
|
6895
6928
|
function: {
|
|
6896
|
-
name:
|
|
6897
|
-
|
|
6898
|
-
|
|
6929
|
+
name: ct.id,
|
|
6930
|
+
// the controller id maps back to the tool
|
|
6931
|
+
description: ct.description,
|
|
6932
|
+
parameters: { type: "object", properties: {}, required: [] }
|
|
6899
6933
|
},
|
|
6900
|
-
|
|
6901
|
-
|
|
6934
|
+
endpoint: `/mcp/${ct.id}`,
|
|
6935
|
+
method: "GET",
|
|
6936
|
+
isBuiltIn: false
|
|
6902
6937
|
});
|
|
6938
|
+
changed = true;
|
|
6939
|
+
continue;
|
|
6940
|
+
}
|
|
6941
|
+
const local = next[index];
|
|
6942
|
+
const enabled = Object.prototype.hasOwnProperty.call(choices, local.id) ? choices[local.id] : ct.isEnabled;
|
|
6943
|
+
if (local.enabled !== enabled) {
|
|
6944
|
+
next[index] = { ...local, enabled };
|
|
6945
|
+
changed = true;
|
|
6903
6946
|
}
|
|
6947
|
+
}
|
|
6948
|
+
if (!changed) return;
|
|
6949
|
+
set({ tools: next });
|
|
6950
|
+
void persistQuietly();
|
|
6951
|
+
},
|
|
6952
|
+
// Discover the user's connected MCP servers' tools from the gateway and merge
|
|
6953
|
+
// them into the tool list (so the model can call them). Replaces any prior
|
|
6954
|
+
// MCP-server tools; best-effort — a single unreachable server is skipped.
|
|
6955
|
+
loadMcpServerTools: async () => {
|
|
6956
|
+
let servers;
|
|
6957
|
+
try {
|
|
6958
|
+
servers = await listMcpServers();
|
|
6904
6959
|
} catch (error) {
|
|
6905
|
-
debugLogger.warn("
|
|
6960
|
+
debugLogger.warn("Could not list MCP servers", { error: String(error) });
|
|
6961
|
+
return;
|
|
6906
6962
|
}
|
|
6963
|
+
const collected = [];
|
|
6964
|
+
for (const server of servers.filter((s) => s.enabled)) {
|
|
6965
|
+
try {
|
|
6966
|
+
const { tools } = await discoverMcpTools(server.id);
|
|
6967
|
+
for (const t of tools) {
|
|
6968
|
+
const fnName = sanitizeMcpToolName(`mcp_${server.name}_${t.name}`);
|
|
6969
|
+
const schema = t.inputSchema && typeof t.inputSchema === "object" && t.inputSchema.type === "object" ? t.inputSchema : { type: "object", properties: {}, required: [] };
|
|
6970
|
+
const id = `mcp-${server.id}-${t.name}`;
|
|
6971
|
+
const { choices } = get();
|
|
6972
|
+
collected.push({
|
|
6973
|
+
id,
|
|
6974
|
+
name: fnName,
|
|
6975
|
+
description: t.description || `${t.name} (via ${server.name})`,
|
|
6976
|
+
enabled: Object.prototype.hasOwnProperty.call(choices, id) ? choices[id] : true,
|
|
6977
|
+
type: "function",
|
|
6978
|
+
function: {
|
|
6979
|
+
name: fnName,
|
|
6980
|
+
description: t.description || `${t.name} \u2014 provided by the ${server.name} MCP server.`,
|
|
6981
|
+
parameters: schema
|
|
6982
|
+
},
|
|
6983
|
+
mcpServerId: server.id,
|
|
6984
|
+
mcpToolName: t.name
|
|
6985
|
+
});
|
|
6986
|
+
}
|
|
6987
|
+
} catch (error) {
|
|
6988
|
+
debugLogger.warn("Failed to discover tools for MCP server", { server: server.name, error: String(error) });
|
|
6989
|
+
}
|
|
6990
|
+
}
|
|
6991
|
+
set((state) => ({
|
|
6992
|
+
tools: [...state.tools.filter((t) => !t.mcpServerId), ...collected]
|
|
6993
|
+
}));
|
|
6994
|
+
debugLogger.info("MCP server tools loaded", { count: collected.length });
|
|
6907
6995
|
}
|
|
6908
|
-
|
|
6909
|
-
|
|
6910
|
-
}));
|
|
6911
|
-
debugLogger.info("MCP server tools loaded", { count: collected.length });
|
|
6912
|
-
}
|
|
6913
|
-
}));
|
|
6996
|
+
};
|
|
6997
|
+
});
|
|
6914
6998
|
|
|
6915
6999
|
// src/chat/hooks/useKnowledgeStore.tsx
|
|
6916
7000
|
var import_react4 = require("react");
|