Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 14 additions & 3 deletions pkg/server/session_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -891,9 +891,13 @@ func (sm *SessionManager) RunSession(ctx context.Context, sessionID, agentFilena
defer cancel()
defer runtimeSession.streaming.Unlock()

// Start title generation in parallel if needed
// Start title generation in parallel if needed, coordinating via WaitGroup
// so close(streamChan) does not fire while generateTitle is still sending.
var wg sync.WaitGroup
if needsTitle {
go sm.generateTitle(ctx, sess, titleGen, userMessages, streamChan)
wg.Go(func() {
sm.generateTitle(ctx, sess, titleGen, userMessages, streamChan)
})
} else if titleToEmit != "" {
// Re-emit the existing title so late-joining SSE consumers
// and boards can pick it up without an extra API call.
Expand All @@ -903,11 +907,18 @@ func (sm *SessionManager) RunSession(ctx context.Context, sessionID, agentFilena
stream := runtimeSession.runtime.RunStream(streamCtx, sess)
for event := range stream {
if streamCtx.Err() != nil {
return
break
}
streamChan <- event
}

// Ensure title generation finishes before defers run close(streamChan).
wg.Wait()

if streamCtx.Err() != nil {
return
}

if err := sm.sessionStore.UpdateSession(ctx, sess); err != nil {
return
}
Expand Down
Loading