From a9bc2c648379e1145fc9e4226330a95ceafb40af Mon Sep 17 00:00:00 2001 From: Michael Panchenko Date: Wed, 16 Jul 2025 15:48:37 +0200 Subject: [PATCH] Minor extension of print_system_prompt command, added explanation on using it to readme [ci skip] --- README.md | 8 +++++-- src/serena/agent.py | 38 +++++++++++++++++------------- src/serena/tools/workflow_tools.py | 6 ++--- 3 files changed, 31 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index f509fd6e..7a1cfe3d 100644 --- a/README.md +++ b/README.md @@ -354,8 +354,12 @@ For example, when using `uvx`, you would run claude mcp add serena -- uvx --from git+https://github.com/oraios/serena serena-mcp-server --context ide-assistant --project $(pwd) ``` -ℹ️ Once in Claude Code, run `/mcp__serena__initial_instructions` to load instructions for using Serena's tools. Run this command -whenever you start a new conversation and after any compacting operation to ensure Claude remains properly configured to use Serena's tools. +ℹ️ Serena comes with instructions on how to use tools, and Claude needs to read them to properly use serena's tools. + Once in Claude Code, you can ask to "read Serena's initial instructions" or to run `/mcp__serena__initial_instructions` to load instructions for using Serena's tools. + Do this whenever you start a new conversation and after any compacting operation to ensure Claude remains properly configured to use Serena's tools. + +ℹ️ **NEW**: an alternative to the above is adding the instructions as part of the system prompt, then you will not need to run the command above or to remember re-running it after compacting. + This can be achieved throug starting claude code with `cclaude --append-system-prompt $(uvx --from git+https://github.com/oraios/serena print-system-prompt)`. This is **experimental**, Claude may not understand the instructions correctly in this way. Please report any issues you encounter. ### Claude Desktop diff --git a/src/serena/agent.py b/src/serena/agent.py index 1fa85e90..ac24417f 100644 --- a/src/serena/agent.py +++ b/src/serena/agent.py @@ -127,28 +127,34 @@ def index_project(project: str, log_level: str = "INFO") -> None: @click.command() @click.argument("project", type=click.Path(exists=True), required=False, default=os.getcwd()) @click.option("--log-level", type=click.Choice(["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]), default="WARNING") -def print_system_prompt(project: str, log_level: str = "WARNING") -> None: +@click.option( + "--only-instructions", + is_flag=True, + help="If set, only print the initial instructions prompt (without prefix or postfix). The prefix and postfix are small additions that are used to" + "make the initial instructions more digestible for an LLM in the context of a system prompt, as opposed to their normal usage within a conversation.", +) +def print_system_prompt(project: str, log_level: str = "WARNING", only_instructions: bool = False) -> None: """ - Print the system prompt (initial instructions) for a project. + Print the system prompt (initial instructions with a potential pre/post-fix) for a project. + """ + prefix_to_instructions_prompt = ( + "You will receive access to Serena's symbolic tools. Below are instructions for using them, take them into account." + ) + postfix_to_instructions_prompt = "You begin the conversation by acknowledging that you understood the above instructions on the symbolic tools and are ready to receive a task. You will not need to call the tool on getting initial instructions." + + from serena.tools.workflow_tools import InitialInstructionsTool - :param project: the project to get the system prompt for. By default, the current working directory is used. - """ log_level_int = logging.getLevelNamesMapping()[log_level.upper()] logging.configure(level=log_level_int) - # Create a SerenaAgent instance - agent = SerenaAgent(project=os.path.abspath(project)) - - # Get the InitialInstructionsTool instance - from serena.tools.workflow_tools import InitialInstructionsTool - + agent = SerenaAgent(project=os.path.abspath(project), serena_config=SerenaConfig(web_dashboard=False, log_level=log_level_int)) initial_instructions_tool = agent.get_tool(InitialInstructionsTool) - - # Apply the tool to get the system prompt - system_prompt = initial_instructions_tool.apply() - - # Print the system prompt - print(system_prompt) + initial_instructions = initial_instructions_tool.apply() + if only_instructions: + print(initial_instructions) + else: + system_prompt = f"{prefix_to_instructions_prompt}\n{initial_instructions}\n{postfix_to_instructions_prompt}" + print(system_prompt) class SerenaAgent: diff --git a/src/serena/tools/workflow_tools.py b/src/serena/tools/workflow_tools.py index 2c09a202..6172cc33 100644 --- a/src/serena/tools/workflow_tools.py +++ b/src/serena/tools/workflow_tools.py @@ -132,8 +132,8 @@ class InitialInstructionsTool(Tool, ToolMarkerDoesNotRequireActiveProject): def apply(self) -> str: """ 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! - The only exception is when a user asks you to activate a project, in which case you should call the `activate_project` first - instead and then call this tool. + If you haven't received instructions on how to use Serena's tools in the system prompt, + you should always call this tool before starting to work (including using any other tool) on any programming task, + the only exception being when you are asked to call `activate_project`, which you should then call before. """ return self.agent.create_system_prompt()