Federico Mariani created CAMEL-23955:
----------------------------------------
Summary: camel-openai: conversation memory never persists user
turns and the systemMessage reset is a no-op
Key: CAMEL-23955
URL: https://issues.apache.org/jira/browse/CAMEL-23955
Project: Camel
Issue Type: Bug
Components: camel-openai
Affects Versions: 4.21.0
Reporter: Federico Mariani
Attachments: OpenAIConversationMemoryResetTest.java,
OpenAIConversationMemoryUserMessageTest.java
Two defects in the {{conversationMemory}} feature of the chat-completion
operation, both present since the component was introduced (commit
ac0b0e87f26a, CAMEL-22661).
h3. 1. User turns are never stored in the conversation history
{{OpenAIProducer.updateConversationHistory}} (all three overloads, around lines
663-751) only appends the *assistant* response to the
{{CamelOpenAIConversationHistory}} exchange property. The user message that
produced that response is never added. On the next call the model therefore
sees assistant answers without the user questions that produced them.
Captured request of the second turn from the attached reproducer
({{OpenAIConversationMemoryUserMessageTest}}):
{code}
{"messages":[{"role":"assistant","content":"Nice to meet you!"},
{"content":"What is my name?","role":"user"}],"model":"gpt-5"}
{code}
The first user turn ("My name is Alice") is missing, contradicting the
documented example in {{openai-component.adoc}} ("Conversation Memory (Per
Exchange)": the second response "Will remember Alice").
{{OpenAIToolExecutionProducer}} even works around this bug by re-adding the
user message from the hard-coded {{originalPrompt}} exchange property —
evidence the history is known to be incomplete.
The agentic MCP path has the same defect: {{agenticMessages}} contains
assistant/tool messages but not the triggering user message.
h3. 2. The documented history reset removes a header instead of the exchange
property
{{OpenAIProducer.buildMessages}} (lines 210-214):
{code:java}
// If a system message is configured and conversation memory is enabled, reset
history
if (ObjectHelper.isNotEmpty(config.getSystemMessage()) &&
config.isConversationMemory()) {
in.removeHeader(config.getConversationHistoryProperty());
}
{code}
The conversation history is stored in an exchange *property*
({{addConversationHistory}} reads it via {{getExchange().getProperty(...)}}),
so {{removeHeader}} never removes anything and stale history keeps being sent.
This contradicts the option documentation ("When set and conversationMemory is
enabled, the conversation history is reset") and {{openai-mcp.adoc}}.
Reproducer: {{OpenAIConversationMemoryResetTest}} — the stale entry is still
present in the captured request.
h3. Suggested fix
* Append the outgoing user message (and system/developer messages on the first
turn, if desired) to the history in {{updateConversationHistory}}, for both the
simple and the agentic paths.
* Replace {{in.removeHeader(...)}} with {{exchange.removeProperty(...)}} — or
reconsider whether the reset-on-systemMessage semantics make sense at all now
that it never worked (nobody can have depended on it); if kept, document that
it clears history on *every* call while {{systemMessage}} is set.
Both reproducer tests are attached; they assert the documented behavior and
fail on current main. Related: CAMEL-23394 (history size management) should be
built on top of a corrected history.
_This issue was drafted by Claude Code on behalf of Federico Mariani_
--
This message was sent by Atlassian Jira
(v8.20.10#820010)