char-fork/llama.cpp

git clone https://git.t4t.associates/char-fork/llama.cpp

Aleksander Grygierui: Improve Chat Messages rendering performance (#28460)0afb805b1

char/aliceai-t5-moe
3.0 KiB95 linesraw
1// Sibling-info correctness for buildSiblingInfoMap, including the memoized
2// leaf resolution. A wrong leaf id here breaks branch navigation, so the
3// deep-chain and multi-branch cases below pin the resolution down.
4
5import { MessageRole, MessageType } from '$lib/enums';
6import type { DatabaseMessage } from '$lib/types/database';
7import { buildSiblingInfoMap, findLeafNode } from '$lib/utils/branching';
8import { describe, expect, it } from 'vitest';
9
10function msg(id: string, parent: string | null, children: string[] = []): DatabaseMessage {
11	return {
12		children,
13		content: '',
14		convId: 'c1',
15		id,
16		parent,
17		role: MessageRole.USER,
18		timestamp: 0,
19		type: MessageType.TEXT
20	} as DatabaseMessage;
21}
22
23/** root -> m1 -> ... -> m depth, each node with a single child. */
24function linearChain(depth: number): DatabaseMessage[] {
25	const messages = [msg('m0', null, ['m1'])];
26
27	for (let i = 1; i <= depth; i++) {
28		messages.push(msg(`m${i}`, `m${i - 1}`, i < depth ? [`m${i + 1}`] : []));
29	}
30
31	return messages;
32}
33
34describe('buildSiblingInfoMap', () => {
35	it('resolves the deepest leaf for every node of a long single chain', () => {
36		const messages = linearChain(50);
37		const map = buildSiblingInfoMap(messages);
38		const leafId = messages[messages.length - 1].id;
39
40		// every non-root message of the chain is an only child, and its
41		// navigation target is the chain's deepest leaf
42		for (const m of messages.slice(1)) {
43			const info = map.get(m.id);
44
45			expect(info?.totalSiblings).toBe(1);
46			expect(info?.siblingIds).toEqual([leafId]);
47		}
48	});
49
50	it('reports sibling position and leaf targets on a branched tree', () => {
51		// m0 -> m1, m4 ; m1 -> m2 ; m2 -> m3, m6 ; m4 -> m5
52		const root = msg('m0', null, ['m1', 'm4']);
53		const m1 = msg('m1', 'm0', ['m2']);
54		const m2 = msg('m2', 'm1', ['m3', 'm6']);
55		const m3 = msg('m3', 'm2');
56		const m4 = msg('m4', 'm0', ['m5']);
57		const m5 = msg('m5', 'm4');
58		const m6 = msg('m6', 'm2');
59		const map = buildSiblingInfoMap([root, m1, m2, m3, m4, m5, m6]);
60
61		// m1 and m4 share the root as parent; their nav targets are the
62		// leaves of their subtrees ( m6 for the first branch, m5 for the second )
63		expect(map.get(m1.id)).toMatchObject({
64			currentIndex: 0,
65			siblingIds: [m6.id, m5.id],
66			totalSiblings: 2
67		});
68		expect(map.get(m4.id)).toMatchObject({
69			currentIndex: 1,
70			siblingIds: [m6.id, m5.id],
71			totalSiblings: 2
72		});
73
74		// m3 and m6 are siblings under m2; both are leaves
75		expect(map.get(m3.id)?.siblingIds).toEqual([m3.id, m6.id]);
76		expect(map.get(m6.id)?.currentIndex).toBe(1);
77
78		// the root has no parent and reports itself
79		expect(map.get(root.id)).toMatchObject({
80			currentIndex: 0,
81			siblingIds: [root.id],
82			totalSiblings: 1
83		});
84	});
85
86	it('agrees with findLeafNode for arbitrary nodes', () => {
87		const messages = linearChain(20);
88		const leafId = messages[messages.length - 1].id;
89
90		// every node of the chain resolves to the deepest leaf
91		for (const m of messages) {
92			expect(findLeafNode(messages, m.id), `leaf of ${m.id}`).toBe(leafId);
93		}
94	});
95});