diff --git a/backend/open_webui/utils/context_compaction.py b/backend/open_webui/utils/context_compaction.py index aeb4e9875e..d9cb7879f7 100644 --- a/backend/open_webui/utils/context_compaction.py +++ b/backend/open_webui/utils/context_compaction.py @@ -1,6 +1,7 @@ from __future__ import annotations import logging +import re from typing import Any from fastapi.responses import JSONResponse @@ -19,6 +20,8 @@ from open_webui.utils.task import ( log = logging.getLogger(__name__) +BASE64_DATA_URI_RE = re.compile(r'data:[\w/+.;=%-]*;base64,[A-Za-z0-9+/=]*') + DEFAULT_CONTEXT_COMPACTION_PROMPT = """### Task: Summarize the conversation history that will be compacted out of the active chat context. @@ -439,7 +442,10 @@ def _estimate_messages_tokens(messages: list[dict]) -> int: total += _estimate_tokens(message.get('output')) total += _estimate_tokens(message.get('tool_calls')) - total += _estimate_tokens(message.get('files')) + files = message.get('files') + if files: + # Inline data is not part of the file tags sent to the model. + total += _estimate_tokens(BASE64_DATA_URI_RE.sub('', JSONCodec.dumps(files, ensure_ascii=False))) return total diff --git a/src/lib/components/chat/Chat.svelte b/src/lib/components/chat/Chat.svelte index ba8c2ccb7e..adfe074fd5 100644 --- a/src/lib/components/chat/Chat.svelte +++ b/src/lib/components/chat/Chat.svelte @@ -257,7 +257,11 @@ let next = total + 4 + estimateTokens(message.content); next += estimateTokens(message.output); next += estimateTokens(message.tool_calls); - next += estimateTokens(message.files); + if (message.files?.length) { + next += estimateTokens( + JSON.stringify(message.files).replace(/data:[\w/+.;=%-]*;base64,[A-Za-z0-9+/=]*/g, '') + ); + } return next; }, 0); diff --git a/src/lib/components/chat/MessageInput.svelte b/src/lib/components/chat/MessageInput.svelte index 2adbc27bb3..c621071884 100644 --- a/src/lib/components/chat/MessageInput.svelte +++ b/src/lib/components/chat/MessageInput.svelte @@ -473,7 +473,11 @@ let next = total + 4 + estimateTokens(message.content); next += estimateTokens(message.output); next += estimateTokens(message.tool_calls); - next += estimateTokens(message.files); + if (message.files?.length) { + next += estimateTokens( + JSON.stringify(message.files).replace(/data:[\w/+.;=%-]*;base64,[A-Za-z0-9+/=]*/g, '') + ); + } return next; }, 0);