lionagi 0.0.306__py3-none-any.whl → 0.0.308__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 (78) hide show
  1. lionagi/__init__.py +2 -5
  2. lionagi/core/__init__.py +7 -5
  3. lionagi/core/agent/__init__.py +3 -0
  4. lionagi/core/agent/base_agent.py +10 -12
  5. lionagi/core/branch/__init__.py +4 -0
  6. lionagi/core/branch/base_branch.py +81 -81
  7. lionagi/core/branch/branch.py +16 -28
  8. lionagi/core/branch/branch_flow_mixin.py +3 -7
  9. lionagi/core/branch/executable_branch.py +86 -56
  10. lionagi/core/branch/util.py +77 -162
  11. lionagi/core/{flow/direct → direct}/__init__.py +1 -1
  12. lionagi/core/{flow/direct/predict.py → direct/parallel_predict.py} +39 -17
  13. lionagi/core/direct/parallel_react.py +0 -0
  14. lionagi/core/direct/parallel_score.py +0 -0
  15. lionagi/core/direct/parallel_select.py +0 -0
  16. lionagi/core/direct/parallel_sentiment.py +0 -0
  17. lionagi/core/direct/predict.py +174 -0
  18. lionagi/core/{flow/direct → direct}/react.py +2 -2
  19. lionagi/core/{flow/direct → direct}/score.py +28 -23
  20. lionagi/core/{flow/direct → direct}/select.py +48 -45
  21. lionagi/core/direct/utils.py +83 -0
  22. lionagi/core/flow/monoflow/ReAct.py +6 -5
  23. lionagi/core/flow/monoflow/__init__.py +9 -0
  24. lionagi/core/flow/monoflow/chat.py +10 -10
  25. lionagi/core/flow/monoflow/chat_mixin.py +11 -10
  26. lionagi/core/flow/monoflow/followup.py +6 -5
  27. lionagi/core/flow/polyflow/__init__.py +1 -0
  28. lionagi/core/flow/polyflow/chat.py +15 -3
  29. lionagi/core/mail/mail_manager.py +18 -19
  30. lionagi/core/mail/schema.py +5 -4
  31. lionagi/core/messages/schema.py +18 -20
  32. lionagi/core/prompt/__init__.py +0 -0
  33. lionagi/core/prompt/prompt_template.py +0 -0
  34. lionagi/core/schema/__init__.py +2 -2
  35. lionagi/core/schema/action_node.py +11 -3
  36. lionagi/core/schema/base_mixin.py +56 -59
  37. lionagi/core/schema/base_node.py +34 -37
  38. lionagi/core/schema/condition.py +24 -0
  39. lionagi/core/schema/data_logger.py +96 -99
  40. lionagi/core/schema/data_node.py +19 -19
  41. lionagi/core/schema/prompt_template.py +0 -0
  42. lionagi/core/schema/structure.py +171 -169
  43. lionagi/core/session/__init__.py +1 -3
  44. lionagi/core/session/session.py +196 -214
  45. lionagi/core/tool/tool_manager.py +95 -103
  46. lionagi/integrations/__init__.py +1 -3
  47. lionagi/integrations/bridge/langchain_/documents.py +17 -18
  48. lionagi/integrations/bridge/langchain_/langchain_bridge.py +14 -14
  49. lionagi/integrations/bridge/llamaindex_/llama_index_bridge.py +22 -22
  50. lionagi/integrations/bridge/llamaindex_/node_parser.py +12 -12
  51. lionagi/integrations/bridge/llamaindex_/reader.py +11 -11
  52. lionagi/integrations/bridge/llamaindex_/textnode.py +7 -7
  53. lionagi/integrations/config/openrouter_configs.py +0 -1
  54. lionagi/integrations/provider/oai.py +26 -26
  55. lionagi/integrations/provider/services.py +38 -38
  56. lionagi/libs/__init__.py +34 -1
  57. lionagi/libs/ln_api.py +211 -221
  58. lionagi/libs/ln_async.py +53 -60
  59. lionagi/libs/ln_convert.py +118 -120
  60. lionagi/libs/ln_dataframe.py +32 -33
  61. lionagi/libs/ln_func_call.py +334 -342
  62. lionagi/libs/ln_nested.py +99 -107
  63. lionagi/libs/ln_parse.py +161 -165
  64. lionagi/libs/sys_util.py +52 -52
  65. lionagi/tests/test_core/test_session.py +254 -266
  66. lionagi/tests/test_core/test_session_base_util.py +299 -300
  67. lionagi/tests/test_core/test_tool_manager.py +70 -74
  68. lionagi/tests/test_libs/test_nested.py +2 -7
  69. lionagi/tests/test_libs/test_parse.py +2 -2
  70. lionagi/version.py +1 -1
  71. {lionagi-0.0.306.dist-info → lionagi-0.0.308.dist-info}/METADATA +4 -2
  72. lionagi-0.0.308.dist-info/RECORD +115 -0
  73. lionagi/core/flow/direct/utils.py +0 -43
  74. lionagi-0.0.306.dist-info/RECORD +0 -106
  75. /lionagi/core/{flow/direct → direct}/sentiment.py +0 -0
  76. {lionagi-0.0.306.dist-info → lionagi-0.0.308.dist-info}/LICENSE +0 -0
  77. {lionagi-0.0.306.dist-info → lionagi-0.0.308.dist-info}/WHEEL +0 -0
  78. {lionagi-0.0.306.dist-info → lionagi-0.0.308.dist-info}/top_level.txt +0 -0
