lionagi 0.5.5__py3-none-any.whl → 0.6.0__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
Files changed (428) hide show
  1. lionagi/__init__.py +16 -24
  2. lionagi/{core/_class_registry.py → _class_registry.py} +51 -10
  3. lionagi/_errors.py +35 -0
  4. lionagi/libs/__init__.py +3 -0
  5. lionagi/libs/compress/__init__.py +3 -0
  6. lionagi/libs/compress/models.py +6 -2
  7. lionagi/libs/compress/utils.py +4 -16
  8. lionagi/libs/file/__init__.py +3 -0
  9. lionagi/libs/file/chunk.py +4 -0
  10. lionagi/libs/file/file_ops.py +4 -0
  11. lionagi/libs/file/params.py +4 -41
  12. lionagi/libs/file/process.py +4 -0
  13. lionagi/libs/file/save.py +5 -1
  14. lionagi/libs/{parse/flatten → nested}/flatten.py +4 -0
  15. lionagi/libs/{parse/nested → nested}/nfilter.py +4 -0
  16. lionagi/libs/{parse/nested → nested}/nget.py +6 -1
  17. lionagi/libs/{parse/nested → nested}/ninsert.py +5 -1
  18. lionagi/libs/{parse/nested → nested}/nmerge.py +4 -0
  19. lionagi/libs/{parse/nested → nested}/npop.py +5 -2
  20. lionagi/libs/{parse/nested → nested}/nset.py +6 -1
  21. lionagi/libs/{parse/flatten → nested}/unflatten.py +4 -0
  22. lionagi/libs/{parse/nested → nested}/utils.py +5 -1
  23. lionagi/libs/package/__init__.py +3 -0
  24. lionagi/libs/package/imports.py +6 -2
  25. lionagi/libs/package/management.py +7 -3
  26. lionagi/libs/package/params.py +4 -0
  27. lionagi/libs/package/system.py +4 -0
  28. lionagi/libs/parse.py +30 -0
  29. lionagi/libs/{parse/json → schema}/as_readable.py +10 -4
  30. lionagi/libs/{parse/string_parse/code_block.py → schema/extract_code_block.py} +4 -0
  31. lionagi/libs/{parse/string_parse/docstring.py → schema/extract_docstring.py} +4 -0
  32. lionagi/libs/{parse/string_parse/function_.py → schema/function_to_schema.py} +21 -9
  33. lionagi/libs/{parse/json/schema.py → schema/json_schema.py} +5 -1
  34. lionagi/libs/validate/common_field_validators.py +170 -0
  35. lionagi/libs/{parse/validate/keys.py → validate/fuzzy_match_keys.py} +42 -8
  36. lionagi/libs/{parse/validate/mapping.py → validate/fuzzy_validate_mapping.py} +41 -6
  37. lionagi/libs/{string_similarity/algorithms.py → validate/string_similarity.py} +115 -1
  38. lionagi/libs/{parse/validate/boolean.py → validate/validate_boolean.py} +42 -3
  39. lionagi/operations/__init__.py +13 -3
  40. lionagi/operations/brainstorm/__init__.py +3 -3
  41. lionagi/operations/brainstorm/brainstorm.py +33 -19
  42. lionagi/operations/brainstorm/prompt.py +4 -0
  43. lionagi/operations/plan/__init__.py +4 -0
  44. lionagi/operations/plan/plan.py +16 -13
  45. lionagi/operations/plan/prompt.py +4 -0
  46. lionagi/operations/select/__init__.py +4 -0
  47. lionagi/operations/select/prompt.py +4 -0
  48. lionagi/operations/select/select.py +1 -1
  49. lionagi/operations/select/utils.py +4 -4
  50. lionagi/{strategies → operations/strategies}/base.py +6 -2
  51. lionagi/{strategies → operations/strategies}/concurrent.py +8 -5
  52. lionagi/{strategies → operations/strategies}/concurrent_chunk.py +6 -3
  53. lionagi/{strategies → operations/strategies}/concurrent_sequential_chunk.py +8 -4
  54. lionagi/{strategies → operations/strategies}/params.py +10 -6
  55. lionagi/{strategies → operations/strategies}/sequential.py +6 -2
  56. lionagi/{strategies → operations/strategies}/sequential_chunk.py +7 -3
  57. lionagi/{strategies → operations/strategies}/sequential_concurrent_chunk.py +9 -4
  58. lionagi/{strategies → operations/strategies}/utils.py +6 -3
  59. lionagi/{core/models/__init__.py → operations/types.py} +3 -1
  60. lionagi/operations/utils.py +6 -3
  61. lionagi/operatives/action/function_calling.py +136 -0
  62. lionagi/operatives/action/manager.py +239 -0
  63. lionagi/operatives/action/request_response_model.py +90 -0
  64. lionagi/operatives/action/tool.py +141 -0
  65. lionagi/{protocols/operatives/action.py → operatives/action/utils.py} +52 -90
  66. lionagi/{core → operatives}/forms/base.py +9 -4
  67. lionagi/{core → operatives}/forms/form.py +8 -13
  68. lionagi/{core → operatives}/forms/report.py +5 -3
  69. lionagi/operatives/instruct/base.py +79 -0
  70. lionagi/operatives/instruct/instruct.py +105 -0
  71. lionagi/operatives/instruct/instruct_collection.py +52 -0
  72. lionagi/operatives/instruct/node.py +13 -0
  73. lionagi/{protocols/operatives → operatives/instruct}/prompts.py +0 -34
  74. lionagi/{protocols/operatives → operatives/instruct}/reason.py +14 -7
  75. lionagi/{integrations/anthropic_/version.py → operatives/manager.py} +5 -1
  76. lionagi/operatives/models/field_model.py +194 -0
  77. lionagi/operatives/models/model_params.py +307 -0
  78. lionagi/{core → operatives}/models/note.py +20 -28
  79. lionagi/{core → operatives}/models/operable_model.py +153 -71
  80. lionagi/{core → operatives}/models/schema_model.py +4 -3
  81. lionagi/{protocols/operatives → operatives}/operative.py +10 -7
  82. lionagi/{protocols/operatives → operatives}/step.py +67 -26
  83. lionagi/operatives/types.py +69 -0
  84. lionagi/protocols/_adapter.py +224 -0
  85. lionagi/protocols/_concepts.py +94 -0
  86. lionagi/protocols/generic/element.py +460 -0
  87. lionagi/protocols/generic/event.py +177 -0
  88. lionagi/protocols/generic/log.py +237 -0
  89. lionagi/{core → protocols}/generic/pile.py +172 -131
  90. lionagi/protocols/generic/processor.py +316 -0
  91. lionagi/protocols/generic/progression.py +500 -0
  92. lionagi/protocols/graph/edge.py +166 -0
  93. lionagi/protocols/graph/graph.py +290 -0
  94. lionagi/protocols/graph/node.py +109 -0
  95. lionagi/protocols/mail/exchange.py +116 -0
  96. lionagi/protocols/mail/mail.py +25 -0
  97. lionagi/protocols/mail/mailbox.py +47 -0
  98. lionagi/protocols/mail/manager.py +168 -0
  99. lionagi/protocols/mail/package.py +55 -0
  100. lionagi/protocols/messages/action_request.py +165 -0
  101. lionagi/protocols/messages/action_response.py +132 -0
  102. lionagi/{core/communication → protocols/messages}/assistant_response.py +55 -79
  103. lionagi/protocols/messages/base.py +73 -0
  104. lionagi/protocols/messages/instruction.py +582 -0
  105. lionagi/protocols/messages/manager.py +429 -0
  106. lionagi/protocols/messages/message.py +216 -0
  107. lionagi/protocols/messages/system.py +115 -0
  108. lionagi/protocols/messages/templates/assistant_response.jinja2 +6 -0
  109. lionagi/{core/communication → protocols/messages}/templates/instruction_message.jinja2 +2 -2
  110. lionagi/protocols/types.py +96 -0
  111. lionagi/service/__init__.py +10 -12
  112. lionagi/service/endpoints/base.py +517 -0
  113. lionagi/service/endpoints/chat_completion.py +102 -0
  114. lionagi/service/endpoints/match_endpoint.py +60 -0
  115. lionagi/service/endpoints/rate_limited_processor.py +145 -0
  116. lionagi/service/endpoints/token_calculator.py +209 -0
  117. lionagi/service/imodel.py +263 -96
  118. lionagi/service/manager.py +45 -0
  119. lionagi/service/providers/anthropic_/messages.py +64 -0
  120. lionagi/service/providers/groq_/chat_completions.py +56 -0
  121. lionagi/service/providers/openai_/chat_completions.py +62 -0
  122. lionagi/service/providers/openrouter_/chat_completions.py +62 -0
  123. lionagi/service/providers/perplexity_/__init__.py +3 -0
  124. lionagi/service/providers/perplexity_/chat_completions.py +40 -0
  125. lionagi/session/__init__.py +3 -0
  126. lionagi/session/branch.py +1287 -0
  127. lionagi/session/session.py +296 -0
  128. lionagi/settings.py +62 -118
  129. lionagi/utils.py +2386 -0
  130. lionagi/version.py +1 -1
  131. {lionagi-0.5.5.dist-info → lionagi-0.6.0.dist-info}/METADATA +7 -6
  132. lionagi-0.6.0.dist-info/RECORD +160 -0
  133. lionagi/core/action/action_manager.py +0 -289
  134. lionagi/core/action/base.py +0 -109
  135. lionagi/core/action/function_calling.py +0 -153
  136. lionagi/core/action/tool.py +0 -202
  137. lionagi/core/action/types.py +0 -16
  138. lionagi/core/communication/action_request.py +0 -163
  139. lionagi/core/communication/action_response.py +0 -149
  140. lionagi/core/communication/base_mail.py +0 -49
  141. lionagi/core/communication/instruction.py +0 -376
  142. lionagi/core/communication/message.py +0 -286
  143. lionagi/core/communication/message_manager.py +0 -543
  144. lionagi/core/communication/system.py +0 -116
  145. lionagi/core/communication/templates/assistant_response.jinja2 +0 -2
  146. lionagi/core/communication/types.py +0 -27
  147. lionagi/core/communication/utils.py +0 -256
  148. lionagi/core/forms/types.py +0 -13
  149. lionagi/core/generic/component.py +0 -422
  150. lionagi/core/generic/edge.py +0 -163
  151. lionagi/core/generic/element.py +0 -199
  152. lionagi/core/generic/graph.py +0 -377
  153. lionagi/core/generic/log.py +0 -151
  154. lionagi/core/generic/log_manager.py +0 -320
  155. lionagi/core/generic/node.py +0 -11
  156. lionagi/core/generic/progression.py +0 -395
  157. lionagi/core/generic/types.py +0 -23
  158. lionagi/core/generic/utils.py +0 -53
  159. lionagi/core/models/base.py +0 -28
  160. lionagi/core/models/field_model.py +0 -145
  161. lionagi/core/models/model_params.py +0 -194
  162. lionagi/core/models/types.py +0 -19
  163. lionagi/core/session/branch.py +0 -130
  164. lionagi/core/session/branch_mixins.py +0 -581
  165. lionagi/core/session/session.py +0 -163
  166. lionagi/core/session/types.py +0 -8
  167. lionagi/core/typing/__init__.py +0 -9
  168. lionagi/core/typing/_concepts.py +0 -173
  169. lionagi/core/typing/_id.py +0 -104
  170. lionagi/core/typing/_pydantic.py +0 -33
  171. lionagi/core/typing/_typing.py +0 -54
  172. lionagi/integrations/__init__.py +0 -0
  173. lionagi/integrations/_services.py +0 -17
  174. lionagi/integrations/anthropic_/AnthropicModel.py +0 -268
  175. lionagi/integrations/anthropic_/AnthropicService.py +0 -127
  176. lionagi/integrations/anthropic_/anthropic_max_output_token_data.yaml +0 -12
  177. lionagi/integrations/anthropic_/anthropic_price_data.yaml +0 -34
  178. lionagi/integrations/anthropic_/api_endpoints/api_request.py +0 -277
  179. lionagi/integrations/anthropic_/api_endpoints/data_models.py +0 -40
  180. lionagi/integrations/anthropic_/api_endpoints/match_response.py +0 -119
  181. lionagi/integrations/anthropic_/api_endpoints/messages/request/message_models.py +0 -14
  182. lionagi/integrations/anthropic_/api_endpoints/messages/request/request_body.py +0 -74
  183. lionagi/integrations/anthropic_/api_endpoints/messages/response/__init__.py +0 -0
  184. lionagi/integrations/anthropic_/api_endpoints/messages/response/content_models.py +0 -32
  185. lionagi/integrations/anthropic_/api_endpoints/messages/response/response_body.py +0 -101
  186. lionagi/integrations/anthropic_/api_endpoints/messages/response/usage_models.py +0 -25
  187. lionagi/integrations/groq_/GroqModel.py +0 -325
  188. lionagi/integrations/groq_/GroqService.py +0 -156
  189. lionagi/integrations/groq_/api_endpoints/__init__.py +0 -0
  190. lionagi/integrations/groq_/api_endpoints/data_models.py +0 -187
  191. lionagi/integrations/groq_/api_endpoints/groq_request.py +0 -288
  192. lionagi/integrations/groq_/api_endpoints/match_response.py +0 -106
  193. lionagi/integrations/groq_/api_endpoints/response_utils.py +0 -105
  194. lionagi/integrations/groq_/groq_max_output_token_data.yaml +0 -21
  195. lionagi/integrations/groq_/groq_price_data.yaml +0 -58
  196. lionagi/integrations/groq_/groq_rate_limits.yaml +0 -105
  197. lionagi/integrations/groq_/version.py +0 -5
  198. lionagi/integrations/litellm_/imodel.py +0 -76
  199. lionagi/integrations/ollama_/OllamaModel.py +0 -244
  200. lionagi/integrations/ollama_/OllamaService.py +0 -142
  201. lionagi/integrations/ollama_/api_endpoints/api_request.py +0 -179
  202. lionagi/integrations/ollama_/api_endpoints/chat_completion/message_models.py +0 -31
  203. lionagi/integrations/ollama_/api_endpoints/chat_completion/request_body.py +0 -46
  204. lionagi/integrations/ollama_/api_endpoints/chat_completion/response_body.py +0 -67
  205. lionagi/integrations/ollama_/api_endpoints/chat_completion/tool_models.py +0 -49
  206. lionagi/integrations/ollama_/api_endpoints/completion/__init__.py +0 -0
  207. lionagi/integrations/ollama_/api_endpoints/completion/request_body.py +0 -72
  208. lionagi/integrations/ollama_/api_endpoints/completion/response_body.py +0 -59
  209. lionagi/integrations/ollama_/api_endpoints/data_models.py +0 -15
  210. lionagi/integrations/ollama_/api_endpoints/embedding/__init__.py +0 -0
  211. lionagi/integrations/ollama_/api_endpoints/embedding/request_body.py +0 -33
  212. lionagi/integrations/ollama_/api_endpoints/embedding/response_body.py +0 -29
  213. lionagi/integrations/ollama_/api_endpoints/match_data_model.py +0 -62
  214. lionagi/integrations/ollama_/api_endpoints/match_response.py +0 -190
  215. lionagi/integrations/ollama_/api_endpoints/model/copy_model.py +0 -13
  216. lionagi/integrations/ollama_/api_endpoints/model/create_model.py +0 -28
  217. lionagi/integrations/ollama_/api_endpoints/model/delete_model.py +0 -11
  218. lionagi/integrations/ollama_/api_endpoints/model/list_model.py +0 -60
  219. lionagi/integrations/ollama_/api_endpoints/model/pull_model.py +0 -34
  220. lionagi/integrations/ollama_/api_endpoints/model/push_model.py +0 -35
  221. lionagi/integrations/ollama_/api_endpoints/model/show_model.py +0 -36
  222. lionagi/integrations/ollama_/api_endpoints/option_models.py +0 -68
  223. lionagi/integrations/openai_/OpenAIModel.py +0 -419
  224. lionagi/integrations/openai_/OpenAIService.py +0 -435
  225. lionagi/integrations/openai_/__init__.py +0 -0
  226. lionagi/integrations/openai_/api_endpoints/__init__.py +0 -3
  227. lionagi/integrations/openai_/api_endpoints/api_request.py +0 -277
  228. lionagi/integrations/openai_/api_endpoints/audio/__init__.py +0 -9
  229. lionagi/integrations/openai_/api_endpoints/audio/speech_models.py +0 -34
  230. lionagi/integrations/openai_/api_endpoints/audio/transcription_models.py +0 -136
  231. lionagi/integrations/openai_/api_endpoints/audio/translation_models.py +0 -41
  232. lionagi/integrations/openai_/api_endpoints/audio/types.py +0 -41
  233. lionagi/integrations/openai_/api_endpoints/batch/__init__.py +0 -17
  234. lionagi/integrations/openai_/api_endpoints/batch/batch_models.py +0 -146
  235. lionagi/integrations/openai_/api_endpoints/batch/cancel_batch.py +0 -7
  236. lionagi/integrations/openai_/api_endpoints/batch/create_batch.py +0 -26
  237. lionagi/integrations/openai_/api_endpoints/batch/list_batch.py +0 -37
  238. lionagi/integrations/openai_/api_endpoints/batch/request_object_models.py +0 -65
  239. lionagi/integrations/openai_/api_endpoints/batch/retrieve_batch.py +0 -7
  240. lionagi/integrations/openai_/api_endpoints/batch/types.py +0 -4
  241. lionagi/integrations/openai_/api_endpoints/chat_completions/__init__.py +0 -1
  242. lionagi/integrations/openai_/api_endpoints/chat_completions/request/__init__.py +0 -39
  243. lionagi/integrations/openai_/api_endpoints/chat_completions/request/message_models.py +0 -121
  244. lionagi/integrations/openai_/api_endpoints/chat_completions/request/request_body.py +0 -221
  245. lionagi/integrations/openai_/api_endpoints/chat_completions/request/response_format.py +0 -71
  246. lionagi/integrations/openai_/api_endpoints/chat_completions/request/stream_options.py +0 -14
  247. lionagi/integrations/openai_/api_endpoints/chat_completions/request/tool_choice_models.py +0 -17
  248. lionagi/integrations/openai_/api_endpoints/chat_completions/request/tool_models.py +0 -54
  249. lionagi/integrations/openai_/api_endpoints/chat_completions/request/types.py +0 -18
  250. lionagi/integrations/openai_/api_endpoints/chat_completions/response/__init__.py +0 -0
  251. lionagi/integrations/openai_/api_endpoints/chat_completions/response/choice_models.py +0 -62
  252. lionagi/integrations/openai_/api_endpoints/chat_completions/response/function_models.py +0 -16
  253. lionagi/integrations/openai_/api_endpoints/chat_completions/response/log_prob_models.py +0 -47
  254. lionagi/integrations/openai_/api_endpoints/chat_completions/response/message_models.py +0 -25
  255. lionagi/integrations/openai_/api_endpoints/chat_completions/response/response_body.py +0 -99
  256. lionagi/integrations/openai_/api_endpoints/chat_completions/response/types.py +0 -8
  257. lionagi/integrations/openai_/api_endpoints/chat_completions/response/usage_models.py +0 -24
  258. lionagi/integrations/openai_/api_endpoints/chat_completions/util.py +0 -46
  259. lionagi/integrations/openai_/api_endpoints/data_models.py +0 -23
  260. lionagi/integrations/openai_/api_endpoints/embeddings/__init__.py +0 -3
  261. lionagi/integrations/openai_/api_endpoints/embeddings/request_body.py +0 -79
  262. lionagi/integrations/openai_/api_endpoints/embeddings/response_body.py +0 -67
  263. lionagi/integrations/openai_/api_endpoints/files/__init__.py +0 -11
  264. lionagi/integrations/openai_/api_endpoints/files/delete_file.py +0 -20
  265. lionagi/integrations/openai_/api_endpoints/files/file_models.py +0 -56
  266. lionagi/integrations/openai_/api_endpoints/files/list_files.py +0 -27
  267. lionagi/integrations/openai_/api_endpoints/files/retrieve_file.py +0 -9
  268. lionagi/integrations/openai_/api_endpoints/files/upload_file.py +0 -38
  269. lionagi/integrations/openai_/api_endpoints/fine_tuning/__init__.py +0 -37
  270. lionagi/integrations/openai_/api_endpoints/fine_tuning/cancel_jobs.py +0 -9
  271. lionagi/integrations/openai_/api_endpoints/fine_tuning/create_jobs.py +0 -133
  272. lionagi/integrations/openai_/api_endpoints/fine_tuning/fine_tuning_job_checkpoint_models.py +0 -58
  273. lionagi/integrations/openai_/api_endpoints/fine_tuning/fine_tuning_job_event_models.py +0 -31
  274. lionagi/integrations/openai_/api_endpoints/fine_tuning/fine_tuning_job_models.py +0 -140
  275. lionagi/integrations/openai_/api_endpoints/fine_tuning/list_fine_tuning_checkpoints.py +0 -51
  276. lionagi/integrations/openai_/api_endpoints/fine_tuning/list_fine_tuning_events.py +0 -42
  277. lionagi/integrations/openai_/api_endpoints/fine_tuning/list_fine_tuning_jobs.py +0 -31
  278. lionagi/integrations/openai_/api_endpoints/fine_tuning/retrieve_jobs.py +0 -9
  279. lionagi/integrations/openai_/api_endpoints/fine_tuning/training_format.py +0 -30
  280. lionagi/integrations/openai_/api_endpoints/images/__init__.py +0 -9
  281. lionagi/integrations/openai_/api_endpoints/images/image_edit_models.py +0 -69
  282. lionagi/integrations/openai_/api_endpoints/images/image_models.py +0 -56
  283. lionagi/integrations/openai_/api_endpoints/images/image_variation_models.py +0 -56
  284. lionagi/integrations/openai_/api_endpoints/images/response_body.py +0 -30
  285. lionagi/integrations/openai_/api_endpoints/match_data_model.py +0 -197
  286. lionagi/integrations/openai_/api_endpoints/match_response.py +0 -336
  287. lionagi/integrations/openai_/api_endpoints/models/__init__.py +0 -7
  288. lionagi/integrations/openai_/api_endpoints/models/delete_fine_tuned_model.py +0 -17
  289. lionagi/integrations/openai_/api_endpoints/models/models_models.py +0 -31
  290. lionagi/integrations/openai_/api_endpoints/models/retrieve_model.py +0 -9
  291. lionagi/integrations/openai_/api_endpoints/moderations/__init__.py +0 -3
  292. lionagi/integrations/openai_/api_endpoints/moderations/request_body.py +0 -20
  293. lionagi/integrations/openai_/api_endpoints/moderations/response_body.py +0 -139
  294. lionagi/integrations/openai_/api_endpoints/uploads/__init__.py +0 -19
  295. lionagi/integrations/openai_/api_endpoints/uploads/add_upload_part.py +0 -11
  296. lionagi/integrations/openai_/api_endpoints/uploads/cancel_upload.py +0 -7
  297. lionagi/integrations/openai_/api_endpoints/uploads/complete_upload.py +0 -18
  298. lionagi/integrations/openai_/api_endpoints/uploads/create_upload.py +0 -17
  299. lionagi/integrations/openai_/api_endpoints/uploads/uploads_models.py +0 -52
  300. lionagi/integrations/openai_/image_token_calculator/__init__.py +0 -0
  301. lionagi/integrations/openai_/image_token_calculator/image_token_calculator.py +0 -98
  302. lionagi/integrations/openai_/image_token_calculator/openai_image_token_data.yaml +0 -15
  303. lionagi/integrations/openai_/openai_max_output_token_data.yaml +0 -12
  304. lionagi/integrations/openai_/openai_price_data.yaml +0 -26
  305. lionagi/integrations/openai_/version.py +0 -1
  306. lionagi/integrations/pandas_/__init__.py +0 -24
  307. lionagi/integrations/pandas_/extend_df.py +0 -61
  308. lionagi/integrations/pandas_/read.py +0 -103
  309. lionagi/integrations/pandas_/remove_rows.py +0 -61
  310. lionagi/integrations/pandas_/replace_keywords.py +0 -65
  311. lionagi/integrations/pandas_/save.py +0 -131
  312. lionagi/integrations/pandas_/search_keywords.py +0 -69
  313. lionagi/integrations/pandas_/to_df.py +0 -196
  314. lionagi/integrations/pandas_/update_cells.py +0 -54
  315. lionagi/integrations/perplexity_/PerplexityModel.py +0 -274
  316. lionagi/integrations/perplexity_/PerplexityService.py +0 -118
  317. lionagi/integrations/perplexity_/api_endpoints/__init__.py +0 -0
  318. lionagi/integrations/perplexity_/api_endpoints/api_request.py +0 -171
  319. lionagi/integrations/perplexity_/api_endpoints/chat_completions/__init__.py +0 -0
  320. lionagi/integrations/perplexity_/api_endpoints/chat_completions/request/__init__.py +0 -0
  321. lionagi/integrations/perplexity_/api_endpoints/chat_completions/request/request_body.py +0 -121
  322. lionagi/integrations/perplexity_/api_endpoints/chat_completions/response/__init__.py +0 -0
  323. lionagi/integrations/perplexity_/api_endpoints/chat_completions/response/response_body.py +0 -146
  324. lionagi/integrations/perplexity_/api_endpoints/data_models.py +0 -63
  325. lionagi/integrations/perplexity_/api_endpoints/match_response.py +0 -26
  326. lionagi/integrations/perplexity_/perplexity_max_output_token_data.yaml +0 -3
  327. lionagi/integrations/perplexity_/perplexity_price_data.yaml +0 -10
  328. lionagi/integrations/perplexity_/version.py +0 -1
  329. lionagi/integrations/pydantic_/__init__.py +0 -8
  330. lionagi/integrations/pydantic_/break_down_annotation.py +0 -81
  331. lionagi/integrations/pydantic_/new_model.py +0 -208
  332. lionagi/libs/constants.py +0 -98
  333. lionagi/libs/file/path.py +0 -301
  334. lionagi/libs/file/types.py +0 -22
  335. lionagi/libs/func/__init__.py +0 -0
  336. lionagi/libs/func/async_calls/__init__.py +0 -24
  337. lionagi/libs/func/async_calls/alcall.py +0 -210
  338. lionagi/libs/func/async_calls/bcall.py +0 -130
  339. lionagi/libs/func/async_calls/mcall.py +0 -134
  340. lionagi/libs/func/async_calls/pcall.py +0 -149
  341. lionagi/libs/func/async_calls/rcall.py +0 -217
  342. lionagi/libs/func/async_calls/tcall.py +0 -114
  343. lionagi/libs/func/async_calls/ucall.py +0 -85
  344. lionagi/libs/func/decorators.py +0 -277
  345. lionagi/libs/func/lcall.py +0 -57
  346. lionagi/libs/func/params.py +0 -64
  347. lionagi/libs/func/throttle.py +0 -119
  348. lionagi/libs/func/types.py +0 -39
  349. lionagi/libs/func/utils.py +0 -96
  350. lionagi/libs/package/types.py +0 -26
  351. lionagi/libs/parse/__init__.py +0 -1
  352. lionagi/libs/parse/flatten/__init__.py +0 -9
  353. lionagi/libs/parse/flatten/params.py +0 -52
  354. lionagi/libs/parse/json/__init__.py +0 -27
  355. lionagi/libs/parse/json/extract.py +0 -102
  356. lionagi/libs/parse/json/parse.py +0 -179
  357. lionagi/libs/parse/json/to_json.py +0 -71
  358. lionagi/libs/parse/nested/__init__.py +0 -33
  359. lionagi/libs/parse/nested/to_flat_list.py +0 -64
  360. lionagi/libs/parse/params.py +0 -0
  361. lionagi/libs/parse/string_parse/__init__.py +0 -11
  362. lionagi/libs/parse/type_convert/__init__.py +0 -19
  363. lionagi/libs/parse/type_convert/params.py +0 -145
  364. lionagi/libs/parse/type_convert/to_dict.py +0 -333
  365. lionagi/libs/parse/type_convert/to_list.py +0 -186
  366. lionagi/libs/parse/type_convert/to_num.py +0 -358
  367. lionagi/libs/parse/type_convert/to_str.py +0 -195
  368. lionagi/libs/parse/types.py +0 -9
  369. lionagi/libs/parse/validate/__init__.py +0 -14
  370. lionagi/libs/parse/validate/params.py +0 -62
  371. lionagi/libs/parse/xml/__init__.py +0 -10
  372. lionagi/libs/parse/xml/convert.py +0 -56
  373. lionagi/libs/parse/xml/parser.py +0 -93
  374. lionagi/libs/string_similarity/__init__.py +0 -32
  375. lionagi/libs/string_similarity/matcher.py +0 -102
  376. lionagi/libs/string_similarity/utils.py +0 -15
  377. lionagi/libs/utils.py +0 -266
  378. lionagi/protocols/adapters/__init__.py +0 -0
  379. lionagi/protocols/adapters/adapter.py +0 -79
  380. lionagi/protocols/adapters/json_adapter.py +0 -43
  381. lionagi/protocols/adapters/pandas_adapter.py +0 -96
  382. lionagi/protocols/configs/__init__.py +0 -0
  383. lionagi/protocols/configs/branch_config.py +0 -86
  384. lionagi/protocols/configs/id_config.py +0 -15
  385. lionagi/protocols/configs/imodel_config.py +0 -73
  386. lionagi/protocols/configs/log_config.py +0 -93
  387. lionagi/protocols/configs/retry_config.py +0 -29
  388. lionagi/protocols/configs/types.py +0 -15
  389. lionagi/protocols/operatives/instruct.py +0 -194
  390. lionagi/protocols/operatives/types.py +0 -19
  391. lionagi/protocols/registries/_component_registry.py +0 -23
  392. lionagi/protocols/registries/_pile_registry.py +0 -30
  393. lionagi/service/complete_request_info.py +0 -11
  394. lionagi/service/rate_limiter.py +0 -108
  395. lionagi/service/service.py +0 -41
  396. lionagi/service/service_match_util.py +0 -131
  397. lionagi/service/service_util.py +0 -72
  398. lionagi/service/token_calculator.py +0 -51
  399. lionagi/strategies/__init__.py +0 -0
  400. lionagi/strategies/types.py +0 -21
  401. lionagi-0.5.5.dist-info/RECORD +0 -374
  402. /lionagi/{core → libs/nested}/__init__.py +0 -0
  403. /lionagi/{core/action → libs/schema}/__init__.py +0 -0
  404. /lionagi/{core/communication → libs/validate}/__init__.py +0 -0
  405. /lionagi/{core/forms → operations/strategies}/__init__.py +0 -0
  406. /lionagi/{core/generic → operatives}/__init__.py +0 -0
  407. /lionagi/{core/session → operatives/action}/__init__.py +0 -0
  408. /lionagi/{integrations/anthropic_ → operatives/forms}/__init__.py +0 -0
  409. /lionagi/{core → operatives}/forms/utils.py +0 -0
  410. /lionagi/{integrations/anthropic_/api_endpoints → operatives/instruct}/__init__.py +0 -0
  411. /lionagi/{integrations/anthropic_/api_endpoints/messages → operatives/models}/__init__.py +0 -0
  412. /lionagi/{integrations/anthropic_/api_endpoints/messages/request → protocols/generic}/__init__.py +0 -0
  413. /lionagi/{integrations/groq_ → protocols/graph}/__init__.py +0 -0
  414. /lionagi/{integrations/litellm_ → protocols/mail}/__init__.py +0 -0
  415. /lionagi/{integrations/ollama_ → protocols/messages}/__init__.py +0 -0
  416. /lionagi/{core/communication → protocols/messages}/templates/README.md +0 -0
  417. /lionagi/{core/communication → protocols/messages}/templates/action_request.jinja2 +0 -0
  418. /lionagi/{core/communication → protocols/messages}/templates/action_response.jinja2 +0 -0
  419. /lionagi/{core/communication → protocols/messages}/templates/system_message.jinja2 +0 -0
  420. /lionagi/{core/communication → protocols/messages}/templates/tool_schemas.jinja2 +0 -0
  421. /lionagi/{integrations/ollama_/api_endpoints → service/endpoints}/__init__.py +0 -0
  422. /lionagi/{integrations/ollama_/api_endpoints/chat_completion → service/providers}/__init__.py +0 -0
  423. /lionagi/{integrations/ollama_/api_endpoints/model → service/providers/anthropic_}/__init__.py +0 -0
  424. /lionagi/{integrations/perplexity_ → service/providers/groq_}/__init__.py +0 -0
  425. /lionagi/{protocols/operatives → service/providers/openai_}/__init__.py +0 -0
  426. /lionagi/{protocols/registries → service/providers/openrouter_}/__init__.py +0 -0
  427. {lionagi-0.5.5.dist-info → lionagi-0.6.0.dist-info}/WHEEL +0 -0
  428. {lionagi-0.5.5.dist-info → lionagi-0.6.0.dist-info}/licenses/LICENSE +0 -0
