




















@@ -58,6 +58,34 @@ function isOptionalToolAllowed(params: {
5858return params.allowlist.has("group:plugins");
5959}
606061+function isRecord(value: unknown): value is Record<string, unknown> {
62+return Boolean(value && typeof value === "object" && !Array.isArray(value));
63+}
64+65+function readPluginToolName(tool: unknown): string {
66+if (!isRecord(tool)) {
67+return "";
68+}
69+return typeof tool.name === "string" ? tool.name.trim() : "";
70+}
71+72+function describeMalformedPluginTool(tool: unknown): string | undefined {
73+if (!isRecord(tool)) {
74+return "tool must be an object";
75+}
76+const name = readPluginToolName(tool);
77+if (!name) {
78+return "missing non-empty name";
79+}
80+if (typeof tool.execute !== "function") {
81+return `${name} missing execute function`;
82+}
83+if (!isRecord(tool.parameters)) {
84+return `${name} missing parameters object`;
85+}
86+return undefined;
87+}
88+6189function resolvePluginToolRegistry(params: {
6290loadOptions: PluginLoadOptions;
6391allowGatewaySubagentBinding?: boolean;
@@ -146,11 +174,11 @@ export function resolvePluginTools(params: {
146174}
147175continue;
148176}
149-const listRaw = Array.isArray(resolved) ? resolved : [resolved];
177+const listRaw: unknown[] = Array.isArray(resolved) ? resolved : [resolved];
150178const list = entry.optional
151179 ? listRaw.filter((tool) =>
152180isOptionalToolAllowed({
153-toolName: tool.name,
181+toolName: readPluginToolName(tool),
154182pluginId: entry.pluginId,
155183 allowlist,
156184}),
@@ -160,7 +188,20 @@ export function resolvePluginTools(params: {
160188continue;
161189}
162190const nameSet = new Set<string>();
163-for (const tool of list) {
191+for (const toolRaw of list) {
192+const malformedReason = describeMalformedPluginTool(toolRaw);
193+if (malformedReason) {
194+const message = `plugin tool is malformed (${entry.pluginId}): ${malformedReason}`;
195+context.logger.error(message);
196+registry.diagnostics.push({
197+level: "error",
198+pluginId: entry.pluginId,
199+source: entry.source,
200+ message,
201+});
202+continue;
203+}
204+const tool = toolRaw as AnyAgentTool;
164205if (nameSet.has(tool.name) || existing.has(tool.name)) {
165206const message = `plugin tool name conflict (${entry.pluginId}): ${tool.name}`;
166207if (!params.suppressNameConflicts) {
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。