Open
Description
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.
Metadata
Metadata
Assignees
Labels
Type
Projects
Milestone
Relationships
Development
No branches or pull requests
Activity
EbadullahJ commentedon May 17, 2025
When you use the
@function_tool
decorator, it wraps your function in aFuncTool
object that is not directly callable—it's designed to be executed by an LLM or agent, not manually by you. That’s why callingadd(1, 2)
raises aTypeError: 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 usingadd.__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.AreebaxIrfan commentedon May 17, 2025
@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.
chiehmin-wei commentedon May 18, 2025
chiehmin-wei commentedon May 18, 2025
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 commentedon May 19, 2025
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 commentedon May 20, 2025
Yes I think that would work.
Wondering if there's anyway to unit test the wrapped function though.
rm-openai commentedon May 20, 2025
Yeah you can do something like this:
https://github.com/openai/openai-agents-python/blob/main/tests/test_function_tool_decorator.py#L42