@@ -1528,9 +1528,11 @@ async def search_knowledge_files(
15281528 skip : int = 0 ,
15291529 __request__ : Request = None ,
15301530 __user__ : dict = None ,
1531+ __model_knowledge__ : Optional [list [dict ]] = None ,
15311532) -> str :
15321533 """
1533- Search files across knowledge bases the user has access to.
1534+ Search files by filename across knowledge bases the user has access to.
1535+ When the model has attached knowledge, searches only within attached KBs and files.
15341536
15351537 :param query: The search query to find matching files by filename
15361538 :param knowledge_id: Optional KB id to limit search to a specific knowledge base
@@ -1546,10 +1548,87 @@ async def search_knowledge_files(
15461548
15471549 try :
15481550 from open_webui .models .knowledge import Knowledges
1551+ from open_webui .models .files import Files
1552+ from open_webui .models .access_grants import AccessGrants
15491553
15501554 user_id = __user__ .get ('id' )
1555+ user_role = __user__ .get ('role' , 'user' )
15511556 user_group_ids = [group .id for group in Groups .get_groups_by_member_id (user_id )]
15521557
1558+ # When model has attached knowledge, scope to attached KBs/files only
1559+ if __model_knowledge__ :
1560+ attached_kb_ids = set ()
1561+ attached_file_ids = set ()
1562+
1563+ for item in __model_knowledge__ :
1564+ item_type = item .get ('type' )
1565+ item_id = item .get ('id' )
1566+ if item_type == 'collection' :
1567+ attached_kb_ids .add (item_id )
1568+ elif item_type == 'file' :
1569+ attached_file_ids .add (item_id )
1570+
1571+ # If knowledge_id specified, verify it's in the attached set
1572+ if knowledge_id :
1573+ if knowledge_id not in attached_kb_ids :
1574+ return json .dumps ({'error' : f'Knowledge base { knowledge_id } is not attached to this model' })
1575+ attached_kb_ids = {knowledge_id }
1576+
1577+ all_files = []
1578+
1579+ # Search within attached KBs
1580+ for kb_id in attached_kb_ids :
1581+ knowledge = Knowledges .get_knowledge_by_id (kb_id )
1582+ if not knowledge :
1583+ continue
1584+
1585+ if not (
1586+ user_role == 'admin'
1587+ or knowledge .user_id == user_id
1588+ or AccessGrants .has_access (
1589+ user_id = user_id ,
1590+ resource_type = 'knowledge' ,
1591+ resource_id = knowledge .id ,
1592+ permission = 'read' ,
1593+ user_group_ids = set (user_group_ids ),
1594+ )
1595+ ):
1596+ continue
1597+
1598+ result = Knowledges .search_files_by_id (
1599+ knowledge_id = kb_id ,
1600+ user_id = user_id ,
1601+ filter = {'query' : query },
1602+ skip = 0 ,
1603+ limit = count + skip ,
1604+ )
1605+
1606+ for file in result .items :
1607+ all_files .append ({
1608+ 'id' : file .id ,
1609+ 'filename' : file .filename ,
1610+ 'knowledge_id' : knowledge .id ,
1611+ 'knowledge_name' : knowledge .name ,
1612+ 'updated_at' : file .updated_at ,
1613+ })
1614+
1615+ # Search within directly attached files (filename match)
1616+ if not knowledge_id and attached_file_ids :
1617+ query_lower = query .lower () if query else ''
1618+ for file_id in attached_file_ids :
1619+ file = Files .get_file_by_id (file_id )
1620+ if file and (not query_lower or query_lower in file .filename .lower ()):
1621+ all_files .append ({
1622+ 'id' : file .id ,
1623+ 'filename' : file .filename ,
1624+ 'updated_at' : file .updated_at ,
1625+ })
1626+
1627+ # Apply pagination across combined results
1628+ all_files = all_files [skip :skip + count ]
1629+ return json .dumps (all_files , ensure_ascii = False )
1630+
1631+ # No attached knowledge - search all accessible KBs
15531632 if knowledge_id :
15541633 result = Knowledges .search_files_by_id (
15551634 knowledge_id = knowledge_id ,
@@ -1793,7 +1872,7 @@ async def view_knowledge_file(
17931872 return json .dumps ({'error' : str (e )})
17941873
17951874
1796- async def list_attached_knowledge (
1875+ async def list_knowledge (
17971876 __request__ : Request = None ,
17981877 __user__ : dict = None ,
17991878 __model_knowledge__ : Optional [list [dict ]] = None ,
@@ -1895,121 +1974,7 @@ async def list_attached_knowledge(
18951974 'notes' : notes ,
18961975 }, ensure_ascii = False )
18971976 except Exception as e :
1898- log .exception (f'list_attached_knowledge error: { e } ' )
1899- return json .dumps ({'error' : str (e )})
1900-
1901-
1902- async def search_attached_files (
1903- query : str ,
1904- knowledge_id : Optional [str ] = None ,
1905- count : int = 10 ,
1906- skip : int = 0 ,
1907- __request__ : Request = None ,
1908- __user__ : dict = None ,
1909- __model_knowledge__ : Optional [list [dict ]] = None ,
1910- ) -> str :
1911- """
1912- Search files by filename within the attached knowledge scope.
1913- Only searches knowledge bases and files that are attached to the current model.
1914-
1915- :param query: The filename search query
1916- :param knowledge_id: Optional KB id to limit search to a specific attached knowledge base
1917- :param count: Maximum number of results to return (default: 10)
1918- :param skip: Number of results to skip for pagination (default: 0)
1919- :return: JSON with matching files containing id, filename, knowledge_id, and knowledge_name
1920- """
1921- if __request__ is None :
1922- return json .dumps ({'error' : 'Request context not available' })
1923-
1924- if not __user__ :
1925- return json .dumps ({'error' : 'User context not available' })
1926-
1927- if not __model_knowledge__ :
1928- return json .dumps ([])
1929-
1930- try :
1931- from open_webui .models .knowledge import Knowledges
1932- from open_webui .models .files import Files
1933- from open_webui .models .access_grants import AccessGrants
1934-
1935- user_id = __user__ .get ('id' )
1936- user_role = __user__ .get ('role' , 'user' )
1937- user_group_ids = [group .id for group in Groups .get_groups_by_member_id (user_id )]
1938-
1939- # Collect attached KB IDs and direct file IDs
1940- attached_kb_ids = set ()
1941- attached_file_ids = set ()
1942-
1943- for item in __model_knowledge__ :
1944- item_type = item .get ('type' )
1945- item_id = item .get ('id' )
1946- if item_type == 'collection' :
1947- attached_kb_ids .add (item_id )
1948- elif item_type == 'file' :
1949- attached_file_ids .add (item_id )
1950-
1951- # If knowledge_id is specified, verify it's in the attached set
1952- if knowledge_id :
1953- if knowledge_id not in attached_kb_ids :
1954- return json .dumps ({'error' : f'Knowledge base { knowledge_id } is not attached to this model' })
1955- attached_kb_ids = {knowledge_id }
1956-
1957- all_files = []
1958-
1959- # Search within attached KBs
1960- for kb_id in attached_kb_ids :
1961- knowledge = Knowledges .get_knowledge_by_id (kb_id )
1962- if not knowledge :
1963- continue
1964-
1965- if not (
1966- user_role == 'admin'
1967- or knowledge .user_id == user_id
1968- or AccessGrants .has_access (
1969- user_id = user_id ,
1970- resource_type = 'knowledge' ,
1971- resource_id = knowledge .id ,
1972- permission = 'read' ,
1973- user_group_ids = set (user_group_ids ),
1974- )
1975- ):
1976- continue
1977-
1978- result = Knowledges .search_files_by_id (
1979- knowledge_id = kb_id ,
1980- user_id = user_id ,
1981- filter = {'query' : query },
1982- skip = 0 ,
1983- limit = count + skip , # Fetch enough for pagination across KBs
1984- )
1985-
1986- for file in result .items :
1987- all_files .append ({
1988- 'id' : file .id ,
1989- 'filename' : file .filename ,
1990- 'knowledge_id' : knowledge .id ,
1991- 'knowledge_name' : knowledge .name ,
1992- 'updated_at' : file .updated_at ,
1993- })
1994-
1995- # Search within directly attached files (filename match)
1996- if not knowledge_id and attached_file_ids :
1997- query_lower = query .lower () if query else ''
1998- for file_id in attached_file_ids :
1999- file = Files .get_file_by_id (file_id )
2000- if file and (not query_lower or query_lower in file .filename .lower ()):
2001- all_files .append ({
2002- 'id' : file .id ,
2003- 'filename' : file .filename ,
2004- 'updated_at' : file .updated_at ,
2005- })
2006-
2007- # Apply pagination across combined results
2008- all_files = all_files [skip :skip + count ]
2009-
2010- return json .dumps (all_files , ensure_ascii = False )
2011- except Exception as e :
2012- log .exception (f'search_attached_files error: { e } ' )
1977+ log .exception (f'list_knowledge error: { e } ' )
20131978 return json .dumps ({'error' : str (e )})
20141979
20151980
0 commit comments