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.
Files changed (2) hide show
  1. package/dist/fluxflow.js +45 -37
  2. 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='<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>]')]
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, PROACTIVE USAGE) --
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', content='exact memory id')]
998
- - Update: [tool:functions.Memory(action='user', method='update', content-new='string to update', content-old='exact memory id')]
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 + content.length > MAX_CHARS) {
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: content };
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 + content.length} chars)`;
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 'content-old' (id) or 'content-new' for update.";
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
- memories[index].memory = newText;
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 'content' (id) for deletion.";
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(-12).filter((msg) => msg.text && !msg.text.includes("[TOOL RESULT]") && !msg.text.includes("OBSERVATION:")).map((msg) => {
3528
- let processedText = msg.text.replace(/\[tool:functions\..*?\]/g, "").replace(/<think>[\s\S]*?<\/think>/g, "").replace(/\[Prompted on:.*?\]/g, "").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();
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
- true
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 = 5;
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 Memory (${attempts + 1})...\x07`);
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;Memory Error\x07`);
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;Memory Error\x07`);
3674
+ process.stdout.write(`\x1B]0;Finalizing Error\x07`);
3667
3675
  }
3668
3676
  await new Promise((resolve) => setTimeout(resolve, 3e3));
3669
3677
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "fluxflow-cli",
3
- "version": "1.12.5",
4
- "date": "2026-05-22",
3
+ "version": "1.12.7",
4
+ "date": "2026-05-23",
5
5
  "description": "A high-fidelity agentic terminal assistant for the Flux Era.",
6
6
  "keywords": [
7
7
  "ai",