refactor: rename the router subsystem to Talkie
The 'router' name was misleading — it's the always-on conversational front-end
(CHAT triage + STEERING into a running workflow), not a routing layer, and it's
distinct from InferenceRouter. Rename core:router -> core:talkie, package
com.correx.core.router -> com.correx.core.talkie, and RouterFacade/Config/State/
Repository/ContextBuilder/Projector/Reducer/Response -> Talkie*. Config section
[router] -> [talkie] (legacy [router] still read as fallback).
Persisted wire formats are preserved: ChatTurnRole.ROUTER and the
RouterNarrationEvent @SerialName("RouterNarration") stay, so existing event
logs still replay. RouterNarrationEvent the class is now TalkieNarrationEvent.
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -9,7 +9,7 @@ data class CorrexConfig(
|
||||
val cli: CliConfig = CliConfig(),
|
||||
val tools: ToolsConfig = ToolsConfig(),
|
||||
val providers: List<ProviderConfig> = emptyList(),
|
||||
val router: RouterConfig = RouterConfig(),
|
||||
val talkie: TalkieConfig = TalkieConfig(),
|
||||
val models: List<ModelConfig> = emptyList(),
|
||||
val modelsSettings: ModelsSettings = ModelsSettings(),
|
||||
val artifacts: List<ArtifactKindConfig> = 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,
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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) =
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ class CorrexConfigWriterTest {
|
||||
shellAllowedExecutables = listOf("git", "ls"),
|
||||
networkAllowedHosts = listOf("example.com"),
|
||||
),
|
||||
router = RouterConfig(
|
||||
talkie = TalkieConfig(
|
||||
conversationKeepLast = 7,
|
||||
retrievalK = 4,
|
||||
tokenBudget = 5000,
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -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,
|
||||
@@ -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)
|
||||
|
||||
+6
-4
@@ -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",
|
||||
@@ -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<RouterState> {
|
||||
|
||||
override fun initial(): RouterState = reducer.initial
|
||||
|
||||
override fun apply(state: RouterState, event: StoredEvent): RouterState =
|
||||
reducer.reduce(state, event)
|
||||
}
|
||||
@@ -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<RouterState>,
|
||||
) : RouterRepository {
|
||||
override suspend fun getRouterState(sessionId: SessionId): RouterState =
|
||||
replayer.rebuild(sessionId)
|
||||
}
|
||||
+2
-2
@@ -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
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package com.correx.core.router
|
||||
package com.correx.core.talkie
|
||||
|
||||
import kotlinx.serialization.json.Json
|
||||
import kotlinx.serialization.json.JsonObject
|
||||
+19
-19
@@ -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<WorkflowSummary> = 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<Idea> = { 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<WorkflowSummary>,
|
||||
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 {
|
||||
+23
-23
@@ -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<WorkflowSummary> = { 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,
|
||||
@@ -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<TalkieState> {
|
||||
|
||||
override fun initial(): TalkieState = reducer.initial
|
||||
|
||||
override fun apply(state: TalkieState, event: StoredEvent): TalkieState =
|
||||
reducer.reduce(state, event)
|
||||
}
|
||||
+23
-23
@@ -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),
|
||||
@@ -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<TalkieState>,
|
||||
) : TalkieRepository {
|
||||
override suspend fun getTalkieState(sessionId: SessionId): TalkieState =
|
||||
replayer.rebuild(sessionId)
|
||||
}
|
||||
+1
-1
@@ -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
|
||||
+1
-1
@@ -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
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package com.correx.core.router.l3
|
||||
package com.correx.core.talkie.l3
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
+1
-1
@@ -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
|
||||
+1
-1
@@ -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.
|
||||
+1
-1
@@ -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
|
||||
+1
-1
@@ -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
|
||||
+1
-1
@@ -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
|
||||
+1
-1
@@ -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(
|
||||
+2
-2
@@ -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(
|
||||
+2
-2
@@ -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),
|
||||
+2
-2
@@ -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,
|
||||
)
|
||||
+4
-4
@@ -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<RouterL2Entry> = emptyList(),
|
||||
val conversationHistory: List<RouterTurn> = emptyList(),
|
||||
val conversationHistory: List<TalkieTurn> = emptyList(),
|
||||
val lastRetrievedMemory: List<L3RetrievedHit> = emptyList(),
|
||||
/**
|
||||
* Steering notes accumulated during the current stage, harvested into the
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package com.correx.core.router.model
|
||||
package com.correx.core.talkie.model
|
||||
|
||||
data class WorkflowSummary(
|
||||
val id: String,
|
||||
+1
-1
@@ -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
|
||||
+1
-1
@@ -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
|
||||
+1
-1
@@ -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
|
||||
+1
-1
@@ -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
|
||||
Reference in New Issue
Block a user