> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mellea.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# mellea.backends.tools

> LLM tool definitions, parsing, and validation for mellea backends.

export const SidebarFix = () => <script dangerouslySetInnerHTML={{
  __html: `
        (function () {
          const INTERVAL_MS = 500;

          const upgradeSidebar = () => {
            const links = document.querySelectorAll('a[href^="#"]');

            links.forEach((link) => {
              if (link.dataset.badged === "true") return;

              const rawText = (link.textContent || "").trim();

              // ========== FUNC ==========
              if (rawText.startsWith("FUNC ")) {
                const label = rawText.replace(/^FUNC\\s+/, "").trim();

                while (link.firstChild) link.removeChild(link.firstChild);

                // 👉 Make the whole link a single flex row & prevent wrapping
                link.style.display = "flex";
                link.style.alignItems = "center";
                link.style.whiteSpace = "nowrap";
                link.style.columnGap = "0.5rem";

                const badge = document.createElement("span");
                badge.style.marginRight = "0.5rem";
                badge.style.display = "inline-flex";
                badge.style.alignItems = "center";
                badge.style.borderRadius = "9999px";
                badge.style.padding = "0rem 0.6rem";
                badge.style.fontSize = "0.5rem";
                badge.style.fontWeight = "700";
                badge.style.letterSpacing = "0.05em";
                badge.style.backgroundColor = "rgba(48, 100, 227, 0.20)";
                badge.style.color = "#1D4ED8";

                badge.textContent = "FUNC";

                link.appendChild(badge);
                link.appendChild(document.createTextNode(label));
                link.dataset.badged = "true";
                return;
              }

              // ========== CLASS ==========
              if (rawText.startsWith("CLASS ")) {
                const label = rawText.replace(/^CLASS\\s+/, "").trim();

                while (link.firstChild) link.removeChild(link.firstChild);

                // 👉 Same flex / nowrap treatment for class links
                link.style.display = "flex";
                link.style.alignItems = "center";
                link.style.whiteSpace = "nowrap";
                link.style.columnGap = "0.5rem";

                const badge = document.createElement("span");
                badge.style.marginRight = "0.5rem";
                badge.style.display = "inline-flex";
                badge.style.alignItems = "center";
                badge.style.borderRadius = "9999px";
                badge.style.padding = "0rem 0.6rem";
                badge.style.fontSize = "0.5rem";
                badge.style.fontWeight = "700";
                badge.style.letterSpacing = "0.05em";
                badge.style.backgroundColor = "rgba(74, 222, 128, 0.20)";
                badge.style.color = "#15803D";

                badge.textContent = "CLASS";

                link.appendChild(badge);
                link.appendChild(document.createTextNode(label));
                link.dataset.badged = "true";
                return;
              }
            });
          };

          upgradeSidebar();
          setInterval(upgradeSidebar, INTERVAL_MS);
        })();
      `
}} />;

<SidebarFix />

LLM tool definitions, parsing, and validation for mellea backends.

Provides the `MelleaTool` class (and the `@tool` decorator shorthand) for
wrapping Python callables as OpenAI-compatible tool schemas, with factory methods
for LangChain and smolagents interoperability. Also includes helpers for converting
tool lists to JSON, extracting tool call requests from raw LLM output strings, and
validating/coercing tool arguments against the tool's JSON schema using Pydantic.

## Functions

<div className="w-full h-px bg-gray-200 dark:bg-gray-700 my-4" />

### <span className="ml-2 inline-flex items-center rounded-full px-2 py-1 text-[0.7rem] font-bold tracking-wide bg-[#3064E3]/20 text-[#1D4ED8]">FUNC</span> `tool` <sup><a href="https://github.com/generative-computing/mellea/blob/v0.6.0/mellea/backends/tools.py#L246" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>

```python theme={null}
tool(func: Callable[P, R] | Callable[P, Awaitable[R]] | None = None, name: str | None = None) -> MelleaTool[P, R] | Callable[[Callable[P, R]], MelleaTool[P, R]]
```

