lionagi 0.3.6__py3-none-any.whl → 0.3.8__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/core/collections/abc/component.py +26 -29
- lionagi/core/collections/abc/concepts.py +0 -6
- lionagi/core/collections/flow.py +0 -1
- lionagi/core/collections/model.py +3 -2
- lionagi/core/collections/pile.py +1 -1
- lionagi/core/collections/progression.py +4 -5
- lionagi/core/director/operations/select.py +2 -92
- lionagi/core/generic/registry/component_registry/__init__.py +0 -0
- lionagi/core/rule/choice.py +2 -2
- lionagi/core/unit/unit_mixin.py +3 -3
- lionagi/integrations/langchain_/__init__.py +0 -0
- lionagi/integrations/llamaindex_/__init__.py +0 -0
- lionagi/libs/sys_util.py +196 -32
- lionagi/lions/director/__init__.py +0 -0
- lionagi/operations/__init__.py +6 -0
- lionagi/operations/brainstorm.py +87 -0
- lionagi/operations/config.py +6 -0
- lionagi/operations/rank.py +102 -0
- lionagi/operations/score.py +144 -0
- lionagi/operations/select.py +141 -0
- lionagi/version.py +1 -1
- lionagi-0.3.8.dist-info/METADATA +241 -0
- {lionagi-0.3.6.dist-info → lionagi-0.3.8.dist-info}/RECORD +25 -21
- lionagi/core/director/models/__init__.py +0 -13
- lionagi/core/director/models/action_model.py +0 -61
- lionagi/core/director/models/brainstorm_model.py +0 -42
- lionagi/core/director/models/plan_model.py +0 -51
- lionagi/core/director/models/reason_model.py +0 -63
- lionagi/core/director/models/step_model.py +0 -65
- lionagi-0.3.6.dist-info/METADATA +0 -69
- {lionagi-0.3.6.dist-info → lionagi-0.3.8.dist-info}/LICENSE +0 -0
- {lionagi-0.3.6.dist-info → lionagi-0.3.8.dist-info}/WHEEL +0 -0
@@ -1,11 +1,11 @@
|
|
1
1
|
"""Component class, base building block in LionAGI."""
|
2
2
|
|
3
3
|
import contextlib
|
4
|
-
from abc import ABC
|
5
|
-
from collections.abc import Sequence
|
6
4
|
from functools import singledispatchmethod
|
7
|
-
from typing import Any,
|
5
|
+
from typing import Any, TypeAlias, TypeVar, Union
|
8
6
|
|
7
|
+
import lionfuncs as ln
|
8
|
+
from lionabc import Observable
|
9
9
|
from pandas import DataFrame, Series
|
10
10
|
from pydantic import AliasChoices, BaseModel, Field, ValidationError
|
11
11
|
|
@@ -22,7 +22,13 @@ T = TypeVar("T")
|
|
22
22
|
_init_class = {}
|
23
23
|
|
24
24
|
|
25
|
-
|
25
|
+
def change_dict_key(dict_: dict, old_key: str, new_key: str) -> None:
|
26
|
+
"""Change a key in a dictionary."""
|
27
|
+
if old_key in dict_:
|
28
|
+
dict_[new_key] = dict_.pop(old_key)
|
29
|
+
|
30
|
+
|
31
|
+
class Element(BaseModel, Observable):
|
26
32
|
"""Base class for elements within the LionAGI system.
|
27
33
|
|
28
34
|
Attributes:
|
@@ -31,15 +37,14 @@ class Element(BaseModel, ABC):
|
|
31
37
|
"""
|
32
38
|
|
33
39
|
ln_id: str = Field(
|
34
|
-
default_factory=SysUtil.
|
40
|
+
default_factory=SysUtil.id,
|
35
41
|
title="ID",
|
36
|
-
description="A 32-char unique hash identifier.",
|
37
42
|
frozen=True,
|
38
43
|
validation_alias=AliasChoices("node_id", "ID", "id"),
|
39
44
|
)
|
40
45
|
|
41
46
|
timestamp: str = Field(
|
42
|
-
default_factory=lambda:
|
47
|
+
default_factory=lambda: ln.time(type_="iso"),
|
43
48
|
title="Creation Timestamp",
|
44
49
|
description="The UTC timestamp of creation",
|
45
50
|
frozen=True,
|
@@ -57,7 +62,7 @@ class Element(BaseModel, ABC):
|
|
57
62
|
return True
|
58
63
|
|
59
64
|
|
60
|
-
class Component(Element
|
65
|
+
class Component(Element):
|
61
66
|
"""
|
62
67
|
Represents a distinguishable, temporal entity in LionAGI.
|
63
68
|
|
@@ -195,17 +200,15 @@ class Component(Element, ABC):
|
|
195
200
|
"""Create a Component instance from a LlamaIndex object."""
|
196
201
|
dict_ = obj.to_dict()
|
197
202
|
|
198
|
-
|
203
|
+
change_dict_key(dict_, "text", "content")
|
199
204
|
metadata = dict_.pop("metadata", {})
|
200
205
|
|
201
206
|
for field in llama_meta_fields:
|
202
207
|
metadata[field] = dict_.pop(field, None)
|
203
208
|
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
metadata, "relationships", "llama_index_relationships"
|
208
|
-
)
|
209
|
+
change_dict_key(metadata, "class_name", "llama_index_class")
|
210
|
+
change_dict_key(metadata, "id_", "llama_index_id")
|
211
|
+
change_dict_key(metadata, "relationships", "llama_index_relationships")
|
209
212
|
|
210
213
|
dict_["metadata"] = metadata
|
211
214
|
return cls.from_obj(dict_)
|
@@ -244,7 +247,7 @@ class Component(Element, ABC):
|
|
244
247
|
@classmethod
|
245
248
|
def _process_langchain_dict(cls, dict_: dict) -> dict:
|
246
249
|
"""Process a dictionary containing Langchain-specific data."""
|
247
|
-
|
250
|
+
change_dict_key(dict_, "page_content", "content")
|
248
251
|
|
249
252
|
metadata = dict_.pop("metadata", {})
|
250
253
|
metadata.update(dict_.pop("kwargs", {}))
|
@@ -264,9 +267,9 @@ class Component(Element, ABC):
|
|
264
267
|
if field in dict_:
|
265
268
|
metadata[field] = dict_.pop(field)
|
266
269
|
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
+
change_dict_key(metadata, "lc", "langchain")
|
271
|
+
change_dict_key(metadata, "type", "lc_type")
|
272
|
+
change_dict_key(metadata, "id", "lc_id")
|
270
273
|
|
271
274
|
extra_fields = {
|
272
275
|
k: v for k, v in metadata.items() if k not in lc_meta_fields
|
@@ -298,9 +301,9 @@ class Component(Element, ABC):
|
|
298
301
|
dict_["metadata"] = meta_
|
299
302
|
|
300
303
|
if "ln_id" not in dict_:
|
301
|
-
dict_["ln_id"] = meta_.pop("ln_id", SysUtil.
|
304
|
+
dict_["ln_id"] = meta_.pop("ln_id", SysUtil.id())
|
302
305
|
if "timestamp" not in dict_:
|
303
|
-
dict_["timestamp"] =
|
306
|
+
dict_["timestamp"] = ln.time(type_="iso")
|
304
307
|
if "metadata" not in dict_:
|
305
308
|
dict_["metadata"] = {}
|
306
309
|
if "extra_fields" not in dict_:
|
@@ -453,13 +456,13 @@ class Component(Element, ABC):
|
|
453
456
|
ninsert(
|
454
457
|
self.metadata,
|
455
458
|
["last_updated", name],
|
456
|
-
|
459
|
+
ln.time(type_="iso")[:-6],
|
457
460
|
)
|
458
461
|
elif isinstance(a, tuple) and isinstance(a[0], int):
|
459
462
|
nset(
|
460
463
|
self.metadata,
|
461
464
|
["last_updated", name],
|
462
|
-
|
465
|
+
ln.time(type_="iso")[:-6],
|
463
466
|
)
|
464
467
|
|
465
468
|
def _meta_pop(self, indices, default=...):
|
@@ -614,10 +617,4 @@ LionIDable: TypeAlias = Union[str, Element]
|
|
614
617
|
|
615
618
|
def get_lion_id(item: LionIDable) -> str:
|
616
619
|
"""Get the Lion ID of an item."""
|
617
|
-
|
618
|
-
item = item[0]
|
619
|
-
if isinstance(item, str) and len(item) == 32:
|
620
|
-
return item
|
621
|
-
if getattr(item, "ln_id", None) is not None:
|
622
|
-
return item.ln_id
|
623
|
-
raise LionTypeError("Item must be a single LionIDable object.")
|
620
|
+
return SysUtil.get_id(item)
|
@@ -227,12 +227,6 @@ class Sendable(BaseModel, ABC):
|
|
227
227
|
return value
|
228
228
|
|
229
229
|
a = get_lion_id(value)
|
230
|
-
if not isinstance(a, str) or len(a) != 32:
|
231
|
-
raise LionTypeError(
|
232
|
-
"Invalid sender or recipient value. "
|
233
|
-
"Expected a valid node id or one of "
|
234
|
-
"'system' or 'user'."
|
235
|
-
)
|
236
230
|
return a
|
237
231
|
|
238
232
|
|
lionagi/core/collections/flow.py
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
import asyncio
|
2
2
|
import os
|
3
3
|
|
4
|
+
import lionfuncs as ln
|
4
5
|
import numpy as np
|
5
6
|
from dotenv import load_dotenv
|
6
7
|
|
@@ -91,8 +92,8 @@ class iModel:
|
|
91
92
|
service (BaseService, optional): An instance of BaseService.
|
92
93
|
**kwargs: Additional parameters for the model.
|
93
94
|
"""
|
94
|
-
self.ln_id: str = SysUtil.
|
95
|
-
self.timestamp: str =
|
95
|
+
self.ln_id: str = SysUtil.id()
|
96
|
+
self.timestamp: str = ln.time(type_="iso")
|
96
97
|
self.endpoint = endpoint
|
97
98
|
self.allowed_parameters = allowed_parameters
|
98
99
|
if isinstance(provider, type):
|
lionagi/core/collections/pile.py
CHANGED
@@ -3,7 +3,7 @@ from __future__ import annotations
|
|
3
3
|
import asyncio
|
4
4
|
from collections.abc import AsyncIterator, Callable, Iterable
|
5
5
|
from functools import wraps
|
6
|
-
from typing import Any, Generic,
|
6
|
+
from typing import Any, Generic, TypeVar
|
7
7
|
|
8
8
|
from pydantic import Field, field_validator
|
9
9
|
|
@@ -1,9 +1,8 @@
|
|
1
1
|
import contextlib
|
2
2
|
|
3
|
+
import lionfuncs as ln
|
3
4
|
from pydantic import Field, field_validator
|
4
5
|
|
5
|
-
from lionagi.libs import SysUtil
|
6
|
-
|
7
6
|
from .abc import Element, ItemNotFoundError, LionIDable, Ordering, get_lion_id
|
8
7
|
from .util import _validate_order
|
9
8
|
|
@@ -90,7 +89,7 @@ class Progression(Element, Ordering):
|
|
90
89
|
"""Remove the next occurrence of an item from the progression."""
|
91
90
|
if item in self:
|
92
91
|
item = self._validate_order(item)
|
93
|
-
l_ =
|
92
|
+
l_ = ln.copy(self.order)
|
94
93
|
|
95
94
|
with contextlib.suppress(Exception):
|
96
95
|
for i in item:
|
@@ -143,7 +142,7 @@ class Progression(Element, Ordering):
|
|
143
142
|
def __radd__(self, other):
|
144
143
|
if not isinstance(other, Progression):
|
145
144
|
_copy = self.copy()
|
146
|
-
l_ =
|
145
|
+
l_ = ln.copy(_copy.order)
|
147
146
|
l_.insert(0, get_lion_id(other))
|
148
147
|
_copy.order = l_
|
149
148
|
return _copy
|
@@ -190,7 +189,7 @@ class Progression(Element, Ordering):
|
|
190
189
|
|
191
190
|
def __list__(self):
|
192
191
|
"""Return a list representation of the progression."""
|
193
|
-
return
|
192
|
+
return ln.copy(self.order)
|
194
193
|
|
195
194
|
def __reversed__(self):
|
196
195
|
"""Return a reversed progression."""
|
@@ -1,93 +1,3 @@
|
|
1
|
-
from
|
1
|
+
from lionagi.operations.select import select
|
2
2
|
|
3
|
-
|
4
|
-
from enum import Enum
|
5
|
-
|
6
|
-
from lionfuncs import choose_most_similar
|
7
|
-
from pydantic import BaseModel
|
8
|
-
|
9
|
-
from lionagi.core.director.models import ReasonModel
|
10
|
-
from lionagi.core.session.branch import Branch
|
11
|
-
|
12
|
-
from .utils import is_enum
|
13
|
-
|
14
|
-
PROMPT = "Please select up to {max_num_selections} items from the following list {choices}. Provide the selection(s), and no comments from you"
|
15
|
-
|
16
|
-
|
17
|
-
class SelectionModel(BaseModel):
|
18
|
-
selected: list[str | Enum]
|
19
|
-
|
20
|
-
|
21
|
-
class ReasonSelectionModel(BaseModel):
|
22
|
-
selected: list[str | Enum]
|
23
|
-
reason: ReasonModel
|
24
|
-
|
25
|
-
|
26
|
-
async def select(
|
27
|
-
choices: list[str] | type[Enum],
|
28
|
-
max_num_selections: int = 1,
|
29
|
-
instruction=None,
|
30
|
-
context=None,
|
31
|
-
system=None,
|
32
|
-
sender=None,
|
33
|
-
recipient=None,
|
34
|
-
reason: bool = False,
|
35
|
-
return_enum: bool = False,
|
36
|
-
enum_parser: Callable = None, # parse the model string response to appropriate type
|
37
|
-
branch: Branch = None,
|
38
|
-
return_pydantic_model=False,
|
39
|
-
**kwargs, # additional chat arguments
|
40
|
-
):
|
41
|
-
selections = []
|
42
|
-
if return_enum and not is_enum(choices):
|
43
|
-
raise ValueError("return_enum can only be True if choices is an Enum")
|
44
|
-
|
45
|
-
if is_enum(choices):
|
46
|
-
selections = [selection.value for selection in choices]
|
47
|
-
else:
|
48
|
-
selections = choices
|
49
|
-
|
50
|
-
prompt = PROMPT.format(
|
51
|
-
max_num_selections=max_num_selections, choices=selections
|
52
|
-
)
|
53
|
-
|
54
|
-
if instruction:
|
55
|
-
prompt = f"{instruction}\n\n{prompt} \n\n "
|
56
|
-
|
57
|
-
branch = branch or Branch()
|
58
|
-
response: SelectionModel | ReasonSelectionModel | str = await branch.chat(
|
59
|
-
instruction=prompt,
|
60
|
-
context=context,
|
61
|
-
system=system,
|
62
|
-
sender=sender,
|
63
|
-
recipient=recipient,
|
64
|
-
pydantic_model=SelectionModel if not reason else ReasonSelectionModel,
|
65
|
-
return_pydantic_model=True,
|
66
|
-
**kwargs,
|
67
|
-
)
|
68
|
-
|
69
|
-
selected = response
|
70
|
-
if isinstance(response, SelectionModel | ReasonSelectionModel):
|
71
|
-
selected = response.selected
|
72
|
-
selected = [selected] if not isinstance(selected, list) else selected
|
73
|
-
corrected_selections = [
|
74
|
-
choose_most_similar(selection, selections) for selection in selected
|
75
|
-
]
|
76
|
-
|
77
|
-
if return_enum:
|
78
|
-
out = []
|
79
|
-
if not enum_parser:
|
80
|
-
enum_parser = lambda x: x
|
81
|
-
for selection in corrected_selections:
|
82
|
-
selection = enum_parser(selection)
|
83
|
-
for member in choices.__members__.values():
|
84
|
-
if member.value == selection:
|
85
|
-
out.append(member)
|
86
|
-
corrected_selections = out
|
87
|
-
|
88
|
-
if return_pydantic_model:
|
89
|
-
if not isinstance(response, SelectionModel | ReasonSelectionModel):
|
90
|
-
return SelectionModel(selected=corrected_selections)
|
91
|
-
response.selected = corrected_selections
|
92
|
-
return response
|
93
|
-
return corrected_selections
|
3
|
+
__all__ = ["select"]
|
File without changes
|
lionagi/core/rule/choice.py
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
from lionfuncs import
|
1
|
+
from lionfuncs import string_similarity
|
2
2
|
|
3
3
|
from lionagi.core.rule.base import Rule
|
4
4
|
|
@@ -45,4 +45,4 @@ class ChoiceRule(Rule):
|
|
45
45
|
Returns:
|
46
46
|
str: The most similar value from the set of predefined choices.
|
47
47
|
"""
|
48
|
-
return
|
48
|
+
return string_similarity(value, self.keys, choose_most_similar=True)
|
lionagi/core/unit/unit_mixin.py
CHANGED
@@ -2,9 +2,9 @@ import asyncio
|
|
2
2
|
import contextlib
|
3
3
|
import re
|
4
4
|
from abc import ABC
|
5
|
-
from typing import Any
|
5
|
+
from typing import Any
|
6
6
|
|
7
|
-
from lionfuncs import
|
7
|
+
from lionfuncs import extract_block, to_dict, validate_mapping
|
8
8
|
|
9
9
|
from lionagi.core.collections.abc import ActionError
|
10
10
|
from lionagi.core.message import ActionRequest, ActionResponse, Instruction
|
@@ -1156,7 +1156,7 @@ class DirectiveMixin(ABC):
|
|
1156
1156
|
return to_dict(out_, fuzzy_parse=True)
|
1157
1157
|
|
1158
1158
|
with contextlib.suppress(Exception):
|
1159
|
-
return
|
1159
|
+
return extract_block(out_)
|
1160
1160
|
|
1161
1161
|
with contextlib.suppress(Exception):
|
1162
1162
|
match = re.search(r"```json\n({.*?})\n```", out_, re.DOTALL)
|
File without changes
|
File without changes
|