fix(adobe-firefly): default gpt-image detailLevel to maximal (5) (#8863)

* fix(adobe-firefly): default gpt-image detailLevel to maximal (5)

GPT Image 2 quality is dominated by generationSettings.detailLevel (1-5).
The SPA often defaults to 3 (medium); missing/auto quality previously mapped
to 3 as well. Default now to 5 (high/max) so API clients and Media without
an explicit quality still get maximal detail. Explicit low/medium still honored.

* chore(quality): rebaseline adobeFireflyClient + changelog fragment

adobeFireflyClient.ts 2317->2322 (+5) — this PR's own growth at the existing
payload-build site. Covered by tests/unit/adobe-firefly.test.ts.

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

---------

Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
Co-authored-by: diegosouzapw <diegosouzapw@users.noreply.github.com>
This commit is contained in:
NOXX - Commiter
2026-07-28 20:37:22 +03:00
committed by GitHub
parent bf77648071
commit fff11cbb57
4 changed files with 57 additions and 8 deletions

View File

@@ -0,0 +1 @@
- **Adobe Firefly**: `gpt-image` requests now default `detailLevel` to maximal (5) instead of leaving the upstream default, so generations come back at the quality the model is capable of

View File

@@ -358,7 +358,7 @@
"open-sse/mcp-server/server.ts": 1407,
"open-sse/mcp-server/tools/advancedTools.ts": 1120,
"open-sse/services/accountFallback.ts": 1966,
"open-sse/services/adobeFireflyClient.ts": 2317,
"open-sse/services/adobeFireflyClient.ts": 2322,
"open-sse/services/claudeCodeCompatible.ts": 1202,
"open-sse/services/combo.ts": 3648,
"open-sse/services/compression/strategySelector.ts": 1060,
@@ -411,5 +411,6 @@
"_rebaseline_2026_07_28_8842_antigravity_projectid_refresh": "PR #8842 (fix/antigravity-projectid-refresh) own growth: open-sse/executors/antigravity.ts 1493->1528 (+35 = projectId discovery in refreshCredentials: import ensureAntigravityProjectAssigned + trim projectId + call ensureAntigravityProjectAssigned with 8s timeout + persistDiscoveredAntigravityProjectId + log success/failure). Irreducible wiring at the existing credential-refresh chokepoint. Covered by tests/unit/executor-antigravity.test.ts (4 new test cases).",
"_rebaseline_2026_07_28_8842_antigravity_test": "PR #8842 test growth: tests/unit/executor-antigravity.test.ts new testFrozen 1098 (4 new test cases for projectId discovery during refresh: discovers when empty, skips when set, handles failure, skips when access_token not a string). All above cap 1000 on day one.",
"_rebaseline_2026_07_28_8860_tokenrefresh_projectid": "PR #8860 (fix/antigravity-projectid-centralized) own test growth: tests/unit/token-refresh-service.test.ts 1311->1378 (+67 = 4 cases covering projectId discovery on the tokenRefresh.ts path — the Dashboard/health-check refresh route, which #8842 did not reach since that fixed the executor path). Covered by the same file.",
"_rebaseline_2026_07_28_8861_xiaomi_token_plan": "PR #8861 (feat/xiaomi-token-plan-protocol-selector) own growth: EditConnectionModal.tsx 1283->1316 (+33 = the per-connection API-protocol selector field) and open-sse/executors/base.ts 1540->1562 (+22 = alternate-format resolution at the existing buildUrl/headers chokepoint). Both are irreducible wiring at existing call sites."
"_rebaseline_2026_07_28_8861_xiaomi_token_plan": "PR #8861 (feat/xiaomi-token-plan-protocol-selector) own growth: EditConnectionModal.tsx 1283->1316 (+33 = the per-connection API-protocol selector field) and open-sse/executors/base.ts 1540->1562 (+22 = alternate-format resolution at the existing buildUrl/headers chokepoint). Both are irreducible wiring at existing call sites.",
"_rebaseline_2026_07_28_8863_firefly_detail_level": "PR #8863 (fix/adobe-firefly-gpt-detail-level-max) own growth: adobeFireflyClient.ts 2317->2322 (+5 = gpt-image detailLevel defaulting to maximal at the existing payload-build site). Covered by tests/unit/adobe-firefly.test.ts."
}

View File

@@ -660,13 +660,18 @@ export function resolveAdobeVideoModel(model: string): {
return { id: "sora-2", spec: ADOBE_FIREFLY_VIDEO_MODELS["sora-2"] };
}
/**
* Map OpenAI/VibeProxy quality tiers onto Firefly gpt-image `generationSettings.detailLevel`.
* Wire range is integer 15 (discovery schema). Default is **maximal (5)** —
* the SPA often defaults to 3, but detail is critical for GPT Image 2 output quality.
* Explicit low/medium still honor the caller's choice.
*/
function gptDetailLevel(quality: unknown): number {
// Live firefly.adobe.com default for gpt-image is detailLevel 3 (medium).
const q = String(quality ?? "medium").trim().toLowerCase();
if (q === "high" || q === "4k" || q === "ultra") return 5;
if (q === "low" || q === "1k") return 1;
if (q === "medium" || q === "2k" || q === "standard" || q === "hd" || q === "auto") return 3;
return 3;
const q = String(quality ?? "high").trim().toLowerCase();
if (q === "low" || q === "1k" || q === "1") return 1;
if (q === "medium" || q === "2k" || q === "standard" || q === "hd" || q === "3") return 3;
// high / 4k / ultra / auto / empty / unknown → max detail
return 5;
}
export function buildAdobeImagePayload(opts: {

View File

@@ -190,6 +190,48 @@ test("buildAdobeImagePayload produces nano and gpt-image shapes", () => {
assert.equal((gpt.modelSpecificPayload as Record<string, unknown>).size, "auto");
assert.equal(gpt.size, undefined);
assert.equal(gpt.outputResolution, undefined);
// Missing / auto quality → maximal detail (5). Explicit low/medium still honored.
const gptDefault = buildAdobeImagePayload({
prompt: "a dog",
aspectRatio: "1:1",
outputResolution: "1K",
modelSpec: ADOBE_FIREFLY_IMAGE_MODELS["gpt-image-2"],
});
assert.equal((gptDefault.generationSettings as Record<string, unknown>).detailLevel, 5);
const gptAuto = buildAdobeImagePayload({
prompt: "a dog",
aspectRatio: "1:1",
outputResolution: "1K",
modelSpec: ADOBE_FIREFLY_IMAGE_MODELS["gpt-image"],
quality: "auto",
});
assert.equal((gptAuto.generationSettings as Record<string, unknown>).detailLevel, 5);
const gptLow = buildAdobeImagePayload({
prompt: "a dog",
aspectRatio: "1:1",
outputResolution: "1K",
modelSpec: ADOBE_FIREFLY_IMAGE_MODELS["gpt-image"],
quality: "low",
});
assert.equal((gptLow.generationSettings as Record<string, unknown>).detailLevel, 1);
const gptMedium = buildAdobeImagePayload({
prompt: "a dog",
aspectRatio: "1:1",
outputResolution: "1K",
modelSpec: ADOBE_FIREFLY_IMAGE_MODELS["gpt-image"],
quality: "medium",
});
assert.equal((gptMedium.generationSettings as Record<string, unknown>).detailLevel, 3);
// Firefly UI resolution tiers map onto the same detailLevel scale.
const gpt4k = buildAdobeImagePayload({
prompt: "a dog",
aspectRatio: "1:1",
outputResolution: "1K",
modelSpec: ADOBE_FIREFLY_IMAGE_MODELS["gpt-image"],
quality: "4k",
});
assert.equal((gpt4k.generationSettings as Record<string, unknown>).detailLevel, 5);
});
test("buildAdobeImagePayload attaches referenceBlobs like live adobe_atach_images capture", () => {