@burtson-labs/bandit-engine 2.0.71 → 2.0.72
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-2QWK6OUO.mjs → chat-GLBQOPNT.mjs} +2 -2
- package/dist/{chunk-VKDU2OMI.mjs → chunk-7ZHLQXHL.mjs} +2 -2
- package/dist/{chunk-CMBYMC3G.mjs → chunk-LDL4X6CB.mjs} +126 -31
- package/dist/chunk-LDL4X6CB.mjs.map +1 -0
- package/dist/index.js +125 -30
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2 -2
- package/dist/management/management.js +125 -30
- package/dist/management/management.js.map +1 -1
- package/dist/management/management.mjs +1 -1
- package/package.json +1 -1
- package/dist/chunk-CMBYMC3G.mjs.map +0 -1
- /package/dist/{chat-2QWK6OUO.mjs.map → chat-GLBQOPNT.mjs.map} +0 -0
- /package/dist/{chunk-VKDU2OMI.mjs.map → chunk-7ZHLQXHL.mjs.map} +0 -0
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
chat_default
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-LDL4X6CB.mjs";
|
|
4
4
|
import {
|
|
5
5
|
chat_provider_default
|
|
6
6
|
} from "./chunk-SXLI47FV.mjs";
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
useGatewayHealth,
|
|
11
11
|
useGatewayMemory,
|
|
12
12
|
useGatewayModels
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-7ZHLQXHL.mjs";
|
|
14
14
|
import "./chunk-U633CJBV.mjs";
|
|
15
15
|
import "./chunk-6ITUH375.mjs";
|
|
16
16
|
import "./chunk-DHYP4K5O.mjs";
|
|
@@ -23545,41 +23545,38 @@ _This link is temporary and expires in about ${mins} minutes._`;
|
|
|
23545
23545
|
try {
|
|
23546
23546
|
const toolResultsText = summarizableResults.map((r) => `## ${r.name}
|
|
23547
23547
|
${r.output}`).join("\n\n");
|
|
23548
|
-
const
|
|
23549
|
-
|
|
23548
|
+
const MAX_CHAIN_ROUNDS = 4;
|
|
23549
|
+
const enabledToolsForChain = getEnabledMCPToolsForAI();
|
|
23550
|
+
const convo = [
|
|
23551
|
+
{ role: "system", content: enhancedSystemPrompt },
|
|
23550
23552
|
...contextMessages,
|
|
23551
23553
|
{ role: "user", content: question },
|
|
23552
|
-
{ role: "assistant", content: stripToolBlocks(fullMessage) || "Let me
|
|
23554
|
+
{ role: "assistant", content: stripToolBlocks(fullMessage) || "Let me work on that." },
|
|
23553
23555
|
{
|
|
23554
23556
|
role: "user",
|
|
23555
|
-
content: `
|
|
23557
|
+
content: `Here are the results of the tool(s) so far:
|
|
23556
23558
|
|
|
23557
23559
|
${toolResultsText}
|
|
23558
23560
|
|
|
23559
|
-
|
|
23561
|
+
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. Do NOT add a "Sources"/"References"/"Citations" list \u2014 one is appended automatically.`
|
|
23560
23562
|
}
|
|
23561
23563
|
];
|
|
23562
|
-
const
|
|
23563
|
-
model: modelName,
|
|
23564
|
-
messages: summaryMessages,
|
|
23565
|
-
stream: true,
|
|
23566
|
-
options: { num_predict: tokenLimit + 250 }
|
|
23567
|
-
};
|
|
23568
|
-
clearFlushTimer();
|
|
23569
|
-
setStreamBuffer("");
|
|
23570
|
-
setIsThinking?.(true);
|
|
23571
|
-
const summaryText = await new Promise((resolve) => {
|
|
23564
|
+
const streamTurn = (req) => new Promise((resolve) => {
|
|
23572
23565
|
let acc = "";
|
|
23566
|
+
const native = [];
|
|
23573
23567
|
let settled = false;
|
|
23574
23568
|
let timer;
|
|
23575
|
-
const
|
|
23569
|
+
const finish = (value) => {
|
|
23576
23570
|
if (settled) return;
|
|
23577
23571
|
settled = true;
|
|
23578
23572
|
if (timer) clearTimeout(timer);
|
|
23579
23573
|
resolve(value);
|
|
23580
23574
|
};
|
|
23581
|
-
const
|
|
23575
|
+
const sub2 = provider.chat(req).subscribe({
|
|
23582
23576
|
next: (data) => {
|
|
23577
|
+
if (Array.isArray(data?.message?.tool_calls) && data.message.tool_calls.length) {
|
|
23578
|
+
native.push(...data.message.tool_calls);
|
|
23579
|
+
}
|
|
23583
23580
|
if (data?.message?.content) {
|
|
23584
23581
|
acc += data.message.content;
|
|
23585
23582
|
const visible = stripThinking(acc);
|
|
@@ -23589,27 +23586,125 @@ Using these results together with your own knowledge, answer my original questio
|
|
|
23589
23586
|
setStreamBuffer(visible);
|
|
23590
23587
|
}
|
|
23591
23588
|
},
|
|
23592
|
-
error: (
|
|
23593
|
-
|
|
23594
|
-
error: summaryErr instanceof Error ? summaryErr.message : String(summaryErr)
|
|
23595
|
-
});
|
|
23596
|
-
done("");
|
|
23597
|
-
},
|
|
23598
|
-
complete: () => done(stripThinking(acc).trim())
|
|
23589
|
+
error: () => finish({ text: stripThinking(acc).trim(), native }),
|
|
23590
|
+
complete: () => finish({ text: stripThinking(acc).trim(), native })
|
|
23599
23591
|
});
|
|
23600
|
-
currentSubRef.current =
|
|
23592
|
+
currentSubRef.current = sub2;
|
|
23601
23593
|
timer = setTimeout(() => {
|
|
23602
|
-
debugLogger.warn("Summarization pass timed out; using inline tool output");
|
|
23603
23594
|
try {
|
|
23604
|
-
|
|
23595
|
+
sub2.unsubscribe();
|
|
23605
23596
|
} catch {
|
|
23606
23597
|
}
|
|
23607
|
-
|
|
23598
|
+
finish({ text: stripThinking(acc).trim(), native });
|
|
23608
23599
|
}, 3e4);
|
|
23609
23600
|
});
|
|
23601
|
+
const runChainedTool = async (fn, params) => {
|
|
23602
|
+
if (fn === "ask_user" || fn === "ask-user") {
|
|
23603
|
+
const qs = parseAskUserQuestions(params.questions ?? params);
|
|
23604
|
+
if (!qs.length) return "ask_user failed: it needs a questions array.";
|
|
23605
|
+
const ans = await useAskUserStore.getState().ask(qs);
|
|
23606
|
+
return ans ? "The user answered:\n\n" + qs.map((q) => `Q: ${q.question}
|
|
23607
|
+
A: ${(ans[q.id] || "").trim() || "(no answer)"}`).join("\n\n") : "The user dismissed the question(s). Proceed with your best judgment.";
|
|
23608
|
+
}
|
|
23609
|
+
const status = fn === "create_file" || fn === "create-file" ? "Creating the file\u2026" : fn === "web_search" || fn === "web-search" ? "Searching the web\u2026" : fn === "web_fetch" || fn === "web-fetch" ? "Reading the page\u2026" : fn === "image_generation" || fn === "image-generation" ? "Generating the image\u2026" : "Working on it\u2026";
|
|
23610
|
+
setStreamBuffer(`_${status}_`);
|
|
23611
|
+
const result = await executeMCPTool({ toolName: fn, parameters: params });
|
|
23612
|
+
if (!result.success) return `That step failed: ${result.error || "unknown error"}.`;
|
|
23613
|
+
if (fn === "create_file" || fn === "create-file") {
|
|
23614
|
+
const f = result.data ?? {};
|
|
23615
|
+
if (f.url) {
|
|
23616
|
+
const mins = f.expiresInMinutes ?? 60;
|
|
23617
|
+
const name = f.filename || "your file";
|
|
23618
|
+
inlineImageBlocks.push(`\u{1F4C4} **[${name}](${f.url})** \u2014 ready to download.
|
|
23619
|
+
|
|
23620
|
+
_This link is temporary and expires in about ${mins} minutes._`);
|
|
23621
|
+
return `File created and its download link is now shown to the user. Briefly confirm it's ready and that it expires in ~${mins} minutes.`;
|
|
23622
|
+
}
|
|
23623
|
+
return "The file was created.";
|
|
23624
|
+
}
|
|
23625
|
+
if (fn === "image_generation" || fn === "image-generation") {
|
|
23626
|
+
const img = result.data ?? {};
|
|
23627
|
+
if (img.imageUrl) {
|
|
23628
|
+
inlineImageBlocks.push(``);
|
|
23629
|
+
return "Image generated and shown to the user.";
|
|
23630
|
+
}
|
|
23631
|
+
}
|
|
23632
|
+
if (typeof result.data === "string") return result.data.slice(0, 2e3);
|
|
23633
|
+
if (result.data) return JSON.stringify(result.data).slice(0, 1500);
|
|
23634
|
+
return "Done.";
|
|
23635
|
+
};
|
|
23636
|
+
clearFlushTimer();
|
|
23637
|
+
let finalText = "";
|
|
23638
|
+
let lastTurnText = "";
|
|
23639
|
+
for (let round = 0; round < MAX_CHAIN_ROUNDS; round++) {
|
|
23640
|
+
setStreamBuffer("");
|
|
23641
|
+
setIsThinking?.(true);
|
|
23642
|
+
const turnRequest = {
|
|
23643
|
+
model: modelName,
|
|
23644
|
+
messages: convo,
|
|
23645
|
+
stream: true,
|
|
23646
|
+
tools: enabledToolsForChain.length ? enabledToolsForChain : void 0,
|
|
23647
|
+
options: { num_predict: tokenLimit + 250 }
|
|
23648
|
+
};
|
|
23649
|
+
const { text: turnText, native: turnNative } = await streamTurn(turnRequest);
|
|
23650
|
+
setIsThinking?.(false);
|
|
23651
|
+
if (turnText.trim()) lastTurnText = turnText;
|
|
23652
|
+
let toolText = turnText;
|
|
23653
|
+
if (turnNative.length && !/```(?:tool_code|TOOL_CODE)/.test(toolText)) {
|
|
23654
|
+
for (const raw of turnNative) {
|
|
23655
|
+
const tc = raw;
|
|
23656
|
+
const fnName = tc.function?.name ?? tc.name;
|
|
23657
|
+
if (!fnName) continue;
|
|
23658
|
+
const a = tc.function?.arguments ?? tc.arguments ?? {};
|
|
23659
|
+
toolText += `
|
|
23660
|
+
|
|
23661
|
+
\`\`\`tool_code
|
|
23662
|
+
${fnName}(${typeof a === "string" ? a : JSON.stringify(a ?? {})})
|
|
23663
|
+
\`\`\``;
|
|
23664
|
+
}
|
|
23665
|
+
}
|
|
23666
|
+
const chainMatches = toolText.match(/```(?:tool_code|TOOL_CODE)\s*\n([^`]+)\n```/gi);
|
|
23667
|
+
if (!chainMatches || !chainMatches.length) {
|
|
23668
|
+
finalText = turnText;
|
|
23669
|
+
break;
|
|
23670
|
+
}
|
|
23671
|
+
const roundOut = [];
|
|
23672
|
+
for (const m of chainMatches) {
|
|
23673
|
+
const code = m.replace(/```(?:tool_code|TOOL_CODE)\s*\n|\n```/gi, "").trim();
|
|
23674
|
+
const fm = code.match(/^(\w+)\(\s*(.*?)\s*\)$/);
|
|
23675
|
+
if (!fm) continue;
|
|
23676
|
+
const [, fnName, rawParams] = fm;
|
|
23677
|
+
let parsed = {};
|
|
23678
|
+
const rp = rawParams.trim();
|
|
23679
|
+
if (rp) {
|
|
23680
|
+
try {
|
|
23681
|
+
parsed = JSON.parse(rp.startsWith("{") ? rp : `{${rp}}`);
|
|
23682
|
+
} catch {
|
|
23683
|
+
parsed = {};
|
|
23684
|
+
}
|
|
23685
|
+
}
|
|
23686
|
+
try {
|
|
23687
|
+
roundOut.push(`## ${fnName}
|
|
23688
|
+
${await runChainedTool(fnName, parsed)}`);
|
|
23689
|
+
} catch (e) {
|
|
23690
|
+
roundOut.push(`## ${fnName}
|
|
23691
|
+
That step failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
23692
|
+
}
|
|
23693
|
+
}
|
|
23694
|
+
convo.push({ role: "assistant", content: stripToolBlocks(turnText) || "(using a tool)" });
|
|
23695
|
+
convo.push({
|
|
23696
|
+
role: "user",
|
|
23697
|
+
content: `Tool results:
|
|
23698
|
+
|
|
23699
|
+
${roundOut.join("\n\n")}
|
|
23700
|
+
|
|
23701
|
+
Now give your final answer to my original request, or call another tool if you still genuinely need to. Do NOT add a "Sources" list.`
|
|
23702
|
+
});
|
|
23703
|
+
}
|
|
23610
23704
|
setIsThinking?.(false);
|
|
23611
|
-
|
|
23612
|
-
|
|
23705
|
+
const answerText = finalText.trim() ? finalText : lastTurnText;
|
|
23706
|
+
if (answerText.trim() || inlineImageBlocks.length) {
|
|
23707
|
+
const cleanedSummary = answerText.replace(
|
|
23613
23708
|
/\n{1,}\s*(?:[*_#>\s]*)(?:sources?|references?|citations?|further reading)(?:\s*:)?\s*(?:[*_]*)\s*\n[\s\S]*$/i,
|
|
23614
23709
|
""
|
|
23615
23710
|
).trimEnd();
|