lionagi 0.0.312__py3-none-any.whl → 0.2.1__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
Files changed (268) hide show
  1. lionagi/__init__.py +61 -3
  2. lionagi/core/__init__.py +0 -14
  3. lionagi/core/_setting/_setting.py +59 -0
  4. lionagi/core/action/__init__.py +14 -0
  5. lionagi/core/action/function_calling.py +136 -0
  6. lionagi/core/action/manual.py +1 -0
  7. lionagi/core/action/node.py +109 -0
  8. lionagi/core/action/tool.py +114 -0
  9. lionagi/core/action/tool_manager.py +356 -0
  10. lionagi/core/agent/__init__.py +0 -3
  11. lionagi/core/agent/base_agent.py +45 -36
  12. lionagi/core/agent/eval/evaluator.py +1 -0
  13. lionagi/core/agent/eval/vote.py +40 -0
  14. lionagi/core/agent/learn/learner.py +59 -0
  15. lionagi/core/agent/plan/unit_template.py +1 -0
  16. lionagi/core/collections/__init__.py +17 -0
  17. lionagi/core/collections/_logger.py +319 -0
  18. lionagi/core/collections/abc/__init__.py +53 -0
  19. lionagi/core/collections/abc/component.py +615 -0
  20. lionagi/core/collections/abc/concepts.py +297 -0
  21. lionagi/core/collections/abc/exceptions.py +150 -0
  22. lionagi/core/collections/abc/util.py +45 -0
  23. lionagi/core/collections/exchange.py +161 -0
  24. lionagi/core/collections/flow.py +426 -0
  25. lionagi/core/collections/model.py +419 -0
  26. lionagi/core/collections/pile.py +913 -0
  27. lionagi/core/collections/progression.py +236 -0
  28. lionagi/core/collections/util.py +64 -0
  29. lionagi/core/director/direct.py +314 -0
  30. lionagi/core/director/director.py +2 -0
  31. lionagi/core/engine/branch_engine.py +333 -0
  32. lionagi/core/engine/instruction_map_engine.py +204 -0
  33. lionagi/core/engine/sandbox_.py +14 -0
  34. lionagi/core/engine/script_engine.py +99 -0
  35. lionagi/core/executor/base_executor.py +90 -0
  36. lionagi/core/executor/graph_executor.py +330 -0
  37. lionagi/core/executor/neo4j_executor.py +384 -0
  38. lionagi/core/generic/__init__.py +7 -0
  39. lionagi/core/generic/edge.py +112 -0
  40. lionagi/core/generic/edge_condition.py +16 -0
  41. lionagi/core/generic/graph.py +236 -0
  42. lionagi/core/generic/hyperedge.py +1 -0
  43. lionagi/core/generic/node.py +220 -0
  44. lionagi/core/generic/tree.py +48 -0
  45. lionagi/core/generic/tree_node.py +79 -0
  46. lionagi/core/mail/__init__.py +7 -3
  47. lionagi/core/mail/mail.py +25 -0
  48. lionagi/core/mail/mail_manager.py +142 -58
  49. lionagi/core/mail/package.py +45 -0
  50. lionagi/core/mail/start_mail.py +36 -0
  51. lionagi/core/message/__init__.py +19 -0
  52. lionagi/core/message/action_request.py +133 -0
  53. lionagi/core/message/action_response.py +135 -0
  54. lionagi/core/message/assistant_response.py +95 -0
  55. lionagi/core/message/instruction.py +234 -0
  56. lionagi/core/message/message.py +101 -0
  57. lionagi/core/message/system.py +86 -0
  58. lionagi/core/message/util.py +283 -0
  59. lionagi/core/report/__init__.py +4 -0
  60. lionagi/core/report/base.py +217 -0
  61. lionagi/core/report/form.py +231 -0
  62. lionagi/core/report/report.py +166 -0
  63. lionagi/core/report/util.py +28 -0
  64. lionagi/core/rule/__init__.py +0 -0
  65. lionagi/core/rule/_default.py +16 -0
  66. lionagi/core/rule/action.py +99 -0
  67. lionagi/core/rule/base.py +238 -0
  68. lionagi/core/rule/boolean.py +56 -0
  69. lionagi/core/rule/choice.py +47 -0
  70. lionagi/core/rule/mapping.py +96 -0
  71. lionagi/core/rule/number.py +71 -0
  72. lionagi/core/rule/rulebook.py +109 -0
  73. lionagi/core/rule/string.py +52 -0
  74. lionagi/core/rule/util.py +35 -0
  75. lionagi/core/session/__init__.py +0 -3
  76. lionagi/core/session/branch.py +431 -0
  77. lionagi/core/session/directive_mixin.py +287 -0
  78. lionagi/core/session/session.py +230 -902
  79. lionagi/core/structure/__init__.py +1 -0
  80. lionagi/core/structure/chain.py +1 -0
  81. lionagi/core/structure/forest.py +1 -0
  82. lionagi/core/structure/graph.py +1 -0
  83. lionagi/core/structure/tree.py +1 -0
  84. lionagi/core/unit/__init__.py +5 -0
  85. lionagi/core/unit/parallel_unit.py +245 -0
  86. lionagi/core/unit/template/__init__.py +0 -0
  87. lionagi/core/unit/template/action.py +81 -0
  88. lionagi/core/unit/template/base.py +51 -0
  89. lionagi/core/unit/template/plan.py +84 -0
  90. lionagi/core/unit/template/predict.py +109 -0
  91. lionagi/core/unit/template/score.py +124 -0
  92. lionagi/core/unit/template/select.py +104 -0
  93. lionagi/core/unit/unit.py +362 -0
  94. lionagi/core/unit/unit_form.py +305 -0
  95. lionagi/core/unit/unit_mixin.py +1168 -0
  96. lionagi/core/unit/util.py +71 -0
  97. lionagi/core/validator/__init__.py +0 -0
  98. lionagi/core/validator/validator.py +364 -0
  99. lionagi/core/work/__init__.py +0 -0
  100. lionagi/core/work/work.py +76 -0
  101. lionagi/core/work/work_function.py +101 -0
  102. lionagi/core/work/work_queue.py +103 -0
  103. lionagi/core/work/worker.py +258 -0
  104. lionagi/core/work/worklog.py +120 -0
  105. lionagi/experimental/__init__.py +0 -0
  106. lionagi/experimental/compressor/__init__.py +0 -0
  107. lionagi/experimental/compressor/base.py +46 -0
  108. lionagi/experimental/compressor/llm_compressor.py +247 -0
  109. lionagi/experimental/compressor/llm_summarizer.py +61 -0
  110. lionagi/experimental/compressor/util.py +70 -0
  111. lionagi/experimental/directive/__init__.py +19 -0
  112. lionagi/experimental/directive/parser/__init__.py +0 -0
  113. lionagi/experimental/directive/parser/base_parser.py +282 -0
  114. lionagi/experimental/directive/template/__init__.py +0 -0
  115. lionagi/experimental/directive/template/base_template.py +79 -0
  116. lionagi/experimental/directive/template/schema.py +36 -0
  117. lionagi/experimental/directive/tokenizer.py +73 -0
  118. lionagi/experimental/evaluator/__init__.py +0 -0
  119. lionagi/experimental/evaluator/ast_evaluator.py +131 -0
  120. lionagi/experimental/evaluator/base_evaluator.py +218 -0
  121. lionagi/experimental/knowledge/__init__.py +0 -0
  122. lionagi/experimental/knowledge/base.py +10 -0
  123. lionagi/experimental/knowledge/graph.py +0 -0
  124. lionagi/experimental/memory/__init__.py +0 -0
  125. lionagi/experimental/strategies/__init__.py +0 -0
  126. lionagi/experimental/strategies/base.py +1 -0
  127. lionagi/integrations/bridge/autogen_/__init__.py +0 -0
  128. lionagi/integrations/bridge/autogen_/autogen_.py +124 -0
  129. lionagi/integrations/bridge/langchain_/documents.py +4 -0
  130. lionagi/integrations/bridge/llamaindex_/index.py +30 -0
  131. lionagi/integrations/bridge/llamaindex_/llama_index_bridge.py +6 -0
  132. lionagi/integrations/bridge/llamaindex_/llama_pack.py +227 -0
  133. lionagi/integrations/bridge/llamaindex_/node_parser.py +6 -9
  134. lionagi/integrations/bridge/pydantic_/pydantic_bridge.py +1 -0
  135. lionagi/integrations/bridge/transformers_/__init__.py +0 -0
  136. lionagi/integrations/bridge/transformers_/install_.py +36 -0
  137. lionagi/integrations/chunker/__init__.py +0 -0
  138. lionagi/integrations/chunker/chunk.py +312 -0
  139. lionagi/integrations/config/oai_configs.py +38 -7
  140. lionagi/integrations/config/ollama_configs.py +1 -1
  141. lionagi/integrations/config/openrouter_configs.py +14 -2
  142. lionagi/integrations/loader/__init__.py +0 -0
  143. lionagi/integrations/loader/load.py +253 -0
  144. lionagi/integrations/loader/load_util.py +195 -0
  145. lionagi/integrations/provider/_mapping.py +46 -0
  146. lionagi/integrations/provider/litellm.py +2 -1
  147. lionagi/integrations/provider/mlx_service.py +16 -9
  148. lionagi/integrations/provider/oai.py +91 -4
  149. lionagi/integrations/provider/ollama.py +7 -6
  150. lionagi/integrations/provider/openrouter.py +115 -8
  151. lionagi/integrations/provider/services.py +2 -2
  152. lionagi/integrations/provider/transformers.py +18 -22
  153. lionagi/integrations/storage/__init__.py +3 -0
  154. lionagi/integrations/storage/neo4j.py +665 -0
  155. lionagi/integrations/storage/storage_util.py +287 -0
  156. lionagi/integrations/storage/structure_excel.py +285 -0
  157. lionagi/integrations/storage/to_csv.py +63 -0
  158. lionagi/integrations/storage/to_excel.py +83 -0
  159. lionagi/libs/__init__.py +26 -1
  160. lionagi/libs/ln_api.py +78 -23
  161. lionagi/libs/ln_context.py +37 -0
  162. lionagi/libs/ln_convert.py +21 -9
  163. lionagi/libs/ln_func_call.py +69 -28
  164. lionagi/libs/ln_image.py +107 -0
  165. lionagi/libs/ln_knowledge_graph.py +405 -0
  166. lionagi/libs/ln_nested.py +26 -11
  167. lionagi/libs/ln_parse.py +110 -14
  168. lionagi/libs/ln_queue.py +117 -0
  169. lionagi/libs/ln_tokenize.py +164 -0
  170. lionagi/{core/prompt/field_validator.py → libs/ln_validate.py} +79 -14
  171. lionagi/libs/special_tokens.py +172 -0
  172. lionagi/libs/sys_util.py +107 -2
  173. lionagi/lions/__init__.py +0 -0
  174. lionagi/lions/coder/__init__.py +0 -0
  175. lionagi/lions/coder/add_feature.py +20 -0
  176. lionagi/lions/coder/base_prompts.py +22 -0
  177. lionagi/lions/coder/code_form.py +13 -0
  178. lionagi/lions/coder/coder.py +168 -0
  179. lionagi/lions/coder/util.py +96 -0
  180. lionagi/lions/researcher/__init__.py +0 -0
  181. lionagi/lions/researcher/data_source/__init__.py +0 -0
  182. lionagi/lions/researcher/data_source/finhub_.py +191 -0
  183. lionagi/lions/researcher/data_source/google_.py +199 -0
  184. lionagi/lions/researcher/data_source/wiki_.py +96 -0
  185. lionagi/lions/researcher/data_source/yfinance_.py +21 -0
  186. lionagi/tests/integrations/__init__.py +0 -0
  187. lionagi/tests/libs/__init__.py +0 -0
  188. lionagi/tests/libs/test_field_validators.py +353 -0
  189. lionagi/tests/{test_libs → libs}/test_func_call.py +23 -21
  190. lionagi/tests/{test_libs → libs}/test_nested.py +36 -21
  191. lionagi/tests/{test_libs → libs}/test_parse.py +1 -1
  192. lionagi/tests/libs/test_queue.py +67 -0
  193. lionagi/tests/test_core/collections/__init__.py +0 -0
  194. lionagi/tests/test_core/collections/test_component.py +206 -0
  195. lionagi/tests/test_core/collections/test_exchange.py +138 -0
  196. lionagi/tests/test_core/collections/test_flow.py +145 -0
  197. lionagi/tests/test_core/collections/test_pile.py +171 -0
  198. lionagi/tests/test_core/collections/test_progression.py +129 -0
  199. lionagi/tests/test_core/generic/__init__.py +0 -0
  200. lionagi/tests/test_core/generic/test_edge.py +67 -0
  201. lionagi/tests/test_core/generic/test_graph.py +96 -0
  202. lionagi/tests/test_core/generic/test_node.py +106 -0
  203. lionagi/tests/test_core/generic/test_tree_node.py +73 -0
  204. lionagi/tests/test_core/test_branch.py +115 -292
  205. lionagi/tests/test_core/test_form.py +46 -0
  206. lionagi/tests/test_core/test_report.py +105 -0
  207. lionagi/tests/test_core/test_validator.py +111 -0
  208. lionagi/version.py +1 -1
  209. {lionagi-0.0.312.dist-info → lionagi-0.2.1.dist-info}/LICENSE +12 -11
  210. {lionagi-0.0.312.dist-info → lionagi-0.2.1.dist-info}/METADATA +19 -118
  211. lionagi-0.2.1.dist-info/RECORD +240 -0
  212. lionagi/core/branch/__init__.py +0 -4
  213. lionagi/core/branch/base_branch.py +0 -654
  214. lionagi/core/branch/branch.py +0 -471
  215. lionagi/core/branch/branch_flow_mixin.py +0 -96
  216. lionagi/core/branch/executable_branch.py +0 -347
  217. lionagi/core/branch/util.py +0 -323
  218. lionagi/core/direct/__init__.py +0 -6
  219. lionagi/core/direct/predict.py +0 -161
  220. lionagi/core/direct/score.py +0 -278
  221. lionagi/core/direct/select.py +0 -169
  222. lionagi/core/direct/utils.py +0 -87
  223. lionagi/core/direct/vote.py +0 -64
  224. lionagi/core/flow/base/baseflow.py +0 -23
  225. lionagi/core/flow/monoflow/ReAct.py +0 -238
  226. lionagi/core/flow/monoflow/__init__.py +0 -9
  227. lionagi/core/flow/monoflow/chat.py +0 -95
  228. lionagi/core/flow/monoflow/chat_mixin.py +0 -263
  229. lionagi/core/flow/monoflow/followup.py +0 -214
  230. lionagi/core/flow/polyflow/__init__.py +0 -1
  231. lionagi/core/flow/polyflow/chat.py +0 -248
  232. lionagi/core/mail/schema.py +0 -56
  233. lionagi/core/messages/__init__.py +0 -3
  234. lionagi/core/messages/schema.py +0 -533
  235. lionagi/core/prompt/prompt_template.py +0 -316
  236. lionagi/core/schema/__init__.py +0 -22
  237. lionagi/core/schema/action_node.py +0 -29
  238. lionagi/core/schema/base_mixin.py +0 -296
  239. lionagi/core/schema/base_node.py +0 -199
  240. lionagi/core/schema/condition.py +0 -24
  241. lionagi/core/schema/data_logger.py +0 -354
  242. lionagi/core/schema/data_node.py +0 -93
  243. lionagi/core/schema/prompt_template.py +0 -67
  244. lionagi/core/schema/structure.py +0 -910
  245. lionagi/core/tool/__init__.py +0 -3
  246. lionagi/core/tool/tool_manager.py +0 -280
  247. lionagi/integrations/bridge/pydantic_/base_model.py +0 -7
  248. lionagi/tests/test_core/test_base_branch.py +0 -427
  249. lionagi/tests/test_core/test_chat_flow.py +0 -63
  250. lionagi/tests/test_core/test_mail_manager.py +0 -75
  251. lionagi/tests/test_core/test_prompts.py +0 -51
  252. lionagi/tests/test_core/test_session.py +0 -254
  253. lionagi/tests/test_core/test_session_base_util.py +0 -312
  254. lionagi/tests/test_core/test_tool_manager.py +0 -95
  255. lionagi-0.0.312.dist-info/RECORD +0 -111
  256. /lionagi/core/{branch/base → _setting}/__init__.py +0 -0
  257. /lionagi/core/{flow → agent/eval}/__init__.py +0 -0
  258. /lionagi/core/{flow/base → agent/learn}/__init__.py +0 -0
  259. /lionagi/core/{prompt → agent/plan}/__init__.py +0 -0
  260. /lionagi/core/{tool/manual.py → agent/plan/plan.py} +0 -0
  261. /lionagi/{tests/test_integrations → core/director}/__init__.py +0 -0
  262. /lionagi/{tests/test_libs → core/engine}/__init__.py +0 -0
  263. /lionagi/{tests/test_libs/test_async.py → core/executor/__init__.py} +0 -0
  264. /lionagi/tests/{test_libs → libs}/test_api.py +0 -0
  265. /lionagi/tests/{test_libs → libs}/test_convert.py +0 -0
  266. /lionagi/tests/{test_libs → libs}/test_sys_util.py +0 -0
  267. {lionagi-0.0.312.dist-info → lionagi-0.2.1.dist-info}/WHEEL +0 -0
  268. {lionagi-0.0.312.dist-info → lionagi-0.2.1.dist-info}/top_level.txt +0 -0
