From 69d14891ca359443c99ff85c71956ca410e5976d Mon Sep 17 00:00:00 2001 From: Dominik Jain Date: Sat, 8 Aug 2026 17:46:15 +0200 Subject: [PATCH] Minor refactoring: Rename _format_prompt to _render_prompt, adding docstring --- CHANGELOG.md | 4 +++- src/serena/agent.py | 22 ++++++++++++++++------ 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 755801f7..75148ebe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,7 +16,9 @@ Status of the `main` branch. Changes prior to the next official version change w - ProjectServer: Configure trusted hosts (local hosts only) when listening on localhost - SerenaDashboardTrayManager: Configure trusted hosts (local hosts only) - Enclose sub-prompts in XML-like tags to make scopes explicit - - Allow initial project prompts and project-specific newly activated modes to use templating + - Prompts and prompt templates: + - Allow initial project prompts and project-specific newly activated modes to use templating + - Support function `embed_memory` in prompt templates to inline a memory's contents * CLI: - Fix: `start-mcp-server` help text for `--project-from-cwd` falsely promised a fallback to the CWD, which was diff --git a/src/serena/agent.py b/src/serena/agent.py index 82376cb4..898bfcab 100644 --- a/src/serena/agent.py +++ b/src/serena/agent.py @@ -956,12 +956,22 @@ class SerenaAgent: result[tool_class.get_name_from_cls()] = new_tool_class.get_name_from_cls() return result - def _format_prompt_tag(self, text: str, tag: str, tag_name_attr: str | None = None) -> str: + @staticmethod + def _format_prompt_tag(text: str, tag: str, tag_name_attr: str | None = None) -> str: open_tag = f"<{tag}" + (f' name="{tag_name_attr}"' if tag_name_attr is not None else "") + ">" close_tag = f"" return f"{open_tag}\n{text.strip()}\n{close_tag}" - def _format_prompt(self, prompt_template: str, tag: str | None = None, tag_name_attr: str | None = None) -> str: + def _render_prompt(self, prompt_template: str, tag: str | None = None, tag_name_attr: str | None = None) -> str: + """ + Renders the given prompt template, providing the necessary variables and functions + + :param prompt_template: the template text (jinja2) to render + :param tag: if not None, wraps the rendered prompt text in a tag + :param tag_name_attr: for the case where tag is not None, specifies the value of the "name" attribute of the tag + :return: the rendered prompt + """ + def embed_memory(memory_name: str) -> str: try: memory_manager = self._get_memory_manager() @@ -1029,8 +1039,8 @@ class SerenaAgent: self._project_prompt_status.mark_mode_prompts_as_provided(session_id) system_prompt = self.prompt_factory.create_system_prompt( - context_system_prompt=self._format_prompt(self._context.prompt, tag="context"), - mode_system_prompts=[self._format_prompt(mode.prompt, tag="mode", tag_name_attr=mode.name) for mode in relevant_modes], + context_system_prompt=self._render_prompt(self._context.prompt, tag="context"), + mode_system_prompts=[self._render_prompt(mode.prompt, tag="mode", tag_name_attr=mode.name) for mode in relevant_modes], available_tools=available_tools.tool_names, available_markers=available_markers, global_memories_list=global_memories_str, @@ -1087,12 +1097,12 @@ class SerenaAgent: modes_with_prompts = self._project_prompt_status.get_modes_with_prompts_to_be_provided_for_project_activation(session_id) if modes_with_prompts: for mode in modes_with_prompts: - msg += self._format_prompt(mode.prompt, tag="mode", tag_name_attr=mode.name) + "\n" + msg += self._render_prompt(mode.prompt, tag="mode", tag_name_attr=mode.name) + "\n" self._project_prompt_status.mark_mode_prompts_as_provided(session_id) # add project-specific prompt if proj.project_config.initial_prompt: - msg += "\n" + self._format_prompt(proj.project_config.initial_prompt, tag="project-instructions") + msg += "\n" + self._render_prompt(proj.project_config.initial_prompt, tag="project-instructions") self._project_prompt_status.mark_project_activation_message_as_provided(session_id)