Skip to content

Commit

Permalink
Merge pull request #44 from tukcomCD2024/backend/feature/42-gpt-api-r…
Browse files Browse the repository at this point in the history
…esponse-dto

Backend/feature/42 gpt api response dto
  • Loading branch information
yo0oni authored Mar 9, 2024
2 parents deeb535 + fd069c5 commit 1899acd
Show file tree
Hide file tree
Showing 12 changed files with 164 additions and 82 deletions.
3 changes: 3 additions & 0 deletions backend/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ dependencies {
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.security:spring-security-test'

//GSON
implementation 'com.google.code.gson:gson:2.8.8'

}

tasks.named('test') {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,53 @@ public class GptConfig {
public static final String AUTHORIZATION = "Authorization";
public static final String BEARER = "Bearer ";
public static final String CHAT_MODEL = "gpt-3.5-turbo";
public static final Integer MAX_TOKEN = 300;
public static final Integer MAX_TOKEN = 3000;
public static final Boolean STREAM = false;
public static final String ROLE = "user";
public static final Double TEMPERATURE = 0.6;
public static final String MEDIA_TYPE = "application/json; charset=UTF-8";
public static final String CHAT_URL = "https://api.openai.com/v1/chat/completions";
public static final String PROMPT = """
I would like you to plan a package tour program to plan your travel itinerary.Destination: %s
Purpose of travel: %s
Departure date: %s
Entry date: %s
The flight schedule is as follows.
Also, plan your itinerary based on the travel distance and famous tourist destinations.
If possible, create the schedule in one-hour intervals.
Make sure to plan for at least 10 hours of activity each day.
I would like the format to be as follows:
For example
---
2024-02-06
1. Go to location
2. See the place
3. Eat the Lunch
4. Go to location
5. See the place
6. Eat the dinner
7. shopping
2024-02-07
1. Go to location
2. See the place
3. Eat the Lunch
4. Go to location
5. See the place
6. Eat the dinner
7. shopping
2024-02-08
1. Go to location
2. See the place
3. Eat the Lunch
4. Go to location
5. See the place
6. Eat the dinner
7. shopping
---
No need to say anything else, just plan your schedule right away.
Please create the result in Korean.""";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.isp.backend.domain.gpt.constant;

import java.util.List;

public class ParsingConstants {
public static final String DATE_REGEX = "(\\d{4}-\\d{2}-\\d{2})";
public static final String NEW_LINE_REGEX = "\n";
public static final String CURRENT_DATE = "";
public static final int BEGIN_INDEX = 3;
public static final List<String> FILTER_STRINGS = List.of(
"Message(role=assistant, content=", ")"
);
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
package com.isp.backend.domain.gpt.controller;

import com.isp.backend.domain.gpt.dto.GptResponseDTO;
import com.isp.backend.domain.gpt.dto.GptScheduleRequestDto;
import com.isp.backend.domain.gpt.entity.GptMessage;
import com.isp.backend.domain.gpt.dto.GptScheduleResponseDto;
import com.isp.backend.domain.gpt.service.GptService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
Expand All @@ -18,8 +17,8 @@ public class GptController {
private final GptService gptService;

@PostMapping("/question")
public ResponseEntity<GptMessage> sendQuestion(@RequestBody GptScheduleRequestDto gptScheduleRequestDto) {
GptResponseDTO gptResponseDTO = gptService.askQuestion(gptScheduleRequestDto);
return ResponseEntity.ok(gptResponseDTO.getChoices().get(0).getMessage());
public ResponseEntity<GptScheduleResponseDto> sendQuestion(@RequestBody GptScheduleRequestDto gptScheduleRequestDto) {
GptScheduleResponseDto gptScheduleResponseDto = gptService.askQuestion(gptScheduleRequestDto);
return ResponseEntity.ok(gptScheduleResponseDto);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.isp.backend.domain.gpt.dto;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.isp.backend.domain.gpt.entity.GptMessage;
import lombok.AllArgsConstructor;
import lombok.Getter;
Expand All @@ -13,30 +12,11 @@
@NoArgsConstructor
@AllArgsConstructor
public class GptResponseDTO {
private String id;
private String object;
private long created;
private String model;
private Usage usage;
private List<Choice> choices;

@Getter
@Setter
public static class Usage {
@JsonProperty("prompt_tokens")
private int promptTokens;
@JsonProperty("completion_tokens")
private int completionTokens;
@JsonProperty("total_tokens")
private int totalTokens;
}

@Getter
@Setter
public static class Choice {
private GptMessage message;
@JsonProperty("finish_reason")
private String finishReason;
private int index;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@
import lombok.Getter;
import lombok.NoArgsConstructor;

import java.util.List;

@Getter
@NoArgsConstructor
@AllArgsConstructor
public class GptScheduleResponseDto {
private GptSchedule gptSchedule;
private List<GptSchedule> schedules;
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.isp.backend.domain.gpt.entity;

import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

Expand All @@ -9,10 +8,11 @@
@Data
@NoArgsConstructor
public class GptSchedule {
private List<GptScheduleDetail> gptScheduleDetails;
private String date;
private List<String> scheduleDetail;

@Builder
public GptSchedule(List<GptScheduleDetail> gptScheduleDetails) {
this.gptScheduleDetails = gptScheduleDetails;
public GptSchedule(String date, List<String> scheduleDetail) {
this.date = date;
this.scheduleDetail = scheduleDetail;
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package com.isp.backend.domain.gpt.entity;

import com.isp.backend.domain.gpt.constant.ParsingConstants;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@RequiredArgsConstructor
@Component
public class GptScheduleParser {

public List<GptSchedule> parseScheduleText(String scheduleText) {
List<GptSchedule> schedules = new ArrayList<>();
Pattern pattern = Pattern.compile(ParsingConstants.DATE_REGEX);

List<String> lines = List.of(scheduleText.split(ParsingConstants.NEW_LINE_REGEX));
List<String> currentScheduleDetail = new ArrayList<>();
String currentDate = ParsingConstants.CURRENT_DATE;

for (String line : lines) {
processLine(line, pattern, schedules, currentScheduleDetail, currentDate);
}

addScheduleIfNotEmpty(currentDate, schedules, currentScheduleDetail);

return schedules;
}

private void processLine(String line, Pattern pattern, List<GptSchedule> schedules, List<String> currentScheduleDetail, String currentDate) {
Matcher dateMatcher = pattern.matcher(line);

if (dateMatcher.find()) {
handleNewDate(currentDate, schedules, currentScheduleDetail, dateMatcher.group(1));
} else {
handleNonDateLine(line, currentScheduleDetail);
}
}

private void handleNewDate(String currentDate, List<GptSchedule> schedules, List<String> currentScheduleDetail, String newDate) {
if (!currentDate.isEmpty()) {
schedules.add(new GptSchedule(currentDate, currentScheduleDetail));
}
}

private void handleNonDateLine(String line, List<String> currentScheduleDetail) {
if (!line.trim().isEmpty() && ParsingConstants.FILTER_STRINGS.stream().noneMatch(line::contains)) {
currentScheduleDetail.add(line.trim().substring(ParsingConstants.BEGIN_INDEX)); // Remove leading index
}
}

private void addScheduleIfNotEmpty(String currentDate, List<GptSchedule> schedules, List<String> currentScheduleDetail) {
if (!currentDate.isEmpty()) {
schedules.add(new GptSchedule(currentDate, currentScheduleDetail));
}
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
import com.isp.backend.domain.gpt.dto.GptRequestDTO;
import com.isp.backend.domain.gpt.dto.GptResponseDTO;
import com.isp.backend.domain.gpt.dto.GptScheduleRequestDto;
import com.isp.backend.domain.gpt.dto.GptScheduleResponseDto;
import com.isp.backend.domain.gpt.entity.GptMessage;
import com.isp.backend.domain.gpt.mapper.GptMapper;
import com.isp.backend.domain.gpt.entity.GptSchedule;
import com.isp.backend.domain.gpt.entity.GptScheduleParser;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
Expand All @@ -25,7 +27,7 @@
@Service
public class GptService {
private final RestTemplate restTemplate;
private final GptMapper gptMapper;
private final GptScheduleParser gptScheduleParser;

@Value("${api-key.chat-gpt}")
private String apiKey;
Expand All @@ -37,7 +39,7 @@ public HttpEntity<GptRequestDTO> buildHttpEntity(GptRequestDTO gptRequestDTO) {
return new HttpEntity<>(gptRequestDTO, httpHeaders);
}

public GptResponseDTO getResponse(HttpEntity<GptRequestDTO> chatGptRequestHttpEntity) {
public GptScheduleResponseDto getResponse(HttpEntity<GptRequestDTO> chatGptRequestHttpEntity) {

SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
requestFactory.setConnectTimeout(60000);
Expand All @@ -48,13 +50,29 @@ public GptResponseDTO getResponse(HttpEntity<GptRequestDTO> chatGptRequestHttpEn
GptConfig.CHAT_URL,
chatGptRequestHttpEntity,
GptResponseDTO.class);
List<GptSchedule> gptSchedules = gptScheduleParser.parseScheduleText(getScheduleText(responseEntity));
return new GptScheduleResponseDto(gptSchedules);
}

private String getScheduleText(ResponseEntity<GptResponseDTO> responseEntity) {
return getGptMessage(responseEntity).toString();
}

private GptMessage getGptMessage(ResponseEntity<GptResponseDTO> responseEntity) {
return getChoices(responseEntity).get(0).getMessage();
}

private List<GptResponseDTO.Choice> getChoices(ResponseEntity<GptResponseDTO> responseEntity) {
return getBody(responseEntity).getChoices();
}

private GptResponseDTO getBody(ResponseEntity<GptResponseDTO> responseEntity) {
return responseEntity.getBody();
}

public GptResponseDTO askQuestion(GptScheduleRequestDto questionRequestDTO) {
public GptScheduleResponseDto askQuestion(GptScheduleRequestDto questionRequestDTO) {
List<GptMessage> messages = new ArrayList<>();
String question = questionRequestDTO.getDepartureDate();
String question = makeQuestion(questionRequestDTO);
messages.add(GptMessage.builder()
.role(GptConfig.ROLE)
.content(question)
Expand All @@ -71,4 +89,13 @@ public GptResponseDTO askQuestion(GptScheduleRequestDto questionRequestDTO) {
)
);
}

private String makeQuestion(GptScheduleRequestDto questionRequestDTO) {
return String.format(GptConfig.PROMPT,
questionRequestDTO.getDestination(),
questionRequestDTO.getPurpose(),
questionRequestDTO.getDepartureDate(),
questionRequestDTO.getReturnDate()
);
}
}

0 comments on commit 1899acd

Please sign in to comment.