Skip to content

Commit

Permalink
add summarization
Browse files Browse the repository at this point in the history
  • Loading branch information
vmleon committed Jun 17, 2024
1 parent f5b7bcc commit 15812e9
Show file tree
Hide file tree
Showing 28 changed files with 532 additions and 159 deletions.
52 changes: 45 additions & 7 deletions LOCAL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# Run Local

## Web
## Run components

### Run web

Run locally in a terminal with:

Expand All @@ -12,23 +14,59 @@ cd web
npm run dev
```

## Backend
### Run Backend

Run locally on another terminal with:

```bash
cd backend
```

Edit `/backend/src/main/resources/application.yaml` to have the correct values.
Copy `/backend/src/main/resources/application.yaml` to `/backend/src/main/resources/application-local.yaml` and modify the values required.

It should look like this:

```yaml
spring:
main:
banner-mode: "off"
profiles:
active: production
datasource:
driver-class-name: oracle.jdbc.OracleDriver
url: jdbc:oracle:thin:@ADB_SERVICE_NAME_GOES_HERE_high?TNS_ADMIN=/PATH/TO/WALLET/UNZIPPED/IN/TERRAFORM/GENERATED
username: ADMIN
password: "ADB_PASSWORD_GOES_HERE"
type: oracle.ucp.jdbc.PoolDataSource
oracleucp:
sql-for-validate-connection: SELECT * FROM dual
connection-pool-name: connectionPoolName1
initial-pool-size: 5
min-pool-size: 5
max-pool-size: 10
jpa:
hibernate:
use-new-id-generator-mappings: false
ddl-auto: update
oracle:
jdbc:
fanEnabled: true

genai:
endpoint: "https://inference.generativeai.us-chicago-1.oci.oraclecloud.com"
region: "us-chicago-1"
compartment_id: "GENAI_COMPARTMENT_OCID_GOES_HERE"
chat_model_id: "GEN_AI_CHAT_MODEL_OCID_GOES_HERE"
summarization_model_id: "GEN_AI_SUMMARIZATION_MODEL_OCID_GOES_HERE"
```
Run the Spring Boot backend application in local profile:
```bash
./gradlew bootRun
./gradlew bootRun -Plocal
```

## Build for distribution

## Build artifacts
## Other tasks

### Build Java Application:

Expand Down
1 change: 1 addition & 0 deletions backend/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ dependencies {
implementation 'com.oracle.database.security:oraclepki:21.8.0.0'
implementation 'com.oracle.database.security:osdt_cert:21.8.0.0'
implementation 'com.oracle.database.security:osdt_core:21.8.0.0'
implementation 'org.apache.pdfbox:pdfbox:3.0.2' exclude(group: 'commons-logging', module: 'commons-logging')
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@

@ResponseStatus(code = HttpStatus.BAD_REQUEST, reason = "Invalid request params")
public class InvalidPromptRequest extends RuntimeException {


}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package dev.victormartin.oci.genai.backend.backend;
package dev.victormartin.oci.genai.backend.backend.config;

import com.oracle.bmc.ClientConfiguration;
import com.oracle.bmc.retrier.RetryConfiguration;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
package dev.victormartin.oci.genai.backend.backend;
package dev.victormartin.oci.genai.backend.backend.config;

import com.oracle.bmc.ClientConfiguration;
import com.oracle.bmc.ConfigFileReader;
import com.oracle.bmc.Region;
import com.oracle.bmc.auth.AuthenticationDetailsProvider;
import com.oracle.bmc.auth.ConfigFileAuthenticationDetailsProvider;
import com.oracle.bmc.auth.InstancePrincipalsAuthenticationDetailsProvider;
import com.oracle.bmc.auth.okeworkloadidentity.OkeWorkloadIdentityAuthenticationDetailsProvider;
import com.oracle.bmc.generativeai.GenerativeAiClient;
import jakarta.annotation.PostConstruct;
Expand Down Expand Up @@ -39,8 +38,11 @@ public class GenerativeAiClientConfig {
@Value("${genai.config.profile}")
private String CONFIG_PROFILE;

@Value("${genai.model_id}")
private String modelId;
@Value("${genai.chat_model_id}")
private String chatModelId;

@Value("${genai.summarization_model_id}")
private String summarizationModelId;

private Region region;

Expand All @@ -62,12 +64,11 @@ GenerativeAiClient genAiClient() throws IOException {
}

GenerativeAiClient instancePrincipalConfig() throws IOException {
final OkeWorkloadIdentityAuthenticationDetailsProvider okeProvider =
new OkeWorkloadIdentityAuthenticationDetailsProvider
.OkeWorkloadIdentityAuthenticationDetailsProviderBuilder()
.build();
// final InstancePrincipalsAuthenticationDetailsProvider provider =
// new InstancePrincipalsAuthenticationDetailsProvider.InstancePrincipalsAuthenticationDetailsProviderBuilder().build();
final OkeWorkloadIdentityAuthenticationDetailsProvider okeProvider = new OkeWorkloadIdentityAuthenticationDetailsProvider.OkeWorkloadIdentityAuthenticationDetailsProviderBuilder()
.build();
// final InstancePrincipalsAuthenticationDetailsProvider provider =
// new
// InstancePrincipalsAuthenticationDetailsProvider.InstancePrincipalsAuthenticationDetailsProviderBuilder().build();

GenerativeAiClient generativeAiClient = new GenerativeAiClient(okeProvider, clientConfiguration);
generativeAiClient.setRegion(okeProvider.getRegion());
Expand All @@ -76,9 +77,11 @@ GenerativeAiClient instancePrincipalConfig() throws IOException {
}

GenerativeAiClient localConfig() throws IOException {
// Configuring the AuthenticationDetailsProvider. It's assuming there is a default OCI config file
// "~/.oci/config", and a profile in that config with the name defined in CONFIG_PROFILE variable.
final ConfigFileReader.ConfigFile configFile = ConfigFileReader.parse(CONFIG_LOCATION, CONFIG_PROFILE);
// Configuring the AuthenticationDetailsProvider. It's assuming there is a
// default OCI config file
// "~/.oci/config", and a profile in that config with the name defined in
// CONFIG_PROFILE variable.
final ConfigFileReader.ConfigFile configFile = ConfigFileReader.parse(CONFIG_LOCATION, CONFIG_PROFILE);
final AuthenticationDetailsProvider provider = new ConfigFileAuthenticationDetailsProvider(configFile);

GenerativeAiClient generativeAiClient = new GenerativeAiClient(provider,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package dev.victormartin.oci.genai.backend.backend;
package dev.victormartin.oci.genai.backend.backend.config;

import com.oracle.bmc.ClientConfiguration;
import com.oracle.bmc.ConfigFileReader;
Expand Down Expand Up @@ -38,8 +38,11 @@ public class GenerativeAiInferenceClientConfig {
@Value("${genai.config.profile}")
private String CONFIG_PROFILE;

@Value("${genai.model_id}")
private String modelId;
@Value("${genai.chat_model_id}")
private String modelChatId;

@Value("${genai.summarization_model_id}")
private String modelSummarizationId;

private Region region;

Expand All @@ -62,8 +65,8 @@ GenerativeAiInferenceClient genAiInferenceClient() throws IOException {
}

GenerativeAiInferenceClient instancePrincipalConfig() throws IOException {
final InstancePrincipalsAuthenticationDetailsProvider provider =
new InstancePrincipalsAuthenticationDetailsProvider.InstancePrincipalsAuthenticationDetailsProviderBuilder().build();
final InstancePrincipalsAuthenticationDetailsProvider provider = new InstancePrincipalsAuthenticationDetailsProvider.InstancePrincipalsAuthenticationDetailsProviderBuilder()
.build();

GenerativeAiInferenceClient generativeAiInferenceClient = new GenerativeAiInferenceClient(provider,
clientConfiguration);
Expand All @@ -73,12 +76,14 @@ GenerativeAiInferenceClient instancePrincipalConfig() throws IOException {
}

GenerativeAiInferenceClient localConfig() throws IOException {
// Configuring the AuthenticationDetailsProvider. It's assuming there is a default OCI config file
// "~/.oci/config", and a profile in that config with the name defined in CONFIG_PROFILE variable.
final ConfigFileReader.ConfigFile configFile = ConfigFileReader.parse(CONFIG_LOCATION, CONFIG_PROFILE);
// Configuring the AuthenticationDetailsProvider. It's assuming there is a
// default OCI config file
// "~/.oci/config", and a profile in that config with the name defined in
// CONFIG_PROFILE variable.
final ConfigFileReader.ConfigFile configFile = ConfigFileReader.parse(CONFIG_LOCATION, CONFIG_PROFILE);
final AuthenticationDetailsProvider provider = new ConfigFileAuthenticationDetailsProvider(configFile);

GenerativeAiInferenceClient generativeAiInferenceClient = new GenerativeAiInferenceClient(provider,
GenerativeAiInferenceClient generativeAiInferenceClient = new GenerativeAiInferenceClient(provider,
clientConfiguration);
generativeAiInferenceClient.setEndpoint(ENDPOINT);
generativeAiInferenceClient.setRegion(region);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package dev.victormartin.oci.genai.backend.backend;
package dev.victormartin.oci.genai.backend.backend.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
package dev.victormartin.oci.genai.backend.backend;
package dev.victormartin.oci.genai.backend.backend.controller;

import com.oracle.bmc.ClientConfiguration;
import com.oracle.bmc.generativeai.GenerativeAiClient;
import com.oracle.bmc.generativeai.model.ModelCapability;
import com.oracle.bmc.generativeai.requests.ListModelsRequest;
import com.oracle.bmc.generativeai.responses.ListModelsResponse;
import dev.victormartin.oci.genai.backend.backend.dao.GenAiModel;
import org.bouncycastle.util.Objects;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package dev.victormartin.oci.genai.backend.backend.controller;


import dev.victormartin.oci.genai.backend.backend.service.OCIGenAIService;
import dev.victormartin.oci.genai.backend.backend.service.PDFConvertorService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MaxUploadSizeExceededException;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;

@RestController
public class PDFConvertorController {
Logger log = LoggerFactory.getLogger(PDFConvertorController.class);

@Value("${storage.path}")
String storagePath;

@Value("${genai.summarization_model_id}")
String summarizationModelId;

@Autowired
OCIGenAIService ociGenAIService;

@Autowired
PDFConvertorService pdfConvertorService;

@Autowired
SummaryController summaryController;

@PostMapping("/api/upload")
public String fileUploading(@RequestParam("file") MultipartFile multipartFile) {
String filename = StringUtils.cleanPath(multipartFile.getOriginalFilename());
log.info("File uploaded {} {} bytes ({})", filename, multipartFile.getSize(), multipartFile.getContentType());
try {
if (filename.contains("..")) {
throw new Exception("Filename contains invalid path sequence");
}
if (multipartFile.getBytes().length > (1024 * 1024)) {
throw new Exception("File size exceeds maximum limit");
}
String fileDestinationPath = StringUtils.cleanPath(storagePath);
File file = new File(fileDestinationPath + File.separator + filename);
multipartFile.transferTo(file);
log.info("File destination path: {}", file.getAbsolutePath());
String convertedText = pdfConvertorService.convert(file.getAbsolutePath());
String summaryText = ociGenAIService.summaryText(convertedText, summarizationModelId);
log.info("Summary text: {}(...)", summaryText.substring(0, 40));
summaryController.handleSummary(summaryText);
return summaryText;
} catch (MaxUploadSizeExceededException maxUploadSizeExceededException) {
log.error(maxUploadSizeExceededException.getMessage());
throw new RuntimeException(maxUploadSizeExceededException);
} catch (Exception e) {
log.error(e.getMessage());
throw new RuntimeException(e);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package dev.victormartin.oci.genai.backend.backend;
package dev.victormartin.oci.genai.backend.backend.controller;

import com.oracle.bmc.model.BmcException;
import dev.victormartin.oci.genai.backend.backend.InvalidPromptRequest;
import dev.victormartin.oci.genai.backend.backend.service.OCIGenAIService;
import dev.victormartin.oci.genai.backend.backend.dao.Answer;
import dev.victormartin.oci.genai.backend.backend.dao.Prompt;
import dev.victormartin.oci.genai.backend.backend.data.Interaction;
Expand All @@ -21,14 +23,17 @@
public class PromptController {
Logger logger = LoggerFactory.getLogger(PromptController.class);

@Value("${genai.model_id}")
private String hardcodedModelId;
@Value("${genai.chat_model_id}")
private String hardcodedChatModelId;

@Value("${genai.summarization_model_id}")
private String hardcodedSummarizationModelId;

@Autowired
private final InteractionRepository interactionRepository;

@Autowired
OCIGenAIService genAI;
OCIGenAIService genAI;

public PromptController(InteractionRepository interactionRepository, OCIGenAIService genAI) {
this.interactionRepository = interactionRepository;
Expand All @@ -40,17 +45,21 @@ public PromptController(InteractionRepository interactionRepository, OCIGenAISer
public Answer handlePrompt(Prompt prompt) {
String promptEscaped = HtmlUtils.htmlEscape(prompt.content());
logger.info("Prompt " + promptEscaped + " received, on model " + prompt.modelId() + " but using hardcoded one" +
" " + hardcodedModelId);
" " + hardcodedChatModelId);
Interaction interaction = new Interaction();
interaction.setConversationId(prompt.conversationId());
interaction.setDatetimeRequest(new Date());
interaction.setModelId(hardcodedModelId);
interaction.setModelId(hardcodedChatModelId);
interaction.setRequest(promptEscaped);
Interaction saved = interactionRepository.save(interaction);
try {
if (prompt.content() == null || prompt.content().length()< 1) { throw new InvalidPromptRequest(); }
// if (prompt.modelId() == null || !prompt.modelId().startsWith("ocid1.generativeaimodel.")) { throw new InvalidPromptRequest(); }
String responseFromGenAI = genAI.request(promptEscaped, hardcodedModelId);
if (prompt.content() == null || prompt.content().length() < 1) {
throw new InvalidPromptRequest();
}
// if (prompt.modelId() == null ||
// !prompt.modelId().startsWith("ocid1.generativeaimodel.")) { throw new
// InvalidPromptRequest(); }
String responseFromGenAI = genAI.request(promptEscaped, hardcodedChatModelId);
saved.setDatetimeResponse(new Date());
saved.setResponse(responseFromGenAI);
interactionRepository.save(saved);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package dev.victormartin.oci.genai.backend.backend.controller;

import com.oracle.bmc.model.BmcException;
import dev.victormartin.oci.genai.backend.backend.InvalidPromptRequest;
import dev.victormartin.oci.genai.backend.backend.dao.Answer;
import dev.victormartin.oci.genai.backend.backend.dao.Prompt;
import dev.victormartin.oci.genai.backend.backend.data.Interaction;
import dev.victormartin.oci.genai.backend.backend.data.InteractionRepository;
import dev.victormartin.oci.genai.backend.backend.service.OCIGenAIService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.simp.annotation.SendToUser;
import org.springframework.messaging.simp.annotation.SubscribeMapping;
import org.springframework.stereotype.Controller;
import org.springframework.web.util.HtmlUtils;

import java.util.Date;

@Controller
public class SummaryController {
Logger logger = LoggerFactory.getLogger(SummaryController.class);

@SendToUser("/queue/summary")
public Answer handleSummary(String summary) {
logger.info("handleSummary");
return new Answer(summary , "");
}

}
Loading

0 comments on commit 15812e9

Please sign in to comment.