feat: correx-managed model lifecycle slice 1 — config + manager factory + boot/shutdown
[[models]] config (ModelConfig/ModelsSettings) parsed by ConfigLoader; InfrastructureModule.createModelManager + modelConfigToDescriptor; Main.kt managed boot path spawns the default llama-server when [[models]] is present (static [[providers]] path preserved when absent) and kills it on shutdown. Plan: docs/plans/2026-05-31-model-lifecycle-management.md (slice 1 of 5).
This commit is contained in:
@@ -47,6 +47,7 @@ import com.correx.core.toolintent.rules.PathContainmentRule
|
||||
import com.correx.infrastructure.InfrastructureModule
|
||||
import com.correx.infrastructure.inference.DefaultProviderRegistry
|
||||
import com.correx.infrastructure.inference.FirstAvailableRoutingStrategy
|
||||
import com.correx.core.inference.InferenceProvider
|
||||
import com.correx.infrastructure.inference.llama.cpp.LlamaCppInferenceProvider
|
||||
import com.correx.infrastructure.tools.FileEditConfig
|
||||
import com.correx.infrastructure.tools.FileReadConfig
|
||||
@@ -71,15 +72,48 @@ fun main() {
|
||||
logStoresInfo(eventStore, artifactStore)
|
||||
|
||||
val correxConfig = ConfigLoader.load()
|
||||
val providers = buildProviders(correxConfig)
|
||||
require(providers.isNotEmpty()) { "At least one provider must be configured" }
|
||||
val infraRegistry = InfrastructureModule.createProviderRegistry(providers)
|
||||
val llamaProvider = providers.first()
|
||||
val modelId = llamaProvider.id.value
|
||||
val modelPath = "(from config)"
|
||||
val llamaUrl = "(from config)"
|
||||
val eventDispatcher = EventDispatcher(eventStore)
|
||||
|
||||
logModelInfo(modelId, modelPath, llamaUrl, infraRegistry)
|
||||
// Managed path: [[models]] present → correx spawns llama-server at boot
|
||||
// Static path: [[models]] absent → legacy [[providers]] / env-var behavior
|
||||
val firstProvider: InferenceProvider
|
||||
val infraRegistry: DefaultProviderRegistry
|
||||
|
||||
if (correxConfig.models.isNotEmpty()) {
|
||||
val settings = correxConfig.modelsSettings
|
||||
val modelManager = InfrastructureModule.createModelManager(settings, eventStore, eventDispatcher)
|
||||
val targetId = settings.defaultModel ?: correxConfig.models.first().id
|
||||
val targetModelConfig = correxConfig.models.firstOrNull { it.id == targetId }
|
||||
?: correxConfig.models.first()
|
||||
log.info("Managed path: loading model '{}' from '{}'", targetModelConfig.id, targetModelConfig.modelPath)
|
||||
val descriptor = InfrastructureModule.modelConfigToDescriptor(targetModelConfig)
|
||||
val managedProvider = runBlocking { modelManager.load(descriptor) }
|
||||
firstProvider = managedProvider
|
||||
infraRegistry = InfrastructureModule.createProviderRegistry(listOf(managedProvider))
|
||||
// Also register any static providers from [[providers]] (non-managed remotes)
|
||||
correxConfig.providers.mapNotNull { providerConfig ->
|
||||
when (providerConfig.type.lowercase()) {
|
||||
"llamacpp" -> buildProviderFromConfig(providerConfig)
|
||||
else -> { log.error("Unknown provider type: {}", providerConfig.type); null }
|
||||
}
|
||||
}.forEach { infraRegistry.register(it) }
|
||||
// Shutdown hook to kill the managed llama-server
|
||||
Runtime.getRuntime().addShutdownHook(Thread {
|
||||
log.info("Shutdown: unloading managed model '{}'", targetModelConfig.id)
|
||||
runBlocking {
|
||||
runCatching { modelManager.unload(targetModelConfig.id) }
|
||||
.onFailure { log.warn("Error during managed model unload: {}", it.message) }
|
||||
}
|
||||
})
|
||||
} else {
|
||||
val staticProviders = buildProviders(correxConfig)
|
||||
require(staticProviders.isNotEmpty()) { "At least one provider must be configured" }
|
||||
firstProvider = staticProviders.first()
|
||||
infraRegistry = InfrastructureModule.createProviderRegistry(staticProviders)
|
||||
}
|
||||
|
||||
val modelId = firstProvider.id.value
|
||||
logModelInfo(modelId, infraRegistry)
|
||||
|
||||
val repositories = buildRepositories(eventStore)
|
||||
val approvalEngine = DefaultApprovalEngine()
|
||||
@@ -107,7 +141,7 @@ fun main() {
|
||||
)
|
||||
val toolExecutor = InfrastructureModule.createToolExecutor(
|
||||
registry = toolRegistry,
|
||||
eventDispatcher = EventDispatcher(eventStore),
|
||||
eventDispatcher = eventDispatcher,
|
||||
workDir = sandboxRoot,
|
||||
artifactStore = artifactStore,
|
||||
)
|
||||
@@ -156,7 +190,7 @@ fun main() {
|
||||
engines = engines,
|
||||
retryCoordinator = DefaultRetryCoordinator(eventStore),
|
||||
artifactStore = artifactStore,
|
||||
tokenizer = llamaProvider.tokenizer,
|
||||
tokenizer = firstProvider.tokenizer,
|
||||
)
|
||||
val defaultOrchestrationConfig = OrchestrationConfig(
|
||||
sandboxRoot = sandboxRoot,
|
||||
@@ -173,7 +207,7 @@ fun main() {
|
||||
eventStore = eventStore,
|
||||
inferenceRouter = inferenceRouter,
|
||||
config = RouterConfig(),
|
||||
tokenizer = llamaProvider.tokenizer,
|
||||
tokenizer = firstProvider.tokenizer,
|
||||
embedder = embedder,
|
||||
l3MemoryStore = l3MemoryStore,
|
||||
)
|
||||
@@ -206,14 +240,10 @@ fun main() {
|
||||
|
||||
private fun logModelInfo(
|
||||
modelId: String,
|
||||
modelPath: String,
|
||||
llamaUrl: String,
|
||||
infraRegistry: DefaultProviderRegistry,
|
||||
) {
|
||||
log.info("==========MODEL INFO==========")
|
||||
log.info(" model id : {}", modelId)
|
||||
log.info(" model path : {}", modelPath)
|
||||
log.info(" llama url : {}", llamaUrl)
|
||||
log.info(" providers : {} registered", infraRegistry.listAll().size)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user