CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-io-quarkiverse-langchain4j--quarkus-langchain4j-azure-openai

Quarkus extension for Azure OpenAI integration with LangChain4j, providing ChatModel, StreamingChatModel, EmbeddingModel, and ImageModel implementations with Azure-specific authentication and configuration support.

Overview
Eval results
Files

image-models.mddocs/

Image Models

Azure OpenAI image models enable generating images from text prompts using DALL-E models. The extension provides AzureOpenAiImageModel which implements the LangChain4j ImageModel interface.

Core API

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();
}

Builder API

Required Configuration

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);
}

Image Generation Parameters

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);
}

Image Persistence

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);
}

Network and Reliability

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);
}

Observability

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);
}

Additional Configuration

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();
}

Usage Examples

Generate a Single Image

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();

Generate Multiple Images

// 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());
}

Persist Images to Disk

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());

High-Quality Image Generation

// 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"
);

CDI Integration with Configuration

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/images

Inject 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();
    }
}

Using Base64 Response Format

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);

Revised Prompts

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);

Named Configurations for Different Styles

# 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=standard

Inject specific models:

import io.quarkiverse.langchain4j.ModelName;

@Inject
@ModelName("artistic")
ImageModel artisticModel;

@Inject
@ModelName("photo")
ImageModel photoModel;

Model Comparison

DALL-E 2

  • Sizes: 256x256, 512x512, 1024x1024
  • Multiple images: Supports generating 1-10 images per request
  • Quality: Standard quality only
  • Style: No style parameter
  • Speed: Faster generation
  • Cost: Lower cost per image

DALL-E 3

  • Sizes: 1024x1024, 1792x1024, 1024x1792
  • Multiple images: Only supports n=1
  • Quality: Standard or HD
  • Style: Vivid or Natural
  • Speed: Slower generation
  • Cost: Higher cost, especially for HD quality
  • Prompt handling: Automatically revises prompts for safety and clarity

Image Persistence Details

When persistDirectory is configured:

  1. Images are automatically downloaded after generation
  2. For URL responses: Downloaded from the URL
  3. For base64 responses: Decoded and saved
  4. Files are saved with unique names in the specified directory
  5. The Image.url() is updated to point to the local file path

This is useful for:

  • Avoiding external dependency on Azure storage
  • Keeping images available after Azure's temporary URLs expire
  • Building local image galleries
  • Processing images with local tools

Important Notes

  1. DALL-E 3 Limitation: When using dall-e-3, only one image can be generated per request (n must equal 1)
  2. Size Constraints: Sizes must match the model:
    • dall-e-2: 256x256, 512x512, or 1024x1024
    • dall-e-3: 1024x1024, 1792x1024, or 1024x1792
  3. Quality Parameter: Only available for dall-e-3, ignored for dall-e-2
  4. Style Parameter: Only available for dall-e-3, ignored for dall-e-2
  5. URL Expiration: Azure OpenAI image URLs are temporary and expire after a period (exact time varies)
  6. Prompt Revisions: DALL-E 3 may revise prompts for safety, style, or clarity
  7. Authentication: Exactly one of apiKey or adToken must be provided
  8. Native Compilation: Supports Quarkus native compilation
  9. Response Format: URLs are simpler but temporary; base64 is more reliable but larger

Configuration Properties

When 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

Related Types

// 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

docs

chat-models.md

configuration.md

embedding-models.md

image-models.md

index.md

tile.json