File size: 6,356 Bytes
d4ea1a4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
import inspect
import json
import re

import requests
import openai


class FunctionManager:
    def __init__(self, functions=None):
        self.functions = {}
        self.excluded_functions = {'inspect', 'create_engine'}  # 添加这行
        if functions:
            for func in functions:
                self.functions[func.__name__] = func

    def add_function(self, func):
        self.functions[func.__name__] = func

    def generate_functions_array(self):
        type_mapping = {
            "str": "string",
            "int": "integer",
            "float": "number",
            "bool": "boolean",
            "list": "array",
            "dict": "object"
        }
        functions_array = []

        for function_name, function in self.functions.items():
            if function_name in self.excluded_functions:  # 添加这行
                continue
            # 获取函数的文档字符串和参数列表
            docstring = function.__doc__
            parameters = inspect.signature(function).parameters

            # 提取函数描述
            docstring_lines = docstring.strip().split(
                '\n') if docstring else []
            function_description = docstring_lines[0].strip(
            ) if docstring_lines else ''

            # 解析参数列表并生成函数描述
            function_info = {
                "name": function_name,
                "description": function_description,
                "parameters": {
                    "type": "object",
                    "properties": {},
                    "required": []  # Add a required field
                }
            }

            for parameter_name, parameter in parameters.items():
                # 获取参数的注释
                parameter_annotation = parameter.annotation
                if parameter_annotation == inspect.Parameter.empty:
                    continue

                # 如果注解是一个类型,获取它的名字
                # 如果注解是一个字符串,直接使用它
                if isinstance(parameter_annotation, type):
                    parameter_annotation_name = parameter_annotation.__name__.lower(
                    )
                else:
                    parameter_annotation_name = parameter_annotation.lower()

                # 提取参数描述
                param_description_pattern = rf"{parameter_name}: (.+)"
                param_description_match = [
                    re.search(param_description_pattern, line)
                    for line in docstring_lines
                ]
                param_description = next(
                    (match.group(1)
                     for match in param_description_match if match), '')

                # 添加参数描述
                parameter_description = {
                    "type":
                    type_mapping.get(parameter_annotation_name,
                                     parameter_annotation_name),
                    "description":
                    param_description
                }
                function_info["parameters"]["properties"][
                    parameter_name] = parameter_description

                # If the parameter has no default value, add it to the required field.
                if parameter.default == inspect.Parameter.empty:
                    function_info["parameters"]["required"].append(
                        parameter_name)

            functions_array.append(function_info)

        return functions_array

    async def call_function(self, function_name, args_dict):
        if function_name not in self.functions:
            raise ValueError(f"Function '{function_name}' not found")

        function = self.functions[function_name]
        # {"role": "function", "name": "get_current_weather", "content": "{\"temperature\": "22", \"unit\": \"celsius\", \"description\": \"Sunny\"}"}
        print(function, args_dict)
        res = await function(**args_dict)
        # 如果返回的内容是元祖或者列表或者字典,那么就返回一个json字符串
        if isinstance(res, (tuple, list, dict)):
            res = json.dumps(res)
        return res


# 测试
def get_current_weather(location: str, unit: str = "celsius"):
    """
    Get the current weather in a given location.

    Parameters:
        - location: The city and state, e.g. San Francisco, CA
        - unit: The unit of temperature (celsius or fahrenheit)
    """
    return {"temperature": "22", "unit": "celsius", "description": "Sunny"}


# 定义一个方法来根据传进来的url地址,读取网页的内容
def get_html(url: str):
    # 定义一个请求头,模拟浏览器访问
    """
    Get the html content of the url.if user provide the url,then return the html content of the url.
    Parameters:
        url: The url of the website. (required)
    """
    headers = {
        'User-Agent':
        'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) '
        'AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36'
    }
    # 发送请求
    response = requests.get(url, headers=headers)
    # 返回网页内容
    return response.text


def search_by_bard(content: str):
    """
    Search the content(translate to English language) by bard.if the input content that you don't know how to say, you can use this function.
    Parameters:
        content: The content to search.please change the content language to English.(required)
    """
    print(content)
    response = openai.ChatCompletion.create(model="bard",
                                            messages=[{
                                                'role': 'user',
                                                'content': content
                                            }],
                                            stream=False,
                                            temperature=0)
    print(response)
    return {'content': response['choices'][0]['message']['content']}


if __name__ == "__main__":
    function_manager = FunctionManager(functions=[search_by_bard])
    functions_array = function_manager.generate_functions_array()
    print(functions_array)

    # result = function_manager.call_function('get_current_weather', {'location': 'San Francisco, CA', 'unit': 'celsius'})
    # print(result)