lionagi 0.0.201__py3-none-any.whl → 0.0.204__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. lionagi/_services/anthropic.py +79 -1
  2. lionagi/_services/base_service.py +1 -1
  3. lionagi/_services/services.py +61 -25
  4. lionagi/_services/transformers.py +46 -0
  5. lionagi/agents/__init__.py +0 -0
  6. lionagi/configs/oai_configs.py +1 -1
  7. lionagi/configs/openrouter_configs.py +1 -1
  8. lionagi/core/__init__.py +3 -7
  9. lionagi/core/branch/__init__.py +0 -0
  10. lionagi/core/branch/branch.py +589 -0
  11. lionagi/core/branch/branch_manager.py +139 -0
  12. lionagi/core/branch/cluster.py +1 -0
  13. lionagi/core/branch/conversation.py +484 -0
  14. lionagi/core/core_util.py +59 -0
  15. lionagi/core/flow/__init__.py +0 -0
  16. lionagi/core/flow/flow.py +19 -0
  17. lionagi/core/instruction_set/__init__.py +0 -0
  18. lionagi/core/instruction_set/instruction_set.py +343 -0
  19. lionagi/core/messages/__init__.py +0 -0
  20. lionagi/core/messages/messages.py +176 -0
  21. lionagi/core/sessions/__init__.py +0 -0
  22. lionagi/core/sessions/session.py +428 -0
  23. lionagi/models/__init__.py +0 -0
  24. lionagi/models/base_model.py +0 -0
  25. lionagi/models/imodel.py +53 -0
  26. lionagi/schema/data_logger.py +75 -155
  27. lionagi/tests/test_utils/test_call_util.py +658 -657
  28. lionagi/tools/tool_manager.py +121 -188
  29. lionagi/utils/__init__.py +5 -10
  30. lionagi/utils/call_util.py +667 -585
  31. lionagi/utils/io_util.py +3 -0
  32. lionagi/utils/nested_util.py +17 -211
  33. lionagi/utils/pd_util.py +57 -0
  34. lionagi/utils/sys_util.py +220 -184
  35. lionagi/utils/url_util.py +55 -0
  36. lionagi/version.py +1 -1
  37. {lionagi-0.0.201.dist-info → lionagi-0.0.204.dist-info}/METADATA +12 -8
  38. {lionagi-0.0.201.dist-info → lionagi-0.0.204.dist-info}/RECORD +47 -32
  39. lionagi/core/branch.py +0 -193
  40. lionagi/core/conversation.py +0 -341
  41. lionagi/core/flow.py +0 -8
  42. lionagi/core/instruction_set.py +0 -150
  43. lionagi/core/messages.py +0 -243
  44. lionagi/core/sessions.py +0 -474
  45. /lionagi/{tools → agents}/planner.py +0 -0
  46. /lionagi/{tools → agents}/prompter.py +0 -0
  47. /lionagi/{tools → agents}/scorer.py +0 -0
  48. /lionagi/{tools → agents}/summarizer.py +0 -0
  49. /lionagi/{tools → agents}/validator.py +0 -0
  50. /lionagi/core/{flow_util.py → flow/flow_util.py} +0 -0
  51. {lionagi-0.0.201.dist-info → lionagi-0.0.204.dist-info}/LICENSE +0 -0
  52. {lionagi-0.0.201.dist-info → lionagi-0.0.204.dist-info}/WHEEL +0 -0
  53. {lionagi-0.0.201.dist-info → lionagi-0.0.204.dist-info}/top_level.txt +0 -0
@@ -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): #,update=False, new=False, prefix=None, postfix=None):
15
-
16
- # if self._name_existed(tool.name):
17
- # if update and new:
18
- # raise ValueError(f"Cannot both update and create new registry for existing function {tool.name} at the same time")
19
-
20
- # if len(name) > len(tool.func.__name__):
21
- # if new and not postfix:
22
- # try:
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 (dict): The JSON response containing function information.
92
+ response (Dict): The JSON response containing function information.
59
93
 
60
94
  Returns:
61
- Tuple[str, dict]: The function name and its arguments.
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): #, update=False, new=False, prefix=None, postfix=None ):
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
- # import asyncio
86
- # import json
87
- # from typing import Dict, Any, Optional, List, Tuple
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
- # from lionagi.schema.base_tool import Tool
90
- # from lionagi.utils.type_util import to_list
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
- # class ToolRegistry:
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
- # This class provides functionalities to register tools, check for their existence,
98
- # and invoke them dynamically with specified arguments.
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
- # Attributes:
101
- # registry (Dict[str, BaseTool]): A dictionary to store registered tools by name.
102
-
103
- # Methods:
104
- # _name_exists: Checks if a tool name already exists in the registry.
105
-
106
- # _register_tool: Registers a tool in the registry.
107
-
108
- # invoke: Dynamically invokes a registered tool with given arguments.
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
- # @staticmethod
231
- # def get_function_call(response):
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
- str_to_datetime, find_depth, is_schema, strip_lower,
5
- as_dict
6
- )
4
+ as_dict)
7
5
 
8
6
  from .nested_util import (
9
- to_list, to_readable_dict, nfilter, nset, nget,
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',