(
sessionId: string,
startTime: number,
handle: SessionHandle,
)
| 440 | } |
| 441 | |
| 442 | function onSessionDone( |
| 443 | sessionId: string, |
| 444 | startTime: number, |
| 445 | handle: SessionHandle, |
| 446 | ): (status: SessionDoneStatus) => void { |
| 447 | return (rawStatus: SessionDoneStatus): void => { |
| 448 | const workId = sessionWorkIds.get(sessionId) |
| 449 | activeSessions.delete(sessionId) |
| 450 | sessionStartTimes.delete(sessionId) |
| 451 | sessionWorkIds.delete(sessionId) |
| 452 | sessionIngressTokens.delete(sessionId) |
| 453 | const compatId = sessionCompatIds.get(sessionId) ?? sessionId |
| 454 | sessionCompatIds.delete(sessionId) |
| 455 | logger.removeSession(compatId) |
| 456 | titledSessions.delete(compatId) |
| 457 | v2Sessions.delete(sessionId) |
| 458 | // Clear per-session timeout timer |
| 459 | const timer = sessionTimers.get(sessionId) |
| 460 | if (timer) { |
| 461 | clearTimeout(timer) |
| 462 | sessionTimers.delete(sessionId) |
| 463 | } |
| 464 | // Clear token refresh timer |
| 465 | tokenRefresh?.cancel(sessionId) |
| 466 | // Wake the at-capacity sleep so the bridge can accept new work immediately |
| 467 | capacityWake.wake() |
| 468 | |
| 469 | // If the session was killed by the timeout watchdog, treat it as a |
| 470 | // failed session (not a server/shutdown interrupt) so we still call |
| 471 | // stopWork and archiveSession below. |
| 472 | const wasTimedOut = timedOutSessions.delete(sessionId) |
| 473 | const status: SessionDoneStatus = |
| 474 | wasTimedOut && rawStatus === 'interrupted' ? 'failed' : rawStatus |
| 475 | const durationMs = Date.now() - startTime |
| 476 | |
| 477 | logForDebugging( |
| 478 | `[bridge:session] sessionId=${sessionId} workId=${workId ?? 'unknown'} exited status=${status} duration=${formatDuration(durationMs)}`, |
| 479 | ) |
| 480 | logEvent('tengu_bridge_session_done', { |
| 481 | status: |
| 482 | status as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS, |
| 483 | duration_ms: durationMs, |
| 484 | }) |
| 485 | logForDiagnosticsNoPII('info', 'bridge_session_done', { |
| 486 | status, |
| 487 | duration_ms: durationMs, |
| 488 | }) |
| 489 | |
| 490 | // Clear the status display before printing final log |
| 491 | logger.clearStatus() |
| 492 | stopStatusUpdates() |
| 493 | |
| 494 | // Build error message from stderr if available |
| 495 | const stderrSummary = |
| 496 | handle.lastStderr.length > 0 ? handle.lastStderr.join('\n') : undefined |
| 497 | let failureMessage: string | undefined |
| 498 | |
| 499 | switch (status) { |
no test coverage detected