@@ -274,40 +274,35 @@ export class RunInTerminalTool extends Disposable implements IToolImpl {
274
274
}
275
275
276
276
let error : string | undefined ;
277
+ const isNewSession = ! args . isBackground && ! this . _sessionTerminalAssociations . has ( chatSessionId ) ;
277
278
278
279
const timingStart = Date . now ( ) ;
279
280
const termId = generateUuid ( ) ;
280
281
281
- if ( args . isBackground ) {
282
- const store = new DisposableStore ( ) ;
283
- let outputAndIdle : { terminalExecutionIdleBeforeTimeout : boolean ; output : string ; pollDurationMs ?: number ; modelOutputEvalResponse ?: string } | undefined = undefined ;
282
+ const store = new DisposableStore ( ) ;
284
283
285
- this . _logService . debug ( `RunInTerminalTool: Creating background terminal with ID=${ termId } ` ) ;
286
- const toolTerminal = await this . _instantiationService . createInstance ( ToolTerminalCreator ) . createTerminal ( token ) ;
287
- this . _sessionTerminalAssociations . set ( chatSessionId , toolTerminal ) ;
288
- if ( token . isCancellationRequested ) {
289
- toolTerminal . instance . dispose ( ) ;
290
- throw new CancellationError ( ) ;
291
- }
292
- await this . _setupTerminalAssociation ( toolTerminal , chatSessionId , termId , args . isBackground ) ;
284
+ this . _logService . debug ( `RunInTerminalTool: Creating ${ args . isBackground ? 'background' : 'foreground' } terminal. termId=${ termId } , chatSessionId=${ chatSessionId } ` ) ;
285
+ const toolTerminal = await ( args . isBackground ? this . _initBackgroundTerminal : this . _initForegroundTerminal ) ( chatSessionId , termId , token ) ;
293
286
294
- this . _terminalService . setActiveInstance ( toolTerminal . instance ) ;
295
- const timingConnectMs = Date . now ( ) - timingStart ;
287
+ this . _terminalService . setActiveInstance ( toolTerminal . instance ) ;
288
+ const timingConnectMs = Date . now ( ) - timingStart ;
296
289
297
- const xterm = await toolTerminal . instance . xtermReadyPromise ;
298
- if ( ! xterm ) {
299
- throw new Error ( 'Instance was disposed before xterm.js was ready' ) ;
300
- }
290
+ const xterm = await toolTerminal . instance . xtermReadyPromise ;
291
+ if ( ! xterm ) {
292
+ throw new Error ( 'Instance was disposed before xterm.js was ready' ) ;
293
+ }
301
294
302
- let inputUserChars = 0 ;
303
- let inputUserSigint = false ;
304
- store . add ( xterm . raw . onData ( data => {
305
- if ( ! telemetryIgnoredSequences . includes ( data ) ) {
306
- inputUserChars += data . length ;
307
- }
308
- inputUserSigint ||= data === '\x03' ;
309
- } ) ) ;
295
+ let inputUserChars = 0 ;
296
+ let inputUserSigint = false ;
297
+ store . add ( xterm . raw . onData ( data => {
298
+ if ( ! telemetryIgnoredSequences . includes ( data ) ) {
299
+ inputUserChars += data . length ;
300
+ }
301
+ inputUserSigint ||= data === '\x03' ;
302
+ } ) ) ;
310
303
304
+ if ( args . isBackground ) {
305
+ let outputAndIdle : { terminalExecutionIdleBeforeTimeout : boolean ; output : string ; pollDurationMs ?: number ; modelOutputEvalResponse ?: string } | undefined = undefined ;
311
306
try {
312
307
this . _logService . debug ( `RunInTerminalTool: Starting background execution \`${ command } \`` ) ;
313
308
@@ -372,40 +367,6 @@ export class RunInTerminalTool extends Disposable implements IToolImpl {
372
367
} ) ;
373
368
}
374
369
} else {
375
- const store = new DisposableStore ( ) ;
376
- let toolTerminal : IToolTerminal | undefined = this . _sessionTerminalAssociations . get ( chatSessionId ) ;
377
- const isNewSession = ! toolTerminal ;
378
- if ( toolTerminal ) {
379
- this . _logService . debug ( `RunInTerminalTool: Using existing terminal with session ID \`${ chatSessionId } \`` ) ;
380
- } else {
381
- this . _logService . debug ( `RunInTerminalTool: Creating terminal with session ID \`${ chatSessionId } \`` ) ;
382
- toolTerminal = await this . _instantiationService . createInstance ( ToolTerminalCreator ) . createTerminal ( token ) ;
383
- this . _sessionTerminalAssociations . set ( chatSessionId , toolTerminal ) ;
384
- if ( token . isCancellationRequested ) {
385
- toolTerminal . instance . dispose ( ) ;
386
- throw new CancellationError ( ) ;
387
- }
388
- await this . _setupTerminalAssociation ( toolTerminal , chatSessionId , termId , args . isBackground ) ;
389
- }
390
-
391
- this . _terminalService . setActiveInstance ( toolTerminal . instance ) ;
392
-
393
- const timingConnectMs = Date . now ( ) - timingStart ;
394
-
395
- const xterm = await toolTerminal . instance . xtermReadyPromise ;
396
- if ( ! xterm ) {
397
- throw new Error ( 'Instance was disposed before xterm.js was ready' ) ;
398
- }
399
-
400
- let inputUserChars = 0 ;
401
- let inputUserSigint = false ;
402
- store . add ( xterm . raw . onData ( data => {
403
- if ( ! telemetryIgnoredSequences . includes ( data ) ) {
404
- inputUserChars += data . length ;
405
- }
406
- inputUserSigint ||= data === '\x03' ;
407
- } ) ) ;
408
-
409
370
let terminalResult = '' ;
410
371
411
372
let outputLineCount = - 1 ;
@@ -484,6 +445,34 @@ export class RunInTerminalTool extends Disposable implements IToolImpl {
484
445
}
485
446
}
486
447
448
+ private async _initBackgroundTerminal ( chatSessionId : string , termId : string , token : CancellationToken ) : Promise < IToolTerminal > {
449
+ this . _logService . debug ( `RunInTerminalTool: Creating background terminal with ID=${ termId } ` ) ;
450
+ const toolTerminal = await this . _instantiationService . createInstance ( ToolTerminalCreator ) . createTerminal ( token ) ;
451
+ this . _sessionTerminalAssociations . set ( chatSessionId , toolTerminal ) ;
452
+ if ( token . isCancellationRequested ) {
453
+ toolTerminal . instance . dispose ( ) ;
454
+ throw new CancellationError ( ) ;
455
+ }
456
+ await this . _setupTerminalAssociation ( toolTerminal , chatSessionId , termId , true ) ;
457
+ return toolTerminal ;
458
+ }
459
+
460
+ private async _initForegroundTerminal ( chatSessionId : string , termId : string , token : CancellationToken ) : Promise < IToolTerminal > {
461
+ const cachedTerminal = this . _sessionTerminalAssociations . get ( chatSessionId ) ;
462
+ if ( cachedTerminal ) {
463
+ this . _logService . debug ( `RunInTerminalTool: Using cached foreground terminal with session ID \`${ chatSessionId } \`` ) ;
464
+ return cachedTerminal ;
465
+ }
466
+ const toolTerminal = await this . _instantiationService . createInstance ( ToolTerminalCreator ) . createTerminal ( token ) ;
467
+ this . _sessionTerminalAssociations . set ( chatSessionId , toolTerminal ) ;
468
+ if ( token . isCancellationRequested ) {
469
+ toolTerminal . instance . dispose ( ) ;
470
+ throw new CancellationError ( ) ;
471
+ }
472
+ await this . _setupTerminalAssociation ( toolTerminal , chatSessionId , termId , false ) ;
473
+ return toolTerminal ;
474
+ }
475
+
487
476
protected async _rewriteCommandIfNeeded ( args : IRunInTerminalInputParams , instance : Pick < ITerminalInstance , 'getCwdResource' > | undefined , shell : string ) : Promise < string > {
488
477
const commandLine = args . command ;
489
478
const os = await this . _osBackend ;
0 commit comments