feat(kernel): retried stages receive explicit failure feedback; default retry backoff 1s

This commit is contained in:
2026-06-10 21:53:45 +04:00
parent 91cca9aee3
commit 629b910e7f
5 changed files with 62 additions and 4 deletions
@@ -6,10 +6,32 @@ package com.correx.core.kernel.orchestration
import com.correx.core.context.model.ContextEntry
import com.correx.core.context.model.ContextLayer
import com.correx.core.context.model.EntryRole
import com.correx.core.events.events.RetryAttemptedEvent
import com.correx.core.events.events.StoredEvent
import com.correx.core.events.types.ContextEntryId
import com.correx.core.events.types.StageId
import com.correx.core.sessions.BoundProjectProfile
import java.util.UUID
fun buildRetryFeedbackEntry(events: List<StoredEvent>, stageId: StageId): ContextEntry? {
val latest = events
.mapNotNull { it.payload as? RetryAttemptedEvent }
.lastOrNull { it.stageId == stageId } ?: return null
val content = "## Retry feedback\n" +
"Attempt ${latest.attemptNumber} of ${latest.maxAttempts} for stage '${stageId.value}'. " +
"The previous attempt failed: ${latest.failureReason}\n" +
"Address the failure cause directly. Do not repeat the identical approach."
return ContextEntry(
id = ContextEntryId(UUID.randomUUID().toString()),
layer = ContextLayer.L1,
content = content,
sourceType = "retryFeedback",
sourceId = stageId.value,
tokenEstimate = content.length / 4,
role = EntryRole.SYSTEM,
)
}
fun buildProjectProfileEntry(profile: BoundProjectProfile): ContextEntry {
val content = buildString {
append("## Project profile\n")
@@ -365,9 +365,11 @@ abstract class SessionOrchestrator(
} ?: emptyList()
val projectProfileEntries = session.state.boundProjectProfile
?.let { listOf(buildProjectProfileEntry(it)) } ?: emptyList()
val retryFeedbackEntries = buildRetryFeedbackEntry(eventStore.read(sessionId), stageId)
?.let { listOf(it) } ?: emptyList()
var accumulatedEntries =
systemPrompt + profileEntries + projectProfileEntries + journalEntries + repoMapEntries +
needsEntries + schemaEntries + promptEntries + steeringEntries
needsEntries + schemaEntries + promptEntries + steeringEntries + retryFeedbackEntries
val contextPack = contextPackBuilder.build(
id = ContextPackId(UUID.randomUUID().toString()),
sessionId = sessionId,