mirror of
				https://github.com/open-webui/open-webui
				synced 2025-06-26 18:26:48 +00:00 
			
		
		
		
	Merge branch 'dev' into playwright
This commit is contained in:
		
						commit
						93cc1a88ee
					
				@ -57,7 +57,7 @@ class ERROR_MESSAGES(str, Enum):
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    FILE_NOT_SENT = "FILE_NOT_SENT"
 | 
			
		||||
    FILE_NOT_SUPPORTED = "Oops! It seems like the file format you're trying to upload is not supported. Please upload a file with a supported format (e.g., JPG, PNG, PDF, TXT) and try again."
 | 
			
		||||
    FILE_NOT_SUPPORTED = "Oops! It seems like the file format you're trying to upload is not supported. Please upload a file with a supported format and try again."
 | 
			
		||||
 | 
			
		||||
    NOT_FOUND = "We could not find what you're looking for :/"
 | 
			
		||||
    USER_NOT_FOUND = "We could not find what you're looking for :/"
 | 
			
		||||
 | 
			
		||||
@ -1101,9 +1101,15 @@ async def process_chat_response(
 | 
			
		||||
                        reasoning_duration = block.get("duration", None)
 | 
			
		||||
 | 
			
		||||
                        if reasoning_duration:
 | 
			
		||||
                            content = f'{content}<details type="reasoning" done="true" duration="{reasoning_duration}">\n<summary>Thought for {reasoning_duration} seconds</summary>\n{reasoning_display_content}\n</details>\n'
 | 
			
		||||
                            if raw:
 | 
			
		||||
                                content = f'{content}<{block["tag"]}>{block["content"]}</{block["tag"]}>\n'
 | 
			
		||||
                            else:
 | 
			
		||||
                                content = f'{content}<details type="reasoning" done="true" duration="{reasoning_duration}">\n<summary>Thought for {reasoning_duration} seconds</summary>\n{reasoning_display_content}\n</details>\n'
 | 
			
		||||
                        else:
 | 
			
		||||
                            content = f'{content}<details type="reasoning" done="false">\n<summary>Thinking…</summary>\n{reasoning_display_content}\n</details>\n'
 | 
			
		||||
                            if raw:
 | 
			
		||||
                                content = f'{content}<{block["tag"]}>{block["content"]}</{block["tag"]}>\n'
 | 
			
		||||
                            else:
 | 
			
		||||
                                content = f'{content}<details type="reasoning" done="false">\n<summary>Thinking…</summary>\n{reasoning_display_content}\n</details>\n'
 | 
			
		||||
 | 
			
		||||
                    elif block["type"] == "code_interpreter":
 | 
			
		||||
                        attributes = block.get("attributes", {})
 | 
			
		||||
@ -1114,11 +1120,14 @@ async def process_chat_response(
 | 
			
		||||
                            output = html.escape(json.dumps(output))
 | 
			
		||||
 | 
			
		||||
                            if raw:
 | 
			
		||||
                                content = f'{content}<details type="code_interpreter" done="true" output="{output}">\n<summary>Analyzed</summary>\n```{lang}\n{block["content"]}\n```\n```output\n{output}\n```\n</details>\n'
 | 
			
		||||
                                content = f'{content}<code_interpreter type="code" lang="{lang}">\n{block["content"]}\n</code_interpreter>\n```output\n{output}\n```\n'
 | 
			
		||||
                            else:
 | 
			
		||||
                                content = f'{content}<details type="code_interpreter" done="true" output="{output}">\n<summary>Analyzed</summary>\n```{lang}\n{block["content"]}\n```\n</details>\n'
 | 
			
		||||
                        else:
 | 
			
		||||
                            content = f'{content}<details type="code_interpreter" done="false">\n<summary>Analyzing...</summary>\n```{lang}\n{block["content"]}\n```\n</details>\n'
 | 
			
		||||
                            if raw:
 | 
			
		||||
                                content = f'{content}<code_interpreter type="code" lang="{lang}">\n{block["content"]}\n</code_interpreter>\n'
 | 
			
		||||
                            else:
 | 
			
		||||
                                content = f'{content}<details type="code_interpreter" done="false">\n<summary>Analyzing...</summary>\n```{lang}\n{block["content"]}\n```\n</details>\n'
 | 
			
		||||
 | 
			
		||||
                    else:
 | 
			
		||||
                        block_content = str(block["content"]).strip()
 | 
			
		||||
@ -1349,6 +1358,15 @@ async def process_chat_response(
 | 
			
		||||
                        if not content_blocks[-1]["content"]:
 | 
			
		||||
                            content_blocks.pop()
 | 
			
		||||
 | 
			
		||||
                    await event_emitter(
 | 
			
		||||
                        {
 | 
			
		||||
                            "type": "chat:completion",
 | 
			
		||||
                            "data": {
 | 
			
		||||
                                "content": serialize_content_blocks(content_blocks),
 | 
			
		||||
                            },
 | 
			
		||||
                        }
 | 
			
		||||
                    )
 | 
			
		||||
 | 
			
		||||
                    if response.background:
 | 
			
		||||
                        await response.background()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -45,7 +45,7 @@
 | 
			
		||||
		promptTemplate,
 | 
			
		||||
		splitStream,
 | 
			
		||||
		sleep,
 | 
			
		||||
		removeDetailsWithReasoning,
 | 
			
		||||
		removeDetails,
 | 
			
		||||
		getPromptVariables
 | 
			
		||||
	} from '$lib/utils';
 | 
			
		||||
 | 
			
		||||
@ -1338,8 +1338,17 @@
 | 
			
		||||
		parentId: string,
 | 
			
		||||
		{ modelId = null, modelIdx = null, newChat = false } = {}
 | 
			
		||||
	) => {
 | 
			
		||||
		const _chatId = JSON.parse(JSON.stringify($chatId));
 | 
			
		||||
		// If modelId is provided, use it, else use selected model
 | 
			
		||||
		let selectedModelIds = modelId
 | 
			
		||||
			? [modelId]
 | 
			
		||||
			: atSelectedModel !== undefined
 | 
			
		||||
				? [atSelectedModel.id]
 | 
			
		||||
				: selectedModels;
 | 
			
		||||
 | 
			
		||||
		// Create response messages for each selected model
 | 
			
		||||
		const responseMessageIds: Record<PropertyKey, string> = {};
 | 
			
		||||
 | 
			
		||||
		const _chatId = JSON.parse(JSON.stringify($chatId));
 | 
			
		||||
		// Create new chat if newChat is true and first user message
 | 
			
		||||
		if (
 | 
			
		||||
			newChat &&
 | 
			
		||||
@ -1351,15 +1360,6 @@
 | 
			
		||||
			await saveChatHandler(_chatId);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// If modelId is provided, use it, else use selected model
 | 
			
		||||
		let selectedModelIds = modelId
 | 
			
		||||
			? [modelId]
 | 
			
		||||
			: atSelectedModel !== undefined
 | 
			
		||||
				? [atSelectedModel.id]
 | 
			
		||||
				: selectedModels;
 | 
			
		||||
 | 
			
		||||
		// Create response messages for each selected model
 | 
			
		||||
		const responseMessageIds: Record<PropertyKey, string> = {};
 | 
			
		||||
		for (const [_modelIdx, modelId] of selectedModelIds.entries()) {
 | 
			
		||||
			const model = $models.filter((m) => m.id === modelId).at(0);
 | 
			
		||||
 | 
			
		||||
@ -1515,7 +1515,7 @@
 | 
			
		||||
				: undefined,
 | 
			
		||||
			...createMessagesList(history, responseMessageId).map((message) => ({
 | 
			
		||||
				...message,
 | 
			
		||||
				content: removeDetailsWithReasoning(message.content)
 | 
			
		||||
				content: removeDetails(message.content, ['reasoning', 'code_interpreter'])
 | 
			
		||||
			}))
 | 
			
		||||
		]
 | 
			
		||||
			.filter((message) => message?.content?.trim())
 | 
			
		||||
 | 
			
		||||
@ -668,8 +668,15 @@ export const cleanText = (content: string) => {
 | 
			
		||||
	return removeFormattings(removeEmojis(content.trim()));
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const removeDetailsWithReasoning = (content) => {
 | 
			
		||||
	return content.replace(/<details\s+type="reasoning"[^>]*>.*?<\/details>/gis, '').trim();
 | 
			
		||||
export const removeDetails = (content, types) => {
 | 
			
		||||
	for (const type of types) {
 | 
			
		||||
		content = content.replace(
 | 
			
		||||
			new RegExp(`<details\\s+type="${type}"[^>]*>.*?<\\/details>`, 'gis'),
 | 
			
		||||
			''
 | 
			
		||||
		);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return content;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// This regular expression matches code blocks marked by triple backticks
 | 
			
		||||
@ -741,7 +748,7 @@ export const extractSentencesForAudio = (text: string) => {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const getMessageContentParts = (content: string, split_on: string = 'punctuation') => {
 | 
			
		||||
	content = removeDetailsWithReasoning(content);
 | 
			
		||||
	content = removeDetails(content, ['reasoning', 'code_interpreter']);
 | 
			
		||||
	const messageContentParts: string[] = [];
 | 
			
		||||
 | 
			
		||||
	switch (split_on) {
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user