@juspay/neurolink
Version:
Universal AI Development Platform with working MCP integration, multi-provider support, and professional CLI. Built-in tools operational, 58+ external MCP servers discoverable. Connect to filesystem, GitHub, database operations, and more. Build, test, and
428 lines (427 loc) • 15 kB
JavaScript
/**
* Object Transformation Utilities
* Centralizes repeated object transformation patterns to improve code reuse and maintainability
*/
// ============================================================================
// TOOL EXECUTION TRANSFORMATIONS
// ============================================================================
/**
* Transform tool execution results from AI SDK format to NeuroLink GenerateResult format
* Handles both single execution and array formats with robust type checking
*
* @param toolExecutions - Array of tool execution results from AI SDK (optional)
* @returns Array of standardized tool execution objects with name, input, output, and duration
*
* @example
* ```typescript
* const executions = transformToolExecutions([
* { name: "calculator", input: { a: 5, b: 3 }, output: 8, duration: 150 }
* ]);
* // Returns: [{ name: "calculator", input: { a: 5, b: 3 }, output: 8, duration: 150 }]
* ```
*/
export function transformToolExecutions(toolExecutions) {
if (!toolExecutions || !Array.isArray(toolExecutions)) {
return [];
}
return toolExecutions.map((te, index) => {
const teRecord = te;
// Enhanced tool name extraction with multiple fallback strategies
let toolName = teRecord.name ||
teRecord.toolName ||
teRecord.tool ||
"";
// If still no name, try to extract from nested objects
if (!toolName &&
teRecord.toolCall &&
typeof teRecord.toolCall === "object") {
const toolCall = teRecord.toolCall;
toolName =
toolCall.name || toolCall.toolName || "";
}
// Last resort: use index-based fallback to avoid "Unknown Tool"
if (!toolName) {
toolName = `tool_execution_${index}`;
}
// Enhanced input extraction
let input = teRecord.input ||
teRecord.parameters ||
teRecord.args ||
{};
// Extract input from nested toolCall if available
if (Object.keys(input).length === 0 &&
teRecord.toolCall &&
typeof teRecord.toolCall === "object") {
const toolCall = teRecord.toolCall;
input =
toolCall.input ||
toolCall.parameters ||
toolCall.args ||
{};
}
// Enhanced output extraction with success indication
let output = teRecord.output ||
teRecord.result ||
teRecord.response ||
"success";
// Enhanced duration extraction
let duration = teRecord.duration ??
teRecord.executionTime ??
teRecord.responseTime ??
0;
return {
name: toolName,
input: input,
output: output,
duration: duration,
};
});
}
/**
* Transform tool execution results from AI SDK format to internal format (for MCP generation)
* Used in tryMCPGeneration method
*/
export function transformToolExecutionsForMCP(toolExecutions) {
if (!toolExecutions || !Array.isArray(toolExecutions)) {
return [];
}
return toolExecutions.map((te, index) => {
const teRecord = te;
// Enhanced tool name extraction matching the main function
let toolName = teRecord.name ||
teRecord.toolName ||
teRecord.tool ||
"";
// Try nested toolCall extraction
if (!toolName &&
teRecord.toolCall &&
typeof teRecord.toolCall === "object") {
const toolCall = teRecord.toolCall;
toolName =
toolCall.name || toolCall.toolName || "";
}
// Fallback to avoid empty names
if (!toolName) {
toolName = `mcp_tool_execution_${index}`;
}
// Enhanced execution time extraction
let executionTime = teRecord.duration ??
teRecord.executionTime ??
teRecord.responseTime ??
0;
// Enhanced success detection - check for actual success indicators
let success = true; // Default to true
// Check for explicit success/error indicators
if (teRecord.success !== undefined) {
success = Boolean(teRecord.success);
}
else if (teRecord.error !== undefined) {
success = false;
}
else if (teRecord.status !== undefined) {
const status = String(teRecord.status).toLowerCase().trim();
success = !["error", "failed", "failure", "fail"].includes(status);
}
// Enhanced server ID extraction
let serverId = teRecord.serverId ||
teRecord.server ||
teRecord.source ||
undefined;
// Try to extract from nested structures
if (!serverId &&
teRecord.toolCall &&
typeof teRecord.toolCall === "object") {
const toolCall = teRecord.toolCall;
serverId =
toolCall.serverId ||
toolCall.server ||
undefined;
}
return {
toolName: toolName,
executionTime: executionTime,
success: success,
serverId: serverId,
};
});
}
// ============================================================================
// AVAILABLE TOOLS TRANSFORMATIONS
// ============================================================================
/**
* Transform available tools from internal format to GenerateResult format
* Ensures consistent tool information structure across the API with schema normalization
*
* @param availableTools - Array of tool definitions from various sources (MCP servers, builtin tools, etc.)
* @returns Array of normalized tool descriptions with consistent schema format
*
* @example
* ```typescript
* const tools = transformAvailableTools([
* { name: "calculator", description: "Math tool", server: "builtin", inputSchema: {...} }
* ]);
* // Returns: [{ name: "calculator", description: "Math tool", serverId: "builtin", schema: {...} }]
* ```
*/
export function transformAvailableTools(availableTools) {
if (!availableTools || !Array.isArray(availableTools)) {
return [];
}
return availableTools.map((tool) => {
const toolRecord = tool;
return {
name: tool.name || "",
description: tool.description || "",
server: tool.server || "",
parameters: toolRecord.inputSchema ||
toolRecord.parameters ||
toolRecord.schema ||
{},
};
});
}
/**
* Transform tools for MCP generation format
* Simple transformation for internal MCP tool lists
*/
export function transformToolsForMCP(availableTools) {
return availableTools.map((tool) => ({
name: tool.name,
description: tool.description,
server: tool.server,
category: tool.category,
}));
}
/**
* Transform tools to expected format with required properties
* Used in getAllAvailableTools method for final output
*/
export function transformToolsToExpectedFormat(tools) {
return tools.map((tool) => ({
name: tool.name,
description: tool.description || "No description available",
server: tool.serverId || "unknown",
category: tool.category,
inputSchema: tool.inputSchema,
}));
}
// ============================================================================
// STRING AND ARRAY TRANSFORMATIONS
// ============================================================================
/**
* Extract tool names from tool objects
* Common pattern for creating arrays of tool names
*/
export function extractToolNames(tools) {
return tools.map((tool) => tool.name);
}
/**
* Extract object keys as a comma-separated string
* Common pattern for logging and debugging
*/
export function getKeysAsString(obj, fallback = "none") {
const keys = Object.keys(obj);
return keys.length > 0 ? keys.join(", ") : fallback;
}
/**
* Count object properties
* Common pattern for metrics and logging
*/
export function getKeyCount(obj) {
return Object.keys(obj).length;
}
// ============================================================================
// SCHEMA TRANSFORMATIONS
// ============================================================================
/**
* Transform schema properties to parameter descriptions
* Used in tool-aware system prompt generation
*/
export function transformSchemaToParameterDescription(schema) {
if (!schema?.properties) {
return "";
}
const requiredParams = new Set(schema.required || []);
return Object.entries(schema.properties)
.map(([key, value]) => {
const typedValue = value;
const required = requiredParams.has(key) ? " (required)" : "";
return ` - ${key}: ${typedValue.type || "unknown"}${required}`;
})
.join("\n");
}
/**
* Transform tools to tool descriptions for system prompts
* Consolidated pattern for creating tool-aware prompts
*/
export function transformToolsToDescriptions(availableTools) {
return availableTools
.map((tool) => {
const schema = tool.inputSchema;
let params = "";
if (schema?.properties) {
params = transformSchemaToParameterDescription(schema);
}
return `- ${tool.name}: ${tool.description} (from ${tool.server})\n${params}`;
})
.join("\n\n");
}
// ============================================================================
// VALIDATION TRANSFORMATIONS
// ============================================================================
/**
* Transform parameters for validation
* Common pattern when logging or checking parameter structures
*/
export function transformParamsForLogging(params) {
if (!params || typeof params !== "object") {
return String(params);
}
const record = params;
return `${Object.keys(record).length} params`;
}
/**
* Safe property extraction from unknown objects
* Common pattern for safely accessing properties from unknown structures
*/
export function safeExtractProperty(obj, key, fallback) {
if (!obj || typeof obj !== "object" || obj === null) {
return fallback;
}
const record = obj;
const value = record[key];
return value !== undefined ? value : fallback;
}
/**
* Safe extraction of string properties
* Specialized version for string properties with fallback
*/
export function safeExtractString(obj, key, fallback = "") {
const value = safeExtractProperty(obj, key, fallback);
return typeof value === "string" ? value : fallback;
}
/**
* Safe extraction of number properties
* Specialized version for number properties with fallback
*/
export function safeExtractNumber(obj, key, fallback = 0) {
const value = safeExtractProperty(obj, key, fallback);
return typeof value === "number" ? value : fallback;
}
/**
* Safe extraction of boolean properties
* Specialized version for boolean properties with fallback
*/
export function safeExtractBoolean(obj, key, fallback = false) {
const value = safeExtractProperty(obj, key, fallback);
return typeof value === "boolean" ? value : fallback;
}
// ============================================================================
// COLLECTION TRANSFORMATIONS
// ============================================================================
/**
* Transform Map to array of values
* Common pattern for converting tool maps to arrays
*/
export function mapToArray(map) {
return Array.from(map.values());
}
/**
* Transform Map to array of key-value pairs
* Common pattern for processing map entries
*/
export function mapToEntries(map) {
return Array.from(map.entries());
}
/**
* Group array items by a key
* Common pattern for organizing tools or other objects by category
*/
export function groupBy(items, keyFn) {
const groups = new Map();
for (const item of items) {
const key = keyFn(item);
const existing = groups.get(key) || [];
existing.push(item);
groups.set(key, existing);
}
return groups;
}
/**
* Remove undefined properties from objects
* Common pattern for cleaning up object structures
*/
export function removeUndefinedProperties(obj) {
const cleaned = {};
for (const [key, value] of Object.entries(obj)) {
if (value !== undefined) {
cleaned[key] = value;
}
}
return cleaned;
}
/**
* Merge objects with undefined handling
* Common pattern for combining configuration objects
*/
export function mergeWithUndefinedHandling(target, ...sources) {
const result = { ...target };
for (const source of sources) {
for (const [key, value] of Object.entries(source)) {
if (value !== undefined) {
result[key] = value;
}
}
}
return result;
}
// ============================================================================
// TOOL OPTIMIZATION UTILITIES
// ============================================================================
/**
* Optimize tool information for collection with minimal object creation
* Consolidates repeated optimization patterns across different tool sources
*
* @param tool - Tool information to optimize
* @param defaults - Default values to apply if missing
* @returns Optimized tool with minimal object creation
*
* @example
* ```typescript
* const optimized = optimizeToolForCollection(tool, {
* serverId: "builtin",
* category: "math"
* });
* ```
*/
export function optimizeToolForCollection(tool, defaults) {
// Check what properties actually need modification
const needsDescription = !tool.description && defaults.description;
const needsServerId = !tool.serverId && defaults.serverId;
const needsCategory = !tool.category && defaults.category;
const needsInputSchema = !tool.inputSchema && defaults.inputSchema;
const hasParametersConflict = tool.inputSchema && "parameters" in tool;
// Only create new object if modifications are actually needed
if (!needsDescription &&
!needsServerId &&
!needsCategory &&
!needsInputSchema &&
!hasParametersConflict) {
return tool; // Return original tool without modification
}
// Create optimized tool with only necessary changes
const optimizedTool = {
...tool,
...(needsDescription && { description: defaults.description }),
...(needsServerId && { serverId: defaults.serverId }),
...(needsCategory && { category: defaults.category }),
...(needsInputSchema && { inputSchema: defaults.inputSchema }),
};
// Clean up schema conflicts if present
if (hasParametersConflict) {
const cleanedTool = { ...optimizedTool };
delete cleanedTool.parameters;
return cleanedTool;
}
return optimizedTool;
}