fluxflow-cli 1.10.6 → 1.10.7
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 +47 -9
- package/package.json +1 -1
package/dist/fluxflow.js
CHANGED
|
@@ -3503,6 +3503,8 @@ ${thinkingLevel != "Fast" ? "[SYSTEM] **STRICTLY FOLLOW THINKING POLICY AS STRIC
|
|
|
3503
3503
|
let isStutteringLoop = false;
|
|
3504
3504
|
let isInitialAttempt = true;
|
|
3505
3505
|
let accumulatedContext = "";
|
|
3506
|
+
let dedupeBuffer = "";
|
|
3507
|
+
let isDedupeActive = false;
|
|
3506
3508
|
while (retryCount <= MAX_RETRIES && inStreamRetryCount <= MAX_RETRIES && !success && !TERMINATION_SIGNAL) {
|
|
3507
3509
|
try {
|
|
3508
3510
|
if (isInitialAttempt) {
|
|
@@ -3512,7 +3514,9 @@ ${thinkingLevel != "Fast" ? "[SYSTEM] **STRICTLY FOLLOW THINKING POLICY AS STRIC
|
|
|
3512
3514
|
yield { type: "turn_reset", content: true };
|
|
3513
3515
|
yield { type: "spinner", content: true };
|
|
3514
3516
|
isInitialAttempt = false;
|
|
3515
|
-
|
|
3517
|
+
if (inStreamRetryCount === 1) {
|
|
3518
|
+
accumulatedContext = "";
|
|
3519
|
+
}
|
|
3516
3520
|
}
|
|
3517
3521
|
const contents = modifiedHistory.filter((msg) => (msg.role === "user" || msg.role === "agent" || msg.role === "system") && !String(msg.id).startsWith("welcome") && !msg.isMeta).map((msg) => {
|
|
3518
3522
|
const parts = [{ text: msg.text }];
|
|
@@ -3583,8 +3587,8 @@ ${thinkingLevel != "Fast" ? "[SYSTEM] **STRICTLY FOLLOW THINKING POLICY AS STRIC
|
|
|
3583
3587
|
toolCallPointer = 0;
|
|
3584
3588
|
yield { type: "model_update", content: null };
|
|
3585
3589
|
yield { type: "status", content: "Working..." };
|
|
3586
|
-
|
|
3587
|
-
|
|
3590
|
+
dedupeBuffer = "";
|
|
3591
|
+
isDedupeActive = accumulatedContext.length > 0;
|
|
3588
3592
|
for await (const chunk of stream) {
|
|
3589
3593
|
if (TERMINATION_SIGNAL) {
|
|
3590
3594
|
yield { type: "status", content: "Termination Signal Received." };
|
|
@@ -3992,6 +3996,25 @@ ${boxBottom}` };
|
|
|
3992
3996
|
success = true;
|
|
3993
3997
|
await incrementUsage("agent");
|
|
3994
3998
|
} catch (err) {
|
|
3999
|
+
if (isDedupeActive && dedupeBuffer.length > 0) {
|
|
4000
|
+
let overlapLen = 0;
|
|
4001
|
+
const maxPossibleOverlap = Math.min(accumulatedContext.length, dedupeBuffer.length);
|
|
4002
|
+
for (let len = maxPossibleOverlap; len > 0; len--) {
|
|
4003
|
+
if (accumulatedContext.endsWith(dedupeBuffer.substring(0, len))) {
|
|
4004
|
+
overlapLen = len;
|
|
4005
|
+
break;
|
|
4006
|
+
}
|
|
4007
|
+
}
|
|
4008
|
+
const cleanText = dedupeBuffer.substring(overlapLen);
|
|
4009
|
+
if (cleanText) {
|
|
4010
|
+
const dedupeClean = cleanText.replace(/^\s*<(think|thought)>[\s\S]*?<\/(think|thought)>\s*/gi, "").replace(/^\s*<(think|thought)>\s*/gi, "");
|
|
4011
|
+
if (dedupeClean) {
|
|
4012
|
+
turnText += dedupeClean;
|
|
4013
|
+
}
|
|
4014
|
+
}
|
|
4015
|
+
isDedupeActive = false;
|
|
4016
|
+
dedupeBuffer = "";
|
|
4017
|
+
}
|
|
3995
4018
|
const errMsg = err.status || err.error && err.error.message || String(err);
|
|
3996
4019
|
const errLog = String(err);
|
|
3997
4020
|
const date = (/* @__PURE__ */ new Date()).toLocaleString();
|
|
@@ -4009,16 +4032,31 @@ ${boxBottom}` };
|
|
|
4009
4032
|
throw err;
|
|
4010
4033
|
}
|
|
4011
4034
|
}
|
|
4012
|
-
if (turnText.trim().length > 0 ||
|
|
4035
|
+
if (turnText.trim().length > 0 || inStreamRetryCount > 1) {
|
|
4013
4036
|
if (inStreamRetryCount <= MAX_RETRIES) {
|
|
4014
4037
|
inStreamRetryCount++;
|
|
4015
4038
|
const waitTime = Math.min(1e3 * Math.pow(2, inStreamRetryCount - 1), 24e3);
|
|
4016
|
-
|
|
4017
|
-
|
|
4018
|
-
|
|
4039
|
+
if (turnText.trim().length > 0) {
|
|
4040
|
+
modifiedHistory.push({ role: "agent", text: turnText });
|
|
4041
|
+
const recoveryText = "[SYSTEM: STREAM RECOVERY]\n- SEAMLESS CONTINUATION: Resume immediately. Pick up from last words with zero gap/disruption.\n- NO REPETITION: Do not repeat any text already written.\n- NO RE-THINK: Do not restart or open <think> if reasoning already started.\n- MID-TOOL SAFETY: If cutoff was mid-tool call, restart that tool call from start.\n- STEALTH: Do not mention/apologize for cutoff.\n- KEEP LENGTH: Maintain standard depth/length.";
|
|
4042
|
+
if (toolResults.length > 0) {
|
|
4043
|
+
toolResults.forEach((tr, idx) => {
|
|
4044
|
+
if (idx === toolResults.length - 1) {
|
|
4045
|
+
modifiedHistory.push({
|
|
4046
|
+
...tr,
|
|
4047
|
+
text: `${tr.text}
|
|
4048
|
+
|
|
4049
|
+
${recoveryText}`
|
|
4050
|
+
});
|
|
4051
|
+
} else {
|
|
4052
|
+
modifiedHistory.push(tr);
|
|
4053
|
+
}
|
|
4054
|
+
});
|
|
4055
|
+
} else {
|
|
4056
|
+
modifiedHistory.push({ role: "user", text: recoveryText });
|
|
4057
|
+
}
|
|
4058
|
+
accumulatedContext += turnText;
|
|
4019
4059
|
}
|
|
4020
|
-
modifiedHistory.push({ role: "user", text: "[SYSTEM] Response got cut for internal error, continue from checkpoint seamlessly, DON'T repeat what you already said! PICK UP FROM THE WORD IN A WAY THAT USER SHOULD NOT NOTICE ANY CUTOFF. Rules:\n- Do not reuse <think> if the thinking already started just continue from the word and end it properly.\n- If the cutoff was in middle of a tool call, start the tool call from start.\n- Visually the new pickup and continuation should look natual sentence flow.\n- Dont mention about the cutoff.\n- DON'T try to think shorter, keep length standard." });
|
|
4021
|
-
accumulatedContext += turnText;
|
|
4022
4060
|
for (let i = waitTime / 1e3; i > 0; i--) {
|
|
4023
4061
|
yield { type: "status", content: `Error Occured. Recovering Stream (${inStreamRetryCount}/${MAX_RETRIES}) [${i}s]...` };
|
|
4024
4062
|
await new Promise((resolve) => setTimeout(resolve, 1e3));
|