Add support for message history pagination, preserve scroll in rendering, and improve draft/message workflows.
This commit is contained in:
+53
-5
@@ -217,10 +217,39 @@ export function createChatsRouter({repositories, chatService, modelService, conf
|
||||
const chatId = Number(req.params.id);
|
||||
const chat = repositories.getChat(chatId, req.session.user);
|
||||
if (!chat) return res.status(404).json({error: "Chat not found"});
|
||||
return res.json({
|
||||
messages: chatService.listActiveBranchMessages(chatId),
|
||||
chat
|
||||
});
|
||||
const options = {};
|
||||
for (const key of ["limit", "before", "leaf", "around"]) {
|
||||
if (req.query[key] === undefined) continue;
|
||||
const value = Number(req.query[key]);
|
||||
if (!Number.isSafeInteger(value) || value < 1 || (key === "limit" && value > 100)) {
|
||||
return res.status(400).json({error: `Invalid history ${key}`});
|
||||
}
|
||||
options[key] = value;
|
||||
}
|
||||
const result = chatService.getHistoryPage(chatId, options);
|
||||
if (result.error) return res.status(result.status).json(result);
|
||||
return res.json({...result, chat});
|
||||
});
|
||||
|
||||
router.get("/chats/:id/branches", (req, res) => {
|
||||
const chatId = Number(req.params.id);
|
||||
const chat = repositories.getChat(chatId, req.session.user);
|
||||
if (!chat) return res.status(404).json({error: "Chat not found"});
|
||||
const after = Number(req.query.after || 0);
|
||||
if (!Number.isSafeInteger(after) || after < 0) return res.status(400).json({error: "Invalid branch cursor"});
|
||||
const nodes = repositories.listBranchNodes(chatId, {after});
|
||||
const hasMore = nodes.length > 200;
|
||||
if (hasMore) nodes.pop();
|
||||
return res.json({nodes, activeLeafId: chat.active_leaf_message_id || nodes.at(-1)?.id || null,
|
||||
next: hasMore ? nodes.at(-1).id : null});
|
||||
});
|
||||
|
||||
router.get("/chats/:id/messages/:messageId/versions", (req, res) => {
|
||||
const chatId = Number(req.params.id);
|
||||
if (!repositories.getChat(chatId, req.session.user)) return res.status(404).json({error: "Chat not found"});
|
||||
const message = repositories.getChatMessage(chatId, Number(req.params.messageId));
|
||||
if (!message) return res.status(404).json({error: "Message not found"});
|
||||
return res.json({message: chatService.formatChatMessage(message)});
|
||||
});
|
||||
|
||||
router.put("/chats/:id/generation-settings", validateBody(generationSettingsValidator), (req, res) => {
|
||||
@@ -406,7 +435,26 @@ export function createChatsRouter({repositories, chatService, modelService, conf
|
||||
const chatId = Number(req.params.id);
|
||||
const chat = repositories.getChat(chatId, req.session.user);
|
||||
if (!chat) return res.status(404).json({error: "Chat not found"});
|
||||
return res.json({memories: repositories.listChatMemories(chatId, req.session.user)});
|
||||
const payload = chatService.buildMessagesPayload({user: req.session.user, chatId, session: chat});
|
||||
const characters = payload.messagesPayload.reduce((total, message) => total + String(message.content || "").length, 0);
|
||||
return res.json({memories: repositories.listChatMemories(chatId, req.session.user), summary: chat.context_summary || "",
|
||||
summaryMessageId: chat.context_summary_message_id || 0, summaryMaxChars: config.chatSummaryMaxChars,
|
||||
context: {estimatedTokens: Math.ceil(characters / 4), contextLength: chat.context_length || null,
|
||||
recentMessageLimit: config.chatHistoryLimit, memoryFactLimit: 30}});
|
||||
});
|
||||
|
||||
router.put("/chats/:id/summary", (req, res) => {
|
||||
const chatId = Number(req.params.id);
|
||||
const chat = repositories.getChat(chatId, req.session.user);
|
||||
if (!chat) return res.status(404).json({error: "Chat not found"});
|
||||
if (chatService.isGenerating(chatId)) return res.status(409).json({error: "Wait for the response to finish before editing its summary."});
|
||||
const summary = req.body?.summary;
|
||||
if (typeof summary !== "string" || summary.length > config.chatSummaryMaxChars) {
|
||||
return res.status(400).json({error: `Summary must be text of at most ${config.chatSummaryMaxChars} characters.`});
|
||||
}
|
||||
if (req.body.previousSummary !== (chat.context_summary || "")) return res.status(409).json({error: "The summary changed. Reopen memory to review it before saving."});
|
||||
repositories.updateChatContextSummary(chatId, req.session.user, summary.trim() || null, chat.context_summary_message_id);
|
||||
return res.json({summary: summary.trim()});
|
||||
});
|
||||
|
||||
router.post("/chats/:id/memories", validateBody(memoryValidator), (req, res) => {
|
||||
|
||||
Reference in New Issue
Block a user