Files
wehub-resource-sync c6af9e284a
Tests / catch-all (windows-latest) (push) Has been cancelled
Tests / jvm (macos-latest) (push) Has been cancelled
Tests / jvm (ubuntu-latest) (push) Has been cancelled
Tests / jvm (windows-latest) (push) Has been cancelled
Tests / native (macos-latest) (push) Has been cancelled
Tests / native (ubuntu-latest) (push) Has been cancelled
Tests / native (windows-latest) (push) Has been cancelled
Tests / niche (ubuntu-latest) (push) Has been cancelled
Tests / other-langs (macos-latest) (push) Has been cancelled
Tests / other-langs (ubuntu-latest) (push) Has been cancelled
Tests / other-langs (windows-latest) (push) Has been cancelled
Tests / catch-all (macos-latest) (push) Has been cancelled
Tests / catch-all (ubuntu-latest) (push) Has been cancelled
Docs Build / build (push) Has been cancelled
Docs Build / deploy (push) Has been cancelled
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (javascript-typescript) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Codespell / Check for spelling errors (push) Has been cancelled
Build and Push Docker Images / build-and-push (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:39:38 +08:00

177 lines
7.1 KiB
Python

"""
Demonstrates diagnostics tools and edit-tool diagnostic reporting on the Serena repo itself.
The script creates a temporary Python file inside this repository, introduces one warning,
shows file and symbol diagnostics, then introduces another warning and verifies that the
second edit reports only the newly introduced warning.
"""
import json
import shutil
import tempfile
from pathlib import Path
from pprint import pprint
from serena.agent import SerenaAgent
from serena.config.serena_config import LanguageBackend, ProjectConfig, RegisteredProject, SerenaConfig
from serena.constants import REPO_ROOT
from serena.project import Project
from serena.tools import (
CreateTextFileTool,
EditingToolWithDiagnostics,
GetDiagnosticsForFileTool,
GetDiagnosticsForSymbolTool,
ReplaceContentTool,
)
from solidlsp.ls_config import Language
SEPARATOR = "=" * 80
REPO_PATH = Path(REPO_ROOT)
EDIT_RESULT_PREFIX = "Edit introduced new warning-or-higher diagnostics: "
def make_agent() -> SerenaAgent:
"""Create an LSP-backed Serena agent for the Serena repository."""
serena_config = SerenaConfig.from_config_file()
serena_config.web_dashboard = False
serena_config.language_backend = LanguageBackend.LSP
project = Project(
project_root=str(REPO_PATH),
project_config=ProjectConfig(
project_name="demo_serena_repo",
languages=[Language.PYTHON],
ignored_paths=[],
excluded_tools=[],
read_only=False,
ignore_all_files_in_gitignore=True,
initial_prompt="",
encoding="utf-8",
),
serena_config=serena_config,
)
serena_config.projects = [RegisteredProject.from_project_instance(project)]
return SerenaAgent(project="demo_serena_repo", serena_config=serena_config)
def print_section(title: str) -> None:
"""Print a visibly separated section header."""
print(f"\n{SEPARATOR}")
print(title)
print(SEPARATOR)
def parse_json_result(result: str) -> object:
"""Parse and pretty-print JSON tool output."""
parsed = json.loads(result)
pprint(parsed, width=200)
return parsed
def parse_edit_diagnostics_result(result: str) -> dict:
"""Extract the grouped diagnostics payload from an edit-tool result."""
assert result.startswith(EDIT_RESULT_PREFIX), result
return json.loads(result[len(EDIT_RESULT_PREFIX) :])
if __name__ == "__main__":
EditingToolWithDiagnostics.ENABLE_DIAGNOSTICS = True
temp_dir = Path(tempfile.mkdtemp(prefix="serena_demo_", dir=REPO_PATH))
temp_file = temp_dir / "demo_temp_diagnostics.py"
relative_path = temp_file.relative_to(REPO_PATH).as_posix()
initial_content = """def demo_existing_issue() -> int:
value = 1
return value
"""
agent = make_agent()
try:
# letting the language server finish startup
agent.execute_task(lambda: None)
create_text_file_tool = agent.get_tool(CreateTextFileTool)
replace_content_tool = agent.get_tool(ReplaceContentTool)
get_diagnostics_for_file_tool = agent.get_tool(GetDiagnosticsForFileTool)
get_diagnostics_for_symbol_tool = agent.get_tool(GetDiagnosticsForSymbolTool)
# creating a clean temporary file
print_section("Create Temporary File")
create_result = agent.execute_task(lambda: create_text_file_tool.apply(relative_path=relative_path, content=initial_content))
print(create_result)
# showing file diagnostics before introducing any warning
print_section("Initial File Diagnostics")
initial_diagnostics_result = agent.execute_task(
lambda: get_diagnostics_for_file_tool.apply(relative_path=relative_path, min_severity=2)
)
initial_diagnostics = parse_json_result(initial_diagnostics_result)
assert initial_diagnostics == {}, initial_diagnostics
# introducing the first warning
print_section("First Edit Result")
first_edit_result = agent.execute_task(
lambda: replace_content_tool.apply(
relative_path=relative_path,
needle="value = 1",
repl="value = missing_one",
mode="literal",
)
)
print(first_edit_result)
first_edit_diagnostics = parse_edit_diagnostics_result(first_edit_result)
pprint(first_edit_diagnostics, width=200)
assert "missing_one" in json.dumps(first_edit_diagnostics), first_edit_diagnostics
# showing the file- and symbol-level diagnostics after the first warning
print_section("File Diagnostics After First Edit")
diagnostics_after_first_edit_result = agent.execute_task(
lambda: get_diagnostics_for_file_tool.apply(relative_path=relative_path, min_severity=2)
)
diagnostics_after_first_edit = parse_json_result(diagnostics_after_first_edit_result)
assert "missing_one" in json.dumps(diagnostics_after_first_edit), diagnostics_after_first_edit
print_section("Symbol Diagnostics After First Edit")
symbol_diagnostics_result = agent.execute_task(
lambda: get_diagnostics_for_symbol_tool.apply(
name_path="demo_existing_issue",
reference_file=relative_path,
min_severity=2,
)
)
symbol_diagnostics = parse_json_result(symbol_diagnostics_result)
assert "missing_one" in json.dumps(symbol_diagnostics), symbol_diagnostics
# introducing a second warning while keeping the first one unchanged
print_section("Second Edit Result")
second_edit_result = agent.execute_task(
lambda: replace_content_tool.apply(
relative_path=relative_path,
needle=" return value\n",
repl=" other = missing_two\n return value + other\n",
mode="literal",
)
)
print(second_edit_result)
second_edit_diagnostics = parse_edit_diagnostics_result(second_edit_result)
pprint(second_edit_diagnostics, width=200)
second_edit_json = json.dumps(second_edit_diagnostics)
assert "missing_two" in second_edit_json, second_edit_diagnostics
assert "missing_one" not in second_edit_json, second_edit_diagnostics
print("\nVerified: the second edit result reports only the newly introduced warning.")
# showing the complete file diagnostics after both warnings exist
print_section("File Diagnostics After Second Edit")
diagnostics_after_second_edit_result = agent.execute_task(
lambda: get_diagnostics_for_file_tool.apply(relative_path=relative_path, min_severity=2)
)
diagnostics_after_second_edit = parse_json_result(diagnostics_after_second_edit_result)
diagnostics_after_second_edit_json = json.dumps(diagnostics_after_second_edit)
assert "missing_one" in diagnostics_after_second_edit_json, diagnostics_after_second_edit
assert "missing_two" in diagnostics_after_second_edit_json, diagnostics_after_second_edit
finally:
shutil.rmtree(temp_dir, ignore_errors=True)
agent.shutdown()