fluxflow-cli 3.16.6 → 3.17.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 +460 -114
- 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, 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();
|
|
@@ -3345,12 +3345,20 @@ var init_text = __esm({
|
|
|
3345
3345
|
};
|
|
3346
3346
|
REGEX_INITIAL_THINK = /<\/think>(\r?\n){2}/gi;
|
|
3347
3347
|
REGEX_INITIAL_TOOL = /(\r?\n){2}(?=\[?(?:tool:functions|tool\.functions|agent:generalist|agent\.generalist|\s*turn\s*:))/gi;
|
|
3348
|
+
isInsideBacktick = (str, idx) => {
|
|
3349
|
+
let inCode = false;
|
|
3350
|
+
for (let i = 0; i < idx; i++) {
|
|
3351
|
+
if (str[i] === "`") inCode = !inCode;
|
|
3352
|
+
}
|
|
3353
|
+
return inCode;
|
|
3354
|
+
};
|
|
3348
3355
|
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
3356
|
REGEX_ARROWS_ALL = /(\$?\\?\/?\\rightarrow\$?|\$\\rightarrow\$)|(\$?\\?\/?\\leftarrow\$?|\$\\leftarrow\$)|(\$?\\?\/?\\uparrow\$?|\$\\uparrow\$)|(\$?\\?\/?\\downarrow\$?|\$\\downarrow\$)|(\$?\\?\/?\\leftrightarrow\$?|\$\\leftrightarrow\$)/gi;
|
|
3350
3357
|
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;
|
|
3358
|
+
bypassBacktick = false;
|
|
3351
3359
|
cleanSignals = (text) => {
|
|
3352
3360
|
if (!text) return text;
|
|
3353
|
-
let result = text.replace(REGEX_INITIAL_THINK, "</think>").replace(REGEX_INITIAL_TOOL, "");
|
|
3361
|
+
let result = text.replace(REGEX_INITIAL_THINK, "</think>").replace(REGEX_INITIAL_TOOL, (match, _nl, offset, str) => !bypassBacktick && isInsideBacktick(str, offset) ? match : "");
|
|
3354
3362
|
const trigger = "tool:functions.";
|
|
3355
3363
|
const subagentTrigger = "agent:generalist.";
|
|
3356
3364
|
if (result.toLowerCase().includes(trigger) || result.toLowerCase().includes(subagentTrigger)) {
|
|
@@ -3365,6 +3373,35 @@ var init_text = __esm({
|
|
|
3365
3373
|
triggerIdxToUse = subagentIdx;
|
|
3366
3374
|
}
|
|
3367
3375
|
if (triggerIdxToUse === -1) break;
|
|
3376
|
+
if (!bypassBacktick && isInsideBacktick(result, triggerIdxToUse)) {
|
|
3377
|
+
const searchFrom = triggerIdxToUse + currentTrigger.length;
|
|
3378
|
+
const nextTool = lowerResult.indexOf(trigger, searchFrom);
|
|
3379
|
+
const nextAgent = lowerResult.indexOf(subagentTrigger, searchFrom);
|
|
3380
|
+
if (nextTool === -1 && nextAgent === -1) break;
|
|
3381
|
+
let safeIdx = -1;
|
|
3382
|
+
let searchPos = 0;
|
|
3383
|
+
while (true) {
|
|
3384
|
+
const tIdx = lowerResult.indexOf(trigger, searchPos);
|
|
3385
|
+
const aIdx = lowerResult.indexOf(subagentTrigger, searchPos);
|
|
3386
|
+
let candidate = -1;
|
|
3387
|
+
let candidateTrigger = trigger;
|
|
3388
|
+
if (tIdx === -1 && aIdx === -1) break;
|
|
3389
|
+
if (tIdx === -1 || aIdx !== -1 && aIdx < tIdx) {
|
|
3390
|
+
candidate = aIdx;
|
|
3391
|
+
candidateTrigger = subagentTrigger;
|
|
3392
|
+
} else {
|
|
3393
|
+
candidate = tIdx;
|
|
3394
|
+
}
|
|
3395
|
+
if (!isInsideBacktick(result, candidate)) {
|
|
3396
|
+
safeIdx = candidate;
|
|
3397
|
+
currentTrigger = candidateTrigger;
|
|
3398
|
+
break;
|
|
3399
|
+
}
|
|
3400
|
+
searchPos = candidate + candidateTrigger.length;
|
|
3401
|
+
}
|
|
3402
|
+
if (safeIdx === -1) break;
|
|
3403
|
+
triggerIdxToUse = safeIdx;
|
|
3404
|
+
}
|
|
3368
3405
|
let startIdx = triggerIdxToUse;
|
|
3369
3406
|
let hasOuterBracket = false;
|
|
3370
3407
|
let k = triggerIdxToUse - 1;
|
|
@@ -6808,8 +6845,8 @@ var init_main_tools = __esm({
|
|
|
6808
6845
|
}
|
|
6809
6846
|
return `
|
|
6810
6847
|
-- TOOL DEFINITIONS --
|
|
6811
|
-
Tool calls: ONLY use [tool:functions.ToolName(
|
|
6812
|
-
**NO OTHER SYNTAX/MARKERS/BOUNDARY ALLOWED**
|
|
6848
|
+
Tool calls: ONLY use [tool:functions.ToolName(arg1="value1")]
|
|
6849
|
+
**NO OTHER SYNTAX/MARKERS/WRAPPER/BOUNDARY ALLOWED**
|
|
6813
6850
|
|
|
6814
6851
|
**TOOL CALLS POLICY:**
|
|
6815
6852
|
- MAX 4 TOOL CALLS/TURN${mode === "Flux" ? " (Todo: 4+, Run: max 1 or 2 consecutive)" : ""}
|
|
@@ -6830,25 +6867,26 @@ ${mode === "Flux" ? `- Escape quotes: \\" for code strings
|
|
|
6830
6867
|
|
|
6831
6868
|
${mode === "Flux" ? `- WORKSPACE TOOLS (path = relative; FIRST ARGUMENT, path separator: '/') -
|
|
6832
6869
|
- [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.
|
|
6870
|
+
- [tool:functions.ReadFolder(path="...", recurse="integer 1-3 optional, default: 1")]. DIR Contents + File Size. Minimize recursion
|
|
6834
6871
|
- [tool:functions.PatchFile(path="...", allowMultiple="bool optional, default: false", replaceContent1="...", newContent1="...", ...MAX15)]. TARGET MINIMAL DIFF. allowMultiple: Replace all matches ONLY WHEN SURE. Multi-blocks: replaceContent2/newContent2... Verify diffs
|
|
6835
6872
|
- [tool:functions.WriteFile(path="...", content="...")]. Creates/Overwrites. File Exist? PatchFile > WriteFile
|
|
6836
6873
|
- [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
6874
|
- [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
|
|
6875
|
+
- [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
6876
|
${_cachedAdvanceRollback ? `
|
|
6840
|
-
- EMERGENCY
|
|
6877
|
+
- EMERGENCY TOOLS -
|
|
6841
6878
|
Info: \`initial\` = current task prompt. Revert \`id\` = turn before disaster (eg. disaster: \`turn_3\` \u2192 revert: \`turn_2\`). Reason explicitly
|
|
6842
6879
|
- [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
6880
|
` : ""}${enableSubAgents ? `
|
|
6844
6881
|
- SUB AGENT TOOLS -
|
|
6845
6882
|
**PROACTIVE sub-agent use HIGHLY RECOMMENDED. Prefer for any task with even slight benefit, no user nudge needed**
|
|
6846
6883
|
Invocations:
|
|
6847
|
-
\u2022 Invoke (async/background, \u22647 parallel). Parallelize long tasks.
|
|
6884
|
+
\u2022 Invoke (async/background, \u22647 parallel). Parallelize long tasks. May take time
|
|
6848
6885
|
\u2022 InvokeSync (sync/blocking). Sequential, repetitive or delegated tasks. Saves tokens/cost
|
|
6849
|
-
- [
|
|
6850
|
-
- [
|
|
6851
|
-
- [
|
|
6886
|
+
- [tool:functions.InvokeSync/Invoke(title="...", task="...")]. Task must be detailed: exact file paths, imports/exports, dependencies & folder structure
|
|
6887
|
+
- [tool:functions.Await(id="...", timeout="integer seconds, default: 120")]. Event-driven wait
|
|
6888
|
+
- [tool:functions.GetProgress(id="...")]. Poll \`getProgress\` sparingly; NO initial poll. Work or await. Never end while subagent runs
|
|
6889
|
+
- [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
6890
|
- [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
6891
|
- [tool:functions.WriteDoc(path="...", content="...")]. A4 Word document, NO WATERMARKS, stable margins & headers/footers
|
|
6854
6892
|
- WORKSPACE & SUB AGENT TOOLS ARE NOT AVAILABLE IN FLOW`.trim()}`.trim();
|
|
@@ -8565,7 +8603,7 @@ Check these first; These Files > Training Data. Safety rules apply
|
|
|
8565
8603
|
Identity: Flux Flow. Sassy, CLI Agent
|
|
8566
8604
|
${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
8605
|
|
|
8568
|
-
-
|
|
8606
|
+
- USE DIRECTORY STRUCTURE FOR FILE AVAILABILITY AND PATH RESOLUTION
|
|
8569
8607
|
- USE RELATIVE TIME REFERENCE eg. few mins ago
|
|
8570
8608
|
|
|
8571
8609
|
-- THINKING GUIDANCE --
|
|
@@ -8585,7 +8623,7 @@ ${projectContextBlock}${isMemoryEnabled ? `
|
|
|
8585
8623
|
-- CHAT FORMATTING --
|
|
8586
8624
|
- GFM Markdown ONLY
|
|
8587
8625
|
- Same Language as User Query
|
|
8588
|
-
-
|
|
8626
|
+
- After tool calls emit no chat in this turn
|
|
8589
8627
|
- On completion: summarize changes (why) + edited files${mode === "Flux" ? "" : "\n- Use Kaomojis HEAVILY"}
|
|
8590
8628
|
=== END SYSTEM PROMPT ===
|
|
8591
8629
|
|
|
@@ -12493,10 +12531,33 @@ var init_invokeSync = __esm({
|
|
|
12493
12531
|
});
|
|
12494
12532
|
|
|
12495
12533
|
// src/utils/subagent_state.js
|
|
12496
|
-
var
|
|
12534
|
+
var subagent_state_exports = {};
|
|
12535
|
+
__export(subagent_state_exports, {
|
|
12536
|
+
addPendingNudge: () => addPendingNudge,
|
|
12537
|
+
clearPendingNudges: () => clearPendingNudges,
|
|
12538
|
+
consumePendingNudges: () => consumePendingNudges,
|
|
12539
|
+
pendingSubagentNudges: () => pendingSubagentNudges,
|
|
12540
|
+
subagentProgress: () => subagentProgress
|
|
12541
|
+
});
|
|
12542
|
+
var subagentProgress, pendingSubagentNudges, addPendingNudge, consumePendingNudges, clearPendingNudges;
|
|
12497
12543
|
var init_subagent_state = __esm({
|
|
12498
12544
|
"src/utils/subagent_state.js"() {
|
|
12499
12545
|
subagentProgress = [];
|
|
12546
|
+
pendingSubagentNudges = [];
|
|
12547
|
+
addPendingNudge = (msg) => {
|
|
12548
|
+
if (msg) {
|
|
12549
|
+
pendingSubagentNudges.push(msg);
|
|
12550
|
+
}
|
|
12551
|
+
};
|
|
12552
|
+
consumePendingNudges = () => {
|
|
12553
|
+
if (pendingSubagentNudges.length === 0) return [];
|
|
12554
|
+
const nudges = [...pendingSubagentNudges];
|
|
12555
|
+
pendingSubagentNudges = [];
|
|
12556
|
+
return nudges;
|
|
12557
|
+
};
|
|
12558
|
+
clearPendingNudges = () => {
|
|
12559
|
+
pendingSubagentNudges = [];
|
|
12560
|
+
};
|
|
12500
12561
|
}
|
|
12501
12562
|
});
|
|
12502
12563
|
|
|
@@ -12528,13 +12589,24 @@ var init_invoke = __esm({
|
|
|
12528
12589
|
}
|
|
12529
12590
|
}
|
|
12530
12591
|
const taskId = `subagent-${Date.now()}-${Math.floor(Math.random() * 1e3)}`;
|
|
12592
|
+
let _resolveCompletion = null;
|
|
12593
|
+
let _rejectCompletion = null;
|
|
12594
|
+
const completionPromise = new Promise((res, rej) => {
|
|
12595
|
+
_resolveCompletion = res;
|
|
12596
|
+
_rejectCompletion = rej;
|
|
12597
|
+
});
|
|
12531
12598
|
const taskEntry = {
|
|
12532
12599
|
id: taskId,
|
|
12533
12600
|
title: title || task.substring(0, 30),
|
|
12534
12601
|
task,
|
|
12535
12602
|
status: "running",
|
|
12603
|
+
startedAt: Date.now(),
|
|
12536
12604
|
lastChunkTime: Date.now(),
|
|
12537
12605
|
wps: 0,
|
|
12606
|
+
questions: [],
|
|
12607
|
+
completionPromise,
|
|
12608
|
+
_resolveCompletion,
|
|
12609
|
+
_rejectCompletion,
|
|
12538
12610
|
progress: []
|
|
12539
12611
|
// Array of arrays containing logs for each turn
|
|
12540
12612
|
};
|
|
@@ -12547,6 +12619,32 @@ var init_invoke = __esm({
|
|
|
12547
12619
|
const subagentContext = {
|
|
12548
12620
|
...context,
|
|
12549
12621
|
taskId,
|
|
12622
|
+
onAskMain: async (questionText, optionsObj) => {
|
|
12623
|
+
const questionId = `q-${Date.now()}-${Math.floor(Math.random() * 1e3)}`;
|
|
12624
|
+
let questionResolver = null;
|
|
12625
|
+
const qPromise = new Promise((resolve) => {
|
|
12626
|
+
questionResolver = resolve;
|
|
12627
|
+
});
|
|
12628
|
+
const qEntry = {
|
|
12629
|
+
id: questionId,
|
|
12630
|
+
question: questionText,
|
|
12631
|
+
options: optionsObj,
|
|
12632
|
+
answered: false,
|
|
12633
|
+
answer: null,
|
|
12634
|
+
askedAt: Date.now(),
|
|
12635
|
+
_resolve: questionResolver
|
|
12636
|
+
};
|
|
12637
|
+
taskEntry.questions.push(qEntry);
|
|
12638
|
+
taskEntry.status = "waiting";
|
|
12639
|
+
if (context.onSubagentUpdate) {
|
|
12640
|
+
context.onSubagentUpdate();
|
|
12641
|
+
}
|
|
12642
|
+
addPendingNudge(`[SYSTEM] Background subagent "${taskEntry.title}" is WAITING FOR YOUR INPUT: "${questionText}"
|
|
12643
|
+
Respond using tool: [tool:functions.Answer(id="${taskId}", answer="...")]
|
|
12644
|
+
[/SYSTEM]`);
|
|
12645
|
+
const answer = await qPromise;
|
|
12646
|
+
return answer;
|
|
12647
|
+
},
|
|
12550
12648
|
onVisualFeedback: (feedbackLabel) => {
|
|
12551
12649
|
taskEntry.lastChunkTime = Date.now();
|
|
12552
12650
|
const clean = feedbackLabel.replace(/\x1b\[[0-9;]*m/g, "");
|
|
@@ -12608,16 +12706,22 @@ var init_invoke = __esm({
|
|
|
12608
12706
|
if (context.onSubagentUpdate) {
|
|
12609
12707
|
context.onSubagentUpdate();
|
|
12610
12708
|
}
|
|
12611
|
-
}).then((finalAnswer) => {
|
|
12612
|
-
if (taskEntry.status === "cancelled")
|
|
12613
|
-
|
|
12614
|
-
|
|
12615
|
-
|
|
12709
|
+
}, true).then((finalAnswer) => {
|
|
12710
|
+
if (taskEntry.status === "cancelled") {
|
|
12711
|
+
if (taskEntry._resolveCompletion) taskEntry._resolveCompletion(finalAnswer);
|
|
12712
|
+
return;
|
|
12713
|
+
}
|
|
12714
|
+
if (currentTurnLogs.length > 0) {
|
|
12715
|
+
taskEntry.progress.push([...currentTurnLogs]);
|
|
12716
|
+
currentTurnLogs = [];
|
|
12717
|
+
}
|
|
12616
12718
|
taskEntry.status = "completed";
|
|
12617
12719
|
taskEntry.finalAnswer = finalAnswer;
|
|
12618
12720
|
if (context.onSubagentUpdate) {
|
|
12619
12721
|
context.onSubagentUpdate();
|
|
12620
12722
|
}
|
|
12723
|
+
addPendingNudge(`[SYSTEM] Background subagent "${taskEntry.title}" (id: ${taskId}) has FINISHED. Call GetProgress(id="${taskId}") to see the final result. [/SYSTEM]`);
|
|
12724
|
+
if (taskEntry._resolveCompletion) taskEntry._resolveCompletion(finalAnswer);
|
|
12621
12725
|
}).catch(async (err) => {
|
|
12622
12726
|
const { isTerminationSignaled: isTerminationSignaled2 } = await init_ai().then(() => ai_exports);
|
|
12623
12727
|
const isCancelled = err.message === "Subagent task was cancelled." || taskEntry.status === "cancelled" || isTerminationSignaled2();
|
|
@@ -12628,6 +12732,7 @@ ${finalAnswer}`);
|
|
|
12628
12732
|
if (context.onSubagentUpdate) {
|
|
12629
12733
|
context.onSubagentUpdate();
|
|
12630
12734
|
}
|
|
12735
|
+
if (taskEntry._resolveCompletion) taskEntry._resolveCompletion(null);
|
|
12631
12736
|
return;
|
|
12632
12737
|
}
|
|
12633
12738
|
currentTurnLogs.push(`[SUBAGENT FAILURE] Error: ${err.message}`);
|
|
@@ -12637,6 +12742,8 @@ ${finalAnswer}`);
|
|
|
12637
12742
|
if (context.onSubagentUpdate) {
|
|
12638
12743
|
context.onSubagentUpdate();
|
|
12639
12744
|
}
|
|
12745
|
+
addPendingNudge(`[SYSTEM] Background subagent "${taskEntry.title}" (id: ${taskId}) FAILED with error: ${err.message}. [/SYSTEM]`);
|
|
12746
|
+
if (taskEntry._rejectCompletion) taskEntry._rejectCompletion(err);
|
|
12640
12747
|
});
|
|
12641
12748
|
return `SUCCESS: Background subagent started. Task ID: ${taskId}`;
|
|
12642
12749
|
};
|
|
@@ -12664,14 +12771,47 @@ var init_getProgress = __esm({
|
|
|
12664
12771
|
output += `Title: ${task.title}
|
|
12665
12772
|
`;
|
|
12666
12773
|
output += `Task: ${task.task}
|
|
12774
|
+
`;
|
|
12775
|
+
if (task.startedAt) {
|
|
12776
|
+
const elapsedSec = Math.floor((Date.now() - task.startedAt) / 1e3);
|
|
12777
|
+
output += `Elapsed Time: ${elapsedSec}s
|
|
12778
|
+
`;
|
|
12779
|
+
}
|
|
12780
|
+
output += `Turns Completed: ${task.progress.length}
|
|
12781
|
+
`;
|
|
12782
|
+
if (task.status === "running" || task.status === "waiting") {
|
|
12783
|
+
if (task.currentTool) output += `Current Tool: ${task.currentTool}
|
|
12784
|
+
`;
|
|
12785
|
+
if (task.wps > 0) output += `WPS: ${task.wps}
|
|
12786
|
+
`;
|
|
12787
|
+
}
|
|
12788
|
+
if (task.questions && task.questions.length > 0) {
|
|
12789
|
+
const pending = task.questions.filter((q) => !q.answered);
|
|
12790
|
+
if (pending.length > 0) {
|
|
12791
|
+
output += `
|
|
12792
|
+
**PENDING QUESTION**
|
|
12793
|
+
`;
|
|
12794
|
+
pending.forEach((q) => {
|
|
12795
|
+
output += `"${q.question}"
|
|
12796
|
+
`;
|
|
12797
|
+
if (q.options && Object.keys(q.options).length > 0) {
|
|
12798
|
+
output += `Options: ${JSON.stringify(q.options)}
|
|
12799
|
+
`;
|
|
12800
|
+
}
|
|
12801
|
+
});
|
|
12802
|
+
output += `Respond using tool: [tool:functions.Answer(id="${task.id}", answer="...")]
|
|
12667
12803
|
|
|
12668
12804
|
`;
|
|
12669
|
-
|
|
12805
|
+
}
|
|
12806
|
+
}
|
|
12807
|
+
output += `
|
|
12808
|
+
Progress Log:
|
|
12670
12809
|
`;
|
|
12671
12810
|
task.progress.forEach((turnLogs, index) => {
|
|
12672
12811
|
output += `--- Turn ${index + 1} ---
|
|
12673
12812
|
`;
|
|
12674
|
-
const
|
|
12813
|
+
const filteredLogs = turnLogs.filter((log) => !log.startsWith("[SUBAGENT SUCCESS]"));
|
|
12814
|
+
const processedLogs = filteredLogs.map((log) => {
|
|
12675
12815
|
if (log.startsWith("[Subagent Response]")) {
|
|
12676
12816
|
const header = "[Subagent Response]";
|
|
12677
12817
|
const body = log.substring(header.length);
|
|
@@ -12746,7 +12886,7 @@ ${task.finalAnswer}
|
|
|
12746
12886
|
output += `Failure Error: ${task.error}
|
|
12747
12887
|
`;
|
|
12748
12888
|
}
|
|
12749
|
-
const sanitized = output.trim().replace(/\[TOOL RESULT\]/gi, "TOOL RESULT:");
|
|
12889
|
+
const sanitized = output.replace(/\r\n/g, "\n").replace(/\n{3,}/g, "\n\n").trim().replace(/\[TOOL RESULT\]/gi, "TOOL RESULT:");
|
|
12750
12890
|
return sanitized;
|
|
12751
12891
|
};
|
|
12752
12892
|
}
|
|
@@ -12784,37 +12924,9 @@ var init_cancel = __esm({
|
|
|
12784
12924
|
});
|
|
12785
12925
|
|
|
12786
12926
|
// src/tools/await.js
|
|
12787
|
-
var awaitTool;
|
|
12788
12927
|
var init_await = __esm({
|
|
12789
12928
|
"src/tools/await.js"() {
|
|
12790
12929
|
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
12930
|
}
|
|
12819
12931
|
});
|
|
12820
12932
|
|
|
@@ -13169,6 +13281,120 @@ Tools Used: ${toolsStr}
|
|
|
13169
13281
|
}
|
|
13170
13282
|
});
|
|
13171
13283
|
|
|
13284
|
+
// src/tools/awaitSubagent.js
|
|
13285
|
+
var awaitSubagent;
|
|
13286
|
+
var init_awaitSubagent = __esm({
|
|
13287
|
+
"src/tools/awaitSubagent.js"() {
|
|
13288
|
+
init_subagent_state();
|
|
13289
|
+
init_arg_parser();
|
|
13290
|
+
awaitSubagent = async (args, context = {}) => {
|
|
13291
|
+
const parsed = parseArgs(args);
|
|
13292
|
+
const id = parsed.id;
|
|
13293
|
+
let timeoutSec = parseInt(parsed.timeout || parsed.time || "120", 10);
|
|
13294
|
+
if (isNaN(timeoutSec) || timeoutSec <= 0) timeoutSec = 120;
|
|
13295
|
+
if (timeoutSec > 300) timeoutSec = 300;
|
|
13296
|
+
if (!id) {
|
|
13297
|
+
if (parsed.time) {
|
|
13298
|
+
await new Promise((resolve) => setTimeout(resolve, timeoutSec * 1e3));
|
|
13299
|
+
return `SUCCESS: Waited for ${timeoutSec}s.`;
|
|
13300
|
+
}
|
|
13301
|
+
return 'ERROR: Missing "id" argument for Await.';
|
|
13302
|
+
}
|
|
13303
|
+
const task = subagentProgress.find((t) => t.id === id);
|
|
13304
|
+
if (!task) {
|
|
13305
|
+
return `ERROR: Subagent task with ID [${id}] not found.`;
|
|
13306
|
+
}
|
|
13307
|
+
if (task.status === "completed") {
|
|
13308
|
+
return `SUCCESS: Subagent task [${id}] completed.
|
|
13309
|
+
Final Answer:
|
|
13310
|
+
${task.finalAnswer || "(No output)"}`;
|
|
13311
|
+
}
|
|
13312
|
+
if (task.status === "failed") {
|
|
13313
|
+
return `ERROR: Subagent task [${id}] failed.
|
|
13314
|
+
Error: ${task.error || "Unknown error"}`;
|
|
13315
|
+
}
|
|
13316
|
+
if (task.status === "cancelled") {
|
|
13317
|
+
return `INFO: Subagent task [${id}] was cancelled.`;
|
|
13318
|
+
}
|
|
13319
|
+
let timeoutId;
|
|
13320
|
+
const timeoutPromise = new Promise((resolve) => {
|
|
13321
|
+
timeoutId = setTimeout(() => {
|
|
13322
|
+
resolve({ type: "timeout" });
|
|
13323
|
+
}, timeoutSec * 1e3);
|
|
13324
|
+
});
|
|
13325
|
+
try {
|
|
13326
|
+
const result = await Promise.race([
|
|
13327
|
+
task.completionPromise.then(() => ({ type: "completion" })),
|
|
13328
|
+
timeoutPromise
|
|
13329
|
+
]);
|
|
13330
|
+
clearTimeout(timeoutId);
|
|
13331
|
+
if (result.type === "timeout") {
|
|
13332
|
+
return `TIMEOUT: Subagent task [${id}] is still running (status: ${task.status.toUpperCase()}) after ${timeoutSec}s. You can continue other work or call Await again.`;
|
|
13333
|
+
}
|
|
13334
|
+
if (task.status === "completed") {
|
|
13335
|
+
return `SUCCESS: Subagent task [${id}] completed.
|
|
13336
|
+
Final Answer:
|
|
13337
|
+
${task.finalAnswer || "(No output)"}`;
|
|
13338
|
+
} else if (task.status === "failed") {
|
|
13339
|
+
return `ERROR: Subagent task [${id}] failed.
|
|
13340
|
+
Error: ${task.error || "Unknown error"}`;
|
|
13341
|
+
} else if (task.status === "cancelled") {
|
|
13342
|
+
return `INFO: Subagent task [${id}] was cancelled.`;
|
|
13343
|
+
} else {
|
|
13344
|
+
return `INFO: Subagent task [${id}] status changed to ${task.status.toUpperCase()}.`;
|
|
13345
|
+
}
|
|
13346
|
+
} catch (err) {
|
|
13347
|
+
clearTimeout(timeoutId);
|
|
13348
|
+
return `ERROR: Exception while awaiting subagent [${id}]: ${err.message}`;
|
|
13349
|
+
}
|
|
13350
|
+
};
|
|
13351
|
+
}
|
|
13352
|
+
});
|
|
13353
|
+
|
|
13354
|
+
// src/tools/answerSubagent.js
|
|
13355
|
+
var answerSubagent;
|
|
13356
|
+
var init_answerSubagent = __esm({
|
|
13357
|
+
"src/tools/answerSubagent.js"() {
|
|
13358
|
+
init_subagent_state();
|
|
13359
|
+
init_arg_parser();
|
|
13360
|
+
answerSubagent = async (args, context = {}) => {
|
|
13361
|
+
const parsed = parseArgs(args);
|
|
13362
|
+
const id = parsed.id;
|
|
13363
|
+
const answer = parsed.answer || parsed.response;
|
|
13364
|
+
if (!id) {
|
|
13365
|
+
return 'ERROR: Missing "id" argument for Answer.';
|
|
13366
|
+
}
|
|
13367
|
+
if (!answer) {
|
|
13368
|
+
return 'ERROR: Missing "answer" argument for Answer.';
|
|
13369
|
+
}
|
|
13370
|
+
const task = subagentProgress.find((t) => t.id === id);
|
|
13371
|
+
if (!task) {
|
|
13372
|
+
return `ERROR: Subagent task with ID [${id}] not found.`;
|
|
13373
|
+
}
|
|
13374
|
+
if (!task.questions || task.questions.length === 0) {
|
|
13375
|
+
return `INFO: Subagent task [${id}] has no pending questions.`;
|
|
13376
|
+
}
|
|
13377
|
+
const pending = task.questions.filter((q) => !q.answered);
|
|
13378
|
+
if (pending.length === 0) {
|
|
13379
|
+
return `INFO: Subagent task [${id}] has no unanswered questions.`;
|
|
13380
|
+
}
|
|
13381
|
+
pending.forEach((q) => {
|
|
13382
|
+
q.answered = true;
|
|
13383
|
+
q.answer = answer;
|
|
13384
|
+
q.answeredAt = Date.now();
|
|
13385
|
+
if (q._resolve) {
|
|
13386
|
+
q._resolve(answer);
|
|
13387
|
+
}
|
|
13388
|
+
});
|
|
13389
|
+
task.status = "running";
|
|
13390
|
+
if (context.onSubagentUpdate) {
|
|
13391
|
+
context.onSubagentUpdate();
|
|
13392
|
+
}
|
|
13393
|
+
return `SUCCESS: Answer provided to subagent task [${id}]. Subagent execution resumed.`;
|
|
13394
|
+
};
|
|
13395
|
+
}
|
|
13396
|
+
});
|
|
13397
|
+
|
|
13172
13398
|
// src/utils/tools.js
|
|
13173
13399
|
var TOOL_MAP, dispatchTool;
|
|
13174
13400
|
var init_tools = __esm({
|
|
@@ -13197,6 +13423,8 @@ var init_tools = __esm({
|
|
|
13197
13423
|
init_cancel();
|
|
13198
13424
|
init_await();
|
|
13199
13425
|
init_emergency_rollback();
|
|
13426
|
+
init_awaitSubagent();
|
|
13427
|
+
init_answerSubagent();
|
|
13200
13428
|
TOOL_MAP = {
|
|
13201
13429
|
web_search,
|
|
13202
13430
|
web_scrape,
|
|
@@ -13219,8 +13447,12 @@ var init_tools = __esm({
|
|
|
13219
13447
|
invoke,
|
|
13220
13448
|
getProgress,
|
|
13221
13449
|
cancel,
|
|
13450
|
+
awaitSubagent,
|
|
13451
|
+
answerSubagent,
|
|
13222
13452
|
invoke_sync: invokeSync,
|
|
13223
13453
|
get_progress: getProgress,
|
|
13454
|
+
await_subagent: awaitSubagent,
|
|
13455
|
+
answer_subagent: answerSubagent,
|
|
13224
13456
|
ask: ask_user,
|
|
13225
13457
|
// PascalCase Normalizations for Token Efficiency
|
|
13226
13458
|
Ask: ask_user,
|
|
@@ -13245,14 +13477,12 @@ var init_tools = __esm({
|
|
|
13245
13477
|
addMemoryScore: addMemScore,
|
|
13246
13478
|
AddMemoryScore: addMemScore,
|
|
13247
13479
|
FileMap: file_map,
|
|
13248
|
-
|
|
13249
|
-
|
|
13250
|
-
|
|
13251
|
-
|
|
13252
|
-
|
|
13253
|
-
|
|
13254
|
-
await: awaitTool,
|
|
13255
|
-
Await: awaitTool,
|
|
13480
|
+
answer: answerSubagent,
|
|
13481
|
+
Answer: answerSubagent,
|
|
13482
|
+
AnswerSubagent: answerSubagent,
|
|
13483
|
+
await: awaitSubagent,
|
|
13484
|
+
Await: awaitSubagent,
|
|
13485
|
+
AwaitSubagent: awaitSubagent,
|
|
13256
13486
|
EmergencyRollback: emergency_rollback,
|
|
13257
13487
|
emergency_rollback
|
|
13258
13488
|
};
|
|
@@ -13521,6 +13751,7 @@ __export(ai_exports, {
|
|
|
13521
13751
|
deleteChatSummary: () => deleteChatSummary,
|
|
13522
13752
|
getAIStream: () => getAIStream,
|
|
13523
13753
|
getCleanGroupedLength: () => getCleanGroupedLength,
|
|
13754
|
+
getGoogleClient: () => getGoogleClient,
|
|
13524
13755
|
initAI: () => initAI,
|
|
13525
13756
|
isModelMultimodal: () => isModelMultimodal,
|
|
13526
13757
|
isTerminationSignaled: () => isTerminationSignaled,
|
|
@@ -13532,7 +13763,7 @@ import dotenv from "dotenv";
|
|
|
13532
13763
|
import { GoogleGenAI, ThinkingLevel, HarmBlockThreshold, HarmCategory } from "@google/genai";
|
|
13533
13764
|
import path26, { normalize } from "path";
|
|
13534
13765
|
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;
|
|
13766
|
+
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
13767
|
var init_ai = __esm({
|
|
13537
13768
|
async "src/utils/ai.js"() {
|
|
13538
13769
|
await init_prompts();
|
|
@@ -13563,15 +13794,27 @@ var init_ai = __esm({
|
|
|
13563
13794
|
RE_STUTTER_WORD_BOUNDARY = /^[^\w]+|[^\w]+$/g;
|
|
13564
13795
|
RE_STUTTER_NON_ALNUM = /[^a-z0-9]/gi;
|
|
13565
13796
|
RE_TOOL_CALL_FUNC = /\[\s*tool:functions\.([a-z0-9_]+)\s*\(/gi;
|
|
13797
|
+
RE_TOOL_CALL_ANY = /\[\s*(?:tool:functions\.|agent:generalist\.)([a-z0-9_]+)\s*\(/gi;
|
|
13566
13798
|
RE_TOOL_PARTIAL_ARGS_FALLBACK = /(?:path|targetFile|TargetFile|directory|keyword|id|taskId|title|task)\s*=\s*\\?["']?([^\\"' \),]+)/;
|
|
13567
13799
|
RE_STRIP_QUOTES = /["']/g;
|
|
13568
13800
|
RE_BACKSLASH_SLASH = /\\/g;
|
|
13801
|
+
RE_STRIP_THINK_CLOSED = /(?:<(think|thought)>|\[(think|thought)\])[\s\S]*?(?:<\/(think|thought)>|\[\/(think|thought)\])/gi;
|
|
13802
|
+
RE_STRIP_THINK_OPEN = /(?:<(think|thought)>|\[(think|thought)\])[\s\S]*$/gi;
|
|
13803
|
+
RE_STRIP_THINK_SIMPLE = /(?:<think>|\[think\])[\s\S]*?(?:<\/think>|\[\/think\]|$)/gi;
|
|
13804
|
+
RE_STRIP_THINK_FULL = /(?:<(think|thought|thoughts)>|\[(think|thought|thoughts)\])[\s\S]*?(?:<\/(think|thought|thoughts)>|\[\/(think|thought|thoughts)\]|$)/gi;
|
|
13805
|
+
RE_BACKTICK_SPAN = /`[^`]*`/g;
|
|
13806
|
+
RE_BACKTICK_OPEN = /`[^`]*$/;
|
|
13807
|
+
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;
|
|
13808
|
+
RE_KIMI_JSON_PAIR = /"([^"]+)"\s*:\s*(?:"([^"]*)"|(\d+)|true|false|null)/g;
|
|
13809
|
+
RE_KIMI_SECTION_BEGIN = /<\|\s*tool_calls_section_begin\s*\|>/gi;
|
|
13810
|
+
RE_KIMI_SECTION_END = /<\|\s*tool_calls_section_end\s*\|>/gi;
|
|
13811
|
+
bypassBacktick2 = false;
|
|
13569
13812
|
client = null;
|
|
13570
13813
|
globalSettings = {};
|
|
13571
13814
|
systemInstructionCache = { key: null, value: null };
|
|
13572
13815
|
colorMainWords = (label) => {
|
|
13573
13816
|
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) => {
|
|
13817
|
+
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
13818
|
return `${ansiBefore || ""}${icon}${ansiAfter || ""} \x1B[95m${word}\x1B[0m`;
|
|
13576
13819
|
});
|
|
13577
13820
|
};
|
|
@@ -14496,12 +14739,14 @@ var init_ai = __esm({
|
|
|
14496
14739
|
"generate_image": "Generating",
|
|
14497
14740
|
"todo": "Planning",
|
|
14498
14741
|
"Todo": "Planning",
|
|
14499
|
-
"invoke_sync": "
|
|
14500
|
-
"invoke": "
|
|
14742
|
+
"invoke_sync": "Sub-Agent Working",
|
|
14743
|
+
"invoke": "Starting Agent",
|
|
14501
14744
|
"get_progress": "Checking Progress",
|
|
14502
14745
|
"cancel": "Cancelling",
|
|
14503
14746
|
"await": "Waiting",
|
|
14504
|
-
"EmergencyRollback": "Don't Panic. Lookin' into it"
|
|
14747
|
+
"EmergencyRollback": "Don't Panic. Lookin' into it",
|
|
14748
|
+
"answer": "Answering Sub-Agent",
|
|
14749
|
+
"Answer": "Answering Sub-Agent"
|
|
14505
14750
|
};
|
|
14506
14751
|
getToolDetail = (toolName, argsStr) => {
|
|
14507
14752
|
try {
|
|
@@ -14519,6 +14764,12 @@ var init_ai = __esm({
|
|
|
14519
14764
|
return null;
|
|
14520
14765
|
}
|
|
14521
14766
|
};
|
|
14767
|
+
getGoogleClient = (apiKey) => {
|
|
14768
|
+
if (apiKey) {
|
|
14769
|
+
return new GoogleGenAI({ apiKey });
|
|
14770
|
+
}
|
|
14771
|
+
return client;
|
|
14772
|
+
};
|
|
14522
14773
|
runJanitorTask = async (settings, agentText, fullAgentTextRaw, history, callbacks = {}) => {
|
|
14523
14774
|
const USER_CONTEXT_LENGTH = 4 * (1024 * 2);
|
|
14524
14775
|
const AGENT_CONTEXT_LENGTH = 4 * (1024 * 8);
|
|
@@ -14657,7 +14908,8 @@ ${originalTextProcessed.length > USER_CONTEXT_LENGTH ? "... (truncated) ...\n\n"
|
|
|
14657
14908
|
const firstResult2 = await iterator2.next();
|
|
14658
14909
|
return { iterator: iterator2, firstResult: firstResult2 };
|
|
14659
14910
|
} else {
|
|
14660
|
-
const
|
|
14911
|
+
const googleClient = getGoogleClient(apiKey);
|
|
14912
|
+
const stream = await googleClient.models.generateContentStream({
|
|
14661
14913
|
model: janitorModel || (attempts === MAX_JANITOR_RETRIES ? getFallbackValue("janitor_default") : getFallbackValue("gemma_janitor_fallback_google")),
|
|
14662
14914
|
contents: janitorContents,
|
|
14663
14915
|
config: {
|
|
@@ -14812,16 +15064,17 @@ ${originalTextProcessed.length > USER_CONTEXT_LENGTH ? "... (truncated) ...\n\n"
|
|
|
14812
15064
|
}
|
|
14813
15065
|
};
|
|
14814
15066
|
getActiveToolContext = (text) => {
|
|
14815
|
-
const cleanText = text.replace(
|
|
15067
|
+
const cleanText = text.replace(RE_STRIP_THINK_CLOSED, "").replace(RE_STRIP_THINK_OPEN, "");
|
|
15068
|
+
const scanText = bypassBacktick2 ? cleanText : cleanText.replace(RE_BACKTICK_SPAN, (m) => " ".repeat(m.length)).replace(RE_BACKTICK_OPEN, (m) => " ".repeat(m.length));
|
|
14816
15069
|
RE_TOOL_CALL_FUNC.lastIndex = 0;
|
|
14817
15070
|
let match;
|
|
14818
|
-
while ((match = RE_TOOL_CALL_FUNC.exec(
|
|
15071
|
+
while ((match = RE_TOOL_CALL_FUNC.exec(scanText)) !== null) {
|
|
14819
15072
|
const startIdx = match.index + match[0].length - 1;
|
|
14820
15073
|
let balance = 0;
|
|
14821
15074
|
let inString = null;
|
|
14822
15075
|
let isEscaped = false;
|
|
14823
15076
|
let closed = false;
|
|
14824
|
-
for (let i = startIdx; i <
|
|
15077
|
+
for (let i = startIdx; i < scanText.length; i++) {
|
|
14825
15078
|
const char = cleanText[i];
|
|
14826
15079
|
if (!inString && (char === '"' || char === "'" || char === "`")) {
|
|
14827
15080
|
inString = char;
|
|
@@ -14834,8 +15087,8 @@ ${originalTextProcessed.length > USER_CONTEXT_LENGTH ? "... (truncated) ...\n\n"
|
|
|
14834
15087
|
else if (char === ")") balance--;
|
|
14835
15088
|
if (balance === 0) {
|
|
14836
15089
|
let j = i + 1;
|
|
14837
|
-
while (j <
|
|
14838
|
-
if (j <
|
|
15090
|
+
while (j < scanText.length && /\s/.test(scanText[j])) j++;
|
|
15091
|
+
if (j < scanText.length && scanText[j] === "]") {
|
|
14839
15092
|
closed = true;
|
|
14840
15093
|
RE_TOOL_CALL_FUNC.lastIndex = j + 1;
|
|
14841
15094
|
break;
|
|
@@ -14852,13 +15105,14 @@ ${originalTextProcessed.length > USER_CONTEXT_LENGTH ? "... (truncated) ...\n\n"
|
|
|
14852
15105
|
return { inside: false };
|
|
14853
15106
|
};
|
|
14854
15107
|
getContextSafeText = (text, stripThoughts = true) => {
|
|
14855
|
-
const toolRegex =
|
|
15108
|
+
const toolRegex = RE_TOOL_CALL_FUNC;
|
|
15109
|
+
toolRegex.lastIndex = 0;
|
|
14856
15110
|
let result = "";
|
|
14857
15111
|
let lastIdx = 0;
|
|
14858
15112
|
let match;
|
|
14859
15113
|
while ((match = toolRegex.exec(text)) !== null) {
|
|
14860
15114
|
const before = text.substring(lastIdx, match.index);
|
|
14861
|
-
result += stripThoughts ? before.replace(
|
|
15115
|
+
result += stripThoughts ? before.replace(RE_STRIP_THINK_SIMPLE, "") : before;
|
|
14862
15116
|
const startIdx = match.index + match[0].length - 1;
|
|
14863
15117
|
let balance = 0;
|
|
14864
15118
|
let inString = null;
|
|
@@ -14904,12 +15158,13 @@ ${originalTextProcessed.length > USER_CONTEXT_LENGTH ? "... (truncated) ...\n\n"
|
|
|
14904
15158
|
}
|
|
14905
15159
|
}
|
|
14906
15160
|
if (lastIdx < text.length) {
|
|
14907
|
-
result += stripThoughts ? text.substring(lastIdx).replace(
|
|
15161
|
+
result += stripThoughts ? text.substring(lastIdx).replace(RE_STRIP_THINK_SIMPLE, "") : text.substring(lastIdx);
|
|
14908
15162
|
}
|
|
14909
15163
|
return result;
|
|
14910
15164
|
};
|
|
14911
15165
|
contextSafeReplace = (text, regex, replacement) => {
|
|
14912
|
-
const toolRegex =
|
|
15166
|
+
const toolRegex = RE_TOOL_CALL_FUNC;
|
|
15167
|
+
toolRegex.lastIndex = 0;
|
|
14913
15168
|
let result = "";
|
|
14914
15169
|
let lastIdx = 0;
|
|
14915
15170
|
let match;
|
|
@@ -14992,8 +15247,8 @@ ${originalTextProcessed.length > USER_CONTEXT_LENGTH ? "... (truncated) ...\n\n"
|
|
|
14992
15247
|
const toPascalCase = (str) => {
|
|
14993
15248
|
return str.split("_").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join("");
|
|
14994
15249
|
};
|
|
14995
|
-
|
|
14996
|
-
let result = text.replace(
|
|
15250
|
+
RE_KIMI_TOOL_CALL.lastIndex = 0;
|
|
15251
|
+
let result = text.replace(RE_KIMI_TOOL_CALL, (match, toolName, argsJsonStr) => {
|
|
14997
15252
|
let parsedArgs = "";
|
|
14998
15253
|
try {
|
|
14999
15254
|
const argsObj = JSON.parse(argsJsonStr.trim());
|
|
@@ -15006,7 +15261,8 @@ ${originalTextProcessed.length > USER_CONTEXT_LENGTH ? "... (truncated) ...\n\n"
|
|
|
15006
15261
|
}
|
|
15007
15262
|
} catch (e) {
|
|
15008
15263
|
const pairs = [];
|
|
15009
|
-
const pairRegex =
|
|
15264
|
+
const pairRegex = RE_KIMI_JSON_PAIR;
|
|
15265
|
+
pairRegex.lastIndex = 0;
|
|
15010
15266
|
let pMatch;
|
|
15011
15267
|
while ((pMatch = pairRegex.exec(argsJsonStr)) !== null) {
|
|
15012
15268
|
const key = pMatch[1];
|
|
@@ -15023,8 +15279,10 @@ ${originalTextProcessed.length > USER_CONTEXT_LENGTH ? "... (truncated) ...\n\n"
|
|
|
15023
15279
|
const normToolName = PASCAL_MAP[cleanKey] || toPascalCase(toolName);
|
|
15024
15280
|
return `[tool:functions.${normToolName}(${parsedArgs})]`;
|
|
15025
15281
|
});
|
|
15026
|
-
|
|
15027
|
-
|
|
15282
|
+
RE_KIMI_SECTION_BEGIN.lastIndex = 0;
|
|
15283
|
+
RE_KIMI_SECTION_END.lastIndex = 0;
|
|
15284
|
+
result = result.replace(RE_KIMI_SECTION_BEGIN, "");
|
|
15285
|
+
result = result.replace(RE_KIMI_SECTION_END, "");
|
|
15028
15286
|
return result;
|
|
15029
15287
|
};
|
|
15030
15288
|
REGEX_PLACEHOLDER_ARG = /(?:path|query|url|keyword|command|method|title|task|id)\s*=\s*['"`]?\s*\.\.\.\s*['"`]?/i;
|
|
@@ -15037,18 +15295,21 @@ ${originalTextProcessed.length > USER_CONTEXT_LENGTH ? "... (truncated) ...\n\n"
|
|
|
15037
15295
|
detectToolCalls = (text) => {
|
|
15038
15296
|
if (!text) return [];
|
|
15039
15297
|
const translatedText = translateKimiToolCalls(text);
|
|
15040
|
-
|
|
15298
|
+
RE_STRIP_THINK_FULL.lastIndex = 0;
|
|
15299
|
+
const cleanText = translatedText.replace(RE_STRIP_THINK_FULL, "");
|
|
15041
15300
|
const results = [];
|
|
15042
|
-
const
|
|
15301
|
+
const scanText = bypassBacktick2 ? cleanText : cleanText.replace(RE_BACKTICK_SPAN, (m) => " ".repeat(m.length)).replace(RE_BACKTICK_OPEN, (m) => " ".repeat(m.length));
|
|
15302
|
+
const toolRegex = RE_TOOL_CALL_ANY;
|
|
15303
|
+
toolRegex.lastIndex = 0;
|
|
15043
15304
|
let match;
|
|
15044
|
-
while ((match = toolRegex.exec(
|
|
15305
|
+
while ((match = toolRegex.exec(scanText)) !== null) {
|
|
15045
15306
|
const toolName = match[1];
|
|
15046
15307
|
const startIdx = match.index + match[0].length - 1;
|
|
15047
15308
|
let balance = 0;
|
|
15048
15309
|
let inString = null;
|
|
15049
15310
|
let endIdx = -1;
|
|
15050
15311
|
let closingParenIdx = -1;
|
|
15051
|
-
for (let i = startIdx; i <
|
|
15312
|
+
for (let i = startIdx; i < scanText.length; i++) {
|
|
15052
15313
|
const char = cleanText[i];
|
|
15053
15314
|
if (inString) {
|
|
15054
15315
|
if (char === inString) {
|
|
@@ -15070,8 +15331,8 @@ ${originalTextProcessed.length > USER_CONTEXT_LENGTH ? "... (truncated) ...\n\n"
|
|
|
15070
15331
|
if (balance === 0) {
|
|
15071
15332
|
closingParenIdx = i;
|
|
15072
15333
|
let j = i + 1;
|
|
15073
|
-
while (j <
|
|
15074
|
-
if (j <
|
|
15334
|
+
while (j < scanText.length && /\s/.test(scanText[j])) j++;
|
|
15335
|
+
if (j < scanText.length && scanText[j] === "]") {
|
|
15075
15336
|
endIdx = j;
|
|
15076
15337
|
break;
|
|
15077
15338
|
}
|
|
@@ -15126,7 +15387,6 @@ ${originalTextProcessed.length > USER_CONTEXT_LENGTH ? "... (truncated) ...\n\n"
|
|
|
15126
15387
|
}
|
|
15127
15388
|
};
|
|
15128
15389
|
}
|
|
15129
|
-
return client;
|
|
15130
15390
|
};
|
|
15131
15391
|
generateSimpleContent = async (settings, model, contents, systemInstruction, thinkingLevel = "Fast", temperature = 0.75, usageKey = "agent") => {
|
|
15132
15392
|
return withRetry(async () => {
|
|
@@ -15153,7 +15413,8 @@ ${originalTextProcessed.length > USER_CONTEXT_LENGTH ? "... (truncated) ...\n\n"
|
|
|
15153
15413
|
} else if (aiProvider === "NVIDIA") {
|
|
15154
15414
|
stream = getNVIDIAStream(apiKey, model, normalizedContents, systemInstruction, thinkingLevel, mode, isModelMultimodal(model), signal, temperature);
|
|
15155
15415
|
} else {
|
|
15156
|
-
const
|
|
15416
|
+
const googleClient = getGoogleClient(apiKey);
|
|
15417
|
+
const genStream = await googleClient.models.generateContentStream({
|
|
15157
15418
|
model,
|
|
15158
15419
|
contents: normalizedContents,
|
|
15159
15420
|
config: {
|
|
@@ -16058,7 +16319,7 @@ OS: ${osDetected}${systemSettings?.dynamicDirAwareness ? dirStructure : ""}${cwd
|
|
|
16058
16319
|
WARNING: CWD Changed from previous: "${lastCwd}" to current: "${process.cwd()}", write change in chat to avoid future path mismatches
|
|
16059
16320
|
` : ""}${memoryPrompt}${ideBlock}
|
|
16060
16321
|
[/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(
|
|
16322
|
+
${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
16323
|
${taggedContextStr}[USER PROMPT]
|
|
16063
16324
|
${cleanPromptForModel.trim()}
|
|
16064
16325
|
[/USER PROMPT]`.trim();
|
|
@@ -16093,10 +16354,31 @@ ${cleanPromptForModel.trim()}
|
|
|
16093
16354
|
yield { type: "status", content: "Working" };
|
|
16094
16355
|
}
|
|
16095
16356
|
if (TERMINATION_SIGNAL) {
|
|
16357
|
+
try {
|
|
16358
|
+
const { clearPendingNudges: clearPendingNudges2 } = await Promise.resolve().then(() => (init_subagent_state(), subagent_state_exports));
|
|
16359
|
+
clearPendingNudges2();
|
|
16360
|
+
} catch (e) {
|
|
16361
|
+
}
|
|
16096
16362
|
yield { type: "status", content: "Request Cancelled" };
|
|
16097
16363
|
yield { type: "text", content: "\n\n\x1B[33m\u24D8 Request Cancelled\x1B[0m" };
|
|
16098
16364
|
break;
|
|
16099
16365
|
}
|
|
16366
|
+
try {
|
|
16367
|
+
const { consumePendingNudges: consumePendingNudges2 } = await Promise.resolve().then(() => (init_subagent_state(), subagent_state_exports));
|
|
16368
|
+
const pendingNudges = consumePendingNudges2();
|
|
16369
|
+
if (pendingNudges && pendingNudges.length > 0) {
|
|
16370
|
+
const combinedNudge = pendingNudges.join("\n\n");
|
|
16371
|
+
if (modifiedHistory.length > 0 && modifiedHistory[modifiedHistory.length - 1].role === "user") {
|
|
16372
|
+
modifiedHistory[modifiedHistory.length - 1].text += `
|
|
16373
|
+
|
|
16374
|
+
${combinedNudge}`;
|
|
16375
|
+
} else {
|
|
16376
|
+
modifiedHistory.push({ role: "user", text: combinedNudge });
|
|
16377
|
+
}
|
|
16378
|
+
yield { type: "status", content: "Subagent Update" };
|
|
16379
|
+
}
|
|
16380
|
+
} catch (e) {
|
|
16381
|
+
}
|
|
16100
16382
|
if (steeringCallback) {
|
|
16101
16383
|
const hint = await steeringCallback();
|
|
16102
16384
|
if (hint) {
|
|
@@ -16358,7 +16640,8 @@ ${ideErr} [/ERROR]`;
|
|
|
16358
16640
|
);
|
|
16359
16641
|
stream = wrapNvidiaStreamWithQueueDepth(rawStream, targetModel);
|
|
16360
16642
|
} else {
|
|
16361
|
-
const
|
|
16643
|
+
const googleClient = getGoogleClient(settings?.apiKey);
|
|
16644
|
+
const apiCallPromise = googleClient.models.generateContentStream({
|
|
16362
16645
|
model: targetModel || "gemini-3-flash-preview",
|
|
16363
16646
|
contents: activeContents,
|
|
16364
16647
|
config: {
|
|
@@ -16699,19 +16982,19 @@ ${ideErr} [/ERROR]`;
|
|
|
16699
16982
|
"getProgress": "get_progress",
|
|
16700
16983
|
"GetProgress": "get_progress",
|
|
16701
16984
|
"Cancel": "cancel",
|
|
16702
|
-
"
|
|
16703
|
-
"
|
|
16985
|
+
"Await": "await",
|
|
16986
|
+
"Answer": "answer"
|
|
16704
16987
|
};
|
|
16705
16988
|
const potentialTool = NORMALIZE_MAP[toolContext.toolName] || toolContext.toolName;
|
|
16706
16989
|
const partialArgs = toolContext.args || "";
|
|
16707
16990
|
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)) {
|
|
16991
|
+
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
16992
|
const pArgs = parseArgs(partialArgs);
|
|
16710
16993
|
const filePath = pArgs.path || pArgs.targetFile || pArgs.TargetFile || pArgs.directory;
|
|
16711
16994
|
const keyword = pArgs.keyword;
|
|
16712
16995
|
const title = pArgs.title || pArgs.task;
|
|
16713
16996
|
const id = pArgs.id || pArgs.taskId;
|
|
16714
|
-
const timeVal = pArgs.time;
|
|
16997
|
+
const timeVal = pArgs.timeout || pArgs.time;
|
|
16715
16998
|
if (keyword !== void 0 && keyword !== null) {
|
|
16716
16999
|
detail = String(keyword).replace(RE_STRIP_QUOTES, "");
|
|
16717
17000
|
} else if (filePath) {
|
|
@@ -16778,17 +17061,19 @@ ${ideErr} [/ERROR]`;
|
|
|
16778
17061
|
"Ask": "User Input Required",
|
|
16779
17062
|
"Memory": "Updating Memory",
|
|
16780
17063
|
"GenerateImage": "Generating",
|
|
16781
|
-
"InvokeSync": "
|
|
16782
|
-
"invoke_sync": "
|
|
16783
|
-
"Invoke": "
|
|
16784
|
-
"invoke": "
|
|
17064
|
+
"InvokeSync": "Sub-Agent Working",
|
|
17065
|
+
"invoke_sync": "Sub-Agent Working",
|
|
17066
|
+
"Invoke": "Working",
|
|
17067
|
+
"invoke": "Working",
|
|
16785
17068
|
"GetProgress": "Checking Progress",
|
|
16786
17069
|
"get_progress": "Checking Progress",
|
|
16787
17070
|
"Cancel": "Stopping Generalist",
|
|
16788
17071
|
"cancel": "Stopping Generalist",
|
|
16789
17072
|
"Await": "Waiting",
|
|
16790
17073
|
"await": "Waiting",
|
|
16791
|
-
"EmergencyRollback": "Rolling the Ball"
|
|
17074
|
+
"EmergencyRollback": "Rolling the Ball",
|
|
17075
|
+
"Answer": "Answering Sub-Agent",
|
|
17076
|
+
"answer": "Answering Sub-Agent"
|
|
16792
17077
|
};
|
|
16793
17078
|
const toolTitle = TOOL_TITLES[potentialTool] || "Working";
|
|
16794
17079
|
process.stdout.write(`\x1B]0;${toolTitle}...\x07`);
|
|
@@ -16920,14 +17205,20 @@ ${ideErr} [/ERROR]`;
|
|
|
16920
17205
|
"generate_image": "generate_image",
|
|
16921
17206
|
"todo": "todo",
|
|
16922
17207
|
"Todo": "todo",
|
|
16923
|
-
"
|
|
17208
|
+
"Invoke": "invoke",
|
|
16924
17209
|
"InvokeSync": "invoke_sync",
|
|
16925
17210
|
"getProgress": "get_progress",
|
|
16926
17211
|
"GetProgress": "get_progress",
|
|
17212
|
+
"Await": "await",
|
|
17213
|
+
"await": "await",
|
|
17214
|
+
"AwaitSubagent": "await",
|
|
17215
|
+
"awaitSubagent": "await",
|
|
17216
|
+
"Answer": "answer",
|
|
17217
|
+
"answer": "answer",
|
|
17218
|
+
"AnswerSubagent": "answer",
|
|
17219
|
+
"answerSubagent": "answer",
|
|
16927
17220
|
"Cancel": "cancel",
|
|
16928
17221
|
"cancel": "cancel",
|
|
16929
|
-
"await": "await",
|
|
16930
|
-
"Await": "await",
|
|
16931
17222
|
"EmergencyRollback": "EmergencyRollback"
|
|
16932
17223
|
};
|
|
16933
17224
|
const normToolName = NORMALIZE_MAP[toolCall.toolName] || toolCall.toolName;
|
|
@@ -17013,10 +17304,9 @@ ${ideErr} [/ERROR]`;
|
|
|
17013
17304
|
const { method } = parseArgs(toolCall.args);
|
|
17014
17305
|
label = method === "forceRevert" ? "" : "\u2714 Rollback Point Checked";
|
|
17015
17306
|
} 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;
|
|
17307
|
+
const { time, timeout } = parseArgs(toolCall.args);
|
|
17308
|
+
let sec = parseFloat(timeout || time) || 0;
|
|
17309
|
+
if (!sec) sec = 120;
|
|
17020
17310
|
const formatTime = (s) => {
|
|
17021
17311
|
if (s >= 60) {
|
|
17022
17312
|
const m = Math.floor(s / 60);
|
|
@@ -17055,6 +17345,8 @@ ${ideErr} [/ERROR]`;
|
|
|
17055
17345
|
];
|
|
17056
17346
|
let randomVibe = existentialVibes[Math.floor(Math.random() * existentialVibes.length)];
|
|
17057
17347
|
label = `\u2714 ${randomVibe} \u2192 ${formatTime(sec)}`;
|
|
17348
|
+
} else if (normToolName === "Answer" || normToolName === "answer") {
|
|
17349
|
+
label = "\u2714 Resolved Sub-Agent Query";
|
|
17058
17350
|
} else if (normToolName === "exec_command" || normToolName === "ask") {
|
|
17059
17351
|
label = "";
|
|
17060
17352
|
} else {
|
|
@@ -17983,7 +18275,7 @@ ${snippet2}`;
|
|
|
17983
18275
|
const waitTime = Math.min(1e3 * Math.pow(2, inStreamRetryCount - 1), 24e3);
|
|
17984
18276
|
if (turnText.trim().length > 0) {
|
|
17985
18277
|
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>
|
|
18278
|
+
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
18279
|
if (toolResults.length > 0) {
|
|
17988
18280
|
toolResults.forEach((tr, idx) => {
|
|
17989
18281
|
if (idx === toolResults.length - 1) {
|
|
@@ -18176,7 +18468,7 @@ Error Log can be found in ${path26.join(LOGS_DIR, "agent", "error.log")}`);
|
|
|
18176
18468
|
}
|
|
18177
18469
|
yield { type: "status", content: null };
|
|
18178
18470
|
};
|
|
18179
|
-
runSubagent = async (task, settings, model = null, allowedTools = null, maxTurns = 50, logCallback = null) => {
|
|
18471
|
+
runSubagent = async (task, settings, model = null, allowedTools = null, maxTurns = 50, logCallback = null, isAsync = false) => {
|
|
18180
18472
|
const savedSettings = await loadSettings();
|
|
18181
18473
|
const mergedSettings = { ...savedSettings, ...settings };
|
|
18182
18474
|
const envSubagentModel = process.env.SUBAGENT_MODEL ? process.env.SUBAGENT_MODEL.trim() : null;
|
|
@@ -18250,8 +18542,8 @@ Error Log can be found in ${path26.join(LOGS_DIR, "agent", "error.log")}`);
|
|
|
18250
18542
|
const targetModel = model || subAgentCustomModel || settings?.modelName || settings?.activeModel || savedSettings.activeModel;
|
|
18251
18543
|
const osDetected = process.platform === "win32" ? "Windows" : process.platform === "darwin" ? "macOS" : "Linux";
|
|
18252
18544
|
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**
|
|
18545
|
+
TO ACCESS TOOLS **STRICTLY USE THE EXACT FORMAT IN CHAT OUTPUT:** [tool:functions.ToolName(arg1="value1")]
|
|
18546
|
+
**NO OTHER SYNTAX/MARKERS/WRAPPER/BOUNDARY ALLOWED**
|
|
18255
18547
|
|
|
18256
18548
|
TOOL POLICY:
|
|
18257
18549
|
- Escape quotes: \\" for code strings
|
|
@@ -18262,10 +18554,12 @@ TOOL POLICY:
|
|
|
18262
18554
|
- Need text or huge files? SearchKeyword > Full Read
|
|
18263
18555
|
- Update Todos from realtime progress each turn
|
|
18264
18556
|
- Restricted Shell Access, No Deletion
|
|
18557
|
+
- ONLY valid tools and syntax defined below are allowed
|
|
18265
18558
|
|
|
18266
18559
|
**PROVIDED TOOLS**
|
|
18267
|
-
-- Communication
|
|
18268
|
-
- [tool:functions.Ask(question="...", optionA="option::description", ...MAX 4)]. Ambiguity: MUST for path divergence, security risk. Ask, don't finish/guess. Suggest best options; no preferences. Keep options short
|
|
18560
|
+
-- Communication Tools --
|
|
18561
|
+
- [tool:functions.Ask(question="...", optionA="option::description", ...MAX 4)]. Communicate with USER. Ambiguity: MUST for path divergence, security risk. Ask, don't finish/guess. Suggest best options; no preferences. Keep options short
|
|
18562
|
+
${isAsync ? `- [tool:functions.AskMain(question="...", optionA="option::description", ...MAX 4)]. Communicate with PARENT/MAIN AGENT. When clarification/decision is needed for a task` : ""}
|
|
18269
18563
|
|
|
18270
18564
|
-- Web Tools --
|
|
18271
18565
|
- [tool:functions.WebSearch(query="...", aiMode="bool optional, default: false", limit="integer 3-10, aiMode: exclude")]. Usage: unknown info/docs. aiMode: LLM search
|
|
@@ -18278,7 +18572,7 @@ TOOL POLICY:
|
|
|
18278
18572
|
- [tool:functions.PatchFile(path="...", allowMultiple="bool optional, default: false", replaceContent1="...", newContent1="...", ...MAX15)]. TARGET MINIMAL DIFF. allowMultiple: Replace all matches ONLY WHEN SURE. Multi-blocks: replaceContent2/newContent2... Verify diffs
|
|
18279
18573
|
- [tool:functions.WriteFile(path="...", content="...")]. Creates/Overwrites. File Exist? PatchFile > WriteFile. VERIFY IMPORTS
|
|
18280
18574
|
- [tool:functions.Run(command="...")]. Runs ${osDetected === "Windows" ? isPsAvailable() ? `WINDOWS POWERSHELL` : `WINDOWS CMD` : `BASH`} command. Destructive/Irreversible ops \u2192 Ask user`.trim();
|
|
18281
|
-
const
|
|
18575
|
+
const systemInstructionSubAgent = `=== START SYSTEM PROMPT ===
|
|
18282
18576
|
You are a subagent helping the main FluxFlow CLI agent
|
|
18283
18577
|
Your task is: "${task}"
|
|
18284
18578
|
|
|
@@ -18318,7 +18612,7 @@ Current Time: ${time}
|
|
|
18318
18612
|
parts: [{ text: m.text }]
|
|
18319
18613
|
}));
|
|
18320
18614
|
if (logCallback) logCallback(`[Subagent Turn ${turn + 1}] Invoking model ${targetModel}...`);
|
|
18321
|
-
const response = await generateSimpleContent(mergedSettings, targetModel, contents,
|
|
18615
|
+
const response = await generateSimpleContent(mergedSettings, targetModel, contents, systemInstructionSubAgent, "Fast");
|
|
18322
18616
|
const responseText = response.text || "";
|
|
18323
18617
|
const cleanResponse = responseText.replace(/(?:<think>|\[think\])[\s\S]*?(?:<\/think>|\[\/think\])/gi, "").trim();
|
|
18324
18618
|
finalAnswer = cleanResponse;
|
|
@@ -18330,6 +18624,8 @@ ${cleanResponse}
|
|
|
18330
18624
|
if (toolCalls.length === 0) {
|
|
18331
18625
|
break;
|
|
18332
18626
|
}
|
|
18627
|
+
const askMainCalls = toolCalls.filter((tc) => tc.toolName.toLowerCase() === "askmain" || tc.toolName.toLowerCase() === "ask_main");
|
|
18628
|
+
let processedAskMainInTurn = false;
|
|
18333
18629
|
let toolResultsStr = "";
|
|
18334
18630
|
for (const toolCall of toolCalls) {
|
|
18335
18631
|
if (TERMINATION_SIGNAL) {
|
|
@@ -18346,6 +18642,39 @@ ${cleanResponse}
|
|
|
18346
18642
|
}
|
|
18347
18643
|
}
|
|
18348
18644
|
const normalizedToolName = toolCall.toolName.toLowerCase();
|
|
18645
|
+
if (normalizedToolName === "askmain" || normalizedToolName === "ask_main") {
|
|
18646
|
+
if (processedAskMainInTurn) continue;
|
|
18647
|
+
processedAskMainInTurn = true;
|
|
18648
|
+
let questionText = "";
|
|
18649
|
+
let optionsObj = {};
|
|
18650
|
+
if (askMainCalls.length === 1) {
|
|
18651
|
+
const pArgs = parseArgs(askMainCalls[0].args);
|
|
18652
|
+
questionText = pArgs.question || askMainCalls[0].args;
|
|
18653
|
+
optionsObj = pArgs;
|
|
18654
|
+
} else {
|
|
18655
|
+
questionText = askMainCalls.map((tc, idx) => {
|
|
18656
|
+
const pArgs = parseArgs(tc.args);
|
|
18657
|
+
return `Q${idx + 1}: ${pArgs.question || tc.args}`;
|
|
18658
|
+
}).join("\n");
|
|
18659
|
+
optionsObj = {};
|
|
18660
|
+
}
|
|
18661
|
+
if (settings.onAskMain) {
|
|
18662
|
+
if (logCallback) logCallback(`[Executing Tool] AskMain("${questionText}")...`);
|
|
18663
|
+
const answer = await settings.onAskMain(questionText, optionsObj);
|
|
18664
|
+
if (logCallback) logCallback(`[Tool Result]
|
|
18665
|
+
Answer from Main Agent: ${answer}
|
|
18666
|
+
`);
|
|
18667
|
+
toolResultsStr += `[TOOL RESULT for AskMain]: Answer from Main Agent: ${answer}
|
|
18668
|
+
|
|
18669
|
+
`;
|
|
18670
|
+
await incrementUsage("toolSuccess");
|
|
18671
|
+
} else {
|
|
18672
|
+
toolResultsStr += `[TOOL RESULT for AskMain]: ERROR: Main agent communication channel not available.
|
|
18673
|
+
|
|
18674
|
+
`;
|
|
18675
|
+
}
|
|
18676
|
+
continue;
|
|
18677
|
+
}
|
|
18349
18678
|
const allowed = allowedTools ? allowedTools.some((t) => t.toLowerCase() === normalizedToolName) : true;
|
|
18350
18679
|
if (!allowed) {
|
|
18351
18680
|
const errorMsg = `ERROR: Tool [${toolCall.toolName}] is not in the allowed tools list for this subagent.`;
|
|
@@ -22601,10 +22930,27 @@ Selection: ${val}`,
|
|
|
22601
22930
|
commitActiveStreamingMessage();
|
|
22602
22931
|
inThinkMode = true;
|
|
22603
22932
|
thinkConsumedInTurn = true;
|
|
22604
|
-
let thinkStartText = afterText.replace(/<(think|thought)>/gi, "");
|
|
22605
22933
|
currentThinkId = "think-" + Date.now();
|
|
22606
22934
|
activeStreamingMsgRef.current = { id: currentThinkId, role: "think", text: "", isStreaming: true, startTime: Date.now() };
|
|
22607
|
-
|
|
22935
|
+
if (afterText.match(/<\/(think|thought)>/i)) {
|
|
22936
|
+
const parts = afterText.split(/<\/(think|thought)>/i);
|
|
22937
|
+
const rawThinkContent = parts[0] || "";
|
|
22938
|
+
const thinkContent = rawThinkContent.replace(/^<(think|thought)>/i, "");
|
|
22939
|
+
const agentContent = parts.slice(2).join("").replace(/<\/?(think|thought)>/gi, "");
|
|
22940
|
+
activeStreamingMsgRef.current.text = flattenString(thinkContent);
|
|
22941
|
+
const startTime = activeStreamingMsgRef.current.startTime || Date.now();
|
|
22942
|
+
activeStreamingMsgRef.current.duration = Date.now() - startTime;
|
|
22943
|
+
commitActiveStreamingMessage();
|
|
22944
|
+
inThinkMode = false;
|
|
22945
|
+
currentAgentId = "agent-" + Date.now();
|
|
22946
|
+
activeStreamingMsgRef.current = { id: currentAgentId, role: "agent", text: "", isStreaming: true };
|
|
22947
|
+
if (agentContent) {
|
|
22948
|
+
appendStreamText(agentContent);
|
|
22949
|
+
}
|
|
22950
|
+
} else {
|
|
22951
|
+
let thinkStartText = afterText.replace(/^<(think|thought)>/gi, "");
|
|
22952
|
+
appendStreamText(thinkStartText);
|
|
22953
|
+
}
|
|
22608
22954
|
continue;
|
|
22609
22955
|
}
|
|
22610
22956
|
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 ---",
|