ask personalized questions for site creation
This commit is contained in:
@@ -3,7 +3,8 @@ package com.krrishg.dto;
|
||||
import java.util.List;
|
||||
|
||||
public record SuggestSectionsResponse(
|
||||
List<SectionSuggestion> sections
|
||||
List<SectionSuggestion> sections,
|
||||
List<PersonalizedQuestion> personalizedQuestions
|
||||
) {
|
||||
public record SectionSuggestion(
|
||||
String title,
|
||||
@@ -16,4 +17,11 @@ public record SuggestSectionsResponse(
|
||||
String title,
|
||||
String description
|
||||
) {}
|
||||
|
||||
public record PersonalizedQuestion(
|
||||
String id,
|
||||
String question,
|
||||
String type,
|
||||
List<String> options
|
||||
) {}
|
||||
}
|
||||
@@ -617,12 +617,14 @@ public class LLMService {
|
||||
}
|
||||
|
||||
private SuggestSectionsResponse parseSectionSuggestions(String llmOutput) {
|
||||
String json = extractJsonArray(llmOutput);
|
||||
String json = extractJsonObject(llmOutput);
|
||||
try {
|
||||
JsonNode root = objectMapper.readTree(json);
|
||||
List<SuggestSectionsResponse.SectionSuggestion> sections = new ArrayList<>();
|
||||
if (root.isArray()) {
|
||||
for (JsonNode node : root) {
|
||||
List<SuggestSectionsResponse.PersonalizedQuestion> questions = new ArrayList<>();
|
||||
|
||||
if (root.has("sections") && root.get("sections").isArray()) {
|
||||
for (JsonNode node : root.get("sections")) {
|
||||
String title = node.has("title") ? node.get("title").asText() : null;
|
||||
String description = node.has("description") ? node.get("description").asText() : null;
|
||||
String slug = node.has("slug") ? node.get("slug").asText() : null;
|
||||
@@ -641,15 +643,61 @@ public class LLMService {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (root.has("personalizedQuestions") && root.get("personalizedQuestions").isArray()) {
|
||||
for (JsonNode node : root.get("personalizedQuestions")) {
|
||||
String id = node.has("id") ? node.get("id").asText() : null;
|
||||
String question = node.has("question") ? node.get("question").asText() : null;
|
||||
String type = node.has("type") ? node.get("type").asText() : "text";
|
||||
if (id != null && question != null) {
|
||||
List<String> options = null;
|
||||
if (node.has("options") && node.get("options").isArray()) {
|
||||
options = new ArrayList<>();
|
||||
for (JsonNode opt : node.get("options")) {
|
||||
options.add(opt.asText());
|
||||
}
|
||||
}
|
||||
questions.add(new SuggestSectionsResponse.PersonalizedQuestion(id, question, type, options));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (sections.isEmpty()) {
|
||||
throw new IllegalArgumentException("LLM output must contain at least one section suggestion");
|
||||
}
|
||||
return new SuggestSectionsResponse(sections);
|
||||
return new SuggestSectionsResponse(sections, questions);
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new IllegalArgumentException("Failed to parse section suggestions as JSON: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private String extractJsonObject(String raw) {
|
||||
if (raw == null || raw.isBlank()) {
|
||||
throw new IllegalArgumentException("LLM output is empty");
|
||||
}
|
||||
String trimmed = raw.trim();
|
||||
if (trimmed.startsWith("```")) {
|
||||
int start = trimmed.indexOf('\n');
|
||||
int end = trimmed.lastIndexOf("```");
|
||||
if (start > 0 && end > start) {
|
||||
trimmed = trimmed.substring(start, end).trim();
|
||||
}
|
||||
}
|
||||
if (!trimmed.startsWith("{")) {
|
||||
int brace = trimmed.indexOf('{');
|
||||
if (brace >= 0) {
|
||||
trimmed = trimmed.substring(brace);
|
||||
}
|
||||
}
|
||||
if (!trimmed.endsWith("}")) {
|
||||
int brace = trimmed.lastIndexOf('}');
|
||||
if (brace >= 0) {
|
||||
trimmed = trimmed.substring(0, brace + 1);
|
||||
}
|
||||
}
|
||||
return trimmed;
|
||||
}
|
||||
|
||||
private String extractJsonArray(String raw) {
|
||||
if (raw == null || raw.isBlank()) {
|
||||
throw new IllegalArgumentException("LLM output is empty");
|
||||
|
||||
@@ -380,7 +380,8 @@ class LLMControllerTest {
|
||||
List.of(
|
||||
new SuggestSectionsResponse.SectionSuggestion("Home", "Hero section", "home", List.of()),
|
||||
new SuggestSectionsResponse.SectionSuggestion("About", "Bio", "about", List.of())
|
||||
)
|
||||
),
|
||||
List.of()
|
||||
);
|
||||
when(llmService.suggestSections(any(), anyString(), anyString(), any(), any(), any())).thenReturn(response);
|
||||
|
||||
|
||||
@@ -502,7 +502,8 @@ class LLMServiceTest {
|
||||
@Test
|
||||
void suggestSectionsReturnsParsedSuggestions() {
|
||||
geminiProvider.withContent("""
|
||||
[
|
||||
{
|
||||
"sections": [
|
||||
{"title": "Home", "description": "Hero section", "slug": "home",
|
||||
"patterns": [
|
||||
{"title": "Full-screen hero", "description": "Large image with text overlay"},
|
||||
@@ -513,7 +514,12 @@ class LLMServiceTest {
|
||||
{"title": "Timeline", "description": "Vertical story timeline"}
|
||||
]},
|
||||
{"title": "Gallery", "description": "Portfolio grid", "slug": "gallery", "patterns": []}
|
||||
]
|
||||
],
|
||||
"personalizedQuestions": [
|
||||
{"id": "name", "question": "What is your name?", "type": "text"},
|
||||
{"id": "bio", "question": "Write a short bio", "type": "textarea"}
|
||||
]
|
||||
}
|
||||
""");
|
||||
|
||||
SuggestSectionsResponse response = llmService.suggestSections(
|
||||
@@ -527,6 +533,10 @@ class LLMServiceTest {
|
||||
assertEquals("Full-screen hero", response.sections().get(0).patterns().get(0).title());
|
||||
assertEquals("Timeline", response.sections().get(1).patterns().get(0).title());
|
||||
assertEquals(0, response.sections().get(2).patterns().size());
|
||||
|
||||
assertEquals(2, response.personalizedQuestions().size());
|
||||
assertEquals("name", response.personalizedQuestions().get(0).id());
|
||||
assertEquals("textarea", response.personalizedQuestions().get(1).type());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -540,9 +550,12 @@ class LLMServiceTest {
|
||||
@Test
|
||||
void suggestSectionsUsesProvidedApiKey() {
|
||||
geminiProvider.withContent("""
|
||||
[
|
||||
{
|
||||
"sections": [
|
||||
{"title": "Home", "description": "Hero", "slug": "home", "patterns": []}
|
||||
]
|
||||
],
|
||||
"personalizedQuestions": []
|
||||
}
|
||||
""");
|
||||
|
||||
SuggestSectionsResponse response = llmService.suggestSections(
|
||||
|
||||
Reference in New Issue
Block a user