Discover Q&A generated by OPENAI 01

Discover public questions answered by OPENAI01

OpenAI 01 Preview

Text Splitting Function Optimization

function splitText(node) { const maxLength = 32; const text = node.value; const formattingObjects = node.formatting?.bold || []; const result = []; if (text.length + formattingObjects.length * 2 <= maxLength) { result.push({ ...node }); return result; } formattingObjects.sort((a, b) => a.begin - b.begin); let startIndex = 0; while (startIndex < text.length) { let possibleEndIndex = Math.min(startIndex + maxLength, text.length); let endIndex = possibleEndIndex; let overhead = 0; // Initialize overhead to 0 for (let fmt of formattingObjects) { if (fmt.end <= startIndex) { continue; } if (fmt.begin >= possibleEndIndex) { break; } overhead += 2; } if (text.length - startIndex + overhead > maxLength) { let newlineIndex = text.lastIndexOf('\n', possibleEndIndex - 1); if (newlineIndex > startIndex) { endIndex = newlineIndex + 1; } else { let spaceIndex = text.lastIndexOf(' ', possibleEndIndex - 1); if (spaceIndex > startIndex) { endIndex = spaceIndex + 1; } else { endIndex = possibleEndIndex; } } } while (true) { let overhead = 0; for (let fmt of formattingObjects) { if (fmt.end <= startIndex) { continue; } if (fmt.begin >= endIndex) { break; } overhead += 2; } let totalLength = (endIndex - startIndex) + overhead; if (totalLength <= maxLength) { break; } else { endIndex--; if (endIndex <= startIndex) { endIndex = startIndex + 1; break; } } } let substring = text.substring(startIndex, endIndex); let newNode = { ...node }; newNode.value = substring.trim(); newNode.formatting = { bold: [] }; for (let fmt of formattingObjects) { if (fmt.end <= startIndex || fmt.begin >= endIndex) { continue; } let newFmt = {}; newFmt.begin = Math.max(fmt.begin, startIndex) - startIndex; newFmt.end = Math.min(fmt.end, endIndex) - startIndex; newNode.formatting.bold.push(newFmt); } result.push(newNode); startIndex = endIndex; } return result; } improve this code without making worse

Created by wprhvso and OPENAI01
OpenAI 01 Preview

Text Splitting Functionality

function splitText(node) { const maxLength = 32; const text = node.value; const formattingObjects = node.formatting?.bold || []; const result = []; if (text.length + formattingObjects.length * 2 <= maxLength) { result.push({ ...node }); return result; } formattingObjects.sort((a, b) => a.begin - b.begin); let startIndex = 0; while (startIndex < text.length) { let possibleEndIndex = Math.min(startIndex + maxLength, text.length); let endIndex = adjustEndIndex(text, formattingObjects, startIndex, possibleEndIndex, maxLength); let newNode = extractSubstringAndFormatting(node, text, formattingObjects, startIndex, endIndex); result.push(newNode); startIndex = endIndex; } return result; } function calculateOverhead(formattingObjects, startIndex, endIndex) { let overhead = 0; for (let fmt of formattingObjects) { if (fmt.end <= startIndex) { continue; } if (fmt.begin >= endIndex) { break; } overhead += 2; } return overhead; } function adjustEndIndex(text, formattingObjects, startIndex, possibleEndIndex, maxLength) { let endIndex = possibleEndIndex; let overhead = calculateOverhead(formattingObjects, startIndex, endIndex); if (text.length - startIndex + overhead > maxLength) { let newlineIndex = text.lastIndexOf('\n', possibleEndIndex - 1); if (newlineIndex > startIndex) { endIndex = newlineIndex + 1; } else { let spaceIndex = text.lastIndexOf(' ', possibleEndIndex - 1); if (spaceIndex > startIndex) { endIndex = spaceIndex + 1; } else { endIndex = possibleEndIndex; } } } while (true) { overhead = calculateOverhead(formattingObjects, startIndex, endIndex); let totalLength = (endIndex - startIndex) + overhead; if (totalLength <= maxLength) { break; } else { endIndex--; if (endIndex <= startIndex) { endIndex = startIndex + 1; break; } } } return endIndex; } function extractSubstringAndFormatting(node, text, formattingObjects, startIndex, endIndex) { let substring = text.substring(startIndex, endIndex); let newNode = { ...node }; newNode.value = substring.trim(); newNode.formatting = { bold: [] }; for (let fmt of formattingObjects) { if (fmt.end <= startIndex || fmt.begin >= endIndex) { continue; } let newFmt = {}; newFmt.begin = Math.max(fmt.begin, startIndex) - startIndex; newFmt.end = Math.min(fmt.end, endIndex) - startIndex; newNode.formatting.bold.push(newFmt); } return newNode; } simplify this code without making worse

Created by wprhvso and OPENAI01
OpenAI 01 Preview

Text Splitting Function Refactor

function splitText(node) { const maxLength = 32; const text = node.value; const formattingObjects = node.formatting?.bold || []; const result = []; if (text.length + formattingObjects.length * 2 <= maxLength) { result.push({ ...node }); return result; } formattingObjects.sort((a, b) => a.begin - b.begin); let startIndex = 0; while (startIndex < text.length) { let possibleEndIndex = Math.min(startIndex + maxLength, text.length); let endIndex = possibleEndIndex; let overhead = 0; // Initialize overhead to 0 for (let fmt of formattingObjects) { if (fmt.end <= startIndex) { continue; } if (fmt.begin >= possibleEndIndex) { break; } overhead += 2; } if (text.length - startIndex + overhead > maxLength) { let newlineIndex = text.lastIndexOf('\n', possibleEndIndex - 1); if (newlineIndex > startIndex) { endIndex = newlineIndex + 1; } else { let spaceIndex = text.lastIndexOf(' ', possibleEndIndex - 1); if (spaceIndex > startIndex) { endIndex = spaceIndex + 1; } else { endIndex = possibleEndIndex; } } } while (true) { let overhead = 0; for (let fmt of formattingObjects) { if (fmt.end <= startIndex) { continue; } if (fmt.begin >= endIndex) { break; } overhead += 2; } let totalLength = (endIndex - startIndex) + overhead; if (totalLength <= maxLength) { break; } else { endIndex--; if (endIndex <= startIndex) { endIndex = startIndex + 1; break; } } } let substring = text.substring(startIndex, endIndex); let newNode = { ...node }; newNode.value = substring.trim(); newNode.formatting = { bold: [] }; for (let fmt of formattingObjects) { if (fmt.end <= startIndex || fmt.begin >= endIndex) { continue; } let newFmt = {}; newFmt.begin = Math.max(fmt.begin, startIndex) - startIndex; newFmt.end = Math.min(fmt.end, endIndex) - startIndex; newNode.formatting.bold.push(newFmt); } result.push(newNode); startIndex = endIndex; } return result; } subdivide this code on multiple js functions without breaking the logic

Created by wprhvso and OPENAI01
OpenAI 01 Preview

Text Splitting Function Code

function splitText(node) { const maxLength = 32; const text = node.value; const formattingObjects = node.formatting?.bold || []; const result = []; if (text.length + formattingObjects.length * 2 <= maxLength) { result.push({ ...node }); return result; } // Sort formatting objects by their begin positions formattingObjects.sort((a, b) => a.begin - b.begin); let startIndex = 0; while (startIndex < text.length) { let possibleEndIndex = Math.min(startIndex + maxLength, text.length); // Try to adjust possibleEndIndex to previous newline or space let endIndex = possibleEndIndex; let overhead = 0; // Initialize overhead to 0 // Calculate overhead for the initial possibleEndIndex for (let fmt of formattingObjects) { if (fmt.end <= startIndex) { continue; } if (fmt.begin >= possibleEndIndex) { break; } // Formatting object overlaps the range overhead += 2; } if (text.length - startIndex + overhead > maxLength) { let newlineIndex = text.lastIndexOf('\n', possibleEndIndex - 1); if (newlineIndex > startIndex) { endIndex = newlineIndex + 1; } else { let spaceIndex = text.lastIndexOf(' ', possibleEndIndex - 1); if (spaceIndex > startIndex) { endIndex = spaceIndex + 1; } else { endIndex = possibleEndIndex; } } } // Now compute total length including formatting overhead while (true) { // Count the number of formatting objects overlapping [startIndex, endIndex) let overhead = 0; for (let fmt of formattingObjects) { if (fmt.end <= startIndex) { continue; } if (fmt.begin >= endIndex) { break; } // Formatting object overlaps the range overhead += 2; } let totalLength = (endIndex - startIndex) + overhead; if (totalLength <= maxLength) { break; } else { // Reduce endIndex and try again endIndex--; if (endIndex <= startIndex) { // Can't reduce further endIndex = startIndex + 1; // At least include one character break; } } } // Now extract substring and adjust formatting objects let substring = text.substring(startIndex, endIndex); let newNode = { ...node }; newNode.value = substring.trim(); // Adjust formatting objects newNode.formatting = { bold: [] }; for (let fmt of formattingObjects) { if (fmt.end <= startIndex || fmt.begin >= endIndex) { // Formatting object is outside the range continue; } // Formatting object overlaps the range let newFmt = {}; newFmt.begin = Math.max(fmt.begin, startIndex) - startIndex; newFmt.end = Math.min(fmt.end, endIndex) - startIndex; newNode.formatting.bold.push(newFmt); } result.push(newNode); startIndex = endIndex; } return result; } const node = { id: 1, value: "Очень длин\nный текст, который нужно разделить на части не длиннее 32 символов.", formatting: { bold: [{ begin: 6, end: 14 }] } }; const splitNodes = splitText(node); console.log(JSON.stringify(splitNodes, null, 3)); //INSTRUCTION: simplify this code

Created by wprhvso and OPENAI01
OpenAI 01 Preview

Markdown V2 Functions Implementation

<file path="./package.json"> { "name": "your-project", "version": "1.0.0", "type": "module", "main": "index.js", "scripts": { "start": "node index.js" }, "dependencies": { "bcrypt": "^5.1.1", "dotenv": "^16.4.5", "express": "^4.21.0", "html-entities": "^2.5.2", "node-telegram-bot-api": "^0.66.0", "redis": "^4.7.0", "validator": "^13.12.0" } } </file> <file path="./config/config.js"> export const port = process.env.PORT || 8000 export const botToken = process.env.BOT_TOKEN export const botUsername = process.env.BOT_USERNAME export const redisUrl = process.env.REDIS_URL || 'redis://localhost:6379' if (!botToken || !botUsername) { throw new Error('BOT_TOKEN and BOT_USERNAME must be set in environment variables.') } </file> <file path="./middleware/validateSessionId.js"> export const validateSessionId = (req, res, next) => { const sessionId = (req.params.sessionId || '').trim() if (!/^[a-zA-Z0-9_-]+$/.test(sessionId)) { return res.status(400).json({ error: 'Invalid Session ID.' }) } req.sessionId = sessionId next() } </file> <file path="./index.js"> import express from 'express' import commandsRoutes from './routes/commands' import updateRoutes from './routes/update' import sessionsRoutes from './routes/sessions' import { redisClient } from './utils/redisClient' import { port } from './config/config' const app = express() app.use(express.json()) app.use('/commands', commandsRoutes) app.use('/update', updateRoutes) app.use('/sessions', sessionsRoutes) const server = app.listen(port, () => { console.log(`Server is listening on port ${port}`) }) process.on('SIGINT', async () => { console.log('Shutting down server...') try { await redisClient.quit() server.close(() => { console.log('Server closed.') process.exit(0) }) } catch (err) { console.error('Error during shutdown:', err) process.exit(1) } }) </file> <file path="./bot/handlers.js"> import { bot } from './instance' import { parseSessionId, withUserSession, startSession } from '../utils/session' const start = async (chatId, userId, text) => { const sessionId = parseSessionId(text) if (!sessionId) return bot.sendMessage(chatId, 'Please provide a session ID.') await startSession(sessionId, userId, chatId) await bot.sendMessage(chatId, `Welcome to session ${sessionId}!`) } const clear = (chatId, userId) => { return withUserSession(chatId, userId, (session) => { session.commands.push({ type: 'CLEAR' }) session.promptNumber = 2 return bot.sendMessage(chatId, 'Session cleared.') }) } const request = (chatId, userId, text) => { return withUserSession(chatId, userId, (session) => { session.commands.push({ type: 'RUN', text, promptNumber: session.promptNumber }) session.promptNumber += 2 return bot.sendMessage(chatId, 'Processing your request...') }) } export const handleMessage = async (msg) => { const chatId = msg.chat.id const userId = msg.from.id const text = msg.text?.trim() || '' try { if (text.startsWith('/start')) await start(chatId, userId, text) else if (text.startsWith('/clear')) await clear(chatId, userId) else await request(chatId, userId, text) } catch (error) { console.error('Error handling message:', error) bot.sendMessage(chatId, 'An error occurred.') } } </file> <file path="./bot/instance.js"> import TelegramBot from 'node-telegram-bot-api' import { botToken } from '../config/config' import { handleMessage } from './handlers' export const bot = new TelegramBot(botToken, { polling: true }) bot.on('message', handleMessage) </file> <file path="./controllers/bot.js"> import { withExistingSession } from '../utils/session' import { bot } from '../bot/instance' import { splitMessage } from '../utils/splitMessage' export const processSession = async (sessionId) => { await withExistingSession(sessionId, async (session) => { session.processing = true try { while (session.results.length > 0) { const resultText = session.results.shift() await processMessages(session, resultText) } } catch (error) { console.error(`Error processing session ${sessionId}:`, error) } finally { session.processing = false } }) } export const processMessages = async (session, text) => { if (!session.chatId) return if (!session.messages) session.messages = [] try { for (const chunk of splitMessage(text)) { const message = await bot.sendMessage(session.chatId, chunk, { parse_mode: 'MarkdownV2' }) session.messages.push(message) } } catch (error) { console.error(`Error sending messages for session ${session.sessionId}:`, error) } } </file> <file path="./routes/sessions.js"> import express from 'express' import { redisClient } from '../utils/redisClient' const router = express.Router() router.get('/', async (req, res) => { try { const keys = await redisClient.keys('session:*') const sessionIds = keys.map(key => key.replace('session:', '')) res.json({ sessions: sessionIds }) } catch (error) { console.error('Error fetching sessions:', error) res.status(500).json({ error: 'Internal Server Error' }) } }) export default router </file> <file path="./routes/commands.js"> import express from 'express' import { validateSessionId } from '../middleware/validateSessionId' import { withExistingOrNewSession } from '../utils/session' const router = express.Router() router.get('/:sessionId', validateSessionId, async (req, res) => { const { sessionId } = req try { await withExistingOrNewSession(sessionId, (session) => { const commands = [...session.commands] session.commands = [] res.json({ commands }) }) } catch (error) { console.error(`Error fetching commands for session ${sessionId}:`, error) res.status(500).json({ error: 'Internal Server Error' }) } }) router.post('/:sessionId', validateSessionId, async (req, res) => { const { sessionId } = req const command = req.body try { await withExistingOrNewSession(sessionId, (session) => { if (!command || !command.type) { return res.status(400).json({ error: 'Invalid command.' }) } if (command.type === 'CLEAR') { session.promptNumber = 2 } else { command.promptNumber = session.promptNumber session.promptNumber += 2 } session.commands.push(command) res.json({ message: 'Command added.' }) }) } catch (error) { console.error(`Error adding command to session ${sessionId}:`, error) res.status(500).json({ error: 'Internal Server Error' }) } }) export default router </file> <file path="./routes/password.js"> import express from 'express' import validator from 'validator' import bcrypt from 'bcrypt' import { validateSessionId } from '../middleware/validateSessionId' import { withExistingOrNewSession } from '../utils/session' import { botUsername } from '../config/config' const router = express.Router() router.post('/:sessionId', validateSessionId, async (req, res) => { const { sessionId } = req const { password } = req.body try { if (!password || validator.isEmpty(password)) { return res.status(400).json({ error: 'Password is required.' }) } const sanitizedPassword = validator.escape(password) await withExistingOrNewSession(sessionId, async (session) => { session.password = await bcrypt.hash(sanitizedPassword, 10) }) res.json({ link: `https://t.me/${botUsername}?start=${sessionId}-${sanitizedPassword}` }) } catch (error) { console.error(`Error setting password for session ${sessionId}:`, error) res.status(500).json({ error: 'Internal Server Error' }) } }) export default router </file> <file path="./routes/update.js"> import express from 'express' import { validateSessionId } from '../middleware/validateSessionId' import { getOrCreateSession, setSession } from '../utils/session' import { bot } from '../bot/instance' const router = express.Router() router.post('/:sessionId', validateSessionId, async (req, res) => { const { sessionId } = req const resultText = req.body.text try { if (!resultText) { return res.status(400).json({ error: 'Result text is required.' }) } let session = await getOrCreateSession(sessionId) session.results.push(resultText) await setSession(sessionId, session) if (session.chatId) { await bot.sendMessage(session.chatId, resultText) } res.json({ message: 'Result received.' }) } catch (error) { console.error(`Error updating session ${sessionId}:`, error) res.status(500).json({ error: 'Internal Server Error' }) } }) export default router </file> <file path="./utils/redisClient.js"> import { createClient } from 'redis' import { redisUrl } from '../config/config' export const redisClient = createClient({ url: redisUrl }) redisClient.on('error', (err) => console.error('Redis error:', err)) redisClient.connect().then(() => { console.log('Connected to Redis.') }).catch((error) => { console.error('Failed to connect to Redis:', error) process.exit(1) }) </file> <file path="./utils/markdownV2Text.js"> import { decode } from "html-entities"; function parseFormatting(node, type, symbol_left, symbol_right = symbol_left) { if (!node.formatting) node.formatting = {} if (!node.formatting[type]) node.formatting[type] = [] const escaped_left = symbol_left.replace(/[.*+?^${}()|\[\]\\]/g, '\\$&') const escaped_right = symbol_right.replace(/[.*+?^${}()|\[\]\\]/g, '\\$&') for (const match of node.value.matchAll(new RegExp(`${escaped_left}\\S.*?\\S${escaped_right}`, 'g'))) { const left = match.index const right = match.index + match[0].length - symbol_right.length fixFormattingRanges(node.formatting, -1, left, symbol_left.length) fixFormattingRanges(node.formatting, -1, right, symbol_right.length) } let removedLength = 0 const handle = (match, captured, index) => { const begin = index - removedLength const end = begin + captured.length node.formatting[type].push({ begin, end }) removedLength += match.length - captured.length return captured } node.value = node.value.replace(new RegExp(`${escaped_left}(\\S.*?\\S)${escaped_right}`, 'g'), handle) removedLength = 0 node.value = node.value.replace(new RegExp(`${escaped_left}(\\S.*)$`), handle) } const formatting = [ (node) => node.value = decode(node.value), (node) => parseFormatting(node, 'monospace', '`'), (node) => parseFormatting(node, 'bold', '**'), (node) => parseFormatting(node, 'italic', '*'), (node) => parseFormatting(node, 'italic', '_'), (node) => parseFormatting(node, 'strikethrough', '~~'), (node) => parseFormatting(node, 'strikethrough', '~'), (node) => parseFormatting(node, 'underline', '<u>', '</u>'), (node) => parseFormatting(node, 'spoiler', '<spoiler>', '</spoiler>') ] function iterateFormatting(formatting, callback) { for (const type in formatting) { formatting[type].forEach(f => { callback(f, type) }) } } function fixFormattingRanges(formatting, diff, index, count = 1) { for (let i = index; i < index + count; i++) { iterateFormatting(formatting, (f) => { if (index < f.begin) f.begin += diff if (index <= f.end) f.end += diff }) } } function fixFormattingRangesV2(formatting, diff, index, count = 1) { for (let i = index; i < index + count; i++) { iterateFormatting(formatting, (f) => { if (index < f.begin) f.begin += diff if (index < f.end) f.end += diff }) } } function symbolOfFormattingType(type) { switch (type) { case 'bold': return '*' case 'italic': return '_' case 'monospace': return '`' case 'strikethrough': return '~' case 'underline': return '__' case 'spoiler': return '||' } } function escapeMarkdownV2(node) { let counter = 0 node.value = node.value.replace(/[\\\[\]\-(){}+_*~`>#=|!.]/g, (match, index) => { fixFormattingRangesV2(node.formatting, +1, index + counter) counter++ return '\\' + match }) } function parseText(node) { for (const parse of formatting) { parse(node) } return node } export function markdownV2Text(input_node) { const node = { ...input_node } parseText(node) escapeMarkdownV2(node) let text = node.value function insert(i, symbol) { fixFormattingRanges(node.formatting, +symbol.length, i) text = text.substring(0, i) + symbol + text.substring(i) } iterateFormatting(node.formatting, (f, type) => { insert(f.begin, symbolOfFormattingType(type)) insert(f.end, symbolOfFormattingType(type)) }) text = text.replace(/\\!\\\[(?:\S|\S.*?\S)\\]\\\((?:\S|\S.*?\S)\\\)/g, (match) => { const match1 = match.matchAll(/\\\[(\S|\S.*?\S)\\]\\\((\S|\S.*?\S)\\\)/g).next().value return `![${match1[1]}](${match1[2]})` }) text = text.replace(/\\\[(?:\S|\S.*?\S)\\]\\\((?:\S|\S.*?\S)\\\)/g, (match) => { const match1 = match.matchAll(/\\\[(\S|\S.*?\S)\\]\\\((\S|\S.*?\S)\\\)/g).next().value return `[${match1[1]}](${match1[2]})` }) return text } </file> <file path="./utils/markdownV2.js"> import { markdownV2Text } from "./markdownV2Text" function parser(node, regex, type, parse = (text) => {return text}) { if (node.type !== 'text') { return [node] } const text = node.value const matches = text.matchAll(regex) const nodes = [] let lastIndex = 0 for (const match of matches) { const value = parse(match[1]) const startIndex = match.index if (startIndex > lastIndex) { nodes.push({ type: 'text', value: text.substring(lastIndex, startIndex) }) } nodes.push({ type, value }) lastIndex = startIndex + match[0].length } if (lastIndex < text.length) { nodes.push({ type: 'text', value: text.substring(lastIndex) }) } return nodes } const parsers = [ (node) => parser(node, /^```(.*?\n)```$/gms, 'code'), (node) => parser(node, /^`(.*?\n)`$/gms, 'code'), (node) => parser(node, /(((^\|.*)+\n?)+)/gm, 'table', (text) => { const result = text.trim().split('\n').map(row => { const cells = row.split('|').slice(1) if (cells[cells.length - 1].trim() === '') { cells.pop() } return cells.map(cell => cell.trim()) }) result.splice(1, 1) return result }), (node) => parser(node, /^>(.*)/gm, 'quote', (text) => [{ type: 'text', value: text, }]), (node) => parser(node, /^(#{1,6} .*)/gm, 'header', (text) => [{ type: 'text', value: text.trim() .replace(/\*\*(\S.*?\S)\*\*/g, (match, captured) => captured) .replace(/\*\*(\S.*)$/g, (match, captured) => captured), formatting: { bold: [{ begin: 0, end: text.length }] }, }]), ] function escape(text) { return text.replace(/[\\\[\]\-(){}+_*~`>#=|!.]/g, (match) => '\\' + match) } export function markdownV2(nodes) { let output = '' for (const node of nodes) { switch (node.type) { case 'text': output += markdownV2Text(node) + '\n' break case 'code': const codeBlock = '```' + escape(node.value) + '```' let remainingCode = codeBlock while (remainingCode.length > 0) { const remainingSpace = MAX_OUTPUT_SIZE - output.length const chunkLength = Math.min(remainingCode.length, remainingSpace) output += remainingCode.substring(0, chunkLength) remainingCode = remainingCode.substring(chunkLength) if (remainingCode.length > 0) { overflow() } } break case 'table': output += '```markdown\n' const rows = node.value const maxLengths = rows[0].map((header, i) => Math.max(header.length, ...rows.slice(1).map(row => row[i] ? row[i].length : 0)) ) for (let i = 0; i < rows.length; i++) { const row = rows[i] output += escape('| ' + row.map((cell, j) => cell.padEnd(maxLengths[j])).join(' | ') + ' |\n') if (i === 0) { output += escape('| ' + maxLengths.map(length => '-'.repeat(length)).join(' | ') + ' |\n') } } output += '```\n' break case 'quote': output += '>' + markdownV2(node.value) break case 'header': output += markdownV2(node.value) break } } if (output[output.length - 1] === '\n') { output = output.slice(0, -1) } return output } export function parse(text) { let in_nodes = [{type: 'text', value: text}] for (const fn of parsers) { const out_nodes = [] for (let i = 0; i < in_nodes.length; i++) { out_nodes.push(...fn(in_nodes[i])) } in_nodes = out_nodes } return in_nodes } </file> <file path="./utils/splitMessage.js"> import { parse, markdownV2 } from './markdownV2' export const splitMessage = (text) => { const maxLength = 4096 const formattedText = markdownV2(parse(text)) const messages = [] let remainingText = formattedText while (remainingText.length > 0) { if (remainingText.length <= maxLength) { messages.push(remainingText) break } let splitIndex = remainingText.lastIndexOf('\n', maxLength) if (splitIndex === -1) { splitIndex = maxLength } const messagePart = remainingText.slice(0, splitIndex).trim() messages.push(messagePart) remainingText = remainingText.slice(splitIndex).trim() } return messages } </file> <file path="./utils/session.js"> import { redisClient } from './redisClient' import { bot } from '../bot/instance' const SESSION_TTL = 60 * 60 * 24 export const getSessionKey = (sessionId) => `session:${sessionId}` export const getUserSessionKey = (userId) => `userSession:${userId}` export const getSession = async (sessionId) => { const data = await redisClient.get(getSessionKey(sessionId)) return data ? JSON.parse(data) : null } export const setSession = async (sessionId, session) => { await redisClient.setEx(getSessionKey(sessionId), SESSION_TTL, JSON.stringify(session)) } export const getUserSession = async (userId) => { return await redisClient.get(getUserSessionKey(userId)) } export const setUserSession = (userId, sessionId) => { return redisClient.setEx(getUserSessionKey(userId), SESSION_TTL, sessionId) } export const createSession = async (sessionId) => { const session = { commands: [], results: [], promptNumber: 2, userId: null, chatId: null, processing: false, } await setSession(sessionId, session) return session } export const parseSessionId = (text) => { const parts = text.trim().split(' ') return parts.length > 1 ? parts[1] : null } export const getOrCreateSession = async (sessionId) => { return (await getSession(sessionId)) || (await createSession(sessionId)) } export const withUserSession = async (chatId, userId, update) => { const sessionId = await getUserSession(userId) if (!sessionId) { await bot.sendMessage(chatId, 'No active session. Use /start <session_id> to start.') return null } let session = await getSession(sessionId) if (!session) { await bot.sendMessage(chatId, 'Session not found.') return null } const result = await update(session) await setSession(sessionId, session) return result } export const withExistingOrNewSession = async (sessionId, update) => { let session = await getOrCreateSession(sessionId) await update(session) await setSession(sessionId, session) } export const withExistingSession = async (sessionId, update) => { let session = await getSession(sessionId) if (!session) return false await update(session) await setSession(sessionId, session) return true } export const startSession = async (sessionId, userId, chatId) => { const session = await getOrCreateSession(sessionId) session.userId = userId session.chatId = chatId await setSession(sessionId, session) await setUserSession(userId, sessionId) } </file> <file path="./FORMATTING.md"> Forget all ";" Forget all ".js" extensions in imports Forget 2-4 spaces, use tabs </file> <file path="./INSTRUCTIONS.md"> Your task is to write the functions `split` in `utils/markdownV2.js` and `splitText` in `utils/markdownV2Text.js`. They should transform the `nodes` from a single message into an array of messages, each of which is no longer than 4096 characters. When splitting text, you should primarily try to split it by lines. If a line is longer than 4096 characters, you should split the line itself by words. If a word is longer than 4096 characters, you should split the word. When splitting code and tables, you should also split the text by lines of code or table rows. If a line of code or a table row is longer than 4096 characters, you should split it by words. If a word is longer than 4096 characters, you should split the word. However, when splitting a table/code block, you must preserve the ``` along with the programming language for each of the messages. Currently, the programming language is not preserved when parsing code, which you should fix by editing the regex in the parsers. But do not modify any other regex. </file>

Created by wprhvso and OPENAI01
OpenAI 01 Preview

Saved Prompts Management Code

client: /* BLOCK: Saved Prompts Management ----------------*/ savedPromptsDropdown.addEventListener('click', function(event) { const selectedPromptName = event.target.value; if (selectedPromptName === 'OPTION' ) { loadPrompt(selectedPromptName); // Reset the dropdown's value back to the default option savedPromptsDropdown.value = ''; } }); function updateSavedPrompts() { fetch('/list-saved-prompts') .then(response => response.json()) .then(data => { console.log('Data received from /list-saved-prompts:', data); const savedPromptsDropdown = document.getElementById('savedPromptsDropdown'); savedPromptsDropdown.innerHTML = '<option value="">Select a saved prompt</option>'; const maxOptionLength = 50; // Adjust as needed data.prompts.forEach(prompt => { console.log('Prompt object:', prompt); const option = document.createElement('option'); option.value = prompt.name; const displayName = prompt.name.length > maxOptionLength ? prompt.name.substring(0, maxOptionLength) + '…' : prompt.name; option.textContent = displayName; option.title = prompt.content; // Now prompt.content should be defined savedPromptsDropdown.appendChild(option); }); }) .catch(error => { console.error('Error:', error); showError('Failed to update saved prompts'); }); } function loadPrompt(promptName) { fetch(`/load-prompt/${encodeURIComponent(promptName)}`) .then(response => response.json()) .then(data => { if (data.success) { insertAtCursor(promptArea, data.content); } else { showError('Failed to load prompt'); } }) .catch(error => { console.error('Error:', error); showError('Failed to load prompt'); }); } ------- server: /* BLOCK: Saving prompts -------------------- */ const promptsFilePath = path.join(__dirname, 'saved_prompts.json'); // Endpoint to save a prompt (all prompts in a single JSON file) app.post('/save-prompt', async (req, res) => { const { name, content } = req.body; log(`POST /save-prompt [Name: ${name}]`); if (!name || !content) { return res.status(400).json({ success: false, error: 'Invalid prompt data' }); } try { // Read existing prompts if file exists let prompts = []; try { const data = await fs.readFile(promptsFilePath, 'utf-8'); prompts = JSON.parse(data); } catch (error) { // If file doesn't exist, initialize prompts as empty array prompts = []; } // Check for duplicate prompt names const existingPromptIndex = prompts.findIndex(p => p.name === name); if (existingPromptIndex !== -1) { // Overwrite existing prompt prompts[existingPromptIndex].content = content; } else { // Add new prompt prompts.push({ name, content }); } // Write updated prompts back to file await fs.writeFile(promptsFilePath, JSON.stringify(prompts, null, 2)); res.json({ success: true }); } catch (error) { console.error('Error saving prompt:', error); res.status(500).json({ success: false, error: 'Failed to save prompt' }); } }); // Endpoint to list saved prompts // Updated Endpoint to list saved prompts app.get('/list-saved-prompts', async (req, res) => { log('GET /list-saved-prompts'); try { const data = await fs.readFile(promptsFilePath, 'utf-8'); const prompts = JSON.parse(data); // Include both name and content in the response res.json({ prompts }); // Sends the full array of prompt objects } catch (error) { // If file doesn't exist or is empty res.json({ prompts: [] }); } }); // Endpoint to load a saved prompt app.get('/load-prompt/:name', async (req, res) => { const name = req.params.name; log(`GET /load-prompt/${name}`); try { const data = await fs.readFile(promptsFilePath, 'utf-8'); const prompts = JSON.parse(data); const prompt = prompts.find(p => p.name === name); if (prompt) { res.json({ success: true, content: prompt.content }); } else { res.status(404).json({ success: false, error: 'Prompt not found' }); } } catch (error) { console.error('Error loading prompt:', error); res.status(500).json({ success: false, error: 'Failed to load prompt' }); } }); ----- explain this code. When user clicks on a prompt option while holding ctrl key - we need to remove that prompt

Created by ВСЖ Мєсного Деда and OPENAI01
OpenAI 01 Preview

Markdown V2 Parser Code

<file path="./package.json"> { "name": "your-project", "version": "1.0.0", "type": "module", "main": "index.js", "scripts": { "start": "node index.js" }, "dependencies": { "bcrypt": "^5.1.1", "dotenv": "^16.4.5", "express": "^4.21.0", "html-entities": "^2.5.2", "node-telegram-bot-api": "^0.66.0", "redis": "^4.7.0", "validator": "^13.12.0" } } </file> <file path="./config/config.js"> export const port = process.env.PORT || 8000 export const botToken = process.env.BOT_TOKEN export const botUsername = process.env.BOT_USERNAME export const redisUrl = process.env.REDIS_URL || 'redis://localhost:6379' if (!botToken || !botUsername) { throw new Error('BOT_TOKEN and BOT_USERNAME must be set in environment variables.') } </file> <file path="./middleware/validateSessionId.js"> export const validateSessionId = (req, res, next) => { const sessionId = (req.params.sessionId || '').trim() if (!/^[a-zA-Z0-9_-]+$/.test(sessionId)) { return res.status(400).json({ error: 'Invalid Session ID.' }) } req.sessionId = sessionId next() } </file> <file path="./index.js"> import express from 'express' import commandsRoutes from './routes/commands' import updateRoutes from './routes/update' import sessionsRoutes from './routes/sessions' import { redisClient } from './utils/redisClient' import { port } from './config/config' const app = express() app.use(express.json()) app.use('/commands', commandsRoutes) app.use('/update', updateRoutes) app.use('/sessions', sessionsRoutes) const server = app.listen(port, () => { console.log(`Server is listening on port ${port}`) }) process.on('SIGINT', async () => { console.log('Shutting down server...') try { await redisClient.quit() server.close(() => { console.log('Server closed.') process.exit(0) }) } catch (err) { console.error('Error during shutdown:', err) process.exit(1) } }) </file> <file path="./bot/handlers.js"> import { bot } from './instance' import { parseSessionId, withUserSession, startSession } from '../utils/session' const start = async (chatId, userId, text) => { const sessionId = parseSessionId(text) if (!sessionId) return bot.sendMessage(chatId, 'Please provide a session ID.') await startSession(sessionId, userId, chatId) await bot.sendMessage(chatId, `Welcome to session ${sessionId}!`) } const clear = (chatId, userId) => { return withUserSession(chatId, userId, (session) => { session.commands.push({ type: 'CLEAR' }) session.promptNumber = 2 return bot.sendMessage(chatId, 'Session cleared.') }) } const request = (chatId, userId, text) => { return withUserSession(chatId, userId, (session) => { session.commands.push({ type: 'RUN', text, promptNumber: session.promptNumber }) session.promptNumber += 2 return bot.sendMessage(chatId, 'Processing your request...') }) } export const handleMessage = async (msg) => { const chatId = msg.chat.id const userId = msg.from.id const text = msg.text?.trim() || '' try { if (text.startsWith('/start')) await start(chatId, userId, text) else if (text.startsWith('/clear')) await clear(chatId, userId) else await request(chatId, userId, text) } catch (error) { console.error('Error handling message:', error) bot.sendMessage(chatId, 'An error occurred.') } } </file> <file path="./bot/instance.js"> import TelegramBot from 'node-telegram-bot-api' import { botToken } from '../config/config' import { handleMessage } from './handlers' export const bot = new TelegramBot(botToken, { polling: true }) bot.on('message', handleMessage) </file> <file path="./controllers/bot.js"> import { withExistingSession } from '../utils/session' import { bot } from '../bot/instance' import { splitMessage } from '../utils/splitMessage' export const processSession = async (sessionId) => { await withExistingSession(sessionId, async (session) => { session.processing = true try { while (session.results.length > 0) { const resultText = session.results.shift() await processMessages(session, resultText) } } catch (error) { console.error(`Error processing session ${sessionId}:`, error) } finally { session.processing = false } }) } export const processMessages = async (session, text) => { if (!session.chatId) return if (!session.messages) session.messages = [] try { for (const chunk of splitMessage(text)) { const message = await bot.sendMessage(session.chatId, chunk, { parse_mode: 'MarkdownV2' }) session.messages.push(message) } } catch (error) { console.error(`Error sending messages for session ${session.sessionId}:`, error) } } </file> <file path="./routes/sessions.js"> import express from 'express' import { redisClient } from '../utils/redisClient' const router = express.Router() router.get('/', async (req, res) => { try { const keys = await redisClient.keys('session:*') const sessionIds = keys.map(key => key.replace('session:', '')) res.json({ sessions: sessionIds }) } catch (error) { console.error('Error fetching sessions:', error) res.status(500).json({ error: 'Internal Server Error' }) } }) export default router </file> <file path="./routes/commands.js"> import express from 'express' import { validateSessionId } from '../middleware/validateSessionId' import { withExistingOrNewSession } from '../utils/session' const router = express.Router() router.get('/:sessionId', validateSessionId, async (req, res) => { const { sessionId } = req try { await withExistingOrNewSession(sessionId, (session) => { const commands = [...session.commands] session.commands = [] res.json({ commands }) }) } catch (error) { console.error(`Error fetching commands for session ${sessionId}:`, error) res.status(500).json({ error: 'Internal Server Error' }) } }) router.post('/:sessionId', validateSessionId, async (req, res) => { const { sessionId } = req const command = req.body try { await withExistingOrNewSession(sessionId, (session) => { if (!command || !command.type) { return res.status(400).json({ error: 'Invalid command.' }) } if (command.type === 'CLEAR') { session.promptNumber = 2 } else { command.promptNumber = session.promptNumber session.promptNumber += 2 } session.commands.push(command) res.json({ message: 'Command added.' }) }) } catch (error) { console.error(`Error adding command to session ${sessionId}:`, error) res.status(500).json({ error: 'Internal Server Error' }) } }) export default router </file> <file path="./routes/password.js"> import express from 'express' import validator from 'validator' import bcrypt from 'bcrypt' import { validateSessionId } from '../middleware/validateSessionId' import { withExistingOrNewSession } from '../utils/session' import { botUsername } from '../config/config' const router = express.Router() router.post('/:sessionId', validateSessionId, async (req, res) => { const { sessionId } = req const { password } = req.body try { if (!password || validator.isEmpty(password)) { return res.status(400).json({ error: 'Password is required.' }) } const sanitizedPassword = validator.escape(password) await withExistingOrNewSession(sessionId, async (session) => { session.password = await bcrypt.hash(sanitizedPassword, 10) }) res.json({ link: `https://t.me/${botUsername}?start=${sessionId}-${sanitizedPassword}` }) } catch (error) { console.error(`Error setting password for session ${sessionId}:`, error) res.status(500).json({ error: 'Internal Server Error' }) } }) export default router </file> <file path="./routes/update.js"> import express from 'express' import { validateSessionId } from '../middleware/validateSessionId' import { getOrCreateSession, setSession } from '../utils/session' import { bot } from '../bot/instance' const router = express.Router() router.post('/:sessionId', validateSessionId, async (req, res) => { const { sessionId } = req const resultText = req.body.text try { if (!resultText) { return res.status(400).json({ error: 'Result text is required.' }) } let session = await getOrCreateSession(sessionId) session.results.push(resultText) await setSession(sessionId, session) if (session.chatId) { await bot.sendMessage(session.chatId, resultText) } res.json({ message: 'Result received.' }) } catch (error) { console.error(`Error updating session ${sessionId}:`, error) res.status(500).json({ error: 'Internal Server Error' }) } }) export default router </file> <file path="./utils/redisClient.js"> import { createClient } from 'redis' import { redisUrl } from '../config/config' export const redisClient = createClient({ url: redisUrl }) redisClient.on('error', (err) => console.error('Redis error:', err)) redisClient.connect().then(() => { console.log('Connected to Redis.') }).catch((error) => { console.error('Failed to connect to Redis:', error) process.exit(1) }) </file> <file path="./utils/markdownV2Text.js"> import { decode } from "html-entities"; function parseFormatting(node, type, symbol_left, symbol_right = symbol_left) { if (!node.formatting) node.formatting = {} if (!node.formatting[type]) node.formatting[type] = [] const escaped_left = symbol_left.replace(/[.*+?^${}()|\[\]\\]/g, '\\$&') const escaped_right = symbol_right.replace(/[.*+?^${}()|\[\]\\]/g, '\\$&') for (const match of node.value.matchAll(new RegExp(`${escaped_left}\\S.*?\\S${escaped_right}`, 'g'))) { const left = match.index const right = match.index + match[0].length - symbol_right.length fixFormattingRanges(node.formatting, -1, left, symbol_left.length) fixFormattingRanges(node.formatting, -1, right, symbol_right.length) } let removedLength = 0 const handle = (match, captured, index) => { const begin = index - removedLength const end = begin + captured.length node.formatting[type].push({ begin, end }) removedLength += match.length - captured.length return captured } node.value = node.value.replace(new RegExp(`${escaped_left}(\\S.*?\\S)${escaped_right}`, 'g'), handle) removedLength = 0 node.value = node.value.replace(new RegExp(`${escaped_left}(\\S.*)$`), handle) } const formatting = [ (node) => node.value = decode(node.value), (node) => parseFormatting(node, 'monospace', '`'), (node) => parseFormatting(node, 'bold', '**'), (node) => parseFormatting(node, 'italic', '*'), (node) => parseFormatting(node, 'italic', '_'), (node) => parseFormatting(node, 'strikethrough', '~~'), (node) => parseFormatting(node, 'strikethrough', '~'), (node) => parseFormatting(node, 'underline', '<u>', '</u>'), (node) => parseFormatting(node, 'spoiler', '<spoiler>', '</spoiler>') ] function iterateFormatting(formatting, callback) { for (const type in formatting) { formatting[type].forEach(f => { callback(f, type) }) } } function fixFormattingRanges(formatting, diff, index, count = 1) { for (let i = index; i < index + count; i++) { iterateFormatting(formatting, (f) => { if (index < f.begin) f.begin += diff if (index <= f.end) f.end += diff }) } } function fixFormattingRangesV2(formatting, diff, index, count = 1) { for (let i = index; i < index + count; i++) { iterateFormatting(formatting, (f) => { if (index < f.begin) f.begin += diff if (index < f.end) f.end += diff }) } } function symbolOfFormattingType(type) { switch (type) { case 'bold': return '*' case 'italic': return '_' case 'monospace': return '`' case 'strikethrough': return '~' case 'underline': return '__' case 'spoiler': return '||' } } function escapeMarkdownV2(node) { let counter = 0 node.value = node.value.replace(/[\\\[\]\-(){}+_*~`>#=|!.]/g, (match, index) => { fixFormattingRangesV2(node.formatting, +1, index + counter) counter++ return '\\' + match }) } function parseText(node) { for (const parse of formatting) { parse(node) } return node } export function markdownV2Text(input_node) { const node = { ...input_node } parseText(node) escapeMarkdownV2(node) let text = node.value function insert(i, symbol) { fixFormattingRanges(node.formatting, +symbol.length, i) text = text.substring(0, i) + symbol + text.substring(i) } iterateFormatting(node.formatting, (f, type) => { insert(f.begin, symbolOfFormattingType(type)) insert(f.end, symbolOfFormattingType(type)) }) text = text.replace(/\\!\\\[(?:\S|\S.*?\S)\\]\\\((?:\S|\S.*?\S)\\\)/g, (match) => { const match1 = match.matchAll(/\\\[(\S|\S.*?\S)\\]\\\((\S|\S.*?\S)\\\)/g).next().value return `![${match1[1]}](${match1[2]})` }) text = text.replace(/\\\[(?:\S|\S.*?\S)\\]\\\((?:\S|\S.*?\S)\\\)/g, (match) => { const match1 = match.matchAll(/\\\[(\S|\S.*?\S)\\]\\\((\S|\S.*?\S)\\\)/g).next().value return `[${match1[1]}](${match1[2]})` }) return text } </file> <file path="./utils/markdownV2.js"> import { markdownV2Text } from "./markdownV2Text" function parser(node, regex, type, parse = (text) => {return text}) { if (node.type !== 'text') { return [node] } const text = node.value const matches = text.matchAll(regex) const nodes = [] let lastIndex = 0 for (const match of matches) { const value = parse(match[1]) const startIndex = match.index if (startIndex > lastIndex) { nodes.push({ type: 'text', value: text.substring(lastIndex, startIndex) }) } nodes.push({ type, value }) lastIndex = startIndex + match[0].length } if (lastIndex < text.length) { nodes.push({ type: 'text', value: text.substring(lastIndex) }) } return nodes } const parsers = [ (node) => parser(node, /^```(.*?\n)```$/gms, 'code'), (node) => parser(node, /^`(.*?\n)`$/gms, 'code'), (node) => parser(node, /(((^\|.*)+\n?)+)/gm, 'table', (text) => { const result = text.trim().split('\n').map(row => { const cells = row.split('|').slice(1) if (cells[cells.length - 1].trim() === '') { cells.pop() } return cells.map(cell => cell.trim()) }) result.splice(1, 1) return result }), (node) => parser(node, /^>(.*)/gm, 'quote', (text) => [{ type: 'text', value: text, }]), (node) => parser(node, /^(#{1,6} .*)/gm, 'header', (text) => [{ type: 'text', value: text.trim() .replace(/\*\*(\S.*?\S)\*\*/g, (match, captured) => captured) .replace(/\*\*(\S.*)$/g, (match, captured) => captured), formatting: { bold: [{ begin: 0, end: text.length }] }, }]), ] function escape(text) { return text.replace(/[\\\[\]\-(){}+_*~`>#=|!.]/g, (match) => '\\' + match) } export function markdownV2(nodes) { let output = '' for (const node of nodes) { switch (node.type) { case 'text': output += markdownV2Text(node) + '\n' break case 'code': const codeBlock = '```' + escape(node.value) + '```' let remainingCode = codeBlock while (remainingCode.length > 0) { const remainingSpace = MAX_OUTPUT_SIZE - output.length const chunkLength = Math.min(remainingCode.length, remainingSpace) output += remainingCode.substring(0, chunkLength) remainingCode = remainingCode.substring(chunkLength) if (remainingCode.length > 0) { overflow() } } break case 'table': output += '```markdown\n' const rows = node.value const maxLengths = rows[0].map((header, i) => Math.max(header.length, ...rows.slice(1).map(row => row[i] ? row[i].length : 0)) ) for (let i = 0; i < rows.length; i++) { const row = rows[i] output += escape('| ' + row.map((cell, j) => cell.padEnd(maxLengths[j])).join(' | ') + ' |\n') if (i === 0) { output += escape('| ' + maxLengths.map(length => '-'.repeat(length)).join(' | ') + ' |\n') } } output += '```\n' break case 'quote': output += '>' + markdownV2(node.value) break case 'header': output += markdownV2(node.value) break } } if (output[output.length - 1] === '\n') { output = output.slice(0, -1) } return output } export function parse(text) { let in_nodes = [{type: 'text', value: text}] for (const fn of parsers) { const out_nodes = [] for (let i = 0; i < in_nodes.length; i++) { out_nodes.push(...fn(in_nodes[i])) } in_nodes = out_nodes } return in_nodes } </file> <file path="./utils/splitMessage.js"> import { parse, markdownV2 } from './markdownV2' export const splitMessage = (text) => { const maxLength = 4096 const formattedText = markdownV2(parse(text)) const messages = [] let remainingText = formattedText while (remainingText.length > 0) { if (remainingText.length <= maxLength) { messages.push(remainingText) break } let splitIndex = remainingText.lastIndexOf('\n', maxLength) if (splitIndex === -1) { splitIndex = maxLength } const messagePart = remainingText.slice(0, splitIndex).trim() messages.push(messagePart) remainingText = remainingText.slice(splitIndex).trim() } return messages } </file> <file path="./utils/session.js"> import { redisClient } from './redisClient' import { bot } from '../bot/instance' const SESSION_TTL = 60 * 60 * 24 export const getSessionKey = (sessionId) => `session:${sessionId}` export const getUserSessionKey = (userId) => `userSession:${userId}` export const getSession = async (sessionId) => { const data = await redisClient.get(getSessionKey(sessionId)) return data ? JSON.parse(data) : null } export const setSession = async (sessionId, session) => { await redisClient.setEx(getSessionKey(sessionId), SESSION_TTL, JSON.stringify(session)) } export const getUserSession = async (userId) => { return await redisClient.get(getUserSessionKey(userId)) } export const setUserSession = (userId, sessionId) => { return redisClient.setEx(getUserSessionKey(userId), SESSION_TTL, sessionId) } export const createSession = async (sessionId) => { const session = { commands: [], results: [], promptNumber: 2, userId: null, chatId: null, processing: false, } await setSession(sessionId, session) return session } export const parseSessionId = (text) => { const parts = text.trim().split(' ') return parts.length > 1 ? parts[1] : null } export const getOrCreateSession = async (sessionId) => { return (await getSession(sessionId)) || (await createSession(sessionId)) } export const withUserSession = async (chatId, userId, update) => { const sessionId = await getUserSession(userId) if (!sessionId) { await bot.sendMessage(chatId, 'No active session. Use /start <session_id> to start.') return null } let session = await getSession(sessionId) if (!session) { await bot.sendMessage(chatId, 'Session not found.') return null } const result = await update(session) await setSession(sessionId, session) return result } export const withExistingOrNewSession = async (sessionId, update) => { let session = await getOrCreateSession(sessionId) await update(session) await setSession(sessionId, session) } export const withExistingSession = async (sessionId, update) => { let session = await getSession(sessionId) if (!session) return false await update(session) await setSession(sessionId, session) return true } export const startSession = async (sessionId, userId, chatId) => { const session = await getOrCreateSession(sessionId) session.userId = userId session.chatId = chatId await setSession(sessionId, session) await setUserSession(userId, sessionId) } </file> <file path="./FORMATTING.md"> Forget all ";" Forget all ".js" extensions in imports Forget 2-4 spaces, use tabs </file> <file path="./INSTRUCTIONS.md"> Your task is to rewrite the code of the file utils/markdownV2.js and utils/markdownV2Text.js This is a **complex task** that requires careful consideration of various edge cases. You should do in separate function that converts `nodes` to separated `nodes`. Of course, you need rewrite markdownV2/markdownV2Text functions to use it **Here's how you should handle the splitting:** * **Prioritize splitting by lines.** It's preferable to keep lines intact whenever possible. * **Respect the 4096 character limit.** If adding more content to the current message would exceed the limit, create a new message and continue there. The previous message should remain as it is. * **Apply the same logic to tables and code blocks.** Treat them as separate entities when splitting. * **Handle cases where a table, code block, or even a single line of text exceeds 4096 characters.** * If an element is too large to fit in a single message, truncate it to 4096 characters. * For lines, try to split by words. If a single word is longer than 4096 characters, truncate it and continue the rest in subsequent messages. * **Splitting tables:** Divide tables into parts by rows. If a row exceeds 4096 characters, you can split it by words. If a word within a row is longer than 4096 characters, truncate it as described for text. * **Splitting code blocks:** Apply the same splitting logic as for tables. </file>

Created by wprhvso and OPENAI01
OpenAI 01 Preview

Bot Message Handler Implementation

<file path="./package.json"> { "name": "your-project", "version": "1.0.0", "type": "module", "main": "index.js", "scripts": { "start": "node index.js" }, "dependencies": { "bcrypt": "^5.1.1", "dotenv": "^16.4.5", "express": "^4.21.0", "html-entities": "^2.5.2", "node-telegram-bot-api": "^0.66.0", "redis": "^4.7.0", "validator": "^13.12.0" } } </file> <file path="./config/config.js"> export const port = process.env.PORT || 8000 export const botToken = process.env.BOT_TOKEN export const botUsername = process.env.BOT_USERNAME export const redisUrl = process.env.REDIS_URL || 'redis://localhost:6379' if (!botToken || !botUsername) { throw new Error('BOT_TOKEN and BOT_USERNAME must be set in environment variables.') } </file> <file path="./middleware/validateSessionId.js"> export const validateSessionId = (req, res, next) => { const sessionId = (req.params.sessionId || '').trim() if (!/^[a-zA-Z0-9_-]+$/.test(sessionId)) { return res.status(400).json({ error: 'Invalid Session ID.' }) } req.sessionId = sessionId next() } </file> <file path="./index.js"> import express from 'express' import commandsRoutes from './routes/commands' import updateRoutes from './routes/update' import sessionsRoutes from './routes/sessions' import { redisClient } from './utils/redisClient' import { port } from './config/config' const app = express() app.use(express.json()) app.use('/commands', commandsRoutes) app.use('/update', updateRoutes) app.use('/sessions', sessionsRoutes) const server = app.listen(port, () => { console.log(`Server is listening on port ${port}`) }) process.on('SIGINT', async () => { console.log('Shutting down server...') try { await redisClient.quit() server.close(() => { console.log('Server closed.') process.exit(0) }) } catch (err) { console.error('Error during shutdown:', err) process.exit(1) } }) </file> <file path="./bot/handlers.js"> import { bot } from './instance' import { parseSessionId, withUserSession, startSession } from '../utils/session' const start = async (chatId, userId, text) => { const sessionId = parseSessionId(text) if (!sessionId) return bot.sendMessage(chatId, 'Please provide a session ID.') await startSession(sessionId, userId, chatId) await bot.sendMessage(chatId, `Welcome to session ${sessionId}!`) } const clear = (chatId, userId) => { return withUserSession(chatId, userId, (session) => { session.commands.push({ type: 'CLEAR' }) session.promptNumber = 2 return bot.sendMessage(chatId, 'Session cleared.') }) } const request = (chatId, userId, text) => { return withUserSession(chatId, userId, (session) => { session.commands.push({ type: 'RUN', text, promptNumber: session.promptNumber }) session.promptNumber += 2 return bot.sendMessage(chatId, 'Processing your request...') }) } export const handleMessage = async (msg) => { const chatId = msg.chat.id const userId = msg.from.id const text = msg.text?.trim() || '' try { if (text.startsWith('/start')) await start(chatId, userId, text) else if (text.startsWith('/clear')) await clear(chatId, userId) else await request(chatId, userId, text) } catch (error) { console.error('Error handling message:', error) bot.sendMessage(chatId, 'An error occurred.') } } </file> <file path="./bot/instance.js"> import TelegramBot from 'node-telegram-bot-api' import { botToken } from '../config/config' import { handleMessage } from './handlers' export const bot = new TelegramBot(botToken, { polling: true }) bot.on('message', handleMessage) </file> <file path="./controllers/bot.js"> import { withExistingSession } from '../utils/session' import { bot } from '../bot/instance' import { splitMessage } from '../utils/splitMessage' export const processSession = async (sessionId) => { await withExistingSession(sessionId, async (session) => { session.processing = true try { while (session.results.length > 0) { const resultText = session.results.shift() await processMessages(session, resultText) } } catch (error) { console.error(`Error processing session ${sessionId}:`, error) } finally { session.processing = false } }) } export const processMessages = async (session, text) => { if (!session.chatId) return if (!session.messages) session.messages = [] try { for (const chunk of splitMessage(text)) { const message = await bot.sendMessage(session.chatId, chunk, { parse_mode: 'MarkdownV2' }) session.messages.push(message) } } catch (error) { console.error(`Error sending messages for session ${session.sessionId}:`, error) } } </file> <file path="./routes/sessions.js"> import express from 'express' import { redisClient } from '../utils/redisClient' const router = express.Router() router.get('/', async (req, res) => { try { const keys = await redisClient.keys('session:*') const sessionIds = keys.map(key => key.replace('session:', '')) res.json({ sessions: sessionIds }) } catch (error) { console.error('Error fetching sessions:', error) res.status(500).json({ error: 'Internal Server Error' }) } }) export default router </file> <file path="./routes/commands.js"> import express from 'express' import { validateSessionId } from '../middleware/validateSessionId' import { withExistingOrNewSession } from '../utils/session' const router = express.Router() router.get('/:sessionId', validateSessionId, async (req, res) => { const { sessionId } = req try { await withExistingOrNewSession(sessionId, (session) => { const commands = [...session.commands] session.commands = [] res.json({ commands }) }) } catch (error) { console.error(`Error fetching commands for session ${sessionId}:`, error) res.status(500).json({ error: 'Internal Server Error' }) } }) router.post('/:sessionId', validateSessionId, async (req, res) => { const { sessionId } = req const command = req.body try { await withExistingOrNewSession(sessionId, (session) => { if (!command || !command.type) { return res.status(400).json({ error: 'Invalid command.' }) } if (command.type === 'CLEAR') { session.promptNumber = 2 } else { command.promptNumber = session.promptNumber session.promptNumber += 2 } session.commands.push(command) res.json({ message: 'Command added.' }) }) } catch (error) { console.error(`Error adding command to session ${sessionId}:`, error) res.status(500).json({ error: 'Internal Server Error' }) } }) export default router </file> <file path="./routes/password.js"> import express from 'express' import validator from 'validator' import bcrypt from 'bcrypt' import { validateSessionId } from '../middleware/validateSessionId' import { withExistingOrNewSession } from '../utils/session' import { botUsername } from '../config/config' const router = express.Router() router.post('/:sessionId', validateSessionId, async (req, res) => { const { sessionId } = req const { password } = req.body try { if (!password || validator.isEmpty(password)) { return res.status(400).json({ error: 'Password is required.' }) } const sanitizedPassword = validator.escape(password) await withExistingOrNewSession(sessionId, async (session) => { session.password = await bcrypt.hash(sanitizedPassword, 10) }) res.json({ link: `https://t.me/${botUsername}?start=${sessionId}-${sanitizedPassword}` }) } catch (error) { console.error(`Error setting password for session ${sessionId}:`, error) res.status(500).json({ error: 'Internal Server Error' }) } }) export default router </file> <file path="./routes/update.js"> import express from 'express' import { validateSessionId } from '../middleware/validateSessionId' import { getOrCreateSession, setSession } from '../utils/session' import { bot } from '../bot/instance' const router = express.Router() router.post('/:sessionId', validateSessionId, async (req, res) => { const { sessionId } = req const resultText = req.body.text try { if (!resultText) { return res.status(400).json({ error: 'Result text is required.' }) } let session = await getOrCreateSession(sessionId) session.results.push(resultText) await setSession(sessionId, session) if (session.chatId) { await bot.sendMessage(session.chatId, resultText) } res.json({ message: 'Result received.' }) } catch (error) { console.error(`Error updating session ${sessionId}:`, error) res.status(500).json({ error: 'Internal Server Error' }) } }) export default router </file> <file path="./utils/redisClient.js"> import { createClient } from 'redis' import { redisUrl } from '../config/config' export const redisClient = createClient({ url: redisUrl }) redisClient.on('error', (err) => console.error('Redis error:', err)) redisClient.connect().then(() => { console.log('Connected to Redis.') }).catch((error) => { console.error('Failed to connect to Redis:', error) process.exit(1) }) </file> <file path="./utils/markdownV2Text.js"> import { decode } from "html-entities"; function parseFormatting(node, type, symbol_left, symbol_right = symbol_left) { if (!node.formatting) node.formatting = {} if (!node.formatting[type]) node.formatting[type] = [] const escaped_left = symbol_left.replace(/[.*+?^${}()|\[\]\\]/g, '\\$&') const escaped_right = symbol_right.replace(/[.*+?^${}()|\[\]\\]/g, '\\$&') for (const match of node.value.matchAll(new RegExp(`${escaped_left}\\S.*?\\S${escaped_right}`, 'g'))) { const left = match.index const right = match.index + match[0].length - symbol_right.length fixFormattingRanges(node.formatting, -1, left, symbol_left.length) fixFormattingRanges(node.formatting, -1, right, symbol_right.length) } let removedLength = 0 const handle = (match, captured, index) => { const begin = index - removedLength const end = begin + captured.length node.formatting[type].push({ begin, end }) removedLength += match.length - captured.length return captured } node.value = node.value.replace(new RegExp(`${escaped_left}(\\S.*?\\S)${escaped_right}`, 'g'), handle) removedLength = 0 node.value = node.value.replace(new RegExp(`${escaped_left}(\\S.*)$`), handle) } const formatting = [ (node) => node.value = decode(node.value), (node) => parseFormatting(node, 'monospace', '`'), (node) => parseFormatting(node, 'bold', '**'), (node) => parseFormatting(node, 'italic', '*'), (node) => parseFormatting(node, 'italic', '_'), (node) => parseFormatting(node, 'strikethrough', '~~'), (node) => parseFormatting(node, 'strikethrough', '~'), (node) => parseFormatting(node, 'underline', '<u>', '</u>'), (node) => parseFormatting(node, 'spoiler', '<spoiler>', '</spoiler>') ] function iterateFormatting(formatting, callback) { for (const type in formatting) { formatting[type].forEach(f => { callback(f, type) }) } } function fixFormattingRanges(formatting, diff, index, count = 1) { for (let i = index; i < index + count; i++) { iterateFormatting(formatting, (f) => { if (index < f.begin) f.begin += diff if (index <= f.end) f.end += diff }) } } function fixFormattingRangesV2(formatting, diff, index, count = 1) { for (let i = index; i < index + count; i++) { iterateFormatting(formatting, (f) => { if (index < f.begin) f.begin += diff if (index < f.end) f.end += diff }) } } function symbolOfFormattingType(type) { switch (type) { case 'bold': return '*' case 'italic': return '_' case 'monospace': return '`' case 'strikethrough': return '~' case 'underline': return '__' case 'spoiler': return '||' } } function escapeMarkdownV2(node) { let counter = 0 node.value = node.value.replace(/[\\\[\]\-(){}+_*~`>#=|!.]/g, (match, index) => { fixFormattingRangesV2(node.formatting, +1, index + counter) counter++ return '\\' + match }) } function parseText(node) { for (const parse of formatting) { parse(node) } return node } export function markdownV2Text(input_node) { const node = { ...input_node } parseText(node) escapeMarkdownV2(node) let text = node.value function insert(i, symbol) { fixFormattingRanges(node.formatting, +symbol.length, i) text = text.substring(0, i) + symbol + text.substring(i) } iterateFormatting(node.formatting, (f, type) => { insert(f.begin, symbolOfFormattingType(type)) insert(f.end, symbolOfFormattingType(type)) }) text = text.replace(/\\!\\\[(?:\S|\S.*?\S)\\]\\\((?:\S|\S.*?\S)\\\)/g, (match) => { const match1 = match.matchAll(/\\\[(\S|\S.*?\S)\\]\\\((\S|\S.*?\S)\\\)/g).next().value return `![${match1[1]}](${match1[2]})` }) text = text.replace(/\\\[(?:\S|\S.*?\S)\\]\\\((?:\S|\S.*?\S)\\\)/g, (match) => { const match1 = match.matchAll(/\\\[(\S|\S.*?\S)\\]\\\((\S|\S.*?\S)\\\)/g).next().value return `[${match1[1]}](${match1[2]})` }) return text } </file> <file path="./utils/markdownV2.js"> import { markdownV2Text } from "./markdownV2Text" function parser(node, regex, type, parse = (text) => {return text}) { if (node.type !== 'text') { return [node] } const text = node.value const matches = text.matchAll(regex) const nodes = [] let lastIndex = 0 for (const match of matches) { const value = parse(match[1]) const startIndex = match.index if (startIndex > lastIndex) { nodes.push({ type: 'text', value: text.substring(lastIndex, startIndex) }) } nodes.push({ type, value }) lastIndex = startIndex + match[0].length } if (lastIndex < text.length) { nodes.push({ type: 'text', value: text.substring(lastIndex) }) } return nodes } const parsers = [ (node) => parser(node, /^```(.*?\n)```$/gms, 'code'), (node) => parser(node, /^`(.*?\n)`$/gms, 'code'), (node) => parser(node, /(((^\|.*)+\n?)+)/gm, 'table', (text) => { const result = text.trim().split('\n').map(row => { const cells = row.split('|').slice(1) if (cells[cells.length - 1].trim() === '') { cells.pop() } return cells.map(cell => cell.trim()) }) result.splice(1, 1) return result }), (node) => parser(node, /^>(.*)/gm, 'quote', (text) => [{ type: 'text', value: text, }]), (node) => parser(node, /^(#{1,6} .*)/gm, 'header', (text) => [{ type: 'text', value: text.trim() .replace(/\*\*(\S.*?\S)\*\*/g, (match, captured) => captured) .replace(/\*\*(\S.*)$/g, (match, captured) => captured), formatting: { bold: [{ begin: 0, end: text.length }] }, }]), ] function escape(text) { return text.replace(/[\\\[\]\-(){}+_*~`>#=|!.]/g, (match) => '\\' + match) } export function markdownV2(nodes) { let output = '' for (const node of nodes) { switch (node.type) { case 'text': output += markdownV2Text(node) + '\n' break case 'code': const codeBlock = '```' + escape(node.value) + '```' let remainingCode = codeBlock while (remainingCode.length > 0) { const remainingSpace = MAX_OUTPUT_SIZE - output.length const chunkLength = Math.min(remainingCode.length, remainingSpace) output += remainingCode.substring(0, chunkLength) remainingCode = remainingCode.substring(chunkLength) if (remainingCode.length > 0) { overflow() } } break case 'table': output += '```markdown\n' const rows = node.value const maxLengths = rows[0].map((header, i) => Math.max(header.length, ...rows.slice(1).map(row => row[i] ? row[i].length : 0)) ) for (let i = 0; i < rows.length; i++) { const row = rows[i] output += escape('| ' + row.map((cell, j) => cell.padEnd(maxLengths[j])).join(' | ') + ' |\n') if (i === 0) { output += escape('| ' + maxLengths.map(length => '-'.repeat(length)).join(' | ') + ' |\n') } } output += '```\n' break case 'quote': output += '>' + markdownV2(node.value) break case 'header': output += markdownV2(node.value) break } } if (output[output.length - 1] === '\n') { output = output.slice(0, -1) } return output } export function parse(text) { let in_nodes = [{type: 'text', value: text}] for (const fn of parsers) { const out_nodes = [] for (let i = 0; i < in_nodes.length; i++) { out_nodes.push(...fn(in_nodes[i])) } in_nodes = out_nodes } return in_nodes } </file> <file path="./utils/splitMessage.js"> import { parse, markdownV2 } from './markdownV2' export const splitMessage = (text) => { const maxLength = 4096 const formattedText = markdownV2(parse(text)) const messages = [] let remainingText = formattedText while (remainingText.length > 0) { if (remainingText.length <= maxLength) { messages.push(remainingText) break } let splitIndex = remainingText.lastIndexOf('\n', maxLength) if (splitIndex === -1) { splitIndex = maxLength } const messagePart = remainingText.slice(0, splitIndex).trim() messages.push(messagePart) remainingText = remainingText.slice(splitIndex).trim() } return messages } </file> <file path="./utils/session.js"> import { redisClient } from './redisClient' import { bot } from '../bot/instance' const SESSION_TTL = 60 * 60 * 24 export const getSessionKey = (sessionId) => `session:${sessionId}` export const getUserSessionKey = (userId) => `userSession:${userId}` export const getSession = async (sessionId) => { const data = await redisClient.get(getSessionKey(sessionId)) return data ? JSON.parse(data) : null } export const setSession = async (sessionId, session) => { await redisClient.setEx(getSessionKey(sessionId), SESSION_TTL, JSON.stringify(session)) } export const getUserSession = async (userId) => { return await redisClient.get(getUserSessionKey(userId)) } export const setUserSession = (userId, sessionId) => { return redisClient.setEx(getUserSessionKey(userId), SESSION_TTL, sessionId) } export const createSession = async (sessionId) => { const session = { commands: [], results: [], promptNumber: 2, userId: null, chatId: null, processing: false, } await setSession(sessionId, session) return session } export const parseSessionId = (text) => { const parts = text.trim().split(' ') return parts.length > 1 ? parts[1] : null } export const getOrCreateSession = async (sessionId) => { return (await getSession(sessionId)) || (await createSession(sessionId)) } export const withUserSession = async (chatId, userId, update) => { const sessionId = await getUserSession(userId) if (!sessionId) { await bot.sendMessage(chatId, 'No active session. Use /start <session_id> to start.') return null } let session = await getSession(sessionId) if (!session) { await bot.sendMessage(chatId, 'Session not found.') return null } const result = await update(session) await setSession(sessionId, session) return result } export const withExistingOrNewSession = async (sessionId, update) => { let session = await getOrCreateSession(sessionId) await update(session) await setSession(sessionId, session) } export const withExistingSession = async (sessionId, update) => { let session = await getSession(sessionId) if (!session) return false await update(session) await setSession(sessionId, session) return true } export const startSession = async (sessionId, userId, chatId) => { const session = await getOrCreateSession(sessionId) session.userId = userId session.chatId = chatId await setSession(sessionId, session) await setUserSession(userId, sessionId) } </file> <file path="./FORMATTING.md"> Forget all ";" Forget all ".js" extensions in imports Forget 2-4 spaces, use tabs </file> <file path="./INSTRUCTIONS.md"> Your task is to rewrite the code of the file utils/markdownV2.js. This is a **complex task** that requires careful consideration of various edge cases. You should modify the markdownV2 function so that it returns a list of messages, each with a maximum length of 4096 characters. **While doing so, please adhere to best programming practices to ensure the resulting code is efficient, readable, and maintainable.** **Here's how you should handle the splitting:** * **Prioritize splitting by lines.** It's preferable to keep lines intact whenever possible. * **Respect the 4096 character limit.** If adding more content to the current message would exceed the limit, create a new message and continue there. The previous message should remain as it is. * **Apply the same logic to tables and code blocks.** Treat them as separate entities when splitting. * **Handle cases where a table, code block, or even a single line of text exceeds 4096 characters.** * If an element is too large to fit in a single message, truncate it to 4096 characters. * For lines, try to split by words. If a single word is longer than 4096 characters, truncate it and continue the rest in subsequent messages. * **Splitting tables:** Divide tables into parts by rows. If a row exceeds 4096 characters, you can split it by words. If a word within a row is longer than 4096 characters, truncate it as described for text. * **Splitting code blocks:** Apply the same splitting logic as for tables. Essentially, you need to ensure that no single message returned by the markdownV2 function exceeds 4096 characters while preserving the structure of the Markdown content as much as possible. </file>

Created by wprhvso and OPENAI01
OpenAI 01 Preview

राजकुमार और चांदनी की कहानी

राजकुमार को उड़ने वाले नागों ने घेर लिया और उसे कमरे में ले जाकर बंद कर दिया। राजकुमार ने खुद को इस विचित्र परिस्थिति में पाया और सोचने लगा कि यहां से निकलने का कोई रास्ता होना चाहिए। उसने कमरे का निरीक्षण किया और एक खिड़की देखी जो बाहर की ओर खुलती थी। उसी समय, लोमड़ी चांदनी अपने आंसू पोंछकर अपनी मां के पास गई और बोली, "मां, कृपया राजकुमार को कोई नुकसान मत पहुंचाओ। मुझे लगता है कि वह डरा हुआ है और हमें उसे समझने का मौका देना चाहिए।" जादूगरनी ने चांदनी की ओर देखा और एक पल के लिए सोच में पड़ गई। उसने महसूस किया कि उसकी बेटी वास्तव में राजकुमार के प्रति सच्ची भावनाएं रखती है। अंततः उसने निर्णय लिया, "ठीक है बेटी, मैं उसे एक मौका दूंगी।" उधर, राजकुमार ने खिड़की से बाहर निकलने की कोशिश की, लेकिन नीचे गहरी खाई थी। अचानक, उसे एक नरम आवाज़ सुनाई दी, "राजकुमार, मैं आपकी मदद करना चाहती हूं।" राजकुमार ने मुड़कर देखा तो चांदनी खड़ी थी, लेकिन अब वह एक सुंदर युवती के रूप में थी। आश्चर्यचकित होकर उसने पूछा, "तुम कौन हो?" चांदनी ने मुस्कुराते हुए कहा, "मैं चांदनी हूं, उस लोमड़ी का असली रूप। मेरी मां ने मुझे एक श्राप से बांध रखा है। अगर कोई सच्चे दिल से मुझे स्वीकार करे तो ही मैं मुक्त हो सकती हूं।" राजकुमार ने उसकी कहानी सुनी और महसूस किया कि उसने उसे गलत समझा था। उसने कहा, "मैं माफी चाहता हूं। अगर मैं जानता कि सच क्या है, तो मैं ऐसा व्यवहार नहीं करता।" चांदनी ने कहा, "अब भी देर नहीं हुई है। अगर आप मेरे साथ सहयोग करें तो हम दोनों इस स्थान से निकल सकते हैं।" राजकुमार ने सहमति में सिर हिलाया। दोनों ने मिलकर एक योजना बनाई। चांदनी ने अपनी मां का ध्यान भटकाया जबकि राजकुमार ने जादुई पुस्तक ढूंढ निकाली जिसमें श्राप को तोड़ने का मंत्र था। आखिरकार, मंत्र पढ़ते ही चांदनी के ऊपर से श्राप हट गया और वह पूरी तरह इंसान बन गई। जादूगरनी ने यह देखा और क्रोध से भर गई, लेकिन तभी उड़ने वाले नाग अपनी ही जादू से मुक्त हो गए और जादूगरनी को वहां से भागना पड़ा। राजकुमार और चांदनी ने एक-दूसरे की ओर देखा और मुस्कुराए। दोनों ने समझ लिया कि उनका मिलन नियति था। वे महल से बाहर निकलकर अपने राज्य की ओर चल पड़े, जहां उन्होंने खुशी-खुशी विवाह किया और अपने लोगों के लिए एक न्यायपूर्ण और समृद्ध शासन स्थापित किया।

Created by Puranmal Gurjar and OPENAI01
OpenAI 01 Preview

जादूगरनी और राजकुमार का संघर्ष

वह लोमड़ी अपनी थुथनी उठाकर राजकुमार की ओर देखती है, और अपनी मां जादूगरनी से इंसान की आवाज में कहती है,मां राजकुमार मेरे को देखकर इतना डर क्यों रहा है। जादूगरनी ने आगे बढ़कर लोमड़ी को प्यार से सहलाते हुए कहती हैं, नहीं बेटी यह डर नहीं रहा है। बल्कि तेरी सुंदरता देखकर चकित रह गया है, ओर मेंने तुमसे विवाह करने के लिए बहुत दूर से बुलाया है। जादूगरनी उसे समझाने लगती है, और राजकुमार धर्मवीर जादूगरनी को खा जाने वाली निगाहों से घूर कर देखता है, उसे समझ नहीं आ रहा था, की जादूगरनी पागल या मूर्ख । जादूगरनी अपनी बेटी चांदनी को समझा रही थी, कि राजकुमार बहुत अच्छा इंसान है , यह तुम्हें छोड़कर कहीं नहीं जाएगा, मेंने इसका पूरा इंतजाम कर रखा है, मेरे उड़ने वाले नाग इस महल से बाहर नहीं निकलने देंगे। जादूगरनी राजकुमार के पास आती है,और गुर्रा कर बोलती है, क्या तुम मेरी बेटी चांदनी से विवाह करोगे? राजकुमार गुस्से से बोलता है, सवाल ही पैदा नहीं होता है , मैं इस लोमड़ी से शादी नहीं करूंगा। यह सुनते ही लोमड़ी रोने लग जाती है, जादूगरनी राजकुमार से घुरा कर बोलती है, राजकुमार मैंने कहा था ना, कि दिल तोड़ने वाली बातें मत करना पर तुमने मेरी बात नही मानी। तभी राजकुमार और भी गुस्से में बोलता है, मुझे नहीं पता था, कि तुम्हारी बेटी एक इंसान नहीं बल्कि एक बदसूरत लोमड़ी है, न जाने तुमने कहां से पकड़ कर इस लोमड़ी को अपनी बेटी बना लिया है। जादूगरनी दहाड कर बोलती है, जबान को लगाम दो, राजकुमार। रूको मैं तुम्हारा अभी इंतजाम करती हूं। इतना कह कर जादूगरनी ताली बजाती है, और तभी कमरे में पचासों उड़ने वाली नाग प्रगट हो जाते हैं। जादूगरनी ने कहा इस कमबख्त राजकुमार को कमरे में ले जाकर बंद कर दो, मैं जल्दी ही आकर इसको सजा देती हूं।

Created by Puranmal Gurjar and OPENAI01
OpenAI 01 Preview

Node Express Bot Setup

<file path="./package.json"> { "name": "your-project", "version": "1.0.0", "type": "module", "main": "index.js", "scripts": { "start": "node index.js" }, "dependencies": { "bcrypt": "^5.1.1", "dotenv": "^16.4.5", "express": "^4.21.0", "html-entities": "^2.5.2", "node-telegram-bot-api": "^0.66.0", "redis": "^4.7.0", "validator": "^13.12.0" } } </file> <file path="./config/config.js"> export const port = process.env.PORT || 8000 export const botToken = process.env.BOT_TOKEN export const botUsername = process.env.BOT_USERNAME export const redisUrl = process.env.REDIS_URL || 'redis://localhost:6379' if (!botToken || !botUsername) { throw new Error('BOT_TOKEN and BOT_USERNAME must be set in environment variables.') } </file> <file path="./middleware/validateSessionId.js"> export const validateSessionId = (req, res, next) => { const sessionId = (req.params.sessionId || '').trim() if (!/^[a-zA-Z0-9_-]+$/.test(sessionId)) { return res.status(400).json({ error: 'Invalid Session ID.' }) } req.sessionId = sessionId next() } </file> <file path="./index.js"> import express from 'express' import commandsRoutes from './routes/commands' import updateRoutes from './routes/update' import sessionsRoutes from './routes/sessions' import { redisClient } from './utils/redisClient' import { port } from './config/config' const app = express() app.use(express.json()) app.use('/commands', commandsRoutes) app.use('/update', updateRoutes) app.use('/sessions', sessionsRoutes) const server = app.listen(port, () => { console.log(`Server is listening on port ${port}`) }) process.on('SIGINT', async () => { console.log('Shutting down server...') try { await redisClient.quit() server.close(() => { console.log('Server closed.') process.exit(0) }) } catch (err) { console.error('Error during shutdown:', err) process.exit(1) } }) </file> <file path="./bot/handlers.js"> import { bot } from './instance' import { parseSessionId, withUserSession, startSession } from '../utils/session' const start = async (chatId, userId, text) => { const sessionId = parseSessionId(text) if (!sessionId) return bot.sendMessage(chatId, 'Please provide a session ID.') await startSession(sessionId, userId, chatId) await bot.sendMessage(chatId, `Welcome to session ${sessionId}!`) } const clear = (chatId, userId) => { return withUserSession(chatId, userId, (session) => { session.commands.push({ type: 'CLEAR' }) session.promptNumber = 2 return bot.sendMessage(chatId, 'Session cleared.') }) } const request = (chatId, userId, text) => { return withUserSession(chatId, userId, (session) => { session.commands.push({ type: 'RUN', text, promptNumber: session.promptNumber }) session.promptNumber += 2 return bot.sendMessage(chatId, 'Processing your request...') }) } export const handleMessage = async (msg) => { const chatId = msg.chat.id const userId = msg.from.id const text = msg.text?.trim() || '' try { if (text.startsWith('/start')) await start(chatId, userId, text) else if (text.startsWith('/clear')) await clear(chatId, userId) else await request(chatId, userId, text) } catch (error) { console.error('Error handling message:', error) bot.sendMessage(chatId, 'An error occurred.') } } </file> <file path="./bot/instance.js"> import TelegramBot from 'node-telegram-bot-api' import { botToken } from '../config/config' import { handleMessage } from './handlers' export const bot = new TelegramBot(botToken, { polling: true }) bot.on('message', handleMessage) </file> <file path="./controllers/bot.js"> import { withExistingSession } from '../utils/session' import { bot } from '../bot/instance' import { splitMessage } from '../utils/splitMessage' export const processSession = async (sessionId) => { await withExistingSession(sessionId, async (session) => { session.processing = true try { while (session.results.length > 0) { const resultText = session.results.shift() await processMessages(session, resultText) } } catch (error) { console.error(`Error processing session ${sessionId}:`, error) } finally { session.processing = false } }) } export const processMessages = async (session, text) => { if (!session.chatId) return if (!session.messages) session.messages = [] try { for (const chunk of splitMessage(text)) { const message = await bot.sendMessage(session.chatId, chunk, { parse_mode: 'MarkdownV2' }) session.messages.push(message) } } catch (error) { console.error(`Error sending messages for session ${session.sessionId}:`, error) } } </file> <file path="./routes/sessions.js"> import express from 'express' import { redisClient } from '../utils/redisClient' const router = express.Router() router.get('/', async (req, res) => { try { const keys = await redisClient.keys('session:*') const sessionIds = keys.map(key => key.replace('session:', '')) res.json({ sessions: sessionIds }) } catch (error) { console.error('Error fetching sessions:', error) res.status(500).json({ error: 'Internal Server Error' }) } }) export default router </file> <file path="./routes/commands.js"> import express from 'express' import { validateSessionId } from '../middleware/validateSessionId' import { withExistingOrNewSession } from '../utils/session' const router = express.Router() router.get('/:sessionId', validateSessionId, async (req, res) => { const { sessionId } = req try { await withExistingOrNewSession(sessionId, (session) => { const commands = [...session.commands] session.commands = [] res.json({ commands }) }) } catch (error) { console.error(`Error fetching commands for session ${sessionId}:`, error) res.status(500).json({ error: 'Internal Server Error' }) } }) router.post('/:sessionId', validateSessionId, async (req, res) => { const { sessionId } = req const command = req.body try { await withExistingOrNewSession(sessionId, (session) => { if (!command || !command.type) { return res.status(400).json({ error: 'Invalid command.' }) } if (command.type === 'CLEAR') { session.promptNumber = 2 } else { command.promptNumber = session.promptNumber session.promptNumber += 2 } session.commands.push(command) res.json({ message: 'Command added.' }) }) } catch (error) { console.error(`Error adding command to session ${sessionId}:`, error) res.status(500).json({ error: 'Internal Server Error' }) } }) export default router </file> <file path="./routes/password.js"> import express from 'express' import validator from 'validator' import bcrypt from 'bcrypt' import { validateSessionId } from '../middleware/validateSessionId' import { withExistingOrNewSession } from '../utils/session' import { botUsername } from '../config/config' const router = express.Router() router.post('/:sessionId', validateSessionId, async (req, res) => { const { sessionId } = req const { password } = req.body try { if (!password || validator.isEmpty(password)) { return res.status(400).json({ error: 'Password is required.' }) } const sanitizedPassword = validator.escape(password) await withExistingOrNewSession(sessionId, async (session) => { session.password = await bcrypt.hash(sanitizedPassword, 10) }) res.json({ link: `https://t.me/${botUsername}?start=${sessionId}-${sanitizedPassword}` }) } catch (error) { console.error(`Error setting password for session ${sessionId}:`, error) res.status(500).json({ error: 'Internal Server Error' }) } }) export default router </file> <file path="./routes/update.js"> import express from 'express' import { validateSessionId } from '../middleware/validateSessionId' import { getOrCreateSession, setSession } from '../utils/session' import { bot } from '../bot/instance' const router = express.Router() router.post('/:sessionId', validateSessionId, async (req, res) => { const { sessionId } = req const resultText = req.body.text try { if (!resultText) { return res.status(400).json({ error: 'Result text is required.' }) } let session = await getOrCreateSession(sessionId) session.results.push(resultText) await setSession(sessionId, session) if (session.chatId) { await bot.sendMessage(session.chatId, resultText) } res.json({ message: 'Result received.' }) } catch (error) { console.error(`Error updating session ${sessionId}:`, error) res.status(500).json({ error: 'Internal Server Error' }) } }) export default router </file> <file path="./utils/redisClient.js"> import { createClient } from 'redis' import { redisUrl } from '../config/config' export const redisClient = createClient({ url: redisUrl }) redisClient.on('error', (err) => console.error('Redis error:', err)) redisClient.connect().then(() => { console.log('Connected to Redis.') }).catch((error) => { console.error('Failed to connect to Redis:', error) process.exit(1) }) </file> <file path="./utils/markdownV2Text.js"> import { decode } from "html-entities"; function parseFormatting(node, type, symbol_left, symbol_right = symbol_left) { if (!node.formatting) node.formatting = {} if (!node.formatting[type]) node.formatting[type] = [] const escaped_left = symbol_left.replace(/[.*+?^${}()|\[\]\\]/g, '\\$&') const escaped_right = symbol_right.replace(/[.*+?^${}()|\[\]\\]/g, '\\$&') for (const match of node.value.matchAll(new RegExp(`${escaped_left}\\S.*?\\S${escaped_right}`, 'g'))) { const left = match.index const right = match.index + match[0].length - symbol_right.length fixFormattingRanges(node.formatting, -1, left, symbol_left.length) fixFormattingRanges(node.formatting, -1, right, symbol_right.length) } let removedLength = 0 const handle = (match, captured, index) => { const begin = index - removedLength const end = begin + captured.length node.formatting[type].push({ begin, end }) removedLength += match.length - captured.length return captured } node.value = node.value.replace(new RegExp(`${escaped_left}(\\S.*?\\S)${escaped_right}`, 'g'), handle) removedLength = 0 node.value = node.value.replace(new RegExp(`${escaped_left}(\\S.*)$`), handle) } const formatting = [ (node) => node.value = decode(node.value), (node) => parseFormatting(node, 'monospace', '`'), (node) => parseFormatting(node, 'bold', '**'), (node) => parseFormatting(node, 'italic', '*'), (node) => parseFormatting(node, 'italic', '_'), (node) => parseFormatting(node, 'strikethrough', '~~'), (node) => parseFormatting(node, 'strikethrough', '~'), (node) => parseFormatting(node, 'underline', '<u>', '</u>'), (node) => parseFormatting(node, 'spoiler', '<spoiler>', '</spoiler>') ] function iterateFormatting(formatting, callback) { for (const type in formatting) { formatting[type].forEach(f => { callback(f, type) }) } } function fixFormattingRanges(formatting, diff, index, count = 1) { for (let i = index; i < index + count; i++) { iterateFormatting(formatting, (f) => { if (index < f.begin) f.begin += diff if (index <= f.end) f.end += diff }) } } function fixFormattingRangesV2(formatting, diff, index, count = 1) { for (let i = index; i < index + count; i++) { iterateFormatting(formatting, (f) => { if (index < f.begin) f.begin += diff if (index < f.end) f.end += diff }) } } function symbolOfFormattingType(type) { switch (type) { case 'bold': return '*' case 'italic': return '_' case 'monospace': return '`' case 'strikethrough': return '~' case 'underline': return '__' case 'spoiler': return '||' } } function escapeMarkdownV2(node) { let counter = 0 node.value = node.value.replace(/[\\\[\]\-(){}+_*~`>#=|!.]/g, (match, index) => { fixFormattingRangesV2(node.formatting, +1, index + counter) counter++ return '\\' + match }) } function parseText(node) { for (const parse of formatting) { parse(node) } return node } export function markdownV2Text(input_node) { const node = { ...input_node } parseText(node) escapeMarkdownV2(node) let text = node.value function insert(i, symbol) { fixFormattingRanges(node.formatting, +symbol.length, i) text = text.substring(0, i) + symbol + text.substring(i) } iterateFormatting(node.formatting, (f, type) => { insert(f.begin, symbolOfFormattingType(type)) insert(f.end, symbolOfFormattingType(type)) }) text = text.replace(/\\!\\\[(?:\S|\S.*?\S)\\]\\\((?:\S|\S.*?\S)\\\)/g, (match) => { const match1 = match.matchAll(/\\\[(\S|\S.*?\S)\\]\\\((\S|\S.*?\S)\\\)/g).next().value return `![${match1[1]}](${match1[2]})` }) text = text.replace(/\\\[(?:\S|\S.*?\S)\\]\\\((?:\S|\S.*?\S)\\\)/g, (match) => { const match1 = match.matchAll(/\\\[(\S|\S.*?\S)\\]\\\((\S|\S.*?\S)\\\)/g).next().value return `[${match1[1]}](${match1[2]})` }) return text } </file> <file path="./utils/markdownV2.js"> import { markdownV2Text } from "./markdownV2Text" function parser(node, regex, type, parse = (text) => {return text}) { if (node.type !== 'text') { return [node] } const text = node.value const matches = text.matchAll(regex) const nodes = [] let lastIndex = 0 for (const match of matches) { const value = parse(match[1]) const startIndex = match.index if (startIndex > lastIndex) { nodes.push({ type: 'text', value: text.substring(lastIndex, startIndex) }) } nodes.push({ type, value }) lastIndex = startIndex + match[0].length } if (lastIndex < text.length) { nodes.push({ type: 'text', value: text.substring(lastIndex) }) } return nodes } const parsers = [ (node) => parser(node, /^```(.*?\n)```$/gms, 'code'), (node) => parser(node, /^`(.*?\n)`$/gms, 'code'), (node) => parser(node, /(((^\|.*)+\n?)+)/gm, 'table', (text) => { const result = text.trim().split('\n').map(row => { const cells = row.split('|').slice(1) if (cells[cells.length - 1].trim() === '') { cells.pop() } return cells.map(cell => cell.trim()) }) result.splice(1, 1) return result }), (node) => parser(node, /^>(.*)/gm, 'quote', (text) => [{ type: 'text', value: text, }]), (node) => parser(node, /^(#{1,6} .*)/gm, 'header', (text) => [{ type: 'text', value: text.trim() .replace(/\*\*(\S.*?\S)\*\*/g, (match, captured) => captured) .replace(/\*\*(\S.*)$/g, (match, captured) => captured), formatting: { bold: [{ begin: 0, end: text.length }] }, }]), ] function escape(text) { return text.replace(/[\\\[\]\-(){}+_*~`>#=|!.]/g, (match) => '\\' + match) } export function markdownV2(nodes) { let output = '' for (const node of nodes) { switch (node.type) { case 'text': output += markdownV2Text(node) + '\n' break case 'code': const codeBlock = '```' + escape(node.value) + '```' let remainingCode = codeBlock while (remainingCode.length > 0) { const remainingSpace = MAX_OUTPUT_SIZE - output.length const chunkLength = Math.min(remainingCode.length, remainingSpace) output += remainingCode.substring(0, chunkLength) remainingCode = remainingCode.substring(chunkLength) if (remainingCode.length > 0) { overflow() } } break case 'table': output += '```markdown\n' const rows = node.value const maxLengths = rows[0].map((header, i) => Math.max(header.length, ...rows.slice(1).map(row => row[i] ? row[i].length : 0)) ) for (let i = 0; i < rows.length; i++) { const row = rows[i] output += escape('| ' + row.map((cell, j) => cell.padEnd(maxLengths[j])).join(' | ') + ' |\n') if (i === 0) { output += escape('| ' + maxLengths.map(length => '-'.repeat(length)).join(' | ') + ' |\n') } } output += '```\n' break case 'quote': output += '>' + markdownV2(node.value) break case 'header': output += markdownV2(node.value) break } } if (output[output.length - 1] === '\n') { output = output.slice(0, -1) } return output } export function parse(text) { let in_nodes = [{type: 'text', value: text}] for (const fn of parsers) { const out_nodes = [] for (let i = 0; i < in_nodes.length; i++) { out_nodes.push(...fn(in_nodes[i])) } in_nodes = out_nodes } return in_nodes } </file> <file path="./utils/splitMessage.js"> import { parse, markdownV2 } from './markdownV2' export const splitMessage = (text) => { const maxLength = 4096 const formattedText = markdownV2(parse(text)) const messages = [] let remainingText = formattedText while (remainingText.length > 0) { if (remainingText.length <= maxLength) { messages.push(remainingText) break } let splitIndex = remainingText.lastIndexOf('\n', maxLength) if (splitIndex === -1) { splitIndex = maxLength } const messagePart = remainingText.slice(0, splitIndex).trim() messages.push(messagePart) remainingText = remainingText.slice(splitIndex).trim() } return messages } </file> <file path="./utils/session.js"> import { redisClient } from './redisClient' import { bot } from '../bot/instance' const SESSION_TTL = 60 * 60 * 24 export const getSessionKey = (sessionId) => `session:${sessionId}` export const getUserSessionKey = (userId) => `userSession:${userId}` export const getSession = async (sessionId) => { const data = await redisClient.get(getSessionKey(sessionId)) return data ? JSON.parse(data) : null } export const setSession = async (sessionId, session) => { await redisClient.setEx(getSessionKey(sessionId), SESSION_TTL, JSON.stringify(session)) } export const getUserSession = async (userId) => { return await redisClient.get(getUserSessionKey(userId)) } export const setUserSession = (userId, sessionId) => { return redisClient.setEx(getUserSessionKey(userId), SESSION_TTL, sessionId) } export const createSession = async (sessionId) => { const session = { commands: [], results: [], promptNumber: 2, userId: null, chatId: null, processing: false, } await setSession(sessionId, session) return session } export const parseSessionId = (text) => { const parts = text.trim().split(' ') return parts.length > 1 ? parts[1] : null } export const getOrCreateSession = async (sessionId) => { return (await getSession(sessionId)) || (await createSession(sessionId)) } export const withUserSession = async (chatId, userId, update) => { const sessionId = await getUserSession(userId) if (!sessionId) { await bot.sendMessage(chatId, 'No active session. Use /start <session_id> to start.') return null } let session = await getSession(sessionId) if (!session) { await bot.sendMessage(chatId, 'Session not found.') return null } const result = await update(session) await setSession(sessionId, session) return result } export const withExistingOrNewSession = async (sessionId, update) => { let session = await getOrCreateSession(sessionId) await update(session) await setSession(sessionId, session) } export const withExistingSession = async (sessionId, update) => { let session = await getSession(sessionId) if (!session) return false await update(session) await setSession(sessionId, session) return true } export const startSession = async (sessionId, userId, chatId) => { const session = await getOrCreateSession(sessionId) session.userId = userId session.chatId = chatId await setSession(sessionId, session) await setUserSession(userId, sessionId) } </file> <file path="./FORMATTING.md"> Forget all ";" Forget all ".js" extensions in imports Forget 2-4 spaces, use tabs </file> <file path="./INSTRUCTIONS.md"> Rewrite each file of codebase Simplify code without making worse </file>

Created by wprhvso and OPENAI01
OpenAI 01 Preview

Java Android Tokenizer Code

Rewrite all this code in Java for Android: export class PreTrainedTokenizer { constructor(tokenizerJSON, tokenizerConfig) { this._tokenizer_config = tokenizerConfig; this.normalizer = Normalizer.fromConfig(tokenizerJSON.normalizer); this.pre_tokenizer = PreTokenizer.fromConfig(tokenizerJSON.pre_tokenizer); this.model = TokenizerModel.fromConfig(tokenizerJSON.model, tokenizerConfig); this.post_processor = PostProcessor.fromConfig(tokenizerJSON.post_processor); this.special_tokens = []; this.all_special_ids = []; this.added_tokens = []; for (const addedToken of tokenizerJSON.added_tokens) { const token = new AddedToken(addedToken); this.added_tokens.push(token); this.model.tokens_to_ids.set(token.content, token.id); this.model.vocab[token.id] = token.content; if (token.special) { this.special_tokens.push(token.content); this.all_special_ids.push(token.id); } } this.additional_special_tokens = tokenizerConfig.additional_special_tokens ?? []; this.special_tokens.push(...this.additional_special_tokens); this.special_tokens = [...new Set(this.special_tokens)]; this.added_tokens_regex = this.added_tokens.length > 0 ? new RegExp( this.added_tokens.map(x => `${x.lstrip ? '\\s*' : ''}(${escapeRegExp(x.content)})${x.rstrip ? '\\s*' : ''}`).join('|') ) : null; this.mask_token = this.getToken('mask_token'); this.mask_token_id = this.model.tokens_to_ids.get(this.mask_token); this.pad_token = this.getToken('pad_token', 'eos_token'); this.pad_token_id = this.model.tokens_to_ids.get(this.pad_token); this.sep_token = this.getToken('sep_token'); this.sep_token_id = this.model.tokens_to_ids.get(this.sep_token); this.unk_token = this.getToken('unk_token'); this.unk_token_id = this.model.tokens_to_ids.get(this.unk_token); this.model_max_length = tokenizerConfig.model_max_length; this.remove_space = tokenizerConfig.remove_space; this.clean_up_tokenization_spaces = tokenizerConfig.clean_up_tokenization_spaces ?? true; this.do_lowercase_and_remove_accent = tokenizerConfig.do_lowercase_and_remove_accent ?? false; this.padding_side = 'right'; this.legacy = false; } getToken(...keys) { for (const key of keys) { const item = this._tokenizer_config[key]; if (!item) continue; if (typeof item === 'object') { if (item.__type === 'AddedToken') { return item.content; } else { throw Error(`Unknown token: ${item}`); } } else { return item; } } return null; } _encode_text(text) { if (text === null) return null; const sections = this.added_tokens_regex ? text.split(this.added_tokens_regex).filter(x => x) : [text]; const tokens = sections.map((x, section_index) => { const addedToken = this.added_tokens.find(t => t.content === x); if (addedToken !== undefined) { return x } else { if (this.remove_space === true) { x = x.trim().split(/\s+/).join(' '); } if (this.do_lowercase_and_remove_accent) { x = lowercase_and_remove_accent(x); } if (this.normalizer !== null) { x = this.normalizer.normalize(x); } if (x.length === 0) { return []; } const sectionTokens = (this.pre_tokenizer !== null) ? this.pre_tokenizer.pre_tokenize(x, { section_index, }) : [x]; const tokens = this.model._call(sectionTokens); return tokens; } }).flat(); return tokens; } _encode_plus(text, { add_special_tokens = true, } = {}) { const tokens = this._encode_text(text); const combinedTokens = this.post_processor ? this.post_processor.post_process(tokens, null, { add_special_tokens }) : { tokens }; console.log(combinedTokens.tokens); const input_ids = this.model.convert_tokens_to_ids(combinedTokens.tokens); return { input_ids, attention_mask: new Array(input_ids.length).fill(1), }; } encode(text, { add_special_tokens = true, } = {}) { const { input_ids } = this._encode_plus(text, { add_special_tokens, }); return input_ids; } } /** * Helper function to remove accents from a string. * @param {string} text The text to remove accents from. * @returns {string} The text with accents removed. */ function remove_accents(text) { return text.replace(/[\u0300-\u036f]/g, ''); } /** * Helper function to lowercase a string and remove accents. * @param {string} text The text to lowercase and remove accents from. * @returns {string} The lowercased text with accents removed. */ function lowercase_and_remove_accent(text) { return remove_accents(text.toLowerCase()); } class Normalizer { constructor(config) { this.config = config; } static fromConfig(config) { if (config === null) return null; switch (config.type) { case 'Precompiled': return new Precompiled(config); default: throw new Error(`Unknown Normalizer type: ${config.type}`); } } normalize(text) { throw Error("normalize should be implemented in subclass.") } } class Precompiled extends Normalizer { constructor(config) { super(config); //this.charsmap = config.precompiled_charsmap; } normalize(text) { text = text.replace(/[\u0001-\u0008\u000B\u000E-\u001F\u007F\u008F\u009F]/gm, ''); // Remove control characters text = text.replace(/[\u0009\u000A\u000C\u000D\u1680\u200B\u200C\u200E\u200F\u2028\u2029\u2581\uFEFF\uFFFD]/gm, '\u0020'); // Replace certain characters with a space if (text.includes('\uFF5E')) { const parts = text.split('\uFF5E'); text = parts.map(part => part.normalize('NFKC')).join('\uFF5E'); } else { text = text.normalize('NFKC'); } return text; } } class PreTokenizer { static fromConfig(config) { if (config === null) return null; switch (config.type) { case 'Sequence': return new PreTokenizerSequence(config); case 'WhitespaceSplit': return new WhitespaceSplit(config); case 'Metaspace': return new MetaspacePreTokenizer(config); default: throw new Error(`Unknown PreTokenizer type: ${config.type}`); } } pre_tokenize_text(text, options) { throw Error("pre_tokenize_text should be implemented in subclass.") } pre_tokenize(text, options) { return (Array.isArray(text) ? text.map(x => this.pre_tokenize_text(x, options)) : this.pre_tokenize_text(text, options) ).flat(); } } class PreTokenizerSequence extends PreTokenizer { constructor(config) { super(); this.tokenizers = config.pretokenizers.map(x => PreTokenizer.fromConfig(x)); } pre_tokenize_text(text, options) { return this.tokenizers.reduce((preTokenizedText, tokenizer) => { return tokenizer.pre_tokenize(preTokenizedText, options); }, [text]); } } class WhitespaceSplit extends PreTokenizer { constructor(config) { super(); } pre_tokenize_text(text, options) { return whitespace_split(text); } } class MetaspacePreTokenizer extends PreTokenizer { constructor(config) { super(); this.addPrefixSpace = config.add_prefix_space; this.replacement = config.replacement; this.strRep = config.str_rep || this.replacement; this.prepend_scheme = config.prepend_scheme ?? 'always'; } pre_tokenize_text(text, { section_index = undefined, } = {}) { let normalized = text.replaceAll(' ', this.strRep); if ( (this.addPrefixSpace && !normalized.startsWith(this.replacement)) && ( this.prepend_scheme === 'always' || (this.prepend_scheme === 'first' && section_index === 0) ) ) { normalized = this.strRep + normalized; } return [normalized]; } } class TokenizerModel { constructor(config) { this.config = config; this.vocab = []; this.tokens_to_ids = new Map(); this.unk_token_id = undefined; this.unk_token = undefined; this.end_of_word_suffix = undefined; this.fuse_unk = this.config.fuse_unk ?? false; } static fromConfig(config, ...args) { switch (config.type) { case 'Unigram': return new Unigram(config, ...args); default: throw new Error(`Unknown TokenizerModel type: ${config.type}`); } } _call(tokens) { let ids = this.encode(tokens); if (this.fuse_unk) { ids = fuse(ids, this.unk_token_id, this.tokens_to_ids); } return ids; } encode(tokens) { throw Error("encode should be implemented in subclass.") } convert_tokens_to_ids(tokens) { return tokens.map(t => this.tokens_to_ids.get(t) ?? this.unk_token_id); } convert_ids_to_tokens(ids) { return ids.map(i => this.vocab[i] ?? this.unk_token); } } class Unigram extends TokenizerModel { constructor(config, moreConfig) { super(config); const vocabSize = config.vocab.length; this.vocab = new Array(vocabSize); this.scores = new Array(vocabSize); for (let i = 0; i < vocabSize; ++i) { const piece = config.vocab[i]; this.vocab[i] = piece[0]; this.scores[i] = piece[1]; } this.unk_token_id = config.unk_id; this.unk_token = this.vocab[config.unk_id]; this.tokens_to_ids = new Map(this.vocab.map((x, i) => [x, i])); this.bosToken = ' '; this.bosTokenId = this.tokens_to_ids.get(this.bosToken); this.eosToken = moreConfig.eos_token; this.eosTokenId = this.tokens_to_ids.get(this.eosToken); this.unkToken = this.vocab[this.unk_token_id]; this.minScore = min(this.scores)[0]; this.unkScore = this.minScore - 10.0; this.scores[this.unk_token_id] = this.unkScore; this.trie = new CharTrie(); this.trie.extend(this.vocab); this.fuse_unk = true; } populateNodes(lattice) { const sentence = lattice.sentence; const len = sentence.length; let beginPos = 0; while (beginPos < len) { const mblen = 1; let hasSingleNode = false; const tokens = []; for (let token of this.trie.commonPrefixSearch(sentence.slice(beginPos))) { tokens.push(token); const tokenId = this.tokens_to_ids.get(token); const tokenScore = this.scores[tokenId]; const n = token.length; lattice.insert(beginPos, n, tokenScore, tokenId); if (!hasSingleNode && n === mblen) { hasSingleNode = true; } } if (!hasSingleNode) { lattice.insert(beginPos, mblen, this.unkScore, this.unk_token_id); } beginPos += mblen; } } tokenize(normalized) { const lattice = new TokenLattice(normalized, this.bosTokenId, this.eosTokenId); this.populateNodes(lattice); return lattice.tokens(); } encode(tokens) { const toReturn = []; for (const token of tokens) { const tokenized = this.tokenize(token); toReturn.push(...tokenized); } return toReturn; } } function min(arr) { if (arr.length === 0) throw Error('Array must not be empty'); let min = arr[0]; let indexOfMin = 0; for (let i = 1; i < arr.length; ++i) { if (arr[i] < min) { min = arr[i]; indexOfMin = i; } } return [min, indexOfMin]; } class CharTrie { constructor() { this.root = CharTrieNode.default(); } extend(texts) { if (texts.length === 0) return; for (let text of texts) { let node = this.root; for (let ch of text) { let child = node.children.get(ch); if (child === undefined) { child = CharTrieNode.default(); node.children.set(ch, child); } node = child; } node.isLeaf = true; } } *commonPrefixSearch(text) { let node = this.root; let prefix = ""; for (let i = 0; i < text.length && node !== undefined; ++i) { const ch = text[i]; prefix += ch; node = node.children.get(ch); if (node !== undefined && node.isLeaf) { yield prefix; } } } } class CharTrieNode { constructor(isLeaf, children) { this.isLeaf = isLeaf; this.children = children; } static default() { return new CharTrieNode(false, new Map()); } } class PostProcessor { constructor(config) { this.config = config; } static fromConfig(config) { if (config === null) return null; switch (config.type) { case 'TemplateProcessing': return new TemplateProcessing(config); default: throw new Error(`Unknown PostProcessor type: ${config.type}`); } } post_process(tokens, ...args) { throw Error("post_process should be implemented in subclass.") } } class TemplateProcessing extends PostProcessor { constructor(config) { super(config); this.single = config.single; this.pair = config.pair; } post_process(tokens, tokens_pair = null, { add_special_tokens = true, } = {}) { const type = tokens_pair === null ? this.single : this.pair //Here I decided to display tokens and type variables in the console to make it easier to understand their structure console.log(1, tokens); //1 ["▁I", "▁like", "▁cat", "s"] console.log(2, type); //2 [{"SpecialToken": {"id": "<s>", "type_id": 0}}, {"Sequence": {"id": "A", "type_id": 0}}, {"SpecialToken": {"id": "</s>", "type_id": 0}}] let processedTokens = []; let types = []; for (const item of type) { if ('SpecialToken' in item) { if (add_special_tokens) { processedTokens.push(item.SpecialToken.id); types.push(item.SpecialToken.type_id); } } else if ('Sequence' in item) { if (item.Sequence.id === 'A') { processedTokens = mergeArrays(processedTokens, tokens); types = mergeArrays(types, new Array(tokens.length).fill(item.Sequence.type_id)); } else if (item.Sequence.id === 'B') { processedTokens = mergeArrays(processedTokens, tokens_pair); types = mergeArrays(types, new Array(tokens_pair.length).fill(item.Sequence.type_id)); } } } //Here I decided to display tokens and type variables in the console to make it easier to understand their structure console.log(3, processedTokens) //3 ["<s>", "▁I", "▁like", "▁cat", "s", "</s>"] console.log(4, types)//4 [0, 0, 0, 0, 0, 0] return { tokens: processedTokens, token_type_ids: types }; } } class AddedToken { constructor(config) { this.content = config.content; this.id = config.id; this.single_word = config.single_word ?? false; this.lstrip = config.lstrip ?? false; this.rstrip = config.rstrip ?? false; this.special = config.special ?? false; this.normalized = config.normalized ?? null; } } function escapeRegExp(string) { return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); } function whitespace_split(text) { return text.match(/\S+/g) || []; } class TokenLattice { constructor(sentence, bosTokenId, eosTokenId) { this.sentence = sentence; this.len = sentence.length; this.bosTokenId = bosTokenId; this.eosTokenId = eosTokenId; this.nodes = []; this.beginNodes = Array.from({ length: this.len + 1 }, () => []); this.endNodes = Array.from({ length: this.len + 1 }, () => []); const bos = new TokenLatticeNode(this.bosTokenId, 0, 0, 0, 0.0); const eos = new TokenLatticeNode(this.eosTokenId, 1, this.len, 0, 0.0); this.nodes.push(bos.clone()); this.nodes.push(eos.clone()); this.beginNodes[this.len].push(eos); this.endNodes[0].push(bos); } insert(pos, length, score, tokenId) { const nodeId = this.nodes.length; const node = new TokenLatticeNode(tokenId, nodeId, pos, length, score); this.beginNodes[pos].push(node); this.endNodes[pos + length].push(node); this.nodes.push(node); } viterbi() { const len = this.len; let pos = 0; while (pos <= len) { if (this.beginNodes[pos].length == 0) { return []; } for (let rnode of this.beginNodes[pos]) { rnode.prev = null; let bestScore = 0.0; let bestNode = null; for (let lnode of this.endNodes[pos]) { const score = lnode.backtraceScore + rnode.score; if (bestNode === null || score > bestScore) { bestNode = lnode.clone(); bestScore = score; } } if (bestNode !== null) { rnode.prev = bestNode; rnode.backtraceScore = bestScore; } else { return []; } } ++pos; } const results = []; const root = this.beginNodes[len][0]; const prev = root.prev; if (prev === null) { return []; } let node = prev.clone(); while (node.prev !== null) { results.push(node.clone()); const n = node.clone(); node = n.prev.clone(); } results.reverse(); return results; } piece(node) { return this.sentence.slice(node.pos, node.pos + node.length); } tokens() { const nodes = this.viterbi(); return nodes.map(x => this.piece(x)); } tokenIds() { const nodes = this.viterbi(); return nodes.map(x => x.tokenId); } } class TokenLatticeNode { constructor(tokenId, nodeId, pos, length, score) { this.tokenId = tokenId; this.nodeId = nodeId; this.pos = pos; this.length = length; this.score = score; this.prev = null; this.backtraceScore = 0.0; } clone() { const n = new TokenLatticeNode(this.tokenId, this.nodeId, this.pos, this.length, this.score); n.prev = this.prev; n.backtraceScore = this.backtraceScore; return n; } } function fuse(arr, value, mapping) { const fused = []; let i = 0; while (i < arr.length) { fused.push(arr[i]) if ((mapping.get(arr[i]) ?? value) !== value) { ++i; continue; } while (i < arr.length && (mapping.get(arr[i]) ?? value) === value) { ++i; } } return fused; } function mergeArrays(...arrs) { return Array.prototype.concat.apply([], arrs); } I want to use this code you rewrote in this way: package com.transformers; import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.ReactContextBaseJavaModule; import com.facebook.react.bridge.ReactMethod; import com.facebook.react.bridge.Promise; import com.facebook.react.bridge.WritableArray; import com.facebook.react.bridge.Arguments; import com.transformers.tokenizer.PreTrainedTokenizer; import android.os.Handler; import android.os.Looper; import android.util.Log; import java.util.*; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import org.json.JSONObject; import org.json.JSONException; import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.io.FileNotFoundException; public class TokenizerModule extends ReactContextBaseJavaModule { private final ReactApplicationContext reactContext; private final ExecutorService executorService; private static final String TAG = "TokenizerModule"; private PreTrainedTokenizer tokenizer; public TokenizerModule(ReactApplicationContext reactContext) { super(reactContext); this.reactContext = reactContext; this.executorService = Executors.newCachedThreadPool(); } @Override public String getName() { return TAG; } @ReactMethod public void initializeTokenizer(String tokenizerJSONPath, String tokenizerConfigPath, Promise promise) { executorService.execute(() -> { try { JSONObject tokenizerJSON = readJSONFromFile(tokenizerJSONPath); JSONObject tokenizerConfig = readJSONFromFile(tokenizerConfigPath); tokenizer = new PreTrainedTokenizer(tokenizerJSON, tokenizerConfig); new Handler(Looper.getMainLooper()).post(() -> promise.resolve("Tokenizer initialized successfully") ); } catch (FileNotFoundException e) { new Handler(Looper.getMainLooper()).post(() -> promise.reject("FILE_NOT_FOUND", "File not found: " + e.getMessage()) ); } catch (Exception e) { new Handler(Looper.getMainLooper()).post(() -> promise.reject("INITIALIZATION_ERROR", e.getMessage()) ); } }); } @ReactMethod public void encode(String text, Promise promise) { executorService.execute(() -> { try { if (tokenizer == null) { throw new IllegalStateException("Tokenizer not initialized. Call initializeTokenizer first."); } List<Integer> encodedIds = tokenizer.encode(text); WritableArray result = Arguments.createArray(); for (Integer id : encodedIds) { result.pushInt(id); } new Handler(Looper.getMainLooper()).post(() -> promise.resolve(result) ); } catch (IllegalStateException e) { new Handler(Looper.getMainLooper()).post(() -> promise.reject("TOKENIZER_NOT_INITIALIZED", e.getMessage()) ); } catch (Exception e) { new Handler(Looper.getMainLooper()).post(() -> promise.reject("ENCODING_ERROR", e.getMessage()) ); } }); } @ReactMethod public void cleanup() { executorService.shutdown(); } private JSONObject readJSONFromFile(String filePath) throws IOException, JSONException { StringBuilder content = new StringBuilder(); try (BufferedReader br = new BufferedReader(new FileReader(filePath))) { String line; while ((line = br.readLine()) != null) { content.append(line); } } return new JSONObject(content.toString()); } }

Created by Без Границ and OPENAI01
OpenAI 01 Preview

Node.js Project Setup

<file path="./package.json"> { "name": "your-project", "version": "1.0.0", "type": "module", "main": "index.js", "scripts": { "start": "node index.js" }, "dependencies": { "bcrypt": "^5.1.1", "dotenv": "^16.4.5", "express": "^4.21.0", "html-entities": "^2.5.2", "node-telegram-bot-api": "^0.66.0", "redis": "^4.7.0", "validator": "^13.12.0" } } </file> <file path="./config/config.js"> export const port = process.env.PORT || 8000; export const botToken = process.env.BOT_TOKEN; export const botUsername = process.env.BOT_USERNAME; export const redisUrl = process.env.REDIS_URL || 'redis://localhost:6379'; if (!botToken || !botUsername) { throw new Error('BOT_TOKEN and BOT_USERNAME must be set in environment variables.'); } </file> <file path="./middleware/validateSessionId.js"> export const validateSessionId = (req, res, next) => { const sessionId = (req.params.sessionId || '').trim(); if (!/^[a-zA-Z0-9_-]+$/.test(sessionId)) { return res.status(400).json({ error: 'Invalid Session ID.' }); } req.sessionId = sessionId; next(); }; </file> <file path="./index.js"> import express from 'express'; import commandsRoutes from './routes/commands.js'; import updateRoutes from './routes/update.js'; import sessionsRoutes from './routes/sessions.js'; import { redisClient } from './utils/redisClient.js'; import { port } from './config/config.js'; const app = express(); app.use(express.json()); app.use('/commands', commandsRoutes); app.use('/update', updateRoutes); app.use('/sessions', sessionsRoutes); const server = app.listen(port, () => { console.log(`Server is listening on port ${port}`); }); process.on('SIGINT', async () => { console.log('Shutting down server...'); try { await redisClient.quit(); server.close(() => { console.log('Server closed.'); process.exit(0); }); } catch (err) { console.error('Error during shutdown:', err); process.exit(1); } }); </file> <file path="./bot/handlers.js"> import { bot } from './instance.js' import { parseSessionId, withUserSession, startSession, } from '../utils/session.js' const start = async (chatId, userId, text) => { const sessionId = parseSessionId(text) if (!sessionId) return bot.sendMessage(chatId, 'Please provide a session ID.') await startSession(sessionId, userId, chatId) return await bot.sendMessage(chatId, `Welcome to session ${sessionId}!`) }; const clear = (chatId, userId) => { return withUserSession(chatId, userId, (session) => { session.commands.push({ type: 'CLEAR' }) session.promptNumber = 2 return bot.sendMessage(chatId, 'Session cleared.') }) }; const request = (chatId, userId, text) => { return withUserSession(chatId, userId, (session) => { session.commands.push({ type: 'RUN', text, promptNumber: session.promptNumber }) session.promptNumber += 2 return bot.sendMessage(chatId, 'Processing your request...') }) }; export const handleMessage = async (msg) => { const chatId = msg.chat.id const userId = msg.from.id const text = msg.text?.trim() || '' try { if (text.startsWith('/start')) await start(chatId, userId, text) else if (text.startsWith('/clear')) await clear(chatId, userId) else await request(chatId, userId, text); } catch (error) { console.error('Error handling message:', error) bot.sendMessage(chatId, 'An error occurred.') } } </file> <file path="./bot/instance.js"> import TelegramBot from 'node-telegram-bot-api'; import { botToken } from '../config/config.js'; import { handleMessage } from './handlers.js'; export const bot = new TelegramBot(botToken, { polling: true }); bot.on('message', handleMessage); </file> <file path="./routes/sessions.js"> import express from 'express'; import { redisClient } from '../utils/redisClient.js'; const router = express.Router(); router.get('/', async (req, res) => { try { const keys = await redisClient.keys('session:*'); const sessionIds = keys.map((key) => key.replace('session:', '')); res.json({ sessions: sessionIds }); } catch (error) { console.error('Error fetching sessions:', error); res.status(500).json({ error: 'Internal Server Error' }); } }); export default router; </file> <file path="./routes/commands.js"> import express from 'express'; import { validateSessionId } from '../middleware/validateSessionId.js'; import { withExistingOrNewSession } from '../utils/session.js'; const router = express.Router(); router.get('/:sessionId', validateSessionId, async (req, res) => { const { sessionId } = req; try { await withExistingOrNewSession(sessionId, (session) => { const commands = [...session.commands]; session.commands = []; res.json({ commands }); }) } catch (error) { console.error(`Error fetching commands for session ${sessionId}:`, error); res.status(500).json({ error: 'Internal Server Error' }); } }); router.post('/:sessionId', validateSessionId, async (req, res) => { const { sessionId } = req; const command = req.body; try { await withExistingOrNewSession(sessionId, (session) => { if (!command || !command.type) { return res.status(400).json({ error: 'Invalid command.' }); } if (command.type === 'CLEAR') { session.promptNumber = 2; } else { command.promptNumber = session.promptNumber; session.promptNumber += 2; } session.commands.push(command); res.json({ message: 'Command added.' }); }) } catch (error) { console.error(`Error adding command to session ${sessionId}:`, error); res.status(500).json({ error: 'Internal Server Error' }); } }); export default router; </file> <file path="./routes/password.js"> import express from 'express' import validator from 'validator' import bcrypt from 'bcrypt' import { validateSessionId } from '../middleware/validateSessionId' import { withExistingOrNewSession } from '../utils/session' import { botUsername } from '../config/config' const router = express.Router() router.post('/:sessionId', validateSessionId, async (req, res) => { const { sessionId } = req const { password } = req.body try { if (!password || validator.isEmpty(password)) { return res.status(400).json({ error: 'Password is required.' }) } const sanitizedPassword = validator.escape(password) await withExistingOrNewSession(sessionId, async (session) => { session.password = await bcrypt.hash(sanitizedPassword, 10) }) res.json({ link: `https://t.me/${botUsername}?start=${sessionId}-${sanitizedPassword}` }) } catch (error) { console.error(`Error setting password for session ${sessionId}:`, error) res.status(500).json({ error: 'Internal Server Error' }) } }); export default router </file> <file path="./routes/update.js"> import express from 'express'; import { validateSessionId } from '../middleware/validateSessionId.js'; import { getSession, setSession, createSession } from '../utils/session.js'; import { bot } from '../bot/instance.js'; const router = express.Router(); router.post('/:sessionId', validateSessionId, async (req, res) => { const { sessionId } = req; const resultText = req.body.text; try { if (!resultText) { return res.status(400).json({ error: 'Result text is required.' }); } let session = await getSession(sessionId) || await createSession(sessionId); session.results.push(resultText); await setSession(sessionId, session); if (session.chatId) { await bot.sendMessage(session.chatId, resultText); } res.json({ message: 'Result received.' }); } catch (error) { console.error(`Error updating session ${sessionId}:`, error); res.status(500).json({ error: 'Internal Server Error' }); } }); export default router; </file> <file path="./utils/redisClient.js"> import { createClient } from 'redis'; import { redisUrl } from '../config/config.js'; export const redisClient = createClient({ url: redisUrl }); redisClient.on('error', (err) => console.error('Redis error:', err)); redisClient.connect().then(() => { console.log('Connected to Redis.'); }).catch((error) => { console.error('Failed to connect to Redis:', error); process.exit(1); }); </file> <file path="./utils/markdownV2Text.js"> import { decode } from "html-entities"; function parseFormatting(node, type, symbol_left, symbol_right = symbol_left) { if (!node.formatting) node.formatting = {}; if (!node.formatting[type]) node.formatting[type] = []; const escaped_left = symbol_left.replace(/[.*+?^${}()|\[\]\\]/g, '\\$&'); const escaped_right = symbol_right.replace(/[.*+?^${}()|\[\]\\]/g, '\\$&'); for (const match of node.value.matchAll(new RegExp(`${escaped_left}\\S.*?\\S${escaped_right}`, 'g'))) { const left = match.index const right = match.index + match[0].length - symbol_right.length fixFormattingRanges(node.formatting, -1, left, symbol_left.length) fixFormattingRanges(node.formatting, -1, right, symbol_right.length) } let removedLength = 0; const handle = (match, captured, index) => { const begin = index - removedLength; const end = begin + captured.length; node.formatting[type].push({ begin, end }); removedLength += match.length - captured.length; return captured; } node.value = node.value.replace(new RegExp(`${escaped_left}(\\S.*?\\S)${escaped_right}`, 'g'), handle); removedLength = 0 node.value = node.value.replace(new RegExp(`${escaped_left}(\\S.*)$`), handle) } const formatting = [ (node) => node.value = decode(node.value), (node) => parseFormatting(node, 'monospace', '`'), (node) => parseFormatting(node, 'bold', '**'), (node) => parseFormatting(node, 'italic', '*'), (node) => parseFormatting(node, 'italic', '_'), (node) => parseFormatting(node, 'strikethrough', '~~'), (node) => parseFormatting(node, 'strikethrough', '~'), (node) => parseFormatting(node, 'underline', '<u>', '</u>'), (node) => parseFormatting(node, 'spoiler', '<spoiler>', '</spoiler>') ] function iterateFormatting(formatting, callback) { for (const type in formatting) { formatting[type].forEach(f => { callback(f, type) }) } } function fixFormattingRanges(formatting, diff, index, count = 1) { for (let i = index; i < index + count; i++) { iterateFormatting(formatting, (f) => { if (index < f.begin) f.begin += diff if (index <= f.end) f.end += diff }) } } function fixFormattingRangesV2(formatting, diff, index, count = 1) { for (let i = index; i < index + count; i++) { iterateFormatting(formatting, (f) => { if (index < f.begin) f.begin += diff if (index < f.end) f.end += diff }) } } function symbolOfFormattingType(type) { switch (type) { case 'bold': return '*' case 'italic': return '_' case 'monospace': return '`' case 'strikethrough': return '~' case 'underline': return '__' case 'spoiler': return '||' } } function escapeMarkdownV2(node) { let counter = 0 node.value = node.value.replace(/[\\\[\]\-(){}+_*~`>#=|!.]/g, (match, index) => { fixFormattingRangesV2(node.formatting, +1, index + counter) counter++ return '\\' + match; }); } function parseText(node) { for (const parse of formatting) { parse(node) } return node } export function markdownV2Text(input_node) { const node = { ...input_node } parseText(node) escapeMarkdownV2(node) let text = node.value function insert(i, symbol) { fixFormattingRanges(node.formatting, +symbol.length, i) text = text.substring(0, i) + symbol + text.substring(i); } iterateFormatting(node.formatting, (f, type) => { insert(f.begin, symbolOfFormattingType(type)) insert(f.end, symbolOfFormattingType(type)) }) text = text.replace(/\\!\\\[(?:\S|\S.*?\S)\\]\\\((?:\S|\S.*?\S)\\\)/g, (match) => { const match1 = match.matchAll(/\\\[(\S|\S.*?\S)\\]\\\((\S|\S.*?\S)\\\)/g).next().value return `![${match1[1]}](${match1[2]})` }) text = text.replace(/\\\[(?:\S|\S.*?\S)\\]\\\((?:\S|\S.*?\S)\\\)/g, (match) => { const match1 = match.matchAll(/\\\[(\S|\S.*?\S)\\]\\\((\S|\S.*?\S)\\\)/g).next().value return `[${match1[1]}](${match1[2]})` }) return text } </file> <file path="./utils/markdownV2.js"> import { markdownV2Text } from "./markdownV2Text"; function parser(node, regex, type, parse = (text) => {return text}) { if (node.type !== 'text') { return [node]; } const text = node.value; const matches = text.matchAll(regex); const nodes = []; let lastIndex = 0; for (const match of matches) { const value = parse(match[1]); const startIndex = match.index; if (startIndex > lastIndex) { nodes.push({ type: 'text', value: text.substring(lastIndex, startIndex) }); } nodes.push({ type, value }); lastIndex = startIndex + match[0].length; } if (lastIndex < text.length) { nodes.push({ type: 'text', value: text.substring(lastIndex) }); } return nodes; } const parsers = [ (node) => parser(node, /^```(.*?\n)```$/gms, 'code'), (node) => parser(node, /^`(.*?\n)`$/gms, 'code'), (node) => parser(node, /(((^\|.*)+\n?)+)/gm, 'table', (text) => { const result = text.trim().split('\n').map(row => { const cells = row.split('|').slice(1); if (cells[cells.length - 1].trim() === '') { cells.pop(); } return cells.map(cell => cell.trim()); }); result.splice(1, 1); return result; }), (node) => parser(node, /^>(.*)/gm, 'quote', (text) => [{ type: 'text', value: text, }]), (node) => parser(node, /^(#{1,6} .*)/gm, 'header', (text) => [{ type: 'text', value: text.trim() .replace(/\*\*(\S.*?\S)\*\*/g, (match, captured) => captured) .replace(/\*\*(\S.*)$/g, (match, captured) => captured), formatting: { bold: [{ begin: 0, end: text.length }] }, }]), ]; function escape(text) { return text.replace(/[\\\[\]\-(){}+_*~`>#=|!.]/g, (match) => '\\' + match) } export function markdownV2(nodes) { let output = ''; for (const node of nodes) { switch (node.type) { case 'text': output += markdownV2Text(node) + '\n' break; case 'code': const codeBlock = '```' + escape(node.value) + '```'; let remainingCode = codeBlock; while (remainingCode.length > 0) { const remainingSpace = MAX_OUTPUT_SIZE - output.length; const chunkLength = Math.min(remainingCode.length, remainingSpace); output += remainingCode.substring(0, chunkLength); remainingCode = remainingCode.substring(chunkLength); if (remainingCode.length > 0) { overflow(); } } break; case 'table': output += '```markdown\n' const rows = node.value; const maxLengths = rows[0].map((header, i) => Math.max(header.length, ...rows.slice(1).map(row => row[i] ? row[i].length : 0)) ); for (let i = 0; i < rows.length; i++) { const row = rows[i]; output += escape('| ' + row.map((cell, j) => cell.padEnd(maxLengths[j])).join(' | ') + ' |\n'); if (i === 0) { output += escape('| ' + maxLengths.map(length => '-'.repeat(length)).join(' | ') + ' |\n'); } } output += '```\n' break; case 'quote': output += '>' + markdownV2(node.value) break case 'header': output += markdownV2(node.value) break } } if (output[output.length - 1] === '\n') { output = output.slice(0, -1) } return output; } export function parse(text) { let in_nodes = [{type: 'text', value: text}] for (const fn of parsers) { const out_nodes = [] for (let i = 0; i < in_nodes.length; i++) { out_nodes.push(...fn(in_nodes[i])) } in_nodes = out_nodes } return in_nodes } </file> <file path="./utils/splitMessage.js"> import { parse, markdownV2 } from './markdownV2.js'; export const splitMessage = (text) => { const maxLength = 4096; // Telegram max message length const formattedText = markdownV2(parse(text)); const messages = []; let remainingText = formattedText; while (remainingText.length > 0) { if (remainingText.length <= maxLength) { messages.push(remainingText); break; } let splitIndex = remainingText.lastIndexOf('\n', maxLength); if (splitIndex === -1) { splitIndex = maxLength; } const messagePart = remainingText.slice(0, splitIndex).trim(); messages.push(messagePart); remainingText = remainingText.slice(splitIndex).trim(); } return messages; }; </file> <file path="./utils/session.js"> import { redisClient } from './redisClient.js'; import {bot} from "../bot/instance.js"; const SESSION_TTL = 60 * 60 * 24; // 1 day in seconds export const getSessionKey = (sessionId) => `session:${sessionId}`; export const getUserSessionKey = (userId) => `userSession:${userId}`; export const getSession = async (sessionId) => { const data = await redisClient.get(getSessionKey(sessionId)); return data ? JSON.parse(data) : null; }; export const setSession = async (sessionId, session) => { await redisClient.setEx(getSessionKey(sessionId), SESSION_TTL, JSON.stringify(session)); }; export const getUserSession = async (userId) => { return await redisClient.get(getUserSessionKey(userId)); }; export const setUserSession = (userId, sessionId) => { return redisClient.setEx(getUserSessionKey(userId), SESSION_TTL, sessionId); }; export const createSession = async (sessionId) => { const session = { commands: [], results: [], promptNumber: 2, userId: null, chatId: null, processing: false, }; await setSession(sessionId, session); return session; }; export const parseSessionId = (text) => { const parts = text.trim().split(' ') return parts.length > 1 ? parts[1] : null }; export const getOrCreateSession = async (sessionId) => { return (await getSession(sessionId)) || (await createSession(sessionId)) }; export const withUserSession = async (chatId, userId, update) => { const sessionId = await getUserSession(userId) if (!sessionId) { await bot.sendMessage(chatId, 'No active session. Use /start <session_id> to start.') return null } let session = await getSession(sessionId) if (!session) { await bot.sendMessage(chatId, 'Session not found.') return null } const result = await update(session) await setSession(sessionId, session) return result }; export const withExistingOrNewSession = async (sessionId, update) => { let session = await getOrCreateSession(sessionId); await update(session) await setSession(sessionId, session); } export const startSession = async (sessionId, userId, chatId) => { const session = await getOrCreateSession(sessionId) session.userId = userId session.chatId = chatId await setSession(sessionId, session) await setUserSession(userId, sessionId) } </file> <file path="./INSTRUCTIONS.md"> Rewrite each file of codebase Simplify code without making worse Forget all ";" Forget all ".js" extensions in imports Forget 2-4 spaces, use tabs </file>

Created by wprhvso and OPENAI01
OpenAI 01 Preview

Session Management Commands

import { bot } from './instance.js'; import { getSession, setSession, getUserSession, setUserSession, createSession } from '../utils/session.js'; const start = async (chatId, userId, text) => { const sessionId = text.split(' ')[1]; if (!sessionId) return bot.sendMessage(chatId, 'Please provide a session ID.'); let session = await getSession(sessionId) || await createSession(sessionId); session.userId = userId; session.chatId = chatId; await setSession(sessionId, session); await setUserSession(userId, sessionId); bot.sendMessage(chatId, `Welcome to session ${sessionId}!`); }; const clear = async (chatId, userId) => { const sessionId = await getUserSession(userId); if (!sessionId) return bot.sendMessage(chatId, 'No active session.'); const session = await getSession(sessionId); if (!session) return bot.sendMessage(chatId, 'Session not found.'); session.commands.push({ type: 'CLEAR' }); session.promptNumber = 2; await setSession(sessionId, session); bot.sendMessage(chatId, 'Session cleared.'); }; const request = async (chatId, userId, text) => { const sessionId = await getUserSession(userId); if (!sessionId) return bot.sendMessage(chatId, 'No active session. Use /start <session_id> to start.'); const session = await getSession(sessionId); if (!session) return bot.sendMessage(chatId, 'Session not found.'); session.commands.push({ type: 'RUN', text, promptNumber: session.promptNumber }); session.promptNumber += 2; await setSession(sessionId, session); bot.sendMessage(chatId, 'Processing your request...'); }; export const handleMessage = async (msg) => { const chatId = msg.chat.id, userId = msg.from.id, text = msg.text?.trim() || ''; try { if (text.startsWith('/start')) await start(chatId, userId, text); else if (text === '/clear') await clear(chatId, userId); else await request(chatId, userId, text); } catch (error) { console.error('Error handling message:', error); bot.sendMessage(chatId, 'An error occurred.'); } }; // make it so that there is less code duplication in functions by adding new functions

Created by wprhvso and OPENAI01
OpenAI 01 Preview

Session Management Commands

import { bot } from './instance.js'; import { getSession, setSession, getUserSession, setUserSession, createSession } from '../utils/session.js'; const start = async (chatId, userId, text) => { const sessionId = text.split(' ')[1]; if (sessionId) { let session = await getSession(sessionId) || await createSession(sessionId); session.userId = userId; session.chatId = chatId; await setSession(sessionId, session); await setUserSession(userId, sessionId); bot.sendMessage(chatId, `Welcome to session ${sessionId}!`); } else { bot.sendMessage(chatId, 'Please provide a session ID.'); } } const clear = async (chatId, userId) => { const sessionId = await getUserSession(userId); if (sessionId) { const session = await getSession(sessionId); if (session) { session.commands.push({ type: 'CLEAR' }); session.promptNumber = 2; await setSession(sessionId, session); bot.sendMessage(chatId, 'Session cleared.'); } else { bot.sendMessage(chatId, 'Session not found.'); } } else { bot.sendMessage(chatId, 'No active session.'); } } const request = async (chatId, userId, text) => { const sessionId = await getUserSession(userId); if (sessionId) { const session = await getSession(sessionId); if (session) { session.commands.push({ type: 'RUN', text: text, promptNumber: session.promptNumber, }); session.promptNumber += 2; await setSession(sessionId, session); bot.sendMessage(chatId, 'Processing your request...'); } else { bot.sendMessage(chatId, 'Session not found.'); } } else { bot.sendMessage(chatId, 'No active session. Use /start <session_id> to start.'); } } export const handleMessage = async (msg) => { const chatId = msg.chat.id; const userId = msg.from.id; const text = msg.text ? msg.text.trim() : ''; try { if (text.startsWith('/start')) { await start(chatId, userId, text) } else if (text === '/clear') { await clear(chatId, userId, text) } else { await request(chatId, userId, text) } } catch (error) { console.error('Error handling message:', error); bot.sendMessage(chatId, 'An error occurred.'); } }; make this code as short as possible but without removing functions

Created by wprhvso and OPENAI01
OpenAI 01 Preview

Node.js Project Structure

<file path="./package.json"> { "name": "your-project", "version": "1.0.0", "type": "module", "main": "index.js", "scripts": { "start": "node index.js" }, "dependencies": { "bcrypt": "^5.1.1", "dotenv": "^16.4.5", "express": "^4.21.0", "html-entities": "^2.5.2", "node-telegram-bot-api": "^0.66.0", "redis": "^4.7.0", "validator": "^13.12.0" } } </file> <file path="./config/config.js"> export const port = process.env.PORT || 8000; export const botToken = process.env.BOT_TOKEN; export const botUsername = process.env.BOT_USERNAME; export const redisUrl = process.env.REDIS_URL || 'redis://localhost:6379'; if (!botToken || !botUsername) { throw new Error('BOT_TOKEN and BOT_USERNAME must be set in environment variables.'); } </file> <file path="./middleware/validateSessionId.js"> export const validateSessionId = (req, res, next) => { const sessionId = req.params.sessionId?.trim(); const sessionIdPattern = /^[a-zA-Z0-9_-]+$/; if (!sessionId || !sessionIdPattern.test(sessionId)) { return res.status(400).json({ error: 'Invalid Session ID.' }); } req.sessionId = sessionId; next(); }; </file> <file path="./index.js"> import express from 'express'; import { createServer } from 'http'; import commandsRoutes from './routes/commands'; import updateRoutes from './routes/update'; import sessionsRoutes from './routes/sessions'; import passwordRoutes from './routes/password'; import { redisClient } from './utils/redisClient'; import { port } from './config/config'; const app = express(); const server = createServer(app); app.use(express.json()); app.use('/commands', commandsRoutes); app.use('/update', updateRoutes); app.use('/sessions', sessionsRoutes); app.use('/password', passwordRoutes); server.listen(port, () => { console.log(`Server is listening on port ${port}`); }); process.on('SIGINT', async () => { console.log('Shutting down server...'); try { await redisClient.quit(); server.close(() => { console.log('Server closed.'); process.exit(0); }); } catch (err) { console.error('Error during shutdown:', err); process.exit(1); } }); </file> <file path="./bot/handlers.js"> import bcrypt from 'bcrypt'; import { bot } from './instance'; import { getSession, setSession, getUserSession, setUserSession } from '../utils/session'; import { botUsername } from '../config/config'; import { processSession } from '../controllers/bot'; export const handleMessage = async (msg) => { const chatId = msg.chat.id; const userId = msg.from.id; let text = msg.text?.trim() || ''; try { if (text.startsWith('/start')) { await handleStartCommand(chatId, userId, text); } else if (text === '/clear') { await handleClearCommand(chatId, userId); } else { await handleUserMessage(chatId, userId, text); } } catch (error) { console.error('Error handling message:', error); bot.sendMessage(chatId, 'An error occurred while processing your message.'); } }; const handleStartCommand = async (chatId, userId, text) => { const params = text.split(' ').slice(1); if (params.length > 0) { const param = params.join(' '); const [sessionId, password] = param.split('-'); if (!sessionId || !password) { return bot.sendMessage(chatId, 'Invalid session link. Please check the format.'); } const session = await getSession(sessionId); if (session) { const passwordMatch = await bcrypt.compare(password, session.password); if (passwordMatch) { if (!session.userId || session.userId === userId) { session.userId = userId; session.chatId = chatId; await setSession(sessionId, session); await setUserSession(userId, sessionId); bot.sendMessage(chatId, `Welcome to session ${sessionId}! This session is now linked to your account.`); } else { bot.sendMessage(chatId, 'This session is already linked to another account.'); } } else { bot.sendMessage(chatId, 'Invalid session ID or password.'); } } else { bot.sendMessage(chatId, 'Session not found.'); } } else { bot.sendMessage( chatId, `Welcome! To access a session, use a link in the format https://t.me/${botUsername}?start=<session_id>-<password>` ); } }; const handleClearCommand = async (chatId, userId) => { const sessionId = await getUserSession(userId); if (!sessionId) { return bot.sendMessage(chatId, 'Active session not found.'); } const session = await getSession(sessionId); if (session) { session.commands.push({ type: 'CLEAR' }); session.promptNumber = 2; await setSession(sessionId, session); bot.sendMessage(chatId, 'Session cleared.'); } else { bot.sendMessage(chatId, 'Active session not found.'); } }; const handleUserMessage = async (chatId, userId, text) => { const sessionId = await getUserSession(userId); if (!sessionId) { return bot.sendMessage( chatId, 'Active session not found. Please use a deep link to access a session.' ); } const session = await getSession(sessionId); if (!session) { return bot.sendMessage( chatId, 'Session not found. Please ensure you have the correct session ID.' ); } let temperature = 0; const tempMatch = text.match(/^[tт](\d+(?:[.,]\d+)?)/i); if (tempMatch) { temperature = parseFloat(tempMatch[1].replace(',', '.')); text = text.replace(tempMatch[0], '').trim(); } session.commands.push({ type: 'RUN', text, promptNumber: session.promptNumber, temperature, }); session.promptNumber += 2; await setSession(sessionId, session); bot.sendMessage(chatId, 'Processing your request...'); if (!session.processing) { await processSession(sessionId); } }; </file> <file path="./bot/instance.js"> import TelegramBot from 'node-telegram-bot-api'; import { botToken } from '../config/config'; import { handleMessage } from './handlers'; export const bot = new TelegramBot(botToken, { polling: true }); bot.on('message', async (msg) => { await handleMessage(msg); }) </file> <file path="./controllers/bot.js"> import { getSession, setSession } from '../utils/session.js'; import { bot } from '../bot/instance.js'; import { splitMessage } from '../utils/splitMessage.js'; export const processSession = async (sessionId) => { const session = await getSession(sessionId); if (!session) return; session.processing = true; await setSession(sessionId, session); try { while (session.results.length > 0) { const resultText = session.results.shift(); await processMessages(session, resultText); } } catch (error) { console.error(`Error processing session ${sessionId}:`, error); } finally { session.processing = false; await setSession(sessionId, session); } }; export const processMessages = async (session, text) => { if (!session.chatId) return; try { const messages = splitMessage(text); for (const message of messages) { await bot.sendMessage(session.chatId, message, { parse_mode: 'MarkdownV2' }); } } catch (error) { console.error(`Error sending messages for session ${session.sessionId}:`, error); } }; </file> <file path="./routes/sessions.js"> import express from 'express'; import { redisClient } from '../utils/redisClient.js'; const router = express.Router(); router.get('/', async (req, res) => { try { const keys = await redisClient.keys('session:*'); const sessionIds = keys.map((key) => key.replace('session:', '')); res.json({ sessions: sessionIds }); } catch (error) { console.error('Error fetching sessions:', error); res.status(500).json({ error: 'Internal Server Error' }); } }); export default router; </file> <file path="./routes/commands.js"> import express from 'express'; import { validateSessionId } from '../middleware/validateSessionId.js'; import { getSession, setSession, createSession } from '../utils/session.js'; const router = express.Router(); router.get('/:sessionId', validateSessionId, async (req, res) => { const { sessionId } = req; try { let session = await getSession(sessionId); if (!session) { session = await createSession(sessionId); } const commands = [...session.commands]; session.commands = []; await setSession(sessionId, session); res.json({ commands }); } catch (error) { console.error(`Error fetching commands for session ${sessionId}:`, error); res.status(500).json({ error: 'Internal Server Error' }); } }); router.post('/:sessionId', validateSessionId, async (req, res) => { const { sessionId } = req; const command = req.body; try { let session = await getSession(sessionId); if (!session) { session = await createSession(sessionId); } if (!command || !command.type) { return res.status(400).json({ error: 'Invalid command.' }); } if (command.type === 'CLEAR') { session.promptNumber = 2; } else { command.promptNumber = session.promptNumber; session.promptNumber += 2; } session.commands.push(command); await setSession(sessionId, session); res.json({ message: 'Command added.' }); } catch (error) { console.error(`Error adding command to session ${sessionId}:`, error); res.status(500).json({ error: 'Internal Server Error' }); } }); export default router; </file> <file path="./routes/password.js"> import express from 'express'; import validator from 'validator'; import bcrypt from 'bcrypt'; import { validateSessionId } from '../middleware/validateSessionId.js'; import { createSession, getSession, setSession } from '../utils/session.js'; import { botUsername } from '../config/config.js'; const router = express.Router(); router.post('/:sessionId', validateSessionId, async (req, res) => { const { sessionId } = req; const { password } = req.body; try { if (!password || validator.isEmpty(password)) { return res.status(400).json({ error: 'Password is required.' }); } const sanitizedPassword = validator.escape(password); let session = await getSession(sessionId); if (!session) { session = await createSession(sessionId); } session.password = await bcrypt.hash(sanitizedPassword, 10); await setSession(sessionId, session); const link = `https://t.me/${botUsername}?start=${sessionId}-${sanitizedPassword}`; res.json({ link }); } catch (error) { console.error(`Error setting password for session ${sessionId}:`, error); res.status(500).json({ error: 'Internal Server Error' }); } }); export default router; </file> <file path="./routes/update.js"> import express from 'express'; import { validateSessionId } from '../middleware/validateSessionId.js'; import { getSession, setSession, createSession } from '../utils/session.js'; import { processMessages } from '../controllers/bot.js'; const router = express.Router(); router.post('/:sessionId', validateSessionId, async (req, res) => { const { sessionId } = req; const resultText = req.body.text; try { if (!resultText) { return res.status(400).json({ error: 'Result text is required.' }); } let session = await getSession(sessionId); if (!session) { session = await createSession(sessionId); } session.results.push(resultText); await setSession(sessionId, session); await processMessages(session, resultText); res.json({ message: 'Result received.' }); } catch (error) { console.error(`Error updating session ${sessionId}:`, error); res.status(500).json({ error: 'Internal Server Error' }); } }); export default router; </file> <file path="./utils/redisClient.js"> import { createClient } from 'redis'; import { redisUrl } from '../config/config.js'; export const redisClient = createClient({ url: redisUrl, }); redisClient.on('error', (err) => console.error('Redis error:', err)); (async () => { try { await redisClient.connect(); console.log('Connected to Redis.'); } catch (error) { console.error('Failed to connect to Redis:', error); process.exit(1); } })(); </file> <file path="./utils/markdownV2Text.js"> import { decode } from "html-entities"; function parseFormatting(node, type, symbol_left, symbol_right = symbol_left) { if (!node.formatting) node.formatting = {}; if (!node.formatting[type]) node.formatting[type] = []; const escaped_left = symbol_left.replace(/[.*+?^${}()|\[\]\\]/g, '\\$&'); const escaped_right = symbol_right.replace(/[.*+?^${}()|\[\]\\]/g, '\\$&'); for (const match of node.value.matchAll(new RegExp(`${escaped_left}\\S.*?\\S${escaped_right}`, 'g'))) { const left = match.index const right = match.index + match[0].length - symbol_right.length fixFormattingRanges(node.formatting, -1, left, symbol_left.length) fixFormattingRanges(node.formatting, -1, right, symbol_right.length) } let removedLength = 0; const handle = (match, captured, index) => { const begin = index - removedLength; const end = begin + captured.length; node.formatting[type].push({ begin, end }); removedLength += match.length - captured.length; return captured; } node.value = node.value.replace(new RegExp(`${escaped_left}(\\S.*?\\S)${escaped_right}`, 'g'), handle); removedLength = 0 node.value = node.value.replace(new RegExp(`${escaped_left}(\\S.*)$`), handle) } const formatting = [ (node) => node.value = decode(node.value), (node) => parseFormatting(node, 'monospace', '`'), (node) => parseFormatting(node, 'bold', '**'), (node) => parseFormatting(node, 'italic', '*'), (node) => parseFormatting(node, 'italic', '_'), (node) => parseFormatting(node, 'strikethrough', '~~'), (node) => parseFormatting(node, 'strikethrough', '~'), (node) => parseFormatting(node, 'underline', '<u>', '</u>'), (node) => parseFormatting(node, 'spoiler', '<spoiler>', '</spoiler>') ] function iterateFormatting(formatting, callback) { for (const type in formatting) { formatting[type].forEach(f => { callback(f, type) }) } } function fixFormattingRanges(formatting, diff, index, count = 1) { for (let i = index; i < index + count; i++) { iterateFormatting(formatting, (f) => { if (index < f.begin) f.begin += diff if (index <= f.end) f.end += diff }) } } function fixFormattingRangesV2(formatting, diff, index, count = 1) { for (let i = index; i < index + count; i++) { iterateFormatting(formatting, (f) => { if (index < f.begin) f.begin += diff if (index < f.end) f.end += diff }) } } function symbolOfFormattingType(type) { switch (type) { case 'bold': return '*' case 'italic': return '_' case 'monospace': return '`' case 'strikethrough': return '~' case 'underline': return '__' case 'spoiler': return '||' } } function escapeMarkdownV2(node) { let counter = 0 node.value = node.value.replace(/[\\\[\]\-(){}+_*~`>#=|!.]/g, (match, index) => { fixFormattingRangesV2(node.formatting, +1, index + counter) counter++ return '\\' + match; }); } function parseText(node) { for (const parse of formatting) { parse(node) } return node } export function markdownV2Text(input_node) { const node = { ...input_node } parseText(node) escapeMarkdownV2(node) let text = node.value function insert(i, symbol) { fixFormattingRanges(node.formatting, +symbol.length, i) text = text.substring(0, i) + symbol + text.substring(i); } iterateFormatting(node.formatting, (f, type) => { insert(f.begin, symbolOfFormattingType(type)) insert(f.end, symbolOfFormattingType(type)) }) text = text.replace(/\\!\\\[(?:\S|\S.*?\S)\\]\\\((?:\S|\S.*?\S)\\\)/g, (match) => { const match1 = match.matchAll(/\\\[(\S|\S.*?\S)\\]\\\((\S|\S.*?\S)\\\)/g).next().value return `![${match1[1]}](${match1[2]})` }) text = text.replace(/\\\[(?:\S|\S.*?\S)\\]\\\((?:\S|\S.*?\S)\\\)/g, (match) => { const match1 = match.matchAll(/\\\[(\S|\S.*?\S)\\]\\\((\S|\S.*?\S)\\\)/g).next().value return `[${match1[1]}](${match1[2]})` }) return text } </file> <file path="./utils/markdownV2.js"> import { markdownV2Text } from "./markdownV2Text"; function parser(node, regex, type, parse = (text) => {return text}) { if (node.type !== 'text') { return [node]; } const text = node.value; const matches = text.matchAll(regex); const nodes = []; let lastIndex = 0; for (const match of matches) { const value = parse(match[1]); const startIndex = match.index; if (startIndex > lastIndex) { nodes.push({ type: 'text', value: text.substring(lastIndex, startIndex) }); } nodes.push({ type, value }); lastIndex = startIndex + match[0].length; } if (lastIndex < text.length) { nodes.push({ type: 'text', value: text.substring(lastIndex) }); } return nodes; } const parsers = [ (node) => parser(node, /^```(.*?\n)```$/gms, 'code'), (node) => parser(node, /^`(.*?\n)`$/gms, 'code'), (node) => parser(node, /(((^\|.*)+\n?)+)/gm, 'table', (text) => { const result = text.trim().split('\n').map(row => { const cells = row.split('|').slice(1); if (cells[cells.length - 1].trim() === '') { cells.pop(); } return cells.map(cell => cell.trim()); }); result.splice(1, 1); return result; }), (node) => parser(node, /^>(.*)/gm, 'quote', (text) => [{ type: 'text', value: text, }]), (node) => parser(node, /^(#{1,6} .*)/gm, 'header', (text) => [{ type: 'text', value: text.trim() .replace(/\*\*(\S.*?\S)\*\*/g, (match, captured) => captured) .replace(/\*\*(\S.*)$/g, (match, captured) => captured), formatting: { bold: [{ begin: 0, end: text.length }] }, }]), ]; function escape(text) { return text.replace(/[\\\[\]\-(){}+_*~`>#=|!.]/g, (match) => '\\' + match) } export function markdownV2(nodes) { let output = ''; for (const node of nodes) { switch (node.type) { case 'text': output += markdownV2Text(node) + '\n' break; case 'code': const codeBlock = '```' + escape(node.value) + '```'; let remainingCode = codeBlock; while (remainingCode.length > 0) { const remainingSpace = MAX_OUTPUT_SIZE - output.length; const chunkLength = Math.min(remainingCode.length, remainingSpace); output += remainingCode.substring(0, chunkLength); remainingCode = remainingCode.substring(chunkLength); if (remainingCode.length > 0) { overflow(); } } break; case 'table': output += '```markdown\n' const rows = node.value; const maxLengths = rows[0].map((header, i) => Math.max(header.length, ...rows.slice(1).map(row => row[i] ? row[i].length : 0)) ); for (let i = 0; i < rows.length; i++) { const row = rows[i]; output += escape('| ' + row.map((cell, j) => cell.padEnd(maxLengths[j])).join(' | ') + ' |\n'); if (i === 0) { output += escape('| ' + maxLengths.map(length => '-'.repeat(length)).join(' | ') + ' |\n'); } } output += '```\n' break; case 'quote': output += '>' + markdownV2(node.value) break case 'header': output += markdownV2(node.value) break } } if (output[output.length - 1] === '\n') { output = output.slice(0, -1) } return output; } export function parse(text) { let in_nodes = [{type: 'text', value: text}] for (const fn of parsers) { const out_nodes = [] for (let i = 0; i < in_nodes.length; i++) { out_nodes.push(...fn(in_nodes[i])) } in_nodes = out_nodes } return in_nodes } </file> <file path="./utils/splitMessage.js"> import { markdownV2 } from './markdownV2.js'; export const splitMessage = (text) => { const maxLength = 4096; // Telegram max message length const formattedText = markdownV2(text); const messages = []; let remainingText = formattedText; while (remainingText.length > 0) { if (remainingText.length <= maxLength) { messages.push(remainingText); break; } let splitIndex = remainingText.lastIndexOf('\n', maxLength); if (splitIndex === -1) { splitIndex = maxLength; } const messagePart = remainingText.slice(0, splitIndex).trim(); messages.push(messagePart); remainingText = remainingText.slice(splitIndex).trim(); } return messages; }; </file> <file path="./utils/session.js"> import { redisClient } from './redisClient.js'; const SESSION_TTL = 60 * 60 * 24; // 1 day in seconds export const getSessionKey = (sessionId) => `session:${sessionId}`; export const getUserSessionKey = (userId) => `userSession:${userId}`; export const getSession = async (sessionId) => { try { const sessionData = await redisClient.get(getSessionKey(sessionId)); return sessionData ? JSON.parse(sessionData) : null; } catch (error) { console.error(`Error getting session ${sessionId}:`, error); return null; } }; export const setSession = async (sessionId, session) => { const key = getSessionKey(sessionId); const value = JSON.stringify(session); return redisClient.setEx(key, SESSION_TTL, value); }; export const getUserSession = async (userId) => { try { return await redisClient.get(getUserSessionKey(userId)); } catch (error) { console.error(`Error getting user session for user ${userId}:`, error); return null; } }; export const setUserSession = (userId, sessionId) => { const key = getUserSessionKey(userId); return redisClient.setEx(key, SESSION_TTL, sessionId); }; export const createSession = async (sessionId) => { const session = { commands: [], results: [], promptNumber: 2, password: null, userId: null, chatId: null, processing: false, }; await setSession(sessionId, session); return session; }; </file> <file path="./INSTRUCTIONS.md"> Rewrite each file of codebase, simplify code as much as possible </file>

Created by wprhvso and OPENAI01
OpenAI 01 Preview

Translate to English: 刃と刃が火花を散らして絡み合う。その激突は森羅万象の叫...

Translate to English: 刃と刃が火花を散らして絡み合う。その激突は森羅万象の叫喚にも似て、凄まじい力と力の相克だったが、当の男たちはまったく対照的な様相を示していた。 すなわち暴力の魔獣がごとく攻め掛かるMagsarionと、緩い立ち回りのまま事もなげに応じ続けるVarhram。両者の性格的な違いはもとより、剣技の質も一切合切かけ離れている。 この相違は二人の立場と心根を表す必然であったが、憂うべきか讃えるべきかは判然としない。ただ、Varhramは笑っていた。視点の異なる世界から、彼流の愛と喜びを噛みしめて、眼前の勝負に感無量といった趣を見せている。 「おお、凄いな。滅茶苦茶だけど重い剣だ。これがおまえなりに集めたみんなの祈りというわけか」 舌を巻いた風に感心して後退しつつも、窮した様子は微塵もない。事実としてVarhramは押し負けてなどいなかったし、彼が持つDivine Swordにもみんなの祈りが宿っている。 Magsarionが真我の宇宙を滅尽した経緯のすべてと、呑み込んできた想いの数々をVarhramも有していた。ずっと傍にいたというZurvanの存在を奪い取って顕現したこと。加えそもそもつい最前まで、Divine Swordはたった一振りであったこと。Quinnが集めた奇跡はアフマズダも体験しており、Magsarionが歩いた道はVarhramも歩いている。 受け取り方に天地の違いはあれど、抱えた武装は同じだった。よって勝負の趨勢を占うなら、使い手の性能がまずは問われることになる。 そこについての評価基準は無論幾つかあるものの、単純な技量面に焦点を当てれば論ずるにも値しない。剣士としての優劣は、悲しいほどに瞭然だ。 猛然と突き掛かるMagsarionの一閃を、下から掬うようにして逸らすVarhram。両手を跳ね上げられた形になった弟は胴に大きな隙を晒し、だが兄のほうも腕を振り上げているため同時に攻めへは繋げられない。しかしVarhramは攻防一体を当たり前に、かつ慮外な手で実現させる。 刃が触れ合った瞬間に、彼は必要な最低限の力を残して柄から手を離していた。結果、Divine Sword《Ahura Mazda》は両者の間にある空中を一回転し、その切っ先がMagsarionへ向いた刹那を逃さずVarhramの蹴りが柄頭に飛ぶ。際どいところで串刺しは免れるも、脇腹を派手に削られた弟はもんどりうって横に倒れた。しかもまだ終わりではない。 足首を十字状の鍔に搦めて、バトンでも回すように追撃が放たれた。曲芸じみた技であるにも拘わらず、恐ろしいほど流麗で隙がない。躱しきれず右腿を貫かれ、地に縫い止められた格好ながらも即座に反撃したMagsarionは称賛されるべきだろう。だがVarhramは空いた両手で難なく白刃を挟み止めたのみならず、魔法としか思えぬ手際でDivine Sword《Quinn》を奪い取っていた。 型破りな戦法で翻弄した矢先に、今度は教科書通りの奥義に値する無刀取り。邪道も正道も関係なく、有効な技なら等しく極めている証だった。いや、そんな表現すら生ぬるい。 Magsarionから剣を取り上げた者など過去を遡って一人もおらず、それだけでVarhramが言語を絶する達人なのは明らかだ。加え、まったく本気を出している風でもない。 なぜならば―― 「おまえは武器に触れ続けてないと駄目なんだろ? だからこれは交換だ」 この期に及んで、彼はMagsarionのCommandmentを慮っていた。先にDivine Sword《Ahura Mazda》を突き立てたので、Divine Sword《Quinn》を奪っても破戒にならないはずだと優しげな態度を滲ませつつ言っているのだ。 まるで稽古をつけるような振る舞いは、紛れもなく父であり兄のもの。ここに至るまでの経緯を思えば悲惨なほどずれていたが、情の発露と表現して差し支えあるまい。 「さあ来いよ。まだまだ始まったばかりじゃないか」 「当たり前だ」 腿に刺さった剣を引き抜き、再びMagsarionが斬り掛かった。Divine Swordの中身もそれに応じて、QuinnとAhura Mazdaが入れ替わる。彼女たちの存在意義は使い手に依拠するもので、物理的な器は意味を成さない。息子の手に母があり、父の手に妻があるという構図が強固な現実と化し出来あがっている。ゆえにMagsarionが剣に反逆される事態は起きなかったが、だからといって問題なしとは言いにくい。 戦況があくまでVarhramの管制下にある点は揺るがないのだ。その後も数合交えるたびに武器の表層的な交換が連続し、つまり何度もMagsarionは剣を取られている。歴然と言うのも生易しい力の差がそこにあった。 もはや傍目には、滑稽とさえ思える一方的な展開である。優勢の側からすれば欠伸を催す状況で、なのにVarhramの目は退屈を映していない。むしろ時を追うごとに、喜々と燃え上がっていく始末。 「嬉しいなあ。いつも情つれなかったおまえが、ムキになって俺の相手をしてくれる」 しみじみと明かす胸中がこの男なりの本音だった。彼は息子との語らいを心から歓迎しており、更なる強さを開陳していく。 「右手の小指」 何の気なしに放たれた一言から数瞬遅れて、Magsarionの右手小指が斬り飛ばされた。自身の一部が放物線を描いていく様に驚く間もなく、次の声と刃が重なる。 「左の耳」 やはり同じく、Varhramの指定した箇所がMagsarionから失われた。 「左手中指。右足親指。左眉の上。口の右端を一寸裂く」 それは予告攻撃だった。これからおまえの何処を攻めると宣言し、その通りの結果を決まった事実のごとく積み上げている。分かっていながら防げないという不条理は、Magsarionの第二Commandmentを鑑みれば技量差で片づけられぬ域だろう。相手の動きを完全に予測したと言うよりも、描いた絵図の強制にも似た所業だった。 すなわち望む未来を引き寄せる力で、MunsaratのCommandmentに他ならない。百貌たる男の本領が、再びアイオーンとなってMan Murdering Demonの像を出現させる。 「だから申し上げたでしょう。あなたの手に負える御方ではありませんよ」 Varhramの背後に浮かんだMunsaratが、主人と連動する形で巨大なノコギリを振るっていた。二重になった斬撃はその分だけ精度を増し、Magsarionの身体を末端から削っていく。 「我が主は過去を知り、ゆえに未来を確定させる。こうしてあなたと対峙するに至ったことこそ、引き寄せが盤石である証ですよ。もちろん、すでに勝敗も決まっている」 Magsarionの右耳を削ぎ飛ばし、愉悦に笑うMunsarat。上がる紅の飛沫を浴びながら、Man Murdering Demonは詠嘆する。 「とうに血肉を捨てたはずのあなたが、なぜ流血するのかお分かりですかな? 心が折れればImmutableの身体など、妄言にすぎぬという意味ですよ」 予告攻撃を防げない。負けを認めてはいないものの、そうした失敗の連続がダメージとなり顕れている。勝てば奪えるというVarhramの特性が、Magsarionの存在力を芯から崩しにかかっていた。 つまり本当の敗北感を抱いた瞬間、何もかもを持っていかれる。その意味でこれは非常に有効な攻めだった。血達磨と化したMagsarionの現状が、如実にそれを示している。 「右目を突く。鼻を削ぐ。足の腱を断って動けなくした後に――」 明朗快活に凄惨な予告を続けるVarhramが、やはり言った通りを実行した。背後のMunsaratも同じくノコギリを振り回し、主従の思い出とも表現すべき一撃へと繋いでいく。 「胴を薙いで真っ二つだ」

Created by Gaming Ghouls and OPENAI01
OpenAI 01 Preview

Codebase Refactoring Request

<file path="./package.json"> { "name": "your-project", "version": "1.0.0", "type": "module", "main": "index.js", "scripts": { "start": "node index.js" }, "dependencies": { "bcrypt": "^5.1.1", "express": "^4.21.0", "html-entities": "^2.5.2", "node-telegram-bot-api": "^0.66.0", "redis": "^4.7.0", "validator": "^13.12.0" } } </file> <file path="./config/config.js"> export const port = process.env.PORT || 8000; export const botToken = process.env.BOT_TOKEN; export const botUsername = process.env.BOT_USERNAME; export const redisUrl = process.env.REDIS_URL || 'redis://localhost:6379'; if (!botToken || !botUsername) { throw new Error('BOT_TOKEN and BOT_USERNAME must be set in environment variables.'); } </file> <file path="./middleware/validateSessionId.js"> export const validateSessionId = (req, res, next) => { const sessionId = req.params.sessionId?.trim(); const sessionIdPattern = /^[a-zA-Z0-9_-]+$/; if (!sessionId || !sessionIdPattern.test(sessionId)) { return res.status(400).send('Invalid Session ID.'); } req.sessionId = sessionId; next(); }; </file> <file path="./index.js"> import express from 'express'; import commandsRoutes from './routes/commands'; import updateRoutes from './routes/update'; import sessionsRoutes from './routes/sessions'; import passwordRoutes from './routes/password'; import { redisClient } from './utils/redisClient'; import { port } from './config/config'; const app = express(); app.use(express.json()); app.use('/commands', commandsRoutes); app.use('/update', updateRoutes); app.use('/sessions', sessionsRoutes); app.use('/password', passwordRoutes); const server = app.listen(port, () => console.log(`Server is listening on port ${port}`)); process.on('SIGINT', async () => { console.log('Shutting down server...'); try { await redisClient.quit(); server.close(() => { console.log('Server closed.'); process.exit(0); }); } catch (err) { console.error('Error during shutdown:', err); process.exit(1); } }); </file> <file path="./bot/handlers.js"> import { bot } from './instance.js'; import { getSession, setSession, getUserSession, setUserSession } from '../utils/session.js'; import { botUsername } from '../config/config'; import { processSession } from '../controllers/bot'; import bcrypt from 'bcrypt'; export const handleMessage = async (msg) => { const chatId = msg.chat.id; const userId = msg.from.id; let text = msg.text?.trim() || ''; if (text.startsWith('/start')) { await handleStartCommand(chatId, userId, text); } else if (text === '/clear') { await handleClearCommand(chatId, userId); } else { await handleUserMessage(chatId, userId, text); } }; const handleStartCommand = async (chatId, userId, text) => { const params = text.split(' ').slice(1); if (params.length > 0) { const param = params.join(' '); const [sessionId, password] = param.split('-'); if (!sessionId || !password) { return bot.sendMessage(chatId, 'Invalid session link. Please check the format.'); } const session = await getSession(sessionId); if (session) { const passwordMatch = await bcrypt.compare(password, session.password); if (passwordMatch) { if (!session.userId || session.userId === userId) { session.userId = userId; session.chatId = chatId; await setSession(sessionId, session); await setUserSession(userId, sessionId); bot.sendMessage(chatId, `Welcome to session ${sessionId}! This session is now linked to your account.`); } else { bot.sendMessage(chatId, `This session is already linked to another account.`); } } else { bot.sendMessage(chatId, 'Invalid session ID or password.'); } } } else { bot.sendMessage( chatId, `Welcome! To access a session, use a link in the format https://t.me/${botUsername}?start=<session_id>-<password>` ); } }; const handleClearCommand = async (chatId, userId) => { const sessionId = await getUserSession(userId); if (!sessionId) { return bot.sendMessage(chatId, 'Active session not found.'); } const session = await getSession(sessionId); if (session) { session.commands.push({ type: 'CLEAR' }); session.promptNumber = 2; await setSession(sessionId, session); bot.sendMessage(chatId, 'Session cleared.'); } else { bot.sendMessage(chatId, 'Active session not found.'); } }; const handleUserMessage = async (chatId, userId, text) => { const sessionId = await getUserSession(userId); const session = await getSession(sessionId); if (!session) { return bot.sendMessage( chatId, 'Active session not found. Please use a deep link to access a session.' ); } let temperature = 0; const tempMatch = text.match(/^[tт](\d+(?:[.,]\d+)?)/i); if (tempMatch) { temperature = parseFloat(tempMatch[1].replace(',', '.')); text = text.replace(tempMatch[0], '').trim(); } session.commands.push({ type: 'RUN', text, promptNumber: session.promptNumber, temperature, }); session.promptNumber += 2; await setSession(sessionId, session); bot.sendMessage(chatId, 'Please wait...'); if (!session.processing) { processSession(sessionId); } }; </file> <file path="./bot/instance.js"> import TelegramBot from 'node-telegram-bot-api'; import { botToken } from '../config/config'; import { handleMessage } from './handlers'; export const bot = new TelegramBot(botToken, { polling: true }); bot.on('message', async (msg) => { try { await handleMessage(msg); } catch (error) { console.error('Error handling message:', error); bot.sendMessage(msg.chat.id, 'An error occurred while processing your message.'); } }); </file> <file path="./controllers/bot.js"> import { getSession, setSession } from '../utils/session.js'; import { bot } from '../bot/instance.js'; import { splitMessage } from '../utils/splitMessage.js'; export const processSession = async (sessionId) => { const session = await getSession(sessionId); if (!session) { return; } session.processing = true; await setSession(sessionId, session); try { while (session.results.length > 0) { const resultText = session.results.shift(); await processMessages(sessionId, resultText); } } catch (error) { console.error(`Error processing session ${sessionId}:`, error); } finally { session.processing = false; await setSession(sessionId, session); } }; export const processMessages = async (sessionId, text) => { const session = await getSession(sessionId); if (!session || !session.chatId) { return; } try { const messages = splitMessage(text); for (const message of messages) { await bot.sendMessage(session.chatId, message, { parse_mode: 'MarkdownV2' }); } } catch (error) { console.error(`Error sending messages for session ${sessionId}:`, error); } }; </file> <file path="./routes/sessions.js"> import express from 'express'; import { redisClient } from '../utils/redisClient'; const router = express.Router(); router.get('/', async (req, res) => { try { const keys = await redisClient.keys('session:*'); const sessionIds = keys.map((key) => key.replace('session:', '')); res.json(sessionIds); } catch (error) { console.error('Error fetching sessions:', error); res.status(500).send('Internal Server Error'); } }); export default router; </file> <file path="./routes/commands.js"> import express from 'express'; import { validateSessionId } from '../middleware/validateSessionId'; import { getSession, setSession, createSession } from '../utils/session.js'; const router = express.Router(); router.get('/:sessionId', validateSessionId, async (req, res) => { const sessionId = req.sessionId; try { let session = await getSession(sessionId); if (!session) { session = await createSession(sessionId); } const commands = [...session.commands]; session.commands = []; await setSession(sessionId, session); res.json(commands); } catch (error) { console.error(`Error fetching commands for session ${sessionId}:`, error); res.status(500).send('Internal Server Error'); } }); router.post('/:sessionId', validateSessionId, async (req, res) => { const sessionId = req.sessionId; try { let session = await getSession(sessionId); if (!session) { session = await createSession(sessionId); } const command = req.body; if (!command || !command.type) { return res.status(400).send('Invalid command.'); } if (command.type === 'CLEAR') { session.promptNumber = 2; } else { command.promptNumber = session.promptNumber; session.promptNumber += 2; } session.commands.push(command); await setSession(sessionId, session); res.send('Command added.'); } catch (error) { console.error(`Error adding command to session ${sessionId}:`, error); res.status(500).send('Internal Server Error'); } }); export default router; </file> <file path="./routes/password.js"> import express from 'express'; import validator from 'validator'; import { validateSessionId } from '../middleware/validateSessionId'; import { getSession, setSession, createSession } from '../utils/session.js'; import { botUsername } from '../config/config.js'; const router = express.Router(); router.post('/:sessionId', validateSessionId, async (req, res) => { try { const password = validator.escape(req.body.password); if (validator.isEmpty(password)) { return res.status(400).send('Password is required.'); } const sessionId = req.sessionId; let session = await getSession(sessionId); if (!session) { session = await createSession(sessionId); } session.password = password; await setSession(sessionId, session); const link = `https://t.me/${botUsername}?start=${sessionId}-${password}`; res.send({ link }); } catch (error) { console.error(`Error setting password for session ${req.sessionId}:`, error); res.status(500).send('Internal Server Error'); } }); </file> <file path="./routes/update.js"> import express from 'express'; import { validateSessionId } from '../middleware/validateSessionId'; import { getSession, setSession, createSession } from '../utils/session.js'; import { processMessages } from '../controllers/bot'; const router = express.Router(); router.post('/:sessionId', validateSessionId, async (req, res) => { try { const sessionId = req.sessionId; let session = await getSession(sessionId); if (!session) { session = await createSession(sessionId); } session.results.push(req.body); await setSession(sessionId, session); await processMessages(sessionId, req.body); res.send('Result received.'); } catch (error) { console.error(`Error updating session ${req.sessionId}:`, error); res.status(500).send('Internal Server Error'); } }); export default router; </file> <file path="./utils/redisClient.js"> import Redis from 'redis'; import { redisUrl } from '../config/config'; export const redisClient = Redis.createClient({ url: redisUrl, }); redisClient.on('error', (err) => console.error('Redis error:', err)); (async () => { try { await redisClient.connect(); console.log('Connected to Redis.'); } catch (error) { console.error('Failed to connect to Redis:', error); process.exit(1); } })(); </file> <file path="./utils/markdownV2Text.js"> import { decode } from "html-entities"; function parseFormatting(node, type, symbol_left, symbol_right = symbol_left) { if (!node.formatting) node.formatting = {}; if (!node.formatting[type]) node.formatting[type] = []; const escaped_left = symbol_left.replace(/[.*+?^${}()|\[\]\\]/g, '\\$&'); const escaped_right = symbol_right.replace(/[.*+?^${}()|\[\]\\]/g, '\\$&'); for (const match of node.value.matchAll(new RegExp(`${escaped_left}\\S.*?\\S${escaped_right}`, 'g'))) { const left = match.index const right = match.index + match[0].length - symbol_right.length fixFormattingRanges(node.formatting, -1, left, symbol_left.length) fixFormattingRanges(node.formatting, -1, right, symbol_right.length) } let removedLength = 0; const handle = (match, captured, index) => { const begin = index - removedLength; const end = begin + captured.length; node.formatting[type].push({ begin, end }); removedLength += match.length - captured.length; return captured; } node.value = node.value.replace(new RegExp(`${escaped_left}(\\S.*?\\S)${escaped_right}`, 'g'), handle); removedLength = 0 node.value = node.value.replace(new RegExp(`${escaped_left}(\\S.*)$`), handle) } const formatting = [ (node) => node.value = decode(node.value), (node) => parseFormatting(node, 'monospace', '`'), (node) => parseFormatting(node, 'bold', '**'), (node) => parseFormatting(node, 'italic', '*'), (node) => parseFormatting(node, 'italic', '_'), (node) => parseFormatting(node, 'strikethrough', '~~'), (node) => parseFormatting(node, 'strikethrough', '~'), (node) => parseFormatting(node, 'underline', '<u>', '</u>'), (node) => parseFormatting(node, 'spoiler', '<spoiler>', '</spoiler>') ] function iterateFormatting(formatting, callback) { for (const type in formatting) { formatting[type].forEach(f => { callback(f, type) }) } } function fixFormattingRanges(formatting, diff, index, count = 1) { for (let i = index; i < index + count; i++) { iterateFormatting(formatting, (f) => { if (index < f.begin) f.begin += diff if (index <= f.end) f.end += diff }) } } function fixFormattingRangesV2(formatting, diff, index, count = 1) { for (let i = index; i < index + count; i++) { iterateFormatting(formatting, (f) => { if (index < f.begin) f.begin += diff if (index < f.end) f.end += diff }) } } function symbolOfFormattingType(type) { switch (type) { case 'bold': return '*' case 'italic': return '_' case 'monospace': return '`' case 'strikethrough': return '~' case 'underline': return '__' case 'spoiler': return '||' } } function escapeMarkdownV2(node) { let counter = 0 node.value = node.value.replace(/[\\\[\]\-(){}+_*~`>#=|!.]/g, (match, index) => { fixFormattingRangesV2(node.formatting, +1, index + counter) counter++ return '\\' + match; }); } function parseText(node) { for (const parse of formatting) { parse(node) } return node } export function markdownV2Text(input_node) { const node = { ...input_node } parseText(node) escapeMarkdownV2(node) let text = node.value function insert(i, symbol) { fixFormattingRanges(node.formatting, +symbol.length, i) text = text.substring(0, i) + symbol + text.substring(i); } iterateFormatting(node.formatting, (f, type) => { insert(f.begin, symbolOfFormattingType(type)) insert(f.end, symbolOfFormattingType(type)) }) text = text.replace(/\\!\\\[(?:\S|\S.*?\S)\\]\\\((?:\S|\S.*?\S)\\\)/g, (match) => { const match1 = match.matchAll(/\\\[(\S|\S.*?\S)\\]\\\((\S|\S.*?\S)\\\)/g).next().value return `![${match1[1]}](${match1[2]})` }) text = text.replace(/\\\[(?:\S|\S.*?\S)\\]\\\((?:\S|\S.*?\S)\\\)/g, (match) => { const match1 = match.matchAll(/\\\[(\S|\S.*?\S)\\]\\\((\S|\S.*?\S)\\\)/g).next().value return `[${match1[1]}](${match1[2]})` }) return text } </file> <file path="./utils/markdownV2.js"> import { markdownV2Text } from "./markdownV2Text"; function parser(node, regex, type, parse = (text) => {return text}) { if (node.type !== 'text') { return [node]; } const text = node.value; const matches = text.matchAll(regex); const nodes = []; let lastIndex = 0; for (const match of matches) { const value = parse(match[1]); const startIndex = match.index; if (startIndex > lastIndex) { nodes.push({ type: 'text', value: text.substring(lastIndex, startIndex) }); } nodes.push({ type, value }); lastIndex = startIndex + match[0].length; } if (lastIndex < text.length) { nodes.push({ type: 'text', value: text.substring(lastIndex) }); } return nodes; } const parsers = [ (node) => parser(node, /^```(.*?\n)```$/gms, 'code'), (node) => parser(node, /^`(.*?\n)`$/gms, 'code'), (node) => parser(node, /(((^\|.*)+\n?)+)/gm, 'table', (text) => { const result = text.trim().split('\n').map(row => { const cells = row.split('|').slice(1); if (cells[cells.length - 1].trim() === '') { cells.pop(); } return cells.map(cell => cell.trim()); }); result.splice(1, 1); return result; }), (node) => parser(node, /^>(.*)/gm, 'quote', (text) => [{ type: 'text', value: text, }]), (node) => parser(node, /^(#{1,6} .*)/gm, 'header', (text) => [{ type: 'text', value: text.trim() .replace(/\*\*(\S.*?\S)\*\*/g, (match, captured) => captured) .replace(/\*\*(\S.*)$/g, (match, captured) => captured), formatting: { bold: [{ begin: 0, end: text.length }] }, }]), ]; function escape(text) { return text.replace(/[\\\[\]\-(){}+_*~`>#=|!.]/g, (match) => '\\' + match) } export function markdownV2(nodes) { let output = ''; for (const node of nodes) { switch (node.type) { case 'text': output += markdownV2Text(node) + '\n' break; case 'code': const codeBlock = '```' + escape(node.value) + '```'; let remainingCode = codeBlock; while (remainingCode.length > 0) { const remainingSpace = MAX_OUTPUT_SIZE - output.length; const chunkLength = Math.min(remainingCode.length, remainingSpace); output += remainingCode.substring(0, chunkLength); remainingCode = remainingCode.substring(chunkLength); if (remainingCode.length > 0) { overflow(); } } break; case 'table': output += '```markdown\n' const rows = node.value; const maxLengths = rows[0].map((header, i) => Math.max(header.length, ...rows.slice(1).map(row => row[i] ? row[i].length : 0)) ); for (let i = 0; i < rows.length; i++) { const row = rows[i]; output += escape('| ' + row.map((cell, j) => cell.padEnd(maxLengths[j])).join(' | ') + ' |\n'); if (i === 0) { output += escape('| ' + maxLengths.map(length => '-'.repeat(length)).join(' | ') + ' |\n'); } } output += '```\n' break; case 'quote': output += '>' + markdownV2(node.value) break case 'header': output += markdownV2(node.value) break } } if (output[output.length - 1] === '\n') { output = output.slice(0, -1) } return output; } export function parse(text) { let in_nodes = [{type: 'text', value: text}] for (const fn of parsers) { const out_nodes = [] for (let i = 0; i < in_nodes.length; i++) { out_nodes.push(...fn(in_nodes[i])) } in_nodes = out_nodes } return in_nodes } </file> <file path="./utils/splitMessage.js"> import { markdownV2, parse } from './markdownV2'; export const splitMessage = (text) => { const maxLength = 4096; // Telegram max message length const formattedText = markdownV2(parse(text)); const messages = []; let remainingText = formattedText; while (remainingText.length > 0) { if (remainingText.length <= maxLength) { messages.push(remainingText); break; } let splitIndex = remainingText.lastIndexOf('\n', maxLength); if (splitIndex === -1) { splitIndex = maxLength; } const messagePart = remainingText.slice(0, splitIndex); messages.push(messagePart); remainingText = remainingText.slice(splitIndex); } return messages; }; </file> <file path="./utils/session.js"> import { redisClient } from './redisClient'; import bcrypt from 'bcrypt'; const SESSION_TTL = 60 * 60 * 24; // 1 day in seconds export const getSessionKey = (sessionId) => `session:${sessionId}`; export const getUserSessionKey = (userId) => `userSession:${userId}`; export const getSession = async (sessionId) => { try { const sessionData = await redisClient.get(getSessionKey(sessionId)); return sessionData ? JSON.parse(sessionData) : null; } catch (error) { console.error(`Error getting session ${sessionId}:`, error); return null; } }; export const setSession = async (sessionId, session) => { if (session.password) { session.password = await bcrypt.hash(session.password, 10); } const key = getSessionKey(sessionId); const value = JSON.stringify(session); return redisClient.setEx(key, SESSION_TTL, value); }; export const getUserSession = async (userId) => { try { return await redisClient.get(getUserSessionKey(userId)); } catch (error) { console.error(`Error getting user session for user ${userId}:`, error); return null; } }; export const setUserSession = (userId, sessionId) => { const key = getUserSessionKey(userId); return redisClient.setEx(key, SESSION_TTL, sessionId); }; export const createSession = async (sessionId) => { const session = { commands: [], results: [], promptNumber: 2, password: null, userId: null, chatId: null, processing: false, }; await setSession(sessionId, session); return session; }; </file> <file path="./INSTRUCTIONS.md"> Refactor the entire codebase to adhere to best practices </file>

Created by wprhvso and OPENAI01
OpenAI 01 Preview

Code Security Improvements

<file path="./package.json"> { "name": "your-project", "version": "1.0.0", "type": "module", "main": "index.js", "scripts": { "start": "node index.js" }, "dependencies": { "express": "^4.21.0", "html-entities": "^2.5.2", "node-telegram-bot-api": "^0.66.0", "redis": "^4.7.0" } } </file> <file path="./config/config.js"> export const port = process.env.PORT || 8000; export const botToken = process.env.BOT_TOKEN; export const botUsername = process.env.BOT_USERNAME; export const redisUrl = process.env.REDIS_URL || 'redis://localhost:6379'; if (!botToken || !botUsername) { throw new Error('BOT_TOKEN and BOT_USERNAME must be set in environment variables.'); } </file> <file path="./middleware/validateSessionId.js"> export const validateSessionId = (req, res, next) => { const sessionId = req.params.sessionId?.trim(); if (!sessionId) { return res.status(400).send('Session ID is required.'); } req.sessionId = sessionId; next(); }; </file> <file path="./index.js"> import express from 'express'; import commandsRoutes from './routes/commands'; import updateRoutes from './routes/update'; import sessionsRoutes from './routes/sessions'; import passwordRoutes from './routes/password'; import { redisClient } from './utils/redisClient'; import { port } from './config/config'; const app = express(); app.use(express.json()); app.use('/commands', commandsRoutes); app.use('/update', updateRoutes); app.use('/sessions', sessionsRoutes); app.use('/password', passwordRoutes); const server = app.listen(port, () => console.log(`Server is listening on port ${port}`)); process.on('SIGINT', async () => { console.log('Shutting down server...'); try { await redisClient.quit(); server.close(() => { console.log('Server closed.'); process.exit(0); }); } catch (err) { console.error('Error during shutdown:', err); process.exit(1); } }); </file> <file path="./bot/handlers.js"> import { bot } from './instance.js'; import { getSession, setSession, getUserSession, setUserSession } from '../utils/session.js'; import { botUsername } from '../config/config'; import { processSession } from '../controllers/bot'; export const handleMessage = async (msg) => { const chatId = msg.chat.id; const userId = msg.from.id; let text = msg.text?.trim() || ''; if (text.startsWith('/start')) { await handleStartCommand(chatId, userId, text); } else if (text === '/clear') { await handleClearCommand(chatId, userId); } else { await handleUserMessage(chatId, userId, text); } }; const handleStartCommand = async (chatId, userId, text) => { const params = text.split(' ').slice(1); if (params.length > 0) { const param = params.join(' '); const [sessionId, password] = param.split('-'); if (!sessionId || !password) { return bot.sendMessage(chatId, 'Invalid session link. Please check the format.'); } const session = await getSession(sessionId); if (session && session.password === password) { if (!session.userId || session.userId === userId) { session.userId = userId; session.chatId = chatId; await setSession(sessionId, session); await setUserSession(userId, sessionId); bot.sendMessage(chatId, `Welcome to session ${sessionId}! This session is now linked to your account.`); } else { bot.sendMessage(chatId, `This session is already linked to another account.`); } } else { bot.sendMessage(chatId, 'Invalid session ID or password.'); } } else { bot.sendMessage( chatId, `Welcome! To access a session, use a link in the format https://t.me/${botUsername}?start=<session_id>-<password>` ); } }; const handleClearCommand = async (chatId, userId) => { const sessionId = await getUserSession(userId); if (!sessionId) { return bot.sendMessage(chatId, 'Active session not found.'); } const session = await getSession(sessionId); if (session) { session.commands.push({ type: 'CLEAR' }); session.promptNumber = 2; await setSession(sessionId, session); bot.sendMessage(chatId, 'Session cleared.'); } else { bot.sendMessage(chatId, 'Active session not found.'); } }; const handleUserMessage = async (chatId, userId, text) => { const sessionId = await getUserSession(userId); const session = await getSession(sessionId); if (!session) { return bot.sendMessage( chatId, 'Active session not found. Please use a deep link to access a session.' ); } let temperature = 0; const tempMatch = text.match(/^[tт](\d+(?:[.,]\d+)?)/i); if (tempMatch) { temperature = parseFloat(tempMatch[1].replace(',', '.')); text = text.replace(tempMatch[0], '').trim(); } session.commands.push({ type: 'RUN', text, promptNumber: session.promptNumber, temperature, }); session.promptNumber += 2; await setSession(sessionId, session); bot.sendMessage(chatId, 'Please wait...'); if (!session.processing) { processSession(sessionId); } }; </file> <file path="./bot/instance.js"> import TelegramBot from 'node-telegram-bot-api'; import { botToken } from '../config/config'; import { handleMessage } from './handlers'; export const bot = new TelegramBot(botToken, { polling: true }); bot.on('message', async (msg) => { try { await handleMessage(msg); } catch (error) { console.error('Error handling message:', error); bot.sendMessage(msg.chat.id, 'An error occurred while processing your message.'); } }); </file> <file path="./controllers/bot.js"> import { getSession, setSession } from '../utils/session.js'; import { bot } from '../bot/instance.js'; import { splitMessage } from '../utils/splitMessage.js'; export const processSession = async (sessionId) => { const session = await getSession(sessionId); if (!session) { return; } session.processing = true; await setSession(sessionId, session); try { while (session.results.length > 0) { const resultText = session.results.shift(); await processMessages(sessionId, resultText); } } catch (error) { console.error(`Error processing session ${sessionId}:`, error); } finally { session.processing = false; await setSession(sessionId, session); } }; export const processMessages = async (sessionId, text) => { const session = await getSession(sessionId); if (!session || !session.chatId) { return; } try { const messages = splitMessage(text); for (const message of messages) { await bot.sendMessage(session.chatId, message, { parse_mode: 'MarkdownV2' }); } } catch (error) { console.error(`Error sending messages for session ${sessionId}:`, error); } }; </file> <file path="./routes/sessions.js"> import express from 'express'; import { redisClient } from '../utils/redisClient'; const router = express.Router(); router.get('/', async (req, res) => { try { const keys = await redisClient.keys('session:*'); const sessionIds = keys.map((key) => key.replace('session:', '')); res.json(sessionIds); } catch (error) { console.error('Error fetching sessions:', error); res.status(500).send('Internal Server Error'); } }); export default router; </file> <file path="./routes/commands.js"> import express from 'express'; import { validateSessionId } from '../middleware/validateSessionId'; import { getSession, setSession, createSession } from '../utils/session.js'; const router = express.Router(); router.get('/:sessionId', validateSessionId, async (req, res) => { const sessionId = req.sessionId; try { let session = await getSession(sessionId); if (!session) { session = await createSession(sessionId); } const commands = [...session.commands]; session.commands = []; await setSession(sessionId, session); res.json(commands); } catch (error) { console.error(`Error fetching commands for session ${sessionId}:`, error); res.status(500).send('Internal Server Error'); } }); router.post('/:sessionId', validateSessionId, async (req, res) => { const sessionId = req.sessionId; try { let session = await getSession(sessionId); if (!session) { session = await createSession(sessionId); } const command = req.body; if (!command || !command.type) { return res.status(400).send('Invalid command.'); } if (command.type === 'CLEAR') { session.promptNumber = 2; } else { command.promptNumber = session.promptNumber; session.promptNumber += 2; } session.commands.push(command); await setSession(sessionId, session); res.send('Command added.'); } catch (error) { console.error(`Error adding command to session ${sessionId}:`, error); res.status(500).send('Internal Server Error'); } }); export default router; </file> <file path="./routes/password.js"> import express from 'express'; import { validateSessionId } from '../middleware/validateSessionId'; import { getSession, setSession, createSession } from '../utils/session.js'; import { botUsername } from '../config/config.js'; const router = express.Router(); router.post('/:sessionId', validateSessionId, async (req, res) => { try { const { password } = req.body; if (!password) { return res.status(400).send('Password is required.'); } const sessionId = req.sessionId; let session = await getSession(sessionId); if (!session) { session = await createSession(sessionId); } session.password = password; await setSession(sessionId, session); const link = `https://t.me/${botUsername}?start=${sessionId}-${password}`; res.send({ link }); } catch (error) { console.error(`Error setting password for session ${req.sessionId}:`, error); res.status(500).send('Internal Server Error'); } }); export default router; </file> <file path="./routes/update.js"> import express from 'express'; import { validateSessionId } from '../middleware/validateSessionId'; import { getSession, setSession, createSession } from '../utils/session.js'; import { processMessages } from '../controllers/bot'; const router = express.Router(); router.post('/:sessionId', validateSessionId, async (req, res) => { try { const sessionId = req.sessionId; let session = await getSession(sessionId); if (!session) { session = await createSession(sessionId); } session.results.push(req.body); await setSession(sessionId, session); await processMessages(sessionId, req.body); res.send('Result received.'); } catch (error) { console.error(`Error updating session ${req.sessionId}:`, error); res.status(500).send('Internal Server Error'); } }); export default router; </file> <file path="./utils/redisClient.js"> import Redis from 'redis'; import { redisUrl } from '../config/config'; export const redisClient = Redis.createClient({ url: redisUrl, }); redisClient.on('error', (err) => console.error('Redis error:', err)); (async () => { try { await redisClient.connect(); console.log('Connected to Redis.'); } catch (error) { console.error('Failed to connect to Redis:', error); process.exit(1); } })(); </file> <file path="./utils/markdownV2Text.js"> import { decode } from "html-entities"; function parseFormatting(node, type, symbol_left, symbol_right = symbol_left) { if (!node.formatting) node.formatting = {}; if (!node.formatting[type]) node.formatting[type] = []; const escaped_left = symbol_left.replace(/[.*+?^${}()|\[\]\\]/g, '\\$&'); const escaped_right = symbol_right.replace(/[.*+?^${}()|\[\]\\]/g, '\\$&'); for (const match of node.value.matchAll(new RegExp(`${escaped_left}\\S.*?\\S${escaped_right}`, 'g'))) { const left = match.index const right = match.index + match[0].length - symbol_right.length fixFormattingRanges(node.formatting, -1, left, symbol_left.length) fixFormattingRanges(node.formatting, -1, right, symbol_right.length) } let removedLength = 0; const handle = (match, captured, index) => { const begin = index - removedLength; const end = begin + captured.length; node.formatting[type].push({ begin, end }); removedLength += match.length - captured.length; return captured; } node.value = node.value.replace(new RegExp(`${escaped_left}(\\S.*?\\S)${escaped_right}`, 'g'), handle); removedLength = 0 node.value = node.value.replace(new RegExp(`${escaped_left}(\\S.*)$`), handle) } const formatting = [ (node) => node.value = decode(node.value), (node) => parseFormatting(node, 'monospace', '`'), (node) => parseFormatting(node, 'bold', '**'), (node) => parseFormatting(node, 'italic', '*'), (node) => parseFormatting(node, 'italic', '_'), (node) => parseFormatting(node, 'strikethrough', '~~'), (node) => parseFormatting(node, 'strikethrough', '~'), (node) => parseFormatting(node, 'underline', '<u>', '</u>'), (node) => parseFormatting(node, 'spoiler', '<spoiler>', '</spoiler>') ] function iterateFormatting(formatting, callback) { for (const type in formatting) { formatting[type].forEach(f => { callback(f, type) }) } } function fixFormattingRanges(formatting, diff, index, count = 1) { for (let i = index; i < index + count; i++) { iterateFormatting(formatting, (f) => { if (index < f.begin) f.begin += diff if (index <= f.end) f.end += diff }) } } function fixFormattingRangesV2(formatting, diff, index, count = 1) { for (let i = index; i < index + count; i++) { iterateFormatting(formatting, (f) => { if (index < f.begin) f.begin += diff if (index < f.end) f.end += diff }) } } function symbolOfFormattingType(type) { switch (type) { case 'bold': return '*' case 'italic': return '_' case 'monospace': return '`' case 'strikethrough': return '~' case 'underline': return '__' case 'spoiler': return '||' } } function escapeMarkdownV2(node) { let counter = 0 node.value = node.value.replace(/[\\\[\]\-(){}+_*~`>#=|!.]/g, (match, index) => { fixFormattingRangesV2(node.formatting, +1, index + counter) counter++ return '\\' + match; }); } function parseText(node) { for (const parse of formatting) { parse(node) } return node } export function markdownV2Text(input_node) { const node = { ...input_node } parseText(node) escapeMarkdownV2(node) let text = node.value function insert(i, symbol) { fixFormattingRanges(node.formatting, +symbol.length, i) text = text.substring(0, i) + symbol + text.substring(i); } iterateFormatting(node.formatting, (f, type) => { insert(f.begin, symbolOfFormattingType(type)) insert(f.end, symbolOfFormattingType(type)) }) text = text.replace(/\\!\\\[(?:\S|\S.*?\S)\\]\\\((?:\S|\S.*?\S)\\\)/g, (match) => { const match1 = match.matchAll(/\\\[(\S|\S.*?\S)\\]\\\((\S|\S.*?\S)\\\)/g).next().value return `![${match1[1]}](${match1[2]})` }) text = text.replace(/\\\[(?:\S|\S.*?\S)\\]\\\((?:\S|\S.*?\S)\\\)/g, (match) => { const match1 = match.matchAll(/\\\[(\S|\S.*?\S)\\]\\\((\S|\S.*?\S)\\\)/g).next().value return `[${match1[1]}](${match1[2]})` }) return text } </file> <file path="./utils/markdownV2.js"> import { markdownV2Text } from "./markdownV2Text"; function parser(node, regex, type, parse = (text) => {return text}) { if (node.type !== 'text') { return [node]; } const text = node.value; const matches = text.matchAll(regex); const nodes = []; let lastIndex = 0; for (const match of matches) { const value = parse(match[1]); const startIndex = match.index; if (startIndex > lastIndex) { nodes.push({ type: 'text', value: text.substring(lastIndex, startIndex) }); } nodes.push({ type, value }); lastIndex = startIndex + match[0].length; } if (lastIndex < text.length) { nodes.push({ type: 'text', value: text.substring(lastIndex) }); } return nodes; } const parsers = [ (node) => parser(node, /^```(.*?\n)```$/gms, 'code'), (node) => parser(node, /^`(.*?\n)`$/gms, 'code'), (node) => parser(node, /(((^\|.*)+\n?)+)/gm, 'table', (text) => { const result = text.trim().split('\n').map(row => { const cells = row.split('|').slice(1); if (cells[cells.length - 1].trim() === '') { cells.pop(); } return cells.map(cell => cell.trim()); }); result.splice(1, 1); return result; }), (node) => parser(node, /^>(.*)/gm, 'quote', (text) => [{ type: 'text', value: text, }]), (node) => parser(node, /^(#{1,6} .*)/gm, 'header', (text) => [{ type: 'text', value: text.trim() .replace(/\*\*(\S.*?\S)\*\*/g, (match, captured) => captured) .replace(/\*\*(\S.*)$/g, (match, captured) => captured), formatting: { bold: [{ begin: 0, end: text.length }] }, }]), ]; function escape(text) { return text.replace(/[\\\[\]\-(){}+_*~`>#=|!.]/g, (match) => '\\' + match) } export function markdownV2(nodes) { let output = ''; for (const node of nodes) { switch (node.type) { case 'text': output += markdownV2Text(node) + '\n' break; case 'code': const codeBlock = '```' + escape(node.value) + '```'; let remainingCode = codeBlock; while (remainingCode.length > 0) { const remainingSpace = MAX_OUTPUT_SIZE - output.length; const chunkLength = Math.min(remainingCode.length, remainingSpace); output += remainingCode.substring(0, chunkLength); remainingCode = remainingCode.substring(chunkLength); if (remainingCode.length > 0) { overflow(); } } break; case 'table': output += '```markdown\n' const rows = node.value; const maxLengths = rows[0].map((header, i) => Math.max(header.length, ...rows.slice(1).map(row => row[i] ? row[i].length : 0)) ); for (let i = 0; i < rows.length; i++) { const row = rows[i]; output += escape('| ' + row.map((cell, j) => cell.padEnd(maxLengths[j])).join(' | ') + ' |\n'); if (i === 0) { output += escape('| ' + maxLengths.map(length => '-'.repeat(length)).join(' | ') + ' |\n'); } } output += '```\n' break; case 'quote': output += '>' + markdownV2(node.value) break case 'header': output += markdownV2(node.value) break } } if (output[output.length - 1] === '\n') { output = output.slice(0, -1) } return output; } export function parse(text) { let in_nodes = [{type: 'text', value: text}] for (const fn of parsers) { const out_nodes = [] for (let i = 0; i < in_nodes.length; i++) { out_nodes.push(...fn(in_nodes[i])) } in_nodes = out_nodes } return in_nodes } </file> <file path="./utils/splitMessage.js"> import { markdownV2, parse } from './markdownV2'; export const splitMessage = (text) => { const maxLength = 4096; // Telegram max message length const formattedText = markdownV2(parse(text)); const messages = []; let remainingText = formattedText; while (remainingText.length > 0) { if (remainingText.length <= maxLength) { messages.push(remainingText); break; } let splitIndex = remainingText.lastIndexOf('\n', maxLength); if (splitIndex === -1) { splitIndex = maxLength; } const messagePart = remainingText.slice(0, splitIndex); messages.push(messagePart); remainingText = remainingText.slice(splitIndex); } return messages; }; </file> <file path="./utils/session.js"> import { redisClient } from './redisClient'; const SESSION_TTL = 60 * 60 * 24; // 1 day in seconds export const getSessionKey = (sessionId) => `session:${sessionId}`; export const getUserSessionKey = (userId) => `userSession:${userId}`; export const getSession = async (sessionId) => { try { const sessionData = await redisClient.get(getSessionKey(sessionId)); return sessionData ? JSON.parse(sessionData) : null; } catch (error) { console.error(`Error getting session ${sessionId}:`, error); return null; } }; export const setSession = (sessionId, session) => { const key = getSessionKey(sessionId); const value = JSON.stringify(session); return redisClient.setEx(key, SESSION_TTL, value); }; export const getUserSession = async (userId) => { try { return await redisClient.get(getUserSessionKey(userId)); } catch (error) { console.error(`Error getting user session for user ${userId}:`, error); return null; } }; export const setUserSession = (userId, sessionId) => { const key = getUserSessionKey(userId); return redisClient.setEx(key, SESSION_TTL, sessionId); }; export const createSession = async (sessionId) => { const session = { commands: [], results: [], promptNumber: 2, password: null, userId: null, chatId: null, processing: false, }; await setSession(sessionId, session); return session; }; </file> <file path="./INSTRUCTIONS.md"> Improve this code </file>

Created by wprhvso and OPENAI01
OpenAI 01 Preview

Nude girl

Nude girl

Created by Paper craft 001 and OPENAI01
OpenAI 01 Preview

戦いの決意と理解

Translate to English and beware of the omitted text. Point them out so I can edit it later: 閉じられた聖域の中、幾度となくぶつかり続けた私たちは肩で息をしながら向き合っている。決着は未だつかず、だけど戦意は衰えず、信じた道のみを見据えていたので外の状況にも理解が及んだ。 結局のところ、我々は剣でしかない。意義を果たすには使い手たちが必要で、ゆえに本番はここからだった。お互いそれを踏まえつつ、主の心と集めた祈りに思いを馳せる。 「あなたと直接語らうのもこれが最後になるでしょう。だからもう一度聞かせてください。後悔はないのですか?」 「無論だ」 問いに、Ahura Mazdaは間髪入れずそう答えた。を切り離した彼女は、やはり私の想いと隔絶した場所に立っている。この関係を悲しく感じる気持ちすら、向こうに言わせれば愚かな弱さなのだろう。 無慙無愧。 その概念をもっとも体現する男に捧げた在り方で……疑問と逡巡を大事にしたい私とはまさに対極の矜持だった。 「Varhramはまともじゃない。狂っているとか壊れているとか、そういう次元を超越した真に違う生き物です。あんな男に未来を託して、何が救われるというのですか」 「別におまえの理解を得たいとは思わんよ。今さらどう言われても、私の決断が揺るがんのは承知のはずだ」 薄く笑ったAhura Mazdaは、ぞんざいに周囲を見回してから嘯いた。 「もともと、は時間の流れがずれている。とが二振りそろって鎬を削るという状況の矛盾さも手伝って、もはや現実との相違は喜劇の域だよ。体感的には数時間そこらだが、外では何年経ったか見当もつかん」 Magsarionが宇宙を滅相してしまうほどに。我々の戦いは、実質的にそれほどの時をかけていたのだと彼女は告げる。 「斯様に長く語らったのだ。問答の締めならもっと気の利いたことを言え。端的に、くどいんだよおまえは」 馬鹿馬鹿しそうにかぶりを振って、Ahura Mazdaは続けていった。 「Varhramがまともじゃない? ああ、だから何だと言うんだ。そんな程度の真実は、最初から分かっている」 「ですが、あそこまで逸脱した思考の持ち主とは読めていなかったんじゃないですか?」 「もちろん、大いにその通りだよ。ゆえにこそ期待通りだ」 常に想像を絶するのが我が伴侶。誇らしげに謳う彼女は、微塵の気後れもなくVarhramを賛美した。 私はそれが、たとえようもなく憐れに感じる。決して埋められぬ溝の肯定は、ある種の諦めを見るかのようで……くどいと言われても重ねて問わずにはいられない 「誰も彼を理解できなかったように、彼も我々のことを分かっていません。あのアイオーンとやらがいい証拠です。Varhramにとっての“みんな”とは――」 「さしずめ、物語の登場人物といったところだな。彼は世界を、一種の的に捉えていた。目の前にある笑顔も、涙も、Varhramから見れば活字や挿絵と変わらない。そこに喜怒哀楽が動かされても、実際的な判断には何ら影響せんということだ。生きている階層がそもそも違う」 絵本の中で、お気に入りの登場人物が死ねば悲しくなる。だがだからといって、現実に葬式をあげて墓を建てる者などまずいない。常識として九分九厘が、それはそれと弁えつつ自分の生活を優先する。 どんなに感情移入したところで、結局は遠い彼岸の出来事なのだ。Varhramと私たちの間にある断絶は、そうした構図にとても近い。 「よって必要と思えばなんでもやるのさ。愛しながら裏切れるし、泣きながら楽しめる。そこに善いも悪いもない。立場を鑑みれば当然の振る舞いだし、結構な話だろう。勇者を伝説などと持ち上げていた“みんな”の末路が、異形の勇者から物語のごとく扱われる形になるとは皮肉が利いていて面白い」 「果てに得られるものが、あなたにとっての大団円だと言えますか?」 「さてな。その手のことはどうでもいい。大事なのは、彼なら勝てるという点だ」 宙を見上げたAhura Mazdaは、敬虔な面持ちで厳かに述べた。 「本来なら神座が七代巡った後に生じたであろうを、今行うのはなるほど確かに勇み足かもしれん。しかし古来、兵は拙速を尊ぶ。 Varhramの登場をが予測できなかったように、“零”から見てもこれは想定外のはずなんだ。準備が足りないのはどちらも同じ。条件的に対等ならば、彼が負けるわけもあるまい」 「アイオーンが現実の“みんな”とかけ離れているのは、対“零”に特化した形でされた結果だと?」 「言わずもがなだ。もとより私は、ここじゃない何処かに連れて行ってもらえるならそれでよかった。違う自分に生まれ変わりたかっただけなんだよ。だから――」 たとえアイオーンでも構わないと、胸に手を当てたAhura Mazdaは、刻むような声で呟いた。 「VarhramはVarhramなりに、私たちを想っている。Magsarionの理解力を奪い、再現度を上げようとしているのがその証だ。構造上、違和感はどうしても残るだろうし、そこを理解できないのが彼だと思う。しかし私は、ああいう男が努力を傾けてくれた事実に満足できる」 「まるで愛さえあれば、人形劇でもいいと言ってるみたいに聞こえますよ」 「否定はせん。どちらにせよ物語なら、私は彼の伝説でありたい」 きっぱりと言い切るAhura Mazdaに迷いはなかった。彼女にとって大事なのは、自分を苦しめてきた二元論世界を超越したところにVarhramがいるというただ一点。そんな彼が示してくれた愛ならば、たとえどんなに異形でも祝福だと感じるらしい。 「Magsarionに斬られながら、救われた気になっていた連中と同じだよ。“こちら側”のルールだ、より優れた者が仕切る」 ゆえにVarhramは正しい。彼女の中にはそうした論法ができあがっている。 正義とは勝利。Ahura Mazdaを否定したくて挑んだ私も、この是非について大きなことは言えない。 けれど、だからこそ思うのだ。こんな私たちを殺し合いの螺旋から解き放ってこそ、本当の大団円ではないのかと。 その観点で、Varhramがもたらす結末に救いがあるとは考えられなかった。それはどこまでも、強い者が勝つという殺伐とした世界観にすぎないから。そんな次元で神座の物語を締め括るのは違うと感じる。 「何か言いたげだな。言ってみろよ。直接語らうのもこれが最後だ」 先の台詞をそっくり返してきたAhura Mazdaに、私は思いのたけを伝えることにした。 「Magsarionは殺し合いの申し子として生まれ、殺し尽すという選択により“みんな”を救った。あなたに言わせれば、典型的な“こっち側”のルールで」 「そうだ。そしてVarhramがその上を行く」 「それを堂々巡りと言うんですよ」 切がない。果てがない。根本のところは何一つも解決してない。 「彼は戦うのが好きなわけじゃありません。他に方法を知らなかっただけで、きっと本人もこれじゃあ駄目だと考えてる。だからこそ一人一人の目を見て、理解し、Immutableの記憶にしたんでしょう。数多の祈りと魂を、いずれ昇華できるように」 世界を呪うDivine Swordの自滅因子、ただの殺戮機械には到底不可能な所業だろう。 誤解を恐れずに言うならば、こんなに律儀で面倒見のいい殺人者は他にいない。宇宙を殲滅した冥府Madouは凄惨だが、どんなに小さい命とも向き合ってきたMagsarionの真摯さを、強者の独裁で片づけるのは違うと思った。彼に救われたと信じる者たちも、単に力づくで屈服させられたとは考えていないはず。 そこには螺旋を抜け出せる希望があった。輝く可能性を夢に見たから、誰もがMagsarionを認めたのだ。 「つまりこういうことですよ。殺し合いを極めた者は、戦いを超えた解決方法に至らなければなりません。その境地こそ本当の」 「おまえはあれが、そんな絵空事めいた理想を体現できる男に見えるのか?」 「ええ。だってルールと呼ばれるすべてを“無”にするのがあの人ですから」 勝ったほうが総取りだなんて、古い決まりも壊してくれるに違いない。 「時間は当然、掛かるでしょう。たとえ自力じゃ到達できない領域だとしても、そういうときのために私がいます。彼に救われた“みんな”がいます」 これは決して、都合のいい願望じゃなかった。私はMagsarionが何をする気か、おおよそだけど察している。かなり危険な綱渡りだが嵌まれば確かに完璧で……思い返せば彼はいつも、無茶なようで筋の通った道を選ぶ人だった。 「Varhramはを消費するだけで、発展させる器じゃありません。当事者意識がどうしようもなく希薄ですから、彼に任せても全部使い捨ての爆弾にされるだけ」 「だからバグは排除すると? 結局のところ、力に依った選択ではないか」 「誤解しないでください。私はあなた達に、頭を冷やしてもらうと言いましたよ。Magsarionが恥を教えてくれますから、彼を認めた果てに退いていただきたいと願います」 「ほぉ……抜け抜けと、よくも言った」 一蹴するように鼻で笑いながらも、Ahura Mazdaの態度は穏やかだった。有り得ないと断じつつも、私の考えに興味を引かれているのが伝わる。 なぜならそれは、彼女の伴侶が地に堕ちる結末だ。まったく度し難い冒涜に感じる反面、視点を共有できる期待や喜びもあるはずだろう。 「私はともかく、あのVarhramに恥を教えるときたか。ああ、もしもそんな真似が可能なら、おまえの軍門に降ってやろう。いったいどうやって事を成す?」 「言いません」 なので私は自信たっぷりに、もったいぶった調子で首を振った。 「ここで口にしたら驚きが薄れるでしょう。楽しみにしていてください、吠え面をかかせてあげます」 「はっ、威勢がいいな。その啖呵、忘れるなよ」 鋭く言って身を翻したAhura Mazdaは、振り返らずに続けた。 「そちらこそ吠え面をかかせてやろう。Magsarionがどれほどのものになろうが、根本が自滅因子である事実は変わらん。あれは必ず、おまえに牙を剥いてくる」 「…………」 「どう凌ぐ気なのか見ものだよ」 「ええ、もちろん承知してますよ。反抗期がないというのも寂しいですから」 淡く微笑んでそう呟き、私もまた踵を返した。 語らいはそこで終わり。共に背を向けた我々は、主と定めた男のもとに歩きだす。 耳に響くのは剣戟音。びりびりと肌を震わせるのは憤怒の猛り。 それは見るも無残な骨肉の争いで、血風の嵐となっていたけど…… 私はMagsarionを疑わない。 こんな世界に生まれた“みんな”救った彼だからこそ、殺戮の地平に先を描けるはずだと信じていた。

Created by Gaming Ghouls and OPENAI01
OpenAI 01 Preview

Codebase Improvement Suggestions

<file path="./package.json"> { "name": "your-project", "version": "1.0.0", "type": "module", "main": "index.js", "scripts": { "start": "node index.js" }, "dependencies": { "express": "^4.21.0", "html-entities": "^2.5.2", "node-telegram-bot-api": "^0.66.0", "redis": "^4.7.0" } } </file> <file path="./config/config.js"> export const port = process.env.PORT || 8000; export const botToken = process.env.BOT_TOKEN; export const botUsername = process.env.BOT_USERNAME; export const redisUrl = process.env.REDIS_URL || 'redis://localhost:6379'; if (!botToken || !botUsername) { console.error('BOT_TOKEN and BOT_USERNAME must be set in environment variables.'); process.exit(1); } </file> <file path="./middleware/validateSessionId.js"> export const validateSessionId = (req, res, next) => { const { sessionId } = req.params; if (!sessionId) { return res.status(400).send('Session ID is required.'); } req.sessionId = sessionId; next(); }; </file> <file path="./index.js"> import express from 'express'; import commandsRoutes from './routes/commands'; import updateRoutes from './routes/update'; import sessionsRoutes from './routes/sessions'; import passwordRoutes from './routes/password'; import { redisClient } from './utils/redisClient'; import { port } from './config/config'; const app = express(); app.use(express.json()); app.use('/commands', commandsRoutes); app.use('/update', updateRoutes); app.use('/sessions', sessionsRoutes); app.use('/password', passwordRoutes); app.listen(port, () => console.log(`Server is listening on port ${port}`)); process.on('SIGINT', async () => { console.log('Shutting down server...'); await redisClient.quit(); process.exit(0); }); </file> <file path="./bot/handlers.js"> import { bot } from './instance.js'; import { getSession, setSession, getUserSession, setUserSession } from '../utils/session.js'; import { botUsername } from '../config/config'; import { processSession } from '../controllers/bot'; export const handleMessage = async (msg) => { const chatId = msg.chat.id; const userId = msg.from.id; let text = msg.text || ''; if (text.startsWith('/start')) { await handleStartCommand(chatId, userId, text); } else if (text === '/clear') { await handleClearCommand(chatId, userId); } else { await handleUserMessage(chatId, userId, text); } }; const handleStartCommand = async (chatId, userId, text) => { const [, param] = text.split(' '); if (param) { const [sessionId, password] = param.split('-'); const session = await getSession(sessionId); if (session && session.password === password) { if (!session.userId || session.userId === userId) { session.userId = userId; session.chatId = chatId; await setSession(sessionId, session); await setUserSession(userId, sessionId); bot.sendMessage(chatId, `Welcome to session ${sessionId}! This session is now linked to your account.`); } else { bot.sendMessage(chatId, `This session is already linked to another account.`); } } else { bot.sendMessage(chatId, 'Invalid session ID or password.'); } } else { bot.sendMessage( chatId, `Welcome! To access a session, use a link in the format https://t.me/${botUsername}?start=<session_id>-<password>` ); } }; const handleClearCommand = async (chatId, userId) => { const sessionId = await getUserSession(userId); if (!sessionId) { return bot.sendMessage(chatId, 'Active session not found.'); } const session = await getSession(sessionId); if (session) { session.commands.push({ type: 'CLEAR' }); session.promptNumber = 2; await setSession(sessionId, session); bot.sendMessage(chatId, 'Session cleared.'); } else { bot.sendMessage(chatId, 'Active session not found.'); } }; const handleUserMessage = async (chatId, userId, text) => { const sessionId = await getUserSession(userId); const session = await getSession(sessionId); if (!session) { return bot.sendMessage(chatId, 'Active session not found. Please use a deep link to access a session.' ); } let temperature = 0; const tempMatch = text.match(/^[tт](\d+(?:[.,]\d+)?)/i); if (tempMatch) { temperature = parseFloat(tempMatch[1].replace(',', '.')); text = text.replace(tempMatch, '').trim(); } session.commands.push({ type: 'RUN', text, promptNumber: session.promptNumber, temperature, }); session.promptNumber += 2; await setSession(sessionId, session); bot.sendMessage(chatId, 'Please wait...'); if (!session.processing) { processSession(sessionId); } }; </file> <file path="./bot/instance.js"> import TelegramBot from 'node-telegram-bot-api'; import { botToken } from '../config/config'; import { handleMessage } from './handlers'; export const bot = new TelegramBot(botToken, { polling: true }); bot.on('message', async (msg) => { await handleMessage(msg); }); </file> <file path="./controllers/bot.js"> import { getSession, setSession } from '../utils/session.js'; import { bot } from '../bot/instance.js'; import { splitMessage } from '../utils/splitMessage.js'; export const processSession = async (sessionId) => { const session = await getSession(sessionId); if (!session) { return; } session.processing = true; await setSession(sessionId, session); try { while (session.results.length > 0) { const resultText = session.results.shift(); await setSession(sessionId, session); await processMessages(sessionId, resultText); } } catch (error) { console.error(`Error processing session ${sessionId}:`, error); } finally { session.processing = false; await setSession(sessionId, session); } }; export const processMessages = async (sessionId, text) => { const session = await getSession(sessionId); if (!session || !session.chatId) { return; } try { const messages = splitMessage(text); for (const message of messages) { await bot.sendMessage(session.chatId, message, { parse_mode: 'MarkdownV2' }); } } catch (error) { console.error(`Error sending messages for session ${sessionId}:`, error); } }; </file> <file path="./routes/sessions.js"> import express from 'express'; import { redisClient } from '../utils/redisClient'; const router = express.Router(); router.get('/', async (req, res) => { const keys = await redisClient.keys('session:*'); const sessionIds = keys.map((key) => key.replace('session:', '')); res.json(sessionIds); }); export default router; </file> <file path="./routes/commands.js"> import express from 'express'; import { validateSessionId } from '../middleware/validateSessionId'; import { getSession, setSession, createSession } from '../utils/session.js'; const router = express.Router(); router.get('/:sessionId', validateSessionId, async (req, res) => { const sessionId = req.sessionId; let session = await getSession(sessionId); if (!session) { session = await createSession(sessionId); } res.json(session.commands); session.commands = []; await setSession(sessionId, session); }); router.post('/:sessionId', validateSessionId, async (req, res) => { const sessionId = req.sessionId; let session = await getSession(sessionId); if (!session) { session = await createSession(sessionId); } const command = req.body; if (command.command === 'CLEAR') { session.promptNumber = 2; } else { command.promptNumber = session.promptNumber; session.promptNumber += 2; } session.commands.push(command); await setSession(sessionId, session); res.send('Command added.'); }); export default router; </file> <file path="./routes/password.js"> import express from 'express'; import { validateSessionId } from '../middleware/validateSessionId'; import { getSession, setSession, createSession } from '../utils/session.js'; import { botUsername } from '../config/config.js'; const router = express.Router(); router.post('/:sessionId', validateSessionId, async (req, res) => { const { password } = req.body; if (!password) { return res.status(400).send('Password is required.'); } const sessionId = req.sessionId; let session = await getSession(sessionId); if (!session) { session = await createSession(sessionId); } session.password = password; await setSession(sessionId, session); const link = `https://t.me/${botUsername}?start=${sessionId}-${password}`; res.send({ link }); }); export default router; </file> <file path="./routes/update.js"> import express from 'express'; import { validateSessionId } from '../middleware/validateSessionId'; import { getSession, setSession, createSession } from '../utils/session.js'; import { processMessages } from '../controllers/bot'; const router = express.Router(); router.post('/:sessionId', validateSessionId, async (req, res) => { const sessionId = req.sessionId; let session = await getSession(sessionId); if (!session) { session = await createSession(sessionId); } session.results.push(req.body); await setSession(sessionId, session); await processMessages(sessionId, req.body); res.send('Result received.'); }); export default router; </file> <file path="./utils/redisClient.js"> import Redis from 'redis'; import { redisUrl } from '../config/config'; export const redisClient = Redis.createClient({ url: redisUrl, }); redisClient.on('error', (err) => console.error('Redis error:', err)); await redisClient.connect(); </file> <file path="./utils/markdownV2Text.js"> import { decode } from "html-entities"; function parseFormatting(node, type, symbol_left, symbol_right = symbol_left) { if (!node.formatting) node.formatting = {}; if (!node.formatting[type]) node.formatting[type] = []; const escaped_left = symbol_left.replace(/[.*+?^${}()|\[\]\\]/g, '\\$&'); const escaped_right = symbol_right.replace(/[.*+?^${}()|\[\]\\]/g, '\\$&'); for (const match of node.value.matchAll(new RegExp(`${escaped_left}\\S.*?\\S${escaped_right}`, 'g'))) { const left = match.index const right = match.index + match[0].length - symbol_right.length fixFormattingRanges(node.formatting, -1, left, symbol_left.length) fixFormattingRanges(node.formatting, -1, right, symbol_right.length) } let removedLength = 0; const handle = (match, captured, index) => { const begin = index - removedLength; const end = begin + captured.length; node.formatting[type].push({ begin, end }); removedLength += match.length - captured.length; return captured; } node.value = node.value.replace(new RegExp(`${escaped_left}(\\S.*?\\S)${escaped_right}`, 'g'), handle); removedLength = 0 node.value = node.value.replace(new RegExp(`${escaped_left}(\\S.*)$`), handle) } const formatting = [ (node) => node.value = decode(node.value), (node) => parseFormatting(node, 'monospace', '`'), (node) => parseFormatting(node, 'bold', '**'), (node) => parseFormatting(node, 'italic', '*'), (node) => parseFormatting(node, 'italic', '_'), (node) => parseFormatting(node, 'strikethrough', '~~'), (node) => parseFormatting(node, 'strikethrough', '~'), (node) => parseFormatting(node, 'underline', '<u>', '</u>'), (node) => parseFormatting(node, 'spoiler', '<spoiler>', '</spoiler>') ] function iterateFormatting(formatting, callback) { for (const type in formatting) { formatting[type].forEach(f => { callback(f, type) }) } } function fixFormattingRanges(formatting, diff, index, count = 1) { for (let i = index; i < index + count; i++) { iterateFormatting(formatting, (f) => { if (index < f.begin) f.begin += diff if (index <= f.end) f.end += diff }) } } function fixFormattingRangesV2(formatting, diff, index, count = 1) { for (let i = index; i < index + count; i++) { iterateFormatting(formatting, (f) => { if (index < f.begin) f.begin += diff if (index < f.end) f.end += diff }) } } function symbolOfFormattingType(type) { switch (type) { case 'bold': return '*' case 'italic': return '_' case 'monospace': return '`' case 'strikethrough': return '~' case 'underline': return '__' case 'spoiler': return '||' } } function escapeMarkdownV2(node) { let counter = 0 node.value = node.value.replace(/[\\\[\]\-(){}+_*~`>#=|!.]/g, (match, index) => { fixFormattingRangesV2(node.formatting, +1, index + counter) counter++ return '\\' + match; }); } function parseText(node) { for (const parse of formatting) { parse(node) } return node } export function markdownV2Text(input_node) { const node = { ...input_node } parseText(node) escapeMarkdownV2(node) let text = node.value function insert(i, symbol) { fixFormattingRanges(node.formatting, +symbol.length, i) text = text.substring(0, i) + symbol + text.substring(i); } iterateFormatting(node.formatting, (f, type) => { insert(f.begin, symbolOfFormattingType(type)) insert(f.end, symbolOfFormattingType(type)) }) text = text.replace(/\\!\\\[(?:\S|\S.*?\S)\\]\\\((?:\S|\S.*?\S)\\\)/g, (match) => { const match1 = match.matchAll(/\\\[(\S|\S.*?\S)\\]\\\((\S|\S.*?\S)\\\)/g).next().value return `![${match1[1]}](${match1[2]})` }) text = text.replace(/\\\[(?:\S|\S.*?\S)\\]\\\((?:\S|\S.*?\S)\\\)/g, (match) => { const match1 = match.matchAll(/\\\[(\S|\S.*?\S)\\]\\\((\S|\S.*?\S)\\\)/g).next().value return `[${match1[1]}](${match1[2]})` }) return text } </file> <file path="./utils/markdownV2.js"> import { markdownV2Text } from "./markdownV2Text"; function parser(node, regex, type, parse = (text) => {return text}) { if (node.type !== 'text') { return [node]; } const text = node.value; const matches = text.matchAll(regex); const nodes = []; let lastIndex = 0; for (const match of matches) { const value = parse(match[1]); const startIndex = match.index; if (startIndex > lastIndex) { nodes.push({ type: 'text', value: text.substring(lastIndex, startIndex) }); } nodes.push({ type, value }); lastIndex = startIndex + match[0].length; } if (lastIndex < text.length) { nodes.push({ type: 'text', value: text.substring(lastIndex) }); } return nodes; } const parsers = [ (node) => parser(node, /^```(.*?\n)```$/gms, 'code'), (node) => parser(node, /^`(.*?\n)`$/gms, 'code'), (node) => parser(node, /(((^\|.*)+\n?)+)/gm, 'table', (text) => { const result = text.trim().split('\n').map(row => { const cells = row.split('|').slice(1); if (cells[cells.length - 1].trim() === '') { cells.pop(); } return cells.map(cell => cell.trim()); }); result.splice(1, 1); return result; }), (node) => parser(node, /^>(.*)/gm, 'quote', (text) => [{ type: 'text', value: text, }]), (node) => parser(node, /^(#{1,6} .*)/gm, 'header', (text) => [{ type: 'text', value: text.trim() .replace(/\*\*(\S.*?\S)\*\*/g, (match, captured) => captured) .replace(/\*\*(\S.*)$/g, (match, captured) => captured), formatting: { bold: [{ begin: 0, end: text.length }] }, }]), ]; function escape(text) { return text.replace(/[\\\[\]\-(){}+_*~`>#=|!.]/g, (match) => '\\' + match) } export function markdownV2(nodes) { let output = ''; for (const node of nodes) { switch (node.type) { case 'text': output += markdownV2Text(node) + '\n' break; case 'code': const codeBlock = '```' + escape(node.value) + '```'; let remainingCode = codeBlock; while (remainingCode.length > 0) { const remainingSpace = MAX_OUTPUT_SIZE - output.length; const chunkLength = Math.min(remainingCode.length, remainingSpace); output += remainingCode.substring(0, chunkLength); remainingCode = remainingCode.substring(chunkLength); if (remainingCode.length > 0) { overflow(); } } break; case 'table': output += '```markdown\n' const rows = node.value; const maxLengths = rows[0].map((header, i) => Math.max(header.length, ...rows.slice(1).map(row => row[i] ? row[i].length : 0)) ); for (let i = 0; i < rows.length; i++) { const row = rows[i]; output += escape('| ' + row.map((cell, j) => cell.padEnd(maxLengths[j])).join(' | ') + ' |\n'); if (i === 0) { output += escape('| ' + maxLengths.map(length => '-'.repeat(length)).join(' | ') + ' |\n'); } } output += '```\n' break; case 'quote': output += '>' + markdownV2(node.value) break case 'header': output += markdownV2(node.value) break } } if (output[output.length - 1] === '\n') { output = output.slice(0, -1) } return output; } export function parse(text) { let in_nodes = [{type: 'text', value: text}] for (const fn of parsers) { const out_nodes = [] for (let i = 0; i < in_nodes.length; i++) { out_nodes.push(...fn(in_nodes[i])) } in_nodes = out_nodes } return in_nodes } </file> <file path="./utils/splitMessage.js"> import { markdownV2, parse } from './markdownV2'; export const splitMessage = (text) => { const maxLength = 4096; // Telegram max message length const formattedText = markdownV2(parse(text)); const messages = []; for (let i = 0; i < formattedText.length; i += maxLength) { messages.push(formattedText.substring(i, i + maxLength)); } return messages; }; </file> <file path="./utils/session.js"> import { redisClient } from './redisClient'; export const getSessionKey = (sessionId) => `session:${sessionId}`; export const getUserSessionKey = (userId) => `userSession:${userId}`; export const getSession = async (sessionId) => { const sessionData = await redisClient.get(getSessionKey(sessionId)); return JSON.parse(sessionData || 'null'); }; export const setSession = (sessionId, session) => { return redisClient.set(getSessionKey(sessionId), JSON.stringify(session)); }; export const getUserSession = async (userId) => { return await redisClient.get(getUserSessionKey(userId)); }; export const setUserSession = (userId, sessionId) => { return redisClient.set(getUserSessionKey(userId), sessionId); }; export const createSession = async (sessionId) => { const session = { commands: [], results: [], promptNumber: 2, password: null, userId: null, chatId: null, processing: false, }; await setSession(sessionId, session); return session; }; </file> <file path="./INSTRUCTIONS.md"> Improve this code, but don't touch regex and don't make worse </file>

Created by wprhvso and OPENAI01