Core runtime module for Quarkus LangChain4j integration with declarative AI services, guardrails, and observability
Media content annotations enable AI services to process multimodal inputs including images, audio, video, and PDF documents. These annotations mark method parameters as URLs to media resources that AI models can analyze.
import io.quarkiverse.langchain4j.ImageUrl;
import io.quarkiverse.langchain4j.AudioUrl;
import io.quarkiverse.langchain4j.VideoUrl;
import io.quarkiverse.langchain4j.PdfUrl;
import dev.langchain4j.service.UserMessage;
import java.net.URL;
import java.net.URI;package io.quarkiverse.langchain4j;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface ImageUrl {
}Marks an AI service method parameter as an image URL for vision models.
Supported Types:
Stringjava.net.URLjava.net.URIdev.langchain4j.data.image.ImageLimitation: At most one @ImageUrl parameter per method.
package io.quarkiverse.langchain4j;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface AudioUrl {
}Marks an AI service method parameter as an audio URL for audio-capable models.
Supported Types:
Stringjava.net.URLjava.net.URIdev.langchain4j.data.audio.AudioLimitation: At most one @AudioUrl parameter per method.
package io.quarkiverse.langchain4j;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface VideoUrl {
}Marks an AI service method parameter as a video URL for video-capable models.
Supported Types:
Stringjava.net.URLjava.net.URIdev.langchain4j.data.video.VideoLimitation: At most one @VideoUrl parameter per method.
package io.quarkiverse.langchain4j;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface PdfUrl {
}Marks an AI service method parameter as a PDF URL for document analysis.
Supported Types:
Stringjava.net.URLjava.net.URIdev.langchain4j.data.pdf.PdfFileLimitation: At most one @PdfUrl parameter per method.
import io.quarkiverse.langchain4j.RegisterAiService;
import io.quarkiverse.langchain4j.ImageUrl;
import dev.langchain4j.service.UserMessage;
@RegisterAiService
public interface VisionService {
@UserMessage("Describe what you see in this image")
String describeImage(@ImageUrl String imageUrl);
@UserMessage("What objects are visible in this image?")
List<String> listObjects(@ImageUrl String imageUrl);
}
// Usage
@Inject
VisionService vision;
public void analyzeImage() {
String description = vision.describeImage("https://example.com/photo.jpg");
System.out.println(description);
}import java.net.URL;
import java.net.URI;
@RegisterAiService
public interface MultiTypeVisionService {
// Using String
String describe(@ImageUrl String url);
// Using URL
String describe(@ImageUrl URL url);
// Using URI
String describe(@ImageUrl URI uri);
// Using LangChain4j Image type
String describe(@ImageUrl dev.langchain4j.data.image.Image image);
}@RegisterAiService
public interface ImageQA {
@UserMessage("Look at this image and answer: {question}")
String answerQuestion(@ImageUrl String imageUrl, @V("question") String question);
}
// Usage
String answer = imageQA.answerQuestion(
"https://example.com/chart.png",
"What is the trend in the data?"
);@RegisterAiService
public interface AudioService {
@UserMessage("Transcribe this audio")
String transcribe(@AudioUrl String audioUrl);
@UserMessage("Summarize the content of this audio")
String summarize(@AudioUrl String audioUrl);
}
// Usage
@Inject
AudioService audio;
public void processAudio() {
String transcript = audio.transcribe("https://example.com/meeting.mp3");
String summary = audio.summarize("https://example.com/meeting.mp3");
}@RegisterAiService
public interface VideoService {
@UserMessage("Describe what happens in this video")
String describeVideo(@VideoUrl String videoUrl);
@UserMessage("Identify the key moments in this video")
List<String> keyMoments(@VideoUrl String videoUrl);
}
// Usage
@Inject
VideoService video;
public void analyzeVideo() {
String description = video.describeVideo("https://example.com/tutorial.mp4");
List<String> moments = video.keyMoments("https://example.com/tutorial.mp4");
}@RegisterAiService
public interface DocumentService {
@UserMessage("Summarize this PDF document")
String summarize(@PdfUrl String pdfUrl);
@UserMessage("Extract key findings from this research paper")
List<String> extractFindings(@PdfUrl String pdfUrl);
@UserMessage("What is discussed about {topic} in this document?")
String searchTopic(@PdfUrl String pdfUrl, @V("topic") String topic);
}
// Usage
@Inject
DocumentService docs;
public void processDocument() {
String summary = docs.summarize("https://example.com/report.pdf");
String findings = docs.searchTopic("https://example.com/research.pdf", "climate");
}@RegisterAiService
public interface ImageComparison {
@UserMessage("Compare the image at {url1} with the image at {url2}")
String compare(@V("url1") @ImageUrl String image1,
@V("url2") String image2Ref);
}
// Note: Only one @ImageUrl annotation allowed per method
// For multiple images, pass URLs as regular parameters in the message template@RegisterAiService
public interface AdvancedVision {
@UserMessage("""
Analyze this image and provide:
1. A detailed description
2. Identified objects and their locations
3. Any text visible in the image
4. The dominant colors
5. The likely context or setting
""")
ImageAnalysis analyzeComprehensive(@ImageUrl String imageUrl);
}
public record ImageAnalysis(
String description,
List<DetectedObject> objects,
String extractedText,
List<String> dominantColors,
String context
) {}
public record DetectedObject(
String name,
String location
) {}@RegisterAiService
public interface MedicalImaging {
@UserMessage("""
Analyze this medical image for:
- Visible structures
- Any anomalies
- Image quality assessment
Note: This is for educational purposes only.
""")
String analyzeXRay(@ImageUrl String xrayUrl);
}@RegisterAiService
public interface OCRService {
@UserMessage("Extract all text from this image")
String extractText(@ImageUrl String imageUrl);
@UserMessage("Extract the invoice number and total amount from this receipt")
InvoiceData extractInvoiceData(@ImageUrl String receiptUrl);
}
public record InvoiceData(
String invoiceNumber,
BigDecimal totalAmount
) {}@RegisterAiService
public interface AudioAnalysis {
@UserMessage("""
Listen to this audio and provide:
- Speaker count
- Main topics discussed
- Sentiment analysis
- Key takeaways
""")
AudioReport analyze(@AudioUrl String audioUrl);
}
public record AudioReport(
int speakerCount,
List<String> topics,
String sentiment,
List<String> keyTakeaways
) {}@RegisterAiService
public interface VideoModeration {
@UserMessage("Check if this video contains inappropriate content")
ModerationResult moderate(@VideoUrl String videoUrl);
}
public record ModerationResult(
boolean isAppropriate,
List<String> flags,
String reasoning
) {}@RegisterAiService
public interface PDFProcessor {
@UserMessage("Extract the table of contents from this PDF")
List<TocEntry> extractTOC(@PdfUrl String pdfUrl);
@UserMessage("Find all references to {term} in this document")
List<Reference> findReferences(@PdfUrl String pdfUrl, @V("term") String term);
}
public record TocEntry(
String title,
int pageNumber
) {}
public record Reference(
String context,
int pageNumber
) {}@RegisterAiService
public interface ImageClassifier {
@SystemMessage("You are an image classifier. Respond with only the category name.")
@UserMessage("Classify this image into one of: landscape, portrait, abstract, architecture, nature")
String classify(@ImageUrl String imageUrl);
}
// Usage
String category = classifier.classify("https://example.com/photo.jpg");@RegisterAiService
public interface ScreenshotAnalyzer {
@UserMessage("This is a screenshot of a UI. Describe what you see and suggest improvements.")
UIAnalysis analyzeUI(@ImageUrl String screenshotUrl);
}
public record UIAnalysis(
String description,
List<String> elements,
List<String> suggestions
) {}@RegisterAiService
public interface ChartReader {
@UserMessage("Extract the data points from this chart image")
ChartData extractData(@ImageUrl String chartUrl);
@UserMessage("What trend does this graph show?")
String analyzeTrend(@ImageUrl String chartUrl);
}
public record ChartData(
String chartType,
List<DataPoint> dataPoints
) {}
public record DataPoint(
String label,
double value
) {}Different AI models support different media types:
Always verify that your chosen model supports the media type before use.
Typical format support (verify with your specific model):
Install with Tessl CLI
npx tessl i tessl/maven-io-quarkiverse-langchain4j--quarkus-langchain4j-core