70 lines
2.2 KiB
Python
70 lines
2.2 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
extract_tools.py
|
|
|
|
Usage:
|
|
python extract_tools.py path/to/your_module.py > tools.json
|
|
|
|
Parses the given Python file for calls to:
|
|
tool_declarations.append(
|
|
generative_models.FunctionDeclaration(...)
|
|
)
|
|
and outputs a JSON list of the kwargs passed to each FunctionDeclaration.
|
|
"""
|
|
|
|
import ast
|
|
import json
|
|
import sys
|
|
|
|
def extract_function_declarations(source: str):
|
|
tree = ast.parse(source)
|
|
tools = []
|
|
|
|
for node in ast.walk(tree):
|
|
# look for expressions like: tool_declarations.append( generative_models.FunctionDeclaration(...) )
|
|
if (
|
|
isinstance(node, ast.Expr)
|
|
and isinstance(node.value, ast.Call)
|
|
and isinstance(node.value.func, ast.Attribute)
|
|
and node.value.func.attr == "append"
|
|
# ensure it's tool_declarations.append
|
|
and isinstance(node.value.func.value, ast.Name)
|
|
and node.value.func.value.id == "tool_declarations"
|
|
and node.value.args
|
|
and isinstance(node.value.args[0], ast.Call)
|
|
):
|
|
decl_call = node.value.args[0]
|
|
# ensure it's generative_models.FunctionDeclaration(...)
|
|
if (
|
|
isinstance(decl_call.func, ast.Attribute)
|
|
and decl_call.func.attr == "FunctionDeclaration"
|
|
):
|
|
tool_obj = {}
|
|
for kw in decl_call.keywords:
|
|
# use ast.literal_eval to turn the AST node into a Python object
|
|
try:
|
|
value = ast.literal_eval(kw.value)
|
|
except ValueError:
|
|
# if something non-literal sneaks in, fallback to the raw source
|
|
value = ast.get_source_segment(source, kw.value)
|
|
tool_obj[kw.arg] = value
|
|
tools.append(tool_obj)
|
|
|
|
return tools
|
|
|
|
def main():
|
|
if len(sys.argv) != 2:
|
|
print("Usage: python extract_tools.py path/to/your_module.py", file=sys.stderr)
|
|
sys.exit(1)
|
|
|
|
path = sys.argv[1]
|
|
with open(path, "r", encoding="utf-8") as f:
|
|
source = f.read()
|
|
|
|
tools = extract_function_declarations(source)
|
|
json.dump(tools, sys.stdout, indent=2)
|
|
sys.stdout.write("\n")
|
|
|
|
if __name__ == "__main__":
|
|
main()
|