feat: switchable router embedder and L3 backends via config
Adds [router.embedder] and [router.l3] sections to CorrexConfig with backend selectors. Ships LlamaCppEmbedder that hits llama.cpp's /embedding endpoint (handles OpenAI-compatible, simple, and array response shapes; validates dimension). InfrastructureModule gains createEmbedderFromConfig and createL3MemoryStoreFromConfig that dispatch on backend value. Defaults preserve current behavior (noop embedder + in-memory L3). Switching to "llamacpp" / "turbovec" is a config-only change — no code edits required. For turbovec backend, the bundled python sidecar script is extracted from classpath to ~/.cache/correx/ on first use.
This commit is contained in:
@@ -6,6 +6,8 @@ import com.correx.core.approvals.DefaultApprovalRepository
|
||||
import com.correx.core.artifacts.DefaultArtifactReducer
|
||||
import com.correx.core.artifacts.repository.ArtifactRepository
|
||||
import com.correx.core.artifactstore.ArtifactStore
|
||||
import com.correx.core.config.EmbedderConfig
|
||||
import com.correx.core.config.L3Config
|
||||
import com.correx.core.events.EventDispatcher
|
||||
import com.correx.core.events.stores.EventStore
|
||||
import com.correx.core.inference.CapabilityScore
|
||||
@@ -33,7 +35,10 @@ import com.correx.infrastructure.artifactscas.index.SqliteArtifactIndex
|
||||
import com.correx.infrastructure.inference.DefaultProviderRegistry
|
||||
import com.correx.infrastructure.inference.commons.ModelDescriptor
|
||||
import com.correx.infrastructure.inference.commons.ResidencyMode
|
||||
import com.correx.infrastructure.inference.llama.cpp.LlamaCppEmbedder
|
||||
import com.correx.infrastructure.inference.llama.cpp.LlamaCppInferenceProvider
|
||||
import com.correx.infrastructure.router.turbovec.TurboVecL3MemoryStore
|
||||
import com.correx.infrastructure.router.turbovec.TurboVecSidecarConfig
|
||||
import com.correx.infrastructure.persistence.SqliteEventStore
|
||||
import com.correx.infrastructure.persistence.artifact.LiveArtifactRepository
|
||||
import com.correx.infrastructure.tools.DefaultToolRegistry
|
||||
@@ -49,6 +54,7 @@ import kotlinx.coroutines.runBlocking
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
import java.nio.file.Paths
|
||||
import java.nio.file.StandardCopyOption
|
||||
import java.sql.DriverManager
|
||||
|
||||
@Suppress("TooManyFunctions")
|
||||
@@ -137,6 +143,70 @@ object InfrastructureModule {
|
||||
|
||||
fun createInMemoryL3MemoryStore(): L3MemoryStore = InMemoryL3MemoryStore()
|
||||
|
||||
fun createLlamaCppEmbedder(config: EmbedderConfig): Embedder {
|
||||
val url = config.url ?: throw IllegalArgumentException(
|
||||
"EmbedderConfig with backend 'llamacpp' requires non-null 'url'"
|
||||
)
|
||||
return LlamaCppEmbedder(
|
||||
url = url,
|
||||
modelId = config.modelId,
|
||||
dimension = config.dimension,
|
||||
)
|
||||
}
|
||||
|
||||
fun createTurboVecL3MemoryStore(config: L3Config): L3MemoryStore {
|
||||
val scriptPath = config.scriptPath?.let { Paths.get(it) }
|
||||
?: extractBundledTurboVecScript()
|
||||
|
||||
val persistPath = config.persistPath?.let { Paths.get(it) }
|
||||
|
||||
val sidecarConfig = TurboVecSidecarConfig(
|
||||
pythonExecutable = config.pythonExecutable,
|
||||
scriptPath = scriptPath,
|
||||
dim = config.dim,
|
||||
bitWidth = config.bitWidth,
|
||||
persistPath = persistPath,
|
||||
)
|
||||
|
||||
return TurboVecL3MemoryStore(sidecarConfig)
|
||||
}
|
||||
|
||||
private fun extractBundledTurboVecScript(): Path {
|
||||
val cacheDir = Paths.get(System.getProperty("user.home"), ".cache", "correx")
|
||||
Files.createDirectories(cacheDir)
|
||||
|
||||
val targetPath = cacheDir.resolve("turbovec_sidecar.py")
|
||||
|
||||
val inputStream = InfrastructureModule::class.java.getResourceAsStream("/python/turbovec_sidecar.py")
|
||||
?: throw IllegalStateException("Could not find bundled turbovec_sidecar.py in classpath")
|
||||
|
||||
inputStream.use { input ->
|
||||
Files.copy(input, targetPath, StandardCopyOption.REPLACE_EXISTING)
|
||||
}
|
||||
|
||||
return targetPath
|
||||
}
|
||||
|
||||
fun createEmbedderFromConfig(config: EmbedderConfig): Embedder {
|
||||
return when (config.backend) {
|
||||
"noop" -> createNoopEmbedder(config.dimension)
|
||||
"llamacpp" -> createLlamaCppEmbedder(config)
|
||||
else -> throw IllegalArgumentException(
|
||||
"Unknown embedder backend: '${config.backend}'. Supported: noop, llamacpp"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun createL3MemoryStoreFromConfig(config: L3Config): L3MemoryStore {
|
||||
return when (config.backend) {
|
||||
"in_memory" -> createInMemoryL3MemoryStore()
|
||||
"turbovec" -> createTurboVecL3MemoryStore(config)
|
||||
else -> throw IllegalArgumentException(
|
||||
"Unknown L3 backend: '${config.backend}'. Supported: in_memory, turbovec"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun createRouterFacade(
|
||||
eventStore: EventStore,
|
||||
inferenceRouter: InferenceRouter,
|
||||
|
||||
Reference in New Issue
Block a user