Dynamiq
Agents

Tools & Function Tools

The built-in tool catalog, the function_tool decorator for wrapping Python functions, and custom tool nodes.

Tools are workflow nodes the agent can call during its reasoning loop. Pass any tool node in the agent's tools list — the agent reads each tool's name, description, and input schema to decide when and how to call it. This page tours the built-in tools in dynamiq.nodes.tools, then shows the two ways to build your own: the function_tool decorator and a custom Node subclass.

Built-in tools

All classes below are importable from dynamiq.nodes.tools unless noted otherwise.

ToolService
ExaToolExa neural search
TavilyToolTavily
ScaleSerpToolScale SERP (Google results)
FirecrawlSearchToolFirecrawl search
JinaSearchToolJina search

Web scraping

ToolService
FirecrawlToolFirecrawl scrape/crawl
JinaScrapeToolJina reader
ZenRowsToolZenRows

Code execution

ToolWhere code runs
E2BInterpreterToolE2B cloud sandbox (Python + shell)
DaytonaInterpreterToolDaytona sandbox
PythonPredefined Python code you author, executed as a node
PythonCodeExecutorExecutes code the agent supplies at run time
PythonMontyRestricted local Python interpreter

Browser and desktop automation

ToolWhat it drives
StagehandHeadless browser sessions
E2BDesktopToolE2B desktop VM
CuaDesktopToolComputer-use desktop automation

Files and data

ToolPurpose
FileReadTool, FileWriteTool, FileListToolRead, write, and list files in the agent's file store
SQLExecutorRun SQL against a configured database connection
CypherExecutorRun Cypher against Neo4j
HttpApiCallCall arbitrary HTTP APIs
PipedreamInvoke Pipedream-connected apps
MCPServer / MCPToolExpose tools from an MCP server to the agent

RAG

ToolPurpose
VectorStoreRetriever (dynamiq.nodes.retrievers)Semantic search over a vector store: embeds the query, retrieves, optionally re-ranks
VectorStoreWriter (dynamiq.nodes.writers)Lets the agent embed and upsert documents into a vector store

See Retrievers & Rankers for configuration.

Agent utilities

ToolPurpose
HumanFeedbackToolPause and ask a human for input
ThinkingToolA scratchpad action for extended reasoning
TodoWriteToolMaintain a todo list across loop iterations
SummarizerToolLLM summarization of long content
SkillsToolLoad and execute reusable skills
ParallelToolCallsToolBatch several tool calls into one step
SubAgentToolWraps a child agent so a parent can call it as a tool

Any Agent instance can also be passed directly in another agent's tools list — the SDK wraps it as a sub-agent automatically. See Orchestrators for multi-agent patterns.

Wrapping a function with function_tool

The fastest path from a Python function to a tool. The decorator builds a FunctionTool subclass whose input schema is generated from the function signature, and whose description comes from the docstring:

from dynamiq.connections import OpenAI as OpenAIConnection
from dynamiq.nodes.agents import Agent
from dynamiq.nodes.llms import OpenAI
from dynamiq.nodes.tools.function_tool import function_tool

@function_tool
def multiply_numbers(a: int, b: int, **kwargs) -> int:
    """Multiply two numbers together."""
    return a * b

llm = OpenAI(connection=OpenAIConnection(), model="gpt-4o")

agent = Agent(
    name="math-agent",
    llm=llm,
    tools=[multiply_numbers()],  # call the decorated function to instantiate the tool
    max_loops=4,
)

result = agent.run(input_data={"input": "What is 6 times 7?"})
print(result.output["content"])

Notes on the generated tool:

  • Type hints become the validated input schema (a: int, b: int above). Parameters named kwargs or config are excluded from the schema.
  • The tool's name defaults to the function name and its description to the docstring plus the function signature — write docstrings the LLM can act on.
  • The function's return value is wrapped as {"content": result}.

You can also subclass FunctionTool directly when you want explicit naming and a hand-written schema:

from pydantic import BaseModel

from dynamiq.nodes.tools.function_tool import FunctionTool

class AddNumbersInputSchema(BaseModel):
    a: int = -1
    b: int = -1

class AddNumbersTool(FunctionTool):
    name: str = "Add Numbers Tool"
    description: str = "A tool that adds two numbers together."

    def run_func(self, input_data: AddNumbersInputSchema, **kwargs) -> int:
        """Add two numbers together."""
        return input_data.a + input_data.b

Custom tool nodes

For tools that need connections, state, or full control over execution, subclass Node with group = NodeGroup.TOOLS and implement execute:

from typing import Any, Literal

import sympy as sp
from pydantic import ConfigDict

from dynamiq.nodes import NodeGroup
from dynamiq.nodes.node import Node, ensure_config
from dynamiq.runnables import RunnableConfig

class CalculatorTool(Node):
    group: Literal[NodeGroup.TOOLS] = NodeGroup.TOOLS
    name: str = "Calculator"
    description: str = (
        "Tool to evaluate mathematical expressions. "
        "Provide a raw string of the math operation to parse and evaluate."
    )

    model_config = ConfigDict(arbitrary_types_allowed=True)

    def execute(
        self, input_data: dict[str, Any], config: RunnableConfig = None, **kwargs
    ) -> dict[str, Any]:
        config = ensure_config(config)
        self.run_on_node_execute_run(config.callbacks, **kwargs)

        expression = input_data.get("input", "")
        try:
            result = sp.sympify(expression)
        except Exception as e:
            result = str(e)
        return {"content": result}

Rules for custom tools:

  • Return a dict with the result under "content" — that is what the agent reads as the observation.
  • Write a description that tells the LLM when to use the tool and what input shape it expects; it is the single biggest factor in tool-selection quality.
  • Call ensure_config and run_on_node_execute_run so callbacks and tracing work.

See Custom Nodes for the full node contract, including input schemas and connection handling.

Tool output handling

Two agent-level settings shape what the agent sees from tools:

  • tool_output_max_length / tool_output_truncate_enabled — long tool outputs are truncated to a token budget before entering the prompt (enabled by default).
  • direct_tool_output_enabled — when true, the agent may return a raw tool output as the final answer without rephrasing it.

Next steps

On this page