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.
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
  ]