@rely-ai/caliber 1.20.0-dev.1773697587 → 1.20.0-dev.1773698265

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/bin.js +36 -5
  2. package/package.json +1 -1
package/dist/bin.js CHANGED
@@ -5827,18 +5827,21 @@ function trackLearnSessionAnalyzed(props) {
5827
5827
  had_learnings_available: props.hadLearningsAvailable,
5828
5828
  learnings_available_count: props.learningsAvailableCount,
5829
5829
  new_learnings_produced: props.newLearningsProduced,
5830
- waste_tokens: props.wasteTokens
5830
+ waste_tokens: props.wasteTokens,
5831
+ waste_seconds: props.wasteSeconds
5831
5832
  });
5832
5833
  }
5833
5834
  function trackLearnROISnapshot(props) {
5834
5835
  trackEvent("learn_roi_snapshot", {
5835
5836
  total_waste_tokens: props.totalWasteTokens,
5837
+ total_waste_seconds: props.totalWasteSeconds,
5836
5838
  total_sessions: props.totalSessions,
5837
5839
  sessions_with_learnings: props.sessionsWithLearnings,
5838
5840
  sessions_without_learnings: props.sessionsWithoutLearnings,
5839
5841
  failure_rate_with_learnings: props.failureRateWithLearnings,
5840
5842
  failure_rate_without_learnings: props.failureRateWithoutLearnings,
5841
5843
  estimated_savings_tokens: props.estimatedSavingsTokens,
5844
+ estimated_savings_seconds: props.estimatedSavingsSeconds,
5842
5845
  learning_count: props.learningCount
5843
5846
  });
5844
5847
  }
