lionagi 0.7.0__py3-none-any.whl → 0.7.2__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. lionagi/operations/ReAct/ReAct.py +2 -2
  2. lionagi/operations/_act/act.py +10 -3
  3. lionagi/operations/communicate/communicate.py +0 -59
  4. lionagi/operations/interpret/interpret.py +1 -2
  5. lionagi/operations/operate/operate.py +10 -5
  6. lionagi/operations/parse/parse.py +0 -36
  7. lionagi/operations/plan/plan.py +3 -3
  8. lionagi/operatives/action/manager.py +105 -82
  9. lionagi/operatives/action/request_response_model.py +31 -0
  10. lionagi/operatives/action/tool.py +50 -20
  11. lionagi/protocols/_concepts.py +1 -1
  12. lionagi/protocols/adapters/adapter.py +25 -0
  13. lionagi/protocols/adapters/json_adapter.py +107 -27
  14. lionagi/protocols/adapters/pandas_/csv_adapter.py +55 -11
  15. lionagi/protocols/adapters/pandas_/excel_adapter.py +52 -10
  16. lionagi/protocols/adapters/pandas_/pd_dataframe_adapter.py +54 -4
  17. lionagi/protocols/adapters/pandas_/pd_series_adapter.py +40 -0
  18. lionagi/protocols/generic/element.py +1 -1
  19. lionagi/protocols/generic/pile.py +5 -8
  20. lionagi/protocols/graph/edge.py +1 -1
  21. lionagi/protocols/graph/graph.py +16 -8
  22. lionagi/protocols/graph/node.py +1 -1
  23. lionagi/protocols/mail/exchange.py +126 -15
  24. lionagi/protocols/mail/mail.py +33 -0
  25. lionagi/protocols/mail/mailbox.py +62 -0
  26. lionagi/protocols/mail/manager.py +97 -41
  27. lionagi/protocols/mail/package.py +57 -3
  28. lionagi/protocols/messages/action_request.py +77 -26
  29. lionagi/protocols/messages/action_response.py +55 -26
  30. lionagi/protocols/messages/assistant_response.py +50 -15
  31. lionagi/protocols/messages/base.py +36 -0
  32. lionagi/protocols/messages/instruction.py +175 -145
  33. lionagi/protocols/messages/manager.py +152 -56
  34. lionagi/protocols/messages/message.py +61 -25
  35. lionagi/protocols/messages/system.py +54 -19
  36. lionagi/service/imodel.py +24 -0
  37. lionagi/session/branch.py +40 -32
  38. lionagi/utils.py +1 -0
  39. lionagi/version.py +1 -1
  40. {lionagi-0.7.0.dist-info → lionagi-0.7.2.dist-info}/METADATA +1 -1
  41. {lionagi-0.7.0.dist-info → lionagi-0.7.2.dist-info}/RECORD +43 -43
  42. {lionagi-0.7.0.dist-info → lionagi-0.7.2.dist-info}/WHEEL +0 -0
  43. {lionagi-0.7.0.dist-info → lionagi-0.7.2.dist-info}/licenses/LICENSE +0 -0
@@ -2,6 +2,12 @@
2
2
  #
3
3
  # SPDX-License-Identifier: Apache-2.0
4
4
 
5
+ """
6
+ Defines the `Tool` class, which wraps a Python callable (function/method)
7
+ with optional pre/post-processing and schema auto-generation. Also includes
8
+ type aliases for function references.
9
+ """
10
+
5
11
  import inspect
6
12
  from collections.abc import Callable
7
13
  from typing import Any, Self, TypeAlias
