mirror of
https://gitee.com/mateos/mateclaw.git
synced 2026-09-15 20:08:18 +08:00
feat(skill-mcp): expose readable display name alongside prefixed MCP tool names
Add a parallel effectiveAllowedToolsDisplay field on the runtime status payload so the SkillMarket detail drawer can render mcp_<server>_<slug>_<hash> with the raw tool name appended in parentheses, while leaving the original prefixed list unchanged for any caller that needs the machine name. McpSkillBridge#decorateToolNameForDisplay reverses a prefixed name via the per-server cached tool list; the frontend prefers the new display field and falls back to effectiveAllowedTools when the field is absent.
This commit is contained in:
parent
adddf0402a
commit
18148aa724
@ -1,6 +1,8 @@
|
|||||||
package vip.mate.skill.controller;
|
package vip.mate.skill.controller;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
@ -57,6 +59,7 @@ public class SkillController {
|
|||||||
private final AgentBindingService agentBindingService;
|
private final AgentBindingService agentBindingService;
|
||||||
private final vip.mate.skill.mcp.McpSkillBridge mcpSkillBridge;
|
private final vip.mate.skill.mcp.McpSkillBridge mcpSkillBridge;
|
||||||
private final vip.mate.skill.acp.AcpSkillBridge acpSkillBridge;
|
private final vip.mate.skill.acp.AcpSkillBridge acpSkillBridge;
|
||||||
|
private final ObjectMapper objectMapper;
|
||||||
|
|
||||||
@Operation(summary = "获取技能分页列表(RFC-042 §2.1)")
|
@Operation(summary = "获取技能分页列表(RFC-042 §2.1)")
|
||||||
@GetMapping
|
@GetMapping
|
||||||
@ -392,8 +395,34 @@ public class SkillController {
|
|||||||
|
|
||||||
@Operation(summary = "获取所有技能的运行时解析状态(管理页面使用)")
|
@Operation(summary = "获取所有技能的运行时解析状态(管理页面使用)")
|
||||||
@GetMapping("/runtime/status")
|
@GetMapping("/runtime/status")
|
||||||
public R<List<ResolvedSkill>> getRuntimeStatus() {
|
public R<List<Map<String, Object>>> getRuntimeStatus() {
|
||||||
return R.ok(skillRuntimeService.resolveAllSkillsStatus());
|
List<ResolvedSkill> skills = skillRuntimeService.resolveAllSkillsStatus();
|
||||||
|
return R.ok(skills.stream().map(this::toRuntimeStatusView).toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform a display transformation on `effectiveAllowedTools` (returned to the frontend),
|
||||||
|
* and store the transformed result in `effectiveAllowedToolsDisplay`.
|
||||||
|
* In addition to displaying the tool name in the format `mcp_<serverId>_<slug>_<hash6>`,
|
||||||
|
* also display the original MCP tool name in parentheses immediately following it.
|
||||||
|
*
|
||||||
|
* @param skill
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private Map<String, Object> toRuntimeStatusView(ResolvedSkill skill) {
|
||||||
|
Map<String, Object> view = objectMapper.convertValue(
|
||||||
|
skill,
|
||||||
|
new TypeReference<Map<String, Object>>() {}
|
||||||
|
);
|
||||||
|
|
||||||
|
if ("mcp".equalsIgnoreCase(skill.getSource())) {
|
||||||
|
List<String> displayTools = skill.getEffectiveAllowedTools().stream()
|
||||||
|
.map(mcpSkillBridge::decorateToolNameForDisplay)
|
||||||
|
.toList();
|
||||||
|
view.put("effectiveAllowedToolsDisplay", displayTools);
|
||||||
|
}
|
||||||
|
|
||||||
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "刷新 active skills 缓存,resync=true 时同步内置技能到 workspace")
|
@Operation(summary = "刷新 active skills 缓存,resync=true 时同步内置技能到 workspace")
|
||||||
|
|||||||
@ -121,6 +121,26 @@ public class McpSkillBridge {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a "display-only" method to reverse-lookup a prefixed name back to its raw name.
|
||||||
|
*
|
||||||
|
* @param prefixedName
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public String decorateToolNameForDisplay(String prefixedName) {
|
||||||
|
McpToolNameResolver.ParsedRef ref = McpToolNameResolver.parse(prefixedName);
|
||||||
|
if (ref == null) return prefixedName;
|
||||||
|
|
||||||
|
McpServerEntity server = mcpServerService.getById(ref.serverId());
|
||||||
|
for (String raw : readToolRawNames(server)) {
|
||||||
|
String rebuilt = McpToolNameResolver.prefixedName(ref.serverId(), raw);
|
||||||
|
if (rebuilt.equals(prefixedName)) {
|
||||||
|
return prefixedName + " (" + raw + ")";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return prefixedName;
|
||||||
|
}
|
||||||
|
|
||||||
private List<McpServerEntity> listEnabledServers() {
|
private List<McpServerEntity> listEnabledServers() {
|
||||||
try {
|
try {
|
||||||
return mcpServerService.listEnabled();
|
return mcpServerService.listEnabled();
|
||||||
|
|||||||
@ -311,6 +311,8 @@ export interface SkillRuntimeStatus {
|
|||||||
activeFeatures?: string[]
|
activeFeatures?: string[]
|
||||||
/** Tools advertised to the LLM after feature filtering */
|
/** Tools advertised to the LLM after feature filtering */
|
||||||
effectiveAllowedTools?: string[]
|
effectiveAllowedTools?: string[]
|
||||||
|
/** Human-readable tool names for display after feature filtering */
|
||||||
|
effectiveAllowedToolsDisplay?: string[]
|
||||||
}
|
}
|
||||||
|
|
||||||
/** RFC-090 §14.6 — typed view onto manifest_json */
|
/** RFC-090 §14.6 — typed view onto manifest_json */
|
||||||
|
|||||||
@ -807,7 +807,9 @@ const detailManifest = computed(() => detailRuntime.value?.manifest ?? null)
|
|||||||
const detailManifestPretty = computed(() =>
|
const detailManifestPretty = computed(() =>
|
||||||
detailManifest.value ? JSON.stringify(detailManifest.value, null, 2) : '',
|
detailManifest.value ? JSON.stringify(detailManifest.value, null, 2) : '',
|
||||||
)
|
)
|
||||||
const detailEffectiveTools = computed(() => detailRuntime.value?.effectiveAllowedTools || [])
|
const detailEffectiveTools = computed(() =>
|
||||||
|
detailRuntime.value?.effectiveAllowedToolsDisplay || detailRuntime.value?.effectiveAllowedTools || [],
|
||||||
|
)
|
||||||
const detailToolsCount = computed(() => detailEffectiveTools.value.length)
|
const detailToolsCount = computed(() => detailEffectiveTools.value.length)
|
||||||
const detailFeatures = computed(() => {
|
const detailFeatures = computed(() => {
|
||||||
const m = detailManifest.value
|
const m = detailManifest.value
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user