@@ -197,10 +197,12 @@ export function Prompt(props: PromptProps) {
197197 setDismissedEditorSelectionKey ( editorSelectionKey ( editorContext ( ) ) )
198198 editor . clearSelection ( )
199199 }
200- const fileStyleId = syntax ( ) . getStyleId ( "extmark.file" ) !
201- const agentStyleId = syntax ( ) . getStyleId ( "extmark.agent" ) !
202- const pasteStyleId = syntax ( ) . getStyleId ( "extmark.paste" ) !
200+ const fileStyleId = ( ) => syntax ( ) . getStyleId ( "extmark.file" ) !
201+ const agentStyleId = ( ) => syntax ( ) . getStyleId ( "extmark.agent" ) !
202+ const pasteStyleId = ( ) => syntax ( ) . getStyleId ( "extmark.paste" ) !
203203 let promptPartTypeId = 0
204+ let interruptTimer : ReturnType < typeof setTimeout > | undefined
205+ onCleanup ( ( ) => clearTimeout ( interruptTimer ) )
204206 const event = useEvent ( )
205207
206208 onCleanup (
@@ -380,14 +382,16 @@ export function Prompt(props: PromptProps) {
380382
381383 setStore ( "interrupt" , store . interrupt + 1 )
382384
383- setTimeout ( ( ) => {
385+ clearTimeout ( interruptTimer )
386+ interruptTimer = setTimeout ( ( ) => {
384387 setStore ( "interrupt" , 0 )
385388 } , 5000 )
386389
387390 if ( store . interrupt >= 2 ) {
388391 void sdk . client . session . abort ( {
389392 sessionID : props . sessionID ,
390393 } )
394+ clearTimeout ( interruptTimer )
391395 setStore ( "interrupt" , 0 )
392396 }
393397 dialog . clear ( )
@@ -402,12 +406,7 @@ export function Prompt(props: PromptProps) {
402406 dialog . clear ( )
403407
404408 // replace summarized text parts with the actual text
405- const text = store . prompt . parts
406- . filter ( ( p ) => p . type === "text" )
407- . reduce ( ( acc , p ) => {
408- if ( ! p . source ) return acc
409- return acc . replace ( p . source . text . value , p . text )
410- } , store . prompt . input )
409+ const text = expandPastedTextPlaceholders ( store . prompt . input , store . prompt . parts )
411410
412411 const nonTextParts = store . prompt . parts . filter ( ( p ) => p . type !== "text" )
413412
@@ -642,17 +641,17 @@ export function Prompt(props: PromptProps) {
642641 start = part . source . text . start
643642 end = part . source . text . end
644643 virtualText = part . source . text . value
645- styleId = fileStyleId
644+ styleId = fileStyleId ( )
646645 } else if ( part . type === "agent" && part . source ) {
647646 start = part . source . start
648647 end = part . source . end
649648 virtualText = part . source . value
650- styleId = agentStyleId
649+ styleId = agentStyleId ( )
651650 } else if ( part . type === "text" && part . source ?. text ) {
652651 start = part . source . text . start
653652 end = part . source . text . end
654653 virtualText = part . source . text . value
655- styleId = pasteStyleId
654+ styleId = pasteStyleId ( )
656655 }
657656
658657 if ( virtualText ) {
@@ -918,8 +917,6 @@ export function Prompt(props: PromptProps) {
918917 }
919918
920919 async function submitInner ( ) {
921- workspace . clearNotice ( )
922-
923920 // IME: double-defer may fire before onContentChange flushes the last
924921 // composed character (e.g. Korean hangul) to the store, so read
925922 // plainText directly and sync before any downstream reads.
@@ -1031,15 +1028,26 @@ export function Prompt(props: PromptProps) {
10311028
10321029 if ( store . mode === "shell" ) {
10331030 move . startSubmit ( )
1034- void sdk . client . session . shell ( {
1035- sessionID,
1036- agent : agent . name ,
1037- model : {
1038- providerID : selectedModel . providerID ,
1039- modelID : selectedModel . modelID ,
1040- } ,
1041- command : inputText ,
1042- } )
1031+ sdk . client . session
1032+ . shell (
1033+ {
1034+ sessionID,
1035+ agent : agent . name ,
1036+ model : {
1037+ providerID : selectedModel . providerID ,
1038+ modelID : selectedModel . modelID ,
1039+ } ,
1040+ command : inputText ,
1041+ } ,
1042+ { throwOnError : true } ,
1043+ )
1044+ . catch ( ( error ) => {
1045+ toast . show ( {
1046+ title : "Failed to run shell command" ,
1047+ message : errorMessage ( error ) ,
1048+ variant : "error" ,
1049+ } )
1050+ } )
10431051 setStore ( "mode" , "normal" )
10441052 } else if (
10451053 inputText . startsWith ( "/" ) &&
@@ -1053,15 +1061,26 @@ export function Prompt(props: PromptProps) {
10531061 const restOfInput = firstLineEnd === - 1 ? "" : inputText . slice ( firstLineEnd + 1 )
10541062 const args = firstLineArgs . join ( " " ) + ( restOfInput ? "\n" + restOfInput : "" )
10551063
1056- void sdk . client . session . command ( {
1057- sessionID,
1058- command : command . slice ( 1 ) ,
1059- arguments : args ,
1060- agent : agent . name ,
1061- model : `${ selectedModel . providerID } /${ selectedModel . modelID } ` ,
1062- variant,
1063- parts : nonTextParts . filter ( ( x ) => x . type === "file" ) ,
1064- } )
1064+ sdk . client . session
1065+ . command (
1066+ {
1067+ sessionID,
1068+ command : command . slice ( 1 ) ,
1069+ arguments : args ,
1070+ agent : agent . name ,
1071+ model : `${ selectedModel . providerID } /${ selectedModel . modelID } ` ,
1072+ variant,
1073+ parts : nonTextParts . filter ( ( x ) => x . type === "file" ) ,
1074+ } ,
1075+ { throwOnError : true } ,
1076+ )
1077+ . catch ( ( error ) => {
1078+ toast . show ( {
1079+ title : "Failed to run command" ,
1080+ message : errorMessage ( error ) ,
1081+ variant : "error" ,
1082+ } )
1083+ } )
10651084 } else {
10661085 move . startSubmit ( )
10671086 sdk . client . session
@@ -1130,7 +1149,7 @@ export function Prompt(props: PromptProps) {
11301149 start : extmarkStart ,
11311150 end : extmarkEnd ,
11321151 virtual : true ,
1133- styleId : pasteStyleId ,
1152+ styleId : pasteStyleId ( ) ,
11341153 typeId : promptPartTypeId ,
11351154 } )
11361155
@@ -1162,7 +1181,7 @@ export function Prompt(props: PromptProps) {
11621181 const attachment = await readLocalAttachment ( filepath )
11631182 const filename = path . basename ( filepath )
11641183 if ( attachment ?. type === "text" ) {
1165- pasteText ( attachment . content , `[SVG: ${ filename ?? "image" } ]` )
1184+ pasteText ( attachment . content , `[SVG: ${ filename || "image" } ]` )
11661185 return
11671186 }
11681187 if ( attachment ?. type === "binary" ) {
@@ -1213,7 +1232,7 @@ export function Prompt(props: PromptProps) {
12131232 start : extmarkStart ,
12141233 end : extmarkEnd ,
12151234 virtual : true ,
1216- styleId : pasteStyleId ,
1235+ styleId : pasteStyleId ( ) ,
12171236 typeId : promptPartTypeId ,
12181237 } )
12191238
@@ -1483,7 +1502,6 @@ export function Prompt(props: PromptProps) {
14831502 </ Show >
14841503 </ box >
14851504 < Autocomplete
1486- sessionID = { props . sessionID }
14871505 ref = { ( r ) => {
14881506 setAuto ( ( ) => r )
14891507 } }
0 commit comments