lionagi 0.15.5__py3-none-any.whl → 0.15.7__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.
lionagi/ln/_async_call.py CHANGED
@@ -37,7 +37,7 @@ async def alcall(
37
37
  retry_initial_deplay: float = 0,
38
38
  retry_backoff: float = 1,
39
39
  retry_default: Any = Unset,
40
- retry_timeout: float = 0,
40
+ retry_timeout: float = None,
41
41
  retry_attempts: int = 0,
42
42
  max_concurrent: int | None = None,
43
43
  throttle_period: float | None = None,
@@ -277,8 +277,8 @@ class AlcallParams(Params):
277
277
  async def __call__(
278
278
  self, input_: list[Any], func: Callable[..., T], **kw
279
279
  ) -> list[T]:
280
- f = self.as_partial()
281
- return await f(input_, func, **kw)
280
+ kwargs = {**self.default_kw(), **kw}
281
+ return await alcall(input_, func, **kwargs)
282
282
 
283
283
 
284
284
  @dataclass(slots=True, init=False, frozen=True)
@@ -290,5 +290,7 @@ class BcallParams(AlcallParams):
290
290
  async def __call__(
291
291
  self, input_: list[Any], func: Callable[..., T], **kw
292
292
  ) -> list[T]:
293
- f = self.as_partial()
294
- return await f(input_, func, self.batch_size, **kw)
293
+ kwargs = {**self.default_kw(), **kw}
294
+ func = self._func
295
+
296
+ return await func(input_, func, self.batch_size, **kwargs)
lionagi/ln/_models.py CHANGED
@@ -1,5 +1,4 @@
1
1
  from dataclasses import dataclass, field
2
- from functools import partial
3
2
  from typing import Any, ClassVar
4
3
 
5
4
  from typing_extensions import override
@@ -9,8 +8,9 @@ from ._types import Undefined, Unset, is_sentinel
9
8
  __all__ = ("Params", "DataClass")
10
9
 
11
10
 
12
- class _SentinelAware:
13
- """Metaclass to ensure sentinels are handled correctly in subclasses."""
11
+ @dataclass(slots=True, frozen=True, init=False)
12
+ class Params:
13
+ """Base class for parameters used in various functions."""
14
14
 
15
15
  _none_as_sentinel: ClassVar[bool] = False
16
16
  """If True, None is treated as a sentinel value."""
@@ -26,6 +26,25 @@ class _SentinelAware:
26
26
  )
27
27
  """Class variable cache to store allowed keys for parameters."""
28
28
 
29
+ def __init__(self, **kwargs: Any):
30
+ """Initialize the Params object with keyword arguments."""
31
+ # Set all attributes from kwargs, allowing for sentinel values
32
+ for k, v in kwargs.items():
33
+ if k in self.allowed():
34
+ object.__setattr__(self, k, v)
35
+ else:
36
+ raise ValueError(f"Invalid parameter: {k}")
37
+
38
+ # Validate after setting all attributes
39
+ self._validate()
40
+
41
+ @classmethod
42
+ def _is_sentinel(cls, value: Any) -> bool:
43
+ """Check if a value is a sentinel (Undefined or Unset)."""
44
+ if value is None and cls._none_as_sentinel:
45
+ return True
46
+ return is_sentinel(value)
47
+
29
48
  @classmethod
30
49
  def allowed(cls) -> set[str]:
31
50
  """Return the keys of the parameters."""
@@ -36,35 +55,6 @@ class _SentinelAware:
36
55
  }
37
56
  return cls._allowed_keys
38
57
 
39
- @classmethod
40
- def _is_sentinel(cls, value: Any) -> bool:
41
- """Check if a value is a sentinel (Undefined or Unset)."""
42
- if value is None and cls._none_as_sentinel:
43
- return True
44
- return is_sentinel(value)
45
-
46
- def __post_init__(self):
47
- """Post-initialization to ensure all fields are set."""
48
- self._validate()
49
-
50
- def _validate(self) -> None:
51
- pass
52
-
53
- def to_dict(self) -> dict[str, str]:
54
- data = {}
55
- for k in self.allowed():
56
- if not self._is_sentinel(v := getattr(self, k)):
57
- data[k] = v
58
- return data
59
-
60
-
61
- @dataclass(slots=True, frozen=True, init=False)
62
- class Params(_SentinelAware):
63
- """Base class for parameters used in various functions."""
64
-
65
- _func: ClassVar[Any] = Unset
66
- _particial_func: ClassVar[Any] = Unset
67
-
68
58
  @override
