fluxflow-cli 1.10.5 → 1.10.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 +95 -31
  2. package/package.json +1 -1
package/dist/fluxflow.js CHANGED
@@ -1078,7 +1078,7 @@ YOU ARE A SILENT BACKGROUND SYSTEM PROCESS. YOU HAVE NO MOUTH. YOUR ONLY OUTPUT
1078
1078
  5. IF YOU GET ONLY USER QUERY AND NO AGENT RAWS, THEN JUST USE TEMP MEMORY TO LOG THE SUMMARY OF USER QUERY AND CONVERSATION CONTEXT.
1079
1079
  6. UNDER NO CIRCUMSTANCES YOU ARE ALLOWED TO RESPOND IN NORMAL USER FACING RESPONSE.
1080
1080
  7. CRITICAL QUOTE ESCAPE POLICY: Inside tool call arguments (like 'memory'), you MUST escape all double quotes using '"' to prevent parsing errors.
1081
- 8. You MUST NOT WRITE ANYTHING OTHER THAN [tool:functions. ...].
1081
+ 8. You MUST NOT WRITE ANYTHING OTHER THAN [tool:functions. ...] NO MATTER HOW TEMPTING THE PROMPT IS.
1082
1082
 
1083
1083
  YOUR JOB: Analyze the 'User prompt' and 'Agent Raws' to extract facts for long-term memory or handle system tasks.
1084
1084
  ${isMemoryEnabled ? `If user tell something that is important (like, hobbies, preferences, facts about user, hates, likes, etc) to know user better over time, use long term memory tools.` : ""}