Decorator to mark a function as a Mellea tool with type-safe parameter and return types.

This decorator wraps a function to make it usable as a tool without
requiring explicit MelleaTool.from\_callable() calls. The decorated
function returns a MelleaTool instance that must be called via .run().

**Args:**

* `func`: The function to decorate (when used without arguments)
* `name`: Optional custom name for the tool (defaults to function name)

**Returns:**

* A MelleaTool\[P, R] instance with preserved parameter and return types. Use .run() to invoke.
* The returned object passes isinstance(result, MelleaTool) checks.

**Examples:**

Basic usage:

```python theme={null}
>>> @tool
... def get_weather(location: str, days: int = 1) -> dict:
...     '''Get weather forecast.
...
...     Args:
...         location: City name
...         days: Number of days to forecast
...     '''
...     return {{"location": location, "forecast": "sunny"}}
>>>
>>> # The decorated function IS a MelleaTool
>>> isinstance(get_weather, MelleaTool)  # True
>>>
>>> # Can be used directly in tools list (no extraction needed)
>>> tools = [get_weather]
>>>
>>> # Must use .run() to invoke the tool - now with type hints
>>> result = get_weather.run(location="Boston")  # IDE shows: location: str, days: int = 1
With custom name (as decorator):
>>> @tool(name="weather_api")
... def get_weather(location: str) -> dict:
...     return {{"location": location}}
>>>
>>> result = get_weather.run(location="New York")
With custom name (as function):
>>> def new_tool(): ...
>>> differently_named_tool = tool(new_tool, name="different_name")
```

<div className="w-full h-px bg-gray-200 dark:bg-gray-700 my-4" />

### <span className="ml-2 inline-flex items-center rounded-full px-2 py-1 text-[0.7rem] font-bold tracking-wide bg-[#3064E3]/20 text-[#1D4ED8]">FUNC</span> `add_tools_from_model_options` <sup><a href="https://github.com/generative-computing/mellea/blob/v0.6.0/mellea/backends/tools.py#L314" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>

```python theme={null}
add_tools_from_model_options(tools_dict: dict[str, AbstractMelleaTool], model_options: dict[str, Any])
```

If model\_options has tools, add those tools to the tools\_dict.

Accepts MelleaTool instances or @tool decorated functions.

**Args:**

* `tools_dict`: Mutable mapping of tool name to tool instance; modified in-place.
* `model_options`: Model options dict that may contain a `ModelOption.TOOLS`
  entry (either a list of `MelleaTool` or a `dict[str, MelleaTool]`).

<div className="w-full h-px bg-gray-200 dark:bg-gray-700 my-4" />

### <span className="ml-2 inline-flex items-center rounded-full px-2 py-1 text-[0.7rem] font-bold tracking-wide bg-[#3064E3]/20 text-[#1D4ED8]">FUNC</span> `add_tools_from_context_actions` <sup><a href="https://github.com/generative-computing/mellea/blob/v0.6.0/mellea/backends/tools.py#L358" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>

```python theme={null}
add_tools_from_context_actions(tools_dict: dict[str, AbstractMelleaTool], ctx_actions: list[Component | CBlock] | None)
```

If any of the actions in ctx\_actions have tools in their template\_representation, add those to the tools\_dict.

**Args:**