69
59
  def _validate(self) -> None:
70
60
  def _validate_strict(k):
@@ -79,38 +69,58 @@ class Params(_SentinelAware):
79
69
  for k in self.allowed():
80
70
  _validate_strict(k)
81
71
 
82
- def as_partial(self) -> Any:
83
- # if partial function is already cached, return it
84
- if self._particial_func is not Unset:
85
- return self._particial_func
86
-
87
- # validate is there is a function to apply
88
- if self._func is Unset:
89
- raise ValueError("No function defined for partial application.")
90
- if not callable(self._func):
91
- raise TypeError(
92
- f"Expected a callable, got {type(self._func).__name__}."
93
- )
72
+ def default_kw(self) -> Any:
94
73
 
95
74
  # create a partial function with the current parameters
96
75
  dict_ = self.to_dict()
97
- if not dict_:
98
- self._particial_func = self._func
99
- return self._func
100
76
 
101
77
  # handle kwargs if present, handle both 'kwargs' and 'kw'
102
78
  kw_ = {}
103
79
  kw_.update(dict_.pop("kwargs", {}))
104
80
  kw_.update(dict_.pop("kw", {}))
105
81
  dict_.update(kw_)
106
- self._particial_func = partial(self._func, **dict_)
107
- return self._particial_func
82
+ return dict_
83
+
84
+ def to_dict(self) -> dict[str, str]:
85
+ data = {}
86
+ for k in self.allowed():
87
+ if not self._is_sentinel(v := getattr(self, k, Undefined)):
88
+ data[k] = v
89
+ return data
108
90
 
109
91
 
110
92
  @dataclass(slots=True)
111
- class DataClass(_SentinelAware):
93
+ class DataClass:
112
94
  """A base class for data classes with strict parameter handling."""
113
95
 
96
+ _none_as_sentinel: ClassVar[bool] = False
97
+ """If True, None is treated as a sentinel value."""
98
+
99
+ _strict: ClassVar[bool] = False
100
+ """No sentinels allowed if strict is True."""
101
+
102
+ _prefill_unset: ClassVar[bool] = True
103
+ """If True, unset fields are prefilled with Unset."""
104
+
105
+ _allowed_keys: ClassVar[set[str]] = field(
106
+ default=set(), init=False, repr=False
107
+ )
108
+ """Class variable cache to store allowed keys for parameters."""
109
+
110
+ def __post_init__(self):
111
+ """Post-initialization to ensure all fields are set."""
112
+ self._validate()
113
+
114
+ @classmethod
115
+ def allowed(cls) -> set[str]:
116
+ """Return the keys of the parameters."""
117
+ if cls._allowed_keys:
118
+ return cls._allowed_keys
119
+ cls._allowed_keys = {
120
+ i for i in cls.__dataclass_fields__.keys() if not i.startswith("_")
121
+ }
122
+ return cls._allowed_keys
123
+
114
124
  @override
115
125
  def _validate(self) -> None:
116
126
  def _validate_strict(k):
@@ -124,3 +134,18 @@ class DataClass(_SentinelAware):
124
134
 
125
135
  for k in self.allowed():
126
136
  _validate_strict(k)
