| import inspect |
| from typing import get_type_hints, List, Dict, Any |
|
|
|
|
| def doc_to_dict(docstring): |
| lines = docstring.split("\n") |
| description = lines[1].strip() |
| param_dict = {} |
|
|
| for line in lines: |
| if ":param" in line: |
| line = line.replace(":param", "").strip() |
| param, desc = line.split(":", 1) |
| param_dict[param.strip()] = desc.strip() |
| ret_dict = {"description": description, "params": param_dict} |
| return ret_dict |
|
|
|
|
| def get_tools_specs(tools) -> List[dict]: |
| function_list = [ |
| {"name": func, "function": getattr(tools, func)} |
| for func in dir(tools) |
| if callable(getattr(tools, func)) |
| and not func.startswith("__") |
| and not inspect.isclass(getattr(tools, func)) |
| ] |
|
|
| specs = [] |
| for function_item in function_list: |
| function_name = function_item["name"] |
| function = function_item["function"] |
|
|
| function_doc = doc_to_dict(function.__doc__ or function_name) |
| specs.append( |
| { |
| "name": function_name, |
| |
| "description": function_doc.get("description", function_name), |
| "parameters": { |
| "type": "object", |
| "properties": { |
| param_name: { |
| "type": param_annotation.__name__.lower(), |
| **( |
| { |
| "enum": ( |
| str(param_annotation.__args__) |
| if hasattr(param_annotation, "__args__") |
| else None |
| ) |
| } |
| if hasattr(param_annotation, "__args__") |
| else {} |
| ), |
| "description": function_doc.get("params", {}).get( |
| param_name, param_name |
| ), |
| } |
| for param_name, param_annotation in get_type_hints( |
| function |
| ).items() |
| if param_name != "return" |
| and not ( |
| param_name.startswith("__") and param_name.endswith("__") |
| ) |
| }, |
| "required": [ |
| name |
| for name, param in inspect.signature( |
| function |
| ).parameters.items() |
| if param.default is param.empty |
| and not (name.startswith("__") and name.endswith("__")) |
| ], |
| }, |
| } |
| ) |
|
|
| return specs |
|
|