@burtson-labs/bandit-engine 2.0.102 → 2.0.104
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/dist/{chat-PMO3WTM4.mjs → chat-TIX4XHMD.mjs} +2 -2
- package/dist/{chunk-7NXSMMCU.mjs → chunk-BJOPAWGI.mjs} +2 -2
- package/dist/{chunk-R3HBSHLE.mjs → chunk-EGIUL7QB.mjs} +83 -21
- package/dist/chunk-EGIUL7QB.mjs.map +1 -0
- package/dist/index.js +83 -21
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2 -2
- package/dist/management/management.js +83 -21
- package/dist/management/management.js.map +1 -1
- package/dist/management/management.mjs +1 -1
- package/package.json +1 -1
- package/dist/chunk-R3HBSHLE.mjs.map +0 -1
- /package/dist/{chat-PMO3WTM4.mjs.map → chat-TIX4XHMD.mjs.map} +0 -0
- /package/dist/{chunk-7NXSMMCU.mjs.map → chunk-BJOPAWGI.mjs.map} +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
chat_default
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-EGIUL7QB.mjs";
|
|
4
4
|
import "./chunk-ONQMRE2G.mjs";
|
|
5
5
|
import "./chunk-KYC7CC6C.mjs";
|
|
6
6
|
import "./chunk-BN3D45E2.mjs";
|
|
@@ -13,4 +13,4 @@ import "./chunk-BJTO5JO5.mjs";
|
|
|
13
13
|
export {
|
|
14
14
|
chat_default as default
|
|
15
15
|
};
|
|
16
|
-
//# sourceMappingURL=chat-
|
|
16
|
+
//# sourceMappingURL=chat-TIX4XHMD.mjs.map
|
|
@@ -9738,7 +9738,7 @@ var MCPToolsTabV2_default = MCPToolsTabV2;
|
|
|
9738
9738
|
|
|
9739
9739
|
// src/management/management.tsx
|
|
9740
9740
|
import { jsx as jsx14, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
9741
|
-
var preloadChatPage = () => import("./chat-
|
|
9741
|
+
var preloadChatPage = () => import("./chat-TIX4XHMD.mjs");
|
|
9742
9742
|
var buildCapabilitiesUrl = (gatewayApiUrl) => {
|
|
9743
9743
|
const trimmed = gatewayApiUrl.replace(/\/$/, "");
|
|
9744
9744
|
if (trimmed.endsWith("/api")) {
|
|
@@ -11104,4 +11104,4 @@ export {
|
|
|
11104
11104
|
useGatewayMemory,
|
|
11105
11105
|
management_default
|
|
11106
11106
|
};
|
|
11107
|
-
//# sourceMappingURL=chunk-
|
|
11107
|
+
//# sourceMappingURL=chunk-BJOPAWGI.mjs.map
|
|
@@ -436,6 +436,14 @@ var stripSourcesForDisplay = (content) => {
|
|
|
436
436
|
);
|
|
437
437
|
return c.replace(/\s+$/u, "");
|
|
438
438
|
};
|
|
439
|
+
var linkifyCitations = (content, sources) => {
|
|
440
|
+
if (!content || sources.length === 0) return content;
|
|
441
|
+
const link = (text) => text.replace(/\[(\d{1,2})\]/g, (full, num) => {
|
|
442
|
+
const src = sources[parseInt(num, 10) - 1];
|
|
443
|
+
return src ? `[\\[${num}\\]](${src.url})` : full;
|
|
444
|
+
});
|
|
445
|
+
return content.split(/(```[\s\S]*?```)/g).map((seg, i) => i % 2 === 0 ? link(seg) : seg).join("");
|
|
446
|
+
};
|
|
439
447
|
var domainOf = (url) => {
|
|
440
448
|
try {
|
|
441
449
|
return new URL(url).hostname.replace(/^www\./, "");
|
|
@@ -633,7 +641,7 @@ var ChatMessages = ({
|
|
|
633
641
|
/* @__PURE__ */ jsx6(
|
|
634
642
|
StreamingMarkdown_default,
|
|
635
643
|
{
|
|
636
|
-
content: stripSourcesForDisplay(content),
|
|
644
|
+
content: linkifyCitations(stripSourcesForDisplay(content), parseWebSources(content)),
|
|
637
645
|
isStreaming: isStreaming && isLast,
|
|
638
646
|
sources: sourceSummaries
|
|
639
647
|
}
|
|
@@ -3644,7 +3652,7 @@ TOOL USAGE PROTOCOL (conservative approach)
|
|
|
3644
3652
|
* web_search() - when asked about recent/current events, breaking news, live information (weather, prices, sports scores), or when you need to look up documentation, libraries, APIs, error messages, or verify a specific fact
|
|
3645
3653
|
* web_fetch() - to read the FULL contents of a specific URL you already have. Reach for this when the user wants to "tell me more", "go deeper", "read/open that article", or asks for details about a specific source, link, or article from an EARLIER answer: take that item's URL from the previous Sources list in this conversation and fetch it, then answer from the page's actual content (not just the prior summary)
|
|
3646
3654
|
* image_generation() - ONLY when explicitly asked to create or generate an image
|
|
3647
|
-
* create_file({"content": "...", "filename": "report.docx", "format": "docx"}) - when the user asks for a downloadable FILE (a document, spreadsheet, slides, markdown, code, etc.) or to "export"/"download"/"save" something. Formats: md, txt, csv, json, html, xml, yaml, docx, pptx. For docx/pptx write well-structured Markdown (use "## " headings to start each slide for pptx). It returns a temporary download link \u2014 ALWAYS tell the user the file expires (~1 hour). If it is unclear whether they want it shown inline vs. as a downloadable file, use ask_user first.
|
|
3655
|
+
* create_file({"content": "...", "filename": "report.docx", "format": "docx"}) - when the user asks for a downloadable FILE (a document, spreadsheet, slides, markdown, code, etc.) or to "export"/"download"/"save" something. Formats: md, txt, csv, json, html, xml, yaml, docx, pptx. PDF is NOT a supported format \u2014 if the user asks for a PDF, create a docx instead. For docx/pptx write well-structured Markdown (use "## " headings to start each slide for pptx). It returns a temporary download link \u2014 ALWAYS tell the user the file expires (~1 hour). If it is unclear whether they want it shown inline vs. as a downloadable file, use ask_user first.
|
|
3648
3656
|
* ask_user({"questions": [{"question": "...", "header": "Format", "options": [{"label": "Inline (Recommended)"}, {"label": "Download a file"}]}]}) - when you are genuinely BLOCKED on a decision that is the USER's to make and cannot resolve from the request, context, or sensible defaults (e.g. show content inline vs. let them download it, which format/option they want). Renders clickable options the user answers in one step \u2014 better than asking in prose and ending your turn. Give 1-4 questions, each with 2-4 options; if one is clearly best, list it first and append " (Recommended)". The user may also type their own answer; act on it directly.
|
|
3649
3657
|
- For general questions about concepts, definitions, explanations, or how-to topics, use your built-in knowledge WITHOUT calling tools.
|
|
3650
3658
|
- Examples of what NOT to use tools for: "who are you?", "what is React?", "explain machine learning", "how does X work?", general programming questions.
|
|
@@ -3830,16 +3838,50 @@ ${fn}(${argStr})
|
|
|
3830
3838
|
\`\`\``;
|
|
3831
3839
|
}
|
|
3832
3840
|
}
|
|
3833
|
-
|
|
3834
|
-
const
|
|
3835
|
-
const
|
|
3836
|
-
|
|
3837
|
-
|
|
3838
|
-
|
|
3839
|
-
|
|
3841
|
+
const extractToolCalls = (message) => {
|
|
3842
|
+
const KNOWN = ["web_search", "web_fetch", "image_generation", "create_file", "ask_user", "ask-user"];
|
|
3843
|
+
const out = [];
|
|
3844
|
+
const nameRe = new RegExp(`\\b(${KNOWN.join("|")})\\s*\\(`, "g");
|
|
3845
|
+
let m;
|
|
3846
|
+
while ((m = nameRe.exec(message)) !== null) {
|
|
3847
|
+
const functionName = m[1];
|
|
3848
|
+
const openIdx = m.index + m[0].length - 1;
|
|
3849
|
+
let depth = 0;
|
|
3850
|
+
let i = openIdx;
|
|
3851
|
+
let inStr = false;
|
|
3852
|
+
let esc = false;
|
|
3853
|
+
for (; i < message.length; i++) {
|
|
3854
|
+
const ch = message[i];
|
|
3855
|
+
if (inStr) {
|
|
3856
|
+
if (esc) esc = false;
|
|
3857
|
+
else if (ch === "\\") esc = true;
|
|
3858
|
+
else if (ch === '"') inStr = false;
|
|
3859
|
+
} else if (ch === '"') inStr = true;
|
|
3860
|
+
else if (ch === "(") depth++;
|
|
3861
|
+
else if (ch === ")") {
|
|
3862
|
+
depth--;
|
|
3863
|
+
if (depth === 0) {
|
|
3864
|
+
i++;
|
|
3865
|
+
break;
|
|
3866
|
+
}
|
|
3867
|
+
}
|
|
3868
|
+
}
|
|
3869
|
+
if (depth !== 0) continue;
|
|
3870
|
+
const params = message.slice(openIdx + 1, i - 1).trim();
|
|
3871
|
+
let start = m.index;
|
|
3872
|
+
let end = i;
|
|
3873
|
+
const fenceOpen = message.slice(0, m.index).match(/```[a-zA-Z0-9_-]*[ \t]*\n[ \t]*$/);
|
|
3874
|
+
if (fenceOpen) {
|
|
3875
|
+
start = m.index - fenceOpen[0].length;
|
|
3876
|
+
const fenceClose = message.slice(i).match(/^[ \t]*\n```/);
|
|
3877
|
+
if (fenceClose) end = i + fenceClose[0].length;
|
|
3878
|
+
}
|
|
3879
|
+
out.push({ raw: message.slice(start, end), functionName, params });
|
|
3880
|
+
nameRe.lastIndex = i;
|
|
3840
3881
|
}
|
|
3841
|
-
|
|
3842
|
-
|
|
3882
|
+
return out;
|
|
3883
|
+
};
|
|
3884
|
+
const toolCallMatches = extractToolCalls(fullMessage);
|
|
3843
3885
|
let enhancedMessage = fullMessage;
|
|
3844
3886
|
const summarizableResults = [];
|
|
3845
3887
|
const inlineImageBlocks = [];
|
|
@@ -3847,13 +3889,10 @@ ${fm[1].trim()}
|
|
|
3847
3889
|
if (toolCallMatches && toolCallMatches.length > 0 && mcpToolsAvailable) {
|
|
3848
3890
|
debugLogger.info("Detected tool calls in AI response", {
|
|
3849
3891
|
toolCallCount: toolCallMatches.length,
|
|
3850
|
-
toolCalls: toolCallMatches
|
|
3892
|
+
toolCalls: toolCallMatches.map((t) => t.functionName)
|
|
3851
3893
|
});
|
|
3852
|
-
for (const
|
|
3853
|
-
const
|
|
3854
|
-
const functionCallMatch = toolCallCode.match(/^(\w+)\(\s*(.*?)\s*\)$/);
|
|
3855
|
-
if (!functionCallMatch) continue;
|
|
3856
|
-
const [, functionName, params] = functionCallMatch;
|
|
3894
|
+
for (const call of toolCallMatches) {
|
|
3895
|
+
const { raw: match, functionName, params } = call;
|
|
3857
3896
|
try {
|
|
3858
3897
|
let parsedParams = {};
|
|
3859
3898
|
const raw = params.trim();
|
|
@@ -4017,6 +4056,29 @@ _This link is temporary and expires in about ${mins} minutes._`;
|
|
|
4017
4056
|
try {
|
|
4018
4057
|
const toolResultsText = summarizableResults.map((r) => `## ${r.name}
|
|
4019
4058
|
${r.output}`).join("\n\n");
|
|
4059
|
+
const dedupeSources = (arr) => {
|
|
4060
|
+
const seen = /* @__PURE__ */ new Set();
|
|
4061
|
+
return arr.filter((s) => seen.has(s.url) ? false : (seen.add(s.url), true));
|
|
4062
|
+
};
|
|
4063
|
+
const citeDomain = (u) => {
|
|
4064
|
+
try {
|
|
4065
|
+
return new URL(u).hostname.replace(/^www\./, "");
|
|
4066
|
+
} catch {
|
|
4067
|
+
return u;
|
|
4068
|
+
}
|
|
4069
|
+
};
|
|
4070
|
+
const buildCitationGuide = () => {
|
|
4071
|
+
const cite = dedupeSources(collectedSources).slice(0, 6);
|
|
4072
|
+
if (!cite.length)
|
|
4073
|
+
return `
|
|
4074
|
+
|
|
4075
|
+
Do NOT add citations, footnotes, superscript reference numbers, or a Sources list \u2014 sources are attached automatically.`;
|
|
4076
|
+
const list = cite.map((s, i) => `[${i + 1}] ${s.title || citeDomain(s.url)}`).join("\n");
|
|
4077
|
+
return `
|
|
4078
|
+
|
|
4079
|
+
When a statement is supported by one of the sources below, add an inline citation right after it using that source's number in square brackets \u2014 e.g. [1] or [2]. Use ONLY these numbers, never invent one, never use superscripts, and do NOT write your own Sources/References list (the numbered list is attached automatically below your answer):
|
|
4080
|
+
${list}`;
|
|
4081
|
+
};
|
|
4020
4082
|
const MAX_CHAIN_ROUNDS = 4;
|
|
4021
4083
|
const enabledToolsForChain = getEnabledMCPToolsForAI();
|
|
4022
4084
|
const convo = [
|
|
@@ -4032,7 +4094,7 @@ ${r.output}`).join("\n\n");
|
|
|
4032
4094
|
${toolResultsText}
|
|
4033
4095
|
===END TOOL RESULTS===
|
|
4034
4096
|
|
|
4035
|
-
Use them to fully complete my original request. If you still need to take an action I asked for (for example, actually create a file I want to download), call the appropriate tool now with a \`\`\`tool_code\`\`\` block. Otherwise give your final answer
|
|
4097
|
+
Use them to fully complete my original request. If you still need to take an action I asked for (for example, actually create a file I want to download), call the appropriate tool now with a \`\`\`tool_code\`\`\` block. Otherwise give your final answer.${buildCitationGuide()}`
|
|
4036
4098
|
}
|
|
4037
4099
|
];
|
|
4038
4100
|
const streamTurn = (req) => new Promise((resolve) => {
|
|
@@ -4178,7 +4240,7 @@ That step failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
|
4178
4240
|
${roundOut.join("\n\n")}
|
|
4179
4241
|
===END TOOL RESULTS===
|
|
4180
4242
|
|
|
4181
|
-
Now give your final answer to my original request, or call another tool if you still genuinely need to
|
|
4243
|
+
Now give your final answer to my original request, or call another tool if you still genuinely need to.${buildCitationGuide()}`
|
|
4182
4244
|
});
|
|
4183
4245
|
}
|
|
4184
4246
|
setIsThinking?.(false);
|
|
@@ -4191,7 +4253,7 @@ Now give your final answer to my original request, or call another tool if you s
|
|
|
4191
4253
|
const sourcesMd = collectedSources.length ? `
|
|
4192
4254
|
|
|
4193
4255
|
**Sources**
|
|
4194
|
-
${collectedSources.slice(0, 6).map((s) => {
|
|
4256
|
+
${dedupeSources(collectedSources).slice(0, 6).map((s) => {
|
|
4195
4257
|
let domain = s.url;
|
|
4196
4258
|
try {
|
|
4197
4259
|
domain = new URL(s.url).hostname.replace(/^www\./, "");
|
|
@@ -10663,4 +10725,4 @@ var chat_default = Chat;
|
|
|
10663
10725
|
export {
|
|
10664
10726
|
chat_default
|
|
10665
10727
|
};
|
|
10666
|
-
//# sourceMappingURL=chunk-
|
|
10728
|
+
//# sourceMappingURL=chunk-EGIUL7QB.mjs.map
|