Skip to content

Commit 1c0c426

Browse files
committed
Fix function_tool method detection
1 parent 0477032 commit 1c0c426

2 files changed

Lines changed: 49 additions & 1 deletion

File tree

src/agents/tool.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1841,7 +1841,11 @@ def function_tool(
18411841

18421842
def _is_instance_method_tool(the_func: ToolFunction[...]) -> bool:
18431843
parameters = tuple(inspect.signature(the_func).parameters.values())
1844-
return bool(parameters) and parameters[0].name == "self"
1844+
if not parameters:
1845+
return False
1846+
1847+
parent_name = the_func.__qualname__.rsplit(".", 1)[0]
1848+
return "." in the_func.__qualname__ and not parent_name.endswith("<locals>")
18451849

18461850
def _create_function_tool(
18471851
the_func: ToolFunction[...],

tests/test_function_tool.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,50 @@ def lookup(self, account_id: str) -> str:
180180
assert result == "acct:123"
181181

182182

183+
@pytest.mark.asyncio
184+
async def test_instance_method_function_tool_binds_non_self_receiver_name():
185+
class AccountTools:
186+
def __init__(self, prefix: str) -> None:
187+
self.prefix = prefix
188+
189+
@function_tool
190+
def lookup(this, account_id: str) -> str:
191+
"""Look up an account."""
192+
return f"{this.prefix}:{account_id}"
193+
194+
tools = AccountTools("acct")
195+
tool = tools.lookup
196+
197+
assert "this" not in tool.params_json_schema["properties"]
198+
assert "account_id" in tool.params_json_schema["properties"]
199+
200+
result = await tool.on_invoke_tool(
201+
ToolContext(None, tool_name=tool.name, tool_call_id="1", tool_arguments=""),
202+
'{"account_id": "123"}',
203+
)
204+
205+
assert result == "acct:123"
206+
207+
208+
@pytest.mark.asyncio
209+
async def test_function_tool_does_not_treat_self_named_argument_as_method():
210+
def lookup(self: str, account_id: str) -> str:
211+
"""Look up an account."""
212+
return f"{self}:{account_id}"
213+
214+
tool = function_tool(lookup)
215+
216+
assert "self" in tool.params_json_schema["properties"]
217+
assert "account_id" in tool.params_json_schema["properties"]
218+
219+
result = await tool.on_invoke_tool(
220+
ToolContext(None, tool_name=tool.name, tool_call_id="1", tool_arguments=""),
221+
'{"self": "acct", "account_id": "123"}',
222+
)
223+
224+
assert result == "acct:123"
225+
226+
183227
@pytest.mark.asyncio
184228
async def test_instance_method_function_tool_supports_context_after_self():
185229
class AccountTools:

0 commit comments

Comments
 (0)