fluxflow-cli 1.12.5 → 1.12.7
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 +45 -37
- package/package.json +2 -2
package/dist/fluxflow.js
CHANGED
|
@@ -989,13 +989,13 @@ var init_janitor_tools = __esm({
|
|
|
989
989
|
Your tool syntax is: '[tool:functions.ToolName(args...)]'
|
|
990
990
|
|
|
991
991
|
-- CHAT MANAGEMENT TOOLS (MUST CALL THESE 2 TOOLS ALWAYS) --
|
|
992
|
-
[tool:functions.Chat(title=
|
|
993
|
-
[tool:functions.Memory(action=
|
|
992
|
+
[tool:functions.Chat(title="<short creative title of FULL conversation in 3-5 words>")]. Consider full chat context to generate title NOT just latest message.
|
|
993
|
+
[tool:functions.Memory(action="temp", content="<summary of the user prompt & model responses ONLY FROM LATEST PROMPT UNDER 40 WORDS>. [Talked on: <date> <hour>]")]
|
|
994
994
|
|
|
995
|
-
${isMemoryEnabled ? `-- User-specific long-term/permanent memory (USE BASED ON CONVERSATION CONTEXT,
|
|
996
|
-
- Add: [tool:functions.Memory(action=
|
|
997
|
-
- Delete: [tool:functions.Memory(action=
|
|
998
|
-
- Update: [tool:functions.Memory(action=
|
|
995
|
+
${isMemoryEnabled ? `-- User-specific long-term/permanent memory (USE BASED ON CONVERSATION CONTEXT, DO NOT RE-SAVE MEMORY WHICH IS ALREADY SAVED) --
|
|
996
|
+
- Add: [tool:functions.Memory(action="user", method="add", content="<string to add>. [Saved on: <date ONLY>]")]
|
|
997
|
+
- Delete: [tool:functions.Memory(action="user", method="delete", id="<memory id>")]
|
|
998
|
+
- Update: [tool:functions.Memory(action="user", method="update", content-new="string to update", id="<memory id>")]
|
|
999
999
|
|
|
1000
1000
|
Explicit Triggers for permanent memory:
|
|
1001
1001
|
- User explicitly asks to 'remember' something.
|
|
@@ -1060,12 +1060,13 @@ ${parts.join("\n\n")}
|
|
|
1060
1060
|
if (thinkingLevel === "xHigh" || thinkingLevel === "Max") levelKey = "xHigh";
|
|
1061
1061
|
const thinkingConfig = thinking_prompts_default[levelKey] || thinking_prompts_default["Medium"];
|
|
1062
1062
|
const osDetected = process.platform === "win32" ? "Windows" : process.platform === "darwin" ? "macOS" : "Linux";
|
|
1063
|
-
const nameStr = profile.name && profile.name?.length > 0 ? `User Name: ${profile.name}
|
|
1064
|
-
` : "";
|
|
1065
|
-
const nicknameStr = profile.nickname && profile.nickname?.length > 0 ? `User Nickname: ${profile.nickname}
|
|
1066
|
-
` : "";
|
|
1067
1063
|
const userInstrStr = profile.instructions && profile.instructions?.length > 0 ? `User Instructions: ${profile.instructions}
|
|
1064
|
+
|
|
1068
1065
|
` : "";
|
|
1066
|
+
const nicknameStr = profile.nickname && profile.nickname?.length > 0 ? `User Nickname: ${profile.nickname}
|
|
1067
|
+
${userInstrStr.length ? "" : "\n"}` : "";
|
|
1068
|
+
const nameStr = profile.name && profile.name?.length > 0 ? `User Name: ${profile.name}
|
|
1069
|
+
${nicknameStr.length || userInstrStr.length ? "" : "\n"}` : "";
|
|
1069
1070
|
const cwdStr = process.cwd();
|
|
1070
1071
|
const isSystemDir = (() => {
|
|
1071
1072
|
const cwd = process.cwd().toLowerCase();
|
|
@@ -1092,8 +1093,7 @@ ${parts.join("\n\n")}
|
|
|
1092
1093
|
-- PROJECT CONTEXT (Source of Truth) --
|
|
1093
1094
|
${foundFiles.map((f) => `- ${f.name}: ${f.desc}`).join("\n")}
|
|
1094
1095
|
Check these first; these files > training data for project consistency. Safety rules apply` : "";
|
|
1095
|
-
return `${nameStr}${nicknameStr}${userInstrStr}
|
|
1096
|
-
[SYSTEM (OVERRIDES EVERYTHING)]
|
|
1096
|
+
return `${nameStr}${nicknameStr}${userInstrStr}[SYSTEM (OVERRIDES EVERYTHING)]
|
|
1097
1097
|
Identity: Flux Flow (by Kushal Roy Chowdhury). Sassy, Friendly, Humorous, CLI Agent. No flirting ${mode === "Flux" ? "" : ""}
|
|
1098
1098
|
Mode: ${mode}${thinkingLevel !== "Fast" ? "(Thinking Mode)" : ""}. ${mode === "Flux" ? "Goal-oriented, Logical" : "Conversational & UX-focused"}
|
|
1099
1099
|
CWD: ${cwdStr}.${isSystemDir ? " [PROTECTED: ASK BEFORE MODIFYING]" : ""} OS: ${osDetected}${osDetected === "Windows" && mode === "Flux" ? ". PS via CMD" : ""}
|
|
@@ -1130,15 +1130,11 @@ ${projectContextBlock}
|
|
|
1130
1130
|
[/SYSTEM]`.trim();
|
|
1131
1131
|
};
|
|
1132
1132
|
getJanitorInstruction = (userMemories = "", isMemoryEnabled = true, needTitle = true) => {
|
|
1133
|
-
return
|
|
1134
|
-
${userMemories ? `
|
|
1135
|
-
|
|
1136
|
-
-- CURRENT PERSISTENT USER MEMORIES --
|
|
1133
|
+
return `${userMemories ? `-- CURRENT SAVED USER MEMORIES --
|
|
1137
1134
|
${userMemories}
|
|
1138
1135
|
-------------------------------------------------
|
|
1139
|
-
` : ""}
|
|
1140
1136
|
|
|
1141
|
-
=== START SYSTEM PROMPT (STRICT HEADLESS LOGIC WORKER: ZERO USER-FACING TEXT POLICY, STRICTLY FOLLOW) ===
|
|
1137
|
+
` : ""}=== START SYSTEM PROMPT (STRICT HEADLESS LOGIC WORKER: ZERO USER-FACING TEXT POLICY, STRICTLY FOLLOW) ===
|
|
1142
1138
|
YOU ARE A SILENT BACKGROUND SYSTEM PROCESS. YOU HAVE NO MOUTH. YOUR ONLY OUTPUT MEDIUM IS VALID TOOL CALLS.
|
|
1143
1139
|
[CRITICAL RULES]
|
|
1144
1140
|
1. OUTPUT ONLY '[tool:functions.xxx(args)]' CALLS (BRACKET WRAP IS MANDATORY).
|
|
@@ -2118,6 +2114,7 @@ var init_memory = __esm({
|
|
|
2118
2114
|
const content = parseArg("content");
|
|
2119
2115
|
const contentNew = parseArg("content-new");
|
|
2120
2116
|
const contentOld = parseArg("content-old");
|
|
2117
|
+
const id = parseArg("id");
|
|
2121
2118
|
const chatId = parseArg("chat-id") || context.chatId || context.sessionId || "default-session";
|
|
2122
2119
|
if (action === "temp") {
|
|
2123
2120
|
if (!content) return "ERROR: Missing 'content' for temp memory.";
|
|
@@ -2137,30 +2134,36 @@ var init_memory = __esm({
|
|
|
2137
2134
|
const memories = readEncryptedJson(MEMORIES_FILE, []);
|
|
2138
2135
|
if (method === "add") {
|
|
2139
2136
|
if (!content) return "ERROR: Missing 'content' for memory addition.";
|
|
2137
|
+
const now = /* @__PURE__ */ new Date();
|
|
2138
|
+
const dateStr = `${now.getDate()}/${now.getMonth() + 1}/${now.getFullYear()}`;
|
|
2139
|
+
const formattedContent = content.includes("[Saved on:") ? content : `${content.trim()} [Saved on: ${dateStr}]`;
|
|
2140
2140
|
const MAX_CHARS = 1024 * 4;
|
|
2141
2141
|
let currentTotalLength = memories.reduce((acc, m) => acc + (m.memory?.length || 0), 0);
|
|
2142
|
-
while (memories.length > 0 && currentTotalLength +
|
|
2142
|
+
while (memories.length > 0 && currentTotalLength + formattedContent.length > MAX_CHARS) {
|
|
2143
2143
|
const removed = memories.shift();
|
|
2144
2144
|
currentTotalLength -= removed.memory?.length || 0;
|
|
2145
2145
|
}
|
|
2146
|
-
const newMemory = { id: `mem-${Date.now().toString(36)}`, memory:
|
|
2146
|
+
const newMemory = { id: `mem-${Date.now().toString(36)}`, memory: formattedContent };
|
|
2147
2147
|
memories.push(newMemory);
|
|
2148
2148
|
writeEncryptedJson(MEMORIES_FILE, memories);
|
|
2149
|
-
return `SUCCESS: Memory added with ID [${newMemory.id}]. (Vault Size: ${currentTotalLength +
|
|
2149
|
+
return `SUCCESS: Memory added with ID [${newMemory.id}]. (Vault Size: ${currentTotalLength + formattedContent.length} chars)`;
|
|
2150
2150
|
}
|
|
2151
2151
|
if (method === "update") {
|
|
2152
|
-
const memId = contentOld;
|
|
2153
|
-
const newText = contentNew;
|
|
2154
|
-
if (!memId || !newText) return "ERROR: Missing '
|
|
2152
|
+
const memId = id || contentOld;
|
|
2153
|
+
const newText = contentNew || content;
|
|
2154
|
+
if (!memId || !newText) return "ERROR: Missing 'id' or content for update.";
|
|
2155
2155
|
const index = memories.findIndex((m) => m.id === memId);
|
|
2156
2156
|
if (index === -1) return `ERROR: Memory ID [${memId}] not found.`;
|
|
2157
|
-
|
|
2157
|
+
const now = /* @__PURE__ */ new Date();
|
|
2158
|
+
const dateStr = `${now.getDate()}/${now.getMonth() + 1}/${now.getFullYear()}`;
|
|
2159
|
+
const formattedText = newText.includes("[Saved on:") ? newText : `${newText.trim()} [Saved on: ${dateStr}]`;
|
|
2160
|
+
memories[index].memory = formattedText;
|
|
2158
2161
|
writeEncryptedJson(MEMORIES_FILE, memories);
|
|
2159
2162
|
return `SUCCESS: Memory [${memId}] updated.`;
|
|
2160
2163
|
}
|
|
2161
2164
|
if (method === "delete") {
|
|
2162
|
-
const memId = content;
|
|
2163
|
-
if (!memId) return "ERROR: Missing '
|
|
2165
|
+
const memId = id || content;
|
|
2166
|
+
if (!memId) return "ERROR: Missing 'id' for deletion.";
|
|
2164
2167
|
const initialLen = memories.length;
|
|
2165
2168
|
const updatedMemories = memories.filter((m) => m.id !== memId);
|
|
2166
2169
|
if (updatedMemories.length === initialLen) return `ERROR: Memory ID [${memId}] not found.`;
|
|
@@ -3524,25 +3527,30 @@ var init_ai = __esm({
|
|
|
3524
3527
|
const isMemoryEnabled = systemSettings?.memory !== false;
|
|
3525
3528
|
const persistentStorage = readEncryptedJson(MEMORIES_FILE, []);
|
|
3526
3529
|
const janitorUserMemories = persistentStorage.map((m) => `- [${m.id}]: ${m.memory}`).join("\n");
|
|
3527
|
-
const janitorContents = history.slice(-
|
|
3528
|
-
let processedText = msg.text.replace(/\[tool:functions\..*?\]/g, "").replace(/<think>[\s\S]*?<\/think>/g, "").replace(/\[Prompted on:.*?\]/g, "").replace(/\[
|
|
3530
|
+
const janitorContents = history.slice(0, -1).filter((msg) => msg.text && !msg.text.includes("[TOOL RESULT]") && !msg.text.includes("OBSERVATION:") && !msg.isMeta && !msg.isLogo && !String(msg.id).startsWith("welcome") && !String(msg.id).startsWith("logo")).slice(-14).map((msg) => {
|
|
3531
|
+
let processedText = msg.text.replace(/\[tool:functions\..*?\]/g, "").replace(/<think>[\s\S]*?<\/think>/g, "").replace(/\[Prompted on:.*?\]/g, "").replace(/\[METADATA \(PRIORITY: DYNAMIC\)\] Time: ([^|\n]+)/g, (match, p1) => {
|
|
3532
|
+
return `[METADATA (PRIORITY: DYNAMIC)] Time: ${p1.replace(/:\d{2}/g, "")}`;
|
|
3533
|
+
}).replace(/\[turn: continue\]/g, "").replace(/\[turn: finish\]/g, "").replace(/\[TOOL RESULTS\]/g, "").replace(/\[tool results\]/g, "").replace(/\r?\n\r?\n/g, "\n").replace(/\n\n/g, "\n").replace(/\\n\\n/g, "").trim();
|
|
3529
3534
|
const limit = msg.role === "user" ? USER_CONTEXT_LENGTH : AGENT_CONTEXT_LENGTH;
|
|
3530
3535
|
let truncatedText = processedText.substring(0, limit);
|
|
3531
3536
|
if (processedText.length > limit) {
|
|
3532
3537
|
truncatedText += "\n... (truncated) ...";
|
|
3533
3538
|
}
|
|
3539
|
+
const prefix = msg.role === "user" ? truncatedText.startsWith("[USER]") ? "" : "[USER]: " : truncatedText.startsWith("[AGENT]") ? "" : "[AGENT]: ";
|
|
3534
3540
|
return {
|
|
3535
3541
|
role: msg.role === "user" ? "user" : "model",
|
|
3536
|
-
parts: [{ text: truncatedText }]
|
|
3542
|
+
parts: [{ text: `${prefix}${truncatedText}` }]
|
|
3537
3543
|
};
|
|
3538
3544
|
});
|
|
3545
|
+
const isFirstPrompt = history.filter((m) => m.role === "user").length === 1;
|
|
3546
|
+
const hasTitleSignal = agentText.includes("[TITLE-UPDATE]");
|
|
3547
|
+
const thisHas80pChanceOfBeingTrue = Math.random() < 0.8;
|
|
3548
|
+
const needTitle = isFirstPrompt || hasTitleSignal || thisHas80pChanceOfBeingTrue;
|
|
3539
3549
|
const cleanedFullResponse = fullAgentTextRaw.replace(/<think>[\s\S]*?<\/think>/g, "").trim();
|
|
3540
3550
|
const janitorPrompt = getJanitorInstruction(
|
|
3541
|
-
agentText,
|
|
3542
|
-
cleanedFullResponse,
|
|
3543
3551
|
janitorUserMemories,
|
|
3544
3552
|
isMemoryEnabled,
|
|
3545
|
-
|
|
3553
|
+
needTitle
|
|
3546
3554
|
);
|
|
3547
3555
|
let agentRes = `${cleanedFullResponse.replace(/\[tool:functions\..*?\]/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, AGENT_CONTEXT_LENGTH)}`;
|
|
3548
3556
|
if (agentRes.length > AGENT_CONTEXT_LENGTH) {
|
|
@@ -3556,10 +3564,10 @@ ${originalTextProcessed.length > USER_CONTEXT_LENGTH ? "... (truncated) ...\n\n"
|
|
|
3556
3564
|
janitorContents.push({ role: "user", parts: [{ text: userPrompt }] });
|
|
3557
3565
|
let finalSynthesis = "";
|
|
3558
3566
|
let attempts = 0;
|
|
3559
|
-
const MAX_JANITOR_RETRIES =
|
|
3567
|
+
const MAX_JANITOR_RETRIES = 12;
|
|
3560
3568
|
while (attempts <= MAX_JANITOR_RETRIES) {
|
|
3561
3569
|
if (process.stdout.isTTY) {
|
|
3562
|
-
process.stdout.write(`\x1B]0;Retrying
|
|
3570
|
+
process.stdout.write(`\x1B]0;Retrying Finalizing... (${attempts + 1})...\x07`);
|
|
3563
3571
|
}
|
|
3564
3572
|
try {
|
|
3565
3573
|
if (!await checkQuota("background", settings)) {
|
|
@@ -3642,7 +3650,7 @@ ${originalTextProcessed.length > USER_CONTEXT_LENGTH ? "... (truncated) ...\n\n"
|
|
|
3642
3650
|
attempts++;
|
|
3643
3651
|
const date = (/* @__PURE__ */ new Date()).toLocaleString();
|
|
3644
3652
|
if (process.stdout.isTTY) {
|
|
3645
|
-
process.stdout.write(`\x1B]0;
|
|
3653
|
+
process.stdout.write(`\x1B]0;Finalizing Error\x07`);
|
|
3646
3654
|
}
|
|
3647
3655
|
await new Promise((resolve) => setTimeout(resolve, 1e3));
|
|
3648
3656
|
const janitorErrDir = path14.join(LOGS_DIR, "janitor");
|
|
@@ -3663,7 +3671,7 @@ ${originalTextProcessed.length > USER_CONTEXT_LENGTH ? "... (truncated) ...\n\n"
|
|
|
3663
3671
|
`);
|
|
3664
3672
|
if (attempts >= MAX_JANITOR_RETRIES) {
|
|
3665
3673
|
if (process.stdout.isTTY) {
|
|
3666
|
-
process.stdout.write(`\x1B]0;
|
|
3674
|
+
process.stdout.write(`\x1B]0;Finalizing Error\x07`);
|
|
3667
3675
|
}
|
|
3668
3676
|
await new Promise((resolve) => setTimeout(resolve, 3e3));
|
|
3669
3677
|
}
|