Skip to content

Commit 4e4e050

Browse files
committed
Fix dreamer key-files lease loss during long LLM call
The key-files post-task phase ran outside the dreamer task wrapper that provides periodic lease renewal, so when the LLM call took longer than the 2-minute lease TTL (e.g. 197s on this project's corpus), the commit-time peekLeaseHolderAndExpiry check failed with "lease lost" even though no other holder had taken over. Three consecutive dream runs failed with this exact pattern after v6 key-files shipped. The fix mirrors the proven setInterval pattern used by the smart-notes post-task phase at runner.ts:1068. Wraps the LLM call + commit in a setInterval that calls renewLease every 60s, cleared in finally.
1 parent 925e4aa commit 4e4e050

1 file changed

Lines changed: 39 additions & 22 deletions

File tree

packages/plugin/src/features/magic-context/key-files/identify-key-files.ts

Lines changed: 39 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -513,30 +513,47 @@ export async function runKeyFilesTask(args: {
513513

514514
const prompt = buildV6KeyFilesPrompt({ candidates, currentRows, config: args.config });
515515
let validated: ValidatedKeyFilesOutput;
516+
// Renew the dream lease every 60s while the LLM call is in flight so the
517+
// commit-time lease check (peekLeaseHolderAndExpiry) sees a live expiry.
518+
// Without this, key-files runs longer than the 2-minute lease TTL fail at
519+
// commit time with "lease lost" even though no other holder took over.
520+
const leaseInterval = setInterval(() => {
521+
try {
522+
if (!renewLease(args.db, args.holderId)) {
523+
log("[key-files] lease renewal failed during LLM call");
524+
}
525+
} catch (error) {
526+
log(`[key-files] lease renewal threw: ${getErrorMessage(error)}`);
527+
}
528+
}, 60_000);
516529
try {
517-
const raw = await runKeyFilesLlm({
518-
client: args.client,
519-
parentSessionId: args.parentSessionId,
530+
try {
531+
const raw = await runKeyFilesLlm({
532+
client: args.client,
533+
parentSessionId: args.parentSessionId,
534+
projectPath,
535+
prompt,
536+
deadline: args.deadline,
537+
fallbackModels: args.fallbackModels,
538+
});
539+
validated = validateLlmOutput(raw, args.config, projectPath);
540+
} catch (error) {
541+
log(`[key-files] LLM validation failed: ${getErrorMessage(error)}`);
542+
throw error;
543+
}
544+
if (validated.no_change)
545+
return { committedVersion: null, candidates: candidates.length, noChange: true };
546+
const committedVersion = commitKeyFiles({
547+
db: args.db,
520548
projectPath,
521-
prompt,
522-
deadline: args.deadline,
523-
fallbackModels: args.fallbackModels,
549+
validated,
550+
configHash,
551+
modelId: args.fallbackModels?.[0] ?? "dreamer",
552+
leaseHolderId: args.holderId,
524553
});
525-
validated = validateLlmOutput(raw, args.config, projectPath);
526-
} catch (error) {
527-
log(`[key-files] LLM validation failed: ${getErrorMessage(error)}`);
528-
throw error;
554+
renewLease(args.db, args.holderId);
555+
return { committedVersion, candidates: candidates.length, noChange: false };
556+
} finally {
557+
clearInterval(leaseInterval);
529558
}
530-
if (validated.no_change)
531-
return { committedVersion: null, candidates: candidates.length, noChange: true };
532-
const committedVersion = commitKeyFiles({
533-
db: args.db,
534-
projectPath,
535-
validated,
536-
configHash,
537-
modelId: args.fallbackModels?.[0] ?? "dreamer",
538-
leaseHolderId: args.holderId,
539-
});
540-
renewLease(args.db, args.holderId);
541-
return { committedVersion, candidates: candidates.length, noChange: false };
542559
}

0 commit comments

Comments
 (0)