lionagi 0.1.2__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 +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 +76 -0
  94. lionagi/core/work/work_function.py +101 -0
  95. lionagi/core/work/work_queue.py +103 -0
  96. lionagi/core/work/worker.py +258 -0
  97. lionagi/core/work/worklog.py +120 -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.1.dist-info/LICENSE +202 -0
  168. lionagi-0.2.1.dist-info/METADATA +272 -0
  169. lionagi-0.2.1.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.1.dist-info}/WHEEL +0 -0
  268. {lionagi-0.1.2.dist-info → lionagi-0.2.1.dist-info}/top_level.txt +0 -0
@@ -1,323 +0,0 @@
1
- import contextlib
2
- from datetime import datetime
3
- from typing import Any
4
-
5
- from lionagi.libs import convert, nested, func_call, dataframe
6
-
7
- from lionagi.core.messages.schema import (
8
- System,
9
- Instruction,
10
- Response,
11
- BaseMessage,
12
- BranchColumns,
13
- )
14
-
15
- CUSTOM_TYPE = dict[str, Any] | str | list[Any] | None
16
-
17
-
18
- class MessageUtil:
19
-
20
- @staticmethod
21
- def create_message(
22
- system: System | CUSTOM_TYPE = None,
23
- instruction: Instruction | CUSTOM_TYPE = None,
24
- context: str | dict[str, Any] | None = None,
25
- response: Response | CUSTOM_TYPE = None,
26
- output_fields=None,
27
- **kwargs,
28
- ) -> BaseMessage:
29
- """
30
- Creates a message object based on the input parameters, ensuring only one message role is present.
31
-
32
- Args:
33
- system: Information for creating a System message.
34
- instruction: Information for creating an Instruction message.
35
- context: Context information for the message.
36
- response: Response data for creating a message.
37
- **kwargs: Additional keyword arguments for message creation.
38
-
39
- Returns:
40
- A message object of the appropriate type based on provided inputs.
41
-
42
- Raises:
43
- ValueError: If more than one of the role-specific parameters are provided.
44
- """
45
- if sum(func_call.lcall([system, instruction, response], bool)) != 1:
46
- raise ValueError("Error: Message must have one and only one role.")
47
-
48
- if isinstance(system, System):
49
- return system
50
- elif isinstance(instruction, Instruction):
51
- return instruction
52
- elif isinstance(response, Response):
53
- return response
54
-
55
- msg = 0
56
- if response:
57
- msg = Response(response=response, **kwargs)
58
- elif instruction:
59
- msg = Instruction(
60
- instruction=instruction,
61
- context=context,
62
- output_fields=output_fields,
63
- **kwargs,
64
- )
65
- elif system:
66
- msg = System(system=system, **kwargs)
67
- return msg
68
-
69
- @staticmethod
70
- def validate_messages(messages: dataframe.ln_DataFrame) -> bool:
71
- """
72
- Validates the format and content of a DataFrame containing messages.
73
-
74
- Args:
75
- messages: A DataFrame with message information.
76
-
77
- Returns:
78
- True if the messages DataFrame is correctly formatted, False otherwise.
79
-
80
- Raises:
81
- ValueError: If the DataFrame does not match expected schema or content requirements.
82
- """
83
-
84
- if list(messages.columns) != BranchColumns.COLUMNS.value:
85
- raise ValueError("Invalid messages dataframe. Unmatched columns.")
86
- if messages.isnull().values.any():
87
- raise ValueError("Invalid messages dataframe. Cannot have null.")
88
- if any(
89
- role not in ["system", "user", "assistant"]
90
- for role in messages["role"].unique()
91
- ):
92
- raise ValueError(
93
- 'Invalid messages dataframe. Cannot have role other than ["system", "user", "assistant"].'
94
- )
95
- for cont in messages["content"]:
96
- if cont.startswith("Sender"):
97
- cont = cont.split(":", 1)[1]
98
- try:
99
- convert.to_dict(cont)
100
- except:
101
- raise ValueError(
102
- "Invalid messages dataframe. Content expect json string."
103
- )
104
- return True
105
-
106
- @staticmethod
107
- def sign_message(
108
- messages: dataframe.ln_DataFrame, sender: str
109
- ) -> dataframe.ln_DataFrame:
110
- """
111
- Appends a sender prefix to the 'content' field of each message in a DataFrame.
112
-
113
- Args:
114
- messages: A DataFrame containing message data.
115
- sender: The identifier of the sender to prefix to message contents.
116
-
117
- Returns:
118
- A DataFrame with sender-prefixed message contents.
119
-
120
- Raises:
121
- ValueError: If the sender is None or the value is 'none'.
122
- """
123
-
124
- if sender is None or convert.strip_lower(sender) == "none":
125
- raise ValueError("sender cannot be None")
126
- df = convert.to_df(messages)
127
-
128
- for i in df.index:
129
- if not df.loc[i, "content"].startswith("Sender"):
130
- df.loc[i, "content"] = f"Sender {sender}: {df.loc[i, 'content']}"
131
- else:
132
- content = df.loc[i, "content"].split(":", 1)[1]
133
- df.loc[i, "content"] = f"Sender {sender}: {content}"
134
-
135
- return convert.to_df(df)
136
-
137
- @staticmethod
138
- def filter_messages_by(
139
- messages: dataframe.ln_DataFrame,
140
- role: str | None = None,
141
- sender: str | None = None,
142
- start_time: datetime | None = None,
143
- end_time: datetime | None = None,
144
- content_keywords: str | list[str] | None = None,
145
- case_sensitive: bool = False,
146
- ) -> dataframe.ln_DataFrame:
147
- """
148
- Filters messages in a DataFrame based on specified criteria.
149
-
150
- Args:
151
- messages: The DataFrame to filter.
152
- role: The role to filter by.
153
- sender: The sender to filter by.
154
- start_time: The minimum timestamp for messages.
155
- end_time: The maximum timestamp for messages.
156
- content_keywords: Keywords to look for in message content.
157
- case_sensitive: Whether the keyword search should be case-sensitive.
158
-
159
- Returns:
160
- A filtered DataFrame based on the specified criteria.
161
- """
162
-
163
- try:
164
- outs = messages.copy()
165
-
166
- if content_keywords:
167
- outs = MessageUtil.search_keywords(
168
- outs, keywords=content_keywords, case_sensitive=case_sensitive
169
- )
170
-
171
- outs = outs[outs["role"] == role] if role else outs
172
- outs = outs[outs["sender"] == sender] if sender else outs
173
- outs = outs[outs["timestamp"] > start_time] if start_time else outs
174
- outs = outs[outs["timestamp"] < end_time] if end_time else outs
175
-
176
- return convert.to_df(outs)
177
-
178
- except Exception as e:
179
- raise ValueError(f"Error in filtering messages: {e}") from e
180
-
181
- @staticmethod
182
- def remove_message(messages: dataframe.ln_DataFrame, node_id: str) -> bool:
183
- """
184
- Removes a message from the DataFrame based on its node ID.
185
-
186
- Args:
187
- messages: The DataFrame containing messages.
188
- node_id: The unique identifier of the message to be removed.
189
-
190
- Returns:
191
- If any messages are removed.
192
-
193
- Examples:
194
- >>> messages = dataframe.ln_DataFrame([...])
195
- >>> updated_messages = MessageUtil.remove_message(messages, "node_id_123")
196
- """
197
-
198
- initial_length = len(messages)
199
- messages.drop(messages[messages["node_id"] == node_id].index, inplace=True)
200
- messages.reset_index(drop=True, inplace=True)
201
-
202
- return len(messages) < initial_length
203
-
204
- @staticmethod
205
- def get_message_rows(
206
- messages: dataframe.ln_DataFrame,
207
- sender: str | None = None,
208
- role: str | None = None,
209
- n: int = 1,
210
- sign_: bool = False,
211
- from_: str = "front",
212
- ) -> dataframe.ln_DataFrame:
213
- """
214
- Retrieves a specified number of message rows based on sender and role.
215
-
216
- Args:
217
- messages: The DataFrame containing messages.
218
- sender: Filter messages by the sender.
219
- role: Filter messages by the role.
220
- n: The number of messages to retrieve.
221
- sign_: If True, sign the message with the sender.
222
- from_: Specify retrieval from the 'front' or 'last' of the DataFrame.
223
-
224
- Returns:
225
- A DataFrame containing the filtered messages.
226
- """
227
-
228
- outs = ""
229
-
230
- if from_ == "last":
231
- if sender is None and role is None:
232
- outs = messages.iloc[-n:]
233
- elif sender and role:
234
- outs = messages[
235
- (messages["sender"] == sender) & (messages["role"] == role)
236
- ].iloc[-n:]
237
-
238
- elif sender:
239
- outs = messages[messages["sender"] == sender].iloc[-n:]
240
- else:
241
- outs = messages[messages["role"] == role].iloc[-n:]
242
-
243
- elif from_ == "front":
244
- if sender is None and role is None:
245
- outs = messages.iloc[:n]
246
- elif sender and role:
247
- outs = messages[
248
- (messages["sender"] == sender) & (messages["role"] == role)
249
- ].iloc[:n]
250
- elif sender:
251
- outs = messages[messages["sender"] == sender].iloc[:n]
252
- else:
253
- outs = messages[messages["role"] == role].iloc[:n]
254
-
255
- return MessageUtil.sign_message(outs, sender) if sign_ else outs
256
-
257
- @staticmethod
258
- def extend(
259
- df1: dataframe.ln_DataFrame, df2: dataframe.ln_DataFrame, **kwargs
260
- ) -> dataframe.ln_DataFrame:
261
- """
262
- Extends a DataFrame with another DataFrame's rows, ensuring no duplicate 'node_id'.
263
-
264
- Args:
265
- df1: The primary DataFrame.
266
- df2: The DataFrame to merge with the primary DataFrame.
267
- **kwargs: Additional keyword arguments for `drop_duplicates`.
268
-
269
- Returns:
270
- A DataFrame combined from df1 and df2 with duplicates removed based on 'node_id'.
271
-
272
- Examples:
273
- >>> df_main = dataframe.ln_DataFrame([...])
274
- >>> df_additional = dataframe.ln_DataFrame([...])
275
- >>> combined_df = MessageUtil.extend(df_main, df_additional, keep='first')
276
- """
277
-
278
- MessageUtil.validate_messages(df2)
279
- try:
280
- if len(df2.dropna(how="all")) > 0 and len(df1.dropna(how="all")) > 0:
281
- df = convert.to_df([df1, df2])
282
- df.drop_duplicates(
283
- inplace=True, subset=["node_id"], keep="first", **kwargs
284
- )
285
- return convert.to_df(df)
286
- except Exception as e:
287
- raise ValueError(f"Error in extending messages: {e}") from e
288
-
289
- @staticmethod
290
- def to_markdown_string(messages: dataframe.ln_DataFrame) -> str:
291
- """
292
- Converts messages in a DataFrame to a Markdown-formatted string for easy reading.
293
-
294
- Args:
295
- messages: A DataFrame containing messages with columns for 'role' and 'content'.
296
-
297
- Returns:
298
- A string formatted in Markdown, where each message's content is presented
299
- according to its role in a readable format.
300
- """
301
-
302
- answers = []
303
- for _, i in messages.iterrows():
304
- content = convert.to_dict(i.content)
305
-
306
- if i.role == "assistant":
307
- with contextlib.suppress(Exception):
308
- a = nested.nget(content, ["action_response", "func"])
309
- b = nested.nget(content, ["action_response", "arguments"])
310
- c = nested.nget(content, ["action_response", "output"])
311
- if a is not None:
312
- answers.extend(
313
- (f"Function: {a}", f"Arguments: {b}", f"Output: {c}")
314
- )
315
- else:
316
- answers.append(nested.nget(content, ["assistant_response"]))
317
- elif i.role == "user":
318
- with contextlib.suppress(Exception):
319
- answers.append(nested.nget(content, ["instruction"]))
320
- else:
321
- with contextlib.suppress(Exception):
322
- answers.append(nested.nget(content, ["system_info"]))
323
- return "\n".join(answers)
@@ -1,19 +0,0 @@
1
- from .predict import predict
2
- from .select import select
3
- from .score import score
4
- from .react import react
5
- from .vote import vote
6
- from .plan import plan
7
- from .cot import chain_of_thoughts, chain_of_react
8
-
9
-
10
- __all__ = [
11
- "predict",
12
- "select",
13
- "score",
14
- "vote",
15
- "react",
16
- "plan",
17
- "chain_of_thoughts",
18
- "chain_of_react",
19
- ]
@@ -1,123 +0,0 @@
1
- from lionagi.libs import convert
2
-
3
- from lionagi.core.direct.predict import predict
4
- from lionagi.core.direct.plan import plan
5
- from lionagi.core.direct.react import react
6
-
7
- from .utils import _process_tools
8
-
9
-
10
- async def chain_of_thoughts(
11
- sentence=None,
12
- branch=None,
13
- instruction=None,
14
- reason=False,
15
- confidence_score=False,
16
- num_steps=3,
17
- directive_kwargs={},
18
- return_branch=False,
19
- **kwargs,
20
- ):
21
-
22
- out_, outs, answer, reasons, confidence_score = "", [], "", [], 0
23
- if branch is not None:
24
- out_ = await plan(
25
- sentence,
26
- branch=branch,
27
- instruction=instruction,
28
- num_steps=num_steps,
29
- **kwargs,
30
- )
31
- else:
32
- out_, branch = await plan(
33
- sentence,
34
- instruction=instruction,
35
- branch=branch,
36
- num_steps=num_steps,
37
- return_branch=True,
38
- **kwargs,
39
- )
40
-
41
- for i in range(len(out_.plan)):
42
- _out = await predict(
43
- branch=branch,
44
- instruction=out_.plan[f"step_{i+1}"],
45
- reason=reason,
46
- confidence_score=confidence_score,
47
- **directive_kwargs,
48
- )
49
- answer += _out.answer
50
- if reason:
51
- reasons.append(_out.reason)
52
- if confidence_score:
53
- confidence_score += _out.confidence_score
54
- outs.append(_out)
55
-
56
- setattr(out_, "chain_output", outs)
57
- setattr(out_, "chain_answer", answer)
58
-
59
- if reason:
60
- setattr(out_, "chain_reasons", reasons)
61
- if confidence_score:
62
- setattr(out_, "chain_confidence_score", confidence_score / len(outs))
63
-
64
- if return_branch:
65
- return out_, branch
66
-
67
- return out_
68
-
69
-
70
- async def chain_of_react(
71
- sentence=None,
72
- branch=None,
73
- instruction=None,
74
- num_steps=3,
75
- tools=None,
76
- directive_system=None,
77
- directive_kwargs={},
78
- return_branch=False,
79
- **kwargs,
80
- ):
81
- out_, outs, reasons, actions, action_responses = "", [], [], [], []
82
- if branch is not None:
83
- out_ = await plan(
84
- sentence,
85
- branch=branch,
86
- instruction=instruction,
87
- num_steps=num_steps,
88
- **kwargs,
89
- )
90
- else:
91
- out_, branch = await plan(
92
- sentence,
93
- instruction=instruction,
94
- branch=branch,
95
- num_steps=num_steps,
96
- return_branch=True,
97
- **kwargs,
98
- )
99
-
100
- _process_tools(tools, branch)
101
-
102
- for i in range(len(out_.plan)):
103
- _out = await react(
104
- branch=branch,
105
- system=directive_system,
106
- instruction=out_.plan[f"step_{i+1}"],
107
- **directive_kwargs,
108
- )
109
- outs.append(_out)
110
- reasons.append(_out.reason)
111
- actions.append(_out.actions)
112
- if _out.action_needed:
113
- action_responses.append(_out.action_response)
114
-
115
- setattr(out_, "chain_output", convert.to_list(outs))
116
- setattr(out_, "chain_reason", convert.to_list(reasons))
117
- setattr(out_, "chain_actions", convert.to_list(actions))
118
- setattr(out_, "chain_action_response", convert.to_list(action_responses))
119
-
120
- if return_branch:
121
- return out_, branch
122
-
123
- return out_
@@ -1,164 +0,0 @@
1
- # plan.py
2
-
3
- from lionagi.libs import func_call, ParseUtil
4
- from lionagi.integrations.bridge.pydantic_.pydantic_bridge import Field
5
- from lionagi.core.form.scored_form import ScoredForm
6
- from lionagi.core.branch.branch import Branch
7
-
8
-
9
- class PlanTemplate(ScoredForm):
10
- template_name: str = "default_plan"
11
- sentence: str | list | dict = Field(
12
- default_factory=str,
13
- description="the given sentence(s) or context to generate a plan for",
14
- )
15
- plan: dict | str = Field(
16
- default_factory=dict,
17
- description="the generated step by step plan, return as a dictionary following {step_n: {plan: ..., reason: ...}} format",
18
- )
19
- signature: str = "sentence -> plan"
20
-
21
- def __init__(
22
- self,
23
- sentence=None,
24
- instruction=None,
25
- confidence_score=False,
26
- reason=False,
27
- num_step=3,
28
- **kwargs,
29
- ):
30
- super().__init__(**kwargs)
31
-
32
- self.sentence = sentence
33
- self.task = f"Generate a {num_step}_step plan based on the given context. Instruction: {instruction}."
34
-
35
- if reason:
36
- self.output_fields.append("reason")
37
-
38
- if confidence_score:
39
- self.output_fields.append("confidence_score")
40
-
41
-
42
- async def _plan(
43
- sentence,
44
- *,
45
- instruction=None,
46
- branch=None,
47
- confidence_score=False,
48
- reason=False,
49
- retries=2,
50
- delay=0.5,
51
- backoff_factor=2,
52
- default_value=None,
53
- timeout=None,
54
- branch_name=None,
55
- system=None,
56
- messages=None,
57
- service=None,
58
- sender=None,
59
- llmconfig=None,
60
- tools=None,
61
- datalogger=None,
62
- persist_path=None,
63
- tool_manager=None,
64
- return_branch=False,
65
- **kwargs,
66
- ):
67
- if "temperature" not in kwargs:
68
- kwargs["temperature"] = 0.1
69
-
70
- instruction = instruction or ""
71
-
72
- branch = branch or Branch(
73
- name=branch_name,
74
- system=system,
75
- messages=messages,
76
- service=service,
77
- sender=sender,
78
- llmconfig=llmconfig,
79
- tools=tools,
80
- datalogger=datalogger,
81
- persist_path=persist_path,
82
- tool_manager=tool_manager,
83
- )
84
-
85
- _template = PlanTemplate(
86
- sentence=sentence,
87
- instruction=instruction,
88
- confidence_score=confidence_score,
89
- reason=reason,
90
- )
91
-
92
- await func_call.rcall(
93
- branch.chat,
94
- form=_template,
95
- retries=retries,
96
- delay=delay,
97
- backoff_factor=backoff_factor,
98
- default=default_value,
99
- timeout=timeout,
100
- **kwargs,
101
- )
102
-
103
- _template.plan = ParseUtil.fuzzy_parse_json(_template.plan)
104
-
105
- return (_template, branch) if return_branch else _template
106
-
107
-
108
- async def plan(
109
- sentence,
110
- *,
111
- instruction=None,
112
- num_instances=1,
113
- branch=None,
114
- confidence_score=False,
115
- reason=False,
116
- retries=2,
117
- delay=0.5,
118
- backoff_factor=2,
119
- default_value=None,
120
- timeout=None,
121
- branch_name=None,
122
- system=None,
123
- messages=None,
124
- service=None,
125
- sender=None,
126
- llmconfig=None,
127
- tools=None,
128
- datalogger=None,
129
- persist_path=None,
130
- tool_manager=None,
131
- return_branch=False,
132
- **kwargs,
133
- ):
134
- async def _inner(i=0):
135
- return await _plan(
136
- sentence=sentence,
137
- instruction=instruction,
138
- branch=branch,
139
- confidence_score=confidence_score,
140
- reason=reason,
141
- retries=retries,
142
- delay=delay,
143
- backoff_factor=backoff_factor,
144
- default_value=default_value,
145
- timeout=timeout,
146
- branch_name=branch_name,
147
- system=system,
148
- messages=messages,
149
- service=service,
150
- sender=sender,
151
- llmconfig=llmconfig,
152
- tools=tools,
153
- datalogger=datalogger,
154
- persist_path=persist_path,
155
- tool_manager=tool_manager,
156
- return_branch=return_branch,
157
- **kwargs,
158
- )
159
-
160
- if num_instances == 1:
161
- return await _inner()
162
-
163
- elif num_instances > 1:
164
- return await func_call.alcall(range(num_instances), _inner)