char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
0afb805b1
char/aliceai-t5-moe
1import { parseToolArgs } from '$lib/components/app/chat/ChatMessages/ChatMessage/ChatMessageToolCall/parsers/_shared' ; 2import { 3parseEditFileMeta , 4parseEditFileTitleMeta 5} from '$lib/components/app/chat/ChatMessages/ChatMessage/ChatMessageToolCall/parsers/edit-file' ; 6import { parseExecShellCommandMeta } from '$lib/components/app/chat/ChatMessages/ChatMessage/ChatMessageToolCall/parsers/exec-shell-command' ; 7import { parseFileGlobSearchMeta } from '$lib/components/app/chat/ChatMessages/ChatMessage/ChatMessageToolCall/parsers/file-glob-search' ; 8import { parseGrepSearchMeta } from '$lib/components/app/chat/ChatMessages/ChatMessage/ChatMessageToolCall/parsers/grep-search' ; 9import { parseReadFileMeta } from '$lib/components/app/chat/ChatMessages/ChatMessage/ChatMessageToolCall/parsers/read-file' ; 10import { parseRunJavascriptMeta } from '$lib/components/app/chat/ChatMessages/ChatMessage/ChatMessageToolCall/parsers/run-javascript' ; 11import { 12parseWriteFileMeta , 13parseWriteFileTitleMeta 14} from '$lib/components/app/chat/ChatMessages/ChatMessage/ChatMessageToolCall/parsers/write-file' ; 15import { AgenticSectionType , BuiltInTool } from '$lib/enums' ; 16import type { AgenticSection , WriteFileMeta } from '$lib/types' ; 17import { abbreviateHome , formatCwdMessage , lastPathSegment , parseCwdMessage } from '$lib/utils' ; 18import { describe , expect , it } from 'vitest' ; 19 20function makeSection ( 21overrides :Partial < AgenticSection > = {}, 22toolName = BuiltInTool . SERVER_READ_FILE 23) :AgenticSection { 24return { 25content :'' , 26toolArgs :JSON . stringify ({ path :'/foo.txt' }), 27 toolName, 28toolResult :undefined , 29type :AgenticSectionType . TOOL_CALL , 30 ...overrides 31}; 32} 33 34describe ( 'lastPathSegment' , () => { 35it ( 'returns the last segment of an absolute path' , () => { 36expect ( lastPathSegment ( '/Users/me/code/my-project' )). toBe ( 'my-project' ); 37}); 38 39it ( 'returns the last segment of a tilde-relative path' , () => { 40expect ( lastPathSegment ( '~/git/llama.brand' )). toBe ( 'llama.brand' ); 41}); 42 43it ( 'strips trailing slashes' , () => { 44expect ( lastPathSegment ( '/foo/bar/' )). toBe ( 'bar' ); 45}); 46 47it ( 'strips multiple trailing slashes' , () => { 48expect ( lastPathSegment ( '/foo/bar///' )). toBe ( 'bar' ); 49}); 50 51it ( 'returns the input unchanged when there is no slash' , () => { 52expect ( lastPathSegment ( 'project' )). toBe ( 'project' ); 53}); 54 55it ( 'returns tilde when only tilde is given' , () => { 56expect ( lastPathSegment ( '~/' )). toBe ( '~' ); 57}); 58}); 59 60describe ( 'abbreviateHome' , () => { 61it ( 'abbreviates paths under home with a tilde' , () => { 62expect ( abbreviateHome ( '/Users/al/Documents/x.txt' , '/Users/al' )). toBe ( '~/Documents/x.txt' ); 63}); 64 65it ( 'abbreviates home itself to a bare tilde' , () => { 66expect ( abbreviateHome ( '/Users/al' , '/Users/al' )). toBe ( '~' ); 67}); 68 69it ( 'returns paths outside home unchanged' , () => { 70expect ( abbreviateHome ( '/opt/project' , '/Users/al' )). toBe ( '/opt/project' ); 71}); 72 73it ( 'does not abbreviate a mere prefix match' , () => { 74expect ( abbreviateHome ( '/Users/alice/x' , '/Users/al' )). toBe ( '/Users/alice/x' ); 75}); 76 77it ( 'returns the path unchanged when home is unknown' , () => { 78expect ( abbreviateHome ( '/Users/al/Documents' , null )). toBe ( '/Users/al/Documents' ); 79}); 80}); 81 82describe ( 'formatCwdMessage / parseCwdMessage' , () => { 83it ( 'formats a cwd change matching the UI text, with a file link' , () => { 84expect ( formatCwdMessage ( '/Users/al/Documents' , '/Users/al' )). toBe ( 85'Set working directory to [file:///Users/al/Documents](~/Documents).' 86); 87}); 88 89it ( 'falls back to the basename display when home is unknown' , () => { 90expect ( formatCwdMessage ( '/opt/project' , null )). toBe ( 91'Set working directory to [file:///opt/project](project).' 92); 93}); 94 95it ( 'round-trips through the parser' , () => { 96const info = parseCwdMessage ( formatCwdMessage ( '/Users/al/Documents' , '/Users/al' )); 97 98expect ( info ?. path ). toBe ( '/Users/al/Documents' ); 99expect ( info ?. display ). toBe ( '~/Documents' ); 100}); 101 102it ( 'parses a cwd message even when guidance follows the link' , () => { 103expect ( 104parseCwdMessage ( 105'Set working directory to [file:///a/b](~/b). Tool calls run with this as their working directory.' 106) 107). toEqual ({ display :'~/b' , path :'/a/b' }); 108}); 109 110it ( 'parses the cleared marker' , () => { 111expect ( parseCwdMessage ( 'Working directory cleared' )). toEqual ({ display :'' , path :null }); 112}); 113 114it ( 'returns null for non-cwd content' , () => { 115expect ( parseCwdMessage ( 'hello there' )). toBeNull (); 116}); 117}); 118 119describe ( 'parseToolArgs (shared)' , () => { 120it ( 'returns null when the section has no toolArgs' , () => { 121const result = parseToolArgs ( 122BuiltInTool . SERVER_READ_FILE , 123makeSection ({ toolArgs :undefined }) 124); 125 126expect ( result ). toBeNull (); 127}); 128 129it ( 'returns null when the tool name does not match' , () => { 130const result = parseToolArgs ( 131BuiltInTool . SERVER_READ_FILE , 132makeSection ({ toolArgs :'{"path":"/x"}' }, BuiltInTool . SERVER_WRITE_FILE ) 133); 134 135expect ( result ). toBeNull (); 136}); 137 138it ( 'returns null when args are not valid final JSON (partial: false)' , () => { 139const result = parseToolArgs ( 140BuiltInTool . SERVER_READ_FILE , 141makeSection ({ toolArgs :'{"path": "/foo.tx' }) 142); 143 144expect ( result ). toBeNull (); 145}); 146 147it ( 'returns parsed args when valid final JSON' , () => { 148const result = parseToolArgs ( 149BuiltInTool . SERVER_READ_FILE , 150makeSection ({ toolArgs :'{"path":"/foo.txt"}' }) 151); 152 153expect ( result ). toEqual ({ path :'/foo.txt' }); 154}); 155 156it ( 'accepts partial JSON when partial: true' , () => { 157const result = parseToolArgs ( 158BuiltInTool . SERVER_READ_FILE , 159makeSection ({ toolArgs :'{"path": "/foo.tx' }), 160{ partial :true } 161); 162 163expect ( result ). toEqual ({ path :'/foo.tx' }); 164}); 165}); 166 167describe ( 'parseWriteFileMeta' , () => { 168it ( 'returns null for sections with a different tool name' , () => { 169expect ( 170parseWriteFileMeta ( 171makeSection ({ 172toolArgs :'{"path":"/x","content":"y"}' , 173toolName :BuiltInTool . SERVER_READ_FILE 174}) 175) 176). toBeNull (); 177}); 178 179it ( 'returns null when args have no path-like field' , () => { 180expect ( 181parseWriteFileMeta ( 182makeSection ({ toolArgs :'{"content":"x"}' , toolName :BuiltInTool . SERVER_WRITE_FILE }) 183) 184). toBeNull (); 185}); 186 187it ( 'accepts partial args (renders incrementally as content streams in)' , () => { 188const meta = parseWriteFileMeta ( 189makeSection ({ toolArgs :'{"path":"/foo.t' , toolName :BuiltInTool . SERVER_WRITE_FILE }) 190); 191 192expect ( meta ?. filePath ). toBe ( '/foo.t' ); 193}); 194 195it ( 'returns file path, language, content, bytes, resultMessage' , () => { 196const meta = parseWriteFileMeta ( 197makeSection ( 198{ 199toolArgs :'{"path":"/foo.ts","content":"x"}' , 200toolName :BuiltInTool . SERVER_WRITE_FILE , 201toolResult :'{"result":"wrote","bytes":42}' 202}, 203BuiltInTool . SERVER_WRITE_FILE 204) 205); 206 207expect ( meta ). toMatchObject < Partial < WriteFileMeta >>({ 208bytesWritten :42 , 209content :'x' , 210filePath :'/foo.ts' , 211language :expect . any ( String ), 212resultMessage :'wrote' 213}); 214}); 215 216it ( 'surfaces errorMessage from the result blob' , () => { 217const meta = parseWriteFileMeta ( 218makeSection ({ 219toolArgs :'{"path":"/foo","content":"x"}' , 220toolName :BuiltInTool . SERVER_WRITE_FILE , 221toolResult :'{"error":"permission denied"}' 222}) 223); 224 225expect ( meta ?. errorMessage ). toBe ( 'permission denied' ); 226}); 227}); 228 229describe ( 'parseWriteFileTitleMeta' , () => { 230it ( 'matches the full meta for path, language and result fields' , () => { 231const args = JSON . stringify ({ content :'x' . repeat ( 50_000 ), path :'/foo.ts' }); 232const toolResult = '{"result":"wrote","bytes":42}' ; 233const section = makeSection ( 234{ toolArgs :args , toolName :BuiltInTool . SERVER_WRITE_FILE , toolResult}, 235BuiltInTool . SERVER_WRITE_FILE 236); 237const full = parseWriteFileMeta ( section ); 238const title = parseWriteFileTitleMeta ( section ); 239 240expect ( title ?. filePath ). toBe ( full ?. filePath ); 241expect ( title ?. fileName ). toBe ( full ?. fileName ); 242expect ( title ?. language ). toBe ( full ?. language ); 243expect ( title ?. bytesWritten ). toBe ( full ?. bytesWritten ); 244expect ( title ?. resultMessage ). toBe ( full ?. resultMessage ); 245expect ( title ?. errorMessage ). toBe ( full ?. errorMessage ); 246}); 247 248it ( 'extracts a path with escaped characters without parsing the content blob' , () => { 249const section = makeSection ( 250{ 251toolArgs :'{"path":"/a\\nb\\"c/d.ts","content":"x"}' , 252toolName :BuiltInTool . SERVER_WRITE_FILE 253}, 254BuiltInTool . SERVER_WRITE_FILE 255); 256 257expect ( parseWriteFileTitleMeta ( section )?. filePath ). toBe ( '/a\nb"c/d.ts' ); 258}); 259 260it ( 'falls back to the full parse for args the extractor can not see' , () => { 261const section = makeSection ( 262{ 263// key written with an escaped unicode escape sequence in the name 264toolArgs :'{"\\u0070ath":"/foo.ts","content":"x"}' , 265toolName :BuiltInTool . SERVER_WRITE_FILE 266}, 267BuiltInTool . SERVER_WRITE_FILE 268); 269 270expect ( parseWriteFileTitleMeta ( section )?. filePath ). toBe ( '/foo.ts' ); 271}); 272 273it ( 'accepts partial args like the full parser' , () => { 274const section = makeSection ( 275{ toolArgs :'{"path":"/foo.t' , toolName :BuiltInTool . SERVER_WRITE_FILE }, 276BuiltInTool . SERVER_WRITE_FILE 277); 278 279expect ( parseWriteFileTitleMeta ( section )?. filePath ). toBe ( '/foo.t' ); 280}); 281 282it ( 'returns null for sections with a different tool name' , () => { 283expect ( 284parseWriteFileTitleMeta ( 285makeSection ({ 286toolArgs :'{"path":"/x","content":"y"}' , 287toolName :BuiltInTool . SERVER_READ_FILE 288}) 289) 290). toBeNull (); 291}); 292}); 293 294describe ( 'parseEditFileTitleMeta' , () => { 295it ( 'matches the full meta for path and result fields' , () => { 296const section = makeSection ( 297{ 298toolArgs :'{"path":"/foo.ts","edits":[{"old_text":"a","new_text":"b"}]}' + ' ' . repeat ( 0 ), 299toolName :BuiltInTool . SERVER_EDIT_FILE , 300toolResult :'{"result":"ok","edits_applied":1}' 301}, 302BuiltInTool . SERVER_EDIT_FILE 303); 304const full = parseEditFileMeta ( section ); 305const title = parseEditFileTitleMeta ( section ); 306 307expect ( title ?. filePath ). toBe ( full ?. filePath ); 308expect ( title ?. fileName ). toBe ( full ?. fileName ); 309expect ( title ?. editsApplied ). toBe ( full ?. editsApplied ); 310expect ( title ?. resultMessage ). toBe ( full ?. resultMessage ); 311expect ( title ?. errorMessage ). toBe ( full ?. errorMessage ); 312}); 313 314it ( 'surfaces errorMessage from the result blob without parsing args' , () => { 315const section = makeSection ( 316{ 317toolArgs :'{"path":"/foo.ts","edits":[]}' , 318toolName :BuiltInTool . SERVER_EDIT_FILE , 319toolResult :'{"error":"permission denied"}' 320}, 321BuiltInTool . SERVER_EDIT_FILE 322); 323 324expect ( parseEditFileTitleMeta ( section )?. errorMessage ). toBe ( 'permission denied' ); 325}); 326 327it ( 'returns null when args have no path-like field' , () => { 328expect ( 329parseEditFileTitleMeta ( 330makeSection ({ toolArgs :'{"edits":[]}' , toolName :BuiltInTool . SERVER_EDIT_FILE }) 331) 332). toBeNull (); 333}); 334}); 335 336describe ( 'parseEditFileMeta' , () => { 337it ( 'parses edits array and applies editsApplied from the result' , () => { 338const section = makeSection ( 339{ 340toolArgs : 341'{"path":"/foo.ts","edits":[{"old_text":"a","new_text":"b"},{"old_text":"c","new_text":"d"}]}' , 342toolName :BuiltInTool . SERVER_EDIT_FILE , 343toolResult :'{"result":"ok","edits_applied":2}' 344}, 345BuiltInTool . SERVER_EDIT_FILE 346); 347const meta = parseEditFileMeta ( section ); 348 349expect ( meta ?. edits ). toEqual ([ 350{ newText :'b' , oldText :'a' }, 351{ newText :'d' , oldText :'c' } 352]); 353expect ( meta ?. editsApplied ). toBe ( 2 ); 354expect ( meta ?. resultMessage ). toBe ( 'ok' ); 355}); 356 357it ( 'drops edits with empty old_text' , () => { 358const section = makeSection ( 359{ 360toolArgs :'{"path":"/foo","edits":[{"old_text":""},{"old_text":"a","new_text":""}]}' , 361toolName :BuiltInTool . SERVER_EDIT_FILE 362}, 363BuiltInTool . SERVER_EDIT_FILE 364); 365const meta = parseEditFileMeta ( section ); 366 367// First entry is dropped (empty old_text). Second is kept 368// (empty new_text is fine - it's the "delete" case). 369expect ( meta ?. edits ). toEqual ([{ newText :'' , oldText :'a' }]); 370}); 371 372it ( 'errorMessage wins over result message' , () => { 373const section = makeSection ( 374{ 375toolArgs :'{"path":"/foo"}' , 376toolName :BuiltInTool . SERVER_EDIT_FILE , 377toolResult :'{"error":"bad path","result":"ok"}' 378}, 379BuiltInTool . SERVER_EDIT_FILE 380); 381const meta = parseEditFileMeta ( section ); 382 383expect ( meta ?. errorMessage ). toBe ( 'bad path' ); 384expect ( meta ?. resultMessage ). toBeUndefined (); 385}); 386}); 387 388describe ( 'parseReadFileMeta' , () => { 389it ( 'parses file name alone (no range)' , () => { 390const meta = parseReadFileMeta ( 391makeSection ({ toolArgs :'{"path":"/foo.txt"}' }, BuiltInTool . SERVER_READ_FILE ) 392); 393 394expect ( meta ?. fileName ). toBe ( 'foo.txt' ); 395expect ( meta ?. lineRange ). toBeNull (); 396}); 397 398it ( 'parses start_line + end_line into a range' , () => { 399const meta = parseReadFileMeta ( 400makeSection ( 401{ toolArgs :'{"path":"/foo.ts","start_line":10,"end_line":20}' }, 402BuiltInTool . SERVER_READ_FILE 403) 404); 405 406expect ( meta ?. lineRange ). toEqual ({ end :20 , start :10 }); 407}); 408 409it ( 'parses start_line + line_count into a range' , () => { 410const meta = parseReadFileMeta ( 411makeSection ( 412{ toolArgs :'{"path":"/foo.ts","start_line":10,"line_count":5}' }, 413BuiltInTool . SERVER_READ_FILE 414) 415); 416 417expect ( meta ?. lineRange ). toEqual ({ end :14 , start :10 }); 418}); 419 420it ( 'returns null when args cannot be parsed' , () => { 421expect ( 422parseReadFileMeta ( makeSection ({ toolArgs :'{bad' }, BuiltInTool . SERVER_READ_FILE )) 423). toBeNull (); 424}); 425}); 426 427describe ( 'parseGrepSearchMeta' , () => { 428it ( 'returns null when path or pattern is missing' , () => { 429expect ( 430parseGrepSearchMeta ( 431makeSection ({ toolArgs :'{"pattern":"foo"}' , toolName :BuiltInTool . SERVER_GREP_SEARCH }) 432) 433). toBeNull (); 434expect ( 435parseGrepSearchMeta ( 436makeSection ({ toolArgs :'{"path":"/x"}' , toolName :BuiltInTool . SERVER_GREP_SEARCH }) 437) 438). toBeNull (); 439}); 440 441it ( 'parses structured plain_text_response into matches' , () => { 442const meta = parseGrepSearchMeta ( 443makeSection ( 444{ 445toolArgs :'{"path":"/x","pattern":"foo"}' , 446toolName :BuiltInTool . SERVER_GREP_SEARCH , 447toolResult :JSON . stringify ({ plain_text_response :'a.ts:hello\nb.ts:world' }) 448}, 449BuiltInTool . SERVER_GREP_SEARCH 450) 451); 452 453expect ( meta ?. matches ). toHaveLength ( 2 ); 454expect ( meta ?. matches [ 0 ]). toEqual ({ content :'hello' , file :'a.ts' }); 455}); 456 457it ( 'falls back to raw-text parsing when result is not JSON' , () => { 458const meta = parseGrepSearchMeta ( 459makeSection ( 460{ 461toolArgs :'{"path":"/x","pattern":"foo"}' , 462toolName :BuiltInTool . SERVER_GREP_SEARCH , 463toolResult :'a.ts:hello\nb.ts:world' 464}, 465BuiltInTool . SERVER_GREP_SEARCH 466) 467); 468 469expect ( meta ?. matches ). toHaveLength ( 2 ); 470}); 471 472it ( 'parses line numbers when return_line_numbers is true' , () => { 473const meta = parseGrepSearchMeta ( 474makeSection ( 475{ 476toolArgs :'{"path":"/x","pattern":"foo","return_line_numbers":true}' , 477toolName :BuiltInTool . SERVER_GREP_SEARCH , 478toolResult :'a.ts:12:hello' 479}, 480BuiltInTool . SERVER_GREP_SEARCH 481) 482); 483 484expect ( meta ?. matches [ 0 ]). toEqual ({ content :'hello' , file :'a.ts' , line :12 }); 485expect ( meta ?. showLineNumbers ). toBe ( true ); 486}); 487}); 488 489describe ( 'parseFileGlobSearchMeta' , () => { 490it ( 'falls back to raw-text parsing when result is not JSON' , () => { 491const meta = parseFileGlobSearchMeta ( 492makeSection ( 493{ 494toolArgs :'{"path":"/x"}' , 495toolName :BuiltInTool . SERVER_FILE_GLOB_SEARCH , 496toolResult :'a.ts\nb.ts' 497}, 498BuiltInTool . SERVER_FILE_GLOB_SEARCH 499) 500); 501 502expect ( meta ?. matches ). toEqual ([ 'a.ts' , 'b.ts' ]); 503}); 504 505it ( 'parses plain_text_response from a JSON object' , () => { 506const meta = parseFileGlobSearchMeta ( 507makeSection ( 508{ 509toolArgs :'{"path":"/x"}' , 510toolName :BuiltInTool . SERVER_FILE_GLOB_SEARCH , 511toolResult :JSON . stringify ({ plain_text_response :'a.ts\nb.ts' }) 512}, 513BuiltInTool . SERVER_FILE_GLOB_SEARCH 514) 515); 516 517expect ( meta ?. matches ). toEqual ([ 'a.ts' , 'b.ts' ]); 518}); 519 520it ( 'surfaces errorMessage from the result blob' , () => { 521const meta = parseFileGlobSearchMeta ( 522makeSection ( 523{ 524toolArgs :'{"path":"/x"}' , 525toolName :BuiltInTool . SERVER_FILE_GLOB_SEARCH , 526toolResult :JSON . stringify ({ error :'permission denied' }) 527}, 528BuiltInTool . SERVER_FILE_GLOB_SEARCH 529) 530); 531 532expect ( meta ?. errorMessage ). toBe ( 'permission denied' ); 533}); 534}); 535 536describe ( 'parseRunJavascriptMeta' , () => { 537it ( 'returns null when code is missing' , () => { 538expect ( 539parseRunJavascriptMeta ( 540makeSection ({ toolArgs :'{}' , toolName :BuiltInTool . BROWSER_RUN_JAVASCRIPT }) 541) 542). toBeNull (); 543}); 544 545it ( 'reads code and timeout' , () => { 546const meta = parseRunJavascriptMeta ( 547makeSection ( 548{ 549toolArgs :'{"code":"Math.PI","timeout_ms":5000}' , 550toolName :BuiltInTool . BROWSER_RUN_JAVASCRIPT 551}, 552BuiltInTool . BROWSER_RUN_JAVASCRIPT 553) 554); 555 556expect ( meta ?. code ). toBe ( 'Math.PI' ); 557expect ( meta ?. timeoutMs ). toBe ( 5000 ); 558}); 559 560it ( 'reads error field from a JSON-object result' , () => { 561const meta = parseRunJavascriptMeta ( 562makeSection ( 563{ 564toolArgs :'{"code":"throw new Error()"}' , 565toolName :BuiltInTool . BROWSER_RUN_JAVASCRIPT , 566toolResult :JSON . stringify ({ error :'undefined is not a function' }) 567}, 568BuiltInTool . BROWSER_RUN_JAVASCRIPT 569) 570); 571 572expect ( meta ?. errorMessage ). toBe ( 'undefined is not a function' ); 573}); 574 575it ( 'does NOT treat a JSON-array result as an error' , () => { 576// SandboxService returns successful output as a JSON array; 577// only JSON objects carry `error`. Raw arrays must round-trip 578// through unchanged. 579const meta = parseRunJavascriptMeta ( 580makeSection ( 581{ 582toolArgs :'{"code":"[1,2,3]"}' , 583toolName :BuiltInTool . BROWSER_RUN_JAVASCRIPT , 584toolResult :'[1,2,3]' 585}, 586BuiltInTool . BROWSER_RUN_JAVASCRIPT 587) 588); 589 590expect ( meta ?. errorMessage ). toBeUndefined (); 591}); 592 593it ( 'scans a non-JSON string result for an `Error:` line' , () => { 594const meta = parseRunJavascriptMeta ( 595makeSection ( 596{ 597toolArgs :'{"code":"foo"}' , 598toolName :BuiltInTool . BROWSER_RUN_JAVASCRIPT , 599toolResult :'Error: undefined is not a function\n at <anonymous>:1:1' 600}, 601BuiltInTool . BROWSER_RUN_JAVASCRIPT 602) 603); 604 605expect ( meta ?. errorMessage ). toBe ( 'undefined is not a function' ); 606}); 607}); 608 609describe ( 'parseExecShellCommandMeta' , () => { 610it ( 'reads command from the args' , () => { 611const meta = parseExecShellCommandMeta ( 612makeSection ( 613{ toolArgs :'{"command":"ls -la"}' , toolName :BuiltInTool . SERVER_EXEC_SHELL_COMMAND }, 614BuiltInTool . SERVER_EXEC_SHELL_COMMAND 615) 616); 617 618expect ( meta ?. command ). toBe ( 'ls -la' ); 619}); 620 621it ( 'accepts cmd / shell_command aliases' , () => { 622expect ( 623parseExecShellCommandMeta ( 624makeSection ( 625{ toolArgs :'{"cmd":"ls"}' , toolName :BuiltInTool . SERVER_EXEC_SHELL_COMMAND }, 626BuiltInTool . SERVER_EXEC_SHELL_COMMAND 627) 628)?. command 629). toBe ( 'ls' ); 630expect ( 631parseExecShellCommandMeta ( 632makeSection ( 633{ toolArgs :'{"shell_command":"ls"}' , toolName :BuiltInTool . SERVER_EXEC_SHELL_COMMAND }, 634BuiltInTool . SERVER_EXEC_SHELL_COMMAND 635) 636)?. command 637). toBe ( 'ls' ); 638}); 639 640it ( 'returns null when no command alias is present' , () => { 641expect ( 642parseExecShellCommandMeta ( 643makeSection ( 644{ toolArgs :'{"cwd":"/x"}' , toolName :BuiltInTool . SERVER_EXEC_SHELL_COMMAND }, 645BuiltInTool . SERVER_EXEC_SHELL_COMMAND 646) 647) 648). toBeNull (); 649}); 650});