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

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