From 77c28ba313b1b03a72f1e74ca68033d52dce2059 Mon Sep 17 00:00:00 2001 From: kami Date: Fri, 3 Jul 2026 13:16:20 +0400 Subject: [PATCH] refactor(config): move embedder/l3 to top-level [embedder]/[l3] sections They are shared infra (the orchestrator uses them for workflow repo-knowledge, not just the router chat layer), so [router.embedder]/[router.l3] was misleading. Loader/writer use the new names; legacy [router.*] still read as a fallback. Also notes the STEERING LLM-reformulation cost as a ponytail follow-up. --- .../main/kotlin/com/correx/core/config/ConfigLoader.kt | 7 +++++-- .../kotlin/com/correx/core/config/CorrexConfigWriter.kt | 4 ++-- .../main/kotlin/com/correx/core/router/RouterFacade.kt | 5 +++++ docs/sample-config.toml | 9 ++++++--- 4 files changed, 18 insertions(+), 7 deletions(-) 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 125b0a20..66b8cfbe 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 @@ -419,8 +419,11 @@ object ConfigLoader { val toolsFileWriteSection = sections["tools.file_write"] ?: emptyMap() val toolsFileEditSection = sections["tools.file_edit"] ?: emptyMap() val routerSection = sections["router"] ?: emptyMap() - val routerEmbedderSection = sections["router.embedder"] ?: emptyMap() - val routerL3Section = sections["router.l3"] ?: 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 modelsSection = sections["models"] ?: emptyMap() 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 8744aeab..bbfd5e68 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 @@ -56,13 +56,13 @@ object CorrexConfigWriter { b.kv("retrieval_k", cfg.router.retrievalK) b.kv("token_budget", cfg.router.tokenBudget) - b.section("router.embedder") + 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.section("router.l3") + 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)) diff --git a/core/router/src/main/kotlin/com/correx/core/router/RouterFacade.kt b/core/router/src/main/kotlin/com/correx/core/router/RouterFacade.kt index d303647a..8051e712 100644 --- a/core/router/src/main/kotlin/com/correx/core/router/RouterFacade.kt +++ b/core/router/src/main/kotlin/com/correx/core/router/RouterFacade.kt @@ -186,6 +186,11 @@ class DefaultRouterFacade( emitIdeasCaptured(sessionId, ideas.ideas) } + // ponytail: STEERING launders the user's text through the router LLM (the `content` above) + // before injecting it as a note. For a clear instruction that's an extra inference that can + // distort intent; the reformulation only earns its cost when the input is terse/context- + // dependent. Upgrade path: inject the raw (validated) input directly and skip the rewrite + // unless a heuristic flags the message as too short/ambiguous to stand alone. val steeringEmitted = mode == ChatMode.STEERING && rawContent.isNotBlank() if (steeringEmitted) { val validationError = validateSteering?.invoke(content) diff --git a/docs/sample-config.toml b/docs/sample-config.toml index 6d56351c..133ed4de 100644 --- a/docs/sample-config.toml +++ b/docs/sample-config.toml @@ -107,15 +107,18 @@ top_p = 0.9 max_tokens = 1024 max_per_run = 100 -[router.embedder] +# Embedder + L3 vector memory. Shared infra: the orchestrator uses these for workflow +# repo-knowledge retrieval, not just the router chat layer — hence top-level, not [router.*]. +# (Legacy [router.embedder] / [router.l3] are still read as a fallback.) +[embedder] backend = "noop" # or "llamacpp" dimension = 1536 # url = "http://127.0.0.1:11000" # model_id = "nomic-embed-text" -[router.l3] +[l3] backend = "in_memory" # or "turbovec" -# persist_path = "~/.config/correx/router/l3/index.tq" +# persist_path = "~/.config/correx/l3/index.tq" # python_executable = "python3" # script_path = "~/.config/correx/python/turbovec_sidecar.py" # dim = 1536