Skip to content

[5417] fix(api): declare mount binary responses and regenerate the Fern client - #5518

Open
mmabrouk wants to merge 1 commit into
mainfrom
chore/mounts-binary-openapi-fern-regen
Open

[5417] fix(api): declare mount binary responses and regenerate the Fern client#5518
mmabrouk wants to merge 1 commit into
mainfrom
chore/mounts-binary-openapi-fern-regen

Conversation

@mmabrouk

Copy link
Copy Markdown
Member

Closes part of #5417.

The problem

Three mount routes return raw bytes, but none of them declared a response media type:

Route Returns OpenAPI said
POST /mounts/files/export a streamed zip application/json
GET /mounts/{mount_id}/files/download a file's bytes application/json
GET /sessions/mounts/{mount_id}/files/download a file's bytes application/json

FastAPI advertises application/json for any route that declares nothing, so the Fern generator produced methods that parse the body as JSON. Parsing a zip as JSON corrupts it. That is the reason the drive UI could never call these routes through the generated client and had to reach for raw axios and raw fetch instead, which is the deviation from web/AGENTS.md that #5417 was filed about.

The export route also carried a hand-written exportMountFiles method inside the generated directory, added in daf3f6a18 when the route was renamed to /files/export, with a note that it "stays hand-written until the Fern regen ticket". This is that ticket.

The change

Declare the real media types. application/zip for the archive export, application/octet-stream for the two downloads. The declarations live in mounts/utils.py next to the helpers that produce the bytes, since both routers share them.

Setting responses= alone is not enough, and this is the part that is easy to get wrong: FastAPI keeps its default application/json entry unless the route also declares a response_class whose media type is empty. I verified this against the pinned FastAPI version before writing it. With responses= only, the 200 lists both application/json and application/zip, and the generator still picks JSON.

Runtime behavior does not change. Each handler already returns its own Response, so response_class only affects the generated schema.

Regenerate the client once, from the spec the modified code actually serves. Before and after, for all three methods:

// before
public exportMountFiles(...): core.HttpResponsePromise<unknown>
// (no responseType, so the fetcher parses the zip as JSON)

// after
public exportMountFiles(...): core.HttpResponsePromise<core.BinaryResponse>
//   responseType: "binary-response"

core.BinaryResponse exposes both .blob() and .stream(), which is what the follow-up needs: the buffered download path wants a blob, and the stream-to-disk path wants a ReadableStream.

The regeneration also picks up two pieces of drift the hand-edits had left behind: GetMountFilesRequest.order becomes a generated enum instead of a loose string | null, and MountFile moves under the mounts resource.

How the spec was produced

Worth recording, because generating from the wrong source silently destroys the client. A regeneration from the local OSS stack deletes 39 files: the entire auth layer (that spec has no security schemes) plus the billing and events resources. The committed client comes from an EE spec.

So the spec here came from the EE image running this branch's code, served over HTTP rather than dumped in-process, because FastAPI only adds the root_path server entry when it serves the document. Dumping it in-process instead rewrites environments.ts from /api to an absolute host URL.

The resulting spec differs from the deployed EE spec in exactly six ways: the three routes each losing application/json and gaining their binary type. Nothing else.

Verification

  • The three mount routes render exactly the intended 200 content types, checked by diffing the served spec against the deployed one.
  • tsc compiles the regenerated client, and @agenta/shared, @agenta/ui, @agenta/sdk, @agenta/entities all typecheck against it.
  • The regenerated client keeps every method the app calls; the method list is unchanged from main.
  • 90 mounts unit tests pass.
  • ruff format and ruff check are clean.
  • No cloud or dev-box host leaked into the generated output.

What this does not do

The frontend still calls these routes through raw axios. Moving it onto the generated client is the second half of #5417 and lands in a PR stacked on this one, since it needs the BinaryResponse methods this PR generates.

https://claude.ai/code/session_011npNAXwcM2adqdSX6QGcsz

The three mount routes that return raw bytes declared no response media type, so
FastAPI advertised application/json for them. The generated clients then parsed a
zip or a file body as JSON and corrupted it, which is why the frontend had to call
these routes through raw axios.

Declare the real media types (application/zip for the archive export,
application/octet-stream for the two file downloads). Setting responses= alone is
not enough: FastAPI keeps its default application/json entry unless the route also
declares a response_class with no media type, so both are set. Runtime behavior is
unchanged, since each handler already returns its own Response.

Regenerate the TypeScript client once from the resulting spec, replacing the
exportMountFiles method that was hand-written into the generated directory after
the /files/export rename. The three methods now return core.BinaryResponse with
responseType binary-response, which exposes both .blob() and .stream(). The
regeneration also corrects two pieces of drift the hand-edits had left behind:
GetMountFilesRequest.order becomes a generated enum, and MountFile moves under the
mounts resource.

Refs #5417

Claude-Session: https://claude.ai/code/session_011npNAXwcM2adqdSX6QGcsz
@dosubot dosubot Bot added the size:L This PR changes 100-499 lines, ignoring generated files. label Jul 25, 2026
@vercel

vercel Bot commented Jul 25, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
agenta-documentation Ready Ready Preview, Comment Jul 25, 2026 6:30pm

Request Review

@coderabbitai

coderabbitai Bot commented Jul 25, 2026

Copy link
Copy Markdown

Review Change Stack

Important

Review skipped

No new commits to review since the last review.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 0329a674-4e6a-4c21-bc64-f154ffe34b09

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

FastAPI mount archive and file download routes now explicitly declare streaming or binary response classes and OpenAPI schemas for ZIP and octet-stream payloads.

Changes

Binary response metadata

Layer / File(s) Summary
Define binary response declarations
api/oss/src/apis/fastapi/mounts/utils.py
Adds OpenAPI response mappings for application/zip and application/octet-stream responses.
Wire response metadata into routes
api/oss/src/apis/fastapi/mounts/router.py, api/oss/src/apis/fastapi/sessions/router.py
Configures archive export with StreamingResponse and ZIP metadata, and mount downloads with Response and binary metadata.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related issues

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly captures the binary response declaration and Fern client regeneration.
Description check ✅ Passed The description is directly related and details the response-type fixes and client regeneration.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/mounts-binary-openapi-fern-regen

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@mmabrouk

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 25, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@github-actions

Copy link
Copy Markdown
Contributor

Railway Preview Environment

Preview URL https://gateway-production-5d26.up.railway.app/w
Project agenta-oss-pr-5518
Image tag pr-5518-782187d
Status Deployed
Railway logs Open logs
Workflow logs View workflow run
Updated at 2026-07-25T18:40:07.272Z

@mmabrouk mmabrouk left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

lgtm

@mmabrouk mmabrouk added the lgtm This PR has been approved by a maintainer label Jul 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Backend lgtm This PR has been approved by a maintainer size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant