Skip to content

fix(external-providers): admin guard, validation, locale keys#9171

Merged
lstein merged 12 commits into
invoke-ai:mainfrom
Pfannkuchensack:fix/external-provider-hardening
May 18, 2026
Merged

fix(external-providers): admin guard, validation, locale keys#9171
lstein merged 12 commits into
invoke-ai:mainfrom
Pfannkuchensack:fix/external-provider-hardening

Conversation

@Pfannkuchensack
Copy link
Copy Markdown
Collaborator

Summary

  • Require AdminUserOrDefault on POST / DELETE /external_providers/config/{id} so non-admins in multiuser mode can no longer set/reset shared credentials
  • Reject Seedream batch requests where references + init + outputs > 15 before posting, surfacing ExternalProviderCapabilityError instead of a provider-side 400
  • Surface Seedream batch item errors via provider_metadata.partial_failures and raise when every item failed, instead of silently dropping filtered results
  • Set max_reference_images=3 on Qwen Image Edit Max so the central validator enforces the documented limit before hitting DashScope
  • Add missing parameters.* locale keys (quality, background, inputFidelity, temperature, thinkingLevel, watermark, optimizePrompt) so the OpenAI, Gemini, and Seedream option panels render their labels without fallbacks

Related Issues / Discussions

https://discord.com/channels/1020123559063990373/1049495067846524939/1504485218461941770

QA Instructions

Backend tests (all pass):

uv run --extra cuda pytest \
  tests/app/services/external_generation/test_seedream_provider.py \
  tests/app/services/external_generation/test_external_generation_service.py \
  tests/app/routers/test_app_info.py

Admin guard (multiuser mode):

  1. Start the server with multiuser: true.
  2. As a non-admin user, POST /api/v1/app/external_providers/config/openai with {"api_key": "x"} → expect 403 Admin privileges required.
  3. Same call as an admin → expect 200.
  4. Repeat both for DELETE /api/v1/app/external_providers/config/{openai|gemini|alibabacloud|seedream}.
  5. Single-user mode is unchanged (system user is treated as admin).

Seedream combined limit:

  1. Configure Seedream API key, install Seedream 4.5 (or any batch model).
  2. Submit a generation with 14 reference images and num_images=15 → expect a capability error in the UI; no request reaches BytePlus.
  3. Submit with 13 references + 1 init + 1 output (= 15) → expect the request to proceed.

Seedream partial failures:

  1. Trigger a batch generation where at least one item is content-filtered (e.g. prompt that filters one of several outputs).
  2. Expect the successful images to still come back; check the queue item / logs for the partial_failures metadata entry and the warning log line.
  3. If every item is filtered, expect an ExternalProviderRequestError surfacing the provider's message.

Qwen Image Edit Max reference limit:

  1. Install the Qwen Image Edit Max starter model.
  2. Try a generation with 4 reference images → expect ExternalProviderCapabilityError ("supports at most 3 reference images") before any DashScope call.

Locale keys:

  1. Open the right-hand panel for an OpenAI, Gemini, and Seedream model.
  2. Each form label (Quality, Background, Input Fidelity, Temperature, Thinking Level, Watermark, Optimize Prompt) should resolve via i18n rather than the hard-coded English fallback (verified by inspecting parameters.* keys in en.json).

Merge Plan

Standard merge — no schema or migration changes.

Checklist

  • The PR has a short but descriptive title, suitable for a changelog
  • Tests added / updated (if applicable)
  • ❗Changes to a redux slice have a corresponding migration
  • Documentation added / updated (if applicable)
  • Updated What's New copy (if doing a release after this PR)

- Require AdminUserOrDefault on POST/DELETE /external_providers/config/{id}
  so non-admins in multiuser mode can no longer set/reset shared credentials
- Reject Seedream batch requests where references + init + outputs > 15
  before posting, surfacing ExternalProviderCapabilityError instead of a
  provider-side 400
- Surface Seedream batch item errors via provider_metadata.partial_failures
  and raise when every item failed, instead of silently dropping filtered
  results
- Set max_reference_images=3 on Qwen Image Edit Max so the central validator
  enforces the documented limit before hitting DashScope
