diff --git a/apps/server/build.gradle b/apps/server/build.gradle index db59d600..8eec50e9 100644 --- a/apps/server/build.gradle +++ b/apps/server/build.gradle @@ -38,7 +38,7 @@ dependencies { implementation project(':infrastructure:inference:llama_cpp') implementation project(':infrastructure:inference:openai_compat') implementation project(':infrastructure:inference:commons') - implementation project(':core:router') + implementation project(':core:talkie') implementation project(':core:tools') implementation project(':core:toolintent') implementation project(':infrastructure:tools') diff --git a/apps/server/src/main/kotlin/com/correx/apps/server/Main.kt b/apps/server/src/main/kotlin/com/correx/apps/server/Main.kt index 7375b645..4e29f8ef 100644 --- a/apps/server/src/main/kotlin/com/correx/apps/server/Main.kt +++ b/apps/server/src/main/kotlin/com/correx/apps/server/Main.kt @@ -44,9 +44,9 @@ import com.correx.core.kernel.orchestration.WorkspaceTools import com.correx.core.kernel.orchestration.WorkspaceToolRegistryProvider import com.correx.core.kernel.retry.DefaultRetryCoordinator import com.correx.core.risk.DefaultRiskAssessor -import com.correx.core.router.RouterFacade -import com.correx.core.router.l3.L3MetadataRehydrator -import com.correx.core.router.model.RouterConfig +import com.correx.core.talkie.TalkieFacade +import com.correx.core.talkie.l3.L3MetadataRehydrator +import com.correx.core.talkie.model.TalkieConfig import com.correx.core.sessions.DefaultSessionReducer import com.correx.core.sessions.DefaultSessionRepository import com.correx.core.sessions.SessionProjector @@ -294,7 +294,7 @@ fun main() { // 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 embedder = InfrastructureModule.createEmbedderFromConfig(correxConfig.talkie.embedder) val engines = OrchestratorEngines( transitionResolver = DefaultTransitionResolver { condition, ctx -> condition.evaluate(ctx) }, contextPackBuilder = DefaultContextPackBuilder( @@ -345,7 +345,7 @@ fun main() { val artifactKindRegistry = DefaultArtifactKindRegistry().also { reg -> configArtifactKindsEarly.forEach { reg.register(it) } } - val l3MemoryStore = InfrastructureModule.createL3MemoryStoreFromConfig(correxConfig.router.l3) + val l3MemoryStore = InfrastructureModule.createL3MemoryStoreFromConfig(correxConfig.talkie.l3) // 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 // non-rehydratable backends like in_memory). @@ -390,11 +390,11 @@ fun main() { InfrastructureModule.createWorkflowLoader(configArtifactKindsEarly), ) // Builds the router facade from a config snapshot, mapping the [router] block onto the domain - // RouterConfig. Reused by ConfigService's rebuild hook so router knob edits apply live (the + // TalkieConfig. Reused by ConfigService's rebuild hook so router knob edits apply live (the // embedder and L3 store are construction-time and reused; the facade is what gets swapped). - fun buildRouterFacade(cfg: CorrexConfig): RouterFacade { - val rc = cfg.router - val domainRouterConfig = RouterConfig( + fun buildTalkieFacade(cfg: CorrexConfig): TalkieFacade { + val rc = cfg.talkie + val domainTalkieConfig = TalkieConfig( conversationKeepLast = rc.conversationKeepLast, retrievalK = rc.retrievalK, tokenBudget = TokenBudget(limit = rc.tokenBudget), @@ -410,16 +410,16 @@ fun main() { ), narrationModelId = rc.narration.modelId, ) - return InfrastructureModule.createRouterFacade( + return InfrastructureModule.createTalkieFacade( eventStore = eventStore, inferenceRouter = inferenceRouter, - config = domainRouterConfig, + config = domainTalkieConfig, tokenizer = firstProvider.tokenizer, embedder = embedder, l3MemoryStore = l3MemoryStore, workflowSummaryProvider = { workflowRegistry.listAll().map { s -> - com.correx.core.router.model.WorkflowSummary(s.workflowId, s.description, s.stageIds) + com.correx.core.talkie.model.WorkflowSummary(s.workflowId, s.description, s.stageIds) } }, sessionProfileProvider = { sid -> @@ -429,7 +429,7 @@ fun main() { }, ) } - val routerFacade = buildRouterFacade(correxConfig) + val routerFacade = buildTalkieFacade(correxConfig) val sessionUndoService = com.correx.apps.server.undo.SessionUndoService( eventStore = eventStore, artifactStore = artifactStore, @@ -546,7 +546,7 @@ fun main() { modelSwapper = modelSwapper, resourceProbe = resourceProbe, workspaceResolver = workspaceResolver, - narrationMaxPerRun = correxConfig.router.narration.maxPerRun, + narrationMaxPerRun = correxConfig.talkie.narration.maxPerRun, projectMemory = projectMemory, architectContradictionChecker = architectContradictionChecker, configHolder = configHolder, @@ -564,7 +564,7 @@ fun main() { // services. Built after the module so the rebuild hook can swap them in place. module.configService = ConfigService(configHolder, ConfigLoader.configPath()) { cfg -> module.applyRebuiltServices( - newRouterFacade = buildRouterFacade(cfg), + newTalkieFacade = buildTalkieFacade(cfg), newProjectMemory = buildProjectMemory(cfg), newProfileAdaptationService = buildProfileAdaptation(cfg), ) diff --git a/apps/server/src/main/kotlin/com/correx/apps/server/ServerModule.kt b/apps/server/src/main/kotlin/com/correx/apps/server/ServerModule.kt index c5a78882..e2549341 100644 --- a/apps/server/src/main/kotlin/com/correx/apps/server/ServerModule.kt +++ b/apps/server/src/main/kotlin/com/correx/apps/server/ServerModule.kt @@ -39,7 +39,7 @@ import com.correx.core.kernel.execution.WorkflowResult import com.correx.core.kernel.orchestration.DefaultSessionOrchestrator import com.correx.core.kernel.orchestration.OrchestrationConfig import com.correx.core.kernel.orchestration.OrchestrationRepository -import com.correx.core.router.RouterFacade +import com.correx.core.talkie.TalkieFacade import com.correx.core.sessions.DefaultSessionRepository import com.correx.core.sessions.SessionSummary import com.correx.core.sessions.SessionSummaryProjector @@ -72,7 +72,7 @@ class ServerModule( val defaultOrchestrationConfig: OrchestrationConfig, // Rebuilt by ConfigService on a live config edit (router knobs); read at use-time by // GlobalStreamHandler.onUserInput so the next chat turn picks up the new facade. - routerFacade: RouterFacade, + routerFacade: TalkieFacade, val orchestrationRepository: OrchestrationRepository, val approvalRepository: DefaultApprovalRepository, val toolRegistry: ToolRegistry, @@ -134,7 +134,7 @@ class ServerModule( // Config-derived services that ConfigService swaps on a live edit. Reads happen at use-time // (next session / next chat turn), so in-flight sessions keep the config they started with. @Volatile - var routerFacade: RouterFacade = routerFacade + var routerFacade: TalkieFacade = routerFacade private set @Volatile @@ -154,11 +154,11 @@ class ServerModule( * In-flight sessions are untouched; the next session/turn reads the new instances. */ fun applyRebuiltServices( - newRouterFacade: RouterFacade, + newTalkieFacade: TalkieFacade, newProjectMemory: com.correx.apps.server.memory.ProjectMemoryService?, newProfileAdaptationService: com.correx.apps.server.personalization.ProfileAdaptationService?, ) { - this.routerFacade = newRouterFacade + this.routerFacade = newTalkieFacade this.projectMemory = newProjectMemory this.profileAdaptationService = newProfileAdaptationService } diff --git a/apps/server/src/main/kotlin/com/correx/apps/server/bridge/DomainEventMapper.kt b/apps/server/src/main/kotlin/com/correx/apps/server/bridge/DomainEventMapper.kt index 18ada65c..fbdb1fe1 100644 --- a/apps/server/src/main/kotlin/com/correx/apps/server/bridge/DomainEventMapper.kt +++ b/apps/server/src/main/kotlin/com/correx/apps/server/bridge/DomainEventMapper.kt @@ -39,7 +39,7 @@ import com.correx.core.events.events.ToolCallAssessedEvent import com.correx.core.events.events.ToolInvocationRequestedEvent import com.correx.core.events.events.TransitionExecutedEvent import com.correx.core.events.events.WorkflowCompletedEvent -import com.correx.core.events.events.RouterNarrationEvent +import com.correx.core.events.events.TalkieNarrationEvent import com.correx.core.events.events.WorkflowFailedEvent import com.correx.core.events.events.WorkflowProposedEvent import com.correx.core.events.risk.RiskAction @@ -249,7 +249,7 @@ suspend fun domainEventToServerMessage( sequence = seq, sessionSequence = sessionSequence, ) - is RouterNarrationEvent -> ServerMessage.Narration( + is TalkieNarrationEvent -> ServerMessage.Narration( sessionId = p.sessionId, content = p.content, stageId = p.stageId, diff --git a/apps/server/src/main/kotlin/com/correx/apps/server/memory/ArchitectContradictionChecker.kt b/apps/server/src/main/kotlin/com/correx/apps/server/memory/ArchitectContradictionChecker.kt index bafddd21..76d72f90 100644 --- a/apps/server/src/main/kotlin/com/correx/apps/server/memory/ArchitectContradictionChecker.kt +++ b/apps/server/src/main/kotlin/com/correx/apps/server/memory/ArchitectContradictionChecker.kt @@ -5,8 +5,8 @@ import com.correx.core.events.events.RelatedDecision import com.correx.core.events.types.SessionId import com.correx.core.events.types.StageId import com.correx.core.inference.Embedder -import com.correx.core.router.l3.L3MemoryStore -import com.correx.core.router.l3.L3Query +import com.correx.core.talkie.l3.L3MemoryStore +import com.correx.core.talkie.l3.L3Query /** * Display-only architect contradiction surfacing (BACKLOG §B-§4). When the architect records a diff --git a/apps/server/src/main/kotlin/com/correx/apps/server/memory/L3RepoKnowledgeRetriever.kt b/apps/server/src/main/kotlin/com/correx/apps/server/memory/L3RepoKnowledgeRetriever.kt index 57b738fb..5a817e1d 100644 --- a/apps/server/src/main/kotlin/com/correx/apps/server/memory/L3RepoKnowledgeRetriever.kt +++ b/apps/server/src/main/kotlin/com/correx/apps/server/memory/L3RepoKnowledgeRetriever.kt @@ -4,8 +4,8 @@ import com.correx.core.events.events.RepoKnowledgeHit import com.correx.core.events.types.SessionId import com.correx.core.inference.Embedder import com.correx.core.kernel.orchestration.RepoKnowledgeRetriever -import com.correx.core.router.l3.L3MemoryStore -import com.correx.core.router.l3.L3Query +import com.correx.core.talkie.l3.L3MemoryStore +import com.correx.core.talkie.l3.L3Query private const val RETRIEVAL_OVERSAMPLE_FACTOR = 4 diff --git a/apps/server/src/main/kotlin/com/correx/apps/server/memory/ProjectMemoryService.kt b/apps/server/src/main/kotlin/com/correx/apps/server/memory/ProjectMemoryService.kt index b55494d1..be7b6515 100644 --- a/apps/server/src/main/kotlin/com/correx/apps/server/memory/ProjectMemoryService.kt +++ b/apps/server/src/main/kotlin/com/correx/apps/server/memory/ProjectMemoryService.kt @@ -13,9 +13,9 @@ import com.correx.core.events.types.SessionId import com.correx.core.inference.Embedder import com.correx.core.journal.DefaultDecisionJournalRepository import com.correx.core.journal.ProjectMemoryDistiller -import com.correx.core.router.l3.L3MemoryEntry -import com.correx.core.router.l3.L3MemoryStore -import com.correx.core.router.l3.L3Query +import com.correx.core.talkie.l3.L3MemoryEntry +import com.correx.core.talkie.l3.L3MemoryStore +import com.correx.core.talkie.l3.L3Query import kotlinx.coroutines.CancellationException import kotlinx.datetime.Clock import org.slf4j.LoggerFactory diff --git a/apps/server/src/main/kotlin/com/correx/apps/server/narration/NarrationSubscriber.kt b/apps/server/src/main/kotlin/com/correx/apps/server/narration/NarrationSubscriber.kt index 09658eee..46bb794f 100644 --- a/apps/server/src/main/kotlin/com/correx/apps/server/narration/NarrationSubscriber.kt +++ b/apps/server/src/main/kotlin/com/correx/apps/server/narration/NarrationSubscriber.kt @@ -13,8 +13,8 @@ import com.correx.core.events.events.WorkflowFailedEvent import com.correx.core.events.events.WorkflowStartedEvent import com.correx.core.events.stores.EventStore import com.correx.core.events.types.SessionId -import com.correx.core.router.RouterFacade -import com.correx.core.router.model.NarrationTrigger +import com.correx.core.talkie.TalkieFacade +import com.correx.core.talkie.model.NarrationTrigger import kotlinx.coroutines.CancellationException import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.channels.Channel @@ -27,7 +27,7 @@ import java.util.concurrent.ConcurrentHashMap class NarrationSubscriber( private val eventStore: EventStore, - private val routerFacade: RouterFacade, + private val routerFacade: TalkieFacade, private val scope: CoroutineScope, private val maxPerRun: Int = DEFAULT_MAX_PER_RUN, ) { diff --git a/apps/server/src/main/kotlin/com/correx/apps/server/protocol/ClientMessage.kt b/apps/server/src/main/kotlin/com/correx/apps/server/protocol/ClientMessage.kt index f53c04b4..de592440 100644 --- a/apps/server/src/main/kotlin/com/correx/apps/server/protocol/ClientMessage.kt +++ b/apps/server/src/main/kotlin/com/correx/apps/server/protocol/ClientMessage.kt @@ -8,7 +8,7 @@ import com.correx.core.events.types.ClarificationRequestId import com.correx.core.events.types.GrantId import com.correx.core.events.types.SessionId import com.correx.core.events.types.StageId -import com.correx.core.router.ChatMode +import com.correx.core.talkie.ChatMode import kotlinx.datetime.Instant import kotlinx.serialization.Serializable diff --git a/apps/server/src/main/kotlin/com/correx/apps/server/protocol/ServerMessage.kt b/apps/server/src/main/kotlin/com/correx/apps/server/protocol/ServerMessage.kt index 32f08c91..7b3e3d85 100644 --- a/apps/server/src/main/kotlin/com/correx/apps/server/protocol/ServerMessage.kt +++ b/apps/server/src/main/kotlin/com/correx/apps/server/protocol/ServerMessage.kt @@ -562,7 +562,7 @@ sealed interface ServerMessage { @Serializable @SerialName("router.response") - data class RouterResponseMessage( + data class TalkieResponseMessage( val sessionId: SessionId, val content: String, val steeringEmitted: Boolean, diff --git a/apps/server/src/main/kotlin/com/correx/apps/server/ws/GlobalStreamHandler.kt b/apps/server/src/main/kotlin/com/correx/apps/server/ws/GlobalStreamHandler.kt index 4695ce40..fb69db9f 100644 --- a/apps/server/src/main/kotlin/com/correx/apps/server/ws/GlobalStreamHandler.kt +++ b/apps/server/src/main/kotlin/com/correx/apps/server/ws/GlobalStreamHandler.kt @@ -35,7 +35,7 @@ import com.correx.core.kernel.orchestration.WorkspaceContext import com.correx.core.config.ProjectProfileLoader import com.correx.core.config.ProjectProfileWriter import com.correx.core.config.withConvention -import com.correx.core.router.IdeaReader +import com.correx.core.talkie.IdeaReader import com.correx.core.utils.TypeId import com.correx.infrastructure.inference.commons.ResourceProbe import com.correx.infrastructure.inference.commons.ResourceSnapshot @@ -253,7 +253,7 @@ class GlobalStreamHandler(private val module: ServerModule) { is ClientMessage.ChatInput -> { // The USER and ROUTER turns are emitted as ChatTurnEvents inside onUserInput // and reach the client as chat.turn frames via streamGlobal — no direct - // RouterResponseMessage (the conversation is event-derived). + // TalkieResponseMessage (the conversation is event-derived). withSessionContext(msg.sessionId) { runCatching { module.routerFacade.onUserInput(msg.sessionId, msg.text, msg.mode) diff --git a/apps/server/src/main/kotlin/com/correx/apps/server/ws/SessionStreamHandler.kt b/apps/server/src/main/kotlin/com/correx/apps/server/ws/SessionStreamHandler.kt index 4c07d411..9167e972 100644 --- a/apps/server/src/main/kotlin/com/correx/apps/server/ws/SessionStreamHandler.kt +++ b/apps/server/src/main/kotlin/com/correx/apps/server/ws/SessionStreamHandler.kt @@ -6,7 +6,7 @@ import com.correx.apps.server.logging.withSessionContext import com.correx.apps.server.protocol.ClientMessage import com.correx.apps.server.protocol.ProtocolSerializer import com.correx.apps.server.protocol.ServerMessage -import com.correx.apps.server.protocol.ServerMessage.RouterResponseMessage +import com.correx.apps.server.protocol.ServerMessage.TalkieResponseMessage import com.correx.core.events.types.SessionId import io.ktor.server.websocket.DefaultWebSocketServerSession import io.ktor.websocket.Frame @@ -93,7 +93,7 @@ class SessionStreamHandler(private val module: ServerModule) { session.send( Frame.Text( ProtocolSerializer.encodeServerMessage( - RouterResponseMessage( + TalkieResponseMessage( sessionId = msg.sessionId, content = response.content, steeringEmitted = response.steeringEmitted, diff --git a/apps/server/src/main/kotlin/com/correx/apps/server/ws/StreamQueries.kt b/apps/server/src/main/kotlin/com/correx/apps/server/ws/StreamQueries.kt index c84c554b..7eb8652b 100644 --- a/apps/server/src/main/kotlin/com/correx/apps/server/ws/StreamQueries.kt +++ b/apps/server/src/main/kotlin/com/correx/apps/server/ws/StreamQueries.kt @@ -14,7 +14,7 @@ import com.correx.core.approvals.GRANT_LEDGER_SESSION_ID import com.correx.core.approvals.GrantScope import com.correx.core.approvals.ProjectIdentity import com.correx.core.events.types.ProjectId -import com.correx.core.router.IdeaReader +import com.correx.core.talkie.IdeaReader import com.correx.core.config.EditableConfig import com.correx.core.events.events.ArtifactContentStoredEvent import com.correx.core.events.events.ArtifactCreatedEvent diff --git a/apps/server/src/test/kotlin/com/correx/apps/server/ArchitectContradictionHookTest.kt b/apps/server/src/test/kotlin/com/correx/apps/server/ArchitectContradictionHookTest.kt index a07b3289..e31ab0ab 100644 --- a/apps/server/src/test/kotlin/com/correx/apps/server/ArchitectContradictionHookTest.kt +++ b/apps/server/src/test/kotlin/com/correx/apps/server/ArchitectContradictionHookTest.kt @@ -35,11 +35,11 @@ import com.correx.core.kernel.orchestration.OrchestratorEngines import com.correx.core.kernel.orchestration.OrchestratorRepositories import com.correx.core.kernel.retry.DefaultRetryCoordinator import com.correx.core.risk.DefaultRiskAssessor -import com.correx.core.router.l3.L3Hit -import com.correx.core.router.l3.L3MemoryEntry -import com.correx.core.router.l3.L3MemoryStore -import com.correx.core.router.l3.L3Query -import com.correx.core.router.model.RouterConfig +import com.correx.core.talkie.l3.L3Hit +import com.correx.core.talkie.l3.L3MemoryEntry +import com.correx.core.talkie.l3.L3MemoryStore +import com.correx.core.talkie.l3.L3Query +import com.correx.core.talkie.model.TalkieConfig import com.correx.core.sessions.DefaultSessionReducer import com.correx.core.sessions.DefaultSessionRepository import com.correx.core.sessions.SessionProjector @@ -182,10 +182,10 @@ class ArchitectContradictionHookTest { tokenizer = provider.tokenizer, decisionJournalRepository = InfrastructureModule.createDecisionJournalRepository(eventStore), ) - val routerFacade = InfrastructureModule.createRouterFacade( + val routerFacade = InfrastructureModule.createTalkieFacade( eventStore = eventStore, inferenceRouter = inferenceRouter, - config = RouterConfig(), + config = TalkieConfig(), tokenizer = provider.tokenizer, ) val noopProviderRegistry = object : ProviderRegistry { diff --git a/apps/server/src/test/kotlin/com/correx/apps/server/lifecycle/LifecycleTestSupport.kt b/apps/server/src/test/kotlin/com/correx/apps/server/lifecycle/LifecycleTestSupport.kt index 9418f022..cbe3315f 100644 --- a/apps/server/src/test/kotlin/com/correx/apps/server/lifecycle/LifecycleTestSupport.kt +++ b/apps/server/src/test/kotlin/com/correx/apps/server/lifecycle/LifecycleTestSupport.kt @@ -24,7 +24,7 @@ import com.correx.core.kernel.orchestration.OrchestratorEngines import com.correx.core.kernel.orchestration.OrchestratorRepositories import com.correx.core.kernel.retry.DefaultRetryCoordinator import com.correx.core.risk.DefaultRiskAssessor -import com.correx.core.router.model.RouterConfig +import com.correx.core.talkie.model.TalkieConfig import com.correx.core.sessions.DefaultSessionReducer import com.correx.core.sessions.DefaultSessionRepository import com.correx.core.sessions.SessionProjector @@ -116,10 +116,10 @@ fun buildTestServerModule( decisionJournalRepository = decisionJournalRepository, ) - val routerFacade = InfrastructureModule.createRouterFacade( + val routerFacade = InfrastructureModule.createTalkieFacade( eventStore = eventStore, inferenceRouter = modelSwapper, - config = RouterConfig(), + config = TalkieConfig(), tokenizer = firstProvider.tokenizer, ) diff --git a/apps/server/src/test/kotlin/com/correx/apps/server/memory/ArchitectContradictionCheckerTest.kt b/apps/server/src/test/kotlin/com/correx/apps/server/memory/ArchitectContradictionCheckerTest.kt index 36188d50..18ec8df6 100644 --- a/apps/server/src/test/kotlin/com/correx/apps/server/memory/ArchitectContradictionCheckerTest.kt +++ b/apps/server/src/test/kotlin/com/correx/apps/server/memory/ArchitectContradictionCheckerTest.kt @@ -3,10 +3,10 @@ package com.correx.apps.server.memory import com.correx.core.events.types.SessionId import com.correx.core.events.types.StageId import com.correx.core.inference.Embedder -import com.correx.core.router.l3.L3Hit -import com.correx.core.router.l3.L3MemoryEntry -import com.correx.core.router.l3.L3MemoryStore -import com.correx.core.router.l3.L3Query +import com.correx.core.talkie.l3.L3Hit +import com.correx.core.talkie.l3.L3MemoryEntry +import com.correx.core.talkie.l3.L3MemoryStore +import com.correx.core.talkie.l3.L3Query import kotlinx.coroutines.runBlocking import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Assertions.assertNull diff --git a/apps/server/src/test/kotlin/com/correx/apps/server/memory/L3RepoKnowledgeRetrieverTest.kt b/apps/server/src/test/kotlin/com/correx/apps/server/memory/L3RepoKnowledgeRetrieverTest.kt index 8db9c7d5..6d82f7e7 100644 --- a/apps/server/src/test/kotlin/com/correx/apps/server/memory/L3RepoKnowledgeRetrieverTest.kt +++ b/apps/server/src/test/kotlin/com/correx/apps/server/memory/L3RepoKnowledgeRetrieverTest.kt @@ -2,8 +2,8 @@ package com.correx.apps.server.memory import com.correx.core.events.types.SessionId import com.correx.core.inference.Embedder -import com.correx.core.router.l3.InMemoryL3MemoryStore -import com.correx.core.router.l3.L3MemoryEntry +import com.correx.core.talkie.l3.InMemoryL3MemoryStore +import com.correx.core.talkie.l3.L3MemoryEntry import kotlinx.coroutines.runBlocking import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Test diff --git a/apps/server/src/test/kotlin/com/correx/apps/server/memory/ProjectMemoryServiceObservationTest.kt b/apps/server/src/test/kotlin/com/correx/apps/server/memory/ProjectMemoryServiceObservationTest.kt index 8f07aa8a..846457e0 100644 --- a/apps/server/src/test/kotlin/com/correx/apps/server/memory/ProjectMemoryServiceObservationTest.kt +++ b/apps/server/src/test/kotlin/com/correx/apps/server/memory/ProjectMemoryServiceObservationTest.kt @@ -10,7 +10,7 @@ import com.correx.core.inference.Embedder import com.correx.core.journal.DecisionJournalProjector import com.correx.core.journal.DefaultDecisionJournalReducer import com.correx.core.journal.DefaultDecisionJournalRepository -import com.correx.core.router.l3.InMemoryL3MemoryStore +import com.correx.core.talkie.l3.InMemoryL3MemoryStore import com.correx.core.sessions.projections.replay.DefaultEventReplayer import com.correx.infrastructure.persistence.InMemoryEventStore import kotlinx.coroutines.runBlocking diff --git a/apps/server/src/test/kotlin/com/correx/apps/server/memory/ProjectMemoryServiceReuseTest.kt b/apps/server/src/test/kotlin/com/correx/apps/server/memory/ProjectMemoryServiceReuseTest.kt index ae3e6652..fd478d53 100644 --- a/apps/server/src/test/kotlin/com/correx/apps/server/memory/ProjectMemoryServiceReuseTest.kt +++ b/apps/server/src/test/kotlin/com/correx/apps/server/memory/ProjectMemoryServiceReuseTest.kt @@ -6,7 +6,7 @@ import com.correx.core.inference.Embedder import com.correx.core.journal.DecisionJournalProjector import com.correx.core.journal.DefaultDecisionJournalReducer import com.correx.core.journal.DefaultDecisionJournalRepository -import com.correx.core.router.l3.InMemoryL3MemoryStore +import com.correx.core.talkie.l3.InMemoryL3MemoryStore import com.correx.core.sessions.projections.replay.DefaultEventReplayer import com.correx.core.events.types.SessionId import com.correx.infrastructure.persistence.InMemoryEventStore diff --git a/apps/server/src/test/kotlin/com/correx/apps/server/memory/ProjectMemoryServiceTest.kt b/apps/server/src/test/kotlin/com/correx/apps/server/memory/ProjectMemoryServiceTest.kt index 29012032..6b12555c 100644 --- a/apps/server/src/test/kotlin/com/correx/apps/server/memory/ProjectMemoryServiceTest.kt +++ b/apps/server/src/test/kotlin/com/correx/apps/server/memory/ProjectMemoryServiceTest.kt @@ -13,7 +13,7 @@ import com.correx.core.inference.Embedder import com.correx.core.journal.DecisionJournalProjector import com.correx.core.journal.DefaultDecisionJournalReducer import com.correx.core.journal.DefaultDecisionJournalRepository -import com.correx.core.router.l3.InMemoryL3MemoryStore +import com.correx.core.talkie.l3.InMemoryL3MemoryStore import com.correx.core.sessions.projections.replay.DefaultEventReplayer import com.correx.infrastructure.persistence.InMemoryEventStore import kotlinx.coroutines.runBlocking diff --git a/apps/server/src/test/kotlin/com/correx/apps/server/narration/NarrationSubscriberTest.kt b/apps/server/src/test/kotlin/com/correx/apps/server/narration/NarrationSubscriberTest.kt index c5f198ab..b946dfdf 100644 --- a/apps/server/src/test/kotlin/com/correx/apps/server/narration/NarrationSubscriberTest.kt +++ b/apps/server/src/test/kotlin/com/correx/apps/server/narration/NarrationSubscriberTest.kt @@ -25,10 +25,10 @@ import com.correx.core.events.types.StageId import com.correx.core.events.types.TransitionId import com.correx.core.events.types.ValidationReportId import org.junit.jupiter.api.Assertions.assertTrue -import com.correx.core.router.ChatMode -import com.correx.core.router.RouterFacade -import com.correx.core.router.model.NarrationTrigger -import com.correx.core.router.model.RouterResponse +import com.correx.core.talkie.ChatMode +import com.correx.core.talkie.TalkieFacade +import com.correx.core.talkie.model.NarrationTrigger +import com.correx.core.talkie.model.TalkieResponse import kotlinx.coroutines.CompletableDeferred import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -72,10 +72,10 @@ class NarrationSubscriberTest { override suspend fun lastGlobalSequence(): Long = 0L } - private class RecordingRouterFacade : RouterFacade { + private class RecordingTalkieFacade : TalkieFacade { val calls = CopyOnWriteArrayList>() - override suspend fun onUserInput(sessionId: SessionId, input: String, mode: ChatMode): RouterResponse = + override suspend fun onUserInput(sessionId: SessionId, input: String, mode: ChatMode): TalkieResponse = error("unused in narration tests") override suspend fun narrate(sessionId: SessionId, trigger: NarrationTrigger) { @@ -99,7 +99,7 @@ class NarrationSubscriberTest { @Test fun `triggers are narrated in order for matching events`(): Unit = runBlocking { - val facade = RecordingRouterFacade() + val facade = RecordingTalkieFacade() NarrationSubscriber(fakeStore, facade, scope).start() // Wait for subscription to be attached @@ -122,7 +122,7 @@ class NarrationSubscriberTest { @Test fun `pause narration is grounded with the pending approval tool and preview`(): Unit = runBlocking { - val facade = RecordingRouterFacade() + val facade = RecordingTalkieFacade() NarrationSubscriber(fakeStore, facade, scope).start() while (liveFlow.subscriptionCount.value == 0) yield() @@ -158,7 +158,7 @@ class NarrationSubscriberTest { @Test fun `maxPerRun=1 skips second trigger after first narration`(): Unit = runBlocking { - val facade = RecordingRouterFacade() + val facade = RecordingTalkieFacade() NarrationSubscriber(fakeStore, facade, scope, maxPerRun = 1).start() while (liveFlow.subscriptionCount.value == 0) yield() @@ -180,10 +180,10 @@ class NarrationSubscriberTest { @Test fun `a throwing narrate does not prevent subsequent narrations`(): Unit = runBlocking { var callCount = 0 - val facade = object : RouterFacade { + val facade = object : TalkieFacade { val calls = CopyOnWriteArrayList() - override suspend fun onUserInput(sessionId: SessionId, input: String, mode: ChatMode): RouterResponse = + override suspend fun onUserInput(sessionId: SessionId, input: String, mode: ChatMode): TalkieResponse = error("unused") override suspend fun narrate(sessionId: SessionId, trigger: NarrationTrigger) { @@ -210,7 +210,7 @@ class NarrationSubscriberTest { @Test fun `execution plan rejection triggers narration with rejection reason`(): Unit = runBlocking { - val facade = RecordingRouterFacade() + val facade = RecordingTalkieFacade() NarrationSubscriber(fakeStore, facade, scope).start() while (liveFlow.subscriptionCount.value == 0) yield() @@ -244,7 +244,7 @@ class NarrationSubscriberTest { * letting the test enqueue further events (and resolve the pause) while the pause narration is * still pending in the channel. */ - private class GatingRouterFacade : RouterFacade { + private class GatingTalkieFacade : TalkieFacade { val calls = CopyOnWriteArrayList() val release = CompletableDeferred() // Signals that the worker has pulled the first (warmup) trigger and is now blocked, @@ -252,7 +252,7 @@ class NarrationSubscriberTest { val blocked = CompletableDeferred() private var first = true - override suspend fun onUserInput(sessionId: SessionId, input: String, mode: ChatMode): RouterResponse = + override suspend fun onUserInput(sessionId: SessionId, input: String, mode: ChatMode): TalkieResponse = error("unused in narration tests") override suspend fun narrate(sessionId: SessionId, trigger: NarrationTrigger) { @@ -289,7 +289,7 @@ class NarrationSubscriberTest { @Test fun `resolved approval drops the still-queued pause narration`(): Unit = runBlocking { - val facade = GatingRouterFacade() + val facade = GatingTalkieFacade() NarrationSubscriber(fakeStore, facade, scope).start() while (liveFlow.subscriptionCount.value == 0) yield() @@ -320,7 +320,7 @@ class NarrationSubscriberTest { @Test fun `unrelated approval resolution leaves the pending pause intact`(): Unit = runBlocking { - val facade = GatingRouterFacade() + val facade = GatingTalkieFacade() NarrationSubscriber(fakeStore, facade, scope).start() while (liveFlow.subscriptionCount.value == 0) yield() @@ -342,7 +342,7 @@ class NarrationSubscriberTest { @Test fun `resume drops every queued pause narration for the session`(): Unit = runBlocking { - val facade = GatingRouterFacade() + val facade = GatingTalkieFacade() NarrationSubscriber(fakeStore, facade, scope).start() while (liveFlow.subscriptionCount.value == 0) yield() diff --git a/apps/server/src/test/kotlin/com/correx/apps/server/routes/EventInspectRoutesTest.kt b/apps/server/src/test/kotlin/com/correx/apps/server/routes/EventInspectRoutesTest.kt index 57e3aebd..6c8c27a4 100644 --- a/apps/server/src/test/kotlin/com/correx/apps/server/routes/EventInspectRoutesTest.kt +++ b/apps/server/src/test/kotlin/com/correx/apps/server/routes/EventInspectRoutesTest.kt @@ -33,7 +33,7 @@ import com.correx.core.kernel.orchestration.OrchestratorRepositories import com.correx.core.kernel.retry.DefaultRetryCoordinator import com.correx.core.events.types.ProviderId import com.correx.core.risk.DefaultRiskAssessor -import com.correx.core.router.model.RouterConfig +import com.correx.core.talkie.model.TalkieConfig import com.correx.core.sessions.DefaultSessionReducer import com.correx.core.sessions.DefaultSessionRepository import com.correx.core.sessions.SessionProjector @@ -165,10 +165,10 @@ class EventInspectRoutesTest { tokenizer = provider.tokenizer, decisionJournalRepository = InfrastructureModule.createDecisionJournalRepository(eventStore), ) - val routerFacade = InfrastructureModule.createRouterFacade( + val routerFacade = InfrastructureModule.createTalkieFacade( eventStore = eventStore, inferenceRouter = inferenceRouter, - config = RouterConfig(), + config = TalkieConfig(), tokenizer = provider.tokenizer, ) val noopProviderRegistry = object : ProviderRegistry { diff --git a/apps/server/src/test/kotlin/com/correx/apps/server/routes/TaskRoutesTest.kt b/apps/server/src/test/kotlin/com/correx/apps/server/routes/TaskRoutesTest.kt index 7f97789c..70f0b353 100644 --- a/apps/server/src/test/kotlin/com/correx/apps/server/routes/TaskRoutesTest.kt +++ b/apps/server/src/test/kotlin/com/correx/apps/server/routes/TaskRoutesTest.kt @@ -26,7 +26,7 @@ import com.correx.core.kernel.orchestration.OrchestratorRepositories import com.correx.core.kernel.retry.DefaultRetryCoordinator import com.correx.core.events.types.ProviderId import com.correx.core.risk.DefaultRiskAssessor -import com.correx.core.router.model.RouterConfig +import com.correx.core.talkie.model.TalkieConfig import com.correx.core.sessions.DefaultSessionReducer import com.correx.core.sessions.DefaultSessionRepository import com.correx.core.sessions.SessionProjector @@ -444,10 +444,10 @@ class TaskRoutesTest { tokenizer = provider.tokenizer, decisionJournalRepository = InfrastructureModule.createDecisionJournalRepository(eventStore), ) - val routerFacade = InfrastructureModule.createRouterFacade( + val routerFacade = InfrastructureModule.createTalkieFacade( eventStore = eventStore, inferenceRouter = inferenceRouter, - config = RouterConfig(), + config = TalkieConfig(), tokenizer = provider.tokenizer, ) val noopProviderRegistry = object : ProviderRegistry { diff --git a/apps/server/src/test/kotlin/com/correx/apps/server/ws/WorkspaceHandshakeTest.kt b/apps/server/src/test/kotlin/com/correx/apps/server/ws/WorkspaceHandshakeTest.kt index 398341a5..08c11ab3 100644 --- a/apps/server/src/test/kotlin/com/correx/apps/server/ws/WorkspaceHandshakeTest.kt +++ b/apps/server/src/test/kotlin/com/correx/apps/server/ws/WorkspaceHandshakeTest.kt @@ -186,10 +186,10 @@ class WorkspaceHandshakeTest { decisionJournalRepository = InfrastructureModule.createDecisionJournalRepository(eventStore), ) - val routerFacade = InfrastructureModule.createRouterFacade( + val routerFacade = InfrastructureModule.createTalkieFacade( eventStore = eventStore, inferenceRouter = inferenceRouter, - config = com.correx.core.router.model.RouterConfig(), + config = com.correx.core.talkie.model.TalkieConfig(), tokenizer = provider.tokenizer, ) diff --git a/core/config/src/main/kotlin/com/correx/core/config/ConfigLoader.kt b/core/config/src/main/kotlin/com/correx/core/config/ConfigLoader.kt index 66b8cfbe..41a8a674 100644 --- a/core/config/src/main/kotlin/com/correx/core/config/ConfigLoader.kt +++ b/core/config/src/main/kotlin/com/correx/core/config/ConfigLoader.kt @@ -418,14 +418,14 @@ object ConfigLoader { val toolsFileReadSection = sections["tools.file_read"] ?: emptyMap() val toolsFileWriteSection = sections["tools.file_write"] ?: emptyMap() val toolsFileEditSection = sections["tools.file_edit"] ?: emptyMap() - val routerSection = sections["router"] ?: emptyMap() + val routerSection = sections["talkie"] ?: sections["router"] ?: emptyMap() // Embedder + L3 are shared infra (the orchestrator uses them for workflow repo-knowledge, // not just the router chat layer). Prefer the top-level [embedder]/[l3] sections; fall back // to the legacy [router.embedder]/[router.l3] so existing configs keep working. val routerEmbedderSection = sections["embedder"] ?: sections["router.embedder"] ?: emptyMap() val routerL3Section = sections["l3"] ?: sections["router.l3"] ?: emptyMap() - val routerGenerationSection = sections["router.generation"] ?: emptyMap() - val routerNarrationSection = sections["router.narration"] ?: emptyMap() + val routerGenerationSection = sections["talkie.generation"] ?: sections["router.generation"] ?: emptyMap() + val routerNarrationSection = sections["talkie.narration"] ?: sections["router.narration"] ?: emptyMap() val modelsSection = sections["models"] ?: emptyMap() val server = ServerConfig( @@ -575,7 +575,7 @@ object ConfigLoader { modelId = asStringOrNull(routerNarrationSection["model_id"]), ) - val router = RouterConfig( + val router = TalkieConfig( embedder = embedder, l3 = l3, conversationKeepLast = asInt(routerSection["conversation_keep_last"], 6), @@ -655,7 +655,7 @@ object ConfigLoader { cli = cli, tools = tools, providers = providers, - router = router, + talkie = router, models = models, modelsSettings = modelsSettings, artifacts = artifacts, diff --git a/core/config/src/main/kotlin/com/correx/core/config/CorrexConfig.kt b/core/config/src/main/kotlin/com/correx/core/config/CorrexConfig.kt index aa33010e..04fe4060 100644 --- a/core/config/src/main/kotlin/com/correx/core/config/CorrexConfig.kt +++ b/core/config/src/main/kotlin/com/correx/core/config/CorrexConfig.kt @@ -9,7 +9,7 @@ data class CorrexConfig( val cli: CliConfig = CliConfig(), val tools: ToolsConfig = ToolsConfig(), val providers: List = emptyList(), - val router: RouterConfig = RouterConfig(), + val talkie: TalkieConfig = TalkieConfig(), val models: List = emptyList(), val modelsSettings: ModelsSettings = ModelsSettings(), val artifacts: List = emptyList(), @@ -189,7 +189,7 @@ data class ProviderConfig( ) @Serializable -data class RouterConfig( +data class TalkieConfig( val embedder: EmbedderConfig = EmbedderConfig(), val l3: L3Config = L3Config(), val conversationKeepLast: Int = 6, diff --git a/core/config/src/main/kotlin/com/correx/core/config/CorrexConfigWriter.kt b/core/config/src/main/kotlin/com/correx/core/config/CorrexConfigWriter.kt index bbfd5e68..0ffe77af 100644 --- a/core/config/src/main/kotlin/com/correx/core/config/CorrexConfigWriter.kt +++ b/core/config/src/main/kotlin/com/correx/core/config/CorrexConfigWriter.kt @@ -51,36 +51,36 @@ object CorrexConfigWriter { b.section("tools.file_edit") b.kv("enabled", cfg.tools.fileEditEnabled) - b.section("router") - b.kv("conversation_keep_last", cfg.router.conversationKeepLast) - b.kv("retrieval_k", cfg.router.retrievalK) - b.kv("token_budget", cfg.router.tokenBudget) + b.section("talkie") + b.kv("conversation_keep_last", cfg.talkie.conversationKeepLast) + b.kv("retrieval_k", cfg.talkie.retrievalK) + b.kv("token_budget", cfg.talkie.tokenBudget) b.section("embedder") - b.kv("backend", str(cfg.router.embedder.backend)) - b.kv("dimension", cfg.router.embedder.dimension) - cfg.router.embedder.url?.let { b.kv("url", str(it)) } - cfg.router.embedder.modelId?.let { b.kv("model_id", str(it)) } + b.kv("backend", str(cfg.talkie.embedder.backend)) + b.kv("dimension", cfg.talkie.embedder.dimension) + cfg.talkie.embedder.url?.let { b.kv("url", str(it)) } + cfg.talkie.embedder.modelId?.let { b.kv("model_id", str(it)) } b.section("l3") - b.kv("backend", str(cfg.router.l3.backend)) - cfg.router.l3.persistPath?.let { b.kv("persist_path", str(it)) } - b.kv("python_executable", str(cfg.router.l3.pythonExecutable)) - cfg.router.l3.scriptPath?.let { b.kv("script_path", str(it)) } - b.kv("dim", cfg.router.l3.dim) - b.kv("bit_width", cfg.router.l3.bitWidth) + b.kv("backend", str(cfg.talkie.l3.backend)) + cfg.talkie.l3.persistPath?.let { b.kv("persist_path", str(it)) } + b.kv("python_executable", str(cfg.talkie.l3.pythonExecutable)) + cfg.talkie.l3.scriptPath?.let { b.kv("script_path", str(it)) } + b.kv("dim", cfg.talkie.l3.dim) + b.kv("bit_width", cfg.talkie.l3.bitWidth) - b.section("router.generation") - b.kv("temperature", cfg.router.generation.temperature) - b.kv("top_p", cfg.router.generation.topP) - b.kv("max_tokens", cfg.router.generation.maxTokens) + b.section("talkie.generation") + b.kv("temperature", cfg.talkie.generation.temperature) + b.kv("top_p", cfg.talkie.generation.topP) + b.kv("max_tokens", cfg.talkie.generation.maxTokens) - b.section("router.narration") - b.kv("temperature", cfg.router.narration.temperature) - b.kv("top_p", cfg.router.narration.topP) - b.kv("max_tokens", cfg.router.narration.maxTokens) - b.kv("max_per_run", cfg.router.narration.maxPerRun) - cfg.router.narration.modelId?.let { b.kv("model_id", str(it)) } + b.section("talkie.narration") + b.kv("temperature", cfg.talkie.narration.temperature) + b.kv("top_p", cfg.talkie.narration.topP) + b.kv("max_tokens", cfg.talkie.narration.maxTokens) + b.kv("max_per_run", cfg.talkie.narration.maxPerRun) + cfg.talkie.narration.modelId?.let { b.kv("model_id", str(it)) } b.section("orchestration") b.kv("stage_timeout_ms", cfg.orchestration.stageTimeoutMs) diff --git a/core/config/src/main/kotlin/com/correx/core/config/EditableConfig.kt b/core/config/src/main/kotlin/com/correx/core/config/EditableConfig.kt index 979b3484..fee6b5b9 100644 --- a/core/config/src/main/kotlin/com/correx/core/config/EditableConfig.kt +++ b/core/config/src/main/kotlin/com/correx/core/config/EditableConfig.kt @@ -87,57 +87,57 @@ object EditableConfig { ), EditableField( "router.conversation_keep_last", ConfigFieldType.INT, - getString = { it.router.conversationKeepLast.toString() }, + getString = { it.talkie.conversationKeepLast.toString() }, withString = { c, v -> rtr(c) { it.copy(conversationKeepLast = int("router.conversation_keep_last", v)) } }, ), EditableField( "router.retrieval_k", ConfigFieldType.INT, - getString = { it.router.retrievalK.toString() }, + getString = { it.talkie.retrievalK.toString() }, withString = { c, v -> rtr(c) { it.copy(retrievalK = int("router.retrieval_k", v)) } }, ), EditableField( "router.token_budget", ConfigFieldType.INT, - getString = { it.router.tokenBudget.toString() }, + getString = { it.talkie.tokenBudget.toString() }, withString = { c, v -> rtr(c) { it.copy(tokenBudget = int("router.token_budget", v)) } }, ), EditableField( "router.generation.temperature", ConfigFieldType.DOUBLE, - getString = { it.router.generation.temperature.toString() }, + getString = { it.talkie.generation.temperature.toString() }, withString = { c, v -> gen(c) { it.copy(temperature = dbl("router.generation.temperature", v)) } }, ), EditableField( "router.generation.top_p", ConfigFieldType.DOUBLE, - getString = { it.router.generation.topP.toString() }, + getString = { it.talkie.generation.topP.toString() }, withString = { c, v -> gen(c) { it.copy(topP = dbl("router.generation.top_p", v)) } }, ), EditableField( "router.generation.max_tokens", ConfigFieldType.INT, - getString = { it.router.generation.maxTokens.toString() }, + getString = { it.talkie.generation.maxTokens.toString() }, withString = { c, v -> gen(c) { it.copy(maxTokens = int("router.generation.max_tokens", v)) } }, ), EditableField( "router.narration.temperature", ConfigFieldType.DOUBLE, - getString = { it.router.narration.temperature.toString() }, + getString = { it.talkie.narration.temperature.toString() }, withString = { c, v -> nar(c) { it.copy(temperature = dbl("router.narration.temperature", v)) } }, ), EditableField( "router.narration.top_p", ConfigFieldType.DOUBLE, - getString = { it.router.narration.topP.toString() }, + getString = { it.talkie.narration.topP.toString() }, withString = { c, v -> nar(c) { it.copy(topP = dbl("router.narration.top_p", v)) } }, ), EditableField( "router.narration.max_tokens", ConfigFieldType.INT, - getString = { it.router.narration.maxTokens.toString() }, + getString = { it.talkie.narration.maxTokens.toString() }, withString = { c, v -> nar(c) { it.copy(maxTokens = int("router.narration.max_tokens", v)) } }, ), EditableField( "router.narration.max_per_run", ConfigFieldType.INT, - getString = { it.router.narration.maxPerRun.toString() }, + getString = { it.talkie.narration.maxPerRun.toString() }, withString = { c, v -> nar(c) { it.copy(maxPerRun = int("router.narration.max_per_run", v)) } }, ), EditableField( "router.narration.model_id", ConfigFieldType.STRING, - getString = { it.router.narration.modelId.orEmpty() }, + getString = { it.talkie.narration.modelId.orEmpty() }, withString = { c, v -> nar(c) { it.copy(modelId = v.trim().ifBlank { null }) } }, ), EditableField( @@ -215,7 +215,7 @@ private fun srv(c: CorrexConfig, f: (ServerConfig) -> ServerConfig) = c.copy(ser private fun tui(c: CorrexConfig, f: (TuiConfig) -> TuiConfig) = c.copy(tui = f(c.tui)) private fun cli(c: CorrexConfig, f: (CliConfig) -> CliConfig) = c.copy(cli = f(c.cli)) private fun tls(c: CorrexConfig, f: (ToolsConfig) -> ToolsConfig) = c.copy(tools = f(c.tools)) -private fun rtr(c: CorrexConfig, f: (RouterConfig) -> RouterConfig) = c.copy(router = f(c.router)) +private fun rtr(c: CorrexConfig, f: (TalkieConfig) -> TalkieConfig) = c.copy(talkie = f(c.talkie)) private fun gen(c: CorrexConfig, f: (GenerationSettings) -> GenerationSettings) = rtr(c) { it.copy(generation = f(it.generation)) } private fun nar(c: CorrexConfig, f: (NarrationSettings) -> NarrationSettings) = diff --git a/core/config/src/test/kotlin/com/correx/core/config/ConfigLoaderTest.kt b/core/config/src/test/kotlin/com/correx/core/config/ConfigLoaderTest.kt index 47f13725..305c0724 100644 --- a/core/config/src/test/kotlin/com/correx/core/config/ConfigLoaderTest.kt +++ b/core/config/src/test/kotlin/com/correx/core/config/ConfigLoaderTest.kt @@ -307,16 +307,16 @@ class ConfigLoaderTest { parseTomlMethod.isAccessible = true val result = parseTomlMethod.invoke(ConfigLoader, toml) as CorrexConfig - assertEquals("llamacpp", result.router.embedder.backend) - assertEquals(1536, result.router.embedder.dimension) - assertEquals("http://localhost:11000", result.router.embedder.url) - assertEquals("nomic-embed-text", result.router.embedder.modelId) + assertEquals("llamacpp", result.talkie.embedder.backend) + assertEquals(1536, result.talkie.embedder.dimension) + assertEquals("http://localhost:11000", result.talkie.embedder.url) + assertEquals("nomic-embed-text", result.talkie.embedder.modelId) - assertEquals("turbovec", result.router.l3.backend) - assertEquals("/tmp/router/l3.tq", result.router.l3.persistPath) - assertEquals("python3", result.router.l3.pythonExecutable) - assertEquals(1536, result.router.l3.dim) - assertEquals(4, result.router.l3.bitWidth) + assertEquals("turbovec", result.talkie.l3.backend) + assertEquals("/tmp/router/l3.tq", result.talkie.l3.persistPath) + assertEquals("python3", result.talkie.l3.pythonExecutable) + assertEquals(1536, result.talkie.l3.dim) + assertEquals(4, result.talkie.l3.bitWidth) } @Test @@ -331,16 +331,16 @@ class ConfigLoaderTest { parseTomlMethod.isAccessible = true val result = parseTomlMethod.invoke(ConfigLoader, toml) as CorrexConfig - assertEquals("noop", result.router.embedder.backend) - assertEquals(1536, result.router.embedder.dimension) - assertEquals(null, result.router.embedder.url) - assertEquals(null, result.router.embedder.modelId) + assertEquals("noop", result.talkie.embedder.backend) + assertEquals(1536, result.talkie.embedder.dimension) + assertEquals(null, result.talkie.embedder.url) + assertEquals(null, result.talkie.embedder.modelId) - assertEquals("in_memory", result.router.l3.backend) - assertEquals(null, result.router.l3.persistPath) - assertEquals("python3", result.router.l3.pythonExecutable) - assertEquals(1536, result.router.l3.dim) - assertEquals(4, result.router.l3.bitWidth) + assertEquals("in_memory", result.talkie.l3.backend) + assertEquals(null, result.talkie.l3.persistPath) + assertEquals("python3", result.talkie.l3.pythonExecutable) + assertEquals(1536, result.talkie.l3.dim) + assertEquals(4, result.talkie.l3.bitWidth) } @Test @@ -477,15 +477,15 @@ class ConfigLoaderTest { parseTomlMethod.isAccessible = true val result = parseTomlMethod.invoke(ConfigLoader, toml) as CorrexConfig - assertEquals(8, result.router.conversationKeepLast) - assertEquals(3, result.router.retrievalK) - assertEquals(8192, result.router.tokenBudget) - assertEquals(0.4, result.router.generation.temperature) - assertEquals(0.8, result.router.generation.topP) - assertEquals(600, result.router.generation.maxTokens) - assertEquals(0.55, result.router.narration.temperature) - assertEquals(2048, result.router.narration.maxTokens) - assertEquals(25, result.router.narration.maxPerRun) + assertEquals(8, result.talkie.conversationKeepLast) + assertEquals(3, result.talkie.retrievalK) + assertEquals(8192, result.talkie.tokenBudget) + assertEquals(0.4, result.talkie.generation.temperature) + assertEquals(0.8, result.talkie.generation.topP) + assertEquals(600, result.talkie.generation.maxTokens) + assertEquals(0.55, result.talkie.narration.temperature) + assertEquals(2048, result.talkie.narration.maxTokens) + assertEquals(25, result.talkie.narration.maxPerRun) } @Test @@ -494,10 +494,10 @@ class ConfigLoaderTest { parseTomlMethod.isAccessible = true val result = parseTomlMethod.invoke(ConfigLoader, "[server]\nhost = \"x\"") as CorrexConfig - assertEquals(6, result.router.conversationKeepLast) - assertEquals(512, result.router.generation.maxTokens) - assertEquals(4096, result.router.narration.maxTokens) - assertEquals(100, result.router.narration.maxPerRun) + assertEquals(6, result.talkie.conversationKeepLast) + assertEquals(512, result.talkie.generation.maxTokens) + assertEquals(4096, result.talkie.narration.maxTokens) + assertEquals(100, result.talkie.narration.maxPerRun) } @Test @@ -530,7 +530,7 @@ class ConfigLoaderTest { val result = ConfigLoader.parseTomlForTest(toml) - assertEquals("llama-cpp:phi-3-mini", result.router.narration.modelId) + assertEquals("llama-cpp:phi-3-mini", result.talkie.narration.modelId) } @Test @@ -542,6 +542,6 @@ class ConfigLoaderTest { val result = ConfigLoader.parseTomlForTest(toml) - assertNull(result.router.narration.modelId) + assertNull(result.talkie.narration.modelId) } } diff --git a/core/config/src/test/kotlin/com/correx/core/config/CorrexConfigWriterTest.kt b/core/config/src/test/kotlin/com/correx/core/config/CorrexConfigWriterTest.kt index 5bd23570..c89d57e0 100644 --- a/core/config/src/test/kotlin/com/correx/core/config/CorrexConfigWriterTest.kt +++ b/core/config/src/test/kotlin/com/correx/core/config/CorrexConfigWriterTest.kt @@ -26,7 +26,7 @@ class CorrexConfigWriterTest { shellAllowedExecutables = listOf("git", "ls"), networkAllowedHosts = listOf("example.com"), ), - router = RouterConfig( + talkie = TalkieConfig( conversationKeepLast = 7, retrievalK = 4, tokenBudget = 5000, diff --git a/core/config/src/test/kotlin/com/correx/core/config/EditableConfigTest.kt b/core/config/src/test/kotlin/com/correx/core/config/EditableConfigTest.kt index 11e6f1e8..53643cdf 100644 --- a/core/config/src/test/kotlin/com/correx/core/config/EditableConfigTest.kt +++ b/core/config/src/test/kotlin/com/correx/core/config/EditableConfigTest.kt @@ -25,7 +25,7 @@ class EditableConfigTest { CorrexConfig(), mapOf("router.generation.temperature" to "0.25", "orchestration.stage_timeout_ms" to "90000"), ).getOrThrow() - assertEquals(0.25, out.router.generation.temperature) + assertEquals(0.25, out.talkie.generation.temperature) assertEquals(90_000L, out.orchestration.stageTimeoutMs) } diff --git a/core/events/src/main/kotlin/com/correx/core/events/events/RouterEvents.kt b/core/events/src/main/kotlin/com/correx/core/events/events/TalkieEvents.kt similarity index 97% rename from core/events/src/main/kotlin/com/correx/core/events/events/RouterEvents.kt rename to core/events/src/main/kotlin/com/correx/core/events/events/TalkieEvents.kt index c6b438ff..af8b276d 100644 --- a/core/events/src/main/kotlin/com/correx/core/events/events/RouterEvents.kt +++ b/core/events/src/main/kotlin/com/correx/core/events/events/TalkieEvents.kt @@ -53,7 +53,7 @@ data class ContextTruncatedEvent( @Serializable @SerialName("RouterNarration") -data class RouterNarrationEvent( +data class TalkieNarrationEvent( val sessionId: SessionId, val narrationId: String, val trigger: String, diff --git a/core/events/src/main/kotlin/com/correx/core/events/serialization/Serialization.kt b/core/events/src/main/kotlin/com/correx/core/events/serialization/Serialization.kt index 9f07ba22..3e9a8b89 100644 --- a/core/events/src/main/kotlin/com/correx/core/events/serialization/Serialization.kt +++ b/core/events/src/main/kotlin/com/correx/core/events/serialization/Serialization.kt @@ -20,7 +20,7 @@ import com.correx.core.events.events.ClarificationRequestedEvent import com.correx.core.events.events.ChatTurnEvent import com.correx.core.events.events.CritiqueFindingsRecordedEvent import com.correx.core.events.events.CritiqueOutcomeCorrelatedEvent -import com.correx.core.events.events.RouterNarrationEvent +import com.correx.core.events.events.TalkieNarrationEvent import com.correx.core.events.events.OperatorProfileBoundEvent import com.correx.core.events.events.ProjectProfileBoundEvent import com.correx.core.events.events.SessionWorkspaceBoundEvent @@ -147,7 +147,7 @@ val eventModule = SerializersModule { subclass(ChatSessionStartedEvent::class) subclass(SessionWorkingTaskEvent::class) subclass(ChatTurnEvent::class) - subclass(RouterNarrationEvent::class) + subclass(TalkieNarrationEvent::class) subclass(SessionWorkspaceBoundEvent::class) subclass(OperatorProfileBoundEvent::class) subclass(ProjectProfileBoundEvent::class) diff --git a/core/events/src/test/kotlin/com/correx/core/events/serialization/RouterNarrationEventSerializationTest.kt b/core/events/src/test/kotlin/com/correx/core/events/serialization/TalkieNarrationEventSerializationTest.kt similarity index 79% rename from core/events/src/test/kotlin/com/correx/core/events/serialization/RouterNarrationEventSerializationTest.kt rename to core/events/src/test/kotlin/com/correx/core/events/serialization/TalkieNarrationEventSerializationTest.kt index fbc55490..789652c2 100644 --- a/core/events/src/test/kotlin/com/correx/core/events/serialization/RouterNarrationEventSerializationTest.kt +++ b/core/events/src/test/kotlin/com/correx/core/events/serialization/TalkieNarrationEventSerializationTest.kt @@ -1,16 +1,16 @@ package com.correx.core.events.serialization import com.correx.core.events.events.EventPayload -import com.correx.core.events.events.RouterNarrationEvent +import com.correx.core.events.events.TalkieNarrationEvent import com.correx.core.events.types.SessionId import com.correx.core.inference.TokenUsage import kotlin.test.Test import kotlin.test.assertEquals import kotlin.test.assertTrue -class RouterNarrationEventSerializationTest { +class TalkieNarrationEventSerializationTest { - private val sample = RouterNarrationEvent( + private val sample = TalkieNarrationEvent( sessionId = SessionId("sess-1"), narrationId = "narr-42", trigger = "stage_start", @@ -24,6 +24,8 @@ class RouterNarrationEventSerializationTest { @Test fun `round-trips as polymorphic EventPayload`() { val encoded = eventJson.encodeToString(EventPayload.serializer(), sample) + // Wire discriminator is intentionally still "RouterNarration": the class was renamed + // Router->Talkie, but changing a persisted @SerialName would break replay of existing logs. assertTrue(encoded.contains("\"type\":\"RouterNarration\""), "SerialName must be present: $encoded") val decoded = eventJson.decodeFromString(EventPayload.serializer(), encoded) assertEquals(sample, decoded) @@ -31,7 +33,7 @@ class RouterNarrationEventSerializationTest { @Test fun `round-trips with optional fields absent`() { - val minimal = RouterNarrationEvent( + val minimal = TalkieNarrationEvent( sessionId = SessionId("sess-2"), narrationId = "narr-0", trigger = "manual", diff --git a/core/router/src/main/kotlin/com/correx/core/router/RouterProjector.kt b/core/router/src/main/kotlin/com/correx/core/router/RouterProjector.kt deleted file mode 100644 index 844d9676..00000000 --- a/core/router/src/main/kotlin/com/correx/core/router/RouterProjector.kt +++ /dev/null @@ -1,15 +0,0 @@ -package com.correx.core.router - -import com.correx.core.events.events.StoredEvent -import com.correx.core.router.model.RouterState -import com.correx.core.sessions.projections.Projection - -class RouterProjector( - private val reducer: RouterReducer, -) : Projection { - - override fun initial(): RouterState = reducer.initial - - override fun apply(state: RouterState, event: StoredEvent): RouterState = - reducer.reduce(state, event) -} diff --git a/core/router/src/main/kotlin/com/correx/core/router/RouterRepository.kt b/core/router/src/main/kotlin/com/correx/core/router/RouterRepository.kt deleted file mode 100644 index aa687e17..00000000 --- a/core/router/src/main/kotlin/com/correx/core/router/RouterRepository.kt +++ /dev/null @@ -1,16 +0,0 @@ -package com.correx.core.router - -import com.correx.core.events.types.SessionId -import com.correx.core.router.model.RouterState -import com.correx.core.sessions.projections.replay.EventReplayer - -interface RouterRepository { - suspend fun getRouterState(sessionId: SessionId): RouterState -} - -class DefaultRouterRepository( - private val replayer: EventReplayer, -) : RouterRepository { - override suspend fun getRouterState(sessionId: SessionId): RouterState = - replayer.rebuild(sessionId) -} diff --git a/core/router/AGENTS.md b/core/talkie/AGENTS.md similarity index 100% rename from core/router/AGENTS.md rename to core/talkie/AGENTS.md diff --git a/core/router/build.gradle b/core/talkie/build.gradle similarity index 100% rename from core/router/build.gradle rename to core/talkie/build.gradle diff --git a/core/router/src/main/kotlin/com/correx/core/router/IdeaReader.kt b/core/talkie/src/main/kotlin/com/correx/core/talkie/IdeaReader.kt similarity index 96% rename from core/router/src/main/kotlin/com/correx/core/router/IdeaReader.kt rename to core/talkie/src/main/kotlin/com/correx/core/talkie/IdeaReader.kt index d724c88a..d24755c2 100644 --- a/core/router/src/main/kotlin/com/correx/core/router/IdeaReader.kt +++ b/core/talkie/src/main/kotlin/com/correx/core/talkie/IdeaReader.kt @@ -1,11 +1,11 @@ -package com.correx.core.router +package com.correx.core.talkie import com.correx.core.events.events.IdeaCapturedEvent import com.correx.core.events.events.IdeaDiscardedEvent import com.correx.core.events.events.IdeaPromotedEvent import com.correx.core.events.stores.EventStore import com.correx.core.events.types.SessionId -import com.correx.core.router.model.Idea +import com.correx.core.talkie.model.Idea /** * Rebuilds the operator's idea board from the event log. Cross-session by design: it folds over diff --git a/core/router/src/main/kotlin/com/correx/core/router/Ideas.kt b/core/talkie/src/main/kotlin/com/correx/core/talkie/Ideas.kt similarity index 98% rename from core/router/src/main/kotlin/com/correx/core/router/Ideas.kt rename to core/talkie/src/main/kotlin/com/correx/core/talkie/Ideas.kt index fda44e0a..baaa22a9 100644 --- a/core/router/src/main/kotlin/com/correx/core/router/Ideas.kt +++ b/core/talkie/src/main/kotlin/com/correx/core/talkie/Ideas.kt @@ -1,4 +1,4 @@ -package com.correx.core.router +package com.correx.core.talkie import kotlinx.serialization.json.Json import kotlinx.serialization.json.JsonObject diff --git a/core/router/src/main/kotlin/com/correx/core/router/RouterContextBuilder.kt b/core/talkie/src/main/kotlin/com/correx/core/talkie/TalkieContextBuilder.kt similarity index 96% rename from core/router/src/main/kotlin/com/correx/core/router/RouterContextBuilder.kt rename to core/talkie/src/main/kotlin/com/correx/core/talkie/TalkieContextBuilder.kt index e35fef3e..dc76a70d 100644 --- a/core/router/src/main/kotlin/com/correx/core/router/RouterContextBuilder.kt +++ b/core/talkie/src/main/kotlin/com/correx/core/talkie/TalkieContextBuilder.kt @@ -1,4 +1,4 @@ -package com.correx.core.router +package com.correx.core.talkie import com.correx.core.context.model.CompressionMetadata import com.correx.core.context.model.ContextEntry @@ -11,20 +11,20 @@ import com.correx.core.events.types.ContextPackId import com.correx.core.events.types.SessionId import com.correx.core.events.types.StageId import com.correx.core.inference.Tokenizer -import com.correx.core.router.model.Idea -import com.correx.core.router.model.NarrationTrigger -import com.correx.core.router.model.RouterConfig -import com.correx.core.router.model.RouterL2Entry -import com.correx.core.router.model.RouterState -import com.correx.core.router.model.RouterTurn -import com.correx.core.router.model.TurnRole -import com.correx.core.router.model.WorkflowSummary +import com.correx.core.talkie.model.Idea +import com.correx.core.talkie.model.NarrationTrigger +import com.correx.core.talkie.model.TalkieConfig +import com.correx.core.talkie.model.RouterL2Entry +import com.correx.core.talkie.model.TalkieState +import com.correx.core.talkie.model.TalkieTurn +import com.correx.core.talkie.model.TurnRole +import com.correx.core.talkie.model.WorkflowSummary import java.util.* import kotlinx.coroutines.CancellationException -interface RouterContextBuilder { +interface TalkieContextBuilder { suspend fun build( - state: RouterState, + state: TalkieState, budget: TokenBudget, availableWorkflows: List = emptyList(), projectProfileText: String? = null, @@ -38,18 +38,18 @@ interface RouterContextBuilder { * Default delegates to [build] so that anonymous test stubs that only override [build] compile * without needing a stub override. */ - suspend fun buildNarrationContext(state: RouterState, trigger: NarrationTrigger, budget: TokenBudget): ContextPack = + suspend fun buildNarrationContext(state: TalkieState, trigger: NarrationTrigger, budget: TokenBudget): ContextPack = build(state, budget, emptyList(), null) } -class DefaultRouterContextBuilder( - private val config: RouterConfig, +class DefaultTalkieContextBuilder( + private val config: TalkieConfig, private val tokenizer: Tokenizer? = null, // Cross-session ideas to surface to the router (router-only context). Read fresh each build so // newly-captured ideas appear on the next turn; injected via the constructor so the build() // interface — and its many test doubles — stay unchanged. private val ideaProvider: () -> List = { emptyList() }, -) : RouterContextBuilder { +) : TalkieContextBuilder { companion object { private val SYSTEM_PROMPT = @@ -106,7 +106,7 @@ class DefaultRouterContextBuilder( } override suspend fun build( - state: RouterState, + state: TalkieState, budget: TokenBudget, availableWorkflows: List, projectProfileText: String?, @@ -179,7 +179,7 @@ class DefaultRouterContextBuilder( // --- Conversation turns (L1) --- // The current (protected) user turn is the last element in conversationHistory, // regardless of conversationKeepLast — it must always be present. - val protectedUserTurn: RouterTurn? = state.conversationHistory.lastOrNull() + val protectedUserTurn: TalkieTurn? = state.conversationHistory.lastOrNull() // Apply conversationKeepLast cap. The protected turn may or may not fall within this window. val cappedTurns = state.conversationHistory.takeLast(config.conversationKeepLast) @@ -317,7 +317,7 @@ class DefaultRouterContextBuilder( ) } - private fun buildWorkflowStatusContent(state: RouterState, stageOverride: String? = null): String { + private fun buildWorkflowStatusContent(state: TalkieState, stageOverride: String? = null): String { val status = capitalizeFirst(state.workflowStatus.name.lowercase()) val stage = stageOverride ?: state.currentStageId?.value ?: "none" return "Status: $status, Stage: $stage" @@ -400,7 +400,7 @@ class DefaultRouterContextBuilder( * narration lines never enter the conversation flow. */ override suspend fun buildNarrationContext( - state: RouterState, + state: TalkieState, trigger: NarrationTrigger, budget: TokenBudget, ): ContextPack { diff --git a/core/router/src/main/kotlin/com/correx/core/router/RouterFacade.kt b/core/talkie/src/main/kotlin/com/correx/core/talkie/TalkieFacade.kt similarity index 93% rename from core/router/src/main/kotlin/com/correx/core/router/RouterFacade.kt rename to core/talkie/src/main/kotlin/com/correx/core/talkie/TalkieFacade.kt index 8051e712..3b27af9f 100644 --- a/core/router/src/main/kotlin/com/correx/core/router/RouterFacade.kt +++ b/core/talkie/src/main/kotlin/com/correx/core/talkie/TalkieFacade.kt @@ -1,4 +1,4 @@ -package com.correx.core.router +package com.correx.core.talkie import com.correx.core.events.events.ChatTurnEvent import com.correx.core.events.events.ChatTurnRole @@ -8,7 +8,7 @@ import com.correx.core.events.events.IdeaCapturedEvent import com.correx.core.events.events.L3MemoryRetrievedEvent import com.correx.core.events.events.L3RetrievedHit import com.correx.core.events.events.NewEvent -import com.correx.core.events.events.RouterNarrationEvent +import com.correx.core.events.events.TalkieNarrationEvent import com.correx.core.events.events.SteeringNoteAddedEvent import com.correx.core.events.events.WorkflowProposedEvent import com.correx.core.events.stores.EventStore @@ -23,53 +23,53 @@ import com.correx.core.inference.InferenceRouter import com.correx.core.inference.ModelCapability import com.correx.core.inference.ResponseFormat import com.correx.core.inference.TokenUsage -import com.correx.core.router.l3.L3MemoryEntry -import com.correx.core.router.l3.L3MemoryStore -import com.correx.core.router.l3.L3Query -import com.correx.core.router.model.NarrationTrigger -import com.correx.core.router.model.RouterConfig -import com.correx.core.router.model.RouterResponse -import com.correx.core.router.model.WorkflowSummary +import com.correx.core.talkie.l3.L3MemoryEntry +import com.correx.core.talkie.l3.L3MemoryStore +import com.correx.core.talkie.l3.L3Query +import com.correx.core.talkie.model.NarrationTrigger +import com.correx.core.talkie.model.TalkieConfig +import com.correx.core.talkie.model.TalkieResponse +import com.correx.core.talkie.model.WorkflowSummary import kotlinx.coroutines.CancellationException import kotlinx.datetime.Clock import org.slf4j.LoggerFactory import java.util.UUID -private val log = LoggerFactory.getLogger(DefaultRouterFacade::class.java) +private val log = LoggerFactory.getLogger(DefaultTalkieFacade::class.java) -interface RouterFacade { +interface TalkieFacade { suspend fun onUserInput( sessionId: SessionId, input: String, mode: ChatMode = ChatMode.CHAT, - ): RouterResponse + ): TalkieResponse suspend fun narrate(sessionId: SessionId, trigger: NarrationTrigger) } -class DefaultRouterFacade( - private val routerRepository: RouterRepository, - private val routerContextBuilder: RouterContextBuilder, +class DefaultTalkieFacade( + private val routerRepository: TalkieRepository, + private val routerContextBuilder: TalkieContextBuilder, private val inferenceRouter: InferenceRouter, private val eventStore: EventStore, - private val config: RouterConfig, + private val config: TalkieConfig, private val validateSteering: (suspend (String) -> String?)? = null, private val embedder: Embedder, private val l3MemoryStore: L3MemoryStore, private val workflowSummaryProvider: () -> List = { emptyList() }, private val sessionProfileProvider: suspend (SessionId) -> String? = { null }, -) : RouterFacade { +) : TalkieFacade { override suspend fun onUserInput( sessionId: SessionId, input: String, mode: ChatMode, - ): RouterResponse { + ): TalkieResponse { // Emit USER turn event and get the turnId for retrieval dedup val userTurnId = emitChatTurn(sessionId, input, ChatTurnRole.USER) // Rebuild state with user turn appended - var state = routerRepository.getRouterState(sessionId) + var state = routerRepository.getTalkieState(sessionId) val effectiveStageId = state.currentStageId ?: StageId.NONE // L3 retrieval — non-fatal; results fed back into state via event. @@ -119,7 +119,7 @@ class DefaultRouterFacade( ), ) // Rebuild state so lastRetrievedMemory reflects this turn - state = routerRepository.getRouterState(sessionId) + state = routerRepository.getTalkieState(sessionId) val contextPack = routerContextBuilder.build(state, config.tokenBudget, workflowSummaryProvider(), sessionProfileProvider(sessionId)) @@ -199,11 +199,11 @@ class DefaultRouterFacade( } } - return RouterResponse(content = content, steeringEmitted = steeringEmitted) + return TalkieResponse(content = content, steeringEmitted = steeringEmitted) } override suspend fun narrate(sessionId: SessionId, trigger: NarrationTrigger) { - val state = routerRepository.getRouterState(sessionId) + val state = routerRepository.getTalkieState(sessionId) val effectiveStageId = trigger.stageId?.let { StageId(it) } ?: state.currentStageId ?: StageId.NONE val contextPack = routerContextBuilder.buildNarrationContext(state, trigger, config.tokenBudget) @@ -234,7 +234,7 @@ class DefaultRouterFacade( causationId = null, correlationId = null, ), - payload = RouterNarrationEvent( + payload = TalkieNarrationEvent( sessionId = sessionId, narrationId = narrationId, trigger = trigger.kind, diff --git a/core/talkie/src/main/kotlin/com/correx/core/talkie/TalkieProjector.kt b/core/talkie/src/main/kotlin/com/correx/core/talkie/TalkieProjector.kt new file mode 100644 index 00000000..c0b213cb --- /dev/null +++ b/core/talkie/src/main/kotlin/com/correx/core/talkie/TalkieProjector.kt @@ -0,0 +1,15 @@ +package com.correx.core.talkie + +import com.correx.core.events.events.StoredEvent +import com.correx.core.talkie.model.TalkieState +import com.correx.core.sessions.projections.Projection + +class TalkieProjector( + private val reducer: TalkieReducer, +) : Projection { + + override fun initial(): TalkieState = reducer.initial + + override fun apply(state: TalkieState, event: StoredEvent): TalkieState = + reducer.reduce(state, event) +} diff --git a/core/router/src/main/kotlin/com/correx/core/router/RouterReducer.kt b/core/talkie/src/main/kotlin/com/correx/core/talkie/TalkieReducer.kt similarity index 75% rename from core/router/src/main/kotlin/com/correx/core/router/RouterReducer.kt rename to core/talkie/src/main/kotlin/com/correx/core/talkie/TalkieReducer.kt index ec6282b9..ca924502 100644 --- a/core/router/src/main/kotlin/com/correx/core/router/RouterReducer.kt +++ b/core/talkie/src/main/kotlin/com/correx/core/talkie/TalkieReducer.kt @@ -1,4 +1,4 @@ -package com.correx.core.router +package com.correx.core.talkie import com.correx.core.events.events.ChatTurnEvent import com.correx.core.events.events.L3MemoryRetrievedEvent @@ -11,22 +11,22 @@ import com.correx.core.events.events.StoredEvent import com.correx.core.events.events.WorkflowCompletedEvent import com.correx.core.events.events.WorkflowFailedEvent import com.correx.core.events.events.WorkflowStartedEvent -import com.correx.core.router.model.RouterL2Entry -import com.correx.core.router.model.RouterState -import com.correx.core.router.model.RouterTurn -import com.correx.core.router.model.StageOutcomeKind -import com.correx.core.router.model.TurnRole -import com.correx.core.router.model.WorkflowStatus +import com.correx.core.talkie.model.RouterL2Entry +import com.correx.core.talkie.model.TalkieState +import com.correx.core.talkie.model.TalkieTurn +import com.correx.core.talkie.model.StageOutcomeKind +import com.correx.core.talkie.model.TurnRole +import com.correx.core.talkie.model.WorkflowStatus import kotlinx.datetime.Instant -interface RouterReducer { - val initial: RouterState - fun reduce(state: RouterState, event: StoredEvent): RouterState +interface TalkieReducer { + val initial: TalkieState + fun reduce(state: TalkieState, event: StoredEvent): TalkieState } -class DefaultRouterReducer : RouterReducer { +class DefaultTalkieReducer : TalkieReducer { - override val initial: RouterState = RouterState( + override val initial: TalkieState = TalkieState( sessionId = null, workflowStatus = WorkflowStatus.IDLE, currentStageId = null, @@ -34,7 +34,7 @@ class DefaultRouterReducer : RouterReducer { conversationHistory = emptyList(), ) - override fun reduce(state: RouterState, event: StoredEvent): RouterState { + override fun reduce(state: TalkieState, event: StoredEvent): TalkieState { return when (val payload = event.payload) { is WorkflowStartedEvent -> handleWorkflowStarted(state, event) is WorkflowCompletedEvent -> handleWorkflowCompleted(state) @@ -50,7 +50,7 @@ class DefaultRouterReducer : RouterReducer { } } - private fun handleWorkflowStarted(state: RouterState, event: StoredEvent): RouterState { + private fun handleWorkflowStarted(state: TalkieState, event: StoredEvent): TalkieState { val payload = event.payload as WorkflowStartedEvent return state.copy( sessionId = payload.sessionId, @@ -59,33 +59,33 @@ class DefaultRouterReducer : RouterReducer { ) } - private fun handleWorkflowCompleted(state: RouterState): RouterState { + private fun handleWorkflowCompleted(state: TalkieState): TalkieState { return state.copy( workflowStatus = WorkflowStatus.COMPLETED, currentStageId = null ) } - private fun handleWorkflowFailed(state: RouterState): RouterState { + private fun handleWorkflowFailed(state: TalkieState): TalkieState { return state.copy( workflowStatus = WorkflowStatus.FAILED, currentStageId = null ) } - private fun handleOrchestrationPaused(state: RouterState): RouterState { + private fun handleOrchestrationPaused(state: TalkieState): TalkieState { return state.copy( workflowStatus = WorkflowStatus.PAUSED ) } - private fun handleOrchestrationResumed(state: RouterState): RouterState { + private fun handleOrchestrationResumed(state: TalkieState): TalkieState { return state.copy( workflowStatus = WorkflowStatus.RUNNING ) } - private fun handleStageCompleted(state: RouterState, event: StoredEvent): RouterState { + private fun handleStageCompleted(state: TalkieState, event: StoredEvent): TalkieState { val payload = event.payload as StageCompletedEvent val entry = RouterL2Entry( stageId = payload.stageId, @@ -100,7 +100,7 @@ class DefaultRouterReducer : RouterReducer { ) } - private fun handleStageFailed(state: RouterState, event: StoredEvent): RouterState { + private fun handleStageFailed(state: TalkieState, event: StoredEvent): TalkieState { val payload = event.payload as StageFailedEvent val entry = RouterL2Entry( stageId = payload.stageId, @@ -120,16 +120,16 @@ class DefaultRouterReducer : RouterReducer { // adr-0003 §4: harvest user steering into the current stage's decision point. // Accumulate here; handleStageCompleted/Failed attach and clear. Pure field // extraction from the event stream — no inference. - private fun handleSteeringNote(state: RouterState, payload: SteeringNoteAddedEvent): RouterState = + private fun handleSteeringNote(state: TalkieState, payload: SteeringNoteAddedEvent): TalkieState = state.copy(pendingSteeringNotes = state.pendingSteeringNotes + payload.content) - private fun handleChatTurn(state: RouterState, event: StoredEvent): RouterState { + private fun handleChatTurn(state: TalkieState, event: StoredEvent): TalkieState { val payload = event.payload as ChatTurnEvent val turnRole = when (payload.role) { com.correx.core.events.events.ChatTurnRole.USER -> TurnRole.USER com.correx.core.events.events.ChatTurnRole.ROUTER -> TurnRole.ROUTER } - val turn = RouterTurn( + val turn = TalkieTurn( role = turnRole, content = payload.content, timestamp = Instant.fromEpochMilliseconds(payload.timestampMs), diff --git a/core/talkie/src/main/kotlin/com/correx/core/talkie/TalkieRepository.kt b/core/talkie/src/main/kotlin/com/correx/core/talkie/TalkieRepository.kt new file mode 100644 index 00000000..4c8baa77 --- /dev/null +++ b/core/talkie/src/main/kotlin/com/correx/core/talkie/TalkieRepository.kt @@ -0,0 +1,16 @@ +package com.correx.core.talkie + +import com.correx.core.events.types.SessionId +import com.correx.core.talkie.model.TalkieState +import com.correx.core.sessions.projections.replay.EventReplayer + +interface TalkieRepository { + suspend fun getTalkieState(sessionId: SessionId): TalkieState +} + +class DefaultTalkieRepository( + private val replayer: EventReplayer, +) : TalkieRepository { + override suspend fun getTalkieState(sessionId: SessionId): TalkieState = + replayer.rebuild(sessionId) +} diff --git a/core/router/src/main/kotlin/com/correx/core/router/WorkflowProposals.kt b/core/talkie/src/main/kotlin/com/correx/core/talkie/WorkflowProposals.kt similarity index 98% rename from core/router/src/main/kotlin/com/correx/core/router/WorkflowProposals.kt rename to core/talkie/src/main/kotlin/com/correx/core/talkie/WorkflowProposals.kt index 2927f99b..554f6843 100644 --- a/core/router/src/main/kotlin/com/correx/core/router/WorkflowProposals.kt +++ b/core/talkie/src/main/kotlin/com/correx/core/talkie/WorkflowProposals.kt @@ -1,4 +1,4 @@ -package com.correx.core.router +package com.correx.core.talkie import com.correx.core.events.events.ProposedWorkflow import kotlinx.serialization.json.Json diff --git a/core/router/src/main/kotlin/com/correx/core/router/l3/InMemoryL3MemoryStore.kt b/core/talkie/src/main/kotlin/com/correx/core/talkie/l3/InMemoryL3MemoryStore.kt similarity index 98% rename from core/router/src/main/kotlin/com/correx/core/router/l3/InMemoryL3MemoryStore.kt rename to core/talkie/src/main/kotlin/com/correx/core/talkie/l3/InMemoryL3MemoryStore.kt index 4ed7df66..65a6243e 100644 --- a/core/router/src/main/kotlin/com/correx/core/router/l3/InMemoryL3MemoryStore.kt +++ b/core/talkie/src/main/kotlin/com/correx/core/talkie/l3/InMemoryL3MemoryStore.kt @@ -1,4 +1,4 @@ -package com.correx.core.router.l3 +package com.correx.core.talkie.l3 import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock diff --git a/core/router/src/main/kotlin/com/correx/core/router/l3/L3Hit.kt b/core/talkie/src/main/kotlin/com/correx/core/talkie/l3/L3Hit.kt similarity index 79% rename from core/router/src/main/kotlin/com/correx/core/router/l3/L3Hit.kt rename to core/talkie/src/main/kotlin/com/correx/core/talkie/l3/L3Hit.kt index 77a7d2f5..3666c4de 100644 --- a/core/router/src/main/kotlin/com/correx/core/router/l3/L3Hit.kt +++ b/core/talkie/src/main/kotlin/com/correx/core/talkie/l3/L3Hit.kt @@ -1,4 +1,4 @@ -package com.correx.core.router.l3 +package com.correx.core.talkie.l3 import kotlinx.serialization.Serializable diff --git a/core/router/src/main/kotlin/com/correx/core/router/l3/L3MemoryEntry.kt b/core/talkie/src/main/kotlin/com/correx/core/talkie/l3/L3MemoryEntry.kt similarity index 97% rename from core/router/src/main/kotlin/com/correx/core/router/l3/L3MemoryEntry.kt rename to core/talkie/src/main/kotlin/com/correx/core/talkie/l3/L3MemoryEntry.kt index 5e658d45..fb53352f 100644 --- a/core/router/src/main/kotlin/com/correx/core/router/l3/L3MemoryEntry.kt +++ b/core/talkie/src/main/kotlin/com/correx/core/talkie/l3/L3MemoryEntry.kt @@ -1,4 +1,4 @@ -package com.correx.core.router.l3 +package com.correx.core.talkie.l3 import com.correx.core.events.types.SessionId import kotlinx.serialization.Serializable diff --git a/core/router/src/main/kotlin/com/correx/core/router/l3/L3MemoryStore.kt b/core/talkie/src/main/kotlin/com/correx/core/talkie/l3/L3MemoryStore.kt similarity index 95% rename from core/router/src/main/kotlin/com/correx/core/router/l3/L3MemoryStore.kt rename to core/talkie/src/main/kotlin/com/correx/core/talkie/l3/L3MemoryStore.kt index b3777302..ced27ae6 100644 --- a/core/router/src/main/kotlin/com/correx/core/router/l3/L3MemoryStore.kt +++ b/core/talkie/src/main/kotlin/com/correx/core/talkie/l3/L3MemoryStore.kt @@ -1,4 +1,4 @@ -package com.correx.core.router.l3 +package com.correx.core.talkie.l3 /** * Cross-session memory store interface for vector-based retrieval. diff --git a/core/router/src/main/kotlin/com/correx/core/router/l3/L3MetadataRehydrator.kt b/core/talkie/src/main/kotlin/com/correx/core/talkie/l3/L3MetadataRehydrator.kt similarity index 97% rename from core/router/src/main/kotlin/com/correx/core/router/l3/L3MetadataRehydrator.kt rename to core/talkie/src/main/kotlin/com/correx/core/talkie/l3/L3MetadataRehydrator.kt index b9e63939..d7b57869 100644 --- a/core/router/src/main/kotlin/com/correx/core/router/l3/L3MetadataRehydrator.kt +++ b/core/talkie/src/main/kotlin/com/correx/core/talkie/l3/L3MetadataRehydrator.kt @@ -1,4 +1,4 @@ -package com.correx.core.router.l3 +package com.correx.core.talkie.l3 import com.correx.core.events.events.ChatTurnEvent import com.correx.core.events.stores.EventStore diff --git a/core/router/src/main/kotlin/com/correx/core/router/l3/L3Query.kt b/core/talkie/src/main/kotlin/com/correx/core/talkie/l3/L3Query.kt similarity index 96% rename from core/router/src/main/kotlin/com/correx/core/router/l3/L3Query.kt rename to core/talkie/src/main/kotlin/com/correx/core/talkie/l3/L3Query.kt index 3ac4d550..c249d8b7 100644 --- a/core/router/src/main/kotlin/com/correx/core/router/l3/L3Query.kt +++ b/core/talkie/src/main/kotlin/com/correx/core/talkie/l3/L3Query.kt @@ -1,4 +1,4 @@ -package com.correx.core.router.l3 +package com.correx.core.talkie.l3 import com.correx.core.events.types.SessionId import kotlinx.serialization.Serializable diff --git a/core/router/src/main/kotlin/com/correx/core/router/l3/RehydratableL3MemoryStore.kt b/core/talkie/src/main/kotlin/com/correx/core/talkie/l3/RehydratableL3MemoryStore.kt similarity index 96% rename from core/router/src/main/kotlin/com/correx/core/router/l3/RehydratableL3MemoryStore.kt rename to core/talkie/src/main/kotlin/com/correx/core/talkie/l3/RehydratableL3MemoryStore.kt index 9597e5e3..1bd10ae2 100644 --- a/core/router/src/main/kotlin/com/correx/core/router/l3/RehydratableL3MemoryStore.kt +++ b/core/talkie/src/main/kotlin/com/correx/core/talkie/l3/RehydratableL3MemoryStore.kt @@ -1,4 +1,4 @@ -package com.correx.core.router.l3 +package com.correx.core.talkie.l3 /** * An [L3MemoryStore] whose vectors persist independently of the JVM (e.g. a diff --git a/core/router/src/main/kotlin/com/correx/core/router/model/Idea.kt b/core/talkie/src/main/kotlin/com/correx/core/talkie/model/Idea.kt similarity index 83% rename from core/router/src/main/kotlin/com/correx/core/router/model/Idea.kt rename to core/talkie/src/main/kotlin/com/correx/core/talkie/model/Idea.kt index 8f2318e5..3ec9c6c4 100644 --- a/core/router/src/main/kotlin/com/correx/core/router/model/Idea.kt +++ b/core/talkie/src/main/kotlin/com/correx/core/talkie/model/Idea.kt @@ -1,4 +1,4 @@ -package com.correx.core.router.model +package com.correx.core.talkie.model /** An active idea on the operator's cross-session scratchpad (a captured, not-yet-discarded note). */ data class Idea( diff --git a/core/router/src/main/kotlin/com/correx/core/router/model/NarrationTrigger.kt b/core/talkie/src/main/kotlin/com/correx/core/talkie/model/NarrationTrigger.kt similarity index 88% rename from core/router/src/main/kotlin/com/correx/core/router/model/NarrationTrigger.kt rename to core/talkie/src/main/kotlin/com/correx/core/talkie/model/NarrationTrigger.kt index f4ab1b38..ccb65615 100644 --- a/core/router/src/main/kotlin/com/correx/core/router/model/NarrationTrigger.kt +++ b/core/talkie/src/main/kotlin/com/correx/core/talkie/model/NarrationTrigger.kt @@ -1,9 +1,9 @@ -package com.correx.core.router.model +package com.correx.core.talkie.model /** * Describes the event or condition that prompted a narration inference call. * - * The trigger is stored verbatim in [RouterNarrationEvent.trigger] so it can be + * The trigger is stored verbatim in [TalkieNarrationEvent.trigger] so it can be * replayed and displayed without re-querying the environment. */ data class NarrationTrigger( diff --git a/core/router/src/main/kotlin/com/correx/core/router/model/RouterConfig.kt b/core/talkie/src/main/kotlin/com/correx/core/talkie/model/TalkieConfig.kt similarity index 94% rename from core/router/src/main/kotlin/com/correx/core/router/model/RouterConfig.kt rename to core/talkie/src/main/kotlin/com/correx/core/talkie/model/TalkieConfig.kt index c757aed6..c62d5cf1 100644 --- a/core/router/src/main/kotlin/com/correx/core/router/model/RouterConfig.kt +++ b/core/talkie/src/main/kotlin/com/correx/core/talkie/model/TalkieConfig.kt @@ -1,11 +1,11 @@ -package com.correx.core.router.model +package com.correx.core.talkie.model import com.correx.core.context.model.TokenBudget import com.correx.core.inference.GenerationConfig import kotlinx.serialization.Serializable @Serializable -data class RouterConfig( +data class TalkieConfig( val conversationKeepLast: Int = 6, val retrievalK: Int = 5, val tokenBudget: TokenBudget = TokenBudget(limit = 4096), diff --git a/core/router/src/main/kotlin/com/correx/core/router/model/RouterResponse.kt b/core/talkie/src/main/kotlin/com/correx/core/talkie/model/TalkieResponse.kt similarity index 66% rename from core/router/src/main/kotlin/com/correx/core/router/model/RouterResponse.kt rename to core/talkie/src/main/kotlin/com/correx/core/talkie/model/TalkieResponse.kt index 96708f01..2c5573f3 100644 --- a/core/router/src/main/kotlin/com/correx/core/router/model/RouterResponse.kt +++ b/core/talkie/src/main/kotlin/com/correx/core/talkie/model/TalkieResponse.kt @@ -1,9 +1,9 @@ -package com.correx.core.router.model +package com.correx.core.talkie.model import kotlinx.serialization.Serializable @Serializable -data class RouterResponse( +data class TalkieResponse( val content: String, val steeringEmitted: Boolean = false, ) diff --git a/core/router/src/main/kotlin/com/correx/core/router/model/RouterState.kt b/core/talkie/src/main/kotlin/com/correx/core/talkie/model/TalkieState.kt similarity index 91% rename from core/router/src/main/kotlin/com/correx/core/router/model/RouterState.kt rename to core/talkie/src/main/kotlin/com/correx/core/talkie/model/TalkieState.kt index 39382ea1..e2f26a70 100644 --- a/core/router/src/main/kotlin/com/correx/core/router/model/RouterState.kt +++ b/core/talkie/src/main/kotlin/com/correx/core/talkie/model/TalkieState.kt @@ -1,4 +1,4 @@ -package com.correx.core.router.model +package com.correx.core.talkie.model import com.correx.core.events.events.L3RetrievedHit import com.correx.core.events.types.SessionId @@ -41,7 +41,7 @@ data class RouterL2Entry( ) @Serializable -data class RouterTurn( +data class TalkieTurn( val role: TurnRole, val content: String, val timestamp: Instant, @@ -49,12 +49,12 @@ data class RouterTurn( ) @Serializable -data class RouterState( +data class TalkieState( val sessionId: SessionId? = null, val workflowStatus: WorkflowStatus = WorkflowStatus.IDLE, val currentStageId: StageId? = null, val l2Memory: List = emptyList(), - val conversationHistory: List = emptyList(), + val conversationHistory: List = emptyList(), val lastRetrievedMemory: List = emptyList(), /** * Steering notes accumulated during the current stage, harvested into the diff --git a/core/router/src/main/kotlin/com/correx/core/router/model/WorkflowSummary.kt b/core/talkie/src/main/kotlin/com/correx/core/talkie/model/WorkflowSummary.kt similarity index 75% rename from core/router/src/main/kotlin/com/correx/core/router/model/WorkflowSummary.kt rename to core/talkie/src/main/kotlin/com/correx/core/talkie/model/WorkflowSummary.kt index 711be304..2bf25034 100644 --- a/core/router/src/main/kotlin/com/correx/core/router/model/WorkflowSummary.kt +++ b/core/talkie/src/main/kotlin/com/correx/core/talkie/model/WorkflowSummary.kt @@ -1,4 +1,4 @@ -package com.correx.core.router.model +package com.correx.core.talkie.model data class WorkflowSummary( val id: String, diff --git a/core/router/src/test/kotlin/com/correx/core/router/IdeaReaderTest.kt b/core/talkie/src/test/kotlin/com/correx/core/talkie/IdeaReaderTest.kt similarity index 99% rename from core/router/src/test/kotlin/com/correx/core/router/IdeaReaderTest.kt rename to core/talkie/src/test/kotlin/com/correx/core/talkie/IdeaReaderTest.kt index 0a48ae10..03ed8dc9 100644 --- a/core/router/src/test/kotlin/com/correx/core/router/IdeaReaderTest.kt +++ b/core/talkie/src/test/kotlin/com/correx/core/talkie/IdeaReaderTest.kt @@ -1,4 +1,4 @@ -package com.correx.core.router +package com.correx.core.talkie import com.correx.core.events.events.EventMetadata import com.correx.core.events.events.EventPayload diff --git a/core/router/src/test/kotlin/com/correx/core/router/IdeasTest.kt b/core/talkie/src/test/kotlin/com/correx/core/talkie/IdeasTest.kt similarity index 98% rename from core/router/src/test/kotlin/com/correx/core/router/IdeasTest.kt rename to core/talkie/src/test/kotlin/com/correx/core/talkie/IdeasTest.kt index 12f76ad6..2904920a 100644 --- a/core/router/src/test/kotlin/com/correx/core/router/IdeasTest.kt +++ b/core/talkie/src/test/kotlin/com/correx/core/talkie/IdeasTest.kt @@ -1,4 +1,4 @@ -package com.correx.core.router +package com.correx.core.talkie import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Assertions.assertTrue diff --git a/core/router/src/test/kotlin/com/correx/core/router/WorkflowProposalsTest.kt b/core/talkie/src/test/kotlin/com/correx/core/talkie/WorkflowProposalsTest.kt similarity index 98% rename from core/router/src/test/kotlin/com/correx/core/router/WorkflowProposalsTest.kt rename to core/talkie/src/test/kotlin/com/correx/core/talkie/WorkflowProposalsTest.kt index 9e16ed10..652b7302 100644 --- a/core/router/src/test/kotlin/com/correx/core/router/WorkflowProposalsTest.kt +++ b/core/talkie/src/test/kotlin/com/correx/core/talkie/WorkflowProposalsTest.kt @@ -1,4 +1,4 @@ -package com.correx.core.router +package com.correx.core.talkie import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Assertions.assertTrue diff --git a/core/router/src/test/kotlin/com/correx/core/router/l3/InMemoryL3MemoryStoreTest.kt b/core/talkie/src/test/kotlin/com/correx/core/talkie/l3/InMemoryL3MemoryStoreTest.kt similarity index 99% rename from core/router/src/test/kotlin/com/correx/core/router/l3/InMemoryL3MemoryStoreTest.kt rename to core/talkie/src/test/kotlin/com/correx/core/talkie/l3/InMemoryL3MemoryStoreTest.kt index 2b074e1f..47a5527f 100644 --- a/core/router/src/test/kotlin/com/correx/core/router/l3/InMemoryL3MemoryStoreTest.kt +++ b/core/talkie/src/test/kotlin/com/correx/core/talkie/l3/InMemoryL3MemoryStoreTest.kt @@ -1,4 +1,4 @@ -package com.correx.core.router.l3 +package com.correx.core.talkie.l3 import com.correx.core.events.types.SessionId import com.correx.core.utils.TypeId diff --git a/infrastructure/build.gradle b/infrastructure/build.gradle index d8558551..98e87cb9 100644 --- a/infrastructure/build.gradle +++ b/infrastructure/build.gradle @@ -7,7 +7,7 @@ plugins { dependencies { implementation project(":core:tools") implementation project(":core:events") - implementation project(":core:router") + implementation project(":core:talkie") implementation project(":core:inference") implementation project(":core:approvals") implementation project(":core:sessions") diff --git a/infrastructure/router/build.gradle b/infrastructure/router/build.gradle index ba5b5485..f0275550 100644 --- a/infrastructure/router/build.gradle +++ b/infrastructure/router/build.gradle @@ -5,7 +5,7 @@ plugins { } dependencies { - implementation project(':core:router') + implementation project(':core:talkie') implementation project(':core:events') testImplementation "org.junit.jupiter:junit-jupiter" testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test" diff --git a/infrastructure/router/turbovec/build.gradle b/infrastructure/router/turbovec/build.gradle index 1eca6295..f77b6376 100644 --- a/infrastructure/router/turbovec/build.gradle +++ b/infrastructure/router/turbovec/build.gradle @@ -5,7 +5,7 @@ plugins { } dependencies { - implementation project(':core:router') + implementation project(':core:talkie') implementation project(':core:sessions') implementation project(':core:events') testImplementation "org.junit.jupiter:junit-jupiter" diff --git a/infrastructure/router/turbovec/src/main/kotlin/com/correx/infrastructure/router/turbovec/TurboVecL3MemoryStore.kt b/infrastructure/router/turbovec/src/main/kotlin/com/correx/infrastructure/router/turbovec/TurboVecL3MemoryStore.kt index eda5eeda..acf3d7d8 100644 --- a/infrastructure/router/turbovec/src/main/kotlin/com/correx/infrastructure/router/turbovec/TurboVecL3MemoryStore.kt +++ b/infrastructure/router/turbovec/src/main/kotlin/com/correx/infrastructure/router/turbovec/TurboVecL3MemoryStore.kt @@ -1,9 +1,9 @@ package com.correx.infrastructure.router.turbovec -import com.correx.core.router.l3.L3Hit -import com.correx.core.router.l3.L3MemoryEntry -import com.correx.core.router.l3.L3Query -import com.correx.core.router.l3.RehydratableL3MemoryStore +import com.correx.core.talkie.l3.L3Hit +import com.correx.core.talkie.l3.L3MemoryEntry +import com.correx.core.talkie.l3.L3Query +import com.correx.core.talkie.l3.RehydratableL3MemoryStore import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock import kotlinx.coroutines.withTimeout diff --git a/infrastructure/src/main/kotlin/com/correx/infrastructure/InfrastructureModule.kt b/infrastructure/src/main/kotlin/com/correx/infrastructure/InfrastructureModule.kt index 51725ed5..98ea2fb8 100644 --- a/infrastructure/src/main/kotlin/com/correx/infrastructure/InfrastructureModule.kt +++ b/infrastructure/src/main/kotlin/com/correx/infrastructure/InfrastructureModule.kt @@ -22,17 +22,17 @@ import com.correx.core.inference.InferenceRouter import com.correx.core.inference.ModelCapability import com.correx.core.inference.NoopEmbedder import com.correx.core.inference.Tokenizer -import com.correx.core.router.DefaultRouterContextBuilder -import com.correx.core.router.DefaultRouterFacade -import com.correx.core.router.IdeaReader -import com.correx.core.router.DefaultRouterReducer -import com.correx.core.router.DefaultRouterRepository -import com.correx.core.router.RouterFacade -import com.correx.core.router.RouterProjector -import com.correx.core.router.l3.InMemoryL3MemoryStore -import com.correx.core.router.l3.L3MemoryStore -import com.correx.core.router.model.RouterConfig -import com.correx.core.router.model.WorkflowSummary +import com.correx.core.talkie.DefaultTalkieContextBuilder +import com.correx.core.talkie.DefaultTalkieFacade +import com.correx.core.talkie.IdeaReader +import com.correx.core.talkie.DefaultTalkieReducer +import com.correx.core.talkie.DefaultTalkieRepository +import com.correx.core.talkie.TalkieFacade +import com.correx.core.talkie.TalkieProjector +import com.correx.core.talkie.l3.InMemoryL3MemoryStore +import com.correx.core.talkie.l3.L3MemoryStore +import com.correx.core.talkie.model.TalkieConfig +import com.correx.core.talkie.model.WorkflowSummary import com.correx.core.events.types.SessionId import com.correx.core.sessions.projections.replay.DefaultEventReplayer import com.correx.core.tools.contract.Tool @@ -306,22 +306,22 @@ object InfrastructureModule { } } - fun createRouterFacade( + fun createTalkieFacade( eventStore: EventStore, inferenceRouter: InferenceRouter, - config: RouterConfig = RouterConfig(), + config: TalkieConfig = TalkieConfig(), tokenizer: Tokenizer? = null, embedder: Embedder = createNoopEmbedder(), l3MemoryStore: L3MemoryStore = createInMemoryL3MemoryStore(), workflowSummaryProvider: () -> List = { emptyList() }, sessionProfileProvider: suspend (SessionId) -> String? = { null }, - ): RouterFacade { - val reducer = DefaultRouterReducer() - val projector = RouterProjector(reducer) + ): TalkieFacade { + val reducer = DefaultTalkieReducer() + val projector = TalkieProjector(reducer) val replayer = DefaultEventReplayer(eventStore, projector) - val repository = DefaultRouterRepository(replayer) + val repository = DefaultTalkieRepository(replayer) val ideaReader = IdeaReader(eventStore) - val contextBuilder = DefaultRouterContextBuilder(config, tokenizer, ideaProvider = { ideaReader.activeIdeas() }) - return DefaultRouterFacade(repository, contextBuilder, inferenceRouter, eventStore, config, null, embedder, l3MemoryStore, workflowSummaryProvider, sessionProfileProvider) + val contextBuilder = DefaultTalkieContextBuilder(config, tokenizer, ideaProvider = { ideaReader.activeIdeas() }) + return DefaultTalkieFacade(repository, contextBuilder, inferenceRouter, eventStore, config, null, embedder, l3MemoryStore, workflowSummaryProvider, sessionProfileProvider) } } diff --git a/settings.gradle b/settings.gradle index 73b6735f..40eeff5b 100644 --- a/settings.gradle +++ b/settings.gradle @@ -21,7 +21,7 @@ include ':core:validation' include ':core:approvals' include ':core:tools' include ':core:toolintent' -include ':core:router' +include ':core:talkie' include ':core:sessions' include ':core:tasks' include ':core:config' diff --git a/testing/deterministic/build.gradle b/testing/deterministic/build.gradle index ea4dcb19..2dc645a4 100644 --- a/testing/deterministic/build.gradle +++ b/testing/deterministic/build.gradle @@ -6,7 +6,7 @@ plugins { dependencies { testImplementation(project(":core:events")) - testImplementation(project(":core:router")) + testImplementation(project(":core:talkie")) testImplementation(project(":core:sessions")) testImplementation(project(":core:transitions")) testImplementation(project(":core:validation")) diff --git a/testing/deterministic/src/test/kotlin/L3MetadataRehydratorTest.kt b/testing/deterministic/src/test/kotlin/L3MetadataRehydratorTest.kt index 4687fea0..6c52f317 100644 --- a/testing/deterministic/src/test/kotlin/L3MetadataRehydratorTest.kt +++ b/testing/deterministic/src/test/kotlin/L3MetadataRehydratorTest.kt @@ -8,12 +8,12 @@ import com.correx.core.events.events.StoredEvent import com.correx.core.events.stores.EventStore import com.correx.core.events.types.EventId import com.correx.core.events.types.SessionId -import com.correx.core.router.l3.InMemoryL3MemoryStore -import com.correx.core.router.l3.L3Hit -import com.correx.core.router.l3.L3MemoryEntry -import com.correx.core.router.l3.L3MetadataRehydrator -import com.correx.core.router.l3.L3Query -import com.correx.core.router.l3.RehydratableL3MemoryStore +import com.correx.core.talkie.l3.InMemoryL3MemoryStore +import com.correx.core.talkie.l3.L3Hit +import com.correx.core.talkie.l3.L3MemoryEntry +import com.correx.core.talkie.l3.L3MetadataRehydrator +import com.correx.core.talkie.l3.L3Query +import com.correx.core.talkie.l3.RehydratableL3MemoryStore import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.runBlocking import kotlinx.datetime.Instant diff --git a/testing/deterministic/src/test/kotlin/RouterContextBuilderTest.kt b/testing/deterministic/src/test/kotlin/TalkieContextBuilderTest.kt similarity index 87% rename from testing/deterministic/src/test/kotlin/RouterContextBuilderTest.kt rename to testing/deterministic/src/test/kotlin/TalkieContextBuilderTest.kt index 8b2426dc..83a23b8b 100644 --- a/testing/deterministic/src/test/kotlin/RouterContextBuilderTest.kt +++ b/testing/deterministic/src/test/kotlin/TalkieContextBuilderTest.kt @@ -5,15 +5,15 @@ import com.correx.core.context.model.TokenBudget import com.correx.core.events.events.L3RetrievedHit import com.correx.core.events.types.SessionId import com.correx.core.events.types.StageId -import com.correx.core.router.DefaultRouterContextBuilder -import com.correx.core.router.model.RouterConfig -import com.correx.core.router.model.WorkflowSummary -import com.correx.core.router.model.RouterL2Entry -import com.correx.core.router.model.RouterState -import com.correx.core.router.model.RouterTurn -import com.correx.core.router.model.StageOutcomeKind -import com.correx.core.router.model.TurnRole -import com.correx.core.router.model.WorkflowStatus +import com.correx.core.talkie.DefaultTalkieContextBuilder +import com.correx.core.talkie.model.TalkieConfig +import com.correx.core.talkie.model.WorkflowSummary +import com.correx.core.talkie.model.RouterL2Entry +import com.correx.core.talkie.model.TalkieState +import com.correx.core.talkie.model.TalkieTurn +import com.correx.core.talkie.model.StageOutcomeKind +import com.correx.core.talkie.model.TurnRole +import com.correx.core.talkie.model.WorkflowStatus import kotlinx.coroutines.runBlocking import kotlinx.datetime.Clock import kotlinx.datetime.Instant @@ -24,12 +24,12 @@ import org.junit.jupiter.api.Assertions.assertNull import org.junit.jupiter.api.Assertions.assertTrue import org.junit.jupiter.api.Test -class RouterContextBuilderTest { +class TalkieContextBuilderTest { - private val config = RouterConfig(conversationKeepLast = 3, tokenBudget = TokenBudget(limit = 200)) - private val builder = DefaultRouterContextBuilder(config) + private val config = TalkieConfig(conversationKeepLast = 3, tokenBudget = TokenBudget(limit = 200)) + private val builder = DefaultTalkieContextBuilder(config) - private fun buildPack(state: RouterState, budget: TokenBudget): ContextPack = runBlocking { + private fun buildPack(state: TalkieState, budget: TokenBudget): ContextPack = runBlocking { builder.build(state, budget) } @@ -43,12 +43,12 @@ class RouterContextBuilderTest { @Test fun `build fits within budget when all entries are small`() { - val state = RouterState( + val state = TalkieState( sessionId = sessionId, workflowStatus = WorkflowStatus.RUNNING, currentStageId = stageId, conversationHistory = listOf( - RouterTurn(TurnRole.USER, "hi", clock.now()), + TalkieTurn(TurnRole.USER, "hi", clock.now()), ), ) val pack = buildPack(state, TokenBudget(limit = 10000)) @@ -60,14 +60,14 @@ class RouterContextBuilderTest { fun `build drops entries when budget is exceeded`() { // Build a state where conversation + L2 entries together exceed the tight budget val longContent = "x".repeat(800) // ~400 tokens each - val state = RouterState( + val state = TalkieState( sessionId = sessionId, workflowStatus = WorkflowStatus.RUNNING, currentStageId = stageId, conversationHistory = listOf( - RouterTurn(TurnRole.USER, longContent, clock.now()), - RouterTurn(TurnRole.ROUTER, longContent, clock.now()), - RouterTurn(TurnRole.USER, longContent, clock.now()), + TalkieTurn(TurnRole.USER, longContent, clock.now()), + TalkieTurn(TurnRole.ROUTER, longContent, clock.now()), + TalkieTurn(TurnRole.USER, longContent, clock.now()), ), l2Memory = listOf( RouterL2Entry(StageId("s1"), "summary", StageOutcomeKind.SUCCESS, clock.now()), @@ -82,10 +82,10 @@ class RouterContextBuilderTest { fun `build drops entries oldest-first for L2 memory when budget forces partial drop`() { // Each L2 entry: "Stage sN (SUCCESS): " + 200-char summary ≈ 55 tokens each. // Use a config with conversationKeepLast=0 so only L0 + L2 compete for budget. - val configNoConv = RouterConfig(conversationKeepLast = 0, tokenBudget = TokenBudget(limit = 10000)) - val builderNoConv = DefaultRouterContextBuilder(configNoConv) + val configNoConv = TalkieConfig(conversationKeepLast = 0, tokenBudget = TokenBudget(limit = 10000)) + val builderNoConv = DefaultTalkieContextBuilder(configNoConv) val summary = "x".repeat(200) // ~50 tokens; with prefix "Stage sN (SUCCESS): " ~55 tokens total - val state = RouterState( + val state = TalkieState( sessionId = sessionId, workflowStatus = WorkflowStatus.RUNNING, currentStageId = stageId, @@ -115,18 +115,18 @@ class RouterContextBuilderTest { @Test fun `build drops conversation turns oldest-first when conversationKeepLast exceeded`() { - val configWide = RouterConfig(conversationKeepLast = 2, tokenBudget = TokenBudget(limit = 10000)) - val builderWide = DefaultRouterContextBuilder(configWide) + val configWide = TalkieConfig(conversationKeepLast = 2, tokenBudget = TokenBudget(limit = 10000)) + val builderWide = DefaultTalkieContextBuilder(configWide) val longContent = "x".repeat(400) - val state = RouterState( + val state = TalkieState( sessionId = sessionId, workflowStatus = WorkflowStatus.RUNNING, currentStageId = stageId, conversationHistory = listOf( - RouterTurn(TurnRole.USER, longContent, Instant.parse("2026-01-01T00:00:00Z")), - RouterTurn(TurnRole.ROUTER, longContent, Instant.parse("2026-01-02T00:00:00Z")), - RouterTurn(TurnRole.USER, longContent, Instant.parse("2026-01-03T00:00:00Z")), - RouterTurn(TurnRole.ROUTER, longContent, Instant.parse("2026-01-04T00:00:00Z")), + TalkieTurn(TurnRole.USER, longContent, Instant.parse("2026-01-01T00:00:00Z")), + TalkieTurn(TurnRole.ROUTER, longContent, Instant.parse("2026-01-02T00:00:00Z")), + TalkieTurn(TurnRole.USER, longContent, Instant.parse("2026-01-03T00:00:00Z")), + TalkieTurn(TurnRole.ROUTER, longContent, Instant.parse("2026-01-04T00:00:00Z")), ), ) // Budget allows L0 + 2 long conversation turns; oldest 2 turns are dropped. @@ -144,7 +144,7 @@ class RouterContextBuilderTest { @Test fun `L0 system prompt is always present`() { - val state = RouterState( + val state = TalkieState( sessionId = sessionId, workflowStatus = WorkflowStatus.IDLE, currentStageId = null, @@ -156,7 +156,7 @@ class RouterContextBuilderTest { @Test fun `L0 workflow status is always present`() { - val state = RouterState( + val state = TalkieState( sessionId = sessionId, workflowStatus = WorkflowStatus.FAILED, currentStageId = StageId("failed-stage"), @@ -171,7 +171,7 @@ class RouterContextBuilderTest { @Test fun `L0 entries survive zero budget`() { - val state = RouterState( + val state = TalkieState( sessionId = sessionId, workflowStatus = WorkflowStatus.COMPLETED, currentStageId = null, @@ -185,12 +185,12 @@ class RouterContextBuilderTest { @Test fun `L0 entries survive budget that cannot cover L1 or L2`() { - val state = RouterState( + val state = TalkieState( sessionId = sessionId, workflowStatus = WorkflowStatus.RUNNING, currentStageId = stageId, conversationHistory = listOf( - RouterTurn(TurnRole.USER, "x".repeat(500), clock.now()), + TalkieTurn(TurnRole.USER, "x".repeat(500), clock.now()), ), l2Memory = listOf( RouterL2Entry(StageId("s1"), "x".repeat(500), StageOutcomeKind.SUCCESS, clock.now()), @@ -215,10 +215,10 @@ class RouterContextBuilderTest { // Each L2 entry: "Stage sN (SUCCESS): " + 100-char summary ≈ 30 tokens each. // L0 ~30 tokens; budget 90 leaves ~60. Two entries (~30 each = ~60) fit; oldest dropped. val summary = "x".repeat(100) // ~25 tokens; with prefix ~30 tokens total - val configTight = RouterConfig(conversationKeepLast = 0, tokenBudget = TokenBudget(limit = 10000)) - val builderTight = DefaultRouterContextBuilder(configTight) + val configTight = TalkieConfig(conversationKeepLast = 0, tokenBudget = TokenBudget(limit = 10000)) + val builderTight = DefaultTalkieContextBuilder(configTight) val baseTime = Instant.parse("2026-01-01T00:00:00Z") - val state = RouterState( + val state = TalkieState( sessionId = sessionId, workflowStatus = WorkflowStatus.RUNNING, currentStageId = stageId, @@ -251,9 +251,9 @@ class RouterContextBuilderTest { @Test fun `L2 entries fit within budget are all retained`() { - val config = RouterConfig(conversationKeepLast = 0, tokenBudget = TokenBudget(limit = 10000)) - val builder = DefaultRouterContextBuilder(config) - val state = RouterState( + val config = TalkieConfig(conversationKeepLast = 0, tokenBudget = TokenBudget(limit = 10000)) + val builder = DefaultTalkieContextBuilder(config) + val state = TalkieState( sessionId = sessionId, workflowStatus = WorkflowStatus.RUNNING, currentStageId = stageId, @@ -274,7 +274,7 @@ class RouterContextBuilderTest { @Test fun `system prompt is classified as L0`() { - val state = RouterState( + val state = TalkieState( sessionId = sessionId, workflowStatus = WorkflowStatus.IDLE, ) @@ -286,7 +286,7 @@ class RouterContextBuilderTest { @Test fun `workflow status is classified as L0`() { - val state = RouterState( + val state = TalkieState( sessionId = sessionId, workflowStatus = WorkflowStatus.RUNNING, currentStageId = stageId, @@ -298,13 +298,13 @@ class RouterContextBuilderTest { @Test fun `conversation turns are classified as L1`() { - val state = RouterState( + val state = TalkieState( sessionId = sessionId, workflowStatus = WorkflowStatus.RUNNING, currentStageId = stageId, conversationHistory = listOf( - RouterTurn(TurnRole.USER, "hello", clock.now()), - RouterTurn(TurnRole.ROUTER, "hi", clock.now()), + TalkieTurn(TurnRole.USER, "hello", clock.now()), + TalkieTurn(TurnRole.ROUTER, "hi", clock.now()), ), ) val pack = buildPack(state, TokenBudget(limit = 10000)) @@ -317,7 +317,7 @@ class RouterContextBuilderTest { @Test fun `l2 memory entries are classified as L2`() { - val state = RouterState( + val state = TalkieState( sessionId = sessionId, workflowStatus = WorkflowStatus.RUNNING, currentStageId = stageId, @@ -335,12 +335,12 @@ class RouterContextBuilderTest { @Test fun `no entries other than L0 L1 L2 appear in pack`() { - val state = RouterState( + val state = TalkieState( sessionId = sessionId, workflowStatus = WorkflowStatus.RUNNING, currentStageId = stageId, conversationHistory = listOf( - RouterTurn(TurnRole.USER, "hello", clock.now()), + TalkieTurn(TurnRole.USER, "hello", clock.now()), ), l2Memory = listOf( RouterL2Entry(StageId("s1"), "summary", StageOutcomeKind.SUCCESS, clock.now()), @@ -359,18 +359,18 @@ class RouterContextBuilderTest { @Test fun `conversationHistory respects conversationKeepLast from config`() { - val config = RouterConfig(conversationKeepLast = 2, tokenBudget = TokenBudget(limit = 10000)) - val builder = DefaultRouterContextBuilder(config) - val state = RouterState( + val config = TalkieConfig(conversationKeepLast = 2, tokenBudget = TokenBudget(limit = 10000)) + val builder = DefaultTalkieContextBuilder(config) + val state = TalkieState( sessionId = sessionId, workflowStatus = WorkflowStatus.RUNNING, currentStageId = stageId, conversationHistory = listOf( - RouterTurn(TurnRole.USER, "one", Instant.parse("2026-01-01T00:00:00Z")), - RouterTurn(TurnRole.ROUTER, "two", Instant.parse("2026-01-02T00:00:00Z")), - RouterTurn(TurnRole.USER, "three", Instant.parse("2026-01-03T00:00:00Z")), - RouterTurn(TurnRole.ROUTER, "four", Instant.parse("2026-01-04T00:00:00Z")), - RouterTurn(TurnRole.USER, "five", Instant.parse("2026-01-05T00:00:00Z")), + TalkieTurn(TurnRole.USER, "one", Instant.parse("2026-01-01T00:00:00Z")), + TalkieTurn(TurnRole.ROUTER, "two", Instant.parse("2026-01-02T00:00:00Z")), + TalkieTurn(TurnRole.USER, "three", Instant.parse("2026-01-03T00:00:00Z")), + TalkieTurn(TurnRole.ROUTER, "four", Instant.parse("2026-01-04T00:00:00Z")), + TalkieTurn(TurnRole.USER, "five", Instant.parse("2026-01-05T00:00:00Z")), ), ) val pack = runBlocking { builder.build(state, TokenBudget(limit = 10000)) } @@ -381,17 +381,17 @@ class RouterContextBuilderTest { @Test fun `conversationHistory takeLast preserves ordering`() { - val config = RouterConfig(conversationKeepLast = 3, tokenBudget = TokenBudget(limit = 10000)) - val builder = DefaultRouterContextBuilder(config) - val state = RouterState( + val config = TalkieConfig(conversationKeepLast = 3, tokenBudget = TokenBudget(limit = 10000)) + val builder = DefaultTalkieContextBuilder(config) + val state = TalkieState( sessionId = sessionId, workflowStatus = WorkflowStatus.RUNNING, currentStageId = stageId, conversationHistory = listOf( - RouterTurn(TurnRole.USER, "first", Instant.parse("2026-01-01T00:00:00Z")), - RouterTurn(TurnRole.ROUTER, "second", Instant.parse("2026-01-02T00:00:00Z")), - RouterTurn(TurnRole.USER, "third", Instant.parse("2026-01-03T00:00:00Z")), - RouterTurn(TurnRole.ROUTER, "fourth", Instant.parse("2026-01-04T00:00:00Z")), + TalkieTurn(TurnRole.USER, "first", Instant.parse("2026-01-01T00:00:00Z")), + TalkieTurn(TurnRole.ROUTER, "second", Instant.parse("2026-01-02T00:00:00Z")), + TalkieTurn(TurnRole.USER, "third", Instant.parse("2026-01-03T00:00:00Z")), + TalkieTurn(TurnRole.ROUTER, "fourth", Instant.parse("2026-01-04T00:00:00Z")), ), ) val pack = buildPack(state, TokenBudget(limit = 10000)) @@ -409,7 +409,7 @@ class RouterContextBuilderTest { @Test fun `build with empty state produces L0 only`() { - val state = RouterState() + val state = TalkieState() val pack = buildPack(state, TokenBudget(limit = 10000)) val l0Entries = pack.layers[ContextLayer.L0] assertNotNull(l0Entries) @@ -420,7 +420,7 @@ class RouterContextBuilderTest { @Test fun `pack contains correct metadata on empty state`() { - val state = RouterState() + val state = TalkieState() val pack = buildPack(state, TokenBudget(limit = 5000)) assertEquals(5000, pack.budgetLimit) assertEquals(0, pack.compressionMetadata.entriesDropped) @@ -430,7 +430,7 @@ class RouterContextBuilderTest { @Test fun `pack has correct context pack id and session info`() { - val state = RouterState( + val state = TalkieState( sessionId = sessionId, workflowStatus = WorkflowStatus.RUNNING, currentStageId = stageId, @@ -447,7 +447,7 @@ class RouterContextBuilderTest { @Test fun `system prompt has expected content`() { - val state = RouterState() + val state = TalkieState() val pack = buildPack(state, TokenBudget(limit = 10000)) val systemEntry = pack.layers[ContextLayer.L0]?.find { it.sourceType == "systemPrompt" } assertNotNull(systemEntry) @@ -461,7 +461,7 @@ class RouterContextBuilderTest { @Test fun `workflow status entry contains status and stage`() { - val state = RouterState( + val state = TalkieState( sessionId = sessionId, workflowStatus = WorkflowStatus.COMPLETED, currentStageId = null, @@ -475,12 +475,12 @@ class RouterContextBuilderTest { @Test fun `conversation turn entry is formatted with role prefix`() { - val state = RouterState( + val state = TalkieState( sessionId = sessionId, workflowStatus = WorkflowStatus.RUNNING, currentStageId = stageId, conversationHistory = listOf( - RouterTurn(TurnRole.USER, "user message", clock.now()), + TalkieTurn(TurnRole.USER, "user message", clock.now()), ), ) val pack = buildPack(state, TokenBudget(limit = 10000)) @@ -492,7 +492,7 @@ class RouterContextBuilderTest { @Test fun `l2 entry is formatted with stage outcome and summary`() { - val state = RouterState( + val state = TalkieState( sessionId = sessionId, workflowStatus = WorkflowStatus.RUNNING, currentStageId = stageId, @@ -516,12 +516,12 @@ class RouterContextBuilderTest { @Test fun `budgetUsed equals sum of tokenEstimate of all retained entries`() { - val state = RouterState( + val state = TalkieState( sessionId = sessionId, workflowStatus = WorkflowStatus.RUNNING, currentStageId = stageId, conversationHistory = listOf( - RouterTurn(TurnRole.USER, "hello world", clock.now()), + TalkieTurn(TurnRole.USER, "hello world", clock.now()), ), l2Memory = listOf( RouterL2Entry(StageId("s1"), "summary", StageOutcomeKind.SUCCESS, clock.now()), @@ -535,14 +535,14 @@ class RouterContextBuilderTest { @Test fun `compressionMetadata entriesDropped reflects dropped count`() { - val config = RouterConfig(conversationKeepLast = 0, tokenBudget = TokenBudget(limit = 10)) - val builder = DefaultRouterContextBuilder(config) - val state = RouterState( + val config = TalkieConfig(conversationKeepLast = 0, tokenBudget = TokenBudget(limit = 10)) + val builder = DefaultTalkieContextBuilder(config) + val state = TalkieState( sessionId = sessionId, workflowStatus = WorkflowStatus.RUNNING, currentStageId = stageId, conversationHistory = listOf( - RouterTurn(TurnRole.USER, "x".repeat(200), clock.now()), + TalkieTurn(TurnRole.USER, "x".repeat(200), clock.now()), ), l2Memory = listOf( RouterL2Entry(StageId("s1"), "x".repeat(500), StageOutcomeKind.SUCCESS, clock.now()), @@ -561,17 +561,17 @@ class RouterContextBuilderTest { @Test fun `build with full state including all layers`() { - val config = RouterConfig(conversationKeepLast = 2, tokenBudget = TokenBudget(limit = 10000)) - val builder = DefaultRouterContextBuilder(config) - val state = RouterState( + val config = TalkieConfig(conversationKeepLast = 2, tokenBudget = TokenBudget(limit = 10000)) + val builder = DefaultTalkieContextBuilder(config) + val state = TalkieState( sessionId = sessionId, workflowStatus = WorkflowStatus.RUNNING, currentStageId = stageId, conversationHistory = listOf( - RouterTurn(TurnRole.USER, "first turn", Instant.parse("2026-01-01T00:00:00Z")), - RouterTurn(TurnRole.ROUTER, "first reply", Instant.parse("2026-01-02T00:00:00Z")), - RouterTurn(TurnRole.USER, "second turn", Instant.parse("2026-01-03T00:00:00Z")), - RouterTurn(TurnRole.ROUTER, "second reply", Instant.parse("2026-01-04T00:00:00Z")), + TalkieTurn(TurnRole.USER, "first turn", Instant.parse("2026-01-01T00:00:00Z")), + TalkieTurn(TurnRole.ROUTER, "first reply", Instant.parse("2026-01-02T00:00:00Z")), + TalkieTurn(TurnRole.USER, "second turn", Instant.parse("2026-01-03T00:00:00Z")), + TalkieTurn(TurnRole.ROUTER, "second reply", Instant.parse("2026-01-04T00:00:00Z")), ), l2Memory = listOf( RouterL2Entry( @@ -614,7 +614,7 @@ class RouterContextBuilderTest { @Test fun `build with null sessionId produces unknown pack id`() { - val state = RouterState( + val state = TalkieState( workflowStatus = WorkflowStatus.IDLE, ) val pack = buildPack(state, TokenBudget(limit = 1000)) @@ -627,7 +627,7 @@ class RouterContextBuilderTest { @Test fun `L3 hits injected into pack ordered by score descending`() { - val state = RouterState( + val state = TalkieState( sessionId = sessionId, workflowStatus = WorkflowStatus.RUNNING, currentStageId = stageId, @@ -667,7 +667,7 @@ class RouterContextBuilderTest { @Test fun `L3 entries carry recalled memory label in content`() { - val state = RouterState( + val state = TalkieState( sessionId = sessionId, workflowStatus = WorkflowStatus.RUNNING, lastRetrievedMemory = listOf( @@ -694,7 +694,7 @@ class RouterContextBuilderTest { fun `L3 hits dropped when budget exhausted and counted in entriesDropped`() { // Budget tight enough for L0 but not L3 entries with long text val longText = "x".repeat(800) // ~200 tokens - val state = RouterState( + val state = TalkieState( sessionId = sessionId, workflowStatus = WorkflowStatus.RUNNING, lastRetrievedMemory = listOf( @@ -721,14 +721,14 @@ class RouterContextBuilderTest { @Test fun `system prompt and current user turn survive tight budget`() { val longContent = "x".repeat(800) // ~200 tokens each - val state = RouterState( + val state = TalkieState( sessionId = sessionId, workflowStatus = WorkflowStatus.RUNNING, currentStageId = stageId, conversationHistory = listOf( - RouterTurn(TurnRole.USER, longContent, Instant.parse("2026-01-01T00:00:00Z"), turnId = "old-turn"), - RouterTurn(TurnRole.ROUTER, longContent, Instant.parse("2026-01-02T00:00:00Z"), turnId = "mid-turn"), - RouterTurn(TurnRole.USER, "current user input", Instant.parse("2026-01-03T00:00:00Z"), turnId = "current-turn"), + TalkieTurn(TurnRole.USER, longContent, Instant.parse("2026-01-01T00:00:00Z"), turnId = "old-turn"), + TalkieTurn(TurnRole.ROUTER, longContent, Instant.parse("2026-01-02T00:00:00Z"), turnId = "mid-turn"), + TalkieTurn(TurnRole.USER, "current user input", Instant.parse("2026-01-03T00:00:00Z"), turnId = "current-turn"), ), ) // Budget 60: L0 frame ~30 tokens -> remaining ~30; current user turn ~4 tokens -> protected. @@ -748,17 +748,17 @@ class RouterContextBuilderTest { @Test fun `oldest conversation turn is dropped before newest when budget is tight`() { - val config3 = RouterConfig(conversationKeepLast = 3, tokenBudget = TokenBudget(limit = 10000)) - val builder3 = DefaultRouterContextBuilder(config3) + val config3 = TalkieConfig(conversationKeepLast = 3, tokenBudget = TokenBudget(limit = 10000)) + val builder3 = DefaultTalkieContextBuilder(config3) val longContent = "x".repeat(800) // ~200 tokens each - val state = RouterState( + val state = TalkieState( sessionId = sessionId, workflowStatus = WorkflowStatus.RUNNING, currentStageId = stageId, conversationHistory = listOf( - RouterTurn(TurnRole.USER, "oldest turn $longContent", Instant.parse("2026-01-01T00:00:00Z"), turnId = "t1"), - RouterTurn(TurnRole.ROUTER, "middle turn $longContent", Instant.parse("2026-01-02T00:00:00Z"), turnId = "t2"), - RouterTurn(TurnRole.USER, "newest turn", Instant.parse("2026-01-03T00:00:00Z"), turnId = "t3"), + TalkieTurn(TurnRole.USER, "oldest turn $longContent", Instant.parse("2026-01-01T00:00:00Z"), turnId = "t1"), + TalkieTurn(TurnRole.ROUTER, "middle turn $longContent", Instant.parse("2026-01-02T00:00:00Z"), turnId = "t2"), + TalkieTurn(TurnRole.USER, "newest turn", Instant.parse("2026-01-03T00:00:00Z"), turnId = "t3"), ), ) // Budget 100: L0 frame ~30 tokens -> remaining ~70; newest turn ~3 tokens -> protected. @@ -776,12 +776,12 @@ class RouterContextBuilderTest { @Test fun `L3 and L2 dropped before recent conversation when budget is tight`() { val longContent = "x".repeat(200) // ~50 tokens each - val state = RouterState( + val state = TalkieState( sessionId = sessionId, workflowStatus = WorkflowStatus.RUNNING, currentStageId = stageId, conversationHistory = listOf( - RouterTurn(TurnRole.USER, "current user message", clock.now(), turnId = "curr"), + TalkieTurn(TurnRole.USER, "current user message", clock.now(), turnId = "curr"), ), lastRetrievedMemory = listOf( L3RetrievedHit( @@ -816,7 +816,7 @@ class RouterContextBuilderTest { @Test fun `available workflows entry is injected into L0 when non-empty`() { val workflows = listOf(WorkflowSummary("healthcheck", "Runs the health check pipeline", listOf("collect", "report"))) - val pack = runBlocking { builder.build(RouterState(), TokenBudget(limit = 10000), availableWorkflows = workflows) } + val pack = runBlocking { builder.build(TalkieState(), TokenBudget(limit = 10000), availableWorkflows = workflows) } val entry = (pack.layers[ContextLayer.L0] ?: emptyList()).find { it.sourceType == "availableWorkflows" } assertNotNull(entry) assertTrue(entry!!.content.contains("## Available workflows")) @@ -825,27 +825,27 @@ class RouterContextBuilderTest { @Test fun `available workflows entry is omitted when list is empty`() { - val pack = runBlocking { builder.build(RouterState(), TokenBudget(limit = 10000)) } + val pack = runBlocking { builder.build(TalkieState(), TokenBudget(limit = 10000)) } assertNull((pack.layers[ContextLayer.L0] ?: emptyList()).find { it.sourceType == "availableWorkflows" }) } @Test fun `project profile text is injected into L0 when non-null`() { val text = "## Project profile\nA Kotlin service.\n### Conventions\n- Use runCatching" - val pack = runBlocking { builder.build(RouterState(), TokenBudget(limit = 10000), projectProfileText = text) } + val pack = runBlocking { builder.build(TalkieState(), TokenBudget(limit = 10000), projectProfileText = text) } val entry = (pack.layers[ContextLayer.L0] ?: emptyList()).find { it.sourceType == "projectProfile" } assertEquals(text, entry!!.content) } @Test fun `project profile text is omitted when null or blank`() { - val pack = runBlocking { builder.build(RouterState(), TokenBudget(limit = 10000), projectProfileText = " ") } + val pack = runBlocking { builder.build(TalkieState(), TokenBudget(limit = 10000), projectProfileText = " ") } assertNull((pack.layers[ContextLayer.L0] ?: emptyList()).find { it.sourceType == "projectProfile" }) } @Test fun `system prompt contains triage directive not bare refusal`() { - val pack = buildPack(RouterState(), TokenBudget(limit = 10000)) + val pack = buildPack(TalkieState(), TokenBudget(limit = 10000)) val content = pack.layers[ContextLayer.L0]?.find { it.sourceType == "systemPrompt" }!!.content assertFalse(content.contains("if something is not in context, say you do not have it")) assertTrue(content.contains("Available workflows", ignoreCase = true)) @@ -855,13 +855,13 @@ class RouterContextBuilderTest { @Test fun `truncatedLayers populated with affected layers when drops occur`() { val longText = "x".repeat(800) - val state = RouterState( + val state = TalkieState( sessionId = sessionId, workflowStatus = WorkflowStatus.RUNNING, currentStageId = stageId, conversationHistory = listOf( - RouterTurn(TurnRole.USER, longText, clock.now(), turnId = "old"), - RouterTurn(TurnRole.USER, "current", clock.now(), turnId = "curr"), + TalkieTurn(TurnRole.USER, longText, clock.now(), turnId = "old"), + TalkieTurn(TurnRole.USER, "current", clock.now(), turnId = "curr"), ), lastRetrievedMemory = listOf( L3RetrievedHit( @@ -889,12 +889,12 @@ class RouterContextBuilderTest { // The current user turn must still be included; budgetUsed must report the true total; // appliedStrategies must contain "BudgetExceeded". val longUserTurn = "x".repeat(200) // ~50 tokens - val state = RouterState( + val state = TalkieState( sessionId = sessionId, workflowStatus = WorkflowStatus.RUNNING, currentStageId = stageId, conversationHistory = listOf( - RouterTurn(TurnRole.USER, longUserTurn, clock.now(), turnId = "current"), + TalkieTurn(TurnRole.USER, longUserTurn, clock.now(), turnId = "current"), ), ) // Budget 1: system prompt + workflow status alone exceed this. @@ -928,16 +928,16 @@ class RouterContextBuilderTest { @Test fun `conversationKeepLast zero still includes the current user turn`() { - val configZero = RouterConfig(conversationKeepLast = 0, tokenBudget = TokenBudget(limit = 10000)) - val builderZero = DefaultRouterContextBuilder(configZero) - val state = RouterState( + val configZero = TalkieConfig(conversationKeepLast = 0, tokenBudget = TokenBudget(limit = 10000)) + val builderZero = DefaultTalkieContextBuilder(configZero) + val state = TalkieState( sessionId = sessionId, workflowStatus = WorkflowStatus.RUNNING, currentStageId = stageId, conversationHistory = listOf( - RouterTurn(TurnRole.USER, "old turn 1", Instant.parse("2026-01-01T00:00:00Z"), turnId = "t1"), - RouterTurn(TurnRole.ROUTER, "old reply", Instant.parse("2026-01-02T00:00:00Z"), turnId = "t2"), - RouterTurn(TurnRole.USER, "current user input", Instant.parse("2026-01-03T00:00:00Z"), turnId = "t3"), + TalkieTurn(TurnRole.USER, "old turn 1", Instant.parse("2026-01-01T00:00:00Z"), turnId = "t1"), + TalkieTurn(TurnRole.ROUTER, "old reply", Instant.parse("2026-01-02T00:00:00Z"), turnId = "t2"), + TalkieTurn(TurnRole.USER, "current user input", Instant.parse("2026-01-03T00:00:00Z"), turnId = "t3"), ), ) val pack = runBlocking { builderZero.build(state, TokenBudget(limit = 10000)) } @@ -955,7 +955,7 @@ class RouterContextBuilderTest { @Test fun `appliedStrategies includes L3Recall when lastRetrievedMemory is non-empty`() { - val state = RouterState( + val state = TalkieState( sessionId = sessionId, workflowStatus = WorkflowStatus.RUNNING, currentStageId = stageId, @@ -978,7 +978,7 @@ class RouterContextBuilderTest { @Test fun `appliedStrategies does not include L3Recall when lastRetrievedMemory is empty`() { - val state = RouterState( + val state = TalkieState( sessionId = sessionId, workflowStatus = WorkflowStatus.RUNNING, ) @@ -995,12 +995,12 @@ class RouterContextBuilderTest { @Test fun `layers map is sorted by ContextLayer ordinal`() { - val state = RouterState( + val state = TalkieState( sessionId = sessionId, workflowStatus = WorkflowStatus.RUNNING, currentStageId = stageId, conversationHistory = listOf( - RouterTurn(TurnRole.USER, "hello", clock.now()), + TalkieTurn(TurnRole.USER, "hello", clock.now()), ), l2Memory = listOf( RouterL2Entry(StageId("s1"), "summary", StageOutcomeKind.SUCCESS, clock.now()), diff --git a/testing/deterministic/src/test/kotlin/RouterFacadeTest.kt b/testing/deterministic/src/test/kotlin/TalkieFacadeTest.kt similarity index 82% rename from testing/deterministic/src/test/kotlin/RouterFacadeTest.kt rename to testing/deterministic/src/test/kotlin/TalkieFacadeTest.kt index 89a038a8..d768a5a0 100644 --- a/testing/deterministic/src/test/kotlin/RouterFacadeTest.kt +++ b/testing/deterministic/src/test/kotlin/TalkieFacadeTest.kt @@ -29,26 +29,26 @@ import com.correx.core.inference.NoopEmbedder import com.correx.core.inference.ProviderHealth import com.correx.core.inference.ResponseFormat import com.correx.core.inference.TokenUsage -import com.correx.core.router.ChatMode -import com.correx.core.router.DefaultRouterContextBuilder -import com.correx.core.router.DefaultRouterFacade -import com.correx.core.router.DefaultRouterReducer -import com.correx.core.router.IdeaReader -import com.correx.core.router.RouterContextBuilder -import com.correx.core.router.RouterFacade -import com.correx.core.router.RouterProjector -import com.correx.core.router.RouterRepository -import com.correx.core.router.l3.InMemoryL3MemoryStore -import com.correx.core.router.l3.L3MemoryEntry -import com.correx.core.router.l3.L3MemoryStore -import com.correx.core.router.l3.L3Query -import com.correx.core.router.model.RouterConfig -import com.correx.core.router.model.RouterResponse -import com.correx.core.router.model.RouterState -import com.correx.core.router.model.RouterTurn -import com.correx.core.router.model.TurnRole -import com.correx.core.router.model.WorkflowSummary -import com.correx.core.router.model.WorkflowStatus +import com.correx.core.talkie.ChatMode +import com.correx.core.talkie.DefaultTalkieContextBuilder +import com.correx.core.talkie.DefaultTalkieFacade +import com.correx.core.talkie.DefaultTalkieReducer +import com.correx.core.talkie.IdeaReader +import com.correx.core.talkie.TalkieContextBuilder +import com.correx.core.talkie.TalkieFacade +import com.correx.core.talkie.TalkieProjector +import com.correx.core.talkie.TalkieRepository +import com.correx.core.talkie.l3.InMemoryL3MemoryStore +import com.correx.core.talkie.l3.L3MemoryEntry +import com.correx.core.talkie.l3.L3MemoryStore +import com.correx.core.talkie.l3.L3Query +import com.correx.core.talkie.model.TalkieConfig +import com.correx.core.talkie.model.TalkieResponse +import com.correx.core.talkie.model.TalkieState +import com.correx.core.talkie.model.TalkieTurn +import com.correx.core.talkie.model.TurnRole +import com.correx.core.talkie.model.WorkflowSummary +import com.correx.core.talkie.model.WorkflowStatus import com.correx.core.sessions.projections.replay.DefaultEventReplayer import com.correx.testing.fixtures.EventFixtures import com.correx.testing.fixtures.inference.MockTokenizer @@ -63,7 +63,7 @@ import org.junit.jupiter.api.Assertions.assertNull import org.junit.jupiter.api.Assertions.assertTrue import org.junit.jupiter.api.Test -class RouterFacadeTest { +class TalkieFacadeTest { // -------------------------------------------------------------------------- // CHAT mode @@ -135,21 +135,21 @@ class RouterFacadeTest { fun `STEERING mode appends SteeringNoteAddedEvent with current stageId`(): Unit = runBlocking { val mockStore = mockEventStore() val stageId = StageId("stage-A") - val facade = DefaultRouterFacade( - routerRepository = object : RouterRepository { - override suspend fun getRouterState(sessionId: SessionId): RouterState = - RouterState( + val facade = DefaultTalkieFacade( + routerRepository = object : TalkieRepository { + override suspend fun getTalkieState(sessionId: SessionId): TalkieState = + TalkieState( sessionId = sessionId, workflowStatus = WorkflowStatus.RUNNING, currentStageId = stageId, ) }, - routerContextBuilder = object : RouterContextBuilder { - override suspend fun build(state: RouterState, budget: TokenBudget, availableWorkflows: List, projectProfileText: String?): ContextPack = emptyContextPack() + routerContextBuilder = object : TalkieContextBuilder { + override suspend fun build(state: TalkieState, budget: TokenBudget, availableWorkflows: List, projectProfileText: String?): ContextPack = emptyContextPack() }, inferenceRouter = mockInferenceRouter("steering response"), eventStore = mockStore, - config = RouterConfig(tokenBudget = TokenBudget(limit = 5000)), + config = TalkieConfig(tokenBudget = TokenBudget(limit = 5000)), embedder = NoopEmbedder(dimension = 8), l3MemoryStore = InMemoryL3MemoryStore(), ) @@ -166,26 +166,26 @@ class RouterFacadeTest { @Test fun `conversation history grows per call - user and router turns appended`(): Unit = runBlocking { - val capturedStates = mutableListOf() + val capturedStates = mutableListOf() val eventStore = mockEventStore() - val replayer = DefaultEventReplayer( + val replayer = DefaultEventReplayer( store = eventStore, - projection = RouterProjector(DefaultRouterReducer()), + projection = TalkieProjector(DefaultTalkieReducer()), ) - val facade = DefaultRouterFacade( - routerRepository = object : RouterRepository { - override suspend fun getRouterState(sessionId: SessionId): RouterState = + val facade = DefaultTalkieFacade( + routerRepository = object : TalkieRepository { + override suspend fun getTalkieState(sessionId: SessionId): TalkieState = replayer.rebuild(sessionId) }, - routerContextBuilder = object : RouterContextBuilder { - override suspend fun build(state: RouterState, budget: TokenBudget, availableWorkflows: List, projectProfileText: String?): ContextPack { + routerContextBuilder = object : TalkieContextBuilder { + override suspend fun build(state: TalkieState, budget: TokenBudget, availableWorkflows: List, projectProfileText: String?): ContextPack { capturedStates.add(state) return emptyContextPack() } }, inferenceRouter = mockInferenceRouter("router reply"), eventStore = eventStore, - config = RouterConfig(tokenBudget = TokenBudget(limit = 5000)), + config = TalkieConfig(tokenBudget = TokenBudget(limit = 5000)), embedder = NoopEmbedder(dimension = 8), l3MemoryStore = InMemoryL3MemoryStore(), ) @@ -206,26 +206,26 @@ class RouterFacadeTest { @Test fun `conversation history is session-scoped - different sessions do not share history`(): Unit = runBlocking { - val capturedStates = mutableListOf() + val capturedStates = mutableListOf() val eventStore = mockEventStore() - val replayer = DefaultEventReplayer( + val replayer = DefaultEventReplayer( store = eventStore, - projection = RouterProjector(DefaultRouterReducer()), + projection = TalkieProjector(DefaultTalkieReducer()), ) - val facade = DefaultRouterFacade( - routerRepository = object : RouterRepository { - override suspend fun getRouterState(sessionId: SessionId): RouterState = + val facade = DefaultTalkieFacade( + routerRepository = object : TalkieRepository { + override suspend fun getTalkieState(sessionId: SessionId): TalkieState = replayer.rebuild(sessionId) }, - routerContextBuilder = object : RouterContextBuilder { - override suspend fun build(state: RouterState, budget: TokenBudget, availableWorkflows: List, projectProfileText: String?): ContextPack { + routerContextBuilder = object : TalkieContextBuilder { + override suspend fun build(state: TalkieState, budget: TokenBudget, availableWorkflows: List, projectProfileText: String?): ContextPack { capturedStates.add(state) return emptyContextPack() } }, inferenceRouter = mockInferenceRouter("response"), eventStore = eventStore, - config = RouterConfig(tokenBudget = TokenBudget(limit = 5000)), + config = TalkieConfig(tokenBudget = TokenBudget(limit = 5000)), embedder = NoopEmbedder(dimension = 8), l3MemoryStore = InMemoryL3MemoryStore(), ) @@ -246,17 +246,17 @@ class RouterFacadeTest { @Test fun `state is passed through to context builder`(): Unit = runBlocking { - val capturedState = mutableListOf() - val mockContextBuilder = object : RouterContextBuilder { - override suspend fun build(state: RouterState, budget: TokenBudget, availableWorkflows: List, projectProfileText: String?): ContextPack { + val capturedState = mutableListOf() + val mockContextBuilder = object : TalkieContextBuilder { + override suspend fun build(state: TalkieState, budget: TokenBudget, availableWorkflows: List, projectProfileText: String?): ContextPack { capturedState.add(state) return emptyContextPack() } } - val facade = DefaultRouterFacade( - routerRepository = object : RouterRepository { - override suspend fun getRouterState(sessionId: SessionId): RouterState = - RouterState( + val facade = DefaultTalkieFacade( + routerRepository = object : TalkieRepository { + override suspend fun getTalkieState(sessionId: SessionId): TalkieState = + TalkieState( sessionId = sessionId, workflowStatus = WorkflowStatus.RUNNING, currentStageId = StageId("s1"), @@ -265,7 +265,7 @@ class RouterFacadeTest { routerContextBuilder = mockContextBuilder, inferenceRouter = mockInferenceRouter("inference response"), eventStore = mockEventStore(), - config = RouterConfig(tokenBudget = TokenBudget(limit = 5000)), + config = TalkieConfig(tokenBudget = TokenBudget(limit = 5000)), embedder = NoopEmbedder(dimension = 8), l3MemoryStore = InMemoryL3MemoryStore(), ) @@ -278,20 +278,20 @@ class RouterFacadeTest { @Test fun `budget is passed through to context builder`(): Unit = runBlocking { val capturedBudget = mutableListOf() - val mockContextBuilder = object : RouterContextBuilder { - override suspend fun build(state: RouterState, budget: TokenBudget, availableWorkflows: List, projectProfileText: String?): ContextPack { + val mockContextBuilder = object : TalkieContextBuilder { + override suspend fun build(state: TalkieState, budget: TokenBudget, availableWorkflows: List, projectProfileText: String?): ContextPack { capturedBudget.add(budget) return emptyContextPack() } } - val facade = DefaultRouterFacade( - routerRepository = object : RouterRepository { - override suspend fun getRouterState(sessionId: SessionId): RouterState = RouterState() + val facade = DefaultTalkieFacade( + routerRepository = object : TalkieRepository { + override suspend fun getTalkieState(sessionId: SessionId): TalkieState = TalkieState() }, routerContextBuilder = mockContextBuilder, inferenceRouter = mockInferenceRouter("response"), eventStore = mockEventStore(), - config = RouterConfig(tokenBudget = TokenBudget(limit = 4200)), + config = TalkieConfig(tokenBudget = TokenBudget(limit = 4200)), embedder = NoopEmbedder(dimension = 8), l3MemoryStore = InMemoryL3MemoryStore(), ) @@ -313,20 +313,20 @@ class RouterFacadeTest { } } val stateStageId = StageId("state-stage") - val facade = DefaultRouterFacade( - routerRepository = object : RouterRepository { - override suspend fun getRouterState(sessionId: SessionId): RouterState = RouterState( + val facade = DefaultTalkieFacade( + routerRepository = object : TalkieRepository { + override suspend fun getTalkieState(sessionId: SessionId): TalkieState = TalkieState( sessionId = sessionId, workflowStatus = WorkflowStatus.RUNNING, currentStageId = stateStageId, ) }, - routerContextBuilder = object : RouterContextBuilder { - override suspend fun build(state: RouterState, budget: TokenBudget, availableWorkflows: List, projectProfileText: String?): ContextPack = emptyContextPack() + routerContextBuilder = object : TalkieContextBuilder { + override suspend fun build(state: TalkieState, budget: TokenBudget, availableWorkflows: List, projectProfileText: String?): ContextPack = emptyContextPack() }, inferenceRouter = mockInferenceRouter, eventStore = mockEventStore(), - config = RouterConfig(tokenBudget = TokenBudget(limit = 5000)), + config = TalkieConfig(tokenBudget = TokenBudget(limit = 5000)), embedder = NoopEmbedder(dimension = 8), l3MemoryStore = InMemoryL3MemoryStore(), ) @@ -346,20 +346,20 @@ class RouterFacadeTest { return mockProvider("response") } } - val facade = DefaultRouterFacade( - routerRepository = object : RouterRepository { - override suspend fun getRouterState(sessionId: SessionId): RouterState = RouterState( + val facade = DefaultTalkieFacade( + routerRepository = object : TalkieRepository { + override suspend fun getTalkieState(sessionId: SessionId): TalkieState = TalkieState( sessionId = sessionId, workflowStatus = WorkflowStatus.IDLE, currentStageId = null, ) }, - routerContextBuilder = object : RouterContextBuilder { - override suspend fun build(state: RouterState, budget: TokenBudget, availableWorkflows: List, projectProfileText: String?): ContextPack = emptyContextPack() + routerContextBuilder = object : TalkieContextBuilder { + override suspend fun build(state: TalkieState, budget: TokenBudget, availableWorkflows: List, projectProfileText: String?): ContextPack = emptyContextPack() }, inferenceRouter = mockInferenceRouter, eventStore = mockEventStore(), - config = RouterConfig(tokenBudget = TokenBudget(limit = 5000)), + config = TalkieConfig(tokenBudget = TokenBudget(limit = 5000)), embedder = NoopEmbedder(dimension = 8), l3MemoryStore = InMemoryL3MemoryStore(), ) @@ -378,16 +378,16 @@ class RouterFacadeTest { return mockProviderWithCapture("response", capturedRequestIds) } } - val facade = DefaultRouterFacade( - routerRepository = object : RouterRepository { - override suspend fun getRouterState(sessionId: SessionId): RouterState = RouterState() + val facade = DefaultTalkieFacade( + routerRepository = object : TalkieRepository { + override suspend fun getTalkieState(sessionId: SessionId): TalkieState = TalkieState() }, - routerContextBuilder = object : RouterContextBuilder { - override suspend fun build(state: RouterState, budget: TokenBudget, availableWorkflows: List, projectProfileText: String?): ContextPack = emptyContextPack() + routerContextBuilder = object : TalkieContextBuilder { + override suspend fun build(state: TalkieState, budget: TokenBudget, availableWorkflows: List, projectProfileText: String?): ContextPack = emptyContextPack() }, inferenceRouter = mockInferenceRouter, eventStore = mockEventStore(), - config = RouterConfig(tokenBudget = TokenBudget(limit = 5000)), + config = TalkieConfig(tokenBudget = TokenBudget(limit = 5000)), embedder = NoopEmbedder(dimension = 8), l3MemoryStore = InMemoryL3MemoryStore(), ) @@ -408,16 +408,16 @@ class RouterFacadeTest { return mockProviderWithRequestCapture("response", capturedRequests) } } - val facade = DefaultRouterFacade( - routerRepository = object : RouterRepository { - override suspend fun getRouterState(sessionId: SessionId): RouterState = RouterState() + val facade = DefaultTalkieFacade( + routerRepository = object : TalkieRepository { + override suspend fun getTalkieState(sessionId: SessionId): TalkieState = TalkieState() }, - routerContextBuilder = object : RouterContextBuilder { - override suspend fun build(state: RouterState, budget: TokenBudget, availableWorkflows: List, projectProfileText: String?): ContextPack = emptyContextPack() + routerContextBuilder = object : TalkieContextBuilder { + override suspend fun build(state: TalkieState, budget: TokenBudget, availableWorkflows: List, projectProfileText: String?): ContextPack = emptyContextPack() }, inferenceRouter = mockInferenceRouter, eventStore = mockEventStore(), - config = RouterConfig(tokenBudget = TokenBudget(limit = 5000)), + config = TalkieConfig(tokenBudget = TokenBudget(limit = 5000)), embedder = NoopEmbedder(dimension = 8), l3MemoryStore = InMemoryL3MemoryStore(), ) @@ -431,12 +431,12 @@ class RouterFacadeTest { @Test fun `context pack is passed to inference provider`(): Unit = runBlocking { val capturedContextPacks = mutableListOf() - val facade = DefaultRouterFacade( - routerRepository = object : RouterRepository { - override suspend fun getRouterState(sessionId: SessionId): RouterState = RouterState() + val facade = DefaultTalkieFacade( + routerRepository = object : TalkieRepository { + override suspend fun getTalkieState(sessionId: SessionId): TalkieState = TalkieState() }, - routerContextBuilder = object : RouterContextBuilder { - override suspend fun build(state: RouterState, budget: TokenBudget, availableWorkflows: List, projectProfileText: String?): ContextPack { + routerContextBuilder = object : TalkieContextBuilder { + override suspend fun build(state: TalkieState, budget: TokenBudget, availableWorkflows: List, projectProfileText: String?): ContextPack { val pack = ContextPack( id = ContextPackId("test-pack"), sessionId = state.sessionId ?: SessionId("unknown"), @@ -478,7 +478,7 @@ class RouterFacadeTest { } }, eventStore = mockEventStore(), - config = RouterConfig(tokenBudget = TokenBudget(limit = 5000)), + config = TalkieConfig(tokenBudget = TokenBudget(limit = 5000)), embedder = NoopEmbedder(dimension = 8), l3MemoryStore = InMemoryL3MemoryStore(), ) @@ -488,12 +488,12 @@ class RouterFacadeTest { @Test fun `responseFormat defaults to Text`(): Unit = runBlocking { val capturedRequests = mutableListOf() - val facade = DefaultRouterFacade( - routerRepository = object : RouterRepository { - override suspend fun getRouterState(sessionId: SessionId): RouterState = RouterState() + val facade = DefaultTalkieFacade( + routerRepository = object : TalkieRepository { + override suspend fun getTalkieState(sessionId: SessionId): TalkieState = TalkieState() }, - routerContextBuilder = object : RouterContextBuilder { - override suspend fun build(state: RouterState, budget: TokenBudget, availableWorkflows: List, projectProfileText: String?): ContextPack = emptyContextPack() + routerContextBuilder = object : TalkieContextBuilder { + override suspend fun build(state: TalkieState, budget: TokenBudget, availableWorkflows: List, projectProfileText: String?): ContextPack = emptyContextPack() }, inferenceRouter = object : InferenceRouter { override suspend fun route( @@ -504,7 +504,7 @@ class RouterFacadeTest { } }, eventStore = mockEventStore(), - config = RouterConfig(tokenBudget = TokenBudget(limit = 5000)), + config = TalkieConfig(tokenBudget = TokenBudget(limit = 5000)), embedder = NoopEmbedder(dimension = 8), l3MemoryStore = InMemoryL3MemoryStore(), ) @@ -514,7 +514,7 @@ class RouterFacadeTest { } @Test - fun `onUserInput returns RouterResponse with content and mode flag`(): Unit = runBlocking { + fun `onUserInput returns TalkieResponse with content and mode flag`(): Unit = runBlocking { val mockStore = mockEventStore() val facade = facadeWithMocks(eventStore = mockStore, chatMode = ChatMode.STEERING) val response = facade.onUserInput(sessionId = SessionId("test-session"), input = "Hello!") @@ -576,19 +576,19 @@ class RouterFacadeTest { override fun capabilities(): Set = setOf(CapabilityScore(ModelCapability.General, 1.0)) } val eventStore = mockEventStore() - val facade = DefaultRouterFacade( - routerRepository = object : RouterRepository { - override suspend fun getRouterState(sessionId: SessionId): RouterState = RouterState() + val facade = DefaultTalkieFacade( + routerRepository = object : TalkieRepository { + override suspend fun getTalkieState(sessionId: SessionId): TalkieState = TalkieState() }, - routerContextBuilder = object : RouterContextBuilder { - override suspend fun build(state: RouterState, budget: TokenBudget, availableWorkflows: List, projectProfileText: String?): ContextPack = emptyContextPack() + routerContextBuilder = object : TalkieContextBuilder { + override suspend fun build(state: TalkieState, budget: TokenBudget, availableWorkflows: List, projectProfileText: String?): ContextPack = emptyContextPack() }, inferenceRouter = object : InferenceRouter { override suspend fun route(stageId: StageId, requiredCapabilities: Set): InferenceProvider = metricsProvider }, eventStore = eventStore, - config = RouterConfig(tokenBudget = TokenBudget(limit = 5000)), + config = TalkieConfig(tokenBudget = TokenBudget(limit = 5000)), embedder = NoopEmbedder(dimension = 8), l3MemoryStore = InMemoryL3MemoryStore(), ) @@ -717,16 +717,16 @@ class RouterFacadeTest { store: EventStore, reply: String, workflows: List, - ): RouterFacade = DefaultRouterFacade( - routerRepository = object : RouterRepository { - override suspend fun getRouterState(sessionId: SessionId): RouterState = RouterState(sessionId = sessionId) + ): TalkieFacade = DefaultTalkieFacade( + routerRepository = object : TalkieRepository { + override suspend fun getTalkieState(sessionId: SessionId): TalkieState = TalkieState(sessionId = sessionId) }, - routerContextBuilder = object : RouterContextBuilder { - override suspend fun build(state: RouterState, budget: TokenBudget, availableWorkflows: List, projectProfileText: String?): ContextPack = emptyContextPack() + routerContextBuilder = object : TalkieContextBuilder { + override suspend fun build(state: TalkieState, budget: TokenBudget, availableWorkflows: List, projectProfileText: String?): ContextPack = emptyContextPack() }, inferenceRouter = mockInferenceRouter(reply), eventStore = store, - config = RouterConfig(tokenBudget = TokenBudget(limit = 5000)), + config = TalkieConfig(tokenBudget = TokenBudget(limit = 5000)), embedder = NoopEmbedder(dimension = 8), l3MemoryStore = InMemoryL3MemoryStore(), workflowSummaryProvider = { workflows }, @@ -739,28 +739,28 @@ class RouterFacadeTest { chatMode: ChatMode = ChatMode.CHAT, embedder: Embedder = NoopEmbedder(dimension = 8), l3MemoryStore: L3MemoryStore = InMemoryL3MemoryStore(), - ): RouterFacade = DefaultRouterFacade( - routerRepository = object : RouterRepository { - override suspend fun getRouterState(sessionId: SessionId): RouterState = - RouterState( + ): TalkieFacade = DefaultTalkieFacade( + routerRepository = object : TalkieRepository { + override suspend fun getTalkieState(sessionId: SessionId): TalkieState = + TalkieState( sessionId = sessionId, workflowStatus = WorkflowStatus.RUNNING, currentStageId = StageId("s1"), ) }, - routerContextBuilder = object : RouterContextBuilder { - override suspend fun build(state: RouterState, budget: TokenBudget, availableWorkflows: List, projectProfileText: String?): ContextPack = emptyContextPack() + routerContextBuilder = object : TalkieContextBuilder { + override suspend fun build(state: TalkieState, budget: TokenBudget, availableWorkflows: List, projectProfileText: String?): ContextPack = emptyContextPack() }, inferenceRouter = mockInferenceRouter("inference response"), eventStore = eventStore, - config = RouterConfig(tokenBudget = TokenBudget(limit = 5000)), + config = TalkieConfig(tokenBudget = TokenBudget(limit = 5000)), embedder = embedder, l3MemoryStore = l3MemoryStore, ).let { impl -> - object : RouterFacade { - override suspend fun onUserInput(sessionId: SessionId, input: String, mode: ChatMode): RouterResponse = + object : TalkieFacade { + override suspend fun onUserInput(sessionId: SessionId, input: String, mode: ChatMode): TalkieResponse = impl.onUserInput(sessionId = sessionId, input = input, mode = chatMode) - override suspend fun narrate(sessionId: SessionId, trigger: com.correx.core.router.model.NarrationTrigger) = + override suspend fun narrate(sessionId: SessionId, trigger: com.correx.core.talkie.model.NarrationTrigger) = impl.narrate(sessionId = sessionId, trigger = trigger) } } @@ -872,21 +872,21 @@ class RouterFacadeTest { ) val eventStore = mockEventStore() - val replayer = DefaultEventReplayer( + val replayer = DefaultEventReplayer( store = eventStore, - projection = RouterProjector(DefaultRouterReducer()), + projection = TalkieProjector(DefaultTalkieReducer()), ) - val facade = DefaultRouterFacade( - routerRepository = object : RouterRepository { - override suspend fun getRouterState(sessionId: SessionId): RouterState = + val facade = DefaultTalkieFacade( + routerRepository = object : TalkieRepository { + override suspend fun getTalkieState(sessionId: SessionId): TalkieState = replayer.rebuild(sessionId) }, - routerContextBuilder = object : RouterContextBuilder { - override suspend fun build(state: RouterState, budget: TokenBudget, availableWorkflows: List, projectProfileText: String?): ContextPack = emptyContextPack() + routerContextBuilder = object : TalkieContextBuilder { + override suspend fun build(state: TalkieState, budget: TokenBudget, availableWorkflows: List, projectProfileText: String?): ContextPack = emptyContextPack() }, inferenceRouter = mockInferenceRouter("router reply"), eventStore = eventStore, - config = RouterConfig(tokenBudget = TokenBudget(limit = 5000), retrievalK = 5), + config = TalkieConfig(tokenBudget = TokenBudget(limit = 5000), retrievalK = 5), embedder = stubEmbedder, l3MemoryStore = l3Store, ) @@ -928,9 +928,9 @@ class RouterFacadeTest { ) val eventStore = mockEventStore() - val replayer = DefaultEventReplayer( + val replayer = DefaultEventReplayer( store = eventStore, - projection = RouterProjector(DefaultRouterReducer()), + projection = TalkieProjector(DefaultTalkieReducer()), ) // Bootstrap session with a ChatTurnEvent whose turnId matches the L3 entry @@ -954,17 +954,17 @@ class RouterFacadeTest { ) ) - val facade = DefaultRouterFacade( - routerRepository = object : RouterRepository { - override suspend fun getRouterState(sessionId: SessionId): RouterState = + val facade = DefaultTalkieFacade( + routerRepository = object : TalkieRepository { + override suspend fun getTalkieState(sessionId: SessionId): TalkieState = replayer.rebuild(sessionId) }, - routerContextBuilder = object : RouterContextBuilder { - override suspend fun build(state: RouterState, budget: TokenBudget, availableWorkflows: List, projectProfileText: String?): ContextPack = emptyContextPack() + routerContextBuilder = object : TalkieContextBuilder { + override suspend fun build(state: TalkieState, budget: TokenBudget, availableWorkflows: List, projectProfileText: String?): ContextPack = emptyContextPack() }, inferenceRouter = mockInferenceRouter("router reply"), eventStore = eventStore, - config = RouterConfig(tokenBudget = TokenBudget(limit = 5000), retrievalK = 5), + config = TalkieConfig(tokenBudget = TokenBudget(limit = 5000), retrievalK = 5), embedder = stubEmbedder, l3MemoryStore = l3Store, ) @@ -986,16 +986,16 @@ class RouterFacadeTest { throw RuntimeException("embedding service unavailable") } val eventStore = mockEventStore() - val facade = DefaultRouterFacade( - routerRepository = object : RouterRepository { - override suspend fun getRouterState(sessionId: SessionId): RouterState = RouterState() + val facade = DefaultTalkieFacade( + routerRepository = object : TalkieRepository { + override suspend fun getTalkieState(sessionId: SessionId): TalkieState = TalkieState() }, - routerContextBuilder = object : RouterContextBuilder { - override suspend fun build(state: RouterState, budget: TokenBudget, availableWorkflows: List, projectProfileText: String?): ContextPack = emptyContextPack() + routerContextBuilder = object : TalkieContextBuilder { + override suspend fun build(state: TalkieState, budget: TokenBudget, availableWorkflows: List, projectProfileText: String?): ContextPack = emptyContextPack() }, inferenceRouter = mockInferenceRouter("response"), eventStore = eventStore, - config = RouterConfig(tokenBudget = TokenBudget(limit = 5000)), + config = TalkieConfig(tokenBudget = TokenBudget(limit = 5000)), embedder = throwingEmbedder, l3MemoryStore = InMemoryL3MemoryStore(), ) @@ -1014,9 +1014,9 @@ class RouterFacadeTest { } @Test - fun `replay of L3MemoryRetrievedEvent populates lastRetrievedMemory in RouterState`(): Unit = runBlocking { - val reducer = DefaultRouterReducer() - val projector = RouterProjector(reducer) + fun `replay of L3MemoryRetrievedEvent populates lastRetrievedMemory in TalkieState`(): Unit = runBlocking { + val reducer = DefaultTalkieReducer() + val projector = TalkieProjector(reducer) val sessionId = SessionId("replay-session") val hits = listOf( L3RetrievedHit( @@ -1048,28 +1048,28 @@ class RouterFacadeTest { @Test fun `ContextTruncatedEvent emitted when context builder drops entries`(): Unit = runBlocking { - // Use the real DefaultRouterContextBuilder with a tight budget and large conversation + // Use the real DefaultTalkieContextBuilder with a tight budget and large conversation val longContent = "x".repeat(800) // ~200 tokens each val sessionId = SessionId("truncation-session") val eventStore = mockEventStore() - val replayer = DefaultEventReplayer( + val replayer = DefaultEventReplayer( store = eventStore, - projection = RouterProjector(DefaultRouterReducer()), + projection = TalkieProjector(DefaultTalkieReducer()), ) - val facade = DefaultRouterFacade( - routerRepository = object : RouterRepository { - override suspend fun getRouterState(sessionId: SessionId): RouterState = + val facade = DefaultTalkieFacade( + routerRepository = object : TalkieRepository { + override suspend fun getTalkieState(sessionId: SessionId): TalkieState = replayer.rebuild(sessionId) }, - routerContextBuilder = DefaultRouterContextBuilder( - config = RouterConfig( + routerContextBuilder = DefaultTalkieContextBuilder( + config = TalkieConfig( conversationKeepLast = 4, tokenBudget = TokenBudget(limit = 80), ), ), inferenceRouter = mockInferenceRouter("response"), eventStore = eventStore, - config = RouterConfig( + config = TalkieConfig( conversationKeepLast = 4, tokenBudget = TokenBudget(limit = 80), ), @@ -1112,16 +1112,16 @@ class RouterFacadeTest { @Test fun `no ContextTruncatedEvent when budget is generous`(): Unit = runBlocking { val eventStore = mockEventStore() - val facade = DefaultRouterFacade( - routerRepository = object : RouterRepository { - override suspend fun getRouterState(sessionId: SessionId): RouterState = RouterState() + val facade = DefaultTalkieFacade( + routerRepository = object : TalkieRepository { + override suspend fun getTalkieState(sessionId: SessionId): TalkieState = TalkieState() }, - routerContextBuilder = DefaultRouterContextBuilder( - config = RouterConfig(tokenBudget = TokenBudget(limit = 10000)), + routerContextBuilder = DefaultTalkieContextBuilder( + config = TalkieConfig(tokenBudget = TokenBudget(limit = 10000)), ), inferenceRouter = mockInferenceRouter("response"), eventStore = eventStore, - config = RouterConfig(tokenBudget = TokenBudget(limit = 10000)), + config = TalkieConfig(tokenBudget = TokenBudget(limit = 10000)), embedder = NoopEmbedder(dimension = 8), l3MemoryStore = InMemoryL3MemoryStore(), ) @@ -1136,9 +1136,9 @@ class RouterFacadeTest { val longContent = "x".repeat(800) val sessionId = SessionId("turnid-session") val eventStore = mockEventStore() - val replayer = DefaultEventReplayer( + val replayer = DefaultEventReplayer( store = eventStore, - projection = RouterProjector(DefaultRouterReducer()), + projection = TalkieProjector(DefaultTalkieReducer()), ) // Pre-seed with a large turn so the budget overflows on the next call @@ -1162,17 +1162,17 @@ class RouterFacadeTest { ) ) - val facade = DefaultRouterFacade( - routerRepository = object : RouterRepository { - override suspend fun getRouterState(sessionId: SessionId): RouterState = + val facade = DefaultTalkieFacade( + routerRepository = object : TalkieRepository { + override suspend fun getTalkieState(sessionId: SessionId): TalkieState = replayer.rebuild(sessionId) }, - routerContextBuilder = DefaultRouterContextBuilder( - config = RouterConfig(conversationKeepLast = 4, tokenBudget = TokenBudget(limit = 80)), + routerContextBuilder = DefaultTalkieContextBuilder( + config = TalkieConfig(conversationKeepLast = 4, tokenBudget = TokenBudget(limit = 80)), ), inferenceRouter = mockInferenceRouter("response"), eventStore = eventStore, - config = RouterConfig(conversationKeepLast = 4, tokenBudget = TokenBudget(limit = 80)), + config = TalkieConfig(conversationKeepLast = 4, tokenBudget = TokenBudget(limit = 80)), embedder = NoopEmbedder(dimension = 8), l3MemoryStore = InMemoryL3MemoryStore(), ) @@ -1192,28 +1192,28 @@ class RouterFacadeTest { // Each turn must emit L3MemoryRetrievedEvent (with empty hits), so that // lastRetrievedMemory is always current-turn-scoped and never stale. val eventStore = mockEventStore() - val replayer = DefaultEventReplayer( + val replayer = DefaultEventReplayer( store = eventStore, - projection = RouterProjector(DefaultRouterReducer()), + projection = TalkieProjector(DefaultTalkieReducer()), ) - val capturedStates = mutableListOf() - val facade = DefaultRouterFacade( - routerRepository = object : RouterRepository { - override suspend fun getRouterState(sessionId: SessionId): RouterState = + val capturedStates = mutableListOf() + val facade = DefaultTalkieFacade( + routerRepository = object : TalkieRepository { + override suspend fun getTalkieState(sessionId: SessionId): TalkieState = replayer.rebuild(sessionId) }, - routerContextBuilder = object : RouterContextBuilder { - private val real = DefaultRouterContextBuilder( - config = RouterConfig(tokenBudget = TokenBudget(limit = 10000)), + routerContextBuilder = object : TalkieContextBuilder { + private val real = DefaultTalkieContextBuilder( + config = TalkieConfig(tokenBudget = TokenBudget(limit = 10000)), ) - override suspend fun build(state: RouterState, budget: TokenBudget, availableWorkflows: List, projectProfileText: String?): ContextPack { + override suspend fun build(state: TalkieState, budget: TokenBudget, availableWorkflows: List, projectProfileText: String?): ContextPack { capturedStates.add(state) return real.build(state, budget) } }, inferenceRouter = mockInferenceRouter("reply"), eventStore = eventStore, - config = RouterConfig(tokenBudget = TokenBudget(limit = 10000), retrievalK = 5), + config = TalkieConfig(tokenBudget = TokenBudget(limit = 10000), retrievalK = 5), embedder = NoopEmbedder(dimension = 8), l3MemoryStore = InMemoryL3MemoryStore(), ) @@ -1265,25 +1265,25 @@ class RouterFacadeTest { val capturedPacks = mutableListOf() val eventStore = mockEventStore() - val replayer = DefaultEventReplayer( + val replayer = DefaultEventReplayer( store = eventStore, - projection = RouterProjector(DefaultRouterReducer()), + projection = TalkieProjector(DefaultTalkieReducer()), ) - val facade = DefaultRouterFacade( - routerRepository = object : RouterRepository { - override suspend fun getRouterState(sessionId: SessionId): RouterState = + val facade = DefaultTalkieFacade( + routerRepository = object : TalkieRepository { + override suspend fun getTalkieState(sessionId: SessionId): TalkieState = replayer.rebuild(sessionId) }, - routerContextBuilder = object : RouterContextBuilder { - private val real = DefaultRouterContextBuilder( - config = RouterConfig(tokenBudget = TokenBudget(limit = 10000)), + routerContextBuilder = object : TalkieContextBuilder { + private val real = DefaultTalkieContextBuilder( + config = TalkieConfig(tokenBudget = TokenBudget(limit = 10000)), ) - override suspend fun build(state: RouterState, budget: TokenBudget, availableWorkflows: List, projectProfileText: String?): ContextPack = + override suspend fun build(state: TalkieState, budget: TokenBudget, availableWorkflows: List, projectProfileText: String?): ContextPack = real.build(state, budget).also { capturedPacks.add(it) } }, inferenceRouter = mockInferenceRouter("router reply"), eventStore = eventStore, - config = RouterConfig(tokenBudget = TokenBudget(limit = 10000), retrievalK = 5), + config = TalkieConfig(tokenBudget = TokenBudget(limit = 10000), retrievalK = 5), embedder = stubEmbedder, l3MemoryStore = l3Store, ) @@ -1321,16 +1321,16 @@ class RouterFacadeTest { return mockProvider("narration text") } } - val facade = DefaultRouterFacade( - routerRepository = object : RouterRepository { - override suspend fun getRouterState(sessionId: SessionId): RouterState = RouterState() + val facade = DefaultTalkieFacade( + routerRepository = object : TalkieRepository { + override suspend fun getTalkieState(sessionId: SessionId): TalkieState = TalkieState() }, - routerContextBuilder = object : RouterContextBuilder { - override suspend fun build(state: RouterState, budget: TokenBudget, availableWorkflows: List, projectProfileText: String?): ContextPack = emptyContextPack() + routerContextBuilder = object : TalkieContextBuilder { + override suspend fun build(state: TalkieState, budget: TokenBudget, availableWorkflows: List, projectProfileText: String?): ContextPack = emptyContextPack() }, inferenceRouter = mockInferenceRouter, eventStore = mockEventStore(), - config = RouterConfig( + config = TalkieConfig( tokenBudget = TokenBudget(limit = 5000), narrationModelId = "llama-cpp:phi-3-mini", ), @@ -1339,7 +1339,7 @@ class RouterFacadeTest { ) facade.narrate( sessionId = SessionId("test-session"), - trigger = com.correx.core.router.model.NarrationTrigger( + trigger = com.correx.core.talkie.model.NarrationTrigger( kind = "test", instruction = "describe what happened", ), @@ -1366,16 +1366,16 @@ class RouterFacadeTest { return mockProvider("response") } } - val facade = DefaultRouterFacade( - routerRepository = object : RouterRepository { - override suspend fun getRouterState(sessionId: SessionId): RouterState = RouterState() + val facade = DefaultTalkieFacade( + routerRepository = object : TalkieRepository { + override suspend fun getTalkieState(sessionId: SessionId): TalkieState = TalkieState() }, - routerContextBuilder = object : RouterContextBuilder { - override suspend fun build(state: RouterState, budget: TokenBudget, availableWorkflows: List, projectProfileText: String?): ContextPack = emptyContextPack() + routerContextBuilder = object : TalkieContextBuilder { + override suspend fun build(state: TalkieState, budget: TokenBudget, availableWorkflows: List, projectProfileText: String?): ContextPack = emptyContextPack() }, inferenceRouter = mockInferenceRouter, eventStore = mockEventStore(), - config = RouterConfig( + config = TalkieConfig( tokenBudget = TokenBudget(limit = 5000), narrationModelId = "llama-cpp:phi-3-mini", ), @@ -1393,9 +1393,9 @@ class RouterFacadeTest { @Test fun `workflowSummaryProvider is called and forwarded to context builder on each turn`(): Unit = runBlocking { val captured = mutableListOf>() - val capturingBuilder = object : RouterContextBuilder { + val capturingBuilder = object : TalkieContextBuilder { override suspend fun build( - state: RouterState, + state: TalkieState, budget: TokenBudget, availableWorkflows: List, projectProfileText: String?, @@ -1413,9 +1413,9 @@ class RouterFacadeTest { @Test fun `sessionProfileProvider is called and forwarded to context builder`(): Unit = runBlocking { val capturedProfiles = mutableListOf() - val capturingBuilder = object : RouterContextBuilder { + val capturingBuilder = object : TalkieContextBuilder { override suspend fun build( - state: RouterState, + state: TalkieState, budget: TokenBudget, availableWorkflows: List, projectProfileText: String?, @@ -1433,9 +1433,9 @@ class RouterFacadeTest { } private fun facadeWith( - contextBuilder: RouterContextBuilder = object : RouterContextBuilder { + contextBuilder: TalkieContextBuilder = object : TalkieContextBuilder { override suspend fun build( - state: RouterState, + state: TalkieState, budget: TokenBudget, availableWorkflows: List, projectProfileText: String?, @@ -1443,14 +1443,14 @@ class RouterFacadeTest { }, workflowSummaryProvider: () -> List = { emptyList() }, sessionProfileProvider: suspend (SessionId) -> String? = { null }, - ): RouterFacade = DefaultRouterFacade( - routerRepository = object : RouterRepository { - override suspend fun getRouterState(sessionId: SessionId): RouterState = RouterState(sessionId = sessionId) + ): TalkieFacade = DefaultTalkieFacade( + routerRepository = object : TalkieRepository { + override suspend fun getTalkieState(sessionId: SessionId): TalkieState = TalkieState(sessionId = sessionId) }, routerContextBuilder = contextBuilder, inferenceRouter = mockInferenceRouter("inference response"), eventStore = mockEventStore(), - config = RouterConfig(tokenBudget = TokenBudget(limit = 5000)), + config = TalkieConfig(tokenBudget = TokenBudget(limit = 5000)), embedder = NoopEmbedder(dimension = 8), l3MemoryStore = InMemoryL3MemoryStore(), workflowSummaryProvider = workflowSummaryProvider, diff --git a/testing/deterministic/src/test/kotlin/RouterNarrationTest.kt b/testing/deterministic/src/test/kotlin/TalkieNarrationTest.kt similarity index 83% rename from testing/deterministic/src/test/kotlin/RouterNarrationTest.kt rename to testing/deterministic/src/test/kotlin/TalkieNarrationTest.kt index 0f791eb0..598eea54 100644 --- a/testing/deterministic/src/test/kotlin/RouterNarrationTest.kt +++ b/testing/deterministic/src/test/kotlin/TalkieNarrationTest.kt @@ -4,7 +4,7 @@ import com.correx.core.context.model.TokenBudget import com.correx.core.events.events.ChatTurnEvent import com.correx.core.events.events.EventMetadata import com.correx.core.events.events.NewEvent -import com.correx.core.events.events.RouterNarrationEvent +import com.correx.core.events.events.TalkieNarrationEvent import com.correx.core.events.events.StoredEvent import com.correx.core.events.stores.EventStore import com.correx.core.events.types.ContextPackId @@ -25,19 +25,19 @@ import com.correx.core.inference.NoopEmbedder import com.correx.core.inference.ProviderHealth import com.correx.core.inference.ResponseFormat import com.correx.core.inference.TokenUsage -import com.correx.core.router.DefaultRouterContextBuilder -import com.correx.core.router.DefaultRouterFacade -import com.correx.core.router.RouterContextBuilder -import com.correx.core.router.RouterRepository -import com.correx.core.router.l3.InMemoryL3MemoryStore -import com.correx.core.router.l3.L3MemoryEntry -import com.correx.core.router.l3.L3MemoryStore -import com.correx.core.router.l3.L3Query -import com.correx.core.router.model.NarrationTrigger -import com.correx.core.router.model.RouterConfig -import com.correx.core.router.model.RouterState -import com.correx.core.router.model.WorkflowStatus -import com.correx.core.router.model.WorkflowSummary +import com.correx.core.talkie.DefaultTalkieContextBuilder +import com.correx.core.talkie.DefaultTalkieFacade +import com.correx.core.talkie.TalkieContextBuilder +import com.correx.core.talkie.TalkieRepository +import com.correx.core.talkie.l3.InMemoryL3MemoryStore +import com.correx.core.talkie.l3.L3MemoryEntry +import com.correx.core.talkie.l3.L3MemoryStore +import com.correx.core.talkie.l3.L3Query +import com.correx.core.talkie.model.NarrationTrigger +import com.correx.core.talkie.model.TalkieConfig +import com.correx.core.talkie.model.TalkieState +import com.correx.core.talkie.model.WorkflowStatus +import com.correx.core.talkie.model.WorkflowSummary import com.correx.testing.fixtures.inference.MockTokenizer import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.runBlocking @@ -47,14 +47,14 @@ import org.junit.jupiter.api.Assertions.assertNull import org.junit.jupiter.api.Assertions.assertTrue import org.junit.jupiter.api.Test -class RouterNarrationTest { +class TalkieNarrationTest { // -------------------------------------------------------------------------- // narrate() — event emission // -------------------------------------------------------------------------- @Test - fun `narrate emits RouterNarrationEvent with inference content and metrics`(): Unit = runBlocking { + fun `narrate emits TalkieNarrationEvent with inference content and metrics`(): Unit = runBlocking { val knownLatencyMs = 55L val knownUsage = TokenUsage(promptTokens = 8, completionTokens = 3) val eventStore = MapBackedEventStore() @@ -68,7 +68,7 @@ class RouterNarrationTest { facade.narrate(SessionId("sess-1"), trigger) - val narrationEvents = eventStore.appendedEvents.map { it.payload }.filterIsInstance() + val narrationEvents = eventStore.appendedEvents.map { it.payload }.filterIsInstance() assertEquals(1, narrationEvents.size) val event = narrationEvents[0] assertEquals("narration line", event.content) @@ -112,8 +112,8 @@ class RouterNarrationTest { facade.narrate(SessionId("sess-4"), trigger) - val narrationEvents = eventStore.appendedEvents.map { it.payload }.filterIsInstance() - assertTrue(narrationEvents.isEmpty(), "blank inference must not emit RouterNarrationEvent") + val narrationEvents = eventStore.appendedEvents.map { it.payload }.filterIsInstance() + assertTrue(narrationEvents.isEmpty(), "blank inference must not emit TalkieNarrationEvent") } @Test @@ -124,30 +124,30 @@ class RouterNarrationTest { facade.narrate(SessionId("sess-5"), trigger) - val narrationEvents = eventStore.appendedEvents.map { it.payload }.filterIsInstance() - assertTrue(narrationEvents.isEmpty(), "empty inference must not emit RouterNarrationEvent") + val narrationEvents = eventStore.appendedEvents.map { it.payload }.filterIsInstance() + assertTrue(narrationEvents.isEmpty(), "empty inference must not emit TalkieNarrationEvent") } @Test - fun `narrate RouterNarrationEvent carries sessionId and stageId from state`(): Unit = runBlocking { + fun `narrate TalkieNarrationEvent carries sessionId and stageId from state`(): Unit = runBlocking { val stageId = StageId("my-stage") val eventStore = MapBackedEventStore() - val facade = DefaultRouterFacade( - routerRepository = object : RouterRepository { - override suspend fun getRouterState(sessionId: SessionId): RouterState = - RouterState( + val facade = DefaultTalkieFacade( + routerRepository = object : TalkieRepository { + override suspend fun getTalkieState(sessionId: SessionId): TalkieState = + TalkieState( sessionId = sessionId, workflowStatus = WorkflowStatus.RUNNING, currentStageId = stageId, ) }, - routerContextBuilder = object : RouterContextBuilder { - override suspend fun build(state: RouterState, budget: TokenBudget, availableWorkflows: List, projectProfileText: String?): ContextPack = emptyContextPack() - override suspend fun buildNarrationContext(state: RouterState, trigger: NarrationTrigger, budget: TokenBudget): ContextPack = emptyContextPack() + routerContextBuilder = object : TalkieContextBuilder { + override suspend fun build(state: TalkieState, budget: TokenBudget, availableWorkflows: List, projectProfileText: String?): ContextPack = emptyContextPack() + override suspend fun buildNarrationContext(state: TalkieState, trigger: NarrationTrigger, budget: TokenBudget): ContextPack = emptyContextPack() }, inferenceRouter = mockInferenceRouter("stage narration", latencyMs = 10L, tokensUsed = TokenUsage(1, 1)), eventStore = eventStore, - config = RouterConfig(tokenBudget = TokenBudget(limit = 5000)), + config = TalkieConfig(tokenBudget = TokenBudget(limit = 5000)), embedder = NoopEmbedder(dimension = 8), l3MemoryStore = InMemoryL3MemoryStore(), ) @@ -155,7 +155,7 @@ class RouterNarrationTest { facade.narrate(SessionId("session-x"), trigger) - val narrationEvents = eventStore.appendedEvents.map { it.payload }.filterIsInstance() + val narrationEvents = eventStore.appendedEvents.map { it.payload }.filterIsInstance() assertEquals(1, narrationEvents.size) assertEquals(SessionId("session-x"), narrationEvents[0].sessionId) assertEquals("my-stage", narrationEvents[0].stageId) @@ -167,8 +167,8 @@ class RouterNarrationTest { @Test fun `buildNarrationContext includes system entry in L0`(): Unit = runBlocking { - val builder = DefaultRouterContextBuilder(RouterConfig()) - val state = RouterState(sessionId = SessionId("s"), workflowStatus = WorkflowStatus.IDLE) + val builder = DefaultTalkieContextBuilder(TalkieConfig()) + val state = TalkieState(sessionId = SessionId("s"), workflowStatus = WorkflowStatus.IDLE) val trigger = NarrationTrigger(kind = "test", instruction = "Do something.") val pack = builder.buildNarrationContext(state, trigger, TokenBudget(limit = 5000)) @@ -179,8 +179,8 @@ class RouterNarrationTest { @Test fun `buildNarrationContext includes workflow status entry`(): Unit = runBlocking { - val builder = DefaultRouterContextBuilder(RouterConfig()) - val state = RouterState( + val builder = DefaultTalkieContextBuilder(TalkieConfig()) + val state = TalkieState( sessionId = SessionId("s"), workflowStatus = WorkflowStatus.RUNNING, currentStageId = StageId("my-stage"), @@ -196,8 +196,8 @@ class RouterNarrationTest { @Test fun `buildNarrationContext includes trigger instruction as final entry`(): Unit = runBlocking { - val builder = DefaultRouterContextBuilder(RouterConfig()) - val state = RouterState(sessionId = SessionId("s"), workflowStatus = WorkflowStatus.IDLE) + val builder = DefaultTalkieContextBuilder(TalkieConfig()) + val state = TalkieState(sessionId = SessionId("s"), workflowStatus = WorkflowStatus.IDLE) val instruction = "Narrate the completed action now." val trigger = NarrationTrigger(kind = "stage_completed", instruction = instruction) val pack = builder.buildNarrationContext(state, trigger, TokenBudget(limit = 5000)) @@ -214,8 +214,8 @@ class RouterNarrationTest { // Regression: the trigger instruction must render as a user turn. When it was filed // under L0 it folded into the system message, leaving zero user messages and the chat // template rejected the request ("No user query found in messages"). - val builder = DefaultRouterContextBuilder(RouterConfig()) - val state = RouterState(sessionId = SessionId("s"), workflowStatus = WorkflowStatus.RUNNING) + val builder = DefaultTalkieContextBuilder(TalkieConfig()) + val state = TalkieState(sessionId = SessionId("s"), workflowStatus = WorkflowStatus.RUNNING) val instruction = "Tell the user the stage just completed." val trigger = NarrationTrigger(kind = "stage_completed", instruction = instruction) val pack = builder.buildNarrationContext(state, trigger, TokenBudget(limit = 5000)) @@ -231,8 +231,8 @@ class RouterNarrationTest { @Test fun `buildNarrationContext stays within budget`(): Unit = runBlocking { - val builder = DefaultRouterContextBuilder(RouterConfig()) - val state = RouterState(sessionId = SessionId("s"), workflowStatus = WorkflowStatus.IDLE) + val builder = DefaultTalkieContextBuilder(TalkieConfig()) + val state = TalkieState(sessionId = SessionId("s"), workflowStatus = WorkflowStatus.IDLE) val trigger = NarrationTrigger(kind = "test", instruction = "Short.") val budget = TokenBudget(limit = 5000) val pack = builder.buildNarrationContext(state, trigger, budget) @@ -242,13 +242,13 @@ class RouterNarrationTest { @Test fun `buildNarrationContext does not include conversationHistory turns`(): Unit = runBlocking { - val builder = DefaultRouterContextBuilder(RouterConfig()) - val state = RouterState( + val builder = DefaultTalkieContextBuilder(TalkieConfig()) + val state = TalkieState( sessionId = SessionId("s"), workflowStatus = WorkflowStatus.IDLE, conversationHistory = listOf( - com.correx.core.router.model.RouterTurn( - role = com.correx.core.router.model.TurnRole.USER, + com.correx.core.talkie.model.TalkieTurn( + role = com.correx.core.talkie.model.TurnRole.USER, content = "secret conversation turn", timestamp = kotlinx.datetime.Clock.System.now(), ), @@ -274,19 +274,19 @@ class RouterNarrationTest { latencyMs: Long = 10L, tokensUsed: TokenUsage = TokenUsage(5, 5), l3MemoryStore: L3MemoryStore = InMemoryL3MemoryStore(), - ): DefaultRouterFacade = DefaultRouterFacade( - routerRepository = object : RouterRepository { - override suspend fun getRouterState(sessionId: SessionId): RouterState = - RouterState( + ): DefaultTalkieFacade = DefaultTalkieFacade( + routerRepository = object : TalkieRepository { + override suspend fun getTalkieState(sessionId: SessionId): TalkieState = + TalkieState( sessionId = sessionId, workflowStatus = WorkflowStatus.RUNNING, currentStageId = StageId("s1"), ) }, - routerContextBuilder = DefaultRouterContextBuilder(RouterConfig()), + routerContextBuilder = DefaultTalkieContextBuilder(TalkieConfig()), inferenceRouter = mockInferenceRouter(responseText, latencyMs, tokensUsed), eventStore = eventStore, - config = RouterConfig(tokenBudget = TokenBudget(limit = 5000)), + config = TalkieConfig(tokenBudget = TokenBudget(limit = 5000)), embedder = NoopEmbedder(dimension = 8), l3MemoryStore = l3MemoryStore, ) @@ -372,7 +372,7 @@ class RouterNarrationTest { storedEntries.add(entry) } - override suspend fun query(query: L3Query): List = emptyList() + override suspend fun query(query: L3Query): List = emptyList() override suspend fun existsByTurnIdPrefix(prefix: String): Boolean = false diff --git a/testing/deterministic/src/test/kotlin/RouterProjectorTest.kt b/testing/deterministic/src/test/kotlin/TalkieProjectorTest.kt similarity index 94% rename from testing/deterministic/src/test/kotlin/RouterProjectorTest.kt rename to testing/deterministic/src/test/kotlin/TalkieProjectorTest.kt index 1a91020f..56f6c2fa 100644 --- a/testing/deterministic/src/test/kotlin/RouterProjectorTest.kt +++ b/testing/deterministic/src/test/kotlin/TalkieProjectorTest.kt @@ -9,27 +9,27 @@ import com.correx.core.events.events.WorkflowFailedEvent import com.correx.core.events.events.WorkflowStartedEvent import com.correx.core.events.types.SessionId import com.correx.core.events.types.StageId -import com.correx.core.router.DefaultRouterReducer -import com.correx.core.router.RouterProjector -import com.correx.core.router.model.RouterState -import com.correx.core.router.model.StageOutcomeKind -import com.correx.core.router.model.WorkflowStatus +import com.correx.core.talkie.DefaultTalkieReducer +import com.correx.core.talkie.TalkieProjector +import com.correx.core.talkie.model.TalkieState +import com.correx.core.talkie.model.StageOutcomeKind +import com.correx.core.talkie.model.WorkflowStatus import com.correx.testing.fixtures.EventFixtures.stored import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Assertions.assertNull import org.junit.jupiter.api.Assertions.assertTrue import org.junit.jupiter.api.Test -class RouterProjectorTest { +class TalkieProjectorTest { - private val reducer = DefaultRouterReducer() - private val projector = RouterProjector(reducer) + private val reducer = DefaultTalkieReducer() + private val projector = TalkieProjector(reducer) private val sessionId = SessionId("s1") private val stageId = StageId("stage-1") private val workflowId = "workflow-test" @Test - fun `initial() returns RouterState with IDLE status and empty collections`() { + fun `initial() returns TalkieState with IDLE status and empty collections`() { val state = projector.initial() assertEquals(WorkflowStatus.IDLE, state.workflowStatus) assertNull(state.sessionId) @@ -190,7 +190,7 @@ class RouterProjectorTest { @Test fun `full lifecycle through projector mirrors reducer pipeline`() { - var state: RouterState = projector.initial() + var state: TalkieState = projector.initial() state = projector.apply( state, diff --git a/testing/deterministic/src/test/kotlin/RouterReducerTest.kt b/testing/deterministic/src/test/kotlin/TalkieReducerTest.kt similarity index 97% rename from testing/deterministic/src/test/kotlin/RouterReducerTest.kt rename to testing/deterministic/src/test/kotlin/TalkieReducerTest.kt index 2e2287c2..1dfbbebf 100644 --- a/testing/deterministic/src/test/kotlin/RouterReducerTest.kt +++ b/testing/deterministic/src/test/kotlin/TalkieReducerTest.kt @@ -9,9 +9,9 @@ import com.correx.core.events.events.WorkflowFailedEvent import com.correx.core.events.events.WorkflowStartedEvent import com.correx.core.events.types.SessionId import com.correx.core.events.types.StageId -import com.correx.core.router.DefaultRouterReducer -import com.correx.core.router.model.StageOutcomeKind -import com.correx.core.router.model.WorkflowStatus +import com.correx.core.talkie.DefaultTalkieReducer +import com.correx.core.talkie.model.StageOutcomeKind +import com.correx.core.talkie.model.WorkflowStatus import com.correx.testing.fixtures.EventFixtures.stored import kotlinx.datetime.Instant import org.junit.jupiter.api.Assertions.assertEquals @@ -20,9 +20,9 @@ import org.junit.jupiter.api.Assertions.assertNull import org.junit.jupiter.api.Assertions.assertTrue import org.junit.jupiter.api.Test -class RouterReducerTest { +class TalkieReducerTest { - private val reducer = DefaultRouterReducer() + private val reducer = DefaultTalkieReducer() private val sessionId = SessionId("s1") private val stageId = StageId("stage-1") private val workflowId = "workflow-test" diff --git a/testing/integration/build.gradle b/testing/integration/build.gradle index 0de0ca40..6b8b8e9e 100644 --- a/testing/integration/build.gradle +++ b/testing/integration/build.gradle @@ -29,6 +29,6 @@ dependencies { testImplementation(project(":infrastructure:tools")) testImplementation(project(":infrastructure:tools:filesystem")) testImplementation(project(":apps:server")) - testImplementation(project(":core:router")) + testImplementation(project(":core:talkie")) testImplementation(project(":core:config")) } \ No newline at end of file diff --git a/testing/integration/logs/archive/correx-2026-06-28-1.log.gz b/testing/integration/logs/archive/correx-2026-06-28-1.log.gz new file mode 100644 index 00000000..f8efbbb9 Binary files /dev/null and b/testing/integration/logs/archive/correx-2026-06-28-1.log.gz differ diff --git a/testing/integration/logs/archive/correx-2026-06-30-1.log.gz b/testing/integration/logs/archive/correx-2026-06-30-1.log.gz new file mode 100644 index 00000000..47dc695a Binary files /dev/null and b/testing/integration/logs/archive/correx-2026-06-30-1.log.gz differ diff --git a/testing/integration/logs/archive/correx-2026-07-01-1.log.gz b/testing/integration/logs/archive/correx-2026-07-01-1.log.gz new file mode 100644 index 00000000..ef8a299c Binary files /dev/null and b/testing/integration/logs/archive/correx-2026-07-01-1.log.gz differ diff --git a/testing/integration/logs/archive/correx-2026-07-02-1.log.gz b/testing/integration/logs/archive/correx-2026-07-02-1.log.gz new file mode 100644 index 00000000..9ec0c5b2 Binary files /dev/null and b/testing/integration/logs/archive/correx-2026-07-02-1.log.gz differ diff --git a/testing/integration/src/test/kotlin/RepoMapReuseIntegrationTest.kt b/testing/integration/src/test/kotlin/RepoMapReuseIntegrationTest.kt index 84dcd159..03db6b51 100644 --- a/testing/integration/src/test/kotlin/RepoMapReuseIntegrationTest.kt +++ b/testing/integration/src/test/kotlin/RepoMapReuseIntegrationTest.kt @@ -10,7 +10,7 @@ import com.correx.core.inference.Embedder import com.correx.core.journal.DecisionJournalProjector import com.correx.core.journal.DefaultDecisionJournalReducer import com.correx.core.journal.DefaultDecisionJournalRepository -import com.correx.core.router.l3.InMemoryL3MemoryStore +import com.correx.core.talkie.l3.InMemoryL3MemoryStore import com.correx.core.sessions.projections.replay.DefaultEventReplayer import com.correx.infrastructure.persistence.InMemoryEventStore import kotlinx.coroutines.runBlocking diff --git a/testing/projections/build.gradle b/testing/projections/build.gradle index c62a84f5..795cdd60 100644 --- a/testing/projections/build.gradle +++ b/testing/projections/build.gradle @@ -12,7 +12,7 @@ dependencies { testImplementation(project(":core:inference")) testImplementation(project(":core:kernel")) testImplementation(project(":core:artifacts")) - testImplementation(project(":core:router")) + testImplementation(project(":core:talkie")) testImplementation(project(":core:journal")) implementation(project(":testing:fixtures")) } \ No newline at end of file diff --git a/testing/projections/src/test/kotlin/RouterProjectorTest.kt b/testing/projections/src/test/kotlin/TalkieProjectorTest.kt similarity index 95% rename from testing/projections/src/test/kotlin/RouterProjectorTest.kt rename to testing/projections/src/test/kotlin/TalkieProjectorTest.kt index 75940ea4..0dbac0ef 100644 --- a/testing/projections/src/test/kotlin/RouterProjectorTest.kt +++ b/testing/projections/src/test/kotlin/TalkieProjectorTest.kt @@ -8,19 +8,19 @@ import com.correx.core.events.events.WorkflowFailedEvent import com.correx.core.events.events.WorkflowStartedEvent import com.correx.core.events.types.SessionId import com.correx.core.events.types.StageId -import com.correx.core.router.DefaultRouterReducer -import com.correx.core.router.RouterProjector -import com.correx.core.router.model.StageOutcomeKind -import com.correx.core.router.model.WorkflowStatus +import com.correx.core.talkie.DefaultTalkieReducer +import com.correx.core.talkie.TalkieProjector +import com.correx.core.talkie.model.StageOutcomeKind +import com.correx.core.talkie.model.WorkflowStatus import com.correx.testing.fixtures.EventFixtures.stored import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Assertions.assertNull import org.junit.jupiter.api.Test -class RouterProjectorTest { +class TalkieProjectorTest { - private val reducer = DefaultRouterReducer() - private val projector = RouterProjector(reducer) + private val reducer = DefaultTalkieReducer() + private val projector = TalkieProjector(reducer) private val sessionId = SessionId("s1") private val stageId = StageId("stage-1") private val workflowId = "workflow-test"