lionagi 0.12.2__py3-none-any.whl → 0.12.3__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/version.py CHANGED
@@ -1 +1 @@
1
- __version__ = "0.12.2"
1
+ __version__ = "0.12.3"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lionagi
3
- Version: 0.12.2
3
+ Version: 0.12.3
4
4
  Summary: An Intelligence Operating System.
5
5
  Author-email: HaiyangLi <quantocean.li@gmail.com>, Liangbingyan Luo <llby_luo@outlook.com>
6
6
  License: Apache License
@@ -219,19 +219,38 @@ Classifier: Programming Language :: Python :: 3.11
219
219
  Classifier: Programming Language :: Python :: 3.12
220
220
  Classifier: Programming Language :: Python :: 3.13
221
221
  Requires-Python: >=3.10
222
+ Requires-Dist: aiocache>=0.12.0
223
+ Requires-Dist: aiohttp>=3.10.0
222
224
  Requires-Dist: jinja2>=3.0.0
223
- Requires-Dist: khive>=0.2.7
224
225
  Requires-Dist: pandas>=2.0.0
226
+ Requires-Dist: pillow>=10.0.0
227
+ Requires-Dist: pydantic>2.0.0
228
+ Requires-Dist: python-dotenv>=1.1.0
225
229
  Requires-Dist: tiktoken>=0.8.0
230
+ Requires-Dist: toml>=0.9.0
226
231
  Provides-Extra: all
227
- Requires-Dist: khive[ollama,reader]; extra == 'all'
228
- Requires-Dist: litellm; extra == 'all'
232
+ Requires-Dist: docling>=2.15.1; extra == 'all'
233
+ Requires-Dist: litellm>=1.59.5; extra == 'all'
234
+ Requires-Dist: ollama>=0.4.7; extra == 'all'
235
+ Requires-Dist: openai>=1.60.0; extra == 'all'
236
+ Provides-Extra: docs
237
+ Requires-Dist: furo>=2024.8.6; extra == 'docs'
238
+ Requires-Dist: sphinx-autobuild>=2024.10.3; extra == 'docs'
239
+ Requires-Dist: sphinx>=8.1.3; extra == 'docs'
240
+ Provides-Extra: lint
241
+ Requires-Dist: black[jupyter]>=24.10.0; extra == 'lint'
242
+ Requires-Dist: isort>=5.13.2; extra == 'lint'
243
+ Requires-Dist: pre-commit>=4.0.1; extra == 'lint'
229
244
  Provides-Extra: llms
230
- Requires-Dist: litellm; extra == 'llms'
245
+ Requires-Dist: litellm>=1.59.5; extra == 'llms'
231
246
  Provides-Extra: ollama
232
- Requires-Dist: khive[ollama]; extra == 'ollama'
247
+ Requires-Dist: ollama>=0.4.7; extra == 'ollama'
248
+ Requires-Dist: openai>=1.60.0; extra == 'ollama'
249
+ Provides-Extra: test
250
+ Requires-Dist: pytest-asyncio>=0.25.0; extra == 'test'
251
+ Requires-Dist: pytest>=8.3.4; extra == 'test'
233
252
  Provides-Extra: tools
234
- Requires-Dist: khive[reader]; extra == 'tools'
253
+ Requires-Dist: docling>=2.15.1; extra == 'tools'
235
254
  Description-Content-Type: text/markdown
236
255
 
