fluxflow-cli 1.8.11 → 1.8.12

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 +46 -9
  2. package/package.json +1 -1
package/dist/fluxflow.js CHANGED
@@ -1301,7 +1301,7 @@ var init_web_search = __esm({
1301
1301
  const jitter = attempt === 1 ? Math.random() * 1e3 + 500 : Math.random() * 2e3 + 1e3;
1302
1302
  await new Promise((r) => setTimeout(r, jitter));
1303
1303
  const searchUrl = `https://html.duckduckgo.com/html/?q=${encodeURIComponent(query)}`;
1304
- await page.goto(searchUrl, { waitUntil: "networkidle2" });
1304
+ await page.goto(searchUrl, { waitUntil: "networkidle2", timeout: 18e4 });
1305
1305
  const results = await page.$$eval(".result", (elements, maxLimit) => {
1306
1306
  return elements.slice(0, maxLimit).map((el, i) => {
1307
1307
  const titleEl = el.querySelector(".result__a");
@@ -1384,7 +1384,7 @@ var init_web_scrape = __esm({
1384
1384
  await page.setViewport({ width: 1366, height: 768 });
1385
1385
  const jitter = attempt === 1 ? Math.random() * 1e3 + 500 : Math.random() * 2e3 + 1e3;
1386
1386
  await new Promise((r) => setTimeout(r, jitter));
1387
- await page.goto(url, { waitUntil: "networkidle2", timeout: 45e3 });
1387
+ await page.goto(url, { waitUntil: "networkidle2", timeout: 18e4 });
1388
1388
  await new Promise((r) => setTimeout(r, 5e3));
1389
1389
  let htmlContent = await page.evaluate(() => {
1390
1390
  const junk = document.querySelectorAll("script, style, nav, footer, header, noscript, svg, canvas, iframe, ad, .ads, link, meta, img");
@@ -2150,7 +2150,7 @@ var init_write_pdf = __esm({
2150
2150
  <div class="watermark">Generated by FluxFlow CLI (AI)</div>
2151
2151
  ${content}
2152
2152
  `;
2153
- await page.setContent(styledContent, { waitUntil: "networkidle0" });
2153
+ await page.setContent(styledContent, { waitUntil: "networkidle0", timeout: 18e4 });
2154
2154
  const pdfBytes = await page.pdf({
2155
2155
  format: "A4",
2156
2156
  landscape: orientation.toLowerCase() === "landscape",
@@ -2697,6 +2697,7 @@ var init_ai = __esm({
2697
2697
  try {
2698
2698
  if (isInitialAttempt) {
2699
2699
  yield { type: "turn_reset", content: true };
2700
+ yield { type: "spinner", content: true };
2700
2701
  isInitialAttempt = false;
2701
2702
  accumulatedContext = "";
2702
2703
  }
@@ -2810,15 +2811,44 @@ var init_ai = __esm({
2810
2811
  const uniqueSentences = new Set(sentences);
2811
2812
  const repetitionRatio = sentences.length > 10 ? (sentences.length - uniqueSentences.size) / sentences.length : 0;
2812
2813
  const wordCount = thinkContent.split(/\s+/).filter((w) => w.length > 0).length;
2813
- let repetitionThreshold = 0.4;
2814
- let isOverVerbose = wordCount > 2500;
2815
- if (repetitionRatio > repetitionThreshold || isOverVerbose) {
2816
- const reason = repetitionRatio > repetitionThreshold ? "Thinking Loop Detected" : "Rambling Detected";
2814
+ let repetitionThresholdThinking = 0.4;
2815
+ let repetitionThresholdResponse = 0.6;
2816
+ let isOverVerboseThinking = wordCount > 2500;
2817
+ if (repetitionRatio > repetitionThresholdThinking || isOverVerboseThinking) {
2818
+ const reason = repetitionRatio > repetitionThresholdThinking ? "Thinking Loop Detected" : "Rambling Detected";
2817
2819
  yield { type: "status", content: `${reason}. Re-centering...` };
2818
2820
  isThinkingLoop = true;
2819
2821
  await new Promise((resolve) => setTimeout(resolve, 3e3));
2820
2822
  break;
2821
2823
  }
2824
+ const responseContent = signalSafeText2.trim();
2825
+ const respSentences = responseContent.split(/[.!?]\s+/);
2826
+ const uniqueRespSentences = new Set(respSentences);
2827
+ const respRepetitionRatio = respSentences.length > 10 ? (respSentences.length - uniqueRespSentences.size) / respSentences.length : 0;
2828
+ if (respRepetitionRatio > repetitionThresholdResponse) {
2829
+ yield { type: "status", content: `Response Loop Detected. Re-centering...` };
2830
+ isThinkingLoop = false;
2831
+ await new Promise((resolve) => setTimeout(resolve, 3e3));
2832
+ break;
2833
+ }
2834
+ const allWords = contextSafeText.split(/\s+/).filter((w) => w.length > 0);
2835
+ if (allWords.length > 12) {
2836
+ let stutterDetected = false;
2837
+ for (let i = 0; i < allWords.length - 10; i++) {
2838
+ const sub = allWords.slice(i, i + 5).join(" ");
2839
+ const next = allWords.slice(i + 5, i + 10).join(" ");
2840
+ if (sub === next) {
2841
+ stutterDetected = true;
2842
+ break;
2843
+ }
2844
+ }
2845
+ if (stutterDetected) {
2846
+ yield { type: "status", content: `Stuttering Detected. Re-centering...` };
2847
+ isThinkingLoop = false;
2848
+ await new Promise((resolve) => setTimeout(resolve, 3e3));
2849
+ break;
2850
+ }
2851
+ }
2822
2852
  const toolActionableText = turnText.replace(/<think>[\s\S]*?(?:<\/think>|$)/gi, "");
2823
2853
  const allToolsFound = detectToolCalls(toolActionableText);
2824
2854
  while (allToolsFound.length > toolCallPointer) {
@@ -2943,12 +2973,14 @@ ${boxBottom}
2943
2973
  }
2944
2974
  }
2945
2975
  const effectiveStart = lastToolEventTime || Date.now();
2976
+ yield { type: "spinner", content: false };
2946
2977
  let result = await dispatchTool(toolCall.toolName, toolCall.args, {
2947
2978
  chatId,
2948
2979
  history,
2949
2980
  onChunk: (chunk2) => settings.onExecChunk ? settings.onExecChunk(chunk2) : null,
2950
2981
  onAskUser: settings.onAskUser
2951
2982
  });
2983
+ yield { type: "spinner", content: true };
2952
2984
  const toolEnd = Date.now();
2953
2985
  yield { type: "tool_time", content: toolEnd - effectiveStart };
2954
2986
  lastToolEventTime = toolEnd;
@@ -3568,6 +3600,7 @@ Check what's new using \`/changelog\` command.`,
3568
3600
  return formatDuration(Math.floor(ms / 1e3));
3569
3601
  };
3570
3602
  const [statusText, setStatusText] = useState7(null);
3603
+ const [isSpinnerActive, setIsSpinnerActive] = useState7(true);
3571
3604
  const [isProcessing, setIsProcessing] = useState7(false);
3572
3605
  const [escPressed, setEscPressed] = useState7(false);
3573
3606
  const [escTimer, setEscTimer] = useState7(null);
@@ -4242,6 +4275,10 @@ Selection: ${val}`,
4242
4275
  setStatusText(packet.content);
4243
4276
  continue;
4244
4277
  }
4278
+ if (packet.type === "spinner") {
4279
+ setIsSpinnerActive(packet.content);
4280
+ continue;
4281
+ }
4245
4282
  if (packet.type === "model_update") {
4246
4283
  setTempModelOverride(packet.content);
4247
4284
  continue;
@@ -4933,7 +4970,7 @@ Selection: ${val}`,
4933
4970
  }
4934
4971
  )));
4935
4972
  default:
4936
- return /* @__PURE__ */ React10.createElement(Box10, { flexDirection: "column", marginTop: 1, flexShrink: 0, width: "100%" }, /* @__PURE__ */ React10.createElement(Box10, { paddingX: 1, marginBottom: 0, justifyContent: "space-between", width: "100%" }, /* @__PURE__ */ React10.createElement(Box10, null, statusText && /* @__PURE__ */ React10.createElement(Box10, null, /* @__PURE__ */ React10.createElement(Text10, { color: "magenta" }, /* @__PURE__ */ React10.createElement(Spinner2, { type: "dots" })), /* @__PURE__ */ React10.createElement(Text10, { color: "magenta", italic: true }, " ", statusText))), /* @__PURE__ */ React10.createElement(Text10, { color: "gray", dimColor: true }, "(", tempModelOverride || activeModel, ")")), suggestions.length > 0 && /* @__PURE__ */ React10.createElement(Box10, { paddingY: 0 }), /* @__PURE__ */ React10.createElement(Box10, { backgroundColor: "#333333", paddingX: 1, paddingY: 1, width: "100%" }, /* @__PURE__ */ React10.createElement(Box10, { flexDirection: "column", width: "100%" }, maxLines > 2 && !isExpanded ? /* @__PURE__ */ React10.createElement(Box10, { flexDirection: "row", width: "100%", paddingY: 0, height: 1, overflow: "hidden" }, /* @__PURE__ */ React10.createElement(Box10, { flexShrink: 0, width: 3 }, /* @__PURE__ */ React10.createElement(Text10, { color: "yellow" }, "\u276F ")), /* @__PURE__ */ React10.createElement(Box10, { flexGrow: 1, flexDirection: "row" }, /* @__PURE__ */ React10.createElement(Box10, { flexShrink: 0 }, /* @__PURE__ */ React10.createElement(Text10, { color: "magenta", bold: true }, "[Pasted ", maxLines, " Lines]")), /* @__PURE__ */ React10.createElement(Box10, { flexGrow: 1, marginLeft: 1 }, /* @__PURE__ */ React10.createElement(
4973
+ return /* @__PURE__ */ React10.createElement(Box10, { flexDirection: "column", marginTop: 1, flexShrink: 0, width: "100%" }, /* @__PURE__ */ React10.createElement(Box10, { paddingX: 1, marginBottom: 0, justifyContent: "space-between", width: "100%" }, /* @__PURE__ */ React10.createElement(Box10, null, statusText && /* @__PURE__ */ React10.createElement(Box10, null, isSpinnerActive && /* @__PURE__ */ React10.createElement(Text10, { color: "magenta" }, /* @__PURE__ */ React10.createElement(Spinner2, { type: "dots" })), /* @__PURE__ */ React10.createElement(Text10, { color: "magenta", italic: true }, isSpinnerActive ? " " : "", statusText))), /* @__PURE__ */ React10.createElement(Text10, { color: "gray", dimColor: true }, "(", tempModelOverride || activeModel, ")")), suggestions.length > 0 && /* @__PURE__ */ React10.createElement(Box10, { paddingY: 0 }), /* @__PURE__ */ React10.createElement(Box10, { backgroundColor: "#333333", paddingX: 1, paddingY: 1, width: "100%" }, /* @__PURE__ */ React10.createElement(Box10, { flexDirection: "column", width: "100%" }, maxLines > 2 && !isExpanded ? /* @__PURE__ */ React10.createElement(Box10, { flexDirection: "row", width: "100%", paddingY: 0, height: 1, overflow: "hidden" }, /* @__PURE__ */ React10.createElement(Box10, { flexShrink: 0, width: 3 }, /* @__PURE__ */ React10.createElement(Text10, { color: "yellow" }, "\u276F ")), /* @__PURE__ */ React10.createElement(Box10, { flexGrow: 1, flexDirection: "row" }, /* @__PURE__ */ React10.createElement(Box10, { flexShrink: 0 }, /* @__PURE__ */ React10.createElement(Text10, { color: "magenta", bold: true }, "[Pasted ", maxLines, " Lines]")), /* @__PURE__ */ React10.createElement(Box10, { flexGrow: 1, marginLeft: 1 }, /* @__PURE__ */ React10.createElement(
4937
4974
  MultilineInput,
4938
4975
  {
4939
4976
  value: "",
@@ -5055,7 +5092,7 @@ var init_app = __esm({
5055
5092
  init_text();
5056
5093
  SESSION_START_TIME = Date.now();
5057
5094
  CHANGELOG_URL = "https://fluxflow-cli.onrender.com/changelog.html";
5058
- versionFluxflow = "1.8.11";
5095
+ versionFluxflow = "1.8.12";
5059
5096
  updatedOn = "2026-05-09";
5060
5097
  ResolutionModal = ({ data, onResolve, onEdit }) => /* @__PURE__ */ React10.createElement(Box10, { flexDirection: "column", borderStyle: "round", borderColor: "magenta", paddingX: 2, paddingY: 1, width: "100%" }, /* @__PURE__ */ React10.createElement(Text10, { color: "magenta", bold: true, underline: true }, "\u{1F7E3} STEERING HINT RESOLUTION"), /* @__PURE__ */ React10.createElement(Text10, { marginTop: 1 }, "The agent already finished the task before your hint was consumed."), /* @__PURE__ */ React10.createElement(Box10, { marginTop: 1, backgroundColor: "#222", paddingX: 1, width: "100%" }, /* @__PURE__ */ React10.createElement(Text10, { italic: true, color: "gray" }, '"', data, '"')), /* @__PURE__ */ React10.createElement(Box10, { marginTop: 1 }, /* @__PURE__ */ React10.createElement(Text10, { color: "cyan" }, "How would you like to proceed?")), /* @__PURE__ */ React10.createElement(Box10, { marginTop: 1 }, /* @__PURE__ */ React10.createElement(
5061
5098
  CommandMenu,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fluxflow-cli",
3
- "version": "1.8.11",
3
+ "version": "1.8.12",
4
4
  "description": "A high-fidelity agentic terminal assistant for the Flux Era.",
5
5
  "keywords": [
6
6
  "ai",