@workermill/agent 0.2.0 → 0.2.2

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/dist/planner.js +46 -6
  2. package/package.json +1 -1
package/dist/planner.js CHANGED
@@ -260,6 +260,9 @@ export async function planTask(task, config) {
260
260
  let currentPrompt = basePrompt;
261
261
  let bestPlan = null;
262
262
  let bestScore = 0;
263
+ // Track critic history across iterations for analytics
264
+ const criticHistory = [];
265
+ let totalFileCapTruncations = 0;
263
266
  for (let iteration = 1; iteration <= MAX_ITERATIONS; iteration++) {
264
267
  const iterLabel = MAX_ITERATIONS > 1 ? ` (attempt ${iteration}/${MAX_ITERATIONS})` : "";
265
268
  if (iteration > 1) {
@@ -299,6 +302,7 @@ export async function planTask(task, config) {
299
302
  // 2c. Apply file cap (max 5 files per story)
300
303
  const { truncatedCount, details } = applyFileCap(plan);
301
304
  if (truncatedCount > 0) {
305
+ totalFileCapTruncations += truncatedCount;
302
306
  const msg = `${PREFIX} File cap applied: ${truncatedCount} stories truncated to max 5 targetFiles`;
303
307
  console.log(`${ts()} ${taskLabel} ${chalk.yellow("⚠")} ${msg}`);
304
308
  await postLog(task.id, msg);
@@ -319,19 +323,38 @@ export async function planTask(task, config) {
319
323
  // Critic failed entirely — use this plan as fallback
320
324
  bestPlan = plan;
321
325
  }
326
+ // Record critic history for this iteration
327
+ if (criticResult) {
328
+ criticHistory.push({
329
+ iteration,
330
+ score: criticResult.score,
331
+ approved: criticResult.approved || criticResult.score >= AUTO_APPROVAL_THRESHOLD,
332
+ risks: criticResult.risks,
333
+ suggestions: criticResult.suggestions,
334
+ filesCapApplied: truncatedCount > 0 ? truncatedCount : undefined,
335
+ });
336
+ }
322
337
  // 2e. Check critic result
323
338
  if (!criticResult) {
324
339
  // Critic failed (timeout, parse error, etc.) — post plan without critic gate
325
340
  const msg = `${PREFIX} Critic validation failed — posting plan without critic score`;
326
341
  console.log(`${ts()} ${taskLabel} ${chalk.yellow("⚠")} ${msg}`);
327
342
  await postLog(task.id, msg);
328
- return await postValidatedPlan(task.id, plan, config.agentId, taskLabel, elapsed);
343
+ const planningDurationMs = Date.now() - startTime;
344
+ return await postValidatedPlan(task.id, plan, config.agentId, taskLabel, elapsed, undefined, undefined, criticHistory, totalFileCapTruncations, planningDurationMs, iteration);
329
345
  }
330
346
  if (criticResult.approved || criticResult.score >= AUTO_APPROVAL_THRESHOLD) {
331
347
  // Approved! Post the file-capped plan
332
348
  const msg = `${PREFIX} Critic approved (score: ${criticResult.score}/100)`;
349
+ console.log(`${ts()} ${taskLabel} ${chalk.green("✓")} ${msg}`);
333
350
  await postLog(task.id, msg);
334
- return await postValidatedPlan(task.id, plan, config.agentId, taskLabel, elapsed);
351
+ if (criticResult.risks.length > 0) {
352
+ const risksMsg = `${PREFIX} Critic risks (non-blocking): ${criticResult.risks.join("; ")}`;
353
+ console.log(`${ts()} ${taskLabel} ${chalk.dim(risksMsg)}`);
354
+ await postLog(task.id, risksMsg);
355
+ }
356
+ const planningDurationMs = Date.now() - startTime;
357
+ return await postValidatedPlan(task.id, plan, config.agentId, taskLabel, elapsed, criticResult.score, criticResult.risks, criticHistory, totalFileCapTruncations, planningDurationMs, iteration);
335
358
  }
336
359
  // 2f. Rejected — append critic feedback for next iteration
337
360
  if (iteration < MAX_ITERATIONS) {
@@ -341,7 +364,14 @@ export async function planTask(task, config) {
341
364
  console.log(`${ts()} ${taskLabel} ${chalk.yellow("⚠")} ${msg}`);
342
365
  await postLog(task.id, msg);
343
366
  if (criticResult.risks.length > 0) {
344
- await postLog(task.id, `${PREFIX} Critic risks: ${criticResult.risks.join("; ")}`);
367
+ const risksMsg = `${PREFIX} Critic risks: ${criticResult.risks.join("; ")}`;
368
+ console.log(`${ts()} ${taskLabel} ${chalk.dim(risksMsg)}`);
369
+ await postLog(task.id, risksMsg);
370
+ }
371
+ if (criticResult.suggestions && criticResult.suggestions.length > 0) {
372
+ const sugMsg = `${PREFIX} Critic suggestions: ${criticResult.suggestions.join("; ")}`;
373
+ console.log(`${ts()} ${taskLabel} ${chalk.dim(sugMsg)}`);
374
+ await postLog(task.id, sugMsg);
345
375
  }
346
376
  }
347
377
  else {
@@ -350,10 +380,14 @@ export async function planTask(task, config) {
350
380
  console.error(`${ts()} ${taskLabel} ${chalk.red("✗")} ${msg}`);
351
381
  await postLog(task.id, msg, "error", "error");
352
382
  if (criticResult.risks.length > 0) {
353
- await postLog(task.id, `${PREFIX} Final risks: ${criticResult.risks.join("; ")}`, "error", "error");
383
+ const risksMsg = `${PREFIX} Final risks: ${criticResult.risks.join("; ")}`;
384
+ console.error(`${ts()} ${taskLabel} ${risksMsg}`);
385
+ await postLog(task.id, risksMsg, "error", "error");
354
386
  }
355
387
  if (criticResult.suggestions && criticResult.suggestions.length > 0) {
356
- await postLog(task.id, `${PREFIX} Suggestions: ${criticResult.suggestions.join("; ")}`, "error", "error");
388
+ const sugMsg = `${PREFIX} Suggestions: ${criticResult.suggestions.join("; ")}`;
389
+ console.error(`${ts()} ${taskLabel} ${sugMsg}`);
390
+ await postLog(task.id, sugMsg, "error", "error");
357
391
  }
358
392
  }
359
393
  }
@@ -365,13 +399,19 @@ export async function planTask(task, config) {
365
399
  * Re-serializes the plan as a JSON code block since the server-side
366
400
  * parseExecutionPlan() expects that format.
367
401
  */
368
- async function postValidatedPlan(taskId, plan, agentId, taskLabel, elapsed) {
402
+ async function postValidatedPlan(taskId, plan, agentId, taskLabel, elapsed, criticScore, criticRisks, criticHistory, fileCapTruncations, planningDurationMs, criticIterations) {
369
403
  const serialized = serializePlan(plan);
370
404
  try {
371
405
  const result = await api.post("/api/agent/plan-result", {
372
406
  taskId,
373
407
  rawOutput: serialized,
374
408
  agentId,
409
+ criticScore,
410
+ criticRisks,
411
+ criticHistory,
412
+ criticIterations,
413
+ fileCapTruncations,
414
+ planningDurationMs,
375
415
  });
376
416
  const storyCount = result.data.storyCount;
377
417
  console.log(`${ts()} ${taskLabel} ${chalk.green("✓")} Plan validated: ${chalk.bold(storyCount)} stories → ${chalk.green("queued")}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@workermill/agent",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "description": "WorkerMill Remote Agent - Run AI workers locally with your Claude Max subscription",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",