From 3c5306825d39bf0a10ed8d7f01ea8d10fffc8326 Mon Sep 17 00:00:00 2001 From: Victor Martin Date: Fri, 2 Aug 2024 12:27:03 +0200 Subject: [PATCH] add summary from text, add interaction to database for all scenarios, improve code and bump versions --- backend/build.gradle | 2 +- .../controller/PDFConvertorController.java | 30 ++++- .../backend/controller/PromptController.java | 2 + .../backend/controller/SummaryController.java | 77 ++++++++++++ .../backend/backend/dao/SummaryRequest.java | 4 + .../backend/backend/data/Interaction.java | 15 ++- .../backend/backend/data/InteractionType.java | 5 + deploy/terraform/.terraform.lock.hcl | 110 +++++++++--------- web/package.json | 4 +- web/src/App.jsx | 25 ++-- web/src/Chat.jsx | 9 +- web/src/IdentityContext.jsx | 5 + web/src/Routing.jsx | 5 + web/src/Summary.jsx | 17 ++- web/src/SummaryText.jsx | 77 ++++++++++++ 15 files changed, 304 insertions(+), 83 deletions(-) create mode 100644 backend/src/main/java/dev/victormartin/oci/genai/backend/backend/controller/SummaryController.java create mode 100644 backend/src/main/java/dev/victormartin/oci/genai/backend/backend/dao/SummaryRequest.java create mode 100644 backend/src/main/java/dev/victormartin/oci/genai/backend/backend/data/InteractionType.java create mode 100644 web/src/IdentityContext.jsx create mode 100644 web/src/SummaryText.jsx diff --git a/backend/build.gradle b/backend/build.gradle index 7be7e3b7..4e95793a 100644 --- a/backend/build.gradle +++ b/backend/build.gradle @@ -5,7 +5,7 @@ plugins { } group = 'dev.victormartin.oci.genai.backend' -version = '0.0.5' +version = '0.0.6' java { sourceCompatibility = '17' diff --git a/backend/src/main/java/dev/victormartin/oci/genai/backend/backend/controller/PDFConvertorController.java b/backend/src/main/java/dev/victormartin/oci/genai/backend/backend/controller/PDFConvertorController.java index 86d480f8..153b603d 100644 --- a/backend/src/main/java/dev/victormartin/oci/genai/backend/backend/controller/PDFConvertorController.java +++ b/backend/src/main/java/dev/victormartin/oci/genai/backend/backend/controller/PDFConvertorController.java @@ -3,6 +3,9 @@ import com.oracle.bmc.model.BmcException; import dev.victormartin.oci.genai.backend.backend.dao.Answer; +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.data.InteractionType; import dev.victormartin.oci.genai.backend.backend.service.OCIGenAIService; import dev.victormartin.oci.genai.backend.backend.service.PDFConvertorService; import org.slf4j.Logger; @@ -11,12 +14,15 @@ 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.RequestHeader; 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 org.springframework.web.util.HtmlUtils; import java.io.File; +import java.util.Date; @RestController public class PDFConvertorController { @@ -34,8 +40,13 @@ public class PDFConvertorController { @Autowired PDFConvertorService pdfConvertorService; + @Autowired + private InteractionRepository interactionRepository; + @PostMapping("/api/upload") - public Answer fileUploading(@RequestParam("file") MultipartFile multipartFile) { + public Answer fileUploading(@RequestParam("file") MultipartFile multipartFile, + @RequestHeader("conversationID") String conversationId, + @RequestHeader("modelId") String modelId) { String filename = StringUtils.cleanPath(multipartFile.getOriginalFilename()); log.info("File uploaded {} {} bytes ({})", filename, multipartFile.getSize(), multipartFile.getContentType()); try { @@ -50,7 +61,18 @@ public Answer fileUploading(@RequestParam("file") MultipartFile multipartFile) { multipartFile.transferTo(file); log.info("File destination path: {}", file.getAbsolutePath()); String convertedText = pdfConvertorService.convert(file.getAbsolutePath()); - String summaryText = ociGenAIService.summaryText(convertedText, summarizationModelId); + String textEscaped = HtmlUtils.htmlEscape(convertedText); + Interaction interaction = new Interaction(); + interaction.setType(InteractionType.SUMMARY_FILE); + interaction.setConversationId(conversationId); + interaction.setDatetimeRequest(new Date()); + interaction.setModelId(summarizationModelId); + interaction.setRequest(textEscaped); + Interaction saved = interactionRepository.save(interaction); + String summaryText = ociGenAIService.summaryText(textEscaped, summarizationModelId); + saved.setDatetimeResponse(new Date()); + saved.setResponse(summaryText); + interactionRepository.save(saved); log.info("Summary text: {}(...)", summaryText.substring(0, 40)); Answer answer = new Answer(summaryText, ""); return answer; @@ -58,11 +80,7 @@ public Answer fileUploading(@RequestParam("file") MultipartFile multipartFile) { log.error(maxUploadSizeExceededException.getMessage()); throw new RuntimeException(maxUploadSizeExceededException); } catch (BmcException exception) { - log.error("Message: {}", exception.getMessage()); - log.error("Original Message: {}", exception.getOriginalMessage()); log.error("Unmodified Message: {}", exception.getUnmodifiedMessage()); - log.error("Service Details: {}", exception.getServiceDetails()); - log.error("Status Code: {}", exception.getStatusCode()); String unmodifiedMessage = exception.getUnmodifiedMessage(); int statusCode = exception.getStatusCode(); String errorMessage = statusCode + " " + unmodifiedMessage; diff --git a/backend/src/main/java/dev/victormartin/oci/genai/backend/backend/controller/PromptController.java b/backend/src/main/java/dev/victormartin/oci/genai/backend/backend/controller/PromptController.java index 6f6fb90a..94d2ecfe 100644 --- a/backend/src/main/java/dev/victormartin/oci/genai/backend/backend/controller/PromptController.java +++ b/backend/src/main/java/dev/victormartin/oci/genai/backend/backend/controller/PromptController.java @@ -2,6 +2,7 @@ import com.oracle.bmc.model.BmcException; import dev.victormartin.oci.genai.backend.backend.InvalidPromptRequest; +import dev.victormartin.oci.genai.backend.backend.data.InteractionType; 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; @@ -44,6 +45,7 @@ public Answer handlePrompt(Prompt prompt) { logger.info("Prompt " + promptEscaped + " received, on model " + prompt.modelId() + " but using hardcoded one" + " " + hardcodedChatModelId); Interaction interaction = new Interaction(); + interaction.setType(InteractionType.CHAT); interaction.setConversationId(prompt.conversationId()); interaction.setDatetimeRequest(new Date()); interaction.setModelId(hardcodedChatModelId); diff --git a/backend/src/main/java/dev/victormartin/oci/genai/backend/backend/controller/SummaryController.java b/backend/src/main/java/dev/victormartin/oci/genai/backend/backend/controller/SummaryController.java new file mode 100644 index 00000000..40b6b98e --- /dev/null +++ b/backend/src/main/java/dev/victormartin/oci/genai/backend/backend/controller/SummaryController.java @@ -0,0 +1,77 @@ +package dev.victormartin.oci.genai.backend.backend.controller; + +import com.oracle.bmc.model.BmcException; +import dev.victormartin.oci.genai.backend.backend.dao.Answer; +import dev.victormartin.oci.genai.backend.backend.dao.SummaryRequest; +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.data.InteractionType; +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.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.util.HtmlUtils; + +import java.util.Date; + +@RestController +public class SummaryController { + Logger logger = LoggerFactory.getLogger(SummaryController.class); + + @Value("${genai.summarization_model_id}") + String summarizationModelId; + + @Autowired + OCIGenAIService ociGenAIService; + + @Autowired + private InteractionRepository interactionRepository; + + @PostMapping("/api/genai/summary") + public Answer postSummaryText(@RequestBody SummaryRequest summaryRequest, + @RequestHeader("conversationID") String conversationId, + @RequestHeader("modelId") String modelId) { + logger.info("postSummaryText()"); + String contentEscaped = HtmlUtils.htmlEscape(summaryRequest.content()); + logger.info("contentEscaped: {}...", contentEscaped.substring(0, 50)); + Interaction interaction = new Interaction(); + interaction.setType(InteractionType.SUMMARY_TEXT); + interaction.setConversationId(conversationId); + interaction.setDatetimeRequest(new Date()); + interaction.setModelId(summarizationModelId); + interaction.setRequest(contentEscaped); + Interaction saved = interactionRepository.save(interaction); + try { + String summaryText = ociGenAIService.summaryText(contentEscaped, summarizationModelId); + saved.setDatetimeResponse(new Date()); + saved.setResponse(summaryText); + interactionRepository.save(saved); + logger.info("summaryText: {}...", summaryText.substring(0, 50)); + Answer answer = new Answer(); + answer.setContent(summaryText); + answer.setErrorMessage(""); + return answer; + } catch (BmcException e) { + String unmodifiedMessage = e.getUnmodifiedMessage(); + int statusCode = e.getStatusCode(); + String errorMessage = statusCode + " " + unmodifiedMessage; + logger.error(errorMessage); + saved.setErrorMessage(errorMessage); + interactionRepository.save(saved); + Answer answer = new Answer("", errorMessage); + return answer; + } catch (Exception e) { + String errorMessage = e.getLocalizedMessage(); + logger.error(errorMessage); + saved.setErrorMessage(errorMessage); + interactionRepository.save(saved); + Answer answer = new Answer("", errorMessage); + return answer; + } + } +} diff --git a/backend/src/main/java/dev/victormartin/oci/genai/backend/backend/dao/SummaryRequest.java b/backend/src/main/java/dev/victormartin/oci/genai/backend/backend/dao/SummaryRequest.java new file mode 100644 index 00000000..588def2a --- /dev/null +++ b/backend/src/main/java/dev/victormartin/oci/genai/backend/backend/dao/SummaryRequest.java @@ -0,0 +1,4 @@ +package dev.victormartin.oci.genai.backend.backend.dao; + +public record SummaryRequest(String content) { +} diff --git a/backend/src/main/java/dev/victormartin/oci/genai/backend/backend/data/Interaction.java b/backend/src/main/java/dev/victormartin/oci/genai/backend/backend/data/Interaction.java index 0c1b915a..56480885 100644 --- a/backend/src/main/java/dev/victormartin/oci/genai/backend/backend/data/Interaction.java +++ b/backend/src/main/java/dev/victormartin/oci/genai/backend/backend/data/Interaction.java @@ -13,6 +13,9 @@ public class Interaction { String conversationId; + @Enumerated(EnumType.STRING) + InteractionType type; + @Temporal(TemporalType.DATE) Date datetimeRequest; @@ -41,12 +44,12 @@ public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Interaction that = (Interaction) o; - return Objects.equals(id, that.id) && Objects.equals(conversationId, that.conversationId) && Objects.equals(datetimeRequest, that.datetimeRequest) && Objects.equals(modelId, that.modelId) && Objects.equals(request, that.request) && Objects.equals(datetimeResponse, that.datetimeResponse) && Objects.equals(response, that.response) && Objects.equals(errorMessage, that.errorMessage); + return Objects.equals(id, that.id) && Objects.equals(conversationId, that.conversationId) && type == that.type && Objects.equals(datetimeRequest, that.datetimeRequest) && Objects.equals(modelId, that.modelId) && Objects.equals(request, that.request) && Objects.equals(datetimeResponse, that.datetimeResponse) && Objects.equals(response, that.response) && Objects.equals(errorMessage, that.errorMessage); } @Override public int hashCode() { - return Objects.hash(id, conversationId, datetimeRequest, modelId, request, datetimeResponse, response, errorMessage); + return Objects.hash(id, conversationId, type, datetimeRequest, modelId, request, datetimeResponse, response, errorMessage); } public Long getId() { @@ -61,6 +64,14 @@ public void setConversationId(String conversationId) { this.conversationId = conversationId; } + public InteractionType getType() { + return type; + } + + public void setType(InteractionType type) { + this.type = type; + } + public Date getDatetimeRequest() { return datetimeRequest; } diff --git a/backend/src/main/java/dev/victormartin/oci/genai/backend/backend/data/InteractionType.java b/backend/src/main/java/dev/victormartin/oci/genai/backend/backend/data/InteractionType.java new file mode 100644 index 00000000..1d47e02f --- /dev/null +++ b/backend/src/main/java/dev/victormartin/oci/genai/backend/backend/data/InteractionType.java @@ -0,0 +1,5 @@ +package dev.victormartin.oci.genai.backend.backend.data; + +public enum InteractionType { + CHAT, SUMMARY_FILE, SUMMARY_TEXT +} diff --git a/deploy/terraform/.terraform.lock.hcl b/deploy/terraform/.terraform.lock.hcl index f028cf39..8301e611 100644 --- a/deploy/terraform/.terraform.lock.hcl +++ b/deploy/terraform/.terraform.lock.hcl @@ -22,42 +22,42 @@ provider "registry.terraform.io/hashicorp/cloudinit" { } provider "registry.terraform.io/hashicorp/helm" { - version = "2.13.2" + version = "2.14.0" constraints = ">= 2.9.0" hashes = [ - "h1:KHLdE3Xb4XbLCWwCSArYcXulYyBJKTFizaIzBiYVJxQ=", - "zh:06c0663031ef5aa19e238fe50be5d3cbf5fb00548d2b26e779c607dfd2dc69a7", - "zh:1850b8f2e729553ba8b96d69dce035b814ce959c6805c25484f407c4e720c497", - "zh:1ec76814a99461cd79ee4c879ed455ab338a3cb9e63fbe9308f91b5515e72e42", - "zh:78546b2f0b2e9072370c017d8056a2ffda908c2e463d2792244e4be6562ab772", - "zh:9205eef438aa3d5e49505655b7c300f7cecfa30f8fa37ed84679f674420403f2", - "zh:9335c7300675e5088ab4090af3c8150701c0bb8ea67ad23ebd753f6ab3a922a9", - "zh:9722d8b419e9615a04b8fc9acb50e52d6ba988c7565cc517bc16faa0a9e895b3", - "zh:aa93d9fc7db91f261b6e41970453926341eaa4222c1b8d507cdeabd0be0af4eb", - "zh:c59a2af538de99c37e4ffe988f33633a9fb064e5360230adac5f6eb0fd473be8", - "zh:d6323f61f255131a7d9f5a645982eb0f0d12f685270f54beade95c0b51a7a6c9", - "zh:e7f46dd2aac9537d20aaac217806f2ebb3a347aaf6bbd28192c042286103635c", + "h1:8Vt9264v3UE6mHLRG8yiteVl5h8ZSTkJXf1xdVLa7GA=", + "zh:087a475fda3649e4b6b9aeb5f21704972f5d85c10d0bf334289b0a1b8c1a5575", + "zh:1877991d976491d4e2a653a89491bd3b92123a00f442f15aa62caea8902677c7", + "zh:233d9e550b900be8bbf62871322964239bb4827b3500b77d7e2652a8bae6a106", + "zh:6ed09d405ade276dfc6ec591d113ca328ea3fe423405d4bc1116f7a06dfd86ec", + "zh:9039de4cbee5ae006d9cbf27f40f0a285feb02c3b00901535a1112853de55b5f", + "zh:aea6311b0f29edddefa21b8c7953314459caeace77d72d60588d1277f1723c54", + "zh:bd6a4fea3461c2751527f1c4e4c2c160e72f5b5a3b5cfbfe051adf61badd5ead", + "zh:c5f12a2ea4c3b62d9dd2d8f62c9918ef77b1f9dd4d6ccf1758a2a24139ab5319", + "zh:cd84d7258f263c3bd24138e7633b022451fdc1935a11e34932b63f71bbe6059f", + "zh:e637d01ee4dc2e5702d62c158399ab0d0ba3269e71f5db38db922ff05505ae2a", "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + "zh:fbf9c9936ae547b75a81170b7bd20f72bc5538e015efcf7d12f822358d758f57", ] } provider "registry.terraform.io/hashicorp/http" { - version = "3.4.3" + version = "3.4.4" constraints = ">= 3.2.1" hashes = [ - "h1:Ep4kCumou6eEyPkFJFAfuzd7IAsYM7xMAdDaFTwdDZ8=", - "zh:001e12b8079955a9fa7f8fcd515ae665b2e1087107fd337c4b872e88a86d540b", - "zh:0874fb3f870b2ac24c967a9685f2da641079589024109340389694696301a85b", - "zh:3b5e533c3d2859575945568aad0aac66b71bfc709706231fc2de94e01ca76d7f", - "zh:622ee28d42ed9d4b1399dde377db515e62cac08bd65bb2455068621f7a42d90d", - "zh:6dea688d78840a3f678e06ee602d37c766ce2ee625dcdce0c6658116ebcbde8e", + "h1:EqpXf0aaUCTyYzlNP9XhjzAMMImD1T5bAy1pgLjWx4s=", + "zh:28910c348aff60df15cb70c2838c5dac463de5d52fe41a511f122b0b5fa6032d", + "zh:61ddcdb703900b01a8d38c67bd68304e87e05aa82c2d6636a5c49813b0cee8bf", + "zh:6d7ba9fcebff1079b9cbad066874d83680a4aedc997baa597927f59b29a69186", "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", - "zh:7f57a1436a464bc2e1698457b402ff0fd98ef9e7dcf6707d6bd0debc67fad164", - "zh:829d89d82e6fc3c89714950dc8afa51d622bb8e4f4bd5c73037505fb55a67834", - "zh:e453202d09b62531ed3278926307d315276e05784e7c6448a2c21c6a2da6e48f", - "zh:e76edc035240b4ad9334b4a0282b44a086e001df3007a2fc51f6262c4db032d1", - "zh:eeb0379da9093e155a193f666079de6baf8ed02855bf2a443448903f7cfef378", - "zh:fcb00eeb665ccae383645173d8e10c3071946396629a7797db39c798997f21b0", + "zh:82caa166f57808dd8421e9edf51bca0692135ca06ab548d5a2e3fe612bdd45a6", + "zh:95cb8ece59966d8f4020660879728dabaa158b3d188f22c0b92229347e740346", + "zh:ae56558b4262a4de250eec83e200ea4647badde10d1a14ed273f4daff650336f", + "zh:c1c5051eab9d9759fdb31bca6d7575a693558887a1156fa5f268963e05be4d92", + "zh:c90234ce3877e54be5b43493f51b582c6f9cb09138844cb048f63e9cd9f230fa", + "zh:cb237c6c47f085bf15149d6d2727b8bf108267582a30e7e2cd7393115896d003", + "zh:e7d782985f8b422cf265a856541ddb14f0d3ab0b54eb1aad6087ccfedacc7335", + "zh:ed0cc12d15226499fc7d173ad2b156c1934efae718cf254e79ca7f0ccd686b6d", ] } @@ -122,44 +122,44 @@ provider "registry.terraform.io/hashicorp/random" { } provider "registry.terraform.io/hashicorp/time" { - version = "0.11.2" + version = "0.12.0" constraints = ">= 0.9.1" hashes = [ - "h1:qg3O4PmHnlPcvuZ2LvzOYEAPGOKtccgD5kPdQPZw094=", - "zh:02588b5b8ba5d31e86d93edc93b306bcbf47c789f576769245968cc157a9e8c5", - "zh:088a30c23796133678d1d6614da5cf5544430570408a17062288b58c0bd67ac8", - "zh:0df5faa072d67616154d38021934d8a8a316533429a3f582df3b4b48c836cf89", - "zh:12edeeaef96c47f694bd1ba7ead6ccdb96028b25df352eea4bc5e40de7a59177", - "zh:1e859504a656a6e988f07b908e6ffe946b28bfb56889417c0a07ea9605a3b7b0", - "zh:64a6ae0320d4956c4fdb05629cfcebd03bcbd2206e2d733f2f18e4a97f4d5c7c", + "h1:Os2Ok7txtlUJHh6Hg7o+74Ql85SnRb/fGmah22yXpLw=", + "zh:019a4c09af254ef80b72cf0d843dfe72d99483e227138cf5b514a1b9977ab4c3", + "zh:0ae310ec740ebc6f275529507d60bb747d0bf39e72fc5a2fa90d74486006132c", + "zh:13d6aec117f05237fbf8c7d91d6ebb19797b00aa87e7a812642d3ea4738a394e", + "zh:2e87abbc261f9317d0c2ef26e01d5fabf77679da7d2cac6f47df7d198f720989", + "zh:4a6d471176ce0264455aa7d5457b8702f78400010c201c1719708958a1b7b647", "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", - "zh:924d137959193bf7aee6ebf241fbb9aec46d6eef828c5cf8d3c588770acae7b2", - "zh:b3cc76281a4faa9c2293a2460fc6962f6539e900994053f85185304887dddab8", - "zh:cbb40c791d4a1cdba56cffa43a9c0ed8e69930d49aa6bd931546b18c36e3b720", - "zh:d227d43594f8cb3d24f1fdd71382f14502cbe2a6deaddbc74242656bb5b38daf", - "zh:d4840641c46176bb9d70ba3aff09de749282136c779996b546c81e5ff701bbf6", + "zh:8978d5474a6da30bc0ad21c17db188d6918cacf3df3f6506b72ef3a268d53e2e", + "zh:b109efe138dfcb45dc04a9cc6809d185ab8b0ebc12040847c2dac430fda5af68", + "zh:b58e039b9106ac0a8de3c07f53b5279d7f0215fb35f2d23df642dfce0875382f", + "zh:ba2cbb2e515922d13efe3a46647be84f5426fcfcaa0f1520b3efeab8db847ed3", + "zh:c6c1ef1f26f25bca3abb5e07fa33dca37ed39cc26d0ff877964f2ffe5edd618c", + "zh:f8e171f923b7d2e789abd034072465dec3e6133c3a7644b7a7a965a74d52224e", ] } provider "registry.terraform.io/oracle/oci" { - version = "5.46.0" + version = "5.47.0" constraints = ">= 4.67.3, >= 4.119.0, ~> 5.38" hashes = [ - "h1:YnxOoKaBVUxvyEAcRrc8/amNglrtGTzxeTDmzm3R+LY=", - "zh:0dac7eba4d556d209627d11e2af6ae564a579617b548f411b5282952632d6820", - "zh:1b2d3e2282de8252ed6c017fc693c65747a0bf078b01423d6455df4723f5db60", - "zh:27763b8525aa2561adfb7c10f879e06fed71b4862f0f4d19086a0e22c05d6b49", - "zh:30cb5dca2edbfe4d31a73004ef049bde4b9f91ea85fdc188fc12f8e660563a45", - "zh:33b46e57b2d5a81e9bca7b6c7cd1a56dd0dc90f47f0624834e7eb1092a19a2d4", - "zh:3944bb473e7ed85fd08f6d47d65b5796f0da7714b51748c3e1c4854e9bc328a5", - "zh:3f2a950cd9604b00f03fb5ecdf0597b682fb9928a05e58d55c59c4b044824ba2", - "zh:47c85fc844dc0d685d5f3e513494ada8d785bb94188faad2ae00124ef10b319c", - "zh:5fc8235fb0be1192cfbd22b2cd14d20037b6611c3e783b9881ba3810befff805", + "h1:Jr/vt2+jZGZd+h2qM5LPg8/+1DuZkI9UA6+Xb35VwPY=", + "zh:1989a7d68753329c25e1175cdae0ecfb917e86a1b7687366888a69727cfdf383", + "zh:4b497dd634896c78f05c6000f51cc295adffa4d77edaf4e8cec889ee24751754", + "zh:4f50ed77d982eac118bf1e00b5cf90f12eb09acb1aa3be5b3f71601935093675", + "zh:50dc6e13843ab8b13439cb9029d9893f55debeb20541a63aef62e20bb85ece91", + "zh:6332a8ec1a5e80030b80dd0d37f20e6755bd1225a308fe512c083e65ca66ce83", + "zh:83bbb9f06ff4d7a09a13dcb145db9b8298b5c679ea681a753d6fbaf2fdc40d20", + "zh:9173587be16322072947be951834ce4bd7be1fd0f846b527ff478b6dd4e8a91b", "zh:9b12af85486a96aedd8d7984b0ff811a4b42e3d88dad1a3fb4c0b580d04fa425", - "zh:ac6537a460a506b6e09a7c90b1e26020fea4f621acc340a45286c9259a1e8a6f", - "zh:b4e4bc61eca8b7ee631976d40a506d67c4036c5ba63e74e2e19a28de57a13f77", - "zh:f0d67a9b83ad23b8083a9be648522b4e2f76fe302c782a0f5ece740e27111fb1", - "zh:f1daa463d29a83b97b51fa43e128abfae86613bedd4e214f085646c7702f8ee6", - "zh:fbc09b3f713baf0f0525a70dcabd774b05f494ad9773870bcf6fe104c46feb92", + "zh:a4331ca1d66848414857b4c5c0f9b2fe49aa4f72e283fb1df6edefbac1f76474", + "zh:a7d7bd1bd421ee94d72772f0c71f012ce538cbe48f8a646baf00c07755738122", + "zh:d0738787cae2842d6f13ac1d5d9cea6d5ec6acfe78ca25f1f992c1f2ed55eb5f", + "zh:d6e47352cc460bab26a04b45bf00f9ffd3fb01bdc254df2209e3af8c640e28d2", + "zh:e12ec25cba44489dac966ecb5ea89b63e88aefad6c0d28b54bde3af79f1389d7", + "zh:fe6aa72e82f9912b6c9893025bd58d967fad0f5864ea1151acc2d804ddbf7d70", + "zh:ff703d90bb3afab257c660732c23269cc7f58167fe85d163b3fa29cd70010d3a", ] } diff --git a/web/package.json b/web/package.json index a5dfbd1e..f5051194 100644 --- a/web/package.json +++ b/web/package.json @@ -1,7 +1,7 @@ { "name": "web", "private": true, - "version": "0.0.3", + "version": "0.0.4", "type": "module", "scripts": { "dev": "vite", @@ -33,4 +33,4 @@ "eslint-plugin-react-refresh": "^0.4.5", "vite": "^5.0.13" } -} +} \ No newline at end of file diff --git a/web/src/App.jsx b/web/src/App.jsx index b819f91d..cc82791e 100644 --- a/web/src/App.jsx +++ b/web/src/App.jsx @@ -1,7 +1,16 @@ import { Container, Typography } from "@mui/material"; import { StompProvider } from "./stompHook"; -import Chat from "./Chat"; import Routing from "./Routing"; +import { v4 as uuidv4 } from "uuid"; +import IdentityContext from "./IdentityContext"; + +let conversationId; +if (localStorage.getItem("conversationId")) { + conversationId = localStorage.getItem("conversationId"); +} else { + conversationId = uuidv4(); + localStorage.setItem("conversationId", conversationId); +} const protocol = window.location.protocol === "http:" ? "ws://" : "wss://"; const hostname = @@ -17,12 +26,14 @@ function App() { brokerURL: brokerURL, }} > - - - OCI GenAI PoC - - - + + + + OCI GenAI PoC + + + + ); } diff --git a/web/src/Chat.jsx b/web/src/Chat.jsx index c4d9f126..e7cd639d 100644 --- a/web/src/Chat.jsx +++ b/web/src/Chat.jsx @@ -1,13 +1,12 @@ -import { useState, useEffect } from "react"; +import { useState, useEffect, useContext } from "react"; import { Box, CircularProgress, Snackbar } from "@mui/material"; import PromptInput from "./PromptInput"; import Conversation from "./Conversation"; import { useStomp } from "./stompHook"; -import { v4 as uuidv4 } from "uuid"; - -const conversationId = uuidv4(); +import IdentityContext from "./IdentityContext"; function Chat() { + const identity = useContext(IdentityContext); const [conversation, setConversation] = useState([]); const [promptValue, setPromptValue] = useState(""); const [waiting, setWaiting] = useState(false); @@ -82,7 +81,7 @@ function Chat() { useEffect(() => { if (isConnected && promptValue.length) { send("/genai/prompt", { - conversationId, + conversationId: identity, content: promptValue, modelId: "notapply", }); diff --git a/web/src/IdentityContext.jsx b/web/src/IdentityContext.jsx new file mode 100644 index 00000000..1a3b1a0b --- /dev/null +++ b/web/src/IdentityContext.jsx @@ -0,0 +1,5 @@ +import { createContext } from "react"; + +const IdentityContext = createContext(undefined); + +export default IdentityContext; diff --git a/web/src/Routing.jsx b/web/src/Routing.jsx index e177820f..cf837d68 100644 --- a/web/src/Routing.jsx +++ b/web/src/Routing.jsx @@ -1,6 +1,7 @@ import { createBrowserRouter, RouterProvider } from "react-router-dom"; import Chat from "./Chat"; import Summary from "./Summary"; +import SummaryText from "./SummaryText"; const router = createBrowserRouter([ { @@ -11,6 +12,10 @@ const router = createBrowserRouter([ path: "/summary", element: , }, + { + path: "/summaryText", + element: , + }, ]); function Routing() { diff --git a/web/src/Summary.jsx b/web/src/Summary.jsx index 63362c55..569a7c0f 100644 --- a/web/src/Summary.jsx +++ b/web/src/Summary.jsx @@ -6,12 +6,14 @@ import { TextField, Typography, } from "@mui/material"; -import { useEffect, useState } from "react"; +import { useEffect, useState, useContext } from "react"; import { useForm } from "react-hook-form"; import { useStomp } from "./stompHook"; +import IdentityContext from "./IdentityContext"; function Summary() { - const { register, handleSubmit } = useForm(); + const identity = useContext(IdentityContext); + const { register, handleSubmit, reset } = useForm(); const [waiting, setWaiting] = useState(false); const [showError, setShowError] = useState(false); const [errorMessage, setErrorMessage] = useState(); @@ -21,7 +23,6 @@ function Summary() { useEffect(() => { if (isConnected) { subscribe("/user/queue/summary", (message) => { - setWaiting(false); if (message.errorMessage.length > 0) { setErrorMessage(message.errorMessage); setShowError(true); @@ -39,12 +40,14 @@ function Summary() { }, [isConnected]); const onSubmit = async (data) => { + setWaiting(true); const formData = new FormData(); formData.append("file", data.file[0]); const res = await fetch("/api/upload", { method: "POST", body: formData, + headers: { conversationId: identity, modelId: "n/a" }, }); const responseData = await res.json(); const { content, errorMessage } = responseData; @@ -55,6 +58,8 @@ function Summary() { console.log(content); setSummary(content); } + setWaiting(false); + reset(); }; return ( @@ -66,10 +71,12 @@ function Summary() { {...register("file")} /> - + - {summary.length && {summary}} + {summary.length !== 0 && {summary}} { + setWaiting(true); + const body = JSON.stringify({ + content: data.fullText, + }); + + const res = await fetch("/api/genai/summary", { + method: "POST", + body: body, + headers: { + "Content-Type": "application/json", + conversationId: identity, + modelId: "n/a", + }, + }); + const responseData = await res.json(); + const { content, errorMessage } = responseData; + if (errorMessage.length) { + setErrorMessage(errorMessage); + setShowError(true); + } else { + setSummary(content); + } + setWaiting(false); + reset(); + }; + return ( + +
+ + + + +
+ {summary.length !== 0 && {summary}} + { + setErrorMessage(); + setShowError(false); + }} + message={errorMessage} + /> +
+ ); +} + +export default SummaryText;