lionagi 0.0.306__py3-none-any.whl → 0.0.307__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.
- lionagi/__init__.py +2 -5
- lionagi/core/__init__.py +7 -5
- lionagi/core/agent/__init__.py +3 -0
- lionagi/core/agent/base_agent.py +10 -12
- lionagi/core/branch/__init__.py +4 -0
- lionagi/core/branch/base_branch.py +81 -81
- lionagi/core/branch/branch.py +16 -28
- lionagi/core/branch/branch_flow_mixin.py +3 -7
- lionagi/core/branch/executable_branch.py +86 -56
- lionagi/core/branch/util.py +77 -162
- lionagi/core/{flow/direct → direct}/__init__.py +1 -1
- lionagi/core/{flow/direct/predict.py → direct/parallel_predict.py} +39 -17
- lionagi/core/direct/parallel_react.py +0 -0
- lionagi/core/direct/parallel_score.py +0 -0
- lionagi/core/direct/parallel_select.py +0 -0
- lionagi/core/direct/parallel_sentiment.py +0 -0
- lionagi/core/direct/predict.py +174 -0
- lionagi/core/{flow/direct → direct}/react.py +2 -2
- lionagi/core/{flow/direct → direct}/score.py +28 -23
- lionagi/core/{flow/direct → direct}/select.py +48 -45
- lionagi/core/direct/utils.py +83 -0
- lionagi/core/flow/monoflow/ReAct.py +6 -5
- lionagi/core/flow/monoflow/__init__.py +9 -0
- lionagi/core/flow/monoflow/chat.py +10 -10
- lionagi/core/flow/monoflow/chat_mixin.py +11 -10
- lionagi/core/flow/monoflow/followup.py +6 -5
- lionagi/core/flow/polyflow/__init__.py +1 -0
- lionagi/core/flow/polyflow/chat.py +15 -3
- lionagi/core/mail/mail_manager.py +18 -19
- lionagi/core/mail/schema.py +5 -4
- lionagi/core/messages/schema.py +18 -20
- lionagi/core/prompt/__init__.py +0 -0
- lionagi/core/prompt/prompt_template.py +0 -0
- lionagi/core/schema/__init__.py +2 -2
- lionagi/core/schema/action_node.py +11 -3
- lionagi/core/schema/base_mixin.py +56 -59
- lionagi/core/schema/base_node.py +35 -38
- lionagi/core/schema/condition.py +24 -0
- lionagi/core/schema/data_logger.py +96 -99
- lionagi/core/schema/data_node.py +19 -19
- lionagi/core/schema/prompt_template.py +0 -0
- lionagi/core/schema/structure.py +171 -169
- lionagi/core/session/__init__.py +1 -3
- lionagi/core/session/session.py +196 -214
- lionagi/core/tool/tool_manager.py +95 -103
- lionagi/integrations/__init__.py +1 -3
- lionagi/integrations/bridge/langchain_/documents.py +17 -18
- lionagi/integrations/bridge/langchain_/langchain_bridge.py +14 -14
- lionagi/integrations/bridge/llamaindex_/llama_index_bridge.py +22 -22
- lionagi/integrations/bridge/llamaindex_/node_parser.py +12 -12
- lionagi/integrations/bridge/llamaindex_/reader.py +11 -11
- lionagi/integrations/bridge/llamaindex_/textnode.py +7 -7
- lionagi/integrations/config/openrouter_configs.py +0 -1
- lionagi/integrations/provider/oai.py +26 -26
- lionagi/integrations/provider/services.py +38 -38
- lionagi/libs/__init__.py +34 -1
- lionagi/libs/ln_api.py +211 -221
- lionagi/libs/ln_async.py +53 -60
- lionagi/libs/ln_convert.py +118 -120
- lionagi/libs/ln_dataframe.py +32 -33
- lionagi/libs/ln_func_call.py +334 -342
- lionagi/libs/ln_nested.py +99 -107
- lionagi/libs/ln_parse.py +161 -165
- lionagi/libs/sys_util.py +52 -52
- lionagi/tests/test_core/test_session.py +254 -266
- lionagi/tests/test_core/test_session_base_util.py +299 -300
- lionagi/tests/test_core/test_tool_manager.py +70 -74
- lionagi/tests/test_libs/test_nested.py +2 -7
- lionagi/tests/test_libs/test_parse.py +2 -2
- lionagi/version.py +1 -1
- {lionagi-0.0.306.dist-info → lionagi-0.0.307.dist-info}/METADATA +4 -2
- lionagi-0.0.307.dist-info/RECORD +115 -0
- lionagi/core/flow/direct/utils.py +0 -43
- lionagi-0.0.306.dist-info/RECORD +0 -106
- /lionagi/core/{flow/direct → direct}/sentiment.py +0 -0
- {lionagi-0.0.306.dist-info → lionagi-0.0.307.dist-info}/LICENSE +0 -0
- {lionagi-0.0.306.dist-info → lionagi-0.0.307.dist-info}/WHEEL +0 -0
- {lionagi-0.0.306.dist-info → lionagi-0.0.307.dist-info}/top_level.txt +0 -0
@@ -1,266 +1,254 @@
|
|
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
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
self.branch1.receive_all.assert_not_called()
|
256
|
-
self.branch2.receive_all.assert_not_called()
|
257
|
-
|
258
|
-
def test_collect_send_all_with_receive_all(self):
|
259
|
-
"""Test collecting and sending requests across all branches with receiving."""
|
260
|
-
self.session.collect_send_all(receive_all=True)
|
261
|
-
self.branch1.receive_all.assert_called()
|
262
|
-
self.branch2.receive_all.assert_called()
|
263
|
-
|
264
|
-
|
265
|
-
if __name__ == "__main__":
|
266
|
-
unittest.main()
|
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()
|