IMG.LY AI Generation Utilities
A powerful toolkit for implementing AI generation providers in CreativeEditor SDK.
Overview
Note: This package is only relevant if you need to create new AI providers or extend existing functionality. For simple integration of AI features, use the @imgly/plugin-ai-apps-web package instead.
This package provides the foundation for creating AI generation plugins for CreativeEditor SDK. It offers a standardized interface for implementing AI generation providers that can create images, videos, audio, or text assets. The package includes utilities for handling:
- Provider registration and initialization
- User interface generation
- Global action registry for quick actions and plugin actions
- Type-safe quick action definitions
- Cross-plugin action support
Getting Started
Installation
npm install @imgly/plugin-ai-generation-web
Creating a Custom Provider
The core of this package is the Provider
interface which defines the contract for AI generation providers. Here's how to implement a basic provider:
import {
Provider,
ImageOutput,
initializeProvider,
loggingMiddleware,
CommonProviderConfiguration
} from '@imgly/plugin-ai-generation-web';
interface MyProviderConfiguration
extends CommonProviderConfiguration<MyInputType, ImageOutput> {
baseURL?: string;
}
function createMyImageProvider(config: MyProviderConfiguration): Provider<'image', MyInputType, ImageOutput> {
return {
id: 'my-image-provider',
kind: 'image',
initialize: async ({ engine, cesdk }) => {
myAIApi.configure({
apiKey: 'YOUR_API_KEY',
headers: config.headers
});
},
input: {
panel: {
type: 'schema',
document: myApiSchema,
inputReference: '#/components/schemas/GenerationInput',
getBlockInput: async (input) => ({
image: { width: 1024, height: 1024 }
})
},
quickActions: {
supported: {
'ly.img.editImage': {
mapInput: (input) => ({
prompt: input.prompt,
image_url: input.uri
})
},
'ly.img.styleTransfer': {
mapInput: (input) => ({
prompt: input.style,
image_url: input.uri
})
}
}
}
},
output: {
abortable: true,
history: '@imgly/indexedDB',
middleware: [loggingMiddleware()],
notification: {
success: {
show: true,
message: 'Generation successful!'
}
},
generate: async (input, { abortSignal, engine }) => {
const response = await myAIApi.generateImage(input, {
headers: config.headers
});
return {
kind: 'image',
url: response.imageUrl
};
}
}
};
}
const myImageProvider = createMyImageProvider({
proxyUrl: 'http://your-proxy-server.com/api/proxy',
headers: {
'x-client-version': '1.0.0',
'x-request-source': 'cesdk-plugin'
},
debug: false,
middleware: [loggingMiddleware()],
baseURL: 'https://assets.example.com'
});
Action Registry
The package includes a global ActionRegistry
for managing quick actions and plugin actions. To register a new action:
import { ActionRegistry } from '@imgly/plugin-ai-generation-web';
const registry = ActionRegistry.get();
const unregister = registry.register({
id: 'my-quick-action',
type: 'quick',
kind: 'image',
label: 'My Quick Action',
enable: true,
render: (context) => {
context.builder.Button('my-button', {
label: 'Generate',
onClick: async () => {
await context.generate({ prompt: 'Hello world' });
}
});
}
});
Provider Interface
The Provider interface is generic and type-safe, supporting four output kinds:
interface Provider<K extends OutputKind, I, O extends Output, C = O> { ... }
Common Provider Configuration
All providers should extend the CommonProviderConfiguration
interface, which provides standardized configuration options:
interface CommonProviderConfiguration<I, O extends Output> {
proxyUrl: string;
debug?: boolean;
middleware?: Middleware<I, O>[];
headers?: Record<string, string>;
history?: false | '@imgly/local' | '@imgly/indexedDB' | (string & {});
supportedQuickActions?: {
[quickActionId: string]: Partial<QuickActionSupport<I>> | false | null;
};
}
Extended Configuration Options
History Configuration
The history
field allows you to override the provider's default history storage behavior:
const provider = createMyImageProvider({
proxyUrl: 'https://proxy.example.com',
history: false,
});
Available Options:
false
: Disable history storage entirely
'@imgly/local'
: Use temporary local storage (not persistent across sessions)
'@imgly/indexedDB'
: Use browser IndexedDB storage (persistent across sessions)
string
: Use your own custom asset source ID
Quick Actions Configuration
The supportedQuickActions
field allows you to customize which quick actions are supported and how they behave:
const provider = createMyImageProvider({
proxyUrl: 'https://proxy.example.com',
supportedQuickActions: {
'ly.img.editImage': false,
'ly.img.swapBackground': {
mapInput: (input) => ({
prompt: input.prompt,
image_url: input.uri,
strength: 0.9,
style: 'REALISTIC'
})
},
'ly.img.customAction': {
mapInput: (input) => ({
prompt: `Custom prefix: ${input.text}`,
image_url: input.imageUrl
})
}
}
});
Configuration Values:
false
or null
: Remove the quick action entirely
true
: Keep the provider's default implementation
- Object with
mapInput
: Override the quick action with custom input mapping
- Object with other properties: Override with custom configuration
The headers
property allows you to include custom HTTP headers in all API requests made by your provider. This is useful for:
- Adding custom client identification headers
- Including version information
- Passing through metadata required by your API
- Adding correlation IDs for request tracing
Implementation Note: When implementing your provider's generate
function, ensure you merge the custom headers with any required headers for your API:
const response = await fetch(apiUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${apiKey}`,
...config.headers
},
body: JSON.stringify(requestData)
});
Key Provider Options
- id: Unique identifier for your provider
- kind: Type of asset generated ('image', 'video', 'audio', 'text')
- name: Optional human-readable name
- initialize: Setup function called when the provider is loaded
- input: Configuration for input UI and parameters
- output: Configuration for generation and result handling
Provider Output Options
The output
property has several important options:
- generate: Main function that performs the actual generation
- history: Asset storage strategy ('false', '@imgly/local', '@imgly/indexedDB', or custom ID)
- abortable: Whether generation can be cancelled by the user
- middleware: Array of middleware functions for pre/post-processing
- notification: Success and error notification configuration
- generationHintText: Text to display below the generation button
Notification Configuration
The notification system allows fine-grained control over success and error messages:
notification: {
success: {
show: true,
message: 'Generation successful!',
action: {
label: 'View',
onClick: (context) => { }
},
duration: 'short'
},
error: {
show: true,
message: 'Generation failed',
}
}
Streaming Generation
The generate
function can return a simple output object or an AsyncGenerator for streaming results:
generate: async (input, options) => {
const result = await api.generateImage(input);
return { kind: 'image', url: result.url };
}
generate: async function* (input, options) {
const stream = api.streamGenerationResult(input);
let inferredText: string = '';
for await (const chunk of stream) {
inferredText += chunk;
yield { kind: 'text', text: inferredText };
}
return { kind: 'text', text: inferredText };
}
Generation Hint Text
The generationHintText
property allows providers to display helpful information below the generation button:
generationHintText: "Generation may take up to a minute. You can close this panel and will be notified when ready."
Input Panel Types
The package supports two approaches for creating input panels:
1. Schema-based Input Panels
The schema
type uses OpenAPI specification to declaratively define your input form.
input: {
panel: {
type: 'schema',
document: myOpenAPISchema,
inputReference: '#/components/schemas/GenerationInput',
orderExtensionKeyword: 'x-order-properties',
getBlockInput: async (input) => ({
image: { width: 1024, height: 1024 }
}),
renderCustomProperty: {
imageUrl: (context, property) => {
const valueState = context.state('imageUrl', '');
context.builder.TextInput('imageUrl', {
inputLabel: 'Image URL',
...valueState
});
return () => { id: property.id, type: 'string', value: valueState.value };
}
}
}
}
OpenAPI Schema Example
{
"openapi": "3.0.0",
"components": {
"schemas": {
"GenerationInput": {
"type": "object",
"required": ["prompt"],
"properties": {
"prompt": {
"type": "string",
"title": "Prompt",
"description": "Describe what you want to generate",
"x-imgly-builder": {
"component": "TextArea"
}
},
"width": {
"type": "integer",
"title": "Width",
"default": 1024,
"enum": [512, 1024, 2048],
"x-imgly-builder": {
"component": "Select"
}
}
},
"x-order-properties": ["prompt", "width"]
}
}
}
}
Benefits of Schema-based Input
- Built-in validation based on schema constraints
- AI providers like fal.ai provide schemas for their models
- Automatic UI component generation based on property types
- Extensions like
x-imgly-builder
to specify component types
- Property ordering via
orderExtensionKeyword
- Customizable property rendering with
renderCustomProperty
2. Custom Input Panels
The custom
type gives you complete control over UI components. For more details on how to build custom panels and see all available builder components, refer to the Create a Custom Panel guide.
input: {
panel: {
type: 'custom',
render: (context, options) => {
const promptState = context.state('prompt', '');
context.builder.TextArea('prompt', {
inputLabel: 'Prompt',
...promptState
});
const widthState = context.state('width', 1024);
context.builder.Select('width', {
inputLabel: 'Width',
options: [
{ value: 512, label: '512px' },
{ value: 1024, label: '1024px' },
{ value: 2048, label: '2048px' }
],
...widthState
});
return {
getInput: () => ({
prompt: promptState.value,
width: widthState.value
}),
getBlockInput: () => ({
image: {
width: widthState.value,
height: widthState.value,
label: `AI Image: ${promptState.value.substring(0, 20)}...`
}
})
};
}
}
}
Benefits of Custom Input Panels
- Complete control over UI components and layout
- Complex logic between fields (dependencies, conditionals)
- Dynamic UI that changes based on user interactions
Panel User Flow Options
Both panel types accept additional configuration:
panel: {
type: 'schema',
userFlow: 'placeholder',
includeHistoryLibrary: true
}
The getBlockInput
Function
The getBlockInput
function is crucial for both panel types. It converts your input into the parameters needed to create a block in CreativeEditor SDK.
What It Does
- Defines dimensions, duration, and appearance of asset blocks
- Creates placeholders before generation completes
- Maps your AI provider's inputs to standardized block parameters
Required Return Values by Output Kind
Each output kind requires specific parameters:
For Images
getBlockInput: async (input) => ({
image: {
width: 1024,
height: 1024,
label: 'My Image'
}
});
For Videos
getBlockInput: async (input) => ({
video: {
width: 1280,
height: 720,
duration: 10,
label: 'My Video'
}
});
For Audio
getBlockInput: async (input) => ({
audio: {
duration: 30,
thumbnailUrl: 'path/to/img.jpg',
label: 'My Audio'
}
});
For Text
getBlockInput: async (input) => ({
text: {
length: 250,
label: 'My Text'
}
});
Quick Actions
Quick Actions provide context-aware AI generation capabilities directly in CreativeEditor SDK's canvas menu. Unlike panels (which appear in the side panel), quick actions appear when users select elements on the canvas.
Available Quick Action IDs
Here are all the quick action IDs that can be used in the supported
field of your provider configuration:
Image Quick Actions
-
ly.img.artistTransfer
: Transform image in the style of famous artists
- Input:
{ artist: string, uri: string }
-
ly.img.combineImages
: Combine multiple images with instructions
- Input:
{ prompt: string, uris: string[], exportFromBlockIds: number[] }
-
ly.img.createVariant
: Create a variation of the image
- Input:
{ prompt: string, uri: string }
-
ly.img.editImage
: Change image based on description
- Input:
{ prompt: string, uri: string }
-
ly.img.remixPage
: Convert the page into a single image
- Input:
{ prompt: string, uri: string }
-
ly.img.remixPageWithPrompt
: Remix the page with custom instructions
- Input:
{ prompt: string, uri: string }
-
ly.img.styleTransfer
: Transform image into different art styles
- Input:
{ style: string, uri: string }
-
ly.img.swapBackground
: Change the background of the image
- Input:
{ prompt: string, uri: string }
-
ly.img.gpt-image-1.changeStyleLibrary
: Apply different art styles (GPT-specific)
- Input:
{ prompt: string, uri: string }
Text Quick Actions
-
ly.img.changeTextTo
: Change text to a different format or style
- Input:
{ prompt: string, customPrompt: string }
-
ly.img.changeTone
: Change the tone of the text
- Input:
{ prompt: string, type: string }
-
ly.img.fix
: Fix spelling and grammar
- Input:
{ prompt: string }
-
ly.img.improve
: Improve writing quality
- Input:
{ prompt: string }
-
ly.img.longer
: Make text longer
- Input:
{ prompt: string }
-
ly.img.shorter
: Make text shorter
- Input:
{ prompt: string }
-
ly.img.translate
: Translate text to different languages
- Input:
{ prompt: string, language: string }
Video Quick Actions
ly.img.createVideo
: Opens the image2video generation panel with the current image
Provider Quick Action Support
Providers declare which quick actions they support and how to map quick action inputs to provider inputs:
const myProvider = {
input: {
quickActions: {
supported: {
'ly.img.editImage': {
mapInput: (quickActionInput) => ({
prompt: quickActionInput.prompt,
image_url: quickActionInput.uri
})
},
'ly.img.styleTransfer': {
mapInput: (quickActionInput) => ({
style: quickActionInput.style,
image_url: quickActionInput.uri
})
}
}
}
}
};
Quick Action Expanded View
Quick actions can have two rendering modes:
- Collapsed View: Shows as a simple button in the quick action menu alongside other actions
- Expanded View: Takes over the entire menu space, hiding other actions while the user interacts with this specific action
The expanded view is useful for quick actions that need user input (like text prompts). When a quick action is expanded, the complete menu is replaced with the expanded interface, and other menu items are not shown until the user either completes the action or cancels back to the collapsed view.
render: ({ builder, isExpanded, toggleExpand }) => {
if (isExpanded) {
builder.TextArea('prompt', { });
builder.ButtonRow('actions', { });
} else {
builder.Button('expand', {
label: 'Edit Image...',
onClick: toggleExpand
});
}
}
Customizing Labels and Text
You can customize all labels and text in the AI generation interface using the translation system. This allows you to provide better labels for your users in any language.
Translation Priority
The system checks for translations in this order (highest to lowest priority):
- Provider & Kind-specific:
ly.img.plugin-ai-${kind}-generation-web.${provider}.property.${field}
- Override labels for a specific AI provider and generation type
- Generic:
ly.img.plugin-ai-generation-web.property.${field}
- Override labels for all AI plugins
Where ${kind}
can be:
image
for image generation plugins
video
for video generation plugins
audio
for audio generation plugins
text
for text generation plugins
Basic Example
cesdk.i18n.setTranslations({
en: {
'ly.img.plugin-ai-generation-web.property.prompt': 'Describe what you want to create',
'ly.img.plugin-ai-generation-web.property.image_size': 'Image Dimensions',
'ly.img.plugin-ai-generation-web.property.duration': 'Video Length',
'ly.img.plugin-ai-image-generation-web.fal-ai/recraft-v3.property.prompt': 'Describe your Recraft image',
'ly.img.plugin-ai-image-generation-web.fal-ai/recraft-v3.property.image_size': 'Canvas Size',
'ly.img.plugin-ai-video-generation-web.fal-ai/veo3.property.prompt': 'Describe your video scene',
'ly.img.plugin-ai-video-generation-web.fal-ai/veo3.property.duration': 'Video Duration'
}
});
Dropdown Options
For dropdown menus, add the option value to the translation key:
cesdk.i18n.setTranslations({
en: {
'ly.img.plugin-ai-image-generation-web.fal-ai/recraft-v3.property.image_size.square_hd': 'Square HD (1024×1024)',
'ly.img.plugin-ai-image-generation-web.fal-ai/recraft-v3.property.image_size.portrait_4_3': 'Portrait 4:3 (768×1024)',
'ly.img.plugin-ai-video-generation-web.fal-ai/veo3.property.duration.5': '5 seconds',
'ly.img.plugin-ai-video-generation-web.fal-ai/veo3.property.duration.10': '10 seconds'
}
});
QuickAction Translations
QuickActions use their own translation keys with provider-specific overrides:
cesdk.i18n.setTranslations({
en: {
'ly.img.plugin-ai-image-generation-web.fal-ai/gemini-flash-edit.quickAction.editImage': 'Edit with Gemini',
'ly.img.plugin-ai-text-generation-web.anthropic.quickAction.improve': 'Improve with Claude',
'ly.img.plugin-ai-image-generation-web.quickAction.editImage': 'Edit Image...',
'ly.img.plugin-ai-image-generation-web.quickAction.editImage.prompt': 'Edit Image...',
'ly.img.plugin-ai-image-generation-web.quickAction.editImage.apply': 'Change',
'ly.img.plugin-ai-text-generation-web.quickAction.improve': 'Improve Text',
'ly.img.plugin-ai-text-generation-web.quickAction.translate': 'Translate Text',
'ly.img.plugin-ai-video-generation-web.quickAction.createVideo': 'Create Video'
}
});
QuickAction Translation Priority:
- Provider-specific:
ly.img.plugin-ai-${kind}-generation-web.${provider}.quickAction.${action}.${field}
- Generic plugin:
ly.img.plugin-ai-${kind}-generation-web.quickAction.${action}.${field}
Translation Structure:
- Base key (e.g.,
.quickAction.editImage
): Button text when QuickAction is collapsed
.prompt
: Label for input field when expanded
.prompt.placeholder
: Placeholder text for input field
.apply
: Text for action/submit button
Using Your Provider
Once you've created your provider, you need to initialize it with CreativeEditor SDK and integrate it into the UI.
Initializing Your Provider
Use the initializeProvider
function to register your provider:
import { initializeProvider } from '@imgly/plugin-ai-generation-web';
const myProvider = createMyProvider({
proxyUrl: 'http://your-proxy-server.com/api/proxy',
headers: {
'x-custom-header': 'value',
'x-client-version': '1.0.0'
}
});
function setupMyProvider(cesdk) {
const result = initializeProvider(
myProvider,
{
engine: cesdk.engine,
cesdk
},
{
debug: false,
dryRun: false
}
);
return result;
}
Panel IDs and Registration
When a provider is initialized, it automatically registers panels with specific IDs:
ly.img.plugin-ai-{kind}-generation-web.{provider-id}
For example:
- A provider with ID
my-image-provider
for images registers a panel with ID ly.img.plugin-ai-image-generation-web.my-image-provider
- A provider with ID
fal-ai/recraft-v3
for images registers a panel with ID ly.img.plugin-ai-image-generation-web.fal-ai/recraft-v3
You can programmatically get a panel ID using the getPanelId
function:
import { getPanelId } from '@imgly/plugin-ai-generation-web';
const panelId = getPanelId('my-image-provider');
cesdk.ui.openPanel(panelId);
Quick actions are automatically registered in canvas menus with these IDs:
ly.img.plugin-ai-{kind}-generation-web.canvasMenu
For example:
- Image quick actions:
ly.img.plugin-ai-image-generation-web.canvasMenu
- Video quick actions:
ly.img.plugin-ai-video-generation-web.canvasMenu
- Audio quick actions:
ly.img.plugin-ai-audio-generation-web.canvasMenu
- Text quick actions:
ly.img.plugin-ai-text-generation-web.canvasMenu
Customizing Quick Action Availability
You can control which quick actions appear in your application using the Feature API. This is useful when you want to:
- Show only specific AI capabilities to certain user groups
- Simplify the UI by hiding advanced features
- Create different feature sets for different subscription tiers
- Disable actions that aren't relevant to your use case
Disabling Specific Quick Actions
All quick actions are enabled by default. To hide specific quick actions from the UI:
cesdk.feature.enable(
'ly.img.plugin-ai-image-generation-web.quickAction.editImage',
false
);
cesdk.feature.enable('ly.img.plugin-ai-text-generation-web.quickAction.changeTone', false);
cesdk.feature.enable('ly.img.plugin-ai-text-generation-web.quickAction.translate', false);
Dynamic Feature Control
You can also pass a function to dynamically control feature availability based on context. This is powerful for implementing complex business logic, time-based features, or context-sensitive UI. See the CE.SDK Feature API documentation for more details.
cesdk.feature.enable(
'ly.img.plugin-ai-image-generation-web.quickAction.artistTransfer',
({ isPreviousEnable }) => {
const hour = new Date().getHours();
const isBusinessHours = hour >= 9 && hour < 18;
return isBusinessHours && isPreviousEnable();
}
);
cesdk.feature.enable(
'ly.img.plugin-ai-text-generation-web.quickAction.translate',
({ engine, isPreviousEnable }) => {
const selectedBlocks = engine.block.findAllSelected();
if (selectedBlocks.length === 0) return false;
const blockId = selectedBlocks[0];
const textContent = engine.block.getString(blockId, 'text/text');
const hasEnoughText = textContent && textContent.length > 20;
return hasEnoughText && isPreviousEnable();
}
);
Creating Feature Sets for Different User Tiers
function configureAIFeatures(cesdk, userTier) {
if (userTier === 'basic') {
cesdk.feature.enable('ly.img.plugin-ai-text-generation-web.quickAction.improve', true);
cesdk.feature.enable('ly.img.plugin-ai-text-generation-web.quickAction.fix', true);
cesdk.feature.enable('ly.img.plugin-ai-text-generation-web.quickAction.translate', false);
cesdk.feature.enable('ly.img.plugin-ai-text-generation-web.quickAction.changeTone', false);
cesdk.feature.enable('ly.img.plugin-ai-image-generation-web.quickAction.artistTransfer', false);
cesdk.feature.enable('ly.img.plugin-ai-image-generation-web.quickAction.styleTransfer', false);
} else if (userTier === 'premium') {
}
}
Available Feature Flags
Core Plugin Features
These feature flags control the main functionality of each AI plugin:
General Features:
ly.img.plugin-ai-{kind}-generation-web.providerSelect
- Enable/disable provider selection dropdown in panels
ly.img.plugin-ai-{kind}-generation-web.quickAction
- Enable/disable all quick actions for a plugin
ly.img.plugin-ai-{kind}-generation-web.quickAction.providerSelect
- Enable/disable provider selection dropdown in quick actions
Input Type Features (Image & Video only):
ly.img.plugin-ai-image-generation-web.fromText
- Enable/disable text-to-image generation
ly.img.plugin-ai-image-generation-web.fromImage
- Enable/disable image-to-image generation
ly.img.plugin-ai-video-generation-web.fromText
- Enable/disable text-to-video generation
ly.img.plugin-ai-video-generation-web.fromImage
- Enable/disable image-to-video generation
Usage Examples:
cesdk.feature.enable('ly.img.plugin-ai-video-generation-web.providerSelect', false);
cesdk.feature.enable('ly.img.plugin-ai-image-generation-web.fromImage', false);
cesdk.feature.enable('ly.img.plugin-ai-image-generation-web.fromText', true);
cesdk.feature.enable('ly.img.plugin-ai-image-generation-web.quickAction.providerSelect', false);
cesdk.feature.enable('ly.img.plugin-ai-image-generation-web.quickAction', false);
Quick Action Features
The quick action feature flags follow this pattern: ly.img.plugin-ai-{kind}-generation-web.quickAction.{actionName}
Image Quick Actions:
ly.img.plugin-ai-image-generation-web.quickAction.editImage
ly.img.plugin-ai-image-generation-web.quickAction.swapBackground
ly.img.plugin-ai-image-generation-web.quickAction.styleTransfer
ly.img.plugin-ai-image-generation-web.quickAction.artistTransfer
ly.img.plugin-ai-image-generation-web.quickAction.createVariant
ly.img.plugin-ai-image-generation-web.quickAction.combineImages
ly.img.plugin-ai-image-generation-web.quickAction.remixPage
ly.img.plugin-ai-image-generation-web.quickAction.remixPageWithPrompt
Text Quick Actions:
ly.img.plugin-ai-text-generation-web.quickAction.improve
ly.img.plugin-ai-text-generation-web.quickAction.fix
ly.img.plugin-ai-text-generation-web.quickAction.shorter
ly.img.plugin-ai-text-generation-web.quickAction.longer
ly.img.plugin-ai-text-generation-web.quickAction.changeTone
ly.img.plugin-ai-text-generation-web.quickAction.translate
ly.img.plugin-ai-text-generation-web.quickAction.changeTextTo
Video Quick Actions:
ly.img.plugin-ai-video-generation-web.quickAction.createVideo
Note: Quick actions are automatically enabled when their plugin is loaded. Each quick action manages its own feature flag internally, ensuring proper initialization and registration.
Provider-Specific Style Features
Some providers (like RecraftV3 and Recraft20b) support style groups that can be controlled independently:
RecraftV3 Style Groups:
ly.img.plugin-ai-image-generation-web.fal-ai/recraft-v3.style.image
- Enable/disable image styles (realistic, digital illustration)
ly.img.plugin-ai-image-generation-web.fal-ai/recraft-v3.style.vector
- Enable/disable vector styles (vector illustration and variants)
Recraft20b Style Groups:
ly.img.plugin-ai-image-generation-web.fal-ai/recraft/v2/text-to-image.style.image
- Enable/disable image styles
ly.img.plugin-ai-image-generation-web.fal-ai/recraft/v2/text-to-image.style.vector
- Enable/disable vector styles
ly.img.plugin-ai-image-generation-web.fal-ai/recraft/v2/text-to-image.style.icon
- Enable/disable icon styles
When all style groups are disabled for a provider, it automatically falls back to the 'any' style. For more details on style control, see the @imgly/plugin-ai-image-generation-web documentation.
Using with Existing AI Generation Plugins
IMG.LY offers several pre-built AI generation packages that work with this base plugin:
import CreativeEditorSDK from '@cesdk/cesdk-js';
import ImageGeneration from '@imgly/plugin-ai-image-generation-web';
import FalAiImage from '@imgly/plugin-ai-image-generation-web/fal-ai';
import VideoGeneration from '@imgly/plugin-ai-video-generation-web';
import FalAiVideo from '@imgly/plugin-ai-video-generation-web/fal-ai';
CreativeEditorSDK.create(domElement, {
license: 'your-license-key'
}).then(async (cesdk) => {
await cesdk.addDefaultAssetSources();
cesdk.addPlugin(
ImageGeneration({
text2image: FalAiImage.RecraftV3({
proxyUrl: 'http://your-proxy-server.com/api/proxy'
}),
image2image: FalAiImage.GeminiFlashEdit({
proxyUrl: 'http://your-proxy-server.com/api/proxy'
})
})
);
cesdk.addPlugin(
VideoGeneration({
text2video: FalAiVideo.MinimaxVideo01Live({
proxyUrl: 'http://your-proxy-server.com/api/proxy'
})
})
);
cesdk.ui.setCanvasMenuOrder([
'ly.img.plugin-ai-image-generation-web.canvasMenu',
'ly.img.plugin-ai-video-generation-web.canvasMenu',
...cesdk.ui.getCanvasMenuOrder()
]);
});
Advanced Features
Middleware
The package includes a middleware system to augment the generation flow:
Rate Limiting Middleware
import { rateLimitMiddleware } from '@imgly/plugin-ai-generation-web';
const rateLimit = rateLimitMiddleware({
maxRequests: 10,
timeWindowMs: 60000,
onRateLimitExceeded: (input, options, info) => {
console.log(
`Rate limit exceeded: ${info.currentCount}/${info.maxRequests}`
);
return false;
}
});
const provider = {
output: {
middleware: [rateLimit]
}
};
Note: This middleware provides client-side rate limiting for UI purposes only. Always implement proper server-side rate limiting and authentication for production APIs.
Upload Middleware
The uploadMiddleware
allows you to upload generated content to your own servers:
import { uploadMiddleware } from '@imgly/plugin-ai-generation-web';
const upload = uploadMiddleware(async (output) => {
const response = await fetch('https://your-api.example.com/upload', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(output)
});
const result = await response.json();
return {
...output,
url: result.url
};
});
const provider = {
output: {
middleware: [upload]
}
};
Provider Registry
The ProviderRegistry
is a global singleton that manages all registered providers:
import { ProviderRegistry } from '@imgly/plugin-ai-generation-web';
const registry = ProviderRegistry.get();
const allProviders = registry.getAll();
const imageProviders = registry.getByKind('image');
const myProvider = registry.getById('my-provider-id');
TypeScript Support
This package is fully typed with TypeScript, providing excellent IntelliSense support during development:
- Generic Provider Types: Strongly typed providers with input/output validation
- Quick Action Types: Type-safe quick action definitions with proper input mapping
- Registry Types: Fully typed action and provider registries
- Middleware Types: Typed middleware functions for better composition
API Reference
Core Exports
export { Provider, ImageOutput, VideoOutput, AudioOutput, TextOutput } from './core/provider';
export { ActionRegistry, QuickActionDefinition, PluginActionDefinition } from './core/ActionRegistry';
export { ProviderRegistry } from './core/ProviderRegistry';
export { initializeProvider, initializeProviders } from './providers/';
export { loggingMiddleware, rateLimitMiddleware, uploadMiddleware } from './middleware/';
export { getPanelId, enableQuickActionForImageFill, mergeQuickActionsConfig } from './utils/';
Initialization Functions
initializeProviders
The initializeProviders
function is used to initialize multiple providers at once. It creates a composite history asset source and library entry for all providers of the same kind.
const result = await initializeProviders(
providers,
{ engine, cesdk },
config
);
{
panel: {
builderRenderFunction: Function
},
history: {
assetSourceId: string,
assetLibraryEntryId: string
},
providerInitializationResults: Array<{
provider: Provider,
result: ProviderInitializationResult
}>
}
Key Points:
- Creates a composite history asset source with ID format:
ly.img.plugin-ai-{kind}-generation-web.history
- Automatically creates an asset library entry with the same ID as the asset source
- The library entry is configured with appropriate settings (sortBy: insertedAt descending, canRemove: true, etc.)
- Returns both the asset source ID and library entry ID for reference
Common Types
interface CommonProviderConfiguration<I, O extends Output> {
proxyUrl: string;
debug?: boolean;
middleware?: Middleware<I, O>[];
headers?: Record<string, string>;
history?: false | '@imgly/local' | '@imgly/indexedDB' | (string & {});
supportedQuickActions?: {
[quickActionId: string]: Partial<QuickActionSupport<I>> | false | null;
};
}
interface QuickActionDefinition<Q extends Record<string, any>> {
id: string;
type: 'quick';
kind: OutputKind;
label?: string;
enable: boolean | ((context: { engine: CreativeEngine }) => boolean);
render: (context: QuickActionRenderContext<Q>) => void;
}
Translations
For customization and localization, see the translations.json file which contains base translation keys that can be overridden for all AI plugins.