lionagi 0.15.11__py3-none-any.whl → 0.15.13__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.
@@ -1,7 +1,12 @@
1
1
  """
2
- Clean LionAGI async PostgreSQL adapter for integration into lionagi core.
3
-
4
- This adapter leverages pydapter v1.0.2+ CRUD operations.
2
+ Simplified LionAGI async PostgreSQL adapter for pydapter v1.0.4+
3
+
4
+ This adapter leverages pydapter's improved raw SQL handling.
5
+ No workarounds needed - pydapter now properly handles:
6
+ - Raw SQL without table parameter
7
+ - No table inspection for raw SQL
8
+ - ORDER BY operations
9
+ - Both SQLite and PostgreSQL connections
5
10
  """
6
11
 
7
12
  from __future__ import annotations
@@ -24,11 +29,12 @@ T = TypeVar("T")
24
29
 
25
30
  class LionAGIAsyncPostgresAdapter(AsyncPostgresAdapter[T]):
26
31
  """
27
- Zero-config async PostgreSQL adapter for lionagi Nodes.
32
+ Streamlined async adapter for lionagi Nodes.
28
33
 
34
+ Features:
29
35
  - Auto-creates tables with lionagi schema
30
- - Changes default adapt_meth to "to_dict" for lionagi Elements
31
- - Everything else handled by parent AsyncPostgresAdapter
36
+ - Inherits all pydapter v1.0.4+ improvements
37
+ - No workarounds needed for SQLite or raw SQL
32
38
  """
33
39
 
34
40
  obj_key: ClassVar[str] = "lionagi_async_pg"
@@ -40,10 +46,10 @@ class LionAGIAsyncPostgresAdapter(AsyncPostgresAdapter[T]):
40
46
  /,
41
47
  *,
42
48
  many: bool = True,
43
- adapt_meth: str = "as_jsonable", # Default to to_dict for lionagi
49
+ adapt_meth: str = None,
44
50
  **kw,
45
51
  ):
46
- """Write lionagi Node(s) to PostgreSQL with CRUD support."""
52
+ """Write lionagi Node(s) to database with auto-table creation."""
47
53
  # Auto-create table if needed
48
54
  if table := kw.get("table"):
49
55
  if engine_url := (kw.get("dsn") or kw.get("engine_url")):
@@ -58,14 +64,12 @@ class LionAGIAsyncPostgresAdapter(AsyncPostgresAdapter[T]):
58
64
  @classmethod
59
65
  async def _ensure_table(cls, engine_or_url, table_name: str):
60
66
  """Create table with lionagi schema if it doesn't exist."""
61
- # Handle both engine and URL
62
- should_dispose = None
67
+ should_dispose = False
63
68
  if isinstance(engine_or_url, str):
64
69
  engine = create_async_engine(engine_or_url, future=True)
65
70
  should_dispose = True
66
71
  else:
67
72
  engine = engine_or_url
68
- should_dispose = False
69
73
 
70
74
  try:
71
75
  async with engine.begin() as conn:
@@ -84,12 +88,8 @@ class LionAGIAsyncPostgresAdapter(AsyncPostgresAdapter[T]):
84
88
  sa.MetaData(),
85
89
  sa.Column("id", sa.String, primary_key=True),
86
90
  sa.Column("content", json_type),
87
- sa.Column(
88
- "metadata", json_type
89
- ), # Use metadata directly now
90
- sa.Column(
91
- "created_at", sa.Float
92
- ), # Stored as float timestamp
91
+ sa.Column("node_metadata", json_type),
92
+ sa.Column("created_at", sa.DateTime),
93
93
  sa.Column("embedding", json_type, nullable=True),
94
94
  ).create(sync_conn, checkfirst=True)
95
95
  )
lionagi/ln/_async_call.py CHANGED
@@ -4,6 +4,7 @@ from dataclasses import dataclass
4
4
  from typing import Any, ClassVar
5
5
 
6
6
  import anyio
7
+ import anyio.to_thread
7
8
  from pydantic import BaseModel
