[codex] Handle chat run abort lifecycle (#454)

* feat: call upstream stop API when aborting a run

- Modified handleAbort to call POST /v1/runs/{run_id}/stop endpoint
- Use profile-specific upstream URL and API key from gatewayManager
- Add 5-second timeout with error handling and logging
- Keep local abortController.abort() for EventSource cleanup
- Change handleAbort to async method and update call site

This ensures the upstream Hermes gateway is properly notified
when a user aborts a run, allowing graceful termination.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: close ChatRunSocket connections on shutdown to prevent hanging

- Add close() method to ChatRunSocket to abort all active runs
  and clear session state
- Pass chatRunServer to bindShutdown and close it before
  groupChatServer during shutdown
- This prevents EventSource connections and abort controllers
  from keeping the process alive during nodemon restart

Fixes the "still waiting for sub-process to finish" issue.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Handle chat run abort lifecycle

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
ekko
2026-05-05 13:03:14 +08:00
committed by GitHub
parent f13ce3a080
commit e3d28f4659
8 changed files with 524 additions and 231 deletions
+3 -2
View File
@@ -37,6 +37,7 @@ process.on('unhandledRejection', (reason) => {
})
let server: any = null
let chatRunServer: any = null
export async function bootstrap() {
console.log(`hermes-web-ui v${APP_VERSION} starting...`)
@@ -102,7 +103,7 @@ export async function bootstrap() {
groupChatServer.setGatewayManager(getGatewayManagerInstance())
// Chat run Socket.IO — shares the same Server instance, just adds /chat-run namespace
const chatRunServer = new ChatRunSocket(groupChatServer.getIO(), getGatewayManagerInstance())
chatRunServer = new ChatRunSocket(groupChatServer.getIO(), getGatewayManagerInstance())
setChatRunServer(chatRunServer)
chatRunServer.init()
@@ -139,7 +140,7 @@ export async function bootstrap() {
logger.error({ err }, 'Server error')
})
bindShutdown(server, groupChatServer)
bindShutdown(server, groupChatServer, chatRunServer)
startVersionCheck()
}