99from jupyter_ai .tools .models import Tool , Toolkit
1010
1111
12- async def read (file_path : str , offset : Optional [int ] = None , limit : Optional [int ] = None ) -> str :
12+ def read (file_path : str , offset : Optional [int ] = None , limit : Optional [int ] = None ) -> str :
1313 """Reads a file from the local filesystem
1414
1515 Args:
@@ -27,31 +27,31 @@ async def read(file_path: str, offset: Optional[int] = None, limit: Optional[int
2727 if not os .path .isfile (file_path ):
2828 return f"Error: Not a file: { file_path } "
2929
30- content = await _read_file_content (file_path , offset , limit )
30+ content = _read_file_content (file_path , offset , limit )
3131 return content
3232 except Exception as e :
3333 return f"Error: Failed to read file: { str (e )} "
3434
3535
36- async def _read_file_content (
36+ def _read_file_content (
3737 file_path : str , offset : Optional [int ] = None , limit : Optional [int ] = None
3838) -> str :
3939 """Helper function to read file content in a separate thread"""
4040 with open (file_path , "r" , encoding = "utf-8" ) as f :
4141 if offset is not None :
4242 # Skip lines until we reach the offset
4343 for _ in range (offset ):
44- line = await f .readline ()
44+ line = f .readline ()
4545 if not line :
4646 break
4747
4848 # Read the specified number of lines or all lines if limit is None
4949 if limit is not None :
50- lines = [await f .readline () for _ in range (limit )]
50+ lines = [f .readline () for _ in range (limit )]
5151 # Filter out None values in case we hit EOF
5252 lines = [line for line in lines if line ]
5353 else :
54- lines = await f .readlines ()
54+ lines = f .readlines ()
5555
5656 # Add line numbers (starting from offset+1 if offset is provided)
5757 start_line = (offset or 0 ) + 1
@@ -60,7 +60,6 @@ async def _read_file_content(
6060 return "" .join (numbered_lines )
6161
6262
63- # Question: Should this be async?
6463def write (file_path : str , content : str ) -> str :
6564 """Writes content to a file on the local filesystem
6665
@@ -89,7 +88,7 @@ def _write_file_content(file_path: str, content: str) -> None:
8988 f .write (content )
9089
9190
92- async def edit (file_path : str , old_string : str , new_string : str , replace_all : bool = False ) -> str :
91+ def edit (file_path : str , old_string : str , new_string : str , replace_all : bool = False ) -> str :
9392 """Performs string replacement in a file
9493
9594 Args:
@@ -114,7 +113,7 @@ async def edit(file_path: str, old_string: str, new_string: str, replace_all: bo
114113
115114 # Check if old_string exists in the file
116115 if old_string not in content :
117- return f "Error: String to replace not found in file"
116+ return "Error: String to replace not found in file"
118117
119118 # Perform the replacement
120119 if replace_all :
@@ -209,12 +208,13 @@ async def glob(pattern: str, path: Optional[str] = None) -> List[str]:
209208 matching_files = await asyncio .to_thread (_glob_search , search_path , pattern )
210209
211210 if not matching_files :
212- return []
211+ return "No matching files found"
213212
214213 # Sort files by modification time (most recent first)
215214 matching_files .sort (key = lambda f : os .path .getmtime (f ), reverse = True )
216-
217- return matching_files
215+ matching_files = [str (f ) for f in matching_files ]
216+
217+ return "\n " .join (matching_files )
218218 except Exception as e :
219219 return [f"Error: Failed to perform glob search: { str (e )} " ]
220220
@@ -284,7 +284,7 @@ async def grep(
284284 return [f"Error: Failed to perform grep search: { str (e )} " ]
285285
286286
287- async def ls (path : str , ignore : Optional [List [str ]] = None ) -> List [ str ] :
287+ async def ls (path : str , ignore : Optional [List [str ]] = None ) -> str :
288288 """Lists files and directories in a given path
289289
290290 Args:
@@ -327,7 +327,7 @@ async def ls(path: str, ignore: Optional[List[str]] = None) -> List[str]:
327327 # Sort by type (directories first) and then by name
328328 full_paths .sort (key = lambda p : (0 if os .path .isdir (p ) else 1 , p .lower ()))
329329
330- return full_paths
330+ return " \n " . join ( full_paths )
331331 except Exception as e :
332332 return [f"Error: Failed to list directory: { str (e )} " ]
333333
@@ -336,11 +336,11 @@ async def ls(path: str, ignore: Optional[List[str]] = None) -> List[str]:
336336 name = "file_system_toolkit" ,
337337 description = "Tools to do search, list, read, write and edit operations on files." ,
338338)
339- toolkit .add (Tool (callable = read , read = True ))
340- toolkit .add (Tool (callable = write , write = True ))
341- toolkit .add (Tool (callable = edit , read = True , write = True ))
342- toolkit .add (Tool (callable = search_and_replace , read = True , write = True ))
343- toolkit .add (Tool (callable = glob , read = True ))
344- toolkit .add (Tool (callable = grep , read = True ))
345- toolkit .add (Tool (callable = ls , read = True ))
339+ toolkit .add_tool (Tool (callable = read , read = True ))
340+ toolkit .add_tool (Tool (callable = edit , read = True , write = True ))
341+ toolkit .add_tool (Tool (callable = write , write = True ))
342+ toolkit .add_tool (Tool (callable = search_and_replace , read = True , write = True ))
343+ toolkit .add_tool (Tool (callable = glob , read = True ))
344+ toolkit .add_tool (Tool (callable = grep , read = True ))
345+ toolkit .add_tool (Tool (callable = ls , read = True ))
346346
0 commit comments