@@ -20,11 +20,13 @@ type QueueInput = { body: string; front: boolean }
2020type Item =
2121 | { kind : "prompt" ; info : Info ; label : string ; body : string ; parts : InputPart [ ] }
2222 | { kind : "command" ; info : Info ; source : string ; cmd : string ; args : string ; files : FilePartInput [ ] }
23+ | { kind : "compact" ; info : Info ; source : string }
2324 | { kind : "shell" ; info : Info ; source : string ; shell : string }
2425
2526type EntryOp =
2627 | { kind : "prompt" ; label : string ; body : string }
2728 | { kind : "command" ; source : string ; cmd : string ; args : string }
29+ | { kind : "compact" ; source : string }
2830 | { kind : "shell" ; source : string ; shell : string }
2931
3032type Activity = { kind : "idle" } | { kind : "busy" } | { kind : "sending" ; idle : boolean }
@@ -85,7 +87,16 @@ const parse = (input: QueueInput, files = 0): Op => {
8587 }
8688
8789 const match = text . match ( CMD )
88- if ( match ) return { kind : "command" , source : text , cmd : match [ 1 ] , args : match [ 2 ] ?? "" , front }
90+ if ( match ) {
91+ const cmd = match [ 1 ]
92+ const args = match [ 2 ] ?? ""
93+ if ( cmd === "compact" ) {
94+ if ( args . trim ( ) ) return { kind : "invalid" , message : "Queue compact does not accept arguments" }
95+ if ( files ) return { kind : "invalid" , message : "Queue compact does not support attachments" }
96+ return { kind : "compact" , source : text , front }
97+ }
98+ return { kind : "command" , source : text , cmd, args, front }
99+ }
89100 return { kind : "prompt" , label : brief ( input . body , files ) , body : input . body , front }
90101}
91102
@@ -206,9 +217,18 @@ export const QueuePlugin: Plugin = async ({ client }) => {
206217
207218 const prompt = ( sid : string , info : Info , parts : InputPart [ ] , noReply ?: boolean ) => client . session . prompt ( { path : { id : sid } , body : { ...opts ( info ) , noReply, parts } as any } )
208219 const shell = ( sid : string , command : string , info : Run ) => client . session . shell ( { path : { id : sid } , body : { agent : info . agent , model : info . model , command } } )
220+ // TUI command events target the focused session; queued replay must target the original session.
221+ const compact = ( sid : string , info : Info ) =>
222+ client . session . summarize ( {
223+ path : { id : sid } ,
224+ body : { providerID : info . model . providerID , modelID : info . model . modelID } ,
225+ throwOnError : true ,
226+ } )
227+ const tuiCommand = ( command : string ) => client . tui . executeCommand ( { body : { command } , throwOnError : true } )
209228
210229 const replay = async ( sid : string , item : Item ) => {
211230 if ( item . kind === "shell" ) return shell ( sid , item . shell , item . info )
231+ if ( item . kind === "compact" ) return compact ( sid , item . info )
212232
213233 if ( item . kind === "command" ) {
214234 await client . session . command ( {
@@ -390,6 +410,11 @@ export const QueuePlugin: Plugin = async ({ client }) => {
390410 throw new Error ( HANDLED )
391411 }
392412
413+ if ( op . kind === "compact" ) {
414+ await tuiCommand ( "session_compact" )
415+ throw new Error ( HANDLED )
416+ }
417+
393418 if ( op . kind === "command" ) {
394419 await client . session . command ( { path : { id : sid } , body : { command : op . cmd , arguments : op . args , parts } as any } )
395420 throw new Error ( HANDLED )
@@ -412,6 +437,7 @@ export const QueuePlugin: Plugin = async ({ client }) => {
412437 const current = state ( sid )
413438 const parts = files ( output . parts )
414439 const op = parse ( request , parts . length )
440+ const meta = input as Meta
415441
416442 if ( control ( op ) ) {
417443 hide ( output . message . id , text )
@@ -427,6 +453,11 @@ export const QueuePlugin: Plugin = async ({ client }) => {
427453
428454 if ( current . activity . kind === "idle" && ! current . stopped ) {
429455 if ( op . kind === "command" ) return
456+ if ( op . kind === "compact" ) {
457+ hide ( output . message . id , text )
458+ await compact ( sid , { agent : output . message . agent , model : output . message . model , variant : meta . variant , controls : meta . controls , fast : meta . fast } )
459+ return
460+ }
430461 if ( op . kind === "shell" ) {
431462 hide ( output . message . id , text )
432463 await shell ( sid , op . shell , { agent : output . message . agent , model : output . message . model } )
@@ -436,13 +467,13 @@ export const QueuePlugin: Plugin = async ({ client }) => {
436467 return
437468 }
438469
439- const meta = input as Meta
440470 const info = { agent : output . message . agent , model : { ...output . message . model } , variant : meta . variant , controls : meta . controls , fast : meta . fast }
441471 const prior = await latest ( sid )
442472 if ( prior ) Object . assign ( output . message , opts ( prior ) )
443473 else console . warn ( "QueuePlugin could not neutralize queued placeholder metadata because the session has no previous message context" )
444474 let item : Item
445475 if ( op . kind === "shell" ) item = { kind : "shell" , info, source : op . source , shell : op . shell }
476+ else if ( op . kind === "compact" ) item = { kind : "compact" , info, source : op . source }
446477 else if ( op . kind === "command" ) item = { kind : "command" , info, source : op . source , cmd : op . cmd , args : op . args , files : parts }
447478 else {
448479 item = {
0 commit comments