8
9
 
9
10
  from ._models import Params
@@ -190,11 +190,13 @@ class Element(BaseModel, Observable):
190
190
  return val
191
191
 
192
192
  @field_validator("created_at", mode="before")
193
- def _coerce_created_at(cls, val: float | dt.datetime | None) -> float:
193
+ def _coerce_created_at(
194
+ cls, val: float | dt.datetime | str | None
195
+ ) -> float:
194
196
  """Coerces `created_at` to a float-based timestamp.
195
197
 
196
198
  Args:
197
- val (float | datetime | None): The initial creation time value.
199
+ val (float | datetime | str | None): The initial creation time value.
198
200
 
199
201
  Returns:
200
202
  float: A float representing Unix epoch time in seconds.
@@ -208,6 +210,27 @@ class Element(BaseModel, Observable):
208
210
  return val
209
211
  if isinstance(val, dt.datetime):
210
212
  return val.timestamp()
213
+ if isinstance(val, str):
214
+ # Parse datetime string from database
215
+ try:
216
+ # Handle datetime strings like "2025-08-30 10:54:59.310329"
217
+ # Convert space to T for ISO format, but handle timezone properly
218
+ iso_string = val.replace(" ", "T")
219
+ parsed_dt = dt.datetime.fromisoformat(iso_string)
220
+
221
+ # If parsed as naive datetime (no timezone), treat as UTC to avoid local timezone issues
222
+ if parsed_dt.tzinfo is None:
223
+ parsed_dt = parsed_dt.replace(tzinfo=dt.timezone.utc)
224
+
225
+ return parsed_dt.timestamp()
226
+ except ValueError:
227
+ # Try parsing as float string as fallback
228
+ try:
229
+ return float(val)
230
+ except ValueError:
231
+ raise ValueError(
232
+ f"Invalid datetime string: {val}"
233
+ ) from None
211
234
  try:
212
235
  return float(val) # type: ignore
213
236
  except Exception:
@@ -245,7 +268,7 @@ class Element(BaseModel, Observable):
245
268
  Returns:
246
269
  datetime: The creation time in UTC.
247
270
  """
248
- return dt.datetime.fromtimestamp(self.created_at)
271
+ return dt.datetime.fromtimestamp(self.created_at, tz=dt.timezone.utc)
249
272
 
250
273
  def __eq__(self, other: Any) -> bool:
251
274
  """Compares two Element instances by their ID."""
@@ -279,18 +302,26 @@ class Element(BaseModel, Observable):
279
302
  dict_["metadata"].update({"lion_class": self.class_name(full=True)})
280
303
  return {k: v for k, v in dict_.items() if ln.not_sentinel(v)}
281
304
 
282
- def to_dict(self, mode: Literal["python", "json"] = "python") -> dict:
305
+ def to_dict(
306
+ self, mode: Literal["python", "json", "db"] = "python"
307
+ ) -> dict:
283
308
  """Converts this Element to a dictionary."""
284
309
  if mode == "python":
285
310
  return self._to_dict()
286
- return orjson.loads(self.to_json(decode=False))
311
+ if mode == "json":
312
+ return orjson.loads(self.to_json(decode=False))
313
+ if mode == "db":
314
+ dict_ = orjson.loads(self.to_json(decode=False))
315
+ dict_["node_metadata"] = dict_.pop("metadata", {})
316
+ dict_["created_at"] = self.created_datetime.isoformat(sep=" ")
317
+ return dict_
287
318
 
288
319
  def as_jsonable(self) -> dict:
289
320
  """Converts this Element to a JSON-serializable dictionary."""
290
321
  return self.to_dict(mode="json")
291
322
 
292
323
  @classmethod
293
- def from_dict(cls, data: dict, /) -> Element:
324
+ def from_dict(cls, data: dict, /, mode: str = "python") -> Element:
294
325
  """Deserializes a dictionary into an Element or subclass of Element.
295
326
 
296
327
  If `lion_class` in `metadata` refers to a subclass, this method
@@ -298,8 +329,17 @@ class Element(BaseModel, Observable):
298
329
 
299
330
  Args:
300
331
  data (dict): A dictionary of field data.
332
+ mode (str): Format mode - "python" for normal dicts, "db" for database format.
301
333
  """
