From 89a74f4cbdf7ca65a69f83b750c41fd484125947 Mon Sep 17 00:00:00 2001 From: ULookup Date: Mon, 22 Jun 2026 09:15:06 +0000 Subject: [PATCH] fix(context): inject system prompt into messages so it reaches the LLM MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SerializedPayload.system_text was built by the serializer but never placed into payload.messages. AgentLoop::build_context() only returned payload.messages (conversation history), so the system prompt — including agent identity from merak_core.md — was silently dropped before reaching the LLM. DeepSeek then defaulted to its training identity ("Claude"). - Add system_text field to SerializedPayload - Set it in ContextSerializer::serialize() - Prepend system message in AgentLoop::build_context() --- libs/context/include/merak/context_serializer.hpp | 1 + libs/context/src/context_serializer.cpp | 1 + libs/loop/src/agent_loop.cpp | 11 +++++++++-- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/libs/context/include/merak/context_serializer.hpp b/libs/context/include/merak/context_serializer.hpp index b0549b74..de4e78fe 100644 --- a/libs/context/include/merak/context_serializer.hpp +++ b/libs/context/include/merak/context_serializer.hpp @@ -11,6 +11,7 @@ namespace merak { struct SerializedPayload { nlohmann::json openai_json; nlohmann::json anthropic_json; + std::string system_text; std::vector messages; std::vector tool_schemas; bool is_anthropic = false; diff --git a/libs/context/src/context_serializer.cpp b/libs/context/src/context_serializer.cpp index 76f2ed28..068eaf4c 100644 --- a/libs/context/src/context_serializer.cpp +++ b/libs/context/src/context_serializer.cpp @@ -22,6 +22,7 @@ SerializedPayload ContextSerializer::serialize( if (!system_prompt_full.empty()) { system_text = system_prompt_full + "\n\n" + system_text; } + payload.system_text = system_text; payload.messages = ctx.provider_messages; payload.tool_schemas = ctx.tool_schemas; diff --git a/libs/loop/src/agent_loop.cpp b/libs/loop/src/agent_loop.cpp index 0ac49681..4cbd8399 100644 --- a/libs/loop/src/agent_loop.cpp +++ b/libs/loop/src/agent_loop.cpp @@ -496,9 +496,16 @@ std::vector AgentLoop::build_context() { effective_system_prompt, config_.default_model, config_.model_max_tokens, session_history_, sources); - // Prepend compaction summaries before returning (they are NOT part - // of session_history_ to avoid index conflicts) + // Prepend system prompt before conversation messages. + // The pipeline serializes it but does not inject it into payload.messages, + // so we must do it here for it to reach the LLM. auto messages = payload.messages; + if (!payload.system_text.empty()) { + Message sys_msg; + sys_msg.role = "system"; + sys_msg.content = payload.system_text; + messages.insert(messages.begin(), sys_msg); + } if (!compaction_summaries_.empty()) { messages.insert(messages.begin(), compaction_summaries_.begin(), compaction_summaries_.end());