Fix: Convert form parameters to schema-defined types before MCP tool calls (#397)

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: samanhappy <2755122+samanhappy@users.noreply.github.com>
This commit is contained in:
Copilot
2025-10-29 18:41:23 +08:00
committed by GitHub
parent 6268a02c0e
commit 7e570a900a
5 changed files with 387 additions and 150 deletions

View File

@@ -1,73 +1,7 @@
// Simple unit test to validate the type conversion logic
describe('Parameter Type Conversion Logic', () => {
// Extract the conversion function for testing
function convertQueryParametersToTypes(
queryParams: Record<string, any>,
inputSchema: Record<string, any>
): Record<string, any> {
if (!inputSchema || typeof inputSchema !== 'object' || !inputSchema.properties) {
return queryParams;
}
const convertedParams: Record<string, any> = {};
const properties = inputSchema.properties;
for (const [key, value] of Object.entries(queryParams)) {
const propDef = properties[key];
if (!propDef || typeof propDef !== 'object') {
// No schema definition found, keep as is
convertedParams[key] = value;
continue;
}
const propType = propDef.type;
try {
switch (propType) {
case 'integer':
case 'number':
// Convert string to number
if (typeof value === 'string') {
const numValue = propType === 'integer' ? parseInt(value, 10) : parseFloat(value);
convertedParams[key] = isNaN(numValue) ? value : numValue;
} else {
convertedParams[key] = value;
}
break;
case 'boolean':
// Convert string to boolean
if (typeof value === 'string') {
convertedParams[key] = value.toLowerCase() === 'true' || value === '1';
} else {
convertedParams[key] = value;
}
break;
case 'array':
// Handle array conversion if needed (e.g., comma-separated strings)
if (typeof value === 'string' && value.includes(',')) {
convertedParams[key] = value.split(',').map(item => item.trim());
} else {
convertedParams[key] = value;
}
break;
default:
// For string and other types, keep as is
convertedParams[key] = value;
break;
}
} catch (error) {
// If conversion fails, keep the original value
console.warn(`Failed to convert parameter '${key}' to type '${propType}':`, error);
convertedParams[key] = value;
}
}
return convertedParams;
}
import { convertParametersToTypes } from '../../src/utils/parameterConversion.js';
// Integration tests for OpenAPI controller's parameter type conversion
describe('OpenAPI Controller - Parameter Type Conversion Integration', () => {
test('should convert integer parameters correctly', () => {
const queryParams = {
limit: '5',
@@ -84,7 +18,7 @@ describe('Parameter Type Conversion Logic', () => {
}
};
const result = convertQueryParametersToTypes(queryParams, inputSchema);
const result = convertParametersToTypes(queryParams, inputSchema);
expect(result).toEqual({
limit: 5, // Converted to integer
@@ -107,7 +41,7 @@ describe('Parameter Type Conversion Logic', () => {
}
};
const result = convertQueryParametersToTypes(queryParams, inputSchema);
const result = convertParametersToTypes(queryParams, inputSchema);
expect(result).toEqual({
price: 19.99,
@@ -133,7 +67,7 @@ describe('Parameter Type Conversion Logic', () => {
}
};
const result = convertQueryParametersToTypes(queryParams, inputSchema);
const result = convertParametersToTypes(queryParams, inputSchema);
expect(result).toEqual({
enabled: true,
@@ -157,7 +91,7 @@ describe('Parameter Type Conversion Logic', () => {
}
};
const result = convertQueryParametersToTypes(queryParams, inputSchema);
const result = convertParametersToTypes(queryParams, inputSchema);
expect(result).toEqual({
tags: ['tag1', 'tag2', 'tag3'],
@@ -171,7 +105,7 @@ describe('Parameter Type Conversion Logic', () => {
name: 'test'
};
const result = convertQueryParametersToTypes(queryParams, {});
const result = convertParametersToTypes(queryParams, {});
expect(result).toEqual({
limit: '5', // Should remain as string
@@ -192,7 +126,7 @@ describe('Parameter Type Conversion Logic', () => {
}
};
const result = convertQueryParametersToTypes(queryParams, inputSchema);
const result = convertParametersToTypes(queryParams, inputSchema);
expect(result).toEqual({
limit: 5, // Converted based on schema
@@ -214,7 +148,7 @@ describe('Parameter Type Conversion Logic', () => {
}
};
const result = convertQueryParametersToTypes(queryParams, inputSchema);
const result = convertParametersToTypes(queryParams, inputSchema);
expect(result).toEqual({
limit: 'not-a-number', // Should remain as string when conversion fails