302
- metadata = data.pop("metadata", {})
334
+ # Preprocess database format if needed
335
+ if mode == "db":
336
+ data = cls._preprocess_db_data(data.copy())
337
+ metadata = {}
338
+
339
+ if "node_metadata" in data:
340
+ metadata = data.pop("node_metadata")
341
+ elif "metadata" in data:
342
+ metadata = data.pop("metadata")
303
343
  if "lion_class" in metadata:
304
344
  subcls: str = metadata.pop("lion_class")
305
345
  if subcls != Element.class_name(full=True):
@@ -327,6 +367,56 @@ class Element(BaseModel, Observable):
327
367
  data["metadata"] = metadata
328
368
  return cls.model_validate(data)
329
369
 
370
+ @classmethod
371
+ def _preprocess_db_data(cls, data: dict) -> dict:
372
+ """Preprocess raw database data for Element compatibility."""
373
+ import datetime as dt
374
+ import json
375
+
376
+ # Handle created_at field - convert datetime string to timestamp
377
+ if "created_at" in data and isinstance(data["created_at"], str):
378
+ try:
379
+ # Parse datetime string and convert to timestamp
380
+ dt_obj = dt.datetime.fromisoformat(
381
+ data["created_at"].replace(" ", "T")
382
+ )
383
+ # Treat as UTC if naive
384
+ if dt_obj.tzinfo is None:
385
+ dt_obj = dt_obj.replace(tzinfo=dt.timezone.utc)
386
+ data["created_at"] = dt_obj.timestamp()
387
+ except (ValueError, TypeError):
388
+ # Keep as string if parsing fails
389
+ pass
390
+
391
+ # Handle JSON string fields - parse to dict/list
392
+ json_fields = ["content", "node_metadata", "embedding"]
393
+ for field in json_fields:
394
+ if field in data and isinstance(data[field], str):
395
+ if data[field] in ("null", ""):
396
+ data[field] = None if field == "embedding" else {}
397
+ else:
398
+ try:
399
+ data[field] = json.loads(data[field])
400
+ except (json.JSONDecodeError, TypeError):
401
+ # Keep as empty dict for metadata fields, None for embedding
402
+ data[field] = {} if field != "embedding" else None
403
+
404
+ # Handle node_metadata -> metadata mapping
405
+ if "node_metadata" in data:
406
+ if (
407
+ data["node_metadata"] == "null"
408
+ or data["node_metadata"] is None
409
+ ):
410
+ data["metadata"] = {}
411
+ else:
412
+ data["metadata"] = (
413
+ data["node_metadata"] if data["node_metadata"] else {}
414
+ )
415
+ # Remove node_metadata to avoid Pydantic validation error
416
+ data.pop("node_metadata", None)
417
+
418
+ return data
419
+
330
420
  def to_json(self, decode: bool = True) -> str:
331
421
  """Converts this Element to a JSON string."""
332
422
  dict_ = self._to_dict()
@@ -338,10 +428,11 @@ class Element(BaseModel, Observable):
338
428
  ).decode()
339
429
  return orjson.dumps(dict_, default=DEFAULT_ELEMENT_SERIALIZER)
340
430
 
341
- def from_json(cls, json_str: str) -> Element:
431
+ @classmethod
432
+ def from_json(cls, json_str: str, mode: str = "python") -> Element:
342
433
  """Deserializes a JSON string into an Element or subclass of Element."""
343
434
  data = orjson.loads(json_str)
344
- return cls.from_dict(data)
435
+ return cls.from_dict(data, mode=mode)
345
436
 
346
437
 
