Skip to content

feat(files): add client.files and image_ref support in realtime#145

Merged
AdirAmsalem merged 7 commits into
mainfrom
bismarck
May 26, 2026
Merged

feat(files): add client.files and image_ref support in realtime#145
AdirAmsalem merged 7 commits into
mainfrom
bismarck

Conversation

@AdirAmsalem
Copy link
Copy Markdown
Contributor

@AdirAmsalem AdirAmsalem commented May 25, 2026

Description

Adds a server-managed file upload surface to the SDK, backed by POST /v1/files in the api. Users upload an asset once, get a "file_..." id, and reuse it across realtime updates without re-uploading or base64-ing it on every call. Files expire after 24 h server-side.

The realtime methods (set, setImage, initialState.image) accept the id as a plain string — callers persist the id in their own storage, not the full metadata object. The SDK detects the "file_" prefix and routes through the image_ref field on the wire (mutually exclusive with image_data).

Usage

const client = createDecartClient({ apiKey });

const ref = await client.files.upload(blob);   // -> { id: "file_...", expires_at, ... }

// Realtime — pass the id string. SDK sends image_ref instead of base64.
await rt.set({ image: ref.id, prompt: "make it cinematic" });
await rt.set({ image: ref.id, prompt: "now in noir" });   // reused, no re-upload

// Or as initial state on connect:
await client.realtime.connect(stream, {
  model,
  initialState: { image: ref.id, prompt: { text: "anime style" } },
});

Changes

  • New client.files sub-client: upload(file), get(fileId), delete(fileId).
  • Realtime set_image wire message gains an optional image_ref (oneof with image_data); the internal setImage API takes a { kind: "data" | "ref" } payload.
  • setInputSchema.image and modelStateSchema.image accept a "file_..." id string; non-file_ strings still flow through imageToBase64 (data URLs, http(s) URLs, raw base64) as today.
  • 6 new unit tests for client.files, 1 new test for the realtime ref path. Updated the 5 existing realtime unit tests to match the new internal payload shape.

Note

Medium Risk
Changes realtime signaling and connect initial-state behavior for a new wire field; scope is SDK-only with tests, but incorrect ref handling could break image updates in production sessions.

Overview
Adds client.files (upload, get, delete) against POST/GET/DELETE /v1/files, with optional TTL validation and new FILES_* error codes, wired into createDecartClient.

Realtime set, setImage, and initialState.image now accept a plain file_... id: the SDK routes those through image_ref on the wire instead of base64 image_data, using an internal { kind: "data" | "ref" } payload through signaling and stream session.

The SDK test page gains a Files API panel (upload, metadata, delete, use ref as image). Unit, realtime unit, and e2e tests cover the files client and ref-based image paths.

Reviewed by Cursor Bugbot for commit 0f37b6b. Bugbot is set up for automated code reviews on this repo. Configure here.

Adds a server-managed file upload surface backed by POST /v1/files in the
bouncer. `client.files.upload(blob)` returns a `FileReference`; pass `ref.id`
to `rt.set({ image })`, `setImage(...)`, or `initialState.image` to reuse the
asset across realtime updates without re-uploading or base64'ing it every
time.

Realtime accepts the id as a plain string (callers persist the id in their
own storage; the full metadata object is not required).

Example:
  const ref = await client.files.upload(blob);
  await rt.set({ image: ref.id, prompt: "make it cinematic" });
  await rt.set({ image: ref.id, prompt: "now in noir" });   // reused
@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented May 25, 2026

Open in StackBlitz

npm i https://pkg.pr.new/@decartai/sdk@145

commit: 0f37b6b

Comment thread packages/sdk/src/realtime/stream-session.ts
@AdirAmsalem AdirAmsalem changed the title feat(files): add client.files and image_ref support in realtime feat(files): add client.files and image_ref support in realtime May 25, 2026
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 5534fd1. Configure here.

Comment thread packages/sdk/src/files/client.ts Outdated
Bugbot review: response.ok already covers 204, so the extra status !== 204
branch is dead. Simplifies to !response.ok.
Mirrors the bouncer's new ttl_seconds field. FileReference.expires_at is
now string | null since persistent uploads have no expiry.
Catches "forever" / -1 / out-of-range values at the call site instead of
after a round-trip. Matches the pattern in realtime/methods.ts where
client-side input is parsed with zod before being sent.
@AdirAmsalem AdirAmsalem merged commit c3b2f45 into main May 26, 2026
5 checks passed
@AdirAmsalem AdirAmsalem deleted the bismarck branch May 26, 2026 06:19
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