Skip to content

feat: output.getDownloadUrl() + SDK User-Agent identification#16

Merged
wei-hai merged 4 commits into
mainfrom
feat/output-get-download-url
Jul 23, 2026
Merged

feat: output.getDownloadUrl() + SDK User-Agent identification#16
wei-hai merged 4 commits into
mainfrom
feat/output-get-download-url

Conversation

@wei-hai

@wei-hai wei-hai commented Jul 23, 2026

Copy link
Copy Markdown
Collaborator

What

  • Output.getDownloadUrl(): Promise<{ url, expiresAt }> — a directly-fetchable URL for an output, so a caller (e.g. a Cloudflare/serverless worker) can hand the URL to a downstream consumer without streaming the bytes through itself.
    • Object-storage backends (Cloud/serverless): the self-authorizing signed URL (from the content endpoint's redirect Location) + its expiry.
    • Self-hosted (proxy serves inline): the content-endpoint URL, expiresAt: null.
    • Works on every backend and never throws (write-once/run-anywhere). Short-lived, self-authorizing bearer credential.
    • Per-output: a multi-output job resolves each output to its own distinct URL.
  • User-Agent on every request: comfy-sdk-typescript/{version} (node {version}), with an optional clientInfo appending app/{name}. Request metadata, not telemetry.

How

New getAssetContentUrl() fetches GET /assets/{id}/content with redirect: "manual" (the existing getAssetContent still uses follow), reads the Location without following it (bearer can't leak cross-origin), and parses GCS V4 X-Goog-Date/X-Goog-Expires for the expiry.

Tests

vitest run --coverage — 128 passed (incl. cloud-redirect, self-hosted-inline, multi-output-distinct-URLs, bearer-not-leaked, User-Agent + clientInfo). tsc + oxlint + oxfmt clean. Not added to OPERATION_IDS (a second low method over the same operation, not a new operationId).

Add a first-class Output.getDownloadUrl() returning { url, expiresAt } — a
directly-fetchable URL for an output (signed URL on object-storage backends,
content URL on self-hosted; never throws). Also set a User-Agent identifying
the SDK on every request, with an optional clientInfo app token.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@wei-hai
wei-hai requested review from a team as code owners July 23, 2026 06:46
@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@wei-hai, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 28 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 8935f890-52b4-4cf8-b22a-a50429180b01

📥 Commits

Reviewing files that changed from the base of the PR and between 1ae77a9 and f8869b4.

📒 Files selected for processing (2)
  • src/low/transport.test.ts
  • src/low/transport.ts

Warning

.coderabbit.yaml has a parsing error

The CodeRabbit configuration file in this repository has a parsing error and default settings were used instead. Please fix the error(s) in the configuration file. You can initialize chat with CodeRabbit to get help with the configuration file.

💥 Parsing errors (1)
Validation error: Too big: expected string to have <=250 characters at "tone_instructions"
⚙️ Configuration instructions
  • Please see the configuration documentation for more information.
  • You can also validate your configuration using the online YAML validator.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json
📝 Walkthrough

Walkthrough

The SDK adds asset download URL resolution with redirect and expiry handling, configurable User-Agent metadata, clientInfo wiring, and an Output.getDownloadUrl() helper. Tests cover redirect security, backend variants, multiple outputs, and header behavior.

Changes

Asset URLs and User-Agent Metadata

Layer / File(s) Summary
Transport asset URL resolution
src/low/transport.ts, src/low/index.ts, src/low/transport.test.ts, test/support/stub-server.ts
Adds manual redirect handling, signed URL expiry parsing, typed asset URL results, and coverage for redirect, self-hosted, error, and authorization behavior.
Client User-Agent propagation
src/low/transport.ts, src/sdk/client.ts, src/low/transport.test.ts, test/support/stub-server.ts, README.md
Builds default SDK User-Agent values, appends clientInfo, preserves explicit headers, wires client options through the SDK, and documents the behavior.
Output download URL API
src/sdk/outputs.ts, src/sdk/outputs.test.ts
Adds Output.getDownloadUrl() and validates distinct URLs and expiry values across backend responses and output IDs.

Sequence Diagram(s)

sequenceDiagram
  participant Output
  participant ComfyLow
  participant AssetEndpoint
  Output->>ComfyLow: getAssetContentUrl(assetId)
  ComfyLow->>AssetEndpoint: GET asset content with redirect: manual
  AssetEndpoint-->>ComfyLow: content response or redirect Location
  ComfyLow-->>Output: downloadable URL and expiresAt
Loading
🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
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 feat/output-get-download-url
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch feat/output-get-download-url

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/low/transport.ts`:
- Around line 36-41: The hand-maintained SDK_VERSION constant can diverge from
package.json without detection. Add a focused test that reads package.json and
asserts its version equals SDK_VERSION, so any version bump missing from the
constant fails immediately.
- Around line 352-371: Update getAssetContentUrl so the inline 200/206 response
body is consumed or destroyed before returning the local URL result, while
preserving the existing redirect handling and return values. Ensure the response
connection is released even when the inline response has a body.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 39db2493-b8f0-4a0e-83aa-307bdad5a806

📥 Commits

Reviewing files that changed from the base of the PR and between 5f7c428 and 1ae77a9.

📒 Files selected for processing (8)
  • README.md
  • src/low/index.ts
  • src/low/transport.test.ts
  • src/low/transport.ts
  • src/sdk/client.ts
  • src/sdk/outputs.test.ts
  • src/sdk/outputs.ts
  • test/support/stub-server.ts

Comment thread src/low/transport.ts
Comment thread src/low/transport.ts
wei-hai and others added 3 commits July 23, 2026 08:29
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…uard SDK_VERSION drift

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@wei-hai
wei-hai merged commit d922672 into main Jul 23, 2026
7 checks passed
@wei-hai
wei-hai deleted the feat/output-get-download-url branch July 23, 2026 16:16
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.

1 participant