@@ -640,16 +640,25 @@ def __init__(
640640 name: The name of the function.
641641 description: A description of the function.
642642 approval_mode: Whether or not approval is required to run this tool.
643- Default is that approval is required.
643+ Default is that approval is NOT required (``"never_require"``) .
644644 max_invocations: The maximum number of times this function can be invoked.
645645 If None, there is no limit. Should be at least 1.
646646 max_invocation_exceptions: The maximum number of exceptions allowed during invocations.
647647 If None, there is no limit. Should be at least 1.
648648 additional_properties: Additional properties to set on the function.
649- func: The function to wrap.
649+ func: The function to wrap. When ``None``, creates a declaration-only tool
650+ that has no implementation. Declaration-only tools are useful when you want
651+ the agent to reason about tool usage without executing them, or when the
652+ actual implementation exists elsewhere (e.g., client-side rendering).
650653 input_model: The Pydantic model that defines the input parameters for the function.
651654 This can also be a JSON schema dictionary.
652- If not provided, it will be inferred from the function signature.
655+ If not provided and ``func`` is not ``None``, it will be inferred from
656+ the function signature. When ``func`` is ``None`` and ``input_model`` is
657+ not provided, the tool will use an empty input model (no parameters) in
658+ its JSON schema. For declaration-only tools that should declare
659+ parameters, explicitly provide ``input_model`` (either a Pydantic
660+ ``BaseModel`` or a JSON schema dictionary) so the model can reason about
661+ the expected arguments.
653662 **kwargs: Additional keyword arguments.
654663 """
655664 super ().__init__ (
@@ -1286,7 +1295,11 @@ def tool(
12861295 to bypass automatic inference from the function signature.
12871296
12881297 Args:
1289- func: The function to decorate.
1298+ func: The function to decorate. This parameter enables the decorator to be used
1299+ both with and without parentheses: ``@tool`` directly decorates the function,
1300+ while ``@tool()`` or ``@tool(name="custom")`` returns a decorator. For
1301+ declaration-only tools (no implementation), use :class:`FunctionTool` directly
1302+ with ``func=None``—see the example below.
12901303
12911304 Keyword Args:
12921305 name: The name of the function. If not provided, the function's ``__name__``
@@ -1301,7 +1314,7 @@ def tool(
13011314 When provided, the schema is used instead of inferring one from the
13021315 function's signature. Defaults to ``None`` (infer from signature).
13031316 approval_mode: Whether or not approval is required to run this tool.
1304- Default is that approval is required.
1317+ Default is that approval is NOT required (``"never_require"``) .
13051318 max_invocations: The maximum number of times this function can be invoked.
13061319 If None, there is no limit, should be at least 1.
13071320 max_invocation_exceptions: The maximum number of exceptions allowed during invocations.
@@ -1369,6 +1382,20 @@ def get_weather(location: str, unit: str = "celsius") -> str:
13691382 '''Get weather for a location.'''
13701383 return f"Weather in {location}: 22 {unit}"
13711384
1385+
1386+ # Declaration-only tool (no implementation)
1387+ # Use FunctionTool directly when you need a tool declaration without
1388+ # an executable function. The agent can request this tool, but it won't
1389+ # be executed automatically. Useful for testing agent reasoning or when
1390+ # the implementation is handled externally (e.g., client-side rendering).
1391+ from agent_framework import FunctionTool
1392+
1393+ declaration_only_tool = FunctionTool(
1394+ name="get_current_time",
1395+ description="Get the current time in ISO 8601 format.",
1396+ func=None, # Explicitly no implementation - makes declaration_only=True
1397+ )
1398+
13721399 """
13731400
13741401 def decorator (func : Callable [..., ReturnT | Awaitable [ReturnT ]]) -> FunctionTool [Any , ReturnT ]:
0 commit comments