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.
Files changed (268) hide show
  1. lionagi/__init__.py +60 -5
  2. lionagi/core/__init__.py +0 -25
  3. lionagi/core/_setting/_setting.py +59 -0
  4. lionagi/core/action/__init__.py +14 -0
  5. lionagi/core/action/function_calling.py +136 -0
  6. lionagi/core/action/manual.py +1 -0
  7. lionagi/core/action/node.py +109 -0
  8. lionagi/core/action/tool.py +114 -0
  9. lionagi/core/action/tool_manager.py +356 -0
  10. lionagi/core/agent/base_agent.py +27 -13
  11. lionagi/core/agent/eval/evaluator.py +1 -0
  12. lionagi/core/agent/eval/vote.py +40 -0
  13. lionagi/core/agent/learn/learner.py +59 -0
  14. lionagi/core/agent/plan/unit_template.py +1 -0
  15. lionagi/core/collections/__init__.py +17 -0
  16. lionagi/core/{generic/data_logger.py → collections/_logger.py} +69 -55
  17. lionagi/core/collections/abc/__init__.py +53 -0
  18. lionagi/core/collections/abc/component.py +615 -0
  19. lionagi/core/collections/abc/concepts.py +297 -0
  20. lionagi/core/collections/abc/exceptions.py +150 -0
  21. lionagi/core/collections/abc/util.py +45 -0
  22. lionagi/core/collections/exchange.py +161 -0
  23. lionagi/core/collections/flow.py +426 -0
  24. lionagi/core/collections/model.py +419 -0
  25. lionagi/core/collections/pile.py +913 -0
  26. lionagi/core/collections/progression.py +236 -0
  27. lionagi/core/collections/util.py +64 -0
  28. lionagi/core/director/direct.py +314 -0
  29. lionagi/core/director/director.py +2 -0
  30. lionagi/core/{execute/branch_executor.py → engine/branch_engine.py} +134 -97
  31. lionagi/core/{execute/instruction_map_executor.py → engine/instruction_map_engine.py} +80 -55
  32. lionagi/{experimental/directive/evaluator → core/engine}/script_engine.py +17 -1
  33. lionagi/core/executor/base_executor.py +90 -0
  34. lionagi/core/{execute/structure_executor.py → executor/graph_executor.py} +62 -66
  35. lionagi/core/{execute → executor}/neo4j_executor.py +70 -67
  36. lionagi/core/generic/__init__.py +3 -33
  37. lionagi/core/generic/edge.py +29 -79
  38. lionagi/core/generic/edge_condition.py +16 -0
  39. lionagi/core/generic/graph.py +236 -0
  40. lionagi/core/generic/hyperedge.py +1 -0
  41. lionagi/core/generic/node.py +156 -221
  42. lionagi/core/generic/tree.py +48 -0
  43. lionagi/core/generic/tree_node.py +79 -0
  44. lionagi/core/mail/__init__.py +12 -0
  45. lionagi/core/mail/mail.py +25 -0
  46. lionagi/core/mail/mail_manager.py +139 -58
  47. lionagi/core/mail/package.py +45 -0
  48. lionagi/core/mail/start_mail.py +36 -0
  49. lionagi/core/message/__init__.py +19 -0
  50. lionagi/core/message/action_request.py +133 -0
  51. lionagi/core/message/action_response.py +135 -0
  52. lionagi/core/message/assistant_response.py +95 -0
  53. lionagi/core/message/instruction.py +234 -0
  54. lionagi/core/message/message.py +101 -0
  55. lionagi/core/message/system.py +86 -0
  56. lionagi/core/message/util.py +283 -0
  57. lionagi/core/report/__init__.py +4 -0
  58. lionagi/core/report/base.py +217 -0
  59. lionagi/core/report/form.py +231 -0
  60. lionagi/core/report/report.py +166 -0
  61. lionagi/core/report/util.py +28 -0
  62. lionagi/core/rule/_default.py +16 -0
  63. lionagi/core/rule/action.py +99 -0
  64. lionagi/core/rule/base.py +238 -0
  65. lionagi/core/rule/boolean.py +56 -0
  66. lionagi/core/rule/choice.py +47 -0
  67. lionagi/core/rule/mapping.py +96 -0
  68. lionagi/core/rule/number.py +71 -0
  69. lionagi/core/rule/rulebook.py +109 -0
  70. lionagi/core/rule/string.py +52 -0
  71. lionagi/core/rule/util.py +35 -0
  72. lionagi/core/session/branch.py +431 -0
  73. lionagi/core/session/directive_mixin.py +287 -0
  74. lionagi/core/session/session.py +229 -903
  75. lionagi/core/structure/__init__.py +1 -0
  76. lionagi/core/structure/chain.py +1 -0
  77. lionagi/core/structure/forest.py +1 -0
  78. lionagi/core/structure/graph.py +1 -0
  79. lionagi/core/structure/tree.py +1 -0
  80. lionagi/core/unit/__init__.py +5 -0
  81. lionagi/core/unit/parallel_unit.py +245 -0
  82. lionagi/core/unit/template/action.py +81 -0
  83. lionagi/core/unit/template/base.py +51 -0
  84. lionagi/core/unit/template/plan.py +84 -0
  85. lionagi/core/unit/template/predict.py +109 -0
  86. lionagi/core/unit/template/score.py +124 -0
  87. lionagi/core/unit/template/select.py +104 -0
  88. lionagi/core/unit/unit.py +362 -0
  89. lionagi/core/unit/unit_form.py +305 -0
  90. lionagi/core/unit/unit_mixin.py +1168 -0
  91. lionagi/core/unit/util.py +71 -0
  92. lionagi/core/validator/validator.py +364 -0
  93. lionagi/core/work/work.py +74 -0
  94. lionagi/core/work/work_function.py +92 -0
  95. lionagi/core/work/work_queue.py +81 -0
  96. lionagi/core/work/worker.py +195 -0
  97. lionagi/core/work/worklog.py +124 -0
  98. lionagi/experimental/compressor/base.py +46 -0
  99. lionagi/experimental/compressor/llm_compressor.py +247 -0
  100. lionagi/experimental/compressor/llm_summarizer.py +61 -0
  101. lionagi/experimental/compressor/util.py +70 -0
  102. lionagi/experimental/directive/__init__.py +19 -0
  103. lionagi/experimental/directive/parser/base_parser.py +69 -2
  104. lionagi/experimental/directive/{template_ → template}/base_template.py +17 -1
  105. lionagi/{libs/ln_tokenizer.py → experimental/directive/tokenizer.py} +16 -0
  106. lionagi/experimental/{directive/evaluator → evaluator}/ast_evaluator.py +16 -0
  107. lionagi/experimental/{directive/evaluator → evaluator}/base_evaluator.py +16 -0
  108. lionagi/experimental/knowledge/base.py +10 -0
  109. lionagi/experimental/memory/__init__.py +0 -0
  110. lionagi/experimental/strategies/__init__.py +0 -0
  111. lionagi/experimental/strategies/base.py +1 -0
  112. lionagi/integrations/bridge/langchain_/documents.py +4 -0
  113. lionagi/integrations/bridge/llamaindex_/index.py +30 -0
  114. lionagi/integrations/bridge/llamaindex_/llama_index_bridge.py +6 -0
  115. lionagi/integrations/chunker/chunk.py +161 -24
  116. lionagi/integrations/config/oai_configs.py +34 -3
  117. lionagi/integrations/config/openrouter_configs.py +14 -2
  118. lionagi/integrations/loader/load.py +122 -21
  119. lionagi/integrations/loader/load_util.py +6 -77
  120. lionagi/integrations/provider/_mapping.py +46 -0
  121. lionagi/integrations/provider/litellm.py +2 -1
  122. lionagi/integrations/provider/mlx_service.py +16 -9
  123. lionagi/integrations/provider/oai.py +91 -4
  124. lionagi/integrations/provider/ollama.py +6 -5
  125. lionagi/integrations/provider/openrouter.py +115 -8
  126. lionagi/integrations/provider/services.py +2 -2
  127. lionagi/integrations/provider/transformers.py +18 -22
  128. lionagi/integrations/storage/__init__.py +3 -3
  129. lionagi/integrations/storage/neo4j.py +52 -60
  130. lionagi/integrations/storage/storage_util.py +44 -46
  131. lionagi/integrations/storage/structure_excel.py +43 -26
  132. lionagi/integrations/storage/to_excel.py +11 -4
  133. lionagi/libs/__init__.py +22 -1
  134. lionagi/libs/ln_api.py +75 -20
  135. lionagi/libs/ln_context.py +37 -0
  136. lionagi/libs/ln_convert.py +21 -9
  137. lionagi/libs/ln_func_call.py +69 -28
  138. lionagi/libs/ln_image.py +107 -0
  139. lionagi/libs/ln_nested.py +26 -11
  140. lionagi/libs/ln_parse.py +82 -23
  141. lionagi/libs/ln_queue.py +16 -0
  142. lionagi/libs/ln_tokenize.py +164 -0
  143. lionagi/libs/ln_validate.py +16 -0
  144. lionagi/libs/special_tokens.py +172 -0
  145. lionagi/libs/sys_util.py +95 -24
  146. lionagi/lions/coder/code_form.py +13 -0
  147. lionagi/lions/coder/coder.py +50 -3
  148. lionagi/lions/coder/util.py +30 -25
  149. lionagi/tests/libs/test_func_call.py +23 -21
  150. lionagi/tests/libs/test_nested.py +36 -21
  151. lionagi/tests/libs/test_parse.py +1 -1
  152. lionagi/tests/test_core/collections/__init__.py +0 -0
  153. lionagi/tests/test_core/collections/test_component.py +206 -0
  154. lionagi/tests/test_core/collections/test_exchange.py +138 -0
  155. lionagi/tests/test_core/collections/test_flow.py +145 -0
  156. lionagi/tests/test_core/collections/test_pile.py +171 -0
  157. lionagi/tests/test_core/collections/test_progression.py +129 -0
  158. lionagi/tests/test_core/generic/test_edge.py +67 -0
  159. lionagi/tests/test_core/generic/test_graph.py +96 -0
  160. lionagi/tests/test_core/generic/test_node.py +106 -0
  161. lionagi/tests/test_core/generic/test_tree_node.py +73 -0
  162. lionagi/tests/test_core/test_branch.py +115 -294
  163. lionagi/tests/test_core/test_form.py +46 -0
  164. lionagi/tests/test_core/test_report.py +105 -0
  165. lionagi/tests/test_core/test_validator.py +111 -0
  166. lionagi/version.py +1 -1
  167. lionagi-0.2.0.dist-info/LICENSE +202 -0
  168. lionagi-0.2.0.dist-info/METADATA +272 -0
  169. lionagi-0.2.0.dist-info/RECORD +240 -0
  170. lionagi/core/branch/base.py +0 -653
  171. lionagi/core/branch/branch.py +0 -474
  172. lionagi/core/branch/flow_mixin.py +0 -96
  173. lionagi/core/branch/util.py +0 -323
  174. lionagi/core/direct/__init__.py +0 -19
  175. lionagi/core/direct/cot.py +0 -123
  176. lionagi/core/direct/plan.py +0 -164
  177. lionagi/core/direct/predict.py +0 -166
  178. lionagi/core/direct/react.py +0 -171
  179. lionagi/core/direct/score.py +0 -279
  180. lionagi/core/direct/select.py +0 -170
  181. lionagi/core/direct/sentiment.py +0 -1
  182. lionagi/core/direct/utils.py +0 -110
  183. lionagi/core/direct/vote.py +0 -64
  184. lionagi/core/execute/base_executor.py +0 -47
  185. lionagi/core/flow/baseflow.py +0 -23
  186. lionagi/core/flow/monoflow/ReAct.py +0 -240
  187. lionagi/core/flow/monoflow/__init__.py +0 -9
  188. lionagi/core/flow/monoflow/chat.py +0 -95
  189. lionagi/core/flow/monoflow/chat_mixin.py +0 -253
  190. lionagi/core/flow/monoflow/followup.py +0 -215
  191. lionagi/core/flow/polyflow/__init__.py +0 -1
  192. lionagi/core/flow/polyflow/chat.py +0 -251
  193. lionagi/core/form/action_form.py +0 -26
  194. lionagi/core/form/field_validator.py +0 -287
  195. lionagi/core/form/form.py +0 -302
  196. lionagi/core/form/mixin.py +0 -214
  197. lionagi/core/form/scored_form.py +0 -13
  198. lionagi/core/generic/action.py +0 -26
  199. lionagi/core/generic/component.py +0 -532
  200. lionagi/core/generic/condition.py +0 -46
  201. lionagi/core/generic/mail.py +0 -90
  202. lionagi/core/generic/mailbox.py +0 -36
  203. lionagi/core/generic/relation.py +0 -70
  204. lionagi/core/generic/signal.py +0 -22
  205. lionagi/core/generic/structure.py +0 -362
  206. lionagi/core/generic/transfer.py +0 -20
  207. lionagi/core/generic/work.py +0 -40
  208. lionagi/core/graph/graph.py +0 -126
  209. lionagi/core/graph/tree.py +0 -190
  210. lionagi/core/mail/schema.py +0 -63
  211. lionagi/core/messages/schema.py +0 -325
  212. lionagi/core/tool/__init__.py +0 -5
  213. lionagi/core/tool/tool.py +0 -28
  214. lionagi/core/tool/tool_manager.py +0 -283
  215. lionagi/experimental/report/form.py +0 -64
  216. lionagi/experimental/report/report.py +0 -138
  217. lionagi/experimental/report/util.py +0 -47
  218. lionagi/experimental/tool/function_calling.py +0 -43
  219. lionagi/experimental/tool/manual.py +0 -66
  220. lionagi/experimental/tool/schema.py +0 -59
  221. lionagi/experimental/tool/tool_manager.py +0 -138
  222. lionagi/experimental/tool/util.py +0 -16
  223. lionagi/experimental/validator/rule.py +0 -139
  224. lionagi/experimental/validator/validator.py +0 -56
  225. lionagi/experimental/work/__init__.py +0 -10
  226. lionagi/experimental/work/async_queue.py +0 -54
  227. lionagi/experimental/work/schema.py +0 -73
  228. lionagi/experimental/work/work_function.py +0 -67
  229. lionagi/experimental/work/worker.py +0 -56
  230. lionagi/experimental/work2/form.py +0 -371
  231. lionagi/experimental/work2/report.py +0 -289
  232. lionagi/experimental/work2/schema.py +0 -30
  233. lionagi/experimental/work2/tests.py +0 -72
  234. lionagi/experimental/work2/work_function.py +0 -89
  235. lionagi/experimental/work2/worker.py +0 -12
  236. lionagi/integrations/bridge/llamaindex_/get_index.py +0 -294
  237. lionagi/tests/test_core/generic/test_component.py +0 -89
  238. lionagi/tests/test_core/test_base_branch.py +0 -426
  239. lionagi/tests/test_core/test_chat_flow.py +0 -63
  240. lionagi/tests/test_core/test_mail_manager.py +0 -75
  241. lionagi/tests/test_core/test_prompts.py +0 -51
  242. lionagi/tests/test_core/test_session.py +0 -254
  243. lionagi/tests/test_core/test_session_base_util.py +0 -313
  244. lionagi/tests/test_core/test_tool_manager.py +0 -95
  245. lionagi-0.1.2.dist-info/LICENSE +0 -9
  246. lionagi-0.1.2.dist-info/METADATA +0 -174
  247. lionagi-0.1.2.dist-info/RECORD +0 -206
  248. /lionagi/core/{branch → _setting}/__init__.py +0 -0
  249. /lionagi/core/{execute → agent/eval}/__init__.py +0 -0
  250. /lionagi/core/{flow → agent/learn}/__init__.py +0 -0
  251. /lionagi/core/{form → agent/plan}/__init__.py +0 -0
  252. /lionagi/core/{branch/executable_branch.py → agent/plan/plan.py} +0 -0
  253. /lionagi/core/{graph → director}/__init__.py +0 -0
  254. /lionagi/core/{messages → engine}/__init__.py +0 -0
  255. /lionagi/{experimental/directive/evaluator → core/engine}/sandbox_.py +0 -0
  256. /lionagi/{experimental/directive/evaluator → core/executor}/__init__.py +0 -0
  257. /lionagi/{experimental/directive/template_ → core/rule}/__init__.py +0 -0
  258. /lionagi/{experimental/report → core/unit/template}/__init__.py +0 -0
  259. /lionagi/{experimental/tool → core/validator}/__init__.py +0 -0
  260. /lionagi/{experimental/validator → core/work}/__init__.py +0 -0
  261. /lionagi/experimental/{work2 → compressor}/__init__.py +0 -0
  262. /lionagi/{core/flow/mono_chat_mixin.py → experimental/directive/template/__init__.py} +0 -0
  263. /lionagi/experimental/directive/{schema.py → template/schema.py} +0 -0
  264. /lionagi/experimental/{work2/util.py → evaluator/__init__.py} +0 -0
  265. /lionagi/experimental/{work2/work.py → knowledge/__init__.py} +0 -0
  266. /lionagi/{tests/libs/test_async.py → experimental/knowledge/graph.py} +0 -0
  267. {lionagi-0.1.2.dist-info → lionagi-0.2.0.dist-info}/WHEEL +0 -0
  268. {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)