- Add missing parameters.* locale keys (quality, background, inputFidelity,
  temperature, thinkingLevel, watermark, optimizePrompt) so the OpenAI,
  Gemini, and Seedream option panels render their labels without fallbacks
@github-actions github-actions Bot added api python PRs that change python files backend PRs that change backend files services PRs that change app services frontend PRs that change frontend files python-tests PRs that change python tests labels May 14, 2026
@JPPhoto JPPhoto self-assigned this May 14, 2026
@JPPhoto JPPhoto moved this to 6.13.x Theme: MODELS in Invoke - Community Roadmap May 14, 2026
@JPPhoto JPPhoto removed their assignment May 14, 2026
@JPPhoto
Copy link
Copy Markdown
Collaborator

JPPhoto commented May 14, 2026

I can't run tests so here's what I have:

  • invokeai/frontend/web/src/features/parameters/components/External/OpenAIProviderOptions.tsx:46 and invokeai/frontend/web/src/features/parameters/components/External/GeminiProviderOptions.tsx:65 still render provider option labels as raw English strings. PR 9171 adds the missing parameters.* label keys in invokeai/frontend/web/public/locales/en.json:1749, but the visible <option> text remains hardcoded: OpenAI uses Auto, High, Medium, Low, Transparent, Opaque, Default; Gemini uses Default, Minimal, High. In non-English locales, the field labels can now translate but the select values stay English. To expose this issue, add a frontend i18n test or lint rule that fails when TSX under external provider options renders visible parameter labels/options as raw literals instead of t(...), then convert these option labels to locale-backed keys.

Pfannkuchensack and others added 2 commits May 15, 2026 00:43
Wrap the visible <option> text in OpenAIProviderOptions and
GeminiProviderOptions with t(...) so non-English locales translate
the values alongside their <FormLabel> (previously the labels
translated but Auto/High/Medium/Low/Transparent/Opaque/Default/
Minimal stayed English). Adds the matching
parameters.{quality,background,inputFidelity,thinkingLevel}Options
keys to en.json and a colocated vitest guard that fails if any
<FormLabel> or <option> in External/*ProviderOptions.tsx contains
a raw literal instead of a {t(...)} expression.
@lstein
Copy link
Copy Markdown
Collaborator

lstein commented May 15, 2026

@JPPhoto I've run through the functional tests; have not looked at the code.

All the tests suggested in the PR description were successful:

  1. Non-admins in multi-user mode cannot set external provider credentials - WORKS
  2. Reject Seedream batch requests when the ref_images + init_image + outputs > 15. WORKS
  3. Seedream partial failures. WORKS
  4. Qwen Image Edit Max reference limit: WORKS
  5. Locale keys: WORKS

I did surface a new bug, however. When the Canvas is selected, I can drag images into the Regional Reference Image section of the canvas and create a new regional guidance layer. However, regional guidance is not supported by the external models and is disabled in the layer creation menu.

JPPhoto and others added 7 commits May 14, 2026 20:38
The Canvas drop area registered every <DndDropTarget> as long as the
canvas wasn't busy, so dragging an image onto the "Regional Reference
Image" tile created a regional_guidance layer even when the active
model didn't support it (e.g. OpenAI/Gemini/Seedream). The
layer-creation menu already disables those entries via
useIsEntityTypeEnabled, but the drop tiles bypassed that check.

Pull useIsEntityTypeEnabled into CanvasDropArea and OR each tile's
isDisabled with !isEnabled for its entity type. Same fix closes the
symmetric gaps for SD3 / CogView4 / Flux Kontext on the control-layer
and inpaint-mask tiles, mirroring the menu in one place.
Copy link
Copy Markdown
Collaborator

@lstein lstein left a comment

Choose a reason for hiding this comment

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

Drag-and-drop canvas issue has been fixed. Wait for @JPPhoto approval before merging.

@lstein lstein enabled auto-merge (squash) May 18, 2026 19:00
@lstein lstein merged commit 028c976 into invoke-ai:main May 18, 2026
17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

api backend PRs that change backend files frontend PRs that change frontend files python PRs that change python files python-tests PRs that change python tests services PRs that change app services v6.13.x

Projects

Status: 6.13.x Theme: MODELS

Development

Successfully merging this pull request may close these issues.

3 participants