@@ -2,49 +2,49 @@
2
2
  #
3
3
  # SPDX-License-Identifier: Apache-2.0
4
4
 
5
+ from __future__ import annotations
6
+
5
7
  import asyncio
8
+ import json
6
9
  import threading
7
- from collections.abc import AsyncIterator, Callable, Iterator, Sequence
10
+ from collections import deque
11
+ from collections.abc import (
12
+ AsyncIterator,
13
+ Callable,
14
+ Generator,
15
+ Iterator,
16
+ Sequence,
17
+ )
8
18
  from functools import wraps
9
19
  from pathlib import Path
20
+ from typing import Any, ClassVar, Generic, Self, TypeVar
10
21
 
11
22
  import pandas as pd
23
+ from pydantic import Field, field_serializer
24
+ from pydantic.fields import FieldInfo
12
25
  from typing_extensions import override
13
26
 
14
- from lionagi.core.typing import (
15
- ID,
16
- UNDEFINED,
17
- Any,
18
- ClassVar,
19
- Field,
20
- FieldInfo,
21
- Generic,
22
- ItemExistsError,
23
- ItemNotFoundError,
24
- Observable,
25
- Self,
26
- TypeVar,
27
- field_serializer,
28
- )
29
- from lionagi.core.typing._concepts import IDType
30
- from lionagi.libs.parse import is_same_dtype, to_list
31
- from lionagi.protocols.adapters.adapter import Adapter, AdapterRegistry
32
- from lionagi.protocols.registries._pile_registry import PileAdapterRegistry
27
+ from lionagi._errors import ItemExistsError, ItemNotFoundError
28
+ from lionagi.utils import UNDEFINED, is_same_dtype, to_list
33
29
 