347
438
  DEFAULT_ELEMENT_SERIALIZER = ln.get_orjson_default(
@@ -62,8 +62,8 @@ class Node(Element, Relational, AsyncAdaptable, Adaptable):
62
62
  async def adapt_to_async(
63
63
  self, obj_key: str, many=False, **kwargs: Any
64
64
  ) -> Any:
65
- kwargs["adapt_meth"] = "as_jsonable"
66
- kwargs["mode"] = "json"
65
+ kwargs["adapt_meth"] = "to_dict"
66
+ kwargs["mode"] = "db"
67
67
  return await super().adapt_to_async(
68
68
  obj_key=obj_key, many=many, **kwargs
69
69
  )
@@ -77,6 +77,7 @@ class Node(Element, Relational, AsyncAdaptable, Adaptable):
77
77
  **kwargs: Any,
78
78
  ) -> Node:
79
79
  kwargs["adapt_meth"] = "from_dict"
80
+ kwargs["mode"] = "db"
80
81
  return await super().adapt_from_async(
81
82
  obj, obj_key=obj_key, many=many, **kwargs
82
83
  )
@@ -85,8 +86,8 @@ class Node(Element, Relational, AsyncAdaptable, Adaptable):
85
86
  """
86
87
  Convert this Node to another format using a registered adapter.
87
88
  """
88
- kwargs["adapt_meth"] = "as_jsonable"
89
- kwargs["mode"] = "json"
89
+ kwargs["adapt_meth"] = "to_dict"
90
+ kwargs["mode"] = "db"
90
91
  return super().adapt_to(obj_key=obj_key, many=many, **kwargs)
91
92
 
92
93
  @classmethod
@@ -103,6 +104,7 @@ class Node(Element, Relational, AsyncAdaptable, Adaptable):
103
104
  auto-delegate to the correct subclass via from_dict.
