File size: 2,369 Bytes
a9effa1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
from functools import wraps
import json
import inspect
import re

def generate_tools_json(functions):
    """
    Generates a JSON representation of the tools based on the provided functions.
    """
    tools = []
    for func in functions:
        tools.append(func.tool_info)

    with open('tools.json', 'w') as file:
        json.dump(tools, file, indent=4)

    return {
        "tools": tools
    }

def tool(func):
    """
    Decorator to get function information for tool generation.
    Args:
        func: The function to be decorated.
    """
    @wraps(func)
    def wrapper(*args, **kwargs):
        return func(*args, **kwargs)

    description = func.__doc__.strip() if func.__doc__ else "No description available."

    sig = inspect.signature(func)
    parameters = {}
    required = []

    for param_name, param in sig.parameters.items():
        param_type = param.annotation
        if param_type == param.empty:
            param_type = "string"
        else:
            param_type = param_type.__name__
            if param_type == 'str':
                param_type = 'string'
            elif param_type == 'int':
                param_type = 'integer'
            elif param_type == 'list':
                param_type = 'array'
            elif param_type == 'float':
                param_type = 'number'
            elif param_type == 'bool':
                param_type = 'boolean'
            elif param_type == 'dict':
                param_type = 'object'

        param_description = f"The {param_name}."

        docstring_lines = description.split('\n')
        for line in docstring_lines:
            match = re.match(rf"\s*{param_name}\s*\(.*\):\s*(.*)", line)
            if match:
                param_description = match.group(1).strip()
                break

        parameters[param_name] = {
            "type": param_type,
            "description": param_description,
        }

        if param.default == param.empty:
            required.append(param_name)

    wrapper.tool_info = {
        "type": "function",
        "function": {
            "name": func.__name__,
            "description": description.split('\n')[0],
            "parameters": {
                "type": "object",
                "properties": parameters,
                "required": required,
            },
        },
    }
    return wrapper