Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.ssu.unithon.sign.infrastructure.openai.OpenAiClient;
import java.util.List;
import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
Expand All @@ -11,6 +12,11 @@ public class SignSentenceService {

private static final Logger log = LoggerFactory.getLogger(SignSentenceService.class);

/** Standalone greetings/acknowledgements that don't need LLM composition — the single word already is the sentence. */
private static final Set<String> STANDALONE_WORDS = Set.of(
"감사합니다", "고맙습니다", "안녕하세요", "안녕", "네", "예", "아니요", "아니오"
);

private static final String SYSTEM_PROMPT = """
너는 실시간 접근성 통화 중계 서비스의 통역 보조 도구다. 통화 중 한쪽은 청각장애인(농인)이고, \
그 사람은 한국수어로 상대방(비장애인)에게 무언가를 문의하거나 요청하는 중이다. \
Expand Down Expand Up @@ -46,6 +52,9 @@ public SignSentenceService(OpenAiClient client) {

/** Converts a signed gloss sequence into one natural Korean sentence via an LLM, using prior turns as context, falling back to a plain join on failure. */
public String compose(List<String> words, List<HistoryTurn> history) {
if (words.size() == 1 && STANDALONE_WORDS.contains(words.get(0).trim())) {
return words.get(0).trim();
}
String joined = String.join(" ", words);
String userMessage = buildUserMessage(words, history);
try {
Expand Down
13 changes: 13 additions & 0 deletions src/test/java/com/ssu/unithon/sign/api/SignControllerTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,19 @@ void includes_history_in_the_prompt_when_provided() throws Exception {
.contains("4시 변경");
}

@Test
void returns_standalone_word_without_calling_the_llm() throws Exception {
String response = mvc.perform(post("/api/sign-language/compose")
.contentType(MediaType.APPLICATION_JSON)
.content("{\"words\":[\"감사합니다\"]}"))
.andExpect(status().isOk())
.andReturn().getResponse().getContentAsString();

JsonNode body = json.readTree(response);
assertThat(body.get("sentence").asText()).isEqualTo("감사합니다");
assertThat(openAi.lastUserMessage).isNull();
}

@Test
void rejects_empty_word_list() throws Exception {
mvc.perform(post("/api/sign-language/compose")
Expand Down
Loading