@@ -22,10 +28,13 @@ __all__ = (
22
28
 
23
29
 
24
30
  class Tool(Element):
25
- """A class for handling function calls with schema validation and processing.
31
+ """
32
+ Wraps a callable function with optional:
33
+ - Preprocessing of arguments,
34
+ - Postprocessing of results,
35
+ - Strict or partial argument matching.
26
36
 
27
- This class wraps callable objects with optional pre and post processing,
28
- schema validation, and provides utility methods for function inspection.
37
+ `tool_schema` is auto-generated from the function signature if not provided.
29
38
  """
30
39
 
31
40
  func_callable: Callable[..., Any] = Field(
@@ -82,28 +91,19 @@ class Tool(Element):
82
91
 
83
92
  @property
84
93
  def function(self) -> str:
85
- """Get the name of the function from the schema.
86
-
87
- Returns:
88
- str: The name of the function as defined in the schema.
89
- """
94
+ """Return the function name from the auto-generated schema."""
90
95
  return self.tool_schema["function"]["name"]
91
96
 
92
97
  @property
93
98
  def required_fields(self) -> set[str]:
94
- """Get the required fields from the schema.
95
-
96
- Returns:
97
- set[str]: Set of required field names.
98
- """
99
+ """Return the set of required parameter names from the schema."""
99
100
  return set(self.tool_schema["function"]["parameters"]["required"])
100
101
 
101
102
  @property
102
103
  def minimum_acceptable_fields(self) -> set[str]:
103
- """Get the minimum required fields from function signature.
104
-
105
- Returns:
106
- set[str]: Set of minimum required field names.
104
+ """
105
+ Return the set of parameters that have no default values,
106
+ ignoring `*args` or `**kwargs`.
107
107
  """
108
108
  try:
109
109
  a = {
@@ -123,13 +123,15 @@ class Tool(Element):
123
123
 
124
124
  @classmethod
125
125
  def from_dict(cls, data: dict[str, Any]):
126
- raise NotImplementedError("Tool.from_dict is not implemented.")
126
+ """This is not implemented, as Tools are not typically created from arbitrary dicts."""
127
+ raise NotImplementedError("`Tool.from_dict` is not supported.")
127
128
 
128
129
  def to_dict(self) -> dict[str, Any]:
129
- """Convert Tool instance to dictionary.
130
+ """
131
+ Serialize the Tool to a dict, including the `function` name.
130
132
 
131
133
  Returns:
132
- dict[str, Any]: Dictionary representation of the Tool.
134
+ dict[str, Any]: The dictionary form (excluding callables).
133
135
  """
134
136
  dict_ = super().to_dict()
135
137
  dict_["function"] = self.function
@@ -137,5 +139,33 @@ class Tool(Element):
137
139
 
138
140
 
139
141
  FuncTool: TypeAlias = Tool | Callable[..., Any]
142
+ """Represents either a `Tool` instance or a raw callable function."""
143
+
140
144
  FuncToolRef: TypeAlias = FuncTool | str
145
+ """
146
+ A reference to a function-based tool, by either the actual object,
147
+ the raw callable, or the function name as a string.
148
+ """
149
+
141
150
  ToolRef: TypeAlias = FuncToolRef | list[FuncToolRef] | bool
151
+ """
152
+ Used for specifying one or more tool references, or a boolean
153
+ indicating 'all' or 'none'.
154
+ """
155
+
156
+
157
+ def func_to_tool(func: Callable[..., Any], **kwargs) -> Tool:
158
+ """
159
+ Convenience function that wraps a raw function in a `Tool`.
160
+
161
+ Args:
162
+ func (Callable[..., Any]): The function to wrap.
163
+ **kwargs: Additional arguments passed to the `Tool` constructor.
164
+
165
+ Returns:
166
+ Tool: A new Tool instance wrapping `func`.
167
+ """
168
+ return Tool(func_callable=func, **kwargs)
169
+
170
+
171
+ # File: lionagi/operatives/action/tool.py
@@ -91,4 +91,4 @@ class Ordering(ABC, Generic[E]):
91
91
  pass
92
92
 
93
93
 
94
- # File: protocols/generic/concepts.py
94
+ # File: lionagi/protocols/_concepts.py
@@ -2,6 +2,12 @@
2
2
  #
3
3
  # SPDX-License-Identifier: Apache-2.0
4
4
 
5
+ """
6
+ Defines the `Adapter` protocol (a formal interface), along with the
7
+ `AdapterRegistry` that maps string/file extensions or object keys to
8
+ specific adapter implementations.
9
+ """
10
+
5
11
  import logging
6
12
  from typing import Any, Protocol, TypeVar, runtime_checkable
7
13
 
@@ -18,6 +24,25 @@ __all__ = (
18
24
 
19
25
  @runtime_checkable
20
26
  class Adapter(Protocol):
27
+ """
28
+ Describes a two-way converter that knows how to transform an object
29
+ from an external representation to an internal format, and vice versa.
30
+
31
+ Attributes
32
+ ----------
33
+ obj_key : str
34
+ A unique key or extension that identifies what format this
35
+ adapter supports (e.g. ".csv", "json", "pd_dataframe").
36
+
37
+ Methods
38
+ -------
39
+ from_obj(subj_cls: type[T], obj: Any, /, many: bool, **kwargs) -> dict|list[dict]
40
+ Converts a raw external object (file contents, JSON string, etc.)
41
+ into a dictionary or list of dictionaries.
42
+ to_obj(subj: T, /, many: bool, **kwargs) -> Any
43
+ Converts an internal object (e.g., a Pydantic-based model)
44
+ into the target format (file, JSON, DataFrame, etc.).
45
+ """
21
46
 
22
47
  obj_key: str
23
48
 
@@ -1,3 +1,9 @@
1
+ """
2
+ Implements two adapters:
3
+ - `JsonAdapter` for in-memory JSON strings
4
+ - `JsonFileAdapter` for reading/writing JSON files
5
+ """
6
+
1
7
  import json
2
8
  import logging
3
9
  from pathlib import Path
@@ -8,6 +14,11 @@ from .adapter import Adapter, T
8
14
 
9
15
 
10
16
  class JsonAdapter(Adapter):
17
+ """
18
+ Adapter that converts to/from JSON **strings** in memory.
19
+ Example usage: taking a Python dictionary and making JSON,
20
+ or parsing JSON string to a dict.
21
+ """
11
22
 
12
23
  obj_key = "json"
13
24
 
@@ -22,16 +33,31 @@ class JsonAdapter(Adapter):
22
33
  **kwargs,
23
34
  ) -> dict | list[dict]:
24
35
  """
25
- kwargs for json.loads(s, **kwargs)
36
+ Convert a JSON string into a dict or list of dicts.
37
+
38
+ Parameters
39
+ ----------
40
+ subj_cls : type[T]
41
+ The target class for context (not always used).
42
+ obj : str
43
+ The JSON string.
44
+ many : bool, optional
45
+ If True, expects a JSON array (returns list[dict]).
46
+ Otherwise returns a single dict or the first element.
47
+ **kwargs
48
+ Extra arguments for json.loads().
49
+
50
+ Returns
51
+ -------
52
+ dict | list[dict]
53
+ The loaded JSON data.
26
54
  """
27
55
  result = json.loads(obj, **kwargs)
28
56
  if many:
29
57
  return result if isinstance(result, list) else [result]
30
- return (
31
- result[0]
32
- if isinstance(result, list) and len(result) > 0
33
- else result
34
- )
58
+ if isinstance(result, list) and len(result) > 0:
59
+ return result[0]
60
+ return result
35
61
 
36
62
  @classmethod
37
63
  def to_obj(
@@ -40,18 +66,38 @@ class JsonAdapter(Adapter):
40
66
  *,
41
67
  many: bool = False,
42
68
  **kwargs,
43
- ):
69
+ ) -> str:
44
70
  """
45
- kwargs for json.dumps(obj, **kwargs)
71
+ Convert an object (or collection) to a JSON string.
72
+
73
+ Parameters
74
+ ----------
75
+ subj : T
76
+ The object to serialize.
77
+ many : bool, optional
78
+ If True, convert multiple items to a JSON array.
79
+ **kwargs
80
+ Extra arguments for json.dumps().
81
+
82
+ Returns
83
+ -------
84
+ str
85
+ The resulting JSON string.
46
86
  """
47
87
  if many:
48
88
  if isinstance(subj, Collective):
49
- return json.dumps([i.to_dict() for i in subj], **kwargs)
50
- return json.dumps([subj.to_dict()], **kwargs)
89
+ data = [i.to_dict() for i in subj]
90
+ else:
91
+ data = [subj.to_dict()]
92
+ return json.dumps(data, **kwargs)
51
93
  return json.dumps(subj.to_dict(), **kwargs)
52
94
 
53
95
 
54
96
  class JsonFileAdapter(Adapter):
97
+ """
98
+ Adapter that reads/writes JSON data to/from a file on disk.
99
+ The file extension key is ".json".
100
+ """
55
101
 
56
102
  obj_key = ".json"
57
103
 
@@ -66,17 +112,31 @@ class JsonFileAdapter(Adapter):
66
112
  **kwargs,
67
113
  ) -> dict | list[dict]:
68
114
  """
69
- kwargs for json.load(fp, **kwargs)
115
+ Read a JSON file from disk and return a dict or list of dicts.
116
+
117
+ Parameters
118
+ ----------
119
+ subj_cls : type[T]
120
+ The target class for context.
121
+ obj : str | Path
122
+ The JSON file path.
123
+ many : bool
124
+ If True, expects a list. Otherwise single dict or first element.
125
+ **kwargs
126
+ Extra arguments for json.load().
127
+
128
+ Returns
129
+ -------
130
+ dict | list[dict]
131
+ The loaded data from file.
70
132
  """
71
- with open(obj) as f:
133
+ with open(obj, encoding="utf-8") as f:
72
134
  result = json.load(f, **kwargs)
73
135
  if many:
74
136
  return result if isinstance(result, list) else [result]
75
- return (
76
- result[0]
77
- if isinstance(result, list) and len(result) > 0
78
- else result
79
- )
137
+ if isinstance(result, list) and len(result) > 0:
138
+ return result[0]
139
+ return result
80
140
 
81
141
  @classmethod
82
142
  def to_obj(
@@ -86,16 +146,36 @@ class JsonFileAdapter(Adapter):
86
146
  *,
87
147
  fp: str | Path,
88
148
  many: bool = False,
149
+ mode: str = "w",
89
150
  **kwargs,
90
- ):
151
+ ) -> None:
91
152
  """
92
- kwargs for json.dump(obj, fp, **kwargs)
153
+ Write a dict (or list) to a JSON file.
154
+
155
+ Parameters
156
+ ----------
157
+ subj : T
158
+ The object/collection to serialize.
159
+ fp : str | Path
160
+ The file path to write.
161
+ many : bool
162
+ If True, write as a JSON array of multiple items.
163
+ **kwargs
164
+ Extra arguments for json.dump().
165
+
166
+ Returns
167
+ -------
168
+ None
93
169
  """
94
- if many:
95
- if isinstance(subj, Collective):
96
- json.dump([i.to_dict() for i in subj], fp=fp, **kwargs)
97
- return
98
- json.dump([subj.to_dict()], fp=fp, **kwargs)
99
- return
100
- json.dump(subj.to_dict(), fp=fp, **kwargs)
101
- logging.info(f"Successfully saved data to {fp}")
170
+ with open(fp, mode, encoding="utf-8") as f:
171
+ if many:
172
+ if isinstance(subj, Collective):
173
+ json.dump([i.to_dict() for i in subj], f, **kwargs)
174
+ else:
175
+ json.dump([subj.to_dict()], f, **kwargs)
176
+ else:
177
+ json.dump(subj.to_dict(), f, **kwargs)
178
+ logging.info(f"JSON data saved to {fp}")
179
+
180
+
181
+ # File: lionagi/protocols/adapters/json_adapter.py
@@ -9,6 +9,11 @@ from ..adapter import Adapter, T
9
9
 
10
10
 
11
11
  class CSVFileAdapter(Adapter):
12
+ """
13
+ Reads/writes CSV files to a list of dicts or vice versa,
14
+ using `pandas`.
15
+ """
16
+
12
17
  obj_key = ".csv"
13
18
 
14
19
  @classmethod
@@ -21,10 +26,31 @@ class CSVFileAdapter(Adapter):
21
26
  many: bool = False,
22
27
  **kwargs,
23
28
  ) -> list[dict]:
24
- """kwargs for pd.read_csv"""
29
+ """
30
+ Read a CSV file into a list of dictionaries.
31
+
32
+ Parameters
33
+ ----------
34
+ subj_cls : type[T]
35
+ The target class for context (not used).
36
+ obj : str | Path
37
+ The CSV file path.
38
+ many : bool, optional
39
+ If True, returns list[dict]; if False, returns only
40
+ the first dict.
41
+ **kwargs
42
+ Additional options for `pd.read_csv`.
43
+
44
+ Returns
45
+ -------
46
+ list[dict]
47
+ The parsed CSV data as a list of row dictionaries.
48
+ """
25
49
  df: pd.DataFrame = pd.read_csv(obj, **kwargs)
26
50
  dicts_ = df.to_dict(orient="records")
27
- return dicts_[0] if not many else dicts_
51
+ if many:
52
+ return dicts_
53
+ return dicts_[0] if len(dicts_) > 0 else {}
28
54
 
29
55
  @classmethod
30
56
  def to_obj(
@@ -35,16 +61,34 @@ class CSVFileAdapter(Adapter):
35
61
  fp: str | Path,
36
62
  many: bool = False,
37
63
  **kwargs,
38
- ):
39
- """kwargs for pd.DataFrame.to_csv"""
40
- kwargs["index"] = False
64
+ ) -> None:
65
+ """
66
+ Write an object's data to a CSV file.
67
+
68
+ Parameters
69
+ ----------
70
+ subj : T
71
+ The item(s) to convert. If `many=True`, can be a Collective.
72
+ fp : str | Path
73
+ File path to write the CSV.
74
+ many : bool
75
+ If True, we assume a collection of items, else a single item.
76
+ **kwargs
77
+ Extra params for `DataFrame.to_csv`.
78
+
79
+ Returns
80
+ -------
81
+ None
82
+ """
83
+ kwargs["index"] = False # By default, do not save index
41
84
  if many:
42
85
  if isinstance(subj, Collective):
43
86
  pd.DataFrame([i.to_dict() for i in subj]).to_csv(fp, **kwargs)
44
- logging.info(f"Successfully saved data to {fp}")
45
- return
87
+ else:
88
+ pd.DataFrame([subj.to_dict()]).to_csv(fp, **kwargs)
89
+ else:
46
90
  pd.DataFrame([subj.to_dict()]).to_csv(fp, **kwargs)
47
- logging.info(f"Successfully saved data to {fp}")
48
- return
49
- pd.DataFrame([subj.to_dict()]).to_csv(fp, **kwargs)
50
- logging.info(f"Successfully saved data to {fp}")
91
+ logging.info(f"CSV data saved to {fp}")
92
+
93
+
94
+ # File: lionagi/protocols/adapters/pandas_/csv_adapter.py
@@ -1,3 +1,8 @@
1
+ """
2
+ Provides an ExcelFileAdapter for reading/writing Excel (.xlsx) files
3
+ via pandas.
4
+ """
5
+
1
6
  import logging
2
7
  from pathlib import Path
3
8
 
@@ -9,6 +14,10 @@ from ..adapter import Adapter, T
9
14
 
10
15
 
11
16
  class ExcelFileAdapter(Adapter):
17
+ """
18
+ Reads/writes Excel (XLSX) files, using `pandas`.
19
+ """
20
+
12
21
  obj_key = ".xlsx"
13
22
 
14
23
  @classmethod
@@ -21,10 +30,29 @@ class ExcelFileAdapter(Adapter):
21
30
  many: bool = False,
22
31
  **kwargs,
23
32
  ) -> list[dict]:
24
- """kwargs for pd.read_csv"""
33
+ """
34
+ Read an Excel file into a list of dictionaries.
35
+
36
+ Parameters
37
+ ----------
38
+ subj_cls : type[T]
39
+ Target class for context.
40
+ obj : str | Path
41
+ The Excel file path.
42
+ many : bool, optional
43
+ If True, returns list[dict]. If False, returns single dict or first element.
44
+ **kwargs
45
+ Additional options for `pd.read_excel`.
46
+
47
+ Returns
48
+ -------
49
+ list[dict]
50
+ """
25
51
  df: pd.DataFrame = pd.read_excel(obj, **kwargs)
26
52
  dicts_ = df.to_dict(orient="records")
27
- return dicts_[0] if not many else dicts_
53
+ if many:
54
+ return dicts_
55
+ return dicts_[0] if len(dicts_) > 0 else {}
28
56
 
29
57
  @classmethod
30
58
  def to_obj(
@@ -35,18 +63,32 @@ class ExcelFileAdapter(Adapter):
35
63
  fp: str | Path,
36
64
  many: bool = False,
37
65
  **kwargs,
38
- ):
39
- """kwargs for pd.DataFrame.to_csv"""
66
+ ) -> None:
67
+ """
68
+ Write data to an Excel file.
69
+
70
+ Parameters
71
+ ----------
72
+ subj : T
73
+ The object(s) to convert to Excel rows.
74
+ fp : str | Path
75
+ Path to save the XLSX file.
76
+ many : bool
77
+ If True, writes multiple items (e.g., a Collective).
78
+ **kwargs
79
+ Extra parameters for `DataFrame.to_excel`.
80
+ """
40
81
  kwargs["index"] = False
41
82
  if many:
42
83
  if isinstance(subj, Collective):
43
84
  pd.DataFrame([i.to_dict() for i in subj]).to_excel(
44
85
  fp, **kwargs
45
86
  )
46
- logging.info(f"Successfully saved data to {fp}")
47
- return
87
+ else:
88
+ pd.DataFrame([subj.to_dict()]).to_excel(fp, **kwargs)
89
+ else:
48
90
  pd.DataFrame([subj.to_dict()]).to_excel(fp, **kwargs)
49
- logging.info(f"Successfully saved data to {fp}")
50
- return
51
- pd.DataFrame([subj.to_dict()]).to_excel(fp, **kwargs)
52
- logging.info(f"Successfully saved data to {fp}")
91
+ logging.info(f"Excel data saved to {fp}")
92
+
93
+
94
+ # File: lionagi/protocols/adapters/pandas_/excel_adapter.py
@@ -1,3 +1,8 @@
1
+ """
2
+ Defines a `PandasDataFrameAdapter` that converts between
3
+ a DataFrame and a list of dictionary-based elements.
4
+ """
5
+
1
6
  from datetime import datetime
2
7
 
3
8
  import pandas as pd
@@ -6,6 +11,11 @@ from ..adapter import Adapter, T
6
11
 
7
12
 
8
13
  class PandasDataFrameAdapter(Adapter):
14
+ """
15
+ Converts a set of objects to a single `pd.DataFrame`, or
16
+ a DataFrame to a list of dictionaries. Typically used in memory,
17
+ not for saving to file.
18
+ """
9
19
 
10
20
  obj_key = "pd_dataframe"
11
21
  alias = ("pandas_dataframe", "pd.DataFrame", "pd_dataframe")
@@ -14,18 +24,58 @@ class PandasDataFrameAdapter(Adapter):
14
24
  def from_obj(
15
25
  cls, subj_cls: type[T], obj: pd.DataFrame, /, **kwargs
16
26
  ) -> list[dict]:
17
- """kwargs for pd.DataFrame.to_dict"""
27
+ """
28
+ Convert an existing DataFrame into a list of dicts.
29
+
30
+ Parameters
31
+ ----------
32
+ subj_cls : type[T]
33
+ The internal class to which we might parse.
34
+ obj : pd.DataFrame
35
+ The DataFrame to convert.
36
+ **kwargs
37
+ Additional args for DataFrame.to_dict (like `orient`).
38
+
39
+ Returns
40
+ -------
41
+ list[dict]
42
+ Each row as a dictionary.
43
+ """
18
44
  return obj.to_dict(orient="records", **kwargs)
19
45
 
20
46
  @classmethod
21
47
  def to_obj(cls, subj: list[T], /, **kwargs) -> pd.DataFrame:
22
- """kwargs for pd.DataFrame"""
48
+ """
49
+ Convert multiple items into a DataFrame, adjusting `created_at` to datetime.
50
+
51
+ Parameters
52
+ ----------
53
+ subj : list[T]
54
+ The items to convert. Each item must have `to_dict()`.
55
+ **kwargs
56
+ Additional arguments for `pd.DataFrame(...)`.
57
+
58
+ Returns
59
+ -------
60
+ pd.DataFrame
61
+ The resulting DataFrame.
62
+ """
23
63
  out_ = []
24
64
  for i in subj:
25
65
  _dict = i.to_dict()
26
- _dict["created_at"] = datetime.fromtimestamp(_dict["created_at"])
66
+ # Attempt to parse timestamps
67
+ if "created_at" in _dict:
68
+ try:
69
+ _dict["created_at"] = datetime.fromtimestamp(
70
+ _dict["created_at"]
71
+ )
72
+ except Exception:
73
+ pass
27
74
  out_.append(_dict)
28
75
  df = pd.DataFrame(out_, **kwargs)
76
+ # Convert created_at to datetime if present
29
77
  if "created_at" in df.columns:
30
- df["created_at"] = pd.to_datetime(df["created_at"])
78
+ df["created_at"] = pd.to_datetime(
79
+ df["created_at"], errors="coerce"
80
+ )
31
81
  return df
@@ -1,17 +1,57 @@
1
+ """
2
+ Defines a `PandasSeriesAdapter` that converts a single object
3
+ to/from a `pd.Series`.
4
+ """
5
+
1
6
  import pandas as pd
2
7
 
3
8
  from ..adapter import Adapter, T
4
9
 
5
10
 
6
11
  class PandasSeriesAdapter(Adapter):
12
+ """
13
+ Converts a single item to a Pandas Series and vice versa.
14
+ Great for 1-row data or simpler key-value pairs.
15
+ """
7
16
 
8
17
  obj_key = "pd_series"
9
18
  alias = ("pandas_series", "pd.series", "pd_series")
10
19
 
11
20
  @classmethod
12
21
  def from_obj(cls, subj_cls: type[T], obj: pd.Series, /, **kwargs) -> dict:
22
+ """
23
+ Convert a Pandas Series into a dictionary.
24
+
25
+ Parameters
26
+ ----------
27
+ subj_cls : type[T]
28
+ Possibly the class we might use to rehydrate the item.
29
+ obj : pd.Series
30
+ The series to interpret.
31
+ **kwargs
32
+ Additional arguments for `Series.to_dict`.
33
+
34
+ Returns
35
+ -------
36
+ dict
37
+ The data from the Series as a dictionary.
38
+ """
13
39
  return obj.to_dict(**kwargs)
14
40
 
15
41
  @classmethod
16
42
  def to_obj(cls, subj: T, /, **kwargs) -> pd.Series:
43
+ """
44
+ Convert a single item to a Series.
45
+
46
+ Parameters
47
+ ----------
48
+ subj : T
49
+ The item, which must have `to_dict()`.
50
+ **kwargs
51
+ Extra args passed to `pd.Series`.
52
+
53
+ Returns
54
+ -------
55
+ pd.Series
56
+ """
17
57
  return pd.Series(subj.to_dict(), **kwargs)
@@ -457,4 +457,4 @@ class ID(Generic[E]):
457
457
  return False
458
458
 
459
459
 
460
- # File: protocols/generic/element.py
460
+ # File: lionagi/protocols/generic/element.py