Skip to content

feat: Make Stored Upload Image Resolution Configurable - #16983

Open
RutgerLubbers wants to merge 2 commits into
LibreChat-AI:devfrom
RutgerLubbers:feat/upload-resize-config
Open

RutgerLubbers wants to merge 2 commits into
LibreChat-AI:devfrom
RutgerLubbers:feat/upload-resize-config

Conversation

@RutgerLubbers

@RutgerLubbers RutgerLubbers commented Oct 11, 2026 •

Copy link
Copy Markdown

Summary

Stored image uploads are always resized to the built-in 'high' preset (short side ≤ 768px, long side ≤ 2000px) with no way to change it. Anything that reads the stored upload is capped at that size.

This adds fileConfig.imageUploadResize to configure the stored-upload resolution:

  • high (default) / low — presets
  • { px: 2048 } — longest-edge cap, aspect ratio preserved
  • { percentage: 50 } — scale relative to the original

Implementation

The storage handlers already accept a resolution argument defaulting to 'high'; the upload path just never passed one. processImageFile now reads fileConfig.imageUploadResize and forwards it through handleImageUpload, covering every storage strategy (Local, S3, CloudFront, Azure, Firebase). resizeImageBuffer already handles { px } / { percentage }, so it is unchanged.

imageUploadResizeSchema validates the value via the existing configSchema; TImageUploadResize / ImageUploadResolution flow into the storage layer. Default remains 'high' (current behavior).

Testing

  • packages/api/src/storage/__tests__/images.test.ts — { px } resolution reaches resizeImageBuffer.
  • api/server/services/Files/process.spec.js — configured imageUploadResize is forwarded to handleImageUpload; unset defaults to 'high'.
  • packages/data-provider/specs/config-schemas.spec.ts — accepts presets and { px }/{ percentage }; rejects unknown presets, bare objects, and px: 0.

tsc --noEmit clean in packages/api and packages/data-provider; eslint/prettier clean.

Compatibility

Optional key; the default reproduces current behavior. Per-endpoint overrides are a possible follow-up.

Copilot AI balanced review requested due to automatic review settings October 11, 2026 11:40

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

Validation currently accepts invalid or ambiguous resize values, and defaulting behavior is placed in the legacy CJS layer.

4 open findings
What changed in this PR

Adds configurable server-side resizing for stored image uploads while preserving the existing high default.

Changes:

  • Adds and documents imageUploadResize configuration.
  • Propagates resize settings through upload storage handlers.
  • Adds schema and passthrough tests.
File Description
packages/​data-provider/​src/​file-config.ts Defines the resize configuration schema and type.
packages/​data-provider/​specs/​config-schemas.spec.ts Tests accepted and rejected configurations.
packages/​api/​src/​storage/​types.ts Types custom upload resolutions.
packages/​api/​src/​storage/​images.ts Accepts custom resolutions in cloud storage.
packages/​api/​src/​storage/​__tests__/​images.test.ts Tests custom resolution forwarding.
librechat.example.yaml Documents the new setting.
api/​server/​services/​Files/​process.spec.js Tests upload-path configuration forwarding.
api/​server/​services/​Files/​process.js Passes configured resolution into storage.

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread packages/api/src/storage/types.ts Outdated
Comment thread packages/data-provider/src/file-config.ts Outdated
Comment thread packages/data-provider/src/file-config.ts Outdated
Comment thread api/server/services/Files/process.js Outdated
@RutgerLubbers RutgerLubbers changed the title 🧯 feat: Make Stored Upload Image Resolution Configurable feat: Make Stored Upload Image Resolution Configurable Oct 11, 2026
@RutgerLubbers
RutgerLubbers force-pushed the feat/upload-resize-config branch from 718ea4c to d90cbce Compare October 11, 2026 12:21
Add fileConfig.imageUploadResize so deployers can pick the resolution applied
when storing image uploads: a named preset ('high' | 'low') or { px } (cap the
longest edge, keeping aspect ratio) / { percentage }. Defaults to 'high', so
existing behavior is unchanged.

processImageFile reads the value off the deployment config (mirroring the
existing draft-image `imageGeneration` consumer) and passes it to the storage
handlers; both Local's uploadLocalImage and the packages/api ImageService
already accept a resolution argument, they just never received one from the
upload path. The imageUploadResizeSchema validates the shape via the config
schema.

Why it matters: providers' image tools work on the stored upload, and
OpenAI-compatible image servers (e.g. local FLUX.2 / Qwen models) commonly size
their edit output to the input's dimensions, so this effectively caps the images
those tools produce - bigger than the built-in 'high' preset when the server can
handle it, smaller when storage or a provider's limits demand it.
Model the custom resize forms as an exclusive union in both the schema and
the storage type, so `{}` and dual-key objects (`px` + `percentage`) are
rejected instead of silently accepted or ignored.

Reject `percentage: 0`, which previously passed validation but produced
zero-sized targets that Sharp rejects at the storage layer.

Keep /api wiring-only per AGENTS.md: `processImageFile` passes
`imageUploadResize` through unchanged when unset, leaving the existing
'high' default at the storage handlers.
@RutgerLubbers
RutgerLubbers force-pushed the feat/upload-resize-config branch from d90cbce to c9bfe54 Compare October 11, 2026 13:47

This branch has not been deployed

No deployments
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.

2 participants