char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
0021a77de
char/aliceai-t5-moe
1/** 2* Shared `file_glob_search` runners with a short-lived result cache, so a 3* repeated query for the same (type, path, glob, depth) reuses the last 4* result instead of re-walking the tree. 5*/ 6 7import { lastPathSegment } from './path-display' ; 8import { buildGlobSearchArgs , joinPath , rankEntries } from './working-directory' ; 9import { GLOB , PATH_SEPARATOR , SEARCH } from '$lib/constants' ; 10import { BuiltInTool , GlobSearchType } from '$lib/enums' ; 11import { ToolsService } from '$lib/services/tools.service' ; 12import type { 13GlobEntry , 14GlobEntryResult , 15GlobSearchArgs , 16GlobSearchChildOptions , 17GlobSearchChildResult , 18GlobSearchResult 19} from '$lib/types/glob' ; 20 21const SEARCH_CACHE_TTL_MS = 2000 ; 22 23interface CacheEntry { 24results :GlobEntry []; 25base :string ; 26at :number ; 27} 28 29const searchCache = new Map < string , CacheEntry >(); 30 31export async function runGlobSearch ( 32args :GlobSearchArgs , 33type :GlobSearchType , 34limit :number , 35signal :AbortSignal 36) :Promise < GlobSearchResult > { 37const key = ` ${ type } \u0000 ${ args . path } \u0000 ${ args . include } \u0000 ${ args . maxDepth } \u0000 ${ limit } ` ; 38const cached = searchCache . get ( key ); 39 40if ( cached && Date . now () - cached . at < SEARCH_CACHE_TTL_MS ) { 41return { base :cached . base , entries :cached . results }; 42} 43 44const res = await ToolsService . executeToolRaw ( 45BuiltInTool . SERVER_FILE_GLOB_SEARCH , 46{ include :args . include , limit, max_depth :args . maxDepth , path :args . path , type}, 47signal 48); 49 50if ( typeof res . error === 'string' ) return { base :'' , entries :[], error :res . error }; 51 52const base = typeof res . base === 'string' ?res . base :'' ; 53const entries = Array . isArray ( res . entries ) ?( res . entries as GlobEntry []) :[]; 54const now = Date . now (); 55 56// prune stale entries so the short-lived cache cannot grow unbounded 57for ( const [ k , v ] of searchCache ) { 58if ( now - v . at >= SEARCH_CACHE_TTL_MS ) searchCache . delete ( k ); 59} 60searchCache . set ( key , { at :now , base, results :entries }); 61 62return { base, entries}; 63} 64 65function toEntryResult ( e :GlobEntry , base :string ) :GlobEntryResult { 66return { name :lastPathSegment ( e . path ), path :joinPath ( base , e . path ), type :e . type }; 67} 68 69/** 70* One ranked glob search that may also list the matched directory's 71* children, shared by the WD picker (descend on exact match) and the 72* mention picker (descend on a trailing `/` or `\`). 73*/ 74export async function runGlobSearchWithChildren ( 75query :string , 76scopePath :string , 77searchDepth :number , 78limit :number , 79signal :AbortSignal , 80options :GlobSearchChildOptions = {} 81) :Promise < GlobSearchChildResult > { 82const { 83 childMaxDepth= SEARCH . PATH_NAV_MAX_DEPTH , 84 descendOnTrailingSeparator= false , 85 type= GlobSearchType . ALL 86} = options ; 87const args = buildGlobSearchArgs ( query , scopePath , searchDepth ); 88const res = await runGlobSearch ( args , type , limit , signal ); 89 90if ( res . error ) return { args, base :res . base , entries :[], error :res . error }; 91 92const ranked = rankEntries ( res . entries , args . rankQuery ); 93const entries = ranked . map (( e ) => toEntryResult ( e , res . base )); 94const last = args . last ; 95 96if ( last ) { 97const wantsDescend = descendOnTrailingSeparator 98 ?query . endsWith ( PATH_SEPARATOR ) || query . endsWith ( GLOB . WINDOWS_SEPARATOR ) 99 :true ; 100const exact = ranked . find ( 101( e ) => e . type === 'dir' && lastPathSegment ( e . path ). toLowerCase () === last . toLowerCase () 102); 103 104if ( wantsDescend && exact ) { 105const exactDir = joinPath ( res . base , exact . path ); 106const childRes = await runGlobSearch ( 107{ include :GLOB . WILDCARD , maxDepth :childMaxDepth , path :exactDir , rankQuery :'' }, 108type , 109limit , 110signal 111); 112 113if ( ! childRes . error ) { 114const children = childRes . entries 115. map (( e ) => toEntryResult ( e , childRes . base )) 116. sort (( a , b ) => a . path . localeCompare ( b . path )); 117 118return { args, base :res . base , entries :[ ...entries , ...children ], exactDir}; 119} 120} 121} 122 123return { args, base :res . base , entries}; 124}