@@ -9,10 +9,10 @@ import { useModelStore } from "@/stores/ModelStore";
99import { sessionManager } from "@/services/sessionManager" ;
1010import { ChatInput } from "./ChatInput" ;
1111import { MessageList } from "./MessageList" ;
12- import { ApprovalDialog } from "../dialogs/ApprovalDialog" ;
1312import { useCodexEvents } from "../../hooks/useCodexEvents" ;
1413import { ReasoningEffortSelector } from './ReasoningEffortSelector' ;
1514import { Sandbox } from "./Sandbox" ;
15+ import { generateUniqueId } from "@/utils/genUniqueId" ;
1616
1717interface ChatInterfaceProps {
1818 sessionId : string ;
@@ -25,8 +25,6 @@ export const ChatInterface: React.FC<ChatInterfaceProps> = ({
2525} ) => {
2626 const { inputValue, setInputValue } = useChatInputStore ( ) ;
2727 const { currentModel, currentProvider, reasoningEffort } = useModelStore ( ) ;
28- const [ pendingApproval , setPendingApproval ] =
29- useState < ApprovalRequest | null > ( null ) ;
3028 const [ isConnected , setIsConnected ] = useState ( false ) ;
3129 const [ tempSessionId , setTempSessionId ] = useState < string | null > ( null ) ;
3230 const [ activeSessionId , setActiveSessionId ] = useState < string > ( sessionId ) ;
@@ -79,7 +77,6 @@ export const ChatInterface: React.FC<ChatInterfaceProps> = ({
7977
8078 useCodexEvents ( {
8179 sessionId : activeSessionId ,
82- onApprovalRequest : setPendingApproval ,
8380 } ) ;
8481
8582 const messages = [ ...sessionMessages ] ;
@@ -150,7 +147,7 @@ export const ChatInterface: React.FC<ChatInterfaceProps> = ({
150147 } catch ( error ) {
151148 console . error ( "Failed to auto-start session:" , error ) ;
152149 const errorMessage = {
153- id : `${ sessionId } -auto-start-error-${ Date . now ( ) } - ${ Math . random ( ) . toString ( 36 ) . substring ( 2 , 11 ) } ` ,
150+ id : `${ sessionId } -auto-start-error-${ generateUniqueId ( ) } ` ,
154151 role : "system" as const ,
155152 content : `Failed to start Codex session: ${ error } ` ,
156153 timestamp : Date . now ( ) ,
@@ -218,7 +215,7 @@ export const ChatInterface: React.FC<ChatInterfaceProps> = ({
218215 await sessionManager . closeAllSessions ( ) ;
219216 }
220217
221- actualSessionId = `codex-event-${ Date . now ( ) } - ${ Math . random ( ) . toString ( 36 ) . substr ( 2 , 9 ) } ` ;
218+ actualSessionId = `codex-event-${ generateUniqueId ( ) } ` ;
222219 setTempSessionId ( actualSessionId ) ;
223220 setPendingNewConversation ( false ) ;
224221 isPendingSession = true ;
@@ -230,7 +227,7 @@ export const ChatInterface: React.FC<ChatInterfaceProps> = ({
230227 ) ;
231228 if ( ! conversationExists ) {
232229 // Always use timestamp format for consistency
233- actualSessionId = `codex-event-${ Date . now ( ) } - ${ Math . random ( ) . toString ( 36 ) . substr ( 2 , 9 ) } ` ;
230+ actualSessionId = `codex-event-${ generateUniqueId ( ) } ` ;
234231 createConversation ( "New Chat" , "agent" , actualSessionId ) ;
235232 }
236233 }
@@ -268,7 +265,7 @@ export const ChatInterface: React.FC<ChatInterfaceProps> = ({
268265 console . error ( "Failed to start session:" , error ) ;
269266 setSessionStarting ( false ) ;
270267 const errorMessage = {
271- id : `${ actualSessionId } -startup-error-${ Date . now ( ) } - ${ Math . random ( ) . toString ( 36 ) . substring ( 2 , 11 ) } ` ,
268+ id : `${ actualSessionId } -startup-error-${ generateUniqueId ( ) } ` ,
272269 role : "system" as const ,
273270 content : `Failed to start Codex session: ${ error } ` ,
274271 timestamp : Date . now ( ) ,
@@ -280,7 +277,7 @@ export const ChatInterface: React.FC<ChatInterfaceProps> = ({
280277
281278 // Add user message to conversation store
282279 const userMessage = {
283- id : `${ actualSessionId } -user-${ Date . now ( ) } - ${ Math . random ( ) . toString ( 36 ) . substring ( 2 , 11 ) } ` ,
280+ id : `${ actualSessionId } -user-${ generateUniqueId ( ) } ` ,
284281 role : "user" as const ,
285282 content : messageContent ,
286283 timestamp : Date . now ( ) ,
@@ -303,7 +300,7 @@ export const ChatInterface: React.FC<ChatInterfaceProps> = ({
303300 } catch ( error ) {
304301 console . error ( "Failed to send message:" , error ) ;
305302 const errorMessage = {
306- id : `${ actualSessionId } -send-error-${ Date . now ( ) } - ${ Math . random ( ) . toString ( 36 ) . substring ( 2 , 11 ) } ` ,
303+ id : `${ actualSessionId } -send-error-${ generateUniqueId ( ) } ` ,
307304 role : "system" as const ,
308305 content : `Failed to send message: ${ error } ` ,
309306 timestamp : Date . now ( ) ,
@@ -313,33 +310,64 @@ export const ChatInterface: React.FC<ChatInterfaceProps> = ({
313310 }
314311 } ;
315312
316- const handleApproval = async ( approved : boolean ) => {
317- if ( ! pendingApproval ) return ;
318-
313+ const handleApproval = async ( approved : boolean , approvalRequest : ApprovalRequest ) => {
319314 try {
320315 // Extract raw session ID for backend communication
321316 const rawSessionId = sessionId . startsWith ( "codex-event-" )
322317 ? sessionId . replace ( "codex-event-" , "" )
323318 : sessionId ;
324319
325- if ( pendingApproval . type === 'apply_patch' ) {
326- // For apply_patch, use event.id (stored in pendingApproval.id)
327- await invoke ( "approve_patch" , {
328- sessionId : rawSessionId ,
329- approvalId : pendingApproval . id ,
330- approved,
331- } ) ;
332- } else {
333- // For exec, use call_id (stored in pendingApproval.id)
334- await invoke ( "approve_execution" , {
320+ // Handle different approval types with appropriate backend calls
321+ switch ( approvalRequest . type ) {
322+ case 'exec' :
323+ await invoke ( "approve_execution" , {
324+ sessionId : rawSessionId ,
325+ approvalId : approvalRequest . id ,
326+ approved,
327+ } ) ;
328+ break ;
329+
330+ case 'patch' :
331+ await invoke ( "approve_patch" , {
332+ sessionId : rawSessionId ,
333+ approvalId : approvalRequest . id ,
334+ approved,
335+ } ) ;
336+ break ;
337+
338+ case 'apply_patch' :
339+ await invoke ( "approve_patch" , {
340+ sessionId : rawSessionId ,
341+ approvalId : approvalRequest . id ,
342+ approved,
343+ } ) ;
344+ break ;
345+
346+ default :
347+ console . error ( 'Unknown approval request type:' , approvalRequest . type ) ;
348+ return ;
349+ }
350+
351+ console . log ( `✅ Approval ${ approved ? 'granted' : 'denied' } for ${ approvalRequest . type } request ${ approvalRequest . id } ` ) ;
352+
353+ // If denied, pause the session to stop further execution
354+ if ( ! approved ) {
355+ console . log ( '🛑 Pausing session due to denied approval' ) ;
356+ await invoke ( "pause_session" , {
335357 sessionId : rawSessionId ,
336- approvalId : pendingApproval . id ,
337- approved,
338358 } ) ;
339359 }
340- setPendingApproval ( null ) ;
341360 } catch ( error ) {
342361 console . error ( "Failed to send approval:" , error ) ;
362+
363+ // Add error message to conversation
364+ const errorMessage = {
365+ id : `${ sessionId } -approval-error-${ generateUniqueId ( ) } ` ,
366+ role : "system" as const ,
367+ content : `Failed to process approval: ${ error } ` ,
368+ timestamp : Date . now ( ) ,
369+ } ;
370+ addMessage ( sessionId , errorMessage ) ;
343371 }
344372 } ;
345373
@@ -370,10 +398,6 @@ export const ChatInterface: React.FC<ChatInterfaceProps> = ({
370398 messages = { messages }
371399 isLoading = { isLoading }
372400 isPendingNewConversation = { pendingNewConversation || ! sessionId . trim ( ) }
373- />
374-
375- < ApprovalDialog
376- pendingApproval = { pendingApproval }
377401 onApproval = { handleApproval }
378402 />
379403
0 commit comments