aip-agents-binary 0.6.4__py3-none-any.whl
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.
- aip_agents/__init__.py +65 -0
- aip_agents/__init__.pyi +19 -0
- aip_agents/a2a/__init__.py +19 -0
- aip_agents/a2a/__init__.pyi +3 -0
- aip_agents/a2a/server/__init__.py +10 -0
- aip_agents/a2a/server/__init__.pyi +4 -0
- aip_agents/a2a/server/base_executor.py +1086 -0
- aip_agents/a2a/server/base_executor.pyi +73 -0
- aip_agents/a2a/server/google_adk_executor.py +198 -0
- aip_agents/a2a/server/google_adk_executor.pyi +51 -0
- aip_agents/a2a/server/langflow_executor.py +180 -0
- aip_agents/a2a/server/langflow_executor.pyi +43 -0
- aip_agents/a2a/server/langgraph_executor.py +270 -0
- aip_agents/a2a/server/langgraph_executor.pyi +47 -0
- aip_agents/a2a/types.py +232 -0
- aip_agents/a2a/types.pyi +132 -0
- aip_agents/agent/__init__.py +27 -0
- aip_agents/agent/__init__.pyi +9 -0
- aip_agents/agent/base_agent.py +970 -0
- aip_agents/agent/base_agent.pyi +221 -0
- aip_agents/agent/base_langgraph_agent.py +3037 -0
- aip_agents/agent/base_langgraph_agent.pyi +233 -0
- aip_agents/agent/google_adk_agent.py +926 -0
- aip_agents/agent/google_adk_agent.pyi +141 -0
- aip_agents/agent/google_adk_constants.py +6 -0
- aip_agents/agent/google_adk_constants.pyi +3 -0
- aip_agents/agent/hitl/__init__.py +24 -0
- aip_agents/agent/hitl/__init__.pyi +6 -0
- aip_agents/agent/hitl/config.py +28 -0
- aip_agents/agent/hitl/config.pyi +15 -0
- aip_agents/agent/hitl/langgraph_hitl_mixin.py +515 -0
- aip_agents/agent/hitl/langgraph_hitl_mixin.pyi +42 -0
- aip_agents/agent/hitl/manager.py +532 -0
- aip_agents/agent/hitl/manager.pyi +200 -0
- aip_agents/agent/hitl/models.py +18 -0
- aip_agents/agent/hitl/models.pyi +3 -0
- aip_agents/agent/hitl/prompt/__init__.py +9 -0
- aip_agents/agent/hitl/prompt/__init__.pyi +4 -0
- aip_agents/agent/hitl/prompt/base.py +42 -0
- aip_agents/agent/hitl/prompt/base.pyi +24 -0
- aip_agents/agent/hitl/prompt/deferred.py +73 -0
- aip_agents/agent/hitl/prompt/deferred.pyi +30 -0
- aip_agents/agent/hitl/registry.py +149 -0
- aip_agents/agent/hitl/registry.pyi +101 -0
- aip_agents/agent/interface.py +138 -0
- aip_agents/agent/interface.pyi +81 -0
- aip_agents/agent/interfaces.py +65 -0
- aip_agents/agent/interfaces.pyi +44 -0
- aip_agents/agent/langflow_agent.py +464 -0
- aip_agents/agent/langflow_agent.pyi +133 -0
- aip_agents/agent/langgraph_memory_enhancer_agent.py +767 -0
- aip_agents/agent/langgraph_memory_enhancer_agent.pyi +50 -0
- aip_agents/agent/langgraph_react_agent.py +2856 -0
- aip_agents/agent/langgraph_react_agent.pyi +170 -0
- aip_agents/agent/system_instruction_context.py +34 -0
- aip_agents/agent/system_instruction_context.pyi +13 -0
- aip_agents/clients/__init__.py +10 -0
- aip_agents/clients/__init__.pyi +4 -0
- aip_agents/clients/langflow/__init__.py +10 -0
- aip_agents/clients/langflow/__init__.pyi +4 -0
- aip_agents/clients/langflow/client.py +477 -0
- aip_agents/clients/langflow/client.pyi +140 -0
- aip_agents/clients/langflow/types.py +18 -0
- aip_agents/clients/langflow/types.pyi +7 -0
- aip_agents/constants.py +23 -0
- aip_agents/constants.pyi +7 -0
- aip_agents/credentials/manager.py +132 -0
- aip_agents/examples/__init__.py +5 -0
- aip_agents/examples/__init__.pyi +0 -0
- aip_agents/examples/compare_streaming_client.py +783 -0
- aip_agents/examples/compare_streaming_client.pyi +48 -0
- aip_agents/examples/compare_streaming_server.py +142 -0
- aip_agents/examples/compare_streaming_server.pyi +18 -0
- aip_agents/examples/hello_world_a2a_google_adk_client.py +49 -0
- aip_agents/examples/hello_world_a2a_google_adk_client.pyi +9 -0
- aip_agents/examples/hello_world_a2a_google_adk_client_agent.py +48 -0
- aip_agents/examples/hello_world_a2a_google_adk_client_agent.pyi +9 -0
- aip_agents/examples/hello_world_a2a_google_adk_client_streaming.py +60 -0
- aip_agents/examples/hello_world_a2a_google_adk_client_streaming.pyi +9 -0
- aip_agents/examples/hello_world_a2a_google_adk_server.py +79 -0
- aip_agents/examples/hello_world_a2a_google_adk_server.pyi +15 -0
- aip_agents/examples/hello_world_a2a_langchain_client.py +39 -0
- aip_agents/examples/hello_world_a2a_langchain_client.pyi +5 -0
- aip_agents/examples/hello_world_a2a_langchain_client_agent.py +39 -0
- aip_agents/examples/hello_world_a2a_langchain_client_agent.pyi +5 -0
- aip_agents/examples/hello_world_a2a_langchain_client_lm_invoker.py +37 -0
- aip_agents/examples/hello_world_a2a_langchain_client_lm_invoker.pyi +5 -0
- aip_agents/examples/hello_world_a2a_langchain_client_streaming.py +41 -0
- aip_agents/examples/hello_world_a2a_langchain_client_streaming.pyi +5 -0
- aip_agents/examples/hello_world_a2a_langchain_reference_client_streaming.py +60 -0
- aip_agents/examples/hello_world_a2a_langchain_reference_client_streaming.pyi +5 -0
- aip_agents/examples/hello_world_a2a_langchain_reference_server.py +105 -0
- aip_agents/examples/hello_world_a2a_langchain_reference_server.pyi +15 -0
- aip_agents/examples/hello_world_a2a_langchain_server.py +79 -0
- aip_agents/examples/hello_world_a2a_langchain_server.pyi +15 -0
- aip_agents/examples/hello_world_a2a_langchain_server_lm_invoker.py +78 -0
- aip_agents/examples/hello_world_a2a_langchain_server_lm_invoker.pyi +15 -0
- aip_agents/examples/hello_world_a2a_langflow_client.py +83 -0
- aip_agents/examples/hello_world_a2a_langflow_client.pyi +9 -0
- aip_agents/examples/hello_world_a2a_langflow_server.py +82 -0
- aip_agents/examples/hello_world_a2a_langflow_server.pyi +14 -0
- aip_agents/examples/hello_world_a2a_langgraph_artifact_client.py +73 -0
- aip_agents/examples/hello_world_a2a_langgraph_artifact_client.pyi +5 -0
- aip_agents/examples/hello_world_a2a_langgraph_artifact_client_streaming.py +76 -0
- aip_agents/examples/hello_world_a2a_langgraph_artifact_client_streaming.pyi +5 -0
- aip_agents/examples/hello_world_a2a_langgraph_artifact_server.py +92 -0
- aip_agents/examples/hello_world_a2a_langgraph_artifact_server.pyi +16 -0
- aip_agents/examples/hello_world_a2a_langgraph_client.py +54 -0
- aip_agents/examples/hello_world_a2a_langgraph_client.pyi +9 -0
- aip_agents/examples/hello_world_a2a_langgraph_client_agent.py +54 -0
- aip_agents/examples/hello_world_a2a_langgraph_client_agent.pyi +9 -0
- aip_agents/examples/hello_world_a2a_langgraph_client_agent_lm_invoker.py +32 -0
- aip_agents/examples/hello_world_a2a_langgraph_client_agent_lm_invoker.pyi +2 -0
- aip_agents/examples/hello_world_a2a_langgraph_client_streaming.py +50 -0
- aip_agents/examples/hello_world_a2a_langgraph_client_streaming.pyi +9 -0
- aip_agents/examples/hello_world_a2a_langgraph_client_streaming_lm_invoker.py +44 -0
- aip_agents/examples/hello_world_a2a_langgraph_client_streaming_lm_invoker.pyi +5 -0
- aip_agents/examples/hello_world_a2a_langgraph_client_streaming_tool_streaming.py +92 -0
- aip_agents/examples/hello_world_a2a_langgraph_client_streaming_tool_streaming.pyi +5 -0
- aip_agents/examples/hello_world_a2a_langgraph_server.py +84 -0
- aip_agents/examples/hello_world_a2a_langgraph_server.pyi +14 -0
- aip_agents/examples/hello_world_a2a_langgraph_server_lm_invoker.py +79 -0
- aip_agents/examples/hello_world_a2a_langgraph_server_lm_invoker.pyi +15 -0
- aip_agents/examples/hello_world_a2a_langgraph_server_tool_streaming.py +132 -0
- aip_agents/examples/hello_world_a2a_langgraph_server_tool_streaming.pyi +15 -0
- aip_agents/examples/hello_world_a2a_mcp_langgraph.py +196 -0
- aip_agents/examples/hello_world_a2a_mcp_langgraph.pyi +48 -0
- aip_agents/examples/hello_world_a2a_three_level_agent_hierarchy_client.py +244 -0
- aip_agents/examples/hello_world_a2a_three_level_agent_hierarchy_client.pyi +48 -0
- aip_agents/examples/hello_world_a2a_three_level_agent_hierarchy_server.py +251 -0
- aip_agents/examples/hello_world_a2a_three_level_agent_hierarchy_server.pyi +45 -0
- aip_agents/examples/hello_world_a2a_with_metadata_langchain_client.py +57 -0
- aip_agents/examples/hello_world_a2a_with_metadata_langchain_client.pyi +5 -0
- aip_agents/examples/hello_world_a2a_with_metadata_langchain_server_lm_invoker.py +80 -0
- aip_agents/examples/hello_world_a2a_with_metadata_langchain_server_lm_invoker.pyi +15 -0
- aip_agents/examples/hello_world_google_adk.py +41 -0
- aip_agents/examples/hello_world_google_adk.pyi +5 -0
- aip_agents/examples/hello_world_google_adk_mcp_http.py +34 -0
- aip_agents/examples/hello_world_google_adk_mcp_http.pyi +5 -0
- aip_agents/examples/hello_world_google_adk_mcp_http_stream.py +40 -0
- aip_agents/examples/hello_world_google_adk_mcp_http_stream.pyi +5 -0
- aip_agents/examples/hello_world_google_adk_mcp_sse.py +44 -0
- aip_agents/examples/hello_world_google_adk_mcp_sse.pyi +5 -0
- aip_agents/examples/hello_world_google_adk_mcp_sse_stream.py +48 -0
- aip_agents/examples/hello_world_google_adk_mcp_sse_stream.pyi +5 -0
- aip_agents/examples/hello_world_google_adk_mcp_stdio.py +44 -0
- aip_agents/examples/hello_world_google_adk_mcp_stdio.pyi +5 -0
- aip_agents/examples/hello_world_google_adk_mcp_stdio_stream.py +48 -0
- aip_agents/examples/hello_world_google_adk_mcp_stdio_stream.pyi +5 -0
- aip_agents/examples/hello_world_google_adk_stream.py +44 -0
- aip_agents/examples/hello_world_google_adk_stream.pyi +5 -0
- aip_agents/examples/hello_world_langchain.py +28 -0
- aip_agents/examples/hello_world_langchain.pyi +5 -0
- aip_agents/examples/hello_world_langchain_lm_invoker.py +15 -0
- aip_agents/examples/hello_world_langchain_lm_invoker.pyi +2 -0
- aip_agents/examples/hello_world_langchain_mcp_http.py +34 -0
- aip_agents/examples/hello_world_langchain_mcp_http.pyi +5 -0
- aip_agents/examples/hello_world_langchain_mcp_http_interactive.py +130 -0
- aip_agents/examples/hello_world_langchain_mcp_http_interactive.pyi +16 -0
- aip_agents/examples/hello_world_langchain_mcp_http_stream.py +42 -0
- aip_agents/examples/hello_world_langchain_mcp_http_stream.pyi +5 -0
- aip_agents/examples/hello_world_langchain_mcp_multi_server.py +155 -0
- aip_agents/examples/hello_world_langchain_mcp_multi_server.pyi +18 -0
- aip_agents/examples/hello_world_langchain_mcp_sse.py +34 -0
- aip_agents/examples/hello_world_langchain_mcp_sse.pyi +5 -0
- aip_agents/examples/hello_world_langchain_mcp_sse_stream.py +40 -0
- aip_agents/examples/hello_world_langchain_mcp_sse_stream.pyi +5 -0
- aip_agents/examples/hello_world_langchain_mcp_stdio.py +30 -0
- aip_agents/examples/hello_world_langchain_mcp_stdio.pyi +5 -0
- aip_agents/examples/hello_world_langchain_mcp_stdio_stream.py +41 -0
- aip_agents/examples/hello_world_langchain_mcp_stdio_stream.pyi +5 -0
- aip_agents/examples/hello_world_langchain_stream.py +36 -0
- aip_agents/examples/hello_world_langchain_stream.pyi +5 -0
- aip_agents/examples/hello_world_langchain_stream_lm_invoker.py +39 -0
- aip_agents/examples/hello_world_langchain_stream_lm_invoker.pyi +5 -0
- aip_agents/examples/hello_world_langflow_agent.py +163 -0
- aip_agents/examples/hello_world_langflow_agent.pyi +35 -0
- aip_agents/examples/hello_world_langgraph.py +39 -0
- aip_agents/examples/hello_world_langgraph.pyi +5 -0
- aip_agents/examples/hello_world_langgraph_gl_connector_twitter.py +44 -0
- aip_agents/examples/hello_world_langgraph_gl_connector_twitter.pyi +5 -0
- aip_agents/examples/hello_world_langgraph_mcp_http.py +31 -0
- aip_agents/examples/hello_world_langgraph_mcp_http.pyi +5 -0
- aip_agents/examples/hello_world_langgraph_mcp_http_stream.py +34 -0
- aip_agents/examples/hello_world_langgraph_mcp_http_stream.pyi +5 -0
- aip_agents/examples/hello_world_langgraph_mcp_sse.py +35 -0
- aip_agents/examples/hello_world_langgraph_mcp_sse.pyi +5 -0
- aip_agents/examples/hello_world_langgraph_mcp_sse_stream.py +50 -0
- aip_agents/examples/hello_world_langgraph_mcp_sse_stream.pyi +5 -0
- aip_agents/examples/hello_world_langgraph_mcp_stdio.py +35 -0
- aip_agents/examples/hello_world_langgraph_mcp_stdio.pyi +5 -0
- aip_agents/examples/hello_world_langgraph_mcp_stdio_stream.py +50 -0
- aip_agents/examples/hello_world_langgraph_mcp_stdio_stream.pyi +5 -0
- aip_agents/examples/hello_world_langgraph_stream.py +43 -0
- aip_agents/examples/hello_world_langgraph_stream.pyi +5 -0
- aip_agents/examples/hello_world_langgraph_stream_lm_invoker.py +37 -0
- aip_agents/examples/hello_world_langgraph_stream_lm_invoker.pyi +5 -0
- aip_agents/examples/hello_world_model_switch_cli.py +210 -0
- aip_agents/examples/hello_world_model_switch_cli.pyi +30 -0
- aip_agents/examples/hello_world_multi_agent_adk.py +75 -0
- aip_agents/examples/hello_world_multi_agent_adk.pyi +6 -0
- aip_agents/examples/hello_world_multi_agent_langchain.py +54 -0
- aip_agents/examples/hello_world_multi_agent_langchain.pyi +5 -0
- aip_agents/examples/hello_world_multi_agent_langgraph.py +66 -0
- aip_agents/examples/hello_world_multi_agent_langgraph.pyi +5 -0
- aip_agents/examples/hello_world_multi_agent_langgraph_lm_invoker.py +69 -0
- aip_agents/examples/hello_world_multi_agent_langgraph_lm_invoker.pyi +5 -0
- aip_agents/examples/hello_world_pii_logger.py +21 -0
- aip_agents/examples/hello_world_pii_logger.pyi +5 -0
- aip_agents/examples/hello_world_ptc.py +49 -0
- aip_agents/examples/hello_world_ptc.pyi +5 -0
- aip_agents/examples/hello_world_sentry.py +133 -0
- aip_agents/examples/hello_world_sentry.pyi +21 -0
- aip_agents/examples/hello_world_step_limits.py +273 -0
- aip_agents/examples/hello_world_step_limits.pyi +17 -0
- aip_agents/examples/hello_world_stock_a2a_server.py +103 -0
- aip_agents/examples/hello_world_stock_a2a_server.pyi +17 -0
- aip_agents/examples/hello_world_tool_output_client.py +55 -0
- aip_agents/examples/hello_world_tool_output_client.pyi +5 -0
- aip_agents/examples/hello_world_tool_output_server.py +114 -0
- aip_agents/examples/hello_world_tool_output_server.pyi +19 -0
- aip_agents/examples/hitl_demo.py +724 -0
- aip_agents/examples/hitl_demo.pyi +67 -0
- aip_agents/examples/mcp_configs/configs.py +63 -0
- aip_agents/examples/mcp_servers/common.py +76 -0
- aip_agents/examples/mcp_servers/mcp_name.py +29 -0
- aip_agents/examples/mcp_servers/mcp_server_http.py +19 -0
- aip_agents/examples/mcp_servers/mcp_server_sse.py +19 -0
- aip_agents/examples/mcp_servers/mcp_server_stdio.py +19 -0
- aip_agents/examples/mcp_servers/mcp_time.py +10 -0
- aip_agents/examples/pii_demo_langgraph_client.py +69 -0
- aip_agents/examples/pii_demo_langgraph_client.pyi +5 -0
- aip_agents/examples/pii_demo_langgraph_server.py +126 -0
- aip_agents/examples/pii_demo_langgraph_server.pyi +20 -0
- aip_agents/examples/pii_demo_multi_agent_client.py +80 -0
- aip_agents/examples/pii_demo_multi_agent_client.pyi +5 -0
- aip_agents/examples/pii_demo_multi_agent_server.py +247 -0
- aip_agents/examples/pii_demo_multi_agent_server.pyi +40 -0
- aip_agents/examples/todolist_planning_a2a_langchain_client.py +70 -0
- aip_agents/examples/todolist_planning_a2a_langchain_client.pyi +5 -0
- aip_agents/examples/todolist_planning_a2a_langgraph_server.py +88 -0
- aip_agents/examples/todolist_planning_a2a_langgraph_server.pyi +19 -0
- aip_agents/examples/tools/__init__.py +27 -0
- aip_agents/examples/tools/__init__.pyi +9 -0
- aip_agents/examples/tools/adk_arithmetic_tools.py +36 -0
- aip_agents/examples/tools/adk_arithmetic_tools.pyi +24 -0
- aip_agents/examples/tools/adk_weather_tool.py +60 -0
- aip_agents/examples/tools/adk_weather_tool.pyi +18 -0
- aip_agents/examples/tools/data_generator_tool.py +103 -0
- aip_agents/examples/tools/data_generator_tool.pyi +15 -0
- aip_agents/examples/tools/data_visualization_tool.py +312 -0
- aip_agents/examples/tools/data_visualization_tool.pyi +19 -0
- aip_agents/examples/tools/image_artifact_tool.py +136 -0
- aip_agents/examples/tools/image_artifact_tool.pyi +26 -0
- aip_agents/examples/tools/langchain_arithmetic_tools.py +26 -0
- aip_agents/examples/tools/langchain_arithmetic_tools.pyi +17 -0
- aip_agents/examples/tools/langchain_currency_exchange_tool.py +88 -0
- aip_agents/examples/tools/langchain_currency_exchange_tool.pyi +20 -0
- aip_agents/examples/tools/langchain_graph_artifact_tool.py +172 -0
- aip_agents/examples/tools/langchain_graph_artifact_tool.pyi +25 -0
- aip_agents/examples/tools/langchain_weather_tool.py +48 -0
- aip_agents/examples/tools/langchain_weather_tool.pyi +19 -0
- aip_agents/examples/tools/langgraph_streaming_tool.py +130 -0
- aip_agents/examples/tools/langgraph_streaming_tool.pyi +43 -0
- aip_agents/examples/tools/mock_retrieval_tool.py +56 -0
- aip_agents/examples/tools/mock_retrieval_tool.pyi +13 -0
- aip_agents/examples/tools/pii_demo_tools.py +189 -0
- aip_agents/examples/tools/pii_demo_tools.pyi +54 -0
- aip_agents/examples/tools/random_chart_tool.py +142 -0
- aip_agents/examples/tools/random_chart_tool.pyi +20 -0
- aip_agents/examples/tools/serper_tool.py +202 -0
- aip_agents/examples/tools/serper_tool.pyi +16 -0
- aip_agents/examples/tools/stock_tools.py +82 -0
- aip_agents/examples/tools/stock_tools.pyi +36 -0
- aip_agents/examples/tools/table_generator_tool.py +167 -0
- aip_agents/examples/tools/table_generator_tool.pyi +22 -0
- aip_agents/examples/tools/time_tool.py +82 -0
- aip_agents/examples/tools/time_tool.pyi +15 -0
- aip_agents/examples/tools/weather_forecast_tool.py +38 -0
- aip_agents/examples/tools/weather_forecast_tool.pyi +14 -0
- aip_agents/executor/agent_executor.py +473 -0
- aip_agents/executor/base.py +48 -0
- aip_agents/guardrails/__init__.py +83 -0
- aip_agents/guardrails/__init__.pyi +6 -0
- aip_agents/guardrails/engines/__init__.py +69 -0
- aip_agents/guardrails/engines/__init__.pyi +4 -0
- aip_agents/guardrails/engines/base.py +90 -0
- aip_agents/guardrails/engines/base.pyi +61 -0
- aip_agents/guardrails/engines/nemo.py +101 -0
- aip_agents/guardrails/engines/nemo.pyi +46 -0
- aip_agents/guardrails/engines/phrase_matcher.py +113 -0
- aip_agents/guardrails/engines/phrase_matcher.pyi +48 -0
- aip_agents/guardrails/exceptions.py +39 -0
- aip_agents/guardrails/exceptions.pyi +23 -0
- aip_agents/guardrails/manager.py +163 -0
- aip_agents/guardrails/manager.pyi +42 -0
- aip_agents/guardrails/middleware.py +199 -0
- aip_agents/guardrails/middleware.pyi +87 -0
- aip_agents/guardrails/schemas.py +63 -0
- aip_agents/guardrails/schemas.pyi +43 -0
- aip_agents/guardrails/utils.py +45 -0
- aip_agents/guardrails/utils.pyi +19 -0
- aip_agents/mcp/__init__.py +1 -0
- aip_agents/mcp/__init__.pyi +0 -0
- aip_agents/mcp/client/__init__.py +14 -0
- aip_agents/mcp/client/__init__.pyi +5 -0
- aip_agents/mcp/client/base_mcp_client.py +369 -0
- aip_agents/mcp/client/base_mcp_client.pyi +148 -0
- aip_agents/mcp/client/connection_manager.py +228 -0
- aip_agents/mcp/client/connection_manager.pyi +51 -0
- aip_agents/mcp/client/google_adk/__init__.py +11 -0
- aip_agents/mcp/client/google_adk/__init__.pyi +3 -0
- aip_agents/mcp/client/google_adk/client.py +381 -0
- aip_agents/mcp/client/google_adk/client.pyi +75 -0
- aip_agents/mcp/client/langchain/__init__.py +11 -0
- aip_agents/mcp/client/langchain/__init__.pyi +3 -0
- aip_agents/mcp/client/langchain/client.py +265 -0
- aip_agents/mcp/client/langchain/client.pyi +48 -0
- aip_agents/mcp/client/persistent_session.py +612 -0
- aip_agents/mcp/client/persistent_session.pyi +122 -0
- aip_agents/mcp/client/session_pool.py +351 -0
- aip_agents/mcp/client/session_pool.pyi +101 -0
- aip_agents/mcp/client/transports.py +263 -0
- aip_agents/mcp/client/transports.pyi +132 -0
- aip_agents/mcp/utils/__init__.py +7 -0
- aip_agents/mcp/utils/__init__.pyi +0 -0
- aip_agents/mcp/utils/config_validator.py +139 -0
- aip_agents/mcp/utils/config_validator.pyi +82 -0
- aip_agents/memory/__init__.py +14 -0
- aip_agents/memory/__init__.pyi +5 -0
- aip_agents/memory/adapters/__init__.py +10 -0
- aip_agents/memory/adapters/__init__.pyi +4 -0
- aip_agents/memory/adapters/base_adapter.py +811 -0
- aip_agents/memory/adapters/base_adapter.pyi +176 -0
- aip_agents/memory/adapters/mem0.py +84 -0
- aip_agents/memory/adapters/mem0.pyi +22 -0
- aip_agents/memory/base.py +84 -0
- aip_agents/memory/base.pyi +60 -0
- aip_agents/memory/constants.py +49 -0
- aip_agents/memory/constants.pyi +25 -0
- aip_agents/memory/factory.py +86 -0
- aip_agents/memory/factory.pyi +24 -0
- aip_agents/memory/guidance.py +20 -0
- aip_agents/memory/guidance.pyi +3 -0
- aip_agents/memory/simple_memory.py +47 -0
- aip_agents/memory/simple_memory.pyi +23 -0
- aip_agents/middleware/__init__.py +17 -0
- aip_agents/middleware/__init__.pyi +5 -0
- aip_agents/middleware/base.py +96 -0
- aip_agents/middleware/base.pyi +75 -0
- aip_agents/middleware/manager.py +150 -0
- aip_agents/middleware/manager.pyi +84 -0
- aip_agents/middleware/todolist.py +274 -0
- aip_agents/middleware/todolist.pyi +125 -0
- aip_agents/ptc/__init__.py +48 -0
- aip_agents/ptc/__init__.pyi +10 -0
- aip_agents/ptc/doc_gen.py +122 -0
- aip_agents/ptc/doc_gen.pyi +40 -0
- aip_agents/ptc/exceptions.py +39 -0
- aip_agents/ptc/exceptions.pyi +22 -0
- aip_agents/ptc/executor.py +143 -0
- aip_agents/ptc/executor.pyi +73 -0
- aip_agents/ptc/mcp/__init__.py +45 -0
- aip_agents/ptc/mcp/__init__.pyi +7 -0
- aip_agents/ptc/mcp/sandbox_bridge.py +668 -0
- aip_agents/ptc/mcp/sandbox_bridge.pyi +47 -0
- aip_agents/ptc/mcp/templates/__init__.py +1 -0
- aip_agents/ptc/mcp/templates/__init__.pyi +0 -0
- aip_agents/ptc/mcp/templates/mcp_client.py.template +239 -0
- aip_agents/ptc/naming.py +184 -0
- aip_agents/ptc/naming.pyi +76 -0
- aip_agents/ptc/payload.py +26 -0
- aip_agents/ptc/payload.pyi +15 -0
- aip_agents/ptc/prompt_builder.py +571 -0
- aip_agents/ptc/prompt_builder.pyi +55 -0
- aip_agents/ptc/ptc_helper.py +16 -0
- aip_agents/ptc/ptc_helper.pyi +1 -0
- aip_agents/ptc/sandbox_bridge.py +58 -0
- aip_agents/ptc/sandbox_bridge.pyi +25 -0
- aip_agents/ptc/template_utils.py +33 -0
- aip_agents/ptc/template_utils.pyi +13 -0
- aip_agents/ptc/templates/__init__.py +1 -0
- aip_agents/ptc/templates/__init__.pyi +0 -0
- aip_agents/ptc/templates/ptc_helper.py.template +134 -0
- aip_agents/sandbox/__init__.py +43 -0
- aip_agents/sandbox/__init__.pyi +5 -0
- aip_agents/sandbox/defaults.py +9 -0
- aip_agents/sandbox/defaults.pyi +2 -0
- aip_agents/sandbox/e2b_runtime.py +267 -0
- aip_agents/sandbox/e2b_runtime.pyi +51 -0
- aip_agents/sandbox/template_builder.py +131 -0
- aip_agents/sandbox/template_builder.pyi +36 -0
- aip_agents/sandbox/types.py +24 -0
- aip_agents/sandbox/types.pyi +14 -0
- aip_agents/sandbox/validation.py +50 -0
- aip_agents/sandbox/validation.pyi +20 -0
- aip_agents/schema/__init__.py +69 -0
- aip_agents/schema/__init__.pyi +9 -0
- aip_agents/schema/a2a.py +56 -0
- aip_agents/schema/a2a.pyi +40 -0
- aip_agents/schema/agent.py +111 -0
- aip_agents/schema/agent.pyi +65 -0
- aip_agents/schema/hitl.py +157 -0
- aip_agents/schema/hitl.pyi +89 -0
- aip_agents/schema/langgraph.py +37 -0
- aip_agents/schema/langgraph.pyi +28 -0
- aip_agents/schema/model_id.py +97 -0
- aip_agents/schema/model_id.pyi +54 -0
- aip_agents/schema/step_limit.py +108 -0
- aip_agents/schema/step_limit.pyi +63 -0
- aip_agents/schema/storage.py +40 -0
- aip_agents/schema/storage.pyi +21 -0
- aip_agents/sentry/__init__.py +11 -0
- aip_agents/sentry/__init__.pyi +3 -0
- aip_agents/sentry/sentry.py +151 -0
- aip_agents/sentry/sentry.pyi +48 -0
- aip_agents/storage/__init__.py +41 -0
- aip_agents/storage/__init__.pyi +8 -0
- aip_agents/storage/base.py +85 -0
- aip_agents/storage/base.pyi +58 -0
- aip_agents/storage/clients/__init__.py +12 -0
- aip_agents/storage/clients/__init__.pyi +3 -0
- aip_agents/storage/clients/minio_client.py +318 -0
- aip_agents/storage/clients/minio_client.pyi +137 -0
- aip_agents/storage/config.py +62 -0
- aip_agents/storage/config.pyi +29 -0
- aip_agents/storage/providers/__init__.py +15 -0
- aip_agents/storage/providers/__init__.pyi +5 -0
- aip_agents/storage/providers/base.py +106 -0
- aip_agents/storage/providers/base.pyi +88 -0
- aip_agents/storage/providers/memory.py +114 -0
- aip_agents/storage/providers/memory.pyi +79 -0
- aip_agents/storage/providers/object_storage.py +214 -0
- aip_agents/storage/providers/object_storage.pyi +98 -0
- aip_agents/tools/__init__.py +64 -0
- aip_agents/tools/__init__.pyi +11 -0
- aip_agents/tools/browser_use/__init__.py +82 -0
- aip_agents/tools/browser_use/__init__.pyi +14 -0
- aip_agents/tools/browser_use/action_parser.py +103 -0
- aip_agents/tools/browser_use/action_parser.pyi +18 -0
- aip_agents/tools/browser_use/browser_use_tool.py +1120 -0
- aip_agents/tools/browser_use/browser_use_tool.pyi +50 -0
- aip_agents/tools/browser_use/llm_config.py +120 -0
- aip_agents/tools/browser_use/llm_config.pyi +52 -0
- aip_agents/tools/browser_use/minio_storage.py +198 -0
- aip_agents/tools/browser_use/minio_storage.pyi +109 -0
- aip_agents/tools/browser_use/schemas.py +119 -0
- aip_agents/tools/browser_use/schemas.pyi +32 -0
- aip_agents/tools/browser_use/session.py +76 -0
- aip_agents/tools/browser_use/session.pyi +4 -0
- aip_agents/tools/browser_use/session_errors.py +132 -0
- aip_agents/tools/browser_use/session_errors.pyi +53 -0
- aip_agents/tools/browser_use/steel_session_recording.py +317 -0
- aip_agents/tools/browser_use/steel_session_recording.pyi +63 -0
- aip_agents/tools/browser_use/streaming.py +815 -0
- aip_agents/tools/browser_use/streaming.pyi +81 -0
- aip_agents/tools/browser_use/structured_data_parser.py +257 -0
- aip_agents/tools/browser_use/structured_data_parser.pyi +86 -0
- aip_agents/tools/browser_use/structured_data_recovery.py +204 -0
- aip_agents/tools/browser_use/structured_data_recovery.pyi +43 -0
- aip_agents/tools/browser_use/types.py +78 -0
- aip_agents/tools/browser_use/types.pyi +45 -0
- aip_agents/tools/code_sandbox/__init__.py +26 -0
- aip_agents/tools/code_sandbox/__init__.pyi +3 -0
- aip_agents/tools/code_sandbox/constant.py +13 -0
- aip_agents/tools/code_sandbox/constant.pyi +4 -0
- aip_agents/tools/code_sandbox/e2b_cloud_sandbox_extended.py +306 -0
- aip_agents/tools/code_sandbox/e2b_cloud_sandbox_extended.pyi +102 -0
- aip_agents/tools/code_sandbox/e2b_sandbox_tool.py +411 -0
- aip_agents/tools/code_sandbox/e2b_sandbox_tool.pyi +29 -0
- aip_agents/tools/constants.py +177 -0
- aip_agents/tools/constants.pyi +138 -0
- aip_agents/tools/date_range_tool.py +554 -0
- aip_agents/tools/date_range_tool.pyi +21 -0
- aip_agents/tools/document_loader/__init__.py +44 -0
- aip_agents/tools/document_loader/__init__.pyi +7 -0
- aip_agents/tools/document_loader/base_reader.py +302 -0
- aip_agents/tools/document_loader/base_reader.pyi +75 -0
- aip_agents/tools/document_loader/docx_reader_tool.py +68 -0
- aip_agents/tools/document_loader/docx_reader_tool.pyi +10 -0
- aip_agents/tools/document_loader/excel_reader_tool.py +171 -0
- aip_agents/tools/document_loader/excel_reader_tool.pyi +26 -0
- aip_agents/tools/document_loader/pdf_reader_tool.py +79 -0
- aip_agents/tools/document_loader/pdf_reader_tool.pyi +11 -0
- aip_agents/tools/document_loader/pdf_splitter.py +169 -0
- aip_agents/tools/document_loader/pdf_splitter.pyi +18 -0
- aip_agents/tools/execute_ptc_code.py +308 -0
- aip_agents/tools/execute_ptc_code.pyi +90 -0
- aip_agents/tools/gl_connector/__init__.py +5 -0
- aip_agents/tools/gl_connector/__init__.pyi +3 -0
- aip_agents/tools/gl_connector/tool.py +383 -0
- aip_agents/tools/gl_connector/tool.pyi +74 -0
- aip_agents/tools/gl_connector_tools.py +119 -0
- aip_agents/tools/gl_connector_tools.pyi +39 -0
- aip_agents/tools/memory_search/__init__.py +29 -0
- aip_agents/tools/memory_search/__init__.pyi +5 -0
- aip_agents/tools/memory_search/base.py +200 -0
- aip_agents/tools/memory_search/base.pyi +69 -0
- aip_agents/tools/memory_search/mem0.py +365 -0
- aip_agents/tools/memory_search/mem0.pyi +29 -0
- aip_agents/tools/memory_search/schema.py +81 -0
- aip_agents/tools/memory_search/schema.pyi +25 -0
- aip_agents/tools/memory_search_tool.py +34 -0
- aip_agents/tools/memory_search_tool.pyi +3 -0
- aip_agents/tools/time_tool.py +117 -0
- aip_agents/tools/time_tool.pyi +16 -0
- aip_agents/tools/tool_config_injector.py +300 -0
- aip_agents/tools/tool_config_injector.pyi +26 -0
- aip_agents/tools/web_search/__init__.py +15 -0
- aip_agents/tools/web_search/__init__.pyi +3 -0
- aip_agents/tools/web_search/serper_tool.py +187 -0
- aip_agents/tools/web_search/serper_tool.pyi +19 -0
- aip_agents/types/__init__.py +70 -0
- aip_agents/types/__init__.pyi +36 -0
- aip_agents/types/a2a_events.py +13 -0
- aip_agents/types/a2a_events.pyi +3 -0
- aip_agents/utils/__init__.py +79 -0
- aip_agents/utils/__init__.pyi +11 -0
- aip_agents/utils/a2a_connector.py +1757 -0
- aip_agents/utils/a2a_connector.pyi +146 -0
- aip_agents/utils/artifact_helpers.py +502 -0
- aip_agents/utils/artifact_helpers.pyi +203 -0
- aip_agents/utils/constants.py +22 -0
- aip_agents/utils/constants.pyi +10 -0
- aip_agents/utils/datetime/__init__.py +34 -0
- aip_agents/utils/datetime/__init__.pyi +4 -0
- aip_agents/utils/datetime/normalization.py +231 -0
- aip_agents/utils/datetime/normalization.pyi +95 -0
- aip_agents/utils/datetime/timezone.py +206 -0
- aip_agents/utils/datetime/timezone.pyi +48 -0
- aip_agents/utils/env_loader.py +27 -0
- aip_agents/utils/env_loader.pyi +10 -0
- aip_agents/utils/event_handler_registry.py +58 -0
- aip_agents/utils/event_handler_registry.pyi +23 -0
- aip_agents/utils/file_prompt_utils.py +176 -0
- aip_agents/utils/file_prompt_utils.pyi +21 -0
- aip_agents/utils/final_response_builder.py +211 -0
- aip_agents/utils/final_response_builder.pyi +34 -0
- aip_agents/utils/formatter_llm_client.py +231 -0
- aip_agents/utils/formatter_llm_client.pyi +71 -0
- aip_agents/utils/langgraph/__init__.py +19 -0
- aip_agents/utils/langgraph/__init__.pyi +3 -0
- aip_agents/utils/langgraph/converter.py +128 -0
- aip_agents/utils/langgraph/converter.pyi +49 -0
- aip_agents/utils/langgraph/tool_managers/__init__.py +15 -0
- aip_agents/utils/langgraph/tool_managers/__init__.pyi +5 -0
- aip_agents/utils/langgraph/tool_managers/a2a_tool_manager.py +99 -0
- aip_agents/utils/langgraph/tool_managers/a2a_tool_manager.pyi +35 -0
- aip_agents/utils/langgraph/tool_managers/base_tool_manager.py +66 -0
- aip_agents/utils/langgraph/tool_managers/base_tool_manager.pyi +48 -0
- aip_agents/utils/langgraph/tool_managers/delegation_tool_manager.py +1096 -0
- aip_agents/utils/langgraph/tool_managers/delegation_tool_manager.pyi +56 -0
- aip_agents/utils/langgraph/tool_output_management.py +1047 -0
- aip_agents/utils/langgraph/tool_output_management.pyi +329 -0
- aip_agents/utils/logger.py +195 -0
- aip_agents/utils/logger.pyi +60 -0
- aip_agents/utils/metadata/__init__.py +27 -0
- aip_agents/utils/metadata/__init__.pyi +5 -0
- aip_agents/utils/metadata/activity_metadata_helper.py +407 -0
- aip_agents/utils/metadata/activity_metadata_helper.pyi +25 -0
- aip_agents/utils/metadata/activity_narrative/__init__.py +35 -0
- aip_agents/utils/metadata/activity_narrative/__init__.pyi +7 -0
- aip_agents/utils/metadata/activity_narrative/builder.py +817 -0
- aip_agents/utils/metadata/activity_narrative/builder.pyi +35 -0
- aip_agents/utils/metadata/activity_narrative/constants.py +51 -0
- aip_agents/utils/metadata/activity_narrative/constants.pyi +10 -0
- aip_agents/utils/metadata/activity_narrative/context.py +49 -0
- aip_agents/utils/metadata/activity_narrative/context.pyi +32 -0
- aip_agents/utils/metadata/activity_narrative/formatters.py +230 -0
- aip_agents/utils/metadata/activity_narrative/formatters.pyi +48 -0
- aip_agents/utils/metadata/activity_narrative/utils.py +35 -0
- aip_agents/utils/metadata/activity_narrative/utils.pyi +12 -0
- aip_agents/utils/metadata/schemas/__init__.py +16 -0
- aip_agents/utils/metadata/schemas/__init__.pyi +4 -0
- aip_agents/utils/metadata/schemas/activity_schema.py +29 -0
- aip_agents/utils/metadata/schemas/activity_schema.pyi +18 -0
- aip_agents/utils/metadata/schemas/thinking_schema.py +31 -0
- aip_agents/utils/metadata/schemas/thinking_schema.pyi +20 -0
- aip_agents/utils/metadata/thinking_metadata_helper.py +38 -0
- aip_agents/utils/metadata/thinking_metadata_helper.pyi +4 -0
- aip_agents/utils/metadata_helper.py +358 -0
- aip_agents/utils/metadata_helper.pyi +117 -0
- aip_agents/utils/name_preprocessor/__init__.py +17 -0
- aip_agents/utils/name_preprocessor/__init__.pyi +6 -0
- aip_agents/utils/name_preprocessor/base_name_preprocessor.py +73 -0
- aip_agents/utils/name_preprocessor/base_name_preprocessor.pyi +52 -0
- aip_agents/utils/name_preprocessor/google_name_preprocessor.py +100 -0
- aip_agents/utils/name_preprocessor/google_name_preprocessor.pyi +38 -0
- aip_agents/utils/name_preprocessor/name_preprocessor.py +87 -0
- aip_agents/utils/name_preprocessor/name_preprocessor.pyi +41 -0
- aip_agents/utils/name_preprocessor/openai_name_preprocessor.py +48 -0
- aip_agents/utils/name_preprocessor/openai_name_preprocessor.pyi +34 -0
- aip_agents/utils/pii/__init__.py +25 -0
- aip_agents/utils/pii/__init__.pyi +5 -0
- aip_agents/utils/pii/pii_handler.py +397 -0
- aip_agents/utils/pii/pii_handler.pyi +96 -0
- aip_agents/utils/pii/pii_helper.py +207 -0
- aip_agents/utils/pii/pii_helper.pyi +78 -0
- aip_agents/utils/pii/uuid_deanonymizer_mapping.py +195 -0
- aip_agents/utils/pii/uuid_deanonymizer_mapping.pyi +73 -0
- aip_agents/utils/reference_helper.py +273 -0
- aip_agents/utils/reference_helper.pyi +81 -0
- aip_agents/utils/sse_chunk_transformer.py +831 -0
- aip_agents/utils/sse_chunk_transformer.pyi +166 -0
- aip_agents/utils/step_limit_manager.py +265 -0
- aip_agents/utils/step_limit_manager.pyi +112 -0
- aip_agents/utils/token_usage_helper.py +156 -0
- aip_agents/utils/token_usage_helper.pyi +60 -0
- aip_agents_binary-0.6.4.dist-info/METADATA +673 -0
- aip_agents_binary-0.6.4.dist-info/RECORD +612 -0
- aip_agents_binary-0.6.4.dist-info/WHEEL +5 -0
- aip_agents_binary-0.6.4.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
"""MCP Transport Handlers.
|
|
2
|
+
|
|
3
|
+
This module provides abstract and concrete transport classes for STDIO, SSE, and streamable HTTP.
|
|
4
|
+
Each transport handles connection establishment specific to its protocol.
|
|
5
|
+
|
|
6
|
+
Authors:
|
|
7
|
+
Putu Ravindra Wiguna (putu.r.wiguna@gdplabs.id)
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from abc import ABC, abstractmethod
|
|
11
|
+
from collections.abc import AsyncIterator
|
|
12
|
+
from enum import StrEnum
|
|
13
|
+
from typing import Any, Protocol
|
|
14
|
+
|
|
15
|
+
import httpx
|
|
16
|
+
from gllm_tools.mcp.client.config import MCPConfiguration
|
|
17
|
+
from mcp.client.sse import sse_client
|
|
18
|
+
from mcp.client.stdio import StdioServerParameters, stdio_client
|
|
19
|
+
from mcp.client.streamable_http import streamable_http_client
|
|
20
|
+
|
|
21
|
+
from aip_agents.utils.logger import get_logger
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class TransportContext(Protocol):
|
|
25
|
+
"""Protocol defining the interface for async context managers used in MCP transport connections."""
|
|
26
|
+
|
|
27
|
+
async def __aenter__(self):
|
|
28
|
+
"""Enter the async context, establishing the connection and returning read/write streams."""
|
|
29
|
+
...
|
|
30
|
+
|
|
31
|
+
async def __aexit__(self, _exc_type, _exc_val, _exc_tb):
|
|
32
|
+
"""Exit the async context, performing cleanup and closing the connection.
|
|
33
|
+
|
|
34
|
+
Args:
|
|
35
|
+
_exc_type: Exception type if an exception occurred.
|
|
36
|
+
_exc_val: Exception value if an exception occurred.
|
|
37
|
+
_exc_tb: Exception traceback if an exception occurred.
|
|
38
|
+
"""
|
|
39
|
+
...
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
logger = get_logger(__name__)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
DEFAULT_TIMEOUT: float = 30.0
|
|
46
|
+
"""Default connection timeout in seconds."""
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def _sanitize_headers(config: MCPConfiguration) -> dict[str, str]:
|
|
50
|
+
"""Remove headers with None values to avoid invalid HTTP headers.
|
|
51
|
+
|
|
52
|
+
Args:
|
|
53
|
+
config (MCPConfiguration): Transport configuration containing optional headers.
|
|
54
|
+
|
|
55
|
+
Returns:
|
|
56
|
+
dict[str, str]: Filtered headers with None values removed.
|
|
57
|
+
"""
|
|
58
|
+
headers = config.get("headers", {}) or {}
|
|
59
|
+
return {key: value for key, value in headers.items() if value is not None}
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
class TransportType(StrEnum):
|
|
63
|
+
"""Enum for supported MCP transport types."""
|
|
64
|
+
|
|
65
|
+
HTTP = "http"
|
|
66
|
+
SSE = "sse"
|
|
67
|
+
STDIO = "stdio"
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
class Transport(ABC):
|
|
71
|
+
"""Abstract base class for MCP transports."""
|
|
72
|
+
|
|
73
|
+
def __init__(self, server_name: str, config: MCPConfiguration) -> None:
|
|
74
|
+
"""Initialize the transport.
|
|
75
|
+
|
|
76
|
+
Args:
|
|
77
|
+
server_name (str): Name of the MCP server.
|
|
78
|
+
config (MCPConfiguration): Configuration for the transport.
|
|
79
|
+
"""
|
|
80
|
+
self.server_name = server_name
|
|
81
|
+
self.config = config
|
|
82
|
+
self.ctx: Any = None
|
|
83
|
+
|
|
84
|
+
@abstractmethod
|
|
85
|
+
async def connect(self) -> tuple[AsyncIterator[bytes], AsyncIterator[bytes], TransportContext]:
|
|
86
|
+
"""Establish connection and return read/write streams and context manager.
|
|
87
|
+
|
|
88
|
+
Returns:
|
|
89
|
+
tuple[AsyncIterator[bytes], AsyncIterator[bytes], Any]:
|
|
90
|
+
(read_stream, write_stream, ctx)
|
|
91
|
+
Where:
|
|
92
|
+
- read_stream: AsyncIterator[bytes] for reading from the server.
|
|
93
|
+
- write_stream: AsyncIterator[bytes] for writing to the server.
|
|
94
|
+
- ctx: The async context manager instance for cleanup via __aexit__.
|
|
95
|
+
|
|
96
|
+
Raises:
|
|
97
|
+
ValueError: If required config (e.g., URL or command) is missing.
|
|
98
|
+
ConnectionError: If connection establishment fails.
|
|
99
|
+
"""
|
|
100
|
+
pass
|
|
101
|
+
|
|
102
|
+
async def close(self) -> None:
|
|
103
|
+
"""Clean up the transport connection."""
|
|
104
|
+
if self.ctx:
|
|
105
|
+
try:
|
|
106
|
+
await self.ctx.__aexit__(None, None, None)
|
|
107
|
+
except Exception as e:
|
|
108
|
+
logger.warning(f"Error during transport cleanup for {self.server_name}: {e}")
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
class SSETransport(Transport):
|
|
112
|
+
"""SSE transport handler."""
|
|
113
|
+
|
|
114
|
+
async def connect(self) -> tuple[AsyncIterator[bytes], AsyncIterator[bytes], TransportContext]:
|
|
115
|
+
"""Connect using SSE transport.
|
|
116
|
+
|
|
117
|
+
Builds SSE URL from config, initializes client with timeout, and enters context.
|
|
118
|
+
|
|
119
|
+
Returns:
|
|
120
|
+
tuple[AsyncIterator[bytes], AsyncIterator[bytes], Any]: (read_stream, write_stream, ctx)
|
|
121
|
+
|
|
122
|
+
Raises:
|
|
123
|
+
ValueError: If URL is missing.
|
|
124
|
+
ConnectionError: If SSE connection fails.
|
|
125
|
+
"""
|
|
126
|
+
base_url = self.config.get("url", "").rstrip("/")
|
|
127
|
+
if not base_url:
|
|
128
|
+
raise ValueError("URL is required for SSE transport")
|
|
129
|
+
|
|
130
|
+
url = f"{base_url}/sse" if not base_url.endswith("/sse") else base_url
|
|
131
|
+
timeout = self.config.get("timeout", DEFAULT_TIMEOUT)
|
|
132
|
+
headers = _sanitize_headers(self.config)
|
|
133
|
+
logger.debug(f"Attempting SSE connection to {url} with headers: {list(headers.keys())}")
|
|
134
|
+
try:
|
|
135
|
+
self.ctx = sse_client(url=url, timeout=timeout, sse_read_timeout=300.0, headers=headers)
|
|
136
|
+
read_stream, write_stream = await self.ctx.__aenter__()
|
|
137
|
+
logger.info(f"Connected to {self.server_name} via SSE")
|
|
138
|
+
return read_stream, write_stream, self.ctx
|
|
139
|
+
except Exception as e:
|
|
140
|
+
raise ConnectionError(f"SSE connection failed for {self.server_name}: {str(e)}") from e
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
class HTTPTransport(Transport):
|
|
144
|
+
"""Streamable HTTP transport handler."""
|
|
145
|
+
|
|
146
|
+
def __init__(self, server_name: str, config: MCPConfiguration) -> None:
|
|
147
|
+
"""Initialize the HTTP transport.
|
|
148
|
+
|
|
149
|
+
Args:
|
|
150
|
+
server_name (str): Name of the MCP server.
|
|
151
|
+
config (MCPConfiguration): Configuration for the transport.
|
|
152
|
+
"""
|
|
153
|
+
super().__init__(server_name, config)
|
|
154
|
+
self._http_client: httpx.AsyncClient | None = None
|
|
155
|
+
|
|
156
|
+
async def close(self) -> None:
|
|
157
|
+
"""Clean up the transport connection and any owned HTTP client."""
|
|
158
|
+
await super().close()
|
|
159
|
+
if self._http_client:
|
|
160
|
+
try:
|
|
161
|
+
await self._http_client.aclose()
|
|
162
|
+
except Exception as e:
|
|
163
|
+
logger.warning(f"Error during HTTP client cleanup for {self.server_name}: {e}")
|
|
164
|
+
finally:
|
|
165
|
+
self._http_client = None
|
|
166
|
+
|
|
167
|
+
async def connect(self) -> tuple[AsyncIterator[bytes], AsyncIterator[bytes], TransportContext]:
|
|
168
|
+
"""Connect using streamable HTTP transport.
|
|
169
|
+
|
|
170
|
+
Builds MCP URL from config, initializes client with timeout, and enters context.
|
|
171
|
+
|
|
172
|
+
Returns:
|
|
173
|
+
tuple[AsyncIterator[bytes], AsyncIterator[bytes], Any]: (read_stream, write_stream, ctx)
|
|
174
|
+
|
|
175
|
+
Raises:
|
|
176
|
+
ValueError: If URL is missing.
|
|
177
|
+
ConnectionError: If HTTP connection fails.
|
|
178
|
+
"""
|
|
179
|
+
base_url = self.config.get("url", "").rstrip("/")
|
|
180
|
+
if not base_url:
|
|
181
|
+
raise ValueError("URL is required for HTTP transport")
|
|
182
|
+
|
|
183
|
+
url = f"{base_url}/mcp" if not base_url.endswith("/mcp") else base_url
|
|
184
|
+
timeout = self.config.get("timeout", DEFAULT_TIMEOUT)
|
|
185
|
+
headers = _sanitize_headers(self.config)
|
|
186
|
+
logger.debug(f"Attempting streamable HTTP connection to {url} with headers: {list(headers.keys())}")
|
|
187
|
+
try:
|
|
188
|
+
http_client = httpx.AsyncClient(
|
|
189
|
+
timeout=httpx.Timeout(timeout),
|
|
190
|
+
headers=headers,
|
|
191
|
+
follow_redirects=True,
|
|
192
|
+
)
|
|
193
|
+
self._http_client = http_client
|
|
194
|
+
self.ctx = streamable_http_client(url=url, http_client=http_client)
|
|
195
|
+
read_stream, write_stream, _ = await self.ctx.__aenter__()
|
|
196
|
+
logger.info(f"Connected to {self.server_name} via HTTP")
|
|
197
|
+
return read_stream, write_stream, self.ctx
|
|
198
|
+
except Exception as e:
|
|
199
|
+
if self._http_client:
|
|
200
|
+
try:
|
|
201
|
+
await self._http_client.aclose()
|
|
202
|
+
except Exception as close_exc:
|
|
203
|
+
logger.warning(f"Error during HTTP client cleanup for {self.server_name}: {close_exc}")
|
|
204
|
+
finally:
|
|
205
|
+
self._http_client = None
|
|
206
|
+
raise ConnectionError(f"HTTP connection failed for {self.server_name}: {str(e)}") from e
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
class StdioTransport(Transport):
|
|
210
|
+
"""STDIO transport handler."""
|
|
211
|
+
|
|
212
|
+
async def connect(self) -> tuple[AsyncIterator[bytes], AsyncIterator[bytes], TransportContext]:
|
|
213
|
+
"""Connect using STDIO transport.
|
|
214
|
+
|
|
215
|
+
Initializes stdio client from command/args/env in config and enters context.
|
|
216
|
+
|
|
217
|
+
Returns:
|
|
218
|
+
tuple[AsyncIterator[bytes], AsyncIterator[bytes], Any]: (read_stream, write_stream, ctx)
|
|
219
|
+
|
|
220
|
+
Raises:
|
|
221
|
+
ValueError: If command is missing.
|
|
222
|
+
ConnectionError: If STDIO connection fails.
|
|
223
|
+
"""
|
|
224
|
+
command = self.config.get("command")
|
|
225
|
+
args = self.config.get("args", [])
|
|
226
|
+
env = self.config.get("env")
|
|
227
|
+
|
|
228
|
+
if not command:
|
|
229
|
+
raise ValueError("Command is required for stdio transport")
|
|
230
|
+
|
|
231
|
+
logger.debug(f"Attempting stdio connection with command: {command}, args: {args}")
|
|
232
|
+
try:
|
|
233
|
+
stdio_params = StdioServerParameters(command=command, args=args, env=env)
|
|
234
|
+
self.ctx = stdio_client(stdio_params)
|
|
235
|
+
read_stream, write_stream = await self.ctx.__aenter__()
|
|
236
|
+
logger.info(f"Connected to {self.server_name} via STDIO")
|
|
237
|
+
return read_stream, write_stream, self.ctx
|
|
238
|
+
except Exception as e:
|
|
239
|
+
raise ConnectionError(f"STDIO connection failed for {self.server_name}: {str(e)}") from e
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
def create_transport(server_name: str, config: MCPConfiguration, transport_type: TransportType | str) -> Transport:
|
|
243
|
+
"""Factory to create the appropriate transport instance.
|
|
244
|
+
|
|
245
|
+
Args:
|
|
246
|
+
server_name (str): Server name
|
|
247
|
+
config (MCPConfiguration): Config
|
|
248
|
+
transport_type (str): Transport type ('http', 'sse', 'stdio')
|
|
249
|
+
|
|
250
|
+
Returns:
|
|
251
|
+
Transport: Concrete transport instance
|
|
252
|
+
|
|
253
|
+
Raises:
|
|
254
|
+
ValueError: If transport_type is unsupported.
|
|
255
|
+
"""
|
|
256
|
+
if transport_type == TransportType.HTTP:
|
|
257
|
+
return HTTPTransport(server_name, config)
|
|
258
|
+
elif transport_type == TransportType.SSE:
|
|
259
|
+
return SSETransport(server_name, config)
|
|
260
|
+
elif transport_type == TransportType.STDIO:
|
|
261
|
+
return StdioTransport(server_name, config)
|
|
262
|
+
else:
|
|
263
|
+
raise ValueError(f"Unsupported transport type: {transport_type}")
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
from _typeshed import Incomplete
|
|
2
|
+
from abc import ABC, abstractmethod
|
|
3
|
+
from aip_agents.utils.logger import get_logger as get_logger
|
|
4
|
+
from collections.abc import AsyncIterator as AsyncIterator
|
|
5
|
+
from enum import StrEnum
|
|
6
|
+
from gllm_tools.mcp.client.config import MCPConfiguration
|
|
7
|
+
from typing import Any, Protocol
|
|
8
|
+
|
|
9
|
+
class TransportContext(Protocol):
|
|
10
|
+
"""Protocol defining the interface for async context managers used in MCP transport connections."""
|
|
11
|
+
async def __aenter__(self) -> None:
|
|
12
|
+
"""Enter the async context, establishing the connection and returning read/write streams."""
|
|
13
|
+
async def __aexit__(self, _exc_type, _exc_val, _exc_tb) -> None:
|
|
14
|
+
"""Exit the async context, performing cleanup and closing the connection.
|
|
15
|
+
|
|
16
|
+
Args:
|
|
17
|
+
_exc_type: Exception type if an exception occurred.
|
|
18
|
+
_exc_val: Exception value if an exception occurred.
|
|
19
|
+
_exc_tb: Exception traceback if an exception occurred.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
logger: Incomplete
|
|
23
|
+
DEFAULT_TIMEOUT: float
|
|
24
|
+
|
|
25
|
+
class TransportType(StrEnum):
|
|
26
|
+
"""Enum for supported MCP transport types."""
|
|
27
|
+
HTTP: str
|
|
28
|
+
SSE: str
|
|
29
|
+
STDIO: str
|
|
30
|
+
|
|
31
|
+
class Transport(ABC):
|
|
32
|
+
"""Abstract base class for MCP transports."""
|
|
33
|
+
server_name: Incomplete
|
|
34
|
+
config: Incomplete
|
|
35
|
+
ctx: Any
|
|
36
|
+
def __init__(self, server_name: str, config: MCPConfiguration) -> None:
|
|
37
|
+
"""Initialize the transport.
|
|
38
|
+
|
|
39
|
+
Args:
|
|
40
|
+
server_name (str): Name of the MCP server.
|
|
41
|
+
config (MCPConfiguration): Configuration for the transport.
|
|
42
|
+
"""
|
|
43
|
+
@abstractmethod
|
|
44
|
+
async def connect(self) -> tuple[AsyncIterator[bytes], AsyncIterator[bytes], TransportContext]:
|
|
45
|
+
"""Establish connection and return read/write streams and context manager.
|
|
46
|
+
|
|
47
|
+
Returns:
|
|
48
|
+
tuple[AsyncIterator[bytes], AsyncIterator[bytes], Any]:
|
|
49
|
+
(read_stream, write_stream, ctx)
|
|
50
|
+
Where:
|
|
51
|
+
- read_stream: AsyncIterator[bytes] for reading from the server.
|
|
52
|
+
- write_stream: AsyncIterator[bytes] for writing to the server.
|
|
53
|
+
- ctx: The async context manager instance for cleanup via __aexit__.
|
|
54
|
+
|
|
55
|
+
Raises:
|
|
56
|
+
ValueError: If required config (e.g., URL or command) is missing.
|
|
57
|
+
ConnectionError: If connection establishment fails.
|
|
58
|
+
"""
|
|
59
|
+
async def close(self) -> None:
|
|
60
|
+
"""Clean up the transport connection."""
|
|
61
|
+
|
|
62
|
+
class SSETransport(Transport):
|
|
63
|
+
"""SSE transport handler."""
|
|
64
|
+
ctx: Incomplete
|
|
65
|
+
async def connect(self) -> tuple[AsyncIterator[bytes], AsyncIterator[bytes], TransportContext]:
|
|
66
|
+
"""Connect using SSE transport.
|
|
67
|
+
|
|
68
|
+
Builds SSE URL from config, initializes client with timeout, and enters context.
|
|
69
|
+
|
|
70
|
+
Returns:
|
|
71
|
+
tuple[AsyncIterator[bytes], AsyncIterator[bytes], Any]: (read_stream, write_stream, ctx)
|
|
72
|
+
|
|
73
|
+
Raises:
|
|
74
|
+
ValueError: If URL is missing.
|
|
75
|
+
ConnectionError: If SSE connection fails.
|
|
76
|
+
"""
|
|
77
|
+
|
|
78
|
+
class HTTPTransport(Transport):
|
|
79
|
+
"""Streamable HTTP transport handler."""
|
|
80
|
+
def __init__(self, server_name: str, config: MCPConfiguration) -> None:
|
|
81
|
+
"""Initialize the HTTP transport.
|
|
82
|
+
|
|
83
|
+
Args:
|
|
84
|
+
server_name (str): Name of the MCP server.
|
|
85
|
+
config (MCPConfiguration): Configuration for the transport.
|
|
86
|
+
"""
|
|
87
|
+
async def close(self) -> None:
|
|
88
|
+
"""Clean up the transport connection and any owned HTTP client."""
|
|
89
|
+
ctx: Incomplete
|
|
90
|
+
async def connect(self) -> tuple[AsyncIterator[bytes], AsyncIterator[bytes], TransportContext]:
|
|
91
|
+
"""Connect using streamable HTTP transport.
|
|
92
|
+
|
|
93
|
+
Builds MCP URL from config, initializes client with timeout, and enters context.
|
|
94
|
+
|
|
95
|
+
Returns:
|
|
96
|
+
tuple[AsyncIterator[bytes], AsyncIterator[bytes], Any]: (read_stream, write_stream, ctx)
|
|
97
|
+
|
|
98
|
+
Raises:
|
|
99
|
+
ValueError: If URL is missing.
|
|
100
|
+
ConnectionError: If HTTP connection fails.
|
|
101
|
+
"""
|
|
102
|
+
|
|
103
|
+
class StdioTransport(Transport):
|
|
104
|
+
"""STDIO transport handler."""
|
|
105
|
+
ctx: Incomplete
|
|
106
|
+
async def connect(self) -> tuple[AsyncIterator[bytes], AsyncIterator[bytes], TransportContext]:
|
|
107
|
+
"""Connect using STDIO transport.
|
|
108
|
+
|
|
109
|
+
Initializes stdio client from command/args/env in config and enters context.
|
|
110
|
+
|
|
111
|
+
Returns:
|
|
112
|
+
tuple[AsyncIterator[bytes], AsyncIterator[bytes], Any]: (read_stream, write_stream, ctx)
|
|
113
|
+
|
|
114
|
+
Raises:
|
|
115
|
+
ValueError: If command is missing.
|
|
116
|
+
ConnectionError: If STDIO connection fails.
|
|
117
|
+
"""
|
|
118
|
+
|
|
119
|
+
def create_transport(server_name: str, config: MCPConfiguration, transport_type: TransportType | str) -> Transport:
|
|
120
|
+
"""Factory to create the appropriate transport instance.
|
|
121
|
+
|
|
122
|
+
Args:
|
|
123
|
+
server_name (str): Server name
|
|
124
|
+
config (MCPConfiguration): Config
|
|
125
|
+
transport_type (str): Transport type ('http', 'sse', 'stdio')
|
|
126
|
+
|
|
127
|
+
Returns:
|
|
128
|
+
Transport: Concrete transport instance
|
|
129
|
+
|
|
130
|
+
Raises:
|
|
131
|
+
ValueError: If transport_type is unsupported.
|
|
132
|
+
"""
|
|
File without changes
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
"""Configuration validation utilities for MCP.
|
|
2
|
+
|
|
3
|
+
This module provides validation logic for MCP server configurations,
|
|
4
|
+
specifically for the allowed_tools feature.
|
|
5
|
+
|
|
6
|
+
Authors:
|
|
7
|
+
Putu Ravindra Wiguna (putu.r.wiguna@gdplabs.id)
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from typing import Any
|
|
11
|
+
|
|
12
|
+
from aip_agents.utils.logger import get_logger
|
|
13
|
+
|
|
14
|
+
logger = get_logger(__name__)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def validate_allowed_tools_list(
|
|
18
|
+
allowed_tools: list[str] | None,
|
|
19
|
+
context: str,
|
|
20
|
+
) -> list[str] | None:
|
|
21
|
+
"""Validate that allowed_tools is a list of strings or None.
|
|
22
|
+
|
|
23
|
+
This function validates the type and contents of allowed_tools parameter.
|
|
24
|
+
It can be used to validate allowed_tools from any source (config dict, function parameter, etc).
|
|
25
|
+
|
|
26
|
+
Args:
|
|
27
|
+
allowed_tools: The allowed_tools value to validate (can be any type)
|
|
28
|
+
context: Context string for error messages (e.g., "Server 'my_server'", "'allowed_tools' parameter")
|
|
29
|
+
|
|
30
|
+
Returns:
|
|
31
|
+
Validated list of allowed tool names, or None if allowed_tools is None or empty.
|
|
32
|
+
None/empty means no restriction (all tools allowed).
|
|
33
|
+
|
|
34
|
+
Raises:
|
|
35
|
+
ValueError: If allowed_tools is not None/list or contains non-string elements
|
|
36
|
+
|
|
37
|
+
Examples:
|
|
38
|
+
>>> validate_allowed_tools_list(None, "test")
|
|
39
|
+
None
|
|
40
|
+
>>> validate_allowed_tools_list([], "test")
|
|
41
|
+
None
|
|
42
|
+
>>> validate_allowed_tools_list(["tool1", "tool2"], "test")
|
|
43
|
+
['tool1', 'tool2']
|
|
44
|
+
>>> validate_allowed_tools_list("invalid", "test") # doctest: +SKIP
|
|
45
|
+
ValueError: test: 'allowed_tools' must be a list of strings, got str
|
|
46
|
+
"""
|
|
47
|
+
# None or empty list is valid and means no restriction
|
|
48
|
+
if allowed_tools is None or allowed_tools == []:
|
|
49
|
+
return None
|
|
50
|
+
|
|
51
|
+
# Validate that it's a list
|
|
52
|
+
if not isinstance(allowed_tools, list):
|
|
53
|
+
raise ValueError(f"{context}: 'allowed_tools' must be a list of strings, got {type(allowed_tools).__name__}")
|
|
54
|
+
|
|
55
|
+
# Validate that all elements are strings
|
|
56
|
+
for idx, tool_name in enumerate(allowed_tools):
|
|
57
|
+
if not isinstance(tool_name, str):
|
|
58
|
+
raise ValueError(f"{context}: 'allowed_tools[{idx}]' must be a string, got {type(tool_name).__name__}")
|
|
59
|
+
if not tool_name.strip():
|
|
60
|
+
raise ValueError(f"{context}: 'allowed_tools[{idx}]' must be a non-empty string")
|
|
61
|
+
|
|
62
|
+
return allowed_tools
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def validate_allowed_tools_config(config: dict[str, Any], server_name: str) -> list[str] | None:
|
|
66
|
+
"""Validate and extract allowed_tools configuration from server config.
|
|
67
|
+
|
|
68
|
+
This function validates that the allowed_tools field, if present, is a list of strings.
|
|
69
|
+
It returns a normalized list of allowed tool names, or None if not specified/empty.
|
|
70
|
+
|
|
71
|
+
Args:
|
|
72
|
+
config: Server configuration dictionary that may contain 'allowed_tools' field
|
|
73
|
+
server_name: Name of the server (for error messages)
|
|
74
|
+
|
|
75
|
+
Returns:
|
|
76
|
+
List of allowed tool names, or None if allowed_tools is not specified or is empty.
|
|
77
|
+
None means no restriction (all tools allowed).
|
|
78
|
+
|
|
79
|
+
Raises:
|
|
80
|
+
ValueError: If allowed_tools is present but not a list
|
|
81
|
+
ValueError: If allowed_tools contains non-string elements
|
|
82
|
+
|
|
83
|
+
Examples:
|
|
84
|
+
>>> validate_allowed_tools_config({"url": "..."}, "my_server")
|
|
85
|
+
None
|
|
86
|
+
>>> validate_allowed_tools_config({"url": "...", "allowed_tools": []}, "my_server")
|
|
87
|
+
None
|
|
88
|
+
>>> validate_allowed_tools_config({"url": "...", "allowed_tools": ["tool1", "tool2"]}, "my_server")
|
|
89
|
+
['tool1', 'tool2']
|
|
90
|
+
"""
|
|
91
|
+
if "allowed_tools" not in config:
|
|
92
|
+
return None
|
|
93
|
+
|
|
94
|
+
allowed_tools = config["allowed_tools"]
|
|
95
|
+
|
|
96
|
+
# Use common validation logic
|
|
97
|
+
return validate_allowed_tools_list(allowed_tools, f"Server '{server_name}'")
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def validate_mcp_server_config(config: dict[str, Any], server_name: str) -> dict[str, Any]:
|
|
101
|
+
"""Validate complete MCP server configuration including allowed_tools.
|
|
102
|
+
|
|
103
|
+
This function performs comprehensive validation on an MCP server configuration,
|
|
104
|
+
ensuring all required fields are present and allowed_tools (if present) is valid.
|
|
105
|
+
Unknown configuration fields (such as any leftover disabled_tools) are silently ignored.
|
|
106
|
+
|
|
107
|
+
Args:
|
|
108
|
+
config: Server configuration dictionary
|
|
109
|
+
server_name: Name of the server (for error messages)
|
|
110
|
+
|
|
111
|
+
Returns:
|
|
112
|
+
Validated configuration dictionary (same as input, after validation)
|
|
113
|
+
|
|
114
|
+
Raises:
|
|
115
|
+
ValueError: If configuration is invalid
|
|
116
|
+
|
|
117
|
+
Examples:
|
|
118
|
+
>>> validate_mcp_server_config({"url": "http://localhost:8080"}, "my_server")
|
|
119
|
+
{'url': 'http://localhost:8080'}
|
|
120
|
+
>>> validate_mcp_server_config({"command": "python", "args": ["server.py"]}, "my_server")
|
|
121
|
+
{'command': 'python', 'args': ['server.py']}
|
|
122
|
+
"""
|
|
123
|
+
if not isinstance(config, dict):
|
|
124
|
+
raise ValueError(f"Server '{server_name}': configuration must be a dictionary")
|
|
125
|
+
|
|
126
|
+
if not config:
|
|
127
|
+
raise ValueError(f"Server '{server_name}': configuration must not be empty")
|
|
128
|
+
|
|
129
|
+
# Validate required fields (url OR command)
|
|
130
|
+
has_url = "url" in config
|
|
131
|
+
has_command = "command" in config
|
|
132
|
+
|
|
133
|
+
if not (has_url or has_command):
|
|
134
|
+
raise ValueError(f"Server '{server_name}': must have either 'url' or 'command' field")
|
|
135
|
+
|
|
136
|
+
# Validate allowed_tools if present (ignore unknown fields like disabled_tools)
|
|
137
|
+
validate_allowed_tools_config(config, server_name)
|
|
138
|
+
|
|
139
|
+
return config
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
from _typeshed import Incomplete
|
|
2
|
+
from aip_agents.utils.logger import get_logger as get_logger
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
logger: Incomplete
|
|
6
|
+
|
|
7
|
+
def validate_allowed_tools_list(allowed_tools: list[str] | None, context: str) -> list[str] | None:
|
|
8
|
+
'''Validate that allowed_tools is a list of strings or None.
|
|
9
|
+
|
|
10
|
+
This function validates the type and contents of allowed_tools parameter.
|
|
11
|
+
It can be used to validate allowed_tools from any source (config dict, function parameter, etc).
|
|
12
|
+
|
|
13
|
+
Args:
|
|
14
|
+
allowed_tools: The allowed_tools value to validate (can be any type)
|
|
15
|
+
context: Context string for error messages (e.g., "Server \'my_server\'", "\'allowed_tools\' parameter")
|
|
16
|
+
|
|
17
|
+
Returns:
|
|
18
|
+
Validated list of allowed tool names, or None if allowed_tools is None or empty.
|
|
19
|
+
None/empty means no restriction (all tools allowed).
|
|
20
|
+
|
|
21
|
+
Raises:
|
|
22
|
+
ValueError: If allowed_tools is not None/list or contains non-string elements
|
|
23
|
+
|
|
24
|
+
Examples:
|
|
25
|
+
>>> validate_allowed_tools_list(None, "test")
|
|
26
|
+
None
|
|
27
|
+
>>> validate_allowed_tools_list([], "test")
|
|
28
|
+
None
|
|
29
|
+
>>> validate_allowed_tools_list(["tool1", "tool2"], "test")
|
|
30
|
+
[\'tool1\', \'tool2\']
|
|
31
|
+
>>> validate_allowed_tools_list("invalid", "test") # doctest: +SKIP
|
|
32
|
+
ValueError: test: \'allowed_tools\' must be a list of strings, got str
|
|
33
|
+
'''
|
|
34
|
+
def validate_allowed_tools_config(config: dict[str, Any], server_name: str) -> list[str] | None:
|
|
35
|
+
'''Validate and extract allowed_tools configuration from server config.
|
|
36
|
+
|
|
37
|
+
This function validates that the allowed_tools field, if present, is a list of strings.
|
|
38
|
+
It returns a normalized list of allowed tool names, or None if not specified/empty.
|
|
39
|
+
|
|
40
|
+
Args:
|
|
41
|
+
config: Server configuration dictionary that may contain \'allowed_tools\' field
|
|
42
|
+
server_name: Name of the server (for error messages)
|
|
43
|
+
|
|
44
|
+
Returns:
|
|
45
|
+
List of allowed tool names, or None if allowed_tools is not specified or is empty.
|
|
46
|
+
None means no restriction (all tools allowed).
|
|
47
|
+
|
|
48
|
+
Raises:
|
|
49
|
+
ValueError: If allowed_tools is present but not a list
|
|
50
|
+
ValueError: If allowed_tools contains non-string elements
|
|
51
|
+
|
|
52
|
+
Examples:
|
|
53
|
+
>>> validate_allowed_tools_config({"url": "..."}, "my_server")
|
|
54
|
+
None
|
|
55
|
+
>>> validate_allowed_tools_config({"url": "...", "allowed_tools": []}, "my_server")
|
|
56
|
+
None
|
|
57
|
+
>>> validate_allowed_tools_config({"url": "...", "allowed_tools": ["tool1", "tool2"]}, "my_server")
|
|
58
|
+
[\'tool1\', \'tool2\']
|
|
59
|
+
'''
|
|
60
|
+
def validate_mcp_server_config(config: dict[str, Any], server_name: str) -> dict[str, Any]:
|
|
61
|
+
'''Validate complete MCP server configuration including allowed_tools.
|
|
62
|
+
|
|
63
|
+
This function performs comprehensive validation on an MCP server configuration,
|
|
64
|
+
ensuring all required fields are present and allowed_tools (if present) is valid.
|
|
65
|
+
Unknown configuration fields (such as any leftover disabled_tools) are silently ignored.
|
|
66
|
+
|
|
67
|
+
Args:
|
|
68
|
+
config: Server configuration dictionary
|
|
69
|
+
server_name: Name of the server (for error messages)
|
|
70
|
+
|
|
71
|
+
Returns:
|
|
72
|
+
Validated configuration dictionary (same as input, after validation)
|
|
73
|
+
|
|
74
|
+
Raises:
|
|
75
|
+
ValueError: If configuration is invalid
|
|
76
|
+
|
|
77
|
+
Examples:
|
|
78
|
+
>>> validate_mcp_server_config({"url": "http://localhost:8080"}, "my_server")
|
|
79
|
+
{\'url\': \'http://localhost:8080\'}
|
|
80
|
+
>>> validate_mcp_server_config({"command": "python", "args": ["server.py"]}, "my_server")
|
|
81
|
+
{\'command\': \'python\', \'args\': [\'server.py\']}
|
|
82
|
+
'''
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"""Memory module for the GLLM agents.
|
|
2
|
+
|
|
3
|
+
Authors:
|
|
4
|
+
Raymond Christopher (raymond.christopher@gdplabs.id)
|
|
5
|
+
|
|
6
|
+
References:
|
|
7
|
+
https://github.com/GDP-ADMIN/gdplabs-exploration/blob/ai-agent-app/backend/aip_agents/memory/__init__.py
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from aip_agents.memory.base import BaseMemory
|
|
11
|
+
from aip_agents.memory.constants import MemoryMethod
|
|
12
|
+
from aip_agents.memory.factory import MemoryFactory
|
|
13
|
+
|
|
14
|
+
__all__ = ["BaseMemory", "MemoryMethod", "MemoryFactory"]
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"""Memory adapter implementations.
|
|
2
|
+
|
|
3
|
+
Authors:
|
|
4
|
+
Raymond Christopher (raymond.christopher@gdplabs.id)
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from aip_agents.memory.adapters.base_adapter import BaseMemoryAdapter
|
|
8
|
+
from aip_agents.memory.adapters.mem0 import Mem0Memory
|
|
9
|
+
|
|
10
|
+
__all__ = ["Mem0Memory", "BaseMemoryAdapter"]
|