const express = require('express'); const fetch = require('node-fetch'); const crypto = require('crypto'); const app = express(); const port = 8000; const NOTDIAMOND_URL = 'https://chat.notdiamond.ai/mini-chat'; const NOTDIAMOND_HEADERS = { 'Content-Type': 'application/json', 'next-action': '8189eb37107121e024940f588629a394a594e6a4' }; const AUTH_KEY = process.env.AUTH_KEY; const DEFAULT_MODEL = 'gpt-4-turbo-2024-04-09'; function createOpenAIChunk(content, model, finishReason = null) { return { id: `chatcmpl-${crypto.randomUUID()}`, object: "chat.completion.chunk", created: Math.floor(Date.now() / 1000), model: model, system_fingerprint: "fp_4e2b2da518", choices: [ { index: 0, delta: content ? { content: content } : {}, logprobs: null, finish_reason: finishReason } ], usage: null }; } async function* streamNotdiamondResponse(response, model) { const reader = response.body.getReader(); const decoder = new TextDecoder(); let buffer = ""; let lastContent = ""; function processDollars(str) { return str.replace(/\${2,}/, match => match.slice(1)); } while (true) { const { done, value } = await reader.read(); if (done) break; buffer += decoder.decode(value, { stream: true }); let lines = buffer.split('\n'); buffer = lines.pop() || ""; for (const line of lines) { if (line.trim() === '') continue; try { const jsonMatch = line.match(/\{.*\}/); if (jsonMatch) { const data = JSON.parse(jsonMatch[0]); let content = ''; if (data.output?.curr !== undefined) { content = processDollars(data.output.curr); lastContent = content; } else if (data.curr !== undefined) { content = processDollars(data.curr); lastContent = content; } else if (data.diff !== undefined && Array.isArray(data.diff) && data.diff.length > 1) { const newContent = processDollars(data.diff[1]); content = lastContent + newContent; lastContent = content; } else if (data.diff !== undefined && Array.isArray(data.diff) && data.diff.length === 1) { content = lastContent; // If diff is empty, use the last content } if (content) { yield createOpenAIChunk(content, model); } } } catch (error) { console.error('Error processing line:', error, 'Raw line:', line); } } } if (buffer.trim()) { try { const jsonMatch = buffer.match(/\{.*\}/); if (jsonMatch) { const data = JSON.parse(jsonMatch[0]); let content = ''; if (data.output?.curr !== undefined) { content = processDollars(data.output.curr); } else if (data.curr !== undefined) { content = processDollars(data.curr); } else if (data.diff !== undefined && Array.isArray(data.diff) && data.diff.length > 1) { const newContent = processDollars(data.diff[1]); content = lastContent + newContent; } else if (data.diff !== undefined && Array.isArray(data.diff) && data.diff.length === 1) { content = lastContent; } if (content) { yield createOpenAIChunk(content, model); } } } catch (error) { console.error('Error processing final buffer:', error); } } yield createOpenAIChunk('', model, 'stop'); } app.use(express.json()); app.post('/ai/v1/chat/completions', async (req, res) => { const authHeader = req.headers['authorization']; if (!authHeader || !authHeader.startsWith('Bearer ') || authHeader.slice(7) !== AUTH_KEY) { return res.status(401).json({ error: 'Unauthorized' }); } try { let requestData = req.body; let messages = requestData.messages; let model = requestData.model || DEFAULT_MODEL; const stream = requestData.stream || false; if (!messages || !Array.isArray(messages)) { return res.status(400).json({ error: 'Invalid request body', details: 'messages should be an array of message objects', receivedBody: req.body }); } const payload = { messages: messages, model: model, stream: stream, frequency_penalty: requestData.frequency_penalty || 0, presence_penalty: requestData.presence_penalty || 0, temperature: requestData.temperature || 0.6, top_p: requestData.top_p || 1 }; const headers = { 'Content-Type': 'application/json', 'next-action': '4e63dabc37fef18cae74cbfd41d1bace49acf47e' }; const response = await fetch(NOTDIAMOND_URL, { method: 'POST', headers: headers, body: JSON.stringify([payload]) }); const generator = streamNotdiamondResponse(response, model); if (stream) { res.writeHead(200, { 'Content-Type': 'text/event-stream', 'Cache-Control': 'no-cache', 'Connection': 'keep-alive' }); for await (const chunk of generator) { res.write(`data: ${JSON.stringify(chunk)}\n\n`); } res.write("data: [DONE]\n\n"); res.end(); } else { let fullContent = ""; for await (const chunk of generator) { if (chunk.choices[0].delta.content) { fullContent += chunk.choices[0].delta.content; } } res.json({ id: `chatcmpl-${crypto.randomUUID()}`, object: "chat.completion", created: Math.floor(Date.now() / 1000), model: model, system_fingerprint: "fp_4e2b2da518", choices: [ { index: 0, message: { role: "assistant", content: fullContent }, finish_reason: "stop" } ], usage: { prompt_tokens: Math.floor(fullContent.length / 4), completion_tokens: Math.floor(fullContent.length / 4), total_tokens: Math.floor(fullContent.length / 2) } }); } } catch (error) { res.status(500).json({ error: 'Internal Server Error', details: error.message }); } }); app.listen(port, () => { console.log(`Server running on port ${port}`); });