Files
memind/message-stream.mjs
T
John 2e14873f2d Initial commit: Memind H5 portal with MindSpace, Plaza, and agent jobs.
Track application source and tests; exclude local env, user workspaces, and runtime data via .gitignore.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-15 15:04:43 -07:00

67 lines
1.8 KiB
JavaScript

/**
* Merge streaming assistant chunks from SSE Message events.
* Upstream may send deltas, cumulative snapshots, or multi-part content arrays.
*/
export function mergeStreamingChunk(previous, incoming) {
const prev = String(previous ?? '');
const next = String(incoming ?? '');
if (!next) return prev;
if (!prev) return next;
if (next === prev) return prev;
if (next.startsWith(prev)) return next;
if (prev.startsWith(next)) return prev;
if (prev.endsWith(next)) return prev;
const maxOverlap = Math.min(prev.length, next.length);
for (let size = maxOverlap; size > 0; size -= 1) {
if (prev.endsWith(next.slice(0, size))) {
return prev + next.slice(size);
}
}
return prev + next;
}
function findLastContentIndex(content, type) {
for (let index = content.length - 1; index >= 0; index -= 1) {
if (content[index]?.type === type) return index;
}
return -1;
}
function mergeTextLikeBlock(block, incomingValue, field) {
block[field] = mergeStreamingChunk(block[field], incomingValue);
}
export function mergeMessageContent(existingContent, incomingContent) {
const merged = [...existingContent];
for (const item of incomingContent) {
if (item.type === 'text') {
const index = findLastContentIndex(merged, 'text');
if (index >= 0) {
mergeTextLikeBlock(merged[index], item.text, 'text');
continue;
}
merged.push({ ...item });
continue;
}
if (item.type === 'thinking') {
const index = findLastContentIndex(merged, 'thinking');
if (index >= 0) {
mergeTextLikeBlock(merged[index], item.thinking, 'thinking');
continue;
}
merged.push({ ...item });
continue;
}
const tail = merged[merged.length - 1];
if (tail && JSON.stringify(tail) === JSON.stringify(item)) continue;
merged.push({ ...item });
}
return merged;
}