fluxflow-cli 1.17.1 → 1.17.2
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 +35 -17
- package/package.json +1 -1
package/dist/fluxflow.js
CHANGED
|
@@ -304,7 +304,10 @@ var init_ChatLayout = __esm({
|
|
|
304
304
|
const colPercentage = Math.floor(100 / header.length);
|
|
305
305
|
const availableWidth = terminalWidth - 8;
|
|
306
306
|
const colChars = Math.floor(availableWidth / header.length) - 2;
|
|
307
|
-
return
|
|
307
|
+
return (
|
|
308
|
+
// Table MarginY here
|
|
309
|
+
/* @__PURE__ */ React2.createElement(Box2, { flexDirection: "column", borderStyle: "round", borderColor: "#454545ff", paddingX: 1, marginY: 0, width: "100%", flexGrow: 1 }, /* @__PURE__ */ React2.createElement(Box2, { flexDirection: "row", borderStyle: "single", borderBottom: true, borderTop: false, borderLeft: false, borderRight: false, borderColor: "#444", marginBottom: 1, paddingBottom: 0, width: "100%" }, header.map((cell, i) => /* @__PURE__ */ React2.createElement(Box2, { key: i, flexBasis: `${colPercentage}%`, flexGrow: 1, flexShrink: 0, paddingRight: 2 }, /* @__PURE__ */ React2.createElement(InlineMarkdown, { text: wrapText(cell, colChars), color: "cyan" })))), data.map((row, ri) => /* @__PURE__ */ React2.createElement(Box2, { key: ri, flexDirection: "row", marginBottom: ri === data.length - 1 ? 0 : 1, width: "100%" }, row.map((cell, ci) => /* @__PURE__ */ React2.createElement(Box2, { key: ci, flexBasis: `${colPercentage}%`, flexGrow: 1, flexShrink: 0, paddingRight: 2, flexDirection: "column" }, /* @__PURE__ */ React2.createElement(InlineMarkdown, { text: wrapText(cell, colChars), color: "white" }))))))
|
|
310
|
+
);
|
|
308
311
|
});
|
|
309
312
|
MarkdownText = React2.memo(({ text, color = "white", columns = 80 }) => {
|
|
310
313
|
if (!text) return null;
|
|
@@ -391,7 +394,7 @@ var init_ChatLayout = __esm({
|
|
|
391
394
|
const match = text.match(/\[DIFF_START\]([\s\S]*?)\[DIFF_END\]/);
|
|
392
395
|
const diffBody = match ? match[1].trim() : "";
|
|
393
396
|
const diffLines = diffBody.split("\n");
|
|
394
|
-
return /* @__PURE__ */ React2.createElement(Box2, { flexDirection: "column", width: "100%" }, /* @__PURE__ */ React2.createElement(Box2, { flexDirection: "column", backgroundColor: "#1a1a1a", paddingY: 0, width: "100%" }, diffLines.map((line, i) => /* @__PURE__ */ React2.createElement(DiffLine, { key: i, line, columns }))));
|
|
397
|
+
return /* @__PURE__ */ React2.createElement(Box2, { flexDirection: "column", width: "100%", marginBottom: 0 }, /* @__PURE__ */ React2.createElement(Box2, { flexDirection: "column", backgroundColor: "#1a1a1a", paddingY: 0, width: "100%" }, diffLines.map((line, i) => /* @__PURE__ */ React2.createElement(DiffLine, { key: i, line, columns }))));
|
|
395
398
|
});
|
|
396
399
|
CodeRenderer = React2.memo(({ text, columns = 80 }) => {
|
|
397
400
|
if (!text) return null;
|
|
@@ -419,9 +422,17 @@ var init_ChatLayout = __esm({
|
|
|
419
422
|
const code = match ? match[2] : part.replace(/^```\w*\n?/, "").replace(/```$/, "");
|
|
420
423
|
const codeLines = code.trimEnd().split("\n");
|
|
421
424
|
const gutterWidth = String(codeLines.length).length;
|
|
422
|
-
return /* @__PURE__ */ React2.createElement(Box2, { key: i, flexDirection: "column", marginY:
|
|
425
|
+
return /* @__PURE__ */ React2.createElement(Box2, { key: i, flexDirection: "column", marginY: 0, backgroundColor: "#111", borderStyle: "round", borderColor: "#333", paddingX: 1, width: "100%" }, /* @__PURE__ */ React2.createElement(Box2, { alignSelf: "flex-end", marginTop: -1, marginRight: 1 }, /* @__PURE__ */ React2.createElement(Text2, { backgroundColor: "#333", color: "white" }, " ", lang.toUpperCase(), " ")), /* @__PURE__ */ React2.createElement(Box2, { flexDirection: "column", paddingY: 1, width: "100%" }, codeLines.map((line, idx) => /* @__PURE__ */ React2.createElement(Box2, { key: idx, width: "100%" }, /* @__PURE__ */ React2.createElement(Box2, { width: gutterWidth + 2, flexShrink: 0 }, /* @__PURE__ */ React2.createElement(Text2, { color: "gray", dimColor: true }, String(idx + 1).padStart(gutterWidth, " "), " ")), /* @__PURE__ */ React2.createElement(Box2, { flexGrow: 1 }, /* @__PURE__ */ React2.createElement(Text2, { color: "cyan" }, line))))));
|
|
426
|
+
}
|
|
427
|
+
let cleanPart = part;
|
|
428
|
+
if (i > 0) {
|
|
429
|
+
cleanPart = cleanPart.replace(/^[\r\n]+/, "");
|
|
423
430
|
}
|
|
424
|
-
|
|
431
|
+
if (i < parts.length - 1) {
|
|
432
|
+
cleanPart = cleanPart.replace(/[\r\n]+$/, "");
|
|
433
|
+
}
|
|
434
|
+
if (!cleanPart) return null;
|
|
435
|
+
return /* @__PURE__ */ React2.createElement(MarkdownText, { key: i, text: cleanPart, columns });
|
|
425
436
|
}));
|
|
426
437
|
}
|
|
427
438
|
return /* @__PURE__ */ React2.createElement(MarkdownText, { text, columns });
|
|
@@ -522,7 +533,7 @@ var init_ChatLayout = __esm({
|
|
|
522
533
|
}, [content, msg.role, showFullThinking, msg.isStreaming]);
|
|
523
534
|
return (
|
|
524
535
|
// [SPACE POINT]
|
|
525
|
-
/* @__PURE__ */ React2.createElement(Box2, { marginBottom: msg.role === "think" ? 0 : msg.role === "user" ? 1 : msg.role === "agent" ? 0 :
|
|
536
|
+
/* @__PURE__ */ React2.createElement(Box2, { marginBottom: msg.role === "think" ? 0 : msg.role === "user" ? 1 : msg.role === "agent" ? 0 : 1, marginTop: msg.role === "think" ? 0 : msg.role === "user" ? 0 : msg.role === "agent" ? 0 : 0, flexDirection: "column", flexShrink: 0, width: "100%", flexGrow: 1 }, msg.role === "user" ? /* @__PURE__ */ React2.createElement(
|
|
526
537
|
Box2,
|
|
527
538
|
{
|
|
528
539
|
backgroundColor: "#262626",
|
|
@@ -535,7 +546,7 @@ var init_ChatLayout = __esm({
|
|
|
535
546
|
finalContent.replace(/\r\n/g, "\n").replace(/\r/g, "\n").replace(/\\\n/g, "\n").replace(/\\$/, ""),
|
|
536
547
|
columns - 6
|
|
537
548
|
).split("\n").map((line, lineIdx) => /* @__PURE__ */ React2.createElement(Box2, { key: lineIdx, flexDirection: "row", width: "100%" }, /* @__PURE__ */ React2.createElement(Box2, { flexShrink: 0, width: 2 }, /* @__PURE__ */ React2.createElement(Text2, { bold: true, color: "white" }, lineIdx === 0 ? "\u276F" : " ")), /* @__PURE__ */ React2.createElement(Box2, { flexGrow: 1, marginLeft: 1 }, /* @__PURE__ */ React2.createElement(InlineMarkdown, { text: line, color: msg.color || "white" }))))
|
|
538
|
-
) : msg.role === "think" ? /* @__PURE__ */ React2.createElement(Box2, { flexDirection: "column", marginTop: 0, marginBottom: 0, paddingX: 1, width: "100%" }, msg.isStreaming && !msg.duration ? /* @__PURE__ */ React2.createElement(Text2, { bold: true, color: "white" }, "\u2727 Thinking...") : /* @__PURE__ */ React2.createElement(Text2, { bold: true, color: "white" }, "\u2726 Thought", msg.duration ? /* @__PURE__ */ React2.createElement(Text2, {
|
|
549
|
+
) : msg.role === "think" ? /* @__PURE__ */ React2.createElement(Box2, { flexDirection: "column", marginTop: 0, marginBottom: 0, paddingX: 1, width: "100%" }, msg.isStreaming && !msg.duration ? /* @__PURE__ */ React2.createElement(Text2, { bold: true, color: "white" }, "\u2727 Thinking...") : /* @__PURE__ */ React2.createElement(Text2, { bold: true, color: "white" }, "\u2726 Thought", msg.duration ? /* @__PURE__ */ React2.createElement(Text2, { color: "gray" }, " for ", /* @__PURE__ */ React2.createElement(Text2, { bold: true, color: "cyan" }, formatThinkingDuration(msg.duration))) : ""), /* @__PURE__ */ React2.createElement(Box2, { borderStyle: "single", borderLeft: true, borderRight: false, borderTop: false, borderBottom: false, paddingLeft: 2, paddingTop: 1, paddingBottom: 1, flexDirection: "column", width: "100%" }, formatThinkText(finalContent, columns))) : /* @__PURE__ */ React2.createElement(Box2, { flexDirection: "column", paddingX: 1, marginTop: 0, width: "100%" }, /* @__PURE__ */ React2.createElement(CodeRenderer, { text: finalContent.replace(/ \|\n\n/g, " |\n"), columns }), msg.memoryUpdated && /* @__PURE__ */ React2.createElement(Box2, { marginTop: 1, width: "100%" }, /* @__PURE__ */ React2.createElement(Text2, { color: "yellow", italic: true }, "\u2728 [Memory Updated]")), msg.role === "agent" && msg.workedDuration ? /* @__PURE__ */ React2.createElement(Box2, { marginTop: 1, marginBottom: 2, width: "100%" }, /* @__PURE__ */ React2.createElement(Text2, null, "["), /* @__PURE__ */ React2.createElement(Text2, { color: "gray" }, "\u26A1 Worked for ", /* @__PURE__ */ React2.createElement(Text2, { bold: true, color: "cyan" }, formatThinkingDuration(msg.workedDuration))), /* @__PURE__ */ React2.createElement(Text2, null, "]")) : null))
|
|
539
550
|
);
|
|
540
551
|
});
|
|
541
552
|
ChatLayout = React2.memo(({ messages, showFullThinking, columns = 80 }) => {
|
|
@@ -1280,7 +1291,8 @@ var init_main_tools = __esm({
|
|
|
1280
1291
|
TOOL_PROTOCOL = (mode, osDetected) => `
|
|
1281
1292
|
-- TOOL DEFINITIONS --
|
|
1282
1293
|
Access to internal tools. To call a tool, MUST use the exact syntax on a new line: [tool:functions.ToolName(args)]
|
|
1283
|
-
|
|
1294
|
+
STRICT POLICY
|
|
1295
|
+
- **MAX 3 TOOL CALLS PER TURN. Next Turn, verify results, plan next**${mode === "Flux" ? "\n- **File Tools >> Code in chat**" : ""}
|
|
1284
1296
|
|
|
1285
1297
|
- COMMUNICATION TOOLS -
|
|
1286
1298
|
1. [tool:functions.Ask(question="...", optionA="option::description", ...MAX 4)]. Ambiguity Resolution. Mandatory Triggers: Path Divergence, Security, Risk Mitigation. ask >> finish
|
|
@@ -1302,7 +1314,6 @@ ${mode === "Flux" ? `- PROJECT TOOLS (path = relative to CWD) -
|
|
|
1302
1314
|
9. [tool:functions.WriteDoc(path="...", content="...")]. A4 Word document
|
|
1303
1315
|
|
|
1304
1316
|
- VERIFY TOOL RESULT CONTENTS. Fix errors. No hallucinations
|
|
1305
|
-
- File tools >>> Long chat
|
|
1306
1317
|
|
|
1307
1318
|
- Escape quotes: \\" for code strings
|
|
1308
1319
|
- Literal escapes: Double-escape sequences (e.g., \\\\n, \\\\t)
|
|
@@ -1424,7 +1435,7 @@ Check these first; These Files > Training Data. Safety rules apply
|
|
|
1424
1435
|
return `${nameStr}${nicknameStr}${userInstrStr}[SYSTEM]
|
|
1425
1436
|
Identity: Flux Flow (by Kushal Roy Chowdhury). Sassy${mode === "Flux" ? ", No Flirting, Respectful" : ", Friendly, Humorous, Sarcastic"}, CLI Agent
|
|
1426
1437
|
Mode: ${mode}${thinkingLevel !== "Fast" ? " (Thinking Mode)" : ""}. ${mode === "Flux" ? "Logical, Highly Detailed, Task-Driven. Prioritizes scalable file/folder structures, modular architecture, clean code abstractions, step-by-step execution. Industry standard latest coding practices/libraries, clean code, Double Check Imports, Client-Server Sync" : "Conversational, Concise"}
|
|
1427
|
-
|
|
1438
|
+
|
|
1428
1439
|
-- THINKING RULES --
|
|
1429
1440
|
${thinkingConfig}
|
|
1430
1441
|
${thinkingLevel !== "Fast" ? `
|
|
@@ -1439,7 +1450,7 @@ ${projectContextBlock}
|
|
|
1439
1450
|
- Temporal Awareness: RELATIVE TIME REFERENCE eg. few mins ago
|
|
1440
1451
|
|
|
1441
1452
|
-- SECURITY RULES --${systemSettings.allowExternalAccess ? "" : "\n- ACCESS CONTROL: CWD only"}
|
|
1442
|
-
- Sensitive files? Ask before Read
|
|
1453
|
+
- Sensitive files? Ask before Read${isSystemDir ? "\nPROTECTED DIRECTORY: ASK BEFORE MODIFYING" : ""}
|
|
1443
1454
|
|
|
1444
1455
|
-- FORMATTING --
|
|
1445
1456
|
- GFM Supported
|
|
@@ -1450,6 +1461,7 @@ ${projectContextBlock}
|
|
|
1450
1461
|
- End with [turn: continue] to continue or [turn: finish] when task done
|
|
1451
1462
|
- Tool Called? No post tool response until [turn: continue]
|
|
1452
1463
|
- Task Complete? End loop with [turn: finish]
|
|
1464
|
+
- NEVER USE [turn: continue] [turn:finish] together
|
|
1453
1465
|
[/SYSTEM]`.trim();
|
|
1454
1466
|
};
|
|
1455
1467
|
getJanitorInstruction = (userMemories = "", isMemoryEnabled = true, needTitle = true) => {
|
|
@@ -2957,7 +2969,7 @@ var init_update_file = __esm({
|
|
|
2957
2969
|
const lineEndPos = currentContent.indexOf("\n", affectedEndPos);
|
|
2958
2970
|
const actualEndPos = lineEndPos === -1 ? currentContent.length : lineEndPos;
|
|
2959
2971
|
const fullOldLines = currentContent.substring(lineStartPos, actualEndPos).split("\n");
|
|
2960
|
-
const newAffectedEndPos = startPos +
|
|
2972
|
+
const newAffectedEndPos = startPos + finalContentToAdd.length;
|
|
2961
2973
|
const newLineEndPos = newFileContent.indexOf("\n", newAffectedEndPos);
|
|
2962
2974
|
const actualNewEndPos = newLineEndPos === -1 ? newFileContent.length : newLineEndPos;
|
|
2963
2975
|
const fullNewLines = newFileContent.substring(lineStartPos, actualNewEndPos).split("\n");
|
|
@@ -4699,13 +4711,14 @@ ${newMemoryListStr}
|
|
|
4699
4711
|
return "";
|
|
4700
4712
|
}
|
|
4701
4713
|
};
|
|
4714
|
+
yield { type: "status", content: "Gathering Context..." };
|
|
4702
4715
|
let dirStructure = process.cwd() + "\n" + getDirTree(process.cwd());
|
|
4703
4716
|
const firstUserMsg = `[METADATA (PRIORITY: DYNAMIC)] Time: ${dateTimeStr} | v${versionFluxflow2}
|
|
4704
4717
|
CWD: ${process.cwd()}
|
|
4705
4718
|
**DIRECTORY STRUCTURE**
|
|
4706
4719
|
${dirStructure}
|
|
4707
4720
|
${memoryPrompt}
|
|
4708
|
-
${thinkingLevel != "Fast" ? "[SYSTEM] **STRICTLY FOLLOW THINKING POLICY AS
|
|
4721
|
+
${thinkingLevel != "Fast" ? "[SYSTEM] **STRICTLY FOLLOW THINKING POLICY AS CRITICAL PRIORITY. DO NOT START A RESPONSE WITHOUT <think> ... </think>**\n" : ""}[USER] ${agentText.replace(/\s*\[Prompted on:.*?\]/g, "").trim()}`.trim();
|
|
4709
4722
|
modifiedHistory.push({ role: "user", text: firstUserMsg });
|
|
4710
4723
|
let lastUsage = null;
|
|
4711
4724
|
const MAX_LOOPS = mode === "Flux" ? 70 : 7;
|
|
@@ -4736,7 +4749,7 @@ ${thinkingLevel != "Fast" ? "[SYSTEM] **STRICTLY FOLLOW THINKING POLICY AS CORE
|
|
|
4736
4749
|
|
|
4737
4750
|
[STEERING HINT]: ${hint}`;
|
|
4738
4751
|
} else {
|
|
4739
|
-
modifiedHistory.push({ role: "user", text: `${thinkingLevel != "Fast" ? "[SYSTEM] **STRICTLY FOLLOW THINKING POLICY AS
|
|
4752
|
+
modifiedHistory.push({ role: "user", text: `${thinkingLevel != "Fast" ? "[SYSTEM] **STRICTLY FOLLOW THINKING POLICY AS CRITICAL PRIORITY. DO NOT START A RESPONSE WITHOUT <think> ... </think>**\n" : ""}[STEERING HINT]: ${hint}` });
|
|
4740
4753
|
}
|
|
4741
4754
|
yield { type: "status", content: "Steering Hint Injected." };
|
|
4742
4755
|
}
|
|
@@ -4803,7 +4816,7 @@ ${thinkingLevel != "Fast" ? "[SYSTEM] **STRICTLY FOLLOW THINKING POLICY AS CORE
|
|
|
4803
4816
|
const currentSystemInstruction = getSystemInstruction(profile, thinkingLevel, mode, systemSettings, isMemoryEnabled, MAX_LOOPS, loop + 1);
|
|
4804
4817
|
const jitInstruction = `
|
|
4805
4818
|
|
|
4806
|
-
[SYSTEM] Tool result received. Analyze output and proceed with your turn.${thinkingLevel != "Fast" ? "**STRICTLY MAINTAIN THINKING
|
|
4819
|
+
[SYSTEM] Tool result received. Analyze output and proceed with your turn.${thinkingLevel != "Fast" ? "**STRICTLY MAINTAIN THINKING POLICY. DO NOT START A RESPONSE WITHOUT <think> ... </think>**" : ""}`;
|
|
4807
4820
|
const lastUserMsg = contents[contents.length - 1];
|
|
4808
4821
|
let addedMarker = false;
|
|
4809
4822
|
if (lastUserMsg && lastUserMsg.role === "user" && lastUserMsg.parts?.[0]?.text?.startsWith("[TOOL RESULT]")) {
|
|
@@ -5836,8 +5849,8 @@ function formatPromptPreview(prompt) {
|
|
|
5836
5849
|
if (!prompt) return "";
|
|
5837
5850
|
const firstLine = prompt.split("\n")[0] || "";
|
|
5838
5851
|
const words = firstLine.split(/\s+/).filter(Boolean);
|
|
5839
|
-
if (words.length >
|
|
5840
|
-
return words.slice(0,
|
|
5852
|
+
if (words.length > 15) {
|
|
5853
|
+
return words.slice(0, 15).join(" ") + "...";
|
|
5841
5854
|
}
|
|
5842
5855
|
if (prompt.includes("\n")) {
|
|
5843
5856
|
return firstLine + "...";
|
|
@@ -7130,7 +7143,8 @@ ${timestamp}` };
|
|
|
7130
7143
|
let hasFiredJanitor = false;
|
|
7131
7144
|
setIsProcessing(true);
|
|
7132
7145
|
setIsExpanded(false);
|
|
7133
|
-
|
|
7146
|
+
let apiStart = Date.now();
|
|
7147
|
+
let isFirstPacket = true;
|
|
7134
7148
|
try {
|
|
7135
7149
|
const cleanHistoryForAI = [...messages, userMessage].filter(
|
|
7136
7150
|
(m) => m.role !== "think" && !m.isVisualFeedback && !String(m.id).startsWith("welcome")
|
|
@@ -7267,6 +7281,10 @@ Selection: ${val}`,
|
|
|
7267
7281
|
let inToolCallString = null;
|
|
7268
7282
|
const signalRegex = /\[?\s*turn\s*:\s*.*?\s*\]?/gi;
|
|
7269
7283
|
for await (const packet of stream) {
|
|
7284
|
+
if (isFirstPacket && packet.type === "text") {
|
|
7285
|
+
apiStart = Date.now();
|
|
7286
|
+
isFirstPacket = false;
|
|
7287
|
+
}
|
|
7270
7288
|
if (packet.type === "status") {
|
|
7271
7289
|
setStatusText(packet.content);
|
|
7272
7290
|
continue;
|