ADR-013 Appendix: Integration Analysis with Related ADRs

Date: 2025-12-06 Purpose: Analyze relationships, overlaps, and integration strategies between ADR-013 (LangChain4j) and ADRs 008, 010, 011


Executive Summary

ADR Primary Purpose Integration Role with ADR-013
ADR-008 AD Registry (data source) Data Provider - Provides metadata for LangChain4j tools
ADR-010 MCP Server (external AI interface) Alternative Interface - Different transport for same capabilities
ADR-011 cloudempiere.ai (deep iDempiere context) Enhanced Backend - Secure execution with full ERP context
ADR-013 LangChain4j (internal routing) Orchestration Layer - Natural language to CLI command routing

Relationship Matrix

                    ┌─────────────────────────────────────────────────────────┐
                    │                   AI INTERFACES                          │
                    │                                                          │
                    │  ┌───────────────┐         ┌───────────────┐            │
                    │  │   ADR-010     │         │   ADR-013     │            │
                    │  │  MCP Server   │         │  LangChain4j  │            │
                    │  │               │         │               │            │
                    │  │ External AI   │         │  Internal AI  │            │
                    │  │ (Claude Code) │         │ (CLI `ask`)   │            │
                    │  └───────┬───────┘         └───────┬───────┘            │
                    │          │                         │                     │
                    └──────────┼─────────────────────────┼─────────────────────┘
                               │                         │
                               │    ┌────────────────────┘
                               │    │
                               ▼    ▼
                    ┌─────────────────────────────────────────────────────────┐
                    │                 SHARED SERVICE LAYER                     │
                    │                                                          │
                    │  ┌─────────────────────────────────────────────────────┐│
                    │  │              CLI Services (existing)                 ││
                    │  │  RegistryService, GeneratorRegistry, TableService   ││
                    │  └─────────────────────────────────────────────────────┘│
                    │                         │                                │
                    └─────────────────────────┼────────────────────────────────┘
                                              │
                               ┌──────────────┼──────────────┐
                               │              │              │
                               ▼              ▼              ▼
                    ┌────────────────┐ ┌────────────┐ ┌────────────────┐
                    │    ADR-008     │ │  Direct DB │ │   ADR-011      │
                    │   Registry     │ │   (JDBC)   │ │ cloudempiere   │
                    │   (metadata)   │ │            │ │ .ai (secure)   │
                    └────────────────┘ └────────────┘ └────────────────┘

Detailed Analysis

1. ADR-008 (Application Dictionary Registry) ↔ ADR-013

Relationship Type: DATA DEPENDENCY

Aspect ADR-008 Role ADR-013 Role
Purpose Provides AD metadata (tables, windows, patterns) Consumes metadata for intelligent routing
Data Flow Exports JSON, serves queries Enriches LLM context with AD knowledge
Integration Point RegistryService RegistryTools wraps service

Integration Strategy:

// ADR-013 LangChain4j Tool using ADR-008 Registry
public class RegistryTools {

    @Inject
    RegistryService registryService;  // From ADR-008

    @Tool("Lists tables from Application Dictionary. " +
          "Returns table names, descriptions, and access levels.")
    public String listTables(String pattern) {
        // Leverage ADR-008's RegistryService
        return registryService.listTables(pattern).toJson();
    }

    @Tool("Gets table metadata including columns and relationships. " +
          "Use for understanding iDempiere data structures.")
    public String describeTable(String tableName) {
        // Uses ADR-008's detailed export
        return registryService.exportTable(tableName).toJson();
    }
}

Overlap: None - complementary roles (data vs. orchestration)

Recommendation: ADR-013 should directly depend on ADR-008's RegistryService for all AD metadata queries. No duplication needed.


2. ADR-010 (MCP Server) ↔ ADR-013

Relationship Type: PARALLEL INTERFACES (potential consolidation)

Aspect ADR-010 (MCP) ADR-013 (LangChain4j)
Transport stdio/SSE (JSON-RPC) In-process (Java)
Client Claude Code, Claude Desktop CLI user via ask command
Tool Definition @McpTool annotations @Tool annotations
Deployment Separate JAR Embedded in CLI
LLM External (Claude API) Configurable (local/cloud)

Overlap Analysis:

