fix: resolve $ref references in tool input schema properties
This commit is contained in:
parent
c7683b464a
commit
fb7fae1436
3 changed files with 65 additions and 7 deletions
|
|
@ -18,6 +18,7 @@ import {
|
||||||
generateDefaultValue,
|
generateDefaultValue,
|
||||||
isPropertyRequired,
|
isPropertyRequired,
|
||||||
normalizeUnionType,
|
normalizeUnionType,
|
||||||
|
resolveRef,
|
||||||
} from "@/utils/schemaUtils";
|
} from "@/utils/schemaUtils";
|
||||||
import {
|
import {
|
||||||
CompatibilityCallToolResult,
|
CompatibilityCallToolResult,
|
||||||
|
|
@ -90,14 +91,21 @@ const ToolsTab = ({
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const params = Object.entries(
|
const params = Object.entries(
|
||||||
selectedTool?.inputSchema.properties ?? [],
|
selectedTool?.inputSchema.properties ?? [],
|
||||||
).map(([key, value]) => [
|
).map(([key, value]) => {
|
||||||
key,
|
// First resolve any $ref references
|
||||||
generateDefaultValue(
|
const resolvedValue = resolveRef(
|
||||||
value as JsonSchemaType,
|
value as JsonSchemaType,
|
||||||
key,
|
|
||||||
selectedTool?.inputSchema as JsonSchemaType,
|
selectedTool?.inputSchema as JsonSchemaType,
|
||||||
),
|
);
|
||||||
]);
|
return [
|
||||||
|
key,
|
||||||
|
generateDefaultValue(
|
||||||
|
resolvedValue,
|
||||||
|
key,
|
||||||
|
selectedTool?.inputSchema as JsonSchemaType,
|
||||||
|
),
|
||||||
|
];
|
||||||
|
});
|
||||||
setParams(Object.fromEntries(params));
|
setParams(Object.fromEntries(params));
|
||||||
|
|
||||||
// Reset validation errors when switching tools
|
// Reset validation errors when switching tools
|
||||||
|
|
@ -154,7 +162,12 @@ const ToolsTab = ({
|
||||||
</p>
|
</p>
|
||||||
{Object.entries(selectedTool.inputSchema.properties ?? []).map(
|
{Object.entries(selectedTool.inputSchema.properties ?? []).map(
|
||||||
([key, value]) => {
|
([key, value]) => {
|
||||||
const prop = normalizeUnionType(value as JsonSchemaType);
|
// First resolve any $ref references
|
||||||
|
const resolvedValue = resolveRef(
|
||||||
|
value as JsonSchemaType,
|
||||||
|
selectedTool.inputSchema as JsonSchemaType,
|
||||||
|
);
|
||||||
|
const prop = normalizeUnionType(resolvedValue);
|
||||||
const inputSchema =
|
const inputSchema =
|
||||||
selectedTool.inputSchema as JsonSchemaType;
|
selectedTool.inputSchema as JsonSchemaType;
|
||||||
const required = isPropertyRequired(key, inputSchema);
|
const required = isPropertyRequired(key, inputSchema);
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,7 @@ export type JsonSchemaType = {
|
||||||
const?: JsonValue;
|
const?: JsonValue;
|
||||||
oneOf?: (JsonSchemaType | JsonSchemaConst)[];
|
oneOf?: (JsonSchemaType | JsonSchemaConst)[];
|
||||||
anyOf?: (JsonSchemaType | JsonSchemaConst)[];
|
anyOf?: (JsonSchemaType | JsonSchemaConst)[];
|
||||||
|
$ref?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type JsonObject = { [key: string]: JsonValue };
|
export type JsonObject = { [key: string]: JsonValue };
|
||||||
|
|
|
||||||
|
|
@ -145,6 +145,50 @@ export function isPropertyRequired(
|
||||||
return schema.required?.includes(propertyName) ?? false;
|
return schema.required?.includes(propertyName) ?? false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolves $ref references in JSON schema
|
||||||
|
* @param schema The schema that may contain $ref
|
||||||
|
* @param rootSchema The root schema to resolve references against
|
||||||
|
* @returns The resolved schema without $ref
|
||||||
|
*/
|
||||||
|
export function resolveRef(
|
||||||
|
schema: JsonSchemaType,
|
||||||
|
rootSchema: JsonSchemaType,
|
||||||
|
): JsonSchemaType {
|
||||||
|
if (!("$ref" in schema) || !schema.$ref) {
|
||||||
|
return schema;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ref = schema.$ref;
|
||||||
|
|
||||||
|
// Handle simple #/properties/name references
|
||||||
|
if (ref.startsWith("#/")) {
|
||||||
|
const path = ref.substring(2).split("/");
|
||||||
|
let current: unknown = rootSchema;
|
||||||
|
|
||||||
|
for (const segment of path) {
|
||||||
|
if (
|
||||||
|
current &&
|
||||||
|
typeof current === "object" &&
|
||||||
|
current !== null &&
|
||||||
|
segment in current
|
||||||
|
) {
|
||||||
|
current = (current as Record<string, unknown>)[segment];
|
||||||
|
} else {
|
||||||
|
// If reference cannot be resolved, return the original schema
|
||||||
|
console.warn(`Could not resolve $ref: ${ref}`);
|
||||||
|
return schema;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return current as JsonSchemaType;
|
||||||
|
}
|
||||||
|
|
||||||
|
// For other types of references, return the original schema
|
||||||
|
console.warn(`Unsupported $ref format: ${ref}`);
|
||||||
|
return schema;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Normalizes union types (like string|null from FastMCP) to simple types for form rendering
|
* Normalizes union types (like string|null from FastMCP) to simple types for form rendering
|
||||||
* @param schema The JSON schema to normalize
|
* @param schema The JSON schema to normalize
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue