sapper-iq 1.0.22 → 1.0.23

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 +20 -5
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sapper-iq",
3
- "version": "1.0.22",
3
+ "version": "1.0.23",
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
@@ -182,11 +182,14 @@ WORKFLOW:
182
182
  role: 'system',
183
183
  content: messages[0].content // Keep system prompt
184
184
  }];
185
- return ask();
185
+ return await ask();
186
186
  }
187
187
 
188
188
  messages.push({ role: 'user', content: input });
189
189
 
190
+ let toolRounds = 0; // Prevent infinite loops
191
+ const MAX_TOOL_ROUNDS = 5;
192
+
190
193
  let active = true;
191
194
  while (active) {
192
195
  if (stepMode) await safeQuestion(chalk.gray('[STEP] Press Enter to let AI think...'));
@@ -198,7 +201,7 @@ WORKFLOW:
198
201
  } catch (ollamaError) {
199
202
  spinner.stop();
200
203
  console.error(chalk.red('\n❌ Ollama error:'), ollamaError.message);
201
- return ask();
204
+ return await ask();
202
205
  }
203
206
  spinner.stop();
204
207
 
@@ -215,6 +218,18 @@ WORKFLOW:
215
218
  const toolMatches = [...msg.matchAll(/\[TOOL:(\w+)\](.+?)(?:\]([\s\S]*?))?\[\/TOOL\]/g)];
216
219
 
217
220
  if (toolMatches.length > 0) {
221
+ toolRounds++;
222
+
223
+ // Prevent infinite tool loops
224
+ if (toolRounds >= MAX_TOOL_ROUNDS) {
225
+ console.log(chalk.yellow(`\n⚠️ Tool limit reached (${MAX_TOOL_ROUNDS} rounds). Stopping auto-execution.`));
226
+ messages.push({
227
+ role: 'user',
228
+ content: 'STOP using tools now. You have enough information. Please provide your analysis based on what you have read.'
229
+ });
230
+ continue; // Let AI respond without tools
231
+ }
232
+
218
233
  for (const match of toolMatches) {
219
234
  const [_, type, path, content] = match;
220
235
  console.log(chalk.cyan(`\n[ACTION] ${type} -> ${path}`));
@@ -251,10 +266,10 @@ WORKFLOW:
251
266
  } catch (error) {
252
267
  console.error(chalk.red('\n❌ Error:'), error.message);
253
268
  }
254
- // ALWAYS call ask() again - keep the conversation going
255
- ask();
269
+ // ALWAYS call ask() again with await - keep the conversation going
270
+ await ask();
256
271
  };
257
- ask();
272
+ await ask();
258
273
  }
259
274
 
260
275
  runSapper();