mirror of
https://github.com/tiennm99/serena.git
synced 2026-10-12 20:15:56 +00:00
Merge branch 'main' into v1-beta
This commit is contained in:
commit
620a226878
3 files changed
+47
-27
No files matched your search
+44
-3
@@ -2,6 +2,7 @@
|
||||
The Serena Model Context Protocol (MCP) Server
|
||||
"""
|
||||
|
||||
import json
|
||||
import multiprocessing
|
||||
import os
|
||||
import platform
|
||||
@@ -35,7 +36,16 @@ from serena.ls_manager import LanguageServerManager
|
||||
from serena.project import MemoriesManager, Project
|
||||
from serena.prompt_factory import SerenaPromptFactory
|
||||
from serena.task_executor import TaskExecutor
|
||||
from serena.tools import ActivateProjectTool, GetCurrentConfigTool, OpenDashboardTool, ReplaceContentTool, Tool, ToolMarker, ToolRegistry
|
||||
from serena.tools import (
|
||||
ActivateProjectTool,
|
||||
GetCurrentConfigTool,
|
||||
OpenDashboardTool,
|
||||
ReadMemoryTool,
|
||||
ReplaceContentTool,
|
||||
Tool,
|
||||
ToolMarker,
|
||||
ToolRegistry,
|
||||
)
|
||||
from serena.util.gui import system_has_usable_display
|
||||
from serena.util.inspection import iter_subclasses
|
||||
from serena.util.logging import MemoryLogHandler
|
||||
@@ -81,6 +91,9 @@ class AvailableTools:
|
||||
def contains_tool_name(self, tool_name: str) -> bool:
|
||||
return tool_name in self._tool_name_set
|
||||
|
||||
def contains_tool_class(self, tool_class: type[Tool]) -> bool:
|
||||
return self.contains_tool_name(tool_class.get_name_from_cls())
|
||||
|
||||
|
||||
class ToolSet:
|
||||
"""
|
||||
@@ -579,7 +592,7 @@ class SerenaAgent:
|
||||
stdin=subprocess.DEVNULL,
|
||||
stdout=subprocess.DEVNULL,
|
||||
stderr=subprocess.DEVNULL,
|
||||
start_new_session=True, # Detach from parent process
|
||||
start_new_session=False,
|
||||
)
|
||||
|
||||
def get_exposed_tool_instances(self) -> list["Tool"]:
|
||||
@@ -648,11 +661,39 @@ class SerenaAgent:
|
||||
|
||||
# If a project is active at startup, append its activation message
|
||||
if self._active_project is not None:
|
||||
system_prompt += "\n\n" + self._active_project.get_activation_message()
|
||||
system_prompt += "\n\n" + self.get_project_activation_message()
|
||||
|
||||
log.info("System prompt:\n%s", system_prompt)
|
||||
return system_prompt
|
||||
|
||||
def get_project_activation_message(self) -> str:
|
||||
"""
|
||||
:return: a message providing information about the project upon activation (e.g. programming language, memories, initial prompt)
|
||||
:raise: AssertionError if no project is active
|
||||
"""
|
||||
proj = self._active_project
|
||||
assert proj is not None, "A project must be active before calling this."
|
||||
if proj.is_newly_created:
|
||||
msg = f"Created and activated a new project with name '{proj.project_name}' at {proj.project_root}. "
|
||||
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])
|
||||
msg += f"\nProgramming languages: {languages_str}."
|
||||
msg += "File encoding: {proj.project_config.encoding}."
|
||||
|
||||
include_memories = self._active_tools.contains_tool_class(ReadMemoryTool)
|
||||
if include_memories:
|
||||
project_memories = proj.memories_manager.list_project_memories()
|
||||
if project_memories:
|
||||
msg += (
|
||||
f"\n{json.dumps(project_memories.to_dict())}\n"
|
||||
+ "Use the `read_memory` tool to read these memories later if they are relevant to the task."
|
||||
)
|
||||
if proj.project_config.initial_prompt:
|
||||
msg += f"\nAdditional project-specific instructions:\n {proj.project_config.initial_prompt}"
|
||||
return msg
|
||||
|
||||
def _update_active_modes(self) -> None:
|
||||
"""
|
||||
Updates the active modes based on the Serena configuration, the active project configuration (if any),
|
||||
|
||||
+1
-22
@@ -1,4 +1,3 @@
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
@@ -291,7 +290,7 @@ class Project(ToStringMixin):
|
||||
|
||||
self.language_server_manager: LanguageServerManager | None = None
|
||||
self._language_server_manager_init_error: Exception | None = None
|
||||
self._is_newly_created = is_newly_created
|
||||
self.is_newly_created = is_newly_created
|
||||
self._agent: Optional["SerenaAgent"] = None
|
||||
|
||||
# create .gitignore file in the project's Serena data folder if not yet present
|
||||
@@ -379,26 +378,6 @@ class Project(ToStringMixin):
|
||||
def path_to_project_yml(self) -> str:
|
||||
return self.serena_config.get_project_yml_location(self.project_root)
|
||||
|
||||
def get_activation_message(self) -> str:
|
||||
"""
|
||||
:return: a message providing information about the project upon activation (e.g. programming language, memories, initial prompt)
|
||||
"""
|
||||
if self._is_newly_created:
|
||||
msg = f"Created and activated a new project with name '{self.project_name}' at {self.project_root}. "
|
||||
else:
|
||||
msg = f"The project with name '{self.project_name}' at {self.project_root} is activated."
|
||||
languages_str = ", ".join([lang.value for lang in self.project_config.languages])
|
||||
msg += f"\nProgramming languages: {languages_str}; file encoding: {self.project_config.encoding}"
|
||||
project_memories = self.memories_manager.list_project_memories()
|
||||
if project_memories:
|
||||
msg += (
|
||||
f"\nAvailable project memories: {json.dumps(project_memories.to_dict())}\n"
|
||||
+ "Use the `read_memory` tool to read these memories later if they are relevant to the task."
|
||||
)
|
||||
if self.project_config.initial_prompt:
|
||||
msg += f"\nAdditional project-specific instructions:\n {self.project_config.initial_prompt}"
|
||||
return msg
|
||||
|
||||
def read_file(self, relative_path: str) -> str:
|
||||
"""
|
||||
Reads a file relative to the project root.
|
||||
|
||||
@@ -28,8 +28,8 @@ class ActivateProjectTool(Tool, ToolMarkerDoesNotRequireActiveProject):
|
||||
|
||||
:param project: the name of a registered project to activate or a path to a project directory
|
||||
"""
|
||||
active_project = self.agent.activate_project_from_path_or_name(project)
|
||||
result = active_project.get_activation_message()
|
||||
self.agent.activate_project_from_path_or_name(project)
|
||||
result = self.agent.get_project_activation_message()
|
||||
result += "\nIMPORTANT: If you have not yet read the 'Serena Instructions Manual', do it now before continuing!"
|
||||
return result
|
||||
|
||||
|
||||
Reference in new issue
Block a user