sharktide commited on
Commit
6ef88a3
·
verified ·
1 Parent(s): 5d415f8

Update server/wsHandler.js

Browse files
Files changed (1) hide show
  1. server/wsHandler.js +72 -14
server/wsHandler.js CHANGED
@@ -48,6 +48,7 @@ import { pendingTurnstileTokens } from './index.js';
48
 
49
  const activeStreams = new Map();
50
  const VERSION_META_FIELDS = ['toolCalls', 'responseEdits', 'responseSegments', 'error'];
 
51
  const CONTINUE_ASSISTANT_PROMPT =
52
  'Continue your previous response exactly where it left off. Do not restart, summarize, or repeat the opening. Preserve the same formatting and only add the missing continuation.';
53
  const FREE_WEB_SEARCH_LIMIT = 15;
@@ -454,7 +455,13 @@ const handlers = {
454
  await sessionStore.updateUserSession(client.userId, client.accessToken, sessionId, { history: newHistory, name: newName });
455
  else sessionStore.updateTempSession(client.tempId, sessionId, { history: newHistory, name: newName });
456
 
457
- safeSend(ws, { type: aborted ? 'chat:aborted' : 'chat:done', sessionId, name: newName, history: extractFlatHistory(newRootMessage) });
 
 
 
 
 
 
458
  },
459
  onError(err) {
460
  activeStreams.delete(ws);
@@ -525,7 +532,15 @@ const handlers = {
525
  return safeSend(ws, { type: 'error', message: 'Failed to apply edit - message lost' });
526
  }
527
 
528
- safeSend(ws, { type: 'chat:messageEdited', sessionId, messageId: targetMsg.id, messageIndex, message: updatedTargetMsg, history: updatedFlatHistory });
 
 
 
 
 
 
 
 
529
  },
530
 
531
  'chat:selectVersion': async (ws, msg, client) => {
@@ -560,7 +575,14 @@ const handlers = {
560
  }
561
 
562
  // Send back with messageId for clarity
563
- safeSend(ws, { type: 'chat:versionSelected', sessionId, messageId: targetMsg.id, messageIndex, history: extractFlatHistory(newRoot) });
 
 
 
 
 
 
 
564
  },
565
 
566
  'chat:assistantAction': async (ws, msg, client) => {
@@ -709,7 +731,13 @@ const handlers = {
709
  sessionStore.updateTempSession(client.tempId, sessionId, { history: newHistory, name: newName });
710
  }
711
 
712
- safeSend(ws, { type: 'chat:done', sessionId, name: newName, history: extractFlatHistory(newRoot) });
 
 
 
 
 
 
713
  },
714
  onError(err) {
715
  activeStreams.delete(ws);
@@ -853,7 +881,22 @@ const handlers = {
853
  },
854
  };
855
 