lionagi/libs/sys_util.py CHANGED
@@ -12,7 +12,6 @@ from hashlib import sha256
12
12
  from pathlib import Path
13
13
  from typing import Any
14
14
 
15
-
16
15
  _timestamp_syms = ["-", ":", "."]
17
16
 
18
17
  PATH_TYPE = str | Path
@@ -26,36 +25,39 @@ class SysUtil:
26
25
  Pauses execution for a specified duration.
27
26
 
28
27
  Args:
29
- delay (float): The amount of time, in seconds, to pause execution.
28
+ delay (float): The amount of time, in seconds, to pause execution.
30
29
  """
31
30
  time.sleep(delay)
32
31
 
33
32
  @staticmethod
34
- def get_now(datetime_: bool = False) -> float | datetime:
33
+ def get_now(datetime_: bool = False, tz=None) -> float | datetime:
35
34
  """Returns the current time either as a Unix timestamp or a datetime object.
36
35
 
37
36
  Args:
38
- datetime_ (bool): If True, returns a datetime object; otherwise, returns a Unix timestamp.
37
+ datetime_ (bool): If True, returns a datetime object; otherwise, returns a Unix timestamp.
39
38
 
40
39
  Returns:
41
- Union[float, datetime.datetime]: The current time as a Unix timestamp or a datetime object.
40
+ Union[float, datetime.datetime]: The current time as a Unix timestamp or a datetime object.
42
41
  """
42
+
43
43
  if not datetime_:
44
44
  return time.time()
45
- else:
46
- return datetime.now()
45
+ config_ = {}
46
+ if tz:
47
+ config_["tz"] = tz if isinstance(tz, timezone) else timezone.utc
48
+ return datetime.now(**config_)
47
49
 
48
50
  @staticmethod
49
51
  def change_dict_key(dict_: dict[Any, Any], old_key: str, new_key: str) -> None:
50
52
  """Safely changes a key in a dictionary if the old key exists.
51
53
 
52
54
  Args:
53
- dict_ (Dict[Any, Any]): The dictionary in which to change the key.
54
- old_key (str): The old key to be changed.
55
- new_key (str): The new key to replace the old key.
55
+ dict_ (Dict[Any, Any]): The dictionary in which to change the key.
56
+ old_key (str): The old key to be changed.
57
+ new_key (str): The new key to replace the old key.
56
58
 
57
59
  Returns:
58
- None
60
+ None
59
61
  """
60
62
  if old_key in dict_:
61
63
  dict_[new_key] = dict_.pop(old_key)
@@ -65,11 +67,11 @@ class SysUtil:
65
67
  """Returns a timestamp string with optional custom separators and timezone.
66
68
 
67
69
  Args:
68
- tz (timezone): The timezone for the timestamp.
69
- sep (str): The separator to use in the timestamp string, replacing '-', ':', and '.'.
70
+ tz (timezone): The timezone for the timestamp.
71
+ sep (str): The separator to use in the timestamp string, replacing '-', ':', and '.'.
70
72
 
