Skip to content

Commit fc733e6

Browse files
authored
Merge pull request #37 from Azure-Samples/update-ui-3
Update UI 3
2 parents 02ce979 + ec2f96e commit fc733e6

File tree

76 files changed

+4775
-2057
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

76 files changed

+4775
-2057
lines changed

app/backend/src/main/java/com/microsoft/openai/samples/rag/approaches/RAGOptions.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ public Builder top(Integer top) {
9494
return this;
9595
}
9696

97+
9798
public RAGOptions build() {
9899
RAGOptions ragOptions = new RAGOptions();
99100
ragOptions.retrievalMode = this.retrievalMode;

app/backend/src/main/java/com/microsoft/openai/samples/rag/ask/approaches/semantickernel/JavaSemanticKernelChainsApproach.java

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.microsoft.openai.samples.rag.ask.approaches.semantickernel;
22

33
import com.azure.ai.openai.OpenAIAsyncClient;
4+
import com.microsoft.openai.samples.rag.approaches.ContentSource;
45
import com.microsoft.openai.samples.rag.approaches.RAGApproach;
56
import com.microsoft.openai.samples.rag.approaches.RAGOptions;
67
import com.microsoft.openai.samples.rag.approaches.RAGResponse;
@@ -9,15 +10,16 @@
910
import com.microsoft.semantickernel.Kernel;
1011
import com.microsoft.semantickernel.SKBuilders;
1112
import com.microsoft.semantickernel.orchestration.SKContext;
12-
import com.microsoft.semantickernel.planner.sequentialplanner.SequentialPlanner;
13-
import com.microsoft.semantickernel.planner.sequentialplanner.SequentialPlannerRequestSettings;
1413
import org.slf4j.Logger;
1514
import org.slf4j.LoggerFactory;
1615
import org.springframework.beans.factory.annotation.Value;
1716
import org.springframework.stereotype.Component;
1817

18+
import java.util.Arrays;
19+
import java.util.Collections;
20+
import java.util.List;
1921
import java.util.Objects;
20-
import java.util.Set;
22+
import java.util.stream.Collectors;
2123

2224
/**
2325
* Use Java Semantic Kernel framework with semantic and native functions chaining. It uses an imperative style for AI orchestration through semantic kernel functions chaining.
@@ -59,6 +61,8 @@ public RAGResponse run(String question, RAGOptions options) {
5961
question,
6062
semanticKernel.getSkill("InformationFinder").getFunction("Search", null)).block();
6163

64+
var sources = formSourcesList(searchContext.getResult());
65+
6266
var answerVariables = SKBuilders.variables()
6367
.withVariable("sources", searchContext.getResult())
6468
.withVariable("input", question)
@@ -70,12 +74,33 @@ public RAGResponse run(String question, RAGOptions options) {
7074
return new RAGResponse.Builder()
7175
.prompt("Prompt is managed by Semantic Kernel")
7276
.answer(answerExecutionContext.getResult())
77+
.sources(sources)
7378
.sourcesAsText(searchContext.getResult())
7479
.question(question)
7580
.build();
7681

7782
}
7883

84+
private List<ContentSource> formSourcesList(String result) {
85+
if (result == null) {
86+
return Collections.emptyList();
87+
}
88+
return Arrays.stream(result
89+
.split("\n"))
90+
.map(source -> {
91+
String[] split = source.split(":", 2);
92+
if (split.length >= 2) {
93+
var sourceName = split[0].trim();
94+
var sourceContent = split[1].trim();
95+
return new ContentSource(sourceName, sourceContent);
96+
} else {
97+
return null;
98+
}
99+
})
100+
.filter(Objects::nonNull)
101+
.collect(Collectors.toList());
102+
}
103+
79104
private Kernel buildSemanticKernel( RAGOptions options) {
80105
Kernel kernel = SKBuilders.kernel()
81106
.withDefaultAIService(SKBuilders.chatCompletion()

app/backend/src/main/java/com/microsoft/openai/samples/rag/ask/approaches/semantickernel/JavaSemanticKernelWithMemoryApproach.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import com.azure.core.credential.TokenCredential;
55
import com.azure.search.documents.SearchAsyncClient;
66
import com.azure.search.documents.SearchDocument;
7+
import com.microsoft.openai.samples.rag.approaches.ContentSource;
78
import com.microsoft.openai.samples.rag.approaches.RAGApproach;
89
import com.microsoft.openai.samples.rag.approaches.RAGOptions;
910
import com.microsoft.openai.samples.rag.approaches.RAGResponse;
@@ -22,6 +23,7 @@
2223

2324
import java.util.List;
2425
import java.util.function.Function;
26+
import java.util.stream.Collectors;
2527

2628
/**
2729
* Accomplish the same task as in the PlainJavaAskApproach approach but using Semantic Kernel framework:
@@ -78,6 +80,7 @@ public RAGResponse run(String question, RAGOptions options) {
7880
LOGGER.info("Total {} sources found in cognitive vector store for search query[{}]", memoryResult.size(), question);
7981

8082
String sources = buildSourcesText(memoryResult);
83+
List<ContentSource> sourcesList = buildSources(memoryResult);
8184

8285
SKContext skcontext = SKBuilders.context().build()
8386
.setVariable("sources", sources)
@@ -90,12 +93,25 @@ public RAGResponse run(String question, RAGOptions options) {
9093
//.prompt(plan.toPlanString())
9194
.prompt("placeholders for prompt")
9295
.answer(result.block().getResult())
96+
.sources(sourcesList)
9397
.sourcesAsText(sources)
9498
.question(question)
9599
.build();
96100

97101
}
98102

103+
private List<ContentSource> buildSources(List<MemoryQueryResult> memoryResult) {
104+
return memoryResult
105+
.stream()
106+
.map(result -> {
107+
return new ContentSource(
108+
result.getMetadata().getId(),
109+
result.getMetadata().getText()
110+
);
111+
})
112+
.collect(Collectors.toList());
113+
}
114+
99115
private String buildSourcesText(List<MemoryQueryResult> memoryResult) {
100116
StringBuilder sourcesContentBuffer = new StringBuilder();
101117
memoryResult.stream().forEach(memory -> {
Lines changed: 26 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,16 @@
11
package com.microsoft.openai.samples.rag.ask.controller;
22

3-
import com.microsoft.openai.samples.rag.approaches.*;
4-
import com.microsoft.openai.samples.rag.controller.Overrides;
3+
import com.microsoft.openai.samples.rag.approaches.RAGApproach;
4+
import com.microsoft.openai.samples.rag.approaches.RAGApproachFactory;
5+
import com.microsoft.openai.samples.rag.approaches.RAGOptions;
6+
import com.microsoft.openai.samples.rag.approaches.RAGResponse;
7+
import com.microsoft.openai.samples.rag.approaches.RAGType;
8+
import com.microsoft.openai.samples.rag.controller.ChatAppRequest;
9+
import com.microsoft.openai.samples.rag.controller.ChatResponse;
10+
import com.microsoft.openai.samples.rag.controller.ResponseChoice;
11+
import com.microsoft.openai.samples.rag.controller.ResponseContext;
12+
import com.microsoft.openai.samples.rag.controller.ResponseMessage;
13+
import com.microsoft.openai.samples.rag.common.ChatGPTMessage;
514
import org.slf4j.Logger;
615
import org.slf4j.LoggerFactory;
716
import org.springframework.http.HttpStatus;
@@ -11,7 +20,7 @@
1120
import org.springframework.web.bind.annotation.RequestBody;
1221
import org.springframework.web.bind.annotation.RestController;
1322

14-
import java.util.Arrays;
23+
import java.util.Collections;
1524
import java.util.List;
1625

1726
@RestController
@@ -25,59 +34,34 @@ public class AskController {
2534
}
2635

2736
@PostMapping("/api/ask")
28-
public ResponseEntity<AskResponse> openAIAsk(@RequestBody AskRequest askRequest) {
29-
LOGGER.info("Received request for ask api with question [{}] and approach[{}]", askRequest.getQuestion(), askRequest.getApproach());
37+
public ResponseEntity<ChatResponse> openAIAsk(@RequestBody ChatAppRequest askRequest) {
38+
String question = askRequest.messages().get(askRequest.messages().size() - 1).content();
39+
LOGGER.info("Received request for ask api with question [{}] and approach[{}]", question, askRequest.approach());
3040

31-
if (!StringUtils.hasText(askRequest.getApproach())) {
41+
if (!StringUtils.hasText(askRequest.approach())) {
3242
LOGGER.warn("approach cannot be null in ASK request");
3343
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(null);
3444
}
3545

36-
if (!StringUtils.hasText(askRequest.getQuestion())) {
46+
if (!StringUtils.hasText(question)) {
3747
LOGGER.warn("question cannot be null in ASK request");
3848
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(null);
3949
}
4050

4151
var ragOptions = new RAGOptions.Builder()
42-
.retrievialMode(askRequest.getOverrides().getRetrievalMode())
43-
.semanticKernelMode(askRequest.getOverrides().getSemantickKernelMode())
44-
.semanticRanker(askRequest.getOverrides().isSemanticRanker())
45-
.semanticCaptions(askRequest.getOverrides().isSemanticCaptions())
46-
.excludeCategory(askRequest.getOverrides().getExcludeCategory())
47-
.promptTemplate(askRequest.getOverrides().getPromptTemplate())
48-
.top(askRequest.getOverrides().getTop())
52+
.retrievialMode(askRequest.context().overrides().retrieval_mode().name())
53+
.semanticKernelMode(askRequest.context().overrides().semantic_kernel_mode())
54+
.semanticRanker(askRequest.context().overrides().semantic_ranker())
55+
.semanticCaptions(askRequest.context().overrides().semantic_captions())
56+
.excludeCategory(askRequest.context().overrides().exclude_category())
57+
.promptTemplate(askRequest.context().overrides().prompt_template())
58+
.top(askRequest.context().overrides().top())
4959
.build();
5060

51-
RAGApproach<String, RAGResponse> ragApproach = ragApproachFactory.createApproach(askRequest.getApproach(), RAGType.ASK, ragOptions);
61+
RAGApproach<String, RAGResponse> ragApproach = ragApproachFactory.createApproach(askRequest.approach(), RAGType.ASK, ragOptions);
5262

53-
//set empty overrides if not provided
54-
if (askRequest.getOverrides() == null) {
55-
askRequest.setOverrides(new Overrides());
56-
}
57-
58-
59-
60-
return ResponseEntity.ok(buildAskResponse(ragApproach.run(askRequest.getQuestion(), ragOptions)));
63+
return ResponseEntity.ok(ChatResponse.buildChatResponse(ragApproach.run(question, ragOptions)));
6164
}
6265

63-
private AskResponse buildAskResponse(RAGResponse ragResponse) {
64-
var askResponse = new AskResponse();
65-
66-
askResponse.setAnswer(ragResponse.getAnswer());
67-
List<String> dataPoints;
68-
if (ragResponse.getSourcesAsText() != null && !ragResponse.getSourcesAsText().isEmpty()) {
69-
dataPoints = Arrays.asList(ragResponse.getSourcesAsText().split("\n"));
70-
} else {
71-
dataPoints = ragResponse.getSources().stream()
72-
.map(source -> source.getSourceName() + ": " + source.getSourceContent())
73-
.toList();
74-
}
75-
76-
askResponse.setDataPoints(dataPoints);
77-
78-
askResponse.setThoughts("Question:<br>" + ragResponse.getQuestion() + "<br><br>Prompt:<br>" + ragResponse.getPrompt().replace("\n", "<br>"));
79-
80-
return askResponse;
81-
}
8266

8367
}

app/backend/src/main/java/com/microsoft/openai/samples/rag/ask/controller/AskRequest.java

Lines changed: 0 additions & 35 deletions
This file was deleted.

app/backend/src/main/java/com/microsoft/openai/samples/rag/ask/controller/AskResponse.java

Lines changed: 0 additions & 38 deletions
This file was deleted.

0 commit comments

Comments
 (0)