TOOL DEFINITIONS OVERLAP:
┌────────────────────────────────────────────────────────────────┐
│                                                                 │
│  ADR-010 MCP Tools          ADR-013 LangChain4j Tools          │
│  ─────────────────          ────────────────────────           │
│  @McpTool addTable()   ←──→ @Tool createTable()      OVERLAP   │
│  @McpTool listTables() ←──→ @Tool listTables()       OVERLAP   │
│  @McpTool describeTable()←→ @Tool describeTable()    OVERLAP   │
│  @McpTool generateModel()←→ @Tool generateModel()    OVERLAP   │
│  @McpTool syncTable()  ←──→ @Tool syncTable()        OVERLAP   │
│                                                                 │
└────────────────────────────────────────────────────────────────┘

Integration Strategies:

Extract tool logic into shared service classes that both ADR-010 and ADR-013 consume:

// Shared tool logic (new package: org.idempiere.cli.ai.shared)
public class TableToolLogic {

    @Inject TableService tableService;
    @Inject RegistryService registryService;

    public ToolResult listTables(String pattern) {
        // Shared implementation
        return new ToolResult(registryService.listTables(pattern));
    }

    public ToolResult createTable(String name, String description, String columns) {
        // Shared implementation
        return new ToolResult(tableService.createTable(name, description, columns));
    }
}

// ADR-010 MCP wrapper
@McpTool(name = "listTables", description = "...")
public class McpTableTool {
    @Inject TableToolLogic logic;

    public String listTables(String pattern) {
        return logic.listTables(pattern).toMcpFormat();
    }
}

// ADR-013 LangChain4j wrapper
public class LangChainTableTool {
    @Inject TableToolLogic logic;

    @Tool("Lists tables matching pattern...")
    public String listTables(String pattern) {
        return logic.listTables(pattern).toLangChainFormat();
    }
}

Option B: MCP Server Uses LangChain4j Internally

ADR-010 MCP Server delegates to LangChain4j for actual routing:

// MCP Server with LangChain4j backend
public class McpServerWithLangChain {

    @Inject CliRouterAgent langChainAgent;  // From ADR-013

    @McpTool(name = "naturalLanguage", description = "Process natural language request")
    public String processRequest(String request) {
        // Delegate to LangChain4j for complex routing
        return langChainAgent.route(request);
    }
}

Recommendation: Option A (Shared Tool Implementation) to avoid duplication while maintaining clean separation between transport mechanisms.


3. ADR-011 (cloudempiere.ai) ↔ ADR-013

Relationship Type: BACKEND ENHANCEMENT

Aspect ADR-011 ADR-013
Security Role-based, MRole.addAccessSQL() None (inherits from backend)
Context Live iDempiere session, window state Static AD metadata
Audit AIG_QueryAudit table None
Execution Inside iDempiere JVM Standalone CLI

Integration Strategy:

ADR-013's LangChain4j tools can use ADR-011's cloudempiere.ai as a secure backend:

public class SecureRegistryTools {

    @Inject
    BackendAdapter backend;  // Can be CloudempiereAiBackend (ADR-011)

    @Tool("Executes secure database query with role-based filtering")
    public String secureQuery(
            @P("SQL query") String sql,
            @P("Role ID for permissions") int roleId) {

        if (backend instanceof CloudempiereAiBackend) {
            // Use ADR-011 secure execution
            return ((CloudempiereAiBackend) backend)
                    .executeSecureQuery(sql, roleId)
                    .toJson();
        } else {
            // Fallback to direct query (less secure)
            return backend.executeQuery(sql).toJson();
        }
    }
}

Backend Selection at Runtime:

# application.properties
idempiere.cli.ai.backend=cloudempiere  # Options: direct, rest, cloudempiere

# For cloudempiere.ai backend (ADR-011)
cloudempiere.ai.url=http://localhost:8080/api/ai
cloudempiere.ai.token=${CLOUDEMPIERE_AI_TOKEN}
cloudempiere.ai.role-id=102

Overlap: Minimal - ADR-011 provides security/context, ADR-013 provides orchestration

Recommendation: ADR-013 should support ADR-011 as an optional enhanced backend for production deployments requiring security.


Consolidated Architecture

┌─────────────────────────────────────────────────────────────────────────────┐
│                            USER INTERFACES                                   │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                              │
│  ┌──────────────────┐  ┌──────────────────┐  ┌──────────────────┐           │
│  │  Claude Code     │  │  CLI Traditional │  │  CLI Natural     │           │
│  │  Claude Desktop  │  │  (Picocli)       │  │  Language (ask)  │           │
│  │                  │  │                  │  │                  │           │
│  │  External AI     │  │  `registry list` │  │ `ask "list all   │           │
│  │                  │  │  `generate model`│  │  audit tables"`  │           │
│  └────────┬─────────┘  └────────┬─────────┘  └────────┬─────────┘           │
│           │                     │                     │                      │
│           │ stdio/JSON-RPC      │ direct              │ in-process           │
│           │                     │                     │                      │
└───────────┼─────────────────────┼─────────────────────┼──────────────────────┘
            │                     │                     │
            ▼                     │                     ▼
┌───────────────────────┐         │         ┌───────────────────────┐
│      ADR-010          │         │         │      ADR-013          │
│    MCP Server         │         │         │    LangChain4j        │
│                       │         │         │                       │
│ - @McpTool wrappers   │         │         │ - @Tool wrappers      │
│ - MCP Resources       │         │         │ - Agent routing       │
│ - MCP Prompts         │         │         │ - Local LLM support   │
└───────────┬───────────┘         │         └───────────┬───────────┘
            │                     │                     │
            └─────────────────────┼─────────────────────┘
                                  │
                                  ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│                     SHARED TOOL LOGIC LAYER (NEW)                            │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                              │
│  ┌────────────────┐  ┌────────────────┐  ┌────────────────┐                 │
│  │ TableToolLogic │  │GeneratorTool   │  │ MigrationTool  │                 │
│  │                │  │Logic           │  │ Logic          │                 │
│  │ - listTables() │  │ - model()      │  │ - create()     │                 │
│  │ - createTable()│  │ - process()    │  │ - apply()      │                 │
│  │ - describeT()  │  │ - window()     │  │ - rollback()   │                 │
│  └───────┬────────┘  └───────┬────────┘  └───────┬────────┘                 │
│          │                   │                   │                           │
└──────────┼───────────────────┼───────────────────┼───────────────────────────┘
           │                   │                   │
           └───────────────────┼───────────────────┘
                               │
                               ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│                        CLI SERVICES (EXISTING)                               │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                              │
│  ┌────────────────┐  ┌────────────────┐  ┌────────────────┐                 │
│  │RegistryService │  │GeneratorRegistry│ │MigrationService│                 │
│  │   (ADR-008)    │  │   (ADR-003)    │  │   (ADR-005)   │                 │
│  └───────┬────────┘  └───────┬────────┘  └───────┬────────┘                 │
│          │                   │                   │                           │
└──────────┼───────────────────┼───────────────────┼───────────────────────────┘
           │                   │                   │
           └───────────────────┼───────────────────┘
                               │
                               ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│                         BACKEND ADAPTERS                                     │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                              │
│  ┌────────────────┐  ┌────────────────┐  ┌────────────────┐                 │
│  │  DirectDB      │  │   REST API     │  │ cloudempiere   │                 │
│  │  Backend       │  │   Backend      │  │ .ai Backend    │                 │
│  │                │  │   (ADR-009)    │  │   (ADR-011)    │                 │
│  │ JDBC direct    │  │ OpenAPI client │  │ Secure + Audit │                 │
│  └───────┬────────┘  └───────┬────────┘  └───────┬────────┘                 │
│          │                   │                   │                           │
└──────────┼───────────────────┼───────────────────┼───────────────────────────┘
           │                   │                   │
           ▼                   ▼                   ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│                          DATA SOURCES                                        │
├─────────────────────────────────────────────────────────────────────────────┤
│  PostgreSQL DB          iDempiere REST API       iDempiere (with OSGi)      │
└─────────────────────────────────────────────────────────────────────────────┘

Implementation Status

Shared Tool Logic Layer - IMPLEMENTED

The org.idempiere.cli.ai.shared package has been created with the following classes:

src/main/java/org/idempiere/cli/ai/shared/
├── package-info.java          # Package documentation
├── ToolResult.java            # Standardized response format
├── RegistryToolLogic.java     # AD metadata operations
├── TableToolLogic.java        # Table operations
├── GeneratorToolLogic.java    # Code generation
├── MigrationToolLogic.java    # Migration scripts
└── DoctorToolLogic.java       # Diagnostics

Class Summary

Class Methods Purpose
ToolResult success(), error(), data(), toJson(), toMcpFormat(), toLangChainFormat() Unified response format
RegistryToolLogic getStatistics(), listTables(), describeTable(), listWindows(), listProcesses(), search() AD queries
TableToolLogic createTable(), syncTable(), listTables(), deleteTable() Table operations
GeneratorToolLogic listGenerators(), generate(), generateModel(), generateProcess(), generatePlugin() Code generation
MigrationToolLogic generateMigration(), applyMigrations(), initMigrationFolder() Migration scripts
DoctorToolLogic checkEnvironment(), checkApi(), checkDatabase(), getConfigStatus() Diagnostics

Implementation Recommendations

Next Steps: Create Wrapper Layers

Create wrapper packages for both interfaces:

src/main/java/org/idempiere/cli/ai/
├── shared/                    # ✅ IMPLEMENTED: Shared tool logic
│   ├── package-info.java
│   ├── ToolResult.java
│   ├── RegistryToolLogic.java
│   ├── TableToolLogic.java
│   ├── GeneratorToolLogic.java
│   ├── MigrationToolLogic.java
│   └── DoctorToolLogic.java
├── langchain/                 # TODO: ADR-013 LangChain4j wrappers
│   ├── CliRouterAgent.java
│   └── tools/
│       ├── RegistryTools.java    # Uses shared.RegistryToolLogic
│       └── GeneratorTools.java   # Uses shared.GeneratorToolLogic
└── mcp/                       # TODO: ADR-010 MCP wrappers (if embedded)
    └── tools/
        ├── McpRegistryTool.java  # Uses shared.RegistryToolLogic
        └── McpGeneratorTool.java # Uses shared.GeneratorToolLogic

Priority 2: Backend Abstraction

Extend BackendAdapter interface to support all backends:

public interface BackendAdapter {
    // Query operations
    QueryResult executeQuery(String sql);
    QueryResult executeSecureQuery(String sql, int roleId);  // For ADR-011

    // Metadata operations
    TableMetadata getTableMetadata(String tableName);
    List<TableInfo> listTables(String pattern);

    // Context operations (ADR-011 only)
    default Optional<WindowContext> getWindowContext(int windowNo) {
        return Optional.empty();  // Only cloudempiere.ai supports this
    }

    // Backend capabilities
    boolean supportsSecureQuery();
    boolean supportsLiveContext();
}

Priority 3: Configuration Unification

Single configuration for all AI features:

# idempiere-cli AI Configuration

# LLM Provider (ADR-013)
idempiere.ai.provider=ollama           # ollama, anthropic, openai
idempiere.ai.model=llama3              # Model name
idempiere.ai.ollama.url=http://localhost:11434

# Backend Selection
idempiere.ai.backend=direct            # direct, rest, cloudempiere
idempiere.ai.cloudempiere.url=http://localhost:8080/api/ai
idempiere.ai.cloudempiere.token=${CLOUDEMPIERE_TOKEN}

# MCP Server (ADR-010)
idempiere.mcp.enabled=true
idempiere.mcp.transport=stdio          # stdio, sse

Decision Updates for ADR-013

Based on this analysis, update ADR-013 to include:

  1. Dependency on ADR-008: Direct use of RegistryService for all AD metadata
  2. Shared Tool Layer: Extract tool logic for reuse by ADR-010 MCP Server
  3. Backend Abstraction: Support ADR-011 cloudempiere.ai as secure backend option
  4. No Overlap with ADR-010: Different interfaces (internal vs external), shared implementation

Summary Table

Concern ADR-008 ADR-010 ADR-011 ADR-013
AD Metadata ✅ Owner Consumer Consumer Consumer
Tool Logic N/A Wrapper N/A Wrapper
External AI N/A ✅ Owner Backend N/A
Internal AI N/A N/A N/A ✅ Owner
Security N/A N/A ✅ Owner Consumer
LLM Routing N/A N/A N/A ✅ Owner
Local LLM N/A N/A N/A ✅ Owner

References

Path: /docs/developers/architecture/idempiere-hub/013-appendix-integration-analysis