@burtson-labs/bandit-engine 2.0.71 → 2.0.73
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-W4HX45DE.mjs} +2 -2
- package/dist/{chunk-VKDU2OMI.mjs → chunk-E7GT3NR4.mjs} +2 -2
- package/dist/{chunk-CMBYMC3G.mjs → chunk-YBQRVTZF.mjs} +161 -37
- package/dist/chunk-YBQRVTZF.mjs.map +1 -0
- package/dist/index.js +160 -36
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2 -2
- package/dist/management/management.js +160 -36
- 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-W4HX45DE.mjs.map} +0 -0
- /package/dist/{chunk-VKDU2OMI.mjs.map → chunk-E7GT3NR4.mjs.map} +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
chat_default
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-YBQRVTZF.mjs";
|
|
4
4
|
import "./chunk-ONQMRE2G.mjs";
|
|
5
5
|
import "./chunk-U633CJBV.mjs";
|
|
6
6
|
import "./chunk-DHYP4K5O.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-W4HX45DE.mjs.map
|
|
@@ -9503,7 +9503,7 @@ var MCPToolsTabV2_default = MCPToolsTabV2;
|
|
|
9503
9503
|
|
|
9504
9504
|
// src/management/management.tsx
|
|
9505
9505
|
import { jsx as jsx13, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
9506
|
-
var preloadChatPage = () => import("./chat-
|
|
9506
|
+
var preloadChatPage = () => import("./chat-W4HX45DE.mjs");
|
|
9507
9507
|
var buildCapabilitiesUrl = (gatewayApiUrl) => {
|
|
9508
9508
|
const trimmed = gatewayApiUrl.replace(/\/$/, "");
|
|
9509
9509
|
if (trimmed.endsWith("/api")) {
|
|
@@ -10848,4 +10848,4 @@ export {
|
|
|
10848
10848
|
useGatewayMemory,
|
|
10849
10849
|
management_default
|
|
10850
10850
|
};
|
|
10851
|
-
//# sourceMappingURL=chunk-
|
|
10851
|
+
//# sourceMappingURL=chunk-E7GT3NR4.mjs.map
|
|
@@ -3341,6 +3341,7 @@ ${protocol}`;
|
|
|
3341
3341
|
let latestDisplayMessage = "";
|
|
3342
3342
|
let sawToolBlock = false;
|
|
3343
3343
|
const nativeToolCalls = [];
|
|
3344
|
+
let workingTimer = null;
|
|
3344
3345
|
const stripThinking = (text) => {
|
|
3345
3346
|
let result = text.replace(/<think>[\s\S]*?<\/think>/g, "");
|
|
3346
3347
|
const openIdx = result.indexOf("<think>");
|
|
@@ -3348,6 +3349,28 @@ ${protocol}`;
|
|
|
3348
3349
|
return result.trimStart();
|
|
3349
3350
|
};
|
|
3350
3351
|
const stripToolBlocks = (text) => text.replace(/```(?:tool_code|TOOL_CODE)\s*\n[\s\S]*?\n```/gi, "").trim();
|
|
3352
|
+
let workingLabel = "Working on it";
|
|
3353
|
+
let workingPreamble = "";
|
|
3354
|
+
const stopWorking = () => {
|
|
3355
|
+
if (workingTimer) {
|
|
3356
|
+
clearInterval(workingTimer);
|
|
3357
|
+
workingTimer = null;
|
|
3358
|
+
}
|
|
3359
|
+
};
|
|
3360
|
+
const startWorking = (label = "Working on it") => {
|
|
3361
|
+
workingLabel = label.replace(/[.…]+\s*$/, "").trim() || "Working on it";
|
|
3362
|
+
workingPreamble = stripToolBlocks(stripThinking(fullMessage)).trim();
|
|
3363
|
+
if (workingTimer) return;
|
|
3364
|
+
let dots = 0;
|
|
3365
|
+
const render = () => {
|
|
3366
|
+
dots = (dots + 1) % 4;
|
|
3367
|
+
setStreamBuffer(
|
|
3368
|
+
`${workingPreamble}${workingPreamble ? "\n\n" : ""}_${workingLabel}${".".repeat(dots)}_`
|
|
3369
|
+
);
|
|
3370
|
+
};
|
|
3371
|
+
render();
|
|
3372
|
+
workingTimer = setInterval(render, 450);
|
|
3373
|
+
};
|
|
3351
3374
|
const flushNow = () => {
|
|
3352
3375
|
clearFlushTimer();
|
|
3353
3376
|
if (!sawToolBlock) {
|
|
@@ -3383,6 +3406,7 @@ ${protocol}`;
|
|
|
3383
3406
|
nativeToolCalls.push(...data.message.tool_calls);
|
|
3384
3407
|
sawToolBlock = true;
|
|
3385
3408
|
clearFlushTimer();
|
|
3409
|
+
startWorking();
|
|
3386
3410
|
}
|
|
3387
3411
|
if (data.message.content) {
|
|
3388
3412
|
fullMessage += data.message.content;
|
|
@@ -3394,6 +3418,7 @@ ${protocol}`;
|
|
|
3394
3418
|
if (/```(?:tool_code|TOOL_CODE)/.test(visibleMessage)) {
|
|
3395
3419
|
sawToolBlock = true;
|
|
3396
3420
|
clearFlushTimer();
|
|
3421
|
+
startWorking();
|
|
3397
3422
|
}
|
|
3398
3423
|
latestDisplayMessage = visibleMessage;
|
|
3399
3424
|
if (!sawToolBlock) {
|
|
@@ -3402,6 +3427,7 @@ ${protocol}`;
|
|
|
3402
3427
|
},
|
|
3403
3428
|
error: (err) => {
|
|
3404
3429
|
debugLogger.error("Stream error:", err);
|
|
3430
|
+
stopWorking();
|
|
3405
3431
|
overrideComponentStatus("Idle");
|
|
3406
3432
|
setIsSubmitting(false);
|
|
3407
3433
|
setIsStreaming(false);
|
|
@@ -3486,6 +3512,7 @@ ${fn}(${argStr})
|
|
|
3486
3512
|
if (functionName === "ask_user" || functionName === "ask-user") {
|
|
3487
3513
|
enhancedMessage = enhancedMessage.replace(match, "");
|
|
3488
3514
|
clearFlushTimer();
|
|
3515
|
+
stopWorking();
|
|
3489
3516
|
const askPreamble = stripToolBlocks(fullMessage).trim();
|
|
3490
3517
|
setStreamBuffer(askPreamble || "_Waiting for your answer\u2026_");
|
|
3491
3518
|
const questions = parseAskUserQuestions(
|
|
@@ -3508,11 +3535,8 @@ A: ${(answers[q.id] || "").trim() || "(no answer)"}`).join("\n\n") : "The user d
|
|
|
3508
3535
|
const placeholderToken = `<<TOOL_LOADING_${functionName}_${Math.random().toString(36).slice(2)}>>`;
|
|
3509
3536
|
enhancedMessage = enhancedMessage.replace(match, placeholderToken);
|
|
3510
3537
|
clearFlushTimer();
|
|
3511
|
-
const toolStatus = functionName === "web_search" || functionName === "web-search" ? "Searching the web
|
|
3512
|
-
|
|
3513
|
-
setStreamBuffer(toolPreamble ? `${toolPreamble}
|
|
3514
|
-
|
|
3515
|
-
_${toolStatus}_` : `_${toolStatus}_`);
|
|
3538
|
+
const toolStatus = functionName === "web_search" || functionName === "web-search" ? "Searching the web" : functionName === "web_fetch" || functionName === "web-fetch" ? "Reading the page" : functionName === "image_generation" || functionName === "image-generation" ? "Generating the image" : functionName === "create_file" || functionName === "create-file" ? "Creating your file" : "Working on it";
|
|
3539
|
+
startWorking(toolStatus);
|
|
3516
3540
|
telemetryEvent("tool_loop:tool_execute", { name: functionName, params: parsedParams });
|
|
3517
3541
|
const result = await executeMCPTool({
|
|
3518
3542
|
toolName: functionName,
|
|
@@ -3626,71 +3650,170 @@ _This link is temporary and expires in about ${mins} minutes._`;
|
|
|
3626
3650
|
try {
|
|
3627
3651
|
const toolResultsText = summarizableResults.map((r) => `## ${r.name}
|
|
3628
3652
|
${r.output}`).join("\n\n");
|
|
3629
|
-
const
|
|
3630
|
-
|
|
3653
|
+
const MAX_CHAIN_ROUNDS = 4;
|
|
3654
|
+
const enabledToolsForChain = getEnabledMCPToolsForAI();
|
|
3655
|
+
const convo = [
|
|
3656
|
+
{ role: "system", content: enhancedSystemPrompt },
|
|
3631
3657
|
...contextMessages,
|
|
3632
3658
|
{ role: "user", content: question },
|
|
3633
|
-
{ role: "assistant", content: stripToolBlocks(fullMessage) || "Let me
|
|
3659
|
+
{ role: "assistant", content: stripToolBlocks(fullMessage) || "Let me work on that." },
|
|
3634
3660
|
{
|
|
3635
3661
|
role: "user",
|
|
3636
|
-
content: `
|
|
3662
|
+
content: `Here are the results of the tool(s) so far:
|
|
3637
3663
|
|
|
3638
3664
|
${toolResultsText}
|
|
3639
3665
|
|
|
3640
|
-
|
|
3666
|
+
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.`
|
|
3641
3667
|
}
|
|
3642
3668
|
];
|
|
3643
|
-
const
|
|
3644
|
-
model: modelName,
|
|
3645
|
-
messages: summaryMessages,
|
|
3646
|
-
stream: true,
|
|
3647
|
-
options: { num_predict: tokenLimit + 250 }
|
|
3648
|
-
};
|
|
3649
|
-
clearFlushTimer();
|
|
3650
|
-
setStreamBuffer("");
|
|
3651
|
-
setIsThinking?.(true);
|
|
3652
|
-
const summaryText = await new Promise((resolve) => {
|
|
3669
|
+
const streamTurn = (req) => new Promise((resolve) => {
|
|
3653
3670
|
let acc = "";
|
|
3671
|
+
const native = [];
|
|
3654
3672
|
let settled = false;
|
|
3655
3673
|
let timer;
|
|
3656
|
-
const
|
|
3674
|
+
const finish = (value) => {
|
|
3657
3675
|
if (settled) return;
|
|
3658
3676
|
settled = true;
|
|
3659
3677
|
if (timer) clearTimeout(timer);
|
|
3660
3678
|
resolve(value);
|
|
3661
3679
|
};
|
|
3662
|
-
const
|
|
3680
|
+
const sub2 = provider.chat(req).subscribe({
|
|
3663
3681
|
next: (data) => {
|
|
3682
|
+
if (Array.isArray(data?.message?.tool_calls) && data.message.tool_calls.length) {
|
|
3683
|
+
native.push(...data.message.tool_calls);
|
|
3684
|
+
}
|
|
3664
3685
|
if (data?.message?.content) {
|
|
3665
3686
|
acc += data.message.content;
|
|
3666
3687
|
const visible = stripThinking(acc);
|
|
3667
3688
|
latestDisplayMessage = visible;
|
|
3668
3689
|
lastPartialRef.current.text = visible;
|
|
3669
|
-
if (visible)
|
|
3690
|
+
if (visible) {
|
|
3691
|
+
stopWorking();
|
|
3692
|
+
setIsThinking?.(false);
|
|
3693
|
+
}
|
|
3670
3694
|
setStreamBuffer(visible);
|
|
3671
3695
|
}
|
|
3672
3696
|
},
|
|
3673
|
-
error: (
|
|
3674
|
-
|
|
3675
|
-
error: summaryErr instanceof Error ? summaryErr.message : String(summaryErr)
|
|
3676
|
-
});
|
|
3677
|
-
done("");
|
|
3678
|
-
},
|
|
3679
|
-
complete: () => done(stripThinking(acc).trim())
|
|
3697
|
+
error: () => finish({ text: stripThinking(acc).trim(), native }),
|
|
3698
|
+
complete: () => finish({ text: stripThinking(acc).trim(), native })
|
|
3680
3699
|
});
|
|
3681
|
-
currentSubRef.current =
|
|
3700
|
+
currentSubRef.current = sub2;
|
|
3682
3701
|
timer = setTimeout(() => {
|
|
3683
|
-
debugLogger.warn("Summarization pass timed out; using inline tool output");
|
|
3684
3702
|
try {
|
|
3685
|
-
|
|
3703
|
+
sub2.unsubscribe();
|
|
3686
3704
|
} catch {
|
|
3687
3705
|
}
|
|
3688
|
-
|
|
3706
|
+
finish({ text: stripThinking(acc).trim(), native });
|
|
3689
3707
|
}, 3e4);
|
|
3690
3708
|
});
|
|
3709
|
+
const runChainedTool = async (fn, params) => {
|
|
3710
|
+
if (fn === "ask_user" || fn === "ask-user") {
|
|
3711
|
+
const qs = parseAskUserQuestions(params.questions ?? params);
|
|
3712
|
+
if (!qs.length) return "ask_user failed: it needs a questions array.";
|
|
3713
|
+
const ans = await useAskUserStore.getState().ask(qs);
|
|
3714
|
+
return ans ? "The user answered:\n\n" + qs.map((q) => `Q: ${q.question}
|
|
3715
|
+
A: ${(ans[q.id] || "").trim() || "(no answer)"}`).join("\n\n") : "The user dismissed the question(s). Proceed with your best judgment.";
|
|
3716
|
+
}
|
|
3717
|
+
const status = fn === "create_file" || fn === "create-file" ? "Creating your file" : fn === "web_search" || fn === "web-search" ? "Searching the web" : fn === "web_fetch" || fn === "web-fetch" ? "Reading the page" : fn === "image_generation" || fn === "image-generation" ? "Generating the image" : "Working on it";
|
|
3718
|
+
startWorking(status);
|
|
3719
|
+
const result = await executeMCPTool({ toolName: fn, parameters: params });
|
|
3720
|
+
if (!result.success) return `That step failed: ${result.error || "unknown error"}.`;
|
|
3721
|
+
if (fn === "create_file" || fn === "create-file") {
|
|
3722
|
+
const f = result.data ?? {};
|
|
3723
|
+
if (f.url) {
|
|
3724
|
+
const mins = f.expiresInMinutes ?? 60;
|
|
3725
|
+
const name = f.filename || "your file";
|
|
3726
|
+
inlineImageBlocks.push(`\u{1F4C4} **[${name}](${f.url})** \u2014 ready to download.
|
|
3727
|
+
|
|
3728
|
+
_This link is temporary and expires in about ${mins} minutes._`);
|
|
3729
|
+
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.`;
|
|
3730
|
+
}
|
|
3731
|
+
return "The file was created.";
|
|
3732
|
+
}
|
|
3733
|
+
if (fn === "image_generation" || fn === "image-generation") {
|
|
3734
|
+
const img = result.data ?? {};
|
|
3735
|
+
if (img.imageUrl) {
|
|
3736
|
+
inlineImageBlocks.push(``);
|
|
3737
|
+
return "Image generated and shown to the user.";
|
|
3738
|
+
}
|
|
3739
|
+
}
|
|
3740
|
+
if (typeof result.data === "string") return result.data.slice(0, 2e3);
|
|
3741
|
+
if (result.data) return JSON.stringify(result.data).slice(0, 1500);
|
|
3742
|
+
return "Done.";
|
|
3743
|
+
};
|
|
3744
|
+
clearFlushTimer();
|
|
3745
|
+
let finalText = "";
|
|
3746
|
+
let lastTurnText = "";
|
|
3747
|
+
for (let round = 0; round < MAX_CHAIN_ROUNDS; round++) {
|
|
3748
|
+
stopWorking();
|
|
3749
|
+
setStreamBuffer("");
|
|
3750
|
+
setIsThinking?.(true);
|
|
3751
|
+
const turnRequest = {
|
|
3752
|
+
model: modelName,
|
|
3753
|
+
messages: convo,
|
|
3754
|
+
stream: true,
|
|
3755
|
+
tools: enabledToolsForChain.length ? enabledToolsForChain : void 0,
|
|
3756
|
+
options: { num_predict: tokenLimit + 250 }
|
|
3757
|
+
};
|
|
3758
|
+
const { text: turnText, native: turnNative } = await streamTurn(turnRequest);
|
|
3759
|
+
setIsThinking?.(false);
|
|
3760
|
+
if (turnText.trim()) lastTurnText = turnText;
|
|
3761
|
+
let toolText = turnText;
|
|
3762
|
+
if (turnNative.length && !/```(?:tool_code|TOOL_CODE)/.test(toolText)) {
|
|
3763
|
+
for (const raw of turnNative) {
|
|
3764
|
+
const tc = raw;
|
|
3765
|
+
const fnName = tc.function?.name ?? tc.name;
|
|
3766
|
+
if (!fnName) continue;
|
|
3767
|
+
const a = tc.function?.arguments ?? tc.arguments ?? {};
|
|
3768
|
+
toolText += `
|
|
3769
|
+
|
|
3770
|
+
\`\`\`tool_code
|
|
3771
|
+
${fnName}(${typeof a === "string" ? a : JSON.stringify(a ?? {})})
|
|
3772
|
+
\`\`\``;
|
|
3773
|
+
}
|
|
3774
|
+
}
|
|
3775
|
+
const chainMatches = toolText.match(/```(?:tool_code|TOOL_CODE)\s*\n([^`]+)\n```/gi);
|
|
3776
|
+
if (!chainMatches || !chainMatches.length) {
|
|
3777
|
+
finalText = turnText;
|
|
3778
|
+
break;
|
|
3779
|
+
}
|
|
3780
|
+
const roundOut = [];
|
|
3781
|
+
for (const m of chainMatches) {
|
|
3782
|
+
const code = m.replace(/```(?:tool_code|TOOL_CODE)\s*\n|\n```/gi, "").trim();
|
|
3783
|
+
const fm = code.match(/^(\w+)\(\s*(.*?)\s*\)$/);
|
|
3784
|
+
if (!fm) continue;
|
|
3785
|
+
const [, fnName, rawParams] = fm;
|
|
3786
|
+
let parsed = {};
|
|
3787
|
+
const rp = rawParams.trim();
|
|
3788
|
+
if (rp) {
|
|
3789
|
+
try {
|
|
3790
|
+
parsed = JSON.parse(rp.startsWith("{") ? rp : `{${rp}}`);
|
|
3791
|
+
} catch {
|
|
3792
|
+
parsed = {};
|
|
3793
|
+
}
|
|
3794
|
+
}
|
|
3795
|
+
try {
|
|
3796
|
+
roundOut.push(`## ${fnName}
|
|
3797
|
+
${await runChainedTool(fnName, parsed)}`);
|
|
3798
|
+
} catch (e) {
|
|
3799
|
+
roundOut.push(`## ${fnName}
|
|
3800
|
+
That step failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
3801
|
+
}
|
|
3802
|
+
}
|
|
3803
|
+
convo.push({ role: "assistant", content: stripToolBlocks(turnText) || "(using a tool)" });
|
|
3804
|
+
convo.push({
|
|
3805
|
+
role: "user",
|
|
3806
|
+
content: `Tool results:
|
|
3807
|
+
|
|
3808
|
+
${roundOut.join("\n\n")}
|
|
3809
|
+
|
|
3810
|
+
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.`
|
|
3811
|
+
});
|
|
3812
|
+
}
|
|
3691
3813
|
setIsThinking?.(false);
|
|
3692
|
-
|
|
3693
|
-
|
|
3814
|
+
const answerText = finalText.trim() ? finalText : lastTurnText;
|
|
3815
|
+
if (answerText.trim() || inlineImageBlocks.length) {
|
|
3816
|
+
const cleanedSummary = answerText.replace(
|
|
3694
3817
|
/\n{1,}\s*(?:[*_#>\s]*)(?:sources?|references?|citations?|further reading)(?:\s*:)?\s*(?:[*_]*)\s*\n[\s\S]*$/i,
|
|
3695
3818
|
""
|
|
3696
3819
|
).trimEnd();
|
|
@@ -3716,6 +3839,7 @@ ${inlineImageBlocks.join("\n\n")}` : "");
|
|
|
3716
3839
|
}
|
|
3717
3840
|
}
|
|
3718
3841
|
}
|
|
3842
|
+
stopWorking();
|
|
3719
3843
|
overrideComponentStatus("Idle");
|
|
3720
3844
|
setIsSubmitting(false);
|
|
3721
3845
|
setPreviousQuestion(question);
|
|
@@ -9954,4 +10078,4 @@ var chat_default = Chat;
|
|
|
9954
10078
|
export {
|
|
9955
10079
|
chat_default
|
|
9956
10080
|
};
|
|
9957
|
-
//# sourceMappingURL=chunk-
|
|
10081
|
+
//# sourceMappingURL=chunk-YBQRVTZF.mjs.map
|