Improved output structure in GetSymbolsOverviewTool, major token reduction!

As before for jetbrains, grouped and without name_path. Using recursive structure for depth>0
This commit is contained in:
Michael Panchenko committed 2025-12-21 11:55:53 +07:00
1 parent 73f24011f2
commit f0f3d8004e
2 files changed
+46 -2

No files matched your search

+2
View File
@@ -98,6 +98,8 @@ class JetBrainsGetSymbolsOverviewTool(Tool, ToolMarkerSymbolicRead, ToolMarkerOp
Retrieves an overview of the top-level symbols within a specified file using the JetBrains backend
"""
# TODO: support depth param, structure output in the same way as in GetSymbolsOverviewTool (by extracting
# the post-processing logic used there into a shared utility function)
def apply(
self,
relative_path: str,
+44 -2
View File
@@ -7,6 +7,8 @@ from collections.abc import Sequence
from copy import copy
from typing import Any
from black.trans import defaultdict
from serena.tools import (
SUCCESS_RESULT,
Tool,
@@ -61,7 +63,15 @@ class GetSymbolsOverviewTool(Tool, ToolMarkerSymbolicRead):
:param max_answer_chars: if the overview is longer than this number of characters,
no content will be returned. -1 means the default value from the config will be used.
Don't adjust unless there is really no other way to get the content required for the task.
:return: a JSON object containing info about top-level symbols in the file
:return: a JSON object containing symbols grouped by kind in a compact format.
For depth=0, the structure is: {"Kind1": ["name1", "name2"], "Kind2": ["name3"]}
For depth>0, symbols with children use nested dicts: {"Class": [{"ClassName": {"Method": ["method1", "method2"]}}]}
The name_path for any symbol can be inferred from the structure:
- Top-level symbols: name_path = name
- Nested symbols: name_path = parent_name + "/" + name
Example: "method1" under class "ClassName" has name_path "ClassName/method1"
"""
symbol_retriever = self.create_language_server_symbol_retriever()
file_path = os.path.join(self.project.project_root, relative_path)
@@ -73,9 +83,41 @@ class GetSymbolsOverviewTool(Tool, ToolMarkerSymbolicRead):
if os.path.isdir(file_path):
raise ValueError(f"Expected a file path, but got a directory path: {relative_path}. ")
result = symbol_retriever.get_symbol_overview(relative_path, depth=depth)[relative_path]
result_json_str = self._to_json(result)
# Transform to compact format
compact_result = self._transform_symbols_to_compact_format(result)
result_json_str = self._to_json(compact_result)
return self._limit_length(result_json_str, max_answer_chars)
@staticmethod
def _transform_symbols_to_compact_format(symbols: list[dict[str, Any]]) -> dict[str, list]:
"""
Transform symbol overview from verbose format to compact grouped format.
Groups symbols by kind and uses names instead of full symbol objects.
For symbols with children, creates nested dictionaries.
The name_path can be inferred from the hierarchical structure:
- Top-level symbols: name_path = name
- Nested symbols: name_path = parent_name + "/" + name
For example, "convert" under class "ProjectType" has name_path "ProjectType/convert".
"""
result = defaultdict(list)
for symbol in symbols:
kind = symbol.get("kind", "Unknown")
name = symbol.get("name", "unknown")
children = symbol.get("children", [])
if children:
# Symbol has children: create nested dict {name: children_dict}
children_dict = GetSymbolsOverviewTool._transform_symbols_to_compact_format(children)
result[kind].append({name: children_dict})
else:
# Symbol has no children: just add the name
result[kind].append(name)
return result
class FindSymbolTool(Tool, ToolMarkerSymbolicRead):
"""