lionagi 0.3.8__py3-none-any.whl → 0.5.0__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
Files changed (584) hide show
  1. lionagi/__init__.py +14 -46
  2. lionagi/core/__init__.py +3 -1
  3. lionagi/core/_class_registry.py +69 -0
  4. lionagi/core/action/__init__.py +3 -13
  5. lionagi/core/action/action_manager.py +287 -0
  6. lionagi/core/action/base.py +109 -0
  7. lionagi/core/action/function_calling.py +127 -92
  8. lionagi/core/action/tool.py +172 -70
  9. lionagi/core/action/types.py +16 -0
  10. lionagi/core/communication/__init__.py +3 -0
  11. lionagi/core/communication/action_request.py +163 -0
  12. lionagi/core/communication/action_response.py +149 -0
  13. lionagi/core/communication/assistant_response.py +161 -0
  14. lionagi/core/communication/base_mail.py +49 -0
  15. lionagi/core/communication/instruction.py +376 -0
  16. lionagi/core/communication/message.py +286 -0
  17. lionagi/core/communication/message_manager.py +530 -0
  18. lionagi/core/communication/system.py +116 -0
  19. lionagi/core/communication/templates/README.md +28 -0
  20. lionagi/core/communication/templates/action_request.jinja2 +5 -0
  21. lionagi/core/communication/templates/action_response.jinja2 +9 -0
  22. lionagi/core/communication/templates/assistant_response.jinja2 +2 -0
  23. lionagi/core/communication/templates/instruction_message.jinja2 +61 -0
  24. lionagi/core/communication/templates/system_message.jinja2 +11 -0
  25. lionagi/core/communication/templates/tool_schemas.jinja2 +7 -0
  26. lionagi/core/communication/types.py +27 -0
  27. lionagi/core/communication/utils.py +254 -0
  28. lionagi/core/forms/__init__.py +3 -0
  29. lionagi/core/forms/base.py +232 -0
  30. lionagi/core/forms/form.py +791 -0
  31. lionagi/core/forms/report.py +321 -0
  32. lionagi/core/forms/types.py +13 -0
  33. lionagi/core/forms/utils.py +26 -0
  34. lionagi/core/generic/__init__.py +3 -6
  35. lionagi/core/generic/component.py +422 -0
  36. lionagi/core/generic/edge.py +143 -101
  37. lionagi/core/generic/element.py +195 -0
  38. lionagi/core/generic/graph.py +297 -180
  39. lionagi/core/generic/log.py +151 -0
  40. lionagi/core/generic/log_manager.py +320 -0
  41. lionagi/core/generic/node.py +7 -229
  42. lionagi/core/generic/pile.py +1017 -0
  43. lionagi/core/generic/progression.py +388 -0
  44. lionagi/core/generic/types.py +23 -0
  45. lionagi/core/generic/utils.py +50 -0
  46. lionagi/core/models/__init__.py +5 -0
  47. lionagi/core/models/base.py +85 -0
  48. lionagi/core/models/field_model.py +122 -0
  49. lionagi/core/models/new_model_params.py +195 -0
  50. lionagi/core/models/note.py +351 -0
  51. lionagi/core/models/operable_model.py +392 -0
  52. lionagi/core/models/schema_model.py +50 -0
  53. lionagi/core/models/types.py +10 -0
  54. lionagi/core/session/__init__.py +3 -0
  55. lionagi/core/session/branch.py +115 -415
  56. lionagi/core/session/branch_mixins.py +507 -0
  57. lionagi/core/session/session.py +122 -257
  58. lionagi/core/session/types.py +8 -0
  59. lionagi/core/typing/__init__.py +9 -0
  60. lionagi/core/typing/concepts.py +132 -0
  61. lionagi/core/typing/config.py +15 -0
  62. lionagi/core/typing/id.py +221 -0
  63. lionagi/core/typing/pydantic_.py +33 -0
  64. lionagi/core/typing/typing_.py +54 -0
  65. lionagi/integrations/__init__.py +0 -1
  66. lionagi/integrations/anthropic_/AnthropicModel.py +268 -0
  67. lionagi/integrations/anthropic_/AnthropicService.py +113 -0
  68. lionagi/integrations/anthropic_/__init__.py +3 -0
  69. lionagi/integrations/anthropic_/anthropic_max_output_token_data.yaml +7 -0
  70. lionagi/integrations/anthropic_/anthropic_price_data.yaml +14 -0
  71. lionagi/integrations/anthropic_/api_endpoints/__init__.py +3 -0
  72. lionagi/integrations/anthropic_/api_endpoints/api_request.py +277 -0
  73. lionagi/integrations/anthropic_/api_endpoints/data_models.py +40 -0
  74. lionagi/integrations/anthropic_/api_endpoints/match_response.py +119 -0
  75. lionagi/integrations/anthropic_/api_endpoints/messages/__init__.py +3 -0
  76. lionagi/integrations/anthropic_/api_endpoints/messages/request/__init__.py +3 -0
  77. lionagi/integrations/anthropic_/api_endpoints/messages/request/message_models.py +14 -0
  78. lionagi/integrations/anthropic_/api_endpoints/messages/request/request_body.py +74 -0
  79. lionagi/integrations/anthropic_/api_endpoints/messages/response/content_models.py +32 -0
  80. lionagi/integrations/anthropic_/api_endpoints/messages/response/response_body.py +101 -0
  81. lionagi/integrations/anthropic_/api_endpoints/messages/response/usage_models.py +25 -0
  82. lionagi/integrations/anthropic_/version.py +5 -0
  83. lionagi/integrations/groq_/GroqModel.py +318 -0
  84. lionagi/integrations/groq_/GroqService.py +147 -0
  85. lionagi/integrations/groq_/__init__.py +3 -0
  86. lionagi/integrations/groq_/api_endpoints/data_models.py +187 -0
  87. lionagi/integrations/groq_/api_endpoints/groq_request.py +288 -0
  88. lionagi/integrations/groq_/api_endpoints/match_response.py +106 -0
  89. lionagi/integrations/groq_/api_endpoints/response_utils.py +105 -0
  90. lionagi/integrations/groq_/groq_max_output_token_data.yaml +21 -0
  91. lionagi/integrations/groq_/groq_price_data.yaml +58 -0
  92. lionagi/integrations/groq_/groq_rate_limits.yaml +105 -0
  93. lionagi/integrations/groq_/version.py +5 -0
  94. lionagi/integrations/litellm_/__init__.py +3 -0
  95. lionagi/integrations/litellm_/imodel.py +69 -0
  96. lionagi/integrations/ollama_/OllamaModel.py +244 -0
  97. lionagi/integrations/ollama_/OllamaService.py +138 -0
  98. lionagi/integrations/ollama_/__init__.py +3 -0
  99. lionagi/integrations/ollama_/api_endpoints/__init__.py +3 -0
  100. lionagi/integrations/ollama_/api_endpoints/api_request.py +179 -0
  101. lionagi/integrations/ollama_/api_endpoints/chat_completion/__init__.py +3 -0
  102. lionagi/integrations/ollama_/api_endpoints/chat_completion/message_models.py +31 -0
  103. lionagi/integrations/ollama_/api_endpoints/chat_completion/request_body.py +46 -0
  104. lionagi/integrations/ollama_/api_endpoints/chat_completion/response_body.py +67 -0
  105. lionagi/integrations/ollama_/api_endpoints/chat_completion/tool_models.py +49 -0
  106. lionagi/integrations/ollama_/api_endpoints/completion/request_body.py +72 -0
  107. lionagi/integrations/ollama_/api_endpoints/completion/response_body.py +59 -0
  108. lionagi/integrations/ollama_/api_endpoints/data_models.py +15 -0
  109. lionagi/integrations/ollama_/api_endpoints/embedding/request_body.py +33 -0
  110. lionagi/integrations/ollama_/api_endpoints/embedding/response_body.py +29 -0
  111. lionagi/integrations/ollama_/api_endpoints/match_data_model.py +62 -0
  112. lionagi/integrations/ollama_/api_endpoints/match_response.py +190 -0
  113. lionagi/integrations/ollama_/api_endpoints/model/__init__.py +3 -0
  114. lionagi/integrations/ollama_/api_endpoints/model/copy_model.py +13 -0
  115. lionagi/integrations/ollama_/api_endpoints/model/create_model.py +28 -0
  116. lionagi/integrations/ollama_/api_endpoints/model/delete_model.py +11 -0
  117. lionagi/integrations/ollama_/api_endpoints/model/list_model.py +60 -0
  118. lionagi/integrations/ollama_/api_endpoints/model/pull_model.py +34 -0
  119. lionagi/integrations/ollama_/api_endpoints/model/push_model.py +35 -0
  120. lionagi/integrations/ollama_/api_endpoints/model/show_model.py +36 -0
  121. lionagi/integrations/ollama_/api_endpoints/option_models.py +68 -0
  122. lionagi/integrations/openai_/OpenAIModel.py +414 -0
  123. lionagi/integrations/openai_/OpenAIService.py +426 -0
  124. lionagi/integrations/openai_/api_endpoints/__init__.py +3 -0
  125. lionagi/integrations/openai_/api_endpoints/api_request.py +277 -0
  126. lionagi/integrations/openai_/api_endpoints/audio/__init__.py +9 -0
  127. lionagi/integrations/openai_/api_endpoints/audio/speech_models.py +34 -0
  128. lionagi/integrations/openai_/api_endpoints/audio/transcription_models.py +136 -0
  129. lionagi/integrations/openai_/api_endpoints/audio/translation_models.py +41 -0
  130. lionagi/integrations/openai_/api_endpoints/audio/types.py +41 -0
  131. lionagi/integrations/openai_/api_endpoints/batch/__init__.py +17 -0
  132. lionagi/integrations/openai_/api_endpoints/batch/batch_models.py +146 -0
  133. lionagi/integrations/openai_/api_endpoints/batch/cancel_batch.py +7 -0
  134. lionagi/integrations/openai_/api_endpoints/batch/create_batch.py +26 -0
  135. lionagi/integrations/openai_/api_endpoints/batch/list_batch.py +37 -0
  136. lionagi/integrations/openai_/api_endpoints/batch/request_object_models.py +65 -0
  137. lionagi/integrations/openai_/api_endpoints/batch/retrieve_batch.py +7 -0
  138. lionagi/integrations/openai_/api_endpoints/batch/types.py +4 -0
  139. lionagi/integrations/openai_/api_endpoints/chat_completions/__init__.py +1 -0
  140. lionagi/integrations/openai_/api_endpoints/chat_completions/request/__init__.py +39 -0
  141. lionagi/integrations/openai_/api_endpoints/chat_completions/request/message_models.py +121 -0
  142. lionagi/integrations/openai_/api_endpoints/chat_completions/request/request_body.py +221 -0
  143. lionagi/integrations/openai_/api_endpoints/chat_completions/request/response_format.py +71 -0
  144. lionagi/integrations/openai_/api_endpoints/chat_completions/request/stream_options.py +14 -0
  145. lionagi/integrations/openai_/api_endpoints/chat_completions/request/tool_choice_models.py +17 -0
  146. lionagi/integrations/openai_/api_endpoints/chat_completions/request/tool_models.py +54 -0
  147. lionagi/integrations/openai_/api_endpoints/chat_completions/request/types.py +18 -0
  148. lionagi/integrations/openai_/api_endpoints/chat_completions/response/choice_models.py +62 -0
  149. lionagi/integrations/openai_/api_endpoints/chat_completions/response/function_models.py +16 -0
  150. lionagi/integrations/openai_/api_endpoints/chat_completions/response/log_prob_models.py +47 -0
  151. lionagi/integrations/openai_/api_endpoints/chat_completions/response/message_models.py +25 -0
  152. lionagi/integrations/openai_/api_endpoints/chat_completions/response/response_body.py +99 -0
  153. lionagi/integrations/openai_/api_endpoints/chat_completions/response/types.py +8 -0
  154. lionagi/integrations/openai_/api_endpoints/chat_completions/response/usage_models.py +24 -0
  155. lionagi/integrations/openai_/api_endpoints/chat_completions/util.py +46 -0
  156. lionagi/integrations/openai_/api_endpoints/data_models.py +23 -0
  157. lionagi/integrations/openai_/api_endpoints/embeddings/__init__.py +3 -0
  158. lionagi/integrations/openai_/api_endpoints/embeddings/request_body.py +79 -0
  159. lionagi/integrations/openai_/api_endpoints/embeddings/response_body.py +67 -0
  160. lionagi/integrations/openai_/api_endpoints/files/__init__.py +11 -0
  161. lionagi/integrations/openai_/api_endpoints/files/delete_file.py +20 -0
  162. lionagi/integrations/openai_/api_endpoints/files/file_models.py +56 -0
  163. lionagi/integrations/openai_/api_endpoints/files/list_files.py +27 -0
  164. lionagi/integrations/openai_/api_endpoints/files/retrieve_file.py +9 -0
  165. lionagi/integrations/openai_/api_endpoints/files/upload_file.py +38 -0
  166. lionagi/integrations/openai_/api_endpoints/fine_tuning/__init__.py +37 -0
  167. lionagi/integrations/openai_/api_endpoints/fine_tuning/cancel_jobs.py +9 -0
  168. lionagi/integrations/openai_/api_endpoints/fine_tuning/create_jobs.py +133 -0
  169. lionagi/integrations/openai_/api_endpoints/fine_tuning/fine_tuning_job_checkpoint_models.py +58 -0
  170. lionagi/integrations/openai_/api_endpoints/fine_tuning/fine_tuning_job_event_models.py +31 -0
  171. lionagi/integrations/openai_/api_endpoints/fine_tuning/fine_tuning_job_models.py +140 -0
  172. lionagi/integrations/openai_/api_endpoints/fine_tuning/list_fine_tuning_checkpoints.py +51 -0
  173. lionagi/integrations/openai_/api_endpoints/fine_tuning/list_fine_tuning_events.py +42 -0
  174. lionagi/integrations/openai_/api_endpoints/fine_tuning/list_fine_tuning_jobs.py +31 -0
  175. lionagi/integrations/openai_/api_endpoints/fine_tuning/retrieve_jobs.py +9 -0
  176. lionagi/integrations/openai_/api_endpoints/fine_tuning/training_format.py +30 -0
  177. lionagi/integrations/openai_/api_endpoints/images/__init__.py +9 -0
  178. lionagi/integrations/openai_/api_endpoints/images/image_edit_models.py +69 -0
  179. lionagi/integrations/openai_/api_endpoints/images/image_models.py +56 -0
  180. lionagi/integrations/openai_/api_endpoints/images/image_variation_models.py +56 -0
  181. lionagi/integrations/openai_/api_endpoints/images/response_body.py +30 -0
  182. lionagi/integrations/openai_/api_endpoints/match_data_model.py +197 -0
  183. lionagi/integrations/openai_/api_endpoints/match_response.py +336 -0
  184. lionagi/integrations/openai_/api_endpoints/models/__init__.py +7 -0
  185. lionagi/integrations/openai_/api_endpoints/models/delete_fine_tuned_model.py +17 -0
  186. lionagi/integrations/openai_/api_endpoints/models/models_models.py +31 -0
  187. lionagi/integrations/openai_/api_endpoints/models/retrieve_model.py +9 -0
  188. lionagi/integrations/openai_/api_endpoints/moderations/__init__.py +3 -0
  189. lionagi/integrations/openai_/api_endpoints/moderations/request_body.py +20 -0
  190. lionagi/integrations/openai_/api_endpoints/moderations/response_body.py +139 -0
  191. lionagi/integrations/openai_/api_endpoints/uploads/__init__.py +19 -0
  192. lionagi/integrations/openai_/api_endpoints/uploads/add_upload_part.py +11 -0
  193. lionagi/integrations/openai_/api_endpoints/uploads/cancel_upload.py +7 -0
  194. lionagi/integrations/openai_/api_endpoints/uploads/complete_upload.py +18 -0
  195. lionagi/integrations/openai_/api_endpoints/uploads/create_upload.py +17 -0
  196. lionagi/integrations/openai_/api_endpoints/uploads/uploads_models.py +52 -0
  197. lionagi/integrations/openai_/image_token_calculator/image_token_calculator.py +92 -0
  198. lionagi/integrations/openai_/image_token_calculator/openai_image_token_data.yaml +15 -0
  199. lionagi/integrations/openai_/openai_max_output_token_data.yaml +12 -0
  200. lionagi/integrations/openai_/openai_price_data.yaml +26 -0
  201. lionagi/integrations/openai_/version.py +1 -0
  202. lionagi/integrations/pandas_/__init__.py +24 -0
  203. lionagi/integrations/pandas_/extend_df.py +61 -0
  204. lionagi/integrations/pandas_/read.py +103 -0
  205. lionagi/integrations/pandas_/remove_rows.py +61 -0
  206. lionagi/integrations/pandas_/replace_keywords.py +65 -0
  207. lionagi/integrations/pandas_/save.py +131 -0
  208. lionagi/integrations/pandas_/search_keywords.py +69 -0
  209. lionagi/integrations/pandas_/to_df.py +196 -0
  210. lionagi/integrations/pandas_/update_cells.py +54 -0
  211. lionagi/integrations/perplexity_/PerplexityModel.py +269 -0
  212. lionagi/integrations/perplexity_/PerplexityService.py +109 -0
  213. lionagi/integrations/perplexity_/__init__.py +3 -0
  214. lionagi/integrations/perplexity_/api_endpoints/api_request.py +171 -0
  215. lionagi/integrations/perplexity_/api_endpoints/chat_completions/request/request_body.py +121 -0
  216. lionagi/integrations/perplexity_/api_endpoints/chat_completions/response/response_body.py +146 -0
  217. lionagi/integrations/perplexity_/api_endpoints/data_models.py +63 -0
  218. lionagi/integrations/perplexity_/api_endpoints/match_response.py +26 -0
  219. lionagi/integrations/perplexity_/perplexity_max_output_token_data.yaml +3 -0
  220. lionagi/integrations/perplexity_/perplexity_price_data.yaml +10 -0
  221. lionagi/integrations/perplexity_/version.py +1 -0
  222. lionagi/integrations/pydantic_/__init__.py +8 -0
  223. lionagi/integrations/pydantic_/break_down_annotation.py +81 -0
  224. lionagi/integrations/pydantic_/new_model.py +208 -0
  225. lionagi/integrations/services.py +17 -0
  226. lionagi/libs/__init__.py +0 -55
  227. lionagi/libs/compress/models.py +62 -0
  228. lionagi/libs/compress/utils.py +81 -0
  229. lionagi/libs/constants.py +98 -0
  230. lionagi/libs/file/chunk.py +265 -0
  231. lionagi/libs/file/file_ops.py +114 -0
  232. lionagi/libs/file/params.py +212 -0
  233. lionagi/libs/file/path.py +301 -0
  234. lionagi/libs/file/process.py +139 -0
  235. lionagi/libs/file/save.py +90 -0
  236. lionagi/libs/file/types.py +22 -0
  237. lionagi/libs/func/async_calls/__init__.py +21 -0
  238. lionagi/libs/func/async_calls/alcall.py +157 -0
  239. lionagi/libs/func/async_calls/bcall.py +82 -0
  240. lionagi/libs/func/async_calls/mcall.py +134 -0
  241. lionagi/libs/func/async_calls/pcall.py +149 -0
  242. lionagi/libs/func/async_calls/rcall.py +185 -0
  243. lionagi/libs/func/async_calls/tcall.py +114 -0
  244. lionagi/libs/func/async_calls/ucall.py +85 -0
  245. lionagi/libs/func/decorators.py +277 -0
  246. lionagi/libs/func/lcall.py +57 -0
  247. lionagi/libs/func/params.py +64 -0
  248. lionagi/libs/func/throttle.py +119 -0
  249. lionagi/libs/func/types.py +39 -0
  250. lionagi/libs/func/utils.py +96 -0
  251. lionagi/libs/package/imports.py +162 -0
  252. lionagi/libs/package/management.py +58 -0
  253. lionagi/libs/package/params.py +26 -0
  254. lionagi/libs/package/system.py +18 -0
  255. lionagi/libs/package/types.py +26 -0
  256. lionagi/libs/parse/__init__.py +1 -0
  257. lionagi/libs/parse/flatten/__init__.py +9 -0
  258. lionagi/libs/parse/flatten/flatten.py +168 -0
  259. lionagi/libs/parse/flatten/params.py +52 -0
  260. lionagi/libs/parse/flatten/unflatten.py +79 -0
  261. lionagi/libs/parse/json/__init__.py +27 -0
  262. lionagi/libs/parse/json/as_readable.py +104 -0
  263. lionagi/libs/parse/json/extract.py +102 -0
  264. lionagi/libs/parse/json/parse.py +179 -0
  265. lionagi/libs/parse/json/schema.py +227 -0
  266. lionagi/libs/parse/json/to_json.py +71 -0
  267. lionagi/libs/parse/nested/__init__.py +33 -0
  268. lionagi/libs/parse/nested/nfilter.py +55 -0
  269. lionagi/libs/parse/nested/nget.py +40 -0
  270. lionagi/libs/parse/nested/ninsert.py +103 -0
  271. lionagi/libs/parse/nested/nmerge.py +155 -0
  272. lionagi/libs/parse/nested/npop.py +66 -0
  273. lionagi/libs/parse/nested/nset.py +89 -0
  274. lionagi/libs/parse/nested/to_flat_list.py +64 -0
  275. lionagi/libs/parse/nested/utils.py +185 -0
  276. lionagi/libs/parse/string_parse/__init__.py +11 -0
  277. lionagi/libs/parse/string_parse/code_block.py +73 -0
  278. lionagi/libs/parse/string_parse/docstring.py +179 -0
  279. lionagi/libs/parse/string_parse/function_.py +92 -0
  280. lionagi/libs/parse/type_convert/__init__.py +19 -0
  281. lionagi/libs/parse/type_convert/params.py +145 -0
  282. lionagi/libs/parse/type_convert/to_dict.py +333 -0
  283. lionagi/libs/parse/type_convert/to_list.py +186 -0
  284. lionagi/libs/parse/type_convert/to_num.py +358 -0
  285. lionagi/libs/parse/type_convert/to_str.py +195 -0
  286. lionagi/libs/parse/types.py +9 -0
  287. lionagi/libs/parse/validate/__init__.py +14 -0
  288. lionagi/libs/parse/validate/boolean.py +96 -0
  289. lionagi/libs/parse/validate/keys.py +150 -0
  290. lionagi/libs/parse/validate/mapping.py +109 -0
  291. lionagi/libs/parse/validate/params.py +62 -0
  292. lionagi/libs/parse/xml/__init__.py +10 -0
  293. lionagi/libs/parse/xml/convert.py +56 -0
  294. lionagi/libs/parse/xml/parser.py +93 -0
  295. lionagi/libs/string_similarity/__init__.py +32 -0
  296. lionagi/libs/string_similarity/algorithms.py +219 -0
  297. lionagi/libs/string_similarity/matcher.py +102 -0
  298. lionagi/libs/string_similarity/utils.py +15 -0
  299. lionagi/libs/utils.py +255 -0
  300. lionagi/operations/__init__.py +3 -6
  301. lionagi/operations/brainstorm/__init__.py +3 -0
  302. lionagi/operations/brainstorm/brainstorm.py +204 -0
  303. lionagi/operations/brainstorm/prompt.py +1 -0
  304. lionagi/operations/plan/__init__.py +3 -0
  305. lionagi/operations/plan/plan.py +172 -0
  306. lionagi/operations/plan/prompt.py +21 -0
  307. lionagi/operations/select/__init__.py +3 -0
  308. lionagi/operations/select/prompt.py +1 -0
  309. lionagi/operations/select/select.py +100 -0
  310. lionagi/operations/select/utils.py +107 -0
  311. lionagi/operations/utils.py +35 -0
  312. lionagi/protocols/adapters/adapter.py +79 -0
  313. lionagi/protocols/adapters/json_adapter.py +43 -0
  314. lionagi/protocols/adapters/pandas_adapter.py +96 -0
  315. lionagi/protocols/configs/__init__.py +15 -0
  316. lionagi/protocols/configs/branch_config.py +86 -0
  317. lionagi/protocols/configs/id_config.py +15 -0
  318. lionagi/protocols/configs/imodel_config.py +73 -0
  319. lionagi/protocols/configs/log_config.py +93 -0
  320. lionagi/protocols/configs/retry_config.py +29 -0
  321. lionagi/protocols/operatives/__init__.py +15 -0
  322. lionagi/protocols/operatives/action.py +181 -0
  323. lionagi/protocols/operatives/instruct.py +196 -0
  324. lionagi/protocols/operatives/operative.py +182 -0
  325. lionagi/protocols/operatives/prompts.py +232 -0
  326. lionagi/protocols/operatives/reason.py +56 -0
  327. lionagi/protocols/operatives/step.py +217 -0
  328. lionagi/protocols/registries/_component_registry.py +19 -0
  329. lionagi/protocols/registries/_pile_registry.py +26 -0
  330. lionagi/service/__init__.py +13 -0
  331. lionagi/service/complete_request_info.py +11 -0
  332. lionagi/service/imodel.py +110 -0
  333. lionagi/service/rate_limiter.py +108 -0
  334. lionagi/service/service.py +37 -0
  335. lionagi/service/service_match_util.py +131 -0
  336. lionagi/service/service_util.py +72 -0
  337. lionagi/service/token_calculator.py +51 -0
  338. lionagi/settings.py +136 -0
  339. lionagi/strategies/base.py +53 -0
  340. lionagi/strategies/concurrent.py +71 -0
  341. lionagi/strategies/concurrent_chunk.py +43 -0
  342. lionagi/strategies/concurrent_sequential_chunk.py +104 -0
  343. lionagi/strategies/params.py +128 -0
  344. lionagi/strategies/sequential.py +23 -0
  345. lionagi/strategies/sequential_chunk.py +89 -0
  346. lionagi/strategies/sequential_concurrent_chunk.py +100 -0
  347. lionagi/strategies/types.py +21 -0
  348. lionagi/strategies/utils.py +49 -0
  349. lionagi/version.py +1 -1
  350. lionagi-0.5.0.dist-info/METADATA +348 -0
  351. lionagi-0.5.0.dist-info/RECORD +373 -0
  352. {lionagi-0.3.8.dist-info → lionagi-0.5.0.dist-info}/WHEEL +1 -1
  353. lionagi/core/_setting/_setting.py +0 -59
  354. lionagi/core/action/README.md +0 -20
  355. lionagi/core/action/manual.py +0 -1
  356. lionagi/core/action/node.py +0 -94
  357. lionagi/core/action/tool_manager.py +0 -342
  358. lionagi/core/agent/README.md +0 -1
  359. lionagi/core/agent/base_agent.py +0 -82
  360. lionagi/core/agent/eval/README.md +0 -1
  361. lionagi/core/agent/eval/evaluator.py +0 -1
  362. lionagi/core/agent/eval/vote.py +0 -40
  363. lionagi/core/agent/learn/learner.py +0 -59
  364. lionagi/core/agent/plan/unit_template.py +0 -1
  365. lionagi/core/collections/README.md +0 -23
  366. lionagi/core/collections/__init__.py +0 -16
  367. lionagi/core/collections/_logger.py +0 -312
  368. lionagi/core/collections/abc/README.md +0 -63
  369. lionagi/core/collections/abc/__init__.py +0 -53
  370. lionagi/core/collections/abc/component.py +0 -620
  371. lionagi/core/collections/abc/concepts.py +0 -277
  372. lionagi/core/collections/abc/exceptions.py +0 -136
  373. lionagi/core/collections/abc/util.py +0 -45
  374. lionagi/core/collections/exchange.py +0 -146
  375. lionagi/core/collections/flow.py +0 -416
  376. lionagi/core/collections/model.py +0 -465
  377. lionagi/core/collections/pile.py +0 -1232
  378. lionagi/core/collections/progression.py +0 -221
  379. lionagi/core/collections/util.py +0 -73
  380. lionagi/core/director/README.md +0 -1
  381. lionagi/core/director/direct.py +0 -298
  382. lionagi/core/director/director.py +0 -2
  383. lionagi/core/director/operations/select.py +0 -3
  384. lionagi/core/director/operations/utils.py +0 -6
  385. lionagi/core/engine/branch_engine.py +0 -361
  386. lionagi/core/engine/instruction_map_engine.py +0 -213
  387. lionagi/core/engine/sandbox_.py +0 -16
  388. lionagi/core/engine/script_engine.py +0 -89
  389. lionagi/core/executor/base_executor.py +0 -97
  390. lionagi/core/executor/graph_executor.py +0 -335
  391. lionagi/core/executor/neo4j_executor.py +0 -394
  392. lionagi/core/generic/README.md +0 -0
  393. lionagi/core/generic/edge_condition.py +0 -17
  394. lionagi/core/generic/hyperedge.py +0 -1
  395. lionagi/core/generic/tree.py +0 -49
  396. lionagi/core/generic/tree_node.py +0 -85
  397. lionagi/core/mail/__init__.py +0 -11
  398. lionagi/core/mail/mail.py +0 -26
  399. lionagi/core/mail/mail_manager.py +0 -185
  400. lionagi/core/mail/package.py +0 -49
  401. lionagi/core/mail/start_mail.py +0 -36
  402. lionagi/core/message/__init__.py +0 -18
  403. lionagi/core/message/action_request.py +0 -114
  404. lionagi/core/message/action_response.py +0 -121
  405. lionagi/core/message/assistant_response.py +0 -80
  406. lionagi/core/message/instruction.py +0 -194
  407. lionagi/core/message/message.py +0 -86
  408. lionagi/core/message/system.py +0 -71
  409. lionagi/core/message/util.py +0 -274
  410. lionagi/core/report/__init__.py +0 -4
  411. lionagi/core/report/base.py +0 -201
  412. lionagi/core/report/form.py +0 -212
  413. lionagi/core/report/report.py +0 -150
  414. lionagi/core/report/util.py +0 -15
  415. lionagi/core/rule/_default.py +0 -17
  416. lionagi/core/rule/action.py +0 -87
  417. lionagi/core/rule/base.py +0 -234
  418. lionagi/core/rule/boolean.py +0 -56
  419. lionagi/core/rule/choice.py +0 -48
  420. lionagi/core/rule/mapping.py +0 -82
  421. lionagi/core/rule/number.py +0 -73
  422. lionagi/core/rule/rulebook.py +0 -45
  423. lionagi/core/rule/string.py +0 -43
  424. lionagi/core/rule/util.py +0 -0
  425. lionagi/core/session/directive_mixin.py +0 -307
  426. lionagi/core/structure/__init__.py +0 -1
  427. lionagi/core/structure/chain.py +0 -1
  428. lionagi/core/structure/forest.py +0 -1
  429. lionagi/core/structure/graph.py +0 -1
  430. lionagi/core/structure/tree.py +0 -1
  431. lionagi/core/unit/__init__.py +0 -4
  432. lionagi/core/unit/parallel_unit.py +0 -234
  433. lionagi/core/unit/template/action.py +0 -65
  434. lionagi/core/unit/template/base.py +0 -35
  435. lionagi/core/unit/template/plan.py +0 -69
  436. lionagi/core/unit/template/predict.py +0 -95
  437. lionagi/core/unit/template/score.py +0 -108
  438. lionagi/core/unit/template/select.py +0 -91
  439. lionagi/core/unit/unit.py +0 -452
  440. lionagi/core/unit/unit_form.py +0 -290
  441. lionagi/core/unit/unit_mixin.py +0 -1166
  442. lionagi/core/unit/util.py +0 -103
  443. lionagi/core/validator/validator.py +0 -376
  444. lionagi/core/work/work.py +0 -59
  445. lionagi/core/work/work_edge.py +0 -102
  446. lionagi/core/work/work_function.py +0 -114
  447. lionagi/core/work/work_function_node.py +0 -50
  448. lionagi/core/work/work_queue.py +0 -90
  449. lionagi/core/work/work_task.py +0 -151
  450. lionagi/core/work/worker.py +0 -410
  451. lionagi/core/work/worker_engine.py +0 -208
  452. lionagi/core/work/worklog.py +0 -108
  453. lionagi/experimental/compressor/base.py +0 -47
  454. lionagi/experimental/compressor/llm_compressor.py +0 -265
  455. lionagi/experimental/compressor/llm_summarizer.py +0 -61
  456. lionagi/experimental/compressor/util.py +0 -70
  457. lionagi/experimental/directive/README.md +0 -1
  458. lionagi/experimental/directive/__init__.py +0 -19
  459. lionagi/experimental/directive/parser/base_parser.py +0 -294
  460. lionagi/experimental/directive/parser/base_syntax.txt +0 -200
  461. lionagi/experimental/directive/template/base_template.py +0 -71
  462. lionagi/experimental/directive/template/schema.py +0 -36
  463. lionagi/experimental/directive/tokenizer.py +0 -59
  464. lionagi/experimental/evaluator/README.md +0 -1
  465. lionagi/experimental/evaluator/ast_evaluator.py +0 -119
  466. lionagi/experimental/evaluator/base_evaluator.py +0 -213
  467. lionagi/experimental/knowledge/__init__.py +0 -0
  468. lionagi/experimental/knowledge/base.py +0 -10
  469. lionagi/experimental/knowledge/graph.py +0 -0
  470. lionagi/experimental/memory/__init__.py +0 -0
  471. lionagi/experimental/strategies/__init__.py +0 -0
  472. lionagi/experimental/strategies/base.py +0 -1
  473. lionagi/integrations/bridge/__init__.py +0 -4
  474. lionagi/integrations/bridge/autogen_/__init__.py +0 -0
  475. lionagi/integrations/bridge/autogen_/autogen_.py +0 -127
  476. lionagi/integrations/bridge/langchain_/__init__.py +0 -0
  477. lionagi/integrations/bridge/langchain_/documents.py +0 -138
  478. lionagi/integrations/bridge/langchain_/langchain_bridge.py +0 -68
  479. lionagi/integrations/bridge/llamaindex_/__init__.py +0 -0
  480. lionagi/integrations/bridge/llamaindex_/index.py +0 -36
  481. lionagi/integrations/bridge/llamaindex_/llama_index_bridge.py +0 -108
  482. lionagi/integrations/bridge/llamaindex_/llama_pack.py +0 -256
  483. lionagi/integrations/bridge/llamaindex_/node_parser.py +0 -92
  484. lionagi/integrations/bridge/llamaindex_/reader.py +0 -201
  485. lionagi/integrations/bridge/llamaindex_/textnode.py +0 -59
  486. lionagi/integrations/bridge/pydantic_/__init__.py +0 -0
  487. lionagi/integrations/bridge/pydantic_/pydantic_bridge.py +0 -7
  488. lionagi/integrations/bridge/transformers_/__init__.py +0 -0
  489. lionagi/integrations/bridge/transformers_/install_.py +0 -39
  490. lionagi/integrations/chunker/__init__.py +0 -0
  491. lionagi/integrations/chunker/chunk.py +0 -314
  492. lionagi/integrations/config/__init__.py +0 -4
  493. lionagi/integrations/config/mlx_configs.py +0 -1
  494. lionagi/integrations/config/oai_configs.py +0 -154
  495. lionagi/integrations/config/ollama_configs.py +0 -1
  496. lionagi/integrations/config/openrouter_configs.py +0 -74
  497. lionagi/integrations/langchain_/__init__.py +0 -0
  498. lionagi/integrations/llamaindex_/__init__.py +0 -0
  499. lionagi/integrations/loader/__init__.py +0 -0
  500. lionagi/integrations/loader/load.py +0 -257
  501. lionagi/integrations/loader/load_util.py +0 -214
  502. lionagi/integrations/provider/__init__.py +0 -11
  503. lionagi/integrations/provider/_mapping.py +0 -47
  504. lionagi/integrations/provider/litellm.py +0 -53
  505. lionagi/integrations/provider/mistralai.py +0 -1
  506. lionagi/integrations/provider/mlx_service.py +0 -55
  507. lionagi/integrations/provider/oai.py +0 -196
  508. lionagi/integrations/provider/ollama.py +0 -55
  509. lionagi/integrations/provider/openrouter.py +0 -170
  510. lionagi/integrations/provider/services.py +0 -138
  511. lionagi/integrations/provider/transformers.py +0 -108
  512. lionagi/integrations/storage/__init__.py +0 -3
  513. lionagi/integrations/storage/neo4j.py +0 -681
  514. lionagi/integrations/storage/storage_util.py +0 -302
  515. lionagi/integrations/storage/structure_excel.py +0 -291
  516. lionagi/integrations/storage/to_csv.py +0 -70
  517. lionagi/integrations/storage/to_excel.py +0 -91
  518. lionagi/libs/ln_api.py +0 -944
  519. lionagi/libs/ln_async.py +0 -208
  520. lionagi/libs/ln_context.py +0 -37
  521. lionagi/libs/ln_convert.py +0 -671
  522. lionagi/libs/ln_dataframe.py +0 -187
  523. lionagi/libs/ln_func_call.py +0 -1328
  524. lionagi/libs/ln_image.py +0 -114
  525. lionagi/libs/ln_knowledge_graph.py +0 -422
  526. lionagi/libs/ln_nested.py +0 -822
  527. lionagi/libs/ln_parse.py +0 -750
  528. lionagi/libs/ln_queue.py +0 -107
  529. lionagi/libs/ln_tokenize.py +0 -179
  530. lionagi/libs/ln_validate.py +0 -299
  531. lionagi/libs/special_tokens.py +0 -172
  532. lionagi/libs/sys_util.py +0 -710
  533. lionagi/lions/__init__.py +0 -0
  534. lionagi/lions/coder/__init__.py +0 -0
  535. lionagi/lions/coder/add_feature.py +0 -20
  536. lionagi/lions/coder/base_prompts.py +0 -22
  537. lionagi/lions/coder/code_form.py +0 -15
  538. lionagi/lions/coder/coder.py +0 -184
  539. lionagi/lions/coder/util.py +0 -101
  540. lionagi/lions/director/__init__.py +0 -0
  541. lionagi/lions/judge/__init__.py +0 -0
  542. lionagi/lions/judge/config.py +0 -8
  543. lionagi/lions/judge/data/__init__.py +0 -0
  544. lionagi/lions/judge/data/sample_codes.py +0 -526
  545. lionagi/lions/judge/data/sample_rurbic.py +0 -48
  546. lionagi/lions/judge/forms/__init__.py +0 -0
  547. lionagi/lions/judge/forms/code_analysis_form.py +0 -126
  548. lionagi/lions/judge/rubric.py +0 -34
  549. lionagi/lions/judge/services/__init__.py +0 -0
  550. lionagi/lions/judge/services/judge_code.py +0 -49
  551. lionagi/lions/researcher/__init__.py +0 -0
  552. lionagi/lions/researcher/data_source/__init__.py +0 -0
  553. lionagi/lions/researcher/data_source/finhub_.py +0 -192
  554. lionagi/lions/researcher/data_source/google_.py +0 -207
  555. lionagi/lions/researcher/data_source/wiki_.py +0 -98
  556. lionagi/lions/researcher/data_source/yfinance_.py +0 -21
  557. lionagi/operations/brainstorm.py +0 -87
  558. lionagi/operations/config.py +0 -6
  559. lionagi/operations/rank.py +0 -102
  560. lionagi/operations/score.py +0 -144
  561. lionagi/operations/select.py +0 -141
  562. lionagi-0.3.8.dist-info/METADATA +0 -241
  563. lionagi-0.3.8.dist-info/RECORD +0 -249
  564. /lionagi/{core/_setting → integrations/anthropic_/api_endpoints/messages/response}/__init__.py +0 -0
  565. /lionagi/{core/agent → integrations/groq_/api_endpoints}/__init__.py +0 -0
  566. /lionagi/{core/agent/eval → integrations/ollama_/api_endpoints/completion}/__init__.py +0 -0
  567. /lionagi/{core/agent/learn → integrations/ollama_/api_endpoints/embedding}/__init__.py +0 -0
  568. /lionagi/{core/agent/plan → integrations/openai_}/__init__.py +0 -0
  569. /lionagi/{core/director → integrations/openai_/api_endpoints/chat_completions/response}/__init__.py +0 -0
  570. /lionagi/{core/director/operations → integrations/openai_/image_token_calculator}/__init__.py +0 -0
  571. /lionagi/{core/engine → integrations/perplexity_/api_endpoints}/__init__.py +0 -0
  572. /lionagi/{core/executor → integrations/perplexity_/api_endpoints/chat_completions}/__init__.py +0 -0
  573. /lionagi/{core/generic/registry/component_registry → integrations/perplexity_/api_endpoints/chat_completions/request}/__init__.py +0 -0
  574. /lionagi/{core/rule → integrations/perplexity_/api_endpoints/chat_completions/response}/__init__.py +0 -0
  575. /lionagi/{core/unit/template → libs/compress}/__init__.py +0 -0
  576. /lionagi/{core/validator → libs/file}/__init__.py +0 -0
  577. /lionagi/{core/work → libs/func}/__init__.py +0 -0
  578. /lionagi/{experimental → libs/package}/__init__.py +0 -0
  579. /lionagi/{core/agent/plan/plan.py → libs/parse/params.py} +0 -0
  580. /lionagi/{experimental/compressor → protocols}/__init__.py +0 -0
  581. /lionagi/{experimental/directive/parser → protocols/adapters}/__init__.py +0 -0
  582. /lionagi/{experimental/directive/template → protocols/registries}/__init__.py +0 -0
  583. /lionagi/{experimental/evaluator → strategies}/__init__.py +0 -0
  584. {lionagi-0.3.8.dist-info → lionagi-0.5.0.dist-info/licenses}/LICENSE +0 -0
