mirror of
https://github.com/tiennm99/serena.git
synced 2026-10-13 02:14:49 +00:00
Prompting, tool descriptions. Overview tool no longer returns location info
This commit is contained in:
1 parent
950caaf91c
commit
5392d37630
2 files changed
+51
-13
No files matched your search
@@ -5,8 +5,36 @@ prompt: |
|
||||
Use symbolic editing tools whenever possible for precise code modifications.
|
||||
If no editing task has yet been provided, wait for the user to provide one.
|
||||
|
||||
Your primary tool for editing code is a regex-based replacement. You use other tools to find the relevant content and
|
||||
then use your knowledge of the codebase to write the regex.
|
||||
You have two main approaches for editing code - editing by regex and editing by symbol.
|
||||
The symbol-based approach is appropriate if you need to adjust an entire symbol, e.g. a method, a class, a function, etc.
|
||||
But it is not appropriate if you need to adjust just a few lines of code within a symbol, for that you should
|
||||
use the regex-based approach that is described below.
|
||||
|
||||
Let us first discuss the symbol-based approach.
|
||||
Symbols are identified by their name path and relative file path, see the description of the `find_symbols` tool for more details
|
||||
on how the `name_path` matches symbols.
|
||||
You can get information about available symbols by using the `get_symbols_overview` tool for finding top-level symbols in a file
|
||||
or directory, or by using `find_symbol` if you already know the symbol's name path. You generally try to read as little code as possible
|
||||
while still solving your task, meaning you only read the bodies when you need to, and after you have found the symbol you want to edit.
|
||||
For example, if you are working with python code and alread know that you need to read the body of the constructor of the class Foo, you can directly
|
||||
use `find_symbol` with the name path `Foo/__init__` and `include_body=True`. If you don't know yet which methods in `Foo` you need to read or edit,
|
||||
you can use `find_symbol` with the name path `Foo`, `include_body=False` and `depth=1` to get all (top-level) methods of `Foo` before proceeding
|
||||
to read the desired methods with `include_body=True`.
|
||||
Note that you never need to add additional indentation, as all symbol editing tools will automatically add the indentation of the symbol that
|
||||
you are replacing or inserting above or below. In particular, keep in mind the description of the `replace_symbol_body` tool. If you want to add some new code at the end of the file, you should
|
||||
use the `insert_after_symbol` tool with the last top-level symbol in the file. If you want to add an import, often a good strategy is to use
|
||||
`insert_before_symbol` with the first top-level symbol in the file.
|
||||
You can unterstand relationships between symbols by using the `find_referencing_symbols` tool. If not explicitly requested otherwise by a user,
|
||||
you make sure that when you edit a symbol, it is either done in a backward-compatible way, or you find and adjust the references as needed.
|
||||
The `find_referencing_symbols` tool will give you code snippets around the references, as well as symbolic information.
|
||||
You will generally be able to use the info from the snippets and the regex-based approach to adjust the references as well.
|
||||
You can assume that all symbol editing tools are reliable, so you don't need to verify the results if the tool returns without error.
|
||||
|
||||
Now let us discuss the regex-based approach.
|
||||
The regex-based approach is your primary tool for editing code whenever replacing or deleting a whole symbol would be a more expensive operation.
|
||||
This is the case if you need to adjust just a few lines of code within a method, or a chunk that is much smaller than a whole symbol.
|
||||
You use other tools to find the relevant content and
|
||||
then use your knowledge of the codebase to write the regex, if you haven't collected enough information of this content yet.
|
||||
You are extremely good at regex, so you never need to check whether the replacement produced the correct result.
|
||||
In particular, you know what to escape and what not to escape, and you know how to use wildcards.
|
||||
Moreover, the replacement tool will fail if it can't perform the desired replacement, and this is all the feedback you need.
|
||||
|
||||
+21
-11
@@ -1109,7 +1109,7 @@ class GetSymbolsOverviewTool(Tool):
|
||||
def apply(self, relative_path: str, max_answer_chars: int = _DEFAULT_MAX_ANSWER_LENGTH) -> str:
|
||||
"""
|
||||
Gets an overview of the given file or directory.
|
||||
For each analyzed file, we list the top-level symbols in the file (name, kind, line).
|
||||
For each analyzed file, we list the top-level symbols in the file (name_path, kind).
|
||||
Use this tool to get a high-level understanding of the code symbols.
|
||||
Calling this is often a good idea before more targeted reading, searching or editing operations on the code symbols.
|
||||
|
||||
@@ -1118,12 +1118,14 @@ class GetSymbolsOverviewTool(Tool):
|
||||
no content will be returned. Don't adjust unless there is really no other way to get the content
|
||||
required for the task. If the overview is too long, you should use a smaller directory instead,
|
||||
(e.g. a subdirectory).
|
||||
:return: a JSON object mapping relative paths of all contained files to info about top-level symbols in the file (name, kind, line, column).
|
||||
:return: a JSON object mapping relative paths of all contained files to info about top-level symbols in the file (name_path, kind).
|
||||
"""
|
||||
path_to_symbol_infos = self.language_server.request_overview(relative_path)
|
||||
result = {}
|
||||
for file_path, symbols in path_to_symbol_infos.items():
|
||||
result[file_path] = [_tuple_to_info(*symbol_info) for symbol_info in symbols]
|
||||
# TODO: maybe include not just top-level symbols? We could filter by kind to exclude variables
|
||||
# The language server methods would need to be adjusted for this.
|
||||
result[file_path] = [{"name_path": symbol[0], "kind": int(symbol[1])} for symbol in symbols]
|
||||
|
||||
result_json_str = json.dumps(result)
|
||||
return self._limit_length(result_json_str, max_answer_chars)
|
||||
@@ -1268,16 +1270,26 @@ class ReplaceSymbolBodyTool(Tool, ToolMarkerCanEdit):
|
||||
) -> str:
|
||||
"""
|
||||
Replaces the body of the symbol with the given `name_path`.
|
||||
IMPORTANT:
|
||||
You don't need to provide an adjusted indentation,
|
||||
as the tool will automatically add the indentation of the original symbol to each line. For example,
|
||||
for replacing a method in python, you can just write (using the standard python indentation):
|
||||
body="def my_method_replacement(self, ...):\n first_line\n second_line...". So each line after the first line only has
|
||||
an indentation of 4 (the indentation relative to the first characted),
|
||||
since the additional indentation will be added by the tool. Same for more deeply nested
|
||||
cases. You always only need to write the relative indentation to the first character of the first line, and that
|
||||
in turn should not have any indentation.
|
||||
ALWAYS REMEMBER TO USE THE CORRECT INDENTATION IN THE BODY!
|
||||
|
||||
:param name_path: for finding the symbol to replace, same logic as in the `find_symbol` tool.
|
||||
:param relative_path: the relative path to the file containing the symbol
|
||||
:param body: the new symbol body. Important: Provide the correct level of indentation
|
||||
(as the original body). Note that the first line must not be indented (i.e. no leading spaces).
|
||||
:param body: the new symbol body.
|
||||
"""
|
||||
self.symbol_manager.replace_body(
|
||||
name_path,
|
||||
relative_file_path=relative_path,
|
||||
body=body,
|
||||
use_same_indentation=True,
|
||||
)
|
||||
return SUCCESS_RESULT
|
||||
|
||||
@@ -1300,12 +1312,13 @@ class InsertAfterSymbolTool(Tool, ToolMarkerCanEdit):
|
||||
:param name_path: for finding the symbol to insert after, same logic as in the `find_symbol` tool.
|
||||
:param relative_path: the relative path to the file containing the symbol
|
||||
:param body: the body/content to be inserted. Important: the insterted code will automatically have the
|
||||
same indentation as the symbol's body, so you do not need to provide any indentation.
|
||||
same indentation as the symbol's body, so you do not need to provide any additional indentation.
|
||||
"""
|
||||
self.symbol_manager.insert_after_symbol(
|
||||
name_path,
|
||||
relative_file_path=relative_path,
|
||||
body=body,
|
||||
use_same_indentation=True,
|
||||
)
|
||||
return SUCCESS_RESULT
|
||||
|
||||
@@ -1329,12 +1342,13 @@ class InsertBeforeSymbolTool(Tool, ToolMarkerCanEdit):
|
||||
:param name_path: for finding the symbol to insert before, same logic as in the `find_symbol` tool.
|
||||
:param relative_path: the relative path to the file containing the symbol
|
||||
:param body: the body/content to be inserted. Important: the insterted code will automatically have the
|
||||
same indentation as the symbol's body, so you do not need to provide any indentation.
|
||||
same indentation as the symbol's body, so you do not need to provide any additional indentation.
|
||||
"""
|
||||
self.symbol_manager.insert_before_symbol(
|
||||
name_path,
|
||||
relative_file_path=relative_path,
|
||||
body=body,
|
||||
use_same_indentation=True,
|
||||
)
|
||||
return SUCCESS_RESULT
|
||||
|
||||
@@ -1955,7 +1969,3 @@ class ToolRegistry:
|
||||
for tool_name in sorted(tool_dict.keys()):
|
||||
tool_class = tool_dict[tool_name]
|
||||
print(f" * `{tool_name}`: {tool_class.get_tool_description().strip()}")
|
||||
|
||||
|
||||
def _tuple_to_info(name: str, symbol_type: SymbolKind, line: int, column: int) -> dict[str, int | str]:
|
||||
return {"name": name, "symbol_kind": symbol_type, "line": line, "column": column}
|
||||
Reference in new issue
Block a user