Skip to content

Commit

Permalink
Merge pull request wso2#12374 from wso2/ai-features-beta
Browse files Browse the repository at this point in the history
API Chat and Marketplace Assistant Improvements
  • Loading branch information
ashera96 authored Mar 27, 2024
2 parents d838106 + e668ed8 commit 0a28f09
Show file tree
Hide file tree
Showing 22 changed files with 441 additions and 271 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -813,7 +813,7 @@ Set<SubscribedAPI> getPaginatedSubscribedAPIsByApplication(Application applicati
* Returns the API Chat execute call response as a string
*
* @param apiChatRequestId Request UUID
* @param requestPayload Request payload to be used for the AI service execute call
* @param requestPayload Request payload to be used for the AI service execute call
* @return execution response as a string
* @throws APIManagementException if execute call failed
*/
Expand All @@ -825,7 +825,7 @@ Set<SubscribedAPI> getPaginatedSubscribedAPIsByApplication(Application applicati
* @param apiId ID of the API
* @param apiChatRequestId Request UUID
* @param organization Identifier of an organization
* @return prepare response
* @return prepare response as a string
* @throws APIManagementException if prepare call failed
*/
String invokeApiChatPrepare(String apiId, String apiChatRequestId, String organization)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,12 @@

package org.wso2.carbon.apimgt.api.model;

import org.json.simple.JSONArray;

/**
* Details related to enriched API specification
*/
public class APIChatAPISpec {
private String serviceUrl = null;
private JSONArray tools;
private Object tools;

public String getServiceUrl() {
return serviceUrl;
Expand All @@ -32,11 +33,11 @@ public void setServiceUrl(String serviceUrl) {
this.serviceUrl = serviceUrl;
}

public JSONArray getTools() {
public Object getTools() {
return tools;
}

public void setTools(JSONArray tools) {
public void setTools(Object tools) {
this.tools = tools;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@

package org.wso2.carbon.apimgt.api.model;

/**
* Details related to Published API invocation response
*/
public class APIChatExecutionResponse {
private Integer code = null;
private String path = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
package org.wso2.carbon.apimgt.api.model;

/**
* Details related to API Chat test execution
* Details related to status update on API invocation back to the API Chat service
*/
public class APIChatTestExecutionInfo {
private APIChatExecutionResponse response = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@

package org.wso2.carbon.apimgt.api.model;

import org.json.simple.JSONObject;

/**
* Details related to API Chat test initialization
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -505,14 +505,25 @@ public final class APIConstants {
// Constants related to AI features: API chat and Marketplace Assistant
public static class AI {

public static final String API_CHAT = "APIChat.";
public static final String API_CHAT_ENABLED = API_CHAT + "Enabled";
public static final String API_CHAT_AUTH_TOKEN = API_CHAT + "AuthToken";
public static final String API_CHAT_ENDPOINT = API_CHAT + "Endpoint";
public static final String API_CHAT_PREPARE_RESOURCE = "/prepare";
public static final String API_CHAT_EXECUTE_RESOURCE = "/chat";
public static final String API_CHAT = "APIChat";
public static final String API_CHAT_ENABLED = "Enabled";
public static final String API_CHAT_AUTH_TOKEN = "AuthToken";
public static final String API_CHAT_ENDPOINT = "Endpoint";
public static final String RESOURCES = "Resources";
public static final String API_CHAT_PREPARE_RESOURCE = "PrepareResource";
public static final String API_CHAT_EXECUTE_RESOURCE = "ExecuteResource";
public static final String API_CHAT_ACTION_PREPARE = "PREPARE";
public static final String API_CHAT_ACTION_EXECUTE = "EXECUTE";
public static final String API_CHAT_REQUEST_ID = "apiChatRequestId";

public static final String MARKETPLACE_ASSISTANT = "MarketplaceAssistant";
public static final String MARKETPLACE_ASSISTANT_ENABLED = "Enabled";
public static final String MARKETPLACE_ASSISTANT_AUTH_TOKEN = "AuthToken";
public static final String MARKETPLACE_ASSISTANT_ENDPOINT = "Endpoint";
public static final String MARKETPLACE_ASSISTANT_CHAT_RESOURCE = "ChatResource";
public static final String MARKETPLACE_ASSISTANT_PUBLISH_API_RESOURCE = "ApiPublishResource";
public static final String MARKETPLACE_ASSISTANT_DELETE_API_RESOURCE = "ApiDeleteResource";
public static final String MARKETPLACE_ASSISTANT_API_COUNT_RESOURCE = "ApiCountResource";

private AI() {

Expand Down Expand Up @@ -549,17 +560,6 @@ private AI() {
public static final String FIRST_NAME = DEFAULT_CARBON_DIALECT + "/givenname";
public static final String LAST_NAME = DEFAULT_CARBON_DIALECT + "/lastname";

// constants for marketplace assistant
public static final String MARKETPLACE_ASSISTANT = "MarketplaceAssistant";
public static final String MARKETPLACE_ASSISTANT_ENABLED = "Enabled";
public static final String MARKETPLACE_ASSISTANT_AUTH_TOKEN = "AuthToken";
public static final String MARKETPLACE_ASSISTANT_ENDPOINT = "Endpoint";
public static final String MARKETPLACE_ASSISTANT_CHAT_RESOURCE = "ChatResource";
public static final String MARKETPLACE_ASSISTANT_PUBLISH_API_RESOURCE = "ApiPublishResource";
public static final String MARKETPLACE_ASSISTANT_DELETE_API_RESOURCE = "ApiDeleteResource";
public static final String MARKETPLACE_ASSISTANT_API_COUNT_RESOURCE = "ApiCountResource";


//Overview constants for CORS configuration
public static final String API_OVERVIEW_CORS_CONFIGURATION = "overview_corsConfiguration";
//Registry lifecycle related info
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@

package org.wso2.carbon.apimgt.impl;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.apache.axis2.util.JavaUtils;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
Expand All @@ -31,8 +35,8 @@
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import org.wso2.carbon.CarbonConstants;
import org.wso2.carbon.apimgt.api.APIConsumer;
import org.wso2.carbon.apimgt.api.APIAdmin;
import org.wso2.carbon.apimgt.api.APIConsumer;
import org.wso2.carbon.apimgt.api.APIDefinition;
import org.wso2.carbon.apimgt.api.APIManagementException;
import org.wso2.carbon.apimgt.api.APIMgtAuthorizationFailedException;
Expand Down Expand Up @@ -82,6 +86,7 @@
import org.wso2.carbon.apimgt.api.model.policy.PolicyConstants;
import org.wso2.carbon.apimgt.api.model.webhooks.Subscription;
import org.wso2.carbon.apimgt.api.model.webhooks.Topic;
import org.wso2.carbon.apimgt.impl.dto.ai.ApiChatConfigurationDTO;
import org.wso2.carbon.apimgt.impl.caching.CacheProvider;
import org.wso2.carbon.apimgt.impl.dao.ApiMgtDAO;
import org.wso2.carbon.apimgt.impl.definitions.OASParserUtil;
Expand Down Expand Up @@ -3317,20 +3322,32 @@ public String getOpenAPIDefinition(String apiId, String organization) throws API

@Override
public String invokeApiChatExecute(String apiChatRequestId, String requestPayload) throws APIManagementException {
return APIUtil.invokeAIService(APIConstants.AI.API_CHAT_ENDPOINT,
APIConstants.AI.API_CHAT_AUTH_TOKEN, APIConstants.AI.API_CHAT_EXECUTE_RESOURCE, requestPayload,
ApiChatConfigurationDTO configDto = ServiceReferenceHolder.
getInstance().getAPIManagerConfigurationService().getAPIManagerConfiguration().getApiChatConfigurationDto();
return APIUtil.invokeAIService(configDto.getEndpoint(),
configDto.getAccessToken(), configDto.getExecuteResource(), requestPayload,
apiChatRequestId);
}

@Override
public String invokeApiChatPrepare(String apiId, String apiChatRequestId, String organization)
throws APIManagementException {
String swaggerDefinition = getOpenAPIDefinition(apiId, organization);
String payload = "{\"openapi\": " + swaggerDefinition + "}";
String prepareResponse = APIUtil.invokeAIService(APIConstants.AI.API_CHAT_ENDPOINT,
APIConstants.AI.API_CHAT_AUTH_TOKEN, APIConstants.AI.API_CHAT_PREPARE_RESOURCE, payload,
apiChatRequestId);
return prepareResponse;
try {
// Generate the payload for prepare call
ObjectMapper objectMapper = new ObjectMapper();
JsonNode openAPIDefinitionJsonNode = objectMapper.readTree(getOpenAPIDefinition(apiId, organization));
ObjectNode payload = objectMapper.createObjectNode();
payload.set("openapi", openAPIDefinitionJsonNode);

ApiChatConfigurationDTO configDto = ServiceReferenceHolder.getInstance().getAPIManagerConfigurationService()
.getAPIManagerConfiguration().getApiChatConfigurationDto();
return APIUtil.invokeAIService(configDto.getEndpoint(), configDto.getAccessToken(),
configDto.getPrepareResource(), payload.toString(), apiChatRequestId);
} catch (JsonProcessingException e) {
String error = "Error while parsing OpenAPI definition to JSON";
log.error(error, e);
throw new APIManagementException(error, e);
}
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@
import org.wso2.carbon.apimgt.api.model.Environment;
import org.wso2.carbon.apimgt.api.model.VHost;
import org.wso2.carbon.apimgt.common.gateway.configdto.HttpClientConfigurationDTO;
import org.wso2.carbon.apimgt.impl.ai.MarketplaceAssistantConfigurationDto;
import org.wso2.carbon.apimgt.impl.dto.ai.ApiChatConfigurationDTO;
import org.wso2.carbon.apimgt.impl.dto.ai.MarketplaceAssistantConfigurationDTO;
import org.wso2.carbon.apimgt.common.gateway.dto.ClaimMappingDto;
import org.wso2.carbon.apimgt.common.gateway.dto.JWKSConfigurationDTO;
import org.wso2.carbon.apimgt.common.gateway.dto.TokenIssuerDto;
Expand All @@ -49,7 +50,6 @@
import org.wso2.carbon.apimgt.impl.monetization.MonetizationConfigurationDto;
import org.wso2.carbon.apimgt.impl.recommendationmgt.RecommendationEnvironment;
import org.wso2.carbon.apimgt.impl.utils.APIUtil;
import org.wso2.carbon.utils.CarbonUtils;
import org.wso2.securevault.SecretResolver;
import org.wso2.securevault.SecretResolverFactory;
import org.wso2.securevault.commons.MiscellaneousUtil;
Expand Down Expand Up @@ -117,7 +117,8 @@ public class APIManagerConfiguration {
private boolean initialized;
private ThrottleProperties throttleProperties = new ThrottleProperties();
private ExtendedJWTConfigurationDto jwtConfigurationDto = new ExtendedJWTConfigurationDto();
private static MarketplaceAssistantConfigurationDto marketplaceAssistantConfigurationDto = new MarketplaceAssistantConfigurationDto();
private static MarketplaceAssistantConfigurationDTO marketplaceAssistantConfigurationDto = new MarketplaceAssistantConfigurationDTO();
private static ApiChatConfigurationDTO apiChatConfigurationDto = new ApiChatConfigurationDTO();

private WorkflowProperties workflowProperties = new WorkflowProperties();
private Map<String, Environment> apiGatewayEnvironments = new LinkedHashMap<String, Environment>();
Expand Down Expand Up @@ -163,11 +164,16 @@ public static boolean isTokenRevocationEnabled() {
return !tokenRevocationClassName.isEmpty();
}

public MarketplaceAssistantConfigurationDto getMarketplaceAssistantConfigurationDto() {
public MarketplaceAssistantConfigurationDTO getMarketplaceAssistantConfigurationDto() {

return marketplaceAssistantConfigurationDto;
}

public ApiChatConfigurationDTO getApiChatConfigurationDto() {

return apiChatConfigurationDto;
}

private Set<APIStore> externalAPIStores = new HashSet<APIStore>();
private EventHubConfigurationDto eventHubConfigurationDto;
private MonetizationConfigurationDto monetizationConfigurationDto = new MonetizationConfigurationDto();
Expand Down Expand Up @@ -632,8 +638,10 @@ private void readChildElements(OMElement serverConfig,
jsonObject.put(APIConstants.CustomPropertyAttributes.REQUIRED, isRequired);
customProperties.add(jsonObject);
}
} else if (APIConstants.MARKETPLACE_ASSISTANT.equals(localName)) {
} else if (APIConstants.AI.MARKETPLACE_ASSISTANT.equals(localName)) {
setMarketplaceAssistantConfiguration(element);
} else if (APIConstants.AI.API_CHAT.equals(localName)) {
setApiChatConfiguration(element);
}
readChildElements(element, nameStack);
nameStack.pop();
Expand Down Expand Up @@ -2339,43 +2347,89 @@ public void setHttpClientConfiguration(HttpClientConfigurationDTO httpClientConf

public void setMarketplaceAssistantConfiguration(OMElement omElement){
OMElement marketplaceAssistantEnableElement =
omElement.getFirstChildWithName(new QName(APIConstants.MARKETPLACE_ASSISTANT_ENABLED));
omElement.getFirstChildWithName(new QName(APIConstants.AI.MARKETPLACE_ASSISTANT_ENABLED));
if (marketplaceAssistantEnableElement != null) {
marketplaceAssistantConfigurationDto.setEnabled(Boolean.parseBoolean(marketplaceAssistantEnableElement.getText()));
}
if (marketplaceAssistantConfigurationDto.isEnabled()) {
OMElement marketplaceAssistantEndpoint =
omElement.getFirstChildWithName(new QName(APIConstants.MARKETPLACE_ASSISTANT_ENDPOINT));
omElement.getFirstChildWithName(new QName(APIConstants.AI.MARKETPLACE_ASSISTANT_ENDPOINT));
if (marketplaceAssistantEndpoint != null) {
marketplaceAssistantConfigurationDto.setEndpoint(marketplaceAssistantEndpoint.getText());
}
OMElement marketplaceAssistantToken =
omElement.getFirstChildWithName(new QName(APIConstants.MARKETPLACE_ASSISTANT_AUTH_TOKEN));
omElement.getFirstChildWithName(new QName(APIConstants.AI.MARKETPLACE_ASSISTANT_AUTH_TOKEN));

if (marketplaceAssistantToken != null) {
String AccessToken = MiscellaneousUtil.resolve(marketplaceAssistantToken, secretResolver);
marketplaceAssistantConfigurationDto.setAccessToken(AccessToken);
if (!AccessToken.isEmpty()){
marketplaceAssistantConfigurationDto.setAuthTokenProvided(true);
}
}

OMElement resources =
omElement.getFirstChildWithName(new QName(APIConstants.AI.RESOURCES));

OMElement marketplaceAssistantApiCountResource =
omElement.getFirstChildWithName(new QName(APIConstants.MARKETPLACE_ASSISTANT_API_COUNT_RESOURCE));
resources.getFirstChildWithName(new QName(APIConstants.AI.MARKETPLACE_ASSISTANT_API_COUNT_RESOURCE));
if (marketplaceAssistantApiCountResource != null) {
marketplaceAssistantConfigurationDto.setApiCountResource(marketplaceAssistantApiCountResource.getText());
}
OMElement marketplaceAssistantApiDeleteResource =
omElement.getFirstChildWithName(new QName(APIConstants.MARKETPLACE_ASSISTANT_DELETE_API_RESOURCE));
resources.getFirstChildWithName(new QName(APIConstants.AI.MARKETPLACE_ASSISTANT_DELETE_API_RESOURCE));
if (marketplaceAssistantApiDeleteResource != null) {
marketplaceAssistantConfigurationDto.setApiDeleteResource(marketplaceAssistantApiDeleteResource.getText());
}
OMElement marketplaceAssistantApiPublishResource =
omElement.getFirstChildWithName(new QName(APIConstants.MARKETPLACE_ASSISTANT_PUBLISH_API_RESOURCE));
resources.getFirstChildWithName(new QName(APIConstants.AI.MARKETPLACE_ASSISTANT_PUBLISH_API_RESOURCE));
if (marketplaceAssistantApiPublishResource != null) {
marketplaceAssistantConfigurationDto.setApiPublishResource(marketplaceAssistantApiPublishResource.getText());
}
OMElement marketplaceAssistantChatResource =
omElement.getFirstChildWithName(new QName(APIConstants.MARKETPLACE_ASSISTANT_CHAT_RESOURCE));
resources.getFirstChildWithName(new QName(APIConstants.AI.MARKETPLACE_ASSISTANT_CHAT_RESOURCE));
if (marketplaceAssistantChatResource != null) {
marketplaceAssistantConfigurationDto.setChatResource(marketplaceAssistantChatResource.getText());
}
}
}

public void setApiChatConfiguration(OMElement omElement){
OMElement apiChatEnableElement =
omElement.getFirstChildWithName(new QName(APIConstants.AI.API_CHAT_ENABLED));
if (apiChatEnableElement != null) {
apiChatConfigurationDto.setEnabled(Boolean.parseBoolean(apiChatEnableElement.getText()));
}
if (apiChatConfigurationDto.isEnabled()) {
OMElement apiChatEndpoint =
omElement.getFirstChildWithName(new QName(APIConstants.AI.API_CHAT_ENDPOINT));
if (apiChatEndpoint != null) {
apiChatConfigurationDto.setEndpoint(apiChatEndpoint.getText());
}
OMElement apiChatToken =
omElement.getFirstChildWithName(new QName(APIConstants.AI.API_CHAT_AUTH_TOKEN));

if (apiChatToken != null) {
String AccessToken = MiscellaneousUtil.resolve(apiChatToken, secretResolver);
apiChatConfigurationDto.setAccessToken(AccessToken);
if (!AccessToken.isEmpty()){
apiChatConfigurationDto.setAuthTokenProvided(true);
}
}

OMElement resources =
omElement.getFirstChildWithName(new QName(APIConstants.AI.RESOURCES));

OMElement apiChatPrepareResource =
resources.getFirstChildWithName(new QName(APIConstants.AI.API_CHAT_PREPARE_RESOURCE));
if (apiChatPrepareResource != null) {
apiChatConfigurationDto.setPrepareResource(apiChatPrepareResource.getText());
}
OMElement apiChatExecuteResource =
resources.getFirstChildWithName(new QName(APIConstants.AI.API_CHAT_EXECUTE_RESOURCE));
if (apiChatExecuteResource != null) {
apiChatConfigurationDto.setExecuteResource(apiChatExecuteResource.getText());
}
}
}
}
Loading

0 comments on commit 0a28f09

Please sign in to comment.