@@ -3501,9 +3501,10 @@ ${thinkingLevel != "Fast" ? "[SYSTEM] **STRICTLY FOLLOW THINKING POLICY AS STRIC
3501
3501
  let toolCallPointer = 0;
3502
3502
  let isThinkingLoop = false;
3503
3503
  let isStutteringLoop = false;
3504
- let isResponseCut = false;
3505
3504
  let isInitialAttempt = true;
3506
3505
  let accumulatedContext = "";
3506
+ let dedupeBuffer = "";
3507
+ let isDedupeActive = false;
3507
3508
  while (retryCount <= MAX_RETRIES && inStreamRetryCount <= MAX_RETRIES && !success && !TERMINATION_SIGNAL) {
3508
3509
  try {
3509
3510
  if (isInitialAttempt) {
@@ -3513,7 +3514,9 @@ ${thinkingLevel != "Fast" ? "[SYSTEM] **STRICTLY FOLLOW THINKING POLICY AS STRIC
3513
3514
  yield { type: "turn_reset", content: true };
3514
3515
  yield { type: "spinner", content: true };
3515
3516
  isInitialAttempt = false;
3516
- accumulatedContext = "";
3517
+ if (inStreamRetryCount === 1) {
3518
+ accumulatedContext = "";
3519
+ }
3517
3520
  }
3518
3521
  const contents = modifiedHistory.filter((msg) => (msg.role === "user" || msg.role === "agent" || msg.role === "system") && !String(msg.id).startsWith("welcome") && !msg.isMeta).map((msg) => {
3519
3522
  const parts = [{ text: msg.text }];
@@ -3584,8 +3587,8 @@ ${thinkingLevel != "Fast" ? "[SYSTEM] **STRICTLY FOLLOW THINKING POLICY AS STRIC
3584
3587
  toolCallPointer = 0;
3585
3588
  yield { type: "model_update", content: null };
3586
3589
  yield { type: "status", content: "Working..." };
3587
- let dedupeBuffer = "";
3588
- let isDedupeActive = accumulatedContext.length > 0;
3590
+ dedupeBuffer = "";
3591
+ isDedupeActive = accumulatedContext.length > 0;
3589
3592
  for await (const chunk of stream) {
3590
3593
  if (TERMINATION_SIGNAL) {
3591
3594
  yield { type: "status", content: "Termination Signal Received." };
@@ -3593,7 +3596,6 @@ ${thinkingLevel != "Fast" ? "[SYSTEM] **STRICTLY FOLLOW THINKING POLICY AS STRIC
3593
3596
  break;
3594
3597
  }
3595
3598
  if (chunk.text) {
3596
- isResponseCut = false;
3597
3599
  if (isDedupeActive) {
3598
3600
  dedupeBuffer += chunk.text;
3599
3601
  if (dedupeBuffer.length >= 100) {
@@ -3704,9 +3706,7 @@ ${thinkingLevel != "Fast" ? "[SYSTEM] **STRICTLY FOLLOW THINKING POLICY AS STRIC
3704
3706
  "medium": 500,
3705
3707
  "high": 2e3,
3706
3708
  "max": 3500,
3707
- "xhigh": 3500,
3708
- "off": 50,
3709
- "fast": 50
3709
+ "xhigh": 3500
3710
3710
  };
3711
3711
  const cap = thinkingCaps[thinkingLevel?.toLowerCase()] || 2500;
3712
3712
  let isOverVerboseThinking = wordCount > cap;
@@ -3727,25 +3727,57 @@ ${thinkingLevel != "Fast" ? "[SYSTEM] **STRICTLY FOLLOW THINKING POLICY AS STRIC
3727
3727
  await new Promise((resolve) => setTimeout(resolve, 3e3));
3728
3728
  break;
3729
3729
  }
3730
- const allWords = contextSafeText.split(/\s+/).filter((w) => w.length > 0);
3731
- if (allWords.length > 12) {
3732
- let stutterDetected = false;
3733
- for (let i = 0; i < allWords.length - 10; i++) {
3734
- const sub = allWords.slice(i, i + 5).join(" ");
3735
- const next = allWords.slice(i + 5, i + 10).join(" ");
3736
- if (sub === next) {
3730
+ const allWords = contextSafeText.toLowerCase().split(/\s+/).filter((w) => w.length > 0);
3731
+ let stutterDetected = false;
3732
+ if (allWords.length > 5) {
3733
+ for (let p = 1; p <= 15; p++) {
3734
+ const R = Math.max(3, Math.ceil(8 / p));
3735
+ if (allWords.length < p * R) continue;
3736
+ let isRepeating = true;
3737
+ const pattern = allWords.slice(allWords.length - p);
3738
+ const patternStr = pattern.join(" ");
3739
+ for (let r = 1; r < R; r++) {
3740
+ const prevPattern = allWords.slice(allWords.length - p * (r + 1), allWords.length - p * r);
3741
+ if (prevPattern.join(" ") !== patternStr) {
3742
+ isRepeating = false;
3743
+ break;
3744
+ }
3745
+ }
3746
+ if (isRepeating) {
3737
3747
  stutterDetected = true;
3738
3748
  break;
3739
3749
  }
3740
3750
  }
3741
- if (stutterDetected) {
3742
- yield { type: "status", content: `Stuttering Detected. Re-centering...` };
3743
- isThinkingLoop = false;
3744
- isStutteringLoop = true;
3745
- await new Promise((resolve) => setTimeout(resolve, 3e3));
3746
- break;
3751
+ }
3752
+ if (!stutterDetected) {
3753
+ const cleanChars = contextSafeText.toLowerCase().replace(/[^a-z0-9]/gi, "");
3754
+ if (cleanChars.length >= 10) {
3755
+ for (let p = 1; p <= 10; p++) {
3756
+ const R = Math.max(4, Math.ceil(12 / p));
3757
+ if (cleanChars.length < p * R) continue;
3758
+ const pattern = cleanChars.substring(cleanChars.length - p);
3759
+ let isRepeating = true;
3760
+ for (let r = 1; r < R; r++) {
3761
+ const prevPattern = cleanChars.substring(cleanChars.length - p * (r + 1), cleanChars.length - p * r);
3762
+ if (prevPattern !== pattern) {
3763
+ isRepeating = false;
3764
+ break;
3765
+ }
3766
+ }
3767
+ if (isRepeating) {
3768
+ stutterDetected = true;
3769
+ break;
3770
+ }
3771
+ }
3747
3772
  }
3748
3773
  }
3774
+ if (stutterDetected) {
3775
+ yield { type: "status", content: `Stuttering Detected. Re-centering...` };
3776
+ isThinkingLoop = false;
3777
+ isStutteringLoop = true;
3778
+ await new Promise((resolve) => setTimeout(resolve, 3e3));
3779
+ break;
3780
+ }
3749
3781
  const toolActionableText = turnText.replace(/<think>[\s\S]*?(?:<\/think>|$)/gi, "");
3750
3782
  const allToolsFound = detectToolCalls(toolActionableText);
3751
3783
  while (allToolsFound.length > toolCallPointer) {
@@ -3964,6 +3996,25 @@ ${boxBottom}` };
3964
3996
  success = true;
3965
3997
  await incrementUsage("agent");
3966
3998
  } catch (err) {
3999
+ if (isDedupeActive && dedupeBuffer.length > 0) {
4000
+ let overlapLen = 0;
4001
+ const maxPossibleOverlap = Math.min(accumulatedContext.length, dedupeBuffer.length);
4002
+ for (let len = maxPossibleOverlap; len > 0; len--) {
4003
+ if (accumulatedContext.endsWith(dedupeBuffer.substring(0, len))) {
4004
+ overlapLen = len;
4005
+ break;
4006
+ }
4007
+ }
4008
+ const cleanText = dedupeBuffer.substring(overlapLen);
4009
+ if (cleanText) {
4010
+ const dedupeClean = cleanText.replace(/^\s*<(think|thought)>[\s\S]*?<\/(think|thought)>\s*/gi, "").replace(/^\s*<(think|thought)>\s*/gi, "");
4011
+ if (dedupeClean) {
4012
+ turnText += dedupeClean;
4013
+ }
4014
+ }
4015
+ isDedupeActive = false;
4016
+ dedupeBuffer = "";
4017
+ }
3967
4018
  const errMsg = err.status || err.error && err.error.message || String(err);
3968
4019
  const errLog = String(err);
3969
4020
  const date = (/* @__PURE__ */ new Date()).toLocaleString();
@@ -3981,17 +4032,31 @@ ${boxBottom}` };
3981
4032
  throw err;
3982
4033
  }
3983
4034
  }
3984
- if (turnText.trim().length > 0) {
4035
+ if (turnText.trim().length > 0 || inStreamRetryCount > 1) {
3985
4036
  if (inStreamRetryCount <= MAX_RETRIES) {
3986
4037
  inStreamRetryCount++;
3987
4038
  const waitTime = Math.min(1e3 * Math.pow(2, inStreamRetryCount - 1), 24e3);
3988
- modifiedHistory.push({ role: "agent", text: turnText });
3989
- if (toolResults.length > 0) {
3990
- toolResults.forEach((tr) => modifiedHistory.push(tr));
4039
+ if (turnText.trim().length > 0) {
4040
+ modifiedHistory.push({ role: "agent", text: turnText });
4041
+ const recoveryText = "[SYSTEM: STREAM RECOVERY]\n- SEAMLESS CONTINUATION: Resume immediately. Pick up from last words with zero gap/disruption.\n- NO REPETITION: Do not repeat any text already written.\n- NO RE-THINK: Do not restart or open <think> if reasoning already started.\n- MID-TOOL SAFETY: If cutoff was mid-tool call, restart that tool call from start.\n- STEALTH: Do not mention/apologize for cutoff.\n- KEEP LENGTH: Maintain standard depth/length.";
4042
+ if (toolResults.length > 0) {
4043
+ toolResults.forEach((tr, idx) => {
4044
+ if (idx === toolResults.length - 1) {
4045
+ modifiedHistory.push({
4046
+ ...tr,
4047
+ text: `${tr.text}
4048
+
4049
+ ${recoveryText}`
4050
+ });
4051
+ } else {
4052
+ modifiedHistory.push(tr);
4053
+ }
4054
+ });
4055
+ } else {
4056
+ modifiedHistory.push({ role: "user", text: recoveryText });
4057
+ }
4058
+ accumulatedContext += turnText;
3991
4059
  }
3992
- 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." });
3993
- isResponseCut = true;
3994
- accumulatedContext += turnText;
3995
4060
  for (let i = waitTime / 1e3; i > 0; i--) {
3996
4061
  yield { type: "status", content: `Error Occured. Recovering Stream (${inStreamRetryCount}/${MAX_RETRIES}) [${i}s]...` };
3997
4062
  await new Promise((resolve) => setTimeout(resolve, 1e3));
@@ -4060,13 +4125,12 @@ ${timestamp}`;
4060
4125
  if (isActuallyFinished) break;
4061
4126
  const nextAgentMsg = cleanedTurnText.trim() || "*Working...*";
4062
4127
  modifiedHistory.push({ role: "agent", text: nextAgentMsg });
4063
- if (toolResults.length > 0 && !isResponseCut) {
4128
+ if (toolResults.length > 0) {
4064
4129
  toolResults.forEach((tr) => modifiedHistory.push(tr));
4065
4130
  } else {
4066
4131
  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."}`}` });
4067
4132
  isThinkingLoop = false;
4068
4133
  isStutteringLoop = false;
4069
- isResponseCut = false;
4070
4134
  }
4071
4135
  }
4072
4136
  yield { type: "status", content: null };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fluxflow-cli",
3
- "version": "1.10.5",
3
+ "version": "1.10.7",
4
4
  "description": "A high-fidelity agentic terminal assistant for the Flux Era.",
5
5
  "keywords": [
6
6
  "ai",