71
73
  Returns:
72
- str: A string representation of the current timestamp.
74
+ str: A string representation of the current timestamp.
73
75
  """
74
76
  str_ = datetime.now(tz=tz).isoformat()
75
77
  if sep is not None:
@@ -90,11 +92,11 @@ class SysUtil:
90
92
  """Creates deep copies of the input, either as a single copy or a list of copies.
91
93
 
92
94
  Args:
93
- input_ (Any): The input to be copied.
94
- num (int): The number of copies to create.
95
+ input_ (Any): The input to be copied.
96
+ num (int): The number of copies to create.
95
97
 
96
98
  Returns:
97
- Union[Any, List[Any]]: A single copy of the input or a list of deep copies.
99
+ Union[Any, List[Any]]: A single copy of the input or a list of deep copies.
98
100
  """
99
101
  if num < 1:
100
102
  raise ValueError(f"'num' must be a positive integer: {num}")
@@ -110,10 +112,10 @@ class SysUtil:
110
112
  Generates a unique identifier based on the current time and random bytes.
111
113
 
112
114
  Args:
113
- n (int): The length of the generated identifier.
115
+ n (int): The length of the generated identifier.
114
116
 
115
117
  Returns:
116
- str: A unique identifier string.
118
+ str: A unique identifier string.
117
119
  """
118
120
  current_time = datetime.now().isoformat().encode("utf-8")
119
121
  random_bytes = os.urandom(42)
@@ -124,11 +126,11 @@ class SysUtil:
124
126
  """Organizes indices of strings into bins based on a cumulative upper limit.
125
127
 
126
128
  Args:
127
- input_ (List[str]): The list of strings to be binned.
128
- upper (int): The cumulative length upper limit for each bin.
129
+ input_ (List[str]): The list of strings to be binned.
130
+ upper (int): The cumulative length upper limit for each bin.
129
131
 
130
132
  Returns:
131
- List[List[int]]: A list of bins, each bin is a list of indices from the input list.
133
+ List[List[int]]: A list of bins, each bin is a list of indices from the input list.
132
134
  """
133
135
  current = 0
134
136
  bins = []
@@ -152,12 +154,10 @@ class SysUtil:
152
154
  This method categorizes some architectures as 'apple_silicon'.
153
155
 
154
156
  Returns:
155
- str: A string identifying the CPU architecture ('apple_silicon' or 'other_cpu').
157
+ str: A string identifying the CPU architecture ('apple_silicon' or 'other_cpu').
156
158
  """
157
159
  arch: str = platform.machine().lower()
158
- if "arm" in arch or "aarch64" in arch:
159
- return "apple_silicon"
160
- return "other_cpu"
160
+ return "apple_silicon" if "arm" in arch or "aarch64" in arch else "other_cpu"
161
161
 
162
162
  @staticmethod
163
163
  def install_import(
@@ -172,10 +172,10 @@ class SysUtil:
172
172
  to install the package using pip and then retries the import.
173
173
 
174
174
  Args:
175
- package_name: The base name of the package to import.
176
- module_name: The submodule name to import from the package, if applicable. Defaults to None.
177
- import_name: The specific name to import from the module or package. Defaults to None.
178
- pip_name: The pip package name if different from `package_name`. Defaults to None.
175
+ package_name: The base name of the package to import.
176
+ module_name: The submodule name to import from the package, if applicable. Defaults to None.
177
+ import_name: The specific name to import from the module or package. Defaults to None.
178
+ pip_name: The pip package name if different from `package_name`. Defaults to None.
179
179
 
180
180
  Prints a message indicating success or attempts installation if the import fails.
181
181
  """
@@ -213,10 +213,10 @@ class SysUtil:
213
213
  """Checks if a package is currently installed.
214
214
 
215
215
  Args:
216
- package_name: The name of the package to check.
216
+ package_name: The name of the package to check.
217
217
 
218
218
  Returns:
219
- A boolean indicating whether the package is installed.
219
+ A boolean indicating whether the package is installed.
220
220
  """
221
221
  package_spec = importlib.util.find_spec(package_name)
222
222
  return package_spec is not None
