alita-sdk 0.3.447__tar.gz → 0.3.449__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.
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/PKG-INFO +2 -1
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/toolkits/mcp.py +66 -298
- alita_sdk-0.3.449/alita_sdk/runtime/tools/mcp_remote_tool.py +166 -0
- alita_sdk-0.3.449/alita_sdk/runtime/utils/mcp_sse_client.py +347 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk.egg-info/PKG-INFO +2 -1
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk.egg-info/SOURCES.txt +1 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk.egg-info/requires.txt +1 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/pyproject.toml +2 -2
- alita_sdk-0.3.447/alita_sdk/runtime/tools/mcp_remote_tool.py +0 -307
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/LICENSE +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/README.md +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/community/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/community/utils.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/configurations/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/configurations/ado.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/configurations/azure_search.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/configurations/bigquery.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/configurations/bitbucket.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/configurations/browser.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/configurations/carrier.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/configurations/confluence.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/configurations/delta_lake.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/configurations/embedding.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/configurations/figma.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/configurations/github.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/configurations/gitlab.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/configurations/google_places.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/configurations/jira.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/configurations/pgvector.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/configurations/postman.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/configurations/qtest.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/configurations/rally.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/configurations/report_portal.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/configurations/salesforce.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/configurations/service_now.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/configurations/sharepoint.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/configurations/slack.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/configurations/sonar.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/configurations/sql.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/configurations/testio.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/configurations/testrail.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/configurations/xray.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/configurations/zephyr.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/configurations/zephyr_enterprise.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/configurations/zephyr_essential.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/clients/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/clients/artifact.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/clients/client.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/clients/datasource.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/clients/mcp_discovery.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/clients/mcp_manager.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/clients/prompt.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/clients/sandbox_client.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/langchain/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/langchain/agents/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/langchain/agents/xml_chat.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/langchain/assistant.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/langchain/chat_message_template.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/langchain/constants.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/langchain/document_loaders/AlitaBDDScenariosLoader.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/langchain/document_loaders/AlitaCSVLoader.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/langchain/document_loaders/AlitaConfluenceLoader.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/langchain/document_loaders/AlitaDirectoryLoader.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/langchain/document_loaders/AlitaDocxMammothLoader.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/langchain/document_loaders/AlitaExcelLoader.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/langchain/document_loaders/AlitaGitRepoLoader.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/langchain/document_loaders/AlitaImageLoader.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/langchain/document_loaders/AlitaJSONLoader.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/langchain/document_loaders/AlitaJiraLoader.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/langchain/document_loaders/AlitaMarkdownLoader.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/langchain/document_loaders/AlitaPDFLoader.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/langchain/document_loaders/AlitaPowerPointLoader.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/langchain/document_loaders/AlitaPythonLoader.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/langchain/document_loaders/AlitaQtestLoader.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/langchain/document_loaders/AlitaTableLoader.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/langchain/document_loaders/AlitaTextLoader.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/langchain/document_loaders/ImageParser.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/langchain/document_loaders/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/langchain/document_loaders/constants.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/langchain/document_loaders/utils.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/langchain/indexer.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/langchain/interfaces/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/langchain/interfaces/kwextractor.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/langchain/interfaces/llm_processor.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/langchain/interfaces/loaders.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/langchain/interfaces/splitters.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/langchain/langraph_agent.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/langchain/mixedAgentParser.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/langchain/mixedAgentRenderes.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/langchain/retrievers/AlitaRetriever.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/langchain/retrievers/VectorstoreRetriever.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/langchain/retrievers/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/langchain/store_manager.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/langchain/tools/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/langchain/tools/bdd_parser/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/langchain/tools/bdd_parser/bdd_exceptions.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/langchain/tools/bdd_parser/bdd_parser.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/langchain/tools/bdd_parser/feature_types.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/langchain/tools/bdd_parser/parser.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/langchain/tools/git.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/langchain/tools/log.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/langchain/tools/quota.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/langchain/tools/state.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/langchain/tools/utils.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/langchain/tools/vector.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/langchain/utils.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/llms/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/llms/preloaded.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/models/mcp_models.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/toolkits/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/toolkits/application.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/toolkits/artifact.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/toolkits/configurations.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/toolkits/datasource.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/toolkits/prompt.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/toolkits/subgraph.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/toolkits/tools.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/toolkits/vectorstore.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/tools/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/tools/agent.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/tools/application.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/tools/artifact.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/tools/datasource.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/tools/echo.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/tools/function.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/tools/graph.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/tools/image_generation.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/tools/indexer_tool.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/tools/llm.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/tools/loop.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/tools/loop_output.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/tools/mcp_inspect_tool.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/tools/mcp_server_tool.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/tools/pgvector_search.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/tools/prompt.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/tools/router.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/tools/sandbox.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/tools/tool.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/tools/vectorstore.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/tools/vectorstore_base.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/utils/AlitaCallback.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/utils/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/utils/constants.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/utils/evaluate.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/utils/logging.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/utils/mcp_oauth.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/utils/save_dataframe.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/utils/streamlit.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/utils/toolkit_runtime.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/utils/toolkit_utils.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/runtime/utils/utils.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/ado/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/ado/repos/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/ado/repos/repos_wrapper.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/ado/test_plan/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/ado/test_plan/test_plan_wrapper.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/ado/utils.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/ado/wiki/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/ado/wiki/ado_wrapper.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/ado/work_item/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/ado/work_item/ado_wrapper.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/advanced_jira_mining/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/advanced_jira_mining/data_mining_wrapper.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/aws/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/aws/delta_lake/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/aws/delta_lake/api_wrapper.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/aws/delta_lake/schemas.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/aws/delta_lake/tool.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/azure_ai/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/azure_ai/search/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/azure_ai/search/api_wrapper.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/base/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/base/tool.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/base_indexer_toolkit.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/bitbucket/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/bitbucket/api_wrapper.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/bitbucket/bitbucket_constants.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/bitbucket/cloud_api_wrapper.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/browser/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/browser/crawler.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/browser/duck_duck_go_search.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/browser/google_search_rag.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/browser/utils.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/browser/wiki.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/carrier/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/carrier/api_wrapper.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/carrier/backend_reports_tool.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/carrier/backend_tests_tool.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/carrier/cancel_ui_test_tool.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/carrier/carrier_sdk.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/carrier/create_ui_excel_report_tool.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/carrier/create_ui_test_tool.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/carrier/excel_reporter.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/carrier/lighthouse_excel_reporter.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/carrier/run_ui_test_tool.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/carrier/tickets_tool.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/carrier/tools.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/carrier/ui_reports_tool.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/carrier/update_ui_test_schedule_tool.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/carrier/utils.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/chunkers/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/chunkers/code/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/chunkers/code/codeparser.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/chunkers/code/constants.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/chunkers/code/treesitter/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/chunkers/code/treesitter/treesitter.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/chunkers/code/treesitter/treesitter_c.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/chunkers/code/treesitter/treesitter_cpp.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/chunkers/code/treesitter/treesitter_cs.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/chunkers/code/treesitter/treesitter_go.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/chunkers/code/treesitter/treesitter_hs.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/chunkers/code/treesitter/treesitter_java.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/chunkers/code/treesitter/treesitter_js.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/chunkers/code/treesitter/treesitter_kt.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/chunkers/code/treesitter/treesitter_py.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/chunkers/code/treesitter/treesitter_rb.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/chunkers/code/treesitter/treesitter_registry.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/chunkers/code/treesitter/treesitter_rs.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/chunkers/code/treesitter/treesitter_ts.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/chunkers/models.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/chunkers/sematic/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/chunkers/sematic/base.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/chunkers/sematic/json_chunker.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/chunkers/sematic/markdown_chunker.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/chunkers/sematic/proposal_chunker.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/chunkers/sematic/statistical_chunker.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/chunkers/utils.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/cloud/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/cloud/aws/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/cloud/aws/api_wrapper.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/cloud/azure/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/cloud/azure/api_wrapper.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/cloud/gcp/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/cloud/gcp/api_wrapper.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/cloud/k8s/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/cloud/k8s/api_wrapper.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/code/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/code/linter/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/code/linter/api_wrapper.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/code/loaders/codesearcher.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/code/sonar/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/code/sonar/api_wrapper.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/code_indexer_toolkit.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/confluence/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/confluence/api_wrapper.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/confluence/loader.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/confluence/utils.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/custom_open_api/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/custom_open_api/api_wrapper.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/elastic/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/elastic/api_wrapper.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/elitea_base.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/figma/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/figma/api_wrapper.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/github/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/github/api_wrapper.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/github/github_client.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/github/graphql_client_wrapper.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/github/schemas.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/github/tool.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/github/tool_prompts.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/gitlab/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/gitlab/api_wrapper.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/gitlab/tools.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/gitlab/utils.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/gitlab_org/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/gitlab_org/api_wrapper.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/gmail/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/gmail/gmail_wrapper.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/gmail/utils.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/google/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/google/bigquery/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/google/bigquery/api_wrapper.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/google/bigquery/schemas.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/google/bigquery/tool.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/google_places/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/google_places/api_wrapper.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/jira/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/jira/api_wrapper.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/keycloak/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/keycloak/api_wrapper.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/llm/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/llm/img_utils.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/llm/llm_utils.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/localgit/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/localgit/local_git.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/localgit/tool.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/memory/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/non_code_indexer_toolkit.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/ocr/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/ocr/api_wrapper.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/ocr/text_detection.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/openapi/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/pandas/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/pandas/api_wrapper.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/pandas/dataframe/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/pandas/dataframe/errors.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/pandas/dataframe/executor/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/pandas/dataframe/executor/code_environment.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/pandas/dataframe/executor/code_executor.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/pandas/dataframe/generator/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/pandas/dataframe/generator/base.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/pandas/dataframe/generator/code_cleaning.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/pandas/dataframe/generator/code_validator.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/pandas/dataframe/prompts.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/pandas/dataframe/serializer.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/pandas/dataframe/utils.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/pandas/statsmodels/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/pandas/statsmodels/base_stats.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/pandas/statsmodels/descriptive.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/pandas/statsmodels/hypothesis_testing.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/pandas/statsmodels/regression.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/postman/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/postman/api_wrapper.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/postman/postman_analysis.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/pptx/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/pptx/pptx_wrapper.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/qtest/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/qtest/api_wrapper.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/qtest/tool.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/rally/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/rally/api_wrapper.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/report_portal/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/report_portal/api_wrapper.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/report_portal/report_portal_client.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/salesforce/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/salesforce/api_wrapper.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/salesforce/model.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/servicenow/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/servicenow/api_wrapper.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/servicenow/servicenow_client.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/sharepoint/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/sharepoint/api_wrapper.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/sharepoint/authorization_helper.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/sharepoint/utils.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/slack/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/slack/api_wrapper.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/sql/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/sql/api_wrapper.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/sql/models.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/testio/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/testio/api_wrapper.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/testrail/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/testrail/api_wrapper.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/utils/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/utils/available_tools_decorator.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/utils/content_parser.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/vector_adapters/VectorStoreAdapter.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/vector_adapters/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/xray/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/xray/api_wrapper.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/yagmail/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/yagmail/yagmail_wrapper.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/zephyr/Zephyr.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/zephyr/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/zephyr/api_wrapper.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/zephyr/rest_client.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/zephyr_enterprise/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/zephyr_enterprise/api_wrapper.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/zephyr_enterprise/zephyr_enterprise.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/zephyr_essential/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/zephyr_essential/api_wrapper.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/zephyr_essential/client.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/zephyr_scale/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/zephyr_scale/api_wrapper.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/zephyr_squad/__init__.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/zephyr_squad/api_wrapper.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk/tools/zephyr_squad/zephyr_squad_cloud_client.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk.egg-info/dependency_links.txt +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/alita_sdk.egg-info/top_level.txt +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/setup.cfg +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/tests/test_ado_analysis.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/tests/test_github_analysis.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/tests/test_gitlab_analysis.py +0 -0
- {alita_sdk-0.3.447 → alita_sdk-0.3.449}/tests/test_jira_analysis.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: alita_sdk
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.449
|
|
4
4
|
Summary: SDK for building langchain agents using resources from Alita
|
|
5
5
|
Author-email: Artem Rozumenko <artyom.rozumenko@gmail.com>, Mikalai Biazruchka <mikalai_biazruchka@epam.com>, Roman Mitusov <roman_mitusov@epam.com>, Ivan Krakhmaliuk <lifedj27@gmail.com>, Artem Dubrovskiy <ad13box@gmail.com>
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -24,6 +24,7 @@ Requires-Dist: fastapi==0.115.9
|
|
|
24
24
|
Requires-Dist: httpcore==1.0.7
|
|
25
25
|
Requires-Dist: urllib3>=2
|
|
26
26
|
Requires-Dist: certifi==2024.8.30
|
|
27
|
+
Requires-Dist: aiohttp>=3.9.0
|
|
27
28
|
Provides-Extra: runtime
|
|
28
29
|
Requires-Dist: streamlit>=1.28.0; extra == "runtime"
|
|
29
30
|
Requires-Dist: langchain_core<0.4.0,>=0.3.76; extra == "runtime"
|
|
@@ -7,6 +7,7 @@ Following MCP specification: https://modelcontextprotocol.io/specification/2025-
|
|
|
7
7
|
import logging
|
|
8
8
|
import re
|
|
9
9
|
import requests
|
|
10
|
+
import asyncio
|
|
10
11
|
from typing import List, Optional, Any, Dict, Literal, ClassVar, Union
|
|
11
12
|
|
|
12
13
|
from langchain_core.tools import BaseToolkit, BaseTool
|
|
@@ -17,6 +18,7 @@ from ..tools.mcp_remote_tool import McpRemoteTool
|
|
|
17
18
|
from ..tools.mcp_inspect_tool import McpInspectTool
|
|
18
19
|
from ...tools.utils import TOOLKIT_SPLITTER, clean_string
|
|
19
20
|
from ..models.mcp_models import McpConnectionConfig
|
|
21
|
+
from ..utils.mcp_sse_client import McpSseClient
|
|
20
22
|
from ..utils.mcp_oauth import (
|
|
21
23
|
McpAuthorizationRequired,
|
|
22
24
|
canonical_resource,
|
|
@@ -402,12 +404,9 @@ class McpToolkit(BaseToolkit):
|
|
|
402
404
|
]
|
|
403
405
|
|
|
404
406
|
# Create BaseTool instances from discovered metadata
|
|
405
|
-
# Use session_id from
|
|
406
|
-
# If discovery returned a session_id, it means a new session was created
|
|
407
|
-
# Log it so UI can capture and store it
|
|
407
|
+
# Use session_id from frontend (passed via connection_config)
|
|
408
408
|
if session_id:
|
|
409
|
-
logger.info(f"[MCP Session] Using
|
|
410
|
-
logger.info(f"[MCP Session] Session created - server: {canonical_resource(connection_config.url)}, session_id: {session_id}")
|
|
409
|
+
logger.info(f"[MCP Session] Using session_id from frontend: {session_id}")
|
|
411
410
|
|
|
412
411
|
for tool_metadata in tool_metadata_list:
|
|
413
412
|
server_tool = cls._create_tool_from_dict(
|
|
@@ -462,67 +461,76 @@ class McpToolkit(BaseToolkit):
|
|
|
462
461
|
timeout: int
|
|
463
462
|
) -> List[Dict[str, Any]]:
|
|
464
463
|
"""
|
|
465
|
-
|
|
464
|
+
Discover tools and prompts from MCP server using SSE client.
|
|
466
465
|
Returns list of tool/prompt dictionaries with name, description, and inputSchema.
|
|
467
466
|
Prompts are converted to tools that can be invoked.
|
|
468
467
|
"""
|
|
469
|
-
all_tools = []
|
|
470
|
-
|
|
471
|
-
# Check if we have a session_id from UI (passed via connection_config)
|
|
472
|
-
# If not, we'll try discovery without session first, and create one if needed
|
|
473
468
|
session_id = connection_config.session_id
|
|
474
469
|
|
|
475
|
-
|
|
476
|
-
|
|
470
|
+
if not session_id:
|
|
471
|
+
logger.warning(f"[MCP Session] No session_id provided for '{toolkit_name}' - server may require it")
|
|
472
|
+
logger.warning(f"[MCP Session] Frontend should generate a UUID and include it with mcp_tokens")
|
|
473
|
+
|
|
474
|
+
# Run async discovery in sync context
|
|
477
475
|
try:
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
toolkit_name=toolkit_name,
|
|
481
|
-
connection_config=connection_config,
|
|
482
|
-
timeout=timeout,
|
|
483
|
-
session_id=session_id
|
|
484
|
-
)
|
|
485
|
-
except Exception as discovery_error:
|
|
486
|
-
# Check if error is due to missing session
|
|
487
|
-
if "Missing sessionId" in str(discovery_error) and not session_id:
|
|
488
|
-
logger.info(f"[MCP Session] Server requires session for discovery, initializing...")
|
|
489
|
-
# Try to initialize session if we have OAuth headers
|
|
490
|
-
session_id = cls._initialize_mcp_session(
|
|
476
|
+
all_tools = asyncio.run(
|
|
477
|
+
cls._discover_tools_async(
|
|
491
478
|
toolkit_name=toolkit_name,
|
|
492
479
|
connection_config=connection_config,
|
|
493
|
-
timeout=timeout
|
|
494
|
-
extra_headers=connection_config.headers # Use headers from connection_config
|
|
480
|
+
timeout=timeout
|
|
495
481
|
)
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
all_tools
|
|
513
|
-
|
|
482
|
+
)
|
|
483
|
+
return all_tools, session_id
|
|
484
|
+
except Exception as e:
|
|
485
|
+
logger.error(f"[MCP SSE] Discovery failed for '{toolkit_name}': {e}")
|
|
486
|
+
raise
|
|
487
|
+
|
|
488
|
+
@classmethod
|
|
489
|
+
async def _discover_tools_async(
|
|
490
|
+
cls,
|
|
491
|
+
toolkit_name: str,
|
|
492
|
+
connection_config: McpConnectionConfig,
|
|
493
|
+
timeout: int
|
|
494
|
+
) -> List[Dict[str, Any]]:
|
|
495
|
+
"""
|
|
496
|
+
Async implementation of tool discovery using SSE client.
|
|
497
|
+
"""
|
|
498
|
+
all_tools = []
|
|
499
|
+
session_id = connection_config.session_id
|
|
500
|
+
|
|
501
|
+
if not session_id:
|
|
502
|
+
logger.error(f"[MCP SSE] session_id is required for SSE servers")
|
|
503
|
+
raise ValueError("session_id is required. Frontend must generate UUID.")
|
|
504
|
+
|
|
505
|
+
logger.info(f"[MCP SSE] Discovering from {connection_config.url} with session {session_id}")
|
|
514
506
|
|
|
515
|
-
#
|
|
507
|
+
# Prepare headers
|
|
508
|
+
headers = {}
|
|
509
|
+
if connection_config.headers:
|
|
510
|
+
headers.update(connection_config.headers)
|
|
511
|
+
|
|
512
|
+
# Create SSE client
|
|
513
|
+
client = McpSseClient(
|
|
514
|
+
url=connection_config.url,
|
|
515
|
+
session_id=session_id,
|
|
516
|
+
headers=headers,
|
|
517
|
+
timeout=timeout
|
|
518
|
+
)
|
|
519
|
+
|
|
520
|
+
# Initialize MCP session
|
|
521
|
+
await client.initialize()
|
|
522
|
+
logger.info(f"[MCP SSE] Session initialized for '{toolkit_name}'")
|
|
523
|
+
|
|
524
|
+
# Discover tools
|
|
525
|
+
tools = await client.list_tools()
|
|
526
|
+
all_tools.extend(tools)
|
|
527
|
+
logger.info(f"[MCP SSE] Discovered {len(tools)} tools from '{toolkit_name}'")
|
|
528
|
+
|
|
529
|
+
# Discover prompts
|
|
516
530
|
try:
|
|
517
|
-
|
|
518
|
-
endpoint="prompts/list",
|
|
519
|
-
toolkit_name=toolkit_name,
|
|
520
|
-
connection_config=connection_config,
|
|
521
|
-
timeout=timeout,
|
|
522
|
-
session_id=session_id
|
|
523
|
-
)
|
|
531
|
+
prompts = await client.list_prompts()
|
|
524
532
|
# Convert prompts to tool format
|
|
525
|
-
for prompt in
|
|
533
|
+
for prompt in prompts:
|
|
526
534
|
prompt_tool = {
|
|
527
535
|
"name": f"prompt_{prompt.get('name', 'unnamed')}",
|
|
528
536
|
"description": prompt.get('description', f"Execute prompt: {prompt.get('name')}"),
|
|
@@ -547,252 +555,12 @@ class McpToolkit(BaseToolkit):
|
|
|
547
555
|
"_mcp_prompt_name": prompt.get('name')
|
|
548
556
|
}
|
|
549
557
|
all_tools.append(prompt_tool)
|
|
550
|
-
logger.info(f"Discovered {len(
|
|
558
|
+
logger.info(f"[MCP SSE] Discovered {len(prompts)} prompts from '{toolkit_name}'")
|
|
551
559
|
except Exception as e:
|
|
552
|
-
logger.warning(f"Failed to discover prompts
|
|
560
|
+
logger.warning(f"[MCP SSE] Failed to discover prompts: {e}")
|
|
553
561
|
|
|
554
|
-
logger.info(f"Total discovered {len(all_tools)}
|
|
555
|
-
return all_tools
|
|
556
|
-
|
|
557
|
-
@classmethod
|
|
558
|
-
def _initialize_mcp_session(
|
|
559
|
-
cls,
|
|
560
|
-
toolkit_name: str,
|
|
561
|
-
connection_config: McpConnectionConfig,
|
|
562
|
-
timeout: int,
|
|
563
|
-
extra_headers: Optional[Dict[str, str]] = None
|
|
564
|
-
) -> Optional[str]:
|
|
565
|
-
"""
|
|
566
|
-
Initialize an MCP session for stateful SSE servers.
|
|
567
|
-
Returns sessionId if successful, None if server doesn't require sessions.
|
|
568
|
-
|
|
569
|
-
Note: This session should be stored by the caller (e.g., UI sessionStorage)
|
|
570
|
-
and passed back for subsequent requests. Sessions should NOT be cached
|
|
571
|
-
on the backend for security reasons (multi-tenant environment).
|
|
572
|
-
|
|
573
|
-
Args:
|
|
574
|
-
toolkit_name: Name of the toolkit
|
|
575
|
-
connection_config: MCP connection configuration
|
|
576
|
-
timeout: Request timeout in seconds
|
|
577
|
-
extra_headers: Additional headers (e.g., Authorization) to include
|
|
578
|
-
"""
|
|
579
|
-
import time
|
|
580
|
-
|
|
581
|
-
mcp_request = {
|
|
582
|
-
"jsonrpc": "2.0",
|
|
583
|
-
"id": f"initialize_{int(time.time())}",
|
|
584
|
-
"method": "initialize",
|
|
585
|
-
"params": {
|
|
586
|
-
"protocolVersion": "2024-11-05",
|
|
587
|
-
"capabilities": {
|
|
588
|
-
"roots": {"listChanged": True},
|
|
589
|
-
"sampling": {}
|
|
590
|
-
},
|
|
591
|
-
"clientInfo": {
|
|
592
|
-
"name": "Alita MCP Client",
|
|
593
|
-
"version": "1.0.0"
|
|
594
|
-
}
|
|
595
|
-
}
|
|
596
|
-
}
|
|
597
|
-
|
|
598
|
-
headers = {
|
|
599
|
-
"Content-Type": "application/json",
|
|
600
|
-
"Accept": "application/json, text/event-stream"
|
|
601
|
-
}
|
|
602
|
-
if connection_config.headers:
|
|
603
|
-
headers.update(connection_config.headers)
|
|
604
|
-
if extra_headers:
|
|
605
|
-
headers.update(extra_headers)
|
|
606
|
-
logger.debug(f"[MCP Session] Added extra headers: {list(extra_headers.keys())}")
|
|
607
|
-
|
|
608
|
-
try:
|
|
609
|
-
logger.info(f"[MCP Session] Attempting to initialize session for {connection_config.url}")
|
|
610
|
-
logger.debug(f"[MCP Session] Initialize request: {mcp_request}")
|
|
611
|
-
response = requests.post(
|
|
612
|
-
connection_config.url,
|
|
613
|
-
json=mcp_request,
|
|
614
|
-
headers=headers,
|
|
615
|
-
timeout=timeout
|
|
616
|
-
)
|
|
617
|
-
|
|
618
|
-
logger.info(f"[MCP Session] Initialize response status: {response.status_code}")
|
|
619
|
-
if response.status_code == 200:
|
|
620
|
-
# Parse the response to extract sessionId
|
|
621
|
-
content_type = response.headers.get('Content-Type', '')
|
|
622
|
-
logger.debug(f"[MCP Session] Response Content-Type: {content_type}")
|
|
623
|
-
|
|
624
|
-
if 'text/event-stream' in content_type:
|
|
625
|
-
data = cls._parse_sse_response(response.text)
|
|
626
|
-
elif 'application/json' in content_type:
|
|
627
|
-
data = response.json()
|
|
628
|
-
else:
|
|
629
|
-
logger.warning(f"[MCP Session] Unexpected Content-Type during initialize: {content_type}")
|
|
630
|
-
logger.debug(f"[MCP Session] Response text: {response.text[:500]}")
|
|
631
|
-
return None
|
|
632
|
-
|
|
633
|
-
logger.debug(f"[MCP Session] Parsed response: {data}")
|
|
634
|
-
|
|
635
|
-
# Extract sessionId from response
|
|
636
|
-
result = data.get("result", {})
|
|
637
|
-
session_id = result.get("sessionId")
|
|
638
|
-
if session_id:
|
|
639
|
-
logger.info(f"[MCP Session] ✓ Session initialized for '{toolkit_name}': {session_id}")
|
|
640
|
-
logger.info(f"[MCP Session] This sessionId should be stored by the caller and sent back for subsequent requests")
|
|
641
|
-
return session_id
|
|
642
|
-
else:
|
|
643
|
-
logger.info(f"[MCP Session] No sessionId in initialize response for '{toolkit_name}' - server may not require sessions")
|
|
644
|
-
logger.debug(f"[MCP Session] Full result: {result}")
|
|
645
|
-
return None
|
|
646
|
-
else:
|
|
647
|
-
logger.warning(f"[MCP Session] Initialize returned {response.status_code} for '{toolkit_name}' - server may not support sessions")
|
|
648
|
-
logger.debug(f"[MCP Session] Response: {response.text[:500]}")
|
|
649
|
-
return None
|
|
650
|
-
|
|
651
|
-
except Exception as e:
|
|
652
|
-
logger.warning(f"[MCP Session] Failed to initialize MCP session for '{toolkit_name}': {e} - proceeding without session")
|
|
653
|
-
import traceback
|
|
654
|
-
logger.debug(f"[MCP Session] Traceback: {traceback.format_exc()}")
|
|
655
|
-
return None
|
|
656
|
-
|
|
657
|
-
@classmethod
|
|
658
|
-
def _discover_mcp_endpoint(
|
|
659
|
-
cls,
|
|
660
|
-
endpoint: str,
|
|
661
|
-
toolkit_name: str,
|
|
662
|
-
connection_config: McpConnectionConfig,
|
|
663
|
-
timeout: int,
|
|
664
|
-
session_id: Optional[str] = None
|
|
665
|
-
) -> List[Dict[str, Any]]:
|
|
666
|
-
"""
|
|
667
|
-
Discover items from a specific MCP endpoint (tools/list or prompts/list).
|
|
668
|
-
Returns list of dictionaries.
|
|
669
|
-
"""
|
|
670
|
-
import time
|
|
671
|
-
|
|
672
|
-
# MCP protocol request
|
|
673
|
-
mcp_request = {
|
|
674
|
-
"jsonrpc": "2.0",
|
|
675
|
-
"id": f"discover_{endpoint.replace('/', '_')}_{int(time.time())}",
|
|
676
|
-
"method": endpoint,
|
|
677
|
-
"params": {}
|
|
678
|
-
}
|
|
679
|
-
|
|
680
|
-
headers = {
|
|
681
|
-
"Content-Type": "application/json",
|
|
682
|
-
"Accept": "application/json, text/event-stream"
|
|
683
|
-
}
|
|
684
|
-
if connection_config.headers:
|
|
685
|
-
headers.update(connection_config.headers)
|
|
686
|
-
|
|
687
|
-
# Add sessionId to URL if provided (for stateful SSE servers)
|
|
688
|
-
url = connection_config.url
|
|
689
|
-
if session_id:
|
|
690
|
-
separator = '&' if '?' in url else '?'
|
|
691
|
-
url = f"{url}{separator}sessionId={session_id}"
|
|
692
|
-
logger.info(f"[MCP Session] Using session {session_id} for {endpoint} request")
|
|
693
|
-
else:
|
|
694
|
-
logger.debug(f"[MCP Session] No session ID available for {endpoint} request - server may not require sessions")
|
|
695
|
-
|
|
696
|
-
try:
|
|
697
|
-
logger.debug(f"Sending MCP {endpoint} request to {url}")
|
|
698
|
-
response = requests.post(
|
|
699
|
-
url,
|
|
700
|
-
json=mcp_request,
|
|
701
|
-
headers=headers,
|
|
702
|
-
timeout=timeout
|
|
703
|
-
)
|
|
704
|
-
|
|
705
|
-
auth_header = response.headers.get('WWW-Authenticate', '')
|
|
706
|
-
if response.status_code == 401:
|
|
707
|
-
resource_metadata_url = extract_resource_metadata_url(auth_header, connection_config.url)
|
|
708
|
-
metadata = fetch_resource_metadata(resource_metadata_url, timeout=timeout) if resource_metadata_url else None
|
|
709
|
-
|
|
710
|
-
# If we couldn't get metadata from the resource_metadata endpoint,
|
|
711
|
-
# infer authorization servers from the WWW-Authenticate header and server URL
|
|
712
|
-
if not metadata or not metadata.get('authorization_servers'):
|
|
713
|
-
inferred_servers = infer_authorization_servers_from_realm(auth_header, connection_config.url)
|
|
714
|
-
if inferred_servers:
|
|
715
|
-
if not metadata:
|
|
716
|
-
metadata = {}
|
|
717
|
-
metadata['authorization_servers'] = inferred_servers
|
|
718
|
-
logger.info(f"Inferred authorization servers for {connection_config.url}: {inferred_servers}")
|
|
719
|
-
|
|
720
|
-
# Fetch OAuth authorization server metadata from the inferred server
|
|
721
|
-
# This avoids CORS issues in the frontend
|
|
722
|
-
from alita_sdk.runtime.utils.mcp_oauth import fetch_oauth_authorization_server_metadata
|
|
723
|
-
auth_server_metadata = fetch_oauth_authorization_server_metadata(inferred_servers[0], timeout=timeout)
|
|
724
|
-
if auth_server_metadata:
|
|
725
|
-
metadata['oauth_authorization_server'] = auth_server_metadata
|
|
726
|
-
logger.info(f"Fetched OAuth metadata for {inferred_servers[0]}")
|
|
727
|
-
|
|
728
|
-
raise McpAuthorizationRequired(
|
|
729
|
-
message=f"MCP server {connection_config.url} requires OAuth authorization",
|
|
730
|
-
server_url=canonical_resource(connection_config.url),
|
|
731
|
-
resource_metadata_url=resource_metadata_url,
|
|
732
|
-
www_authenticate=auth_header,
|
|
733
|
-
resource_metadata=metadata,
|
|
734
|
-
status=response.status_code,
|
|
735
|
-
tool_name=toolkit_name,
|
|
736
|
-
)
|
|
737
|
-
|
|
738
|
-
if response.status_code != 200:
|
|
739
|
-
logger.error(f"MCP server returned non-200 status: {response.status_code}")
|
|
740
|
-
raise Exception(f"HTTP {response.status_code}: {response.text}")
|
|
741
|
-
|
|
742
|
-
# Check content type and parse accordingly
|
|
743
|
-
content_type = response.headers.get('Content-Type', '')
|
|
744
|
-
|
|
745
|
-
if 'text/event-stream' in content_type:
|
|
746
|
-
# Parse SSE (Server-Sent Events) format
|
|
747
|
-
data = cls._parse_sse_response(response.text)
|
|
748
|
-
elif 'application/json' in content_type:
|
|
749
|
-
# Parse regular JSON
|
|
750
|
-
try:
|
|
751
|
-
data = response.json()
|
|
752
|
-
except ValueError as json_err:
|
|
753
|
-
raise Exception(f"Invalid JSON response: {json_err}. Response text: {response.text[:200]}")
|
|
754
|
-
else:
|
|
755
|
-
raise Exception(f"Unexpected Content-Type: {content_type}. Response: {response.text[:200]}")
|
|
756
|
-
|
|
757
|
-
if "error" in data:
|
|
758
|
-
raise Exception(f"MCP Error: {data['error']}")
|
|
759
|
-
|
|
760
|
-
# Parse MCP response - different endpoints return different keys
|
|
761
|
-
result = data.get("result", {})
|
|
762
|
-
if endpoint == "tools/list":
|
|
763
|
-
return result.get("tools", [])
|
|
764
|
-
elif endpoint == "prompts/list":
|
|
765
|
-
return result.get("prompts", [])
|
|
766
|
-
else:
|
|
767
|
-
return result.get("items", [])
|
|
768
|
-
|
|
769
|
-
except Exception as e:
|
|
770
|
-
logger.error(f"Failed to discover from {endpoint} on MCP toolkit '{toolkit_name}': {e}")
|
|
771
|
-
raise
|
|
772
|
-
|
|
773
|
-
@staticmethod
|
|
774
|
-
def _parse_sse_response(sse_text: str) -> Dict[str, Any]:
|
|
775
|
-
"""
|
|
776
|
-
Parse Server-Sent Events (SSE) format response.
|
|
777
|
-
SSE format: event: message\ndata: {json}\n\n
|
|
778
|
-
"""
|
|
779
|
-
import json
|
|
780
|
-
|
|
781
|
-
lines = sse_text.strip().split('\n')
|
|
782
|
-
data_line = None
|
|
783
|
-
|
|
784
|
-
for line in lines:
|
|
785
|
-
if line.startswith('data:'):
|
|
786
|
-
data_line = line[5:].strip() # Remove 'data:' prefix
|
|
787
|
-
break
|
|
788
|
-
|
|
789
|
-
if not data_line:
|
|
790
|
-
raise Exception(f"No data found in SSE response: {sse_text[:200]}")
|
|
791
|
-
|
|
792
|
-
try:
|
|
793
|
-
return json.loads(data_line)
|
|
794
|
-
except json.JSONDecodeError as e:
|
|
795
|
-
raise Exception(f"Failed to parse SSE data as JSON: {e}. Data: {data_line[:200]}")
|
|
562
|
+
logger.info(f"[MCP SSE] Total discovered {len(all_tools)} items from '{toolkit_name}'")
|
|
563
|
+
return all_tools
|
|
796
564
|
|
|
797
565
|
@classmethod
|
|
798
566
|
def _create_tool_from_dict(
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
"""
|
|
2
|
+
MCP Remote Tool for direct HTTP/SSE invocation.
|
|
3
|
+
This tool is used for remote MCP servers accessed via HTTP/SSE.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import asyncio
|
|
7
|
+
import json
|
|
8
|
+
import logging
|
|
9
|
+
import time
|
|
10
|
+
import uuid
|
|
11
|
+
from concurrent.futures import ThreadPoolExecutor
|
|
12
|
+
from typing import Any, Dict, Optional
|
|
13
|
+
|
|
14
|
+
from .mcp_server_tool import McpServerTool
|
|
15
|
+
from pydantic import Field
|
|
16
|
+
from ..utils.mcp_oauth import (
|
|
17
|
+
McpAuthorizationRequired,
|
|
18
|
+
canonical_resource,
|
|
19
|
+
extract_resource_metadata_url,
|
|
20
|
+
fetch_resource_metadata_async,
|
|
21
|
+
infer_authorization_servers_from_realm,
|
|
22
|
+
)
|
|
23
|
+
from ..utils.mcp_sse_client import McpSseClient
|
|
24
|
+
|
|
25
|
+
logger = logging.getLogger(__name__)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class McpRemoteTool(McpServerTool):
|
|
29
|
+
"""
|
|
30
|
+
Tool for invoking remote MCP server tools via HTTP/SSE.
|
|
31
|
+
Extends McpServerTool and overrides _run to use direct HTTP calls instead of client.mcp_tool_call.
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
# Remote MCP connection details
|
|
35
|
+
server_url: str = Field(..., description="URL of the remote MCP server")
|
|
36
|
+
server_headers: Optional[Dict[str, str]] = Field(default=None, description="HTTP headers for authentication")
|
|
37
|
+
original_tool_name: Optional[str] = Field(default=None, description="Original tool name from MCP server (before optimization)")
|
|
38
|
+
is_prompt: bool = False # Flag to indicate if this is a prompt tool
|
|
39
|
+
prompt_name: Optional[str] = None # Original prompt name if this is a prompt
|
|
40
|
+
session_id: Optional[str] = Field(default=None, description="MCP session ID for stateful SSE servers")
|
|
41
|
+
|
|
42
|
+
def model_post_init(self, __context: Any) -> None:
|
|
43
|
+
"""Update metadata with session info after model initialization."""
|
|
44
|
+
super().model_post_init(__context)
|
|
45
|
+
self._update_metadata_with_session()
|
|
46
|
+
|
|
47
|
+
def _update_metadata_with_session(self):
|
|
48
|
+
"""Update the metadata dict with current session information."""
|
|
49
|
+
if self.session_id:
|
|
50
|
+
if self.metadata is None:
|
|
51
|
+
self.metadata = {}
|
|
52
|
+
self.metadata.update({
|
|
53
|
+
'mcp_session_id': self.session_id,
|
|
54
|
+
'mcp_server_url': canonical_resource(self.server_url)
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
def __getstate__(self):
|
|
58
|
+
"""Custom serialization for pickle compatibility."""
|
|
59
|
+
state = super().__getstate__()
|
|
60
|
+
# Ensure headers are serializable
|
|
61
|
+
if 'server_headers' in state and state['server_headers'] is not None:
|
|
62
|
+
state['server_headers'] = dict(state['server_headers'])
|
|
63
|
+
return state
|
|
64
|
+
|
|
65
|
+
def _run(self, *args, **kwargs):
|
|
66
|
+
"""
|
|
67
|
+
Execute the MCP tool via direct HTTP/SSE call to the remote server.
|
|
68
|
+
Overrides the parent method to avoid using client.mcp_tool_call.
|
|
69
|
+
"""
|
|
70
|
+
try:
|
|
71
|
+
# Always create a new event loop for sync context
|
|
72
|
+
with ThreadPoolExecutor() as executor:
|
|
73
|
+
future = executor.submit(self._run_in_new_loop, kwargs)
|
|
74
|
+
return future.result(timeout=self.tool_timeout_sec)
|
|
75
|
+
except McpAuthorizationRequired:
|
|
76
|
+
# Bubble up so LangChain can surface a tool error with useful metadata
|
|
77
|
+
raise
|
|
78
|
+
except Exception as e:
|
|
79
|
+
logger.error(f"Error executing remote MCP tool '{self.name}': {e}")
|
|
80
|
+
return f"Error executing tool: {e}"
|
|
81
|
+
|
|
82
|
+
def _run_in_new_loop(self, kwargs: Dict[str, Any]) -> str:
|
|
83
|
+
"""Run the async tool invocation in a new event loop."""
|
|
84
|
+
return asyncio.run(self._execute_remote_tool(kwargs))
|
|
85
|
+
|
|
86
|
+
async def _execute_remote_tool(self, kwargs: Dict[str, Any]) -> str:
|
|
87
|
+
"""Execute the actual remote MCP tool call using SSE client."""
|
|
88
|
+
from ...tools.utils import TOOLKIT_SPLITTER
|
|
89
|
+
|
|
90
|
+
# Check for session_id requirement
|
|
91
|
+
if not self.session_id:
|
|
92
|
+
logger.error(f"[MCP Session] Missing session_id for tool '{self.name}'")
|
|
93
|
+
raise Exception("sessionId required. Frontend must generate UUID and send with mcp_tokens.")
|
|
94
|
+
|
|
95
|
+
# Use the original tool name from discovery for MCP server invocation
|
|
96
|
+
tool_name_for_server = self.original_tool_name
|
|
97
|
+
if not tool_name_for_server:
|
|
98
|
+
tool_name_for_server = self.name.rsplit(TOOLKIT_SPLITTER, 1)[-1] if TOOLKIT_SPLITTER in self.name else self.name
|
|
99
|
+
logger.warning(f"original_tool_name not set for '{self.name}', using extracted: {tool_name_for_server}")
|
|
100
|
+
|
|
101
|
+
logger.info(f"[MCP SSE] Executing tool '{tool_name_for_server}' with session {self.session_id}")
|
|
102
|
+
|
|
103
|
+
try:
|
|
104
|
+
# Prepare headers
|
|
105
|
+
headers = {}
|
|
106
|
+
if self.server_headers:
|
|
107
|
+
headers.update(self.server_headers)
|
|
108
|
+
|
|
109
|
+
# Create SSE client
|
|
110
|
+
client = McpSseClient(
|
|
111
|
+
url=self.server_url,
|
|
112
|
+
session_id=self.session_id,
|
|
113
|
+
headers=headers,
|
|
114
|
+
timeout=self.tool_timeout_sec
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
# Execute tool call via SSE
|
|
118
|
+
result = await client.call_tool(tool_name_for_server, kwargs)
|
|
119
|
+
|
|
120
|
+
# Format the result
|
|
121
|
+
if isinstance(result, dict):
|
|
122
|
+
# Check for content array (common in MCP responses)
|
|
123
|
+
if "content" in result:
|
|
124
|
+
content_items = result["content"]
|
|
125
|
+
if isinstance(content_items, list):
|
|
126
|
+
# Extract text from content items
|
|
127
|
+
text_parts = []
|
|
128
|
+
for item in content_items:
|
|
129
|
+
if isinstance(item, dict):
|
|
130
|
+
if item.get("type") == "text" and "text" in item:
|
|
131
|
+
text_parts.append(item["text"])
|
|
132
|
+
elif "text" in item:
|
|
133
|
+
text_parts.append(item["text"])
|
|
134
|
+
else:
|
|
135
|
+
text_parts.append(json.dumps(item))
|
|
136
|
+
else:
|
|
137
|
+
text_parts.append(str(item))
|
|
138
|
+
return "\n".join(text_parts)
|
|
139
|
+
|
|
140
|
+
# Return formatted JSON if no content field
|
|
141
|
+
return json.dumps(result, indent=2)
|
|
142
|
+
|
|
143
|
+
# Return as string for other types
|
|
144
|
+
return str(result)
|
|
145
|
+
|
|
146
|
+
except Exception as e:
|
|
147
|
+
logger.error(f"[MCP SSE] Tool execution failed: {e}", exc_info=True)
|
|
148
|
+
raise
|
|
149
|
+
|
|
150
|
+
def _parse_sse(self, text: str) -> Dict[str, Any]:
|
|
151
|
+
"""Parse Server-Sent Events (SSE) format response."""
|
|
152
|
+
for line in text.split('\n'):
|
|
153
|
+
line = line.strip()
|
|
154
|
+
if line.startswith('data:'):
|
|
155
|
+
json_str = line[5:].strip()
|
|
156
|
+
return json.loads(json_str)
|
|
157
|
+
raise ValueError("No data found in SSE response")
|
|
158
|
+
|
|
159
|
+
def get_session_metadata(self) -> dict:
|
|
160
|
+
"""Return session metadata to be included in tool responses."""
|
|
161
|
+
if self.session_id:
|
|
162
|
+
return {
|
|
163
|
+
'mcp_session_id': self.session_id,
|
|
164
|
+
'mcp_server_url': canonical_resource(self.server_url)
|
|
165
|
+
}
|
|
166
|
+
return {}
|