Skip to content
This repository has been archived by the owner on Mar 1, 2024. It is now read-only.

Commit

Permalink
Adding PythonFileToolSpec
Browse files Browse the repository at this point in the history
  • Loading branch information
ajhofmann committed Aug 10, 2023
1 parent d133b42 commit 0b862f2
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 0 deletions.
4 changes: 4 additions & 0 deletions llama_hub/tools/library.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@
"id": "tools/weather",
"author": "logan-markewich"
},
"PythonFileToolSpec": {
"id": "tools/python_file",
"author": "ajhofmann"
},
"RequestsToolSpec": {
"id": "tools/requests",
"author": "ajhofmann"
Expand Down
30 changes: 30 additions & 0 deletions llama_hub/tools/python_file/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Python File Tool

This tool loads a python file and extracts function names, arguments and descriptions automatically. This tool is particular useful for automatically creating custom Tool Specs when you already have well documented python functions.

## Usage

This tool has more extensive example usage documented in a Jupyter notebook [here](https://github.com/emptycrown/llama-hub/tree/main/llama_hub/tools/notebooks/create_a_tool.ipynb)

Here's an example usage of the PythonFileToolSpec.

```python
from llama_hub.tools.openapi.base import PythonFileToolSpec
from llama_index.agent import OpenAIAgent

pyfile = PythonFileToolSpec('./numpy_linalg.py')

agent = OpenAIAgent.from_tools(tool_spec.to_tool_list())

agent.chat("""Load the eig, transpose and solve functions from the python file,
and then write a function defintion using only builtin python types (List, float, Tuple)
with a short 5-10 line doc string tool prompts for the functions that only has a small description and arguments
""")
```

`function_definitions`: Get all of the function definitions from the Python file
`get_function`: Get a specfic function definiton from the Python file
`get_functions`: Get a list of functions from the python file

This loader is designed to be used as a way to load data as a Tool in a Agent. See [here](https://github.com/emptycrown/llama-hub/tree/main) for examples.

1 change: 1 addition & 0 deletions llama_hub/tools/python_file/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# init file
58 changes: 58 additions & 0 deletions llama_hub/tools/python_file/base.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@

from typing import Optional, List
from llama_index.tools.tool_spec.base import BaseToolSpec
import ast

class PythonFileToolSpec(BaseToolSpec):
spec_functions = ['function_definitions', 'get_function', 'get_functions']

def __init__(self, file_name: str) -> None:
f = open(file_name).read()
self.tree = ast.parse(f)

def function_definitions(self, external: Optional[bool] = True) -> str:
"""
Use this function to get the name and arguments of all function defintions in the python file
Args:
external (Optional[bool]): Defaults to true. If false, this function will also return functions that start with _
"""
functions = ""
for node in ast.walk(self.tree):
if isinstance(node, ast.FunctionDef):
if external and node.name.startswith('_'):
continue
functions += f"""
name: {node.name}
arguments: {ast.dump(node.args)}
"""
return functions

def get_function(self, name: str) -> str:
"""
Use this function to get the name and arguments of a single function definition in the python file.
Args:
name (str): The name of the function to retrieve
"""
for node in ast.walk(self.tree):
if isinstance(node, ast.FunctionDef):
if node.name == name:
return f"""
name: {node.name}
arguments: {ast.dump(node.args)}
docstring: {ast.get_docstring(node)}
"""

def get_functions(self, names: List[str]) -> str:
"""
Use this function to get the name and arguments of a list of function definition in the python file.
Args:
name (List[str]): The names of the functions to retrieve
"""
functions = ""
for name in names:
functions += self.get_function(name) + '\n'
return functions

0 comments on commit 0b862f2

Please sign in to comment.