Skip to content

Conversation

@Adiking117
Copy link

📌 Title
Add Agentic Reconciliation Workflow with LLM‑Generated Reports and Email Delivery

📝 Description
This PR introduces a modular agentic workflow for automated account reconciliation in the banking portal. The workflow leverages LangGraph4j for orchestration and LangChain4j (Groq LLM endpoint) for intelligent report generation. It replaces ad‑hoc/manual reconciliation with a reusable, extensible pipeline.

🔄 Changes Introduced
Workflow Graph (GraphBuilder)

Defines a three‑node pipeline:

TransactionFetchNode → fetches transactions + user info

ReportGenerationNode → generates a natural‑language reconciliation report using Groq LLM

MailReportNode → emails the report to the account holder

LLM Integration

Configurable via application.properties (groq.api.key, groq.api.model, groq.api.endpoint)

Centralized LlmConfig bean for clean injection of OpenAiChatModel

Report Enhancements

Balance consistency check (opening + deposits – withdrawals – transfers = closing)

Narrative explanations in plain language (money‑diary style)

Alerts for large withdrawals and low balances

Weekly/monthly trend summaries

Professional, non‑technical formatting (no markdown, no IDs/codes)

Email Delivery

Uses EmailService to send reconciliation reports with a friendly, customer‑facing template

Controller

/api/workflow/run endpoint to trigger the workflow manually

⚙️ Configuration
Add the following to application.properties:

properties

LLM API

groq.api.key=your-groq-api-key
groq.api.model=openai/gpt-oss-120b
groq.api.endpoint=https://api.groq.com/openai/v1

✅ Benefits
Provides end‑to‑end reconciliation automation

Generates human‑friendly, diary‑style reports instead of raw technical logs

Modular design → easy to extend with fraud detection, compliance checks, or chatbot integration

Clean separation of concerns (fetch → generate → deliver)

🚀 Next Steps
Integrate with chatbot interface for on‑demand execution

@abhi9720 abhi9720 self-assigned this Oct 21, 2025
@abhi9720 abhi9720 added the Feature Adds new functionality label Oct 21, 2025
@AmrElsayyad AmrElsayyad requested a review from Copilot October 22, 2025 13:55
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR introduces an automated reconciliation workflow that generates AI-powered account reports and delivers them via email. The implementation uses LangGraph4j for workflow orchestration and integrates with Groq's LLM API (via LangChain4j) to generate natural-language, customer-friendly reconciliation summaries.

Key changes:

  • Agentic workflow pipeline with three sequential nodes: transaction fetching, LLM-based report generation, and email delivery
  • Integration with Groq LLM API for generating narrative-style reconciliation reports
  • New REST endpoint (/api/workflow/run) to trigger the workflow manually

Reviewed Changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
application.properties.sample Added configuration placeholders for Groq API credentials and endpoints
ReconState.java Workflow state class managing account data, transactions, generated reports, and user information
TransactionFetchNode.java First workflow node that retrieves transactions and user details for the logged-in account
ReportGenerationNode.java Second workflow node that uses LLM to generate customer-friendly reconciliation reports
MailReportNode.java Third workflow node that emails the generated report to the account holder
GraphBuilder.java Orchestrator that builds and executes the three-node workflow graph
EmailServiceImpl.java Added HTML email template method for reconciliation reports
EmailService.java Interface method declaration for reconciliation report template
WorkFlowController.java REST controller exposing the workflow execution endpoint
LLMConfig.java Spring configuration for OpenAI chat model bean using Groq API settings
pom.xml Added LangGraph4j and LangChain4j dependencies with version management

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Comment on lines +35 to +37
groq.api.key = your-api-key
groq.api.model = your-model
groq.api.endpoint = your-model-endpoint
Copy link

Copilot AI Oct 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Property definitions should not contain spaces around the '=' sign. Remove spaces to follow standard Spring Boot property file conventions: groq.api.key=your-api-key

Suggested change
groq.api.key = your-api-key
groq.api.model = your-model
groq.api.endpoint = your-model-endpoint
groq.api.key=your-api-key
groq.api.model=your-model
groq.api.endpoint=your-model-endpoint

Copilot uses AI. Check for mistakes.
Comment on lines +19 to +24
public static final Map<String, Channel<?>> SCHEMA = Map.of(
ACCOUNT_KEY, Channels.appender(ArrayList::new),
TXNS_KEY, Channels.appender(ArrayList::new),
REPORT_KEY, Channels.appender(ArrayList::new),
USER_KEY, Channels.appender(ArrayList::new)
);
Copy link

Copilot AI Oct 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using appender channels for all keys creates unnecessary complexity since only the last value is retrieved. Consider using Channels.lastValue() or a single-value channel type for ACCOUNT_KEY, REPORT_KEY, and USER_KEY to simplify the retrieval logic and improve performance.

Copilot uses AI. Check for mistakes.
Comment on lines +50 to +53
ReconState.USER_KEY, Map.of(
"name", userResponse.getName(),
"email", userResponse.getEmail()
)
Copy link

Copilot AI Oct 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Type mismatch: USER_KEY is typed to store UserResponse objects (line 45-47 in ReconState), but this code stores a Map<String, String>. This causes a ClassCastException in MailReportNode line 26. Store the entire userResponse object instead: ReconState.USER_KEY, userResponse

Suggested change
ReconState.USER_KEY, Map.of(
"name", userResponse.getName(),
"email", userResponse.getEmail()
)
ReconState.USER_KEY, userResponse

Copilot uses AI. Check for mistakes.
// Join the stringified transactions into one block
String txnSummary = String.join("\n", txns);

String prompt = """
Copy link

Copilot AI Oct 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Corrected spelling of 'Reconcilation' to 'Reconciliation' in the PR title (note: appears in title, not in this code file)

Copilot uses AI. Check for mistakes.
Comment on lines +65 to +67
for (var item : compiled.stream(Map.of())) {
System.out.println("State after step: " + item);
}
Copy link

Copilot AI Oct 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Console output statements should be replaced with proper logging using SLF4J or similar framework. Add a logger instance: private static final Logger log = LoggerFactory.getLogger(GraphBuilder.class); and use log.info() or log.debug() instead.

Copilot uses AI. Check for mistakes.
graphBuilder.runGraph();
return ResponseEntity.ok("Workflow executed successfully");
} catch (Exception e) {
e.printStackTrace();
Copy link

Copilot AI Oct 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using printStackTrace() is not recommended for production code. Replace with proper logging: inject a Logger and use log.error(\"Workflow execution failed\", e); to ensure exceptions are logged through the application's logging framework.

Copilot uses AI. Check for mistakes.
import java.io.File;
import java.util.concurrent.CompletableFuture;

import com.webapp.bankingportal.dto.UserResponse;
Copy link

Copilot AI Oct 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The imported UserResponse class is not used in this file. Remove this unused import.

Suggested change
import com.webapp.bankingportal.dto.UserResponse;

Copilot uses AI. Check for mistakes.

import java.util.concurrent.CompletableFuture;

import com.webapp.bankingportal.dto.UserResponse;
Copy link

Copilot AI Oct 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The imported UserResponse class is not used in this interface. Remove this unused import.

Suggested change
import com.webapp.bankingportal.dto.UserResponse;

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Feature Adds new functionality

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants