Skip to content

.NET: Add container file download extension for Code Interpreter cfile_ IDs#5014

Open
chetantoshniwal wants to merge 2 commits intomicrosoft:mainfrom
chetantoshniwal:agent/fix-3081-1
Open

.NET: Add container file download extension for Code Interpreter cfile_ IDs#5014
chetantoshniwal wants to merge 2 commits intomicrosoft:mainfrom
chetantoshniwal:agent/fix-3081-1

Conversation

@chetantoshniwal
Copy link
Copy Markdown
Contributor

Motivation and Context

Azure OpenAI Responses API Code Interpreter generates files with cfile_ IDs that live inside containers (cntr_ IDs). The standard Files API (GetOpenAIFileClient) cannot download these container-scoped files, leaving users unable to retrieve Code Interpreter output.

Fixes #3081

Description

The root cause is that container files require the Containers API (GetContainerClient) rather than the Files API. This change adds a new OpenAIClientContainerFileExtensions class with a DownloadContainerFileAsync extension method on OpenAIClient that routes downloads through GetContainerClient().DownloadContainerFileAsync(containerId, fileId). Unit tests validate argument guard behavior for null, empty, and whitespace inputs on both containerId and fileId parameters.

Contribution Checklist

  • The code builds clean without any errors or warnings
  • The PR follows the Contribution Guidelines
  • All unit tests pass, and I have added new tests where possible
  • Is this a breaking change? If yes, add "[BREAKING]" prefix to the title of the PR.

Note: PR autogenerated by chetantoshniwal's agent

…microsoft#3081)

Add OpenAIClientContainerFileExtensions with DownloadContainerFileAsync
extension method on OpenAIClient. Files generated by Code Interpreter
have cfile_ prefixed IDs and reside in containers, requiring the
Containers API instead of the standard Files API. This extension
provides a discoverable way to download these container-scoped files.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

@chetantoshniwal chetantoshniwal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated Code Review

Reviewers: 4 | Confidence: 86%

✓ Correctness

The PR adds a thin extension method on OpenAIClient to download container files, plus comprehensive input-validation unit tests. The implementation is clean: argument guards use the shared Throw helper consistently, the CancellationToken is forwarded correctly, the namespace follows existing conventions (OpenAI extensions live in the OpenAI namespace), and the [Experimental] attribute matches other extension classes. The tests correctly expect ArgumentNullException for null inputs and ArgumentException for empty/whitespace, matching the Throw.IfNullOrWhitespace behavior. No correctness issues found.

✓ Security Reliability

This PR adds a clean extension method for downloading OpenAI container files, with proper input validation via the established Throw helpers, correct CancellationToken propagation, and ConfigureAwait(false) for library code. The method follows the same patterns used by other extension methods in the project (e.g., OpenAIResponseClientExtensions). Tests cover all guard-clause branches. No security or reliability concerns were identified — there are no injection risks, resource leaks, secrets, or unhandled failure modes.

✗ Test Coverage

The test file thoroughly covers all input-validation guard clauses (null, empty, and whitespace for both containerId and fileId, plus null client), which is good. However, there is no happy-path test verifying that when valid arguments are supplied, the method actually delegates to client.GetContainerClient().DownloadContainerFileAsync(...) with the correct arguments and propagates the CancellationToken. The tests only exercise the three Throw.* lines (lines 39-41 of the production code) and never reach the actual business logic on lines 43-44. This is a significant gap: without a happy-path test, a regression that breaks the delegation or drops the CancellationToken would go undetected.

✓ Design Approach

The extension follows the established pattern in this codebase (thin validated wrapper over an SDK method, placed in the SDK's namespace) and the implementation itself is sound. The only meaningful gap is the complete absence of a happy-path test: all seven tests exercise pre-condition validation that fires before the method reaches GetContainerClient().DownloadContainerFileAsync(), so the actual delegation logic—the one line of real behaviour—is entirely untested. If the underlying SDK method is mockable or the OpenAIClient subclass approach already used in the test file can be extended to stub the container client, a success-case test should be added.

Flagged Issues

  • No happy-path test: the core behavior of the method — obtaining a ContainerClient and calling DownloadContainerFileAsync with the correct containerId, fileId, and CancellationToken (lines 43-44) — is completely untested. All seven tests only cover argument-validation guard clauses.

Suggestions

  • Add a happy-path test that extends the existing TestOpenAIClient stub (similar to the pattern in OpenAIAssistantClientExtensionsTests) to intercept GetContainerClient().DownloadContainerFileAsync, then verify that the extension correctly delegates with the expected containerId, fileId, and CancellationToken and returns the expected ClientResult.
  • Consider adding a test that verifies CancellationToken propagation — e.g., passing a pre-cancelled token and asserting it is forwarded to the underlying SDK call.

Automated review by chetantoshniwal's agents

public TestOpenAIClient()
{
}
}
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The TestOpenAIClient stub is only sufficient for guard-clause tests. To test the actual delegation behavior (lines 43-44 of the production code), extend this type or add a separate test fixture that overides GetContainerClient() to capture and assert that the correct containerId, fileId, and CancellationToken are forwarded to DownloadContainerFileAsync.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a .NET extension on OpenAIClient to download Code Interpreter container-scoped files (cfile_ within cntr_) via the Containers API, addressing the inability to download these files through the standard Files API.

Changes:

  • Added OpenAIClientContainerFileExtensions.DownloadContainerFileAsync to route downloads through GetContainerClient().
  • Added unit tests covering null/empty/whitespace argument guards for client, containerId, and fileId.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 5 comments.

File Description
dotnet/src/Microsoft.Agents.AI.OpenAI/Extensions/OpenAIClientContainerFileExtensions.cs New OpenAIClient extension method to download container-scoped cfile_ outputs via Containers API.
dotnet/tests/Microsoft.Agents.AI.OpenAI.UnitTests/Extensions/OpenAIClientContainerFileExtensionsTests.cs New unit tests validating argument guard behavior for the new extension method.

Comment on lines +39 to +45
Throw.IfNull(client);
Throw.IfNullOrWhitespace(containerId);
Throw.IfNullOrWhitespace(fileId);

var containerClient = client.GetContainerClient();
return await containerClient.DownloadContainerFileAsync(containerId, fileId, cancellationToken).ConfigureAwait(false);
}
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Current tests only validate argument guards; there’s no coverage that a valid call actually routes through GetContainerClient().DownloadContainerFileAsync(...) (the core behavior this PR adds). Consider adding a positive-path test using a custom transport / pipeline to assert the request goes to the Containers API endpoint and succeeds (without requiring real network calls).

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot apply changes based on this feedback

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

.NET: Cannot download Code Interpreter generated files using cfile_ IDs from Azure OpenAI Responses API

3 participants