analize:
 

import express from 'express';

import { Client } from "@gradio/client";

import { JSDOM } from 'jsdom';


const app = express();

app.use(express.json());


// Function to convert mixed HTML/Markdown to pure Markdown

function convertToMarkdown(input) {

const dom = new JSDOM(input);

const document = dom.window.document;


function nodeToMarkdown(node) {

if (node.nodeType === 3) return node.textContent;

if (node.nodeType !== 1) return '';


let md = '';

switch (node.tagName.toLowerCase()) {

case 'br':

return '\n';

case 'p':

return '\n\n' + Array.from(node.childNodes).map(nodeToMarkdown).join('') + '\n\n';

case 'strong':

case 'b':

return '**' + Array.from(node.childNodes).map(nodeToMarkdown).join('') + '**';

case 'pre':

let codeContent = Array.from(node.childNodes).map(nodeToMarkdown).join('');

let language = node.querySelector('code')?.className?.replace('language-', '') || '';

return '\n```' + language + '\n' + codeContent.trim() + '\n```\n';

case 'code':

if (node.parentNode.tagName.toLowerCase() !== 'pre') {

return '`' + node.textContent + '`';

}

return node.textContent;

default:

return Array.from(node.childNodes).map(nodeToMarkdown).join('');

}

}


let markdown = nodeToMarkdown(document.body);

markdown = markdown.replace(/&lt;/g, '<')

.replace(/&gt;/g, '>')

.replace(/&amp;/g, '&');

markdown = markdown.replace(/\n{3,}/g, '\n\n').trim();


return markdown;

}


// Connect to the Gradio client

let client;

(async () => {

client = await Client.connect("yuntian-deng/o1mini");

})();


app.post('/v1/chat/completions', async (req, res) => {

try {

const messages = req.body.messages;

if (!messages || !Array.isArray(messages)) {

return res.status(400).send('Invalid messages format');

}


let chatbot = [];

let chatCounter = 0;


// Process all messages except the last one

for (let i = 0; i < messages.length - 1; i++) {

const message = messages[i];

if (message.role === 'user') {

chatbot.push([message.content, '']);

} else if (message.role === 'assistant' && chatbot.length > 0) {

chatbot[chatbot.length - 1][1] = message.content;

}

chatCounter++;

}


// Process the last message (should be from user)

const lastMessage = messages[messages.length - 1];

if (lastMessage.role !== 'user') {

return res.status(400).send('Last message must be from user');

}

const userInput = lastMessage.content;


// Set up SSE

res.writeHead(200, {

'Content-Type': 'text/event-stream',

'Cache-Control': 'no-cache',

'Connection': 'keep-alive'

});


// Make prediction

const result = await client.predict("/predict", {

inputs: userInput,

top_p: 1,

temperature: 1,

chat_counter: chatCounter,

chatbot: chatbot

});


// Extract AI response

const aiResponse = result.data[0][result.data[0].length - 1][1];


// Convert AI response to Markdown

const markdownResponse = convertToMarkdown(aiResponse);


// Send SSE response

const sseResponse = {

id: `chatcmpl-${Date.now()}`,

model: "o1-mini",

object: "chat.completion.chunk",

created: Math.floor(Date.now() / 1000),

choices: [{

index: 0,

delta: { content: markdownResponse },

finish_reason: "stop"

}]

};


res.write(`data: ${JSON.stringify(sseResponse)}\n\n`);

res.write('data: [DONE]\n\n');

res.end();


} catch (error) {

console.error("Error:", error);

res.status(500).send('Internal Server Error');

}

});


const PORT = process.env.PORT || 3000;

app.listen(PORT, () => console.log(`Server running on port ${PORT}`));