feat: output.getDownloadUrl() + SDK User-Agent identification#16
Conversation
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>
|
Warning Review limit reached
Next review available in: 28 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the 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 configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
Warning
|
| 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
🚥 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.
Comment @coderabbitai help to get the list of available commands.
There was a problem hiding this comment.
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
📒 Files selected for processing (8)
README.mdsrc/low/index.tssrc/low/transport.test.tssrc/low/transport.tssrc/sdk/client.tssrc/sdk/outputs.test.tssrc/sdk/outputs.tstest/support/stub-server.ts
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…uard SDK_VERSION drift Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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.Location) + its expiry.expiresAt: null.User-Agenton every request:comfy-sdk-typescript/{version} (node {version}), with an optionalclientInfoappendingapp/{name}. Request metadata, not telemetry.How
New
getAssetContentUrl()fetchesGET /assets/{id}/contentwithredirect: "manual"(the existinggetAssetContentstill usesfollow), reads theLocationwithout following it (bearer can't leak cross-origin), and parses GCS V4X-Goog-Date/X-Goog-Expiresfor 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+oxfmtclean. Not added toOPERATION_IDS(a second low method over the same operation, not a new operationId).