sapper-iq 1.1.30 → 1.1.32
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/package.json +1 -1
- package/sapper.mjs +37 -3
package/package.json
CHANGED
package/sapper.mjs
CHANGED
|
@@ -1061,7 +1061,10 @@ TOOL SYNTAX:
|
|
|
1061
1061
|
spinner.stop();
|
|
1062
1062
|
|
|
1063
1063
|
let msg = '';
|
|
1064
|
-
const MAX_RESPONSE_LENGTH =
|
|
1064
|
+
const MAX_RESPONSE_LENGTH = 100000; // 100KB - allow long code generation
|
|
1065
|
+
let lastChunkTime = Date.now();
|
|
1066
|
+
let repetitionCount = 0;
|
|
1067
|
+
let lastContent = '';
|
|
1065
1068
|
abortStream = false; // Reset abort flag before streaming
|
|
1066
1069
|
|
|
1067
1070
|
console.log(chalk.magenta('┌─[') + chalk.white.bold('Sapper') + chalk.magenta(']'));
|
|
@@ -1077,9 +1080,27 @@ TOOL SYNTAX:
|
|
|
1077
1080
|
process.stdout.write(content);
|
|
1078
1081
|
msg += content;
|
|
1079
1082
|
|
|
1083
|
+
// Smart loop detection: check for repetitive content patterns
|
|
1084
|
+
if (msg.length > 10000) {
|
|
1085
|
+
const recentContent = msg.slice(-500);
|
|
1086
|
+
const previousContent = msg.slice(-1000, -500);
|
|
1087
|
+
|
|
1088
|
+
// If last 500 chars are very similar to previous 500, might be looping
|
|
1089
|
+
if (recentContent === previousContent) {
|
|
1090
|
+
repetitionCount++;
|
|
1091
|
+
if (repetitionCount > 3) {
|
|
1092
|
+
console.log(chalk.red('\n\n⚠️ REPETITIVE OUTPUT DETECTED: Stopping to prevent loop.'));
|
|
1093
|
+
break;
|
|
1094
|
+
}
|
|
1095
|
+
} else {
|
|
1096
|
+
repetitionCount = 0;
|
|
1097
|
+
}
|
|
1098
|
+
}
|
|
1099
|
+
|
|
1100
|
+
// Hard limit as final safety net
|
|
1080
1101
|
if (msg.length > MAX_RESPONSE_LENGTH) {
|
|
1081
|
-
console.log(chalk.
|
|
1082
|
-
break
|
|
1102
|
+
console.log(chalk.yellow('\n\n⚠️ Response very long (100KB+). Continuing... (Ctrl+C to stop)'));
|
|
1103
|
+
// Don't break - just warn. User can Ctrl+C if needed
|
|
1083
1104
|
}
|
|
1084
1105
|
}
|
|
1085
1106
|
console.log();
|
|
@@ -1101,6 +1122,19 @@ TOOL SYNTAX:
|
|
|
1101
1122
|
// Regex: supports both old format (path]content) and new format (path:::content)
|
|
1102
1123
|
const toolMatches = [...msg.matchAll(/\[TOOL:(\w+)\]([^:\]]*?)(?:(?:::|\])([\s\S]*?))?\[\/TOOL\]/g)];
|
|
1103
1124
|
|
|
1125
|
+
// Check for unclosed tool calls (AI started a tool but didn't close it)
|
|
1126
|
+
const hasUnclosedTool = msg.includes('[TOOL:') && !msg.includes('[/TOOL]');
|
|
1127
|
+
if (hasUnclosedTool) {
|
|
1128
|
+
console.log(chalk.yellow('\n⚠️ Unclosed tool detected! AI forgot [/TOOL] closing tag.'));
|
|
1129
|
+
console.log(chalk.gray(' Asking AI to complete the tool call...\n'));
|
|
1130
|
+
|
|
1131
|
+
messages.push({
|
|
1132
|
+
role: 'user',
|
|
1133
|
+
content: 'ERROR: Your tool call is incomplete - you forgot to add [/TOOL] at the end. Please complete the tool call by providing the closing [/TOOL] tag. If you were writing a file, just output [/TOOL] to close it.'
|
|
1134
|
+
});
|
|
1135
|
+
continue; // Let AI respond with the closing tag
|
|
1136
|
+
}
|
|
1137
|
+
|
|
1104
1138
|
// Debug mode: show what regex sees
|
|
1105
1139
|
if (debugMode) {
|
|
1106
1140
|
console.log(chalk.magenta('\n═══ DEBUG: REGEX ANALYSIS ═══'));
|