refs #708: report configured Smilegate Select AI profile

This commit is contained in:
devmrko
2026-07-23 14:06:16 +09:00
parent 14b237a734
commit a579501d6e
2 changed files with 38 additions and 13 deletions

View File

@@ -1,5 +1,6 @@
package com.cloudhandson.vpdbackoffice.service; package com.cloudhandson.vpdbackoffice.service;
import com.cloudhandson.vpdbackoffice.config.BackofficeProperties;
import com.cloudhandson.vpdbackoffice.domain.mcp.McpToolView; import com.cloudhandson.vpdbackoffice.domain.mcp.McpToolView;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
@@ -14,24 +15,20 @@ public class McpSseService {
private static final String SELECT_AI_VPD_QUERY_TOOL = "oracle.select_ai.smilegate_game_text2sql"; private static final String SELECT_AI_VPD_QUERY_TOOL = "oracle.select_ai.smilegate_game_text2sql";
private static final String SELECT_AI_VPD_QUERY_PATH = "/mcp (tools/call)"; private static final String SELECT_AI_VPD_QUERY_PATH = "/mcp (tools/call)";
private static final String SELECT_AI_VPD_QUERY_PROFILE = "SGMP_POC_HAIKU45"; private static final String DEFAULT_SELECT_AI_PROFILE = "SGMP_POC_OCI_GPT54MINI";
private static final McpToolView SELECT_AI_VPD_QUERY_VIEW = new McpToolView(
SELECT_AI_VPD_QUERY_TOOL,
"SGMP_POC_HAIKU45 프로파일로 게임 로그·서비스 데이터용 읽기 전용 SELECT/WITH SQL을 생성하고, 검증 후 읽기 전용 트랜잭션에서 실행합니다. 생성 SQL과 최대 100건의 조회 결과를 함께 반환하며 DDL/DML/잠금/패키지 호출은 실행하지 않습니다.",
-1L,
"Smilegate 게임 데이터 Text2SQL",
SELECT_AI_VPD_QUERY_PATH
);
private final SmilegateSelectAiService smilegateSelectAiService; private final SmilegateSelectAiService smilegateSelectAiService;
private final ObjectMapper objectMapper; private final ObjectMapper objectMapper;
private final BackofficeProperties properties;
public McpSseService( public McpSseService(
SmilegateSelectAiService smilegateSelectAiService, SmilegateSelectAiService smilegateSelectAiService,
ObjectMapper objectMapper ObjectMapper objectMapper,
BackofficeProperties properties
) { ) {
this.smilegateSelectAiService = smilegateSelectAiService; this.smilegateSelectAiService = smilegateSelectAiService;
this.objectMapper = objectMapper; this.objectMapper = objectMapper;
this.properties = properties;
} }
public ObjectNode handle(String contextPath, JsonNode request) { public ObjectNode handle(String contextPath, JsonNode request) {
@@ -70,7 +67,7 @@ public class McpSseService {
/** The only tool registered by this MCP server. */ /** The only tool registered by this MCP server. */
public List<McpToolView> registeredTools() { public List<McpToolView> registeredTools() {
return List.of(SELECT_AI_VPD_QUERY_VIEW); return List.of(selectAiVpdQueryView());
} }
private ObjectNode initializeResult(String contextPath) { private ObjectNode initializeResult(String contextPath) {
@@ -97,7 +94,7 @@ public class McpSseService {
private ObjectNode selectAiVpdQueryTool() { private ObjectNode selectAiVpdQueryTool() {
ObjectNode item = objectMapper.createObjectNode(); ObjectNode item = objectMapper.createObjectNode();
item.put("name", SELECT_AI_VPD_QUERY_TOOL); item.put("name", SELECT_AI_VPD_QUERY_TOOL);
item.put("description", SELECT_AI_VPD_QUERY_VIEW.description()); item.put("description", selectAiVpdQueryView().description());
ObjectNode schema = objectMapper.createObjectNode(); ObjectNode schema = objectMapper.createObjectNode();
schema.put("type", "object"); schema.put("type", "object");
@@ -138,7 +135,7 @@ public class McpSseService {
ObjectNode payload = objectMapper.createObjectNode(); ObjectNode payload = objectMapper.createObjectNode();
payload.put("toolName", SELECT_AI_VPD_QUERY_TOOL); payload.put("toolName", SELECT_AI_VPD_QUERY_TOOL);
payload.put("profile", SELECT_AI_VPD_QUERY_PROFILE); payload.put("profile", selectAiProfile());
payload.put("ordsPath", SELECT_AI_VPD_QUERY_PATH); payload.put("ordsPath", SELECT_AI_VPD_QUERY_PATH);
payload.set("response", response); payload.set("response", response);
@@ -169,6 +166,25 @@ public class McpSseService {
return result; return result;
} }
private McpToolView selectAiVpdQueryView() {
String profile = selectAiProfile();
return new McpToolView(
SELECT_AI_VPD_QUERY_TOOL,
profile + " 프로파일로 게임 로그·서비스 데이터용 읽기 전용 SELECT/WITH SQL을 생성하고, 검증 후 읽기 전용 트랜잭션에서 실행합니다. 생성 SQL과 최대 100건의 조회 결과를 함께 반환하며 DDL/DML/잠금/패키지 호출은 실행하지 않습니다.",
-1L,
"Smilegate 게임 데이터 Text2SQL",
SELECT_AI_VPD_QUERY_PATH
);
}
private String selectAiProfile() {
BackofficeProperties.SelectAi selectAi = properties == null ? null : properties.selectAi();
if (selectAi == null || selectAi.profile() == null || selectAi.profile().isBlank()) {
return DEFAULT_SELECT_AI_PROFILE;
}
return selectAi.profile().trim();
}
private String pretty(Object value) { private String pretty(Object value) {
try { try {
return objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(value); return objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(value);

View File

@@ -1,6 +1,7 @@
package com.cloudhandson.vpdbackoffice.service; package com.cloudhandson.vpdbackoffice.service;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import com.cloudhandson.vpdbackoffice.config.BackofficeProperties;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.node.ObjectNode;
@@ -12,7 +13,14 @@ class McpSseServiceTest {
private final SmilegateSelectAiService selectAiService = new CapturingSmilegateSelectAiService(); private final SmilegateSelectAiService selectAiService = new CapturingSmilegateSelectAiService();
private final McpSseService service = new McpSseService( private final McpSseService service = new McpSseService(
selectAiService, selectAiService,
objectMapper objectMapper,
new BackofficeProperties(
null,
null,
null,
null,
new BackofficeProperties.SelectAi("", "", "", "SGMP_POC_OCI_GPT54MINI")
)
); );
@Test @Test
@@ -23,6 +31,7 @@ class McpSseServiceTest {
assertThat(tools).hasSize(1); assertThat(tools).hasSize(1);
var selectAi = tools.get(0); var selectAi = tools.get(0);
assertThat(selectAi.path("name").asText()).isEqualTo("oracle.select_ai.smilegate_game_text2sql"); assertThat(selectAi.path("name").asText()).isEqualTo("oracle.select_ai.smilegate_game_text2sql");
assertThat(selectAi.path("description").asText()).contains("SGMP_POC_OCI_GPT54MINI");
assertThat(selectAi.path("inputSchema").path("required")) assertThat(selectAi.path("inputSchema").path("required"))
.extracting(node -> node.asText()) .extracting(node -> node.asText())
.contains("prompt"); .contains("prompt");