@@ -19,6 +19,7 @@ import type {
1919 Model ,
2020 Thread ,
2121 ThreadItem ,
22+ TurnCompletedNotification ,
2223 UserInput ,
2324 ReasoningEffortOption
2425} from "./app-server/v2" ;
@@ -739,13 +740,20 @@ export class CodexAcpServer implements acp.Agent {
739740 approvalHandler ,
740741 elicitationHandler ) ;
741742
742- if ( await this . availableCommands . tryHandle ( params . prompt , sessionState ) ) {
743+ const commandResult = await this . availableCommands . tryHandle ( params . prompt , sessionState ) ;
744+ if ( commandResult ) {
743745 logger . log ( "Prompt handled by a command" ) ;
744- return {
745- stopReason : "end_turn" ,
746- usage : this . buildPromptUsage ( sessionState . lastTokenUsage ) ,
747- _meta : this . buildQuotaMeta ( sessionState ) ,
748- } ;
746+ if ( commandResult !== true ) {
747+ const interruptedResponse = await this . createInterruptedResponseIfNeeded ( params . sessionId , commandResult , sessionState ) ;
748+ if ( interruptedResponse ) {
749+ return interruptedResponse ;
750+ }
751+ }
752+ const error = eventHandler . getFailure ( ) ;
753+ if ( error ) {
754+ throw error ;
755+ }
756+ return this . createPromptResponse ( "end_turn" , sessionState ) ;
749757 }
750758
751759 const modelId = ModelId . fromString ( sessionState . currentModelId ) ;
@@ -768,22 +776,9 @@ export class CodexAcpServer implements acp.Agent {
768776 ( ) => this . codexAcpClient . sendPrompt ( params , agentMode , modelId , disableSummary , sessionState . cwd ) ) ;
769777
770778 // Check if turn was interrupted (cancelled)
771- if ( turnCompleted . turn . status === "interrupted" ) {
772- await this . connection . sessionUpdate ( {
773- sessionId : params . sessionId ,
774- update : {
775- sessionUpdate : "agent_message_chunk" ,
776- content : {
777- type : "text" ,
778- text : "*Conversation interrupted*"
779- }
780- }
781- } ) ;
782- return {
783- stopReason : "cancelled" ,
784- usage : this . buildPromptUsage ( sessionState . lastTokenUsage ) ,
785- _meta : this . buildQuotaMeta ( sessionState ) ,
786- } ;
779+ const interruptedResponse = await this . createInterruptedResponseIfNeeded ( params . sessionId , turnCompleted , sessionState ) ;
780+ if ( interruptedResponse ) {
781+ return interruptedResponse ;
787782 }
788783
789784 const error = eventHandler . getFailure ( )
@@ -792,11 +787,7 @@ export class CodexAcpServer implements acp.Agent {
792787 throw error ;
793788 }
794789
795- return {
796- stopReason : "end_turn" ,
797- usage : this . buildPromptUsage ( sessionState . lastTokenUsage ) ,
798- _meta : this . buildQuotaMeta ( sessionState ) ,
799- } ;
790+ return this . createPromptResponse ( "end_turn" , sessionState ) ;
800791 } catch ( err ) {
801792 logger . error ( `Prompt for session ${ params . sessionId } failed` , err ) ;
802793 throw err ;
@@ -832,6 +823,35 @@ export class CodexAcpServer implements acp.Agent {
832823 return toPromptUsage ( lastTokenUsage ) ;
833824 }
834825
826+ private async createInterruptedResponseIfNeeded (
827+ sessionId : string ,
828+ turnCompleted : TurnCompletedNotification ,
829+ sessionState : SessionState
830+ ) : Promise < acp . PromptResponse | null > {
831+ if ( turnCompleted . turn . status !== "interrupted" ) {
832+ return null ;
833+ }
834+ await this . connection . sessionUpdate ( {
835+ sessionId,
836+ update : {
837+ sessionUpdate : "agent_message_chunk" ,
838+ content : {
839+ type : "text" ,
840+ text : "*Conversation interrupted*"
841+ }
842+ }
843+ } ) ;
844+ return this . createPromptResponse ( "cancelled" , sessionState ) ;
845+ }
846+
847+ private createPromptResponse ( stopReason : acp . PromptResponse [ "stopReason" ] , sessionState : SessionState ) : acp . PromptResponse {
848+ return {
849+ stopReason,
850+ usage : this . buildPromptUsage ( sessionState . lastTokenUsage ) ,
851+ _meta : this . buildQuotaMeta ( sessionState ) ,
852+ } ;
853+ }
854+
835855 private async runWithProcessCheck < T > ( operation : ( ) => Promise < T > ) : Promise < T > {
836856 try {
837857 return await operation ( ) ;
0 commit comments