104
105
  """
105
106
  kwargs["adapt_meth"] = "from_dict"
107
+ kwargs["mode"] = "db"
106
108
  return super().adapt_from(obj, obj_key=obj_key, many=many, **kwargs)
107
109
 
108
110
  @field_serializer("content")
lionagi/version.py CHANGED
@@ -1 +1 @@
1
- __version__ = "0.15.11"
1
+ __version__ = "0.15.13"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lionagi
3
- Version: 0.15.11
3
+ Version: 0.15.13
4
4
  Summary: An Intelligence Operating System.
5
5
  Author-email: HaiyangLi <quantocean.li@gmail.com>
6
6
  License: Apache License
@@ -225,10 +225,10 @@ Requires-Dist: anyio>=4.7.0
225
225
  Requires-Dist: backoff>=2.0.0
226
226
  Requires-Dist: jinja2>=3.0.0
227
227
  Requires-Dist: json-repair>=0.40.0
228
- Requires-Dist: pillow>=11.0.0
228
+ Requires-Dist: pillow>=10.0.0
229
229
  Requires-Dist: psutil>=6.0.0
230
230
  Requires-Dist: pydantic-settings>=2.8.0
231
- Requires-Dist: pydapter[pandas]>=1.0.2
231
+ Requires-Dist: pydapter[pandas]>=1.0.4
232
232
  Requires-Dist: python-dotenv>=1.1.0
233
233
  Requires-Dist: tiktoken>=0.9.0
234
234
  Requires-Dist: toml>=0.8.0
@@ -274,13 +274,13 @@ Description-Content-Type: text/markdown
274
274
  ![PyPI - Downloads](https://img.shields.io/pypi/dm/lionagi?color=blue)
275
275
  ![Python Version](https://img.shields.io/badge/python-3.10%2B-blue)
276
276
 
277
- [Documentation](https://lion-agi.github.io/lionagi/) |
277
+ [Documentation](https://khive-ai.github.io/lionagi/) |
278
278
  [Discord](https://discord.gg/JDj9ENhUE8) |
279
279
  [PyPI](https://pypi.org/project/lionagi/)
280
280
 
281
281
  # LION - Language InterOperable Network
282
282
 
283
- ## An Agentic Intelligence SDK
283
+ ## An AGentic Intelligence SDK
284
284
 
285
285
  LionAGI is a robust framework for orchestrating multi-step AI operations with
286
286
  precise control. Bring together multiple models, advanced ReAct reasoning, tool
@@ -288,13 +288,13 @@ integrations, and custom validations in a single coherent pipeline.
288
288
 
289
289
  ## Why LionAGI?
290
290
 
291
- - **Structured**: LLM interactions are validated and typed (via Pydantic).
291
+ - **Structured**: Validate and type all LLM interactions with Pydantic.
292
292
  - **Expandable**: Integrate multiple providers (OpenAI, Anthropic, Perplexity,
293
293
  custom) with minimal friction.
294
- - **Controlled**: Built-in safety checks, concurrency strategies, and advanced
295
- multi-step flowslike ReAct with verbose outputs.
296
- - **Transparent**: Real-time logging, message introspection, and easy debugging
297
- of tool usage.
294
+ - **Controlled**: Use built-in safety checks, concurrency strategies, and advanced
295
+ multi-step flows like ReAct.
296
+ - **Transparent**: Debug easily with real-time logging, message introspection, and
297
+ tool usage tracking.
298
298
 
299
299
  ## Installation
300
300
 
@@ -310,12 +310,12 @@ pip install lionagi # or install directly
310
310
  from lionagi import Branch, iModel
311
311
 
312
312
  # Pick a model
313
- gpt41 = iModel(provider="openai", model="gpt-4.1-mini")
313
+ gpt4o = iModel(provider="openai", model="gpt-4o-mini")
314
314
 
315
315
  # Create a Branch (conversation context)
316
316
  hunter = Branch(
317
317
  system="you are a hilarious dragon hunter who responds in 10 words rhymes.",
318
- chat_model=gpt41,
318
+ chat_model=gpt4o,
319
319
  )
320
320
 
321
321
  # Communicate asynchronously
@@ -341,8 +341,8 @@ res = await hunter.communicate(
341
341
  "Tell me a short dragon joke",
342
342
  response_format=Joke
343
343
  )
344
- print(type(response))
345
- print(response.joke)
344
+ print(type(res))
345
+ print(res.joke)
346
346
  ```
347
347
 
348
348
  ```
@@ -362,7 +362,10 @@ pip install "lionagi[reader]"
362
362
  ```python
363
363
  from lionagi.tools.types import ReaderTool
364
364
 
365
- branch = Branch(chat_model=gpt4o, tools=ReaderTool)
365
+ # Define model first
366
+ gpt4o = iModel(provider="openai", model="gpt-4o-mini")
367
+
368
+ branch = Branch(chat_model=gpt4o, tools=[ReaderTool])
366
369
  result = await branch.ReAct(
367
370
  instruct={
368
371
  "instruction": "Summarize my PDF and compare with relevant papers.",
@@ -396,13 +399,15 @@ print(df.tail())
396
399
  ```python
397
400
  from lionagi import Branch, iModel
398
401
 
402
+ # Define models for multi-model orchestration
403
+ gpt4o = iModel(provider="openai", model="gpt-4o-mini")
399
404
  sonnet = iModel(
400
405
  provider="anthropic",
401
406
  model="claude-3-5-sonnet-20241022",
402
407
  max_tokens=1000, # max_tokens is required for anthropic models
403
408
  )
404
409
 
405
- branch = Branch(chat_model=gpt41)
410
+ branch = Branch(chat_model=gpt4o)
406
411
  analysis = await branch.communicate("Analyze these stats", chat_model=sonnet) # Switch mid-flow
407
412
  ```
408
413
 
@@ -6,10 +6,10 @@ lionagi/config.py,sha256=W3JOC_TFad8hFkpTG8yv0-GNupa7x3wX4NAUfWpB59U,3763
6
6
  lionagi/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
7
  lionagi/settings.py,sha256=HDuKCEJCpc4HudKodBnhoQUGuTGhRHdlIFhbtf3VBtY,1633
8
8
  lionagi/utils.py,sha256=7Hlt60LiShRdNPXv4y2e_xq7W2N0PM5cGRJnc8qXAVw,28660
9
- lionagi/version.py,sha256=Bw5DUxQ3jqdKvFLsxUsxaKKMc-9Ywbelea4Rftx-Kj0,24
9
+ lionagi/version.py,sha256=6AIqVLeKq3uS7QeuesqvTQrN9gWiCBFTAygmSJRA6-0,24
10
10
  lionagi/adapters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
11
  lionagi/adapters/_utils.py,sha256=n4DS27CZfC-0O_UFaYtlUdjiMx9IeYsGpP7MVaFO5ZA,885
12
- lionagi/adapters/async_postgres_adapter.py,sha256=FzkRVMhw8xZNjyc9O_YVYRHBFhsoaL0HWIy2SUd-GvE,3284
12
+ lionagi/adapters/async_postgres_adapter.py,sha256=OEJd9ie8prxRQK2_-W9qmdI3Sl6Q7xxRs7Vey16G3pQ,3172
13
13
  lionagi/adapters/postgres_model_adapter.py,sha256=uwWrbnihtYsCIttHExmtAIZwyohFtKoxnHU1N1M2NvQ,4519
14
14
  lionagi/fields/__init__.py,sha256=yrn9NDAM6_v73kK7aJeb-Pvqigeu8WASaV-My-6CDsc,939
15
15
  lionagi/fields/action.py,sha256=OziEpbaUeEVo34KdtbzDxXJBgkf3QLxlcKIQAfHe4O0,5791
@@ -82,7 +82,7 @@ lionagi/libs/validate/to_num.py,sha256=ZRHDjpTCykPfDIZZa4rZKNaR_8ZHbPDFlw9rc02Dr
82
82
  lionagi/libs/validate/validate_boolean.py,sha256=bjiX_WZ3Bg8XcqoWLzE1G9BpO0AisrlZUxrpye_mlGk,3614
83
83
  lionagi/libs/validate/xml_parser.py,sha256=PHBYAre4hhthPpDP9Yrp3UYSWdANPx60F1qhxe0m4uw,7004
84
84
  lionagi/ln/__init__.py,sha256=aunFi1qRkEuTzdcrkN9pv499aynmQdjlNbJJBRPwRvc,1754
85
- lionagi/ln/_async_call.py,sha256=N8vpXPDyonVqfszVEgOTQS8M1MohYJH9vcf1xwuo4JU,9367
85
+ lionagi/ln/_async_call.py,sha256=pRwJqUELQ22YMiLVv4zS-NSuTGHftqBvxSnt5P_ReZk,9390
86
86
  lionagi/ln/_extract_json.py,sha256=K82UBoVQbb6hib9bIqnYgFFYefvw7hIx11D6NKMZfws,1843
87
87
  lionagi/ln/_fuzzy_json.py,sha256=zJGyyBoEidLFSIF9i8sactTrQOhyAecQhtvhls9w4mU,3541
88
88
  lionagi/ln/_hash.py,sha256=g20yJfuVhAsfsBOWlkO889DHte6cbUCl6vV5QMT8nUo,3499
@@ -155,7 +155,7 @@ lionagi/protocols/forms/flow.py,sha256=t9Ycvmb-stj0rCyvXXwd7WBcDtuCCTEKYst2aqFDV
155
155
  lionagi/protocols/forms/form.py,sha256=B4903km_Ljz-OxYkb1ZT_cpHZSaAYYJpZMsffWlooo8,3062
156
156
  lionagi/protocols/forms/report.py,sha256=SvJJjOSCTfVuqK7AKaY8ldQIGJeSK2zoyPWUV41ge2c,1609
157
157
  lionagi/protocols/generic/__init__.py,sha256=5y5joOZzfFWERl75auAcNcKC3lImVJ5ZZGvvHZUFCJM,112
158
- lionagi/protocols/generic/element.py,sha256=9TdWPnKyskIcNkJyhfkcWjwu2t3xoU5-QVg36bYavtM,14810
158
+ lionagi/protocols/generic/element.py,sha256=5R9cLodaPzSPbellgFEudRxZIOMJDiCV8emyQKuEbPI,18621
159
159
  lionagi/protocols/generic/event.py,sha256=Rwke4sNLddQlJ8PTu-dTPZYBy1qmwaLAERbOLd_udpg,6512
160
160
  lionagi/protocols/generic/log.py,sha256=Y06zAQewkNlaIWjut_c6c45KY_LJfLHwzUaDGLULaas,8212
161
161
  lionagi/protocols/generic/pile.py,sha256=mc10zh9RdqfozPEBOgRdkrTgIWUHBz8enAcQ-8pFhRQ,37046
@@ -165,7 +165,7 @@ lionagi/protocols/graph/__init__.py,sha256=UPu3OmUpjSgX2aBuBJUdG2fppGlfqAH96hU0q
165
165
  lionagi/protocols/graph/_utils.py,sha256=mts4M2wcGKdY9hC-1917lxIJT5oycW9VnRgfRx8ydbI,605
166
166
  lionagi/protocols/graph/edge.py,sha256=YxSGj4w_fG7khm-zpKduuK5fJzhJDx23JhU1dZp29d8,5241
167
167
  lionagi/protocols/graph/graph.py,sha256=iM54gAluKgnYtv-6UaYqWhlzdijZPw0B1vren-LrNes,10605
168
- lionagi/protocols/graph/node.py,sha256=vj_VbmnGVwsY9GkDAEI84EzdC_RvQwAmVPrcGPXFBKg,4546
168
+ lionagi/protocols/graph/node.py,sha256=JwX-yaXgjifZbWYUtfL99H2_9T8EnWs73tPqo5xvI00,4594
169
169
  lionagi/protocols/mail/__init__.py,sha256=5y5joOZzfFWERl75auAcNcKC3lImVJ5ZZGvvHZUFCJM,112
170
170
  lionagi/protocols/mail/exchange.py,sha256=P1PcrFylIBeiQa8kox9H1qyJ4kjhUlbLiTUT8rs1OXg,7041
171
171
  lionagi/protocols/mail/mail.py,sha256=RB5CUft_4J85H9nM9g6aRXomTaqKwF5xVjJacPAhoa8,1356
@@ -235,7 +235,7 @@ lionagi/tools/types.py,sha256=XtJLY0m-Yi_ZLWhm0KycayvqMCZd--HxfQ0x9vFUYDE,230
235
235
  lionagi/tools/file/__init__.py,sha256=5y5joOZzfFWERl75auAcNcKC3lImVJ5ZZGvvHZUFCJM,112
236
236
  lionagi/tools/file/reader.py,sha256=2YKgU3VKo76zfL_buDAUQJoPLC56f6WJ4_mdJjlMDIM,9509
237
237
  lionagi/tools/memory/tools.py,sha256=earYkKxSOz_iXkqVZYTEDfE3dwZYIWPXZrqQ1DYGz4I,15941
238
- lionagi-0.15.11.dist-info/METADATA,sha256=MGbzbThvkwxpLaHEsqWXP0CMiWigSU5opBOgCl_rKV0,22896
239
- lionagi-0.15.11.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
240
- lionagi-0.15.11.dist-info/licenses/LICENSE,sha256=VXFWsdoN5AAknBCgFqQNgPWYx7OPp-PFEP961zGdOjc,11288
241
- lionagi-0.15.11.dist-info/RECORD,,
238
+ lionagi-0.15.13.dist-info/METADATA,sha256=gEYHcdvOzt-bHqXoLJsguGdJTqDtYkISaxtv5tKVdGE,23052
239
+ lionagi-0.15.13.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
240
+ lionagi-0.15.13.dist-info/licenses/LICENSE,sha256=VXFWsdoN5AAknBCgFqQNgPWYx7OPp-PFEP961zGdOjc,11288
241
+ lionagi-0.15.13.dist-info/RECORD,,