mirror of
https://github.com/open-webui/open-webui.git
synced 2026-09-08 22:21:38 +00:00
fix: stop citing web search results as sources (#29631)
A web search is not something that can be cited. The search engine returns a title, a link and a one line snippet for each hit, and the model never opens any of those pages. Emitting them as citation sources produced one <source> tag per result, all named search_web with empty bodies, and the citation template then instructed the model to cite them by id. Models either hesitated visibly or attached an id to content from a different result, which the citations panel then resolved to a title that looked plausible, so the misattribution read as correct. Web search results now stay in the tool output the model reads, and stop being offered as things to cite. Where the model needs to cite a page it calls fetch_url, whose citation names the URL and already works. Web search results no longer appear in the citations panel. That is the point of the change: the panel was offering pages that nothing had read. Scoped to the native tool-calling path. The legacy handler cites every tool result as one opaque source and does not single out web search, so it is left alone rather than special-cased.
This commit is contained in:
parent
0b804c5316
commit
c7cce962d2
1 changed files with 6 additions and 38 deletions
|
|
@ -400,9 +400,6 @@ def get_citation_source_from_tool_result(
|
|||
|
||||
Returns a list of sources (usually one, but query_knowledge_files/query_chat_files may return multiple).
|
||||
"""
|
||||
_EXPECTS_LIST = {'search_web', 'query_knowledge_files', 'query_chat_files'}
|
||||
_EXPECTS_DICT = {'view_knowledge_file', 'view_file'}
|
||||
|
||||
try:
|
||||
try:
|
||||
tool_result = JSONCodec.loads(tool_result)
|
||||
|
|
@ -411,41 +408,10 @@ def get_citation_source_from_tool_result(
|
|||
if isinstance(tool_result, dict) and 'error' in tool_result:
|
||||
return []
|
||||
|
||||
# Validate tool_result type based on what the branch expects
|
||||
if tool_name in _EXPECTS_LIST and not isinstance(tool_result, list):
|
||||
return []
|
||||
elif tool_name in _EXPECTS_DICT and not isinstance(tool_result, dict):
|
||||
return []
|
||||
if tool_name in ('view_knowledge_file', 'view_file'):
|
||||
if not isinstance(tool_result, dict):
|
||||
return []
|
||||
|
||||
if tool_name == 'search_web':
|
||||
# Parse JSON array: [{"title": "...", "link": "...", "snippet": "..."}]
|
||||
results = tool_result
|
||||
documents = []
|
||||
metadata = []
|
||||
|
||||
for result in results:
|
||||
title = result.get('title', '')
|
||||
link = result.get('link', '')
|
||||
snippet = result.get('snippet', '')
|
||||
|
||||
documents.append(f'{title}\n{snippet}')
|
||||
metadata.append(
|
||||
{
|
||||
'source': link,
|
||||
'name': title,
|
||||
'url': link,
|
||||
}
|
||||
)
|
||||
|
||||
return [
|
||||
{
|
||||
'source': {'name': 'search_web', 'id': 'search_web'},
|
||||
'document': documents,
|
||||
'metadata': metadata,
|
||||
}
|
||||
]
|
||||
|
||||
elif tool_name in ('view_knowledge_file', 'view_file'):
|
||||
file_data = tool_result
|
||||
filename = file_data.get('filename', 'Unknown File')
|
||||
file_id = file_data.get('id', '')
|
||||
|
|
@ -490,6 +456,9 @@ def get_citation_source_from_tool_result(
|
|||
]
|
||||
|
||||
elif tool_name in ('query_knowledge_files', 'query_chat_files'):
|
||||
if not isinstance(tool_result, list):
|
||||
return []
|
||||
|
||||
chunks = tool_result
|
||||
|
||||
# Group chunks by source for better citation display
|
||||
|
|
@ -5772,7 +5741,6 @@ async def streaming_chat_response_handler(response, ctx):
|
|||
citations_enabled
|
||||
and tool_function_name
|
||||
in [
|
||||
'search_web',
|
||||
'fetch_url',
|
||||
'view_file',
|
||||
'view_knowledge_file',
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue