Skip to content

feat(tcloud): imagesEdit — OpenAI /v1/images/edits over multipart#31

Open
drewstone wants to merge 1 commit into
mainfrom
feat/images-edit
Open

feat(tcloud): imagesEdit — OpenAI /v1/images/edits over multipart#31
drewstone wants to merge 1 commit into
mainfrom
feat/images-edit

Conversation

@drewstone
Copy link
Copy Markdown
Contributor

Adds the sibling to imageGenerate so callers can drive the OpenAI image-edit / inpaint / multi-image-fusion workflow without hand-rolling a custom multipart transport. Closes the last gap blocking physim's "place this CAD design into the user's uploaded yard photo" feature.

API

```ts
import { TCloud, type ImageEditOptions } from '@tangle-network/tcloud'

await client.imagesEdit({
prompt: 'A chicken coop placed in this yard, snowy Vermont, golden hour',
image: yardPhotoBlob, // or ArrayBuffer, or {data: b64, mediaType, filename?}
mask: roiMaskPng, // optional inpainting mask
model: 'gpt-image-2', // default
n: 1,
size: '1024x1024',
quality: 'high',
response_format: 'b64_json',
})
```

`image` is polymorphic: single attachment OR an array (gpt-image-2 supports multi-image fusion — pass two reference frames + a prompt that composes them). Accepted shapes:

Where it comes from
`Blob` browser, Node 22+ `fetch().then(r => r.blob())`
`ArrayBuffer` binary reads, `response.arrayBuffer()`
`{data: base64, mediaType, filename?}` DB / disk reads where the bytes are already encoded

Transport

Mirrors the existing `transcribe()` pattern — multipart through `proxiedFetch`, `Content-Type` deleted so FormData sets its own boundary, manual `checkLimits()` + `_requestCount++` for credit accounting. cli-bridge already implements the target route (`/v1/images/edits`) and dispatches to either `router.tangle.tools` or OpenAI direct.

Why now

Used by physim's generate_concept_image once this lands — the tool currently routes through `imageGenerate` for prompt-only renders; the edit path lets it ingest a user-uploaded reference photo (yard, room, workshop) and place the proposed CAD design into it. The image stays consistent with the SCAD parameters by construction because the prompt is assembled from the same source-of-truth spec.

Version bump 0.4.6 → 0.4.7 (additive — existing surface unchanged).

Adds the sibling to `imageGenerate` so callers can drive the
edit / inpaint / multi-image composition workflow without
hand-rolling a custom transport. cli-bridge already speaks the
target route (`POST /v1/images/edits` proxied to either
`router.tangle.tools/v1/images/edits` when TANGLE_API_KEY is set
or OpenAI direct), so this is the last piece needed for the
"place this CAD design into the user's uploaded yard photo"
workflow in physim's `generate_concept_image`.

API:

  client.imagesEdit({
    prompt: "...",
    image: blob | ArrayBuffer | {data: b64, mediaType, filename?},
    mask?: <same shape>,           // inpainting mask
    model?: "gpt-image-2",         // default
    n?: 1,
    size?: "1024x1024",
    quality?: "high",
    response_format?: "b64_json",
  }) → ImageResponse

The `image` field accepts a single attachment or an array (for
gpt-image-2's multi-image fusion). Polymorphic input keeps both
browser (Blob / ArrayBuffer from `fetch().then(r => r.blob())`)
and Node-server callers (base64 strings from a DB / disk read)
ergonomic without forcing either side to do a conversion dance.

The transport mirrors the existing `transcribe()` path —
multipart/form-data through `proxiedFetch`, `Content-Type`
deleted so FormData sets the boundary, manual `checkLimits()` +
`_requestCount++` for credit accounting.

Bumps to v0.4.7. Re-exported from `index.ts` alongside the
existing image types.
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