fluxflow-cli 3.3.0 → 3.3.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 +119 -71
  2. package/package.json +1 -1
package/dist/fluxflow.js CHANGED
@@ -9846,8 +9846,11 @@ var init_invokeSync = __esm({
9846
9846
  }
9847
9847
  return result;
9848
9848
  } catch (err) {
9849
+ const { isTerminationSignaled: isTerminationSignaled2 } = await init_ai().then(() => ai_exports);
9850
+ const isCancelled = err.message === "Subagent task was cancelled by user." || isTerminationSignaled2();
9849
9851
  if (context.onVisualFeedback) {
9850
- context.onVisualFeedback(`\x1B[95mSubAgent\x1B[0m: \x1B[32mGeneralist\x1B[0m \u2192 ${title} [FAILED]
9852
+ const statusLabel = isCancelled ? "[CANCELLED]" : "[FAILED]";
9853
+ context.onVisualFeedback(`\x1B[95mSubAgent\x1B[0m: \x1B[32mGeneralist\x1B[0m \u2192 ${title} ${statusLabel}
9851
9854
  `);
9852
9855
  }
9853
9856
  return `ERROR: Subagent execution failed: ${err.message}`;
@@ -9967,8 +9970,18 @@ ${finalAnswer}`);
9967
9970
  if (context.onSubagentUpdate) {
9968
9971
  context.onSubagentUpdate();
9969
9972
  }
9970
- }).catch((err) => {
9971
- if (taskEntry.status === "cancelled") return;
9973
+ }).catch(async (err) => {
9974
+ const { isTerminationSignaled: isTerminationSignaled2 } = await init_ai().then(() => ai_exports);
9975
+ const isCancelled = err.message === "Subagent task was cancelled." || taskEntry.status === "cancelled" || isTerminationSignaled2();
9976
+ if (isCancelled) {
9977
+ taskEntry.status = "cancelled";
9978
+ currentTurnLogs.push(`[SUBAGENT CANCELLED] Task was cancelled.`);
9979
+ taskEntry.progress.push([...currentTurnLogs]);
9980
+ if (context.onSubagentUpdate) {
9981
+ context.onSubagentUpdate();
9982
+ }
9983
+ return;
9984
+ }
9972
9985
  currentTurnLogs.push(`[SUBAGENT FAILURE] Error: ${err.message}`);
9973
9986
  taskEntry.progress.push([...currentTurnLogs]);
9974
9987
  taskEntry.status = "failed";
@@ -10721,6 +10734,7 @@ __export(ai_exports, {
10721
10734
  getCleanGroupedLength: () => getCleanGroupedLength,
10722
10735
  initAI: () => initAI,
10723
10736
  isModelMultimodal: () => isModelMultimodal,
10737
+ isTerminationSignaled: () => isTerminationSignaled,
10724
10738
  runJanitorTask: () => runJanitorTask,
10725
10739
  runSubagent: () => runSubagent,
10726
10740
  signalTermination: () => signalTermination
@@ -10728,7 +10742,7 @@ __export(ai_exports, {
10728
10742
  import { GoogleGenAI, ThinkingLevel, HarmBlockThreshold, HarmCategory } from "@google/genai";
10729
10743
  import path21, { normalize } from "path";
10730
10744
  import fs22 from "fs";
10731
- var client, globalSettings, colorMainWords, withRetry, TERMINATION_SIGNAL, MULTIMODAL_MODELS, isModelMultimodal, getCleanGroupedLength, stripAnsi2, fetchWithBackoff, getDeepSeekStream, getNVIDIAStream, wrapNvidiaStreamWithQueueDepth, getOpenRouterStream, signalTermination, TOOL_LABELS2, getToolDetail, runJanitorTask, getActiveToolContext, getContextSafeText, contextSafeReplace, getSanitizedText, translateKimiToolCalls, detectToolCalls, initAI, generateSimpleContent, consolidatePastMemories, compressHistory, deleteChatSummary, getAIStream, runSubagent;
10745
+ var client, globalSettings, colorMainWords, withRetry, TERMINATION_SIGNAL, MULTIMODAL_MODELS, isModelMultimodal, getCleanGroupedLength, stripAnsi2, fetchWithBackoff, getDeepSeekStream, getNVIDIAStream, wrapNvidiaStreamWithQueueDepth, getOpenRouterStream, signalTermination, isTerminationSignaled, TOOL_LABELS2, getToolDetail, runJanitorTask, getActiveToolContext, getContextSafeText, contextSafeReplace, getSanitizedText, translateKimiToolCalls, detectToolCalls, initAI, generateSimpleContent, consolidatePastMemories, compressHistory, deleteChatSummary, getAIStream, runSubagent;
10732
10746
  var init_ai = __esm({
10733
10747
  async "src/utils/ai.js"() {
10734
10748
  await init_prompts();
@@ -11449,6 +11463,9 @@ var init_ai = __esm({
11449
11463
  signalTermination = () => {
11450
11464
  TERMINATION_SIGNAL = true;
11451
11465
  };
11466
+ isTerminationSignaled = () => {
11467
+ return TERMINATION_SIGNAL;
11468
+ };
11452
11469
  TOOL_LABELS2 = {
11453
11470
  "write_file": "Writing",
11454
11471
  "update_file": "Editing",
@@ -12063,78 +12080,93 @@ ${originalTextProcessed.length > USER_CONTEXT_LENGTH ? "... (truncated) ...\n\n"
12063
12080
  let fullText = "";
12064
12081
  let usageMetadata = null;
12065
12082
  const normalizedContents = typeof contents === "string" ? [{ role: "user", parts: [{ text: contents }] }] : contents;
12066
- let stream;
12067
- if (aiProvider === "OpenRouter") {
12068
- stream = getOpenRouterStream(apiKey, model, normalizedContents, systemInstruction, thinkingLevel, mode, false, null, temperature);
12069
- } else if (aiProvider === "DeepSeek") {
12070
- stream = getDeepSeekStream(apiKey, model, normalizedContents, systemInstruction, thinkingLevel, mode, false, null, temperature);
12071
- } else if (aiProvider === "NVIDIA") {
12072
- stream = getNVIDIAStream(apiKey, model, normalizedContents, systemInstruction, thinkingLevel, mode, false, null, temperature);
12073
- } else {
12074
- const genStream = await client.models.generateContentStream({
12075
- model,
12076
- contents: normalizedContents,
12077
- config: {
12078
- systemInstruction,
12079
- temperature,
12080
- thinkingConfig: (() => {
12081
- const modelLower = (model || "").toLowerCase();
12082
- const isGemma4 = modelLower.includes("gemma-4") || modelLower.startsWith("gemma");
12083
- const isGemini3 = modelLower.includes("gemini-3");
12084
- if (isGemma4 || isGemini3) {
12085
- if (isGemma4) {
12086
- if (thinkingLevel.toLowerCase() !== "xhigh" || false) return { includeThoughts: false, thinkingLevel: ThinkingLevel.MINIMAL };
12087
- else return { includeThoughts: true, thinkingLevel: ThinkingLevel.HIGH };
12088
- }
12089
- return {
12090
- includeThoughts: true,
12091
- thinkingLevel: {
12092
- "Fast": modelLower.includes("pro") ? ThinkingLevel.LOW : ThinkingLevel.MINIMAL,
12093
- "Low": ThinkingLevel.LOW,
12094
- "Medium": ThinkingLevel.MEDIUM,
12095
- "Standard": ThinkingLevel.MEDIUM,
12096
- "High": ThinkingLevel.HIGH,
12097
- "xHigh": ThinkingLevel.HIGH
12098
- }[thinkingLevel] || ThinkingLevel.MEDIUM
12099
- };
12100
- } else {
12101
- const budget = {
12102
- "Fast": 0,
12103
- "Low": 512,
12104
- "Medium": 2048,
12105
- "Standard": 2048,
12106
- "High": 16384,
12107
- "xHigh": 24576
12108
- }[thinkingLevel] || 2048;
12109
- if (budget === 0) {
12110
- return { includeThoughts: false };
12083
+ const abortController = new AbortController();
12084
+ const signal = abortController.signal;
12085
+ let connectionPollInterval = setInterval(() => {
12086
+ if (TERMINATION_SIGNAL) {
12087
+ abortController.abort();
12088
+ clearInterval(connectionPollInterval);
12089
+ }
12090
+ }, 100);
12091
+ try {
12092
+ let stream;
12093
+ if (aiProvider === "OpenRouter") {
12094
+ stream = getOpenRouterStream(apiKey, model, normalizedContents, systemInstruction, thinkingLevel, mode, false, signal, temperature);
12095
+ } else if (aiProvider === "DeepSeek") {
12096
+ stream = getDeepSeekStream(apiKey, model, normalizedContents, systemInstruction, thinkingLevel, mode, false, signal, temperature);
12097
+ } else if (aiProvider === "NVIDIA") {
12098
+ stream = getNVIDIAStream(apiKey, model, normalizedContents, systemInstruction, thinkingLevel, mode, false, signal, temperature);
12099
+ } else {
12100
+ const genStream = await client.models.generateContentStream({
12101
+ model,
12102
+ contents: normalizedContents,
12103
+ config: {
12104
+ systemInstruction,
12105
+ temperature,
12106
+ thinkingConfig: (() => {
12107
+ const modelLower = (model || "").toLowerCase();
12108
+ const isGemma4 = modelLower.includes("gemma-4") || modelLower.startsWith("gemma");
12109
+ const isGemini3 = modelLower.includes("gemini-3");
12110
+ if (isGemma4 || isGemini3) {
12111
+ if (isGemma4) {
12112
+ if (thinkingLevel.toLowerCase() !== "xhigh" || false) return { includeThoughts: false, thinkingLevel: ThinkingLevel.MINIMAL };
12113
+ else return { includeThoughts: true, thinkingLevel: ThinkingLevel.HIGH };
12114
+ }
12115
+ return {
12116
+ includeThoughts: true,
12117
+ thinkingLevel: {
12118
+ "Fast": modelLower.includes("pro") ? ThinkingLevel.LOW : ThinkingLevel.MINIMAL,
12119
+ "Low": ThinkingLevel.LOW,
12120
+ "Medium": ThinkingLevel.MEDIUM,
12121
+ "Standard": ThinkingLevel.MEDIUM,
12122
+ "High": ThinkingLevel.HIGH,
12123
+ "xHigh": ThinkingLevel.HIGH
12124
+ }[thinkingLevel] || ThinkingLevel.MEDIUM
12125
+ };
12126
+ } else {
12127
+ const budget = {
12128
+ "Fast": 0,
12129
+ "Low": 512,
12130
+ "Medium": 2048,
12131
+ "Standard": 2048,
12132
+ "High": 16384,
12133
+ "xHigh": 24576
12134
+ }[thinkingLevel] || 2048;
12135
+ if (budget === 0) {
12136
+ return { includeThoughts: false };
12137
+ }
12138
+ return {
12139
+ includeThoughts: true,
12140
+ thinkingBudget: budget
12141
+ };
12111
12142
  }
12112
- return {
12113
- includeThoughts: true,
12114
- thinkingBudget: budget
12115
- };
12116
- }
12117
- })()
12118
- }
12119
- });
12120
- stream = genStream;
12121
- }
12122
- for await (const chunk of stream) {
12123
- if (settings?.taskId && typeof subagentProgress !== "undefined") {
12124
- const taskObj = subagentProgress.find((t) => t.id === settings.taskId);
12125
- if (taskObj && taskObj.status === "cancelled") {
12143
+ })()
12144
+ }
12145
+ }, { signal });
12146
+ stream = genStream;
12147
+ }
12148
+ for await (const chunk of stream) {
12149
+ if (TERMINATION_SIGNAL) {
12126
12150
  throw new Error("Subagent task was cancelled.");
12127
12151
  }
12128
- }
12129
- if (settings && typeof settings.onTokenChunk === "function") {
12130
- settings.onTokenChunk();
12131
- }
12132
- if (chunk.candidates?.[0]?.content?.parts) {
12133
- for (const part of chunk.candidates[0].content.parts) {
12134
- if (part.text && !part.thought) fullText += part.text;
12152
+ if (settings?.taskId && typeof subagentProgress !== "undefined") {
12153
+ const taskObj = subagentProgress.find((t) => t.id === settings.taskId);
12154
+ if (taskObj && taskObj.status === "cancelled") {
12155
+ throw new Error("Subagent task was cancelled.");
12156
+ }
12157
+ }
12158
+ if (settings && typeof settings.onTokenChunk === "function") {
12159
+ settings.onTokenChunk();
12135
12160
  }
12161
+ if (chunk.candidates?.[0]?.content?.parts) {
12162
+ for (const part of chunk.candidates[0].content.parts) {
12163
+ if (part.text && !part.thought) fullText += part.text;
12164
+ }
12165
+ }
12166
+ if (chunk.usageMetadata) usageMetadata = chunk.usageMetadata;
12136
12167
  }
12137
- if (chunk.usageMetadata) usageMetadata = chunk.usageMetadata;
12168
+ } finally {
12169
+ clearInterval(connectionPollInterval);
12138
12170
  }
12139
12171
  if (usageMetadata) {
12140
12172
  const total = usageMetadata.totalTokenCount || 0;
@@ -13080,6 +13112,7 @@ ${activeSummaryBlock}${thinkingLevel !== "Fast" && thinkingLevel !== "xHigh" &&
13080
13112
  let text = msg.text || "";
13081
13113
  if (msg.role === "agent") {
13082
13114
  text = text.replace(/\[turn:\s*finish\]/gi, "").replace(/\[\[END\]\]/gi, "").trim();
13115
+ text = text.replaceAll("\x1B[33m\u24D8 Request Cancelled\x1B[0m", "*User Cancelled Response Generation*");
13083
13116
  }
13084
13117
  const parts = [{ text }];
13085
13118
  if (msg.binaryPart && isModelMultimodal(targetModel)) {
@@ -15077,6 +15110,14 @@ Current Time: ${(/* @__PURE__ */ new Date()).toLocaleString("en-US", { year: "nu
15077
15110
  let turn = 0;
15078
15111
  let finalAnswer = "";
15079
15112
  while (turn < maxTurns) {
15113
+ if (TERMINATION_SIGNAL) {
15114
+ if (settings?.taskId && typeof subagentProgress !== "undefined") {
15115
+ const taskObj = subagentProgress.find((t) => t.id === settings.taskId);
15116
+ if (taskObj) taskObj.status = "cancelled";
15117
+ }
15118
+ if (logCallback) logCallback(`[SUBAGENT CANCELLED] Subagent task was cancelled.`);
15119
+ throw new Error("Subagent task was cancelled.");
15120
+ }
15080
15121
  if (settings?.taskId && typeof subagentProgress !== "undefined") {
15081
15122
  const taskObj = subagentProgress.find((t) => t.id === settings.taskId);
15082
15123
  if (taskObj && taskObj.status === "cancelled") {
@@ -15103,6 +15144,13 @@ ${cleanResponse}
15103
15144
  }
15104
15145
  let toolResultsStr = "";
15105
15146
  for (const toolCall of toolCalls) {
15147
+ if (TERMINATION_SIGNAL) {
15148
+ if (settings?.taskId && typeof subagentProgress !== "undefined") {
15149
+ const taskObj = subagentProgress.find((t) => t.id === settings.taskId);
15150
+ if (taskObj) taskObj.status = "cancelled";
15151
+ }
15152
+ throw new Error("Subagent task was cancelled.");
15153
+ }
15106
15154
  if (settings?.taskId && typeof subagentProgress !== "undefined") {
15107
15155
  const taskObj = subagentProgress.find((t) => t.id === settings.taskId);
15108
15156
  if (taskObj && taskObj.status === "cancelled") {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fluxflow-cli",
3
- "version": "3.3.0",
3
+ "version": "3.3.1",
4
4
  "date": "2026-07-09",
5
5
  "description": "A High-Fidelity Agentic CLI with Sub-Agents for the Flux Era.",
6
6
  "keywords": [