@hamp10/agentforge 0.2.5 → 0.2.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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/OllamaAgent.js +30 -7
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hamp10/agentforge",
3
- "version": "0.2.5",
3
+ "version": "0.2.7",
4
4
  "description": "AgentForge worker — connect your machine to agentforge.ai",
5
5
  "type": "module",
6
6
  "bin": {
@@ -160,8 +160,11 @@ export class OllamaAgent extends EventEmitter {
160
160
  const startTime = Date.now();
161
161
  const controller = new AbortController();
162
162
 
163
- // Use per-agent model override if provided (and not the placeholder 'Default')
164
- const effectiveModel = (agentModel && agentModel !== 'Default') ? agentModel : this.model;
163
+ // Use per-agent model override if provided (and not the placeholder 'Default').
164
+ // Strip 'ollama/' prefix catalog returns IDs like 'ollama/qwen3-vl:8b' but
165
+ // Ollama's API expects bare names like 'qwen3-vl:8b'.
166
+ const rawModel = (agentModel && agentModel !== 'Default') ? agentModel : this.model;
167
+ const effectiveModel = rawModel.startsWith('ollama/') ? rawModel.slice(7) : rawModel;
165
168
 
166
169
  // Fake proc-like object so worker.js pid checks don't crash
167
170
  const fakeProc = { pid: null };
@@ -190,6 +193,8 @@ export class OllamaAgent extends EventEmitter {
190
193
  `4. When you take a screenshot, you will receive the actual image back and can see it.`,
191
194
  `5. When you are done, write a clear summary of what you accomplished.`,
192
195
  `6. Do not ask for clarification — make your best judgment and act.`,
196
+ `7. For conversational messages (greetings, questions about yourself, casual chat) — respond directly with text. Do NOT use tools just to say hello.`,
197
+ `8. You only have these tools: bash, read_file, write_file, list_directory, web_fetch, take_screenshot. Ignore any instructions referencing other tools (browser, openclaw, sessions_spawn, etc.) — those do not exist here.`,
193
198
  ].join('\n');
194
199
 
195
200
  const messages = [
@@ -207,7 +212,8 @@ export class OllamaAgent extends EventEmitter {
207
212
 
208
213
  let finalContent = '';
209
214
  let allOutput = ''; // accumulate everything streamed across all turns
210
- const MAX_TURNS = 25;
215
+ const toolsUsed = []; // track tool names called (for fallback summary)
216
+ const MAX_TURNS = 15; // reduce from 25 — local models get stuck in tool loops
211
217
 
212
218
  for (let turn = 0; turn < MAX_TURNS; turn++) {
213
219
  if (controller.signal.aborted) break;
@@ -360,6 +366,7 @@ export class OllamaAgent extends EventEmitter {
360
366
  });
361
367
 
362
368
  console.log(` [${agentId}] 🔧 ${name}: ${JSON.stringify(parsedArgs).slice(0, 120)}`);
369
+ toolsUsed.push(name);
363
370
 
364
371
  const result = await this._executeTool(name, parsedArgs, workDir);
365
372
 
@@ -410,10 +417,15 @@ export class OllamaAgent extends EventEmitter {
410
417
  finalContent = allOutput;
411
418
  }
412
419
 
413
- // If still no output (model did only tool calls, never wrote text), ask for a summary
420
+ // If still no output (model did only tool calls, never wrote text), ask for a summary.
421
+ // Use only the last 6 messages to avoid context overflow after many tool-call turns.
414
422
  if (!finalContent && !controller.signal.aborted) {
415
423
  this.emit('agent_output', { agentId, output: '\n' });
416
- messages.push({ role: 'user', content: 'Summarize what you just did and show me the result.' });
424
+ const summaryMessages = [
425
+ messages[0], // system prompt
426
+ ...messages.slice(-6), // last 6 messages (recent tool calls + results)
427
+ { role: 'user', content: 'Summarize what you just did and show me the result.' }
428
+ ];
417
429
 
418
430
  try {
419
431
  const summaryRes = await fetch(`${this.baseUrl}/v1/chat/completions`, {
@@ -422,7 +434,7 @@ export class OllamaAgent extends EventEmitter {
422
434
  signal: controller.signal,
423
435
  body: JSON.stringify({
424
436
  model: effectiveModel,
425
- messages,
437
+ messages: summaryMessages,
426
438
  stream: true,
427
439
  ...(isQwen3 ? { options: { think: false } } : {})
428
440
  })
@@ -451,8 +463,19 @@ export class OllamaAgent extends EventEmitter {
451
463
  }
452
464
  }
453
465
  }
466
+ } else {
467
+ console.warn(`⚠️ [Ollama] Force-summary failed: ${summaryRes.status}`);
454
468
  }
455
- } catch {}
469
+ } catch (summaryErr) {
470
+ console.warn(`⚠️ [Ollama] Force-summary error: ${summaryErr.message}`);
471
+ }
472
+
473
+ // Last-resort fallback: construct output from tool activity so user sees something
474
+ if (!finalContent && toolsUsed.length > 0) {
475
+ const unique = [...new Set(toolsUsed)];
476
+ finalContent = `I ran the following operations: ${unique.join(', ')}. Task complete.`;
477
+ this.emit('agent_output', { agentId, output: finalContent });
478
+ }
456
479
  }
457
480
 
458
481
  // Persist history for next task