lionagi 0.0.111__py3-none-any.whl → 0.0.113__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 +7 -2
- lionagi/bridge/__init__.py +7 -0
- lionagi/bridge/langchain.py +131 -0
- lionagi/bridge/llama_index.py +157 -0
- lionagi/configs/__init__.py +7 -0
- lionagi/configs/oai_configs.py +49 -0
- lionagi/configs/openrouter_config.py +49 -0
- lionagi/core/__init__.py +15 -0
- lionagi/{session/conversation.py → core/conversations.py} +10 -17
- lionagi/core/flows.py +1 -0
- lionagi/core/instruction_sets.py +1 -0
- lionagi/{session/message.py → core/messages.py} +5 -5
- lionagi/core/sessions.py +262 -0
- lionagi/datastore/__init__.py +1 -0
- lionagi/datastore/chroma.py +1 -0
- lionagi/datastore/deeplake.py +1 -0
- lionagi/datastore/elasticsearch.py +1 -0
- lionagi/datastore/lantern.py +1 -0
- lionagi/datastore/pinecone.py +1 -0
- lionagi/datastore/postgres.py +1 -0
- lionagi/datastore/qdrant.py +1 -0
- lionagi/loader/__init__.py +12 -0
- lionagi/loader/chunker.py +157 -0
- lionagi/loader/reader.py +124 -0
- lionagi/objs/__init__.py +7 -0
- lionagi/objs/messenger.py +163 -0
- lionagi/objs/tool_registry.py +247 -0
- lionagi/schema/__init__.py +11 -0
- lionagi/schema/base_condition.py +1 -0
- lionagi/schema/base_schema.py +239 -0
- lionagi/schema/base_tool.py +9 -0
- lionagi/schema/data_logger.py +94 -0
- lionagi/services/__init__.py +14 -0
- lionagi/services/anthropic.py +1 -0
- lionagi/services/anyscale.py +0 -0
- lionagi/services/azure.py +1 -0
- lionagi/{api/oai_service.py → services/base_api_service.py} +74 -148
- lionagi/services/bedrock.py +0 -0
- lionagi/services/chatcompletion.py +48 -0
- lionagi/services/everlyai.py +0 -0
- lionagi/services/gemini.py +0 -0
- lionagi/services/gpt4all.py +0 -0
- lionagi/services/huggingface.py +0 -0
- lionagi/services/litellm.py +1 -0
- lionagi/services/localai.py +0 -0
- lionagi/services/mistralai.py +0 -0
- lionagi/services/oai.py +34 -0
- lionagi/services/ollama.py +1 -0
- lionagi/services/openllm.py +0 -0
- lionagi/services/openrouter.py +32 -0
- lionagi/services/perplexity.py +0 -0
- lionagi/services/predibase.py +0 -0
- lionagi/services/rungpt.py +0 -0
- lionagi/services/service_objs.py +282 -0
- lionagi/services/vllm.py +0 -0
- lionagi/services/xinference.py +0 -0
- lionagi/structure/__init__.py +7 -0
- lionagi/structure/relationship.py +128 -0
- lionagi/structure/structure.py +160 -0
- lionagi/tests/__init__.py +0 -0
- lionagi/tests/test_flatten_util.py +426 -0
- lionagi/tools/__init__.py +0 -0
- lionagi/tools/coder.py +1 -0
- lionagi/tools/planner.py +1 -0
- lionagi/tools/prompter.py +1 -0
- lionagi/tools/sandbox.py +1 -0
- lionagi/tools/scorer.py +1 -0
- lionagi/tools/summarizer.py +1 -0
- lionagi/tools/validator.py +1 -0
- lionagi/utils/__init__.py +46 -8
- lionagi/utils/api_util.py +63 -416
- lionagi/utils/call_util.py +347 -0
- lionagi/utils/flat_util.py +540 -0
- lionagi/utils/io_util.py +102 -0
- lionagi/utils/load_utils.py +190 -0
- lionagi/utils/sys_util.py +85 -660
- lionagi/utils/tool_util.py +82 -199
- lionagi/utils/type_util.py +81 -0
- lionagi/version.py +1 -1
- {lionagi-0.0.111.dist-info → lionagi-0.0.113.dist-info}/METADATA +44 -15
- lionagi-0.0.113.dist-info/RECORD +84 -0
- lionagi/api/__init__.py +0 -8
- lionagi/api/oai_config.py +0 -16
- lionagi/session/__init__.py +0 -7
- lionagi/session/session.py +0 -380
- lionagi/utils/doc_util.py +0 -331
- lionagi/utils/log_util.py +0 -86
- lionagi-0.0.111.dist-info/RECORD +0 -20
- {lionagi-0.0.111.dist-info → lionagi-0.0.113.dist-info}/LICENSE +0 -0
- {lionagi-0.0.111.dist-info → lionagi-0.0.113.dist-info}/WHEEL +0 -0
- {lionagi-0.0.111.dist-info → lionagi-0.0.113.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,426 @@
|
|
1
|
+
import unittest
|
2
|
+
|
3
|
+
from ..utils.flat_util import *
|
4
|
+
|
5
|
+
class TestFlattenDict(unittest.TestCase):
|
6
|
+
|
7
|
+
def test_flatten_empty_dict(self):
|
8
|
+
self.assertEqual(flatten_dict({}), {})
|
9
|
+
|
10
|
+
def test_flatten_flat_dict(self):
|
11
|
+
self.assertEqual(flatten_dict({'a': 1, 'b': 2, 'c': 3}), {'a': 1, 'b': 2, 'c': 3})
|
12
|
+
|
13
|
+
def test_flatten_nested_dict(self):
|
14
|
+
nested_dict = {'a': 1, 'b': {'c': 2, 'd': {'e': 3, 'f': 4}}}
|
15
|
+
expected_flat_dict = {'a': 1, 'b_c': 2, 'b_d_e': 3, 'b_d_f': 4}
|
16
|
+
self.assertEqual(flatten_dict(nested_dict), expected_flat_dict)
|
17
|
+
|
18
|
+
def test_flatten_dict_with_custom_separator(self):
|
19
|
+
nested_dict = {'a': {'b': 1, 'c': {'d': 2}}}
|
20
|
+
expected_flat_dict = {'a.b': 1, 'a.c.d': 2}
|
21
|
+
self.assertEqual(flatten_dict(nested_dict, sep='.'), expected_flat_dict)
|
22
|
+
|
23
|
+
def test_flatten_dict_with_empty_subdict(self):
|
24
|
+
nested_dict = {'a': 1, 'b': {}}
|
25
|
+
expected_flat_dict = {'a': 1}
|
26
|
+
self.assertEqual(flatten_dict(nested_dict), expected_flat_dict)
|
27
|
+
|
28
|
+
def test_flatten_dict_with_non_dict_values(self):
|
29
|
+
nested_dict = {'a': [1, 2, 3], 'b': 'string', 'c': {'d': 4}}
|
30
|
+
expected_flat_dict = {'a': [1, 2, 3], 'b': 'string', 'c_d': 4}
|
31
|
+
self.assertEqual(flatten_dict(nested_dict), expected_flat_dict)
|
32
|
+
|
33
|
+
class TestFlattenList(unittest.TestCase):
|
34
|
+
def test_flatten_empty_list(self): self.assertEqual(flatten_list([]), [])
|
35
|
+
|
36
|
+
def test_flatten_flat_list(self):
|
37
|
+
self.assertEqual(flatten_list([1, 2, 3]), [1, 2, 3])
|
38
|
+
|
39
|
+
def test_flatten_nested_list(self):
|
40
|
+
self.assertEqual(flatten_list([1, [2, [3, 4]], 5]), [1, 2, 3, 4, 5])
|
41
|
+
|
42
|
+
def test_flatten_list_with_None(self):
|
43
|
+
self.assertEqual(flatten_list([1, None, [2, None], 3], dropna=True), [1, 2, 3])
|
44
|
+
self.assertEqual(flatten_list([1, None, [2, None], 3], dropna=False), [1, None, 2, None, 3])
|
45
|
+
|
46
|
+
def test_flatten_list_with_other_datatypes(self):
|
47
|
+
self.assertEqual(flatten_list([1, "string", [2, (3, 4)], 5]), [1, "string", 2, (3, 4), 5])
|
48
|
+
|
49
|
+
def test_flatten_list_with_multiple_nested_lists(self):
|
50
|
+
self.assertEqual(flatten_list([[1, [2, 3]], [4, [5, [6, 7]]]]), [1, 2, 3, 4, 5, 6, 7])
|
51
|
+
|
52
|
+
class TestChangeSeparator(unittest.TestCase):
|
53
|
+
|
54
|
+
def test_change_separator_basic(self):
|
55
|
+
input_dict = {'a_b': 1, 'a_b_c': 2, 'd': 3}
|
56
|
+
expected_dict = {'a-b': 1, 'a-b-c': 2, 'd': 3}
|
57
|
+
result_dict = change_separator(input_dict, '_', '-')
|
58
|
+
self.assertEqual(expected_dict, result_dict)
|
59
|
+
|
60
|
+
def test_change_separator_no_change(self):
|
61
|
+
input_dict = {'a-b': 1, 'b-c': 2}
|
62
|
+
expected_dict = {'a-b': 1, 'b-c': 2}
|
63
|
+
result_dict = change_separator(input_dict, '_', '-')
|
64
|
+
self.assertEqual(expected_dict, result_dict)
|
65
|
+
|
66
|
+
def test_change_separator_empty_dict(self):
|
67
|
+
self.assertEqual({}, change_separator({}, '_', '-'))
|
68
|
+
|
69
|
+
def test_change_separator_same_separators(self):
|
70
|
+
input_dict = {'a_b': 1, 'b_c': 2}
|
71
|
+
expected_dict = {'a_b': 1, 'b_c': 2}
|
72
|
+
result_dict = change_separator(input_dict, '_', '_')
|
73
|
+
self.assertEqual(expected_dict, result_dict)
|
74
|
+
|
75
|
+
def test_change_separator_multiple_occurrences(self):
|
76
|
+
input_dict = {'a_b_c_b': 1, 'd_e_f_e': 2}
|
77
|
+
expected_dict = {'a-b-c-b': 1, 'd-e-f-e': 2}
|
78
|
+
result_dict = change_separator(input_dict, '_', '-')
|
79
|
+
self.assertEqual(expected_dict, result_dict)
|
80
|
+
|
81
|
+
class TestUnflattenDict(unittest.TestCase):
|
82
|
+
|
83
|
+
def test_unflatten_simple(self):
|
84
|
+
flat_dict = {'a_b_c': 1, 'a_b_d': 2}
|
85
|
+
expected = {'a': {'b': {'c': 1, 'd': 2}}}
|
86
|
+
self.assertEqual(unflatten_dict(flat_dict), expected)
|
87
|
+
|
88
|
+
def test_unflatten_with_int_keys(self):
|
89
|
+
flat_dict = {'1_2_3': 'a', '1_2_4': 'b'}
|
90
|
+
expected = {1: {2: {3: 'a', 4: 'b'}}}
|
91
|
+
self.assertEqual(unflatten_dict(flat_dict), expected)
|
92
|
+
|
93
|
+
def test_unflatten_with_mixed_keys(self):
|
94
|
+
flat_dict = {'a_2_c': 1, 'a_2_d': 2, 'b_3': 3}
|
95
|
+
expected = {'a': {2: {'c': 1, 'd': 2}}, 'b': {3: 3}}
|
96
|
+
self.assertEqual(unflatten_dict(flat_dict), expected)
|
97
|
+
|
98
|
+
def test_unflatten_with_custom_separator(self):
|
99
|
+
flat_dict = {'a|b|c': 1, 'a|b|d': 2}
|
100
|
+
expected = {'a': {'b': {'c': 1, 'd': 2}}}
|
101
|
+
self.assertEqual(unflatten_dict(flat_dict, sep='|'), expected)
|
102
|
+
|
103
|
+
def test_unflatten_with_non_dict_value(self):
|
104
|
+
flat_dict = {'a_b': [1, 2, 3], 'a_c': (4, 5)}
|
105
|
+
expected = {'a': {'b': [1, 2, 3], 'c': (4, 5)}}
|
106
|
+
self.assertEqual(unflatten_dict(flat_dict), expected)
|
107
|
+
|
108
|
+
def test_unflatten_with_nested_list(self):
|
109
|
+
flat_dict = {'a_0': 1, 'a_1': 2, 'b_0': 3, 'b_1': 4}
|
110
|
+
expected = {'a': [1, 2], 'b': [3, 4]}
|
111
|
+
self.assertEqual(unflatten_dict(flat_dict), expected)
|
112
|
+
|
113
|
+
def test_unflatten_with_overlapping_keys(self):
|
114
|
+
flat_dict = {'a_b': 1, 'a': 2}
|
115
|
+
with self.assertRaises(ValueError):
|
116
|
+
unflatten_dict(flat_dict)
|
117
|
+
|
118
|
+
class TestIsFlattenable(unittest.TestCase):
|
119
|
+
|
120
|
+
def test_flattenable_dict(self):
|
121
|
+
self.assertTrue(is_flattenable({'a': {'b': 1}, 'c': [2, 3]}))
|
122
|
+
|
123
|
+
def test_flattenable_list(self):
|
124
|
+
self.assertTrue(is_flattenable([1, {'a': 2}, [3]]))
|
125
|
+
|
126
|
+
def test_non_flattenable_dict(self):
|
127
|
+
self.assertFalse(is_flattenable({'a': 1, 'b': 2}))
|
128
|
+
|
129
|
+
def test_non_flattenable_list(self):
|
130
|
+
self.assertFalse(is_flattenable([1, 2, 3]))
|
131
|
+
|
132
|
+
def test_empty_dict(self):
|
133
|
+
self.assertFalse(is_flattenable({}))
|
134
|
+
|
135
|
+
def test_empty_list(self):
|
136
|
+
self.assertFalse(is_flattenable([]))
|
137
|
+
|
138
|
+
def test_non_flattenable_types(self):
|
139
|
+
self.assertFalse(is_flattenable(1))
|
140
|
+
self.assertFalse(is_flattenable(1.0))
|
141
|
+
self.assertFalse(is_flattenable('string'))
|
142
|
+
self.assertFalse(is_flattenable(None))
|
143
|
+
|
144
|
+
def test_nested_mix_flattenable(self):
|
145
|
+
self.assertTrue(is_flattenable({'a': [{'b': 1}], 'c': (2, 3)}))
|
146
|
+
|
147
|
+
def test_deeply_nested_flattenable(self):
|
148
|
+
self.assertTrue(is_flattenable({'a': {'b': {'c': {'d': [1]}}}}))
|
149
|
+
|
150
|
+
|
151
|
+
def default_logic_func(parent_key, key, value, sep='_'):
|
152
|
+
new_key = f"{parent_key}{sep}{key}" if parent_key else key
|
153
|
+
return new_key, value
|
154
|
+
|
155
|
+
|
156
|
+
class TestFlattenWithCustomLogic(unittest.TestCase):
|
157
|
+
def test_flatten_dict(self):
|
158
|
+
input_dict = {'a': 1, 'b': {'c': 2, 'd': {'e': 3}}}
|
159
|
+
expected_output = {'a': 1, 'b_c': 2, 'b_d_e': 3}
|
160
|
+
self.assertEqual(flatten_with_custom_logic(input_dict, default_logic_func), expected_output)
|
161
|
+
|
162
|
+
def test_flatten_list(self):
|
163
|
+
input_list = [1, 2, [3, 4]]
|
164
|
+
expected_output = {'0': 1, '1': 2, '2_0': 3, '2_1': 4}
|
165
|
+
self.assertEqual(flatten_with_custom_logic(input_list, default_logic_func), expected_output)
|
166
|
+
|
167
|
+
|
168
|
+
def test_empty_dict(self):
|
169
|
+
self.assertEqual(flatten_with_custom_logic({}, default_logic_func), {})
|
170
|
+
|
171
|
+
def test_empty_list(self):
|
172
|
+
self.assertEqual(flatten_with_custom_logic([], default_logic_func), {})
|
173
|
+
|
174
|
+
def test_nested_combination(self):
|
175
|
+
input_obj = {'a': [{'b': 1}, {'c': 2}], 'd': []}
|
176
|
+
expected_output = {'a_0_b': 1, 'a_1_c': 2, 'd': None}
|
177
|
+
self.assertEqual(flatten_with_custom_logic(input_obj, default_logic_func), expected_output)
|
178
|
+
|
179
|
+
def test_custom_separator(self):
|
180
|
+
input_obj = {'a': 1, 'b': {'c': 2}}
|
181
|
+
expected_output = {'a': 1, 'b#c': 2}
|
182
|
+
self.assertEqual(flatten_with_custom_logic(input_obj, default_logic_func, sep='#'), expected_output)
|
183
|
+
|
184
|
+
def test_logic_func_none(self):
|
185
|
+
input_obj = {'a': 1, 'b': {'c': 2}}
|
186
|
+
expected_output = {'a': 1, 'b_c': 2}
|
187
|
+
self.assertEqual(flatten_with_custom_logic(input_obj, None), expected_output)
|
188
|
+
|
189
|
+
def test_obj_with_none_values(self):
|
190
|
+
input_obj = {'a': None, 'b': {'c': None}}
|
191
|
+
expected_output = {'a': None, 'b_c': None}
|
192
|
+
self.assertEqual(flatten_with_custom_logic(input_obj, default_logic_func), expected_output)
|
193
|
+
|
194
|
+
def test_custom_logic_func(self):
|
195
|
+
def custom_logic(parent_key, key, value, sep='_'):
|
196
|
+
new_key = f"{parent_key}{sep}{key}".upper() if parent_key else key.upper()
|
197
|
+
return new_key, value*2 if isinstance(value, int) else value
|
198
|
+
|
199
|
+
input_obj = {'a': 1, 'b': {'c': 2}}
|
200
|
+
expected_output = {'A': 2, 'B_C': 4}
|
201
|
+
self.assertEqual(flatten_with_custom_logic(input_obj, custom_logic), expected_output)
|
202
|
+
|
203
|
+
class TestDynamicFlatten(unittest.TestCase):
|
204
|
+
|
205
|
+
def test_flatten_dict(self):
|
206
|
+
sample_dict = {'a': 1, 'b': {'c': 2, 'd': {'e': 3}}}
|
207
|
+
flattened = dynamic_flatten(sample_dict)
|
208
|
+
expected = {'a': 1, 'b_c': 2, 'b_d_e': 3}
|
209
|
+
self.assertEqual(flattened, expected)
|
210
|
+
|
211
|
+
def test_flatten_list(self):
|
212
|
+
sample_list = [1, 2, [3, 4]]
|
213
|
+
flattened = dynamic_flatten(sample_list)
|
214
|
+
expected = {'0': 1, '1': 2, '2_0': 3, '2_1': 4}
|
215
|
+
self.assertEqual(flattened, expected)
|
216
|
+
|
217
|
+
def test_flatten_with_max_depth(self):
|
218
|
+
sample_dict = {'a': 1, 'b': {'c': 2, 'd': {'e': 3}}}
|
219
|
+
flattened = dynamic_flatten(sample_dict, max_depth=1)
|
220
|
+
expected = {'a': 1, 'b_c': 2, 'b_d': {'e': 3}}
|
221
|
+
self.assertEqual(flattened, expected)
|
222
|
+
|
223
|
+
def test_flatten_with_different_separator(self):
|
224
|
+
sample_dict = {'a': 1, 'b': {'c': 2, 'd': {'e': 3}}}
|
225
|
+
flattened = dynamic_flatten(sample_dict, sep='.')
|
226
|
+
expected = {'a': 1, 'b.c': 2, 'b.d.e': 3}
|
227
|
+
self.assertEqual(flattened, expected)
|
228
|
+
|
229
|
+
def test_flatten_empty_dictionary(self):
|
230
|
+
sample_dict = {}
|
231
|
+
flattened = dynamic_flatten(sample_dict)
|
232
|
+
expected = {}
|
233
|
+
self.assertEqual(flattened, expected)
|
234
|
+
|
235
|
+
def test_flatten_empty_list(self):
|
236
|
+
sample_list = []
|
237
|
+
flattened = dynamic_flatten(sample_list)
|
238
|
+
expected = {}
|
239
|
+
self.assertEqual(flattened, expected)
|
240
|
+
|
241
|
+
def test_flatten_non_dict_non_list(self):
|
242
|
+
with self.assertRaises(TypeError):
|
243
|
+
dynamic_flatten(42)
|
244
|
+
|
245
|
+
def test_flatten_nested_empty_dict(self):
|
246
|
+
sample_dict = {'a': {}, 'b': {'c': {}}}
|
247
|
+
flattened = dynamic_flatten(sample_dict)
|
248
|
+
expected = {'a': {}, 'b_c': {}}
|
249
|
+
self.assertEqual(flattened, expected)
|
250
|
+
|
251
|
+
def test_flatten_nested_empty_list(self):
|
252
|
+
sample_list = [1, [], [3, []]]
|
253
|
+
flattened = dynamic_flatten(sample_list)
|
254
|
+
expected = {'0': 1, '1': [], '2_0': 3, '2_1': []}
|
255
|
+
self.assertEqual(flattened, expected)
|
256
|
+
|
257
|
+
# class TestDynamicUnflatten(unittest.TestCase):
|
258
|
+
|
259
|
+
# def test_unflatten_dict(self):
|
260
|
+
# flat_dict = {'a': 1, 'b_c': 2, 'b_d_e': 3}
|
261
|
+
# expected = {'a': 1, 'b': {'c': 2, 'd': {'e': 3}}}
|
262
|
+
# self.assertEqual(dynamic_unflatten(flat_dict), expected)
|
263
|
+
|
264
|
+
|
265
|
+
# def test_unflatten_with_different_separator(self):
|
266
|
+
# flat_dict = {'a': 1, 'b.c': 2, 'b.d.e': 3}
|
267
|
+
# expected = {'a': 1, 'b': {'c': 2, 'd': {'e': 3}}}
|
268
|
+
# self.assertEqual(dynamic_unflatten(flat_dict, sep='.'), expected)
|
269
|
+
|
270
|
+
# def test_unflatten_empty_dict(self):
|
271
|
+
# flat_dict = {}
|
272
|
+
# expected = []
|
273
|
+
# self.assertEqual(dynamic_unflatten(flat_dict), expected)
|
274
|
+
|
275
|
+
# def test_unflatten_empty_string_keys(self):
|
276
|
+
# flat_dict = {'': 1}
|
277
|
+
# expected = {'': 1}
|
278
|
+
# self.assertEqual(dynamic_unflatten(flat_dict), expected)
|
279
|
+
|
280
|
+
# def test_unflatten_single_key(self):
|
281
|
+
# flat_dict = {'a': 1}
|
282
|
+
# expected = {'a': 1}
|
283
|
+
# self.assertEqual(dynamic_unflatten(flat_dict), expected)
|
284
|
+
|
285
|
+
# def test_unflatten_nested_empty_dict(self):
|
286
|
+
# flat_dict = {'a': {}, 'b_c': {}}
|
287
|
+
# expected = {'a': {}, 'b': {'c': {}}}
|
288
|
+
# self.assertEqual(dynamic_unflatten(flat_dict), expected)
|
289
|
+
|
290
|
+
|
291
|
+
# def test_unflatten_max_depth(self):
|
292
|
+
# flat_dict = {'a_b_c_d_e': 1}
|
293
|
+
# expected = {'a': {'b': {'c': {'d': {'e': 1}}}}}
|
294
|
+
# self.assertEqual(dynamic_unflatten(flat_dict, max_depth=3), expected)
|
295
|
+
|
296
|
+
class TestUnflattenToList(unittest.TestCase):
|
297
|
+
|
298
|
+
def test_unflatten_simple_list(self):
|
299
|
+
flat_dict = {'0': 'a', '1': 'b', '2': 'c'}
|
300
|
+
expected = ['a', 'b', 'c']
|
301
|
+
self.assertEqual(unflatten_to_list(flat_dict), expected)
|
302
|
+
|
303
|
+
def test_unflatten_nested_dicts_in_list(self):
|
304
|
+
flat_dict = {'0_a': 'value1', '1_b': 'value2', '2_c_d': 'value3'}
|
305
|
+
expected = [{'a': 'value1'}, {'b': 'value2'}, {'c': {'d': 'value3'}}]
|
306
|
+
self.assertEqual(unflatten_to_list(flat_dict), expected)
|
307
|
+
|
308
|
+
def test_unflatten_empty_dict(self):
|
309
|
+
flat_dict = {}
|
310
|
+
expected = []
|
311
|
+
self.assertEqual(unflatten_to_list(flat_dict), expected)
|
312
|
+
|
313
|
+
def test_unflatten_with_custom_separator(self):
|
314
|
+
flat_dict = {'0-a': 'value1', '1-b': 'value2', '2-c-d': 'value3'}
|
315
|
+
expected = [{'a': 'value1'}, {'b': 'value2'}, {'c': {'d': 'value3'}}]
|
316
|
+
self.assertEqual(unflatten_to_list(flat_dict, sep='-'), expected)
|
317
|
+
|
318
|
+
def test_unflatten_with_sparse_indices(self):
|
319
|
+
flat_dict = {'0': 'value1', '2': 'value2', '5': 'value3'}
|
320
|
+
expected = ['value1', None, 'value2', None, None, 'value3']
|
321
|
+
self.assertEqual(unflatten_to_list(flat_dict), expected)
|
322
|
+
|
323
|
+
def test_unflatten_with_negative_indices(self):
|
324
|
+
flat_dict = {'-1': 'value1', '1': 'value2'}
|
325
|
+
with self.assertRaises(ValueError): # Expect ValueError instead of IndexError
|
326
|
+
unflatten_to_list(flat_dict)
|
327
|
+
|
328
|
+
def test_unflatten_with_custom_separator(self):
|
329
|
+
flat_dict = {'0-a': 'value1', '1-b': 'value2', '2-c-d': 'value3'}
|
330
|
+
expected = [{'a': 'value1'}, {'b': 'value2'}, {'c': {'d': 'value3'}}]
|
331
|
+
self.assertEqual(unflatten_to_list(flat_dict, sep='-'), expected)
|
332
|
+
|
333
|
+
|
334
|
+
class TestFlattenIterable(unittest.TestCase):
|
335
|
+
|
336
|
+
def test_flatten_empty_list(self):
|
337
|
+
self.assertEqual(list(flatten_iterable([])), [])
|
338
|
+
|
339
|
+
def test_flatten_nested_lists(self):
|
340
|
+
nested_list = [1, [2, [3, 4], 5], 6]
|
341
|
+
expected_flat_list = [1, 2, 3, 4, 5, 6]
|
342
|
+
self.assertEqual(list(flatten_iterable(nested_list)), expected_flat_list)
|
343
|
+
|
344
|
+
def test_flatten_nested_tuples(self):
|
345
|
+
nested_tuple = (1, (2, (3, 4), 5), 6)
|
346
|
+
expected_flat_list = [1, 2, 3, 4, 5, 6]
|
347
|
+
self.assertEqual(list(flatten_iterable(nested_tuple)), expected_flat_list)
|
348
|
+
|
349
|
+
def test_flatten_with_max_depth(self):
|
350
|
+
nested_list = [1, [2, [3, 4], 5], 6]
|
351
|
+
expected_flat_list_depth_1 = [1, [2, [3, 4], 5], 6]
|
352
|
+
self.assertEqual(list(flatten_iterable(nested_list, max_depth=1)), expected_flat_list_depth_1)
|
353
|
+
|
354
|
+
expected_flat_list_depth_2 = [1, 2, [3, 4], 5, 6]
|
355
|
+
self.assertEqual(list(flatten_iterable(nested_list, max_depth=2)), expected_flat_list_depth_2)
|
356
|
+
|
357
|
+
# def test_flatten_strings(self):
|
358
|
+
# nested_list = ["hello", ["world", ["!"]]]
|
359
|
+
# expected_flat_list = ["hello", "world", ["!"]]
|
360
|
+
# self.assertEqual(list(flatten_iterable(nested_list)), expected_flat_list)
|
361
|
+
|
362
|
+
def test_flatten_with_non_iterable(self):
|
363
|
+
nested_list = [1, [2, 3], 4, "text", 5]
|
364
|
+
expected_flat_list = [1, 2, 3, 4, "text", 5]
|
365
|
+
self.assertEqual(list(flatten_iterable(nested_list)), expected_flat_list)
|
366
|
+
|
367
|
+
def test_flatten_with_none_max_depth(self):
|
368
|
+
nested_list = [1, [2, [3, [4, [5]]]]]
|
369
|
+
expected_flat_list = [1, 2, 3, 4, 5]
|
370
|
+
self.assertEqual(list(flatten_iterable(nested_list, max_depth=None)), expected_flat_list)
|
371
|
+
|
372
|
+
def test_flatten_iterable_to_list_function(self):
|
373
|
+
nested_list = [1, [2, [3, 4], 5], 6]
|
374
|
+
expected_flat_list = [1, 2, 3, 4, 5, 6]
|
375
|
+
self.assertEqual(flatten_iterable_to_list(nested_list), expected_flat_list)
|
376
|
+
|
377
|
+
nested_list_with_depth = [1, [2, [3, [4, [5]]]]]
|
378
|
+
expected_flat_list_with_depth = [1, 2, [3, [4, [5]]]]
|
379
|
+
self.assertEqual(flatten_iterable_to_list(nested_list_with_depth, max_depth=2), expected_flat_list_with_depth)
|
380
|
+
|
381
|
+
|
382
|
+
class TestUnflattenDictWithCustomLogic(unittest.TestCase):
|
383
|
+
|
384
|
+
@staticmethod
|
385
|
+
def logic_func_upper(key: str, value: Any) -> Tuple[str, Any]:
|
386
|
+
return key.upper(), value
|
387
|
+
|
388
|
+
@staticmethod
|
389
|
+
def logic_func_append_prefix(key: str, value: Any) -> Tuple[str, Any]:
|
390
|
+
|
391
|
+
return f"prefix_{key}", value
|
392
|
+
|
393
|
+
# def test_unflatten_dict_with_uppercase_logic(self):
|
394
|
+
# flat_dict = {'a_1': 10, 'b_2': 20, 'c_sub_1': 30}
|
395
|
+
# expected_dict = {'A': {'1': 10}, 'B': {'2': 20}, 'C_SUB': {'1': 30}}
|
396
|
+
# self.assertEqual(
|
397
|
+
# unflatten_dict_with_custom_logic(flat_dict, self.logic_func_upper),
|
398
|
+
# expected_dict
|
399
|
+
# )
|
400
|
+
|
401
|
+
# def test_unflatten_dict_with_prefix_logic(self):
|
402
|
+
# flat_dict = {'a_1': 10, 'b_2': 20, 'c_sub_1': 30}
|
403
|
+
# expected_dict = {'prefix_a': {'prefix_1': 10}, 'prefix_b': {'prefix_2': 20}, 'prefix_c_sub': {'prefix_1': 30}}
|
404
|
+
# self.assertEqual(
|
405
|
+
# unflatten_dict_with_custom_logic(flat_dict, self.logic_func_append_prefix),
|
406
|
+
# expected_dict
|
407
|
+
# )
|
408
|
+
|
409
|
+
def test_unflatten_dict_with_no_modification_logic(self):
|
410
|
+
flat_dict = {'a_1': 10, 'b_2': 20, 'c_sub_1': 30}
|
411
|
+
identity_logic_func = lambda key, value: (key, value)
|
412
|
+
expected_dict = {'a': {'1': 10}, 'b': {'2': 20}, 'c': {'sub': {'1': 30}}}
|
413
|
+
self.assertEqual(
|
414
|
+
unflatten_dict_with_custom_logic(flat_dict, identity_logic_func),
|
415
|
+
expected_dict
|
416
|
+
)
|
417
|
+
|
418
|
+
def test_unflatten_dict_empty(self):
|
419
|
+
flat_dict = {}
|
420
|
+
self.assertEqual(
|
421
|
+
unflatten_dict_with_custom_logic(flat_dict, self.logic_func_upper),
|
422
|
+
{}
|
423
|
+
)
|
424
|
+
|
425
|
+
if __name__ == "main":
|
426
|
+
unittest.main()
|
File without changes
|
lionagi/tools/coder.py
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
# TODO
|
lionagi/tools/planner.py
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
# TODO
|
@@ -0,0 +1 @@
|
|
1
|
+
# TODO
|
lionagi/tools/sandbox.py
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
# TODO
|
lionagi/tools/scorer.py
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
# TODO
|
@@ -0,0 +1 @@
|
|
1
|
+
# TODO
|
@@ -0,0 +1 @@
|
|
1
|
+
# TODO
|
lionagi/utils/__init__.py
CHANGED
@@ -1,11 +1,49 @@
|
|
1
|
-
from .
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
1
|
+
from .flat_util import (
|
2
|
+
flatten_dict, flatten_list, change_separator,
|
3
|
+
unflatten_dict, is_flattenable, dynamic_flatten,
|
4
|
+
unflatten_to_list, flatten_iterable, flatten_iterable_to_list
|
5
|
+
)
|
6
|
+
|
7
|
+
from .sys_util import (
|
8
|
+
create_copy, get_timestamp, create_id, create_path,
|
9
|
+
split_path, get_bins, change_dict_key
|
10
|
+
)
|
11
|
+
|
12
|
+
|
13
|
+
from .api_util import (
|
14
|
+
api_method, api_endpoint_from_url, api_error,
|
15
|
+
api_rate_limit_error
|
16
|
+
)
|
17
|
+
|
18
|
+
from .call_util import (
|
19
|
+
hcall, ahcall, lcall, alcall,
|
20
|
+
mcall, amcall, ecall, aecall
|
21
|
+
)
|
22
|
+
|
23
|
+
from .io_util import to_temp, to_csv, append_to_jsonl
|
24
|
+
from .load_utils import dir_to_path, dir_to_nodes, chunk_text, read_text, file_to_chunks
|
25
|
+
from .type_util import str_to_num, to_list
|
26
|
+
from .tool_util import func_to_schema
|
27
|
+
|
28
|
+
|
29
|
+
|
30
|
+
|
6
31
|
|
7
32
|
__all__ = [
|
8
|
-
"
|
9
|
-
"
|
10
|
-
|
33
|
+
"api_method", "api_endpoint_from_url", "api_error",
|
34
|
+
"api_rate_limit_error",
|
35
|
+
|
36
|
+
"flatten_dict", "flatten_list", "change_separator",
|
37
|
+
"unflatten_dict", "is_flattenable", "dynamic_flatten",
|
38
|
+
"unflatten_to_list", "flatten_iterable", "flatten_iterable_to_list",
|
39
|
+
|
40
|
+
"create_copy", "get_timestamp", "create_id", "create_path",
|
41
|
+
"split_path", "get_bins", "change_dict_key",
|
42
|
+
|
43
|
+
"hcall", "ahcall", "lcall", "alcall",
|
44
|
+
"mcall", "amcall", "ecall", "aecall",
|
45
|
+
|
46
|
+
"to_temp", "to_csv", "append_to_jsonl",
|
47
|
+
"dir_to_path", "chunk_text", "file_to_chunks",
|
48
|
+
"str_to_num", "to_list", "func_to_schema"
|
11
49
|
]
|