mirror of
https://github.com/tiennm99/serena.git
synced 2026-10-13 10:16:00 +00:00
SerenaConfig: Use configuration setting 'language_backend' instead of 'jetbrains'
introducing enum LanguageBackend
This commit is contained in:
1 parent
946b0e7d51
commit
d410aa9f90
5 files changed
+70
-35
No files matched your search
@@ -25,7 +25,6 @@ if __name__ == "__main__":
|
||||
|
||||
serena_config = SerenaConfig.from_config_file()
|
||||
serena_config.log_level = logging.INFO
|
||||
serena_config.jetbrains = False
|
||||
serena_config.gui_log_window_enabled = False
|
||||
serena_config.web_dashboard = False
|
||||
|
||||
|
||||
+7
-4
@@ -18,7 +18,7 @@ from interprompt.jinja_template import JinjaTemplate
|
||||
from serena import serena_version
|
||||
from serena.analytics import RegisteredTokenCountEstimator, ToolUsageStats
|
||||
from serena.config.context_mode import SerenaAgentContext, SerenaAgentMode
|
||||
from serena.config.serena_config import SerenaConfig, ToolInclusionDefinition
|
||||
from serena.config.serena_config import LanguageBackend, SerenaConfig, ToolInclusionDefinition
|
||||
from serena.dashboard import SerenaDashboardAPI
|
||||
from serena.ls_manager import LanguageServerManager
|
||||
from serena.project import Project
|
||||
@@ -226,7 +226,10 @@ class SerenaAgent:
|
||||
self._tool_usage_stats = ToolUsageStats(token_count_estimator)
|
||||
|
||||
# log fundamental information
|
||||
log.info(f"Starting Serena server (version={serena_version()}, process id={os.getpid()}, parent process id={os.getppid()})")
|
||||
log.info(
|
||||
f"Starting Serena server (version={serena_version()}, process id={os.getpid()}, parent process id={os.getppid()}; "
|
||||
f"language backend={self.serena_config.language_backend.name})"
|
||||
)
|
||||
log.info("Configuration file: %s", self.serena_config.config_file_path)
|
||||
log.info("Available projects: {}".format(", ".join(self.serena_config.project_names)))
|
||||
log.info(f"Loaded tools ({len(self._all_tools)}): {', '.join([tool.get_name_from_cls() for tool in self._all_tools.values()])}")
|
||||
@@ -238,7 +241,7 @@ class SerenaAgent:
|
||||
tool_inclusion_definitions: list[ToolInclusionDefinition] = [self.serena_config, self._context]
|
||||
if self._context.single_project:
|
||||
tool_inclusion_definitions.extend(self._single_project_context_tool_inclusion_definitions(project))
|
||||
if self.serena_config.jetbrains:
|
||||
if self.serena_config.language_backend == LanguageBackend.JETBRAINS:
|
||||
tool_inclusion_definitions.append(SerenaAgentMode.from_name_internal("jetbrains"))
|
||||
|
||||
self._base_tool_set = ToolSet.default().apply(*tool_inclusion_definitions)
|
||||
@@ -514,7 +517,7 @@ class SerenaAgent:
|
||||
"""
|
||||
:return: whether this agent uses language server-based code analysis
|
||||
"""
|
||||
return not self.serena_config.jetbrains
|
||||
return self.serena_config.language_backend == LanguageBackend.LSP
|
||||
|
||||
def _activate_project(self, project: Project) -> None:
|
||||
log.info(f"Activating {project.project_name} at {project.project_root}")
|
||||
|
||||
@@ -9,6 +9,7 @@ from collections.abc import Iterable
|
||||
from copy import deepcopy
|
||||
from dataclasses import dataclass, field
|
||||
from datetime import datetime
|
||||
from enum import Enum
|
||||
from functools import cached_property
|
||||
from pathlib import Path
|
||||
from typing import TYPE_CHECKING, Any, Optional, Self, TypeVar
|
||||
@@ -106,6 +107,26 @@ def get_serena_managed_in_project_dir(project_root: str | Path) -> str:
|
||||
return os.path.join(project_root, SERENA_MANAGED_DIR_NAME)
|
||||
|
||||
|
||||
class LanguageBackend(Enum):
|
||||
LSP = "LSP"
|
||||
"""
|
||||
Use the language server protocol (LSP), spawning freely available language servers
|
||||
via the SolidLSP library that is part of Serena
|
||||
"""
|
||||
JETBRAINS = "JetBrains"
|
||||
"""
|
||||
Use the Serena plugin in your JetBrains IDE.
|
||||
(requires the plugin to be installed and the project being worked on to be open in your IDE)
|
||||
"""
|
||||
|
||||
@staticmethod
|
||||
def from_str(backend_str: str) -> "LanguageBackend":
|
||||
for backend in LanguageBackend:
|
||||
if backend.value.lower() == backend_str.lower():
|
||||
return backend
|
||||
raise ValueError(f"Unknown language backend '{backend_str}': valid values are {[b.value for b in LanguageBackend]}")
|
||||
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class ProjectConfig(ToolInclusionDefinition, ToStringMixin):
|
||||
project_name: str
|
||||
@@ -362,9 +383,10 @@ class SerenaConfig(ToolInclusionDefinition, ToStringMixin):
|
||||
the path to the configuration file to which updates of the configuration shall be saved;
|
||||
if None, the configuration is not saved to disk
|
||||
"""
|
||||
jetbrains: bool = False
|
||||
|
||||
language_backend: LanguageBackend = LanguageBackend.LSP
|
||||
"""
|
||||
whether to apply JetBrains mode
|
||||
the language backend to use for code understanding features
|
||||
"""
|
||||
|
||||
token_count_estimator: str = RegisteredTokenCountEstimator.CHAR_COUNT.name
|
||||
@@ -446,7 +468,7 @@ class SerenaConfig(ToolInclusionDefinition, ToStringMixin):
|
||||
|
||||
# load list of known projects
|
||||
instance.projects = []
|
||||
num_project_migrations = 0
|
||||
num_migrations = 0
|
||||
for path in loaded_commented_yaml["projects"]:
|
||||
path = Path(path).resolve()
|
||||
if not path.exists() or (path.is_dir() and not (path / ProjectConfig.rel_path_to_project_yml()).exists()):
|
||||
@@ -456,7 +478,7 @@ class SerenaConfig(ToolInclusionDefinition, ToStringMixin):
|
||||
path = cls._migrate_out_of_project_config_file(path)
|
||||
if path is None:
|
||||
continue
|
||||
num_project_migrations += 1
|
||||
num_migrations += 1
|
||||
project_config = ProjectConfig.load(path)
|
||||
project = RegisteredProject(
|
||||
project_root=str(path),
|
||||
@@ -469,7 +491,21 @@ class SerenaConfig(ToolInclusionDefinition, ToStringMixin):
|
||||
field_name = key
|
||||
return loaded_commented_yaml.get(key, get_dataclass_default(SerenaConfig, field_name))
|
||||
|
||||
# set other configuration parameters
|
||||
# determine language backend
|
||||
language_backend = get_dataclass_default(SerenaConfig, "language_backend")
|
||||
if "language_backend" in loaded_commented_yaml:
|
||||
backend_str = loaded_commented_yaml["language_backend"]
|
||||
language_backend = LanguageBackend.from_str(backend_str)
|
||||
else:
|
||||
# backward compatibility (migrate Boolean field "jetbrains")
|
||||
if "jetbrains" in loaded_commented_yaml:
|
||||
num_migrations += 1
|
||||
if loaded_commented_yaml["jetbrains"]:
|
||||
language_backend = LanguageBackend.JETBRAINS
|
||||
del loaded_commented_yaml["jetbrains"]
|
||||
instance.language_backend = language_backend
|
||||
|
||||
# set other configuration parameters (primitive types)
|
||||
instance.gui_log_window_enabled = get_value_or_default("gui_log_window", "gui_log_window_enabled")
|
||||
instance.web_dashboard_listen_address = get_value_or_default("web_dashboard_listen_address")
|
||||
instance.log_level = loaded_commented_yaml.get("log_level", loaded_commented_yaml.get("gui_log_level", logging.INFO))
|
||||
@@ -479,16 +515,13 @@ class SerenaConfig(ToolInclusionDefinition, ToStringMixin):
|
||||
instance.trace_lsp_communication = get_value_or_default("trace_lsp_communication")
|
||||
instance.excluded_tools = get_value_or_default("excluded_tools")
|
||||
instance.included_optional_tools = get_value_or_default("included_optional_tools")
|
||||
instance.jetbrains = get_value_or_default("jetbrains")
|
||||
instance.token_count_estimator = get_value_or_default("token_count_estimator")
|
||||
instance.default_max_tool_answer_chars = get_value_or_default("default_max_tool_answer_chars")
|
||||
instance.ls_specific_settings = get_value_or_default("ls_specific_settings")
|
||||
|
||||
# re-save the configuration file if any migrations were performed
|
||||
if num_project_migrations > 0:
|
||||
log.info(
|
||||
f"Migrated {num_project_migrations} project configurations from legacy format to in-project configuration; re-saving configuration"
|
||||
)
|
||||
if num_migrations > 0:
|
||||
log.info("Legacy configuration was migrated; re-saving configuration file")
|
||||
instance.save()
|
||||
|
||||
return instance
|
||||
@@ -591,9 +624,15 @@ class SerenaConfig(ToolInclusionDefinition, ToStringMixin):
|
||||
"""
|
||||
if self.config_file_path is None:
|
||||
return
|
||||
|
||||
assert self.loaded_commented_yaml is not None, "Cannot save configuration without loaded YAML"
|
||||
|
||||
loaded_original_yaml = deepcopy(self.loaded_commented_yaml)
|
||||
# projects are unique absolute paths
|
||||
# we also canonicalize them before saving
|
||||
|
||||
# convert project objects into list of paths
|
||||
loaded_original_yaml["projects"] = sorted({str(project.project_root) for project in self.projects})
|
||||
|
||||
# convert language backend to string
|
||||
loaded_original_yaml["language_backend"] = self.language_backend.value
|
||||
|
||||
save_yaml(self.config_file_path, loaded_original_yaml, preserve_comments=True)
|
||||
@@ -9,6 +9,7 @@ from pydantic import BaseModel
|
||||
from sensai.util import logging
|
||||
|
||||
from serena.analytics import ToolUsageStats
|
||||
from serena.config.serena_config import LanguageBackend
|
||||
from serena.constants import SERENA_DASHBOARD_DIR
|
||||
from serena.task_executor import TaskExecutor
|
||||
from serena.util.logging import MemoryLogHandler
|
||||
@@ -443,7 +444,7 @@ class SerenaDashboardAPI:
|
||||
available_modes=available_modes,
|
||||
available_contexts=available_contexts,
|
||||
available_memories=available_memories,
|
||||
jetbrains_mode=self._agent.serena_config.jetbrains,
|
||||
jetbrains_mode=self._agent.serena_config.language_backend == LanguageBackend.JETBRAINS,
|
||||
languages=languages,
|
||||
encoding=encoding,
|
||||
)
|
||||
|
||||
@@ -1,3 +1,12 @@
|
||||
language_backend: LSP
|
||||
# the language backend to use for code understanding and manipulation.
|
||||
# Possible values are:
|
||||
# * LSP: Use the language server protocol (LSP), spawning freely available language servers
|
||||
# via the SolidLSP library that is part of Serena.
|
||||
# * JetBrains: Use the Serena plugin in your JetBrains IDE.
|
||||
# (requires the plugin to be installed and the project being worked on to be open
|
||||
# in your IDE).
|
||||
|
||||
gui_log_window: False
|
||||
# whether to open a graphical window with Serena's logs.
|
||||
# This is mainly supported on Windows and (partly) on Linux; not available on macOS.
|
||||
@@ -42,7 +51,6 @@ ls_specific_settings: {}
|
||||
# (same entry as in project.yml) to the options.
|
||||
# Have a look at the docstring of the constructors of the LS implementations within solidlsp (e.g., for C# or PHP) to see which options are available.
|
||||
# No documentation on options means no options are available.
|
||||
#
|
||||
|
||||
tool_timeout: 240
|
||||
# timeout, in seconds, after which tool executions are terminated
|
||||
@@ -53,12 +61,6 @@ excluded_tools: []
|
||||
included_optional_tools: []
|
||||
# list of optional tools (which are disabled by default) to be included
|
||||
|
||||
jetbrains: False
|
||||
# whether to enable JetBrains mode and use tools based on the Serena JetBrains IDE plugin
|
||||
# instead of language server-based tools
|
||||
# NOTE: The plugin is yet unreleased. This is for Serena developers only.
|
||||
|
||||
|
||||
default_max_tool_answer_chars: 150000
|
||||
# Used as default for tools where the apply method has a default maximal answer length.
|
||||
# Even though the value of the max_answer_chars can be changed when calling the tool, it may make sense to adjust this default
|
||||
@@ -73,14 +75,5 @@ token_count_estimator: CHAR_COUNT
|
||||
# data files on first run), or ANTHROPIC_CLAUDE_SONNET_4 which will use the (free of cost) Anthropic API to
|
||||
# estimate the token count using the Claude Sonnet 4 tokenizer.
|
||||
|
||||
|
||||
# MANAGED BY SERENA, KEEP AT THE BOTTOM OF THE YAML AND DON'T EDIT WITHOUT NEED
|
||||
# The list of registered projects.
|
||||
# To add a project, within a chat, simply ask Serena to "activate the project /path/to/project" or,
|
||||
# if the project was previously added, "activate the project <project name>".
|
||||
# By default, the project's name will be the name of the directory containing the project, but you may change it
|
||||
# by editing the (auto-generated) project configuration file `/path/project/project/.serena/project.yml` file.
|
||||
# If you want to maintain full control of the project configuration, create the project.yml file manually and then
|
||||
# instruct Serena to activate the project by its path for first-time activation.
|
||||
# NOTE: Make sure there are no name collisions in the names of registered projects.
|
||||
# The list of registered project paths (updated automatically).
|
||||
projects: []
|
||||
Reference in new issue
Block a user