@@ -9133,20 +9136,28 @@ ${eventsText}`;
9133
9136
  }
9134
9137
  function calculateSessionWaste(events) {
9135
9138
  let totalWasteTokens = 0;
9139
+ let totalWasteSeconds = 0;
9136
9140
  let failureCount = 0;
9137
9141
  let promptCount = 0;
9138
- for (const event of events) {
9142
+ for (let i = 0; i < events.length; i++) {
9143
+ const event = events[i];
9139
9144
  if (event.hook_event_name === "PostToolUseFailure") {
9140
9145
  const te = event;
9141
9146
  const inputStr = JSON.stringify(te.tool_input);
9142
9147
  const responseStr = typeof te.tool_response === "object" && "_truncated" in te.tool_response ? String(te.tool_response._truncated) : JSON.stringify(te.tool_response);
9143
9148
  totalWasteTokens += estimateTokens(inputStr + responseStr);
9144
9149
  failureCount++;
9150
+ if (i > 0) {
9151
+ const prev = new Date(events[i - 1].timestamp).getTime();
9152
+ const curr = new Date(event.timestamp).getTime();
9153
+ const elapsed = (curr - prev) / 1e3;
9154
+ if (elapsed > 0 && elapsed < 600) totalWasteSeconds += elapsed;
9155
+ }
9145
9156
  } else if (event.hook_event_name === "UserPromptSubmit") {
9146
9157
  promptCount++;
9147
9158
  }
9148
9159
  }
9149
- return { totalWasteTokens, failureCount, promptCount };
9160
+ return { totalWasteTokens, totalWasteSeconds, failureCount, promptCount };
9150
9161
  }
9151
9162
 
9152
9163
  // src/commands/learn.ts
@@ -9158,11 +9169,13 @@ import fs32 from "fs";
9158
9169
  import path26 from "path";
9159
9170
  var DEFAULT_TOTALS = {
9160
9171
  totalWasteTokens: 0,
9172
+ totalWasteSeconds: 0,
9161
9173
  totalSessionsWithLearnings: 0,
9162
9174
  totalSessionsWithoutLearnings: 0,
9163
9175
  totalFailuresWithLearnings: 0,
9164
9176
  totalFailuresWithoutLearnings: 0,
9165
9177
  estimatedSavingsTokens: 0,
9178
+ estimatedSavingsSeconds: 0,
9166
9179
  firstSessionTimestamp: "",
9167
9180
  lastSessionTimestamp: ""
9168
9181
  };
@@ -9187,11 +9200,13 @@ function writeROIStats(stats) {
9187
9200
  function recalculateTotals(stats) {
9188
9201
  const totals = stats.totals;
9189
9202
  totals.totalWasteTokens = stats.learnings.reduce((sum, l) => sum + l.wasteTokens, 0);
9203
+ totals.totalWasteSeconds = 0;
9190
9204
  totals.totalSessionsWithLearnings = 0;
9191
9205
  totals.totalSessionsWithoutLearnings = 0;
9192
9206
  totals.totalFailuresWithLearnings = 0;
9193
9207
  totals.totalFailuresWithoutLearnings = 0;
9194
9208
  for (const s of stats.sessions) {
9209
+ totals.totalWasteSeconds += s.wasteSeconds || 0;
9195
9210
  if (s.hadLearningsAvailable) {
9196
9211
  totals.totalSessionsWithLearnings++;
9197
9212
  totals.totalFailuresWithLearnings += s.failureCount;
@@ -9201,6 +9216,7 @@ function recalculateTotals(stats) {
9201
9216
  }
9202
9217
  }
9203
9218
  totals.estimatedSavingsTokens = totals.totalWasteTokens * totals.totalSessionsWithLearnings;
9219
+ totals.estimatedSavingsSeconds = totals.totalWasteSeconds * totals.totalSessionsWithLearnings;
9204
9220
  if (stats.sessions.length > 0) {
9205
9221
  totals.firstSessionTimestamp = stats.sessions[0].timestamp;
9206
9222
  totals.lastSessionTimestamp = stats.sessions[stats.sessions.length - 1].timestamp;
@@ -9224,6 +9240,12 @@ function recordSession(summary, learnings) {
9224
9240
  writeROIStats(stats);
9225
9241
  return stats;
9226
9242
  }
9243
+ function formatDuration(seconds) {
9244
+ if (seconds < 60) return `${Math.round(seconds)}s`;
9245
+ const mins = Math.floor(seconds / 60);
9246
+ const secs = Math.round(seconds % 60);
9247
+ return secs > 0 ? `${mins}m ${secs}s` : `${mins}m`;
9248
+ }
9227
9249
  function formatROISummary(stats) {
9228
9250
  const t = stats.totals;
9229
9251
  const totalSessions = t.totalSessionsWithLearnings + t.totalSessionsWithoutLearnings;
@@ -9232,7 +9254,7 @@ function formatROISummary(stats) {
9232
9254
  lines.push(` Sessions tracked: ${totalSessions}`);
9233
9255
  lines.push(` Sessions with learnings: ${t.totalSessionsWithLearnings}`);
9234
9256
  if (t.totalSessionsWithoutLearnings > 0) {
9235
- const rateWithout = t.totalSessionsWithoutLearnings > 0 ? (t.totalFailuresWithoutLearnings / t.totalSessionsWithoutLearnings).toFixed(1) : "0.0";
9257
+ const rateWithout = (t.totalFailuresWithoutLearnings / t.totalSessionsWithoutLearnings).toFixed(1);
9236
9258
  lines.push(` Failure rate (no learnings): ${rateWithout}/session`);
9237
9259
  }
9238
9260
  if (t.totalSessionsWithLearnings > 0) {
@@ -9245,6 +9267,11 @@ function formatROISummary(stats) {
9245
9267
  if (t.estimatedSavingsTokens > 0) {
9246
9268
  lines.push(` Estimated savings: ~${t.estimatedSavingsTokens.toLocaleString()} tokens`);
9247
9269
  }
9270
+ if (t.estimatedSavingsSeconds > 0) {
9271
+ lines.push(` Time saved: at least ${formatDuration(t.estimatedSavingsSeconds)} (not counting human frustration)`);
9272
+ } else if (t.totalWasteSeconds > 0) {
9273
+ lines.push(` Time wasted on failures: ${formatDuration(t.totalWasteSeconds)} (and counting)`);
9274
+ }
9248
9275
  return lines.join("\n");
9249
9276
  }
9250
9277
 
@@ -9373,6 +9400,7 @@ async function learnFinalizeCommand(options) {
9373
9400
  eventCount: events.length,
9374
9401
  failureCount: waste.failureCount,
9375
9402
  promptCount: waste.promptCount,
9403
+ wasteSeconds: Math.round(waste.totalWasteSeconds),
9376
9404
  hadLearningsAvailable: hadLearnings,
9377
9405
  learningsCount: existingLearnedItems,
9378
9406
  newLearningsProduced
@@ -9385,18 +9413,21 @@ async function learnFinalizeCommand(options) {
9385
9413
  hadLearningsAvailable: hadLearnings,
9386
9414
  learningsAvailableCount: existingLearnedItems,
9387
9415
  newLearningsProduced,
9388
- wasteTokens: waste.totalWasteTokens
9416
+ wasteTokens: waste.totalWasteTokens,
9417
+ wasteSeconds: Math.round(waste.totalWasteSeconds)
9389
9418
  });
9390
9419
  const t = roiStats.totals;
9391
9420
  const totalSessions = t.totalSessionsWithLearnings + t.totalSessionsWithoutLearnings;
9392
9421
  trackLearnROISnapshot({
9393
9422
  totalWasteTokens: t.totalWasteTokens,
9423
+ totalWasteSeconds: t.totalWasteSeconds,
9394
9424
  totalSessions,
9395
9425
  sessionsWithLearnings: t.totalSessionsWithLearnings,
9396
9426
  sessionsWithoutLearnings: t.totalSessionsWithoutLearnings,
9397
9427
  failureRateWithLearnings: t.totalSessionsWithLearnings > 0 ? t.totalFailuresWithLearnings / t.totalSessionsWithLearnings : 0,
9398
9428
  failureRateWithoutLearnings: t.totalSessionsWithoutLearnings > 0 ? t.totalFailuresWithoutLearnings / t.totalSessionsWithoutLearnings : 0,
9399
9429
  estimatedSavingsTokens: t.estimatedSavingsTokens,
9430
+ estimatedSavingsSeconds: t.estimatedSavingsSeconds,
9400
9431
  learningCount: roiStats.learnings.length
9401
9432
  });
9402
9433
  if (t.estimatedSavingsTokens > 0) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rely-ai/caliber",
3
- "version": "1.20.0-dev.1773697587",
3
+ "version": "1.20.0-dev.1773698265",
4
4
  "description": "Analyze your codebase and generate optimized AI agent configs (CLAUDE.md, .cursorrules, skills) — no API key needed",
5
5
  "type": "module",
6
6
  "bin": {