fix(lsp): wire LspRuntime and LspToolAdapter into actor execution
CI / push-validation (pull_request) Successful in 27s
CI / helm (pull_request) Successful in 33s
CI / build (pull_request) Successful in 1m0s
CI / lint (pull_request) Failing after 1m23s
CI / quality (pull_request) Successful in 1m24s
CI / typecheck (pull_request) Successful in 1m33s
CI / security (pull_request) Successful in 1m52s
CI / coverage (pull_request) Has been skipped
CI / unit_tests (pull_request) Failing after 3m30s
CI / docker (pull_request) Has been skipped
CI / e2e_tests (pull_request) Successful in 3m39s
CI / integration_tests (pull_request) Successful in 3m57s
CI / status-check (pull_request) Failing after 4s

- Replace standard logging with structlog in LspActorService to fix typecheck errors (structlog uses keyword arguments for structured logging, not positional like stdlib logging)

- Fix LspServerConfig command field: use str not list[str] in test step definitions

- Add _MockLifecycleManager stub to prevent real LSP server process spawning during unit tests

- Rename duplicate step "a clean LSP registry" to "a clean LSP actor service registry" to avoid conflict with lsp_registry_steps.py

- Fix B904 lint error: raise ValueError from None in except clause
This commit is contained in:
HAL9000
2026-04-23 12:36:47 +00:00
parent 7e4f40bcc9
commit 63ffbd082b
3 changed files with 42 additions and 8 deletions
+1 -1
View File
@@ -1,7 +1,7 @@
Feature: LSP Actor Service — wire LspRuntime and LspToolAdapter into actor execution Feature: LSP Actor Service — wire LspRuntime and LspToolAdapter into actor execution
Background: Background:
Given a clean LSP registry Given a clean LSP actor service registry
And a test workspace directory And a test workspace directory
Scenario: LspActorService activates bindings and generates tool specs Scenario: LspActorService activates bindings and generates tool specs
+38 -5
View File
@@ -3,23 +3,56 @@
from __future__ import annotations from __future__ import annotations
import tempfile import tempfile
from pathlib import Path
from typing import Any from typing import Any
from behave import given, then, when from behave import given, then, when
from cleveragents.application.services.lsp_actor_service import LspActorService from cleveragents.application.services.lsp_actor_service import LspActorService
from cleveragents.lsp.client import LspClient
from cleveragents.lsp.lifecycle import LspLifecycleManager
from cleveragents.lsp.models import LspBinding, LspCapability, LspServerConfig from cleveragents.lsp.models import LspBinding, LspCapability, LspServerConfig
from cleveragents.lsp.registry import LspRegistry from cleveragents.lsp.registry import LspRegistry
@given("a clean LSP registry") class _MockLifecycleManager(LspLifecycleManager):
"""Stub lifecycle manager that does not spawn real processes."""
def __init__(self) -> None:
self._servers: dict[str, object] = {}
self._started: set[str] = set()
def start_server(self, config: LspServerConfig, workspace_path: str) -> LspClient:
"""Record the server as started without spawning a process."""
self._started.add(config.name)
mock_client: LspClient = LspClient.__new__(LspClient)
return mock_client
def stop_server(self, name: str) -> None:
"""Record the server as stopped."""
self._started.discard(name)
def health_check(self, name: str) -> bool:
"""Return True if the server was started."""
return name in self._started
def stop_all(self) -> None:
"""Clear all started servers."""
self._started.clear()
def _make_mock_lifecycle() -> LspLifecycleManager:
"""Create a mock lifecycle manager that does not spawn real processes."""
return _MockLifecycleManager()
@given("a clean LSP actor service registry")
def step_clean_lsp_registry(context: Any) -> None: def step_clean_lsp_registry(context: Any) -> None:
"""Initialize a clean LSP registry.""" """Initialize a clean LSP registry."""
context.registry = LspRegistry() context.registry = LspRegistry()
context.service = LspActorService() context.service = LspActorService()
# Override the service's registry with our test registry # Override the service's registry and lifecycle with test doubles
context.service._runtime._registry = context.registry context.service._runtime._registry = context.registry
context.service._runtime._lifecycle = _make_mock_lifecycle()
@given("a test workspace directory") @given("a test workspace directory")
@@ -37,11 +70,11 @@ def step_register_lsp_server(context: Any, server_name: str) -> None:
try: try:
capabilities.append(LspCapability[cap_name]) capabilities.append(LspCapability[cap_name])
except KeyError: except KeyError:
raise ValueError(f"Unknown capability: {cap_name}") raise ValueError(f"Unknown capability: {cap_name}") from None
config = LspServerConfig( config = LspServerConfig(
name=server_name, name=server_name,
command=["echo", "mock-server"], command="echo",
capabilities=capabilities, capabilities=capabilities,
) )
context.registry.register(config) context.registry.register(config)
@@ -13,13 +13,14 @@ Based on docs/specification.md LSP Integration (Server Lifecycle).
from __future__ import annotations from __future__ import annotations
import logging
from typing import Any from typing import Any
import structlog
from cleveragents.lsp.runtime import LspRuntime from cleveragents.lsp.runtime import LspRuntime
from cleveragents.lsp.tool_adapter import LspToolAdapter from cleveragents.lsp.tool_adapter import LspToolAdapter
logger = logging.getLogger(__name__) logger = structlog.get_logger(__name__)
class LspActorService: class LspActorService: