feat(manifest): expose tool usage guidance
All checks were successful
Deploy to OCIWP / deploy (push) Successful in 3m17s

This commit is contained in:
jade
2026-08-17 15:11:46 +09:00
parent 0816c0ff0c
commit 8bd9b9e922
3 changed files with 18 additions and 3 deletions

View File

@@ -1,5 +1,6 @@
package io.shinhanlife.dap.lib.manifest; package io.shinhanlife.dap.lib.manifest;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.List; import java.util.List;
/** Operational metadata exposed by the Tool Service manifest. */ /** Operational metadata exposed by the Tool Service manifest. */
@@ -11,5 +12,8 @@ public record ToolManifestMeta(
List<String> tags, List<String> tags,
String legacyInterfaceId, String legacyInterfaceId,
List<String> requiredEnvKeys, List<String> requiredEnvKeys,
String ownerOrg) { String ownerOrg,
@JsonProperty("when_to_use") String whenToUse,
@JsonProperty("when_not_to_use") String whenNotToUse,
@JsonProperty("io_limits") String ioLimits) {
} }

View File

@@ -68,7 +68,8 @@ public class ToolManifestService {
tool.getTimeoutMillis() == null ? DEFAULT_TIMEOUT_MILLIS : tool.getTimeoutMillis(), tool.getTimeoutMillis() == null ? DEFAULT_TIMEOUT_MILLIS : tool.getTimeoutMillis(),
tool.getEnabled() == null || tool.getEnabled(), tool.getEnabled() == null || tool.getEnabled(),
defaultList(tool.getExampleQueries()), defaultList(tool.getTags()), defaultList(tool.getExampleQueries()), defaultList(tool.getTags()),
tool.getMciServiceId(), defaultList(tool.getRequiredEnvKeys()), tool.getOwnerOrg())); tool.getMciServiceId(), defaultList(tool.getRequiredEnvKeys()), tool.getOwnerOrg(),
tool.getWhenToUse(), tool.getWhenNotToUse(), tool.getIoLimits()));
} }
private void validate(List<ToolManifestItem> tools) { private void validate(List<ToolManifestItem> tools) {

View File

@@ -16,7 +16,7 @@ class ToolManifestServiceTest {
private final ObjectMapper objectMapper = new ObjectMapper(); private final ObjectMapper objectMapper = new ObjectMapper();
@Test @Test
void buildsStandardManifestAndDerivesRevisionFromToolDefinition() { void buildsStandardManifestAndDerivesRevisionFromToolDefinition() throws Exception {
McpProperties properties = manifestProperties("insurance-processing", "processing."); McpProperties properties = manifestProperties("insurance-processing", "processing.");
ToolManifestService service = new ToolManifestService( ToolManifestService service = new ToolManifestService(
() -> List.of(tool("processing.contract.inquiry", "1.2.0", 3000)), objectMapper, properties); () -> List.of(tool("processing.contract.inquiry", "1.2.0", 3000)), objectMapper, properties);
@@ -35,6 +35,13 @@ class ToolManifestServiceTest {
assertTrue(item.annotations().readOnlyHint()); assertTrue(item.annotations().readOnlyHint());
assertEquals("1.2.0", item.meta().version()); assertEquals("1.2.0", item.meta().version());
assertEquals(3000, item.meta().timeoutMillis()); assertEquals(3000, item.meta().timeoutMillis());
assertEquals("when to use", item.meta().whenToUse());
assertEquals("when not to use", item.meta().whenNotToUse());
assertEquals("io limits", item.meta().ioLimits());
String payload = objectMapper.writeValueAsString(manifest);
assertTrue(payload.contains("\"when_to_use\":\"when to use\""));
assertTrue(payload.contains("\"when_not_to_use\":\"when not to use\""));
assertTrue(payload.contains("\"io_limits\":\"io limits\""));
assertEquals(List.of("계약 상태를 알려줘", "내 계약을 조회해줘", "계약번호로 찾아줘"), assertEquals(List.of("계약 상태를 알려줘", "내 계약을 조회해줘", "계약번호로 찾아줘"),
item.meta().exampleQueries()); item.meta().exampleQueries());
} }
@@ -91,6 +98,9 @@ class ToolManifestServiceTest {
.exampleQueries(List.of("계약 상태를 알려줘", "내 계약을 조회해줘", "계약번호로 찾아줘")) .exampleQueries(List.of("계약 상태를 알려줘", "내 계약을 조회해줘", "계약번호로 찾아줘"))
.tags(List.of("계약")) .tags(List.of("계약"))
.ownerOrg("MCP_TOOL") .ownerOrg("MCP_TOOL")
.whenToUse("when to use")
.whenNotToUse("when not to use")
.ioLimits("io limits")
.parametersSchema(Map.of("type", "object", "properties", Map.of("contractNo", Map.of("type", "string")), .parametersSchema(Map.of("type", "object", "properties", Map.of("contractNo", Map.of("type", "string")),
"required", List.of("contractNo"), "additionalProperties", false)) "required", List.of("contractNo"), "additionalProperties", false))
.semver(version) .semver(version)