lionagi 0.0.312__py3-none-any.whl → 0.2.1__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
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