def calc_div(a:int,b:int):
"Divides a/b - example tool"
try: return a/b
except: return explain_exc("dividing")
calc_div(1,0)'Error: division by zero'
Convert an current exception to an LLM friendly error message.
'Error: division by zero'
Works like assert b, msg but raise ValueError and is not disabled when run with python -O
'Error: B cannot be zero'
Return expanded/resolved Path, raising FileNotFoundError if must_exist and missing
def run_cmd(
cmd:str, # The command name to run
argstr:str='', # All args to the command, will be split with shlex
disallow_re:str=None, # optional regex which, if matched on argstr, will disallow the command
allow_re:str=None, # optional regex which, if not matched on argstr, will disallow the command
):
Run cmd passing split argstr, optionally checking for allowed argstr
With this little function, we can now run any cli command:
__pycache__
_parallel_win.ipynb
_quarto.yml
00_test.ipynb
000_tour.ipynb
01_basics.ipynb
02_foundation.ipynb
03_xtras
Note that, for tool safety, this is not passed through the shell, so wildcards, env vars, etc will not work:
Let’s create some useful functions from this that will allow for searching, reading and modifing content on the file system.
Run the rg command with the args in argstr (no need to backslash escape)
Functions implemented with run_cmd like this one can be passed regexps to allow or disallow arg strs, i.e to block parent or root directories:
disallowed = r' /|\.\.'
rg('[email protected] ..', disallow_re=disallowed)'Error: args disallowed'
rg('[email protected] /', disallow_re=disallowed)'Error: args disallowed'
NB: These tools have special behavior around errors. Since these have been speficially designed for work with LLMs, any exceptions created from there use is returned as a string to help them debug their work.
Run the sed command with the args in argstr (e.g for reading a section of a file)
project:
type: website
pre-render:
- pysym2md --output_file apilist.txt fastcore
post-render:
Python implementations of the text editor tools from Anthropic, plus more. These tools are especially useful in an AI’s tool loop. See claudette for examples.
def view(
path:str, # Path to directory or file to view
view_range:tuple=None, # Optional 1-indexed (start, end) line range for files, end=-1 for EOF. Do NOT use unless it's known that the file is too big to keep in context—simply view the WHOLE file when possible
nums:bool=False, # Whether to show line numbers
skip_folders:tuple=('_proc', '__pycache__'), # Folder names to skip when listing directories
):
View directory or file contents with optional line range and numbers
You can specify line ranges and whether to have the output contain line numbers:
1 │ project:
2 │ type: website
3 │ pre-render:
4 │ - pysym2md --output_file apilist.txt fastcore
5 │ post-render:
6 │ - llms_txt2ctx llms.txt --optional true --save_nbdev_fname llms-ctx-full.txt
7 │ - llms_txt2ctx llms.txt --save_nbdev_fname llms-ctx.txt
8 │ resources:
9 │ - "*.txt"
10 │ preview:
Here’s what the output looks like when viewing a directory:
Directory contents of /path:
/path/llms.txt (3.7k)
/path/000_tour.ipynb (18.2k)
/path/parallel_test.py (0.6k)
/path/_quarto.yml (0.8k)
/path/08_style.ipynb (12.3k)
Creates a new file with the given content at the specified path
Created file /path/test.txt.
Contents:
1 │ Hello, world!
Insert new_str at specified line number
1 │ Let's add a new line
2 │ Hello, world!
Replace first occurrence of old_str with new_str in file
Replaced text in /Users/jhoward/aai-ws/fastcore/nbs/test.txt
1 │ Let's add a new line:
2 │ Hello, world!
Replace for each str pair in old_strs,new_strs
Results for each replacement:
Replaced text in /Users/jhoward/aai-ws/fastcore/nbs/test.txt; Replaced text in /Users/jhoward/aai-ws/fastcore/nbs/test.txt
1 │ Let's just say:
2 │ Hello, friends!
3 │ Nice to see you.
Results for each replacement:
Error: Text "a missing" not found in file; Error: Text "and shoul…" not found in file
1 │ Let's just say:
2 │ Hello, friends!
3 │ Nice to see you.
Replace lines in file using start and end line-numbers (index starting at 1)
1 │ Replaced first two lines
2 │ Nice to see you.
'Error: File not found: /path/missing.txt'
Move lines from start_line:end_line to before dest_line
The move_lines function relocates a range of lines within a file to a new position. It handles the tricky index adjustment when the destination is after the removed chunk.
Let’s test it by creating a simple 5-line file:
1 │ Line 1
2 │ Line 2
3 │ Line 3
4 │ Line 4
5 │ Line 5
Move lines 4-5 up to before line 2:
Moved lines 4-5 to line 2
1 │ Line 1
2 │ Line 4
3 │ Line 5
4 │ Line 2
5 │ Line 3
Move lines down — moving lines 1-2 to the end (line 6) correctly adjusts the destination index after removal:
Moved lines 1-2 to line 4
1 │ Line 5
2 │ Line 2
3 │ Line 3
4 │ Line 1
5 │ Line 4
Error handling — destination within source range, invalid line ranges, and invalid destinations are all caught:
Error: Destination within source range
Error: Invalid range 10-12
Error: Invalid destination 99
Error: File not found: /path/mising.txt
Return callable objects defined in caller’s module