refs #737: move game query planning into ADB MCP tool
This commit is contained in:
@@ -200,12 +200,12 @@ public class McpSseService {
|
||||
} else if (gameScopeTool) {
|
||||
response = gameScopeResponse(gameScopeService.resolve(
|
||||
token, arguments.path("question").asText("")));
|
||||
} else if (gameCatalogTool) {
|
||||
response = gameCatalogVectorResponse(gameCatalogVectorService.resolve(
|
||||
token, arguments.path("question").asText(""), arguments.path("topK").asInt(5)));
|
||||
} else if (gameQueryPlanTool) {
|
||||
response = gameQueryPlanResponse(gameCatalogVectorService.resolve(
|
||||
token, arguments.path("question").asText(""), arguments.path("topK").asInt(5)));
|
||||
} else if (gameCatalogTool || gameQueryPlanTool) {
|
||||
response = gameCatalogVectorService.queryPlan(
|
||||
token,
|
||||
arguments.path("question").asText(""),
|
||||
arguments.path("topK").asInt(5)
|
||||
);
|
||||
} else {
|
||||
String prompt = arguments.path("prompt").asText("");
|
||||
response = queryTool
|
||||
@@ -258,50 +258,6 @@ public class McpSseService {
|
||||
return response;
|
||||
}
|
||||
|
||||
private ObjectNode gameCatalogVectorResponse(GameCatalogVectorService.Resolution resolution) {
|
||||
ObjectNode response = objectMapper.createObjectNode();
|
||||
response.put("scopeType", resolution.scopeType());
|
||||
boolean hasUnmatched = resolution.mentions().stream()
|
||||
.anyMatch(mention -> "UNMATCHED".equals(mention.status()));
|
||||
response.put("status", resolution.candidates().isEmpty()
|
||||
? "NO_MATCH" : hasUnmatched ? "PARTIAL" : "CANDIDATES");
|
||||
ArrayNode items = response.putArray("matchedGames");
|
||||
for (GameCatalogVectorService.GameCandidate c : resolution.candidates()) {
|
||||
addGameCandidate(items.addObject(), c, true);
|
||||
}
|
||||
ArrayNode mentionResults = response.putArray("mentionResults");
|
||||
for (GameCatalogVectorService.MentionResolution mention
|
||||
: resolution.mentions()) {
|
||||
ObjectNode item = mentionResults.addObject();
|
||||
item.put("mention", mention.mention());
|
||||
item.put("status", mention.status());
|
||||
if (mention.matchedGame() != null) {
|
||||
item.put("matchedGameKey", mention.matchedGame().gameKey());
|
||||
}
|
||||
ArrayNode candidates = item.putArray("candidateGames");
|
||||
for (GameCatalogVectorService.GameCandidate candidate
|
||||
: mention.candidates()) {
|
||||
addGameCandidate(candidates.addObject(), candidate, false);
|
||||
}
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
private void addGameCandidate(
|
||||
ObjectNode item,
|
||||
GameCatalogVectorService.GameCandidate candidate,
|
||||
boolean includeAliases
|
||||
) {
|
||||
item.put("gameKey", candidate.gameKey());
|
||||
item.put("gameId", candidate.gameId());
|
||||
item.put("gamePrefix", candidate.gamePrefix());
|
||||
item.put("gameName", candidate.gameName());
|
||||
if (includeAliases) {
|
||||
item.put("aliases", candidate.aliases());
|
||||
}
|
||||
item.put("cosineDistance", candidate.similarity());
|
||||
}
|
||||
|
||||
private ObjectNode qaVectorStoreResponse(QaVectorService.VectorStoreResult stored) {
|
||||
ObjectNode response = objectMapper.createObjectNode();
|
||||
response.put("status", "QA_VECTOR_STORED");
|
||||
@@ -409,44 +365,6 @@ public class McpSseService {
|
||||
-1L, "게임 질의 계획", SELECT_AI_TOOL_PATH);
|
||||
}
|
||||
|
||||
private ObjectNode gameQueryPlanResponse(GameCatalogVectorService.Resolution resolution) {
|
||||
ObjectNode response = gameCatalogVectorResponse(resolution);
|
||||
List<GameCatalogVectorService.MentionResolution> unmatchedMentions =
|
||||
resolution.mentions().stream()
|
||||
.filter(mention -> "UNMATCHED".equals(mention.status()))
|
||||
.toList();
|
||||
response.put("status", resolution.candidates().isEmpty()
|
||||
? "NO_MATCH" : unmatchedMentions.isEmpty() ? "SUPPORTED" : "PARTIAL");
|
||||
ArrayNode supported = response.putArray("supportedGames");
|
||||
for (GameCatalogVectorService.GameCandidate c : resolution.candidates()) {
|
||||
ObjectNode item = supported.addObject();
|
||||
item.put("gameKey", c.gameKey());
|
||||
item.put("gameId", c.gameId());
|
||||
item.put("gameName", c.gameName());
|
||||
item.put("gamePrefix", c.gamePrefix());
|
||||
item.put("cosineDistance", c.similarity());
|
||||
}
|
||||
ArrayNode unmatched = response.putArray("unmatchedGames");
|
||||
for (GameCatalogVectorService.MentionResolution mention
|
||||
: unmatchedMentions) {
|
||||
ObjectNode item = unmatched.addObject();
|
||||
item.put("mention", mention.mention());
|
||||
item.put("reasonCode", "NO_CATALOG_IDENTITY_MATCH");
|
||||
}
|
||||
response.put("nextAction", resolution.candidates().isEmpty()
|
||||
? "STOP_NO_MATCH"
|
||||
: ("MULTI_GAME".equals(resolution.scopeType())
|
||||
? "CALL_FEWSHOT_PER_GAME" : "CALL_FEWSHOT"));
|
||||
String mode = switch (resolution.scopeType()) {
|
||||
case "SINGLE_GAME" -> "SINGLE";
|
||||
case "MULTI_GAME" -> "FAN_OUT";
|
||||
case "ALL_GAMES" -> "GROUPED";
|
||||
default -> "BLOCKED";
|
||||
};
|
||||
response.put("executionMode", mode);
|
||||
return response;
|
||||
}
|
||||
|
||||
private String selectAiProfile() {
|
||||
BackofficeProperties.SelectAi selectAi = properties == null ? null : properties.selectAi();
|
||||
if (selectAi == null || selectAi.profile() == null || selectAi.profile().isBlank()) {
|
||||
|
||||
Reference in New Issue
Block a user