From 0561402e4c5f2d680af189333ea5ac11ea6f4ea1 Mon Sep 17 00:00:00 2001 From: Miguel Rasero Date: Wed, 10 Jun 2026 22:43:01 +0000 Subject: [PATCH] docs(sdk,studio): prefer UploadedAsset.ref for model inputs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The backend now resolves runflow://assets/{uuid} refs to freshly signed URLs at model dispatch (monorepo ee8d34ec + e08eb657, verified live — formerly tracked as RUN-418). That makes ref the right default: it never expires, while the signed url stays the short-TTL answer for browser previews. JSDoc + README examples updated; patch changeset; no runtime changes. --- .changeset/prefer-asset-ref.md | 6 ++++++ packages/proxy/package.json | 6 +----- packages/sdk/README.md | 22 +++++++++++++--------- packages/sdk/package.json | 6 +----- packages/sdk/src/assets.ts | 22 ++++++++++++---------- packages/studio/README.md | 3 ++- packages/studio/package.json | 10 ++-------- 7 files changed, 37 insertions(+), 38 deletions(-) create mode 100644 .changeset/prefer-asset-ref.md diff --git a/.changeset/prefer-asset-ref.md b/.changeset/prefer-asset-ref.md new file mode 100644 index 0000000..7fb1aaf --- /dev/null +++ b/.changeset/prefer-asset-ref.md @@ -0,0 +1,6 @@ +--- +"@runflow-io/sdk": patch +"@runflow-io/studio": patch +--- + +Docs: `UploadedAsset.ref` (`runflow://assets/{id}`) is now the recommended model input — the API resolves refs to freshly signed URLs at dispatch (shipped backend-side, formerly RUN-418), so refs never expire in your hands. `url` remains the short-TTL signed HTTPS URL for immediate browser use. Examples and JSDoc updated accordingly; no runtime changes. diff --git a/packages/proxy/package.json b/packages/proxy/package.json index ec06276..4284f96 100644 --- a/packages/proxy/package.json +++ b/packages/proxy/package.json @@ -26,11 +26,7 @@ "require": "./dist/node.cjs" } }, - "files": [ - "dist", - "README.md", - "LICENSE" - ], + "files": ["dist", "README.md", "LICENSE"], "scripts": { "build": "tsup", "dev": "tsup --watch", diff --git a/packages/sdk/README.md b/packages/sdk/README.md index e30df6b..ad7b7b0 100644 --- a/packages/sdk/README.md +++ b/packages/sdk/README.md @@ -39,19 +39,22 @@ The browser SDK never sees your API key — it's injected by ```ts const asset = await rf.assets.upload(fileInput.files[0]); await rf.models.run("google/nano-banana-pro/edit", { - input: { prompt: "remove the price tag", image_urls: [asset.url] }, + // asset.ref is the stable runflow://assets/{id} reference — dispatch + // resolves it to a fresh signed URL server-side, so it never expires. + input: { prompt: "remove the price tag", image_urls: [asset.ref] }, }); ``` `upload()` runs the platform's presigned flow (create session → PUT the bytes to storage → confirm), retrying transient failures, and returns -`{ id, url, ref, ... }`. `url` is a short-TTL **signed HTTPS URL** — -pass it straight to any model's media inputs, but don't persist it: -store `id` (or the stable `runflow://assets/{id}` `ref`) and re-mint a -fresh url with `rf.assets.get(id)` when needed. Works in the browser -through `@runflow-io/proxy` (the upload + asset-read endpoints are on -its default allow-list). Raw `Blob`s need `{ filename }`; the cap is -50 MB. +`{ id, url, ref, ... }`. **Prefer `ref`** (`runflow://assets/{id}`) for +model inputs and for anything you store — the API resolves it to a +freshly signed URL at dispatch, so it never expires. `url` is a +short-TTL **signed HTTPS URL** for immediate browser use (previews, +``); re-mint one with `rf.assets.get(id)` when needed. Works in +the browser through `@runflow-io/proxy` (the upload + asset-read +endpoints are on its default allow-list). Raw `Blob`s need +`{ filename }`; the cap is 50 MB. ### Pin-based editing @@ -148,7 +151,8 @@ information for `buildRequest` and the run helpers. are URL-encoded; `..`/empty segments are rejected. - `runflow.runs.get(id)` / `runflow.runs.poll(id)` / `runflow.runs.wait(id)` - `runflow.assets.upload(file, opts?)` — presigned upload (with retry); - returns a signed https `url` + stable `runflow://` `ref`. + returns the stable `runflow://` `ref` (preferred model input) + a + short-TTL signed https `url` for browser display. - `runflow.assets.get(id)` — re-fetch an asset with a freshly signed `url`. - `runflow.tools.run(tool, args)` / `runflow.tools.dispatch(tool, args)` - `runflow.health.check()` diff --git a/packages/sdk/package.json b/packages/sdk/package.json index 068837f..556d2e6 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -21,11 +21,7 @@ "require": "./dist/index.cjs" } }, - "files": [ - "dist", - "README.md", - "LICENSE" - ], + "files": ["dist", "README.md", "LICENSE"], "scripts": { "build": "tsup", "dev": "tsup --watch", diff --git a/packages/sdk/src/assets.ts b/packages/sdk/src/assets.ts index 91e723e..46b7749 100644 --- a/packages/sdk/src/assets.ts +++ b/packages/sdk/src/assets.ts @@ -27,16 +27,18 @@ export interface UploadedAsset { /** Asset id (uuid). The durable identifier — store THIS, not `url`. */ id: string; /** - * Short-TTL signed HTTPS URL for the file. Pass it directly to model - * inputs (`image_url`, `image_urls`, `mask_url`, …) right away. Do not - * persist it — it expires; re-mint a fresh one with `rf.assets.get(id)` - * (allowed through the proxy by default). + * Short-TTL signed HTTPS URL for the file — for immediate browser use + * (previews, ``, downloads). For model inputs prefer `ref`. If you + * do pass `url` somewhere, use it right away and never persist it — it + * expires; re-mint a fresh one with `rf.assets.get(id)`. */ url: string; /** - * Canonical stable reference (`runflow://assets/{id}`). Accepted today by - * ComfyUI workflow file inputs; once the API resolves asset refs at model - * dispatch (RUN-418), prefer this over the expiring `url`. + * Canonical stable reference (`runflow://assets/{id}`) — the PREFERRED + * model input. Dispatch resolves it to a freshly signed URL server-side, + * so it never expires in your hands. Accepted by model media inputs + * (`image_url`, `image_urls`, `mask_url`, …) and ComfyUI file inputs + * alike. Store this (or `id`). */ ref: string; /** Original filename. */ @@ -154,10 +156,10 @@ function mapAsset(asset: RawAsset): UploadedAsset { * const rf = new Runflow({ baseUrl: "/api/runflow" }); * const asset = await rf.assets.upload(fileInput.files[0]); * await rf.models.run("google/nano-banana-pro/edit", { - * input: { prompt, image_urls: [asset.url] }, + * input: { prompt, image_urls: [asset.ref] }, // stable ref — never expires * }); - * // Later, if you stored asset.id and the signed url expired: - * const fresh = await rf.assets.get(asset.id); + * // asset.url is a short-TTL signed https URL for previews/; + * // re-mint one later with rf.assets.get(asset.id) if needed. * ``` */ export class AssetsResource { diff --git a/packages/studio/README.md b/packages/studio/README.md index 71cd321..63dafa1 100644 --- a/packages/studio/README.md +++ b/packages/studio/README.md @@ -190,7 +190,8 @@ mask.syncToDisplay(rect.width, rect.height, devicePixelRatio); // pointer events → beginStroke / strokeTo / endStroke; then: const blob = await mask.toMaskBlob(img.naturalWidth, img.naturalHeight); const asset = await rf.assets.upload(blob, { filename: "mask.png" }); -// → feed asset.url as mask_url to runflow/reference-inpaint etc. +// → feed asset.ref (stable, never expires) as mask_url to +// runflow/reference-inpaint etc. ``` A React state reducer for building a custom shell is tracked as a diff --git a/packages/studio/package.json b/packages/studio/package.json index 2b1a6b8..30b3899 100644 --- a/packages/studio/package.json +++ b/packages/studio/package.json @@ -13,9 +13,7 @@ "main": "./dist/index.cjs", "module": "./dist/index.js", "types": "./dist/index.d.ts", - "sideEffects": [ - "./dist/styles.css" - ], + "sideEffects": ["./dist/styles.css"], "exports": { ".": { "types": "./dist/index.d.ts", @@ -34,11 +32,7 @@ }, "./styles.css": "./dist/styles.css" }, - "files": [ - "dist", - "README.md", - "LICENSE" - ], + "files": ["dist", "README.md", "LICENSE"], "scripts": { "build": "tsup && cp src/styles.css dist/styles.css", "dev": "tsup --watch",