From f55092509cace1760bb775b3cb2c18ae6af8b370 Mon Sep 17 00:00:00 2001 From: Tomer Shlasky Date: Wed, 13 May 2026 13:04:58 +0300 Subject: [PATCH 1/8] feat(realtime): add optional referenceFrame to set/setImage --- packages/sdk/src/realtime/methods.ts | 19 ++- packages/sdk/src/realtime/types.ts | 1 + .../sdk/src/realtime/webrtc-connection.ts | 11 +- packages/sdk/src/realtime/webrtc-manager.ts | 7 +- packages/sdk/tests/unit.test.ts | 128 ++++++++++++++++++ 5 files changed, 162 insertions(+), 4 deletions(-) diff --git a/packages/sdk/src/realtime/methods.ts b/packages/sdk/src/realtime/methods.ts index 6755d415..8c7ffaf0 100644 --- a/packages/sdk/src/realtime/methods.ts +++ b/packages/sdk/src/realtime/methods.ts @@ -10,6 +10,9 @@ const setInputSchema = z prompt: z.string().min(1).optional(), enhance: z.boolean().optional().default(true), image: z.union([z.instanceof(Blob), z.instanceof(File), z.string(), z.null()]).optional(), + referenceFrame: z + .union([z.instanceof(Blob), z.instanceof(File), z.string(), z.null()]) + .optional(), }) .refine((data) => data.prompt !== undefined || data.image !== undefined, { message: "At least one of 'prompt' or 'image' must be provided", @@ -41,14 +44,26 @@ export const realtimeMethods = ( throw parsed.error; } - const { prompt, enhance, image } = parsed.data; + const { prompt, enhance, image, referenceFrame } = parsed.data; let imageBase64: string | null = null; if (image !== undefined && image !== null) { imageBase64 = await imageToBase64(image); } - await webrtcManager.setImage(imageBase64, { prompt, enhance, timeout: UPDATE_TIMEOUT_MS }); + const options: { + prompt?: string; + enhance: boolean; + timeout: number; + referenceFrameBase64?: string | null; + } = { prompt, enhance, timeout: UPDATE_TIMEOUT_MS }; + + if (referenceFrame !== undefined) { + options.referenceFrameBase64 = + referenceFrame === null ? null : await imageToBase64(referenceFrame); + } + + await webrtcManager.setImage(imageBase64, options); }; const setPrompt = async (prompt: string, { enhance }: { enhance?: boolean } = {}): Promise => { diff --git a/packages/sdk/src/realtime/types.ts b/packages/sdk/src/realtime/types.ts index d6fe21d9..7808ce82 100644 --- a/packages/sdk/src/realtime/types.ts +++ b/packages/sdk/src/realtime/types.ts @@ -40,6 +40,7 @@ export type SetAvatarImageMessage = { image_data: string | null; // Base64-encoded image data, or null to clear/use placeholder prompt?: string | null; // Optional prompt to send with the image, null for passthrough enhance_prompt?: boolean; // Optional flag to enhance the prompt + reference_frame?: string | null; // Optional base64-encoded reference frame (e.g. current camera frame) to give prompt enhancement extra context }; export type SetImageAckMessage = { diff --git a/packages/sdk/src/realtime/webrtc-connection.ts b/packages/sdk/src/realtime/webrtc-connection.ts index 6e59a863..5359eb5f 100644 --- a/packages/sdk/src/realtime/webrtc-connection.ts +++ b/packages/sdk/src/realtime/webrtc-connection.ts @@ -311,7 +311,12 @@ export class WebRTCConnection { async setImageBase64( imageBase64: string | null, - options?: { prompt?: string | null; enhance?: boolean; timeout?: number }, + options?: { + prompt?: string | null; + enhance?: boolean; + timeout?: number; + referenceFrameBase64?: string | null; + }, ): Promise { return new Promise((resolve, reject) => { const timeoutId = setTimeout(() => { @@ -336,6 +341,7 @@ export class WebRTCConnection { image_data: string | null; prompt?: string | null; enhance_prompt?: boolean; + reference_frame?: string | null; } = { type: "set_image", image_data: imageBase64, @@ -347,6 +353,9 @@ export class WebRTCConnection { if (options?.enhance !== undefined) { message.enhance_prompt = options.enhance; } + if (options?.referenceFrameBase64 !== undefined) { + message.reference_frame = options.referenceFrameBase64; + } if (!this.send(message)) { clearTimeout(timeoutId); diff --git a/packages/sdk/src/realtime/webrtc-manager.ts b/packages/sdk/src/realtime/webrtc-manager.ts index 174c897f..abf8c5ba 100644 --- a/packages/sdk/src/realtime/webrtc-manager.ts +++ b/packages/sdk/src/realtime/webrtc-manager.ts @@ -244,7 +244,12 @@ export class WebRTCManager { setImage( imageBase64: string | null, - options?: { prompt?: string; enhance?: boolean; timeout?: number }, + options?: { + prompt?: string; + enhance?: boolean; + timeout?: number; + referenceFrameBase64?: string | null; + }, ): Promise { return this.connection.setImageBase64(imageBase64, options); } diff --git a/packages/sdk/tests/unit.test.ts b/packages/sdk/tests/unit.test.ts index a5abb6be..c342f9f0 100644 --- a/packages/sdk/tests/unit.test.ts +++ b/packages/sdk/tests/unit.test.ts @@ -1232,6 +1232,80 @@ describe("WebRTCConnection", () => { vi.useRealTimers(); } }); + + it("includes reference_frame in the outgoing set_image message when provided", async () => { + vi.useFakeTimers(); + try { + const { WebRTCConnection } = await import("../src/realtime/webrtc-connection.js"); + const connection = new WebRTCConnection(); + const sendSpy = vi.spyOn(connection, "send").mockReturnValue(true); + + const promise = connection + .setImageBase64("imgbase64", { referenceFrameBase64: "refbase64" }) + .catch(() => {}); + + expect(sendSpy).toHaveBeenCalledWith({ + type: "set_image", + image_data: "imgbase64", + reference_frame: "refbase64", + }); + + await vi.advanceTimersByTimeAsync(30001); + await promise; + sendSpy.mockRestore(); + } finally { + vi.useRealTimers(); + } + }); + + it("omits reference_frame when not provided", async () => { + vi.useFakeTimers(); + try { + const { WebRTCConnection } = await import("../src/realtime/webrtc-connection.js"); + const connection = new WebRTCConnection(); + const sendSpy = vi.spyOn(connection, "send").mockReturnValue(true); + + const promise = connection.setImageBase64("imgbase64").catch(() => {}); + + const sentMessage = sendSpy.mock.calls[0]?.[0] as Record; + expect(sentMessage).toEqual({ + type: "set_image", + image_data: "imgbase64", + }); + expect("reference_frame" in sentMessage).toBe(false); + + await vi.advanceTimersByTimeAsync(30001); + await promise; + sendSpy.mockRestore(); + } finally { + vi.useRealTimers(); + } + }); + + it("forwards explicit null reference_frame", async () => { + vi.useFakeTimers(); + try { + const { WebRTCConnection } = await import("../src/realtime/webrtc-connection.js"); + const connection = new WebRTCConnection(); + const sendSpy = vi.spyOn(connection, "send").mockReturnValue(true); + + const promise = connection + .setImageBase64("imgbase64", { referenceFrameBase64: null }) + .catch(() => {}); + + expect(sendSpy).toHaveBeenCalledWith({ + type: "set_image", + image_data: "imgbase64", + reference_frame: null, + }); + + await vi.advanceTimersByTimeAsync(30001); + await promise; + sendSpy.mockRestore(); + } finally { + vi.useRealTimers(); + } + }); }); describe("setupNewPeerConnection", () => { @@ -1445,6 +1519,60 @@ describe("set()", () => { timeout: 30000, }); }); + + it("converts referenceFrame Blob to base64 and forwards it", async () => { + const refBlob = new Blob(["ref-frame"], { type: "image/jpeg" }); + mockImageToBase64.mockImplementation(async (input) => + input === refBlob ? "refbase64" : "imgbase64", + ); + + await methods.set({ prompt: "a cat", image: "rawimg", referenceFrame: refBlob }); + + expect(mockImageToBase64).toHaveBeenCalledWith(refBlob); + expect(mockManager.setImage).toHaveBeenCalledWith("imgbase64", { + prompt: "a cat", + enhance: true, + timeout: 30000, + referenceFrameBase64: "refbase64", + }); + }); + + it("forwards a base64 string referenceFrame through imageToBase64", async () => { + mockImageToBase64.mockImplementation(async (input) => + input === "raw-ref" ? "refbase64" : "imgbase64", + ); + + await methods.set({ image: "raw-img", referenceFrame: "raw-ref" }); + + expect(mockImageToBase64).toHaveBeenCalledWith("raw-ref"); + expect(mockManager.setImage).toHaveBeenCalledWith("imgbase64", { + prompt: undefined, + enhance: true, + timeout: 30000, + referenceFrameBase64: "refbase64", + }); + }); + + it("forwards null referenceFrame without calling imageToBase64", async () => { + mockImageToBase64.mockResolvedValue("imgbase64"); + + await methods.set({ image: "raw-img", referenceFrame: null }); + + expect(mockImageToBase64).toHaveBeenCalledTimes(1); + expect(mockImageToBase64).toHaveBeenCalledWith("raw-img"); + expect(mockManager.setImage).toHaveBeenCalledWith("imgbase64", { + prompt: undefined, + enhance: true, + timeout: 30000, + referenceFrameBase64: null, + }); + }); + + it("omits referenceFrameBase64 when referenceFrame is not provided", async () => { + await methods.set({ prompt: "a cat" }); + const call = mockManager.setImage.mock.calls[0]?.[1] as Record; + expect("referenceFrameBase64" in call).toBe(false); + }); }); describe("Subscribe Token", () => { From 6420325058865b10b3a8eaaf51488b66f4a63b04 Mon Sep 17 00:00:00 2001 From: Tomer Shlasky Date: Wed, 13 May 2026 13:11:24 +0300 Subject: [PATCH 2/8] chore: biome format --- packages/sdk/src/realtime/methods.ts | 7 ++----- packages/sdk/tests/unit.test.ts | 16 ++++------------ 2 files changed, 6 insertions(+), 17 deletions(-) diff --git a/packages/sdk/src/realtime/methods.ts b/packages/sdk/src/realtime/methods.ts index 8c7ffaf0..f45ecb34 100644 --- a/packages/sdk/src/realtime/methods.ts +++ b/packages/sdk/src/realtime/methods.ts @@ -10,9 +10,7 @@ const setInputSchema = z prompt: z.string().min(1).optional(), enhance: z.boolean().optional().default(true), image: z.union([z.instanceof(Blob), z.instanceof(File), z.string(), z.null()]).optional(), - referenceFrame: z - .union([z.instanceof(Blob), z.instanceof(File), z.string(), z.null()]) - .optional(), + referenceFrame: z.union([z.instanceof(Blob), z.instanceof(File), z.string(), z.null()]).optional(), }) .refine((data) => data.prompt !== undefined || data.image !== undefined, { message: "At least one of 'prompt' or 'image' must be provided", @@ -59,8 +57,7 @@ export const realtimeMethods = ( } = { prompt, enhance, timeout: UPDATE_TIMEOUT_MS }; if (referenceFrame !== undefined) { - options.referenceFrameBase64 = - referenceFrame === null ? null : await imageToBase64(referenceFrame); + options.referenceFrameBase64 = referenceFrame === null ? null : await imageToBase64(referenceFrame); } await webrtcManager.setImage(imageBase64, options); diff --git a/packages/sdk/tests/unit.test.ts b/packages/sdk/tests/unit.test.ts index c342f9f0..930a5f31 100644 --- a/packages/sdk/tests/unit.test.ts +++ b/packages/sdk/tests/unit.test.ts @@ -1240,9 +1240,7 @@ describe("WebRTCConnection", () => { const connection = new WebRTCConnection(); const sendSpy = vi.spyOn(connection, "send").mockReturnValue(true); - const promise = connection - .setImageBase64("imgbase64", { referenceFrameBase64: "refbase64" }) - .catch(() => {}); + const promise = connection.setImageBase64("imgbase64", { referenceFrameBase64: "refbase64" }).catch(() => {}); expect(sendSpy).toHaveBeenCalledWith({ type: "set_image", @@ -1289,9 +1287,7 @@ describe("WebRTCConnection", () => { const connection = new WebRTCConnection(); const sendSpy = vi.spyOn(connection, "send").mockReturnValue(true); - const promise = connection - .setImageBase64("imgbase64", { referenceFrameBase64: null }) - .catch(() => {}); + const promise = connection.setImageBase64("imgbase64", { referenceFrameBase64: null }).catch(() => {}); expect(sendSpy).toHaveBeenCalledWith({ type: "set_image", @@ -1522,9 +1518,7 @@ describe("set()", () => { it("converts referenceFrame Blob to base64 and forwards it", async () => { const refBlob = new Blob(["ref-frame"], { type: "image/jpeg" }); - mockImageToBase64.mockImplementation(async (input) => - input === refBlob ? "refbase64" : "imgbase64", - ); + mockImageToBase64.mockImplementation(async (input) => (input === refBlob ? "refbase64" : "imgbase64")); await methods.set({ prompt: "a cat", image: "rawimg", referenceFrame: refBlob }); @@ -1538,9 +1532,7 @@ describe("set()", () => { }); it("forwards a base64 string referenceFrame through imageToBase64", async () => { - mockImageToBase64.mockImplementation(async (input) => - input === "raw-ref" ? "refbase64" : "imgbase64", - ); + mockImageToBase64.mockImplementation(async (input) => (input === "raw-ref" ? "refbase64" : "imgbase64")); await methods.set({ image: "raw-img", referenceFrame: "raw-ref" }); From 9121ccb2296ad4f4e8acc12fb7baf4ab6f06a469 Mon Sep 17 00:00:00 2001 From: Tomer Shlasky Date: Wed, 13 May 2026 13:20:04 +0300 Subject: [PATCH 3/8] feat(realtime): wire referenceFrame through RealTimeClient.setImage --- packages/sdk/src/realtime/client.ts | 30 +++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/packages/sdk/src/realtime/client.ts b/packages/sdk/src/realtime/client.ts index 8327a37d..aa10fe04 100644 --- a/packages/sdk/src/realtime/client.ts +++ b/packages/sdk/src/realtime/client.ts @@ -117,7 +117,12 @@ export type RealTimeClient = { subscribeToken: string | null; setImage: ( image: Blob | File | string | null, - options?: { prompt?: string; enhance?: boolean; timeout?: number }, + options?: { + prompt?: string; + enhance?: boolean; + timeout?: number; + referenceFrame?: Blob | File | string | null; + }, ) => Promise; }; @@ -332,13 +337,30 @@ export const createRealTimeClient = (opts: RealTimeClientOptions) => { }, setImage: async ( image: Blob | File | string | null, - options?: { prompt?: string; enhance?: boolean; timeout?: number }, + options?: { + prompt?: string; + enhance?: boolean; + timeout?: number; + referenceFrame?: Blob | File | string | null; + }, ) => { + const { referenceFrame, ...rest } = options ?? {}; + const managerOptions: { + prompt?: string; + enhance?: boolean; + timeout?: number; + referenceFrameBase64?: string | null; + } = rest; + + if (referenceFrame !== undefined) { + managerOptions.referenceFrameBase64 = referenceFrame === null ? null : await imageToBase64(referenceFrame); + } + if (image === null) { - return manager.setImage(null, options); + return manager.setImage(null, managerOptions); } const base64 = await imageToBase64(image); - return manager.setImage(base64, options); + return manager.setImage(base64, managerOptions); }, }; From 7f856bb89318a1532637e45cbec334276a2ca698 Mon Sep 17 00:00:00 2001 From: Tomer Shlasky Date: Wed, 13 May 2026 13:23:19 +0300 Subject: [PATCH 4/8] feat(models): add lucy-2.5 realtime model --- packages/sdk/src/shared/model.ts | 11 +++++++++++ packages/sdk/tests/unit.test.ts | 9 +++++++++ 2 files changed, 20 insertions(+) diff --git a/packages/sdk/src/shared/model.ts b/packages/sdk/src/shared/model.ts index 2487812c..2a255f03 100644 --- a/packages/sdk/src/shared/model.ts +++ b/packages/sdk/src/shared/model.ts @@ -34,6 +34,7 @@ function warnDeprecated(model: string): void { export const realtimeModels = z.union([ // Canonical names z.literal("lucy-2.1"), + z.literal("lucy-2.5"), z.literal("lucy-2.1-vton"), z.literal("lucy-vton-2"), z.literal("lucy-restyle-2"), @@ -192,6 +193,7 @@ export const modelInputSchemas = { "lucy-image-2": imageEditSchema, "lucy-restyle-2": restyleSchema, "lucy-2.1": videoEdit2Schema, + "lucy-2.5": videoEdit2Schema, "lucy-2.1-vton": videoEdit2Schema, "lucy-vton-2": videoEdit2Schema, // Latest aliases (server-side resolution) @@ -264,6 +266,14 @@ const _models = { height: 624, inputSchema: z.object({}), }, + "lucy-2.5": { + urlPath: "/v1/stream", + name: "lucy-2.5" as const, + fps: 20, + width: 1088, + height: 624, + inputSchema: z.object({}), + }, "lucy-2.1-vton": { urlPath: "/v1/stream", name: "lucy-2.1-vton" as const, @@ -503,6 +513,7 @@ export const models = { * * Available options: * - `"lucy-2.1"` - Lucy 2.1 realtime video editing + * - `"lucy-2.5"` - Lucy 2.5 realtime video editing * - `"lucy-2.1-vton"` - Lucy 2.1 virtual try-on * - `"lucy-vton-2"` - Lucy virtual try-on 2 * - `"lucy-restyle-2"` - Realtime video restyling diff --git a/packages/sdk/tests/unit.test.ts b/packages/sdk/tests/unit.test.ts index 930a5f31..d48364ae 100644 --- a/packages/sdk/tests/unit.test.ts +++ b/packages/sdk/tests/unit.test.ts @@ -3397,6 +3397,15 @@ describe("Canonical Model Names", () => { expect(model.height).toBe(624); }); + it("lucy-2.5 canonical name works", () => { + const model = models.realtime("lucy-2.5"); + expect(model.name).toBe("lucy-2.5"); + expect(model.urlPath).toBe("/v1/stream"); + expect(model.fps).toBe(20); + expect(model.width).toBe(1088); + expect(model.height).toBe(624); + }); + it("lucy-2.1-vton canonical name works", () => { const model = models.realtime("lucy-2.1-vton"); expect(model.name).toBe("lucy-2.1-vton"); From 8923231566a438aaeddf30688aa95adf2dd3da55 Mon Sep 17 00:00:00 2001 From: Tomer Shlasky Date: Wed, 13 May 2026 13:26:51 +0300 Subject: [PATCH 5/8] feat(models): mark lucy-2.5 canonical and update registry test count --- packages/sdk/src/shared/model.ts | 9 ++++++++- packages/sdk/tests/unit.test.ts | 10 ++++++++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/packages/sdk/src/shared/model.ts b/packages/sdk/src/shared/model.ts index 42dcf662..e6179fb0 100644 --- a/packages/sdk/src/shared/model.ts +++ b/packages/sdk/src/shared/model.ts @@ -3,6 +3,7 @@ import { createModelNotFoundError } from "../utils/errors"; const CANONICAL_MODEL_NAMES = [ "lucy-2.1", + "lucy-2.5", "lucy-2.1-vton", "lucy-vton-2", "lucy-restyle-2", @@ -10,7 +11,13 @@ const CANONICAL_MODEL_NAMES = [ "lucy-image-2", ] as const; -const CANONICAL_REALTIME_MODEL_NAMES = ["lucy-2.1", "lucy-2.1-vton", "lucy-vton-2", "lucy-restyle-2"] as const; +const CANONICAL_REALTIME_MODEL_NAMES = [ + "lucy-2.1", + "lucy-2.5", + "lucy-2.1-vton", + "lucy-vton-2", + "lucy-restyle-2", +] as const; const CANONICAL_VIDEO_MODEL_NAMES = [ "lucy-clip", "lucy-2.1", diff --git a/packages/sdk/tests/unit.test.ts b/packages/sdk/tests/unit.test.ts index 3db28269..c85cd7c4 100644 --- a/packages/sdk/tests/unit.test.ts +++ b/packages/sdk/tests/unit.test.ts @@ -3434,7 +3434,13 @@ describe("Canonical Model Names", () => { expect(canonicalModelSchema.safeParse(alias).success).toBe(false); } - expect(canonicalRealtimeModels.options).toEqual(["lucy-2.1", "lucy-2.1-vton", "lucy-vton-2", "lucy-restyle-2"]); + expect(canonicalRealtimeModels.options).toEqual([ + "lucy-2.1", + "lucy-2.5", + "lucy-2.1-vton", + "lucy-vton-2", + "lucy-restyle-2", + ]); expect(canonicalVideoModels.options).toEqual([ "lucy-clip", "lucy-2.1", @@ -3500,7 +3506,7 @@ describe("Canonical Model Names", () => { it("lists all models when called without options", () => { const listedModels = listModels(); - expect(listedModels).toHaveLength(26); + expect(listedModels).toHaveLength(27); expect(listedModels.some((model) => model.kind === "realtime" && model.name === "lucy-2.1")).toBe(true); expect(listedModels.some((model) => model.kind === "video" && model.name === "lucy-clip")).toBe(true); expect(listedModels.some((model) => model.kind === "image" && model.name === "lucy-image-2")).toBe(true); From c37dbe4028cd1f57d8ef24cc740a4643c3869521 Mon Sep 17 00:00:00 2001 From: Tomer Shlasky Date: Wed, 13 May 2026 13:34:55 +0300 Subject: [PATCH 6/8] feat(playground): add lucy-2.5 option and reference frame capture toggle --- packages/sdk/index.html | 53 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/packages/sdk/index.html b/packages/sdk/index.html index 58e86d26..8eb02ee5 100644 --- a/packages/sdk/index.html +++ b/packages/sdk/index.html @@ -242,6 +242,7 @@

Configuration

+ @@ -321,6 +322,12 @@

Image Reference (Style Transfer)

+
+ + +
@@ -380,6 +387,39 @@

Console Logs

let decartClient = null; let decartRealtime = null; let localStream = null; + + // Captures a low-res JPEG snapshot from the local camera stream. + // Mirrors the pattern used in tryonv1 so the bouncer's prompt enhancer can see what the person is currently wearing. + async function captureReferenceFrame() { + if (!localStream) return null; + const video = document.createElement('video'); + video.srcObject = localStream; + video.muted = true; + video.playsInline = true; + await video.play(); + await new Promise((resolve) => { + if ('requestVideoFrameCallback' in video) { + video.requestVideoFrameCallback(() => resolve()); + } else { + requestAnimationFrame(() => requestAnimationFrame(() => resolve())); + } + }); + if (!video.videoWidth) { + video.pause(); + video.srcObject = null; + return null; + } + const scale = 320 / video.videoWidth; + const canvas = document.createElement('canvas'); + canvas.width = 320; + canvas.height = Math.round(video.videoHeight * scale); + canvas.getContext('2d').drawImage(video, 0, 0, canvas.width, canvas.height); + video.pause(); + video.srcObject = null; + return new Promise((resolve) => { + canvas.toBlob((blob) => resolve(blob), 'image/jpeg', 0.5); + }); + } let isConnected = false; let processedVideoUrl = null; let currentSessionId = null; @@ -412,6 +452,7 @@

Console Logs

logsContainer: document.getElementById('logs-container'), // Image reference elements referenceImage: document.getElementById('reference-image'), + includeReferenceFrame: document.getElementById('include-reference-frame'), setImage: document.getElementById('send-image'), imageStatus: document.getElementById('image-status'), imageStatusText: document.getElementById('image-status-text'), @@ -757,7 +798,17 @@

Console Logs

addLog('Sending reference image...', 'info'); - await decartRealtime.setImage(file); + let referenceFrame = null; + if (elements.includeReferenceFrame.checked) { + referenceFrame = await captureReferenceFrame(); + if (referenceFrame) { + addLog(`Captured reference frame from camera (${(referenceFrame.size / 1024).toFixed(1)} KB)`, 'info'); + } else { + addLog('Camera stream not available — skipping reference frame', 'warning'); + } + } + + await decartRealtime.setImage(file, referenceFrame ? { referenceFrame } : undefined); elements.imageStatusText.textContent = '✅ Image sent successfully!'; elements.imageStatusText.style.color = '#4CAF50'; From a0aa5d4e3215241e11aed01903a1810f5cfe737f Mon Sep 17 00:00:00 2001 From: Tomer Shlasky Date: Wed, 13 May 2026 13:40:04 +0300 Subject: [PATCH 7/8] chore(playground): shorten reference frame checkbox label --- packages/sdk/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/sdk/index.html b/packages/sdk/index.html index 8eb02ee5..eb06df4b 100644 --- a/packages/sdk/index.html +++ b/packages/sdk/index.html @@ -325,7 +325,7 @@

Image Reference (Style Transfer)