34
- from .element import Element
30
+ from .._adapter import Adapter, AdapterRegistry, PileAdapterRegistry
31
+ from .._concepts import Observable
32
+ from .element import ID, Collective, E, Element, IDType, validate_order
35
33
  from .progression import Progression
36
- from .utils import to_list_type, validate_order
37
34
 
38
- T = TypeVar("T", bound=Element)
39
35
  D = TypeVar("D")
36
+ T = TypeVar("T", bound=E)
40
37
 
41
38
 
42
- __all__ = ("Pile", "pile")
39
+ __all__ = (
40
+ "Pile",
41
+ "pile",
42
+ )
43
43
 
44
44
 
45
45
  def synchronized(func: Callable):
46
46
  @wraps(func)
47
- def wrapper(self: "Pile", *args, **kwargs):
47
+ def wrapper(self: Pile, *args, **kwargs):
48
48
  with self.lock:
49
49
  return func(self, *args, **kwargs)
50
50
 
@@ -53,14 +53,14 @@ def synchronized(func: Callable):
53
53
 
54
54
  def async_synchronized(func: Callable):
55
55
  @wraps(func)
56
- async def wrapper(self: "Pile", *args, **kwargs):
56
+ async def wrapper(self: Pile, *args, **kwargs):
57
57
  async with self.async_lock:
