@rely-ai/caliber 1.20.0-dev.1773696964 → 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.
- package/dist/bin.js +74 -33
- 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
|
}
|
|
@@ -6535,7 +6538,7 @@ function validateSetup(setup, dir, checkExists = existsSync9) {
|
|
|
6535
6538
|
}
|
|
6536
6539
|
function buildFeedbackMessage(issues) {
|
|
6537
6540
|
const lines = [
|
|
6538
|
-
"
|
|
6541
|
+
"Fix ONLY these scoring issues \u2014 do not rewrite, restructure, or make cosmetic changes:\n"
|
|
6539
6542
|
];
|
|
6540
6543
|
for (let i = 0; i < issues.length; i++) {
|
|
6541
6544
|
const issue = issues[i];
|
|
@@ -6543,7 +6546,6 @@ function buildFeedbackMessage(issues) {
|
|
|
6543
6546
|
lines.push(` Action: ${issue.fixInstruction}
|
|
6544
6547
|
`);
|
|
6545
6548
|
}
|
|
6546
|
-
lines.push("Return the complete updated AgentSetup JSON with only these fixes applied.");
|
|
6547
6549
|
return lines.join("\n");
|
|
6548
6550
|
}
|
|
6549
6551
|
function countIssuePoints(issues) {
|
|
@@ -6576,12 +6578,20 @@ async function scoreAndRefine(setup, dir, sessionHistory, callbacks) {
|
|
|
6576
6578
|
const issueNames = issues.map((i) => i.check).join(", ");
|
|
6577
6579
|
callbacks.onStatus(`Fixing ${issues.length} scoring issue${issues.length === 1 ? "" : "s"}: ${issueNames}...`);
|
|
6578
6580
|
}
|
|
6579
|
-
const
|
|
6580
|
-
if (!
|
|
6581
|
+
const refined = await applyTargetedFixes(currentSetup, issues);
|
|
6582
|
+
if (!refined) {
|
|
6581
6583
|
if (callbacks?.onStatus) callbacks.onStatus("Refinement failed, keeping current setup");
|
|
6582
6584
|
return bestSetup;
|
|
6583
6585
|
}
|
|
6584
|
-
|
|
6586
|
+
sessionHistory.push({
|
|
6587
|
+
role: "user",
|
|
6588
|
+
content: `Fix scoring issues: ${issues.map((i) => i.check).join(", ")}`
|
|
6589
|
+
});
|
|
6590
|
+
sessionHistory.push({
|
|
6591
|
+
role: "assistant",
|
|
6592
|
+
content: `Applied scoring fixes for: ${issues.map((i) => i.check).join(", ")}`
|
|
6593
|
+
});
|
|
6594
|
+
currentSetup = refined;
|
|
6585
6595
|
}
|
|
6586
6596
|
const finalIssues = validateSetup(currentSetup, dir, cachedExists);
|
|
6587
6597
|
const finalLostPoints = countIssuePoints(finalIssues);
|
|
@@ -6590,41 +6600,44 @@ async function scoreAndRefine(setup, dir, sessionHistory, callbacks) {
|
|
|
6590
6600
|
}
|
|
6591
6601
|
return bestSetup;
|
|
6592
6602
|
}
|
|
6593
|
-
async function applyTargetedFixes(setup, issues
|
|
6603
|
+
async function applyTargetedFixes(setup, issues) {
|
|
6594
6604
|
const { claudeMd, agentsMd } = extractConfigContent(setup);
|
|
6595
|
-
const
|
|
6596
|
-
if (
|
|
6605
|
+
const targets = [];
|
|
6606
|
+
if (claudeMd) targets.push({ key: "claudeMd", label: "CLAUDE.md", content: claudeMd });
|
|
6607
|
+
if (agentsMd) targets.push({ key: "agentsMd", label: "AGENTS.md", content: agentsMd });
|
|
6608
|
+
if (targets.length === 0) return null;
|
|
6597
6609
|
const feedbackMessage = buildFeedbackMessage(issues);
|
|
6598
|
-
const
|
|
6610
|
+
const contentBlock = targets.map(
|
|
6611
|
+
(t) => `### ${t.label}
|
|
6612
|
+
\`\`\`markdown
|
|
6613
|
+
${t.content}
|
|
6614
|
+
\`\`\``
|
|
6615
|
+
).join("\n\n");
|
|
6599
6616
|
const prompt = [
|
|
6600
|
-
|
|
6601
|
-
|
|
6602
|
-
"
|
|
6603
|
-
content,
|
|
6604
|
-
"```\n",
|
|
6617
|
+
"Here are the config files with scoring issues:\n",
|
|
6618
|
+
contentBlock,
|
|
6619
|
+
"\n",
|
|
6605
6620
|
feedbackMessage,
|
|
6606
6621
|
`
|
|
6607
|
-
Return ONLY the fixed
|
|
6622
|
+
Return ONLY the fixed content as a JSON object with keys ${targets.map((t) => `"${t.key}"`).join(", ")}. Each value is the fixed markdown string. No code fences, no explanations.`
|
|
6608
6623
|
].join("\n");
|
|
6609
6624
|
try {
|
|
6610
6625
|
const raw = await llmCall({
|
|
6611
|
-
system:
|
|
6626
|
+
system: "You fix scoring issues in AI agent configuration files. Return only a JSON object with the fixed content \u2014 no explanations, no code fences.",
|
|
6612
6627
|
prompt,
|
|
6613
6628
|
maxTokens: 8e3
|
|
6614
6629
|
});
|
|
6615
|
-
const
|
|
6616
|
-
|
|
6617
|
-
const
|
|
6618
|
-
|
|
6619
|
-
|
|
6620
|
-
|
|
6621
|
-
|
|
6630
|
+
const cleaned = stripMarkdownFences(raw);
|
|
6631
|
+
const jsonStart = cleaned.indexOf("{");
|
|
6632
|
+
const jsonToParse = jsonStart !== -1 ? cleaned.slice(jsonStart) : cleaned;
|
|
6633
|
+
const fixes = JSON.parse(jsonToParse);
|
|
6634
|
+
const patched = structuredClone(setup);
|
|
6635
|
+
for (const target of targets) {
|
|
6636
|
+
if (typeof fixes[target.key] === "string" && fixes[target.key].length > 50) {
|
|
6637
|
+
const parent = target.key === "claudeMd" ? patched.claude : patched.codex;
|
|
6638
|
+
if (parent) parent[target.key] = fixes[target.key];
|
|
6639
|
+
}
|
|
6622
6640
|
}
|
|
6623
|
-
sessionHistory.push({ role: "user", content: feedbackMessage });
|
|
6624
|
-
sessionHistory.push({
|
|
6625
|
-
role: "assistant",
|
|
6626
|
-
content: `Applied scoring fixes for: ${issues.map((i) => i.check).join(", ")}`
|
|
6627
|
-
});
|
|
6628
6641
|
return patched;
|
|
6629
6642
|
} catch {
|
|
6630
6643
|
return null;
|
|
@@ -9123,20 +9136,28 @@ ${eventsText}`;
|
|
|
9123
9136
|
}
|
|
9124
9137
|
function calculateSessionWaste(events) {
|
|
9125
9138
|
let totalWasteTokens = 0;
|
|
9139
|
+
let totalWasteSeconds = 0;
|
|
9126
9140
|
let failureCount = 0;
|
|
9127
9141
|
let promptCount = 0;
|
|
9128
|
-
for (
|
|
9142
|
+
for (let i = 0; i < events.length; i++) {
|
|
9143
|
+
const event = events[i];
|
|
9129
9144
|
if (event.hook_event_name === "PostToolUseFailure") {
|
|
9130
9145
|
const te = event;
|
|
9131
9146
|
const inputStr = JSON.stringify(te.tool_input);
|
|
9132
9147
|
const responseStr = typeof te.tool_response === "object" && "_truncated" in te.tool_response ? String(te.tool_response._truncated) : JSON.stringify(te.tool_response);
|
|
9133
9148
|
totalWasteTokens += estimateTokens(inputStr + responseStr);
|
|
9134
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
|
+
}
|
|
9135
9156
|
} else if (event.hook_event_name === "UserPromptSubmit") {
|
|
9136
9157
|
promptCount++;
|
|
9137
9158
|
}
|
|
9138
9159
|
}
|
|
9139
|
-
return { totalWasteTokens, failureCount, promptCount };
|
|
9160
|
+
return { totalWasteTokens, totalWasteSeconds, failureCount, promptCount };
|
|
9140
9161
|
}
|
|
9141
9162
|
|
|
9142
9163
|
// src/commands/learn.ts
|
|
@@ -9148,11 +9169,13 @@ import fs32 from "fs";
|
|
|
9148
9169
|
import path26 from "path";
|
|
9149
9170
|
var DEFAULT_TOTALS = {
|
|
9150
9171
|
totalWasteTokens: 0,
|
|
9172
|
+
totalWasteSeconds: 0,
|
|
9151
9173
|
totalSessionsWithLearnings: 0,
|
|
9152
9174
|
totalSessionsWithoutLearnings: 0,
|
|
9153
9175
|
totalFailuresWithLearnings: 0,
|
|
9154
9176
|
totalFailuresWithoutLearnings: 0,
|
|
9155
9177
|
estimatedSavingsTokens: 0,
|
|
9178
|
+
estimatedSavingsSeconds: 0,
|
|
9156
9179
|
firstSessionTimestamp: "",
|
|
9157
9180
|
lastSessionTimestamp: ""
|
|
9158
9181
|
};
|
|
@@ -9177,11 +9200,13 @@ function writeROIStats(stats) {
|
|
|
9177
9200
|
function recalculateTotals(stats) {
|
|
9178
9201
|
const totals = stats.totals;
|
|
9179
9202
|
totals.totalWasteTokens = stats.learnings.reduce((sum, l) => sum + l.wasteTokens, 0);
|
|
9203
|
+
totals.totalWasteSeconds = 0;
|
|
9180
9204
|
totals.totalSessionsWithLearnings = 0;
|
|
9181
9205
|
totals.totalSessionsWithoutLearnings = 0;
|
|
9182
9206
|
totals.totalFailuresWithLearnings = 0;
|
|
9183
9207
|
totals.totalFailuresWithoutLearnings = 0;
|
|
9184
9208
|
for (const s of stats.sessions) {
|
|
9209
|
+
totals.totalWasteSeconds += s.wasteSeconds || 0;
|
|
9185
9210
|
if (s.hadLearningsAvailable) {
|
|
9186
9211
|
totals.totalSessionsWithLearnings++;
|
|
9187
9212
|
totals.totalFailuresWithLearnings += s.failureCount;
|
|
@@ -9191,6 +9216,7 @@ function recalculateTotals(stats) {
|
|
|
9191
9216
|
}
|
|
9192
9217
|
}
|
|
9193
9218
|
totals.estimatedSavingsTokens = totals.totalWasteTokens * totals.totalSessionsWithLearnings;
|
|
9219
|
+
totals.estimatedSavingsSeconds = totals.totalWasteSeconds * totals.totalSessionsWithLearnings;
|
|
9194
9220
|
if (stats.sessions.length > 0) {
|
|
9195
9221
|
totals.firstSessionTimestamp = stats.sessions[0].timestamp;
|
|
9196
9222
|
totals.lastSessionTimestamp = stats.sessions[stats.sessions.length - 1].timestamp;
|
|
@@ -9214,6 +9240,12 @@ function recordSession(summary, learnings) {
|
|
|
9214
9240
|
writeROIStats(stats);
|
|
9215
9241
|
return stats;
|
|
9216
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
|
+
}
|
|
9217
9249
|
function formatROISummary(stats) {
|
|
9218
9250
|
const t = stats.totals;
|
|
9219
9251
|
const totalSessions = t.totalSessionsWithLearnings + t.totalSessionsWithoutLearnings;
|
|
@@ -9222,7 +9254,7 @@ function formatROISummary(stats) {
|
|
|
9222
9254
|
lines.push(` Sessions tracked: ${totalSessions}`);
|
|
9223
9255
|
lines.push(` Sessions with learnings: ${t.totalSessionsWithLearnings}`);
|
|
9224
9256
|
if (t.totalSessionsWithoutLearnings > 0) {
|
|
9225
|
-
const rateWithout =
|
|
9257
|
+
const rateWithout = (t.totalFailuresWithoutLearnings / t.totalSessionsWithoutLearnings).toFixed(1);
|
|
9226
9258
|
lines.push(` Failure rate (no learnings): ${rateWithout}/session`);
|
|
9227
9259
|
}
|
|
9228
9260
|
if (t.totalSessionsWithLearnings > 0) {
|
|
@@ -9235,6 +9267,11 @@ function formatROISummary(stats) {
|
|
|
9235
9267
|
if (t.estimatedSavingsTokens > 0) {
|
|
9236
9268
|
lines.push(` Estimated savings: ~${t.estimatedSavingsTokens.toLocaleString()} tokens`);
|
|
9237
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
|
+
}
|
|
9238
9275
|
return lines.join("\n");
|
|
9239
9276
|
}
|
|
9240
9277
|
|
|
@@ -9363,6 +9400,7 @@ async function learnFinalizeCommand(options) {
|
|
|
9363
9400
|
eventCount: events.length,
|
|
9364
9401
|
failureCount: waste.failureCount,
|
|
9365
9402
|
promptCount: waste.promptCount,
|
|
9403
|
+
wasteSeconds: Math.round(waste.totalWasteSeconds),
|
|
9366
9404
|
hadLearningsAvailable: hadLearnings,
|
|
9367
9405
|
learningsCount: existingLearnedItems,
|
|
9368
9406
|
newLearningsProduced
|
|
@@ -9375,18 +9413,21 @@ async function learnFinalizeCommand(options) {
|
|
|
9375
9413
|
hadLearningsAvailable: hadLearnings,
|
|
9376
9414
|
learningsAvailableCount: existingLearnedItems,
|
|
9377
9415
|
newLearningsProduced,
|
|
9378
|
-
wasteTokens: waste.totalWasteTokens
|
|
9416
|
+
wasteTokens: waste.totalWasteTokens,
|
|
9417
|
+
wasteSeconds: Math.round(waste.totalWasteSeconds)
|
|
9379
9418
|
});
|
|
9380
9419
|
const t = roiStats.totals;
|
|
9381
9420
|
const totalSessions = t.totalSessionsWithLearnings + t.totalSessionsWithoutLearnings;
|
|
9382
9421
|
trackLearnROISnapshot({
|
|
9383
9422
|
totalWasteTokens: t.totalWasteTokens,
|
|
9423
|
+
totalWasteSeconds: t.totalWasteSeconds,
|
|
9384
9424
|
totalSessions,
|
|
9385
9425
|
sessionsWithLearnings: t.totalSessionsWithLearnings,
|
|
9386
9426
|
sessionsWithoutLearnings: t.totalSessionsWithoutLearnings,
|
|
9387
9427
|
failureRateWithLearnings: t.totalSessionsWithLearnings > 0 ? t.totalFailuresWithLearnings / t.totalSessionsWithLearnings : 0,
|
|
9388
9428
|
failureRateWithoutLearnings: t.totalSessionsWithoutLearnings > 0 ? t.totalFailuresWithoutLearnings / t.totalSessionsWithoutLearnings : 0,
|
|
9389
9429
|
estimatedSavingsTokens: t.estimatedSavingsTokens,
|
|
9430
|
+
estimatedSavingsSeconds: t.estimatedSavingsSeconds,
|
|
9390
9431
|
learningCount: roiStats.learnings.length
|
|
9391
9432
|
});
|
|
9392
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.
|
|
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": {
|