mirror of
https://github.com/open-webui/open-webui.git
synced 2026-10-24 05:44:07 +00:00
fix: preserve system prompt across context compaction
Context compaction dropped the user's system prompt and replaced it with the summary. compact_messages_for_request() treated messages[0] (the chat system prompt, re-prepended in middleware) as ordinary history: _find_compaction_boundary always folded it into the compacted slice, and _apply_latest_summary_checkpoint's messages[summary_idx:] slice cut it off on every subsequent turn. The function then returned only recent_messages with no system role, so add_or_update_system_message(..., append=True) had nothing to append to and inserted a summary-only system message instead. The system_prompt argument was used purely for token estimation, never to exempt it from compaction. Pop a leading system message on entry and re-prepend it on every return path, so the summarizer never sees it and append=True appends the summary to the real system prompt as intended. Fixes #26710
This commit is contained in:
parent
4b55e69640
commit
cb5bb1e7b0
1 changed files with 11 additions and 3 deletions
|
|
@ -52,16 +52,24 @@ async def compact_messages_for_request(
|
|||
if not config['enable']:
|
||||
return messages, None, False
|
||||
|
||||
# Exempt a leading system message from compaction; re-prepend on every return.
|
||||
system_message = None
|
||||
if messages and messages[0].get('role') == 'system':
|
||||
system_message, messages = messages[0], messages[1:]
|
||||
|
||||
def _restore(msgs: list[dict]) -> list[dict]:
|
||||
return [system_message, *msgs] if system_message else msgs
|
||||
|
||||
messages, previous_summary = _apply_latest_summary_checkpoint(messages)
|
||||
token_threshold = _resolve_token_threshold(config['token_threshold'], metadata)
|
||||
if not _exceeds_token_threshold(messages, system_prompt, previous_summary, token_threshold) or len(messages) <= 3:
|
||||
return messages, previous_summary, False
|
||||
return _restore(messages), previous_summary, False
|
||||
|
||||
boundary = _find_compaction_boundary(messages)
|
||||
compacted_messages = messages[:boundary]
|
||||
recent_messages = messages[boundary:]
|
||||
if not compacted_messages or not recent_messages:
|
||||
return messages, previous_summary, False
|
||||
return _restore(messages), previous_summary, False
|
||||
|
||||
event_emitter = None
|
||||
if metadata.get('chat_id') and metadata.get('message_id'):
|
||||
|
|
@ -138,7 +146,7 @@ async def compact_messages_for_request(
|
|||
}
|
||||
)
|
||||
|
||||
return recent_messages, summary, True
|
||||
return _restore(recent_messages), summary, True
|
||||
|
||||
|
||||
async def compact_chat_branch(request, user, chat: Any, model_id: str, models: dict) -> dict:
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue