Implemented: AI plugin — LangChain4j integration for AI/LLM capabilities in OFBiz services (OFBIZ-13408)#244
Open
patelanil wants to merge 16 commits into
Open
Implemented: AI plugin — LangChain4j integration for AI/LLM capabilities in OFBiz services (OFBIZ-13408)#244patelanil wants to merge 16 commits into
patelanil wants to merge 16 commits into
Conversation
- ofbiz-component.xml: registers plugin, container, service resource - build.gradle: LangChain4j 1.8.0 dependencies (Apache 2.0) - servicedef/services.xml: empty stub (populated in Step 6) - config/ai.properties: gitignored, template only Plugin compiles cleanly into root OFBiz jar. Note: ai.properties is gitignored — not committed. Ref: patelanil/ofbiz-dev#1 OFBIZ-13408
- Implements Container interface following BirtContainer pattern - init() stores name and configFile only - start() reads provider-agnostic ai.properties: ai.provider, ai.model, ai.apiKey, ai.baseUrl, ai.timeout - Validates apiKey — fails fast with clear error if not configured - Provider switch builds ChatModel interface (not OpenAiChatModel) - openai case covers OpenAI, Groq, Ollama, Azure via baseUrl - Additional providers (anthropic, bedrock) can be added in switch - Stores singleton via AiFactory.setChatModel() (Step 3) - stop() calls AiFactory.destroy() - Note: ai.properties is gitignored — not committed Ref: patelanil/ofbiz-dev#1 OFBIZ-13408
- Static factory parallel to BirtFactory pattern - setChatModel(ChatModel) — called by AiContainer.start() - getChatModel() — throws IllegalStateException if not initialized - destroy() — called by AiContainer.stop() - Compiles cleanly with AiContainer Ref: patelanil/ofbiz-dev#1 OFBIZ-13408
- generate(dctx, messages) → String - generateStructured(dctx, messages, schema) → Map<String,Object> - TYPE_BUILDERS map pattern — no switch, extensible - JSON Schema vocabulary: string, number, integer, boolean, array, object - toChatMessages() converts List<Map> to LangChain4j ChatMessage list - buildJsonObjectSchema() + buildSchemaElement() for schema conversion - ResponseFormatType.JSON (JSON_SCHEMA does not exist in LangChain4j 1.8.0) - Jackson ObjectMapper for JSON response parsing - dctx parameter present for future use (audit logging, delegator) - GeneralException wraps all failures with clear message Ref: patelanil/ofbiz-dev#1 OFBIZ-13408
- generate(dctx, context) → calls AiWorker.generate, returns response - generateStructured(dctx, context) → calls AiWorker.generateStructured, returns result Map - ServiceUtil.returnSuccess/returnError pattern - UtilGenerics.cast() for unchecked context parameter casts - Pure delegation — no LangChain4j imports Ref: patelanil/ofbiz-dev#1 OFBIZ-13408
- ai.generate: messages (List IN) → response (String OUT) - ai.generateStructured: messages (List IN) + schema (Map IN) → result (Map OUT) - configName optional IN on both services (reserved for future use) - engine=java, location=org.apache.ofbiz.ai.AiServices Ref: patelanil/ofbiz-dev#1 OFBIZ-13408
- AiTest.groovy: calls AiWorker.generate with test message - ai.smokeTest service registered in services.xml - Verified end to end: response 'Hello!' received from OpenAI - Full stack confirmed: AiContainer → AiFactory → AiWorker → LangChain4j → OpenAI Ref: patelanil/ofbiz-dev#1 OFBIZ-13408
- What the plugin does and JIRA reference OFBIZ-13408 - Architecture table: AiContainer, AiFactory, AiWorker, AiServices - Installation and configuration instructions - Multiple provider support via ai.baseUrl - Usage examples: generate() and generateStructured() - Available services table with IN/OUT params - Smoke test instructions - Guide for adding new providers Ref: patelanil/ofbiz-dev#1 OFBIZ-13408
- ai.generate → aiGenerate - ai.generateStructured → aiGenerateStructured - ai.smokeTest → aiSmokeTest Dot notation is not OFBiz convention for service names. Updated services.xml and README.md. Ref: patelanil/ofbiz-dev#1 OFBIZ-13408
- AiStructuredTest.groovy: calls AiWorker.generateStructured with simple schema [word: 'string'] - aiSmokeTestStructured service registered in services.xml - Verified end to end: response [word:Helloreceived from OpenAI - Validates key presence in response Map Ref: patelanil/ofbiz-dev#1 OFBIZ-13408
- AiTest.groovy: add final String MODULE = 'AiTest.groovy' - AiStructuredTest.groovy: add final String MODULE = 'AiStructuredTest.groovy' - Replace all Debug.log string literal module arguments with MODULE - Follows OFBiz Groovy script convention (ArtifactInfo.groovy pattern) Ref: patelanil/ofbiz-dev#1 OFBIZ-13408
Contributor
Author
|
Fixed the SonarCloud violation — replaced the 'AiStructuredTest' string Also applied the same fix to AiTest.groovy proactively. |
Add langchain4j-anthropic:1.8.0 and langchain4j-ollama:1.8.0 to build.gradle. Refactor AiContainer to support openai, anthropic, and ollama via ai.properties config — replaces single-provider switch block with buildChatModel() if/else-if. AiContainer now holds the static ChatModel field and exposes getChatModel(), following the ServiceContainer pattern. AiFactory is deleted. Refactor AiWorker to reference AiContainer directly. Align both generate() and generateStructured() to fetch chatModel before the try block with consistent null guards — fixes a pre-existing NPE risk in generateStructured().
Both files are safe to track — ai.properties now uses placeholder values only, and CLAUDE.md contains no credentials.
Document all three supported providers (openai, anthropic, ollama) with inline comments, model examples, and placeholder API key. Follows OFBiz convention of committing properties files with placeholder values.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.




Adds a new optional plugin (plugins/ai) that integrates LangChain4j 1.8.0 to bring
native AI/LLM capabilities to OFBiz services, Groovy scripts, and screen actions.
The plugin follows established OFBiz patterns throughout:
following the same pattern as BirtContainer in the birt plugin
parallel to BirtWorker
The design is provider-agnostic — a switch on ai.provider selects the LangChain4j
builder. The initial implementation supports OpenAI and any OpenAI-compatible endpoint
(Ollama, Groq, Together AI, Azure OpenAI) via ai.baseUrl. Additional providers
(Anthropic, Bedrock) can be added by extending the switch in AiContainer.java.
Dependencies added (both Apache 2.0):
Smoke test verified end to end: ai.smokeTest service returned a live response
from OpenAI gpt-4o-mini.