feat(server,kernel): repo-map indexer + droppable L3 context injection
This commit is contained in:
@@ -418,6 +418,9 @@ object ConfigLoader {
|
||||
enabled = asBoolean(projectSection["enabled"], false),
|
||||
root = asString(projectSection["root"], ""),
|
||||
memoryK = asInt(projectSection["memory_k"], 5),
|
||||
maxDepth = asInt(projectSection["max_depth"], 4),
|
||||
ignoreGlobs = asStringList(projectSection["ignore_globs"]).ifEmpty { ProjectConfig.DEFAULT_IGNORES },
|
||||
injectTopK = asInt(projectSection["inject_top_k"], 30),
|
||||
)
|
||||
|
||||
val modelsSettings = ModelsSettings(
|
||||
|
||||
@@ -26,7 +26,16 @@ data class ProjectConfig(
|
||||
val enabled: Boolean = false,
|
||||
val root: String = "",
|
||||
val memoryK: Int = 5,
|
||||
)
|
||||
val maxDepth: Int = 4,
|
||||
val ignoreGlobs: List<String> = DEFAULT_IGNORES,
|
||||
val injectTopK: Int = 30,
|
||||
) {
|
||||
companion object {
|
||||
val DEFAULT_IGNORES: List<String> = listOf(
|
||||
".git", "node_modules", "build", "target", ".gradle", "dist", ".idea", ".opencode",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A user-declared artifact kind. [schemaPath] points to a JSON file holding the
|
||||
|
||||
+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