Implementation:Run llama Llama index Tool Calling
Overview
The calling.py module provides utility functions for invoking tools within the LlamaIndex framework. It contains both synchronous and asynchronous functions for calling tools directly with argument dictionaries, as well as higher-level functions that resolve tool selections from a sequence of available tools. These utilities serve as the central dispatch mechanism for tool execution throughout the agent pipeline.
Source File: llama-index-core/llama_index/core/tools/calling.py
Module: llama_index.core.tools.calling
Lines of Code: 106
Dependencies
| Dependency | Type | Purpose |
|---|---|---|
llama_index.core.tools.types.BaseTool |
Internal | Base tool interface for all tool implementations |
llama_index.core.tools.types.ToolOutput |
Internal | Standard output wrapper returned by tool calls |
llama_index.core.tools.types.adapt_to_async_tool |
Internal | Adapter function to convert sync tools to async tools |
llama_index.core.llms.llm.ToolSelection |
Internal | Data model representing an LLM's tool selection |
json |
Standard Library | JSON serialization for verbose logging |
typing |
Standard Library | Type annotations (TYPE_CHECKING, Sequence) |
Function: call_tool
The call_tool function is the primary synchronous entry point for invoking a tool with a dictionary of arguments.
Signature
def call_tool(tool: BaseTool, arguments: dict) -> ToolOutput
Parameters
| Parameter | Type | Description |
|---|---|---|
tool |
BaseTool |
The tool instance to call |
arguments |
dict |
Dictionary of keyword arguments to pass to the tool |
Logic
The function implements a smart invocation strategy:
- It checks whether the tool's parameter schema has exactly one property and exactly one argument is provided.
- If so, it attempts to call the tool with the single argument as a positional parameter (using
next(iter(arguments))to extract the value). - If that positional call fails (some tools require keyword arguments), it falls back to
tool(**arguments). - For multi-argument tools, it calls
tool(**arguments)directly. - If any exception occurs during invocation, it returns a
ToolOutputwithis_error=True, capturing the error message and exception object.
def call_tool(tool: BaseTool, arguments: dict) -> ToolOutput:
try:
if (
len(tool.metadata.get_parameters_dict()["properties"]) == 1
and len(arguments) == 1
):
try:
single_arg = arguments[next(iter(arguments))]
return tool(single_arg)
except Exception:
return tool(**arguments)
else:
return tool(**arguments)
except Exception as e:
return ToolOutput(
content="Encountered error: " + str(e),
tool_name=tool.metadata.get_name(),
raw_input=arguments,
raw_output=str(e),
is_error=True,
exception=e,
)
Function: acall_tool
The asynchronous counterpart to call_tool.
Signature
async def acall_tool(tool: BaseTool, arguments: dict) -> ToolOutput
Logic
- Converts the tool to an async-compatible tool via
adapt_to_async_tool(tool). - Applies the same single-argument vs. multi-argument invocation strategy as
call_tool, but usesawait async_tool.acall(...). - Error handling is identical, returning a
ToolOutputwithis_error=Trueon failure.
Function: call_tool_with_selection
A higher-level function that dispatches a ToolSelection to the appropriate tool from a sequence.
Signature
def call_tool_with_selection(
tool_call: ToolSelection,
tools: Sequence["BaseTool"],
verbose: bool = False,
) -> ToolOutput
Parameters
| Parameter | Type | Description |
|---|---|---|
tool_call |
ToolSelection |
The LLM's tool selection containing tool name and keyword arguments |
tools |
Sequence[BaseTool] |
Available tools to select from |
verbose |
bool |
Whether to print function call details and output (default: False)
|
Logic
- Builds a dictionary mapping tool names to tool instances from the provided sequence.
- Extracts the tool name from
tool_call.tool_name. - If
verboseisTrue, prints the function name and JSON-serialized arguments. - Looks up the tool by name and delegates to
call_tool. - If
verboseisTrue, prints the output content. - Returns the
ToolOutput.
Function: acall_tool_with_selection
The asynchronous counterpart to call_tool_with_selection.
Signature
async def acall_tool_with_selection(
tool_call: ToolSelection,
tools: Sequence["BaseTool"],
verbose: bool = False,
) -> ToolOutput
Logic
Identical to call_tool_with_selection but delegates to acall_tool using await.
Error Handling
All four functions share a consistent error-handling pattern. When an exception occurs during tool execution:
- The error is caught and wrapped in a
ToolOutputobject. - The
contentfield is set to"Encountered error: " + str(e). - The
is_errorflag is set toTrue. - The original
exceptionobject is preserved for upstream inspection. - The
raw_inputis set to the original arguments dictionary.
This ensures that tool failures do not crash the agent pipeline but instead propagate as structured error outputs.
Design Patterns
Single-Argument Optimization
The module detects when a tool has exactly one parameter and exactly one argument is provided. In this case, it first tries calling the tool with the value as a positional argument rather than a keyword argument. This accommodates tools that accept a simple positional string input (common for query-based tools) while falling back to keyword arguments for tools that require them.
Sync/Async Symmetry
Every synchronous function has a corresponding async version:
call_tool/acall_toolcall_tool_with_selection/acall_tool_with_selection
This allows the same calling patterns to be used in both synchronous and asynchronous agent execution contexts.
See Also
- Run_llama_Llama_index_Tool_Schema_Utils - Utilities for generating tool schemas from functions
- Run_llama_Llama_index_EvalQueryEngineTool - Query engine tool with evaluation
- Run_llama_Llama_index_QueryPlanTool - Tool for executing query plans