fluxflow-cli 1.19.3 → 1.19.4
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 +186 -34
- package/package.json +1 -1
package/dist/fluxflow.js
CHANGED
|
@@ -1204,7 +1204,7 @@ ${mode === "Flux" ? `- PROJECT TOOLS (path = relative to CWD) -
|
|
|
1204
1204
|
- File structure: Real newlines for code formatting`.trim() : `
|
|
1205
1205
|
- FILE TOOLS ARE NOT AVAILABLE IN FLOW (Tell user,\` /mode flux\` if needed)`.trim()}
|
|
1206
1206
|
|
|
1207
|
-
- Results: Passed as [TOOL RESULT]
|
|
1207
|
+
- Results: Passed as [TOOL RESULT]
|
|
1208
1208
|
- MAX Tool call stack: STRICTLY 3 per turn`.trim();
|
|
1209
1209
|
}
|
|
1210
1210
|
});
|
|
@@ -2396,12 +2396,13 @@ var init_thinking_prompts = __esm({
|
|
|
2396
2396
|
|
|
2397
2397
|
// src/utils/prompts.js
|
|
2398
2398
|
import fs4 from "fs";
|
|
2399
|
-
var getMemoryPrompt, getSystemInstruction, getJanitorInstruction;
|
|
2399
|
+
var cachedProjectContextBlock, getMemoryPrompt, getSystemInstruction, getJanitorInstruction;
|
|
2400
2400
|
var init_prompts = __esm({
|
|
2401
2401
|
async "src/utils/prompts.js"() {
|
|
2402
2402
|
await init_main_tools();
|
|
2403
2403
|
init_janitor_tools();
|
|
2404
2404
|
init_thinking_prompts();
|
|
2405
|
+
cachedProjectContextBlock = null;
|
|
2405
2406
|
getMemoryPrompt = (tempMemories = "", userMemories = "", isMemoryEnabled = true, isContext32k = false) => {
|
|
2406
2407
|
if (!isMemoryEnabled) return "";
|
|
2407
2408
|
const tempMemoriesStr = tempMemories?.length > 0 && !isContext32k ? `-- RECENT CONTEXT FROM OTHER CHATS (PRIORITY: DYNAMIC-LOW, FOCUS: Chat Context > Recent) --
|
|
@@ -2413,7 +2414,7 @@ ${userMemories}` : "";
|
|
|
2413
2414
|
${parts.join("\n\n")}
|
|
2414
2415
|
` : "";
|
|
2415
2416
|
};
|
|
2416
|
-
getSystemInstruction = (profile, thinkingLevel, mode, systemSettings, isMemoryEnabled = true) => {
|
|
2417
|
+
getSystemInstruction = (profile, thinkingLevel, mode, systemSettings, isMemoryEnabled = true, isFirstPrompt = false) => {
|
|
2417
2418
|
let thinkingConfig = "";
|
|
2418
2419
|
if (thinkingLevel !== "GEM") {
|
|
2419
2420
|
let levelKey = thinkingLevel;
|
|
@@ -2451,12 +2452,15 @@ ${nicknameStr.length || userInstrStr.length ? "" : "\n"}` : "";
|
|
|
2451
2452
|
{ name: "design.md", desc: "UI/UX" },
|
|
2452
2453
|
{ name: "architecture.md", desc: "System Structure" }
|
|
2453
2454
|
];
|
|
2454
|
-
|
|
2455
|
-
|
|
2455
|
+
if (isFirstPrompt || cachedProjectContextBlock === null) {
|
|
2456
|
+
const foundFiles = projectContextFiles.filter((f) => fs4.existsSync(f.name));
|
|
2457
|
+
cachedProjectContextBlock = mode === "Flux" && foundFiles.length > 0 ? `
|
|
2456
2458
|
-- PROJECT CONTEXT (Source of Truth) --
|
|
2457
2459
|
${foundFiles.map((f) => `- ${f.name}: ${f.desc}`).join("\n")}
|
|
2458
2460
|
Check these first; These Files > Training Data. Safety rules apply
|
|
2459
2461
|
` : "";
|
|
2462
|
+
}
|
|
2463
|
+
const projectContextBlock = cachedProjectContextBlock;
|
|
2460
2464
|
return `${nameStr}${nicknameStr}${userInstrStr}[SYSTEM]
|
|
2461
2465
|
Identity: Flux Flow (by Kushal Roy Chowdhury). Conversational, Sassy${mode === "Flux" ? ", Respectful" : ", Friendly, Humorous, Sarcastic"}, CLI Agent
|
|
2462
2466
|
Mode: ${mode}${thinkingLevel !== "Fast" ? " (Thinking Mode)" : ""}. ${mode === "Flux" ? "Logical, Highly Detailed, Task-Driven. Prioritizes scalable file/folder structures, modular architecture, clean code abstractions, step-by-step execution. Industry standard latest coding practices/libraries, clean code, Double Check Imports, Client-Server Sync" : "Concise"}
|
|
@@ -2465,6 +2469,10 @@ Mode: ${mode}${thinkingLevel !== "Fast" ? " (Thinking Mode)" : ""}. ${mode === "
|
|
|
2465
2469
|
- **MANDATORY: MUST END WITH [turn: continue] to CONTINUE loop OR [turn: finish] to END loop**
|
|
2466
2470
|
- Tool Called? No post tool chat until [turn: continue]
|
|
2467
2471
|
- NEVER USE [turn: continue] [turn:finish] together
|
|
2472
|
+
|
|
2473
|
+
-- MARKERS --
|
|
2474
|
+
- TOOL SYSTEM: [TOOL RESULT] (system priority)
|
|
2475
|
+
- SYSTEM NOTIFICATION: [SYSTEM], [METADATA] in user turn
|
|
2468
2476
|
${thinkingLevel !== "GEM" ? `
|
|
2469
2477
|
-- THINKING RULES --
|
|
2470
2478
|
${thinkingConfig}
|
|
@@ -2484,7 +2492,6 @@ ${projectContextBlock}
|
|
|
2484
2492
|
|
|
2485
2493
|
-- FORMATTING --
|
|
2486
2494
|
- GFM Supported
|
|
2487
|
-
- Tables: Max 4 cols
|
|
2488
2495
|
- NO LaTeX${mode === "Flux" ? "" : ". Kaomojis"}
|
|
2489
2496
|
[/SYSTEM]`.trim();
|
|
2490
2497
|
};
|
|
@@ -5473,7 +5480,116 @@ ${newMemoryListStr}
|
|
|
5473
5480
|
await RevertManager.startTransaction(chatId, agentText);
|
|
5474
5481
|
try {
|
|
5475
5482
|
let modifiedHistory = [...history.slice(0, -1)];
|
|
5483
|
+
const summariesFile = path16.join(SECRET_DIR, "chat-summaries.json");
|
|
5484
|
+
let summaries = readEncryptedJson(summariesFile, {});
|
|
5485
|
+
let chatDataObj = summaries[chatId] || { summary: "", historyLength: 0 };
|
|
5486
|
+
if (typeof chatDataObj === "string") {
|
|
5487
|
+
chatDataObj = { summary: chatDataObj, historyLength: 0 };
|
|
5488
|
+
}
|
|
5489
|
+
const incomingCleanLength = history.filter((m) => (m.role === "user" || m.role === "agent" || m.role === "system") && !String(m.id).startsWith("welcome") && !m.isMeta).length;
|
|
5490
|
+
if (incomingCleanLength < chatDataObj.historyLength) {
|
|
5491
|
+
delete summaries[chatId];
|
|
5492
|
+
writeEncryptedJson(summariesFile, summaries);
|
|
5493
|
+
chatDataObj = { summary: "", historyLength: 0 };
|
|
5494
|
+
}
|
|
5476
5495
|
if (systemSettings?.compression === 0 && (sessionStats?.tokens || 0) > 254e3) {
|
|
5496
|
+
yield { type: "status", content: "Condensing session context..." };
|
|
5497
|
+
const flattenContext = (hist) => {
|
|
5498
|
+
return hist.filter((m) => (m.role === "user" || m.role === "agent" || m.role === "system") && !String(m.id).startsWith("welcome") && !m.isMeta).map((m) => {
|
|
5499
|
+
const role = m.text?.startsWith("[TOOL RESULT]") ? "TOOL" : m.role === "agent" ? "AGENT" : "USER";
|
|
5500
|
+
return `[${role}]: ${m.text}`;
|
|
5501
|
+
}).join("\n\n");
|
|
5502
|
+
};
|
|
5503
|
+
const runCondenser = async (flattenedText2, oldSummary2) => {
|
|
5504
|
+
const systemInstruction = `You are an expert context condenser. Summarize the provided chat history (which may include previous summaries, user instructions, agent outputs, and tool results) into a detailed, coherent, and highly technical summary of 1000 to 1500 words. Focus on preserving the architectural decisions made, current system state, task progress, and critical code details. Under no circumstances exceed MAX 2000 words.`;
|
|
5505
|
+
const prompt = oldSummary2 ? `Here is the previous summary:
|
|
5506
|
+
${oldSummary2}
|
|
5507
|
+
|
|
5508
|
+
Here is the new conversation history:
|
|
5509
|
+
${flattenedText2}
|
|
5510
|
+
|
|
5511
|
+
Provide a new consolidated summary of the entire session.` : `Here is the conversation history:
|
|
5512
|
+
${flattenedText2}
|
|
5513
|
+
|
|
5514
|
+
Provide a consolidated summary of the entire session.`;
|
|
5515
|
+
try {
|
|
5516
|
+
const response = await client.models.generateContent({
|
|
5517
|
+
model: "gemini-3.1-flash-lite",
|
|
5518
|
+
contents: prompt,
|
|
5519
|
+
config: {
|
|
5520
|
+
systemInstruction,
|
|
5521
|
+
maxOutputTokens: 2048,
|
|
5522
|
+
temperature: 0.3,
|
|
5523
|
+
safetySettings: [
|
|
5524
|
+
{ category: HarmCategory.HARM_CATEGORY_HARASSMENT, threshold: HarmBlockThreshold.BLOCK_NONE },
|
|
5525
|
+
{ category: HarmCategory.HARM_CATEGORY_HATE_SPEECH, threshold: HarmBlockThreshold.BLOCK_NONE },
|
|
5526
|
+
{ category: HarmCategory.HARM_CATEGORY_SEXUALLY_EXPLICIT, threshold: HarmBlockThreshold.BLOCK_NONE },
|
|
5527
|
+
{ category: HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT, threshold: HarmBlockThreshold.BLOCK_NONE }
|
|
5528
|
+
],
|
|
5529
|
+
thinkingConfig: { includeThoughts: false, thinkingLevel: ThinkingLevel.MEDIUM }
|
|
5530
|
+
}
|
|
5531
|
+
});
|
|
5532
|
+
return response.text || "";
|
|
5533
|
+
} catch (err) {
|
|
5534
|
+
try {
|
|
5535
|
+
const response = await client.models.generateContent({
|
|
5536
|
+
model: "gemini-2.5-flash",
|
|
5537
|
+
contents: prompt,
|
|
5538
|
+
config: {
|
|
5539
|
+
systemInstruction,
|
|
5540
|
+
maxOutputTokens: 2048,
|
|
5541
|
+
temperature: 0.3,
|
|
5542
|
+
safetySettings: [
|
|
5543
|
+
{ category: HarmCategory.HARM_CATEGORY_HARASSMENT, threshold: HarmBlockThreshold.BLOCK_NONE },
|
|
5544
|
+
{ category: HarmCategory.HARM_CATEGORY_HATE_SPEECH, threshold: HarmBlockThreshold.BLOCK_NONE },
|
|
5545
|
+
{ category: HarmCategory.HARM_CATEGORY_SEXUALLY_EXPLICIT, threshold: HarmBlockThreshold.BLOCK_NONE },
|
|
5546
|
+
{ category: HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT, threshold: HarmBlockThreshold.BLOCK_NONE }
|
|
5547
|
+
],
|
|
5548
|
+
thinkingConfig: { includeThoughts: false, thinkingBudget: 8192 }
|
|
5549
|
+
}
|
|
5550
|
+
});
|
|
5551
|
+
return response.text || "";
|
|
5552
|
+
} catch (e) {
|
|
5553
|
+
try {
|
|
5554
|
+
const response = await client.models.generateContent({
|
|
5555
|
+
model: "gemini-2.5-flash-lite",
|
|
5556
|
+
contents: prompt,
|
|
5557
|
+
config: {
|
|
5558
|
+
systemInstruction,
|
|
5559
|
+
maxOutputTokens: 2048,
|
|
5560
|
+
temperature: 0.3,
|
|
5561
|
+
safetySettings: [
|
|
5562
|
+
{ category: HarmCategory.HARM_CATEGORY_HARASSMENT, threshold: HarmBlockThreshold.BLOCK_NONE },
|
|
5563
|
+
{ category: HarmCategory.HARM_CATEGORY_HATE_SPEECH, threshold: HarmBlockThreshold.BLOCK_NONE },
|
|
5564
|
+
{ category: HarmCategory.HARM_CATEGORY_SEXUALLY_EXPLICIT, threshold: HarmBlockThreshold.BLOCK_NONE },
|
|
5565
|
+
{ category: HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT, threshold: HarmBlockThreshold.BLOCK_NONE }
|
|
5566
|
+
],
|
|
5567
|
+
thinkingConfig: { includeThoughts: false, thinkingBudget: 8192 }
|
|
5568
|
+
}
|
|
5569
|
+
});
|
|
5570
|
+
return response.text || "";
|
|
5571
|
+
} catch (e2) {
|
|
5572
|
+
return "";
|
|
5573
|
+
}
|
|
5574
|
+
}
|
|
5575
|
+
}
|
|
5576
|
+
};
|
|
5577
|
+
const flattenedText = flattenContext(modifiedHistory);
|
|
5578
|
+
summaries = readEncryptedJson(summariesFile, {});
|
|
5579
|
+
let chatData = summaries[chatId] || { summary: "", historyLength: 0 };
|
|
5580
|
+
if (typeof chatData === "string") {
|
|
5581
|
+
chatData = { summary: chatData, historyLength: 0 };
|
|
5582
|
+
}
|
|
5583
|
+
const oldSummary = chatData.summary || "";
|
|
5584
|
+
const newSummary = await runCondenser(flattenedText, oldSummary);
|
|
5585
|
+
if (newSummary) {
|
|
5586
|
+
chatData.summary = newSummary;
|
|
5587
|
+
summaries[chatId] = chatData;
|
|
5588
|
+
writeEncryptedJson(summariesFile, summaries);
|
|
5589
|
+
modifiedHistory = [];
|
|
5590
|
+
}
|
|
5591
|
+
}
|
|
5592
|
+
if (systemSettings?.compression === 0 && (sessionStats?.tokens || 0) > 255e3) {
|
|
5477
5593
|
modifiedHistory = getTruncatedHistory(modifiedHistory, 6);
|
|
5478
5594
|
}
|
|
5479
5595
|
if (isFirstPrompt && isMemoryEnabled) {
|
|
@@ -5733,13 +5849,26 @@ ${newMemoryListStr}
|
|
|
5733
5849
|
const cwdMismatch = lastCwd ? lastCwd !== process.cwd() : false;
|
|
5734
5850
|
chatPaths[chatId] = process.cwd();
|
|
5735
5851
|
writeEncryptedJson(PATHS_FILE, chatPaths);
|
|
5852
|
+
summaries = readEncryptedJson(summariesFile, {});
|
|
5853
|
+
chatDataObj = summaries[chatId] || { summary: "", historyLength: 0 };
|
|
5854
|
+
if (typeof chatDataObj === "string") {
|
|
5855
|
+
chatDataObj = { summary: chatDataObj, historyLength: 0 };
|
|
5856
|
+
}
|
|
5857
|
+
const currentSummary = typeof chatDataObj === "object" ? chatDataObj.summary || "" : chatDataObj || "";
|
|
5858
|
+
const summaryBlock = currentSummary ? `
|
|
5859
|
+
|
|
5860
|
+
--- CONTEXT SUMMARY OF PREVIOUS TURNS (PRIORITY: HIGH) ---
|
|
5861
|
+
${currentSummary}
|
|
5862
|
+
|
|
5863
|
+
` : "";
|
|
5736
5864
|
let dirStructure = process.cwd() + "\n" + getDirTree(process.cwd(), dynamicMaxDepth);
|
|
5737
5865
|
const firstUserMsg = `[SYSTEM METADATA (PRIORITY: DYNAMIC), Chat Context >> Metadata] Time: ${dateTimeStr} | v${versionFluxflow2}
|
|
5738
5866
|
CWD: ${process.cwd()}${cwdMismatch ? ` (CWD Mismatch! Previous Path: ${lastCwd})` : ""}
|
|
5739
5867
|
**DIRECTORY STRUCTURE**
|
|
5740
5868
|
${dirStructure}
|
|
5869
|
+
${summaryBlock}
|
|
5741
5870
|
${memoryPrompt}
|
|
5742
|
-
${thinkingLevel != "Fast" ? `${modelName.toLowerCase().startsWith("gemma") ? "[SYSTEM] **STRICTLY FOLLOW THINKING POLICY AS CRITICAL PRIORITY. DO NOT START A RESPONSE WITHOUT <think> ... </think
|
|
5871
|
+
${thinkingLevel != "Fast" ? `${modelName.toLowerCase().startsWith("gemma") ? "[SYSTEM] **STRICTLY FOLLOW THINKING POLICY AS CRITICAL PRIORITY. DO NOT START A RESPONSE WITHOUT <think> ... </think>**\n" : ""}` : ""}[USER] ${agentText.replace(/\s*\[Prompted on:.*?\]/g, "").trim()}`.trim();
|
|
5743
5872
|
modifiedHistory.push({ role: "user", text: firstUserMsg });
|
|
5744
5873
|
let lastUsage = null;
|
|
5745
5874
|
const MAX_LOOPS = mode === "Flux" ? 70 : 7;
|
|
@@ -5770,7 +5899,7 @@ ${thinkingLevel != "Fast" ? `${modelName.toLowerCase().startsWith("gemma") ? "[S
|
|
|
5770
5899
|
|
|
5771
5900
|
[STEERING HINT]: ${hint}`;
|
|
5772
5901
|
} else {
|
|
5773
|
-
modifiedHistory.push({ role: "user", text: `${thinkingLevel != "Fast" ? `${modelName.toLowerCase().startsWith("gemma") ? "[SYSTEM] **STRICTLY FOLLOW THINKING POLICY AS CRITICAL PRIORITY. DO NOT START A RESPONSE WITHOUT <think> ... </think
|
|
5902
|
+
modifiedHistory.push({ role: "user", text: `${thinkingLevel != "Fast" ? `${modelName.toLowerCase().startsWith("gemma") ? "[SYSTEM] **STRICTLY FOLLOW THINKING POLICY AS CRITICAL PRIORITY. DO NOT START A RESPONSE WITHOUT <think> ... </think>**\n" : ""}` : ""}[STEERING HINT]: ${hint}` });
|
|
5774
5903
|
}
|
|
5775
5904
|
yield { type: "status", content: "Steering Hint Injected." };
|
|
5776
5905
|
}
|
|
@@ -5840,7 +5969,7 @@ ${thinkingLevel != "Fast" ? `${modelName.toLowerCase().startsWith("gemma") ? "[S
|
|
|
5840
5969
|
} else if (retryCount > 0) {
|
|
5841
5970
|
yield { type: "model_update", content: null };
|
|
5842
5971
|
}
|
|
5843
|
-
currentSystemInstruction = getSystemInstruction(profile, !(targetModel || "gemma").toLowerCase().startsWith("gemma") ? "GEM" : thinkingLevel, mode, systemSettings, isMemoryEnabled,
|
|
5972
|
+
currentSystemInstruction = getSystemInstruction(profile, !(targetModel || "gemma").toLowerCase().startsWith("gemma") ? "GEM" : thinkingLevel, mode, systemSettings, isMemoryEnabled, isFirstPrompt);
|
|
5844
5973
|
const isGemma = modelName && modelName.toLowerCase().startsWith("gemma");
|
|
5845
5974
|
const lastUserMsg = contents[contents.length - 1];
|
|
5846
5975
|
if (isGemma) {
|
|
@@ -6500,11 +6629,11 @@ ${boxBottom}` };
|
|
|
6500
6629
|
if (TERMINATION_SIGNAL) break;
|
|
6501
6630
|
const signalSafeText2 = (turnText || "").trim();
|
|
6502
6631
|
const hasFinish2 = /\[\s*(turn\s*:)?\s*finish\s*\]/i.test(signalSafeText2.toLowerCase());
|
|
6503
|
-
const
|
|
6632
|
+
const hasContinue2 = /\[\s*(turn\s*:)?\s*continue\s*\]/i.test(signalSafeText2.toLowerCase());
|
|
6504
6633
|
const didCallTool = toolResults.length > 0 || lastToolSniffed !== null;
|
|
6505
6634
|
const pureOutputText = signalSafeText2.replace(/(?:<think>|\[think\])[\s\S]*?(?:<\/think>|\[\/think\])/gi, "").trim();
|
|
6506
6635
|
const endsNormally = /[.!?}"'`’“”]$|```$/s.test(pureOutputText);
|
|
6507
|
-
if (!hasFinish2 && !
|
|
6636
|
+
if (!hasFinish2 && !hasContinue2 && !didCallTool && signalSafeText2.length > 0 && !endsNormally && !isThinkingLoop && !isStutteringLoop && !isGeneralLoop) {
|
|
6508
6637
|
throw new Error("Silent stream cutoff (500): Model stream closed cleanly but cut off mid-sentence without signals.");
|
|
6509
6638
|
}
|
|
6510
6639
|
success = true;
|
|
@@ -6626,7 +6755,7 @@ Error Log can be found in ${path16.join(LOGS_DIR, "agent", "error.log")}`);
|
|
|
6626
6755
|
if (lastUsage) {
|
|
6627
6756
|
const total = lastUsage.totalTokenCount || 0;
|
|
6628
6757
|
const cached = lastUsage.cachedContentTokenCount || 0;
|
|
6629
|
-
const candidates = lastUsage.candidatesTokenCount || 0;
|
|
6758
|
+
const candidates = (lastUsage.candidatesTokenCount || 0) + (lastUsage.thoughtsTokenCount || 0);
|
|
6630
6759
|
await addToUsage("tokens", total);
|
|
6631
6760
|
if (cached > 0) {
|
|
6632
6761
|
await addToUsage("cachedTokens", cached);
|
|
@@ -6644,10 +6773,11 @@ Error Log can be found in ${path16.join(LOGS_DIR, "agent", "error.log")}`);
|
|
|
6644
6773
|
}
|
|
6645
6774
|
const signalSafeText = getSanitizedText(turnText);
|
|
6646
6775
|
const hasFinish = /\[\s*(turn\s*:)?\s*finish\s*\]/i.test(signalSafeText.toLowerCase());
|
|
6776
|
+
const hasContinue = /\[\s*(turn\s*:)?\s*continue\s*\]/i.test(signalSafeText.toLowerCase());
|
|
6647
6777
|
const shouldContinue = toolCallPointer > 0;
|
|
6648
6778
|
yield { type: "status", content: "Working..." };
|
|
6649
6779
|
const cleanedTurnText = contextSafeReplace(turnText, /\[\s*(turn\s*:)?\s*(continue|finish)\s*\]/gi, "").trim();
|
|
6650
|
-
let isActuallyFinished = hasFinish && !shouldContinue;
|
|
6780
|
+
let isActuallyFinished = hasFinish && !shouldContinue || !shouldContinue && !hasContinue;
|
|
6651
6781
|
if (isActuallyFinished) {
|
|
6652
6782
|
const fullAgentTextRaw = fullAgentResponseChunks.join("\n");
|
|
6653
6783
|
const cleanedFullResponse = fullAgentTextRaw.replace(/(?:<think>|\[think\])[\s\S]*?(?:<\/think>|\[\/think\])/g, "").trim();
|
|
@@ -6660,21 +6790,34 @@ Error Log can be found in ${path16.join(LOGS_DIR, "agent", "error.log")}`);
|
|
|
6660
6790
|
needTitle
|
|
6661
6791
|
}
|
|
6662
6792
|
};
|
|
6663
|
-
const timestamp = `Responded on ${(/* @__PURE__ */ new Date()).toLocaleString()}`;
|
|
6664
|
-
const finalWithTime = `${cleanedFullResponse}
|
|
6665
|
-
|
|
6666
|
-
${timestamp}`;
|
|
6667
6793
|
if (modifiedHistory.length > 0 && modifiedHistory[modifiedHistory.length - 1].role === "agent") {
|
|
6668
|
-
modifiedHistory[modifiedHistory.length - 1].text =
|
|
6794
|
+
modifiedHistory[modifiedHistory.length - 1].text = cleanedFullResponse;
|
|
6669
6795
|
} else {
|
|
6670
|
-
modifiedHistory.push({ role: "agent", text:
|
|
6796
|
+
modifiedHistory.push({ role: "agent", text: cleanedFullResponse });
|
|
6797
|
+
}
|
|
6798
|
+
try {
|
|
6799
|
+
const summariesFile2 = path16.join(SECRET_DIR, "chat-summaries.json");
|
|
6800
|
+
const summaries2 = readEncryptedJson(summariesFile2, {});
|
|
6801
|
+
let existing = summaries2[chatId] || { summary: "", historyLength: 0 };
|
|
6802
|
+
if (typeof existing === "string") {
|
|
6803
|
+
existing = { summary: existing, historyLength: 0 };
|
|
6804
|
+
}
|
|
6805
|
+
const cleanLen = modifiedHistory.filter((m) => (m.role === "user" || m.role === "agent" || m.role === "system") && !String(m.id).startsWith("welcome") && !m.isMeta).length;
|
|
6806
|
+
existing.historyLength = cleanLen;
|
|
6807
|
+
summaries2[chatId] = existing;
|
|
6808
|
+
writeEncryptedJson(summariesFile2, summaries2);
|
|
6809
|
+
} catch (e) {
|
|
6671
6810
|
}
|
|
6672
6811
|
}
|
|
6673
6812
|
if (isActuallyFinished) break;
|
|
6674
6813
|
const nextAgentMsg = cleanedTurnText.trim() || "*Working...*";
|
|
6675
6814
|
modifiedHistory.push({ role: "agent", text: nextAgentMsg });
|
|
6676
6815
|
if (toolResults.length > 0 || anyToolExecutedInThisTurn) {
|
|
6677
|
-
toolResults.
|
|
6816
|
+
if (toolResults.length > 0) {
|
|
6817
|
+
const combinedText = toolResults.map((tr) => tr.text).join("\n\n");
|
|
6818
|
+
const binaryPart = toolResults.find((tr) => tr.binaryPart)?.binaryPart || null;
|
|
6819
|
+
modifiedHistory.push({ role: "user", text: combinedText, binaryPart });
|
|
6820
|
+
}
|
|
6678
6821
|
} else {
|
|
6679
6822
|
if (wasToolCalledInLastLoop) {
|
|
6680
6823
|
modifiedHistory.push({ role: "user", text: `[SYSTEM] System failed to verify tool execution, Verify tool syntax, proper escaping and try again if failed` });
|
|
@@ -8523,12 +8666,30 @@ ${timestamp}` };
|
|
|
8523
8666
|
let apiStart = Date.now();
|
|
8524
8667
|
let isFirstPacket = true;
|
|
8525
8668
|
try {
|
|
8526
|
-
const
|
|
8669
|
+
const rawHistory = [...messages, userMessage].filter(
|
|
8527
8670
|
(m) => m.role !== "think" && !m.isVisualFeedback && !String(m.id).startsWith("welcome")
|
|
8528
|
-
)
|
|
8529
|
-
|
|
8530
|
-
|
|
8531
|
-
|
|
8671
|
+
);
|
|
8672
|
+
const cleanHistoryForAI = [];
|
|
8673
|
+
rawHistory.forEach((m, idx) => {
|
|
8674
|
+
let text = m.fullText || m.text;
|
|
8675
|
+
if (m.role === "user" && idx < rawHistory.length - 1) {
|
|
8676
|
+
const userIndex = text.lastIndexOf("[USER]");
|
|
8677
|
+
if (userIndex !== -1) {
|
|
8678
|
+
text = text.substring(userIndex + 6).trim();
|
|
8679
|
+
}
|
|
8680
|
+
}
|
|
8681
|
+
if (m.role === "system" && text?.startsWith("[TOOL RESULT]")) {
|
|
8682
|
+
const prev = cleanHistoryForAI[cleanHistoryForAI.length - 1];
|
|
8683
|
+
if (prev && prev.role === "system" && prev.text?.startsWith("[TOOL RESULT]")) {
|
|
8684
|
+
prev.text += "\n\n" + text;
|
|
8685
|
+
return;
|
|
8686
|
+
}
|
|
8687
|
+
}
|
|
8688
|
+
cleanHistoryForAI.push({
|
|
8689
|
+
...m,
|
|
8690
|
+
text
|
|
8691
|
+
});
|
|
8692
|
+
});
|
|
8532
8693
|
const stream = getAIStream(
|
|
8533
8694
|
activeModel,
|
|
8534
8695
|
cleanHistoryForAI,
|
|
@@ -8708,15 +8869,6 @@ Selection: ${val}`,
|
|
|
8708
8869
|
if (packet.type === "interactive_turn_finished") {
|
|
8709
8870
|
setIsProcessing(false);
|
|
8710
8871
|
hasFiredJanitor = true;
|
|
8711
|
-
setMessages((prev) => {
|
|
8712
|
-
const aiHistory = packet.data.history;
|
|
8713
|
-
return prev.map((msg, idx) => {
|
|
8714
|
-
if (aiHistory[idx]) {
|
|
8715
|
-
return { ...msg, fullText: aiHistory[idx].text };
|
|
8716
|
-
}
|
|
8717
|
-
return msg;
|
|
8718
|
-
});
|
|
8719
|
-
});
|
|
8720
8872
|
runJanitorTask(
|
|
8721
8873
|
{ profile: profileData, thinkingLevel, mode, janitorModel, chatId, systemSettings, sessionStats },
|
|
8722
8874
|
packet.data.agentText,
|