dispatch_agents 0.14.2__tar.gz → 0.14.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/PKG-INFO +1 -1
- dispatch_agents-0.14.3/RELEASE_NOTES.md +2 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/dispatch_agents/mcp.py +36 -2
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/pyproject.toml +1 -1
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/tests/test_mcp.py +68 -2
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/uv.lock +1 -1
- dispatch_agents-0.14.2/RELEASE_NOTES.md +0 -2
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/.claude-plugin/marketplace.json +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/.github/scripts/change_scope.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/.github/scripts/ci_git.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/.github/scripts/version_policy.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/.github/tests/test_change_scope.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/.github/tests/test_ci_git.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/.github/tests/test_version_policy.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/.github/workflows/ci-reusable.yml +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/.github/workflows/feature-branch.yml +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/.github/workflows/release.yml +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/.github/workflows/version-policy-reusable.yml +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/.gitignore +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/CONTRIBUTING.md +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/LICENSE +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/LICENSE-3rdparty.csv +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/NOTICE +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/README.md +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/agentservice/__init__.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/agentservice/py.typed +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/agentservice/v1/__init__.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/agentservice/v1/message_pb2.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/agentservice/v1/message_pb2.pyi +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/agentservice/v1/message_pb2_grpc.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/agentservice/v1/request_response_pb2.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/agentservice/v1/request_response_pb2.pyi +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/agentservice/v1/request_response_pb2_grpc.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/agentservice/v1/service_pb2.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/agentservice/v1/service_pb2.pyi +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/agentservice/v1/service_pb2_grpc.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/dispatch_agents/__init__.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/dispatch_agents/_deprecated_public_api.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/dispatch_agents/_internal/__init__.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/dispatch_agents/_internal/agent_service.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/dispatch_agents/_internal/bootstrap.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/dispatch_agents/_internal/config_validation.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/dispatch_agents/_internal/dev.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/dispatch_agents/_internal/dispatch.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/dispatch_agents/_internal/grpc_server.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/dispatch_agents/_internal/instrument.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/dispatch_agents/_internal/llm_langchain.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/dispatch_agents/_internal/models.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/dispatch_agents/_internal/proxy/__init__.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/dispatch_agents/_internal/proxy/server.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/dispatch_agents/_internal/proxy/sse_utils.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/dispatch_agents/_internal/transport.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/dispatch_agents/_internal/version.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/dispatch_agents/config.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/dispatch_agents/context.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/dispatch_agents/contrib/__init__.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/dispatch_agents/contrib/claude/__init__.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/dispatch_agents/contrib/openai/__init__.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/dispatch_agents/events.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/dispatch_agents/handlers.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/dispatch_agents/integrations/__init__.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/dispatch_agents/integrations/github/README.md +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/dispatch_agents/integrations/github/__init__.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/dispatch_agents/integrations/github/client.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/dispatch_agents/integrations/github/events.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/dispatch_agents/invocation.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/dispatch_agents/llm.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/dispatch_agents/logging.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/dispatch_agents/memory.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/dispatch_agents/models.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/dispatch_agents/py.typed +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/dispatch_agents/storage.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/examples/README.md +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/examples/company-researcher/.gitignore +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/examples/company-researcher/AGENTS.md +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/examples/company-researcher/README.md +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/examples/company-researcher/agent.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/examples/company-researcher/dispatch.yaml +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/examples/company-researcher/pyproject.toml +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/examples/company-researcher/uv.lock +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/examples/conversational-agent/README.md +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/examples/conversational-agent/agent.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/examples/conversational-agent/dispatch.yaml +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/examples/conversational-agent/pyproject.toml +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/examples/daily-digest/README.md +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/examples/daily-digest/agent.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/examples/daily-digest/dispatch.yaml +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/examples/daily-digest/pyproject.toml +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/examples/deep-research/README.md +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/examples/deep-research/agent.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/examples/deep-research/configuration.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/examples/deep-research/deep_researcher.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/examples/deep-research/dispatch.yaml +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/examples/deep-research/prompts.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/examples/deep-research/pyproject.toml +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/examples/deep-research/state.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/examples/deep-research/tools.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/examples/hello_world/.gitignore +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/examples/hello_world/AGENTS.md +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/examples/hello_world/README.md +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/examples/hello_world/agent.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/examples/hello_world/dispatch.yaml +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/examples/hello_world/pyproject.toml +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/examples/hello_world/test_agent.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/examples/hello_world/uv.lock +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/examples/knowledge-base-query/.env.example +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/examples/knowledge-base-query/.gitignore +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/examples/knowledge-base-query/AGENTS.md +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/examples/knowledge-base-query/agent.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/examples/knowledge-base-query/dispatch.yaml +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/examples/knowledge-base-query/pyproject.toml +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/examples/multi-framework/README.md +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/examples/multi-framework/agent.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/examples/multi-framework/dispatch.yaml +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/examples/multi-framework/pyproject.toml +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/examples/pyproject.toml +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/examples/uv.lock +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/examples/weather-assistant/.gitignore +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/examples/weather-assistant/AGENTS.md +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/examples/weather-assistant/agent.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/examples/weather-assistant/dispatch.yaml +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/examples/weather-assistant/pyproject.toml +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/examples/weather-assistant/uv.lock +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/examples/weather-service/.gitignore +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/examples/weather-service/AGENTS.md +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/examples/weather-service/agent.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/examples/weather-service/dispatch.yaml +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/examples/weather-service/pyproject.toml +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/examples/weather-service/uv.lock +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/internal/py.typed +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/plugins/README.md +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/tests/__init__.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/tests/conftest.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/tests/e2e_claude_mcp_proxy.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/tests/schemas/README.md +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/tests/schemas/octokit-webhooks.json +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/tests/test.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/tests/test_agent_service.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/tests/test_agent_uid.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/tests/test_config.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/tests/test_contrib_claude.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/tests/test_contrib_openai.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/tests/test_dev_mode_isolation.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/tests/test_extra_headers.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/tests/test_fn_decorator.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/tests/test_github_client.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/tests/test_github_integration.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/tests/test_github_schema_compliance.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/tests/test_grpc_server.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/tests/test_init.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/tests/test_instrument.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/tests/test_llm_langchain.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/tests/test_llm_logging.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/tests/test_logging.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/tests/test_memory.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/tests/test_proxy_e2e.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/tests/test_proxy_server.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/tests/test_public_api.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/tests/test_resources.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/tests/test_sse_utils.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/tests/test_trace_context.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/tests/test_typed_events.py +0 -0
- {dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/tests/typing_checks.py +0 -0
|
@@ -26,6 +26,7 @@ from dispatch_agents._internal.dispatch import (
|
|
|
26
26
|
get_current_trace_id,
|
|
27
27
|
get_invocation_id_for_trace,
|
|
28
28
|
)
|
|
29
|
+
from dispatch_agents.logging import get_logger
|
|
29
30
|
|
|
30
31
|
if TYPE_CHECKING:
|
|
31
32
|
from dispatch_agents.models import (
|
|
@@ -41,6 +42,8 @@ if TYPE_CHECKING:
|
|
|
41
42
|
|
|
42
43
|
__all__ = ["MCPClient", "get_mcp_client", "get_mcp_servers_config"]
|
|
43
44
|
|
|
45
|
+
_logger = get_logger(__name__)
|
|
46
|
+
|
|
44
47
|
MCP_CONFIG_PATH = os.environ.get("MCP_CONFIG_PATH", ".mcp.json")
|
|
45
48
|
|
|
46
49
|
|
|
@@ -282,14 +285,29 @@ def _get_dispatch_mcp_servers() -> dict[str, Any]:
|
|
|
282
285
|
|
|
283
286
|
Constructs URLs and auth headers from runtime environment variables
|
|
284
287
|
(``DISPATCH_MCP_GATEWAY_URL``, ``DISPATCH_NAMESPACE``, ``DISPATCH_API_KEY``).
|
|
285
|
-
No file I/O.
|
|
288
|
+
No file I/O. Returns ``{}`` in local dev, where the gateway is unavailable.
|
|
286
289
|
"""
|
|
290
|
+
from dispatch_agents._internal.transport import is_local_dev_mode
|
|
287
291
|
from dispatch_agents.config import _load_runtime_config
|
|
288
292
|
|
|
289
293
|
cfg = _load_runtime_config()
|
|
290
294
|
if not cfg.mcp_servers:
|
|
291
295
|
return {}
|
|
292
296
|
|
|
297
|
+
# The MCP gateway is a deployed/production concern; it is not available under
|
|
298
|
+
# `dispatch agent dev` (the local router does not proxy /api/v1/mcp/...). Skip
|
|
299
|
+
# dispatch-managed servers in local dev rather than crashing on the missing
|
|
300
|
+
# gateway URL. Authors who want to exercise MCP locally supply a .mcp.json.
|
|
301
|
+
if is_local_dev_mode():
|
|
302
|
+
names = ", ".join(s.server for s in cfg.mcp_servers)
|
|
303
|
+
_logger.warning(
|
|
304
|
+
"Skipping dispatch-managed MCP server(s) in local dev mode: %s. "
|
|
305
|
+
"The MCP gateway is not available under `dispatch agent dev`. "
|
|
306
|
+
"To test MCP locally, define the server(s) in a .mcp.json file.",
|
|
307
|
+
names,
|
|
308
|
+
)
|
|
309
|
+
return {}
|
|
310
|
+
|
|
293
311
|
gateway = _require_env("DISPATCH_MCP_GATEWAY_URL")
|
|
294
312
|
namespace = os.environ.get("DISPATCH_NAMESPACE") or cfg.namespace
|
|
295
313
|
if not namespace:
|
|
@@ -346,13 +364,25 @@ def _get_merged_mcp_servers() -> dict[str, Any]:
|
|
|
346
364
|
|
|
347
365
|
def _get_server_config(server_name: str) -> dict[str, Any]:
|
|
348
366
|
"""Get configuration for a specific MCP server."""
|
|
367
|
+
from dispatch_agents._internal.transport import is_local_dev_mode
|
|
368
|
+
|
|
349
369
|
servers = _get_merged_mcp_servers()
|
|
350
370
|
if server_name not in servers:
|
|
351
371
|
available = list(servers.keys())
|
|
352
|
-
|
|
372
|
+
message = (
|
|
353
373
|
f"MCP server '{server_name}' not found in config. "
|
|
354
374
|
f"Available servers: {available}"
|
|
355
375
|
)
|
|
376
|
+
# Dispatch-managed servers are skipped under `dispatch agent dev` (the
|
|
377
|
+
# local router does not proxy the MCP gateway), so a server declared in
|
|
378
|
+
# dispatch.yaml will be absent here. Point the author at the local escape
|
|
379
|
+
# hatch rather than leaving them with a bare "not found".
|
|
380
|
+
if is_local_dev_mode():
|
|
381
|
+
message += (
|
|
382
|
+
" Dispatch-managed MCP servers are skipped under `dispatch agent "
|
|
383
|
+
"dev`; define the server in a .mcp.json file to use it locally."
|
|
384
|
+
)
|
|
385
|
+
raise ValueError(message)
|
|
356
386
|
return servers[server_name]
|
|
357
387
|
|
|
358
388
|
|
|
@@ -365,6 +395,10 @@ def get_mcp_servers_config() -> dict[str, McpHttpServerConfig]:
|
|
|
365
395
|
is merged additively; duplicate names with dispatch-managed servers are
|
|
366
396
|
rejected.
|
|
367
397
|
|
|
398
|
+
In local dev (``dispatch agent dev``) the MCP gateway is unavailable, so
|
|
399
|
+
dispatch-managed servers are skipped and only ``.mcp.json`` servers are
|
|
400
|
+
returned.
|
|
401
|
+
|
|
368
402
|
Returns:
|
|
369
403
|
Mapping of server name to HTTP URL and headers.
|
|
370
404
|
|
|
@@ -5,6 +5,7 @@ config builders.
|
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
7
|
import json
|
|
8
|
+
import logging
|
|
8
9
|
from unittest.mock import AsyncMock, MagicMock, patch
|
|
9
10
|
|
|
10
11
|
import pytest
|
|
@@ -272,6 +273,7 @@ class TestGetDispatchMcpServers:
|
|
|
272
273
|
|
|
273
274
|
def test_missing_required_env_raises(self, monkeypatch):
|
|
274
275
|
monkeypatch.delenv("DISPATCH_MCP_GATEWAY_URL", raising=False)
|
|
276
|
+
monkeypatch.delenv("DISPATCH_LOCAL_DEV", raising=False)
|
|
275
277
|
monkeypatch.setenv("DISPATCH_NAMESPACE", "ns")
|
|
276
278
|
monkeypatch.setenv("DISPATCH_API_KEY", "key")
|
|
277
279
|
|
|
@@ -285,6 +287,33 @@ class TestGetDispatchMcpServers:
|
|
|
285
287
|
):
|
|
286
288
|
_get_dispatch_mcp_servers()
|
|
287
289
|
|
|
290
|
+
def test_local_dev_skips_dispatch_servers(self, monkeypatch, caplog):
|
|
291
|
+
# In local dev the MCP gateway is unavailable, so dispatch-managed
|
|
292
|
+
# servers are skipped (with a warning) instead of crashing.
|
|
293
|
+
monkeypatch.setenv("DISPATCH_LOCAL_DEV", "true")
|
|
294
|
+
monkeypatch.delenv("DISPATCH_MCP_GATEWAY_URL", raising=False)
|
|
295
|
+
|
|
296
|
+
config = DispatchConfig(
|
|
297
|
+
mcp_servers=[MCPServerConfig(server="my-server")],
|
|
298
|
+
)
|
|
299
|
+
|
|
300
|
+
# The SDK logger sets propagate=False, so caplog's root handler never
|
|
301
|
+
# sees the record. Attach caplog's handler to the SDK logger directly.
|
|
302
|
+
sdk_logger = logging.getLogger("dispatch_agents")
|
|
303
|
+
sdk_logger.addHandler(caplog.handler)
|
|
304
|
+
try:
|
|
305
|
+
with patch(
|
|
306
|
+
"dispatch_agents.config._load_runtime_config", return_value=config
|
|
307
|
+
):
|
|
308
|
+
with caplog.at_level("WARNING", logger="dispatch_agents"):
|
|
309
|
+
result = _get_dispatch_mcp_servers()
|
|
310
|
+
finally:
|
|
311
|
+
sdk_logger.removeHandler(caplog.handler)
|
|
312
|
+
|
|
313
|
+
assert result == {}
|
|
314
|
+
assert "local dev mode" in caplog.text
|
|
315
|
+
assert "my-server" in caplog.text
|
|
316
|
+
|
|
288
317
|
|
|
289
318
|
class TestGetMergedMcpServers:
|
|
290
319
|
def test_merges_dispatch_and_user_servers(self, tmp_path, monkeypatch):
|
|
@@ -326,6 +355,28 @@ class TestGetMergedMcpServers:
|
|
|
326
355
|
|
|
327
356
|
assert list(result) == ["dispatch-server"]
|
|
328
357
|
|
|
358
|
+
def test_local_dev_uses_only_user_servers(self, tmp_path, monkeypatch):
|
|
359
|
+
# In local dev, dispatch-managed servers are skipped, so the merged set
|
|
360
|
+
# comes entirely from the user's .mcp.json -- no gateway URL required.
|
|
361
|
+
monkeypatch.setenv("DISPATCH_LOCAL_DEV", "true")
|
|
362
|
+
monkeypatch.delenv("DISPATCH_MCP_GATEWAY_URL", raising=False)
|
|
363
|
+
|
|
364
|
+
config = DispatchConfig(
|
|
365
|
+
mcp_servers=[MCPServerConfig(server="dispatch-server")],
|
|
366
|
+
)
|
|
367
|
+
|
|
368
|
+
user_config = {"mcpServers": {"user-server": {"url": "http://user:3000"}}}
|
|
369
|
+
config_file = tmp_path / ".mcp.json"
|
|
370
|
+
config_file.write_text(json.dumps(user_config))
|
|
371
|
+
|
|
372
|
+
with (
|
|
373
|
+
patch("dispatch_agents.config._load_runtime_config", return_value=config),
|
|
374
|
+
patch("dispatch_agents.mcp.MCP_CONFIG_PATH", str(config_file)),
|
|
375
|
+
):
|
|
376
|
+
result = _get_merged_mcp_servers()
|
|
377
|
+
|
|
378
|
+
assert list(result) == ["user-server"]
|
|
379
|
+
|
|
329
380
|
def test_duplicate_user_server_raises(self, tmp_path, monkeypatch):
|
|
330
381
|
monkeypatch.setenv("DISPATCH_MCP_GATEWAY_URL", "https://gw.example.com")
|
|
331
382
|
monkeypatch.setenv("DISPATCH_NAMESPACE", "ns")
|
|
@@ -350,13 +401,28 @@ class TestGetMergedMcpServers:
|
|
|
350
401
|
|
|
351
402
|
|
|
352
403
|
class TestGetServerConfig:
|
|
353
|
-
def test_not_found_raises(self, tmp_path):
|
|
404
|
+
def test_not_found_raises(self, tmp_path, monkeypatch):
|
|
405
|
+
monkeypatch.delenv("DISPATCH_LOCAL_DEV", raising=False)
|
|
354
406
|
config = {"mcpServers": {"other-server": {"url": "http://localhost:3000"}}}
|
|
355
407
|
config_file = tmp_path / ".mcp.json"
|
|
356
408
|
config_file.write_text(json.dumps(config))
|
|
357
409
|
|
|
358
410
|
with patch("dispatch_agents.mcp.MCP_CONFIG_PATH", str(config_file)):
|
|
359
|
-
with pytest.raises(ValueError, match="not found in config"):
|
|
411
|
+
with pytest.raises(ValueError, match="not found in config") as exc_info:
|
|
412
|
+
_get_server_config("missing-server")
|
|
413
|
+
# Outside local dev, no dev-mode hint is appended.
|
|
414
|
+
assert "dispatch agent dev" not in str(exc_info.value)
|
|
415
|
+
|
|
416
|
+
def test_not_found_in_local_dev_hints_at_mcp_json(self, tmp_path, monkeypatch):
|
|
417
|
+
# In local dev a dispatch-managed server is skipped, so it is absent here.
|
|
418
|
+
# The error should point the author at the .mcp.json escape hatch instead
|
|
419
|
+
# of leaving them with a bare "not found".
|
|
420
|
+
monkeypatch.setenv("DISPATCH_LOCAL_DEV", "true")
|
|
421
|
+
config_file = tmp_path / ".mcp.json"
|
|
422
|
+
config_file.write_text(json.dumps({"mcpServers": {}}))
|
|
423
|
+
|
|
424
|
+
with patch("dispatch_agents.mcp.MCP_CONFIG_PATH", str(config_file)):
|
|
425
|
+
with pytest.raises(ValueError, match="dispatch agent dev"):
|
|
360
426
|
_get_server_config("missing-server")
|
|
361
427
|
|
|
362
428
|
def test_returns_server_config(self, tmp_path):
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/.github/workflows/version-policy-reusable.yml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/agentservice/v1/request_response_pb2_grpc.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/dispatch_agents/_internal/agent_service.py
RENAMED
|
File without changes
|
|
File without changes
|
{dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/dispatch_agents/_internal/config_validation.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/dispatch_agents/_internal/llm_langchain.py
RENAMED
|
File without changes
|
|
File without changes
|
{dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/dispatch_agents/_internal/proxy/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/dispatch_agents/_internal/proxy/sse_utils.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/dispatch_agents/contrib/claude/__init__.py
RENAMED
|
File without changes
|
{dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/dispatch_agents/contrib/openai/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/dispatch_agents/integrations/github/README.md
RENAMED
|
File without changes
|
{dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/dispatch_agents/integrations/github/__init__.py
RENAMED
|
File without changes
|
{dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/dispatch_agents/integrations/github/client.py
RENAMED
|
File without changes
|
{dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/dispatch_agents/integrations/github/events.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/examples/company-researcher/pyproject.toml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/examples/conversational-agent/dispatch.yaml
RENAMED
|
File without changes
|
{dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/examples/conversational-agent/pyproject.toml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/examples/knowledge-base-query/.env.example
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/examples/knowledge-base-query/dispatch.yaml
RENAMED
|
File without changes
|
{dispatch_agents-0.14.2 → dispatch_agents-0.14.3}/examples/knowledge-base-query/pyproject.toml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|