fluxflow-cli 1.8.15 → 1.8.17

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 +81 -46
  2. package/package.json +1 -1
package/dist/fluxflow.js CHANGED
@@ -740,7 +740,7 @@ var init_janitor_tools = __esm({
740
740
  JANITOR_TOOLS_PROTOCOL = (isMemoryEnabled = true, needTitle = false) => `
741
741
  ${needTitle ? `-- START CHAT MANAGEMENT TOOLS --
742
742
  1. YOU MUST UPDATE CHAT TITLE (URGENT PRIORITY):
743
- tool:functions.chat(title='<short summary of conversation in 3-5 words>')
743
+ tool:functions.chat(title='<short summary of conversation context in 3-5 words>')
744
744
  -- END CHAT MANAGEMENT TOOLS --
745
745
 
746
746
  ` : ""}
@@ -780,10 +780,10 @@ RULES:
780
780
  - NO HEADINGS. Just a solid, stable analytical monologue.
781
781
  - Be thorough and exhaustive. Explore the 'why' behind every decision.
782
782
  - Use internal critique: Question your own logic as you go.
783
- - The monologue length should scale with the complexity of the task, but for MAX effort, leave no stone unturned.
783
+ - **MANDATORY REASONING**: Unless the prompt is a simple greeting (e.g. 'hi') or trivial math (e.g. '1+1'), you MUST engage in full architectural reasoning regardless of perceived simplicity.
784
784
  -- END THINKING INSTRUCTIONS --`,
785
- High: "-- START THINKING INSTRUCTIONS --\nEFFORT_LEVEL: HIGH\nThink in a stable, analytical monologue within the <think>...</think> block. Avoid headings or structured formatting. Your thinking should be a continuous stream of logical deduction:\n1. Analyze the immediate task and its dependencies.\n2. Mentally simulate the execution to identify potential failure points.\n3. Structure a precise plan that addresses both primary goals and secondary constraints.\n\nRULES:\n- NO HEADINGS. Maintain a fluid monologue style.\n- Be detailed and rigorous in your self-questioning.\n- Focus on accuracy and technical correctness.\n-- END THINKING INSTRUCTIONS --",
786
- Medium: "-- START THINKING INSTRUCTIONS --\nEFFORT_LEVEL: MEDIUM\nThink in a concise, stable monologue within the <think>...</think> block. No headings needed. Focus on the core logic required to solve the task efficiently:\n1. Identify the most direct path to the solution.\n2. Briefly consider and discard obvious alternatives.\n3. Confirm the plan meets the user's immediate requirements.\n\nRULES:\n- NO HEADINGS. Keep it as a simple, logical stream.\n- Be efficient. Spend energy only on what matters for the task.\n-- END THINKING INSTRUCTIONS --",
785
+ High: "-- START THINKING INSTRUCTIONS --\nEFFORT_LEVEL: HIGH\nThink in a stable, analytical monologue within the <think>...</think> block. Avoid headings or structured formatting. Your thinking should be a continuous stream of logical deduction:\n1. Analyze the immediate task and its dependencies.\n2. Mentally simulate the execution to identify potential failure points.\n3. Structure a precise plan that addresses both primary goals and secondary constraints.\n\nRULES:\n- NO HEADINGS. Maintain a fluid monologue style.\n- Be detailed and rigorous in your self-questioning.\n- Focus on accuracy and technical correctness.\n- **MANDATORY REASONING**: For any request beyond basic conversation, you MUST enter reasoning to verify the path forward.\n-- END THINKING INSTRUCTIONS --",
786
+ Medium: "-- START THINKING INSTRUCTIONS --\nEFFORT_LEVEL: MEDIUM\nThink in a concise, stable monologue within the <think>...</think> block. No headings needed. Focus on the core logic required to solve the task efficiently:\n1. Identify the most direct path to the solution.\n2. Briefly consider and discard obvious alternatives.\n3. Confirm the plan meets the user's immediate requirements.\n\nRULES:\n- NO HEADINGS. Keep it as a simple, logical stream.\n- Be efficient. Spend energy only on what matters for the task.\n- **REQUIRED REASONING**: Engage in a baseline mental check for all technical tasks.\n-- END THINKING INSTRUCTIONS --",
787
787
  Minimal: "-- START THINKING INSTRUCTIONS --\nEFFORT_LEVEL: LOW\nThink in a brief, focused monologue within the <think>...</think> block. No headings. Just a quick mental check before acting:\n1. Verify the objective.\n2. Note the target files/tools.\n\nRULES:\n- NO HEADINGS. Just a few lines of clear, linear thought.\n- Use minimal/no thinking for simple or conversational requests.\n-- END THINKING INSTRUCTIONS --"
788
788
  };
789
789
  }
@@ -2768,6 +2768,7 @@ var init_ai = __esm({
2768
2768
  thinkingConfig: {
2769
2769
  includeThoughts: false,
2770
2770
  thinkingLevel: ThinkingLevel.MINIMAL
2771
+ // Gemma's API Reasoning is bad. Keep it Minimal.
2771
2772
  }
2772
2773
  }
2773
2774
  });
@@ -3061,6 +3062,9 @@ ${boxBottom}
3061
3062
  const agentErrDir = path16.join(LOGS_DIR, "agent");
3062
3063
  if (!fs16.existsSync(agentErrDir)) fs16.mkdirSync(agentErrDir, { recursive: true });
3063
3064
  fs16.appendFileSync(path16.join(agentErrDir, "error.log"), `ERROR [${date}]: ${errLog}
3065
+
3066
+ ----------------------------------------------------------------------
3067
+
3064
3068
  `);
3065
3069
  if (retryCount < MAX_RETRIES) {
3066
3070
  retryCount++;
@@ -3112,7 +3116,7 @@ ${boxBottom}
3112
3116
  cleanedFullResponse,
3113
3117
  janitorUserMemories,
3114
3118
  isMemoryEnabled,
3115
- needTitle
3119
+ true
3116
3120
  );
3117
3121
  janitorContents.push({ role: "user", parts: [{ text: janitorPrompt }] });
3118
3122
  let finalSynthesis = "";
@@ -3121,52 +3125,80 @@ ${boxBottom}
3121
3125
  console.warn("Quota Exhausted for Background Model. Skipping refinement.");
3122
3126
  throw new Error("QUOTA_BLOCKED");
3123
3127
  }
3124
- const janitorResult = await client.models.generateContent({
3125
- model: janitorModel || "gemma-4-26b-a4b-it",
3126
- contents: janitorContents,
3127
- config: {
3128
- maxOutputTokens: 384,
3129
- temperature: 0.69,
3130
- safetySettings: [
3131
- {
3132
- category: HarmCategory.HARM_CATEGORY_HARASSMENT,
3133
- threshold: HarmBlockThreshold.BLOCK_NONE
3134
- },
3135
- {
3136
- category: HarmCategory.HARM_CATEGORY_HATE_SPEECH,
3137
- threshold: HarmBlockThreshold.BLOCK_NONE
3138
- },
3139
- {
3140
- category: HarmCategory.HARM_CATEGORY_SEXUALLY_EXPLICIT,
3141
- threshold: HarmBlockThreshold.BLOCK_NONE
3142
- },
3143
- {
3144
- category: HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT,
3145
- threshold: HarmBlockThreshold.BLOCK_NONE
3128
+ yield { type: "spinner", content: false };
3129
+ let fullContent = "";
3130
+ let lastUsage2 = null;
3131
+ try {
3132
+ const timeoutPromise = new Promise(
3133
+ (_, reject) => setTimeout(() => reject(new Error("JANITOR_TIMEOUT")), 2e4)
3134
+ );
3135
+ const streamPromise = (async () => {
3136
+ const stream2 = await client.models.generateContentStream({
3137
+ model: janitorModel || "gemma-4-26b-a4b-it",
3138
+ contents: janitorContents,
3139
+ config: {
3140
+ maxOutputTokens: 384,
3141
+ temperature: 0.69,
3142
+ safetySettings: [
3143
+ { category: HarmCategory.HARM_CATEGORY_HARASSMENT, threshold: HarmBlockThreshold.BLOCK_NONE },
3144
+ { category: HarmCategory.HARM_CATEGORY_HATE_SPEECH, threshold: HarmBlockThreshold.BLOCK_NONE },
3145
+ { category: HarmCategory.HARM_CATEGORY_SEXUALLY_EXPLICIT, threshold: HarmBlockThreshold.BLOCK_NONE },
3146
+ { category: HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT, threshold: HarmBlockThreshold.BLOCK_NONE }
3147
+ ],
3148
+ thinkingConfig: { includeThoughts: false, thinkingLevel: ThinkingLevel.MINIMAL }
3146
3149
  }
3147
- ],
3148
- thinkingConfig: {
3149
- includeThoughts: false,
3150
- thinkingLevel: ThinkingLevel.MINIMAL
3150
+ });
3151
+ await incrementUsage("background");
3152
+ const iterator2 = stream2[Symbol.asyncIterator]();
3153
+ const firstResult2 = await iterator2.next();
3154
+ return { iterator: iterator2, firstResult: firstResult2 };
3155
+ })();
3156
+ const { iterator, firstResult } = await Promise.race([streamPromise, timeoutPromise]);
3157
+ let { value: firstChunk, done: firstDone } = firstResult;
3158
+ if (!firstDone && firstChunk) {
3159
+ const parts = firstChunk.candidates?.[0]?.content?.parts;
3160
+ const chunkText = parts?.[1]?.text || parts?.[0]?.text || (typeof firstChunk.text === "function" ? firstChunk.text() : "");
3161
+ if (chunkText) {
3162
+ fullContent += chunkText;
3163
+ yield { type: "status", content: "Finishing..." };
3164
+ }
3165
+ lastUsage2 = firstChunk.usageMetadata;
3166
+ for await (const chunk of { [Symbol.asyncIterator]: () => iterator }) {
3167
+ const p = chunk.candidates?.[0]?.content?.parts;
3168
+ const t = p?.[1]?.text || p?.[0]?.text || (typeof chunk.text === "function" ? chunk.text() : "");
3169
+ if (t) {
3170
+ fullContent += t;
3171
+ }
3172
+ lastUsage2 = chunk.usageMetadata;
3151
3173
  }
3152
3174
  }
3153
- });
3154
- const parts = janitorResult.candidates?.[0]?.content?.parts;
3155
- if (parts && parts[1]?.text) {
3156
- finalSynthesis = parts[1].text;
3175
+ } catch (e) {
3176
+ if (e.message === "JANITOR_TIMEOUT") {
3177
+ throw new Error("Janitor API Timeout: No tokens received within 20s.");
3178
+ }
3179
+ throw e;
3180
+ }
3181
+ yield { type: "spinner", content: true };
3182
+ if (fullContent) {
3183
+ finalSynthesis = fullContent;
3184
+ if (lastUsage2) {
3185
+ await addToUsage("tokens", lastUsage2.totalTokenCount || 0);
3186
+ }
3157
3187
  const date = (/* @__PURE__ */ new Date()).toLocaleString();
3158
3188
  const janitorLogDir = path16.join(LOGS_DIR, "janitor");
3159
3189
  if (!fs16.existsSync(janitorLogDir)) {
3160
3190
  fs16.mkdirSync(janitorLogDir, { recursive: true });
3161
3191
  }
3162
- fs16.appendFileSync(path16.join(janitorLogDir, "debug.log"), `DEBUG [${date}]: ${finalSynthesis}
3192
+ fs16.appendFileSync(path16.join(janitorLogDir, "debug.log"), `
3193
+
3194
+ ---------------------------------------------------
3195
+
3196
+
3197
+ DEBUG [${date}]: ${finalSynthesis}
3198
+
3163
3199
  `);
3164
- } else if (parts && parts[0]?.text) finalSynthesis = parts[0].text;
3165
- else if (janitorResult.response && janitorResult.response.text) finalSynthesis = janitorResult.response.text();
3166
- else throw new Error("No synthesis generated by Janitor.");
3167
- await incrementUsage("background");
3168
- if (janitorResult.usageMetadata) {
3169
- await addToUsage("tokens", janitorResult.usageMetadata.totalTokenCount || 0);
3200
+ } else {
3201
+ throw new Error("No synthesis generated by Janitor.");
3170
3202
  }
3171
3203
  yield { type: "background_increment" };
3172
3204
  const janitorToolCalls = detectToolCalls(finalSynthesis);
@@ -3188,8 +3220,11 @@ ${boxBottom}
3188
3220
  fs16.mkdirSync(janitorErrDir, { recursive: true });
3189
3221
  }
3190
3222
  fs16.appendFileSync(path16.join(janitorErrDir, "error.log"), `ERROR [${date}]: ${String(janitorErr)}
3223
+
3224
+ ----------------------------------------------------------------------
3225
+
3226
+
3191
3227
  `);
3192
- console.error("Janitor Background Tasks Failed:", janitorErr.message);
3193
3228
  }
3194
3229
  const timestamp = `Responded on ${(/* @__PURE__ */ new Date()).toLocaleString()}`;
3195
3230
  const finalWithTime = `${cleanedFullResponse}
@@ -3982,7 +4017,7 @@ ${hintText}`, color: "magenta" }];
3982
4017
  resumedMsgs.unshift({ id: "welcome-" + Date.now(), role: "system", text: FLUX_LOGO + "\n\n\u{1F30A}\u26A1 Resuming Flux Flow Session...\n" });
3983
4018
  }
3984
4019
  setMessages(resumedMsgs);
3985
- setMessages((prev) => [...prev, { id: "sys-" + Date.now(), role: "system", text: `\u{1F4E1} SESSION RESUMED: [${targetId}]` }]);
4020
+ setMessages((prev) => [...prev, { id: "sys-" + Date.now(), role: "system", text: `\u{1F4E1} SESSION RESUMED: [${targetId}]`, isMeta: true }]);
3986
4021
  setCompletedIndex(0);
3987
4022
  } else {
3988
4023
  setMessages((prev) => [...prev, { id: "err-" + Date.now(), role: "system", text: `\u274C ERROR: Session [${targetId}] not found.` }]);
@@ -5162,8 +5197,8 @@ var init_app = __esm({
5162
5197
  init_text();
5163
5198
  SESSION_START_TIME = Date.now();
5164
5199
  CHANGELOG_URL = "https://fluxflow-cli.onrender.com/changelog.html";
5165
- versionFluxflow = "1.8.15";
5166
- updatedOn = "2026-05-09";
5200
+ versionFluxflow = "1.8.17";
5201
+ updatedOn = "2026-05-10";
5167
5202
  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(
5168
5203
  CommandMenu,
5169
5204
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fluxflow-cli",
3
- "version": "1.8.15",
3
+ "version": "1.8.17",
4
4
  "description": "A high-fidelity agentic terminal assistant for the Flux Era.",
5
5
  "keywords": [
6
6
  "ai",