refs #708: report configured Smilegate Select AI profile
This commit is contained in:
@@ -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);
|
||||||
|
|||||||
@@ -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");
|
||||||
|
|||||||
Reference in New Issue
Block a user