lionagi 0.0.312__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.
Files changed (268) hide show
  1. lionagi/__init__.py +61 -3
  2. lionagi/core/__init__.py +0 -14
  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/__init__.py +0 -3
  11. lionagi/core/agent/base_agent.py +45 -36
  12. lionagi/core/agent/eval/evaluator.py +1 -0
  13. lionagi/core/agent/eval/vote.py +40 -0
  14. lionagi/core/agent/learn/learner.py +59 -0
  15. lionagi/core/agent/plan/unit_template.py +1 -0
  16. lionagi/core/collections/__init__.py +17 -0
  17. lionagi/core/collections/_logger.py +319 -0
  18. lionagi/core/collections/abc/__init__.py +53 -0
  19. lionagi/core/collections/abc/component.py +615 -0
  20. lionagi/core/collections/abc/concepts.py +297 -0
  21. lionagi/core/collections/abc/exceptions.py +150 -0
  22. lionagi/core/collections/abc/util.py +45 -0
  23. lionagi/core/collections/exchange.py +161 -0
  24. lionagi/core/collections/flow.py +426 -0
  25. lionagi/core/collections/model.py +419 -0
  26. lionagi/core/collections/pile.py +913 -0
  27. lionagi/core/collections/progression.py +236 -0
  28. lionagi/core/collections/util.py +64 -0
  29. lionagi/core/director/direct.py +314 -0
  30. lionagi/core/director/director.py +2 -0
  31. lionagi/core/engine/branch_engine.py +333 -0
  32. lionagi/core/engine/instruction_map_engine.py +204 -0
  33. lionagi/core/engine/sandbox_.py +14 -0
  34. lionagi/core/engine/script_engine.py +99 -0
  35. lionagi/core/executor/base_executor.py +90 -0
  36. lionagi/core/executor/graph_executor.py +330 -0
  37. lionagi/core/executor/neo4j_executor.py +384 -0
  38. lionagi/core/generic/__init__.py +7 -0
  39. lionagi/core/generic/edge.py +112 -0
  40. lionagi/core/generic/edge_condition.py +16 -0
  41. lionagi/core/generic/graph.py +236 -0
  42. lionagi/core/generic/hyperedge.py +1 -0
  43. lionagi/core/generic/node.py +220 -0
  44. lionagi/core/generic/tree.py +48 -0
  45. lionagi/core/generic/tree_node.py +79 -0
  46. lionagi/core/mail/__init__.py +7 -3
  47. lionagi/core/mail/mail.py +25 -0
  48. lionagi/core/mail/mail_manager.py +142 -58
  49. lionagi/core/mail/package.py +45 -0
  50. lionagi/core/mail/start_mail.py +36 -0
  51. lionagi/core/message/__init__.py +19 -0
  52. lionagi/core/message/action_request.py +133 -0
  53. lionagi/core/message/action_response.py +135 -0
  54. lionagi/core/message/assistant_response.py +95 -0
  55. lionagi/core/message/instruction.py +234 -0
  56. lionagi/core/message/message.py +101 -0
  57. lionagi/core/message/system.py +86 -0
  58. lionagi/core/message/util.py +283 -0
  59. lionagi/core/report/__init__.py +4 -0
  60. lionagi/core/report/base.py +217 -0
  61. lionagi/core/report/form.py +231 -0
  62. lionagi/core/report/report.py +166 -0
  63. lionagi/core/report/util.py +28 -0
  64. lionagi/core/rule/__init__.py +0 -0
  65. lionagi/core/rule/_default.py +16 -0
  66. lionagi/core/rule/action.py +99 -0
  67. lionagi/core/rule/base.py +238 -0
  68. lionagi/core/rule/boolean.py +56 -0
  69. lionagi/core/rule/choice.py +47 -0
  70. lionagi/core/rule/mapping.py +96 -0
  71. lionagi/core/rule/number.py +71 -0
  72. lionagi/core/rule/rulebook.py +109 -0
  73. lionagi/core/rule/string.py +52 -0
  74. lionagi/core/rule/util.py +35 -0
  75. lionagi/core/session/__init__.py +0 -3
  76. lionagi/core/session/branch.py +431 -0
  77. lionagi/core/session/directive_mixin.py +287 -0
  78. lionagi/core/session/session.py +230 -902
  79. lionagi/core/structure/__init__.py +1 -0
  80. lionagi/core/structure/chain.py +1 -0
  81. lionagi/core/structure/forest.py +1 -0
  82. lionagi/core/structure/graph.py +1 -0
  83. lionagi/core/structure/tree.py +1 -0
  84. lionagi/core/unit/__init__.py +5 -0
  85. lionagi/core/unit/parallel_unit.py +245 -0
  86. lionagi/core/unit/template/__init__.py +0 -0
  87. lionagi/core/unit/template/action.py +81 -0
  88. lionagi/core/unit/template/base.py +51 -0
  89. lionagi/core/unit/template/plan.py +84 -0
  90. lionagi/core/unit/template/predict.py +109 -0
  91. lionagi/core/unit/template/score.py +124 -0
  92. lionagi/core/unit/template/select.py +104 -0
  93. lionagi/core/unit/unit.py +362 -0
  94. lionagi/core/unit/unit_form.py +305 -0
  95. lionagi/core/unit/unit_mixin.py +1168 -0
  96. lionagi/core/unit/util.py +71 -0
  97. lionagi/core/validator/__init__.py +0 -0
  98. lionagi/core/validator/validator.py +364 -0
  99. lionagi/core/work/__init__.py +0 -0
  100. lionagi/core/work/work.py +76 -0
  101. lionagi/core/work/work_function.py +101 -0
  102. lionagi/core/work/work_queue.py +103 -0
  103. lionagi/core/work/worker.py +258 -0
  104. lionagi/core/work/worklog.py +120 -0
  105. lionagi/experimental/__init__.py +0 -0
  106. lionagi/experimental/compressor/__init__.py +0 -0
  107. lionagi/experimental/compressor/base.py +46 -0
  108. lionagi/experimental/compressor/llm_compressor.py +247 -0
  109. lionagi/experimental/compressor/llm_summarizer.py +61 -0
  110. lionagi/experimental/compressor/util.py +70 -0
  111. lionagi/experimental/directive/__init__.py +19 -0
  112. lionagi/experimental/directive/parser/__init__.py +0 -0
  113. lionagi/experimental/directive/parser/base_parser.py +282 -0
  114. lionagi/experimental/directive/template/__init__.py +0 -0
  115. lionagi/experimental/directive/template/base_template.py +79 -0
  116. lionagi/experimental/directive/template/schema.py +36 -0
  117. lionagi/experimental/directive/tokenizer.py +73 -0
  118. lionagi/experimental/evaluator/__init__.py +0 -0
  119. lionagi/experimental/evaluator/ast_evaluator.py +131 -0
  120. lionagi/experimental/evaluator/base_evaluator.py +218 -0
  121. lionagi/experimental/knowledge/__init__.py +0 -0
  122. lionagi/experimental/knowledge/base.py +10 -0
  123. lionagi/experimental/knowledge/graph.py +0 -0
  124. lionagi/experimental/memory/__init__.py +0 -0
  125. lionagi/experimental/strategies/__init__.py +0 -0
  126. lionagi/experimental/strategies/base.py +1 -0
  127. lionagi/integrations/bridge/autogen_/__init__.py +0 -0
  128. lionagi/integrations/bridge/autogen_/autogen_.py +124 -0
  129. lionagi/integrations/bridge/langchain_/documents.py +4 -0
  130. lionagi/integrations/bridge/llamaindex_/index.py +30 -0
  131. lionagi/integrations/bridge/llamaindex_/llama_index_bridge.py +6 -0
  132. lionagi/integrations/bridge/llamaindex_/llama_pack.py +227 -0
  133. lionagi/integrations/bridge/llamaindex_/node_parser.py +6 -9
  134. lionagi/integrations/bridge/pydantic_/pydantic_bridge.py +1 -0
  135. lionagi/integrations/bridge/transformers_/__init__.py +0 -0
  136. lionagi/integrations/bridge/transformers_/install_.py +36 -0
  137. lionagi/integrations/chunker/__init__.py +0 -0
  138. lionagi/integrations/chunker/chunk.py +312 -0
  139. lionagi/integrations/config/oai_configs.py +38 -7
  140. lionagi/integrations/config/ollama_configs.py +1 -1
  141. lionagi/integrations/config/openrouter_configs.py +14 -2
  142. lionagi/integrations/loader/__init__.py +0 -0
  143. lionagi/integrations/loader/load.py +253 -0
  144. lionagi/integrations/loader/load_util.py +195 -0
  145. lionagi/integrations/provider/_mapping.py +46 -0
  146. lionagi/integrations/provider/litellm.py +2 -1
  147. lionagi/integrations/provider/mlx_service.py +16 -9
  148. lionagi/integrations/provider/oai.py +91 -4
  149. lionagi/integrations/provider/ollama.py +7 -6
  150. lionagi/integrations/provider/openrouter.py +115 -8
  151. lionagi/integrations/provider/services.py +2 -2
  152. lionagi/integrations/provider/transformers.py +18 -22
  153. lionagi/integrations/storage/__init__.py +3 -0
  154. lionagi/integrations/storage/neo4j.py +665 -0
  155. lionagi/integrations/storage/storage_util.py +287 -0
  156. lionagi/integrations/storage/structure_excel.py +285 -0
  157. lionagi/integrations/storage/to_csv.py +63 -0
  158. lionagi/integrations/storage/to_excel.py +83 -0
  159. lionagi/libs/__init__.py +26 -1
  160. lionagi/libs/ln_api.py +78 -23
  161. lionagi/libs/ln_context.py +37 -0
  162. lionagi/libs/ln_convert.py +21 -9
  163. lionagi/libs/ln_func_call.py +69 -28
  164. lionagi/libs/ln_image.py +107 -0
  165. lionagi/libs/ln_knowledge_graph.py +405 -0
  166. lionagi/libs/ln_nested.py +26 -11
  167. lionagi/libs/ln_parse.py +110 -14
  168. lionagi/libs/ln_queue.py +117 -0
  169. lionagi/libs/ln_tokenize.py +164 -0
  170. lionagi/{core/prompt/field_validator.py → libs/ln_validate.py} +79 -14
  171. lionagi/libs/special_tokens.py +172 -0
  172. lionagi/libs/sys_util.py +107 -2
  173. lionagi/lions/__init__.py +0 -0
  174. lionagi/lions/coder/__init__.py +0 -0
  175. lionagi/lions/coder/add_feature.py +20 -0
  176. lionagi/lions/coder/base_prompts.py +22 -0
  177. lionagi/lions/coder/code_form.py +13 -0
  178. lionagi/lions/coder/coder.py +168 -0
  179. lionagi/lions/coder/util.py +96 -0
  180. lionagi/lions/researcher/__init__.py +0 -0
  181. lionagi/lions/researcher/data_source/__init__.py +0 -0
  182. lionagi/lions/researcher/data_source/finhub_.py +191 -0
  183. lionagi/lions/researcher/data_source/google_.py +199 -0
  184. lionagi/lions/researcher/data_source/wiki_.py +96 -0
  185. lionagi/lions/researcher/data_source/yfinance_.py +21 -0
  186. lionagi/tests/integrations/__init__.py +0 -0
  187. lionagi/tests/libs/__init__.py +0 -0
  188. lionagi/tests/libs/test_field_validators.py +353 -0
  189. lionagi/tests/{test_libs → libs}/test_func_call.py +23 -21
  190. lionagi/tests/{test_libs → libs}/test_nested.py +36 -21
  191. lionagi/tests/{test_libs → libs}/test_parse.py +1 -1
  192. lionagi/tests/libs/test_queue.py +67 -0
  193. lionagi/tests/test_core/collections/__init__.py +0 -0
  194. lionagi/tests/test_core/collections/test_component.py +206 -0
  195. lionagi/tests/test_core/collections/test_exchange.py +138 -0
  196. lionagi/tests/test_core/collections/test_flow.py +145 -0
  197. lionagi/tests/test_core/collections/test_pile.py +171 -0
  198. lionagi/tests/test_core/collections/test_progression.py +129 -0
  199. lionagi/tests/test_core/generic/__init__.py +0 -0
  200. lionagi/tests/test_core/generic/test_edge.py +67 -0
  201. lionagi/tests/test_core/generic/test_graph.py +96 -0
  202. lionagi/tests/test_core/generic/test_node.py +106 -0
  203. lionagi/tests/test_core/generic/test_tree_node.py +73 -0
  204. lionagi/tests/test_core/test_branch.py +115 -292
  205. lionagi/tests/test_core/test_form.py +46 -0
  206. lionagi/tests/test_core/test_report.py +105 -0
  207. lionagi/tests/test_core/test_validator.py +111 -0
  208. lionagi/version.py +1 -1
  209. {lionagi-0.0.312.dist-info → lionagi-0.2.1.dist-info}/LICENSE +12 -11
  210. {lionagi-0.0.312.dist-info → lionagi-0.2.1.dist-info}/METADATA +19 -118
  211. lionagi-0.2.1.dist-info/RECORD +240 -0
  212. lionagi/core/branch/__init__.py +0 -4
  213. lionagi/core/branch/base_branch.py +0 -654
  214. lionagi/core/branch/branch.py +0 -471
  215. lionagi/core/branch/branch_flow_mixin.py +0 -96
  216. lionagi/core/branch/executable_branch.py +0 -347
  217. lionagi/core/branch/util.py +0 -323
  218. lionagi/core/direct/__init__.py +0 -6
  219. lionagi/core/direct/predict.py +0 -161
  220. lionagi/core/direct/score.py +0 -278
  221. lionagi/core/direct/select.py +0 -169
  222. lionagi/core/direct/utils.py +0 -87
  223. lionagi/core/direct/vote.py +0 -64
  224. lionagi/core/flow/base/baseflow.py +0 -23
  225. lionagi/core/flow/monoflow/ReAct.py +0 -238
  226. lionagi/core/flow/monoflow/__init__.py +0 -9
  227. lionagi/core/flow/monoflow/chat.py +0 -95
  228. lionagi/core/flow/monoflow/chat_mixin.py +0 -263
  229. lionagi/core/flow/monoflow/followup.py +0 -214
  230. lionagi/core/flow/polyflow/__init__.py +0 -1
  231. lionagi/core/flow/polyflow/chat.py +0 -248
  232. lionagi/core/mail/schema.py +0 -56
  233. lionagi/core/messages/__init__.py +0 -3
  234. lionagi/core/messages/schema.py +0 -533
  235. lionagi/core/prompt/prompt_template.py +0 -316
  236. lionagi/core/schema/__init__.py +0 -22
  237. lionagi/core/schema/action_node.py +0 -29
  238. lionagi/core/schema/base_mixin.py +0 -296
  239. lionagi/core/schema/base_node.py +0 -199
  240. lionagi/core/schema/condition.py +0 -24
  241. lionagi/core/schema/data_logger.py +0 -354
  242. lionagi/core/schema/data_node.py +0 -93
  243. lionagi/core/schema/prompt_template.py +0 -67
  244. lionagi/core/schema/structure.py +0 -910
  245. lionagi/core/tool/__init__.py +0 -3
  246. lionagi/core/tool/tool_manager.py +0 -280
  247. lionagi/integrations/bridge/pydantic_/base_model.py +0 -7
  248. lionagi/tests/test_core/test_base_branch.py +0 -427
  249. lionagi/tests/test_core/test_chat_flow.py +0 -63
  250. lionagi/tests/test_core/test_mail_manager.py +0 -75
  251. lionagi/tests/test_core/test_prompts.py +0 -51
  252. lionagi/tests/test_core/test_session.py +0 -254
  253. lionagi/tests/test_core/test_session_base_util.py +0 -312
  254. lionagi/tests/test_core/test_tool_manager.py +0 -95
  255. lionagi-0.0.312.dist-info/RECORD +0 -111
  256. /lionagi/core/{branch/base → _setting}/__init__.py +0 -0
  257. /lionagi/core/{flow → agent/eval}/__init__.py +0 -0
  258. /lionagi/core/{flow/base → agent/learn}/__init__.py +0 -0
  259. /lionagi/core/{prompt → agent/plan}/__init__.py +0 -0
  260. /lionagi/core/{tool/manual.py → agent/plan/plan.py} +0 -0
  261. /lionagi/{tests/test_integrations → core/director}/__init__.py +0 -0
  262. /lionagi/{tests/test_libs → core/engine}/__init__.py +0 -0
  263. /lionagi/{tests/test_libs/test_async.py → core/executor/__init__.py} +0 -0
  264. /lionagi/tests/{test_libs → libs}/test_api.py +0 -0
  265. /lionagi/tests/{test_libs → libs}/test_convert.py +0 -0
  266. /lionagi/tests/{test_libs → libs}/test_sys_util.py +0 -0
  267. {lionagi-0.0.312.dist-info → lionagi-0.2.1.dist-info}/WHEEL +0 -0
  268. {lionagi-0.0.312.dist-info → lionagi-0.2.1.dist-info}/top_level.txt +0 -0
