char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
0afb805b1
char/aliceai-t5-moe
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 { 11return { 12 children, 13content :'' , 14convId :'c1' , 15 id, 16 parent, 17role :MessageRole . USER , 18timestamp :0 , 19type :MessageType . TEXT 20} as DatabaseMessage ; 21} 22 23/** root -> m1 -> ... -> m depth, each node with a single child. */ 24function linearChain ( depth :number ) :DatabaseMessage [] { 25const messages = [ msg ( 'm0' , null , [ 'm1' ])]; 26 27for ( let i = 1 ; i <= depth ; i ++ ) { 28messages . push ( msg ( `m ${ i } ` , `m ${ i - 1 } ` , i < depth ?[ `m ${ i + 1 } ` ] :[])); 29} 30 31return messages ; 32} 33 34describe ( 'buildSiblingInfoMap' , () => { 35it ( 'resolves the deepest leaf for every node of a long single chain' , () => { 36const messages = linearChain ( 50 ); 37const map = buildSiblingInfoMap ( messages ); 38const 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 42for ( const m of messages . slice ( 1 )) { 43const info = map . get ( m . id ); 44 45expect ( info ?. totalSiblings ). toBe ( 1 ); 46expect ( info ?. siblingIds ). toEqual ([ leafId ]); 47} 48}); 49 50it ( 'reports sibling position and leaf targets on a branched tree' , () => { 51// m0 -> m1, m4 ; m1 -> m2 ; m2 -> m3, m6 ; m4 -> m5 52const root = msg ( 'm0' , null , [ 'm1' , 'm4' ]); 53const m1 = msg ( 'm1' , 'm0' , [ 'm2' ]); 54const m2 = msg ( 'm2' , 'm1' , [ 'm3' , 'm6' ]); 55const m3 = msg ( 'm3' , 'm2' ); 56const m4 = msg ( 'm4' , 'm0' , [ 'm5' ]); 57const m5 = msg ( 'm5' , 'm4' ); 58const m6 = msg ( 'm6' , 'm2' ); 59const 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 ) 63expect ( map . get ( m1 . id )). toMatchObject ({ 64currentIndex :0 , 65siblingIds :[ m6 . id , m5 . id ], 66totalSiblings :2 67}); 68expect ( map . get ( m4 . id )). toMatchObject ({ 69currentIndex :1 , 70siblingIds :[ m6 . id , m5 . id ], 71totalSiblings :2 72}); 73 74// m3 and m6 are siblings under m2; both are leaves 75expect ( map . get ( m3 . id )?. siblingIds ). toEqual ([ m3 . id , m6 . id ]); 76expect ( map . get ( m6 . id )?. currentIndex ). toBe ( 1 ); 77 78// the root has no parent and reports itself 79expect ( map . get ( root . id )). toMatchObject ({ 80currentIndex :0 , 81siblingIds :[ root . id ], 82totalSiblings :1 83}); 84}); 85 86it ( 'agrees with findLeafNode for arbitrary nodes' , () => { 87const messages = linearChain ( 20 ); 88const leafId = messages [ messages . length - 1 ]. id ; 89 90// every node of the chain resolves to the deepest leaf 91for ( const m of messages ) { 92expect ( findLeafNode ( messages , m . id ), `leaf of ${ m . id } ` ). toBe ( leafId ); 93} 94}); 95});