huggingface / huggingface/smolagents
Allow for introspection and type hints over class attributes when defining tool classes
- Dominant language
- Python
- Stars
- 29.3k
- Forks
- 3k
- Avg merge
- 17m
- Merged PRs (30d)
- 2
Description
**Is your feature request related to a problem? Please describe.**
I love smolagents, but defining my own tools as classes feels clunky
Currently when using classes over functions, class definitions are not very idiomatic python, e.g.
```python
class HFModelDownloadsTool(Tool):
name = "model_download_counter"
description = """
This is a tool that returns the most downloaded model of a given task on the Hugging Face Hub.
It returns the name of the checkpoint."""
inputs = {
"task": {
"type": "string",
"description": "the task category (such as text-classification, depth-estimation, etc)",
}
}
output_type = "string"
def forward(self, task: str):
from huggingface_hub import list_models
model = next(iter(list_models(filter=task, sort="downloads", direction=-1)))
return model.id
```
all of the 4 required class attributes could instead be introspected from docstrings and type hints (as they are when using tool function decorators).
Additionally, the example is confusing, because it looks like there is some introspection of the `forward` happening method:
https://github.com/huggingface/smolagents/blob/d74837b10a4e2bc51105cce9b81f21b64dde55ac/src/smolagents/tools.py#L149-L157
but it's not really clear how that relates to the class attributes, if one takes precedence over the other, particularly the (less expressive) type in `output_type`. It also looks like it's possible to have contradictory type hints and class attributes, and it's not clear what the overall effect is on prompt generation and result interpretation.
**Describe the solution you'd like**
More idiomatic python would look like:
```python
class HFModelDownloadsTool(Tool):
"""
This is a tool that returns the most downloaded model of a given task on the Hugging Face Hub.
It returns the name of the checkpoint."""
def forward(self, task: str) -> string:
"""
Args:
task: the task category (such as text-classification, depth-estimation, etc)
Returns:
name of the checkpoint
"""
from huggingface_hub import list_models
model = next(iter(list_models(filter=task, sort="downloads", direction=-1)))
return model.id
```
I could try a PR for this but I don't know where this fits on your roadmap
**Is this not possible with the current options.**
As an interim step it would be good to have more docs here that explain best practice:
https://huggingface.co/docs/smolagents/tutorials/tools
In particular this isn't clear:
> An output_type attribute, which specifies the output type. The types for both inputs and output_type should be [Pydantic formats](https://docs.pydantic.dev/latest/concepts/json_schema/#generating-json-schema), they can be either of these: ~AUTHORIZED_TYPES().
The pydantic docs are for generating json schema, and it looks like the `~AUTHORIZED_TYPES()` is meant to auto-expand.
**Describe alternatives you've considered**
An alternative would be to encourage use of decorated functions, but to add a `context` argument, similar to pydantic-ai, which would bypass the current limitations of this (simpler) approach
https://ai.pydantic.dev/#tools-dependency-injection-example
Contributor guide
Research direction
Start in src/smolagents/tools.py around lines 149-157 and compare class-based tools with decorated function handling. Clarify how forward annotations, docstrings, and class attributes interact, including precedence and prompt/result behavior; update the tools tutorial with the chosen best practice and document what happens for conflicting definitions.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- tooling
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100