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.
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',