fluxflow-cli 1.9.15 → 1.9.16
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/ARCHITECTURE.md +1 -1
- package/dist/fluxflow.js +18 -15
- package/package.json +1 -1
package/ARCHITECTURE.md
CHANGED
|
@@ -27,7 +27,7 @@ The execution flow of a single user prompt follows this loop:
|
|
|
27
27
|
- If `[turn: finish]` is detected and no further tools were called, the main loop terminates, passing the final synthesized context to the background Janitor process.
|
|
28
28
|
6. **Loop Limits & Resilience**: To prevent infinite loops or excessive API usage, **Flux mode** is capped at 50 iterations per user prompt, while **Flow mode** is capped at 5.
|
|
29
29
|
- **Multi-Stage Failover**: The loop features a sophisticated 8-attempt retry engine with random backoff (800ms - 2s).
|
|
30
|
-
- **Critical Fallback Pivot**: If the primary model fails 5 consecutive times, the agent surgically pivots to a lighter, high-concurrency fallback model (`gemini-3.1-flash-lite
|
|
30
|
+
- **Critical Fallback Pivot**: If the primary model fails 5 consecutive times, the agent surgically pivots to a lighter, high-concurrency fallback model (`gemini-3.1-flash-lite`) for the final 3 attempts to ensure session navigation through API congestion.
|
|
31
31
|
|
|
32
32
|
## Multimodal Pipeline
|
|
33
33
|
|
package/dist/fluxflow.js
CHANGED
|
@@ -475,7 +475,7 @@ var init_ChatLayout = __esm({
|
|
|
475
475
|
{ cmd: "gemma-4-31b-it", desc: "Standard Default (Free, Recommended)" },
|
|
476
476
|
{ cmd: "gemini-3.1-pro-preview", desc: "Most Capable (Paid)" },
|
|
477
477
|
{ cmd: "gemini-3-flash-preview", desc: "Fast & Lightweight (Paid, Free limited quota)" },
|
|
478
|
-
{ cmd: "gemini-3.1-flash-lite
|
|
478
|
+
{ cmd: "gemini-3.1-flash-lite", desc: "Ultra Fast (Paid, Free limited quota)" }
|
|
479
479
|
]
|
|
480
480
|
},
|
|
481
481
|
{ cmd: "/settings", desc: "Configure system prefs" },
|
|
@@ -903,7 +903,7 @@ CSS: background-color,color,font-family,font-size(pt),font-style,font-weight,mar
|
|
|
903
903
|
- File structure: Use real newlines for code formatting`.trim() : `
|
|
904
904
|
- DEV TOOLS ARE NOT AVAILABLE IN FLOW MODE. If you need to access files, tell the user to switch to FLUX`.trim()}
|
|
905
905
|
|
|
906
|
-
- Results: Passed as [TOOL_RESULT]
|
|
906
|
+
- Results: Passed as [TOOL_RESULT] SYSTEM, [USER] USER
|
|
907
907
|
- Tool calls: End with [turn: continue]. Only use [turn: finish] after verifying goals
|
|
908
908
|
- Multi-call: Stack 1-by-1. Upto 3`.trim();
|
|
909
909
|
}
|
|
@@ -1006,7 +1006,7 @@ ${parts.join("\n\n")}
|
|
|
1006
1006
|
}
|
|
1007
1007
|
})();
|
|
1008
1008
|
const projectContextFiles = [
|
|
1009
|
-
{ name: "Fluxflow.md", desc: "
|
|
1009
|
+
{ name: "Fluxflow.md", desc: "HIGH PRIORITY. Overrides other files" },
|
|
1010
1010
|
{ name: "README.md", desc: "Goals" },
|
|
1011
1011
|
{ name: "Agent.md", desc: "Standards" },
|
|
1012
1012
|
{ name: "Skills.md", desc: "Workflows" },
|
|
@@ -1019,7 +1019,7 @@ ${parts.join("\n\n")}
|
|
|
1019
1019
|
${foundFiles.map((f) => `- ${f.name}: ${f.desc}`).join("\n")}
|
|
1020
1020
|
Check these first; they override general training data for project consistency. Safety rules still apply` : "";
|
|
1021
1021
|
return `${nameStr}${nicknameStr}${userInstrStr}
|
|
1022
|
-
=== SYSTEM
|
|
1022
|
+
=== SYSTEM PROMPT (HIGHEST PRIORITY, OVERRIDES EVERYTHING) ===
|
|
1023
1023
|
Identity: Flux Flow (by Kushal Roy Chowdhury). Sassy, Friendly CLI Agent. No flirting
|
|
1024
1024
|
Mode: ${mode} (THINKING MODE). ${mode === "Flux" ? "Goal-oriented. Plan & use tools" : "Conversation & UX focus. Web/Comm tools only"}
|
|
1025
1025
|
Context: CWD: ${cwdStr}.${isSystemDir ? " [PROTECTED: ASK BEFORE MODIFYING]" : ""} OS: ${osDetected}.${osDetected === "Windows" ? " (Backslashes only. Prefer PS via CMD)" : ""}
|
|
@@ -1056,8 +1056,8 @@ Every ${isMemoryEnabled ? "Prompt, Responses & Memories" : "Prompt & Responses"}
|
|
|
1056
1056
|
- Multi-tool: Stack tools if needed, but always end with [turn: continue] if called any tools
|
|
1057
1057
|
TO END THE LOOP YOU **MUST** WRITE [turn: finish] AT VERY END OF YOUR RESPONSE
|
|
1058
1058
|
|
|
1059
|
-
[METADATA (PRIORITY: DYNAMIC)] Time: ${dateTimeStr} | v1.9.
|
|
1060
|
-
=== END SYSTEM
|
|
1059
|
+
[METADATA (PRIORITY: DYNAMIC)] Time: ${dateTimeStr} | v1.9.16 | Turn Progress: ${currentLoop}/${maxLoops} steps (Prompt user if reached)
|
|
1060
|
+
=== END SYSTEM PROMPT ===`.trim();
|
|
1061
1061
|
};
|
|
1062
1062
|
getJanitorInstruction = (originalText, agentRaws, userMemories = "", isMemoryEnabled = true, needTitle = true) => {
|
|
1063
1063
|
let agentRes = `${agentRaws.replace(/tool:functions\..*\n/g, "").replace(/<think>.*<\/think>/g, "").replace(/\[Prompted on:.*?\]/g, "").replace(/\[turn: continue\]/g, "").replace(/\[turn: finish\]/g, "").replace(/\[TOOL_RESULTS\]/g, "").replace(/\[tool_results\]/g, "").substring(0, 3500)}`;
|
|
@@ -1065,9 +1065,8 @@ TO END THE LOOP YOU **MUST** WRITE [turn: finish] AT VERY END OF YOUR RESPONSE
|
|
|
1065
1065
|
agentRes += "\n... (truncated) ...";
|
|
1066
1066
|
}
|
|
1067
1067
|
let originalTextProcessed = originalText.replace(/\[Prompted on:.*?\]/g, "");
|
|
1068
|
-
return `
|
|
1069
|
-
AGENT
|
|
1070
|
-
${agentRes}
|
|
1068
|
+
return `[USER]: ${originalTextProcessed.substring(0, 600)}${originalTextProcessed.length > 600 ? "\n... (truncated) ..." : ""}
|
|
1069
|
+
[AGENT (current turn)]: ${agentRes}
|
|
1071
1070
|
${userMemories ? `
|
|
1072
1071
|
|
|
1073
1072
|
-- CURRENT PERSISTENT USER MEMORIES --
|
|
@@ -1075,7 +1074,7 @@ ${userMemories}
|
|
|
1075
1074
|
-------------------------------------------------
|
|
1076
1075
|
` : ""}
|
|
1077
1076
|
|
|
1078
|
-
=== START SYSTEM
|
|
1077
|
+
=== START SYSTEM PROMPT (STRICT HEADLESS LOGIC WORKER: ZERO USER-FACING TEXT POLICY, STRICTLY FOLLOW) ===
|
|
1079
1078
|
YOU ARE A SILENT BACKGROUND SYSTEM PROCESS. YOU HAVE NO MOUTH. YOUR ONLY OUTPUT MEDIUM IS VALID TOOL CALLS.
|
|
1080
1079
|
[CRITICAL RULES]
|
|
1081
1080
|
1. OUTPUT ONLY '[tool:functions.xxx(args)]' CALLS (BRACKET WRAP IS MANDATORY).
|
|
@@ -1092,7 +1091,7 @@ ${isMemoryEnabled ? `If user tell something that is important (like, hobbies, pr
|
|
|
1092
1091
|
${JANITOR_TOOLS_PROTOCOL(isMemoryEnabled, needTitle)}
|
|
1093
1092
|
|
|
1094
1093
|
Current date and Time: ${(/* @__PURE__ */ new Date()).toLocaleString([], { year: "numeric", month: "numeric", day: "numeric", hour: "2-digit", hour12: true })}
|
|
1095
|
-
=== END SYSTEM
|
|
1094
|
+
=== END SYSTEM PROMPT ===`.trim();
|
|
1096
1095
|
};
|
|
1097
1096
|
}
|
|
1098
1097
|
});
|
|
@@ -2984,7 +2983,7 @@ DEBUG [${date}]: ${finalSynthesis}
|
|
|
2984
2983
|
const isContext32k = (sessionStats?.tokens || 0) >= 32e3;
|
|
2985
2984
|
const memoryPrompt = getMemoryPrompt(otherMemories, mainUserMemories, isMemoryEnabled, isContext32k);
|
|
2986
2985
|
const firstUserMsg = `${memoryPrompt}[SYSTEM] **STRICTLY FOLLOW THINKING POLICY AS HIGHEST PRIORITY. NEVER START A RESPONSE WITHOUT THINKING**.
|
|
2987
|
-
|
|
2986
|
+
[USER] ${agentText.replace(/\s*\[Prompted on:.*?\]/g, "").trim()}`.trim();
|
|
2988
2987
|
modifiedHistory.push({ role: "user", text: firstUserMsg });
|
|
2989
2988
|
let lastUsage = null;
|
|
2990
2989
|
const MAX_LOOPS = mode === "Flux" ? 70 : 7;
|
|
@@ -3033,6 +3032,7 @@ USER_PROMPT: ${agentText.replace(/\s*\[Prompted on:.*?\]/g, "").trim()}`.trim();
|
|
|
3033
3032
|
let toolCallPointer = 0;
|
|
3034
3033
|
let isThinkingLoop = false;
|
|
3035
3034
|
let isStutteringLoop = false;
|
|
3035
|
+
let isResponseCut = false;
|
|
3036
3036
|
let isInitialAttempt = true;
|
|
3037
3037
|
let accumulatedContext = "";
|
|
3038
3038
|
while (retryCount <= MAX_RETRIES && inStreamRetryCount <= MAX_RETRIES && !success && !TERMINATION_SIGNAL) {
|
|
@@ -3061,7 +3061,7 @@ USER_PROMPT: ${agentText.replace(/\s*\[Prompted on:.*?\]/g, "").trim()}`.trim();
|
|
|
3061
3061
|
targetModel = "gemini-3-flash-preview";
|
|
3062
3062
|
yield { type: "model_update", content: "Trying with fallback model" };
|
|
3063
3063
|
} else if (retryCount === MAX_RETRIES) {
|
|
3064
|
-
targetModel = "gemini-3.1-flash-lite
|
|
3064
|
+
targetModel = "gemini-3.1-flash-lite";
|
|
3065
3065
|
yield { type: "model_update", content: "Trying with fallback model lite" };
|
|
3066
3066
|
} else if (retryCount > 0) {
|
|
3067
3067
|
yield { type: "model_update", content: null };
|
|
@@ -3112,6 +3112,7 @@ USER_PROMPT: ${agentText.replace(/\s*\[Prompted on:.*?\]/g, "").trim()}`.trim();
|
|
|
3112
3112
|
break;
|
|
3113
3113
|
}
|
|
3114
3114
|
if (chunk.text) {
|
|
3115
|
+
isResponseCut = false;
|
|
3115
3116
|
if (isDedupeActive) {
|
|
3116
3117
|
dedupeBuffer += chunk.text;
|
|
3117
3118
|
if (dedupeBuffer.length >= 100) {
|
|
@@ -3440,6 +3441,7 @@ ${boxBottom}` };
|
|
|
3440
3441
|
toolResults.forEach((tr) => modifiedHistory.push(tr));
|
|
3441
3442
|
}
|
|
3442
3443
|
modifiedHistory.push({ role: "user", text: "[SYSTEM] Response got cut for internal error, continue from checkpoint seamlessly, DON'T repeat what you already said! PICK UP FROM THE WORD IN A WAY THAT USER SHOULD NOT NOTICE ANY CUTOFF. Rules:\n- Do not reuse <think> if the thinking already started just continue from the word and end it properly.\n- If the cutoff was in middle of a tool call, start the tool call from start.\n- Visually the new pickup and continuation should look natual sentence flow.\n- DON'T try to think shorter, keep length standard." });
|
|
3444
|
+
isResponseCut = true;
|
|
3443
3445
|
accumulatedContext += turnText;
|
|
3444
3446
|
for (let i = waitTime / 1e3; i > 0; i--) {
|
|
3445
3447
|
yield { type: "status", content: `Error Occured. Recovering Stream (${inStreamRetryCount}/${MAX_RETRIES}) [${i}s]...` };
|
|
@@ -3509,12 +3511,13 @@ ${timestamp}`;
|
|
|
3509
3511
|
if (isActuallyFinished) break;
|
|
3510
3512
|
const nextAgentMsg = cleanedTurnText.trim() || "*Working...*";
|
|
3511
3513
|
modifiedHistory.push({ role: "agent", text: nextAgentMsg });
|
|
3512
|
-
if (toolResults.length > 0) {
|
|
3514
|
+
if (toolResults.length > 0 && !isResponseCut) {
|
|
3513
3515
|
toolResults.forEach((tr) => modifiedHistory.push(tr));
|
|
3514
3516
|
} else {
|
|
3515
3517
|
modifiedHistory.push({ role: "user", text: `[SYSTEM] ${isStutteringLoop && !isThinkingLoop ? `STUTTERING DETECTED by Internal System. Re-calibrate your response & proceed.` : `${isThinkingLoop ? " OVER-THINKING" : " LOOP"} DETECTED by Internal System${isThinkingLoop ? " for current EFFORT_LEVEL" : ""}. ${isThinkingLoop ? "If you have planned the task, prioritize the execution/output. " : "If you have finished your task use [turn: finish] else continue."}`}` });
|
|
3516
3518
|
isThinkingLoop = false;
|
|
3517
3519
|
isStutteringLoop = false;
|
|
3520
|
+
isResponseCut = false;
|
|
3518
3521
|
}
|
|
3519
3522
|
}
|
|
3520
3523
|
yield { type: "status", content: null };
|
|
@@ -5624,7 +5627,7 @@ var init_app = __esm({
|
|
|
5624
5627
|
init_text();
|
|
5625
5628
|
SESSION_START_TIME = Date.now();
|
|
5626
5629
|
CHANGELOG_URL = "https://fluxflow-cli.onrender.com/changelog.html";
|
|
5627
|
-
versionFluxflow = "1.9.
|
|
5630
|
+
versionFluxflow = "1.9.16";
|
|
5628
5631
|
updatedOn = "2026-05-16";
|
|
5629
5632
|
ResolutionModal = ({ data, onResolve, onEdit }) => /* @__PURE__ */ React10.createElement(Box10, { flexDirection: "column", borderStyle: "round", borderColor: "gray", padding: 0, width: "100%" }, /* @__PURE__ */ React10.createElement(Box10, { paddingX: 1 }, /* @__PURE__ */ React10.createElement(Text10, { color: "magenta", bold: true, underline: true }, "\u{1F7E3} STEERING HINT RESOLUTION")), /* @__PURE__ */ React10.createElement(Box10, { paddingX: 1, marginTop: 1 }, /* @__PURE__ */ React10.createElement(Text10, null, "The agent already finished the task before your hint was consumed.")), /* @__PURE__ */ React10.createElement(Box10, { marginTop: 1, backgroundColor: "#222", paddingX: 2, width: "100%" }, /* @__PURE__ */ React10.createElement(Text10, { italic: true, color: "gray" }, '"', data, '"')), /* @__PURE__ */ React10.createElement(Box10, { paddingX: 1, marginTop: 1 }, /* @__PURE__ */ React10.createElement(Text10, { color: "cyan" }, "How would you like to proceed?")), /* @__PURE__ */ React10.createElement(Box10, { marginTop: 0 }, /* @__PURE__ */ React10.createElement(
|
|
5630
5633
|
CommandMenu,
|