The renderMessages(req, res)
function is responsible for rendering a set of messages for a specific conversation based on user query parameters, by parsing dates, loading conversation files, filtering messages, and rendering them in a formatted format. It utilizes Markdown rendering with the remarkable
library to format AI-generated messages, and limits the number of rendered messages to 25.
npm run import -- "render message history"
const path = require('path')
const fs = require('fs')
const {Remarkable} = require('remarkable');
const md = new Remarkable({html: true, xhtmlOut: true, breaks: true});
const {ACTIVE_CONVERSATIONS, PROJECT_PATH, DEFAULT_MODEL} = importer.import("general chit chat")
function renderMessages(req, res) {
let now = new Date()
let when = now
if(req.query.when) {
when = new Date(parseInt(req.query.when))
}
let from = new Date(0)
if(req.query.from) {
from = new Date(parseInt(req.query.from))
}
//console.log(when.getTime(), from.getTime())
if(!req.query.session) {
return res.send(importer.interpret('resume chat program').code)
}
let convoFile = path.join(PROJECT_PATH, now.getFullYear() + '-'
+ String(now.getMonth() + 1).padStart(2, '0')
+ '-' + DEFAULT_MODEL
+ '-' + req.query.session + '.json')
// TODO: reload chat
if(typeof ACTIVE_CONVERSATIONS[convoFile] == 'undefined') {
if(fs.existsSync(convoFile)) {
ACTIVE_CONVERSATIONS[convoFile] = JSON.parse(fs.readFileSync(convoFile))
} else {
ACTIVE_CONVERSATIONS[convoFile] = {}
}
}
let messageTimes = Object.keys(ACTIVE_CONVERSATIONS[convoFile]).filter(k => k != 'summaries' && k != 'memories')
messageTimes.sort((a, b) => b - a)
let compareWhen = when.getTime()
let compareFrom = from.getTime()
let count = 0
let messages = ''
for(let i = 0; i < messageTimes.length && count < 25; i++) {
if(parseInt(messageTimes[i]) > compareWhen || parseInt(messageTimes[i]) < compareFrom) {
continue
}
let message = ACTIVE_CONVERSATIONS[convoFile][messageTimes[i]]
// load messages in reverse order because the are sorted from recent to oldest
if(typeof message.content != 'undefined') {
if(message.user) {
messages = '<div id="id-' + messageTimes[i] + '" class="user"><p>User: ' + message.content + '</p></div>\n' + messages
} else {
const mdHtml = md.render(message.content);
messages = '<div id="id-' + messageTimes[i] + '" class="ai">AI: ' + mdHtml + '</div>\n' + messages
}
} else {
if(message.user) {
messages = '<div id="id-' + messageTimes[i] + '" class="user"><p>User: Content off the record</p></div>\n' + messages
} else {
messages = '<div id="id-' + messageTimes[i] + '" class="ai">AI: Content off the record</div>\n' + messages
}
}
count++
}
return res.send(importer.interpret('resume chat program').code
.replace('<div id="messages">', '<div id="messages">' + messages))
}
module.exports = renderMessages
const path = require('path');
const fs = require('fs');
const { Remarkable } = require('remarkable');
const md = new Remarkable({ html: true, xhtmlOut: true, breaks: true });
const { ACTIVE_CONVERSATIONS, PROJECT_PATH, DEFAULT_MODEL } = importer.import('general chit chat');
const generateConversationFilePath = (now) => {
const date = now.toISOString().split('T')[0];
return path.join(PROJECT_PATH, `${date}-${DEFAULT_MODEL}-` + importer.interpret('session id').code + '.json');
};
const getConversation = (convoFile) => {
if (!fs.existsSync(convoFile)) {
return {};
}
const conversation = JSON.parse(fs.readFileSync(convoFile));
if (!ACTIVE_CONVERSATIONS[convoFile]) {
ACTIVE_CONVERSATIONS[convoFile] = conversation;
}
return conversation;
};
const createMessageElement = (message) => {
const user = message.user? `User: ` : '';
const content = message.user? message.content : `Content off the record`;
const mdHtml = message.user? content : md.render(message.content);
return ` `;
};
const renderMessages = (req, res) => {
const now = new Date();
const when = req.query.when? new Date(parseInt(req.query.when)) : now;
const from = req.query.from? new Date(parseInt(req.query.from)) : new Date(0);
if (!req.query.session) {
return res.send(importer.interpret('resume chat program').code);
}
const convoFile = generateConversationFilePath(now);
const conversation = getConversation(convoFile);
const messageTimes = Object.keys(conversation).filter((k) => k!=='summaries' && k!=='memories').sort((a, b) => b - a);
const compareWhen = when.getTime();
const compareFrom = from.getTime();
let count = 0;
let messages = '';
for (const time of messageTimes) {
if (parseInt(time) > compareWhen || parseInt(time) < compareFrom) {
continue;
}
const message = conversation[time];
if (message.content!== undefined) {
messages = createMessageElement(message) + messages;
count++;
}
if (count >= 25) {
break;
}
}
return res.send(importer.interpret('resume chat program').code.replace('', '' + messages));
};
module.exports = renderMessages;Function Breakdown: renderMessages(req, res)
Overview
The renderMessages(req, res)
function is responsible for rendering a set of messages for a specific conversation based on user query parameters.
Parameters
req
: HTTP request object
res
: HTTP response object
Logic
- Date parsing:
- Extracts
when
and from
dates from query parameters using parseInt()
.
- Falls back to current date if
when
or from
parameters are missing.
- Conversation file generation:
- Creates a conversation file path using the current date, session ID, and default model.
- Conversation loading:
- Checks if the conversation file exists and loads its contents into
ACTIVE_CONVERSATIONS
object.
- Initializes an empty conversation file if it doesn't exist.
- Message filtering:
- Extracts message timestamps from the conversation object.
- Filters out timestamps that are earlier than
from
or later than when
.
- Message rendering:
- Iterates through the filtered message timestamps and extracts message contents.
- Renders messages in the format
<div>AI/User: Message content</div>
.
- Returns the rendered messages in the response object.
Notes
- The function uses Markdown rendering with
remarkable
library to format AI-generated messages.
- The
count
variable is used to limit the number of messages rendered to 25.
- The
messages
variable is built incrementally using string concatenation.