Skip to content

[Customer Portal][BE] Add AI chat agent for case classification during creation - #126

Merged
Rashmika998 merged 8 commits into
wso2-open-operations:customer-portal-milestone-1from
Rashmika998:customer-portal-milestone-1-chat
Feb 11, 2026
Merged

Rashmika998 merged 8 commits into
wso2-open-operations:customer-portal-milestone-1from
Rashmika998:customer-portal-milestone-1-chat

Conversation

@Rashmika998

@Rashmika998 Rashmika998 commented Feb 11, 2026 •

Copy link
Copy Markdown
Contributor

Description

This PR introduces an AI-powered chat agent to classify cases during the case creation flow and return relevant suggestions to the case creation page.

Changes

  • Integrated AI chat agent for case classification
  • Implemented request/response handling for AI-based analysis
  • Mapped AI classification results to case creation UI

Testing

  • Tested AI classification with multiple case scenarios
  • Verified response rendering on case creation page
  • Validated fallback behavior
  • Performed regression testing on existing case workflows

Related Issue

Checklist

  • AI agent integrated
  • Classification logic validated
  • Error handling implemented
  • No impact on existing flows

Summary by CodeRabbit

  • New Features
    • AI-powered case classification that categorizes and prioritizes customer cases using chat history, product details, environment, region, and service tier.
    • New API endpoint to submit cases for automated classification and receive structured classification responses.
    • OAuth2-backed AI service integration with configurable endpoint and credentials for secure communication.

@Rashmika998 Rashmika998 self-assigned this Feb 11, 2026
@Rashmika998 Rashmika998 added Type/New Feature Represents a request or task for a new feature App/Customer Portal Area/Backend labels Feb 11, 2026
@coderabbitai

coderabbitai Bot commented Feb 11, 2026 •

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

Adds an AI chat agent integration: new config section, OAuth2-backed HTTP client with retry settings, typed request/response models, a new service resource POST /cases/classify that forwards payloads to the AI service and returns classification responses or server errors.

Changes

Cohort / File(s) Summary
Configuration
apps/customer-portal/backend/config.toml.local
Adds [customer_portal.ai_chat_agent] section with aiChatAgentBaseUrl and nested clientCredentialsOauth2Config entries for tokenUrl, clientId, clientSecret, scopes.
AI Chat Agent — client
apps/customer-portal/backend/modules/ai_chat_agent/client.bal
Adds final http:Client aiChatAgentClient configured with OAuth2 client-credentials, HTTP/1.1, keep-alive disabled, 300s timeout, retry (3 attempts, 2s) for 502/503/504.
AI Chat Agent — API
apps/customer-portal/backend/modules/ai_chat_agent/ai_chat_agent.bal
Adds public isolated function createCaseClassification(CaseClassificationPayload) that delegates the payload to aiChatAgentClient POST /case_classification.
AI Chat Agent — types
apps/customer-portal/backend/modules/ai_chat_agent/types.bal
Adds public records CaseClassificationPayload, CaseClassificationResponse, ChatCaseInfo and a configurable ClientCredentialsOauth2Config record; includes JSON mapping annotations.
Service & shared types
apps/customer-portal/backend/service.bal, apps/customer-portal/backend/types.bal
Imports AI module, adds resource function post cases/classify(...) that checks user-info header, constructs and forwards classification request, logs errors and returns classification response or InternalServerError; adds shared CaseClassificationPayload type.

Sequence Diagram

sequenceDiagram
    participant Client
    participant Service as Backend Service
    participant Module as AI Chat Agent Module
    participant AIService as External AI Service

    Client->>Service: POST /cases/classify (payload)
    Service->>Service: Read user-info header
    alt header missing
        Service-->>Client: 500 InternalServerError
    else header present
        Service->>Module: createCaseClassification(payload)
        Module->>AIService: POST /case_classification (with OAuth2 token)
        Note right of AIService: Retries (3 attempts, 2s interval) on 502/503/504
        AIService-->>Module: CaseClassificationResponse
        Module-->>Service: Return response
        Service-->>Client: CaseClassificationResponse
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested reviewers

  • cloby99

Poem

🐰 I hopped through configs, keys in paw,

OAuth tokens humming, retries on guard,
I sent the chat to learn and tell,
A case emerged where issues dwell,
Hooray — the portal listens hard!

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Description check ⚠️ Warning The description is incomplete and does not follow the required template structure. It lacks critical sections like Purpose, Goals, Approach, User stories, Release note, Documentation, Training, Certification, Marketing, Automation tests, Security checks, and other required sections. Follow the repository's description template comprehensively. Include all required sections: Purpose with issue links, Goals, Approach with details, User stories, Release note, Documentation, Training, Certification, Marketing, Automation tests with coverage, Security checks, Samples, Related PRs, Migrations (if applicable), Test environment, and Learning.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: adding an AI chat agent for case classification in the customer portal backend.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

No actionable comments were generated in the recent review. 🎉

🧹 Recent nitpick comments
apps/customer-portal/backend/service.bal (3)

837-838: Consider defining a public-facing response type instead of exposing ai_chat_agent:CaseClassificationResponse directly.

Other endpoints in this service define public types in types.bal and map module-internal responses (e.g., mapCommentsResponse, mapDeployments). Exposing the internal module type directly couples the public API surface to the AI module's type definition — any field change there silently alters the contract with the frontend. Based on learnings, the Customer Portal backend should validate public API surfaces and corresponding mapping logic between internal and public types.


849-858: Mixed naming convention in AI service payload: chat_history (snake_case) vs productDetails, environments, etc. (camelCase).

The outgoing payload mixes chat_history (snake_case) with camelCase fields. This is likely dictated by the AI service's expected schema, but it makes the contract harder to reason about. If the external API requires snake_case, consider aligning all field names consistently in the ChatCaseInfo type definition and documenting the external contract.

Also, the TODO on line 849 to persist chat history is noted — ensure this is tracked in an issue so it isn't forgotten.

,

Do you want me to open a GitHub issue to track the chat history persistence TODO?


837-869: Consider rate-limiting or throttling on the AI classification endpoint.

AI service calls are typically expensive (latency and cost). This endpoint is open to any authenticated user with no visible rate-limiting. Depending on your infrastructure setup, consider applying per-user rate limits or throttling at the gateway/service level to prevent abuse or unexpected cost spikes.

Tip

Issue Planner is now in beta. Read the docs and try it out! Share your feedback on Discord.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@apps/customer-portal/backend/config.toml.local`:
- Around line 28-34: The TOML has the OAuth2 config under the wrong section —
change the header currently named
[customer_portal.updates.clientCredentialsOauth2Config] to
[customer_portal.ai_chat_agent.clientCredentialsOauth2Config] so the
ai_chat_agent gets its own credentials; ensure the block sits under the
customer_portal.ai_chat_agent section (matching aiChatAgentBaseUrl) and remove
any duplicate/incorrect [customer_portal.updates.clientCredentialsOauth2Config]
entry to avoid overwriting the updates config.

In `@apps/customer-portal/backend/modules/ai_chat_agent/types.bal`:
- Around line 30-42: Change the CaseClassificationPayload fields to idiomatic
camelCase (e.g., chatHistory, productDetails, environments, region, tier) and
add `@jsondata`:Name annotations to each field to map them to the snake_case keys
expected by the external API (for example annotate chatHistory with
`@jsondata`:Name("chat_history")); follow the same pattern used in
CaseClassificationResponse (caseInfo -> case_info) so the Ballerina record uses
camelCase internally while the serialized JSON matches the /case_classification
endpoint.
🧹 Nitpick comments (3)
apps/customer-portal/backend/types.bal (1)

312-325: Consider adding input constraints on chatHistory.

The chatHistory field accepts an unbounded string. Since this is forwarded to an external AI service (with a 300s timeout and retries), a very large payload could cause performance issues or exceed the downstream service's limits. Consider adding a @constraint:String {maxLength: ...} annotation, consistent with how other payloads in this file use constraints (e.g., CommentCreatePayload).

apps/customer-portal/backend/service.bal (2)

849-849: Track the TODO for persisting chat history.

The comment on line 849 notes the need to persist chat history. Consider creating a tracked issue so this doesn't get lost.

Do you want me to open a GitHub issue to track this?


850-858: Inconsistent field naming convention between the two CaseClassificationPayload types.

The public-facing CaseClassificationPayload (in types.bal) uses camelCase (chatHistory), while the AI chat agent module's CaseClassificationPayload (in ai_chat_agent/types.bal) uses snake_case (chat_history) for that same field but camelCase for all others (productDetails, environments, etc.). This mixed naming within the internal type is confusing. Consider aligning the AI module's payload to use either all camelCase (with @jsondata:Name annotations for the wire format) or all snake_case consistently.

Comment thread apps/customer-portal/backend/config.toml.local
Comment thread apps/customer-portal/backend/modules/ai_chat_agent/types.bal
suhand
suhand previously approved these changes Feb 11, 2026
Comment thread apps/customer-portal/backend/service.bal Outdated
Comment thread apps/customer-portal/backend/service.bal
Comment thread apps/customer-portal/backend/service.bal Outdated
@Rashmika998
Rashmika998 merged commit 0626dc1 into wso2-open-operations:customer-portal-milestone-1 Feb 11, 2026
1 check passed
@Rashmika998 Rashmika998 moved this from Done to Staging Deployed in Customer Portal Development Feb 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

App/Customer Portal Area/Backend Type/New Feature Represents a request or task for a new feature

Projects

Status: Staging Deployed

Development

Successfully merging this pull request may close these issues.

3 participants