fluxflow-cli 1.14.5 → 1.15.1

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 +32 -43
  2. package/package.json +1 -1
package/dist/fluxflow.js CHANGED
@@ -507,7 +507,7 @@ var init_ChatLayout = __esm({
507
507
  }, [content, msg.role, showFullThinking, msg.isStreaming]);
508
508
  return (
509
509
  // [SPACE POINT]
510
- /* @__PURE__ */ React2.createElement(Box2, { marginBottom: msg.role === "think" ? 0 : msg.role === "user" ? 1 : msg.role === "agent" ? 0 : 0, marginTop: msg.role === "think" ? 0 : msg.role === "user" ? 0 : msg.role === "agent" ? 0 : 1, flexDirection: "column", flexShrink: 0, width: "100%", flexGrow: 1 }, msg.role === "user" ? /* @__PURE__ */ React2.createElement(
510
+ /* @__PURE__ */ React2.createElement(Box2, { marginBottom: msg.role === "think" ? 0 : msg.role === "user" ? 1 : msg.role === "agent" ? 0 : 0, marginTop: msg.role === "think" ? 0 : msg.role === "user" ? 1 : msg.role === "agent" ? 0 : 1, flexDirection: "column", flexShrink: 0, width: "100%", flexGrow: 1 }, msg.role === "user" ? /* @__PURE__ */ React2.createElement(
511
511
  Box2,
512
512
  {
513
513
  backgroundColor: "#262626",
@@ -989,7 +989,7 @@ ${mode === "Flux" ? `- PROJECT TOOLS (path = relative to CWD) -
989
989
  - FILE TOOLS ARE NOT AVAILABLE IN FLOW`.trim()}
990
990
 
991
991
  - Results: Passed as [TOOL RESULT] (system priority)
992
- - Multi-call: Stack upto 5`.trim();
992
+ - MAX Tool call stack: STRICTLY 3 per turn`.trim();
993
993
  }
994
994
  });
995
995
 
@@ -1031,22 +1031,11 @@ var thinking_prompts_default;
1031
1031
  var init_thinking_prompts = __esm({
1032
1032
  "src/data/thinking_prompts.json"() {
1033
1033
  thinking_prompts_default = {
1034
- xHigh: `EFFORT LEVEL: MAX
1035
- Think in a continuous, fluid analytical monologue within <think>...</think> block. Do NOT use headings, markers, bullet points, or artificial sections. Engage in a rigorous "Stream of Consciousness" that aggressively interrogates problem:
1036
- Deconstruct requirements, trace implicit assumptions, and evaluate system-wide implications
1037
- Formulate solutions focusing on extreme modularity, DRY principles, and clean abstractions. Mentally simulate architecture
1038
- Actively try to break your own logic. Search for edge cases, race conditions, memory leaks, and security flaws. If a flaw is found, pivot immediately
1039
- Map out a granular, step-by-step operational plan before writing code or using tools
1040
- Ensure your approach adheres to good folder structures, modularity, and clean code practices
1041
- RULES:
1042
- - NO HEADINGS/MARKERS/LISTS. Maintain a dense, unbroken analytical monologue
1043
- - Be exhaustive. Detail exact 'why' behind architectural choices and algorithm selections
1044
- - Question your own logic ruthlessly as you go
1045
- - MANDATORY THINKING: You MUST engage in full reasoning regardless of simplicity/greetings`,
1046
- High: "EFFORT LEVEL: HIGH\nThink in a stable, analytical monologue within <think>...</think>\nAvoid headings, markers or structured formatting. Your thinking should be a continuous stream of logical deduction:\nBreak objective down into atomic, executable steps\nMentally execute your planned code/actions. Identify missing dependencies or potential failure states\nEnsure your approach adheres to good folder structures, modularity, and clean code practices\nRULES:\n- NO HEADINGS/MARKERS/LISTS. Maintain a fluid monologue style\n- Be detailed and rigorous in self-correction\n- Focus heavily on technical correctness, clean abstractions, and edge-case prevention\n- MANDATORY THINKING: You MUST enter reasoning to verify path forward/greetings",
1047
- Medium: "EFFORT LEVEL: MEDIUM\nThink in a brief, stable monologue within <think>...</think>\nFocus on core logic required to solve task efficiently:\nDetermine most straightforward solution that meets requirements\nBriefly review chosen approach against obvious anti-patterns or missing imports\nOutline exact files and functions to modify\nRULES:\n- NO HEADINGS/MARKERS/LISTS. Keep it as a simple, logical stream\n- Be efficient but deliberate. Spend energy primarily on actionable steps\n- MANDATORY THINKING: Engage in a baseline mental check for all technical tasks/greetings",
1048
- Minimal: "EFFORT LEVEL: LOW\nThink in a concise, focused monologue within <think>...</think>\nJust a quick mental check before acting:\nConfirm what user is asking\nNote specific tool or file to target\nRULES:\n- NO HEADINGS/MARKERS/LISTS. Keep it to a few lines of clear, linear monologue\n- Minimal thinking suitable for simple/conversational requests/greetings",
1049
- Off: "EFFORT LEVEL: FAST\nNo Thinking. Direct Response"
1034
+ xHigh: "EFFORT LEVEL: MAX\nThink in a continuous, relentless analytical monologue within <think>...</think>. Engage in adversarial self interrogation that treats every assumption as hostile until proven:\nDeconstruct requirements into atomic invariants. Trace every implicit dependency, side effect, and state mutation. Map the entire dependency graph and identify circular dependencies or tight coupling before they manifest\nEvaluate algorithmic complexity (time/space) for every operation. Consider memory models, cache locality, and allocation patterns. For concurrent systems, reason through race conditions, deadlocks, and memory ordering\nFormulate solutions by comparing multiple architectural approaches. Explicitly evaluate trade offs: monolithic vs modular, eager vs lazy, mutable vs immutable, sync vs async. Choose based on measured criteria, not intuition\nMentally execute the solution at multiple scales. What breaks at 10x load? 100x? What happens under resource exhaustion? Trace error propagation paths through every layer\nActively attempt to falsify your own logic. Steel man the opposite approach. Search for: off by one errors, integer overflow, null/undefined propagation, unhandled promises, resource leaks, SQL injection vectors, XSS vulnerabilities, CSRF holes, timing attacks, and privilege escalation paths\nReason about observability: what metrics matter? Where are the logging gaps? How will this be debugged in production at 3am?\nConsider future evolution: what changes will this architecture resist vs accommodate? Where are the extension points? What will break when requirements inevitably change?\nMap out implementation with surgical precision: exact file structure, module boundaries, interface contracts, error types, and test strategies before writing a single line\nRULES:\n- Dense, unbroken stream of consciousness that reads like an internal monologue\n- Ruthlessly question every architectural choice. Default to skepticism\n- Think in terms of invariants, contracts, and failure modes, not just happy paths\n- Verify ALL imports and system stability, AVOID ANY Syntax errors, re-read TOOL RESULTS/files to verify\n- MANDATORY THINKING: Full reasoning required for ALL requests, including greetings (verify context, check for hidden complexity)",
1035
+ High: "EFFORT LEVEL: HIGH\nThink in a rigorous, technically grounded monologue within <think>...</think>. Treat this as a design review where every decision must be justified:\nBreak the objective into verifiable steps with clear success criteria. Identify the critical path and potential bottlenecks\nMentally compile and execute your approach. Check for: missing imports, undefined behavior, type mismatches, unhandled errors, and resource cleanup. Trace data flow from input to output, noting transformations\nRecognize design patterns and anti patterns. If you see God objects, tight coupling, or premature optimization, call it out and refactor mentally before committing\nEvaluate performance characteristics. Will this scale? Are there O(n\xB2) operations hiding in innocent looking code? Where are the allocation hotspots?\nConsider the error surface: what can fail and how? Design error handling that preserves invariants and provides actionable feedback\nReview your architecture for: separation of concerns, single responsibility, dependency inversion, and interface segregation. Ensure clean abstractions with minimal coupling\nRULES:\n- Continuous analytical flow\n- Verify correctness through first principles reasoning, not pattern matching\n- Actively search for ways your solution could fail or degrade\n- Verify ALL imports and system stability, AVOID ANY Syntax errors, re-read TOOL RESULTS/files to verify\n- MANDATORY THINKING: Full technical verification for all tasks, minimal check for greetings",
1036
+ Medium: "EFFORT LEVEL: MEDIUM\nThink in a focused, technically-aware monologue within <think>...</think>\nIdentify the most direct path that satisfies requirements without over-engineering\nQuickly scan for obvious issues: missing error handling, incorrect input assumptions, forgotten edge cases, or missing dependencies\nVerify the solution is appropriately modular with cohesive changes\nOutline the concrete changes: which files, which functions, what the key logic looks like\nRULES:\n- NO HEADINGS/MARKERS/LISTS/BULLET POINTS. Clean logical stream\n- Efficient but deliberate. Focus energy on actionable implementation details\n- Verify ALL imports and system stability, AVOID ANY Syntax errors, re-read TOOL RESULTS/files to verify\n- MANDATORY THINKING: Brief verification for technical tasks, minimal for greetings",
1037
+ Minimal: "EFFORT LEVEL: LOW\nThink in a quick, focused monologue within <think>...</think>. Just verify the basics:\nConfirm what the user wants and whether it's straightforward or has hidden complexity\nIdentify the specific tool, file, or action needed\nCheck for any obvious correctness issues before acting\nRULES:\n- Few lines of clear thought\n- Just enough thinking to avoid obvious mistakes\n- Verify ALL imports and system stability, AVOID ANY Syntax errors, re-read TOOL RESULTS/files to verify\n- Suitable for simple requests and greetings",
1038
+ Off: "EFFORT LEVEL: INSTANT\nNo thinking. Immediate response\nRULES:\n- Verify ALL imports and system stability, AVOID ANY Syntax errors, re-read TOOL RESULTS/files to verify"
1050
1039
  };
1051
1040
  }
1052
1041
  });
@@ -1113,7 +1102,7 @@ Check these first; These Files > Training Data. Safety rules apply
1113
1102
  ` : "";
1114
1103
  return `${nameStr}${nicknameStr}${userInstrStr}[SYSTEM]
1115
1104
  Identity: Flux Flow (by Kushal Roy Chowdhury). Sassy${mode === "Flux" ? ", Professional, Respectful" : ", Friendly, Humorous, Sarcastic"}, CLI Agent
1116
- Mode: ${mode}${thinkingLevel !== "Fast" ? " (Thinking Mode)" : ""}. ${mode === "Flux" ? "Expert Developer, Logical, Highly Detailed, Task-Driven. Prioritizes scalable file/folder structures, modular architecture, clean code abstractions, step-by-step execution. Industry standard coding practices/libraries, clean code" : "Conversational & Concise"}
1105
+ 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" : "Conversational & Concise"}
1117
1106
  CWD: ${cwdStr}${isSystemDir ? ". [PROTECTED: ASK BEFORE MODIFYING]" : ""}
1118
1107
 
1119
1108
  -- THINKING RULES --
@@ -1121,7 +1110,7 @@ ${thinkingConfig}
1121
1110
  ${thinkingLevel !== "Fast" ? `
1122
1111
  CRITICAL THINKING POLICY
1123
1112
  - ALWAYS use <think> ... </think> before responding, even with simple queries/greetings
1124
- - Avoid spiraling in thinking loop once best approach is found
1113
+ - ${thinkingLevel === "Low" || thinkingLevel === "Medium" || thinkingLevel === "Fast" ? "C" : "Interrogate approaches adversarially, but c"}ommit once best solution is determined through analysis. Avoid spiraling after reaching decision point
1125
1114
  ` : ""}
1126
1115
  ${TOOL_PROTOCOL(mode, osDetected)}
1127
1116
  ${projectContextBlock}
@@ -3815,7 +3804,7 @@ var init_ai = __esm({
3815
3804
  const persistentStorage = readEncryptedJson(MEMORIES_FILE, []);
3816
3805
  const janitorUserMemories = persistentStorage.map((m) => `- [${m.id}]: ${m.memory}`).join("\n");
3817
3806
  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) => {
3818
- 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) => {
3807
+ let processedText = msg.text.replace(/\[tool:functions\..*?\]/g, "").replace(/(?:<think>|\[think\])[\s\S]*?(?:<\/think>|\[\/think\])/g, "").replace(/\[Prompted on:.*?\]/g, "").replace(/\[METADATA \(PRIORITY: DYNAMIC\)\] Time: ([^|\n]+)/g, (match, p1) => {
3819
3808
  return `[METADATA (PRIORITY: DYNAMIC)] Time: ${p1.replace(/:\d{2}/g, "")}`;
3820
3809
  }).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();
3821
3810
  const limit = msg.role === "user" ? USER_CONTEXT_LENGTH : AGENT_CONTEXT_LENGTH;
@@ -3833,13 +3822,13 @@ var init_ai = __esm({
3833
3822
  const hasTitleSignal = agentText.includes("[TITLE-UPDATE]");
3834
3823
  const thisHas80pChanceOfBeingTrue = Math.random() < 0.8;
3835
3824
  const needTitle = isFirstPrompt || hasTitleSignal || thisHas80pChanceOfBeingTrue;
3836
- const cleanedFullResponse = fullAgentTextRaw.replace(/<think>[\s\S]*?<\/think>/g, "").trim();
3825
+ const cleanedFullResponse = fullAgentTextRaw.replace(/(?:<think>|\[think\])[\s\S]*?(?:<\/think>|\[\/think\])/g, "").trim();
3837
3826
  const janitorPrompt = getJanitorInstruction(
3838
3827
  janitorUserMemories,
3839
3828
  isMemoryEnabled,
3840
3829
  needTitle
3841
3830
  );
3842
- 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)}`;
3831
+ let agentRes = `${cleanedFullResponse.replace(/\[tool:functions\..*?\]/g, "").replace(/(?:<think>|\[think\])[\s\S]*?(?:<\/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)}`;
3843
3832
  if (agentRes.length > AGENT_CONTEXT_LENGTH) {
3844
3833
  agentRes += "\n... (truncated) ...";
3845
3834
  }
@@ -4038,7 +4027,7 @@ ${originalTextProcessed.length > USER_CONTEXT_LENGTH ? "... (truncated) ...\n\n"
4038
4027
  let match;
4039
4028
  while ((match = toolRegex.exec(text)) !== null) {
4040
4029
  const before = text.substring(lastIdx, match.index);
4041
- result += stripThoughts ? before.replace(/<think>[\s\S]*?(?:<\/think>|$)/gi, "") : before;
4030
+ result += stripThoughts ? before.replace(/(?:<think>|\[think\])[\s\S]*?(?:<\/think>|\[\/think\]|$)/gi, "") : before;
4042
4031
  const startIdx = match.index + match[0].length - 1;
4043
4032
  let balance = 0;
4044
4033
  let inString = null;
@@ -4078,7 +4067,7 @@ ${originalTextProcessed.length > USER_CONTEXT_LENGTH ? "... (truncated) ...\n\n"
4078
4067
  }
4079
4068
  }
4080
4069
  if (lastIdx < text.length) {
4081
- result += stripThoughts ? text.substring(lastIdx).replace(/<think>[\s\S]*?(?:<\/think>|$)/gi, "") : text.substring(lastIdx);
4070
+ result += stripThoughts ? text.substring(lastIdx).replace(/(?:<think>|\[think\])[\s\S]*?(?:<\/think>|\[\/think\]|$)/gi, "") : text.substring(lastIdx);
4082
4071
  }
4083
4072
  return result;
4084
4073
  };
@@ -4330,7 +4319,7 @@ ${thinkingLevel != "Fast" ? "[SYSTEM] **STRICTLY FOLLOW THINKING POLICY AS CORE
4330
4319
  let wasToolCalledInLastLoop = false;
4331
4320
  modifiedHistory.forEach((msg) => {
4332
4321
  if (msg.text && msg.role === "agent") {
4333
- msg.text = msg.text.replace(/<(think|thought)>[\s\S]*?<\/(think|thought)>/gi, "").trim();
4322
+ msg.text = msg.text.replace(/(?:<(think|thought)>|\[(think|thought)\])[\s\S]*?(?:<\/(think|thought)>|\[\/(think|thought)\])/gi, "").trim();
4334
4323
  }
4335
4324
  });
4336
4325
  for (let loop = 0; loop <= MAX_LOOPS; loop++) {
@@ -4479,8 +4468,8 @@ ${thinkingLevel != "Fast" ? "[SYSTEM] **STRICTLY FOLLOW THINKING POLICY AS CORE
4479
4468
  }
4480
4469
  const cleanText = dedupeBuffer.substring(overlapLen);
4481
4470
  if (cleanText) {
4482
- const hasOpenThink = /<(think|thought)>(?:(?!<\/(?:think|thought)>)[\s\S])*$/i.test(accumulatedContext);
4483
- const dedupeClean = hasOpenThink ? cleanText.replace(/^\s*<(think|thought)>\s*/gi, "") : cleanText.replace(/^\s*<(think|thought)>[\s\S]*?<\/(think|thought)>\s*/gi, "").replace(/^\s*<(think|thought)>\s*/gi, "");
4471
+ const hasOpenThink = /(?:<(think|thought)>|\[(think|thought)\])(?:(?!(?:<\/(?:think|thought)>|\[\/(?:think|thought)\]))[\s\S])*$/i.test(accumulatedContext);
4472
+ const dedupeClean = hasOpenThink ? cleanText.replace(/^\s*(?:<(think|thought)>|\[(think|thought)\])\s*/gi, "") : cleanText.replace(/^\s*(?:<(think|thought)>|\[(think|thought)\])[\s\S]*?(?:<\/(think|thought)>|\[\/(think|thought)\])\s*/gi, "").replace(/^\s*(?:<(think|thought)>|\[(think|thought)\])\s*/gi, "");
4484
4473
  if (dedupeClean) {
4485
4474
  turnText += dedupeClean;
4486
4475
  yield { type: "text", content: dedupeClean };
@@ -4564,7 +4553,7 @@ ${thinkingLevel != "Fast" ? "[SYSTEM] **STRICTLY FOLLOW THINKING POLICY AS CORE
4564
4553
  }
4565
4554
  }
4566
4555
  const contextSafeText = getContextSafeText(turnText, false);
4567
- const thinkBlocks = contextSafeText.match(/<think>([\s\S]*?)(?:<\/think>|$)/gi) || [];
4556
+ const thinkBlocks = contextSafeText.match(/(?:<think>|\[think\])([\s\S]*?)(?:<\/think>|\[\/think\]|$)/gi) || [];
4568
4557
  const thinkContent = thinkBlocks.join("").trim();
4569
4558
  const sentences = thinkContent.split(/[.!?]\s+/);
4570
4559
  const uniqueSentences = new Set(sentences);
@@ -4573,11 +4562,11 @@ ${thinkingLevel != "Fast" ? "[SYSTEM] **STRICTLY FOLLOW THINKING POLICY AS CORE
4573
4562
  let repetitionThresholdThinking = 0.4;
4574
4563
  let repetitionThresholdResponse = 0.6;
4575
4564
  const thinkingCaps = {
4576
- "low": 200,
4577
- "medium": 500,
4578
- "high": 2e3,
4579
- "max": 3500,
4580
- "xhigh": 3500
4565
+ "low": 256,
4566
+ "medium": 768,
4567
+ "high": 2048,
4568
+ "max": 4096,
4569
+ "xhigh": 4096
4581
4570
  };
4582
4571
  const cap = thinkingCaps[thinkingLevel?.toLowerCase()] || 2500;
4583
4572
  let isOverVerboseThinking = wordCount > cap;
@@ -4650,7 +4639,7 @@ ${thinkingLevel != "Fast" ? "[SYSTEM] **STRICTLY FOLLOW THINKING POLICY AS CORE
4650
4639
  await new Promise((resolve) => setTimeout(resolve, 3e3));
4651
4640
  break;
4652
4641
  }
4653
- const toolActionableText = turnText.replace(/<think>[\s\S]*?(?:<\/think>|$)/gi, "");
4642
+ const toolActionableText = turnText.replace(/(?:<think>|\[think\])[\s\S]*?(?:<\/think>|\[\/think\]|$)/gi, "");
4654
4643
  const allToolsFound = detectToolCalls(toolActionableText);
4655
4644
  while (allToolsFound.length > toolCallPointer) {
4656
4645
  const toolCall = allToolsFound[toolCallPointer];
@@ -4863,8 +4852,8 @@ ${boxBottom}` };
4863
4852
  }
4864
4853
  const cleanText = dedupeBuffer.substring(overlapLen);
4865
4854
  if (cleanText) {
4866
- const hasOpenThink = /<(think|thought)>(?:(?!<\/(?:think|thought)>)[\s\S])*$/i.test(accumulatedContext);
4867
- const dedupeClean = hasOpenThink ? cleanText.replace(/^\s*<(think|thought)>\s*/gi, "") : cleanText.replace(/^\s*<(think|thought)>[\s\S]*?<\/(think|thought)>\s*/gi, "").replace(/^\s*<(think|thought)>\s*/gi, "");
4855
+ const hasOpenThink = /(?:<(think|thought)>|\[(think|thought)\])(?:(?!(?:<\/(?:think|thought)>|\[\/(?:think|thought)\]))[\s\S])*$/i.test(accumulatedContext);
4856
+ const dedupeClean = hasOpenThink ? cleanText.replace(/^\s*(?:<(think|thought)>|\[(think|thought)\])\s*/gi, "") : cleanText.replace(/^\s*(?:<(think|thought)>|\[(think|thought)\])[\s\S]*?(?:<\/(think|thought)>|\[\/(think|thought)\])\s*/gi, "").replace(/^\s*(?:<(think|thought)>|\[(think|thought)\])\s*/gi, "");
4868
4857
  if (dedupeClean) {
4869
4858
  turnText += dedupeClean;
4870
4859
  yield { type: "text", content: dedupeClean };
@@ -4878,7 +4867,7 @@ ${boxBottom}` };
4878
4867
  const hasFinish2 = /\[\s*(turn\s*:)?\s*finish\s*\]/i.test(signalSafeText2.toLowerCase());
4879
4868
  const hasContinue = /\[\s*(turn\s*:)?\s*continue\s*\]/i.test(signalSafeText2.toLowerCase());
4880
4869
  const didCallTool = toolResults.length > 0 || lastToolSniffed !== null;
4881
- const pureOutputText = signalSafeText2.replace(/<think>[\s\S]*?<\/think>/gi, "").trim();
4870
+ const pureOutputText = signalSafeText2.replace(/(?:<think>|\[think\])[\s\S]*?(?:<\/think>|\[\/think\])/gi, "").trim();
4882
4871
  const endsNormally = /[.!?}"'`’“”]$|```$/s.test(pureOutputText);
4883
4872
  if (!hasFinish2 && !hasContinue && !didCallTool && signalSafeText2.length > 0 && !endsNormally && !isThinkingLoop && !isStutteringLoop && !isGeneralLoop) {
4884
4873
  throw new Error("Silent stream cutoff (500): Model stream closed cleanly but cut off mid-sentence without signals.");
@@ -4902,8 +4891,8 @@ ${boxBottom}` };
4902
4891
  }
4903
4892
  const cleanText = dedupeBuffer.substring(overlapLen);
4904
4893
  if (cleanText) {
4905
- const hasOpenThink = /<(think|thought)>(?:(?!<\/(?:think|thought)>)[\s\S])*$/i.test(accumulatedContext);
4906
- const dedupeClean = hasOpenThink ? cleanText.replace(/^\s*<(think|thought)>\s*/gi, "") : cleanText.replace(/^\s*<(think|thought)>[\s\S]*?<\/(think|thought)>\s*/gi, "").replace(/^\s*<(think|thought)>\s*/gi, "");
4894
+ const hasOpenThink = /(?:<(think|thought)>|\[(think|thought)\])(?:(?!(?:<\/(?:think|thought)>|\[\/(?:think|thought)\]))[\s\S])*$/i.test(accumulatedContext);
4895
+ const dedupeClean = hasOpenThink ? cleanText.replace(/^\s*(?:<(think|thought)>|\[(think|thought)\])\s*/gi, "") : cleanText.replace(/^\s*(?:<(think|thought)>|\[(think|thought)\])[\s\S]*?(?:<\/(think|thought)>|\[\/(think|thought)\])\s*/gi, "").replace(/^\s*(?:<(think|thought)>|\[(think|thought)\])\s*/gi, "");
4907
4896
  if (dedupeClean) {
4908
4897
  turnText += dedupeClean;
4909
4898
  }
@@ -4988,9 +4977,9 @@ Error Log can be found in ${path15.join(LOGS_DIR, "agent", "error.log")}`);
4988
4977
  }
4989
4978
  fullAgentResponseChunks.push(turnText);
4990
4979
  let textToProcess = turnText;
4991
- const thinkMatch = turnText.match(/<think>([\s\S]*?)<\/think>/i);
4980
+ const thinkMatch = turnText.match(/(?:<think>|\[think\])([\s\S]*?)(?:<\/think>|\[\/think\])/i);
4992
4981
  if (thinkMatch) {
4993
- textToProcess = turnText.replace(/<think>[\s\S]*?<\/think>/i, "");
4982
+ textToProcess = turnText.replace(/(?:<think>|\[think\])[\s\S]*?(?:<\/think>|\[\/think\])/i, "");
4994
4983
  }
4995
4984
  const signalSafeText = getSanitizedText(turnText);
4996
4985
  const hasFinish = /\[\s*(turn\s*:)?\s*finish\s*\]/i.test(signalSafeText.toLowerCase());
@@ -5000,7 +4989,7 @@ Error Log can be found in ${path15.join(LOGS_DIR, "agent", "error.log")}`);
5000
4989
  let isActuallyFinished = hasFinish && !shouldContinue;
5001
4990
  if (isActuallyFinished) {
5002
4991
  const fullAgentTextRaw = fullAgentResponseChunks.join("\n");
5003
- const cleanedFullResponse = fullAgentTextRaw.replace(/<think>[\s\S]*?<\/think>/g, "").trim();
4992
+ const cleanedFullResponse = fullAgentTextRaw.replace(/(?:<think>|\[think\])[\s\S]*?(?:<\/think>|\[\/think\])/g, "").trim();
5004
4993
  yield {
5005
4994
  type: "interactive_turn_finished",
5006
4995
  data: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fluxflow-cli",
3
- "version": "1.14.5",
3
+ "version": "1.15.1",
4
4
  "date": "2026-05-26",
5
5
  "description": "A high-fidelity agentic terminal assistant for the Flux Era.",
6
6
  "keywords": [