From 291ee91f5b3b5ee21cf68549f6efce70cbc9a6f5 Mon Sep 17 00:00:00 2001 From: Michael Panchenko Date: Sat, 5 Apr 2025 19:39:23 +0200 Subject: [PATCH 1/3] New tool: GetReferencingCodeExtractsTool --- README.md | 3 ++- src/serena/agent.py | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 7564734..0a3d437 100644 --- a/README.md +++ b/README.md @@ -560,6 +560,7 @@ Here the full list of Serena's default tools with a short description (the outpu * `find_symbol`: Performs a global (or local) search for symbols with/containing a given name/substring (optionally filtered by type). * `get_dir_overview`: Gets an overview of the top-level symbols defined in all files within a given directory. * `get_document_overview`: Gets an overview of the top-level symbols defined in a given file. + * `get_referencing_code_extracts`: Gets the code blocks that reference the symbol at the given location. * `insert_after_symbol`: Inserts content after the end of the definition of a given symbol. * `insert_at_line`: Inserts content at a given line in a file. * `insert_before_symbol`: Inserts content before the beginning of the definition of a given symbol. @@ -569,6 +570,7 @@ Here the full list of Serena's default tools with a short description (the outpu * `prepare_for_new_conversation`: Provides instructions for preparing for a new conversation (in order to continue with the necessary context). * `read_file`: Reads a file within the project directory. * `read_memory`: Reads the memory with the given name from Serena's project-specific memory store. + * `replace_lines`: Replaces a range of lines within a file with new content. * `replace_symbol_body`: Replaces the full definition of a symbol. * `search_in_all_code`: Performs a search for a pattern in all code files (and only in code files) in the project. * `summarize_changes`: Provides instructions for summarizing the changes made to the codebase. @@ -576,4 +578,3 @@ Here the full list of Serena's default tools with a short description (the outpu * `think_about_task_adherence`: Thinking tool for determining whether the agent is still on track with the current task. * `think_about_whether_you_are_done`: Thinking tool for determining whether the task is truly completed. * `write_memory`: Writes a named memory (for future reference) to Serena's project-specific memory store. - diff --git a/src/serena/agent.py b/src/serena/agent.py index 88983da..3ac5a57 100644 --- a/src/serena/agent.py +++ b/src/serena/agent.py @@ -536,6 +536,45 @@ class FindReferencingSymbolsTool(Tool): return self._limit_length(result, max_answer_chars) +class GetReferencingCodeExtractsTool(Tool): + """ + Gets the code blocks that reference the symbol at the given location. + """ + + def apply( + self, + relative_path: str, + line: int, + column: int, + context_lines_before: int = 0, + context_lines_after: int = 0, + max_answer_chars: int = _DEFAULT_MAX_ANSWER_LENGTH, + ) -> str: + """ + Returns short code extracts where the symbol at the given location is referenced. + + Contrary to the find_referencing_symbols tool, this tool returns references that are not symbols but instead + code extracts that may or may not be contained in a symbol (for example, file-level calls). + It may make sense to use this tool if you want to get a quick and dirty overview of the code that references + the symbol. Usually just looking at the code extracts is not enough to understand the context, + unless the case you are investigating is very simple, + or you already have read the relevant symbols using the find_referencing_symbols tool and + now want to get an overview of how the referenced symbol (at the given location) is used in them. + + :param relative_path: the relative path to the file containing the symbol + :param line: the line number + :param column: the column + :param context_lines_before: the number of lines to include before the reference + :param context_lines_after: the number of lines to include after the reference + """ + matches = self.language_server.request_references_with_content( + relative_path, line, column, context_lines_before, context_lines_after + ) + result = [match.to_display_string() for match in matches] + result_json_str = json.dumps(result) + return self._limit_length(result_json_str, max_answer_chars) + + class ReplaceSymbolBodyTool(Tool): """ Replaces the full definition of a symbol. From 385deb05c9375e45eef02312784cacac49adee1b Mon Sep 17 00:00:00 2001 From: Michael Panchenko Date: Sat, 5 Apr 2025 19:56:27 +0200 Subject: [PATCH 2/3] Docstring, minor --- src/serena/agent.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/serena/agent.py b/src/serena/agent.py index 3ac5a57..bcbe4bb 100644 --- a/src/serena/agent.py +++ b/src/serena/agent.py @@ -553,10 +553,10 @@ class GetReferencingCodeExtractsTool(Tool): """ Returns short code extracts where the symbol at the given location is referenced. - Contrary to the find_referencing_symbols tool, this tool returns references that are not symbols but instead + Contrary to the `find_referencing_symbols` tool, this tool returns references that are not symbols but instead code extracts that may or may not be contained in a symbol (for example, file-level calls). It may make sense to use this tool if you want to get a quick and dirty overview of the code that references - the symbol. Usually just looking at the code extracts is not enough to understand the context, + the symbol. Usually, just looking at the code extracts is not enough to understand the context, unless the case you are investigating is very simple, or you already have read the relevant symbols using the find_referencing_symbols tool and now want to get an overview of how the referenced symbol (at the given location) is used in them. @@ -564,8 +564,12 @@ class GetReferencingCodeExtractsTool(Tool): :param relative_path: the relative path to the file containing the symbol :param line: the line number :param column: the column - :param context_lines_before: the number of lines to include before the reference - :param context_lines_after: the number of lines to include after the reference + :param context_lines_before: the number of lines to include before the line containing the reference + :param context_lines_after: the number of lines to include after the line containing the reference + :param max_answer_chars: if the output is longer than this number of characters, + no content will be returned. Don't adjust unless there is really no other way to get the content + required for the task. Instead, if the output is too long, you should + make a stricter query. """ matches = self.language_server.request_references_with_content( relative_path, line, column, context_lines_before, context_lines_after From 6052f7b0aea67828ca2431c83d7e95707c33ecc5 Mon Sep 17 00:00:00 2001 From: Michael Panchenko Date: Sun, 6 Apr 2025 13:22:39 +0200 Subject: [PATCH 3/3] Minor docstring changes --- CHANGELOG.md | 4 ++++ src/serena/agent.py | 21 +++++++++++++-------- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7128943..599b9d9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ # Changelog +## 06.04.2025 +- New tool: FindReferencingCodeSnippets +- Adjusted prompt in CreateTextFileTool to prevent writing partial content (see [here](https://www.reddit.com/r/ClaudeAI/comments/1jpavtm/comment/mloek1x/?utm_source=share&utm_medium=web3x&utm_name=web3xcss&utm_term=1&utm_content=share_button)). + ## 01.04.2025: Initial Release \ No newline at end of file diff --git a/src/serena/agent.py b/src/serena/agent.py index bcbe4bb..f9175b6 100644 --- a/src/serena/agent.py +++ b/src/serena/agent.py @@ -332,6 +332,10 @@ class CreateTextFileTool(Tool): You can also use insert_at_line to insert content at a specific line for existing files if the symbolic operations are not the right choice for what you want to do. + If ever used on an existing file, the content has to be the complete content of that file (so it + may never end with something like "The remaining content of the file is left unchanged."). + For operations that just replace a part of a file, use the replace_lines or the symbolic editing tools instead. + :param relative_path: the relative path to the file to create :param content: the (utf-8-encoded) content to write to the file :return: a message indicating success or failure @@ -536,9 +540,9 @@ class FindReferencingSymbolsTool(Tool): return self._limit_length(result, max_answer_chars) -class GetReferencingCodeExtractsTool(Tool): +class FindReferencingCodeSnippetsTool(Tool): """ - Gets the code blocks that reference the symbol at the given location. + Finds code snippets in which the symbol at the given location is referenced. """ def apply( @@ -551,19 +555,20 @@ class GetReferencingCodeExtractsTool(Tool): max_answer_chars: int = _DEFAULT_MAX_ANSWER_LENGTH, ) -> str: """ - Returns short code extracts where the symbol at the given location is referenced. + Returns short code snippets where the symbol at the given location is referenced. Contrary to the `find_referencing_symbols` tool, this tool returns references that are not symbols but instead - code extracts that may or may not be contained in a symbol (for example, file-level calls). - It may make sense to use this tool if you want to get a quick and dirty overview of the code that references - the symbol. Usually, just looking at the code extracts is not enough to understand the context, + code snippets that may or may not be contained in a symbol (for example, file-level calls). + It may make sense to use this tool to get a quick overview of the code that references + the symbol. Usually, just looking at code snippets is not enough to understand the full context, unless the case you are investigating is very simple, or you already have read the relevant symbols using the find_referencing_symbols tool and now want to get an overview of how the referenced symbol (at the given location) is used in them. + The size of the snippets is controlled by the context_lines_before and context_lines_after parameters. :param relative_path: the relative path to the file containing the symbol - :param line: the line number - :param column: the column + :param line: the line number of the symbol to find references for + :param column: the column of the symbol to find references for :param context_lines_before: the number of lines to include before the line containing the reference :param context_lines_after: the number of lines to include after the line containing the reference :param max_answer_chars: if the output is longer than this number of characters,