lionagi 0.17.2__tar.gz → 0.17.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.17.2 → lionagi-0.17.4}/.github/workflows/ci.yml +1 -9
- {lionagi-0.17.2 → lionagi-0.17.4}/PKG-INFO +28 -1
- {lionagi-0.17.2 → lionagi-0.17.4}/README.md +27 -0
- lionagi-0.17.4/cookbooks/using_mcp/.mcp.json +14 -0
- lionagi-0.17.4/cookbooks/using_mcp/README.md +190 -0
- lionagi-0.17.4/cookbooks/using_mcp/react_mcp_with_schema.py +102 -0
- lionagi-0.17.4/cookbooks/using_mcp/search_group.py +80 -0
- lionagi-0.17.4/cookbooks/using_mcp/search_group_config.json +6 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/__init__.py +5 -1
- lionagi-0.17.4/lionagi/protocols/action/manager.py +509 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/protocols/action/tool.py +45 -29
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/protocols/generic/pile.py +6 -1
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/protocols/messages/assistant_response.py +6 -0
- lionagi-0.17.4/lionagi/service/connections/mcp/wrapper.py +259 -0
- lionagi-0.17.4/lionagi/service/connections/providers/__init__.py +3 -0
- lionagi-0.17.4/lionagi/version.py +1 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/pyproject.toml +2 -1
- {lionagi-0.17.2 → lionagi-0.17.4}/uv.lock +476 -82
- lionagi-0.17.2/lionagi/protocols/action/manager.py +0 -251
- lionagi-0.17.2/lionagi/version.py +0 -1
- {lionagi-0.17.2 → lionagi-0.17.4}/.coveragerc +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/.env.example +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/.github/FUNDING.yml +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/.github/dependabot.yml +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/.github/workflows/benchmarks.yml +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/.github/workflows/codeql.yml +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/.github/workflows/docs-deploy.yml +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/.github/workflows/refresh-bench-baselines.yml +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/.github/workflows/release.yml +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/.gitignore +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/.pre-commit-config.yaml +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/.python-version +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/CODE_OF_CONDUCT.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/CONTRIBUTING.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/LICENSE +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/assets/operation_builder.gif +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/benchmarks/README.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/benchmarks/baselines/.gitkeep +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/benchmarks/baselines/concurrency-asyncio.json +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/benchmarks/baselines/concurrency-trio.json +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/benchmarks/baselines/fuzzy.json +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/benchmarks/baselines/ln-asyncio.json +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/benchmarks/baselines/ln-trio.json +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/benchmarks/ci_compare.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/benchmarks/concurrency_bench.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/benchmarks/fuzzy_bench.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/benchmarks/ln_bench.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/cookbooks/001_branch_converse.ipynb +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/cookbooks/002_branch_interact.ipynb +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/cookbooks/003_branch_info.ipynb +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/cookbooks/004_conversation_patterns.ipynb +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/cookbooks/005_react_basics.ipynb +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/cookbooks/006_operation_graphs_claim_extraction.ipynb +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/cookbooks/007_fan_out_in.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/cookbooks/claude_proxy/README.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/cookbooks/claude_proxy/claude_code_proxy.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/cookbooks/claude_proxy/run_w_claude_code_proxy.ipynb +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/cookbooks/data/002_comedian.json +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/cookbooks/data/002_critic.json +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/cookbooks/data/006_lion_proof_ch2.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/cookbooks/using_claude_code.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/docs/DOCUMENTATION_STANDARDS.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/docs/advanced/custom-operations.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/docs/advanced/error-handling.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/docs/advanced/flow-composition.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/docs/advanced/index.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/docs/advanced/observability.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/docs/advanced/performance.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/docs/code-of-conduct.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/docs/comparisons/langgraph.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/docs/contributing.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/docs/cookbook/brainstorming.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/docs/cookbook/claim-extraction.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/docs/cookbook/code-review-crew.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/docs/cookbook/data-persistence.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/docs/cookbook/hr-automation.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/docs/cookbook/index.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/docs/cookbook/research-synthesis.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/docs/core-concepts/index.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/docs/core-concepts/lionagi-philosophy.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/docs/core-concepts/messages-and-memory.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/docs/core-concepts/models-and-providers.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/docs/core-concepts/operations.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/docs/core-concepts/sessions-and-branches.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/docs/core-concepts/tools-and-functions.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/docs/for-ai-agents/claude-code-usage.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/docs/for-ai-agents/index.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/docs/for-ai-agents/orchestration-guide.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/docs/for-ai-agents/pattern-selection.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/docs/for-ai-agents/self-improvement.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/docs/includes/abbreviations.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/docs/index.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/docs/integrations/databases.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/docs/integrations/dspy-optimization.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/docs/integrations/index.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/docs/integrations/llamaindex-rag.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/docs/integrations/llm-providers.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/docs/integrations/mcp-servers.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/docs/integrations/tools.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/docs/integrations/vector-stores.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/docs/marketing/language-interoperability-manifesto.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/docs/migration/from-autogen.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/docs/migration/from-crewai.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/docs/migration/from-langchain.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/docs/migration/index.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/docs/patterns/conditional-flows.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/docs/patterns/fan-out-in.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/docs/patterns/index.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/docs/patterns/react-with-rag.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/docs/patterns/sequential-analysis.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/docs/patterns/tournament-validation.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/docs/problem-statement.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/docs/quickstart/claude-code-integration.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/docs/quickstart/index.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/docs/quickstart/installation.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/docs/quickstart/orchestration-first.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/docs/quickstart/your-first-flow.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/docs/reference/api/index.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/docs/reference/changelog.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/docs/reference/troubleshooting.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/docs/stylesheets/extra.css +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/docs/thinking-in-lionagi/branches-as-agents.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/docs/thinking-in-lionagi/builder-pattern.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/docs/thinking-in-lionagi/graphs-over-chains.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/docs/thinking-in-lionagi/index.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/docs/thinking-in-lionagi/why-lionagi.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/_class_registry.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/_errors.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/_types.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/adapters/__init__.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/adapters/_utils.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/adapters/async_postgres_adapter.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/config.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/fields/__init__.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/fields/action.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/fields/base.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/fields/code.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/fields/file.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/fields/instruct.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/fields/reason.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/fields/research.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/libs/__init__.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/libs/file/__init__.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/libs/file/_utils.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/libs/file/chunk.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/libs/file/concat.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/libs/file/concat_files.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/libs/file/file_ops.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/libs/file/process.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/libs/file/save.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/libs/schema/__init__.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/libs/schema/as_readable.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/libs/schema/extract_code_block.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/libs/schema/extract_docstring.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/libs/schema/function_to_schema.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/libs/schema/load_pydantic_model_from_schema.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/libs/validate/__init__.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/libs/validate/common_field_validators.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/libs/validate/to_num.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/libs/validate/validate_boolean.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/ln/__init__.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/ln/_async_call.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/ln/_hash.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/ln/_json_dump.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/ln/_list_call.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/ln/_to_list.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/ln/_utils.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/ln/concurrency/__init__.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/ln/concurrency/_compat.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/ln/concurrency/cancel.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/ln/concurrency/errors.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/ln/concurrency/patterns.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/ln/concurrency/primitives.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/ln/concurrency/resource_tracker.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/ln/concurrency/task.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/ln/concurrency/throttle.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/ln/concurrency/utils.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/ln/fuzzy/__init__.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/ln/fuzzy/_extract_json.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/ln/fuzzy/_fuzzy_json.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/ln/fuzzy/_fuzzy_match.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/ln/fuzzy/_fuzzy_validate.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/ln/fuzzy/_string_similarity.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/ln/fuzzy/_to_dict.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/ln/types.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/models/__init__.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/models/field_model.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/models/hashable_model.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/models/model_params.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/models/operable_model.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/models/schema_model.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/operations/ReAct/ReAct.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/operations/ReAct/__init__.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/operations/ReAct/utils.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/operations/__init__.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/operations/_act/__init__.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/operations/_act/act.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/operations/_visualize_graph.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/operations/brainstorm/__init__.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/operations/brainstorm/brainstorm.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/operations/brainstorm/prompt.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/operations/builder.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/operations/chat/__init__.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/operations/chat/chat.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/operations/communicate/__init__.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/operations/communicate/communicate.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/operations/flow.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/operations/instruct/__init__.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/operations/instruct/instruct.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/operations/interpret/__init__.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/operations/interpret/interpret.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/operations/manager.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/operations/node.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/operations/operate/__init__.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/operations/operate/operate.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/operations/parse/__init__.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/operations/parse/parse.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/operations/plan/__init__.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/operations/plan/plan.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/operations/plan/prompt.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/operations/select/__init__.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/operations/select/select.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/operations/select/utils.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/operations/types.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/operations/utils.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/protocols/__init__.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/protocols/_concepts.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/protocols/action/__init__.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/protocols/action/function_calling.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/protocols/contracts.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/protocols/forms/__init__.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/protocols/forms/base.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/protocols/forms/flow.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/protocols/forms/form.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/protocols/forms/report.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/protocols/generic/__init__.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/protocols/generic/element.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/protocols/generic/event.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/protocols/generic/log.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/protocols/generic/processor.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/protocols/generic/progression.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/protocols/graph/__init__.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/protocols/graph/edge.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/protocols/graph/graph.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/protocols/graph/node.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/protocols/ids.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/protocols/mail/__init__.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/protocols/mail/exchange.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/protocols/mail/mail.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/protocols/mail/mailbox.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/protocols/mail/manager.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/protocols/mail/package.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/protocols/messages/__init__.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/protocols/messages/action_request.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/protocols/messages/action_response.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/protocols/messages/base.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/protocols/messages/instruction.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/protocols/messages/manager.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/protocols/messages/message.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/protocols/messages/system.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/protocols/messages/templates/README.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/protocols/messages/templates/action_request.jinja2 +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/protocols/messages/templates/action_response.jinja2 +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/protocols/messages/templates/assistant_response.jinja2 +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/protocols/messages/templates/instruction_message.jinja2 +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/protocols/messages/templates/system_message.jinja2 +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/protocols/messages/templates/tool_schemas.jinja2 +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/protocols/operatives/__init__.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/protocols/operatives/operative.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/protocols/operatives/step.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/protocols/types.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/py.typed +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/service/__init__.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/service/connections/__init__.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/service/connections/api_calling.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/service/connections/endpoint.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/service/connections/endpoint_config.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/service/connections/header_factory.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/service/connections/match_endpoint.py +0 -0
- {lionagi-0.17.2/lionagi/service/connections/providers → lionagi-0.17.4/lionagi/service/connections/mcp}/__init__.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/service/connections/providers/anthropic_.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/service/connections/providers/claude_code_cli.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/service/connections/providers/exa_.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/service/connections/providers/nvidia_nim_.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/service/connections/providers/oai_.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/service/connections/providers/ollama_.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/service/connections/providers/perplexity_.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/service/connections/providers/types.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/service/hooks/__init__.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/service/hooks/_types.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/service/hooks/_utils.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/service/hooks/hook_event.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/service/hooks/hook_registry.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/service/imodel.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/service/manager.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/service/rate_limited_processor.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/service/resilience.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/service/third_party/README.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/service/third_party/__init__.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/service/third_party/anthropic_models.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/service/third_party/claude_code.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/service/third_party/exa_models.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/service/third_party/openai_model_names.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/service/third_party/pplx_models.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/service/token_calculator.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/service/types.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/session/__init__.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/session/branch.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/session/prompts.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/session/session.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/settings.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/tools/__init__.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/tools/base.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/tools/file/__init__.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/tools/file/reader.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/tools/types.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/lionagi/utils.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/main.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/mkdocs.yml +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/scripts/README.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.4}/scripts/update_openai_models.py +0 -0
@@ -27,18 +27,10 @@ jobs:
|
|
27
27
|
curl -LsSf https://astral.sh/uv/install.sh | sh
|
28
28
|
echo "$HOME/.cargo/bin" >> $GITHUB_PATH
|
29
29
|
|
30
|
-
- name: Load cached dependencies
|
31
|
-
id: cached-uv-dependencies
|
32
|
-
uses: actions/cache@v4
|
33
|
-
with:
|
34
|
-
path: .venv
|
35
|
-
key: venv-${{ runner.os }}-${{ matrix.python-version }}-${{ hashFiles('pyproject.toml') }}
|
36
|
-
|
37
30
|
- name: Install dependencies
|
38
|
-
if: steps.cached-uv-dependencies.outputs.cache-hit != 'true'
|
39
31
|
run: |
|
40
32
|
uv venv
|
41
|
-
uv sync --
|
33
|
+
uv sync --all-extras
|
42
34
|
|
43
35
|
- name: Run tests with coverage
|
44
36
|
run: |
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: lionagi
|
3
|
-
Version: 0.17.
|
3
|
+
Version: 0.17.4
|
4
4
|
Summary: An Intelligence Operating System.
|
5
5
|
Author-email: HaiyangLi <quantocean.li@gmail.com>
|
6
6
|
License: Apache License
|
@@ -374,6 +374,33 @@ print(result)
|
|
374
374
|
The LLM can now open the PDF, read in slices, fetch references, and produce a
|
375
375
|
final structured summary.
|
376
376
|
|
377
|
+
### MCP (Model Context Protocol) Integration
|
378
|
+
|
379
|
+
LionAGI supports Anthropic's Model Context Protocol for seamless tool integration:
|
380
|
+
|
381
|
+
```
|
382
|
+
pip install "lionagi[mcp]"
|
383
|
+
```
|
384
|
+
|
385
|
+
```python
|
386
|
+
from lionagi import load_mcp_tools
|
387
|
+
|
388
|
+
# Load tools from any MCP server
|
389
|
+
tools = await load_mcp_tools(".mcp.json", ["search", "memory"])
|
390
|
+
|
391
|
+
# Use with ReAct reasoning
|
392
|
+
branch = Branch(chat_model=gpt4o, tools=tools)
|
393
|
+
result = await branch.ReAct(
|
394
|
+
instruct={"instruction": "Research recent AI developments"},
|
395
|
+
tools=["search_exa_search"],
|
396
|
+
max_extensions=3
|
397
|
+
)
|
398
|
+
```
|
399
|
+
|
400
|
+
- **Dynamic Discovery**: Auto-discover and register tools from MCP servers
|
401
|
+
- **Type Safety**: Full Pydantic validation for tool interactions
|
402
|
+
- **Connection Pooling**: Efficient resource management with automatic reuse
|
403
|
+
|
377
404
|
### Observability & Debugging
|
378
405
|
|
379
406
|
- Inspect messages:
|
@@ -110,6 +110,33 @@ print(result)
|
|
110
110
|
The LLM can now open the PDF, read in slices, fetch references, and produce a
|
111
111
|
final structured summary.
|
112
112
|
|
113
|
+
### MCP (Model Context Protocol) Integration
|
114
|
+
|
115
|
+
LionAGI supports Anthropic's Model Context Protocol for seamless tool integration:
|
116
|
+
|
117
|
+
```
|
118
|
+
pip install "lionagi[mcp]"
|
119
|
+
```
|
120
|
+
|
121
|
+
```python
|
122
|
+
from lionagi import load_mcp_tools
|
123
|
+
|
124
|
+
# Load tools from any MCP server
|
125
|
+
tools = await load_mcp_tools(".mcp.json", ["search", "memory"])
|
126
|
+
|
127
|
+
# Use with ReAct reasoning
|
128
|
+
branch = Branch(chat_model=gpt4o, tools=tools)
|
129
|
+
result = await branch.ReAct(
|
130
|
+
instruct={"instruction": "Research recent AI developments"},
|
131
|
+
tools=["search_exa_search"],
|
132
|
+
max_extensions=3
|
133
|
+
)
|
134
|
+
```
|
135
|
+
|
136
|
+
- **Dynamic Discovery**: Auto-discover and register tools from MCP servers
|
137
|
+
- **Type Safety**: Full Pydantic validation for tool interactions
|
138
|
+
- **Connection Pooling**: Efficient resource management with automatic reuse
|
139
|
+
|
113
140
|
### Observability & Debugging
|
114
141
|
|
115
142
|
- Inspect messages:
|
@@ -0,0 +1,14 @@
|
|
1
|
+
{
|
2
|
+
"mcpServers": {
|
3
|
+
"search": {
|
4
|
+
"command": "/Users/lion/projects/lionagi/.venv/bin/python",
|
5
|
+
"args": [
|
6
|
+
"-m",
|
7
|
+
"khivemcp.cli",
|
8
|
+
"/Users/lion/projects/lionagi/cookbooks/using_mcp/search_group_config.json"
|
9
|
+
],
|
10
|
+
"timeout": 300,
|
11
|
+
"alwaysAllow": []
|
12
|
+
}
|
13
|
+
}
|
14
|
+
}
|
@@ -0,0 +1,190 @@
|
|
1
|
+
# Using MCP (Model Context Protocol) with LionAGI
|
2
|
+
|
3
|
+
This cookbook demonstrates how to integrate MCP servers with LionAGI for dynamic
|
4
|
+
tool discovery and execution.
|
5
|
+
|
6
|
+
## What is MCP?
|
7
|
+
|
8
|
+
The Model Context Protocol (MCP) is an open standard developed by Anthropic that
|
9
|
+
enables seamless integration between AI models and external tools/data sources.
|
10
|
+
It provides a unified protocol for:
|
11
|
+
|
12
|
+
- Dynamic tool discovery
|
13
|
+
- Standardized tool execution
|
14
|
+
- Connection pooling for efficient resource management
|
15
|
+
|
16
|
+
## Installation
|
17
|
+
|
18
|
+
```bash
|
19
|
+
pip install "lionagi[mcp]" khivemcp
|
20
|
+
```
|
21
|
+
|
22
|
+
## Quick Start
|
23
|
+
|
24
|
+
### 1. Configure Your MCP Server
|
25
|
+
|
26
|
+
Create a `.mcp.json` file to define your MCP servers:
|
27
|
+
|
28
|
+
```json
|
29
|
+
{
|
30
|
+
"mcpServers": {
|
31
|
+
"search": {
|
32
|
+
"command": "python",
|
33
|
+
"args": ["-m", "khivemcp.cli", "search_group_config.json"],
|
34
|
+
"timeout": 300
|
35
|
+
}
|
36
|
+
}
|
37
|
+
}
|
38
|
+
```
|
39
|
+
|
40
|
+
### 2. Define Request Wrappers
|
41
|
+
|
42
|
+
MCP tools expect requests wrapped in a specific format. Create Pydantic models
|
43
|
+
to handle this:
|
44
|
+
|
45
|
+
```python
|
46
|
+
from pydantic import BaseModel
|
47
|
+
from lionagi.service.third_party.exa_models import ExaSearchRequest
|
48
|
+
from lionagi.service.third_party.pplx_models import PerplexityChatRequest
|
49
|
+
|
50
|
+
class ExaRequest(BaseModel):
|
51
|
+
request: ExaSearchRequest
|
52
|
+
|
53
|
+
class PerplexityRequest(BaseModel):
|
54
|
+
request: PerplexityChatRequest
|
55
|
+
```
|
56
|
+
|
57
|
+
### 3. Load and Use MCP Tools
|
58
|
+
|
59
|
+
```python
|
60
|
+
from lionagi import Branch, iModel
|
61
|
+
from lionagi.protocols.action.manager import load_mcp_tools
|
62
|
+
|
63
|
+
# Load tools with Pydantic validation
|
64
|
+
tools = await load_mcp_tools(
|
65
|
+
".mcp.json",
|
66
|
+
server_names=["search"],
|
67
|
+
request_options_map={
|
68
|
+
"search": {
|
69
|
+
"exa_search": ExaRequest,
|
70
|
+
"perplexity_search": PerplexityRequest,
|
71
|
+
}
|
72
|
+
}
|
73
|
+
)
|
74
|
+
|
75
|
+
# Use with Branch for ReAct reasoning
|
76
|
+
branch = Branch(
|
77
|
+
chat_model=iModel(provider="openai", model="gpt-4.1-mini"),
|
78
|
+
tools=tools
|
79
|
+
)
|
80
|
+
|
81
|
+
result = await branch.ReAct(
|
82
|
+
instruct={
|
83
|
+
"instruction": "Research recent AI developments",
|
84
|
+
"context": {}
|
85
|
+
},
|
86
|
+
tools=["search_exa_search"],
|
87
|
+
max_extensions=3
|
88
|
+
)
|
89
|
+
```
|
90
|
+
|
91
|
+
## Files in This Cookbook
|
92
|
+
|
93
|
+
- **`.mcp.json`** - MCP server configuration
|
94
|
+
- **`search_group_config.json`** - Configuration for the search service group
|
95
|
+
- **`search_group.py`** - MCP server implementation with Exa and Perplexity
|
96
|
+
search
|
97
|
+
- **`react_mcp_with_schema.py`** - Complete example using MCP tools with ReAct
|
98
|
+
reasoning
|
99
|
+
|
100
|
+
## Key Features
|
101
|
+
|
102
|
+
### Dynamic Tool Discovery
|
103
|
+
|
104
|
+
MCP servers can be queried for available tools at runtime:
|
105
|
+
|
106
|
+
```python
|
107
|
+
from lionagi.protocols.action.manager import ActionManager
|
108
|
+
|
109
|
+
manager = ActionManager()
|
110
|
+
tools = await manager.register_mcp_server(
|
111
|
+
{"server": "search"},
|
112
|
+
update=True
|
113
|
+
)
|
114
|
+
```
|
115
|
+
|
116
|
+
### Connection Pooling
|
117
|
+
|
118
|
+
Efficient connection reuse across multiple tool invocations:
|
119
|
+
|
120
|
+
```python
|
121
|
+
from lionagi.service.connections.mcp.wrapper import MCPConnectionPool
|
122
|
+
|
123
|
+
# Connections are automatically pooled and reused
|
124
|
+
MCPConnectionPool.load_config(".mcp.json")
|
125
|
+
client = await MCPConnectionPool.get_client({"server": "search"})
|
126
|
+
```
|
127
|
+
|
128
|
+
### Type Safety with Pydantic
|
129
|
+
|
130
|
+
Full request/response validation using Pydantic models ensures type safety
|
131
|
+
throughout the pipeline.
|
132
|
+
|
133
|
+
## Advanced Configuration
|
134
|
+
|
135
|
+
### Environment Variables
|
136
|
+
|
137
|
+
Control MCP server logging and debugging:
|
138
|
+
|
139
|
+
```bash
|
140
|
+
export MCP_DEBUG=true # Enable debug mode
|
141
|
+
export LOG_LEVEL=ERROR # Set logging level
|
142
|
+
export FASTMCP_QUIET=true # Suppress FastMCP output
|
143
|
+
```
|
144
|
+
|
145
|
+
### Custom MCP Servers
|
146
|
+
|
147
|
+
Create your own MCP server by extending `ServiceGroup`:
|
148
|
+
|
149
|
+
```python
|
150
|
+
from khivemcp import ServiceGroup, operation
|
151
|
+
|
152
|
+
class MyServiceGroup(ServiceGroup):
|
153
|
+
@operation(name="my_tool", schema=MyRequestModel)
|
154
|
+
async def my_tool(self, request: MyRequestModel):
|
155
|
+
# Tool implementation
|
156
|
+
return {"result": "success"}
|
157
|
+
```
|
158
|
+
|
159
|
+
## Troubleshooting
|
160
|
+
|
161
|
+
### Common Issues
|
162
|
+
|
163
|
+
1. **Schema Mismatch**: Ensure your wrapper models correctly wrap the request
|
164
|
+
with a `request` field
|
165
|
+
2. **Server Not Found**: Check that your `.mcp.json` paths are correct
|
166
|
+
3. **Verbose Logging**: Set environment variables to suppress server output
|
167
|
+
|
168
|
+
### Debug Mode
|
169
|
+
|
170
|
+
Enable debug logging to troubleshoot issues:
|
171
|
+
|
172
|
+
```python
|
173
|
+
tools = await load_mcp_tools(
|
174
|
+
".mcp.json",
|
175
|
+
server_names=["search"],
|
176
|
+
debug=True # Enable debug mode
|
177
|
+
)
|
178
|
+
```
|
179
|
+
|
180
|
+
## Resources
|
181
|
+
|
182
|
+
- [MCP Specification](https://modelcontextprotocol.io)
|
183
|
+
- [FastMCP Documentation](https://gofastmcp.com)
|
184
|
+
- [KhiveMCP](https://github.com/khive-ai/khivemcp)
|
185
|
+
- [LionAGI Documentation](https://github.com/lion-agi/lionagi)
|
186
|
+
|
187
|
+
## License
|
188
|
+
|
189
|
+
This cookbook is part of the LionAGI project and follows the same Apache 2.0
|
190
|
+
license.
|
@@ -0,0 +1,102 @@
|
|
1
|
+
#!/usr/bin/env python3
|
2
|
+
"""
|
3
|
+
Test ReAct reasoning with MCP search tools and proper Pydantic schemas
|
4
|
+
"""
|
5
|
+
|
6
|
+
import asyncio
|
7
|
+
|
8
|
+
from pydantic import BaseModel
|
9
|
+
|
10
|
+
from lionagi import Branch, iModel
|
11
|
+
from lionagi.protocols.action.manager import load_mcp_tools
|
12
|
+
from lionagi.service.third_party.exa_models import ExaSearchRequest
|
13
|
+
from lionagi.service.third_party.pplx_models import PerplexityChatRequest
|
14
|
+
|
15
|
+
|
16
|
+
class ExaRequest(BaseModel):
|
17
|
+
request: ExaSearchRequest
|
18
|
+
|
19
|
+
|
20
|
+
class PerplexityRequest(BaseModel):
|
21
|
+
request: PerplexityChatRequest
|
22
|
+
|
23
|
+
|
24
|
+
async def test_react_with_mcp():
|
25
|
+
print("🦁 Testing ReAct with MCP Search Tools (with Pydantic schemas)")
|
26
|
+
print("=" * 60)
|
27
|
+
|
28
|
+
# 1. Load MCP search tools with proper Pydantic schemas
|
29
|
+
print("\n1. Loading MCP search tools with Pydantic validation...")
|
30
|
+
tools = await load_mcp_tools(
|
31
|
+
"/Users/lion/projects/lionagi/cookbooks/using_mcp/.mcp.json",
|
32
|
+
server_names=["search"],
|
33
|
+
request_options_map={
|
34
|
+
"search": {
|
35
|
+
"exa_search": ExaRequest,
|
36
|
+
"perplexity_search": PerplexityRequest,
|
37
|
+
}
|
38
|
+
},
|
39
|
+
)
|
40
|
+
print(f" ✅ Loaded {len(tools)} search tools with schemas:")
|
41
|
+
for tool in tools:
|
42
|
+
print(
|
43
|
+
f" - {tool.function} (has request_options: {tool.request_options is not None})"
|
44
|
+
)
|
45
|
+
|
46
|
+
# 2. Create a Branch with the tools
|
47
|
+
print("\n2. Creating Branch with gpt-4.1-mini...")
|
48
|
+
branch = Branch(
|
49
|
+
name="react_test",
|
50
|
+
chat_model=iModel(provider="openai", model="gpt-4.1-mini"),
|
51
|
+
tools=tools,
|
52
|
+
)
|
53
|
+
print(" ✅ Branch created")
|
54
|
+
|
55
|
+
# 3. Run ReAct reasoning
|
56
|
+
print("\n3. Running ReAct reasoning (max 3 extensions)...")
|
57
|
+
print(
|
58
|
+
" Question: What are the latest developments in Model Context Protocol (MCP)?"
|
59
|
+
)
|
60
|
+
print("\n Executing ReAct...")
|
61
|
+
|
62
|
+
try:
|
63
|
+
result = await branch.ReAct(
|
64
|
+
instruct={
|
65
|
+
"instruction": (
|
66
|
+
"Research the latest developments in Model Context Protocol (MCP). "
|
67
|
+
"Use the search tools to find recent information about MCP, "
|
68
|
+
"its features, and adoption by different platforms."
|
69
|
+
),
|
70
|
+
"context": {},
|
71
|
+
},
|
72
|
+
tools=["search_exa_search", "search_perplexity_search"],
|
73
|
+
max_extensions=3,
|
74
|
+
verbose=True,
|
75
|
+
)
|
76
|
+
|
77
|
+
print("\n4. ReAct Result:")
|
78
|
+
print("-" * 40)
|
79
|
+
if result:
|
80
|
+
# Print result content
|
81
|
+
if hasattr(result, "content"):
|
82
|
+
print(result.content)
|
83
|
+
else:
|
84
|
+
print(str(result))
|
85
|
+
print("-" * 40)
|
86
|
+
|
87
|
+
except Exception as e:
|
88
|
+
print(f"\n❌ ReAct failed: {e}")
|
89
|
+
import traceback
|
90
|
+
|
91
|
+
traceback.print_exc()
|
92
|
+
|
93
|
+
print("\n" + "=" * 60)
|
94
|
+
print("✅ Test Complete!")
|
95
|
+
print("\nKey improvements:")
|
96
|
+
print(" • Tools now have proper Pydantic schemas for validation")
|
97
|
+
print(" • Model knows exactly what parameters to provide")
|
98
|
+
print(" • Type safety and validation at runtime")
|
99
|
+
|
100
|
+
|
101
|
+
if __name__ == "__main__":
|
102
|
+
asyncio.run(test_react_with_mcp())
|
@@ -0,0 +1,80 @@
|
|
1
|
+
import logging
|
2
|
+
from typing import Literal
|
3
|
+
|
4
|
+
from dotenv import load_dotenv
|
5
|
+
from khivemcp import ServiceGroup, operation
|
6
|
+
|
7
|
+
from lionagi import iModel
|
8
|
+
from lionagi.service.connections.api_calling import APICalling
|
9
|
+
from lionagi.service.third_party.exa_models import ExaSearchRequest
|
10
|
+
from lionagi.service.third_party.pplx_models import PerplexityChatRequest
|
11
|
+
|
12
|
+
logger = logging.getLogger(__name__)
|
13
|
+
|
14
|
+
PROVIDERS = Literal["exa", "perplexity"]
|
15
|
+
|
16
|
+
|
17
|
+
class SearchServiceGroup(ServiceGroup):
|
18
|
+
def __init__(self, config: dict | None = None):
|
19
|
+
"""
|
20
|
+
Initialize the LLMServiceGroup.
|
21
|
+
"""
|
22
|
+
load_dotenv()
|
23
|
+
super().__init__(config=config)
|
24
|
+
logger.info(
|
25
|
+
f"[LLMServiceGroup] Initialized.",
|
26
|
+
)
|
27
|
+
self.imodels = {}
|
28
|
+
|
29
|
+
@operation(name="exa_search", schema=ExaSearchRequest)
|
30
|
+
async def exa_search(self, request: ExaSearchRequest):
|
31
|
+
"""Performs a search using Exa's search endpoint."""
|
32
|
+
if not "exa_search" in self.imodels:
|
33
|
+
self.imodels["exa_search"] = iModel(
|
34
|
+
provider="exa",
|
35
|
+
endpoint="search",
|
36
|
+
queue_capacity=5,
|
37
|
+
interval=1,
|
38
|
+
limit_requests=5,
|
39
|
+
api_key="EXA_API_KEY",
|
40
|
+
)
|
41
|
+
|
42
|
+
result: APICalling = await self.imodels["exa_search"].invoke(
|
43
|
+
**request.model_dump(exclude_none=True),
|
44
|
+
is_cached=True,
|
45
|
+
)
|
46
|
+
return {
|
47
|
+
"id": str(result.id),
|
48
|
+
"created_at": result.created_datetime.isoformat(),
|
49
|
+
"status": result.execution.status.value,
|
50
|
+
"duration": result.execution.duration,
|
51
|
+
"response": result.execution.response,
|
52
|
+
"error": result.execution.error,
|
53
|
+
}
|
54
|
+
|
55
|
+
@operation(name="perplexity_search", schema=PerplexityChatRequest)
|
56
|
+
async def perplexity_search(self, request: PerplexityChatRequest):
|
57
|
+
"""Performs a search using Perplexity's chat completion endpoint."""
|
58
|
+
if not "perplexity_search" in self.imodels:
|
59
|
+
self.imodels["perplexity_search"] = iModel(
|
60
|
+
provider="perplexity",
|
61
|
+
endpoint="chat",
|
62
|
+
interval=60,
|
63
|
+
limit_tokens=20000,
|
64
|
+
api_key="PERPLEXITY_API_KEY",
|
65
|
+
limit_requests=10,
|
66
|
+
)
|
67
|
+
|
68
|
+
imodel = self.imodels["perplexity_search"]
|
69
|
+
result: APICalling = await imodel.invoke(
|
70
|
+
**request.model_dump(exclude_none=True),
|
71
|
+
is_cached=True,
|
72
|
+
)
|
73
|
+
return {
|
74
|
+
"id": str(result.id),
|
75
|
+
"created_at": result.created_datetime.isoformat(),
|
76
|
+
"status": result.execution.status.value,
|
77
|
+
"duration": result.execution.duration,
|
78
|
+
"response": result.execution.response,
|
79
|
+
"error": result.execution.error,
|
80
|
+
}
|
@@ -6,7 +6,6 @@ import logging
|
|
6
6
|
|
7
7
|
from pydantic import BaseModel, Field
|
8
8
|
|
9
|
-
# Eager imports for commonly used components
|
10
9
|
from . import ln as ln
|
11
10
|
from .operations.node import Operation
|
12
11
|
from .service.imodel import iModel
|
@@ -35,6 +34,11 @@ def __getattr__(name: str):
|
|
35
34
|
|
36
35
|
_lazy_imports["Builder"] = Builder
|
37
36
|
return Builder
|
37
|
+
elif name == "load_mcp_tools":
|
38
|
+
from .protocols.action.manager import load_mcp_tools
|
39
|
+
|
40
|
+
_lazy_imports["load_mcp_tools"] = load_mcp_tools
|
41
|
+
return load_mcp_tools
|
38
42
|
|
39
43
|
raise AttributeError(f"module '{__name__}' has no attribute '{name}'")
|
40
44
|
|