mirror of
https://github.com/tiennm99/serena.git
synced 2026-10-13 02:14:49 +00:00
Merge branch 'main' into habaneraa/main
This commit is contained in:
commit
6734e5d03c
11 files changed
+40
-16
No files matched your search
@@ -80,8 +80,8 @@ Serena incorporates a powerful abstraction layer for the integration of language
|
||||
that implement the language server protocol (LSP).
|
||||
The underlying language servers are typically open-source projects (like Serena) or at least freely available for use.
|
||||
|
||||
With Serena's LSP library, we provide **support for over 30 programming languages**, including
|
||||
AL, Ansible, Bash, C#, C/C++, Clojure, Dart, Elixir, Elm, Erlang, Fortran, GLSL, Go, Groovy (partial support), Haskell, HLSL, Java, Javascript, Julia, Kotlin, Lean 4, Lua, Luau, Markdown, MATLAB, Nix, OCaml, Perl, PHP, PowerShell, Python, R, Ruby, Rust, Scala, Solidity, Swift, TOML, TypeScript, WGSL, YAML, and Zig.
|
||||
With Serena's LSP library, we provide **support for over 40 programming languages**, including
|
||||
AL, Ansible, Bash, C#, C/C++, Clojure, Dart, Elixir, Elm, Erlang, Fortran, F# (currently with some bugs), GLSL, Go, Groovy (partial support), Haskell, HLSL, Java, Javascript, Julia, Kotlin, Lean 4, Lua, Luau, Markdown, MATLAB, Nix, OCaml, Perl, PHP, PowerShell, Python, R, Ruby, Rust, Scala, Solidity, Swift, TOML, TypeScript, WGSL, YAML, and Zig.
|
||||
|
||||
> [!IMPORTANT]
|
||||
> Some language servers require additional dependencies to be installed; see the [Language Support](https://oraios.github.io/serena/01-about/020_programming-languages.html) page for details.
|
||||
|
||||
+8
-2
@@ -483,7 +483,7 @@ class SerenaAgent:
|
||||
else:
|
||||
log_path = SerenaPaths().last_returned_log_file_path
|
||||
if log_path is not None:
|
||||
return f"Find the current log file here: f{log_path}"
|
||||
return f"Find the current log file here: {log_path}"
|
||||
else:
|
||||
return "Unfortunately, logs are not available. We recommend enabling the web dashboard/logging in general."
|
||||
|
||||
@@ -699,6 +699,11 @@ class SerenaAgent:
|
||||
f"(2) Configure one MCP server per backend in your client."
|
||||
)
|
||||
|
||||
# shut down the previously active project to release its language server processes
|
||||
if self._active_project is not None:
|
||||
log.info(f"Shutting down previously active project '{self._active_project.project_name}' before switching")
|
||||
self._active_project.shutdown()
|
||||
|
||||
self._active_project = project
|
||||
project.set_agent(self)
|
||||
|
||||
@@ -845,7 +850,8 @@ class SerenaAgent:
|
||||
"""
|
||||
Shuts down the agent, freeing resources and stopping background tasks.
|
||||
"""
|
||||
if not hasattr(self, "_is_initialized"):
|
||||
# guard against __del__ being called on a partially constructed instance
|
||||
if not hasattr(self, "_active_project"):
|
||||
return
|
||||
log.info("SerenaAgent is shutting down ...")
|
||||
if self._active_project is not None:
|
||||
|
||||
@@ -5,7 +5,7 @@ from collections.abc import Callable
|
||||
from pathlib import Path
|
||||
from typing import TYPE_CHECKING, Any, Self
|
||||
|
||||
from flask import Flask, Response, request, send_from_directory
|
||||
from flask import Flask, Response, redirect, request, send_from_directory
|
||||
from pydantic import BaseModel
|
||||
from sensai.util import logging
|
||||
|
||||
@@ -148,6 +148,10 @@ class SerenaDashboardAPI:
|
||||
return self._memory_log_handler
|
||||
|
||||
def _setup_routes(self) -> None:
|
||||
@self._app.route("/")
|
||||
def redirect_to_dashboard() -> Response:
|
||||
return redirect("/dashboard/") # type: ignore[return-value]
|
||||
|
||||
# Static files
|
||||
@self._app.route("/dashboard/<path:filename>")
|
||||
def serve_dashboard(filename: str) -> Response:
|
||||
|
||||
+6
-2
@@ -341,8 +341,12 @@ class SerenaMCPFactory:
|
||||
openai_tool_compatible = self.context.name in ["chatgpt", "codex", "oaicompat-agent"]
|
||||
self._set_mcp_tools(mcp_server, openai_tool_compatible=openai_tool_compatible)
|
||||
log.info("MCP server lifetime setup complete")
|
||||
yield
|
||||
log.info("MCP server shutting down")
|
||||
try:
|
||||
yield
|
||||
finally:
|
||||
log.info("MCP server shutting down")
|
||||
if self.agent is not None:
|
||||
self.agent.shutdown()
|
||||
|
||||
def _get_initial_instructions(self) -> str:
|
||||
assert self.agent is not None
|
||||
|
||||
@@ -118,7 +118,7 @@ class CCLS(SolidLanguageServer):
|
||||
"workspaceFolders": [
|
||||
{
|
||||
"uri": root_uri,
|
||||
"name": "$name",
|
||||
"name": os.path.basename(repository_absolute_path),
|
||||
}
|
||||
],
|
||||
# ccls supports initializationOptions but none are required for basic functionality
|
||||
|
||||
@@ -228,7 +228,7 @@ class ClangdLanguageServer(SolidLanguageServer):
|
||||
"workspaceFolders": [
|
||||
{
|
||||
"uri": root_uri,
|
||||
"name": "$name",
|
||||
"name": os.path.basename(repository_absolute_path),
|
||||
}
|
||||
],
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
import logging
|
||||
import os
|
||||
import pathlib
|
||||
import shutil
|
||||
import subprocess
|
||||
import threading
|
||||
@@ -134,7 +135,7 @@ class ErlangLanguageServer(SolidLanguageServer):
|
||||
initialize_params = {
|
||||
"processId": None,
|
||||
"rootPath": self.repository_root_path,
|
||||
"rootUri": f"file://{self.repository_root_path}",
|
||||
"rootUri": pathlib.Path(self.repository_root_path).as_uri(),
|
||||
"capabilities": {
|
||||
"textDocument": {
|
||||
"synchronization": {"didSave": True},
|
||||
|
||||
@@ -166,7 +166,7 @@ class FSharpLanguageServer(SolidLanguageServer):
|
||||
"documentHighlight": {"dynamicRegistration": True},
|
||||
"documentSymbol": {
|
||||
"dynamicRegistration": True,
|
||||
"symbolKind": {"valueSet": list(range(1, 26))}, # All SymbolKind values
|
||||
"symbolKind": {"valueSet": list(range(1, 27))}, # All SymbolKind values (1-26)
|
||||
"hierarchicalDocumentSymbolSupport": True,
|
||||
},
|
||||
"codeAction": {
|
||||
|
||||
+1
-1
@@ -817,7 +817,7 @@ class SolidLanguageServer(ABC):
|
||||
Delete text between the given start and end positions in the given file and return the deleted text.
|
||||
"""
|
||||
if not self.server_started:
|
||||
log.error("insert_text_at_position called before Language Server started")
|
||||
log.error("delete_text_between_positions called before Language Server started")
|
||||
raise SolidLSPException("Language Server not started")
|
||||
|
||||
absolute_file_path = str(PurePath(self.repository_root_path, relative_file_path))
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import platform
|
||||
import shlex
|
||||
import subprocess
|
||||
|
||||
|
||||
@@ -15,8 +16,14 @@ def subprocess_kwargs() -> dict:
|
||||
|
||||
def quote_arg(arg: str) -> str:
|
||||
"""
|
||||
Adds quotes around an argument if it contains spaces.
|
||||
Quotes a shell argument to prevent interpretation of metacharacters.
|
||||
|
||||
Uses :func:`shlex.quote` on POSIX systems for proper escaping of all
|
||||
shell-special characters. On Windows, wraps arguments containing spaces
|
||||
in double quotes (Windows shell does not interpret single-quoted strings).
|
||||
"""
|
||||
if " " not in arg:
|
||||
return arg
|
||||
return f'"{arg}"'
|
||||
if platform.system() == "Windows":
|
||||
if " " not in arg:
|
||||
return arg
|
||||
return f'"{arg}"'
|
||||
return shlex.quote(arg)
|
||||
@@ -10,7 +10,9 @@ from solidlsp.ls_utils import SymbolUtils
|
||||
from test.conftest import is_ci
|
||||
|
||||
|
||||
# Currently, most F# tests fail, there seems to be a regression or instability.
|
||||
@pytest.mark.fsharp
|
||||
@pytest.mark.skipif(is_ci, reason="F# language server is currently unreliable")
|
||||
class TestFSharpLanguageServer:
|
||||
@pytest.mark.parametrize("language_server", [Language.FSHARP], indirect=True)
|
||||
def test_find_symbol(self, language_server: SolidLanguageServer) -> None:
|
||||
|
||||
Reference in new issue
Block a user