fluxflow-cli 1.0.12 → 1.0.13
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.
- package/dist/fluxflow.js +23 -49
- package/package.json +1 -1
package/dist/fluxflow.js
CHANGED
|
@@ -192,7 +192,7 @@ function StatusBar({ mode, thinkingLevel, tokens = "0.0k", chatId = "NEW-SESSION
|
|
|
192
192
|
},
|
|
193
193
|
/* @__PURE__ */ React3.createElement(Box3, null, /* @__PURE__ */ React3.createElement(Text3, { color: modeColor, bold: true }, modeIcon, " ", mode.toUpperCase()), /* @__PURE__ */ React3.createElement(Text3, { color: "gray" }, " \u2502 "), /* @__PURE__ */ React3.createElement(Text3, { color: "magenta" }, "\u{1F9E0} ", thinkingLevel)),
|
|
194
194
|
/* @__PURE__ */ React3.createElement(Box3, { flexGrow: 1, justifyContent: "center", paddingX: 2 }, /* @__PURE__ */ React3.createElement(Text3, { color: "gray", dimColor: true }, "\u{1F4C1} "), /* @__PURE__ */ React3.createElement(Text3, { color: "blue", dimColor: true, italic: true }, process.cwd())),
|
|
195
|
-
/* @__PURE__ */ React3.createElement(Box3, null, /* @__PURE__ */ React3.createElement(Text3, { color: "gray" }, "MEM: "), /* @__PURE__ */ React3.createElement(Text3, { color: memStatus === "ON" ? "green" : "red" }, memStatus), /* @__PURE__ */ React3.createElement(Text3, { color: "gray" }, " \u2502 "), /* @__PURE__ */ React3.createElement(Text3, { color: "blue" }, " Tokens ", tokens > 1e3 ? `${(tokens / 1e3).toFixed(1)}k` : tokens, " (", Math.round(tokens /
|
|
195
|
+
/* @__PURE__ */ React3.createElement(Box3, null, /* @__PURE__ */ React3.createElement(Text3, { color: "gray" }, "MEM: "), /* @__PURE__ */ React3.createElement(Text3, { color: memStatus === "ON" ? "green" : "red" }, memStatus), /* @__PURE__ */ React3.createElement(Text3, { color: "gray" }, " \u2502 "), /* @__PURE__ */ React3.createElement(Text3, { color: "blue" }, " Tokens ", tokens > 1e3 ? `${(tokens / 1e3).toFixed(1)}k` : tokens, " (", Math.round(tokens / 254e3 * 100), "%)"), /* @__PURE__ */ React3.createElement(Text3, { color: "gray" }, " \u2502 "), /* @__PURE__ */ React3.createElement(Text3, { color: "dim" }, "ID: ", chatId, " "))
|
|
196
196
|
);
|
|
197
197
|
}
|
|
198
198
|
|
|
@@ -345,11 +345,11 @@ tool:functions.tool_name(arguments)
|
|
|
345
345
|
2. Web Scrape: tool:functions.web_scrape(url="<url>"). provides detail from a URL.
|
|
346
346
|
${mode === "Flux" ? `
|
|
347
347
|
- DEV & FILE TOOLS (Available in FLUX MODE ONLY) -
|
|
348
|
-
1. View File: tool:functions.view_file(path="relative/path", start_line=number, end_line=number). Reads file content.
|
|
348
|
+
1. View File: tool:functions.view_file(path="relative/path", start_line=number, end_line=number). Reads file content. Auto-truncates at 500 lines unless start_line and end_line are provided.
|
|
349
349
|
2. List Files: tool:functions.list_files(path="relative/path"). Lists content of a directory.
|
|
350
350
|
3. Read Folder: tool:functions.read_folder(path="relative/path"). Detailed stats of a directory.
|
|
351
|
-
4. Write File: tool:functions.write_file(path="
|
|
352
|
-
5. Update File: tool:functions.update_file(path="relative/path", content_to_replace="old", content_to_add="new"). Surgical patching. RETURNS: High-fidelity visual diff and old code block. You MUST verify that the change specifically matches your intent using the returned diff. PREFFER UPDATE FILE OVER WRITE FILE if file already exists. DONT WRAP UPDATE FILE CALL CONTENT IN MARKDOWN CODE BLOCKS.
|
|
351
|
+
4. Write File: tool:functions.write_file(path="path", content="content"). Creates/Overwrites. NO CODE BLOCKS. RETURNS: Disk verification + original content (if overwritten) for 100% reversibility.
|
|
352
|
+
5. Update File: tool:functions.update_file(path="relative/path", content_to_replace="old", content_to_add="new"). Surgical patching. RETURNS: High-fidelity visual diff and old code block. You MUST verify that the change specifically matches your intent using the returned diff. PREFFER UPDATE FILE OVER WRITE FILE if file already exists for better reversal tracking (if a file has 500+ lines, try to stick with update_file over full-rewrite). DONT WRAP UPDATE FILE CALL CONTENT IN MARKDOWN CODE BLOCKS.
|
|
353
353
|
6. Execution: tool:functions.exec_command(command="terminal command"). Runs a shell command.`.trim() : `
|
|
354
354
|
- DEV & FILE TOOLS are not available in FLOW MODE. If you need to access files, tell the user to switch to FLUX MODE (manually by user).`.trim()}
|
|
355
355
|
-----------------
|
|
@@ -843,46 +843,6 @@ var chat = async (rawArgs, context = {}) => {
|
|
|
843
843
|
}
|
|
844
844
|
};
|
|
845
845
|
|
|
846
|
-
// src/tools/summary.js
|
|
847
|
-
var summary = async (rawArgs, context = {}) => {
|
|
848
|
-
const parseArg = (key) => {
|
|
849
|
-
const regex = new RegExp(`${key}\\s*=\\s*(["'])(.*?)\\1(?=\\s*[,)]|\\s+\\w+\\s*=|$)`, "s");
|
|
850
|
-
const match = rawArgs.match(regex);
|
|
851
|
-
return match ? match[2].trim() : null;
|
|
852
|
-
};
|
|
853
|
-
const content = parseArg("content");
|
|
854
|
-
const chatId = context.chatId;
|
|
855
|
-
const { startIndex, endIndex } = context.summarizedIndices || {};
|
|
856
|
-
if (!chatId) return "ERROR: No active chatId found in tool context.";
|
|
857
|
-
if (!content) return "ERROR: Missing 'content' argument.";
|
|
858
|
-
if (startIndex === void 0 || endIndex === void 0) {
|
|
859
|
-
return "ERROR: Summary tool called without target range indices in context.";
|
|
860
|
-
}
|
|
861
|
-
try {
|
|
862
|
-
const history = await loadHistory();
|
|
863
|
-
if (history[chatId]) {
|
|
864
|
-
const messages = history[chatId].messages;
|
|
865
|
-
const summaryMsg = {
|
|
866
|
-
id: `summary-${Date.now()}`,
|
|
867
|
-
role: "system",
|
|
868
|
-
text: content
|
|
869
|
-
};
|
|
870
|
-
const actualStart = Math.min(startIndex, messages.length - 1);
|
|
871
|
-
const actualEnd = Math.min(endIndex, messages.length - 1);
|
|
872
|
-
const count = actualEnd - actualStart + 1;
|
|
873
|
-
if (count > 0) {
|
|
874
|
-
messages.splice(actualStart, count, summaryMsg);
|
|
875
|
-
await saveChat(chatId, history[chatId].name, messages);
|
|
876
|
-
return `SUCCESS: Compressed ${count} turns into a summary block.`;
|
|
877
|
-
}
|
|
878
|
-
return "ERROR: Targeted range for summarization is invalid or empty.";
|
|
879
|
-
}
|
|
880
|
-
return "ERROR: Chat session not found.";
|
|
881
|
-
} catch (err) {
|
|
882
|
-
return `ERROR: Failed to save summary: ${err.message}`;
|
|
883
|
-
}
|
|
884
|
-
};
|
|
885
|
-
|
|
886
846
|
// src/tools/list_files.js
|
|
887
847
|
import fs7 from "fs";
|
|
888
848
|
import path8 from "path";
|
|
@@ -980,6 +940,21 @@ var write_file = async (args) => {
|
|
|
980
940
|
const absolutePath = path10.resolve(process.cwd(), targetPath);
|
|
981
941
|
const parentDir = path10.dirname(absolutePath);
|
|
982
942
|
try {
|
|
943
|
+
let ancestry = "";
|
|
944
|
+
if (fs9.existsSync(absolutePath)) {
|
|
945
|
+
try {
|
|
946
|
+
const oldData = fs9.readFileSync(absolutePath, "utf8");
|
|
947
|
+
const lines = oldData.split(/\r?\n/);
|
|
948
|
+
ancestry = `Old File contents:
|
|
949
|
+
${lines.map((l, i) => `${i + 1} | ${l}`).join("\n")}
|
|
950
|
+
|
|
951
|
+
`;
|
|
952
|
+
} catch (e) {
|
|
953
|
+
ancestry = `[Note: Could not read existing file for reversal reference]
|
|
954
|
+
|
|
955
|
+
`;
|
|
956
|
+
}
|
|
957
|
+
}
|
|
983
958
|
if (!fs9.existsSync(parentDir)) {
|
|
984
959
|
fs9.mkdirSync(parentDir, { recursive: true });
|
|
985
960
|
}
|
|
@@ -1010,7 +985,7 @@ ${tail}`;
|
|
|
1010
985
|
return `SUCCESS: File [${targetPath}] verified and persisted.
|
|
1011
986
|
|
|
1012
987
|
- Stats: [${verifiedLineCount} lines, ${(verifiedSize / 1024).toFixed(1)} KB]
|
|
1013
|
-
- Content Preview:
|
|
988
|
+
${ancestry}- Content Preview:
|
|
1014
989
|
${snippet}`;
|
|
1015
990
|
} catch (err) {
|
|
1016
991
|
return `ERROR: Failed to write file [${targetPath}]: ${err.message}`;
|
|
@@ -1187,7 +1162,6 @@ var TOOL_MAP = {
|
|
|
1187
1162
|
web_scrape,
|
|
1188
1163
|
memory,
|
|
1189
1164
|
chat,
|
|
1190
|
-
summary,
|
|
1191
1165
|
list_files,
|
|
1192
1166
|
view_file,
|
|
1193
1167
|
write_file,
|
|
@@ -1264,7 +1238,7 @@ var getAIStream = async function* (modelName, history, settings, steeringCallbac
|
|
|
1264
1238
|
const needTitle = isFirstPrompt || hasTitleSignal;
|
|
1265
1239
|
const agentText = originalText.replace(/\[TITLE-UPDATE\]/g, "").trim();
|
|
1266
1240
|
let modifiedHistory = [...history.slice(0, -1)];
|
|
1267
|
-
if (systemSettings?.compression === 0 && (sessionStats?.tokens || 0) >
|
|
1241
|
+
if (systemSettings?.compression === 0 && (sessionStats?.tokens || 0) > 254e3) {
|
|
1268
1242
|
modifiedHistory = getTruncatedHistory(modifiedHistory, 4);
|
|
1269
1243
|
}
|
|
1270
1244
|
const tempStorage = readEncryptedJson(TEMP_MEM_FILE, {});
|
|
@@ -1342,10 +1316,10 @@ USER_PROMPT: ${agentText}`.trim();
|
|
|
1342
1316
|
if (retryCount < MAX_RETRIES) {
|
|
1343
1317
|
retryCount++;
|
|
1344
1318
|
const waitTime = Math.floor(Math.random() * (2e3 - 800 + 1)) + 800;
|
|
1345
|
-
yield { type: "status", content: `Retrying (${retryCount}/${MAX_RETRIES})...` };
|
|
1319
|
+
yield { type: "status", content: `Retrying (${retryCount}/${MAX_RETRIES + 1})...` };
|
|
1346
1320
|
await new Promise((resolve) => setTimeout(resolve, waitTime));
|
|
1347
1321
|
} else {
|
|
1348
|
-
throw new Error(`Model cannot be reached: ${errMsg}. (Failed ${MAX_RETRIES} times)`);
|
|
1322
|
+
throw new Error(`Model cannot be reached: ${errMsg}. (Failed ${MAX_RETRIES + 1} times)`);
|
|
1349
1323
|
}
|
|
1350
1324
|
}
|
|
1351
1325
|
}
|