openai_agents: tool wrapper is re-applied on every turn
@alexander-alderman-webb đang làm issue này rồi.
Từ ngày 31/8/2026.
Đánh giá
Issue này chưa được đánh giá.
Mô tả
How do you use Sentry?
Sentry SaaS (sentry.io)
Version
2.68.1
Steps to Reproduce
We ran into the tool-rebuild problem that #6961 fixed. Our agent crash-looped on UserError: ToolSearchTool() requires at least one searchable Responses surface, because defer_loading came back False on every tool. Moving to 2.67.0 fixed it for us, and the switch to RunHooks in #6994 looks like the right call.
While reading that fix I noticed one thing still worth reporting in patches/tools.py. It now sets on_invoke_tool in place:
tool.on_invoke_tool = create_wrapped_invoke(tool, original_on_invoke)
get_all_tools returns the agent's own tool objects and runs once per turn, so the wrapper goes on again on each turn and the previous one stays underneath it.
That file is only wired up for openai-agents < 0.3.2, so this repro calls _get_all_tools directly with a stub standing in for the original:
import asyncio, sentry_sdk
sentry_sdk.init(dsn="https://a@b.ingest.sentry.io/1", traces_sample_rate=1.0)
from sentry_sdk.integrations.openai_agents.patches.tools import _get_all_tools
from agents import Agent, FunctionTool
async def invoke(ctx, args): return "ok"
tool = FunctionTool(
name="t", description="d",
params_json_schema={"type": "object", "properties": {}, "additionalProperties": False},
on_invoke_tool=invoke,
)
agent = Agent(name="a", tools=[tool])
async def original(a, c): return list(a.tools) # stands in for get_all_tools
async def main():
for turn in range(1, 6):
await _get_all_tools(original, agent, None)
f, depth = agent.tools[0].on_invoke_tool, 0
while hasattr(f, "__wrapped__"):
f, depth = f.__wrapped__, depth + 1
print(f"after turn {turn}: wrapper depth = {depth}")
asyncio.run(main())
Expected Result
A tool gets wrapped once, however many turns a run takes, and one tool call produces one gen_ai.execute_tool span.
Actual Result
after turn 1: wrapper depth = 1
after turn 2: wrapper depth = 2
after turn 3: wrapper depth = 3
after turn 4: wrapper depth = 4
after turn 5: wrapper depth = 5
A tool call on turn N opens N nested gen_ai.execute_tool spans, and the wrapping stays on the caller's Agent after the run.
_patch_run_hooks in patches/runner.py already guards against this with _sentry_is_patched. The same flag on the tool would cover it.
Tested on Python 3.13 with openai-agents 0.17.5.
- Ngôn ngữ chính
- Python
- Star
- 2.2k
- Fork
- 672
- Merge trung bình
- 22 giờ 47 phút
- Pull request đã merge (30 ngày)
- 224
Hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của getsentry/sentry-python
-
Python
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 65/100
getsentry/sentry-python#7569 · 1 bình luận ·
-
Python
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 85/100
getsentry/sentry-python#7568 · 2 bình luận ·
-
Python
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 65/100
getsentry/sentry-python#7567 · 1 bình luận ·
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
getsentry/sentry-python#7543 · 2 bình luận · 1 người được giao ·
-
Python
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100
getsentry/sentry-python#6992 · 1 bình luận ·
Tất cả issue của getsentry/sentry-python
Issue tương tự
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 75/100
anthropics/skills#1811 · 1 bình luận ·
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 75/100
speaches-ai/speaches#678 ·
-
bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 75/100
datalayer/mcp-compose#42 ·
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 75/100
conda-forge/spacy-feedstock#177 ·
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 70/100
UKGovernmentBEIS/inspect_evals#2523 ·