@imgly/plugin-ai-image-generation-web 0.2.4 → 0.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,18 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [0.2.5] - 2025-09-03
6
+
7
+ ### New Features
8
+
9
+ - [image-generation] **NanoBanana Provider**: Added NanoBanana text-to-image provider via fal.ai with fast generation times, 1024×1024 resolution, support for multiple output formats (JPEG, PNG), configurable number of images (1-4), and remixPageWithPrompt quick action
10
+ - [image-generation] **NanoBananaEdit Provider**: Added NanoBananaEdit image-to-image provider via fal.ai for editing existing images with text prompts, supporting all standard quick actions (editImage, swapBackground, styleTransfer, artistTransfer, createVariant, combineImages with up to 10 images, remixPage, remixPageWithPrompt)
11
+
12
+ ### Bug Fixes
13
+
14
+ - [all] **fal.ai Provider Configuration**: Fixed singleton configuration conflict when using multiple fal.ai providers with different proxy URLs. Each provider now maintains its own client instance instead of overwriting a global configuration
15
+ - [video-generation] **Missing Dependency**: Added missing `@fal-ai/client` dependency to plugin-ai-video-generation-web package.json to ensure the package works correctly when installed independently
16
+
5
17
  ## [0.2.4] - 2025-08-07
6
18
 
7
19
  ### New Features
package/README.md CHANGED
@@ -106,6 +106,13 @@ CreativeEditorSDK.create(domElement, {
106
106
  'x-client-version': '1.0.0'
107
107
  }
108
108
  }),
