Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions apps/customer-portal/backend/config.toml.local
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,11 @@ updatesServiceUrl = "<base_url>"
clientId = "<client_id>"
clientSecret = "<client_secret>"
scopes = ["<scopes>"]

[customer_portal.ai_chat_agent]
aiChatAgentBaseUrl = "<base_url>"
[customer_portal.ai_chat_agent.clientCredentialsOauth2Config]
tokenUrl = "<token_url>"
clientId = "<client_id>"
clientSecret = "<client_secret>"
scopes = ["<scopes>"]
Comment thread
Rashmika998 marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright (c) 2026 WSO2 LLC. (https://www.wso2.com).
//
// WSO2 LLC. licenses this file to you under the Apache License,
// Version 2.0 (the "License"); you may not use this file except
// in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.

# Create case classification for the given payload.
#
# + payload - Case classification payload
# + return - Case classification response or error
public isolated function createCaseClassification(CaseClassificationPayload payload)
returns CaseClassificationResponse|error {

return aiChatAgentClient->/case_classification.post(payload);
}
37 changes: 37 additions & 0 deletions apps/customer-portal/backend/modules/ai_chat_agent/client.bal
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Copyright (c) 2026 WSO2 LLC. (https://www.wso2.com).
//
// WSO2 LLC. licenses this file to you under the Apache License,
// Version 2.0 (the "License"); you may not use this file except
// in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
import ballerina/http;

configurable string aiChatAgentBaseUrl = ?;
configurable ClientCredentialsOauth2Config clientCredentialsOauth2Config = ?;

final http:Client aiChatAgentClient = check new (aiChatAgentBaseUrl, {
auth: {
...clientCredentialsOauth2Config
},
httpVersion: http:HTTP_1_1,
http1Settings: {keepAlive: http:KEEPALIVE_NEVER},
timeout: 300.0,
retryConfig: {
count: 3,
interval: 2.0,
statusCodes: [
http:STATUS_BAD_GATEWAY,
http:STATUS_SERVICE_UNAVAILABLE,
http:STATUS_GATEWAY_TIMEOUT
]
}
});
73 changes: 73 additions & 0 deletions apps/customer-portal/backend/modules/ai_chat_agent/types.bal
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// Copyright (c) 2026 WSO2 LLC. (https://www.wso2.com).
//
// WSO2 LLC. licenses this file to you under the Apache License,
// Version 2.0 (the "License"); you may not use this file except
// in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
import ballerina/data.jsondata;

# [Configurable] Client credentials grant type oauth2 configuration.
type ClientCredentialsOauth2Config record {|
# OAuth2 token endpoint
string tokenUrl;
# OAuth2 client ID
string clientId;
# OAuth2 client secret
string clientSecret;
# OAuth2 scopes
string[] scopes = [];
|};

# Case classification payload.
public type CaseClassificationPayload record {|
# Chat history
string chat_history;
# Product details
string[] productDetails;
# Environments
string[] environments;
# Region
string region;
# Tier
string tier;
|};
Comment thread
coderabbitai[bot] marked this conversation as resolved.

# Case classification response.
public type CaseClassificationResponse record {|
# Issue type
string issueType;
# Case information
@jsondata:Name {value: "case_info"}
ChatCaseInfo caseInfo;
# Severity level
string severityLevel;
json...;
|};

# Chat case information.
public type ChatCaseInfo record {|
# Description
string description;
# Short description
string shortDescription;
# Product name
string productName;
# Product version
string productVersion;
# Environment
string environment;
# Tier
string tier;
# Region
string region;
json...;
|};
39 changes: 39 additions & 0 deletions apps/customer-portal/backend/service.bal
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
// specific language governing permissions and limitations
// under the License.

import customer_portal.ai_chat_agent;
import customer_portal.authorization;
import customer_portal.entity;
import customer_portal.scim;
Expand Down Expand Up @@ -829,6 +830,44 @@ service http:InterceptableService / on new http:Listener(9090) {
return getCaseFilters(caseMetadata);
}

# Classify the case using AI chat agent.
#
# + payload - Case classification payload
# + return - Case classification response or an error
resource function post cases/classify(http:RequestContext ctx, CaseClassificationPayload payload)
returns ai_chat_agent:CaseClassificationResponse|http:InternalServerError {

authorization:UserInfoPayload|error userInfo = ctx.getWithType(authorization:HEADER_USER_INFO);
if userInfo is error {
return <http:InternalServerError>{
body: {
message: ERR_MSG_USER_INFO_HEADER_NOT_FOUND
}
};
}

// TODO: Need to persist the chat history
ai_chat_agent:CaseClassificationResponse|error classificationResponse =
ai_chat_agent:createCaseClassification(
{
chat_history: payload.chatHistory,
productDetails: payload.productDetails,
environments: payload.environments,
region: payload.region,
tier: payload.tier
Comment thread
Rashmika998 marked this conversation as resolved.
});
if classificationResponse is error {
string customError = "Failed to classify chat message.";
log:printError(customError, classificationResponse);
return <http:InternalServerError>{
body: {
message: customError
}
};
}
return classificationResponse;
}

# Get comments for a specific case.
#
# + id - ID of the case
Expand Down
14 changes: 14 additions & 0 deletions apps/customer-portal/backend/types.bal
Original file line number Diff line number Diff line change
Expand Up @@ -309,3 +309,17 @@ public type AttachmentPayload record {|
# Base 64 encoded content
string content;
|};

# Case classification payload.
public type CaseClassificationPayload record {|
# Chat history
string chatHistory;
# Product details
string[] productDetails;
# Environments
string[] environments;
# Region
string region;
# Tier
string tier;
|};