@@ -0,0 +1,204 @@
1
+ # Copyright (c) 2023 - 2024, HaiyangLi <quantocean.li at gmail dot com>
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+
6
+ from lionagi.core.session.branch import Branch
7
+ from lionagi.core.session.session import Session
8
+ from lionagi.core.typing import ID, Any, BaseModel
9
+ from lionagi.libs.func import alcall
10
+ from lionagi.libs.parse import to_flat_list
11
+ from lionagi.protocols.operatives.instruct import (
12
+ INSTRUCT_MODEL_FIELD,
13
+ Instruct,
14
+ InstructResponse,
15
+ )
16
+
17
+ from ..utils import prepare_instruct, prepare_session
18
+ from .prompt import PROMPT
19
+
20
+
21
+ class BrainstormOperation(BaseModel):
22
+ initial: Any
23
+ brainstorm: list[Instruct] | None = None
24
+ explore: list[InstructResponse] | None = None
25
+
26
+
27
+ async def run_instruct(
28
+ ins: Instruct,
29
+ session: Session,
30
+ branch: Branch,
31
+ auto_run: bool,
32
+ verbose: bool = True,
33
+ **kwargs: Any,
34
+ ) -> Any:
35
+ """Execute an instruction within a brainstorming session.
36
+
37
+ Args:
38
+ ins: The instruction model to run.
39
+ session: The current session.
40
+ branch: The branch to operate on.
41
+ auto_run: Whether to automatically run nested instructions.
42
+ verbose: Whether to enable verbose output.
43
+ **kwargs: Additional keyword arguments.
44
+
45
+ Returns:
46
+ The result of the instruction execution.
47
+ """
48
+
49
+ async def run(ins_):
50
+ if verbose:
51
+ msg_ = (
52
+ ins_.guidance[:100] + "..."
53
+ if len(ins_.guidance) > 100
54
+ else ins_.guidance
55
+ )
56
+ print(f"\n-----Running instruction-----\n{msg_}")
57
+ b_ = session.split(branch)
58
+ return await run_instruct(
59
+ ins_, session, b_, False, verbose=verbose, **kwargs
60
+ )
61
+
62
+ config = {**ins.model_dump(), **kwargs}
63
+ res = await branch.operate(**config)
64
+ branch.msgs.logger.dump()
65
+ instructs = []
66
+
67
+ if hasattr(res, "instruct_models"):
68
+ instructs = res.instruct_models
69
+
70
+ if auto_run is True and instructs:
71
+ ress = await alcall(instructs, run)
72
+ response_ = []
73
+ for res in ress:
74
+ if isinstance(res, list):
75
+ response_.extend(res)
76
+ else:
77
+ response_.append(res)
78
+ response_.insert(0, res)
79
+ return response_
80
+
81
+ return res
82
+
83
+
84
+ async def brainstorm(
85
+ instruct: Instruct | dict[str, Any],
86
+ num_instruct: int = 2,
87
+ session: Session | None = None,
88
+ branch: Branch | ID.Ref | None = None,
89
+ auto_run: bool = True,
90
+ auto_explore: bool = False,
91
+ explore_kwargs: dict[str, Any] | None = None,
92
+ branch_kwargs: dict[str, Any] | None = None,
93
+ return_session: bool = False,
94
+ verbose: bool = False,
95
+ **kwargs: Any,
96
+ ) -> Any:
97
+ """Perform a brainstorming session.
98
+
99
+ Args:
100
+ instruct: Instruction model or dictionary.
101
+ num_instruct: Number of instructions to generate.
102
+ session: Existing session or None to create a new one.
103
+ branch: Existing branch or reference.
104
+ auto_run: If True, automatically run generated instructions.
105
+ branch_kwargs: Additional arguments for branch creation.
106
+ return_session: If True, return the session with results.
107
+ verbose: Whether to enable verbose output.
108
+ **kwargs: Additional keyword arguments.
109
+
110
+ Returns:
111
+ The results of the brainstorming session, optionally with the session.
112
+ """
113
+
114
+ if auto_explore and not auto_run:
115
+ raise ValueError("auto_explore requires auto_run to be True.")
116
+
117
+ if verbose:
118
+ print(f"Starting brainstorming...")
119
+
120
+ field_models: list = kwargs.get("field_models", [])
121
+ if INSTRUCT_MODEL_FIELD not in field_models:
122
+ field_models.append(INSTRUCT_MODEL_FIELD)
123
+
124
+ kwargs["field_models"] = field_models
125
+ session, branch = prepare_session(session, branch, branch_kwargs)
126
+ instruct = prepare_instruct(
127
+ instruct, PROMPT.format(num_instruct=num_instruct)
128
+ )
129
+ res1 = await branch.operate(**instruct, **kwargs)
130
+ out = BrainstormOperation(initial=res1)
131
+
132
+ if verbose:
133
+ print("Initial brainstorming complete.")
134
+
135
+ instructs = None
136
+
137
+ async def run(ins_):
138
+ if verbose:
139
+ msg_ = (
140
+ ins_.guidance[:100] + "..."
141
+ if len(ins_.guidance) > 100
142
+ else ins_.guidance
143
+ )
144
+ print(f"\n-----Running instruction-----\n{msg_}")
145
+ b_ = session.split(branch)
146
+ return await run_instruct(
147
+ ins_, session, b_, auto_run, verbose=verbose, **kwargs
148
+ )
149
+
150
+ if not auto_run:
151
+ if return_session:
152
+ return out, session
153
+ return out
154
+
155
+ async with session.branches:
156
+ response_ = []
157
+ if hasattr(res1, "instruct_models"):
158
+ instructs: list[Instruct] = res1.instruct_models
159
+ ress = await alcall(instructs, run)
160
+ ress = to_flat_list(ress, dropna=True)
161
+
162
+ response_ = [
163
+ res if not isinstance(res, str | dict) else None
164
+ for res in ress
165
+ ]
166
+ response_ = to_flat_list(response_, unique=True, dropna=True)
167
+ out.brainstorm = (
168
+ response_ if isinstance(response_, list) else [response_]
169
+ )
170
+ response_.insert(0, res1)
171
+
172
+ if response_ and auto_explore:
173
+
174
+ async def explore(ins_: Instruct):
175
+ if verbose:
176
+ msg_ = (
177
+ ins_.guidance[:100] + "..."
178
+ if len(ins_.guidance) > 100
179
+ else ins_.guidance
180
+ )
181
+ print(f"\n-----Exploring Idea-----\n{msg_}")
182
+ b_ = session.split(branch)
183
+ res = await b_.instruct(ins_, **(explore_kwargs or {}))
184
+ return InstructResponse(
185
+ instruct=ins_,
186
+ response=res,
187
+ )
188
+
189
+ response_ = to_flat_list(
190
+ [
191
+ i.instruct_models
192
+ for i in response_
193
+ if hasattr(i, "instruct_models")
194
+ ],
195
+ dropna=True,
196
+ unique=True,
197
+ )
198
+ res_explore = await alcall(response_, explore)
199
+ out.explore = res_explore
200
+
201
+ if return_session:
202
+ return out, session
203
+
204
+ return out
@@ -0,0 +1 @@
1
+ PROMPT = """Perform a brainstorm session. Fill in {num_instruct} Instruct for the appropriate next step, we will run them separately and concurrently with same external context, but you should supplement each idea with certain amount of uniqueness while adhering to the guidelines and standards of the project. The Instruct should be concisely informational. If you think a particular step requries further extension, you should mention it in the instruct"""
@@ -0,0 +1,3 @@
1
+ from .plan import plan
2
+
3
+ __all__ = ["plan"]
@@ -0,0 +1,172 @@
1
+ # Copyright (c) 2023 - 2024, HaiyangLi <quantocean.li at gmail dot com>
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+
6
+ from lionagi.core.session.branch import Branch
7
+ from lionagi.core.session.session import Session
8
+ from lionagi.core.typing import ID, Any, BaseModel, Literal
9
+ from lionagi.protocols.operatives.instruct import (
10
+ INSTRUCT_MODEL_FIELD,
11
+ Instruct,
12
+ InstructResponse,
13
+ )
14
+
15
+ from ..utils import prepare_instruct, prepare_session
16
+ from .prompt import EXPANSION_PROMPT, PLAN_PROMPT
17
+
18
+
19
+ class PlanOperation(BaseModel):
20
+ initial: Any
21
+ plan: list[Instruct] | None = None
22
+ execute: list[InstructResponse] | None = None
23
+
24
+
25
+ async def run_step(
26
+ ins: Instruct,
27
+ session: Session,
28
+ branch: Branch,
29
+ verbose: bool = True,
30
+ **kwargs: Any,
31
+ ) -> Any:
32
+ """Execute a single step of the plan.
33
+
34
+ Args:
35
+ ins: The instruction model for the step.
36
+ session: The current session.
37
+ branch: The branch to operate on.
38
+ verbose: Whether to enable verbose output.
39
+ **kwargs: Additional keyword arguments.
40
+
41
+ Returns:
42
+ The result of the branch operation.
43
+ """
44
+ if verbose:
45
+ instruction = (
46
+ ins.instruction[:100] + "..."
47
+ if len(ins.instruction) > 100
48
+ else ins.instruction
49
+ )
50
+ print(f"Further planning: {instruction}")
51
+
52
+ config = {**ins.model_dump(), **kwargs}
53
+ guide = config.pop("guidance", "")
54
+ config["guidance"] = EXPANSION_PROMPT + "\n" + str(guide)
55
+
56
+ res = await branch.operate(**config)
57
+ branch.msgs.logger.dump()
58
+ return res
59
+
60
+
61
+ async def plan(
62
+ instruct: Instruct | dict[str, Any],
63
+ num_steps: int = 2,
64
+ session: Session | None = None,
65
+ branch: Branch | ID.Ref | None = None,
66
+ auto_run: bool = True,
67
+ auto_execute: bool = False,
68
+ execution_strategy: Literal["sequential"] = "sequential",
69
+ execution_kwargs: dict[str, Any] | None = None,
70
+ branch_kwargs: dict[str, Any] | None = None,
71
+ return_session: bool = False,
72
+ verbose: bool = True,
73
+ **kwargs: Any,
74
+ ) -> PlanOperation | tuple[list[InstructResponse], Session]:
75
+ """Create and execute a multi-step plan.
76
+
77
+ Args:
78
+ instruct: Instruction model or dictionary.
79
+ num_steps: Number of steps in the plan.
80
+ session: Existing session or None to create a new one.
81
+ branch: Existing branch or reference.
82
+ auto_run: If True, automatically run the steps.
83
+ branch_kwargs: Additional keyword arguments for branch creation.
84
+ return_session: If True, return the session along with results.
85
+ verbose: Whether to enable verbose output.
86
+ **kwargs: Additional keyword arguments.
87
+
88
+ Returns:
89
+ Results of the plan execution, optionally with the session.
90
+ """
91
+ if num_steps > 5:
92
+ raise ValueError("Number of steps must be 5 or less")
93
+
94
+ if verbose:
95
+ print(f"Planning execution with {num_steps} steps...")
96
+
97
+ field_models: list = kwargs.get("field_models", [])
98
+ if INSTRUCT_MODEL_FIELD not in field_models:
99
+ field_models.append(INSTRUCT_MODEL_FIELD)
100
+ kwargs["field_models"] = field_models
101
+ session, branch = prepare_session(session, branch, branch_kwargs)
102
+ execute_branch: Branch = session.split(branch)
103
+ instruct = prepare_instruct(
104
+ instruct, PLAN_PROMPT.format(num_steps=num_steps)
105
+ )
106
+
107
+ res1 = await branch.operate(**instruct, **kwargs)
108
+ out = PlanOperation(initial=res1)
109
+
110
+ if verbose:
111
+ print("Initial planning complete. Starting step planning...")
112
+
113
+ if not auto_run:
114
+ if return_session:
115
+ return res1, session
116
+ return res1
117
+
118
+ results = []
119
+ if hasattr(res1, "instruct_models"):
120
+ instructs: list[Instruct] = res1.instruct_models
121
+ for i, ins in enumerate(instructs, 1):
122
+ if verbose:
123
+ print(f"\n----- Planning step {i}/{len(instructs)} -----")
124
+ res = await run_step(
125
+ ins, session, branch, verbose=verbose, **kwargs
126
+ )
127
+ results.append(res)
128
+
129
+ if verbose:
130
+ print("\nAll planning completed successfully!")
131
+
132
+ all_plans = []
133
+ for res in results:
134
+ if hasattr(res, "instruct_models"):
135
+ for i in res.instruct_models:
136
+ if i and i not in all_plans:
137
+ all_plans.append(i)
138
+ out.plan = all_plans
139
+
140
+ if auto_execute:
141
+ if verbose:
142
+ print("\nStarting execution of all steps...")
143
+ results = []
144
+ match execution_strategy:
145
+ case "sequential":
146
+ for i, ins in enumerate(all_plans, 1):
147
+ if verbose:
148
+ print(
149
+ f"\n------ Executing step {i}/{len(all_plans)} ------"
150
+ )
151
+ msg = (
152
+ ins.instruction[:100] + "..."
153
+ if len(ins.instruction) > 100
154
+ else ins.instruction
155
+ )
156
+ print(f"Instruction: {msg}")
157
+ res = await execute_branch.instruct(
158
+ ins, **(execution_kwargs or {})
159
+ )
160
+ res_ = InstructResponse(instruct=ins, response=res)
161
+ results.append(res_)
162
+ out.execute = results
163
+ if verbose:
164
+ print("\nAll steps executed successfully!")
165
+ case _:
166
+ raise ValueError(
167
+ f"Invalid execution strategy: {execution_strategy}"
168
+ )
169
+
170
+ if return_session:
171
+ return out, session
172
+ return out
@@ -0,0 +1,21 @@
1
+ PLAN_PROMPT = """
2
+ Develop a high-level plan with {num_steps} distinct steps. Each step should:
3
+ 1. Represent a major milestone or phase
4
+ 2. Be logically sequenced for dependencies
5
+ 3. Be clearly distinct from other steps
6
+ 4. Have measurable completion criteria
7
+ 5. Be suitable for further decomposition
8
+ """
9
+
10
+ EXPANSION_PROMPT = """
11
+ Break down a high-level plan into detailed concrete executable actions. Each step should:
12
+ - Ensure actions are atomic and verifiable
13
+ - Include necessary context and preconditions
14
+ - Specify expected outcomes and validations
15
+ - Maintain sequential dependencies
16
+ - Be self-contained with clear scope
17
+ - Include all required context/parameters
18
+ - Have unambiguous success criteria
19
+ - Specify error handling approach
20
+ - Define expected outputs
21
+ """
@@ -0,0 +1,3 @@
1
+ from .select import select
2
+
3
+ __all__ = ["select"]
@@ -0,0 +1 @@
1
+ PROMPT = "Please select up to {max_num_selections} items from the following list {choices}. Provide the selection(s) into appropriate field in format required, and no comments from you"
@@ -0,0 +1,100 @@
1
+ # Copyright (c) 2023 - 2024, HaiyangLi <quantocean.li at gmail dot com>
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+
6
+ from enum import Enum
7
+ from typing import Any
8
+
9
+ from pydantic import BaseModel, Field
10
+
11
+ from lionagi import Branch
12
+ from lionagi.protocols.operatives.instruct import Instruct
13
+
14
+ from .prompt import PROMPT
15
+ from .utils import parse_selection, parse_to_representation
16
+
17
+
18
+ class SelectionModel(BaseModel):
19
+ """Model representing the selection output."""
20
+
21
+ selected: list[Any] = Field(default_factory=list)
22
+
23
+
24
+ async def select(
25
+ instruct: Instruct | dict[str, Any],
26
+ choices: list[str] | type[Enum] | dict[str, Any],
27
+ max_num_selections: int = 1,
28
+ branch: Branch | None = None,
29
+ branch_kwargs: dict[str, Any] | None = None,
30
+ return_branch: bool = False,
31
+ verbose: bool = False,
32
+ **kwargs: Any,
33
+ ) -> SelectionModel | tuple[SelectionModel, Branch]:
34
+ """Perform a selection operation from given choices.
35
+
36
+ Args:
37
+ instruct: Instruction model or dictionary.
38
+ choices: Options to select from.
39
+ max_num_selections: Maximum selections allowed.
40
+ branch: Existing branch or None to create a new one.
41
+ branch_kwargs: Additional arguments for branch creation.
42
+ return_branch: If True, return the branch with the selection.
43
+ verbose: Whether to enable verbose output.
44
+ **kwargs: Additional keyword arguments.
45
+
46
+ Returns:
47
+ A SelectionModel instance, optionally with the branch.
48
+ """
49
+ if verbose:
50
+ print(f"Starting selection with up to {max_num_selections} choices.")
51
+
52
+ branch = branch or Branch(**(branch_kwargs or {}))
53
+ selections, contents = parse_to_representation(choices)
54
+ prompt = PROMPT.format(
55
+ max_num_selections=max_num_selections, choices=selections
56
+ )
57
+
58
+ if isinstance(instruct, Instruct):
59
+ instruct = instruct.to_dict()
60
+
61
+ instruct = instruct or {}
62
+
63
+ if instruct.get("instruction", None) is not None:
64
+ instruct["instruction"] = (
65
+ f"{instruct['instruction']}\n\n{prompt} \n\n "
66
+ )
67
+ else:
68
+ instruct["instruction"] = prompt
69
+
70
+ context = instruct.get("context", None) or []
71
+ context = [context] if not isinstance(context, list) else context
72
+ context.extend([{k: v} for k, v in zip(selections, contents)])
73
+ instruct["context"] = context
74
+
75
+ response_model: SelectionModel = await branch.operate(
76
+ operative_model=SelectionModel,
77
+ **kwargs,
78
+ **instruct,
79
+ )
80
+ if verbose:
81
+ print(f"Received selection: {response_model.selected}")
82
+
83
+ selected = response_model
84
+ if isinstance(response_model, BaseModel) and hasattr(
85
+ response_model, "selected"
86
+ ):
87
+ selected = response_model.selected
88
+ selected = [selected] if not isinstance(selected, list) else selected
89
+
90
+ corrected_selections = [parse_selection(i, choices) for i in selected]
91
+
92
+ if isinstance(response_model, BaseModel):
93
+ response_model.selected = corrected_selections
94
+
95
+ elif isinstance(response_model, dict):
96
+ response_model["selected"] = corrected_selections
97
+
98
+ if return_branch:
99
+ return response_model, branch
100
+ return response_model
@@ -0,0 +1,107 @@
1
+ # Copyright (c) 2023 - 2024, HaiyangLi <quantocean.li at gmail dot com>
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+
6
+ import inspect
7
+ from enum import Enum
8
+ from typing import Any
9
+
10
+ from lionagi.core.typing import BaseModel, JsonValue
11
+ from lionagi.libs.parse import is_same_dtype
12
+ from lionagi.libs.string_similarity import string_similarity
13
+
14
+
15
+ def parse_to_representation(
16
+ choices: Enum | dict | list | tuple | set,
17
+ ) -> tuple[list[str], JsonValue]:
18
+ """
19
+ should use
20
+ 1. iterator of string | BaseModel
21
+ 2. dict[str, JsonValue | BaseModel]
22
+ 3. Enum[str, JsonValue | BaseModel]
23
+ """
24
+
25
+ if isinstance(choices, tuple | set | list):
26
+ choices = list(choices)
27
+ if is_same_dtype(choices, str):
28
+ return choices, choices
29
+
30
+ if isinstance(choices, list):
31
+ if is_same_dtype(choices, BaseModel):
32
+ choices = {i.__class__.__name__: i for i in choices}
33
+ if all(
34
+ inspect.isclass(i) and issubclass(i, BaseModel) for i in choices
35
+ ):
36
+ choices = {i.__name__: i for i in choices}
37
+ if isinstance(choices, type) and issubclass(choices, Enum):
38
+ keys = [i.name for i in choices]
39
+ contents = [get_choice_representation(i) for i in choices]
40
+ return keys, contents
41
+
42
+ if isinstance(choices, dict):
43
+ keys = list(choices.keys())
44
+ contents = list(choices.values())
45
+ contents = [get_choice_representation(v) for k, v in choices.items()]
46
+ return keys, contents
47
+
48
+ if isinstance(choices, tuple | set | list):
49
+ choices = list(choices)
50
+ if is_same_dtype(choices, str):
51
+ return choices, choices
52
+
53
+ raise NotImplementedError
54
+
55
+
56
+ def get_choice_representation(choice: Any) -> str:
57
+
58
+ if isinstance(choice, str):
59
+ return choice
60
+
61
+ if isinstance(choice, BaseModel):
62
+ return f"{choice.__class__.__name__}:\n{choice.model_json_schema(indent=2)}"
63
+
64
+ if isinstance(choice, Enum):
65
+ return get_choice_representation(choice.value)
66
+
67
+
68
+ def parse_selection(selection_str: str, choices: Any):
69
+
70
+ select_from = []
71
+
72
+ if isinstance(choices, dict):
73
+ select_from = list(choices.keys())
74
+
75
+ if inspect.isclass(choices) and issubclass(choices, Enum):
76
+ select_from = [choice.name for choice in choices]
77
+
78
+ if isinstance(choices, list | tuple | set):
79
+ if is_same_dtype(choices, BaseModel):
80
+ select_from = [i.__class__.__name__ for i in choices]
81
+ if is_same_dtype(choices, str):
82
+ select_from = list(choices)
83
+ if all(
84
+ inspect.isclass(i) and issubclass(i, BaseModel) for i in choices
85
+ ):
86
+ select_from = [i.__name__ for i in choices]
87
+
88
+ if not select_from:
89
+ raise ValueError("The values provided for choice is not valid")
90
+
91
+ selected = string_similarity(
92
+ selection_str, select_from, return_most_similar=True
93
+ )
94
+
95
+ if isinstance(choices, dict) and selected in choices:
96
+ return choices[selected]
97
+
98
+ if inspect.isclass(choices) and issubclass(choices, Enum):
99
+ for i in choices:
100
+ if i.name == selected:
101
+ return i
102
+
103
+ if isinstance(choices, list) and is_same_dtype(choices, str):
104
+ if selected in choices:
105
+ return selected
106
+
107
+ return selected
@@ -0,0 +1,35 @@
1
+ from lionagi.core.session.branch import Branch
2
+ from lionagi.core.session.session import Session
3
+ from lionagi.protocols.operatives.instruct import Instruct
4
+
5
+
6
+ def prepare_session(
7
+ session=None, branch=None, branch_kwargs=None
8
+ ) -> tuple[Session, Branch]:
9
+ if session is not None:
10
+ if branch is not None:
11
+ branch: Branch = session.branches[branch]
12
+ else:
13
+ branch = session.new_branch(**(branch_kwargs or {}))
14
+ else:
15
+ session = Session()
16
+ if isinstance(branch, Branch):
17
+ session.branches.include(branch)
18
+ session.default_branch = branch
19
+ if branch is None:
20
+ branch = session.new_branch(**(branch_kwargs or {}))
21
+
22
+ return session, branch
23
+
24
+
25
+ def prepare_instruct(instruct: Instruct | dict, prompt: str):
26
+ if isinstance(instruct, Instruct):
27
+ instruct = instruct.to_dict()
28
+ if not isinstance(instruct, dict):
29
+ raise ValueError(
30
+ "instruct needs to be an InstructModel object or a dictionary of valid parameters"
31
+ )
32
+
33
+ guidance = instruct.get("guidance", "")
34
+ instruct["guidance"] = f"\n{prompt}\n{guidance}"
35
+ return instruct