char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
e21152dc9
char/aliceai-t5-moe
1import { 2LEADING_SLASHES_REGEX , 3TEMPLATE_EXPRESSION_REGEX , 4URI_SCHEME_SEPARATOR , 5URI_TEMPLATE_SYMBOLS , 6VARIABLE_EXPLODE_MODIFIER_REGEX , 7VARIABLE_PREFIX_MODIFIER_REGEX 8} from '../constants' ; 9 10/** 11* Normalize a resource URI for comparison. 12* 13* URI template expansion (especially with path operators like {/var}) 14* can produce URIs that differ from listed resource URIs in slash placement. 15* For example, the template `svelte://{/slug*}.md` with slug="svelte/$effect" 16* expands to `svelte:///svelte/$effect.md`, while the listed resource URI is 17* `svelte://svelte/$effect.md`. 18* 19* This function strips extra leading slashes after the scheme to normalize 20* both forms to the same string for comparison purposes. 21* 22* @param uri - The URI to normalize 23* @returns Normalized URI string 24*/ 25export function normalizeResourceUri ( uri :string ) :string { 26const schemeEnd = uri . indexOf ( URI_SCHEME_SEPARATOR ); 27 28if ( schemeEnd === - 1 ) return uri ; 29 30const scheme = uri . substring ( 0 , schemeEnd ); 31const rest = uri 32. substring ( schemeEnd + URI_SCHEME_SEPARATOR . length ) 33. replace ( LEADING_SLASHES_REGEX , '' ); 34 35return ` ${ scheme } ${ URI_SCHEME_SEPARATOR } ${ rest } ` ; 36} 37 38/** 39* A parsed variable from a URI template expression. 40*/ 41export interface UriTemplateVariable { 42/** Variable name */ 43name :string ; 44/** Operator prefix (+, #, /, etc.) or empty string */ 45operator :string ; 46} 47 48/** 49* Extract all variable names from a URI template string. 50* 51* @param template - URI template string (RFC 6570) 52* @returns Array of unique variable descriptors 53* 54* @example 55* ```ts 56* extractTemplateVariables("file:///{path}") 57* // => [{ name: "path", operator: "" }] 58* 59* extractTemplateVariables("db://{schema}/{table}") 60* // => [{ name: "schema", operator: "" }, { name: "table", operator: "" }] 61* ``` 62*/ 63export function extractTemplateVariables ( template :string ) :UriTemplateVariable [] { 64const variables :UriTemplateVariable [] = []; 65const seen = new Set < string >(); 66 67let match ; 68 69TEMPLATE_EXPRESSION_REGEX . lastIndex = 0 ; 70 71while (( match = TEMPLATE_EXPRESSION_REGEX . exec ( template )) !== null ) { 72const operator = match [ 1 ] || '' ; 73const varList = match [ 2 ]; 74 75// RFC 6570 allows comma-separated variable lists: {x,y,z} 76for ( const varSpec of varList . split ( ',' )) { 77// Strip explode modifier (*) and prefix modifier (:N) 78const name = varSpec 79. replace ( VARIABLE_EXPLODE_MODIFIER_REGEX , '' ) 80. replace ( VARIABLE_PREFIX_MODIFIER_REGEX , '' ) 81. trim (); 82 83if ( name && ! seen . has ( name )) { 84seen . add ( name ); 85variables . push ({ name, operator}); 86} 87} 88} 89 90return variables ; 91} 92 93/** 94* Expand a URI template with the given variable values. 95* Implements a simplified RFC 6570 Level 2 expansion. 96* 97* @param template - URI template string 98* @param values - Map of variable name to value 99* @returns Expanded URI string 100* 101* @example 102* ```ts 103* expandTemplate("file:///{path}", { path: "src/main.rs" }) 104* // => "file:///src/main.rs" 105* ``` 106*/ 107export function expandTemplate ( template :string , values :Record < string , string >) :string { 108TEMPLATE_EXPRESSION_REGEX . lastIndex = 0 ; 109 110return template . replace ( 111TEMPLATE_EXPRESSION_REGEX , 112( _match , operator :string , varList :string ) => { 113const varNames = varList 114. split ( ',' ) 115. map (( v :string ) => 116v 117. replace ( VARIABLE_EXPLODE_MODIFIER_REGEX , '' ) 118. replace ( VARIABLE_PREFIX_MODIFIER_REGEX , '' ) 119. trim () 120); 121const expandedParts = varNames 122. map (( name :string ) => values [ name ] ?? '' ) 123. filter (( v :string ) => v !== '' ); 124 125if ( expandedParts . length === 0 ) return '' ; 126 127switch ( operator ) { 128case URI_TEMPLATE_SYMBOLS . RESERVED : 129// Reserved expansion: no encoding 130return expandedParts . join ( URI_TEMPLATE_SYMBOLS . COMMA ); 131case URI_TEMPLATE_SYMBOLS . FRAGMENT : 132// Fragment expansion 133return URI_TEMPLATE_SYMBOLS . FRAGMENT + expandedParts . join ( URI_TEMPLATE_SYMBOLS . COMMA ); 134case URI_TEMPLATE_SYMBOLS . PATH_SEGMENT : 135// Path segments 136return ( 137URI_TEMPLATE_SYMBOLS . PATH_SEGMENT + 138expandedParts . join ( URI_TEMPLATE_SYMBOLS . PATH_SEGMENT ) 139); 140case URI_TEMPLATE_SYMBOLS . LABEL : 141// Label expansion 142return URI_TEMPLATE_SYMBOLS . LABEL + expandedParts . join ( URI_TEMPLATE_SYMBOLS . LABEL ); 143case URI_TEMPLATE_SYMBOLS . PATH_PARAM : 144// Path-style parameters 145return varNames 146. filter (( _ :string , i :number ) => expandedParts [ i ]) 147. map ( 148( name :string , i :number ) => 149` ${ URI_TEMPLATE_SYMBOLS . PATH_PARAM } ${ name } = ${ expandedParts [ i ]} ` 150) 151. join ( '' ); 152case URI_TEMPLATE_SYMBOLS . FORM_QUERY : 153// Form-style query 154return ( 155URI_TEMPLATE_SYMBOLS . FORM_QUERY + 156varNames 157. filter (( _ :string , i :number ) => expandedParts [ i ]) 158. map ( 159( name :string , i :number ) => 160` ${ encodeURIComponent ( name )} = ${ encodeURIComponent ( expandedParts [ i ])} ` 161) 162. join ( URI_TEMPLATE_SYMBOLS . FORM_CONTINUATION ) 163); 164case URI_TEMPLATE_SYMBOLS . FORM_CONTINUATION : 165// Form-style query continuation 166return ( 167URI_TEMPLATE_SYMBOLS . FORM_CONTINUATION + 168varNames 169. filter (( _ :string , i :number ) => expandedParts [ i ]) 170. map ( 171( name :string , i :number ) => 172` ${ encodeURIComponent ( name )} = ${ encodeURIComponent ( expandedParts [ i ])} ` 173) 174. join ( URI_TEMPLATE_SYMBOLS . COMMA ) 175); 176default : 177// Simple string expansion (default operator) 178return expandedParts 179. map (( v :string ) => encodeURIComponent ( v )) 180. join ( URI_TEMPLATE_SYMBOLS . COMMA ); 181} 182} 183); 184} 185 186/** 187* Check whether all required variables in a template have been provided. 188* 189* @param template - URI template string 190* @param values - Map of variable name to value 191* @returns true if all variables have non-empty values 192*/ 193export function isTemplateComplete ( template :string , values :Record < string , string >) :boolean { 194const variables = extractTemplateVariables ( template ); 195 196return variables . every (( v ) => ( values [ v . name ] ?? '' ). trim () !== '' ); 197}