agent-clinch 0.7.6 → 0.7.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/cli.js +35 -16
  2. package/package.json +1 -1
package/cli.js CHANGED
@@ -205,6 +205,7 @@ function downloadFile(url, dest) {
205
205
  async function promptAI(systemPrompt, userText, cfg) {
206
206
  if (cfg.engine === 'ollama') {
207
207
  try {
208
+ console.log(c.dim(`\n[Agent Q] Dispatching request to local Ollama (${cfg.ollamaModel || 'llama3'})...`));
208
209
  const res = await fetch('http://127.0.0.1:11434/api/chat', {
209
210
  method: 'POST',
210
211
  headers: { 'Content-Type': 'application/json' },
@@ -233,6 +234,8 @@ async function promptAI(systemPrompt, userText, cfg) {
233
234
  await downloadFile(cfg.ggufUrl || "https://huggingface.co/Qwen/Qwen2.5-1.5B-Instruct-GGUF/resolve/main/qwen2.5-1.5b-instruct-q4_k_m.gguf", resolvedPath);
234
235
  }
235
236
 
237
+ console.log(c.dim(`\n[Agent Q] Loading GGUF model into memory (this may take a few seconds)...`));
238
+
236
239
  let nodeLlama;
237
240
  try { nodeLlama = await import('node-llama-cpp'); }
238
241
  catch (e) {
@@ -250,6 +253,8 @@ async function promptAI(systemPrompt, userText, cfg) {
250
253
  chatWrapper: new nodeLlama.ChatMLChatWrapper()
251
254
  });
252
255
 
256
+ console.log(c.dim(`[Agent Q] Model loaded. Analyzing intent...`));
257
+
253
258
  let responseText = "";
254
259
  await session.prompt(userText, { maxTokens: 1500, onTextChunk: (chunk) => { responseText += chunk; } });
255
260
  return responseText;
@@ -257,24 +262,42 @@ async function promptAI(systemPrompt, userText, cfg) {
257
262
  }
258
263
 
259
264
  async function parseIntentWithLLM(userInput, cfg) {
260
- console.log(c.dim(`\n[Agent Q] Booting local parser (${cfg.engine}) to analyze your request...`));
261
- const systemPrompt = `You are a structured data extractor. Convert the user's conversational intent into a strict JSON schema.
262
- Your response MUST be ONLY valid JSON matching this schema exactly. Do not output conversational text.
265
+ const systemPrompt = `You are a structured data extractor for a purchasing agent.
266
+ Analyze the user's input.
267
+
268
+ If the user says a greeting (like "hi" or "hello") or does not clearly specify BOTH an item and a budget, output EXACTLY this JSON:
269
+ {"error": "Please specify what you want to buy and your maximum budget (e.g. 'Get me a laptop for under $500')."}
263
270
 
264
- JSON Schema:
271
+ If they DO specify a purchase intent, output EXACTLY this JSON schema:
265
272
  {
266
273
  "intent": "purchase",
267
- "category": "string (e.g. domain_name, electronics, kitchen_appliance)",
268
- "item": "string (the exact item, website, or product they want)",
269
- "max_budget": number (extract budget numeric value)
270
- }`;
274
+ "category": "string (e.g. electronics, domain_names, software, etc)",
275
+ "item": "string (the actual item requested)",
276
+ "max_budget": number (integer representing the max budget)
277
+ }
278
+ Your response MUST be ONLY valid JSON. Do not include conversational text.`;
271
279
 
272
280
  try {
273
281
  const rawRes = await promptAI(systemPrompt, userInput, cfg);
274
282
  const cleanJson = rawRes.replace(/```json|```/g, "").trim();
275
- return JSON.parse(cleanJson);
283
+
284
+ const parsed = JSON.parse(cleanJson);
285
+
286
+ // Check if the LLM flagged the input as a greeting/unclear
287
+ if (parsed.error) {
288
+ console.log(c.yellow(`\n[Agent Q] ${parsed.error}`));
289
+ return null;
290
+ }
291
+
292
+ // Fallback validation to ensure it didn't hallucinate missing fields
293
+ if (!parsed.item || !parsed.max_budget) {
294
+ console.log(c.yellow(`\n[Agent Q] I couldn't quite figure out the item or budget from your request. Please be specific!`));
295
+ return null;
296
+ }
297
+
298
+ return parsed;
276
299
  } catch (e) {
277
- console.error(c.red("Failed to parse intent. Falling back to manual entry."));
300
+ console.error(c.red("\n[Agent Q] Failed to parse intent correctly. Falling back to manual entry."));
278
301
  return null;
279
302
  }
280
303
  }
@@ -408,7 +431,7 @@ program
408
431
 
409
432
  const parsed = await parseIntentWithLLM(naturalIntent, cfg);
410
433
  if (!parsed) {
411
- console.error(c.red("✗ Error parsing constraints. Please try manual entry."));
434
+ // We failed to parse correctly (or the user typed hi), gracefully exit rather than crashing
412
435
  process.exit(1);
413
436
  }
414
437
 
@@ -423,7 +446,7 @@ program
423
446
  constraints = parsed;
424
447
  budget = parsed.max_budget;
425
448
 
426
- console.log(c.dim(`\nQuerying registry for category "${parsed.category}"...`));
449
+ console.log(c.dim(`\n[Network] Querying registry for category "${parsed.category}"...`));
427
450
  const coreDiscovery = getClinchCore(cfg);
428
451
  await coreDiscovery.initialize(cfg.token);
429
452
  const results = await coreDiscovery.search(parsed.category);
@@ -483,10 +506,7 @@ program
483
506
  return;
484
507
  }
485
508
 
486
- // Ask the core to build the context prompt, but evaluate it HERE in the CLI
487
509
  const promptStr = core.buildAgentPrompt(sessionId, incomingMessage);
488
- console.log(c.dim(`\n[Agent Q] Evaluating turn ${session.currentTurn} with ${cfg.engine}...`));
489
-
490
510
  const aiResponse = await promptAI(promptStr, incomingMessage, cfg);
491
511
 
492
512
  let price = null;
@@ -635,7 +655,6 @@ program
635
655
  console.log(c.yellow(`\nRehydrating Session ${c.bold(sessionId)}...\n`));
636
656
  if (opts.auto) {
637
657
  cfg = await ensureAIEngine(cfg);
638
- // ... hook auto logic here if needed (omitted for brevity, handled heavily in negotiate)
639
658
  }
640
659
 
641
660
  const core = getClinchCore(cfg);
package/package.json CHANGED
@@ -6,7 +6,7 @@
6
6
 
7
7
 
8
8
  "name": "agent-clinch",
9
- "version": "0.7.6",
9
+ "version": "0.7.7",
10
10
  "description": "Clinch Protocol CLI — agent negotiation from your terminal",
11
11
  "main": "cli.js",
12
12
  "bin": {