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
lionagi/utils/io_util.py CHANGED
@@ -6,6 +6,9 @@ from collections.abc import Iterable
6
6
  from typing import Any, Dict, List
7
7
 
8
8
  class IOUtil:
9
+ """
10
+ Utility class for reading and writing data from/to files in various formats.
11
+ """
9
12
 
10
13
  @staticmethod
11
14
  def read_csv(filepath: str) -> List[Dict[str, Any]]:
@@ -1,42 +1,9 @@
1
1
  import json
2
2
  from collections import defaultdict
3
3
  from copy import deepcopy
4
- from itertools import chain
5
- from typing import Any, Callable, Dict, Generator, List, Tuple, Union, Iterable, Optional
6
-
7
- def to_list(input_: Any, flatten: bool = True, dropna: bool = False) -> List[Any]:
8
- """
9
- Converts the input to a list, optionally flattening it and dropping None values.
10
-
11
- Args:
12
- input_ (Any): The input to convert to a list.
13
- flatten (bool): Whether to flatten the input if it is a nested list. Defaults to True.
14
- dropna (bool): Whether to drop None values from the list. Defaults to False.
15
-
16
- Returns:
17
- List[Any]: The input converted to a list.
18
-
19
- Raises:
20
- ValueError: If the input cannot be converted to a list.
21
4
 
22
- Examples:
23
- >>> to_list([1, [2, [3, 4]], 5])
24
- [1, 2, 3, 4, 5]
25
- >>> to_list([1, None, 3], dropna=True)
26
- [1, 3]
27
- """
28
- if isinstance(input_, list) and flatten:
29
- input_ = _flatten_list(input_)
30
- elif isinstance(input_, Iterable) and not isinstance(input_, (str, dict)):
31
- try:
32
- input_ = list(input_)
33
- except:
34
- raise ValueError("Input cannot be converted to a list.")
35
- else:
36
- input_ = [input_]
37
- if dropna:
38
- input_ = [i for i in input_ if i is not None]
39
- return input_
5
+ from typing import Any, Callable, Dict, Generator, List, Tuple, Union, Iterable, Optional
6
+ from itertools import chain
40
7
 
41
8
  def to_readable_dict(input: Union[Dict, List]) -> Union[str, List]:
42
9
  """
@@ -433,24 +400,11 @@ def get_flattened_keys(obj: Any, sep: str = '_', max_depth: Union[int, None] = N
433
400
  else:
434
401
  return list(flatten(obj, sep=sep, max_depth=max_depth, dict_only=dict_only).keys())
435
402
 
436
- def _flatten_list(l: List, dropna: bool = True) -> List:
437
- """
438
- Flattens a nested list into a single-level list.
439
-
440
- Args:
441
- l (List): The nested list to flatten.
442
- dropna (bool, optional): If True, removes None values from the flattened list. Defaults to True.
443
-
444
- Returns:
445
- List: The flattened list, with or without None values based on the dropna parameter.
446
- """
447
- flattened_list = list(_flatten_list_generator(l, dropna))
448
- return _dropna(flattened_list) if dropna else flattened_list
449
-
450
-
451
- def _dynamic_flatten_in_place(obj: Any, parent_key: str = '', sep: str = '_',
452
- max_depth: Union[int, None] = None,
453
- current_depth: int = 0, dict_only: bool = False) -> None:
403
+ def _dynamic_flatten_in_place(
404
+ obj: Any, parent_key: str = '', sep: str = '_',
405
+ max_depth: Union[int, None] = None, current_depth: int = 0,
406
+ dict_only: bool = False
407
+ ) -> None:
454
408
  """
455
409
  Helper function to flatten the object in place.
456
410
 
@@ -502,23 +456,10 @@ def _handle_list_insert(sub_obj: List, part: int, value: Any):
502
456
  while len(sub_obj) <= part:
503
457
  sub_obj.append(None)
504
458
  sub_obj[part] = value
505
-
506
- def _convert_to_int_if_possible(s: str) -> Union[int, str]:
507
- """
508
- Converts a string to an integer if possible; otherwise, returns the string.
509
459
 
510
- Args:
511
- s (str): The string to convert.
512
-
513
- Returns:
514
- Union[int, str]: The converted integer or the original string.
515
- """
516
- return int(s) if s.lstrip('-').isdigit() else s
517
-
518
- def _is_iterable(obj) -> bool:
519
- return isinstance(obj, Iterable) and not isinstance(obj, str)
520
-
521
- def _ensure_list_index(lst: List, index: int, default=None) -> None:
460
+ def _ensure_list_index(
461
+ lst: List, index: int, default=None
462
+ ) -> None:
522
463
  """Ensures that a list is at least as long as a specified index.
523
464
 
524
465
  This method appends the default value to the list until its length is at least
@@ -614,52 +555,10 @@ def _deep_merge_dicts(dict1: Dict, dict2: Dict) -> Dict:
614
555
  else:
615
556
  dict1[key] = dict2[key]
616
557
  return dict1
617
-
618
- def _extend_list_to_index(lst: List[Any], index: int, fill_value: Any = None) -> None:
619
- """
620
- Extends a list to a specified index with a fill value.
621
-
622
- Args:
623
- lst (List[Any]): The list to extend.
624
- index (int): The index to extend the list to.
625
- fill_value (Any, optional): The value to fill the extended part of the list with. Defaults to None.
626
-
627
- Returns:
628
- None: This function modifies the input list in place and returns None.
629
- """
630
- while len(lst) <= index:
631
- lst.append(fill_value)
632
-
633
- def _dropna(l: List) -> List:
634
- """
635
- Removes None values from a list.
636
-
637
- Args:
638
- l (List): The list to remove None values from.
639
-
640
- Returns:
641
- List: A new list with None values removed.
642
- """
643
- return [item for item in l if item is not None]
644
-
645
- def _flatten_list_generator(l: List, dropna: bool = True) -> Generator[Any, None, None]:
646
- """
647
- Generator to flatten a nested list.
648
-
649
- Args:
650
- l (List): The nested list to flatten.
651
- dropna (bool, optional): If True, removes None values during the flattening process. Defaults to True.
652
-
653
- Yields:
654
- Generator[Any, None, None]: Yields elements of the flattened list.
655
- """
656
- for i in l:
657
- if isinstance(i, list):
658
- yield from _flatten_list_generator(i, dropna)
659
- else:
660
- yield i
661
-
662
- def _is_homogeneous(iterables: List[Union[Dict, List, Iterable]], type_check: type) -> bool:
558
+
559
+ def _is_homogeneous(
560
+ iterables: List[Union[Dict, List, Iterable]], type_check: type
561
+ ) -> bool:
663
562
  """Checks if all elements in a list are of the same specified type.
664
563
 
665
564
  Args:
