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.
Prerequisites: Quick Start complete, pip install mellea,
Ollama running locally. LangChain interop requires pip install langchain-community.
Note: An agent is a generative program in which an LLM determines the control
flow of the program. The patterns in this page range from simple one-shot tool use
to goal-driven agentic loops.
The @tool decorator turns a regular Python function into a tool the LLM can call.
Mellea uses the function’s docstring and type hints to build the tool schema:
from mellea.backends import tool
@tool
def get_weather(location: str, days: int = 1) -> dict:
"""Get weather forecast for a location.
Args:
location: City name.
days: Number of days to forecast.
"""
return {"location": location, "days": days, "forecast": "sunny", "temperature": 72}
Use @tool(name="...") to override the tool name as it appears to the model:
from mellea.backends import tool
@tool(name="calculator")
def calculate(expression: str) -> str:
"""Evaluate a mathematical expression.
Args:
expression: A mathematical expression to evaluate.
"""
return str(eval(expression)) # noqa: S307 — use only with trusted input
Decorated tools expose a .run() method for direct invocation without going through
the LLM:
weather = get_weather.run("Boston", days=3)
You can also construct a tool from any callable manually:
from mellea.backends.tools import MelleaTool
def double(x: int) -> int:
"""Double the input. Args: x: Input value."""
return x * 2
my_tool = MelleaTool.from_callable(double)
Pass tools via ModelOption.TOOLS. The model can then choose to call them:
from mellea import start_session
from mellea.backends import ModelOption, tool
@tool
def get_weather(location: str, days: int = 1) -> dict:
"""Get weather forecast for a location.
Args:
location: City name.
days: Number of days to forecast.
"""
return {"location": location, "days": days, "forecast": "sunny", "temperature": 72}
m = start_session()
response = m.instruct(
"What is the weather like in San Francisco?",
model_options={ModelOption.TOOLS: [get_weather]},
)
print(str(response))
# Output will vary — LLM responses depend on model and temperature.
Use the uses_tool requirement to enforce that the model actually calls a specific
tool:
from mellea import start_session
from mellea.backends import ModelOption
from mellea.backends.tools import MelleaTool
from mellea.stdlib.requirements import uses_tool
from mellea.stdlib.tools import local_code_interpreter
m = start_session()
response = m.instruct(
"Use the code interpreter tool to compute 7 factorial.",
requirements=[uses_tool(local_code_interpreter)],
model_options={ModelOption.TOOLS: [MelleaTool.from_callable(local_code_interpreter)]},
tool_calls=True,
)
With tool_calls=True, the result exposes a .tool_calls dict you can inspect and
execute:
code = response.tool_calls["local_code_interpreter"].args["code"]
exec_result = response.tool_calls["local_code_interpreter"].call_func()
print(exec_result)
tool_arg_validator adds fine-grained validation over the arguments the model
generates for a tool call:
from mellea import start_session
from mellea.backends import ModelOption
from mellea.backends.tools import MelleaTool
from mellea.stdlib.requirements import tool_arg_validator, uses_tool
from mellea.stdlib.tools import local_code_interpreter
m = start_session()
response = m.instruct(
"Use the code interpreter to plot y=x². Save the plot to /tmp/output.png.",
requirements=[
uses_tool(local_code_interpreter),
tool_arg_validator(
"The plot must be saved to /tmp/output.png and must not call plt.show()",
tool_name=local_code_interpreter,
arg_name="code",
validation_fn=lambda code: (
"/tmp/output.png" in code and "plt.show()" not in code
),
),
],
model_options={ModelOption.TOOLS: [MelleaTool.from_callable(local_code_interpreter)]},
tool_calls=True,
)
LangChain and smolagents interop
Import tools directly from LangChain or smolagents. Install the required
packages first: uv pip install langchain-community ddgs.
from langchain_community.tools import DuckDuckGoSearchResults
from mellea.backends.tools import MelleaTool
search_tool = MelleaTool.from_langchain(DuckDuckGoSearchResults(output_format="list"))
MelleaTool.from_smolagents() works the same way for smolagents tools.
ReACT agent
react() is a built-in goal-driven agentic loop. It iteratively selects and calls
tools until the goal is met or a step budget is reached:
import asyncio
from mellea import start_session
from mellea.backends.tools import MelleaTool
from mellea.stdlib.context import ChatContext
from mellea.stdlib.frameworks.react import react
from langchain_community.tools import DuckDuckGoSearchResults
m = start_session()
search_tool = MelleaTool.from_langchain(DuckDuckGoSearchResults(output_format="list"))
async def main():
result, _ = await react(
goal="What is the Mellea Python library?",
context=ChatContext(),
backend=m.backend,
tools=[search_tool],
)
print(result)
asyncio.run(main())
# Output will vary — LLM responses depend on model and temperature.
react() can return a structured Pydantic object by passing a format parameter:
import asyncio
import pydantic
from mellea import start_session
from mellea.backends.tools import MelleaTool
from mellea.stdlib.context import ChatContext
from mellea.stdlib.frameworks.react import react
from langchain_community.tools import DuckDuckGoSearchResults
class Email(pydantic.BaseModel):
to: str
subject: str
body: str
m = start_session()
search_tool = MelleaTool.from_langchain(DuckDuckGoSearchResults(output_format="list"))
async def main():
result, _ = await react(
goal="Write an email about Mellea to Jake with subject 'cool library'.",
context=ChatContext(),
backend=m.backend,
tools=[search_tool],
format=Email,
)
print(result.parsed_repr.body)
asyncio.run(main())
# Output will vary — LLM responses depend on model and temperature.
Advanced: The core idea of ReACT is to alternate between reasoning (“Thought”)
and acting (“Action”) in a loop: generate a thought, choose an action, supply
arguments, observe the tool output, then check whether the goal is achieved.
Mellea’s react() implements this loop using chat() with structured output at
each step, backed by @generative for constrained argument selection. You can
build a custom ReACT-style loop by hand using the same primitives — see
mellea.stdlib.components.react for reference.
Code interpreter
Mellea includes a built-in Python code interpreter tool:
from mellea.stdlib.tools import code_interpreter
result = code_interpreter("print(1 + 1)")
print(result) # "2"
Pass local_code_interpreter as a tool to instruct() to let the LLM write and
execute code. Combine with uses_tool and tool_arg_validator to constrain what
gets generated (see examples above).
Warning: local_code_interpreter executes Python code in the current process.
Do not use it in production contexts without sandboxing.
See also: Tutorial 04: Making Agents Reliable | Instruct, Validate, Repair