Quarkus extension for Azure OpenAI integration with LangChain4j, providing ChatModel, StreamingChatModel, EmbeddingModel, and ImageModel implementations with Azure-specific authentication and configuration support.
Azure OpenAI image models enable generating images from text prompts using DALL-E models. The extension provides AzureOpenAiImageModel which implements the LangChain4j ImageModel interface.
package io.quarkiverse.langchain4j.azure.openai;
public class AzureOpenAiImageModel implements dev.langchain4j.model.image.ImageModel {
/**
* Generate a single image from a text prompt.
*
* @param prompt Text description of the desired image
* @return Response containing the generated image
*/
public dev.langchain4j.model.output.Response<dev.langchain4j.data.image.Image> generate(String prompt);
/**
* Generate multiple images from a text prompt.
*
* @param prompt Text description of the desired images
* @param n Number of images to generate (1-10, but dall-e-3 only supports n=1)
* @return Response containing the list of generated images
*/
public dev.langchain4j.model.output.Response<java.util.List<dev.langchain4j.data.image.Image>>
generate(String prompt, int n);
/**
* Create a builder for configuring the image model.
*
* @return Builder instance
*/
public static Builder builder();
}public static class Builder {
/**
* Set the Azure OpenAI endpoint URL.
* Format: https://{resource-name}.openai.azure.com/openai/deployments/{deployment-name}
*
* @param endpoint The full endpoint URL (required)
* @return This builder
*/
public Builder endpoint(String endpoint);
/**
* Set the Azure OpenAI API version.
* Format: YYYY-MM-DD (e.g., "2024-10-21")
*
* @param apiVersion The API version (required)
* @return This builder
*/
public Builder apiVersion(String apiVersion);
/**
* Set the Azure OpenAI API key for authentication.
* Either apiKey or adToken must be provided, but not both.
*
* @param apiKey The API key
* @return This builder
*/
public Builder apiKey(String apiKey);
/**
* Set the Azure AD token for authentication.
* Either apiKey or adToken must be provided, but not both.
*
* @param adToken The Azure AD token
* @return This builder
*/
public Builder adToken(String adToken);
}public static class Builder {
/**
* Set the model name.
* Default: "dall-e-3"
*
* @param modelName Model name (e.g., "dall-e-2", "dall-e-3")
* @return This builder
*/
public Builder modelName(String modelName);
/**
* Set the size of generated images.
* For dall-e-3: "1024x1024", "1792x1024", or "1024x1792"
* For dall-e-2: "256x256", "512x512", or "1024x1024"
* Default: "1024x1024"
*
* @param size Image size specification
* @return This builder
*/
public Builder size(String size);
/**
* Set the quality of generated images.
* "hd" creates images with finer details and greater consistency.
* "standard" is faster and less expensive.
* Only supported for dall-e-3.
* Default: "standard"
*
* @param quality Image quality ("standard" or "hd")
* @return This builder
*/
public Builder quality(String quality);
/**
* Set the style of generated images.
* "vivid" generates hyper-real and dramatic images.
* "natural" generates more natural, less hyper-real images.
* Only supported for dall-e-3.
* Default: "vivid"
*
* @param style Image style ("vivid" or "natural")
* @return This builder
*/
public Builder style(String style);
/**
* Set the response format.
* "url" returns a URL to the generated image.
* "b64_json" returns the image as base64-encoded JSON.
* Default: "url"
*
* @param responseFormat Response format ("url" or "b64_json")
* @return This builder
*/
public Builder responseFormat(String responseFormat);
/**
* Set a unique identifier for the end user.
* Can help OpenAI monitor and detect abuse.
*
* @param user User identifier (wrapped in Optional)
* @return This builder
*/
public Builder user(java.util.Optional<String> user);
}public static class Builder {
/**
* Set directory for persisting generated images to disk.
* When set, images are automatically downloaded and saved.
* If not set, images are not persisted.
*
* @param persistDirectory Directory path (wrapped in Optional)
* @return This builder
*/
public Builder persistDirectory(java.util.Optional<java.nio.file.Path> persistDirectory);
}public static class Builder {
/**
* Set timeout for API calls.
* Default: 60 seconds
*
* @param timeout The timeout duration
* @return This builder
*/
public Builder timeout(java.time.Duration timeout);
/**
* Set maximum number of retry attempts.
* Default: 1 (no retries)
*
* @param maxRetries Maximum retry attempts (must be >= 1)
* @return This builder
*/
public Builder maxRetries(Integer maxRetries);
}public static class Builder {
/**
* Enable request logging.
* Default: false
*
* @param logRequests Whether to log requests
* @return This builder
*/
public Builder logRequests(Boolean logRequests);
/**
* Enable response logging.
* Default: false
*
* @param logResponses Whether to log responses
* @return This builder
*/
public Builder logResponses(Boolean logResponses);
/**
* Enable cURL-format request logging.
* Default: false
*
* @param logCurl Whether to log requests as cURL commands
* @return This builder
*/
public Builder logCurl(Boolean logCurl);
}public static class Builder {
/**
* Set configuration name for named model instances.
* Used for CDI integration with @ModelName qualifier.
*
* @param configName The configuration name
* @return This builder
*/
public Builder configName(String configName);
/**
* Build the image model instance.
*
* @return Configured AzureOpenAiImageModel instance
*/
public AzureOpenAiImageModel build();
}import io.quarkiverse.langchain4j.azure.openai.AzureOpenAiImageModel;
import dev.langchain4j.data.image.Image;
import dev.langchain4j.model.output.Response;
// Build the image model
AzureOpenAiImageModel imageModel = AzureOpenAiImageModel.builder()
.endpoint("https://my-resource.openai.azure.com/openai/deployments/dall-e-3")
.apiKey("your-api-key")
.apiVersion("2024-10-21")
.modelName("dall-e-3")
.size("1024x1024")
.quality("standard")
.style("vivid")
.build();
// Generate an image
Response<Image> response = imageModel.generate("A futuristic city with flying cars at sunset");
Image image = response.content();
// Access the image
String imageUrl = image.url().toString();
System.out.println("Image URL: " + imageUrl);
// Or get base64 data if responseFormat was "b64_json"
String base64Data = image.base64Data();// Configure for multiple images (only works with dall-e-2)
AzureOpenAiImageModel imageModel = AzureOpenAiImageModel.builder()
.endpoint("https://my-resource.openai.azure.com/openai/deployments/dall-e-2")
.apiKey("your-api-key")
.apiVersion("2024-10-21")
.modelName("dall-e-2")
.size("512x512")
.build();
// Generate 4 images
Response<List<Image>> response = imageModel.generate("Abstract digital art", 4);
List<Image> images = response.content();
// Process all images
for (int i = 0; i < images.size(); i++) {
System.out.println("Image " + (i + 1) + ": " + images.get(i).url());
}import java.nio.file.Paths;
import java.util.Optional;
// Build model with persistence enabled
AzureOpenAiImageModel imageModel = AzureOpenAiImageModel.builder()
.endpoint("https://my-resource.openai.azure.com/openai/deployments/dall-e-3")
.apiKey("your-api-key")
.apiVersion("2024-10-21")
.persistDirectory(Optional.of(Paths.get("/path/to/images")))
.build();
// Generate and automatically save image
Response<Image> response = imageModel.generate("A serene mountain landscape");
// The image is now saved to disk and the URL points to the local file
Image image = response.content();
System.out.println("Image saved to: " + image.url());// Use DALL-E 3 with high-quality settings
AzureOpenAiImageModel imageModel = AzureOpenAiImageModel.builder()
.endpoint("https://my-resource.openai.azure.com/openai/deployments/dall-e-3")
.apiKey("your-api-key")
.apiVersion("2024-10-21")
.modelName("dall-e-3")
.size("1792x1024") // Wide format
.quality("hd") // High definition
.style("natural") // Natural style
.build();
Response<Image> response = imageModel.generate(
"A professional photograph of a modern office space with natural lighting"
);Configure via application.properties:
quarkus.langchain4j.azure-openai.api-key=your-key
quarkus.langchain4j.azure-openai.image-model.deployment-name=dall-e-3
quarkus.langchain4j.azure-openai.resource-name=my-resource
quarkus.langchain4j.azure-openai.image-model.size=1024x1024
quarkus.langchain4j.azure-openai.image-model.quality=hd
quarkus.langchain4j.azure-openai.image-model.persist=true
quarkus.langchain4j.azure-openai.image-model.persist-directory=/var/imagesInject and use:
import dev.langchain4j.model.image.ImageModel;
import jakarta.inject.Inject;
public class ImageGenerationService {
@Inject
ImageModel imageModel;
public String generateImage(String prompt) {
Response<Image> response = imageModel.generate(prompt);
return response.content().url().toString();
}
}AzureOpenAiImageModel imageModel = AzureOpenAiImageModel.builder()
.endpoint("https://my-resource.openai.azure.com/openai/deployments/dall-e-3")
.apiKey("your-api-key")
.apiVersion("2024-10-21")
.responseFormat("b64_json") // Get base64 instead of URL
.build();
Response<Image> response = imageModel.generate("Digital artwork of a sunset");
Image image = response.content();
// Get base64 data directly
String base64Data = image.base64Data();
// Decode and save or process the image
byte[] imageBytes = java.util.Base64.getDecoder().decode(base64Data);
java.nio.file.Files.write(Paths.get("output.png"), imageBytes);DALL-E 3 may revise your prompt for safety or clarity. Access the revised prompt:
Response<Image> response = imageModel.generate("A cat wearing a hat");
Image image = response.content();
// Get the revised prompt that was actually used
String revisedPrompt = image.revisedPrompt();
System.out.println("Original: A cat wearing a hat");
System.out.println("Revised: " + revisedPrompt);# Creative, artistic images
quarkus.langchain4j.azure-openai.artistic.api-key=key1
quarkus.langchain4j.azure-openai.artistic.image-model.deployment-name=dall-e-3
quarkus.langchain4j.azure-openai.artistic.resource-name=resource1
quarkus.langchain4j.azure-openai.artistic.image-model.style=vivid
quarkus.langchain4j.azure-openai.artistic.image-model.quality=hd
# Natural, photographic images
quarkus.langchain4j.azure-openai.photo.api-key=key2
quarkus.langchain4j.azure-openai.photo.image-model.deployment-name=dall-e-3
quarkus.langchain4j.azure-openai.photo.resource-name=resource2
quarkus.langchain4j.azure-openai.photo.image-model.style=natural
quarkus.langchain4j.azure-openai.photo.image-model.quality=standardInject specific models:
import io.quarkiverse.langchain4j.ModelName;
@Inject
@ModelName("artistic")
ImageModel artisticModel;
@Inject
@ModelName("photo")
ImageModel photoModel;When persistDirectory is configured:
Image.url() is updated to point to the local file pathThis is useful for:
apiKey or adToken must be providedWhen using declarative configuration, image model specific properties are prefixed with quarkus.langchain4j.azure-openai.image-model.:
# Model configuration
quarkus.langchain4j.azure-openai.image-model.model-name=dall-e-3
quarkus.langchain4j.azure-openai.image-model.size=1024x1024
quarkus.langchain4j.azure-openai.image-model.quality=standard
quarkus.langchain4j.azure-openai.image-model.style=vivid
quarkus.langchain4j.azure-openai.image-model.response-format=url
quarkus.langchain4j.azure-openai.image-model.number=1
# Persistence configuration
quarkus.langchain4j.azure-openai.image-model.persist=true
quarkus.langchain4j.azure-openai.image-model.persist-directory=/var/images
# User identifier (optional)
quarkus.langchain4j.azure-openai.image-model.user=user-123
# Logging
quarkus.langchain4j.azure-openai.image-model.log-requests=true
quarkus.langchain4j.azure-openai.image-model.log-responses=true// From LangChain4j framework
package dev.langchain4j.data.image;
public class Image {
public java.net.URI url();
public String base64Data();
public String revisedPrompt();
public static Builder builder();
}
package dev.langchain4j.model.output;
public class Response<T> {
public T content();
}Install with Tessl CLI
npx tessl i tessl/maven-io-quarkiverse-langchain4j--quarkus-langchain4j-azure-openai@1.7.0