refs #737: move game query planning into ADB MCP tool

This commit is contained in:
devmrko
2026-07-27 16:39:58 +09:00
parent 8dffa2f515
commit 00a939f9a1
6 changed files with 263 additions and 288 deletions

View File

@@ -2,51 +2,14 @@ package com.cloudhandson.vpdbackoffice.service;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.List;
import org.junit.jupiter.api.Test;
class GameCatalogVectorServiceTest {
private static final GameCatalogVectorService.GameCandidate CATALOG_GAME =
new GameCatalogVectorService.GameCandidate(
"GAME_KEY",
"GAME_ID",
"GME",
"Catalog Game",
"GME Catalog Game 카탈로그게임",
0.31
);
@Test
void acceptsCandidateWhoseCatalogIdentityContainsTheExtractedMention() {
var match = GameCatalogVectorService.selectMatchedCandidate(
"카탈로그 게임", List.of(CATALOG_GAME));
assertThat(match).contains(CATALOG_GAME);
}
@Test
void rejectsNearestVectorCandidateWithoutCatalogIdentityMatch() {
var match = GameCatalogVectorService.selectMatchedCandidate(
"Unknown title", List.of(CATALOG_GAME));
assertThat(match).isEmpty();
}
@Test
void choosesClosestCandidateAmongIdentityMatches() {
var farther = new GameCatalogVectorService.GameCandidate(
"GAME_KEY_2",
"GAME_ID_2",
"GM2",
"Catalog Game Plus",
"Catalog Game Plus",
0.44
);
var match = GameCatalogVectorService.selectMatchedCandidate(
"Catalog Game", List.of(farther, CATALOG_GAME));
assertThat(match).contains(CATALOG_GAME);
void boundsCandidateCountPassedToTheAdbPlanningTool() {
assertThat(GameCatalogVectorService.boundedTopK(0)).isEqualTo(1);
assertThat(GameCatalogVectorService.boundedTopK(3)).isEqualTo(3);
assertThat(GameCatalogVectorService.boundedTopK(100)).isEqualTo(20);
}
}

View File

@@ -262,7 +262,7 @@ class McpSseServiceTest {
.contains("\"status\" : \"PARTIAL\"")
.contains("\"gameKey\" : \"SUPPORTED_GAME\"")
.contains("\"mention\" : \"Unknown game\"")
.contains("\"reasonCode\" : \"NO_CATALOG_IDENTITY_MATCH\"");
.contains("\"reasonCode\" : \"LLM_NO_CANDIDATE_MATCH\"");
}
private ObjectNode request(int id, String method) {
@@ -370,41 +370,24 @@ class McpSseServiceTest {
}
@Override
public Resolution resolve(String token, String question, int topK) {
GameCandidate supported = new GameCandidate(
"SUPPORTED_GAME",
"SUPPORTED_GAME_ID",
"SUPPORTED_PREFIX",
"Supported game",
"Supported",
0.1
);
GameCandidate nearestUnknownCandidate = new GameCandidate(
"OTHER_GAME",
"OTHER_GAME_ID",
"OTHER_PREFIX",
"Other game",
"Other",
0.6
);
return new Resolution(
"MULTI_GAME",
java.util.List.of(supported),
java.util.List.of(
new MentionResolution(
"Supported game",
"MATCHED",
supported,
java.util.List.of(supported)
),
new MentionResolution(
"Unknown game",
"UNMATCHED",
null,
java.util.List.of(nearestUnknownCandidate)
)
)
);
public ObjectNode queryPlan(String token, String question, int topK) {
ObjectNode plan = new ObjectMapper().createObjectNode();
plan.put("scopeType", "MULTI_GAME");
plan.put("status", "PARTIAL");
plan.putArray("matchedGames")
.addObject()
.put("gameKey", "SUPPORTED_GAME");
plan.putArray("mentionResults");
plan.putArray("supportedGames")
.addObject()
.put("gameKey", "SUPPORTED_GAME");
plan.putArray("unmatchedGames")
.addObject()
.put("mention", "Unknown game")
.put("reasonCode", "LLM_NO_CANDIDATE_MATCH");
plan.put("nextAction", "CALL_FEWSHOT_PER_GAME");
plan.put("executionMode", "FAN_OUT");
return plan;
}
}
}