

















@@ -7,12 +7,20 @@ import {
77} from "../agents/model-catalog.js";
88import { resolveDefaultModelForAgent } from "../agents/model-selection.js";
99import { supportsModelTools } from "../agents/model-tool-support.js";
10+import { createBundleMcpToolRuntime } from "../agents/pi-bundle-mcp-tools.js";
11+import { applyFinalEffectiveToolPolicy } from "../agents/pi-embedded-runner/effective-tool-policy.js";
12+import { shouldCreateBundleMcpRuntimeForAttempt } from "../agents/pi-embedded-runner/run/attempt-tool-construction-plan.js";
1013import { createOpenClawCodingTools } from "../agents/pi-tools.js";
1114import { normalizeAgentRuntimeTools } from "../agents/runtime-plan/tools.js";
1215import { buildWorkspaceSkillStatus, type SkillStatusEntry } from "../agents/skills-status.js";
13-import { inspectRuntimeToolInputSchemas } from "../agents/tool-schema-projection.js";
16+import {
17+inspectRuntimeToolInputSchemas,
18+type RuntimeToolSchemaDiagnostic,
19+} from "../agents/tool-schema-projection.js";
20+import type { AnyAgentTool } from "../agents/tools/common.js";
1421import { collectUnavailableAgentSkills } from "../commands/doctor-skills-core.js";
1522import type { OpenClawConfig } from "../config/types.openclaw.js";
23+import { formatErrorMessage } from "../infra/errors.js";
1624import type { ProviderRuntimeModel } from "../plugins/provider-runtime-model.types.js";
1725import { getPluginToolMeta } from "../plugins/tools.js";
1826import type { HealthFinding } from "./health-checks.js";
@@ -56,6 +64,100 @@ function buildDoctorRuntimeModel(params: {
5664} as ProviderRuntimeModel;
5765}
586667+function toolSchemaDiagnosticToFinding(params: {
68+tools: readonly AnyAgentTool[];
69+diagnostic: RuntimeToolSchemaDiagnostic;
70+}): HealthFinding {
71+const tool = params.tools[params.diagnostic.toolIndex];
72+const pluginId = tool ? getPluginToolMeta(tool)?.pluginId : undefined;
73+const owner = pluginId ? ` from plugin ${pluginId}` : "";
74+const path =
75+pluginId === "bundle-mcp"
76+ ? "mcp.servers"
77+ : pluginId
78+ ? `plugins.entries.${pluginId}`
79+ : `tools.${params.diagnostic.toolName}`;
80+const fixHint =
81+pluginId === "bundle-mcp"
82+ ? "Disable or update the offending MCP server/tool so its parameters are a JSON object schema, then rerun doctor."
83+ : "Disable or update the offending plugin/tool so its parameters are a JSON object schema, then rerun doctor.";
84+return {
85+checkId: "core/doctor/runtime-tool-schemas",
86+severity: "error",
87+message: `Tool ${params.diagnostic.toolName}${owner} has an unsupported input schema for runtime projection.`,
88+ path,
89+target: params.diagnostic.toolName,
90+requirement: params.diagnostic.violations.join(", "),
91+ fixHint,
92+};
93+}
94+95+function collectToolSchemaFindings(tools: readonly AnyAgentTool[]): HealthFinding[] {
96+return inspectRuntimeToolInputSchemas(tools).map((diagnostic) =>
97+toolSchemaDiagnosticToFinding({
98+ tools,
99+ diagnostic,
100+}),
101+);
102+}
103+104+async function collectBundleMcpRuntimeToolSchemaFindings(params: {
105+cfg: OpenClawConfig;
106+agentId: string;
107+workspaceDir: string;
108+modelRef: { provider: string; model: string };
109+model: ProviderRuntimeModel;
110+}): Promise<readonly HealthFinding[]> {
111+if (
112+!shouldCreateBundleMcpRuntimeForAttempt({
113+toolsEnabled: true,
114+})
115+) {
116+return [];
117+}
118+119+let bundleRuntime: Awaited<ReturnType<typeof createBundleMcpToolRuntime>> | undefined;
120+try {
121+bundleRuntime = await createBundleMcpToolRuntime({
122+workspaceDir: params.workspaceDir,
123+cfg: params.cfg,
124+});
125+const activeBundleTools = applyFinalEffectiveToolPolicy({
126+bundledTools: bundleRuntime.tools,
127+config: params.cfg,
128+agentId: params.agentId,
129+modelProvider: params.modelRef.provider,
130+modelId: params.modelRef.model,
131+warn: () => {},
132+});
133+const normalizedTools = normalizeAgentRuntimeTools({
134+tools: activeBundleTools,
135+provider: params.modelRef.provider,
136+config: params.cfg,
137+workspaceDir: params.workspaceDir,
138+env: process.env,
139+modelId: params.modelRef.model,
140+modelApi: params.model.api,
141+model: params.model,
142+});
143+return collectToolSchemaFindings(normalizedTools);
144+} catch (error) {
145+return [
146+{
147+checkId: "core/doctor/runtime-tool-schemas",
148+severity: "error",
149+message: "Configured MCP tool schema validation could not load the runtime tool set.",
150+path: "mcp.servers",
151+requirement: formatErrorMessage(error),
152+fixHint:
153+"Fix or disable the offending MCP server, then rerun doctor before relying on assistant tool startup.",
154+},
155+];
156+} finally {
157+await bundleRuntime?.dispose();
158+}
159+}
160+59161export async function collectRuntimeToolSchemaFindings(
60162cfg: OpenClawConfig,
61163): Promise<readonly HealthFinding[]> {
@@ -97,19 +199,14 @@ export async function collectRuntimeToolSchemaFindings(
97199modelApi: model.api,
98200 model,
99201});
100-return inspectRuntimeToolInputSchemas(normalizedTools).map((diagnostic) => {
101-const tool = normalizedTools[diagnostic.toolIndex];
102-const pluginId = tool ? getPluginToolMeta(tool)?.pluginId : undefined;
103-const owner = pluginId ? ` from plugin ${pluginId}` : "";
104-return {
105-checkId: "core/doctor/runtime-tool-schemas",
106-severity: "error",
107-message: `Tool ${diagnostic.toolName}${owner} has an unsupported input schema for runtime projection.`,
108-path: pluginId ? `plugins.entries.${pluginId}` : `tools.${diagnostic.toolName}`,
109-target: diagnostic.toolName,
110-requirement: diagnostic.violations.join(", "),
111-fixHint:
112-"Disable or update the offending plugin/tool so its parameters are a JSON object schema, then rerun doctor.",
113-} satisfies HealthFinding;
114-});
202+return [
203+ ...collectToolSchemaFindings(normalizedTools),
204+ ...(await collectBundleMcpRuntimeToolSchemaFindings({
205+ cfg,
206+ agentId,
207+ workspaceDir,
208+ modelRef,
209+ model,
210+})),
211+];
115212}
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。