You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
apis/src/openai/responses/compact/tests.rs:239-249 (conversation_text_array_content) — let text = build_conversation_text(&messages);
Description
After rehydration, state.messages contains prior history followed by the current request's normalized state.input. should_compact sends all of state.messages to the summarizer, so the generated summary already includes the current user turn. replace_messages then constructs the outbound context as the summary followed by state.input, duplicating the current turn semantically. This can cause the model to answer or weigh the latest request twice and wastes the context compaction was intended to reclaim.
Reproduction
Construct state with one historical exchange and current input "CURRENT UNIQUE TURN", set history_rehydrated and a zero compaction threshold, and capture the summarization request. Its user message contains CURRENT UNIQUE TURN. After applying the returned summary, inspect state.messages: the summary represents that turn and the original current-input item is also present.
Recommendation
Use the full context for threshold accounting if desired, but build the summarization text only from the history prefix state.messages[..state.messages.len() - state.input.len()]. Preserve state.input exactly once after the compaction item.
Minimum fix scope
Split history from the current-input tail when constructing conversation_text, retaining existing full-context token accounting where appropriate, and add one focused compaction lifecycle test.
Human review gate
This issue requires human review before any work can begin. Do not self-assign and Do not submit a PR before the issue has been validated.
Clawpatch finding
feat_custom_apis_openai_responses_retrieval_proxyfnd_sig-feat-custom-apis-openai-resp_b177a277d520260824T070943-dd5f81.clawpatch/reports/20260824T070943-dd5f81.mdEvidence
apis/src/openai/responses/compact/mod.rs:291-322(should_compact) — let conversation_text = build_conversation_text(&state.messages);apis/src/openai/responses/compact/mod.rs:505-515(replace_messages) — new_messages.extend(state.input.iter().cloned());apis/src/openai/responses/compact/tests.rs:239-249(conversation_text_array_content) — let text = build_conversation_text(&messages);Description
After rehydration,
state.messagescontains prior history followed by the current request's normalizedstate.input.should_compactsends all ofstate.messagesto the summarizer, so the generated summary already includes the current user turn.replace_messagesthen constructs the outbound context as the summary followed bystate.input, duplicating the current turn semantically. This can cause the model to answer or weigh the latest request twice and wastes the context compaction was intended to reclaim.Reproduction
Construct state with one historical exchange and current input
"CURRENT UNIQUE TURN", sethistory_rehydratedand a zero compaction threshold, and capture the summarization request. Its user message containsCURRENT UNIQUE TURN. After applying the returned summary, inspectstate.messages: the summary represents that turn and the original current-input item is also present.Recommendation
Use the full context for threshold accounting if desired, but build the summarization text only from the history prefix
state.messages[..state.messages.len() - state.input.len()]. Preservestate.inputexactly once after the compaction item.Minimum fix scope
Split history from the current-input tail when constructing
conversation_text, retaining existing full-context token accounting where appropriate, and add one focused compaction lifecycle test.Human review gate
This issue requires human review before any work can begin. Do not self-assign and Do not submit a PR before the issue has been validated.