109
+ FalAiImage.NanoBanana({
110
+ proxyUrl: 'http://your-proxy-server.com/api/proxy',
111
+ headers: {
112
+ 'x-custom-header': 'value',
113
+ 'x-client-version': '1.0.0'
114
+ }
115
+ }),
109
116
  FalAiImage.Recraft20b({
110
117
  proxyUrl: 'http://your-proxy-server.com/api/proxy',
111
118
  headers: {
@@ -131,6 +138,13 @@ CreativeEditorSDK.create(domElement, {
131
138
  'x-client-version': '1.0.0'
132
139
  }
133
140
  }),
141
+ FalAiImage.NanoBananaEdit({
142
+ proxyUrl: 'http://your-proxy-server.com/api/proxy',
143
+ headers: {
144
+ 'x-custom-header': 'value',
145
+ 'x-client-version': '1.0.0'
146
+ }
147
+ }),
134
148
  OpenAiImage.GptImage1.Image2Image({
135
149
  proxyUrl: 'http://your-proxy-server.com/api/proxy',
136
150
  headers: {
@@ -364,6 +378,73 @@ Key features:
364
378
  - Maintains original dimensions
365
379
  - Canvas quick-action integration
366
380
 
381
+ #### 9. NanoBanana (Text-to-Image)
382
+
383
+ A fast and efficient text-to-image model from fal.ai that generates high-quality images:
384
+
385
+ ```typescript
386
+ text2image: FalAiImage.NanoBanana({
387
+ proxyUrl: 'http://your-proxy-server.com/api/proxy',
388
+ headers: {
389
+ 'x-custom-header': 'value',
390
+ 'x-client-version': '1.0.0'
391
+ }
392
+ })
393
+ ```
394
+
395
+ Key features:
396
+ - Fast generation times for quick prototyping
397
+ - High-quality image output at 1024×1024 resolution
398
+ - Simple prompt-based interface
399
+ - Support for multiple output formats (JPEG, PNG)
400
+ - Configurable number of images (1-4)
401
+ - Supports page remixing with custom prompts
402
+ - Custom headers support for API requests
403
+
404
+ **Custom Translations:**
405
+ ```typescript
406
+ cesdk.i18n.setTranslations({
407
+ en: {
408
+ 'ly.img.plugin-ai-image-generation-web.fal-ai/nano-banana.property.prompt': 'Describe your image',
409
+ 'ly.img.plugin-ai-image-generation-web.fal-ai/nano-banana.property.num_images': 'Number of Images',
410
+ 'ly.img.plugin-ai-image-generation-web.fal-ai/nano-banana.property.output_format': 'Output Format'
411
+ }
412
+ });
413
+ ```
414
+
415
+ #### 10. NanoBananaEdit (Image-to-Image)
416
+
417
+ An image editing model from fal.ai that transforms existing images using text prompts:
418
+
419
+ ```typescript
420
+ image2image: FalAiImage.NanoBananaEdit({
421
+ proxyUrl: 'http://your-proxy-server.com/api/proxy',
422
+ headers: {
423
+ 'x-custom-header': 'value',
424
+ 'x-client-version': '1.0.0'
425
+ }
426
+ })
427
+ ```
428
+
429
+ Key features:
430
+ - Edit existing images with text prompts
431
+ - Supports combining multiple images (up to 10 images)
432
+ - Maintains original image dimensions automatically
433
+ - Supports all standard image editing quick actions
434
+ - Fast processing times
435
+ - Canvas quick-action integration
436
+ - Custom headers support for API requests
437
+
438
+ **Custom Translations:**
439
+ ```typescript
440
+ cesdk.i18n.setTranslations({
441
+ en: {
442
+ 'ly.img.plugin-ai-image-generation-web.fal-ai/nano-banana/edit.property.prompt': 'Edit instructions',
443
+ 'ly.img.plugin-ai-image-generation-web.fal-ai/nano-banana/edit.property.image_url': 'Source Image'
444
+ }
445
+ });
446
+ ```
447
+
367
448
  ### Customizing Labels and Translations
368
449
 
369
450
  You can customize all labels and text in the AI image generation interface using the translation system. This allows you to provide better labels for your users in any language.
@@ -401,22 +482,27 @@ cesdk.i18n.setTranslations({
401
482
 
402
483
  #### QuickAction Translations
403
484
 
404
- QuickActions (like "Edit Image", "Style Transfer", etc.) use their own translation keys:
485
+ QuickActions (like "Edit Image", "Style Transfer", etc.) use their own translation keys with provider-specific overrides:
405
486
 
406
487
  ```typescript
407
488
  cesdk.i18n.setTranslations({
408
489
  en: {
409
- // QuickAction button labels
490
+ // Provider-specific translations (highest priority)
491
+ 'ly.img.plugin-ai-image-generation-web.fal-ai/gemini-flash-edit.quickAction.editImage': 'Edit with Gemini',
492
+ 'ly.img.plugin-ai-image-generation-web.fal-ai/flux-pro/kontext.quickAction.styleTransfer': 'Style with Flux Pro Kontext',
493
+ 'ly.img.plugin-ai-image-generation-web.open-ai/gpt-image-1/image2image.quickAction.editImage': 'Edit with GPT',
494
+
495
+ // Generic plugin translations
410
496
  'ly.img.plugin-ai-image-generation-web.quickAction.editImage': 'Edit Image...',
411
497
  'ly.img.plugin-ai-image-generation-web.quickAction.swapBackground': 'Swap Background...',
412
498
  'ly.img.plugin-ai-image-generation-web.quickAction.styleTransfer': 'Style Transfer...',
413
499
  'ly.img.plugin-ai-image-generation-web.quickAction.createVariant': 'Create Variant...',
500
+ 'ly.img.plugin-ai-image-generation-web.quickAction.artistTransfer': 'Painted By...',
414
501
 
415
502
  // QuickAction input fields and buttons
416
503
  'ly.img.plugin-ai-image-generation-web.quickAction.editImage.prompt': 'Edit Image...',
417
504
  'ly.img.plugin-ai-image-generation-web.quickAction.editImage.prompt.placeholder': 'e.g. "Add a sunset"',
418
505
  'ly.img.plugin-ai-image-generation-web.quickAction.editImage.apply': 'Change',
419
-
420
506
  'ly.img.plugin-ai-image-generation-web.quickAction.swapBackground.prompt': 'Swap Background...',
421
507
  'ly.img.plugin-ai-image-generation-web.quickAction.swapBackground.prompt.placeholder': 'e.g. "Beach at sunset"',
422
508
  'ly.img.plugin-ai-image-generation-web.quickAction.swapBackground.apply': 'Swap'
@@ -424,12 +510,59 @@ cesdk.i18n.setTranslations({
424
510
  });
425
511
  ```
426
512
 
427
- **QuickAction Translation Structure:**
513
+ **QuickAction Translation Priority:**
514
+ 1. Provider-specific: `ly.img.plugin-ai-image-generation-web.${provider}.quickAction.${action}.${field}`
515
+ 2. Generic plugin: `ly.img.plugin-ai-image-generation-web.quickAction.${action}.${field}`
516
+
517
+ **Translation Structure:**
428
518
  - Base key (e.g., `.quickAction.editImage`): Button text when QuickAction is collapsed
429
519
  - `.prompt`: Label for input field when expanded
430
520
  - `.prompt.placeholder`: Placeholder text for input field
431
521
  - `.apply`: Text for action/submit button
432
522
 
523
+ #### QuickAction Dropdown Options
524
+
525
+ Some QuickActions like Artist Transfer and Style Transfer include dropdown menus with predefined options. You can customize these dropdown labels using provider-specific translation keys:
526
+
527
+ ```typescript
528
+ cesdk.i18n.setTranslations({
529
+ en: {
530
+ // Artist Transfer dropdown options (provider-specific)
531
+ 'ly.img.plugin-ai-image-generation-web.quickAction.artistTransfer.fal-ai/gemini-flash-edit.property.artist.van-gogh': 'Van Gogh',
532
+ 'ly.img.plugin-ai-image-generation-web.quickAction.artistTransfer.fal-ai/gemini-flash-edit.property.artist.monet': 'Monet',
533
+ 'ly.img.plugin-ai-image-generation-web.quickAction.artistTransfer.fal-ai/gemini-flash-edit.property.artist.picasso': 'Picasso',
534
+ 'ly.img.plugin-ai-image-generation-web.quickAction.artistTransfer.fal-ai/gemini-flash-edit.property.artist.dali': 'Dalí',
535
+ 'ly.img.plugin-ai-image-generation-web.quickAction.artistTransfer.fal-ai/gemini-flash-edit.property.artist.matisse': 'Matisse',
536
+ 'ly.img.plugin-ai-image-generation-web.quickAction.artistTransfer.fal-ai/gemini-flash-edit.property.artist.warhol': 'Warhol',
537
+ 'ly.img.plugin-ai-image-generation-web.quickAction.artistTransfer.fal-ai/gemini-flash-edit.property.artist.michelangelo': 'Michelangelo',
538
+ 'ly.img.plugin-ai-image-generation-web.quickAction.artistTransfer.fal-ai/gemini-flash-edit.property.artist.da-vinci': 'Da Vinci',
539
+ 'ly.img.plugin-ai-image-generation-web.quickAction.artistTransfer.fal-ai/gemini-flash-edit.property.artist.rembrandt': 'Rembrandt',
540
+ 'ly.img.plugin-ai-image-generation-web.quickAction.artistTransfer.fal-ai/gemini-flash-edit.property.artist.mondrian': 'Mondrian',
541
+ 'ly.img.plugin-ai-image-generation-web.quickAction.artistTransfer.fal-ai/gemini-flash-edit.property.artist.kahlo': 'Frida Kahlo',
542
+ 'ly.img.plugin-ai-image-generation-web.quickAction.artistTransfer.fal-ai/gemini-flash-edit.property.artist.hokusai': 'Hokusai',
543
+
544
+ // Style Transfer dropdown options (provider-specific)
545
+ 'ly.img.plugin-ai-image-generation-web.quickAction.styleTransfer.fal-ai/gemini-flash-edit.property.style.water': 'Watercolor Painting',
546
+ 'ly.img.plugin-ai-image-generation-web.quickAction.styleTransfer.fal-ai/gemini-flash-edit.property.style.oil': 'Oil Painting',
547
+ 'ly.img.plugin-ai-image-generation-web.quickAction.styleTransfer.fal-ai/gemini-flash-edit.property.style.charcoal': 'Charcoal Sketch',
548
+ 'ly.img.plugin-ai-image-generation-web.quickAction.styleTransfer.fal-ai/gemini-flash-edit.property.style.pencil': 'Pencil Drawing',
549
+ 'ly.img.plugin-ai-image-generation-web.quickAction.styleTransfer.fal-ai/gemini-flash-edit.property.style.pastel': 'Pastel Artwork',
550
+ 'ly.img.plugin-ai-image-generation-web.quickAction.styleTransfer.fal-ai/gemini-flash-edit.property.style.ink': 'Ink Wash',
551
+ 'ly.img.plugin-ai-image-generation-web.quickAction.styleTransfer.fal-ai/gemini-flash-edit.property.style.stained-glass': 'Stained Glass Window',
552
+ 'ly.img.plugin-ai-image-generation-web.quickAction.styleTransfer.fal-ai/gemini-flash-edit.property.style.japanese': 'Japanese Woodblock Print',
553
+
554
+ // Generic fallback options (applies to all providers)
555
+ 'ly.img.plugin-ai-image-generation-web.quickAction.artistTransfer.property.artist.van-gogh': 'Van Gogh',
556
+ 'ly.img.plugin-ai-image-generation-web.quickAction.styleTransfer.property.style.water': 'Watercolor Painting'
557
+ }
558
+ });
559
+ ```
560
+
561
+ The system checks for translations in this order (highest to lowest priority):
562
+
563
+ 1. **Provider-specific**: `ly.img.plugin-ai-image-generation-web.quickAction.${actionName}.${providerId}.property.${field}.${option}` - Override labels for a specific AI provider
564
+ 2. **Generic**: `ly.img.plugin-ai-image-generation-web.quickAction.${actionName}.property.${field}.${option}` - Override labels for all AI plugins
565
+
433
566
  ### Configuration Options
434
567
 
435
568
  The plugin accepts the following configuration options:
@@ -677,6 +810,26 @@ FalAiImage.FluxProKontextMaxEdit(config: {
677
810
  })
678
811
  ```
679
812
 
813
+ #### NanoBanana
814
+
815
+ ```typescript
816
+ FalAiImage.NanoBanana(config: {
817
+ proxyUrl: string;
818
+ headers?: Record<string, string>;
819
+ debug?: boolean;
820
+ })
821
+ ```
822
+
823
+ #### NanoBananaEdit
824
+
825
+ ```typescript
826
+ FalAiImage.NanoBananaEdit(config: {
827
+ proxyUrl: string;
828
+ headers?: Record<string, string>;
829
+ debug?: boolean;
830
+ })
831
+ ```
832
+
680
833
  ## UI Integration
681
834
 
682
835
  The plugin automatically registers the following UI components:
@@ -769,6 +922,8 @@ const myImageProvider = {
769
922
  - GptImage1.Image2Image: `ly.img.ai.open-ai/gpt-image-1/image2image`
770
923
  - FluxProKontextEdit: `ly.img.ai.fal-ai/flux-pro/kontext`
771
924
  - FluxProKontextMaxEdit: `ly.img.ai.fal-ai/flux-pro/kontext/max`
925
+ - NanoBanana: `ly.img.ai.fal-ai/nano-banana`
926
+ - NanoBananaEdit: `ly.img.ai.fal-ai/nano-banana/edit`
772
927
 
773
928
  ### Asset History
774
929
 
@@ -782,6 +937,8 @@ Generated images are automatically stored in asset sources with the following ID
782
937
  - GptImage1.Image2Image: `open-ai/gpt-image-1/image2image.history`
783
938
  - FluxProKontextEdit: `fal-ai/flux-pro/kontext.history`
784
939
  - FluxProKontextMaxEdit: `fal-ai/flux-pro/kontext/max.history`
940
+ - NanoBanana: `fal-ai/nano-banana.history`
941
+ - NanoBananaEdit: `fal-ai/nano-banana/edit.history`
785
942
 
786
943
  ### Dock Integration
787
944
 
@@ -0,0 +1,13 @@
1
+ import { ImageOutput, CommonProviderConfiguration, type Provider } from '@imgly/plugin-ai-generation-web';
2
+ import CreativeEditorSDK from '@cesdk/cesdk-js';
3
+ type NanoBananaInput = {
4
+ prompt: string;
5
+ num_images?: number;
6
+ sync_mode?: boolean;
7
+ output_format?: 'jpeg' | 'png';
8
+ };
9
+ export declare function NanoBanana(config: CommonProviderConfiguration<NanoBananaInput, ImageOutput>): (context: {
10
+ cesdk: CreativeEditorSDK;
11
+ }) => Promise<Provider<'image', NanoBananaInput, ImageOutput>>;
12
+ declare function getProvider(cesdk: CreativeEditorSDK, config: CommonProviderConfiguration<NanoBananaInput, ImageOutput>): Provider<'image', NanoBananaInput, ImageOutput>;
13
+ export default getProvider;
@@ -0,0 +1,13 @@
1
+ import { ImageOutput, type Provider, type CommonProviderConfiguration } from '@imgly/plugin-ai-generation-web';
2
+ import CreativeEditorSDK from '@cesdk/cesdk-js';
3
+ type NanoBananaEditInput = {
4
+ prompt: string;
5
+ image_url?: string;
6
+ image_urls?: string[];
7
+ exportFromBlockIds?: number[];
8
+ };
9
+ export declare function NanoBananaEdit(config: CommonProviderConfiguration<NanoBananaEditInput, ImageOutput>): (context: {
10
+ cesdk: CreativeEditorSDK;
11
+ }) => Promise<Provider<'image', NanoBananaEditInput, ImageOutput>>;
12
+ declare function getProvider(cesdk: CreativeEditorSDK, config: CommonProviderConfiguration<NanoBananaEditInput, ImageOutput>): Provider<'image', NanoBananaEditInput, ImageOutput>;
13
+ export default getProvider;
@@ -1,9 +1,9 @@
1
- import { RecraftV3Input } from '@fal-ai/client/endpoints';
1
+ import { RecraftV3TextToImageInput } from '@fal-ai/client/endpoints';
2
2
  export declare function getImageDimensions(id: string): {
3
3
  width: number;
4
4
  height: number;
5
5
  };
6
- export type StyleId = Extract<RecraftV3Input['style'], string>;
6
+ export type StyleId = Extract<RecraftV3TextToImageInput['style'], string>;
7
7
  export declare const STYLES_IMAGE: {
8
8
  id: StyleId;
9
9
  label: string;
@@ -1,12 +1,12 @@
1
1
  import { CommonProviderConfiguration, type Provider } from '@imgly/plugin-ai-generation-web';
2
- import { type RecraftV3Input } from '@fal-ai/client/endpoints';
2
+ import { type RecraftV3TextToImageInput } from '@fal-ai/client/endpoints';
3
3
  import CreativeEditorSDK from '@cesdk/cesdk-js';
4
4
  type RecraftV3Output = {
5
5
  kind: 'image';
6
6
  url: string;
7
7
  };
8
- export type StyleId = Extract<RecraftV3Input['style'], string>;
9
- interface ProviderConfiguration extends CommonProviderConfiguration<RecraftV3Input, RecraftV3Output> {
8
+ export type StyleId = Extract<RecraftV3TextToImageInput['style'], string>;
9
+ interface ProviderConfiguration extends CommonProviderConfiguration<RecraftV3TextToImageInput, RecraftV3Output> {
10
10
  /**
11
11
  * Base URL used for the UI assets used in the plugin.
12
12
  *
@@ -17,6 +17,6 @@ interface ProviderConfiguration extends CommonProviderConfiguration<RecraftV3Inp
17
17
  }
18
18
  export declare function RecraftV3(config: ProviderConfiguration): (context: {
19
19
  cesdk: CreativeEditorSDK;
20
- }) => Promise<Provider<'image', RecraftV3Input, RecraftV3Output>>;
21
- declare function getProvider(cesdk: CreativeEditorSDK, config: ProviderConfiguration): Provider<'image', RecraftV3Input, RecraftV3Output>;
20
+ }) => Promise<Provider<'image', RecraftV3TextToImageInput, RecraftV3Output>>;
21
+ declare function getProvider(cesdk: CreativeEditorSDK, config: ProviderConfiguration): Provider<'image', RecraftV3TextToImageInput, RecraftV3Output>;
22
22
  export default getProvider;
@@ -0,0 +1,3 @@
1
+ import { type FalClient as FalClientType } from '@fal-ai/client';
2
+ export type FalClient = FalClientType;
3
+ export declare function createFalClient(proxyUrl: string, headers?: Record<string, string>): FalClient;
@@ -25,7 +25,10 @@ type ImageProviderConfiguration = {
25
25
  * Creates a base provider from schema. This should work out of the box
26
26
  * but may be rough around the edges and should/can be further customized.
27
27
  */
28
- declare function createImageProvider<I extends Record<string, any>>(options: {
28
+ declare function createImageProvider<I extends Record<string, any> & {
29
+ image_url?: string;
30
+ image_urls?: string[];
31
+ }>(options: {
29
32
  modelKey: string;
30
33
  name?: string;
31
34
  schema: OpenAPIV3.Document;
@@ -5,12 +5,16 @@ import { FluxProKontextEdit } from './FluxProKontextEdit';
5
5
  import { FluxProKontextMaxEdit } from './FluxProKontextMaxEdit';
6
6
  import { IdeogramV3 } from './IdeogramV3';
7
7
  import { IdeogramV3Remix } from './IdeogramV3Remix';
8
+ import { NanoBanana } from './NanoBanana';
9
+ import { NanoBananaEdit } from './NanoBananaEdit';
8
10
  declare const FalAi: {
9
11
  FluxProKontextEdit: typeof FluxProKontextEdit;
10
12
  FluxProKontextMaxEdit: typeof FluxProKontextMaxEdit;
11
13
  GeminiFlashEdit: typeof GeminiFlashEdit;
12
14
  IdeogramV3: typeof IdeogramV3;
13
15
  IdeogramV3Remix: typeof IdeogramV3Remix;
16
+ NanoBanana: typeof NanoBanana;
17
+ NanoBananaEdit: typeof NanoBananaEdit;
14
18
  Recraft20b: typeof Recraft20b;
15
19
  RecraftV3: typeof RecraftV3;
16
20
  };