Skip to main content

Overview

When the built-in tools don’t fit your needs, wrap any Python function as a custom tool to extend your agent. This page covers three forms: plain-argument functions, context-aware functions, and long-running tasks.
  • A plain-argument function is the simplest custom tool: define a function, add type hints and a docstring, and register it on the agent. The agent decides when to call it and how to pass arguments based on the signature and docstring.
  • A context-aware function adds a tool_context: ToolContext parameter to access the agent’s runtime context — shared session state and other runtime information. The framework injects this argument automatically; the model neither sees nor needs to pass it.
  • Long-running tasks suit time-consuming or asynchronous work (large computations, data analysis, batch jobs). Wrap the function with LongRunningFunctionTool: the tool returns a pending status and a task ID first, your app advances the task in the background, then feeds the final result back to the agent.

Prerequisites

Complete model configuration before running the agent examples. Plain Python functions can also be called locally without a model or service credentials.

Usage

Plain-argument functions

1

Define the function

Use flat, clear arguments and return types.
2

Write the docstring

Describe what the function does, its arguments, and its return value — the model relies on this to understand the tool.
3

Register it on the agent

Put the function in the agent’s tools list.
The calculator below illustrates this. Note the divide branch: on division by zero it returns status: "error" with no result, consistent with the status: "success" of the other branches.
examples/tools/function_tools/simple_function_tool.py

Context-aware functions

examples/tools/function_tools/tool_context_usage.py
The tool function can read and update shared session state through tool_context.state, so later tool calls and callbacks can reuse that information.

Long-running tasks

This example simulates submission and completion without downloading data or starting a background job. The tool returns pending, the run loop captures the long-running call, then a FunctionResponse feeds back a finish status so the agent can produce its final reply.
examples/tools/function_tools/long_running_tool.py

Synchronous, asynchronous, and long-running calls

A normal tool may use def or async def. Async functions can await network or storage operations, but do not automatically create background jobs. LongRunningFunctionTool marks a call that expects a later result; the application still owns submission, persistence, polling, and failure handling. When supplying the final result, preserve the original FunctionResponse call ID and tool name, and use the same application, user, and session identifiers. Do not attach another request’s result. Normal functions should also return an explicit success or failure status so error text is not treated as business data.
Last modified on September 19, 2026