feat(server,kernel): repo-map indexer + droppable L3 context injection
This commit is contained in:
+37
-1
@@ -30,6 +30,7 @@ import com.correx.core.events.events.ArtifactValidatingEvent
|
||||
import com.correx.core.events.events.EventMetadata
|
||||
import com.correx.core.events.events.EventPayload
|
||||
import com.correx.core.events.events.InferenceCompletedEvent
|
||||
import com.correx.core.events.events.RepoMapComputedEvent
|
||||
import com.correx.core.events.events.InferenceFailedEvent
|
||||
import com.correx.core.events.events.InferenceStartedEvent
|
||||
import com.correx.core.events.events.InferenceTimeoutEvent
|
||||
@@ -117,6 +118,7 @@ import kotlin.coroutines.cancellation.CancellationException
|
||||
|
||||
private const val MAX_TOOL_ROUNDS = 10
|
||||
private const val STAGE_COMPLETE_TOOL = "stage_complete"
|
||||
private const val REPO_MAP_INJECT_TOP_K = 30
|
||||
|
||||
@SuppressWarnings(
|
||||
"ForbiddenComment",
|
||||
@@ -303,7 +305,9 @@ abstract class SessionOrchestrator(
|
||||
role = EntryRole.SYSTEM,
|
||||
),
|
||||
)
|
||||
var accumulatedEntries = systemPrompt + journalEntries + schemaEntries + promptEntries + steeringEntries
|
||||
val repoMapEntries = buildRepoMapEntries(sessionId)
|
||||
var accumulatedEntries =
|
||||
systemPrompt + journalEntries + repoMapEntries + schemaEntries + promptEntries + steeringEntries
|
||||
val contextPack = contextPackBuilder.build(
|
||||
id = ContextPackId(UUID.randomUUID().toString()),
|
||||
sessionId = sessionId,
|
||||
@@ -807,6 +811,38 @@ abstract class SessionOrchestrator(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders a top-K slice of the recorded repo map as a droppable L3 context entry. Reads
|
||||
* the latest [RepoMapComputedEvent] from the log (replay-safe — never re-scans the FS).
|
||||
* Not pinned: under budget pressure this yields before the working set (paths + symbols
|
||||
* only, so the model can `file_read` for detail).
|
||||
*/
|
||||
private suspend fun buildRepoMapEntries(sessionId: SessionId): List<ContextEntry> {
|
||||
val map = eventStore.read(sessionId)
|
||||
.mapNotNull { it.payload as? RepoMapComputedEvent }
|
||||
.lastOrNull() ?: return emptyList()
|
||||
val top = map.entries.sortedByDescending { it.score }.take(REPO_MAP_INJECT_TOP_K)
|
||||
if (top.isEmpty()) return emptyList()
|
||||
val content = buildString {
|
||||
appendLine("## Repo map (top files by recency — read files for detail)")
|
||||
top.forEach { entry ->
|
||||
val symbols = if (entry.symbols.isEmpty()) "" else ": ${entry.symbols.joinToString(", ")}"
|
||||
appendLine("- ${entry.path}$symbols")
|
||||
}
|
||||
}.trimEnd()
|
||||
return listOf(
|
||||
ContextEntry(
|
||||
id = ContextEntryId(UUID.randomUUID().toString()),
|
||||
layer = ContextLayer.L3,
|
||||
content = content,
|
||||
sourceType = "repoMap",
|
||||
sourceId = "repo-map",
|
||||
tokenEstimate = estimateTokens(content),
|
||||
role = EntryRole.SYSTEM,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
private suspend fun emitToolArtifacts(
|
||||
sessionId: SessionId,
|
||||
stageId: StageId,
|
||||
|
||||
Reference in New Issue
Block a user