@@ -1,316 +0,0 @@
1
- """
2
- This module defines the PromptTemplate and ScoredTemplate classes for creating and managing prompt templates.
3
-
4
- The PromptTemplate class is a base class for creating prompt templates with input and output fields, validation,
5
- and processing. The ScoredTemplate class extends the PromptTemplate class and adds fields for confidence score and reason.
6
- """
7
-
8
- from typing import Any
9
- from lionagi.libs import convert, func_call
10
- from lionagi.core.schema.base_node import BaseComponent
11
-
12
- from pydantic import Field
13
- from .field_validator import validation_funcs
14
-
15
-
16
- _non_prompt_words = [
17
- "id_",
18
- "node_id",
19
- "meta",
20
- "timestamp",
21
- "metadata",
22
- "signature",
23
- "task",
24
- "template_name",
25
- ]
26
-
27
-
28
- class PromptTemplate(BaseComponent):
29
- """
30
- A base class for creating and managing prompt templates.
31
-
32
- Attributes:
33
- signature (str): The signature indicating the input and output fields.
34
- choices (dict[str, list[str]]): The choices to select from for each field.
35
- out_validation_kwargs (dict[str, Any]): The validation keyword arguments for output fields.
36
- in_validation_kwargs (dict[str, Any]): The validation keyword arguments for input fields.
37
- task (str | dict[str, Any] | None): The task to follow.
38
- fix_input (bool): Whether to fix input fields.
39
- fix_output (bool): Whether to fix output fields.
40
- template_name (str): The name of the prompt template.
41
- version (str | float | int): The version of the prompt template.
42
- description (dict | str | None): The description of the prompt template.
43
- input_fields (list[str]): The input fields of the prompt template.
44
- output_fields (list[str]): The output fields of the prompt template.
45
-
46
- Methods:
47
- __init__(self, template_name="default_prompt_template", version_=None, description_=None, task=None, **kwargs):
48
- Initializes a new instance of the PromptTemplate class.
49
- _validate_input_choices(self, fix_=fix_input):
50
- Validates the input choices based on the defined choices.
51
- _validate_output_choices(self, fix_=fix_output):
52
- Validates the output choices based on the defined choices.
53
- _get_input_output_fields(str_) -> tuple[list[str], list[str]]:
54
- Extracts the input and output fields from the signature string.
55
- instruction_context(self) -> str:
56
- Returns the instruction context based on the input fields.
57
- instruction(self) -> str:
58
- Returns the instruction based on the task and input/output fields.
59
- instruction_output_fields(self) -> dict[str, str]:
60
- Returns a dictionary mapping output fields to their descriptions.
61
- prompt_fields_annotation(self) -> dict[str, list[str]]:
62
- Returns a dictionary mapping prompt fields to their annotated types.
63
- _validate_field(self, k, v, choices=None, fix_=False, **kwargs) -> bool:
64
- Validates a single field based on its annotated type and choices.
65
- _process_input(self, fix_=False):
66
- Processes and validates the input fields.
67
- _process_response(self, out_, fix_=True):
68
- Processes and validates the output fields.
69
- in_(self) -> dict[str, Any]:
70
- Returns a dictionary mapping input fields to their values.
71
- out(self) -> dict[str, Any]:
72
- Returns a dictionary mapping output fields to their values.
73
- process(self, in_=None, out_=None):
74
- Processes and validates the input and output fields.
75
- """
76
-
77
- signature: str = Field("null", description="signature indicating inputs, outputs")
78
- choices: dict[str, list[str]] = Field(
79
- default_factory=dict, description="choices to select from"
80
- )
81
- out_validation_kwargs: dict[str, Any] = Field(
82
- default_factory=dict, description="validation kwargs for output"
83
- )
84
- in_validation_kwargs: dict[str, Any] = Field(
85
- default_factory=dict, description="validation kwargs for input"
86
- )
87
- task: str | dict[str, Any] | None = Field(None, description="task to follow")
88
- fix_input: bool = Field(True, description="whether to fix input")
89
- fix_output: bool = Field(True, description="whether to fix output")
90
-
91
- def __init__(
92
- self,
93
- template_name: str = "default_prompt_template",
94
- version_: str | float | int = None,
95
- description_: dict | str | None = None,
96
- task: str | None = None,
97
- **kwargs,
98
- ):
99
- super().__init__(**kwargs)
100
- self.template_name = template_name
101
- self.meta_insert(["version"], version_)
102
- self.meta_insert(["description"], description_ or "")
103
- self.task = task
104
- self.input_fields, self.output_fields = self._get_input_output_fields(
105
- self.signature
106
- )
107
- self.process(in_=True)
108
-
109
- def _validate_input_choices(self, fix_=fix_input):
110
- if len(self.choices) >= 1:
111
- for k, choices in self.choices.items():
112
- if k in self.input_fields and not self._validate_field(
113
- k, getattr(self, k), choices, fix_
114
- ):
115
- raise ValueError(
116
- f"Invalid choice for field {k}: {getattr(self, k)} is not in {choices}"
117
- )
118
-
119
- def _validate_output_choices(self, fix_=fix_output):
120
- if len(self.choices) >= 1:
121
- for k, choices in self.choices.items():
122
- if k in self.output_fields and not self._validate_field(
123
- k, getattr(self, k), choices, fix_
124
- ):
125
- raise ValueError(
126
- f"Invalid choice for field {k}: {getattr(self, k)} is not in {choices}"
127
- )
128
-
129
- @property
130
- def version(self):
131
- return self.metadata["version"]
132
-
133
- @version.setter
134
- def version(self, value):
135
- self.metadata["version"] = value
136
-
137
- @property
138
- def description(self):
139
- return self.metadata["description"]
140
-
141
- @description.setter
142
- def description(self, value):
143
- self.metadata["description"] = value
144
-
145
- @property
146
- def prompt_fields(self):
147
- return [
148
- _field for _field in self.property_keys if _field not in _non_prompt_words
149
- ]
150
-
151
- @staticmethod
152
- def _get_input_output_fields(str_):
153
- _inputs, _outputs = str_.split("->")
154
-
155
- _inputs = [convert.strip_lower(i) for i in _inputs.split(",")]
156
- _outputs = [convert.strip_lower(o) for o in _outputs.split(",")]
157
-
158
- return _inputs, _outputs
159
-
160
- @property
161
- def instruction_context(self):
162
- a = "".join(
163
- f"""
164
- ## input: {i}:
165
- - description: {self.model_fields[i].description}
166
- - value: {str(self.__getattribute__(self.input_fields[idx]))}
167
- """
168
- for idx, i in enumerate(self.input_fields)
169
- )
170
- return a.replace(" ", "")
171
-
172
- @property
173
- def instruction(self):
174
- ccc = f"""
175
- 0. Your task is {self.task},
176
- 1. provided: {self.input_fields},
177
- 2. requested: {self.output_fields}
178
- ----------
179
- """
180
- return ccc.replace(" ", "")
181
-
182
- @property
183
- def instruction_output_fields(self):
184
- return {i: self.model_fields[i].description for i in self.output_fields}
185
-
186
- @property
187
- def prompt_fields_annotation(self):
188
- dict_ = {i: self.model_fields[i].annotation for i in self.prompt_fields}
189
- for k, v in dict_.items():
190
- if "|" in str(v):
191
- v = str(v)
192
- v = v.split("|")
193
- dict_[k] = func_call.lcall(v, convert.strip_lower)
194
- else:
195
- dict_[k] = [v.__name__]
196
-
197
- return dict_
198
-
199
- def _validate_field(self, k, v, choices=None, fix_=False, **kwargs):
200
-
201
- str_ = self.prompt_fields_annotation[k]
202
-
203
- if choices:
204
- v_ = validation_funcs["enum"](v, choices=choices, fix_=fix_, **kwargs)
205
- if v_ not in choices:
206
- raise ValueError(f"{v} is not in chocies {choices}")
207
- setattr(self, k, v_)
208
- return True
209
-
210
- elif "bool" in str_:
211
- self.__setattr__(k, validation_funcs["bool"](v, fix_=fix_, **kwargs))
212
- return True
213
-
214
- elif "int" in str_ or "float" in str_:
215
- self.__setattr__(k, validation_funcs["number"](v, fix_=fix_, **kwargs))
216
- return True
217
-
218
- elif "str" in str_:
219
- self.__setattr__(k, validation_funcs["str"](v, fix_=fix_, **kwargs))
220
- return True
221
-
222
- return False
223
-
224
- def _process_input(self, fix_=False):
225
- kwargs = self.in_validation_kwargs.copy()
226
- for k, v in self.in_.items():
227
- if k not in kwargs:
228
- kwargs = {k: {}}
229
-
230
- try:
231
- if (
232
- self.model_fields[k].json_schema_extra["choices"] is not None
233
- and "choices" in self.model_fields[k].json_schema_extra
234
- ):
235
- self.choices[k] = self.model_fields[k].json_schema_extra["choices"]
236
- if self._validate_field(
237
- k, v, choices=self.choices[k], fix_=fix_, **kwargs[k]
238
- ):
239
- continue
240
- else:
241
- raise ValueError(f"{k} has no choices")
242
-
243
- except Exception as e:
244
- if self._validate_field(k, v, fix_=fix_, **kwargs[k]):
245
- continue
246
- else:
247
- raise ValueError(f"failed to validate field {k}") from e
248
-
249
- def _process_response(self, out_, fix_=True):
250
- kwargs = self.out_validation_kwargs.copy()
251
- for k, v in out_.items():
252
- if k not in kwargs:
253
- kwargs = {k: {}}
254
- try:
255
- if (
256
- self.model_fields[k].json_schema_extra["choices"] is not None
257
- and "choices" in self.model_fields[k].json_schema_extra
258
- ):
259
- self.choices[k] = self.model_fields[k].json_schema_extra["choices"]
260
- if self._validate_field(
261
- k, v, choices=self.choices[k], fix_=fix_, **kwargs[k]
262
- ):
263
- continue
264
- else:
265
- raise ValueError(f"{k} has no choices")
266
-
267
- except Exception as e:
268
- if self._validate_field(k, v, fix_=fix_, **kwargs[k]):
269
- continue
270
- else:
271
- raise ValueError(f"failed to validate field {k}") from e
272
-
273
- @property
274
- def in_(self):
275
- return {i: self.__getattribute__(i) for i in self.input_fields}
276
-
277
- @property
278
- def out(self):
279
- return {i: self.__getattribute__(i) for i in self.output_fields}
280
-
281
- def process(self, in_=None, out_=None):
282
- if in_:
283
- self._process_input(fix_=self.fix_input)
284
- self._validate_input_choices(fix_=self.fix_input)
285
- if out_:
286
- self._process_response(out_, fix_=self.fix_output)
287
- self._validate_output_choices(fix_=self.fix_output)
288
- return self
289
-
290
-
291
- class ScoredTemplate(PromptTemplate):
292
- confidence_score: float | None = Field(
293
- -1,
294
- description="a numeric score between 0 to 1 formatted in num:0.2f",
295
- )
296
- reason: str | None = Field(
297
- default_factory=str, description="brief reason for the given output"
298
- )
299
-
300
-
301
- # class Weather(PromptTemplate):
302
- # sunny: bool = Field(True, description="true if the weather is sunny outside else false")
303
- # rainy: bool = Field(False, description="true if it is raining outside else false")
304
- # play1: bool = Field(True, description="conduct play1")
305
- # play2: bool = Field(False, description="conduct play2")
306
- # signature: str = Field("sunny, rainy -> play1, play2")
307
-
308
- # predictor = Weather(
309
- # template_name="predictor",
310
- # task_ = "decides to conduct one of play1 and play2",
311
- # version_=0.1,
312
- # description_="predicts the weather and decides play",
313
- # signature = "sunny, play1 -> play2"
314
- # )
315
-
316
- # predictor.to_instruction()
@@ -1,22 +0,0 @@
1
- from .base_node import BaseNode, BaseRelatableNode, Tool, TOOL_TYPE
2
- from .data_node import DataNode
3
- from .data_logger import DLog, DataLogger
4
- from .structure import Relationship, Graph, Structure
5
- from .action_node import ActionNode, ActionSelection
6
- from .condition import Condition
7
-
8
- __all__ = [
9
- "BaseNode",
10
- "BaseRelatableNode",
11
- "Tool",
12
- "DataNode",
13
- "DLog",
14
- "DataLogger",
15
- "Relationship",
16
- "Graph",
17
- "Structure",
18
- "ActionNode",
19
- "TOOL_TYPE",
20
- "ActionSelection",
21
- "Condition",
22
- ]
@@ -1,29 +0,0 @@
1
- from enum import Enum
2
-
3
- from .base_node import BaseNode
4
-
5
-
6
- class ActionSelection(BaseNode):
7
-
8
- def __init__(self, action: str = "chat", action_kwargs=None):
9
- if action_kwargs is None:
10
- action_kwargs = {}
11
- super().__init__()
12
- self.action = action
13
- self.action_kwargs = action_kwargs
14
-
15
-
16
- class ActionNode(BaseNode):
17
-
18
- def __init__(
19
- self, instruction, action: str = "chat", tools=None, action_kwargs=None
20
- ):
21
- if tools is None:
22
- tools = []
23
- if action_kwargs is None:
24
- action_kwargs = {}
25
- super().__init__()
26
- self.instruction = instruction
27
- self.action = action
28
- self.tools = tools
29
- self.action_kwargs = action_kwargs
@@ -1,296 +0,0 @@
1
- from abc import ABC
2
- from functools import singledispatchmethod
3
- from typing import Any, TypeVar, Type, Callable
4
-
5
- import pandas as pd
6
- from pydantic import BaseModel, ValidationError
7
-
8
- from lionagi.libs import nested, convert, ParseUtil, SysUtil
9
-
10
- T = TypeVar("T") # Generic type for return type of from_obj method
11
-
12
-
13
- class BaseToObjectMixin(ABC, BaseModel):
14
-
15
- def to_json_str(self, *args, **kwargs) -> str:
16
- """
17
- Serializes the model instance into a JSON string.
18
-
19
- This method utilizes the model's `model_dump_json` method, typically available in Pydantic
20
- models or models with similar serialization mechanisms, to convert the instance into a JSON
21
- string. It supports passing arbitrary arguments to the underlying `model_dump_json` method.
22
-
23
- Args:
24
- *args: Variable-length argument list to be passed to `model_dump_json`.
25
- **kwargs: Arbitrary keyword arguments, with `by_alias=True` set by default to use
26
- model field aliases in the output JSON, if any.
27
-
28
- Returns:
29
- str: A JSON string representation of the model instance.
30
- """
31
- return self.model_dump_json(*args, by_alias=True, **kwargs)
32
-
33
- def to_dict(self, *args, **kwargs) -> dict[str, Any]:
34
- """
35
- Converts the model instance into a dictionary.
36
-
37
- Leveraging the model's `model_dump` method, this function produces a dictionary representation
38
- of the model. The dictionary keys correspond to the model's field names, with an option to use
39
- aliases instead of the original field names.
40
-
41
- Args:
42
- *args: Variable-length argument list for the `model_dump` method.
43
- **kwargs: Arbitrary keyword arguments. By default, `by_alias=True` is applied, indicating
44
- that field aliases should be used as keys in the resulting dictionary.
45
-
46
- Returns:
47
- dict[str, Any]: The dictionary representation of the model instance.
48
- """
49
- return self.model_dump(*args, by_alias=True, **kwargs)
50
-
51
- def to_xml(self) -> str:
52
- """
53
- Serializes the model instance into an XML string.
54
-
55
- This method converts the model instance into an XML format. It first transforms the instance
56
- into a dictionary and then recursively constructs an XML tree representing the model's data.
57
- The root element of the XML tree is named after the class of the model instance.
58
-
59
- Returns:
60
- str: An XML string representation of the model instance.
61
- """
62
-
63
- import xml.etree.ElementTree as ET
64
-
65
- root = ET.Element(self.__class__.__name__)
66
-
67
- def convert(dict_obj, parent):
68
- for key, val in dict_obj.items():
69
- if isinstance(val, dict):
70
- element = ET.SubElement(parent, key)
71
- convert(val, element)
72
- else:
73
- element = ET.SubElement(parent, key)
74
- element.text = str(val)
75
-
76
- convert(self.to_dict(), root)
77
- return ET.tostring(root, encoding="unicode")
78
-
79
- def to_pd_series(self, *args, pd_kwargs: dict | None = None, **kwargs) -> pd.Series:
80
- """
81
- Converts the model instance into a pandas Series.
82
-
83
- This method first transforms the model instance into a dictionary and then constructs a pandas
84
- Series from it. The Series' index corresponds to the model's field names, with an option to
85
- customize the Series creation through `pd_kwargs`.
86
-
87
- Args:
88
- *args: Variable-length argument list for the `to_dict` method.
89
- pd_kwargs (dict | None): Optional dictionary of keyword arguments to pass to the pandas
90
- Series constructor. Defaults to None, in which case an empty
91
- dictionary is used.
92
- **kwargs: Arbitrary keyword arguments for the `to_dict` method, influencing the dictionary
93
- representation used for Series creation.
94
-
95
- Returns:
96
- pd.Series: A pandas Series representation of the model instance.
97
- """
98
- pd_kwargs = {} if pd_kwargs is None else pd_kwargs
99
- dict_ = self.to_dict(*args, **kwargs)
100
- return pd.Series(dict_, **pd_kwargs)
101
-
102
-
103
- class BaseFromObjectMixin(ABC, BaseModel):
104
-
105
- @singledispatchmethod
106
- @classmethod
107
- def from_obj(cls: Type[T], obj: Any, *args, **kwargs) -> T:
108
- raise NotImplementedError(f"Unsupported type: {type(obj)}")
109
-
110
- @from_obj.register(dict)
111
- @classmethod
112
- def _from_dict(cls, obj: dict, *args, **kwargs) -> T:
113
- return cls.model_validate(obj, *args, **kwargs)
114
-
115
- @from_obj.register(str)
116
- @classmethod
117
- def _from_str(cls, obj: str, *args, fuzzy_parse=False, **kwargs) -> T:
118
- obj = ParseUtil.fuzzy_parse_json(obj) if fuzzy_parse else convert.to_dict(obj)
119
- try:
120
- return cls.from_obj(obj, *args, **kwargs)
121
- except ValidationError as e:
122
- raise ValueError(f"Invalid JSON for deserialization: {e}") from e
123
-
124
- @from_obj.register(list)
125
- @classmethod
126
- def _from_list(cls, obj: list[Any], *args, **kwargs) -> list[T]:
127
- return [cls.from_obj(item, *args, **kwargs) for item in obj]
128
-
129
- @from_obj.register(pd.Series)
130
- @classmethod
131
- def _from_pd_series(cls, obj: pd.Series, *args, pd_kwargs=None, **kwargs) -> T:
132
- if pd_kwargs is None:
133
- pd_kwargs = {}
134
- return cls.from_obj(obj.to_dict(**pd_kwargs), *args, **kwargs)
135
-
136
- @from_obj.register(pd.DataFrame)
137
- @classmethod
138
- def _from_pd_dataframe(
139
- cls, obj: pd.DataFrame, *args, pd_kwargs=None, **kwargs
140
- ) -> list[T]:
141
- if pd_kwargs is None:
142
- pd_kwargs = {}
143
- return [
144
- cls.from_obj(row, *args, **pd_kwargs, **kwargs) for _, row in obj.iterrows()
145
- ]
146
-
147
- @from_obj.register(BaseModel)
148
- @classmethod
149
- def _from_base_model(cls, obj: BaseModel, pydantic_kwargs=None, **kwargs) -> T:
150
- if pydantic_kwargs is None:
151
- pydantic_kwargs = {"by_alias": True}
152
- config_ = {**obj.model_dump(**pydantic_kwargs), **kwargs}
153
- return cls.from_obj(**config_)
154
-
155
-
156
- class BaseMetaManageMixin(ABC, BaseModel):
157
-
158
- def meta_keys(self, flattened: bool = False, **kwargs) -> list[str]:
159
- """
160
- Retrieves a list of metadata keys.
161
-
162
- Args:
163
- flattened (bool): If True, returns keys from a flattened metadata structure.
164
- **kwargs: Additional keyword arguments passed to the flattening function.
165
-
166
- Returns:
167
- list[str]: List of metadata keys.
168
- """
169
- if flattened:
170
- return nested.get_flattened_keys(self.metadata, **kwargs)
171
- return list(self.metadata.keys())
172
-
173
- def meta_has_key(self, key: str, flattened: bool = False, **kwargs) -> bool:
174
- """
175
- Checks if a specified key exists in the metadata.
176
-
177
- Args:
178
- key (str): The key to check.
179
- flattened (bool): If True, checks within a flattened metadata structure.
180
- **kwargs: Additional keyword arguments for flattening.
181
-
182
- Returns:
183
- bool: True if key exists, False otherwise.
184
- """
185
- if flattened:
186
- return key in nested.get_flattened_keys(self.metadata, **kwargs)
187
- return key in self.metadata
188
-
189
- def meta_get(
190
- self, key: str, indices: list[str | int] = None, default: Any = None
191
- ) -> Any:
192
- """
193
- Retrieves the value associated with a given key from the metadata.
194
-
195
- Args:
196
- key (str): The key for the desired value.
197
- indices: Optional indices for nested retrieval.
198
- default (Any): The default value to return if the key is not found.
199
-
200
- Returns:
201
- Any: The value associated with the key or the default value.
202
- """
203
- if indices:
204
- return nested.nget(self.metadata, key, indices, default)
205
- return self.metadata.get(key, default)
206
-
207
- def meta_change_key(self, old_key: str, new_key: str) -> bool:
208
- """
209
- Renames a key in the metadata.
210
-
211
- Args:
212
- old_key (str): The current key name.
213
- new_key (str): The new key name.
214
-
215
- Returns:
216
- bool: True if the key was changed, False otherwise.
217
- """
218
- if old_key in self.metadata:
219
- SysUtil.change_dict_key(self.metadata, old_key, new_key)
220
- return True
221
- return False
222
-
223
- def meta_insert(self, indices: str | list, value: Any, **kwargs) -> bool:
224
- """
225
- Inserts a value into the metadata at specified indices.
226
-
227
- Args:
228
- indices (str | list): The indices where the value should be inserted.
229
- value (Any): The value to insert.
230
- **kwargs: Additional keyword arguments.
231
-
232
- Returns:
233
- bool: True if the insertion was successful, False otherwise.
234
- """
235
- return nested.ninsert(self.metadata, indices, value, **kwargs)
236
-
237
- # ToDo: do a nested pop
238
- def meta_pop(self, key: str, default: Any = None) -> Any:
239
- """
240
- Removes a key from the metadata and returns its value.
241
-
242
- Args:
243
- key (str): The key to remove.
244
- default (Any): The default value to return if the key is not found.
245
-
246
- Returns:
247
- Any: The value of the removed key or the default value.
248
- """
249
- return self.metadata.pop(key, default)
250
-
251
- def meta_merge(
252
- self, additional_metadata: dict[str, Any], overwrite: bool = False, **kwargs
253
- ) -> None:
254
- """
255
- Merges additional metadata into the existing metadata.
256
-
257
- Args:
258
- additional_metadata (dict[str, Any]): The metadata to merge in.
259
- overwrite (bool): If True, existing keys will be overwritten by those in additional_metadata.
260
- **kwargs: Additional keyword arguments for the merge.
261
-
262
- Returns:
263
- None
264
- """
265
- nested.nmerge(
266
- [self.metadata, additional_metadata], overwrite=overwrite, **kwargs
267
- )
268
-
269
- for key, value in additional_metadata.items():
270
- if overwrite or key not in self.metadata:
271
- self.metadata[key] = value
272
-
273
- def meta_clear(self) -> None:
274
- """
275
- Clears all metadata.
276
-
277
- Returns:
278
- None
279
- """
280
- self.metadata.clear()
281
-
282
- def meta_filter(self, condition: Callable[[Any, Any], bool]) -> dict[str, Any]:
283
- """
284
- Filters the metadata based on a condition.
285
-
286
- Args:
287
- condition (Callable[[Any, Any], bool]): The condition function to apply.
288
-
289
- Returns:
290
- dict[str, Any]: The filtered metadata.
291
- """
292
- return nested.nfilter(self.metadata, condition)
293
-
294
-
295
- class BaseComponentMixin(BaseFromObjectMixin, BaseToObjectMixin, BaseMetaManageMixin):
296
- pass