feat: standardize tool names and http clients
Some checks failed
Deploy to OCIWP / deploy (push) Has been cancelled

This commit is contained in:
jade
2026-08-11 17:27:16 +09:00
parent 95a8ae3a1b
commit 9c420dc5ab
50 changed files with 726 additions and 221 deletions

View File

@@ -56,6 +56,8 @@ public class ScaffoldingController {
try {
String baseName = req.get("baseName");
String interfaceId = req.get("interfaceId");
String title = req.get("title");
if (title == null || title.isBlank()) title = baseName;
String description = req.get("description");
String group = req.getOrDefault("categoryKey", req.getOrDefault("group", "COMMON"));
String routingType = req.getOrDefault("routingType", "HTTP");
@@ -66,6 +68,7 @@ public class ScaffoldingController {
if (date == null || date.trim().isEmpty()) date = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy.MM.dd"));
boolean register = Boolean.parseBoolean(req.getOrDefault("register", "true"));
String clientSystemCode = req.get("clientSystemCode");
String httpApiName = req.getOrDefault("httpApiName", "sample");
String inputSchemaResource = req.get("inputSchemaResource");
String outputSchemaResource = req.get("outputSchemaResource");
List<ToolScaffolder.FieldDefinition> inputFields = parseFields(req.get("inputFields"));
@@ -74,7 +77,7 @@ public class ScaffoldingController {
inputFields = List.of(new ToolScaffolder.FieldDefinition("query", "String", "Search query", "example", false));
}
return ToolScaffolder.scaffold(baseName, interfaceId, description, group, routingType, moduleName, author, date, register, clientSystemCode, inputSchemaResource, outputSchemaResource, inputFields, outputFields);
return ToolScaffolder.scaffold(baseName, interfaceId, title, description, group, routingType, moduleName, author, date, register, clientSystemCode, inputSchemaResource, outputSchemaResource, inputFields, outputFields, httpApiName);
} catch (Exception e) {
return "오류 발생: " + e.getMessage();
}

View File

@@ -455,11 +455,17 @@
<input type="text" class="form-control" name="interfaceId" placeholder="e.g. EXCH_001" required>
</div>
</div>
<div class="mb-3">
<label class="form-label">Description (LLM Prompt)</label>
<input type="text" class="form-control" name="description" placeholder="e.g. Fetch current exchange rates for customers." required>
<div class="input-hint">Critical for AI agent intent matching. Be descriptive.</div>
<div class="row mb-3">
<div class="col-md-5">
<label class="form-label">Tool Title (Display Name)</label>
<input type="text" class="form-control" name="title" placeholder="e.g. Employee Information Search" required>
<div class="input-hint">Short, human-facing name shown in tool lists and the Portal.</div>
</div>
<div class="col-md-7 mt-3 mt-md-0">
<label class="form-label">Description (LLM Prompt)</label>
<input type="text" class="form-control" name="description" placeholder="e.g. Use when the user asks to find an employee by employee ID." required>
<div class="input-hint">LLM call guidance: purpose, when to use it, required conditions, and exclusions.</div>
</div>
</div>
<div class="row mb-3">
@@ -539,6 +545,11 @@
<div class="row mb-4">
<div class="col-md-6">
<label class="form-label">HTTP API Name (Glow api-list)</label>
<input type="text" class="form-control" name="httpApiName" value="sample" pattern="^[a-zA-Z0-9_-]+$" placeholder="e.g. employee">
<div class="input-hint">HTTP only. Must match glow.communication.http.api-list[].name; URL and method are read from Glow YAML.</div>
</div>
<div class="col-md-6 mt-3 mt-md-0">
<label class="form-label">Target System Code (MCI Only)</label>
<input type="text" class="form-control" name="clientSystemCode" pattern="^[a-zA-Z]{4}$" maxlength="4" minlength="4" placeholder="e.g. cfpa" oninput="this.value = this.value.toLowerCase()">
<div class="input-hint">Required for MCI Protocol (4 letters).</div>

View File

@@ -18,6 +18,8 @@ package io.shinhanlife.dap.mcg.tool.large;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import io.shinhanlife.dap.mcg.config.McpGatewayProperties;
import io.shinhanlife.dap.mcc.dto.ToolMetadata;
import java.util.Map;
import io.shinhanlife.dap.mcg.resilience.ToolExecutionException;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -42,7 +44,7 @@ class PaginationRequestValidatorTest {
@Test
void shouldSetDefaultPageSizeIfMissing() {
ObjectNode arguments = json.createObjectNode();
ObjectNode normalized = validator.normalize(arguments);
ObjectNode normalized = validator.normalize(paginationTool(), arguments);
assertEquals(100, normalized.get("pageSize").asInt());
}
@@ -51,7 +53,7 @@ class PaginationRequestValidatorTest {
void shouldKeepValidPageSize() {
ObjectNode arguments = json.createObjectNode();
arguments.put("pageSize", 200);
ObjectNode normalized = validator.normalize(arguments);
ObjectNode normalized = validator.normalize(paginationTool(), arguments);
assertEquals(200, normalized.get("pageSize").asInt());
}
@@ -62,7 +64,7 @@ class PaginationRequestValidatorTest {
arguments.put("pageSize", 600);
ToolExecutionException exception = assertThrows(ToolExecutionException.class, () -> {
validator.normalize(arguments);
validator.normalize(paginationTool(), arguments);
});
assertTrue(exception.getMessage().contains("PAGE_SIZE_EXCEEDED"));
@@ -74,9 +76,14 @@ class PaginationRequestValidatorTest {
arguments.put("cursor", "a".repeat(3000));
ToolExecutionException exception = assertThrows(ToolExecutionException.class, () -> {
validator.normalize(arguments);
validator.normalize(paginationTool(), arguments);
});
assertTrue(exception.getMessage().contains("INVALID_CURSOR"));
}
private ToolMetadata paginationTool() {
return ToolMetadata.builder()
.parametersSchema(Map.of("properties", Map.of("pageSize", Map.of())))
.build();
}
}