feat(agents): stage files and download turn artifacts - #4009
Conversation
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
Security findingsAdvisory findings (1)
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
Castiron custom codeMixed files: 49 → 51 2 newly customized · 0 customizations removed · 0 existing customizations changed · 0 generated baselines changed Compared
49 existing customizations unchanged
9 more in the full report. A changed generated baseline means this report cannot reliably identify which handwritten lines changed. Inspect the custom-code diffDownload the exact patch produced by this run (requires repository access): gh run download 36931092923 --repo openai/openai-python \
--name castiron-custom-code-36931092923-1 --dir /tmp/castiron-custom-code-36931092923-1
git apply --stat /tmp/castiron-custom-code-36931092923-1/custom-code.patch
cat /tmp/castiron-custom-code-36931092923-1/custom-code.patchOr reproduce it from an SDK checkout containing the vendored reporter: git fetch --no-tags origin a91d779cb5e725b47909333c6a3d9fe795e93439 e02dd44da92256fb2c9180bf3c56004d23d42ce1
python3 scripts/castiron/custom_code_report.py report \
--base a91d779cb5e725b47909333c6a3d9fe795e93439 \
--head e02dd44da92256fb2c9180bf3c56004d23d42ce1 --fetch --require-head-hash --public \
--out /tmp/castiron-custom-code-e02dd44da922
cat /tmp/castiron-custom-code-e02dd44da922/custom-code.patchThis is the current full custom patch for mixed files, not an attribution of only the handwritten lines changed by this PR. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9479b8d6fc
ℹ️ 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".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b989135267
ℹ️ 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".
There was a problem hiding this comment.
🛡️ Codex Security Review · Automatically triggered
Here are some automated security review suggestions for this pull request.
Reviewed commit: b989135267
ℹ️ About Codex security reviews in GitHub
This is an experimental Codex feature. Security reviews are triggered when:
- You comment "@codex security review"
- A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review
Once complete, Codex will leave suggestions, or a comment if no findings are found.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f0323f2a61
ℹ️ 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".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5e3512acbf
ℹ️ 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".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 187b30fe74
ℹ️ 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".
|
@codex review pls |
🛡️ Codex Security Review · Automatically triggeredSecurity review completed. No security issues were found in this pull request. Reviewed commit: Only the user who started this review can view the report in Codex. ℹ️ About Codex security reviews in GitHubThis is an experimental Codex feature. Security reviews are triggered when:
Once complete, Codex will leave suggestions, or a comment if no findings are found. |
|
Codex Review: Didn't find any major issues. Delightful! Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
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". |
65812a9 to
1c2b129
Compare
527e121 to
4a0ce8f
Compare
0b85107 to
f5e68d3
Compare
4a0ce8f to
1e5f718
Compare
## Summary
Bind a Pydantic output model to the Agents request and its completed
result, so applications can use a typed answer without maintaining
separate schema and parsing code.
Before:
```python
with client.beta.agents.sessions.create(
agent={"model": MODEL, "text": {"format": {
"type": "json_schema", "schema": schema,
}}},
environment={"type": "none"}, input=QUESTION, stream=True,
) as stream:
result = stream.get_final_result()
report = Report.model_validate_json(result.output_text)
```
After:
```python
with client.beta.agents.sessions.create(
agent={"model": MODEL}, environment={"type": "none"},
input=QUESTION, stream=True, output_type=Report,
) as stream:
result = stream.get_final_result()
report = result.output_parsed
```
The same `output_type` works on follow-up streams as a local parser for
an already-configured session. `output_parsed` returns the first parsed
final text part; all final text parts are validated. Raw output remains
available; parsing failures expose the completed result through
`AgentOutputParseError.result`. Sync and async helpers share the
existing Pydantic schema normalization and result collection.
Schema conversion follows the existing Responses helper; API errors
report unsupported schema features. Typed tools and outputs can reuse
the same model without output normalization changing its tool argument
schema.
### Stack
- #4004 (merged
prerequisite)
- #4007 👈 this PR
- #4008
- #4009
1e5f718 to
74be3ea
Compare
f5e68d3 to
f16973a
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 74be3ea165
ℹ️ 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".
|
@codex review pls |
|
@codex review pls |
|
@codex review pls |
|
@codex review pls |
🛡️ Codex Security Review · Automatically triggeredSecurity review completed. No security issues were found in this pull request. Reviewed commit: Only the user who started this review can view the report in Codex. ℹ️ About Codex security reviews in GitHubThis is an experimental Codex feature. Security reviews are triggered when:
Once complete, Codex will leave suggestions, or a comment if no findings are found. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b8653b43fc
ℹ️ 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".
jbeckwith-oai
left a comment
There was a problem hiding this comment.
Reviewed 4e2b103abc35f9606667bb5af2b3d96978c487ed, including all eight changed files and the destination-preflight, native-glob, and per-file async buffering follow-ups. No remaining actionable findings.
The ancestor-set collision check validates destinations before opening/uploading files while preserving input order. Native Path.glob selection avoids walking unrelated subtrees and retains selected-path/symlink checks. The async path now snapshots one file per upload, verifies its preflight identity, closes worker-owned handles even on cancellation, and retains successful upload IDs on a later failure. Result artifact lookup remains scoped to the exact session, turn, and published path, with explicit caller ownership of cleanup and output destinations.
Validation was source-only: implementation, supporting code, regression tests, and prior discussion. I did not run local tests, builds, live API calls, or an independent security scan. The refreshed current-head hosted CI is still queued; this approval does not claim a green full matrix.
|
@codex review pls |
🛡️ Codex Security Review · Automatically triggeredSecurity review completed. No security issues were found in this pull request. Reviewed commit: Only the user who started this review can view the report in Codex. ℹ️ About Codex security reviews in GitHubThis is an experimental Codex feature. Security reviews are triggered when:
Once complete, Codex will leave suggestions, or a comment if no findings are found. |
|
Codex Review: Didn't find any major issues. Hooray! Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
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". |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d7b99b163e
ℹ️ 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".
| def prepare(resource: Files, files: Mapping[str, str | PathLike[str]], options: _RequestOptions) -> PreparedAgentFiles: | ||
| with ExitStack() as stack: | ||
| selected = _prepare_selection(files, options, resource._client.default_headers, stack) | ||
| prepared = PreparedAgentFiles() | ||
| try: |
There was a problem hiding this comment.
Preserve upload ownership while closing source handles
When synchronous prepare() has uploaded one or more path-backed files and ExitStack.__exit__ is interrupted (for example by KeyboardInterrupt) or a handle close raises, both exception handlers have already been exited, so the exception carries no prepared state even though persistent uploads now require cleanup. Fresh evidence beyond the earlier interruption fix is that the outer with ExitStack() remains outside the protected try; include context-exit failures in the ownership-preservation path.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e02dd44da9
ℹ️ 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".
| with _upload_content(file) as content: | ||
| uploaded = resource._client.files.create(file=content, purpose="user_data", **options) |
There was a problem hiding this comment.
Preserve the upload ID when closing the source fails
For a path-backed synchronous upload(), the Files API request can succeed and assign uploaded, but an exception or KeyboardInterrupt while _upload_content closes its handle exits this with before reaching the ownership-preserving handlers below. The persistent upload is then left behind while the propagated exception exposes no uploaded_file_id; include context-exit failures in the same ownership-preservation path.
Useful? React with 👍 / 👎.
Automated Release PR --- ## [3.23.0](openai/openai-python@v3.22.1...v3.23.0) (2026-10-01) ### Features * **agents:** [1/n] return typed answers from session streams ([openai#4007](openai#4007)) ([10f8816](openai@10f8816)) * **agents:** stage files and download turn artifacts ([openai#4009](openai#4009)) ([4fc2438](openai@4fc2438)) * **api:** Add session traces and Realtime translations ([openai#4001](openai#4001)) ([138e3d1](openai@138e3d1)) * **beta:** expose typed application actions as agent tools ([openai#4006](openai#4006)) ([f219c55](openai@f219c55)) * collect final output from beta Agents streams ([157ac4c](openai@157ac4c)) ### Bug Fixes * **api:** allow original image detail in Chat Completions ([openai#4005](openai#4005)) ([8a136c2](openai@8a136c2)) * **api:** correct the eval run cancellation endpoint ([openai#4003](openai#4003)) ([28c5c9a](openai@28c5c9a)) * **api:** retain WebSocket endpoint paths and query parameters ([openai#3999](openai#3999)) ([7f203fd](openai@7f203fd)) * keep Castiron budget results valid when main advances ([openai#4012](openai#4012)) ([73f189b](openai@73f189b)) * **responses:** avoid replaying uncertain typed sends on reconnect ([openai#4011](openai#4011)) ([1dbbf61](openai@1dbbf61)) * **responses:** respect send queue limits during reconnect ([openai#4000](openai#4000)) ([50f95ac](openai@50f95ac)) * use monotonic clock for file processing timeout ([openai#3748](openai#3748)) ([58aca1d](openai@58aca1d)) ### Chores * **api:** retain WebRTC Live session transport types ([openai#4002](openai#4002)) ([5c9ace9](openai@5c9ace9)) * **deps-dev:** bump pyright from 1.1.413 to 1.1.414 ([openai#3902](openai#3902)) ([a91d779](openai@a91d779)) * **deps:** bump astral-sh/setup-uv from 10.0.1 to 10.1.0 ([openai#3976](openai#3976)) ([f15f43c](openai@f15f43c)) * **deps:** bump CodeQL actions to 4.38.1 ([openai#3974](openai#3974)) ([fb70d66](openai@fb70d66)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). Co-authored-by: openai-sdks[bot] <284451331+openai-sdks[bot]@users.noreply.github.com>
Summary
Stage selected local files and read an artifact from the exact completed turn, either in memory or streamed to a local path. The helpers keep upload IDs available for explicit cleanup and stream downloads to a caller-chosen path.
Before:
After:
prepare_directory(..., include=[...])selects a directory snapshot;files.upload(...)uploads and stages one file in an existing environment. Sync and async helpers live under the beta Agents namespace. They preflight selected files before uploading, preserve partial upload ownership on errors, and detect missing or ambiguous artifacts across all pages.Local path selection is intended for static application-owned files and stable directories; it is not a filesystem sandbox for untrusted paths or hostile local writers.
This PR now targets
maindirectly. Reattachment/result recovery is deferred: a silent attachment cannot reliably distinguish pending work from an already-completed turn, so these helpers do not depend on SDK-side recovery heuristics.Stack