refs #731: expose database game scope MCP

This commit is contained in:
devmrko
2026-07-27 13:43:59 +09:00
parent a17f18cffe
commit 455e2aa222
5 changed files with 157 additions and 10 deletions

View File

@@ -2,6 +2,7 @@ package com.cloudhandson.vpdbackoffice.service;
import static org.assertj.core.api.Assertions.assertThat;
import com.cloudhandson.vpdbackoffice.config.BackofficeProperties;
import com.cloudhandson.vpdbackoffice.config.GameScopeProperties;
import com.cloudhandson.vpdbackoffice.config.McpProperties;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.JsonNode;
@@ -13,6 +14,7 @@ class McpSseServiceTest {
private final ObjectMapper objectMapper = new ObjectMapper();
private final SelectAiService selectAiService = new CapturingSelectAiService();
private final QaVectorService qaVectorService = new CapturingQaVectorService();
private final GameScopeService gameScopeService = new CapturingGameScopeService();
private final McpSseService service = new McpSseService(
selectAiService,
objectMapper,
@@ -40,9 +42,13 @@ class McpSseServiceTest {
"테스트 예제 SQL을 저장합니다.",
"oracle.select_ai.test_fewshot_nl2sql",
"테스트 Few-shot NL2SQL",
"테스트 Few-shot 검색 및 실행 도구입니다."
"테스트 Few-shot 검색 및 실행 도구입니다.",
"oracle.select_ai.test_game_scope_resolve",
"테스트 게임 범위 확인",
"테스트 DB 게임 범위 확인 도구입니다."
),
qaVectorService
qaVectorService,
gameScopeService
);
@Test
@@ -50,7 +56,7 @@ class McpSseServiceTest {
ObjectNode response = service.handle("default", request(1, "tools/list"));
var tools = response.path("result").path("tools");
assertThat(tools).hasSize(5);
assertThat(tools).hasSize(6);
var selectAi = tools.get(0);
assertThat(selectAi.path("name").asText()).isEqualTo("oracle.select_ai.test_data_text2sql");
assertThat(selectAi.path("description").asText()).contains("SGMP_POC_OCI_GPT54MINI");
@@ -90,6 +96,12 @@ class McpSseServiceTest {
assertThat(fewShot.path("name").asText())
.isEqualTo("oracle.select_ai.test_fewshot_nl2sql");
assertThat(fewShot.path("description").asText()).contains("Few-shot");
var gameScope = tools.get(5);
assertThat(gameScope.path("name").asText())
.isEqualTo("oracle.select_ai.test_game_scope_resolve");
assertThat(gameScope.path("inputSchema").path("required"))
.extracting(node -> node.asText()).contains("question");
}
@Test
@@ -208,6 +220,23 @@ class McpSseServiceTest {
.contains("exampleId");
}
@Test
void resolvesGameScopeFromTheDatabaseBackedTool() {
ObjectNode request = request(8, "tools/call");
ObjectNode params = (ObjectNode) request.putObject("params");
params.put("name", "oracle.select_ai.test_game_scope_resolve");
params.putObject("arguments").put("question", "games requested");
ObjectNode response = service.handle("default", request, "user-bearer");
assertThat(response.path("result").path("isError").asBoolean()).isFalse();
String payload = response.path("result").path("content").get(0).path("text").asText();
assertThat(payload)
.contains("RESOLVED")
.contains("CALL_FEW_SHOT_NL2SQL")
.contains("REPORT_UNSUPPORTED");
}
private ObjectNode request(int id, String method) {
ObjectNode request = objectMapper.createObjectNode();
request.put("jsonrpc", "2.0");
@@ -223,7 +252,7 @@ class McpSseServiceTest {
private boolean showpromptCalled;
private CapturingSelectAiService() {
super(null, null, null, new ObjectMapper(), null);
super(null, null, null, new ObjectMapper(), null, null);
}
@Override
@@ -240,6 +269,11 @@ class McpSseServiceTest {
return response;
}
@Override
public JsonNode generateAndExecute(String bearerToken, String prompt, String scopeGameKey) {
return generateAndExecute(bearerToken, prompt);
}
@Override
public JsonNode generatePrompt(String bearerToken, String prompt) {
this.bearerToken = bearerToken;
@@ -282,4 +316,21 @@ class McpSseServiceTest {
return new VectorStoreResult(77L, question, "cohere.embed-v4.0");
}
}
private static final class CapturingGameScopeService extends GameScopeService {
private CapturingGameScopeService() {
super(null, new GameScopeProperties(false, "", 8), null, null);
}
@Override
public GameScopeResult resolve(String bearerToken, String question) {
return new GameScopeResult(question, "RESOLVED", java.util.List.of(
new GameScope("SUPPORTED_GAME", "Supported game", "Supported", "SUPPORTED",
"APPROVED_OBJECT_AVAILABLE", 100, "100"),
new GameScope("UNSUPPORTED_GAME", "Unsupported game", "Unsupported", "UNSUPPORTED",
"OBJECT_LIST_NOT_AVAILABLE", 100, "100")
));
}
}
}