add game query plan MCP tool
This commit is contained in:
@@ -16,6 +16,7 @@ public class McpSseService {
|
|||||||
|
|
||||||
private static final String SELECT_AI_TOOL_PATH = "/mcp (tools/call)";
|
private static final String SELECT_AI_TOOL_PATH = "/mcp (tools/call)";
|
||||||
private static final String GAME_CATALOG_TOOL = "oracle.select_ai.game_catalog_resolve";
|
private static final String GAME_CATALOG_TOOL = "oracle.select_ai.game_catalog_resolve";
|
||||||
|
private static final String GAME_QUERY_PLAN_TOOL = "oracle.select_ai.game_query_plan";
|
||||||
|
|
||||||
private final SelectAiService selectAiService;
|
private final SelectAiService selectAiService;
|
||||||
private final ObjectMapper objectMapper;
|
private final ObjectMapper objectMapper;
|
||||||
@@ -81,7 +82,7 @@ public class McpSseService {
|
|||||||
public List<McpToolView> registeredTools() {
|
public List<McpToolView> registeredTools() {
|
||||||
return List.of(
|
return List.of(
|
||||||
selectAiQueryView(), selectAiShowpromptView(), qaVectorSearchView(),
|
selectAiQueryView(), selectAiShowpromptView(), qaVectorSearchView(),
|
||||||
qaVectorStoreView(), fewShotNl2SqlView(), gameScopeView(), gameCatalogView());
|
qaVectorStoreView(), fewShotNl2SqlView(), gameScopeView(), gameCatalogView(), gameQueryPlanView());
|
||||||
}
|
}
|
||||||
|
|
||||||
private ObjectNode initializeResult(String contextPath) {
|
private ObjectNode initializeResult(String contextPath) {
|
||||||
@@ -107,6 +108,7 @@ public class McpSseService {
|
|||||||
tools.add(toolDefinition(fewShotNl2SqlView()));
|
tools.add(toolDefinition(fewShotNl2SqlView()));
|
||||||
tools.add(toolDefinition(gameScopeView()));
|
tools.add(toolDefinition(gameScopeView()));
|
||||||
tools.add(toolDefinition(gameCatalogView()));
|
tools.add(toolDefinition(gameCatalogView()));
|
||||||
|
tools.add(toolDefinition(gameQueryPlanView()));
|
||||||
result.set("tools", tools);
|
result.set("tools", tools);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -122,7 +124,7 @@ public class McpSseService {
|
|||||||
|
|
||||||
ArrayNode required = objectMapper.createArrayNode();
|
ArrayNode required = objectMapper.createArrayNode();
|
||||||
if (qaVectorSearchToolName().equals(toolView.name()) || gameScopeToolName().equals(toolView.name())
|
if (qaVectorSearchToolName().equals(toolView.name()) || gameScopeToolName().equals(toolView.name())
|
||||||
|| GAME_CATALOG_TOOL.equals(toolView.name())) {
|
|| GAME_CATALOG_TOOL.equals(toolView.name()) || GAME_QUERY_PLAN_TOOL.equals(toolView.name())) {
|
||||||
addStringProperty(properties, "question", "few-shot 예제 SQL을 찾을 현재 질문입니다.", 4000);
|
addStringProperty(properties, "question", "few-shot 예제 SQL을 찾을 현재 질문입니다.", 4000);
|
||||||
ObjectNode topK = properties.putObject("topK");
|
ObjectNode topK = properties.putObject("topK");
|
||||||
topK.put("type", "integer");
|
topK.put("type", "integer");
|
||||||
@@ -168,8 +170,9 @@ public class McpSseService {
|
|||||||
boolean fewShotNl2SqlTool = fewShotNl2SqlToolName().equals(calledToolName);
|
boolean fewShotNl2SqlTool = fewShotNl2SqlToolName().equals(calledToolName);
|
||||||
boolean gameScopeTool = gameScopeToolName().equals(calledToolName);
|
boolean gameScopeTool = gameScopeToolName().equals(calledToolName);
|
||||||
boolean gameCatalogTool = GAME_CATALOG_TOOL.equals(calledToolName);
|
boolean gameCatalogTool = GAME_CATALOG_TOOL.equals(calledToolName);
|
||||||
|
boolean gameQueryPlanTool = GAME_QUERY_PLAN_TOOL.equals(calledToolName);
|
||||||
if (!queryTool && !showpromptTool && !qaVectorSearchTool && !qaVectorStoreTool && !fewShotNl2SqlTool
|
if (!queryTool && !showpromptTool && !qaVectorSearchTool && !qaVectorStoreTool && !fewShotNl2SqlTool
|
||||||
&& !gameScopeTool && !gameCatalogTool) {
|
&& !gameScopeTool && !gameCatalogTool && !gameQueryPlanTool) {
|
||||||
throw new AppException("등록되지 않은 MCP tool입니다: " + calledToolName);
|
throw new AppException("등록되지 않은 MCP tool입니다: " + calledToolName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -196,6 +199,9 @@ public class McpSseService {
|
|||||||
} else if (gameCatalogTool) {
|
} else if (gameCatalogTool) {
|
||||||
response = gameCatalogVectorResponse(gameCatalogVectorService.resolve(
|
response = gameCatalogVectorResponse(gameCatalogVectorService.resolve(
|
||||||
token, arguments.path("question").asText(""), arguments.path("topK").asInt(5)));
|
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 {
|
} else {
|
||||||
String prompt = arguments.path("prompt").asText("");
|
String prompt = arguments.path("prompt").asText("");
|
||||||
response = queryTool
|
response = queryTool
|
||||||
@@ -362,6 +368,24 @@ public class McpSseService {
|
|||||||
-1L, "게임 카탈로그 범위 확인", SELECT_AI_TOOL_PATH);
|
-1L, "게임 카탈로그 범위 확인", SELECT_AI_TOOL_PATH);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private McpToolView gameQueryPlanView() {
|
||||||
|
return new McpToolView(GAME_QUERY_PLAN_TOOL,
|
||||||
|
"질문에서 게임 범위와 실행 모드를 판정합니다. SQL은 실행하지 않습니다.",
|
||||||
|
-1L, "게임 질의 계획", SELECT_AI_TOOL_PATH);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ObjectNode gameQueryPlanResponse(GameCatalogVectorService.Resolution resolution) {
|
||||||
|
ObjectNode response = gameCatalogVectorResponse(resolution);
|
||||||
|
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() {
|
private String selectAiProfile() {
|
||||||
BackofficeProperties.SelectAi selectAi = properties == null ? null : properties.selectAi();
|
BackofficeProperties.SelectAi selectAi = properties == null ? null : properties.selectAi();
|
||||||
if (selectAi == null || selectAi.profile() == null || selectAi.profile().isBlank()) {
|
if (selectAi == null || selectAi.profile() == null || selectAi.profile().isBlank()) {
|
||||||
|
|||||||
Reference in New Issue
Block a user