feat(server): wire EmbeddingRelevanceScorer into context builder, default level 4

Move embedder construction ahead of the engines so the context pack builder ranks
freeform turns by query relevance (query-conditioned selection). Default
compression_level 4 (format + static cache + token pruning + age-tiering) for a 12b
on a 16k window.
This commit is contained in:
2026-07-01 14:33:00 +04:00
parent 047e2a4070
commit e3743835ec
3 changed files with 9 additions and 4 deletions
@@ -18,6 +18,7 @@ import com.correx.core.config.ProfileLoader
import com.correx.core.config.ProviderConfig import com.correx.core.config.ProviderConfig
import com.correx.core.context.builder.DefaultContextPackBuilder import com.correx.core.context.builder.DefaultContextPackBuilder
import com.correx.core.context.compression.CompressionPolicy import com.correx.core.context.compression.CompressionPolicy
import com.correx.core.inference.EmbeddingRelevanceScorer
import com.correx.infrastructure.compression.HttpTokenPruner import com.correx.infrastructure.compression.HttpTokenPruner
import com.correx.core.context.compression.DefaultContextCompressor import com.correx.core.context.compression.DefaultContextCompressor
import com.correx.core.context.model.TokenBudget import com.correx.core.context.model.TokenBudget
@@ -291,12 +292,16 @@ fun main() {
WorkspaceTools(registry = wsRegistry, executor = wsExecutor) WorkspaceTools(registry = wsRegistry, executor = wsExecutor)
} }
// Constructed before the engines so the context builder can rank freeform turns by relevance
// to the current query (pipeline §6, query-conditioned selection). Reused by L3 retrieval below.
val embedder = InfrastructureModule.createEmbedderFromConfig(correxConfig.router.embedder)
val engines = OrchestratorEngines( val engines = OrchestratorEngines(
transitionResolver = DefaultTransitionResolver { condition, ctx -> condition.evaluate(ctx) }, transitionResolver = DefaultTransitionResolver { condition, ctx -> condition.evaluate(ctx) },
contextPackBuilder = DefaultContextPackBuilder( contextPackBuilder = DefaultContextPackBuilder(
DefaultContextCompressor(), DefaultContextCompressor(),
policy = CompressionPolicy(correxConfig.orchestration.compressionLevel), policy = CompressionPolicy(correxConfig.orchestration.compressionLevel),
tokenPruner = HttpTokenPruner(baseUrl = correxConfig.orchestration.tokenPrunerUrl), tokenPruner = HttpTokenPruner(baseUrl = correxConfig.orchestration.tokenPrunerUrl),
relevanceScorer = EmbeddingRelevanceScorer(embedder),
), ),
inferenceRouter = inferenceRouter, inferenceRouter = inferenceRouter,
validationPipeline = ValidationPipeline( validationPipeline = ValidationPipeline(
@@ -340,7 +345,6 @@ fun main() {
val artifactKindRegistry = DefaultArtifactKindRegistry().also { reg -> val artifactKindRegistry = DefaultArtifactKindRegistry().also { reg ->
configArtifactKindsEarly.forEach { reg.register(it) } configArtifactKindsEarly.forEach { reg.register(it) }
} }
val embedder = InfrastructureModule.createEmbedderFromConfig(correxConfig.router.embedder)
val l3MemoryStore = InfrastructureModule.createL3MemoryStoreFromConfig(correxConfig.router.l3) val l3MemoryStore = InfrastructureModule.createL3MemoryStoreFromConfig(correxConfig.router.l3)
// Rebuild the L3 metadata map from the ChatTurnEvent log before serving queries: // Rebuild the L3 metadata map from the ChatTurnEvent log before serving queries:
// persisted vectors survive restart but the metadata map does not (no-op for // persisted vectors survive restart but the metadata map does not (no-op for
@@ -624,7 +624,7 @@ object ConfigLoader {
asInt(orchestrationSection["journal_compaction_token_threshold"], 2_000), asInt(orchestrationSection["journal_compaction_token_threshold"], 2_000),
resumeAbandonedMaxAgeMinutes = resumeAbandonedMaxAgeMinutes =
asLong(orchestrationSection["resume_abandoned_max_age_minutes"], 1_440), asLong(orchestrationSection["resume_abandoned_max_age_minutes"], 1_440),
compressionLevel = asInt(orchestrationSection["compression_level"], 2), compressionLevel = asInt(orchestrationSection["compression_level"], 4),
tokenPrunerUrl = tokenPrunerUrl =
asString(orchestrationSection["token_pruner_url"], "http://127.0.0.1:8199"), asString(orchestrationSection["token_pruner_url"], "http://127.0.0.1:8199"),
) )
@@ -64,9 +64,10 @@ data class OrchestrationKnobs(
/** /**
* Context compression pipeline level (docs/plans/correx-compression-pipeline.md §5), additive * Context compression pipeline level (docs/plans/correx-compression-pipeline.md §5), additive
* 1..9. Default 2 = free format-compress + static cache. Raise toward the 16k wall; ≥3 needs * 1..9. Default 2 = free format-compress + static cache. Raise toward the 16k wall; ≥3 needs
* the LLMLingua-2 sidecar at [tokenPrunerUrl] (fails open if absent). * the LLMLingua-2 sidecar at [tokenPrunerUrl] (fails open if absent). Default 4 = format +
* static cache + token pruning + age-tiering, sized for a 12b on a 16k window.
*/ */
val compressionLevel: Int = 2, val compressionLevel: Int = 4,
val tokenPrunerUrl: String = "http://127.0.0.1:8199", val tokenPrunerUrl: String = "http://127.0.0.1:8199",
) )