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.
Files changed (91) hide show
  1. lionagi/__init__.py +7 -2
  2. lionagi/bridge/__init__.py +7 -0
  3. lionagi/bridge/langchain.py +131 -0
  4. lionagi/bridge/llama_index.py +157 -0
  5. lionagi/configs/__init__.py +7 -0
  6. lionagi/configs/oai_configs.py +49 -0
  7. lionagi/configs/openrouter_config.py +49 -0
  8. lionagi/core/__init__.py +15 -0
  9. lionagi/{session/conversation.py → core/conversations.py} +10 -17
  10. lionagi/core/flows.py +1 -0
  11. lionagi/core/instruction_sets.py +1 -0
  12. lionagi/{session/message.py → core/messages.py} +5 -5
  13. lionagi/core/sessions.py +262 -0
  14. lionagi/datastore/__init__.py +1 -0
  15. lionagi/datastore/chroma.py +1 -0
  16. lionagi/datastore/deeplake.py +1 -0
  17. lionagi/datastore/elasticsearch.py +1 -0
  18. lionagi/datastore/lantern.py +1 -0
  19. lionagi/datastore/pinecone.py +1 -0
  20. lionagi/datastore/postgres.py +1 -0
  21. lionagi/datastore/qdrant.py +1 -0
  22. lionagi/loader/__init__.py +12 -0
  23. lionagi/loader/chunker.py +157 -0
  24. lionagi/loader/reader.py +124 -0
  25. lionagi/objs/__init__.py +7 -0
  26. lionagi/objs/messenger.py +163 -0
  27. lionagi/objs/tool_registry.py +247 -0
  28. lionagi/schema/__init__.py +11 -0
  29. lionagi/schema/base_condition.py +1 -0
  30. lionagi/schema/base_schema.py +239 -0
  31. lionagi/schema/base_tool.py +9 -0
  32. lionagi/schema/data_logger.py +94 -0
  33. lionagi/services/__init__.py +14 -0
  34. lionagi/services/anthropic.py +1 -0
  35. lionagi/services/anyscale.py +0 -0
  36. lionagi/services/azure.py +1 -0
  37. lionagi/{api/oai_service.py → services/base_api_service.py} +74 -148
  38. lionagi/services/bedrock.py +0 -0
  39. lionagi/services/chatcompletion.py +48 -0
  40. lionagi/services/everlyai.py +0 -0
  41. lionagi/services/gemini.py +0 -0
  42. lionagi/services/gpt4all.py +0 -0
  43. lionagi/services/huggingface.py +0 -0
  44. lionagi/services/litellm.py +1 -0
  45. lionagi/services/localai.py +0 -0
  46. lionagi/services/mistralai.py +0 -0
  47. lionagi/services/oai.py +34 -0
  48. lionagi/services/ollama.py +1 -0
  49. lionagi/services/openllm.py +0 -0
  50. lionagi/services/openrouter.py +32 -0
  51. lionagi/services/perplexity.py +0 -0
  52. lionagi/services/predibase.py +0 -0
  53. lionagi/services/rungpt.py +0 -0
  54. lionagi/services/service_objs.py +282 -0
  55. lionagi/services/vllm.py +0 -0
  56. lionagi/services/xinference.py +0 -0
  57. lionagi/structure/__init__.py +7 -0
  58. lionagi/structure/relationship.py +128 -0
  59. lionagi/structure/structure.py +160 -0
  60. lionagi/tests/__init__.py +0 -0
  61. lionagi/tests/test_flatten_util.py +426 -0
  62. lionagi/tools/__init__.py +0 -0
  63. lionagi/tools/coder.py +1 -0
  64. lionagi/tools/planner.py +1 -0
  65. lionagi/tools/prompter.py +1 -0
  66. lionagi/tools/sandbox.py +1 -0
  67. lionagi/tools/scorer.py +1 -0
  68. lionagi/tools/summarizer.py +1 -0
  69. lionagi/tools/validator.py +1 -0
  70. lionagi/utils/__init__.py +46 -8
  71. lionagi/utils/api_util.py +63 -416
  72. lionagi/utils/call_util.py +347 -0
  73. lionagi/utils/flat_util.py +540 -0
  74. lionagi/utils/io_util.py +102 -0
  75. lionagi/utils/load_utils.py +190 -0
  76. lionagi/utils/sys_util.py +85 -660
  77. lionagi/utils/tool_util.py +82 -199
  78. lionagi/utils/type_util.py +81 -0
  79. lionagi/version.py +1 -1
  80. {lionagi-0.0.111.dist-info → lionagi-0.0.113.dist-info}/METADATA +44 -15
  81. lionagi-0.0.113.dist-info/RECORD +84 -0
  82. lionagi/api/__init__.py +0 -8
  83. lionagi/api/oai_config.py +0 -16
  84. lionagi/session/__init__.py +0 -7
  85. lionagi/session/session.py +0 -380
  86. lionagi/utils/doc_util.py +0 -331
  87. lionagi/utils/log_util.py +0 -86
  88. lionagi-0.0.111.dist-info/RECORD +0 -20
  89. {lionagi-0.0.111.dist-info → lionagi-0.0.113.dist-info}/LICENSE +0 -0
  90. {lionagi-0.0.111.dist-info → lionagi-0.0.113.dist-info}/WHEEL +0 -0
  91. {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
@@ -0,0 +1 @@
1
+ # TODO
@@ -0,0 +1 @@
1
+ # TODO
@@ -0,0 +1 @@
1
+ # TODO
@@ -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 .sys_util import to_flat_dict, to_list, str_to_num, make_copy, to_temp, to_csv, hold_call, ahold_call, l_call, al_call, m_call, am_call, e_call, ae_call, get_timestamp, create_path, append_to_jsonl
2
- from .doc_util import dir_to_path, read_text, dir_to_files, file_to_chunks, get_bins
3
- from .log_util import DataLogger
4
- from .tool_util import ToolManager
5
- from .api_util import StatusTracker, AsyncQueue, RateLimiter, BaseAPIService
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
- "to_flat_dict", "to_list", "str_to_num", "make_copy", "to_temp", "to_csv", "hold_call", "ahold_call",
9
- "l_call", "al_call", "m_call", "am_call", "e_call", "ae_call", "get_timestamp", "create_path", "append_to_jsonl",
10
- "dir_to_path", "read_text", "dir_to_files", "file_to_chunks", "get_bins", "DataLogger", "ToolManager", "StatusTracker", "AsyncQueue", "RateLimiter", "BaseAPIService"
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
  ]