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.4 KiB90 linesraw
1// Field updates to the active conversation must keep the object identity
2// stable: effects that track the identity ( the chat screen's sibling-info
3// refresh ) refire on every identity change, which used to trigger a full
4// message refetch on every send and tool result.
5
6import { beforeEach, describe, expect, it, vi } from 'vitest';
7
8vi.mock('$lib/services/database.service', () => ({
9	DatabaseService: {
10		getConversation: vi.fn(),
11		getConversationMessages: vi.fn(),
12		updateConversation: vi.fn(),
13		updateCurrentNode: vi.fn()
14	}
15}));
16
17import { DatabaseService } from '$lib/services/database.service';
18import { conversationsStore } from '$lib/stores/conversations/index.svelte';
19import type { DatabaseConversation, DatabaseMessage } from '$lib/types/database';
20
21const getConversationMock = vi.mocked(DatabaseService.getConversation);
22const getMessagesMock = vi.mocked(DatabaseService.getConversationMessages);
23const updateCurrentNodeMock = vi.mocked(DatabaseService.updateCurrentNode);
24
25function makeConversation(overrides: Partial<DatabaseConversation> = {}): DatabaseConversation {
26	return {
27		currNode: 'node-1',
28		id: 'conv-1',
29		lastModified: 1000,
30		name: 'conversation',
31		...overrides
32	};
33}
34
35async function loadActive(conversation: DatabaseConversation, messages: DatabaseMessage[]) {
36	getConversationMock.mockResolvedValue(conversation);
37	getMessagesMock.mockResolvedValue(messages);
38
39	expect(await conversationsStore.loadConversation(conversation.id)).toBe(true);
40}
41
42beforeEach(() => {
43	getConversationMock.mockReset();
44	getMessagesMock.mockReset();
45	updateCurrentNodeMock.mockReset();
46	updateCurrentNodeMock.mockResolvedValue(undefined);
47	vi.mocked(DatabaseService.updateConversation).mockReset();
48	vi.mocked(DatabaseService.updateConversation).mockResolvedValue(undefined);
49});
50
51describe('active conversation identity', () => {
52	it('hands the load read off exactly once', async () => {
53		await loadActive(makeConversation(), []);
54
55		expect(conversationsStore.consumeLastLoadedMessages('conv-1')).toEqual([]);
56		// a second consume is a miss: branch actions must fall back to a refetch
57		expect(conversationsStore.consumeLastLoadedMessages('conv-1')).toBeNull();
58	});
59
60	it('writes currNode in place on updateCurrentNode', async () => {
61		await loadActive(makeConversation(), []);
62		const before = conversationsStore.activeConversation;
63
64		await conversationsStore.updateCurrentNode('node-2');
65
66		expect(conversationsStore.activeConversation).toBe(before);
67		expect(conversationsStore.activeConversation?.currNode).toBe('node-2');
68	});
69
70	it('writes renamed and pinned fields in place on applyConversationUpdate', async () => {
71		await loadActive(makeConversation(), []);
72		const before = conversationsStore.activeConversation;
73
74		conversationsStore.applyConversationUpdate('conv-1', { name: 'renamed', pinned: true });
75
76		expect(conversationsStore.activeConversation).toBe(before);
77		expect(conversationsStore.activeConversation?.name).toBe('renamed');
78		expect(conversationsStore.activeConversation?.pinned).toBe(true);
79	});
80
81	it('writes lastModified in place on updateConversationTimestamp', async () => {
82		await loadActive(makeConversation(), []);
83		const before = conversationsStore.activeConversation;
84
85		conversationsStore.updateConversationTimestamp('conv-1');
86
87		expect(conversationsStore.activeConversation).toBe(before);
88		expect(conversationsStore.activeConversation?.lastModified).toBeGreaterThan(1000);
89	});
90});