Refactoring: Rename ProjectConfig.languages to language_servers

This commit is contained in:
Dominik Jain authored and Dominik Jain committed 2026-07-22 21:41:00 +02:00
1 parent d2cf18ddcb
commit 4f8f9b3fc8
17 files changed
+90 -75

No files matched your search

+19 -11
View File
@@ -1,7 +1,8 @@
# the name by which the project can be referenced within Serena/when chatting with the LLM.
project_name: "serena"
# list of languages for which language servers are started (LSP backend only); choose from:
# list of language servers to start when using the LSP backend; choose from:
# ada al angular ansible bash
# bsl clojure cpp cpp_ccls crystal
# csharp csharp_omnisharp cue dart elixir
@@ -19,7 +20,7 @@ project_name: "serena"
# (This list may be outdated; generated with scripts/print_language_list.py;
# For the current list, see values of Language enum here:
# https://github.com/oraios/serena/blob/main/src/solidlsp/ls_config.py)
# For some languages, there are alternative language servers, e.g. csharp_omnisharp, ruby_solargraph.)
# For some languages, there are several alternative language servers, e.g. csharp_omnisharp, ruby_solargraph.)
# Note:
# - For C, use cpp
# - For JavaScript, use typescript
@@ -28,20 +29,27 @@ project_name: "serena"
# - For SCSS / Sass / plain CSS, use scss (some-sass-language-server handles all three)
# - For Free Pascal/Lazarus, use pascal
# Special requirements:
# Some languages require additional setup/installations.
# Some language servers require additional setup/installations.
# See here for details: https://oraios.github.io/serena/01-about/020_programming-languages.html#language-servers
# When using multiple languages, the first language server that supports a given file will be used for that file.
# The first language is the default language and the respective language server will be used as a fallback.
# When using multiple language servers, the first language server that supports a given file will be used for that file.
# The first language server is the default language and the respective language server will be used as a fallback.
# Note that when using the JetBrains backend, language servers are not used and this list is correspondingly ignored.
languages:
- python
- typescript
language_servers:
- python
- typescript
# whether to use project's .gitignore files to ignore files
ignore_all_files_in_gitignore: true
# list of additional paths to ignore in this project.
# Same syntax as gitignore, so you can use * and **.
# Important: quote patterns that start with `*`, otherwise YAML treats them as aliases.
# Example:
# ignored_paths:
# - "examples/**"
# - ".worktrees/**"
# - "**/bin/**"
# - "**/obj/**"
# Note: global ignored_paths from serena_config.yml are also applied additively.
ignored_paths: []
@@ -179,9 +187,9 @@ ls_workspace_folders:
# Paths can be absolute or relative to the project root.
# Each folder is registered as an LSP workspace folder, enabling language servers to discover
# symbols and references across package boundaries, but these folders are not indexed by Serena,
# i.e. the respective symbols will not be found using Serena's symbol search tool.
# i.e. the respective symbols will not be found using Serena's symbol search tools.
# Example:
# additional_workspace_folders:
# - "../sibling-package"
# - "../shared-lib"
# - ../sibling-package
# - ../shared-lib
ls_additional_workspace_folders: []
+2
View File
@@ -4,6 +4,8 @@ Status of the `main` branch. Changes prior to the next official version change w
* General:
- Add Grok Build support (context `grok`, setup CLI, hooks)
- The `languages` key in project configurations was changed to `language_servers` to better reflect
the actual semantics (configurations are automatically migrated)
* Language Servers:
- Allow language server priorities to be configured in `serena_config.yml` (for auto-detection during
+1 -1
View File
@@ -40,7 +40,7 @@ def make_agent() -> SerenaAgent:
project_root=str(REPO_PATH),
project_config=ProjectConfig(
project_name="demo_serena_repo",
languages=[LanguageServerId.PYTHON],
language_servers=[LanguageServerId.PYTHON],
ignored_paths=[],
excluded_tools=[],
read_only=False,
+1 -1
View File
@@ -29,7 +29,7 @@ def make_agent(project_root: Path, language: LanguageServerId, project_name: str
project_root=str(project_root),
project_config=ProjectConfig(
project_name=project_name,
languages=[language],
language_servers=[language],
ignored_paths=[],
excluded_tools=[],
read_only=False,
+1 -1
View File
@@ -27,7 +27,7 @@ def make_agent(project_root: Path, language: LanguageServerId, project_name: str
project_root=str(project_root),
project_config=ProjectConfig(
project_name=project_name,
languages=[language],
language_servers=[language],
ignored_paths=[],
excluded_tools=[],
read_only=False,
+1 -1
View File
@@ -1028,7 +1028,7 @@ class SerenaAgent:
else:
msg = f"The project with name '{proj.project_name}' at {proj.project_root} is activated."
if self._language_backend == LanguageBackend.LSP:
languages_str = ", ".join([lang.value for lang in proj.project_config.languages])
languages_str = ", ".join([lang.value for lang in proj.project_config.language_servers])
msg += f"\nProgramming languages: {languages_str}."
msg += f"File encoding: {proj.project_config.encoding}."
+8 -3
View File
@@ -717,8 +717,8 @@ class ProjectCommands(AutoRegisteringGroup):
languages=languages if languages else None,
interactive=True,
)
languages_str = ", ".join([lang.value for lang in generated_conf.languages]) if generated_conf.languages else "N/A"
click.echo(f"Generated project with languages {{{languages_str}}} at {yml_path}.")
languages_str = ", ".join([lang.value for lang in generated_conf.language_servers]) if generated_conf.language_servers else "N/A"
click.echo(f"Generated project with language servers {{{languages_str}}} at {yml_path}.")
registered_project = serena_config.get_registered_project(str(project_root))
if registered_project is None:
registered_project = RegisteredProject(str(project_root), generated_conf)
@@ -731,7 +731,11 @@ class ProjectCommands(AutoRegisteringGroup):
@click.argument("project_path", type=click.Path(exists=True, file_okay=False), default=os.getcwd())
@click.option("--name", type=str, default=None, help="Project name; defaults to directory name if not specified.")
@click.option(
"--language", type=str, multiple=True, help="Programming language(s); inferred if not specified. Can be passed multiple times."
"--ls",
"--language",
type=str,
multiple=True,
help="Programming language(s); inferred if not specified. Can be passed multiple times.",
)
@click.option("--index", is_flag=True, help="Index the project after creation.")
@click.option(
@@ -761,6 +765,7 @@ class ProjectCommands(AutoRegisteringGroup):
@click.argument("project", type=PROJECT_TYPE, default=os.getcwd(), required=False)
@click.option("--name", type=str, default=None, help="Project name (only used if auto-creating project.yml).")
@click.option(
"--ls",
"--language",
type=str,
multiple=True,
+18 -18
View File
@@ -321,7 +321,7 @@ class ProjectConfigAutoGenerationMode(Enum):
@dataclass(kw_only=True)
class ProjectConfig(SharedConfig, ModeSelectionDefinitionWithAddedModes):
project_name: str
languages: list[LanguageServerId]
language_servers: list[LanguageServerId]
ignored_paths: list[str] = field(default_factory=list)
ls_workspace_folders: list[str] = field(default_factory=lambda: ["."])
ls_additional_workspace_folders: list[str] = field(default_factory=list)
@@ -338,8 +338,8 @@ class ProjectConfig(SharedConfig, ModeSelectionDefinitionWithAddedModes):
# class-level members
SERENA_PROJECT_FILE = "project.yml"
SERENA_LOCAL_PROJECT_FILE = "project.local.yml"
FIELDS_WITHOUT_DEFAULTS = {"project_name", "languages"}
RENAMED_FIELDS = {"additional_workspace_folders": "ls_additional_workspace_folders"}
FIELDS_WITHOUT_DEFAULTS = {"project_name", "language_servers"}
RENAMED_FIELDS = {"additional_workspace_folders": "ls_additional_workspace_folders", "languages": "language_servers"}
YAML_COMMENT_NORMALISATION = YamlCommentNormalisation.LEADING
"""
the comment normalisation strategy to use when loading/saving project configuration files.
@@ -457,7 +457,7 @@ class ProjectConfig(SharedConfig, ModeSelectionDefinitionWithAddedModes):
languages_to_use = [lang.value for lang in languages]
config_with_comments, _ = cls._load_yaml_dict(PROJECT_TEMPLATE_FILE)
config_with_comments["project_name"] = project_name
config_with_comments["languages"] = languages_to_use
config_with_comments["language_servers"] = languages_to_use
project_yml_path = serena_config.get_project_yml_location(str(project_root))
if save_to_disk:
@@ -478,7 +478,7 @@ class ProjectConfig(SharedConfig, ModeSelectionDefinitionWithAddedModes):
def async_language_determination():
try:
with LogTime("Asynchronous language determination", logger=log):
project_config.languages = cls._determine_project_language_servers(
project_config.language_servers = cls._determine_project_language_servers(
str(project_root), interactive=False, serena_config=serena_config
)
if save_to_disk:
@@ -540,8 +540,8 @@ class ProjectConfig(SharedConfig, ModeSelectionDefinitionWithAddedModes):
# backward compatibility
# NOTE: This must also work for project.local.yml files, which may be highly incomplete
# * handle single "language" field
if "languages" not in data and "language" in data:
data["languages"] = [data["language"]]
if "language" in data and not ("languages" in data or "language_servers" in data):
data["language_servers"] = [data["language"]]
del data["language"]
# * handle renamed fields
for old_key, new_key in cls.RENAMED_FIELDS.items():
@@ -580,18 +580,18 @@ class ProjectConfig(SharedConfig, ModeSelectionDefinitionWithAddedModes):
"""
# map languages to list of enum items, checking for errors
lang_name_mapping = {"javascript": "typescript"}
languages: list[LanguageServerId] = []
for language_str in data["languages"]:
orig_language_str = language_str
ls_ids: list[LanguageServerId] = []
for ls_str in data["language_servers"]:
orig_language_str = ls_str
try:
language_str = language_str.lower()
if language_str in lang_name_mapping:
language_str = lang_name_mapping[language_str]
language = LanguageServerId(language_str)
languages.append(language)
ls_str = ls_str.lower()
if ls_str in lang_name_mapping:
ls_str = lang_name_mapping[ls_str]
ls_id = LanguageServerId(ls_str)
ls_ids.append(ls_id)
except ValueError as e:
raise ValueError(
f"Invalid language: {orig_language_str}.\nValid language_strings are: {[l.value for l in LanguageServerId]}"
f"Invalid language server: '{orig_language_str}'.\nValid values are: {[l.value for l in LanguageServerId]}"
) from e
# Validate activation_command_timeout
@@ -632,7 +632,7 @@ class ProjectConfig(SharedConfig, ModeSelectionDefinitionWithAddedModes):
return cls(
project_name=data["project_name"],
languages=languages,
language_servers=ls_ids,
ignored_paths=ignored_paths,
ls_workspace_folders=data["ls_workspace_folders"],
ls_additional_workspace_folders=additional_workspace_folders,
@@ -669,7 +669,7 @@ class ProjectConfig(SharedConfig, ModeSelectionDefinitionWithAddedModes):
del d[k]
# map fields using non-primitive types to a YAML-compatible representation
d["languages"] = [lang.value for lang in self.languages]
d["language_servers"] = [lang.value for lang in self.language_servers]
d["language_backend"] = self.language_backend.value if self.language_backend is not None else None
d["line_ending"] = self.line_ending.value if self.line_ending is not None else None
+3 -3
View File
@@ -514,7 +514,7 @@ class SerenaDashboardAPI:
active_project_name = project.project_name if project else None
project_info = {
"name": active_project_name,
"language": ", ".join([l.value for l in project.project_config.languages]) if project else None,
"language": ", ".join([l.value for l in project.project_config.language_servers]) if project else None,
"path": str(project.project_root) if project else None,
}
@@ -608,7 +608,7 @@ class SerenaDashboardAPI:
# Get list of languages for the active project
languages = []
if project is not None:
languages = [lang.value for lang in project.project_config.languages]
languages = [lang.value for lang in project.project_config.language_servers]
# Get file encoding for the active project
encoding = None
@@ -646,7 +646,7 @@ class SerenaDashboardAPI:
# Filter out already added languages for the active project
project = self._agent.get_active_project()
if project:
current_languages = [lang.value for lang in project.project_config.languages]
current_languages = [lang.value for lang in project.project_config.language_servers]
available_languages = [lang for lang in all_languages if lang not in current_languages]
else:
available_languages = all_languages
+1 -1
View File
@@ -238,7 +238,7 @@ class Project(ToStringMixin):
if self.language_backend.is_lsp():
if os.path.isfile(abs_path):
is_file_in_supported_language = False
for language in self.project_config.languages:
for language in self.project_config.language_servers:
fn_matcher = language.get_source_fn_matcher()
if fn_matcher.is_relevant_filename(abs_path):
is_file_in_supported_language = True
+6 -6
View File
@@ -1,7 +1,7 @@
# the name by which the project can be referenced within Serena/when chatting with the LLM.
project_name: "project_name"
# list of languages for which language servers are started (LSP backend only); choose from:
# list of language servers to start when using the LSP backend; choose from:
# ada al angular ansible bash
# bsl clojure cpp cpp_ccls crystal
# csharp csharp_omnisharp cue dart elixir
@@ -19,7 +19,7 @@ project_name: "project_name"
# (This list may be outdated; generated with scripts/print_language_list.py;
# For the current list, see values of Language enum here:
# https://github.com/oraios/serena/blob/main/src/solidlsp/ls_config.py)
# For some languages, there are alternative language servers, e.g. csharp_omnisharp, ruby_solargraph.)
# For some languages, there are several alternative language servers, e.g. csharp_omnisharp, ruby_solargraph.)
# Note:
# - For C, use cpp
# - For JavaScript, use typescript
@@ -28,12 +28,12 @@ project_name: "project_name"
# - For SCSS / Sass / plain CSS, use scss (some-sass-language-server handles all three)
# - For Free Pascal/Lazarus, use pascal
# Special requirements:
# Some languages require additional setup/installations.
# Some language servers require additional setup/installations.
# See here for details: https://oraios.github.io/serena/01-about/020_programming-languages.html#language-servers
# When using multiple languages, the first language server that supports a given file will be used for that file.
# The first language is the default language and the respective language server will be used as a fallback.
# When using multiple language servers, the first language server that supports a given file will be used for that file.
# The first language server is the default language and the respective language server will be used as a fallback.
# Note that when using the JetBrains backend, language servers are not used and this list is correspondingly ignored.
languages: ["python"]
language_servers: ["python"]
# the encoding used by text files in the project
# For a list of possible encodings, see https://docs.python.org/3.11/library/codecs.html#standard-encodings
@@ -16,7 +16,7 @@ def _create_test_project(
"""Helper to create a Project with the given ignored paths configuration."""
config = ProjectConfig(
project_name="test_project",
languages=[LanguageServerId.PYTHON],
language_servers=[LanguageServerId.PYTHON],
ignored_paths=project_ignored_paths or [],
ignore_all_files_in_gitignore=False,
)
@@ -145,7 +145,7 @@ class TestRegisteredProjectGlobalIgnoredPaths:
"""RegisteredProject.get_project_instance() passes global_ignored_paths to Project."""
config = ProjectConfig(
project_name="test_project",
languages=[LanguageServerId.PYTHON],
language_servers=[LanguageServerId.PYTHON],
ignored_paths=[],
ignore_all_files_in_gitignore=False,
)
@@ -161,7 +161,7 @@ class TestRegisteredProjectGlobalIgnoredPaths:
"""RegisteredProject without global_ignored_paths defaults to empty."""
config = ProjectConfig(
project_name="test_project",
languages=[LanguageServerId.PYTHON],
language_servers=[LanguageServerId.PYTHON],
ignored_paths=[],
ignore_all_files_in_gitignore=False,
)
@@ -193,7 +193,7 @@ class TestRegisteredProjectGlobalIgnoredPaths:
"""RegisteredProject.from_project_instance() threads global_ignored_paths to Project."""
config = ProjectConfig(
project_name="test_project",
languages=[LanguageServerId.PYTHON],
language_servers=[LanguageServerId.PYTHON],
ignored_paths=[],
ignore_all_files_in_gitignore=False,
)
@@ -233,7 +233,7 @@ class TestGlobalIgnoredPathsWithGitignore:
"""Global patterns, project patterns, and .gitignore patterns are all applied together."""
config = ProjectConfig(
project_name="test_project",
languages=[LanguageServerId.PYTHON],
language_servers=[LanguageServerId.PYTHON],
ignored_paths=["build"],
ignore_all_files_in_gitignore=True,
)
+19 -19
View File
@@ -42,7 +42,7 @@ class TestProjectConfigAutogenerate:
config = ProjectConfig.autogenerate(self.project_path, self.serena_config, save_to_disk=False)
assert config.project_name == self.project_path.name
assert config.languages == []
assert config.language_servers == []
def test_autogenerate_empty_directory_logs_warning(self, caplog):
"""Test that autogenerate logs a warning when no language files are found."""
@@ -62,7 +62,7 @@ class TestProjectConfigAutogenerate:
# Verify the configuration
assert config.project_name == self.project_path.name
assert config.languages == [LanguageServerId.PYTHON]
assert config.language_servers == [LanguageServerId.PYTHON]
def test_autogenerate_with_python_files_and_custom_ls_priorities(self):
"""Test successful autogeneration with Python source files, using custom language server priorities."""
@@ -78,7 +78,7 @@ class TestProjectConfigAutogenerate:
# Verify the configuration
assert config.project_name == self.project_path.name
assert config.languages == [LanguageServerId.PYTHON_TY]
assert config.language_servers == [LanguageServerId.PYTHON_TY]
def test_autogenerate_with_js_files(self):
"""Test successful autogeneration with JavaScript source files."""
@@ -88,7 +88,7 @@ class TestProjectConfigAutogenerate:
# Run autogenerate - should pick Python as dominant
config = ProjectConfig.autogenerate(self.project_path, self.serena_config, save_to_disk=False)
assert config.languages == [LanguageServerId.TYPESCRIPT]
assert config.language_servers == [LanguageServerId.TYPESCRIPT]
def test_autogenerate_with_multiple_languages(self):
"""Test autogeneration picks dominant language when multiple are present."""
@@ -100,7 +100,7 @@ class TestProjectConfigAutogenerate:
# Run autogenerate - should pick Python as dominant
config = ProjectConfig.autogenerate(self.project_path, self.serena_config, save_to_disk=False)
assert config.languages == [LanguageServerId.PYTHON]
assert config.language_servers == [LanguageServerId.PYTHON]
def test_autogenerate_saves_to_disk(self):
"""Test that autogenerate can save the configuration to disk."""
@@ -116,7 +116,7 @@ class TestProjectConfigAutogenerate:
assert config_path.exists()
# Verify the content
assert config.languages == [LanguageServerId.GO]
assert config.language_servers == [LanguageServerId.GO]
def test_autogenerate_nonexistent_path(self):
"""Test that autogenerate raises FileNotFoundError for non-existent path."""
@@ -140,7 +140,7 @@ class TestProjectConfigAutogenerate:
config = ProjectConfig.autogenerate(self.project_path, self.serena_config, save_to_disk=False)
assert config.project_name == self.project_path.name
assert config.languages == []
assert config.language_servers == []
def test_autogenerate_custom_project_name(self):
"""Test autogenerate with custom project name."""
@@ -153,7 +153,7 @@ class TestProjectConfigAutogenerate:
config = ProjectConfig.autogenerate(self.project_path, self.serena_config, project_name=custom_name, save_to_disk=False)
assert config.project_name == custom_name
assert config.languages == [LanguageServerId.TYPESCRIPT]
assert config.language_servers == [LanguageServerId.TYPESCRIPT]
class TestProjectConfig:
@@ -168,14 +168,14 @@ class TestProjectConfigLanguageBackend:
def test_language_backend_defaults_to_none(self):
config = ProjectConfig(
project_name="test",
languages=[LanguageServerId.PYTHON],
language_servers=[LanguageServerId.PYTHON],
)
assert config.language_backend is None
def test_language_backend_can_be_set(self):
config = ProjectConfig(
project_name="test",
languages=[LanguageServerId.PYTHON],
language_servers=[LanguageServerId.PYTHON],
language_backend=LanguageBackend.JETBRAINS,
)
assert config.language_backend == LanguageBackend.JETBRAINS
@@ -183,7 +183,7 @@ class TestProjectConfigLanguageBackend:
def test_language_backend_roundtrips_through_yaml(self):
config = ProjectConfig(
project_name="test",
languages=[LanguageServerId.PYTHON],
language_servers=[LanguageServerId.PYTHON],
language_backend=LanguageBackend.JETBRAINS,
)
d = config._to_yaml_dict()
@@ -192,7 +192,7 @@ class TestProjectConfigLanguageBackend:
def test_language_backend_none_roundtrips_through_yaml(self):
config = ProjectConfig(
project_name="test",
languages=[LanguageServerId.PYTHON],
language_servers=[LanguageServerId.PYTHON],
)
d = config._to_yaml_dict()
assert d["language_backend"] is None
@@ -232,7 +232,7 @@ def _make_config_with_project(
project_root=str(Path(__file__).parent.parent / "resources" / "repos" / "python" / "test_repo"),
project_config=ProjectConfig(
project_name=project_name,
languages=[LanguageServerId.PYTHON],
language_servers=[LanguageServerId.PYTHON],
language_backend=language_backend,
),
serena_config=config,
@@ -286,7 +286,7 @@ class TestEffectiveLanguageBackend:
project_root=str(Path(__file__).parent.parent / "resources" / "repos" / "java" / "test_repo"),
project_config=ProjectConfig(
project_name="jb_proj",
languages=[LanguageServerId.JAVA],
language_servers=[LanguageServerId.JAVA],
language_backend=LanguageBackend.JETBRAINS,
),
serena_config=config,
@@ -309,7 +309,7 @@ class TestEffectiveLanguageBackend:
project_root=str(Path(__file__).parent.parent / "resources" / "repos" / "python" / "test_repo"),
project_config=ProjectConfig(
project_name="lsp_proj2",
languages=[LanguageServerId.PYTHON],
language_servers=[LanguageServerId.PYTHON],
language_backend=LanguageBackend.LSP,
),
serena_config=config,
@@ -332,7 +332,7 @@ class TestEffectiveLanguageBackend:
project_root=str(Path(__file__).parent.parent / "resources" / "repos" / "python" / "test_repo"),
project_config=ProjectConfig(
project_name="proj2",
languages=[LanguageServerId.PYTHON],
language_servers=[LanguageServerId.PYTHON],
language_backend=None,
),
serena_config=config,
@@ -432,7 +432,7 @@ class TestProjectSerenaDataFolder:
def _make_project(self, serena_config: "SerenaConfig | None" = None) -> Project:
project_config = ProjectConfig(
project_name="myproject",
languages=[LanguageServerId.PYTHON],
language_servers=[LanguageServerId.PYTHON],
)
project = Project(
project_root=str(self.project_path),
@@ -679,11 +679,11 @@ class TestProjectConfigActivationCommand:
return data
def test_activation_command_defaults_to_none(self):
config = ProjectConfig(project_name="test", languages=[LanguageServerId.PYTHON])
config = ProjectConfig(project_name="test", language_servers=[LanguageServerId.PYTHON])
assert config.activation_command is None
def test_activation_command_timeout_default(self):
config = ProjectConfig(project_name="test", languages=[LanguageServerId.PYTHON])
config = ProjectConfig(project_name="test", language_servers=[LanguageServerId.PYTHON])
assert config.activation_command_timeout == 180.0
def test_activation_command_parsed_from_dict(self):
+1 -1
View File
@@ -25,7 +25,7 @@ def _make_project(
)
project_config = ProjectConfig(
project_name="test-activation",
languages=[LanguageServerId.PYTHON],
language_servers=[LanguageServerId.PYTHON],
activation_command=activation_command,
activation_command_timeout=activation_command_timeout,
)
+2 -2
View File
@@ -245,13 +245,13 @@ class TestProjectCreateHelper:
config = ProjectCommands._create_project(temp_project_dir_with_python_file, "my-project", ()).project_config
assert isinstance(config, ProjectConfig)
assert config.project_name == "my-project"
assert len(config.languages) >= 1
assert len(config.language_servers) >= 1
def test_create_project_helper_with_languages(self, temp_project_dir):
"""Test _create_project with language specification."""
config = ProjectCommands._create_project(temp_project_dir, None, ("python", "typescript")).project_config
assert isinstance(config, ProjectConfig)
assert len(config.languages) >= 1
assert len(config.language_servers) >= 1
def test_create_project_helper_file_exists_error(self, temp_project_dir):
"""Test _create_project raises error if project.yml exists."""
+1 -1
View File
@@ -31,7 +31,7 @@ class _DummyAgent:
def _make_dashboard(project_languages: list[LanguageServerId] | None) -> SerenaDashboardAPI:
project = None
if project_languages is not None:
project = SimpleNamespace(project_config=SimpleNamespace(languages=project_languages))
project = SimpleNamespace(project_config=SimpleNamespace(language_servers=project_languages))
agent = _DummyAgent(project)
return SerenaDashboardAPI(memory_log_handler=_DummyMemoryLogHandler(), tool_names=[], agent=agent, tool_usage_stats=None)
+1 -1
View File
@@ -799,7 +799,7 @@ def serena_config():
project_root=str(repo_path),
project_config=ProjectConfig(
project_name=project_name,
languages=[language],
language_servers=[language],
ignored_paths=[],
excluded_tools=[],
read_only=False,