lionagi 0.0.111__py3-none-any.whl → 0.0.113__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
]
|