From a8c36f5c6effb3c5c99cac15e3652b5940da74fe Mon Sep 17 00:00:00 2001 From: Michael Panchenko Date: Sat, 5 Apr 2025 19:17:12 +0200 Subject: [PATCH] Comments regarding apply method --- README.md | 3 ++- src/serena/agent.py | 12 +++++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index dc7a5799..7564734f 100644 --- a/README.md +++ b/README.md @@ -541,7 +541,8 @@ Without these projects, Serena would not have been possible (or would have been It is very easy to extend Serena's AI functionality with your own ideas. Just implement a new Tool by subclassing from -`serena.agent.Tool`. By default, the `SerenaAgent` will immediately have access to it. +`serena.agent.Tool` and implement the `apply` method (not part of the interface, see +comment in `Tool`). By default, the `SerenaAgent` will immediately have access to it. It is also relatively straightforward to add [support for a new language](/CONTRIBUTING.md#adding-a-new-supported-language). We look forward to seeing what the community will come up with! For details on contributing, see [here](/CONTRIBUTING.md). diff --git a/src/serena/agent.py b/src/serena/agent.py index b98efaa6..e4603e1b 100644 --- a/src/serena/agent.py +++ b/src/serena/agent.py @@ -207,6 +207,16 @@ _DEFAULT_MAX_ANSWER_LENGTH = int(2e5) class Tool(Component): + # NOTE: each tool should implement the apply method, which is then used in + # the central method of the Tool class `apply_ex`. + # Failure to do so will result in an exception at runtime. + # The apply method is not declared as part of the base Tool interface since we cannot + # know the signature of the (input parameters of the) method in advance. + # + # The docstring and types of the apply method are used to generate the tool description + # (which is use by the LLM, so a good description is important) + # and to validate the tool call arguments. + @classmethod def get_name(cls) -> str: name = cls.__name__ @@ -263,7 +273,7 @@ class Tool(Component): """ apply_fn = getattr(self, "apply") if apply_fn is None: - raise ValueError(f"apply not defined in {self}") + raise ValueError(f"apply not defined in {self}. Did you forget to implement it?") if log_call: self._log_tool_application(inspect.currentframe())