mirror of
https://github.com/invoke-ai/InvokeAI.git
synced 2026-04-23 03:00:31 -04:00
main
1495 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
3e318614b6 |
translationBot(ui): update translation (Italian) (#9078)
Currently translated at 97.2% (2521 of 2592 strings) Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ Translation: InvokeAI/Web UI Co-authored-by: Riccardo Giovanetti <riccardo.giovanetti@gmail.com> |
||
|
|
b2d79dc86c |
feat:(model-manager) add sorting capabilities for models (#9024)
* feat(model-manager): add comprehensive sorting capabilities for models dded the ability to sort models in the Model Manager by various attributes including Name, Base, Type, Format, Size, Date Added, and Date Modified. Supports both ascending and descending order. - Backend: Added `order_by` and `direction` query parameters to the ``/api/v1/models`/` listing endpoint. Implemented case-insensitive sorting in the SQLite model records service. - Frontend: Introduced `<ModelSortControl />` UI, updated Redux slices to manage sort state, removed client-side entity adapter sorting to respect server-side ordering, and added i18n localization keys. - Tests: Added test coverage for SQL-based sorting on size and name. * feat(model-manager): add comprehensive sorting capabilities for models dded the ability to sort models in the Model Manager by various attributes including Name, Base, Type, Format, Size, Date Added, and Date Modified. Supports both ascending and descending order. - Backend: Added `order_by` and `direction` query parameters to the ``/api/v1/models`/` listing endpoint. Implemented case-insensitive sorting in the SQLite model records service. - Frontend: Introduced `<ModelSortControl />` UI, updated Redux slices to manage sort state, removed client-side entity adapter sorting to respect server-side ordering, and added i18n localization keys. - Tests: Added test coverage for SQL-based sorting on size and name. * ruff fix * typegen fix * typegen fix - this time without my custom nodes. * another typegen fix * refactor(ui): consolidate model filter and sort controls into a unified menu - Replaced separate `ModelSortControl` and `ModelTypeFilter` components with a single, unified "Filtering" dropdown menu. - Organised filtering options into categorised submenus in the following order: Direction, Sort By, and Model Type. - Enhanced submenu labels to display the currently active selection inline for quick reference. - Improved visual alignment within menus by using hidden checkmarks on unselected items, ensuring consistent indentation across all options. - Resolved styling and linting issues (unused variables, JSX bind warnings) within the new component. * Lint fix * Addresses PR feedback to use translation strings directly within `ORDER_BY_OPTIONS`. Previously, sort keys and their translated labels were maintained in separate constructs (`ORDER_BY_OPTIONS` array and `ORDER_BY_LABELS` map). This refactor converts `ORDER_BY_OPTIONS` into an array of objects containing both the `key` and its corresponding `i18nKey`, creating a single source of truth. This change: - Simplifies the `SortBySubMenu` component by removing the redundant `ORDER_BY_LABELS` lookup map. - Improves maintainability by ensuring developers only need to update one place when adding or modifying sort options. - Reduces the risk of mismatched keys and labels. --------- Co-authored-by: Jonathan <34005131+JPPhoto@users.noreply.github.com> Co-authored-by: Alexander Eichhorn <alex@eichhorn.dev> Co-authored-by: Lincoln Stein <lincoln.stein@gmail.com> |
||
|
|
c550ce31a9 |
fix(ui): FLUX.2 Klein VAE/Qwen3 readiness checks and diffusers source auto-detection (#9041)
* fix(ui): FLUX.2 Klein VAE/Qwen3 readiness checks and diffusers source auto-detection Fix several issues with FLUX.2 Klein model handling: 1. Add readiness validation for non-diffusers Klein models so the invoke button is disabled when required VAE/Qwen3 submodels are missing. 2. Auto-detect installed diffusers flux2 models and pass them as qwen3_source_model in the graph builder, so GGUF/safetensors models can extract VAE and encoder from an available diffusers model. 3. Use variant-aware matching so Klein 9B models pick a 9B diffusers source (not 4B), preventing Qwen3 encoder dimension mismatches. 4. Change placeholder text from "From main model" to "From diffusers model" or "No diffusers model available" depending on availability. 5. Export readiness check functions and add comprehensive tests for both the graph builder and readiness logic. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Chore Fix merge * fix(ui): unify FLUX.2 Klein Qwen3 variant matching Extract KLEIN_TO_QWEN3_VARIANT_MAP and isFlux2KleinQwen3Compatible into features/parameters/util/flux2Klein so UI placeholder, readiness check, and graph builder share one rule. Accepts klein_9b and klein_9b_base as mutual Qwen3 sources (both use qwen3_8b) and guards against undefined === undefined false positives. Use zModelIdentifierField.parse for qwen3_source_model construction in buildFLUXGraph, matching the pattern used for Z-Image. --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Co-authored-by: Alexander Eichhorn <alex@eichhorn.dev> |
||
|
|
eaa42bf63e |
Chore: Code cleanup (#8998)
Co-authored-by: Alexander Eichhorn <alex@eichhorn.dev> |
||
|
|
5867556769 |
feat(canvas): add per-layer lock transparency option (#8943)
Add a "Lock Transparency" toggle to raster layers that preserves the alpha channel when painting. When enabled, brush strokes use 'source-atop' compositing to only paint on existing non-transparent pixels, similar to Photoshop's "Lock Transparent Pixels" feature. Co-authored-by: dunkeroni <dunkeroni@gmail.com> |
||
|
|
9deb545cc1 |
External models (Gemini Nano Banana & OpenAI GPT Image) (#8633) (#8884)
* feat: initial external model support * feat: support reference images for external models * fix: sorting lint error * chore: hide Reidentify button for external models * review: enable auto-install/remove fro external models * feat: show external mode name during install * review: model descriptions * review: implemented review comments * review: added optional seed control for external models * chore: fix linter warning * review: save api keys to a seperate file * docs: updated external model docs * chore: fix linter errors * fix: sync configured external starter models on startup * feat(ui): add provider-specific external generation nodes * feat: expose external panel schemas in model configs * feat(ui): drive external panels from panel schema * docs: sync app config docstring order * feat: add gemini 3.1 flash image preview starter model * feat: update gemini image model limits * fix: resolve TypeScript errors and move external provider config to api_keys.yaml Add 'external', 'external_image_generator', and 'external_api' to Zod enum schemas (zBaseModelType, zModelType, zModelFormat) to match the generated OpenAPI types. Remove redundant union workarounds from component prop types and Record definitions. Fix type errors in ModelEdit (react-hook-form Control invariance), parsing.tsx (model identifier narrowing), buildExternalGraph (edge typing), and ModelSettings import/export buttons. Move external_gemini_base_url and external_openai_base_url into api_keys.yaml alongside the API keys so all external provider config lives in one dedicated file, separate from invokeai.yaml. * feat: add resolution presets and imageConfig support for Gemini 3 models Add combined resolution preset selector for external models that maps aspect ratio + image size to fixed dimensions. Gemini 3 Pro and 3.1 Flash now send imageConfig (aspectRatio + imageSize) via generationConfig instead of text-based aspect ratio hints used by Gemini 2.5 Flash. Backend: ExternalResolutionPreset model, resolution_presets capability field, image_size on ExternalGenerationRequest, and Gemini provider imageConfig logic. Frontend: ExternalSettingsAccordion with combo resolution select, dimension slider disabling for fixed-size models, and panel schema constraint wiring for Steps/Guidance/Seed controls. * Remove unused external model fields and add provider-specific parameters - Remove negative_prompt, steps, guidance, reference_image_weights, reference_image_modes from external model nodes (unused by any provider) - Remove supports_negative_prompt, supports_steps, supports_guidance from ExternalModelCapabilities - Add provider_options dict to ExternalGenerationRequest for provider-specific parameters - Add OpenAI-specific fields: quality, background, input_fidelity - Add Gemini-specific fields: temperature, thinking_level - Add new OpenAI starter models: GPT Image 1.5, GPT Image 1 Mini, DALL-E 3, DALL-E 2 - Fix OpenAI provider to use output_format (GPT Image) vs response_format (DALL-E) and send model ID in requests - Add fixed aspect ratio sizes for OpenAI models (bucketing) - Add ExternalProviderRateLimitError with retry logic for 429 responses - Add provider-specific UI components in ExternalSettingsAccordion - Simplify ParamSteps/ParamGuidance by removing dead external overrides - Update all backend and frontend tests * Chore Ruff check & format * Chore typegen * feat: full canvas workflow integration for external models - Add missing aspect ratios (4:5, 5:4, 8:1, 4:1, 1:4, 1:8) to type system for external model support - Sync canvas bbox when external model resolution preset is selected - Use params preset dimensions in buildExternalGraph to prevent "unsupported aspect ratio" errors - Lock all bbox controls (resize handles, aspect ratio select, width/height sliders, swap/optimal buttons) for external models with fixed dimension presets - Disable denoise strength slider for external models (not applicable) - Sync bbox aspect ratio changes back to paramsSlice for external models - Initialize bbox dimensions when switching to an external model * Chore typegen Linux seperator * feat: full canvas workflow integration for external models - Update buildExternalGraph test to include dimensions in mock params * Merge remote-tracking branch 'upstream/main' into external-models * Chore pnpm fix * add missing parameter * docs: add External Models guide with Gemini and OpenAI provider pages * fix(external-models): address PR review feedback - Gemini recall: write temperature, thinking_level, image_size to image metadata; wire external graph as metadata receiver; add recall handlers. - Canvas: gate regional guidance, inpaint mask, and control layer for external models. - Canvas: throw a clear error on outpainting for external models (was falling back to inpaint and hitting an API-side mask/image size mismatch). - Workflow editor: add ui_model_provider_id filter so OpenAI and Gemini nodes only list their own provider's models. - Workflow editor: silently drop seed when the selected model does not support it instead of raising a capability error. - Remove the legacy external_image_generation invocation and the graph-builder fallback; providers must register a dedicated node. - Regenerate schema.ts. - remove Gemini debug dumps to outputs/external_debug * fix(external-models): resolve TSC errors in metadata parsing and external graph - Export imageSizeChanged from paramsSlice (required by the new ImageSize recall handler). - Emit the external graph's metadata model entry via zModelIdentifierField since ExternalApiModelConfig is not part of the AnyModelConfig union. * chore: prettier format ModelIdentifierFieldInputComponent * fix: remove unsupported thinkingConfig from Gemini image models and restrict GPT Image models to txt2img * chore typegen * chore(docs): regenerate settings.json for external provider fields * fix(external): fix mask handling and mode support for external providers - Remove img2img and inpaint modes from Gemini models (Gemini has no bitmap mask or dedicated edit API; image editing works via reference images in the UI) - Fix DALL-E 2 inpainting: convert grayscale mask to RGBA with alpha channel transparency (OpenAI expects transparent=edit area) and convert init image to RGBA when mask is present * fix(external): update mode support and UI for external providers - Remove DALL-E 2 from starter models (deprecated, shutdown May 12 2026) - Enable img2img for GPT Image 1/1.5/1-mini (supports edits endpoint) - Set Gemini models to txt2img only (no mask/edit API; editing via ref images) - Hide mode/init_image/mask_image fields on Gemini node (not usable) - Hide mask_image field on OpenAI node (no model supports inpaint) * Chore typegen * fix(external): improve OpenAI node UX and disable cache by default - Hide OpenAI node's mode and init_image fields: OpenAI's API has no img2img/inpaint distinction (the edits endpoint is invoked automatically when reference images are provided). init_image is functionally identical to a reference image and was misleading users. - Default use_cache to False for external image generation nodes: external API calls are non-deterministic and incur usage costs. Cache hits returned stale image references that did not produce new gallery entries on repeat invokes. * fix(external): duplicate cached images on cache hit instead of skipping External image generation nodes use the standard invocation cache, but returning the cached output (with stale image_name references) on cache hits resulted in no new gallery entries — the Invoke button would spin indefinitely on repeat invokes with identical parameters. Override invoke_internal so that on cache hit, the cached images are loaded and re-saved as new gallery entries. The expensive API call is still skipped (cost saving), but the user sees a new image as expected. * Chore typegen + ruff * CHore ruff format * fix(external): restore OpenAI advanced settings on Remix recall Remix recall iterates through ImageMetadataHandlers but only Gemini's temperature handler was wired up — OpenAI's quality, background, and input_fidelity were stored in image metadata but never parsed back into the params slice. Add the three missing handlers so Remix restores these settings as expected. --------- Co-authored-by: Alexander Eichhorn <alex@eichhorn.dev> Co-authored-by: Alexander Eichhorn <alex@code-with.us> Co-authored-by: Lincoln Stein <lincoln.stein@gmail.com> |
||
|
|
6d5a788f76 |
ui: translations update from weblate (#9075)
* translationBot(ui): update translation (Italian) Currently translated at 98.0% (2205 of 2250 strings) Co-authored-by: Riccardo Giovanetti <riccardo.giovanetti@gmail.com> Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ Translation: InvokeAI/Web UI * translationBot(ui): update translation files Updated by "Remove blank strings" hook in Weblate. Co-authored-by: Hosted Weblate <hosted@weblate.org> Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/ Translation: InvokeAI/Web UI * translationBot(ui): update translation (Italian) Currently translated at 97.8% (2210 of 2259 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Italian) Currently translated at 97.8% (2224 of 2272 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Italian) Currently translated at 98.1% (2252 of 2295 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Italian) Currently translated at 98.0% (2264 of 2309 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Russian) Currently translated at 60.7% (1419 of 2334 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/ru/ * translationBot(ui): update translation (Italian) Currently translated at 98.1% (2290 of 2334 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Italian) Currently translated at 97.7% (2319 of 2372 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Italian) Currently translated at 97.7% (2327 of 2380 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Italian) Currently translated at 97.7% (2328 of 2382 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Italian) Currently translated at 97.5% (2370 of 2429 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Finnish) Currently translated at 1.5% (37 of 2429 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/fi/ * translationBot(ui): update translation (Italian) Currently translated at 97.5% (2373 of 2433 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Japanese) Currently translated at 87.1% (2120 of 2433 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/ja/ * translationBot(ui): update translation (Italian) Currently translated at 97.5% (2374 of 2433 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Japanese) Currently translated at 92.2% (2244 of 2433 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/ja/ * translationBot(ui): update translation (Italian) Currently translated at 97.5% (2374 of 2433 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Spanish) Currently translated at 29.4% (720 of 2444 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/es/ * translationBot(ui): update translation (Italian) Currently translated at 97.6% (2405 of 2464 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Italian) Currently translated at 97.2% (2471 of 2540 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Italian) Currently translated at 97.1% (2476 of 2548 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Japanese) Currently translated at 90.7% (2352 of 2592 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/ja/ * translationBot(ui): update translation (German) Currently translated at 49.6% (1288 of 2592 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/de/ * translationBot(ui): update translation (Italian) Currently translated at 97.1% (2519 of 2592 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ --------- Co-authored-by: Riccardo Giovanetti <riccardo.giovanetti@gmail.com> Co-authored-by: DustyShoe <warukeichi@gmail.com> Co-authored-by: Ilmari Laakkonen <ilmarille@gmail.com> Co-authored-by: 嶋田豪介 <shimada_gosuke@cyberagent.co.jp> Co-authored-by: Lucas Prone <sac2087@gmail.com> Co-authored-by: Gohsuke Shimada <ghoskay@gmail.com> Co-authored-by: Alexander Eichhorn <pfannkuchensack@einfach-doof.de> |
||
|
|
37ff6c3743 |
ui: translations update from weblate (#9036)
* translationBot(ui): update translation (Italian) Currently translated at 98.0% (2205 of 2250 strings) Co-authored-by: Riccardo Giovanetti <riccardo.giovanetti@gmail.com> Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ Translation: InvokeAI/Web UI * translationBot(ui): update translation files Updated by "Remove blank strings" hook in Weblate. Co-authored-by: Hosted Weblate <hosted@weblate.org> Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/ Translation: InvokeAI/Web UI * translationBot(ui): update translation (Italian) Currently translated at 97.8% (2210 of 2259 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Italian) Currently translated at 97.8% (2224 of 2272 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Italian) Currently translated at 98.1% (2252 of 2295 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Italian) Currently translated at 98.0% (2264 of 2309 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Russian) Currently translated at 60.7% (1419 of 2334 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/ru/ * translationBot(ui): update translation (Italian) Currently translated at 98.1% (2290 of 2334 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Italian) Currently translated at 97.7% (2319 of 2372 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Italian) Currently translated at 97.7% (2327 of 2380 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Italian) Currently translated at 97.7% (2328 of 2382 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Italian) Currently translated at 97.5% (2370 of 2429 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Finnish) Currently translated at 1.5% (37 of 2429 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/fi/ * translationBot(ui): update translation (Italian) Currently translated at 97.5% (2373 of 2433 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Japanese) Currently translated at 87.1% (2120 of 2433 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/ja/ * translationBot(ui): update translation (Italian) Currently translated at 97.5% (2374 of 2433 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Japanese) Currently translated at 92.2% (2244 of 2433 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/ja/ * translationBot(ui): update translation (Italian) Currently translated at 97.5% (2374 of 2433 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Spanish) Currently translated at 29.4% (720 of 2444 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/es/ * translationBot(ui): update translation (Italian) Currently translated at 97.6% (2405 of 2464 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Italian) Currently translated at 97.2% (2471 of 2540 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Italian) Currently translated at 97.1% (2476 of 2548 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ --------- Co-authored-by: Riccardo Giovanetti <riccardo.giovanetti@gmail.com> Co-authored-by: DustyShoe <warukeichi@gmail.com> Co-authored-by: Ilmari Laakkonen <ilmarille@gmail.com> Co-authored-by: 嶋田豪介 <shimada_gosuke@cyberagent.co.jp> Co-authored-by: Lucas Prone <sac2087@gmail.com> |
||
|
|
acd4157bdf |
feat(ui): add canvas project save/load (.invk format) (#8917)
* feat(ui): add canvas project save/load (.invk format) Add ZIP-based .invk file format to save and restore the entire canvas state including all layers, masks, reference images, generation parameters, LoRAs, and embedded image files. Images are deduplicated on load - only missing images are re-uploaded from the project file. - Always clear LoRAs on project load, even when project has none - Fix jszip dependency ordering in package.json - Add useAssertSingleton to SaveCanvasProjectDialog for consistency - Add concurrency limit (max 5) for image fetch/upload requests - Remove redundant deep-clone in remapCroppableImage (mutate in-place) - Default project name to "Canvas Project" instead of empty string * Chore pnpm fix |
||
|
|
06a1881bbd |
feat(ui): group nodes by category in add-node dialog (#8912)
* feat(ui): group nodes by category in add-node dialog Add collapsible category grouping to the node picker command palette. Categories are parsed from the backend schema and displayed as expandable sections with caret icons. All categories auto-expand when searching. * feat(ui): add toggle for category grouping in add-node dialog and prioritize exact matches Add a persistent "Group Nodes by Category" setting to workflow editor settings, allowing users to switch between grouped and flat node list views. Also sort exact title matches to the top when searching. * fix: update test schema categories to match expected templates * feat: add expand/collapse all buttons to node picker and fix node categories Add "Expand All" and "Collapse All" link-buttons above the grouped category list in the add-node dialog so users can quickly open or close all categories at once. Buttons are hidden during search since categories auto-expand while searching. Fix two miscategorized nodes: Z-Image ControlNet was in "Control" instead of "Controlnet", and Upscale (RealESRGAN) was in "Esrgan" instead of "Upscale". * refactor(nodes): clean up node category taxonomy Reorganize all built-in invocation categories into a consistent set of 18 groups (model, prompt, conditioning, controlnet_preprocessors, latents, image, mask, inpaint, tiles, upscale, segmentation, math, strings, primitives, batch, metadata, multimodal, canvas). - Move denoise/i2l/l2i nodes consistently into "latents" - Move all mask creation/manipulation nodes into "mask" - Split ControlNet preprocessors out of "controlnet" into their own group - Fold "unet", "vllm", "string", "ip_adapter", "t2i_adapter" into larger groups - Move metadata_linked denoise wrappers from "latents" to "metadata" - Add missing category to ideal_size - Introduce dedicated "canvas" group for canvas/output/panel nodes Also adds the now-required `category` field to invocation template fixtures in validateConnection.test.ts. * Chore Ruff Format --------- Co-authored-by: dunkeroni <dunkeroni@gmail.com> |
||
|
|
441821ca03 |
Feat(canvas): Add Lasso Tool with Freehand and Polygon modes (#8908)
* Feat(Canvas): Add Lasso tool with Freehand and Polygon modes * Refine Lasso modes behavior and optimisation. * Fix: Pettier * added docs/features/Lasso_tool.md * Fix: Removed restrictions mentioned in PR's conversation: 1. Disabled when there is no visible raster content 2. Lasso is blocked when all inpaint masks are globally hidden. --------- Co-authored-by: dunkeroni <dunkeroni@gmail.com> |
||
|
|
9d62bfdf8e |
Feature: Add optional setting to prune queue on startup (#8861)
* Add more settings to invokeai.yaml for improved queue management. * Adjusted description * More logic tweaking * chore(api): update generated schema types * chore(api): update generated schema types * Add: UI element for max_queue_history to 'Settings' modal. Now it is possible to set Max queue history in both places: .yaml and UI. * chore(api): regenerate schema types * chore(api): normalize generated schema path defaults --------- Co-authored-by: dunkeroni <dunkeroni@gmail.com> |
||
|
|
dd056067a9 |
Added workflow connectors (#9027)
* Add persisted workflow connectors * Polish workflow connector menu and visuals * Refine connector sizing and alignment * Fix connector deletion and unresolved constraints * Format connector deletion tests * Revert frontend test config tweaks * Address workflow connector review feedback * Format workflow flow menu memo |
||
|
|
33ec16deb4 |
Feature: Shared/private workflows and image boards in multiuser mode (#9018)
* feat: Per-user workflow libraries in multiuser mode (#114) * Add per-user workflow isolation: migration 28, service updates, router ownership checks, is_public endpoint, schema regeneration, frontend UI Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * feat: add shared workflow checkbox to Details panel, auto-tag, gate edit/delete, fix tests Co-authored-by: lstein <111189+lstein@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Restrict model sync to admin users only (#118) Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * feat: distinct splash screens for admin/non-admin users in multiuser mode (#116) Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Disable Save when editing another user's shared workflow in multiuser mode (#120) * Disable Save when editing another user's shared workflow in multiuser mode Co-authored-by: lstein <111189+lstein@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * chore(app): ruff * Add board visibility (private/shared/public) feature with tests and UI Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Enforce read-only access for non-owners of shared/public boards in UI Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Fix remaining board access enforcement: invoke icon, drag-out, change-board filter, archive Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * fix: allow drag from shared boards to non-board targets (viewer, ref image, etc.) Previously, images in shared boards owned by another user could not be dragged at all — the draggable setup was completely skipped in GalleryImage.tsx when canWriteImages was false. This blocked ALL drop targets including the viewer, reference image pane, and canvas. Now images are always draggable. The board-move restriction is enforced in the dnd target isValid functions instead: - addImageToBoardDndTarget: rejects moves from shared boards the user doesn't own (unless admin or board is public) - removeImageFromBoardDndTarget: same check Other drop targets (viewer, reference images, canvas, comparison, etc.) remain fully functional for shared board images. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(security): add auth requirement to all sensitive routes in multimodal mode * chore(backend): ruff * fix (backend): improve user isolation for session queue and recall parameters - Sanitize session queue information of all cross-user fields except for the timestamps and status. - Recall parameters are now user-scoped. - Queue status endpoints now report user-scoped activity rather than global activity - Tests added: TestSessionQueueSanitization (4 tests): 1. test_owner_sees_all_fields - Owner sees complete queue item data 2. test_admin_sees_all_fields - Admin sees complete queue item data 3. test_non_owner_sees_only_status_timestamps_errors - Non-owner sees only item_id, queue_id, status, and timestamps; everything else is redacted 4. test_sanitization_does_not_mutate_original - Sanitization doesn't modify the original object TestRecallParametersIsolation (2 tests): 5. test_user1_write_does_not_leak_to_user2 - User1's recall params are not visible in user2's client state 6. test_two_users_independent_state - Both users can write recall params independently without overwriting each other fix(backend): queue status endpoints report user-scoped stats rather than global stats * fix(workflow): do not filter default workflows in multiuser mode Problem: When categories=['user', 'default'] (or no category filter) and user_id was set for multiuser scoping, the SQL query became WHERE category IN ('user', 'default') AND user_id = ?, which excluded default workflows (owned by "system"). Fix: Changed user_id = ? to (user_id = ? OR category = 'default') in all 6 occurrences across workflow_records_sqlite.py — in get_many, counts_by_category, counts_by_tag, and get_all_tags. Default workflows are now always visible regardless of user scoping. Tests added (2): - test_default_workflows_visible_when_listing_user_and_default — categories=['user','default'] includes both - test_default_workflows_visible_when_no_category_filter — no filter still shows defaults * fix(multiuser): scope queue/recall/intermediates endpoints to current user Several read-only and event-emitting endpoints were leaking aggregate cross-user activity in multiuser mode: - recall_parameters_updated event was broadcast to every queue subscriber. Added user_id to the event and routed it to the owner + admin rooms only. - get_queue_status, get_batch_status, counts_by_destination and get_intermediates_count now scope counts to the calling user (admins still see global state). Removed the now-redundant user_pending/user_in_progress fields and simplified QueueCountBadge. - get_queue_status hides current item_id/session_id/batch_id when the current item belongs to another user. Also fixes test_session_queue_sanitization assertions that lagged behind the recently expanded redaction set. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * chore(backend): ruff * fix(multiuser): reject anonymous websockets and scope queue item events Close three cross-user leaks in the websocket layer: - _handle_connect() now rejects connections without a valid JWT in multiuser mode (previously fell through to user_id="system"), so anonymous clients can no longer subscribe to queue rooms and observe other users' activity. In single-user mode it still accepts as system admin. - _handle_sub_queue() no longer silently falls back to the system user for an unknown sid in multiuser mode; it refuses the subscription. - QueueItemStatusChangedEvent and BatchEnqueuedEvent are now routed to user:{user_id} + admin rooms instead of the full queue room. Both events carry unsanitized user_id, batch_id, origin, destination, session_id, and error metadata and must not be broadcast. - BatchEnqueuedEvent gains a user_id field; emit_batch_enqueued and enqueue_batch thread it through. New TestWebSocketAuth suite covers connect accept/reject for both modes, sub_queue refusal, and private routing of the queue item and batch events (plus a QueueClearedEvent sanity check). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(multiuser): verify user record on websocket connect A deleted or deactivated user with an unexpired JWT could still open a websocket and subscribe to queue rooms. Now _handle_connect() checks the backing user record (exists + is_active) in multiuser mode, mirroring the REST auth path in auth_dependencies.py. Fails closed if the user service is unavailable. Tests: added deleted-user and inactive-user rejection tests; updated valid-token test to create the user in the database first. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(multiuser): close bulk download cross-user exfiltration path Backend: - POST /download now validates image read access (per-image) and board read access (per-board) before queuing the download. - GET /download/{name} is intentionally unauthenticated because the browser triggers it via <a download> which cannot carry Authorization headers. Access control relies on POST-time checks, UUID filename unguessability, private socket event routing, and single-fetch deletion. - Added _assert_board_read_access() helper to images router. - Threaded user_id through bulk download handler, base class, event emission, and BulkDownloadEventBase so events carry the initiator. - Bulk download service now tracks download ownership via _download_owners dict (cleaned up on delete). - Socket bulk_download room subscription restricted to authenticated sockets in multiuser mode. - Added error-catching in FastAPIEventService._dispatch_from_queue to prevent silent event dispatch failures. Frontend: - Fixed pre-existing race condition where the "Preparing Download" toast from the POST response overwrote the "Ready to Download" toast from the socket event (background task completes in ~17ms, so the socket event can arrive before Redux processes the HTTP response). Toast IDs are now distinct: "preparing:{name}" vs "{name}". - bulk_download_complete/error handlers now dismiss the preparing toast. Tests (8 new): - Bulk download by image names rejected for non-owner (403) - Bulk download by image names allowed for owner (202) - Bulk download from private board rejected (403) - Bulk download from shared board allowed (202) - Admin can bulk download any images (202) - Bulk download events carry user_id - Bulk download event emitted to download room - GET /download unauthenticated returns 404 for unknown files Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(multiuser): enforce board visibility on image listing endpoints GET /api/v1/images?board_id=... and GET /api/v1/images/names?board_id=... passed board_id directly to the SQL layer without checking board visibility. The SQL only applied user_id filtering for board_id="none" (uncategorized images), so any authenticated user who knew a private board ID could enumerate its images. Both endpoints now call _assert_board_read_access() before querying, returning 403 unless the caller is the board owner, an admin, or the board is Shared/Public. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * chore(backend): ruff * fix(multiuser): require image ownership when adding images to boards add_image_to_board and add_images_to_board only checked write access to the destination board, never verifying that the caller owned the source image. An attacker could add a victim's image to their own board, then exploit the board-ownership fallback in _assert_image_owner to gain delete/patch/star/unstar rights on the image. Both endpoints now call _assert_image_direct_owner which requires direct image ownership (image_records.user_id) or admin — board ownership is intentionally not sufficient, preventing the escalation chain. Also fixed a pre-existing bug where HTTPException from the inner loop in add_images_to_board was caught by the outer except-Exception and returned as 500 instead of propagating the correct status code. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * chore(backend): ruff * fix(multiuser): validate image access in recall parameter resolution The recall endpoint loaded image files and ran ControlNet preprocessors on any image_name supplied in control_layers or ip_adapters without checking that the caller could read the image. An attacker who knew another user's image UUID could extract dimensions and, for supported preprocessors, mint a derived processed image they could then fetch. Added _assert_recall_image_access() which validates read access for every image referenced in the request before any resolution or processing occurs. Access is granted to the image owner, admins, or when the image sits on a Shared/Public board. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(multiuser): require admin auth on model install job endpoints list_model_installs, get_model_install_job, pause, resume, restart_failed, and restart_file were unauthenticated — any caller who could reach the API could view sensitive install job fields (source, local_path, error_traceback) and interfere with installation state. All six endpoints now require AdminUserOrDefault, consistent with the neighboring cancel and prune routes. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(multiuser): close bulk download exfiltration and additional review findings Bulk download capability token exfiltration: - Socket events now route to user:{user_id} + admin rooms instead of the shared 'default' room (the earlier toast race that blocked this approach was fixed in a prior commit). - GET /download/{name} re-requires CurrentUserOrDefault and enforces ownership via get_owner(). - Frontend download handler replaced <a download> (which cannot carry auth headers) with fetch() + Authorization header + programmatic blob download. Additional fixes from reviewer tests: - Public boards now grant write access in _assert_board_write_access and mutation rights in _assert_image_owner (BoardVisibility.Public). - Uncategorized image listing (GET /boards/none/image_names) now filters to the caller's images only, preventing cross-user enumeration. - board_images router uses board_image_records.get_board_for_image() instead of images.get_dto() to avoid dependency on image_files service. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(multiuser): add user_id scoping to workflow SQL mutations Defense-in-depth: the route layer already checks ownership before calling update/delete/update_is_public/update_opened_at, but the SQL statements did not include AND user_id = ?, so a bypass of the route check would allow cross-user mutations. All four methods now accept an optional user_id parameter. When provided, the SQL WHERE clause is scoped to that user. The route layer passes current_user.user_id for non-admin callers and None for admins. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(multiuser): allow non-owner uploads to public boards upload_image() blocked non-owner uploads even to public boards. The board write check now allows uploads when board_visibility is Public, consistent with the public-board semantics in _assert_board_write_access and _assert_image_owner. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com> Co-authored-by: lstein <111189+lstein@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Co-authored-by: Jonathan <34005131+JPPhoto@users.noreply.github.com> |
||
|
|
b42274a57e | Feat[model support]: Qwen Image — full pipeline with edit, generate LoRA, GGUF, quantization, and UI (#9000) | ||
|
|
a3507121da |
feat: add configurable shift parameter for Z-Image (#9004)
* feat: add configurable shift parameter for Z-Image sigma schedule Add a shift (mu) override to the Z-Image denoise invocation and expose it in the UI. When left blank, shift is auto-calculated from image dimensions (existing behavior). Users can override to fine-tune the timestep schedule, with an inline X button to reset back to auto. * refactor: switch Z-Image sigma schedule from exponential to linear time shift Use shift directly as a linear multiplier instead of exp(mu), giving more predictable and uniform control over the timestep schedule. Auto-calculated values are converted via exp(mu) to preserve identical default behavior. * feat: recall Z-Image shift parameter from metadata Write z_image_shift into graph metadata and add a ZImageShift recall handler so the shift override can be restored from previously generated images. Auto-mode (null) is omitted from metadata to avoid persisting a stale value. --------- Co-authored-by: Lincoln Stein <lincoln.stein@gmail.com> |
||
|
|
3c9b282a90 |
Redesign Model Manager Installation Queue (#8910)
* feat(model manager): redesign queue * feat(model manager queue): improve ui/ux - standardized table row widths - sticky table header - reverse table data direction (new items on top) - queue empty state - ui and icon tweaks - add progress tooltip - add code comments for sanity * fix(model manager queue): add missing imports dammit zed editor * fix(model manager queue): play/pause button condition * feat(model manager queue): remove backend status badge * fix(model manager queue): remove unused useStore import * fix(model manager queue): prettier lint * feat(model meneger queue): backend disconnected visual feedback * fix(model manager queue): qol list item ui tweaks * feat(model manager queue): reorganize bulk actions * feat(model manager queue): tweak column widths * feat(model manager queue): disable actions dropdown if items disabled * feat(model manager queue): optimistic updated and code qulity - Treated downloads_done as an active install phase for row UI and bulk cancel. - Stopped stale error text from overriding the badge after resume/restart by only showing the error label when the displayed status is actually error. - Added row-level action locking to block duplicate pause/resume/cancel/restart submissions. - Added optimistic row status handling so the UI does not briefly fall back to stale error/restart state before RTK Query/socket updates arrive. - Fixed local-path basename parsing for both the main row title and restart-required file rows. - Added an accessible aria-label to the overflow menu button. * style(model manager queue): fix prettier lint * feat(model manager queue): keep prune action visible * feat(model manager queue): prune button ui tweak --------- Co-authored-by: joshistoast <me@joshcorbett.com> Co-authored-by: Lincoln Stein <lincoln.stein@gmail.com> |
||
|
|
06eff38354 |
fix(ui): replace all hardcoded frontend strings with i18n translation keys (#9013)
* fix(ui): replace all hardcoded frontend strings with i18n translation keys Remove fallback/defaultValue strings from t() calls, replace hardcoded English text in labels, tooltips, aria-labels, placeholders and JSX content with proper t() calls, and add ~50 missing keys to en.json. Fix incorrect i18n key paths in CanvasObjectImage.ts and a Zoom button aria-label bug in CanvasToolbarScale.tsx. * chore pnpm run fix --------- Co-authored-by: Lincoln Stein <lincoln.stein@gmail.com> |
||
|
|
d4c0e631e2 |
ui: translations update from weblate (#9028)
* translationBot(ui): update translation (Italian) Currently translated at 98.0% (2205 of 2250 strings) Co-authored-by: Riccardo Giovanetti <riccardo.giovanetti@gmail.com> Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ Translation: InvokeAI/Web UI * translationBot(ui): update translation files Updated by "Remove blank strings" hook in Weblate. Co-authored-by: Hosted Weblate <hosted@weblate.org> Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/ Translation: InvokeAI/Web UI * translationBot(ui): update translation (Italian) Currently translated at 97.8% (2210 of 2259 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Italian) Currently translated at 97.8% (2224 of 2272 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Italian) Currently translated at 98.1% (2252 of 2295 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Italian) Currently translated at 98.0% (2264 of 2309 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Russian) Currently translated at 60.7% (1419 of 2334 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/ru/ * translationBot(ui): update translation (Italian) Currently translated at 98.1% (2290 of 2334 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Italian) Currently translated at 97.7% (2319 of 2372 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Italian) Currently translated at 97.7% (2327 of 2380 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Italian) Currently translated at 97.7% (2328 of 2382 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Italian) Currently translated at 97.5% (2370 of 2429 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Finnish) Currently translated at 1.5% (37 of 2429 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/fi/ * translationBot(ui): update translation (Italian) Currently translated at 97.5% (2373 of 2433 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Japanese) Currently translated at 87.1% (2120 of 2433 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/ja/ * translationBot(ui): update translation (Italian) Currently translated at 97.5% (2374 of 2433 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Japanese) Currently translated at 92.2% (2244 of 2433 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/ja/ * translationBot(ui): update translation (Italian) Currently translated at 97.5% (2374 of 2433 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Spanish) Currently translated at 29.4% (720 of 2444 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/es/ * translationBot(ui): update translation (Italian) Currently translated at 97.6% (2405 of 2464 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ --------- Co-authored-by: Riccardo Giovanetti <riccardo.giovanetti@gmail.com> Co-authored-by: DustyShoe <warukeichi@gmail.com> Co-authored-by: Ilmari Laakkonen <ilmarille@gmail.com> Co-authored-by: 嶋田豪介 <shimada_gosuke@cyberagent.co.jp> Co-authored-by: Lucas Prone <sac2087@gmail.com> |
||
|
|
f0d09c34a8 |
feat: add Anima model support (#8961)
* feat: add Anima model support * schema * image to image * regional guidance * loras * last fixes * tests * fix attributions * fix attributions * refactor to use diffusers reference * fix an additional lora type * some adjustments to follow flux 2 paper implementation * use t5 from model manager instead of downloading * make lora identification more reliable * fix: resolve lint errors in anima module Remove unused variable, fix import ordering, inline dict() call, and address minor lint issues across anima-related files. * Chore Ruff format again * fix regional guidance error * fix(anima): validate unexpected keys after strict=False checkpoint loading Capture the load_state_dict result and raise RuntimeError on unexpected keys (indicating a corrupted or incompatible checkpoint), while logging a warning for missing keys (expected for inv_freq buffers regenerated at runtime). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(anima): make model loader submodel fields required instead of Optional Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(anima): add Classification.Prototype to LoRA loaders, fix exception types Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(anima): fix replace-all in key conversion, warn on DoRA+LoKR, unify grouping functions - Use key.replace(old, new, 1) in _convert_kohya_unet_key and _convert_kohya_te_key to avoid replacing multiple occurrences - Upgrade DoRA+LoKR dora_scale strip from logger.debug to logger.warning since it represents data loss - Replace _group_kohya_keys and _group_by_layer with a single _group_keys_by_layer function parameterized by extra_suffixes, with _KOHYA_KNOWN_SUFFIXES and _PEFT_EXTRA_SUFFIXES constants - Add test_empty_state_dict_returns_empty_model to verify empty input produces a model with no layers Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(anima): add safety cap for Qwen3 sequence length to prevent OOM Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(anima): add denoising range validation, fix closure capture, add edge case tests Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(anima): add T5 to metadata, fix dead code, decouple scheduler type guard Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(anima): update VAE field description for required field Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * chore: regenerate frontend types after upstream merge Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * chore: ruff format anima_denoise.py Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(anima): add T5 encoder metadata recall handler The T5 encoder was added to generation metadata but had no recall handler, so it wasn't restored when recalling from metadata. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * chore(frontend): add regression test for buildAnimaGraph Add tests for CFG gating (negative conditioning omitted when cfgScale <= 1) and basic graph structure (model loader, text encoder, denoise nodes). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * only show 0.6b for anima * dont show 0.6b for other models * schema * Anima preview 3 * fix ci --------- Co-authored-by: Your Name <you@example.com> Co-authored-by: kappacommit <samwolfe40@gmail.com> Co-authored-by: Alexander Eichhorn <alex@eichhorn.dev> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> Co-authored-by: Lincoln Stein <lincoln.stein@gmail.com> |
||
|
|
60d0bcdbc1 |
Feature(UI): Canvas Workflow Integration - Run Workflow on Raster Layer (#8665)
* feat: Add canvas-workflow integration feature This commit implements a new feature that allows users to run workflows directly from the unified canvas. Users can now: - Access a "Run Workflow" option from the canvas layer context menu - Select a workflow with image parameters from a modal dialog - Customize workflow parameters (non-image fields) - Execute the workflow with the current canvas layer as input - Have the result automatically added back to the canvas Key changes: - Added canvasWorkflowIntegrationSlice for state management - Created CanvasWorkflowIntegrationModal and related UI components - Added context menu item to raster layers - Integrated workflow execution with canvas image extraction - Added modal to global modal isolator This integration enhances the canvas by allowing users to leverage custom workflows for advanced image processing directly within the canvas workspace. Implements feature request for deeper workflow-canvas integration. * refactor(ui): simplify canvas workflow integration field rendering - Extract WorkflowFieldRenderer component for individual field rendering - Add WorkflowFormPreview component to handle workflow parameter display - Remove workflow compatibility filtering - allow all workflows - Simplify workflow selector to use flattened workflow list - Add comprehensive field type support (String, Integer, Float, Boolean, Enum, Scheduler, Board, Model, Image, Color) - Implement image field selection UI with radio * feat(ui): add canvas-workflow-integration logging namespace * feat(ui): add workflow filtering for canvas-workflow integration - Add useFilteredWorkflows hook to filter workflows with ImageField inputs - Add workflowHasImageField utility to check for ImageField in Form Builder - Only show workflows that have Form Builder with at least one ImageField - Add loading state while filtering workflows - Improve error messages to clarify Form Builder requirement - Update modal description to mention Form Builder and parameter adjustment - Add fallback error message for workflows without Form Builder * feat(ui): add persistence and migration for canvas workflow integration state - Add _version field (v1) to canvasWorkflowIntegrationState for future migrations - Add persistConfig with migration function to handle version upgrades - Add persistDenylist to exclude transient state (isOpen, isProcessing, sourceEntityIdentifier) - Use es-toolkit isPlainObject and tsafe assert for type-safe migration - Persist selectedWorkflowId and fieldValues across sessions * pnpm fix imports * fix(ui): handle workflow errors in canvas staging area and improve form UX - Clear processing state when workflow execution fails at enqueue time or during invocation, so the modal doesn't get stuck - Optimistically update listAllQueueItems cache on queue item status changes so the staging area immediately exits on failure - Clear processing state on invocation_error for canvas workflow origin - Auto-select the only unfilled ImageField in workflow form - Fix image field overflow and thumbnail sizing in workflow form * feat(ui): add canvas_output node and entry-based staging area Add a dedicated `canvas_output` backend invocation node that explicitly marks which images go to the canvas staging area, replacing the fragile board-based heuristic. Each `canvas_output` node produces a separate navigable entry in the staging area, allowing workflows with multiple outputs to be individually previewed and accepted. Key changes: - New `CanvasOutputInvocation` backend node (canvas.py) - Entry-based staging area model where each output image is a separate navigable entry with flat next/prev cycling across all items - Frontend execute hook uses `canvas_output` type detection instead of board field heuristic, with proper board field value translation - Workflow filtering requires both Form Builder and canvas_output node - Updated QueueItemPreviewMini and StagingAreaItemsList for entries - Tests for entry-based navigation, multi-output, and race conditions * Chore pnp run fix * Chore eslint fix * Remove unused useOutputImageDTO export to fix knip lint * Update invokeai/frontend/web/src/features/controlLayers/components/CanvasWorkflowIntegration/useCanvasWorkflowIntegrationExecute.tsx Co-authored-by: dunkeroni <dunkeroni@gmail.com> * move UI text to en.json * fix conflicts merge with main * generate schema * Chore typegen --------- Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: Lincoln Stein <lincoln.stein@gmail.com> Co-authored-by: dunkeroni <dunkeroni@gmail.com> |
||
|
|
32002bd37e |
ui: translations update from weblate (#8992)
* translationBot(ui): update translation (Italian) Currently translated at 98.0% (2205 of 2250 strings) Co-authored-by: Riccardo Giovanetti <riccardo.giovanetti@gmail.com> Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ Translation: InvokeAI/Web UI * translationBot(ui): update translation files Updated by "Remove blank strings" hook in Weblate. Co-authored-by: Hosted Weblate <hosted@weblate.org> Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/ Translation: InvokeAI/Web UI * translationBot(ui): update translation (Italian) Currently translated at 97.8% (2210 of 2259 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Italian) Currently translated at 97.8% (2224 of 2272 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Italian) Currently translated at 98.1% (2252 of 2295 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Italian) Currently translated at 98.0% (2264 of 2309 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Russian) Currently translated at 60.7% (1419 of 2334 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/ru/ * translationBot(ui): update translation (Italian) Currently translated at 98.1% (2290 of 2334 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Italian) Currently translated at 97.7% (2319 of 2372 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Italian) Currently translated at 97.7% (2327 of 2380 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Italian) Currently translated at 97.7% (2328 of 2382 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Italian) Currently translated at 97.5% (2370 of 2429 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Finnish) Currently translated at 1.5% (37 of 2429 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/fi/ * translationBot(ui): update translation (Italian) Currently translated at 97.5% (2373 of 2433 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Japanese) Currently translated at 87.1% (2120 of 2433 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/ja/ * translationBot(ui): update translation (Italian) Currently translated at 97.5% (2374 of 2433 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Japanese) Currently translated at 92.2% (2244 of 2433 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/ja/ * translationBot(ui): update translation (Italian) Currently translated at 97.5% (2374 of 2433 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Spanish) Currently translated at 29.4% (720 of 2444 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/es/ --------- Co-authored-by: Riccardo Giovanetti <riccardo.giovanetti@gmail.com> Co-authored-by: DustyShoe <warukeichi@gmail.com> Co-authored-by: Ilmari Laakkonen <ilmarille@gmail.com> Co-authored-by: 嶋田豪介 <shimada_gosuke@cyberagent.co.jp> Co-authored-by: Lucas Prone <sac2087@gmail.com> |
||
|
|
01c67c5468 |
Fix (multiuser): Ask user to log back in when security token has expired (#9017)
* Initial plan * Warn user when credentials have expired in multiuser mode Agent-Logs-Url: https://github.com/lstein/InvokeAI/sessions/f0947cda-b15c-475d-b7f4-2d553bdf2cd6 Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Address code review: avoid multiple localStorage reads in base query Agent-Logs-Url: https://github.com/lstein/InvokeAI/sessions/f0947cda-b15c-475d-b7f4-2d553bdf2cd6 Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * bugfix(multiuser): ask user to log back in when authentication token expires * feat: sliding window session expiry with token refresh Backend: - SlidingWindowTokenMiddleware refreshes JWT on each mutating request (POST/PUT/PATCH/DELETE), returning a new token in X-Refreshed-Token response header. GET requests don't refresh (they're often background fetches that shouldn't reset the inactivity timer). - CORS expose_headers updated to allow X-Refreshed-Token. Frontend: - dynamicBaseQuery picks up X-Refreshed-Token from responses and updates localStorage so subsequent requests use the fresh expiry. - 401 handler only triggers sessionExpiredLogout when a token was actually sent (not for unauthenticated background requests). - ProtectedRoute polls localStorage every 5s and listens for storage events to detect token removal (e.g. manual deletion, other tabs). Result: session expires after TOKEN_EXPIRATION_NORMAL (1 day) of inactivity, not a fixed time after login. Any user-initiated action resets the clock. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * chore(backend): ruff * fix: address review feedback on auth token handling Bug fixes: - ProtectedRoute: only treat 401 errors as session expiry, not transient 500/network errors that should not force logout - Token refresh: use explicit remember_me claim in JWT instead of inferring from remaining lifetime, preventing silent downgrade of 7-day tokens to 1-day when <24h remains - TokenData: add remember_me field, set during login Tests (6 new): - Mutating requests (POST/PUT/DELETE) return X-Refreshed-Token - GET requests do not return X-Refreshed-Token - Unauthenticated requests do not return X-Refreshed-Token - Remember-me token refreshes to 7-day duration even near expiry - Normal token refreshes to 1-day duration - remember_me claim preserved through refresh cycle Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * chore(backend): ruff --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: lstein <111189+lstein@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Co-authored-by: Jonathan <34005131+JPPhoto@users.noreply.github.com> |
||
|
|
05f4deb68c |
Feat(Canvas): Add button to hide preview stage thumbnails (#8963)
* Feat(Canvas): Add button to hide preview thumbnails in staging area. * Code clean up. Added tests. * Fix: Removed redundant Icon aliases |
||
|
|
474d85e5e0 |
feat: add bulk reidentify action for models (#8951) (#8952)
* feat: add bulk reidentify action for models (#8951) Add a "Reidentify Models" bulk action to the model manager, allowing users to re-probe multiple models at once instead of one by one. - Backend: POST /api/v2/models/i/bulk_reidentify endpoint with partial failure handling (returns succeeded/failed lists) - Frontend: bulk reidentify mutation, confirmation modal with warning about custom settings reset, toast notifications for all outcomes - i18n: new translation keys for bulk reidentify UI strings * fix typgen * Fix bulk reidentify failing for models without trigger_phrases The bulk reidentify endpoint was directly assigning trigger_phrases without checking if the config type supports it, causing an AttributeError for ControlNet models. Added the same hasattr guard used by the individual reidentify endpoint. Also restored the missing path preservation that the individual endpoint has. |
||
|
|
d32f6b5a56 |
ui: translations update from weblate (#8985)
* translationBot(ui): update translation (Italian) Currently translated at 98.0% (2205 of 2250 strings) Co-authored-by: Riccardo Giovanetti <riccardo.giovanetti@gmail.com> Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ Translation: InvokeAI/Web UI * translationBot(ui): update translation files Updated by "Remove blank strings" hook in Weblate. Co-authored-by: Hosted Weblate <hosted@weblate.org> Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/ Translation: InvokeAI/Web UI * translationBot(ui): update translation (Italian) Currently translated at 97.8% (2210 of 2259 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Italian) Currently translated at 97.8% (2224 of 2272 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Italian) Currently translated at 98.1% (2252 of 2295 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Italian) Currently translated at 98.0% (2264 of 2309 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Russian) Currently translated at 60.7% (1419 of 2334 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/ru/ * translationBot(ui): update translation (Italian) Currently translated at 98.1% (2290 of 2334 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Italian) Currently translated at 97.7% (2319 of 2372 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Italian) Currently translated at 97.7% (2327 of 2380 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Italian) Currently translated at 97.7% (2328 of 2382 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Italian) Currently translated at 97.5% (2370 of 2429 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Finnish) Currently translated at 1.5% (37 of 2429 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/fi/ * translationBot(ui): update translation (Italian) Currently translated at 97.5% (2373 of 2433 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Japanese) Currently translated at 87.1% (2120 of 2433 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/ja/ * translationBot(ui): update translation (Italian) Currently translated at 97.5% (2374 of 2433 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ --------- Co-authored-by: Riccardo Giovanetti <riccardo.giovanetti@gmail.com> Co-authored-by: DustyShoe <warukeichi@gmail.com> Co-authored-by: Ilmari Laakkonen <ilmarille@gmail.com> Co-authored-by: 嶋田豪介 <shimada_gosuke@cyberagent.co.jp> |
||
|
|
438515bf9a |
Chore: Bump version to 6.12.0 (#8981)
* chore: bump version to 6.12.0 * chore: update What's New text |
||
|
|
b120ef5183 |
ui: translations update from weblate (#8956)
* translationBot(ui): update translation (Italian) Currently translated at 98.0% (2205 of 2250 strings) Co-authored-by: Riccardo Giovanetti <riccardo.giovanetti@gmail.com> Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ Translation: InvokeAI/Web UI * translationBot(ui): update translation files Updated by "Remove blank strings" hook in Weblate. Co-authored-by: Hosted Weblate <hosted@weblate.org> Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/ Translation: InvokeAI/Web UI * translationBot(ui): update translation (Italian) Currently translated at 97.8% (2210 of 2259 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Italian) Currently translated at 97.8% (2224 of 2272 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Italian) Currently translated at 98.1% (2252 of 2295 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Italian) Currently translated at 98.0% (2264 of 2309 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Russian) Currently translated at 60.7% (1419 of 2334 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/ru/ * translationBot(ui): update translation (Italian) Currently translated at 98.1% (2290 of 2334 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Italian) Currently translated at 97.7% (2319 of 2372 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Italian) Currently translated at 97.7% (2327 of 2380 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Italian) Currently translated at 97.7% (2328 of 2382 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Italian) Currently translated at 97.5% (2370 of 2429 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Finnish) Currently translated at 1.5% (37 of 2429 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/fi/ * translationBot(ui): update translation (Italian) Currently translated at 97.5% (2373 of 2433 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ --------- Co-authored-by: Riccardo Giovanetti <riccardo.giovanetti@gmail.com> Co-authored-by: DustyShoe <warukeichi@gmail.com> Co-authored-by: Ilmari Laakkonen <ilmarille@gmail.com> |
||
|
|
cd47b3baf7 |
Feature: Make strict password checking optional (#8957)
* feat: add strict_password_checking config option to relax password requirements - Add `strict_password_checking: bool = Field(default=False)` to InvokeAIAppConfig - Add `get_password_strength()` function to password_utils.py (returns weak/moderate/strong) - Add `strict_password_checking` field to SetupStatusResponse API endpoint - Update users_base.py and users_default.py to accept `strict_password_checking` param - Update auth.py router to pass config.strict_password_checking to all user service calls - Create shared frontend utility passwordUtils.ts for password strength validation - Update AdministratorSetup, UserProfile, UserManagement components to: - Fetch strict_password_checking from setup status endpoint - Show colored strength indicators (red/yellow/blue) in non-strict mode - Allow any non-empty password in non-strict mode - Maintain strict validation behavior when strict_password_checking=True - Update SetupStatusResponse type in auth.ts endpoint - Add passwordStrength and passwordHelperRelaxed translation keys to en.json - Add tests for new get_password_strength() function Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Changes before error encountered Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * chore(backend): docstrings * chore(frontend): typegen --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: lstein <111189+lstein@users.noreply.github.com> Co-authored-by: Jonathan <34005131+JPPhoto@users.noreply.github.com> |
||
|
|
c8ac303ad2 |
ui: translations update from weblate (#8947)
* translationBot(ui): update translation (Italian) Currently translated at 98.0% (2205 of 2250 strings) Co-authored-by: Riccardo Giovanetti <riccardo.giovanetti@gmail.com> Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ Translation: InvokeAI/Web UI * translationBot(ui): update translation files Updated by "Remove blank strings" hook in Weblate. Co-authored-by: Hosted Weblate <hosted@weblate.org> Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/ Translation: InvokeAI/Web UI * translationBot(ui): update translation (Italian) Currently translated at 97.8% (2210 of 2259 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Italian) Currently translated at 97.8% (2224 of 2272 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Italian) Currently translated at 98.1% (2252 of 2295 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Italian) Currently translated at 98.0% (2264 of 2309 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Russian) Currently translated at 60.7% (1419 of 2334 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/ru/ * translationBot(ui): update translation (Italian) Currently translated at 98.1% (2290 of 2334 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Italian) Currently translated at 97.7% (2319 of 2372 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Italian) Currently translated at 97.7% (2327 of 2380 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Italian) Currently translated at 97.7% (2328 of 2382 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Italian) Currently translated at 97.5% (2370 of 2429 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ --------- Co-authored-by: Riccardo Giovanetti <riccardo.giovanetti@gmail.com> Co-authored-by: DustyShoe <warukeichi@gmail.com> |
||
|
|
2d1dbceae5 |
Add user management UI for admin and regular users (#106) (#8937)
* Add user management UI for admin and regular users (#106) * Add user management UI and backend API endpoints Co-authored-by: lstein <111189+lstein@users.noreply.github.com> Fix user management feedback: cancel/back navigation, system user filter, tooltip fix Co-authored-by: lstein <111189+lstein@users.noreply.github.com> Make Back button on User Management page more prominent Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * chore(frontend): typegen --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: lstein <111189+lstein@users.noreply.github.com> Co-authored-by: Lincoln Stein <lincoln.stein@gmail.com> * Add Confirm Password field to My Profile password change form (#110) Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: lstein <111189+lstein@users.noreply.github.com> --------- Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com> Co-authored-by: lstein <111189+lstein@users.noreply.github.com> Co-authored-by: Alexander Eichhorn <alex@eichhorn.dev> |
||
|
|
b8b6798167 |
ui: translations update from weblate (#8946)
* translationBot(ui): update translation (Italian) Currently translated at 98.0% (2205 of 2250 strings) Co-authored-by: Riccardo Giovanetti <riccardo.giovanetti@gmail.com> Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ Translation: InvokeAI/Web UI * translationBot(ui): update translation files Updated by "Remove blank strings" hook in Weblate. Co-authored-by: Hosted Weblate <hosted@weblate.org> Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/ Translation: InvokeAI/Web UI * translationBot(ui): update translation (Italian) Currently translated at 97.8% (2210 of 2259 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Italian) Currently translated at 97.8% (2224 of 2272 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Italian) Currently translated at 98.1% (2252 of 2295 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Italian) Currently translated at 98.0% (2264 of 2309 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Russian) Currently translated at 60.7% (1419 of 2334 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/ru/ * translationBot(ui): update translation (Italian) Currently translated at 98.1% (2290 of 2334 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Italian) Currently translated at 97.7% (2319 of 2372 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Italian) Currently translated at 97.7% (2327 of 2380 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ --------- Co-authored-by: Riccardo Giovanetti <riccardo.giovanetti@gmail.com> Co-authored-by: DustyShoe <warukeichi@gmail.com> |
||
|
|
fcdcd7f46b |
Prompt Attention Fixes (#8860)
* fix(prompt): add more punctuations, fixes attention hotkeys removing them from prompt. * fix(prompt): improve numeric weighting calculation * feat(prompts): add numeric attention preference toggle to settings * feat(prompts): use attention style preference, rewrite to accomodate prompt functions * fix(prompts): account for weirdness with quotes account for mismatching quotes, missing quotes and other quote entities * fix(prompts): add tests, qol improvements, code cleanup * fix(prompts): test lint * fix(prompts): remove unused exports * fix(prompts): separator whitespace serialization --------- Co-authored-by: joshistoast <me@joshcorbett.com> Co-authored-by: Lincoln Stein <lincoln.stein@gmail.com> |
||
|
|
6b57b004a4 |
feat(MM):model settings export import (#8872)
* feat(model_manager): add export/import for model settings Add the ability to export model settings (default_settings, trigger_phrases, cpu_only) as JSON and import them back. The model name is used as the filename for exports. https://claude.ai/code/session_01LXKjbRjfzcG3d3vzk3xRCh * fix(ui): reset settings forms after import so updated values display immediately The useForm defaultValues only apply on mount, so importing model settings updated the backend but the forms kept showing stale values. Added useEffect to reset forms when the underlying model config changes. Also fixed lint errors (strict equality, missing React import). * fix(ui): harden model settings export/import Prevent cross-model-type import errors by filtering imported fields against the target model's supported fields, showing clear warnings for incompatible or partially compatible settings instead of raw pydantic validation errors. Also fix falsy checks for empty arrays and objects in export, disable export button when nothing to export, add client-side validation and FileReader error handling on import. * Chore pnpm fix --------- Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: Lincoln Stein <lincoln.stein@gmail.com> |
||
|
|
4fd5cd26a0 |
ui: translations update from weblate (#8924)
* translationBot(ui): update translation (Italian) Currently translated at 98.0% (2205 of 2250 strings) Co-authored-by: Riccardo Giovanetti <riccardo.giovanetti@gmail.com> Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ Translation: InvokeAI/Web UI * translationBot(ui): update translation files Updated by "Remove blank strings" hook in Weblate. Co-authored-by: Hosted Weblate <hosted@weblate.org> Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/ Translation: InvokeAI/Web UI * translationBot(ui): update translation (Italian) Currently translated at 97.8% (2210 of 2259 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Italian) Currently translated at 97.8% (2224 of 2272 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Italian) Currently translated at 98.1% (2252 of 2295 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Italian) Currently translated at 98.0% (2264 of 2309 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Russian) Currently translated at 60.7% (1419 of 2334 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/ru/ * translationBot(ui): update translation (Italian) Currently translated at 98.1% (2290 of 2334 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Italian) Currently translated at 97.7% (2319 of 2372 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ --------- Co-authored-by: Riccardo Giovanetti <riccardo.giovanetti@gmail.com> Co-authored-by: DustyShoe <warukeichi@gmail.com> |
||
|
|
146b936844 |
feat(multiuser mode): Support multiple isolated users on same backend (#8822)
* Add comprehensive multi-user support specification and implementation plan Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Clarify Python tooling transition state Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Add executive summary for multi-user support specification Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Reorganize multiuser docs into subfolder and update with approved design decisions Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * docs: fix mkdocs syntax issues * Fix Z-Image VAE operations not reserving working memory for OOM prevention (#8) * Initial plan * Fix Z-Image VAE encode/decode to request working memory Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Add test for Z-Image working memory estimation Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Fix unit test: only set config attribute for AutoencoderKL, not FluxAutoEncoder Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * style: fix ruff errors * Fix test: use model_construct to bypass Pydantic validation for mock fields Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * chore(ruff): fix ruff errors --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: lstein <111189+lstein@users.noreply.github.com> Co-authored-by: Lincoln Stein <lincoln.stein@gmail.com> * Phase 1: Add multi-user database schema and authentication foundation (#6) * Initial plan * Add Phase 1: Database schema, authentication utilities, and user service - Added dependencies: passlib[bcrypt], python-jose[cryptography], email-validator - Created migration_25 for multi-user support database schema - users table with authentication fields - user_sessions, user_invitations, shared_boards tables - Added user_id columns to boards, images, workflows, session_queue, style_presets - Created system user for backward compatibility - Implemented authentication utilities - Password hashing and validation (password_utils.py) - JWT token generation and verification (token_service.py) - Implemented user service - Abstract base class (users_base.py) - SQLite implementation (users_default.py) - Full CRUD operations for users - Authentication and admin management - Added comprehensive tests for all components - All code passes ruff linting and mypy type checking Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Refactor user service to use transaction pattern and improve security documentation - Changed all database operations to use self._db.transaction() context manager - Follows the same pattern as other services like board_records - Improves thread safety and transaction management - Added detailed security warnings for the hardcoded JWT secret key - Documented that it must be moved to config before production - Fixed whitespace linting issues - All tests still pass with the refactored code Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Fix system user email to use valid domain - Changed system user email from system@invokeai.local to system@system.invokeai - .local domains are rejected by email-validator as special-use/reserved - All end-to-end tests now pass successfully Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Fix test failures: password length, migration chain, and table existence checks - Fixed bcrypt 72-byte password limit by truncating long passwords in hash_password and verify_password - Fixed test_migration_25 to use callback directly instead of migrator to avoid fragmented chain error - Updated system user email assertion in test from @invokeai.local to @system.invokeai - Added table existence checks for boards, images, workflows, and session_queue before altering them - This prevents "no such table" errors when migration runs in environments without all tables Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * (chore) fix ruff errors * (chore) fix ruff errors (2) * Fix test failures: use _conn instead of conn and improve password truncation - Fixed test_user_service.py to use db._conn instead of db.conn (SqliteDatabase uses private _conn) - Simplified password truncation logic in password_utils.py for better clarity - Ensured UTF-8 decoding handles truncated bytes properly with errors="ignore" Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * chore(uv): updated uv lockfile * Fix bcrypt password length errors by configuring passlib properly - Added bcrypt__relax_truncate_checks=True to CryptContext to prevent errors on long passwords - Removed min_length=8 constraint from pydantic models to allow service-level validation - Service-level validation provides better error messages and more control - Manual truncation code kept as safety net for passwords >72 bytes Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Fix bcrypt parameter name: use truncate_error instead of relax_truncate_checks - Changed bcrypt__relax_truncate_checks=True to bcrypt__truncate_error=False - The correct passlib parameter is truncate_error (not relax_truncate_checks) - Setting it to False allows passwords >72 bytes without raising an error Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * fix(passwords) downgrade bcrypt to work with current passlib * chore(uv): update locks file --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: lstein <111189+lstein@users.noreply.github.com> Co-authored-by: Lincoln Stein <lincoln.stein@gmail.com> * Implement Phase 2: Authentication Service with JWT and FastAPI Integration (#11) * Initial plan * Add Phase 2 authentication service - auth dependencies, router, and service integration Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Address code review feedback - add token expiration constants and improve documentation Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Fix email validation to allow special-use domains like .local for testing Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Fix system user to not be admin - allows /auth/setup to work on fresh database Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * chore: typegen --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: lstein <111189+lstein@users.noreply.github.com> Co-authored-by: Lincoln Stein <lincoln.stein@gmail.com> * Add Phase 3 integration tests and documentation for authentication middleware (#15) * Initial plan * Add Phase 3 integration tests for auth router endpoints Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Add Phase 3 completion documentation and testing guide Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * chore: ruff --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: lstein <111189+lstein@users.noreply.github.com> Co-authored-by: Lincoln Stein <lincoln.stein@gmail.com> * chore: fix unresolved merged conflict markers * Phase 4: Add multi-tenancy to boards and session queue services (#17) * Initial plan * Update boards service for multi-user support - Add user_id parameter to board creation and filtering - Update board_records base and SQLite implementation to filter by user - Include shared boards and public boards in user queries - Update boards router to require authentication - Update invocation context to pass user_id from queue item - Add user_id field to SessionQueueItem model Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Update session_queue service for multi-user support - Add user_id parameter to enqueue_batch method - Update ValueToInsertTuple to include user_id - Update prepare_values_to_insert to accept and use user_id - Update SQL INSERT statements to include user_id column - Update session_queue router to require authentication - Update retry_items_by_id to preserve user_id when retrying Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Add authentication imports to images, workflows, and style_presets routers - Import CurrentUser dependency in all three routers - Add CurrentUser parameter to upload_image endpoint - Prepare for further authentication requirements in these services Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Add multiuser tests and Phase 4 documentation - Create test_boards_multiuser.py with authentication tests - Verify board operations require authentication - Test board creation and listing with auth tokens - Add comprehensive Phase 4 implementation summary - Document all changes, data flows, and security considerations Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Add authentication to remaining board endpoints - Add CurrentUser to get_board endpoint - Add CurrentUser to update_board endpoint - Add CurrentUser to delete_board endpoint - Ensures all board operations require authentication - Addresses code review feedback Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Feature(image boards): Implement per-user board isolation - Complete verification report with all checks passed - Document code quality, security, and testing results - List all achievements and sign-off criteria - Mark phase as READY FOR MERGE Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * chore: ruff * chore: resolve conflicts in z_image_working_memory test * chore: ruff --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: lstein <111189+lstein@users.noreply.github.com> Co-authored-by: Lincoln Stein <lincoln.stein@gmail.com> * feat: Implement Phase 5 of multiuser plan - Frontend authentication (#19) * Phase 5: Implement frontend authentication infrastructure - Created auth slice with Redux state management for authentication - Created auth API endpoints (login, logout, setup, me) - Created LoginPage component for user authentication - Created AdministratorSetup component for initial admin setup - Created ProtectedRoute wrapper for route authentication checking - Updated API configuration to include Authorization headers - Installed and configured react-router-dom for routing - Updated App component with authentication routes - All TypeScript checks passing Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * chore(style): prettier, typegen and add convenience targets to makefile --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: lstein <111189+lstein@users.noreply.github.com> Co-authored-by: Lincoln Stein <lincoln.stein@gmail.com> * feat: Implement Phase 6 frontend UI updates - UserMenu and admin restrictions Co-authored-by: lstein <111189+lstein@users.noreply.github.com> docs: Add comprehensive testing and verification documentation for Phase 6 Co-authored-by: lstein <111189+lstein@users.noreply.github.com> docs: Add Phase 6 summary document Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * feat: Add user management script for testing multiuser features Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * feat: Implement read-only model manager access for non-admin users Co-authored-by: lstein <111189+lstein@users.noreply.github.com> feat: Add admin authorization to model management API endpoints Co-authored-by: lstein <111189+lstein@users.noreply.github.com> docs: Update specification and implementation plan for read-only model manager Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Phase 7: Comprehensive testing and security validation for multiuser authentication (#23) * Initial plan * Phase 7: Complete test suite with 88 comprehensive tests - Add password utils tests (31 tests): hashing, verification, validation - Add token service tests (20 tests): JWT creation, verification, security - Add security tests (13 tests): SQL injection, XSS, auth bypass prevention - Add data isolation tests (11 tests): multi-user data separation - Add performance tests (13 tests): benchmarks and scalability - Add comprehensive testing documentation - Add phase 7 verification report Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * bugfix(backend): Fix issues with authentication token expiration handling - Remove time.sleep from token uniqueness test (use different expiration instead) - Increase token expiration test time from 1 microsecond to 10 milliseconds - More reliable test timing to prevent flakiness Co-authored-by: lstein <111189+lstein@users.noreply.github.com> Add Phase 7 summary documentation Co-authored-by: lstein <111189+lstein@users.noreply.github.com> Fix test_performance.py missing logger fixture Add missing logger fixture to test_performance.py that was causing test failures. The fixture creates a Logger instance needed by the user_service fixture. Co-authored-by: lstein <111189+lstein@users.noreply.github.com> Add board isolation issue specification document Document the three board isolation issues that need to be addressed: 1. Board list not updating when switching users 2. "Uncategorized" board shared among users 3. Admin cannot access all users' boards Includes technical details, implementation plan, and acceptance criteria. This document will be used to create a separate GitHub issue and PR. Co-authored-by: lstein <111189+lstein@users.noreply.github.com> Fix test failures in Phase 7 tests - Fix board service API calls to use enum values (BoardRecordOrderBy, SQLiteDirection) instead of strings - Fix board deletion test to use get_dto() instead of non-existent get() method - Add exception handling to verify_password() for invalid hash formats - Update SQL injection test to accept both 401 and 422 status codes (Pydantic validation) All fixes ensure tests match actual API signatures and handle edge cases properly. Co-authored-by: lstein <111189+lstein@users.noreply.github.com> Fix token forgery test to properly decode and modify JWT payload The test was attempting to modify the JWT payload by string replacement on the base64-encoded data, which doesn't work since "false" doesn't appear literally in the base64 encoding. Fixed to: - Properly decode the base64 payload - Parse the JSON - Modify the is_admin field - Re-encode the payload - Create a forged token with the modified payload and original signature - Verify it's rejected with 401 status This properly tests that JWT signature verification prevents token forgery. Co-authored-by: lstein <111189+lstein@users.noreply.github.com> Fix test_verify_expired_token timing issue Increased token expiration from 10ms to 100ms and wait time from 20ms to 200ms to make the test more reliable. The previous timing was too tight and could cause race conditions where the token hadn't actually expired yet when verified. This ensures the test reliably validates that expired tokens are properly rejected. Co-authored-by: lstein <111189+lstein@users.noreply.github.com> Fix token verification to properly validate signatures and expiration The verify_token() function was not explicitly enabling JWT verification options, causing it to accept expired tokens and tokens with modified signatures/payloads. Fixed by explicitly setting verification options: - verify_signature: True (reject modified tokens) - verify_exp: True (reject expired tokens) - verify_nbf: True (verify "not before" claim) - verify_iat: True (verify "issued at" claim) - verify_aud: False (we don't use audience claims) Also added catch-all exception handler for other validation errors. This ensures all token security tests pass properly. Co-authored-by: lstein <111189+lstein@users.noreply.github.com> Revert to default python-jose verification behavior Removed explicit options parameter from jwt.decode() call since python-jose verifies signatures and expiration by default. The explicit options may have been causing issues or conflicts with the library's default behavior. Added comments clarifying that python-jose defaults are secure and handle verification properly. Need user to test and provide debugging output if issues persist. Co-authored-by: lstein <111189+lstein@users.noreply.github.com> Fix JWT expiration verification for python-jose 3.5.0 python-jose 3.5.0 has a bug where expiration verification doesn't work properly by default. The jwt.decode() function is not rejecting expired tokens even when they should be rejected. Workaround implemented: 1. First, get unverified claims to extract the 'exp' timestamp 2. Manually check if current time >= exp time (token is expired) 3. Return None immediately if expired 4. Then verify signature with jwt.decode() for tokens that aren't expired This ensures: - Expired tokens are properly rejected - Signature verification still happens for non-expired tokens - Modified tokens are rejected due to signature mismatch All three failing tests should now pass: - test_verify_expired_token - test_verify_token_with_modified_payload - test_token_signature_verification Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Fix race condition in token verification - verify signature before expiration Changed the order of verification in verify_token(): 1. First verify signature with jwt.decode() - rejects modified/forged tokens 2. Then manually check expiration timestamp Previous implementation checked expiration first using get_unverified_claims(), which could cause a race condition where: - Token with valid payload but INVALID signature would pass expiration check - If expiration check happened to return None due to timing, signature was never verified - Modified tokens could be accepted intermittently New implementation ensures signature is ALWAYS verified first, preventing any modified tokens from being accepted, while still working around the python-jose 3.5.0 expiration bug by manually checking expiration after signature verification. This eliminates the non-deterministic test failures in test_verify_token_with_modified_payload. Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * chore(app): ruff --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: lstein <111189+lstein@users.noreply.github.com> Co-authored-by: Lincoln Stein <lincoln.stein@gmail.com> * Backend: Add admin board filtering and uncategorized board isolation Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Fix intermittent token service test failures caused by Base64 padding (#32) * Initial plan * Fix intermittent token service test failures due to Base64 padding Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Address code review: add constants for magic numbers in tests Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * chore(tests): ruff --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: lstein <111189+lstein@users.noreply.github.com> Co-authored-by: Lincoln Stein <lincoln.stein@gmail.com> * Implement user isolation for session queue and socket events (WIP - debugging queue visibility) (#30) * Add user isolation for queue events and field values filtering Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Add user column to queue list UI Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Add field values privacy indicator and implementation documentation Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Allow all users to see queue item status events while keeping invocation events private Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * chore(backend): ruff --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: lstein <111189+lstein@users.noreply.github.com> Co-authored-by: Lincoln Stein <lincoln.stein@gmail.com> * Fix Queue tab not updating for other users in real-time (#34) * Initial plan * Add SessionQueueItemIdList invalidation to queue socket events This ensures the queue item list updates in real-time for all users when queue events occur (status changes, batch enqueued, queue cleared). Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Add SessionQueueItemIdList invalidation to queue_items_retried event Ensures queue list updates when items are retried. Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Improve queue_items_retried event and mutation invalidation - Add individual item invalidation to queue_items_retried event handler - Add SessionQueueStatus and BatchStatus tags to retryItemsById mutation - Ensure consistency between event handler and mutation invalidation patterns Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Add privacy check for batch field values in Queue tab Displays "Hidden for privacy" message for non-admin users viewing queue items they don't own, instead of showing the actual field values. Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * i18n(frontend): change wording of queue values suppressed message * Add SessionQueueItemIdList cache invalidation to queue events Ensures real-time queue updates for all users by invalidating the SessionQueueItemIdList cache tag when queue events occur. Co-authored-by: lstein <111189+lstein@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: lstein <111189+lstein@users.noreply.github.com> Co-authored-by: Lincoln Stein <lincoln.stein@gmail.com> * Fix multiuser information leakage in Queue panel detail view (#38) * Initial plan * Implement multiuser queue information leakage fix - Backend: Update sanitize_queue_item_for_user to clear session graph and workflow - Frontend: Add permission check to disable detail view for unauthorized users - Add test for sanitization logic - Add translation key for permission denied message Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Fix prettier formatting for QueueItemComponent Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Address code review feedback - Move Graph and GraphExecutionState imports to top of file - Remove dependency on test_nodes in sanitization test - Create minimal test invocation directly in test file Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Address additional code review feedback - Create shallow copy to avoid mutating original queue_item - Extract 'system' user_id to constant (SYSTEM_USER_ID) - Add constant to both backend and frontend for consistency Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Fix pydantic validation error in test fixture Add required timestamp fields (created_at, updated_at, started_at, completed_at) to SessionQueueItem in test fixture Co-authored-by: lstein <111189+lstein@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * fix(queue): Enforce user permissions for queue operations in multiuser mode (#36) * Initial plan * Add backend authorization checks for queue operations Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Fix linting issues in authorization changes Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Add frontend authorization checks for queue operations Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Add access denied messages for cancel and clear operations Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Fix access denied messages for all cancel/delete operations Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Fix merge conflict duplicates in QueueItemComponent Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * chore(frontend): typegen --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: lstein <111189+lstein@users.noreply.github.com> Co-authored-by: Lincoln Stein <lincoln.stein@gmail.com> * fix(multiuser): Isolate client state per user to prevent data leakage (#40) * Implement per-user client state storage to fix multiuser leakage Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Fix: Make authentication optional for client_state endpoints to support single-user mode Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Clear params state on logout/login to prevent user data leakage Co-authored-by: lstein <111189+lstein@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * feat(queue): show user/total pending jobs in multiuser mode badge (#43) * Initial plan * Add multiuser queue badge support - show X/Y format in multiuser mode Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Format openapi.json with Prettier Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Address code review feedback - optimize DB queries and improve code clarity Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * translationBot(ui): update translation files (#8767) Updated by "Cleanup translation files" hook in Weblate. Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/ Translation: InvokeAI/Web UI * Limit automated issue closure to bug issues only (#8776) * Initial plan * Add only-labels parameter to limit automated issue closure to bugs only Co-authored-by: lstein <111189+lstein@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * fix(multiuser): Isolate client state per user to prevent data leakage (#40) * Implement per-user client state storage to fix multiuser leakage Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Fix: Make authentication optional for client_state endpoints to support single-user mode Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Clear params state on logout/login to prevent user data leakage Co-authored-by: lstein <111189+lstein@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Initial plan * chore(backend) ruff & typegen * Fix real-time badge updates by invalidating SessionQueueStatus on queue events Co-authored-by: lstein <111189+lstein@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: lstein <111189+lstein@users.noreply.github.com> Co-authored-by: Weblate (bot) <hosted@weblate.org> Co-authored-by: Lincoln Stein <lincoln.stein@gmail.com> * Convert session queue isolation logs from info to debug level Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Add JWT secret storage in database and app_settings service Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Add multiuser configuration option with default false Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Update token service tests to initialize JWT secret Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Fix app_settings_service to use proper database transaction pattern Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * chore(backend): typegen and ruff * chore(docs): update docstrings * Fix frontend to bypass authentication in single-user mode Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Fix auth tests to enable multiuser mode Auth tests were failing because the login and setup endpoints now return 403 when multiuser mode is disabled (the default). Updated test fixtures to enable multiuser mode for all auth-related tests. Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Fix model manager UI visibility in single-user mode Model manager UI for adding, deleting and modifying models is now: - Visible in single-user mode (multiuser: false, the default) - Hidden in multiuser mode for non-admin users - Visible in multiuser mode for admin users Created useIsModelManagerEnabled hook that checks multiuser_enabled status and returns true when multiuser is disabled OR when user is admin. Updated all model manager components to use this hook instead of direct is_admin checks. Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * chore(backend): ruff * chore(frontend): typegen * Fix TypeScript lint errors - Added multiuser_enabled field to SetupStatusResponse type in auth.ts - Removed unused user variable reference in MainModelDefaultSettings.tsx Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Fix test_data_isolation to enable multiuser mode Added fixture to enable multiuser mode for data isolation tests, similar to other auth tests. Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Redirect login and setup pages to app in single-user mode When multiuser mode is disabled, the LoginPage and AdministratorSetup components now redirect to /app instead of showing the login/setup forms. This prevents users from being stuck on the login page after browser refresh in single-user mode. Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Fix test_auth.py to initialize JWT secret Added setup_jwt_secret fixture to test_auth.py to initialize the JWT secret before running auth tests. This fixture was missing, causing token creation/verification to fail in auth router tests. Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Prevent login form flash in single-user mode Show loading spinner instead of login/setup forms when multiuser mode is disabled or when redirecting is about to happen. This prevents the unattractive flash of the login dialog when refreshing the page in single-user mode. Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Fix board and queue operations in single-user mode Changed boards, session_queue, and images routers to use CurrentUserOrDefault instead of CurrentUser. This allows these endpoints to work without authentication when multiuser mode is disabled (default), fixing the issue where users couldn't create boards or add jobs to the queue in single-user mode. Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Add user management utilities and rename add_user.py Created three user management scripts in the scripts/ directory: - useradd.py (renamed from add_user.py) - add users with admin privileges - userdel.py - delete users by email address with confirmation - usermod.py - modify user details (name, password, admin status) All scripts support both CLI and interactive modes for flexibility. Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Fix ESLint errors in frontend code - Fixed brace-style issue in App.tsx (else-if on same line) - Removed unused useAppSelector imports from model manager components - Fixed import sorting in ControlAdapterModelDefaultSettings.tsx Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Add userlist.py script for viewing database users Created scripts/userlist.py to display all users in the database. Supports: - Table format (default): Shows ID, email, display name, admin status, and active status - JSON format (--json flag): Outputs user data as JSON for scripting/automation Example usage: python scripts/userlist.py # Table view python scripts/userlist.py --json # JSON output Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Fix test_boards_multiuser.py test failures Fixed test failures caused by ApiDependencies.invoker not being set properly: - Added setup_jwt_secret fixture to initialize JWT secret for token generation - Added enable_multiuser_for_tests fixture that sets ApiDependencies.invoker as a class attribute - Updated tests to use enable_multiuser_for_tests fixture to ensure ApiDependencies is properly configured - Removed MockApiDependencies class approach in favor of directly setting the class attribute This fixes the AttributeError and ensures all tests have the proper setup. Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * chore(backend): ruff * Fix userlist.py SqliteDatabase initialization Fixed AttributeError in userlist.py where SqliteDatabase was being passed the config object instead of config.db_path. The constructor expects a Path object (db_path) as the first argument, not the entire config object. Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Fix test_boards_multiuser.py by adding app_settings service to mock Added AppSettingsService initialization to the mock_services fixture in tests/conftest.py. The test was failing because setup_jwt_secret fixture expected mock_invoker.services.app_settings to exist, but it wasn't being initialized in the mock services. Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * bugfix(scripts): fix crash in userlist.py script * Fix test_boards_multiuser.py JWT secret initialization Fixed setup_jwt_secret fixture to call set_jwt_secret() directly instead of trying to access non-existent app_settings service. Removed incorrect app_settings parameter from InvocationServices initialization in tests/conftest.py since app_settings is not an attribute of InvocationServices. Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Fix CurrentUserOrDefault to require auth in multiuser mode Changed get_current_user_or_default to raise HTTP 401 when multiuser mode is enabled and credentials are missing, invalid, or the user is inactive. This ensures that board/queue/image operations require authentication in multiuser mode while still working without authentication in single-user mode (default). Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * chore(front & backend): ruff and lint * Add AdminUserOrDefault and fix model settings in single-user mode Created AdminUserOrDefault dependency that allows admin operations to work without authentication in single-user mode while requiring admin privileges in multiuser mode. Updated model_manager router to use AdminUserOrDefault for update_model_record, update_model_image, and reidentify_model endpoints. This fixes the "Missing authentication credentials" error when saving model default settings in single-user mode. Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Fix model manager operations in single-user mode Changed all model manager endpoints from AdminUser to AdminUserOrDefault to allow model installation, deletion, conversion, and cache management operations to work without authentication in single-user mode. This fixes the issue where users couldn't add or delete models in single-user mode. Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Fix syntax error in model_manager.py Added Depends(AdminUserOrDefault) to all AdminUserOrDefault dependency parameters to fix Python syntax error where parameters without defaults were following parameters with defaults. Imported Depends from fastapi. Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Fix FastAPI dependency injection syntax error Removed type annotations from AdminUserOrDefault dependency parameters. FastAPI doesn't allow both Annotated type hints and = Depends() default values together. Changed from `_: AdminUserOrDefault = Depends(AdminUserOrDefault)` to `_ = Depends(AdminUserOrDefault)` throughout model_manager.py. Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Fix delete_model endpoint parameter annotation Changed delete_model endpoint to use Annotated[str, Path(...)] instead of str = Path(...) to match FastAPI's preferred syntax and fix the 422 Unprocessable Entity error when deleting models in single-user mode. Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Fix parameter annotations for all AdminUserOrDefault endpoints Changed all endpoints using AdminUserOrDefault from old syntax (key: str = Path(...)) to FastAPI's preferred Annotated syntax (key: Annotated[str, Path(...)]). This fixes 422 Unprocessable Entity errors when updating model settings and deleting models in single-user mode. Updated endpoints: delete_model_image, install_model, install_hugging_face_model, and convert_model. Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Revert to correct AdminUserOrDefault usage pattern Reverted model_manager.py to state before commit c47af8f and reapplied AdminUserOrDefault correctly. Changed from `_: AdminUser` to `current_admin: AdminUserOrDefault` using the same pattern as boards.py (`current_user: CurrentUserOrDefault`). This fixes all 422 errors in single-user mode while maintaining proper admin authentication in multiuser mode. Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Fix parameter order for AdminUserOrDefault in model manager Moved current_admin: AdminUserOrDefault parameter before all parameters with default values in model_manager.py endpoints. Python requires parameters without defaults to come before parameters with defaults. Fixed 8 endpoints: delete_model, bulk_delete_models, delete_model_image, install_model, install_hugging_face_model, cancel_model_install_job, convert_model, and do_hf_login. Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * chore(frontend): typegen * chore(frontend): typegen again * Docs(app): Comprehensive Documentation of Multiuser Features (#50) * Implement Phase 8: Complete multiuser documentation (user, admin, and API guides) Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Update multiuser documentation for single-user mode and CLI scripts - Document multiuser config option (true/false/absent) - Explain single-user mode behavior (no login required) - Document mode switching and legacy "system" user - Update user management to reference CLI scripts (useradd, userdel, usermod, userlist) - Note that web UI for user management is coming in future release - Add adaptive API client example for both modes Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * docs(multiuser): bring user guide documentation up to date --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * docs(app): update multiuser documentation * bugfix(app): fix misaligned database migration calls * chore(tests): update migration test to accommodate resequencing of migrations * fix(frontend): prevent caching of static pages * chore(backend): ruff * fix(backend): fix incorrect migration import * Fix: Admin users can see image previews from other users' generations (#61) * Initial plan * Fix: strip image preview from InvocationProgressEvent sent to admin room Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * chore: ruff * fix(backend): add migration_29 file * chore(tests): fix migration_29 test --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: lstein <111189+lstein@users.noreply.github.com> Co-authored-by: Lincoln Stein <lincoln.stein@gmail.com> * fix(queue): System user queue items show blank instead of `<hidden>` for non-admin users (#63) * Initial plan * fix(queue): System user queue items show blank instead of `<hidden>` for non-admin users Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * chore(backend): ruff --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: lstein <111189+lstein@users.noreply.github.com> Co-authored-by: Lincoln Stein <lincoln.stein@gmail.com> * Hide "Use Cache" checkbox in node editor for non-admin users in multiuser mode (#65) * Initial plan * Hide use cache checkbox for non-admin users in multiuser mode Co-authored-by: lstein <111189+lstein@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Fix node loading hang when invoke URL ends with /app (#67) * Initial plan * Fix node loading hang when URL ends with /app Co-authored-by: lstein <111189+lstein@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Move user management scripts to installable module with CLI entry points (#69) * Initial plan * Add user management module with invoke-useradd/userdel/userlist/usermod entry points Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * chore(util): remove superceded user administration scripts --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: lstein <111189+lstein@users.noreply.github.com> Co-authored-by: Lincoln Stein <lincoln.stein@gmail.com> * chore(backend): reorganized migrations, but something still broken * Fix migration 28 crash when `client_state.data` column is absent (#70) * Initial plan * Fix migration 28 to handle missing data column in client_state table Co-authored-by: lstein <111189+lstein@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Consolidate multiuser DB migrations 27–29 into a single migration step (#71) * Initial plan * Consolidate migrations 27, 28, and 29 into a single migration step Co-authored-by: lstein <111189+lstein@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Add `--root` option to user management CLI utilities (#81) * Initial plan * Add --root option to user management CLI utilities Co-authored-by: lstein <111189+lstein@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Fix queue clear() endpoint to respect user_id for multi-tenancy (#75) Co-authored-by: lstein <111189+lstein@users.noreply.github.com> Add tests for session queue clear() user_id scoping Co-authored-by: lstein <111189+lstein@users.noreply.github.com> chore(frontend): rebuild typegen Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> * fix: use AdminUserOrDefault for pause and resume queue endpoints (#77) Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * fix: queue pause/resume buttons disabled in single-user mode (#83) In single-user mode, currentUser is never populated (no auth), so `currentUser?.is_admin ?? false` always returns false, disabling the buttons. Follow the same pattern as useIsModelManagerEnabled: treat as admin when multiuser mode is disabled, and check is_admin flag when enabled. Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * fix: enforce board ownership checks in multiuser mode (#84) - get_board: verify current user owns the board (or is admin), return 403 otherwise - update_board: verify ownership before updating, 404 if not found, 403 if unauthorized - delete_board: verify ownership before deleting, 404 if not found, 403 if unauthorized - list_all_board_image_names: add CurrentUserOrDefault auth and ownership check for non-'none' board IDs test: add ownership enforcement tests for board endpoints in multiuser mode - Auth requirement tests for get, update, delete, and list_image_names - Cross-user 403 forbidden tests (non-owner cannot access/modify/delete) - Admin bypass tests (admin can access/update/delete any user's board) - Board listing isolation test (users only see their own boards) - Refactored fixtures to use monkeypatch (consistent with other test files) Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Fix: Clear auth state when switching from multiuser to single-user mode (#86) Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Fix race conditions in download queue and model install service (#98) * Initial plan * Fix race conditions in download queue and model install service Co-authored-by: lstein <111189+lstein@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: lstein <111189+lstein@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: lstein <111189+lstein@users.noreply.github.com> Co-authored-by: Weblate (bot) <hosted@weblate.org> Co-authored-by: Jonathan <34005131+JPPhoto@users.noreply.github.com> |
||
|
|
7aa3c95767 |
ui: translations update from weblate (#8905)
* translationBot(ui): update translation (Italian) Currently translated at 98.0% (2205 of 2250 strings) Co-authored-by: Riccardo Giovanetti <riccardo.giovanetti@gmail.com> Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ Translation: InvokeAI/Web UI * translationBot(ui): update translation files Updated by "Remove blank strings" hook in Weblate. Co-authored-by: Hosted Weblate <hosted@weblate.org> Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/ Translation: InvokeAI/Web UI * translationBot(ui): update translation (Italian) Currently translated at 97.8% (2210 of 2259 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Italian) Currently translated at 97.8% (2224 of 2272 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Italian) Currently translated at 98.1% (2252 of 2295 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Italian) Currently translated at 98.0% (2264 of 2309 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ --------- Co-authored-by: Riccardo Giovanetti <riccardo.giovanetti@gmail.com> |
||
|
|
b9f9015214 |
Feat(Model Manager): Add improved download manager with pause/resume partial download. (#8864)
* Refine messaging and pause behavior * Improved resume download behavior * Syntax fix * Formatting * Improved partial download recovering * fix(downloads): resume integrity, serialized parts, and UI feedback * Fix download test expectations and multifile totals * Ruff appease * schema updates * schema fix * Added toast msg if partial file was deleted. * Formatting * Fixed "missing temp file" message pop up * Update invokeai/app/services/download/download_default.py Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Fix: Add bulk action buttons and force resync on backend reconnect. --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Lincoln Stein <lincoln.stein@gmail.com> |
||
|
|
89df130ca1 |
ui: translations update from weblate (#8881)
* translationBot(ui): update translation (Italian) Currently translated at 98.0% (2205 of 2250 strings) Co-authored-by: Riccardo Giovanetti <riccardo.giovanetti@gmail.com> Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ Translation: InvokeAI/Web UI * translationBot(ui): update translation files Updated by "Remove blank strings" hook in Weblate. Co-authored-by: Hosted Weblate <hosted@weblate.org> Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/ Translation: InvokeAI/Web UI * translationBot(ui): update translation (Italian) Currently translated at 97.8% (2210 of 2259 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Italian) Currently translated at 97.8% (2224 of 2272 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Italian) Currently translated at 98.1% (2252 of 2295 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ --------- Co-authored-by: Riccardo Giovanetti <riccardo.giovanetti@gmail.com> |
||
|
|
e9246c1899 |
Feature(UI): Add text tool to canvas (#8723)
* Initial mashup of mentioned feature. Still need to resolve some quirks and kinks. * Clean text tool integration * Fixed text tool opions bar jumping and added more fonts * Touch up for cursor styling * Minor addition to doc file * Appeasing frontend checks * Prettier fix * knip fixes * Added safe zones to font selection and color picker to be clickable without commiting text. * Removed color probing on cursor and added dynamic font display for fallback, minor tweaks * Finally fixed the text shifting on commit * Cursor now represent actual input field size. Tidy up options UI * Some strikethrough and underline line tweaks * Replaced the focus retry loop with a callback‑ref based approach in in CanvasTextOverlay.tsx Renamed containerMetrics to textContainerData in CanvasTextOverlay.tsx Fixed mouse cursor disapearing during typing. * Added missing localistaion string * Moved canvas-text-tool.md to docs/contributing/frontend * ui: Improve functionality of the text toolbar Few things done with this commit. - The varying size of the font selector box has been fixed. The UI no longer shifts and moves with font change. - We no longer format the font size input to add px each time. Instead now just have a permanent px indicator. - The bug with the random text inputs on the slider value has also been fixed. - The font size value is only committed on blur keeping it consistent with other editing apps. - Fixed the spacing of the toolbar to make it look cleaner. - Font size now permits increments of 1. * Added autoselect text in font size on click allowing immediate imput * Improvement: Added uncommited layer state with CTRL-move and options to select line spacing. * Added rotation handle to rotate uncommiitted text layer. * Fix: Redirect user facing labels to use localization file + Add tool discription to docs * Fixed box padding. Disable tool swich when text input is active, added message on canvas for better UX. * Updated Text tool description * Updated Text tool description * Typo * Add draggable text-box border with improved cursor feedback and larger hit targets. Supress hotkeys on uncommitted text. * Lint * Fix(bug): text commit to link uploaded image assets instead of embedding full base64 --------- Co-authored-by: Lincoln Stein <lincoln.stein@gmail.com> Co-authored-by: blessedcoolant <54517381+blessedcoolant@users.noreply.github.com> |
||
|
|
b0f7b555b7 |
feat(z-image): add Z-Image Base (undistilled) model variant support (#8799)
* feat(z-image): add Z-Image Base (undistilled) model variant support - Add ZImageVariantType enum with 'turbo' and 'zbase' variants - Auto-detect variant on import via scheduler_config.json shift value (3.0=turbo, 6.0=zbase) - Add database migration to populate variant field for existing Z-Image models - Re-add LCM scheduler with variant-aware filtering (LCM hidden for zbase) - Auto-reset scheduler to Euler when switching to zbase model if LCM selected - Update frontend to show/hide LCM option based on model variant - Add toast notification when scheduler is auto-reset Z-Image Base models are undistilled and require more steps (28-50) with higher guidance (3.0-5.0), while Z-Image Turbo is distilled for ~8 steps with CFG 1.0. LCM scheduler only works with distilled (Turbo) models. * Chore ruff format * Chore fix windows path * feat(z-image): filter LoRAs by variant compatibility and warn on mismatch LoRA picker now hides Z-Image LoRAs with incompatible variants (e.g. ZBase LoRAs when using Turbo model). LoRAs without a variant are always shown. Backend loaders warn at runtime if a LoRA variant doesn't match the transformer variant. * Chore typegen --------- Co-authored-by: Lincoln Stein <lincoln.stein@gmail.com> |
||
|
|
dbb20a011a |
Feature: Canvas Blend and Boolean modes (#8661)
* feat(canvas): add raster layer blend modes and boolean operations submenu; support per-layer globalCompositeOperation in compositor; UI to toggle and select color blend modes (multiply, screen, darken, lighten, color-dodge, color-burn, hard-light, soft-light, difference, hue, saturation, color, luminosity). * feat(canvas): boolean ops submenu and UI polish * (chore): prettier lint * add icons to boolean submenu items * add delete button for color blend operations * move composite operation type and imports * chore: pnpm eslint * update blend modes order * update default blend mode to 'color' * add i18n for blend modes * actually use translations for blend modes now * move composite options into types.ts * cleanup and comments * update names * move constant mapping out of function * feat(ui): Refactor Blend Mode Implementation - Blend Modes are not right click menu options anymore. Instead they rest above the layer panel as they do in other art programs readily available for each layer. - Blend Modes have been resorted to match the listings of other art programs so users can avail their muscle memory. - Blend Mode now defaults to `Normal` for each layer as it should. - The extra layer operations have now been moved down to the `Operations Bar` at the bottom of the layer stack. This is to increase familiarity again with other art programs and also to make space for us in the top action bar. - The Operations Bars operations have been resorted in order of usage that makes sense. * fix: use source-over instead of normal * fix: pixel fix for slightly offset action bar labels. * feat(canvas): boolean raster merge creates new layer and disables sources * (fix) lint errors * remove extra typecast --------- Co-authored-by: Lincoln Stein <lincoln.stein@gmail.com> Co-authored-by: blessedcoolant <54517381+blessedcoolant@users.noreply.github.com> |
||
|
|
0fb2ae4fae |
ui: translations update from weblate (#8878)
* translationBot(ui): update translation (Italian) Currently translated at 98.0% (2205 of 2250 strings) Co-authored-by: Riccardo Giovanetti <riccardo.giovanetti@gmail.com> Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ Translation: InvokeAI/Web UI * translationBot(ui): update translation files Updated by "Remove blank strings" hook in Weblate. Co-authored-by: Hosted Weblate <hosted@weblate.org> Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/ Translation: InvokeAI/Web UI * translationBot(ui): update translation (Italian) Currently translated at 97.8% (2210 of 2259 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ * translationBot(ui): update translation (Italian) Currently translated at 97.8% (2224 of 2272 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ --------- Co-authored-by: Riccardo Giovanetti <riccardo.giovanetti@gmail.com> |
||
|
|
77e1ac19fc |
ui: translations update from weblate (#8856)
* translationBot(ui): update translation (Italian) Currently translated at 98.0% (2205 of 2250 strings) Co-authored-by: Riccardo Giovanetti <riccardo.giovanetti@gmail.com> Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ Translation: InvokeAI/Web UI * translationBot(ui): update translation files Updated by "Remove blank strings" hook in Weblate. Co-authored-by: Hosted Weblate <hosted@weblate.org> Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/ Translation: InvokeAI/Web UI * translationBot(ui): update translation (Italian) Currently translated at 97.8% (2210 of 2259 strings) Translation: InvokeAI/Web UI Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ --------- Co-authored-by: Riccardo Giovanetti <riccardo.giovanetti@gmail.com> |
||
|
|
b23f18734b |
feat(model_manager): Add scan and delete of orphaned models (#8826)
* Add script and UI to remove orphaned model files - This commit adds command-line and Web GUI functionality for identifying and optionally removing models in the models directory that are not referenced in the database. Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Add backend service and API routes for orphaned models sync Co-authored-by: lstein <111189+lstein@users.noreply.github.com> Add expandable file list to orphaned models dialog Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * Fix cache invalidation after deleting orphaned models Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * (bugfix) improve status messages * docs(backend): add info on the orphaned model detection/removal feature * Update docs/features/orphaned_model_removal.md --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: lstein <111189+lstein@users.noreply.github.com> Co-authored-by: dunkeroni <dunkeroni@gmail.com> |
||
|
|
76b0838094 |
Feature(backend): Add user toggle to run encoder models on CPU (#8777)
* feature(backend) Add user toggle to run encoder models on CPU Co-authored-by: lstein <111189+lstein@users.noreply.github.com> Add frontend UI for CPU-only model execution toggle Co-authored-by: lstein <111189+lstein@users.noreply.github.com> * chore(frontend): remove package lock file created by npm --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: lstein <111189+lstein@users.noreply.github.com> Co-authored-by: Jonathan <34005131+JPPhoto@users.noreply.github.com> |
||
|
|
b7d7cd0748 |
Feat(UI): Add linear and radial gradient tools to canvas (#8774)
* Adding gradient tool to canvas. Lineara and radial. * Formatting again... * Formatting again 2... * Minor bug fix * Some button design tweaking * Fixed icorrect wording where Circular was used instead of Radial. * Update invokeai/frontend/web/src/features/controlLayers/konva/CanvasObject/CanvasObjectGradient.ts Co-authored-by: dunkeroni <dunkeroni@gmail.com> * Update invokeai/frontend/web/src/features/controlLayers/components/Tool/ToolGradientButton.tsx Co-authored-by: dunkeroni <dunkeroni@gmail.com> * Update invokeai/frontend/web/src/features/controlLayers/components/Tool/ToolGradientButton.tsx Co-authored-by: dunkeroni <dunkeroni@gmail.com> * Update invokeai/frontend/web/src/features/controlLayers/components/Tool/ToolGradientButton.tsx Co-authored-by: dunkeroni <dunkeroni@gmail.com> * Autocommit fix on mouse leaving canvas area * feature(canvas): move gradient mode controls to top toolbar; remove popover mode buttons and group clip+mode cluster * (chore) prettier * remove fixed icon size --------- Co-authored-by: dunkeroni <dunkeroni@gmail.com> Co-authored-by: Lincoln Stein <lincoln.stein@gmail.com> |
||
|
|
d5c59ee64e |
ui: translations update from weblate (#8834)
* translationBot(ui): update translation (Italian) Currently translated at 98.0% (2205 of 2250 strings) Co-authored-by: Riccardo Giovanetti <riccardo.giovanetti@gmail.com> Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/it/ Translation: InvokeAI/Web UI * translationBot(ui): update translation files Updated by "Remove blank strings" hook in Weblate. Co-authored-by: Hosted Weblate <hosted@weblate.org> Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/ Translation: InvokeAI/Web UI --------- Co-authored-by: Riccardo Giovanetti <riccardo.giovanetti@gmail.com> |
||
|
|
c186e51b30 |
translationBot(ui): update translation (Russian) (#8830)
Currently translated at 59.7% (1344 of 2249 strings) Translate-URL: https://hosted.weblate.org/projects/invokeai/web-ui/ru/ Translation: InvokeAI/Web UI Co-authored-by: DustyShoe <warukeichi@gmail.com> |
||
|
|
9566f9a23f |
Feat(UI): Reintroduce paged gallery view as option (#8772)
* Switched to use v5.x gallery pagination design. * Improved pagination UX and gallery grid calculation * Minor bug fix * Formatting... * Fixed Jump to page input behavior and "Locate in gallery" logic. * Changed Jump input field to select text on click for better UX. |