fix: install system mcp when they fail
This commit is contained in:
@@ -2346,10 +2346,6 @@ class LiteLLMProvider(LLMProvider):
|
||||
kwargs["extra_body"]["store"] = False
|
||||
|
||||
request_summary = _summarize_request_for_log(kwargs)
|
||||
logger.debug(
|
||||
"[stream] prepared request: %s",
|
||||
json.dumps(request_summary, default=str),
|
||||
)
|
||||
if request_summary["system_only"]:
|
||||
logger.warning(
|
||||
"[stream] %s request has no non-system chat messages "
|
||||
|
||||
@@ -137,6 +137,13 @@ class MCPRegistry:
|
||||
Skips entirely when the source-tree ``tools/`` directory cannot
|
||||
be located (e.g. wheel installs). Returns the list of names that
|
||||
were newly registered.
|
||||
|
||||
Also runs a self-heal pass over already-registered defaults: if an
|
||||
entry's stdio cwd is unreachable on this machine (e.g. the registry
|
||||
was copied from another developer's box and points at their
|
||||
``/Users/<them>/...`` path), the entry is overwritten with the
|
||||
canonical config so the queen can actually spawn it. The user's
|
||||
``enabled`` toggle and ``overrides`` are preserved.
|
||||
"""
|
||||
# parents: [0]=loader, [1]=framework, [2]=core, [3]=repo root
|
||||
tools_dir = Path(__file__).resolve().parents[3] / "tools"
|
||||
@@ -165,8 +172,32 @@ class MCPRegistry:
|
||||
)
|
||||
del existing[stale]
|
||||
mutated = True
|
||||
|
||||
repaired: list[str] = []
|
||||
for name, spec in _DEFAULT_LOCAL_SERVERS.items():
|
||||
entry = existing.get(name)
|
||||
if entry is None:
|
||||
continue
|
||||
if self._default_entry_runnable(entry, tools_dir, list(spec["args"])):
|
||||
continue
|
||||
existing[name] = self._build_default_entry(
|
||||
name=name,
|
||||
spec=spec,
|
||||
cwd=cwd,
|
||||
preserve_from=entry,
|
||||
)
|
||||
repaired.append(name)
|
||||
mutated = True
|
||||
|
||||
if mutated:
|
||||
self._write_installed(data)
|
||||
if repaired:
|
||||
logger.warning(
|
||||
"MCPRegistry._seed_defaults: repaired %d default server(s) with "
|
||||
"unreachable cwd/script: %s",
|
||||
len(repaired),
|
||||
repaired,
|
||||
)
|
||||
|
||||
for name, spec in _DEFAULT_LOCAL_SERVERS.items():
|
||||
if name in existing:
|
||||
@@ -188,6 +219,93 @@ class MCPRegistry:
|
||||
logger.info("MCPRegistry: seeded default local servers: %s", added)
|
||||
return added
|
||||
|
||||
@staticmethod
|
||||
def _default_entry_runnable(
|
||||
entry: dict, tools_dir: Path, canonical_args: list[str]
|
||||
) -> bool:
|
||||
"""Return True iff ``entry`` can plausibly be spawned on this machine.
|
||||
|
||||
Checks:
|
||||
- transport is stdio (only stdio defaults exist today; non-stdio
|
||||
gets a free pass since we have nothing to compare against)
|
||||
- stdio.cwd is an existing directory
|
||||
- the entry script (the first ``.py`` arg, e.g. ``files_server.py``)
|
||||
exists relative to that cwd
|
||||
|
||||
We deliberately do NOT spawn the subprocess here — this runs on
|
||||
every read path and must be cheap. A filesystem reachability
|
||||
check catches the cross-machine `cwd` drift that is the common
|
||||
failure, without flapping on transient runtime errors.
|
||||
"""
|
||||
transport = entry.get("transport") or "stdio"
|
||||
if transport != "stdio":
|
||||
return True
|
||||
manifest = entry.get("manifest") or {}
|
||||
stdio = manifest.get("stdio") or {}
|
||||
cwd_str = stdio.get("cwd")
|
||||
if not cwd_str:
|
||||
return False
|
||||
cwd_path = Path(cwd_str)
|
||||
if not cwd_path.is_dir():
|
||||
return False
|
||||
# Find the script: the first arg ending in .py, falling back to the
|
||||
# canonical spec if the registered args are unrecognizable. Modules
|
||||
# invoked via `python -m foo.bar` (no .py arg) are accepted as long
|
||||
# as the cwd exists — we can't cheaply prove the module imports.
|
||||
registered_args = stdio.get("args") or []
|
||||
script: str | None = next(
|
||||
(a for a in registered_args if isinstance(a, str) and a.endswith(".py")),
|
||||
None,
|
||||
)
|
||||
if script is None:
|
||||
script = next(
|
||||
(a for a in canonical_args if isinstance(a, str) and a.endswith(".py")),
|
||||
None,
|
||||
)
|
||||
if script is None:
|
||||
return True
|
||||
return (cwd_path / script).is_file()
|
||||
|
||||
@classmethod
|
||||
def _build_default_entry(
|
||||
cls,
|
||||
*,
|
||||
name: str,
|
||||
spec: dict[str, Any],
|
||||
cwd: str,
|
||||
preserve_from: dict | None,
|
||||
) -> dict:
|
||||
"""Construct a fresh canonical entry for a default server.
|
||||
|
||||
When ``preserve_from`` is provided, carries over the user's
|
||||
``enabled`` flag and ``overrides`` so a deliberate disable or
|
||||
custom env var survives the repair.
|
||||
"""
|
||||
manifest = {
|
||||
"name": name,
|
||||
"description": spec["description"],
|
||||
"transport": {"supported": ["stdio"], "default": "stdio"},
|
||||
"stdio": {
|
||||
"command": "uv",
|
||||
"args": list(spec["args"]),
|
||||
"env": {},
|
||||
"cwd": cwd,
|
||||
},
|
||||
}
|
||||
entry = cls._make_entry(
|
||||
source="local",
|
||||
manifest=manifest,
|
||||
transport="stdio",
|
||||
installed_by="hive mcp init (auto-repair)",
|
||||
)
|
||||
if preserve_from is not None:
|
||||
if "enabled" in preserve_from:
|
||||
entry["enabled"] = bool(preserve_from["enabled"])
|
||||
prior_overrides = preserve_from.get("overrides")
|
||||
if isinstance(prior_overrides, dict):
|
||||
entry["overrides"] = prior_overrides
|
||||
return entry
|
||||
|
||||
# ── Internal I/O ────────────────────────────────────────────────
|
||||
|
||||
def _read_installed(self) -> dict:
|
||||
|
||||
Reference in New Issue
Block a user