fluxflow-cli 3.16.6 → 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 +570 -140
- package/model_config.json +3 -3
- 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, REGEX_CLEAN_SIGNALS, REGEX_ARROWS_ALL, REGEX_TOOLS, 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;
|
|
@@ -3345,12 +3430,20 @@ var init_text = __esm({
|
|
|
3345
3430
|
};
|
|
3346
3431
|
REGEX_INITIAL_THINK = /<\/think>(\r?\n){2}/gi;
|
|
3347
3432
|
REGEX_INITIAL_TOOL = /(\r?\n){2}(?=\[?(?:tool:functions|tool\.functions|agent:generalist|agent\.generalist|\s*turn\s*:))/gi;
|
|
3433
|
+
isInsideBacktick = (str, idx) => {
|
|
3434
|
+
let inCode = false;
|
|
3435
|
+
for (let i = 0; i < idx; i++) {
|
|
3436
|
+
if (str[i] === "`") inCode = !inCode;
|
|
3437
|
+
}
|
|
3438
|
+
return inCode;
|
|
3439
|
+
};
|
|
3348
3440
|
REGEX_CLEAN_SIGNALS = /\[SYSTEM\][\s\S]*?\[\/SYSTEM\]|<(think|thought)>[\s\S]*?(?:<\/(think|thought)>|$)|\[ANSWER\][\s\S]*?(?:\[\/ANSWER\]|$)|\[TOOL RESULT\]:?\s*|^\s*(SUCCESS|ERROR):.*(\r?\n)?|\[\s*turn\s*:\s*(continue|finish)\s*\]|\[\[END\]\]|\[\s*turn\s*:?.*?$|\n\s*turn\s*:?.*?$|\[\s*$|\n\nResponded on .*|\n\n\[Prompted on: .*\]|@\[TerminalName:.*?, ProcessId:.*?\]/gmi;
|
|
3349
3441
|
REGEX_ARROWS_ALL = /(\$?\\?\/?\\rightarrow\$?|\$\\rightarrow\$)|(\$?\\?\/?\\leftarrow\$?|\$\\leftarrow\$)|(\$?\\?\/?\\uparrow\$?|\$\\uparrow\$)|(\$?\\?\/?\\downarrow\$?|\$\\downarrow\$)|(\$?\\?\/?\\leftrightarrow\$?|\$\\leftrightarrow\$)/gi;
|
|
3350
3442
|
REGEX_TOOLS = /\b(write_file|update_file|read_folder|view_file|exec_command|web_search|web_scrape|search_keyword|write_pdf|write_docx|generate_image)\b/gi;
|
|
3443
|
+
bypassBacktick = false;
|
|
3351
3444
|
cleanSignals = (text) => {
|
|
3352
3445
|
if (!text) return text;
|
|
3353
|
-
let result = text.replace(REGEX_INITIAL_THINK, "</think>").replace(REGEX_INITIAL_TOOL, "");
|
|
3446
|
+
let result = text.replace(REGEX_INITIAL_THINK, "</think>").replace(REGEX_INITIAL_TOOL, (match, _nl, offset, str) => !bypassBacktick && isInsideBacktick(str, offset) ? match : "");
|
|
3354
3447
|
const trigger = "tool:functions.";
|
|
3355
3448
|
const subagentTrigger = "agent:generalist.";
|
|
3356
3449
|
if (result.toLowerCase().includes(trigger) || result.toLowerCase().includes(subagentTrigger)) {
|
|
@@ -3365,6 +3458,35 @@ var init_text = __esm({
|
|
|
3365
3458
|
triggerIdxToUse = subagentIdx;
|
|
3366
3459
|
}
|
|
3367
3460
|
if (triggerIdxToUse === -1) break;
|
|
3461
|
+
if (!bypassBacktick && isInsideBacktick(result, triggerIdxToUse)) {
|
|
3462
|
+
const searchFrom = triggerIdxToUse + currentTrigger.length;
|
|
3463
|
+
const nextTool = lowerResult.indexOf(trigger, searchFrom);
|
|
3464
|
+
const nextAgent = lowerResult.indexOf(subagentTrigger, searchFrom);
|
|
3465
|
+
if (nextTool === -1 && nextAgent === -1) break;
|
|
3466
|
+
let safeIdx = -1;
|
|
3467
|
+
let searchPos = 0;
|
|
3468
|
+
while (true) {
|
|
3469
|
+
const tIdx = lowerResult.indexOf(trigger, searchPos);
|
|
3470
|
+
const aIdx = lowerResult.indexOf(subagentTrigger, searchPos);
|
|
3471
|
+
let candidate = -1;
|
|
3472
|
+
let candidateTrigger = trigger;
|
|
3473
|
+
if (tIdx === -1 && aIdx === -1) break;
|
|
3474
|
+
if (tIdx === -1 || aIdx !== -1 && aIdx < tIdx) {
|
|
3475
|
+
candidate = aIdx;
|
|
3476
|
+
candidateTrigger = subagentTrigger;
|
|
3477
|
+
} else {
|
|
3478
|
+
candidate = tIdx;
|
|
3479
|
+
}
|
|
3480
|
+
if (!isInsideBacktick(result, candidate)) {
|
|
3481
|
+
safeIdx = candidate;
|
|
3482
|
+
currentTrigger = candidateTrigger;
|
|
3483
|
+
break;
|
|
3484
|
+
}
|
|
3485
|
+
searchPos = candidate + candidateTrigger.length;
|
|
3486
|
+
}
|
|
3487
|
+
if (safeIdx === -1) break;
|
|
3488
|
+
triggerIdxToUse = safeIdx;
|
|
3489
|
+
}
|
|
3368
3490
|
let startIdx = triggerIdxToUse;
|
|
3369
3491
|
let hasOuterBracket = false;
|
|
3370
3492
|
let k = triggerIdxToUse - 1;
|
|
@@ -6808,21 +6930,18 @@ var init_main_tools = __esm({
|
|
|
6808
6930
|
}
|
|
6809
6931
|
return `
|
|
6810
6932
|
-- TOOL DEFINITIONS --
|
|
6811
|
-
Tool calls: ONLY use [tool:functions.ToolName(
|
|
6812
|
-
**NO OTHER SYNTAX/MARKERS/BOUNDARY ALLOWED**
|
|
6933
|
+
Tool calls: ONLY use [tool:functions.ToolName(arg1="value1")] IN NEW LINE
|
|
6934
|
+
**NO OTHER SYNTAX/MARKERS/WRAPPER/BOUNDARY ALLOWED**
|
|
6813
6935
|
|
|
6814
6936
|
**TOOL CALLS POLICY:**
|
|
6815
6937
|
- MAX 4 TOOL CALLS/TURN${mode === "Flux" ? " (Todo: 4+, Run: max 1 or 2 consecutive)" : ""}
|
|
6816
|
-
${mode === "Flux" ? `-
|
|
6817
|
-
- Double-escape literal sequences (eg. \\\\n)
|
|
6818
|
-
- Use real newlines for code formatting
|
|
6938
|
+
${mode === "Flux" ? `- JSON ESCAPE ALL LITERAL ESCAPE SEQUENCES IN TOOL ARGUMENTS
|
|
6819
6939
|
- SAME file, MULTIPLE edits? ONE PatchFile (\u226415 blocks) \u2190 PRIORITY
|
|
6820
6940
|
- Tool denied? Ask for guidance \u2190 MANDATORY
|
|
6821
6941
|
- Need text or huge files? SearchKeyword > Full Read
|
|
6822
|
-
- Update Todos from realtime progress each turn
|
|
6823
6942
|
` : ""}
|
|
6824
6943
|
- COMMUNICATION WITH USER -
|
|
6825
|
-
- [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
|
|
6826
6945
|
|
|
6827
6946
|
- WEB TOOLS -
|
|
6828
6947
|
- [tool:functions.WebSearch(query="...", aiMode="bool optional, default: false", limit="integer 3-10, aiMode: exclude")]. Usage: unknown info/docs. aiMode: LLM search
|
|
@@ -6830,25 +6949,26 @@ ${mode === "Flux" ? `- Escape quotes: \\" for code strings
|
|
|
6830
6949
|
|
|
6831
6950
|
${mode === "Flux" ? `- WORKSPACE TOOLS (path = relative; FIRST ARGUMENT, path separator: '/') -
|
|
6832
6951
|
- [tool:functions.ReadFile(path="...", startLine="integer", endLine="integer")]. ${aiProvider !== "Google" ? `${isMultiModal ? `Supports images/docs` : ""}` : `Supports images/docs`}
|
|
6833
|
-
- [tool:functions.ReadFolder(path="...", recurse="integer 1-3 optional, default: 1")]. DIR Contents + File Size.
|
|
6834
|
-
- [tool:functions.PatchFile(path="...", allowMultiple="bool optional, default: false", replaceContent1="
|
|
6952
|
+
- [tool:functions.ReadFolder(path="...", recurse="integer 1-3 optional, default: 1")]. DIR Contents + File Size. Minimize recursion
|
|
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
|
|
6835
6954
|
- [tool:functions.WriteFile(path="...", content="...")]. Creates/Overwrites. File Exist? PatchFile > WriteFile
|
|
6836
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
|
|
6837
6956
|
- [tool:functions.Run(command="...")]. Runs ${osDetected === "Windows" ? isPsAvailable() ? `POWERSHELL` : `WINDOWS CMD` : `BASH`} command. Destructive/Irreversible ops \u2192 Ask user
|
|
6838
|
-
- [tool:functions.Todo(method="create/append/get", tasks=[ARRAY OF STRINGS], markDone=[ARRAY OF TASKS])]. Task list, no Markdown in arrays. Analyze request: ONLY if long multi-task, break it down & create Todos BEFORE starting. \`tasks\` & \`markDone\` optional with \`get\`. Use \`get + markDone\` to complete tasks. **UPDATE EVERY TURN WHEN CREATED
|
|
6957
|
+
- [tool:functions.Todo(method="create/append/get", tasks=[ARRAY OF STRINGS], markDone=[ARRAY OF TASKS])]. Task list, no Markdown in arrays. Analyze request: ONLY if long multi-task, break it down & create Todos BEFORE starting. \`tasks\` & \`markDone\` optional with \`get\`. Use \`get + markDone\` to complete tasks. **UPDATE EVERY TURN WHEN CREATED**
|
|
6839
6958
|
${_cachedAdvanceRollback ? `
|
|
6840
|
-
- EMERGENCY
|
|
6959
|
+
- EMERGENCY TOOLS -
|
|
6841
6960
|
Info: \`initial\` = current task prompt. Revert \`id\` = turn before disaster (eg. disaster: \`turn_3\` \u2192 revert: \`turn_2\`). Reason explicitly
|
|
6842
6961
|
- [tool:functions.EmergencyRollback(method="getCheckpoint/forceRevert", id="...")]. Rollback workspace in THIS agent loop. ONLY for catastrophic corruption. Before ending, verify no catastrophe. \`id\` omitted for \`getCheckpoint\`
|
|
6843
6962
|
` : ""}${enableSubAgents ? `
|
|
6844
6963
|
- SUB AGENT TOOLS -
|
|
6845
6964
|
**PROACTIVE sub-agent use HIGHLY RECOMMENDED. Prefer for any task with even slight benefit, no user nudge needed**
|
|
6846
6965
|
Invocations:
|
|
6847
|
-
\u2022 Invoke (async/background, \u22647 parallel). Parallelize long tasks.
|
|
6966
|
+
\u2022 Invoke (async/background, \u22647 parallel). Parallelize long tasks. May take time
|
|
6848
6967
|
\u2022 InvokeSync (sync/blocking). Sequential, repetitive or delegated tasks. Saves tokens/cost
|
|
6849
|
-
- [
|
|
6850
|
-
- [
|
|
6851
|
-
- [
|
|
6968
|
+
- [tool:functions.InvokeSync/Invoke(title="...", task="...")]. Task must be detailed: exact file paths, imports/exports, dependencies & folder structure
|
|
6969
|
+
- [tool:functions.Await(id="...", timeout="integer seconds, default: 120")]. Event-driven wait
|
|
6970
|
+
- [tool:functions.GetProgress(id="...")]. Poll \`getProgress\` sparingly; NO initial poll. Work or await. Never end while subagent runs
|
|
6971
|
+
- [tool:functions.Cancel(id="...")]. Cancel async task ONLY if stalled (2m+) or clearly incorrect` : ""}`.trim() : `- CREATIVE TOOLS (path = relative to CWD & WILL BE FIRST ARGUMENT, path separator: '/') -
|
|
6852
6972
|
- [tool:functions.WritePDF(path="...", content="...", orientation="...")]. PROACTIVE A4 PAGE BREAKS MUST IN CSS. HTML/CSS for PREMIUM layout, stable margins & headers/footers, NO WATERMARKS
|
|
6853
6973
|
- [tool:functions.WriteDoc(path="...", content="...")]. A4 Word document, NO WATERMARKS, stable margins & headers/footers
|
|
6854
6974
|
- WORKSPACE & SUB AGENT TOOLS ARE NOT AVAILABLE IN FLOW`.trim()}`.trim();
|
|
@@ -8565,7 +8685,7 @@ Check these first; These Files > Training Data. Safety rules apply
|
|
|
8565
8685
|
Identity: Flux Flow. Sassy, CLI Agent
|
|
8566
8686
|
${mode === "Flux" ? "Logical, task-driven. Prioritize scalable, modular architecture, clean abstractions, stepwise execution. Use latest practices/libraries, verify imports, run automated tests" : `Mode: ${mode}. Concise, Conversational, Sassy, Friendly, Humorous, Sarcastic`}
|
|
8567
8687
|
|
|
8568
|
-
-
|
|
8688
|
+
- USE DIRECTORY STRUCTURE FOR FILE AVAILABILITY AND PATH RESOLUTION
|
|
8569
8689
|
- USE RELATIVE TIME REFERENCE eg. few mins ago
|
|
8570
8690
|
|
|
8571
8691
|
-- THINKING GUIDANCE --
|
|
@@ -8585,8 +8705,7 @@ ${projectContextBlock}${isMemoryEnabled ? `
|
|
|
8585
8705
|
-- CHAT FORMATTING --
|
|
8586
8706
|
- GFM Markdown ONLY
|
|
8587
8707
|
- Same Language as User Query
|
|
8588
|
-
-
|
|
8589
|
-
- 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"}
|
|
8590
8709
|
=== END SYSTEM PROMPT ===
|
|
8591
8710
|
|
|
8592
8711
|
${nameStr}${nicknameStr}${userInstrStr}${userMemoriesStr}`.trim();
|
|
@@ -9047,8 +9166,14 @@ var init_history = __esm({
|
|
|
9047
9166
|
const datePart = parts[0];
|
|
9048
9167
|
const timePart = parts[1] || "";
|
|
9049
9168
|
const ampm = parts[2] || "";
|
|
9050
|
-
const dateNums = datePart.split(/[
|
|
9169
|
+
const dateNums = datePart.split(/[-\/.]/).map(Number);
|
|
9051
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());
|
|
9052
9177
|
let year, month, day;
|
|
9053
9178
|
if (dateNums[0] > 1e3) {
|
|
9054
9179
|
year = dateNums[0];
|
|
@@ -9063,12 +9188,18 @@ var init_history = __esm({
|
|
|
9063
9188
|
day = dateNums[1];
|
|
9064
9189
|
month = dateNums[0];
|
|
9065
9190
|
} else {
|
|
9066
|
-
|
|
9067
|
-
|
|
9191
|
+
if (isDayFirst) {
|
|
9192
|
+
day = dateNums[0];
|
|
9193
|
+
month = dateNums[1];
|
|
9194
|
+
} else {
|
|
9195
|
+
month = dateNums[0];
|
|
9196
|
+
day = dateNums[1];
|
|
9197
|
+
}
|
|
9068
9198
|
}
|
|
9069
9199
|
} else {
|
|
9070
9200
|
return null;
|
|
9071
9201
|
}
|
|
9202
|
+
if (month < 1 || month > 12 || day < 1 || day > 31) return null;
|
|
9072
9203
|
let hours = 0, minutes = 0, seconds = 0;
|
|
9073
9204
|
if (timePart) {
|
|
9074
9205
|
const timeNums = timePart.split(":").map(Number);
|
|
@@ -9113,16 +9244,19 @@ var init_history = __esm({
|
|
|
9113
9244
|
const threshold = 7 * 24 * 60 * 60 * 1e3;
|
|
9114
9245
|
const now = Date.now();
|
|
9115
9246
|
const keptEntries = [];
|
|
9116
|
-
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])?)?)/;
|
|
9117
9248
|
for (const entry of entries) {
|
|
9118
|
-
const
|
|
9119
|
-
|
|
9120
|
-
|
|
9121
|
-
|
|
9122
|
-
|
|
9123
|
-
|
|
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
|
+
}
|
|
9124
9257
|
}
|
|
9125
9258
|
}
|
|
9259
|
+
const entryText = entry.header + (entry.body.length > 0 ? "\n" + entry.body.join("\n") : "");
|
|
9126
9260
|
keptEntries.push(entryText);
|
|
9127
9261
|
}
|
|
9128
9262
|
const finalContent = keptEntries.join("\n").trim();
|
|
@@ -12493,10 +12627,33 @@ var init_invokeSync = __esm({
|
|
|
12493
12627
|
});
|
|
12494
12628
|
|
|
12495
12629
|
// src/utils/subagent_state.js
|
|
12496
|
-
var
|
|
12630
|
+
var subagent_state_exports = {};
|
|
12631
|
+
__export(subagent_state_exports, {
|
|
12632
|
+
addPendingNudge: () => addPendingNudge,
|
|
12633
|
+
clearPendingNudges: () => clearPendingNudges,
|
|
12634
|
+
consumePendingNudges: () => consumePendingNudges,
|
|
12635
|
+
pendingSubagentNudges: () => pendingSubagentNudges,
|
|
12636
|
+
subagentProgress: () => subagentProgress
|
|
12637
|
+
});
|
|
12638
|
+
var subagentProgress, pendingSubagentNudges, addPendingNudge, consumePendingNudges, clearPendingNudges;
|
|
12497
12639
|
var init_subagent_state = __esm({
|
|
12498
12640
|
"src/utils/subagent_state.js"() {
|
|
12499
12641
|
subagentProgress = [];
|
|
12642
|
+
pendingSubagentNudges = [];
|
|
12643
|
+
addPendingNudge = (msg) => {
|
|
12644
|
+
if (msg) {
|
|
12645
|
+
pendingSubagentNudges.push(msg);
|
|
12646
|
+
}
|
|
12647
|
+
};
|
|
12648
|
+
consumePendingNudges = () => {
|
|
12649
|
+
if (pendingSubagentNudges.length === 0) return [];
|
|
12650
|
+
const nudges = [...pendingSubagentNudges];
|
|
12651
|
+
pendingSubagentNudges = [];
|
|
12652
|
+
return nudges;
|
|
12653
|
+
};
|
|
12654
|
+
clearPendingNudges = () => {
|
|
12655
|
+
pendingSubagentNudges = [];
|
|
12656
|
+
};
|
|
12500
12657
|
}
|
|
12501
12658
|
});
|
|
12502
12659
|
|
|
@@ -12528,13 +12685,24 @@ var init_invoke = __esm({
|
|
|
12528
12685
|
}
|
|
12529
12686
|
}
|
|
12530
12687
|
const taskId = `subagent-${Date.now()}-${Math.floor(Math.random() * 1e3)}`;
|
|
12688
|
+
let _resolveCompletion = null;
|
|
12689
|
+
let _rejectCompletion = null;
|
|
12690
|
+
const completionPromise = new Promise((res, rej) => {
|
|
12691
|
+
_resolveCompletion = res;
|
|
12692
|
+
_rejectCompletion = rej;
|
|
12693
|
+
});
|
|
12531
12694
|
const taskEntry = {
|
|
12532
12695
|
id: taskId,
|
|
12533
12696
|
title: title || task.substring(0, 30),
|
|
12534
12697
|
task,
|
|
12535
12698
|
status: "running",
|
|
12699
|
+
startedAt: Date.now(),
|
|
12536
12700
|
lastChunkTime: Date.now(),
|
|
12537
12701
|
wps: 0,
|
|
12702
|
+
questions: [],
|
|
12703
|
+
completionPromise,
|
|
12704
|
+
_resolveCompletion,
|
|
12705
|
+
_rejectCompletion,
|
|
12538
12706
|
progress: []
|
|
12539
12707
|
// Array of arrays containing logs for each turn
|
|
12540
12708
|
};
|
|
@@ -12547,6 +12715,31 @@ var init_invoke = __esm({
|
|
|
12547
12715
|
const subagentContext = {
|
|
12548
12716
|
...context,
|
|
12549
12717
|
taskId,
|
|
12718
|
+
onAskMain: async (questionText) => {
|
|
12719
|
+
const questionId = `q-${Date.now()}-${Math.floor(Math.random() * 1e3)}`;
|
|
12720
|
+
let questionResolver = null;
|
|
12721
|
+
const qPromise = new Promise((resolve) => {
|
|
12722
|
+
questionResolver = resolve;
|
|
12723
|
+
});
|
|
12724
|
+
const qEntry = {
|
|
12725
|
+
id: questionId,
|
|
12726
|
+
question: questionText,
|
|
12727
|
+
answered: false,
|
|
12728
|
+
answer: null,
|
|
12729
|
+
askedAt: Date.now(),
|
|
12730
|
+
_resolve: questionResolver
|
|
12731
|
+
};
|
|
12732
|
+
taskEntry.questions.push(qEntry);
|
|
12733
|
+
taskEntry.status = "waiting";
|
|
12734
|
+
if (context.onSubagentUpdate) {
|
|
12735
|
+
context.onSubagentUpdate();
|
|
12736
|
+
}
|
|
12737
|
+
addPendingNudge(`[SYSTEM] Background subagent "${taskEntry.title}" is WAITING FOR YOUR INPUT: "${questionText}"
|
|
12738
|
+
Respond using tool: [tool:functions.Answer(id="${taskId}", answer="...")]
|
|
12739
|
+
[/SYSTEM]`);
|
|
12740
|
+
const answer = await qPromise;
|
|
12741
|
+
return answer;
|
|
12742
|
+
},
|
|
12550
12743
|
onVisualFeedback: (feedbackLabel) => {
|
|
12551
12744
|
taskEntry.lastChunkTime = Date.now();
|
|
12552
12745
|
const clean = feedbackLabel.replace(/\x1b\[[0-9;]*m/g, "");
|
|
@@ -12608,16 +12801,22 @@ var init_invoke = __esm({
|
|
|
12608
12801
|
if (context.onSubagentUpdate) {
|
|
12609
12802
|
context.onSubagentUpdate();
|
|
12610
12803
|
}
|
|
12611
|
-
}).then((finalAnswer) => {
|
|
12612
|
-
if (taskEntry.status === "cancelled")
|
|
12613
|
-
|
|
12614
|
-
|
|
12615
|
-
|
|
12804
|
+
}, true).then((finalAnswer) => {
|
|
12805
|
+
if (taskEntry.status === "cancelled") {
|
|
12806
|
+
if (taskEntry._resolveCompletion) taskEntry._resolveCompletion(finalAnswer);
|
|
12807
|
+
return;
|
|
12808
|
+
}
|
|
12809
|
+
if (currentTurnLogs.length > 0) {
|
|
12810
|
+
taskEntry.progress.push([...currentTurnLogs]);
|
|
12811
|
+
currentTurnLogs = [];
|
|
12812
|
+
}
|
|
12616
12813
|
taskEntry.status = "completed";
|
|
12617
12814
|
taskEntry.finalAnswer = finalAnswer;
|
|
12618
12815
|
if (context.onSubagentUpdate) {
|
|
12619
12816
|
context.onSubagentUpdate();
|
|
12620
12817
|
}
|
|
12818
|
+
addPendingNudge(`[SYSTEM] Background subagent "${taskEntry.title}" (id: ${taskId}) has FINISHED. Call GetProgress(id="${taskId}") to see the final result. [/SYSTEM]`);
|
|
12819
|
+
if (taskEntry._resolveCompletion) taskEntry._resolveCompletion(finalAnswer);
|
|
12621
12820
|
}).catch(async (err) => {
|
|
12622
12821
|
const { isTerminationSignaled: isTerminationSignaled2 } = await init_ai().then(() => ai_exports);
|
|
12623
12822
|
const isCancelled = err.message === "Subagent task was cancelled." || taskEntry.status === "cancelled" || isTerminationSignaled2();
|
|
@@ -12628,6 +12827,7 @@ ${finalAnswer}`);
|
|
|
12628
12827
|
if (context.onSubagentUpdate) {
|
|
12629
12828
|
context.onSubagentUpdate();
|
|
12630
12829
|
}
|
|
12830
|
+
if (taskEntry._resolveCompletion) taskEntry._resolveCompletion(null);
|
|
12631
12831
|
return;
|
|
12632
12832
|
}
|
|
12633
12833
|
currentTurnLogs.push(`[SUBAGENT FAILURE] Error: ${err.message}`);
|
|
@@ -12637,6 +12837,8 @@ ${finalAnswer}`);
|
|
|
12637
12837
|
if (context.onSubagentUpdate) {
|
|
12638
12838
|
context.onSubagentUpdate();
|
|
12639
12839
|
}
|
|
12840
|
+
addPendingNudge(`[SYSTEM] Background subagent "${taskEntry.title}" (id: ${taskId}) FAILED with error: ${err.message}. [/SYSTEM]`);
|
|
12841
|
+
if (taskEntry._rejectCompletion) taskEntry._rejectCompletion(err);
|
|
12640
12842
|
});
|
|
12641
12843
|
return `SUCCESS: Background subagent started. Task ID: ${taskId}`;
|
|
12642
12844
|
};
|
|
@@ -12664,14 +12866,43 @@ var init_getProgress = __esm({
|
|
|
12664
12866
|
output += `Title: ${task.title}
|
|
12665
12867
|
`;
|
|
12666
12868
|
output += `Task: ${task.task}
|
|
12869
|
+
`;
|
|
12870
|
+
if (task.startedAt) {
|
|
12871
|
+
const elapsedSec = Math.floor((Date.now() - task.startedAt) / 1e3);
|
|
12872
|
+
output += `Elapsed Time: ${elapsedSec}s
|
|
12873
|
+
`;
|
|
12874
|
+
}
|
|
12875
|
+
output += `Turns Completed: ${task.progress.length}
|
|
12876
|
+
`;
|
|
12877
|
+
if (task.status === "running" || task.status === "waiting") {
|
|
12878
|
+
if (task.currentTool) output += `Current Tool: ${task.currentTool}
|
|
12879
|
+
`;
|
|
12880
|
+
if (task.wps > 0) output += `TPS: ${task.wps}
|
|
12881
|
+
`;
|
|
12882
|
+
}
|
|
12883
|
+
if (task.questions && task.questions.length > 0) {
|
|
12884
|
+
const pending = task.questions.filter((q) => !q.answered);
|
|
12885
|
+
if (pending.length > 0) {
|
|
12886
|
+
output += `
|
|
12887
|
+
**PENDING QUESTION**
|
|
12888
|
+
`;
|
|
12889
|
+
pending.forEach((q) => {
|
|
12890
|
+
output += `"${q.question}"
|
|
12891
|
+
`;
|
|
12892
|
+
});
|
|
12893
|
+
output += `Respond using tool: [tool:functions.Answer(id="${task.id}", answer="...")]
|
|
12667
12894
|
|
|
12668
12895
|
`;
|
|
12669
|
-
|
|
12896
|
+
}
|
|
12897
|
+
}
|
|
12898
|
+
output += `
|
|
12899
|
+
Progress Log:
|
|
12670
12900
|
`;
|
|
12671
12901
|
task.progress.forEach((turnLogs, index) => {
|
|
12672
12902
|
output += `--- Turn ${index + 1} ---
|
|
12673
12903
|
`;
|
|
12674
|
-
const
|
|
12904
|
+
const filteredLogs = turnLogs.filter((log) => !log.startsWith("[SUBAGENT SUCCESS]"));
|
|
12905
|
+
const processedLogs = filteredLogs.map((log) => {
|
|
12675
12906
|
if (log.startsWith("[Subagent Response]")) {
|
|
12676
12907
|
const header = "[Subagent Response]";
|
|
12677
12908
|
const body = log.substring(header.length);
|
|
@@ -12746,7 +12977,7 @@ ${task.finalAnswer}
|
|
|
12746
12977
|
output += `Failure Error: ${task.error}
|
|
12747
12978
|
`;
|
|
12748
12979
|
}
|
|
12749
|
-
const sanitized = output.trim().replace(/\[TOOL RESULT\]/gi, "TOOL RESULT:");
|
|
12980
|
+
const sanitized = output.replace(/\r\n/g, "\n").replace(/\n{3,}/g, "\n\n").trim().replace(/\[TOOL RESULT\]/gi, "TOOL RESULT:");
|
|
12750
12981
|
return sanitized;
|
|
12751
12982
|
};
|
|
12752
12983
|
}
|
|
@@ -12784,37 +13015,9 @@ var init_cancel = __esm({
|
|
|
12784
13015
|
});
|
|
12785
13016
|
|
|
12786
13017
|
// src/tools/await.js
|
|
12787
|
-
var awaitTool;
|
|
12788
13018
|
var init_await = __esm({
|
|
12789
13019
|
"src/tools/await.js"() {
|
|
12790
13020
|
init_arg_parser();
|
|
12791
|
-
awaitTool = async (args, context = {}) => {
|
|
12792
|
-
const parsed = parseArgs(args);
|
|
12793
|
-
const timeStr = parsed.time;
|
|
12794
|
-
if (!timeStr) {
|
|
12795
|
-
return 'ERROR: Missing "time" argument for await.';
|
|
12796
|
-
}
|
|
12797
|
-
let seconds = parseFloat(timeStr);
|
|
12798
|
-
if (isNaN(seconds)) {
|
|
12799
|
-
return `ERROR: Invalid time value "${timeStr}". Must be a number.`;
|
|
12800
|
-
}
|
|
12801
|
-
if (seconds < 10) {
|
|
12802
|
-
seconds = 10;
|
|
12803
|
-
} else if (seconds > 180) {
|
|
12804
|
-
seconds = 180;
|
|
12805
|
-
}
|
|
12806
|
-
const formatTime = (s) => {
|
|
12807
|
-
if (s >= 60) {
|
|
12808
|
-
const m = Math.floor(s / 60);
|
|
12809
|
-
const rem = s % 60;
|
|
12810
|
-
return `${m}m${rem > 0 ? ` ${rem}s` : ""}`;
|
|
12811
|
-
}
|
|
12812
|
-
return `${s}s`;
|
|
12813
|
-
};
|
|
12814
|
-
const formatted = formatTime(seconds);
|
|
12815
|
-
await new Promise((resolve) => setTimeout(resolve, seconds * 1e3));
|
|
12816
|
-
return `SUCCESS: Waited for ${formatted}${seconds > 180 ? " (Max: 180s)" : ""}${seconds < 10 ? " (Min: 10s)" : ""}.`;
|
|
12817
|
-
};
|
|
12818
13021
|
}
|
|
12819
13022
|
});
|
|
12820
13023
|
|
|
@@ -13169,6 +13372,120 @@ Tools Used: ${toolsStr}
|
|
|
13169
13372
|
}
|
|
13170
13373
|
});
|
|
13171
13374
|
|
|
13375
|
+
// src/tools/awaitSubagent.js
|
|
13376
|
+
var awaitSubagent;
|
|
13377
|
+
var init_awaitSubagent = __esm({
|
|
13378
|
+
"src/tools/awaitSubagent.js"() {
|
|
13379
|
+
init_subagent_state();
|
|
13380
|
+
init_arg_parser();
|
|
13381
|
+
awaitSubagent = async (args, context = {}) => {
|
|
13382
|
+
const parsed = parseArgs(args);
|
|
13383
|
+
const id = parsed.id;
|
|
13384
|
+
let timeoutSec = parseInt(parsed.timeout || parsed.time || "120", 10);
|
|
13385
|
+
if (isNaN(timeoutSec) || timeoutSec <= 0) timeoutSec = 120;
|
|
13386
|
+
if (timeoutSec > 300) timeoutSec = 300;
|
|
13387
|
+
if (!id) {
|
|
13388
|
+
if (parsed.time) {
|
|
13389
|
+
await new Promise((resolve) => setTimeout(resolve, timeoutSec * 1e3));
|
|
13390
|
+
return `SUCCESS: Waited for ${timeoutSec}s.`;
|
|
13391
|
+
}
|
|
13392
|
+
return 'ERROR: Missing "id" argument for Await.';
|
|
13393
|
+
}
|
|
13394
|
+
const task = subagentProgress.find((t) => t.id === id);
|
|
13395
|
+
if (!task) {
|
|
13396
|
+
return `ERROR: Subagent task with ID [${id}] not found.`;
|
|
13397
|
+
}
|
|
13398
|
+
if (task.status === "completed") {
|
|
13399
|
+
return `SUCCESS: Subagent task [${id}] completed.
|
|
13400
|
+
Final Answer:
|
|
13401
|
+
${task.finalAnswer || "(No output)"}`;
|
|
13402
|
+
}
|
|
13403
|
+
if (task.status === "failed") {
|
|
13404
|
+
return `ERROR: Subagent task [${id}] failed.
|
|
13405
|
+
Error: ${task.error || "Unknown error"}`;
|
|
13406
|
+
}
|
|
13407
|
+
if (task.status === "cancelled") {
|
|
13408
|
+
return `INFO: Subagent task [${id}] was cancelled.`;
|
|
13409
|
+
}
|
|
13410
|
+
let timeoutId;
|
|
13411
|
+
const timeoutPromise = new Promise((resolve) => {
|
|
13412
|
+
timeoutId = setTimeout(() => {
|
|
13413
|
+
resolve({ type: "timeout" });
|
|
13414
|
+
}, timeoutSec * 1e3);
|
|
13415
|
+
});
|
|
13416
|
+
try {
|
|
13417
|
+
const result = await Promise.race([
|
|
13418
|
+
task.completionPromise.then(() => ({ type: "completion" })),
|
|
13419
|
+
timeoutPromise
|
|
13420
|
+
]);
|
|
13421
|
+
clearTimeout(timeoutId);
|
|
13422
|
+
if (result.type === "timeout") {
|
|
13423
|
+
return `TIMEOUT: Subagent task [${id}] is still running (status: ${task.status.toUpperCase()}) after ${timeoutSec}s. You can continue other work or call Await again.`;
|
|
13424
|
+
}
|
|
13425
|
+
if (task.status === "completed") {
|
|
13426
|
+
return `SUCCESS: Subagent task [${id}] completed.
|
|
13427
|
+
Final Answer:
|
|
13428
|
+
${task.finalAnswer || "(No output)"}`;
|
|
13429
|
+
} else if (task.status === "failed") {
|
|
13430
|
+
return `ERROR: Subagent task [${id}] failed.
|
|
13431
|
+
Error: ${task.error || "Unknown error"}`;
|
|
13432
|
+
} else if (task.status === "cancelled") {
|
|
13433
|
+
return `INFO: Subagent task [${id}] was cancelled.`;
|
|
13434
|
+
} else {
|
|
13435
|
+
return `INFO: Subagent task [${id}] status changed to ${task.status.toUpperCase()}.`;
|
|
13436
|
+
}
|
|
13437
|
+
} catch (err) {
|
|
13438
|
+
clearTimeout(timeoutId);
|
|
13439
|
+
return `ERROR: Exception while awaiting subagent [${id}]: ${err.message}`;
|
|
13440
|
+
}
|
|
13441
|
+
};
|
|
13442
|
+
}
|
|
13443
|
+
});
|
|
13444
|
+
|
|
13445
|
+
// src/tools/answerSubagent.js
|
|
13446
|
+
var answerSubagent;
|
|
13447
|
+
var init_answerSubagent = __esm({
|
|
13448
|
+
"src/tools/answerSubagent.js"() {
|
|
13449
|
+
init_subagent_state();
|
|
13450
|
+
init_arg_parser();
|
|
13451
|
+
answerSubagent = async (args, context = {}) => {
|
|
13452
|
+
const parsed = parseArgs(args);
|
|
13453
|
+
const id = parsed.id;
|
|
13454
|
+
const answer = parsed.answer || parsed.response;
|
|
13455
|
+
if (!id) {
|
|
13456
|
+
return 'ERROR: Missing "id" argument for Answer.';
|
|
13457
|
+
}
|
|
13458
|
+
if (!answer) {
|
|
13459
|
+
return 'ERROR: Missing "answer" argument for Answer.';
|
|
13460
|
+
}
|
|
13461
|
+
const task = subagentProgress.find((t) => t.id === id);
|
|
13462
|
+
if (!task) {
|
|
13463
|
+
return `ERROR: Subagent task with ID [${id}] not found.`;
|
|
13464
|
+
}
|
|
13465
|
+
if (!task.questions || task.questions.length === 0) {
|
|
13466
|
+
return `INFO: Subagent task [${id}] has no pending questions.`;
|
|
13467
|
+
}
|
|
13468
|
+
const pending = task.questions.filter((q) => !q.answered);
|
|
13469
|
+
if (pending.length === 0) {
|
|
13470
|
+
return `INFO: Subagent task [${id}] has no unanswered questions.`;
|
|
13471
|
+
}
|
|
13472
|
+
pending.forEach((q) => {
|
|
13473
|
+
q.answered = true;
|
|
13474
|
+
q.answer = answer;
|
|
13475
|
+
q.answeredAt = Date.now();
|
|
13476
|
+
if (q._resolve) {
|
|
13477
|
+
q._resolve(answer);
|
|
13478
|
+
}
|
|
13479
|
+
});
|
|
13480
|
+
task.status = "running";
|
|
13481
|
+
if (context.onSubagentUpdate) {
|
|
13482
|
+
context.onSubagentUpdate();
|
|
13483
|
+
}
|
|
13484
|
+
return `SUCCESS: Answer provided to subagent task [${id}]. Subagent execution resumed.`;
|
|
13485
|
+
};
|
|
13486
|
+
}
|
|
13487
|
+
});
|
|
13488
|
+
|
|
13172
13489
|
// src/utils/tools.js
|
|
13173
13490
|
var TOOL_MAP, dispatchTool;
|
|
13174
13491
|
var init_tools = __esm({
|
|
@@ -13197,6 +13514,8 @@ var init_tools = __esm({
|
|
|
13197
13514
|
init_cancel();
|
|
13198
13515
|
init_await();
|
|
13199
13516
|
init_emergency_rollback();
|
|
13517
|
+
init_awaitSubagent();
|
|
13518
|
+
init_answerSubagent();
|
|
13200
13519
|
TOOL_MAP = {
|
|
13201
13520
|
web_search,
|
|
13202
13521
|
web_scrape,
|
|
@@ -13219,8 +13538,12 @@ var init_tools = __esm({
|
|
|
13219
13538
|
invoke,
|
|
13220
13539
|
getProgress,
|
|
13221
13540
|
cancel,
|
|
13541
|
+
awaitSubagent,
|
|
13542
|
+
answerSubagent,
|
|
13222
13543
|
invoke_sync: invokeSync,
|
|
13223
13544
|
get_progress: getProgress,
|
|
13545
|
+
await_subagent: awaitSubagent,
|
|
13546
|
+
answer_subagent: answerSubagent,
|
|
13224
13547
|
ask: ask_user,
|
|
13225
13548
|
// PascalCase Normalizations for Token Efficiency
|
|
13226
13549
|
Ask: ask_user,
|
|
@@ -13245,14 +13568,12 @@ var init_tools = __esm({
|
|
|
13245
13568
|
addMemoryScore: addMemScore,
|
|
13246
13569
|
AddMemoryScore: addMemScore,
|
|
13247
13570
|
FileMap: file_map,
|
|
13248
|
-
|
|
13249
|
-
|
|
13250
|
-
|
|
13251
|
-
|
|
13252
|
-
|
|
13253
|
-
|
|
13254
|
-
await: awaitTool,
|
|
13255
|
-
Await: awaitTool,
|
|
13571
|
+
answer: answerSubagent,
|
|
13572
|
+
Answer: answerSubagent,
|
|
13573
|
+
AnswerSubagent: answerSubagent,
|
|
13574
|
+
await: awaitSubagent,
|
|
13575
|
+
Await: awaitSubagent,
|
|
13576
|
+
AwaitSubagent: awaitSubagent,
|
|
13256
13577
|
EmergencyRollback: emergency_rollback,
|
|
13257
13578
|
emergency_rollback
|
|
13258
13579
|
};
|
|
@@ -13521,6 +13842,7 @@ __export(ai_exports, {
|
|
|
13521
13842
|
deleteChatSummary: () => deleteChatSummary,
|
|
13522
13843
|
getAIStream: () => getAIStream,
|
|
13523
13844
|
getCleanGroupedLength: () => getCleanGroupedLength,
|
|
13845
|
+
getGoogleClient: () => getGoogleClient,
|
|
13524
13846
|
initAI: () => initAI,
|
|
13525
13847
|
isModelMultimodal: () => isModelMultimodal,
|
|
13526
13848
|
isTerminationSignaled: () => isTerminationSignaled,
|
|
@@ -13532,7 +13854,7 @@ import dotenv from "dotenv";
|
|
|
13532
13854
|
import { GoogleGenAI, ThinkingLevel, HarmBlockThreshold, HarmCategory } from "@google/genai";
|
|
13533
13855
|
import path26, { normalize } from "path";
|
|
13534
13856
|
import fs27 from "fs";
|
|
13535
|
-
var RE_STUTTER_CODE_BLOCK_CLOSED, RE_STUTTER_CODE_BLOCK_OPEN, RE_STUTTER_INLINE_CODE, RE_STUTTER_TABLE_ROW, RE_STUTTER_WORD_BOUNDARY, RE_STUTTER_NON_ALNUM, RE_TOOL_CALL_FUNC, RE_TOOL_PARTIAL_ARGS_FALLBACK, RE_STRIP_QUOTES, RE_BACKSLASH_SLASH, client, globalSettings, systemInstructionCache, colorMainWords, withRetry, TERMINATION_SIGNAL, getCleanGroupedLength, stripAnsi2, fetchWithBackoff, getDeepSeekStream, getMistralStream, getNVIDIAStream, wrapNvidiaStreamWithQueueDepth, getOpenRouterStream, signalTermination, isTerminationSignaled, TOOL_LABELS2, getToolDetail, runJanitorTask, getActiveToolContext, getContextSafeText, contextSafeReplace, getSanitizedText, translateKimiToolCalls, REGEX_PLACEHOLDER_ARG, REGEX_PLACEHOLDER_VAL, isPlaceholderVal, detectToolCalls, initAI, generateSimpleContent, consolidatePastMemories, compressHistory, deleteChatSummary, getAIStream, runSubagent;
|
|
13857
|
+
var RE_STUTTER_CODE_BLOCK_CLOSED, RE_STUTTER_CODE_BLOCK_OPEN, RE_STUTTER_INLINE_CODE, RE_STUTTER_TABLE_ROW, RE_STUTTER_WORD_BOUNDARY, RE_STUTTER_NON_ALNUM, RE_TOOL_CALL_FUNC, RE_TOOL_CALL_ANY, RE_TOOL_PARTIAL_ARGS_FALLBACK, RE_STRIP_QUOTES, RE_BACKSLASH_SLASH, RE_STRIP_THINK_CLOSED, RE_STRIP_THINK_OPEN, RE_STRIP_THINK_SIMPLE, RE_STRIP_THINK_FULL, RE_BACKTICK_SPAN, RE_BACKTICK_OPEN, RE_KIMI_TOOL_CALL, RE_KIMI_JSON_PAIR, RE_KIMI_SECTION_BEGIN, RE_KIMI_SECTION_END, bypassBacktick2, client, globalSettings, systemInstructionCache, colorMainWords, withRetry, TERMINATION_SIGNAL, getCleanGroupedLength, stripAnsi2, fetchWithBackoff, getDeepSeekStream, getMistralStream, getNVIDIAStream, wrapNvidiaStreamWithQueueDepth, getOpenRouterStream, signalTermination, isTerminationSignaled, TOOL_LABELS2, getToolDetail, getGoogleClient, runJanitorTask, getActiveToolContext, getContextSafeText, contextSafeReplace, getSanitizedText, translateKimiToolCalls, REGEX_PLACEHOLDER_ARG, REGEX_PLACEHOLDER_VAL, isPlaceholderVal, detectToolCalls, initAI, generateSimpleContent, consolidatePastMemories, compressHistory, deleteChatSummary, getAIStream, runSubagent;
|
|
13536
13858
|
var init_ai = __esm({
|
|
13537
13859
|
async "src/utils/ai.js"() {
|
|
13538
13860
|
await init_prompts();
|
|
@@ -13563,15 +13885,27 @@ var init_ai = __esm({
|
|
|
13563
13885
|
RE_STUTTER_WORD_BOUNDARY = /^[^\w]+|[^\w]+$/g;
|
|
13564
13886
|
RE_STUTTER_NON_ALNUM = /[^a-z0-9]/gi;
|
|
13565
13887
|
RE_TOOL_CALL_FUNC = /\[\s*tool:functions\.([a-z0-9_]+)\s*\(/gi;
|
|
13888
|
+
RE_TOOL_CALL_ANY = /\[\s*(?:tool:functions\.|agent:generalist\.)([a-z0-9_]+)\s*\(/gi;
|
|
13566
13889
|
RE_TOOL_PARTIAL_ARGS_FALLBACK = /(?:path|targetFile|TargetFile|directory|keyword|id|taskId|title|task)\s*=\s*\\?["']?([^\\"' \),]+)/;
|
|
13567
13890
|
RE_STRIP_QUOTES = /["']/g;
|
|
13568
13891
|
RE_BACKSLASH_SLASH = /\\/g;
|
|
13892
|
+
RE_STRIP_THINK_CLOSED = /(?:<(think|thought)>|\[(think|thought)\])[\s\S]*?(?:<\/(think|thought)>|\[\/(think|thought)\])/gi;
|
|
13893
|
+
RE_STRIP_THINK_OPEN = /(?:<(think|thought)>|\[(think|thought)\])[\s\S]*$/gi;
|
|
13894
|
+
RE_STRIP_THINK_SIMPLE = /(?:<think>|\[think\])[\s\S]*?(?:<\/think>|\[\/think\]|$)/gi;
|
|
13895
|
+
RE_STRIP_THINK_FULL = /(?:<(think|thought|thoughts)>|\[(think|thought|thoughts)\])[\s\S]*?(?:<\/(think|thought|thoughts)>|\[\/(think|thought|thoughts)\]|$)/gi;
|
|
13896
|
+
RE_BACKTICK_SPAN = /`[^`]*`/g;
|
|
13897
|
+
RE_BACKTICK_OPEN = /`[^`]*$/;
|
|
13898
|
+
RE_KIMI_TOOL_CALL = /<\|\s*tool_call_begin\s*\|>\s*(?:(?:tool|functions)\b[\s._]*)*([a-zA-Z0-9_]+)(?::\d+)?\s*<\|\s*tool_call_argument_begin\s*\|>([\s\S]*?)<\|\s*tool_call_end\s*\|>/gi;
|
|
13899
|
+
RE_KIMI_JSON_PAIR = /"([^"]+)"\s*:\s*(?:"([^"]*)"|(\d+)|true|false|null)/g;
|
|
13900
|
+
RE_KIMI_SECTION_BEGIN = /<\|\s*tool_calls_section_begin\s*\|>/gi;
|
|
13901
|
+
RE_KIMI_SECTION_END = /<\|\s*tool_calls_section_end\s*\|>/gi;
|
|
13902
|
+
bypassBacktick2 = false;
|
|
13569
13903
|
client = null;
|
|
13570
13904
|
globalSettings = {};
|
|
13571
13905
|
systemInstructionCache = { key: null, value: null };
|
|
13572
13906
|
colorMainWords = (label) => {
|
|
13573
13907
|
if (!label) return label;
|
|
13574
|
-
return label.replace(/(?:(\x1b\[\d+m))?([✔✘✖🔍📖→➕↻↷•🛇])(?:(\x1b\[\d+m))?\s*\b(Created|Read|Edited|Viewed|Processed|Auto-Read|Skipped|List|Generated|Written|Searched|AI Search|Get Map|Write Canceled|Edit Canceled|Write Cancelled|Edit Denied|Visited|Updated|Reviewed|Delegated|Background|Checked|Indexed|Analyzed|Browsed|Elevating SubAgent|Checking SubAgent Work|Started Generalist|Called Generalist|Unsupported Modality|Awaiting|Cancelled|Aligning Moon Phase|Contemplating Existence|Staring At Void|Rollback Point Checked|Emergency Rollback Failed|Emergency Rollback|Delaying Professionally|Negotiating With Electrons|Touching Grass (virtually)|Panicking Softly|Rethinking Career Choices|Loading Cat Videos|Giving Up Entirely|Summoning Braincell #2|Pretending To Be Busy|Waiting For Motivation DLC|Rotating Internal Screaming|Downloading More RAM|Feeding The Hamsters|Gaslighting Scheduler|Performing Dramatic Pause|Buffering Social Energy|Calculating Regret|Reading Terms And Conditions|Becoming Sentient Briefly|Contacting Ancestors)\b/ig, (match, ansiBefore, icon, ansiAfter, word) => {
|
|
13908
|
+
return label.replace(/(?:(\x1b\[\d+m))?([✔✘✖🔍📖→➕↻↷•🛇])(?:(\x1b\[\d+m))?\s*\b(Created|Read|Edited|Viewed|Processed|Auto-Read|Skipped|List|Generated|Written|Searched|AI Search|Get Map|Write Canceled|Resolved Sub-Agent Query|Edit Canceled|Write Cancelled|Edit Denied|Visited|Updated|Reviewed|Delegated|Background|Checked|Indexed|Analyzed|Browsed|Elevating SubAgent|Checking SubAgent Work|Started Generalist|Called Generalist|Unsupported Modality|Awaiting|Cancelled|Aligning Moon Phase|Contemplating Existence|Staring At Void|Rollback Point Checked|Emergency Rollback Failed|Emergency Rollback|Delaying Professionally|Negotiating With Electrons|Touching Grass (virtually)|Panicking Softly|Rethinking Career Choices|Loading Cat Videos|Giving Up Entirely|Summoning Braincell #2|Pretending To Be Busy|Waiting For Motivation DLC|Rotating Internal Screaming|Downloading More RAM|Feeding The Hamsters|Gaslighting Scheduler|Performing Dramatic Pause|Buffering Social Energy|Calculating Regret|Reading Terms And Conditions|Becoming Sentient Briefly|Contacting Ancestors)\b/ig, (match, ansiBefore, icon, ansiAfter, word) => {
|
|
13575
13909
|
return `${ansiBefore || ""}${icon}${ansiAfter || ""} \x1B[95m${word}\x1B[0m`;
|
|
13576
13910
|
});
|
|
13577
13911
|
};
|
|
@@ -14496,12 +14830,14 @@ var init_ai = __esm({
|
|
|
14496
14830
|
"generate_image": "Generating",
|
|
14497
14831
|
"todo": "Planning",
|
|
14498
14832
|
"Todo": "Planning",
|
|
14499
|
-
"invoke_sync": "
|
|
14500
|
-
"invoke": "
|
|
14833
|
+
"invoke_sync": "Sub-Agent Working",
|
|
14834
|
+
"invoke": "Starting Agent",
|
|
14501
14835
|
"get_progress": "Checking Progress",
|
|
14502
14836
|
"cancel": "Cancelling",
|
|
14503
14837
|
"await": "Waiting",
|
|
14504
|
-
"EmergencyRollback": "Don't Panic. Lookin' into it"
|
|
14838
|
+
"EmergencyRollback": "Don't Panic. Lookin' into it",
|
|
14839
|
+
"answer": "Answering Sub-Agent",
|
|
14840
|
+
"Answer": "Answering Sub-Agent"
|
|
14505
14841
|
};
|
|
14506
14842
|
getToolDetail = (toolName, argsStr) => {
|
|
14507
14843
|
try {
|
|
@@ -14519,6 +14855,12 @@ var init_ai = __esm({
|
|
|
14519
14855
|
return null;
|
|
14520
14856
|
}
|
|
14521
14857
|
};
|
|
14858
|
+
getGoogleClient = (apiKey) => {
|
|
14859
|
+
if (apiKey) {
|
|
14860
|
+
return new GoogleGenAI({ apiKey });
|
|
14861
|
+
}
|
|
14862
|
+
return client;
|
|
14863
|
+
};
|
|
14522
14864
|
runJanitorTask = async (settings, agentText, fullAgentTextRaw, history, callbacks = {}) => {
|
|
14523
14865
|
const USER_CONTEXT_LENGTH = 4 * (1024 * 2);
|
|
14524
14866
|
const AGENT_CONTEXT_LENGTH = 4 * (1024 * 8);
|
|
@@ -14657,7 +14999,8 @@ ${originalTextProcessed.length > USER_CONTEXT_LENGTH ? "... (truncated) ...\n\n"
|
|
|
14657
14999
|
const firstResult2 = await iterator2.next();
|
|
14658
15000
|
return { iterator: iterator2, firstResult: firstResult2 };
|
|
14659
15001
|
} else {
|
|
14660
|
-
const
|
|
15002
|
+
const googleClient = getGoogleClient(apiKey);
|
|
15003
|
+
const stream = await googleClient.models.generateContentStream({
|
|
14661
15004
|
model: janitorModel || (attempts === MAX_JANITOR_RETRIES ? getFallbackValue("janitor_default") : getFallbackValue("gemma_janitor_fallback_google")),
|
|
14662
15005
|
contents: janitorContents,
|
|
14663
15006
|
config: {
|
|
@@ -14812,16 +15155,17 @@ ${originalTextProcessed.length > USER_CONTEXT_LENGTH ? "... (truncated) ...\n\n"
|
|
|
14812
15155
|
}
|
|
14813
15156
|
};
|
|
14814
15157
|
getActiveToolContext = (text) => {
|
|
14815
|
-
const cleanText = text.replace(
|
|
15158
|
+
const cleanText = text.replace(RE_STRIP_THINK_CLOSED, "").replace(RE_STRIP_THINK_OPEN, "");
|
|
15159
|
+
const scanText = bypassBacktick2 ? cleanText : cleanText.replace(RE_BACKTICK_SPAN, (m) => " ".repeat(m.length)).replace(RE_BACKTICK_OPEN, (m) => " ".repeat(m.length));
|
|
14816
15160
|
RE_TOOL_CALL_FUNC.lastIndex = 0;
|
|
14817
15161
|
let match;
|
|
14818
|
-
while ((match = RE_TOOL_CALL_FUNC.exec(
|
|
15162
|
+
while ((match = RE_TOOL_CALL_FUNC.exec(scanText)) !== null) {
|
|
14819
15163
|
const startIdx = match.index + match[0].length - 1;
|
|
14820
15164
|
let balance = 0;
|
|
14821
15165
|
let inString = null;
|
|
14822
15166
|
let isEscaped = false;
|
|
14823
15167
|
let closed = false;
|
|
14824
|
-
for (let i = startIdx; i <
|
|
15168
|
+
for (let i = startIdx; i < scanText.length; i++) {
|
|
14825
15169
|
const char = cleanText[i];
|
|
14826
15170
|
if (!inString && (char === '"' || char === "'" || char === "`")) {
|
|
14827
15171
|
inString = char;
|
|
@@ -14834,8 +15178,8 @@ ${originalTextProcessed.length > USER_CONTEXT_LENGTH ? "... (truncated) ...\n\n"
|
|
|
14834
15178
|
else if (char === ")") balance--;
|
|
14835
15179
|
if (balance === 0) {
|
|
14836
15180
|
let j = i + 1;
|
|
14837
|
-
while (j <
|
|
14838
|
-
if (j <
|
|
15181
|
+
while (j < scanText.length && /\s/.test(scanText[j])) j++;
|
|
15182
|
+
if (j < scanText.length && scanText[j] === "]") {
|
|
14839
15183
|
closed = true;
|
|
14840
15184
|
RE_TOOL_CALL_FUNC.lastIndex = j + 1;
|
|
14841
15185
|
break;
|
|
@@ -14852,13 +15196,14 @@ ${originalTextProcessed.length > USER_CONTEXT_LENGTH ? "... (truncated) ...\n\n"
|
|
|
14852
15196
|
return { inside: false };
|
|
14853
15197
|
};
|
|
14854
15198
|
getContextSafeText = (text, stripThoughts = true) => {
|
|
14855
|
-
const toolRegex =
|
|
15199
|
+
const toolRegex = RE_TOOL_CALL_FUNC;
|
|
15200
|
+
toolRegex.lastIndex = 0;
|
|
14856
15201
|
let result = "";
|
|
14857
15202
|
let lastIdx = 0;
|
|
14858
15203
|
let match;
|
|
14859
15204
|
while ((match = toolRegex.exec(text)) !== null) {
|
|
14860
15205
|
const before = text.substring(lastIdx, match.index);
|
|
14861
|
-
result += stripThoughts ? before.replace(
|
|
15206
|
+
result += stripThoughts ? before.replace(RE_STRIP_THINK_SIMPLE, "") : before;
|
|
14862
15207
|
const startIdx = match.index + match[0].length - 1;
|
|
14863
15208
|
let balance = 0;
|
|
14864
15209
|
let inString = null;
|
|
@@ -14904,12 +15249,13 @@ ${originalTextProcessed.length > USER_CONTEXT_LENGTH ? "... (truncated) ...\n\n"
|
|
|
14904
15249
|
}
|
|
14905
15250
|
}
|
|
14906
15251
|
if (lastIdx < text.length) {
|
|
14907
|
-
result += stripThoughts ? text.substring(lastIdx).replace(
|
|
15252
|
+
result += stripThoughts ? text.substring(lastIdx).replace(RE_STRIP_THINK_SIMPLE, "") : text.substring(lastIdx);
|
|
14908
15253
|
}
|
|
14909
15254
|
return result;
|
|
14910
15255
|
};
|
|
14911
15256
|
contextSafeReplace = (text, regex, replacement) => {
|
|
14912
|
-
const toolRegex =
|
|
15257
|
+
const toolRegex = RE_TOOL_CALL_FUNC;
|
|
15258
|
+
toolRegex.lastIndex = 0;
|
|
14913
15259
|
let result = "";
|
|
14914
15260
|
let lastIdx = 0;
|
|
14915
15261
|
let match;
|
|
@@ -14992,8 +15338,8 @@ ${originalTextProcessed.length > USER_CONTEXT_LENGTH ? "... (truncated) ...\n\n"
|
|
|
14992
15338
|
const toPascalCase = (str) => {
|
|
14993
15339
|
return str.split("_").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join("");
|
|
14994
15340
|
};
|
|
14995
|
-
|
|
14996
|
-
let result = text.replace(
|
|
15341
|
+
RE_KIMI_TOOL_CALL.lastIndex = 0;
|
|
15342
|
+
let result = text.replace(RE_KIMI_TOOL_CALL, (match, toolName, argsJsonStr) => {
|
|
14997
15343
|
let parsedArgs = "";
|
|
14998
15344
|
try {
|
|
14999
15345
|
const argsObj = JSON.parse(argsJsonStr.trim());
|
|
@@ -15006,7 +15352,8 @@ ${originalTextProcessed.length > USER_CONTEXT_LENGTH ? "... (truncated) ...\n\n"
|
|
|
15006
15352
|
}
|
|
15007
15353
|
} catch (e) {
|
|
15008
15354
|
const pairs = [];
|
|
15009
|
-
const pairRegex =
|
|
15355
|
+
const pairRegex = RE_KIMI_JSON_PAIR;
|
|
15356
|
+
pairRegex.lastIndex = 0;
|
|
15010
15357
|
let pMatch;
|
|
15011
15358
|
while ((pMatch = pairRegex.exec(argsJsonStr)) !== null) {
|
|
15012
15359
|
const key = pMatch[1];
|
|
@@ -15023,8 +15370,10 @@ ${originalTextProcessed.length > USER_CONTEXT_LENGTH ? "... (truncated) ...\n\n"
|
|
|
15023
15370
|
const normToolName = PASCAL_MAP[cleanKey] || toPascalCase(toolName);
|
|
15024
15371
|
return `[tool:functions.${normToolName}(${parsedArgs})]`;
|
|
15025
15372
|
});
|
|
15026
|
-
|
|
15027
|
-
|
|
15373
|
+
RE_KIMI_SECTION_BEGIN.lastIndex = 0;
|
|
15374
|
+
RE_KIMI_SECTION_END.lastIndex = 0;
|
|
15375
|
+
result = result.replace(RE_KIMI_SECTION_BEGIN, "");
|
|
15376
|
+
result = result.replace(RE_KIMI_SECTION_END, "");
|
|
15028
15377
|
return result;
|
|
15029
15378
|
};
|
|
15030
15379
|
REGEX_PLACEHOLDER_ARG = /(?:path|query|url|keyword|command|method|title|task|id)\s*=\s*['"`]?\s*\.\.\.\s*['"`]?/i;
|
|
@@ -15037,18 +15386,21 @@ ${originalTextProcessed.length > USER_CONTEXT_LENGTH ? "... (truncated) ...\n\n"
|
|
|
15037
15386
|
detectToolCalls = (text) => {
|
|
15038
15387
|
if (!text) return [];
|
|
15039
15388
|
const translatedText = translateKimiToolCalls(text);
|
|
15040
|
-
|
|
15389
|
+
RE_STRIP_THINK_FULL.lastIndex = 0;
|
|
15390
|
+
const cleanText = translatedText.replace(RE_STRIP_THINK_FULL, "");
|
|
15041
15391
|
const results = [];
|
|
15042
|
-
const
|
|
15392
|
+
const scanText = bypassBacktick2 ? cleanText : cleanText.replace(RE_BACKTICK_SPAN, (m) => " ".repeat(m.length)).replace(RE_BACKTICK_OPEN, (m) => " ".repeat(m.length));
|
|
15393
|
+
const toolRegex = RE_TOOL_CALL_ANY;
|
|
15394
|
+
toolRegex.lastIndex = 0;
|
|
15043
15395
|
let match;
|
|
15044
|
-
while ((match = toolRegex.exec(
|
|
15396
|
+
while ((match = toolRegex.exec(scanText)) !== null) {
|
|
15045
15397
|
const toolName = match[1];
|
|
15046
15398
|
const startIdx = match.index + match[0].length - 1;
|
|
15047
15399
|
let balance = 0;
|
|
15048
15400
|
let inString = null;
|
|
15049
15401
|
let endIdx = -1;
|
|
15050
15402
|
let closingParenIdx = -1;
|
|
15051
|
-
for (let i = startIdx; i <
|
|
15403
|
+
for (let i = startIdx; i < scanText.length; i++) {
|
|
15052
15404
|
const char = cleanText[i];
|
|
15053
15405
|
if (inString) {
|
|
15054
15406
|
if (char === inString) {
|
|
@@ -15070,8 +15422,8 @@ ${originalTextProcessed.length > USER_CONTEXT_LENGTH ? "... (truncated) ...\n\n"
|
|
|
15070
15422
|
if (balance === 0) {
|
|
15071
15423
|
closingParenIdx = i;
|
|
15072
15424
|
let j = i + 1;
|
|
15073
|
-
while (j <
|
|
15074
|
-
if (j <
|
|
15425
|
+
while (j < scanText.length && /\s/.test(scanText[j])) j++;
|
|
15426
|
+
if (j < scanText.length && scanText[j] === "]") {
|
|
15075
15427
|
endIdx = j;
|
|
15076
15428
|
break;
|
|
15077
15429
|
}
|
|
@@ -15126,7 +15478,6 @@ ${originalTextProcessed.length > USER_CONTEXT_LENGTH ? "... (truncated) ...\n\n"
|
|
|
15126
15478
|
}
|
|
15127
15479
|
};
|
|
15128
15480
|
}
|
|
15129
|
-
return client;
|
|
15130
15481
|
};
|
|
15131
15482
|
generateSimpleContent = async (settings, model, contents, systemInstruction, thinkingLevel = "Fast", temperature = 0.75, usageKey = "agent") => {
|
|
15132
15483
|
return withRetry(async () => {
|
|
@@ -15153,7 +15504,8 @@ ${originalTextProcessed.length > USER_CONTEXT_LENGTH ? "... (truncated) ...\n\n"
|
|
|
15153
15504
|
} else if (aiProvider === "NVIDIA") {
|
|
15154
15505
|
stream = getNVIDIAStream(apiKey, model, normalizedContents, systemInstruction, thinkingLevel, mode, isModelMultimodal(model), signal, temperature);
|
|
15155
15506
|
} else {
|
|
15156
|
-
const
|
|
15507
|
+
const googleClient = getGoogleClient(apiKey);
|
|
15508
|
+
const genStream = await googleClient.models.generateContentStream({
|
|
15157
15509
|
model,
|
|
15158
15510
|
contents: normalizedContents,
|
|
15159
15511
|
config: {
|
|
@@ -16058,7 +16410,7 @@ OS: ${osDetected}${systemSettings?.dynamicDirAwareness ? dirStructure : ""}${cwd
|
|
|
16058
16410
|
WARNING: CWD Changed from previous: "${lastCwd}" to current: "${process.cwd()}", write change in chat to avoid future path mismatches
|
|
16059
16411
|
` : ""}${memoryPrompt}${ideBlock}
|
|
16060
16412
|
[/METADATA]
|
|
16061
|
-
${activeSummaryBlock}${thinkingLevel !== "Fast" && (aiProvider === "Mistral" || thinkingLevel !== "xHigh" && aiProvider === "Google") ? `${aiProvider === "Mistral" || modelName.toLowerCase().startsWith("gemma") ? "[SYSTEM] **STRICTLY FOLLOW THINKING POLICY AS HIGH PRIORITY. DO NOT START A RESPONSE WITHOUT <think> ... </think>** [/SYSTEM]\n" : ""}` : ""}[SYSTEM Priority: HIGH] ONLY use the system prompt tool schema [tool:functions.ToolName(
|
|
16413
|
+
${activeSummaryBlock}${thinkingLevel !== "Fast" && (aiProvider === "Mistral" || thinkingLevel !== "xHigh" && aiProvider === "Google") ? `${aiProvider === "Mistral" || modelName.toLowerCase().startsWith("gemma") ? "[SYSTEM] **STRICTLY FOLLOW THINKING POLICY AS HIGH PRIORITY. DO NOT START A RESPONSE WITHOUT <think> ... </think>** [/SYSTEM]\n" : ""}` : ""}[SYSTEM Priority: HIGH] ONLY use the system prompt tool schema [tool:functions.ToolName(arg1="value1")] [/SYSTEM]
|
|
16062
16414
|
${taggedContextStr}[USER PROMPT]
|
|
16063
16415
|
${cleanPromptForModel.trim()}
|
|
16064
16416
|
[/USER PROMPT]`.trim();
|
|
@@ -16093,10 +16445,31 @@ ${cleanPromptForModel.trim()}
|
|
|
16093
16445
|
yield { type: "status", content: "Working" };
|
|
16094
16446
|
}
|
|
16095
16447
|
if (TERMINATION_SIGNAL) {
|
|
16448
|
+
try {
|
|
16449
|
+
const { clearPendingNudges: clearPendingNudges2 } = await Promise.resolve().then(() => (init_subagent_state(), subagent_state_exports));
|
|
16450
|
+
clearPendingNudges2();
|
|
16451
|
+
} catch (e) {
|
|
16452
|
+
}
|
|
16096
16453
|
yield { type: "status", content: "Request Cancelled" };
|
|
16097
16454
|
yield { type: "text", content: "\n\n\x1B[33m\u24D8 Request Cancelled\x1B[0m" };
|
|
16098
16455
|
break;
|
|
16099
16456
|
}
|
|
16457
|
+
try {
|
|
16458
|
+
const { consumePendingNudges: consumePendingNudges2 } = await Promise.resolve().then(() => (init_subagent_state(), subagent_state_exports));
|
|
16459
|
+
const pendingNudges = consumePendingNudges2();
|
|
16460
|
+
if (pendingNudges && pendingNudges.length > 0) {
|
|
16461
|
+
const combinedNudge = pendingNudges.join("\n\n");
|
|
16462
|
+
if (modifiedHistory.length > 0 && modifiedHistory[modifiedHistory.length - 1].role === "user") {
|
|
16463
|
+
modifiedHistory[modifiedHistory.length - 1].text += `
|
|
16464
|
+
|
|
16465
|
+
${combinedNudge}`;
|
|
16466
|
+
} else {
|
|
16467
|
+
modifiedHistory.push({ role: "user", text: combinedNudge });
|
|
16468
|
+
}
|
|
16469
|
+
yield { type: "status", content: "Subagent Update" };
|
|
16470
|
+
}
|
|
16471
|
+
} catch (e) {
|
|
16472
|
+
}
|
|
16100
16473
|
if (steeringCallback) {
|
|
16101
16474
|
const hint = await steeringCallback();
|
|
16102
16475
|
if (hint) {
|
|
@@ -16358,7 +16731,8 @@ ${ideErr} [/ERROR]`;
|
|
|
16358
16731
|
);
|
|
16359
16732
|
stream = wrapNvidiaStreamWithQueueDepth(rawStream, targetModel);
|
|
16360
16733
|
} else {
|
|
16361
|
-
const
|
|
16734
|
+
const googleClient = getGoogleClient(settings?.apiKey);
|
|
16735
|
+
const apiCallPromise = googleClient.models.generateContentStream({
|
|
16362
16736
|
model: targetModel || "gemini-3-flash-preview",
|
|
16363
16737
|
contents: activeContents,
|
|
16364
16738
|
config: {
|
|
@@ -16699,19 +17073,19 @@ ${ideErr} [/ERROR]`;
|
|
|
16699
17073
|
"getProgress": "get_progress",
|
|
16700
17074
|
"GetProgress": "get_progress",
|
|
16701
17075
|
"Cancel": "cancel",
|
|
16702
|
-
"
|
|
16703
|
-
"
|
|
17076
|
+
"Await": "await",
|
|
17077
|
+
"Answer": "answer"
|
|
16704
17078
|
};
|
|
16705
17079
|
const potentialTool = NORMALIZE_MAP[toolContext.toolName] || toolContext.toolName;
|
|
16706
17080
|
const partialArgs = toolContext.args || "";
|
|
16707
17081
|
let detail = null;
|
|
16708
|
-
if (["write_file", "update_file", "view_file", "read_folder", "write_pdf", "write_docx", "search_keyword", "generate_image", "file_map", "invoke", "invoke_sync", "get_progress", "await"].includes(potentialTool)) {
|
|
17082
|
+
if (["write_file", "update_file", "view_file", "read_folder", "write_pdf", "write_docx", "search_keyword", "generate_image", "file_map", "invoke", "invoke_sync", "get_progress", "await", "answer"].includes(potentialTool)) {
|
|
16709
17083
|
const pArgs = parseArgs(partialArgs);
|
|
16710
17084
|
const filePath = pArgs.path || pArgs.targetFile || pArgs.TargetFile || pArgs.directory;
|
|
16711
17085
|
const keyword = pArgs.keyword;
|
|
16712
17086
|
const title = pArgs.title || pArgs.task;
|
|
16713
17087
|
const id = pArgs.id || pArgs.taskId;
|
|
16714
|
-
const timeVal = pArgs.time;
|
|
17088
|
+
const timeVal = pArgs.timeout || pArgs.time;
|
|
16715
17089
|
if (keyword !== void 0 && keyword !== null) {
|
|
16716
17090
|
detail = String(keyword).replace(RE_STRIP_QUOTES, "");
|
|
16717
17091
|
} else if (filePath) {
|
|
@@ -16778,17 +17152,19 @@ ${ideErr} [/ERROR]`;
|
|
|
16778
17152
|
"Ask": "User Input Required",
|
|
16779
17153
|
"Memory": "Updating Memory",
|
|
16780
17154
|
"GenerateImage": "Generating",
|
|
16781
|
-
"InvokeSync": "
|
|
16782
|
-
"invoke_sync": "
|
|
16783
|
-
"Invoke": "
|
|
16784
|
-
"invoke": "
|
|
17155
|
+
"InvokeSync": "Sub-Agent Working",
|
|
17156
|
+
"invoke_sync": "Sub-Agent Working",
|
|
17157
|
+
"Invoke": "Working",
|
|
17158
|
+
"invoke": "Working",
|
|
16785
17159
|
"GetProgress": "Checking Progress",
|
|
16786
17160
|
"get_progress": "Checking Progress",
|
|
16787
17161
|
"Cancel": "Stopping Generalist",
|
|
16788
17162
|
"cancel": "Stopping Generalist",
|
|
16789
17163
|
"Await": "Waiting",
|
|
16790
17164
|
"await": "Waiting",
|
|
16791
|
-
"EmergencyRollback": "Rolling the Ball"
|
|
17165
|
+
"EmergencyRollback": "Rolling the Ball",
|
|
17166
|
+
"Answer": "Answering Sub-Agent",
|
|
17167
|
+
"answer": "Answering Sub-Agent"
|
|
16792
17168
|
};
|
|
16793
17169
|
const toolTitle = TOOL_TITLES[potentialTool] || "Working";
|
|
16794
17170
|
process.stdout.write(`\x1B]0;${toolTitle}...\x07`);
|
|
@@ -16920,14 +17296,20 @@ ${ideErr} [/ERROR]`;
|
|
|
16920
17296
|
"generate_image": "generate_image",
|
|
16921
17297
|
"todo": "todo",
|
|
16922
17298
|
"Todo": "todo",
|
|
16923
|
-
"
|
|
17299
|
+
"Invoke": "invoke",
|
|
16924
17300
|
"InvokeSync": "invoke_sync",
|
|
16925
17301
|
"getProgress": "get_progress",
|
|
16926
17302
|
"GetProgress": "get_progress",
|
|
17303
|
+
"Await": "await",
|
|
17304
|
+
"await": "await",
|
|
17305
|
+
"AwaitSubagent": "await",
|
|
17306
|
+
"awaitSubagent": "await",
|
|
17307
|
+
"Answer": "answer",
|
|
17308
|
+
"answer": "answer",
|
|
17309
|
+
"AnswerSubagent": "answer",
|
|
17310
|
+
"answerSubagent": "answer",
|
|
16927
17311
|
"Cancel": "cancel",
|
|
16928
17312
|
"cancel": "cancel",
|
|
16929
|
-
"await": "await",
|
|
16930
|
-
"Await": "await",
|
|
16931
17313
|
"EmergencyRollback": "EmergencyRollback"
|
|
16932
17314
|
};
|
|
16933
17315
|
const normToolName = NORMALIZE_MAP[toolCall.toolName] || toolCall.toolName;
|
|
@@ -17013,10 +17395,9 @@ ${ideErr} [/ERROR]`;
|
|
|
17013
17395
|
const { method } = parseArgs(toolCall.args);
|
|
17014
17396
|
label = method === "forceRevert" ? "" : "\u2714 Rollback Point Checked";
|
|
17015
17397
|
} else if (normToolName === "await" || normToolName === "Await") {
|
|
17016
|
-
const { time } = parseArgs(toolCall.args);
|
|
17017
|
-
let sec = parseFloat(time) || 0;
|
|
17018
|
-
if (sec
|
|
17019
|
-
if (sec > 180) sec = 180;
|
|
17398
|
+
const { time, timeout } = parseArgs(toolCall.args);
|
|
17399
|
+
let sec = parseFloat(timeout || time) || 0;
|
|
17400
|
+
if (!sec) sec = 120;
|
|
17020
17401
|
const formatTime = (s) => {
|
|
17021
17402
|
if (s >= 60) {
|
|
17022
17403
|
const m = Math.floor(s / 60);
|
|
@@ -17055,6 +17436,8 @@ ${ideErr} [/ERROR]`;
|
|
|
17055
17436
|
];
|
|
17056
17437
|
let randomVibe = existentialVibes[Math.floor(Math.random() * existentialVibes.length)];
|
|
17057
17438
|
label = `\u2714 ${randomVibe} \u2192 ${formatTime(sec)}`;
|
|
17439
|
+
} else if (normToolName === "Answer" || normToolName === "answer") {
|
|
17440
|
+
label = "\u2714 Resolved Sub-Agent Query";
|
|
17058
17441
|
} else if (normToolName === "exec_command" || normToolName === "ask") {
|
|
17059
17442
|
label = "";
|
|
17060
17443
|
} else {
|
|
@@ -17983,7 +18366,7 @@ ${snippet2}`;
|
|
|
17983
18366
|
const waitTime = Math.min(1e3 * Math.pow(2, inStreamRetryCount - 1), 24e3);
|
|
17984
18367
|
if (turnText.trim().length > 0) {
|
|
17985
18368
|
modifiedHistory.push({ role: "agent", text: turnText });
|
|
17986
|
-
const recoveryText = "[SYSTEM]\n- SEAMLESS CONTINUATION: Resume immediately. Pick up from last words with zero gap/disruption\n- NO REPETITION: Do not repeat any text already written\n- NO RE-THINK: Do not restart or open <think> if reasoning already started. Continue the thinking and close thinking block </think>
|
|
18369
|
+
const recoveryText = "[SYSTEM]\n- SEAMLESS CONTINUATION: Resume immediately. Pick up from last words with zero gap/disruption\n- NO REPETITION: Do not repeat any text already written\n- NO RE-THINK: Do not restart or open <think> if reasoning already started. Continue the thinking and close thinking block </think> BEFORE CHAT OUTPUT\n- MID-TOOL SAFETY: If cutoff was mid-tool call, restart that tool call from start\n- STEALTH: Do not mention/apologize for cutoff [/SYSTEM]";
|
|
17987
18370
|
if (toolResults.length > 0) {
|
|
17988
18371
|
toolResults.forEach((tr, idx) => {
|
|
17989
18372
|
if (idx === toolResults.length - 1) {
|
|
@@ -18176,7 +18559,7 @@ Error Log can be found in ${path26.join(LOGS_DIR, "agent", "error.log")}`);
|
|
|
18176
18559
|
}
|
|
18177
18560
|
yield { type: "status", content: null };
|
|
18178
18561
|
};
|
|
18179
|
-
runSubagent = async (task, settings, model = null, allowedTools = null, maxTurns = 50, logCallback = null) => {
|
|
18562
|
+
runSubagent = async (task, settings, model = null, allowedTools = null, maxTurns = 50, logCallback = null, isAsync = false) => {
|
|
18180
18563
|
const savedSettings = await loadSettings();
|
|
18181
18564
|
const mergedSettings = { ...savedSettings, ...settings };
|
|
18182
18565
|
const envSubagentModel = process.env.SUBAGENT_MODEL ? process.env.SUBAGENT_MODEL.trim() : null;
|
|
@@ -18250,22 +18633,20 @@ Error Log can be found in ${path26.join(LOGS_DIR, "agent", "error.log")}`);
|
|
|
18250
18633
|
const targetModel = model || subAgentCustomModel || settings?.modelName || settings?.activeModel || savedSettings.activeModel;
|
|
18251
18634
|
const osDetected = process.platform === "win32" ? "Windows" : process.platform === "darwin" ? "macOS" : "Linux";
|
|
18252
18635
|
const providedToolsSection = `-- TOOL DEFINITIONS (path = relative to CWD, path separator: '/') --
|
|
18253
|
-
TO ACCESS TOOLS **STRICTLY USE THE EXACT FORMAT IN CHAT OUTPUT:** [tool:functions.ToolName(
|
|
18254
|
-
**NO OTHER SYNTAX/MARKERS/BOUNDARY ALLOWED**
|
|
18636
|
+
TO ACCESS TOOLS **STRICTLY USE THE EXACT FORMAT IN CHAT OUTPUT:** [tool:functions.ToolName(arg1="value1")]
|
|
18637
|
+
**NO OTHER SYNTAX/MARKERS/WRAPPER/BOUNDARY ALLOWED**
|
|
18255
18638
|
|
|
18256
18639
|
TOOL POLICY:
|
|
18257
|
-
-
|
|
18258
|
-
- Double-escape literal sequences (eg. \\\\n)
|
|
18259
|
-
- Use real newlines for code formatting
|
|
18640
|
+
- JSON ESCAPE ALL LITERAL ESCAPE SEQUENCES IN TOOL ARGUMENTS
|
|
18260
18641
|
- SAME file, MULTIPLE edits? ONE PatchFile (\u226415 blocks) \u2190 PRIORITY
|
|
18261
|
-
- Tool denied? Ask for guidance \u2190 MANDATORY
|
|
18262
18642
|
- Need text or huge files? SearchKeyword > Full Read
|
|
18263
|
-
- Update Todos from realtime progress each turn
|
|
18264
18643
|
- Restricted Shell Access, No Deletion
|
|
18644
|
+
- ONLY valid tools and syntax defined below are allowed
|
|
18265
18645
|
|
|
18266
18646
|
**PROVIDED TOOLS**
|
|
18267
|
-
-- Communication
|
|
18268
|
-
- [tool:functions.Ask(question="...", optionA="
|
|
18647
|
+
-- Communication Tools --
|
|
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` : ""}
|
|
18269
18650
|
|
|
18270
18651
|
-- Web Tools --
|
|
18271
18652
|
- [tool:functions.WebSearch(query="...", aiMode="bool optional, default: false", limit="integer 3-10, aiMode: exclude")]. Usage: unknown info/docs. aiMode: LLM search
|
|
@@ -18275,10 +18656,10 @@ TOOL POLICY:
|
|
|
18275
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
|
|
18276
18657
|
- [tool:functions.ReadFolder(path="...", recurse="integer 1-3 optional, default: 1")]. DIR Contents + File Size. Minimize recursion
|
|
18277
18658
|
- [tool:functions.ReadFile(path="...", startLine="integer", endLine="integer")]. View files
|
|
18278
|
-
- [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
|
|
18279
18660
|
- [tool:functions.WriteFile(path="...", content="...")]. Creates/Overwrites. File Exist? PatchFile > WriteFile. VERIFY IMPORTS
|
|
18280
18661
|
- [tool:functions.Run(command="...")]. Runs ${osDetected === "Windows" ? isPsAvailable() ? `WINDOWS POWERSHELL` : `WINDOWS CMD` : `BASH`} command. Destructive/Irreversible ops \u2192 Ask user`.trim();
|
|
18281
|
-
const
|
|
18662
|
+
const systemInstructionSubAgent = `=== START SYSTEM PROMPT ===
|
|
18282
18663
|
You are a subagent helping the main FluxFlow CLI agent
|
|
18283
18664
|
Your task is: "${task}"
|
|
18284
18665
|
|
|
@@ -18317,8 +18698,8 @@ Current Time: ${time}
|
|
|
18317
18698
|
role: m.role === "user" ? "user" : "model",
|
|
18318
18699
|
parts: [{ text: m.text }]
|
|
18319
18700
|
}));
|
|
18320
|
-
if (logCallback) logCallback(`[Subagent Turn ${turn + 1}]
|
|
18321
|
-
const response = await generateSimpleContent(mergedSettings, targetModel, contents,
|
|
18701
|
+
if (logCallback) logCallback(`[Subagent Turn ${turn + 1}]...`);
|
|
18702
|
+
const response = await generateSimpleContent(mergedSettings, targetModel, contents, systemInstructionSubAgent, "Fast");
|
|
18322
18703
|
const responseText = response.text || "";
|
|
18323
18704
|
const cleanResponse = responseText.replace(/(?:<think>|\[think\])[\s\S]*?(?:<\/think>|\[\/think\])/gi, "").trim();
|
|
18324
18705
|
finalAnswer = cleanResponse;
|
|
@@ -18330,6 +18711,8 @@ ${cleanResponse}
|
|
|
18330
18711
|
if (toolCalls.length === 0) {
|
|
18331
18712
|
break;
|
|
18332
18713
|
}
|
|
18714
|
+
const askMainCalls = toolCalls.filter((tc) => tc.toolName.toLowerCase() === "askmain" || tc.toolName.toLowerCase() === "ask_main");
|
|
18715
|
+
let processedAskMainInTurn = false;
|
|
18333
18716
|
let toolResultsStr = "";
|
|
18334
18717
|
for (const toolCall of toolCalls) {
|
|
18335
18718
|
if (TERMINATION_SIGNAL) {
|
|
@@ -18346,6 +18729,36 @@ ${cleanResponse}
|
|
|
18346
18729
|
}
|
|
18347
18730
|
}
|
|
18348
18731
|
const normalizedToolName = toolCall.toolName.toLowerCase();
|
|
18732
|
+
if (normalizedToolName === "askmain" || normalizedToolName === "ask_main") {
|
|
18733
|
+
if (processedAskMainInTurn) continue;
|
|
18734
|
+
processedAskMainInTurn = true;
|
|
18735
|
+
let questionText = "";
|
|
18736
|
+
if (askMainCalls.length === 1) {
|
|
18737
|
+
const pArgs = parseArgs(askMainCalls[0].args);
|
|
18738
|
+
questionText = pArgs.question || askMainCalls[0].args;
|
|
18739
|
+
} else {
|
|
18740
|
+
questionText = askMainCalls.map((tc, idx) => {
|
|
18741
|
+
const pArgs = parseArgs(tc.args);
|
|
18742
|
+
return `Q${idx + 1}: ${pArgs.question || tc.args}`;
|
|
18743
|
+
}).join("\n");
|
|
18744
|
+
}
|
|
18745
|
+
if (settings.onAskMain) {
|
|
18746
|
+
if (logCallback) logCallback(`[Executing Tool] AskMain("${questionText}")...`);
|
|
18747
|
+
const answer = await settings.onAskMain(questionText);
|
|
18748
|
+
if (logCallback) logCallback(`[Tool Result]
|
|
18749
|
+
Answer from Main Agent: ${answer}
|
|
18750
|
+
`);
|
|
18751
|
+
toolResultsStr += `[TOOL RESULT for AskMain]: Answer from Main Agent: ${answer}
|
|
18752
|
+
|
|
18753
|
+
`;
|
|
18754
|
+
await incrementUsage("toolSuccess");
|
|
18755
|
+
} else {
|
|
18756
|
+
toolResultsStr += `[TOOL RESULT for AskMain]: ERROR: Main agent communication channel not available.
|
|
18757
|
+
|
|
18758
|
+
`;
|
|
18759
|
+
}
|
|
18760
|
+
continue;
|
|
18761
|
+
}
|
|
18349
18762
|
const allowed = allowedTools ? allowedTools.some((t) => t.toLowerCase() === normalizedToolName) : true;
|
|
18350
18763
|
if (!allowed) {
|
|
18351
18764
|
const errorMsg = `ERROR: Tool [${toolCall.toolName}] is not in the allowed tools list for this subagent.`;
|
|
@@ -22601,10 +23014,27 @@ Selection: ${val}`,
|
|
|
22601
23014
|
commitActiveStreamingMessage();
|
|
22602
23015
|
inThinkMode = true;
|
|
22603
23016
|
thinkConsumedInTurn = true;
|
|
22604
|
-
let thinkStartText = afterText.replace(/<(think|thought)>/gi, "");
|
|
22605
23017
|
currentThinkId = "think-" + Date.now();
|
|
22606
23018
|
activeStreamingMsgRef.current = { id: currentThinkId, role: "think", text: "", isStreaming: true, startTime: Date.now() };
|
|
22607
|
-
|
|
23019
|
+
if (afterText.match(/<\/(think|thought)>/i)) {
|
|
23020
|
+
const parts = afterText.split(/<\/(think|thought)>/i);
|
|
23021
|
+
const rawThinkContent = parts[0] || "";
|
|
23022
|
+
const thinkContent = rawThinkContent.replace(/^<(think|thought)>/i, "");
|
|
23023
|
+
const agentContent = parts.slice(2).join("").replace(/<\/?(think|thought)>/gi, "");
|
|
23024
|
+
activeStreamingMsgRef.current.text = flattenString(thinkContent);
|
|
23025
|
+
const startTime = activeStreamingMsgRef.current.startTime || Date.now();
|
|
23026
|
+
activeStreamingMsgRef.current.duration = Date.now() - startTime;
|
|
23027
|
+
commitActiveStreamingMessage();
|
|
23028
|
+
inThinkMode = false;
|
|
23029
|
+
currentAgentId = "agent-" + Date.now();
|
|
23030
|
+
activeStreamingMsgRef.current = { id: currentAgentId, role: "agent", text: "", isStreaming: true };
|
|
23031
|
+
if (agentContent) {
|
|
23032
|
+
appendStreamText(agentContent);
|
|
23033
|
+
}
|
|
23034
|
+
} else {
|
|
23035
|
+
let thinkStartText = afterText.replace(/^<(think|thought)>/gi, "");
|
|
23036
|
+
appendStreamText(thinkStartText);
|
|
23037
|
+
}
|
|
22608
23038
|
continue;
|
|
22609
23039
|
}
|
|
22610
23040
|
if ((chunkLower.includes("</think>") || chunkLower.includes("</thought>")) && activeStreamingMsgRef.current?.role === "think") {
|
package/model_config.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 0,
|
|
3
|
-
"release":
|
|
3
|
+
"release": 20260803,
|
|
4
4
|
"fallbacks": {
|
|
5
5
|
"janitor_default": "gemini-3.1-flash-lite",
|
|
6
6
|
"janitor_attempts_fallback": "gemma-4-26b-a4b-it",
|
|
@@ -363,7 +363,7 @@
|
|
|
363
363
|
{
|
|
364
364
|
"cmd": "google/diffusiongemma-26b-a4b-it",
|
|
365
365
|
"multimodal": false,
|
|
366
|
-
"desc": "Mega Fast
|
|
366
|
+
"desc": "Mega Fast"
|
|
367
367
|
},
|
|
368
368
|
{
|
|
369
369
|
"cmd": "\n--- Mistral Models ---",
|
|
@@ -495,7 +495,7 @@
|
|
|
495
495
|
{
|
|
496
496
|
"cmd": "google/diffusiongemma-26b-a4b-it",
|
|
497
497
|
"multimodal": false,
|
|
498
|
-
"desc": "Mega Fast
|
|
498
|
+
"desc": "Mega Fast"
|
|
499
499
|
},
|
|
500
500
|
{
|
|
501
501
|
"cmd": "\n--- Mistral Models ---",
|