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,254 +0,0 @@
1
- # from lionagi.core.branch.branch import Branch
2
- # from lionagi.core.session.session import Session
3
-
4
- # import unittest
5
- # from unittest.mock import patch, call, MagicMock
6
- # import pandas as pd
7
- # import json
8
- # from datetime import datetime
9
-
10
-
11
- # class TestSession(unittest.TestCase):
12
-
13
- # def setUp(self):
14
- # mock_branch = MagicMock()
15
-
16
- # mock_branch.to_csv_file = MagicMock()
17
- # mock_branch.to_json_file = MagicMock()
18
-
19
- # mock_datalogger = MagicMock()
20
- # mock_datalogger.to_csv_file = MagicMock()
21
- # mock_datalogger.to_json_file = MagicMock()
22
-
23
- # # Assign the mocked datalogger to the mock_branch
24
- # mock_branch.datalogger = mock_datalogger
25
-
26
- # self.branch1 = mock_branch(name="branch1")
27
- # self.branch1.messages = pd.DataFrame(
28
- # [{
29
- # "node_id": "1", "timestamp": "2021-01-01 00:00:00",
30
- # "role": "system", "sender": "system",
31
- # "content": json.dumps({"system_info": "System message"}),
32
- # }]
33
- # )
34
- # self.branch2 = mock_branch(name="branch2")
35
- # self.branch1.messages = pd.DataFrame(
36
- # [{
37
- # "node_id": "2", "timestamp": "2021-01-01 00:01:00",
38
- # "role": "user", "sender": "user1",
39
- # "content": json.dumps({"instruction": "User message"}),
40
- # }]
41
- # )
42
-
43
- # branches = {"branch1": self.branch1, "branch2": self.branch2}
44
-
45
- # self.session = Session(
46
- # branches=branches, default_branch_name="branch1",
47
- # default_branch=branches["branch1"], )
48
- # self.session.mail_manager = MagicMock()
49
-
50
- # # def test_from_csv_initialization(self):
51
- # # """Test Session initialization from a CSV file."""
52
- # # mock_df = pd.DataFrame(
53
- # # {
54
- # # "node_id": ["1", "2"],
55
- # # "timestamp": [datetime(2021, 1, 1), datetime(2021, 1, 1)],
56
- # # "role": ["system", "user"],
57
- # # "sender": ["system", "user1"],
58
- # # "content": [
59
- # # json.dumps({"system_info": "System message"}),
60
- # # json.dumps({"instruction": "User message"}),
61
- # # ],
62
- # # }
63
- # # )
64
- # # filepath = "path/to/mock.csv"
65
-
66
- # # with patch("pandas.read_csv", return_value=mock_df) as mock_read_csv:
67
- # # session = Session.from_csv(filepath)
68
- # # mock_read_csv.assert_called_once_with(filepath)
69
- # # pd.testing.assert_frame_equal(session.messages, mock_df)
70
-
71
- # # def test_from_json_initialization(self):
72
- # # """Test Session initialization from a CSV file."""
73
- # # mock_df = pd.DataFrame(
74
- # # {
75
- # # "node_id": ["1", "2"],
76
- # # "timestamp": [datetime(2021, 1, 1), datetime(2021, 1, 1)],
77
- # # "role": ["system", "user"],
78
- # # "sender": ["system", "user1"],
79
- # # "content": [
80
- # # json.dumps({"system_info": "System message"}),
81
- # # json.dumps({"instruction": "User message"}),
82
- # # ],
83
- # # }
84
- # # )
85
- # # filepath = "path/to/mock.json"
86
-
87
- # # with patch("pandas.read_json", return_value=mock_df) as mock_read_json:
88
- # # session = Session.from_json(filepath)
89
- # # mock_read_json.assert_called_once_with(filepath)
90
- # # pd.testing.assert_frame_equal(session.messages, mock_df)
91
-
92
- # def test_to_csv_file(self):
93
- # """Ensure to_csv_file calls each branch's to_csv_file method."""
94
- # filename = "test_export.csv"
95
- # self.session.to_csv_file(filename=filename)
96
-
97
- # for name, branch in self.session.branches.items():
98
- # # Verify it was called twice
99
- # self.assertEqual(branch.to_csv_file.call_count, 2)
100
-
101
- # # Verify the arguments of the last call
102
- # expected_filename = f"{name}_{filename}"
103
- # self.assertIn(
104
- # expected_filename,
105
- # ["branch1_test_export.csv", "branch2_test_export.csv"], )
106
-
107
- # def test_to_json_file(self):
108
- # """Ensure to_json_file calls each branch's to_json_file method."""
109
- # filename = "test_export.json"
110
- # self.session.to_json_file(filename=filename)
111
-
112
- # for name, branch in self.session.branches.items():
113
- # # Verify it was called twice
114
- # self.assertEqual(branch.to_json_file.call_count, 2)
115
-
116
- # # Verify the arguments of the last call
117
- # expected_filename = f"{name}_{filename}"
118
- # self.assertIn(
119
- # expected_filename,
120
- # ["branch1_test_export.json", "branch2_test_export.json"], )
121
-
122
- # def test_log_to_csv(self):
123
- # """Ensure log_to_csv calls each branch's log_to_csv method."""
124
- # filename = "test_export.csv"
125
- # self.session.log_to_csv(filename=filename)
126
-
127
- # for name, branch in self.session.branches.items():
128
- # # Verify it was called twice
129
- # self.assertEqual(branch.log_to_csv.call_count, 2)
130
-
131
- # # Verify the arguments of the last call
132
- # expected_filename = f"{name}_{filename}"
133
- # self.assertIn(
134
- # expected_filename,
135
- # ["branch1_test_export.csv", "branch2_test_export.csv"], )
136
-
137
- # def test_log_to_json(self):
138
- # """Ensure log_to_json calls each branch's log_to_json method."""
139
- # filename = "test_export.json"
140
- # self.session.log_to_json(filename=filename)
141
-
142
- # for name, branch in self.session.branches.items():
143
- # # Verify it was called twice
144
- # self.assertEqual(branch.log_to_json.call_count, 2)
145
-
146
- # # Verify the arguments of the last call
147
- # expected_filename = f"{name}_{filename}"
148
- # self.assertIn(
149
- # expected_filename,
150
- # ["branch1_test_export.json", "branch2_test_export.json"], )
151
-
152
- # def test_all_messages(self):
153
- # """Test aggregation of all messages across branches."""
154
- # expected_df = pd.concat(
155
- # [self.branch1.messages, self.branch2.messages], ignore_index=True
156
- # )
157
-
158
- # actual_df = self.session.all_messages
159
-
160
- # pd.testing.assert_frame_equal(actual_df, expected_df)
161
-
162
- # def test_new_branch_creation(self):
163
- # """Test creating a new branch successfully."""
164
- # branch_name = "test_branch"
165
- # self.session.new_branch(branch_name=branch_name)
166
- # self.assertIn(branch_name, self.session.branches)
167
-
168
- # def test_new_branch_duplicate_name(self):
169
- # """Test error handling for duplicate branch names."""
170
- # branch_name = "test_branch"
171
- # self.session.new_branch(branch_name=branch_name)
172
- # with self.assertRaises(ValueError):
173
- # self.session.new_branch(branch_name=branch_name)
174
-
175
- # def test_get_branch_by_name(self):
176
- # """Test retrieving a branch by its name."""
177
- # branch_name = "test_branch"
178
- # self.session.new_branch(branch_name=branch_name)
179
- # branch = self.session.get_branch(branch_name)
180
- # self.assertIsInstance(branch, Branch)
181
-
182
- # def test_get_branch_invalid_name(self):
183
- # """Test error handling for invalid branch names."""
184
- # with self.assertRaises(ValueError):
185
- # self.session.get_branch("nonexistent_branch")
186
-
187
- # def test_change_default_branch(self):
188
- # """Test changing the default branch."""
189
- # branch_name = "new_default"
190
- # self.session.new_branch(branch_name=branch_name)
191
- # self.session.change_default_branch(branch_name)
192
- # self.assertEqual(self.session.default_branch_name, branch_name)
193
-
194
- # def test_delete_branch(self):
195
- # """Test deleting a branch."""
196
- # branch_name = "test_branch"
197
- # self.session.new_branch(branch_name=branch_name)
198
- # self.session.delete_branch(branch_name)
199
- # self.assertNotIn(branch_name, self.session.branches)
200
-
201
- # def test_delete_default_branch_error(self):
202
- # """Test error when trying to delete the default branch."""
203
- # with self.assertRaises(ValueError):
204
- # self.session.delete_branch(self.session.default_branch_name)
205
-
206
- # def test_merge_branch(self):
207
- # """Test merging two branches."""
208
- # from_branch = "source_branch"
209
- # to_branch = "target_branch"
210
- # self.session.new_branch(branch_name=from_branch)
211
- # self.session.new_branch(branch_name=to_branch)
212
- # self.session.merge_branch(
213
- # from_=from_branch, to_branch=to_branch, del_=True
214
- # )
215
- # self.assertIn(to_branch, self.session.branches)
216
- # self.assertNotIn(from_branch, self.session.branches)
217
-
218
- # def test_collect_from_specified_branches(self):
219
- # """Test collecting requests from specified branches."""
220
- # self.session.collect(from_=["branch1"])
221
- # self.assertEqual(self.session.mail_manager.collect.call_count, 1)
222
-
223
- # def test_collect_from_all_branches(self):
224
- # """Test collecting requests from all branches."""
225
- # self.session.collect()
226
- # self.assertEqual(self.session.mail_manager.collect.call_count, 2)
227
-
228
- # def test_send_to_specified_branches(self):
229
- # """Test sending requests to specified branches."""
230
- # self.session.send(to_=["branch_1"])
231
- # self.assertEqual(self.session.mail_manager.send.call_count, 1)
232
-
233
- # def test_send_to_all_branches(self):
234
- # """Test sending requests to all branches."""
235
- # self.session.send()
236
- # self.assertEqual(self.session.mail_manager.send.call_count, 2)
237
-
238
- # def test_collect_send_all_without_receive_all(self):
239
- # """Test collecting and sending requests across all branches without receiving."""
240
- # self.session.collect_send_all()
241
- # self.assertEqual(self.session.mail_manager.collect.call_count, 2)
242
- # self.assertEqual(self.session.mail_manager.send.call_count, 2)
243
- # self.branch1.receive_all.assert_not_called()
244
- # self.branch2.receive_all.assert_not_called()
245
-
246
- # def test_collect_send_all_with_receive_all(self):
247
- # """Test collecting and sending requests across all branches with receiving."""
248
- # self.session.collect_send_all(receive_all=True)
249
- # self.branch1.receive_all.assert_called()
250
- # self.branch2.receive_all.assert_called()
251
-
252
-
253
- # if __name__ == "__main__":
254
- # unittest.main()
@@ -1,312 +0,0 @@
1
- # from lionagi.core.branch.util import MessageUtil
2
- # from lionagi.core.messages.schema import System, Instruction, Response
3
-
4
- # import unittest
5
- # import pandas as pd
6
- # import json
7
- # from datetime import datetime
8
-
9
-
10
- # class TestCreateMessage(unittest.TestCase):
11
-
12
- # def test_create_system_message(self):
13
- # """Test creating a System message."""
14
- # system_info = {"system_info": "System information"}
15
- # message = MessageUtil.create_message(
16
- # system=system_info["system_info"]
17
- # )
18
- # self.assertIsInstance(message, System)
19
- # self.assertEqual(message.content, system_info)
20
-
21
- # def test_create_instruction_message(self):
22
- # """Test creating an Instruction message with context."""
23
- # instruction_info = {"task": "Do something"}
24
- # context = {"additional": "context"}
25
- # message = MessageUtil.create_message(
26
- # instruction=instruction_info, context=context
27
- # )
28
- # self.assertIsInstance(message, Instruction)
29
- # self.assertEqual(message.content["instruction"], instruction_info)
30
- # self.assertEqual(message.content["context"], context)
31
-
32
- # def test_create_response_message(self):
33
- # """Test creating a Response message."""
34
- # response_info = {"message": {"content": "This is a response"}}
35
- # message = MessageUtil.create_message(response=response_info)
36
- # self.assertIsInstance(message, Response)
37
- # self.assertEqual(
38
- # message.content["response"], response_info["message"]["content"]
39
- # )
40
-
41
- # def test_error_on_multiple_roles(self):
42
- # """Test error is raised when multiple roles are provided."""
43
- # with self.assertRaises(ValueError):
44
- # MessageUtil.create_message(
45
- # system={"info": "info"}, instruction={"task": "task"}
46
- # )
47
-
48
- # def test_return_existing_base_message_instance(self):
49
- # """Test returning an existing BaseMessage instance if provided."""
50
- # existing_message = System(system={"info": "Already created"})
51
- # message = MessageUtil.create_message(system=existing_message)
52
- # self.assertEqual(message.content, existing_message.content)
53
-
54
-
55
- # class TestValidateMessages(unittest.TestCase):
56
-
57
- # # def test_validate_messages_correct_format(self):
58
- # # """Test messages DataFrame with the correct format."""
59
- # # messages = pd.DataFrame({
60
- # # "node_id": ["1"],
61
- # # "role": ["user"],
62
- # # "sender": ["test"],
63
- # # "timestamp": ["2020-01-01T00:00:00"],
64
- # # "content": ['{"message": "test"}']
65
- # # })
66
- # # self.assertTrue(MessageUtil.validate_messages(messages))
67
-
68
- # def test_validate_messages_incorrect_columns(self):
69
- # """Test messages DataFrame with incorrect columns raises ValueError."""
70
- # messages = pd.DataFrame(
71
- # {
72
- # "id": ["1"], "type": ["user"], "source": ["test"],
73
- # "time": ["2020-01-01T00:00:00"],
74
- # "data": ['{"message": "test"}'],
75
- # }
76
- # )
77
- # with self.assertRaises(ValueError):
78
- # MessageUtil.validate_messages(messages)
79
-
80
- # def test_validate_messages_null_values(self):
81
- # """Test messages DataFrame with null values raises ValueError."""
82
- # messages = pd.DataFrame(
83
- # {
84
- # "node_id": [None], "role": ["user"], "sender": ["test"],
85
- # "timestamp": ["2020-01-01T00:00:00"],
86
- # "content": ['{"message": "test"}'],
87
- # }
88
- # )
89
- # with self.assertRaises(ValueError):
90
- # MessageUtil.validate_messages(messages)
91
-
92
-
93
- # class TestSignMessage(unittest.TestCase):
94
-
95
- # def test_sign_message(self):
96
- # """Test signing message content with sender."""
97
- # messages = pd.DataFrame(
98
- # {
99
- # "node_id": ["1"], "role": ["user"], "sender": ["test"],
100
- # "timestamp": ["2020-01-01T00:00:00"],
101
- # "content": ["Original message"],
102
- # }
103
- # )
104
- # sender = "system"
105
- # signed_messages = MessageUtil.sign_message(messages, sender)
106
- # expected_content = "Sender system: Original message"
107
- # self.assertEqual(signed_messages["content"][0], expected_content)
108
-
109
- # def test_sign_message_invalid_sender(self):
110
- # """Test signing message with an invalid sender raises ValueError."""
111
- # messages = pd.DataFrame(
112
- # {
113
- # "node_id": ["1"], "role": ["user"], "sender": ["test"],
114
- # "timestamp": ["2020-01-01T00:00:00"],
115
- # "content": ["Original message"],
116
- # }
117
- # )
118
- # with self.assertRaises(ValueError):
119
- # MessageUtil.sign_message(messages, None)
120
-
121
-
122
- # class TestFilterMessagesBy(unittest.TestCase):
123
-
124
- # def setUp(self):
125
- # self.messages = pd.DataFrame(
126
- # {
127
- # "node_id": ["1", "2"], "role": ["user", "assistant"],
128
- # "sender": ["test", "assistant"],
129
- # "timestamp": [datetime(2020, 1, 1), datetime(2020, 1, 2)],
130
- # "content": ['{"message": "test"}', '{"response": "ok"}'],
131
- # }
132
- # )
133
-
134
- # def test_filter_by_role(self):
135
- # """Test filtering messages by role."""
136
- # filtered = MessageUtil.filter_messages_by(
137
- # self.messages, role="assistant"
138
- # )
139
- # self.assertEqual(len(filtered), 1)
140
- # self.assertEqual(filtered.iloc[0]["sender"], "assistant")
141
-
142
- # def test_filter_by_sender(self):
143
- # """Test filtering messages by sender."""
144
- # filtered = MessageUtil.filter_messages_by(
145
- # self.messages, sender="test"
146
- # )
147
- # self.assertEqual(len(filtered), 1)
148
- # self.assertEqual(filtered.iloc[0]["sender"], "test")
149
-
150
- # def test_filter_by_time_range(self):
151
- # """Test filtering messages by time range."""
152
- # start_time = datetime(2020, 1, 1, 12)
153
- # end_time = datetime(2020, 1, 2, 12)
154
- # filtered = MessageUtil.filter_messages_by(
155
- # self.messages, start_time=start_time, end_time=end_time
156
- # )
157
- # self.assertEqual(len(filtered), 1)
158
- # self.assertTrue(
159
- # start_time <= filtered.iloc[0]["timestamp"] <= end_time
160
- # )
161
-
162
-
163
- # class TestRemoveMessage(unittest.TestCase):
164
-
165
- # def test_remove_message(self):
166
- # """Test removing a message by node_id."""
167
- # messages = pd.DataFrame(
168
- # {
169
- # "node_id": ["1", "2"], "role": ["user", "assistant"],
170
- # "content": ["message1", "message2"],
171
- # }
172
- # )
173
- # updated_messages = MessageUtil.remove_message(messages, "1")
174
- # self.assertTrue(updated_messages)
175
-
176
-
177
- # class TestGetMessageRows(unittest.TestCase):
178
-
179
- # def test_get_message_rows(self):
180
- # """Test retrieving the last 'n' message rows based on criteria."""
181
- # messages = pd.DataFrame(
182
- # {
183
- # "node_id": ["1", "2", "3"],
184
- # "role": ["user", "assistant", "user"],
185
- # "sender": ["A", "B", "A"],
186
- # "content": ["message1", "message2", "message3"],
187
- # }
188
- # )
189
- # rows = MessageUtil.get_message_rows(
190
- # messages, sender="A", role="user", n=2
191
- # )
192
- # self.assertEqual(len(rows), 2)
193
-
194
-
195
- # # class TestExtend(unittest.TestCase):
196
-
197
- # # def test_extend(self):
198
- # # """Test extending one DataFrame with another, ensuring no duplicate 'node_id'."""
199
- # # df1 = pd.DataFrame({
200
- # # "node_id": ["1"],
201
- # # "role": ["user"],
202
- # # "sender": ["test"],
203
- # # "timestamp": ["2020-01-01T00:00:00"],
204
- # # "content": ['{"message": "test"}']
205
- # # })
206
- # # df2 = pd.DataFrame({
207
- # # "node_id": ["2"],
208
- # # "role": ["user"],
209
- # # "sender": ["test"],
210
- # # "timestamp": ["2020-01-02T00:00:00"],
211
- # # "content": ['{"message": "test2"}']
212
- # # })
213
- # # combined = MessageUtil.extend(df1, df2)
214
- # # self.assertEqual(len(combined), 2)
215
-
216
-
217
- # class TestToMarkdownString(unittest.TestCase):
218
-
219
- # def test_to_markdown_string(self):
220
- # """Test converting messages to a Markdown-formatted string."""
221
- # messages = pd.DataFrame(
222
- # {
223
- # "node_id": ["1"], "role": ["user"],
224
- # "content": [json.dumps({"instruction": "Hello, World!"})],
225
- # }
226
- # )
227
- # markdown_str = MessageUtil.to_markdown_string(messages)
228
- # self.assertIn("Hello, World!", markdown_str)
229
-
230
-
231
- # # class TestSearchKeywords(unittest.TestCase):
232
-
233
- # # def test_search_keywords(self):
234
- # # """Test filtering DataFrame for rows containing specified keywords."""
235
- # # messages = pd.DataFrame(
236
- # # {"node_id": ["1", "2"], "content": ["Hello world", "Goodbye world"]}
237
- # # )
238
- # # filtered = MessageUtil.search_keywords(messages, "Hello")
239
- # # print(filtered)
240
- # # self.assertEqual(len(filtered), 1)
241
-
242
-
243
- # # class TestReplaceKeyword(unittest.TestCase):
244
-
245
- # # def test_replace_keyword(self):
246
- # # """Test replacing a keyword in DataFrame's specified column."""
247
- # # messages = pd.DataFrame({"content": ["Hello world", "Goodbye world"]})
248
- # # MessageUtil.replace_keyword(messages, "world", "universe")
249
- # # self.assertTrue(all(messages["content"].str.contains("universe")))
250
-
251
-
252
- # # class TestReadCsv(unittest.TestCase):
253
-
254
- # # @patch("pandas.read_csv")
255
- # # def test_read_csv(self, mock_read_csv):
256
- # # """Test reading a CSV file into a DataFrame."""
257
- # # mock_df = pd.DataFrame(
258
- # # {"node_id": ["1", "2"], "content": ["Hello, World!", "Goodbye, World!"]}
259
- # # )
260
- # # mock_read_csv.return_value = mock_df
261
-
262
- # # df = MessageUtil.read_csv("path/to/nonexistent/file.csv")
263
-
264
- # # mock_read_csv.assert_called_once_with("path/to/nonexistent/file.csv")
265
-
266
- # # self.assertTrue(isinstance(df, pd.DataFrame))
267
- # # self.assertEqual(len(df), 2)
268
- # # self.assertEqual(list(df.columns), ["node_id", "content"])
269
-
270
-
271
- # # class TestReadJson(unittest.TestCase):
272
-
273
- # # @patch("pandas.read_json")
274
- # # def test_read_json(self, mock_read_json):
275
- # # """Test reading a JSON file into a DataFrame."""
276
- # # mock_df = pd.DataFrame(
277
- # # {"node_id": ["1", "2"], "content": ["JSON Message 1", "JSON Message 2"]}
278
- # # )
279
- # # mock_read_json.return_value = mock_df
280
-
281
- # # df = MessageUtil.read_json("path/to/nonexistent/file.json")
282
-
283
- # # mock_read_json.assert_called_once_with("path/to/nonexistent/file.json")
284
-
285
- # # self.assertTrue(isinstance(df, pd.DataFrame))
286
- # # self.assertEqual(len(df), 2)
287
- # # self.assertEqual(list(df.columns), ["node_id", "content"])
288
-
289
-
290
- # # class TestRemoveLastNRows(unittest.TestCase):
291
-
292
- # # def test_remove_last_n_rows(self):
293
- # # """Test removing the last 'n' rows from a DataFrame."""
294
- # # messages = pd.DataFrame({"content": ["message1", "message2", "message3"]})
295
- # # updated = MessageUtil.remove_last_n_rows(messages, 2)
296
- # # self.assertEqual(len(updated), 1)
297
-
298
-
299
- # # class TestUpdateRow(unittest.TestCase):
300
-
301
- # # def test_update_row(self):
302
- # # """Test updating a row's value for a specified column."""
303
- # # messages = pd.DataFrame(
304
- # # {"node_id": ["1", "2"], "content": ["message1", "message2"]}
305
- # # )
306
- # # success = MessageUtil.update_row(messages, 0, "node_id", "3")
307
- # # self.assertTrue(success)
308
- # # self.assertTrue("3" in messages["node_id"].values)
309
-
310
-
311
- # if __name__ == "__main__":
312
- # unittest.main()
@@ -1,95 +0,0 @@
1
- # from lionagi.core.tool.tool_manager import ToolManager
2
- # from lionagi.core.schema import Tool
3
-
4
- # import unittest
5
- # from unittest.mock import patch, AsyncMock
6
- # import asyncio
7
- # import json
8
-
9
-
10
- # class TestToolManager(unittest.TestCase):
11
- # def setUp(self):
12
- # self.manager = ToolManager()
13
- # self.tool = Tool(
14
- # func=lambda x: x, schema_={"function": {"name": "test_func"}}
15
- # )
16
-
17
- # def test_register_and_check_tool(self):
18
- # """Test registering a tool and checking its existence."""
19
- # self.manager._register_tool(self.tool)
20
- # self.assertTrue(self.manager.name_existed("test_func"))
21
-
22
- # def test_register_tool_type_error(self):
23
- # """Test that registering a non-Tool object raises a TypeError."""
24
- # with self.assertRaises(TypeError):
25
- # self.manager._register_tool("not_a_tool")
26
-
27
- # def test_name_not_existed(self):
28
- # """Test querying a non-registered tool's existence."""
29
- # self.assertFalse(self.manager.name_existed("non_existent_func"))
30
-
31
-
32
- # class TestToolInvocation(unittest.TestCase):
33
-
34
- # def setUp(self):
35
- # self.manager = ToolManager()
36
-
37
- # async def async_tool_func(x):
38
- # return x
39
-
40
- # self.async_tool = Tool(
41
- # func=async_tool_func,
42
- # schema_={"function": {"name": "async_test_func"}}
43
- # )
44
- # self.sync_tool = Tool(
45
- # func=lambda x: x, schema_={"function": {"name": "sync_test_func"}}
46
- # )
47
-
48
- # # @patch('lionagi.core.tool.tool_manager', return_value=False) # def test_invoke_sync_tool(self, mock_is_coroutine): # """Test invoking a synchronous tool.""" # self.manager._register_tool(self.sync_tool) # result = asyncio.run(self.manager.invoke(('sync_test_func', {'x': 10}))) # self.assertEqual(result, 10)
49
-
50
- # # @patch('lionagi.core.tool.tool_manager', return_value=True) # def test_invoke_async_tool(self, mock_call_handler, mock_is_coroutine): # """Test invoking an asynchronous tool.""" # mock_call_handler.return_value = 10 # self.manager._register_tool(self.async_tool) # result = asyncio.run(self.manager.invoke(('async_test_func', {'x': 10}))) # self.assertEqual(result, 10)
51
-
52
-
53
- # class TestFunctionCallExtraction(unittest.TestCase):
54
-
55
- # def setUp(self):
56
- # self.manager = ToolManager()
57
-
58
- # def test_get_function_call_valid(self):
59
- # """Test extracting a valid function call."""
60
- # response = {
61
- # "action": "action_test_func", "arguments": json.dumps({"x": 10})
62
- # }
63
- # func_call = self.manager.get_function_call(response)
64
- # self.assertEqual(func_call, ("test_func", {"x": 10}))
65
-
66
- # def test_get_function_call_invalid(self):
67
- # """Test handling an invalid function call."""
68
- # with self.assertRaises(ValueError):
69
- # self.manager.get_function_call({})
70
-
71
-
72
- # class TestToolParser(unittest.TestCase):
73
-
74
- # def setUp(self):
75
- # self.manager = ToolManager()
76
- # self.tool = Tool(
77
- # func=lambda x: x, schema_={"function": {"name": "test_func"}}
78
- # )
79
- # self.manager._register_tool(self.tool)
80
-
81
- # def test_tool_parser_single_tool(self):
82
- # """Test parsing a single tool name."""
83
- # parsed = self.manager.parse_tool("test_func")
84
- # self.assertIn("tools", parsed)
85
- # self.assertEqual(len(parsed["tools"]), 1)
86
- # self.assertEqual(parsed["tools"][0]["function"]["name"], "test_func")
87
-
88
- # def test_tool_parser_unregistered_tool(self):
89
- # """Test parsing an unregistered tool name."""
90
- # with self.assertRaises(ValueError):
91
- # self.manager.parse_tool("unregistered_func")
92
-
93
-
94
- # if __name__ == "__main__":
95
- # unittest.main()