Enable automatic web search by default; improve toggle behavior and search planning.
CI / check (22) (push) Successful in 9m35s
CI / check (24) (push) Successful in 9m34s

This commit is contained in:
2026-10-06 08:50:03 +02:00
parent 674abf78f6
commit 7be654af11
17 changed files with 300 additions and 54 deletions
+15 -9
View File
@@ -24,6 +24,12 @@ const messageValidator = (body) => {
return {value: {content, retryActiveIndex: body?.retryActiveIndex}};
};
const searchPreferencesValidator = (body) => {
if (body?.webSearch !== undefined && typeof body.webSearch !== "boolean") return {error: "webSearch must be a boolean"};
if (body?.reasoning !== undefined && typeof body.reasoning !== "boolean") return {error: "reasoning must be a boolean"};
return {value: {webSearch: body?.webSearch !== false, reasoning: body?.reasoning === true}};
};
const sendMessageValidator = (body) => {
const attachments = body?.attachments ?? [];
if (!Array.isArray(attachments) || attachments.some(id => typeof id !== "string" || !/^[a-f0-9-]{36}$/.test(id))) return {error: "Invalid attachment IDs"};
@@ -31,9 +37,9 @@ const sendMessageValidator = (body) => {
const chatId = Number(body?.chatId);
if (!chatId) return {error: "chatId is required"};
if (!message) return {error: "message is required"};
if (body.webSearch !== undefined && typeof body.webSearch !== "boolean") return {error: "webSearch must be a boolean"};
if (body.reasoning !== undefined && typeof body.reasoning !== "boolean") return {error: "reasoning must be a boolean"};
return {value: {message, chatId, attachments, model: String(body?.model || "qwen3:14b"), webSearch: body.webSearch === true, reasoning: body.reasoning === true}};
const preferences = searchPreferencesValidator(body);
if (preferences.error) return preferences;
return {value: {message, chatId, attachments, model: String(body?.model || "qwen3:14b"), ...preferences.value}};
};
const organizationValidator = (body) => ({
@@ -574,7 +580,7 @@ export function createChatsRouter({repositories, chatService, modelService, conf
res.json({message: chatService.formatChatMessage(repositories.getChatMessage(chatId, messageId))});
});
router.post(["/chats/:id/messages/:messageId/retry", "/chats/:id/messages/:messageId/retry/stream"], ...chatRateLimiters, generationCancellation, asyncHandler(async (req, res) => {
router.post(["/chats/:id/messages/:messageId/retry", "/chats/:id/messages/:messageId/retry/stream"], ...chatRateLimiters, generationCancellation, validateBody(searchPreferencesValidator), asyncHandler(async (req, res) => {
const chatId = Number(req.params.id);
const messageId = Number(req.params.messageId);
const chat = repositories.getChat(chatId, req.session.user);
@@ -598,8 +604,8 @@ export function createChatsRouter({repositories, chatService, modelService, conf
selectedModel: String(req.body?.model || "qwen3:14b"),
targetMessage,
retryStyle: String(req.body?.style || "").trim() || null,
webSearch: req.body?.webSearch === true,
reasoning: req.body?.reasoning === true,
webSearch: req.validatedBody.webSearch,
reasoning: req.validatedBody.reasoning,
signal: req.generationSignal,
...(streaming ? {
...createTextStreamEvents(sendEvent),
@@ -621,7 +627,7 @@ export function createChatsRouter({repositories, chatService, modelService, conf
}
}));
router.post("/chats/:id/messages/by-index/:index/retry", ...chatRateLimiters, generationCancellation, asyncHandler(async (req, res) => {
router.post("/chats/:id/messages/by-index/:index/retry", ...chatRateLimiters, generationCancellation, validateBody(searchPreferencesValidator), asyncHandler(async (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"});
@@ -638,8 +644,8 @@ export function createChatsRouter({repositories, chatService, modelService, conf
selectedModel: String(req.body?.model || "qwen3:14b"),
targetMessage,
retryStyle: String(req.body?.style || "").trim() || null,
webSearch: req.body?.webSearch === true,
reasoning: req.body?.reasoning === true
webSearch: req.validatedBody.webSearch,
reasoning: req.validatedBody.reasoning
});
if (result.error) return res.status(result.status).json({error: result.error});
return res.json(result);