fluxflow-cli 3.17.0 → 3.18.0
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/fluxflow.js +126 -42
- package/package.json +2 -2
package/dist/fluxflow.js
CHANGED
|
@@ -2570,7 +2570,7 @@ var init_build = __esm({
|
|
|
2570
2570
|
|
|
2571
2571
|
// src/utils/text.js
|
|
2572
2572
|
import os2 from "os";
|
|
2573
|
-
var flattenString, wrapText, formatTokens, truncatePath, parsePatchPairs, applyPatches, generateHighFidelityDiff, parseLineInfo, getSimilarity, alignChangeGroup, blocksCache, streamingBlocksCache, MAX_CACHE_SIZE, CHUNK_SIZE, indexBlockIntoMap, parseMessageToBlocks, TOOL_LABELS, REGEX_INITIAL_THINK, REGEX_INITIAL_TOOL, isInsideBacktick, REGEX_CLEAN_SIGNALS, REGEX_ARROWS_ALL, REGEX_TOOLS, bypassBacktick, cleanSignals, clearBlocksCache;
|
|
2573
|
+
var flattenString, wrapText, formatTokens, truncatePath, parsePatchPairs, buildEscapeFuzzyRegex, applyPatches, generateHighFidelityDiff, parseLineInfo, getSimilarity, alignChangeGroup, blocksCache, streamingBlocksCache, MAX_CACHE_SIZE, CHUNK_SIZE, indexBlockIntoMap, parseMessageToBlocks, TOOL_LABELS, REGEX_INITIAL_THINK, REGEX_INITIAL_TOOL, isInsideBacktick, REGEX_CLEAN_SIGNALS, REGEX_ARROWS_ALL, REGEX_TOOLS, bypassBacktick, cleanSignals, clearBlocksCache;
|
|
2574
2574
|
var init_text = __esm({
|
|
2575
2575
|
"src/utils/text.js"() {
|
|
2576
2576
|
init_paths();
|
|
@@ -2677,6 +2677,53 @@ var init_text = __esm({
|
|
|
2677
2677
|
}
|
|
2678
2678
|
return { patchPairs, allowMultiple };
|
|
2679
2679
|
};
|
|
2680
|
+
buildEscapeFuzzyRegex = (content_to_replace) => {
|
|
2681
|
+
if (!content_to_replace) return null;
|
|
2682
|
+
let pattern = "";
|
|
2683
|
+
let i = 0;
|
|
2684
|
+
const len = content_to_replace.length;
|
|
2685
|
+
while (i < len) {
|
|
2686
|
+
const char = content_to_replace[i];
|
|
2687
|
+
if (char === "\\") {
|
|
2688
|
+
while (i < len && content_to_replace[i] === "\\") {
|
|
2689
|
+
i++;
|
|
2690
|
+
}
|
|
2691
|
+
pattern += "\\\\*";
|
|
2692
|
+
} else if (char === "\n") {
|
|
2693
|
+
pattern += "(?:\\r?\\n|\\\\*n|\\\\*r|\\s*)";
|
|
2694
|
+
i++;
|
|
2695
|
+
} else if (char === "\r") {
|
|
2696
|
+
pattern += "(?:\\r|\\\\*r)?";
|
|
2697
|
+
i++;
|
|
2698
|
+
} else if (char === " ") {
|
|
2699
|
+
pattern += "(?:\\t|\\\\*t|\\s*)";
|
|
2700
|
+
i++;
|
|
2701
|
+
} else if (char === '"' || char === "'" || char === "`") {
|
|
2702
|
+
if (!pattern.endsWith("\\\\*")) {
|
|
2703
|
+
pattern += "\\\\*";
|
|
2704
|
+
}
|
|
2705
|
+
pattern += char;
|
|
2706
|
+
i++;
|
|
2707
|
+
} else if (/[.*+?^${}()|[\]]/.test(char)) {
|
|
2708
|
+
pattern += "\\" + char;
|
|
2709
|
+
i++;
|
|
2710
|
+
} else if (/\s/.test(char)) {
|
|
2711
|
+
while (i < len && /\s/.test(content_to_replace[i]) && content_to_replace[i] !== "\n" && content_to_replace[i] !== "\r" && content_to_replace[i] !== " ") {
|
|
2712
|
+
i++;
|
|
2713
|
+
}
|
|
2714
|
+
pattern += "\\s*";
|
|
2715
|
+
} else {
|
|
2716
|
+
pattern += char;
|
|
2717
|
+
i++;
|
|
2718
|
+
}
|
|
2719
|
+
}
|
|
2720
|
+
if (!pattern) return null;
|
|
2721
|
+
try {
|
|
2722
|
+
return new RegExp(pattern, "g");
|
|
2723
|
+
} catch (e) {
|
|
2724
|
+
return null;
|
|
2725
|
+
}
|
|
2726
|
+
};
|
|
2680
2727
|
applyPatches = (content, patches, options = {}) => {
|
|
2681
2728
|
const allowMultiple = typeof options === "boolean" ? options : !!(options && options.allowMultiple);
|
|
2682
2729
|
let currentFileContent = content.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
@@ -2713,8 +2760,40 @@ var init_text = __esm({
|
|
|
2713
2760
|
const patchMatches = [];
|
|
2714
2761
|
for (let i = 0; i < patches.length; i++) {
|
|
2715
2762
|
const pair = patches[i];
|
|
2716
|
-
const
|
|
2763
|
+
const rawReplace = (pair.replace || "").trim();
|
|
2717
2764
|
const content_to_add = strip(pair.new || "");
|
|
2765
|
+
if (rawReplace.startsWith("^LINE:") && rawReplace.endsWith("$")) {
|
|
2766
|
+
const body = rawReplace.slice(6, -1).trim();
|
|
2767
|
+
const parts = body.split("..");
|
|
2768
|
+
const startLine = parseInt(parts[0]);
|
|
2769
|
+
const endLine = parts[1] !== void 0 ? parseInt(parts[1]) : startLine;
|
|
2770
|
+
if (!isNaN(startLine) && !isNaN(endLine)) {
|
|
2771
|
+
const fileLines = currentFileContent.split("\n");
|
|
2772
|
+
if (startLine < 1 || startLine > fileLines.length || endLine < startLine || endLine > fileLines.length) {
|
|
2773
|
+
patchMatches.push({
|
|
2774
|
+
index: i,
|
|
2775
|
+
success: false,
|
|
2776
|
+
error: `Block ${i + 1}: Line range ^LINE:${startLine}..${endLine}$ out of bounds (file has ${fileLines.length} lines).`
|
|
2777
|
+
});
|
|
2778
|
+
continue;
|
|
2779
|
+
}
|
|
2780
|
+
const slicedLines = fileLines.slice(startLine - 1, endLine);
|
|
2781
|
+
const firstMatchContent = slicedLines.join("\n");
|
|
2782
|
+
let startPos = 0;
|
|
2783
|
+
for (let k = 0; k < startLine - 1; k++) {
|
|
2784
|
+
startPos += fileLines[k].length + 1;
|
|
2785
|
+
}
|
|
2786
|
+
patchMatches.push({
|
|
2787
|
+
index: i,
|
|
2788
|
+
success: true,
|
|
2789
|
+
startPos,
|
|
2790
|
+
firstMatchContent,
|
|
2791
|
+
content_to_add
|
|
2792
|
+
});
|
|
2793
|
+
continue;
|
|
2794
|
+
}
|
|
2795
|
+
}
|
|
2796
|
+
const content_to_replace = strip(pair.replace || "");
|
|
2718
2797
|
if (content_to_replace === "" && content_to_add === "") {
|
|
2719
2798
|
patchMatches.push({ index: i, success: false, error: `Block ${i + 1}: Empty replace and add content.` });
|
|
2720
2799
|
continue;
|
|
@@ -2736,7 +2815,13 @@ var init_text = __esm({
|
|
|
2736
2815
|
matchRegex = new RegExp(exactPattern, "g");
|
|
2737
2816
|
}
|
|
2738
2817
|
}
|
|
2739
|
-
|
|
2818
|
+
let matches = [...currentFileContent.matchAll(matchRegex)];
|
|
2819
|
+
if (matches.length === 0 && content_to_replace !== "") {
|
|
2820
|
+
const escapeFuzzyRegex = buildEscapeFuzzyRegex(content_to_replace);
|
|
2821
|
+
if (escapeFuzzyRegex) {
|
|
2822
|
+
matches = [...currentFileContent.matchAll(escapeFuzzyRegex)];
|
|
2823
|
+
}
|
|
2824
|
+
}
|
|
2740
2825
|
if (matches.length === 0) {
|
|
2741
2826
|
patchMatches.push({ index: i, success: false, error: `Block ${i + 1}: Could not find match.` });
|
|
2742
2827
|
continue;
|
|
@@ -6845,21 +6930,18 @@ var init_main_tools = __esm({
|
|
|
6845
6930
|
}
|
|
6846
6931
|
return `
|
|
6847
6932
|
-- TOOL DEFINITIONS --
|
|
6848
|
-
Tool calls: ONLY use [tool:functions.ToolName(arg1="value1")]
|
|
6933
|
+
Tool calls: ONLY use [tool:functions.ToolName(arg1="value1")] IN NEW LINE
|
|
6849
6934
|
**NO OTHER SYNTAX/MARKERS/WRAPPER/BOUNDARY ALLOWED**
|
|
6850
6935
|
|
|
6851
6936
|
**TOOL CALLS POLICY:**
|
|
6852
6937
|
- MAX 4 TOOL CALLS/TURN${mode === "Flux" ? " (Todo: 4+, Run: max 1 or 2 consecutive)" : ""}
|
|
6853
|
-
${mode === "Flux" ? `-
|
|
6854
|
-
- Double-escape literal sequences (eg. \\\\n)
|
|
6855
|
-
- Use real newlines for code formatting
|
|
6938
|
+
${mode === "Flux" ? `- JSON ESCAPE ALL LITERAL ESCAPE SEQUENCES IN TOOL ARGUMENTS
|
|
6856
6939
|
- SAME file, MULTIPLE edits? ONE PatchFile (\u226415 blocks) \u2190 PRIORITY
|
|
6857
6940
|
- Tool denied? Ask for guidance \u2190 MANDATORY
|
|
6858
6941
|
- Need text or huge files? SearchKeyword > Full Read
|
|
6859
|
-
- Update Todos from realtime progress each turn
|
|
6860
6942
|
` : ""}
|
|
6861
6943
|
- COMMUNICATION WITH USER -
|
|
6862
|
-
- [tool:functions.Ask(question="...", optionA="
|
|
6944
|
+
- [tool:functions.Ask(question="...", optionA="title::description", ...MAX4)]. Ambiguity: MUST for path divergence, security risk. Ask, don't finish/guess. Suggest best options; no preferences. Keep titles short
|
|
6863
6945
|
|
|
6864
6946
|
- WEB TOOLS -
|
|
6865
6947
|
- [tool:functions.WebSearch(query="...", aiMode="bool optional, default: false", limit="integer 3-10, aiMode: exclude")]. Usage: unknown info/docs. aiMode: LLM search
|
|
@@ -6868,7 +6950,7 @@ ${mode === "Flux" ? `- Escape quotes: \\" for code strings
|
|
|
6868
6950
|
${mode === "Flux" ? `- WORKSPACE TOOLS (path = relative; FIRST ARGUMENT, path separator: '/') -
|
|
6869
6951
|
- [tool:functions.ReadFile(path="...", startLine="integer", endLine="integer")]. ${aiProvider !== "Google" ? `${isMultiModal ? `Supports images/docs` : ""}` : `Supports images/docs`}
|
|
6870
6952
|
- [tool:functions.ReadFolder(path="...", recurse="integer 1-3 optional, default: 1")]. DIR Contents + File Size. Minimize recursion
|
|
6871
|
-
- [tool:functions.PatchFile(path="...", allowMultiple="bool optional, default: false", replaceContent1="
|
|
6953
|
+
- [tool:functions.PatchFile(path="...", allowMultiple="bool optional, default: false", replaceContent1="string OR ^LINE:start..end$", newContent1="...", ...MAX15)]. TARGET MINIMAL DIFF. replaceContent accepts exact string OR "^LINE:start..end$" to target line ranges. Multi-blocks supported. Verify diffs
|
|
6872
6954
|
- [tool:functions.WriteFile(path="...", content="...")]. Creates/Overwrites. File Exist? PatchFile > WriteFile
|
|
6873
6955
|
- [tool:functions.SearchKeyword(keyword="...", path="optional, dir/file/glob/regex", fuzzy="bool optional, default: false", regex="bool optional, default: auto")]. path scopes search. Find definitions, logic, relevant code
|
|
6874
6956
|
- [tool:functions.Run(command="...")]. Runs ${osDetected === "Windows" ? isPsAvailable() ? `POWERSHELL` : `WINDOWS CMD` : `BASH`} command. Destructive/Irreversible ops \u2192 Ask user
|
|
@@ -8623,8 +8705,7 @@ ${projectContextBlock}${isMemoryEnabled ? `
|
|
|
8623
8705
|
-- CHAT FORMATTING --
|
|
8624
8706
|
- GFM Markdown ONLY
|
|
8625
8707
|
- Same Language as User Query
|
|
8626
|
-
-
|
|
8627
|
-
- On completion: summarize changes (why) + edited files${mode === "Flux" ? "" : "\n- Use Kaomojis HEAVILY"}
|
|
8708
|
+
- Finish all chatting before tool calls${mode === "Flux" ? "" : "\n- Use Kaomojis HEAVILY"}
|
|
8628
8709
|
=== END SYSTEM PROMPT ===
|
|
8629
8710
|
|
|
8630
8711
|
${nameStr}${nicknameStr}${userInstrStr}${userMemoriesStr}`.trim();
|
|
@@ -9085,8 +9166,14 @@ var init_history = __esm({
|
|
|
9085
9166
|
const datePart = parts[0];
|
|
9086
9167
|
const timePart = parts[1] || "";
|
|
9087
9168
|
const ampm = parts[2] || "";
|
|
9088
|
-
const dateNums = datePart.split(/[
|
|
9169
|
+
const dateNums = datePart.split(/[-\/.]/).map(Number);
|
|
9089
9170
|
if (dateNums.length !== 3) return null;
|
|
9171
|
+
let locale = "en";
|
|
9172
|
+
try {
|
|
9173
|
+
locale = Intl.DateTimeFormat().resolvedOptions().locale || "en";
|
|
9174
|
+
} catch {
|
|
9175
|
+
}
|
|
9176
|
+
const isDayFirst = !/^en[-_]?us$|^en$/.test(locale?.toLowerCase());
|
|
9090
9177
|
let year, month, day;
|
|
9091
9178
|
if (dateNums[0] > 1e3) {
|
|
9092
9179
|
year = dateNums[0];
|
|
@@ -9101,12 +9188,18 @@ var init_history = __esm({
|
|
|
9101
9188
|
day = dateNums[1];
|
|
9102
9189
|
month = dateNums[0];
|
|
9103
9190
|
} else {
|
|
9104
|
-
|
|
9105
|
-
|
|
9191
|
+
if (isDayFirst) {
|
|
9192
|
+
day = dateNums[0];
|
|
9193
|
+
month = dateNums[1];
|
|
9194
|
+
} else {
|
|
9195
|
+
month = dateNums[0];
|
|
9196
|
+
day = dateNums[1];
|
|
9197
|
+
}
|
|
9106
9198
|
}
|
|
9107
9199
|
} else {
|
|
9108
9200
|
return null;
|
|
9109
9201
|
}
|
|
9202
|
+
if (month < 1 || month > 12 || day < 1 || day > 31) return null;
|
|
9110
9203
|
let hours = 0, minutes = 0, seconds = 0;
|
|
9111
9204
|
if (timePart) {
|
|
9112
9205
|
const timeNums = timePart.split(":").map(Number);
|
|
@@ -9151,16 +9244,19 @@ var init_history = __esm({
|
|
|
9151
9244
|
const threshold = 7 * 24 * 60 * 60 * 1e3;
|
|
9152
9245
|
const now = Date.now();
|
|
9153
9246
|
const keptEntries = [];
|
|
9154
|
-
const timestampRegex = /(\d{1,4}[
|
|
9247
|
+
const timestampRegex = /(\d{1,4}[-\/.]\d{1,4}[-\/.]\d{1,4}(?:,\s*|\s+)?(?:\d{1,2}:\d{2}:\d{2}(?:\s*[aApP][mM])?)?)/;
|
|
9155
9248
|
for (const entry of entries) {
|
|
9156
|
-
const
|
|
9157
|
-
|
|
9158
|
-
|
|
9159
|
-
|
|
9160
|
-
|
|
9161
|
-
|
|
9249
|
+
const isLogEntry = entryStartRegex.test(entry.header);
|
|
9250
|
+
if (isLogEntry) {
|
|
9251
|
+
const headerMatch = entry.header.match(timestampRegex);
|
|
9252
|
+
if (headerMatch) {
|
|
9253
|
+
const timeMs = parseCustomDate(headerMatch[1]);
|
|
9254
|
+
if (timeMs && now - timeMs > threshold) {
|
|
9255
|
+
continue;
|
|
9256
|
+
}
|
|
9162
9257
|
}
|
|
9163
9258
|
}
|
|
9259
|
+
const entryText = entry.header + (entry.body.length > 0 ? "\n" + entry.body.join("\n") : "");
|
|
9164
9260
|
keptEntries.push(entryText);
|
|
9165
9261
|
}
|
|
9166
9262
|
const finalContent = keptEntries.join("\n").trim();
|
|
@@ -12619,7 +12715,7 @@ var init_invoke = __esm({
|
|
|
12619
12715
|
const subagentContext = {
|
|
12620
12716
|
...context,
|
|
12621
12717
|
taskId,
|
|
12622
|
-
onAskMain: async (questionText
|
|
12718
|
+
onAskMain: async (questionText) => {
|
|
12623
12719
|
const questionId = `q-${Date.now()}-${Math.floor(Math.random() * 1e3)}`;
|
|
12624
12720
|
let questionResolver = null;
|
|
12625
12721
|
const qPromise = new Promise((resolve) => {
|
|
@@ -12628,7 +12724,6 @@ var init_invoke = __esm({
|
|
|
12628
12724
|
const qEntry = {
|
|
12629
12725
|
id: questionId,
|
|
12630
12726
|
question: questionText,
|
|
12631
|
-
options: optionsObj,
|
|
12632
12727
|
answered: false,
|
|
12633
12728
|
answer: null,
|
|
12634
12729
|
askedAt: Date.now(),
|
|
@@ -12782,7 +12877,7 @@ var init_getProgress = __esm({
|
|
|
12782
12877
|
if (task.status === "running" || task.status === "waiting") {
|
|
12783
12878
|
if (task.currentTool) output += `Current Tool: ${task.currentTool}
|
|
12784
12879
|
`;
|
|
12785
|
-
if (task.wps > 0) output += `
|
|
12880
|
+
if (task.wps > 0) output += `TPS: ${task.wps}
|
|
12786
12881
|
`;
|
|
12787
12882
|
}
|
|
12788
12883
|
if (task.questions && task.questions.length > 0) {
|
|
@@ -12794,10 +12889,6 @@ var init_getProgress = __esm({
|
|
|
12794
12889
|
pending.forEach((q) => {
|
|
12795
12890
|
output += `"${q.question}"
|
|
12796
12891
|
`;
|
|
12797
|
-
if (q.options && Object.keys(q.options).length > 0) {
|
|
12798
|
-
output += `Options: ${JSON.stringify(q.options)}
|
|
12799
|
-
`;
|
|
12800
|
-
}
|
|
12801
12892
|
});
|
|
12802
12893
|
output += `Respond using tool: [tool:functions.Answer(id="${task.id}", answer="...")]
|
|
12803
12894
|
|
|
@@ -18546,20 +18637,16 @@ TO ACCESS TOOLS **STRICTLY USE THE EXACT FORMAT IN CHAT OUTPUT:** [tool:function
|
|
|
18546
18637
|
**NO OTHER SYNTAX/MARKERS/WRAPPER/BOUNDARY ALLOWED**
|
|
18547
18638
|
|
|
18548
18639
|
TOOL POLICY:
|
|
18549
|
-
-
|
|
18550
|
-
- Double-escape literal sequences (eg. \\\\n)
|
|
18551
|
-
- Use real newlines for code formatting
|
|
18640
|
+
- JSON ESCAPE ALL LITERAL ESCAPE SEQUENCES IN TOOL ARGUMENTS
|
|
18552
18641
|
- SAME file, MULTIPLE edits? ONE PatchFile (\u226415 blocks) \u2190 PRIORITY
|
|
18553
|
-
- Tool denied? Ask for guidance \u2190 MANDATORY
|
|
18554
18642
|
- Need text or huge files? SearchKeyword > Full Read
|
|
18555
|
-
- Update Todos from realtime progress each turn
|
|
18556
18643
|
- Restricted Shell Access, No Deletion
|
|
18557
18644
|
- ONLY valid tools and syntax defined below are allowed
|
|
18558
18645
|
|
|
18559
18646
|
**PROVIDED TOOLS**
|
|
18560
18647
|
-- Communication Tools --
|
|
18561
|
-
- [tool:functions.Ask(question="...", optionA="
|
|
18562
|
-
${isAsync ? `- [tool:functions.AskMain(question="..."
|
|
18648
|
+
- [tool:functions.Ask(question="...", optionA="title::description", ...MAX4)]. Communicate with USER. Ambiguity: MUST for path divergence, security risk. Ask, don't finish/guess. Suggest best options; no preferences. Keep titles short
|
|
18649
|
+
${isAsync ? `- [tool:functions.AskMain(question="...")]. Communicate with PARENT/MAIN AGENT. When clarification/decision is needed for a task` : ""}
|
|
18563
18650
|
|
|
18564
18651
|
-- Web Tools --
|
|
18565
18652
|
- [tool:functions.WebSearch(query="...", aiMode="bool optional, default: false", limit="integer 3-10, aiMode: exclude")]. Usage: unknown info/docs. aiMode: LLM search
|
|
@@ -18569,7 +18656,7 @@ ${isAsync ? `- [tool:functions.AskMain(question="...", optionA="option::descript
|
|
|
18569
18656
|
- [tool:functions.SearchKeyword(keyword="...", path="optional, dir/file/glob/regex", fuzzy="bool optional, default: false", regex="bool optional, default: auto")]. path scopes search. Find definitions, logic, relevant code
|
|
18570
18657
|
- [tool:functions.ReadFolder(path="...", recurse="integer 1-3 optional, default: 1")]. DIR Contents + File Size. Minimize recursion
|
|
18571
18658
|
- [tool:functions.ReadFile(path="...", startLine="integer", endLine="integer")]. View files
|
|
18572
|
-
- [tool:functions.PatchFile(path="...", allowMultiple="bool optional, default: false", replaceContent1="
|
|
18659
|
+
- [tool:functions.PatchFile(path="...", allowMultiple="bool optional, default: false", replaceContent1="string OR ^LINE:start..end$", newContent1="...", ...MAX15)]. TARGET MINIMAL DIFF. replaceContent accepts exact string OR "^LINE:start..end$" to target line ranges. Multi-blocks supported. Verify diffs
|
|
18573
18660
|
- [tool:functions.WriteFile(path="...", content="...")]. Creates/Overwrites. File Exist? PatchFile > WriteFile. VERIFY IMPORTS
|
|
18574
18661
|
- [tool:functions.Run(command="...")]. Runs ${osDetected === "Windows" ? isPsAvailable() ? `WINDOWS POWERSHELL` : `WINDOWS CMD` : `BASH`} command. Destructive/Irreversible ops \u2192 Ask user`.trim();
|
|
18575
18662
|
const systemInstructionSubAgent = `=== START SYSTEM PROMPT ===
|
|
@@ -18611,7 +18698,7 @@ Current Time: ${time}
|
|
|
18611
18698
|
role: m.role === "user" ? "user" : "model",
|
|
18612
18699
|
parts: [{ text: m.text }]
|
|
18613
18700
|
}));
|
|
18614
|
-
if (logCallback) logCallback(`[Subagent Turn ${turn + 1}]
|
|
18701
|
+
if (logCallback) logCallback(`[Subagent Turn ${turn + 1}]...`);
|
|
18615
18702
|
const response = await generateSimpleContent(mergedSettings, targetModel, contents, systemInstructionSubAgent, "Fast");
|
|
18616
18703
|
const responseText = response.text || "";
|
|
18617
18704
|
const cleanResponse = responseText.replace(/(?:<think>|\[think\])[\s\S]*?(?:<\/think>|\[\/think\])/gi, "").trim();
|
|
@@ -18646,21 +18733,18 @@ ${cleanResponse}
|
|
|
18646
18733
|
if (processedAskMainInTurn) continue;
|
|
18647
18734
|
processedAskMainInTurn = true;
|
|
18648
18735
|
let questionText = "";
|
|
18649
|
-
let optionsObj = {};
|
|
18650
18736
|
if (askMainCalls.length === 1) {
|
|
18651
18737
|
const pArgs = parseArgs(askMainCalls[0].args);
|
|
18652
18738
|
questionText = pArgs.question || askMainCalls[0].args;
|
|
18653
|
-
optionsObj = pArgs;
|
|
18654
18739
|
} else {
|
|
18655
18740
|
questionText = askMainCalls.map((tc, idx) => {
|
|
18656
18741
|
const pArgs = parseArgs(tc.args);
|
|
18657
18742
|
return `Q${idx + 1}: ${pArgs.question || tc.args}`;
|
|
18658
18743
|
}).join("\n");
|
|
18659
|
-
optionsObj = {};
|
|
18660
18744
|
}
|
|
18661
18745
|
if (settings.onAskMain) {
|
|
18662
18746
|
if (logCallback) logCallback(`[Executing Tool] AskMain("${questionText}")...`);
|
|
18663
|
-
const answer = await settings.onAskMain(questionText
|
|
18747
|
+
const answer = await settings.onAskMain(questionText);
|
|
18664
18748
|
if (logCallback) logCallback(`[Tool Result]
|
|
18665
18749
|
Answer from Main Agent: ${answer}
|
|
18666
18750
|
`);
|