


























@@ -107,17 +107,19 @@ function buildPluginGroups(params: {
107107suppressNameConflicts: true,
108108allowGatewaySubagentBinding: true,
109109});
110+const activeRegistry = getActivePluginRegistry();
110111const groups = new Map<string, ToolCatalogGroup>();
111112// Key metadata by plugin ownership and tool name so we only project metadata that
112113// was registered BY the tool's owning plugin. Without this scoping, plugin-X
113114// could override the catalog label/description/risk/tags for another plugin's
114115// tool by registering metadata with the same toolName.
115116const pluginToolMetadata = new Map(
116-(getActivePluginRegistry()?.toolMetadata ?? []).map((entry) => [
117+(activeRegistry?.toolMetadata ?? []).map((entry) => [
117118buildPluginToolMetadataKey(entry.pluginId, entry.metadata.toolName),
118119entry.metadata,
119120]),
120121);
122+const seenToolIds = new Set<string>();
121123for (const tool of pluginTools) {
122124const meta = getPluginToolMeta(tool);
123125const pluginId = meta?.pluginId ?? "plugin";
@@ -153,8 +155,46 @@ function buildPluginGroups(params: {
153155tags: ownedMetadata?.tags,
154156defaultProfiles: [],
155157});
158+seenToolIds.add(tool.name);
156159groups.set(groupId, existing);
157160}
161+for (const entry of activeRegistry?.tools ?? []) {
162+const names = entry.names.length > 0 ? entry.names : (entry.declaredNames ?? []);
163+for (const name of names) {
164+if (seenToolIds.has(name) || params.existingToolNames.has(name)) {
165+continue;
166+}
167+const groupId = `plugin:${entry.pluginId}`;
168+const existing =
169+groups.get(groupId) ??
170+({
171+id: groupId,
172+label: entry.pluginName ?? entry.pluginId,
173+source: "plugin",
174+pluginId: entry.pluginId,
175+tools: [],
176+} as ToolCatalogGroup);
177+const ownedMetadata = pluginToolMetadata.get(
178+buildPluginToolMetadataKey(entry.pluginId, name),
179+);
180+existing.tools.push({
181+id: name,
182+label: normalizeOptionalString(ownedMetadata?.displayName) ?? name,
183+description:
184+summarizeToolDescriptionText({
185+rawDescription: ownedMetadata?.description,
186+}) || `Plugin tool from ${entry.pluginName ?? entry.pluginId}`,
187+source: "plugin",
188+pluginId: entry.pluginId,
189+optional: entry.optional,
190+risk: ownedMetadata?.risk,
191+tags: ownedMetadata?.tags,
192+defaultProfiles: [],
193+});
194+seenToolIds.add(name);
195+groups.set(groupId, existing);
196+}
197+}
158198return [...groups.values()]
159199.map((group) =>
160200Object.assign({}, group, { tools: group.tools.toSorted((a, b) => a.id.localeCompare(b.id)) }),
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。