fix: persist modelIdx so duplicate side-by-side models don't collapse on reload (#26980)
When the same model is selected multiple times in a side-by-side chat, each response is created with a distinct modelIdx (0,1,2,3) that identifies its column. The backend now owns message persistence, but it built the assistant placeholders without modelIdx, so the field was never saved. On reload MultiResponseMessages groups responses by modelIdx and falls back to grouping by model id when modelIdx is missing; with duplicate models that fallback lumps every response into each column, so all columns render the first response (and show a bogus '1/N' pager). Send modelIdx with each message_ids entry from the frontend and persist it on the assistant placeholders in both the new-chat and existing-chat paths. The message_ids list is now forwarded for every send (not just multi-model ones) so single-column regenerations in a duplicate-model chat also keep their column identity across reloads.
This commit is contained in:
+21
-11
@@ -1259,7 +1259,7 @@ async def chat_completion(
|
||||
target_model_id = entry['model_id']
|
||||
assistant_message_id = entry['message_id']
|
||||
if assistant_message_id:
|
||||
history_messages[assistant_message_id] = {
|
||||
assistant_message = {
|
||||
'id': assistant_message_id,
|
||||
'parentId': user_message_id,
|
||||
'childrenIds': [],
|
||||
@@ -1269,6 +1269,11 @@ async def chat_completion(
|
||||
'model': target_model_id,
|
||||
'timestamp': int(time.time()),
|
||||
}
|
||||
# Preserve the side-by-side column index so duplicate
|
||||
# models don't collapse into one another on reload.
|
||||
if entry.get('modelIdx') is not None:
|
||||
assistant_message['modelIdx'] = entry['modelIdx']
|
||||
history_messages[assistant_message_id] = assistant_message
|
||||
|
||||
await Chats.insert_new_chat(
|
||||
chat_id,
|
||||
@@ -1481,19 +1486,24 @@ async def chat_completion(
|
||||
target_model_id = entry['model_id']
|
||||
assistant_message_id = entry['message_id']
|
||||
if assistant_message_id:
|
||||
assistant_message = {
|
||||
'id': assistant_message_id,
|
||||
'parentId': user_message_id,
|
||||
'childrenIds': [],
|
||||
'role': 'assistant',
|
||||
'content': '',
|
||||
'done': False,
|
||||
'model': target_model_id,
|
||||
'timestamp': int(time.time()),
|
||||
}
|
||||
# Preserve the side-by-side column index so duplicate
|
||||
# models don't collapse into one another on reload.
|
||||
if entry.get('modelIdx') is not None:
|
||||
assistant_message['modelIdx'] = entry['modelIdx']
|
||||
await Chats.upsert_message_to_chat_by_id_and_message_id(
|
||||
chat_id,
|
||||
assistant_message_id,
|
||||
{
|
||||
'id': assistant_message_id,
|
||||
'parentId': user_message_id,
|
||||
'childrenIds': [],
|
||||
'role': 'assistant',
|
||||
'content': '',
|
||||
'done': False,
|
||||
'model': target_model_id,
|
||||
'timestamp': int(time.time()),
|
||||
},
|
||||
assistant_message,
|
||||
)
|
||||
await publish_event(
|
||||
request,
|
||||
|
||||
@@ -2777,9 +2777,11 @@
|
||||
: selectedModels;
|
||||
|
||||
// Create response messages for each selected model
|
||||
// Build message_ids list: [{model_id, message_id}, ...]
|
||||
// Build message_ids list: [{model_id, message_id, modelIdx}, ...]
|
||||
// Uses an array instead of a dict to support duplicate model IDs in side-by-side chat.
|
||||
const messageIdsList: Array<{ model_id: string; message_id: string }> = [];
|
||||
// modelIdx identifies each side-by-side column so the backend can persist it; without
|
||||
// it, duplicate models collapse into one another when the chat is reloaded.
|
||||
const messageIdsList: Array<{ model_id: string; message_id: string; modelIdx: number }> = [];
|
||||
for (const [_modelIdx, modelId] of selectedModelIds.entries()) {
|
||||
const model = $models.filter((m) => m.id === modelId).at(0);
|
||||
|
||||
@@ -2811,7 +2813,11 @@
|
||||
}
|
||||
|
||||
responseMessageIds[`${modelId}-${modelIdx ? modelIdx : _modelIdx}`] = responseMessageId;
|
||||
messageIdsList.push({ model_id: modelId, message_id: responseMessageId });
|
||||
messageIdsList.push({
|
||||
model_id: modelId,
|
||||
message_id: responseMessageId,
|
||||
modelIdx: modelIdx ? modelIdx : _modelIdx
|
||||
});
|
||||
}
|
||||
}
|
||||
history = history;
|
||||
@@ -2890,7 +2896,11 @@
|
||||
primaryResponseMessageId,
|
||||
_chatId,
|
||||
{
|
||||
messageIdsList: selectedModelIds.length > 1 ? messageIdsList : undefined,
|
||||
// Always forward the message_ids list (not just for multi-model sends) so the
|
||||
// backend persists each response's modelIdx — including single-column
|
||||
// regenerations in a duplicate-model chat, which would otherwise lose their
|
||||
// column identity and collapse on reload.
|
||||
messageIdsList: messageIdsList.length > 0 ? messageIdsList : undefined,
|
||||
regenerationPrompt
|
||||
}
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user