lionagi 0.0.201__py3-none-any.whl → 0.0.204__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- lionagi/_services/anthropic.py +79 -1
- lionagi/_services/base_service.py +1 -1
- lionagi/_services/services.py +61 -25
- lionagi/_services/transformers.py +46 -0
- lionagi/agents/__init__.py +0 -0
- lionagi/configs/oai_configs.py +1 -1
- lionagi/configs/openrouter_configs.py +1 -1
- lionagi/core/__init__.py +3 -7
- lionagi/core/branch/__init__.py +0 -0
- lionagi/core/branch/branch.py +589 -0
- lionagi/core/branch/branch_manager.py +139 -0
- lionagi/core/branch/cluster.py +1 -0
- lionagi/core/branch/conversation.py +484 -0
- lionagi/core/core_util.py +59 -0
- lionagi/core/flow/__init__.py +0 -0
- lionagi/core/flow/flow.py +19 -0
- lionagi/core/instruction_set/__init__.py +0 -0
- lionagi/core/instruction_set/instruction_set.py +343 -0
- lionagi/core/messages/__init__.py +0 -0
- lionagi/core/messages/messages.py +176 -0
- lionagi/core/sessions/__init__.py +0 -0
- lionagi/core/sessions/session.py +428 -0
- lionagi/models/__init__.py +0 -0
- lionagi/models/base_model.py +0 -0
- lionagi/models/imodel.py +53 -0
- lionagi/schema/data_logger.py +75 -155
- lionagi/tests/test_utils/test_call_util.py +658 -657
- lionagi/tools/tool_manager.py +121 -188
- lionagi/utils/__init__.py +5 -10
- lionagi/utils/call_util.py +667 -585
- lionagi/utils/io_util.py +3 -0
- lionagi/utils/nested_util.py +17 -211
- lionagi/utils/pd_util.py +57 -0
- lionagi/utils/sys_util.py +220 -184
- lionagi/utils/url_util.py +55 -0
- lionagi/version.py +1 -1
- {lionagi-0.0.201.dist-info → lionagi-0.0.204.dist-info}/METADATA +12 -8
- {lionagi-0.0.201.dist-info → lionagi-0.0.204.dist-info}/RECORD +47 -32
- lionagi/core/branch.py +0 -193
- lionagi/core/conversation.py +0 -341
- lionagi/core/flow.py +0 -8
- lionagi/core/instruction_set.py +0 -150
- lionagi/core/messages.py +0 -243
- lionagi/core/sessions.py +0 -474
- /lionagi/{tools → agents}/planner.py +0 -0
- /lionagi/{tools → agents}/prompter.py +0 -0
- /lionagi/{tools → agents}/scorer.py +0 -0
- /lionagi/{tools → agents}/summarizer.py +0 -0
- /lionagi/{tools → agents}/validator.py +0 -0
- /lionagi/core/{flow_util.py → flow/flow_util.py} +0 -0
- {lionagi-0.0.201.dist-info → lionagi-0.0.204.dist-info}/LICENSE +0 -0
- {lionagi-0.0.201.dist-info → lionagi-0.0.204.dist-info}/WHEEL +0 -0
- {lionagi-0.0.201.dist-info → lionagi-0.0.204.dist-info}/top_level.txt +0 -0
lionagi/tools/tool_manager.py
CHANGED
@@ -1,39 +1,73 @@
|
|
1
1
|
import json
|
2
2
|
import asyncio
|
3
|
-
from typing import Dict
|
3
|
+
from typing import Dict, Union, List, Tuple, Any
|
4
4
|
from lionagi.utils import lcall
|
5
5
|
from lionagi.schema import BaseNode, Tool
|
6
6
|
|
7
7
|
|
8
8
|
class ToolManager(BaseNode):
|
9
|
+
"""
|
10
|
+
A manager class to handle registration and invocation of tools that are subclasses of Tool.
|
11
|
+
|
12
|
+
Attributes:
|
13
|
+
registry (Dict[str, Tool]): A dictionary to hold registered tools, using their names as keys.
|
14
|
+
"""
|
9
15
|
registry: Dict = {}
|
10
16
|
|
11
|
-
def name_existed(self, name: str):
|
17
|
+
def name_existed(self, name: str) -> bool:
|
18
|
+
"""
|
19
|
+
Check if a tool name already exists in the registry.
|
20
|
+
|
21
|
+
Parameters:
|
22
|
+
name (str): The name of the tool to check.
|
23
|
+
|
24
|
+
Returns:
|
25
|
+
bool: True if the name exists, False otherwise.
|
26
|
+
|
27
|
+
Examples:
|
28
|
+
>>> tool_manager.name_existed('existing_tool')
|
29
|
+
True
|
30
|
+
>>> tool_manager.name_existed('nonexistent_tool')
|
31
|
+
False
|
32
|
+
"""
|
12
33
|
return True if name in self.registry.keys() else False
|
13
34
|
|
14
|
-
def _register_tool(self, tool
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
# idx = str_to_num(name[-3:], int)
|
24
|
-
# if idx > 0:
|
25
|
-
# postfix = idx + 1
|
26
|
-
# except:
|
27
|
-
# pass
|
28
|
-
|
29
|
-
# name = f"{prefix or ''}{name}{postfix}" if new else tool.func.__name__
|
35
|
+
def _register_tool(self, tool: Tool) -> None:
|
36
|
+
"""
|
37
|
+
Register a new tool in the registry if it's an instance of Tool.
|
38
|
+
|
39
|
+
Parameters:
|
40
|
+
tool (Tool): The tool instance to register.
|
41
|
+
|
42
|
+
Raises:
|
43
|
+
TypeError: If the provided tool is not an instance of Tool.
|
30
44
|
|
45
|
+
Examples:
|
46
|
+
>>> tool_manager._register_tool(Tool())
|
47
|
+
# Tool is registered without any output
|
48
|
+
"""
|
31
49
|
if not isinstance(tool, Tool):
|
32
50
|
raise TypeError('Please register a Tool object.')
|
33
51
|
name = tool.schema_['function']['name']
|
34
52
|
self.registry.update({name: tool})
|
35
53
|
|
36
|
-
async def invoke(self, func_call):
|
54
|
+
async def invoke(self, func_call: Tuple[str, Dict[str, Any]]) -> Any:
|
55
|
+
"""
|
56
|
+
Invoke a registered tool's function with the provided arguments.
|
57
|
+
|
58
|
+
Args:
|
59
|
+
func_call (Tuple[str, Dict[str, Any]]): A tuple containing the tool's function name and kwargs.
|
60
|
+
|
61
|
+
Returns:
|
62
|
+
Any: The result of the tool's function invocation.
|
63
|
+
|
64
|
+
Raises:
|
65
|
+
ValueError: If the function is not registered or an error occurs during invocation.
|
66
|
+
|
67
|
+
Examples:
|
68
|
+
>>> await tool_manager.invoke(('registered_function', {'arg1': 'value1'}))
|
69
|
+
# Result of the registered_function with given arguments
|
70
|
+
"""
|
37
71
|
name, kwargs = func_call
|
38
72
|
if self.name_existed(name):
|
39
73
|
tool = self.registry[name]
|
@@ -50,15 +84,22 @@ class ToolManager(BaseNode):
|
|
50
84
|
raise ValueError(f"Function {name} is not registered.")
|
51
85
|
|
52
86
|
@staticmethod
|
53
|
-
def get_function_call(response):
|
87
|
+
def get_function_call(response: Dict) -> Tuple[str, Dict]:
|
54
88
|
"""
|
55
89
|
Extract function name and arguments from a response JSON.
|
56
90
|
|
57
91
|
Parameters:
|
58
|
-
response (
|
92
|
+
response (Dict): The JSON response containing function information.
|
59
93
|
|
60
94
|
Returns:
|
61
|
-
Tuple[str,
|
95
|
+
Tuple[str, Dict]: The function name and its arguments.
|
96
|
+
|
97
|
+
Raises:
|
98
|
+
ValueError: If the response is not a valid function call.
|
99
|
+
|
100
|
+
Examples:
|
101
|
+
>>> ToolManager.get_function_call({"action": "execute_add", "arguments": '{"x":1, "y":2}'})
|
102
|
+
('add', {'x': 1, 'y': 2})
|
62
103
|
"""
|
63
104
|
try:
|
64
105
|
func = response['action'][7:]
|
@@ -72,182 +113,74 @@ class ToolManager(BaseNode):
|
|
72
113
|
except:
|
73
114
|
raise ValueError('response is not a valid function call')
|
74
115
|
|
75
|
-
def register_tools(self, tools
|
116
|
+
def register_tools(self, tools: List[Tool]) -> None:
|
117
|
+
"""
|
118
|
+
Register multiple tools using a given list.
|
119
|
+
|
120
|
+
Parameters:
|
121
|
+
tools (List[Tool]): A list of Tool instances to register.
|
122
|
+
|
123
|
+
Examples:
|
124
|
+
>>> tool_manager.register_tools([Tool(), Tool()])
|
125
|
+
# Multiple Tool instances registered
|
126
|
+
"""
|
76
127
|
lcall(tools, self._register_tool) #, update=update, new=new, prefix=prefix, postfix=postfix)
|
77
128
|
|
78
|
-
def to_tool_schema_list(self):
|
129
|
+
def to_tool_schema_list(self) -> List[Dict[str, Any]]:
|
130
|
+
"""
|
131
|
+
Convert the registry of tools to a list of their schemas.
|
132
|
+
|
133
|
+
Returns:
|
134
|
+
List[Dict[str, Any]]: A list of tool schemas.
|
135
|
+
|
136
|
+
Examples:
|
137
|
+
>>> tool_manager.to_tool_schema_list()
|
138
|
+
# Returns a list of registered tool schemas
|
139
|
+
"""
|
79
140
|
schema_list = []
|
80
141
|
for tool in self.registry.values():
|
81
142
|
schema_list.append(tool.schema_)
|
82
143
|
return schema_list
|
83
144
|
|
145
|
+
def _tool_parser(self, tools: Union[Dict, Tool, List[Tool], str, List[str], List[Dict]], **kwargs) -> Dict:
|
146
|
+
"""
|
147
|
+
Parse tools and additional keyword arguments to form a dictionary used for tool configuration.
|
84
148
|
|
85
|
-
|
86
|
-
|
87
|
-
|
149
|
+
Parameters:
|
150
|
+
tools: A single tool object, a list of tool objects, a tool name, a list of tool names, or a dictionary.
|
151
|
+
**kwargs: Additional keyword arguments.
|
88
152
|
|
89
|
-
|
90
|
-
|
91
|
-
# from lionagi.utils.tool_util import func_to_tool
|
153
|
+
Returns:
|
154
|
+
Dict: A dictionary of tools and additional keyword arguments.
|
92
155
|
|
93
|
-
|
94
|
-
|
95
|
-
# ToolManager manages the registration and invocation of tools.
|
156
|
+
Raises:
|
157
|
+
ValueError: If a tool name string does not correspond to a registered tool.
|
96
158
|
|
97
|
-
|
98
|
-
|
159
|
+
Examples:
|
160
|
+
>>> tool_manager._tool_parser('registered_tool')
|
161
|
+
# Returns a dictionary containing the schema of the registered tool
|
162
|
+
"""
|
163
|
+
def tool_check(tool):
|
164
|
+
if isinstance(tool, dict):
|
165
|
+
return tool
|
166
|
+
elif isinstance(tool, Tool):
|
167
|
+
return tool.schema_
|
168
|
+
elif isinstance(tool, str):
|
169
|
+
if self.name_existed(tool):
|
170
|
+
tool = self.registry[tool]
|
171
|
+
return tool.schema_
|
172
|
+
else:
|
173
|
+
raise ValueError(f'Function {tool} is not registered.')
|
99
174
|
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
# register_tools: Registers multiple tools in the registry.
|
111
|
-
# """
|
112
|
-
|
113
|
-
# def __init__(self):
|
114
|
-
# """
|
115
|
-
# Initializes the ToolManager with an empty registry.
|
116
|
-
# """
|
117
|
-
# self.registry: Dict[str, Tool] = {}
|
118
|
-
|
119
|
-
# def _name_exists(self, name: str) -> bool:
|
120
|
-
# """
|
121
|
-
# Checks if a tool name already exists in the registry.
|
122
|
-
|
123
|
-
# Parameters:
|
124
|
-
# name (str): The name of the tool to check.
|
125
|
-
|
126
|
-
# Returns:
|
127
|
-
# bool: True if the name exists in the registry, False otherwise.
|
128
|
-
# """
|
129
|
-
# return name in self.registry
|
130
|
-
|
131
|
-
# def _register_tool(self, tool: Tool, name: Optional[str] = None, update: bool = False, new: bool = False, prefix: Optional[str] = None, postfix: Optional[int] = None):
|
132
|
-
# """
|
133
|
-
# Registers a tool in the registry.
|
134
|
-
|
135
|
-
# Parameters:
|
136
|
-
# tool (BaseTool): The tool to be registered.
|
137
|
-
|
138
|
-
# name (Optional[str]): The name to register the tool with. Defaults to the tool's function name.
|
139
|
-
|
140
|
-
# update (bool): If True, updates the existing tool. Defaults to False.
|
141
|
-
|
142
|
-
# new (bool): If True, creates a new registry entry. Defaults to False.
|
143
|
-
|
144
|
-
# prefix (Optional[str]): A prefix for the tool name.
|
145
|
-
|
146
|
-
# postfix (Optional[int]): A postfix for the tool name.
|
147
|
-
|
148
|
-
# Raises:
|
149
|
-
# ValueError: If both update and new are True for an existing function.
|
150
|
-
# """
|
151
|
-
# name = name or tool.func.__name__
|
152
|
-
# original_name = name
|
153
|
-
|
154
|
-
# if self._name_exists(name):
|
155
|
-
# if update and new:
|
156
|
-
# raise ValueError("Cannot both update and create new registry for existing function.")
|
157
|
-
# if new:
|
158
|
-
# idx = 1
|
159
|
-
# while self._name_exists(f"{prefix or ''}{name}{postfix or ''}{idx}"):
|
160
|
-
# idx += 1
|
161
|
-
# name = f"{prefix or ''}{name}{postfix or ''}{idx}"
|
162
|
-
# else:
|
163
|
-
# self.registry.pop(original_name, None)
|
164
|
-
|
165
|
-
# self.registry[name] = tool
|
166
|
-
|
167
|
-
# async def invoke(self, name_kwargs: Tuple) -> Any:
|
168
|
-
# """
|
169
|
-
# Dynamically invokes a registered tool with given arguments.
|
170
|
-
|
171
|
-
# Parameters:
|
172
|
-
# name (str): The name of the tool to invoke.
|
173
|
-
|
174
|
-
# kwargs (Dict[str, Any]): A dictionary of keyword arguments to pass to the tool.
|
175
|
-
|
176
|
-
# Returns:
|
177
|
-
# Any: The result of the tool invocation.
|
178
|
-
|
179
|
-
# Raises:
|
180
|
-
# ValueError: If the tool is not registered or if an error occurs during invocation.
|
181
|
-
# """
|
182
|
-
# name, kwargs = name_kwargs
|
183
|
-
# if not self._name_exists(name):
|
184
|
-
# raise ValueError(f"Function {name} is not registered.")
|
185
|
-
|
186
|
-
# tool = self.registry[name]
|
187
|
-
# func = tool.func
|
188
|
-
# parser = tool.parser
|
189
|
-
|
190
|
-
# try:
|
191
|
-
# result = await func(**kwargs) if asyncio.iscoroutinefunction(func) else func(**kwargs)
|
192
|
-
# return await parser(result) if parser and asyncio.iscoroutinefunction(parser) else parser(result) if parser else result
|
193
|
-
# except Exception as e:
|
194
|
-
# raise ValueError(f"Error invoking function {name}: {str(e)}")
|
195
|
-
|
196
|
-
# def register_tools(self, tools: List[Tool], update: bool = False, new: bool = False,
|
197
|
-
# prefix: Optional[str] = None, postfix: Optional[int] = None):
|
198
|
-
# """
|
199
|
-
# Registers multiple tools in the registry.
|
200
|
-
|
201
|
-
# Parameters:
|
202
|
-
# tools (List[BaseTool]): A list of tools to register.
|
203
|
-
|
204
|
-
# update (bool): If True, updates existing tools. Defaults to False.
|
205
|
-
|
206
|
-
# new (bool): If True, creates new registry entries. Defaults to False.
|
207
|
-
|
208
|
-
# prefix (Optional[str]): A prefix for the tool names.
|
209
|
-
|
210
|
-
# postfix (Optional[int]): A postfix for the tool names.
|
211
|
-
# """
|
212
|
-
# for tool in tools:
|
213
|
-
# self._register_tool(tool, update=update, new=new, prefix=prefix, postfix=postfix)
|
214
|
-
|
215
|
-
# def _register_func(self, func_, parser=None, **kwargs):
|
216
|
-
# # kwargs for _register_tool
|
217
|
-
|
218
|
-
# tool = func_to_tool(func_=func_, parser=parser)
|
219
|
-
# self._register_tool(tool=tool, **kwargs)
|
220
|
-
|
221
|
-
# def register_funcs(self, funcs, parsers=None, **kwargs):
|
222
|
-
# funcs, parsers = to_list(funcs), to_list(parsers)
|
223
|
-
# if parsers is not None and len(parsers) != len(funcs):
|
224
|
-
# raise ValueError("The number of funcs and tools should be the same")
|
225
|
-
# parsers = parsers or [None for _ in range(len(funcs))]
|
226
|
-
|
227
|
-
# for i, func in enumerate(funcs):
|
228
|
-
# self._register_func(func_=func, parser=parsers[i], **kwargs)
|
175
|
+
if isinstance(tools, bool):
|
176
|
+
tool_kwarg = {"tools": self.to_tool_schema_list()}
|
177
|
+
kwargs = {**tool_kwarg, **kwargs}
|
178
|
+
|
179
|
+
else:
|
180
|
+
if not isinstance(tools, list):
|
181
|
+
tools = [tools]
|
182
|
+
tool_kwarg = {"tools": lcall(tools, tool_check)}
|
183
|
+
kwargs = {**tool_kwarg, **kwargs}
|
229
184
|
|
230
|
-
|
231
|
-
|
232
|
-
# """
|
233
|
-
# Extract function name and arguments from a response JSON.
|
234
|
-
|
235
|
-
# Parameters:
|
236
|
-
# response (dict): The JSON response containing function information.
|
237
|
-
|
238
|
-
# Returns:
|
239
|
-
# Tuple[str, dict]: The function name and its arguments.
|
240
|
-
# """
|
241
|
-
# try:
|
242
|
-
# # out = json.loads(response)
|
243
|
-
# func = response['function'][5:]
|
244
|
-
# args = json.loads(response['arguments'])
|
245
|
-
# return (func, args)
|
246
|
-
# except:
|
247
|
-
# try:
|
248
|
-
# func = response['recipient_name'].split('.')[-1]
|
249
|
-
# args = response['parameters']
|
250
|
-
# return (func, args)
|
251
|
-
# except:
|
252
|
-
# raise ValueError('response is not a valid function call')
|
253
|
-
|
185
|
+
return kwargs
|
186
|
+
|
lionagi/utils/__init__.py
CHANGED
@@ -1,31 +1,26 @@
|
|
1
1
|
from .sys_util import (
|
2
2
|
get_timestamp, create_copy, create_path, split_path,
|
3
3
|
get_bins, change_dict_key, str_to_num, create_id,
|
4
|
-
|
5
|
-
as_dict
|
6
|
-
)
|
4
|
+
as_dict)
|
7
5
|
|
8
6
|
from .nested_util import (
|
9
|
-
|
7
|
+
to_readable_dict, nfilter, nset, nget,
|
10
8
|
nmerge, ninsert, flatten, unflatten,
|
11
|
-
is_structure_homogeneous, get_flattened_keys
|
12
|
-
|
13
|
-
)
|
9
|
+
is_structure_homogeneous, get_flattened_keys)
|
14
10
|
|
15
11
|
from .api_util import APIUtil
|
16
12
|
from .encrypt_util import EncrytionUtil
|
17
13
|
from .io_util import IOUtil
|
18
14
|
|
19
15
|
from .call_util import (
|
16
|
+
to_list,
|
20
17
|
lcall, alcall, mcall, tcall, bcall,
|
21
|
-
rcall, CallDecorator
|
22
|
-
)
|
18
|
+
rcall, CallDecorator)
|
23
19
|
|
24
20
|
|
25
21
|
__all__ = [
|
26
22
|
'get_timestamp', 'create_copy', 'create_path', 'split_path',
|
27
23
|
'get_bins', 'change_dict_key', 'str_to_num', 'create_id',
|
28
|
-
'str_to_datetime', 'find_depth', 'is_schema', 'strip_lower',
|
29
24
|
'as_dict', 'to_list', 'to_readable_dict', 'nfilter', 'nset',
|
30
25
|
'nget', 'nmerge', 'ninsert', 'flatten', 'unflatten',
|
31
26
|
'is_structure_homogeneous', 'get_flattened_keys', 'APIUtil',
|