237
256
  ![PyPI - Version](https://img.shields.io/pypi/v/lionagi?labelColor=233476aa&color=231fc935)
@@ -239,9 +258,8 @@ Description-Content-Type: text/markdown
239
258
  ![Python Version](https://img.shields.io/badge/python-3.10%2B-blue)
240
259
 
241
260
  [Documentation](https://lion-agi.github.io/lionagi/) |
242
- [Discord](https://discord.gg/aqSJ2v46vu) |
261
+ [Discord](https://discord.gg/JDj9ENhUE8) |
243
262
  [PyPI](https://pypi.org/project/lionagi/) |
244
- [Roadmap](https://trello.com/b/3seomsrI/lionagi)
245
263
 
246
264
  # LION - Language InterOperable Network
247
265
 
@@ -3,8 +3,8 @@ lionagi/_class_registry.py,sha256=pfUO1DjFZIqr3OwnNMkFqL_fiEBrrf8-swkGmP_KDLE,31
3
3
  lionagi/_errors.py,sha256=JlBTFJnRWtVYcRxKb7fWFiJHLbykl1E19mSJ8sXYVxg,455
4
4
  lionagi/_types.py,sha256=iDdYewsP9rDrM7QY19_NDTcWUk7swp8vnGCrloHMtUM,53
5
5
  lionagi/settings.py,sha256=W52mM34E6jXF3GyqCFzVREKZrmnUqtZm_BVDsUiDI_s,1627
6
- lionagi/utils.py,sha256=KDcxyMcDrAMxixkQ1FhGkC81bXjae5_nYWB-vh8lyEc,53114
7
- lionagi/version.py,sha256=NJQQPiZZfrBXFMqZlsia0JrhloS2PexbdxYYUs0c2Us,23
6
+ lionagi/utils.py,sha256=uLTJKl7aTnFXV6ehA6zwiwEB7G2nQYKsO2pZ6mqFzUk,78908
7
+ lionagi/version.py,sha256=Qu8-91hLcRe7wfW37PwNdivTonHHKLrqtJPOAq3Jvhc,23
8
8
  lionagi/adapters/__init__.py,sha256=FJBV1Fb7GR9mcRApEB9bNP3IRMQ9Qjg5aVTouZFyTBU,45
9
9
  lionagi/adapters/adapter.py,sha256=aW7s1OKAdxHd8HBv2UcThn-r2Q08EyArssNyFobMLuA,3357
10
10
  lionagi/adapters/json_adapter.py,sha256=EJj0Jev46ZhU3ZMnlYwyzN2rLxjLCVrMDpHkEuggBvk,4561
@@ -19,21 +19,20 @@ lionagi/fields/__init__.py,sha256=8oU7Vfk-fKiULFKqhM6VpJMqdZcVXPTM7twVfNDN_SQ,60
19
19
  lionagi/fields/action.py,sha256=iWSApCM77jS0Oc28lb7G601Etkp-yjx5U1hfI_FQgfA,5792
20
20
  lionagi/fields/base.py,sha256=5CJc7j8kTTWzXwpYzkSAFzx4BglABfx3AElIATKB7bg,3857
21
21
  lionagi/fields/code.py,sha256=TFym51obzaSfCmeRoHZJyBtjfDI4tvl9F-1sjFc9rMw,7713
22
- lionagi/fields/file.py,sha256=BMrjxyyfQwC-7w5tA8sJmyjsKcWkldfHAL6dl8UGJr0,7313
22
+ lionagi/fields/file.py,sha256=DhQ_HE0RvTNzkvBGQHRgbMYSokDkzE8GEu814i6jw5Q,7297
23
23
  lionagi/fields/instruct.py,sha256=sMbCxEv0HQLa31JkJDmdrWWEzIfeKbcmN2hYOehz3Q0,4773
24
- lionagi/fields/reason.py,sha256=TnsViRY1QdwvEmfeUiYR8Mt0VAhyIHmlEesmYVEjcH0,1450
24
+ lionagi/fields/reason.py,sha256=3Ksz9_40dI-oQ9VtmpnYAmJdeDDIO-TwLDrf1ijbXGM,1438
25
25
  lionagi/fields/research.py,sha256=eEPKocx8eQy2E9FExRWVIo6MK_xvmwBAoRZciBY3RG0,1421
26
26
  lionagi/libs/__init__.py,sha256=5y5joOZzfFWERl75auAcNcKC3lImVJ5ZZGvvHZUFCJM,112
27
+ lionagi/libs/parse.py,sha256=JRS3bql0InHJqATnAatl-hQv4N--XXw4P77JHhTFnrc,1011
27
28
  lionagi/libs/file/__init__.py,sha256=5y5joOZzfFWERl75auAcNcKC3lImVJ5ZZGvvHZUFCJM,112
28
29
  lionagi/libs/file/chunk.py,sha256=XeVMwM33JF0X1W6udz_nhlb3DCevA_EK6A50Hn_e5SY,9300
29
- lionagi/libs/file/concat.py,sha256=nrL155_92YRTKAymAHbFY5CFNFiRwIc6-KRdjDydVzY,4018
30
- lionagi/libs/file/concat_files.py,sha256=r8-W8vI9nZFQ36hgQJkiSHT63gCQi9ckkE1hBkXzdtE,3218
31
- lionagi/libs/file/create_path.py,sha256=dCM_P2Nxmy9j2icB0CLMukwwQS4_IN219vsklQo4UsI,2704
30
+ lionagi/libs/file/concat.py,sha256=YSauXVBL3WWx5Mvpn208Cj7q9TLt_aq-0M9J1fm-ins,3864
31
+ lionagi/libs/file/concat_files.py,sha256=FoI983oWFzp9VfFDP7kmbRb3t1CPe5F5LCtsux0ASAs,3089
32
32
  lionagi/libs/file/file_ops.py,sha256=HBiIh1EljIJ5VTIXuyvJM0ppSs0YYOPUWmgDMJT634U,3430
33
- lionagi/libs/file/file_util.py,sha256=BNP1rhWCJXnj2FmOOb_QrxDlZOVC5ohMOSL4TSWS4PI,10562
34
33
  lionagi/libs/file/params.py,sha256=SZ5DkoffWfxWudOAYCfCxpL8UIm-1UjeyTtploo-Lqs,5824
35
34
  lionagi/libs/file/process.py,sha256=EsnEJcQUm4ReP7qkCeMvL4Qe6fLRcENVWZndh9TSUsc,8692
36
- lionagi/libs/file/save.py,sha256=Fo2C96XQ0orlnPE70ThLgqUx_tEnp4ZwGmU0FQy-cZ8,2862
35
+ lionagi/libs/file/save.py,sha256=TCxVlKxFFnr3xZ-HAXPpTomQoyiVrp6nKRoj-bcQt4k,2863
37
36
  lionagi/libs/nested/__init__.py,sha256=5y5joOZzfFWERl75auAcNcKC3lImVJ5ZZGvvHZUFCJM,112
38
37
  lionagi/libs/nested/flatten.py,sha256=sB4jxZRoaUbjak9RbIWVWNKz2hzkhQJPFffV_Ws1GA0,5479
39
38
  lionagi/libs/nested/nfilter.py,sha256=kF7AWjLFHr22SOjRBSTx-7iRPaR7gs0FY5Y4XF2sWJ8,1768
@@ -45,20 +44,12 @@ lionagi/libs/nested/nset.py,sha256=vkLR970hSzj8xCk-Z3RNQMJL2x0uMHmx1pw0VZQx2T0,3
45
44
  lionagi/libs/nested/unflatten.py,sha256=lTON1LfCyhZ3xeTEdBiIONcHLQouPcBNARTbXzHZ03U,2618
46
45
  lionagi/libs/nested/utils.py,sha256=r8xuBpH0qQaHMnCqXPF6unIKzw-TqwVbq-ARooWRERo,6090
47
46
  lionagi/libs/package/__init__.py,sha256=5y5joOZzfFWERl75auAcNcKC3lImVJ5ZZGvvHZUFCJM,112
48
- lionagi/libs/package/imports.py,sha256=AY8G7g3LdK1WdrpNhhAUrDum0sKeF8wJ7EXtzjS-Cz0,5624
47
+ lionagi/libs/package/imports.py,sha256=wg6Ip9dnW5rNPxINu-AT3XQLp1EQLaAFdehVZAVB140,424
49
48
  lionagi/libs/package/management.py,sha256=zgzZ1lNpUhunu_QExiobSYWlvBbR0EORXW4jrtV0wuE,1684
50
49
  lionagi/libs/package/params.py,sha256=4dJiuaTlnhho6OHmBv-02cHx89XRCjnKqpMhVRvTse8,1056
51
50
  lionagi/libs/package/system.py,sha256=UW8Y6tEPRCy_pBv_Q8CXJAIbuo7CJDDoWEDdnP0ixp4,564
52
- lionagi/libs/parse/__init__.py,sha256=5y5joOZzfFWERl75auAcNcKC3lImVJ5ZZGvvHZUFCJM,112
53
- lionagi/libs/parse/fuzzy_parse_json.py,sha256=tavyEg8s3oWAEdrusBb-Aj2fnMwnVJLOVkViboVAq9Q,3544
54
- lionagi/libs/parse/to_dict.py,sha256=t7zGXEVLOxfeHBm4vsmwaj44An2dwRNYt0xSy1SjEAM,9608
55
- lionagi/libs/parse/to_json.py,sha256=cCpLH5uUwDWqNUfeJ29LXLtOo4q1uHVG6xU5_I9ZNJQ,1893
56
- lionagi/libs/parse/to_num.py,sha256=ZRHDjpTCykPfDIZZa4rZKNaR_8ZHbPDFlw9rc02DrII,11610
57
- lionagi/libs/parse/to_xml.py,sha256=g-VkdVcDkFymiq_ggtO97OTGZaj7wwLJr0WEMuIDN-M,2112
58
- lionagi/libs/parse/xml_parser.py,sha256=2SVlNxKDqqJscmLN906Ns-uF9-pHAzs77IQ4RoeN5-g,4920
59
51
  lionagi/libs/schema/__init__.py,sha256=5y5joOZzfFWERl75auAcNcKC3lImVJ5ZZGvvHZUFCJM,112
60
52
  lionagi/libs/schema/as_readable.py,sha256=W4fi98WVkP5rfZ6A-iWqP5YFJexYCjt9Hf-l0iNs-2Q,5916
61
- lionagi/libs/schema/breakdown_pydantic_annotation.py,sha256=-Brc42n6VC66UHmbyNwnRJFxyzzz3XvuLvr54IEPXb0,1333
62
53
  lionagi/libs/schema/extract_code_block.py,sha256=PuJbJj1JnqR5fSZudowPcVPpEoKISLr0MjTOOVXSzwY,2394
63
54
  lionagi/libs/schema/extract_docstring.py,sha256=aYyLSRlB8lTH9QF9-6a56uph3AAkNuTyZ0S_duf5-fw,5729
64
55
  lionagi/libs/schema/function_to_schema.py,sha256=XAB031WbYu3a7eFJyYjXVMAjmtWYSYr5kC_DYgjiuyM,5604
@@ -75,7 +66,7 @@ lionagi/libs/token_transform/synthlang_/translate_to_synthlang.py,sha256=lRBpeKG
75
66
  lionagi/libs/token_transform/synthlang_/resources/frameworks/abstract_algebra.toml,sha256=2TuOAo97g8mNhdPH96HP8vYZpnC8neiP-KlhVqbp1Us,970
76
67
  lionagi/libs/token_transform/synthlang_/resources/frameworks/category_theory.toml,sha256=Stg9W3h8o7VkQ9tdAfSZmR3LctFqcH6OhOPdaw9BlIg,1064
77
68
  lionagi/libs/token_transform/synthlang_/resources/frameworks/complex_analysis.toml,sha256=iE6FS7Cn5_uJRG5-StLuMM4XVAk95bxhbYWwlstw_tA,1044
78
- lionagi/libs/token_transform/synthlang_/resources/frameworks/framework_options.json,sha256=_MQcXWBcgzPM6F13e_JDoF7rzTbi_zlXOXutyyYahBY,1384
69
+ lionagi/libs/token_transform/synthlang_/resources/frameworks/framework_options.json,sha256=phAkedPGrwgNGW8hgPyH6pKU47pvKEAnG7vheWFvOLc,1760
79
70
  lionagi/libs/token_transform/synthlang_/resources/frameworks/group_theory.toml,sha256=iVlcS250YMosNRv3l8bz3BT9Tx1xCmiwhfNt4CjjRYc,713
80
71
  lionagi/libs/token_transform/synthlang_/resources/frameworks/math_logic.toml,sha256=jeFOF8gjRhb4hYXpW7AxTX8uk9c6DvGulJK5Bowxhq4,1037
81
72
  lionagi/libs/token_transform/synthlang_/resources/frameworks/reflective_patterns.toml,sha256=LxBIVLHNLfvVdXjLAzqivrYaHNix514DLNYsbA-VSQ4,5730
@@ -145,7 +136,7 @@ lionagi/protocols/forms/report.py,sha256=SvJJjOSCTfVuqK7AKaY8ldQIGJeSK2zoyPWUV41
145
136
  lionagi/protocols/generic/__init__.py,sha256=5y5joOZzfFWERl75auAcNcKC3lImVJ5ZZGvvHZUFCJM,112
146
137
  lionagi/protocols/generic/element.py,sha256=Eaij2YpTWsGk28Tqjazmjmc_tOnalH7_iGFZrL6QJb4,14420
147
138
  lionagi/protocols/generic/event.py,sha256=InjBd2K9aSYxgai1c20d4jaJOkEx5VGFfb7iZbiMiNA,5200
148
- lionagi/protocols/generic/log.py,sha256=oXFldqTAGmLo32EZzxQT7J-CVR3ohQwmMZKR_ZbX0wQ,7482
139
+ lionagi/protocols/generic/log.py,sha256=vepclOaY3fdR1QgFDj9usOffsx9T-9PbgwXjTvm6twQ,7441
149
140
  lionagi/protocols/generic/pile.py,sha256=DfD1hOc7Mb3Iv-HMBPF9Y9HBjUYEJLUot-3AKniEjSo,31299
150
141
  lionagi/protocols/generic/processor.py,sha256=LTF9Enb-9jj5Wuy_jLanAhiesc5-Gm6WiSntZoAAm8w,10382
151
142
  lionagi/protocols/generic/progression.py,sha256=qlITq1qzV119iR5qR__fBAzV489S7d4t20E8uDRicEw,15189
@@ -168,7 +159,7 @@ lionagi/protocols/messages/instruction.py,sha256=0dUsUYd6xYsbOHU7GafvqBkpDQQoFOX
168
159
  lionagi/protocols/messages/manager.py,sha256=e1jW5JH_3jZpZbFCvWZX0TG0DCgzANRUejW_6NqbtDc,17182
169
160
  lionagi/protocols/messages/message.py,sha256=rrGbya6rF86UB8xZcRP1YjgfJIFCxEWPQfHDcMuyBnM,7724
170
161
  lionagi/protocols/messages/system.py,sha256=x0F1C57SFHaO2-Z9cy1QshYlxv8wjl7VppooaGKbMIg,4658
171
- lionagi/protocols/messages/templates/README.md,sha256=Ux1ua0lN8AP2Ry5_6_eyiPCBtcFHV6e-GdpmEFu3XCs,1282
162
+ lionagi/protocols/messages/templates/README.md,sha256=Ch4JrKSjd85fLitAYO1OhZjNOGKHoEwaKQlcV16jiUI,1286
172
163
  lionagi/protocols/messages/templates/action_request.jinja2,sha256=d6OmxHKyvvNDSK4bnBM3TGSUk_HeE_Q2EtLAQ0ZBEJg,120
173
164
  lionagi/protocols/messages/templates/action_response.jinja2,sha256=Mg0UxmXlIvtP_KPB0GcJxE1TP6lml9BwdPkW1PZxkg8,142
174
165
  lionagi/protocols/messages/templates/assistant_response.jinja2,sha256=oKOX4myBy7it1J1f92mvTS1iBUUlZfsJsY2fC42ygvc,119
@@ -193,7 +184,7 @@ lionagi/service/providers/types.py,sha256=NS91ysRFwOs0cpNeQgFhmtl7JrSz2pJm-tt7sZ
193
184
  lionagi/service/providers/anthropic_/__init__.py,sha256=5y5joOZzfFWERl75auAcNcKC3lImVJ5ZZGvvHZUFCJM,112
194
185
  lionagi/service/providers/anthropic_/messages.py,sha256=EnV2vh60k0aQvtnUitHzTlSmyrFxTVxcXAldANg7Rzc,3148
195
186
  lionagi/service/providers/exa_/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
196
- lionagi/service/providers/exa_/models.py,sha256=wwcMB-NOQ0uswK4ymc89bgCudcA_rkj_xogt6jF_rrI,83
187
+ lionagi/service/providers/exa_/models.py,sha256=263KP-JSxbxmomNrFeYjB_cebquoMOsCJeWsiKZ0mL4,5420
197
188
  lionagi/service/providers/exa_/search.py,sha256=Z3pyJH8KiWiquJSJw8Rd6D7x43BwTFHb2ESsgSicCk0,1932
198
189
  lionagi/service/providers/exa_/types.py,sha256=8ODjXpFajBE9-DGqBJNS--GObwmLSDi667xS84z_AgA,139
199
190
  lionagi/service/providers/groq_/__init__.py,sha256=5y5joOZzfFWERl75auAcNcKC3lImVJ5ZZGvvHZUFCJM,112
@@ -207,7 +198,7 @@ lionagi/service/providers/openrouter_/__init__.py,sha256=5y5joOZzfFWERl75auAcNcK
207
198
  lionagi/service/providers/openrouter_/chat_completions.py,sha256=0pdXjJCXmCPPbKKVubrnqofaodTOxWTJam8fd3NgrNk,1525
208
199
  lionagi/service/providers/perplexity_/__init__.py,sha256=5y5joOZzfFWERl75auAcNcKC3lImVJ5ZZGvvHZUFCJM,112
209
200
  lionagi/service/providers/perplexity_/chat_completions.py,sha256=O4MIS_3xIINGjkAZdlw0Bu_jAfBDR4VZA1F8JW2EU1M,1197
210
- lionagi/service/providers/perplexity_/models.py,sha256=T2GFWKvCTDjp4kFobuAqzuAYBX0_VlmHhYacHloR3uo,154
201
+ lionagi/service/providers/perplexity_/models.py,sha256=Fm5NbmWMdFkDKS0Cec__bNvs3St27lgqxFbHKyNCLsw,4945
211
202
  lionagi/session/__init__.py,sha256=5y5joOZzfFWERl75auAcNcKC3lImVJ5ZZGvvHZUFCJM,112
212
203
  lionagi/session/branch.py,sha256=-4VZJna20HrftkVJoYiEgCb4HrUlP6aBRA-XlrHageQ,69722
213
204
  lionagi/session/prompts.py,sha256=AhuHL19s0TijVZX3tMKUKMi6l88xeVdpkuEn2vJSRyU,3236
@@ -217,7 +208,7 @@ lionagi/tools/base.py,sha256=cld32pyjaTUdyiqZ8hNyJjWKAhcJ8RQNhgImI7R8b-E,1940
217
208
  lionagi/tools/types.py,sha256=XtJLY0m-Yi_ZLWhm0KycayvqMCZd--HxfQ0x9vFUYDE,230
218
209
  lionagi/tools/file/__init__.py,sha256=5y5joOZzfFWERl75auAcNcKC3lImVJ5ZZGvvHZUFCJM,112
219
210
  lionagi/tools/file/reader.py,sha256=K0PtEI1s-Ol-uthBUdGFzDLrQNFr4l1bRkosn2jios8,9539
220
- lionagi-0.12.2.dist-info/METADATA,sha256=JrekthbdkAaX3sK7DWVfz_tN6vfb_YrSzfIXca88npQ,18423
221
- lionagi-0.12.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
222
- lionagi-0.12.2.dist-info/licenses/LICENSE,sha256=VXFWsdoN5AAknBCgFqQNgPWYx7OPp-PFEP961zGdOjc,11288
223
- lionagi-0.12.2.dist-info/RECORD,,
211
+ lionagi-0.12.3.dist-info/METADATA,sha256=YTtNnMWbydX_OzuGlBuYNztS6j54NQf3rlfntX0L4rI,19154
212
+ lionagi-0.12.3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
213
+ lionagi-0.12.3.dist-info/licenses/LICENSE,sha256=VXFWsdoN5AAknBCgFqQNgPWYx7OPp-PFEP961zGdOjc,11288
214
+ lionagi-0.12.3.dist-info/RECORD,,
@@ -1,80 +0,0 @@
1
- # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
- #
3
- # SPDX-License-Identifier: Apache-2.0
4
-
5
- import uuid
6
- from datetime import datetime
7
- from pathlib import Path
8
-
9
-
10
- def create_path(
11
- directory: Path | str,
12
- filename: str,
13
- extension: str = None,
14
- timestamp: bool = False,
15
- dir_exist_ok: bool = True,
16
- file_exist_ok: bool = False,
17
- time_prefix: bool = False,
18
- timestamp_format: str | None = None,
19
- random_hash_digits: int = 0,
20
- ) -> Path:
21
- """
22
- Generate a new file path with optional timestamp and a random suffix.
23
-
24
- Args:
25
- directory: The directory where the file will be created.
26
- filename: The base name of the file to create.
27
- extension: The file extension, if not part of filename.
28
- timestamp: If True, add a timestamp to the filename.
29
- dir_exist_ok: If True, don't error if directory exists.
30
- file_exist_ok: If True, allow overwriting existing files.
31
- time_prefix: If True, timestamp is prefixed instead of suffixed.
32
- timestamp_format: Custom format for timestamp (default: "%Y%m%d%H%M%S").
33
- random_hash_digits: Number of hex digits for a random suffix.
34
-
35
- Returns:
36
- The full Path to the new or existing file.
37
-
38
- Raises:
39
- ValueError: If filename is invalid.
40
- FileExistsError: If file exists and file_exist_ok=False.
41
- """
42
- if "/" in filename:
43
- sub_dir, filename = filename.split("/")[:-1], filename.split("/")[-1]
44
- directory = Path(directory) / "/".join(sub_dir)
45
-
46
- if "\\" in filename:
47
- raise ValueError("Filename cannot contain directory separators.")
48
-
49
- directory = Path(directory)
50
-
51
- # Extract name and extension from filename if present
52
- if "." in filename:
53
- name, ext = filename.rsplit(".", 1)
54
- else:
55
- name, ext = filename, extension
56
-
57
- # Ensure extension has a single leading dot
58
- ext = f".{ext.lstrip('.')}" if ext else ""
59
-
60
- # Add timestamp if requested
61
- if timestamp:
62
- ts_str = datetime.now().strftime(timestamp_format or "%Y%m%d%H%M%S")
63
- name = f"{ts_str}_{name}" if time_prefix else f"{name}_{ts_str}"
64
-
65
- # Add random suffix if requested
66
- if random_hash_digits > 0:
67
- # Use UUID4 and truncate its hex for random suffix
68
- random_suffix = uuid.uuid4().hex[:random_hash_digits]
69
- name = f"{name}-{random_suffix}"
70
-
71
- full_path = directory / f"{name}{ext}"
72
-
73
- # Check if file or directory existence
74
- full_path.parent.mkdir(parents=True, exist_ok=dir_exist_ok)
75
- if full_path.exists() and not file_exist_ok:
76
- raise FileExistsError(
77
- f"File {full_path} already exists and file_exist_ok is False."
78
- )
79
-
80
- return full_path
@@ -1,358 +0,0 @@
1
- # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
- #
3
- # SPDX-License-Identifier: Apache-2.0
4
-
5
- from collections.abc import Callable
6
- from pathlib import Path
7
- from typing import Any, Literal
8
-
9
-
10
- class FileUtil:
11
-
12
- @staticmethod
13
- def chunk_by_chars(
14
- text: str,
15
- chunk_size: int = 2048,
16
- overlap: float = 0,
17
- threshold: int = 256,
18
- ) -> list[str]:
19
- from .chunk import chunk_by_chars
20
-
21
- return chunk_by_chars(
22
- text,
23
- chunk_size=chunk_size,
24
- overlap=overlap,
25
- threshold=threshold,
26
- )
27
-
28
- @staticmethod
29
- def chunk_by_tokens(
30
- text: str,
31
- tokenizer: Callable[[str], list[str]] = str.split,
32
- chunk_size: int = 1024,
33
- overlap: float = 0,
34
- threshold: int = 256,
35
- ) -> list[str]:
36
- from .chunk import chunk_by_tokens
37
-
38
- return chunk_by_tokens(
39
- text,
40
- tokenizer=tokenizer,
41
- chunk_size=chunk_size,
42
- overlap=overlap,
43
- threshold=threshold,
44
- )
45
-
46
- @staticmethod
47
- def chunk_content(
48
- content: str,
49
- chunk_by: Literal["chars", "tokens"] = "chars",
50
- tokenizer: Callable[[str], list[str]] = str.split,
51
- chunk_size: int = 1024,
52
- overlap: float = 0,
53
- threshold: int = 256,
54
- ) -> list[str]:
55
- from .chunk import chunk_content
56
-
57
- return chunk_content(
58
- content,
59
- chunk_by=chunk_by,
60
- tokenizer=tokenizer,
61
- chunk_size=chunk_size,
62
- overlap=overlap,
63
- threshold=threshold,
64
- )
65
-
66
- @staticmethod
67
- def concat_files(
68
- data_path: str | Path | list,
69
- file_types: list[str],
70
- output_dir: str | Path = None,
71
- output_filename: str = None,
72
- file_exist_ok: bool = True,
73
- recursive: bool = True,
74
- verbose: bool = True,
75
- threshold: int = 0,
76
- return_fps: bool = False,
77
- return_files: bool = False,
78
- **kwargs,
79
- ) -> (
80
- list[str] | str | tuple[list[str], list[Path]] | tuple[str, list[Path]]
81
- ):
82
- from .concat_files import concat_files
83
-
84
- return concat_files(
85
- data_path,
86
- file_types=file_types,
87
- output_dir=output_dir,
88
- output_filename=output_filename,
89
- file_exist_ok=file_exist_ok,
90
- recursive=recursive,
91
- verbose=verbose,
92
- threshold=threshold,
93
- return_fps=return_fps,
94
- return_files=return_files,
95
- **kwargs,
96
- )
97
-
98
- @staticmethod
99
- def concat(
100
- data_path: str | Path | list,
101
- file_types: list[str],
102
- output_dir: str | Path = None,
103
- output_filename: str = None,
104
- file_exist_ok: bool = True,
105
- recursive: bool = True,
106
- verbose: bool = True,
107
- threshold: int = 0,
108
- return_fps: bool = False,
109
- return_files: bool = False,
110
- exclude_patterns: list[str] = None,
111
- **kwargs,
112
- ) -> dict[str, Any]:
113
- from .concat import concat
114
-
115
- return concat(
116
- data_path,
117
- file_types=file_types,
118
- output_dir=output_dir,
119
- output_filename=output_filename,
120
- file_exist_ok=file_exist_ok,
121
- recursive=recursive,
122
- verbose=verbose,
123
- threshold=threshold,
124
- return_fps=return_fps,
125
- return_files=return_files,
126
- exclude_patterns=exclude_patterns,
127
- **kwargs,
128
- )
129
-
130
- @staticmethod
131
- def copy_file(src: Path | str, dest: Path | str) -> None:
132
- from .file_ops import copy_file
133
-
134
- copy_file(src, dest)
135
-
136
- @staticmethod
137
- def get_file_size(path: Path | str) -> int:
138
- from .file_ops import get_file_size
139
-
140
- return get_file_size(path)
141
-
142
- @staticmethod
143
- def list_files(
144
- dir_path: Path | str, extension: str | None = None
145
- ) -> list[Path]:
146
- from .file_ops import list_files
147
-
148
- return list_files(dir_path, extension=extension)
149
-
150
- @staticmethod
151
- def read_file(file_path: Path | str, encoding: str = "utf-8") -> str:
152
- from .file_ops import read_file
153
-
154
- return read_file(file_path, encoding=encoding)
155
-
156
- @staticmethod
157
- def read_image_to_base64(image_path: str | Path) -> str:
158
- import base64
159
-
160
- import cv2 # type: ignore[import]
161
-
162
- image_path = str(image_path)
163
- image = cv2.imread(image_path, cv2.COLOR_BGR2RGB)
164
-
165
- if image is None:
166
- raise ValueError(f"Could not read image from path: {image_path}")
167
-
168
- file_extension = "." + image_path.split(".")[-1]
169
-
170
- success, buffer = cv2.imencode(file_extension, image)
171
- if not success:
172
- raise ValueError(
173
- f"Could not encode image to {file_extension} format."
174
- )
175
- encoded_image = base64.b64encode(buffer).decode("utf-8")
176
- return encoded_image
177
-
178
- @staticmethod
179
- def pdf_to_images(
180
- pdf_path: str, output_folder: str, dpi: int = 300, fmt: str = "jpeg"
181
- ) -> list:
182
- """
183
- Convert a PDF file into images, one image per page.
184
-
185
- Args:
186
- pdf_path (str): Path to the input PDF file.
187
- output_folder (str): Directory to save the output images.
188
- dpi (int): Dots per inch (resolution) for conversion (default: 300).
189
- fmt (str): Image format (default: 'jpeg'). Use 'png' if preferred.
190
-
191
- Returns:
192
- list: A list of file paths for the saved images.
193
- """
194
- import os
195
-
196
- from lionagi.utils import check_import
197
-
198
- convert_from_path = check_import(
199
- "pdf2image", import_name="convert_from_path"
200
- )
201
-
202
- # Ensure the output folder exists
203
- os.makedirs(output_folder, exist_ok=True)
204
-
205
- # Convert PDF to a list of PIL Image objects
206
- images = convert_from_path(pdf_path, dpi=dpi)
207
-
208
- saved_paths = []
209
- for i, image in enumerate(images):
210
- # Construct the output file name
211
- image_file = os.path.join(output_folder, f"page_{i + 1}.{fmt}")
212
- image.save(image_file, fmt.upper())
213
- saved_paths.append(image_file)
214
-
215
- return saved_paths
216
-
217
- @staticmethod
218
- def dir_to_files(
219
- directory: str | Path,
220
- file_types: list[str] | None = None,
221
- max_workers: int | None = None,
222
- ignore_errors: bool = False,
223
- verbose: bool = False,
224
- recursive: bool = False,
225
- ) -> list[Path]:
226
- from .process import dir_to_files
227
-
228
- return dir_to_files(
229
- directory,
230
- file_types=file_types,
231
- max_workers=max_workers,
232
- ignore_errors=ignore_errors,
233
- verbose=verbose,
234
- recursive=recursive,
235
- )
236
-
237
- @staticmethod
238
- def file_to_chunks(
239
- file_path: str | Path,
240
- chunk_by: Literal["chars", "tokens"] = "chars",
241
- chunk_size: int = 1500,
242
- overlap: float = 0.1,
243
- threshold: int = 200,
244
- encoding: str = "utf-8",
245
- custom_metadata: dict[str, Any] | None = None,
246
- output_dir: str | Path | None = None,
247
- verbose: bool = False,
248
- timestamp: bool = True,
249
- random_hash_digits: int = 4,
250
- as_node: bool = False,
251
- ) -> list[dict[str, Any]]:
252
- from .file_ops import file_to_chunks
253
-
254
- return file_to_chunks(
255
- file_path,
256
- chunk_by=chunk_by,
257
- chunk_size=chunk_size,
258
- overlap=overlap,
259
- threshold=threshold,
260
- encoding=encoding,
261
- custom_metadata=custom_metadata,
262
- output_dir=output_dir,
263
- verbose=verbose,
264
- timestamp=timestamp,
265
- random_hash_digits=random_hash_digits,
266
- as_node=as_node,
267
- )
268
-
269
- @staticmethod
270
- def chunk(
271
- *,
272
- text: str | None = None,
273
- url_or_path: str | Path = None,
274
- file_types: list[str] | None = None, # only local files
275
- recursive: bool = False, # only local files
276
- tokenizer: Callable[[str], list[str]] = None,
277
- chunk_by: Literal["chars", "tokens"] = "chars",
278
- chunk_size: int = 1500,
279
- overlap: float = 0.1,
280
- threshold: int = 200,
281
- output_file: str | Path | None = None,
282
- metadata: dict[str, Any] | None = None,
283
- reader_tool: Callable = None,
284
- as_node: bool = False,
285
- ) -> list:
286
- from .process import chunk
287
-
288
- return chunk(
289
- text=text,
290
- url_or_path=url_or_path,
291
- file_types=file_types,
292
- recursive=recursive,
293
- tokenizer=tokenizer,
294
- chunk_by=chunk_by,
295
- chunk_size=chunk_size,
296
- overlap=overlap,
297
- threshold=threshold,
298
- output_file=output_file,
299
- metadata=metadata,
300
- reader_tool=reader_tool,
301
- as_node=as_node,
302
- )
303
-
304
- @staticmethod
305
- def save_to_file(
306
- text: str,
307
- directory: str | Path,
308
- filename: str,
309
- extension: str = "txt",
310
- timestamp: bool = True,
311
- dir_exist_ok: bool = True,
312
- file_exist_ok: bool = True,
313
- time_prefix: bool = False,
314
- timestamp_format: str = "%Y%m%d_%H%M%S",
315
- random_hash_digits: int = 4,
316
- verbose: bool = False,
317
- ) -> Path:
318
- from .save import save_to_file
319
-
320
- return save_to_file(
321
- text,
322
- directory=directory,
323
- filename=filename,
324
- extension=extension,
325
- timestamp=timestamp,
326
- dir_exist_ok=dir_exist_ok,
327
- file_exist_ok=file_exist_ok,
328
- time_prefix=time_prefix,
329
- timestamp_format=timestamp_format,
330
- random_hash_digits=random_hash_digits,
331
- verbose=verbose,
332
- )
333
-
334
- @staticmethod
335
- def create_path(
336
- directory: Path | str,
337
- filename: str,
338
- extension: str = None,
339
- timestamp: bool = False,
340
- dir_exist_ok: bool = True,
341
- file_exist_ok: bool = False,
342
- time_prefix: bool = False,
343
- timestamp_format: str | None = None,
344
- random_hash_digits: int = 0,
345
- ) -> Path:
346
- from .create_path import create_path
347
-
348
- return create_path(
349
- directory=directory,
350
- filename=filename,
351
- extension=extension,
352
- timestamp=timestamp,
353
- dir_exist_ok=dir_exist_ok,
354
- file_exist_ok=file_exist_ok,
355
- time_prefix=time_prefix,
356
- timestamp_format=timestamp_format,
357
- random_hash_digits=random_hash_digits,
358
- )
@@ -1,3 +0,0 @@
1
- # Copyright (c) 2023 - 2025, HaiyangLi <quantocean.li at gmail dot com>
2
- #
3
- # SPDX-License-Identifier: Apache-2.0