semantic-prompt-mcp
Version:
MCP server for semantic prompt framework - NLP-inspired adaptive reasoning engine for LLM orchestration
141 lines • 4.83 kB
JavaScript
/**
* Simple Parameter Normalizer
* Handles various input formats to prevent errors in chain_of_thought tool
* Follows KISS principle - only does what's necessary
*/
export class ParameterNormalizer {
/**
* Main normalization function for chain_of_thought parameters
* Handles XML-like strings, malformed JSON, and ensures correct types
*/
normalizeChainOfThoughtParams(input) {
if (!input || typeof input !== 'object') {
return input;
}
const result = { ...input };
// Handle commandSelection if it exists
if (result.commandSelection) {
result.commandSelection = this.normalizeCommandSelection(result.commandSelection);
}
// Handle agentSelection if it exists
if (result.agentSelection) {
result.agentSelection = this.normalizeAgentSelection(result.agentSelection);
}
// Ensure numeric types
if (result.thoughtNumber !== undefined) {
result.thoughtNumber = this.toNumber(result.thoughtNumber);
}
if (result.totalThoughts !== undefined) {
result.totalThoughts = this.toNumber(result.totalThoughts);
}
if (result.revisesThought !== undefined) {
result.revisesThought = this.toNumber(result.revisesThought);
}
if (result.branchFromThought !== undefined) {
result.branchFromThought = this.toNumber(result.branchFromThought);
}
// Ensure boolean types
if (result.nextThoughtNeeded !== undefined) {
result.nextThoughtNeeded = this.toBoolean(result.nextThoughtNeeded);
}
if (result.isRevision !== undefined) {
result.isRevision = this.toBoolean(result.isRevision);
}
if (result.needsMoreThoughts !== undefined) {
result.needsMoreThoughts = this.toBoolean(result.needsMoreThoughts);
}
return result;
}
/**
* Normalizes commandSelection parameter
* Handles XML strings like '<parameter name="type">command</parameter>'
*/
normalizeCommandSelection(input) {
if (!input)
return input;
// If already an object with correct structure, return as-is
if (typeof input === 'object' && 'type' in input) {
return input;
}
// If it's a string, try to parse it
if (typeof input === 'string') {
// Handle XML-like format
if (input.includes('<parameter')) {
const result = {};
// Extract type
const typeMatch = input.match(/name=["']type["']>([^<]+)</);
if (typeMatch) {
result.type = typeMatch[1].trim();
}
// Extract command
const commandMatch = input.match(/name=["']command["']>([^<]+)</);
if (commandMatch) {
result.command = commandMatch[1].trim();
}
// Extract reason
const reasonMatch = input.match(/name=["']reason["']>([^<]+)</);
if (reasonMatch) {
result.reason = reasonMatch[1].trim();
}
return result;
}
// Try to parse as JSON
try {
return JSON.parse(input);
}
catch {
// If not JSON, return as-is
return input;
}
}
return input;
}
/**
* Normalizes agentSelection parameter
*/
normalizeAgentSelection(input) {
if (!input)
return input;
// If already an object with correct structure, return as-is
if (typeof input === 'object' && 'type' in input) {
return input;
}
// If it's a string, try to parse it
if (typeof input === 'string') {
try {
return JSON.parse(input);
}
catch {
return input;
}
}
return input;
}
/**
* Converts value to number
*/
toNumber(value) {
if (typeof value === 'number')
return value;
if (typeof value === 'string') {
const num = parseInt(value, 10);
if (!isNaN(num))
return num;
}
return value;
}
/**
* Converts value to boolean
*/
toBoolean(value) {
if (typeof value === 'boolean')
return value;
if (typeof value === 'string') {
return value.toLowerCase() === 'true';
}
return Boolean(value);
}
}
// Export singleton for convenience
export const parameterNormalizer = new ParameterNormalizer();
//# sourceMappingURL=parameterNormalizer.js.map