Skip to content

Commit 5cd0e04

Browse files
authored
Update config.py
1 parent 7a7064e commit 5cd0e04

1 file changed

Lines changed: 35 additions & 0 deletions

File tree

python_agent_harness/config.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import sys
88
from pathlib import Path
99

10+
from .lsp.config import LSPConfig
1011
from .mcp.config import MCPConfig
1112

1213
# ---- context management -------------------------------------------------
@@ -256,6 +257,15 @@
256257
"context_path": null,
257258
"skill_path": null
258259
}},
260+
"lsp": {{
261+
"_comment": "Optional per-extension LSP server overrides. Keys are file extensions (e.g. '.py', '.cpp'); 'command' is the server argv; 'language_id' defaults to the extension without the dot. These override the built-in DEFAULT_SERVERS table. Remove this section to use only the built-ins. The server binary must be on PATH. The '.example' entry below is inert (no such extension) — copy it to a real extension like '.cpp' to activate.",
262+
"servers": {{
263+
".example": {{
264+
"command": ["clangd", "--background-index", "--clang-tidy"],
265+
"language_id": "cpp"
266+
}}
267+
}}
268+
}},
259269
"mcp": {{
260270
"_comment": "Optional MCP servers (requires: pip install -e '.[mcp]'). Each server's tools become agent tools named mcp__<server>__<tool>. Transports: stdio (spawn command+args, pass through env var names), streamable-http / sse (connect to url, optional headers). 'parallel: true' marks read-only servers whose tools may run concurrently; default is serial. 'timeout' bounds connects, discovery and calls (seconds).",
261271
"servers": {{
@@ -447,6 +457,31 @@ def load_mcp_config(path: str | os.PathLike | None = None) -> MCPConfig:
447457
return MCPConfig.from_dict(section.get("servers"))
448458

449459

460+
def load_lsp_config(path: str | os.PathLike | None = None) -> LSPConfig:
461+
"""Load per-extension LSP server overrides from the config file.
462+
463+
Reads the optional ``lsp.servers`` object (keyed by file extension,
464+
e.g. ``".py"``) and returns an ``LSPConfig`` (empty when the file
465+
has no ``lsp`` section or no servers). These entries layer on top of
466+
the built-in ``DEFAULT_SERVERS`` table in ``lsp/manager.py``.
467+
468+
Malformed entries raise ValueError so config errors surface at
469+
session start rather than the first LSP call.
470+
"""
471+
data = _read_config(path)
472+
section = data.get("lsp") or {}
473+
if not isinstance(section, dict):
474+
raise ValueError(f"config file {_config_path(path)}: lsp must be an object")
475+
servers = section.get("servers") or {}
476+
if not isinstance(servers, dict):
477+
raise ValueError(f"config file {_config_path(path)}: lsp.servers must be an object")
478+
try:
479+
return LSPConfig.from_dict(servers)
480+
except ValueError as e:
481+
# Re-raise with the config-file path for a clearer message.
482+
raise ValueError(f"config file {_config_path(path)}: {e}") from e
483+
484+
450485
def load_models_config(path: str | os.PathLike | None = None) -> dict[str, dict]:
451486
"""Load named LLM profiles from the config file's ``models`` object.
452487

0 commit comments

Comments
 (0)