Files
OmniRoute/open-sse/executors/adobe-firefly.ts
NOXX - Commiter 26d50f1913 feat(adobe-firefly): reference image attach + /v1/images/edits (follow-up #8006) (#8510)
* feat(adobe-firefly): reference image attach + /v1/images/edits (follow-up #8006)

Upload source images to Firefly storage (POST /v2/storage/image) and attach
them as referenceBlobs on generate-async, matching live firefly.adobe.com
captures (usage:general for nano multi-ref; usage:subject for gpt-image).

Also wire built-in adobe-firefly through OpenAI-compatible POST /v1/images/edits
(multipart or JSON data URLs, up to 4 refs) so Media edit-with-references
and Open WebUI image-edit hit the same path as image2image generate.

Unit suite: tests/unit/adobe-firefly.test.ts 41/41.

* test(api): add route-level coverage for Adobe Firefly /v1/images/edits + fix typecheck/file-size drift

Covers the referenceBlobs upload path, the 4-reference cap error, and the
credentials/rate-limit branches added to the /v1/images/edits route for
adobe-firefly (#8510). Also fixes a Buffer/BodyInit typecheck mismatch in
uploadAdobeFireflyImage and corrects the adobeFireflyClient.ts file-size
baseline entry to match the gate's actual LOC count (it counts the trailing
newline, so the frozen value is 2317, not 2316), plus a testFrozen entry for
adobe-firefly.test.ts's own +159 line growth from this PR. Moves the
handleAdobeFireflyImageGeneration re-export out of the middle of the import
block in imageGeneration.ts for readability.

Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>

* fix(security): restore bounded JWT regex quantifiers dropped by edit-route refactor

The edits-route extraction (test commit 62785e972f) had accidentally
reverted 4 JWT-extraction regexes in adobeFireflyClient.ts from the
bounded {1,4096} quantifier back to unbounded +, undoing the ReDoS fix
from #8173 (CodeQL #754/#755/#756). Restored the bounded quantifiers;
behavior is unchanged (45/45 adobe-firefly tests still pass), only the
backtracking bound is back in place.

Co-authored-by: diegosouzapw <diegosouza.pw@gmail.com>

---------

Co-authored-by: ikelvingo <im.kelvinwong@gmail.com>
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
Co-authored-by: diegosouzapw <diegosouza.pw@gmail.com>
2026-07-26 03:53:10 -03:00

35 lines
1.4 KiB
TypeScript

// AdobeFireflyExecutor — chat-completions guard for the adobe-firefly
// web-cookie media provider.
//
// Adobe Firefly is image/video generation only (Firefly 3P async APIs). There
// is no chat/completions surface. Real work lives in:
// open-sse/handlers/imageGeneration/providers/adobeFirefly.ts
// open-sse/handlers/videoGeneration/adobeFireflyHandler.ts
//
// Without this executor, getExecutor("adobe-firefly") would fall through to
// DefaultExecutor and mis-route the user's IMS token / cookie to api.openai.com.
import { BaseExecutor, type ExecuteInput } from "./base.ts";
import { makeExecutorErrorResult } from "../utils/error.ts";
const ADOBE_FIREFLY_BASE_URL = "https://firefly-3p.ff.adobe.io/v2/3p-images/generate-async";
export class AdobeFireflyExecutor extends BaseExecutor {
constructor() {
super("adobe-firefly", { id: "adobe-firefly", baseUrl: ADOBE_FIREFLY_BASE_URL });
}
async execute(_input: ExecuteInput) {
return makeExecutorErrorResult(
400,
"adobe-firefly is a media-generation provider and does not support chat completions. " +
"Use POST /v1/images/generations or /v1/images/edits (e.g. model \"adobe-firefly/nano-banana-pro\") " +
"or POST /v1/videos/generations (e.g. model \"adobe-firefly/sora-2\").",
_input.body,
ADOBE_FIREFLY_BASE_URL
);
}
}
export default AdobeFireflyExecutor;