lionagi 0.14.2__tar.gz → 0.14.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {lionagi-0.14.2 → lionagi-0.14.4}/PKG-INFO +7 -2
- lionagi-0.14.4/lionagi/adapters/async_postgres_adapter.py +362 -0
- lionagi-0.14.4/lionagi/adapters/postgres_model_adapter.py +131 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/protocols/graph/node.py +6 -4
- lionagi-0.14.4/lionagi/service/third_party/__init__.py +0 -0
- lionagi-0.14.4/lionagi/version.py +1 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/pyproject.toml +8 -2
- {lionagi-0.14.2 → lionagi-0.14.4}/uv.lock +299 -3
- lionagi-0.14.2/lionagi/version.py +0 -1
- {lionagi-0.14.2 → lionagi-0.14.4}/.coveragerc +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/.env.example +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/.github/FUNDING.yml +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/.github/dependabot.yml +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/.github/workflows/ci.yml +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/.github/workflows/codeql.yml +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/.github/workflows/docs.yml +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/.github/workflows/release.yml +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/.gitignore +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/.pre-commit-config.yaml +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/.python-version +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/CODE_OF_CONDUCT.md +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/CONTRIBUTING.md +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/LICENSE +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/README.md +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/assets/operation_builder.gif +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/cookbooks/001_branch_converse.ipynb +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/cookbooks/002_branch_interact.ipynb +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/cookbooks/003_branch_info.ipynb +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/cookbooks/004_conversation_patterns.ipynb +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/cookbooks/005_react_basics.ipynb +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/cookbooks/006_operation_graphs_claim_extraction.ipynb +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/cookbooks/data/002_comedian.json +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/cookbooks/data/002_critic.json +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/cookbooks/data/006_lion_proof_ch2.md +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/cookbooks/using_claude_code.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/docs/Makefile +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/docs/_static/custom.css +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/docs/_templates/layout.html +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/docs/conf.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/docs/index.rst +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/docs/modules/action.rst +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/docs/modules/adapter.rst +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/docs/modules/branch.rst +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/docs/modules/branch_operations.rst +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/docs/modules/concepts.rst +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/docs/modules/element_id.rst +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/docs/modules/event.rst +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/docs/modules/form.rst +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/docs/modules/graph.rst +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/docs/modules/index.rst +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/docs/modules/instruct.rst +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/docs/modules/lib_file.rst +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/docs/modules/lib_nested.rst +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/docs/modules/lib_package.rst +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/docs/modules/lib_schema.rst +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/docs/modules/lib_validate.rst +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/docs/modules/log.rst +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/docs/modules/mail.rst +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/docs/modules/message.rst +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/docs/modules/models.rst +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/docs/modules/operative_step.rst +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/docs/modules/pile.rst +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/docs/modules/processor.rst +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/docs/modules/progression.rst +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/docs/modules/service.rst +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/docs/modules/session.rst +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/docs/modules/utils.rst +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/docs/tutorials/get_started.rst +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/docs/tutorials/get_started_pt2.rst +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/docs/tutorials/get_started_pt3.rst +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/docs/tutorials/index.rst +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/__init__.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/_class_registry.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/_errors.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/_types.py +0 -0
- {lionagi-0.14.2/lionagi/libs/token_transform → lionagi-0.14.4/lionagi/adapters}/__init__.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/config.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/fields/__init__.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/fields/action.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/fields/base.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/fields/code.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/fields/file.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/fields/instruct.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/fields/reason.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/fields/research.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/libs/__init__.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/libs/concurrency/__init__.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/libs/concurrency/cancel.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/libs/concurrency/errors.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/libs/concurrency/patterns.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/libs/concurrency/primitives.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/libs/concurrency/task.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/libs/file/__init__.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/libs/file/chunk.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/libs/file/concat.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/libs/file/concat_files.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/libs/file/file_ops.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/libs/file/params.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/libs/file/process.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/libs/file/save.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/libs/nested/__init__.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/libs/nested/flatten.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/libs/nested/nfilter.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/libs/nested/nget.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/libs/nested/ninsert.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/libs/nested/nmerge.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/libs/nested/npop.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/libs/nested/nset.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/libs/nested/unflatten.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/libs/nested/utils.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/libs/package/__init__.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/libs/package/imports.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/libs/package/management.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/libs/package/params.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/libs/package/system.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/libs/parse.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/libs/schema/__init__.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/libs/schema/as_readable.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/libs/schema/extract_code_block.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/libs/schema/extract_docstring.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/libs/schema/function_to_schema.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/libs/schema/json_schema.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/libs/schema/load_pydantic_model_from_schema.py +0 -0
- {lionagi-0.14.2/lionagi/operations/communicate → lionagi-0.14.4/lionagi/libs/token_transform}/__init__.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/libs/token_transform/base.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/libs/token_transform/llmlingua.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/libs/token_transform/perplexity.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/libs/token_transform/symbolic_compress_context.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/libs/token_transform/synthlang.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/libs/token_transform/synthlang_/base.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/libs/token_transform/synthlang_/resources/frameworks/abstract_algebra.toml +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/libs/token_transform/synthlang_/resources/frameworks/category_theory.toml +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/libs/token_transform/synthlang_/resources/frameworks/complex_analysis.toml +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/libs/token_transform/synthlang_/resources/frameworks/framework_options.json +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/libs/token_transform/synthlang_/resources/frameworks/group_theory.toml +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/libs/token_transform/synthlang_/resources/frameworks/math_logic.toml +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/libs/token_transform/synthlang_/resources/frameworks/reflective_patterns.toml +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/libs/token_transform/synthlang_/resources/frameworks/set_theory.toml +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/libs/token_transform/synthlang_/resources/frameworks/topology_fundamentals.toml +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/libs/token_transform/synthlang_/resources/mapping/lion_emoji_mapping.toml +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/libs/token_transform/synthlang_/resources/mapping/python_math_mapping.toml +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/libs/token_transform/synthlang_/resources/mapping/rust_chinese_mapping.toml +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/libs/token_transform/synthlang_/resources/utility/base_synthlang_system_prompt.toml +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/libs/token_transform/synthlang_/translate_to_synthlang.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/libs/token_transform/types.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/libs/validate/__init__.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/libs/validate/common_field_validators.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/libs/validate/fuzzy_match_keys.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/libs/validate/fuzzy_validate_mapping.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/libs/validate/string_similarity.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/libs/validate/validate_boolean.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/models/__init__.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/models/field_model.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/models/hashable_model.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/models/model_params.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/models/note.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/models/operable_model.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/models/schema_model.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/operations/ReAct/ReAct.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/operations/ReAct/__init__.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/operations/ReAct/utils.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/operations/__init__.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/operations/_act/__init__.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/operations/_act/act.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/operations/brainstorm/__init__.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/operations/brainstorm/brainstorm.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/operations/brainstorm/prompt.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/operations/builder.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/operations/chat/__init__.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/operations/chat/chat.py +0 -0
- {lionagi-0.14.2/lionagi/operations/translate → lionagi-0.14.4/lionagi/operations/communicate}/__init__.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/operations/communicate/communicate.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/operations/flow.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/operations/instruct/__init__.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/operations/instruct/instruct.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/operations/interpret/__init__.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/operations/interpret/interpret.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/operations/manager.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/operations/node.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/operations/operate/__init__.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/operations/operate/operate.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/operations/parse/__init__.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/operations/parse/parse.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/operations/plan/__init__.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/operations/plan/plan.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/operations/plan/prompt.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/operations/select/__init__.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/operations/select/select.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/operations/select/utils.py +0 -0
- {lionagi-0.14.2/lionagi/service/third_party → lionagi-0.14.4/lionagi/operations/translate}/__init__.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/operations/translate/translate.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/operations/types.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/operations/utils.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/protocols/__init__.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/protocols/_concepts.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/protocols/action/__init__.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/protocols/action/function_calling.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/protocols/action/manager.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/protocols/action/tool.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/protocols/forms/__init__.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/protocols/forms/base.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/protocols/forms/flow.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/protocols/forms/form.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/protocols/forms/report.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/protocols/generic/__init__.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/protocols/generic/element.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/protocols/generic/event.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/protocols/generic/log.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/protocols/generic/pile.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/protocols/generic/processor.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/protocols/generic/progression.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/protocols/graph/__init__.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/protocols/graph/edge.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/protocols/graph/graph.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/protocols/mail/__init__.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/protocols/mail/exchange.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/protocols/mail/mail.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/protocols/mail/mailbox.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/protocols/mail/manager.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/protocols/mail/package.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/protocols/messages/__init__.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/protocols/messages/action_request.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/protocols/messages/action_response.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/protocols/messages/assistant_response.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/protocols/messages/base.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/protocols/messages/instruction.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/protocols/messages/manager.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/protocols/messages/message.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/protocols/messages/system.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/protocols/messages/templates/README.md +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/protocols/messages/templates/action_request.jinja2 +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/protocols/messages/templates/action_response.jinja2 +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/protocols/messages/templates/assistant_response.jinja2 +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/protocols/messages/templates/instruction_message.jinja2 +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/protocols/messages/templates/system_message.jinja2 +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/protocols/messages/templates/tool_schemas.jinja2 +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/protocols/operatives/__init__.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/protocols/operatives/operative.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/protocols/operatives/step.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/protocols/types.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/py.typed +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/service/__init__.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/service/connections/__init__.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/service/connections/api_calling.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/service/connections/endpoint.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/service/connections/endpoint_config.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/service/connections/header_factory.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/service/connections/match_endpoint.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/service/connections/providers/__init__.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/service/connections/providers/anthropic_.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/service/connections/providers/claude_code_.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/service/connections/providers/claude_code_cli.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/service/connections/providers/exa_.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/service/connections/providers/oai_.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/service/connections/providers/ollama_.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/service/connections/providers/perplexity_.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/service/imodel.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/service/manager.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/service/rate_limited_processor.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/service/resilience.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/service/third_party/README.md +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/service/third_party/anthropic_models.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/service/third_party/exa_models.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/service/third_party/openai_models.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/service/third_party/pplx_models.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/service/token_calculator.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/service/types.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/session/__init__.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/session/branch.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/session/prompts.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/session/session.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/settings.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/tools/__init__.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/tools/base.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/tools/file/__init__.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/tools/file/reader.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/tools/memory/tools.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/tools/types.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/lionagi/utils.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/main.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/scripts/README.md +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/scripts/concat.py +0 -0
- {lionagi-0.14.2 → lionagi-0.14.4}/scripts/config.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: lionagi
|
3
|
-
Version: 0.14.
|
3
|
+
Version: 0.14.4
|
4
4
|
Summary: An Intelligence Operating System.
|
5
5
|
Author-email: HaiyangLi <quantocean.li@gmail.com>, Liangbingyan Luo <llby_luo@outlook.com>
|
6
6
|
License: Apache License
|
@@ -224,7 +224,7 @@ Requires-Dist: aiohttp>=3.12.0
|
|
224
224
|
Requires-Dist: anyio>=4.8.0
|
225
225
|
Requires-Dist: backoff>=2.2.1
|
226
226
|
Requires-Dist: jinja2>=3.1.0
|
227
|
-
Requires-Dist: json-repair>=0.
|
227
|
+
Requires-Dist: json-repair>=0.40.0
|
228
228
|
Requires-Dist: matplotlib>=3.9.0
|
229
229
|
Requires-Dist: pillow>=11.0.0
|
230
230
|
Requires-Dist: psutil>=7.0.0
|
@@ -234,11 +234,13 @@ Requires-Dist: python-dotenv>=1.1.0
|
|
234
234
|
Requires-Dist: tiktoken>=0.8.0
|
235
235
|
Requires-Dist: toml>=0.9.0
|
236
236
|
Provides-Extra: all
|
237
|
+
Requires-Dist: aiosqlite>=0.21.0; extra == 'all'
|
237
238
|
Requires-Dist: claude-code-sdk>=0.0.14; extra == 'all'
|
238
239
|
Requires-Dist: datamodel-code-generator>=0.31.2; extra == 'all'
|
239
240
|
Requires-Dist: docling>=2.15.1; extra == 'all'
|
240
241
|
Requires-Dist: fastmcp>=2.10.5; extra == 'all'
|
241
242
|
Requires-Dist: ollama>=0.4.0; extra == 'all'
|
243
|
+
Requires-Dist: pydapter[postgres]; extra == 'all'
|
242
244
|
Requires-Dist: rich>=13.0.0; extra == 'all'
|
243
245
|
Provides-Extra: claude-code
|
244
246
|
Requires-Dist: claude-code-sdk>=0.0.14; extra == 'claude-code'
|
@@ -254,6 +256,9 @@ Provides-Extra: mcp
|
|
254
256
|
Requires-Dist: fastmcp>=2.10.5; extra == 'mcp'
|
255
257
|
Provides-Extra: ollama
|
256
258
|
Requires-Dist: ollama>=0.4.0; extra == 'ollama'
|
259
|
+
Provides-Extra: postgres
|
260
|
+
Requires-Dist: aiosqlite>=0.21.0; extra == 'postgres'
|
261
|
+
Requires-Dist: pydapter[postgres]; extra == 'postgres'
|
257
262
|
Provides-Extra: reader
|
258
263
|
Requires-Dist: docling>=2.15.1; extra == 'reader'
|
259
264
|
Provides-Extra: rich
|
@@ -0,0 +1,362 @@
|
|
1
|
+
"""
|
2
|
+
Clean LionAGI async PostgreSQL adapter for integration into lionagi core.
|
3
|
+
|
4
|
+
This adapter handles SQLAlchemy async inspection issues and lionagi data
|
5
|
+
serialization while providing seamless async persistence.
|
6
|
+
"""
|
7
|
+
|
8
|
+
from __future__ import annotations
|
9
|
+
|
10
|
+
from datetime import datetime
|
11
|
+
from typing import Any, ClassVar, TypeVar
|
12
|
+
|
13
|
+
from pydapter.exceptions import QueryError
|
14
|
+
|
15
|
+
try:
|
16
|
+
import sqlalchemy as sa
|
17
|
+
from pydapter.extras.async_postgres_ import AsyncPostgresAdapter
|
18
|
+
from sqlalchemy.ext.asyncio import create_async_engine
|
19
|
+
except ImportError:
|
20
|
+
raise ImportError(
|
21
|
+
"This adapter requires postgres option to be installed. "
|
22
|
+
'Please install them using `uv pip install "lionagi[postgres]"`.'
|
23
|
+
)
|
24
|
+
|
25
|
+
|
26
|
+
T = TypeVar("T")
|
27
|
+
|
28
|
+
|
29
|
+
class LionAGIAsyncPostgresAdapter(AsyncPostgresAdapter[T]):
|
30
|
+
"""
|
31
|
+
Async PostgreSQL adapter for lionagi Nodes with critical fixes.
|
32
|
+
|
33
|
+
Solves core issues:
|
34
|
+
1. SQLAlchemy async table inspection ("Inspection on an AsyncConnection is currently not supported")
|
35
|
+
2. LionAGI float timestamp serialization (created_at as float → datetime)
|
36
|
+
3. Datetime objects in JSON content (datetime → ISO strings)
|
37
|
+
4. Automatic metadata field mapping via LionAGIPostgresAdapter
|
38
|
+
|
39
|
+
Features:
|
40
|
+
- Works with lionagi's adapt_to_async() system
|
41
|
+
- Automatic schema creation for lionagi Node structure
|
42
|
+
- Cross-database compatibility (PostgreSQL/SQLite)
|
43
|
+
- Handles all lionagi data serialization edge cases
|
44
|
+
"""
|
45
|
+
|
46
|
+
obj_key: ClassVar[str] = "lionagi_async_pg"
|
47
|
+
|
48
|
+
@classmethod
|
49
|
+
def _table(cls, meta: sa.MetaData, name: str) -> sa.Table:
|
50
|
+
"""
|
51
|
+
Override parent's _table to avoid async inspection issues.
|
52
|
+
|
53
|
+
Uses JSON for SQLite compatibility, JSONB for PostgreSQL performance.
|
54
|
+
"""
|
55
|
+
# Determine JSON type based on database (check connection URL if available)
|
56
|
+
json_type = sa.JSON # Default safe option that works everywhere
|
57
|
+
|
58
|
+
# Try to detect PostgreSQL from the connection
|
59
|
+
if hasattr(meta, "bind") and meta.bind:
|
60
|
+
engine_url = str(meta.bind.engine.url)
|
61
|
+
if "postgresql" in engine_url and "sqlite" not in engine_url:
|
62
|
+
json_type = sa.dialects.postgresql.JSONB
|
63
|
+
|
64
|
+
return sa.Table(
|
65
|
+
name,
|
66
|
+
meta,
|
67
|
+
sa.Column("id", sa.String, primary_key=True),
|
68
|
+
sa.Column("content", json_type),
|
69
|
+
sa.Column(
|
70
|
+
"node_metadata", json_type
|
71
|
+
), # mapped from lionagi metadata
|
72
|
+
sa.Column("created_at", sa.DateTime),
|
73
|
+
sa.Column("embedding", json_type),
|
74
|
+
# Note: No autoload_with to avoid async inspection error
|
75
|
+
)
|
76
|
+
|
77
|
+
@classmethod
|
78
|
+
async def to_obj(
|
79
|
+
cls,
|
80
|
+
subj,
|
81
|
+
/,
|
82
|
+
*,
|
83
|
+
many: bool = True,
|
84
|
+
adapt_meth: str = "model_dump",
|
85
|
+
**kw,
|
86
|
+
):
|
87
|
+
"""
|
88
|
+
Write lionagi Node(s) to PostgreSQL with automatic fixes.
|
89
|
+
|
90
|
+
Handles:
|
91
|
+
1. Table creation if needed
|
92
|
+
2. LionAGI data serialization fixes
|
93
|
+
3. Async database operations
|
94
|
+
"""
|
95
|
+
try:
|
96
|
+
# Validate required parameters
|
97
|
+
engine_url = kw.get("dsn") or kw.get("engine_url")
|
98
|
+
table = kw.get("table")
|
99
|
+
|
100
|
+
if not engine_url or not table:
|
101
|
+
raise ValueError(
|
102
|
+
"Missing required 'dsn' and 'table' parameters"
|
103
|
+
)
|
104
|
+
|
105
|
+
# Ensure table exists with lionagi schema
|
106
|
+
await cls._ensure_table_exists(engine_url, table)
|
107
|
+
|
108
|
+
# Prepare data with lionagi fixes
|
109
|
+
items = subj if isinstance(subj, list) else [subj]
|
110
|
+
if not items:
|
111
|
+
return {"inserted_count": 0}
|
112
|
+
|
113
|
+
# Convert nodes to database rows with serialization fixes
|
114
|
+
rows = []
|
115
|
+
for item in items:
|
116
|
+
data = getattr(item, adapt_meth)()
|
117
|
+
fixed_data = cls._fix_lionagi_data(data)
|
118
|
+
rows.append(fixed_data)
|
119
|
+
|
120
|
+
# Execute async insert
|
121
|
+
engine = create_async_engine(engine_url, future=True)
|
122
|
+
async with engine.begin() as conn:
|
123
|
+
meta = sa.MetaData()
|
124
|
+
meta.bind = conn
|
125
|
+
table_obj = cls._table(meta, table)
|
126
|
+
await conn.execute(sa.insert(table_obj), rows)
|
127
|
+
|
128
|
+
return {"inserted_count": len(rows)}
|
129
|
+
|
130
|
+
except Exception as e:
|
131
|
+
raise QueryError(
|
132
|
+
f"Error in lionagi async adapter: {e}",
|
133
|
+
adapter="lionagi_async_pg",
|
134
|
+
) from e
|
135
|
+
|
136
|
+
@classmethod
|
137
|
+
async def _ensure_table_exists(cls, engine_url: str, table_name: str):
|
138
|
+
"""Create table with lionagi schema if it doesn't exist."""
|
139
|
+
try:
|
140
|
+
engine = create_async_engine(engine_url, future=True)
|
141
|
+
async with engine.begin() as conn:
|
142
|
+
meta = sa.MetaData()
|
143
|
+
meta.bind = conn
|
144
|
+
|
145
|
+
# Use the same _table method to ensure consistency
|
146
|
+
table = cls._table(meta, table_name)
|
147
|
+
|
148
|
+
# Create just this table
|
149
|
+
await conn.run_sync(table.create, checkfirst=True)
|
150
|
+
|
151
|
+
except Exception:
|
152
|
+
# Table might already exist, continue
|
153
|
+
pass
|
154
|
+
|
155
|
+
@classmethod
|
156
|
+
def _fix_lionagi_data(cls, data: dict) -> dict:
|
157
|
+
"""
|
158
|
+
Fix lionagi Node data for database storage.
|
159
|
+
|
160
|
+
Handles:
|
161
|
+
1. Float timestamp → datetime for created_at
|
162
|
+
2. Datetime objects in content → ISO strings
|
163
|
+
"""
|
164
|
+
# Fix created_at timestamp
|
165
|
+
if "created_at" in data and isinstance(
|
166
|
+
data["created_at"], (int, float)
|
167
|
+
):
|
168
|
+
data["created_at"] = datetime.fromtimestamp(data["created_at"])
|
169
|
+
|
170
|
+
# Fix datetime objects in content
|
171
|
+
if "content" in data and isinstance(data["content"], dict):
|
172
|
+
data["content"] = cls._serialize_datetime_recursive(
|
173
|
+
data["content"]
|
174
|
+
)
|
175
|
+
|
176
|
+
return data
|
177
|
+
|
178
|
+
@classmethod
|
179
|
+
def _serialize_datetime_recursive(cls, obj: Any) -> Any:
|
180
|
+
"""Recursively convert datetime objects to ISO strings."""
|
181
|
+
if isinstance(obj, datetime):
|
182
|
+
return obj.isoformat()
|
183
|
+
elif isinstance(obj, dict):
|
184
|
+
return {
|
185
|
+
k: cls._serialize_datetime_recursive(v) for k, v in obj.items()
|
186
|
+
}
|
187
|
+
elif isinstance(obj, list):
|
188
|
+
return [cls._serialize_datetime_recursive(item) for item in obj]
|
189
|
+
else:
|
190
|
+
return obj
|
191
|
+
|
192
|
+
@classmethod
|
193
|
+
async def from_obj(
|
194
|
+
cls,
|
195
|
+
node_cls: type[T],
|
196
|
+
obj: Any,
|
197
|
+
/,
|
198
|
+
*,
|
199
|
+
adapt_meth: str = "from_dict",
|
200
|
+
many: bool = True,
|
201
|
+
**kw,
|
202
|
+
) -> T | list[T] | None:
|
203
|
+
"""
|
204
|
+
Read lionagi Node(s) from database with automatic data reconstruction.
|
205
|
+
|
206
|
+
Handles:
|
207
|
+
1. Database querying with filters
|
208
|
+
2. Reverse metadata field mapping (node_metadata → metadata)
|
209
|
+
3. Reverse data serialization (ISO strings → datetime objects)
|
210
|
+
4. Node object reconstruction
|
211
|
+
|
212
|
+
Args:
|
213
|
+
node_cls: The Node class to instantiate
|
214
|
+
obj: Database connection parameters (dict with dsn, table, etc.)
|
215
|
+
adapt_meth: Adaptation method (unused but required by pydapter)
|
216
|
+
many: Whether to return list or single object
|
217
|
+
**kw: Additional query parameters (where, limit, order_by)
|
218
|
+
|
219
|
+
Returns:
|
220
|
+
Single Node, list of Nodes, or None if no results found
|
221
|
+
"""
|
222
|
+
try:
|
223
|
+
# Merge obj parameters with kw parameters
|
224
|
+
if isinstance(obj, dict):
|
225
|
+
params = {**obj, **kw}
|
226
|
+
else:
|
227
|
+
params = kw
|
228
|
+
|
229
|
+
# Validate required parameters
|
230
|
+
engine_url = params.get("dsn") or params.get("engine_url")
|
231
|
+
table = params.get("table")
|
232
|
+
|
233
|
+
if not engine_url or not table:
|
234
|
+
raise ValueError(
|
235
|
+
"Missing required 'dsn' and 'table' parameters"
|
236
|
+
)
|
237
|
+
|
238
|
+
# Build query
|
239
|
+
engine = create_async_engine(engine_url, future=True)
|
240
|
+
async with engine.begin() as conn:
|
241
|
+
meta = sa.MetaData()
|
242
|
+
meta.bind = conn
|
243
|
+
table_obj = cls._table(meta, table)
|
244
|
+
|
245
|
+
# Build SELECT query
|
246
|
+
query = sa.select(table_obj)
|
247
|
+
|
248
|
+
# Add WHERE conditions if provided
|
249
|
+
where_conditions = params.get("where")
|
250
|
+
if where_conditions:
|
251
|
+
if isinstance(where_conditions, dict):
|
252
|
+
# Convert dict to column conditions
|
253
|
+
for col_name, value in where_conditions.items():
|
254
|
+
if hasattr(table_obj.c, col_name):
|
255
|
+
query = query.where(
|
256
|
+
getattr(table_obj.c, col_name) == value
|
257
|
+
)
|
258
|
+
else:
|
259
|
+
# Assume it's already a SQLAlchemy condition
|
260
|
+
query = query.where(where_conditions)
|
261
|
+
|
262
|
+
# Add ordering if provided
|
263
|
+
order_by = params.get("order_by")
|
264
|
+
if order_by:
|
265
|
+
if isinstance(order_by, str):
|
266
|
+
if hasattr(table_obj.c, order_by):
|
267
|
+
query = query.order_by(
|
268
|
+
getattr(table_obj.c, order_by)
|
269
|
+
)
|
270
|
+
else:
|
271
|
+
query = query.order_by(order_by)
|
272
|
+
|
273
|
+
# Add limit if provided
|
274
|
+
limit = params.get("limit")
|
275
|
+
if limit:
|
276
|
+
query = query.limit(limit)
|
277
|
+
|
278
|
+
# Execute query
|
279
|
+
result = await conn.execute(query)
|
280
|
+
rows = result.fetchall()
|
281
|
+
|
282
|
+
# Use many parameter from params if provided, otherwise use method parameter
|
283
|
+
return_many = params.get("many", many)
|
284
|
+
|
285
|
+
if not rows:
|
286
|
+
return [] if return_many else None
|
287
|
+
|
288
|
+
# Convert database rows back to Node objects
|
289
|
+
nodes = []
|
290
|
+
for row in rows:
|
291
|
+
# Convert row to dict
|
292
|
+
row_dict = dict(row._mapping)
|
293
|
+
|
294
|
+
# Apply reverse lionagi data transformations
|
295
|
+
node_data = cls._reverse_lionagi_data(row_dict)
|
296
|
+
|
297
|
+
# Create Node instance
|
298
|
+
node = node_cls(**node_data)
|
299
|
+
nodes.append(node)
|
300
|
+
|
301
|
+
if return_many:
|
302
|
+
return nodes
|
303
|
+
else:
|
304
|
+
return nodes[-1] if nodes else None
|
305
|
+
|
306
|
+
except Exception as e:
|
307
|
+
raise QueryError(
|
308
|
+
f"Error reading from lionagi async adapter: {e}",
|
309
|
+
adapter="lionagi_async_pg",
|
310
|
+
) from e
|
311
|
+
|
312
|
+
@classmethod
|
313
|
+
def _reverse_lionagi_data(cls, row_data: dict) -> dict:
|
314
|
+
"""
|
315
|
+
Reverse lionagi data transformations from database storage.
|
316
|
+
|
317
|
+
Handles:
|
318
|
+
1. Database field mapping (node_metadata → metadata)
|
319
|
+
2. ISO string → datetime objects in content
|
320
|
+
3. Proper lionagi Node field structure
|
321
|
+
"""
|
322
|
+
# Create a copy to avoid modifying original
|
323
|
+
data = row_data.copy()
|
324
|
+
|
325
|
+
# Reverse field mapping: node_metadata → metadata
|
326
|
+
if "node_metadata" in data:
|
327
|
+
data["metadata"] = data.pop("node_metadata")
|
328
|
+
|
329
|
+
# Reverse datetime serialization in content
|
330
|
+
if "content" in data and isinstance(data["content"], dict):
|
331
|
+
data["content"] = cls._deserialize_datetime_recursive(
|
332
|
+
data["content"]
|
333
|
+
)
|
334
|
+
|
335
|
+
return data
|
336
|
+
|
337
|
+
@classmethod
|
338
|
+
def _deserialize_datetime_recursive(cls, obj: Any) -> Any:
|
339
|
+
"""Recursively convert ISO datetime strings back to datetime objects."""
|
340
|
+
if isinstance(obj, str):
|
341
|
+
# Try to parse as ISO datetime string
|
342
|
+
try:
|
343
|
+
# Check if it looks like an ISO datetime string
|
344
|
+
if "T" in obj and (
|
345
|
+
obj.endswith("Z")
|
346
|
+
or "+" in obj[-10:]
|
347
|
+
or obj.count(":") >= 2
|
348
|
+
):
|
349
|
+
return datetime.fromisoformat(obj.replace("Z", "+00:00"))
|
350
|
+
except (ValueError, AttributeError):
|
351
|
+
# Not a datetime string, return as-is
|
352
|
+
pass
|
353
|
+
return obj
|
354
|
+
elif isinstance(obj, dict):
|
355
|
+
return {
|
356
|
+
k: cls._deserialize_datetime_recursive(v)
|
357
|
+
for k, v in obj.items()
|
358
|
+
}
|
359
|
+
elif isinstance(obj, list):
|
360
|
+
return [cls._deserialize_datetime_recursive(item) for item in obj]
|
361
|
+
else:
|
362
|
+
return obj
|
@@ -0,0 +1,131 @@
|
|
1
|
+
"""
|
2
|
+
Clean LionAGI PostgreSQL adapter for integration into lionagi core.
|
3
|
+
|
4
|
+
This adapter handles the metadata field conflict and provides seamless
|
5
|
+
PostgreSQL persistence for lionagi Nodes.
|
6
|
+
"""
|
7
|
+
|
8
|
+
from __future__ import annotations
|
9
|
+
|
10
|
+
from typing import Any, Union, get_args, get_origin
|
11
|
+
|
12
|
+
from pydantic import BaseModel
|
13
|
+
|
14
|
+
try:
|
15
|
+
from pydapter.model_adapters.postgres_model import PostgresModelAdapter
|
16
|
+
from sqlalchemy import String
|
17
|
+
from sqlalchemy.orm import DeclarativeBase
|
18
|
+
except ImportError:
|
19
|
+
raise ImportError(
|
20
|
+
"This adapter requires postgres option to be installed. "
|
21
|
+
'Please install them using `uv pip install "lionagi[postgres]"`.'
|
22
|
+
)
|
23
|
+
|
24
|
+
|
25
|
+
class LionAGIPostgresAdapter(PostgresModelAdapter):
|
26
|
+
"""
|
27
|
+
PostgreSQL adapter for lionagi Nodes with automatic metadata field mapping.
|
28
|
+
|
29
|
+
Solves the core issue where lionagi's 'metadata' field conflicts with
|
30
|
+
SQLAlchemy's reserved 'metadata' attribute by automatically mapping it
|
31
|
+
to 'node_metadata' in the database schema.
|
32
|
+
|
33
|
+
Features:
|
34
|
+
- Automatic metadata field mapping (metadata → node_metadata)
|
35
|
+
- Handles Union types like list[float] | None for embedding fields
|
36
|
+
- Preserves all PostgreSQL-specific type support from parent
|
37
|
+
- Transparent to lionagi users - Elements work seamlessly
|
38
|
+
"""
|
39
|
+
|
40
|
+
# Core field mapping to resolve SQLAlchemy conflicts
|
41
|
+
FIELD_MAPPINGS = {"metadata": "node_metadata"}
|
42
|
+
|
43
|
+
def __init__(self):
|
44
|
+
super().__init__()
|
45
|
+
self._register_lionagi_types()
|
46
|
+
|
47
|
+
def _register_lionagi_types(self):
|
48
|
+
"""Register lionagi-specific type mappings."""
|
49
|
+
try:
|
50
|
+
# Handle lionagi IDType as String (UUID)
|
51
|
+
from lionagi.protocols.generic.element import IDType
|
52
|
+
|
53
|
+
self.register_type_mapping(
|
54
|
+
python_type=IDType,
|
55
|
+
sql_type_factory=lambda: String(36), # UUID string length
|
56
|
+
python_to_sql=lambda x: str(x),
|
57
|
+
sql_to_python=lambda x: IDType.validate(x) if x else None,
|
58
|
+
)
|
59
|
+
except ImportError:
|
60
|
+
pass # lionagi not available
|
61
|
+
|
62
|
+
@classmethod
|
63
|
+
def pydantic_model_to_sql(
|
64
|
+
cls,
|
65
|
+
model: type[BaseModel],
|
66
|
+
*,
|
67
|
+
table_name: str | None = None,
|
68
|
+
pk_field: str = "id",
|
69
|
+
schema: str | None = None,
|
70
|
+
) -> type[DeclarativeBase]:
|
71
|
+
"""
|
72
|
+
Generate SQLAlchemy model with lionagi field mapping.
|
73
|
+
|
74
|
+
Automatically handles:
|
75
|
+
- metadata → node_metadata mapping
|
76
|
+
- Union type resolution (e.g., list[float] | None → list[float])
|
77
|
+
- Standard lionagi Node field structure
|
78
|
+
"""
|
79
|
+
|
80
|
+
# Create modified field mapping for lionagi compatibility
|
81
|
+
modified_fields = {}
|
82
|
+
|
83
|
+
for name, info in model.model_fields.items():
|
84
|
+
# Apply field name mapping
|
85
|
+
field_name = cls.FIELD_MAPPINGS.get(name, name)
|
86
|
+
|
87
|
+
# Resolve Union types by extracting non-None type
|
88
|
+
annotation = info.annotation
|
89
|
+
origin = get_origin(annotation)
|
90
|
+
|
91
|
+
if origin is Union or (
|
92
|
+
hasattr(annotation, "__class__")
|
93
|
+
and annotation.__class__.__name__ == "UnionType"
|
94
|
+
):
|
95
|
+
args = get_args(annotation)
|
96
|
+
non_none_args = [arg for arg in args if arg is not type(None)]
|
97
|
+
if len(non_none_args) == 1:
|
98
|
+
annotation = non_none_args[0]
|
99
|
+
|
100
|
+
# Create field info with resolved annotation
|
101
|
+
from pydantic.fields import FieldInfo
|
102
|
+
|
103
|
+
modified_fields[field_name] = FieldInfo(
|
104
|
+
annotation=annotation,
|
105
|
+
default=info.default,
|
106
|
+
default_factory=info.default_factory,
|
107
|
+
alias=info.alias,
|
108
|
+
title=info.title,
|
109
|
+
description=info.description,
|
110
|
+
json_schema_extra=info.json_schema_extra,
|
111
|
+
frozen=info.frozen,
|
112
|
+
validate_default=info.validate_default,
|
113
|
+
repr=info.repr,
|
114
|
+
init_var=info.init_var,
|
115
|
+
kw_only=info.kw_only,
|
116
|
+
)
|
117
|
+
|
118
|
+
# Create temporary model with mapped fields
|
119
|
+
class ModifiedModel(BaseModel):
|
120
|
+
model_config = getattr(model, "model_config", {})
|
121
|
+
|
122
|
+
ModifiedModel.model_fields = modified_fields
|
123
|
+
ModifiedModel.__name__ = model.__name__
|
124
|
+
|
125
|
+
# Generate SQLAlchemy model with parent's logic
|
126
|
+
return super().pydantic_model_to_sql(
|
127
|
+
ModifiedModel,
|
128
|
+
table_name=table_name,
|
129
|
+
pk_field=pk_field,
|
130
|
+
schema=schema,
|
131
|
+
)
|
@@ -72,10 +72,12 @@ class Node(Element, Relational, AsyncAdaptable, Adaptable):
|
|
72
72
|
self, obj_key: str, many=False, **kwargs: Any
|
73
73
|
) -> Any:
|
74
74
|
kwargs["adapt_meth"] = "to_dict"
|
75
|
-
return super().adapt_to_async(
|
75
|
+
return await super().adapt_to_async(
|
76
|
+
obj_key=obj_key, many=many, **kwargs
|
77
|
+
)
|
76
78
|
|
77
79
|
@classmethod
|
78
|
-
def adapt_from_async(
|
80
|
+
async def adapt_from_async(
|
79
81
|
cls,
|
80
82
|
obj: Any,
|
81
83
|
obj_key: str,
|
@@ -83,7 +85,7 @@ class Node(Element, Relational, AsyncAdaptable, Adaptable):
|
|
83
85
|
**kwargs: Any,
|
84
86
|
) -> Node:
|
85
87
|
kwargs["adapt_meth"] = "from_dict"
|
86
|
-
return super().adapt_from_async(
|
88
|
+
return await super().adapt_from_async(
|
87
89
|
obj, obj_key=obj_key, many=many, **kwargs
|
88
90
|
)
|
89
91
|
|
@@ -92,7 +94,7 @@ class Node(Element, Relational, AsyncAdaptable, Adaptable):
|
|
92
94
|
Convert this Node to another format using a registered adapter.
|
93
95
|
"""
|
94
96
|
kwargs["adapt_meth"] = "to_dict"
|
95
|
-
return super().adapt_to(obj_key, many=many, **kwargs)
|
97
|
+
return super().adapt_to(obj_key=obj_key, many=many, **kwargs)
|
96
98
|
|
97
99
|
@classmethod
|
98
100
|
def adapt_from(
|
File without changes
|
@@ -0,0 +1 @@
|
|
1
|
+
__version__ = "0.14.4"
|
@@ -1,6 +1,6 @@
|
|
1
1
|
[project]
|
2
2
|
name = "lionagi"
|
3
|
-
version = "0.14.
|
3
|
+
version = "0.14.4"
|
4
4
|
description = "An Intelligence Operating System."
|
5
5
|
authors = [
|
6
6
|
{ name = "HaiyangLi", email = "quantocean.li@gmail.com" },
|
@@ -14,7 +14,7 @@ dependencies = [
|
|
14
14
|
"anyio>=4.8.0",
|
15
15
|
"backoff>=2.2.1",
|
16
16
|
"jinja2>=3.1.0",
|
17
|
-
"json-repair>=0.
|
17
|
+
"json-repair>=0.40.0",
|
18
18
|
"matplotlib>=3.9.0",
|
19
19
|
"pillow>=11.0.0",
|
20
20
|
"psutil>=7.0.0",
|
@@ -98,6 +98,11 @@ schema = [
|
|
98
98
|
"datamodel-code-generator>=0.31.2",
|
99
99
|
]
|
100
100
|
|
101
|
+
postgres = [
|
102
|
+
"pydapter[postgres]",
|
103
|
+
"aiosqlite>=0.21.0",
|
104
|
+
]
|
105
|
+
|
101
106
|
all = [
|
102
107
|
"lionagi[reader]",
|
103
108
|
"lionagi[ollama]",
|
@@ -105,6 +110,7 @@ all = [
|
|
105
110
|
"lionagi[mcp]",
|
106
111
|
"lionagi[rich]",
|
107
112
|
"lionagi[schema]",
|
113
|
+
"lionagi[postgres]",
|
108
114
|
]
|
109
115
|
|
110
116
|
|