fix(items): strip created_by when replaying RunItems as input - #4568
fix(items): strip created_by when replaying RunItems as input#4568hsusul wants to merge 1 commit into
Conversation
ModelResponse.to_input_items already dropped output-only created_by, but RunItem.to_input_item still forwarded it on function calls and tool outputs used for sessions and to_input_list.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0c24229502
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if isinstance(outcome, dict): | ||
| if outcome.get("type") == "exit": | ||
| entry["outcome"] = outcome | ||
| payload.pop("created_by", None) |
There was a problem hiding this comment.
Strip nested shell ownership metadata too
When a ToolCallOutputItem is constructed from an unsanitized dictionary-form shell_call_output, this removes only the top-level created_by; each entry under output can also contain created_by, so to_input_item() still returns a payload the Responses API rejects. The shared _output_item_to_input_item() path already rebuilds these chunks without that field, so apply the same nested sanitization here while retaining the shell-specific field removal.
AGENTS.md reference: AGENTS.md:L93-L93
Useful? React with 👍 / 👎.
seratch
left a comment
There was a problem hiding this comment.
Thanks for addressing the RunItem replay path. The overall direction is right, but one dict-backed path still retains output-only metadata.
I reproduced this on the current head with a ToolCallOutputItem whose raw_item is a shell_call_output mapping. to_input_item() removes the top-level created_by, but output[*].created_by remains in the replayed payload because this branch returns its shallow-copied payload directly and bypasses the nested cleanup in _output_item_to_input_item().
Please keep the existing dict-specific cleanup for status, shell_output, and provider_data, then route the cleaned payload through the shared output-item sanitizer. Please also add a regression test covering a dict-backed ToolCallOutputItem and asserting that:
- both the top-level and nested
created_byfields are removed; - the existing shell-output cleanup is preserved; and
- the original
raw_item, including its nested chunk mapping, is not mutated.
Once that case is covered, this should be ready.
Summary
This pull request fixes a gap left by #4308:
ModelResponse.to_input_items()already strips output-onlycreated_bybefore Responses replay, but public RunItem continuation still leaked it.RunItem.to_input_item()dumped function-call and tool-output payloads withcreated_byintact. That same conversion feedsrun_item_to_input_item(), session persistence, andRunResult.to_input_list(), so a later Responses request can include a field that is not part of the input schema.The base converter now routes through
_output_item_to_input_item(), and the dict path onToolCallOutputItempopscreated_byfrom the copied payload without mutatingraw_item.Test plan
ToolCallItem.to_input_item,ToolCallOutputItem.to_input_item, andrun_item_to_input_itemon function calls/outputs that carrycreated_byuv run pytest tests/test_items_helpers.py tests/test_run_internal_items.pymake format,make lint,make typecheckmake tests— one pre-existing local failure on this host, unrelated to this change:tests/sandbox/test_run_cwd.py::test_python_skill_uses_absolute_root_from_nested_workdir(WorkspaceReadNotFoundErrorfortasks/task-a/nested/output.txt). The same failure occurs on unpatchedupstream/main.Issue number
N/A — small fix, no existing issue.
Checks
.agents/skills/code-change-verification/scripts/run.sh/reviewbefore submitting this PR