feat(tools): support @function_tool on class instance methods (fixes #94)#2879
Draft
m1lestones wants to merge 1 commit intoopenai:mainfrom
Draft
feat(tools): support @function_tool on class instance methods (fixes #94)#2879m1lestones wants to merge 1 commit intoopenai:mainfrom
m1lestones wants to merge 1 commit intoopenai:mainfrom
Conversation
…criptor protocol Fixes openai#94. Decorating a class method with @function_tool now works correctly: - `function_schema()` detects an unannotated leading `self` or `cls` parameter and sets `skips_receiver=True`, stripping the receiver from both the JSON schema and the stored signature so the LLM never sees it and `to_call_args()` never tries to populate it from model output. - `FunctionTool` gains a `__get__` descriptor method. Accessing a method tool on a class instance (e.g. `instance.my_tool`) returns a bound copy whose invoker prepends the instance as the first argument, so the underlying method receives the correct `self`. Accessing via the class returns the unbound tool. - A `_make_impl(receiver)` factory is stored on method tools; `__get__` calls it with the instance and wires the result into the copied tool's invoker. - A `RunContextWrapper`/`ToolContext` parameter immediately after `self`/`cls` is handled correctly (`takes_context=True`), as is the case where context is in the wrong position (still raises `UserError`). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Member
|
Thanks for working on this. I don't think we should merge this as-is. The main issue is that the implementation is not robust enough for a core tool abstraction change:
Also, we're currently working on a different priority, so we may not merge large changes even if they look good. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This implements the method tool support requested in #94 — the previous attempt (#2734) was closed after Codex flagged implementation issues; this PR addresses all of them.
What changed
function_schema.pyFuncSchemagains askips_receiver: boolfieldfunction_schema()detects an unannotated leadingselforclsand strips it from the JSON schema and stored signature — the LLM never sees it, andto_call_args()never tries to populate it from model outputRunContextWrapper/ToolContextimmediately afterself/clsis handled correctly (takes_context=True); wrong position still raisesUserErrortool.pyFunctionToolgains a__get__descriptor methodinstance.my_tool) returns a bound copy whose invoker prepends the instance as the receiverIssues from #2734 — all fixed
UserErrorto_call_args()includesselfin stored signaturesigbefore buildingFuncSchematakes_contextinstead ofskips_receiverskips_receiverflag controls receiver stripping independently__get__descriptor binds the receiver at instance access timeself/clsUsage
Test plan
tests/test_method_tool.pycovering schema stripping, descriptor binding, sync/async methods, context params, wrong-position context error, and@function_tool(...)with argumentsmake formatandmake lintclean🤖 Generated with Claude Code