lionagi 0.17.2__tar.gz → 0.17.3__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.3}/.github/workflows/ci.yml +1 -9
- {lionagi-0.17.2 → lionagi-0.17.3}/PKG-INFO +1 -1
- lionagi-0.17.3/cookbooks/using_mcp/.mcp.json +14 -0
- lionagi-0.17.3/cookbooks/using_mcp/README.md +190 -0
- lionagi-0.17.3/cookbooks/using_mcp/react_mcp_with_schema.py +102 -0
- lionagi-0.17.3/cookbooks/using_mcp/search_group.py +80 -0
- lionagi-0.17.3/cookbooks/using_mcp/search_group_config.json +6 -0
- lionagi-0.17.3/lionagi/protocols/action/manager.py +511 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/protocols/action/tool.py +45 -29
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/protocols/generic/pile.py +6 -1
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/protocols/messages/assistant_response.py +6 -0
- lionagi-0.17.3/lionagi/service/connections/mcp/wrapper.py +259 -0
- lionagi-0.17.3/lionagi/service/connections/providers/__init__.py +3 -0
- lionagi-0.17.3/lionagi/version.py +1 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/pyproject.toml +2 -1
- {lionagi-0.17.2 → lionagi-0.17.3}/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.3}/.coveragerc +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/.env.example +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/.github/FUNDING.yml +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/.github/dependabot.yml +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/.github/workflows/benchmarks.yml +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/.github/workflows/codeql.yml +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/.github/workflows/docs-deploy.yml +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/.github/workflows/refresh-bench-baselines.yml +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/.github/workflows/release.yml +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/.gitignore +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/.pre-commit-config.yaml +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/.python-version +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/CODE_OF_CONDUCT.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/CONTRIBUTING.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/LICENSE +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/README.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/assets/operation_builder.gif +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/benchmarks/README.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/benchmarks/baselines/.gitkeep +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/benchmarks/baselines/concurrency-asyncio.json +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/benchmarks/baselines/concurrency-trio.json +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/benchmarks/baselines/fuzzy.json +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/benchmarks/baselines/ln-asyncio.json +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/benchmarks/baselines/ln-trio.json +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/benchmarks/ci_compare.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/benchmarks/concurrency_bench.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/benchmarks/fuzzy_bench.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/benchmarks/ln_bench.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/cookbooks/001_branch_converse.ipynb +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/cookbooks/002_branch_interact.ipynb +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/cookbooks/003_branch_info.ipynb +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/cookbooks/004_conversation_patterns.ipynb +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/cookbooks/005_react_basics.ipynb +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/cookbooks/006_operation_graphs_claim_extraction.ipynb +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/cookbooks/007_fan_out_in.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/cookbooks/claude_proxy/README.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/cookbooks/claude_proxy/claude_code_proxy.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/cookbooks/claude_proxy/run_w_claude_code_proxy.ipynb +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/cookbooks/data/002_comedian.json +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/cookbooks/data/002_critic.json +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/cookbooks/data/006_lion_proof_ch2.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/cookbooks/using_claude_code.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/docs/DOCUMENTATION_STANDARDS.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/docs/advanced/custom-operations.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/docs/advanced/error-handling.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/docs/advanced/flow-composition.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/docs/advanced/index.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/docs/advanced/observability.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/docs/advanced/performance.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/docs/code-of-conduct.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/docs/comparisons/langgraph.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/docs/contributing.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/docs/cookbook/brainstorming.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/docs/cookbook/claim-extraction.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/docs/cookbook/code-review-crew.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/docs/cookbook/data-persistence.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/docs/cookbook/hr-automation.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/docs/cookbook/index.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/docs/cookbook/research-synthesis.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/docs/core-concepts/index.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/docs/core-concepts/lionagi-philosophy.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/docs/core-concepts/messages-and-memory.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/docs/core-concepts/models-and-providers.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/docs/core-concepts/operations.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/docs/core-concepts/sessions-and-branches.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/docs/core-concepts/tools-and-functions.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/docs/for-ai-agents/claude-code-usage.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/docs/for-ai-agents/index.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/docs/for-ai-agents/orchestration-guide.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/docs/for-ai-agents/pattern-selection.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/docs/for-ai-agents/self-improvement.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/docs/includes/abbreviations.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/docs/index.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/docs/integrations/databases.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/docs/integrations/dspy-optimization.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/docs/integrations/index.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/docs/integrations/llamaindex-rag.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/docs/integrations/llm-providers.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/docs/integrations/mcp-servers.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/docs/integrations/tools.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/docs/integrations/vector-stores.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/docs/marketing/language-interoperability-manifesto.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/docs/migration/from-autogen.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/docs/migration/from-crewai.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/docs/migration/from-langchain.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/docs/migration/index.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/docs/patterns/conditional-flows.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/docs/patterns/fan-out-in.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/docs/patterns/index.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/docs/patterns/react-with-rag.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/docs/patterns/sequential-analysis.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/docs/patterns/tournament-validation.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/docs/problem-statement.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/docs/quickstart/claude-code-integration.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/docs/quickstart/index.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/docs/quickstart/installation.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/docs/quickstart/orchestration-first.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/docs/quickstart/your-first-flow.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/docs/reference/api/index.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/docs/reference/changelog.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/docs/reference/troubleshooting.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/docs/stylesheets/extra.css +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/docs/thinking-in-lionagi/branches-as-agents.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/docs/thinking-in-lionagi/builder-pattern.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/docs/thinking-in-lionagi/graphs-over-chains.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/docs/thinking-in-lionagi/index.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/docs/thinking-in-lionagi/why-lionagi.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/__init__.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/_class_registry.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/_errors.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/_types.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/adapters/__init__.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/adapters/_utils.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/adapters/async_postgres_adapter.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/config.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/fields/__init__.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/fields/action.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/fields/base.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/fields/code.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/fields/file.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/fields/instruct.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/fields/reason.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/fields/research.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/libs/__init__.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/libs/file/__init__.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/libs/file/_utils.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/libs/file/chunk.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/libs/file/concat.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/libs/file/concat_files.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/libs/file/file_ops.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/libs/file/process.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/libs/file/save.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/libs/schema/__init__.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/libs/schema/as_readable.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/libs/schema/extract_code_block.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/libs/schema/extract_docstring.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/libs/schema/function_to_schema.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/libs/schema/load_pydantic_model_from_schema.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/libs/validate/__init__.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/libs/validate/common_field_validators.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/libs/validate/to_num.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/libs/validate/validate_boolean.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/ln/__init__.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/ln/_async_call.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/ln/_hash.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/ln/_json_dump.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/ln/_list_call.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/ln/_to_list.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/ln/_utils.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/ln/concurrency/__init__.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/ln/concurrency/_compat.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/ln/concurrency/cancel.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/ln/concurrency/errors.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/ln/concurrency/patterns.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/ln/concurrency/primitives.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/ln/concurrency/resource_tracker.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/ln/concurrency/task.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/ln/concurrency/throttle.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/ln/concurrency/utils.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/ln/fuzzy/__init__.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/ln/fuzzy/_extract_json.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/ln/fuzzy/_fuzzy_json.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/ln/fuzzy/_fuzzy_match.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/ln/fuzzy/_fuzzy_validate.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/ln/fuzzy/_string_similarity.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/ln/fuzzy/_to_dict.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/ln/types.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/models/__init__.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/models/field_model.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/models/hashable_model.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/models/model_params.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/models/operable_model.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/models/schema_model.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/operations/ReAct/ReAct.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/operations/ReAct/__init__.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/operations/ReAct/utils.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/operations/__init__.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/operations/_act/__init__.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/operations/_act/act.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/operations/_visualize_graph.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/operations/brainstorm/__init__.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/operations/brainstorm/brainstorm.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/operations/brainstorm/prompt.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/operations/builder.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/operations/chat/__init__.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/operations/chat/chat.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/operations/communicate/__init__.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/operations/communicate/communicate.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/operations/flow.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/operations/instruct/__init__.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/operations/instruct/instruct.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/operations/interpret/__init__.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/operations/interpret/interpret.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/operations/manager.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/operations/node.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/operations/operate/__init__.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/operations/operate/operate.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/operations/parse/__init__.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/operations/parse/parse.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/operations/plan/__init__.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/operations/plan/plan.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/operations/plan/prompt.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/operations/select/__init__.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/operations/select/select.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/operations/select/utils.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/operations/types.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/operations/utils.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/protocols/__init__.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/protocols/_concepts.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/protocols/action/__init__.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/protocols/action/function_calling.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/protocols/contracts.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/protocols/forms/__init__.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/protocols/forms/base.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/protocols/forms/flow.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/protocols/forms/form.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/protocols/forms/report.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/protocols/generic/__init__.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/protocols/generic/element.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/protocols/generic/event.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/protocols/generic/log.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/protocols/generic/processor.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/protocols/generic/progression.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/protocols/graph/__init__.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/protocols/graph/edge.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/protocols/graph/graph.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/protocols/graph/node.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/protocols/ids.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/protocols/mail/__init__.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/protocols/mail/exchange.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/protocols/mail/mail.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/protocols/mail/mailbox.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/protocols/mail/manager.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/protocols/mail/package.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/protocols/messages/__init__.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/protocols/messages/action_request.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/protocols/messages/action_response.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/protocols/messages/base.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/protocols/messages/instruction.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/protocols/messages/manager.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/protocols/messages/message.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/protocols/messages/system.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/protocols/messages/templates/README.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/protocols/messages/templates/action_request.jinja2 +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/protocols/messages/templates/action_response.jinja2 +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/protocols/messages/templates/assistant_response.jinja2 +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/protocols/messages/templates/instruction_message.jinja2 +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/protocols/messages/templates/system_message.jinja2 +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/protocols/messages/templates/tool_schemas.jinja2 +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/protocols/operatives/__init__.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/protocols/operatives/operative.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/protocols/operatives/step.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/protocols/types.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/py.typed +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/service/__init__.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/service/connections/__init__.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/service/connections/api_calling.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/service/connections/endpoint.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/service/connections/endpoint_config.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/service/connections/header_factory.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/service/connections/match_endpoint.py +0 -0
- {lionagi-0.17.2/lionagi/service/connections/providers → lionagi-0.17.3/lionagi/service/connections/mcp}/__init__.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/service/connections/providers/anthropic_.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/service/connections/providers/claude_code_cli.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/service/connections/providers/exa_.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/service/connections/providers/nvidia_nim_.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/service/connections/providers/oai_.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/service/connections/providers/ollama_.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/service/connections/providers/perplexity_.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/service/connections/providers/types.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/service/hooks/__init__.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/service/hooks/_types.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/service/hooks/_utils.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/service/hooks/hook_event.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/service/hooks/hook_registry.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/service/imodel.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/service/manager.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/service/rate_limited_processor.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/service/resilience.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/service/third_party/README.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/service/third_party/__init__.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/service/third_party/anthropic_models.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/service/third_party/claude_code.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/service/third_party/exa_models.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/service/third_party/openai_model_names.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/service/third_party/pplx_models.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/service/token_calculator.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/service/types.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/session/__init__.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/session/branch.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/session/prompts.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/session/session.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/settings.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/tools/__init__.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/tools/base.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/tools/file/__init__.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/tools/file/reader.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/tools/types.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/lionagi/utils.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/main.py +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/mkdocs.yml +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/scripts/README.md +0 -0
- {lionagi-0.17.2 → lionagi-0.17.3}/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: |
|
@@ -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
|
+
}
|