lionagi 0.0.312__py3-none-any.whl → 0.2.1__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 (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
@@ -0,0 +1,172 @@
1
+ # disallowed special tokens
2
+
3
+ disallowed_tokens = [
4
+ "▄",
5
+ "▅",
6
+ "▆",
7
+ "▇",
8
+ "█",
9
+ "▏",
10
+ "▎",
11
+ "▍",
12
+ "▌",
13
+ "▋",
14
+ "▊",
15
+ "▉",
16
+ "▔",
17
+ "▕",
18
+ "▁▁",
19
+ "▁▂",
20
+ "▁▃",
21
+ "▁▄",
22
+ "▁▅",
23
+ "▁▆",
24
+ "▁▇",
25
+ "▁█",
26
+ "▁▏",
27
+ "▁▎",
28
+ "▁▍",
29
+ "▁▌",
30
+ "▁▋",
31
+ "▁▊",
32
+ "▁▉",
33
+ "▁▔",
34
+ "▁▕",
35
+ "▄▄",
36
+ "▄▅",
37
+ "▄▆",
38
+ "▄▇",
39
+ "▄█",
40
+ "▄▏",
41
+ "▄▎",
42
+ "▄▍",
43
+ "▄▌",
44
+ "▄▋",
45
+ "▄▊",
46
+ "▄▉",
47
+ "▄▔",
48
+ "▄▕",
49
+ "▅▅",
50
+ "▅▆",
51
+ "▅▇",
52
+ "▅█",
53
+ "▅▏",
54
+ "▅▎",
55
+ "▅▍",
56
+ "▅▌",
57
+ "▅▋",
58
+ "▅▊",
59
+ "▅▉",
60
+ "▅▔",
61
+ "▅▕",
62
+ "▆▆",
63
+ "▆▇",
64
+ "▆█",
65
+ "▆▏",
66
+ "▆▎",
67
+ "▆▍",
68
+ "▆▌",
69
+ "▆▋",
70
+ "▆▊",
71
+ "▆▉",
72
+ "▆▔",
73
+ "▆▕",
74
+ "▇▇",
75
+ "▇█",
76
+ "▇▏",
77
+ "▇▎",
78
+ "▇▍",
79
+ "▇▌",
80
+ "▇▋",
81
+ "▇▊",
82
+ "▇▉",
83
+ "▇▔",
84
+ "▇▕",
85
+ "██",
86
+ "█▏",
87
+ "█▎",
88
+ "█▍",
89
+ "█▌",
90
+ "█▋",
91
+ "█▊",
92
+ "█▉",
93
+ "█",
94
+ "█▔",
95
+ "█▕",
96
+ "▏▏",
97
+ "▏▎",
98
+ "▏▍",
99
+ "▏▌",
100
+ "▏▋",
101
+ "▏▊",
102
+ "▏▉",
103
+ "▏",
104
+ "▏▔",
105
+ "▏▕",
106
+ "▎▎",
107
+ "▎▍",
108
+ "▎▌",
109
+ "▎▋",
110
+ "▎▊",
111
+ "▎▉",
112
+ "▎",
113
+ "▎▔",
114
+ "▎▕",
115
+ "▍▍",
116
+ "▍▌",
117
+ "▍▋",
118
+ "▍▊",
119
+ "▍▉",
120
+ "▍",
121
+ "▍▔",
122
+ "▍▕",
123
+ "▌▌",
124
+ "▌▋",
125
+ "▌▊",
126
+ "▌▉",
127
+ "▌",
128
+ "▌▔",
129
+ "▌▕",
130
+ "▋▋",
131
+ "▋▊",
132
+ "▋▉",
133
+ "▋",
134
+ "▋▔",
135
+ "▋▕",
136
+ "▊▊",
137
+ "▊▉",
138
+ "▊",
139
+ "▊▔",
140
+ "▊▕",
141
+ "▉▉",
142
+ "▉",
143
+ "▉▔",
144
+ "▉▕",
145
+ "▔▔",
146
+ "▔▕",
147
+ "▕▕",
148
+ "▁▁▁",
149
+ "▁▁▂",
150
+ "▁▁▃",
151
+ "▁▁▄",
152
+ "▁▁▅",
153
+ "▁▁▆",
154
+ "▁▁▇",
155
+ "▁▁█",
156
+ "▁▁▏",
157
+ "▁▁▎",
158
+ "▁▁▍",
159
+ "▁▁▌",
160
+ "▁▁▋",
161
+ "▁▁▊",
162
+ "▁▁▉",
163
+ "▁▁▔",
164
+ "▁▁▕",
165
+ "▁▂▂",
166
+ "▁▂▃",
167
+ "▁▂▄",
168
+ "▁▂▅",
169
+ "▁▂▆",
170
+ "▁▂▇",
171
+ "▁▂█",
172
+ ]
lionagi/libs/sys_util.py CHANGED
@@ -1,3 +1,19 @@
1
+ """
2
+ Copyright 2024 HaiyangLi
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ """
16
+
1
17
  import copy
2
18
  import importlib
3
19
  import logging
@@ -245,7 +261,7 @@ class SysUtil:
245
261
  """
246
262
  try:
247
263
  if not SysUtil.is_package_installed(package_name):
248
- print("check")
264
+ # print("check")
249
265
  if attempt_install:
250
266
  logging.info(
251
267
  f"Package {package_name} not found. Attempting to install."
@@ -351,6 +367,7 @@ class SysUtil:
351
367
  dir_exist_ok: bool = True,
352
368
  time_prefix: bool = False,
353
369
  custom_timestamp_format: str | None = None,
370
+ random_hash_digits=0,
354
371
  ) -> Path:
355
372
  """
356
373
  Creates a path with an optional timestamp in the specified directory.
@@ -388,7 +405,13 @@ class SysUtil:
388
405
  else:
389
406
  filename = name
390
407
 
391
- full_filename = f"{filename}{ext}"
408
+ random_hash = (
409
+ "-" + SysUtil.create_id(random_hash_digits)
410
+ if random_hash_digits > 0
411
+ else ""
412
+ )
413
+
414
+ full_filename = f"{filename}{random_hash}{ext}"
392
415
  full_path = directory / full_filename
393
416
  full_path.parent.mkdir(parents=True, exist_ok=dir_exist_ok)
394
417
 
@@ -396,6 +419,19 @@ class SysUtil:
396
419
 
397
420
  @staticmethod
398
421
  def list_files(dir_path: Path | str, extension: str = None) -> list[Path]:
422
+ """
423
+ Lists all files in a specified directory with an optional filter for file extensions.
424
+
425
+ Args:
426
+ dir_path (Path | str): The directory path where files are listed.
427
+ extension (str, optional): Filter files by extension. Default is None, which lists all files.
428
+
429
+ Returns:
430
+ list[Path]: A list of Path objects representing files in the directory.
431
+
432
+ Raises:
433
+ NotADirectoryError: If the provided dir_path is not a directory.
434
+ """
399
435
  dir_path = Path(dir_path)
400
436
  if not dir_path.is_dir():
401
437
  raise NotADirectoryError(f"{dir_path} is not a directory.")
@@ -406,6 +442,16 @@ class SysUtil:
406
442
 
407
443
  @staticmethod
408
444
  def copy_file(src: Path | str, dest: Path | str) -> None:
445
+ """
446
+ Copies a file from a source path to a destination path.
447
+
448
+ Args:
449
+ src (Path | str): The source file path.
450
+ dest (Path | str): The destination file path.
451
+
452
+ Raises:
453
+ FileNotFoundError: If the source file does not exist or is not a file.
454
+ """
409
455
  from shutil import copy2
410
456
 
411
457
  src, dest = Path(src), Path(dest)
@@ -416,6 +462,18 @@ class SysUtil:
416
462
 
417
463
  @staticmethod
418
464
  def get_size(path: Path | str) -> int:
465
+ """
466
+ Gets the size of a file or total size of files in a directory.
467
+
468
+ Args:
469
+ path (Path | str): The file or directory path.
470
+
471
+ Returns:
472
+ int: The size in bytes.
473
+
474
+ Raises:
475
+ FileNotFoundError: If the path does not exist.
476
+ """
419
477
  path = Path(path)
420
478
  if path.is_file():
421
479
  return path.stat().st_size
@@ -423,3 +481,50 @@ class SysUtil:
423
481
  return sum(f.stat().st_size for f in path.glob("**/*") if f.is_file())
424
482
  else:
425
483
  raise FileNotFoundError(f"{path} does not exist.")
484
+
485
+ @staticmethod
486
+ def save_to_file(
487
+ text,
488
+ directory: Path | str,
489
+ filename: str,
490
+ timestamp: bool = True,
491
+ dir_exist_ok: bool = True,
492
+ time_prefix: bool = False,
493
+ custom_timestamp_format: str | None = None,
494
+ random_hash_digits=0,
495
+ verbose=True,
496
+ ):
497
+ """
498
+ Saves text to a file within a specified directory, optionally adding a timestamp, hash, and verbose logging.
499
+
500
+ Args:
501
+ text (str): The text to save.
502
+ directory (Path | str): The directory path to save the file.
503
+ filename (str): The filename for the saved text.
504
+ timestamp (bool): If True, append a timestamp to the filename. Default is True.
505
+ dir_exist_ok (bool): If True, creates the directory if it does not exist. Default is True.
506
+ time_prefix (bool): If True, prepend the timestamp instead of appending. Default is False.
507
+ custom_timestamp_format (str | None): A custom format for the timestamp, if None uses default format. Default is None.
508
+ random_hash_digits (int): Number of random hash digits to append to filename. Default is 0.
509
+ verbose (bool): If True, prints the file path after saving. Default is True.
510
+
511
+ Returns:
512
+ bool: True if the text was successfully saved.
513
+ """
514
+ file_path = SysUtil.create_path(
515
+ directory=directory,
516
+ filename=filename,
517
+ timestamp=timestamp,
518
+ dir_exist_ok=dir_exist_ok,
519
+ time_prefix=time_prefix,
520
+ custom_timestamp_format=custom_timestamp_format,
521
+ random_hash_digits=random_hash_digits,
522
+ )
523
+
524
+ with open(file_path, "w") as file:
525
+ file.write(text)
526
+
527
+ if verbose:
528
+ print(f"Text saved to: {file_path}")
529
+
530
+ return True
File without changes
File without changes
@@ -0,0 +1,20 @@
1
+ # task1 = task1 or """
2
+ # 1. read through the given functions, and try to understand what they do.
3
+ # 2. if any function appear undefined in the environment, define them according to given information
4
+ # 3. add a few test cases and check correctness
5
+ # """
6
+
7
+ # context = "codes to evaluate: "+ context
8
+
9
+ # task2 = task2 or f"""
10
+ # 1. validate correctness, and add 5-10 new functions using pure python
11
+ # 2. improve time/space complexity while preserving usage behavior
12
+ # 3. run to make sure correctness
13
+ # """
14
+
15
+ # task3 = task3 or f"""
16
+ # present the full implementation and save as: {filename}.txt
17
+ # 1. add typing and google format docstrings
18
+ # 2. add a couple examples in the docstrings
19
+ # 3. add unittests
20
+ # """
@@ -0,0 +1,22 @@
1
+ GUIDANCE_RESPONSE = """
2
+ ...
3
+ """
4
+
5
+ PLAN_PROMPT = "..."
6
+ WRITE_PROMPT = "..."
7
+ REVIEW_PROMPT = "..."
8
+ MODIFY_PROMPT = """
9
+ ...
10
+ """
11
+ DEBUG_PROMPT = """
12
+ ...
13
+ """
14
+
15
+ CODER_PROMPTS = {
16
+ "system": GUIDANCE_RESPONSE,
17
+ "plan_code": PLAN_PROMPT,
18
+ "write_code": WRITE_PROMPT,
19
+ "review_code": REVIEW_PROMPT,
20
+ "modify_code": MODIFY_PROMPT,
21
+ "debug_code": DEBUG_PROMPT,
22
+ }
@@ -0,0 +1,13 @@
1
+ from typing import Any
2
+ from pydantic import Field
3
+ from lionagi.libs import ParseUtil, SysUtil
4
+ from lionagi.core import Session
5
+ from lionagi.core.form.action_form import ActionForm
6
+
7
+
8
+ class CodeForm(ActionForm):
9
+ template_name: str = "code_form"
10
+ language: str = Field(
11
+ default="python",
12
+ description="The programming language of the code to be executed.",
13
+ )
@@ -0,0 +1,168 @@
1
+ import asyncio
2
+ from pathlib import Path
3
+
4
+ from lionagi import logging as _logging
5
+ from lionagi.core import Session
6
+ from lionagi.libs import ParseUtil
7
+
8
+ from .base_prompts import CODER_PROMPTS
9
+ from .util import install_missing_dependencies, set_up_interpreter, save_code_file
10
+
11
+
12
+ class Coder:
13
+
14
+ def __init__(
15
+ self,
16
+ prompts: dict = None,
17
+ session: Session = None,
18
+ session_kwargs: dict = None,
19
+ required_libraries: list = None,
20
+ work_dir: Path | str = None,
21
+ ) -> None:
22
+
23
+ self.prompts = prompts or CODER_PROMPTS
24
+ self.session = session or self._create_session(session_kwargs)
25
+ self.required_libraries = required_libraries or ["lionagi"]
26
+ self.work_dir = work_dir or Path.cwd() / "coder" / "code_files"
27
+
28
+ def _create_session(self, session_kwargs: dict = None) -> Session:
29
+ session_kwargs = session_kwargs or {}
30
+ return Session(system=self.prompts["system"], **session_kwargs)
31
+
32
+
33
+ class Coder:
34
+ def __init__(
35
+ self,
36
+ prompts=None,
37
+ session=None,
38
+ session_kwargs=None,
39
+ required_libraries=None,
40
+ work_dir=None,
41
+ ):
42
+ print("Initializing Coder...")
43
+ self.prompts = prompts or CODER_PROMPTS
44
+ self.session = session or self._create_session(session_kwargs)
45
+ self.required_libraries = required_libraries or ["lionagi"]
46
+ self.work_dir = work_dir or Path.cwd() / "coder" / "code_files"
47
+ print("Coder initialized.")
48
+
49
+ def _create_session(self, session_kwargs=None):
50
+ print("Creating session...")
51
+ session_kwargs = session_kwargs or {}
52
+ session = Session(system=self.prompts["system"], **session_kwargs)
53
+ print("Session created.")
54
+ return session
55
+
56
+ async def _plan_code(self, context):
57
+ print("Planning code...")
58
+ plans = await self.session.chat(self.prompts["plan_code"], context=context)
59
+ print("Code planning completed.")
60
+ return plans
61
+
62
+ async def _write_code(self, context=None):
63
+ print("Writing code...")
64
+ code = await self.session.chat(self.prompts["write_code"], context=context)
65
+ print("Code writing completed.")
66
+ return ParseUtil.extract_code_blocks(code)
67
+
68
+ async def _review_code(self, context=None):
69
+ print("Reviewing code...")
70
+ code = await self.session.chat(self.prompts["review_code"], context=context)
71
+ print("Code review completed.")
72
+ return code
73
+
74
+ async def _modify_code(self, context=None):
75
+ print("Modifying code...")
76
+ code = await self.session.chat(self.prompts["modify_code"], context=context)
77
+ print("Code modification completed.")
78
+ return code
79
+
80
+ async def _debug_code(self, context=None):
81
+ print("Debugging code...")
82
+ code = await self.session.chat(self.prompts["debug_code"], context=context)
83
+ print("Code debugging completed.")
84
+ return code
85
+
86
+ def _handle_execution_error(self, execution, required_libraries=None):
87
+ print("Handling execution error...")
88
+ if execution.error and execution.error.name == "ModuleNotFoundError":
89
+ print("ModuleNotFoundError detected. Installing missing dependencies...")
90
+ install_missing_dependencies(required_libraries)
91
+ print("Dependencies installed. Retrying execution.")
92
+ return "try again"
93
+ elif execution.error:
94
+ print(f"Execution error: {execution.error}")
95
+ return execution.error
96
+
97
+ def execute_code(self, code, **kwargs):
98
+ print("Executing code...")
99
+ interpreter = set_up_interpreter()
100
+ with interpreter as sandbox:
101
+ print("Running code in sandbox...")
102
+ execution = sandbox.notebook.exec_cell(code, **kwargs)
103
+ error = self._handle_execution_error(
104
+ execution, required_libraries=kwargs.get("required_libraries")
105
+ )
106
+ if error == "try again":
107
+ print("Retrying code execution...")
108
+ execution = sandbox.notebook.exec_cell(code, **kwargs)
109
+ print("Code execution completed.")
110
+ return execution
111
+
112
+ def _save_code_file(self, code, **kwargs):
113
+ print("Saving code...")
114
+ save_code_file(code, self.work_dir, **kwargs)
115
+ print("Code saved.")
116
+
117
+ @staticmethod
118
+ def _load_code_file(file_path):
119
+ print("Loading code...")
120
+ try:
121
+ with open(file_path, "r") as file:
122
+ print("Code loaded.")
123
+ return file.read()
124
+ except FileNotFoundError:
125
+ _logging.error(f"File not found: {file_path}")
126
+ return None
127
+
128
+
129
+ async def main():
130
+ print("Starting main function...")
131
+ coder = Coder()
132
+
133
+ code_prompt = """
134
+ write a pure python function that takes a list of integers and returns the sum of all the integers in the list. write a couple tests as well
135
+ """
136
+
137
+ print(f"Code prompt: {code_prompt}")
138
+
139
+ print("Planning code...")
140
+ code_plan = await coder._plan_code(context=code_prompt)
141
+ print("Code plan generated.")
142
+
143
+ print("Writing code...")
144
+ code = await coder._write_code()
145
+ print("Code written.")
146
+
147
+ print("Executing code...")
148
+ execution_result = coder.execute_code(code)
149
+ print("Code execution completed.")
150
+
151
+ from IPython.display import Markdown
152
+
153
+ print("Displaying code plan...")
154
+ Markdown(code_plan)
155
+
156
+ print("Displaying generated code...")
157
+ print(code)
158
+
159
+ print("Displaying execution result...")
160
+ print(execution_result)
161
+
162
+ print("Main function completed.")
163
+
164
+
165
+ if __name__ == "__main__":
166
+ print("Running script...")
167
+ asyncio.run(main())
168
+ print("Script execution completed.")
@@ -0,0 +1,96 @@
1
+ from typing import Any
2
+ from pathlib import Path
3
+
4
+ E2B_key_scheme = "E2B_API_KEY"
5
+
6
+
7
+ def set_up_interpreter(interpreter_provider="e2b", key_scheme=E2B_key_scheme):
8
+
9
+ if interpreter_provider == "e2b":
10
+ from dotenv import load_dotenv
11
+
12
+ load_dotenv()
13
+
14
+ from lionagi.libs import SysUtil
15
+
16
+ SysUtil.check_import("e2b_code_interpreter")
17
+
18
+ from e2b_code_interpreter import CodeInterpreter # type: ignore
19
+ from os import getenv
20
+
21
+ return CodeInterpreter(api_key=getenv(key_scheme))
22
+
23
+ else:
24
+ raise ValueError("Invalid interpreter provider")
25
+
26
+
27
+ def install_missing_dependencies(required_libraries):
28
+ print("Checking for missing dependencies...")
29
+ missing_libraries = [
30
+ library for library in required_libraries if not is_library_installed(library)
31
+ ]
32
+
33
+ if missing_libraries:
34
+ print(f"Missing libraries: {', '.join(missing_libraries)}")
35
+ for library in missing_libraries:
36
+ print(f"Installing {library}...")
37
+ install_library(library)
38
+ print("Installation completed.")
39
+ else:
40
+ print("All required dependencies are already installed.")
41
+
42
+
43
+ def is_library_installed(library):
44
+ try:
45
+ import importlib
46
+
47
+ importlib.import_module(library)
48
+ print(f"{library} is already installed.")
49
+ return True
50
+ except ImportError:
51
+ print(f"{library} is not installed.")
52
+ return False
53
+
54
+
55
+ def install_library(library):
56
+ try:
57
+ import subprocess
58
+ import sys
59
+
60
+ subprocess.check_call([sys.executable, "-m", "pip", "install", library])
61
+ print(f"Successfully installed {library}.")
62
+ except subprocess.CalledProcessError as e:
63
+ print(f"Error occurred while installing {library}: {str(e)}")
64
+ print(
65
+ "Please check the error message and ensure you have the necessary permissions to install packages."
66
+ )
67
+ print(
68
+ "You may need to run the script with administrative privileges or use a virtual environment."
69
+ )
70
+
71
+
72
+ def save_code_file(
73
+ code: Any,
74
+ directory: Path | str = None,
75
+ filename: str = "code.py",
76
+ timestamp: bool = True,
77
+ dir_exist_ok: bool = True,
78
+ time_prefix: bool = False,
79
+ custom_timestamp_format: str | None = None,
80
+ random_hash_digits: int = 3,
81
+ verbose: bool = True,
82
+ ):
83
+
84
+ from lionagi.libs import SysUtil
85
+
86
+ return SysUtil.save_to_file(
87
+ text=code,
88
+ directory=directory,
89
+ filename=filename,
90
+ timestamp=timestamp,
91
+ dir_exist_ok=dir_exist_ok,
92
+ time_prefix=time_prefix,
93
+ custom_timestamp_format=custom_timestamp_format,
94
+ random_hash_digits=random_hash_digits,
95
+ verbose=verbose,
96
+ )
File without changes
File without changes