fix: use the active chat model for context compaction when no compaction model is set

The "Context Compaction Model" setting offers a "Current Model" option, described in the admin panel as following the active chat model. That option writes an empty string, which `_generate_summary` treated as "no override" and then resolved through `get_task_model_id`, returning the configured Local or External Task Model whenever one is set. On any instance with a task model configured, compaction therefore ran on the task model and "Current Model" did nothing.

Resolve the compaction model directly instead: use the configured compaction model when it is available, otherwise the active chat model. Task model settings keep governing title, tags, query and follow-up generation; only compaction stops inheriting them. Admins who want compaction on the task model can select that model explicitly in the compaction dropdown.

Note for existing deployments: instances that set a task model and left the compaction model unset will now compact on the active chat model, which is what the setting always claimed to do but may be a more expensive model. Select the intended model in the Context Compaction Model dropdown to pin it.

Fixes #27603
This commit is contained in:
Classic298 2026-07-28 23:31:44 +02:00
parent 29541cbb52
commit 443c0bea8e

View file

@ -11,7 +11,6 @@ from open_webui.utils.json_codec import JSONCodec
from open_webui.utils.misc import get_content_from_message, get_last_user_message, get_message_list
from open_webui.utils.payload import apply_params_to_form_data
from open_webui.utils.task import (
get_task_model_id,
prompt_template,
prompt_variables_template,
replace_messages_variable,
@ -366,25 +365,13 @@ async def _generate_summary(
from open_webui.utils.chat import generate_chat_completion
task_config = await Config.get_many(
'task.model.default',
'task.model.external',
'task.model.params',
'chat.context_compaction.model',
)
context_compaction_model = task_config.get('chat.context_compaction.model')
task_model_id = (
context_compaction_model
if context_compaction_model in models
else get_task_model_id(
model_id,
task_config.get('task.model.default'),
task_config.get('task.model.external'),
models,
)
)
if task_model_id not in models:
task_model_id = model_id
if task_model_id not in models:
configured_model_id = task_config.get('chat.context_compaction.model')
# Unset or unavailable falls back to the active chat model, never the generic task model.
compaction_model_id = configured_model_id if configured_model_id in models else model_id
if compaction_model_id not in models:
raise ValueError('No available model for context compaction')
summary_prompt_template = summary_prompt_template.strip() or DEFAULT_CONTEXT_COMPACTION_PROMPT
@ -401,11 +388,11 @@ async def _generate_summary(
task_model_params = {}
task_model_params = {key: value for key, value in task_model_params.items() if value is not None and value != ''}
task_model_params = task_model_params or {
'max_tokens': models[task_model_id].get('info', {}).get('params', {}).get('max_tokens', 1000)
'max_tokens': models[compaction_model_id].get('info', {}).get('params', {}).get('max_tokens', 1000)
}
payload = {
'model': task_model_id,
'model': compaction_model_id,
'messages': [{'role': 'user', 'content': prompt}],
'stream': False,
'metadata': {
@ -414,7 +401,7 @@ async def _generate_summary(
},
}
payload = apply_params_to_form_data(payload, models[task_model_id], task_model_params)
payload = apply_params_to_form_data(payload, models[compaction_model_id], task_model_params)
response = await generate_chat_completion(request, form_data=payload, user=user)
summary = _response_text(response).strip()
if summary: