Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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.updates.clientCredentialsOauth2Config]
tokenUrl = "<token_url>"
clientId = "<client_id>"
clientSecret = "<client_secret>"
scopes = ["<scopes>"]
Comment thread
Rashmika998 marked this conversation as resolved.
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.

# Get 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.
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
Comment thread
Rashmika998 marked this conversation as resolved.
Resolved
# + return - Case classification response or an error
resource function post cases/classification(http:RequestContext ctx, CaseClassificationPayload payload)
Comment thread
Rashmika998 marked this conversation as resolved.
Resolved
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.
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;
|};