sapper-iq 1.0.22 → 1.0.24

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/package.json +1 -1
  2. package/sapper.mjs +22 -7
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sapper-iq",
3
- "version": "1.0.22",
3
+ "version": "1.0.24",
4
4
  "description": "AI-powered development assistant that executes commands and builds projects",
5
5
  "main": "sapper.mjs",
6
6
  "bin": {
package/sapper.mjs CHANGED
@@ -166,7 +166,8 @@ WORKFLOW:
166
166
  }];
167
167
  }
168
168
 
169
- const ask = async () => {
169
+ // Main conversation loop - never exits unless user types 'exit'
170
+ while (true) {
170
171
  try {
171
172
  const input = await safeQuestion(chalk.blue.bold('\nIbrahim ➔ '));
172
173
 
@@ -182,11 +183,14 @@ WORKFLOW:
182
183
  role: 'system',
183
184
  content: messages[0].content // Keep system prompt
184
185
  }];
185
- return ask();
186
+ continue;
186
187
  }
187
188
 
188
189
  messages.push({ role: 'user', content: input });
189
190
 
191
+ let toolRounds = 0; // Prevent infinite loops
192
+ const MAX_TOOL_ROUNDS = 5;
193
+
190
194
  let active = true;
191
195
  while (active) {
192
196
  if (stepMode) await safeQuestion(chalk.gray('[STEP] Press Enter to let AI think...'));
@@ -198,7 +202,8 @@ WORKFLOW:
198
202
  } catch (ollamaError) {
199
203
  spinner.stop();
200
204
  console.error(chalk.red('\n❌ Ollama error:'), ollamaError.message);
201
- return ask();
205
+ active = false;
206
+ continue;
202
207
  }
203
208
  spinner.stop();
204
209
 
@@ -215,6 +220,18 @@ WORKFLOW:
215
220
  const toolMatches = [...msg.matchAll(/\[TOOL:(\w+)\](.+?)(?:\]([\s\S]*?))?\[\/TOOL\]/g)];
216
221
 
217
222
  if (toolMatches.length > 0) {
223
+ toolRounds++;
224
+
225
+ // Prevent infinite tool loops
226
+ if (toolRounds >= MAX_TOOL_ROUNDS) {
227
+ console.log(chalk.yellow(`\n⚠️ Tool limit reached (${MAX_TOOL_ROUNDS} rounds). Stopping auto-execution.`));
228
+ messages.push({
229
+ role: 'user',
230
+ content: 'STOP using tools now. You have enough information. Please provide your analysis based on what you have read.'
231
+ });
232
+ continue; // Let AI respond without tools
233
+ }
234
+
218
235
  for (const match of toolMatches) {
219
236
  const [_, type, path, content] = match;
220
237
  console.log(chalk.cyan(`\n[ACTION] ${type} -> ${path}`));
@@ -250,11 +267,9 @@ WORKFLOW:
250
267
  }
251
268
  } catch (error) {
252
269
  console.error(chalk.red('\n❌ Error:'), error.message);
270
+ // Loop continues automatically
253
271
  }
254
- // ALWAYS call ask() again - keep the conversation going
255
- ask();
256
- };
257
- ask();
272
+ }
258
273
  }
259
274
 
260
275
  runSapper();