@@ -236,12 +236,12 @@ class SysUtil:
236
236
  it attempts to install the package using `install_import` and then retries the import.
237
237
 
238
238
  Args:
239
- package_name: The name of the package to check and potentially install.
240
- module_name: The submodule name to import from the package, if applicable. Defaults to None.
241
- import_name: The specific name to import from the module or package. Defaults to None.
242
- pip_name: The pip package name if different from `package_name`. Defaults to None.
243
- attempt_install: If attempt to install the package if uninstalled. Defaults to True.
244
- error_message: Error message when the package is not installed and not attempt to install.
239
+ package_name: The name of the package to check and potentially install.
240
+ module_name: The submodule name to import from the package, if applicable. Defaults to None.
241
+ import_name: The specific name to import from the module or package. Defaults to None.
242
+ pip_name: The pip package name if different from `package_name`. Defaults to None.
243
+ attempt_install: If attempt to install the package if uninstalled. Defaults to True.
244
+ error_message: Error message when the package is not installed and not attempt to install.
245
245
  """
246
246
  try:
247
247
  if not SysUtil.is_package_installed(package_name):
@@ -298,12 +298,12 @@ class SysUtil:
298
298
  excluding files that match any pattern in the exclude list.
299
299
 
300
300
  Args:
301
- dir_path (Union[Path, str]): The path to the directory to clear.
302
- recursive (bool): If True, clears directories recursively. Defaults to False.
303
- exclude (List[str]): A list of string patterns to exclude from deletion. Defaults to None.
301
+ dir_path (Union[Path, str]): The path to the directory to clear.
302
+ recursive (bool): If True, clears directories recursively. Defaults to False.
303
+ exclude (List[str]): A list of string patterns to exclude from deletion. Defaults to None.
304
304
 
305
305
  Raises:
306
- FileNotFoundError: If the specified directory does not exist.
306
+ FileNotFoundError: If the specified directory does not exist.
307
307
  """
308
308
  dir_path = Path(dir_path)
309
309
  if not dir_path.exists():
@@ -335,10 +335,10 @@ class SysUtil:
335
335
  Splits a path into its directory and filename components.
336
336
 
337
337
  Args:
338
- path (Union[Path, str]): The path to split.
338
+ path (Union[Path, str]): The path to split.
339
339
 
340
340
  Returns:
341
- Tuple[Path, str]: A tuple containing the directory and filename.
341
+ Tuple[Path, str]: A tuple containing the directory and filename.
342
342
  """
343
343
  path = Path(path)
344
344
  return path.parent, path.name
@@ -356,18 +356,18 @@ class SysUtil:
356
356
  Creates a path with an optional timestamp in the specified directory.
357
357
 
358
358
  Args:
359
- directory (Union[Path, str]): The directory where the file will be located.
360
- filename (str): The filename. Must include a valid extension.
361
- timestamp (bool): If True, adds a timestamp to the filename. Defaults to True.
362
- dir_exist_ok (bool): If True, does not raise an error if the directory exists. Defaults to True.
363
- time_prefix (bool): If True, adds the timestamp as a prefix; otherwise, as a suffix. Defaults to False.
364
- custom_timestamp_format (str): A custom format for the timestamp. Defaults to "%Y%m%d%H%M%S".
359
+ directory (Union[Path, str]): The directory where the file will be located.
360
+ filename (str): The filename. Must include a valid extension.
361
+ timestamp (bool): If True, adds a timestamp to the filename. Defaults to True.
362
+ dir_exist_ok (bool): If True, does not raise an error if the directory exists. Defaults to True.
363
+ time_prefix (bool): If True, adds the timestamp as a prefix; otherwise, as a suffix. Defaults to False.
364
+ custom_timestamp_format (str): A custom format for the timestamp. Defaults to "%Y%m%d%H%M%S".
365
365
 
366
366
  Returns:
367
- Path: The full path to the file.
367
+ Path: The full path to the file.
368
368
 
369
369
  Raises:
370
- ValueError: If the filename is invalid.
370
+ ValueError: If the filename is invalid.
371
371
  """
372
372
  directory = Path(directory)
373
373
  if not re.match(r"^[\w,\s-]+\.[A-Za-z]{1,5}$", filename):