Skip to content

Make FuncTool and @function_tool decorated function callable #708

Open
@chiehmin-wei

Description

@chiehmin-wei

Describe the feature

What is the feature you're requesting? How would it work? Please provide examples and details if possible.

I'm using the @function_tool decorator extensively. In some instances, I want to call the underlying function directly, but I'd get a TypeError: FuncTool is not invokable error if I do.

For example, if I do

@function_tool
def add(a, b):
  return a + b

print(add(1, 2)
assert add(1, 2) == 3

This would throw a TypeError.

This would be useful for unit testing the function directly too.

A workaround I have right now is to just have a util function, and then have a decorated version that calls that util function. However, this makes things ugly since I'd have to repeat the docstrings, etc. since that's where LLMs are getting the function descriptions.

Activity

EbadullahJ

EbadullahJ commented on May 17, 2025

@EbadullahJ

When you use the @function_tool decorator, it wraps your function in a FuncTool object that is not directly callable—it's designed to be executed by an LLM or agent, not manually by you. That’s why calling add(1, 2) raises a TypeError: FuncTool is not invokable. The function becomes metadata for the agent to parse, and execution happens when the agent triggers it, not you. To fix this and allow testing or local use, you can call the original function directly using add.__wrapped__(1, 2). This gives you access to the raw logic without involving the tool system. If you want a cleaner long-term solution, consider modifying your @function_tool decorator to implement __call__ in the wrapper class, which can forward arguments to the original function—making it both agent-compatible and directly callable in tests or scripts.

from openai import function_tool

@function_tool
def add(a: int, b: int) -> int:
    """Adds two numbers."""
    return a + b

result = add.__wrapped__(1, 2)  #  result = 3
AreebaxIrfan

AreebaxIrfan commented on May 17, 2025

@AreebaxIrfan

@function_tool?
It registers your function as a tool for LLMs, enabling agents to understand and call it using metadata (name, docstring, parameters).

Problem:
After decoration, add(1, 2) raises a TypeError because the function is wrapped and no longer directly callable.

✅ Solution:
Use add.wrapped(1, 2) to call the original function for testing or local use.

✅ Ensure the decorator uses functools.wraps() to expose .wrapped.


from agents import function_tool  # Adjust this import

@function_tool
def add(a, b):
    """Add two numbers."""
    return a + b

assert add.__wrapped__(1, 2) == 3
chiehmin-wei

chiehmin-wei commented on May 18, 2025

@chiehmin-wei
Author

Image

chiehmin-wei

chiehmin-wei commented on May 18, 2025

@chiehmin-wei
Author

welp i guess once we add in RunContext as a local parameter, it might be better to just call a separate util function
it'd be interesting to see how to unit test a FunctionTool tho.

rm-openai

rm-openai commented on May 19, 2025

@rm-openai
Collaborator

You could use function_tool() directly instead of as a decorator. So just define your function like usual, and then pass tools=[function_tool(my_function)] to the agent. Would that work?

chiehmin-wei

chiehmin-wei commented on May 20, 2025

@chiehmin-wei
Author

Yes I think that would work.
Wondering if there's anyway to unit test the wrapped function though.

rm-openai

rm-openai commented on May 20, 2025

@rm-openai
Collaborator
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @chiehmin-wei@AreebaxIrfan@EbadullahJ@rm-openai

        Issue actions

          Make FuncTool and @function_tool decorated function callable · Issue #708 · openai/openai-agents-python