58
58
  return await func(self, *args, **kwargs)
59
59
 
60
60
  return wrapper
61
61
 
62
62
 
63
- class Pile(Element, Generic[T]):
63
+ class Pile(Element, Collective[E], Generic[E]):
64
64
  """Thread-safe async-compatible, ordered collection of elements.
65
65
 
66
66
  The Pile class provides a thread-safe, async-compatible collection with:
@@ -76,13 +76,13 @@ class Pile(Element, Generic[T]):
76
76
  strict_type (bool): Whether to enforce strict type checking
77
77
  """
78
78
 
79
- pile_: dict[IDType, T] = Field(default_factory=dict)
80
- item_type: set[type[T]] | None = Field(
79
+ collections: dict[IDType, T] = Field(default_factory=dict)
80
+ item_type: set | None = Field(
81
81
  default=None,
82
82
  description="Set of allowed types for items in the pile.",
83
83
  exclude=True,
84
84
  )
85
- progress: Progression = Field(
85
+ progression: Progression = Field(
86
86
  default_factory=Progression,
87
87
  description="Progression specifying the order of items in the pile.",
88
88
  exclude=True,
@@ -107,7 +107,7 @@ class Pile(Element, Generic[T]):
107
107
  @override
108
108
  def __init__(
109
109
  self,
110
- items: ID.ItemSeq = None,
110
+ collections: ID.ItemSeq = None,
111
111
  item_type: set[type[T]] = None,
112
112
  order: ID.RefSeq = None,
113
113
  strict_type: bool = False,
@@ -122,15 +122,21 @@ class Pile(Element, Generic[T]):
122
122
  strict_type: If True, enforce strict type checking.
123
123
  """
124
124
  _config = {}
125
- if "ln_id" in kwargs:
126
- _config["ln_id"] = kwargs["ln_id"]
127
- if "created_timestamp" in kwargs:
128
- _config["created_timestamp"] = kwargs["created_timestamp"]
125
+ if "id" in kwargs:
126
+ _config["id"] = kwargs["id"]
127
+ if "created_at" in kwargs:
128
+ _config["created_at"] = kwargs["created_at"]
129
129
 
130
130
  super().__init__(strict_type=strict_type, **_config)
131
131
  self.item_type = self._validate_item_type(item_type)
132
- self.pile_ = self._validate_pile(items or kwargs.get("pile_", {}))
133
- self.progress = self._validate_order(order)
132
+
133
+ if isinstance(collections, list) and is_same_dtype(collections, dict):
134
+ collections = [Element.from_dict(i) for i in collections]
135
+
136
+ self.collections = self._validate_pile(
137
+ collections or kwargs.get("collections", {})
138
+ )
139
+ self.progression = self._validate_order(order)
134
140
 
135
141
  # Sync Interface methods
136
142
  @override
@@ -139,7 +145,7 @@ class Pile(Element, Generic[T]):
139
145
  cls,
140
146
  data: dict[str, Any],
141
147
  /,
142
- ) -> "Pile":
148
+ ) -> Pile:
143
149
  """Create a Pile instance from a dictionary.
144
150
 
145
151
  Args:
@@ -151,9 +157,9 @@ class Pile(Element, Generic[T]):
151
157
  Raises:
152
158
  ValueError: If the dictionary format is invalid.
153
159
  """
154
- items = data.pop("pile_", [])
160
+ items = data.pop("collections", [])
155
161
  items = [Element.from_dict(i) for i in items]
156
- return cls(items=items, **data)
162
+ return cls(collections=items, **data)
157
163
 
158
164
  def __setitem__(
159
165
  self,
@@ -178,7 +184,7 @@ class Pile(Element, Generic[T]):
178
184
  key: ID.Ref | ID.RefSeq | int | slice,
179
185
  default: D = UNDEFINED,
180
186
  /,
181
- ) -> T | "Pile" | D:
187
+ ) -> T | Pile | D:
182
188
  """Remove and return item(s) from the Pile.
183
189
 
184
190
  Args:
@@ -287,7 +293,7 @@ class Pile(Element, Generic[T]):
287
293
  key: ID.Ref | ID.RefSeq | int | slice,
288
294
  default: D = UNDEFINED,
289
295
  /,
290
- ) -> T | "Pile" | D:
296
+ ) -> T | Pile | D:
291
297
  """Get item(s) by key with default.
292
298
 
293
299
  Args:
@@ -301,31 +307,31 @@ class Pile(Element, Generic[T]):
301
307
 
302
308
  def keys(self) -> Sequence[str]:
303
309
  """Get all Lion IDs in order."""
304
- return list(self.progress)
310
+ return list(self.progression)
305
311
 
306
312
  def values(self) -> Sequence[T]:
307
313
  """Get all items in order."""
308
- return [self.pile_[key] for key in self.progress]
314
+ return [self.collections[key] for key in self.progression]
309
315
 
310
316
  def items(self) -> Sequence[tuple[IDType, T]]:
311
317
  """Get all (ID, item) pairs in order."""
312
- return [(key, self.pile_[key]) for key in self.progress]
318
+ return [(key, self.collections[key]) for key in self.progression]
313
319
 
314
320
  def is_empty(self) -> bool:
315
321
  """Check if empty."""
316
- return len(self.progress) == 0
322
+ return len(self.progression) == 0
317
323
 
318
324
  def size(self) -> int:
319
325
  """Get number of items."""
320
- return len(self.progress)
326
+ return len(self.progression)
321
327
 
322
328
  def __iter__(self) -> Iterator[T]:
323
329
  """Iterate over items safely."""
324
330
  with self.lock:
325
- current_order = list(self.progress)
331
+ current_order = list(self.progression)
326
332
 
327
333
  for key in current_order:
328
- yield self.pile_[key]
334
+ yield self.collections[key]
329
335
 
330
336
  def __next__(self) -> T:
331
337
  """Get next item."""
@@ -352,11 +358,11 @@ class Pile(Element, Generic[T]):
352
358
 
353
359
  def __contains__(self, item: ID.RefSeq | ID.Ref) -> bool:
354
360
  """Check if item exists."""
355
- return item in self.progress
361
+ return item in self.progression
356
362
 
357
363
  def __len__(self) -> int:
358
364
  """Get number of items."""
359
- return len(self.pile_)
365
+ return len(self.collections)
360
366
 
361
367
  @override
362
368
  def __bool__(self) -> bool:
@@ -367,42 +373,36 @@ class Pile(Element, Generic[T]):
367
373
  """Convert to list."""
368
374
  return self.values()
369
375
 
370
- def __ior__(self, other: "Pile") -> Self:
376
+ def __ior__(self, other: Pile) -> Self:
371
377
  """In-place union."""
372
378
  if not isinstance(other, Pile):
373
379
  raise TypeError(
374
- "Invalid type for Pile operation.",
375
- expected_type=Pile,
376
- actual_type=type(other),
380
+ f"Invalid type for Pile operation. expected <Pile>, got {type(other)}"
377
381
  )
378
382
  other = self._validate_pile(list(other))
379
383
  self.include(other)
380
384
  return self
381
385
 
382
- def __or__(self, other: "Pile") -> "Pile":
386
+ def __or__(self, other: Pile) -> Pile:
383
387
  """Union."""
384
388
  if not isinstance(other, Pile):
385
389
  raise TypeError(
386
- "Invalid type for Pile operation.",
387
- expected_type=Pile,
388
- actual_type=type(other),
390
+ f"Invalid type for Pile operation. expected <Pile>, got {type(other)}"
389
391
  )
390
392
 
391
393
  result = self.__class__(
392
394
  items=self.values(),
393
395
  item_type=self.item_type,
394
- order=self.progress,
396
+ order=self.progression,
395
397
  )
396
398
  result.include(list(other))
397
399
  return result
398
400
 
399
- def __ixor__(self, other: "Pile") -> Self:
401
+ def __ixor__(self, other: Pile) -> Self:
400
402
  """In-place symmetric difference."""
401
403
  if not isinstance(other, Pile):
402
404
  raise TypeError(
403
- "Invalid type for Pile operation.",
404
- expected_type=Pile,
405
- actual_type=type(other),
405
+ f"Invalid type for Pile operation. expected <Pile>, got {type(other)}"
406
406
  )
407
407
 
408
408
  to_exclude = []
@@ -415,13 +415,11 @@ class Pile(Element, Generic[T]):
415
415
  self.include(other)
416
416
  return self
417
417
 
418
- def __xor__(self, other: "Pile") -> "Pile":
418
+ def __xor__(self, other: Pile) -> Pile:
419
419
  """Symmetric difference."""
420
420
  if not isinstance(other, Pile):
421
421
  raise TypeError(
422
- "Invalid type for Pile operation.",
423
- expected_type=Pile,
424
- actual_type=type(other),
422
+ f"Invalid type for Pile operation. expected <Pile>, got {type(other)}"
425
423
  )
426
424
 
427
425
  to_exclude = []
@@ -439,13 +437,11 @@ class Pile(Element, Generic[T]):
439
437
  )
440
438
  return result
441
439
 
442
- def __iand__(self, other: "Pile") -> Self:
440
+ def __iand__(self, other: Pile) -> Self:
443
441
  """In-place intersection."""
444
442
  if not isinstance(other, Pile):
445
443
  raise TypeError(
446
- "Invalid type for Pile operation.",
447
- expected_type=Pile,
448
- actual_type=type(other),
444
+ f"Invalid type for Pile operation. expected <Pile>, got {type(other)}"
449
445
  )
450
446
 
451
447
  to_exclude = []
@@ -455,13 +451,11 @@ class Pile(Element, Generic[T]):
455
451
  self.exclude(to_exclude)
456
452
  return self
457
453
 
458
- def __and__(self, other: "Pile") -> "Pile":
454
+ def __and__(self, other: Pile) -> Pile:
459
455
  """Intersection."""
460
456
  if not isinstance(other, Pile):
461
457
  raise TypeError(
462
- "Invalid type for Pile operation.",
463
- expected_type=Pile,
464
- actual_type=type(other),
458
+ f"Invalid type for Pile operation. expected <Pile>, got {type(other)}"
465
459
  )
466
460
 
467
461
  values = [i for i in self if i in other]
@@ -482,7 +476,7 @@ class Pile(Element, Generic[T]):
482
476
  if length == 0:
483
477
  return "Pile()"
484
478
  elif length == 1:
485
- return f"Pile({next(iter(self.pile_.values())).__repr__()})"
479
+ return f"Pile({next(iter(self.collections.values())).__repr__()})"
486
480
  else:
487
481
  return f"Pile({length})"
488
482
 
@@ -590,10 +584,10 @@ class Pile(Element, Generic[T]):
590
584
  async def __aiter__(self) -> AsyncIterator[T]:
591
585
  """Async iterate over items."""
592
586
  async with self.async_lock:
593
- current_order = list(self.progress)
587
+ current_order = list(self.progression)
594
588
 
595
589
  for key in current_order:
596
- yield self.pile_[key]
590
+ yield self.collections[key]
597
591
  await asyncio.sleep(0) # Yield control to the event loop
598
592
 
599
593
  async def __anext__(self) -> T:
@@ -610,7 +604,7 @@ class Pile(Element, Generic[T]):
610
604
 
611
605
  if isinstance(key, int | slice):
612
606
  try:
613
- result_ids = self.progress[key]
607
+ result_ids = self.progression[key]
614
608
  result_ids = (
615
609
  [result_ids]
616
610
  if not isinstance(result_ids, list)
@@ -618,14 +612,14 @@ class Pile(Element, Generic[T]):
618
612
  )
619
613
  result = []
620
614
  for i in result_ids:
621
- result.append(self.pile_[i])
615
+ result.append(self.collections[i])
622
616
  return result[0] if len(result) == 1 else result
623
617
  except Exception as e:
624
618
  raise ItemNotFoundError(f"index {key}. Error: {e}")
625
619
 
626
620
  elif isinstance(key, IDType):
627
621
  try:
628
- return self.pile_[key]
622
+ return self.collections[key]
629
623
  except Exception as e:
630
624
  raise ItemNotFoundError(f"key {key}. Error: {e}")
631
625
 
@@ -635,7 +629,7 @@ class Pile(Element, Generic[T]):
635
629
  try:
636
630
  for k in key:
637
631
  result_id = ID.get_id(k)
638
- result.append(self.pile_[result_id])
632
+ result.append(self.collections[result_id])
639
633
 
640
634
  if len(result) == 0:
641
635
  raise ItemNotFoundError(f"key {key} item not found")
@@ -654,20 +648,20 @@ class Pile(Element, Generic[T]):
654
648
 
655
649
  item_order = []
656
650
  for i in item_dict.keys():
657
- if i in self.progress:
651
+ if i in self.progression:
658
652
  raise ItemExistsError(f"item {i} already exists in the pile")
659
653
  item_order.append(i)
660
654
  if isinstance(key, int | slice):
661
655
  try:
662
656
  delete_order = (
663
- list(self.progress[key])
664
- if isinstance(self.progress[key], Progression)
665
- else [self.progress[key]]
657
+ list(self.progression[key])
658
+ if isinstance(self.progression[key], Progression)
659
+ else [self.progression[key]]
666
660
  )
667
- self.progress[key] = item_order
661
+ self.progression[key] = item_order
668
662
  for i in to_list(delete_order, flatten=True):
669
- self.pile_.pop(i)
670
- self.pile_.update(item_dict)
663
+ self.collections.pop(i)
664
+ self.collections.update(item_dict)
671
665
  except Exception as e:
672
666
  raise ValueError(f"Failed to set pile. Error: {e}")
673
667
  else:
@@ -684,10 +678,10 @@ class Pile(Element, Generic[T]):
684
678
  raise KeyError(
685
679
  f"Invalid key {id_}. Key and item does not match.",
686
680
  )
687
- self.progress += key
688
- self.pile_.update(item_dict)
681
+ self.progression += key
682
+ self.collections.update(item_dict)
689
683
 
690
- def _get(self, key: Any, default: D = UNDEFINED) -> T | "Pile" | D:
684
+ def _get(self, key: Any, default: D = UNDEFINED) -> T | Pile | D:
691
685
  if isinstance(key, int | slice):
692
686
  try:
693
687
  return self[key]
@@ -724,15 +718,15 @@ class Pile(Element, Generic[T]):
724
718
  self,
725
719
  key: ID.Ref | ID.RefSeq | int | slice,
726
720
  default: D = UNDEFINED,
727
- ) -> T | "Pile" | D:
721
+ ) -> T | Pile | D:
728
722
  if isinstance(key, int | slice):
729
723
  try:
730
- pops = self.progress[key]
724
+ pops = self.progression[key]
731
725
  pops = [pops] if isinstance(pops, IDType) else pops
732
726
  result = []
733
727
  for i in pops:
734
- self.progress.remove(i)
735
- result.append(self.pile_.pop(i))
728
+ self.progression.remove(i)
729
+ result.append(self.collections.pop(i))
736
730
  result = (
737
731
  self.__class__(items=result, item_type=self.item_type)
738
732
  if len(result) > 1
@@ -748,8 +742,8 @@ class Pile(Element, Generic[T]):
748
742
  key = validate_order(key)
749
743
  result = []
750
744
  for k in key:
751
- self.progress.remove(k)
752
- result.append(self.pile_.pop(k))
745
+ self.progression.remove(k)
746
+ result.append(self.collections.pop(k))
753
747
  if len(result) == 0:
754
748
  raise ItemNotFoundError(f"key {key} item not found")
755
749
  elif len(result) == 1:
@@ -775,11 +769,11 @@ class Pile(Element, Generic[T]):
775
769
 
776
770
  item_order = []
777
771
  for i in item_dict.keys():
778
- if i not in self.progress:
772
+ if i not in self.progression:
779
773
  item_order.append(i)
780
774
 
781
- self.progress.append(item_order)
782
- self.pile_.update(item_dict)
775
+ self.progression.append(item_order)
776
+ self.collections.update(item_dict)
783
777
 
784
778
  def _exclude(self, item: ID.Ref | ID.RefSeq):
785
779
  item = to_list_type(item)
@@ -791,14 +785,14 @@ class Pile(Element, Generic[T]):
791
785
  self.pop(exclude_list)
792
786
 
793
787
  def _clear(self) -> None:
794
- self.pile_.clear()
795
- self.progress.clear()
788
+ self.collections.clear()
789
+ self.progression.clear()
796
790
 
797
791
  def _update(self, other: ID.ItemSeq | ID.Item):
798
792
  others = self._validate_pile(other)
799
793
  for i in others.keys():
800
- if i in self.pile_:
801
- self.pile_[i] = others[i]
794
+ if i in self.collections:
795
+ self.collections[i] = others[i]
802
796
  else:
803
797
  self.include(others[i])
804
798
 
@@ -811,9 +805,7 @@ class Pile(Element, Generic[T]):
811
805
  for i in value:
812
806
  if not issubclass(i, Observable):
813
807
  raise TypeError(
814
- message="Item type must be a subclass of T.",
815
- expected_type=T,
816
- actual_type=type(i),
808
+ f"Item type must be a subclass of Observable. Got {i}"
817
809
  )
818
810
 
819
811
  if len(value) != len(set(value)):
@@ -832,11 +824,14 @@ class Pile(Element, Generic[T]):
832
824
 
833
825
  result = {}
834
826
  for i in value:
827
+ if isinstance(i, dict):
828
+ i = Element.from_dict(i)
829
+
835
830
  if self.item_type:
836
831
  if self.strict_type:
837
832
  if type(i) not in self.item_type:
838
833
  raise TypeError(
839
- message="Invalid item type in pile."
834
+ "Invalid item type in pile."
840
835
  f" Expected {self.item_type}",
841
836
  )
842
837
  else:
@@ -849,13 +844,15 @@ class Pile(Element, Generic[T]):
849
844
  if not isinstance(i, Observable):
850
845
  raise ValueError(f"Invalid pile item {i}")
851
846
 
852
- result[i.ln_id] = i
847
+ result[i.id] = i
853
848
 
854
849
  return result
855
850
 
856
851
  def _validate_order(self, value: Any) -> Progression:
857
852
  if not value:
858
- return self.progress.__class__(order=list(self.pile_.keys()))
853
+ return self.progression.__class__(
854
+ order=list(self.collections.keys())
855
+ )
859
856
 
860
857
  if isinstance(value, Progression):
861
858
  value = list(value)
@@ -865,36 +862,36 @@ class Pile(Element, Generic[T]):
865
862
  value_set = set(value)
866
863
  if len(value_set) != len(value):
867
864
  raise ValueError("There are duplicate elements in the order")
868
- if len(value_set) != len(self.pile_.keys()):
865
+ if len(value_set) != len(self.collections.keys()):
869
866
  raise ValueError(
870
867
  "The length of the order does not match the length of the pile"
871
868
  )
872
869
 
873
870
  for i in value_set:
874
- if ID.get_id(i) not in self.pile_.keys():
871
+ if ID.get_id(i) not in self.collections.keys():
875
872
  raise ValueError(
876
873
  f"The order does not match the pile. {i} not found"
877
874
  )
878
875
 
879
- return self.progress.__class__(order=value)
876
+ return self.progression.__class__(order=value)
880
877
 
881
878
  def _insert(self, index: int, item: ID.Item):
882
879
  item_dict = self._validate_pile(item)
883
880
 
884
881
  item_order = []
885
882
  for i in item_dict.keys():
886
- if i in self.progress:
883
+ if i in self.progression:
887
884
  raise ItemExistsError(f"item {i} already exists in the pile")
888
885
  item_order.append(i)
889
- self.progress.insert(index, item_order)
890
- self.pile_.update(item_dict)
886
+ self.progression.insert(index, item_order)
887
+ self.collections.update(item_dict)
891
888
 
892
- @field_serializer("pile_")
889
+ @field_serializer("collections")
893
890
  def _(self, value: dict[str, T]):
894
891
  return [i.to_dict() for i in value.values()]
895
892
 
896
893
  class AsyncPileIterator:
897
- def __init__(self, pile: "Pile"):
894
+ def __init__(self, pile: Pile):
898
895
  self.pile = pile
899
896
  self.index = 0
900
897
 
@@ -904,7 +901,7 @@ class Pile(Element, Generic[T]):
904
901
  async def __anext__(self) -> T:
905
902
  if self.index >= len(self.pile):
906
903
  raise StopAsyncIteration
907
- item = self.pile[self.pile.progress[self.index]]
904
+ item = self.pile[self.pile.progression[self.index]]
908
905
  self.index += 1
909
906
  await asyncio.sleep(0) # Yield control to the event loop
910
907
  return item
@@ -925,7 +922,9 @@ class Pile(Element, Generic[T]):
925
922
 
926
923
  def is_homogenous(self) -> bool:
927
924
  """Check if all items are same type."""
928
- return len(self.pile_) < 2 or all(is_same_dtype(self.pile_.values()))
925
+ return len(self.collections) < 2 or all(
926
+ is_same_dtype(self.collections.values())
927
+ )
929
928
 
930
929
  def adapt_to(self, obj_key: str, /, **kwargs: Any) -> Any:
931
930
  """Convert to another format."""
@@ -954,27 +953,55 @@ class Pile(Element, Generic[T]):
954
953
  cls, obj, obj_key, **kwargs
955
954
  )
956
955
  if isinstance(dict_, list):
957
- dict_ = {"pile_": dict_}
956
+ dict_ = {"collections": dict_}
958
957
  return cls.from_dict(dict_)
959
958
 
960
959
  def to_df(
961
960
  self,
962
961
  columns: list[str] | None = None,
963
962
  **kwargs: Any,
964
- ):
963
+ ) -> pd.DataFrame:
965
964
  """Convert to DataFrame."""
966
965
  return self.adapt_to("pd_dataframe", columns=columns, **kwargs)
967
966
 
968
- def to_csv(self, fp: str | Path, **kwargs: Any) -> None:
967
+ def to_csv_file(self, fp: str | Path, **kwargs: Any) -> None:
969
968
  """Save to CSV file."""
970
969
  self.adapt_to(".csv", fp=fp, **kwargs)
971
970
 
971
+ def to_json_file(
972
+ self,
973
+ path_or_buf,
974
+ *,
975
+ use_pd: bool = False,
976
+ mode="w",
977
+ verbose=False,
978
+ **kwargs,
979
+ ):
980
+ """Export collection to JSON file.
981
+
982
+ Args:
983
+ path_or_buf: File path or buffer to write to.
984
+ use_pd: Use pandas JSON export if True.
985
+ mode: File open mode.
986
+ verbose: Print confirmation message.
987
+ **kwargs: Additional arguments for json.dump() or DataFrame.to_json().
988
+ """
989
+
990
+ if use_pd:
991
+ return self.to_df().to_json(mode=mode, **kwargs)
992
+ dict_ = self.to_dict()
993
+ with open(path_or_buf, mode) as f:
994
+ json.dump(dict_, f, **kwargs)
995
+
996
+ if verbose:
997
+ print(f"Saved Pile to {path_or_buf}")
998
+
972
999
 
973
1000
  def pile(
974
- items: Any = None,
1001
+ collections: Any = None,
975
1002
  /,
976
1003
  item_type: type[T] | set[type[T]] | None = None,
977
- order: list[str] | None = None,
1004
+ progression: list[str] | None = None,
978
1005
  strict_type: bool = False,
979
1006
  df: pd.DataFrame | None = None, # priority 1
980
1007
  fp: str | Path | None = None, # priority 2
@@ -1001,16 +1028,30 @@ def pile(
1001
1028
  return Pile.adapt_from(fp, ".csv", **kwargs)
1002
1029
  if fp.suffix == ".xlsx":
1003
1030
  return Pile.adapt_from(fp, ".xlsx", **kwargs)
1004
- if fp.suffix == ".json":
1031
+ if fp.suffix in [".json", ".jsonl"]:
1005
1032
  return Pile.adapt_from(fp, ".json", **kwargs)
1006
1033
 
1007
1034
  return Pile(
1008
- items,
1035
+ collections,
1009
1036
  item_type=item_type,
1010
- order=order,
1037
+ order=progression,
1011
1038
  strict=strict_type,
1012
1039
  **kwargs,
1013
1040
  )
1014
1041
 
1015
1042
 
1016
- # File: autoos/generic/pile.py
1043
+ def to_list_type(value: Any, /) -> list[Any]:
1044
+ """Convert input to a list format"""
1045
+ if value is None:
1046
+ return []
1047
+ if isinstance(value, IDType):
1048
+ return [value]
1049
+ if isinstance(value, str):
1050
+ return ID.get_id(value) if ID.is_id(value) else []
1051
+ if isinstance(value, Element):
1052
+ return [value]
1053
+ if hasattr(value, "values") and callable(value.values):
1054
+ return list(value.values())
1055
+ if isinstance(value, list | tuple | set | deque | Generator):
1056
+ return list(value)
1057
+ return [value]