Skip to content

fix(core): keep tool output custom_data structured in RunState serialization - #5015

Open
betacatsling wants to merge 1 commit into
openai:mainfrom
betacatsling:fix/runstate-tool-output-custom-data
Open

betacatsling wants to merge 1 commit into
openai:mainfrom
betacatsling:fix/runstate-tool-output-custom-data

Conversation

@betacatsling

Copy link
Copy Markdown

Summary

ToolCallOutputItem.custom_data is SDK-only metadata that persists through RunState, but _serialize_item passed it directly to _ensure_json_compatible, which uses json.dumps(default=str) and degrades Pydantic models and dataclasses to repr strings such as "value=0.9 label='high'". The sibling output field already routes through _serialize_output_value first. This change applies the same pipeline to custom_data so structured payloads round-trip as plain JSON data on save and restore.

The custom_data_extractor contract enforced by normalize_custom_data is unchanged; this only makes RunState persistence faithful for values set directly on the public field, consistent with how output is handled.

Found during a serialization audit; no existing issue covers this field.

Test plan

New regression test test_tool_output_custom_data_preserves_structured_values fails before the fix ({'score': "value=0.9 label='high'"} repr strings) and passes after.

Commands and results:

.venv/bin/python ../repro/repro_custom_data.py
# before: AssertionError: custom_data lost its structured values during persistence
# after:  serialized/restored custom_data contain plain dict values

.venv/bin/python -m pytest tests/test_run_state.py tests/test_run_state_compatibility_corpus.py tests/test_run_state_agent_identity.py tests/test_run_state_pending_input.py -q
# 620 passed

.venv/bin/ruff format --check src/agents/run_state.py tests/test_run_state.py
# 2 files already formatted

.venv/bin/ruff check src/agents/run_state.py tests/test_run_state.py
# All checks passed!

.venv/bin/mypy src/agents/run_state.py
# Success: no issues found in 1 source file

The full verification script (.agents/skills/code-change-verification/scripts/run.sh) could not run in this environment because dev dependency evdev fails to build (-pthread compile error). The focused test suites covering the changed module all pass (620 tests); the limitation is unrelated to this change.

Issue number

Closes #5014

Checks

  • I've added new tests, if relevant
  • I've run .agents/skills/code-change-verification/scripts/run.sh
  • I've confirmed all verification steps pass
  • If using Codex, I've run /review before submitting this PR

…ization

ToolCallOutputItem.custom_data is SDK-only metadata that persists through
RunState. _serialize_item passed it straight to _ensure_json_compatible,
which uses json.dumps(default=str) and degrades Pydantic models and
dataclasses to repr strings. Route it through _serialize_output_value
first, the same pipeline already used for the item's output field, so
structured payloads persist as plain JSON data on save and restore.
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.

Issue draft (not filed): RunState stringifies structured ToolCallOutputItem.custom_data during persistence

1 participant