Fix(tracing): prevent CallDeferred/ApprovalRequired from marking tool spans as errors

Merged
JA
7mo ago
+353-14

Fixes #4530.

CallDeferred and ApprovalRequired are control-flow signals for deferred/human-in-the-loop patterns, not actual errors. Currently they propagate through tracer.start_as_current_span and OTel's default behavior marks the span as ERROR with an exception event — showing misleading red spans in Logfire.

Changes:

  • Disable automatic exception recording on tool spans (record_exception=False, set_status_on_exception=False) and handle all exceptions manually

  • Catch CallDeferred/ApprovalRequired and set span status to OK on version 5+, preserving ERROR on v1-4 for backward compat

  • Record pydantic_ai.tool.deferral.name and pydantic_ai.tool.deferral.metadata as span attributes on all versions (attribute names via InstrumentationNames as suggested by @alexmojaki)

  • Add version 5 to InstrumentationSettings

  • Closes #4530

Pre-Review Checklist

  • No breaking changes in accordance with the version policy.
  • Linting and type checking pass per make format and make typecheck.

Pre-Merge Checklist

  • New tests for any fix or new behavior, maintaining 100% coverage.
  • Updated documentation for new features and behaviors, including docstrings for API docs.