mirror of
https://github.com/tiennm99/serena.git
synced 2026-10-13 10:16:00 +00:00
Display info about the client (that performed the last tool call) in dashboard
Had to hack around a bit to make it happen but worth the added transparency for users
This commit is contained in:
1 parent
5897585ef2
commit
2eca7af593
4 files changed
+36
-3
No files matched your search
@@ -56,6 +56,7 @@ class ResponseConfigOverview(BaseModel):
|
||||
jetbrains_mode: bool
|
||||
languages: list[str]
|
||||
encoding: str | None
|
||||
current_client: str | None
|
||||
|
||||
|
||||
class ResponseAvailableLanguages(BaseModel):
|
||||
@@ -370,6 +371,7 @@ class SerenaDashboardAPI:
|
||||
|
||||
def _get_config_overview(self) -> ResponseConfigOverview:
|
||||
from serena.config.context_mode import SerenaAgentContext, SerenaAgentMode
|
||||
from serena.tools.tools_base import Tool
|
||||
|
||||
# Get active project info
|
||||
project = self._agent.get_active_project()
|
||||
@@ -491,6 +493,7 @@ class SerenaDashboardAPI:
|
||||
jetbrains_mode=self._agent.serena_config.language_backend == LanguageBackend.JETBRAINS,
|
||||
languages=languages,
|
||||
encoding=encoding,
|
||||
current_client=Tool.get_last_tool_call_client_str(),
|
||||
)
|
||||
|
||||
def _shutdown(self) -> None:
|
||||
|
||||
+3
-1
@@ -239,7 +239,9 @@ class SerenaMCPFactory:
|
||||
parameters=parameters,
|
||||
fn_metadata=func_arg_metadata,
|
||||
is_async=is_async,
|
||||
context_kwarg=None,
|
||||
# keep the value in sync with the kwarg name in Tool.apply_ex. The mcp sdk uses reflection to infer this
|
||||
# when the tool is constructed via from_function (which is a bit crazy IMO, but well...)
|
||||
context_kwarg="mcp_ctx",
|
||||
annotations=annotations,
|
||||
title=tool_title,
|
||||
)
|
||||
|
||||
@@ -619,6 +619,10 @@ class Dashboard {
|
||||
html += '<div class="config-label">File Encoding:</div>';
|
||||
html += '<div class="config-value">' + (config.encoding || 'N/A') + '</div>';
|
||||
|
||||
// Current Client info
|
||||
html += '<div class="config-label">Current Client:</div>';
|
||||
html += '<div class="config-value">' + (config.current_client || 'None') + '</div>';
|
||||
|
||||
html += '</div>';
|
||||
|
||||
// Active tools - collapsible
|
||||
|
||||
@@ -4,8 +4,10 @@ from abc import ABC
|
||||
from collections.abc import Iterable
|
||||
from dataclasses import dataclass
|
||||
from types import TracebackType
|
||||
from typing import TYPE_CHECKING, Any, Protocol, Self, TypeVar
|
||||
from typing import TYPE_CHECKING, Any, Protocol, Self, TypeVar, cast
|
||||
|
||||
from mcp import Implementation
|
||||
from mcp.server.fastmcp import Context
|
||||
from mcp.server.fastmcp.utilities.func_metadata import FuncMetadata, func_metadata
|
||||
from sensai.util import logging
|
||||
from sensai.util.string import dict_string
|
||||
@@ -115,6 +117,17 @@ class Tool(Component):
|
||||
# (which is use by the LLM, so a good description is important)
|
||||
# and to validate the tool call arguments.
|
||||
|
||||
_last_tool_call_client_str: str | None = None
|
||||
"""We can only get the client info from within a tool call. Each tool call will update this variable."""
|
||||
|
||||
@classmethod
|
||||
def set_last_tool_call_client_str(cls, client_str: str | None) -> None:
|
||||
cls._last_tool_call_client_str = client_str
|
||||
|
||||
@classmethod
|
||||
def get_last_tool_call_client_str(cls) -> str | None:
|
||||
return cls._last_tool_call_client_str
|
||||
|
||||
@classmethod
|
||||
def get_name_from_cls(cls) -> str:
|
||||
name = cls.__name__
|
||||
@@ -219,10 +232,21 @@ class Tool(Component):
|
||||
def is_active(self) -> bool:
|
||||
return self.agent.tool_is_active(self.__class__)
|
||||
|
||||
def apply_ex(self, log_call: bool = True, catch_exceptions: bool = True, **kwargs) -> str: # type: ignore
|
||||
def apply_ex(self, log_call: bool = True, catch_exceptions: bool = True, mcp_ctx: Context | None = None, **kwargs) -> str: # type: ignore
|
||||
"""
|
||||
Applies the tool with logging and exception handling, using the given keyword arguments
|
||||
"""
|
||||
if mcp_ctx is not None:
|
||||
try:
|
||||
client_params = mcp_ctx.session.client_params
|
||||
if client_params is not None:
|
||||
client_info = cast(Implementation, client_params.clientInfo)
|
||||
client_str = client_info.title if client_info.title else client_info.name + " " + client_info.version
|
||||
if client_str != self.get_last_tool_call_client_str():
|
||||
log.debug(f"Updating client info: {client_info}")
|
||||
self.set_last_tool_call_client_str(client_str)
|
||||
except BaseException as e:
|
||||
log.info(f"Failed to get client info: {e}.")
|
||||
|
||||
def task() -> str:
|
||||
apply_fn = self.get_apply_fn()
|
||||
|
||||
Reference in new issue
Block a user