OpenAI Agents SDK 0.23: تم اختبار حجب أخطاء الأدوات
٩ أكتوبر ٢٠٢٦

ملخص: في openai-agents 0.22.3، كانت الأداة التي تثير استثناءً (exception) ترسل نص الاستثناء الكامل مرة أخرى إلى النموذج وتكتبه في التتبع (trace). أما في 0.23.1، فإن المعالج الافتراضي يعيد رسالة ثابتة بدلاً من ذلك. لقد قمت بتشغيل كلا الإصدارين باستخدام نموذج مبرمج وكلمة مرور قاعدة بيانات وهمية للتحقق.123
إن failure_error_function الخاصة بك لم تتغير ولا تزال ترى كل شيء، وكذلك الأمر بالنسبة لـ trace span التي تنتجها. وينطبق الشيء نفسه على failure_error_function=None. أحد الآثار الجانبية: بالنسبة للمدخلات الخاطئة، لم يعد النموذج يتلقى حتى الملاحظة القصيرة "Invalid JSON input".3
معالجة أخطاء أدوات OpenAI Agents SDK: الإجابة المختصرة
أداة الدالة (function tool) هي دالة Python يمكن للنموذج استدعاؤها. عندما تثير الدالة خطأً، يجب على SDK تحديد ما يراه النموذج بعد ذلك. يذكر دليل الأدوات أن failure_error_function "توفر استجابة خطأ لـ LLM في حالة تعطل استدعاء الأداة".4
في الإصدار 0.22.3، تضمنت الاستجابة الافتراضية رسالة الاستثناء. أما في 0.23.1، فهي النص الثابت "An error occurred while running the tool. Please try again." ويسجل trace span أن "Tool execution failed. Error details are redacted."3
ما ستتعلمه
- محتويات رسالة خطأ الأداة الافتراضية في 0.22.3 وفي 0.23.1
- كيفية إعادة إنتاج الفرق باستخدام نموذج مبرمج وبدون مفتاح API
- المسارات التي لا تزال تكشف عن الاستثناء الخام: المعالج المخصص و
failure_error_function=None - لماذا لا تحمل أخطاء الوسائط الخاطئة (bad-argument) أي تلميح الآن، وما هي تكلفة ذلك
- كيف تغيرت أدوات
**kwargs، ومعالج مختبر يمكنك نسخه
ما الذي تغير بين 0.22.3 و 0.23.1
يتم نشر OpenAI Agents SDK للغة Python على PyPI باسم openai-agents. تم رفع الإصدار 0.22.3 في 17 سبتمبر 2026 (UTC). الإصدار التالي على PyPI هو 0.23.1، والذي تم رفعه في 2 أكتوبر 2026 (UTC). لا يوجد إصدار 0.23.0 على PyPI.1
تم نشر الإصدار 0.23.0 على GitHub في 2 أكتوبر 2026 (UTC)، وعنوان سجل التغييرات الخاص به مؤرخ في 1 أكتوبر. تقول ملاحظات الإصدار 0.23.1 ما يعنيه ذلك للمحدثين: "المستخدمون الذين يقومون بالتحديث من 0.22.3 يتلقون تغييرات سلوك 0.23.0 بالإضافة إلى هذا الإصلاح".56
هناك تغييران في سجل تغييرات 0.23.0 مهمان هنا. تم دمج طلب السحب (Pull request) رقم 5112 في 20 سبتمبر 2026، بعد ثلاثة أيام من 0.22.3. يقول وصفه:2
الإخفاقات الافتراضية الآن تعيد رسالة ثابتة وتحجب تفاصيل الاستثناء من نطاقات الخطأ (error spans)، بما في ذلك الإلغاء المحلي للأداة والوسائط المشوهة.
طلب السحب (Pull request) رقم 5174، الذي تم دمجه في 25 سبتمبر 2026، يرفض المفاتيح الإضافية المسطحة (flat extra keys) في أدوات **kwargs غير الصارمة بدلاً من تجاهلها دون تنبيه.7
إعادة إنتاج المشكلة باستخدام نموذج مبرمج (scripted model)
ستحتاج إلى Python 3.10 أو إصدار أحدث وبيئتين افتراضيتين، واحدة لكل إصدار. ScriptedModel و function_call و assistant_message تأتي من agents.testing، وهي موجودة في كلا الإصدارين. لا يوجد مفتاح API مشارك في العملية.3
python3 -m venv v0.22.3 && ./v0.22.3/bin/pip install openai-agents==0.22.3
python3 -m venv v0.23.1 && ./v0.23.1/bin/pip install openai-agents==0.23.1
./v0.22.3/bin/python matrix.py
./v0.23.1/bin/python matrix.py
احفظ هذا الملف باسم matrix.py. كل حالة تقوم ببناء أداة، وبرمجة النموذج لاستدعائها مرة واحدة، ثم قراءة ما تم عرضه على النموذج في الجولة الثانية، أو تسجيل أن التشغيل تسبب في خطأ بدلاً من ذلك. يقوم معالج التتبع (trace processor) بجمع كل نطاق (span) مُصدّر حتى يتمكن السكريبت من البحث فيها عن كلمة المرور الوهمية.3
import asyncio, json
import importlib.metadata as md
from agents import Agent, Runner, function_tool, set_trace_processors
from agents.tracing import TracingProcessor
from agents.testing import ScriptedModel, assistant_message, function_call
SECRET = "hunter2"
class Collect(TracingProcessor):
def __init__(self): self.spans = []
def on_trace_start(self, trace): pass
def on_trace_end(self, trace): pass
def on_span_start(self, span): pass
def on_span_end(self, span): self.spans.append(span.export())
def shutdown(self): pass
def force_flush(self): pass
def shown_to_model(model):
items = model.last_call.input
return [i["output"] for i in items if isinstance(i, dict) and i.get("type") == "function_call_output"]
def lookup(account_id: str) -> str:
raise ValueError(f"connect failed: postgres://admin:{SECRET}@db.internal/prod")
def add(a: int, b: int) -> int:
return a + b
def kw(a: int, **kwargs) -> str:
return f"a={a} kwargs={kwargs}"
async def run(fn, args, **tool_opts):
col = Collect()
set_trace_processors([col])
tool = function_tool(fn, **tool_opts)
model = ScriptedModel([
[function_call(tool.name, args, call_id="c1")],
[assistant_message("done")],
])
try:
await Runner.run(Agent(name="a", model=model, tools=[tool]), "go")
seen = shown_to_model(model)[0]
except Exception as e:
seen = f"RAISED {type(e).__name__}"
in_trace = SECRET in json.dumps(col.spans, default=str)
return f"model saw: {seen!r} | secret in trace: {in_trace}"
async def main():
print("openai-agents", md.version("openai-agents"))
custom = lambda ctx, e: f"custom saw: {e}"
print("1 tool raises ", await run(lookup, {"account_id": "x"}))
print("2 custom handler ", await run(lookup, {"account_id": "x"}, failure_error_function=custom))
print("3 handler = None ", await run(lookup, {"account_id": "x"}, failure_error_function=None))
print("4 bad JSON arguments ", await run(add, '{"a": 1, "b": '))
print("5 wrong argument type ", await run(add, {"a": "one", "b": 2}))
print("6 extra field, add() ", await run(add, {"a": 1, "b": 2, "c": 3}))
print("7 **kwargs flat extra ", await run(kw, {"a": 1, "extra": "x"}, strict_mode=False))
print("8 **kwargs nested ", await run(kw, {"a": 1, "kwargs": {"extra": "x"}}, strict_mode=False))
asyncio.run(main())
النتائج: 0.22.3 مقابل 0.23.1

