lionagi 0.0.306__py3-none-any.whl → 0.0.307__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
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 +35 -38
  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.307.dist-info}/METADATA +4 -2
  72. lionagi-0.0.307.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.307.dist-info}/LICENSE +0 -0
  77. {lionagi-0.0.306.dist-info → lionagi-0.0.307.dist-info}/WHEEL +0 -0
  78. {lionagi-0.0.306.dist-info → lionagi-0.0.307.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):