* `tools_dict`: Mutable mapping of tool name to tool instance; modified in-place.
* `ctx_actions`: List of [`Component`](../core/base#class-component) or [`CBlock`](../core/base#class-cblock) objects whose template
  representations may declare tools, or `None` to skip.

<div className="w-full h-px bg-gray-200 dark:bg-gray-700 my-4" />

### <span className="ml-2 inline-flex items-center rounded-full px-2 py-1 text-[0.7rem] font-bold tracking-wide bg-[#3064E3]/20 text-[#1D4ED8]">FUNC</span> `convert_tools_to_json` <sup><a href="https://github.com/generative-computing/mellea/blob/v0.6.0/mellea/backends/tools.py#L384" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>

```python theme={null}
convert_tools_to_json(tools: dict[str, AbstractMelleaTool]) -> list[dict]
```

Convert tools to json dict representation.

**Args:**

* `tools`: Mapping of tool name to `AbstractMelleaTool` instance.

**Returns:**

* List of OpenAI-compatible JSON tool schema dicts, one per tool.

Notes:

* Huggingface transformers library lets you pass in an array of functions but doesn't like methods.
* WatsonxAI uses `from langchain_ibm.chat_models import convert_to_openai_tool` in their demos, but it gives the same values.
* OpenAI uses the same format / schema.

<div className="w-full h-px bg-gray-200 dark:bg-gray-700 my-4" />

### <span className="ml-2 inline-flex items-center rounded-full px-2 py-1 text-[0.7rem] font-bold tracking-wide bg-[#3064E3]/20 text-[#1D4ED8]">FUNC</span> `json_extraction` <sup><a href="https://github.com/generative-computing/mellea/blob/v0.6.0/mellea/backends/tools.py#L401" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>

```python theme={null}
json_extraction(text: str) -> Generator[dict, None, None]
```

Yield the next valid JSON object found in a given string.

**Args:**

* `text`: Input string potentially containing one or more JSON objects.

<div className="w-full h-px bg-gray-200 dark:bg-gray-700 my-4" />

### <span className="ml-2 inline-flex items-center rounded-full px-2 py-1 text-[0.7rem] font-bold tracking-wide bg-[#3064E3]/20 text-[#1D4ED8]">FUNC</span> `find_func` <sup><a href="https://github.com/generative-computing/mellea/blob/v0.6.0/mellea/backends/tools.py#L428" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>

```python theme={null}
find_func(d: object) -> tuple[str | None, Mapping | None]
```

Find the first function in a json-like dictionary.

Most llms output tool requests in the form `...\{"name": string, "arguments": \{\}\}...`

**Args:**

* `d`: A JSON-like Python object (typically a `dict`) to search for a function
  call record.

**Returns:**

* A `(name, args)` tuple where `name` is the tool name string and `args`
* is the arguments mapping, or `(None, None)` if no function call was found.

<div className="w-full h-px bg-gray-200 dark:bg-gray-700 my-4" />

### <span className="ml-2 inline-flex items-center rounded-full px-2 py-1 text-[0.7rem] font-bold tracking-wide bg-[#3064E3]/20 text-[#1D4ED8]">FUNC</span> `parse_tools` <sup><a href="https://github.com/generative-computing/mellea/blob/v0.6.0/mellea/backends/tools.py#L464" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>

```python theme={null}
parse_tools(llm_response: str) -> list[tuple[str, Mapping]]
```

A simple parser that will scan a string for tools and attempt to extract them; only works for json based outputs.

**Args:**

* `llm_response`: Raw string output from a language model.

**Returns:**

* List of `(tool_name, arguments)` tuples for each tool call found.

<div className="w-full h-px bg-gray-200 dark:bg-gray-700 my-4" />

### <span className="ml-2 inline-flex items-center rounded-full px-2 py-1 text-[0.7rem] font-bold tracking-wide bg-[#3064E3]/20 text-[#1D4ED8]">FUNC</span> `validate_tool_arguments` <sup><a href="https://github.com/generative-computing/mellea/blob/v0.6.0/mellea/backends/tools.py#L483" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>

```python theme={null}
validate_tool_arguments(tool: AbstractMelleaTool, args: Mapping[str, Any]) -> dict[str, Any]
```

Validate and optionally coerce tool arguments against tool's JSON schema.

This function validates tool call arguments extracted from LLM responses against
the tool's JSON schema from as\_json\_tool. It can automatically coerce common type
mismatches (e.g., string "30" to int 30) and provides detailed error messages.

**Args:**

* `tool`: The MelleaTool instance to validate against
* `args`: Raw arguments from model (post-JSON parsing)
* `coerce_types`: If True, attempt type coercion for common cases (default: True)
* `strict`: If True, raise ValidationError on failures; if False, log warnings
  and return original args (default: False)

**Returns:**

* Validated and optionally coerced arguments dict

**Raises:**

* `ValidationError`: If strict=True and validation fails

**Examples:**

```python theme={null}
>>> def get_weather(location: str, days: int = 1) -> dict:
...     return {{"location": location, "days": days}}
>>> tool = MelleaTool.from_callable(get_weather)
>>> # LLM returns days as string
>>> args = {{"location": "Boston", "days": "3"}}
>>> validated = validate_tool_arguments(tool, args)
>>> validated
{{'location': 'Boston', 'days': 3}}
>>> # Strict mode raises on validation errors
>>> bad_args = {{"location": "Boston", "days": "not_a_number"}}
>>> validate_tool_arguments(tool, bad_args, strict=True)
Traceback (most recent call last):
...
pydantic.ValidationError: ...
```

<div className="w-full h-px bg-gray-200 dark:bg-gray-700 my-4" />

### <span className="ml-2 inline-flex items-center rounded-full px-2 py-1 text-[0.7rem] font-bold tracking-wide bg-[#3064E3]/20 text-[#1D4ED8]">FUNC</span> `convert_function_to_ollama_tool` <sup><a href="https://github.com/generative-computing/mellea/blob/v0.6.0/mellea/backends/tools.py#L991" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>

```python theme={null}
convert_function_to_ollama_tool(func: Callable, name: str | None = None) -> OllamaTool
```

Convert a Python callable to an Ollama-compatible tool schema.

Imported from Ollama, with enhancements to support Pydantic BaseModel parameters.

**Args:**

* `func`: The Python callable to convert.
* `name`: Optional override for the tool name; defaults to `func.__name__`.

**Returns:**

* An `OllamaTool` instance representing the function as an OpenAI-compatible
* tool schema.

<div className="w-full h-px bg-gray-200 dark:bg-gray-700 my-4" />

## Classes

<div className="w-full h-px bg-gray-200 dark:bg-gray-700 my-4" />

### <span className="ml-2 inline-flex items-center rounded-full px-2 py-1 text-[0.7rem] font-bold tracking-wide bg-[#4ADE8033]/20 text-[#15803D]">CLASS</span> `MelleaTool` <sup><a href="https://github.com/generative-computing/mellea/blob/v0.6.0/mellea/backends/tools.py#L31" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>

Tool class to represent a callable tool with an OpenAI-compatible JSON schema.

Wraps a Python callable alongside its JSON schema representation so it can be
registered with backends that support tool calling (OpenAI, Ollama, HuggingFace, etc.).

**Args:**

* `name`: The tool name used for identification and lookup.
* `tool_call`: The underlying Python callable to invoke when the tool is run.
* `as_json_tool`: The OpenAI-compatible JSON schema dict describing
  the tool's parameters.

<div className="h-8" />

**Methods:**

<div className="w-full h-px bg-gray-200 dark:bg-gray-700 my-4" />

#### <span className="ml-2 inline-flex items-center rounded-full px-2 py-1 text-[0.7rem] font-bold tracking-wide bg-[#3064E3]/20 text-[#1D4ED8]">FUNC</span> `run` <sup><a href="https://github.com/generative-computing/mellea/blob/v0.6.0/mellea/backends/tools.py#L64" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>

```python theme={null}
run(self, *args: P.args, **kwargs: P.kwargs) -> R
```

Run the tool with the given arguments.

**Args:**

* `*args`: Positional arguments forwarded to the underlying callable.
* `**kwargs`: Keyword arguments forwarded to the underlying callable.

**Returns:**

* The return value of the underlying callable.

<div className="w-full h-px bg-gray-200 dark:bg-gray-700 my-4" />

#### <span className="ml-2 inline-flex items-center rounded-full px-2 py-1 text-[0.7rem] font-bold tracking-wide bg-[#3064E3]/20 text-[#1D4ED8]">FUNC</span> `as_json_tool` <sup><a href="https://github.com/generative-computing/mellea/blob/v0.6.0/mellea/backends/tools.py#L77" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>

```python theme={null}
as_json_tool(self) -> dict[str, Any]
```

Return the tool converted to a OpenAI compatible JSON object.

<div className="w-full h-px bg-gray-200 dark:bg-gray-700 my-4" />

#### <span className="ml-2 inline-flex items-center rounded-full px-2 py-1 text-[0.7rem] font-bold tracking-wide bg-[#3064E3]/20 text-[#1D4ED8]">FUNC</span> `from_langchain` <sup><a href="https://github.com/generative-computing/mellea/blob/v0.6.0/mellea/backends/tools.py#L82" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>

```python theme={null}
from_langchain(cls, tool: Any) -> 'MelleaTool[..., Any]'
```

Create a MelleaTool from a LangChain tool object.

**Args:**

* `tool`: A `langchain_core.tools.BaseTool` instance to wrap.

**Returns:**

* MelleaTool\[..., Any]: A Mellea tool wrapping the LangChain tool.

**Raises:**

* `ImportError`: If `langchain-core` is not installed.
* `ValueError`: If `tool` is not a `BaseTool` instance.

<div className="w-full h-px bg-gray-200 dark:bg-gray-700 my-4" />

#### <span className="ml-2 inline-flex items-center rounded-full px-2 py-1 text-[0.7rem] font-bold tracking-wide bg-[#3064E3]/20 text-[#1D4ED8]">FUNC</span> `from_smolagents` <sup><a href="https://github.com/generative-computing/mellea/blob/v0.6.0/mellea/backends/tools.py#L129" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>

```python theme={null}
from_smolagents(cls, tool: Any) -> 'MelleaTool[..., Any]'
```

Create a Tool from a HuggingFace smolagents tool object.

**Args:**

* `tool`: A smolagents.Tool instance

**Returns:**

* MelleaTool\[..., Any]: A Mellea tool wrapping the smolagents tool

**Raises:**

* `ImportError`: If smolagents is not installed
* `ValueError`: If tool is not a smolagents Tool instance

<div className="w-full h-px bg-gray-200 dark:bg-gray-700 my-4" />

#### <span className="ml-2 inline-flex items-center rounded-full px-2 py-1 text-[0.7rem] font-bold tracking-wide bg-[#3064E3]/20 text-[#1D4ED8]">FUNC</span> `from_callable` <sup><a href="https://github.com/generative-computing/mellea/blob/v0.6.0/mellea/backends/tools.py#L185" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>

```python theme={null}
from_callable(cls, func: Callable[P, Awaitable[R]], name: str | None = None) -> 'MelleaTool[P, R]'
```

<div className="w-full h-px bg-gray-200 dark:bg-gray-700 my-4" />

#### <span className="ml-2 inline-flex items-center rounded-full px-2 py-1 text-[0.7rem] font-bold tracking-wide bg-[#3064E3]/20 text-[#1D4ED8]">FUNC</span> `from_callable` <sup><a href="https://github.com/generative-computing/mellea/blob/v0.6.0/mellea/backends/tools.py#L191" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>

```python theme={null}
from_callable(cls, func: Callable[P, R], name: str | None = None) -> 'MelleaTool[P, R]'
```

<div className="w-full h-px bg-gray-200 dark:bg-gray-700 my-4" />

#### <span className="ml-2 inline-flex items-center rounded-full px-2 py-1 text-[0.7rem] font-bold tracking-wide bg-[#3064E3]/20 text-[#1D4ED8]">FUNC</span> `from_callable` <sup><a href="https://github.com/generative-computing/mellea/blob/v0.6.0/mellea/backends/tools.py#L196" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>

```python theme={null}
from_callable(cls, func: Callable[P, R] | Callable[P, Awaitable[R]], name: str | None = None) -> 'MelleaTool[P, R]'
```

Create a MelleaTool from a plain Python callable.

Introspects the callable's signature and docstring to build an
OpenAI-compatible JSON schema automatically. Async functions (defined
with `async def`) are supported transparently: the coroutine is
awaited on mellea's shared event loop so sync callers of `.run()`
receive the resolved value rather than an un-awaited coroutine.

**Args:**

* `func`: The Python
  callable (sync or async) to wrap as a tool.
* `name`: Optional name override; defaults to `func.__name__`.

**Returns:**

* MelleaTool\[P, R]: A Mellea tool wrapping the callable with preserved parameter and return types.

<div className="w-full h-px bg-gray-200 dark:bg-gray-700 my-4" />

### <span className="ml-2 inline-flex items-center rounded-full px-2 py-1 text-[0.7rem] font-bold tracking-wide bg-[#4ADE8033]/20 text-[#15803D]">CLASS</span> `SubscriptableBaseModel` <sup><a href="https://github.com/generative-computing/mellea/blob/v0.6.0/mellea/backends/tools.py#L742" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>

Pydantic `BaseModel` subclass that also supports subscript (`[]`) access.

Imported from the Ollama Python client. Allows model fields to be accessed
via `model["field"]` in addition to `model.field`, which is required for
compatibility with Ollama's internal response parsing.

<div className="h-8" />

**Methods:**

<div className="w-full h-px bg-gray-200 dark:bg-gray-700 my-4" />

#### <span className="ml-2 inline-flex items-center rounded-full px-2 py-1 text-[0.7rem] font-bold tracking-wide bg-[#3064E3]/20 text-[#1D4ED8]">FUNC</span> `get` <sup><a href="https://github.com/generative-computing/mellea/blob/v0.6.0/mellea/backends/tools.py#L820" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>

```python theme={null}
get(self, key: str, default: Any = None) -> Any
```

Return the value of a field by name, or a default if the field does not exist.

**Args:**

* `key`: The field name to look up on the model.
* `default`: Value to return when `key` is not a field on the model.
  Defaults to `None`.

**Returns:**

* The field value if the attribute exists, otherwise `default`.

```python theme={null}
>>> msg = Message(role='user')
>>> msg.get('role')
'user'
>>> msg = Message(role='user')
>>> msg.get('nonexistent')
>>> msg = Message(role='user')
>>> msg.get('nonexistent', 'default')
'default'
>>> msg = Message(role='user', tool_calls=[ Message.ToolCall(function=Message.ToolCall.Function(name='foo', arguments={{}}))])
>>> msg.get('tool_calls')[0]['function']['name']
'foo'
```

<div className="w-full h-px bg-gray-200 dark:bg-gray-700 my-4" />

### <span className="ml-2 inline-flex items-center rounded-full px-2 py-1 text-[0.7rem] font-bold tracking-wide bg-[#4ADE8033]/20 text-[#15803D]">CLASS</span> `OllamaTool` <sup><a href="https://github.com/generative-computing/mellea/blob/v0.6.0/mellea/backends/tools.py#L847" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>

Pydantic model for an Ollama-compatible tool schema, imported from the Ollama Python SDK.

Represents the JSON structure that Ollama (and OpenAI-compatible endpoints) expect
when a tool is passed to the chat API. Mellea builds these objects internally via
`convert_function_to_ollama_tool` and never exposes them to end users directly.

**Attributes:**

* `type`: Tool type; always `"function"` for function-calling tools.
* `function`: Nested object containing the function name,
  description, and parameters schema.

<div className="w-full h-px bg-gray-200 dark:bg-gray-700 my-4" />
