mirror of
https://github.com/tiennm99/serena.git
synced 2026-10-15 02:17:26 +00:00
Sync mux
commit c5b59a6cb87a093327b3bc2bbfa2a485a3b18d1f Author: Dominik Jain <dominik.jain@outlook.com> Date: Sun Nov 23 18:53:06 2025 +0100 ToolRegistry: Allow valid tool packages to be modified src-serena/serena/tools/tools_base.py commit 9b4299d4f3e12fe67919e304d9e33c527ee0f345 Author: Dominik Jain <dominik.jain@outlook.com> Date: Sun Nov 23 17:47:39 2025 +0100 ToolInclusionDefinition: Add option to specify a fixed tool set src-serena/serena/agent.py src-serena/serena/config/serena_config.py
This commit is contained in:
1 parent
d58dbebce2
commit
9781710f4e
3 files changed
+60
-24
No files matched your search
+29
-20
@@ -106,26 +106,35 @@ class ToolSet:
|
||||
registry = ToolRegistry()
|
||||
tool_names = set(self._tool_names)
|
||||
for definition in tool_inclusion_definitions:
|
||||
included_tools = []
|
||||
excluded_tools = []
|
||||
for included_tool in definition.included_optional_tools:
|
||||
included_tool = get_updated_tool_name(included_tool)
|
||||
if not registry.is_valid_tool_name(included_tool):
|
||||
raise ValueError(f"Invalid tool name '{included_tool}' provided for inclusion")
|
||||
if included_tool not in tool_names:
|
||||
tool_names.add(included_tool)
|
||||
included_tools.append(included_tool)
|
||||
for excluded_tool in definition.excluded_tools:
|
||||
excluded_tool = get_updated_tool_name(excluded_tool)
|
||||
if not registry.is_valid_tool_name(excluded_tool):
|
||||
raise ValueError(f"Invalid tool name '{excluded_tool}' provided for exclusion")
|
||||
if excluded_tool in tool_names:
|
||||
tool_names.remove(excluded_tool)
|
||||
excluded_tools.append(excluded_tool)
|
||||
if included_tools:
|
||||
log.info(f"{definition} included {len(included_tools)} tools: {', '.join(included_tools)}")
|
||||
if excluded_tools:
|
||||
log.info(f"{definition} excluded {len(excluded_tools)} tools: {', '.join(excluded_tools)}")
|
||||
if definition.is_fixed_tool_set():
|
||||
tool_names = set()
|
||||
for fixed_tool in definition.fixed_tools:
|
||||
fixed_tool = get_updated_tool_name(fixed_tool)
|
||||
if not registry.is_valid_tool_name(fixed_tool):
|
||||
raise ValueError(f"Invalid tool name '{fixed_tool}' provided for fixed tool set")
|
||||
tool_names.add(fixed_tool)
|
||||
log.info(f"{definition} defined a fixed tool set with {len(tool_names)} tools: {', '.join(tool_names)}")
|
||||
else:
|
||||
included_tools = []
|
||||
excluded_tools = []
|
||||
for included_tool in definition.included_optional_tools:
|
||||
included_tool = get_updated_tool_name(included_tool)
|
||||
if not registry.is_valid_tool_name(included_tool):
|
||||
raise ValueError(f"Invalid tool name '{included_tool}' provided for inclusion")
|
||||
if included_tool not in tool_names:
|
||||
tool_names.add(included_tool)
|
||||
included_tools.append(included_tool)
|
||||
for excluded_tool in definition.excluded_tools:
|
||||
excluded_tool = get_updated_tool_name(excluded_tool)
|
||||
if not registry.is_valid_tool_name(excluded_tool):
|
||||
raise ValueError(f"Invalid tool name '{excluded_tool}' provided for exclusion")
|
||||
if excluded_tool in tool_names:
|
||||
tool_names.remove(excluded_tool)
|
||||
excluded_tools.append(excluded_tool)
|
||||
if included_tools:
|
||||
log.info(f"{definition} included {len(included_tools)} tools: {', '.join(included_tools)}")
|
||||
if excluded_tools:
|
||||
log.info(f"{definition} excluded {len(excluded_tools)} tools: {', '.join(excluded_tools)}")
|
||||
return ToolSet(tool_names)
|
||||
|
||||
def without_editing_tools(self) -> "ToolSet":
|
||||
|
||||
@@ -5,7 +5,7 @@ The Serena Model Context Protocol (MCP) Server
|
||||
import dataclasses
|
||||
import os
|
||||
import shutil
|
||||
from collections.abc import Iterable
|
||||
from collections.abc import Sequence
|
||||
from copy import deepcopy
|
||||
from dataclasses import dataclass, field
|
||||
from datetime import datetime
|
||||
@@ -72,8 +72,32 @@ class SerenaPaths:
|
||||
|
||||
@dataclass
|
||||
class ToolInclusionDefinition:
|
||||
excluded_tools: Iterable[str] = ()
|
||||
included_optional_tools: Iterable[str] = ()
|
||||
"""
|
||||
Defines which tools to include/exclude in Serena's operation.
|
||||
This can mean either
|
||||
* defining exclusions/inclusions to apply to an existing set of tools [incremental mode], or
|
||||
* defining a fixed set of tools to use [fixed mode].
|
||||
"""
|
||||
|
||||
excluded_tools: Sequence[str] = ()
|
||||
"""
|
||||
the names of tools to exclude from use [incremental mode]
|
||||
"""
|
||||
included_optional_tools: Sequence[str] = ()
|
||||
"""
|
||||
the names of optional tools to include [incremental mode]
|
||||
"""
|
||||
fixed_tools: Sequence[str] = ()
|
||||
"""
|
||||
the names of tools to use as a fixed set of tools [fixed mode]
|
||||
"""
|
||||
|
||||
def is_fixed_tool_set(self) -> bool:
|
||||
num_fixed = len(self.fixed_tools)
|
||||
num_incremental = len(self.excluded_tools) + len(self.included_optional_tools)
|
||||
if num_fixed > 0 and num_incremental > 0:
|
||||
raise ValueError("Cannot use both fixed_tools and excluded_tools/included_optional_tools at the same time.")
|
||||
return num_fixed > 0
|
||||
|
||||
|
||||
class SerenaConfigError(Exception):
|
||||
|
||||
@@ -350,12 +350,15 @@ class RegisteredTool:
|
||||
tool_name: str
|
||||
|
||||
|
||||
tool_packages = ["serena.tools"]
|
||||
|
||||
|
||||
@singleton
|
||||
class ToolRegistry:
|
||||
def __init__(self) -> None:
|
||||
self._tool_dict: dict[str, RegisteredTool] = {}
|
||||
for cls in iter_subclasses(Tool):
|
||||
if not cls.__module__.startswith("serena.tools"):
|
||||
if not any(cls.__module__.startswith(pkg) for pkg in tool_packages):
|
||||
continue
|
||||
is_optional = issubclass(cls, ToolMarkerOptional)
|
||||
name = cls.get_name_from_cls()
|
||||
|
||||
Reference in new issue
Block a user