137
+
138
+ def to_dict(self) -> dict[str, str]:
139
+ data = {}
140
+ print(self.allowed())
141
+ for k in type(self).allowed():
142
+ if not self._is_sentinel(v := getattr(self, k)):
143
+ data[k] = v
144
+ return data
145
+
146
+ @classmethod
147
+ def _is_sentinel(cls, value: Any) -> bool:
148
+ """Check if a value is a sentinel (Undefined or Unset)."""
149
+ if value is None and cls._none_as_sentinel:
150
+ return True
151
+ return is_sentinel(value)
@@ -24,6 +24,7 @@ from .resource_tracker import (
24
24
  from .task import TaskGroup, create_task_group
25
25
  from .utils import is_coro_func
26
26
 
27
+ ConcurrencyEvent = Event
27
28
  __all__ = (
28
29
  "TaskGroup",
29
30
  "create_task_group",
@@ -48,4 +49,5 @@ __all__ = (
48
49
  "cleanup_check",
49
50
  "get_global_tracker",
50
51
  "is_coro_func",
52
+ "ConcurrencyEvent",
51
53
  )
@@ -12,9 +12,7 @@ using Events for synchronization and CapacityLimiter for concurrency control.
12
12
  import os
13
13
  from typing import Any
14
14
 
15
- from lionagi.ln.concurrency.primitives import CapacityLimiter
16
- from lionagi.ln.concurrency.primitives import Event as ConcurrencyEvent
17
- from lionagi.ln.concurrency.task import create_task_group
15
+ from lionagi.ln import AlcallParams, CapacityLimiter, ConcurrencyEvent
18
16
  from lionagi.operations.node import Operation
19
17
  from lionagi.protocols.types import EventStatus, Graph
20
18
  from lionagi.session.branch import Branch
@@ -36,6 +34,7 @@ class DependencyAwareExecutor:
36
34
  max_concurrent: int = 5,
37
35
  verbose: bool = False,
38
36
  default_branch: Branch | None = None,
37
+ alcall_params: AlcallParams | None = None,
39
38
  ):
40
39
  """Initialize the executor.
41
40
 
@@ -52,6 +51,7 @@ class DependencyAwareExecutor:
52
51
  self.context = context or {}
53
52
  self.max_concurrent = max_concurrent
54
53
  self.verbose = verbose
54
+ self._alcall = alcall_params or AlcallParams()
55
55
  self._default_branch = default_branch
56
56
 
57
57
  # Track results and completion
@@ -92,11 +92,12 @@ class DependencyAwareExecutor:
92
92
  )
93
93
  limiter = CapacityLimiter(capacity)
94
94
 
95
- # Execute all operations using structured concurrency
96
- async with create_task_group() as tg:
97
- for node in self.graph.internal_nodes.values():
98
- if isinstance(node, Operation):
99
- await tg.start_soon(self._execute_operation, node, limiter)
95
+ nodes = [
96
+ n
97
+ for n in self.graph.internal_nodes.values()
98
+ if isinstance(n, Operation)
99
+ ]
100
+ await self._alcall(nodes, self._execute_operation, limiter=limiter)
100
101
 
101
102
  # Return results - only include actually completed operations
102
103
  completed_ops = [
@@ -507,6 +508,7 @@ async def flow(
507
508
  parallel: bool = True,
508
509
  max_concurrent: int = None,
509
510
  verbose: bool = False,
511
+ alcall_params: AlcallParams | None = None,
510
512
  ) -> dict[str, Any]:
511
513
  """Execute a graph using structured concurrency primitives.
512
514
 
@@ -521,6 +523,7 @@ async def flow(
521
523
  parallel: Whether to execute independent operations in parallel
522
524
  max_concurrent: Max concurrent operations (1 if not parallel)
523
525
  verbose: Enable verbose logging
526
+ alcall_params: Parameters for async parallel call execution
524
527
 
525
528
  Returns:
526
529
  Execution results with completed operations and final context
@@ -528,8 +531,7 @@ async def flow(
528
531
 
529
532
  # Handle concurrency limits
530
533
  if not parallel:
531
- max_concurrent = 1 # Force sequential execution
532
- # If max_concurrent is None, it means no limit
534
+ max_concurrent = 1
533
535
 
534
536
  # Execute using the dependency-aware executor
535
537
  executor = DependencyAwareExecutor(
@@ -539,6 +541,7 @@ async def flow(
539
541
  max_concurrent=max_concurrent,
540
542
  verbose=verbose,
541
543
  default_branch=branch,
544
+ alcall_params=alcall_params,
542
545
  )
543
546
 
544
547
  return await executor.execute()
@@ -5,8 +5,7 @@
5
5
  import asyncio
6
6
  from typing import Any, ClassVar
7
7
 
8
- from lionagi.libs.concurrency import Event as ConcurrencyEvent
9
- from lionagi.libs.concurrency import Semaphore, create_task_group
8
+ from lionagi.ln import ConcurrencyEvent, Semaphore, create_task_group
10
9
 
11
10
  from .._concepts import Observer
12
11
  from .element import ID
@@ -387,6 +387,7 @@ class Session(Node, Communicatable, Relational):
387
387
  max_concurrent: int = 5,
388
388
  verbose: bool = False,
389
389
  default_branch: Branch | ID.Ref | None = None,
390
+ alcall_params: Any = None,
390
391
  ) -> dict[str, Any]:
391
392
  """
392
393
  Execute a graph-based workflow using multi-branch orchestration.
@@ -401,7 +402,7 @@ class Session(Node, Communicatable, Relational):
401
402
  max_concurrent: Maximum concurrent operations (branches)
402
403
  verbose: Enable verbose logging
403
404
  default_branch: Branch to use as default (defaults to self.default_branch)
404
- **kwargs: Additional arguments passed to operations
405
+ alcall_params: Parameters for async parallel call execution
405
406
 
406
407
  Returns:
407
408
  Execution results with completed operations and final context
@@ -421,6 +422,7 @@ class Session(Node, Communicatable, Relational):
421
422
  parallel=parallel,
422
423
  max_concurrent=max_concurrent,
423
424
  verbose=verbose,
425
+ alcall_params=alcall_params,
424
426
  )
425
427
 
426
428
 
lionagi/version.py CHANGED
@@ -1 +1 @@
1
- __version__ = "0.15.5"
1
+ __version__ = "0.15.7"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lionagi
3
- Version: 0.15.5
3
+ Version: 0.15.7
4
4
  Summary: An Intelligence Operating System.
5
5
  Author-email: HaiyangLi <quantocean.li@gmail.com>
6
6
  License: Apache License
@@ -220,7 +220,6 @@ Classifier: Programming Language :: Python :: 3.12
220
220
  Classifier: Programming Language :: Python :: 3.13
221
221
  Requires-Python: >=3.10
222
222
  Requires-Dist: aiocache>=0.12.0
223
- Requires-Dist: aiofiles>=24.1.0
224
223
  Requires-Dist: aiohttp>=3.11.0
225
224
  Requires-Dist: anyio>=4.7.0
226
225
  Requires-Dist: backoff>=2.2.1
@@ -6,7 +6,7 @@ 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=LxsMXyXbj5DC64y7QTmg8XzjE6hogxaed5FHw2PyK_M,39811
9
- lionagi/version.py,sha256=axkldpLAi2TFk3heerDJg_kSegHyvqyTI3ogd991rpE,23
9
+ lionagi/version.py,sha256=MAPfkctPEvU6tygJmfGoOx7ZrEBKkfDrKqpCja4D-yM,23
10
10
  lionagi/adapters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
11
  lionagi/adapters/_utils.py,sha256=n4DS27CZfC-0O_UFaYtlUdjiMx9IeYsGpP7MVaFO5ZA,885
12
12
  lionagi/adapters/async_postgres_adapter.py,sha256=QKzEnzGR5_HNxxmnHhyuPELHv6yvQ-p7cfaX1bWRAQU,12722
@@ -86,13 +86,13 @@ lionagi/libs/validate/to_num.py,sha256=ZRHDjpTCykPfDIZZa4rZKNaR_8ZHbPDFlw9rc02Dr
86
86
  lionagi/libs/validate/validate_boolean.py,sha256=bjiX_WZ3Bg8XcqoWLzE1G9BpO0AisrlZUxrpye_mlGk,3614
87
87
  lionagi/libs/validate/xml_parser.py,sha256=PHBYAre4hhthPpDP9Yrp3UYSWdANPx60F1qhxe0m4uw,7004
88
88
  lionagi/ln/__init__.py,sha256=N2wBLrZWUTfLAXFU2b0VbbByAmbW5Xwl42eIu0RaYWg,906
89
- lionagi/ln/_async_call.py,sha256=O4eY4UehsaamueWVCl6asfs8QAx3FXeVWTB4Nbwnpqk,9291
89
+ lionagi/ln/_async_call.py,sha256=N8vpXPDyonVqfszVEgOTQS8M1MohYJH9vcf1xwuo4JU,9367
90
90
  lionagi/ln/_hash.py,sha256=g20yJfuVhAsfsBOWlkO889DHte6cbUCl6vV5QMT8nUo,3499
91
91
  lionagi/ln/_list_call.py,sha256=oDCyTzz7F7KVAMjekKftJp7qgIZ9Yo8BUNMHasKoJhU,3935
92
- lionagi/ln/_models.py,sha256=23RD2PPMfGNN0JqeHy0s1haRF2H3iF8Vb-_xz9Idvmc,3985
92
+ lionagi/ln/_models.py,sha256=GU34C3HB9iMp-3DsraQnaYRMsUg9NrQi6Pf3RGWqN7M,4787
93
93
  lionagi/ln/_to_list.py,sha256=DKjZAah6pm6frHls773yTMVK1I3OY7qxwLemOjRPr5A,5600
94
94
  lionagi/ln/_types.py,sha256=usVaL2tGnYVQ2W12eUhJYiXY-m55b_5e0tUOFcuDtkc,3607
95
- lionagi/ln/concurrency/__init__.py,sha256=cW3Hw5DvV6AVUdC7N6QI0iTF2cIJMjH8Hp5jCBggBbU,1237
95
+ lionagi/ln/concurrency/__init__.py,sha256=Sv1LEvwN1hRESLtuYM5UltyJqx6DRsHvGmr8aof16cA,1286
96
96
  lionagi/ln/concurrency/cancel.py,sha256=TYLxQ1D7mqhs8J4qJ_yTqP0j01zBe-Qed8-YnJlgKi0,4018
97
97
  lionagi/ln/concurrency/errors.py,sha256=FhLgXGFSbKZYPNfXjdnkV-0ShPF_S34RBLyTO_Pk5C8,938
98
98
  lionagi/ln/concurrency/patterns.py,sha256=dlC7nhIYE-D5VySNAPsd6PYYlORRAqNX50oKJRR1PO8,7796
@@ -110,7 +110,7 @@ lionagi/models/operable_model.py,sha256=Zm_Hxdauqyh0za3_TJLCZ3g6nR4F45Rrnc0ZM3d5
110
110
  lionagi/models/schema_model.py,sha256=ghRIM8aBNaToAknwNlhQKpuKXcwzyCw5pDE31bVKxs0,667
111
111
  lionagi/operations/__init__.py,sha256=L22n8rRls9oVdzHoDlznHFGiKJMNw3ZhbwVQbm1Fn6M,584
112
112
  lionagi/operations/builder.py,sha256=TDUaNoMbFyK2yIVSlcVh1IREUfewsfNnKSle6__oq4M,22918
113
- lionagi/operations/flow.py,sha256=fktzGdhRx7XLrFPM2fe9mIpKBog_qeUzf4wHuLEswEo,22228
113
+ lionagi/operations/flow.py,sha256=JB0SnVZbqLJc9cRGHy_p7QKvTBcB63H9n1iDyhWJDRo,22202
114
114
  lionagi/operations/manager.py,sha256=YZr3VjPAZVVFd_bIjF1aoQqzzKZHNA1kcqefNi5QFFM,683
115
115
  lionagi/operations/node.py,sha256=qmjhv-8UzQMO5ocBlNWuv9nqQiLh5CV7AW_tno8jIUM,3183
116
116
  lionagi/operations/types.py,sha256=fM8HphnbBifMzhoKKvdl3JxGCBHlEGPJEYkLWj9b7vE,704
@@ -160,7 +160,7 @@ lionagi/protocols/generic/element.py,sha256=Eaij2YpTWsGk28Tqjazmjmc_tOnalH7_iGFZ
160
160
  lionagi/protocols/generic/event.py,sha256=cAkj6hiStPPJNlaYpmIXEgnix3LVAYYyDDjoubuT0ks,6602
161
161
  lionagi/protocols/generic/log.py,sha256=Y06zAQewkNlaIWjut_c6c45KY_LJfLHwzUaDGLULaas,8212
162
162
  lionagi/protocols/generic/pile.py,sha256=vTBxA40mhhDhoifQm1qQkVF-VuPACVhOt90a4wRHZYk,35461
163
- lionagi/protocols/generic/processor.py,sha256=c_a7HB9WAaCY-HoI19YyStef8WOXcDj9UeiQb5bz_TM,11759
163
+ lionagi/protocols/generic/processor.py,sha256=GvHblXvOaZJ485L3bWcV3S4w9x0GYxWH-LkPXv00zMI,11700
164
164
  lionagi/protocols/generic/progression.py,sha256=qlITq1qzV119iR5qR__fBAzV489S7d4t20E8uDRicEw,15189
165
165
  lionagi/protocols/graph/__init__.py,sha256=UPu3OmUpjSgX2aBuBJUdG2fppGlfqAH96hU0qIMBMp0,253
166
166
  lionagi/protocols/graph/edge.py,sha256=YxSGj4w_fG7khm-zpKduuK5fJzhJDx23JhU1dZp29d8,5241
@@ -228,14 +228,14 @@ lionagi/service/third_party/pplx_models.py,sha256=-EhyJgOWR6rzSv3zczUtk80X6c19p1
228
228
  lionagi/session/__init__.py,sha256=kDypY6L3kGPnatAw7YNQAykgg-9MlIBnlhHExaXvt-c,202
229
229
  lionagi/session/branch.py,sha256=79l014dCsyOdI4daBLOzyTTLnfYv89Bg7uf9qcg_Bwg,68449
230
230
  lionagi/session/prompts.py,sha256=GPr0jibyAAqS3awDzGC8SoCL6aWJLLCCbXY0JUuxOC0,3170
231
- lionagi/session/session.py,sha256=FzsUsqEQ6cnGd57E4HmEucftz5nMKsfj9kemRDqsXwU,13257
231
+ lionagi/session/session.py,sha256=zwsBL9gB3iSbCxMvx3c0frg0PU-Dgg6QLZMn2_b9YiQ,13341
232
232
  lionagi/tools/__init__.py,sha256=5y5joOZzfFWERl75auAcNcKC3lImVJ5ZZGvvHZUFCJM,112
233
233
  lionagi/tools/base.py,sha256=hEGnE4MD0CM4UqnF0xsDRKB0aM-pyrTFHl8utHhyJLU,1897
234
234
  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=jnSHVSQ66AHZXQrgRuGmlbwKT5JHYoo-1zv1hKgTEfc,9544
237
237
  lionagi/tools/memory/tools.py,sha256=earYkKxSOz_iXkqVZYTEDfE3dwZYIWPXZrqQ1DYGz4I,15941
238
- lionagi-0.15.5.dist-info/METADATA,sha256=nj6TquGq_LpwcN7NE9pMzLAraegXI4rkN5MEQViLofc,22927
239
- lionagi-0.15.5.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
240
- lionagi-0.15.5.dist-info/licenses/LICENSE,sha256=VXFWsdoN5AAknBCgFqQNgPWYx7OPp-PFEP961zGdOjc,11288
241
- lionagi-0.15.5.dist-info/RECORD,,
238
+ lionagi-0.15.7.dist-info/METADATA,sha256=gfYkQElSVIU3smdlJiBJjp1pRby8Gc1LTORtxxacg9M,22895
239
+ lionagi-0.15.7.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
240
+ lionagi-0.15.7.dist-info/licenses/LICENSE,sha256=VXFWsdoN5AAknBCgFqQNgPWYx7OPp-PFEP961zGdOjc,11288
241
+ lionagi-0.15.7.dist-info/RECORD,,