mcp-mesh 0.6.3__tar.gz → 0.7.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/.gitignore +1 -1
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/PKG-INFO +4 -1
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/__init__.py +1 -1
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/engine/decorator_registry.py +50 -11
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/engine/http_wrapper.py +10 -2
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/engine/mesh_llm_agent.py +98 -6
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/engine/unified_mcp_proxy.py +10 -2
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/pipeline/api_heartbeat/api_dependency_resolution.py +82 -100
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/pipeline/api_heartbeat/api_heartbeat_send.py +150 -96
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/pipeline/api_startup/route_integration.py +91 -92
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/pipeline/mcp_startup/fastapiserver_setup.py +7 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/tracing/execution_tracer.py +41 -13
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/mesh/decorators.py +43 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/pyproject.toml +8 -5
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/LICENSE +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/README.md +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/engine/__init__.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/engine/async_mcp_client.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/engine/base_injector.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/engine/dependency_injector.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/engine/full_mcp_proxy.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/engine/llm_config.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/engine/llm_errors.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/engine/mcp_client_proxy.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/engine/mesh_llm_agent_injector.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/engine/provider_handlers/__init__.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/engine/provider_handlers/base_provider_handler.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/engine/provider_handlers/claude_handler.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/engine/provider_handlers/generic_handler.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/engine/provider_handlers/openai_handler.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/engine/provider_handlers/provider_handler_registry.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/engine/response_parser.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/engine/self_dependency_proxy.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/engine/session_aware_client.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/engine/session_manager.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/engine/signature_analyzer.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/engine/tool_executor.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/engine/tool_schema_builder.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/generated/.openapi-generator/FILES +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/generated/.openapi-generator/VERSION +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/generated/.openapi-generator-ignore +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/generated/mcp_mesh_registry_client/__init__.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/generated/mcp_mesh_registry_client/api/__init__.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/generated/mcp_mesh_registry_client/api/agents_api.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/generated/mcp_mesh_registry_client/api/health_api.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/generated/mcp_mesh_registry_client/api/tracing_api.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/generated/mcp_mesh_registry_client/api_client.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/generated/mcp_mesh_registry_client/api_response.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/generated/mcp_mesh_registry_client/configuration.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/generated/mcp_mesh_registry_client/exceptions.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/generated/mcp_mesh_registry_client/models/__init__.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/generated/mcp_mesh_registry_client/models/agent_info.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/generated/mcp_mesh_registry_client/models/agent_metadata.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/generated/mcp_mesh_registry_client/models/agent_metadata_dependencies_inner.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/generated/mcp_mesh_registry_client/models/agent_metadata_dependencies_inner_one_of.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/generated/mcp_mesh_registry_client/models/agent_registration.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/generated/mcp_mesh_registry_client/models/agent_registration_metadata.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/generated/mcp_mesh_registry_client/models/agents_list_response.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/generated/mcp_mesh_registry_client/models/capability_info.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/generated/mcp_mesh_registry_client/models/decorator_agent_metadata.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/generated/mcp_mesh_registry_client/models/decorator_agent_request.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/generated/mcp_mesh_registry_client/models/decorator_info.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/generated/mcp_mesh_registry_client/models/dependency_info.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/generated/mcp_mesh_registry_client/models/dependency_resolution_info.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/generated/mcp_mesh_registry_client/models/error_response.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/generated/mcp_mesh_registry_client/models/health_response.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/generated/mcp_mesh_registry_client/models/heartbeat_request.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/generated/mcp_mesh_registry_client/models/heartbeat_request_metadata.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/generated/mcp_mesh_registry_client/models/heartbeat_response.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/generated/mcp_mesh_registry_client/models/llm_provider.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/generated/mcp_mesh_registry_client/models/llm_tool_filter.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/generated/mcp_mesh_registry_client/models/llm_tool_filter_filter_inner.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/generated/mcp_mesh_registry_client/models/llm_tool_filter_filter_inner_one_of.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/generated/mcp_mesh_registry_client/models/llm_tool_info.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/generated/mcp_mesh_registry_client/models/mesh_agent_register_metadata.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/generated/mcp_mesh_registry_client/models/mesh_agent_registration.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/generated/mcp_mesh_registry_client/models/mesh_registration_response.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/generated/mcp_mesh_registry_client/models/mesh_registration_response_dependencies_resolved_value_inner.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/generated/mcp_mesh_registry_client/models/mesh_tool_dependency_registration.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/generated/mcp_mesh_registry_client/models/mesh_tool_register_metadata.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/generated/mcp_mesh_registry_client/models/mesh_tool_registration.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/generated/mcp_mesh_registry_client/models/registration_response.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/generated/mcp_mesh_registry_client/models/resolved_llm_provider.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/generated/mcp_mesh_registry_client/models/rich_dependency.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/generated/mcp_mesh_registry_client/models/root_response.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/generated/mcp_mesh_registry_client/models/standardized_dependency.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/generated/mcp_mesh_registry_client/models/trace_event.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/generated/mcp_mesh_registry_client/py.typed +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/generated/mcp_mesh_registry_client/rest.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/pipeline/__init__.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/pipeline/api_heartbeat/__init__.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/pipeline/api_heartbeat/api_fast_heartbeat_check.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/pipeline/api_heartbeat/api_health_check.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/pipeline/api_heartbeat/api_heartbeat_orchestrator.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/pipeline/api_heartbeat/api_heartbeat_pipeline.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/pipeline/api_heartbeat/api_lifespan_integration.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/pipeline/api_heartbeat/api_registry_connection.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/pipeline/api_startup/__init__.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/pipeline/api_startup/api_pipeline.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/pipeline/api_startup/api_server_setup.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/pipeline/api_startup/fastapi_discovery.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/pipeline/api_startup/middleware_integration.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/pipeline/api_startup/route_collection.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/pipeline/mcp_heartbeat/__init__.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/pipeline/mcp_heartbeat/dependency_resolution.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/pipeline/mcp_heartbeat/fast_heartbeat_check.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/pipeline/mcp_heartbeat/heartbeat_orchestrator.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/pipeline/mcp_heartbeat/heartbeat_pipeline.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/pipeline/mcp_heartbeat/heartbeat_send.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/pipeline/mcp_heartbeat/lifespan_integration.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/pipeline/mcp_heartbeat/llm_tools_resolution.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/pipeline/mcp_heartbeat/registry_connection.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/pipeline/mcp_startup/__init__.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/pipeline/mcp_startup/configuration.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/pipeline/mcp_startup/decorator_collection.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/pipeline/mcp_startup/fastmcpserver_discovery.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/pipeline/mcp_startup/heartbeat_loop.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/pipeline/mcp_startup/heartbeat_preparation.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/pipeline/mcp_startup/server_discovery.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/pipeline/mcp_startup/startup_orchestrator.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/pipeline/mcp_startup/startup_pipeline.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/pipeline/shared/__init__.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/pipeline/shared/base_step.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/pipeline/shared/mesh_pipeline.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/pipeline/shared/pipeline_types.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/pipeline/shared/registry_connection.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/shared/__init__.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/shared/config_resolver.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/shared/content_extractor.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/shared/defaults.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/shared/fast_heartbeat_status.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/shared/fastapi_middleware_manager.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/shared/health_check_cache.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/shared/host_resolver.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/shared/logging_config.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/shared/registry_client_wrapper.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/shared/server_discovery.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/shared/simple_shutdown.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/shared/sse_parser.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/shared/support_types.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/tracing/agent_context_helper.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/tracing/context.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/tracing/fastapi_tracing_middleware.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/tracing/redis_metadata_publisher.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/tracing/trace_context_helper.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/tracing/utils.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/_mcp_mesh/utils/fastmcp_schema_extractor.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/mesh/__init__.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/mesh/helpers.py +0 -0
- {mcp_mesh-0.6.3 → mcp_mesh-0.7.0}/mesh/types.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mcp-mesh
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.7.0
|
|
4
4
|
Summary: Kubernetes-native platform for distributed MCP applications
|
|
5
5
|
Project-URL: Homepage, https://github.com/dhyansraj/mcp-mesh
|
|
6
6
|
Project-URL: Documentation, https://github.com/dhyansraj/mcp-mesh/tree/main/docs
|
|
@@ -23,10 +23,13 @@ Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
|
23
23
|
Classifier: Topic :: System :: Distributed Computing
|
|
24
24
|
Requires-Python: >=3.11
|
|
25
25
|
Requires-Dist: aiohttp<4.0.0,>=3.8.0
|
|
26
|
+
Requires-Dist: cachetools>=5.3.0
|
|
26
27
|
Requires-Dist: click<9.0.0,>=8.1.0
|
|
27
28
|
Requires-Dist: fastapi<1.0.0,>=0.104.0
|
|
28
29
|
Requires-Dist: fastmcp<3.0.0,>=2.8.0
|
|
29
30
|
Requires-Dist: httpx<1.0.0,>=0.25.0
|
|
31
|
+
Requires-Dist: jinja2>=3.1.0
|
|
32
|
+
Requires-Dist: litellm>=1.30.0
|
|
30
33
|
Requires-Dist: mcp<2.0.0,>=1.9.0
|
|
31
34
|
Requires-Dist: prometheus-client<1.0.0,>=0.19.0
|
|
32
35
|
Requires-Dist: pydantic<3.0.0,>=2.4.0
|
|
@@ -38,7 +38,7 @@ class LLMAgentMetadata:
|
|
|
38
38
|
|
|
39
39
|
function: Callable
|
|
40
40
|
config: dict[str, Any] # LLM configuration (provider, model, filter, etc.)
|
|
41
|
-
output_type:
|
|
41
|
+
output_type: type | None # Pydantic model type from return annotation
|
|
42
42
|
param_name: str # Name of MeshLlmAgent parameter
|
|
43
43
|
function_id: str # Unique function ID for registry
|
|
44
44
|
registered_at: datetime
|
|
@@ -70,16 +70,55 @@ class DecoratorRegistry:
|
|
|
70
70
|
_custom_decorators: dict[str, dict[str, DecoratedFunction]] = {}
|
|
71
71
|
|
|
72
72
|
# Immediate uvicorn server storage (for preventing shutdown state)
|
|
73
|
-
_immediate_uvicorn_server:
|
|
73
|
+
_immediate_uvicorn_server: dict[str, Any] | None = None
|
|
74
74
|
|
|
75
75
|
# FastMCP lifespan storage (for proper integration with FastAPI)
|
|
76
|
-
_fastmcp_lifespan:
|
|
76
|
+
_fastmcp_lifespan: Any | None = None
|
|
77
77
|
|
|
78
78
|
# FastMCP HTTP app storage (the same app instance whose lifespan was extracted)
|
|
79
|
-
_fastmcp_http_app:
|
|
79
|
+
_fastmcp_http_app: Any | None = None
|
|
80
80
|
|
|
81
81
|
# FastMCP server info storage (for schema extraction during heartbeat)
|
|
82
|
-
_fastmcp_server_info:
|
|
82
|
+
_fastmcp_server_info: dict[str, Any] | None = None
|
|
83
|
+
|
|
84
|
+
# Route-to-wrapper mapping for @mesh.route dependency injection
|
|
85
|
+
# Key: "METHOD:path" (e.g., "GET:/api/v1/benchmark-services")
|
|
86
|
+
# Value: {"wrapper": Callable, "dependencies": list[str]}
|
|
87
|
+
_route_wrapper_registry: dict[str, dict[str, Any]] = {}
|
|
88
|
+
|
|
89
|
+
@classmethod
|
|
90
|
+
def register_route_wrapper(
|
|
91
|
+
cls, method: str, path: str, wrapper: Callable, dependencies: list[str]
|
|
92
|
+
) -> None:
|
|
93
|
+
"""
|
|
94
|
+
Register a route's wrapper function for dependency injection.
|
|
95
|
+
|
|
96
|
+
Args:
|
|
97
|
+
method: HTTP method (e.g., "GET", "POST")
|
|
98
|
+
path: Route path (e.g., "/api/v1/benchmark-services")
|
|
99
|
+
wrapper: The injection wrapper function
|
|
100
|
+
dependencies: List of dependency capability names
|
|
101
|
+
"""
|
|
102
|
+
route_id = f"{method}:{path}"
|
|
103
|
+
cls._route_wrapper_registry[route_id] = {
|
|
104
|
+
"wrapper": wrapper,
|
|
105
|
+
"dependencies": dependencies,
|
|
106
|
+
"method": method,
|
|
107
|
+
"path": path,
|
|
108
|
+
}
|
|
109
|
+
logger.debug(
|
|
110
|
+
f"📝 Registered route wrapper: {route_id} with {len(dependencies)} dependencies"
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
@classmethod
|
|
114
|
+
def get_route_wrapper(cls, route_id: str) -> dict[str, Any] | None:
|
|
115
|
+
"""Get route wrapper info by route ID (METHOD:path)."""
|
|
116
|
+
return cls._route_wrapper_registry.get(route_id)
|
|
117
|
+
|
|
118
|
+
@classmethod
|
|
119
|
+
def get_all_route_wrappers(cls) -> dict[str, dict[str, Any]]:
|
|
120
|
+
"""Get all registered route wrappers."""
|
|
121
|
+
return cls._route_wrapper_registry.copy()
|
|
83
122
|
|
|
84
123
|
@classmethod
|
|
85
124
|
def register_mesh_agent(cls, func: Callable, metadata: dict[str, Any]) -> None:
|
|
@@ -154,7 +193,7 @@ class DecoratorRegistry:
|
|
|
154
193
|
cls,
|
|
155
194
|
func: Callable,
|
|
156
195
|
config: dict[str, Any],
|
|
157
|
-
output_type:
|
|
196
|
+
output_type: type | None,
|
|
158
197
|
param_name: str,
|
|
159
198
|
function_id: str,
|
|
160
199
|
) -> None:
|
|
@@ -355,7 +394,7 @@ class DecoratorRegistry:
|
|
|
355
394
|
return stats
|
|
356
395
|
|
|
357
396
|
# Cache for resolved agent configuration to avoid repeated work
|
|
358
|
-
_cached_agent_config:
|
|
397
|
+
_cached_agent_config: dict[str, Any] | None = None
|
|
359
398
|
|
|
360
399
|
@classmethod
|
|
361
400
|
def update_agent_config(cls, updates: dict[str, Any]) -> None:
|
|
@@ -610,7 +649,7 @@ class DecoratorRegistry:
|
|
|
610
649
|
)
|
|
611
650
|
|
|
612
651
|
@classmethod
|
|
613
|
-
def get_immediate_uvicorn_server(cls) ->
|
|
652
|
+
def get_immediate_uvicorn_server(cls) -> dict[str, Any] | None:
|
|
614
653
|
"""
|
|
615
654
|
Get stored immediate uvicorn server reference.
|
|
616
655
|
|
|
@@ -659,7 +698,7 @@ class DecoratorRegistry:
|
|
|
659
698
|
logger.debug("🔄 REGISTRY: Stored FastMCP lifespan for FastAPI integration")
|
|
660
699
|
|
|
661
700
|
@classmethod
|
|
662
|
-
def get_fastmcp_lifespan(cls) ->
|
|
701
|
+
def get_fastmcp_lifespan(cls) -> Any | None:
|
|
663
702
|
"""
|
|
664
703
|
Get stored FastMCP lifespan.
|
|
665
704
|
|
|
@@ -686,7 +725,7 @@ class DecoratorRegistry:
|
|
|
686
725
|
logger.debug("🔄 REGISTRY: Stored FastMCP HTTP app for mounting")
|
|
687
726
|
|
|
688
727
|
@classmethod
|
|
689
|
-
def get_fastmcp_http_app(cls) ->
|
|
728
|
+
def get_fastmcp_http_app(cls) -> Any | None:
|
|
690
729
|
"""
|
|
691
730
|
Get stored FastMCP HTTP app.
|
|
692
731
|
|
|
@@ -715,7 +754,7 @@ class DecoratorRegistry:
|
|
|
715
754
|
)
|
|
716
755
|
|
|
717
756
|
@classmethod
|
|
718
|
-
def get_fastmcp_server_info(cls) ->
|
|
757
|
+
def get_fastmcp_server_info(cls) -> dict[str, Any] | None:
|
|
719
758
|
"""
|
|
720
759
|
Get stored FastMCP server info.
|
|
721
760
|
|
|
@@ -132,7 +132,7 @@ class HttpMcpWrapper:
|
|
|
132
132
|
|
|
133
133
|
# Phase 3: Metadata caching
|
|
134
134
|
self._metadata_cache: dict[str, Any] = {}
|
|
135
|
-
self._cache_timestamp:
|
|
135
|
+
self._cache_timestamp: datetime | None = None
|
|
136
136
|
self._cache_ttl: timedelta = timedelta(minutes=5) # Cache for 5 minutes
|
|
137
137
|
|
|
138
138
|
# Phase 5: Session storage and pod info
|
|
@@ -254,7 +254,7 @@ class HttpMcpWrapper:
|
|
|
254
254
|
self._cache_timestamp = datetime.now()
|
|
255
255
|
logger.debug(f"📋 Metadata cache updated with {len(metadata)} entries")
|
|
256
256
|
|
|
257
|
-
def get_cached_metadata(self) ->
|
|
257
|
+
def get_cached_metadata(self) -> dict[str, Any] | None:
|
|
258
258
|
"""Get cached metadata if available and valid."""
|
|
259
259
|
if self._is_cache_valid():
|
|
260
260
|
logger.debug("✅ Returning cached metadata")
|
|
@@ -391,6 +391,14 @@ class HttpMcpWrapper:
|
|
|
391
391
|
try:
|
|
392
392
|
from ..tracing.trace_context_helper import TraceContextHelper
|
|
393
393
|
|
|
394
|
+
# DEBUG: Log incoming headers for trace propagation debugging
|
|
395
|
+
trace_id_header = request.headers.get("X-Trace-ID")
|
|
396
|
+
parent_span_header = request.headers.get("X-Parent-Span")
|
|
397
|
+
self.logger.info(
|
|
398
|
+
f"🔍 INCOMING_HEADERS: X-Trace-ID={trace_id_header}, "
|
|
399
|
+
f"X-Parent-Span={parent_span_header}, path={request.url.path}"
|
|
400
|
+
)
|
|
401
|
+
|
|
394
402
|
# Use helper class for trace context extraction and setup
|
|
395
403
|
trace_context = (
|
|
396
404
|
await TraceContextHelper.extract_trace_context_from_request(
|
|
@@ -8,7 +8,7 @@ import asyncio
|
|
|
8
8
|
import json
|
|
9
9
|
import logging
|
|
10
10
|
from pathlib import Path
|
|
11
|
-
from typing import Any, Dict, List, Optional, Union
|
|
11
|
+
from typing import Any, Dict, List, Literal, Optional, Union
|
|
12
12
|
|
|
13
13
|
from pydantic import BaseModel
|
|
14
14
|
|
|
@@ -41,6 +41,9 @@ except ImportError:
|
|
|
41
41
|
|
|
42
42
|
logger = logging.getLogger(__name__)
|
|
43
43
|
|
|
44
|
+
# Sentinel value to distinguish "context not provided" from "explicitly None/empty"
|
|
45
|
+
_CONTEXT_NOT_PROVIDED = object()
|
|
46
|
+
|
|
44
47
|
|
|
45
48
|
class MeshLlmAgent:
|
|
46
49
|
"""
|
|
@@ -241,7 +244,56 @@ IMPORTANT TOOL CALLING RULES:
|
|
|
241
244
|
f"Expected MeshContextModel, dict, or None."
|
|
242
245
|
)
|
|
243
246
|
|
|
244
|
-
def
|
|
247
|
+
def _resolve_context(
|
|
248
|
+
self,
|
|
249
|
+
runtime_context: Union[dict, None, object],
|
|
250
|
+
context_mode: Literal["replace", "append", "prepend"],
|
|
251
|
+
) -> dict:
|
|
252
|
+
"""
|
|
253
|
+
Resolve effective context for template rendering.
|
|
254
|
+
|
|
255
|
+
Merges auto-populated context (from decorator's context_param) with
|
|
256
|
+
runtime context passed to __call__(), based on the context_mode.
|
|
257
|
+
|
|
258
|
+
Args:
|
|
259
|
+
runtime_context: Context passed at call time, or _CONTEXT_NOT_PROVIDED
|
|
260
|
+
context_mode: How to merge contexts - "replace", "append", or "prepend"
|
|
261
|
+
|
|
262
|
+
Returns:
|
|
263
|
+
Resolved context dictionary for template rendering
|
|
264
|
+
|
|
265
|
+
Behavior:
|
|
266
|
+
- If runtime_context is _CONTEXT_NOT_PROVIDED: use auto-populated context
|
|
267
|
+
- If context_mode is "replace": use runtime_context entirely
|
|
268
|
+
- If context_mode is "append": auto_context | runtime_context (runtime wins)
|
|
269
|
+
- If context_mode is "prepend": runtime_context | auto_context (auto wins)
|
|
270
|
+
|
|
271
|
+
Note:
|
|
272
|
+
Empty dict {} with "replace" mode explicitly clears context.
|
|
273
|
+
Empty dict {} with "append"/"prepend" is a no-op (keeps auto context).
|
|
274
|
+
"""
|
|
275
|
+
# Get auto-populated context from decorator
|
|
276
|
+
auto_context = self._prepare_context(self._context_value)
|
|
277
|
+
|
|
278
|
+
# If no runtime context provided, use auto-populated context unchanged
|
|
279
|
+
if runtime_context is _CONTEXT_NOT_PROVIDED:
|
|
280
|
+
return auto_context
|
|
281
|
+
|
|
282
|
+
# Prepare runtime context (handles MeshContextModel, dict, None)
|
|
283
|
+
runtime_dict = self._prepare_context(runtime_context)
|
|
284
|
+
|
|
285
|
+
# Apply context_mode
|
|
286
|
+
if context_mode == "replace":
|
|
287
|
+
# Replace entirely with runtime context (even if empty)
|
|
288
|
+
return runtime_dict
|
|
289
|
+
elif context_mode == "prepend":
|
|
290
|
+
# Runtime first, auto overwrites (auto wins on conflicts)
|
|
291
|
+
return {**runtime_dict, **auto_context}
|
|
292
|
+
else: # "append" (default)
|
|
293
|
+
# Auto first, runtime overwrites (runtime wins on conflicts)
|
|
294
|
+
return {**auto_context, **runtime_dict}
|
|
295
|
+
|
|
296
|
+
def _render_system_prompt(self, effective_context: Optional[dict] = None) -> str:
|
|
245
297
|
"""
|
|
246
298
|
Render system prompt from template or return literal.
|
|
247
299
|
|
|
@@ -249,6 +301,10 @@ IMPORTANT TOOL CALLING RULES:
|
|
|
249
301
|
If system_prompt was set via set_system_prompt(), uses that override.
|
|
250
302
|
Otherwise, uses config.system_prompt as literal.
|
|
251
303
|
|
|
304
|
+
Args:
|
|
305
|
+
effective_context: Optional pre-resolved context dict for template rendering.
|
|
306
|
+
If None, uses auto-populated _context_value.
|
|
307
|
+
|
|
252
308
|
Returns:
|
|
253
309
|
Rendered system prompt string
|
|
254
310
|
|
|
@@ -261,7 +317,12 @@ IMPORTANT TOOL CALLING RULES:
|
|
|
261
317
|
|
|
262
318
|
# If template provided, render it
|
|
263
319
|
if self._template is not None:
|
|
264
|
-
|
|
320
|
+
# Use provided effective_context or fall back to auto-populated context
|
|
321
|
+
context = (
|
|
322
|
+
effective_context
|
|
323
|
+
if effective_context is not None
|
|
324
|
+
else self._prepare_context(self._context_value)
|
|
325
|
+
)
|
|
265
326
|
try:
|
|
266
327
|
rendered = self._template.render(**context)
|
|
267
328
|
logger.debug(
|
|
@@ -412,7 +473,12 @@ IMPORTANT TOOL CALLING RULES:
|
|
|
412
473
|
raise RuntimeError(f"Mesh LLM provider invocation failed: {e}") from e
|
|
413
474
|
|
|
414
475
|
async def __call__(
|
|
415
|
-
self,
|
|
476
|
+
self,
|
|
477
|
+
message: Union[str, list[dict[str, Any]]],
|
|
478
|
+
*,
|
|
479
|
+
context: Union[dict, None, object] = _CONTEXT_NOT_PROVIDED,
|
|
480
|
+
context_mode: Literal["replace", "append", "prepend"] = "append",
|
|
481
|
+
**kwargs,
|
|
416
482
|
) -> Any:
|
|
417
483
|
"""
|
|
418
484
|
Execute automatic agentic loop and return typed response.
|
|
@@ -422,6 +488,13 @@ IMPORTANT TOOL CALLING RULES:
|
|
|
422
488
|
- str: Single user message (will be wrapped in messages array)
|
|
423
489
|
- List[Dict[str, Any]]: Full conversation history with messages
|
|
424
490
|
in format [{"role": "user|assistant|system", "content": "..."}]
|
|
491
|
+
context: Optional runtime context for system prompt template rendering.
|
|
492
|
+
Can be dict, MeshContextModel, or None. If not provided,
|
|
493
|
+
uses the auto-populated context from decorator's context_param.
|
|
494
|
+
context_mode: How to merge runtime context with auto-populated context:
|
|
495
|
+
- "append" (default): auto_context | runtime_context (runtime wins on conflicts)
|
|
496
|
+
- "prepend": runtime_context | auto_context (auto wins on conflicts)
|
|
497
|
+
- "replace": use runtime_context entirely (ignores auto-populated)
|
|
425
498
|
**kwargs: Additional arguments passed to LLM
|
|
426
499
|
|
|
427
500
|
Returns:
|
|
@@ -431,6 +504,22 @@ IMPORTANT TOOL CALLING RULES:
|
|
|
431
504
|
MaxIterationsError: If max iterations exceeded
|
|
432
505
|
ToolExecutionError: If tool execution fails
|
|
433
506
|
ValidationError: If response doesn't match output_type schema
|
|
507
|
+
|
|
508
|
+
Examples:
|
|
509
|
+
# Use auto-populated context (default behavior)
|
|
510
|
+
result = await llm("What is the answer?")
|
|
511
|
+
|
|
512
|
+
# Append extra context (runtime wins on key conflicts)
|
|
513
|
+
result = await llm("What is the answer?", context={"extra": "info"})
|
|
514
|
+
|
|
515
|
+
# Prepend context (auto wins on key conflicts)
|
|
516
|
+
result = await llm("What is the answer?", context={"extra": "info"}, context_mode="prepend")
|
|
517
|
+
|
|
518
|
+
# Replace context entirely
|
|
519
|
+
result = await llm("What is the answer?", context={"only": "this"}, context_mode="replace")
|
|
520
|
+
|
|
521
|
+
# Explicitly clear context
|
|
522
|
+
result = await llm("What is the answer?", context={}, context_mode="replace")
|
|
434
523
|
"""
|
|
435
524
|
self._iteration_count = 0
|
|
436
525
|
|
|
@@ -440,8 +529,11 @@ IMPORTANT TOOL CALLING RULES:
|
|
|
440
529
|
"litellm is required for MeshLlmAgent. Install with: pip install litellm"
|
|
441
530
|
)
|
|
442
531
|
|
|
443
|
-
#
|
|
444
|
-
|
|
532
|
+
# Resolve effective context (merge auto-populated with runtime context)
|
|
533
|
+
effective_context = self._resolve_context(context, context_mode)
|
|
534
|
+
|
|
535
|
+
# Render base system prompt (from template or literal) with effective context
|
|
536
|
+
base_system_prompt = self._render_system_prompt(effective_context)
|
|
445
537
|
|
|
446
538
|
# Phase 2: Use provider handler to format system prompt
|
|
447
539
|
# This allows vendor-specific optimizations (e.g., OpenAI skips JSON instructions)
|
|
@@ -29,7 +29,7 @@ class UnifiedMCPProxy:
|
|
|
29
29
|
"""
|
|
30
30
|
|
|
31
31
|
def __init__(
|
|
32
|
-
self, endpoint: str, function_name: str, kwargs_config:
|
|
32
|
+
self, endpoint: str, function_name: str, kwargs_config: dict | None = None
|
|
33
33
|
):
|
|
34
34
|
"""Initialize Unified MCP Proxy.
|
|
35
35
|
|
|
@@ -134,12 +134,20 @@ class UnifiedMCPProxy:
|
|
|
134
134
|
"X-Trace-ID": current_trace.trace_id,
|
|
135
135
|
"X-Parent-Span": current_trace.span_id, # Current span becomes parent for downstream
|
|
136
136
|
}
|
|
137
|
+
self.logger.info(
|
|
138
|
+
f"🔗 TRACE_PROPAGATION: Injecting headers trace_id={current_trace.trace_id[:8]}... "
|
|
139
|
+
f"parent_span={current_trace.span_id[:8]}..."
|
|
140
|
+
)
|
|
137
141
|
return headers
|
|
138
142
|
else:
|
|
143
|
+
self.logger.warning("🔗 TRACE_PROPAGATION: No trace context available")
|
|
139
144
|
return {}
|
|
140
145
|
|
|
141
146
|
except Exception as e:
|
|
142
147
|
# Never fail MCP calls due to tracing issues
|
|
148
|
+
self.logger.warning(
|
|
149
|
+
f"🔗 TRACE_PROPAGATION: Exception getting trace context: {e}"
|
|
150
|
+
)
|
|
143
151
|
return {}
|
|
144
152
|
|
|
145
153
|
def _configure_from_kwargs(self):
|
|
@@ -826,7 +834,7 @@ class EnhancedUnifiedMCPProxy(UnifiedMCPProxy):
|
|
|
826
834
|
"""
|
|
827
835
|
|
|
828
836
|
def __init__(
|
|
829
|
-
self, endpoint: str, function_name: str, kwargs_config:
|
|
837
|
+
self, endpoint: str, function_name: str, kwargs_config: dict | None = None
|
|
830
838
|
):
|
|
831
839
|
"""Initialize Enhanced Unified MCP Proxy."""
|
|
832
840
|
super().__init__(endpoint, function_name, kwargs_config)
|