char-fork/llama.cpp

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

Aleksander Grygierui: Stores split refactor (#27240)521a64cd0

char/aliceai-t5-moe
2.4 KiB64 linesraw
1// Pins the contract that makes streaming cheap: updateMessageAtIndex mutates the
2// existing message object instead of replacing it.
3//
4// Replacing it (`{ ...old, ...updates }`) changes the array slot, which
5// invalidates every consumer that merely walks the list - ChatMessages'
6// `displayMessages` rebuilds entries for EVERY message in the conversation. That
7// made per-token cost scale with conversation length (1.26ms at 1 prior message
8// -> 3.07ms at 40). Mutating in place keeps it flat.
9
10import { MessageRole } from '$lib/enums';
11import { conversationsStore } from '$lib/stores/conversations/index.svelte';
12import type { DatabaseMessage } from '$lib/types';
13import { describe, expect, it } from 'vitest';
14
15function makeMessage(id: string): DatabaseMessage {
16	return {
17		children: [],
18		content: '',
19		convId: 'c1',
20		id,
21		parent: null,
22		role: MessageRole.ASSISTANT,
23		timestamp: 0,
24		type: 'text'
25	} as DatabaseMessage;
26}
27
28describe('conversationsStore.updateMessageAtIndex', () => {
29	it('mutates in place, preserving object identity', () => {
30		conversationsStore.activeMessages = [makeMessage('a'), makeMessage('b')];
31		const before = conversationsStore.activeMessages[1];
32
33		conversationsStore.updateMessageAtIndex(1, { content: 'hello' });
34
35		expect(conversationsStore.activeMessages[1].content).toBe('hello');
36		expect(conversationsStore.activeMessages[1]).toBe(before);
37
38		conversationsStore.activeMessages = [];
39	});
40
41	it('leaves other messages and unrelated fields untouched', () => {
42		conversationsStore.activeMessages = [makeMessage('a'), makeMessage('b')];
43		const untouched = conversationsStore.activeMessages[0];
44
45		conversationsStore.updateMessageAtIndex(1, { content: 'x', model: 'm1' });
46
47		expect(conversationsStore.activeMessages[0]).toBe(untouched);
48		expect(conversationsStore.activeMessages[0].content).toBe('');
49		expect(conversationsStore.activeMessages[1].model).toBe('m1');
50		expect(conversationsStore.activeMessages[1].id).toBe('b');
51
52		conversationsStore.activeMessages = [];
53	});
54
55	it('is a no-op for an index of -1 or out of range', () => {
56		conversationsStore.activeMessages = [makeMessage('a')];
57
58		expect(() => conversationsStore.updateMessageAtIndex(-1, { content: 'x' })).not.toThrow();
59		expect(() => conversationsStore.updateMessageAtIndex(9, { content: 'x' })).not.toThrow();
60		expect(conversationsStore.activeMessages[0].content).toBe('');
61
62		conversationsStore.activeMessages = [];
63	});
64});