@rely-ai/caliber 1.40.3 → 1.41.0
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 +164 -8
- package/package.json +1 -1
package/dist/bin.js
CHANGED
|
@@ -4945,6 +4945,37 @@ var CORE_MAX_TOKENS = 16e3;
|
|
|
4945
4945
|
var GENERATION_MAX_TOKENS = 64e3;
|
|
4946
4946
|
var MODEL_MAX_OUTPUT_TOKENS = 128e3;
|
|
4947
4947
|
var MAX_RETRIES2 = 5;
|
|
4948
|
+
var DEFAULT_INACTIVITY_TIMEOUT_MS = 12e4;
|
|
4949
|
+
var DEFAULT_TOTAL_TIMEOUT_MS = 6e5;
|
|
4950
|
+
function parseEnvTimeout(envVar, defaultMs, minMs = 5e3) {
|
|
4951
|
+
const val = process.env[envVar];
|
|
4952
|
+
if (!val) return defaultMs;
|
|
4953
|
+
const parsed = parseInt(val, 10);
|
|
4954
|
+
if (!Number.isFinite(parsed) || parsed < minMs) return defaultMs;
|
|
4955
|
+
return parsed;
|
|
4956
|
+
}
|
|
4957
|
+
function buildDiagnostic(stopReason, raw, charsReceived) {
|
|
4958
|
+
if (stopReason === "timeout_inactivity") {
|
|
4959
|
+
const timeoutSec = Math.round(
|
|
4960
|
+
parseEnvTimeout("CALIBER_STREAM_INACTIVITY_TIMEOUT_MS", DEFAULT_INACTIVITY_TIMEOUT_MS) / 1e3
|
|
4961
|
+
);
|
|
4962
|
+
if (charsReceived === 0) {
|
|
4963
|
+
return `Model produced no output for ${timeoutSec}s. Check your API key and model name, or increase timeout with CALIBER_STREAM_INACTIVITY_TIMEOUT_MS.`;
|
|
4964
|
+
}
|
|
4965
|
+
return `Model stopped responding for ${timeoutSec}s after producing ${charsReceived} chars. The model may be stuck. Try a different model or increase timeout with CALIBER_STREAM_INACTIVITY_TIMEOUT_MS.`;
|
|
4966
|
+
}
|
|
4967
|
+
if (stopReason === "timeout_total") {
|
|
4968
|
+
const timeoutSec = Math.round(
|
|
4969
|
+
parseEnvTimeout("CALIBER_GENERATION_TIMEOUT_MS", DEFAULT_TOTAL_TIMEOUT_MS) / 1e3
|
|
4970
|
+
);
|
|
4971
|
+
return `Generation exceeded ${timeoutSec}s total time limit. Try a different model or increase timeout with CALIBER_GENERATION_TIMEOUT_MS.`;
|
|
4972
|
+
}
|
|
4973
|
+
if (!raw || raw.trim().length === 0) {
|
|
4974
|
+
return "Model produced no output. Check your API key and model name.";
|
|
4975
|
+
}
|
|
4976
|
+
return `Model responded but output was not valid JSON. First 200 chars:
|
|
4977
|
+
${raw.slice(0, 200)}`;
|
|
4978
|
+
}
|
|
4948
4979
|
function isTransientError2(error) {
|
|
4949
4980
|
const msg = error.message.toLowerCase();
|
|
4950
4981
|
return TRANSIENT_ERRORS.some((e) => msg.includes(e.toLowerCase()));
|
|
@@ -5126,18 +5157,59 @@ Generate the skill content following the instructions in the system prompt.`;
|
|
|
5126
5157
|
async function streamGeneration(config) {
|
|
5127
5158
|
const provider = getProvider();
|
|
5128
5159
|
let attempt = 0;
|
|
5160
|
+
const inactivityTimeoutMs = parseEnvTimeout(
|
|
5161
|
+
"CALIBER_STREAM_INACTIVITY_TIMEOUT_MS",
|
|
5162
|
+
DEFAULT_INACTIVITY_TIMEOUT_MS
|
|
5163
|
+
);
|
|
5164
|
+
const totalTimeoutMs = parseEnvTimeout("CALIBER_GENERATION_TIMEOUT_MS", DEFAULT_TOTAL_TIMEOUT_MS);
|
|
5165
|
+
let totalTimedOut = false;
|
|
5166
|
+
let totalResolve = null;
|
|
5167
|
+
const totalTimer = setTimeout(() => {
|
|
5168
|
+
totalTimedOut = true;
|
|
5169
|
+
if (config.callbacks) config.callbacks.onError(buildDiagnostic("timeout_total", "", 0));
|
|
5170
|
+
if (totalResolve) {
|
|
5171
|
+
totalResolve({ setup: null, raw: "", stopReason: "timeout_total" });
|
|
5172
|
+
totalResolve = null;
|
|
5173
|
+
}
|
|
5174
|
+
}, totalTimeoutMs);
|
|
5129
5175
|
const attemptGeneration = async () => {
|
|
5176
|
+
if (totalTimedOut) {
|
|
5177
|
+
return { setup: null, raw: "", stopReason: "timeout_total" };
|
|
5178
|
+
}
|
|
5130
5179
|
attempt++;
|
|
5131
5180
|
const maxTokensForAttempt = Math.min(
|
|
5132
5181
|
config.baseMaxTokens + attempt * config.tokenIncrement,
|
|
5133
5182
|
config.maxTokensCap
|
|
5134
5183
|
);
|
|
5135
5184
|
return new Promise((resolve3) => {
|
|
5185
|
+
totalResolve = resolve3;
|
|
5136
5186
|
let preJsonBuffer = "";
|
|
5137
5187
|
let jsonContent = "";
|
|
5138
5188
|
let inJson = false;
|
|
5139
5189
|
let sentStatuses = 0;
|
|
5140
5190
|
let stopReason = null;
|
|
5191
|
+
let charsReceived = 0;
|
|
5192
|
+
let settled = false;
|
|
5193
|
+
let inactivityTimer = null;
|
|
5194
|
+
function clearInactivityTimer() {
|
|
5195
|
+
if (inactivityTimer) {
|
|
5196
|
+
clearTimeout(inactivityTimer);
|
|
5197
|
+
inactivityTimer = null;
|
|
5198
|
+
}
|
|
5199
|
+
}
|
|
5200
|
+
function resetInactivityTimer() {
|
|
5201
|
+
if (inactivityTimer) clearTimeout(inactivityTimer);
|
|
5202
|
+
inactivityTimer = setTimeout(() => {
|
|
5203
|
+
if (settled) return;
|
|
5204
|
+
settled = true;
|
|
5205
|
+
clearInactivityTimer();
|
|
5206
|
+
const raw = preJsonBuffer + jsonContent;
|
|
5207
|
+
if (config.callbacks)
|
|
5208
|
+
config.callbacks.onError(buildDiagnostic("timeout_inactivity", raw, charsReceived));
|
|
5209
|
+
resolve3({ setup: null, raw, stopReason: "timeout_inactivity" });
|
|
5210
|
+
}, inactivityTimeoutMs);
|
|
5211
|
+
}
|
|
5212
|
+
resetInactivityTimer();
|
|
5141
5213
|
provider.stream(
|
|
5142
5214
|
{
|
|
5143
5215
|
system: config.systemPrompt,
|
|
@@ -5146,6 +5218,9 @@ async function streamGeneration(config) {
|
|
|
5146
5218
|
},
|
|
5147
5219
|
{
|
|
5148
5220
|
onText: (text) => {
|
|
5221
|
+
if (settled || totalTimedOut) return;
|
|
5222
|
+
charsReceived += text.length;
|
|
5223
|
+
resetInactivityTimer();
|
|
5149
5224
|
if (!inJson) {
|
|
5150
5225
|
preJsonBuffer += text;
|
|
5151
5226
|
const lines = preJsonBuffer.split("\n");
|
|
@@ -5173,6 +5248,9 @@ async function streamGeneration(config) {
|
|
|
5173
5248
|
}
|
|
5174
5249
|
},
|
|
5175
5250
|
onEnd: (meta) => {
|
|
5251
|
+
clearInactivityTimer();
|
|
5252
|
+
if (settled || totalTimedOut) return;
|
|
5253
|
+
settled = true;
|
|
5176
5254
|
stopReason = meta?.stopReason ?? null;
|
|
5177
5255
|
let setup = null;
|
|
5178
5256
|
let jsonToParse = (jsonContent || preJsonBuffer).replace(/```\s*$/g, "").trim();
|
|
@@ -5215,23 +5293,37 @@ async function streamGeneration(config) {
|
|
|
5215
5293
|
}
|
|
5216
5294
|
},
|
|
5217
5295
|
onError: (error) => {
|
|
5296
|
+
clearInactivityTimer();
|
|
5297
|
+
if (settled || totalTimedOut) return;
|
|
5218
5298
|
if (isTransientError2(error) && attempt < MAX_RETRIES2) {
|
|
5299
|
+
settled = true;
|
|
5219
5300
|
if (config.callbacks)
|
|
5220
5301
|
config.callbacks.onStatus("Connection interrupted, retrying...");
|
|
5221
5302
|
setTimeout(() => attemptGeneration().then(resolve3), 2e3);
|
|
5222
5303
|
return;
|
|
5223
5304
|
}
|
|
5305
|
+
settled = true;
|
|
5224
5306
|
if (config.callbacks) config.callbacks.onError(error.message);
|
|
5225
5307
|
resolve3({ setup: null, raw: error.message, stopReason: "error" });
|
|
5226
5308
|
}
|
|
5227
5309
|
}
|
|
5228
5310
|
).catch((error) => {
|
|
5311
|
+
clearInactivityTimer();
|
|
5312
|
+
if (settled || totalTimedOut) return;
|
|
5313
|
+
settled = true;
|
|
5229
5314
|
if (config.callbacks) config.callbacks.onError(error.message);
|
|
5230
5315
|
resolve3({ setup: null, raw: error.message, stopReason: "error" });
|
|
5231
5316
|
});
|
|
5232
5317
|
});
|
|
5233
5318
|
};
|
|
5234
|
-
|
|
5319
|
+
try {
|
|
5320
|
+
const result = await attemptGeneration();
|
|
5321
|
+
clearTimeout(totalTimer);
|
|
5322
|
+
return totalTimedOut ? { setup: null, raw: result.raw, stopReason: "timeout_total" } : result;
|
|
5323
|
+
} catch (err) {
|
|
5324
|
+
clearTimeout(totalTimer);
|
|
5325
|
+
throw err;
|
|
5326
|
+
}
|
|
5235
5327
|
}
|
|
5236
5328
|
async function generateCore(fingerprint, targetAgent, prompt, callbacks, failingChecks, currentScore, passingChecks) {
|
|
5237
5329
|
const userMessage = buildGeneratePrompt(
|
|
@@ -9501,6 +9593,10 @@ import fs30 from "fs";
|
|
|
9501
9593
|
// src/ai/refine.ts
|
|
9502
9594
|
async function refineSetup(currentSetup, message, conversationHistory, callbacks) {
|
|
9503
9595
|
const provider = getProvider();
|
|
9596
|
+
const inactivityTimeoutMs = parseEnvTimeout(
|
|
9597
|
+
"CALIBER_STREAM_INACTIVITY_TIMEOUT_MS",
|
|
9598
|
+
DEFAULT_INACTIVITY_TIMEOUT_MS
|
|
9599
|
+
);
|
|
9504
9600
|
const prompt = `Current setup:
|
|
9505
9601
|
${JSON.stringify(currentSetup, null, 2)}
|
|
9506
9602
|
|
|
@@ -9509,6 +9605,25 @@ User request: ${message}
|
|
|
9509
9605
|
Return the complete updated AgentSetup JSON incorporating the user's changes. Respond with ONLY the JSON.`;
|
|
9510
9606
|
return new Promise((resolve3) => {
|
|
9511
9607
|
let buffer = "";
|
|
9608
|
+
let settled = false;
|
|
9609
|
+
let inactivityTimer = null;
|
|
9610
|
+
function clearInactivityTimer() {
|
|
9611
|
+
if (inactivityTimer) {
|
|
9612
|
+
clearTimeout(inactivityTimer);
|
|
9613
|
+
inactivityTimer = null;
|
|
9614
|
+
}
|
|
9615
|
+
}
|
|
9616
|
+
function resetInactivityTimer() {
|
|
9617
|
+
clearInactivityTimer();
|
|
9618
|
+
inactivityTimer = setTimeout(() => {
|
|
9619
|
+
if (settled) return;
|
|
9620
|
+
settled = true;
|
|
9621
|
+
const msg = buffer.length === 0 ? "Model produced no output. Try a different model." : "Model stopped responding. Try rephrasing your request or using a different model.";
|
|
9622
|
+
if (callbacks) callbacks.onError(msg);
|
|
9623
|
+
resolve3(null);
|
|
9624
|
+
}, inactivityTimeoutMs);
|
|
9625
|
+
}
|
|
9626
|
+
resetInactivityTimer();
|
|
9512
9627
|
provider.stream(
|
|
9513
9628
|
{
|
|
9514
9629
|
system: REFINE_SYSTEM_PROMPT,
|
|
@@ -9518,9 +9633,14 @@ Return the complete updated AgentSetup JSON incorporating the user's changes. Re
|
|
|
9518
9633
|
},
|
|
9519
9634
|
{
|
|
9520
9635
|
onText: (text) => {
|
|
9636
|
+
if (settled) return;
|
|
9521
9637
|
buffer += text;
|
|
9638
|
+
resetInactivityTimer();
|
|
9522
9639
|
},
|
|
9523
9640
|
onEnd: () => {
|
|
9641
|
+
clearInactivityTimer();
|
|
9642
|
+
if (settled) return;
|
|
9643
|
+
settled = true;
|
|
9524
9644
|
const cleaned = stripMarkdownFences(buffer);
|
|
9525
9645
|
const jsonStart = cleaned.indexOf("{");
|
|
9526
9646
|
const jsonToParse = jsonStart !== -1 ? cleaned.slice(jsonStart) : cleaned;
|
|
@@ -9529,16 +9649,23 @@ Return the complete updated AgentSetup JSON incorporating the user's changes. Re
|
|
|
9529
9649
|
if (callbacks) callbacks.onComplete(setup);
|
|
9530
9650
|
resolve3(setup);
|
|
9531
9651
|
} catch {
|
|
9532
|
-
if (callbacks)
|
|
9652
|
+
if (callbacks)
|
|
9653
|
+
callbacks.onError("Failed to parse AI response. Try rephrasing your request.");
|
|
9533
9654
|
resolve3(null);
|
|
9534
9655
|
}
|
|
9535
9656
|
},
|
|
9536
9657
|
onError: (error) => {
|
|
9658
|
+
clearInactivityTimer();
|
|
9659
|
+
if (settled) return;
|
|
9660
|
+
settled = true;
|
|
9537
9661
|
if (callbacks) callbacks.onError(error.message);
|
|
9538
9662
|
resolve3(null);
|
|
9539
9663
|
}
|
|
9540
9664
|
}
|
|
9541
9665
|
).catch((error) => {
|
|
9666
|
+
clearInactivityTimer();
|
|
9667
|
+
if (settled) return;
|
|
9668
|
+
settled = true;
|
|
9542
9669
|
if (callbacks) callbacks.onError(error.message);
|
|
9543
9670
|
resolve3(null);
|
|
9544
9671
|
});
|
|
@@ -10033,6 +10160,18 @@ function writeErrorLog(config, rawOutput, error, stopReason) {
|
|
|
10033
10160
|
lines.push("## Error", "```", error, "```", "");
|
|
10034
10161
|
}
|
|
10035
10162
|
lines.push("## Raw LLM Output", "```", rawOutput || "(empty)", "```");
|
|
10163
|
+
if (stopReason?.startsWith("timeout")) {
|
|
10164
|
+
lines.push("", "## Troubleshooting", "");
|
|
10165
|
+
lines.push("This failure was caused by a timeout. You can adjust timeouts with:");
|
|
10166
|
+
lines.push("```bash");
|
|
10167
|
+
lines.push("# Increase inactivity timeout (default: 120s)");
|
|
10168
|
+
lines.push("export CALIBER_STREAM_INACTIVITY_TIMEOUT_MS=180000");
|
|
10169
|
+
lines.push("");
|
|
10170
|
+
lines.push("# Increase total generation timeout (default: 600s)");
|
|
10171
|
+
lines.push("export CALIBER_GENERATION_TIMEOUT_MS=900000");
|
|
10172
|
+
lines.push("```");
|
|
10173
|
+
lines.push("", "If timeouts persist, try a different model.");
|
|
10174
|
+
}
|
|
10036
10175
|
fs32.mkdirSync(path26.join(process.cwd(), ".caliber"), { recursive: true });
|
|
10037
10176
|
fs32.writeFileSync(logPath, lines.join("\n"));
|
|
10038
10177
|
console.log(chalk13.dim(`
|
|
@@ -10049,7 +10188,9 @@ async function evaluateDismissals(failingChecks, fingerprint) {
|
|
|
10049
10188
|
suggestion: c.suggestion
|
|
10050
10189
|
}));
|
|
10051
10190
|
const hasBuildFiles = fingerprint.fileTree.some(
|
|
10052
|
-
(f) => /^(package\.json|Makefile|Cargo\.toml|go\.mod|pyproject\.toml|requirements\.txt|build\.gradle|pom\.xml)$/i.test(
|
|
10191
|
+
(f) => /^(package\.json|Makefile|Cargo\.toml|go\.mod|pyproject\.toml|requirements\.txt|build\.gradle|pom\.xml)$/i.test(
|
|
10192
|
+
f.split("/").pop() || ""
|
|
10193
|
+
)
|
|
10053
10194
|
);
|
|
10054
10195
|
const topFiles = fingerprint.fileTree.slice(0, 30).join(", ");
|
|
10055
10196
|
try {
|
|
@@ -10284,8 +10425,16 @@ async function initCommand(options) {
|
|
|
10284
10425
|
installSessionStartHook();
|
|
10285
10426
|
console.log(` ${chalk14.green("\u2713")} Freshness hook \u2014 warns when configs are stale`);
|
|
10286
10427
|
if (IS_WINDOWS5) {
|
|
10287
|
-
console.log(
|
|
10288
|
-
|
|
10428
|
+
console.log(
|
|
10429
|
+
chalk14.yellow(
|
|
10430
|
+
"\n Note: hooks use shell syntax and require Git Bash (included with Git for Windows)."
|
|
10431
|
+
)
|
|
10432
|
+
);
|
|
10433
|
+
console.log(
|
|
10434
|
+
chalk14.dim(
|
|
10435
|
+
" If hooks don't run, ensure Git for Windows is installed and git is using its bundled sh."
|
|
10436
|
+
)
|
|
10437
|
+
);
|
|
10289
10438
|
}
|
|
10290
10439
|
const { ensureBuiltinSkills: ensureBuiltinSkills2 } = await Promise.resolve().then(() => (init_builtin_skills(), builtin_skills_exports));
|
|
10291
10440
|
for (const agent of targetAgent) {
|
|
@@ -10584,7 +10733,8 @@ async function initCommand(options) {
|
|
|
10584
10733
|
rawOutput = result.raw;
|
|
10585
10734
|
genStopReason = result.stopReason;
|
|
10586
10735
|
if (!generatedSetup) {
|
|
10587
|
-
|
|
10736
|
+
const diagnostic = buildDiagnostic(genStopReason, rawOutput, rawOutput?.length ?? 0);
|
|
10737
|
+
display.update(TASK_CONFIG, "failed", diagnostic.split("\n")[0].slice(0, 80));
|
|
10588
10738
|
display.update(TASK_SKILLS_GEN, "failed", "Skipped");
|
|
10589
10739
|
return;
|
|
10590
10740
|
}
|
|
@@ -12188,9 +12338,10 @@ async function refreshCommand(options) {
|
|
|
12188
12338
|
`${repoName}: refresh failed \u2014 ${err instanceof Error ? err.message : "unknown error"}`
|
|
12189
12339
|
)
|
|
12190
12340
|
);
|
|
12341
|
+
} finally {
|
|
12342
|
+
process.chdir(originalDir);
|
|
12191
12343
|
}
|
|
12192
12344
|
}
|
|
12193
|
-
process.chdir(originalDir);
|
|
12194
12345
|
} catch (err) {
|
|
12195
12346
|
if (err instanceof Error && err.message === "__exit__") throw err;
|
|
12196
12347
|
writeRefreshError(err);
|
|
@@ -12503,6 +12654,7 @@ function trimSessionFileIfNeeded(filePath) {
|
|
|
12503
12654
|
const stat = fs43.statSync(filePath);
|
|
12504
12655
|
if (stat.size > MAX_SESSION_FILE_BYTES) {
|
|
12505
12656
|
fs43.writeFileSync(filePath, "");
|
|
12657
|
+
resetState();
|
|
12506
12658
|
return;
|
|
12507
12659
|
}
|
|
12508
12660
|
} catch {
|
|
@@ -12540,6 +12692,7 @@ function readAllEvents() {
|
|
|
12540
12692
|
const stat = fs43.statSync(filePath);
|
|
12541
12693
|
if (stat.size > MAX_SESSION_FILE_BYTES) {
|
|
12542
12694
|
fs43.writeFileSync(filePath, "");
|
|
12695
|
+
resetState();
|
|
12543
12696
|
return [];
|
|
12544
12697
|
}
|
|
12545
12698
|
} catch {
|
|
@@ -12568,7 +12721,10 @@ function getEventCount() {
|
|
|
12568
12721
|
}
|
|
12569
12722
|
function clearSession() {
|
|
12570
12723
|
const filePath = sessionFilePath();
|
|
12571
|
-
|
|
12724
|
+
try {
|
|
12725
|
+
fs43.writeFileSync(filePath, "");
|
|
12726
|
+
} catch {
|
|
12727
|
+
}
|
|
12572
12728
|
}
|
|
12573
12729
|
function readState2() {
|
|
12574
12730
|
const filePath = stateFilePath();
|
package/package.json
CHANGED