/**
 * Recursively clean schema to remove unsupported fields
 */
function cleanSchema(schema) {
    if (typeof schema !== "object" || schema === null) {
        return schema;
    }
    if (Array.isArray(schema)) {
        return schema.map(cleanSchema);
    }
    const newSchema = {};
    const obj = schema;
    for (const key in obj) {
        // Remove $schema as OpenAI API doesn't accept it
        // Remove exclusiveMinimum/exclusiveMaximum as some models (e.g. Gemini) don't support them
        if (key === "$schema" ||
            key === "exclusiveMinimum" ||
            key === "exclusiveMaximum") {
            continue;
        }
        // Handle type as an array (e.g. ["string", "null"])
        if (key === "type" && Array.isArray(obj[key])) {
            const types = obj[key];
            const nonNullTypes = types.filter((t) => t !== "null");
            if (nonNullTypes.length > 0) {
                newSchema["type"] = nonNullTypes[0];
            }
            if (types.includes("null")) {
                newSchema["nullable"] = true;
            }
            continue;
        }
        newSchema[key] = cleanSchema(obj[key]);
    }
    return newSchema;
}
/**
 * Convert MCP tool to OpenAI function tool format
 */
export function mcpToolToOpenAITool(mcpTool, serverName) {
    const cleanInputSchema = cleanSchema(mcpTool.inputSchema);
    const prefixedName = `mcp__${serverName}__${mcpTool.name}`;
    return {
        type: "function",
        function: {
            name: prefixedName,
            description: `${mcpTool.description || `Tool from MCP server ${serverName}`} (MCP: ${serverName})`,
            parameters: cleanInputSchema,
        },
    };
}
/**
 * Create a tool plugin wrapper for an MCP tool
 */
export function createMcpToolPlugin(mcpTool, serverName, executeTool) {
    const prefixedName = `mcp__${serverName}__${mcpTool.name}`;
    return {
        name: prefixedName,
        config: mcpToolToOpenAITool(mcpTool, serverName),
        async execute(args, context) {
            try {
                const result = await executeTool(prefixedName, args, context);
                return {
                    success: true,
                    content: result.content || `Executed ${mcpTool.name}`,
                };
            }
            catch (error) {
                return {
                    success: false,
                    content: "",
                    error: error instanceof Error ? error.message : String(error),
                };
            }
        },
    };
}
/**
 * Find which server a tool belongs to
 */
export function findToolServer(toolName, servers) {
    return servers.find((s) => s.status === "connected" && s.tools?.some((t) => t.name === toolName));
}
