Skip to content

feat(dotAI): Dot AI LangChain4J - Azure OpenAI#35243

Draft
ihoffmann-dot wants to merge 13 commits intodot-ai-langchain-integrationfrom
dot-ai-langchain-azure-openai
Draft

feat(dotAI): Dot AI LangChain4J - Azure OpenAI#35243
ihoffmann-dot wants to merge 13 commits intodot-ai-langchain-integrationfrom
dot-ai-langchain-azure-openai

Conversation

@ihoffmann-dot
Copy link
Copy Markdown
Member

Summary

Adds Azure OpenAI as a supported provider in the LangChain4J integration layer.
Enterprise customers using Azure-hosted OpenAI deployments can now configure
dotAI without any code changes — only a providerConfig JSON update is required.

  • Add langchain4j-azure-open-ai dependency
  • Add azure_openai case to LangChain4jModelFactory switch
  • Implement buildAzureOpenAiChatModel, buildAzureOpenAiEmbeddingModel, buildAzureOpenAiImageModel
  • Pin Netty (4.1.118.Final) and Reactor (3.4.41) in BOM to resolve transitive version conflicts introduced by Azure SDK
  • Add 3 unit tests in LangChain4jModelFactoryTest

Configuration

{
  "chat": {
    "provider": "azure_openai",
    "apiKey": "...",
    "endpoint": "https://my-company.openai.azure.com/",
    "deploymentName": "gpt-4o",
    "apiVersion": "2024-02-01",
    "maxTokens": 16384,
    "temperature": 1.0
  },
  "embeddings": {
    "provider": "azure_openai",
    "apiKey": "...",
    "endpoint": "https://my-company.openai.azure.com/",
    "deploymentName": "text-embedding-ada-002",
    "apiVersion": "2024-02-01"
  },
  "image": {
    "provider": "azure_openai",
    "apiKey": "...",
    "endpoint": "https://my-company.openai.azure.com/",
    "deploymentName": "dall-e-3",
    "apiVersion": "2024-02-01"
  }
}

Notes

  • deploymentName is required for Azure (differs from model name). Falls back to model if not set.
  • apiVersion maps to Azure's serviceVersion. Recommended: 2024-02-01.
  • Netty/Reactor version pins are required for Azure SDK compatibility and do not affect existing behavior.

Related Issue

This PR fixes #35183
EPIC: dotAI Multi-Provider Support #33970

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 7, 2026

❌ Issue Linking Required

This PR could not be linked to an issue. All PRs must be linked to an issue for tracking purposes.

How to fix this:

Option 1: Add keyword to PR body (Recommended - auto-removes this comment)
Edit this PR description and add one of these lines:

  • This PR fixes #123 or Fixes: #123

  • This PR closes #123 or Closes: #123

  • This PR resolves #123 or Resolves: #123

  • Other supported keywords: fix, fixed, close, closed, resolve, resolved
    Option 2: Link via GitHub UI (Note: won't clear the failed check)

  1. Go to the PR → Development section (right sidebar)

  2. Click "Link issue" and select an existing issue

  3. Push a new commit or re-run the workflow to clear the failed check
    Option 3: Use branch naming
    Create a new branch with one of these patterns:

  • 123-feature-description (number at start)

  • issue-123-feature-description (issue-number at start)

  • feature-issue-123 (issue-number anywhere)

Why is this required?

Issue linking ensures proper tracking, documentation, and helps maintain project history. It connects your code changes to the problem they solve.---

This comment was automatically generated by the issue linking workflow

@claude
Copy link
Copy Markdown
Contributor

claude bot commented Apr 7, 2026

Claude finished @ihoffmann-dot's task in 2m 8s —— View job


Code Review

  • Read changed files
  • Review LangChain4jModelFactory.java
  • Review LangChain4jModelFactoryTest.java
  • Review bom/application/pom.xml
  • Review dotCMS/pom.xml

Findings

Bug: model validation fires even when deploymentName is set

LangChain4jModelFactory.java:93 calls requireNonBlank(config.model(), "model", modelType) for all providers before the switch. For Azure, model is optional — deploymentName is the actual required field. The PR's own documented example configs (embeddings, image sections in the PR body) do not set model, yet the factory would reject them with "providerConfig.embeddings.model is required but was not set". The test helper azureOpenAiConfig() always sets both fields, masking this. The fix is to skip the blanket model check for azure_openai, or relax it to require model OR deploymentName.

Fix this →

Inconsistency: maxCompletionTokens silently ignored in Azure chat builders

OpenAI chat (lines 142-145) and streaming (156-160) check maxCompletionTokens first, falling back to maxTokens. The Azure chat and streaming builders (lines 197, 209) only check maxTokens. A customer migrating a config from openai to azure_openai who uses maxCompletionTokens will silently lose that limit. If AzureOpenAiChatModel doesn't support maxCompletionTokens, it should at least forward the value to maxTokens.

Fix this →

Missing test: buildStreamingChatModel with azure_openai

Tests cover chat, embedding, and image for Azure but not streaming. buildAzureOpenAiStreamingChatModel has its own builder path with slightly different field handling and should have at least a basic smoke test matching the pattern of test_buildChatModel_azureOpenai_returnsModel.

Design fragility: build() grows a positional Function parameter per provider

The private build() signature now has openAiFn and azureOpenAiFn. When Bedrock and Vertex AI land, it becomes 4 positional function arguments, with 4 call sites each needing updating. A Map<String, Function<ProviderConfig, T>> dispatch table would make adding providers a local change with zero signature churn. Worth addressing before the next provider lands.

Risk: Reactor pinned to EOL branch 3.4.x

reactor-core is pinned to 3.4.41, which is in the Reactor 3.4.x EOL branch. The comment says it resolves a conflict between "existing deps (3.3.16)" and Azure's requirement for 3.4+. Jumping from 3.3.x to 3.4.x is fine, but 3.4.41 is the ceiling. If any other dependency in the tree requires 3.5.x+ (which is the current supported branch), Maven will stay on 3.4.41 due to the BOM pin and the conflict will resurface. Worth validating mvn dependency:tree output to confirm no 3.5+ consumers exist currently.

Known limitation: API key auth only

Azure OpenAI guidance for enterprise customers favors Managed Identity / Azure AD (tokenCredential) over API keys. The current implementation only wires apiKey. This is acceptable for an initial cut but should be called out explicitly in docs/README for the enterprise audience the PR targets.


The model validation bug and maxCompletionTokens inconsistency are the ones most likely to bite real users. The rest are lower priority.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

1 participant