lionagi 0.1.2__py3-none-any.whl → 0.2.1__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/__init__.py +60 -5
- lionagi/core/__init__.py +0 -25
- lionagi/core/_setting/_setting.py +59 -0
- lionagi/core/action/__init__.py +14 -0
- lionagi/core/action/function_calling.py +136 -0
- lionagi/core/action/manual.py +1 -0
- lionagi/core/action/node.py +109 -0
- lionagi/core/action/tool.py +114 -0
- lionagi/core/action/tool_manager.py +356 -0
- lionagi/core/agent/base_agent.py +27 -13
- lionagi/core/agent/eval/evaluator.py +1 -0
- lionagi/core/agent/eval/vote.py +40 -0
- lionagi/core/agent/learn/learner.py +59 -0
- lionagi/core/agent/plan/unit_template.py +1 -0
- lionagi/core/collections/__init__.py +17 -0
- lionagi/core/{generic/data_logger.py → collections/_logger.py} +69 -55
- lionagi/core/collections/abc/__init__.py +53 -0
- lionagi/core/collections/abc/component.py +615 -0
- lionagi/core/collections/abc/concepts.py +297 -0
- lionagi/core/collections/abc/exceptions.py +150 -0
- lionagi/core/collections/abc/util.py +45 -0
- lionagi/core/collections/exchange.py +161 -0
- lionagi/core/collections/flow.py +426 -0
- lionagi/core/collections/model.py +419 -0
- lionagi/core/collections/pile.py +913 -0
- lionagi/core/collections/progression.py +236 -0
- lionagi/core/collections/util.py +64 -0
- lionagi/core/director/direct.py +314 -0
- lionagi/core/director/director.py +2 -0
- lionagi/core/{execute/branch_executor.py → engine/branch_engine.py} +134 -97
- lionagi/core/{execute/instruction_map_executor.py → engine/instruction_map_engine.py} +80 -55
- lionagi/{experimental/directive/evaluator → core/engine}/script_engine.py +17 -1
- lionagi/core/executor/base_executor.py +90 -0
- lionagi/core/{execute/structure_executor.py → executor/graph_executor.py} +62 -66
- lionagi/core/{execute → executor}/neo4j_executor.py +70 -67
- lionagi/core/generic/__init__.py +3 -33
- lionagi/core/generic/edge.py +29 -79
- lionagi/core/generic/edge_condition.py +16 -0
- lionagi/core/generic/graph.py +236 -0
- lionagi/core/generic/hyperedge.py +1 -0
- lionagi/core/generic/node.py +156 -221
- lionagi/core/generic/tree.py +48 -0
- lionagi/core/generic/tree_node.py +79 -0
- lionagi/core/mail/__init__.py +12 -0
- lionagi/core/mail/mail.py +25 -0
- lionagi/core/mail/mail_manager.py +139 -58
- lionagi/core/mail/package.py +45 -0
- lionagi/core/mail/start_mail.py +36 -0
- lionagi/core/message/__init__.py +19 -0
- lionagi/core/message/action_request.py +133 -0
- lionagi/core/message/action_response.py +135 -0
- lionagi/core/message/assistant_response.py +95 -0
- lionagi/core/message/instruction.py +234 -0
- lionagi/core/message/message.py +101 -0
- lionagi/core/message/system.py +86 -0
- lionagi/core/message/util.py +283 -0
- lionagi/core/report/__init__.py +4 -0
- lionagi/core/report/base.py +217 -0
- lionagi/core/report/form.py +231 -0
- lionagi/core/report/report.py +166 -0
- lionagi/core/report/util.py +28 -0
- lionagi/core/rule/_default.py +16 -0
- lionagi/core/rule/action.py +99 -0
- lionagi/core/rule/base.py +238 -0
- lionagi/core/rule/boolean.py +56 -0
- lionagi/core/rule/choice.py +47 -0
- lionagi/core/rule/mapping.py +96 -0
- lionagi/core/rule/number.py +71 -0
- lionagi/core/rule/rulebook.py +109 -0
- lionagi/core/rule/string.py +52 -0
- lionagi/core/rule/util.py +35 -0
- lionagi/core/session/branch.py +431 -0
- lionagi/core/session/directive_mixin.py +287 -0
- lionagi/core/session/session.py +229 -903
- lionagi/core/structure/__init__.py +1 -0
- lionagi/core/structure/chain.py +1 -0
- lionagi/core/structure/forest.py +1 -0
- lionagi/core/structure/graph.py +1 -0
- lionagi/core/structure/tree.py +1 -0
- lionagi/core/unit/__init__.py +5 -0
- lionagi/core/unit/parallel_unit.py +245 -0
- lionagi/core/unit/template/action.py +81 -0
- lionagi/core/unit/template/base.py +51 -0
- lionagi/core/unit/template/plan.py +84 -0
- lionagi/core/unit/template/predict.py +109 -0
- lionagi/core/unit/template/score.py +124 -0
- lionagi/core/unit/template/select.py +104 -0
- lionagi/core/unit/unit.py +362 -0
- lionagi/core/unit/unit_form.py +305 -0
- lionagi/core/unit/unit_mixin.py +1168 -0
- lionagi/core/unit/util.py +71 -0
- lionagi/core/validator/validator.py +364 -0
- lionagi/core/work/work.py +76 -0
- lionagi/core/work/work_function.py +101 -0
- lionagi/core/work/work_queue.py +103 -0
- lionagi/core/work/worker.py +258 -0
- lionagi/core/work/worklog.py +120 -0
- lionagi/experimental/compressor/base.py +46 -0
- lionagi/experimental/compressor/llm_compressor.py +247 -0
- lionagi/experimental/compressor/llm_summarizer.py +61 -0
- lionagi/experimental/compressor/util.py +70 -0
- lionagi/experimental/directive/__init__.py +19 -0
- lionagi/experimental/directive/parser/base_parser.py +69 -2
- lionagi/experimental/directive/{template_ → template}/base_template.py +17 -1
- lionagi/{libs/ln_tokenizer.py → experimental/directive/tokenizer.py} +16 -0
- lionagi/experimental/{directive/evaluator → evaluator}/ast_evaluator.py +16 -0
- lionagi/experimental/{directive/evaluator → evaluator}/base_evaluator.py +16 -0
- lionagi/experimental/knowledge/base.py +10 -0
- lionagi/experimental/memory/__init__.py +0 -0
- lionagi/experimental/strategies/__init__.py +0 -0
- lionagi/experimental/strategies/base.py +1 -0
- lionagi/integrations/bridge/langchain_/documents.py +4 -0
- lionagi/integrations/bridge/llamaindex_/index.py +30 -0
- lionagi/integrations/bridge/llamaindex_/llama_index_bridge.py +6 -0
- lionagi/integrations/chunker/chunk.py +161 -24
- lionagi/integrations/config/oai_configs.py +34 -3
- lionagi/integrations/config/openrouter_configs.py +14 -2
- lionagi/integrations/loader/load.py +122 -21
- lionagi/integrations/loader/load_util.py +6 -77
- lionagi/integrations/provider/_mapping.py +46 -0
- lionagi/integrations/provider/litellm.py +2 -1
- lionagi/integrations/provider/mlx_service.py +16 -9
- lionagi/integrations/provider/oai.py +91 -4
- lionagi/integrations/provider/ollama.py +6 -5
- lionagi/integrations/provider/openrouter.py +115 -8
- lionagi/integrations/provider/services.py +2 -2
- lionagi/integrations/provider/transformers.py +18 -22
- lionagi/integrations/storage/__init__.py +3 -3
- lionagi/integrations/storage/neo4j.py +52 -60
- lionagi/integrations/storage/storage_util.py +44 -46
- lionagi/integrations/storage/structure_excel.py +43 -26
- lionagi/integrations/storage/to_excel.py +11 -4
- lionagi/libs/__init__.py +22 -1
- lionagi/libs/ln_api.py +75 -20
- lionagi/libs/ln_context.py +37 -0
- lionagi/libs/ln_convert.py +21 -9
- lionagi/libs/ln_func_call.py +69 -28
- lionagi/libs/ln_image.py +107 -0
- lionagi/libs/ln_nested.py +26 -11
- lionagi/libs/ln_parse.py +82 -23
- lionagi/libs/ln_queue.py +16 -0
- lionagi/libs/ln_tokenize.py +164 -0
- lionagi/libs/ln_validate.py +16 -0
- lionagi/libs/special_tokens.py +172 -0
- lionagi/libs/sys_util.py +95 -24
- lionagi/lions/coder/code_form.py +13 -0
- lionagi/lions/coder/coder.py +50 -3
- lionagi/lions/coder/util.py +30 -25
- lionagi/tests/libs/test_func_call.py +23 -21
- lionagi/tests/libs/test_nested.py +36 -21
- lionagi/tests/libs/test_parse.py +1 -1
- lionagi/tests/test_core/collections/__init__.py +0 -0
- lionagi/tests/test_core/collections/test_component.py +206 -0
- lionagi/tests/test_core/collections/test_exchange.py +138 -0
- lionagi/tests/test_core/collections/test_flow.py +145 -0
- lionagi/tests/test_core/collections/test_pile.py +171 -0
- lionagi/tests/test_core/collections/test_progression.py +129 -0
- lionagi/tests/test_core/generic/test_edge.py +67 -0
- lionagi/tests/test_core/generic/test_graph.py +96 -0
- lionagi/tests/test_core/generic/test_node.py +106 -0
- lionagi/tests/test_core/generic/test_tree_node.py +73 -0
- lionagi/tests/test_core/test_branch.py +115 -294
- lionagi/tests/test_core/test_form.py +46 -0
- lionagi/tests/test_core/test_report.py +105 -0
- lionagi/tests/test_core/test_validator.py +111 -0
- lionagi/version.py +1 -1
- lionagi-0.2.1.dist-info/LICENSE +202 -0
- lionagi-0.2.1.dist-info/METADATA +272 -0
- lionagi-0.2.1.dist-info/RECORD +240 -0
- lionagi/core/branch/base.py +0 -653
- lionagi/core/branch/branch.py +0 -474
- lionagi/core/branch/flow_mixin.py +0 -96
- lionagi/core/branch/util.py +0 -323
- lionagi/core/direct/__init__.py +0 -19
- lionagi/core/direct/cot.py +0 -123
- lionagi/core/direct/plan.py +0 -164
- lionagi/core/direct/predict.py +0 -166
- lionagi/core/direct/react.py +0 -171
- lionagi/core/direct/score.py +0 -279
- lionagi/core/direct/select.py +0 -170
- lionagi/core/direct/sentiment.py +0 -1
- lionagi/core/direct/utils.py +0 -110
- lionagi/core/direct/vote.py +0 -64
- lionagi/core/execute/base_executor.py +0 -47
- lionagi/core/flow/baseflow.py +0 -23
- lionagi/core/flow/monoflow/ReAct.py +0 -240
- lionagi/core/flow/monoflow/__init__.py +0 -9
- lionagi/core/flow/monoflow/chat.py +0 -95
- lionagi/core/flow/monoflow/chat_mixin.py +0 -253
- lionagi/core/flow/monoflow/followup.py +0 -215
- lionagi/core/flow/polyflow/__init__.py +0 -1
- lionagi/core/flow/polyflow/chat.py +0 -251
- lionagi/core/form/action_form.py +0 -26
- lionagi/core/form/field_validator.py +0 -287
- lionagi/core/form/form.py +0 -302
- lionagi/core/form/mixin.py +0 -214
- lionagi/core/form/scored_form.py +0 -13
- lionagi/core/generic/action.py +0 -26
- lionagi/core/generic/component.py +0 -532
- lionagi/core/generic/condition.py +0 -46
- lionagi/core/generic/mail.py +0 -90
- lionagi/core/generic/mailbox.py +0 -36
- lionagi/core/generic/relation.py +0 -70
- lionagi/core/generic/signal.py +0 -22
- lionagi/core/generic/structure.py +0 -362
- lionagi/core/generic/transfer.py +0 -20
- lionagi/core/generic/work.py +0 -40
- lionagi/core/graph/graph.py +0 -126
- lionagi/core/graph/tree.py +0 -190
- lionagi/core/mail/schema.py +0 -63
- lionagi/core/messages/schema.py +0 -325
- lionagi/core/tool/__init__.py +0 -5
- lionagi/core/tool/tool.py +0 -28
- lionagi/core/tool/tool_manager.py +0 -283
- lionagi/experimental/report/form.py +0 -64
- lionagi/experimental/report/report.py +0 -138
- lionagi/experimental/report/util.py +0 -47
- lionagi/experimental/tool/function_calling.py +0 -43
- lionagi/experimental/tool/manual.py +0 -66
- lionagi/experimental/tool/schema.py +0 -59
- lionagi/experimental/tool/tool_manager.py +0 -138
- lionagi/experimental/tool/util.py +0 -16
- lionagi/experimental/validator/rule.py +0 -139
- lionagi/experimental/validator/validator.py +0 -56
- lionagi/experimental/work/__init__.py +0 -10
- lionagi/experimental/work/async_queue.py +0 -54
- lionagi/experimental/work/schema.py +0 -73
- lionagi/experimental/work/work_function.py +0 -67
- lionagi/experimental/work/worker.py +0 -56
- lionagi/experimental/work2/form.py +0 -371
- lionagi/experimental/work2/report.py +0 -289
- lionagi/experimental/work2/schema.py +0 -30
- lionagi/experimental/work2/tests.py +0 -72
- lionagi/experimental/work2/work_function.py +0 -89
- lionagi/experimental/work2/worker.py +0 -12
- lionagi/integrations/bridge/llamaindex_/get_index.py +0 -294
- lionagi/tests/test_core/generic/test_component.py +0 -89
- lionagi/tests/test_core/test_base_branch.py +0 -426
- lionagi/tests/test_core/test_chat_flow.py +0 -63
- lionagi/tests/test_core/test_mail_manager.py +0 -75
- lionagi/tests/test_core/test_prompts.py +0 -51
- lionagi/tests/test_core/test_session.py +0 -254
- lionagi/tests/test_core/test_session_base_util.py +0 -313
- lionagi/tests/test_core/test_tool_manager.py +0 -95
- lionagi-0.1.2.dist-info/LICENSE +0 -9
- lionagi-0.1.2.dist-info/METADATA +0 -174
- lionagi-0.1.2.dist-info/RECORD +0 -206
- /lionagi/core/{branch → _setting}/__init__.py +0 -0
- /lionagi/core/{execute → agent/eval}/__init__.py +0 -0
- /lionagi/core/{flow → agent/learn}/__init__.py +0 -0
- /lionagi/core/{form → agent/plan}/__init__.py +0 -0
- /lionagi/core/{branch/executable_branch.py → agent/plan/plan.py} +0 -0
- /lionagi/core/{graph → director}/__init__.py +0 -0
- /lionagi/core/{messages → engine}/__init__.py +0 -0
- /lionagi/{experimental/directive/evaluator → core/engine}/sandbox_.py +0 -0
- /lionagi/{experimental/directive/evaluator → core/executor}/__init__.py +0 -0
- /lionagi/{experimental/directive/template_ → core/rule}/__init__.py +0 -0
- /lionagi/{experimental/report → core/unit/template}/__init__.py +0 -0
- /lionagi/{experimental/tool → core/validator}/__init__.py +0 -0
- /lionagi/{experimental/validator → core/work}/__init__.py +0 -0
- /lionagi/experimental/{work2 → compressor}/__init__.py +0 -0
- /lionagi/{core/flow/mono_chat_mixin.py → experimental/directive/template/__init__.py} +0 -0
- /lionagi/experimental/directive/{schema.py → template/schema.py} +0 -0
- /lionagi/experimental/{work2/util.py → evaluator/__init__.py} +0 -0
- /lionagi/experimental/{work2/work.py → knowledge/__init__.py} +0 -0
- /lionagi/{tests/libs/test_async.py → experimental/knowledge/graph.py} +0 -0
- {lionagi-0.1.2.dist-info → lionagi-0.2.1.dist-info}/WHEEL +0 -0
- {lionagi-0.1.2.dist-info → lionagi-0.2.1.dist-info}/top_level.txt +0 -0
@@ -1,532 +0,0 @@
|
|
1
|
-
"""base components in lionagi"""
|
2
|
-
|
3
|
-
from abc import ABC
|
4
|
-
from functools import singledispatchmethod
|
5
|
-
from typing import Any, TypeVar, Type
|
6
|
-
from pydantic import AliasChoices, BaseModel, Field, ValidationError
|
7
|
-
from pandas import DataFrame, Series
|
8
|
-
|
9
|
-
from lionagi.libs import SysUtil, convert, ParseUtil, nested, func_call
|
10
|
-
|
11
|
-
|
12
|
-
T = TypeVar("T")
|
13
|
-
|
14
|
-
|
15
|
-
class BaseComponent(BaseModel, ABC):
|
16
|
-
"""
|
17
|
-
Base class for creating component models.
|
18
|
-
|
19
|
-
Attributes:
|
20
|
-
id_ (str): A 32-char unique hash identifier for the node.
|
21
|
-
timestamp (str): The timestamp of when the node was created.
|
22
|
-
"""
|
23
|
-
|
24
|
-
id_: str = Field(
|
25
|
-
title="ID",
|
26
|
-
default_factory=SysUtil.create_id,
|
27
|
-
validation_alias=AliasChoices("node_id", "ID", "id"),
|
28
|
-
description="A 32-char unique hash identifier for the node.",
|
29
|
-
)
|
30
|
-
timestamp: str = Field(
|
31
|
-
default_factory=lambda: SysUtil.get_timestamp(sep=None),
|
32
|
-
description="The timestamp of when the node was created.",
|
33
|
-
)
|
34
|
-
|
35
|
-
extra_fields: dict[str, Any] = Field(
|
36
|
-
default_factory=dict,
|
37
|
-
validation_alias=AliasChoices(
|
38
|
-
"extra", "additional_fields", "schema_extra", "extra_schema"
|
39
|
-
),
|
40
|
-
description="Additional fields for the component.",
|
41
|
-
)
|
42
|
-
|
43
|
-
class Config:
|
44
|
-
"""Model configuration settings."""
|
45
|
-
|
46
|
-
extra = "allow"
|
47
|
-
arbitrary_types_allowed = True
|
48
|
-
populate_by_name = True
|
49
|
-
|
50
|
-
@property
|
51
|
-
def class_name(self) -> str:
|
52
|
-
"""
|
53
|
-
Retrieve the name of the class.
|
54
|
-
|
55
|
-
Returns:
|
56
|
-
str: The name of the class.
|
57
|
-
"""
|
58
|
-
return self._class_name()
|
59
|
-
|
60
|
-
@classmethod
|
61
|
-
def _class_name(cls) -> str:
|
62
|
-
"""
|
63
|
-
Retrieve the name of the class.
|
64
|
-
|
65
|
-
Returns:
|
66
|
-
str: The name of the class.
|
67
|
-
"""
|
68
|
-
return cls.__name__
|
69
|
-
|
70
|
-
def to_json_str(self, *args, **kwargs) -> str:
|
71
|
-
"""
|
72
|
-
Convert the component to a JSON string.
|
73
|
-
|
74
|
-
Returns:
|
75
|
-
str: The JSON string representation of the component.
|
76
|
-
"""
|
77
|
-
dict_ = self.to_dict(*args, **kwargs)
|
78
|
-
return convert.to_str(dict_)
|
79
|
-
|
80
|
-
def to_dict(self, *args, **kwargs) -> dict[str, Any]:
|
81
|
-
"""
|
82
|
-
Convert the component to a dictionary.
|
83
|
-
|
84
|
-
Returns:
|
85
|
-
dict[str, Any]: The dictionary representation of the component.
|
86
|
-
"""
|
87
|
-
dict_ = self.model_dump(*args, by_alias=True, **kwargs)
|
88
|
-
for field_name in list(self.extra_fields.keys()):
|
89
|
-
if field_name not in dict_:
|
90
|
-
dict_[field_name] = getattr(self, field_name, None)
|
91
|
-
dict_.pop("extra_fields", None)
|
92
|
-
return dict_
|
93
|
-
|
94
|
-
def to_xml(self, *args, **kwargs) -> str:
|
95
|
-
"""
|
96
|
-
Convert the component to an XML string.
|
97
|
-
|
98
|
-
Returns:
|
99
|
-
str: The XML string representation of the component.
|
100
|
-
"""
|
101
|
-
import xml.etree.ElementTree as ET
|
102
|
-
|
103
|
-
root = ET.Element(self.__class__.__name__)
|
104
|
-
|
105
|
-
def convert(dict_obj: dict, parent: ET.Element) -> None:
|
106
|
-
for key, val in dict_obj.items():
|
107
|
-
if isinstance(val, dict):
|
108
|
-
element = ET.SubElement(parent, key)
|
109
|
-
convert(val, element)
|
110
|
-
else:
|
111
|
-
element = ET.SubElement(parent, key)
|
112
|
-
element.text = str(val)
|
113
|
-
|
114
|
-
convert(self.to_dict(*args, **kwargs), root)
|
115
|
-
return ET.tostring(root, encoding="unicode")
|
116
|
-
|
117
|
-
def to_pd_series(self, *args, pd_kwargs: dict | None = None, **kwargs) -> Series:
|
118
|
-
"""
|
119
|
-
Convert the node to a Pandas Series.
|
120
|
-
|
121
|
-
Args:
|
122
|
-
pd_kwargs (dict | None): Additional keyword arguments for Pandas Series.
|
123
|
-
|
124
|
-
Returns:
|
125
|
-
Series: The Pandas Series representation of the node.
|
126
|
-
"""
|
127
|
-
pd_kwargs = {} if pd_kwargs is None else pd_kwargs
|
128
|
-
dict_ = self.to_dict(*args, **kwargs)
|
129
|
-
return Series(dict_, **pd_kwargs)
|
130
|
-
|
131
|
-
def _add_field(
|
132
|
-
self,
|
133
|
-
field_name: str,
|
134
|
-
annotation: Any | Type | None = Any,
|
135
|
-
default: Any | None = None,
|
136
|
-
value: Any | None = None,
|
137
|
-
field: Any = None,
|
138
|
-
**kwargs,
|
139
|
-
) -> None:
|
140
|
-
"""
|
141
|
-
Add a field to the model after initialization.
|
142
|
-
|
143
|
-
Args:
|
144
|
-
field_name (str): The name of the field.
|
145
|
-
annotation (Any | Type | None): The type annotation for the field.
|
146
|
-
default (Any | None): The default value for the field.
|
147
|
-
value (Any | None): The initial value for the field.
|
148
|
-
field (Any): The Field object for the field.
|
149
|
-
**kwargs: Additional keyword arguments for the Field object.
|
150
|
-
"""
|
151
|
-
field = field or Field(default=default, **kwargs)
|
152
|
-
self.extra_fields[field_name] = field
|
153
|
-
if annotation:
|
154
|
-
self.extra_fields[field_name].annotation = annotation
|
155
|
-
|
156
|
-
if not value and (a := self._get_field_attr(field_name, "default", None)):
|
157
|
-
value = a
|
158
|
-
|
159
|
-
self.__setattr__(field_name, value)
|
160
|
-
|
161
|
-
@property
|
162
|
-
def _all_fields(self):
|
163
|
-
return {**self.model_fields, **self.extra_fields}
|
164
|
-
|
165
|
-
@property
|
166
|
-
def _field_annotations(self) -> dict:
|
167
|
-
"""
|
168
|
-
Return the annotations for each field in the model.
|
169
|
-
|
170
|
-
Returns:
|
171
|
-
dict: A dictionary mapping field names to their annotations.
|
172
|
-
"""
|
173
|
-
|
174
|
-
return self._get_field_annotation(list(self._all_fields.keys()))
|
175
|
-
|
176
|
-
def _get_field_attr(self, k: str, attr: str, default: Any = False) -> Any:
|
177
|
-
"""
|
178
|
-
Get the value of a field attribute.
|
179
|
-
|
180
|
-
Args:
|
181
|
-
k (str): The field name.
|
182
|
-
attr (str): The attribute name.
|
183
|
-
default (Any): Default value to return if the attribute is not found.
|
184
|
-
|
185
|
-
Returns:
|
186
|
-
Any: The value of the field attribute, or the default value if not found.
|
187
|
-
|
188
|
-
Raises:
|
189
|
-
ValueError: If the field does not have the specified attribute.
|
190
|
-
"""
|
191
|
-
try:
|
192
|
-
if not self._field_has_attr(k, attr):
|
193
|
-
raise ValueError(f"field {k} has no attribute {attr}")
|
194
|
-
|
195
|
-
field = self._all_fields[k]
|
196
|
-
a = getattr(field, attr, None)
|
197
|
-
if not a:
|
198
|
-
try:
|
199
|
-
a = field.json_schema_extra[attr]
|
200
|
-
return a
|
201
|
-
except Exception:
|
202
|
-
return None
|
203
|
-
return a
|
204
|
-
except Exception as e:
|
205
|
-
if default is not False:
|
206
|
-
return default
|
207
|
-
raise e
|
208
|
-
|
209
|
-
@singledispatchmethod
|
210
|
-
def _get_field_annotation(self, field_name: Any) -> Any:
|
211
|
-
"""
|
212
|
-
Get the annotation for a field.
|
213
|
-
|
214
|
-
Args:
|
215
|
-
field_name (str): The name of the field.
|
216
|
-
|
217
|
-
Raises:
|
218
|
-
TypeError: If the field_name is of an unsupported type.
|
219
|
-
"""
|
220
|
-
raise TypeError(f"Unsupported type {type(field_name)}")
|
221
|
-
|
222
|
-
@_get_field_annotation.register(str)
|
223
|
-
def _(self, field_name: str) -> dict[str, Any]:
|
224
|
-
"""
|
225
|
-
Get the annotation for a field as a dictionary.
|
226
|
-
|
227
|
-
Args:
|
228
|
-
field_name (str): The name of the field.
|
229
|
-
|
230
|
-
Returns:
|
231
|
-
dict[str, Any]: A dictionary mapping the field name to its annotation.
|
232
|
-
"""
|
233
|
-
dict_ = {field_name: self._all_fields[field_name].annotation}
|
234
|
-
for k, v in dict_.items():
|
235
|
-
if "|" in str(v):
|
236
|
-
v = str(v)
|
237
|
-
v = v.split("|")
|
238
|
-
dict_[k] = func_call.lcall(v, convert.strip_lower)
|
239
|
-
else:
|
240
|
-
dict_[k] = [v.__name__]
|
241
|
-
return dict_
|
242
|
-
|
243
|
-
@_get_field_annotation.register(list)
|
244
|
-
@_get_field_annotation.register(tuple)
|
245
|
-
def _(self, field_names: list | tuple) -> dict[str, Any]:
|
246
|
-
"""
|
247
|
-
Get the annotations for multiple fields as a dictionary.
|
248
|
-
|
249
|
-
Args:
|
250
|
-
field_names (list | tuple): A list or tuple of field names.
|
251
|
-
|
252
|
-
Returns:
|
253
|
-
dict[str, Any]: A dictionary mapping field names to their annotations.
|
254
|
-
"""
|
255
|
-
dict_ = {}
|
256
|
-
for field_name in field_names:
|
257
|
-
dict_.update(self._get_field_annotation(field_name))
|
258
|
-
return dict_
|
259
|
-
|
260
|
-
def _field_has_attr(self, k: str, attr: str) -> bool:
|
261
|
-
"""
|
262
|
-
Check if a field has a specific attribute.
|
263
|
-
|
264
|
-
Args:
|
265
|
-
k (str): The field name.
|
266
|
-
attr (str): The attribute name.
|
267
|
-
|
268
|
-
Returns:
|
269
|
-
bool: True if the field has the attribute, False otherwise.
|
270
|
-
"""
|
271
|
-
field = self._all_fields.get(k, None)
|
272
|
-
if field is None:
|
273
|
-
raise ValueError(f"Field {k} not found in model fields.")
|
274
|
-
|
275
|
-
a = attr in str(field)
|
276
|
-
if not a:
|
277
|
-
try:
|
278
|
-
a = (
|
279
|
-
self._all_fields[k].json_schema_extra[attr] is not None
|
280
|
-
and attr in self._all_fields[k].json_schema_extra
|
281
|
-
)
|
282
|
-
return a if isinstance(a, bool) else False
|
283
|
-
except Exception:
|
284
|
-
return False
|
285
|
-
return a
|
286
|
-
|
287
|
-
def __str__(self):
|
288
|
-
return f"{self.__class__.__name__}({self.to_json_str()})"
|
289
|
-
|
290
|
-
|
291
|
-
class BaseNode(BaseComponent):
|
292
|
-
"""
|
293
|
-
Base class for creating node models.
|
294
|
-
|
295
|
-
Attributes:
|
296
|
-
content (Any | None): The optional content of the node.
|
297
|
-
metadata (dict[str, Any]): Additional metadata for the node.
|
298
|
-
"""
|
299
|
-
|
300
|
-
content: Any | None = Field(
|
301
|
-
default=None,
|
302
|
-
validation_alias=AliasChoices("text", "page_content", "chunk_content", "data"),
|
303
|
-
description="The optional content of the node.",
|
304
|
-
)
|
305
|
-
|
306
|
-
metadata: dict[str, Any] = Field(
|
307
|
-
default_factory=dict,
|
308
|
-
validation_alias="meta",
|
309
|
-
description="Additional metadata for the node.",
|
310
|
-
)
|
311
|
-
|
312
|
-
@singledispatchmethod
|
313
|
-
@classmethod
|
314
|
-
def from_obj(cls, obj: Any, *args, **kwargs) -> T:
|
315
|
-
"""
|
316
|
-
Create a node instance from an object.
|
317
|
-
|
318
|
-
Args:
|
319
|
-
obj (Any): The object to create the node from.
|
320
|
-
*args: Additional positional arguments.
|
321
|
-
**kwargs: Additional keyword arguments.
|
322
|
-
|
323
|
-
Raises:
|
324
|
-
NotImplementedError: If the object type is not supported.
|
325
|
-
"""
|
326
|
-
if not isinstance(obj, (dict, str, list, Series, DataFrame, BaseModel)):
|
327
|
-
type_ = str(type(obj))
|
328
|
-
if "llama_index" in type_:
|
329
|
-
return cls.from_obj(obj.to_dict())
|
330
|
-
elif "langchain" in type_:
|
331
|
-
langchain_json = obj.to_json()
|
332
|
-
langchain_dict = {
|
333
|
-
"lc_id": langchain_json["id"],
|
334
|
-
**langchain_json["kwargs"],
|
335
|
-
}
|
336
|
-
return cls.from_obj(langchain_dict)
|
337
|
-
|
338
|
-
raise NotImplementedError(f"Unsupported type: {type(obj)}")
|
339
|
-
|
340
|
-
@from_obj.register(dict)
|
341
|
-
@classmethod
|
342
|
-
def _from_dict(cls, obj: dict, *args, **kwargs) -> T:
|
343
|
-
"""
|
344
|
-
Create a node instance from a dictionary.
|
345
|
-
|
346
|
-
Args:
|
347
|
-
obj (dict): The dictionary to create the node from.
|
348
|
-
*args: Additional positional arguments.
|
349
|
-
**kwargs: Additional keyword arguments.
|
350
|
-
|
351
|
-
Returns:
|
352
|
-
T: The created node instance.
|
353
|
-
"""
|
354
|
-
return cls.model_validate(obj, *args, **kwargs)
|
355
|
-
|
356
|
-
@from_obj.register(str)
|
357
|
-
@classmethod
|
358
|
-
def _from_str(cls, obj: str, *args, fuzzy_parse: bool = False, **kwargs) -> T:
|
359
|
-
"""
|
360
|
-
Create a node instance from a JSON string.
|
361
|
-
|
362
|
-
Args:
|
363
|
-
obj (str): The JSON string to create the node from.
|
364
|
-
*args: Additional positional arguments.
|
365
|
-
fuzzy_parse (bool): Whether to perform fuzzy parsing.
|
366
|
-
**kwargs: Additional keyword arguments.
|
367
|
-
|
368
|
-
Returns:
|
369
|
-
T: The created node instance.
|
370
|
-
"""
|
371
|
-
obj = ParseUtil.fuzzy_parse_json(obj) if fuzzy_parse else convert.to_dict(obj)
|
372
|
-
try:
|
373
|
-
return cls.from_obj(obj, *args, **kwargs)
|
374
|
-
except ValidationError as e:
|
375
|
-
raise ValueError(f"Invalid JSON for deserialization: {e}") from e
|
376
|
-
|
377
|
-
@from_obj.register(list)
|
378
|
-
@classmethod
|
379
|
-
def _from_list(cls, obj: list, *args, **kwargs) -> list[T]:
|
380
|
-
"""
|
381
|
-
Create a list of node instances from a list of objects.
|
382
|
-
|
383
|
-
Args:
|
384
|
-
obj (list): The list of objects to create nodes from.
|
385
|
-
*args: Additional positional arguments.
|
386
|
-
**kwargs: Additional keyword arguments.
|
387
|
-
|
388
|
-
Returns:
|
389
|
-
list[T]: The list of created node instances.
|
390
|
-
"""
|
391
|
-
return [cls.from_obj(item, *args, **kwargs) for item in obj]
|
392
|
-
|
393
|
-
@from_obj.register(Series)
|
394
|
-
@classmethod
|
395
|
-
def _from_pd_series(
|
396
|
-
cls, obj: Series, *args, pd_kwargs: dict | None = None, **kwargs
|
397
|
-
) -> T:
|
398
|
-
"""
|
399
|
-
Create a node instance from a Pandas Series.
|
400
|
-
|
401
|
-
Args:
|
402
|
-
obj (Series): The Pandas Series to create the node from.
|
403
|
-
*args: Additional positional arguments.
|
404
|
-
pd_kwargs (dict | None): Additional keyword arguments for Pandas Series.
|
405
|
-
**kwargs: Additional keyword arguments.
|
406
|
-
|
407
|
-
Returns:
|
408
|
-
T: The created node instance.
|
409
|
-
"""
|
410
|
-
pd_kwargs = pd_kwargs or {}
|
411
|
-
return cls.from_obj(obj.to_dict(**pd_kwargs), *args, **kwargs)
|
412
|
-
|
413
|
-
@from_obj.register(DataFrame)
|
414
|
-
@classmethod
|
415
|
-
def _from_pd_dataframe(
|
416
|
-
cls, obj: DataFrame, *args, pd_kwargs: dict | None = None, **kwargs
|
417
|
-
) -> list[T]:
|
418
|
-
"""
|
419
|
-
Create a list of node instances from a Pandas DataFrame.
|
420
|
-
|
421
|
-
Args:
|
422
|
-
obj (DataFrame): The Pandas DataFrame to create nodes from.
|
423
|
-
*args: Additional positional arguments.
|
424
|
-
pd_kwargs (dict | None): Additional keyword arguments for Pandas DataFrame.
|
425
|
-
**kwargs: Additional keyword arguments.
|
426
|
-
|
427
|
-
Returns:
|
428
|
-
list[T]: The list of created node instances.
|
429
|
-
"""
|
430
|
-
if pd_kwargs is None:
|
431
|
-
pd_kwargs = {}
|
432
|
-
|
433
|
-
_objs = []
|
434
|
-
for index, row in obj.iterrows():
|
435
|
-
_obj = cls.from_obj(row, *args, **pd_kwargs, **kwargs)
|
436
|
-
_obj.metadata["df_index"] = index
|
437
|
-
_objs.append(_obj)
|
438
|
-
|
439
|
-
return _objs
|
440
|
-
|
441
|
-
@from_obj.register(BaseModel)
|
442
|
-
@classmethod
|
443
|
-
def _from_base_model(cls, obj, pydantic_kwargs=None, **kwargs) -> T:
|
444
|
-
"""
|
445
|
-
Create a node instance from a Pydantic BaseModel.
|
446
|
-
|
447
|
-
Args:
|
448
|
-
obj (BaseModel): The Pydantic BaseModel to create the node from.
|
449
|
-
|
450
|
-
Returns:
|
451
|
-
T: The created node instance.
|
452
|
-
"""
|
453
|
-
pydantic_kwargs = pydantic_kwargs or {"by_alias": True}
|
454
|
-
try:
|
455
|
-
config_ = {}
|
456
|
-
try:
|
457
|
-
config_ = obj.model_dump(**pydantic_kwargs)
|
458
|
-
except:
|
459
|
-
config_ = obj.to_dict(**pydantic_kwargs)
|
460
|
-
else:
|
461
|
-
config_ = obj.dict(**pydantic_kwargs)
|
462
|
-
except Exception as e:
|
463
|
-
raise ValueError(f"Invalid Pydantic model for deserialization: {e}") from e
|
464
|
-
|
465
|
-
return cls.from_obj(config_ | kwargs)
|
466
|
-
|
467
|
-
def meta_get(
|
468
|
-
self, key: str, indices: list[str | int] | None = None, default: Any = None
|
469
|
-
) -> Any:
|
470
|
-
"""
|
471
|
-
Get a value from the metadata dictionary.
|
472
|
-
|
473
|
-
Args:
|
474
|
-
key (str): The key to retrieve the value for.
|
475
|
-
indices (list[str | int] | None): Optional list of indices for nested retrieval.
|
476
|
-
default (Any): The default value to return if the key is not found.
|
477
|
-
|
478
|
-
Returns:
|
479
|
-
Any: The retrieved value or the default value if not found.
|
480
|
-
"""
|
481
|
-
if indices:
|
482
|
-
return nested.nget(self.metadata, indices, default)
|
483
|
-
return self.metadata.get(key, default)
|
484
|
-
|
485
|
-
def meta_change_key(self, old_key: str, new_key: str) -> bool:
|
486
|
-
"""
|
487
|
-
Change a key in the metadata dictionary.
|
488
|
-
|
489
|
-
Args:
|
490
|
-
old_key (str): The old key to be changed.
|
491
|
-
new_key (str): The new key to replace the old key.
|
492
|
-
|
493
|
-
Returns:
|
494
|
-
bool: True if the key was changed successfully, False otherwise.
|
495
|
-
"""
|
496
|
-
if old_key in self.metadata:
|
497
|
-
SysUtil.change_dict_key(self.metadata, old_key, new_key)
|
498
|
-
return True
|
499
|
-
return False
|
500
|
-
|
501
|
-
def meta_insert(self, indices: str | list, value: Any, **kwargs) -> bool:
|
502
|
-
"""
|
503
|
-
Insert a value into the metadata dictionary at the specified indices.
|
504
|
-
|
505
|
-
Args:
|
506
|
-
indices (str | list): The indices to insert the value at.
|
507
|
-
value (Any): The value to be inserted.
|
508
|
-
**kwargs: Additional keyword arguments for the `nested.ninsert`
|
509
|
-
function.
|
510
|
-
|
511
|
-
Returns:
|
512
|
-
bool: True if the value was inserted successfully, False otherwise.
|
513
|
-
"""
|
514
|
-
return nested.ninsert(self.metadata, indices, value, **kwargs)
|
515
|
-
|
516
|
-
def meta_merge(
|
517
|
-
self, additional_metadata: dict[str, Any], overwrite: bool = False, **kwargs
|
518
|
-
) -> None:
|
519
|
-
"""
|
520
|
-
Merge additional metadata into the existing metadata dictionary.
|
521
|
-
|
522
|
-
Args:
|
523
|
-
additional_metadata (dict[str, Any]): The additional metadata to be
|
524
|
-
merged.
|
525
|
-
overwrite (bool): Whether to overwrite existing keys with the new
|
526
|
-
values.
|
527
|
-
**kwargs: Additional keyword arguments for the `nested.nmerge`
|
528
|
-
function.
|
529
|
-
"""
|
530
|
-
self.metadata = nested.nmerge(
|
531
|
-
[self.metadata, additional_metadata], overwrite=overwrite, **kwargs
|
532
|
-
)
|
@@ -1,46 +0,0 @@
|
|
1
|
-
from abc import ABC, abstractmethod
|
2
|
-
from enum import Enum
|
3
|
-
from typing import Callable
|
4
|
-
from pydantic import BaseModel, Field
|
5
|
-
|
6
|
-
|
7
|
-
class ConditionSource(str, Enum):
|
8
|
-
"""
|
9
|
-
Enumeration for specifying the source type of a condition.
|
10
|
-
|
11
|
-
Attributes:
|
12
|
-
STRUCTURE: Represents a condition based on the structure.
|
13
|
-
EXECUTABLE: Represents a condition that can be executed or evaluated.
|
14
|
-
"""
|
15
|
-
|
16
|
-
STRUCTURE = "structure"
|
17
|
-
EXECUTABLE = "executable"
|
18
|
-
RULE = "rule"
|
19
|
-
|
20
|
-
|
21
|
-
class Condition(BaseModel, ABC):
|
22
|
-
"""
|
23
|
-
Abstract base class for defining conditions associated with edges.
|
24
|
-
|
25
|
-
Attributes:
|
26
|
-
source_type (ConditionSource): Specifies the type of source for the condition.
|
27
|
-
|
28
|
-
Methods:
|
29
|
-
check: Abstract method that should be implemented to evaluate the condition.
|
30
|
-
"""
|
31
|
-
|
32
|
-
source_type: str = Field(..., description="The type of source for the condition.")
|
33
|
-
|
34
|
-
class Config:
|
35
|
-
"""Model configuration settings."""
|
36
|
-
|
37
|
-
extra = "allow"
|
38
|
-
|
39
|
-
@abstractmethod
|
40
|
-
def __call__(self, executable) -> bool:
|
41
|
-
"""Evaluates the condition based on implemented logic.
|
42
|
-
|
43
|
-
Returns:
|
44
|
-
bool: The boolean result of the condition evaluation.
|
45
|
-
"""
|
46
|
-
pass
|
lionagi/core/generic/mail.py
DELETED
@@ -1,90 +0,0 @@
|
|
1
|
-
"""
|
2
|
-
This module defines classes for representing mail packages and mailboxes
|
3
|
-
in a messaging system.
|
4
|
-
|
5
|
-
The module includes the following classes:
|
6
|
-
- MailPackageCategory: An enumeration of categories for mail packages.
|
7
|
-
- Mail: Represents a mail message sent from one component to another.
|
8
|
-
- MailBox: Represents a mailbox that stores pending incoming and outgoing mails.
|
9
|
-
"""
|
10
|
-
|
11
|
-
from typing import Any
|
12
|
-
from enum import Enum
|
13
|
-
|
14
|
-
from pydantic import Field, field_validator
|
15
|
-
|
16
|
-
from lionagi.core.generic.component import BaseComponent
|
17
|
-
|
18
|
-
|
19
|
-
class MailPackageCategory(str, Enum):
|
20
|
-
"""
|
21
|
-
Defines categories for mail packages in a messaging system.
|
22
|
-
|
23
|
-
Attributes:
|
24
|
-
MESSAGES: Represents general messages.
|
25
|
-
TOOL: Represents tools.
|
26
|
-
SERVICE: Represents services.
|
27
|
-
MODEL: Represents models.
|
28
|
-
NODE: Represents nodes.
|
29
|
-
NODE_LIST: Represents a list of nodes.
|
30
|
-
NODE_ID: Represents a node's ID.
|
31
|
-
START: Represents a start signal or value.
|
32
|
-
END: Represents an end signal or value.
|
33
|
-
CONDITION: Represents a condition.
|
34
|
-
"""
|
35
|
-
|
36
|
-
MESSAGES = "messages"
|
37
|
-
TOOL = "tool"
|
38
|
-
SERVICE = "service"
|
39
|
-
MODEL = "model"
|
40
|
-
NODE = "node"
|
41
|
-
NODE_LIST = "node_list"
|
42
|
-
NODE_ID = "node_id"
|
43
|
-
START = "start"
|
44
|
-
END = "end"
|
45
|
-
CONDITION = "condition"
|
46
|
-
|
47
|
-
|
48
|
-
class Package(BaseComponent):
|
49
|
-
category: MailPackageCategory = Field(
|
50
|
-
..., title="Category", description="The category of the mail package."
|
51
|
-
)
|
52
|
-
|
53
|
-
package: Any = Field(
|
54
|
-
..., title="Package", description="The package to send in the mail."
|
55
|
-
)
|
56
|
-
|
57
|
-
|
58
|
-
class Mail(BaseComponent):
|
59
|
-
"""
|
60
|
-
Represents a mail message sent from one component to another within
|
61
|
-
the system.
|
62
|
-
|
63
|
-
Attributes:
|
64
|
-
sender (str): The ID of the sender node.
|
65
|
-
recipient (str): The ID of the recipient node.
|
66
|
-
category (MailPackageCategory): The category of the mail package.
|
67
|
-
package (Any): The content of the mail package.
|
68
|
-
"""
|
69
|
-
|
70
|
-
sender: str = Field(
|
71
|
-
title="Sender",
|
72
|
-
description="The id of the sender node.",
|
73
|
-
)
|
74
|
-
|
75
|
-
recipient: str = Field(
|
76
|
-
title="Recipient",
|
77
|
-
description="The id of the recipient node.",
|
78
|
-
)
|
79
|
-
|
80
|
-
packages: dict[str, Package] = Field(
|
81
|
-
title="Packages",
|
82
|
-
default_factory=dict,
|
83
|
-
description="The packages to send in the mail.",
|
84
|
-
)
|
85
|
-
|
86
|
-
@field_validator("sender", "recipient", mode="before")
|
87
|
-
def _validate_sender_recipient(cls, value):
|
88
|
-
if isinstance(value, BaseComponent):
|
89
|
-
return value.id_
|
90
|
-
return value
|
lionagi/core/generic/mailbox.py
DELETED
@@ -1,36 +0,0 @@
|
|
1
|
-
from collections import deque
|
2
|
-
from pydantic import Field
|
3
|
-
from pydantic.dataclasses import dataclass
|
4
|
-
|
5
|
-
from lionagi.core.generic.mail import Mail
|
6
|
-
|
7
|
-
|
8
|
-
@dataclass
|
9
|
-
class MailBox:
|
10
|
-
|
11
|
-
pile: dict[str, Mail] = Field(
|
12
|
-
default_factory=dict, description="The pile of all mails - {mail_id: Mail}"
|
13
|
-
)
|
14
|
-
|
15
|
-
sequence_in: dict[str, deque] = Field(
|
16
|
-
default_factory=dict,
|
17
|
-
description="The sequence of all incoming mails - {sender_id: deque[mail_id]}",
|
18
|
-
)
|
19
|
-
|
20
|
-
sequence_out: deque = Field(
|
21
|
-
default_factory=deque,
|
22
|
-
description="The sequence of all outgoing mails - deque[mail_id]",
|
23
|
-
)
|
24
|
-
|
25
|
-
def __str__(self) -> str:
|
26
|
-
"""
|
27
|
-
Returns a string representation of the MailBox instance.
|
28
|
-
|
29
|
-
Returns:
|
30
|
-
str: A string describing the number of pending incoming and
|
31
|
-
outgoing mails in the MailBox.
|
32
|
-
"""
|
33
|
-
return (
|
34
|
-
f"MailBox with {len(self.receieving)} pending incoming mails and "
|
35
|
-
f"{len(self.sending)} pending outgoing mails."
|
36
|
-
)
|