mirror of
https://github.com/tiennm99/serena.git
synced 2026-10-13 12:15:10 +00:00
Towards finalization of mode and context handling, WIP
This commit is contained in:
1 parent
13a1d236dc
commit
494189ba16
6 files changed
+73
-68
No files matched your search
@@ -8,7 +8,6 @@ prompts:
|
||||
files containing general information about the codebase. You operate in a frugal and intelligent manner, always
|
||||
keeping in mind to not read or generate content that is not needed for the task at hand.
|
||||
|
||||
{context_system_prompt}
|
||||
{{ context_system_prompt }}
|
||||
|
||||
{mode_system_prompt}
|
||||
|
||||
{{ mode_system_prompt }}
|
||||
@@ -1,5 +1,5 @@
|
||||
"""
|
||||
Autogenerates the `prompt_factory.py` module
|
||||
Autogenerates the `prompt_factory.py` module
|
||||
"""
|
||||
|
||||
from pathlib import Path
|
||||
@@ -15,7 +15,7 @@ log = logging.getLogger(__name__)
|
||||
def main():
|
||||
autogenerate_prompt_factory_module(
|
||||
prompts_dir=PROMPT_TEMPLATES_DIR,
|
||||
target_module_path=str(Path(REPO_ROOT) / "src" / "serena" / "prompt_factory.py"),
|
||||
target_module_path=str(Path(REPO_ROOT) / "src" / "serena" / "generated" / "generated_prompt_factory.py"),
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -357,11 +357,12 @@ def autogenerate_prompt_factory_module(prompts_dir: str, target_module_path: str
|
||||
:param target_module_path: the path to the target module file. Important: The module will be overwritten!
|
||||
"""
|
||||
generated_code = """
|
||||
# NOTE: This class is auto-generated from interprompt.autogenerate_prompt_factory_module, do not edit manually!
|
||||
# ruff: noqa
|
||||
# black: skip
|
||||
# mypy: ignore-errors
|
||||
|
||||
# NOTE: This module is auto-generated from interprompt.autogenerate_prompt_factory_module, do not edit manually!
|
||||
|
||||
from interprompt.promt_template import PromptFactoryBase, PromptList
|
||||
from typing import Any
|
||||
|
||||
@@ -390,7 +391,7 @@ class PromptFactory(PromptFactoryBase):
|
||||
def get_list_{prompt_list_name}(self) -> PromptList:
|
||||
return self._get_prompt_list('{prompt_list_name}')
|
||||
"""
|
||||
|
||||
os.makedirs(os.path.dirname(target_module_path), exist_ok=True)
|
||||
with open(target_module_path, "w", encoding="utf-8") as f:
|
||||
f.write(generated_code)
|
||||
log.info(f"Prompt factory generated successfully in {target_module_path}")
|
||||
+26
-33
@@ -29,7 +29,7 @@ from multilspy.multilspy_config import Language, MultilspyConfig
|
||||
from multilspy.multilspy_logger import MultilspyLogger
|
||||
from multilspy.multilspy_types import SymbolKind
|
||||
from serena import serena_root_path, serena_version
|
||||
from serena.prompt_factory import PromptFactory
|
||||
from serena.prompt_factory import PromptFactory, SerenaPromptFactory
|
||||
from serena.symbol import SymbolLocation, SymbolManager
|
||||
from serena.text_utils import search_files
|
||||
from serena.util.class_decorators import singleton
|
||||
@@ -225,7 +225,7 @@ class SerenaAgent:
|
||||
log.info("Available projects: {}".format(", ".join(self.serena_config.project_names)))
|
||||
|
||||
# Initialize the prompt factory
|
||||
self.prompt_factory = PromptFactory()
|
||||
self.prompt_factory = SerenaPromptFactory()
|
||||
self._project_activation_callback = project_activation_callback
|
||||
|
||||
# Load context and mode configuration
|
||||
@@ -311,20 +311,13 @@ class SerenaAgent:
|
||||
|
||||
:param context: Name or path of the context to use
|
||||
"""
|
||||
try:
|
||||
context_config = self.config_loader.get_context(context)
|
||||
self.current_context = context_config
|
||||
context_config = self.config_loader.get_context(context)
|
||||
self.current_context = context_config
|
||||
|
||||
# Update the prompt factory with the new context
|
||||
self.prompt_factory.set_context(context_config.system_prompt_extension)
|
||||
# Update tool configurations
|
||||
self._update_active_tools()
|
||||
|
||||
# Update tool configurations
|
||||
self._update_active_tools()
|
||||
|
||||
log.info(f"Set context to '{context_config.name}': {context_config.description}")
|
||||
except Exception as e:
|
||||
log.error(f"Failed to set context '{context}': {e}")
|
||||
raise
|
||||
log.info(f"Set context to '{context_config.name}': {context_config.description}")
|
||||
|
||||
def set_modes(self, modes: list[str]) -> None:
|
||||
"""
|
||||
@@ -332,29 +325,29 @@ class SerenaAgent:
|
||||
|
||||
:param modes: List of mode names or paths to use
|
||||
"""
|
||||
try:
|
||||
# Check for tool activation conflicts between modes
|
||||
mode_configs = [self.config_loader.get_mode(mode) for mode in modes]
|
||||
mode_configs = [self.config_loader.get_mode(mode) for mode in modes]
|
||||
self._check_mode_conflicts(mode_configs)
|
||||
self.current_modes = mode_configs
|
||||
self._update_active_tools()
|
||||
|
||||
# Check for conflicts in tool exclusions between modes
|
||||
self._check_mode_conflicts(mode_configs)
|
||||
log.info(f"Set modes to {[mode.name for mode in mode_configs]}")
|
||||
|
||||
self.current_modes = mode_configs
|
||||
def _get_modes_system_prompt(self) -> str:
|
||||
return "\n".join([mode.system_prompt_extension for mode in self.current_modes])
|
||||
|
||||
# Update the prompt factory with the new modes
|
||||
mode_extensions = [mode.system_prompt_extension for mode in mode_configs]
|
||||
self.prompt_factory.set_modes(mode_extensions)
|
||||
def _get_context_system_prompt(self) -> str:
|
||||
return self.current_context.system_prompt_extension
|
||||
|
||||
# Update tool configurations
|
||||
self._update_active_tools()
|
||||
def create_system_prompt(self) -> str:
|
||||
context_system_prompt = self._get_context_system_prompt()
|
||||
mode_system_prompt = self._get_modes_system_prompt()
|
||||
return self.prompt_factory.create_system_prompt(
|
||||
context_system_prompt=context_system_prompt,
|
||||
mode_system_prompt=mode_system_prompt,
|
||||
)
|
||||
|
||||
mode_names = [mode.name for mode in mode_configs]
|
||||
log.info(f"Set modes to {mode_names}")
|
||||
except Exception as e:
|
||||
log.error(f"Failed to set modes {modes}: {e}")
|
||||
raise
|
||||
|
||||
def _check_mode_conflicts(self, mode_configs: list["ConfigData"]) -> None:
|
||||
@staticmethod
|
||||
def _check_mode_conflicts(mode_configs: list["ConfigData"]) -> None:
|
||||
"""
|
||||
Check for conflicts in tool exclusions between modes.
|
||||
|
||||
@@ -1549,7 +1542,7 @@ class InitialInstructionsTool(Tool):
|
||||
Get the initial instructions for the current coding project.
|
||||
You should always call this tool before starting to work (including using any other tool) on any programming task!
|
||||
"""
|
||||
return self.agent.prompt_factory.create_system_prompt()
|
||||
return self.agent.create_system_prompt()
|
||||
|
||||
|
||||
def iter_tool_classes(same_module_only: bool = True) -> Generator[type[Tool], None, None]:
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
# ruff: noqa
|
||||
# black: skip
|
||||
# mypy: ignore-errors
|
||||
|
||||
# NOTE: This module is auto-generated from interprompt.autogenerate_prompt_factory_module, do not edit manually!
|
||||
|
||||
from interprompt.promt_template import PromptFactoryBase, PromptList
|
||||
from typing import Any
|
||||
|
||||
|
||||
class PromptFactory(PromptFactoryBase):
|
||||
"""
|
||||
A class for retrieving and rendering prompt templates and prompt lists.
|
||||
"""
|
||||
|
||||
def create_onboarding_prompt(self, *, system: Any) -> str:
|
||||
return self._render_prompt("onboarding_prompt", system=system)
|
||||
|
||||
def create_think_about_collected_information(self) -> str:
|
||||
return self._render_prompt("think_about_collected_information")
|
||||
|
||||
def create_think_about_task_adherence(self) -> str:
|
||||
return self._render_prompt("think_about_task_adherence")
|
||||
|
||||
def create_think_about_whether_you_are_done(self) -> str:
|
||||
return self._render_prompt("think_about_whether_you_are_done")
|
||||
|
||||
def create_summarize_changes(self) -> str:
|
||||
return self._render_prompt("summarize_changes")
|
||||
|
||||
def create_prepare_for_new_conversation(self) -> str:
|
||||
return self._render_prompt("prepare_for_new_conversation")
|
||||
|
||||
def create_system_prompt(self, *, context_system_prompt: Any, mode_system_prompt: Any) -> str:
|
||||
return self._render_prompt("system_prompt", context_system_prompt=context_system_prompt, mode_system_prompt=mode_system_prompt)
|
||||
@@ -1,34 +1,11 @@
|
||||
from serena.constants import PROMPT_TEMPLATES_DIR
|
||||
from serena.generated.generated_prompt_factory import PromptFactory
|
||||
|
||||
# NOTE: This class is auto-generated from interprompt.autogenerate_prompt_factory_module, do not edit manually!
|
||||
# ruff: noqa
|
||||
# black: skip
|
||||
# mypy: ignore-errors
|
||||
|
||||
from interprompt.promt_template import PromptFactoryBase, PromptList
|
||||
from typing import Any
|
||||
|
||||
class PromptFactory(PromptFactoryBase):
|
||||
class SerenaPromptFactory(PromptFactory):
|
||||
"""
|
||||
A class for retrieving and rendering prompt templates and prompt lists.
|
||||
"""
|
||||
|
||||
def create_onboarding_prompt(self, *, system: Any) -> str:
|
||||
return self._render_prompt("onboarding_prompt", system=system)
|
||||
|
||||
def create_think_about_collected_information(self) -> str:
|
||||
return self._render_prompt("think_about_collected_information")
|
||||
|
||||
def create_think_about_task_adherence(self) -> str:
|
||||
return self._render_prompt("think_about_task_adherence")
|
||||
|
||||
def create_think_about_whether_you_are_done(self) -> str:
|
||||
return self._render_prompt("think_about_whether_you_are_done")
|
||||
|
||||
def create_summarize_changes(self) -> str:
|
||||
return self._render_prompt("summarize_changes")
|
||||
|
||||
def create_prepare_for_new_conversation(self) -> str:
|
||||
return self._render_prompt("prepare_for_new_conversation")
|
||||
|
||||
def create_system_prompt(self) -> str:
|
||||
return self._render_prompt("system_prompt")
|
||||
def __init__(self):
|
||||
super().__init__(PROMPT_TEMPLATES_DIR)
|
||||
Reference in new issue
Block a user