Skip to content

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

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

feat(dotAI): Dot AI LangChain4J - Azure OpenAI#35243
ihoffmann-dot wants to merge 10 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 1m 42s —— View job


PR Review: feat(dotAI): Dot AI LangChain4J - Azure OpenAI

  • Gather context
  • Review LangChain4jModelFactory.java
  • Review LangChain4jModelFactoryTest.java
  • Review bom/application/pom.xml
  • Review dotCMS/pom.xml
  • Post findings

Issues Found

Bug: model is required even when only deploymentName is set

LangChain4jModelFactory.java:93 runs requireNonBlank(config.model(), "model", modelType) before dispatching to the provider. For Azure, deploymentName is the canonical identifier — model is optional. But the PR's own config example omits model:

{
  "provider": "azure_openai",
  "deploymentName": "gpt-4o",
  ...
}

That config will throw "providerConfig.chat.model is required" at runtime. The deploymentName != null ? deploymentName : model fallback in the builders is never reached when model is blank. Either move the model validation inside validateOpenAi only, or relax it to be provider-aware.

Fix this →

Inconsistency: maxCompletionTokens silently ignored for Azure chat models

The OpenAI builders (buildOpenAiChatModel L142–146, buildOpenAiStreamingChatModel L157–161) handle maxCompletionTokens with priority over maxTokens. The Azure equivalents (buildAzureOpenAiChatModel L211, buildAzureOpenAiStreamingChatModel L198) only check maxTokens. If a user migrates an existing OpenAI config (that uses maxCompletionTokens) to Azure, that field is silently dropped with no error or warning. Either add the same fallback logic or note the limitation explicitly.

Fix this →

Design: build() signature won't scale to Phase 2 providers

Adding bedrock and vertex_ai means another parameter per provider on both build() and all four public factory methods (20+ touches). Consider a Map<String, Function<ProviderConfig, T>> pattern now before Phase 2 lands. Not a blocker, but worth noting given the stated roadmap.


Missing tests

  • buildStreamingChatModel with Azure — no test added, unlike the other three model types.
  • Azure config with deploymentName only (no model) — the test helper always sets both. The bug above is invisible because tests mask it.

Fix this →


Minor

  • Netty pin may be incomplete (bom/application/pom.xml): 6 modules are pinned but netty-codec-http, netty-codec-http2, and netty-transport-native-epoll are also common Azure SDK transitive deps. Worth verifying mvn dependency:tree doesn't pull older versions for those.

  • validateAzureOpenAi doesn't validate deploymentName or model — the PR description says deploymentName is required, but the validator only checks apiKey and endpoint. At minimum the fallback logic deploymentName != null ? deploymentName : model should be backed by a "one of these must be set" guard.

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