المخرجات في إصدار 0.22.3:
openai-agents 0.22.3
1 tool raises model saw: 'An error occurred while running the tool. Please try again. Error: connect failed: postgres://admin:hunter2@db.internal/prod' | secret in trace: True
2 custom handler model saw: 'custom saw: connect failed: postgres://admin:hunter2@db.internal/prod' | secret in trace: True
3 handler = None model saw: 'RAISED UserError' | secret in trace: True
4 bad JSON arguments model saw: 'An error occurred while running the tool. Please try again. Error: Invalid JSON input for tool add' | secret in trace: False
5 wrong argument type model saw: 'An error occurred while running the tool. Please try again. Error: Invalid JSON input for tool add' | secret in trace: False
6 extra field, add() model saw: '3' | secret in trace: False
7 **kwargs flat extra model saw: 'a=1 kwargs={}' | secret in trace: False
8 **kwargs nested model saw: "a=1 kwargs={'extra': 'x'}" | secret in trace: False
المخرجات في إصدار 0.23.1:
openai-agents 0.23.1
1 tool raises model saw: 'An error occurred while running the tool. Please try again.' | secret in trace: False
2 custom handler model saw: 'custom saw: connect failed: postgres://admin:hunter2@db.internal/prod' | secret in trace: True
3 handler = None model saw: 'RAISED UserError' | secret in trace: True
4 bad JSON arguments model saw: 'An error occurred while running the tool. Please try again.' | secret in trace: False
5 wrong argument type model saw: 'An error occurred while running the tool. Please try again.' | secret in trace: False
6 extra field, add() model saw: '3' | secret in trace: False
7 **kwargs flat extra model saw: 'An error occurred while running the tool. Please try again.' | secret in trace: False
8 **kwargs nested model saw: "a=1 kwargs={'extra': 'x'}" | secret in trace: False
لقد قمت بتشغيل السكريبت ثلاث مرات لكل إصدار وكانت المخرجات متطابقة في كل مرة.3
الرسالة الافتراضية لم تعد تحمل الاستثناء (exception)
الحالة 1 هي الحالة المهمة فيما يتعلق بالأسرار. تثير الأداة خطأ من نوع ValueError تحتوي رسالته على رابط قاعدة بيانات مع كلمة مرور. في إصدار 0.22.3، رأى النموذج رسالة الاستثناء الكاملة وكان نطاق التتبع يحتوي عليها أيضاً. أما في إصدار 0.23.1، فقد رأى النموذج الرسالة الثابتة فقط، وقرأ النطاق: "Tool execution failed. Error details are redacted."3
يمكن أن تتضمن رسائل الاستثناء من برامج تشغيل قواعد البيانات، وعملاء HTTP، وواجهات برمجة تطبيقات الملفات (file APIs) سلاسل الاتصال، أو مسارات الملفات، أو تفاصيل الطلبات. وأي شيء يراه النموذج يمكن تكراره للمستخدم، أو نسخه في استدعاء لاحق للأداة، أو تخزينه في سجل المحادثة.
استمر سلوك إصدار 0.23.1 مع إعدادات التتبع الافتراضية. يذكر دليل التتبع أنه بشكل افتراضي تكون قيمة trace_include_sensitive_data هي True، ومع ذلك ظل النطاق محجوباً (redacted) في تجربتي.83
المعالج المخصص لا يزال يرى كل شيء
الحالتان 2 و 3 لم تتغيرا. الدالة التي تمررها كـ failure_error_function تستقبل الاستثناء الأصلي، وأي شيء تعيده يذهب مباشرة إلى النموذج. في الحالة 2، نقل نص المعالج الرسالة الكاملة إلى النموذج، واحتوى التتبع على كلمة المرور أيضاً.3
تمرير failure_error_function=None يؤدي إلى إعادة إثارة الخطأ (re-raises)، كما يصف دليل الأدوات.4 تسبب التشغيل في إثارة خطأ UserError، لذا في الحالة 3 لم يرَ النموذج أي شيء على الإطلاق، واحتوى التتبع على كلمة المرور في كلا الإصدارين.3
إذا كنت قد كتبت بالفعل معالجاً يعيد str(error)، فإن الترقية لن تحل المشكلة نيابة عنك. الحجب الجديد يغطي الحالة الافتراضية فقط.
الـ span هو مسار منفصل عن نص النموذج. يوضح قسم الـ handler أدناه أن الـ handler المخصص الذي يعيد سلسلة نصية آمنة للنموذج لا يزال يترك الخطأ الخام في الـ span، إلا إذا قمت بإيقاف trace_include_sensitive_data.
هناك مفتاح تحويل آخر. ضبط OPENAI_AGENTS_DONT_LOG_TOOL_DATA=0 في الإصدار 0.23.1 جعل الـ SDK يكتب وسائط الأداة والرسالة والـ traceback في السجل المحلي. ظل النص الذي رآه النموذج والـ trace spans محجوبة في تلك العملية.3 يوثق دليل التكوين هذا المتغير ويذكر أن ضبطه على 0 "يمكن أن يكشف عن بيانات النموذج أو الأداة الخام في السجلات، ورسائل الاستثناء، وسلاسل الاستثناء، وسياقات التشخيص الأخرى." ويوصي بتفعيله "فقط في بيئة تطوير خاضعة للرقابة."9 ابقهِ مغلقاً في بيئة الإنتاج.
الوسائط الخاطئة تحصل الآن على رسالة عامة أيضاً
توضح الحالتان 4 و 5 التكلفة. في الإصدار 0.22.3، وصل كل من الـ JSON غير السليم ونوع الوسائط الخاطئ إلى النموذج على هيئة "حدث خطأ أثناء تشغيل الأداة. يرجى المحاولة مرة أخرى. الخطأ: مدخل JSON غير صالح للأداة add". هذا يشير إلى وجود خطأ في الوسائط، ولكن ليس ما هو الخطأ أو أي حقل تحديداً. استخدم الـ SDK نفس الصيغة لكلتا الحالتين. في الإصدار 0.23.1، يعود كلاهما بنفس النص العام دون ذكر السبب.3
الرسالة التي تقول فقط "يرجى المحاولة مرة أخرى" لا تعطي النموذج أي شيء ليقوم بتصحيحه. لقد استخدمت نموذجاً مبرمجاً (scripted model)، لذا لا يمكنني تحديد عدد المرات التي يتعافى فيها نموذج حقيقي، ولم أقم بقياس ذلك.
تنبيه آخر. يحتوي مصدر الإصدار 0.22.3 على فرع افتراضي ثانٍ للـ JSON غير السليم يضيف "يرجى المحاولة مرة أخرى باستخدام JSON صالح" ورسالة الـ decoder. لم يتم تفعيل ذلك في تجاربي. يوضح دليل التكوين السبب: "مع تفعيل حجب بيانات الأداة (tool-data redaction)، فإن الوسائط غير الصالحة لـ FunctionTool تثير ModelBehaviorError عاماً دون ربطه بخطأ التحقق الأساسي."9 تتبعت سلسلة أسباب الاستثناء باستخدام سكريبت قصير على كلا الإصدارين ووجدت فقط ModelBehaviorError نفسه.3 قد تتصرف مسارات الاستدعاء الأخرى بشكل مختلف.
إذا كنت تريد أن يحصل النموذج على تلميح، فاكتب handler يحدد ما يجب قوله بناءً على نوع الخطأ. يوجد واحد في قسم الـ handler أدناه.
أداة **kwargs ترفض المفاتيح الإضافية المسطحة
الأداة غير الصارمة (non-strict tool) التي تستخدم **kwargs تعلن عن كائن متداخل واحد يسمى kwargs. في الإصدار 0.22.3، النموذج الذي أرسل {"a": 1, "extra": "x"} حصل على تشغيل ناجح مع kwargs={}: تم إسقاط المفتاح الإضافي بصمت. في الإصدار 0.23.1، يفشل الاستدعاء بالخطأ العام (الحالة 7)، ويذكر الـ pull request أن المفاتيح تُرفض قبل الاستدعاء.73
يصف طلب السحب (Pull request) رقم 5174 نفس الخطأ: "قام Pydantic بتجاهل المفاتيح غير المتوقعة في المستوى الأعلى وعملت الدالة بوسطاء مفقودة."7 النموذج المتداخل {"a": 1, "kwargs": {"extra": "x"}} عمل في كلا الإصدارين (الحالة 8). أما الأداة البسيطة مثل add() فلا تزال تتجاهل أي مفتاح غير معروف في المستوى الأعلى في كلا الإصدارين (الحالة 6). طلب السحب يتعلق فقط بأدوات **kwargs.73
الأداة الصارمة (strict tool) التي تستخدم **kwargs تفشل عند تعريفها في كلا الإصدارين. في الإصدار 0.22.3 كان خطأ UserError يتعلق بـ additionalProperties. أما في الإصدار 0.23.1 فيطلب تعيين strict_mode=False أو استخدام بارامترات صريحة.3
from agents import function_tool
def kw(a: int, **kwargs) -> str:
return ""
try:
function_tool(kw)
except Exception as e:
print(type(e).__name__, e)
المخرجات في الإصدار 0.22.3، ثم في 0.23.1 (سطر واحد لكل منهما):
UserError additionalProperties should not be set for object types. This could be because you're using an older version of Pydantic, or because you configured additional properties to be allowed. If you really need this, update the function or output tool to not use a strict schema.
UserError Variadic keyword parameter `**kwargs` in function kw cannot use a strict schema. Set strict_mode=False on the function tool (or strict_json_schema=False on function_schema) and pass keyword arguments in the nested `kwargs` object, or use explicit parameters for a strict tool.
معالج فشل لما يراه النموذج
يسمح هذا المعالج لفئة استثناء واحدة بالتحدث إلى النموذج، ويعطي تلميحاً ثابتاً للوسطاء المشوهة، ويخفي كل شيء آخر عن النموذج. كما يقوم بتسجيل الخطأ الخام من جانبك، حيث يمكنك تنقيته. يقوم السكريبت بتشغيل كل حالة مرتين، مرة باستخدام trace_include_sensitive_data الافتراضي ومرة أخرى مع تعيينه على False.3
import asyncio, json, logging, sys
from agents import Agent, RunConfig, Runner, function_tool, set_trace_processors
from agents.exceptions import ModelBehaviorError
from agents.tracing import TracingProcessor
from agents.testing import ScriptedModel, assistant_message, function_call
log = logging.getLogger("tool-errors")
logging.basicConfig(level=logging.ERROR, format="server log: %(message)s", stream=sys.stdout)
class Collect(TracingProcessor):
def __init__(self): self.spans = []
def on_trace_start(self, trace): pass
def on_trace_end(self, trace): pass
def on_span_start(self, span): pass
def on_span_end(self, span): self.spans.append(span.export())
def shutdown(self): pass
def force_flush(self): pass
class SafeToolError(Exception):
"""Messages on this class are written for the model and safe to show."""
def failure_handler(ctx, error):
log.error("%s: %s", type(error).__name__, error)
if isinstance(error, SafeToolError):
return f"Tool failed: {error}"
if isinstance(error, ModelBehaviorError):
return "Your arguments did not match the tool schema. Send valid JSON with the listed fields."
return "Tool failed for an internal reason. Do not retry with the same input."
def lookup(account_id: str) -> str:
if account_id == "x":
raise SafeToolError("account x is archived, use an active id")
raise ValueError("connect failed: postgres://admin:hunter2@db.internal/prod")
async def call(args, sensitive):
col = Collect()
set_trace_processors([col])
tool = function_tool(lookup, failure_error_function=failure_handler)
model = ScriptedModel([[function_call("lookup", args, call_id="c1")], [assistant_message("done")]])
cfg = RunConfig(trace_include_sensitive_data=sensitive)
await Runner.run(Agent(name="a", model=model, tools=[tool]), "go", run_config=cfg)
seen = [i["output"] for i in model.last_call.input if isinstance(i, dict) and i.get("type") == "function_call_output"][0]
return f"model saw: {seen} | secret in trace: {'hunter2' in json.dumps(col.spans, default=str)}"
async def main():
for sensitive in (True, False):
print(f"trace_include_sensitive_data={sensitive}")
print(await call({"account_id": "x"}, sensitive))
print(await call({"account_id": "y"}, sensitive))
print(await call('{"account_id": ', sensitive))
asyncio.run(main())
المخرجات، متطابقة في الإصدارين 0.22.3 و 0.23.1:
trace_include_sensitive_data=True
server log: SafeToolError: account x is archived, use an active id
model saw: Tool failed: account x is archived, use an active id | secret in trace: False
server log: ValueError: connect failed: postgres://admin:hunter2@db.internal/prod
model saw: Tool failed for an internal reason. Do not retry with the same input. | secret in trace: True
server log: ModelBehaviorError: Invalid JSON input for tool lookup
model saw: Your arguments did not match the tool schema. Send valid JSON with the listed fields. | secret in trace: False
trace_include_sensitive_data=False
server log: SafeToolError: account x is archived, use an active id
model saw: Tool failed: account x is archived, use an active id | secret in trace: False
server log: ValueError: connect failed: postgres://admin:hunter2@db.internal/prod
model saw: Tool failed for an internal reason. Do not retry with the same input. | secret in trace: False
server log: ModelBehaviorError: Invalid JSON input for tool lookup
model saw: Your arguments did not match the tool schema. Send valid JSON with the listed fields. | secret in trace: False
يقوم المعالج بعمله بالنسبة للنموذج: فقط نص SafeToolError هو الذي مر. هناك شيئان لا يفعلهما؛ فأسطر سجل الخادم لا تزال تحتوي على كلمة المرور. وفي التشغيل الافتراضي، احتوى نطاق التتبع (trace span) على كلمة المرور في حالة ValueError في كلا الإصدارين. يسجل الإصدار 0.22.3 الاستثناء الخام في النطاق لكل معالج، بينما يقوم الإصدار 0.23.1 بحذفه فقط للمعالج الافتراضي.3 تعيين trace_include_sensitive_data=False أدى إلى إزالتها في تجربتي. يذكر دليل التتبع أن نطاقات التوليد ونطاقات الدوال تخزن المدخلات والمخرجات، وأنه يمكنك تعطيل التقاط هذه البيانات بنفس الإعداد.8 قم بتنقية أو تقييد السجل، وحدد إعداد التتبع الذي تريده.
ما لم أقم باختباره
لقد استخدمت نموذجاً مبرمجاً (scripted model)، لذا لا يوجد شيء هنا يوضح كيف يتفاعل نموذج حقيقي مع الرسالة العامة. قمت بتشغيل Python 3.13.16 على Linux مع openai 3.26.1 ولم أجرب إصدارات Python أخرى.3
لم أختبر عمليات التشغيل المتدفقة (streaming runs)، أو أدوات MCP، أو الأدوات المستضافة، أو عمليات التسليم (handoffs) أو تدفقات الموافقة. تسرد قائمة تغييرات 0.23.0 العديد من التغييرات الأخرى، من بينها تحديد نطاق الموافقة لكل وكيل، وخيارات البيئة المعزولة (sandbox)، وميزانية فحص السجل المشفر. لم أختبر أيًا منها.5 إذا كنت تستخدم الموافقات، فإن اختبار needsApproval الخاص بي على JavaScript SDK يغطي استدعاء الموافقة لهذا الـ SDK، ويغطي درس human-in-the-loop التعليمي تدفقات الموافقة في Claude Agent SDK.
قائمة مراجعة الترقية
- ابحث في أدواتك عن
failure_error_functionوعن أي معالج يعيدstr(error). - حدد أنواع الاستثناءات التي يمكن أن تصل إلى النموذج، وأعد سلسلة نصية ثابتة للبقية.
- أضف تلميحاً لـ
ModelBehaviorErrorحتى يتعلم النموذج على الأقل أن وسائطه كانت خاطئة.
**kwargs غير صارمة للموديلات التي ترسل مفاتيح إضافية في المستوى الأعلى.trace_include_sensitive_data ليتناسب مع ذلك.openai-agents قمت باختباره، وأعد تشغيل matrix.py بعد كل عملية ترقية.للاطلاع على أنماط حواجز الحماية (guardrail) الأوسع، راجع موثوقية وكلاء الذكاء الاصطناعي، وحلقات التحقق وحواجز الحماية.
الخلاصة
في الإصدار 0.22.3، كان من الممكن للأداة التي تفشل أن تضع نص الاستثناء الخاص بها أمام الموديل وفي الـ spans التي يصدرها الـ SDK. في الإصدار 0.23.1، يتوقف المعالج الافتراضي عن القيام بذلك.
تظل المعالجات المخصصة، وfailure_error_function=None، وإعدادات التتبع، وتكلفة رسالة الخطأ الخالية من التلميحات، قرارات تعود إليك. اختبرها باستخدام موديل مبرمج (scripted model) قبل الترقية.
Footnotes
-
PyPI, openai-agents, release metadata read through the PyPI JSON API on October 9, 2026: 0.22.3 uploaded 2026-09-17 and 0.23.1 uploaded 2026-10-02, with no 0.23.0 in the release list.
pip download openai-agents==0.23.0also found no matching distribution. ↩ ↩2 ↩3 -
openai/openai-agents-python, pull request #5112, "fix(tools): redact default tool failure details", merged 2026-09-20. The quoted sentence is from the description. ↩ ↩2
-
Author's measurement, October 9, 2026: Python 3.13.16 on Linux,
openai3.26.1,openai-agents0.22.3 and 0.23.1 in separate virtual environments,ScriptedModelfromagents.testing, no API key. Every script in this post was extracted from the finished article and rerun, and the output blocks match. The matrix output was identical across three runs per version. The cause-chain check mentioned above is a separate short script that is not shown, and so is the run that printed the exported span's error field to read its exact text. Statements about branches inside the default handler and the span logic come from reading the installed source fileagents/tool.pyin each version. ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8 ↩9 ↩10 ↩11 ↩12 ↩13 ↩14 ↩15 ↩16 ↩17 ↩18 ↩19 ↩20 ↩21 ↩22 ↩23 -
OpenAI Agents SDK, Tools guide, section "Handling errors in function tools". Quote and the
Nonebehavior taken on October 9, 2026 from the guide's source file,docs/tools.mdon the main branch. ↩ ↩2 -
openai/openai-agents-python GitHub releases, v0.23.0, published 2026-10-02 UTC with a changelog heading of 2026-10-01. The list includes #5112 and #5174 (bug fixes), #5144 (approval scoping), and the features #5116 (sandbox), #5118 (encrypted history scan budget) and #5135 (sandbox). ↩ ↩2
-
openai/openai-agents-python GitHub releases, v0.23.1, published 2026-10-02. The quoted sentence is from the release readiness review in the release notes, which also says PyPI had neither 0.23.0 nor 0.23.1 when the review was written. ↩ ↩2
-
openai/openai-agents-python, pull request #5174, "fix(core): reject silently discarded kwargs tool arguments", merged 2026-09-25. The quoted words are from the summary. ↩ ↩2 ↩3 ↩4
-
OpenAI Agents SDK, Tracing guide, section "Sensitive data": "By default,
trace_include_sensitive_dataisTrue." The same section says: "Thegeneration_span()stores the inputs/outputs of the LLM generation, andfunction_span()stores the inputs/outputs of function calls. These may contain sensitive data, so you can disable capturing that data via" theRunConfig.trace_include_sensitive_datasetting. Taken fromdocs/tracing.mdon the main branch on October 9, 2026. ↩ ↩2 ↩3 -
OpenAI Agents SDK, Configuration guide, section "Sensitive data in logs and diagnostics". Quotes checked on October 9, 2026 against the guide's source file,
docs/config.md, in a clone of the main branch at commit 125efa0 (2026-10-08). ↩ ↩2



