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.
- lionagi/__init__.py +16 -24
- lionagi/{core/_class_registry.py → _class_registry.py} +51 -10
- lionagi/_errors.py +35 -0
- lionagi/libs/__init__.py +3 -0
- lionagi/libs/compress/__init__.py +3 -0
- lionagi/libs/compress/models.py +6 -2
- lionagi/libs/compress/utils.py +4 -16
- lionagi/libs/file/__init__.py +3 -0
- lionagi/libs/file/chunk.py +4 -0
- lionagi/libs/file/file_ops.py +4 -0
- lionagi/libs/file/params.py +4 -41
- lionagi/libs/file/process.py +4 -0
- lionagi/libs/file/save.py +5 -1
- lionagi/libs/{parse/flatten → nested}/flatten.py +4 -0
- lionagi/libs/{parse/nested → nested}/nfilter.py +4 -0
- lionagi/libs/{parse/nested → nested}/nget.py +6 -1
- lionagi/libs/{parse/nested → nested}/ninsert.py +5 -1
- lionagi/libs/{parse/nested → nested}/nmerge.py +4 -0
- lionagi/libs/{parse/nested → nested}/npop.py +5 -2
- lionagi/libs/{parse/nested → nested}/nset.py +6 -1
- lionagi/libs/{parse/flatten → nested}/unflatten.py +4 -0
- lionagi/libs/{parse/nested → nested}/utils.py +5 -1
- lionagi/libs/package/__init__.py +3 -0
- lionagi/libs/package/imports.py +6 -2
- lionagi/libs/package/management.py +7 -3
- lionagi/libs/package/params.py +4 -0
- lionagi/libs/package/system.py +4 -0
- lionagi/libs/parse.py +30 -0
- lionagi/libs/{parse/json → schema}/as_readable.py +10 -4
- lionagi/libs/{parse/string_parse/code_block.py → schema/extract_code_block.py} +4 -0
- lionagi/libs/{parse/string_parse/docstring.py → schema/extract_docstring.py} +4 -0
- lionagi/libs/{parse/string_parse/function_.py → schema/function_to_schema.py} +21 -9
- lionagi/libs/{parse/json/schema.py → schema/json_schema.py} +5 -1
- lionagi/libs/validate/common_field_validators.py +170 -0
- lionagi/libs/{parse/validate/keys.py → validate/fuzzy_match_keys.py} +42 -8
- lionagi/libs/{parse/validate/mapping.py → validate/fuzzy_validate_mapping.py} +41 -6
- lionagi/libs/{string_similarity/algorithms.py → validate/string_similarity.py} +115 -1
- lionagi/libs/{parse/validate/boolean.py → validate/validate_boolean.py} +42 -3
- lionagi/operations/__init__.py +13 -3
- lionagi/operations/brainstorm/__init__.py +3 -3
- lionagi/operations/brainstorm/brainstorm.py +33 -19
- lionagi/operations/brainstorm/prompt.py +4 -0
- lionagi/operations/plan/__init__.py +4 -0
- lionagi/operations/plan/plan.py +16 -13
- lionagi/operations/plan/prompt.py +4 -0
- lionagi/operations/select/__init__.py +4 -0
- lionagi/operations/select/prompt.py +4 -0
- lionagi/operations/select/select.py +1 -1
- lionagi/operations/select/utils.py +4 -4
- lionagi/{strategies → operations/strategies}/base.py +6 -2
- lionagi/{strategies → operations/strategies}/concurrent.py +8 -5
- lionagi/{strategies → operations/strategies}/concurrent_chunk.py +6 -3
- lionagi/{strategies → operations/strategies}/concurrent_sequential_chunk.py +8 -4
- lionagi/{strategies → operations/strategies}/params.py +10 -6
- lionagi/{strategies → operations/strategies}/sequential.py +6 -2
- lionagi/{strategies → operations/strategies}/sequential_chunk.py +7 -3
- lionagi/{strategies → operations/strategies}/sequential_concurrent_chunk.py +9 -4
- lionagi/{strategies → operations/strategies}/utils.py +6 -3
- lionagi/{core/models/__init__.py → operations/types.py} +3 -1
- lionagi/operations/utils.py +6 -3
- lionagi/operatives/action/function_calling.py +136 -0
- lionagi/operatives/action/manager.py +239 -0
- lionagi/operatives/action/request_response_model.py +90 -0
- lionagi/operatives/action/tool.py +141 -0
- lionagi/{protocols/operatives/action.py → operatives/action/utils.py} +52 -90
- lionagi/{core → operatives}/forms/base.py +9 -4
- lionagi/{core → operatives}/forms/form.py +8 -13
- lionagi/{core → operatives}/forms/report.py +5 -3
- lionagi/operatives/instruct/base.py +79 -0
- lionagi/operatives/instruct/instruct.py +105 -0
- lionagi/operatives/instruct/instruct_collection.py +52 -0
- lionagi/operatives/instruct/node.py +13 -0
- lionagi/{protocols/operatives → operatives/instruct}/prompts.py +0 -34
- lionagi/{protocols/operatives → operatives/instruct}/reason.py +14 -7
- lionagi/{integrations/anthropic_/version.py → operatives/manager.py} +5 -1
- lionagi/operatives/models/field_model.py +194 -0
- lionagi/operatives/models/model_params.py +307 -0
- lionagi/{core → operatives}/models/note.py +20 -28
- lionagi/{core → operatives}/models/operable_model.py +153 -71
- lionagi/{core → operatives}/models/schema_model.py +4 -3
- lionagi/{protocols/operatives → operatives}/operative.py +10 -7
- lionagi/{protocols/operatives → operatives}/step.py +67 -26
- lionagi/operatives/types.py +69 -0
- lionagi/protocols/_adapter.py +224 -0
- lionagi/protocols/_concepts.py +94 -0
- lionagi/protocols/generic/element.py +460 -0
- lionagi/protocols/generic/event.py +177 -0
- lionagi/protocols/generic/log.py +237 -0
- lionagi/{core → protocols}/generic/pile.py +172 -131
- lionagi/protocols/generic/processor.py +316 -0
- lionagi/protocols/generic/progression.py +500 -0
- lionagi/protocols/graph/edge.py +166 -0
- lionagi/protocols/graph/graph.py +290 -0
- lionagi/protocols/graph/node.py +109 -0
- lionagi/protocols/mail/exchange.py +116 -0
- lionagi/protocols/mail/mail.py +25 -0
- lionagi/protocols/mail/mailbox.py +47 -0
- lionagi/protocols/mail/manager.py +168 -0
- lionagi/protocols/mail/package.py +55 -0
- lionagi/protocols/messages/action_request.py +165 -0
- lionagi/protocols/messages/action_response.py +132 -0
- lionagi/{core/communication → protocols/messages}/assistant_response.py +55 -79
- lionagi/protocols/messages/base.py +73 -0
- lionagi/protocols/messages/instruction.py +582 -0
- lionagi/protocols/messages/manager.py +429 -0
- lionagi/protocols/messages/message.py +216 -0
- lionagi/protocols/messages/system.py +115 -0
- lionagi/protocols/messages/templates/assistant_response.jinja2 +6 -0
- lionagi/{core/communication → protocols/messages}/templates/instruction_message.jinja2 +2 -2
- lionagi/protocols/types.py +96 -0
- lionagi/service/__init__.py +10 -12
- lionagi/service/endpoints/base.py +517 -0
- lionagi/service/endpoints/chat_completion.py +102 -0
- lionagi/service/endpoints/match_endpoint.py +60 -0
- lionagi/service/endpoints/rate_limited_processor.py +145 -0
- lionagi/service/endpoints/token_calculator.py +209 -0
- lionagi/service/imodel.py +263 -96
- lionagi/service/manager.py +45 -0
- lionagi/service/providers/anthropic_/messages.py +64 -0
- lionagi/service/providers/groq_/chat_completions.py +56 -0
- lionagi/service/providers/openai_/chat_completions.py +62 -0
- lionagi/service/providers/openrouter_/chat_completions.py +62 -0
- lionagi/service/providers/perplexity_/__init__.py +3 -0
- lionagi/service/providers/perplexity_/chat_completions.py +40 -0
- lionagi/session/__init__.py +3 -0
- lionagi/session/branch.py +1287 -0
- lionagi/session/session.py +296 -0
- lionagi/settings.py +62 -118
- lionagi/utils.py +2386 -0
- lionagi/version.py +1 -1
- {lionagi-0.5.5.dist-info → lionagi-0.6.0.dist-info}/METADATA +7 -6
- lionagi-0.6.0.dist-info/RECORD +160 -0
- lionagi/core/action/action_manager.py +0 -289
- lionagi/core/action/base.py +0 -109
- lionagi/core/action/function_calling.py +0 -153
- lionagi/core/action/tool.py +0 -202
- lionagi/core/action/types.py +0 -16
- lionagi/core/communication/action_request.py +0 -163
- lionagi/core/communication/action_response.py +0 -149
- lionagi/core/communication/base_mail.py +0 -49
- lionagi/core/communication/instruction.py +0 -376
- lionagi/core/communication/message.py +0 -286
- lionagi/core/communication/message_manager.py +0 -543
- lionagi/core/communication/system.py +0 -116
- lionagi/core/communication/templates/assistant_response.jinja2 +0 -2
- lionagi/core/communication/types.py +0 -27
- lionagi/core/communication/utils.py +0 -256
- lionagi/core/forms/types.py +0 -13
- lionagi/core/generic/component.py +0 -422
- lionagi/core/generic/edge.py +0 -163
- lionagi/core/generic/element.py +0 -199
- lionagi/core/generic/graph.py +0 -377
- lionagi/core/generic/log.py +0 -151
- lionagi/core/generic/log_manager.py +0 -320
- lionagi/core/generic/node.py +0 -11
- lionagi/core/generic/progression.py +0 -395
- lionagi/core/generic/types.py +0 -23
- lionagi/core/generic/utils.py +0 -53
- lionagi/core/models/base.py +0 -28
- lionagi/core/models/field_model.py +0 -145
- lionagi/core/models/model_params.py +0 -194
- lionagi/core/models/types.py +0 -19
- lionagi/core/session/branch.py +0 -130
- lionagi/core/session/branch_mixins.py +0 -581
- lionagi/core/session/session.py +0 -163
- lionagi/core/session/types.py +0 -8
- lionagi/core/typing/__init__.py +0 -9
- lionagi/core/typing/_concepts.py +0 -173
- lionagi/core/typing/_id.py +0 -104
- lionagi/core/typing/_pydantic.py +0 -33
- lionagi/core/typing/_typing.py +0 -54
- lionagi/integrations/__init__.py +0 -0
- lionagi/integrations/_services.py +0 -17
- lionagi/integrations/anthropic_/AnthropicModel.py +0 -268
- lionagi/integrations/anthropic_/AnthropicService.py +0 -127
- lionagi/integrations/anthropic_/anthropic_max_output_token_data.yaml +0 -12
- lionagi/integrations/anthropic_/anthropic_price_data.yaml +0 -34
- lionagi/integrations/anthropic_/api_endpoints/api_request.py +0 -277
- lionagi/integrations/anthropic_/api_endpoints/data_models.py +0 -40
- lionagi/integrations/anthropic_/api_endpoints/match_response.py +0 -119
- lionagi/integrations/anthropic_/api_endpoints/messages/request/message_models.py +0 -14
- lionagi/integrations/anthropic_/api_endpoints/messages/request/request_body.py +0 -74
- lionagi/integrations/anthropic_/api_endpoints/messages/response/__init__.py +0 -0
- lionagi/integrations/anthropic_/api_endpoints/messages/response/content_models.py +0 -32
- lionagi/integrations/anthropic_/api_endpoints/messages/response/response_body.py +0 -101
- lionagi/integrations/anthropic_/api_endpoints/messages/response/usage_models.py +0 -25
- lionagi/integrations/groq_/GroqModel.py +0 -325
- lionagi/integrations/groq_/GroqService.py +0 -156
- lionagi/integrations/groq_/api_endpoints/__init__.py +0 -0
- lionagi/integrations/groq_/api_endpoints/data_models.py +0 -187
- lionagi/integrations/groq_/api_endpoints/groq_request.py +0 -288
- lionagi/integrations/groq_/api_endpoints/match_response.py +0 -106
- lionagi/integrations/groq_/api_endpoints/response_utils.py +0 -105
- lionagi/integrations/groq_/groq_max_output_token_data.yaml +0 -21
- lionagi/integrations/groq_/groq_price_data.yaml +0 -58
- lionagi/integrations/groq_/groq_rate_limits.yaml +0 -105
- lionagi/integrations/groq_/version.py +0 -5
- lionagi/integrations/litellm_/imodel.py +0 -76
- lionagi/integrations/ollama_/OllamaModel.py +0 -244
- lionagi/integrations/ollama_/OllamaService.py +0 -142
- lionagi/integrations/ollama_/api_endpoints/api_request.py +0 -179
- lionagi/integrations/ollama_/api_endpoints/chat_completion/message_models.py +0 -31
- lionagi/integrations/ollama_/api_endpoints/chat_completion/request_body.py +0 -46
- lionagi/integrations/ollama_/api_endpoints/chat_completion/response_body.py +0 -67
- lionagi/integrations/ollama_/api_endpoints/chat_completion/tool_models.py +0 -49
- lionagi/integrations/ollama_/api_endpoints/completion/__init__.py +0 -0
- lionagi/integrations/ollama_/api_endpoints/completion/request_body.py +0 -72
- lionagi/integrations/ollama_/api_endpoints/completion/response_body.py +0 -59
- lionagi/integrations/ollama_/api_endpoints/data_models.py +0 -15
- lionagi/integrations/ollama_/api_endpoints/embedding/__init__.py +0 -0
- lionagi/integrations/ollama_/api_endpoints/embedding/request_body.py +0 -33
- lionagi/integrations/ollama_/api_endpoints/embedding/response_body.py +0 -29
- lionagi/integrations/ollama_/api_endpoints/match_data_model.py +0 -62
- lionagi/integrations/ollama_/api_endpoints/match_response.py +0 -190
- lionagi/integrations/ollama_/api_endpoints/model/copy_model.py +0 -13
- lionagi/integrations/ollama_/api_endpoints/model/create_model.py +0 -28
- lionagi/integrations/ollama_/api_endpoints/model/delete_model.py +0 -11
- lionagi/integrations/ollama_/api_endpoints/model/list_model.py +0 -60
- lionagi/integrations/ollama_/api_endpoints/model/pull_model.py +0 -34
- lionagi/integrations/ollama_/api_endpoints/model/push_model.py +0 -35
- lionagi/integrations/ollama_/api_endpoints/model/show_model.py +0 -36
- lionagi/integrations/ollama_/api_endpoints/option_models.py +0 -68
- lionagi/integrations/openai_/OpenAIModel.py +0 -419
- lionagi/integrations/openai_/OpenAIService.py +0 -435
- lionagi/integrations/openai_/__init__.py +0 -0
- lionagi/integrations/openai_/api_endpoints/__init__.py +0 -3
- lionagi/integrations/openai_/api_endpoints/api_request.py +0 -277
- lionagi/integrations/openai_/api_endpoints/audio/__init__.py +0 -9
- lionagi/integrations/openai_/api_endpoints/audio/speech_models.py +0 -34
- lionagi/integrations/openai_/api_endpoints/audio/transcription_models.py +0 -136
- lionagi/integrations/openai_/api_endpoints/audio/translation_models.py +0 -41
- lionagi/integrations/openai_/api_endpoints/audio/types.py +0 -41
- lionagi/integrations/openai_/api_endpoints/batch/__init__.py +0 -17
- lionagi/integrations/openai_/api_endpoints/batch/batch_models.py +0 -146
- lionagi/integrations/openai_/api_endpoints/batch/cancel_batch.py +0 -7
- lionagi/integrations/openai_/api_endpoints/batch/create_batch.py +0 -26
- lionagi/integrations/openai_/api_endpoints/batch/list_batch.py +0 -37
- lionagi/integrations/openai_/api_endpoints/batch/request_object_models.py +0 -65
- lionagi/integrations/openai_/api_endpoints/batch/retrieve_batch.py +0 -7
- lionagi/integrations/openai_/api_endpoints/batch/types.py +0 -4
- lionagi/integrations/openai_/api_endpoints/chat_completions/__init__.py +0 -1
- lionagi/integrations/openai_/api_endpoints/chat_completions/request/__init__.py +0 -39
- lionagi/integrations/openai_/api_endpoints/chat_completions/request/message_models.py +0 -121
- lionagi/integrations/openai_/api_endpoints/chat_completions/request/request_body.py +0 -221
- lionagi/integrations/openai_/api_endpoints/chat_completions/request/response_format.py +0 -71
- lionagi/integrations/openai_/api_endpoints/chat_completions/request/stream_options.py +0 -14
- lionagi/integrations/openai_/api_endpoints/chat_completions/request/tool_choice_models.py +0 -17
- lionagi/integrations/openai_/api_endpoints/chat_completions/request/tool_models.py +0 -54
- lionagi/integrations/openai_/api_endpoints/chat_completions/request/types.py +0 -18
- lionagi/integrations/openai_/api_endpoints/chat_completions/response/__init__.py +0 -0
- lionagi/integrations/openai_/api_endpoints/chat_completions/response/choice_models.py +0 -62
- lionagi/integrations/openai_/api_endpoints/chat_completions/response/function_models.py +0 -16
- lionagi/integrations/openai_/api_endpoints/chat_completions/response/log_prob_models.py +0 -47
- lionagi/integrations/openai_/api_endpoints/chat_completions/response/message_models.py +0 -25
- lionagi/integrations/openai_/api_endpoints/chat_completions/response/response_body.py +0 -99
- lionagi/integrations/openai_/api_endpoints/chat_completions/response/types.py +0 -8
- lionagi/integrations/openai_/api_endpoints/chat_completions/response/usage_models.py +0 -24
- lionagi/integrations/openai_/api_endpoints/chat_completions/util.py +0 -46
- lionagi/integrations/openai_/api_endpoints/data_models.py +0 -23
- lionagi/integrations/openai_/api_endpoints/embeddings/__init__.py +0 -3
- lionagi/integrations/openai_/api_endpoints/embeddings/request_body.py +0 -79
- lionagi/integrations/openai_/api_endpoints/embeddings/response_body.py +0 -67
- lionagi/integrations/openai_/api_endpoints/files/__init__.py +0 -11
- lionagi/integrations/openai_/api_endpoints/files/delete_file.py +0 -20
- lionagi/integrations/openai_/api_endpoints/files/file_models.py +0 -56
- lionagi/integrations/openai_/api_endpoints/files/list_files.py +0 -27
- lionagi/integrations/openai_/api_endpoints/files/retrieve_file.py +0 -9
- lionagi/integrations/openai_/api_endpoints/files/upload_file.py +0 -38
- lionagi/integrations/openai_/api_endpoints/fine_tuning/__init__.py +0 -37
- lionagi/integrations/openai_/api_endpoints/fine_tuning/cancel_jobs.py +0 -9
- lionagi/integrations/openai_/api_endpoints/fine_tuning/create_jobs.py +0 -133
- lionagi/integrations/openai_/api_endpoints/fine_tuning/fine_tuning_job_checkpoint_models.py +0 -58
- lionagi/integrations/openai_/api_endpoints/fine_tuning/fine_tuning_job_event_models.py +0 -31
- lionagi/integrations/openai_/api_endpoints/fine_tuning/fine_tuning_job_models.py +0 -140
- lionagi/integrations/openai_/api_endpoints/fine_tuning/list_fine_tuning_checkpoints.py +0 -51
- lionagi/integrations/openai_/api_endpoints/fine_tuning/list_fine_tuning_events.py +0 -42
- lionagi/integrations/openai_/api_endpoints/fine_tuning/list_fine_tuning_jobs.py +0 -31
- lionagi/integrations/openai_/api_endpoints/fine_tuning/retrieve_jobs.py +0 -9
- lionagi/integrations/openai_/api_endpoints/fine_tuning/training_format.py +0 -30
- lionagi/integrations/openai_/api_endpoints/images/__init__.py +0 -9
- lionagi/integrations/openai_/api_endpoints/images/image_edit_models.py +0 -69
- lionagi/integrations/openai_/api_endpoints/images/image_models.py +0 -56
- lionagi/integrations/openai_/api_endpoints/images/image_variation_models.py +0 -56
- lionagi/integrations/openai_/api_endpoints/images/response_body.py +0 -30
- lionagi/integrations/openai_/api_endpoints/match_data_model.py +0 -197
- lionagi/integrations/openai_/api_endpoints/match_response.py +0 -336
- lionagi/integrations/openai_/api_endpoints/models/__init__.py +0 -7
- lionagi/integrations/openai_/api_endpoints/models/delete_fine_tuned_model.py +0 -17
- lionagi/integrations/openai_/api_endpoints/models/models_models.py +0 -31
- lionagi/integrations/openai_/api_endpoints/models/retrieve_model.py +0 -9
- lionagi/integrations/openai_/api_endpoints/moderations/__init__.py +0 -3
- lionagi/integrations/openai_/api_endpoints/moderations/request_body.py +0 -20
- lionagi/integrations/openai_/api_endpoints/moderations/response_body.py +0 -139
- lionagi/integrations/openai_/api_endpoints/uploads/__init__.py +0 -19
- lionagi/integrations/openai_/api_endpoints/uploads/add_upload_part.py +0 -11
- lionagi/integrations/openai_/api_endpoints/uploads/cancel_upload.py +0 -7
- lionagi/integrations/openai_/api_endpoints/uploads/complete_upload.py +0 -18
- lionagi/integrations/openai_/api_endpoints/uploads/create_upload.py +0 -17
- lionagi/integrations/openai_/api_endpoints/uploads/uploads_models.py +0 -52
- lionagi/integrations/openai_/image_token_calculator/__init__.py +0 -0
- lionagi/integrations/openai_/image_token_calculator/image_token_calculator.py +0 -98
- lionagi/integrations/openai_/image_token_calculator/openai_image_token_data.yaml +0 -15
- lionagi/integrations/openai_/openai_max_output_token_data.yaml +0 -12
- lionagi/integrations/openai_/openai_price_data.yaml +0 -26
- lionagi/integrations/openai_/version.py +0 -1
- lionagi/integrations/pandas_/__init__.py +0 -24
- lionagi/integrations/pandas_/extend_df.py +0 -61
- lionagi/integrations/pandas_/read.py +0 -103
- lionagi/integrations/pandas_/remove_rows.py +0 -61
- lionagi/integrations/pandas_/replace_keywords.py +0 -65
- lionagi/integrations/pandas_/save.py +0 -131
- lionagi/integrations/pandas_/search_keywords.py +0 -69
- lionagi/integrations/pandas_/to_df.py +0 -196
- lionagi/integrations/pandas_/update_cells.py +0 -54
- lionagi/integrations/perplexity_/PerplexityModel.py +0 -274
- lionagi/integrations/perplexity_/PerplexityService.py +0 -118
- lionagi/integrations/perplexity_/api_endpoints/__init__.py +0 -0
- lionagi/integrations/perplexity_/api_endpoints/api_request.py +0 -171
- lionagi/integrations/perplexity_/api_endpoints/chat_completions/__init__.py +0 -0
- lionagi/integrations/perplexity_/api_endpoints/chat_completions/request/__init__.py +0 -0
- lionagi/integrations/perplexity_/api_endpoints/chat_completions/request/request_body.py +0 -121
- lionagi/integrations/perplexity_/api_endpoints/chat_completions/response/__init__.py +0 -0
- lionagi/integrations/perplexity_/api_endpoints/chat_completions/response/response_body.py +0 -146
- lionagi/integrations/perplexity_/api_endpoints/data_models.py +0 -63
- lionagi/integrations/perplexity_/api_endpoints/match_response.py +0 -26
- lionagi/integrations/perplexity_/perplexity_max_output_token_data.yaml +0 -3
- lionagi/integrations/perplexity_/perplexity_price_data.yaml +0 -10
- lionagi/integrations/perplexity_/version.py +0 -1
- lionagi/integrations/pydantic_/__init__.py +0 -8
- lionagi/integrations/pydantic_/break_down_annotation.py +0 -81
- lionagi/integrations/pydantic_/new_model.py +0 -208
- lionagi/libs/constants.py +0 -98
- lionagi/libs/file/path.py +0 -301
- lionagi/libs/file/types.py +0 -22
- lionagi/libs/func/__init__.py +0 -0
- lionagi/libs/func/async_calls/__init__.py +0 -24
- lionagi/libs/func/async_calls/alcall.py +0 -210
- lionagi/libs/func/async_calls/bcall.py +0 -130
- lionagi/libs/func/async_calls/mcall.py +0 -134
- lionagi/libs/func/async_calls/pcall.py +0 -149
- lionagi/libs/func/async_calls/rcall.py +0 -217
- lionagi/libs/func/async_calls/tcall.py +0 -114
- lionagi/libs/func/async_calls/ucall.py +0 -85
- lionagi/libs/func/decorators.py +0 -277
- lionagi/libs/func/lcall.py +0 -57
- lionagi/libs/func/params.py +0 -64
- lionagi/libs/func/throttle.py +0 -119
- lionagi/libs/func/types.py +0 -39
- lionagi/libs/func/utils.py +0 -96
- lionagi/libs/package/types.py +0 -26
- lionagi/libs/parse/__init__.py +0 -1
- lionagi/libs/parse/flatten/__init__.py +0 -9
- lionagi/libs/parse/flatten/params.py +0 -52
- lionagi/libs/parse/json/__init__.py +0 -27
- lionagi/libs/parse/json/extract.py +0 -102
- lionagi/libs/parse/json/parse.py +0 -179
- lionagi/libs/parse/json/to_json.py +0 -71
- lionagi/libs/parse/nested/__init__.py +0 -33
- lionagi/libs/parse/nested/to_flat_list.py +0 -64
- lionagi/libs/parse/params.py +0 -0
- lionagi/libs/parse/string_parse/__init__.py +0 -11
- lionagi/libs/parse/type_convert/__init__.py +0 -19
- lionagi/libs/parse/type_convert/params.py +0 -145
- lionagi/libs/parse/type_convert/to_dict.py +0 -333
- lionagi/libs/parse/type_convert/to_list.py +0 -186
- lionagi/libs/parse/type_convert/to_num.py +0 -358
- lionagi/libs/parse/type_convert/to_str.py +0 -195
- lionagi/libs/parse/types.py +0 -9
- lionagi/libs/parse/validate/__init__.py +0 -14
- lionagi/libs/parse/validate/params.py +0 -62
- lionagi/libs/parse/xml/__init__.py +0 -10
- lionagi/libs/parse/xml/convert.py +0 -56
- lionagi/libs/parse/xml/parser.py +0 -93
- lionagi/libs/string_similarity/__init__.py +0 -32
- lionagi/libs/string_similarity/matcher.py +0 -102
- lionagi/libs/string_similarity/utils.py +0 -15
- lionagi/libs/utils.py +0 -266
- lionagi/protocols/adapters/__init__.py +0 -0
- lionagi/protocols/adapters/adapter.py +0 -79
- lionagi/protocols/adapters/json_adapter.py +0 -43
- lionagi/protocols/adapters/pandas_adapter.py +0 -96
- lionagi/protocols/configs/__init__.py +0 -0
- lionagi/protocols/configs/branch_config.py +0 -86
- lionagi/protocols/configs/id_config.py +0 -15
- lionagi/protocols/configs/imodel_config.py +0 -73
- lionagi/protocols/configs/log_config.py +0 -93
- lionagi/protocols/configs/retry_config.py +0 -29
- lionagi/protocols/configs/types.py +0 -15
- lionagi/protocols/operatives/instruct.py +0 -194
- lionagi/protocols/operatives/types.py +0 -19
- lionagi/protocols/registries/_component_registry.py +0 -23
- lionagi/protocols/registries/_pile_registry.py +0 -30
- lionagi/service/complete_request_info.py +0 -11
- lionagi/service/rate_limiter.py +0 -108
- lionagi/service/service.py +0 -41
- lionagi/service/service_match_util.py +0 -131
- lionagi/service/service_util.py +0 -72
- lionagi/service/token_calculator.py +0 -51
- lionagi/strategies/__init__.py +0 -0
- lionagi/strategies/types.py +0 -21
- lionagi-0.5.5.dist-info/RECORD +0 -374
- /lionagi/{core → libs/nested}/__init__.py +0 -0
- /lionagi/{core/action → libs/schema}/__init__.py +0 -0
- /lionagi/{core/communication → libs/validate}/__init__.py +0 -0
- /lionagi/{core/forms → operations/strategies}/__init__.py +0 -0
- /lionagi/{core/generic → operatives}/__init__.py +0 -0
- /lionagi/{core/session → operatives/action}/__init__.py +0 -0
- /lionagi/{integrations/anthropic_ → operatives/forms}/__init__.py +0 -0
- /lionagi/{core → operatives}/forms/utils.py +0 -0
- /lionagi/{integrations/anthropic_/api_endpoints → operatives/instruct}/__init__.py +0 -0
- /lionagi/{integrations/anthropic_/api_endpoints/messages → operatives/models}/__init__.py +0 -0
- /lionagi/{integrations/anthropic_/api_endpoints/messages/request → protocols/generic}/__init__.py +0 -0
- /lionagi/{integrations/groq_ → protocols/graph}/__init__.py +0 -0
- /lionagi/{integrations/litellm_ → protocols/mail}/__init__.py +0 -0
- /lionagi/{integrations/ollama_ → protocols/messages}/__init__.py +0 -0
- /lionagi/{core/communication → protocols/messages}/templates/README.md +0 -0
- /lionagi/{core/communication → protocols/messages}/templates/action_request.jinja2 +0 -0
- /lionagi/{core/communication → protocols/messages}/templates/action_response.jinja2 +0 -0
- /lionagi/{core/communication → protocols/messages}/templates/system_message.jinja2 +0 -0
- /lionagi/{core/communication → protocols/messages}/templates/tool_schemas.jinja2 +0 -0
- /lionagi/{integrations/ollama_/api_endpoints → service/endpoints}/__init__.py +0 -0
- /lionagi/{integrations/ollama_/api_endpoints/chat_completion → service/providers}/__init__.py +0 -0
- /lionagi/{integrations/ollama_/api_endpoints/model → service/providers/anthropic_}/__init__.py +0 -0
- /lionagi/{integrations/perplexity_ → service/providers/groq_}/__init__.py +0 -0
- /lionagi/{protocols/operatives → service/providers/openai_}/__init__.py +0 -0
- /lionagi/{protocols/registries → service/providers/openrouter_}/__init__.py +0 -0
- {lionagi-0.5.5.dist-info → lionagi-0.6.0.dist-info}/WHEEL +0 -0
- {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
|
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.
|
15
|
-
|
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
|
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__ = (
|
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:
|
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:
|
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[
|
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
|
-
|
80
|
-
item_type: set
|
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
|
-
|
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
|
-
|
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 "
|
126
|
-
_config["
|
127
|
-
if "
|
128
|
-
_config["
|
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
|
-
|
133
|
-
|
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
|
-
) ->
|
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("
|
160
|
+
items = data.pop("collections", [])
|
155
161
|
items = [Element.from_dict(i) for i in items]
|
156
|
-
return cls(
|
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 |
|
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 |
|
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.
|
310
|
+
return list(self.progression)
|
305
311
|
|
306
312
|
def values(self) -> Sequence[T]:
|
307
313
|
"""Get all items in order."""
|
308
|
-
return [self.
|
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.
|
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.
|
322
|
+
return len(self.progression) == 0
|
317
323
|
|
318
324
|
def size(self) -> int:
|
319
325
|
"""Get number of items."""
|
320
|
-
return len(self.
|
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.
|
331
|
+
current_order = list(self.progression)
|
326
332
|
|
327
333
|
for key in current_order:
|
328
|
-
yield self.
|
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.
|
361
|
+
return item in self.progression
|
356
362
|
|
357
363
|
def __len__(self) -> int:
|
358
364
|
"""Get number of items."""
|
359
|
-
return len(self.
|
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:
|
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:
|
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.
|
396
|
+
order=self.progression,
|
395
397
|
)
|
396
398
|
result.include(list(other))
|
397
399
|
return result
|
398
400
|
|
399
|
-
def __ixor__(self, other:
|
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:
|
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:
|
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:
|
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.
|
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.
|
587
|
+
current_order = list(self.progression)
|
594
588
|
|
595
589
|
for key in current_order:
|
596
|
-
yield self.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
664
|
-
if isinstance(self.
|
665
|
-
else [self.
|
657
|
+
list(self.progression[key])
|
658
|
+
if isinstance(self.progression[key], Progression)
|
659
|
+
else [self.progression[key]]
|
666
660
|
)
|
667
|
-
self.
|
661
|
+
self.progression[key] = item_order
|
668
662
|
for i in to_list(delete_order, flatten=True):
|
669
|
-
self.
|
670
|
-
self.
|
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.
|
688
|
-
self.
|
681
|
+
self.progression += key
|
682
|
+
self.collections.update(item_dict)
|
689
683
|
|
690
|
-
def _get(self, key: Any, default: D = UNDEFINED) -> T |
|
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 |
|
721
|
+
) -> T | Pile | D:
|
728
722
|
if isinstance(key, int | slice):
|
729
723
|
try:
|
730
|
-
pops = self.
|
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.
|
735
|
-
result.append(self.
|
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.
|
752
|
-
result.append(self.
|
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.
|
772
|
+
if i not in self.progression:
|
779
773
|
item_order.append(i)
|
780
774
|
|
781
|
-
self.
|
782
|
-
self.
|
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.
|
795
|
-
self.
|
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.
|
801
|
-
self.
|
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
|
-
|
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
|
-
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
890
|
-
self.
|
886
|
+
self.progression.insert(index, item_order)
|
887
|
+
self.collections.update(item_dict)
|
891
888
|
|
892
|
-
@field_serializer("
|
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:
|
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.
|
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.
|
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_ = {"
|
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
|
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
|
-
|
1001
|
+
collections: Any = None,
|
975
1002
|
/,
|
976
1003
|
item_type: type[T] | set[type[T]] | None = None,
|
977
|
-
|
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
|
1031
|
+
if fp.suffix in [".json", ".jsonl"]:
|
1005
1032
|
return Pile.adapt_from(fp, ".json", **kwargs)
|
1006
1033
|
|
1007
1034
|
return Pile(
|
1008
|
-
|
1035
|
+
collections,
|
1009
1036
|
item_type=item_type,
|
1010
|
-
order=
|
1037
|
+
order=progression,
|
1011
1038
|
strict=strict_type,
|
1012
1039
|
**kwargs,
|
1013
1040
|
)
|
1014
1041
|
|
1015
1042
|
|
1016
|
-
|
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]
|