lionagi 0.1.2__py3-none-any.whl → 0.2.0__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 +74 -0
- lionagi/core/work/work_function.py +92 -0
- lionagi/core/work/work_queue.py +81 -0
- lionagi/core/work/worker.py +195 -0
- lionagi/core/work/worklog.py +124 -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.0.dist-info/LICENSE +202 -0
- lionagi-0.2.0.dist-info/METADATA +272 -0
- lionagi-0.2.0.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.0.dist-info}/WHEEL +0 -0
- {lionagi-0.1.2.dist-info → lionagi-0.2.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,297 @@
|
|
1
|
+
"""
|
2
|
+
Copyright 2024 HaiyangLi
|
3
|
+
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
you may not use this file except in compliance with the License.
|
6
|
+
You may obtain a copy of the License at
|
7
|
+
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
See the License for the specific language governing permissions and
|
14
|
+
limitations under the License.
|
15
|
+
"""
|
16
|
+
|
17
|
+
"""This module defines abstract base classes for LionAGI."""
|
18
|
+
|
19
|
+
from abc import ABC, abstractmethod
|
20
|
+
from collections.abc import Generator
|
21
|
+
from typing import Any, Iterator, TypeVar
|
22
|
+
|
23
|
+
from pydantic import Field, BaseModel, field_validator
|
24
|
+
|
25
|
+
from .component import LionIDable, get_lion_id
|
26
|
+
from .exceptions import LionTypeError
|
27
|
+
|
28
|
+
T = TypeVar("T")
|
29
|
+
|
30
|
+
|
31
|
+
class Record(ABC):
|
32
|
+
"""
|
33
|
+
Abstract base class for managing a collection of unique LionAGI items.
|
34
|
+
|
35
|
+
Accepts LionIDable for retrieval and requires Component instances for
|
36
|
+
addition.
|
37
|
+
|
38
|
+
Methods:
|
39
|
+
keys: Return an iterator over the ln_id of items in the record.
|
40
|
+
values: Return an iterator over items in the record.
|
41
|
+
get: Retrieve an item by identifier.
|
42
|
+
__getitem__: Return an item using a LionIDable identifier.
|
43
|
+
__setitem__: Add or update an item in the record.
|
44
|
+
__contains__: Check if an item is in the record.
|
45
|
+
__len__: Return the number of items in the record.
|
46
|
+
__iter__: Iterate over items in the record.
|
47
|
+
"""
|
48
|
+
|
49
|
+
@abstractmethod
|
50
|
+
def keys(self) -> Generator[str, None, None]:
|
51
|
+
"""Return an iterator over the ln_id of items in the record."""
|
52
|
+
|
53
|
+
@abstractmethod
|
54
|
+
def values(self) -> Generator[T, None, None]:
|
55
|
+
"""Return an iterator over items in the record."""
|
56
|
+
|
57
|
+
@abstractmethod
|
58
|
+
def get(self, item: LionIDable, /, default: Any = None) -> T:
|
59
|
+
"""
|
60
|
+
Retrieve an item by identifier.
|
61
|
+
|
62
|
+
Accepts a LionIDable object. Returns the default if the item is not
|
63
|
+
found.
|
64
|
+
|
65
|
+
Args:
|
66
|
+
item (LionIDable): The identifier of the item to retrieve.
|
67
|
+
default (Any): The default value to return if the item is not found.
|
68
|
+
|
69
|
+
Returns:
|
70
|
+
T: The retrieved item or the default value.
|
71
|
+
"""
|
72
|
+
|
73
|
+
@abstractmethod
|
74
|
+
def __getitem__(self, item: LionIDable) -> T:
|
75
|
+
"""
|
76
|
+
Return an item using a LionIDable identifier.
|
77
|
+
|
78
|
+
Raises:
|
79
|
+
KeyError: If the item ID is not found.
|
80
|
+
|
81
|
+
Args:
|
82
|
+
item (LionIDable): The identifier of the item to retrieve.
|
83
|
+
|
84
|
+
Returns:
|
85
|
+
T: The retrieved item.
|
86
|
+
"""
|
87
|
+
|
88
|
+
@abstractmethod
|
89
|
+
def __setitem__(self, item: LionIDable, value: T) -> None:
|
90
|
+
"""
|
91
|
+
Add or update an item in the record.
|
92
|
+
|
93
|
+
The value must be a Component instance.
|
94
|
+
|
95
|
+
Args:
|
96
|
+
item (LionIDable): The identifier of the item to add or update.
|
97
|
+
value (T): The Component instance to add or update.
|
98
|
+
"""
|
99
|
+
|
100
|
+
@abstractmethod
|
101
|
+
def __contains__(self, item: LionIDable) -> bool:
|
102
|
+
"""
|
103
|
+
Check if an item is in the record, using either an ID or an object.
|
104
|
+
|
105
|
+
Args:
|
106
|
+
item (LionIDable): The identifier or object to check.
|
107
|
+
|
108
|
+
Returns:
|
109
|
+
bool: True if the item is in the record, False otherwise.
|
110
|
+
"""
|
111
|
+
|
112
|
+
@abstractmethod
|
113
|
+
def __len__(self) -> int:
|
114
|
+
"""
|
115
|
+
Return the number of items in the record.
|
116
|
+
|
117
|
+
Returns:
|
118
|
+
int: The number of items in the record.
|
119
|
+
"""
|
120
|
+
|
121
|
+
@abstractmethod
|
122
|
+
def __iter__(self) -> Iterator[T]:
|
123
|
+
"""
|
124
|
+
Iterate over items in the record.
|
125
|
+
|
126
|
+
Yields:
|
127
|
+
T: The items in the record.
|
128
|
+
"""
|
129
|
+
|
130
|
+
|
131
|
+
class Ordering(ABC):
|
132
|
+
"""Represents sequencing of certain order."""
|
133
|
+
|
134
|
+
@abstractmethod
|
135
|
+
def __len__(self) -> int:
|
136
|
+
"""
|
137
|
+
Return the number of item ids in the ordering.
|
138
|
+
|
139
|
+
Or the number of orderings in another ordering.
|
140
|
+
"""
|
141
|
+
|
142
|
+
@abstractmethod
|
143
|
+
def __contains__(self, item: Any) -> bool:
|
144
|
+
"""Check if an item id is in the ordering."""
|
145
|
+
|
146
|
+
|
147
|
+
class Condition(ABC):
|
148
|
+
"""Represents a condition in a given context."""
|
149
|
+
|
150
|
+
@abstractmethod
|
151
|
+
async def applies(self, value: Any, /, *args: Any, **kwargs: Any) -> Any:
|
152
|
+
"""Asynchronously determine if the condition applies to the given value.
|
153
|
+
|
154
|
+
Args:
|
155
|
+
value (Any): The value to check against the condition.
|
156
|
+
*args: Additional positional arguments.
|
157
|
+
**kwargs: Additional keyword arguments.
|
158
|
+
|
159
|
+
Returns:
|
160
|
+
Any: The result of applying the condition to the value.
|
161
|
+
"""
|
162
|
+
|
163
|
+
|
164
|
+
class Actionable(ABC):
|
165
|
+
"""Represents an action that can be invoked with arguments."""
|
166
|
+
|
167
|
+
@abstractmethod
|
168
|
+
async def invoke(self, /, *args: Any, **kwargs: Any) -> Any:
|
169
|
+
"""
|
170
|
+
Invoke the action asynchronously with the given arguments.
|
171
|
+
|
172
|
+
Args:
|
173
|
+
*args: Positional arguments for invoking the action.
|
174
|
+
**kwargs: Keyword arguments for invoking the action.
|
175
|
+
|
176
|
+
Returns:
|
177
|
+
Any: The result of invoking the action.
|
178
|
+
"""
|
179
|
+
|
180
|
+
|
181
|
+
class Progressable(ABC):
|
182
|
+
"""Represents a process that can progress forward asynchronously."""
|
183
|
+
|
184
|
+
@abstractmethod
|
185
|
+
async def forward(self, /, *args: Any, **kwargs: Any) -> None:
|
186
|
+
"""Move the process forward asynchronously.
|
187
|
+
|
188
|
+
Args:
|
189
|
+
*args: Positional arguments for moving the process forward.
|
190
|
+
**kwargs: Keyword arguments for moving the process forward.
|
191
|
+
"""
|
192
|
+
|
193
|
+
|
194
|
+
class Relatable(ABC):
|
195
|
+
"""Defines a relationship that can be established with arguments."""
|
196
|
+
|
197
|
+
@abstractmethod
|
198
|
+
def relate(self, /, *args: Any, **kwargs: Any) -> None:
|
199
|
+
"""Establish a relationship based on the provided arguments.
|
200
|
+
|
201
|
+
Args:
|
202
|
+
*args: Positional arguments for establishing the relationship.
|
203
|
+
**kwargs: Keyword arguments for establishing the relationship.
|
204
|
+
"""
|
205
|
+
|
206
|
+
|
207
|
+
class Sendable(BaseModel, ABC):
|
208
|
+
"""Represents an object that can be sent with a sender and recipient."""
|
209
|
+
|
210
|
+
sender: str = Field(
|
211
|
+
"N/A",
|
212
|
+
title="Sender",
|
213
|
+
description=("The id of the sender node, or 'system', 'user', or 'assistant'."),
|
214
|
+
)
|
215
|
+
|
216
|
+
recipient: str = Field(
|
217
|
+
"N/A",
|
218
|
+
title="Recipient",
|
219
|
+
description=(
|
220
|
+
"The id of the recipient node, or 'system', 'user', or 'assistant'."
|
221
|
+
),
|
222
|
+
)
|
223
|
+
|
224
|
+
@field_validator("sender", "recipient", mode="before")
|
225
|
+
def _validate_sender_recipient(cls, value):
|
226
|
+
"""Validate the sender and recipient fields.
|
227
|
+
|
228
|
+
Args:
|
229
|
+
value (Any): The value to validate.
|
230
|
+
|
231
|
+
Returns:
|
232
|
+
str: The validated value.
|
233
|
+
|
234
|
+
Raises:
|
235
|
+
LionTypeError: If the value is invalid.
|
236
|
+
"""
|
237
|
+
if value is None:
|
238
|
+
return "N/A"
|
239
|
+
|
240
|
+
if value in ["system", "user", "N/A", "assistant"]:
|
241
|
+
return value
|
242
|
+
|
243
|
+
a = get_lion_id(value)
|
244
|
+
if not isinstance(a, str) or len(a) != 32:
|
245
|
+
raise LionTypeError(
|
246
|
+
"Invalid sender or recipient value. "
|
247
|
+
"Expected a valid node id or one of "
|
248
|
+
"'system' or 'user'."
|
249
|
+
)
|
250
|
+
return a
|
251
|
+
|
252
|
+
|
253
|
+
class Executable(ABC):
|
254
|
+
"""Represents an object that can be executed with arguments."""
|
255
|
+
|
256
|
+
@abstractmethod
|
257
|
+
async def execute(self, /, *args: Any, **kwargs: Any) -> Any:
|
258
|
+
"""Execute the object with the given arguments asynchronously.
|
259
|
+
|
260
|
+
Args:
|
261
|
+
*args: Positional arguments for executing the object.
|
262
|
+
**kwargs: Keyword arguments for executing the object.
|
263
|
+
|
264
|
+
Returns:
|
265
|
+
Any: The result of executing the object.
|
266
|
+
"""
|
267
|
+
|
268
|
+
|
269
|
+
class Directive(ABC):
|
270
|
+
"""Represents a directive that can be directed with arguments."""
|
271
|
+
|
272
|
+
# @abstractmethod
|
273
|
+
# async def direct(self, *args, **kwargs):
|
274
|
+
# """Direct the directive with the given arguments asynchronously.
|
275
|
+
|
276
|
+
# Args:
|
277
|
+
# *args: Positional arguments for directing the directive.
|
278
|
+
# **kwargs: Keyword arguments for directing the directive.
|
279
|
+
# """
|
280
|
+
|
281
|
+
@property
|
282
|
+
def class_name(self) -> str:
|
283
|
+
"""Get the class name of the directive.
|
284
|
+
|
285
|
+
Returns:
|
286
|
+
str: The class name of the directive.
|
287
|
+
"""
|
288
|
+
return self._class_name()
|
289
|
+
|
290
|
+
@classmethod
|
291
|
+
def _class_name(cls) -> str:
|
292
|
+
"""Get the class name of the directive.
|
293
|
+
|
294
|
+
Returns:
|
295
|
+
str: The class name of the directive.
|
296
|
+
"""
|
297
|
+
return cls.__name__
|
@@ -0,0 +1,150 @@
|
|
1
|
+
"""
|
2
|
+
Copyright 2024 HaiyangLi
|
3
|
+
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
you may not use this file except in compliance with the License.
|
6
|
+
You may obtain a copy of the License at
|
7
|
+
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
See the License for the specific language governing permissions and
|
14
|
+
limitations under the License.
|
15
|
+
"""
|
16
|
+
|
17
|
+
# import logging
|
18
|
+
|
19
|
+
# # Configure logging
|
20
|
+
# logging.basicConfig(
|
21
|
+
# level=logging.ERROR,
|
22
|
+
# format="%(asctime)s:%(levelname)s:%(message)s",
|
23
|
+
# )
|
24
|
+
|
25
|
+
|
26
|
+
class LionAGIError(Exception):
|
27
|
+
"""Base class for all exceptions in the LionAGI system."""
|
28
|
+
|
29
|
+
def __init__(self, message=None):
|
30
|
+
if message is None:
|
31
|
+
message = "An unspecified error occurred in the LionAGI system."
|
32
|
+
super().__init__(message)
|
33
|
+
|
34
|
+
|
35
|
+
class LionValueError(LionAGIError):
|
36
|
+
"""Exception raised for errors in the input value."""
|
37
|
+
|
38
|
+
def __init__(self, message=None):
|
39
|
+
if message is None:
|
40
|
+
message = "An error occurred in the input value."
|
41
|
+
super().__init__(message)
|
42
|
+
|
43
|
+
|
44
|
+
class LionTypeError(LionAGIError):
|
45
|
+
"""Exception raised for type mismatch or type checking errors."""
|
46
|
+
|
47
|
+
def __init__(self, message=None):
|
48
|
+
if message is None:
|
49
|
+
message = "Item must be identifiable, `ln_id` or `Component`"
|
50
|
+
super().__init__(message)
|
51
|
+
|
52
|
+
|
53
|
+
class LionItemError(LionAGIError):
|
54
|
+
"""Base class for exceptions related to LionAGI items."""
|
55
|
+
|
56
|
+
def __init__(self, item, message=None):
|
57
|
+
if message is None:
|
58
|
+
message = "An error occurred with the specified item."
|
59
|
+
super().__init__(f"{message} Item: '{item}'.")
|
60
|
+
|
61
|
+
|
62
|
+
class ItemNotFoundError(LionItemError):
|
63
|
+
"""Exception raised when a specified item is not found."""
|
64
|
+
|
65
|
+
def __init__(self, item):
|
66
|
+
super().__init__(item, "Item not found.")
|
67
|
+
|
68
|
+
|
69
|
+
class ItemInvalidError(LionItemError):
|
70
|
+
"""Exception raised when an invalid item is used in an operation."""
|
71
|
+
|
72
|
+
def __init__(self, item):
|
73
|
+
super().__init__(item, "The item is invalid for this operation.")
|
74
|
+
|
75
|
+
|
76
|
+
class FieldError(LionAGIError):
|
77
|
+
"""Exception raised for errors in field validation."""
|
78
|
+
|
79
|
+
def __init__(self, field, message=None):
|
80
|
+
if message is None:
|
81
|
+
message = "An error occurred with the specified field."
|
82
|
+
super().__init__(f"{message}: {field}.")
|
83
|
+
|
84
|
+
|
85
|
+
class LionOperationError(LionAGIError):
|
86
|
+
"""Base class for exceptions related to operational failures."""
|
87
|
+
|
88
|
+
def __init__(self, operation, message=None):
|
89
|
+
if message is None:
|
90
|
+
message = "An operation failed."
|
91
|
+
super().__init__(f"{message} Operation: '{operation}'.")
|
92
|
+
|
93
|
+
|
94
|
+
class ConcurrencyError(LionOperationError):
|
95
|
+
"""Exception raised for errors due to concurrency issues."""
|
96
|
+
|
97
|
+
def __init__(self, operation=None):
|
98
|
+
if operation is None:
|
99
|
+
operation = "a concurrent operation"
|
100
|
+
super().__init__(operation, "A concurrency error occurred during")
|
101
|
+
|
102
|
+
|
103
|
+
class RelationError(LionAGIError):
|
104
|
+
"""Exception raised for errors in relation operations."""
|
105
|
+
|
106
|
+
def __init__(self, message=None):
|
107
|
+
if message is None:
|
108
|
+
message = "Nodes are not related."
|
109
|
+
super().__init__(message)
|
110
|
+
|
111
|
+
|
112
|
+
class ActionError(LionAGIError):
|
113
|
+
"""Exception raised for errors in action operations."""
|
114
|
+
|
115
|
+
def __init__(self, message=None):
|
116
|
+
if message is None:
|
117
|
+
message = "An error occurred with the specified action."
|
118
|
+
super().__init__(message)
|
119
|
+
|
120
|
+
|
121
|
+
class ModelLimitExceededError(LionOperationError):
|
122
|
+
"""Exception raised when a resource limit is exceeded."""
|
123
|
+
|
124
|
+
def __init__(self, message=None):
|
125
|
+
if message is None:
|
126
|
+
message = "The model limit has been exceeded."
|
127
|
+
super().__init__("Model", message)
|
128
|
+
|
129
|
+
|
130
|
+
class TimeoutError(LionOperationError):
|
131
|
+
"""Exception raised when an operation times out."""
|
132
|
+
|
133
|
+
def __init__(self, operation, timeout):
|
134
|
+
super().__init__(operation, f"Operation timed out after {timeout} seconds.")
|
135
|
+
|
136
|
+
|
137
|
+
class ServiceError(LionAGIError):
|
138
|
+
"""Exception raised for errors in endpoint configuration."""
|
139
|
+
|
140
|
+
def __init__(self, message, errors=None):
|
141
|
+
super().__init__(message, errors)
|
142
|
+
|
143
|
+
@classmethod
|
144
|
+
def unavailable(cls, endpoint, service, err_msg=None):
|
145
|
+
msg = f"{endpoint} is currently unavailable"
|
146
|
+
if err_msg:
|
147
|
+
msg += f": {err_msg}"
|
148
|
+
else:
|
149
|
+
msg += f" for {service.__class__.__name__}"
|
150
|
+
return cls(msg)
|
@@ -0,0 +1,45 @@
|
|
1
|
+
base_lion_fields = [
|
2
|
+
"ln_id",
|
3
|
+
"timestamp",
|
4
|
+
"metadata",
|
5
|
+
"extra_fields",
|
6
|
+
"content",
|
7
|
+
"created",
|
8
|
+
"embedding",
|
9
|
+
]
|
10
|
+
|
11
|
+
lc_meta_fields = ["lc", "type", "id", "langchain", "lc_type", "lc_id"]
|
12
|
+
|
13
|
+
llama_meta_fields = [
|
14
|
+
"id_",
|
15
|
+
"embedding",
|
16
|
+
"excluded_embed_metadata_keys",
|
17
|
+
"excluded_llm_metadata_keys",
|
18
|
+
"relationships",
|
19
|
+
"start_char_idx",
|
20
|
+
"end_char_idx",
|
21
|
+
"class_name",
|
22
|
+
"text_template",
|
23
|
+
"metadata_template",
|
24
|
+
"metadata_seperator",
|
25
|
+
]
|
26
|
+
|
27
|
+
SYSTEM_FIELDS = [
|
28
|
+
"ln_id",
|
29
|
+
"timestamp",
|
30
|
+
"metadata",
|
31
|
+
"meta",
|
32
|
+
"extra_fields",
|
33
|
+
"content",
|
34
|
+
"created",
|
35
|
+
"form",
|
36
|
+
"report",
|
37
|
+
"work",
|
38
|
+
"assignment",
|
39
|
+
"assignments",
|
40
|
+
"input_fields",
|
41
|
+
"requested_fields",
|
42
|
+
"instruction",
|
43
|
+
"system",
|
44
|
+
"strict",
|
45
|
+
]
|
@@ -0,0 +1,161 @@
|
|
1
|
+
"""
|
2
|
+
Copyright 2024 HaiyangLi
|
3
|
+
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
you may not use this file except in compliance with the License.
|
6
|
+
You may obtain a copy of the License at
|
7
|
+
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
See the License for the specific language governing permissions and
|
14
|
+
limitations under the License.
|
15
|
+
"""
|
16
|
+
|
17
|
+
from typing import TypeVar, Generic
|
18
|
+
from .abc import Element, Field, Sendable
|
19
|
+
from .pile import Pile, pile
|
20
|
+
from .progression import Progression, progression
|
21
|
+
|
22
|
+
T = TypeVar("T")
|
23
|
+
|
24
|
+
|
25
|
+
class Exchange(Element, Generic[T]):
|
26
|
+
"""
|
27
|
+
Item exchange system designed to handle incoming and outgoing flows of items.
|
28
|
+
|
29
|
+
Attributes:
|
30
|
+
pile (Pile[T]): The pile of items in the exchange.
|
31
|
+
pending_ins (dict[str, Progression]): The pending incoming items to the exchange.
|
32
|
+
pending_outs (Progression): The progression of pending outgoing items.
|
33
|
+
"""
|
34
|
+
|
35
|
+
pile: Pile[T] = Field(
|
36
|
+
default_factory=lambda: pile(),
|
37
|
+
description="The pile of items in the exchange.",
|
38
|
+
title="pending items",
|
39
|
+
)
|
40
|
+
|
41
|
+
pending_ins: dict[str, Progression] = Field(
|
42
|
+
default_factory=dict,
|
43
|
+
description="The pending incoming items to the exchange.",
|
44
|
+
title="pending incoming items",
|
45
|
+
examples=["{'sender_id': Progression}"],
|
46
|
+
)
|
47
|
+
|
48
|
+
pending_outs: Progression = Field(
|
49
|
+
default_factory=lambda: progression(),
|
50
|
+
description="The pending outgoing items to the exchange.",
|
51
|
+
title="pending outgoing items",
|
52
|
+
)
|
53
|
+
|
54
|
+
def __contains__(self, item):
|
55
|
+
"""
|
56
|
+
Check if an item is in the pile.
|
57
|
+
|
58
|
+
Args:
|
59
|
+
item: The item to check.
|
60
|
+
|
61
|
+
Returns:
|
62
|
+
bool: True if the item is in the pile, False otherwise.
|
63
|
+
"""
|
64
|
+
return item in self.pile
|
65
|
+
|
66
|
+
@property
|
67
|
+
def unassigned(self) -> Pile[T]:
|
68
|
+
"""
|
69
|
+
if the item is not in the pending_ins or pending_outs, it is unassigned.
|
70
|
+
"""
|
71
|
+
return pile(
|
72
|
+
[
|
73
|
+
item
|
74
|
+
for item in self.pile
|
75
|
+
if (
|
76
|
+
all(item not in j for j in self.pending_ins.values())
|
77
|
+
and item not in self.pending_outs
|
78
|
+
)
|
79
|
+
]
|
80
|
+
)
|
81
|
+
|
82
|
+
@property
|
83
|
+
def senders(self) -> list[str]:
|
84
|
+
"""
|
85
|
+
Get the list of senders for the pending incoming items.
|
86
|
+
|
87
|
+
Returns:
|
88
|
+
list[str]: The list of sender IDs.
|
89
|
+
"""
|
90
|
+
return list(self.pending_ins.keys())
|
91
|
+
|
92
|
+
def exclude(self, item) -> bool:
|
93
|
+
"""
|
94
|
+
Exclude an item from the exchange.
|
95
|
+
|
96
|
+
Args:
|
97
|
+
item: The item to exclude.
|
98
|
+
|
99
|
+
Returns:
|
100
|
+
bool: True if the item was successfully excluded, False otherwise.
|
101
|
+
"""
|
102
|
+
return (
|
103
|
+
self.pile.exclude(item)
|
104
|
+
and all([v.exclude(item) for v in self.pending_ins.values()])
|
105
|
+
and self.pending_outs.exclude(item)
|
106
|
+
)
|
107
|
+
|
108
|
+
def include(self, item, direction=None) -> bool:
|
109
|
+
"""
|
110
|
+
Include an item in the exchange in a specified direction.
|
111
|
+
|
112
|
+
Args:
|
113
|
+
item: The item to include.
|
114
|
+
direction (str): The direction to include the item ('in' or 'out').
|
115
|
+
|
116
|
+
Returns:
|
117
|
+
bool: True if the item was successfully included, False otherwise.
|
118
|
+
"""
|
119
|
+
if self.pile.include(item):
|
120
|
+
item = self.pile[item]
|
121
|
+
item = [item] if not isinstance(item, list) else item
|
122
|
+
for i in item:
|
123
|
+
if not self._include(i, direction=direction):
|
124
|
+
return False
|
125
|
+
return True
|
126
|
+
|
127
|
+
def _include(self, item: Sendable, direction) -> bool:
|
128
|
+
"""
|
129
|
+
Helper method to include an item in the exchange in a specified direction.
|
130
|
+
|
131
|
+
Args:
|
132
|
+
item (Sendable): The item to include.
|
133
|
+
direction (str): The direction to include the item ('in' or 'out').
|
134
|
+
|
135
|
+
Returns:
|
136
|
+
bool: True if the item was successfully included, False otherwise.
|
137
|
+
"""
|
138
|
+
if direction == "in":
|
139
|
+
if item.sender not in self.pending_ins:
|
140
|
+
self.pending_ins[item.sender] = progression()
|
141
|
+
return self.pending_ins[item.sender].include(item)
|
142
|
+
|
143
|
+
if direction == "out":
|
144
|
+
return self.pending_outs.include(item)
|
145
|
+
|
146
|
+
return True
|
147
|
+
|
148
|
+
def to_dict(self) -> dict:
|
149
|
+
"""
|
150
|
+
Convert the exchange to a dictionary.
|
151
|
+
|
152
|
+
Returns:
|
153
|
+
dict: The dictionary representation of the exchange.
|
154
|
+
"""
|
155
|
+
return self.model_dump(by_alias=True)
|
156
|
+
|
157
|
+
def __bool__(self):
|
158
|
+
return True
|
159
|
+
|
160
|
+
def __len__(self):
|
161
|
+
return len(self.pile)
|