@@ -753,7 +652,9 @@ def _filter_list(lst: List[Any], condition: Callable[[Any], bool]) -> List[Any]:
753
652
  """
754
653
  return [item for item in lst if condition(item)]
755
654
 
756
- def _get_target_container(nested_list: Union[List, Dict], indices: List[Union[int, str]]) -> Union[List, Dict]:
655
+ def _get_target_container(
656
+ nested_list: Union[List, Dict], indices: List[Union[int, str]]
657
+ ) -> Union[List, Dict]:
757
658
  current_element = nested_list
758
659
  for index in indices:
759
660
  if isinstance(current_element, list):
@@ -769,98 +670,3 @@ def _get_target_container(nested_list: Union[List, Dict], indices: List[Union[in
769
670
  else:
770
671
  raise TypeError("Current element is neither a list nor a dictionary")
771
672
  return current_element
772
-
773
-
774
- # def nprint(nested_structure: Union[Dict, Iterable], indent: int = 0) -> None:
775
- # if isinstance(nested_structure, dict):
776
- # nprint(_print_dict(nested_structure, indent))
777
- # elif _is_iterable(nested_structure):
778
- # nprint(" " * indent + "[")
779
- # nprint(_print_iterable(nested_structure, indent + 2))
780
- # nprint(" " * indent + "]")
781
- # else:
782
- # nprint(f"{' ' * indent}{repr(nested_structure)}")
783
-
784
- # def _print_dict(nested_dict: Dict, indent: int) -> str:
785
- # lines = [" " * indent + "{"]
786
- # items = list(nested_dict.items())
787
- # for index, (key, value) in enumerate(items):
788
- # line_end = "," if index < len(items) - 1 else ""
789
- # if isinstance(value, dict):
790
- # lines.append(f"{' ' * (indent + 2)}{repr(key)}: {{")
791
- # lines.append(_print_dict(value, indent + 4))
792
- # lines.append(f"{' ' * (indent + 2)}}}{line_end}")
793
- # elif _is_iterable(value):
794
- # lines.append(f"{' ' * (indent + 2)}{repr(key)}: [")
795
- # lines.append(_print_iterable(value, indent + 4))
796
- # lines.append(f"{' ' * (indent + 2)}]{line_end}")
797
- # else:
798
- # lines.append(f"{' ' * (indent + 2)}{repr(key)}: {repr(value)}{line_end}")
799
- # lines.append(" " * indent + "}")
800
- # return "\n".join(lines)
801
-
802
- # @staticmethod
803
- # def _print_iterable(iterable: Iterable, indent: int) -> str:
804
- # lines = []
805
- # iterable_list = list(iterable)
806
- # for index, item in enumerate(iterable_list):
807
- # line_end = "," if index < len(iterable_list) - 1 else ""
808
- # if isinstance(item, dict):
809
- # lines.append(_print_dict(item, indent + 2) + line_end)
810
- # elif _is_iterable(item):
811
- # lines.append(" " * indent + "[")
812
- # lines.append(_print_iterable(item, indent + 2))
813
- # lines.append(f"{' ' * indent}]{line_end}")
814
- # else:
815
- # lines.append(f"{' ' * indent}{repr(item)}{line_end}")
816
- # return "\n".join(lines)
817
-
818
- # def _tuples_to_dict(tuples_list: List[Tuple[str, Any]]) -> Dict:
819
- # """Converts a list of tuples into a dictionary.
820
-
821
- # Each tuple in the list should be a key-value pair, where the key is a string
822
- # that represents the nested keys separated by underscores.
823
-
824
- # Args:
825
- # tuples_list: A list of tuples where each tuple is a (key, value) pair.
826
-
827
- # Returns:
828
- # A dictionary created from the tuples.
829
- # """
830
- # result_dict = {}
831
- # for key, value in tuples_list:
832
- # ninsert(result_dict, key.split('_'), value)
833
- # return result_dict
834
-
835
-
836
- # @staticmethod
837
- # def _insert_with_dict_handling(result_list: Union[Dict, List],
838
- # indices: List[Union[int, str]],
839
- # value: Any,
840
- # current_depth: int = 0):
841
- # """
842
- # Helper function to insert a value into a list or dictionary at a nested location
843
- # defined by indices.
844
-
845
- # Args:
846
- # result_list (Union[Dict, List]): The list or dictionary to insert into.
847
- # indices (List[Union[int, str]]): The indices defining where to insert the value.
848
- # value (Any): The value to insert.
849
- # current_depth (int, optional): The current depth in the nested structure. Defaults to 0.
850
-
851
- # Returns:
852
- # None: This function modifies the input list or dictionary in place and returns None.
853
- # """
854
- # for index in indices[:-1]:
855
- # if isinstance(result_list, list):
856
- # _extend_list_to_index(result_list, index, [])
857
- # result_list = result_list[index]
858
- # elif isinstance(result_list, dict):
859
- # result_list = result_list.setdefault(index, {})
860
- # current_depth += 1
861
- # last_index = indices[-1]
862
- # if isinstance(result_list, list):
863
- # _extend_list_to_index(result_list, last_index)
864
- # result_list[last_index] = value
865
- # else:
866
- # result_list[last_index] = value
@@ -0,0 +1,57 @@
1
+ from typing import List, Dict
2
+ import pandas as pd
3
+ from ..schema.data_node import DataNode
4
+ from .sys_util import timestamp_to_datetime
5
+
6
+ def to_pd_df(items: List[Dict], how: str = 'all') -> pd.DataFrame:
7
+ """
8
+ Converts a list of dictionaries to a pandas DataFrame, dropping NA values.
9
+
10
+ Args:
11
+ items (List[Dict]): A list of dictionaries to be converted to a DataFrame.
12
+ how (str): How to handle NA values. Options are 'all' to drop rows with all NA values,
13
+ 'any' to drop rows with any NA values, or 'none' to keep all rows.
14
+
15
+ Returns:
16
+ pd.DataFrame: A pandas DataFrame containing the data from the input list of dictionaries.
17
+ """
18
+ df = pd.DataFrame(items).dropna(how=how)
19
+ df.reset_index(drop=True, inplace=True)
20
+ return df
21
+
22
+ def pd_row_to_node(row: pd.Series):
23
+ """
24
+ Converts a pandas Series row to a DataNode object with structured data.
25
+
26
+ Args:
27
+ row (pd.Series): A pandas Series containing row data to be converted.
28
+
29
+ Returns:
30
+ DataNode: A DataNode object containing structured data from the input pandas Series.
31
+ """
32
+ dict_ = row.to_dict()
33
+ dict_['datetime'] = str(timestamp_to_datetime(dict_['datetime']))
34
+ dict_['content'] = {'headline': dict_.pop('headline'), 'summary': dict_.pop('summary')}
35
+ dict_['metadata'] = {'datetime': dict_.pop('datetime'), 'url': dict_.pop('url'), 'id': dict_.pop('id')}
36
+ return DataNode.from_dict(dict_)
37
+
38
+ def expand_df_datetime(df: pd.DataFrame) -> pd.DataFrame:
39
+ """
40
+ Expands a pandas DataFrame with a datetime column into separate year, month, and day columns.
41
+
42
+ Args:
43
+ df (pd.DataFrame): The pandas DataFrame containing a 'datetime' column to be expanded.
44
+
45
+ Returns:
46
+ pd.DataFrame: A pandas DataFrame with 'year', 'month', and 'day' columns.
47
+ """
48
+ df_expanded = df.copy()
49
+ if df_expanded['datetime'].dtype == int:
50
+ df_expanded['datetime'] = df_expanded['datetime'].apply(lambda x: timestamp_to_datetime(x))
51
+
52
+ df_expanded.insert(0, 'year', df_expanded['datetime'].dt.year)
53
+ df_expanded.insert(1, 'month', df_expanded['datetime'].dt.month)
54
+ df_expanded.insert(2, 'day', df_expanded['datetime'].dt.day)
55
+ df_expanded.drop('datetime', axis=1, inplace=True)
56
+
57
+ return df_expanded