LangChain4j integration for Mistral AI providing chat completion, streaming, embedding, moderation, and code completion capabilities
A comprehensive Java integration library for Mistral AI's language models within the LangChain4j framework. Enables seamless incorporation of Mistral AI's chat completion, streaming, embedding, moderation, and fill-in-the-middle code completion capabilities into Java applications.
pom.xml:<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-mistral-ai</artifactId>
<version>1.11.0</version>
</dependency>For Gradle:
implementation 'dev.langchain4j:langchain4j-mistral-ai:1.11.0'// Main model classes
import dev.langchain4j.model.mistralai.MistralAiChatModel;
import dev.langchain4j.model.mistralai.MistralAiStreamingChatModel;
import dev.langchain4j.model.mistralai.MistralAiEmbeddingModel;
import dev.langchain4j.model.mistralai.MistralAiModerationModel;
import dev.langchain4j.model.mistralai.MistralAiFimModel;
import dev.langchain4j.model.mistralai.MistralAiStreamingFimModel;
import dev.langchain4j.model.mistralai.MistralAiModels;
import dev.langchain4j.model.mistralai.MistralAiModelCatalog;Model name enums:
import dev.langchain4j.model.mistralai.MistralAiChatModelName;
import dev.langchain4j.model.mistralai.MistralAiEmbeddingModelName;
import dev.langchain4j.model.mistralai.MistralAiFimModelName;import dev.langchain4j.model.mistralai.MistralAiChatModel;
import dev.langchain4j.model.mistralai.MistralAiChatModelName;
import dev.langchain4j.data.message.AiMessage;
import dev.langchain4j.data.message.UserMessage;
import dev.langchain4j.model.chat.ChatResponse;
import java.util.List;
// Create chat model
MistralAiChatModel chatModel = MistralAiChatModel.builder()
.apiKey(System.getenv("MISTRAL_API_KEY")) // Never hardcode API keys
.modelName(MistralAiChatModelName.MISTRAL_LARGE_LATEST)
.temperature(0.7)
.build();
// Generate response
ChatResponse response = chatModel.chat(
List.of(UserMessage.from("What is the capital of France?"))
);
System.out.println(response.aiMessage().text());
// Output: "The capital of France is Paris."import dev.langchain4j.model.mistralai.MistralAiStreamingChatModel;
import dev.langchain4j.model.chat.StreamingChatResponseHandler;
import dev.langchain4j.model.chat.ChatRequest;
MistralAiStreamingChatModel streamingModel = MistralAiStreamingChatModel.builder()
.apiKey(System.getenv("MISTRAL_API_KEY"))
.modelName(MistralAiChatModelName.MISTRAL_LARGE_LATEST)
.build();
ChatRequest request = ChatRequest.builder()
.messages(UserMessage.from("Tell me a story"))
.build();
streamingModel.chat(request, new StreamingChatResponseHandler() {
@Override
public void onPartialResponse(String token) {
System.out.print(token); // Display tokens as they arrive
}
@Override
public void onCompleteResponse(ChatResponse response) {
System.out.println("\nDone!");
System.out.println("Tokens used: " + response.tokenUsage().totalTokenCount());
}
@Override
public void onError(Throwable error) {
System.err.println("Error: " + error.getMessage());
error.printStackTrace();
}
});import dev.langchain4j.model.mistralai.MistralAiEmbeddingModel;
import dev.langchain4j.model.mistralai.MistralAiEmbeddingModelName;
import dev.langchain4j.data.embedding.Embedding;
import dev.langchain4j.data.segment.TextSegment;
import dev.langchain4j.model.output.Response;
MistralAiEmbeddingModel embeddingModel = MistralAiEmbeddingModel.builder()
.apiKey(System.getenv("MISTRAL_API_KEY"))
.modelName(MistralAiEmbeddingModelName.MISTRAL_EMBED)
.build();
Response<Embedding> response = embeddingModel.embed("Hello, world!");
Embedding embedding = response.content();
float[] vector = embedding.vector(); // 1024-dimensional vector
System.out.println("Embedding dimension: " + vector.length);import dev.langchain4j.model.mistralai.MistralAiFimModel;
import dev.langchain4j.model.mistralai.MistralAiFimModelName;
MistralAiFimModel fimModel = MistralAiFimModel.builder()
.apiKey(System.getenv("MISTRAL_API_KEY"))
.modelName(MistralAiFimModelName.CODESTRAL_LATEST)
.build();
// Fill-in-the-middle code completion
String prefix = "def fibonacci(n):\n if n <= 1:\n return n\n ";
String suffix = "\n return fib(n-1) + fib(n-2)";
Response<String> completion = fimModel.generate(prefix, suffix);
System.out.println("Generated code: " + completion.content());The library provides a clean abstraction layer between LangChain4j's unified interfaces and Mistral AI's proprietary REST API, following these key design patterns:
The library integrates with:
Synchronous and streaming chat completions with multi-turn conversations, tool/function calling, multimodal inputs (text and images), thinking/reasoning output, and extensive configuration options.
public class MistralAiChatModel implements ChatModel {
/**
* Create a builder for configuring the chat model.
* @return Builder instance for fluent configuration
*/
public static MistralAiChatModelBuilder builder() { ... }
/**
* Generate chat response from a chat request.
* @param chatRequest Request containing messages and parameters (non-null)
* @return ChatResponse with AI message and metadata (never null)
* @throws RuntimeException if API call fails after retries
*/
public ChatResponse chat(ChatRequest chatRequest) { ... }
/**
* Convenience method for simple text interactions.
* @param userMessage User message string (non-null, non-empty)
* @return String response from AI (never null)
* @throws RuntimeException if API call fails after retries
*/
public String chat(String userMessage) { ... }
/**
* Generate response from variable number of messages.
* @param messages Variable arguments of ChatMessage (non-null array)
* @return ChatResponse with AI message and metadata (never null)
* @throws RuntimeException if API call fails after retries
*/
public ChatResponse chat(ChatMessage... messages) { ... }
/**
* Generate response from list of messages.
* @param messages List of ChatMessage objects (non-null, can be empty)
* @return ChatResponse with AI message and metadata (never null)
* @throws RuntimeException if API call fails after retries
*/
public ChatResponse chat(List<ChatMessage> messages) { ... }
}public class MistralAiStreamingChatModel implements StreamingChatModel {
/**
* Create a builder for configuring the streaming chat model.
* @return Builder instance for fluent configuration
*/
public static MistralAiStreamingChatModelBuilder builder() { ... }
/**
* Generate streaming chat response from a chat request.
* @param chatRequest Request containing messages and parameters (non-null)
* @param handler Handler for receiving streaming tokens (non-null)
* @throws RuntimeException if API call fails (no retries for streaming)
*/
public void chat(ChatRequest chatRequest, StreamingChatResponseHandler handler) { ... }
}See: Chat Models for comprehensive documentation
Convert text segments into vector embeddings for semantic search, clustering, and similarity comparison. Supports batch processing of multiple text segments with dimension awareness.
public class MistralAiEmbeddingModel extends DimensionAwareEmbeddingModel {
/**
* Create a builder for configuring the embedding model.
* @return Builder instance for fluent configuration
*/
public static MistralAiEmbeddingModelBuilder builder() { ... }
/**
* Embed a single text string.
* @param text Text to embed (non-null, max 8192 tokens)
* @return Response containing Embedding with 1024-dim vector (never null)
* @throws RuntimeException if API call fails after retries or text exceeds token limit
*/
public Response<Embedding> embed(String text) { ... }
/**
* Embed a single text segment.
* @param textSegment TextSegment to embed (non-null)
* @return Response containing Embedding (never null)
* @throws RuntimeException if API call fails after retries
*/
public Response<Embedding> embed(TextSegment textSegment) { ... }
/**
* Batch embed multiple text segments in single API call.
* @param textSegments List of TextSegment objects (non-null, can be empty)
* @return Response containing List of Embeddings, preserving input order (never null)
* @throws RuntimeException if API call fails after retries
*/
public Response<List<Embedding>> embedAll(List<TextSegment> textSegments) { ... }
/**
* Get the dimensionality of embedding vectors.
* @return Fixed dimension count: 1024 for mistral-embed
*/
public int dimension() { ... }
}See: Embedding Model for comprehensive documentation
Fill-in-the-middle code completion for IDE integrations and code generation tasks. Supports prefix-suffix context with synchronous and streaming modes using Mistral's Codestral models.
public class MistralAiFimModel implements LanguageModel {
/**
* Create a builder for configuring the FIM model.
* @return Builder instance for fluent configuration
*/
public static Builder builder() { ... }
/**
* Generate code completion from prompt only.
* @param prompt Code prefix/context before cursor (non-null)
* @return Response containing generated code string (never null)
* @throws RuntimeException if API call fails after retries
*/
public Response<String> generate(String prompt) { ... }
/**
* Generate fill-in-the-middle code completion.
* @param prompt Code prefix before cursor (non-null)
* @param suffix Code suffix after cursor (can be null for append-only)
* @return Response containing code to insert at cursor (never null)
* @throws RuntimeException if API call fails after retries
*/
public Response<String> generate(String prompt, String suffix) { ... }
}public class MistralAiStreamingFimModel implements StreamingLanguageModel {
/**
* Create a builder for configuring the streaming FIM model.
* @return Builder instance for fluent configuration
*/
public static Builder builder() { ... }
/**
* Generate streaming code completion from prompt.
* @param prompt Code prefix/context (non-null)
* @param handler Handler for receiving tokens (non-null)
* @throws RuntimeException if API call fails (no retries for streaming)
*/
public void generate(String prompt, StreamingResponseHandler<String> handler) { ... }
/**
* Generate streaming fill-in-the-middle completion.
* @param prompt Code prefix before cursor (non-null)
* @param suffix Code suffix after cursor (can be null)
* @param handler Handler for receiving tokens (non-null)
* @throws RuntimeException if API call fails (no retries for streaming)
*/
public void generate(String prompt, String suffix, StreamingResponseHandler<String> handler) { ... }
}See: Code Completion for comprehensive documentation
Analyze text and chat messages for harmful content across multiple categories: sexual content, hate speech, harassment, violence, self-harm, dangerous content, PII, health, and legal content. Returns boolean flags and confidence scores per category.
public class MistralAiModerationModel implements ModerationModel {
/**
* Create a builder for configuring the moderation model.
* Note: Use new Builder() syntax, not static builder() method.
* @param builder Configured Builder instance (non-null)
*/
public MistralAiModerationModel(Builder builder) { ... }
/**
* Moderate a single text string.
* @param text Text to analyze (non-null, non-empty)
* @return Response containing Moderation result with flagged status (never null)
* @throws RuntimeException if API call fails after retries
*/
public Response<Moderation> moderate(String text) { ... }
/**
* Moderate a conversation (list of messages).
* @param messages List of ChatMessage to analyze (non-null, can be empty)
* @return Response containing Moderation result (never null)
* @throws RuntimeException if API call fails after retries
*/
public Response<Moderation> moderate(List<ChatMessage> messages) { ... }
}See: Moderation Model for comprehensive documentation
Query available Mistral AI models and their capabilities. Useful for dynamic model selection and capability discovery.
public class MistralAiModels {
/**
* Create a builder for configuring model discovery client.
* @return Builder instance for fluent configuration
*/
public static MistralAiModelsBuilder builder() { ... }
/**
* Quick initialization with API key only.
* @param apiKey Mistral AI API key (non-null, non-empty)
* @return MistralAiModels instance with default settings
*/
public static MistralAiModels withApiKey(String apiKey) { ... }
/**
* Retrieve list of available models from API.
* @return Response containing List of MistralAiModelCard (never null, can be empty list)
* @throws RuntimeException if API call fails after retries
*/
public Response<List<MistralAiModelCard>> availableModels() { ... }
}public class MistralAiModelCatalog implements ModelCatalog {
/**
* Create a builder for configuring model catalog.
* @return Builder instance for fluent configuration
*/
public static Builder builder() { ... }
/**
* List all models with standardized descriptions.
* @return List of ModelDescription objects (never null, can be empty)
* @throws RuntimeException if API call fails
*/
public List<ModelDescription> listModels() { ... }
/**
* Get the model provider identifier.
* @return ModelProvider.MISTRAL_AI constant
*/
public ModelProvider provider() { ... }
}See: Model Discovery for comprehensive documentation
All models share common builder configuration options for authentication, timeouts, logging, retries, and HTTP client customization. Chat models have additional options for listeners and default parameters.
See: Configuration Options for comprehensive documentation
Model name enumerations, response metadata classes, and API enumerations for roles, tool types, tool choice strategies, and response format types.
See: Types and Enums for comprehensive reference
SPI interfaces for dependency injection frameworks and custom instantiation patterns. Enables Spring, Quarkus, and other DI frameworks to provide customized builder instances for all Mistral AI models.
See: Service Provider Interface for integration patterns
The library uses LangChain4j's ChatResponse which includes:
try {
ChatResponse response = chatModel.chat(messages);
// Check finish reason
switch (response.metadata().finishReason()) {
case STOP:
// Normal completion - use the response
AiMessage message = response.aiMessage();
processResponse(message.text());
break;
case LENGTH:
// Hit token limit - response may be incomplete
logger.warn("Response truncated due to max tokens limit");
handleIncompleteResponse(response.aiMessage().text());
break;
case TOOL_CALLS:
// Model wants to execute tools
for (ToolExecutionRequest request : response.aiMessage().toolExecutionRequests()) {
executeToolAndContinue(request);
}
break;
case CONTENT_FILTER:
// Content was filtered by safety systems
logger.warn("Content filtered by moderation");
handleFilteredContent();
break;
}
} catch (RuntimeException e) {
// Handle API failures (network, auth, rate limit, etc.)
logger.error("API call failed: {}", e.getMessage());
if (e.getMessage().contains("rate limit")) {
handleRateLimitError();
} else if (e.getMessage().contains("authentication")) {
handleAuthError();
} else {
handleGeneralError(e);
}
}Define tools using LangChain4j's ToolSpecification. Note that JsonSchemaProperty is not available in this library. For tool parameter specification, refer to LangChain4j core documentation on ToolSpecification builder methods:
import dev.langchain4j.agent.tool.ToolSpecification;
import dev.langchain4j.model.chat.request.ChatRequestParameters;
import dev.langchain4j.model.chat.request.ChatRequest;
// Create tool specification using ToolSpecification.builder()
// Refer to LangChain4j core documentation for parameters() method syntax
ToolSpecification weatherTool = ToolSpecification.builder()
.name("get_weather")
.description("Get current weather for a location")
// Use parameters() method from LangChain4j core to specify tool parameters
.build();
// Tools must be passed in ChatRequest parameters, not directly to chat()
ChatRequestParameters params = ChatRequestParameters.builder()
.toolSpecifications(weatherTool)
.build();
ChatRequest request = ChatRequest.builder()
.messages(messages)
.parameters(params)
.build();
ChatResponse response = chatModel.chat(request);
// Handle tool execution requests
if (response.aiMessage().hasToolExecutionRequests()) {
for (ToolExecutionRequest toolRequest : response.aiMessage().toolExecutionRequests()) {
String toolName = toolRequest.name(); // e.g., "get_weather"
String arguments = toolRequest.arguments(); // JSON string with arguments
// Execute tool and add result to conversation
String toolResult = executeToolFunction(toolName, arguments);
// Continue conversation with tool result...
}
}Configure automatic retries with exponential backoff (applies to synchronous models only, not streaming):
MistralAiChatModel chatModel = MistralAiChatModel.builder()
.apiKey(apiKey)
.maxRetries(3) // Retry up to 3 times on transient failures
.timeout(Duration.ofSeconds(60)) // Timeout per request attempt
.build();
// Note: MistralAiStreamingChatModel does NOT support maxRetries()Use a custom HTTP client implementation for proxy, custom headers, or SSL configuration:
import dev.langchain4j.http.client.HttpClientBuilder;
HttpClientBuilder customClientBuilder = // ... your custom implementation
MistralAiChatModel chatModel = MistralAiChatModel.builder()
.apiKey(apiKey)
.httpClientBuilder(customClientBuilder)
.build();Monitor chat model interactions for logging, metrics, and debugging:
import dev.langchain4j.model.chat.listener.ChatModelListener;
import dev.langchain4j.model.chat.listener.ChatModelRequestContext;
import dev.langchain4j.model.chat.listener.ChatModelResponseContext;
import dev.langchain4j.model.chat.listener.ChatModelErrorContext;
ChatModelListener listener = new ChatModelListener() {
@Override
public void onRequest(ChatModelRequestContext context) {
// Log/monitor request - access messages, parameters, model name
logger.info("Chat request to {}: {} messages",
context.model(), context.messages().size());
}
@Override
public void onResponse(ChatModelResponseContext context) {
// Log/monitor response - access tokens used, finish reason
logger.info("Chat response: {} tokens, finish: {}",
context.response().tokenUsage().totalTokenCount(),
context.response().finishReason());
}
@Override
public void onError(ChatModelErrorContext context) {
// Handle/log errors
logger.error("Chat error: {}", context.error().getMessage());
}
};
MistralAiChatModel chatModel = MistralAiChatModel.builder()
.apiKey(apiKey)
.listeners(List.of(listener))
.build();The library requires:
All models require a Mistral AI API key. Obtain one from Mistral AI Console.
Security Best Practices:
// Recommended: Environment variable
.apiKey(System.getenv("MISTRAL_API_KEY"))
// Alternative: Configuration file
.apiKey(config.getString("mistral.api.key"))
// Alternative: Secrets manager
.apiKey(secretsManager.getSecret("mistral-api-key"))
// DO NOT: Hardcode keys
// .apiKey("sk-...") // NEVER DO THIS| Capability | Synchronous Class | Streaming Class | Model Names |
|---|---|---|---|
| Chat | MistralAiChatModel | MistralAiStreamingChatModel | MistralAiChatModelName |
| Embeddings | MistralAiEmbeddingModel | N/A | MistralAiEmbeddingModelName |
| Code Completion | MistralAiFimModel | MistralAiStreamingFimModel | MistralAiFimModelName |
| Moderation | MistralAiModerationModel | N/A | String ("mistral-moderation-latest") |
| Discovery | MistralAiModels, MistralAiModelCatalog | N/A | N/A |
Error: "401 Unauthorized" or "Invalid API key" Solution: Verify API key is correct and has not expired. Check environment variable is set correctly.
Error: "429 Too Many Requests"
Solution: Implement exponential backoff using maxRetries(), or reduce request frequency. Consider upgrading API plan.
Error: Response truncated or "token limit exceeded"
Solution: Reduce maxTokens() parameter, or chunk long conversations. Check finish reason for LENGTH.
Error: Request timeout
Solution: Increase timeout using .timeout(Duration.ofSeconds(120)), or reduce complexity of request.
Error: "Model not found" or invalid model name Solution: Verify model name using MistralAiModels.availableModels(), or check for typos in model name string.
Install with Tessl CLI
npx tessl i tessl/maven-dev-langchain4j--langchain4j-mistral-ai@1.11.0