mirror of https://github.com/openclaw/openclaw.git
fix: narrow empty MCP tool schema normalization (#60176) (thanks @Bartok9)
This commit is contained in:
parent
19dbe00763
commit
57999f9965
|
|
@ -39,6 +39,7 @@ Docs: https://docs.openclaw.ai
|
|||
- Android/assistant: keep queued App Actions prompts pending when auto-send enqueue is rejected, so transient chat-health drops do not silently lose the assistant request. Thanks @obviyus.
|
||||
- Plugins/Google: separate OAuth CSRF state from PKCE code verifier during Gemini browser sign-in so state validation and token exchange use independent values. (#59116) Thanks @eleqtrizit.
|
||||
- Agents/subagents: honor `agents.defaults.subagents.allowAgents` for `sessions_spawn` and `agents_list`, so default cross-agent allowlists work without duplicating per-agent config. (#59944) Thanks @hclsys.
|
||||
- Agents/tools: normalize only truly empty MCP tool schemas to `{ type: "object", properties: {} }` so OpenAI accepts parameter-free tools without rewriting unrelated conditional schemas. (#60176) Thanks @Bartok9.
|
||||
- Plugins/browser: block SSRF redirect bypass by installing a real-time Playwright route handler before `page.goto()` so navigation to private/internal IPs is intercepted and aborted mid-redirect instead of checked post-hoc. (#58771) Thanks @pgondhi987.
|
||||
- Android/gateway: require TLS for non-loopback remote gateway endpoints while still allowing local loopback and emulator cleartext setup flows. (#58475) Thanks @eleqtrizit.
|
||||
- Exec/Windows: hide transient console windows for `runExec` and `runCommandWithTimeout` child-process launches, matching other Windows exec paths and stopping visible shell flashes during tool runs. (#59466) Thanks @lawrence3699.
|
||||
|
|
|
|||
|
|
@ -20,6 +20,20 @@ describe("normalizeToolParameters", () => {
|
|||
expect(parameters.properties).toEqual({});
|
||||
});
|
||||
|
||||
it("does not rewrite non-empty schemas that still lack type/properties", () => {
|
||||
const tool: AnyAgentTool = {
|
||||
name: "conditional",
|
||||
label: "conditional",
|
||||
description: "Conditional schema stays untouched",
|
||||
parameters: { allOf: [] },
|
||||
execute: vi.fn(),
|
||||
};
|
||||
|
||||
const normalized = normalizeToolParameters(tool);
|
||||
|
||||
expect(normalized.parameters).toEqual({ allOf: [] });
|
||||
});
|
||||
|
||||
it("injects properties:{} for type:object schemas missing properties (MCP no-param tools)", () => {
|
||||
const tool: AnyAgentTool = {
|
||||
name: "list_regions",
|
||||
|
|
|
|||
|
|
@ -133,11 +133,11 @@ export function normalizeToolParameterSchema(
|
|||
? "oneOf"
|
||||
: null;
|
||||
if (!variantKey) {
|
||||
// Handle truly empty schemas (no type, no properties, no unions) —
|
||||
// OpenAI requires `type: "object"` with `properties` for tool schemas.
|
||||
// MCP tools with parameter-free schemas may return `{}` or minimal objects.
|
||||
if (!("type" in schemaRecord) && !("properties" in schemaRecord)) {
|
||||
return applyProviderCleaning({ type: "object", properties: {}, ...schemaRecord });
|
||||
// Handle the proven MCP no-parameter case: a truly empty schema object.
|
||||
// Keep other non-empty shapes unchanged so we do not silently bless
|
||||
// unsupported top-level conditionals like `allOf`.
|
||||
if (Object.keys(schemaRecord).length === 0) {
|
||||
return applyProviderCleaning({ type: "object", properties: {} });
|
||||
}
|
||||
return schema;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue