mirror of
https://github.com/tiennm99/serena.git
synced 2026-10-13 16:15:29 +00:00
Support use of available_tools and available_markers in context/mode prompts
This commit is contained in:
1 parent
e9e05c2f3f
commit
1bff8fa774
3 files changed
+42
-17
No files matched your search
+29
-14
@@ -18,6 +18,7 @@ from typing import TYPE_CHECKING, Any, Optional, TypeVar
|
||||
from sensai.util import logging
|
||||
from sensai.util.logging import LogTime
|
||||
|
||||
from interprompt.jinja_template import JinjaTemplate
|
||||
from serena import serena_version
|
||||
from serena.analytics import RegisteredTokenCountEstimator, ToolUsageStats
|
||||
from serena.config.context_mode import RegisteredContext, SerenaAgentContext, SerenaAgentMode
|
||||
@@ -92,6 +93,23 @@ class MemoriesManager:
|
||||
return f"Memory {name} deleted."
|
||||
|
||||
|
||||
class AvailableTools:
|
||||
def __init__(self, tools: list[Tool]):
|
||||
"""
|
||||
:param tools: the list of available tools
|
||||
"""
|
||||
self.tools = tools
|
||||
self.tool_names = [tool.get_name_from_cls() for tool in tools]
|
||||
self.tool_marker_names = set()
|
||||
for marker_class in iter_subclasses(ToolMarker):
|
||||
for tool in tools:
|
||||
if isinstance(tool, marker_class):
|
||||
self.tool_marker_names.add(marker_class.__name__)
|
||||
|
||||
def __len__(self) -> int:
|
||||
return len(self.tools)
|
||||
|
||||
|
||||
class SerenaAgent:
|
||||
def __init__(
|
||||
self,
|
||||
@@ -193,7 +211,7 @@ class SerenaAgent:
|
||||
tool_inclusion_definitions.append(SerenaAgentMode.from_name_internal("jetbrains"))
|
||||
|
||||
self._base_tool_set = ToolSet.default().apply(*tool_inclusion_definitions)
|
||||
self._exposed_tools = {tc: t for tc, t in self._all_tools.items() if self._base_tool_set.includes_name(t.get_name())}
|
||||
self._exposed_tools = AvailableTools([t for t in self._all_tools.values() if self._base_tool_set.includes_name(t.get_name())])
|
||||
log.info(f"Number of exposed tools: {len(self._exposed_tools)}")
|
||||
|
||||
# create executor for starting the language server and running tools in another thread
|
||||
@@ -302,7 +320,7 @@ class SerenaAgent:
|
||||
If a client should attempt to use a tool that is dynamically disabled
|
||||
(e.g. because a project is activated that disables it), it will receive an error.
|
||||
"""
|
||||
return list(self._exposed_tools.values())
|
||||
return list(self._exposed_tools.tools)
|
||||
|
||||
def get_active_project(self) -> Project | None:
|
||||
"""
|
||||
@@ -336,24 +354,21 @@ class SerenaAgent:
|
||||
"""
|
||||
return list(self._modes)
|
||||
|
||||
def _format_prompt(self, prompt_template: str) -> str:
|
||||
template = JinjaTemplate(prompt_template)
|
||||
return template.render(available_tools=self._exposed_tools.tool_names, available_markers=self._exposed_tools.tool_marker_names)
|
||||
|
||||
def create_system_prompt(self) -> str:
|
||||
available_tools = [tool.get_name_from_cls() for tool in self.get_exposed_tool_instances()]
|
||||
|
||||
# determine available tool markers (i.e. tool categories)
|
||||
available_markers = set()
|
||||
for marker_class in iter_subclasses(ToolMarker):
|
||||
for tool in self.get_exposed_tool_instances():
|
||||
if isinstance(tool, marker_class):
|
||||
available_markers.add(marker_class.__name__)
|
||||
|
||||
available_markers = self._exposed_tools.tool_marker_names
|
||||
log.info("Generating system prompt with available_tools=(see exposed tools), available_markers=%s", available_markers)
|
||||
system_prompt = self.prompt_factory.create_system_prompt(
|
||||
context_system_prompt=self._context.prompt,
|
||||
mode_system_prompts=[mode.prompt for mode in self._modes],
|
||||
available_tools=available_tools,
|
||||
context_system_prompt=self._format_prompt(self._context.prompt),
|
||||
mode_system_prompts=[self._format_prompt(mode.prompt) for mode in self._modes],
|
||||
available_tools=self._exposed_tools.tool_names,
|
||||
available_markers=available_markers,
|
||||
)
|
||||
log.info("System prompt:\n%s", system_prompt)
|
||||
return system_prompt
|
||||
|
||||
def _update_active_tools(self) -> None:
|
||||
"""
|
||||
|
||||
@@ -39,6 +39,10 @@ class SerenaAgentMode(ToolInclusionDefinition, ToStringMixin):
|
||||
|
||||
name: str
|
||||
prompt: str
|
||||
"""
|
||||
a Jinja2 template for the generation of the system prompt.
|
||||
It is formatted by the agent (see SerenaAgent._format_prompt()).
|
||||
"""
|
||||
description: str = ""
|
||||
|
||||
def _tostring_includes(self) -> list[str]:
|
||||
@@ -133,6 +137,10 @@ class SerenaAgentContext(ToolInclusionDefinition, ToStringMixin):
|
||||
|
||||
name: str
|
||||
prompt: str
|
||||
"""
|
||||
a Jinja2 template for the generation of the system prompt.
|
||||
It is formatted by the agent (see SerenaAgent._format_prompt()).
|
||||
"""
|
||||
description: str = ""
|
||||
|
||||
def _tostring_includes(self) -> list[str]:
|
||||
|
||||
@@ -14,7 +14,7 @@ prompt: |
|
||||
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
|
||||
Symbols are identified by their name path and relative file path, see the description of the `find_symbol` 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
|
||||
@@ -34,7 +34,8 @@ prompt: |
|
||||
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.
|
||||
{% if 'replace_regex' in available_tools %}
|
||||
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
|
||||
@@ -104,7 +105,8 @@ prompt: |
|
||||
Generally, I remind you that you rely on the regex tool with providing you the correct feedback, no need for more verification!
|
||||
|
||||
IMPORTANT: REMEMBER TO USE WILDCARDS WHEN APPROPRIATE! I WILL BE VERY UNHAPPY IF YOU WRITE LONG REGEXES WITHOUT USING WILDCARDS INSTEAD!
|
||||
excluded_tools:
|
||||
{% endif %}
|
||||
excluded_tools:
|
||||
- replace_lines
|
||||
- insert_at_line
|
||||
- delete_lines
|
||||
Reference in new issue
Block a user