Skip to content

Fix openai @function_tool tools crashing under default spawn start method - #451

Merged
kowser-orkes merged 2 commits into
mainfrom
fix/openai-agents-function-tool-spawn-safety
Jul 28, 2026
Merged

Fix openai @function_tool tools crashing under default spawn start method#451
kowser-orkes merged 2 commits into
mainfrom
fix/openai-agents-function-tool-spawn-safety

Conversation

@kowser-orkes

Copy link
Copy Markdown
Contributor

Pull Request type

  • Bugfix
  • Feature
  • Refactoring (no functional changes, no api changes)
  • Build related changes
  • WHOSUSING.md
  • Other (please describe):

NOTE: Please remember to run ./gradlew spotlessApply to fix any format violations.

Changes in this PR

  • agents.function_tool (the real openai-agents SDK decorator) rebinds a tool function's
    module-level name to a FunctionTool dataclass instance with no .func/.coroutine/
    __wrapped__ — the existing container-attr hop (added in e714961f for langchain's
    StructuredTool) doesn't match it. FunctionRef.of fell through to unsafe fn_direct
    transport, which crashed the registration-time pickle probe with SpawnSafetyError, even
    though the tool function was correctly defined at module level.
  • Repro: examples/agents/openai/02_function_tools.py, run as shipped against a live
    AI-enabled Conductor server under default spawn — crashed before any LLM call.
  • Fix: FunctionRef.of gets a new fallback that reuses serializer.py's existing generic,
    recursive attribute+closure walk (_find_embedded_function), relocated into
    _worker_entries.py alongside _extract_from_closure so parent-side discovery and
    child-side reconstruction share one implementation and can't drift apart. No
    openai-agents-specific attribute path is hardcoded.

Issue #448

Alternatives considered

  • A named-attribute allowlist (_CLOSURE_CONTAINER_ATTRS = ("on_invoke_tool",)) calling the
    closure-walk directly on on_invoke_tool — the original design. Doesn't work: on_invoke_tool
    has no __closure__ (it's an instance, not a function), and hardcoding the next attribute
    hop (_invoke_tool_impl) would pin to a double-underscore-private name that could rename in
    any openai-agents point release.
  • Duplicating openai-agents-specific extraction knowledge inside FunctionRef instead of
    reusing serializer.py's existing walk — rejected to avoid two independent implementations
    that could silently diverge.

Kowser added 2 commits July 28, 2026 11:14
- FunctionTool has no .func/.coroutine/__wrapped__ (unlike langchain's
  StructuredTool, e714961) — FunctionRef.of fell back to unsafe fn_direct,
  crashing the registration-time pickle probe.
- Relocates _find_embedded_function from serializer.py into
  _worker_entries.py, alongside _extract_from_closure (prior commit) — one
  shared walk for parent-side discovery and FunctionRef's
  verification/reconstruction, can't drift apart.
- No __wrapped__ fallback needed on the deep-extract match (unlike
  _CONTAINER_ATTRS): fn is always _find_embedded_function's own prior
  return value, so identity always matches.
@kowser-orkes
kowser-orkes requested review from bradyyie and v1r3n July 28, 2026 18:17
@codecov

codecov Bot commented Jul 28, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 77.08333% with 11 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/conductor/ai/agents/runtime/_worker_entries.py 77.08% 11 Missing ⚠️
Files with missing lines Coverage Δ
src/conductor/ai/agents/frameworks/serializer.py 29.88% <ø> (+4.52%) ⬆️
src/conductor/ai/agents/runtime/_worker_entries.py 68.05% <77.08%> (+0.84%) ⬆️

... and 58 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@kowser-orkes
kowser-orkes merged commit e924724 into main Jul 28, 2026
11 of 12 checks passed
@kowser-orkes
kowser-orkes deleted the fix/openai-agents-function-tool-spawn-safety branch July 28, 2026 19:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants