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());