@@ -1,8 +1,10 @@
1
1
  # Default configs for the OpenAI API
2
2
 
3
+ API_key_schema = ("OPENAI_API_KEY",)
4
+
3
5
  # ChatCompletion
4
6
  oai_chat_llmconfig = {
5
- "model": "gpt-4-turbo-preview",
7
+ "model": "gpt-4o",
6
8
  "frequency_penalty": 0,
7
9
  "max_tokens": None,
8
10
  "n": 1,
@@ -11,11 +13,13 @@ oai_chat_llmconfig = {
11
13
  "seed": None,
12
14
  "stop": None,
13
15
  "stream": False,
14
- "temperature": 0.7,
16
+ "temperature": 0.1,
15
17
  "top_p": 1,
16
18
  "tools": None,
17
19
  "tool_choice": "none",
18
20
  "user": None,
21
+ "logprobs": False,
22
+ "top_logprobs": None,
19
23
  }
20
24
 
21
25
  oai_chat_schema = {
@@ -36,9 +40,16 @@ oai_chat_schema = {
36
40
  "tool_choice",
37
41
  "user",
38
42
  "max_tokens",
43
+ "logprobs",
44
+ "top_logprobs",
39
45
  ],
40
46
  "input_": "messages",
41
47
  "config": oai_chat_llmconfig,
48
+ "token_encoding_name": "cl100k_base",
49
+ "token_limit": 128_000,
50
+ "interval_tokens": 1_000_000,
51
+ "interval_requests": 1_000,
52
+ "interval": 60,
42
53
  }
43
54
 
44
55
  # Finetune
@@ -79,7 +90,7 @@ oai_audio_speech_schema = {
79
90
  oai_audio_transcriptions_llmconfig = {
80
91
  "model": "whisper-1",
81
92
  "language": None,
82
- "prompt": None,
93
+ "format_prompt": None,
83
94
  "response_format": "json",
84
95
  "temperature": 0,
85
96
  }
@@ -88,7 +99,7 @@ oai_audio_transcriptions_schema = {
88
99
  "optional": [
89
100
  "response_format",
90
101
  "language",
91
- "prompt",
102
+ "format_prompt",
92
103
  "response_format",
93
104
  "temperature",
94
105
  ],
@@ -99,20 +110,38 @@ oai_audio_transcriptions_schema = {
99
110
  # Audio ------------ translations
100
111
  oai_audio_translations_llmconfig = {
101
112
  "model": "whisper-1",
102
- "prompt": None,
113
+ "format_prompt": None,
103
114
  "response_format": "json",
104
115
  "temperature": 0,
105
116
  }
106
117
 
107
118
  oai_audio_translations_schema = {
108
119
  "required": ["model"],
109
- "optional": ["response_format", "speed", "prompt", "temperature"],
120
+ "optional": ["response_format", "speed", "format_prompt", "temperature"],
110
121
  "input_": "file",
111
122
  "config": oai_audio_translations_llmconfig,
112
123
  }
113
124
 
114
- # images
125
+ # embeddings
115
126
 
127
+ oai_embeddings_llmconfig = {
128
+ "model": "text-embedding-ada-002",
129
+ "encoding_format": "float",
130
+ "user": None,
131
+ "dimensions": None,
132
+ }
133
+
134
+ oai_embeddings_schema = {
135
+ "required": ["model", "encoding_format"],
136
+ "optional": ["user", "dimensions"],
137
+ "input_": "input",
138
+ "config": oai_embeddings_llmconfig,
139
+ "token_encoding_name": "cl100k_base",
140
+ "token_limit": 8192,
141
+ "interval_tokens": 1_000_000,
142
+ "interval_requests": 1_000,
143
+ "interval": 60,
144
+ }
116
145
 
117
146
  oai_schema = {
118
147
  "chat/completions": oai_chat_schema,
@@ -120,4 +149,6 @@ oai_schema = {
120
149
  "audio_speech": oai_audio_speech_schema,
121
150
  "audio_transcriptions": oai_audio_transcriptions_schema,
122
151
  "audio_translations": oai_audio_translations_schema,
152
+ "API_key_schema": API_key_schema,
153
+ "embeddings": oai_embeddings_schema,
123
154
  }
@@ -1 +1 @@
1
- model = "llama2"
1
+ model = "llama3"
@@ -1,5 +1,7 @@
1
+ API_key_schema = ("OPENROUTER_API_KEY",)
2
+
1
3
  openrouter_chat_llmconfig = {
2
- "model": "gpt-4-turbo-preview",
4
+ "model": "gpt-4o",
3
5
  "frequency_penalty": 0,
4
6
  "max_tokens": None,
5
7
  "num": 1,
@@ -8,11 +10,13 @@ openrouter_chat_llmconfig = {
8
10
  "seed": None,
9
11
  "stop": None,
10
12
  "stream": False,
11
- "temperature": 0.7,
13
+ "temperature": 0.1,
12
14
  "top_p": 1,
13
15
  "tools": None,
14
16
  "tool_choice": "none",
15
17
  "user": None,
18
+ "logprobs": False,
19
+ "top_logprobs": None,
16
20
  }
17
21
 
18
22
  openrouter_chat_schema = {
@@ -33,9 +37,16 @@ openrouter_chat_schema = {
33
37
  "tool_choice",
34
38
  "user",
35
39
  "max_tokens",
40
+ "logprobs",
41
+ "top_logprobs",
36
42
  ],
37
43
  "input_": "messages",
38
44
  "config": openrouter_chat_llmconfig,
45
+ "token_encoding_name": "cl100k_base",
46
+ "token_limit": 128_000,
47
+ "interval_tokens": 10_000,
48
+ "interval_requests": 100,
49
+ "interval": 60,
39
50
  }
40
51
 
41
52
  openrouter_finetune_llmconfig = {
@@ -59,4 +70,5 @@ openrouter_finetune_schema = {
59
70
  openrouter_schema = {
60
71
  "chat/completions": openrouter_chat_schema,
61
72
  "finetune": openrouter_finetune_schema,
73
+ "API_key_schema": API_key_schema,
62
74
  }
File without changes
@@ -0,0 +1,253 @@
1
+ from typing import Callable
2
+
3
+ from lionagi.core.generic import Node
4
+ from lionagi.core.collections import pile
5
+ from ..bridge.langchain_.langchain_bridge import LangchainBridge
6
+ from ..bridge.llamaindex_.llama_index_bridge import LlamaIndexBridge
7
+
8
+ from .load_util import dir_to_nodes, ReaderType, _datanode_parser
9
+
10
+
11
+ def text_reader(args, kwargs):
12
+ """
13
+ Reads text files from a directory and converts them to Node instances.
14
+
15
+ Args:
16
+ args: Positional arguments for the dir_to_nodes function.
17
+ kwargs: Keyword arguments for the dir_to_nodes function.
18
+
19
+ Returns:
20
+ A list of Node instances.
21
+
22
+ Example usage:
23
+ >>> args = ['path/to/text/files']
24
+ >>> kwargs = {'file_extension': 'txt'}
25
+ >>> nodes = text_reader(args, kwargs)
26
+ """
27
+ return dir_to_nodes(*args, **kwargs)
28
+
29
+
30
+ def load(
31
+ reader: str | Callable = "text_reader",
32
+ input_dir=None,
33
+ input_files=None,
34
+ recursive: bool = False,
35
+ required_exts: list[str] = None,
36
+ reader_type=ReaderType.PLAIN,
37
+ reader_args=None,
38
+ reader_kwargs=None,
39
+ load_args=None,
40
+ load_kwargs=None,
41
+ to_lion: bool | Callable = True,
42
+ ):
43
+ """
44
+ Loads data using the specified reader and converts it to Node instances.
45
+
46
+ Args:
47
+ reader (str | Callable): The reader function or its name. Defaults to "text_reader".
48
+ input_dir (str, optional): The directory to read files from. Defaults to None.
49
+ input_files (list[str], optional): Specific files to read. Defaults to None.
50
+ recursive (bool, optional): Whether to read files recursively. Defaults to False.
51
+ required_exts (list[str], optional): List of required file extensions. Defaults to None.
52
+ reader_type (ReaderType, optional): The type of reader to use. Defaults to ReaderType.PLAIN.
53
+ reader_args (list, optional): Positional arguments for the reader function. Defaults to None.
54
+ reader_kwargs (dict, optional): Keyword arguments for the reader function. Defaults to None.
55
+ load_args (list, optional): Positional arguments for loading. Defaults to None.
56
+ load_kwargs (dict, optional): Keyword arguments for loading. Defaults to None.
57
+ to_lion (bool | Callable, optional): Whether to convert the data to Node instances or a custom parser. Defaults to True.
58
+
59
+ Returns:
60
+ pile: A pile of Node instances.
61
+
62
+ Raises:
63
+ ValueError: If the reader_type is not supported.
64
+
65
+ Example usage:
66
+ >>> nodes = load(input_dir='path/to/text/files', required_exts=['txt'])
67
+ """
68
+
69
+ if reader_args is None:
70
+ reader_args = []
71
+ if reader_kwargs is None:
72
+ reader_kwargs = {}
73
+ if load_args is None:
74
+ load_args = []
75
+ if load_kwargs is None:
76
+ load_kwargs = {}
77
+
78
+ if reader_type == ReaderType.PLAIN:
79
+ reader_kwargs["dir_"] = input_dir
80
+ reader_kwargs["ext"] = required_exts
81
+ reader_kwargs["recursive"] = recursive
82
+
83
+ return read_funcs[ReaderType.PLAIN](reader, reader_args, reader_kwargs)
84
+
85
+ if reader_type == ReaderType.LANGCHAIN:
86
+ return read_funcs[ReaderType.LANGCHAIN](
87
+ reader, reader_args, reader_kwargs, to_lion
88
+ )
89
+
90
+ elif reader_type == ReaderType.LLAMAINDEX:
91
+ if input_dir is not None:
92
+ reader_kwargs["input_dir"] = input_dir
93
+ if input_files is not None:
94
+ reader_kwargs["input_files"] = input_files
95
+ if recursive:
96
+ reader_kwargs["recursive"] = True
97
+ if required_exts is not None:
98
+ reader_kwargs["required_exts"] = required_exts
99
+
100
+ return read_funcs[ReaderType.LLAMAINDEX](
101
+ reader, reader_args, reader_kwargs, load_args, load_kwargs, to_lion
102
+ )
103
+
104
+ elif reader_type == ReaderType.SELFDEFINED:
105
+ return read_funcs[ReaderType.SELFDEFINED](
106
+ reader, reader_args, reader_kwargs, load_args, load_kwargs, to_lion
107
+ )
108
+
109
+ else:
110
+ raise ValueError(
111
+ f"{reader_type} is not supported. Please choose from {list(ReaderType)}"
112
+ )
113
+
114
+
115
+ def _plain_reader(reader, reader_args, reader_kwargs):
116
+ """
117
+ Reads data using a plain reader.
118
+
119
+ Args:
120
+ reader (str | Callable): The reader function or its name.
121
+ reader_args (list): Positional arguments for the reader function.
122
+ reader_kwargs (dict): Keyword arguments for the reader function.
123
+
124
+ Returns:
125
+ pile: A pile of Node instances.
126
+
127
+ Raises:
128
+ ValueError: If the reader is not supported.
129
+
130
+ Example usage:
131
+ >>> nodes = _plain_reader('text_reader', ['path/to/files'], {'ext': 'txt'})
132
+ """
133
+ try:
134
+ if reader == "text_reader":
135
+ reader = text_reader
136
+ nodes = reader(reader_args, reader_kwargs)
137
+ return pile(nodes)
138
+ except Exception as e:
139
+ raise ValueError(
140
+ f"Reader {reader} is currently not supported. Error: {e}"
141
+ ) from e
142
+
143
+
144
+ def _langchain_reader(reader, reader_args, reader_kwargs, to_lion: bool | Callable):
145
+ """
146
+ Reads data using a Langchain reader.
147
+
148
+ Args:
149
+ reader (str | Callable): The reader function or its name.
150
+ reader_args (list): Positional arguments for the reader function.
151
+ reader_kwargs (dict): Keyword arguments for the reader function.
152
+ to_lion (bool | Callable): Whether to convert the data to Node instances or a custom parser.
153
+
154
+ Returns:
155
+ pile: A pile of Node instances or custom parsed nodes.
156
+
157
+ Example usage:
158
+ >>> nodes = _langchain_reader('langchain_reader', ['arg1'], {'key': 'value'}, True)
159
+ """
160
+ nodes = LangchainBridge.langchain_loader(reader, reader_args, reader_kwargs)
161
+ if isinstance(to_lion, bool) and to_lion is True:
162
+ return pile([Node.from_langchain(i) for i in nodes])
163
+
164
+ elif isinstance(to_lion, Callable):
165
+ nodes = _datanode_parser(nodes, to_lion)
166
+ return nodes
167
+
168
+
169
+ def _llama_index_reader(
170
+ reader,
171
+ reader_args,
172
+ reader_kwargs,
173
+ load_args,
174
+ load_kwargs,
175
+ to_lion: bool | Callable,
176
+ ):
177
+ """
178
+ Reads data using a LlamaIndex reader.
179
+
180
+ Args:
181
+ reader (str | Callable): The reader function or its name.
182
+ reader_args (list): Positional arguments for the reader function.
183
+ reader_kwargs (dict): Keyword arguments for the reader function.
184
+ load_args (list): Positional arguments for loading.
185
+ load_kwargs (dict): Keyword arguments for loading.
186
+ to_lion (bool | Callable): Whether to convert the data to Node instances or a custom parser.
187
+
188
+ Returns:
189
+ pile: A pile of Node instances or custom parsed nodes.
190
+
191
+ Example usage:
192
+ >>> nodes = _llama_index_reader('llama_reader', ['arg1'], {'key': 'value'}, [], {}, True)
193
+ """
194
+ nodes = LlamaIndexBridge.llama_index_read_data(
195
+ reader, reader_args, reader_kwargs, load_args, load_kwargs
196
+ )
197
+ if isinstance(to_lion, bool) and to_lion is True:
198
+ return pile([Node.from_llama_index(i) for i in nodes])
199
+
200
+ elif isinstance(to_lion, Callable):
201
+ nodes = _datanode_parser(nodes, to_lion)
202
+ return nodes
203
+
204
+
205
+ def _self_defined_reader(
206
+ reader,
207
+ reader_args,
208
+ reader_kwargs,
209
+ load_args,
210
+ load_kwargs,
211
+ to_lion: bool | Callable,
212
+ ):
213
+ """
214
+ Reads data using a self-defined reader.
215
+
216
+ Args:
217
+ reader (str | Callable): The reader function or its name.
218
+ reader_args (list): Positional arguments for the reader function.
219
+ reader_kwargs (dict): Keyword arguments for the reader function.
220
+ load_args (list): Positional arguments for loading.
221
+ load_kwargs (dict): Keyword arguments for loading.
222
+ to_lion (bool | Callable): Whether to convert the data to Node instances or a custom parser.
223
+
224
+ Returns:
225
+ pile: A pile of Node instances or custom parsed nodes.
226
+
227
+ Raises:
228
+ ValueError: If the self-defined reader is not valid.
229
+
230
+ Example usage:
231
+ >>> nodes = _self_defined_reader(custom_reader, ['arg1'], {'key': 'value'}, [], {}, custom_parser)
232
+ """
233
+ try:
234
+ loader = reader(*reader_args, **reader_kwargs)
235
+ nodes = loader.load(*load_args, **load_kwargs)
236
+ except Exception as e:
237
+ raise ValueError(
238
+ f"Self defined reader {reader} is not valid. Error: {e}"
239
+ ) from e
240
+
241
+ if isinstance(to_lion, bool) and to_lion is True:
242
+ raise ValueError("Please define a valid parser to Node.")
243
+ elif isinstance(to_lion, Callable):
244
+ nodes = _datanode_parser(nodes, to_lion)
245
+ return nodes
246
+
247
+
248
+ read_funcs = {
249
+ ReaderType.PLAIN: _plain_reader,
250
+ ReaderType.LANGCHAIN: _langchain_reader,
251
+ ReaderType.LLAMAINDEX: _llama_index_reader,
252
+ ReaderType.SELFDEFINED: _self_defined_reader,
253
+ }
@@ -0,0 +1,195 @@
1
+ # use utils and schema
2
+ from enum import Enum
3
+ from pathlib import Path
4
+ from typing import List, Union, Dict, Any, Tuple
5
+
6
+ from lionagi.libs import convert, func_call
7
+ from lionagi.libs.ln_tokenize import TokenizeUtil
8
+ from lionagi.core.generic import Node
9
+
10
+
11
+ class ReaderType(str, Enum):
12
+ PLAIN = "plain"
13
+ LANGCHAIN = "langchain"
14
+ LLAMAINDEX = "llama_index"
15
+ SELFDEFINED = "self_defined"
16
+
17
+
18
+ class ChunkerType(str, Enum):
19
+ PLAIN = "plain" # default
20
+ LANGCHAIN = "langchain" # using langchain functions
21
+ LLAMAINDEX = "llama_index" # using llamaindex functions
22
+ SELFDEFINED = "self_defined" # create custom functions
23
+
24
+
25
+ def dir_to_path(
26
+ dir: str, ext: str, recursive: bool = False, flatten: bool = True
27
+ ) -> List[Path]:
28
+ """
29
+ Generates a list of file paths from a directory with the given file extension.
30
+
31
+ Parameters:
32
+ dir (str): The directory to search for files.
33
+
34
+ ext (str): The file extension to filter by.
35
+
36
+ recursive (bool): Whether to search subdirectories recursively. Defaults to False.
37
+
38
+ flatten (bool): Whether to flatten the list. Defaults to True.
39
+
40
+ Returns:
41
+ List[Path]: A list of Paths to the files.
42
+
43
+ Raises:
44
+ ValueError: If the directory or extension is invalid.
45
+ """
46
+
47
+ def _dir_to_path(ext):
48
+ tem = "**/*" if recursive else "*"
49
+ return list(Path(dir).glob(tem + ext))
50
+
51
+ try:
52
+ return convert.to_list(
53
+ func_call.lcall(ext, _dir_to_path, flatten=True), flatten=flatten
54
+ )
55
+ except:
56
+ raise ValueError("Invalid directory or extension, please check the path")
57
+
58
+
59
+ def dir_to_nodes(
60
+ dir_: str,
61
+ ext: Union[List[str], str],
62
+ recursive: bool = False,
63
+ flatten: bool = True,
64
+ clean_text: bool = True,
65
+ ) -> List[Node]:
66
+ """
67
+ Converts directory contents into Node objects based on specified file extensions.
68
+
69
+ This function first retrieves a list of file paths from the specified directory, matching the given file extension. It then reads the content of these files, optionally cleaning the text, and converts each file's content into a Node object.
70
+
71
+ Parameters:
72
+ dir (str): The directory path from which to read files.
73
+ ext: The file extension(s) to include. Can be a single string or a list/tuple of strings.
74
+ recursive (bool, optional): If True, the function searches for files recursively in subdirectories. Defaults to False.
75
+ flatten (bool, optional): If True, flattens the directory structure in the returned paths. Defaults to True.
76
+ clean_text (bool, optional): If True, cleans the text read from files. Defaults to True.
77
+
78
+ Returns:
79
+ list: A list of Node objects created from the files in the specified directory.
80
+
81
+ Example:
82
+ nodes = dir_to_nodes("/path/to/dir", ".txt", recursive=True)
83
+ # This would read all .txt files in /path/to/dir and its subdirectories,
84
+ # converting them into Node objects.
85
+ """
86
+
87
+ path_list = dir_to_path(dir=dir_, ext=ext, recursive=recursive, flatten=flatten)
88
+ files_info = func_call.lcall(path_list, read_text, clean=clean_text)
89
+ return func_call.lcall(files_info, lambda x: Node(content=x[0], metadata=x[1]))
90
+
91
+
92
+ def read_text(filepath: str, clean: bool = True) -> Tuple[str, dict]:
93
+ """
94
+ Reads text from a file and optionally cleans it, returning the content and metadata.
95
+
96
+ Parameters:
97
+ filepath (str): The path to the file to read.
98
+
99
+ clean (bool): Whether to clean the text by replacing certain characters. Defaults to True.
100
+
101
+ Returns:
102
+ Tuple[str, dict]: A tuple containing the content and metadata of the file.
103
+
104
+ Raises:
105
+ FileNotFoundError: If the file cannot be found.
106
+
107
+ PermissionError: If there are permissions issues.
108
+
109
+ OSError: For other OS-related errors.
110
+ """
111
+
112
+ def _get_metadata():
113
+ import os
114
+ from datetime import datetime
115
+
116
+ file = filepath
117
+ size = os.path.getsize(filepath)
118
+ creation_date = datetime.fromtimestamp(os.path.getctime(filepath)).date()
119
+ modified_date = datetime.fromtimestamp(os.path.getmtime(filepath)).date()
120
+ last_accessed_date = datetime.fromtimestamp(os.path.getatime(filepath)).date()
121
+ return {
122
+ "file": convert.to_str(file),
123
+ "size": size,
124
+ "creation_date": str(creation_date),
125
+ "modified_date": str(modified_date),
126
+ "last_accessed_date": str(last_accessed_date),
127
+ }
128
+
129
+ try:
130
+ with open(filepath, "r") as f:
131
+ content = f.read()
132
+ if clean:
133
+ # Define characters to replace and their replacements
134
+ replacements = {"\\": "", "\n\n": "\n"}
135
+ for old, new in replacements.items():
136
+ content = content.replace(old, new).strip()
137
+ metadata = _get_metadata()
138
+ return content, metadata
139
+ except Exception as e:
140
+ raise e
141
+
142
+
143
+ def _file_to_chunks(
144
+ input: Dict[str, Any],
145
+ field: str = "content",
146
+ chunk_size: int = 1500,
147
+ overlap: float = 0.1,
148
+ threshold: int = 200,
149
+ ) -> List[Dict[str, Any]]:
150
+ try:
151
+ out = {key: value for key, value in input.items() if key != field} | {
152
+ "chunk_overlap": overlap,
153
+ "chunk_threshold": threshold,
154
+ }
155
+ chunks = TokenizeUtil.chunk_by_chars(
156
+ input[field], chunk_size=chunk_size, overlap=overlap, threshold=threshold
157
+ )
158
+ logs = []
159
+ for i, chunk in enumerate(chunks):
160
+ chunk_dict = out | {
161
+ "file_chunks": len(chunks),
162
+ "chunk_id": i + 1,
163
+ "chunk_size": len(chunk),
164
+ f"chunk_{field}": chunk,
165
+ }
166
+ logs.append(chunk_dict)
167
+
168
+ return logs
169
+
170
+ except Exception as e:
171
+ raise ValueError(f"An error occurred while chunking the file. {e}") from e
172
+
173
+
174
+ # needs doing TODO
175
+ def file_to_chunks(
176
+ input,
177
+ # project='project',
178
+ # output_dir='data/logs/sources/',
179
+ chunk_func=_file_to_chunks,
180
+ **kwargs,
181
+ ):
182
+ # out_to_csv=False,
183
+ # filename=None,
184
+ # verbose=True,
185
+ # timestamp=True,
186
+ # logger=None,
187
+ return convert.to_list(func_call.lcall(input, chunk_func, **kwargs), flatten=True)
188
+
189
+
190
+ def _datanode_parser(nodes, parser):
191
+
192
+ try:
193
+ return parser(nodes)
194
+ except Exception as e:
195
+ raise ValueError(f"Node parser {parser} failed. Error:{e}") from e
@@ -0,0 +1,46 @@
1
+ from .oai import OpenAIService
2
+ from .openrouter import OpenRouterService
3
+ from .ollama import OllamaService
4
+ from .transformers import TransformersService
5
+ from .litellm import LiteLLMService
6
+ from .mlx_service import MLXService
7
+ from lionagi.integrations.config.oai_configs import oai_schema
8
+ from lionagi.integrations.config.openrouter_configs import openrouter_schema
9
+
10
+ SERVICE_PROVIDERS_MAPPING = {
11
+ "openai": {
12
+ "service": OpenAIService,
13
+ "schema": oai_schema,
14
+ "default_model": "gpt-3.5-turbo",
15
+ },
16
+ "openrouter": {
17
+ "service": OpenRouterService,
18
+ "schema": openrouter_schema,
19
+ "default_model": "gpt-3.5-turbo",
20
+ },
21
+ "litellm": {
22
+ "service": LiteLLMService,
23
+ "schema": oai_schema,
24
+ "default_model": "gpt-3.5-turbo",
25
+ },
26
+ "ollama": {
27
+ "service": OllamaService,
28
+ "schema": {"model": "llama3"},
29
+ "default_model": "llama3",
30
+ },
31
+ "transformers": {
32
+ "service": TransformersService,
33
+ "schema": {"model": "gpt2"},
34
+ "default_model": "gpt2",
35
+ },
36
+ "mlx": {
37
+ "service": MLXService,
38
+ "schema": {"model": "mlx-community/OLMo-7B-hf-4bit-mlx"},
39
+ "default_model": "mlx-community/OLMo-7B-hf-4bit-mlx",
40
+ },
41
+ }
42
+
43
+ # TODO
44
+ # "Ollama": OllamaService,
45
+ # "Transformers": TransformersService,
46
+ # "MLX": MLXService,
@@ -31,12 +31,13 @@ class LiteLLMService(BaseService):
31
31
  self.acompletion = acompletion
32
32
  self.model = model
33
33
  self.kwargs = kwargs
34
+ self.allowed_kwargs = allowed_kwargs
34
35
 
35
36
  async def serve_chat(self, messages, **kwargs):
36
37
  payload = {"messages": messages}
37
38
  config = {}
38
39
  for k, v in kwargs.items():
39
- if k in allowed_kwargs:
40
+ if k in self.allowed_kwargs:
40
41
  config[k] = v
41
42
 
42
43
  kwargs = {**self.kwargs, **config}