lionagi 0.17.11__tar.gz → 0.18.0__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.18.0/AGENTS.md +31 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/PKG-INFO +1 -2
- {lionagi-0.17.11 → lionagi-0.18.0}/cookbooks/using_mcp/react_mcp_with_schema.py +1 -1
- lionagi-0.18.0/docs/quickstart/installation.md +77 -0
- lionagi-0.18.0/docs/quickstart/your-first-flow.md +80 -0
- lionagi-0.18.0/lionagi/libs/schema/minimal_yaml.py +98 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/ln/types.py +32 -5
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/models/field_model.py +9 -0
- lionagi-0.18.0/lionagi/operations/ReAct/ReAct.py +618 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/operations/ReAct/utils.py +3 -0
- lionagi-0.18.0/lionagi/operations/act/act.py +206 -0
- lionagi-0.18.0/lionagi/operations/chat/chat.py +190 -0
- lionagi-0.18.0/lionagi/operations/communicate/communicate.py +183 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/operations/flow.py +4 -4
- lionagi-0.18.0/lionagi/operations/interpret/interpret.py +87 -0
- lionagi-0.18.0/lionagi/operations/operate/operate.py +316 -0
- lionagi-0.18.0/lionagi/operations/parse/parse.py +215 -0
- lionagi-0.18.0/lionagi/operations/select/select.py +141 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/operations/select/utils.py +1 -1
- lionagi-0.18.0/lionagi/operations/types.py +122 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/protocols/generic/log.py +3 -2
- lionagi-0.18.0/lionagi/protocols/messages/__init__.py +29 -0
- lionagi-0.18.0/lionagi/protocols/messages/action_request.py +111 -0
- lionagi-0.18.0/lionagi/protocols/messages/action_response.py +97 -0
- lionagi-0.18.0/lionagi/protocols/messages/assistant_response.py +178 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/protocols/messages/base.py +26 -18
- lionagi-0.18.0/lionagi/protocols/messages/instruction.py +324 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/protocols/messages/manager.py +112 -62
- lionagi-0.18.0/lionagi/protocols/messages/message.py +142 -0
- lionagi-0.18.0/lionagi/protocols/messages/system.py +73 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/protocols/types.py +0 -2
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/service/connections/endpoint.py +0 -8
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/service/connections/providers/oai_.py +29 -94
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/service/connections/providers/ollama_.py +3 -2
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/service/hooks/hooked_event.py +2 -2
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/service/third_party/claude_code.py +3 -2
- lionagi-0.18.0/lionagi/service/third_party/openai_models.py +433 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/session/branch.py +170 -178
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/session/session.py +3 -9
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/tools/file/reader.py +2 -2
- lionagi-0.18.0/lionagi/version.py +1 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/mkdocs.yml +17 -41
- {lionagi-0.17.11 → lionagi-0.18.0}/pyproject.toml +1 -2
- {lionagi-0.17.11 → lionagi-0.18.0}/uv.lock +1 -3
- lionagi-0.17.11/docs/comparisons/langgraph.md +0 -440
- lionagi-0.17.11/docs/marketing/language-interoperability-manifesto.md +0 -181
- lionagi-0.17.11/docs/migration/from-autogen.md +0 -243
- lionagi-0.17.11/docs/migration/from-crewai.md +0 -259
- lionagi-0.17.11/docs/migration/from-langchain.md +0 -350
- lionagi-0.17.11/docs/migration/index.md +0 -64
- lionagi-0.17.11/docs/quickstart/claude-code-integration.md +0 -153
- lionagi-0.17.11/docs/quickstart/index.md +0 -53
- lionagi-0.17.11/docs/quickstart/installation.md +0 -61
- lionagi-0.17.11/docs/quickstart/orchestration-first.md +0 -229
- lionagi-0.17.11/docs/quickstart/your-first-flow.md +0 -253
- lionagi-0.17.11/docs/thinking-in-lionagi/branches-as-agents.md +0 -202
- lionagi-0.17.11/docs/thinking-in-lionagi/builder-pattern.md +0 -276
- lionagi-0.17.11/docs/thinking-in-lionagi/graphs-over-chains.md +0 -306
- lionagi-0.17.11/docs/thinking-in-lionagi/index.md +0 -86
- lionagi-0.17.11/docs/thinking-in-lionagi/why-lionagi.md +0 -169
- lionagi-0.17.11/lionagi/operations/ReAct/ReAct.py +0 -381
- lionagi-0.17.11/lionagi/operations/_act/act.py +0 -86
- lionagi-0.17.11/lionagi/operations/chat/chat.py +0 -174
- lionagi-0.17.11/lionagi/operations/communicate/communicate.py +0 -124
- lionagi-0.17.11/lionagi/operations/interpret/interpret.py +0 -42
- lionagi-0.17.11/lionagi/operations/operate/operate.py +0 -210
- lionagi-0.17.11/lionagi/operations/parse/parse.py +0 -187
- lionagi-0.17.11/lionagi/operations/select/select.py +0 -80
- lionagi-0.17.11/lionagi/operations/types.py +0 -26
- lionagi-0.17.11/lionagi/protocols/messages/action_request.py +0 -209
- lionagi-0.17.11/lionagi/protocols/messages/action_response.py +0 -155
- lionagi-0.17.11/lionagi/protocols/messages/assistant_response.py +0 -207
- lionagi-0.17.11/lionagi/protocols/messages/instruction.py +0 -668
- lionagi-0.17.11/lionagi/protocols/messages/message.py +0 -252
- lionagi-0.17.11/lionagi/protocols/messages/system.py +0 -144
- lionagi-0.17.11/lionagi/protocols/messages/templates/README.md +0 -28
- lionagi-0.17.11/lionagi/protocols/messages/templates/action_request.jinja2 +0 -5
- lionagi-0.17.11/lionagi/protocols/messages/templates/action_response.jinja2 +0 -9
- lionagi-0.17.11/lionagi/protocols/messages/templates/assistant_response.jinja2 +0 -6
- lionagi-0.17.11/lionagi/protocols/messages/templates/instruction_message.jinja2 +0 -61
- lionagi-0.17.11/lionagi/protocols/messages/templates/system_message.jinja2 +0 -11
- lionagi-0.17.11/lionagi/protocols/messages/templates/tool_schemas.jinja2 +0 -7
- lionagi-0.17.11/lionagi/service/connections/providers/types.py +0 -28
- lionagi-0.17.11/lionagi/service/third_party/openai_model_names.py +0 -198
- lionagi-0.17.11/lionagi/service/types.py +0 -58
- lionagi-0.17.11/lionagi/tools/file/__init__.py +0 -2
- lionagi-0.17.11/lionagi/version.py +0 -1
- {lionagi-0.17.11 → lionagi-0.18.0}/.coveragerc +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/.env.example +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/.github/FUNDING.yml +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/.github/dependabot.yml +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/.github/workflows/benchmarks.yml +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/.github/workflows/ci.yml +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/.github/workflows/codeql.yml +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/.github/workflows/docs-deploy.yml +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/.github/workflows/refresh-bench-baselines.yml +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/.github/workflows/release.yml +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/.gitignore +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/.pre-commit-config.yaml +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/.python-version +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/CODE_OF_CONDUCT.md +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/CONTRIBUTING.md +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/LICENSE +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/README.md +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/assets/operation_builder.gif +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/benchmarks/README.md +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/benchmarks/baselines/.gitkeep +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/benchmarks/baselines/concurrency-asyncio.json +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/benchmarks/baselines/concurrency-trio.json +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/benchmarks/baselines/fuzzy.json +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/benchmarks/baselines/ln-asyncio.json +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/benchmarks/baselines/ln-trio.json +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/benchmarks/ci_compare.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/benchmarks/comparisons/README.md +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/benchmarks/comparisons/benchmark_detailed_20250922_182217.csv +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/benchmarks/comparisons/benchmark_professional.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/benchmarks/comparisons/benchmark_results_20250922_182217.json +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/benchmarks/comparisons/benchmark_summary_20250922_182217.csv +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/benchmarks/comparisons/generate_benchmark_report.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/benchmarks/comparisons/report.md +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/benchmarks/concurrency_bench.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/benchmarks/fuzzy_bench.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/benchmarks/ln_bench.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/cookbooks/001_branch_converse.ipynb +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/cookbooks/002_branch_interact.ipynb +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/cookbooks/003_branch_info.ipynb +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/cookbooks/004_conversation_patterns.ipynb +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/cookbooks/005_react_basics.ipynb +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/cookbooks/006_operation_graphs_claim_extraction.ipynb +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/cookbooks/007_fan_out_in.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/cookbooks/data/002_comedian.json +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/cookbooks/data/002_critic.json +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/cookbooks/data/006_lion_proof_ch2.md +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/cookbooks/using_claude_code/claude_proxy/README.md +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/cookbooks/using_claude_code/claude_proxy/claude_code_proxy.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/cookbooks/using_claude_code/claude_proxy/run_w_claude_code_proxy.ipynb +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/cookbooks/using_claude_code/using_claude_code.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/cookbooks/using_mcp/.mcp.json +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/cookbooks/using_mcp/README.md +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/cookbooks/using_mcp/search_group.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/cookbooks/using_mcp/search_group_config.json +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/docs/DOCUMENTATION_STANDARDS.md +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/docs/advanced/custom-operations.md +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/docs/advanced/error-handling.md +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/docs/advanced/flow-composition.md +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/docs/advanced/index.md +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/docs/advanced/observability.md +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/docs/advanced/performance.md +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/docs/code-of-conduct.md +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/docs/contributing.md +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/docs/cookbook/brainstorming.md +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/docs/cookbook/claim-extraction.md +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/docs/cookbook/code-review-crew.md +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/docs/cookbook/data-persistence.md +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/docs/cookbook/hr-automation.md +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/docs/cookbook/index.md +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/docs/cookbook/research-synthesis.md +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/docs/core-concepts/index.md +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/docs/core-concepts/lionagi-philosophy.md +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/docs/core-concepts/messages-and-memory.md +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/docs/core-concepts/models-and-providers.md +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/docs/core-concepts/operations.md +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/docs/core-concepts/sessions-and-branches.md +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/docs/core-concepts/tools-and-functions.md +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/docs/for-ai-agents/claude-code-usage.md +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/docs/for-ai-agents/index.md +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/docs/for-ai-agents/orchestration-guide.md +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/docs/for-ai-agents/pattern-selection.md +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/docs/for-ai-agents/self-improvement.md +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/docs/includes/abbreviations.md +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/docs/index.md +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/docs/integrations/databases.md +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/docs/integrations/dspy-optimization.md +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/docs/integrations/index.md +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/docs/integrations/llamaindex-rag.md +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/docs/integrations/llm-providers.md +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/docs/integrations/mcp-servers.md +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/docs/integrations/tools.md +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/docs/integrations/vector-stores.md +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/docs/patterns/conditional-flows.md +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/docs/patterns/fan-out-in.md +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/docs/patterns/index.md +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/docs/patterns/react-with-rag.md +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/docs/patterns/sequential-analysis.md +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/docs/patterns/tournament-validation.md +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/docs/problem-statement.md +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/docs/reference/api/index.md +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/docs/reference/changelog.md +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/docs/reference/troubleshooting.md +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/docs/stylesheets/extra.css +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/__init__.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/_class_registry.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/_errors.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/_types.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/adapters/__init__.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/adapters/_utils.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/adapters/async_postgres_adapter.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/config.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/fields/__init__.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/fields/action.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/fields/base.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/fields/code.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/fields/file.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/fields/instruct.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/fields/reason.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/fields/research.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/libs/__init__.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/libs/file/__init__.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/libs/file/chunk.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/libs/file/process.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/libs/schema/__init__.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/libs/schema/as_readable.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/libs/schema/breakdown_pydantic_annotation.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/libs/schema/extract_code_block.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/libs/schema/extract_docstring.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/libs/schema/function_to_schema.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/libs/schema/load_pydantic_model_from_schema.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/libs/validate/__init__.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/libs/validate/common_field_validators.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/libs/validate/to_num.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/libs/validate/validate_boolean.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/ln/__init__.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/ln/_async_call.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/ln/_hash.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/ln/_json_dump.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/ln/_list_call.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/ln/_to_list.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/ln/_utils.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/ln/concurrency/__init__.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/ln/concurrency/_compat.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/ln/concurrency/cancel.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/ln/concurrency/errors.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/ln/concurrency/patterns.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/ln/concurrency/primitives.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/ln/concurrency/resource_tracker.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/ln/concurrency/task.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/ln/concurrency/utils.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/ln/fuzzy/__init__.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/ln/fuzzy/_extract_json.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/ln/fuzzy/_fuzzy_json.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/ln/fuzzy/_fuzzy_match.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/ln/fuzzy/_fuzzy_validate.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/ln/fuzzy/_string_similarity.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/ln/fuzzy/_to_dict.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/models/__init__.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/models/hashable_model.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/models/model_params.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/models/operable_model.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/models/schema_model.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/operations/ReAct/__init__.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/operations/__init__.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/operations/_visualize_graph.py +0 -0
- {lionagi-0.17.11/lionagi/operations/_act → lionagi-0.18.0/lionagi/operations/act}/__init__.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/operations/brainstorm/__init__.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/operations/brainstorm/brainstorm.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/operations/brainstorm/prompt.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/operations/builder.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/operations/chat/__init__.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/operations/communicate/__init__.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/operations/instruct/__init__.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/operations/instruct/instruct.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/operations/interpret/__init__.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/operations/manager.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/operations/node.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/operations/operate/__init__.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/operations/parse/__init__.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/operations/plan/__init__.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/operations/plan/plan.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/operations/plan/prompt.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/operations/select/__init__.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/operations/utils.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/protocols/__init__.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/protocols/_concepts.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/protocols/action/__init__.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/protocols/action/function_calling.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/protocols/action/manager.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/protocols/action/tool.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/protocols/contracts.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/protocols/forms/__init__.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/protocols/forms/base.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/protocols/forms/flow.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/protocols/forms/form.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/protocols/forms/report.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/protocols/generic/__init__.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/protocols/generic/element.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/protocols/generic/event.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/protocols/generic/pile.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/protocols/generic/processor.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/protocols/generic/progression.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/protocols/graph/__init__.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/protocols/graph/edge.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/protocols/graph/graph.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/protocols/graph/node.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/protocols/ids.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/protocols/mail/__init__.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/protocols/mail/exchange.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/protocols/mail/mail.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/protocols/mail/mailbox.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/protocols/mail/manager.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/protocols/mail/package.py +0 -0
- {lionagi-0.17.11/lionagi/protocols/messages → lionagi-0.18.0/lionagi/protocols/operatives}/__init__.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/protocols/operatives/operative.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/protocols/operatives/step.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/py.typed +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/service/__init__.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/service/broadcaster.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/service/connections/__init__.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/service/connections/api_calling.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/service/connections/endpoint_config.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/service/connections/header_factory.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/service/connections/match_endpoint.py +0 -0
- {lionagi-0.17.11/lionagi/protocols/operatives → lionagi-0.18.0/lionagi/service/connections/mcp}/__init__.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/service/connections/mcp/wrapper.py +0 -0
- {lionagi-0.17.11/lionagi/service/connections/mcp → lionagi-0.18.0/lionagi/service/connections/providers}/__init__.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/service/connections/providers/anthropic_.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/service/connections/providers/claude_code_cli.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/service/connections/providers/exa_.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/service/connections/providers/nvidia_nim_.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/service/connections/providers/perplexity_.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/service/hooks/__init__.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/service/hooks/_types.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/service/hooks/_utils.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/service/hooks/hook_event.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/service/hooks/hook_registry.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/service/imodel.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/service/manager.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/service/rate_limited_processor.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/service/resilience.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/service/third_party/README.md +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/service/third_party/__init__.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/service/third_party/anthropic_models.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/service/third_party/exa_models.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/service/third_party/pplx_models.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/service/token_calculator.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/session/__init__.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/session/prompts.py +0 -0
- {lionagi-0.17.11/lionagi/service/connections/providers → lionagi-0.18.0/lionagi/tools}/__init__.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/tools/base.py +0 -0
- {lionagi-0.17.11/lionagi/tools → lionagi-0.18.0/lionagi/tools/file}/__init__.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/tools/types.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/lionagi/utils.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/main.py +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/scripts/README.md +0 -0
- {lionagi-0.17.11 → lionagi-0.18.0}/scripts/update_openai_models.py +0 -0
lionagi-0.18.0/AGENTS.md
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# Repository Guidelines
|
2
|
+
|
3
|
+
## Project Structure & Module Organization
|
4
|
+
- Core runtime lives in `lionagi/` with subpackages for adapters, operations, session orchestration, protocol definitions, and tool integrations.
|
5
|
+
- Reusable assets, demos, and reference notebooks sit under `assets/`, `cookbooks/`, and `notebooks/`; automation scripts are in `scripts/`.
|
6
|
+
- Tests mirror the package layout in `tests/` (for example `tests/session/`, `tests/operations/`) with shared fixtures in `tests/fixtures/`.
|
7
|
+
- Documentation sources are maintained in `docs/` (MkDocs) and long-form guides in `CLAUDE.md`; published artifacts land in `site/` after builds.
|
8
|
+
|
9
|
+
## Build, Test, and Development Commands
|
10
|
+
- Install or update the environment with `uv sync --dev`; this pulls project and tooling dependencies from `pyproject.toml` / `uv.lock`.
|
11
|
+
- Run the full suite via `uv run pytest`; pass `-m "not slow"` or `-k session` to target subsets while retaining pytest defaults (parallel, strict markers).
|
12
|
+
- Format and lint before committing: `uv run black .`, `uv run ruff check lionagi tests`, and `pre-commit run --all-files` for the configured hook chain.
|
13
|
+
|
14
|
+
## Coding Style & Naming Conventions
|
15
|
+
- Follow Black’s 79-character line length and isort’s Black profile; keep imports grouped standard/third-party/local.
|
16
|
+
- Prefer explicit type hints and Pydantic models for structured data; name modules and directories in snake_case, classes in PascalCase, async coroutines with `_async` suffix when clarity helps.
|
17
|
+
- Avoid introducing new global state; prefer dependency injection through service or session layers within `lionagi/`.
|
18
|
+
|
19
|
+
## Testing Guidelines
|
20
|
+
- Place unit tests adjacent to the relevant module subtree (`tests/operations/test_branch.py`, etc.) using filenames that start with `test_` and classes prefixed `Test`.
|
21
|
+
- Leverage pytest markers declared in `pyproject.toml` (`unit`, `integration`, `slow`, `performance`); mark long-running or network-dependent flows to keep CI lean.
|
22
|
+
- Maintain coverage by extending fixtures and factories in `tests/fixtures/`; include regression cases for bugs and concurrency edge scenarios.
|
23
|
+
|
24
|
+
## Commit & Pull Request Guidelines
|
25
|
+
- Match the existing history: concise, sentence-case summaries in the imperative voice (e.g., `Improve session retry logic`).
|
26
|
+
- Each PR should describe scope, testing evidence (`uv run pytest` output, linting), linked GitHub issues, and screenshots or logs for UX-facing changes.
|
27
|
+
- Keep changesets focused, update `docs/` or `mkdocs.yml` alongside API changes, and request reviews once CI is green.
|
28
|
+
|
29
|
+
## Documentation & Configuration Notes
|
30
|
+
- Keep `.env.example` aligned with new configuration keys; avoid committing real secrets or API tokens.
|
31
|
+
- When altering public interfaces, update `docs/` and regenerate the MkDocs site with `uv run mkdocs build` to verify navigation.
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: lionagi
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.18.0
|
4
4
|
Summary: An Intelligence Operating System.
|
5
5
|
Author-email: HaiyangLi <quantocean.li@gmail.com>
|
6
6
|
License: Apache License
|
@@ -223,7 +223,6 @@ Requires-Dist: aiocache>=0.12.0
|
|
223
223
|
Requires-Dist: aiohttp>=3.11.0
|
224
224
|
Requires-Dist: anyio>=4.7.0
|
225
225
|
Requires-Dist: backoff>=2.0.0
|
226
|
-
Requires-Dist: jinja2>=3.0.0
|
227
226
|
Requires-Dist: json-repair>=0.40.0
|
228
227
|
Requires-Dist: msgspec>=0.18.0
|
229
228
|
Requires-Dist: pydantic-settings>=2.8.0
|
@@ -0,0 +1,77 @@
|
|
1
|
+
# Installation
|
2
|
+
|
3
|
+
## Install LionAGI
|
4
|
+
|
5
|
+
**Recommended**: Use `uv` for faster dependency resolution:
|
6
|
+
```bash
|
7
|
+
uv add lionagi
|
8
|
+
```
|
9
|
+
|
10
|
+
**Alternative**: Standard pip installation:
|
11
|
+
```bash
|
12
|
+
pip install lionagi
|
13
|
+
```
|
14
|
+
|
15
|
+
## Configure API Keys
|
16
|
+
|
17
|
+
Create a `.env` file in your project root:
|
18
|
+
|
19
|
+
```bash
|
20
|
+
# At minimum, add one provider
|
21
|
+
OPENAI_API_KEY=your_key_here
|
22
|
+
|
23
|
+
# Optional: Additional providers
|
24
|
+
ANTHROPIC_API_KEY=your_key_here
|
25
|
+
OPENROUTER_API_KEY=your_key_here
|
26
|
+
NVIDIA_NIM_API_KEY=your_key_here
|
27
|
+
GROQ_API_KEY=your_key_here
|
28
|
+
PERPLEXITY_API_KEY=your_key_here
|
29
|
+
EXA_API_KEY=your_key_here
|
30
|
+
```
|
31
|
+
|
32
|
+
LionAGI automatically loads from `.env` - no manual configuration needed.
|
33
|
+
|
34
|
+
## Verify Installation
|
35
|
+
|
36
|
+
Run this test to confirm everything works:
|
37
|
+
|
38
|
+
```python
|
39
|
+
from lionagi import Branch, iModel
|
40
|
+
|
41
|
+
async def test():
|
42
|
+
gpt4 = iModel(provider="openai", model="gpt-4o-mini")
|
43
|
+
branch = Branch(chat_model=gpt4)
|
44
|
+
reply = await branch.chat("Hello from LionAGI!")
|
45
|
+
print(f"LionAGI says: {reply}")
|
46
|
+
|
47
|
+
if __name__ == "__main__":
|
48
|
+
import anyio
|
49
|
+
anyio.run(test)
|
50
|
+
```
|
51
|
+
|
52
|
+
Expected output: A conversational response from the model.
|
53
|
+
|
54
|
+
## Supported Providers
|
55
|
+
|
56
|
+
LionAGI comes pre-configured for these providers:
|
57
|
+
|
58
|
+
- **`openai`** - GPT-5, GPT-4.1, o4-mini
|
59
|
+
- **`anthropic`** - Claude 4.5 Sonnet, Claude 4.1 Opus
|
60
|
+
- **`claude_code`** - Claude Code SDK integration
|
61
|
+
- **`ollama`** - Local model hosting
|
62
|
+
- **`openrouter`** - Access 200+ models via single API
|
63
|
+
- **`nvidia_nim`** - NVIDIA inference microservices
|
64
|
+
- **`groq`** - Fast inference on LPU hardware
|
65
|
+
- **`perplexity`** - Search-augmented responses
|
66
|
+
|
67
|
+
### Custom Providers
|
68
|
+
|
69
|
+
**OpenAI-compatible endpoints**:
|
70
|
+
```python
|
71
|
+
custom = iModel(
|
72
|
+
provider="openai_compatible",
|
73
|
+
model="custom-model",
|
74
|
+
api_key="your_key",
|
75
|
+
base_url="https://custom-endpoint.com/v1"
|
76
|
+
)
|
77
|
+
```
|
@@ -0,0 +1,80 @@
|
|
1
|
+
# Your First Flow
|
2
|
+
|
3
|
+
This quickstart shows LionAGI's core pattern: **multiple specialized branches working together**.
|
4
|
+
|
5
|
+
We'll build a self-critiquing joke generator - one branch writes jokes, another critiques them, then they iterate to improve.
|
6
|
+
|
7
|
+
## Complete Example
|
8
|
+
|
9
|
+
```python
|
10
|
+
from lionagi import Branch, iModel
|
11
|
+
|
12
|
+
chat_model = iModel(provider="openai", model="gpt-4.1-mini")
|
13
|
+
|
14
|
+
async def generate_joke(joke_request):
|
15
|
+
# Create two specialized branches
|
16
|
+
comedian = Branch(
|
17
|
+
chat_model=chat_model,
|
18
|
+
system="You are a comedian who makes technical concepts funny."
|
19
|
+
)
|
20
|
+
|
21
|
+
editor = Branch(
|
22
|
+
chat_model=chat_model,
|
23
|
+
system="You are an editor who improves clarity and punch."
|
24
|
+
)
|
25
|
+
|
26
|
+
# Flow: Generate → Critique → Revise → Verify
|
27
|
+
joke = await comedian.communicate(
|
28
|
+
"Write a short joke",
|
29
|
+
context={"user_input": joke_request}
|
30
|
+
)
|
31
|
+
|
32
|
+
feedback = await editor.communicate(
|
33
|
+
"Give humorous critical feedback to improve this joke by addressing clarity and punch.",
|
34
|
+
context={"joke": joke}
|
35
|
+
)
|
36
|
+
|
37
|
+
revision = await comedian.communicate(
|
38
|
+
"Revise the joke based on this feedback.",
|
39
|
+
context={"feedback": feedback}
|
40
|
+
)
|
41
|
+
|
42
|
+
final_check = await editor.communicate(
|
43
|
+
"Is this version better than the original? If yes, reply the following token (including the square brackets) '[YES]' only, otherwise elaborate on why not without including the token.",
|
44
|
+
context={"revised_joke": revision}
|
45
|
+
)
|
46
|
+
|
47
|
+
# Return improved version if approved
|
48
|
+
if "[yes]" in final_check.lower():
|
49
|
+
return revision
|
50
|
+
return joke # Fallback to original if not improved
|
51
|
+
|
52
|
+
# Run it
|
53
|
+
if __name__ == "__main__":
|
54
|
+
import anyio
|
55
|
+
result = anyio.run(generate_joke, "machine learning")
|
56
|
+
print(result)
|
57
|
+
```
|
58
|
+
|
59
|
+
## What Just Happened
|
60
|
+
|
61
|
+
**Branch**: Independent conversation context with its own system prompt and memory
|
62
|
+
- `comedian` = creative joke writing
|
63
|
+
- `editor` = critical feedback
|
64
|
+
|
65
|
+
**Flow**: Sequential operations across branches
|
66
|
+
1. Comedian generates initial joke
|
67
|
+
2. Editor provides feedback
|
68
|
+
3. Comedian revises based on feedback
|
69
|
+
4. Editor validates improvement
|
70
|
+
|
71
|
+
**Context**: Each `communicate()` call can include context from previous steps
|
72
|
+
|
73
|
+
## Try It
|
74
|
+
|
75
|
+
Save the code above and run:
|
76
|
+
```bash
|
77
|
+
uv run your_script.py
|
78
|
+
```
|
79
|
+
|
80
|
+
Expected output: A refined joke about machine learning, improved through iteration.
|
@@ -0,0 +1,98 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
from typing import Any
|
4
|
+
|
5
|
+
import orjson
|
6
|
+
import yaml
|
7
|
+
|
8
|
+
# --- YAML Dumper with minimal, readable settings --------------------------------
|
9
|
+
|
10
|
+
|
11
|
+
class MinimalDumper(yaml.SafeDumper):
|
12
|
+
# Disable anchors/aliases (&id001, *id001) for repeated objects.
|
13
|
+
def ignore_aliases(self, data: Any) -> bool: # type: ignore[override]
|
14
|
+
return True
|
15
|
+
|
16
|
+
|
17
|
+
def _represent_str(dumper: yaml.SafeDumper, data: str):
|
18
|
+
# Use block scalars for multiline text; plain style otherwise.
|
19
|
+
if "\n" in data:
|
20
|
+
return dumper.represent_scalar(
|
21
|
+
"tag:yaml.org,2002:str", data, style="|"
|
22
|
+
)
|
23
|
+
return dumper.represent_scalar("tag:yaml.org,2002:str", data)
|
24
|
+
|
25
|
+
|
26
|
+
MinimalDumper.add_representer(str, _represent_str)
|
27
|
+
|
28
|
+
# --- Optional pruning of empty values -------------------------------------------
|
29
|
+
|
30
|
+
|
31
|
+
def _is_empty(x: Any) -> bool:
|
32
|
+
"""
|
33
|
+
Define 'empty' for pruning. Keeps 0 and False.
|
34
|
+
- None or '' (after strip) are empty
|
35
|
+
- Empty containers are empty
|
36
|
+
"""
|
37
|
+
if x is None:
|
38
|
+
return True
|
39
|
+
if isinstance(x, str):
|
40
|
+
return x.strip() == ""
|
41
|
+
if isinstance(x, dict):
|
42
|
+
return len(x) == 0
|
43
|
+
if isinstance(x, (list, tuple, set)):
|
44
|
+
return len(x) == 0
|
45
|
+
# Keep numbers (including 0) and booleans (including False)
|
46
|
+
return False
|
47
|
+
|
48
|
+
|
49
|
+
def _prune(x: Any) -> Any:
|
50
|
+
"""Recursively remove empty leaves and empty containers produced thereby."""
|
51
|
+
if isinstance(x, dict):
|
52
|
+
pruned = {k: _prune(v) for k, v in x.items() if not _is_empty(v)}
|
53
|
+
# Remove keys that became empty after recursion
|
54
|
+
return {k: v for k, v in pruned.items() if not _is_empty(v)}
|
55
|
+
if isinstance(x, list):
|
56
|
+
pruned_list = [_prune(v) for v in x if not _is_empty(v)]
|
57
|
+
return [v for v in pruned_list if not _is_empty(v)]
|
58
|
+
if isinstance(x, tuple):
|
59
|
+
pruned_list = [_prune(v) for v in x if not _is_empty(v)]
|
60
|
+
return tuple(v for v in pruned_list if not _is_empty(v))
|
61
|
+
if isinstance(x, set):
|
62
|
+
pruned_set = {_prune(v) for v in x if not _is_empty(v)}
|
63
|
+
return {v for v in pruned_set if not _is_empty(v)}
|
64
|
+
return x
|
65
|
+
|
66
|
+
|
67
|
+
# --- Public API ------------------------------------------------------------------
|
68
|
+
|
69
|
+
|
70
|
+
def minimal_yaml(
|
71
|
+
value: Any,
|
72
|
+
*,
|
73
|
+
drop_empties: bool = True,
|
74
|
+
indent: int = 2,
|
75
|
+
line_width: int = 2**31 - 1, # avoid PyYAML inserting line-wraps
|
76
|
+
sort_keys: bool = False,
|
77
|
+
) -> str:
|
78
|
+
"""
|
79
|
+
Convert any Python value (dict/list/scalars) to a minimal, readable YAML string.
|
80
|
+
- Lists -> YAML sequences with '- '
|
81
|
+
- Dicts -> 'key: value' mappings
|
82
|
+
- Multiline strings -> block scalars (|)
|
83
|
+
- Optional pruning of empty values (keeps 0 and False)
|
84
|
+
- No aliases/anchors
|
85
|
+
"""
|
86
|
+
if isinstance(value, str):
|
87
|
+
value = orjson.loads(value)
|
88
|
+
|
89
|
+
data = _prune(value) if drop_empties else value
|
90
|
+
return yaml.dump(
|
91
|
+
data,
|
92
|
+
Dumper=MinimalDumper,
|
93
|
+
default_flow_style=False, # block style
|
94
|
+
sort_keys=sort_keys, # preserve insertion order
|
95
|
+
allow_unicode=True,
|
96
|
+
indent=indent,
|
97
|
+
width=line_width,
|
98
|
+
)
|
@@ -232,10 +232,13 @@ class Params:
|
|
232
232
|
dict_.update(kw_)
|
233
233
|
return dict_
|
234
234
|
|
235
|
-
def to_dict(self) -> dict[str, str]:
|
235
|
+
def to_dict(self, exclude: set[str] = None) -> dict[str, str]:
|
236
236
|
data = {}
|
237
|
+
exclude = exclude or set()
|
237
238
|
for k in self.allowed():
|
238
|
-
if not self._is_sentinel(
|
239
|
+
if k not in exclude and not self._is_sentinel(
|
240
|
+
v := getattr(self, k, Undefined)
|
241
|
+
):
|
239
242
|
data[k] = v
|
240
243
|
return data
|
241
244
|
|
@@ -249,6 +252,12 @@ class Params:
|
|
249
252
|
return False
|
250
253
|
return hash(self) == hash(other)
|
251
254
|
|
255
|
+
def with_updates(self, **kwargs: Any) -> DataClass:
|
256
|
+
"""Return a new instance with updated fields."""
|
257
|
+
dict_ = self.to_dict()
|
258
|
+
dict_.update(kwargs)
|
259
|
+
return type(self)(**dict_)
|
260
|
+
|
252
261
|
|
253
262
|
@dataclass(slots=True)
|
254
263
|
class DataClass:
|
@@ -296,11 +305,13 @@ class DataClass:
|
|
296
305
|
for k in self.allowed():
|
297
306
|
_validate_strict(k)
|
298
307
|
|
299
|
-
def to_dict(self) -> dict[str, str]:
|
308
|
+
def to_dict(self, exclude: set[str] = None) -> dict[str, str]:
|
300
309
|
data = {}
|
301
|
-
|
310
|
+
exclude = exclude or set()
|
302
311
|
for k in type(self).allowed():
|
303
|
-
if not self._is_sentinel(
|
312
|
+
if k not in exclude and not self._is_sentinel(
|
313
|
+
v := getattr(self, k)
|
314
|
+
):
|
304
315
|
data[k] = v
|
305
316
|
return data
|
306
317
|
|
@@ -311,6 +322,22 @@ class DataClass:
|
|
311
322
|
return True
|
312
323
|
return is_sentinel(value)
|
313
324
|
|
325
|
+
def with_updates(self, **kwargs: Any) -> DataClass:
|
326
|
+
"""Return a new instance with updated fields."""
|
327
|
+
dict_ = self.to_dict()
|
328
|
+
dict_.update(kwargs)
|
329
|
+
return type(self)(**dict_)
|
330
|
+
|
331
|
+
def __hash__(self) -> int:
|
332
|
+
from ._hash import hash_dict
|
333
|
+
|
334
|
+
return hash_dict(self.to_dict())
|
335
|
+
|
336
|
+
def __eq__(self, other: Any) -> bool:
|
337
|
+
if not isinstance(other, DataClass):
|
338
|
+
return False
|
339
|
+
return hash(self) == hash(other)
|
340
|
+
|
314
341
|
|
315
342
|
KeysLike = Sequence[str] | KeysDict
|
316
343
|
|
@@ -513,6 +513,15 @@ class FieldModel(Params):
|
|
513
513
|
# These are FieldTemplate markers, don't pass to FieldInfo
|
514
514
|
pass
|
515
515
|
else:
|
516
|
+
# Filter out unserializable objects from json_schema_extra
|
517
|
+
# to avoid Pydantic serialization errors when generating JSON schema
|
518
|
+
from pydantic import BaseModel
|
519
|
+
|
520
|
+
# Skip model classes and other unserializable types
|
521
|
+
if isinstance(meta.value, type):
|
522
|
+
# Skip type objects (including model classes) - they can't be serialized
|
523
|
+
continue
|
524
|
+
|
516
525
|
# Any other metadata goes in json_schema_extra
|
517
526
|
if "json_schema_extra" not in field_kwargs:
|
518
527
|
field_kwargs["json_schema_extra"] = {}
|