-
Notifications
You must be signed in to change notification settings - Fork 709
Expand file tree
/
Copy pathgeneric_tools.py
More file actions
133 lines (108 loc) · 5.26 KB
/
Copy pathgeneric_tools.py
File metadata and controls
133 lines (108 loc) · 5.26 KB
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
import inspect
from typing import Callable
from semantic_kernel.functions import kernel_function
from models.messages_kernel import AgentType
import json
from typing import get_type_hints
class GenericTools:
"""Define Generic Agent functions (tools)"""
agent_name = AgentType.GENERIC.value
@staticmethod
@kernel_function(
description="This is a placeholder function, for a proper Azure AI Search RAG process."
)
async def dummy_function() -> str:
# This is a placeholder function, for a proper Azure AI Search RAG process.
"""This is a placeholder"""
return "This is a placeholder function"
@classmethod
def get_all_kernel_functions(cls) -> dict[str, Callable]:
"""
Returns a dictionary of all methods in this class that have the @kernel_function annotation.
This function itself is not annotated with @kernel_function.
Returns:
Dict[str, Callable]: Dictionary with function names as keys and function objects as values
"""
kernel_functions = {}
# Get all class methods
for name, method in inspect.getmembers(cls, predicate=inspect.isfunction):
# Skip this method itself and any private/special methods
if name.startswith("_") or name == "get_all_kernel_functions":
continue
# Check if the method has the kernel_function annotation
# by looking at its __annotations__ attribute
method_attrs = getattr(method, "__annotations__", {})
if hasattr(method, "__kernel_function__") or "kernel_function" in str(
method_attrs
):
kernel_functions[name] = method
return kernel_functions
@classmethod
def generate_tools_json_doc(cls) -> str:
"""
Generate a JSON document containing information about all methods in the class.
Returns:
str: JSON string containing the methods' information
"""
tools_list = []
# Get all methods from the class that have the kernel_function annotation
for name, method in inspect.getmembers(cls, predicate=inspect.isfunction):
# Skip this method itself and any private methods
if name.startswith("_") or name == "generate_tools_json_doc":
continue
# Check if the method has the kernel_function annotation
if hasattr(method, "__kernel_function__"):
# Get method description from docstring or kernel_function description
description = ""
if hasattr(method, "__doc__") and method.__doc__:
description = method.__doc__.strip()
# Get kernel_function description if available
if hasattr(method, "__kernel_function__") and getattr(
method.__kernel_function__, "description", None
):
description = method.__kernel_function__.description
# Get argument information by introspection
sig = inspect.signature(method)
args_dict = {}
# Get type hints if available
type_hints = get_type_hints(method)
# Process parameters
for param_name, param in sig.parameters.items():
# Skip first parameter 'cls' for class methods (though we're using staticmethod now)
if param_name in ["cls", "self"]:
continue
# Get parameter type
param_type = "string" # Default type
if param_name in type_hints:
type_obj = type_hints[param_name]
# Convert type to string representation
if hasattr(type_obj, "__name__"):
param_type = type_obj.__name__.lower()
else:
# Handle complex types like List, Dict, etc.
param_type = str(type_obj).lower()
if "int" in param_type:
param_type = "int"
elif "float" in param_type:
param_type = "float"
elif "bool" in param_type:
param_type = "boolean"
else:
param_type = "string"
# Create parameter description
# param_desc = param_name.replace("_", " ")
args_dict[param_name] = {
"description": param_name,
"title": param_name.replace("_", " ").title(),
"type": param_type,
}
# Add the tool information to the list
tool_entry = {
"agent": cls.agent_name, # Use HR agent type
"function": name,
"description": description,
"arguments": json.dumps(args_dict).replace('"', "'"),
}
tools_list.append(tool_entry)
# Return the JSON string representation
return json.dumps(tools_list, ensure_ascii=False, indent=2)