856
- function ser(s) { return { id: s.id, name: s.name, created: s.created, history: s.history || [], model: s.model }; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
857
 
858
  function getClientOwner(client) {
859
  return client.userId
@@ -1093,6 +1136,10 @@ function cloneVersionMetaValue(value) {
1093
  return JSON.parse(JSON.stringify(value));
1094
  }
1095
 
 
 
 
 
1096
  function syncMessageFromActiveVersion(message) {
1097
  if (!message) return message;
1098
  const currentVersion = getActiveVersion(message);
@@ -1143,16 +1190,23 @@ function appendConversationTurn(rootMessage, userEntry, assistantEntry, mediaEnt
1143
 
1144
  function extractFlatHistory(rootMessage) {
1145
  if (!rootMessage) return [];
1146
-
1147
- // Helper to ensure message has valid content
1148
- const ensureValidContent = (msg) => {
1149
- if (msg.content === undefined || msg.content === null) {
1150
- msg.content = '';
 
 
 
 
 
 
 
1151
  }
1152
- return syncMessageFromActiveVersion(msg);
1153
  };
1154
-
1155
- const history = [ensureValidContent(rootMessage)];
1156
  const currentVerIdx = rootMessage.currentVersionIdx ?? 0;
1157
 
1158
  if (!Array.isArray(rootMessage.versions)) {
@@ -1171,7 +1225,11 @@ function extractFlatHistory(rootMessage) {
1171
  const walkTail = (tail) => {
1172
  for (let i = 0; i < tail.length; i++) {
1173
  const msg = tail[i];
1174
- history.push(ensureValidContent(msg));
 
 
 
 
1175
  const ver = msg.versions?.[msg.currentVersionIdx ?? 0];
1176
  if (ver?.tail && Array.isArray(ver.tail)) {
1177
  walkTail(ver.tail);
 
48
 
49
  const activeStreams = new Map();
50
  const VERSION_META_FIELDS = ['toolCalls', 'responseEdits', 'responseSegments', 'error'];
51
+ const ROOT_JSON_KEY = '__historyRootJson';
52
  const CONTINUE_ASSISTANT_PROMPT =
53
  'Continue your previous response exactly where it left off. Do not restart, summarize, or repeat the opening. Preserve the same formatting and only add the missing continuation.';
54
  const FREE_WEB_SEARCH_LIMIT = 15;
 
455
  await sessionStore.updateUserSession(client.userId, client.accessToken, sessionId, { history: newHistory, name: newName });
456
  else sessionStore.updateTempSession(client.tempId, sessionId, { history: newHistory, name: newName });
457
 
458
+ safeSend(ws, {
459
+ type: aborted ? 'chat:aborted' : 'chat:done',
460
+ sessionId,
461
+ name: newName,
462
+ history: extractFlatHistory(newRootMessage),
463
+ [ROOT_JSON_KEY]: JSON.stringify(newRootMessage),
464
+ });
465
  },
466
  onError(err) {
467
  activeStreams.delete(ws);
 
532
  return safeSend(ws, { type: 'error', message: 'Failed to apply edit - message lost' });
533
  }
534
 
535
+ safeSend(ws, {
536
+ type: 'chat:messageEdited',
537
+ sessionId,
538
+ messageId: targetMsg.id,
539
+ messageIndex,
540
+ message: updatedTargetMsg,
541
+ history: updatedFlatHistory,
542
+ [ROOT_JSON_KEY]: JSON.stringify(newRoot),
543
+ });
544
  },
545
 
546
  'chat:selectVersion': async (ws, msg, client) => {
 
575
  }
576
 
577
  // Send back with messageId for clarity
578
+ safeSend(ws, {
579
+ type: 'chat:versionSelected',
580
+ sessionId,
581
+ messageId: targetMsg.id,
582
+ messageIndex,
583
+ history: extractFlatHistory(newRoot),
584
+ [ROOT_JSON_KEY]: JSON.stringify(newRoot),
585
+ });
586
  },
587
 
588
  'chat:assistantAction': async (ws, msg, client) => {
 
731
  sessionStore.updateTempSession(client.tempId, sessionId, { history: newHistory, name: newName });
732
  }
733
 
734
+ safeSend(ws, {
735
+ type: 'chat:done',
736
+ sessionId,
737
+ name: newName,
738
+ history: extractFlatHistory(newRoot),
739
+ [ROOT_JSON_KEY]: JSON.stringify(newRoot),
740
+ });
741
  },
742
  onError(err) {
743
  activeStreams.delete(ws);
 
881
  },
882
  };
883
 
884
+ export function serializeSessionForClient(session) {
885
+ const rootMessage = Array.isArray(session?.history) && session.history[0]
886
+ ? cloneAndRepairTree(session.history[0])
887
+ : null;
888
+ return {
889
+ id: session?.id,
890
+ name: session?.name,
891
+ created: session?.created,
892
+ history: rootMessage ? extractFlatHistory(rootMessage) : [],
893
+ model: session?.model || null,
894
+ updatedAt: session?.updatedAt || null,
895
+ [ROOT_JSON_KEY]: rootMessage ? JSON.stringify(rootMessage) : null,
896
+ };
897
+ }
898
+
899
+ function ser(s) { return serializeSessionForClient(s); }
900
 
901
  function getClientOwner(client) {
902
  return client.userId
 
1136
  return JSON.parse(JSON.stringify(value));
1137
  }
1138
 
1139
+ function cloneJson(value) {
1140
+ return JSON.parse(JSON.stringify(value));
1141
+ }
1142
+
1143
  function syncMessageFromActiveVersion(message) {
1144
  if (!message) return message;
1145
  const currentVersion = getActiveVersion(message);
 
1190
 
1191
  function extractFlatHistory(rootMessage) {
1192
  if (!rootMessage) return [];
1193
+
1194
+ const toFlatEntry = (message) => {
1195
+ const cloned = cloneJson(message);
1196
+ if (cloned.content === undefined || cloned.content === null) {
1197
+ cloned.content = '';
1198
+ }
1199
+ syncMessageFromActiveVersion(cloned);
1200
+ if (Array.isArray(cloned.versions)) {
1201
+ cloned.versions = cloned.versions.map((version) => ({
1202
+ ...version,
1203
+ tail: [],
1204
+ }));
1205
  }
1206
+ return cloned;
1207
  };
1208
+
1209
+ const history = [toFlatEntry(rootMessage)];
1210
  const currentVerIdx = rootMessage.currentVersionIdx ?? 0;
1211
 
1212
  if (!Array.isArray(rootMessage.versions)) {
 
1225
  const walkTail = (tail) => {
1226
  for (let i = 0; i < tail.length; i++) {
1227
  const msg = tail[i];
1228
+ if (msg?.content === undefined || msg?.content === null) {
1229
+ msg.content = '';
1230
+ }
1231
+ syncMessageFromActiveVersion(msg);
1232
+ history.push(toFlatEntry(msg));
1233
  const ver = msg.versions?.[msg.currentVersionIdx ?? 0];
1234
  if (ver?.tail && Array.isArray(ver.tail)) {
1235
  walkTail(ver.tail);